Spec-Zone .ru
спецификации, руководства, описания, API
|
Как описано в предыдущем разделе, 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
параметр конфигурации, который можно установить при запуске сервера. Дополнительные соображения описываются
после объяснения автоинкрементного поведения при блокировании.
Во-первых, некоторые определения:
"INSERT
- как" операторы
Все операторы, которые генерируют новые строки в таблице, включая INSERT
, INSERT ... SELECT
, REPLACE
, REPLACE
... SELECT
, и LOAD
DATA
.
"Простые вставки"
Операторы, для которых число строк, которые будут вставлены, может быть определено заранее (когда
оператор первоначально обрабатывается). Это включает единственную строку и многократную строку INSERT
и REPLACE
операторы, у которых нет вложенного подзапроса, но нет INSERT ... ON DUPLICATE KEY UPDATE
.
"Объем вставляет"
Операторы, которыми число строк, которые будут вставлены (и число необходимых автоинкрементных
значений), не известно заранее. Это включает INSERT ... SELECT
, REPLACE ... SELECT
, и LOAD DATA
операторы, но не плоскость INSERT
. InnoDB
присвоит новые значения
для AUTO_INCREMENT
столбец по одному как каждая строка обрабатывается.
"Смешанный режим вставляет"
Они - "простая вставка" операторы,
которые определяют автоинкрементное значение для некоторых (но не все) новых строк. Пример следует,
где c1
AUTO_INCREMENT
столбец таблицы
t1
:
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
Другой тип "смешанного режима вставляет", INSERT ... ON DUPLICATE KEY UPDATE
, который в худшем случае является
в действительности INSERT
сопровождаемый a UPDATE
, где выделенное значение для AUTO_INCREMENT
столбец может или не может использоваться во время фазы обновления.
Есть три возможных настройки для innodb_autoinc_lock_mode
параметр:
innodb_autoinc_lock_mode = 0
("традиционный" режим блокировки)
Этот режим блокировки обеспечивает то же самое поведение как прежде innodb_autoinc_lock_mode
существовавший. Для всех"INSERT
- как" операторы, специальное предложение,
на уровне таблицы AUTO-INC
блокировка получена и сохранена до конца
оператора. Это гарантирует, что автоинкрементные значения, присвоенные любым данным оператором,
последовательны.
Этот режим блокировки предусматривается:
Обратная совместимость.
Тестирование производительности.
Работа вокруг проблем со "смешанным режимом вставляет", из-за возможных различий в семантике, описанной позже.
innodb_autoinc_lock_mode = 1
("последовательный" режим блокировки)
Это - режим блокировки значения по умолчанию. В этом режиме, "объем вставляет" использование специальное предложение AUTO-INC
блокировка на уровне таблицы и содержит это до конца оператора.
Это применяется ко всем INSERT
... SELECT
, REPLACE ...
SELECT
, и LOAD
DATA
операторы. Только один оператор, содержащий AUTO-INC
блокировка может выполниться за один раз.
С этим режимом блокировки, "простые вставки"
(только) используют новую модель блокировки, где легкое взаимное исключение используется во время
выделения автоинкрементных значений, и не на уровне таблицы AUTO-INC
блокировка не используется, если AUTO-INC
блокировка сохранена другой
транзакцией. Если другая транзакция действительно содержит AUTO-INC
блокировка, "простая вставка"
ожидает AUTO-INC
блокировка, как будто это также была "объемная вставка".
Этот режим блокировки гарантирует это, в присутствии INSERT
операторы, где число строк не известно заранее (и где
автоинкрементные числа присваиваются как, оператор прогрессирует), все автоинкрементные значения,
присвоенные любым"INSERT
- как" оператор последовательны, и
операции безопасны для основанной на операторе репликации.
Проще говоря, важное воздействие этого режима блокировки является значительно лучшей масштабируемостью. Этот режим безопасен для использования с основанной на операторе репликацией. Далее, как с "традиционным" режимом блокировки, автоинкрементные числа, присвоенные любым данным оператором, последовательны. В этом режиме нет никакого изменения в семантике по сравнению с "традиционным" режимом ни для какого оператора, который использует автоинкремент с одним важным исключением.
Исключение для "смешанного режима, вставляет",
где пользователь обеспечивает явные значения для AUTO_INCREMENT
столбец
для некоторых, но не всех, строк в многократной строке "простая вставка". Для таких вставок, InnoDB
выделит больше автоинкрементных значений чем число строк, которые будут вставлены. Однако, все
значения, автоматически присвоенные, последовательно сгенерированы (и таким образом выше чем)
автоинкрементное значение, сгенерированное последний раз выполняемым предыдущим оператором. Теряются "Избыточные" числа.
innodb_autoinc_lock_mode = 2
("чередованный" режим блокировки)
В этом режиме блокировки, нет"INSERT
- как" операторы используют на уровне
таблицы AUTO-INC
блокировка, и многократные операторы могут выполниться
одновременно. Это является самым быстрым и большинство масштабируемого режима блокировки, но не
безопасно при использовании основанных на операторе сценариев
репликации или восстановления, когда SQL-операторы воспроизводятся от двоичного журнала.
В этом режиме блокировки автоинкрементные значения, как гарантируют, будут уникальны и монотонно
увеличивающимися через все одновременно выполнение"INSERT
- как" операторы. Однако, потому что
многократные операторы могут генерировать числа одновременно (то есть, выделение чисел чередуется через операторы), значения, сгенерированные для
строк, вставленных любым данным оператором, возможно, не последовательны.
Если единственное выполнение операторов является "простыми вставками", где число строк, которые будут вставлены, знается заранее, не будет никаких разрывов в числах, сгенерированных для единственного оператора, за исключением "смешанного режима вставляет". Однако, когда "объем вставляет", выполняются, могут быть разрывы в автоинкрементных значениях, присвоенных любым данным оператором.
Режимы блокировки автоинкремента, обеспеченные innodb_autoinc_lock_mode
имейте несколько импликаций использования:
Используя автоинкремент с репликацией
Если Вы используете основанную на операторе репликацию, набор innodb_autoinc_lock_mode
к 0 или 1 и использование то же самое
значение на ведущем устройстве и его ведомых устройствах. Автоинкрементные значения не
обеспечиваются, чтобы быть тем же самым на ведомых устройствах как на ведущем устройстве, если Вы
используете innodb_autoinc_lock_mode
= 2 ("чередованный") или конфигурации, где ведущее
устройство и ведомые устройства не используют тот же самый режим блокировки.
Если Вы используете построчную репликацию, все автоинкрементные режимы блокировки безопасны. Построчная репликация не чувствительна к порядку выполнения SQL-операторов.
"Потерянные" автоинкрементные значения и разрывы последовательности
Во всех режимах блокировки (0, 1, и 2), если транзакция, которая генерировала автоинкрементные
значения, откатывает, "теряются" те
автоинкрементные значения. Как только значение сгенерировано для столбца автоприращения, оно не может откатываться, действительно ли"INSERT
- как" оператор завершается, и откатывается ли содержание транзакции. Такие потерянные значения не снова используются. Таким образом могут быть разрывы в значениях, сохраненных в AUTO_INCREMENT
столбец таблицы.
Разрывы в автоинкрементных значениях для "объема вставляют"
С innodb_autoinc_lock_mode
набор к 0 ("традиционный") или 1
("последовательный"),
автоинкрементные значения, сгенерированные любым данным оператором, будет последователен, без
разрывов, потому что на уровне таблицы AUTO-INC
блокировка сохранена,
пока конец оператора, и только одного такого оператора не может выполниться за один раз.
С innodb_autoinc_lock_mode
набор к 2 ("чередованный"), может
быть разрывами в автоинкрементных значениях, сгенерированных "объемом, вставляет," но только если там одновременно
выполняются"INSERT
- как" операторы.
Для режимов блокировки 1 или 2, разрывы могут произойти между последовательными операторами, потому что для объема вставляет точное число автоинкрементных значений, требуемых каждым оператором, возможно, не известен, и переоценка возможна.
Автоинкрементные значения, присвоенные "смешанным режимом, вставляют"
Полагайте, что "смешанный режим вставляет,",
где "простая вставка" определяет
автоинкрементное значение для некоторых (но не все) получающиеся строки. Такой оператор будет вести
себя по-другому в режимах блокировки 0, 1, и 2. Например, принять c1
AUTO_INCREMENT
столбец таблицы t1
, и что
новый автоматически сгенерированный порядковый номер 100. Полагайте, что следующий "смешанный режим вставляет"
оператор:
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
С innodb_autoinc_lock_mode
набор к 0 ("традиционный"), четыре
новых строки будут:
+-----+------+| c1 | c2 |+-----+------+| 1 | a || 101 | b || 5 | c || 102 | d |+-----+------+
Следующее доступное автоинкрементное значение будет 103, потому что автоинкрементные значения
выделяются по одному, не внезапно в начале выполнения оператора. Этим результатом является истина,
выполняются ли там одновременно"INSERT
- как" операторы (любого типа).
С innodb_autoinc_lock_mode
набор к 1 ("последовательный"),
четыре новых строки также будут:
+-----+------+| c1 | c2 |+-----+------+| 1 | a || 101 | b || 5 | c || 102 | d |+-----+------+
Однако, в этом случае, следующее доступное автоинкрементное значение будет 105, не 103, потому что
четыре автоинкрементных значения выделяются в то время, когда оператор обрабатывается, но только два
используются. Этим результатом является истина, выполняются ли там одновременно"INSERT
- как"
операторы (любого типа).
С innodb_autoinc_lock_mode
набор к режиму 2 ("чередованный"),
четыре новых строки будут:
+-----+------+| c1 | c2 |+-----+------+| 1 | a ||x
| b || 5 | c ||y
| d |+-----+------+
Значения x
и y
будет уникальным и больше чем любые ранее сгенерированные строки. Однако, определенные значения x
и y
будет
зависеть от числа автоинкрементных значений, сгенерированных, одновременно выполняя операторы.
Наконец, рассмотрите следующее заявление, сделанное, когда последний раз сгенерированный порядковый номер был значением 4:
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
С любым innodb_autoinc_lock_mode
устанавливая, этот оператор генерирует
двойную ключевую ошибку 23000 (Can't write; duplicate key in table
)
потому что 5 будет выделен для строки (NULL, 'b')
и вставка строки
(5, 'c')
перестанет работать.