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

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

sinye56 2024-10-12 10:15 5 浏览 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

相关推荐

CTO偷偷传我的系统性能优化十大绝招(万字干货)

上篇引言:取与舍软件设计开发某种意义上是“取”与“舍”的艺术。关于性能方面,就像建筑设计成抗震9度需要额外的成本一样,高性能软件系统也意味着更高的实现成本,有时候与其他质量属性甚至会冲突,比如安全性、...

提升效率!VMware虚拟机性能优化十大实用技巧

我40岁,干跨境婚恋中介的。为服务各国用户,常得弄英语、日语、俄语系统环境,VMware虚拟机帮了不少忙。用久了发现优化下性能,效率能更高。今儿就来聊聊优化技巧和同类软件。一、VMware虚拟...

低延迟场景下的性能优化实践

本文摘录自「全球C++及系统软件技术大会」ScottMeyers曾说到过,如果你不在乎性能,为什么要在C++这里,而不去隔壁的Pythonroom呢?今天我们就从“低延迟的概述”、“低延迟系...

Linux性能调优之内存负载调优的一些笔记

写在前面整理一些Linux内存调优的笔记,分享给小伙伴博文没有涉及的Demo,理论方法偏多,可以用作内存调优入门博文内容涉及:Linux内存管理的基本理论寻找内存泄露的进程内存交换空间调优不同方式的...

优化性能套路:带你战胜这只后段程序员的拦路虎

来源|极客时间《卖桃者说》作者|池建强编辑|成敏你好,这里是卖桃者说。今天给大家推荐一篇文章,来自倪朋飞老师的专栏《Linux性能优化实战》,文章主要讲的是优化性能的套路,这几乎是每个后端程序员...

SK海力士CXL优化解决方案已成功搭载于Linux:带宽提升30%,性能提升12%以上

SK海力士宣布,已将用于优化CXL(ComputeExpressLink)存储器运行的自研软件异构存储器软件开发套件(HMSDK)中主要功能成功搭载于全球最大的开源操作系统Linux上,不但提升了...

Linux内核优化:提升系统性能的秘诀

Linux内核优化:提升系统性能的艺术在深入Linux内核优化的世界之前,让我们先来理解一下内核优化的重要性。Linux内核是操作系统的核心,负责管理系统资源和控制硬件。一个经过精心优化的内核可以显著...

Linux系统性能优化:七个实战经验

Linux系统的性能是指操作系统完成任务的有效性、稳定性和响应速度。Linux系统管理员可能经常会遇到系统不稳定、响应速度慢等问题,例如在Linux上搭建了一个web服务,经常出现网页无法打开、打开速...

腾讯面试:linux内存性能优化总结

【1】内存映射Linux内核给每个进程都提供了一个独立且连续的虚拟地址空间,以便进程可以方便地访问虚拟内存;虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长的处理器,地址空间的范围也不同...

Linux文件系统性能调优《参数优化详解》

由于各种的I/O负载情形各异,Linux系统中文件系统的缺省配置一般来说都比较中庸,强调普遍适用性。然而在特定应用下,这种配置往往在I/O性能方面不能达到最优。因此,如果应用对I/O性能要求较高,除...

Nginx 性能优化(吐血总结)

一、性能优化考虑点当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨当前系统结构瓶颈了解业务模式性能与安全1、当前系统结构瓶颈首先需要...

Linux问题分析与性能优化

排查顺序整体情况:top/htop/atop命令查看进程/线程、CPU、内存使用情况,CPU使用情况;dstat2查看CPU、磁盘IO、网络IO、换页、中断、切换,系统I/O状态;vmstat2查...

大神级产品:手机装 Linux 运行 Docker 如此简单

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:灵昱Termux作为一个强大的Android终端模拟器,能够运行多种Linux环境。然而,直接在Termux上运行Docker并不可行,需要...

新手必须掌握的Linux命令

Shell就是终端程序的统称,它充当了人与内核(硬件)之间的翻译官,用户把一些命令“告诉”终端程序,它就会调用相应的程序服务去完成某些工作。现在包括红帽系统在内的许多主流Linux系统默认使用的终端是...

Linux 系统常用的 30 个系统环境变量全解析

在Linux系统中,环境变量起着至关重要的作用,它们犹如隐藏在系统背后的“魔法指令”,掌控着诸多程序的运行路径、配置信息等关键要素。尤其在shell脚本编写时,巧妙运用环境变量,能让脚本如虎...

取消回复欢迎 发表评论: