上一篇博客写了MYSQL主从复制原理 : MySQL(13)---MYSQL主从复制原理html
这篇咱们来写 Docker搭建MYSQL主从复制(一主一从)mysql
说明
系统为阿里云服务器,操做系统为CentOS7.6。MYSQL版本 8.0.22sql
sudo apt-get update sudo apt install docker.io
# 没有指定版本表明拉取最新版本 目前这里最新的是8.0.22。若是想指定版本能够docker pull mysql:5.7 表明下载5.7版本 docker pull mysql
运行完以上命令以后,镜像就已经下载下来了,能够用 docker images 命令查看是否已经下载成功docker
docker run -p 3306:3306 --name MYSQL8 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
参数说明
数据库
-p 3306:3306: 将容器内的3306端口映射到实体机3306端口 --name MYSQL8: 给这个容器取一个容器记住的名字 -e MYSQL_ROOT_PASSWORD=123456: docker的MySQL默认的root密码是随机的,这是改一下默认的root用户密码 -d mysql:latest: 在后台运行mysql:latest镜像产生的容器
以后的第二次启动直接用 docker start MYSQL8 便可。vim
新装了MYSQL8.0后再用navicat链接就会报2059的错误。上网查了发现是8.0以后MYSQL更改了密码的加密规则,只要在命令窗口把加密方法改回去便可。segmentfault
1) 首先使用如下命令进入MySQL的Docker容器bash
# MYSQL8是上面启动的时候 为该容器起的名称 docker exec -it MYSQL8 bash
2)而后登陆MySQL服务器
#这里的密码就是上面设置的密码 mysql -uroot -p123456
3)最后运行如下SQL便可ide
alter user 'root'@'%' identified by '123456' password expire never; alter user 'root'@'%' identified with mysql_native_password by '123456'; flush privileges;
这样就能够经过navicat工具链接当前数据库了。这里顺便看下当前MYSQL的版本,经过 select version()
;
明显能够看到当前MYSQL的版本是 8.0.22
注意
我这边Master库和Slave库不在同一个服务器,因此Slave安装MYSQL的步骤和Master同样就能够了。必定要记住Msater库和Slave库的MYSQL版本号要一致。
这里假设主从服务器的IP以下
由于是经过Docker部署的MYSQL,因此要进入Docker内部修改MYSQL配置文件
# MYSQL8是上面启动的时候 为该容器起的名称 docker exec -it MYSQL8 bash
进入容器后,切换到 /etc/mysql 目录下,使用vim命令编辑 my.cnf 文件。
注意
此时用vim 命令会报 vim: command not found,所以咱们须要在Docker内部安装vim工具。安装步骤推荐一篇博客:vi: command not found
在my.cnf添加以下配置
## 同一局域网内注意要惟一 server-id=100 ## 开启二进制日志功能,能够随便取(关键) log-bin=mysql-bin
添加完后保存,同时退出当前Docker容器。由于修改了配置文件,因此要重启下该MYSQL,这里重启下该Docker容器就行了。
# MYSQL8是上面启动的时候 为该容器起的名称 docker restart MYSQL8
这个时候咱们经过工具链接该MYSQL服务器,你能够经过navicat或者Sequel pro等等,链接登上后。
建立用户并受权
--为从库服务器 设置用户名和密码(代表从服务器的ip必须为47.00.00.02,帐号为slave 密码123456 CREATE USER 'slave'@'47.00.00.02' IDENTIFIED BY '123456'; grant replication slave, replication client on *.* to 'slave'@'47.00.00.02'; --设置权限 flush privileges; --权限生效
至此,Master配置完成。
和上面同样进入到 etc/mysql 路径,使用vim命令编辑 my.cnf 文件:
## 设置server_id,注意要惟一 和master也不能同样 server-id=101 ## 开启二进制日志功能,以备Slave做为其它Slave的Master时使用 log-bin=mysql-slave-bin ## 设置为只读,该项若是不设置,表示slave可读可写 read_only = 1
配置完成后也须要重启Docker容器。
# MYSQL是上面启动的时候 为该容器起的名称 docker restart MYSQL8
上面两步Master和Slave都配置成功了,并且Master也为Slave读取Master数据专门设置了一个帐号,下面就来实现同步。
进入Master库
查看Master状态
--经过该命令能够查看master数据库当前正在使用的二进制日志及当前执行二进制日志位置 show master status
记住File和Position,后面Slave库会在这个文件这个位置进行同步数据。此时必定不要操做Master库,不然将会引发Master状态的变化,File和Position字段也将会进行变化。
进入Slave库
执行SQL
change master to master_host='47.00.00.01', master_user='slave', master_password='123456', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=156 ;
命令说明
master_host :Master库的地址,指的是容器的独立ip,能够经过: master_port :Master的端口号,指的是容器的端口号(默认3306) master_user :用于数据同步的用户 master_password :用于同步的用户的密码 master_log_file :指定 Slave 从哪一个日志文件开始复制数据,即上文中提到的 File 字段的值 master_log_pos :从哪一个 Position 开始读,即上文中提到的 Position 字段的值
使用start slave
命令开启主从复制过程
start slave; -- 顺便提供下其它命令 stop slave 中止slave。reset slave重启slave。 reset master重启master。
启动以后咱们来看下有没有成功。
show slave status
命令
从这张图很明显看出,对于Slave的两个线程都成功了,那就说明整个MYSQL主从搭建成功了。若是有一个为NO,那就须要到后面看错误日志,是什么缘由出错了,解决下就行了。
Slave_IO_Running: 从服务器中I/O线程的运行状态,YES为运行正常 Slave_SQL_Running: 从服务器中SQL线程的运行状态,YES为运行正常
这里简单作一个测试
如今 只在Mater 建立一张User表
,若是如今Slave也一样生成这张User表,那就说明成功了。
CREATE TABLE `user` ( `id` bigint NOT NULL COMMENT '主键', `user_name` varchar(11) NOT NULL COMMENT '用户名', `password` varchar(11) NOT NULL COMMENT '密码', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户表';
实际测试结果是成功的。
注意
这里若是咱们先手动在Slave建立这张User表,而后再到Master建立User表那就出事情了。咱们按照上面的步骤建立完后,去Slave经过 show slave status
查看
发现 SQL线程都变NO了。缘由很简单,错误日志也说明了(Error 'Table 'user' already exists')。由于你在Master建立User表的SQL会记录到bin-log日志中,而后Slave
去读取这个操做,而后写入Slave中的时后发现这个SQL执行失败,由于你Slave已经存在该User表,而后这整个主从复制就卡在这里了。这是个很严重的问题。
因此一旦搭建主从复制成功,只要在Master作更新事件(update、insert、delete),不要在从数据作,不然会出现数据不一致甚至同步失败。
INSERT INTO `user` (`id`, `user_name`, `password`, `create_time`) VALUES (0, '张三', '123456', '2020-11-25 04:29:43');
再去Slave数据库查看
发现从数据库已经写入成功了。
总结
:在搭建的过程可能还有其它的问题出现 你只要在Slave服务器,经过show slave status,若是两个IO是否为YES就表明是否成功,若是有为NO的,
后面有字段说明是什么缘由致使的,你再根据相关错误信息去查询下解决方案,那就能够了。
别人骂我胖,我会生气,由于我内心认可了我胖。别人说我矮,我就会以为可笑,由于我内心知道我不可能矮。这就是咱们为何会对别人的攻击生气。 攻我盾者,乃我心里之矛(33)