MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

MariaDB复制配置实战指南

2024-02-166.6k 阅读

MariaDB 复制基础概念

MariaDB 复制是一种数据同步机制,它允许将一个 MariaDB 数据库服务器(称为主服务器,Master)的数据更改复制到一个或多个其他 MariaDB 数据库服务器(称为从服务器,Slave)。这种机制在很多场景下都非常有用,比如提高系统的可用性、分担读负载以及数据备份等。

在 MariaDB 复制过程中,主服务器记录所有的数据更改操作到二进制日志(Binary Log)中。从服务器通过 I/O 线程连接到主服务器,读取主服务器的二进制日志,并将这些日志记录写到自己的中继日志(Relay Log)中。然后,从服务器的 SQL 线程读取中继日志,将其中记录的操作应用到从服务器的数据库,从而保持与主服务器的数据同步。

环境准备

在开始配置 MariaDB 复制之前,我们需要准备以下环境:

  1. 操作系统:建议使用 Linux 系统,本指南以 CentOS 7 为例。
  2. 安装 MariaDB:确保在主服务器和从服务器上都安装了 MariaDB。可以通过以下命令在 CentOS 7 上安装 MariaDB:
sudo yum install mariadb-server mariadb
  1. 网络配置:主服务器和从服务器之间需要能够相互通信,确保相应的端口(默认为 3306)没有被防火墙阻挡。可以通过以下命令在 CentOS 7 上开放 3306 端口:
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload

主服务器配置

  1. 编辑 MariaDB 配置文件:打开 MariaDB 的配置文件,通常位于 /etc/my.cnf。在 [mysqld] 部分添加或修改以下配置:
[mysqld]
log-bin=mysql-bin
server-id=1
  • log-bin=mysql-bin:启用二进制日志记录,mysql-bin 是日志文件的前缀。
  • server-id=1:设置服务器的唯一标识符,在整个复制环境中,每个服务器的 server-id 必须不同。
  1. 重启 MariaDB 服务:保存配置文件后,重启 MariaDB 服务使配置生效:
sudo systemctl restart mariadb
  1. 创建复制用户:登录到 MariaDB 数据库,创建一个用于从服务器连接主服务器进行复制的用户。例如:
CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;

这里创建了一个名为 replication_user 的用户,允许其从任何主机连接,密码为 password,并授予其复制从服务器所需的权限。

  1. 获取主服务器状态:执行以下命令获取主服务器的二进制日志文件名和位置:
SHOW MASTER STATUS;

输出结果类似如下:

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

记录下 FilePosition 的值,后续配置从服务器时会用到。

从服务器配置

  1. 编辑 MariaDB 配置文件:同样在从服务器上打开 /etc/my.cnf 文件,在 [mysqld] 部分添加或修改以下配置:
[mysqld]
server-id=2

这里设置 server-id=2,确保与主服务器的 server-id 不同。

  1. 重启 MariaDB 服务:保存配置文件后,重启 MariaDB 服务:
sudo systemctl restart mariadb
  1. 配置从服务器连接主服务器:登录到从服务器的 MariaDB 数据库,执行以下命令配置与主服务器的连接:
CHANGE MASTER TO
    MASTER_HOST='master_ip_address',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=154;
  • MASTER_HOST:主服务器的 IP 地址。
  • MASTER_USER:之前在主服务器创建的复制用户。
  • MASTER_PASSWORD:该复制用户的密码。
  • MASTER_LOG_FILEMASTER_LOG_POS:主服务器 SHOW MASTER STATUS 命令输出的 FilePosition 值。
  1. 启动从服务器复制:执行以下命令启动从服务器的复制:
START SLAVE;
  1. 检查从服务器状态:执行以下命令检查从服务器的复制状态:
SHOW SLAVE STATUS \G;

重点关注以下两个参数:

  • Slave_IO_Running: Yes:表示 I/O 线程正在运行,从服务器正在从主服务器读取二进制日志。
  • Slave_SQL_Running: Yes:表示 SQL 线程正在运行,从服务器正在将中继日志中的操作应用到数据库。

如果这两个参数都为 Yes,并且 Seconds_Behind_Master 的值为 0 或接近 0,则表示复制配置成功,从服务器与主服务器的数据同步正常。

