专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

来自小师弟的灵魂拷问之数据泵导出丢失的那些数据量去哪了?

ins518 2024-11-08 12:37:35 技术文章 14 ℃ 0 评论

在精彩刺激又些许无聊的运维生活中,有可爱呆萌的师弟师妹,也是为工作增添了一些色彩。正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有100G,expdp导出的dump文件只有60G,还有40G去哪了?小师妹还没从犯困中走出,是啊,为什么呢?

这时候我是日渐后移的发际线给了我勇气去打破空气中弥漫的那一丝安静。我和小师弟唠了起来…… 我们通过导出日志看看oracle的数据泵到底在导出的时候做了什么?

从日志中我们只有看到表导出的记录详细信息,那么只导出表数据块呢?

从统计结果看到,数据库内部占用空间的数据类型大致分为索引两大类。

问题的结症在于,为什么表数据导出而索引只导出ddl的sql,而不是导出具体索引数据?

从oracle官方的《Database Concepts》中找到data segment和index segment的定义如下:

我难道不知道索引的segment里面放的是索引,数据的segment里面放的是数据!!!

01

看来只能动手去segment里面一看究竟了。还是拿oracle的scott用户下的dept表和对应的索引来下手。查看scott.dept表上一条数据所在的block信息

返回信息解读如下:

scott.dept.deptno=10 所属的对象号87106,文件号4,block号135,对应的行号0

02

那查看scott.dept呢

看到deptno字段类型是number(2)

03

查看索引的对象号

04

查看生产的trace如下,可以看到页块和块地址以及块上的索引条目信息

05

根据trace的内容,通过以下语句获取索引所在的文件和块号

06

查看trace,摘取核心的信息如下:

从块dump的trace文件中,我们可以获取很多信息,比如块类型,大小,定位信息等。重点截取后面部分可以看到该索引块上有4 row 的行目录(row directory),该信息是针对row的描述信息,是一个指针数组,指向对应块中的寻址信息

[8021]-[8010]可以计算出偏移量为11,也就是一行记录占用了11位,一行有1个字段,字段长度为2

01 00 00 87 00 00 假设为16进制,我们转换为二进制

0000 0001 0000 0000 0000 0000 1000 0111 0000 0000 0000 0000

前部加粗的10位转换为十进制为4

中部未加粗22位转换为十进制为135

后部加粗的16位转换为十进制为0

看到4/135/0这是不是有有些眼熟,就是对scott.dept.deptno=10上rowid拆解出来的文件号,块号,行号。到这,我们明白了,在索引块中,存储的是索引字段的rowid号。当我们通过导入导出迁移数据的时候,在导入时,是没有办法保证数据所在的文件号块号行号是完全一致的,也就意味着导出索引块是无意义的。这也是通过导入导出的另一个好处:可以将稀疏的表在迁移的过程中重建,从而达到对表数据的整理。讲到这,大伙都明白了,抬头一看,身边都同事已经一头扎进精彩刺激又些许无聊的运维工作中去。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表