一、实验背景
Docker 是一个开源的引擎,可以轻松的为任何应用创建一个轻量级、可移植、自给自足的容器。
Docker 通常用于如下场景:
web 应用的自动化打包发布
自动化测试和持续集成、发布
在服务性环境中部署和调整数据库或其他的后台应用
Docker 是一种新型的虚拟化方式,和传统的的虚拟化方式相比具有以下优势:
Docker 容器的启动可以在秒级实现,这比传统的的虚拟机方式要快很多。
Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
本文主要讲解docker的安装和MySQL 的主从复制的搭建,Docker 的具体使用可以去找相关的书籍或其他资料自行进行学习,本文就不涉及 Docker 的具体命令的讲解了。
本文分成以下几步来说明如何基于 Docker 来搭建 MySQL 的主从复制:
准备两台 MySQL 服务器
配置主服务器(Master)
配置从服务器(Slave)
完成Master和Slave链接
测试配置是否成功
二、MySQL主从复制原理
主服务器数据库的每次操作都会记录在其二进制文件mysql-bin.xxx(该文件可以在mysql目录下的data目录中看到)中,从服务器的I/O线程使用专用账号登录到主服务器中读取该二进制文件,并将文件内容写入到自己本地的中继日志relay-log文件中,然后从服务器的SQL线程会根据中继日志中的内容执行SQL语句。
MySQL主从同步的作用:
1、可以作为备份机制,相当于热备份
2、可以用来做读写分离,均衡数据库负载
三、实验环境
操作系统: CentOS7.x
MySQL01(master):192..168.1.103
MySQL02(slave): 192.168.1.105
Docker版本:18.06
MySQL镜像版本:5.7.20
四、安装docker,拉取MySQL镜像
在MySQL01、MySQL02服务器
关闭selinux
# setenforce 0
# sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
开放相关端口
# firewall-cmd --zone=public --add-port=3306/tcp --permanent
# firewall-cmd --reload
安装docker
# yum -y install yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum list docker-ce --showduplicates | sort -r
# yum -y install docker-ce-18.06.0.ce
# systemctl start docker
# systemctl status docker
# systemctl enable docker
# docker version
设置镜像加速
# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
# systemctl restart docker
拉取MySQL5.7.x镜像
# docker pull mysql:5.7.20
# docker images
# docker run -it --rm mysql:5.7.20 cat /etc/issue
# docker run -it --rm mysql:5.7.20 cat /etc/passwd
五、安装配置MySQL01
在MySQL01服务器
创建配置文件和数据文件目录
# mkdir /opt/mysqldata
# mkdir /opt/mysqlconfig
创建配置文件
# vim /opt/mysqlconfig/mysqld.cnf
#################################################
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
symbolic-links = 0
max_connections = 1000
server_id = 100
log-bin = mysql-bin
binlog_cache_size = 1M
binlog_format = mixed
expire_logs_days = 7
log_bin_trust_function_creators = 1
# GTID
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
#################################################
# chown 999:999 /opt/mysqlconfig/mysqld.cnf
注意:/opt/mysqlconfig/mysqld.cnf如果属主属组为root,那么权限要求为644,如果属组属主uid为999(容器中mysql用户的uid),文件权限可以为644或者640,否则用镜像起MySQL容器,无法读取自定义的挂载配置文件!
初始化MySQL
# docker run -d \
--name mysql \
-p 3306:3306 \
-e UMASK=0600 \
-e UMASK_DIR=0700 \
-e MYSQL_HISTFILE=/dev/null \
-e MYSQL_ROOT_PASSWORD="MySQL@123" \
-v /opt/mysqldata:/var/lib/mysql \
-v /opt/mysqlconfig/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
mysql:5.7.20
# docker ps -a
# ll /opt/mysqldata
可以看出,生成了MySQL初始化数据,我们后续会用到相关数据,如设置的初始密码。
关于MySQL配置调优,大家可以根据自己的实际应用去编辑mysqld.cnf。
将MySQL注册成系统服务
删掉初始化容器
# docker stop mysql
# docker rm mysql
创建MySQL的systemd Unit文件
# vim /etc/systemd/system/mysqld.service
#######################################################
[Unit]
Description=MySQL Server
After=network-online.target docker.service
Requires=docker.service
[Service]
ExecStartPre=-/usr/bin/docker rm -f mysql
ExecStart=/usr/bin/docker run \
--name mysql \
-p 192.168.1.103:3306:3306 \
-e UMASK=0600 \
-e UMASK_DIR=0700 \
-e MYSQL_HISTFILE=/dev/null \
-v /opt/mysqldata:/var/lib/mysql \
-v /opt/mysqlconfig/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
mysql:5.7.20
ExecStop=/usr/bin/docker stop mysql
LimitNOFILE=65535
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
########################################################
# systemctl daemon-reload
# systemctl start mysqld.service
# systemctl enable mysqld.service
# systemctl status mysqld.service
# docker ps -a
# docker logs mysql
五、安装配置MySQL02
在MySQL02服务器
创建配置文件和数据文件目录
# mkdir /opt/mysqldata
# mkdir /opt/mysqlconfig
创建配置文件
# vim /opt/mysqlconfig/mysqld.cnf
##########################################################
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
symbolic-links = 0
max_connections = 1000
server_id = 200
log-bin = mysql-bin
binlog_cache_size = 1M
binlog_format = mixed
expire_logs_days = 7
log_bin_trust_function_creators = 1
read_only = 1
# GTID
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
#####################################################
# chown 999:999 /opt/mysqlconfig/mysqld.cnf
注意:/opt/mysqlconfig/mysqld.cnf如果属主属组为root,那么权限要求为644,如果属组属主uid为999(容器中mysql用户的uid),文件权限可以为644或者640,否则用镜像起MySQL容器,无法读取自定义的挂载配置文件!
初始化MySQL
# docker run -d \
--name mysql \
-p 3306:3306 \
-e UMASK=0600 \
-e UMASK_DIR=0700 \
-e MYSQL_HISTFILE=/dev/null \
-e MYSQL_ROOT_PASSWORD="MySQL@123" \
-v /opt/mysqldata:/var/lib/mysql \
-v /opt/mysqlconfig/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
mysql:5.7.20
# docker ps -a
# ll /opt/mysqldata
可以看出,生成了MySQL初始化数据,我们后续会用到相关数据,如设置的初始密码。
关于MySQL配置调优,大家可以根据自己的实际应用去编辑mysqld.cnf。
将MySQL注册成系统服务
删掉初始化容器
# docker stop mysql
# docker rm mysql
创建MySQL的systemd Unit文件
# vim /etc/systemd/system/mysqld.service
#######################################################
[Unit]
Description=MySQL Server
After=network-online.target docker.service
Requires=docker.service
[Service]
ExecStartPre=-/usr/bin/docker rm -f mysql
ExecStart=/usr/bin/docker run \
--name mysql \
-p 192.168.1.105:3306:3306 \
-e UMASK=0600 \
-e UMASK_DIR=0700 \
-e MYSQL_HISTFILE=/dev/null \
-v /opt/mysqldata:/var/lib/mysql \
-v /opt/mysqlconfig/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
mysql:5.7.20
ExecStop=/usr/bin/docker stop mysql
LimitNOFILE=65535
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
########################################################
# systemctl daemon-reload
# systemctl start mysqld.service
# systemctl enable mysqld.service
# systemctl status mysqld.service
# docker ps -a
# docker logs mysql
六、配置MySQL01 MySQL02 主从
在MySQL01服务器
创建主从复制账号
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "CREATE USER 'repl'@'127.0.0.1' IDENTIFIED BY 'Repl@123';"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "CREATE USER 'repl'@'192.168.1.105' IDENTIFIED BY 'Repl@123';"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'192.168.1.105';"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "select user,host from mysql.user;"
初始化MySQL master slave状态
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "reset master;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "reset slave;"
在MySQL02服务器
初始化MySQL master slave状态
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "reset master;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "reset slave;"
开启主从同步
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "change master to master_host='192.168.1.103',master_port=3306,master_user='repl',master_password='Repl@123',master_auto_position=1;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "start slave;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "show slave status;"
七、测试主从效果
在MySQL01服务器
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8 COLLATE utf8_general_ci;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "grant all privileges on test.* to 'test'@'%' IDENTIFIED BY 'Test@123';"
在MySQL02服务器
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "select user,host from mysql.user;"
# docker exec -it mysql mysql -u root -p"MySQL@123" -e "show databases;"
七、参考
MySQL主从配置详解
https://www.jianshu.com/p/b0cf461451fb
基于 Docker 的 MySQL 主从复制搭建
https://www.jianshu.com/p/ab20e835a73f
CentOS7.x上容器部署MySQL
https://www.jianshu.com/p/c74b1d2d8ad4
MySQL 查看最大连接数和修改最大连接数
https://www.cnblogs.com/aaronguo/p/8412800.html
解决MySQL使用GTID主从复制错误问题
https://blog.csdn.net/fujiakai/article/details/82700457