常见问题及解决方法

  1. 复制延迟:如果 Seconds_Behind_Master 的值较大,说明从服务器存在复制延迟。可能的原因及解决方法如下:
  • 网络问题:检查主服务器和从服务器之间的网络连接,确保网络稳定且带宽充足。可以使用 pingtraceroute 命令进行网络测试。
  • 从服务器负载过高:查看从服务器的系统资源使用情况,如 CPU、内存、磁盘 I/O 等。如果负载过高,可以考虑优化从服务器的配置或分担负载。
  • 大事务:主服务器上的大事务可能导致从服务器复制延迟。尽量避免在主服务器上执行长时间运行的事务。
  1. I/O 线程或 SQL 线程停止:如果 Slave_IO_RunningSlave_SQL_RunningNo,可以查看错误日志(通常位于 /var/log/mariadb/mariadb.log)获取具体的错误信息。常见的错误原因及解决方法如下:
  • 权限问题:确保复制用户具有正确的权限。可以重新检查并授予权限。
  • 网络连接问题:检查主服务器和从服务器之间的网络连接是否正常。
  • 中继日志损坏:如果中继日志损坏,可以尝试重置从服务器复制配置,重新配置从服务器连接主服务器并启动复制。
  1. 主从数据不一致:在某些情况下,可能会出现主从数据不一致的问题。可以通过以下方法进行排查和解决:
  • 数据校验:使用工具如 pt-table-checksum 来检查主从服务器之间的数据一致性。
  • 手动同步:如果发现少量数据不一致,可以手动在从服务器上执行相应的 SQL 语句来同步数据。但在操作之前,需要确保主服务器的数据状态稳定,避免在同步过程中主服务器又有新的数据更改。

基于 GTID 的复制配置

除了传统的基于日志文件和位置的复制方式,MariaDB 还支持基于全局事务标识符(GTID,Global Transaction Identifier)的复制。GTID 是一个全局唯一的标识符,用于标识每个事务。基于 GTID 的复制相比传统方式更加简单和可靠。

  1. 主服务器配置
  • 编辑 my.cnf 文件,在 [mysqld] 部分添加或修改以下配置:
[mysqld]
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce_gtid_consistency=ON
  • 重启 MariaDB 服务:
sudo systemctl restart mariadb
  • 创建复制用户,与传统方式相同:
CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;
  1. 从服务器配置
  • 编辑 my.cnf 文件,在 [mysqld] 部分添加或修改以下配置:
[mysqld]
server-id=2
gtid_mode=ON
enforce_gtid_consistency=ON
  • 重启 MariaDB 服务:
sudo systemctl restart mariadb
  • 配置从服务器连接主服务器:
CHANGE MASTER TO
    MASTER_HOST='master_ip_address',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='password',
    MASTER_AUTO_POSITION=1;

这里使用 MASTER_AUTO_POSITION=1 来启用基于 GTID 的复制,不需要像传统方式那样指定 MASTER_LOG_FILEMASTER_LOG_POS

  • 启动从服务器复制:
START SLAVE;
  • 检查从服务器状态:
SHOW SLAVE STATUS \G;

同样关注 Slave_IO_RunningSlave_SQL_Running 是否为 Yes,以及 Seconds_Behind_Master 的值。在基于 GTID 的复制中,还可以查看 Retrieved_Gtid_SetExecuted_Gtid_Set,如果它们一致,说明复制正常。

多主复制配置

在某些场景下,可能需要配置多个主服务器,它们之间相互复制数据。这种配置增加了系统的复杂性,但也提高了系统的可用性和写入性能。

  1. 所有服务器通用配置
  • 在每个服务器的 my.cnf 文件 [mysqld] 部分添加或修改以下配置:
[mysqld]
log-bin=mysql-bin
server-id=X
gtid_mode=ON
enforce_gtid_consistency=ON

这里 X 是每个服务器唯一的 server-id,例如主服务器 1 为 1,主服务器 2 为 2 等。

  • 重启 MariaDB 服务:
sudo systemctl restart mariadb
  1. 配置主服务器之间的复制:以两个主服务器为例,假设主服务器 1 的 IP 为 master1_ip,主服务器 2 的 IP 为 master2_ip
  • 在主服务器 1 上创建用于主服务器 2 连接的复制用户:
CREATE USER'replication_user_master2'@'master2_ip' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user_master2'@'master2_ip';
FLUSH PRIVILEGES;
  • 在主服务器 2 上创建用于主服务器 1 连接的复制用户:
CREATE USER'replication_user_master1'@'master1_ip' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user_master1'@'master1_ip';
FLUSH PRIVILEGES;
  • 在主服务器 1 上配置连接主服务器 2:
CHANGE MASTER TO
    MASTER_HOST='master2_ip',
    MASTER_USER='replication_user_master2',
    MASTER_PASSWORD='password',
    MASTER_AUTO_POSITION=1;
  • 在主服务器 2 上配置连接主服务器 1:
CHANGE MASTER TO
    MASTER_HOST='master1_ip',
    MASTER_USER='replication_user_master1',
    MASTER_PASSWORD='password',
    MASTER_AUTO_POSITION=1;
  • 在两个主服务器上分别启动复制:
START SLAVE;
  • 检查每个主服务器的复制状态:
SHOW SLAVE STATUS \G;

