Docker实现Mysql主从复制实战(一主一从、双主双从)
---------------------------------目录----------------------------------
前期扯淡:mysql主从复制和集群区别
一、 Mysql数据库主从复制一主一从
二、 Mysql数据库主从复制双主双从
-----------------------------------------------------------------------
哈哈!欢迎你的到来,俗话说磨刀不误砍柴工,来吧,咱们先看看Mysql的主从复制和集群概念的区别。
MySQL集群是一个无共享的(shared-nothing)、分布式节点架构的存储方案,其目的是提供容错性和高性能。
集群所涉及到的三个概念:
SQL节点(多个):应用程序和数据节点的一个桥梁,应用程序不能直接访问数据节点,只能先访问SQL节点,然后SQL节点再去访问数据节点来返回数据,Cluster中可以有多个SQL节点,通过每个SQL节点查询到的数据都是一致的,一般来说,SQL节点越多,分配到每个SQL节点的负载就越小,系统的整体性能就越好;
数据节点(多个):用于存储数据,数据存放内存中,数据节点中数据保存后自动复制并存储到其他节点,数据节点之间采用的是同步复制来保证各节点之间的数据一致性
管理节点(一个):主要负责管理数据节点和SQL节点,还有集群配置文件和集群日志文件。它监控其他节点的工作状态,能够启动、关闭或者重启某个节点。其他节点从管理节点检索配置数据,当数据节点有新事件就把事件信心发送给管理节点并写入集群日志。
同步复制流程:
a) Master执行提交语句时,事务被发送到Slave,Slave开始准备事务的提交。
b) 每个slave都要准备事务,然后向Master发送OK(或ABORT)消息,表明事务已经准备好(或者无法准备该事务)。
c) Master等待所有Slave发送OK或ABORT消息,如果Master收到所有Slave的OK消息,它就会向所有Slave发送提交消息,告诉Slave提交该事务;如果 Master收到来自任何一个Slave的ABORT消息,它就向所有 Slave发送ABORT消息,告诉Slave去中止事务。
e) 每个Slave等待来自Master的OK或ABORT消息。如果Slave收到提交请求,它们就会提交事务,并向Master发送事务已提交 的确认;如果Slave收到取消请求,它们就会撤销所有改变并释放所占有的资源,从而中止事务,然后向Masterv送事务已中止的确认。
f) Master收到来自所有Slave的确认后,就会报告该事务被提交(或中止),然后继续进行下一个事务处理。
由于同步复制一共需要4次消息传递,故mysql cluster的数据更新速度比单机mysql要慢。所以mysql cluster要求运行在千兆以上的局域网内,节点可以采用双网卡,节点组之间采用直连方式。
主从复制是通过Mysql的Replication来保证数据的一致性。相对Mysql Cluster的异步数据同步方式。
Replication:首先主从服务器必须设置一个唯一的服务器id(局域网内唯一);其中主节点要开启binlog日志功能,binlog记录了master上的所有操作,同时也会被复制到从节点的Relaylog上,并在从节点上binlog回放执行。操作流程入下图所示:
主从复制的日志记录类型
基于SQL语句的复制(statement):在Master上执行的SQL语句,在Slave根据主机系统时间去执行同样的语句。SQL执行同步根据系统时间来确定,MySQL默认采用基于语句的复制,效率比较高。弊端:SQL在主机执行和从机执行时间不一致,导致数据不一致。
基于行的复制(row):把改变的数据内容复制到Slave,而不是把命令在Slave上执行一遍。从MySQL5.0开始支持。弊端:如果执行一天update语句,影响1000万行,那么需要在从库执行1000万次,效率太低。
混合类型的复制(mixed):默认采用基于SQL语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。弊端:是不能识别@@host name 系统变量,同时每太主机的系统变量都不一致导致数据不一致。
一、 Mysql数据库主从复制一主一从
1、拉取镜像
登录docker 镜像官网搜索mysql,找到制定的版本拉去,这里使用mysql5.7.30,版本查找文档:Linux Centos7(Mac) 安装Docker教程
docker pull mysql:5.7.30
2、查看docker的镜像
docker images
3、创建容器本地映射文件,目的持久化数据。
master文件夹与文件准备,my.cnf文件重点关注属性server_id、log_bin、binlog_format、binlog_do_db、binlog_ignore_db.
mkdir -p /root/mysql/master/data /root/mysql/master/logs /root/mysql/master/conf touch /root/mysql/master/conf/my.cnf
在主节点的my.cnf配置文件中添加一下内容
[mysqld] server_id = 1 # 唯一标识,主库从库不能重复 log_bin = mysql-bin # 开启日志 binlog_format=STATEMENT # 日志记录的格式类型 # max_binlog_size = 512M # 单个日志文件最大 # # expire_logs_day = 3 # 日志有效期(天) # # binlog_do_db = test1,test2 # 日志记录(同步复制)那些数据库 # # binlog_ignore_db = mysql,performance_schema,information_schema # 日志记录忽略那些数据库的
slave文件夹与文件准备
mkdir -p /root/mysql/slave/data /root/mysql/slave/logs /root/mysql/slave/conf touch /root/mysql/slave/conf/my.cnf
在slave的my.cnf文件写入下面配置
[mysqld] server_id = 2 # 数据库唯一id,内网唯一 log_bin = mysql-bin # 开启日志,如果从库还会用做主库,建议配置 binlog_format=STATEMENT # 日志记录的格式类型 # max_binlog_size = 512M # 单个日志文件最大 # # expire_logs_day = 3 # 日志有效期(天) # # replicate_do_db = test1,test2 # 是在slave上配置,指定slave要复制哪个库 # # replicate-ignore-db=mysql,performance_schema,information_schema # 是在slave上配置,指定slave要忽略哪个库 # relay_log_recovery = 1 # 从库建议开启,有利于数据一致性 # log_slave_updates = 1 # 如果从库还会用做主库,建议开启
4、创建master主机容器,启动服务。
首先创建容器并启动:
docker run -p 3306:3306 --name mysqlMaster \ -v /root/mysql/master/conf:/etc/mysql/conf.d \ -v /root/mysql/master/logs:/var/log/mysql \ -v /root/mysql/master/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.30
然后查看是否启动 docker ps:
接着登录master节点容器:
docker exec -it mysqlMaster /bin/bash
同时在master容器中执行以下SQL,创建用户授权,四步完成:登录mysql、创建用户、账号授权、刷新动态生效。mysql-管理命令【创建用户、授权、修改密码、删除用户和授权、忘记root密码】
mysql -uroot -proot
CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; GRANT ALL ON *.* TO 'slave'@'%';
GRANT ALL ON *.* TO 'slave'@'%';
flush privileges;
最后查看master的数据库状态,File 是记录的二进制文件名,Position偏移位置,从库会用到。还有需要复制的数据库和不需要忽略的数据库
show master status;
另开一个远程连接窗口,查看master容器ip地址,从库会用到:
docker inspect mysqlMaster|grep IPAddress
5、创建slave主机容器、并启动(注意本地防火墙哦!)
汇总master节点信息
然后启动创建slave库的容器并启动:
docker run -p 3305:3306 --name mysqlSlave \ -v /root/mysql/slave/conf:/etc/mysql/conf.d \ -v /root/mysql/slave/logs:/var/log/mysql \ -v /root/mysql/slave/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.30
登录从库容器
docker exec -it mysqlSlave /bin/bash
登录从库mysql服务器
mysql -uroot -proot
在slave从库中进行配置从库主从信息,如下命令为解释,操作如下图
change master to 开启配置主从信息 -> master_host='172.18.0.2', 指定主节点ip -> master_port=3306, 指定主节点端口 -> master_user='slave', 登录主节点拉去二进制文件的用户名 -> master_password='123456', 用户密码 -> master_log_file='mysql-bin.000001', 二进制文件名,对应File字段 -> master_log_pos=154; 二进制偏移位置对应Position偏移位置
启动slave线程,如果配置错误输入stop slave; 然后重新录入一遍上一步命令
start slave;
查看salve数据库状态,如果
show slave status \G;
6主从验证
在主库创建数据库
CREATE SCHEMA `test1` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ;
在从库中查看:
二、 Mysql数据库主从复制双主双从
双主双从主要是my.cof配置和双主复制的命令不同,mysql默认的自增开始和自增的步长不同
master节点1的配置
[mysqld] server-id=1 log-bin=mysql-bin
#binlog-do-db指定同步的库名,建议使用binlog-ignore-db忽略某些库 binlog-do-db=mycat_m_s binlog_format=STATEMEN log-slave-updates auto-increment-increment=2 auto-increment-offset=1
master节点2配置
[mysqld] server-id=3 log-bin=mysql-bin
#binlog-do-db指定同步的库名,建议使用binlog-ignore-db忽略某些库
binlog-do-db=mycat_m_s
binlog_format=STATEMEN
log-slave-updates
auto-increment-increment=2
auto-increment-offset=2
双主复制的命令
#主机2复制主机1命令 change master to master_host='192.168.220.102', master_port=3307, master_user='slave', master_password='123456', master_log_file='mysql-bin.000005', master_log_pos=333, master_connect_retry=60; #主机1复制主机2命令 change master to master_host='192.168.220.102', master_port=3309, master_user='slave', master_password='123456', master_log_file='mysql-bin.000002', master_log_pos=443, master_connect_retry=60;
然后启动主库的从库
start slave
具体操作参看这位大佬的记录吧:Docker安装Mysql,并搭建一主一从复制集群,一主双从,双主双从集群
Docker(部署常见应用):Docker安装MySql完整教程、实操
Docker实现Mysql主从复制实战(一主一从、双主双从)
mysql 5.8以上版本有问题可以参考: