实战经验:关于Oracle Delete数据后空间重用问题的测试
sinye56 2024-10-12 10:15 4 浏览 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
相关推荐
- Linux基础知识之修改root用户密码
-
现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...
- Linux如何修改远程访问端口
-
对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...
- 如何批量更改文件的权限
-
如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...
- CentOS「linux」学习笔记10:修改文件和目录权限
-
?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...
- Linux下更改串口的权限
-
问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...
- Linux chown命令:修改文件和目录的所有者和所属组
-
chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...
- chmod修改文件夹及子目录权限的方法
-
chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...
- Android 修改隐藏设置项权限
-
在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...
- 完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!
-
最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...
- linux改变安全性设置-改变所属关系
-
CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...
- Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod
-
#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...
- linux更改用户权限为root权限方法大全
-
背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...
- 怎么用ip命令在linux中添加路由表项?
-
在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...
- Linux配置网络
-
1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...
- Linux系列---网络配置文件
-
1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)