실행 취소, mysql의 로그 다시 실행 및 분산 트랜잭션을 위한 솔루션

私聊互关,也可在评论区评论一下

실행 취소 로그 및 다시 실행 로그

데이터베이스 시스템에는 데이터를 저장하기 위한 파일과 로그를 저장하기 위한 파일이 있습니다. 로그에는 메모리에 캐시된 로그 버퍼와 디스크 파일 로그 파일도 있습니다. MySQL에는 트랜잭션과 관련된 두 가지 유형의 로그 파일이 있습니다. 실행 취소 로그와 다시 실행 로그입니다.

실행 취소 로그

데이터베이스 트랜잭션은 원자적 이며 트랜잭션이 실패하면 데이터를 롤백해야 합니다.

실행 취소 로깅을 사용하여 원자성을 달성할 수 있습니다. Undo Log의 원리는 매우 간단하며, 트랜잭션의 원자성을 만족시키기 위해서는 데이터를 운용하기 전에 먼저 Undo Log에 데이터를 백업해야 합니다. 그런 다음 데이터를 수정합니다. 오류가 발생하거나 사용자가 ROLLBACK 문을 실행하면 시스템은 Undo Log의 백업을 사용하여 트랜잭션이 시작되기 전의 상태로 데이터를 복원할 수 있습니다. 데이터베이스는 데이터를 디스크에 쓰기 전에 먼저 메모리에 데이터를 캐시한 다음 트랜잭션이 커밋될 때 디스크에 씁니다. Undo Log로 원자적이고 내구성 있는 트랜잭션을 달성하는 단순화된 프로세스:

假设有A、B两个数据,值分别为1,2。 A. 事务开始. B. 记录A=1到undo log. C. 修改A=3. D. 记录B=2到undo log. E. 修改B=4. F. 将undo log写到磁盘。 G. 将数据写到磁盘。 H. 事务提交

如何保证持久性?

事务提交前,会把修改数据到磁盘前,也就是说只要事务提交了,数据肯定持久化

如何保证原子性?

每次对数据库修改,都会把修改前数据记录在undo log,那么需要回滚时,可以读取undo log,恢复数据。

若系统在G和H之间崩溃

此时事务并未提交,需要回滚。而undo log已经被持久化,可以根据undo log来恢复数据

若系统在G之前崩溃

此时数据并未持久化到硬盘,依然保持在事务之前的状态

Defect: 각 트랜잭션을 커밋하기 전에 디스크에 데이터를 쓰고 Undo Log를 기록합니다. 이는 많은 디스크 IO를 유발하므로 성능이 매우 낮습니다.

일정 기간 동안 데이터를 캐시할 수 있으면 IO를 줄이고 성능을 향상시킬 수 있습니다. 그러나 이것은 트랜잭션의 내구성을 잃게 됩니다. 따라서 지속성을 달성하기 위해 Redo Log 라는 또 다른 메커니즘이 도입되었습니다 .

Undo Log와 달리 Redo Log 는 새로운 데이터 의 백업 을 기록합니다. 트랜잭션이 커밋되기 전에 Redo Log가 지속되는 한 데이터를 유지할 필요가 없으므로 IO 수가 줄어듭니다.

假设有A、B两个数据,值分别为1,2

A. 事务开始. B. 记录A=1到undo log buffer. C. 修改A=3. D. 记录A=3到redo log buffer. E. 记录B=2到undo log buffer. F. 修改B=4. G. 记录B=4到redo log buffer. H. 将undo log写入磁盘 I. 将redo log写入磁盘 J. 事务提交

- 如何保证原子性?

  如果在事务提交前故障,通过undo log日志恢复数据。如果undo log都还没写入,那么数据就尚未持久化,无需回滚

- 如何保证持久化?

  大家会发现,这里并没有出现数据的持久化。因为数据已经写入redo log,而redo log持久化到了硬盘,因此只要到了步骤`I`以后,事务是可以提交的。

- 内存中的数据库数据何时持久化到磁盘?

  因为redo log已经持久化,因此数据库数据写入磁盘与否影响不大,不过为了避免出现脏数据(内存中与磁盘不一致),事务提交后也会将内存数据刷入磁盘(也可以按照固设定的频率刷新内存数据到磁盘中)。

- redo log何时写入磁盘

  redo log会在事务提交之前,或者redo log buffer满了的时候写入磁盘
