• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 14. InnoDB 스토리지 엔진
  • 1. InnoDB 소개
    2. InnoDB의 개념과 아키텍처
    1. MySQL 과 ACID 모델
    2. InnoDB 트랜잭션 모델 및 잠금
    3. InnoDB 잠금 모드
    4. 일관성 nonlock 읽기
    5. 잠금 읽기 (SELECT ... FOR UPDATE 및 SELECT ... LOCK IN SHARE MODE)
    6. InnoDB 레코드 격차 및 넥스트 키 잠금
    7. 넥스트키 로크에 의한 팬텀 문제 해결
    8. InnoDB의 다양한 SQL문에서 설정된 잠금
    9. 암시적 트랜잭션 커밋과 롤백
    10. 교착 상태 감지 및 롤백
    11. 교착 상태 해결 방법
    12. InnoDB 멀티 버전
    13. InnoDB 테이블 및 인덱스 구조
    3. InnoDB 구성
    4. InnoDB 관리
    5. InnoDB 테이블 스페이스 관리
    6. InnoDB 테이블 관리
    7. InnoDB 압축 테이블
    8. InnoDB 파일 형식 관리
    9. InnoDB Row Storage and Row Formats
    10. InnoDB 디스크 I/O 및 파일 영역 관리
    11. InnoDB와 온라인 DDL
    12. InnoDB 부팅 옵션 및 시스템 변수
    13. InnoDB의 성능
    14. InnoDB INFORMATION_SCHEMA 테이블
    15. InnoDB 모니터
    16. InnoDB 백업 및 복구
    17. InnoDB와 MySQL 복제
    18. InnoDB 및 memcached의 통합
    19. InnoDB 문제 해결
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 20. Stored Programs and Views
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

14.2.3 InnoDB 잠금 모드

InnoDB 는 2 개의 잠금 유형 ( 공유 ( S ) 잠금 으로 배타적 ( X ) 잠금 )이 표준 행 수준 잠금이 구현됩니다. 기록 간격 및 넥스트 키의 각 잠금 유형에 대해서는 섹션 14.2.6 "InnoDB 레코드 격차 및 넥스트 키 잠금" 을 참조하십시오.

  • 공유 ( S ) 잠금 은 잠금을 트랜잭션에서 행 읽기가 허용됩니다.

  • 배타적 ( X ) 잠금 은 잠금을 트랜잭션에 의해 행을 갱신 또는 삭제가 허용됩니다.

트랜잭션 T1 이 행 r 에 대한 공유 ( S ) 잠금을 보유하고있는 경우 다른 트랜잭션 T2 에서 행 r 에 대한 잠금 요청은 다음과 같이 처리됩니다.

  • T2 에 따르면 S 락에 대한 요청은 즉시 부여 할 수 있습니다. 그 결과, T1 과 T2 모두가 r 에서 S 잠금을 유지합니다.

  • T2 에 따르면 X 락에 대한 요청은 즉시 부여 할 수 없습니다.

트랜잭션 T1 이 행 r 에서 독점 ( X ) 잠금을 보유하고있는 경우는 r 에서 어떤 유형의 잠금에 대한 일부 개별 트랜잭션 T2 의 요청은 즉시 부여 할 수 없습니다. 대신에 트랜잭션 T2 는 행 r 에서 트랜잭션 T1 의 잠금이 해제 될 때까지 대기해야합니다.

인텐션 잠금

또한 InnoDB 에서는 레코드 잠금 및 테이블 전체 잠금이 공존하는 것을 허용하는 다중 입상 잠금을 지원하고 있습니다. 다중 입상 레벨의 잠금을 실천하기 위해, 인텐션 락 이라는 추가 잠금 유형이 사용됩니다. 인텐션 락은 나중에 트랜잭션이 해당 테이블의 행에 필요한 잠금 유형 (공유 또는 배타)을 나타내는 InnoDB 테이블 잠금입니다. 트랜잭션 T 가 테이블 t 에 지정된 유형의 잠금을 요청했다고 가정하면, InnoDB 에서 사용되는 인텐션 락이는 다음 두 가지 유형이 있습니다.

  • 인텐션 공유 ( IS ) : 트랜잭션 T 는 의도적으로 테이블 t 의 각 행에 S 잠금을 설정합니다.

  • 인텐션 배타적 ( IX ) : 트랜잭션 T 는 의도적으로 이러한 행에 X 잠금을 설정합니다.

예를 들어, SELECT ... LOCK IN SHARE MODE 는 IS 잠금을 설정하고 SELECT ... FOR UPDATE 는 IX 잠금을 설정합니다.

