MySQL 二進制日志的使用

本文的操作環境是 macOS Mojave 10.14.1, mysql 5.7.19

二進制日志的作用

二進制日志主要記錄 MySQL 數據庫的變化。它會記錄所有更改表數據和表結構的事件,比如 update、delete 等,它也會記錄語句執行所用的時間。為了保證事件的準確性,會記錄事件的長度。它不會記錄 select、show 語句的執行。使用二進制日志主要有兩種用途:

  1. 主從備份。主庫上的二進制日志記錄主庫的所有變更,主庫會把日志包含的事件發給從庫,從庫執行這些事件,從而與主庫的數據保持一致;
  2. 從二進制日志恢復數據庫。

Binary logging is done immediately after a statement or transaction completes but before any locks are released or any commit is done. This ensures that the log is logged in commit order.

在 commit 執行之前,寫入二進制日志。

配置方式

默認情況下,二進制日志是關閉的,可以通過修改 MySQL 的配置文件來啟動和設置二進制日志。

查看 MySQL 配置文件的路徑:

shell> mysql --help | grep my.cnf
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf

如果是用 brew 安裝的 mysql,配置文件默認在 /usr/local/etc/my.cnf

在配置文件的 [mysqld] 下面添加:

# 由于 mysql 的 bug,必須配置 server-id,可以是任意值
server-id=11
# 開啟二進制日志,日志文件名稱是 mysql-bin
log-bin=mysql-bin
# 設置過期時間,10天后自動刪除舊的日志。默認是 0,表示永不刪除
expire_logs_days = 10
# 設置每個日志文件的大小,超過這個值,重新創建新的文件。最小值是4096B,最大值是 1GB,默認是1GB
max_binlog_size = 100M

注意:必須配置 server-id,否則啟動 MySQL 會報錯,官方文檔有說明:

If you specify the --log-bin option without also specifying a --server-id, the server is not allowed to start. (Bug #11763963, Bug #56739)

日志文件默認保存在datadir目錄下,也可以設置為其他路徑,比如 log-bin=/usr/local/var/mysql/mysql-bin。即使在文件名稱后面添加后綴,mysql 也會忽略,mysql 會添加數字后綴。

也可以直接配置為 log-bin,不加任何參數。此時日志文件的默認名稱是 host_name-binhost_name 是你的主機名稱。

除了二進制日志,mysql 還會創建一個 mysql-bin.index 文件,該文件保存所有的二進制日志的文件名稱。可以直接使用 cat 命令查看,不要手動修改這個文件。

另外,每次重新啟動 mysql,也會創建新的二進制日志。

當前客戶端可以暫時關閉二進制日志: SET sql_log_bin=OFF

查看方法

使用 show variables like 'log_bin%'; 查詢二進制日志設置:

image

使用 show binary logs; 查看二進制日志文件個數及文件名稱:

image

使用 show master status 查看當前正在使用的日志:

image

使用 SHOW SLAVE STATUS 可以在從庫上查看它在讀取哪個日志;

使用 mysqlbinlog 查看二進制日志的內容,紅色方框里面是該文件的創建時間:

image

二進制日志的格式

有三種格式:row-based logging(ROW),statement-based logging(STATEMENT),mixed-base logging(MIXED)。

There are several reasons why a client might want to set binary logging on a per-session basis:

  • A session that makes many small changes to the database might want to use row-based logging.
  • A session that performs updates that match many rows in the WHERE clause might want to use statement-based logging because it will be more efficient to log a few statements than many rows.
  • Some statements require a lot of execution time on the master, but result in just a few rows being modified. It might therefore be beneficial to replicate them using row-based logging.

官方文檔有這樣兩句話:

Statement may not be safe to log in statement format.

You can avoid these issues by using MySQL's row-based replication instead.

查看日志格式:

mysql> select @@session.binlog_format;
mysql> select @@global.binlog_format;

改變日志格式:

全局改變:

mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';

客戶端改變:

mysql> SET SESSION binlog_format = 'STATEMENT';
mysql> SET SESSION binlog_format = 'ROW';
mysql> SET SESSION binlog_format = 'MIXED';

下面這張圖,上面的日志是 ROW 格式,選中的日志是 STATEMENT 格式:

image

刪除二進制日志

使用 reset master; 刪除所有的二進制日志文件。MySQL 會重新創建二進制日志,新的日志文件擴展名從 000001 開始編號。

MySQL 還提供了刪除指定日志的方法:

purge master logs to 'log_name' 刪除比 log_name 編號小的日志,比如 purge master logs to 'mysql-bin.000003';,編號小于 000003 的日志會被刪除。

purge master logs before 'datatime' 刪除 datatime 之前的日志,日期格式是 YYYY-MM-DD hh:mm:ss

如果日志文件正在用于主從備份,它不會被刪除。

使用二進制日志恢復數據庫

在使用 mysql 的全量備份恢復數據庫之后,可以再使用二進制日志恢復到指定時間點。比如當前時間是11點多,我不小心把一個重要的庫刪除了。幸好每天凌晨兩點做了數據庫全量備份,這時我就可以先恢復數據庫到兩點,然后再使用二進制日志恢復到刪除之前的數據庫。

直接使用日志文件恢復數據庫:

shell> mysqlbinlog binlog_files | mysql -u root -p

可以把日志文件導出文本,然后編輯文本,刪除一些不需要執行的語句,然后再恢復數據庫:

shell> mysqlbinlog binlog_files > tmpfile
shell> ... edit tmpfile ...
shell> mysql -u root -p < tmpfile

如果有多個日志文件,在一個連接中使用它們:

shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p

恢復到指定時間點:

shell> mysqlbinlog --stop-datetime="2018-10-25 11:00:00" \
         /var/log/mysql/bin.123456 | mysql -u root -p

從指定時間點恢復:

shell> mysqlbinlog --start-datetime="2018-10-25 10:01:00" \
         /var/log/mysql/bin.123456 | mysql -u root -p

根據位置恢復:

shell> mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456 \
         | mysql -u root -p

shell> mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456 \
         | mysql -u root -p

位置信息可以從日志文件的 log_pos 獲取。

參考

  1. MySQL 二進制日志簡介

  2. 二進制日志所有參數

  3. mysqlbinlog 的使用方法

  4. 使用二進制日志恢復數據庫

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容