概述

近期一个客户的一张单表,每天delete7天前的数据,每天的数据增量没什么变化,理论上来说,delete释放的空间是可重用的,但发现该表段最近一直在增长,现在大小为300G,170G的75% – 100% free space blocks.通常通过 APPEND,直接路径加载的方式会直接扩展SEGMENT,不会重用DELETE的空间,但客户的系统排除了APPEND INSERT。

测试目的

我们知道ASSM的表INSERT查找可用空间机制,会在L2 Hint for inserts指上的L2块,再通过算法确定L1块,查找存在可用空间的数据块,完成INSERT。

客户的系统里,发现一个现象,DUMP SEGMENT HEADER,发现L2 Hint for inserts一直指向最后一个L2块。

 Segment Type: 1 nl2: 37     blksz: 8192   fbsz: 0      L2 Array start offset:  0x00001434First Level 3 BMB:  0x00000000L2 Hint for inserts:  0x1fd54208    <<<<Last Level 1 BMB:  0x1fd78207Last Level II BMB:  0x1fd54208      <<<<Last Level III BMB:  0x00000000Second Level Bitmap block DBAs --------------------------------------------------------DBA 1:   0x15c00099
省略DBA 36:   0x1fc82208DBA 37:   0x1fd54208  <<<<

如果ORACLE只是通过L2块查找可用空间,L2 Hint for inserts总是指向最后的L2的话,之前L2块所管理的数据块上数据被DELETE掉,那也没有重用的机会。正常的系统不应该是这样的,下面在我的机器上做一个测试,验证存在多个L2块的系统上,如果前面的L2块管理的块上数据DELETE掉,在表扩展之前,会修改 L2 Hint for inserts的指向,到前面有可用空间的L2,从而重用DELETE释放的空间。

测试步骤如下:
1、创建测试表

SQL> create table TEST.tab1(id number,c varchar2(1000)) tablespace users;Table created.

2、INSERT数据,直接产生1个以上L2块为止。我这里有两个L2

insert into TEST.tab1 select 0*100000+rownum,rpad('a',1000,'a')  from dual connect  by rownum<100000;
insert into TEST.tab1 select 1*100000+rownum,rpad('a',1000,'a')  from dual connect  by rownum<100000;
insert into TEST.tab1 select 40*100000+rownum,rpad('a',1000,'a')  from dual connect  by rownum<100000;
这里INSERT了大400万数据
SQL> @seg test.tab1SEG_MB OWNER                SEGMENT_NAME                   SEG_PART_NAME                  SEGMENT_TYPE         SEG_TABLESPACE_NAME                BLOCKS     HDRFIL     HDRBLK
---------- -------------------- ------------------------------ ------------------------------ -------------------- ------------------------------ ---------- ---------- ----------4608 TEST                 TAB1                                                          TABLE                USERS                              589824         23        130SQL> SQL> alter system dump datafile 23 block 130;System altered.Segment Type: 1 nl2: 2      blksz: 8192   fbsz: 0      L2 Array start offset:  0x00001434First Level 3 BMB:  0x00000000L2 Hint for inserts:  0x05c82088 <<<<Last Level 1 BMB:  0x05c8e087Last Level II BMB:  0x05c82088 <<<<Last Level III BMB:  0x00000000Map Header:: next  0x00000000  #extents: 255  obj#: 73129  flag: 0x10000000Second Level Bitmap block DBAs --------------------------------------------------------DBA 1:   0x05c00081DBA 2:   0x05c82088 <<<<

3、当前的空间实用情况

set serverout on
exec show_space('TAB1','TEST');Total Blocks............................589824
Total Bytes.............................4831838208
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................23
Last Used Ext BlockId...................581760
Last Used Block.........................8192
*************************************************
The segment is analyzed
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............1
25% -- 50% free space bytes.............8192
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........237
75% -- 100% free space bytes............1941504
Unused Blocks...........................2816
Unused Bytes............................23068672
Total Blocks............................585709
Total bytes.............................4798128128PL/SQL procedure successfully completed.

