浅究Oracle迁移至DM8产生数据文件膨胀的原因

在将 Oracle 数据库迁移到 DM8 时,可能会出现数据膨胀的情况。这是由于 Oracle 和 DM8 在数据存储和处理方面的差异导致的。

首先要了解 Oracle 与 DM8 的存储架构对比。

特性 Oracle DM8 迁移影响与注意事项
表空间/数据文件 核心逻辑存储单位,由数据文件构成。 概念基本一致。 需在DM8手动预先创建与Oracle源端对应的表空间。
段(SEGMENT)/区(EXTENT) 表、索引等对象是段,由区组成。 采用类似的段、区、数据块层级管理。 迁移后,段的初始区分配策略可能不同,影响初期空间占用。
字符集和编码差异 Oracle的AL32UTF8或WE8ISO8859P1 达梦数据库如果字符集是UTF-8一个中文字符占三个字节,最多存1300个中文字符,达梦数据库如果字符集是GB18030一个中文占2个字节,最多存1950个中文字符。 不同字符集的字符映射规则不同,可能导致数据转换时的存储空间变化或乱码问题。
数据块(BLOCK) I/O最小单位,可配置(如8K)。 页大小可在初始化时设定(如4K,8K,16K等)。 页大小选择至关重要,它会影响单行数据长度(如VARCHAR类型最大长度)和性能。
高水位线(HWM) 标志段中已格式化数据块的最高点。 存在类似概念。 DELETE操作后HWM不自动下降。在Oracle中执行delete删除操作不会降低高水位。原则上MWM只会增大,不会缩小。即使表中的全部数据都删除了,那么HWM还是原值。

接下来探究数据文件膨胀可能的原因。

成因 机制说明 迁移案例
页大小差异 Oracle默认8KB,DM8在创建数据库时可以指定为 4KB、8KB、16KB 或者 32KB。数据迁移后,DM8可能因页大小增加而"膨胀"。 同一表数据文件的总物理大小通常会发生变化。
表空间规划不当 未分离数据/索引表空间,导致索引占用数据表空间,增加文件膨胀。 数据表空间初始10GB,无自动扩展,数据增长到15GB时触发扩展,但因混用,文件实际占用25GB。
页大小和HWM共同作用 相同逻辑数据量,HWM块数减半。 DM8的HWM块数 = Oracle HWM块数 ÷ 2,但迁移工具可能错误保留Oracle的表空间大小,导致数据文件物理空间被过度分配(膨胀)。

可以看到,迁移后数据文件膨胀的可能原因有:

  1. 块大小差异:Oracle的8KB块 vs DM8的16KB块。
    例如:在Oracle中,100MB的数据可能占用约12800个块(100MB / 8KB)。在DM8中,相同数据量可能占用约6400个块(100MB / 16KB),但DM8默认的块大小是16KB,所以实际存储空间会更小。
    所以第一点原因可能是由于迁移工具可能没有正确处理块大小,导致DM8中数据文件被分配了更多空间(例如,初始大小基于Oracle的计算,但DM8的块更大,所以实际使用率低)。
  2. HWM与表空间扩展:
    在Oracle中,HWM上移时,如果表空间未满,Oracle会分配新区(不触发表空间扩展)。但迁移到DM8后,如果DM8表空间的初始大小是基于Oracle的计算(例如,Oracle的HWM在50GB,但DM8的块更大,实际需要空间更少),但DM8表空间初始大小设置得过大,可能导致数据文件膨胀。
    例如:Oracle表空间初始100GB,HWM在50GB。迁移后,DM8表空间也设置为100GB,但DM8的块更大,实际数据只占50GB(物理空间),但数据文件大小是100GB(因为表空间初始100GB),所以膨胀率50%。
  3. HWM在迁移中的变化:
    迁移后,DM8的HWM位置会基于DM8的块大小重新计算。但由于DM8块大小翻倍,HWM的"位置"(以块数表示)会减半,但物理空间需求也减半。
    第三点原因是,如果迁移工具或DBA错误地保留了Oracle的表空间大小而没有调整,DM8的数据文件可能会比实际需要的大。

如何尽量避免数据文件膨胀呢?

  1. 合理设置存储参数:在DM8中创建表时,根据数据特性设置合适的PCTFREE(块内预留空间比例)和存储参数(如初始区大小INITIAL、下次分配区大小NEXT),避免过于粗放的空间分配。
  2. 重新计算存储需求,基于DM8的块大小,调整表空间初始大小。
  3. 确保DM8数据库的字符集与源端Oracle兼容(如ZHS16GBK或AL32UTF8)。在dm.ini中设置COMPATIBLE_MODE=2,以提高对Oracle语法的兼容性。
  4. 迁移前计算Oracle HWM 并转换为DM8物理大小;建表时设置表空间大小 = DM8 HWM物理大小;迁移后执行SHRINK SPACE收缩HWM。

最后浅谈下聚簇(CLUSTER)与非聚簇(堆表)的差异

特性 非聚簇表(普通堆表) 聚簇表
物理存储 数据行无序存放,写入时放入第一个有足够空间的数据块。 将逻辑上关联紧密的数据(如主外键关联的表数据)物理上存储在一起
优点 INSERT效率高;全表扫描速度快;管理简单,是默认和主流选择。 等值连接查询效率极高,因为关联数据可能在同一个数据块中。
缺点 按非索引字段查询效率可能较低。 INSERT可能更慢;全表扫描单个表效率低;如果聚簇键设计不佳易导致空间浪费。

根据资料,DM8不支持Oracle的"聚簇表"(Clustered Table)概念,但有表分区和索引组织表(IOT)作为替代方案。

方案 DM8实现 适用场景 迁移建议
聚簇表 不支持,需用表分区或索引组织表替代 关联查询频繁(如报表、BI) 将Oracle的聚簇表改为DM8的分区表
索引组织表 CREATE TABLE ... ORGANIZATION INDEX 主键查询频繁,减少索引维护开销 适合Oracle中使用CLUSTER的场景
标准表+索引 默认存储方式(与Oracle非聚簇表等效) OLTP高频写入场景 保留Oracle的非聚簇表结构,但需优化索引
相关推荐
optimistic_chen10 小时前
【Redis系列】事务特性
数据库·redis·笔记·缓存·事务
DBA小马哥10 小时前
时序数据库迁移替换与选购指南
数据库·时序数据库
Knight_AL10 小时前
深入解析数据库四大事务隔离级别及其实际应用
服务器·数据库·oracle
xj75730653310 小时前
《精通Django》 第三章 Django模板
数据库·django·sqlite
. . . . .10 小时前
SQLite 技术总结:轻量级数据库的本地存储利器
数据库·sqlite
CodeCipher10 小时前
关于Redis单线程问题
数据库·redis·缓存
威风少侠10 小时前
Redis集群配置优化指南
数据库·redis·缓存
企鹅郁金香10 小时前
Gitlab和Gerrit部署后的工作(二)
数据库·gitlab·gerrit域名无法修改·激活gitlab·gitlab注册ldap·nginx反向代理gitlab·nginx反向代理gerrit
悄悄敲敲敲10 小时前
MySQL表的内外连接
数据库·mysql