作者:禅与计算机程序设计艺术
1.背景介绍
一、什么是数据库复制?
数据库复制(DB replication)是一个数据管理过程,它将主数据库中的数据(数据或结构)拷贝到一个或多个从数据库中,这样就可以在发生灾难时快速恢复数据库并继续工作,提升数据库可用性。由于从数据库提供实时访问,可以使得应用程序可以在不丢失数据的情况下实时更新数据。另外,当主数据库出现问题时,可以故障转移到从数据库,保证服务连续可用。因此,数据库复制是构建可靠的分布式数据库系统的一个重要组成部分。
二、为什么要用数据库复制?
主要有以下几种原因:
- 数据安全性:通过数据库复制,可以实现主备份和异地多中心部署的数据安全性,防止单点故障。
- 提高可用性:如果主数据库出现故障,可以立即切换到备库,从而保证业务连续性。
- 提高性能:数据库复制可以提高主服务器的读写能力,缓解主服务器的压力;同时也能分担读负载,提高吞吐量和查询响应时间。
- 数据同步:通过数据库复制,可以实现多台数据库间的数据实时同步,可以降低延迟,提高系统整体的稳定性。
三、数据库复制模式及流程
数据库复制一般分为两种模式:
1.异步复制(Synchronous Replication)模式:要求主从数据库间数据完全一致,即每次事务提交后,主库写入数据同时也需通知所有的从库。这个模式下,主库写入数据会产生延迟,有一定的数据延迟风险。比如,在事务提交后,从库数据可能只有部分完成。
2.半同步复制(Semisynchronous Replication)模式:要求主从数据库间数据尽量一致,但不要求每次事务提交都必须通知所有从库。所以,它允许有一定的数据延迟。比如,MySQL InnoDB引擎支持这种模式。
数据库复制的基本流程包括:
1.选取从库:首先需要选择好用于复制的从库。通常情况下,复制不会影响源数据库,所以可以保留源数据库运行。但是,为了避免单点故障,也可以设置两个以上的从库,即使其中某个从库出现故障也能保证正常服务。
2.建立连接:复制需要两个数据库之间的网络连接。配置好网络防火墙和开放端口,让数据库可以相互通信。
3.主从复制协议:由于数据一致性的问题,不同的数据库采用了不同的主从复制协议。MySQL支持的是ROW模式和BINLOG模式,其他数据库也有自己的协议。
4.开启binlog:为了能够将变更记录在从库上,需要对源数据库进行如下设置:
在my.cnf配置文件中,打开binlog功能:
log-bin=mysql-bin #指定binlog文件名为mysql-bin binlog_format=row #指定binlog日志格式为ROW模式 server-id=1 #指定本机server-id,用于识别本机 expire_logs_days=7 #指定过期日志自动删除的时间,默认值为0,表示不自动删除 max_binlog_size=1G #指定每个binlog文件的最大大小,默认值为1G
在源数据库执行flush logs命令,将当前的binlog缓存写入硬盘。
5.实时复制:源数据库接收到的每条SQL语句都会被写入binlog中。
6.应用binlog:当从库连接到源数据库之后,通过重放binlog获取到所有未复制的SQL语句。然后应用这些SQL语句到从库,从而达到主从复制的目的。
四、什么是数据库高可用性架构?
数据库高可用性架构(Database High Availability Architecture)简称为HA,它是指将整个数据库系统设计成多副本架构,其中包括数据库服务器、存储设备以及必要的软硬件环境。数据库服务器之间可以做数据复制,从而确保数据库的高可用性。其目的是应对硬件故障、网络故障等非计划内的情况,使数据库系统始终处于可用状态。数据库高可用性架构还需考虑数据库的容量规划、备份策略、监控告警策略、异地多中心部署等一系列环节。
数据库高可用性架构的几个关键要素如下:
1.冗余机制:确保数据库服务器之间的冗余,包括服务器数量、服务器配置、存储位置等。可以是主从模式,也可以是一主多从模式。
2.自动故障切换:数据库集群由若干个节点构成,当某个节点出现问题时,数据库系统可以自动检测到该节点故障,并将请求转发给其他节点,从而确保数据库的高可用性。
3.故障转移恢复:数据库集群由若干个节点构成,当某个节点出现故障时,可以将其下线,另选取一个节点作为主节点,再重新启动集群,使集群保持在高可用状态。
4.热备份:确保数据库数据的热备份。热备份即在业务低峰期对数据库进行完整备份,以保证数据完整性和可用性。
5.数据同步:确保不同节点的数据同步。数据同步是指不同节点的数据在数据一致性方面的同步。例如,可以基于差异化复制实现数据同步。
2.核心概念与联系
一、Master-Slave模式
Master-Slave模式是一种典型的分布式数据库系统架构。数据库的多个节点组成一个逻辑上的数据库集群。其中有一个节点被指定为主节点(Master),其他节点被指定为从节点(Slaves)。主节点负责处理用户的读取和写入请求,从节点则从主节点上读取数据,并提供给其它节点进行数据分发。Slave节点之间可以做数据复制,确保数据一致性。
二、主从复制模式
在主从复制模式下,主节点负责处理用户的写请求,并将数据更改传播到所有从节点上,从而实现数据共享和同步。所有从节点都以只读的方式接入主节点,只能执行查询和搜索数据,不能修改数据。从节点和主节点之间的同步频率可以根据实际需求进行调整。主从复制模式下,从节点承担着增量备份的角色,可以快速恢复到最新状态,并减少主库的压力。
三、双主复制模式
在双主复制模式下,主节点A负责处理用户的写请求,并将数据更改传播到主节点B上。主节点B再将数据更改传播到所有从节点C上。从节点C承担着双主备份的角色,在主节点故障时可以自动故障转移到从节点C,并继续提供数据服务。
四、多主复制模式
在多主复制模式下,多个主节点分别承担着写请求的处理任务,将数据更改传播到所有从节点上。从节点承担着多主备份的角色,在某个主节点故障时可以自动故障转移到其他主节点,确保数据库的高可用性。
五、全量复制与增量复制
1.全量复制
在全量复制模式下,主节点向从节点发送完整的数据库文件,包括数据表定义信息、数据索引、数据内容等。这种方式存在数据一致性问题,因为可能会导致主节点压力过大。并且在同步过程中,如果主节点宕机,那么无法恢复到之前的状态。
2.增量复制
在增量复制模式下,主节点仅发送自身更新的数据记录。从节点通过保存的binlog日志文件来追踪主节点发送的记录,并将新的数据记录应用到从节点上。这种方式可以提高效率,降低主节点的压力。而且在同步过程中,如果主节点宕机,可以将其损坏的记录同步到从节点上,保证数据完整性。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
一、异步复制
异步复制模式下,数据库维护者保证主从数据完全一致性。
缺点:主库数据更新,将会产生延迟,从库数据更新也有延迟。
优点:数据一致性高,数据同步及时,无延迟风险,适合中小型网站等对一致性要求不高的场景。
1.主从复制流程图
2.配置参数
log-bin=mysql-bin #指定binlog日志路径,注意设置为绝对路径
binlog-format=ROW #指定binlog的格式,支持ROW和MIXED,推荐ROW
server-id=1 #指定唯一ID标识,不能重复,值越大,优先级越高,保证主从关系正确
3.主节点写入binlog
insert into user (name,age) values ('Bob',18);
4.从节点读取binlog并写入relaylog
show binary logs; #查看当前的binlog列表
change master to master_host='192.168.1.100',
master_port=3306,
master_user='root', #主库用户名
master_password='<PASSWORD>', #主库密码
master_log_file='mysql-bin.000001', #指定从哪个binlog文件开始读取
master_log_pos=4; #指定从第几个字节开始读取
start slave; #启动从库的IO线程
5.从节点relaylog写入主库
slave IO thread: SQL Thread #从节点IO线程开始接收binlog事件
Query event: table `test`.`user`;; #过滤操作类型为table的event
Relay log creation event:
... #记录日志格式为ROW模式时,会生成一条日志,包含sql语句的执行结果
File position: 4 #日志所在的位置
Event size: 73 #日志大小
Read from relay log file completed on'mysql-bin.000001'
6.从节点提交事务
COMMIT; #提交事务
7.从节点写入relaylog
UPDATE user SET age = 19 WHERE name = 'Bob'; #更新数据
DELETE FROM user WHERE name = 'Tom'; #删除数据
BEGIN; #事务开始
二、半同步复制
半同步复制模式下,主库必须等待从库的数据落后于自己的数据才可以提交事务。对于读多写少的应用场景,可以有效缓解数据库写端压力。
缺点:延迟较高,不能保证强一致性。
优点:支持读写分离,主库负载下降,适合于对一致性要求高的场景。
1.主从复制流程图
2.配置参数
log-bin=mysql-bin #指定binlog日志路径,注意设置为绝对路径
binlog_format=ROW #指定binlog的格式,支持ROW和MIXED,推荐ROW
server-id=1 #指定唯一ID标识,不能重复,值越大,优先级越高,保证主从关系正确
semi_sync_master_wait_for_slave_count=1 #指定等待从库数量
3.主节点写入binlog
insert into user (name,age) values ('Bob',18);
4.从节点读取binlog并写入relaylog
show binary logs; #查看当前的binlog列表
change master to master_host='192.168.1.100',
master_port=3306,
master_user='root', #主库用户名
master_password='passwd', #主库密码
master_log_file='mysql-bin.000001', #指定从哪个binlog文件开始读取
master_log_pos=4; #指定从第几个字节开始读取
start slave; #启动从库的IO线程
5.从节点relaylog写入主库
slave IO thread: SQL Thread #从节点IO线程开始接收binlog事件
Query event: table `test`.`user`;; #过滤操作类型为table的event
Relay log creation event:
... #记录日志格式为ROW模式时,会生成一条日志,包含sql语句的执行结果
File position: 4 #日志所在的位置
Event size: 73 #日志大小
Read from relay log file completed on'mysql-bin.000001'
6.主库等待半同步(等待从库提交事务成功)
Waiting for slave SQL thread to update position to execute event at the moment the next statement is sent to it.
7.主库提交事务
COMMIT; #提交事务
8.从库提交事务成功
SQL Thread waiting for next event in relay log to be applied... #SQL线程正在等待主库发送的下一个事件
9.从库提交事务失败
ERROR 1054 (42S22): Unknown column 'age' in 'field list' #从库提交事务失败,因为还没等到主库确认提交
三、并行复制(Parallel Copying)
并行复制模式下,主库同时向多个从库进行数据复制。这种模式下,数据复制可以在主库和从库间同时进行。
优点:数据复制在主库和从库间同时进行,速度快,可有效缓解主库的压力。
缺点:不能保证强一致性,在数据复制过程中,会产生延迟。
1.主从复制流程图
2.配置参数
log-bin=mysql-bin #指定binlog日志路径,注意设置为绝对路径
binlog_format=ROW #指定binlog的格式,支持ROW和MIXED,推荐ROW
server-id=1 #指定唯一ID标识,不能重复,值越大,优先级越高,保证主从关系正确
replicate-do-db="test" #指定复制哪些数据库
replicate-do-table="user" #指定复制哪些表
slave-parallel-type=LOGICAL_CLOCK #指定复制的日志模式,默认是物理时钟模式,不建议使用
slave-preserve-commit-order=ON #指定按照事务顺序提交,默认为OFF,不建议使用
slave-priority=100 #指定复制优先级,默认值为100,数字越大优先级越高
3.主节点写入binlog
insert into user (name,age) values ('Bob',18);
4.从节点读取binlog并写入relaylog
show binary logs; #查看当前的binlog列表
change master to master_host='192.168.1.100',
master_port=3306,
master_user='root', #主库用户名
master_password='<PASSWORD>', #主库密码
master_log_file='mysql-bin.000001', #指定从哪个binlog文件开始读取
master_log_pos=4; #指定从第几个字节开始读取
start slave; #启动从库的IO线程
5.从节点relaylog写入主库
slave IO thread: SQL Thread #从节点IO线程开始接收binlog事件
Query event: table `test`.`user`;; #过滤操作类型为table的event
Relay log creation event:
... #记录日志格式为ROW模式时,会生成一条日志,包含sql语句的执行结果
File position: 4 #日志所在的位置
Event size: 73 #日志大小
Read from relay log file completed on'mysql-bin.000001'
6.主库提交事务
COMMIT; #提交事务
7.从库提交事务成功
SQL Thread applying batch of events received from the master... #从库正在应用来自主库的批量事件