关系型数据库MySQL(三):主从复制

数据库主从复制

一、主从复制核心概念

定义 :主从复制是一种数据库架构模式,允许一个 MySQL 数据库服务器(主库 )将其数据变更自动复制到一个或多个其他 MySQL 服务器(从库 )。
目的

  • 高可用:主库故障时,从库可接管服务
  • 读写分离:主库处理写操作,从库处理读操作,分担负载
  • 数据备份:从库作为实时备份
  • 数据分析:在从库运行分析任务,避免影响主库性能

二、主从复制工作原理(理论核心)

MySQL 主从复制基于二进制日志(Binary Log) 实现异步复制:

  1. 主库(Master)

    • 开启二进制日志(binlog
    • 所有数据变更(增删改)会以"事件"形式记录到 binlog
    • 从库连接主库后,主库启动一个 Binlog Dump 线程 向从库发送 binlog 内容
  2. 从库(Slave)

    • 开启中继日志(relay log
    • I/O 线程 :连接主库,读取 binlog 并写入本地 relay log
    • SQL 线程 :读取 relay log 并重放其中的 SQL 事件,实现数据同步

关键点

  • 复制是异步的(默认),主库提交事务后立即返回,不等待从库确认
  • 复制单位可以是语句 (Statement-Based)或(Row-Based),后者更可靠

三、OpenEuler 环境准备(运维实操)

1. 环境说明
  • 操作系统:OpenEuler 22.03 LTS
  • MySQL 版本 :8.0.26(通过 dnf 安装)
  • 服务器规划
    • 主库:192.168.1.100
    • 从库:192.168.1.101
2. 安装 MySQL(主从库相同)
bash 复制代码
# 安装MySQL Server
sudo dnf install mysql-server

# 启动服务并设置开机自启
sudo systemctl start mysqld
sudo systemctl enable mysqld

# 获取初始密码(MySQL 8.0默认生成临时密码)
sudo grep 'temporary password' /var/log/mysqld.log
3. 安全初始化(主从库相同)
bash 复制代码
mysql_secure_installation
# 根据提示设置root密码、移除测试库等

四、主库配置(192.168.1.100)

1. 修改配置文件 /etc/my.cnf
ini 复制代码
[mysqld]
server-id = 1             # 唯一ID,主从不能重复
log-bin = mysql-bin       # 开启二进制日志
binlog-format = ROW       # 推荐使用ROW模式
expire_logs_days = 7      # 自动清理7天前的日志
max_binlog_size = 100M    # 单个binlog文件大小
bind-address = 0.0.0.0    # 允许所有IP连接(生产环境建议限制)
2. 重启 MySQL 服务
bash 复制代码
sudo systemctl restart mysqld
3. 创建复制专用账户
sql 复制代码
CREATE USER 'repl'@'192.168.1.101' IDENTIFIED BY 'StrongPass!123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.101';
FLUSH PRIVILEGES;
4. 锁定主库并获取状态信息
sql 复制代码
FLUSH TABLES WITH READ LOCK;  -- 锁定所有表,禁止写入
SHOW MASTER STATUS;           -- 记录File和Position值

输出示例:

复制代码
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |      785 |              |                  |
+------------------+----------+--------------+------------------+
5. 备份主库数据(可选,若从库无数据)
bash 复制代码
mysqldump -u root -p --all-databases --master-data > master_db.sql
6. 解锁主库
sql 复制代码
UNLOCK TABLES;

五、从库配置(192.168.1.101)

1. 修改配置文件 /etc/my.cnf
ini 复制代码
[mysqld]
server-id = 2              # 不同于主库
relay-log = mysql-relay    # 中继日志名称
read_only = ON             # 从库只读(避免误写)
2. 重启 MySQL 服务
bash 复制代码
sudo systemctl restart mysqld
3. 导入主库备份(若已备份)
bash 复制代码
mysql -u root -p < master_db.sql
4. 配置复制链路
sql 复制代码
CHANGE MASTER TO
MASTER_HOST='192.168.1.100',
MASTER_USER='repl',
MASTER_PASSWORD='StrongPass!123',
MASTER_LOG_FILE='mysql-bin.000003', -- 主库SHOW MASTER STATUS的值
MASTER_LOG_POS=785;

START SLAVE; -- 启动复制
5. 检查复制状态
sql 复制代码
SHOW SLAVE STATUS\G

关键指标

  • Slave_IO_Running: Yes(I/O线程正常)
  • Slave_SQL_Running: Yes(SQL线程正常)
  • Seconds_Behind_Master: 0(无延迟)

六、故障排查与运维技巧

1. 常见错误处理
  • I/O 线程错误 (如网络不通):

    sql 复制代码
    STOP SLAVE;
    CHANGE MASTER TO ...; -- 重新配置
    START SLAVE;
  • SQL 线程错误 (如主键冲突):

    sql 复制代码
    STOP SLAVE;
    SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; -- 跳过1个错误事件
    START SLAVE;
2. 延迟监控
sql 复制代码
SHOW SLAVE STATUS\G
# 关注 Seconds_Behind_Master
3. 主从切换(Failover)
  1. 停止主库写入

  2. 提升从库为主库:

    sql 复制代码
    STOP SLAVE;
    RESET SLAVE;
    SET GLOBAL read_only=OFF;
  3. 修改应用连接指向新主库


七、高级主题:GTID 复制(可选)

GTID(Global Transaction Identifier) 简化了复制管理:

ini 复制代码
# 主从库均需配置
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON

配置命令:

sql 复制代码
CHANGE MASTER TO 
MASTER_AUTO_POSITION=1; -- 自动定位同步点

八、总结

通过上述步骤,你已在 OpenEuler 系统上成功搭建 MySQL 主从复制环境。关键要点:

  • 原理:基于 binlog 的异步复制
  • 配置server-idlog-binrelay-log
  • 运维SHOW SLAVE STATUS 监控、GTID 进阶

附录:常用命令速查

sql 复制代码
-- 主库
SHOW MASTER STATUS;
SHOW BINARY LOGS;

-- 从库
SHOW SLAVE STATUS\G
STOP SLAVE;
START SLAVE;
RESET SLAVE ALL; -- 彻底重置复制
相关推荐
a9511416423 小时前
怎么防范通过phpMyAdmin上传WebShell_禁止into outfile权限
jvm·数据库·python
InfinteJustice3 小时前
如何统计SQL分组汇总数据_详解GROUP BY与HAVING用法
jvm·数据库·python
zhangchaoxies3 小时前
如何使用 AWS Lambda 和 Python 获取 EMR 集群的标签列表
jvm·数据库·python
吕源林3 小时前
如何处理SQL插入后的数据一致性校验_使用Checksum比对
jvm·数据库·python
Austindatabases3 小时前
什么int类型里面能插入文字,还不能改字段类型--SQLite 五脏俱全系列 (2)
数据库·sqlite
2301_777599373 小时前
SQL如何实现动态分组统计_使用存储过程与动态SQL
jvm·数据库·python
Shorasul3 小时前
HTML怎么在GeneratePress中精调图片对齐_GP轻量主题CSS覆盖方法
jvm·数据库·python
qq_334563553 小时前
Python开发Flask项目如何部署到云服务器_使用Fabric自动化发布脚本
jvm·数据库·python
试试勇气3 小时前
MySQL--数据类型
数据库·mysql