이 글은 MySQL의 일반적인 로그 문제에 대해 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
MySQL에는 두 가지 로그, 즉 다시 실행 로그와 아카이브 로그(binlog)가 있습니다. (추천 과정: MySQL Tutorial)
그 중 binlog는 대기 데이터베이스로 사용하거나 데이터베이스 기록 데이터 복원을 위해 저장할 수 있습니다. 이는 서버 계층에서 구현되며 모든 엔진에서 공유될 수 있습니다. 리두 로그는 InnoDB에 고유한 로그이며 충돌 방지 기능을 지원하는 데 사용됩니다.
MySQL 트랜잭션의 2단계 커밋에 대해 들어보셨을 것입니다. 즉, 트랜잭션이 제출될 때 준비와 커밋의 두 단계로 나누어진다는 뜻입니다.
그림 1은 마지막 세 단계에서 REDO 로그 준비가 먼저 완료된 다음 binlog가 기록되고 마지막으로 REDO 로그 커밋 단계에 진입하는 것을 볼 수 있습니다.
그림 1 2단계 커밋 다이어그램
여기서 먼저 오해를 설명하고 싶습니다. 이 그림은 단지 업데이트 문의 실행 과정이 아닌가요? 커밋 문도 어떻게 호출됩니까?
일반적으로 이 질문을 하는 이유는 "커밋"의 두 가지 개념을 혼동하기 때문입니다. 질문의 "커밋 문"은 거래 주문을 제출하는 데 사용되는 MySQL 구문을 나타냅니다. 일반적으로 트랜잭션 시작/시작과 함께 사용됩니다. 사진에 사용된 "커밋 단계"는 트랜잭션 제출 프로세스의 작은 단계를 의미하며 마지막 단계이기도 합니다. 이 단계가 완료되면 거래가 제출됩니다.
"커밋 문"이 실행되면 "커밋 단계"가 포함됩니다.
이 예에서는 트랜잭션이 명시적으로 시작되지 않았으므로 업데이트 문 자체가 트랜잭션이 실행 후 제출될 때 이 "커밋 단계"가 사용됩니다.
다음으로, 2단계 제출의 서로 다른 순간에 MySQL이 비정상적으로 다시 시작되면 어떤 일이 발생하는지 함께 분석해 보겠습니다.
그림의 A 시점, 즉 Redo 로그를 작성한 후 준비 단계이고 binlog를 작성하기 전인 시점에 Crash가 발생하면 아직 binlog가 작성되지 않았고 Redo 로그도 작성되지 않았기 때문입니다. 제출되었으므로 크래시 복구 중에 이 트랜잭션이 롤백됩니다. 이때 binlog는 아직 작성되지 않았기 때문에 Standby DB로 전송되지 않습니다. 이쯤 되면 우리 모두 이해할 수 있습니다. binlog가 작성되고 다시 실행 로그가 커밋되기 전에 충돌이 발생하는 B 시간에 문제가 주로 발생한다는 것을 알고 있습니다. MySQL은 충돌 복구를 어떻게 처리합니까?
2단계 제출은 모두가 "괜찮아"라고 말할 때 모두에게 기회를 주는 것입니다.
질문 5: 두 개의 로그를 도입하지 않으면 2단계 제출이 필요하지 않습니다. 크래시 복구와 아카이브 지원을 위해 binlog만 사용하는 것만으로는 충분하지 않나요?
답변: 이 질문을 다시 번역하면 binlog만 유지되고 제출 프로세스는 다음과 같이 변경될 수 있습니다.... -> "메모리에 데이터 업데이트" -> -> "트랜잭션 커밋"도 충돌 복구 기능을 제공합니까?
답은 '아니오'입니다.
역사적인 이유가 있다면 InnoDB가 MySQL의 기본 스토리지 엔진이 아니라는 점입니다. MySQL의 기본 엔진은 MyISAM이며 이는 충돌 복구를 지원하도록 설계되지 않았습니다.
InnoDB는 MySQL 플러그인으로 MySQL 엔진 제품군에 합류하기 전에 이미 충돌 복구 및 트랜잭션 지원을 제공하는 엔진이었습니다.
InnoDB를 MySQL에 연결한 후 binlog에는 충돌 복구 기능이 없으므로 InnoDB의 원래 redo 로그를 사용하는 것이 더 낫다는 것을 알았습니다.
그리고 구현 이유에 대해 이야기하면 여러 가지가 있습니다. 질문에서 언급했듯이 크래시 복구 프로세스를 구현하는 데는 binlog만 사용되며, 여기에는 redo 로그가 없습니다.
그림 2 binlog만 충돌 복구를 지원합니다
이러한 프로세스에서도 binlog는 여전히 충돌 복구를 지원할 수 없습니다. 지원되지 않는 점에 대해 이야기하겠습니다. binlog에는 "데이터 페이지"를 복원하는 기능이 없습니다.
그림에 표시된 위치, 즉 binlog2가 작성되었지만 전체 트랜잭션이 아직 커밋되지 않은 경우 MySQL이 충돌합니다.
다시 시작한 후 엔진 내부 트랜잭션 2가 롤백되고 binlog2를 적용하여 보충할 수 있지만 트랜잭션 1의 경우 시스템은 이미 제출이 완료된 것으로 간주하므로 binlog1을 다시 적용하지 않습니다.
그러나 InnoDB 엔진은 WAL 기술을 사용하여 트랜잭션을 실행할 때 메모리와 로그에 쓴 후 트랜잭션이 완료됩니다. 나중에 충돌이 발생하면 로그를 사용하여 데이터 페이지를 복구하세요.
즉, 그림의 이 위치에서 충돌이 발생하면 트랜잭션 1도 손실될 수 있으며 데이터 페이지 수준도 손실됩니다. 이때 데이터 페이지의 업데이트 내역은 binlog에 기록되지 않으며 복원이 불가능합니다.
binlog의 내용을 최적화하고 데이터 페이지의 변경 사항을 기록하도록 할 수 있나요? 예, 하지만 이는 실제로 또 다른 리두 로그를 만드는 것입니다.
그래서 적어도 현재 binlog 기능은 충돌 복구를 지원할 수 없습니다.
질문 6: 이를 되돌리고 binlog 대신 redo 로그만 사용할 수 있나요?
답변: 충돌 복구의 관점에서는 괜찮습니다. 2단계 커밋이 없도록 binlog를 끌 수 있지만 시스템은 여전히 충돌로부터 안전합니다.
그러나 업계 여러 회사의 사용 시나리오를 살펴보면 공식 프로덕션 라이브러리에서는 binlog가 항상 켜져 있음을 알 수 있습니다. binlog에는 redo log가 대체할 수 없는 기능이 있기 때문입니다.
하나는 보관 중입니다. Redo 로그는 루프로 작성되는데, 끝까지 기록하면 처음으로 돌아가서 계속 작성해야 합니다. 이런 방식으로는 기록 로그를 유지할 수 없으며, 리두 로그는 아카이브 역할을 할 수 없습니다.
하나는 MySQL 시스템이 binlog에 의존한다는 것입니다. Binlog는 MySQL이 처음부터 갖고 있던 기능으로 여러 곳에서 사용된다. 그 중 MySQL 시스템의 고가용성의 기본은 binlog 복제이다.
또한 이기종 시스템(예: 일부 데이터 분석 시스템)을 보유하고 있는 회사가 많으며 이러한 시스템은 MySQL binlog를 사용하여 자체 데이터를 업데이트합니다. binlog가 꺼지면 이러한 다운스트림 시스템은 입력할 수 없습니다.
요컨대, MySQL 고가용성을 포함한 많은 시스템 메커니즘이 이제 binlog에 의존하기 때문에 "까치 둥지를 차지하는 비둘기" redo 로그는 아직 불가능합니다. 알다시피, 생태계를 발전시키는 것이 얼마나 중요한지 알 수 있습니다.
마지막으로 Ding Qi의 "MySQL 실무 강의 45" 칼럼을 주목해 보시길 권합니다. 칼럼에서 Ding Qi는 트랜잭션, 인덱스, 잠금 등 MySQL 학습에 필요한 주요 지식을 정리하는 데 도움을 줄 것이며, 개발 과정에서 자주 직면하는 특정 문제도 분석하고 토론하여 이해를 돕습니다. 문제의 본질. MySQL 핵심 기술과 원리에 대한 자세한 설명과 36가지 일반적인 MySQL 문제점에 대한 분석을 받게 됩니다.
문 형식의 binlog에는 끝에 COMMIT가 있고
row 형식의 binlog에는 끝에 XID 이벤트가 있습니다.
또한 MySQL 버전 5.6.2 이후에는 binlog 내용의 정확성을 확인하기 위해 binlog-checksum 매개변수도 도입되었습니다. 디스크 문제로 인해 로그 중간에 오류가 발생할 수 있는 binlog 로그의 경우 MySQL은 체크섬 결과를 확인하여 알아낼 수 있습니다. 따라서 MySQL에는 여전히 트랜잭션 binlog의 무결성을 확인할 수 있는 방법이 있습니다.
답변: XID라는 공통 데이터 필드가 있습니다. 충돌에서 복구할 때 리두 로그가 순서대로 스캔됩니다:
위 내용은 MySQL의 일반적인 로그 문제 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!