Что происходит, когда auto_increment для целочисленного столбца достигает max_value в базах данных? - PullRequest
62 голосов
/ 11 апреля 2010

Я реализую приложение базы данных и буду использовать JavaDB и MySQL в качестве базы данных. В моих таблицах есть столбец идентификатора, в котором в качестве типа задано целое число, и я использую функцию базы данных auto_increment для этого значения.

Но что происходит, когда я получаю более 2 (или 4) миллиардов постов, а целого недостаточно? Целое число переполнено и продолжается или выброшено исключение, которое я могу обработать?

Да, я могу изменить тип данных на long, но как мне проверить, когда это необходимо? И я думаю, что есть проблема с получением функций last_inserted_id (), если я использую long как тип данных для столбца ID.

Ответы [ 6 ]

48 голосов
/ 16 мая 2011

Просто, чтобы успокоить нервы, подумайте:

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

С 64-битным целым числом в качестве идентификатора это условие переполнения: С населением мира в 6 миллиардов человек, если каждый человек на Земле будет совершать транзакции один раз в секунду каждый день и каждый год (без отдыха), потребуется более 80 лет, чтобы ваш идентификатор обернулся.

Т.е. только гугл должен время от времени размышлять над этой проблемой во время перерыва на кофе.

45 голосов
/ 11 апреля 2010

Комментарий Джима Мартина от §3.6.9. «Использование AUTO_INCREMENT» документации MySQL:

На всякий случай, если есть какие-либо вопросы, поле AUTO_INCREMENT / НЕ ОБРАЩАЕТСЯ /. Как только вы достигнете предела размера поля, INSERT генерирует ошибку. (Согласно Джереми Коулу)

Быстрый тест с MySQL 5.1.45 приводит к ошибке:

ОШИБКА 1467 (HY000): не удалось прочитать значение автоинкремента из механизма хранения

Вы можете проверить эту ошибку при вставке и предпринять соответствующие действия.

9 голосов
/ 11 апреля 2010

Вы узнаете, когда произойдет переполнение, посмотрев на самый большой идентификатор. Вы должны изменить это задолго до того, как любое исключение приблизится к тому, чтобы быть брошенным.

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

6 голосов
/ 18 июля 2017

В ответах здесь указано, что происходит, но только один ответ говорит о том, как обнаружить проблему (и только после того, как произошла ошибка). Обычно полезно иметь возможность обнаруживать эти вещи до того, как они станут производственной проблемой, поэтому я написал запрос, чтобы определить, когда должно произойти переполнение:

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

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 26 ноября 2015

Я хотел бы поделиться личным опытом, который у меня только что был по этому поводу.Использование Nagios + Check_MK + NDOUtils.NDOUtils хранит все проверки в таблице с именем nagios_servicechecks.Первичный ключ - это auto_increment int подписанный.Что происходит с MySQL, когда этот предел ранжирован?Ну, в моем случае MySQL удаляет все записи, кроме последней.Стол теперь почти пуст.Каждый раз, когда вставляется новая запись, старая удаляется.Не почему это происходит, но факт в том, что я потерял все свои записи.IDOUtils, используемый с Icinga (не Nagios), исправил эту проблему, изменив int на bigint.Ошибка не возникла.

0 голосов
/ 23 сентября 2015

Для MySQL 5.6, 3.6.9 Использование AUTO_INCREMENT в говорит:

Используйте наименьший целочисленный тип данных для столбца AUTO_INCREMENT, который достаточно большой, чтобы содержать максимальное значение последовательности, которое вам потребуется. Когда столбец достигает верхнего предела типа данных, следующая попытка сгенерировать порядковый номер не удалась.

...