NW-book-club / Real-MySQL-8.0

Real MySQL 8.0
0 stars 0 forks source link

5장. 트랜잭션과 잠금 #4

Open KKambi opened 1 year ago

KKambi commented 1 year ago

12/04 (5.1 ~ 5.3)

바이너리 로그 포멧의 종류

바이너리 로그 = 복제를 위한 것 (소스 서버 -> 레플리카 서버 / 카프카 커넥트 등)

--binlog-format=type


바이너리 로그 포멧을 설정한다고 해서, 바이너리 로깅이 활성화되는 것은 아니다.


그럼 왜 여러 타입이 필요할까?

innodb_autoin_lock_mode

InnoDB는 AUTO_INCREMENT 값의 채번을 위해 테이블당 하나만 사용되는 AUTO_INCREMENT 락을 제공한다.


그럼 Upsert 쿼리 문장을 사용하면 어떻게 될까? (팀원 경험)

Replace 쿼리 문장

CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)

왜 2개의 행이 영향을 받을까?

  1. Try to insert the new row into the table
  2. While the insertion fails because a duplicate-key error occurs for a primary key or unique index:
    1. Delete from the table the conflicting row that has the duplicate key value
    2. Try again to insert the new row into the table

궁금증1

배치 프로그램의 많은 레코드 변경 쿼리는 자주 데드락의 원인이 되곤 한다. -> 변경해야할 레코드를 찾기 위해 검색한 인덱스의 레코드를 모두 락을 걸기 때문


이런 경우 동일 데이터를 변경하거나 참조하는 프로그램끼리 분류해서 네임드 락을 걸고 쿼리를 실행하면 아주 간단히 해결 -> Q. 원리가 뭐지? -> 동일 데이터 변경, 참조 = 같은 인덱스에 대해 락을 걸게 된다 -> 데드락 = 서로 동일한 데이터를 필요로 하게 되며 발생 -> 네임드 락으로 해소!

궁금증2

InnoDB의 잠금은 레코드를 잠그는 것이 아니라 인덱스를 잠그는 방식 -> Q. 아니 그래서 왜 이렇게 설계한거지? -> 인덱스와 레코드 사이의 정합성 때문일까?

jjy0918 commented 1 year ago

READ

Dirty Read

Non-Repeatable Read

Phantom Read

Transaction

KKambi commented 1 year ago

12/11 (5.4 ~ 6장 끝)

Q. Repeatable Read - 이전 트랜잭션이 내가 수행하는 도중에 커밋해버린다면?

이전 트랜잭션의 ID 값이 더 작으니까, Repeatable Read가 보장 안되지 않을까?

image


Q. Read Committed vs Repetable Read - 언두 영역 버전 탐색 차이

Read Committed

Repetable Read


Q. InnoDB Repeatable Read - 팬텀 리드가 발생하지 않는다면서 자세히 안 알려주네

A. 칼럼 c1의 값이 각각 13 / 17 인 레코드 2개 SELECT c1 FROM t WHERE c1 BETWEEN 10 AND 20 FOR UPDATE 수행 시 아래 범위에 갭 락

따라서 해당 트랜잭션 내에서 이미 조회한 범위에 대해서는 INSERT를 할 수 없으므로 Phantom Read도 발생하지 않는다.