docker部署MySQL5.7主从复制
前言
本文将以MySQL5.7版本来讲MySQL 主从复制的原理以及在Docker环境中如何实现主从复制。
Mysql复制的优点
如果主库出现问题,可以快速切换到从库提供服务
可以在从库执行查询操作,降低主库的访问压力。
可以在从库进行备份,以免备份期间影响主库的服务。
Mysql复制解决的问题
数据分布 (Data distribution )
负载平衡(load balancing)
数据备份(Backups) ,保证数据安全
高可用性和容错行(High availability and failover)
实现读写分离,缓解数据库压力
主从复制的模式:
mysql默认模式为异步模式:主库在更新完事务之后会立即把结果返回给从服务器,并不关心从库是否接收到以及从库是否处理成功。缺点:网络问题没有同步、防火墙的等因素导致同步失败。优点:快,效率高。
全同步模式:主库在更新完事务之后,立即把结果返回到从库,所有的从库执行完毕之后才能继续下一个同步。优点:安全。缺点:性能受到影响。
半同步模式:介乎于异步和全同步之间,主库更新完事务之后,也是同步到从库,同步完成之后有一个等待时间,等待时间是tcp/ip的往返时间,一般为5毫秒左右。即在一定程度上保证了效率,也在一定程度上保证了数据的完整性。
MySQL 主从复制的主要用途
①读写分离
在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
② 数据实时备份
当系统中某个节点发生故障时,可以方便的故障切换(主从切换),提高数据安全-因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据;
③高可用(HA)
因为数据库服务器中的数据都是相同的,当Master挂掉后,可以指定一台Slave充当Master继续保证服务的运行,因为数据是一致性的(如果当插入时Master就挂掉,可能不一致,因为同步也需要时间)当然这种配置不是简单的把一台Slave充当Master,毕竟还要考虑后续的Slave的数据同步到Master。在主服务器上执行写入和更新,在从服务器上向外提供读功能,达到读写分离的效果,也可以动态地调整从服务器的数量,从而调整整个数据库的性能。在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能。
④架构扩展
随着系统中业务访问量的增大,如果是单机部署数据库,就会导致I/O访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单机磁盘I/O访问的频率,提高单个机器的I/O性能。
实验
Master节点配置
1、拉镜像
docker pull mysql:5.7.32
2、建目录
mkdir -p /opt/mysql-master/log/ opt/mysql-master/data /opt/mysql-master/conf
3、写配置文件
cd /opt/mysql-master/conf
vim my.cnf
-----------------------------------------------------
[mysql]
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
[mysqld]
#lower_case_table_names=0,表示区分大小写,创建的库表会原样大小写保存在磁盘上
#lower_case_table_names=1,表示不区分大小写,创建库表时MySQL会将所有的库表名转换成小写字母保存在磁盘上
#且SQL语句中涉及到库表无论写成大写或者小写,都会被转化成小写进行查询和写入
lower_case_table_names=1
#mysql运行的端口
port=3306
#mysql5.7以后的不兼容问题处理
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#打开log-bin日志
log-bin=mysql-bin
#存放数据的路径
datadir=/var/lib/mysql
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
#是否支持符号连接,即数据库或表能够存储在my.cnf
#中指定datadir以外的分区或目录,为0不开启
symbolic-links=0
#mysql服务器分配的ID,在启用主从和集群的时候必须指定,并且不能重复
server-id = 1
#要给从机同步的库
#binlog-do-db=hl
#不给从机同步的库(这里不同步mysql、information_schema,performance_schema、sys库)
#binlog-ignore-db=mysql
#binlog-ignore-db=information_schema
#binlog-ignore-db=performance_schema
#binlog-ignore-db=sys
#mysql允许最大连接数
max_connections=2000
#默认字符集
character-set-server=utf8
#默认存储引擎
default-storage-engine=INNODB
#mysql最大接受的数据包大小
max_allowed_packet=16M
#日志自动过时清理天数
expire_logs_days = 90
#事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败;参数的时间单位是秒
innodb_lock_wait_timeout=120
#设置时区
default-time_zone='+8:00'
[mysqld_safe]
#进程ID文件
pid-file=/data/var/mysql/mysqld.pid
#错误日志纪录位置
log-error=/var/log/mysqld.log
----------转换-------
yum install dos2unix
dos2unix my.cnf
4、创建容器,将数据,日志,配置文件映射到本机
docker run --name=mysql-master \
-p 3306:3306 \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /opt/mysql-master/logs:/logs \
-v /opt/mysql-master/data:/var/lib/mysql \
-v /opt/mysql-master/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7.32
说明
-d 后台运行容器
-p 将容器的端口映射到本机的端口
-v 将主机目录挂载到容器的目录
-e 设置参数
登录容器
docker ps -a
docker exec -it fa1d66741082 /bin/bash
使用容器IP登录
docker inspect mysql-master
mysql -uroot -h172.17.0.2 -proot
-------------
///////// 安装mariadb
yum install mariadb-server mariadb -y
#启动MariaDB systemctl start mariadb
#设置开机启动 systemctl enable mariadb
查看mysql数据库密码
docker exec -it fa1d66741082 env
查看my.cnf文件是否映射到容器
docker exec -it fa1d66741082 /bin/bash
cd /etc/mysql/mysql.conf.d
cat mysqld.cnf
容器外文件位置
cat /etc/mysql/mysql.conf.d/my.cnf
Slave节点配置
1、建目录
mkdir -p /opt/mysql-slave/log/ opt/mysql-slave/data /opt/mysql-slave/conf
2、写配置文件
cd /opt/mysql-slave/conf
vim my.cnf
------------------------------------------------------yum install dos2unix-----------
[mysql]
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
[mysqld]
#lower_case_table_names=0,表示区分大小写,创建的库表会原样大小写保存在磁盘上
#lower_case_table_names=1,表示不区分大小写,创建库表时MySQL会将所有的库表名转换成小写字母保存在磁盘上
#且SQL语句中涉及到库表无论写成大写或者小写,都会被转化成小写进行查询和写入
lower_case_table_names=1
#mysql运行的端口
port=3306
#mysql5.7以后的不兼容问题处理
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#打开log-bin日志
#log-bin=mysql-bin
#存放数据的路径
datadir=/var/lib/mysql
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
#是否支持符号连接,即数据库或表能够存储在my.cnf
#中指定datadir以外的分区或目录,为0不开启
symbolic-links=0
#mysql服务器分配的ID,在启用主从和集群的时候必须指定,并且不能重复
server-id = 2
#要给从机同步的库
#binlog-do-db=hl
#不给从机同步的库(这里不同步mysql、information_schema,performance_schema、sys库)
#binlog-ignore-db=mysql
#binlog-ignore-db=information_schema
#binlog-ignore-db=performance_schema
#binlog-ignore-db=sys
#mysql允许最大连接数
max_connections=2000
#默认字符集
character-set-server=utf8
#默认存储引擎
default-storage-engine=INNODB
#mysql最大接受的数据包大小
max_allowed_packet=16M
#日志自动过时清理天数
expire_logs_days = 90
#事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败;参数的时间单位是秒
innodb_lock_wait_timeout=120
#设置时区
default-time_zone='+8:00'
[mysqld_safe]
#进程ID文件
pid-file=/data/var/mysql/mysqld.pid
#错误日志纪录位置
log-error=/var/log/mysqld.log
----------转换-----------
dos2unix my.cnf
4、创建容器,将数据,日志,配置文件映射到本机
docker run --name=mysql-slave \
-p 3307:3306 \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /opt/mysql-slave/logs:/logs \
-v /opt/mysql-slave/data:/var/lib/mysql \
-v /opt/mysql-slave/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7.32
说明
-d 后台运行容器
-p 将容器的端口映射到本机的端口
-v 将主机目录挂载到容器的目录
-e 设置参数
登录容器
docker ps -a
docker exec -it b4cf79a9db51 /bin/bash
使用容器IP登录
docker inspect mysql-slave
mysql -uroot -h172.17.0.3 -proot
授权用户
master节点授权
CREATE USER 'slave'@'%' IDENTIFIED BY 'root';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;
查看MySQL master状态
SHOW MASTER STATUS;
mysql-bin.000003 | 762
测试通信
在slave查看是否能与master节点通信
docker ps -a
docker exec -it b4cf79a9db51 /bin/bash
测试是否通信,不报错说明就正常
echo > /dev/tcp/172.17.0.2/3306
重启容器
docker restart b4cf79a9db51 fa1d66741082
SHOW MASTER STATUS;
mysql-bin.000004 | 154
slave节点配置
登录数据库后从节点配置
mysql -uroot -h172.17.0.3 -proot
---------------------------------------------------
CHANGE MASTER TO master_host = '192.168.80.28',\
master_user = 'slave',\
master_password = 'root',\
master_port = 3306,\
master_log_file = 'mysql-bin.000004',\
master_log_pos = 154,\
master_connect_retry = 30;
-----------------------------------------------
查看未启动slave服务状态
show slave status \G;
在slave节点启动slave功能
START SLAVE;
show slave status \G;
如果中途报错,之类的,可以使用reset slave进行从服务器重置
reset slave;
数据测试
master主节点创建库表
mysql -uroot -h172.17.0.2 -proot
-----------------------------------------------------
新建测试库
create database yangyang;
use yangyang;
创建一个my_user表
CREATE TABLE `my_user` (
`id` tinyint(4) NOT NULL AUTO_INCREMENT,
`account` varchar(255) DEFAULT NULL,
`passwd` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
插入数据
INSERT INTO `my_user` VALUES ('1','admin','admin');
INSERT INTO `my_user` VALUES ('2','pu','12345');
INSERT INTO `my_user` VALUES ('3','system','system');
INSERT INTO `my_user` VALUES ('4','zxh','zxh');
INSERT INTO `my_user` VALUES ('5','test','test');
INSERT INTO `my_user` VALUES ('6','pudong','pudong');
INSERT INTO `my_user` VALUES ('7','qiqi','qiqi');
------------------------------------------------------------------
slave节点查看
mysql -uroot -h172.17.0.3 -proot
select * from yangyang.my_user;
查看数据正常复制,说明测试正常