百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

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

mhr18 2024-12-17 13:42 17 浏览 0 评论

概述

近期一个客户的一张单表,每天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:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0x1fd54208    <<<<
  Last Level 1 BMB:  0x1fd78207
  Last Level II BMB:  0x1fd54208      <<<<
  Last Level III BMB:  0x00000000
   Second Level Bitmap block DBAs 
   --------------------------------------------------------
   DBA 1:   0x15c00099
省略
   DBA 36:   0x1fc82208
   DBA 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.tab1


    SEG_MB OWNER                SEGMENT_NAME                   SEG_PART_NAME                  SEGMENT_TYPE         SEG_TABLESPACE_NAME                BLOCKS     HDRFIL     HDRBLK
---------- -------------------- ------------------------------ ------------------------------ -------------------- ------------------------------ ---------- ---------- ----------
      4608 TEST                 TAB1                                                          TABLE                USERS                              589824         23        130


SQL> 


SQL> alter system dump datafile 23 block 130;


System altered.


  Segment Type: 1 nl2: 2      blksz: 8192   fbsz: 0      
  L2 Array start offset:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0x05c82088 <<<<
  Last Level 1 BMB:  0x05c8e087
  Last Level II BMB:  0x05c82088 <<<<
  Last Level III BMB:  0x00000000
     Map Header:: next  0x00000000  #extents: 255  obj#: 73129  flag: 0x10000000
     
   Second Level Bitmap block DBAs 
   --------------------------------------------------------
   DBA 1:   0x05c00081
   DBA 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.............................4798128128


PL/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.............................4212989952


PL/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          8
         1         23        136          8
         2         23        144          8
         3         23        152          8
         4         23        160          8
         5         23        168          8
         6         23        176          8
         7         23        184          8
         8         23        192          8
         9         23        200          8
        10         23        208          8
        11         23        216          8
        12         23        224          8
        13         23        232          8
        14         23        240          8
        15         23        248          8
        16         23        256        128
        17         23        384        128
        18         23        512        128
        19         23        640        128
        20         23        768        128
        21         23        896        128
        22         23       1024        128
        23         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.............................4331184128


PL/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        177
     20446         23        177
     20447         23        177
     20448         23        177
     20449         23        177
     20450         23        177
     20451         23        177
。。。。。。。。
     20418         23        188
     20419         23        188
     20420         23        188
     20421         23        188
     20422         23        188
     20423         23        188
     20424         23        189
     20425         23        189
     20426         23        189
     20427         23        189
     20428         23        189
     20429         23        189
     20430         23        189
     20431         23        190
     20432         23        190
     20433         23        190
     20434         23        190
     20435         23        190
     20436         23        190
     20437         23        190
     20438         23        191


99 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: 589824
                  last map  0x00000000  #maps: 0      offset: 2716  
      Highwater::  0x05c90080  ext#: 254    blk#: 8192   ext size: 8192  
  #blocks in seg. hdr's freelists: 0     
  #blocks below: 588763
  mapblk  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: 588763
  mapblk  0x00000000  offset: 254   
  Level 1 BMB for High HWM block: 0x05c8e087
  Level 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:  0x00000000
  L2 Hint for inserts:  0x05c00081  <<<<<<
  Last Level 1 BMB:  0x05c8e087
  Last Level II BMB:  0x05c82088
  Last Level III BMB:  0x00000000
     Map Header:: next  0x00000000  #extents: 255  obj#: 73129  flag: 0x10000000
  Inc # 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

相关推荐

AlmaLinux 9.6发布:升级工具、初步支持IBM Power虚拟化技术

IT之家5月21日消息,科技媒体linuxiac昨日(5月20日)发布博文,报道称代号为SageMargay的AlmaLinux9.6发行版已上线,距上一版本9.5发...

Java最新学习路线,系统全面,零基础适用

首先,我个人比较推崇的学习方法是:先学java前段,也就是HTML,css,js,因为学习java以后肯定是往javaee方向发展的,学习完前端,在学习后端很多东西比计较容易理解!其中J2SE是关键...

深入理解数据库事务(数据库事务处理的理解)

Transaction作为关系型数据库的核心组成,在数据安全方面有着非常重要的作用,本文会一步步解析事务的核心特性,以获得对事务更深的理解。什么是事务数据库几乎是所有系统的核心模块,它将数据有条理地保...

IvorySQL 4.4 发布(1044mysql)

IvorySQL4.4已于2025年3月10日正式发布。新版本全面支持PostgreSQL17.4,新增多项新功能,并修复了已知问题。增强功能PostgreSQL17.3增强功...

Oracle 与 Google Cloud 携手大幅扩展多云服务

据DCD4月10日报道,甲骨文(Oracle)与谷歌云(GoogleCloud)深化合作,全力扩展多云产品。双方计划为OracleDatabaseGoogleCloud解决方案新增11...

Izzi 利用 Oracle 云提高计费效率和客户体验

据thefastmode网5月2日报道,墨西哥电信运营商Izzi宣布采用Oracle云基础设施(OCI),对其业务支持系统(BSS)进行现代化改造增强客户体验,已经成功完成。通过在OCI上运行...

好莱坞群星也有明星脸?硅谷科技名人本尊分身比一比

假如有部电影齐聚了众科技名人角色,如同许多好莱坞大牌卡司所共同主演的《瞒天过海》(Ocean’sEleven)那样,演出彼此在商场上竞逐、或共同对抗外来竞争捍卫硅谷的故事,更在剧中有不少对手戏,会不...

澳大利亚Find My iPhone被黑 多人被黑客锁机

FindMyiPhone本来是一个用于协助找回被盗手机的好工具,但是现在,澳洲的苹果用户发现他们的FindMyiPhone变成了黑客的帮凶。昨天,这名自称为OlegPliss的黑客使用Fin...

服务器密码错误被锁定怎么解决(服务器密码失效)

#服务器密码错误被锁定解决方案当服务器因多次密码错误导致账户被锁定时,可以按照以下步骤进行排查和解决:##一、确认锁定状态###1.检查账户锁定状态(Linux)```bash#查看账户锁定...

凌晨突发的数据库重大故障,我排查了一整天……

春节期间过得太热闹了,上班确实没啥状态,这不刚发生的一个重大性能故障,排查了整整一天,后面的领导都站成了一排,本次把故障发生的详细分析过程分享给大家!本次故障发生在凌晨,核心应用卡顿非常严重,Orac...

Oracle锁表紧急处理!3招快速解锁方案

开篇:突发故障现场凌晨1点,某电商系统突然卡顿,数千笔支付订单无法完成——数据库出现死锁,技术团队紧急响应...(遇到类似情况的,欢迎在评论区分享经历)一、问题重现:死锁是如何产生的?典型场景:问题根...

JetBrains DataGrip Mac中文破解版V2025.1下载安装教程

DataGripforMac是由JetBrains开发的数据库集成开发环境(IDE),专为数据库管理员和开发人员设计。它支持多种数据库(如MySQL、PostgreSQL、Oracle、SQ...

电脑装安卓系统,安卓X86版5.1 RC1下载

日前,谷歌放出了Android-x865.1的第一个候选版本Android-x865.1RC1,该版本基于Android5.1.1r24Lollipop开发,更新包括大量x86(32位)代...

来来来!一文告诉你Eclipse的正确安装使用姿势,你都清楚吗?

前言本学习笔记是有关如何设置Eclipse的详细说明。即使你天天在使用它,但是,相信我,或许你并不足够了解它。安装Java运行时环境Eclipse是Java应用程序,因此设置Eclipse的第一步是安...

分享收藏的 oracle 11.2.0.4各平台的下载地址

概述oracle11.2.0.4是目前生产环境用的比较多的版本,同时也是很稳定的一个版本。目前官网上已经找不到下载链接了,有粉丝在头条里要求分享一下下载地址。一、各平台下载地址1.1Linuxx...

取消回复欢迎 发表评论: