『MySQL 實戰 45 講』24 - MySQL是怎么保證主備一致的?

MySQL是怎么保證主備一致的?

MySQL 主備的基本原理

  1. 基本的主備切換流程
    在這里插入圖片描述
  • 狀態 1:客戶端的讀寫都直接訪問節點 A,而節點 B 是 A 的備庫
  • 狀態 2:切換時,讀寫訪問的都是節點 B,而節點 A 是 B 的備庫
  • 注意:建議備庫只設置制度(readonly)模式
    • 雖然是只讀,但是因為 readonly 設置對超級 (super) 權限用戶是無效的,而用于同步更新的線程,就擁有超級權限
  1. 節點 A 到節點 B 的內部流程
    在這里插入圖片描述
  • 主庫接收到客戶端的更新請求后,執行內部事務的更新邏輯,同時寫 binlog
  • 備庫 B 跟主庫 A 之間維持了一個長連接
  • 完整流程
    • 備庫 B 上通過 change master 命令,設置主庫 A 的 IP、端口、用戶名、密碼,以及要從哪個位置開始請求 binlog,這個位置包含文件名和日志偏移量
    • 在備庫 B 上執行 start slave 命令,這時候備庫會啟動兩個線程,就是圖中的 io_thread 和 sql_thread。其中 io_thread 負責與主庫建立連接
    • 主庫 A 校驗完用戶名、密碼后,開始按照備庫 B 傳過來的位置,從本地讀取 binlog,發給 B
    • 備庫 B 拿到 binlog 后,寫到本地文件,稱為中轉日志(relay log)
    • sql_thread 讀取中轉日志,解析出日志里的命令,并執行

binlog 的三種格式對比

  1. 目前有三種格式:statement、row、mixed
  2. 要注意修改 binlog 格式為 statement,可以用過 show variables like ‘%binlog_format%’; 查看
  • sql
# 使用后重啟 mysql
set global binlog_format='STATEMENT'
  • docker
    • 首先配置一下 my.cnf
      [mysqld]
      server_id=1000
      binlog-ignore-db=mysql  
      log-bin=mall-mysql-bin  
      binlog_cache_size=1M  
      binlog_format=statement
      expire_logs_days=7  
      slave_skip_errors=1062
      
    • 運行 docker
      docker run -p 3305:3306 --name mysql-master --restart=always --privileged=true \
      -v /root/mysql-master/log:/var/log/mysql \
      -v /root/mysql-master/data:/var/lib/mysql \
      -v /root/mysql-master/conf:/etc/mysql \
      -v /etc/localtime:/etc/localtime:ro \
      -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.30
      
  1. 首先創建一個數據表
CREATE TABLE `t` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `t_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `a` (`a`), KEY `t_modified`(`t_modified`)) ENGINE=InnoDB;insert into t values(1,1,'2018-11-13');
insert into t values(2,2,'2018-11-12');
insert into t values(3,3,'2018-11-11');
insert into t values(4,4,'2018-11-10');
insert into t values(5,5,'2018-11-09');

在這里插入圖片描述
4. 執行一次刪除語句,查看 delete 語句在 binlog 是怎么記錄的

  • 要注意執行前,如果是通過 mysql 客戶端 啟動的,要執行 mysql -c -root ***,否則下面的注釋行不會記錄在 binlog
delete from t /*comment*/  where a>=4 and t_modified<='2018-11-10' limit 1;
  1. binlog_format=statement 時,binlog 里面記錄的就是 SQL 語句的原文
  • 首先要通過 show variables like ‘log_%’; 查看 log_bin 參數是否為 ON,否則是看不到日志
  • 通過 show binary logs; 去查看有哪些 binlog 日志,一般最大的 File_size 會記錄剛剛執行的 sql
show binlog events in 'mall-mysql-bin.000004';

在這里插入圖片描述

  • 輸出結果解釋
    • 第一行:可先忽略
    • 第二、四行: BEGIN 與 COMMIT 對應,中間是事務
    • 第三行:真實執行語句
  1. 其實,剛剛執行的 delete 語句,注意:在 statement 格式下,是 unsafe 的,因為會出現主從不一致的情況
    在這里插入圖片描述
  • 不一致的例子
    • 如果 delete 語句使用的是索引 a,那么會根據索引 a 找到第一個滿足條件的行,也就是說刪除的是 a=4 這一行
    • 但如果使用的是索引 t_modified,那么刪除的就是 t_modified='2018-11-09’ 也就是 a=5 這一行
  1. 修改 binlog_format='row',再看看 binlog 實際內容
  • 這里的 binlog 里沒有了 SQL 語句的原文,而是換成兩個 event
    • Table_map event: 要操作的表是 test 庫的表 t
    • Delete_rows event:用于定義刪除的行為
      在這里插入圖片描述
  1. 實際上面的信息還是沒看到i昂西信息,需要借助 mysqlbinlog 工具
  • 如果沒有的話,執行 yum install mysql,會有相關的工具下載下來
# 其中 2191 是上面從對應的位置開始的
# 我這邊沒執行成功,因為可能 8 的版本,5 的 mysqlbinlog 沒辦法解析
mysqlbinlog -vv binlog.000058 --start-position=2191

在這里插入圖片描述

  • 其中的信息如下:
    • server id 1:表示這個事務是在 server_id=1 的這個庫上執行的
    • CRC32:每個 event 都有 CRC32 的值,主要是 binlog_checksum 設置為 CRC32
    • Table_map event:實際 map 到數字應該是 93。如果有操作多個表,每個表會有對應的數字
    • @1=4、 @2=4…:實際就是對應刪除的行每一列的值
    • binlog_row_image 默認配置為 FULL,所以 Delete_event 包含了刪除行的所有字段的值,如果把 binlog_row_image 設置為 MINIMAL,則只會記錄必要的信息,在這個例子里,就是只會記錄 id=4 這個信息
    • 最后的 Xid event,用于表示事務被正確地提交了
  1. 總結
  • 當 binlog_format 使用 row 格式的時候,binlog 里面記錄了真實刪除行的主鍵 id,這樣 binlog 傳到備庫去的時候,就肯定會刪除 id=4 的行,不會有主備刪除不同行的問題

為什么會有 mixed 格式的 binlog

  1. statement 格式的 binlog 可能會導致主備不一致,所以要使用 row 格式
  2. row 格式的缺點是,很占空間。
  • 用一個 delete 語句刪掉 10 萬行數據,用 statement 的話就是一個 SQL 語句被記錄到 binlog 中,占用幾十個字節的空間
  • 用 row 格式的 binlog,就要把這 10 萬條記錄都寫到 binlog 中
  1. MySQL 就取了個折中方案,也就是有了 mixed 格式的 binlog。MySQL 自己會判斷這條 SQL 語句是否可能引起主備不一致,如果有可能,就用 row 格式,否則就用 statement 格式
  2. 越來越多的場景要求把 MySQL 的 binlog 格式設置成 row,最直接好處:恢復數據
  • delete 語句:
    • row 格式的 binlog 保留了被刪掉的行的整行信息。可以將 delete 語句轉換成 insert 數據插入回去恢復
  • insert 語句
    • row 格式下,insert 語句的 binlog 里會記錄所有的字段信息。可以將 insert 轉成 delete 語句,刪除誤插入的一行數據
  • update 語句:
    • binlog 里面會記錄修改前整行的數據和修改后的整行數據。只需要把 event 的前后兩行信息對調一下,就可以去數據庫里面執行恢復更新操作
  1. mixed 格式的 binlog 現在已經用得不多了
  2. 關于時間戳的問題
  • 首先把 binlog 格式設置為 mixed,然后執行下面語句
insert into t values(10,10, now());

在這里插入圖片描述

  • MySQL 會選擇使用 statement 格式。如果 binlog 過了 1 分鐘才傳給備庫的話,主備的數據不會造成不一致,原因為
  • 當使用 mysqlbinlog 工具查看的時候,它會多一條 SET TIMESTAMP 命令
    在這里插入圖片描述
  1. 總結
  • binlog 來恢復數據的標準做法是,用 mysqlbinlog 工具解析出來,然后把解析結果整個發給 MySQL 執行。類似下面的命令
    • 命令意思:將 master.000001 文件里面從第 2738 字節到第 2973 字節中間這段內容解析出來,放到 MySQL 去執行
mysqlbinlog master.000001  --start-position=2738 --stop-position=2973 | mysql -h127.0.0.1 -P13000 -u$user -p$pwd;

循環復制問題(雙 M 結構)

在這里插入圖片描述

  1. 業務邏輯
  • 節點 A 上更新了一條語句,然后再把生成的 binlog 發給節點 B,節點 B 執行完這條更新語句后也會生成 binlog
    • 建議:log_slave_updates 設置為 on,表示備庫執行 relay log 后生成 binlog。可以讓更新事件在備庫上也記錄一份
  1. 上面業務邏輯可能會出現循環復制問題,解決的方式
  • 規定兩個庫的 server id 必須不同,如果相同,則它們之間不能設定為主備關系
  • 一個備庫接到 binlog 并在重放的過程中,生成與原 binlog 的 server id 相同的新的 binlog
  • 每個庫在收到從自己的主庫發過來的日志后,先判斷 server id,如果跟自己的相同,表示這個日志是自己生成的,就直接丟棄這個日志

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

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

相關文章

自薦一部IT方案架構師回憶錄

作者本人畢業于一個不知名大專院校&#xff0c;所讀專業計算機科學技術。2009年開始IT職業生涯&#xff0c;至今工作15年。擅長TSQL/Shell/linux等技術&#xff0c;曾經就職于超萬人大型集團、國內頂級云廠商、央國企公司。參與過運營商大數據平臺、大型智慧城市ICT、云計算、人…

python數據分析之爬蟲基礎:selenium詳細講解

目錄 1、selenium介紹 2、selenium的作用&#xff1a; 3、配置瀏覽器驅動環境及selenium安裝 4、selenium基本語法 4.1、selenium元素的定位 4.2、selenium元素的信息 4.3、selenium元素的交互 5、Phantomjs介紹 6、chrome handless模式 1、selenium介紹 &#xff08;1…

【數據結構——查找】順序查找(頭歌實踐教學平臺習題)【合集】

目錄&#x1f60b; 任務描述 相關知識 測試說明 我的通關代碼: 測試結果&#xff1a; 任務描述 本關任務&#xff1a;實現順序查找的算法。 相關知識 為了完成本關任務&#xff0c;你需要掌握&#xff1a;1.根據輸入數據建立順序表&#xff0c;2.順序表的輸出&#xff0c;…

光伏電站建設成本利潤估算

?截至2024年9月底,全國光伏發電裝機容量達到7.7億千瓦,同比增長48.4%。其中集中式光伏4.3億千瓦,分布式光伏3.4億千瓦。2024年前三季度,全國光伏發電量6359億千瓦時,同比增長45.5%。全國光伏發電利用率97.2%,同比下降1.1個百分點.早在今年2月份,中國光伏行業協會名譽理…

create-react-app react19 搭建項目報錯

報錯截圖 此時運行會報錯&#xff1a; 解決方法&#xff1a; 1.根據提示安裝依賴法 執行npm i web-vitals然后重新允許 2.刪除文件法 在index.js中刪除對報錯文件的引入&#xff0c;刪除報錯文件

scala的集合性能2

可變集合\n可變集合允許在原地修改數據&#xff0c;適合需要頻繁更新的場景。Scala 的可變集合包括 ArrayBuffer、HashSet和HashMap。 1. ArrayBuffer\nArrayBuffer 是一個可變的動態數組&#xff0c;提供高效的隨機訪問和添加操作。 import scala.collection.mutable.ArrayB…

【Ubuntu】腳本自動化控制終端填充

1.sh腳本文件控制終端寫入命令 在SLAM算法中&#xff0c;每次啟動vins都需要起很多終端&#xff0c;盡管使用了超級終端Terminator可以終端內劃分看起來更加便捷&#xff0c;但是每次起算法的命令還是要自己輸入&#xff0c;已經被麻煩了兩年了&#xff0c;今天突然想寫寫一個…

【自學】Vues基礎

學習目錄 Vues基礎本地應用網絡應用綜合應用 工具的準備 我個人比較喜歡使用HTMLDROWNER&#xff0c;學習資料推薦使用VC&#xff0c;僅供選擇吧 前置知識 HTMLCSSJSAJAX&#xff1a;這個是學習資料博主推薦的 個人感覺認真學好HTMLCSSJS理解vues基礎很容易上手 官方網址…

Scratch 消滅字母小游戲

背景 最近嘗試一邊自學Scratch&#xff0c;一邊嘗試教給小孩&#xff0c;看他打字時在鍵盤上亂打一氣&#xff0c;想起來自己小時候玩過的學習機打字母游戲&#xff0c;就想給他下載一個。結果網上看到的代碼&#xff0c;要么質量太差&#xff08;有26個字母就要寫 26 個判斷&…

python調用matlab函數(內置 + 自定義) —— 安裝matlab.engine

文章目錄 一、簡介二、安裝matlab.engine2.1、基于 CMD 安裝2.2、基于 MATLAB 安裝&#xff08;不建議&#xff09; 三、python調用matlab函數&#xff08;內置 自定義&#xff09; 一、簡介 matlab.engine&#xff08;MATLAB Engine API for Python&#xff09;&#xff1a;…

pytroch環境安裝-pycharm

環境介紹 安裝pycharm 官網下載即可&#xff0c;我這里已經安裝&#xff0c;就不演示了 安裝anaconda 【官網鏈接】點擊下載 注意這一步選擇just me 這一步全部勾上 打開 anaconda Prompt 輸入conda create -n pytorch python3.8 命令解釋&#xff1a;創建一個叫pytorch&…

Photoshop提示錯誤彈窗dll缺失是什么原因?要怎么解決?

Photoshop提示錯誤彈窗“DLL缺失”&#xff1a;原因分析與解決方案 在創意設計與圖像處理領域&#xff0c;Photoshop無疑是眾多專業人士和愛好者的首選工具。然而&#xff0c;在使用Photoshop的過程中&#xff0c;有時會遇到一些令人頭疼的問題&#xff0c;比如突然彈出的錯誤…

自己總結:selenium高階知識

全篇大概10000字&#xff08;含代碼&#xff09;&#xff0c;建議閱讀時間30min 一、等待機制 如果有一些內容是通過Ajax加載的內容&#xff0c;那就需要等待內容加載完畢才能進行下一步操作。 為了避免人為操作等待&#xff0c;會遇到的問題&#xff0c; selenium將等待轉換…

上海亞商投顧:創業板指震蕩調整 機器人概念股再度爆發

上海亞商投顧前言&#xff1a;無懼大盤漲跌&#xff0c;解密龍虎榜資金&#xff0c;跟蹤一線游資和機構資金動向&#xff0c;識別短期熱點和強勢個股。 一.市場情緒 滬指昨日沖高回落&#xff0c;深成指、創業板指盤中跌超1%&#xff0c;尾盤跌幅有所收窄。機器人概念股逆勢爆…

(Linux)CentOS7離線安裝MinIO(超詳細)

目錄 前言1. 下載2. 安裝VMware3. 安裝CentOS4. 離線安裝MinIO4.1. ssh工具連接CentOS4.2. 上傳MinIO離線包4.2.1 創建data目錄4.2.2 上傳RPM包到data目錄4.2.3 安裝RPM包4.2.4 創建MinIO數據目錄4.2.5 配置 MinIO 服務4.2.6 啟動 MinIO4.2.7 開放端口 4.2.8 訪問MinIO 創作不易…

【JavaWeb后端學習筆記】Maven項目管理

Maven 1、分模塊設計2、Maven繼承2.1 繼承關系2.2 版本鎖定 3、Maven聚合4、聚合與繼承的關系 1、分模塊設計 如果一個項目中含有大量的功能模塊。可以考慮將這些功能分模塊設計&#xff0c;逐一進行開發。例如將公共類可以定義在一個項目中&#xff0c;將通用工具類也放在一個…

HarmonyOS-高級(四)

文章目錄 應用開發安全應用DFX能力介紹HiLog使用指導HiAppEvent &#x1f3e1;作者主頁&#xff1a;點擊&#xff01; &#x1f916;HarmonyOS專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2024年12月11日11點18分 應用開發安全 應用隱私保護 隱私聲明彈窗的作…

網絡安全法-網絡運行安全

第三章 網絡運行安全 第一節 一般規定 第二十一條 國家實行網絡安全等級保護制度。網絡運營者應當按照網絡安全等級保護制度的要求&#xff0c;履行下列安全保護義務&#xff0c;保障網絡免受干擾、破壞或者未經授權的訪問&#xff0c;防止網絡數據泄露或者被竊取、篡改&…

論文閱讀:Statistical Comparisons of Classifiers over Multiple Data Sets

論文地址&#xff1a;Statistical Comparisons of Classifiers over Multiple Data Sets (acm.org) 前面在機器學習之Friedman檢驗-CSDN博客 中提到了Friedman檢驗&#xff0c;這里將對這個方法的論文進行詳細的閱讀&#xff0c;以了解其原理。 摘要 盡管用于在單個數據集上比…

【Unity技巧】Unity項目中哪些文件不用管理(.gitignore)

Unity的項目編譯后一般都比較大&#xff0c;動轍幾個G。這里面一般我們只需要把Assets, Packages, ProjectSettings這三個文件夾進行源代碼管理就可以&#xff0c;其他文件就可以通過下面的.gitignore來忽略掉。 .gitignore文件的內容如下&#xff1a; # 將此 .gitignore 文件…