某日正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有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号。当我们通过导入导出迁移数据的时候,在导入时,是没有办法保证数据所在的文件号块号行号是完全一致的,也就意味着导出索引块是无意义的。这也是通过导入导出的另一个好处:可以将稀疏的表在迁移的过程中重建,从而达到对表数据的整理。讲到这,大伙都明白了,抬头一看,身边都同事已经一头扎进精彩刺激又些许无聊的运维工作中去。
美创运维中心数据库服务团队拥有Oracle ACE 1人、OCM 10余人、数十名Oracle OCP、MySQL OCP、红帽RHCA、中间件weblogic、tuxedo认证、达梦工程师 ,著有《Oracle DBA实战攻略》,《Oracle数据库性能优化方法和最佳实践》,《Oracle内核技术揭秘》等多本数据运维优化书籍。目前运维各类数据库合计2000余套,精通Oracle、MySQL、SQLServer、DB2、PostgreSQL、达梦等主流商业和开源数据库。并成为首批国内达梦战略合作伙伴之一,拥有海量经验和完善的人员培养体系。并同时提供超融合,私有云整体解决方案。
来源:freebuf.com 2020-06-09 12:07:28 by: database
请登录后发表评论
注册