Ярлыки: Статьи официального аккаунта
Что происходит, когда ключ автоинкремента израсходован?
Когда мы строим таблицу, мы устанавливаем столбец индекса (Примечание. Должен быть индексным столбцом.)Добавить кAUTO_INCREMENT
свойства, например:
CREATE TABLE t (
c1 TINYINT AUTO_INCREMENT,
c2 TINYINT,
KEY idx_c1 (c1)
) ENGINE=InnoDB;
поверхностьt
содержит столбец индексаc1
, столбец добавленAUTO_INCREMENT
Атрибуты. Сначала вставляем запись в таблицу:
mysql> INSERT INTO t(c1, c2) VALUES(126, 1);
Query OK, 1 row affected (0.02 sec)
После этого мы больше неINSERT
Явно вставляется в операторc1
Значение столбца, его значение по умолчанию будет увеличено с текущего вставленного наибольшего значения, например:
mysql> INSERT INTO t(c2) VALUES(1);
Query OK, 1 row affected (0.01 sec)
Давайте посмотрим на это расписаниеt
данные в:
mysql> SELECT * FROM t;
+-----+------+
| c1 | c2 |
+-----+------+
| 126 | 1 |
| 127 | 1 |
+-----+------+
2 rows in set (0.02 sec)
так какc1
столбецTINYINT
Введите, используя 1 байт для хранения данных, максимальное значение, которое он может хранить, равно127
, если когда значение столбца достигает127
После этого продолжаем вставлять данные в таблицу, автоинкрементируя столбцыc1
Какова будет стоимость?
mysql> INSERT INTO t(c2) VALUES(1);
Query OK, 1 row affected (0.01 sec)
После успешной вставки посмотрим на данные в таблице:
mysql> SELECT * FROM t;
+-----+------+
| c1 | c2 |
+-----+------+
| 126 | 1 |
| 127 | 1 |
| 127 | 1 |
+-----+------+
3 rows in set (0.01 sec)
Очевидно, автоинкрементc1
Значение больше не будет продолжать расти, но возьметTINYINT
Максимальное значение, которое можно сохранить.
Здесь следует отметить, что в текущем примере мы просто автоматически увеличиваемc1
Общий вторичный индекс установлен вышеidx_c1
, поэтому нет проблем с повторяющимися значениями ключей. Однако мы, как правило,AUTO_INCREMENT
Атрибут применяется к первичному ключу таблицы.В это время, если значение столбца автоинкремента достигает максимального значения, которое может быть сохранено типом данных, соответствующим первичному ключу, будет сообщено об ошибке (поскольку значение первичного ключа повторяется), все должны быть внимательны!
Что происходит, когда row_id заканчивается?
в нашем использованииInnoDB
Когда механизм хранения создает таблицу, если мы не создадим первичный ключ явно, механизм хранения найдетNOT NULL
Столбец уникального вторичного индекса атрибута действует как первичный ключ, если мы не пишем таблицу сNOT NULL
Единственный вторичный столбец индекса для атрибута, извините, механизм хранения добавит нам новый по умолчанию с именемrow_id
столбец первичного ключа.
этоrow_id
Размер столбца по умолчанию составляет 6 байт, стоит отметить, что дизайнInnoDB
Дядя не для каждой пользовательской таблицы, которая явно не создает первичный ключrow_id
Столбцы поддерживают отдельный счетчик, но все таблицы совместно используют глобальный счетчик. Допустим, у нас нет соответствующей таблицыt1
иt2
Явно создайте первичные ключи, механизм хранения создаст один для них обоих.row_id
столбец, если мы добавим таблицуt1
В таблицу вставляется запись, затем из глобального счетчика выделяется значение, чтобы сделать таблицуrow_id
значение столбца, затем увеличиваем глобальный счетчик на 1, затем добавляем в таблицуt2
Вставьте запись в таблицу, затем присвойте значение из глобального счетчика, чтобы сделать таблицуrow_id
значение столбца, а затем увеличить глобальный счетчик на 1.
У многих студентов возникают сомнения, что произойдет, если значение этого глобального счетчика превысит максимальное значение, которое может быть представлено 6 байтами?
Ха-ха 😄, не так. Несмотря на то чтоrow_id
состоит из 6 байт, но конструкцияInnoDB
Дядя использует 8 байт для хранения значения глобального счетчика, и они записывают эти 8 байт за два разаrow_id
, первые четыре байта справа записываются вrow_id
4 байта справа, затем запишите 4 байта слеваrow_id
2 байта слева, вот так:
Затем запишите четыре байта слева от глобального счетчика.row_id
2 байта слева
При использовании следующей функции:
UNIV_INLINE
void
mach_write_to_2(
/*============*/
byte* b, /*!< in: pointer to two bytes where to store 也就是row_id值前2个字节所在的内存地址*/
ulint n) /*!< in: ulint integer to be stored 也就是全局计数器的左4个字节值*/
{
ut_ad(b);
ut_ad((n | 0xFFFFUL) <= 0xFFFFUL);
b[0] = (byte)(n >> 8);
b[1] = (byte)(n);
}
Вы можете увидеть эту строку в коде:
ut_ad((n | 0xFFFFUL) <= 0xFFFFUL);
Это функция утверждения, эта строка кода означает левое 4-байтовое значение глобального счетчика.n
Оно не должно быть больше максимального значения, которое может храниться в 2 байтах, иначе ассертерия завершится ошибкой, и тогда MySQL будет зависать, зависать и зависать~
То есть, еслиrow_id
После того, как он израсходуется, MySQL зависнет, и такая программа зависнет сразу.Но 6 байт достаточно.Вы можете посчитать, сколько записей нужно вставить, если вы хотите, чтобы MySQL завис?
Ссылки на другие статьи
Сверхполноценный анализ блокировки операторов MySQL (Часть 1)
Сверхполноценный анализ блокировки операторов MySQL (Часть 2)
Сверхполноценный анализ блокировки операторов MySQL (Часть 2)
Не по теме
Написание статей очень утомительно, и иногда вы чувствуете, что чтение идет очень гладко, что на самом деле является результатом бесчисленных правок за ним. Если вы думаете, что это хорошо, пожалуйста, помогите переслать его.Большое спасибо~ Вот мой публичный аккаунт "Мы все маленькие лягушки".