Spec-Zone .ru
спецификации, руководства, описания, API

5.4.4.2. Конфигурируемый InnoDB Автоинкрементная Блокировка

Как описано в предыдущем разделе, InnoDB использует специальную блокировку, названную на уровне таблицы AUTO-INC блокировка для вставок в таблицы с AUTO_INCREMENT столбцы. Эта блокировка, как обычно сохранилось, до конца оператора (не до конца транзакции), гарантирует, что автоинкрементные числа присваиваются в предсказуемом и повторимом порядке на данную последовательность INSERT операторы.

В случае основанной на операторе репликации это означает, что, когда SQL-оператор тиражируется в ведомый сервер, те же самые значения используются для столбца автоприращения в качестве на главном сервере. Результат выполнения многократных INSERT операторы детерминированы, и ведомое устройство воспроизводит те же самые данные как на ведущем устройстве. Если автоинкрементные значения, сгенерированные многократным INSERT операторы были чередованы, результат два параллельный INSERT операторы были бы недетерминированы, и не могли достоверно быть распространены к ведомому серверу, используя основанную на операторе репликацию.

Чтобы ясно дать понять это, рассмотрите пример, который использует эту таблицу:

CREATE TABLE t1 (  c1 INT(11) NOT NULL AUTO_INCREMENT,  c2 VARCHAR(10) DEFAULT NULL,  PRIMARY KEY (c1)) ENGINE=InnoDB;

Предположите, что есть два выполнения транзакций, каждая вставка строки в таблицу с AUTO_INCREMENT столбец. Одна транзакция использует INSERT ... SELECT оператор, который вставляет 1000 строк, и другой использует простое INSERT оператор, который вставляет одну строку:

Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ...Tx2: INSERT INTO t1 (c2) VALUES ('xxx');

InnoDB не может сказать заранее, сколько строк будет получено от SELECT в INSERT оператор в Tx1, и это присваивает автоинкрементные значения по одному, поскольку оператор продолжается. С блокировкой на уровне таблицы, сохраненной до конца оператора, только одного INSERT оператор, обращающийся к таблице t1 может выполниться за один раз, и генерация автоинкрементных чисел различными операторами не чередуется. Автоинкрементное значение сгенерировано Tx1 INSERT ... SELECT оператор будет последователен, и (единственное) автоинкрементное значение, используемое INSERT оператор в Tx2 или будет меньшим или больше чем все используемые для Tx1, в зависимости от которого оператор выполняется сначала.

Пока SQL-операторы выполняются в том же самом порядке когда воспроизводящийся от двоичного журнала (при использовании основанной на операторе репликации, или в сценариях восстановления), результатами будет то же самое, как они были то, когда Tx1 и Tx2 сначала работали. Таким образом блокировки на уровне таблицы, сохраненные до конца оператора, делают INSERT операторы используя автоинкрементный сейф для использования с основанной на операторе репликацией. Однако, те блокировки ограничивают параллелизм и масштабируемость, когда многократные транзакции выполняются, вставляют операторы одновременно.

В предыдущем примере, если не было никакой блокировки на уровне таблицы, значения столбца автоприращения, используемого для INSERT в Tx2 зависит от точно, когда оператор выполняется. Если INSERT из Tx2 выполняется в то время как INSERT из Tx1 работает (а не прежде, чем он запустится или после того, как он завершается), определенные автоинкрементные значения, присвоенные двумя INSERT операторы недетерминированы, и могут измениться от выполненного, чтобы работать.

InnoDB может избегать использования на уровне таблицы AUTO-INC блокировка для class INSERT операторы, где число строк известно заранее, и все еще сохраняет детерминированное выполнение и безопасность для основанной на операторе репликации. Далее, если Вы не используете двоичный журнал, чтобы воспроизвести SQL-операторы как часть восстановления или репликации, можно полностью устранить использование на уровне таблицы AUTO-INC блокировка для еще большего параллелизма и производительности, за счет разрешения разрывов в автоинкрементных числах, присвоенных оператором и потенциально присвоением чисел, одновременно выполняя операторы, чередуется.

Для INSERT операторы, где число строк, которые будут вставлены, известно в начале обработки оператора, InnoDB быстро выделяет необходимое число автоинкрементных значений, не беря блокировки, но только если нет никакого параллельного сеанса, уже содержащего на уровне таблицы AUTO-INC блокировка (потому что тот другой оператор будет выделять автоинкрементные значения один за другим, поскольку это продолжается). Более точно, такой INSERT оператор получает автоинкрементные значения под управлением взаимного исключения (легкая блокировка), который не сохранен, пока оператор не завершается, но только для продолжительности процесса выделения.

Эта новая схема блокировки включает намного большей масштабируемости, но это действительно представляет некоторые тонкие различия в том, как автоинкрементные значения присваиваются по сравнению с исходным механизмом. Чтобы описать путь, автоинкремент работает в InnoDB, следующее обсуждение дает определение некоторым словам, и объясняет как InnoDB ведет себя используя различные настройки innodb_autoinc_lock_mode параметр конфигурации, который можно установить при запуске сервера. Дополнительные соображения описываются после объяснения автоинкрементного поведения при блокировании.

Во-первых, некоторые определения:

Есть три возможных настройки для innodb_autoinc_lock_mode параметр:

Режимы блокировки автоинкремента, обеспеченные innodb_autoinc_lock_mode имейте несколько импликаций использования: