CentOS7中使用Docker部署MySQL实现主从同步

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41402200/article/details/95876316

前言

  最近在学习有关 MyCAT 相关的知识,但是使用 MyCAT 前提是得部署多个 MySQL 实例,由于只有一台服务器,

  所以就使用了 Docker 。本博客实现了 MySQL 一主两从。

本篇博客的操作有:

  ① 拉取 MySQL 官方镜像

  ② MySQL 主从配置

  ③ 运行 MySQL 容器

  ④ 在从库中配置主从同步命令

  ⑤ 验证

拉取 MySQL 官方镜像

  1. 输入命令 systemctl  start docker.service -> 启动 Docker 服务

  2. 输入命令 docker pull mysql:5.7 -> 拉取 MySQL 镜像

配置 MySQL 在宿主机上的配置文件,数据日志目录以及初始化 sql 文件

准备工作

  1. 首先在宿主机上为此次配置创建相应的目录

  2. 输入命令 cd /usr/local/ -> 进入目录

  3. 输入命令 mkdir docker -> 创建文件夹

  4. 输入命令 cd docker/ -> 进入目录

  5. 输入命令 mkdir mysql_master_3306 -> 创建主库文件夹

  6. 轮流输入命令 cd mysql_master_3306、mkdir conf、mkdir data、mkdir log、mkdir sql -> 创建相关

      文件夹

  7. 输入命令 cd .. -> 回到上级目录

  8. 还有两个从库的文件夹目录结构大致相同,所以使用 cp -r 命令来创建

  9. 输入命令 cp -r mysql_master_3306/ mysql_slave_3307/ -> 复制创建第一个从库目录

 10. 输入命令 cp -r mysql_master_3306/ mysql_slave_3308/ -> 复制创建第二个从库目录

配置文件 - master 主库

  1. 输入命令 cd /usr/local/docker/mysql_master_3306/conf/ -> 进入目录

  2. 输入命令 touch my.cnf -> 新建文件

  3. 输入命令 vim my.cnf -> 编辑文件,粘贴下面内容

[client]

default-character-set=utf8mb4


[mysqld]

character-set-client-handshake = FALSE

character-set-server = utf8mb4

collation-server = utf8mb4_unicode_ci

server-id=1        # 数据库唯一 ID,主从的标识号绝对不能重复。

log-bin=/var/log/mysql/binlog    # 开启 bin-log,并指定文件目录和文件名前缀

binlog-do-db=masterSlaveDB  # 需要同步的数据库。如果是多个同步库,就以此格式另写几行即可。如果不指明对某个具体库同步,就去掉此行,表示同步所有库(除了 ignore 忽略的库)。

binlog-ignore-db=mysql  # 不同步mysql系统数据库。如果是多个不同步库,就以此格式另写几行;也可以在一行,中间逗号隔开。

sync_binlog = 1      # 确保 binlog 日志写入后与硬盘同步

binlog_checksum = none  # 跳过现有的采用 checksum 的事件,mysql5.6.5 以后的版本中 binlog_checksum=crc32,而低版本都是 binlog_checksum=none

binlog_format = mixed   # bin-log 日志文件格式,设置为 MIXED 可以防止主键重复。

[mysql]
default-character-set=utf8mb4

  4. 轮流输入命令 esc -> shift 冒号 -> wq -> 回车

配置文件 - slave 从库

  1. 输入命令 cd /usr/local/docker/mysql_slave_3307/conf/ -> 进入目录

  2. 输入命令 touch my.cnf -> 新建文件

  3. 输入命令 vim my.cnf -> 编辑文件,粘贴下面内容

[client]

default-character-set=utf8mb4


[mysqld]

character-set-client-handshake = FALSE

character-set-server = utf8mb4

collation-server = utf8mb4_unicode_ci

server-id=2        # 数据库唯一 ID,主从的标识号绝对不能重复。

log-bin=/var/log/mysql/binlog    # 开启 bin-log,并指定文件目录和文件名前缀

binlog-do-db=masterSlaveDB  # 需要同步的数据库。如果是多个同步库,就以此格式另写几行即可。如果不指明对某个具体库同步,就去掉此行,表示同步所有库(除了 ignore 忽略的库)。

binlog-ignore-db=mysql  # 不同步 mysql 系统数据库。如果是多个不同步库,就以此格式另写几行;也可以在一行,中间逗号隔开。

slave-skip-errors = all   # 跳过所有的错误错误,继续执行复制操作