确保 Slave_IO_RunningSlave_SQL_Running 都为 Yes,并且 Seconds_Behind_Master 的值正常。

复制拓扑优化

  1. 读写分离:在主从复制环境中,可以将读操作分发到从服务器,写操作仍然在主服务器执行。这样可以提高系统的读性能。可以使用一些中间件如 MyCAT、MaxScale 等来实现读写分离。以 MyCAT 为例,配置步骤如下:
  • 下载并安装 MyCAT。
  • 编辑 MyCAT 的配置文件,如 server.xmlschema.xml,配置主从服务器的连接信息以及读写分离规则。例如,在 schema.xml 中可以定义:
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
    <table name="*" dataNode="dn1"/>
</schema>
<dataNode name="dn1" dataHost="host1" database="test"/>
<dataHost name="host1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master" url="jdbc:mysql://master_ip:3306" user="root" password="password">
        <readHost host="slave1" url="jdbc:mysql://slave1_ip:3306" user="root" password="password"/>
        <readHost host="slave2" url="jdbc:mysql://slave2_ip:3306" user="root" password="password"/>
    </writeHost>
</dataHost>

这里 balance="3" 表示所有读操作均匀分配到所有从服务器。

  1. 级联复制:在大规模的复制环境中,如果从服务器数量较多,可以采用级联复制的方式。即从服务器不再直接连接主服务器,而是连接其他从服务器进行复制。这样可以减轻主服务器的负载。例如,主服务器连接从服务器 1,从服务器 1 再连接从服务器 2,从服务器 2 连接从服务器 3 等。配置方法与普通的主从复制类似,只是从服务器连接的是其他从服务器的 IP 地址。

  2. 半同步复制:半同步复制是一种增强的复制方式,它确保主服务器在至少一个从服务器接收到并写入二进制日志后才确认事务提交。这可以提高数据的一致性和安全性,但可能会稍微降低系统的写入性能。配置半同步复制步骤如下:

  • 在主服务器和从服务器上安装半同步复制插件:
INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
  • 在主服务器和从服务器的 my.cnf 文件 [mysqld] 部分添加以下配置:
[mysqld]
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_slave_enabled=ON
  • 重启 MariaDB 服务。
  • 在主服务器上设置半同步复制的超时时间(可选):
SET GLOBAL rpl_semi_sync_master_timeout=1000;

这里设置超时时间为 1000 毫秒。

备份与恢复复制环境

  1. 备份主服务器:可以使用 mysqldump 命令备份主服务器的数据,并结合二进制日志进行恢复。例如,备份整个数据库:
mysqldump -uroot -ppassword --all-databases --master-data=2 > master_backup.sql

--master-data=2 选项会在备份文件中记录主服务器的二进制日志文件名和位置,以便恢复时可以从正确的位置继续复制。

  1. 恢复到从服务器:将备份文件传输到从服务器,然后在从服务器上执行以下步骤:
  • 停止 MariaDB 服务:
sudo systemctl stop mariadb
  • 清空从服务器的数据目录(确保数据已备份或不需要保留):
sudo rm -rf /var/lib/mysql/*
  • 恢复备份数据:
mysql -uroot -ppassword < master_backup.sql
  • 配置从服务器连接主服务器,根据备份文件中记录的二进制日志信息,使用 CHANGE MASTER TO 命令配置连接,然后启动从服务器复制。

监控与维护复制环境

  1. 使用 SHOW STATUS 命令:可以使用 SHOW STATUS 命令获取 MariaDB 服务器的各种状态信息,包括复制相关的信息。例如,在主服务器上可以查看 Binlog_Disk_Writes 来了解二进制日志的写入次数,在从服务器上可以查看 Slave_Seconds_Behind_Master 来监控复制延迟。
SHOW STATUS LIKE 'Binlog_Disk_Writes';
SHOW STATUS LIKE 'Slave_Seconds_Behind_Master';
  1. 使用 MariaDB Enterprise Monitor:MariaDB 提供了企业级监控工具 MariaDB Enterprise Monitor,可以全面监控和管理 MariaDB 复制环境。它可以实时显示主从服务器的状态、性能指标、复制延迟等信息,并提供报警功能。

  2. 定期检查与维护:定期检查主从服务器的状态,包括查看错误日志、检查数据一致性、监控系统资源使用情况等。及时处理发现的问题,确保复制环境的稳定运行。例如,可以编写脚本定期执行 SHOW SLAVE STATUS 命令,并检查关键参数,如 Slave_IO_RunningSlave_SQL_Running,如果发现异常则发送邮件通知管理员。

通过以上详细的步骤和说明,您应该能够成功配置、优化、监控和维护 MariaDB 复制环境,满足不同场景下的数据同步和高可用性需求。在实际应用中,根据具体的业务需求和系统架构,灵活选择合适的复制方式和优化策略。