Download presentation
Presentation is loading. Please wait.
1
聊聊mysql
2
innodb redo undo checkpoint
3
innodb - undo - 回滚 优势:事务原子性,数据持久化 劣势:数据总是写磁盘 内存修改,数据无变化 根据undo log回滚
提交事务 a = 3 b = 4 读取文件片段 到内存 客户端 磁盘数据 a = 1 b = 2 优势:事务原子性,数据持久化 劣势:数据总是写磁盘 事务开始 内存操作 undo log buffer 备份a=1 覆盖 宕机 更新a=3 内存修改,数据无变化 备份a=2 更新b=4 undo log 文件 undo log落地 根据undo log回滚 记录事务提交 磁盘新数据 a = 3 b = 4 新数据落地 根据undo log回滚 事务提交 数据已更新,无需回滚 返回客户端
4
innodb - undo - 回滚 为了保障事务原子性以及数据持久化,在事务提交前需要调用sync保证undo log和data被刷出到磁盘。 凡是事务最终提交前宕机,都可以依靠磁盘保存的undo log完成数据恢复( 回滚)。 通过某种技术手段(redo),避免每个事务持久化data(定时的sync),可 以大幅提升写入性能,主要思路: 更新后的data先缓存在内存,不立即落盘。—-宕机丢失更新? 将更新的数据顺序写到redo log,比覆盖data要快。—- 增量取代全量 宕机重放redo log,恢复已经提交的事务(恢复本应落地的data)。
5
innodb - redo - 重做 提交事务 a = 3 b = 4 读取文件片段 到内存 客户端 磁盘数据 a = 1 b = 2 事务开始 undo log buffer redo log buffer 内存操作 备份a=1 覆盖 事务回滚: 记录1: <trx1, Undo log insert <undo_update xxx set a=1 …>> 记录2: <trx1, update xxx set a=3 …> 记录3: <trx1, Undo log insert <undo_update xxx set b=2…>> 记录4: <trx1, update xxx set b=4…> 记录5: <trx1, update xxx set a=1 …> 记录6: <trx1, update xxx set b=2 …> 记录5: <trx1, rollback …> 更新a=3 备份a=2 内存数据 a = 3 b = 4 按一定策略,定时刷出 磁盘新数据 a = 3 b = 4 更新b=4 redo+undo log 文件 redo+undo log落地 事务回滚 记录事务提交 事务提交: 记录1: <trx1, Undo log insert <undo_update xxx set a=1 …>> 记录2: <trx1, update xxx set a=3 …> 记录3: <trx1, Undo log insert <undo_update xxx set b=2…>> 记录4: <trx1, update xxx set b=4…> 记录5: <trx1, commit …> 事务提交 返回客户端
6
innodb - redo - 重做 无论事务 提交/回滚/宕机,每一条执行的SQL均记录到redo log。
恢复时,只需遍历redo log,收集每个事务关联的redo/undo记录,并重放所有redo记录用于恢复 data。 若能找到事务的commit/rollback日志,说明事务正常结束,无需回滚。 若未能找到事务的commit/rollback日志,说明事务意外中止,反向重放所有undo记录令数据回到 修改前的状态。 redo+undo log持续追加,宕机恢复花费时间长,可以借助checkpoint手段避免: 一个事务(trx)内的SQL关联到同1个LSN标识,LSN标识递增。 一个事务影响多个脏页,取当前最老的脏页的最早LSN作为checkpoint,确保所有拥有 LSN<checkpoint的脏页刷出磁盘。 最终将checkpoint写到redo log头部保存,下次宕机可以跳过redo log中LSN<checkpoint的log。
7
master-slave binlog gtid
8
master-slave - 架构
9
master-slave - GTID GTID在master-slave集群中唯一标识1个事务:
GTID = UUID(server_id):transaction_id。 集群中每个mysqld的server_id各不相同。 每个mysqld内部transaction_id是自增整形。 GTID是引擎(例如:innodb)无关的。 GTID是master与slave进行数据同步的唯一标识。
10
master-slave - binlog binlog用于记录数据库的修改历史,因此只包含提交的事务 。
binlog是引擎无关的,所以不要和innodb的redo/undo log混 淆。 binlog是以事务为单元保存的,每个事务有唯一GTID标识 。
11
master-slave - binlog格式
gtid区间[0,n1) binlog.index binlog meta信息 指向最新binlog binlog.00002 gtid区间[n1,n2) previous_gtid_log_event gtid event - 1 binlog.00003 gtid区间[n2,n3) gtid event - 2 binlog.00123 gtid区间[nn,…) gtid event - N
12
master-slave - binlog format
Statement Level:保存SQL语句。 优点:日志量少,性能高。 缺点: 特定功能/函数导致主从数据不同。 缺乏幂等性,异常情况导致SQL重复执行。 Row Level:保存变更的数据行。 优点:符合幂等性,高度保障数据一致。 若SQL影响多行数据,导致日志体积膨胀,进而增大了主从延迟。 Mixed:根据SQL类型动态选择上述2种模式。
13
master-slave - innodb+binlog
1,prepare阶段:落地redo/undo日志 xid XA:分布式事务 2PC:二阶段提交 - prepare+commit redo+undo log文件 3,commit阶段:落地commit日志 异常恢复: after step 1:innodb重放redo,发现无commit 记录。去binlog找xid无法找到,执行undo回滚。 after step 2:innodb重放redo,发现无commit 记录。去binlog找xid找到完整日志,提交innodb事务。 innodb mysqld 2,确保binlog落地 xid binlog 每个事务都sync太慢! sync_binlog=0:不主动sync(),可能丢失较多事务 sync_binlog=1:每次都sync(),不丢失事务 sync_binlog=N:每N个事务sync()一次,最多丢失N个事务
14
master-slave - 基于gtid的同步
executed_gtid_set master:1 master:2 master:3 并集 binlog-00000 binlog-00001 gtid range [1,2) gtid range [2,4) master master:2 master:3 master:2 master:3 master:1 master:2 master:1 executed_gtid_set master:1 master:2 executed_gtid_set master:1 slave1 slave2
15
master-slave - replica模式
异步(Asynchronous replication):master commit后先返回客户端,再由slave主动拉取master的binlog。 优点:master不需等待slave同步完成,延迟低。 缺点:日志异步传输,master宕机导致部分binlog没有及时同步到slave,造成数据丢失。 全同步(Fully synchronous replication):master commit后立即将binlog传输给所有slave,并等待它们全部执行成功。 优点:一定程度提升了安全性。 缺点:同步等待所有slave执行完成再返回客户端,导致吞吐大幅降低。 半同步(Loss-less Semi-Synchronous Replication):master commit后立即将binlog传输给一台slave,由slave刷出到relay-log后返回 ack给master,然后master返回客户端。 优点: 只等待1台slave落地relay-log即返回,在可容忍的延迟时间内加强了一定的安全性。 缺点: 存在主从一致性问题,解决一致性需要牺牲一定的性能。 这里主从一致是指:master宕机重启后,主从是否能继续同步。
16
master-slave - semi-sync
WAIT_AFTER_COMMIT 开始事务提交 write binlog sync binlog (受sync_binlog参数影响) 正常情况XA可以重做,数据得以恢复。 engine commit relay-log 同步等待 send events master有而slave没有,造成”幻读”。 ack 返回客户端
17
master-slave - semi-sync
WAIT_AFTER_SYNC 开始事务提交 write binlog sync binlog (受sync_binlog参数影响) 正常情况XA可以重做,数据得以恢复。 relay-log 同步等待 send events (受sync_binlog参数影响) slave得到日志并执行, master未sync binlog导致部分丢失, XA事务无法重放, 则slave领先于master。 ack engine commit 返回客户端
18
实战部署 部署mysql 5.7 GTID 1主2从 模拟场景:1从延迟,主宕机,将数据较新slave提高为 master。
模拟场景:基于mysqldump,向集群新增slave节点。
19
Q&A
Similar presentations