为什么要使用redo log
- 数据库数据写入是随机IO,性能很差
- redo log在初始化时会开辟一段连续的空间,写入是顺序IO,性能很好
- 实际上undo log并不是直接写入磁盘,而是先写入到redo log buffer中,当redo log持久化时,undo log就同时持久化到硬盘了,因此事务提交前,只需要对redo log持久化即可

-redo log中记录的数据,有可能包含尚未提交事务,如果此时数据库崩溃,那么如何完成数据恢复?

数据恢复有两种策略:

恢复时,只重做已经提交了的事务

恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些未提交的事务

Inodb引擎采用的是第二种方案,因此undo log要在 redo log前持久化

분산 트랜잭션

데이터베이스가 수평으로 분할되고 서비스가 수직으로 분할된 후 비즈니스 운영은 일반적으로 완료하기 위해 여러 데이터베이스와 서비스에 걸쳐 있습니다. 분산 네트워크 환경에서는 모든 서비스와 데이터베이스가 100% 사용 가능하다고 보장할 수 없으며 일부 서비스와 데이터베이스는 성공적으로 실행되지만 다른 서비스와 데이터베이스는 실패합니다. 일부 비즈니스 운영은 성공하고 일부는 실패하면 비즈니스 데이터가 일관되지 않습니다.

예를 들어, 지불 테이블과 재고 테이블이 서로 다른 데이터베이스에 있고 사용자가 구매 시 금액을 공제하지 못하고 지불 테이블이 롤백되지만 재고 테이블이 상품 테이블과 동일한 데이터베이스에 있지 않기 때문에 롤백이 발생하지 않습니다.

 

분산 트랜잭션 해결을 위한 아이디어

CAP 정리 및 BASE 이론은 이전 기사 참조 가능

해결 방법 1: 단계적으로 제출

1994년에 X/Open 조직(현재 Open Group)은 분산 트랜잭션 처리를 위한 DTP 모델을 정의했습니다. 모델에는 다음 역할이 포함됩니다.

  • 애플리케이션(AP): 당사 마이크로서비스

  • 트랜잭션 관리자( TM ): 글로벌 트랜잭션 관리자

  • 리소스 관리자(RM): 일반적으로 데이터베이스

  • Communication Resource Manager(CRM): TM과 RM 간의 통신 미들웨어

이 모델에서 분산 트랜잭션(글로벌 트랜잭션)은 다른 AP와 RM에서 실행되는 많은 로컬 트랜잭션으로 분할될 수 있습니다. 각 로컬 트랜잭션에 대한 ACID는 잘 구현되어 있지만 글로벌 트랜잭션은 그 안에 포함된 모든 로컬 트랜잭션이 동시에 성공할 수 있고 하나의 로컬 트랜잭션이 실패하면 다른 모든 트랜잭션을 롤백해야 함을 보장해야 합니다. 그러나 문제는 로컬 트랜잭션 처리 과정에서 다른 트랜잭션의 실행 상태를 알 수 없다는 것입니다. 따라서 트랜잭션 실행 상태를 동기화하기 위해 CRM을 통해 각 로컬 트랜잭션에 알려야 합니다.

2단계 커밋

1단계: 준비 단계, 각 로컬 트랜잭션은 로컬 트랜잭션의 준비를 완료합니다.

2단계: 실행 단계, 각 로컬 트랜잭션은 이전 단계의 실행 결과에 따라 커밋하거나 롤백합니다.

이 프로세스에는 조정자(조정자)와 거래 참여자(투표자)가 필요합니다.

 

투표 단계 : 조정 그룹은 각 거래 참여자에게 거래가 실행될 수 있는지 묻습니다. 각 트랜잭션 참여자는 트랜잭션을 실행하고 다시 실행 및 실행 취소 로그를 작성한 다음 트랜잭션의 성공적인 실행에 대한 정보를 피드백하고( agree), 실패하면 동의하지 않음을 반환합니다.

커밋 단계 : 조정 그룹은 각 참가자가 트랜잭션( agree)을 실행할 수 있음을 확인하여 각 트랜잭션 참가자에게 commit지시를 내리고 각 트랜잭션 참가자는 트랜잭션을 커밋하고 그렇지 않으면 롤백합니다.

결함:

단일 실패 지점 문제: 조정 그룹이 끊기면 다음에 커밋할지 롤백할지 결정할 수 없습니다.

