ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MySQL - 스토리지 엔진 수준의 락
    💻 computer science/📦 database 2024. 5. 11. 14:25

    🔒 MySQL 의 락

    MySQL에서 사용되는 락은 크게 스토리지 엔진 레벨과 MySQL 엔진 레벨로 나눌 수 있다.

     

    🧩 스토리지 엔진 레벨의 락

    • 테이블의 데이터를 다루기 위한 락

     

    🧩 MySQL 엔진 레벨의 락

    • 테이블이나 데이터베이스 등과 같은 부분을 위한 락

     

    🆎 스토리지 엔진 레벨의 락의 종류

    • 레코드 락 (Record Lock)
    • 갭 락 (Gap Lock)
    • 넥스트 키 락 (Next Key Lock)
    • 자동 증가 락 (Auto Increment Lock)

     

    1️⃣ 레코드 락

    🎯 레코드 락은 테이블 레코드 자체를 잠그는 락을 의미한다.

     

     

    ❗MySQL에서 레코드 락은 테이블의 레코드가 아닌 인덱스의 레코드를 잠근다는 점이 다른 DBMS와의 차이점이다.

    • MySQL에서는 레코드 자체를 잠그는 것이 아닌 인덱스를 잠그기 때문에, 변경해야 할 레코드를 찾기 위해 검색한 모든 인덱스에 락을 걸어야 한다.

     

    🏃 예시 - employee 테이블

    CREATE TABLE employee (
        emp_id INT NOT NULL AUTO_INCREMENT,
        first_name VARCHAR(64),
        last_name VARCHAR(64),
        hire_at TIMESTAMP,
        PRIMARY KEY(emp_id),
        INDEX idx_last_name (last_name)  // last_name(성)에 대해서만 인덱스가 걸려 있음
    ) ENGINE=InnoDB

     

    UPDATE 
        employee 
    SET 
        hire_at = NOW() 
    WHERE 
        last_name = 'Ko'           // 300건
        AND first_name = 'Beomsic'  // 1건

     

    last_name = ‘Ko’를 만족하는 레코드가 300건, first_name = ‘Beomsic’를 만족하는 레코드가 1건이라고 하자

     

    last_name 은 인덱스가 존재하지만, first_name에 대해서는 존재하지 않는다.

     

    따라서, 1건을 업데이트하기 위해서 300건의 인덱스에 락을 걸어야 한다.

    • 만약, idx_last_name 인덱스조자 없는 상황이라면 UPDATE 쿼리를 위해서 테이블을 풀 스캔하면서 레코드를 갱신하게 된다.
    • 이때, 테이블의 모든 레코드를 잠그게 된다.

    레코드를 갱신하기 위해 인덱스를 통해 검색되는 모든 레코드에 잠금을 걸게 된다.

     

    2️⃣ 갭 락(Gap Lock)

    • MySQL이 다른 DBMS와 차이가 나는 또 다른 부분이 갭 락이다.

     

    📖 갭 락(Gap Lock)

     

    레코드가 아닌 레코드와 레코드 사이의 간격을 잠금으로써 레코드의 생성, 수정 및 삭제를 제어한다.

     

    📍 갭 락은 인덱스 범위 조건 중 실제 레코드를 제외하고, 데이터가 추가될 수 있는 범위에 걸린다.

    MySQL Gap Lock 다시보기

     

    위 테이블에서 id 값이 1, 3, 6을 제외한 값은 언제든지 INSERT 될 수 있는 상태이다.

    • MySQL은 이런 상태의 테이블에서 id = 1인 레코드와 id = 3인 레코드 사이의 간격과 id = 3과 id = 6 사이의 간격을 잠글 수 있다.

     

     

    ⭐ 이렇게 실제 존재하지 않는 레코드 공간을 잠그는 것을 MySQL 서버에서는 Gap Lock이라 한다.

     

     

    🤔 왜 Gap Lock 이 필요할까?

    3가지 목적을 위해서 사용한다.

     

    1. Repeatable Read 격리 수준 보장

     

    2. Replication 일관성 보장

    • 복제 Source DB와 Replica 간 데이터 부정합을 막기 위함

     

    3. Foreign Key 일관성 보장

     

     

    🎯 Gap Lock은 다른 트랜잭션이 대상 간격(Gap)에 새로운 레코드가 INSERT되는 것을 막는 것이 주 목적이다.

     

     

    🏃 예시 - employee 테이블

    • 성이 K 로 시작하는 레코드가 2개 있다고 할 때, 다른 데이터들이 생성될 수 있다.
    SELECT * FROM employee WHERE last_name LIKE "K%" FOR UPDATE; // 쓰기 잠금(베타락)
    SELECT * FROM employee WHERE last_name LIKE "K%" LOCK IN SHARE MODE; // 읽기 잠금(공유락)
    

     

    한 트랜잭션에서 조회를 할 때, 다른 트랙잭션에서 임의의 데이터가 추가되지 않도록 잠구기 위해서는 위의 쿼리를 실행해야 한다.

    • 락은 트랜잭션이 커밋 또는 롤백될 때 해제된다.

     

    3️⃣ 넥스트 키 락(Next Key Lock)

     

    📖 넥스트 키 락

     

    레코드 락과 갭 락을 합친 잠금

    • 갭 락은 넥스트 키 락의 일부로 함께 사용된다.

     

    🎯 목적

    • 바이너리 로그에 기록되는 쿼리가 리플리카 서버에서 실행될 때 소스 서버에서 만들어낸 결과와 동일한 결과를 만들어내도록 보장하는 것

     

    4️⃣ 자동 증가 락(Auto Increment Lock)

    MySQL은 자동 증가하는 숫자값을 위해 AUTO_INCREMENT 라는 컬럼 속성을 제공한다.

     

    AUTO_INCREMENT 컬럼

    • 동시에 Insert 되더라도 중복되지 않고 순차적으로 증가하는 일련번호를 제공하기 위해 내부적으로 테이블 수준의 잠금인 자동 증가 락(Auto Increment Lock)을 사용한다.

     

     

    📖 자동 증가 락(Auto Increment Lock)

     

    INSERT REPLACE 와 같이 새로운 레코드를 저장하는 쿼리에서만 사용한다.

     

    또한 트랜잭션과 관계없이 INSERT, REPLACE 에서 AUTO_INCREMENT 값을 가져오는 순간 락이 걸린다.

    • 자동 증가 락은 테이블에 1개만 존재한다.

     

    📕 참고자료

    [MySQL] B-Tree로 인덱스(Index)에 대해 쉽고 완벽하게 이해하기

    MySQL Gap Lock 다시보기

    [10분 테코톡] ⛲️ 오즈의 데이터베이스 Lock

    '💻 computer science > 📦 database' 카테고리의 다른 글

    MySQL - 트랜잭션 격리 수준 실습  (0) 2024.05.11
    📂 MySQL - 트랜잭션 격리 수준  (0) 2024.05.11
    인덱스  (0) 2022.10.05
    SQL / NoSQL  (1) 2022.10.05
    트랜잭션  (1) 2022.10.05

    댓글

Designed by Tistory.