为已有 MySQL 数据库添加从库

本文最后更新于 1 分钟前,文中所描述的信息可能已发生改变。

在实际生产环境中,我们经常需要为已经运行中的 MySQL 数据库添加从库。本文将详细介绍如何在不影响主库正常运行的情况下,安全地添加从库。

环境准备

  • 主服务器:已运行的 MySQL 数据库
  • 从服务器:新安装的 MySQL 服务器
  • 操作系统:Linux/Unix
  • 确保主从服务器网络互通

主库配置

  1. 检查主库是否已开启二进制日志:
sql
SHOW VARIABLES LIKE 'log_bin';

如果未开启,需要修改主库配置文件 my.cnf

ini
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
  1. 创建用于复制的用户(如果尚未创建):
sql
CREATE USER 'repl'@'%' IDENTIFIED BY 'your_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
  1. 记录主库当前状态:
sql
SHOW MASTER STATUS;

记录下 File 和 Position 的值,这些将在配置从库时使用。

从库配置

  1. 安装 MySQL 服务器(如果尚未安装):
bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install mysql-server

# CentOS/RHEL
sudo yum install mysql-server
  1. 修改从库配置文件 my.cnf
ini
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
log_bin = mysql-bin
read_only = 1
  1. 重启从库 MySQL 服务:
bash
sudo systemctl restart mysql

数据同步方式一:使用 mysqldump

  1. 在主库上创建数据快照:
bash
# 锁定所有表
FLUSH TABLES WITH READ LOCK;

# 记录当前二进制日志位置
SHOW MASTER STATUS;

# 导出数据
mysqldump -u root -p --all-databases --master-data=2 > backup.sql

# 解锁表
UNLOCK TABLES;
  1. 将备份文件传输到从库:
bash
scp backup.sql user@slave_server:/path/to/backup.sql
  1. 在从库上导入数据:
bash
mysql -u root -p < backup.sql
  1. 配置从库连接到主库:
sql
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='your_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=position;
  1. 启动从库复制:
sql
START SLAVE;
  1. 检查从库状态:
sql
SHOW SLAVE STATUS\G

数据同步方式二:复制数据文件

对于大型数据库,使用 mysqldump 可能会导致长时间的备份过程和服务中断。另一种方法是直接复制 MySQL 数据文件:

  1. 确保主库和从库的 MySQL 版本完全相同

  2. 停止主库上的 MySQL 服务:

bash
sudo systemctl stop mysql
  1. 复制数据文件:

    首先找到 MySQL 数据目录:

bash
mysql -u root -p -e "SELECT @@datadir;"
  1. 复制数据文件到从库:
bash
# 在主库上使用 rsync 通过 SSH 传输数据文件(保留权限和属性)
sudo rsync -avzP --delete /var/lib/mysql/ user@slave_server:/path/to/mysql_data_temp/

# 在从库上
sudo systemctl stop mysql
sudo mv /var/lib/mysql /var/lib/mysql.bak  # 备份原数据目录
sudo mkdir -p /var/lib/mysql
sudo rsync -avzP /path/to/mysql_data_temp/ /var/lib/mysql/
sudo chown -R mysql:mysql /var/lib/mysql  # 确保权限正确

或者使用 tar 通过 SSH 流式传输(不需要中间存储):

bash
# 在主库上,通过 SSH 流式传输并在从库上直接解压
sudo tar czf - /var/lib/mysql | ssh user@slave_server "sudo tar xzf - -C /"

# 在从库上确保权限正确
sudo chown -R mysql:mysql /var/lib/mysql
  1. 修改从库的 server-id:
bash
# 编辑从库数据目录中的 auto.cnf 文件
sudo nano /var/lib/mysql/auto.cnf

修改 server-uuid 值,确保与主库不同。

  1. 启动主库和从库的 MySQL 服务:
bash
# 在主库上
sudo systemctl start mysql

# 在从库上
sudo systemctl start mysql
  1. 在主库上记录当前的二进制日志位置:
sql
SHOW MASTER STATUS;
  1. 在从库上配置主从复制:
sql
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='your_password',
MASTER_LOG_FILE='记录的日志文件名',
MASTER_LOG_POS=记录的位置;

START SLAVE;
  1. 检查从库状态:
sql
SHOW SLAVE STATUS\G

确保 Slave_IO_Running 和 Slave_SQL_Running 都显示为 "Yes"。

验证配置

  1. 在主库上创建测试数据:
sql
CREATE DATABASE test_sync;
USE test_sync;
CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(50));
INSERT INTO test_table VALUES (1, 'test');
  1. 在从库上验证数据是否同步:
sql
USE test_sync;
SELECT * FROM test_table;

常见问题解决

  1. 如果从库状态显示错误,检查:

    • 网络连接是否正常
    • 主从服务器的 server-id 是否唯一
    • 用户名和密码是否正确
    • 主库的防火墙设置
  2. 如果数据同步出现问题:

    sql
    STOP SLAVE;
    RESET SLAVE;
    # 重新配置从库
  3. 使用数据文件复制方法时的常见问题:

    • 权限不足:确保数据目录的所有权正确
    • 版本不匹配:确保主从 MySQL 版本完全一致
    • UUID 冲突:确保修改了从库的 server-uuid
    • SELinux 问题:如果使用 SELinux,可能需要重新标记文件
    • rsync 传输问题:确保两台服务器上都安装了 rsync,且 SSH 连接正常

注意事项

  1. 确保主从库的 MySQL 版本兼容
  2. 建议在业务低峰期进行配置
  3. 配置完成后定期监控主从复制状态
  4. 建议配置适当的监控告警机制
  5. 考虑配置延迟复制,避免从库负载过高
  6. 数据文件复制法需要停止主库服务,不适用于要求高可用的环境
  7. 对于非常大的数据库,可以考虑使用 Xtrabackup 等工具进行热备份
  8. 使用 rsync 或 tar+ssh 方式传输数据文件可以保留文件权限,而 scp 不能

总结

为已有数据库添加从库是一个需要谨慎操作的过程。本文介绍了两种主要的数据同步方法:

  • mysqldump 方法:适用于中小型数据库,操作简单
  • 数据文件复制方法:适用于大型数据库,可以减少传输时间

通过选择合适的方法,您可以:

  • 安全地配置主从复制
  • 确保数据一致性
  • 最小化对主库的影响
  • 实现数据库的高可用性

记得在配置完成后进行充分的测试和监控,确保复制正常运行。

API接口安全加密详解:四种关键防护模式全面分析
MySQL 主从配置指南