CentOS7中使用Docker进行MySQL主从复制【论文式教程】

131 阅读9分钟

1、安装Docker

卸载docker

sudo yum remove docker*

安装 yum-utils 工具集,它提供了一些额外的命令和功能,帮助你更好地管理 YUM 软件包管理器。其中包含了一个工具叫做 yum-config-manager,它用于管理 YUM 配置,包括软件仓库源。

sudo yum install -y yum-utils

通过 yum-config-manager 添加一个新的软件仓库源,这里是阿里云的 Docker 仓库源。用国外的太慢,国内好,国内快。

sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装Docker的核心组件并制定版本

sudo yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io-1.4.3

Docker 实际上是一个包含多个组件的平台,这些组件一起协作以实现容器化应用程序的创建、管理和运行。在这些组件中,最核心的就是那三个组件:Docker 引擎、Docker 命令行工具和容器运行时。

  1. Docker 引擎(Docker Engine): 也被称为 Docker 守护进程,是 Docker 平台的核心引擎。它负责管理容器的创建、运行和停止,以及与容器镜像的交互。Docker 引擎使用 Linux 内核的容器特性来实现轻量级的隔离,使得不同的容器能够在同一个主机上运行,而彼此之间相互隔离。
  2. Docker 命令行工具(Docker CLI): 这是用于与 Docker 引擎进行交互的命令行界面。通过 Docker CLI,用户可以使用各种命令来管理容器、镜像、网络、卷等。它是用户与 Docker 平台进行交互的主要方式。
  3. 容器运行时(Container Runtime): 这个组件负责实际运行容器的进程。它负责管理容器的生命周期、文件系统、进程隔离等。Docker 最初使用的容器运行时是 dockerd(Docker 守护进程)和 containerd,后来演化为将容器运行时抽象为 containerd,而 Docker 引擎则使用 containerd 来管理容器。

设置系统启动时自动启动Docker服务

sudo systemctl enable docker --now

配置Docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF

sudo: 以超级用户(root)权限执行命令。

tee: 这个命令用于读取标准输入并将其写入文件和标准输出。通过管道操作,它可以用来将内容写入文件

/etc/docker/daemon.json: 这是指要写入的目标文件的路径,即 Docker 守护进程的配置文件 daemon.json

<<-'EOF': 这是一个 Here Document,允许你在一个多行字符串中定义内容,直到遇到标记 EOF 为止。在这里,JSON 配置将在这个 Here Document 中定义。

重启系统服务

sudo systemctl daemon-reload

因为刚刚修改了系统的配置文件,就是/etc/下的。所以得重启生效

重启docker服务让配置生效

sudo systemctl restart docker

重启docker注意会重启所有的容器,所以重启前确保重要的数据都保存了。

2、安装MYSQL主服务

启动容器,会自动拉取MYSQL镜像的。

docker run -p 3301:3306 --name mysql-master \
-v /mydata/mysql-01/log:/var/log/mysql \
-v /mydata/mysql-01/data:/var/lib/mysql \
-v /mydata/mysql-01/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
--restart=always \
-d mysql:5.7

docker run: 这是启动 Docker 容器的命令。

-p 3301:3306: 这是端口映射选项。它将容器的 3306 端口映射到主机的 3301 端口,这样你可以通过主机的 3301 端口访问容器中的 MySQL 服务。

--name mysql-master: 这为容器指定了一个名字,即 mysql-master

-v /mydata/mysql-01/log:/var/log/mysql: 这是将主机上的 /mydata/mysql-01/log 目录挂载到容器内的 /var/log/mysql 目录,用于存储 MySQL 日志。

-v /mydata/mysql-01/data:/var/lib/mysql: 这是将主机上的 /mydata/mysql-01/data 目录挂载到容器内的 /var/lib/mysql 目录,用于存储 MySQL 数据。

-v /mydata/mysql-01/conf:/etc/mysql/conf.d: 这是将主机上的 /mydata/mysql-01/conf 目录挂载到容器内的 /etc/mysql/conf.d 目录,用于存储 MySQL 配置文件。

-e MYSQL_ROOT_PASSWORD=root: 这是设置 MySQL 的 root 用户密码为 root

--restart=always: 这是设置容器在退出后总是自动重启。

-d mysql:5.7: 这是指定要运行的容器镜像,即 MySQL 5.7 版本的官方镜像。

将文件挂载到容器内的文件,就可以做到修改文件,容器中对应的配置文件也会修改。而且还是双向影响的。而且无需重启容器即刻生效。

以下为验证:

image.png

配置MYSQL容器

mkdir -p /mydata/mysql-01/conf && vim /mydata/mysql-01/conf/default.cnf

配置文件的文件名无所谓,内容如下:

[client]

default-character-set=utf8mb4

[mysql]

default-character-set=utf8mb4

[mysqld]

init_connect='SET collation_connection = utf8mb4_unicode_ci'

init_connect='SET NAMES utf8mb4'

character-set-server=utf8mb4

collation-server=utf8mb4_unicode_ci

skip-character-set-client-handshake

skip-name-resolve

server-id=1

##开启二进制日志

log-bin=mysql-bin

创建同步用户

