1. 트랜잭션의 네 가지 특성은 무엇입니까
- 원자성(또는 불가분성)
- 일관성
- 격리
- 내구성
다음으로 네 가지 주요 기능의 구체적인 개념과 기본 구현 원칙을 분석합니다.
구체적인 네 가지 주요 기능을 설명하기 전에 약간의 사전 지식을 추가해 보겠습니다.
1. 논리적 아키텍처 및 스토리지 엔진
위에 표시된 것처럼 mysql 서버의 논리적 아키텍처를 세 계층으로 나눌 수 있습니다.
① 1계층 : 클라이언트 연결 및 권한 인증 등을 담당
②두 번째 계층: 서버 계층: 쿼리문 구문 분석, 최적화 및 캐싱, 내장 기능 구현 및 저장 등을 담당합니다
③세 번째 계층: 스토리지 엔진: 데이터베이스에 데이터를 저장하고 읽는 역할을 하며 mysql 서버 계층은 트랜잭션을 관리하지 않으며 트랜잭션은 스토리지 엔진에 의해 구현됩니다. 그 중 트랜잭션을 지원하는 스토리지 엔진으로는 innoDB와 NDB Cluster가 있으며 그 중 innoDB가 많이 사용되고 있다.
네 가지 특성을 자세히 소개합니다.
1. 원자성
1. 정의
원자성은 트랜잭션이 분할할 수 없는 작업 단위이며 그 안의 작업이 완료되거나 완료되지 않음을 의미합니다. 트랜잭션의 SQL 문이 실행되지 않으면 실행된 문도 롤백되어야 하며 데이터베이스는 트랜잭션 상태 앞.
2. 실행 원칙: redolog
리두 로그에 대해 자세히 이야기하기 전에 mysql에 존재하는 트랜잭션 로그에 대해 설명하겠습니다. mysql에는 바이너리 로그, 오류 로그 및 쿼리 로그를 포함하여 많은 유형의 트랜잭션 로그가 있습니다. 또한 innoDB는 undolog(롤백 로그) 및 redolog(리두 로그)의 두 가지 로그도 제공합니다. 여기서 undolog는 데이터의 원자성 및 일관성에 대한 중요한 보증이며 redolog는 트랜잭션 섹스의 지속성을 보장하는 데 사용됩니다.
UNDOLOG
Undolog는 트랜잭션 원자성에 대한 중요한 보증입니다.Undolog는 트랜잭션에서 성공적으로 실행된 모든 SQL 문을 롤백할 수 있습니다.구체적인 작업 흐름은 다음과 같습니다: 트랜잭션이 데이터베이스의 데이터를 수정하면 innoDB는 특정 UNDO 로그를 한 번 생성합니다. 트랜잭션 실행이 실패하거나 롤백 작업이 트리거되면 리두 로그의 정보를 사용하여 데이터베이스 수정 이전의 값을 복원할 수 있습니다.
Undolog는 논리적 로그로 롤백이 발생하거나 트랜잭션 실행이 실패하면 innoDB는 undolog에 기록된 정보에 따라 데이터베이스에서 반대 방향으로 작업을 수행합니다.예: 이전 작업은 insert 문이고 delete 문은 이 때 호출되며 if 이전에 실행된 update 문은 반대 방향으로 update 문을 실행하게 됩니다.
2. 끈기
1. 정의
지속성은 트랜잭션이 커밋되면 데이터베이스에 대한 변경 사항이 영구적이어야 함을 의미합니다. 이후의 다른 작업이나 실패는 그것에 영향을 미치지 않아야 합니다.
2. 시행 원칙
리도로그
트랜잭션 지속성에 대해 이야기하기 전에 먼저 redolog의 존재 배경과 존재 필요성에 대해 이야기해 보겠습니다.
데이터베이스에 대한 읽기 및 쓰기 작업은 데이터베이스의 데이터에 대한 작업, 즉 데이터베이스에 대한 IO 작업이 필요하지만 데이터베이스에 대한 빈번한 IO는 매우 비효율적이므로 innoDB는 캐시 계층을 제공합니다. (BufferPool), 데이터베이스의 일부 페이지 매핑은 데이터베이스 데이터의 버퍼로 사용됩니다. 데이터베이스에서 데이터를 읽어야 할 때 먼저 BufferPool에서 검색하지만 BufferPool에서 찾을 수 없습니다. 이때, 데이터베이스에서 데이터를 받아 전송하고 BufferPool에 넣는데, 데이터베이스에 데이터를 쓰는 것도 먼저 BufferPool에 데이터를 쓴 다음 주기적으로 디스크에 새로 고치는 것이다(이 과정은 더티 브러싱이라고 함).
그러나 편리함을 가져오는 반면 특정 시점에서 데이터베이스가 갑자기 crash되고 이때 BufferPool에 아직 데이터가 남아 있거나 수정된 데이터가 디스크에 플러시되지 않으면 필연적으로 위험과 단점이 있습니다. 또한 데이터의 지속성을 보장할 수 없기 때문에 이러한 문제를 해결하기 위해 redolog 로그가 등장하게 되었습니다. Redolog는 innoDB의 로그이기도 합니다.그 구현 원칙은 다음과 같습니다: 데이터가 BufferPool에 기록되기 전 또는 BufferPool의 데이터가 수정되기 전에 작업이 먼저 redolog에 기록됩니다.트랜잭션이 커밋되면 fsync가 사용됩니다.인터페이스 리두 로그를 새로 고치고 데이터베이스가 다운되면 데이터베이스는 리두 로그의 정보를 읽고 데이터베이스의 데이터를 복원합니다. redo log는 WAL(Write-ahead logging, write-ahead log)을 사용하며 모든 데이터는 BufferPool에 기록되거나 BufferPool에서 데이터를 수정하기 전에 redolog에 기록되므로 mysql 다운타임으로 인해 데이터가 손실되지 않습니다. 데이터 지속성을 보장합니다.
그렇다면 redolog도 데이터가 제출될 때 데이터베이스에 데이터를 쓰기 때문에 BufferPool을 통해 데이터베이스에 쓰는 것보다 더 효율적인 이유는 무엇입니까?
주로 다음 두 가지 측면 때문입니다.
1. Redolog는 순차 IO, BufferPool은 임의 IO로 데이터를 읽고 쓰는 위치가 임의로 생성되며 순차 IO보다 속도가 느립니다.
2. BufferPool이 데이터를 쓰는 방식은 데이터 페이지를 기준으로 하며 , 일반적으로 mysql의 페이지 크기는 16kb이며, 페이지에서 데이터가 수정되면 전체 페이지 데이터를 다시 작성해야 하며 , redolog가 실효적이다. 쓰기: 새로 추가되거나 수정된 데이터만 쓰기되며 유효하지 않은 IO가 크게 줄어듭니다 .
3. 격리
1. 정의:
Isolation은 트랜잭션 간의 상호 작용을 연구하는 것으로 Isolation은 트랜잭션 내부의 작업이 다른 트랜잭션과 격리되어 있음을 의미합니다 동시 환경에서 각 트랜잭션은 서로 간섭하지 않습니다 Strict isolation은 트랜잭션 격리 수준에 해당합니다 직렬화 가능(serializable ) , 그러나 직렬화는 성능 고려 사항으로 인해 실제 응용 프로그램에서는 거의 사용되지 않습니다.
2. 시행 원칙
격리를 추구하는 것은 동시 트랜잭션이 서로에게 영향을 미치지 않으며 일상적인 작업에서 가장 중요한 고려 사항은 읽기 작업과 쓰기 작업입니다. 1. 하나의 쓰기 작업이 다른 쓰기 작업에 미치는 영향: 잠금 메커니즘을 통해
해결
2. 하나의 쓰기 작업이 다른 읽기 작업에 미치는 영향: MVCC 메커니즘으로 해결
1. 잠금 메커니즘: 쓰기 작업 요구 사항에서 하나의 트랜잭션만 동시에 데이터의 동일한 부분에 쓸 수 있습니다.innoDB에 의해 구현된 잠금 메커니즘의 구현 원칙은 다음과 같이 이해할 수 있습니다. 트랜잭션 쓰기 전에 잠금 리소스를 먼저 획득해야 하며, 이때 데이터를 쓸 수 있습니다.잠금 리소스를 획득하려는 다른 트랜잭션은 현재 트랜잭션이 트랜잭션을 롤백하거나 쓰기를 제출한 후 잠금을 해제하기를 기다려야 합니다. 작업.
행 잠금 및 테이블 잠금: 잠금의 세분성에 따라 잠금은 행 잠금, 테이블 잠금 및 중간 잠금으로 나눌 수 있습니다. 테이블 잠금은 트랜잭션이 데이터에 대해 작동할 때 전체 테이블을 잠급니다. 동시성 성능이 좋지 않으며, 행 잠금은 트랜잭션이 데이터를 조작할 때만 조작된 데이터를 잠그고 동시성 성능은 좋지만 잠금의 생성, 검사 및 파기는 리소스를 소비해야 하므로 일반적으로 테이블 잠금이 행보다 낫다. lock 일부 리소스를 절약할 수 있지만 비즈니스 및 성능 요구 사항을 고려하여 일반적으로 행 잠금을 사용하지만 sql의 스토리지 엔진마다 테이블 잠금과 행 잠금을 다르게 지원합니다.innoDB의 경우 행 잠금, 잠금 및 테이블 잠금을 지원합니다.
트랜잭션 격리 및 다른 격리로 인해 발생할 수 있는 문제와 관련하여 다른 기사를 읽는 것이 좋습니다. 따라서 여기에서 반복하지 않겠습니다.
2. MVCC 메커니즘: SQL 격리 수준의 기본 격리 수준은 반복 읽기(Repeatly Read)입니다.일반적으로 RR은 팬텀 읽기 문제를 해결할 수 없지만 innoDB에 의해 구현된 RR은 팬텀 읽기 문제를 피할 수 있습니다.RR To 더티 읽기, 반복 불가능한 읽기 및 팬텀 읽기와 같은 문제를 해결하기 위해 MVCC가 사용됩니다. MVCC의 전체 이름은 다중 버전 동시성 제어 프로토콜인 다중 버전 동시성 제어입니다. MVCC에는 다음과 같은 특성이 있습니다. 동시에 서로 다른 트랜잭션에서 읽은 데이터는 다를 수 있습니다(다른 버전의 데이터는 서로 다름). 아래 그림과 같이 이러한 특성을 더 잘 반영할 수 있습니다. T5 시간에 트랜잭션 A 및 트랜잭션 C 서로 다른 버전의 데이터를 읽을 수 있습니다.
MVCC의 가장 큰 장점은 읽기 잠금을 추가할 필요가 없어 읽기와 쓰기의 충돌이 없다는 것입니다. 및 데이터 구조: 1. 숨겨진 열:
데이터베이스 각 데이터 조각에는 숨겨진 열이 있으며 숨겨진 열에는 이 행의 데이터 트랜잭션을 가리키는 id와 undolog에 대한 포인터가 있습니다.
2. Undolog 기반 버전 체인: 각 데이터의 숨겨진 열에는 undolog에 대한 포인터가 있으며 각 undolog 포인터는 이전 버전의 undolog를 가리키므로 undolog 버전 체인을 형성합니다.
3. ReadView: 열과 버전 체인을 숨김으로써 데이터를 이전 버전으로 복원할 수 있지만 복원할 특정 버전은 특정 ReadView에서 결정해야 합니다. 소위 ReadView는 트랜잭션(트랜잭션 A)이 특정 순간에 전체 트랜잭션 시스템(trx_sys)의 스냅샷을 찍고 나중에 읽기 작업을 수행할 때 읽기 트랜잭션 id를 trx_sys와 비교하여 결정하는 것을 의미합니다. 원하는 읽기 가져온 데이터가 이 ReadView에 유효한지 여부, 즉 트랜잭션 A에 유효한지 여부입니다.
trx_sys의 주요 내용과 가시성을 판단하는 규칙은 다음과 같습니다.
low_limit_id: 시스템이 생성된 ReadView에서 트랜잭션에 할당해야 하는 다음 id를 나타내며 트랜잭션의 id가 low_limit_id보다 크거나 같으면 ReadView에 표시되지 않습니다.
up_limit_id: ReadView가 생성될 때 시스템에서 활성 상태였던 트랜잭션을 나타내며 활성 트랜잭션의 id가 up_limit_id보다 작으면 ReadView에 표시됩니다.
rw_trx_ids: ReadView가 생성될 때 시스템에서 활성 트랜잭션의 id 목록을 나타내며 쿼리 데이터의 id가 low_limit_id와 up_limit_id 사이에 있으면 트랜잭션이 rw_trx_ids에 있는지 확인해야 합니다. ReadView가 생성될 때 여전히 활성 상태이면 ReadView가 보이지 않으며 그렇지 않으면 ReadView가 생성될 때 트랜잭션이 커밋되었음을 의미하므로 ReadView에 데이터가 표시됩니다.
3. MVCC는 더티 읽기, 반복 불가능한 읽기, 팬텀 읽기와 같은 문제를 피하기 위한 노래와 같습니다.
3.1 더티 읽기:
트랜잭션 A가 T3에서 장산의 잔고를 읽으면 ReadView가 생성되는데 이때 트랜잭션 B는 Commit이 되지 않은 상태이므로 트랜잭션 id는 ReadView의 rw_trx_ids에 있어야 한다. 트랜잭션 B의 수정은 ReadView가 보이지 않습니다. 다음으로 트랜잭션 A는 포인터가 가리키는 언두 로그에 따라 이전 버전의 데이터를 조회하여 장산의 잔고가 100임을 획득한다. 이러한 방식으로 트랜잭션 A는 더티 읽기를 방지합니다.
3.2 반복 불가능한 읽기
트랜잭션 A가 T2에서 장산의 잔액을 읽기 전에 ReadView가 생성됩니다. 이때 트랜잭션 B는 두 가지 상황으로 논의되는데, 하나는 그림과 같이 트랜잭션이 시작되었으나 커밋되지 않은 경우이며, 이때 트랜잭션 id는 ReadView의 rw_trx_ids에 있고, 다른 하나는 해당 트랜잭션이다. B는 아직 시작하지 않았습니다.이 시점에서 트랜잭션 id는 ReadView의 low_limit_id보다 크거나 같습니다. 두 경우 모두 앞에서 소개한 규칙에 따라 트랜잭션 B의 수정 사항이 ReadView에 표시되지 않습니다.
트랜잭션 A가 T5에서 장산의 잔액을 다시 읽으면 T2에서 생성된 ReadView에 따라 데이터의 가시성을 판단하여 트랜잭션 B의 수정이 보이지 않는다고 판단할 수 있습니다. 포인터가 가리키는 실행 취소 로그 데이터의 첫 번째 버전의 경우 zhangsan의 잔액은 100이므로 반복할 수 없는 읽기를 방지합니다.
3.3 팬텀 판독
팬텀 읽기를 방지하는 MVCC의 메커니즘은 반복 불가능한 읽기를 방지하는 것과 매우 유사합니다.
트랜잭션 A가 T2 시간에 사용자 잔액 0<id<5를 읽기 전에 ReadView가 생성됩니다. 이때 트랜잭션 B는 두 가지 상황으로 논의되는데, 하나는 그림과 같이 트랜잭션이 시작되었으나 커밋되지 않은 경우이며, 이때 트랜잭션 id는 ReadView의 rw_trx_ids에 있고, 다른 하나는 해당 트랜잭션이다. B는 아직 시작하지 않았습니다.이 시점에서 트랜잭션 id는 ReadView의 low_limit_id보다 크거나 같습니다. 두 경우 모두 앞에서 소개한 규칙에 따라 트랜잭션 B의 수정 사항이 ReadView에 표시되지 않습니다.
트랜잭션 A가 T5 시점에 사용자 잔고 0<id<5를 다시 읽으면 T2 시점에 생성된 ReadView에 따라 데이터의 가시성을 판단하여 트랜잭션 B의 수정 사항이 보이지 않는다고 판단할 수 있습니다. . 따라서 새로 삽입된 데이터 lisi(id=2)에 대해 트랜잭션 A는 포인터가 가리키는 언두 로그에 따라 이전 버전의 데이터를 쿼리하고 데이터가 존재하지 않음을 발견하여 팬텀 읽기를 피합니다.
잠긴 읽기는 쿼리할 때 쿼리된 데이터(공유 잠금 또는 배타적 잠금)를 잠급니다. 잠금의 특성으로 인해 트랜잭션이 잠그고 데이터를 읽으면 다른 트랜잭션이 데이터를 쓸 수 없으므로 더티 읽기 및 반복 불가능한 읽기를 피할 수 있습니다. 팬텀 읽기를 방지하려면 다음 키 잠금을 통과해야 합니다. 넥스트 키 락은 레코드 락( record lock ) + 갭 락( gap lock ) 에 해당하는 행 락의 일종으로 , 레코드 자체를 잠그는 것 ( 레코드 락 의 기능 ) 뿐만 아니라 범위를 잠급니다 (갭 잠금 기능 ) . 따라서 잠긴 읽기는 더티 읽기, 반복 불가능한 읽기 및 팬텀 읽기를 방지하여 격리를 보장할 수도 있습니다.
4. 일관성
1. 개념: 일관성은 트랜잭션 실행 후 데이터베이스의 무결성 제약 조건이 깨지지 않고 트랜잭션 실행 전후의 데이터 상태가 합법적임을 의미합니다.
2. 실현: 일관성은 데이터베이스의 궁극적인 목표이며 원자성, 격리성, 지속성은 모두 일관성을 충족시키기 위해 존재하며 데이터 일관성을 보장하기 위한 데이터베이스 수준을 제외하고 일관성의 실현은 애플리케이션 계층에서도 보장됩니다.
일관성을 달성하기 위한 조치:
1. 원자성(Atomicity), 지속성(Persistence), 고립성(Isolation)을 이용하여 일관성을 확보하라 이 세 가지 특성이 보장되지 않으면 일관성도 보장될 수 없다.
2. 데이터베이스 자체는 예를 들어 플라스틱 데이터에 문자열 정보를 삽입할 수 없으며 문자열의 길이가 열의 최대 길이를 초과할 수 없도록 보장합니다.
3. 애플리케이션 수준에서 보장 예를 들어 이체 작업이 받는 사람의 잔액을 늘리지 않고 전송자의 잔액만 차감한다면 데이터베이스가 아무리 완벽하더라도 상태의 일관성을 보장할 수 없습니다.
5. 요약:
- 원자성: 문이 완전히 실행되거나 전혀 실행되지 않는 트랜잭션의 핵심 기능 트랜잭션 자체는 원자성으로 정의되며 구현은 주로 실행 취소 로그를 기반으로 합니다.
- 지속성: 트랜잭션이 커밋된 후 다운타임 및 기타 이유로 인해 데이터가 손실되지 않도록 보장합니다. 구현은 주로 리두 로그를 기반으로 합니다.
- 격리: 트랜잭션 실행이 가능한 한 다른 트랜잭션의 영향을 받지 않도록 보장 InnoDB의 기본 격리 수준은 RR이며 RR의 구현은 주로 잠금 메커니즘(다음 키 잠금 포함), MVCC(숨김 포함)를 기반으로 합니다. 데이터 열 및 실행 취소 로그 체인, ReadView 기반 버전)
- 일관성: 트랜잭션이 추구하는 궁극적인 목표, 일관성의 실현에는 데이터베이스 수준의 보장과 애플리케이션 수준의 보장이 모두 필요합니다.