Spec-Zone.ru › MySQL 8.4

10.11.2 Проблемы блокировки таблиц

Таблицы InnoDB используют блокировку на уровне строк, чтобы несколько сессий и приложений могли одновременно читать и записывать в одну таблицу, не ожидая друг друга и не получая несогласованных результатов. Для этого хранилища избегайте использования оператора LOCK TABLES, потому что он не предлагает дополнительной защиты, но вместо этого снижает конкуреность. Автоматическая блокировка на уровне строк делает эти таблицы подходящими для самых загруженных баз данных с наиболее важной данными, а также упрощает логику приложения, так как вам не нужно блокировать и разблокировать таблицы. Вследствие этого, хранилище InnoDB является по умолчанию в MySQL.

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

  • Критерии производительности в пользу InnoDB

  • Обходные пути для проблем с производительностью блокировки

Критерии производительности в пользу InnoDB

При выборе создания таблицы с помощью InnoDB или другого хранилища, учтите следующие недостатки блокировки таблиц:

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

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

  • Оператор SELECT, который выполняется долго, препятствует обновлению таблицы другими сессиями в это время, заставляя другие сессии казаться медленными или не реагирующими. Пока сессия ожидает получения эксклюзивного доступа к таблице для обновлений, другие сессии, которые выдают операторы SELECT, встают в очередь за ней, что снижает конкуреность даже для сессий только для чтения.

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

Следующие пункты описывают некоторые способы избежать или уменьшить конфликт, вызванный блокировкой таблиц:

  • Рассмотрите возможность переключения таблицы на хранилище InnoDB, либо используя CREATE TABLE ... ENGINE=INNODB во время настройки, либо используя ALTER TABLE ... ENGINE=INNODB для существующей таблицы. Подробнее о этом хранилище см. Главу 17, Хранилище InnoDB.

  • Оптимизируйте операторы SELECT для более быстрого выполнения, чтобы они блокировали таблицы на более короткое время. Возможно, потребуется создать некоторые сводные таблицы.

  • Запустите mysqld с --low-priority-updates. Для хранилищ, которые используют только блокировку на уровне таблиц (таких как MyISAM, MEMORY и MERGE), это даёт всем операторам обновления (модификации) таблицы более низкий приоритет, чем операторам SELECT. В этом случае, второй оператор SELECT в приведенном выше сценарии будет выполняться до оператора UPDATE и не будет ждать завершения первого оператора SELECT.

  • Чтобы указать, что все обновления, выданные в определенном соединении, должны выполняться с низким приоритетом, установите переменную серверной системы low_priority_updates равной 1.

  • Чтобы присвоить более низкий приоритет конкретному оператору INSERT, UPDATE или DELETE, используйте атрибут LOW_PRIORITY.

  • Чтобы присвоить более высокий приоритет конкретному оператору SELECT, используйте атрибут HIGH_PRIORITY. См. Раздел 15.2.13, «Оператор SELECT».

  • Запустите mysqld со значением переменной системы max_write_lock_count для принудительного повышения приоритета всех операторов SELECT, которые ожидают таблицу после определенного количества записей в блоки таблиц (например, для операций вставки). Это позволяет использовать блоки чтения после определенного количества записей в блоки.

  • Если у вас есть проблемы с смешанными операторами SELECT и DELETE, опция LIMIT для оператора DELETE может помочь. См. Раздел 15.2.2, «Оператор DELETE».

  • Использование SQL_BUFFER_RESULT с операторами SELECT может помочь сделать продолжительность блокировок таблиц короче. См. Раздел 15.2.13, «Оператор SELECT».

  • Разделение содержимого таблицы на отдельные таблицы может помочь, разрешая запросы к столбцам в одной таблице, в то время как обновления ограничиваются столбцами в другой таблице.

  • Вы могли бы изменить код блокировки в mysys/thr_lock.c, чтобы использовать одну очередь. В этом случае блокировки записи и блокировки чтения имели бы одинаковый приоритет, что могло бы помочь некоторым приложениям.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/table-locking.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API