您的位置:首页 > 数据库 > MySQL

mysql通过物理备份主库方式恢复从库

2016-07-18 11:06 375 查看

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.

 

也有的说可以move theInnoDB log sequence number (LSN) forward,参考:https://www.percona.com/blog/2013/09/11/how-to-move-the-innodb-log-sequence-number-lsn-forward/,但我没试验,以后有机会再试验吧。

 */

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: