ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DMDRS迁移组合分区表子分区机制解析与踩坑实践

DMDRS迁移组合分区表子分区机制解析与踩坑实践 前阵子做一套业务系统的异构迁移源端有一张跑了三年多的订单流水表按月份做了范围分区每个月份分区下面又按城市做了列表子分区整体是“范围-列表”的组合分区结构。表不大大概1.2TB但分区数量非常可观36个父分区每个父分区下面挂20多个子分区。当时我直接用DMDRS跑了全量加增量迁移结果前两张表一切正常到这张组合分区表就出了幺蛾子——目标端的子分区结构跟源端对不上存储过程里按子分区做数据清理的脚本全跑偏了。事后复盘问题出在我对DMDRS迁移分区表子分区的机制理解不够透。这篇文章就把这块掰开揉碎讲清楚包括DMDRS在全量和增量两个阶段对分区表做了什么、组合分区和子分区应该怎么配、迁移完怎么验证结构一致性以及我踩过的几个典型坑。1. 为什么说分区表的迁移难点从来不在“搬数据”很多人一听“迁移分区表”第一反应是数据量大、传输慢。但真正在实操里折腾人的从来不是数据搬运本身而是分区结构能不能原样搬到目标端。DMDRS处理普通表的时候只要把表定义抓出来、数据灌进去、再开启日志解析补增量就行。但分区表不一样它多了一层“路由逻辑”源端的写入语句是通过分区键和分区定义找到具体分区位置的目标端如果结构对不上后续所有依赖分区的维护操作都会出问题。1.1 先认清常见的分区表家族在配置迁移任务之前得先知道源端的分区表属于哪一型。我给同事做培训的时候习惯这么分类范围分区RANGE最常用按时间、按数值区间切分。比如订单表按月分区每个分区对应一个月。列表分区LIST按离散的枚举值切分比如按城市、按业务线。哈希分区HASH按分区键的哈希值散列主要用来打散IO压力。组合分区COMPOSITE父分区下再挂一层子分区常见搭配有范围-哈希、范围-列表、列表-哈希。迁移组合分区表的时候问题就出现在“两层结构”上。父分区定义了数据的第一次切分维度子分区定义了第二次切分维度。DMDRS如果只识别到父分区把子分区定义丢了那目标端表结构虽然能建出来、数据看起来也进去了但实际上子分区边界是错的。等业务侧按子分区名去清理数据、交换分区、做归档的时候立刻原形毕露。1.2 从“表粒度”到“分区粒度”的思维转换复制工具处理普通表逻辑非常简单建表、导数据、日志追平。处理分区表时全程都要从表粒度降维到分区粒度甚至子分区粒度。比如数据装载阶段理想做法是按分区批量灌入而不是整表一把梭增量同步阶段源端做的SPLIT分区、MERGE分区、TRUNCATE子分区这类操作日志里记录的也不是“某张表变了”而是“某个分区的某个子分区被清空了”。DMDRS得能解析出这一层语义才能在目标端重放出正确的分区级操作。我见过不少人在迁移时只关注全量数据量和增量延迟忽略了对分区结构一致性的核对。结果就是迁移验收当天一切正常一个月后第一次跑分区维护脚本时才发现结构不对这时候再回头补结构成本高得多。2. DMDRS迁移分区表的内核机制拆解DMDRS做数据复制整体思路是“全量建立基线数据 增量日志追平”。这句话说起来简单落到分区表场景里有几个关键环节的处理直接决定成败。2.1 全量阶段表定义抓取不能只抓CREATE TABLE全量阶段的第一步是抓取源端表结构。普通表只需要把CREATE TABLE语句里的字段、约束、存储参数拿过来。分区表则要求在抓取表定义时同步拿到分区定义分区类型、分区键、每个分区的边界值、子分区模板、各个子分区的名称和边界。这里有个细节容易被忽略子分区有两种定义方式。第一种是使用子分区模板SUBPARTITION TEMPLATE父分区的每个分区都会自动套用模板生成相同结构的子分区第二种是逐个分区手工指定子分区不同父分区下面的子分区数量和边界可以不一样。DMDRS在抓取定义时对这两种方式都要能正确处理否则迁移到目标端的子分区结构就跟源端有出入。另外一个常踩的坑是间隔分区INTERVAL。源端如果用了自动扩展的间隔分区迁移到目标端后不能直接照搬“INTERVAL”关键字需要把已物化的分区逐个转成显式分区边界。DMDRS在全量阶段遇到这种表时我的处理习惯是先在目标端人工调整建表脚本再做数据装载避免结构生成阶段就埋雷。2.2 数据装载按子分区并行比整表导入靠谱大分区表的数据导入我强烈建议按子分区维度做并行装载而不是把整张表当成一个整体去导。DMDRS在全量阶段会识别分区键和子分区边界把数据按分区拆成多个装载单元以多个并行通道往目标端灌。这么做的好处有两个一是单个子分区数据量可控装载失败后重试粒度小二是能充分利用目标端的并行能力。如果你在配置任务时看到类似“分区并行度”“子分区并行通道数”的参数不要随手填个默认值建议根据目标端CPU核数和磁盘IO能力适当调大。我在实际项目中子分区并行度从默认的4调到16全量阶段耗时下降了将近一半。2.3 增量阶段日志解析必须读懂分区维护操作增量同步依赖归档日志或Redo日志解析。普通表场景日志里记录的DML操作是“INSERT INTO 表名”解析器只要把SQL重放到目标端就行。分区表场景麻烦在于源端会在运行期执行大量分区维护DDL比如ALTER TABLE ... TRUNCATE PARTITIONALTER TABLE ... SPLIT PARTITIONALTER TABLE ... MERGE PARTITIONSALTER TABLE ... EXCHANGE PARTITION这些操作在日志里对应的不是简单的DML而是带分区语义的DDL。DMDRS如果解析不到这一层目标端就不会执行对应的分区维护动作。我遇到过的典型情况是源端每周跑一次例行清理TRUNCATE掉三个月前的分区目标端由于没同步这个动作历史数据一直留着磁盘空间只增不减。所以在配置增量任务时务必确认你用的DMDRS版本对分区维护DDL有完整的解析支持并适当开启与DDL同步相关的选项。否则图省事的下场就是迁移后目标表的数据还在持续增长而你还找不到原因。3. 组合分区与子分区迁移的完整落地配置下面这部分用我最近一个项目的真实配置过程来演示。源端是某交易系统目标端是达梦数据库中间用DMDRS做在线迁移。源表结构大致是分区键交易日期RANGE按月子分区键城市编码LIST子分区模板每月分区下固定按20个城市拆子分区任务要求是白天业务不停全量灌完历史数据后自动追平增量最终切换。整体时间窗口给了48小时。3.1 迁移前检查清单动手之前一定先把下面几项确认掉源端和目标端的数据库版本、字符集是否兼容。字符集不一致会导致分区键边界值比较出错。目标端表空间是否已创建。源端的分区定义里如果带USERS等表空间迁移后如果目标端没这个表空间建表会直接报错。我在任务里干脆把所有表空间映射切换成目标端统一的DATA_TS。源端分区表和子分区表的数量统计。先跑一遍数据字典摸清总共有多少父分区和子分区迁移完成后核对用。目标端是否有同名表以及业务侧对这个表的分区维护脚本有哪些。这一步能帮你提前知道子分区命名策略重不重要。3.2 创建迁移任务时的关键参数DMDRS的迁移任务配置界面里对普通表和分区表用的其实是一套任务模板但有几个参数我建议你重点确认迁移对象粒度的选择选择按表搬迁不要选择按模式整体搬迁后单独排除某些表。快速装载模式大表建议开启但要注意它会影响索引的构建策略具体后面说。并行度与批量大小并行度根据目标端资源调整批量大小决定了单次提交的行数对分区表来说行数过小会导致每个子分区频繁提交影响装载效率。增量解析模式确认开启DDL同步尤其是分区维护类DDL。我之前踩过的一个坑就是默认批量大小太小导致目标端每个子分区都在“反复提交-等待-再提交”全量灌了一天都没灌完。调整批量大小后速度立刻上来了。另外如果你的DMDRS版本提供了“分区表识别”或“子分区映射”这类选项务必确认它是开启状态。有些版本默认只识别到父分区子分区会以普通数据混入父分区虽然数据不丢但结构已经不对了。3.3 任务运行时的观察重点任务启动后不要只在电脑前干等。我会重点关注三个地方第一全量装载日志里有没有出现“PARTITION”相关的警告。比如“分区边界无法识别”“子分区定义缺失”这类提示一旦出现基本可以断定目标端结构有问题赶紧停任务查。第二目标端对应表空间的数据增长曲线。如果某些子分区容量增长异常可能是源端数据路由和目标端不一致数据导错了分区。第三增量追平阶段的延迟趋势。正常情况延迟应该逐步下降并趋于稳定如果延迟一直居高不下多半是源端日志量太大或者解析端在处理分区操作时效率低下。4. 迁移完成后的结构验证别等跑脚本时才发现问题全量追平、增量延迟归零不代表迁移就真的成功了。我从第一次踩坑之后给自己定了一条铁律任何分区表的迁移验收时必须做分区结构比对比对的维度包括分区数量、分区键、边界值、子分区数量、子分区命名最后还要对每个子分区做行数抽样。4.1 元数据层面对比源端和目标端分别查数据字典重点看两张视图的记录数、分区名和边界值。源端查DBA_TAB_PARTITIONS目标端同样查询对应系统视图。通过对比能直观看到父分区数量是否一致、每个父分区的HIGH_VALUE是否完全相同。子分区层面重点对比DBA_TAB_SUBPARTITIONS看每个父分区下的子分区数量是否一致子分区名和边界值是否对得上。我遇到过目标端子分区名跟源端完全不同的情况虽然数据没丢但业务侧所有按分区名维护的脚本全部要改。所以这个比对不能只看数量一定要连名字一起核对。4.2 数据层面对比结构对了还要确认每个子分区里的数据也对了。最稳妥的做法是把源端每个子分区的行数统计出来目标端同样统计一遍两边做全量比对。这张表有800多个子分区手工一个个看肯定不现实。我当时写了一个简单的比对脚本递归查询每个子分区的COUNT(*)输出差异清单。比对结果全部一致后才算过了数据关。4.3 分区维护脚本的演练这是很多人容易忽略的一步。迁移验收时我会要求业务侧在目标端“演练”一遍他们例行的分区维护脚本跑一次按父分区清理历史数据的SPLIT或TRUNCATE操作确认所有分区名都能被脚本解析、所有边界值都符合脚本预期。提前发现问题总比切换到目标端之后再修要好。5. 踩过的坑和最终推荐的做法最后分享几个我在DMDRS迁移分区表子分区过程中真实踩过的坑以及对应的规避手段。5.1 子分区命名策略不一致第一个坑就是文章开头提到的子分区命名不一致。源端建表时部分分区用了显式子分区名部分分区依赖系统生成的默认名导致目标端在自动建表时生成规则不统一最终子分区名跟源端对不上。规避办法是在执行迁移前先统一源端子分区命名或者在建表脚本阶段手动锁定每个子分区的名称。迁移验收时以业务侧维护脚本里引用的分区名为准做一次全量核对。5.2 快速装载导致索引失效第二个坑是全量阶段开启快速装载后目标端部分二级索引没有自动构建完整。当时我查了目标端这表的索引状态发现几个索引处于UNUSABLE状态导致后续查询走了全表扫描数据校验慢得离谱。规避办法是快速装载结束后主动对目标端所有索引做状态检查发现失效索引立即重建。5.3 源端分区维护操作导致增量中断第三个坑出现在增量追平阶段。源端在正常业务窗口内执行了一次分区SPLIT结果DMDRS的增量解析进程直接停了。排查后发现是解析器对这类复合DDL的支持需要额外的参数配置。后来我在所有涉及分区维护的场景下都会提前确认源端的维护计划并在任务配置里打开DDL同步相关选项再加上实时告警确保解析进程挂掉的第一时间就能介入处理。5.4 我的推荐做法经过这几个项目我现在处理DMDRS分区表迁移的标准流程是先摸清源端分区体系再在任务配置阶段锁定结构同步选项接着在全量阶段按子分区并行装载然后增量追平后先做元数据比对再做数据比对最后让业务侧在目标端演练一遍日常分区维护脚本全部通过才允许切换。这套流程看起来繁琐但每一步都对应着我曾经踩过的坑。尤其是子分区结构一致性这件事宁可多花两三个小时验证也不要等系统跑起来之后再来补救。如果你也在用DMDRS做分区表或组合分区表的迁移我建议你把源端所有分区和子分区的清单导出来存一份目标端验收时逐项比对。这个习惯不复杂但能帮你省掉很多半夜被叫起来处理分区数据错乱的麻烦。
返回列表