[mysql]
default-character-set=utf8mb4

  4. 轮流输入命令 esc -> shift 冒号 -> wq -> 回车

  5. 还有一个 mysql_slave_3308 从库除了 server-id 不一致以外,其他基本一致,这里不再赘述

  6. mysql_slave_3308/conf/my.cnf -> server-id=3

数据目录

  1. 此时在启动 MySQL 容器前,此目录都是空的

日志目录

  1. 此时在启动 MySQL 容器前,此目录也都是空的

初始化 sql 文件

  1. 输入命令 cd /usr/local/docker/mysql_master_3306/sql/ -> 进入目录

  2. 输入命令 touch init.sql -> 新建文件

  3. 输入命令 vim init.sql -> 编辑文件,粘贴下面内容

-- 创建数据库
DROP database IF EXISTS `masterSlaveDB`;
CREATE DATABASE `masterSlaveDB` default character set utf8mb4 collate utf8mb4_unicode_ci;

-- 切换数据库
USE masterSlaveDB;

-- 创建表
DROP TABLE IF EXISTS `masterSlaveTable` ;
CREATE TABLE `masterSlaveTable` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `type` varchar(2) DEFAULT NULL COMMENT '生活用品类别:1. 家电类 2. 厨具',
        `name` varchar(50) DEFAULT NULL COMMENT '生活用品名称',
        `description` varchar(200) DEFAULT NULL COMMENT '生活用品描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='MySQL 主从同步测试表';

INSERT INTO masterSlaveTable ( type , name , description )
VALUES ('1','电饭煲','用来蒸饭'),('1','电热壶','用来烧水'),('1','空调','用来制冷或制热'),('2','菜刀','用来切菜'),('2','刨子','用来剥皮'),('2','打蛋器','用来搅拌鸡蛋');

  4. 轮流输入命令 esc -> shift 冒号 -> wq -> 回车

  5. 一主两从中的初始化 sql 文件都一样,所以这里使用 cp 命令来创建从库的初始化 sql 文件

  6. 输入命令 cp init.sql ../../mysql_slave_3307/sql/ -> 复制文件

  7. 输入命令 cp init.sql ../../mysql_slave_3308/sql/ -> 复制文件

运行 MySQL 容器

  1. 输入命令 docker images -> 查看构建的镜像

  2. 输入命令

docker run -p 3306:3306 --name mysql-master-3306 -v /usr/local/docker/mysql_master_3306/conf/my.cnf:/etc/mysql/conf.d/my.cnf -v /usr/local/docker/mysql_master_3306/data/:/var/lib/mysql/ -v /usr/local/docker/mysql_master_3306/sql/:/docker-entrypoint-initdb.d/ -v /usr/local/docker/mysql_master_3306/log/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

  • -p:端口映射(宿主机端口:容器端口)
  • --name:启动后的容器名称
  • -v:第一个 -v 为映射配置文件(宿主机目录:容器目录)
  • -v:第二个 -v 为映射数据目录,相当于把容器中的数据备份到宿主机指定的目录(宿主机目录:容器目录)
  • -v:第三个 -v 为初始化 sql 目录(宿主机目录:容器目录)
  • -v:第四个 -v 为日志目录(宿主机目录:容器目录)
  • -e MYSQL_ROOT_PASSWORD=123456:设置 root 连接密码
  • 映射实际上是把宿主机和容器相连通
  • 容器中映射目录的文件发生改变时,宿主机中映射目录的文件也发生变化
  • -d:后台启动
  • mysql:5.7:启动的镜像

  3. 还有两个从库启动与主库启动类似,分别为

docker run -p 3307:3306 --name mysql-slave-3307 -v /usr/local/docker/mysql_slave_3307/conf/my.cnf:/etc/mysql/conf.d/my.cnf -v /usr/local/docker/mysql_slave_3307/data/:/var/lib/mysql/ -v /usr/local/docker/mysql_slave_3307/sql/:/docker-entrypoint-initdb.d/ -v /usr/local/docker/mysql_slave_3307/log/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

docker run -p 3308:3306 --name mysql-slave-3308 -v /usr/local/docker/mysql_slave_3308/conf/my.cnf:/etc/mysql/conf.d/my.cnf -v /usr/local/docker/mysql_slave_3308/data/:/var/lib/mysql/ -v /usr/local/docker/mysql_slave_3308/sql/:/docker-entrypoint-initdb.d/ -v /usr/local/docker/mysql_slave_3308/log/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

  4. 全部启动后,输入命令 docker ps -a -> 查看容器运行情况

  5. 发现容器并没有启动成功,状态(STAUTS)为:Exited,使用命令 docker logs CONTAINER ID 查看

     容器启动日志,核心错误内容如下

