圖文結合帶你搞懂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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...