https://dev.mysql.com/doc/refman/8.4/en/innodb-consistent-read.html
Consistent read
- InnoDB는 multi-versioning을 통해서, 데이터 베이스의 특정 시점의 쿼리를 표현한다.
- 트랜잭션에 의해서 수행된 쿼리는, 이후나 커밋되지 않은 트랜잭션들로 인해 영향받지 않는다.
- 오직 이전에 수행된 트랜잭션들에 의해서 영향을 받을 수 있다.
- 같은 트랜잭션내에서 발생된 앞선 변화들에 의한 예외는 존재하는데, 이걸 비일관성 문제라고 한다.
- 예를 들어, 트랜잭션 A에서 테이블의 일부 행을 업데이트한 후 SELECT 문을 실행하면, 그 트랜잭션은 방금 업데이트한 행의 최신 상태를 볼 수 있습니다. 하지만 다른 행들에 대해서는 트랜잭션이 시작되었을 때의 일관된 스냅샷 상태를 읽게 됩니다. 같은 테이블에 대해 일부 행은 최신 버전, 다른 행은 이전 버전으로 보여줄 수 있어, 트랜잭션 시작 시점에 존재하지 않았던 혼재된 상태를 나타낼 수 있습니다.
- 만약 트랜잭션 A가 특정 행을 업데이트하고, 다른 트랜잭션 B가 같은 테이블의 다른 행을 수정했다면, 트랜잭션 A의 SELECT 쿼리는 트랜잭션 A의 최신 업데이트를 포함하면서도, 트랜잭션 B가 수정한 최신 행은 포함하지 않는, 실제로 존재하지 않는 혼합된 데이터 상태를 조회하게 됩니다.
First snapshot
REPEATABLE_READ
- 하나의 트랜잭션 내에서 트랜잭션의 첫번째 읽기에 대한 스냅샷을 일관적으로 읽는 것이 가능하다.
- 읽고 있는 레코드들에 대해 다른 트랜잭션이 삭제하고, 수정, 삽입하는 경우에도 영향을 받지 않는다.
- 읽기 스냅샷은
SELECT
에만 적용이 된다. DML
에 대해서는 이미 커밋된(즉, 스냅샷이 아닌) 데이터를 수정할 수 있다.
SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';
DELETE FROM t1 WHERE c1 = 'xyz';
SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';
UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';
SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba';
Fresh snapshot
READ_COMMITED
- 트랜잭션내에서 읽기가 발생하면, 새로운 스냅샷(fresh snapshot)을 읽을 수 있다.
locking read
SELECT * FROM t FOR SHARE;
- fresh rows를 쿼리한 트랜잭션이 끝날 때까지 잠금을 걸어 최신 데이터를 유지할 수 있다.
Nonlocking
- 일관적 읽기는, REAPEATABLE_READ와 READ_COMMITED에서 기본적인 모드이며, 락킹을 하지 않기 때문에 다른 세션들에서 자유롭게 테이블을 수정할 수 있다.
DDL
- 일관적인 읽기는 DROP_TABLE, ALTER_TALBE와 같은 DDL에서는 동작하지 않을 수 있다.