5.8.4.1 Справочник по зондам mysqld DTrace
- 5.8.4.1.1 Зонды подключений
- 5.8.4.1.2 Зонды команд
- 5.8.4.1.3 Зонды запросов
- 5.8.4.1.4 Зонды разбора запросов
- 5.8.4.1.5 Зонды кэша запросов
- 5.8.4.1.6 Зонды выполнения запросов
- 5.8.4.1.7 Зонды уровня строк
- 5.8.4.1.8 Зонды чтения строк
- 5.8.4.1.9 Зонды индексов
- 5.8.4.1.10 Зонды блокировок
- 5.8.4.1.11 Зонды сортировки файлов
- 5.8.4.1.12 Зонды инструкций
- 5.8.4.1.13 Зонды сети
- 5.8.4.1.14 Зонды кэша ключей
MySQL поддерживает следующие статические зонды, организованные по группам функциональности.
Таблица 5.5 Зонды DTrace MySQL
| Группа | Зонды |
|---|---|
| Подключение |
connection-start, connection-done
|
| Команда |
command-start, command-done
|
| Запрос |
query-start, query-done
|
| Разбор запроса |
query-parse-start, query-parse-done
|
| Кэш запросов |
query-cache-hit, query-cache-miss
|
| Выполнение запроса |
query-exec-start, query-exec-done
|
| Уровень строк |
insert-row-start, insert-row-done
|
update-row-start, update-row-done
| |
delete-row-start, delete-row-done
| |
| Чтение строк |
read-row-start, read-row-done
|
| Чтение индексов |
index-read-row-start, index-read-row-done
|
| Блокировка |
handler-rdlock-start, handler-rdlock-done
|
handler-wrlock-start, handler-wrlock-done
| |
handler-unlock-start, handler-unlock-done
| |
| Сортировка файлов |
filesort-start, filesort-done
|
| Инструкция |
select-start, select-done
|
insert-start, insert-done
| |
insert-select-start, insert-select-done
| |
update-start, update-done
| |
multi-update-start, multi-update-done
| |
delete-start, delete-done
| |
multi-delete-start, multi-delete-done
| |
| Сеть |
net-read-start, net-read-done, net-write-start, net-write-done
|
| Кэш ключей |
keycache-read-start, keycache-read-block, keycache-read-done, keycache-read-hit, keycache-read-miss, keycache-write-start, keycache-write-block, keycache-write-done
|
При извлечении данных аргументов из зондов каждый аргумент доступен как arg, начиная с Narg0. Для идентификации каждого аргумента в определениях используются описательные имена, но доступ к информации необходимо осуществлять с помощью соответствующего параметра arg.N
5.8.4.1.1 Зонды подключений
Зонды connection-start и connection-done охватывают подключение от клиента, независимо от того, осуществляется ли подключение через сокет или сетевое соединение.
connection-start(connectionid, user, host)
connection-done(status, connectionid)-
connection-start: Срабатывает после успешного подключения и аутентификации клиента. Аргументы содержат информацию о подключении:connectionid: Объектunsigned long, содержащий идентификатор подключения. Он совпадает с идентификатором процесса, показанным как значениеIdв выводеSHOW PROCESSLIST.user: Имя пользователя, использованное при аутентификации. Значение пустое для анонимного пользователя.host: Хост клиента при подключении. Для подключения через Unix-сокеты значение пустое.
-
connection-done: Срабатывает при закрытии подключения к клиенту. Аргументы:status: Статус подключения при закрытии. Для выхода значение 0; для любого другого завершения подключения — ненулевое значение.connectionid: Идентификатор подключения, которое было закрыто.
Следующий скрипт D оценивает и суммирует среднюю продолжительность индивидуальных подключений, а также предоставляет подсчёт, выгружая информацию каждые 60 секунд:
#!/usr/sbin/dtrace -s
mysql*:::connection-start
{
self->start = timestamp;
}
mysql*:::connection-done
/self->start/
{
@ = quantize(((timestamp - self->start)/1000000));
self->start = 0;
}
tick-60s
{
printa(@);
}
При выполнении на сервере с большим количеством клиентов, возможно получение вывода подобного:
1 57413 :tick-60s
value ------------- Distribution ------------- count
-1 | 0
0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 30011
1 | 59
2 | 5
4 | 20
8 | 29
16 | 18
32 | 27
64 | 30
128 | 11
256 | 10
512 | 1
1024 | 6
2048 | 8
4096 | 9
8192 | 8
16384 | 2
32768 | 1
65536 | 1
131072 | 0
262144 | 1
524288 | 0 5.8.4.1.2 Запросы команд
Запросы команд выполняются до и после выполнения клиентской команды, включая любое SQL-выражение, которое может быть выполнено в этот период. Команды включают операции, такие как инициализация базы данных, использование операции COM_CHANGE_USER (поддерживаемой протоколом MySQL) и манипулирование подготовленными запросами. Многие из этих команд используются только API MySQL-клиента из различных коннекторов, таких как PHP и Java.
command-start(connectionid, command, user, host)
command-done(status)-
command-start: Срабатывает при отправке команды на сервер.connectionid: Идентификатор подключения клиента, выполняющего команду.-
command: Целое число, представляющее команду, которая была выполнена. Возможные значения показаны в следующей таблице.Значение Имя Описание 00 COM_SLEEP Внутреннее состояние потока 01 COM_QUIT Закрыть соединение 02 COM_INIT_DB Выбор базы данных ( USE ...)03 COM_QUERY Выполнение запроса 04 COM_FIELD_LIST Получение списка полей 05 COM_CREATE_DB Создание базы данных (устарело) 06 COM_DROP_DB Удаление базы данных (устарело) 07 COM_REFRESH Обновить соединение 08 COM_SHUTDOWN Выключение сервера 09 COM_STATISTICS Получить статистику 10 COM_PROCESS_INFO Получить процессы ( SHOW PROCESSLIST)11 COM_CONNECT Инициализация соединения 12 COM_PROCESS_KILL Убить процесс 13 COM_DEBUG Получить отладочную информацию 14 COM_PING Ping 15 COM_TIME Внутреннее состояние потока 16 COM_DELAYED_INSERT Внутреннее состояние потока 17 COM_CHANGE_USER Изменить пользователя 18 COM_BINLOG_DUMP Используется репликой или mysqlbinlog для запуска чтения двоичного лога 19 COM_TABLE_DUMP Используется репликой для получения информации о таблице источника 20 COM_CONNECT_OUT Используется репликой для протоколирования соединения с сервером 21 COM_REGISTER_SLAVE Используется репликой во время регистрации 22 COM_STMT_PREPARE Подготовить оператор 23 COM_STMT_EXECUTE Выполнить оператор 24 COM_STMT_SEND_LONG_DATA Используется клиентом при запросе расширенных данных 25 COM_STMT_CLOSE Закрыть подготовленный оператор 26 COM_STMT_RESET Сбросить подготовленный оператор 27 COM_SET_OPTION Установить опцию сервера 28 COM_STMT_FETCH Извлечь подготовленный оператор user: Пользователь, выполняющий команду.host: Хост клиента.
command-done: Срабатывает при завершении выполнения команды. Аргументstatusсодержит 0, если команда выполнена успешно, или 1, если оператор был прерван до нормального завершения.
Запросы command-start и command-done лучше всего использовать в сочетании с запросами операторов, чтобы получить представление о времени выполнения в целом.
5.8.4.1.3 Запросы операторов
Запросы query-start и query-done срабатывают при получении сервером определенного запроса и после завершения запроса и успешной отправки информации клиенту.
query-start(query, connectionid, database, user, host)
query-done(status)-
query-start: Срабатывает после получения строки запроса от клиента. Аргументы:query: Полный текст отправленного запроса.connectionid: Идентификатор подключения клиента, который отправил запрос. Идентификатор подключения равен идентификатору подключения, возвращённому при первом подключении клиента, и значениюIdв выводе изSHOW PROCESSLIST.database: Имя базы данных, в которой выполняется запрос.user: Имя пользователя, используемого для подключения к серверу.host: Имя хоста клиента.
query-done: Срабатывает после выполнения запроса и возвращения информации клиенту. Запрос содержит один аргумент,status, который возвращает 0 при успешном выполнении запроса и 1, если произошла ошибка.
Вы можете получить простой отчёт о времени выполнения каждого запроса, используя следующий скрипт D:
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("%-20s %-20s %-40s %-9s\n", "Who", "Database", "Query", "Time(ms)");
}
mysql*:::query-start
{
self->query = copyinstr(arg0);
self->connid = arg1;
self->db = copyinstr(arg2);
self->who = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
self->querystart = timestamp;
}
mysql*:::query-done
{
printf("%-20s %-20s %-40s %-9d\n",self->who,self->db,self->query,
(timestamp - self->querystart) / 1000000);
}При выполнении вышеуказанного скрипта вы получите общее представление о времени выполнения запросов:
$> ./query.d
Who Database Query Time(ms)
root@localhost test select * from t1 order by i limit 10 0
root@localhost test set global query_cache_size=0 0
root@localhost test select * from t1 order by i limit 10 776
root@localhost test select * from t1 order by i limit 10 773
root@localhost test select * from t1 order by i desc limit 10 795 5.8.4.1.4 Запросы разбора операторов
Запросы разбора операторов срабатывают перед разбором исходного SQL-оператора и после завершения разбора оператора и определения модели выполнения, необходимой для обработки оператора:
query-parse-start(query)
query-parse-done(status)query-parse-start: Срабатывает непосредственно перед разбором оператора парсером MySQL. Единственный аргумент,query, — строка, содержащая полный текст исходного запроса.query-parse-done: Срабатывает по завершении разбора исходного оператора.status— целое число, описывающее состояние операции.0указывает, что запрос был успешно разобран.1указывает, что разбор запроса не удался.
Например, вы можете отслеживать время выполнения разбора определённого запроса, используя следующий скрипт D:
#!/usr/sbin/dtrace -s
#pragma D option quiet
mysql*:::query-parse-start
{
self->parsestart = timestamp;
self->parsequery = copyinstr(arg0);
}
mysql*:::query-parse-done
/arg0 == 0/
{
printf("Parsing %s: %d microseconds\n", self->parsequery,((timestamp - self->parsestart)/1000));
}
mysql*:::query-parse-done
/arg0 != 0/
{
printf("Error parsing %s: %d microseconds\n", self->parsequery,((timestamp - self->parsestart)/1000));
} В вышеприведённом скрипте используется предикат на query-parse-done, чтобы генерировать различный вывод в зависимости от значения состояния запроса.
При запуске скрипта и отслеживании выполнения:
$> ./query-parsing.d
Error parsing select from t1 join (t2) on (t1.i = t2.i) order by t1.s,t1.i limit 10: 36 ms
Parsing select * from t1 join (t2) on (t1.i = t2.i) order by t1.s,t1.i limit 10: 176 ms
5.8.4.1.5 Запросы к кэшу запросов
Запросы к кэшу запросов запускаются при выполнении любого запроса. Запрос query-cache-hit срабатывает, когда запрос присутствует в кэше запросов, и может быть использован для возвращения информации о кэше запросов. Аргументы содержат исходный текст запроса и количество строк, возвращённых из кэша запросов для запроса. Если запрос не находится в кэше запросов или кэш запросов отключён, то вместо этого срабатывает запрос query-cache-miss.
query-cache-hit(query, rows)
query-cache-miss(query)query-cache-hit: Срабатывает, когда запрос найден в кэше запросов. Первый аргумент,query, содержит исходный текст запроса. Второй аргумент,rows, — целое число, содержащее количество строк в кэшированном запросе.query-cache-miss: Срабатывает, когда запрос не найден в кэше запросов. Первый аргумент,query, содержит исходный текст запроса.
Запросы к кэшу запросов лучше всего комбинировать с запросом на основной запрос, чтобы определить разницу во времени между использованием или неиспользованием кэша запросов для определенных запросов. Например, в следующем скрипте D информация о запросе и кэше запросов объединяется в вывод информации во время мониторинга:
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("%-20s %-20s %-40s %2s %-9s\n", "Who", "Database", "Query", "QC", "Time(ms)");
}
mysql*:::query-start
{
self->query = copyinstr(arg0);
self->connid = arg1;
self->db = copyinstr(arg2);
self->who = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
self->querystart = timestamp;
self->qc = 0;
}
mysql*:::query-cache-hit
{
self->qc = 1;
}
mysql*:::query-cache-miss
{
self->qc = 0;
}
mysql*:::query-done
{
printf("%-20s %-20s %-40s %-2s %-9d\n",self->who,self->db,self->query,(self->qc ? "Y" : "N"),
(timestamp - self->querystart) / 1000000);
}При выполнении скрипта вы можете увидеть влияние кэша запросов. Изначально кэш запросов отключён. Если вы установите размер кэша запросов и затем выполните запрос несколько раз, вы должны увидеть, что кэш запросов используется для возвращения данных запроса:
$> ./query-cache.d
root@localhost test select * from t1 order by i limit 10 N 1072
root@localhost set global query_cache_size=262144 N 0
root@localhost test select * from t1 order by i limit 10 N 781
root@localhost test select * from t1 order by i limit 10 Y 0 5.8.4.1.6 Пробы выполнения запросов
Проба выполнения запроса срабатывает, когда начинается фактическое выполнение запроса после анализа и проверки кэша запросов, но перед проверкой привилегий или оптимизацией. Сравнивая разницу между началом и завершением пробы, можно отслеживать фактическое время, затраченное на обработку запроса (вместо просто обработки синтаксического анализа и других элементов запроса).
query-exec-start(query, connectionid, database, user, host, exec_type)
query-exec-done(status)
Информация, предоставленная в аргументах для query-start и query-exec-start, почти идентична и предназначена для того, чтобы вы могли выбрать мониторинг всего процесса запроса (используя query-start) или только выполнения (используя query-exec-start), одновременно предоставляя основную информацию о пользователе, клиенте и выполняемом запросе.
-
query-exec-start: Срабатывает при запуске выполнения отдельного запроса. Аргументы:query: Полный текст отправленного запроса.connectionid: Идентификатор соединения клиента, который отправил запрос. Идентификатор соединения равен идентификатору соединения, возвращенному при первом подключении клиента, и значениюIdв выводе изSHOW PROCESSLIST.database: Имя базы данных, в которой выполняется запрос.user: Имя пользователя, используемого для подключения к серверу.host: Имя хоста клиента.-
exec_type: Тип выполнения. Типы выполнения определяются на основе содержимого запроса и места его отправки. Значения для каждого типа показаны в следующей таблице.Значение Описание 0 Выполненный запрос из sql_parse, запрос верхнего уровня. 1 Выполнение подготовленного оператора 2 Выполнение оператора курсора 3 Выполнение запроса в хранимой процедуре
query-exec-done: Срабатывает, когда выполнение запроса завершено. Проба включает один аргумент,status, который возвращает 0 при успешном выполнении запроса и 1, если произошла ошибка.
5.8.4.1.7 Пробы на уровне строк
Пробы на уровне строк срабатывают каждый раз, когда операция над строкой передается в движок хранения. Например, если вы выполняете оператор INSERT с 100 строками данных, то пробы insert-row-start и insert-row-done срабатывают по 100 раз для каждой вставки строки.
insert-row-start(database, table)
insert-row-done(status)
update-row-start(database, table)
update-row-done(status)
delete-row-start(database, table)
delete-row-done(status)insert-row-start: Срабатывает перед вставкой строки в таблицу.insert-row-done: Срабатывает после вставки строки в таблицу.update-row-start: Срабатывает перед обновлением строки в таблице.update-row-done: Срабатывает после обновления строки в таблице.delete-row-start: Срабатывает перед удалением строки из таблицы.delete-row-done: Срабатывает после удаления строки из таблицы.
Аргументы, поддерживаемые пробами, согласованы для соответствующих start и done проб в каждом случае:
database: Имя базы данных.table: Имя таблицы.status: Статус; 0 для успеха или 1 для неудачи.
Поскольку пробы на уровне строк срабатывают для каждого отдельного доступа к строке, эти пробы могут срабатывать много тысяч раз в секунду, что может негативно повлиять на скрипт мониторинга и MySQL. Окружение DTrace должно ограничивать срабатывание этих проб, чтобы предотвратить негативное влияние на производительность. Используйте эти пробы экономно или используйте счетчики или агрегационные функции для отчетности по этим пробам, а затем предоставьте сводку при завершении скрипта или в рамках query-done или query-exec-done проб.
Следующий пример скрипта суммирует продолжительность каждой операции со строкой в пределах более крупного запроса:
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("%-2s %-10s %-10s %9s %9s %-s \n",
"St", "Who", "DB", "ConnID", "Dur ms", "Query");
}
mysql*:::query-start
{
self->query = copyinstr(arg0);
self->who = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
self->db = copyinstr(arg2);
self->connid = arg1;
self->querystart = timestamp;
self->rowdur = 0;
}
mysql*:::query-done
{
this->elapsed = (timestamp - self->querystart) /1000000;
printf("%2d %-10s %-10s %9d %9d %s\n",
arg0, self->who, self->db,
self->connid, this->elapsed, self->query);
}
mysql*:::query-done
/ self->rowdur /
{
printf("%34s %9d %s\n", "", (self->rowdur/1000000), "-> Row ops");
}
mysql*:::insert-row-start
{
self->rowstart = timestamp;
}
mysql*:::delete-row-start
{
self->rowstart = timestamp;
}
mysql*:::update-row-start
{
self->rowstart = timestamp;
}
mysql*:::insert-row-done
{
self->rowdur += (timestamp-self->rowstart);
}
mysql*:::delete-row-done
{
self->rowdur += (timestamp-self->rowstart);
}
mysql*:::update-row-done
{
self->rowdur += (timestamp-self->rowstart);
}
Выполняя вышеуказанный скрипт с запросом, который вставляет данные в таблицу, вы можете отслеживать точное время, затраченное на выполнение фактической вставки строк:
St Who DB ConnID Dur ms Query
0 @localhost test 13 20767 insert into t1(select * from t2)
4827 -> Row ops
5.8.4.1.8 Пробы чтения строк
Пробы чтения строк срабатывают на уровне движка хранения каждый раз, когда происходит операция чтения строки. Эти пробы определяются внутри каждого движка хранения (в отличие от проб *row-start, которые находятся в интерфейсе движка хранения). Таким образом, эти пробы можно использовать для отслеживания отдельных операций и производительности чтения строк на уровне движка хранения. Поскольку эти пробы срабатывают вокруг интерфейса чтения строк движка хранения, они могут вызываться значительное количество раз во время простого запроса.
read-row-start(database, table, scan_flag)
read-row-done(status)read-row-start: Срабатывает, когда строка считывается движком хранения из указанногоdatabaseиtable.scan_flagустанавливается в 1 (истина), когда чтение является частью сканирования таблицы (то есть последовательного чтения), или в 0 (ложь), когда считывается конкретная запись.read-row-done: Срабатывает, когда операция чтения строки внутри движка хранения завершается.statusвозвращает 0 при успехе или положительное значение при ошибке.
5.8.4.1.9 Пробы индексов
Пробы индексов срабатывают каждый раз, когда строка считывается с использованием одного из индексов для указанной таблицы. Проба срабатывает внутри соответствующего движка хранения для таблицы.
index-read-row-start(database, table)
index-read-row-done(status)index-read-row-start: Срабатывает, когда строка считывается движком хранения из указанногоdatabaseиtable.index-read-row-done: Срабатывает, когда операция чтения индексированной строки внутри движка хранения завершается.statusвозвращает 0 при успехе или положительное значение при ошибке.
5.8.4.1.10 Пробы блокировок
Пробы блокировок вызываются всякий раз, когда MySQL запрашивает внешнюю блокировку таблицы с использованием соответствующего механизма блокировки таблицы, определенного типом движка таблицы. Существует три различных типа блокировок: чтение, запись и разблокировка. Используя пробы, можно определить продолжительность внешней процедуры блокировки (то есть время, затраченное движком хранения на реализацию блокировки, включая время ожидания, пока другая блокировка не освободится), и общее время процесса блокировки/разблокировки.
handler-rdlock-start(database, table)
handler-rdlock-done(status)
handler-wrlock-start(database, table)
handler-wrlock-done(status)
handler-unlock-start(database, table)
handler-unlock-done(status)handler-rdlock-start: Срабатывает при запросе блокировки чтения на указанномdatabaseиtable.handler-wrlock-start: Срабатывает при запросе блокировки записи на указанномdatabaseиtable.handler-unlock-start: Срабатывает при запросе разблокировки на указанномdatabaseиtable.handler-rdlock-done: Срабатывает при завершении запроса блокировки чтения.statusравно 0, если операция блокировки выполнена успешно, или>0при ошибке.handler-wrlock-done: Срабатывает при завершении запроса блокировки записи.statusравно 0, если операция блокировки выполнена успешно, или>0при ошибке.handler-unlock-done: Срабатывает при завершении запроса разблокировки.statusравно 0, если операция разблокировки выполнена успешно, или>0при ошибке.
Для мониторинга блокировки и разблокировки отдельных таблиц можно использовать массивы, а затем вычислять продолжительность всей блокировки таблицы с помощью следующего скрипта:
#!/usr/sbin/dtrace -s
#pragma D option quiet
mysql*:::handler-rdlock-start
{
self->rdlockstart = timestamp;
this->lockref = strjoin(copyinstr(arg0),strjoin("@",copyinstr(arg1)));
self->lockmap[this->lockref] = self->rdlockstart;
printf("Start: Lock->Read %s.%s\n",copyinstr(arg0),copyinstr(arg1));
}
mysql*:::handler-wrlock-start
{
self->wrlockstart = timestamp;
this->lockref = strjoin(copyinstr(arg0),strjoin("@",copyinstr(arg1)));
self->lockmap[this->lockref] = self->rdlockstart;
printf("Start: Lock->Write %s.%s\n",copyinstr(arg0),copyinstr(arg1));
}
mysql*:::handler-unlock-start
{
self->unlockstart = timestamp;
this->lockref = strjoin(copyinstr(arg0),strjoin("@",copyinstr(arg1)));
printf("Start: Lock->Unlock %s.%s (%d ms lock duration)\n",
copyinstr(arg0),copyinstr(arg1),
(timestamp - self->lockmap[this->lockref])/1000000);
}
mysql*:::handler-rdlock-done
{
printf("End: Lock->Read %d ms\n",
(timestamp - self->rdlockstart)/1000000);
}
mysql*:::handler-wrlock-done
{
printf("End: Lock->Write %d ms\n",
(timestamp - self->wrlockstart)/1000000);
}
mysql*:::handler-unlock-done
{
printf("End: Lock->Unlock %d ms\n",
(timestamp - self->unlockstart)/1000000);
}
При выполнении вы получите информацию как о продолжительности процесса блокировки, так и о блокировках на конкретной таблице:
Start: Lock->Read test.t2
End: Lock->Read 0 ms
Start: Lock->Unlock test.t2 (25743 ms lock duration)
End: Lock->Unlock 0 ms
Start: Lock->Read test.t2
End: Lock->Read 0 ms
Start: Lock->Unlock test.t2 (1 ms lock duration)
End: Lock->Unlock 0 ms
Start: Lock->Read test.t2
End: Lock->Read 0 ms
Start: Lock->Unlock test.t2 (1 ms lock duration)
End: Lock->Unlock 0 ms
Start: Lock->Read test.t2
End: Lock->Read 0 ms
5.8.4.1.11 Пробы Filesort
Пробы filesort срабатывают всякий раз, когда операция filesort применяется к таблице. Более подробную информацию о filesort и условиях, при которых она возникает, см. в разделе 8.2.1.14 «Оптимизация ORDER BY».
filesort-start(database, table)
filesort-done(status, rows)filesort-start: Срабатывает при запуске операции filesort для таблицы. Два аргумента пробы,databaseиtable, идентифицируют таблицу, которая сортируется.filesort-done: Срабатывает при завершении операции filesort. Предоставляются два аргумента:status(0 для успеха, 1 для неудачи) и количество отсортированных строк во время процесса filesort.
Пример этого показан в следующем скрипте, который отслеживает продолжительность процесса filesort в дополнение к продолжительности основного запроса:
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("%-2s %-10s %-10s %9s %18s %-s \n",
"St", "Who", "DB", "ConnID", "Dur microsec", "Query");
}
mysql*:::query-start
{
self->query = copyinstr(arg0);
self->who = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
self->db = copyinstr(arg2);
self->connid = arg1;
self->querystart = timestamp;
self->filesort = 0;
self->fsdb = "";
self->fstable = "";
}
mysql*:::filesort-start
{
self->filesort = timestamp;
self->fsdb = copyinstr(arg0);
self->fstable = copyinstr(arg1);
}
mysql*:::filesort-done
{
this->elapsed = (timestamp - self->filesort) /1000;
printf("%2d %-10s %-10s %9d %18d Filesort on %s\n",
arg0, self->who, self->fsdb,
self->connid, this->elapsed, self->fstable);
}
mysql*:::query-done
{
this->elapsed = (timestamp - self->querystart) /1000;
printf("%2d %-10s %-10s %9d %18d %s\n",
arg0, self->who, self->db,
self->connid, this->elapsed, self->query);
}
Выполнение запроса к большой таблице с условием ORDER
BY, которое инициирует filesort, а затем создание индекса в таблице и повторное выполнение того же запроса, позволяют увидеть разницу в скорости выполнения:
St Who DB ConnID Dur microsec Query
0 @localhost test 14 11335469 Filesort on t1
0 @localhost test 14 11335787 select * from t1 order by i limit 100
0 @localhost test 14 466734378 create index t1a on t1 (i)
0 @localhost test 14 26472 select * from t1 order by i limit 100
5.8.4.1.12 Пробы операторов
Индивидуальные пробы операторов предназначены для предоставления конкретной информации о различных типах операторов. Для проб начала предоставляется строка запроса в качестве единственного аргумента. В зависимости от типа оператора, информация, предоставляемая соответствующей пробой завершения, может отличаться. Для всех проб завершения предоставляется статус операции (0 для успеха, >0 для неудачи). Для операций SELECT, INSERT, INSERT ... (SELECT
FROM ...), DELETE и DELETE FROM
t1,t2 возвращается количество изменённых строк.
Для операторов UPDATE и UPDATE t1,t2
... предоставляется количество сопоставленных строк и количество фактически изменённых строк. Это обусловлено тем, что количество строк, фактически сопоставленных соответствующим WHERE условием, и количество изменённых строк могут отличаться. MySQL не обновляет значение строки, если оно уже соответствует новому значению.
select-start(query)
select-done(status,rows)
insert-start(query)
insert-done(status,rows)
insert-select-start(query)
insert-select-done(status,rows)
update-start(query)
update-done(status,rowsmatched,rowschanged)
multi-update-start(query)
multi-update-done(status,rowsmatched,rowschanged)
delete-start(query)
delete-done(status,rows)
multi-delete-start(query)
multi-delete-done(status,rows)select-start: Срабатывает перед операторомSELECT.select-done: Срабатывает в конце оператораSELECT.insert-start: Срабатывает перед операторомINSERT.insert-done: Срабатывает в конце оператораINSERT.insert-select-start: Срабатывает перед операторомINSERT ... SELECT.insert-select-done: Срабатывает в конце оператораINSERT ... SELECT.update-start: Срабатывает перед операторомUPDATE.update-done: Срабатывает в конце оператораUPDATE.multi-update-start: Срабатывает перед операторомUPDATEс участием нескольких таблиц.multi-update-done: Срабатывает в конце оператораUPDATEс участием нескольких таблиц.delete-start: Срабатывает перед операторомDELETE.delete-done: Срабатывает в конце оператораDELETE.multi-delete-start: Срабатывает перед операторомDELETEс участием нескольких таблиц.multi-delete-done: Срабатывает в конце оператораDELETEс участием нескольких таблиц.
Аргументы для проб операторов:
query: Строка запроса.status: Статус запроса.0для успеха и>0для неудачи.rows: Количество строк, затронутых оператором. Возвращает количество найденных строк дляSELECT, количество удалённых строк дляDELETEи количество успешно вставленных строк дляINSERT.rowsmatched: Количество строк, сопоставленных сWHERE-условием оператораUPDATE.rowschanged: Количество фактически изменённых строк во время оператораUPDATE.
Используйте эти пробы для отслеживания выполнения этих типов операторов без необходимости мониторинга пользователя или клиента, выполняющего эти операторы. Простой пример - отслеживание времени выполнения:
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("%-60s %-8s %-8s %-8s\n", "Query", "RowsU", "RowsM", "Dur (ms)");
}
mysql*:::update-start, mysql*:::insert-start,
mysql*:::delete-start, mysql*:::multi-delete-start,
mysql*:::multi-delete-done, mysql*:::select-start,
mysql*:::insert-select-start, mysql*:::multi-update-start
{
self->query = copyinstr(arg0);
self->querystart = timestamp;
}
mysql*:::insert-done, mysql*:::select-done,
mysql*:::delete-done, mysql*:::multi-delete-done, mysql*:::insert-select-done
/ self->querystart /
{
this->elapsed = ((timestamp - self->querystart)/1000000);
printf("%-60s %-8d %-8d %d\n",
self->query,
0,
arg1,
this->elapsed);
self->querystart = 0;
}
mysql*:::update-done, mysql*:::multi-update-done
/ self->querystart /
{
this->elapsed = ((timestamp - self->querystart)/1000000);
printf("%-60s %-8d %-8d %d\n",
self->query,
arg1,
arg2,
this->elapsed);
self->querystart = 0;
}При выполнении можно увидеть основные временные затраты и количество сопоставленных строк:
Query RowsU RowsM Dur (ms)
select * from t2 0 275 0
insert into t2 (select * from t2) 0 275 9
update t2 set i=5 where i > 75 110 110 8
update t2 set i=5 where i < 25 254 134 12
delete from t2 where i < 5 0 0 0
Другой вариант — использование агрегирующих функций в DTrace для агрегации времени выполнения отдельных операторов:
#!/usr/sbin/dtrace -s
#pragma D option quiet
mysql*:::update-start, mysql*:::insert-start,
mysql*:::delete-start, mysql*:::multi-delete-start,
mysql*:::multi-delete-done, mysql*:::select-start,
mysql*:::insert-select-start, mysql*:::multi-update-start
{
self->querystart = timestamp;
}
mysql*:::select-done
{
@statements["select"] = sum(((timestamp - self->querystart)/1000000));
}
mysql*:::insert-done, mysql*:::insert-select-done
{
@statements["insert"] = sum(((timestamp - self->querystart)/1000000));
}
mysql*:::update-done, mysql*:::multi-update-done
{
@statements["update"] = sum(((timestamp - self->querystart)/1000000));
}
mysql*:::delete-done, mysql*:::multi-delete-done
{
@statements["delete"] = sum(((timestamp - self->querystart)/1000000));
}
tick-30s
{
printa(@statements);
}
Приведенный скрипт агрегирует затраченное время на каждую операцию, что может использоваться для тестирования нагрузок.
delete 0
update 0
insert 23
select 2484
delete 0
update 0
insert 39
select 10744
delete 0
update 26
insert 56
select 10944
delete 0
update 26
insert 2287
select 15985
5.8.4.1.13 Пробы сети
Пробы сети отслеживают передачу информации между сервером MySQL и клиентами всех типов по сети. Пробы определяются следующим образом:
net-read-start()
net-read-done(status, bytes)
net-write-start(bytes)
net-write-done(status)net-read-start: Срабатывает при запуске сетевой операции чтения.net-read-done: Срабатывает при завершении операции сетевого чтения.status— этоinteger, представляющий статус возврата операции,0для успеха и1для неудачи. Аргументbytes— целое число, указывающее количество считанных байтов в процессе.net-start-bytes: Срабатывает при записи данных в сетевой сокет. Единственный аргумент,bytes, задаёт количество байтов, записанных в сетевой сокет.net-write-done: Срабатывает при завершении операции сетевой записи. Единственный аргумент,status, — целое число, представляющее статус возврата операции,0для успеха и1для неудачи.
Пробы сети можно использовать для мониторинга времени, затраченного на чтение и запись данных от и к сетевым клиентам во время выполнения. Следующий скрипт D предоставляет пример этого. Вычисляется как кумулятивное время для чтения/записи, так и количество байтов. Обратите внимание, что размер динамической переменной увеличен (с помощью опции dynvarsize) для обработки быстрого срабатывания отдельных проб для сетевых чтений/записей.
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option dynvarsize=4m
dtrace:::BEGIN
{
printf("%-2s %-30s %-10s %9s %18s %-s \n",
"St", "Who", "DB", "ConnID", "Dur microsec", "Query");
}
mysql*:::query-start
{
self->query = copyinstr(arg0);
self->who = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
self->db = copyinstr(arg2);
self->connid = arg1;
self->querystart = timestamp;
self->netwrite = 0;
self->netwritecum = 0;
self->netwritebase = 0;
self->netread = 0;
self->netreadcum = 0;
self->netreadbase = 0;
}
mysql*:::net-write-start
{
self->netwrite += arg0;
self->netwritebase = timestamp;
}
mysql*:::net-write-done
{
self->netwritecum += (timestamp - self->netwritebase);
self->netwritebase = 0;
}
mysql*:::net-read-start
{
self->netreadbase = timestamp;
}
mysql*:::net-read-done
{
self->netread += arg1;
self->netreadcum += (timestamp - self->netreadbase);
self->netreadbase = 0;
}
mysql*:::query-done
{
this->elapsed = (timestamp - self->querystart) /1000000;
printf("%2d %-30s %-10s %9d %18d %s\n",
arg0, self->who, self->db,
self->connid, this->elapsed, self->query);
printf("Net read: %d bytes (%d ms) write: %d bytes (%d ms)\n",
self->netread, (self->netreadcum/1000000),
self->netwrite, (self->netwritecum/1000000));
}При выполнении вышеуказанного скрипта на машине с удалённым клиентом можно увидеть, что примерно треть времени, затрачиваемого на выполнение запроса, связана с отправкой результатов запроса обратно клиенту.
St Who DB ConnID Dur microsec Query
0 root@::ffff:198.51.100.108 test 31 3495 select * from t1 limit 1000000
Net read: 0 bytes (0 ms) write: 10000075 bytes (1220 ms)
5.8.4.1.14 Пробы кэша ключей
Пробы кэша ключей срабатывают при использовании кэша индексных ключей с движком хранения MyISAM. Пробы предназначены для мониторинга момента, когда данные считываются в кэш ключей, кэшированные данные ключей записываются из кэша в кэшированный файл или при доступе к кэшу ключей.
Использование кэша ключей показывает, когда данные считываются или записываются из файлов индексов в кэш, и может использоваться для мониторинга эффективности использования памяти, выделенной для кэша ключей. Большое количество чтений из кэша ключей в различных запросах может указывать на то, что кэш ключей слишком мал для размера данных, к которым осуществляется доступ.
keycache-read-start(filepath, bytes, mem_used, mem_free)
keycache-read-block(bytes)
keycache-read-hit()
keycache-read-miss()
keycache-read-done(mem_used, mem_free)
keycache-write-start(filepath, bytes, mem_used, mem_free)
keycache-write-block(bytes)
keycache-write-done(mem_used, mem_free) При чтении данных из файлов индексов в кэш ключей, процесс сначала инициализирует операцию чтения (указано keycache-read-start), затем загружает блоки данных (keycache-read-block), а затем считанный блок либо соответствует искомым данным (keycache-read-hit), либо требуется чтение дополнительных данных (keycache-read-miss). После завершения операции чтения, чтение останавливается с keycache-read-done.
Данные могут быть считаны из файла индекса в кэш ключей только тогда, когда указанный ключ ещё не находится в кэше ключей.
keycache-read-start: Срабатывает при запуске операции чтения из кэша ключей. Данные считываются из указанногоfilepath, читая указанное количествоbytes.mem_usedиmem_availуказывают на память, в настоящее время используемую кэшем ключей, и количество доступной памяти в кэше ключей.keycache-read-block: Срабатывает, когда кэш ключей считывает блок данных, содержащий указанное количествоbytes, из файла индекса в кэш ключей.keycache-read-hit: Срабатывает, когда блок данных, считанный из файла индекса, соответствует запрошенным данным ключа.keycache-read-miss: Срабатывает, когда блок данных, считанный из файла индекса, не соответствует необходимым данным ключа.keycache-read-done: Срабатывает по завершении операции чтения из кэша ключей.mem_usedиmem_availуказывают на память, в настоящее время используемую кэшем ключей, и количество доступной памяти в кэше ключей.
Запись в кэш ключей происходит, когда информация индекса обновляется во время операции INSERT, UPDATE или DELETE, и кэшированная информация ключа записывается обратно в файл индекса.
keycache-write-start: Срабатывает при запуске операции записи в кэш ключей. Данные записываются в указанныйfilepath, читая указанное количествоbytes.mem_usedиmem_availуказывают на память, в настоящее время используемую кэшем ключей, и количество доступной памяти в кэше ключей.keycache-write-block: Срабатывает, когда кэш ключей записывает блок данных, содержащий указанное количествоbytes, в файл индекса из кэша ключей.keycache-write-done: Срабатывает по завершении операции записи в кэш ключей.mem_usedиmem_availуказывают на память, в настоящее время используемую кэшем ключей, и количество доступной памяти в кэше ключей.
© 2025 Oracle
Licensed under the GPLv2 License.