Почему простой запрос на обновление MySQL иногда занимает несколько минут? - PullRequest
2 голосов
/ 12 февраля 2010

У меня здоровенный сервер БД с множеством очень похожих баз данных InnoDB. Часто выполняемый запрос просто обновляет отметку времени в одной строке небольшой таблицы. В большинстве случаев это занимает 1-2 мс. Иногда, ночью, возможно, во время работы инструментов резервного копирования и репликации maatkit, один или несколько из этих запросов могут отображать «Обновление» в течение нескольких минут. В течение этого времени другие запросы, в том числе запросы maatkit, выполняются нормально, и никакие другие запросы не выполняются. Я не смог объяснить или исправить это.

Мы используем mysql 4.1.22 и gentoo 2.6.21 на паре 4-way Xeon с 16 ГБ ОЗУ и дисками RAID для хранения. Репликация на месте и работает хорошо с maatkit, подтверждающим репликацию каждую ночь. InnoDB использует большую часть оперативной памяти, а процессор обычно на 70-80% простаивает. В рассматриваемой таблице около 100 строк по 200 байт в каждой. Я пробовал с и без индекса в предложении WHERE без заметных изменений. Не найдено необычных сообщений в журнале (проверены системные сообщения и ошибки mysql).

Кто-нибудь еще слышал об этом? Решено как то так? Есть идеи как исследовать?

Ответы [ 3 ]

1 голос
/ 12 февраля 2010

При выполнении операций DML InnoDB устанавливает блокировки на строки и пробелы в индексах.

Проблема в том, что он блокирует все проверенные строки , а не только те, затронутые .

Скажите, если вы выполните этот запрос:

UPDATE  mytable
SET     value = 10
WHERE   col1 = 1
        AND col2 = 2

, блокировка будет зависеть от индексов, используемых для запроса:

  • Если использовался индекс на col1, col2, блокируются только затронутые строки

  • Если использовался индекс для col, все строки с col1 = 1 будут заблокированы

  • Если использовался индекс для col2, все строки с col2 = 2 будут заблокированы

  • Если индекс не использовался, все строки и пропуски индекса будут заблокированы (в том числе в PRIMARY KEY, так что даже от INSERT до AUTO_INCREMENT столбца будет заблокировано)

Что еще хуже, EXPLAIN в MySQL не работает с DML операциями, поэтому вам придется угадывать, какой индекс использовался, так как оптимизатор может выбрать любой, если сочтет его лучшим.

Возможно, ваши инструменты репликации и обновления одновременно блокируют записи (и, как вы можете видеть, это может произойти, даже если условия WHERE не перекрываются).

0 голосов
/ 26 февраля 2010

Используя некоторую информацию, представленную в ответах, мы продолжили расследование и обнаружили на нашем сервере некоторое тревожное поведение. Простая «контрольная таблица» в любой таблице в любой базе данных вызвала блокировку простых запросов на обновление в других базах данных и других таблицах. Я понятия не имею, почему это произойдет, хотя мы не смогли воспроизвести его на MySQL v5.1, поэтому мы намерены обновить наш сервер базы данных.

Я не думаю, что mk-таблица-контрольная сумма maatkit делает "контрольную таблицу", но она имеет аналогичный эффект. Отключение этого сценария значительно уменьшило проблемы, но мы считаем, что мы не можем жить без этого сценария.

Я собираюсь отметить это как ответ на мой вопрос. Спасибо за помощь.

0 голосов
/ 12 февраля 2010

Если вы можете попасть на сервер, пока этот запрос зависает, попробуйте выполнить «show innodb status». Часть беспорядка данных, который вы получаете, это состояние всех активных соединений / запросов в таблицах InnoDB. Если ваш запрос зависает из-за другой транзакции, он будет указан там. Здесь есть образцы данных блокировки здесь .

Кроме того, вы упоминаете, что, кажется, происходят резервные копии во время резервного копирования. Вы используете mysqldump для этого? Это будет блокировать таблицы, пока дамп активен, так что сбрасываемые данные являются согласованными.

...