分库分表的事务问题 - 怎么实现事务

API Request

Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "分库分表 事务 分布式事务", "topk": 15})

API Request

Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "事务 跨库 跨表", "topk": 15})

API Request

Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "transaction 事务", "topk": 15})

document_path: /灵渠/8 API 参考手册/8.10 TransactionMessage类(mysql事务消费)

contents: [# 8.10 TransactionMessage类(mysql事务消费)

TransactionMessage 类


类说明

类 TransactionMessage 将源端DB的一个事务进行聚合后推送给业务(需要申请实例级别有序的通道)。一个TransactionMessage是DTS给订阅方的一个事务,它包含一个事务中包含的全部DML操作所产生的ClusterMessage。

重要:TransactionMessage需要整体进行ack,即事务中的所有ClusterMessage都消费成功才调用ackAsConsumed()。

类方法

TransactionMessage提供了所有成员的getter方法用于获取数据。这里列出所有的成员以及它们的含义:, Summary of the 0th Table:
,

变量名 类型 含义
topic String 消息所属的topic
partitionId int 此消息所属的分区ID
gtid String 当前事务的gtid
messageList List clusterMessage列表,当前事务包含的消息
truncated boolean 事务是否被截断,自动截断
unCompletedTransaction boolean 极端情况下当DTS数据收到不完整事务数据时,且用户UnCompletedTranactionMessageConsumerStrategy选择了notify,则会将不完整的数据推送给业务,由业务进行处理
seq int 事务批次序号,从0开始,如果被截断会递增

]API Request Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "Zebra 事务 跨库", "topk": 15}) document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极](https://note.pdd.net/doc/202796405263151104) contents: [![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fnote.pdd.net%2Fapi%2Fpuddle%2Fdownload%2Ffile%3Ffile%3D299647564637691904%26preview%3Dtrue%26thumbnail%3Dtrue%26targetId%3D202796405263151104\&pos_id=img-uVxZzedC-1770298943619)

  1. 这个服务有2个pod,每个里面启动了两个datasource,这时候有4个MigrateDatasource需要切换,但是只通知了太极管理员2个,操作了切换,最坏的情况下会有2个datasource切过去,2个datasource没有切。灰色的datasource被遗忘了,同样会引起数据不一致。,

业务自查项(怎样确保上述两点?)

1. 首先确定涉及的服务,有没有服务读写了需要切的表,但是没有用提单时的填入的keychain接入?
2. 正确初始化zebra数据源
  • zebra版本要求3.5.1.RELEASE 及以上

  • Monitor打点信息 : Transaction类型:DAL.Migrate-Init

  • zebra数据源声明方式 :使用 ZebretteDataSourceFactory.getDataSource(keychain) 方法,注意下面代码中的注释:, ```java

    @Bean(name = "dataSource", destroyMethod = "close")

    public DataSource dataSourceZebraMigrate() {

    // 在 太极平台 工单申请页面 填写的 源端keychain的leokey

    String keychain = LeoUtils.getProperty(""); //(此处的keychain必须跟 太极工单中填的源端keychain 是一个相同的才可以)

    //预期结果: keychain = "zebrette-auth-center.songlin_shard_3_3.822z9c9b"

    return ZebretteDataSourceFactory.getDataSource(keychain); // 需要使用该接口,才可以使用太极数据源切换功能 getShardDataSource()等不行,必须用getDataSource()这个方法, //预期结果: return ZebretteDataSourceFactory.getDataSource("zebrette-auth-center.songlin_shard_3_3.822z9c9b");

    //这样不满足切换要求!! return ZebretteDataSourceFactory.getDataSource("699f22ce6043698bf106017d23d575180fd0a97470e773bf4a1431d6d36c2f6f284fa766a68066185866c105923cd2ef6c4");

    }

    3. 创建切换任务步骤后,重启服务的所有实例,比对transaction打点数,和金丝雀上的机器实例数。打点数 = 机器实例数 *n (n >=1,n指一个java进程中相关的zebra datasource个数)。所有服务都要这样确认,然后记录下这个打点数的总和,报告给太极管理员。]

    document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/1. 工单服务/1.3 一键迁移
    contents: [> - 太极校验所需字段,用于校验源端目标端数据的一致性,没有全局唯一字段需进行改造,或者借助帮我生成

    复制代码
    - 使用分布式ID生成器进行改造,参考文档 [4.9 分布式ID生成器]
    - 自动生成唯一键(<b><i>注意:单表情况下可以保证全局唯一,分表情况下只能保证各个单表的唯一性</i></b>)
    复制代码
      ![image.png](https://note.pdd.net/api/puddle/download/file?file=757732824048345088&preview=true&thumbnail=true&targetId=757271307413573632)
    • 3、更新字段
    • 选择的更新字段为unix时间时,太极迁移需要明确时间单位为秒还是毫秒

    keychain允许扫全表, > - 1、全表扫描需要根据业务实际自主选择,其他keychain配置默认与源端一致。 如果一条SQL语句不携带主维度/辅维度,或携带的主维度/辅维度无法明确计算出落到哪张分表上,需要开启全表扫描开关才能执行,否则会抛异常。原则上不建议使用这类SQL,会出现很多慢SQL。 风险详见zebra文档:https://note.pdd.net/doc/457199513882542080

    • 2、一键迁移不支持附加路由。
    • 3、一些单库sql迁至分库分表后不被Zerba-client支持,请在胡桃街验证。

    写keychain类型, > - 1、读写分离:数据源切换过程中,写请求短暂的中断,读请求不受影响(避免长时间占用单个读连接)。但如果有请求 使用了 强制走主库的方式,这些请求会跟请求一起短暂中断

    • 2、单库读写:数据源切换过程中,读写请求同时短暂中断
    • 【说明】:, > - 中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。
      • 建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。

    【注意】, > - 读写分离数据源在切换到目标端 --> 切断源端读连接过程中,如果业务持续占用老connection不释放,会有读旧数据的可能

    • 如果业务可以忍受短暂gap读老数据,希望读请求不中断,建议读写分离
    • 如果对于读一致性要求比较高,建议主库读写

    路由规则

    • 1、手动输入:业务依据拆分库表数量,自行编辑路由规则,需要保证路由规则的正确性,注意:这里路由规则编辑错误可能导致整个工单失败,需重新提单从头执行!
    • 2、帮我生成路由:
    • 编辑路由规则
    复制代码
    - <font color="red">注:单张分表总数需是分库个数的整数倍</font>]

    document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/数据迁移-附录/MySQL数据源切换手册
    contents: [# MySQL数据源切换手册

    [用户] 需要复制该文档,并将下面的确认项 逐一仔细确认 打点数替换成待切换服务 ),然后将迁移工单切换单发给 [工单执行人]( 并添加文档权限 ),预约切换时间!

    | [用户] 切换前确认项: |
    | --- |, | ☐ | [下游依赖确认] 步骤是否完成?[工单下游依赖步骤需要变成绿色][操作方法见:迁移工单执行步骤说明#2.11. 下游依赖确认(需要完成该步骤工单才是处于等待切换的ready状态)[用户+运维人员+大数据]]
    需要在切换前,目标端DB达到可用状态后完成迁移(只读依赖从源端迁移到目标端)

    • DTS消费组:通过 灵渠平台 对消费进行梳理;将与本次切换库表相关的消费组迁移至目标DB
    • 大数据抽数任务:流程见:大数据抽数迁移
    • 源端待迁移库表关联的太极同步工单 :可以联系太极&灵渠小助手协助确认,提单建立新的同步关系,联系下游业务做读流量迁移
    • 其他只读依赖:联系DBA协助确认是否有关联只读keychain,业务服务其他只读依赖 |
      | --- | --- |

    | ☐ | 创建knock群聊(拉取DBA、工单执行人和切换业务关注人)完成?群名格式:[xxx迁移]+[切换对齐]+[预计切换时间] 例如 [太极配置库迁移][切换对齐][2023-01-11 20:00] |
    | --- | --- |, | ☐ | 迁移是以keychain为维度进行迁移,以源端keychain初始化的数据源读写都会切换到目标端,更加详细介绍见:迁移工单执行步骤说明#2.9. 开启反向通道(dry run)(创建反向通道)[自动],是否知晓?
    [访问库表检查] 源端keychain有非同步库表的请求也会被迁移到目标端,请确认源端keychain上非同步库表的流量已经摘干净。 |
    | --- | --- |

    zebra 版本在 3.5.1以上?[说明:数据迁移-太极#正确初始化zebra数据源]

    | ☐ | zebra 初始化数据源使用的是 ZebretteDataSourceFactory.getDataSource(keychain) 方式(唯一正确方式)?[说明:数据迁移-太极#正确初始化zebra数据源]
    zebra确认是否存在如下用法,指定库表操作, ```
    ZebraRouterHelper.executeByDbAndTableIndex
    // 或
    TedasZRouterHelper.executeByDbAndTableIndex

如存在上述用法,在切换前需业务主动控制停写

参考文档 4.2 指定某库某表操作 |

| --- | --- |

| ☐ | [会初始化数据源写入迁移库表] 的gavin定时任务/服务自身定时任务是否已经停止?[说明:这里的gavin任务特指------ 每次启动后会初始化(创建)数据源的gavin任务 ,因为如果在 切换时刻该gavin任务启动 ,可能会 造成切换不彻底数据错误 等情况发生!!!因此为了避免不必要的切换风险,用户需要停止该gavin任务] |

| --- | --- |, | ☐ | 迁移切换步骤执行中禁止 扩容、缩容、发版、重启 操作是否知晓?[仅在运维管理员操作切换过程中,非切换时候可以 扩容、缩容、发版、重启, 切换完成后可以 扩容、缩容、发版、重启 ]

  • 重启后 到 数据源切换完成前 不建议 进行 扩容、缩容、发版、重启操作
  • 在 告知管理员打点截图后 到 切换完成前 一定不能 进行上述操作。这段时间可能造成切换任务异常,导致数据不一致; 业务需在业务自己内部群发公告周知
  • 如果有这段时间有操作需求的话,事后需要 重新告知打点数
  • 数据源切换完成 到 结单前 不建议 进行 扩容、缩容、发版、重启操作
  • 如果业务接入了弹性扩容的话 建议在 重启、告知管理员打点截图后 到 结单前 把 弹性扩容的功能关闭
  • 如果有这段时间有操作需求的话,在重新关闭后需要 重新告知打点数 |
    | --- | --- |]API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "ShardDataSource 事务 跨库 跨表 分布式", "topk": 15})
    API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "分库分表 限制 注意事项", "topk": 15})
    document_path: /数据服务相关文档(公开)/MySQL相关规范/MySQL分库分表建议
    contents: [# MySQL分库分表建议

原 wiki 文档链接:https://wiki.pdd.net/pages/viewpage.action?pageId=10710056

拆分入口

拆分文档, ## 1、拆分基准

  1. 非分库分表容量建议(超过下面标准的,建议做分库分表)

    a. 单表不超过5kw

    b. 单表大小不超过50G

    c. 单实例TPS<2000/s,QPS<8000/s(软限制),TPS+QPS<15000/s(硬限制)

    d. 单表tps<500,行DML<500,qps<=3000

  2. 分库分表建议

    a. 满足业务未来一定时期的容量和QPS需求,分库分表后单实例TPS<2000/s,QPS<8000/s;单表tps<100,qps<=200

    b. 分表后单表在500w行以下,大小 10G以下,保持单实例1T以下,使用水位50%以下

    复制代码
         示例 单表行数2亿行,分表后 
    • 2亿以下 1~4个分库或实例,128个分表
    • 2亿~10亿 4~8个分库或实例,256个分表
    • 10亿~50亿 4~16个分库或实例 512~2048
    • 50亿~以上 8~64个分库或实例 1024~4096, ## 2、拆分库表命名

1)库名字以下划线+数字来命名,比如促销库分库分表 : pernod_0...pernod_1...pernod_2...

2)【使用全局唯一、alldb方式】表名字以下划线+数字来命名,比如促销库分库分表:coupon_record_0...coupon_record_1...coupon_record_2...

  1. 拆分后的表确保要有全局唯一键

3、拆分业务依赖

(1)对于已经有业务运行的大表的业务拆分,必须完全梳理出来当前的应用依赖。]

document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/迁移工单用户最佳实践/迁移工单切换单

contents: [### 源端目标端keychain的服务权限截图

  • 查询入口: 线上https://leo.pdd.net/mysql/index; 保供线上https://leo.temu.team/mysql/index; 打开页面后, 选择数据源列表, 继而选择您的Keychain来查看信息;
  • 确认进行数据源切换的服务,注意keychain不需要给太极服务加权限, 如果keychain权限中有太极服务,可以忽略太极四个服务:taiji-manager, taiji-platform,taiji-manager-upgrade, taiji-platform-upgrade;
  • 以下图为例,排除太极服务,进行数据源切换的服务是{columbus-validation, columbus-pressure},一共2个;
  • 您需要截图您的Keychain的信息, 并替换掉下图。

确认并回答以下问题, - 业务是否已知晓 数据源切换期间 不能做任何变更?

  • 重启后 到 数据源切换完成前 不建议 进行扩容、缩容、发版、重启操作
    • 在 告知管理员打点截图后 到 切换完成前 一定不能 进行上述操作。这段时间可能造成切换任务异常,导致数据不一致; 业务需在业务自己内部群发公告周知
  • 数据源切换完成 到 结单前 不建议 进行扩容、缩容、发版、重启操作
  • 如果业务接入了弹性扩容的话 建议在 切换前 到 结单后 把弹性扩容的功能关闭
  • 业务服务使用提单源keychain只会读写待迁移的表,不会读写不迁移的表?
  • 源端待迁移表的写入流量只会来自提单源keychain,不会来自其他keychain(或其他服务,比如归档任务)?
  • 业务服务中 会用迁移的Keychain创建多少个DataSource ?, - 业务的Zebra版本 是多少?业务代码中创建DataSource的代码段请截图 (所有服务的Zebra版本在必须3.5.1以上,代码中getDataSource()使用方式必须符合示例[查看示例])。
  • 胡桃街是否测试过相应库表的迁移切换流程? 如果未在胡桃街测试,给出未测试的原因。如果胡桃街未测试,因此导致的切换到目标端出问题,后果自负
  • 切换前归档任务是否已关闭? (切换前,要关闭归档任务,否则切换时遇到归档会导致切换失败;切换完成后,业务在新实例上启用归档、长事务查杀等需要源集群上的Mountain配置)
  • 如果是单表迁移到分库分表,是否已验证业务所有sql兼容分库分表场景?如未充分验证,因此导致的切换到目标端后出问题,后果自负, - 如果切换后业务服务有问题,是否已知悉明确回滚流程? (回滚时,太极仅有能力将通过"切换所用keychain"的读写流量切回源端,对于不使用"切换所用keychain"的只读流量,大数据、dts等下游依赖的回滚,用户要做好回滚预案,确定各环节回滚的操作人)
  • 源端是否使用sequence表 [太极迁移过程中业务使用过sequence表的情况梳理]

填写进行切换的服务实例数

  • 在下表中填写 参与切换服务的实例数 (只要用到了都要算进去!!否则会有数据问题

  • 如果有服务没有部署(如columbus-pressure),请说明,实例数填0。

    示例如下:, ### 重启您的服务,统计打点数(仅重启)

  • 这一步骤只是重启机器!!一定不能改Keychain, 改Keychain会导致数据错误; 改Keychain前一定要询问管理员

  • 到了约定的切换时刻; 您需要重启您的服务(先重启一台,看看打点是否正常,是否有报错 ), 统计 DAL.Migrate-Init 打点个数(若没有打点,请检查Zebra接入方式要求:Zebra使用要求 ), 并替换下图,如您有多个服务参与切换,每个服务都需要一个打点截图

  • 一般而言,DAL.Migrate-Init 通常与您的服务实例数相等; (如您一个服务实例中 用迁移的Keychain创建了多个DataSource, 那么每个DataSource都会产生一个打点)

示例:]

document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/1. 工单服务/1.3 一键迁移

contents: [## 1.3.3 拆分

迁移工单申请,点击查看 >>>

1.3.3.1 提单

, ### 1.3.3.2 确认源端信息

【注意事项】:
源端keychain , > - 1、迁移库表需要保证有且仅有提单源端keychain在写入,如果有其他keychain或者直连写入,会造成切换不彻底数据错误!!!

  • 2、迁移是以keychain为维度进行迁移,以源端keychain初始化的数据源读写都会切换到目标端

  • 3、若只迁移部分表,请申请一个新keychain,并在代码层将针对该表的读写流量切换至新申请keychain,隔离流量
    拆分类型 , > - 1、分库分表类型的keychain,拆分类型只能选 全部逻辑表***,***如果需要迁移部分逻辑表,请重新申请keychain,只包含待迁移的逻辑表

  • 2、单库类型的keychain,拆分类型可以选择 整库 or 部分表, ### 1.3.3.3 确认目标端keychain属性

【注意事项】:
目标端逻辑表必备属性配置 (手动选择 or 一键填充)

  • 1、同步自增列

  • 拆分场景默认不同步自增列,主要有以下原因:

    • 分表拆分场景:如果同步自增列,源端相同id的数据经过reshard可能路由至目标端同一张表,导致数据覆盖
    • 单表拆分场景:如果同步自增列,太极切换后,目标端已经写入数据,如果业务需要回切,会导致相同id的数据路由至源端同一张表,导致数据覆盖
  • 2、全局唯一字段]API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "3.2 ShardDataSource 使用说明", "topk": 10})
    document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/迁移工单用户最佳实践/迁移工单切换单
    contents: [- 如果切换后业务服务有问题,是否已知悉明确回滚流程? (回滚时,太极仅有能力将通过"切换所用keychain"的读写流量切回源端,对于不使用"切换所用keychain"的只读流量,大数据、dts等下游依赖的回滚,用户要做好回滚预案,确定各环节回滚的操作人)
  • 源端是否使用sequence表 [太极迁移过程中业务使用过sequence表的情况梳理]

填写进行切换的服务实例数

  • 在下表中填写 参与切换服务的实例数 (只要用到了都要算进去!!否则会有数据问题

  • 如果有服务没有部署(如columbus-pressure),请说明,实例数填0。

    示例如下:, ### 重启您的服务,统计打点数(仅重启)

  • 这一步骤只是重启机器!!一定不能改Keychain, 改Keychain会导致数据错误; 改Keychain前一定要询问管理员

  • 到了约定的切换时刻; 您需要重启您的服务(先重启一台,看看打点是否正常,是否有报错 ), 统计 DAL.Migrate-Init 打点个数(若没有打点,请检查Zebra接入方式要求:Zebra使用要求 ), 并替换下图,如您有多个服务参与切换,每个服务都需要一个打点截图

  • 一般而言,DAL.Migrate-Init 通常与您的服务实例数相等; (如您一个服务实例中 用迁移的Keychain创建了多个DataSource, 那么每个DataSource都会产生一个打点)

示例:,


重要说明[必看!]

数据源切换参数说明, - 数据源切换是一个需要非常谨慎的操作,切换异常可能导致不可恢复的数据源不一致;

  • 用户在数据源切换前,应悉知【[请点击链接查看→→→]几种因信息提供不足导致的切换异常[←←←请点击链接查看]】这里很危险,一定要点击链接阅读!! 并向管理员提供以下**"2项"必须的内容(请按模板提供,否则信息不足管理员无法切换!!)**。
  • 太极系统满足切换条件是否包含数据一致性,数据源切换任务会检查以下三项,如果检查不通过,则切换任务会失败:
    • 校验任务当前进度(时间)与当前时间的差值必须小于下面的2000ms,保证基本所有数据都被校验,且没有不一致行,这样我们认为在两端数据一致的情况下,可以进行切换。
    • 同步的延时必须小于下面的2000ms,即可认为开始切换时(源端禁写),两端数据是一致的,可以进行切换。
    • pipeline是否正常运行, - 太极系统满足切换条件的检查时间: 默认2000ms

反向通道说明

一般不建议开启反向通道。

如果业务方认为业务服务有问题,需要从目的端切换到源端,太极管理员打开回滚流程后反向同步才会开启,起始位点是源端切换到目的端的那一时刻(如果时隔太久超过binlog过期的时间,则反向同步会失败,无法切换到源端)

注意
  • 太极对于业务写的insert和update,同步到对端的处理都是insert on duplicate key update,保证数据最终一致性
    • 业务需保证其全局唯一键的全局唯一性,如果业务全局唯一键不唯一,有可能出现来自目标端不同物理表的数据,回写到源端相同的物理表,出现丢数据的情况
    • 如果业务同步了自增id主键,反向同步会大概率出现相同id数据覆盖的情况,造成丢数据。仅当两端物理表一对一的平移场景,可以同步自增id主键
    • 如果业务切到目标库之后,因为一些原因写了脏数据,业务需考虑脏数据经过反向同步写回源端是否有数据问题。如果脏数据不能反向同步回源端,那么不能走常规回切流程]API Request
      Calling function pga_knowledge_read_document_link({"link":"https://note.pdd.net/doc/457199509536468992"})
      Error: document link not existAPI Request
      Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "Zebra 跨库事务 限制", "topk": 15})
      document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/1. 工单服务/1.3 一键迁移
      contents: [> - 太极校验所需字段,用于校验源端目标端数据的一致性,没有全局唯一字段需进行改造,或者借助帮我生成
复制代码
- 使用分布式ID生成器进行改造,参考文档 [4.9 分布式ID生成器]
- 自动生成唯一键(<b><i>注意:单表情况下可以保证全局唯一,分表情况下只能保证各个单表的唯一性</i></b>)
复制代码
  ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fnote.pdd.net%2Fapi%2Fpuddle%2Fdownload%2Ffile%3Ffile%3D757732824048345088%26preview%3Dtrue%26thumbnail%3Dtrue%26targetId%3D757271307413573632&pos_id=img-FDFP5mxI-1770298943621)
  • 3、更新字段

  • 选择的更新字段为unix时间时,太极迁移需要明确时间单位为秒还是毫秒
    keychain允许扫全表 , > - 1、全表扫描需要根据业务实际自主选择,其他keychain配置默认与源端一致。 如果一条SQL语句不携带主维度/辅维度,或携带的主维度/辅维度无法明确计算出落到哪张分表上,需要开启全表扫描开关才能执行,否则会抛异常。原则上不建议使用这类SQL,会出现很多慢SQL。 风险详见zebra文档:https://note.pdd.net/doc/457199513882542080

  • 2、一键迁移不支持附加路由。

  • 3、一些单库sql迁至分库分表后不被Zerba-client支持,请在胡桃街验证。
    写keychain类型 , > - 1、读写分离:数据源切换过程中,写请求 短暂的中断**,读请求** 不受影响(避免长时间占用单个读连接)。但如果有 请求 使用了 强制走主库的方式,这些 请求会跟 请求一起短暂中断

  • 2、单库读写:数据源切换过程中,读写请求 同时短暂中断

  • 【说明】:, > - 中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。

    • 建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。
      【注意】 , > - 读写分离数据源在切换到目标端 --> 切断源端读连接过程中,如果业务持续占用老connection不释放,会有读旧数据的可能
  • 如果业务可以忍受短暂gap读老数据,希望读请求不中断,建议读写分离

  • 如果对于读一致性要求比较高,建议主库读写
    路由规则

  • 1、手动输入:业务依据拆分库表数量,自行编辑路由规则,需要保证路由规则的正确性,注意: 这里路由规则编辑错误可能导致整个工单失败,需重新提单从头执行!

  • 2、帮我生成路由:

  • 编辑路由规则

    • 注:单张分表总数需是分库个数的整数倍]

document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/数据迁移-附录/MySQL数据源切换手册

contents: [# MySQL数据源切换手册

[用户] 需要复制该文档,并将下面的确认项 逐一仔细确认 打点数替换成待切换服务 ),然后将迁移工单切换单发给 [工单执行人]( 并添加文档权限 ),预约切换时间!

| [用户] 切换前确认项: |

| --- |, | ☐ | [下游依赖确认] 步骤是否完成?[工单下游依赖步骤需要变成绿色][操作方法见:迁移工单执行步骤说明#2.11. 下游依赖确认(需要完成该步骤工单才是处于等待切换的ready状态)[用户+运维人员+大数据]]
需要在切换前,目标端DB达到可用状态后完成迁移(只读依赖从源端迁移到目标端)

  • DTS消费组:通过 灵渠平台 对消费进行梳理;将与本次切换库表相关的消费组迁移至目标DB
  • 大数据抽数任务:流程见:大数据抽数迁移
  • 源端待迁移库表关联的太极同步工单 :可以联系太极&灵渠小助手协助确认,提单建立新的同步关系,联系下游业务做读流量迁移
  • 其他只读依赖:联系DBA协助确认是否有关联只读keychain,业务服务其他只读依赖 |
    | --- | --- |

| ☐ | 创建knock群聊(拉取DBA、工单执行人和切换业务关注人)完成?群名格式:[xxx迁移]+[切换对齐]+[预计切换时间] 例如 [太极配置库迁移][切换对齐][2023-01-11 20:00] |

| --- | --- |, | ☐ | 迁移是以keychain为维度进行迁移,以源端keychain初始化的数据源读写都会切换到目标端,更加详细介绍见:迁移工单执行步骤说明#2.9. 开启反向通道(dry run)(创建反向通道)[自动],是否知晓?
[访问库表检查] 源端keychain有非同步库表的请求也会被迁移到目标端,请确认源端keychain上非同步库表的流量已经摘干净。 |

| --- | --- |

zebra 版本在 3.5.1以上?[说明:数据迁移-太极#正确初始化zebra数据源]

| ☐ | zebra 初始化数据源使用的是 ZebretteDataSourceFactory.getDataSource(keychain) 方式(唯一正确方式)?[说明:数据迁移-太极#正确初始化zebra数据源]

zebra确认是否存在如下用法,指定库表操作, ```

ZebraRouterHelper.executeByDbAndTableIndex

// 或

TedasZRouterHelper.executeByDbAndTableIndex

复制代码
如存在上述用法,在切换前需业务主动控制停写  
参考文档 4.2 指定某库某表操作 |
| --- | --- |

| ☐ | **[会初始化数据源写入迁移库表]** 的gavin定时任务/服务自身定时任务是否已经停止?[说明:这里的gavin任务特指------ **每次启动后会初始化(创建)数据源的gavin任务** ,因为如果在 **切换时刻该gavin任务启动** ,可能会 **造成切换不彻底** , **数据错误** 等情况发生!!!因此为了避免不必要的切换风险,用户需要停止该gavin任务] |
| --- | --- |, | ☐ | 迁移切换步骤执行中禁止 **扩容、缩容、发版、重启** 操作是否知晓?[仅在运维管理员操作切换过程中,非切换时候可以 **扩容、缩容、发版、重启,** 切换完成后可以 **扩容、缩容、发版、重启** ]  
- 重启后 到 数据源切换完成前 **不建议** 进行 **扩容、缩容、发版、重启操作**  
- 在 告知管理员打点截图后 到 切换完成前 **一定不能** 进行上述操作。这段时间可能造成切换任务异常,导致数据不一致; **业务需在业务自己内部群发公告周知**  
- 如果有这段时间有操作需求的话,事后需要 **重新告知打点数**  
- 数据源切换完成 到 结单前 **不建议** 进行 **扩容、缩容、发版、重启操作**  
- 如果业务接入了弹性扩容的话 建议在 重启、告知管理员打点截图后 到 结单前 把 **弹性扩容的功能关闭**  
- 如果有这段时间有操作需求的话,在重新关闭后需要 **重新告知打点数** |
| --- | --- |]API Request
Calling function pga_knowledge_read_document_link({"link":"<https://note.pdd.net/doc/457199513882542080>"})
Error: document link not existAPI Request
Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "Zebra使用要求 事务", "topk": 15})
document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极/[Mysql]单实例-数据迁移(使用太极数据源切换)](https://note.pdd.net/doc/202800992095850496)
contents: [[Mysql]单实例-数据迁移(使用太极数据源切换)
# 特性
- 接入简单(提单只需要两个keychain)
- 自动创建库表
- 数据同步与校验
- 库表映射
- 库表黑白名单
- 列名映射
- 列黑白名单
- 支持 [事务同步](https://note.pdd.net/doc/477471887004295168)
- 自动数据源切换(3-5秒禁写,读不受影响)
- 开起迁移流程后,业务不能对要迁移的库表执行DDL
- 支持 [特定的Where条件](https://note.pdd.net/doc/575734333671452672)
# 一、业务准备工作
如果 符合 Mountain一键迁移要求,可忽略准备工作中的 **申请资源** 和 **太极提单** 步骤,在Mountain上提 [1.3 一键迁移](https://note.pdd.net/doc/458679578129448960) 工单。
## 1. 申请资源
### MySQL机器申请
请联系DBA  
*说明:库表结构,太极会自动创建的。*, ### mountain上申请keychain
申请地址:[https://mountain.pdd.net/#/order/keychaincreate](https://mountain.pdd.net/#/order/keychaincreate)  
如果使用 数据源切换功能,keychain申请中 *读写类型* 需要注意:

读写分离:数据源切换过程中,**写请求** **短暂的中断**,**读请求** **不受影响**(避免长时间占用单个读连接)。但如果有 **读** 请求 使用了 [强制走主库的方式](https://docs.pdd.net/zebra/configuration/group-configs.html?h=%E5%BC%BA%E5%88%B6),这些 **读** 请求会跟 **写** 请求 **一起短暂中断**。

单库读写:数据源切换过程中,**读写请求** **同时短暂中断**。, *说明:*
- *中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。*
- *建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。*
## 2. leo上配置keychain
需要在业务leo项目里配置 zebra 使用的keychain(不要在代码里直接写死keychain)

注意: 这个leo的配置很重要,在切换到新的数据源后,结单前,需要将该key的值改成新的数据源keychain。务必提前配置好!!
## 3. 使用zebra接入数据源
使用要求详见:[Zebra使用要求](https://note.pdd.net/doc/202796405263151104#PU42ki)
## 4. 太极提单
### 地址, ### 页面
![这张图片展示了MySQL单实例数据迁移的配置界面,包括任务名、业务线、源端和目标端keychain、Schema白黑名单等关键配置项,用于指导用户正确填写信息以完成数据库迁移任务,确保数据同步的准确性和安全性](https://note.pdd.net/api/puddle/download/file?file=202800992020156416&preview=true&thumbnail=true&targetId=202800992095850496), ### 配置项说明
**任务名**:必填,迁移任务名,尽量 体现出库名,表名等信息  
**业务线**:必填  
**源端keychain**:必填,切换前,业务代码中使用的 老的数据源keychain(如果不使用太极数据源切换,可以直接用DB的IP地址)  
**目标端keychain**:必填,切换后,业务代码中使用的 新的数据源keychain(如果不使用太极数据源切换,可以直接用DB的IP地址)  
**Schema白名单**:必填,需要同步的schema名(库名),表名。支持输入正则。  
**Schema黑名单**:不需要同步的schema名(库名),表名。支持输入正则。  
**库表映射配置**:如果目标DB 中 库名,表名,列名 与源DB不一致,可以在此配置映射关系。列黑白名单也在此进行配置。

注意:Schema白名单一定要填,如果白名单中使用了正则,但正则中个别表不想同步,可以使用Schema黑名单进行过滤。
# 二、审批]

document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极/[Mysql]分库分表-数据迁移](https://note.pdd.net/doc/202800990481293312)
contents: [### 1.2 mountain上申请keychain

申请地址:[https://mountain.pdd.net/#/order/applyhome](https://mountain.pdd.net/#/order/applyhome)  
使用太极的分库分表功能时, keychain: **不能选只读模式(只读模式的keychain,太极没办法识别数据库地址是否为主库)**

如果使用 数据源切换功能,keychain申请中 读写类型 需要注意:

![这张图片展示了在Mountain上申请keychain时的读写类型选择界面,包括"读写分离"、"只读模式"和"单库读写"选项。结合上下文,它用于指导用户在数据源切换过程中正确选择读写类型,以避免读写请求的中断问题,确保业务的稳定运行](https://note.pdd.net/api/puddle/download/file?file=202800990409752576&preview=true&thumbnail=true&targetId=202800990481293312), 读写分离:数据源切换过程中,**写请求** **短暂的中断**,**读请求** **不受影响**(避免长时间占用单个读连接)。但如果有**读**请求 使用了 [**强制走主库的方式**](https://docs.pdd.net/zebra/configuration/group-configs.html?h=%E5%BC%BA%E5%88%B6),这些**读**请求会跟**写**请求**一起短暂中断**。

单库读写:数据源切换过程中,**读写请求** **同时短暂中断**。

*说明:*

- *中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。*
- *建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。*

> keychain规范

1. 源端和目标端的keychain中的逻辑表数量需要一样
2. keychain中的路由规则,需要保证数据均匀分布,避免数据明显倾斜或者某些库表中永远不会有数据的情况, 分库分表路由的配置参考:[zebra文档](https://docs.pdd.net/zebra/configuration/shard-configs.html)
## 2. leo上配置keychain

需要在业务leo项目里配置 zebra 使用的keychain(不要在代码里直接写死keychain)  
注意: 这个leo的配置很重要,在切换到新的数据源后,结单前,需要将该key的值改成新的数据源keychain。务必提前配置好!!
## 3. 使用zebra接入数据源

如果不使用太极数据源切换功能,可以跳过此步  
使用要求详见:[Zebra使用要求](https://note.pdd.net/doc/202796405263151104#PU42ki)
## 4. 太极提单
### 地址, ### 页面

![这张图片展示了太极数据迁移系统中MySQL分库分表配置界面,重点说明了任务名、业务线、源端和目标端keychain等关键配置项的填写方法及注意事项,帮助用户正确配置数据迁移任务,确保数据源切换的顺利进行](https://note.pdd.net/api/puddle/download/file?file=224988238840389632&preview=true&thumbnail=true&targetId=202800990481293312), ### 配置项说明

**任务名**:必填,分库分表任务名,尽量 体现出库名,表名等信息  
**业务线**:必填  
**源端keychain**:必填,切换前,业务代码中使用的 老的数据源keychain  
**目标端keychain**:必填,切换后,业务代码中使用的 新的数据源keychain  
**自定义两端表名对应关系**:如果目标DB 中 逻辑表名 与源DB不一致,可以在此配置映射关系。  
列名映射 和 列黑白名单:如果目标DB 中 列名,列的数量 与源DB 不一致,可以在导入配置后,给相应的逻辑表 设置 列名映射,列黑白名单。
#### Keychain说明

提单也可以使用json代替keychain导入配置。

json的使用场景:

  1. 不想走流程申请keychain,可以使用json提单。

  2. 分库分表的规则很老,所有分库名都一样(不带数字后缀),keychain不能表达,可以使用json提单。

    注意:使用json后则不能使用太极数据源切换功能

    json示例:]

    document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/迁移工单用户最佳实践/迁移工单切换单
    contents: [- 业务的Zebra版本是多少?业务代码中创建DataSource的代码段请截图 (所有服务的Zebra版本在必须3.5.1以上,代码中getDataSource()使用方式必须符合示例[查看示例])。

    • 胡桃街是否测试过相应库表的迁移切换流程? 如果未在胡桃街测试,给出未测试的原因。如果胡桃街未测试,因此导致的切换到目标端出问题,后果自负
    • 切换前归档任务是否已关闭? (切换前,要关闭归档任务,否则切换时遇到归档会导致切换失败;切换完成后,业务在新实例上启用归档、长事务查杀等需要源集群上的Mountain配置)
    • 如果是单表迁移到分库分表,是否已验证业务所有sql兼容分库分表场景?如未充分验证,因此导致的切换到目标端后出问题,后果自负, - 如果切换后业务服务有问题,是否已知悉明确回滚流程? (回滚时,太极仅有能力将通过"切换所用keychain"的读写流量切回源端,对于不使用"切换所用keychain"的只读流量,大数据、dts等下游依赖的回滚,用户要做好回滚预案,确定各环节回滚的操作人)
    • 源端是否使用sequence表 [太极迁移过程中业务使用过sequence表的情况梳理]

    填写进行切换的服务实例数

    • 在下表中填写 参与切换服务的实例数 (只要用到了都要算进去!!否则会有数据问题

    • 如果有服务没有部署(如columbus-pressure),请说明,实例数填0。
      示例如下:, ### 重启您的服务,统计打点数(仅重启)

    • 这一步骤只是重启机器!!一定不能改Keychain, 改Keychain会导致数据错误; 改Keychain前一定要询问管理员

    • 到了约定的切换时刻; 您需要重启您的服务(先重启一台,看看打点是否正常,是否有报错), 统计 DAL.Migrate-Init 打点个数(若没有打点,请检查Zebra接入方式要求:Zebra使用要求 ), 并替换下图,如您有多个服务参与切换,每个服务都需要一个打点截图

    • 一般而言,DAL.Migrate-Init 通常与您的服务实例数相等; (如您一个服务实例中 用迁移的Keychain创建了多个DataSource, 那么每个DataSource都会产生一个打点)

    示例:,


    重要说明[必看!]

    数据源切换参数说明, - 数据源切换是一个需要非常谨慎的操作,切换异常可能导致不可恢复的数据源不一致;

    • 用户在数据源切换前,应悉知【[请点击链接查看→→→]几种因信息提供不足导致的切换异常[←←←请点击链接查看]】这里很危险,一定要点击链接阅读!! 并向管理员提供以下**"2项"必须的内容(请按模板提供,否则信息不足管理员无法切换!!)**。
    • 太极系统满足切换条件是否包含数据一致性,数据源切换任务会检查以下三项,如果检查不通过,则切换任务会失败:
      • 校验任务当前进度(时间)与当前时间的差值必须小于下面的2000ms,保证基本所有数据都被校验,且没有不一致行,这样我们认为在两端数据一致的情况下,可以进行切换。
      • 同步的延时必须小于下面的2000ms,即可认为开始切换时(源端禁写),两端数据是一致的,可以进行切换。
      • pipeline是否正常运行]

    document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/数据迁移-附录/MySQL数据源切换手册
    contents: [# MySQL数据源切换手册

    [用户] 需要复制该文档,并将下面的确认项 逐一仔细确认 打点数替换成待切换服务 ),然后将迁移工单切换单发给 [工单执行人]( 并添加文档权限 ),预约切换时间!

    | [用户] 切换前确认项: |
    | --- |, | ☐ | [下游依赖确认] 步骤是否完成?[工单下游依赖步骤需要变成绿色][操作方法见:迁移工单执行步骤说明#2.11. 下游依赖确认(需要完成该步骤工单才是处于等待切换的ready状态)[用户+运维人员+大数据]]
    需要在切换前,目标端DB达到可用状态后完成迁移(只读依赖从源端迁移到目标端)

    • DTS消费组:通过 灵渠平台 对消费进行梳理;将与本次切换库表相关的消费组迁移至目标DB
    • 大数据抽数任务:流程见:大数据抽数迁移
    • 源端待迁移库表关联的太极同步工单 :可以联系太极&灵渠小助手协助确认,提单建立新的同步关系,联系下游业务做读流量迁移
    • 其他只读依赖:联系DBA协助确认是否有关联只读keychain,业务服务其他只读依赖 |
      | --- | --- |

    | ☐ | 创建knock群聊(拉取DBA、工单执行人和切换业务关注人)完成?群名格式:[xxx迁移]+[切换对齐]+[预计切换时间] 例如 [太极配置库迁移][切换对齐][2023-01-11 20:00] |
    | --- | --- |, | ☐ | 迁移是以keychain为维度进行迁移,以源端keychain初始化的数据源读写都会切换到目标端,更加详细介绍见:迁移工单执行步骤说明#2.9. 开启反向通道(dry run)(创建反向通道)[自动],是否知晓?
    [访问库表检查] 源端keychain有非同步库表的请求也会被迁移到目标端,请确认源端keychain上非同步库表的流量已经摘干净。 |
    | --- | --- |

    zebra 版本在 3.5.1以上?[说明:数据迁移-太极#正确初始化zebra数据源]

    | ☐ | zebra 初始化数据源使用的是 ZebretteDataSourceFactory.getDataSource(keychain) 方式(唯一正确方式)?[说明:数据迁移-太极#正确初始化zebra数据源]
    zebra确认是否存在如下用法,指定库表操作, ```
    ZebraRouterHelper.executeByDbAndTableIndex
    // 或
    TedasZRouterHelper.executeByDbAndTableIndex

如存在上述用法,在切换前需业务主动控制停写

参考文档 4.2 指定某库某表操作 |

| --- | --- |

| ☐ | [会初始化数据源写入迁移库表] 的gavin定时任务/服务自身定时任务是否已经停止?[说明:这里的gavin任务特指------ 每次启动后会初始化(创建)数据源的gavin任务 ,因为如果在 切换时刻该gavin任务启动 ,可能会 造成切换不彻底数据错误 等情况发生!!!因此为了避免不必要的切换风险,用户需要停止该gavin任务] |

| --- | --- |, | ☐ | 迁移切换步骤执行中禁止 扩容、缩容、发版、重启 操作是否知晓?[仅在运维管理员操作切换过程中,非切换时候可以 扩容、缩容、发版、重启, 切换完成后可以 扩容、缩容、发版、重启 ]

  • 重启后 到 数据源切换完成前 不建议 进行 扩容、缩容、发版、重启操作
  • 在 告知管理员打点截图后 到 切换完成前 一定不能 进行上述操作。这段时间可能造成切换任务异常,导致数据不一致; 业务需在业务自己内部群发公告周知
  • 如果有这段时间有操作需求的话,事后需要 重新告知打点数
  • 数据源切换完成 到 结单前 不建议 进行 扩容、缩容、发版、重启操作
  • 如果业务接入了弹性扩容的话 建议在 重启、告知管理员打点截图后 到 结单前 把 弹性扩容的功能关闭
  • 如果有这段时间有操作需求的话,在重新关闭后需要 重新告知打点数 |
    | --- | --- |]

document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/1. 工单服务/1.3 一键迁移

contents: [> - 太极校验所需字段,用于校验源端目标端数据的一致性,没有全局唯一字段需进行改造,或者借助帮我生成

复制代码
- 使用分布式ID生成器进行改造,参考文档 [4.9 分布式ID生成器]
- 自动生成唯一键(<b><i>注意:单表情况下可以保证全局唯一,分表情况下只能保证各个单表的唯一性</i></b>)
复制代码
  ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fnote.pdd.net%2Fapi%2Fpuddle%2Fdownload%2Ffile%3Ffile%3D757732824048345088%26preview%3Dtrue%26thumbnail%3Dtrue%26targetId%3D757271307413573632&pos_id=img-C5ftFUH1-1770298943621)
  • 3、更新字段

  • 选择的更新字段为unix时间时,太极迁移需要明确时间单位为秒还是毫秒
    keychain允许扫全表 , > - 1、全表扫描需要根据业务实际自主选择,其他keychain配置默认与源端一致。 如果一条SQL语句不携带主维度/辅维度,或携带的主维度/辅维度无法明确计算出落到哪张分表上,需要开启全表扫描开关才能执行,否则会抛异常。原则上不建议使用这类SQL,会出现很多慢SQL。 风险详见zebra文档:https://note.pdd.net/doc/457199513882542080

  • 2、一键迁移不支持附加路由。

  • 3、一些单库sql迁至分库分表后不被Zerba-client支持,请在胡桃街验证。
    写keychain类型 , > - 1、读写分离:数据源切换过程中,写请求 短暂的中断**,读请求** 不受影响(避免长时间占用单个读连接)。但如果有 请求 使用了 强制走主库的方式,这些 请求会跟 请求一起短暂中断

  • 2、单库读写:数据源切换过程中,读写请求 同时短暂中断

  • 【说明】:, > - 中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。

    • 建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。
      【注意】 , > - 读写分离数据源在切换到目标端 --> 切断源端读连接过程中,如果业务持续占用老connection不释放,会有读旧数据的可能
  • 如果业务可以忍受短暂gap读老数据,希望读请求不中断,建议读写分离

  • 如果对于读一致性要求比较高,建议主库读写
    路由规则

  • 1、手动输入:业务依据拆分库表数量,自行编辑路由规则,需要保证路由规则的正确性,注意: 这里路由规则编辑错误可能导致整个工单失败,需重新提单从头执行!

  • 2、帮我生成路由:

  • 编辑路由规则

    • 注:单张分表总数需是分库个数的整数倍]API Request

Calling function pga_knowledge_read_document_link({"link":"https://note.pdd.net/doc/477471887004295168"})
https://note.pdd.net/doc/477471887004295168

MySQL同步-事务支持

一.特性保证

事务通道

  1. 单事务完整性:写到目标库的事务内容与源库保持完全一致

  2. 多事务有序性

    a. 串行:目标端事务执行顺序与源端执行的顺序完全一致。(默认选项,注意:完全串行性能很低,主站TPS < 800,保供因远距离、MySQL性能低、太极资源复用严重TPS < 200,详见:【保供】太极MySQL通道跨DR吞吐)

    b. 行级别并行:包含相同行(主键、唯一键相同)的事务需要与源库保持有序。没有相同行的事务(即两个事务没有行交集)并行执行提高效率。

  3. 事务模式和非事务模式可通过参数配置进行模式切换且兼容。

数据校验

  1. 数据正确性校验:校验源端和目标端数据一致性,保证两端数据的正确性。

二.特别注意

大事务拆分

当源端一个事务超过2000个,会进行事务拆分,在目标端会表现为多个事务执行。

太极同步目标库 DTS消费注意项

当有主键批量更新时,目标库DTS中会拆成多条消息

如表A包含列a, b, c, d, e, f,其中a 和 b为联合主键,业务在源库执行 update b=b1, c=c1, d=d1, e=e1 where a in (a1,a2,a3,a4),太极同步到目标库时会被拆分为update b=b1, c=c1, d=d1, e=e1 where a =a1; update b=b1, c=c1, d=d1, e=e1 where a=a2; update b=b1, c=c1, d=d1, e=e1 where a=a3; update b=b1, c=c1, d=d1, e=e1 where a=a4。业务消费DTS的结果为:源库DTS消费是一条消息,包含4行变更,目标库的DTS消费有4条消息,每条消息1行变更。

当有太极通道重启时,如果存在同一行数据连续变更,目标库DTS中可能存在消息丢失或错误

在太极通道重启或任务解绑绑定等情况,会重复执行部分已执行的事务,导致重复执行的事务可能丢失部分状态或者产生错误状态。如单个事务内包含insert a , insert b , delete a操作,太极正常同步时目标库的事务保持和源库完全一致,但如果发生太极发版/机器宕机等情况,导致这个事务要重新同步,会出现丢失insert b的状态。如一个事务包含:update a1 -> a2 , update a2 -> a3,执行第一遍 包含 2个DTS消息 ,消息1:before a1 after a2,执行第二遍 包含两个DTS消息,消息1:before a3 after a2,就会产生错误状态。

三.场景支持

太极平台

数据同步-MySQL 单实例:https://taiji.pdd.net/workflow/sync/db

数据同步-MySQL 镜像同步:https://taiji.pdd.net/workflow/sync/mirror

数据备份-MySQL 单实例:https://taiji.pdd.net/workflow/backup/db

数据迁移-MySQL 单实例:https://taiji.pdd.net/workflow/migration/migrate

DRC平台

多活同步-MySQL 单区写:https://drc.pdd.net/workflow/sync/shardlive

多活同步-MySQL 单元化:https://drc.pdd.net/workflow/sync/shardunit

多活同步-MySQL 镜像同步:https://drc.pdd.net/workflow/sync/mirror

事务同步case介绍

保证单个事务完整性和数据最终一致性,不包含相同行的事务写入目标DB时可能乱序,可最大限度提升同步效率。

事务并行(安全case)

事务并行(不安全case1)

trx4和trx2这两个源端mysql的事务,从binlog数据层面分析没什么关系,变更的是不同的行,但是业务逻辑上有先后顺序,业务预期trx4变更的数据先可见,trx2变更的数据后可见

但是在目标端,可能被太极乱序回放,可能先可见trx2,后可见trx4(即便乱序回放,目标端数据和源端数据是保证一致的)

事务并行(不安全case2)

API Request

Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "跨库 跨表 事务 限制 不支持", "topk": 15})

document_path: /太极-用户文档/注意事项-太极/MySQL同步-使用限制

contents: [# MySQL同步-使用限制

  • 源和目标不能包含相同的MySQL实例
  • 目标MySQL实例配置需不低于源MySQL实例
  • 同一个源和目标MySQL之间不能存在多个同步
  • 不支持MySQL Keychain既有分库分表,又有单库单表]

document_path: /太极-用户文档/内部项目支持/供应链DB CN迁移US 信息登记

contents: [# 供应链DB CN迁移US 信息登记

一.背景

供应链团队需要迁移部分半托管服务从CN区迁移至美区,相关DB同时也需要做相关迁移,因为牵涉到上下游比较多。

太极临时支持双向同步(注意:实时同步后,就是双向同步,太极同步ready后,业务在目标DB写数据也会同步回源DB,不是回滚时候才开反向同步),但是有以下限制:, 1. 业务控制切换流程,必须保证数据只能在单边写,不支持目标端同时有写入相同表的

  1. 具体切换过程需要DBA大佬@cass.he@darren.chen一起把控,控制禁写阶段的流量符合预期(可以选择直接回收禁写端所有keychain相关权限)

  2. 多实例:工单类型:同步工单-> 太极分库分表提单地址 ,同步前需要确认是否有唯一键变更,并且该工单类型会导致DTS和大数据中间态丢失,业务需要自己评估

  3. 单实例:工单类型:同步工单-> 太极跨境单实例提单地址,同步前需要确认是否有唯一键变更

  4. 支持同步部分表以及表中的部分数据(建议全量同步表中数据,流程简化)

  5. 分库分表类型:支持实例数不同,库名不同(建议保持一致,流程简化),不支持路由规则不同,避免复杂度

  6. 业务需要提前申请目标端的实例,单实例支持同步表结构,分库分表需要业务提前创建, 8. 迁移过程中需要执行DDL流程,需要联系@boom.jiang@cass.he@darren.chen进行确认

二.迁移信息

三.提单流程

统一提单流程:, 1. 登记迁移信息 https://note.temu.team/doc/776276744202715136#GU4ScX,确认登记完成后,需要等DBA大佬录入元信息完成 ,后续进行太极工单提单太极跨境/跨产品域同步-提单指南,在信息栏中进行登记

  1. 单实例:如果是非分库分表:工单管理 ---->数据同步 ---->MySQL单实例 (快捷URL是:太极跨境单实例提单地址 【如果上面的地址提单失败,可以采用备用地址:太极跨境单实例提单备用地址】),需要勾选同步方式:双向 ]API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "分库分表 SQL 限制 不支持", "topk": 15})
    document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/1. 工单服务/1.4 DDL_DML变更
    contents: ['update_at', 'updated_at', 'gmt_modified','update_time', 'updated_time','audit_updated_at', ### 19

🚫 修改列的属性从 null 变成 not null default xxx风险如下:

1、走online DDL。

复制代码
    1)需要记录小于10w行或者表大小小于500M。

    2)  存量数据不存在null值,支持ALGORITHM=INPLACE。如果DDL增量过程也不会产生null值,可以更改成功。如果产生了null值,参考下一项。

    3)存量数据存在null值,当sql_mode包含STRICT_TRANS_TABLES、STRICT_ALL_TABLES报错ERROR 1138 (22004): Invalid use of NULL value,不包含可以改成功,但是需要关注数据截断的风险。

