主从复制
- 一、概述
- 二、作用
- 🎈 场景示例
- 🎈 综合示例
- 三、原理
- 🎈 主从复制基本原则
- 🎈 主从复制存在的问题
- 四、一主一从架构搭建
- 🌱准备工作
- 🌞步骤
- 1. 配置主库(Master)
- 2. 配置从库(Slave)
- 3. 验证主从同步状态
- 4. 故障排查
- 五、同步数据一致性问题
- 1. 主从同步的要求
- 2. 主从同步延迟问题
- (1)概述
- (2)延迟原因
- (3)优化措施
- 3. 复制模式详解
- Ⅰ. 异步复制
- Ⅱ. 半同步复制
- 🌞 配置步骤
- Ⅲ. GTID(全局事务标识符)复制
- 🌞 配置步骤
- 🌞 GTID 复制过程
- 4. 解决数据一致性问题
一、概述
MySQL 主从复制
是一种 用于实现数据库高可用性
和负载均衡
的机制,它允许一个 MySQL 主服务器
(主库
)将数据同步到一个或多个从服务器
(从库
)。这个过程可以实时或近实时进行,主要用于 提高系统的 读取性能、故障转移 和 数据备份。
二、作用
MySQ 主从复制
(Master-Slave Replication)是一种用于 在多个数据库服务器之间同步数据的技术
。它的作用对于保障数据安全
、提升系统性能
、实现高可用性
等方面都有着重要意义。以下是对 MySQL
主从复制作用的详细阐述:
1. 数据备份与容灾
-
实时数据备份:主从复制可以将主服务器的数据实时复制到从服务器,形成数据的冗余备份。
-
容灾恢复:当主服务器发生故障、数据损坏或丢失时,可以迅速从从服务器恢复数据,减少业务中断时间。
-
提高数据可靠性:通过在不同物理位置部署从服务器,防范单点故障,提高系统的容灾能力。
2. 读写分离与负载均衡
-
读写分离:将
写操作
(INSERT、UPDATE、DELETE)集中在主服务器
,读操作
(SELECT)分散到从服务器
,减轻主服务器
的负载。 -
提升并发性能:
从服务器
可以同时处理大量的读
请求,提升系统的并发处理能力。 -
扩展性强:可以根据业务需求增加
从服务器
数量,实现系统的水平扩展。
总结:
MySQL 主从复制在现代数据库架构中扮演着关键角色
,它通过数据同步
和分布式部署
,满足了大型系统对高性能、高可用性和数据安全的需求
。具体作用包括:
保障数据安全与高可用性
:通过实时备份和容灾恢复,提高系统的容错能力。提升系统性能与扩展性
:实现读写分离和负载均衡,支持高并发访问和系统水平扩展。支持业务持续发展
:为数据分析、报表生成、地理分布式部署等提供技术支持,助力业务增长。
通过合理地配置和使用主从复制,企业可以构建一个高效、稳定且可扩展的数据库系统,更好地支撑业务应用的运行和发展。
🎈 场景示例
🎈 综合示例
示例:全球电商平台的综合应用
假设你是一家全球电商平台的数据库架构师,需要设计一个
高可用
、高性能
、可扩展
的数据库系统。这个平台面临以下挑战和需求:
全球用户访问
:用户遍布全球,需要快速访问网站,降低网络延迟。
高并发读写
:每日处理大量的商品浏览(读操作)和订单交易(写操作)。
数据安全与容灾
:保障交易数据安全,防止数据丢失,能够快速恢复故障。
复杂数据分析
:业务部门需要实时的销售统计、用户行为分析等。
系统维护与升级
:在不影响业务的情况下,进行数据库的维护和升级。
开发与测试环境
:开发团队需要真实的数据环境进行测试,避免影响生产环境。
权限管理与安全
:保护用户敏感信息,防止未经授权的访问和操作。
提高容错能力
:防止单点故障,确保系统的高可用性。
为满足上述需求,采用 MySQL
主从复制 技术,设计如下架构:
总结
通过上述架构设计,MySQL 主从复制
在这个全球电商平台中发挥了以下综合作用:
保障数据安全与高可用性
:实现了实时数据备份和快速容灾恢复,防止数据丢失。提升系统性能与用户体验
:读写分离和地理分布式部署,满足了高并发和低延迟的需求。支持业务持续发展
:专用的从库用于数据分析和开发测试,助力业务优化和创新。降低运营风险
:通过系统维护与升级策略,减少了对业务的影响,提高了系统的稳定性。增强系统容错性
:多从库和备用主库的部署,提高了系统的容错能力,防止单点故障。强化安全与合规
:严格的权限管理和数据保护措施,保障了用户信息的安全。
这个综合示例展示了
MySQL 主从复制
如何在一个复杂的业务场景中,充分发挥其多方面的作用,满足企业在性能、可用性、安全性和可扩展性等方面的需求。
三、原理
MySQL主从复制
是一种将主数据库
的数据和操作复制到一个或多个从数据库
的机制,用于实现数据的 同步、读写分离和高可用性。
关键组件
主库(Master
):
- 二进制日志(Binary Log):记录所有数据修改操作的日志文件。
- 日志转储线程(Dump Thread):与从库的I/O线程通信,发送二进制日志。
从库(Slave)
:
- I/O线程:负责从主库读取二进制日志并写入中继日志。
- 中继日志(Relay Log):从库保存的来自主库的日志副本。
- SQL线程:读取中继日志并执行其中的事件,更新从库数据。
复制流程详解
:
1、主库记录二进制日志(Binary Log):
主库
在执行数据修改操作(如INSERT
、UPDATE
、DELETE
)时,会将这些变更以事件的形式记录到二进制日志
中。二进制日志
是按顺序记录的,包含了所有对数据库的更改操作。
2、从库的I/O线程读取二进制日志并写入中继日志(Relay Log):
从库
启动一个I/O
线程,连接到主库
并请求发送新的二进制日志
内容。主库
的日志转储线程
(Dump Thread
)将二进制日志
发送给从库的I/O线程。从库
的I/O
线程接收这些日志事件并写入自己的中继日志
。
3、从库的SQL线程读取并执行中继日志中的事件:
从库
的SQL
线程读取中继日志
中的事件,按顺序在从库
上执行,重放主库
的操作。- 通过执行这些事件,
从库
的数据状态与主库
保持一致。
🎈 主从复制基本原则
- 每个
slave
只有一个maser
- 每个
slave
只能有一个唯一的服务器ID
- 每个
master
可以有多个slave
🎈 主从复制存在的问题
四、一主一从架构搭建
🌱准备工作
- 准备两台虚拟机
参考
虚拟机克隆- 每台虚拟机安装好
MySQL
(以MySQL8.0
为例)
注意:
MySQL
使用UUID
来唯一标识每个服务器,以便保证主从复制
过程中数据的唯一性
和一致性
。克隆虚拟机的MySQL server
的UUID
和被克隆机是相同的,一定要修改一下,否则可能报如下错误:
Last_IO_Error: Fatal error: The slave I/O thread stops
because master and slave have equal MySQL server UUIDs;
these UUIDs must be different for replication to work.
- 首先查看
克隆机 / 被克隆机
的server_uuid
是否相同
SELECT @@server_uuid;
- 修改克隆机的
server_uuid
,然后重启MySQL
服务器
# 通常,server_uuid存储在 MySQL 数据目录中的auto.cnf文件中
vim /var/lib/mysql/auto.cnf
# 重启 MySQL 服务器
systemctl restart mysqld
🌞步骤
1. 配置主库(Master)
(1)修改主库的配置文件
- 首先在主库的
my.cnf
或my.ini
配置文件中进行修改,生成支持二进制日志
(binary log
)和唯一的服务器ID
,这些是主从同步的基础。binlog-format
不是必加项
binlog_format
参数含义参考 Mysql高级篇(下)——日志---------4、二进制日志(Binary Log)
[mysqld]
server-id=1 # 主库的服务器ID,必须唯一
log-bin=mysql-bin # 开启二进制日志,文件名可选
binlog-format=ROW # (可选,不指定默认 STATEMENT )使用行级复制(推荐)
(2)创建用于复制的用户
- 登录到
MySQL主库
中,创建一个专门的用户供从库
使用,来进行复制操作。
# 创建用户
CREATE USER '用户名'@'%' IDENTIFIED BY '用户密码';
# 给用户赋予 '复制' 的权限
GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%';
# 此语句必须执行,否则报错 “2059 - Authentication plugin 'caching_sha2_password' cannot be loaded。。。”
alter user '用户名'@'%' identified with mysql_native_password by 'mysql数据库登录密码';
# 刷新权限
FLUSH PRIVILEGES;
MySQL连接服务器认证报错:“2059” 参考
MySQL:2059
(3)获取主库的二进制日志位置
- 锁定
主库
以防止数据变化,并获取当前的二进制日志
文件名和位置。执行以下命令:
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
结果类似如下,记录 File
和 Position
,以便配置从库
:
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 154 | | |
+------------------+----------+--------------+------------------+
解锁主库:
UNLOCK TABLES;
2. 配置从库(Slave)
(1)修改从库的配置文件
- 在
从库
的MySQL
配置文件my.cnf
中进行必要的配置,确保其有唯一的服务器 ID
并启用中继日志
。
[mysqld]
server-id=2 # 从库的服务器ID,确保唯一
relay-log=relay-bin # 启用中继日志(用于接收主库的二进制日志)
(2)连接到主库并启动复制
- 在
从库
中,通过以下步骤来指定主库的信息并启动复制:
CHANGE MASTER TO
MASTER_HOST='主库的IP地址', # 主库的IP地址
MASTER_USER='replica_user', # 复制用户
MASTER_PASSWORD='replica_password', # 复制用户的密码
MASTER_LOG_FILE='mysql-bin.000001', # 主库的二进制日志文件名
MASTER_LOG_POS=154; # 主库的二进制日志位置
然后启动从库
的复制进程:
START SLAVE;
3. 验证主从同步状态
- 通过以下命令检查
从库
是否成功与主库
同步:
SHOW SLAVE STATUS\G;
类似以下的输出:
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 主库的IP地址
Master_User: replica_user
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 12345
Relay_Master_Log_File: mysql-bin.000001
Exec_Master_Log_Pos: 12345
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
在结果中,确保以下字段显示正常:
Slave_IO_Running
和Slave_SQL_Running
都应该显示Yes
,表示 主从同步正常运行。Master_Log_File
和Exec_Master_Log_Pos
应与主库
上的二进制日志状态 一致。
4. 故障排查
如果复制进程没有正确启动,SHOW SLAVE STATUS
会显示详细的错误信息。常见问题包括:
Last_IO_Error
或Last_SQL_Error
表示IO
或SQL
线程的问题,可以通过重启
复制进程来修复:- 使用
RESET SLAVE;
重启命令 可以删除之前存在的中继日志
STOP SLAVE;
START SLAVE; # 或执行 RESET SLAVE;
小结
主库
配置:开启二进制日志
,设置唯一server-id
,并创建复制用户。从库
配置:设置唯一server-id
,连接到主库,启动复制。验证
:使用SHOW SLAVE STATUS\G
确认同步状态。
这个流程可以用于搭建一主一从的 MySQL 主从复制架构,实现主从同步并确保从库实时更新主库的数据变化。
五、同步数据一致性问题
1. 主从同步的要求
在工作中遇到数据库调优时,使用读写分离的策略,但是读写分离前提就是
主从复制
,此时就会遇到数据同步
问题,主从数据同步
的基本要求如下
读库
与写库
的数据最终一致(最终
一致)写数据
必须写到写库
读数据
必须到读库
2. 主从同步延迟问题
(1)概述
MySQL 主从同步
中的延迟问题
是指从数据库
(Slave
) 滞后于 主数据库
(Master
)的情况,即从数据库
没有及时跟上主数据库
的更新。这种延迟问题可能 会导致数据查询不一致,从而影响系统的性能和数据实时性。
(2)延迟原因
(3)优化措施
[mysqld]
slave_parallel_workers=4
slave_parallel_type=LOGICAL_CLOCK
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
3. 复制模式详解
MySQL 复制模式
可以通过配置不同的复制方式来提高数据一致性,主要有异步复制
、半同步复制
和基于GTID(全局事务标识符)
的复制模式。我们将通过代码示例详细解释这些复制模式的配置和使用,并探讨它们如何在MySQL 主从复制
中解决数据一致性问题。
Ⅰ. 异步复制
异步复制 是 MySQL
默认的复制模式。它的优点是主数据库(Master)
不会等待从数据库(Slave)
确认就能继续处理其他事务,但这种模式容易导致数据不一致,特别是在主数据库
宕机的情况下,未同步的事务会丢失。
🌞 配置步骤 参考上述
一主一从架构搭建步骤
Ⅱ. 半同步复制
半同步复制(Semi-Synchronous Replication)是为了解决异步复制
带来的数据不一致
问题。在这种模式下,主数据库
提交事务时会等待至少一个从数据库确认收到该事务的二进制日志
,从而减少数据丢失的风险。
🌞 配置步骤
1、在主数据库上安装并启用半同步插件:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
2、在从数据库上安装并启用半同步插件:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
3、配置从数据库连接主数据库并启动复制: 和异步复制类似,配置从数据库连接:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='replica_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1234;
START SLAVE;
Ⅲ. GTID(全局事务标识符)复制
GTID 复制
(Global Transaction Identifiers)是一种 基于全局事务 ID 的复制模式。每个事务在主数据库
提交时都会分配一个唯一的GTID
,主从数据库
通过GTID
来确保复制的一致性。GTID
可以简化复制管理并提高数据一致性。
🌞 配置步骤
1. 在主数据库
和从数据库
上启用 GTID 模式
: 在主数据库
和从数据库
的配置文件中都启用 GTID
:
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=ON
log_slave_updates=ON
2. 在主数据库上创建复制用户: 与异步复制类似,创建一个用于复制的用户:
# 创建用户
CREATE USER '用户名'@'%' IDENTIFIED BY '用户密码';
# 给用户赋予 '复制' 的权限
GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%';
# 此语句必须执行,否则报错 “2059 - Authentication plugin 'caching_sha2_password' cannot be loaded。。。”
alter user '用户名'@'%' identified with mysql_native_password by 'mysql数据库登录密码';
# 刷新权限
FLUSH PRIVILEGES;
MySQL连接服务器认证报错:“2059” 参考
MySQL:2059
3. 在从数据库上配置主从复制: 使用 GTID 复制时,不需要指定二进制日志文件和位置,直接通过 GTID 来控制复制:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='replica_user',
MASTER_PASSWORD='password',
MASTER_AUTO_POSITION=1;
START SLAVE;
🌞 GTID 复制过程
假设
主数据库
中发生了崩溃,我们需要将某个从数据库
提升为新的主数据库
。如果没有使用GTID 模式
,则需要手动查找崩溃时的二进制日志
文件和位置,确保从库
能从正确的地方开始复制。而在GTID 模式
下,从库直接基于GTID
进行复制和故障恢复,确保所有事务在主从数据库
之间保持一致。
例如,当主库
崩溃后,提升从库
为主库
的步骤:
1. 停止从库
的复制:
STOP SLAVE;
2. 将从库
提升为主库
并接受新的写入操作:
RESET MASTER;
3. 重新配置其他从库
连接到新的主库
:
CHANGE MASTER TO MASTER_HOST='new_master_ip', MASTER_AUTO_POSITION=1;
START SLAVE;
4. 解决数据一致性问题
在 MySQL 主从复制
中,数据一致性问题指的是主数据库
(Master)和从数据库
(Slave)在数据同步时可能出现的数据不一致情况。虽然 MySQL
提供了复制机制,但由于异步复制的特性、网络、硬件差异等原因,可能会导致主从数据不一致。为了解决数据一致性问题,可以采取以下措施:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
mysqldump -u root -p --all-databases --single-transaction --flush-logs --master-data=2 > dump.sql
[mysqld]
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
pt-table-checksum --replicate=percona.checksums --databases=mydb --host=master_ip
pt-table-sync --execute --replicate percona.checksums --databases=mydb --host=master_ip
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON