背景
是这样的,我们正式环境已经跑了很久的主从和读写分离,而测试环境一直只有一个数据库在跑,正式环境出现好几次主从延迟,但测试环境没办法复现,所以想让测试环境尽可能保持跟正式环境一致,因此,进行了一次主从复制配置。
环境:
我们的测试环境有两个数据库,一个在正常读写,另一个已搭建但未接入使用,原来在用的作为主库(IP就叫10.10.10.1),未接入的作为从库(IP就叫10.10.10.2)
数据库版本:5.7.24-27-log
下面为主从配置详细步骤
step1、主库授权从库
主库执行
MySQL>GRANT REPLICATI ON SLAVEON *.* TO 'rep1'@'10.10.10.2' IDENTIFIED BY 'passwordxx';
说明:
ON 后面的参数为指定可复制至从库的数据库/表,星号表示复制全部,如果想要部分数据库或表不复制,第一个*可改成指定数据库名称,第二个可改成指定表名称;
亦可进入mysql安装目录的etc文件夹,修改 my.cnf 文件,设置忽略复制指定表:replicate_wild_ignore_table=test.% (忽略test库所有表,有其他需要忽略,则添加一行该配置)
rep1—— 为 设置授权用户名
10.10.10.2——从库服务器IP
step2、记录主库信息
主库执行
MySQL>show master status;
记住File、Position、Executed_Gtid_Set的值
说明:
这里的File为主库binlog日志的文件名,Position为该命令所在的位置
如果记录position后,又不小心在主库执行了sql,则position是会变化的,可能会导致设置失败,重来即可;
step3、将从库设置为只读
进入从库安装目录,进入etc目录,点击修改配置文件my.cnf,添加一行
read-only
step4、停止从库
从库执行
MySQL>stop slave;
step5、从库设置同步
从库执行
MySQL>change master to master_host='10.10.10.1',master_user='rep1',master_password='passwordxx',master_log_file='mysql-bin.000004',master_log_pos=198477;
说明
里面各参数的值对应上面各步骤得到的值;
如果主库mysql服务的端口不是默认端口,则设置同步时,需要指定主库端口:
MySQL>change mastertomaster_host='10.10.10.1',master_user='rep1',master_password='passwordxx',master_port=3377,master_log_file='mysql-bin.000004',master_log_pos=198477;
step6、启动从数据库
从库执行
MySQL>start slave;
step7、检查同步是否配置成功
从数据库执行
MySQL>show slave status\G;
检查Slave_IO_Running和Slave_SQL_Running必须为yes;
成功状态时,Slave_SQL_Running_State会提示 Slave has read all relay log; waiting for more updates
以上则主从复制配置完成。
上面是针对主从都是新建立的情况下的设置,如果主库原来正在运行,需要增加从库,则在配置前需要先数据迁移。
主库数据迁移
如果主数据库已经存在数据,需要把binlog文件手动迁移到从数据库,否则是不会自动把已有的数据同步到从库的。可以用mysqldump导入导出的方式,但我这边数据量比较大,用这种方式提示超时了,而且用这种方式,貌似需要在从库手动创建数据库,所以这里用的是直接打包主库数据复制到从库的方式。
1、将主库服务器改成只读模式(不改成只读的话,可能主库会继续增加数据,迁移数据就会丢失),登录主数据库,执行
MySQL >flush tables with read lock;
2、主库所在服务器,进入mysql数据文件夹所在目录,我这边是/data,用tar命令将该目录下全部文件打包
# tar -zcpf mysqldata.tar.gz ./mysql33077_data/*
3、从库所在服务器,进入同样的目录,解压并覆盖原数据
# tar -zxvf mysqldata.tar.gz
4、停止从数据库服务
我这边试了多种正常停止数据库服务的命令,比如 service mysql stop、/etc/inint.d/mysqld stop、service mysqld stop、systemctl stop mysqld都不行,mysqladmin shutdown由于不知道服务器密码(用跳板机登录的)没办法验证,所以用强制kill服务的方式停止了
(这里补充一下,在同事的帮助下,我了解到停止数据库的方法依赖数据库的启动方式,而启动方式是根据数据库的安装方式的,这里数据库的安装我还没有怎么实践,了解有限。数据库的启动方式有serivce启动,my.cnf配置文件启动,inint.d脚本启动等等,我这用的是my.cnf配置文件启动的,可能描述有误,请纠正)
从库服务器,先查看mysql服务进程
# ps -ef|grep mysql
kill掉进程
# kill -9 24524
5、删除从库数据根目录下的auto.cnf文件
因为我是用复制整个数据库数据文件夹的方式迁移数据的,会把主库特定的一些特性文件也复制过来,这些会导致从库的uuid与主库一样或者数据查询不到,导致异常
auto.cnf文件
6、启动从数据库服务
(可以通过查看服务器操作历史查看数据库启动方式~方便快捷!命令:history |grep mysql)
# /usr/local/mysql33077/bin/mysqld --defaults-file=/usr/local/mysql33077/etc/my.cnf --basedir=/usr/local/mysql33077 --datadir=/data/mysql33077_data --plugin-dir=/usr/local/mysql33077/lib/mysql/plugin --user=mysql --log-error=/usr/local/mysql33077/mysqld.log --pid-file=vbj-easychange-b1-20190620-2.pid --socket=/usr/local/mysql33077/tmp/mysql.sock --port=33077
1
7、重新配置同步并启动从库
(其实可以先迁移数据,再配置从库同步的,但我看教程的时候人家是先同步,就跟着做了,不过首先一定要先停止主库的写入,不然sql执行位置就会找不到)
MySQL >change master to master_host='10.10.10.1',master_user='rep1',master_password='passwordxx',master_port=3377,master_log_file='mysql-bin.000004',master_log_pos=198477;
可以看到uuid正常了,从库状态也正常了
8、主数据库解除只读
主库执行
MySQL >unlock tables;MySQL >flush privileges;
9、验证主从是否可以同步,在主数据库插入一条数据,查询从数据库是否同步新增
遇到的问题和解决方法
1、数据迁移后,在到从库能查询到数据库,但查询表数据失败,提示
table doesnt exits;
解决方案:重启mysql服务,启动前记得删除auto.cnf文件,因为这个文件里面的信息是主库的,删除重启后会自动生成新的
2、flush tables with read lock 设置只读后,刚开始是生效的,没多久自动解锁了
这个出现的原因我没找到答案,按照很多网上教程,这个命令应该可以可靠生效的,大概是这个原因,导致我前面一次数据迁移后,主库还有新的写入,从库的sql始终执行不到最新的,gtid是错的,还得重置gtid,问题是数据已经不一致了。。。只好重新配置主从
解决方案:改成通过参数设置
MySQL >setglobal read_only=1;MySQL >flush privileges;
不过这个方式设置的只读对root用户是无效的,所以配置后千万小心不要root用户在主库做插入,我就是误操作了。。。然后又重来,当然可能可以不用重来的,但我没找到更方便的解决方案,请大神指教~
以上,可能有很多说得不对的或者描述不妥的,请一一指出~