4、 DELETE 50万数据,因为我INSERT是顺序的,DELETE id<500000的数据,应该释放的是段的前面的一批BLOCKS

SQL> delete TEST.tab1 where id<500000;499995 rows deleted.commit;

5、再查看空间使用情况
75% – 100% free space blocks从DELETE前的237 增长到 71665。

set serverout on
exec show_space('TAB1','TEST');SQL>
SQL> Total Blocks............................589824
Total Bytes.............................4831838208
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................23
Last Used Ext BlockId...................581760
Last Used Block.........................8192
*************************************************
The segment is analyzed
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............1
25% -- 50% free space bytes.............8192
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........71665 <<<<
75% -- 100% free space bytes............587079680
Unused Blocks...........................2816
Unused Bytes............................23068672
Total Blocks............................514281
Total bytes.............................4212989952PL/SQL procedure successfully completed.SQL>

6、INSERT 999行数据进行测试
因为当前 L2 Hint for inserts指向的L2上仍然有可用空间,会发现下面的INSERT并没有使用DELETE释放的这部分空间。

SQL> insert into TEST.tab1 select 0+rownum,rpad('a',1000,'a')  from dual connect  by rownum<1000;999 rows created.SQL> SQL> commit;Commit complete.SQL> select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where tablespace_name='USERS' and owner='TEST' and segment_name='TAB1' order by extent_id;EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------0         23        128          81         23        136          82         23        144          83         23        152          84         23        160          85         23        168          86         23        176          87         23        184          88         23        192          89         23        200          810         23        208          811         23        216          812         23        224          813         23        232          814         23        240          815         23        248          816         23        256        12817         23        384        12818         23        512        12819         23        640        12820         23        768        12821         23        896        12822         23       1024        12823         23       1152        128
....----该段的前部分块上并没有我们刚刚INSERT的数据,说明没有重用DELETE的空间。
SQL> select id,dbms_rowid.rowid_relative_fno(rowid) file_id,dbms_rowid.rowid_block_number(rowid) block_id from TEST.tab1 where   2  rowid >=dbms_rowid.rowid_create(1,73129,23,127,1)  and rowid <=dbms_rowid.rowid_create(1,73129,23,1024,500)3  and  id<100;no rows selected

7、继续INSERT 10万行数据
因为最后的L2块上,高水位下面没有这么多的空间存放这10万行数据,可以看到这次重用了之前DELETE释放的空间,同时看到L2 Hint for inserts现在指向到了第一个L2块。

SQL> insert into TEST.tab1 select 0+rownum,rpad('a',1000,'a')  from dual connect  by rownum<100000;99999 rows created.SQL> commit;Commit complete.
----INSERT 10万行后,Total Blocks  589824,表总BLOCKS没有增长,75% -- 100% free space blocks从71665减少到60053
SQL> set serverout on
SQL> exec show_space('TAB1','TEST');
Total Blocks............................589824
Total Bytes.............................4831838208
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................23
Last Used Ext BlockId...................581760
Last Used Block.........................8192
*************************************************
The segment is analyzed
0% -- 25% free space blocks.............1
0% -- 25% free space bytes..............8192
25% -- 50% free space blocks............0
25% -- 50% free space bytes.............0
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........60053
75% -- 100% free space bytes............491954176
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................528709
Total bytes.............................4331184128PL/SQL procedure successfully completed.---可以看到前段的1000个块上有我们刚刚INSERT的数据,说明重用了DELETE释放的空间
SQL> select id,dbms_rowid.rowid_relative_fno(rowid) file_id,dbms_rowid.rowid_block_number(rowid) block_id from TEST.tab1 where   2  rowid >=dbms_rowid.rowid_create(1,73129,23,127,1)  and rowid <=dbms_rowid.rowid_create(1,73129,23,10240,500)3  and  id<100000 and rownum<100;ID    FILE_ID   BLOCK_ID
---------- ---------- ----------20445         23        17720446         23        17720447         23        17720448         23        17720449         23        17720450         23        17720451         23        177
。。。。。。。。20418         23        18820419         23        18820420         23        18820421         23        18820422         23        18820423         23        18820424         23        18920425         23        18920426         23        18920427         23        18920428         23        18920429         23        18920430         23        18920431         23        19020432         23        19020433         23        19020434         23        19020435         23        19020436         23        19020437         23        19020438         23        19199 rows selected.SQL> SQL>  alter system dump datafile 23 block 130;System altered.L2 Hint for inserts的指向也从第二个L2块,换成了第一个L2块。Extent Control Header-----------------------------------------------------------------Extent Header:: spare1: 0      spare2: 0      #extents: 255    #blocks: 589824last map  0x00000000  #maps: 0      offset: 2716  Highwater::  0x05c90080  ext#: 254    blk#: 8192   ext size: 8192  #blocks in seg. hdr's freelists: 0     #blocks below: 588763mapblk  0x00000000  offset: 254   Unlocked--------------------------------------------------------Low HighWater Mark : Highwater::  0x05c90080  ext#: 254    blk#: 8192   ext size: 8192  #blocks in seg. hdr's freelists: 0     #blocks below: 588763mapblk  0x00000000  offset: 254   Level 1 BMB for High HWM block: 0x05c8e087Level 1 BMB for Low HWM block: 0x05c8e087--------------------------------------------------------Segment Type: 1 nl2: 2      blksz: 8192   fbsz: 0      L2 Array start offset:  0x00001434 First Level 3 BMB:  0x00000000L2 Hint for inserts:  0x05c00081  <<<<<<Last Level 1 BMB:  0x05c8e087Last Level II BMB:  0x05c82088Last Level III BMB:  0x00000000Map Header:: next  0x00000000  #extents: 255  obj#: 73129  flag: 0x10000000Inc # 0 Second Level Bitmap block DBAs --------------------------------------------------------DBA 1:   0x05c00081  <<<<<DBA 2:   0x05c82088

总结

猜测正常情况下,L2 Hint for inserts指向的L2块找不到可用空间的时侯,在尝试ALLOCATE新的EXTENT的前,会去判断之前的L2块有没有可用空间。如果有,会修改L2 Hint for inserts,去使用之前的L2管理的块上释放出来的空间。
客户环境中,大量75% – 100% free space blocks的情况下,INSERT不重用释放的空间问题,还需要继续分析!

作者

范计杰,云和恩墨技术顾问,5年大型ORACLE数据库维护经验,擅长性能调优、故障处理等。

墨天轮原文链接:https://www.modb.pro/db/43425(复制到浏览器或者点击“阅读原文”立即查看)

推荐阅读:267页!2020年度数据库技术年刊

推荐下载:2020数据技术嘉年华PPT下载

2020数据技术嘉年华近50个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2020DTC”获得!

视频号,新的分享时代,关注我们,看看有什么新发现?

数据和云

ID:OraNews

如有收获,请划至底部,点击“在看”,谢谢!

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

实战经验:关于Oracle Delete数据后空间重用问题的测试相关推荐

  1. oracle delete 空间增加,实战经验:关于Oracle Delete数据后空间重用问题的测试

    概述 近期一个客户的一张单表,每天delete7天前的数据,每天的数据增量没什么变化,理论上来说,delete释放的空间是可重用的,但发现该表段最近一直在增长,现在大小为300G,170G的75% – ...

  2. Oracle 删除数据后释放数据文件所占磁盘空间

    . . . . . 测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小.经查阅资料之后发现这是 Oracle "高水位"所致,那么 ...

  3. MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题)

    MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题) 1.背景知识 1.1 为什么会有碎片 MySQL 中 insert 与 update 都可能导致页分裂,这样就存在碎片 ...

  4. oracle块空间的使用,Oracle管理存储架构(二)--Oracle管理数据块空间

    1.数据块的概念 数据块是数据库中最小的分配单元,块是数据库使用的最小的I/O单元,由一个或多个操作系统block组成. 数据块由block header .free space .data 组成,o ...

  5. Oracle 删除数据后释放数据文件所占磁盘空间(表空间降高水位)

    测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小.经查阅资料之后发现这是 Oracle "高水位"所致,那么怎么把这些数据文件的 ...

  6. 【Oracle实战经验一】:OracleSpatial自定义空间参考

    OracleSpatial自定义空间参考 1.如何判断OracleSpatial中是否存在该空间参考 2.怎么向OracleSpatial中插入自定义的空间参考 2.1插入地理坐标系统 2.1.1权限 ...

  7. 实战经验:Oracle recyclebin过大导致的Insert逻辑读暴增问题的解决

    墨墨导读:某客户的数据库一条insert某段时间突然变慢,平均单次执行逻辑读暴增至20万,本文分享整个处理过程. 概述 某客户的数据库一条insert语句某段时间突然变慢,平均单次执行逻辑读暴增至20 ...

  8. 实战经验:Oracle DG 的归档缺失修复

    客户某天反馈说:"DG库自0221以来就已经不同步了,请核查." 于是我远程登录进行查看. 故障检查 检查归档同步情况 一.查看数据库的情 select database_role ...

  9. 实战经验:Oracle Lost Write Detection机制导致Select产生大量Redo

    墨墨导读:某客户执行一个Select全表扫,产生大量Redo,需要分析原因.一般延迟块清除导致Select产生Redo,但这个案例中并不是延迟块清除的原因. 分析过程 1.在SELECT执行前保存该s ...

最新文章

  1. 热点推荐:程序员路在何方
  2. php中jquery ajax请求参数,浅谈Jquery中Ajax异步请求中的async参数的作用
  3. 渝粤题库]西北工业大学组成与系统结构
  4. 写一个sql实现以下查询结果_SQL复杂查询—知识点梳理(四)
  5. 玩游戏用固态硬盘还是机械硬盘
  6. 程序员不应该“躺平”
  7. android webview 字体被放大,解决因为手机设置字体大小导致h5页面在webview中变形的BUG...
  8. MATLAB 格拉布斯准则代码
  9. 详解自动驾驶安全软件开发流程
  10. Oracle中的next_day(date,char)
  11. python中换页是干嘛的_python什么是转页符
  12. Startssl 现在就启用 HTTPS,免费的!
  13. 获取json文件中的URL
  14. Core Animation (2)
  15. [API ]新浪微博腾讯QQ音乐网易云音乐小米云钉钉笔记百度高德地图淘宝阿里云 API
  16. 全国计算机二级考试有没有access,全国计算机二级考试Access试题
  17. 免费工资总额管控系统-JXHR2016
  18. Java项目:养老院综合服务系统(java+SSM+JSP+jQuery+echarts+mysql)
  19. 迅为4412开发板支持AVIN视频输入/AV监控摄像头输入模块
  20. 华科 中大 计算机 就业,华中科技大学就业信息网

热门文章

  1. 2017 开源软件排行_2017年政府和公民如何使用开源解决人类问题
  2. 数字化转型 数字分析_数字化转型的人员问题
  3. wagtail cms_为Wagtail做准备,这是迄今为止最好的Django CMS
  4. 微软拥抱开源_如何拥抱开源劳动力
  5. (7)<a>标签之锚点和回到顶部功能
  6. WebStorm 打开Node.js的代码提示功能
  7. 中止请求和超时 跨域的HTTP请求 认证方式 JSONP
  8. gis怎么提取水系_SketchUp+Global Mapper 地形提取,连建模都省了...
  9. 前端关系图谱插件_智游告诉你,前端开发应该学什么?
  10. 概率整形 Peobabilistic Shaping PS 第一节