天天看點

【MySQL】innobackupex 長時間hang

【問題現象】

一個資料庫執行個體的備庫在做備份時,備份的log 一直顯示

>> log scanned up to (3015320266621)

....

長達 10多個小時。

mysql> show processlist;

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

| id     | user        | host               | db   | command    | time    |state                              

|      1 | system user |                    | null | connect    | 2684619 | waiting for master to sendevent     

|      2 | system user |                    | null | connect    |      31 | waiting for release of readlock                                ......

4 rows in set (0.00 sec)

system使用者顯示 waiting for release of readlock

執行備份的使用者為xtraback 對應的time 列則每4s 循環一次。system user 的狀态表示 xtraback 程序已經執行了flush tables with read only,并等待xtrabackup程序釋放read lock。我們首先來了解一下xtrabackup 大緻過程:

 backup()并記錄xtrabackup_binary資訊

 mysql_open()  啟動管道連結的子程序連接配接mysql

 mysql_check() 檢查連接配接mysql的子程序是否ok,發送一個虛拟查詢,等待mysql_response_timeout逾時退出

 mysql_close() 關閉連接配接mysql子程序

 start_ibbackup() 建立子程序運作ibbackup來備份innodb資料和索引

   如果不是遠端備份,不是stream模式,進入wait_for_ibbackup_suspend() 檢查ibbackup子程序是否還活着

 mysql_open()

 如果指定–safe-slave-backup 進入wait_for_safe_slave() ,通過每隔3s啟停sql thread來不斷檢查執行個體上打開臨時表數目是否為0

 mysql_check()

 如果沒有指定–no-lock,進入 mysql_lockall(),執行flush tables with read lock;

 backup_files() 拷貝除ibd外所有的檔案

 mysql_unlockall() 執行unlock tables

 如果指定–safe-slave-backup  start slave sql_thread

 mysql_close()

問題出現在 發出flush tables with read lock 并擷取了全局鎖(systemuser 才在等待read lock) innodb 拷貝除ibd外所有的檔案.

但是根據

xtrabackup源碼 

# flush tables with read lock

        mysql_check(); --沒有問題

        mysql_lockall() if !$option_no_lock; 

# timeout in seconds for a reply from mysql

my $mysql_response_timeout = 900;

sub mysql_send {

    my $request = shift;

    $current_mysql_request = $request;

    print mysql_writer "$request\n";

    mysql_check();

    $current_mysql_request = '';

}

sub mysql_lockall {

    $now = current_time();

    print stderr "$now  $prefix starting to lock all tables...\n";=

    mysql_send "use mysql;";

    mysql_send "set autocommit=0;";

    if (compare_versions($mysql_server_version, '4.0.22') == 0

        || compare_versions($mysql_server_version, '4.1.7') == 0) {

        # mysql server version is 4.0.22 or 4.1.7

        mysql_send "commit;";

        mysql_send "flush tables with read lock;";

    } else {

        # mysql server version is other than 4.0.22 or 4.1.7

    }

    write_binlog_info;

    write_slave_info if $option_slave_info;

    print stderr "$now  $prefix all tables locked and flushed to disk\n";

--在執行flush tables with read lock時,mysql_send函數執行逾時900s,備份失敗。我的執行個體的備份卻一直表現為log scanned up to (3015320266621)。

記錄一個疑問在這裡。