ABOUT ME

Today
Yesterday
Total
  • 2024.08.08 index scan lock
    TIL 2024. 8. 8. 22:36

     

     

    MySQL(InnoDB)이 잠금할 레코드를 고르는 방법

    MySQL 을 처음 공부할 때, 레코드 잠금에 관해서 여러가지 궁금한 점들이 많았다. 그동안 궁금했던 세부적인 부분들에 대해서 정리해보고자 한다.MySQL 은 기본적으로 잠금 읽기(locking read), update, de

    pius712.tistory.com

     

    Index관련 문서를 보면 index scan에 걸리는 것들은 lock이 걸린다고 합니다.
    Where조건에 해당이 안되도 lock에 걸릴 수 있다는 것 입니다. 예로UPDATE t SET b = 3 WHERE b = 2 AND c = 3;
    해당 쿼리가 b인덱스만을 사용한다고 해봅시다.Where조건만보면 둘의 조건이 and인 것들만 lock이 걸릴 거 같지만 b=2인 것을은 모두 lock이 걸립니다.
    Uk가 아니면 b=2인 row 모두가 lock에 걸리게 됩니다.위의 조건들은 격리수준이 repeatable read이었을 때에 대한 것들이고 격리수준이 read committed이면 where절과 일치하지 않는다면 처음에 예상한 거 처럼 lock을 해제합니다.

     

    음 궁금해졌다.

    index scan을 할 때 range로 스캔을 하게될 텐데 앞에 값도 lock을 잡나? 아니면 record에만 lock을 잡나?.

    결과는 rocord에 x lock을 잡고 뒤까지 gap lock을 잡지만 gap이 없어서 반영되는 것은 없었다.

     

    순서대로 값이 있을 때

         
      mysql> select * from tb_gaplock;
    +----+-------+------+
    | id | name  | num  |
    +----+-------+------+
    |  1 | Matt  |    1 |
    |  2 | Matt2 |    2 |
    |  3 | msss  |    3 |
    |  4 | Matt2 |    4 |
    |  6 | Peter |    6 |
    | 15 | 15    |   15 |
    | 20 | 20    |   20 |
    +----+-------+------+
    7 rows in set (0.00 sec)
     
        mysql> update tb_gaplock set num = 54 where num = 2;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0

    mysql> update tb_gaplock set num = 54 where num = 1;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0

    mysql> update tb_gaplock set num = 54 where num = 4;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    1번 실행 시
    
    mysql> select * from performance_schema.data_locks\G
    *************************** 1. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:1068:140558509075104
    ENGINE_TRANSACTION_ID: 5396
                THREAD_ID: 48
                 EVENT_ID: 20
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: NULL
    OBJECT_INSTANCE_BEGIN: 140558509075104
                LOCK_TYPE: TABLE
                LOCK_MODE: IX
              LOCK_STATUS: GRANTED
                LOCK_DATA: NULL
    *************************** 2. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:8:140558509072192
    ENGINE_TRANSACTION_ID: 5396
                THREAD_ID: 48
                 EVENT_ID: 20
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072192
                LOCK_TYPE: RECORD
                LOCK_MODE: X
              LOCK_STATUS: GRANTED
                LOCK_DATA: 3, 3
    *************************** 3. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:4:11:140558509072536
    ENGINE_TRANSACTION_ID: 5396
                THREAD_ID: 48
                 EVENT_ID: 20
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: PRIMARY
    OBJECT_INSTANCE_BEGIN: 140558509072536
                LOCK_TYPE: RECORD
                LOCK_MODE: X,REC_NOT_GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 3
    *************************** 4. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:28:140558509072880
    ENGINE_TRANSACTION_ID: 5396
                THREAD_ID: 48
                 EVENT_ID: 20
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072880
                LOCK_TYPE: RECORD
                LOCK_MODE: X,GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 4, 4
    4 rows in set (0.01 sec

     

    그럼 중복 값이 있을 때 정말로 lock을 잡나?

    잡는다 num이 2인 것에 모두 lock이 잡혔다.

    2가 아닌 것은 수정이 가능하다.

    range scan을 했을 때 데이터 페이지의 앞에서 부터 scan을 하지 않는 것인가? 

    음 이건 index seek이라고 부르는 거 같다. 내일 더 알아보자.

     

         
    1 mysql> select * from tb_gaplock;
    +----+-------+------+------+
    | id | name  | num  | num2 |
    +----+-------+------+------+
    |  1 | Matt  |    1 |    1 |
    |  2 | Matt2 |    2 |    2 |
    |  3 | msss  |    2 |    3 |
    |  4 | Matt2 |    2 |    4 |
    |  6 | Peter |    6 |    6 |
    | 15 | 15    |   15 | NULL |
    | 20 | 20    |   20 | NULL |
    +----+-------+------+------+
    7 rows in set (0.00 sec)
     
    2 mysql> explain update tb_gaplock set num = 36 where num = 2 and num2 = 3;
    +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
    | id | select_type | table      | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra                        |
    +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
    |  1 | UPDATE      | tb_gaplock | NULL       | range | idx_num       | idx_num | 5       | const |    3 |   100.00 | Using where; Using temporary |
    +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
    1 row in set, 1 warning (0.00 sec)
     
    3 update tb_gaplock set num = 36 where num = 2 and num2 = 3;  
        mysql> update tb_gaplock set num = 54 where id = 1;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0

     

    3번까지 실행 시
    
    mysql> select * from performance_schema.data_locks\G
    *************************** 1. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:1068:140558509075104
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: NULL
    OBJECT_INSTANCE_BEGIN: 140558509075104
                LOCK_TYPE: TABLE
                LOCK_MODE: IX
              LOCK_STATUS: GRANTED
                LOCK_DATA: NULL
    *************************** 2. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:27:140558509072192
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072192
                LOCK_TYPE: RECORD
                LOCK_MODE: X
              LOCK_STATUS: GRANTED
                LOCK_DATA: 2, 2
    *************************** 3. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:30:140558509072192
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072192
                LOCK_TYPE: RECORD
                LOCK_MODE: X
              LOCK_STATUS: GRANTED
                LOCK_DATA: 2, 3
    *************************** 4. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:31:140558509072192
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072192
                LOCK_TYPE: RECORD
                LOCK_MODE: X
              LOCK_STATUS: GRANTED
                LOCK_DATA: 2, 4
    *************************** 5. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:4:41:140558509072536
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: PRIMARY
    OBJECT_INSTANCE_BEGIN: 140558509072536
                LOCK_TYPE: RECORD
                LOCK_MODE: X,REC_NOT_GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 2
    *************************** 6. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:4:42:140558509072536
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: PRIMARY
    OBJECT_INSTANCE_BEGIN: 140558509072536
                LOCK_TYPE: RECORD
                LOCK_MODE: X,REC_NOT_GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 3
    *************************** 7. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:4:43:140558509072536
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: PRIMARY
    OBJECT_INSTANCE_BEGIN: 140558509072536
                LOCK_TYPE: RECORD
                LOCK_MODE: X,REC_NOT_GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 4
    *************************** 8. row ***************************
                   ENGINE: INNODB
           ENGINE_LOCK_ID: 140558497443840:2:6:9:140558509072880
    ENGINE_TRANSACTION_ID: 5448
                THREAD_ID: 48
                 EVENT_ID: 74
            OBJECT_SCHEMA: sample
              OBJECT_NAME: tb_gaplock
           PARTITION_NAME: NULL
        SUBPARTITION_NAME: NULL
               INDEX_NAME: idx_num
    OBJECT_INSTANCE_BEGIN: 140558509072880
                LOCK_TYPE: RECORD
                LOCK_MODE: X,GAP
              LOCK_STATUS: GRANTED
                LOCK_DATA: 6, 6
    8 rows in set (0.00 sec)

    'TIL' 카테고리의 다른 글

    댓글

Designed by Tistory.