차단 문제: 준비 단계와 커밋 단계에서 각 트랜잭션 참여자는 로컬 리소스를 잠그고 다른 트랜잭션의 실행 결과를 기다리며 차단 시간이 길고 리소스 잠금 시간이 너무 길어 실행 효율성이 상대적으로 낮습니다. .

솔루션 2: TCC 모드

본질적으로 보상의 방법입니다. 트랜잭션 작업 프로세스에는 세 가지 방법이 있습니다.

  • 시도: 리소스 감지 및 예약

  • 확인: 실행된 비즈니스 작업이 제출되고 시도가 성공하면 확인이 성공해야 합니다.

  • 취소: 예약된 리소스가 해제됩니다.

실행에는 두 단계가 있습니다.

  • 준비 단계(시도): 자원 탐지 및 예약;

  • 실행 단계(확인/취소): 이전 단계의 결과에 따라 다음 실행 방법을 결정합니다. 이전 단계의 모든 거래 참여자가 성공했다면 여기에서 확인을 실행하십시오. 그렇지 않으면 취소를 실행하십시오.

 시도, 확인, 취소는 다른 참가자의 영향을 받지 않는 독립적인 거래이며 다른 사람을 기다리는 것을 차단하지 않습니다.

예: 계정 A의 원래 잔액이 100이고 잔액에서 30위안을 공제해야 한다고 가정합니다.

 단점 : 시도, 확인, 취소를 구현하기 위해서는 수동으로 코드를 작성해야 하고, 코드 침입이 많아 개발 복잡성을 증가시킨다. 동시에 취소 작업이 실패하면 리소스를 해제할 수 없으며 재시도 메커니즘을 도입해야 하며 재시도는 반복 실행으로 이어질 수 있으며 재시도 중 멱등 문제도 고려해야 합니다.

솔루션 3: MQ 사용

트랜잭션 개시자 A는 로컬 트랜잭션을 실행하고, 실행할 트랜잭션 정보를 MQ를 통해 트랜잭션 참여자 B에게 전송하고, 트랜잭션 참여자 B는 메시지를 수신한 후 로컬 트랜잭션을 실행한다. mq의 메시지 신뢰성을 사용하여 트랜잭션 참여자 B는 메시지가 결국 소비될 수 있는지 확인해야 하며 실패하면 여러 번 재시도해야 합니다.

단점: MQ의 신뢰성에 따라 메시지 개시자는 롤백할 수 있지만, 메시지 참여자는 트랜잭션 롤백을 일으킬 수 없고, MQ 메시지를 적시에 전송하는지 여부에 따라 트랜잭션 적시성이 나쁘다.

해결 방법 4: AT 모드

TCC 모드와 유사하게 2단계로 나누어져 있지만, Seata에서 구현하는 2단계 코드를 직접 작성할 필요는 없습니다.

첫 번째 단계에서 Seata는 "비즈니스 SQL"을 가로채서 먼저 SQL 의미를 구문 분석하고 " "에서 업데이트할 비즈니스 데이터를 찾고 비즈니스 데이터가 업데이트되기 전에 业务 SQL" "로 저장 한 다음 업데이트를 위해 " "를 실행합니다. 비즈니스 데이터.데이터 업데이트 후 " "로 저장하고 마지막으로 글로벌 행 잠금을 획득하고 트랜잭션을 커밋합니다. 위의 작업은 모두 데이터베이스 트랜잭션 내에서 완료되어 1단계 작업의 원자성을 보장합니다.before image业务 SQLafter image

before image여기서 합계 after image데이터베이스의 실행 취소 및 다시 실행 로그와 유사하지만 실제로는 데이터베이스로 시뮬레이션됩니다.

 두 번째 단계가 제출되면 첫 번째 단계에서 " 业务 SQL"가 데이터베이스에 제출되었기 때문에 Seata 프레임워크는 첫 번째 단계에서 저장된 스냅샷 데이터와 행 잠금만 삭제하면 데이터 정리가 완료됩니다.

두 번째 단계가 롤백인 경우 Seata는 첫 번째 단계에서 실행된 " "를 롤백 业务 SQL하여 비즈니스 데이터를 복원해야 합니다. 롤백 방법은 " before image"를 사용하여 비즈니스 데이터를 복원하는 것입니다.

추천

출처blog.csdn.net/weixin_52210557/article/details/124223667