Что происходит, когда auto_increment на целочисленном столбце достигает max_value в базах данных?
Я использую приложение базы данных, и я буду использовать как базу данных JavaDB, так и MySQL. У меня есть столбец идентификатора в моих таблицах, который имеет целочисленный тип, и я использую функцию auto_increment-functions для значения.
Но что происходит, когда я получаю более 2 (или 4) миллиардов сообщений и целого числа, недостаточно? Является ли целое число переполненным и продолжается или является исключением, которое я могу обработать?
Да, я мог бы долго менять тип данных, но как я могу проверить, когда это необходимо? И я думаю, что есть проблема с получением функций last_inserted_id(), если я использую long как тип данных для столбца ID.
Ответы
Ответ 1
Комментарий Джима Мартина из §3.6.9. "Использование AUTO_INCREMENT" документации MySQL:
На всякий случай возникает вопрос: поле AUTO_INCREMENT/НЕ ПРОСМОТРЕТЬ /. Как только вы достигнете предела для размера поля, INSERT генерируют ошибку. (Согласно Джереми Коулу)
Быстрый тест с MySQL 5.1.45 приводит к ошибке:
ОШИБКА 1467 (HY000): Не удалось прочитать значение автоматического прироста из механизма хранения
Вы можете проверить эту ошибку при вставке и принять соответствующие меры.
Ответ 2
Чтобы успокоить нервы, подумайте об этом:
Предположим, что у вас есть база данных, которая вставляет новое значение для каждого случая, когда пользователь выполняет какую-то транзакцию на вашем веб-сайте.
С 64-битным целым числом в качестве идентификатора это условие переполнения:
С населением в 6 миллиардов человек, если каждый человек на земле совершает транзакцию один раз в секунду каждый день и каждый год (без отдыха), для вашего идентификатора потребуется более 80 лет.
Т.е., только Google должен смутно рассматривать эту проблему время от времени во время перерыва на кофе.
Ответ 3
Вы узнаете, когда он перейдет, просмотрев самый большой идентификатор. Вы должны изменить его хорошо, прежде чем какое-либо исключение даже приблизится к тому, чтобы его бросили.
На самом деле, вы должны проектировать с достаточно большим типом данных для начала. Производительность вашей базы данных не пострадает, даже если вы используете 64-битный идентификатор с самого начала.
Ответ 4
В ответах здесь говорится, что происходит, но только один ответ говорит о том, как обнаружить проблему (а затем только после того, как произошла ошибка). Как правило, полезно обнаруживать эти вещи, прежде чем они станут проблемой производства, поэтому я написал запрос, чтобы обнаружить, когда произойдет переполнение:
SELECT
c.TABLE_CATALOG,
c.TABLE_SCHEMA,
c.TABLE_NAME,
c.COLUMN_NAME
FROM information_schema.COLUMNS AS c
JOIN information_schema.TABLES AS t USING (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME)
WHERE c.EXTRA LIKE '%auto_increment%'
AND t.AUTO_INCREMENT / CASE c.DATA_TYPE
WHEN 'TINYINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 255, 127)
WHEN 'SMALLINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 65535, 32767)
WHEN 'MEDIUMINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 16777215, 8388607)
WHEN 'INT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 4294967295, 2147483647)
WHEN 'BIGINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', '18446744073709551615', 9223372036854775807) # need to quote because column type defaults to unsigned.
ELSE 0
END > .9; # 10% buffer
Надеюсь, это кому-то поможет.
Ответ 5
Для MySQL 5.6, 3.6.9 Использование AUTO_INCREMENT в разделе:
Используйте наименьший целочисленный тип данных для столбца AUTO_INCREMENT, который является достаточно большим для хранения максимального значения последовательности, которое вам нужно. Когда столбец достигает верхнего предела типа данных, следующая попытка сгенерировать порядковый номер терпит неудачу.
Ответ 6
Я хотел бы поделиться личным опытом, который я только что имел об этом. Использование Nagios + Check_MK + NDOUtils. NDOUtils хранит все проверки в таблице nagios_servicechecks. Первичный ключ - это auto_increment int, подписанный. Что происходит с MySQL, когда этот предел находится в диапазоне? Ну, в моем случае MySQL удаляет все записи, кроме последнего. Теперь таблица почти пуста. Каждый раз, когда вставлена новая запись, старый удаляется. Не почему это происходит, но факт в том, что я потерял все свои записи. IDOUtils, используемый с Icinga (не Nagios), исправил эту проблему, меняя int на bigint. Это не вызвало ошибки.