圖文結合帶你搞懂MySQL日誌之Binary log(二進位日誌)

来源:https://www.cnblogs.com/greatsql/archive/2023/06/05/17457381.html
-Advertisement-
Play Games

往期回顧 - [圖文結合帶你搞定MySQL日誌之Undo log(回滾日誌)](http://mp.weixin.qq.com/s?__biz=MzkzMTIzMDgwMg==&mid=2247496981&idx=1&sn=ec496da6e52e19ee505483a15fb54f6b&chks ...


往期回顧


6ingvhy40

此篇為圖文結合搞懂MySQL日誌的最後一篇,MySQL中共有八大日誌,其中數據定義語句日誌不是給用戶查看的,在此篇尾部簡單介紹,接下來圖文結合系列還會繼續推出新文章!

二進位日誌(Binary log)

binlog可以說是MySQL中比較重要的日誌了,在日常開發及運維過程中,經常會遇到。

binlog即binary log,二進位日誌文件,也叫作變更日誌(update log)。它記錄了資料庫所有執行的DDL和DML等資料庫更新事件的語句,但是不包含沒有修改任何數據的語句(如數據查詢語句select、show等)。

它以事件形式記錄並保存在二進位文件中。通過這些信息,我們可以再現數據更新操作的全過程。

如果想要記錄所有語句(例如,為了識別有問題的查詢),需要使用通用查詢日誌。

Binary log主要應用場景:

  • 一是用於數據恢復,如果MySQL資料庫意外停止,可以通過二進位日誌文件來查看用戶執行了哪些操作,對資料庫伺服器文件做了哪些修改,然後根據二進位日誌文件中的記錄來恢複數據庫伺服器。
  • 二是用於數據複製,由於日誌的延續性和時效性,master把它的二進位日誌傳遞給slaves來達到master-slave數據一致的目的。

可以說MySQL資料庫的數據備份、主備、單主、多主、MGR都離不開Binary log,需要依靠Binary log來同步數據,保證數據一致性。

圖片

查看預設情況

查看記錄二進位日誌是否開啟:在MySQL8中預設情況下,二進位文件是開啟的。

mysql>  show variables like '%log_bin%';
+---------------------------------+-----------------------------+
| Variable_name                   | Value                       |
+---------------------------------+-----------------------------+
| log_bin                         | ON                          |  //開關
| log_bin_basename                | /var/lib/mysql/binlog       | // 存放路徑
| log_bin_index                   | /var/lib/mysql/binlog.index |
| log_bin_trust_function_creators | ON                          |//  函數創建 
| log_bin_use_v1_row_events       | OFF                         |
| sql_log_bin                     | ON                          |//變更sql記錄下來
+---------------------------------+-----------------------------+
6 rows in set (0.01 sec)
  • log_bin_basename:是binlog日誌的基本文件名,後面會追加標識來表示每一個文件
  • log_bin_index:是binlog文件的素引文件,這個文件管理了所有的binlog文件的目錄
  • log_bin_trust_function_creators:限制存儲過程,前面我們已經講過了,這是因為二進位日誌的一個重要功能是用於主從複製,而存儲函數有可能導致主從的數據不一致。所以當開啟二進位日誌後,需要限制存儲函數的創建、修改、調用
  • log_bin_use_v1_row_events此只讀系統變數已棄用。ON表示使用版本1二進位日誌行,OFF表示使用版本2二進位日誌行(MySQL5.6的預設值為2)。

日誌參數設置

方式 1 :永久性方式

修改MySQL的my.cnf或my.ini文件可以設置二進位日誌的相關參數:

[mysqld]
#啟用二進位日誌
log-bin=atguigu-bin
binlog_expire_logs_seconds= 600
max_binlog_size=100M

提示:

  1. log-bin=mysql-bin

打開日誌(主機需要打開),這個mysql-bin也可以自定義,這裡也可以加上路徑,如:/home/www/mysql_bin_log/mysql-bin

  1. binlog_expire_logs_seconds

此參數控制二進位日誌文件保留的時長單位是秒,預設2592000 30天 --14400 4小時;86400 1天; 259200 3天;

  1. max_binlog_size

控制單個二進位日誌大小,當前日誌文件大小超過此變數時,執行切換動作。此參數的最大和預設值是1GB,該設置並不能嚴格控制Binlog的大小,尤其是Binlog比較靠近最大值而又遇到一個比較大事務時,為了保證事務的完整性,可能不做切換日誌的動作只能將該事務的所有SQL都記錄進當前日誌,直到事務結束。一般情況下可採取預設值。

設置帶文件夾的bin-log日誌存放目錄

如果想改變日誌文件的目錄和名稱,可以對my.cnf或my.ini中的log_bin參數修改如下:

[mysqld]
log-bin="/var/lib/mysql/binlog/atguigu-bin"

註意:新建的文件夾需要使用mysql用戶,使用下麵的命令即可。

chown -R -v mysql:mysql binlog

提示 資料庫文件最好不要與日誌文件放在同一個磁碟上!這樣,當資料庫文件所在的磁碟發生故障時,可以使用日誌文件恢複數據。

方式 2 :臨時性方式

如果不希望通過修改配置文件並重啟的方式設置二進位日誌的話,還可以使用如下指令,需要註意的是在mysql 8 中只有會話級別的設置,沒有了global級別的設置。

# global 級別
mysql> set global sql_log_bin= 0 ;
ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION variable and can`t be used
with SET GLOBAL

# session級別
mysql> SET sql_log_bin = 0 ;
Query OK, 0 rows affected (0.01 秒)

查看日誌

當MySQL創建二進位日誌文件時,先創建一個以“filename”為名稱、以“.index”為尾碼的文件,再創建一個以“filename”為名稱、以“.000001”為尾碼的文件。

MySQL服務重新啟動一次,以“.000001”為尾碼的文件就會增加一個,並且尾碼名按 1 遞增。即日誌文件的數與MySQL服務啟動的次數相同;如果日誌長度超過了max_binlog_size的上限(預設是1GB),就會創建一個新的日誌文件。

查看當前的二進位日誌文件列表及大小。指令如下:

mysql> SHOW BINARY LOGS;
+--------------------+-----------+-----------+
| Log_name           | File_size | Encrypted |
+--------------------+-----------+-----------+
| atguigu-bin.000001 | 156       | No        |
+--------------------+-----------+-----------+
1 rows in set (0.00 sec)

所有對資料庫的修改都會記錄在binglog中。但binlog是二進位文件,無法直接查看,藉助mysqlbinlog命令工具了。指令如下:在查看執行,先執行一條sQL語句,如下

update student set name='張三_back' where id=1;
[root@localhost ~]$ cd /var/lib/mysql
[root@localhost ~]$ mysqlbinlog  "/var/lib/mysql/lqhdb-binlog.000001"

執行結果可以看到,這是一個簡單的日誌文件,日誌中記錄了用戶的一些操作,這裡並沒有出現具體的SQL語句,這是因為binlog關鍵字後面的內容是經過編碼後的二進位日誌。

這裡一個update語句包含如下事件

  • Query事件負責開始一個事務(BEGIN)
  • Table_map事件負責映射需要的表
  • Update_rows事件負責寫入數據
  • Xid事件負責結束事務

下麵命令將行事件以偽SQL的形式表現出來

mysqlbinlog -v "/var/lib/mysql/binlog/test.000002"

前面的命令同時顯示binlog格式的語句,使用如下命令不顯示它

mysqlbinlog -v --base64-output=DECODE-ROWS "/var/lib/mysql/binlog/test.000002"

關於mysqlbinlog工具的使用技巧還有很多,例如只解析對某個庫的操作或者某個時間段內的操作等。簡單分享幾個常用的語句,更多操作可以參考官方文檔。

# 可查看參數幫助
mysqlbinlog --no-defaults --help

# 查看最後 100 行
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |tail - 100

# 根據position查找
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |grep -A 
20 '4939002'

上面這種辦法讀取出binlog日誌的全文內容比較多,不容易分辨查看到pos點信息,下麵介紹一種更為方便的查詢命令:

mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
  • IN 'log_name':指定要查詢的binlog文件名(不指定就是第一個binlog文件)
  • FROM pos:指定從哪個pos起始點開始查起(不指定就是從整個文件首個pos點開始算)
  • LIMIT [offset]:偏移量(不指定就是 0 )
  • row_count :查詢總條數(不指定就是所有行)

上面這條語句可以將指定的binlog日誌文件,分成有效事件行的方式返回,並可使用limit指定pos點的起始偏移,查詢條數。其它舉例:

#a、查詢第一個最早的binlog日誌:
show binlog events\G ;

#b、指定查詢mysql-bin.088802這個文件
show binlog events in 'atguigu-bin. 008002'\G;

#c、指定查詢mysql-bin. 080802這個文件,從pos點:391開始查起:
show binlog events in 'atguigu-bin.008802' from 391\G;

#d、指定查詢mysql-bin.000802這個文件,從pos點:391開始查起,查詢5條(即5條語句)
show binlog events in 'atguigu-bin.000882' from 391 limit 5\G

#e、指定查詢 mysql-bin.880002這個文件,從pos點:391開始查起,偏移2行〈即中間跳過2個)查詢5條(即5條語句)。
show binlog events in 'atguigu-bin.088882' from 391 limit 2,5\G;

binlog格式查看

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   | //行格式
+---------------+-------+
1 rows in set (0.00 sec)

除此之外,binlog還有 2 種格式,分別是StatemenMixed

  • Statement 每一條會修改數據的sql都會記錄在binlog中。 優點:不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高性能。
  • Row 5.1.5版本的MySQL才開始支持row level 的複製,它不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。 優點:row level 的日誌內容會非常清楚的記錄下每一行數據修改的細節。而且不會出現某些特定情況下的存儲過程,或function,以及trigger的調用和觸發無法被正確複製的問題。
  • Mixed 從5.1.8版本開始,MySQL提供了Mixed格式,實際上就是Statement與Row的結合。

使用日誌恢複數據

mysqlbinlog恢複數據的語法如下:

mysqlbinlog [option] filename|mysql –uuser -ppass;

這個命令可以這樣理解:使用mysqlbinlog命令來讀取filename中的內容,然後使用mysql命令將這些內容恢復到資料庫中。

  • filename:是日誌文件名。

  • option:可選項,比較重要的兩對option參數是–start-date、–stop-date 和 --start-position、–stop-position。

    • –start-date 和 - -stop-date:可以指定恢複數據庫的起始時間點和結束時間點。
    • –start-position和–stop-position:可以指定恢複數據的開始位置和結束位置。

註意:使用mysqlbinlog命令進行恢復操作時,必須是編號小的先恢復,例如atguigu-bin.000001必須在atguigu-bin.000002之前恢復。

flush logs; #可以生成新的binLog 文件,不然這個文件邊恢復邊變大是不行的。

show binary logs; # 顯示有哪些binLog 文件

恢複數據

mysqlbinlog [option] filename|mysql –uuser -ppass;

mysqlbinlog --no-defaults  --start-position=236  --stop-position=1071 --database=my_db1 /var/lib/mysql/lqhdb-bin.000002 | /usr/bin/mysql -root -p123456 -v my_db1

刪除二進位日誌

MySQL的二進位文件可以配置自動刪除,同時MySQL也提供了安全的手動刪除二進位文件的方法。PURGE MASTER LOGS只刪除指定部分的二進位日誌文件,RESET MASTER刪除所有的二進位日誌文件。具體如下:

1.PURGE MASTER LOGS:刪除指定日誌文件

PURGE MASTER LOGS語法如下:

PURGE {MASTER | BINARY} LOGS TO ‘指定日誌文件名’

PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期’

舉例 :使用PURGE MASTER LOGS語句刪除創建時間比binlog.000005早的所有日誌

(1)多次重新啟動MysSQL服務,便於生成多個日誌文件。然後用SHOW語句顯示二進位日誌文件列表

SHOW BINARY LOGS;

(2)執行PURGE MASTER LOGS語句刪除創建時間比binlog.000005早的所有日誌

PURGE MASTER LOGS T0 "binlog. 000005";

(3)顯示二進位日誌文件列表

SHGW BINARY LOGS;

舉例:使用PURGE MASTER LOGS語句刪除2023年3月17日前創建的所有日誌文件。具體步驟如下:

(1) 顯示二進位日誌文件列表

SHOW BINARY LOGS;

(2)執行mysqlbinlog命令查看二進位日誌文件binlog.000005的內容

mysqlbinlog --no-defaults "/var/lib/mysql/binlog/atguigu-bin.000005"

(3)使用PURGE MASTER LOGS語句刪除2023年3月17日前創建的所有日誌文件

PURGE MASTER LOGS before "20220317";

(4)顯示二進位日誌文件列表

SHOW BINARY LOGS;

2022年01月05號之前的二進位日誌文件都已經被刪除,最後一個沒有刪除,是因為當前在用,還未記錄最後的時間,所以未被刪除。

2.RESET MASTER:刪除所有二進位日誌文件

reset master;

其它場景

二進位日誌可以通過資料庫的全量備份和二進位日誌中保存的增量信息,完成資料庫的無損失恢復。但是,如果遇到數據量大、資料庫和數據表很多(比如分庫分表的應用)的場景,用二進位日誌進行數據恢復,是很有挑戰性的,因為起止位置不容易管理。

在這種情況下,一個有效的解決辦法是配置主從資料庫伺服器,甚至是一主多從的架構,把二進位日誌文件的內容通過中繼日誌,同步到從資料庫伺服器中,這樣就可以有效避免資料庫故障導致的數據異常等問題。

深入理解二進位日誌

寫入機制

binlog的寫入時機也非常簡單,事務執行過程中,先把日誌寫到binlog cache,事務提交的時候,再把binlog cache寫到binlog文件中。因為一個事務的binlog不能被拆開,無論這個事務多大,也要確保一次性寫入,所以系統會給每個線程分配一個塊記憶體作為binlog cache。

我們可以通過binlog_cache_size參數控制單個線程binlog cache大,如果存儲內容超過了這個參數,就要暫存到磁碟(Swap)。binlog日誌刷盤流程如下:

圖片

上圖的write,是指把日誌寫入到文件系統的page cache,並沒有把數據持久化到磁碟,所以速度比較快。

上圖的fsync,才是將數據持久化到磁碟的操作

write和fsync的時機,可以由參數sync_binlog控制,預設是 0 。

為 0 的時候,表示每次提交事務都只write,由系統自行判斷什麼時候執行fsync。雖然性能得到提升,但是機器宕機,page cache裡面的binglog 會丟失。如下圖:圖片

為了安全起見,可以設置為 1 ,表示每次提交事務都會執行fsync,就如同 redo log 刷盤流程 一樣。最後還有一種折中方式,可以設置為N(N>1),表示每次提交事務都write,但累積N個事務後才fsync。

圖片

在出現IO瓶頸的場景里,將sync_binlog設置成一個比較大的值,可以提升性能。同樣的,如果機器宕機,會丟失最近N個事務的binlog日誌。

binlog與redolog對比

  • redo log 它是物理日誌,記錄內容是“在某個數據頁上做了什麼修改”,屬於 InnoDB 存儲引擎層產生的。

  • 而 binlog 是邏輯日誌,記錄內容是語句的原始邏輯,類似於“給 ID=2 這一行的 c 欄位加 1”,屬於MySQL Server 層

  • 雖然它們都屬於持久化的保證,但是則重點不同。

    • redo log讓InnoDB存儲引擎擁有了崩潰恢復能力。
    • binlog保證了MySQL集群架構的數據一致性。

Enjoy GreatSQL

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 摘要:本文介紹基於STM32微控制器、BC26 NBIOT模組和華為雲IOT平臺,實現了一款智能井蓋系統。 本文分享自華為雲社區《基於STM32+NBIOT+華為雲IOT設計的智能井蓋》,作者:DS小龍哥 。 一、概述 智能井蓋是一種通過物聯網技術實現對井蓋狀態監測和管理的設備。當前介紹基於STM3 ...
  • ## 前置知識 動態捲管理(LVM,Logical Volume Manger)實現將多個硬碟和硬碟分區做成一個邏輯捲,並將邏輯捲統一管理。創建LVM順序為:物理捲PV->捲組VG->邏輯捲LV。 物理捲(PV,Physical Volume):物理硬碟或分區; 捲組(VG,Volume Group ...
  • 不同ubuntu版本對應的ros版本名稱 ubuntu版本 ros1版本 ros2版本 16.04 kinetic ardent 18.04 melodic dashing 20.04 noetic foxy 1、打開軟體與更新,切換ubuntu軟體源(國內阿裡雲) 2、打開終端,添加ros軟體源( ...
  • # 資料庫系統概論— 設計與應用開發篇(1) ## 一.關係數據理論 主要是關係中**屬性和屬性之間的依賴關係** ### 1相關基本概念 - **第一範式**:表中無表(屬性不可再分) - 數據依賴:是在一個關係內部屬性間的約束,分為函數和多值依賴。 eg:學號決定姓名 ### 2.規範化 ### ...
  • 這是一個與兒童相關的百科知識資料庫,資料庫中包含了小孩子比較有興趣的動物植物、軍事知識、科學知識、天文地理等分類信息,是一個兒童教育必須掌握的知識。載圖下麵有更加詳細的分類統計信息: 詳細的分類情況如下: 動物植物包含:動物常識(256條)、海洋生物(69條)、人體奧秘(155條)、生物工程(114 ...
  • 之前發過一個《看圖猜電視劇電影含圖ACCESS資料庫》,今天又獲得了一個更完美的數據,不論在記錄數上還是在數據內容上都之前那麼更漂亮。更多看圖猜的數據可以訪問“看圖猜詞”分類; 不但包含電影名稱,還包含電影年份、主演、導演等 圖片的尺寸一般是:576X352,平均大小為26KB左右 截圖下方有顯示“ ...
  • 1. 安裝簡介 2. 高可用搭建 3. 高可用及負載均衡測試 4. 問題處理 # 一、安裝簡介 ## 1.1 安裝目的 MySQL官方提供了InnoDB Cluster,該集群由MySQL MGR和MySQL Router組成。MySQL MGR在資料庫層面實現自主高可用性,而MySQL Route ...
  • 今天這個資料庫是女生專項心理測試資料庫,資料庫包含4個表:Subject(測試項目表)、Question(項目下測試題目)、Answer(題目下選項及得分)、Explain(項目累計得分解析表),具體看以下截圖: 包含:你是一個樂觀的女生嗎?你是一個自信的女生嗎?你是一個可愛的女生嗎?你是一個意志堅 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...