Что такое упорядочение очереди ожидания блокировки метаданных таблицы Mysql - PullRequest
0 голосов
/ 06 июня 2018

У меня есть несколько соединений, выполняющих SELECT внутри транзакции, и одно, выполняющее DDL.В руководстве по mysql довольно ясно сказано, как блокировка метаданных используется в транзакциях:

Чтобы обеспечить сериализуемость транзакций, сервер не должен разрешать одному сеансу выполнять инструкцию языка определения данных (DDL) для таблицыэто используется в незавершенной явно или неявно запущенной транзакции в другом сеансе.Сервер достигает этого, получая блокировки метаданных для таблиц, используемых в транзакции, и откладывая освобождение этих блокировок до завершения транзакции.Блокировка метаданных на таблице предотвращает изменения в структуре таблицы.Этот подход к блокировке подразумевает, что таблица, используемая транзакцией в рамках одного сеанса, не может использоваться в выражениях DDL другими сеансами до тех пор, пока транзакция не завершится.

Это имеет смысл, поэтому я сделал этоtest:

connectionA$ begin;
connectionA$ select * from facebook_authorizations;
connectionA$ ....
connectionB$ alter table facebook_authorizations add column foo int default null;
connectionC$ begin;
connectionC$ select * from facebook_authorizations;
connectionA$ commit;

В моей системе, когда connectionA фиксирует, выполняется connectionC, а connectionB все еще зависает: он не может выполнить переходы на основе SELECT.Я ожидал, что список ожидания блокировки метаданных будет обработан примерно в порядке FIFO, но это не так.

Есть ли документация о порядке обработки очереди ожидания метаданных?

1 Ответ

0 голосов
/ 15 октября 2018

Для подробностей о сценарии:

Пытаясь воспроизвести случай, я заблокировал сеанс B, а затем заблокировал сеанс C ... Обратите внимание, что если сеанс B действительно ожидал чего-то другого раньшеполучая блокировку метаданных для таблицы, сеанс C не имеет причин ждать.

Теперь в общем:

Уже предоставленные блокировки метаданных видны в performance_schema, в таблице metadata_locks, с LOCK_STATUS как GRANTED.

См. документ: https://dev.mysql.com/doc/refman/8.0/en/metadata-locks-table.html

Это полезно, чтобы увидеть, какой сессии принадлежит какая блокировка.

Метаданные блокируютожидающие сеансы также видны в той же таблице, с LOCK_STATUS как PENDING.

Это полезно, чтобы увидеть что сеанс ожидает.

(заблокированный) сеанс ожидает блокировки чего-либо, что, в свою очередь, может быть уже заблокировано (с различными LOCK_TYPE и LOCK_DURATION) другими сеансами, но прямой связи «Сессия X ожидает сеанса Y» нет.здесь подразумевается, что замок уже установлен.

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

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

...