最近在我們線上庫(kù)物理備份的時(shí)候出現(xiàn)一個(gè)奇怪的現(xiàn)象:

   我們備份都在從庫(kù)上備份的,在業(yè)務(wù)低一般是在晚上2點(diǎn)鐘開(kāi)始備份.有天發(fā)現(xiàn)從庫(kù)的延遲一直在增加,登錄上實(shí)例,通過(guò)show processlist 發(fā)現(xiàn),sql 線程在等待 binlog lock。同時(shí)看到我們從2點(diǎn)鐘開(kāi)始的壓縮遠(yuǎn)程備份并沒(méi)有完成,備份日志還在掃面ibd文件。

   那么這個(gè)binlog lock 是誰(shuí)持有的呢?仔細(xì)想想我們的業(yè)務(wù)場(chǎng)景,這是一個(gè)只讀從庫(kù),且?guī)焐媳銢](méi)有提供任何讀的服務(wù),唯一的一個(gè)疑點(diǎn)就是我們的備份導(dǎo)致的,通過(guò)show processlist 可以看到,Time列的數(shù)值 均是18510,兩個(gè)時(shí)間上邊吻合,那么問(wèn)題可以初步確認(rèn)是由于備份引起的。

mysql> show processlist;

+---------+-------------+-----------+------------+---------+-------+-----------------+

| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined  |

+---------+-------------+-----------+------------+---------+-------+-----------------+

| 4613465 | system user | | NULL | Connect | 65348 | Waiting for master to send event | NULL | 0 | 0 |

| 4613466 | system user | | NULL | Connect | 18510 | Waiting for binlog lock | NULL | 0 | 0 |

| 4631056 | dbbackup | localhost | NULL | Sleep | 18510 | | NULL | 0 | 0 |

 

   進(jìn)一步的,我們?nèi)フ艺夜傥?,看看什么時(shí)候xtrabackup 會(huì)用到這個(gè)binlog lock 呢?截取一段出來(lái):

 

  • LOCK TABLES FOR BACKUP

  • ... copy .frm, MyISAM, CSV, etc. ...

  • LOCK BINLOG FOR BACKUP

  • UNLOCK TABLES

  • ... get binlog coordinates ...

  • ... wait for redo log copying to finish ...

  • UNLOCK BINLOG

 

   可以看到,Binlog Lock是在備份的尾聲階段,是為了在獲取Master 或者slave 的一致性位置點(diǎn)而是用的。

 

   那么問(wèn)題來(lái)了, 我們的備份現(xiàn)在是到了那個(gè)階段呢?如果已經(jīng)到了尾聲階段,那么這個(gè)鎖Binlog的過(guò)程應(yīng)該是很短暫的。

   為了確認(rèn)我們當(dāng)前備份的一個(gè)狀態(tài), 使用strace -p{pid} 來(lái)看一下,當(dāng)前xtrabackup、innobackupex 都在做些什么事情。

   在通過(guò)strace 查看這個(gè)進(jìn)程到底在做什么事之前, 我們先來(lái)看看一些前埔的知識(shí):

 

   由于我們備份MySQL 是主要用到 innobackupex 和 xtrabackup,前者是一個(gè) perl 腳本,后者是 C/C++ 編譯的二進(jìn)制。

   xtrabackup 是用來(lái)備份 InnoDB 表的,不能備份非 InnoDB 表,和 mysqld server 沒(méi)有交互;而innobackupex 腳本用來(lái)備份非 InnoDB 表,同時(shí)會(huì)調(diào)用 xtrabackup 命令來(lái)備份 InnoDB 表,還會(huì)和 mysqld server 發(fā)送命令進(jìn)行交互,如加讀鎖(FTWRL)、獲取位點(diǎn)(SHOW SLAVE STATUS)等。簡(jiǎn)單來(lái)說(shuō),innobackupex 在 xtrabackup 之上做了一層封裝。

   一般情況下,我們是希望能備份 MyISAM 表的,雖然我們可能自己不用 MyISAM 表,但是 mysql 庫(kù)下的系統(tǒng)表是 MyISAM 的,因此備份基本都通過(guò) innobackupex 命令進(jìn)行;另外一個(gè)原因是我們可能需要保存位點(diǎn)信息。

 

   那么一個(gè)perl腳步和C程序是如何進(jìn)行通信的呢?它們是如何知道撒時(shí)候該執(zhí)行什么步驟的呢?

 

   2個(gè)工具之間的交互和協(xié)調(diào)