[MySQL] The total number of locks exceeds the lock table size

2024. 7. 24. 19:38·Backend/MySQL

대규모 데이터를 삽입해서 테스트를 하기 위해 JDBC로 Batch Insert를 하고 있는데, 갑자기 제목과 같은 에러가 나타났다.

 

user 데이터 1억 개, user 테이블을 참조하는 device_token 데이터 10억 개를 넣는데,

이해가 안 가는 게 Batch size를 10,000으로 잡았을 때, user 데이터는 잘 삽입하더니 device_token 삽입할 때는 에러가 발생한다.

 

 

MySQL Error 1206, 데이터 엔지니어의 눈으로 바라보기

★ 부제 : 데이터엔지니어와 데이터분석가의 경계 “The total number of locks exceeds the lock table size” 락의 총합이 락테이블 사이즈를 초과했다. 무슨 뜻일까? 냉큼 buffer_size를 늘이라고 해서 늘린다면

greypencil.tistory.com

 

 

The total number of locks exceeds the lock table size 이슈 해결

https://velog.io/@alpahexia/MapBook-파일-다운로드-자동화 전국 도서관의 각 도서별 대출 횟수를 구하기 위해 도서관 별 장서 목록 데이터를 수집하고, 그 데이터에서 각각의 대출 횟수를 합산 해야 한다

velog.io

 

우선 위 에러는 보통 너무 많은 데이터를 한 번에 읽으려고 할 때 발생한다.

 

select의 결과를 메모리(buffer)로 가져오는데, buffer_size 옵션에 할당된 값보다 큰 데이터가 넘어오니 실패하는 것이다.

에러 문구가 "out of buffer"가 아닌 "the total number of locks exceeds the lock table size"인 이유는 읽거나 쓰는 과정에서 격리 수준에 따라 lock을 거는데, 이 한계를 초과해버렸기 때문이다.

 

가장 간단한 해결책으로 buffer pool size를 늘려버리라는데, 배우는 입장에서 이런 재미없는 해결책은 원치 않는다.

 

우선 두 테이블의 데이터 크기를 생각해보자.

  1. user
    • id: bigint (8 bytes)
    • account_book_notify, chat_notify, feed_notify : bit(1) each (1 byte each, 3 bytes total)
    • created_at, updated_at, deleted_at: datetime(6) (8 bytes each, 24 bytes total)
    • name, username: varchar(255) (최대 255 bytes each, 평균 50 bytes로 가정하면 100 bytes total)
    • 총 데이터 크기: 약 135 bytes/row
    • 인덱스(id) 크기: 8 bytes/row
    • user table 총 크기 : 약 143 bytes/row
  2. device_token
    • id: bigint (8 bytes)
    • activated: bit(1) (1 byte)
    • created_at, updated_at, datetime(6) (8 bytes each, 16 bytes total)
    • user_id: bigint (8 bytes)
    • token: varchar(255) (최대 255 bytes, 평균 100 bytes 가정)
    • 총 데이터 크기: 약 133 bytes/row
    • 인덱스(PK, FK): 16 bytes/row
    • 총 인덱스 크기: 16bytes/row
    • device_token 테이블 총 크기 : 약 149 bytes/row

여기서 user 테이블 데이터 1억 개, device token에 데이터 10억 개를 추가하면 아래와 같다.

  • user 테이블 1억 행: 143 bytes/row * 100,000,000 = 약 13.3 GB
  • device_token 테이블 10억 행: 149 bytes/row * 1,000,000,000 = 약 138.4 GB

총 151.7 GB...? 아니 이렇게 클 줄 몰랐는데, 내 PC 어떻게 버티고 있는 거지. ㅋㅋ

 

그런데 이상하지 않나? 난 Batch Insert를 하고 있을 뿐인데, 왜 여기서 "the total number of locks exceeds the lock table size" 에러가 발생하는 거고, user 데이터는 아무런 문제가 없던 걸까?

 

 

