Docker 部署 MySQL 主备架构
docker 镜像为
8.0.24
,MySQL 版本为 8.0.24,若无法拉取可以用我这个docker pull registry.cn-shanghai.aliyuncs.com/hhu/mysql:wgl_8.0.24
部署 master 和 slave,可以顺次扩展 slave,流程如下:
# 部署 master
docker run --name mysql-master --privileged=true -v D:\tmp\docker\mysql\master\data:/var/lib/mysql -v D:\tmp\docker\mysql\master\conf\my.cnf:/etc/mysql/my.cnf -v D:\tmp\docker\mysql\master\mysql-files:/var/lib/mysql-files -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql
# 部署 slave
docker run --name mysql-slave1 --privileged=true -v D:\tmp\docker\mysql\slave1\data:/var/lib/mysql -v D:\tmp\docker\mysql\slave1\conf\my.cnf:/etc/mysql/my.cnf -v D:\tmp\docker\mysql\master\mysql-files:/var/lib/mysql-files -p 3308:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=root -d mysql
上述参数做如下说明:
--name
:指定运行之后的容器的名称为mysql-master;--privileged
:指定了当前容器是否真正的具有root权限,所谓的root权限是指具有宿主机的root权限,而不仅仅只是在容器内部有root权限;-v
:指定了容器中指定目录挂载到宿主机上的某个目录,这样做的目的在于防止容器中配置的数据丢失,因为docker容器在重启之后是不会保留前一次在其内部运行的相关数据的;-v D:\tmp\docker\mysql\master\data:/var/lib/mysql
:挂载mysql的data目录,作外部持久化;-v D:\tmp\docker\mysql\master\conf\my.cnf:/etc/mysql/my.cnf
:挂载mysql的配置文件,当然如果是我们自己打的包就不用了,因为像这种配置文件完全调好后直接打包到镜像中;-v D:\tmp\docker\mysql\master\mysql-files:/var/lib/mysql-files
:正常不需要挂载,在启动出现异常Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
,此时需要额外挂载mysql-files
目录;
-p
:表示宿主机上的某个端口映射到docker容器内的某个端口,这里也就是将宿主机的3307、3308端口映射到容器内部的3306端口;-e
:表示指定当前容器运行的环境变量,该变量一般在容器内部程序的配置文件中使用,而在外部运行容器指定该参数。这里的MYSQL_ROOT_PASSWORD表示容器内部的MySQL的启动密码;-d
:参数指定了当前容器是在后台运行;--link
:用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量;
正常启动后,进入 master 和 slave 各个容器,登录 MySQL,发现提示异常:[Warning] World-writable config file '/etc/mysql/my.cnf' is ignored
,这是因为我们挂载的配置文件是全局可写的,MySQL Server 不认可,此时我们改一下挂载的配置文件读写权限即可,我这里是win10,直接右击文件D:\tmp\docker\mysql\master\conf\my.cnf
修改 属性 -> 属性 -> 只读 即可,重启上述容器docker restart mysql-master
、docker restart mysql-slave
即可。
配置主备同步:
# 登录 mysql
mysql -uroot -p
# 查询master的binlog日志信息
show master status;
# 在各个slave上配置master的连接信息,master_file和master_Position就是上面插叙的结果
change master to master_host='master', master_user='root', master_password='root', master_port=3306, master_log_file='[master_file]', master_log_pos=[master_Position], master_connect_retry=30;
# 在各个备库上开启主备复制
start slave;
# 查看开启状态,只要看到两个参数Slave_IO_Running和Slave_SQL_Running都为YES,则表示复制是正常进行的
show slave status;
若start slave
执行失败出现ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
,重置一下该slave即可reset slave
,然后再执行start slave
。
附:
主备的配置文件如下(备库自己修改server-id):
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录
#basedir=D:\Program Files\MySQL\mysql-8.0.20
# 设置mysql数据库的数据的存放目录
#datadir=D:\Program Files\MySQL\mysql-8.0.20\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# binlog配置
# 开启binlog,指定basefileName
# mysql会在baseName后面追加数值来生成新的binlog日志,在服务启动或重启、flush日志、当前日志文件达到max_binlog_size的值都会生成新的日志文件
log-bin=mysql-binlog
# 和log-bin类似,但可以指定路径,实测未生效
#log_bin_basename=D:\Program Files\MySQL\mysql-8.0.20\data\logs\binlog\
# 默认为 log-bin 后面追加 .index,可以不设
log-bin-index=mysql-binlog.index
# binlog模式设置为row
binlog-format=ROW
# 单个binlog文件的大小,单位字节,默认1073741824(即1G),但不是绝对的,binlog在记录事务时,是不会将一个事务进行分割的,总是以一个整体的形式来记录
max_binlog_size=1073741824
# 8.0以下版本必须在开启binlog时必设,8.0及以上默认为1,但不显式设置,虽可以启动但会出现提示信息
server_id=1