MySQL備份失敗,一波三折的問(wèn)題分析和處理
今天和同事一起處理了一個(gè)奇怪的MySQL空間異常問(wèn)題,從這個(gè)問(wèn)題的處理中可以找到一些問(wèn)題處理的方式。
問(wèn)題的背景是有一個(gè)實(shí)例的備份總是失敗,在排查了多次之后,在保證Slave可用的情況先擱置了,剛好借著這幾天的時(shí)間做了下收尾和梳理。
備份失敗的報(bào)錯(cuò)提示信息是:
- innobackupex: Error writing file '/tmp/xbtempevLQbf' (Errcode: 28 - No space left on device)
- xtrabackup: Error: write to logfile failed
- xtrabackup: Error: xtrabackup_copy_logfile() failed.
看起來(lái)多直白的問(wèn)題,空間不足嘛,是不是空間配置的問(wèn)題。
但是在本地進(jìn)行模擬測(cè)試的時(shí)候,使用了如下的腳本開(kāi)啟本機(jī)測(cè)試。
- /usr/local/mysql_tools/percona-xtrabackup-2.4.8-Linux-x86_64/bin/innobackupex --defaults-file=/data/mysql_4308/my.cnf --user=xxxx --password=xxxx --socket=/data/mysql_4308/tmp/mysql.sock --stream=tar /data/xxxx/mysql/xxxx_4308/2020-02-11 > /data/xxxx/mysql/xxxx_4308/2020-02-11.tar.gz
發(fā)現(xiàn)所在的/tmp目錄卻沒(méi)有空間異常的情況,而相反是根目錄的空間使用出現(xiàn)了異常,這是測(cè)試中截取到的一個(gè)空間異常的截圖。
而在拋出異常之后,備份失敗,空間使用率馬上恢復(fù)。
綜合目前得到的信息,我的直觀感覺(jué)是問(wèn)題貌似和/tmp沒(méi)有太直接的聯(lián)系,那一定是在根目錄的使用過(guò)程中的其他目錄產(chǎn)生了異常。
于是我開(kāi)始了第二次測(cè)試,這一次我著重關(guān)注根目錄的整體使用,看看到底是哪個(gè)目錄的使用異常了,但是尷尬的是,盡管做了腳本的快速采集,竟然沒(méi)有發(fā)現(xiàn)在我們常見(jiàn)的目錄下有空間異常。
- 332K ./home
- 411M ./lib
- 26M ./lib64
- 16K ./lost+found
- 4.0K ./media
- 4.0K ./misc
- 4.0K ./mnt
- 0 ./net
- 184M ./opt
- du: cannot access `./proc/40102/task/40102/fd/4': No such file or directory
- du: cannot access `./proc/40102/task/40102/fdinfo/4': No such file or directory
- du: cannot access `./proc/40102/fd/4': No such file or directory
- du: cannot access `./proc/40102/fdinfo/4': No such file or directory
- 0 ./proc
- 2.3G ./root
- 56K ./tmp
- 。。。
所以從目前的情況來(lái)看,應(yīng)該是/proc相關(guān)的目錄下的空間異常了。
事情到了這個(gè)時(shí)候,似乎可用的方式已經(jīng)不多了。
我排查了腳本,排查了參數(shù)文件,整體來(lái)看沒(méi)有和其他環(huán)境相比明顯的問(wèn)題,但是有一個(gè)細(xì)節(jié)引起了我的注意,那就是使用top的時(shí)候,看到這個(gè)實(shí)例的內(nèi)存使用了6G(服務(wù)器內(nèi)存是8G),但是buffer pool的配置才是3G左右,這是一個(gè)從庫(kù)環(huán)境,也沒(méi)有應(yīng)用連接,所以也不大可能存在太多的連接資源消耗,所以綜合來(lái)看,應(yīng)該是和服務(wù)器的內(nèi)存異常有關(guān)。
這個(gè)時(shí)候嘗試了在線resize,發(fā)現(xiàn)已經(jīng)沒(méi)有收縮的空間了。因?yàn)槭菑膸?kù)服務(wù),于是我開(kāi)始重啟從庫(kù)的服務(wù)。
但是意外的是重啟數(shù)據(jù)庫(kù)的時(shí)候卡住了,大概過(guò)了有2分鐘,只是看到一些輸出的小數(shù)點(diǎn),大概輸出了兩行,還是沒(méi)有反應(yīng),查看后臺(tái)日志沒(méi)有任何輸出,于是我開(kāi)始嘗試plan B,準(zhǔn)備Kill 進(jìn)程重啟服務(wù)。
這一次kill操作生效了,過(guò)一會(huì)服務(wù)啟動(dòng)起來(lái)了。但是報(bào)出了從庫(kù)復(fù)制異常。
- Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
- 。。。
- Master_Server_Id: 190
- Master_UUID: 570dcd0e-f6d0-11e8-adc3-005056b7e95f
- 。。。
- Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
- Master_Retry_Count: 86400
- Master_Bind:
- Last_IO_Error_Timestamp: 200211 14:20:57
- Retrieved_Gtid_Set: 570dcd0e-f6d0-11e8-adc3-005056b7e95f:821211986-2157277214
- Executed_Gtid_Set: 570dcd0e-f6d0-11e8-adc3-005056b7e95f:1-820070317:821211986-2157277214
這個(gè)錯(cuò)誤的信息是比較明顯了,是主庫(kù)的binlog被purge掉了,導(dǎo)致在從庫(kù)去復(fù)制應(yīng)用的時(shí)候失敗了。
為什么會(huì)有這么奇怪的一個(gè)問(wèn)題呢,因?yàn)橹鲙?kù)的binlog默認(rèn)還是保留了一些天數(shù),不至于把1個(gè)小時(shí)前的binlog刪除。
關(guān)于GTID的一些變量值如下:
Retrieved_Gtid_Set: 570dcd0e-f6d0-11e8-adc3-005056b7e95f:821211986-2157277214
Executed_Gtid_Set: 570dcd0e-f6d0-11e8-adc3-005056b7e95f:1-820070317:821211986-2157277214
gtid_purged : 570dcd0e-f6d0-11e8-adc3-005056b7e95f:1-820070317:821211986-2131381624
Master端的GTID_Purged為:
gtid_purged :570dcd0e-f6d0-11e8-adc3-005056b7e95f:1-2089314252
綜合這些信息來(lái)看,Slave端的GTID和主庫(kù)沒(méi)有完整的銜接起來(lái),也就意味著在之前對(duì)這個(gè)Slave做過(guò)一些操作,導(dǎo)致GTID在Master和Slave端產(chǎn)生了一些偏差。
而這個(gè)遺漏的變更部分570dcd0e-f6d0-11e8-adc3-005056b7e95f:821211986保守來(lái)估計(jì)也是1個(gè)月以前了,binlog是肯定沒(méi)有保留的。
我們?cè)诖讼葧簳r(shí)修復(fù)這個(gè)復(fù)制問(wèn)題。
停止Slave沒(méi)想到又出問(wèn)題了,一個(gè)看似簡(jiǎn)單的stop Slave操作竟然持續(xù)了1分多鐘。
>>stop slave;
Query OK, 0 rows affected (1 min 1.99 sec)
嘗試減小Buffer pool配置,重啟,stop slave,這個(gè)操作依然很慢,所以可以在這個(gè)方向上排除延遲的問(wèn)題和Buffer Pool關(guān)系不大,而相對(duì)和GTID的關(guān)系更大一些。
Slave端修復(fù)步驟如下:
- reset master;
- stop slave;
- reset slave all;
- SET @@GLOBAL.GTID_PURGED='570dcd0e-f6d0-11e8-adc3-005056b7e95f:1-2157277214';
- CHANGE MASTER TO MASTER_USER='dba_repl', MASTER_PASSWORD='xxxx' , MASTER_HOST='xxxxx',MASTER_PORT=4308,MASTER_AUTO_POSITION = 1;
其中GTID_PURGED的配置是關(guān)鍵。
修復(fù)后,Slave端的延遲問(wèn)題就解決了,而再次嘗試重新備份,在根目錄竟然沒(méi)有了空間消耗。
小結(jié):
這個(gè)過(guò)程中主要是要快速解決問(wèn)題,有些步驟的日志抓取的不夠豐富和細(xì)致,從問(wèn)題的分析來(lái)說(shuō),還是缺少了一些更有說(shuō)服力的東西,對(duì)于問(wèn)題的原因,本質(zhì)上還是不合理的問(wèn)題(比如bug或者配置異常等)導(dǎo)致了不合理的現(xiàn)象。
在這一塊還是可以借鑒的是分析的整體思路,而不是這個(gè)問(wèn)題本身。