当主库存在历史数据时如何完成全量Mysql主从复制
当主库存在历史数据时如何完成全量Mysql主从复制
上一篇文章介绍了docker+mysql的主从复制的搭建,使用docker有许多优点:可以轻松实现跨平台的移植、docker容器之间不会互相影响、容器内部不会污染宿主机的环境等等。如果大家还没有接触docker,建议先去了解一下docker的使用教程,当然了,不会docker也不影响学习解决该问题的大体步骤。
前提:
当决定使用Mysql主从复制的数据库架构时,可能你的工程已经运行了一段时间,这是很常见的场景,比如目前我负责的一个项目,我想改变生产环境的单节点数据库的现状,通过主从复制为读写分离作铺垫。那么就需要两台及以上的节点作为数据库节点,这里所谓的节点不仅仅指服务器,也可能是同一台服务器,不同端口,使用docker进行隔离。
可是我在配置完主从复制后发现,主节点已经存在的数据并没有同步到从节点,当主节点向数据库写数据时,从节点重复这些操作,可从节点本身根本没有创建那些主节点的库,导致运行出错、IO线程坏死,最终从节点挂掉
教程开始
查看主库的已有数据库
show databases;
假设其中test数据库是我们想要主从同步的数据库,模拟生产环境,该数据库中已经有了很多数据
use test;
select * from user;
锁定主数据库
锁定主数据库,只允许读取不允许写入,这样做的目的是防止备份过程中或备份完成之后有新数据插入,导致备份数据和主数据数据不一致,同样,这样做也有弊端,可能在锁库期间会影响正常的业务流程,所以我们应使锁库的粒度尽可能小。
flush tables with read lock;
查询主数据库状态,并记下FILE及Position的值
show master status;
开始备份主数据库
退出mysql终端,执行docker mysql备份命令
docker exec [CONTAINER] /usr/bin/mysqldump -u username --password=xxx [DATABASE] > back.sql
[CONTAINER] 是你自己容器的名字, [DATABASE]是你自己数据库的名字,back.sql是临时产生的备份文件,里面是sql语句, username是你自己的用户名,一般是root,xxx则是你自己的用户密码。该命令的意思是执行docker容器内mysql相关命令:mysqldump,将指定的数据库导出到宿主机当中
我们这里只需要备份test数据库,若要备份全部数据库,[DATABASE]处使用--all-databases
在宿主机上执行下列语句
图中的warnming是因为我们在命令行输入了密码,所以会有安全警告信息。可以看到,已经在宿主机上生成了back.sql,
开始导入从数据库
在导入备份文件之前,需要在从库中手动建立相应的同名库CREATE DATABASE test;
,否则会出现如下报错
找不到相关数据库
在手动创建完数据库后执行下列语句
cat back.sql | docker exec -i [CONTAINER] /usr/bin/mysql -u username --password=xxx [DATABASE]
备份成功
之后就可以开始进行主从模式的配置了,具体可以参考我这篇文章docker+mysql的主从复制的搭建
记住配置完要解锁主库
unlock tables;