有一套主从环境,从库和主库差异量比较大。其中一个库大小800G左右,127个表,平均每个表差异100万条数据。试过用pt-table-checksum,pt-table-sync进行同步,但是太慢了,平均同步一个表需要5个小时。因此,打算通过拷贝主库表空间文件,表结构定义文件,日志文件等到从库的方式,使得从库和主库保持一致。
service mysqld stop
修改配置文件,添加skip-slave-start,避免从库启动时自动启动复制(因为默认数据库自动时会自动启动复制,会从上一次slave停止的位置自动继续复制,这里避免自动启动,是为了后面可以change master to自定义开始复制的位置)。
cd /database1/mysql
rm -rf DatabaseName1 DatabaseName2
rm -rf ibdata1
确保先停掉主库上的业务。
锁定主库,记录下当前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*
service mysqld start
看是否还报错,观察几分钟,看进程是否还在。
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.
抽查主库和从库的几个表记录条数是否一致。
也可以用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/,但我没试验,以后有机会再试验吧。
*/