需要在主服务容器中创建一个用户,专门用来做同步工作,以便从服务器通过这个用户连接到主服务容器进行复制操作。从服务器到时候会复制主服务器中的二进制日志,然后将这些二进制日志应用到自己的数据库中,从而实现数据复制。从服务会一直监控主服务的二进制日志变化,然后一直获取新的二进制日志以保持数据一致。

这些二进制日志记录了主服务容器的数据变更操作。

资料:在这个过程中,从服务器不断地连接到主服务器,请求并应用主服务器的二进制日志,以保持数据同步。需要注意的是,网络连接的稳定性和延迟对复制的效率和性能有影响,因此在配置复制时要考虑网络因素。 此外,复制过程中可能会出现一些问题,比如网络故障、主从服务器的时间差异等,这些问题可能导致复制中断或数据不一致。

create user 'username'@'%' identified by 'password';
grant replication slave,replication client on *.* to 'username'@'%';

image.png

REPLICATION SLAVE:这个权限允许用户作为从服务器连接到主服务器并复制主服务器的二进制日志,以保持数据同步。

REPLICATION CLIENT:这个权限允许用户作为从服务器连接到主服务器,以获取有关主服务器状态和二进制日志的信息。

*.* 表示在所有数据库和所有表上设置这些权限。'username'@'%' 表示允许来自任何主机的连接使用这个用户名。

3、安装MySQL从服务1

新建mysql主服务器容器1,起名mysql-slave1

docker run -p 3302:3306 --name mysql-slave1 \
-v /mydata/mysql-slave1/log:/var/log/mysql \
-v /mydata/mysql-slave1/data:/var/lib/mysql \
-v /mydata/mysql-slave1/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always \
-d mysql:5.7

配置MYSQL容器

mkdir -p /mydata/mysql-slave1/conf && vim /mydata/mysql-slave1/conf/mysql-salve1.cnf

配置文件的文件名无所谓,内容如下:

[client]

default-character-set=utf8mb4

[mysql]

default-character-set=utf8mb4

[mysqld]

init_connect='SET collation_connection = utf8mb4_unicode_ci'

init_connect='SET NAMES utf8mb4'

character-set-server=utf8mb4

collation-server=utf8mb4_unicode_ci

skip-character-set-client-handshake

skip-name-resolve

server-id=2

进入主MySQL容器中,查看主服务二进制日志状态

image.png

再进入从数据库中配置主从配置

跟从服务器说好你的老大是谁,认好老大,看清谁是主库,好跟随主库进行变化。

change master to master_host='主服务容器IP', master_user='你在主服务创建的同步用户名', master_password='用户密码', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=154, master_connect_retry=30;

master_host :Master 的地址,指的是容器的独立 ip, 可以通过 docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称 | 容器 id 查询容器的 ip

master_log_file='mysql-bin.000001', master_log_pos=154, master_connect_retry=30;

这三个值抄上一步结果

在从数据库中查看主从复制状态

show slave status \G;

image.png

Slave_IO_Running: 这个字段指示 I/O 线程的运行状态。如果值为 "Yes",表示 I/O 线程正在运行,I/O线程运行说明,从数据库正在读取主服务的二进制日志,并传输这些二进制日志到从服务器。

Slave_SQL_Running: 这个字段指示 SQL 线程的运行状态。如果值为 "Yes",表示 SQL 线程正在运行,这意味着从服务器正在应用主服务器的二进制日志事件。

Seconds_Behind_Master: 这个字段表示从服务器相对于主服务器的延迟时间(以秒为单位)。如果值为 0 或接近 0,表示从服务器与主服务器数据同步较为实时,这表明主从复制成功

在从服务器容器中开启主从

start slave;

image.png

一些bug

Cannot connect to the Docker daemon

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Docker 守护进程没有在运行。Docker 守护进程负责管理和监控 Docker 容器的创建、运行和停止。

直接启动docker的守护进程:sudo systemctl start docker

show master status 结果是empty set

image.png

估计就是没有启用二进制日志,或者没有产生二进制日志。

image.png 解决:

进入主服务mysql的配置文件,开启日志

image.png

重启mysql服务生效配置

docker restart mysql-master

一定也要加上server-id的配置,因为我就吃亏了,一开始我只配置了log-bin的,结果启动容器会报错,容器会一直处于重启状态restarting。然后我查看容器的日志发现提示我加上server-id。

查看日志:docker logs mysql-master

image.png

change master出错

image.png

image.png 改完重启:docker restart mysql-slave1

补习

在 MySQL 的二进制日志中,每个操作(插入、删除、更新)都被记录为一个事件,并且每个事件都有一个唯一的位置标识,通常被称为“二进制日志位置”(Binary Log Position)。master_log_file 参数设置为 "mysql-bin.000003",而 master_log_pos 参数设置为 "1552"。这意味着从服务器将从 "mysql-bin.000003" 这个二进制日志文件的位置 "1552" 处开始复制数据。

change master to master_host='172.17.0.2', master_user='copyUser', master_password='123456', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos=1552, master_connect_retry=30; 这个命令就是说让从数据库到mysql-bin.000003日志中从1552开始读取日志事件进行复制。

show master status;显示的file就是写入的二进制文件名,position就是最后一个事件的位置。

在这里插入图片描述

这是MySQL的二进制日志文件,这边他设计的是多个二进制日志文件, 当事件到达一定量或者一定时间后,就会创建新的二进制文件存,这样避免一个巨大的日志文件影响性能和管理。