2、走ghost。

复制代码
    1)存量数据存在null值,则拷贝数据过程中报错ERROR 1048: Column cannot be null。

    2)在DDL未完成之前,增量数据没有指定该列赋值,依然会报错ERROR 1048: Column cannot be null。, 3)存量和增量都不存在null值,可以更改成功。

解决办法:1、修改所有该表相关的SQL语句指定该列赋值。2、修改存量表中null数据为not null。

另外,业务SQL里如果有包含指定列=null,也会报错。

1.4.3 DDL 模板示例

👉👉👉 工单地址

sql 复制代码
-- ❤️ 提醒 ❤️

-- !!!禁止将CREATE分表和CREATE单表写在同一个工单中 

-- !!!分库分表不支持创建分区表, -- 建表模板
   -- @单库单表:以下字段是所有表均须存在的字段
      CREATE TABLE table_model (
        id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '数据库自增id,无业务意义,任何业务场景都请不要依赖该字段(包括大数据)',
        created_at datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', 
        updated_at datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',      
        is_deleted tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0-未删除;1-删除',
        PRIMARY KEY (id),, KEY idx_created_at (created_at),
        KEY idx_updated_at (updated_at)
      ) ENGINE=InnoDB AUTO_INCREMENT=1 COMMENT='模板表';, #### **报错提示 类型2**:"<font color='red'>实例当前为多活集群的目标端,禁止提单DDL/DML</font>" 

> 报错原因:提单实例接入过多活,且为多活集群的目标端

> 解决办法:一般情况下,多活集群的目标端不允许提DDL单。正常操作流程是业务在源端提交DDL工单,太极负责同步到目标端

> 如果特殊情况需对目标端进行操作,需要拉实例归属负责人、太极支持人员(商周、松临、何萧)、业务线 DBA 、河伯平台(千仞)四方人员一起确认

> 确认需要在目标端实例提单的,可由DBA 提单(此处提交的 DDL 工单通常 不会引起表结构变化的SQL,比如碎片整理,DBA提单跳过检查), #### **报错提示 类型3**:"<font color='red'>实例所在单元{x}和多活集群流量单元{y}不符,多活集群只能从中心区提单</font>"

> 报错原因:提单实例接入过多活,但是实例所在单元和多活集群当前流量单元不符

> 解决办法:需选择多活集群的中心区单元实例提DDL单,太极会负责同步到目标端

> 如果特殊情况需对所选实例进行操作,需要拉实例归属负责人、太极支持人员(商周、松临、何萧)、业务线 DBA 、河伯平台(千仞)四方人员一起确认

> 确认需要在当前所选实例提单的,可由DBA 提单(DBA提单跳过检查), #### 报错提示 类型4: "<font color='red'>Shard建表不允许创建单表,必须指定分表规则。</font>"

> 报错原因:当前分库分表DB内,不允许创建单表。 单表在多个库里面表名相同<font color='red'>且无数字后缀</font>,属于特殊用法,目前禁止创建这种表,如果是业务表,建议改造为shard表。

> 解决办法:

> 1、若使用了ring sequence方案,必须在每个分库单独创建sequence表,请联系业务线DBA确认,并通过提非常规工单来解决;

