1. 程式人生 > >mysql通過物理備份主庫方式恢復從庫

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.

 */