1.1.1. mysql5.6.14的datadir遷移時遇到報錯
【環境描述】
在機器A上安裝了perconamysql 5.6.14,數據庫停啟正常,datadir路徑為pathA,並且已經做了應用數據庫的初始化工作,然後關閉了這個數據庫實例,把它的datadir和/etc/my.cnf遷移到另外一台機器B上的percona mysql 5.6.14,遷移後的datadir路徑修改成路徑pathB,在啟動mysql服務的時候遇到問題,啟動失敗。
操作步驟:
1) 停掉機器A上的mysql
service mysql stop
2) 對機器A上mysql的datadir(路徑pathA)和my.cnf做打包,傳輸到機器B,並把datadir解壓到pathB
3) 在機器B上安裝percona mysql 5.6.14
4) 使用機器A傳輸過來的my.cnf覆蓋機器B的/etc/my.cnf
5) 修改機器B的/etc/my.cnf中datadir路徑為pathB
6) 在機器B上執行service mysql start啟動mysql服務
7) 啟動失敗,發生報錯
【mysql報錯】
啟動時的報錯servicemysql start:
Starting MySQL(Percona Server)......Theserver quit without[FAILED]ng PID file(/home/mysql_3306_bak/mysql.pid).
錯誤日志中的報錯:
/usr/sbin/mysqld: File '/home/mysql_3306/mysql-bin.000003'not found (Errcode: 2 - No such file or directory)
2014-04-25 22:26:47 27048 [ERROR] Failed toopen log (file '/home/mysql_3306/mysql-bin.000003', errno 2)
2014-04-25 22:26:47 27048 [ERROR] Could notopen log file
2014-04-25 22:26:47 27048 [ERROR] Can'tinit tc log
2014-04-25 22:26:47 27048 [ERROR] Aborting
2014-04-25 22:26:47 27048 [Note] Binlog end
2014-04-25 22:26:47 27048 [Note] Shuttingdown plugin 'partition'
已經修改了my.cnf配置文件中所有的路徑,但是Mysql仍然說找不到'/home/mysql_3306/mysql-bin.000003'路徑的文件,從報錯看上去很詭異。
【問題原因】
Mysql報錯提示找不到binlog,是由於my.cnf中配置了:
log-bin= /home/mysql_3306/mysql-bin
log-bin-index= /home/mysql_3306/bin-index
mysql會在log-bin-index參數指定的文件中維護log-bin的索引列表,並且它是以絕對路徑的方式記錄的:
/home/mysql_3306?mysql-bin.000001
/home/mysql_3306?mysql-bin.000002
/home/mysql_3306?mysql-bin.000003
雖然已經把/etc/my.cnf中的所有路徑都修改正確了,但是mysql服務在啟動時,是通過讀取log-bin-index來查找log-bin日志文件的,查找的文件還是在機器A上指定的位置,所以mysql服務啟動失敗。
【解決方法】
手動修改log-bin-index指定的二進制日志索引文件,修改裡面所有log-bin的路徑,指定到當前datadir下的二進制日志,然後嘗試啟動mysql服務,啟動成功,問題解決。
【問題思考】
Whatis log-bin-index paramter ?
Mysql官方手冊中說明“如果沒有在my.cnf中配置log-bin-index參數指定,mysql會自動創建一個以host_name-bin.index命名的二進制索引文件(實驗證明是mysql-bin.index)”。
所以,嘗試去掉my.cnf中配置的log-bin-index參數,然後啟動mysql服務,此時mysql服務正常啟動,查看log-bin-index文件:
#cat mysql-bin.index
/home/mysql_3306_bak/mysql-bin.000006
我們發現mysql自動創建了名為“mysql-bin.index”的二進制索引文件,並且文件中只包含在啟動時重新生成的二進制文件路徑信息。
此時,mysql只知道此次啟動時生成的二進制文件路徑信息,那麼也就意味著此時mysql丟失了編號000006之前的所有日志文件,我們進行如下的測試:
執行flush logs命令,讓mysql再刷出來幾個二進制日志;
#cat mysql-bin.index
/home/mysql_3306_bak/mysql-bin.000006
/home/mysql_3306_bak/mysql-bin.000007
/home/mysql_3306_bak/mysql-bin.000008
然後,執行purgebinary logs to 'mysql-bin.000004' 命令:
>purge binary logs to 'mysql-bin.000004';
ERROR1373 (HY000): Target log not found in binlog index
此時,mysql提示無法找到000004號二進制日志文件,接下來嘗試刪除000006號二進制日志文件:
> purge binary logs to'mysql-bin.000007';
QueryOK, 0 rows affected (0.03 sec)
查看mysql-bin.index二進制日志索引文件:
#cat mysql-bin.index
/home/mysql_3306_bak/mysql-bin.000007
/home/mysql_3306_bak/mysql-bin.000008
查看二進制日志文件:
#ls -ltr mysql-bin.00000*
mysql-bin.000004
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000005
mysql-bin.000007
mysql-bin.000008
mysql已經徹底刪除了編號000006的二進制日志文件。
接下來,我們嘗試欺騙mysql,配置一個指向虛機路徑的二進制日志文件:
#cat mysql-bin.index
/tmp/mysql-bin.0000005
/home/mysql_3306_bak/mysql-bin.000007
/home/mysql_3306_bak/mysql-bin.000008
在mysql中嘗試刪除編號000007之前的日志:
>purge binary logs to 'mysql-bin.000007';
ERROR 29 (HY000): File '/tmp/mysql-bin.0000005' not found (Errcode:2 - No such file or directory)
mysql在讀取log-bin-index日志索引文件刪除日志的時候發現日志文件不存在,報錯;
我們在嘗試重啟mysql,來判斷它是如何讀取和加載log-bin-index日志索引文件 以及索引文件中指定的二進制日志文件的:
# service mysql stop
Shutting down MySQL (PerconaServer)... [ OK ]
# service mysql start
Starting MySQL (PerconaServer).... [ OK ]
查看error.log日志:
2014-04-2600:53:28 7f752cddc700 InnoDB: Buffer pool(s) load completed at 140426 0:53:28
^G/usr/sbin/mysqld:File '/tmp/mysql-bin.0000005' not found (Errcode: 2 - No such file or directory)
2014-04-2600:53:28 16723 [ERROR] Failed to open log (file '/tmp/mysql-bin.0000005', errno2)
2014-04-2600:53:28 16723 [ERROR] Could not open log file
【總結】
雖然mysql的error日志中有error信息,但是mysql仍然成功啟動了,也就是說mysql在啟動過程會讀取log-bin-index文件,然後也會判斷索引指定的log-bin文件是否存在,結合本案例中遇到的情況,可以知道只有當最後一個路徑指定的log-bin不存在時,mysql服務才會中斷啟動操作,即啟動失敗。
【Sum Up】
1) 如果mysql沒有開啟binlog,則不會遇到這個問題;
2) 如果mysql開啟了binlog,並且在Datadir物理遷移的過程中,修改了datadir的路徑,就會遇到這個問題,此時,可以編輯log-bin-index文件修復log-bin文件的路徑或者直接刪除,然後啟動mysql服務;
3) 為了避免遇到這個問題,在進行datadir遷移的時候,盡量不要改變datadir的路徑;