Print
카테고리: [ MariaDB ]
조회수: 12355

트랜잭션 수준의 일관성 설정

 

mysql> show variable status 'tx_isolation';
mysql> show variables like 'tx_isolation';


동시성 vs 일관성?

 

Isolation Level

Isolation Level Dirty Read Non-Repeatable Read Phantom Read
READ UNCOMMITTED O O O
READ COMMITTED X O O
REPETABLE READ X X O
SERIALIZABLE X X X

 

commit 되지 않은 신뢰성 없는 데이터를 읽을 수 있는 상태다.

commit 여부에 따라 데이터가 달라진다.

없던 데이터가 갑자기 나타나거나, 있던 데이터가 갑자기 사라지는 경우다.

 

레벨 - 상세

Level 0. READ UNCOMMITTED

Level 1. READ COMMIITED

Level 2. REPEATABLE READ

Level 3. SERIALIZE

 

기타

그런데 Isolation Level이 MySQL 기본인 REPEATABLE READ인 상태에서, INSERT INTO SELECT, CREATE TABLE AS SELECT 등을 통해 전체 테이블 참조 쿼리가 발생하면 참조 테이블에 데이터 변경 작업이 "대기" 상태로 빠질 수 있다.

이는 InnoDB의 기본 Isolation Level이 REPEATABLE READ이기 때문이다.

REPETABLE READ에서는 현재 SELECT 버전을 보장하기 위해 snapshot을 이용하는데 이 경우 해당 데이터에 대한 암묵적 lock이 발생한다. 따라서 해당 조회 작업이 완료될 때까지 데이터 변경이 불가능하다.

해결책 :

INSERT INTO SELECT : READ UNCOMMITTED 혹은 READ COMMITTED로 변경한다.

1. 일시적 해결책

mysql> set tx_isolation = 'READ-COMMITTED';

 혹은

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

2. 영구적 해결책 (my.cnf)

transaction-isolation = READ-COMMITTED

 

MySQL lock 종류

특정 세션에서 테이블에 접근하여 데이터를 읽거나 쓸 때 타 세션에서 접근하지 못하도록 거는 lock

특정 세션에서 글로벌하게 Read Lock을 사용할 때 사용, flush tables 명령어 사용

테이블의 이름을 변경하거나 삭제할 때 암묵적으로 걸리는 lock

사용자 레벨에서 lock의 이름과 타임아웃을 정의하여 사용하는 방법

오직 InnoDB