docker搭建mysql8.0.32,实现主从复制(一主两从)

安装docker的步骤、使用命令就不写了,本文章是基于会使用docker、linux基本命令的基础上来写的。

开始步骤:

  1. 拉取 mysql 镜像
bash 复制代码
docker pull mysql:8.0.32
  1. 启动容器并运行mysql

a. 准备mysql的配置文件(该配置文件是:mysql:8.0.32直接启动后的翻译过后的原始配置文件)

bash 复制代码
# 关于如何更改设置的建议,请参考
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html

[mysqld]
#
# 去掉前导的 #,并设置用于 MySQL 中最重要的数据缓存的内存量。
# 对于专用服务器,从总内存开始设置为 70%,否则为 10%。
# innodb_buffer_pool_size = 128M
#
# 去掉前导的 # 以启用一个非常重要的数据完整性选项:在备份之间记录
# 二进制日志中的更改。
# log_bin
#
# 去掉前导的 # 以设置主要用于报告服务器的选项。
# 对于事务和快速 SELECT,默认值更快。
# 根据需要调整大小,尝试找到最佳值。
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

# 去掉前导的 # 以恢复到先前的 default_authentication_plugin 值,
# 这将提高与旧客户端的兼容性。有关背景信息,请参阅:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
# default-authentication-plugin=mysql_native_password
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid

