mysql通過物理備份主庫方式恢復從庫
1 場景描述
有一套主從環境,從庫和主庫差異量比較大。其中一個庫大小800G左右,127個表,平均每個表差異100萬條資料。試過用pt-table-checksum,pt-table-sync進行同步,但是太慢了,平均同步一個表需要5個小時。因此,打算通過拷貝主庫表空間檔案,表結構定義檔案,日誌檔案等到從庫的方式,使得從庫和主庫保持一致。
2 變更步驟
2.1 停止從庫
service mysqld stop
修改配置檔案,新增skip-slave-start,避免從庫啟動時自動啟動複製(因為預設資料庫自動時會自動啟動複製,會從上一次slave停止的位置自動繼續複製,這裡避免自動啟動,是為了後面可以change master to自定義開始複製的位置)。
2.2 刪除從庫表空間檔案和資料庫檔案
cd /database1/mysql
rm -rf DatabaseName1 DatabaseName2
rm -rf ibdata1
2.3 從主庫拷貝資料檔案和表空間檔案
確保先停掉主庫上的業務。
鎖定主庫,記錄下當前binlog日誌及position,方便從庫後續從這個位置開始複製。
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
#為什麼停掉業務了,還要加個讀鎖呢,為了以防萬一,嘿嘿,有時存在定時任務,也會對資料庫進行增刪改。
mysql> show master status;
+--------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
|| master1-bin.001434 | 13144499 | |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
--拷貝資料庫檔案
cd /mysql_data1/mysql
scp -r DatabaseName1 DatabaseName2 從庫IP:/database1/mysql/
--拷貝完資料檔案後,開始拷貝日誌檔案
在從庫上先備份下之前的日誌檔案
cd /database1/mysql
mv ib_logfile0 ib_logfile0_bak_07152225
mv ib_logfile1 ib_logfile1_bak_07152225
mv ib_logfile2 ib_logfile2_bak_07152225
在主庫上拷貝:
scp /mysql_data1/mysql/ib_logfile*從庫IP:/database1/mysql/
日誌檔案拷貝完成後,開始拷貝共享表空間檔案
在從庫上啟動netcat(netcat適合大資料量的拷貝):
nc -l 30240> /database1/mysql/ibdata1
在主庫上:
nc 從庫IP 30240 < /mysql_data1/mysql/ibdata1
拷貝完成後,解鎖
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
--修改owner
在從庫上執行:
chown -R mysql:mysql DatabaseName1 DatabaseName2ibdata1
chown -R mysql:mysql ib_logfile*
2.4啟動從庫
service mysqld start
看是否還報錯,觀察幾分鐘,看程序是否還在。
2.5 開啟複製
mysql> showslave status \G;
***************************1. row ***************************
Slave_IO_State:
Master_Host: ……
Master_User: replica
Master_Port: 3306
Connect_Retry: 60
Master_Log_File:master1-bin.001423
Read_Master_Log_Pos: 40860837
Relay_Log_File:web_appdb_10-relay-bin.000671
Relay_Log_Pos: 40860985
Relay_Master_Log_File:master1-bin.001423
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:np002.%,ccda.%,eip_fileservice.%
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 40860837
Relay_Log_Space: 40863264
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert:No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.00sec)
ERROR:
No query specified
指向當時鎖定的位置:
change master tomaster_host='主庫
IP',master_log_file='master1-bin.001434',master_log_pos=13144499;
start slave;
確保IO程序和SQL程序都為Yes.
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
觀察Seconds_Behind_Master,確保其最後值為0.
3 檢查測試
抽查主庫和從庫的幾個表記錄條數是否一致。
也可以用percona toolkit工具抽查幾個表,看是否存在差異。
沒問題後,讓同事開啟業務。
/*
本實驗需要停掉業務,禁止在主庫上寫資料。因為倘若主庫上有讀寫的話,恢復完從庫,會導致無法啟動從庫,錯誤日誌報錯:
160709 5:47:10 InnoDB: Error: page 7 logsequence number 7229203959465
InnoDB: is in the future! Current system logsequence number 6245064532384.
InnoDB: Your database may be corrupt or youmay have copied the InnoDB
InnoDB: tablespace but not the InnoDB logfiles. See
InnoDB:http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: for more information.
我按網上說的,在從庫配置檔案裡新增引數innodb_force_recovery=n,後來雖然從庫能啟動成功了,但是卻無法讀寫資料,便沒有采取該方案。
mysql>insert into np002.pending_0(_id) values('dan');
ERROR1030 (HY000): Got error -1 from storage engine
錯誤日誌報錯:
InnoDB: Anew raw disk partition was initialized or
InnoDB:innodb_force_recovery is on: we do not allow
InnoDB:database modifications by the user. Shut down
InnoDB:mysqld and edit my.cnf so that newraw is replaced
InnoDB:with raw, and innodb_force_... is removed.
*/