Development Tip

정수 열의 auto_increment가 데이터베이스의 max_value에 도달하면 어떻게됩니까?

yourdevel 2020. 11. 24. 19:57
반응형

정수 열의 auto_increment가 데이터베이스의 max_value에 도달하면 어떻게됩니까?


저는 데이터베이스 애플리케이션을 구현하고 있으며 데이터베이스로 JavaDB와 MySQL을 모두 사용할 것입니다. 정수를 유형으로 갖는 테이블에 ID 열이 있고 값에 대해 데이터베이스 auto_increment-function을 사용합니다.

하지만 게시물이 20 억 개 (또는 40 억 개) 이상이고 정수만으로는 충분하지 않으면 어떻게됩니까? 정수가 오버플로되어 계속되거나 처리 할 수있는 예외가 발생합니까?

예, long as 데이터 유형으로 변경할 수 있지만 필요한 경우 어떻게 확인합니까? 그리고 ID 열에 long as 데이터 유형을 사용하면 last_inserted_id () 함수를 얻는 데 문제가 있다고 생각합니다.


§3.6.9 의 Jim Martin의 의견 . MySQL 문서의 "Using AUTO_INCREMENT" :

질문이있는 경우 AUTO_INCREMENT 필드 / DOES NOT WRAP /. 필드 크기 제한에 도달하면 INSERT가 오류를 생성합니다. (Jeremy Cole에 따라)

MySQL 5.1.45를 사용한 빠른 테스트에서는 다음 오류가 발생합니다.

오류 1467 (HY000) : 스토리지 엔진에서 자동 증가 값을 읽지 못했습니다.

삽입시 해당 오류를 테스트하고 적절한 조치를 취할 수 있습니다.


신경을 진정시키기 위해 다음을 고려하십시오.

사용자가 웹 사이트에서 일종의 트랜잭션을 실행할 때마다 새 값을 삽입하는 데이터베이스가 있다고 가정합니다.

64 비트 정수를 ID로 사용하면 이것이 오버플로의 조건입니다. 세계 인구가 60 억인 경우 지구상의 모든 사람이 매일 1 초에 한 번 (휴식없이) 트랜잭션을 실행하면 80 개 이상이 소요됩니다. 당신의 이드를 감싸는 데 몇 년.

즉, Google만이 커피 휴식 시간 동안 가끔이 문제를 모호하게 고려할 필요가 있습니다.


가장 큰 ID를 보면 언제 넘칠 지 알 수 있습니다. 예외가 발생하기 전에 잘 변경해야합니다.

사실, 시작하기에 충분히 큰 데이터 유형으로 설계해야합니다. 처음부터 64 비트 ID를 사용하더라도 데이터베이스 성능은 저하되지 않습니다.


여기에 어떤 일이 발생했는지에 대한 답변이 나와 있지만 문제를 감지하는 방법은 단 하나뿐입니다 (오류가 발생한 후에 만). 일반적으로 프로덕션 문제가되기 전에 이러한 사항을 감지 할 수 있으면 도움이되므로 오버플로가 발생하려고 할 때 감지하는 쿼리를 작성했습니다.

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

이것이 누군가 어딘가에 도움이되기를 바랍니다.


MySQL 5.6, 3.6.9의 경우 AUTO_INCREMENT사용하면 다음 과 같이 말합니다.

필요한 최대 시퀀스 값을 보유 할만큼 충분히 큰 AUTO_INCREMENT 열에 대해 가장 작은 정수 데이터 유형을 사용하십시오. 열이 데이터 유형의 상한에 도달하면 다음 번 시퀀스 번호 생성 시도가 실패합니다.


이것에 대해 방금 경험 한 개인적인 경험을 나누고 싶습니다. Nagios + Check_MK + NDOUtils 사용. NDOUtils는 nagios_servicechecks라는 테이블에 모든 검사를 저장합니다. 기본 키는 auto_increment int 서명입니다. 이 제한이 범위가 지정되면 MySQL은 어떻게됩니까? 제 경우에는 MySQL이 마지막 레코드를 제외한 모든 레코드를 삭제합니다. 이제 테이블이 거의 비어 있습니다. 새 레코드가 삽입 될 때마다 이전 레코드가 삭제됩니다. 왜 이런 일이 발생하는지 모르겠지만 사실은 모든 기록을 잃어버린 것입니다. Icinga (Nagios 아님)와 함께 사용되는 IDOUtils는 bigint에 의해 int를 변경하는이 문제를 해결했습니다. 오류가 발생하지 않았습니다.

참고 URL : https://stackoverflow.com/questions/2615417/what-happens-when-auto-increment-on-integer-column-reaches-the-max-value-in-data

반응형