이는 user 테이블과 device token 테이블의 차이점 때문인데, 바로 fk의 존재 유무 때문이다.

쓰기 연산을 수행하기 위해 device token에 lock을 거는데, user 테이블을 참조하고 있기 때문에 user 테이블의 관련 행 또한 같이 잠근다.

 

따라서 똑같이 10,000개 씩 batch insert를 하려고 해도, user 테이블은 user 테이블만 잠그면 끝나지만,

device token은 최악의 경우 20,000개의 lock을 필요로 하기 때문이다.

 

8MB니까 기본값이 맞다.

기본으로 설정된 innodb_buffer_pool_size는 8,388,608 byte라고 하는데, 이 값을 늘리면 lock을 관리한 메모리도 증가하므로 문제를 해결할 수 있는 것이었다.

 

어차피 로컬 환경 테스트니까 buffer pool을 늘려서 빠르게 데이터를 삽입하는 것도 나쁘지 않은 생각일지도...

왜냐면 지금 데이터 10억 개 넣는데, 1시간 동안 고작 2천 만 개 넣었다 ㅎㅎ^^

저작자표시 비영리 (새창열림)
'Backend/MySQL' 카테고리의 다른 글
  • [MySQL] goormIDE에 MySQL 서버 구축하기
  • [SQL] Stored Procedure
  • [SQL] Index
  • [SQL] Table & View
나죽못고나강뿐
나죽못고나강뿐
싱클레어, 대부분의 사람들이 가는 길은 쉽고, 우리가 가는 길은 어려워요. 우리 함께 이 길을 가봅시다.
코드를 찢다싱클레어, 대부분의 사람들이 가는 길은 쉽고, 우리가 가는 길은 어려워요. 우리 함께 이 길을 가봅시다.
  • 나죽못고나강뿐
    코드를 찢다
    나죽못고나강뿐
  • 전체
    오늘
    어제
    • 분류 전체보기 (458)
      • Computer Science (60)
        • Git & Github (4)
        • Network (17)
        • Computer Structure & OS (13)
        • Software Engineering (5)
        • Database (9)
        • Security (5)
        • Concept (7)
      • Frontend (21)
        • React (13)
        • Android (4)
        • iOS (4)
      • Backend (77)
        • Spring Boot & JPA (50)
        • Django REST Framework (14)
        • MySQL (8)
        • Nginx (1)
        • FastAPI (4)
      • DevOps (24)
        • Docker & Kubernetes (11)
        • Naver Cloud Platform (1)
        • AWS (2)
        • Linux (6)
        • Jenkins (0)
        • GoCD (3)
      • Coding Test (112)
        • Solution (104)
        • Algorithm (7)
        • Data structure (0)
      • Reference (134)
        • Effective-Java (90)
        • Pragmatic Programmer (0)
        • CleanCode (11)
        • Clean Architecture (2)
        • Test-Driven Development (4)
        • Relational Data Modeling No.. (0)
        • Microservice Architecture (2)
        • 알고리즘 문제 해결 전략 (9)
        • Modern Java in Action (0)
        • Spring in Action (0)
        • DDD start (0)
        • Design Pattern (6)
        • 대규모 시스템 설계 (6)
        • JVM 밑바닥까지 파헤치기 (4)
      • Service Planning (2)
      • Side Project (5)
      • AI (0)
      • MATLAB & Math Concept & Pro.. (1)
      • Review (18)
      • Interview (2)
      • IT News (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃
  • 공지사항

    • 한동안 포스팅은 어려울 것 같습니다. 🥲
    • N Tech Service 풀스택 신입 개발자가 되었습니다⋯
    • 취업 전 계획 재조정
    • 취업 전까지 공부 계획
    • 앞으로의 일정에 대하여..
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
나죽못고나강뿐
[MySQL] The total number of locks exceeds the lock table size

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.