[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/

重点:++将配置文件在计算机本地创建好,后面会用来挂载到docker里的mysql的my.cnf 文件++

++只需要在本地创建 3个 my.cnf 文件,复制上面的内容 ,再分别在文中任意位置,最好放当中 添加 server_id=100、server_id=101、server_id=102 属性即可(没有顺序,值也可以是1、2、3任意的,不同就行,作用只是标记启动的不同数据库拥有不同的id,如果3个数据库不在一个服务器上就不需要添加这个配置了)。++

bash 复制代码
下面是挂载的内容解释:

-- 启动一个mysql将数据挂载到本地目录:/Users/wangqinmin/docker/mysql/master_slave/master_data 
-- 配置文件挂载到,mysql8.0.32的my.cnf文件位置在/etc/my.cnf:/Users/wangqinmin/docker/mysql/master_slave/conf/master_conf/my.cnf:/etc/my.cnf
-- 日志文件挂载到:/Users/wangqinmin/docker/mysql/master_slave/log/master_log:/var/log/mysql
-- SELECT ... INTO OUTFILE 操作导出的文件挂载到:/Users/wangqinmin/docker/mysql/master_slave/file/mysql-files

b. 写好命令,开始执行

bash 复制代码
docker run --name mysql_master_33066 -v /Users/wangqinmin/docker/mysql/master_slave/data/master_data:/var/lib/mysql -v /Users/wangqinmin/docker/mysql/master_slave/conf/master_conf/my.cnf:/etc/my.cnf -v /Users/wangqinmin/docker/mysql/master_slave/log/master_log:/var/log/mysql -v /Users/wangqinmin/docker/mysql/master_slave/file/mysql-files:/var/lib/mysql-files -p 33066:3306 -e MYSQL_ROOT_PASSWORD=wangqinmin -d mysql:8.0.32

docker run --name mysql_slave_33067 -v /Users/wangqinmin/docker/mysql/master_slave/data/slave1_data:/var/lib/mysql -v /Users/wangqinmin/docker/mysql/master_slave/conf/slave1_conf/my.cnf:/etc/my.cnf -v /Users/wangqinmin/docker/mysql/master_slave/log/slave1_log:/var/log/mysql -v /Users/wangqinmin/docker/mysql/master_slave/file/mysql_files_slave1:/var/lib/mysql-files -p 33067:3306 -e MYSQL_ROOT_PASSWORD=wangqinmin -d mysql:8.0.32

docker run --name mysql_slave_33068 -v /Users/wangqinmin/docker/mysql/master_slave/data/slave2_data:/var/lib/mysql -v /Users/wangqinmin/docker/mysql/master_slave/conf/slave2_conf/my.cnf:/etc/my.cnf -v /Users/wangqinmin/docker/mysql/master_slave/log/slave2_log:/var/log/mysql -v /Users/wangqinmin/docker/mysql/master_slave/file/mysql_files_slave2:/var/lib/mysql-files -p 33068:3306 -e MYSQL_ROOT_PASSWORD=wangqinmin -d mysql:8.0.32
  1. 从上面的挂载目录命名就可以看出,我准备将 33066 作为主数据库,33067和33068做为从数据库

4. ++主从复制就是在数据库上做配置的设置(重点在这里,但是很简单,就几条命令)++

1. 进入33066主库 docker容器中

bash 复制代码
docker exec -it mysql_master_33066 /bin/bash

a. 首先 mysql -uroot -p 进入mysql ,或者用 Navicat 工具连接

b. 执行以下两条命令:

bash 复制代码
-- 创建名字为:copy_file_wangqinmin ,密码为:wangqinmin ,访问ip为任意ip的用户
CREATE USER 'copy_file_wangqinmin'@'%' IDENTIFIED BY 'wangqinmin';

-- 为名字是 copy_file_wangqinmin 的用户,只设置 REPLICATION SLAVE (复制数据的权限)
GRANT REPLICATION SLAVE ON *.* TO 'copy_file_wangqinmin'@'%';

-- mysql8.0.32 需要执行这个命令(搭建完成后,发现没有连接成功,看错误日志后添加的这一段命令)
-- 否则会有错误日志:
-- error connecting to master 'copy_file_wangqinmin@192.168.1.3:33066' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
ALTER USER 'copy_file_wangqinmin'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'wangqinmin';


-- 刷新权限
FLUSH PRIVILEGES;

c. 重启主库和从库

bash 复制代码
docker restart mysql_master_33066 mysql_slave_33067 mysql_slave_33068

d. 在主库上执行以下命令,并记下 "File" 和 "Position" 的值:

bash 复制代码
SHOW MASTER STATUS;

我这里获取到的数据为:

因为mysql都在docker内部安装,所以容器的本地ip是127.0.0.1,但是本机外部的本地ip也是127.0.0.1,所以需要查询外部电脑的ip地址:

我的ip地址是: 192.168.1.3

2. 进入33067从库 docker容器中

bash 复制代码
docker exec -it mysql_slave_33067 /bin/bash

进入mysql中 或者 用 Navicat 工具连接后,分别执行以下3条命令:

bash 复制代码
-- 停止从库的复制进程。这是为了确保在修改主从配置时,不会有正在运行的复制进程。
STOP SLAVE;

-- 指定从库要去主库的哪个位置开始复制数据。
CHANGE MASTER TO
  MASTER_HOST='192.168.1.3',
  MASTER_PORT=33066,
  MASTER_USER='copy_file_wangqinmin',
  MASTER_PASSWORD='wangqinmin',
  MASTER_LOG_FILE='binlog.000002',
  MASTER_LOG_POS=721;

-- 启动从库的复制进程,开始从主库复制数据。	
START SLAVE;

3. 进入33068从库 docker容器中

bash 复制代码
docker exec -it mysql_slave_33068 /bin/bash

进入mysql中 或者 用 Navicat 工具连接后,分别执行以下3条命令:

复制代码
-- 停止从库的复制进程。这是为了确保在修改主从配置时,不会有正在运行的复制进程。
STOP SLAVE;

-- 指定从库要去主库的哪个位置开始复制数据。
CHANGE MASTER TO
  MASTER_HOST='192.168.1.3',
  MASTER_PORT=33066,
  MASTER_USER='copy_file_wangqinmin',
  MASTER_PASSWORD='wangqinmin',
  MASTER_LOG_FILE='binlog.000002',
  MASTER_LOG_POS=721;

-- 启动从库的复制进程,开始从主库复制数据。	
START SLAVE;

++解释:++

  • ++MASTER_HOST='192.168.1.3': 指定主库的 IP 地址。++
  • ++MASTER_PORT=33066: 指定主库的端口号。++
  • ++MASTER_USER='copy_file_wangqinmin': 指定用于连接主库的用户。++
  • ++MASTER_PASSWORD='wangqinmin': 指定主库用户的登录密码。++
  • ++MASTER_LOG_FILE='binlog.++ 000002++': 指定主库的二进制日志文件。++
  • ++MASTER_LOG_POS=721: 指定从主库的从哪个二进制日志位置开始复制数据。++

最后一步:查看从库的状态,确定从库是否已经连接到主库,是否能够复制文件和sql:

在从库上执行以下命令:

复制代码
SHOW SLAVE STATUS;

确保 "Slave_IO_Running" 和 "Slave_SQL_Running" 均为 "Yes"

++如果一直没有连接上,可以尝试先重启主库,再重启从库。如果还不行,就看看是不是ip或者是参数填写错误。++

++或者查看错误日志:++

执行命令查看错误日志(这里是我不断调试过程中发现的错误日志):SHOW SLAVE STATUS;

给大家看一下成功的结果:

这时候向主库 【创建数据库,添加数据,修改数据等等】,导致数据变化的操作。从库都会实时的进行数据变更。

有一点要注意的是,虽然实现了主从复制,但是依然会有延迟,并且可能由于:网络、IO、CPU等因素的影响,最终会导致数据的不一致问题,这个问题不能被完全解决,只能优化,同时某些业务如果要求数据一致的情况下,还是需要直接去读主库。

注意!!!!!!!,还没有完 。

上面只是搭建,还有关闭、启动数据库,也是有步骤的。

思想很简单:

1. 先关闭从库,再关闭主库;

2. 先启动主库,再启动从库。

关闭:

bash 复制代码
我们需要:
1. 先关闭从库的复制功能 (这个是有顺序的,必须先执行)
    STOP SLAVE;
2. 然后关闭主库
    systemctl stop mysql   我这里是docker ,就直接: docker stop 容器ID
3. 再关闭多个从库(我这里是两个)
    systemctl stop mysql   我这里是docker ,就直接: docker stop 容器ID

启动:

复制代码
1. 先启动主库
    systemctl start mysql
2. 再启动多个从库
    systemctl start mysql
3. 从库执行 (每个从库都执行)
    START SLAVE;
4. 然后看一下状态是否正确 (正确就可以了)
    SHOW SLAVE STATUS;
  1. 要完成读写分离的话,我使用 sharding jdbc来完成。让主库完成 (增、删、改的操作),让从库的轮询访问来完成读的操作。

~~未完待续

相关推荐
ulias2123 小时前
Linux系统中的权限问题
linux·运维·服务器
青花瓷4 小时前
Ubuntu下OpenClaw的安装(豆包火山API版)
运维·服务器·ubuntu
问简5 小时前
docker 镜像相关
运维·docker·容器
Dreamboat¿5 小时前
SQL 注入漏洞
数据库·sql
Dream of maid6 小时前
Linux(下)
linux·运维·服务器
齐鲁大虾6 小时前
统信系统UOS常用命令集
linux·运维·服务器
Benszen6 小时前
Docker容器化技术实战指南
运维·docker·容器
ZzzZZzzzZZZzzzz…6 小时前
Nginx 平滑升级:从 1.26.3 到 1.28.0,用户无感知
linux·运维·nginx·平滑升级·nginx1.26.3·nginx1.28.0
被摘下的星星7 小时前
MySQL count()函数的用法
数据库·mysql
Hommy887 小时前
【开源剪映小助手】Docker 部署
docker·容器·开源·github·aigc