MySQL читает / пишет в таблице

8

Я оптимизирую нашу БД. По сути, я пытаюсь найти наиболее написанные и наиболее читаемые таблицы в нашей базе данных. После этого я приведу символическую связь этих таблиц в отдельные диски.

Есть ли способ следить за каждым действием таблицы? Как в IOPS следовать, пишет, читает в таблице?

Katafalkas
источник

Ответы:

10

Способ 1

Если вы используете Percona Server или MariaDB (> = 5.2), вы можете просто установить переменную userstat / userstat_running, чтобы включить кучу новых таблиц INFORMATION_SCHEMA, включая таблицу с именем TABLE_STATISTICS, которая предоставляет именно эту информацию.

Например:

mysql> SELECT TABLE_NAME, ROWS_READ, ROWS_CHANGED, ROWS_CHANGED_X_INDEXES FROM TABLE_STATISTICS ORDER BY ROWS_CHANGED DESC LIMIT 5;
+-------------------+------------+--------------+------------------------+
| TABLE_NAME        | ROWS_READ  | ROWS_CHANGED | ROWS_CHANGED_X_INDEXES |
+-------------------+------------+--------------+------------------------+
| user              |   21122527 |      5989231 |               23956924 |
| audit             |       1208 |      5020929 |               20083716 |
| sometemp          |   13995426 |      3182150 |                9546450 |
| creditcards       |    3566482 |      2998976 |               11995904 |
| order             | 2147483647 |      2662606 |               53252120 |
+-------------------+------------+--------------+------------------------+

ROWS_CHANGED будет соответствовать наиболее записанным в таблицы, а ROWS_READ будет наиболее читаемым из. Вам также следует взглянуть на INDEX_STATISTICS, чтобы найти ваши наиболее и наименее используемые индексы.

Смотрите также документацию статистики пользователя MariaDB .

Способ 2

Если вы не используете Percona Server, вы можете использовать pt-query-digest для захвата образца ваших запросов, а затем отфильтровывать только INSERT / UPDATE / DELETE. Это будет выглядеть примерно так:

mysql> SELECT @@GLOBAL.slow_query_log_file;
+------------------------------------------+
| @@GLOBAL.slow_query_log_file             |
+------------------------------------------+
| /var/logs/mysql/slowquery.log            |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL slow_query_log_file='/tmp/allqueries.log';
mysql> SELECT @@GLOBAL.long_query_time;
+--------------------------+
| @@GLOBAL.long_query_time |
+--------------------------+
|                 0.250000 |
+--------------------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL long_query_time = 0;
mysql> FLUSH LOGS;
mysql> SLEEP 600; SET GLOBAL long_query_time = 0.25; SET GLOBAL slow_query_log_file='/var/logs/mysql/slowquery.log'; FLUSH LOGS;

Теперь у вас есть файл, /tmp/allqueries.logкоторый содержит каждый запрос, выполненный на вашем сервере в течение ~ 10 минут.

Затем проанализируйте его с помощью pt-query-digest, чтобы получить наиболее часто записываемые таблицы:

pt-query-digest /tmp/allqueries.log --group-by=distill --filter '$event->{arg} =~ m/^(update|delete|insert)/i' --limit 5 > /tmp/writes.txt

Если вы посмотрите /tmp/writes.txt, вы увидите раздел в верхней части, который выглядит следующим образом:

# Profile
# Rank Query ID Response time Calls R/Call Apdx V/M   Item
# ==== ======== ============= ===== ====== ==== ===== ====================
#    1 0x        0.0558 26.8%   282 0.0002 1.00  0.00 INSERT UPDATE user
#    2 0x        0.0448 21.5%   246 0.0002 1.00  0.00 UPDATE audit
#    3 0x        0.0228 10.9%    11 0.0021 1.00  0.00 UPDATE sometemp
#    4 0x        0.0108  5.2%    16 0.0007 1.00  0.00 UPDATE creditcards
#    5 0x        0.0103  4.9%    43 0.0002 1.00  0.00 UPDATE order

Грубо говоря, это ваши самые записанные таблицы за время выбранной вами выборки. Чтобы получить наибольшее чтение из таблиц (примерно), вы можете изменить --filterпараметр на, --filter '$event->{arg} =~ m/^select/i'и вы увидите похожий вывод.

Если вас интересуют только записи, вы можете передать двоичный журнал pt-query-digestи получить аналогичные результаты:

mysqlbinlog mysql-bin.000511 | pt-query-digest --type=binlog --group-by=distill > /tmp/writes.txt

Вы также можете получить те же данные с помощью tcpdump и pt-query-digest --type=tcpdump

Так что, как говорится, предполагая, что вы используете таблицы InnoDB, я очень сомневаюсь, что вы вообще получите большую выгоду от производительности. Из-за того, что данные буферизируются в журнал InnoDB и затем записываются на диск, я не ожидал бы значительного или какого-либо выигрыша в производительности от перемещения отдельных таблиц таким образом. Вы можете увидеть некоторую выгоду от перемещения самих файлов журналов InnoDB на отдельный, более быстрый диск, чтобы отделить чтение / запись журнала от чтения / записи табличного пространства, но даже это сомнительно. Инвестиции в быстрые, высококачественные RAID-массивы с кэш-памятью с батарейным питанием (или, еще лучше, SSD) будут более эффективным использованием ваших ресурсов.

Аарон Браун
источник
кэш с резервным питанием от батареи - не могли бы вы дать мне какую-нибудь ссылку, чтобы изучить их подробнее?
Катафалкас
en.wikipedia.org/wiki/RAID было бы хорошим началом. RAID10 обычно превосходит RAID5 или 6 для баз данных.
Аарон Браун