因为 pt-osc 对数据库性能影响较大,且容易造成死锁问题,目前我们在线更改表结构都使用 gh-ost 工具进行修改,这里记录一下使用 gh-ost 过程中的问题,以作记录;首先先复习一下gh-ost的基本实现,gh-ost的基本实现原理如下图所示:
根据源码,核心步骤如下:
- initiateStreaming: 初始化 binlog events streaming
- initiateApplier: 初始化 applier
- addDMLEventsListener: 添加对指定表的binlog event过滤
- ReadMigrationRangeValues: 获取对应表唯一索引的 min & max 值
- executeWriteFuncs: 通过applier向ghost表写入数据, binlog event 相比 copy rows具有更高优先级
- iterateChunks: 根据 min & max的值, 批量插入数据到 ghost 表
- cutOver: rename & drop新旧表
问题一:gh-ost导致最新一次写操作丢失
原因分析:
在 initiateStreaming 的过程中通过 show master status 获取主节点当前的 binlog name & pos & Executed_Gtid_Set,然后通过 binlog name & pos 和当前的数据库节点建立复制通道,而后在 ReadMigrationRangeValues 的过程中通过 select min(unique_key) 和 select max(unique_key) 快照读的方式获取原表数据的范围。