1. 程式人生 > >mysql 架構篇系列 3 複製執行狀態監控與選項引數說明

mysql 架構篇系列 3 複製執行狀態監控與選項引數說明

一. 概述

  在上一篇中,搭建了一主一從的複製架構,這篇通過一些診斷方法來了解複製的執行狀態和一些選項引數說明。上次mysql主從服務關機,今天在開啟mysql服務,出現了錯誤資訊。

  1.首先 啟動主從mysql服務

  2.在從庫上執行START SLAVE, 開始複製。

  3.在從庫上執行SHOW PROCESSLIST;  slave已經連線上master, 並開始接受並執行日誌。

  4.在從庫上執行SHOW  SLAVE STATUS,檢視複製狀態

    錯誤資訊: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'

  5. 解決方法 

-- 在主庫上執行,記錄日誌檔案號和位置,如下圖所示:
flush logs;
show master status;

  -- 在從庫上執行
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000072',MASTER_LOG_POS=154;

SLAVE START;

     從庫上再執行SHOW PROCESSLIST,顯示了二個複製程序:一個是 I/O執行緒,連線master,id為7。 一個是SQL執行緒,id為8。如下圖所示:

.複製中的各類檔案

  myql複製中涉及了兩類非常重要的日誌檔案:二進位制日誌檔案(binlog), 中繼日誌檔案(relay log)。 binlog檔案會把mysql中所有資料修改操作以二進位制形式記錄,包括create,drop,insert,update,delete操作等,但不記錄查詢select操作。對於二進位制binlog檔案格式,三種支援型別包括:Statement,Row,Mixed ( 在mysql 架構篇第一篇中有講到)。

  2.1 從庫relay log 中繼日誌檔案

    從庫中繼日誌檔案relay log的檔案格式,內容和主庫二進位制日誌檔案binlog一樣,唯一的區別在於從庫上的sql執行緒在執行完當前中繼日誌檔案relay log中的事件之後,sql 執行緒會自動刪除當前中繼日誌檔案realy log,避免從庫上的中繼日誌檔案relay log佔用過多的磁碟空間。

   2.2 從庫 master.info和realy-log.info檔案

    為了保證從庫crash重啟後,從庫的I/O執行緒仍然能夠知道從哪裡開始複製,從庫上預設還會建立二個日誌檔案master.info 和realy-log.info 用來儲存複製的進度。 這兩個檔案在磁碟上以檔案形式記錄,位置在data目錄下。I/O執行緒維護master.info 中主庫二進位制日誌binlog的進度。sql執行緒維護realy-log.info 應用中繼日誌relay log 的進度。 總結是: I/O執行緒關聯master.info,sql執行緒關聯realy-log.info。再來看下複製原理圖:

  2.3 複製狀態資訊

    在從庫上通過SHOW SLAVE STATUS,能瞭解複製的狀態, 裡面的資訊包含了master.info和realy-log.info的資訊。

    (1) master.info對應的資訊如下:

Master_Host

172.168.18.201

主庫IP

Master_User

rep1

主庫上用於複製的賬號

Master_Port

3306

主庫mysql 埠

Master_Log_File

mysql-bin.000072

從庫I/O執行緒當前讀取主庫binlog的檔名

Read_Master_Log_Pos

514

從庫I/O執行緒讀取主庫binlog的位置

    (2) realy-log.info對應的資訊如下:

Relay_Log_File

xuegod64-relay-bin.000005

SQL執行緒正在應用的relay log

Relay_Log_Pos

680

SQL執行緒正在應用的relay log的位置

Relay_Master_Log_File

mysql-bin.000072

SQL執行緒正在應用的relay log對應的binlog

Exec_Master_Log_Pos

514

SQL執行緒正在應用的relay log的位置對應的主庫binlog的位置

    (3) 其它資訊

Connect_Retry

60

連線中斷後,重新嘗試連線的時間間隔。預設值是60秒

Slave_IO_Running

Yes

I/O執行緒是否被啟動併成功地連線到主伺服器上

Slave_SQL_Running

Yes

SQL執行緒是否被啟動

 Replicate_Do_DB

 Replicate_Ignore_DB

 Replicate_Do_Table

 Replicate_Ignore_Table

 Replicate_Wild_Do_Table

 Replicate_Wild_Ignore_Table

指明哪些庫或表在複製的時候不要同步到從庫

 Last_Error

0

SQL執行緒讀取日誌引數的的錯誤數量和錯誤訊息

