通过DTS迁移MongoDB数据后,您可能会发现目标实例与源实例上的数据量有所变化。本文将介绍排查数据量不一致的方法。
排查思路与方法
迁移完成后,如发现源实例和目标实例的数据量存在差异,您可以依次排查以下项:
表内文档条数是否一致。
索引个数以及大小是否一致。
WT引擎的可重用空间大小是否一致。
建议您通过mongo shell分别连接源实例和目标实例,执行以下命令确认数据量差异的原因:
文档条数
db.<collection>.stats().count
索引
db.<collection>.stats().indexSizes
可重用空间
db.<collection>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
测试结果
本文中迁移测试的环境说明如下。
项目 | 说明 |
地域及可用区 | 源实例和目标实例均位于华东1(杭州)地域可用区H。 |
实例版本及规格 | 源实例和目标实例版本及规格完全一致,具体参数如下:
|
库表个数 | 4个表,分别为test1、test2、test3和test4。 |
测试负载 | 采用YCSB压测工具进行压测。 |
表内文档条数 | 400万条。 |
文档总大小 | 10 KB左右,为10个纯二进制数据的字段。 |
迁移完成后源实例和目标实例的数据对比如下。
对比项 | 源实例 | 目标实例 | 差异(百分比) |
count (文档数) | 4 * 4000000 | 4 * 4000000 | 0% |
size (逻辑存储大小) | 4 * 4671518072 | 4 * 4671518072 | 0% |
storageSize (物理存储大小) | test1:10284060672 test2:9059483648 test3:8771850240 test4:9562763264 | test1:4786364416 test2:4786380800 test3:4801978368 test4:4786257920 | test1:5.1GB(53%) test2:3.9GB(47%) test3:3.7GB(45%) test5:4.4GB(50%) |
indexSize (索引大小) | test1:{ "_id_" : 197046272 } test2:{ "_id_" : 210997248 } test3:{ "_id_" : 211079168 } test4:{ "_id_" : 201854976 } | test1:{ "_id_" : 97783808 } test2:{ "_id_" : 97742848 } test3:{ "_id_" : 102924288 } test4:{ "_id_" : 97742848 } | test1:0.09GB(50%) test2:0.11GB(53%) test3:0.1GB(51%) test4:0.1GB(52%) |
reuse size (重用空间大小) | test1: 4987596800 test2: 3646660608 test3: 3984535552 test4: 4774940672 | test1:237568 test2:237568 test3:176128 test4:237568 | 不涉及 |
storage-reuse (物理存储大小-重用空间大小) | test1: 5296463872 test2: 5412823040 test3: 4787314688 test4: 4787822592 | test1:4786126848 test2:4786143232 test3:4801802240 test4:4786020352 | test1:0.47GB(9.6%) test2:0.58GB(11.6%) test3:-13.4MB(-0.3%) test4:1.7MB(<0.1%) |
通过上表可以得出以下结论:
源实例与目标实例的文档数和逻辑存储大小一致,表示DTS已经成功将数据从源端迁移到目标端。
源实例的存储和索引占用的空间更大,这种情况是因为源实例在DTS迁移前执行过一批UPDATE操作。
相同文档数以及逻辑大小的合集,实际的物理大小也会有细微差异。
排除索引大小以及重用空间大小后,源实例和目标实例的存储空间依然可能有10%左右的差异。
数据的写入方式不同,可能会导致两个相同文档条数的实例的存储大小不同,因为WiredTiger页面的存储和拆分方式可能不同,索引的生成方式有所差异,为了对齐而填充(padding)的内碎片以及数据块的压缩率也会有所差异。因此,源实例和目标实例存储空间大小差异在10%以内都属于符合预期的情况。
补充说明:DTS的实现原理
不同于云数据库MongoDB的物理备份和快照备份,DTS为了兼容更多版本以及不同架构,使用了逻辑同步的方式。所有的文档数据都会被重新插入一遍,因此索引也会重新生成。
DTS迁移数据分为全量迁移和增量迁移两个步骤,这两个步骤均属于逻辑同步,类似于mongodump和mongorestore。全量迁移和增量迁移的迁移流程如下:
全量迁移:DTS会扫描源端每个表的全部记录,然后批量插入到目标端,理论上每个表单线程并发迁移,如果单表的内容非常多,DTS会把大表按_id分段拆分,然后每个范围一个线程迁移,总线程数会控制一个上限。
增量迁移:DTS会直接拉取源端的oplog,然后在目标端回放。
更多关于DTS的介绍,请参见什么是数据传输服务DTS。