介绍
在本实验中,你将学习 MySQL 复制(replication)的基础知识。复制是一个允许你在多个服务器上维护 MySQL 数据库副本的过程。这通常用于负载均衡、数据备份和高可用性。
你将使用 Docker 创建一个真实的 master-slave 复制设置,包含两个独立的 MySQL 容器。首先,你将启动并验证一个 master 容器,该容器已预先配置并启用了二进制日志(binary logging)。你将在 master 上创建一个特殊的复制用户。然后,你将配置第二个容器作为 slave,将其连接到 master,并验证数据是否正确同步。这种实践方法将帮助你理解管理真实 MySQL 复制环境所涉及的关键步骤。
设置 Docker 环境
在第一步中,你将为 master-slave 复制环境设置必要的 Docker 容器。你将创建一个专用的网络并启动两个 MySQL 容器。
创建 Docker 网络:
一个专用的网络允许容器通过名称相互通信。创建一个名为
mysql-net的网络。docker network create mysql-net启动 Master MySQL 容器:
接下来,启动 master 容器。此命令使用
mysql:5.7,并将其 server ID 配置为 1,同时为replication_db数据库启用二进制日志(binary logging)。docker run -d \ --name mysql-master \ --network mysql-net \ -e MYSQL_ROOT_PASSWORD=lab_password \ -e MYSQL_DATABASE=replication_db \ mysql:5.7 \ mysqld --server-id=1 --log-bin=mysql-bin --binlog-do-db=replication_db启动 Slave MySQL 容器:
现在,启动 slave 容器。此容器也位于同一网络上,并配置了 server ID 2。我们还提前创建了
replication_db数据库,以便 slave 可以正确应用来自 master 的更改。docker run -d \ --name mysql-slave \ --network mysql-net \ -e MYSQL_ROOT_PASSWORD=lab_password \ -e MYSQL_DATABASE=replication_db \ mysql:5.7 \ mysqld --server-id=2 --relay-log=mysql-relay-bin --log-slave-updates=1等待容器初始化:
MySQL 容器需要一些时间来初始化。等待大约 15 秒,然后检查容器是否正在运行。
docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfe8c98d2ad0 mysql:5.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mysql-slave fc125bf293ea mysql:5.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mysql-master
现在你的环境已经设置好,你可以继续配置 master 服务器了。
验证 Master 服务器配置
容器运行后,下一步是确保 master 服务器已正确配置以进行复制。master 的主要职责是将其所有数据库更改记录到二进制日志(binary log)中,之后 slave 将读取这些日志。
首先,从你的桌面打开一个终端。
现在我们将连接到 master 容器并验证其配置。
连接到 Master 容器:
使用
docker exec在mysql-master容器内打开一个 MySQL shell。系统会提示你输入密码,密码是lab_password。docker exec -it mysql-master mysql -uroot -plab_password验证二进制日志和 Server ID:
看到
mysql>提示符后,运行以下命令来验证二进制日志是否已启用以及 server ID 是否已正确设置。SHOW VARIABLES LIKE 'log_bin';输出应显示
log_bin为ON。+---------------+----+ | Variable_name | Value | +---------------+----+ | log_bin | ON | +---------------+----+ 1 row in set (0.01 sec)接下来,检查 server ID。
SHOW VARIABLES LIKE 'server_id';输出应显示
server_id为1。+---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 1 | +---------------+-------+ 1 row in set (0.00 sec)现在你已验证了配置,可以退出 MySQL shell 了。
exit;
你已成功确认 master 服务器已准备好进行复制。
创建复制用户和测试数据库
slave 服务器需要连接到 master 以读取二进制日志。为了安全起见,最佳实践是为此目的创建一个具有有限权限的专用用户账户。在这一步中,你将创建一个复制用户并填充测试数据库,以观察复制的实际效果。
连接到 Master 服务器:
在
mysql-master容器内打开一个 MySQL shell。docker exec -it mysql-master mysql -uroot -plab_password创建复制用户:
在
mysql>提示符下,运行以下命令创建一个名为repl_user的用户,密码为repl_password。slave 将使用此用户进行连接。我们使用'@'%'来允许用户从任何主机连接,这包括我们在 Docker 网络上的 slave 容器。CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_password';授予复制权限:
新用户需要
REPLICATION SLAVE权限,该权限允许它从 master 读取二进制日志。GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';授予权限后,重新加载授权表以立即应用更改。
FLUSH PRIVILEGES;检查 Master 的二进制日志状态:
在配置 slave 之前,你需要知道 master 二进制日志中 slave 应该开始复制的确切坐标。
SHOW MASTER STATUS命令提供此信息。SHOW MASTER STATUS;输出将与此类似。记下
File和Position的值,因为在下一步中会用到它们。+------------------+----------+------------------+--------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+------------------+--------------------+-------------------+ | mysql-bin.000001 | 337 | replication_db | | | +------------------+----------+------------------+--------------------+-------------------+ 1 row in set (0.00 sec)创建测试表和数据:
replication_db数据库在容器启动时已创建。让我们创建一个表并插入一些数据来测试复制。USE replication_db; CREATE TABLE messages ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(255) ); INSERT INTO messages (content) VALUES ('Hello from the master!');你可以验证数据是否已正确插入。
SELECT * FROM messages;你应该能看到你刚刚插入的行。
+----+------------------------+ | id | content | +----+------------------------+ | 1 | Hello from the master! | +----+------------------------+ 1 row in set (0.00 sec)现在,退出 MySQL shell。
exit;
你现在已经通过创建复制用户和一些测试数据来准备好 master 服务器了。
配置并启动 Slave 服务器
Master 服务器准备就绪后,你将配置 slave 容器。在这一步中,你将使用在第 3 步中从 Master 记录的二进制日志坐标,来告诉 slave 从何处开始复制。
连接到 Slave 容器:
首先,在
mysql-slave容器内打开一个 MySQL shell。docker exec -it mysql-slave mysql -uroot -plab_password配置 Slave 连接到 Master:
现在,你将使用
CHANGE MASTER TO命令来配置复制设置。使用你在第 3 步的SHOW MASTER STATUS中记录的File和Position值。MASTER_HOST是'mysql-master',这之所以有效是因为两个容器都在同一个 Docker 网络上。注意: 将
mysql-bin.000001和位置数字替换为你自己在第 3 步中记录的实际值。如果你没有这些值,可以在新终端中运行docker exec mysql-master mysql -uroot -plab_password -e "SHOW MASTER STATUS;"来获取它们。CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl_user', MASTER_PASSWORD='repl_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=337;此命令使用所有必要信息配置 slave 以连接到 master。
启动 Slave 线程:
最后,运行
START SLAVE命令来启动复制过程。这将启动两个线程:I/O 线程,它从 master 获取二进制日志;SQL 线程,它执行日志中的事件。START SLAVE;现在你可以退出 MySQL shell 了。
exit;
Slave 现在已配置完成,应该正在尝试连接到 master 并复制数据。
验证复制
启动 slave 后,最后一步是验证复制是否正常工作。你将检查 slave 的状态,并确认从 master 复制的数据是否已成功拷贝。
连接到 Slave 服务器:
在
mysql-slave容器上打开一个 MySQL shell。docker exec -it mysql-slave mysql -uroot -plab_password检查 Slave 状态:
监控复制最重要的命令是
SHOW SLAVE STATUS。\G修饰符以垂直格式显示输出,这使得阅读更加方便。SHOW SLAVE STATUS\G在输出中查找以下两行。它们的值都应该是
Yes。Slave_IO_Running: Yes: 这确认 slave 已成功连接到 master 并正在接收二进制日志数据。Slave_SQL_Running: Yes: 这确认 slave 正在成功执行二进制日志中的事件。
另一个重要的字段是
Seconds_Behind_Master。值为0表示 slave 已完全跟上 master。健康状态将类似于此(某些值可能有所不同):
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: mysql-master Master_User: repl_user Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 529 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 699 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Seconds_Behind_Master: 0 ...验证复制的数据:
现在,检查
replication_db数据库及其数据是否已从 master 复制过来。SHOW DATABASES;你应该在列表中看到
replication_db。+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | replication_db | | sys | +--------------------+切换到该数据库并查询
messages表。USE replication_db; SELECT * FROM messages;你在 master 上插入的数据现在应该出现在 slave 上了。
+----+------------------------+ | id | content | +----+------------------------+ | 1 | Hello from the master! | +----+------------------------+ 1 row in set (0.00 sec)这证实了复制正在正常工作。你现在可以退出 MySQL shell 了。
exit;
你已成功使用 Docker 设置并验证了一个基本的 MySQL master-slave 复制环境。
总结
在此次实验中,你学习了使用 Docker 设置 MySQL master-slave 复制的基本步骤。你首先创建了两个独立的 MySQL 容器,一个作为 master,一个作为 slave,并通过 Docker 网络连接它们。你验证了 master 的配置,包括启用了二进制日志和设置了唯一的服务器 ID。然后,你在 master 上创建了一个专用的复制用户,以实现安全连接。在准备好 master 后,你使用 CHANGE MASTER TO 命令配置了 slave 容器,以建立与 master 二进制日志坐标的连接。最后,你通过检查 slave 的状态(使用 SHOW SLAVE STATUS)并确认测试数据已正确同步,来验证了复制的成功。本次实验为你提供了配置、管理和验证实际 MySQL 复制设置所需的基本技能。