인텐션 락의 단계는 다음과 같습니다.

  • 트랜잭션이 테이블 t 있는 행의 S 잠금을 얻으려면 먼저 t 의 IS 또는 그것보다 강한 락을 취득해야합니다.

  • 트랜잭션이 행의 X 잠금을 얻으려면 먼저 t 의 IX 잠금을 획득해야합니다.

이러한 규칙을 요약 할 때는 다음 잠금 유형 호환성 매트릭스를 사용하면 편리합니다.


X IX S IS
X 경쟁 경쟁 경쟁 경쟁
IX 경쟁 호환 경쟁 호환
S 경쟁 경쟁 호환 호환
IS 경쟁 호환 호환 호환

잠금 기존 잠금과 호환되는 경우 요청자의 트랜잭션에 잠금이 부여되지만 기존의 락과 충돌하는 경우 잠금이 부여되지 않습니다. 트랜잭션은 충돌하는 기존의 잠금이 해제 될 때까지 기다립니다. 잠금 요청이 기존의 락과 충돌, 교착 상태 가 발생하기 때문에 부여 할 수없는 경우 오류가 발생합니다.

따라서, 인텐션 락은 전체 테이블 요청 ( LOCK TABLES ... WRITE 등) 이외는 아무것도 차단되지 않습니다. IX 및 IS 락의 주요 목적은 누군가가 행을 잠글 수 있으며 테이블의 행을 잠그려고하고 있다는 것을 보여주는 것입니다.

교착 상태의 예

다음의 예문은 락 요청에 의해 교착 상태가 발생했을 때 어떻게 오류가 발생 하는지를 보여줍니다. 이 예는 A와 B 두 클라이언트가 등장합니다.

먼저 클라이언트 A가 행을 하나 포함하는 테이블을 작성하고 트랜잭션을 시작합니다. 트랜잭션 내에서 A는 공유 모드에서 선택한 행에서 S 잠금을 획득합니다.

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
Query OK, 0 rows affected (1.07 sec)

mysql> INSERT INTO t (i) VALUES(1);
Query OK, 1 row affected (0.09 sec)

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.10 sec)

그런 다음 클라이언트 B가 트랜잭션을 시작하고 테이블에서 행을 삭제하려고합니다.

 mysql> START TRANSACTION;
 Query OK, 0 rows affected (0.00 sec)

 mysql> DELETE FROM t WHERE i = 1;

삭제 작업을하려면 X 잠금이 필요합니다. 클라이언트 A가 보유하고있는 S 락과 호환이 없기 때문에 잠금을 부여 할 수 없습니다. 따라서 요청은 행 잠금 요청의 대기 클라이언트 B는 차단됩니다.

마지막으로, 클라이언트 A도 테이블에서 행을 삭제하려고합니다.

 mysql> DELETE FROM t WHERE i = 1;
 ERROR 1213 (40001) : Deadlock found when trying to get lock;
 try restarting transaction

클라이언트 A가 열을 제거하기 위해 X 잠금이 필요하기 때문에, 데드락이 발생합니다. 그러나 클라이언트 B는 이미 X 락에 대한 요청이있어, 클라이언트 A가 S 잠금을 해제 할 때까지 대기하고 있기 때문에 잠금 요청을 부여 할 수 없습니다. B에 따르면 X 락에 대한 이전 요청으로 인해 A가 보유하고있는 S 잠금을 X 잠금으로 업그레이드 할 수 없습니다. 그 결과, InnoDB 는 클라이언트 중 하나에 오류가 발생하여 잠금을 해제합니다. 클라이언트는 다음 오류를 반환합니다.

 ERROR 1213 (40001) : Deadlock found when trying to get lock;
 try restarting transaction

이때 다른 클라이언트에 대한 잠금 요청을 부여 할 수있게 테이블에서 행이 삭제됩니다.

참고

InnoDB Monitor 출력 LATEST DETECTED DEADLOCK 절에는 "TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING TRANSACTION"라는 메시지가 포함됩니다. 이것은 대기 목록에서 트랜잭션 수가 200 제한에 도달했음을 나타냅니다. 이 제한은 LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK 에서 정의됩니다. 200 개의 트랜잭션을 넘는 대기 목록은 교착 상태로 처리 대기 목록을 확인하려는 트랜잭션은 롤백됩니다.

잠금 스레드가 대기 목록에서 트랜잭션이 소유 한 1,000,000 개 이상의 잠금을 참조 할 필요가있는 경우에도 같은 오류가 발생할 수 있습니다. 1,000,000 개의 잠금 제한은 LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 에서 정의됩니다.


서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved