[2025]MySQL的事務機制是什么樣的?redolog,undolog、binog三種日志的區別?二階段提交是什么?ACID怎么保證的?主從復制的過程?

MySQL事務機制與日志系統詳解

一、MySQL事務機制

1. 事務特性(ACID)

特性實現機制
原子性(Atomicity)undo log回滾,(事務作為一個整體被執行,包含在其中的對數據庫的操作要么全部被執行,要么都不執行)。
一致性(Consistency)約束檢查+雙寫緩沖(事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態的含義是數據庫中的數據應滿足完整性約束。)
隔離性(Isolation)MVCC+鎖機制(多個事務并發執行時,一個事務的執行不應影響其他事務的執行。)
持久性(Durability)redo log持久化(一個事務一旦提交,他對數據庫的修改應該永久保存在數據庫中)

2. 事務隔離級別

首先需要了解

臟讀:讀到了其他事務還沒有提交的數據。


不可重復讀:對某數據進行讀取過程中,有其他事務對數據進行了修改(UPDATE、DELETE),導致第二次讀取的結果不同。


幻讀:事務在做范圍查詢過程中,有另外一個事務對范圍內新增了記錄(INSERT),導致范圍查詢的結果條數不一致。
?

級別臟讀不可重復讀幻讀實現方式
讀未提交可能可能可能無鎖
讀已提交不可能可能可能MVCC快照讀
可重復讀不可能不可能可能(InnoDB實際避免)一致性視圖
串行化不可能不可能不可能讀寫鎖

1.查看當前會話隔離級別

select @@tx_isolation;

在MySQL 8.0中:SELECT @@transaction_isolation;

2.查看系統當前隔離級別

select @@global.tx_isolation;

3.設置當前會話隔離級別

set session transaction isolatin level repeatable read;

4.設置系統當前隔離級別

set global transaction isolation level repeatable read;

5.命令行,開始事務時

set autocommit=off 或者 start transaction

一次InnnoDB的update操作,涉及到BufferPool、BinLog、UndoLog、RedoLog以及物理磁盤,完整的一次操作過程基本如下:

1、在Buffer Pool中讀取數據:當InnoDB需要更新一條記錄時,首先會在Buffer Pool中查找該記錄是否在內存中。如果沒有在內存中,則從磁盤讀取該頁到Buffer Pool中。

2、記錄UndoLog:在修改操作前,InnoDB會在Undo Log中記錄修改前的數據。Undo Log是用來保證事務原子性和一致性的一種機制,用于在發生事務回滾等情況時,將修改操作回滾到修改前的狀態,以達到事務的原子性和一致性。UndoLog的寫入最開始寫到內存中的,然后由1個后臺線程定時刷新到磁盤中的。

3、在Buffer Pool中更新:當執行update語句時,InnoDB會先更新已經讀取到Buffer Pool中的數據,而不是直接寫入磁盤。同時,InnoDB會將修改后的數據頁狀態設置為“臟頁”(Dirty Page)狀態,表示該頁已經被修改但尚未寫入磁盤。

4、記錄RedoLog Buffer:InnoDB在Buffer Pool中記錄修改操作的同時,InnoDB 會先將修改操作寫入到 redo log buffer 中。

5、提交事務:在執行完所有修改操作后,事務被提交。在提交事務時,InnoDB會將Redo Log寫入磁盤,以保證事務持久性。

6、寫入磁盤:在提交過程后,InnoDB會將Buffer Pool中的臟頁寫入磁盤,以保證數據的持久性。但是這個寫入過程并不是立即執行的,是有一個后臺線程異步執行的,所以可能會延遲寫入,總之就是MYSQL會選擇合適的時機把數據寫入磁盤做持久化。

7、記錄Binlog:在提交過程中,InnoDB會將事務提交的信息記錄到Binlog中。Binlog是MySQL用來實現主從復制的一種機制,用于將主庫上的事務同步到從庫上。在Binlog中記錄的信息包括:事務開始的時間、數據庫名、表名、事務ID、SQL語句等。
?

?

image.png


需要注意的是,在binlog和redolog的寫入過程中,其實是分成了2階段的,通過2階段提交的方式來保證一致性的。

一次insert操作呢:

1、寫入undolog,先將事務修改前的數據記錄到Undo Log中。

2、寫入redolog,處于prepare階段 (表示事務已修改但未提交)。

3、寫入binlog,將binlog 內存日志數據寫入文件緩沖區并刷新到磁盤中。

4、寫入redolog,處于commit階段。

二、三大日志系統對比

在MySQL中,redo log和undo log只適用于InnoDB存儲引擎,因為要支持事務。而不適用于MyISAM等其他存儲引擎。而binlog則適用于所有存儲引擎。

1. redo log(重做日志)

Redo Log是MySQL用于實現崩潰恢復和數據持久性的一種機制

作用

  • 確保事務持久性

  • 實現WAL(Write-Ahead Logging)機制

  • 崩潰恢復時重放已提交事務

特點

  • 物理日志(記錄頁的修改)

  • 循環寫入(固定大小文件組)

  • InnoDB引擎特有

配置參數

innodb_log_file_size = 512M  # 單個日志文件大小
innodb_log_files_in_group = 2 # 日志文件數量

2. undo log(回滾日志)


Undo Log則用于在事務回滾或系統崩潰時撤銷(回滾)事務所做的修改。Undo Log還支持MVCC(多版本并發控制)機制,用于在并發事務執行時提供一定的隔離性。

作用

  • 事務回滾時恢復數據

  • 實現MVCC多版本控制

  • 提供一致性讀視圖

特點

  • 邏輯日志(記錄反向SQL)

  • 存儲在系統表空間或獨立undo表空間

  • 隨事務結束逐漸清理

存儲結構

-- 查看undo表空間
SHOW VARIABLES LIKE 'innodb_undo%';

3. binlog(歸檔日志)

用來數據備份、崩潰恢復、主從復制。主要用來對數據庫進行數據備份、崩潰恢復和數據復制等操作

特點

  • Server層實現(所有引擎通用)

  • 邏輯日志(SQL語句或行事件)

  • 追加寫入(可配置大小)

三種格式:

格式寫入時機性能安全性
STATEMENT事務提交(SQL 語句的原文)低(導致主從同步的數據不一致)
ROW事務提交(每個數據更改的具體行的細節)低(記錄更多的內容)高(記錄行變化)
MIXED自動選擇

在RR下,row和statement都可以生效,但是在RC下,只有row格式才能生效。具體見上面我們貼的那個鏈接的內容。

三、二階段提交(2PC)

1. 跨日志協調過程

2. MySQL實現流程

  1. ●Prepare 階段
    ????????○這個階段 SQL 已經成功執行并生成 redolog,處于prepare階段
    ●BinLog持久化
    ????????○binlog 提交,通過 write() 將 binlog 內存日志數據寫入文件緩沖區;
    ????????○通過fsync() 將 binlog 從文件緩沖區永久寫入磁盤;
    ●Commit
    ????????○在執行引擎內部執行事務操作,更新redolog,處于Commit階段


    write 操作將數據寫入文件的緩沖區,這意味著 write 操作完成后,并不一定立即將數據持久化到磁盤上,而是將數據暫時存儲在內存中


    fsync 用于強制將文件的修改持久化到磁盤上。它通常與 write 配合使用,以確保文件的修改在 fsync 操作完成后被寫入磁盤。

3. 崩潰恢復邏輯

  • binlog無記錄:回滾事務(redo prepare但未commit)

  • binlog完整:提交事務(重放redo log)

四、ACID保證機制

1. 原子性實現

// 偽代碼:事務執行過程
void execute_transaction() {write_undo_log(); // 記錄回滾信息write_redo_log(PREPARE);execute_sql();write_binlog();write_redo_log(COMMIT); // 最終提交
}

2. 隔離性實現

MVCC核心結構

  • ReadView機制:包含m_ids(活躍事務ID列表),幫我們解決可見性的問題的, 即他會來告訴我們本次事務應該看到哪個快照,不應該看到哪個快照。

  • 版本鏈:通過DB_ROLL_PTR指針串聯undo log

可見性判斷規則:基于redaview實現。一個事務,能看到的是在他開始之前就已經提交的事務的結果,而未提交的結果都是不可見的。

●trx_ids,表示在生成ReadView時當前系統中活躍的讀寫事務的事務id列表。
●low_limit_id,應該分配給下一個事務的id 值。
●up_limit_id,未提交的事務中最小的事務 ID。
●creator_trx_id,創建這個 Read View 的事務 ID。

3. 持久性保證

  • redo log刷盤策略

    innodb_flush_log_at_trx_commit = 1 # 每次提交刷盤
  • 雙寫緩沖:防止頁斷裂

    // 寫入流程
    write_to_doublewrite_buffer();
    write_to_data_file();

五、主從復制過程

MySQL 5.6推出基于庫級別的并行復制。

可以配置多個庫并行進行復制,這意味著每個庫都可以有自己的復制線程,可以并行處理來自不同庫的寫入。這提高了并行復制的性能和效率。


MySQL 5.7推出基于組提交的的并行復制。

它通過將多個事務的提交操作合并成一個批處理操作來減少磁盤IO和鎖定開銷,從而加速事務的處理,簡單來說就是將多個事務的提交操作可以合并成一個批處理操作,以減少磁盤IO次數。

一個組中多個事務,都處于Prepare階段之后,才會被優化成組提交。那么就意味著如果多個事務他們能在同一個組內提交,這個就說明了這個幾個事務在鎖上是一定是沒有沖突的。換句話說,就是這幾個事務修改的一定不是同一行記錄,所以他們之間才這樣Slave就可以用多個SQL線程來并行的執行一個組提交中的多條SQL,從而提升效率,降低主從延遲。能互不影響,同時進入Prepare階段,并且進行組提交。

事務的二階段提交就跟原生的有點區別。因為日志的刷盤過程會因為組提交而需要等待

組提交的二階段提交

image.png


MySQL 8.0 推出基于WRITESET的并行復制。

WriteSet 是通過檢測兩個事務是否更新了相同的記錄來判斷事務能否并行回放的,因此需要在運行時保存已經提交的事務信息以記錄歷史事務更新了哪些行,并且在做更新的時候進行沖突檢測,拿新更新的記錄計算出來的hash值和WriteSet作比較,如果不存在,那么就認為是不沖突的,這樣就可以共用同一個last_committed 、

last_committed 指的是該事務提交時,上一個事務提交的編號。


就這樣,就能保證同一個write_set中的變更都是不沖突的,那么同一個write_set就可以并行的通過多個線程進行回放SQL了。

1. 復制原理

2. 詳細步驟

  1. 主庫

    • 事務提交時寫入binlog

    • 通過dump線程發送事件

  2. 從庫

    • IO線程:拉取binlog到relay log

    • SQL線程:重放relay log中的事件

    • 狀態報告:SHOW SLAVE STATUS

3. 復制模式

模式原理優點缺點
異步(默認)主庫不等待從庫ACK高性能數據可能丟失
半同步至少一個從庫ACK平衡性能與安全網絡影響性能
全同步全部從庫ACK安全性可以保障性能很差

4. 配置示例

-- 主庫配置
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';-- 從庫配置
CHANGE MASTER TOMASTER_HOST='master_host',MASTER_USER='repl',MASTER_PASSWORD='password',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=107;
START SLAVE;

5.主從延遲問題

數據庫的主從延遲是指在主從數據庫復制過程中,從服務器(Slave)上的數據與主服務器(Master)上的數據之間存在的時間差或延遲。

一般來說導致主從延遲可能由多種因素引起,以下是一些常見的原因:
網絡延遲:主節點和從節點之間的網絡延遲導致復制延遲這是比較常見的一種情況,


從節點性能問題:從服務器的性能不足也可能導致復制延遲。如果從服務器的硬件資源(CPU、內存、磁盤)不足以處理接收到的復制事件,延遲可能會增加。


復制線程不夠:當從節點只有一個線程,或者線程數不夠的時候,數據回放就會慢,就會導致主從節點的數據延遲。

解決主從延遲主要有幾個事情可以做:


優化網絡:確保主節點和從節點之間的網絡連接穩定,盡量同城或者同單元部署,減小網絡延遲。


提高從服務器性能:增加從服務器的硬件資源,如CPU、內存和磁盤,以提高其性能,從而更快地處理復制事件。


并行復制:借助MySQL提供的并行復制的能力,提升復制的效率,降低延遲。

六、關鍵優化參數

1. 事務相關

transaction-isolation = REPEATABLE-READ
innodb_rollback_on_timeout = ON

2. 日志相關

sync_binlog = 1 # binlog刷盤控制
innodb_flush_log_at_trx_commit = 1 # redo刷盤控制
binlog_format = ROW # 推薦使用ROW模式

3. 復制優化

slave_parallel_workers = 4 # 并行復制
slave_preserve_commit_order = ON # 保持事務順序

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79575.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79575.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79575.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LLama-v2 權重下載

地址:llama模型 官方github倉庫:llama倉庫 注意點 網絡代理位置:美國下面的國家選擇 United States 克隆倉庫后 運行bash download.sh輸入郵箱收到的URL選擇要下載的權重等待下載完成即可 有問題留言!!&#xff01…

zephyr OS架構下構建Nordic MCU boot

目錄 概述 1. 軟硬件環境 1.1 軟件開發環境 1.2 硬件環境 2 MCU boot 2.1 核心功能 2.2 關鍵術語 2.3 重要字段介紹 3 VS-Code下創建MCU-BOOT項目 3.1 軟件框架結構 3.2 創建測試項目 3.3 編譯項目 3.3 固件在Flash中的分布 4 驗證 4.1 燒寫固件 ? 4.2 代碼…

【Mytais系列】介紹、核心概念

MyBatis 是一款優秀的 持久層框架,它通過簡化 JDBC 操作、提供靈活的 SQL 映射能力,成為 Java 開發中處理數據庫交互的核心工具之一。以下是 MyBatis 的核心框架和概念解析: 一、MyBatis 框架概述 1. 核心定位 作用:將 Java 對象…

IO模型和多路復用

一、IO模型的基礎理解 什么是IO? IO全稱是 Input/Output(輸入/輸出),在計算機科學里主要指程序與外部設備(硬盤、網絡、用戶終端等)進行數據交換的操作。首要特點是: IO通常很慢(從CPU和內存的視角看)經常需要等待外部設備響應1. 為什么要談IO模型? 當一個程序需要…

深入理解 Bash 中的 $‘...‘ 字符串語法糖

在 Bash 腳本編程中,字符串處理是不可或缺的一部分。為了讓開發者更高效地處理特殊字符和控制字符,Bash 引入了一種獨特的字符串語法糖:$(帶單引號的 ANSI-C 風格字符串)。這種語法來源于 C 語言的 ANSI-C 標準&#x…

用Python打造自己的專屬命令行工具

在日常的開發和使用過程中,我們常常會編寫一些實用的Python腳本,比如用來批量處理文件、獲取系統信息等。然而,每次都要輸入python script_name.py來運行腳本,時間一長難免覺得繁瑣。要是能像使用系統自帶的命令(如ls、…

【KWDB 創作者計劃】KWDB 2.2.0多模融合架構與分布式時序引擎

KWDB介紹 KWDB數據庫是由開放原子開源基金會孵化的分布式多模數據庫,專為AIoT場景設計,支持時序數據、關系數據和非結構化數據的統一管理。其核心架構采用多模融合引擎,集成列式時序存儲、行式關系存儲及自適應查詢優化器,實現跨模…

學習Linux的第二天

如何在Linux環境下做開發 Linux的一些基操 Tips:平常最表層的是命令行模式,最多見這個默認叫做命令行模式 Vi操作是什么意思呢 就是在提示符輸入vi a.c 是可以創建一個a.c這個文件并進入這個輸入模式 按i可以輸入代碼 要退出的時候按esc 再按:(冒號…

鏈表操作練習

要求 現在有一個雙向鏈表&#xff0c;里面要保存歌曲的名字&#xff1b;例如 蔡琴/渡口.mp3 我們把它定義在一個link.h文件中。 #ifndef LINK_H #define LINK_H #include <stdlib.h> #include <stdio.h> #include <string.h>typedef struct Node {//保存歌…

MATLAB制作散點圖:從基礎到進階的三種類型講解

一、什么是散點圖 散點圖是一種用來展示兩個或多個變量之間關系的圖表形式。它可以幫助我們直觀地觀察變量之間是否存在相關性、趨勢或異常值&#xff0c;常用于數據分析的初步探索階段。 二、三種類型散點圖 1. 基本二維散點圖&#xff1a;最簡單、最常用 基本二維散點圖的…

模塊方法模式(Module Method Pattern)

&#x1f9e0; 模塊方法模式&#xff08;Module Method Pattern&#xff09; 模塊方法模式是一種結構型設計模式&#xff0c;它將復雜的操作分解成一系列相對簡單、獨立且單一職責的模塊。每個模塊負責完成一種具體的操作&#xff0c;其他模塊或系統可以通過調用這些模塊的公開…

Python中的JSON庫,詳細介紹與代碼示例

目錄 1. 前言 2. json 庫基本概念 3. json 的適應場景 4. json 庫的基本用法 4.1 導 json入 模塊 4.2 將 Python 對象轉換為 JSON 字符串 4.3 將 JSON 字符串轉換為 Python 對象 4.4 將 Python 對象寫入 JSON 文件 4.5 從 JSON 文件讀取數據 4.6 json 的其他方法 5.…

網狐旗艦大聯盟組件源碼私測筆記:結構分層、UI重構與本地實操全流程

作為一套衍生于傳統網狐架構的源碼版本&#xff0c;大聯盟這套源碼組件可謂是在經典基礎上進行了深度重塑。與老版死板的框架風格不同&#xff0c;它不僅對界面做了大刀闊斧的重構&#xff0c;還在組件層級的組織上做了優化。本文將基于一整套源碼進行深度解析&#xff0c;強調…

STM32 PulseSensor心跳傳感器驅動代碼

STM32CubeMX中準備工作&#xff1a; 1、設置AD 通道 2、設置一個定時器中斷&#xff0c;間隔時間2ms&#xff0c;我這里采用的是定時器7 3、代碼優化01 PulseSensor.c文件 #include "main.h" #include "PulseSensor/PulseSensor.h"/******************…

C++項目容易犯錯的點

1. 矩陣q要先定義大小&#xff0c;再賦值。不可以直接賦值。下面這種方式是錯誤的Eigen::MatrixXd q&#xff1b;q<<1,2&#xff1b;正確的這樣的&#xff1a; Eigen::MatrixXd q(2,1); q<<1.4, 1.5; 2. 不要重復加載variables.h頭文件&#xff0c;這樣變量會被…

在阿里云 Ubuntu 24.04 上部署 RabbitMQ:一篇實戰指南

前言 RabbitMQ 是業界常用的開源消息中間件,支持 AMQP 協議,易于部署、高可用、插件豐富。本文以阿里云 ECS 上運行的 Ubuntu 24.04 LTS 為例,手把手帶你完成 RabbitMQ 從倉庫配置到運行的全流程,并分享在國內環境下常見的坑與對應解決方案。 環境概況 操作系統:Ubuntu …

【論文筆記】SOTR: Segmenting Objects with Transformers

【題目】&#xff1a;SOTR: Segmenting Objects with Transformers 【引用格式】&#xff1a;Guo R, Niu D, Qu L, et al. Sotr: Segmenting objects with transformers[C]//Proceedings of the IEEE/CVF international conference on computer vision. 2021: 7157-7166. 【網…

MinIO實現https訪問

Windows下實現MinIO的https訪問. 首先需要自己解決證書問題, 這里可以是個人證書 也可以是花錢買的證書. 現在使用個人開發者證書舉例子。 將證書數據解壓到你知道的目錄之下 然后直接使用命令啟動MinIO start minio.exe server --certs-dir D:\xxxxx\tools\certs …

基于 jQuery 實現靈活可配置的輸入框驗證功能

在 Web 表單開發中&#xff0c;輸入框驗證是保障數據準確性和安全性的關鍵環節。無論是用戶注冊、信息提交還是數據錄入場景&#xff0c;都需要對用戶輸入內容進行合法性檢查。本文將介紹如何使用 HTML、CSS 和 jQuery 構建一個可靈活配置的輸入框驗證系統&#xff0c;輕松應對…

Kotlin 04Flow stateIn 和 shareIn的區別

一 Kotlin Flow 中的 stateIn 和 shareIn 一、簡單比喻理解 想象一個水龍頭&#xff08;數據源&#xff09;和幾個水杯&#xff08;數據接收者&#xff09;&#xff1a; 普通 Flow&#xff08;冷流&#xff09;&#xff1a;每個水杯來接水時&#xff0c;都要重新打開水龍頭從…