> 2、非1中场景,是业务表,请改为shard表的方式来使用,兼容后续太极迁移拆分功能;
```, Summary of the 0th Table:
<table>
<thead>
<tr>
<th>序号</th>
<th>DDL/DML 限制规则 (⛑ 有限支持, ❌ 不支持,⭕️ 支持,🚫 限制)列表</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>⛑ 生产环境不支持修改列名(即 不支持 change 语法),htj 环境未发至生产的列名可修改</td>
</tr>
<tr>
<td>2</td>
<td>⛑  生产环境不支持删除列(no drop column),htj 环境未发至生产的列可删除</td>
</tr>
<tr>
<td>3</td>
<td>❌ 不支持外键、触发器</td>
</tr>
<tr>
<td>4</td>
<td>❌ 不支持使用 after, before 修改列的位置</td>
</tr>
<tr>
<td>5</td>
<td>❌ 不支持重命名索引(no rename index)</td>
</tr>
<tr>
<td>6</td>
<td>❌ 禁止SQL语句中 use 某个库</td>
</tr>
<tr>, <td>7</td>
<td>❌ 不允许 insert 时不指定字段列表</td>
</tr>
<tr>
<td>8</td>
<td>❌ DML 工单提交语句影响行数不能大于 50000 行</td>
</tr>
<tr>
<td>9</td>
<td>❌ DML 工单不支持分库分表全表DML(可按单实例对应分表DML)</td>
</tr>
<tr>
<td>10</td>
<td>❌ Shard(分库分表/单库分表)下,不允许创建无数字后缀单表,<a href="https://note.pdd.net/doc/458679580676067328#KhUKbf">解决方案</a></td>
</tr>
<tr>
<td>11</td>
<td>⭕️ 支持删除表(drop table yes)</td>
</tr>
<tr>
<td>12</td>
<td>⭕️ 支持清空表(truncate table yes)</td>
</tr>
<tr>
<td>13</td>
<td>🚫 复合索引最多允许 10 列</td>
</tr>
<tr>
<td>14</td>]

document_path: [/太极-用户文档/注意事项-太极/MySQL同步-使用限制](https://note.pdd.net/doc/423141665006473216)
contents: [# MySQL同步-使用限制

- 源和目标不能包含相同的MySQL实例
- 目标MySQL实例配置需不低于源MySQL实例
- 同一个源和目标MySQL之间不能存在多个同步
- 不支持MySQL Keychain既有分库分表,又有单库单表]

document_path: [/DBA文档中心/Mountain-- MySQL资源一站式管控平台/5. 常问问题/5.4 大表如何处理/5.4.3 分区表](https://note.pdd.net/doc/458679611040661504)
contents: [# 5.4.3 分区表
## 5.4.3.0 分区表创建示例

```sql
-- 注: 分区键(如 pt字段) 必须是主键、UK 中的一部分,不然无法成功创建, -- by range
CREATE TABLE `sample_table` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `cluster_name` varchar(100) NOT NULL DEFAULT '' COMMENT 'cluster_name',
  `ip_addr` varchar(64) DEFAULT NULL COMMENT 'ip_addr',
  `username` varchar(30) DEFAULT NULL COMMENT 'username',
  `collect_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收集时间',
  PRIMARY KEY (`id`,`collect_time`),
  KEY `idx_collect_time` (`collect_time`),
  KEY `idx_cname_time` (`cluster_name`,`collect_time`), ) ENGINE=InnoDB AUTO_INCREMENT=17423633126 DEFAULT CHARSET=utf8mb4 COMMENT='表的comment'
PARTITION BY RANGE ( TO_DAYS(collect_time))
(
PARTITION p20230417 VALUES LESS THAN (738993) ENGINE = InnoDB,
 PARTITION p20230418 VALUES LESS THAN (738994) ENGINE = InnoDB,
 PARTITION p20230419 VALUES LESS THAN (738995) ENGINE = InnoDB,
 PARTITION p20230420 VALUES LESS THAN (738996) ENGINE = InnoDB,
 PARTITION p20230421 VALUES LESS THAN (738997) ENGINE = InnoDB,]API Request
Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "分库分表 跨库事务 不支持 Zebra", "topk": 15})
document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极/[Mysql]分库分表-数据迁移](https://note.pdd.net/doc/202800990481293312)
contents: [### 1.2 mountain上申请keychain

申请地址:[https://mountain.pdd.net/#/order/applyhome](https://mountain.pdd.net/#/order/applyhome)  
使用太极的分库分表功能时, keychain: **不能选只读模式(只读模式的keychain,太极没办法识别数据库地址是否为主库)**

如果使用 数据源切换功能,keychain申请中 读写类型 需要注意:

![这张图片展示了在Mountain上申请keychain时的读写类型选择界面,包括"读写分离"、"只读模式"和"单库读写"选项。结合上下文,它用于指导用户在数据源切换过程中正确选择读写类型,以避免读写请求的中断问题,确保业务的稳定运行](https://note.pdd.net/api/puddle/download/file?file=202800990409752576&preview=true&thumbnail=true&targetId=202800990481293312), 读写分离:数据源切换过程中,**写请求** **短暂的中断**,**读请求** **不受影响**(避免长时间占用单个读连接)。但如果有**读**请求 使用了 [**强制走主库的方式**](https://docs.pdd.net/zebra/configuration/group-configs.html?h=%E5%BC%BA%E5%88%B6),这些**读**请求会跟**写**请求**一起短暂中断**。

单库读写:数据源切换过程中,**读写请求** **同时短暂中断**。

*说明:*

- *中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。*
- *建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。*

> keychain规范

1. 源端和目标端的keychain中的逻辑表数量需要一样
2. keychain中的路由规则,需要保证数据均匀分布,避免数据明显倾斜或者某些库表中永远不会有数据的情况, 分库分表路由的配置参考:[zebra文档](https://docs.pdd.net/zebra/configuration/shard-configs.html)
## 2. leo上配置keychain

需要在业务leo项目里配置 zebra 使用的keychain(不要在代码里直接写死keychain)  
注意: 这个leo的配置很重要,在切换到新的数据源后,结单前,需要将该key的值改成新的数据源keychain。务必提前配置好!!
## 3. 使用zebra接入数据源

如果不使用太极数据源切换功能,可以跳过此步  
使用要求详见:[Zebra使用要求](https://note.pdd.net/doc/202796405263151104#PU42ki)
## 4. 太极提单
### 地址, ### 页面

![这张图片展示了太极数据迁移系统中MySQL分库分表配置界面,重点说明了任务名、业务线、源端和目标端keychain等关键配置项的填写方法及注意事项,帮助用户正确配置数据迁移任务,确保数据源切换的顺利进行](https://note.pdd.net/api/puddle/download/file?file=224988238840389632&preview=true&thumbnail=true&targetId=202800990481293312), ### 配置项说明

**任务名**:必填,分库分表任务名,尽量 体现出库名,表名等信息  
**业务线**:必填  
**源端keychain**:必填,切换前,业务代码中使用的 老的数据源keychain  
**目标端keychain**:必填,切换后,业务代码中使用的 新的数据源keychain  
**自定义两端表名对应关系**:如果目标DB 中 逻辑表名 与源DB不一致,可以在此配置映射关系。  
列名映射 和 列黑白名单:如果目标DB 中 列名,列的数量 与源DB 不一致,可以在导入配置后,给相应的逻辑表 设置 列名映射,列黑白名单。
#### Keychain说明

提单也可以使用json代替keychain导入配置。

json的使用场景:

  1. 不想走流程申请keychain,可以使用json提单。

  2. 分库分表的规则很老,所有分库名都一样(不带数字后缀),keychain不能表达,可以使用json提单。

    注意:使用json后则不能使用太极数据源切换功能

    json示例:]

    document_path: /太极-用户文档/开始使用-太极/数据迁移-太极/[Mysql]单实例-数据迁移(使用太极数据源切换)
    contents: [[Mysql]单实例-数据迁移(使用太极数据源切换)

    特性

    • 接入简单(提单只需要两个keychain)
    • 自动创建库表
    • 数据同步与校验
    • 库表映射
    • 库表黑白名单
    • 列名映射
    • 列黑白名单
    • 支持 事务同步
    • 自动数据源切换(3-5秒禁写,读不受影响)
    • 开起迁移流程后,业务不能对要迁移的库表执行DDL
    • 支持 特定的Where条件

    一、业务准备工作

    如果 符合 Mountain一键迁移要求,可忽略准备工作中的 申请资源太极提单 步骤,在Mountain上提 1.3 一键迁移 工单。

    1. 申请资源

    MySQL机器申请

    请联系DBA
    说明:库表结构,太极会自动创建的。, ### mountain上申请keychain
    申请地址:https://mountain.pdd.net/#/order/keychaincreate
    如果使用 数据源切换功能,keychain申请中 读写类型 需要注意:

    读写分离:数据源切换过程中,写请求 短暂的中断读请求 不受影响(避免长时间占用单个读连接)。但如果有 请求 使用了 强制走主库的方式,这些 请求会跟 请求 一起短暂中断

    单库读写:数据源切换过程中,读写请求 同时短暂中断。, 说明:

    • 中断时间长短 主要由 数据源连接池加载速度决定,一般情况整个中断时间:3-5秒。
    • 建议业务使用 读写分离(如果业务读请求需要打到MySQL master,那么可以申请读写分离时,指定IP都为master地址)。

    2. leo上配置keychain

    需要在业务leo项目里配置 zebra 使用的keychain(不要在代码里直接写死keychain)

    注意: 这个leo的配置很重要,在切换到新的数据源后,结单前,需要将该key的值改成新的数据源keychain。务必提前配置好!!

    3. 使用zebra接入数据源

    使用要求详见:Zebra使用要求

    4. 太极提单

    地址, ### 页面

    , ### 配置项说明
    任务名:必填,迁移任务名,尽量 体现出库名,表名等信息
    业务线:必填
    源端keychain:必填,切换前,业务代码中使用的 老的数据源keychain(如果不使用太极数据源切换,可以直接用DB的IP地址)
    目标端keychain:必填,切换后,业务代码中使用的 新的数据源keychain(如果不使用太极数据源切换,可以直接用DB的IP地址)
    Schema白名单:必填,需要同步的schema名(库名),表名。支持输入正则。
    Schema黑名单:不需要同步的schema名(库名),表名。支持输入正则。
    库表映射配置:如果目标DB 中 库名,表名,列名 与源DB不一致,可以在此配置映射关系。列黑白名单也在此进行配置。

    注意:Schema白名单一定要填,如果白名单中使用了正则,但正则中个别表不想同步,可以使用Schema黑名单进行过滤。

    二、审批]

    document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/Zebra疑难问题汇总/[ZEBRA] 2023_03_07 elvisdb切换 UncategorizedSQLException异常持续时间过长
    contents: [

    TCP指标 Summary of the 3th Table:
    实例 异常
    10.25.101.89
    10.23.126.60
    10.23.104.84/
    10.22.29.210
    10.25.160.160
    Summary of the 4th Table: ,
    服务 单实例 media_kevinelvisdb_48 QPS情况
    elvis-ms 300/21=15
    kevin-api 758/112=7
    kevin-ms 422/109=4
    elvis-api 3/152=0.02
    Summary of the 5th Table: , , ,
    实验 单机QPS 异常情况 异常在故障
    实验1 130image.png zebra-benchmark - problem - 服务大盘 - 服务端监控 Monitor 监控中心 (pdd.net) 15/15个实例在持续7次切换后,持续存在异常,存在约6分,后续逐渐消失
    实验2 300image.png zebra-benchmark - problem - 服务大盘 - 服务端监控 Monitor 监控中心 (pdd.net) 2/15个实例在持续7次切换后,持续存在异常,存在约30分,后续逐渐消失
    实验3 700image.png zebra-benchmark - problem - 服务大盘 - 服务端监控 Monitor 监控中心 (pdd.net) 14/15个实例在持续7次切换后,持续存在异常,存在约30分,后续逐渐消失
    ]

    document_path: /DBA文档中心/Mountain-- MySQL资源一站式管控平台/Zebra疑难问题汇总/[2024-11-16]MySQL磁盘io抖动,zebra in查询导致的服务长时间无法恢复问题
    contents: [long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);

    复制代码
     //判断连接借出去的时间大小
     if (timeMillis >= removeAbandonedTimeoutMillis) {
         iter.remove();
         pooledConnection.setTraceEnable(false);
         abandonedList.add(pooledConnection);
     }

    }

    , # 【问题处理】 复制代码
    1. 业务服务重启。
       - DB抖动导致的隐患持续存在, 需要业务重启才能恢复。
       - 
       - 问题点:DB侧抖动后恢复,但是DBA无法感知业务报错是否收敛?需要依赖业务反馈。
       - 
    
    2. keychain 参数优化。对于removeAbandoned=false,在确保没有长事务的场景下,建议开启removeAbandoned=true,并设置removeAbandonedTimeout=180 (如果没有超过180s的事务,可以改为180s)。
       - 或者可以全局设置一个安全值。
       -, 3. Zebra版本升级。
       - 目前低版本zebra sdk在做多活禁写时可能会有连接池泄漏问题导致实例持续无法获取到连接,大量连接处于busy状态,新版本3.8.3.RC10已经修复该问题,大佬们可以关注下这个;
       - [https://packman.pdd.net/front/v2/packages/detail?group=com.dianping.zebra&artifact=zebra-api&artifactType=jar](https://packman.pdd.net/front/v2/packages/detail?group=com.dianping.zebra&artifact=zebra-api&artifactType=jar)
    
         ![image](https://note.pdd.net/api/puddle/download/file?file=800488437345820672&preview=true&thumbnail=true&targetId=800488416881594368), # TODO
    
     @筹谋 : 可以针对大shard先推动升级,我们这边计划先扫一下有用到zebra线程池的服务,按服务等级去推一下,预计这两天就能有个扫描结果。]
    
    document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极/[Mysql]数据源切换教程/太极迁移过程中业务使用过sequence表的情况梳理](https://note.pdd.net/doc/633777928371867648)
    contents: [
    <td>zebra_distributed_sequence_metadata <code>sql CREATE TABLE `zebra_distributed_sequence_metadata` (   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '数据库自增id,任何业务场景请不要使用',   `sequence_name` varchar(64) NOT NULL DEFAULT '' COMMENT '序列号名',   `generate_date` date NOT NULL COMMENT '生成日期',   `db_set` varchar(64) NOT NULL COMMENT 'db所在部署区',   `current_offset` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '已生成的offset',   `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', ,   `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',   `is_disable` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '是否禁用改offset',   `is_deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '是否逻辑删除',   PRIMARY KEY (`id`),   UNIQUE KEY `uk_sequence_date_db` (`sequence_name`,`generate_date`,`db_set`),   KEY `idx_created_at` (`created_at`),   KEY `idx_updated_at` (`updated_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='序列号生成表'</code></td, >
    <td><strong>支持太极迁移,不需要处理</strong>  升级指南<a href="">zebra多活自动填充sequence使用指南</a></td>
    </tr>
    </tbody>
    </table>]
    
    document_path: [/DBA文档中心/Mountain-- MySQL资源一站式管控平台/值班常问问题](https://note.pdd.net/doc/577448115145744384)
    contents: [> To solve the one or the other, follow the following advices:
    
    1. Verify and test them with `ping`.
    2. Refresh DNS or use IP address in JDBC URL instead.
    3. Verify it based on `my.cnf` of MySQL DB.
    4. Start the DB.
    5. Verify if mysqld is started without the `--skip-networking option`.
    6. Restart the DB and fix your code accordingly that it closes connections in `finally`.
    7. Disable firewall and/or configure firewall/proxy to allow/forward the port.
    
    > **注**:本段摘自 StackOverflow, 2、对于一个一直正常运行着,但应用突然报"**Connection refused** or **Connection timed out** or a MySQL specific `CommunicationsException:`**Communications link failure**" ,这些错,通常也意味着**数据库不可达**。 这种情况下的报错原因,通常是如下有几种原因中的一种:
    
    1. DB server is down.  # 数据库挂了
    2. Network Error. #  网络异常,TCP连接失效,应用的连接探活,可能触发上述报错
    3. Triggered some timeout parameter, e.g. **socket_timeout** . # 请求触发超时,将连接杀掉,导致连接失效
    4. APP Server has something wrong. # 应用服务异常,致自身连接不可正常请求,也可能自身机器有问题
    5. DB server has run out of connections. # 数据库连接数满了
    
    3、以下罗列场景包括但不限于这些场景:, 1. 生产常见**数据库挂的场景**有:a. 物理机硬件异常;b. 凌晨3~5点的日常运维切换;c.触发软件 Bug;
    2. 生产常见可能致网络异常的场景:a. 服务器网卡异常(应用侧、数据库侧任一端异常); b. 应用服务器与数据库间路由所经任一硬件异常; c. 网络拥堵;
    3. 生产常见可能触发超时场景**:**a. 慢查;b. 应用GC 或其他致应用长时间无响应的因素;
    
    **各位大佬遇到此类问题时,可先自行排除日常运维或者网络异常带来的报错,若仍无法解答您的疑惑再找 DBA小助手或者业务线 DBA 咨询**。
    
    Zebra 的 [7 常见问题FAQ](https://note.pdd.net/api/collab_pub/download/document?documentId=457199503913201664), 参考:[StackOverflow1](https://stackoverflow.com/questions/2983248/com-mysql-jdbc-exceptions-jdbc4-communicationsexception-communications-link-fai)、[StackOverflow2](https://stackoverflow.com/questions/2839321/connect-java-to-a-mysql-database/2840358#2840358)
    #### Q:新成员要访问数据库资源/获取权限/加入业务线,请走工单申请权限
    
    A: 👉👉 [保供环境](https://mountain.temu.team/order/joinprojectgroup?env=prod)、 👉👉 [生产环境](https://mountain.pdd.net/order/joinprojectgroup?env=prod)
    ## Keychain/Zebra 相关, #### Q: Zebra/Hikari/HikariPool 常见报错自查链接
    
    A:[7 常见问题FAQ](https://note.pdd.net/api/collab_pub/download/document?documentId=457199503913201664)
    #### Q: Keychain 如何申请添加 delete 权限?
    
    A: [1.5 keychain 变更](https://note.pdd.net/api/collab_pub/download/document?documentId=458679583863062528)
    
    Q: 服务启动的时候,第一次执行语句很慢,后面就恢复正常了
    
    A: 1、未开启连接池预热功能; 2、 spring在第一次执行SQL时需要加载一些资源导致  [详见](https://support-portal.pdd.net/?system=zebra&record_id=pKYGmYQBcFRkSOugmV-B)
    ## Bat 相关, #### Q1:"Caused by: com.pinduoduo.arch.keychain.client.exception.KeychainEncryptionException: keychain:[bat-keychain-auth-center.hutaojie-pub-new.60567552mA9qtN] 不存在或解析失败"
    
    A1: htj 环境用:bat-keychain-auth-center.hutaojie-pub-new.60567552mA9qtN     |   开发环境用:bat-keychain-auth-center.hutaojie-pub-new.62536284W7VsIy
    
    EasyDB 想着
    #### Q1:  easydb 权限没有了,怎么办? 之前申请的权限,现在没有了
    
    A1:1.  已申请权限 30天内未使用,权限会被回收,此时请重新申请; 2. 从未申请过的资源,请申请查询权限]
    
    document_path: [/太极-用户文档/开始使用-太极/数据迁移-太极/迁移工单用户最佳实践](https://note.pdd.net/doc/683005362669043712)
    contents: [### 9.4. 结单提示权限不对
    
    - 用户A:大佬无法结单,提示权限错误,但是我明明已经添加了权限
    - 运维管理员W:结单请参考文档:
      [MySQL迁移-结单说明](https://note.pdd.net/doc/532151337880055808),一步一步的按照文档做是不可能有问题的大佬!!
    ### 9.5. 目标端keychain能否提前替换
    
    切换后.....
    
    - 用户A:大佬我已经验证完毕,切换没有问题了,我是不是可以替换keychain然后重启服务了!
    - 运维管理员A:**不要**!只要**在结单操作的时候才能替换keychain为目标端keychain**,**然后重启服务**。否则提前重启服务会导致迁移工单无法回滚!先稳定观察一天没问题后再替换!, ### 9.6. 提单目标端keychian没有使用了
    
    切换后.....
    
    - 用户A:大佬提单的目标端keychain我现在其实已经没有使用了,结单无法结单怎么办?
    - 运维管理员W:既然已经用了新的非提单源端和目标端keychain(即第三个keychain),那么此时和太极已经关系不大了!大佬可以新创建一个leokey,里面配置一下提单的目标端keychain,结单的时候输出该新创建的LeoKey即可完成结单
    ### 9.7. sequence表迁移是否支持
    
    - 用户A:大佬太极迁移是否支持sequence表迁移?
    - 运维管理员W:单库情况下,迁移库表包含sequence表 + 迁移keychain是初始化sequence数据源的keychain则支持;分库分表需要分情况讨论
      - 普通的[本地模式](https://note.pdd.net/doc/457199536119967744)(DEFAULT_STEP BUFFER_STEP) **不支持迁移中同时迁移sequence表,** **需要业务在迁移前或者迁移后,单独迁移sequence表**, ![这张图片展示了在迁移过程中,普通的本地模式(DEFAULT_STEP和BUFFER_STEP)不支持同时迁移sequence表,需要业务单独处理。图片在文档中用于强调迁移sequence表的限制条件,帮助用户理解迁移策略和注意事项](https://note.pdd.net/api/puddle/download/file?file=689232409226854400&preview=true&thumbnail=true&targetId=683005362669043712)
        
      - 最新的[多活sequence模式](https://note.pdd.net/doc/586324871971852288)(DISTRIBUTED_STEP DISTRIBUTED_UNIT) 支持在迁移的同时迁移sequence表
        - **需要zebra版本 >= 3.8.3.RC3**, ![这张图片展示了在迁移过程中支持迁移sequence表的代码示例,重点标注了使用`DISTRIBUTED_STEP`类型时支持迁移,强调了最新多活sequence模式在zebra版本>=3.8.3.RC3时可实现迁移时同步迁移sequence表,与上下文讨论的迁移支持情况相呼应](https://note.pdd.net/api/puddle/download/file?file=689209937418022912&preview=true&thumbnail=true&targetId=683005362669043712), ### 9.8. 业务迁移过程中支持做DDL吗
    
    - 用户A:拆库持续时间比较长,中间有业务迭代,支持做DDL吗?
    - 运维管理员W:**不支持做DDL**
    - 用户A:那支持在迁移的库新增表吗?新增加的表不参与到迁移
    - 运维管理员W:如果**新增加的表不使用迁移的源端keychain读写是可以的**,但是如果用的访问keychain是源端读写keychain禁止添加!
    - 用户A:那如果新增加的表,需要参与到迁移呢?
    - 运维管理员W:**禁止**!如果非要这样那么请重新申请keychain,然后进行业务改造(将原来的keychain替换为新keychain),然后重新提交太极迁移工单(用新的keychain作为源端提单)]
    
    document_path: [/DBA文档中心/Mountain-- MySQL资源一站式管控平台/Zebra疑难问题汇总](https://note.pdd.net/doc/677602368270331904)
    contents: [Zebra疑难问题汇总]API Request
    Calling function pga_knowledge_read_content({"component_name": "MySQL-Lingqu-Taiji", "document_path": "/数据服务相关文档(公开)/MySQL相关规范/MySQL分库分表建议"})
    [/数据服务相关文档(公开)/MySQL相关规范/MySQL分库分表建议](https://note.pdd.net/doc/202899118441910272)
    # MySQL分库分表建议
    
    > 原 wiki 文档链接:[https://wiki.pdd.net/pages/viewpage.action?pageId=10710056](https://wiki.pdd.net/pages/viewpage.action?pageId=10710056)
    
    [拆分入口](https://mountain.pdd.net/order/shardMigrate?env=prod)
    
    [拆分文档](https://note.pdd.net/doc/458679578129448960)
    
    ## 1、拆分基准
    
    1. 非分库分表容量建议(超过下面标准的,建议做分库分表)
       a. 单表不超过5kw
       b. 单表大小不超过50G
       c. 单实例TPS<2000/s,QPS<8000/s(软限制),TPS+QPS<15000/s(硬限制)
       d. 单表tps<500,行DML<500,qps<=3000
    2. 分库分表建议
       a. 满足业务未来一定时期的容量和QPS需求,分库分表后单实例TPS<2000/s,QPS<8000/s;单表tps<100,qps<=200
       b. 分表后单表在500w行以下,大小 10G以下,保持单实例1T以下,使用水位50%以下
    
                示例 单表行数2亿行,分表后 
        - 2亿以下     1~4个分库或实例,128个分表 
        - 2亿~10亿   4~8个分库或实例,256个分表
        - 10亿~50亿 4~16个分库或实例 512~2048
        - 50亿~以上  8~64个分库或实例 1024~4096
          
    
    ## 2、拆分库表命名
    
     1)库名字以下划线+数字来命名,比如促销库分库分表 : pernod_0...pernod_1...pernod_2......
    
     2)【**使用全局唯一、alldb方式**】表名字以下划线+数字来命名,比如促销库分库分表:coupon_record_0...coupon_record_1...coupon_record_2......
    
     3) 拆分后的表确保要有全局唯一键
    
      
    
    ## 3、拆分业务依赖
    
    (1)对于已经有业务运行的大表的业务拆分,必须完全梳理出来当前的应用依赖。API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "跨库操作 同一事务 多个表", "topk": 15})
    API Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "Zebra 常见问题 FAQ 限制", "topk": 15})
    document_path: [/DBA文档中心/Mountain-- MySQL资源一站式管控平台/Zebra疑难问题汇总](https://note.pdd.net/doc/677602368270331904)
    contents: [Zebra疑难问题汇总]
    
    document_path: [/DBA文档中心/Mountain-- MySQL资源一站式管控平台/值班常问问题](https://note.pdd.net/doc/577448115145744384)
    contents: [2、对于一个一直正常运行着,但应用突然报"**Connection refused** or **Connection timed out** or a MySQL specific `CommunicationsException:`**Communications link failure**" ,这些错,通常也意味着**数据库不可达**。 这种情况下的报错原因,通常是如下有几种原因中的一种:
    
    1. DB server is down.  # 数据库挂了
    2. Network Error. #  网络异常,TCP连接失效,应用的连接探活,可能触发上述报错
    3. Triggered some timeout parameter, e.g. **socket_timeout** . # 请求触发超时,将连接杀掉,导致连接失效
    4. APP Server has something wrong. # 应用服务异常,致自身连接不可正常请求,也可能自身机器有问题
    5. DB server has run out of connections. # 数据库连接数满了
    
    3、以下罗列场景包括但不限于这些场景:, 1. 生产常见**数据库挂的场景**有:a. 物理机硬件异常;b. 凌晨3~5点的日常运维切换;c.触发软件 Bug;
    2. 生产常见可能致网络异常的场景:a. 服务器网卡异常(应用侧、数据库侧任一端异常); b. 应用服务器与数据库间路由所经任一硬件异常; c. 网络拥堵;
    3. 生产常见可能触发超时场景**:**a. 慢查;b. 应用GC 或其他致应用长时间无响应的因素;
    
    **各位大佬遇到此类问题时,可先自行排除日常运维或者网络异常带来的报错,若仍无法解答您的疑惑再找 DBA小助手或者业务线 DBA 咨询**。
    
    Zebra 的 [7 常见问题FAQ](https://note.pdd.net/api/collab_pub/download/document?documentId=457199503913201664), 参考:[StackOverflow1](https://stackoverflow.com/questions/2983248/com-mysql-jdbc-exceptions-jdbc4-communicationsexception-communications-link-fai)、[StackOverflow2](https://stackoverflow.com/questions/2839321/connect-java-to-a-mysql-database/2840358#2840358)
    #### Q:新成员要访问数据库资源/获取权限/加入业务线,请走工单申请权限
    
    A: 👉👉 [保供环境](https://mountain.temu.team/order/joinprojectgroup?env=prod)、 👉👉 [生产环境](https://mountain.pdd.net/order/joinprojectgroup?env=prod)
    ## Keychain/Zebra 相关, #### Q: Zebra/Hikari/HikariPool 常见报错自查链接
    
    A:[7 常见问题FAQ](https://note.pdd.net/api/collab_pub/download/document?documentId=457199503913201664)
    #### Q: Keychain 如何申请添加 delete 权限?
    
    A: [1.5 keychain 变更](https://note.pdd.net/api/collab_pub/download/document?documentId=458679583863062528)
    
    Q: 服务启动的时候,第一次执行语句很慢,后面就恢复正常了
    
    A: 1、未开启连接池预热功能; 2、 spring在第一次执行SQL时需要加载一些资源导致  [详见](https://support-portal.pdd.net/?system=zebra&record_id=pKYGmYQBcFRkSOugmV-B)
    ## Bat 相关, #### Q1:"Caused by: com.pinduoduo.arch.keychain.client.exception.KeychainEncryptionException: keychain:[bat-keychain-auth-center.hutaojie-pub-new.60567552mA9qtN] 不存在或解析失败"
    
    A1: htj 环境用:bat-keychain-auth-center.hutaojie-pub-new.60567552mA9qtN     |   开发环境用:bat-keychain-auth-center.hutaojie-pub-new.62536284W7VsIy
    
    EasyDB 想着
    #### Q1:  easydb 权限没有了,怎么办? 之前申请的权限,现在没有了
    
    A1:1.  已申请权限 30天内未使用,权限会被回收,此时请重新申请; 2. 从未申请过的资源,请申请查询权限]API Request
    Calling function pga_knowledge_read_document_link({"link":"<https://note.pdd.net/api/collab_pub/download/document?documentId=457199503913201664>"})
    Error: document link not existAPI Request
    Calling function pga_knowledge_retrieve({"component_name": "MySQL-Lingqu-Taiji", "query": "已知限制 提单必看", "topk": 15})
    document_path: [/太极-用户文档/已知限制(提单必看)/太极提单必看:主键唯一键变更处理能力限制及解决方案](https://note.pdd.net/doc/849320248006635520)
    contents: [# 太极提单必看:主键唯一键变更处理能力限制及解决方案
    
    简要阅读预计耗时:1min  
    完整阅读预计耗时:18min, ## 当满足什么条件时,我需要阅读此文档?
    
    当你需要太极的同步或者迁移的数据,满足以下条件时,你需要进一步阅读此文档。如不满足以下条件,那么读完此节就可以关闭此文档了。
    
    这些条件是:
    
    - **源端和目标端都是Mysql**
    - **表中具有主键(和/或)唯一键**
    - **会update表中的主键或者唯一键的值**
    
    PS:为方便描述,将以上三个条件统称为"**必要条件**"
    
    如果满足**必要条件**,那么你至少需要阅读至此文档的`**如果我的同步满足必要条件,我该怎么做?**`一节结束(预计耗时:1min),这会帮助你更顺利地完成太极同步/迁移。
    
    如果你想了解太极当前的解决方案及其限制,请至少阅读到`**当前解决方案及其限制**`一节(预计耗时:8min),这会帮助你更了解太极系统以及当前太极的能力限制。
    
    如果你还想了解太极为解决此问题而正在推进的解决方案及其上线计划,请至少阅读至`**远期解决方案及其预期上线时间**`一节(预计耗时:10min),这会告知你我们打算如何一劳永逸地解决问题,以及解决问题的代价。, 如果你想了解有哪些业务场景会突破太极的能力限制而导致同步出现问题,请阅读至`**已知问题归纳**`一节(预计耗时:18min),此节列出了我们已知的所有问题case,这可以帮助你更好地了解你的业务受此问题的影响程度。
    ## 如果我的同步满足必要条件,我该怎么做?
    
    - **在提单前,找到`太极灵渠小助手`,说你即将要提的工单有唯一键变更**
    - **mountain支持用户自助执行工单,如果你的同步满足必要条件,**切勿自助执行**!找到太极灵渠小助手,告知唯一键变更情况,让他帮你执行!**
    ## 太极同步满足必要条件的表时,会出现什么问题?
    
    有概率出现如下情况:
    
    - 全量同步或者增量同步期间出现键冲突
    - 数据校验出现目标端缺数据
    
    **以上问题可能会导致同步推倒重来或者漫长的修数据过程。**
    ## 为什么会出现这样的问题?(太极同步原理简述)
    
    - 太极同步分为两个阶段:
      - 全量同步:将表中的存量数据带到目标端
      - 增量同步:将同步开始后的增量变更带到目标端
    ### 全量同步]
    
    document_path: [/太极-用户文档/已知限制(提单必看)](https://note.pdd.net/doc/849320159318028288)
    contents: [已知限制(提单必看)]好的,让我先解释我的分析计划,然后基于检索到的文档信息来回答分库分表事务的问题。
    
    ## 分析计划
    
    1. 搜索MySQL-Lingqu-Taiji知识库中关于分库分表事务的相关文档
    2. 分析分库分表的技术原理和限制
    3. 总结分库分表场景下事务的处理方式和注意事项
    
    ---
    
    ## 分库分表事务说明
    
    根据检索到的文档信息和分析,以下是分库分表场景下事务的关键说明:
    
    ### 一、核心原则
    
    **分库分表不支持跨库事务(分布式事务)**
    
    分库分表会将数据分散到**不同的数据库实例**中,每个数据库实例是独立的MySQL实例。MySQL的本地事务只能在**单个数据库实例内**生效,因此无法跨越多个数据库实例保证事务的ACID特性。
    
    ### 二、事务支持范围
    
    | 事务类型 | 支持情况 | 说明 |
    |---------|---------|------|
    | **单库内事务** | ✅ 支持 | 同一数据库实例内的多个表操作,可以使用MySQL本地事务 |
    | **跨库事务** | ❌ 不支持 | 涉及不同数据库实例的操作,无法保证ACID |
    | **跨表事务(同库)** | ✅ 支持 | 同一库内的不同分表,可以使用MySQL本地事务 |
    | **跨表事务(跨库)** | ❌ 不支持 | 分布在不同库中的分表,无法使用事务 |
    
    ### 三、从文档中找到的相关限制
    
    从检索到的文档中,可以找到以下相关说明:
    
    1. **SQL限制(文档:DDL_DML变更)**
       - ❌ **不支持**:一些单库SQL迁至分库分表后不被Zebra-client支持
       - ⚠️ **需要注意**:如果业务是从单表迁移到分库分表,需要验证业务所有SQL兼容分库分表场景
    
    2. **事务同步(文档:MySQL同步-事务支持)**
       - 这部分是关于**太极同步平台**的事务支持,用于数据同步和迁移
       - **不是**关于Zebra客户端应用层的事务支持
    
    ### 四、实际场景示例
    
    #### ❌ 不支持的跨库事务场景
    
    ```sql
    -- 假设表A路由到库0,表B路由到库1
    BEGIN;
    -- 表A在库0
    UPDATE table_a SET amount = amount - 100 WHERE id = 1;
    -- 表B在库1
    UPDATE table_b SET balance = balance + 100 WHERE id = 1;
    COMMIT;

问题:这两个UPDATE操作会路由到不同的数据库实例,无法在同一个事务中执行。如果第一个成功但第二个失败,无法回滚第一个操作。

✅ 支持的同库事务场景
sql 复制代码
-- 假设表A和表B都路由到库0(使用相同的分库规则)
BEGIN;
-- 表A在库0
UPDATE table_a SET amount = amount - 100 WHERE id = 1;
-- 表B在库0
UPDATE table_b SET balance = balance + 100 WHERE id = 1;
COMMIT;

可行 :如果两个表使用相同的分库规则(如都按 user_id 分库),那么它们会路由到同一个数据库实例,可以使用MySQL本地事务。

五、解决方案

对于需要跨库事务的业务场景,可以考虑以下方案:

方案 说明 适用场景
业务层补偿 通过业务逻辑进行补偿,如TCC模式 对一致性要求不是特别严格
消息队列 使用消息队列保证最终一致性 异步场景,可以接受短暂不一致
统一分库规则 将需要事务的表使用相同的分库规则 可以解决大部分跨库事务需求
分布式事务框架 使用Seata等分布式事务框架 对一致性要求很高,但性能开销大
单库存储 将需要事务的表放在同一个库中 数据量不大的场景

六、注意事项

  1. 路由规则设计

    • 将经常需要一起事务操作的表设计为相同的分库规则
    • 例如,如果订单表和订单明细表经常需要事务操作,建议使用相同的分库字段(如 order_id
  2. 业务代码改造

    • 从单库迁移到分库分表时,需要检查所有涉及跨表事务的代码
    • 确保事务操作的数据能够路由到同一个数据库实例
  3. 数据一致性保证

    • 对于无法避免的跨库操作,需要设计补偿机制
    • 使用幂等性设计,避免重复操作导致的数据不一致

总结

分库分表不支持跨库事务,这是由分库分表的技术原理决定的。在设计和使用分库分表时:

  1. 支持:同一数据库实例内的本地事务
  2. 不支持:跨数据库实例的分布式事务
  3. 💡 建议:通过合理的路由规则设计,将需要事务操作的表路由到同一个库

如果您有具体的业务场景需要跨库事务,可以告诉我更多细节,我可以帮您分析合适的解决方案。

相关推荐
Java面试题总结2 小时前
基于 Java 的 PDF 文本水印实现方案(iText7 示例)
java·python·pdf
·云扬·2 小时前
MySQL Binlog 配置指南与核心作用解析
数据库·mysql·adb
马猴烧酒.2 小时前
【面试八股|Java集合】Java集合常考面试题详解
java·开发语言·python·面试·八股
天空属于哈夫克32 小时前
Java 版:利用外部群 API 实现自动“技术开课”倒计时提醒
数据库·python·mysql
测试工程师成长之路2 小时前
Serenity BDD 框架:Java + Selenium 全面指南(2026 最新)
java·开发语言·selenium
lang201509282 小时前
Java JSON绑定API:JSR 367详解
java·java-ee
luoluoal2 小时前
基于深度学习的web端多格式纠错系统(源码+文档)
python·mysql·django·毕业设计·源码
eWidget2 小时前
随机森林原理:集成学习思想 —— Java 实现多棵决策树投票机制
java·数据库·随机森林·集成学习·金仓数据库
Traced back2 小时前
SQL Server 核心语法+进阶知识点大全(小白版)
数据库·sqlserver