数据库的 Schema 变更实现
一、减少元数据变更的措施
元数据变更是数据库管理中不可避免的工作项,减少元数据变更次数可降低数据库维护和管理成本,减轻对业务的影响。这里我们可以优先考虑以下 3 点:
精细计划
在数据库设计和开发阶段,精细设计元数据结构可有效避免设计不合理或不充分的情况;
避免过度设计
为降低维护难度和变更次数,元数据结构设计应当秉承简单、实用、符合业务需求的原则,避免过度设计;
合并使用约束
在设计元数据结构时,合并使用约束,包括主键、外键、唯一性约束、非空约束等可以保证数据的完整性和一致性。
二、MySQL Metadata Lock 流程
由 LEX 和 YACC 根据语句的类型给需要访问的表初始化 MDL 锁请求;
MDL_context 调用 acquire_lock 发起 MDL_request;
顺利获取到 MDL_ticket,就完成了 MDL 的获取,可以继续查询过程。如果无法获取到,就需要进行锁等待;
每个线程在进入锁等待前,会进行一次死锁检测,避免当前线程陷入死等。
三、PT-OSC 流程
创建一个与原表结构相同的空表,表名是 _new 后缀;
修改步骤 1 创建的空表的表结构;
在原表上加三个触发器:delete/update/insert,用于复制数据时,将原表中要执行的语句在新表中执行;
将原表数据以数据块的形式复制到新表;
将原表重命名为 old 表,并把新表重命名为原表名,然后删除旧表;
删除触发器。
四、F1 Schema 变更算法
租约:F1 约定了数分钟的 Schema 租约,在租约过期前所有服务器要完成变更操作,如果超时没有完成则认为服务器下线停止工作;
中间状态:把一次 Schema 变更拆解为多个逐步递进的中间状态,使两两中间状态可兼容,整个变更过程转化为演化过程。
五、OSC 流程图
第 1 步:将元数据由 Absent 状态演进到 DELETE_ONLY 状态,Version 加一,同时添加的 Mutation 只对 Delete 操作可见;
第 2 步:通过 waitToUpdateLeases 函数等待集群的其他节点将元数据更新到 Version2,这期间 Version2 的元数据和 Version1 共存,此时在节点 2 插入数据,由于 DELETE_ONLY 状态下 Mutation 对 insert 操作不可见,所以不会增加索引数据;
第 3 步:Mutation 将由 DELETE_ONLY 状态演进到 WRITE_ONLY 状态,同时 Version 加 1,此时 Mutation 对 Insert 和 Delete 操作可见;
第 4 步:再次等待其他节点将表元数据更新到 Version3;
第 5 步:只有需要做数据回填的 DDL 语句才会执行,比如增加索引、删除列、增加带默认值的列等;
第 6 步:Mutation 将变成索引并添加到表元数据中,当前节点完成变更操作;
第 7 步:再次等待其他节点获取到最新的表元数据,此次变更操作结束。
评论