数据库的 Schema 变更实现

一、减少元数据变更的措施

元数据变更是数据库管理中不可避免的工作项,减少元数据变更次数可降低数据库维护和管理成本,减轻对业务的影响。这里我们可以优先考虑以下 3 点:

  • 精细计划

在数据库设计和开发阶段,精细设计元数据结构可有效避免设计不合理或不充分的情况;

  • 避免过度设计

为降低维护难度和变更次数,元数据结构设计应当秉承简单、实用、符合业务需求的原则,避免过度设计;

  • 合并使用约束

在设计元数据结构时,合并使用约束,包括主键、外键、唯一性约束、非空约束等可以保证数据的完整性和一致性。

二、MySQL Metadata Lock 流程

  1. 由 LEX 和 YACC 根据语句的类型给需要访问的表初始化 MDL 锁请求;

  2. MDL_context 调用 acquire_lock 发起 MDL_request;

  3. 顺利获取到 MDL_ticket,就完成了 MDL 的获取,可以继续查询过程。如果无法获取到,就需要进行锁等待;

  4. 每个线程在进入锁等待前,会进行一次死锁检测,避免当前线程陷入死等。

三、PT-OSC 流程

  1. 创建一个与原表结构相同的空表,表名是 _new 后缀;

  2. 修改步骤 1  创建的空表的表结构;

  3. 在原表上加三个触发器:delete/update/insert,用于复制数据时,将原表中要执行的语句在新表中执行;

  4. 将原表数据以数据块的形式复制到新表;

  5. 将原表重命名为 old 表,并把新表重命名为原表名,然后删除旧表;

  6. 删除触发器。

四、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 步:再次等待其他节点获取到最新的表元数据,此次变更操作结束。

猜你喜欢

转载自blog.csdn.net/ZNBase/article/details/131185807