Skip_Counter

0

設定跳過sql執行步數

Relay_Log_Space

890

原有的中繼日誌結合起來的總大小

Master_SSL_Allowed

No

1) 如果允許對主伺服器進行SSL連線,則值為Yes

2) 如果不允許對主伺服器進行SSL連線,則值為No

3) 如果允許SSL連線,但是從屬伺服器沒有讓SSL支援被啟用,則值為Ignored。

SQL_Delay

0

一個非負整數,表示秒數,Slave滯後多少秒於master

Master_Retry_Count

86400

連線主庫失敗最多的重試次數

  2.4  主庫 binlog 格式

-- 檢視當前binlog格式
SHOW VARIABLES LIKE '%binlog_format%'

-- 全部更新
UPDATE  testbackup  SET `name`=CONCAT(`name`,'hello')
--通過mysqlbinlog檢查,可以發現記錄是按row 每行記錄的。
[[email protected] ~]# mysqlbinlog --base64-output=decode-row -v  /var/lib/mysql/mysql-bin.000072
#181029 14:33:20 server id 1  end_log_pos 1539 CRC32 0xde0ceeff     Update_rows: table id 221 flags: STMT_END_F
### UPDATE `test`.`testbackup`
### WHERE
###   @1=1
###   @2='張三2'
### SET
###   @1=1
###   @2='張三2hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=2
###   @2='李四'
### SET
###   @1=2
###   @2='李四hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=3
###   @2='五五'
### SET
###   @1=3
###   @2='五五hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=4
###   @2='趙六'
### SET
###   @1=4
###   @2='趙六hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=5
###   @2='小紅'
### SET
###   @1=5
###   @2='小紅hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=6
###   @2='小明'
### SET
###   @1=6
###   @2='小明hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=7
###   @2='田七'
### SET
###   @1=7
###   @2='田七hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=8
###   @2='小康'
### SET
###   @1=8
###   @2='小康hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=9
###   @2='小王'
### SET
###   @1=9
###   @2='小王hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=10
###   @2='小李'
### SET
###   @1=10
###   @2='小李hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=11
###   @2='小王'
### SET
###   @1=11
###   @2='小王hello'
### UPDATE `test`.`testbackup`
### WHERE
###   @1=12
###   @2='小李子1'
### SET
###   @1=12
###   @2='小李子1hello'
View Code
-- 現在將binlog格式從row 改為 statement 格式
-- 當前會話
SET binlog_format='statement'
-- 全部更新
UPDATE  testbackup  SET `name`=CONCAT(`name`,'hello123')

  再通過mysqlbinlog檢查,可以發現記錄是按statement語句級記錄的。

BEGIN
/*!*/;
# at 1714
#181029 14:41:21 server id 1  end_log_pos 1860 CRC32 0x9fdf71e9     Query    thread_id=2    exec_time=0    error_code=0
use `test`/*!*/;
SET TIMESTAMP=1540795281/*!*/;
-- 全部更新
update  testbackup  set `name`=concat(`name`,'hello123')
/*!*/;
# at 1860
#181029 14:41:21 server id 1  end_log_pos 1891 CRC32 0x4b7199d3     Xid = 579
COMMIT/*!*/;
View Code

  總結:在binlog_format格式為row時,mysql實際上在binlog是一行行記錄資料的變更。當格式為statement時是按語句級記錄。 row格式比statement格式更能保證從庫資料的一致性(複製是記錄,而不是單純操作sql),但row格式下的binlog的日誌量很可能會增大好幾倍,在設定時需要考慮磁碟空間問題。

三. 重新整理磁碟頻率

對於支援事務引擎(如innodb)來說, 每個事務提交時都需要寫binlog,對於不支援事務的引擎(例myisam)來說,每個sql語句執行完成時,都需要寫binlog。 為了保證binlog安全,mysql引入了 sync_binlog 引數來控制binlog重新整理到磁碟的頻率。

-- 檢視binlog格式
SHOW VARIABLES LIKE '%sync_binlog%'

  當sync_binlog=1時,是最安全的,當主機突然斷點,系統最多損失最近的一條事務的資料。但是在多個事務併發提交時,mysql不得不按順序處理請求,同時高頻率的重新整理binlog對I/O影響明顯,很大程度影響了mysql的效能。

  所以一般線上系統mysql的sync_binlog不會設定為1, 而是2或0,在資料安全性和更高的併發之間獲取一個平衡。