本文最后更新于 1 分钟前,文中所描述的信息可能已发生改变。
在实际生产环境中,我们经常需要为已经运行中的 MySQL 数据库添加从库。本文将详细介绍如何在不影响主库正常运行的情况下,安全地添加从库。
环境准备
- 主服务器:已运行的 MySQL 数据库
- 从服务器:新安装的 MySQL 服务器
- 操作系统:Linux/Unix
- 确保主从服务器网络互通
主库配置
- 检查主库是否已开启二进制日志:
sql
SHOW VARIABLES LIKE 'log_bin';
如果未开启,需要修改主库配置文件 my.cnf
:
ini
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
- 创建用于复制的用户(如果尚未创建):
sql
CREATE USER 'repl'@'%' IDENTIFIED BY 'your_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
- 记录主库当前状态:
sql
SHOW MASTER STATUS;
记录下 File 和 Position 的值,这些将在配置从库时使用。
从库配置
- 安装 MySQL 服务器(如果尚未安装):
bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install mysql-server
# CentOS/RHEL
sudo yum install mysql-server
- 修改从库配置文件
my.cnf
:
ini
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
log_bin = mysql-bin
read_only = 1
- 重启从库 MySQL 服务:
bash
sudo systemctl restart mysql
数据同步方式一:使用 mysqldump
- 在主库上创建数据快照:
bash
# 锁定所有表
FLUSH TABLES WITH READ LOCK;
# 记录当前二进制日志位置
SHOW MASTER STATUS;
# 导出数据
mysqldump -u root -p --all-databases --master-data=2 > backup.sql
# 解锁表
UNLOCK TABLES;
- 将备份文件传输到从库:
bash
scp backup.sql user@slave_server:/path/to/backup.sql
- 在从库上导入数据:
bash
mysql -u root -p < backup.sql
- 配置从库连接到主库:
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;
- 启动从库复制:
sql
START SLAVE;
- 检查从库状态:
sql
SHOW SLAVE STATUS\G
数据同步方式二:复制数据文件
对于大型数据库,使用 mysqldump 可能会导致长时间的备份过程和服务中断。另一种方法是直接复制 MySQL 数据文件:
确保主库和从库的 MySQL 版本完全相同
停止主库上的 MySQL 服务:
bash
sudo systemctl stop mysql
复制数据文件:
首先找到 MySQL 数据目录:
bash
mysql -u root -p -e "SELECT @@datadir;"
- 复制数据文件到从库:
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
- 修改从库的 server-id:
bash
# 编辑从库数据目录中的 auto.cnf 文件
sudo nano /var/lib/mysql/auto.cnf
修改 server-uuid 值,确保与主库不同。
- 启动主库和从库的 MySQL 服务:
bash
# 在主库上
sudo systemctl start mysql
# 在从库上
sudo systemctl start mysql
- 在主库上记录当前的二进制日志位置:
sql
SHOW MASTER STATUS;
- 在从库上配置主从复制:
sql
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='your_password',
MASTER_LOG_FILE='记录的日志文件名',
MASTER_LOG_POS=记录的位置;
START SLAVE;
- 检查从库状态:
sql
SHOW SLAVE STATUS\G
确保 Slave_IO_Running 和 Slave_SQL_Running 都显示为 "Yes"。
验证配置
- 在主库上创建测试数据:
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');
- 在从库上验证数据是否同步:
sql
USE test_sync;
SELECT * FROM test_table;
常见问题解决
如果从库状态显示错误,检查:
- 网络连接是否正常
- 主从服务器的 server-id 是否唯一
- 用户名和密码是否正确
- 主库的防火墙设置
如果数据同步出现问题:
sqlSTOP SLAVE; RESET SLAVE; # 重新配置从库
使用数据文件复制方法时的常见问题:
- 权限不足:确保数据目录的所有权正确
- 版本不匹配:确保主从 MySQL 版本完全一致
- UUID 冲突:确保修改了从库的 server-uuid
- SELinux 问题:如果使用 SELinux,可能需要重新标记文件
- rsync 传输问题:确保两台服务器上都安装了 rsync,且 SSH 连接正常
注意事项
- 确保主从库的 MySQL 版本兼容
- 建议在业务低峰期进行配置
- 配置完成后定期监控主从复制状态
- 建议配置适当的监控告警机制
- 考虑配置延迟复制,避免从库负载过高
- 数据文件复制法需要停止主库服务,不适用于要求高可用的环境
- 对于非常大的数据库,可以考虑使用 Xtrabackup 等工具进行热备份
- 使用 rsync 或 tar+ssh 方式传输数据文件可以保留文件权限,而 scp 不能
总结
为已有数据库添加从库是一个需要谨慎操作的过程。本文介绍了两种主要的数据同步方法:
- mysqldump 方法:适用于中小型数据库,操作简单
- 数据文件复制方法:适用于大型数据库,可以减少传输时间
通过选择合适的方法,您可以:
- 安全地配置主从复制
- 确保数据一致性
- 最小化对主库的影响
- 实现数据库的高可用性
记得在配置完成后进行充分的测试和监控,确保复制正常运行。