mysqld: File '/var/log/mysql/binlog.index' not found (Errcode: 13 - Permission denied)

  6. 权限不足,得把 log 文件夹设置 '读写执' 权限

  7. 输入命令 cd /usr/local/docker/mysql_master_3306/ -> 进入目录

  8. 输入命令 chmod -R 777 log/ -> 设置 log 文件夹 '读写执' 权限

  9. 输入命令 cd /usr/local/docker/mysql_slave_3307/ -> 进入目录

 10. 输入命令 chmod -R 777 log/ -> 设置 log 文件夹 '读写执' 权限

 11. 输入命令 cd /usr/local/docker/mysql_slave_3308/ -> 进入目录

 12. 输入命令 chmod -R 777 log/ -> 设置 log 文件夹 '读写执' 权限

 13. 输入命令 docker rm CONTAINER ID -> 删除刚刚启动失败的容器

 14. 再把上面步骤 2,3 中的命令再执行一遍

 15. 输入命令 docker ps -a -> 查看容器运行情况,所有容器都成功启动

在从库中配置主从同步命令

进入 master 主库容器

  1. 输入命令 docker ps -a -> 查看容器运行情况

  2. 输入命令 docker exec -it CONTAINER ID bash -> 进入容器,注意此 CONTAINER ID 为 主库容器 ID

  3. 输入命令 mysql -u root -p -> 登录 MySQL

  4. 回车,输入启动容器时配置的密码(123456

  5. 连接上主库后,输入命令 show master status; -> 查看 master 主库状态

mysql> show master status;
+---------------+----------+---------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB  | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+---------------+------------------+-------------------+
| binlog.000003 |      150 | masterSlaveDB | mysql            |                   |
+---------------+----------+---------------+------------------+-------------------+
1 row in set (0.00 sec)

  6. 其中 File 和 Position 是从库配置需要的参数

进入 slave 从库容器

  1. 输入命令 docker ps -a -> 查看容器运行情况

  2. 输入命令 docker exec -it CONTAINER ID bash -> 进入容器,注意此 CONTAINER ID 为 从库容器 ID

  3. 输入命令 mysql -u root -p -> 登录 MySQL

  4. 回车,输入启动容器时配置的密码(123456

  5. 输入命令 stop slave; -> 先停止 slave

  6. 输入命令 

change  master to master_host='xxx.xxx.xxx.xxx',master_user='root',master_password='123456',master_log_file='binlog.000003',master_log_pos=150;
  • master_host:主库服务器 ip 地址
  • master_user:主库 MySQL 用户名
  • master_password:主库 MySQL 密码
  • master_log_file:为上面查询的主库 File 值 -> binlog.000003
  • master_log_pos:为上面查询的主库 Position 值 -> 150

  7. 输入命令 start slave; -> 开启 slave

  8. 输入命令 show slave status \G; -> 查看从库状态

  9. 如果它们两个状态为 Yes,就证明主从已实现同步

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

验证

  1. 回到上面 master 主库的容器,查看一下 masterSlaveDB 库中的 masterSlaveTable 表中的数据

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| masterSlaveDB      |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use masterSlaveDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------------+
| Tables_in_masterSlaveDB |
+-------------------------+
| masterSlaveTable        |
+-------------------------+
1 row in set (0.00 sec)

mysql> select * from masterSlaveTable;
+----+------+-----------+-----------------------+
| id | type | name      | description           |
+----+------+-----------+-----------------------+
|  1 | 1    | 电饭煲    | 用来蒸饭              |
|  2 | 1    | 电热壶    | 用来烧水              |
|  3 | 1    | 空调      | 用来制冷或制热        |
|  4 | 2    | 菜刀      | 用来切菜              |
|  5 | 2    | 刨子      | 用来剥皮              |
|  6 | 2    | 打蛋器    | 用来搅拌鸡蛋          |
+----+------+-----------+-----------------------+
6 rows in set (0.00 sec)

mysql>

  2. 回到上面 slave 从库的容器,查看一下 masterSlaveDB 库中的 masterSlaveTable 表中的数据

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| masterSlaveDB      |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use masterSlaveDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------------+
| Tables_in_masterSlaveDB |
+-------------------------+
| masterSlaveTable        |
+-------------------------+
1 row in set (0.00 sec)

mysql> select * from masterSlaveTable;
+----+------+-----------+-----------------------+
| id | type | name      | description           |
+----+------+-----------+-----------------------+
|  1 | 1    | 电饭煲    | 用来蒸饭              |
|  2 | 1    | 电热壶    | 用来烧水              |
|  3 | 1    | 空调      | 用来制冷或制热        |
|  4 | 2    | 菜刀      | 用来切菜              |
|  5 | 2    | 刨子      | 用来剥皮              |
|  6 | 2    | 打蛋器    | 用来搅拌鸡蛋          |
+----+------+-----------+-----------------------+
6 rows in set (0.00 sec)

mysql>

  3. 目前主从库中数据都是一致的

  4. 现在来删除主库中的一条数据

  5. 再次回到上面 master 主库的容器,使用 SQL 删除一条记录

mysql> delete from masterSlaveTable where id = 3;
Query OK, 1 row affected (0.00 sec)

mysql> select * from masterSlaveTable;
+----+------+-----------+--------------------+
| id | type | name      | description        |
+----+------+-----------+--------------------+
|  1 | 1    | 电饭煲    | 用来蒸饭           |
|  2 | 1    | 电热壶    | 用来烧水           |
|  4 | 2    | 菜刀      | 用来切菜           |
|  5 | 2    | 刨子      | 用来剥皮           |
|  6 | 2    | 打蛋器    | 用来搅拌鸡蛋       |
+----+------+-----------+--------------------+
5 rows in set (0.00 sec)

mysql>

  6. 再次回到上面 slave 从库的容器,查询数据

mysql> select * from masterSlaveTable;
+----+------+-----------+--------------------+
| id | type | name      | description        |
+----+------+-----------+--------------------+
|  1 | 1    | 电饭煲    | 用来蒸饭           |
|  2 | 1    | 电热壶    | 用来烧水           |
|  4 | 2    | 菜刀      | 用来切菜           |
|  5 | 2    | 刨子      | 用来剥皮           |
|  6 | 2    | 打蛋器    | 用来搅拌鸡蛋       |
+----+------+-----------+--------------------+
5 rows in set (0.00 sec)

mysql>

  7. 证明从库数据与主库同步成功

  8. 上面的验证也可以在 Windows 本地使用 Navicat 远程连接后操作,那样的话就要开启端口的操作


安全组

  注:如果服务器是在阿里云租用的需要设置安全组

  1. 登录到阿里云

  2. 进入到 '云服务器 ECS' 控制台

  3. 左侧栏中选择 '实例'

  4. 进入实例详情,点击左侧栏中 '本实例安全组'

  5. 点击安全组中的 '配置规则'

  6. 点击 '添加安全组规则' 按钮

  7. 配置 3306、3307 和 3308 端口

防火墙

  注:如果服务器是在阿里云租用的需要开启防火墙。服务器是默认不开启防火墙的,感觉不安全

  1. 输入命令 systemctl status firewalld -> 查看防火墙状态

  2. 输入命令 systemctl start firewalld -> 开启防火墙

  3. 如果你不想开防火墙的话,那就输入命令 systemctl stop firewalld -> 关闭防火墙

  4. 输入命令 systemctl restart firewalld.service -> 重启防火墙

端口

  注:端口操作需要在开启防火墙的情况下才能执行成功。如下三条命令只需要执行一组即可

  1. 输入命令 firewall-cmd --permanent --zone=public --add-port=3306/tcp -> 永久开放 3306 端口

      输入命令 firewall-cmd --permanent --zone=public --add-port=3307/tcp -> 永久开放 3307 端口

      输入命令 firewall-cmd --permanent --zone=public --add-port=3308/tcp -> 永久开放 3308 端口

  2. 输入命令 firewall-cmd --zone=public --add-port=3306/tcp -> 临时开放 3306 端口

      输入命令 firewall-cmd --zone=public --add-port=3307/tcp -> 临时开放 3307 端口

      输入命令 firewall-cmd --zone=public --add-port=3308/tcp -> 临时开放 3308 端口


扩展

CentOS7中安装Docker

CentOS7中常用命令行

希望能够帮助到你

over

猜你喜欢

转载自blog.csdn.net/qq_41402200/article/details/95876316