MySQL 复制基础

MySQLBeginner
立即练习

介绍

在本实验中,你将学习 MySQL 复制(replication)的基础知识。复制是一个允许你在多个服务器上维护 MySQL 数据库副本的过程。这通常用于负载均衡、数据备份和高可用性。

你将使用 Docker 创建一个真实的 master-slave 复制设置,包含两个独立的 MySQL 容器。首先,你将启动并验证一个 master 容器,该容器已预先配置并启用了二进制日志(binary logging)。你将在 master 上创建一个特殊的复制用户。然后,你将配置第二个容器作为 slave,将其连接到 master,并验证数据是否正确同步。这种实践方法将帮助你理解管理真实 MySQL 复制环境所涉及的关键步骤。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 86%。获得了学习者 75% 的好评率。

设置 Docker 环境

在第一步中,你将为 master-slave 复制环境设置必要的 Docker 容器。你将创建一个专用的网络并启动两个 MySQL 容器。

  1. 创建 Docker 网络:

    一个专用的网络允许容器通过名称相互通信。创建一个名为 mysql-net 的网络。

    docker network create mysql-net
  2. 启动 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
  3. 启动 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
  4. 等待容器初始化:

    MySQL 容器需要一些时间来初始化。等待大约 15 秒,然后检查容器是否正在运行。

    docker ps
    CONTAINER 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 容器并验证其配置。

  1. 连接到 Master 容器:

    使用 docker execmysql-master 容器内打开一个 MySQL shell。系统会提示你输入密码,密码是 lab_password

    docker exec -it mysql-master mysql -uroot -plab_password
  2. 验证二进制日志和 Server ID:

    看到 mysql> 提示符后,运行以下命令来验证二进制日志是否已启用以及 server ID 是否已正确设置。

    SHOW VARIABLES LIKE 'log_bin';

    输出应显示 log_binON

    +---------------+----+
    | Variable_name | Value |
    +---------------+----+
    | log_bin       | ON |
    +---------------+----+
    1 row in set (0.01 sec)

    接下来,检查 server ID。

    SHOW VARIABLES LIKE 'server_id';

    输出应显示 server_id1

    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | server_id     | 1     |
    +---------------+-------+
    1 row in set (0.00 sec)

    现在你已验证了配置,可以退出 MySQL shell 了。

    exit;

你已成功确认 master 服务器已准备好进行复制。

创建复制用户和测试数据库

slave 服务器需要连接到 master 以读取二进制日志。为了安全起见,最佳实践是为此目的创建一个具有有限权限的专用用户账户。在这一步中,你将创建一个复制用户并填充测试数据库,以观察复制的实际效果。

  1. 连接到 Master 服务器:

    mysql-master 容器内打开一个 MySQL shell。

    docker exec -it mysql-master mysql -uroot -plab_password
  2. 创建复制用户:

    mysql> 提示符下,运行以下命令创建一个名为 repl_user 的用户,密码为 repl_password。slave 将使用此用户进行连接。我们使用 '@'%' 来允许用户从任何主机连接,这包括我们在 Docker 网络上的 slave 容器。

    CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_password';
  3. 授予复制权限:

    新用户需要 REPLICATION SLAVE 权限,该权限允许它从 master 读取二进制日志。

    GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';

    授予权限后,重新加载授权表以立即应用更改。

    FLUSH PRIVILEGES;
  4. 检查 Master 的二进制日志状态:

    在配置 slave 之前,你需要知道 master 二进制日志中 slave 应该开始复制的确切坐标。SHOW MASTER STATUS 命令提供此信息。

    SHOW MASTER STATUS;

    输出将与此类似。记下 FilePosition 的值,因为在下一步中会用到它们。

    +------------------+----------+------------------+--------------------+-------------------+
    | File             | Position | Binlog_Do_DB     | Binlog_Ignore_DB   | Executed_Gtid_Set |
    +------------------+----------+------------------+--------------------+-------------------+
    | mysql-bin.000001 |      337 | replication_db   |                    |                   |
    +------------------+----------+------------------+--------------------+-------------------+
    1 row in set (0.00 sec)
  5. 创建测试表和数据:

    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 从何处开始复制。

  1. 连接到 Slave 容器:

    首先,在 mysql-slave 容器内打开一个 MySQL shell。

    docker exec -it mysql-slave mysql -uroot -plab_password
  2. 配置 Slave 连接到 Master:

    现在,你将使用 CHANGE MASTER TO 命令来配置复制设置。使用你在第 3 步的 SHOW MASTER STATUS 中记录的 FilePosition 值。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。

  3. 启动 Slave 线程:

    最后,运行 START SLAVE 命令来启动复制过程。这将启动两个线程:I/O 线程,它从 master 获取二进制日志;SQL 线程,它执行日志中的事件。

    START SLAVE;

    现在你可以退出 MySQL shell 了。

    exit;

Slave 现在已配置完成,应该正在尝试连接到 master 并复制数据。

验证复制

启动 slave 后,最后一步是验证复制是否正常工作。你将检查 slave 的状态,并确认从 master 复制的数据是否已成功拷贝。

  1. 连接到 Slave 服务器:

    mysql-slave 容器上打开一个 MySQL shell。

    docker exec -it mysql-slave mysql -uroot -plab_password
  2. 检查 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
    ...
  3. 验证复制的数据:

    现在,检查 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 复制设置所需的基本技能。