Oracle中shrink space命令
shrink_clause:
首先oracle shrink 是10g之后才引出的,有shrink table 和shrink space两种,这里介绍shrink space
压缩分两个阶段:
1、数据重组:这个过程是通过一系列的insert delete操作,将数据尽量排在列的前面进行重新组合。
2、HWM调整:这个过程是对HWM的调整,释放空闲数据库。
PS:shrink之间必须开启行移动功能
alter table table_name enable row movement;
基本语法:
alter table <table_name> shrink space [ <null> | cascade | compact ];
--alter table <table_name> shrink space compact;
只收缩表,这个实际上是只执行了第一个阶段,HWM保持不变。
--alter table <table_name> shrink space cascade;
收缩表并且相关索引也会被收缩,HWM会降低
--alter table <table_name> shrink space;
收缩表,降低HWM(High Water Mark)
- shrink space语句两个阶段都执行
- shrink space compact语句只执行第一个阶段。
- 在业务繁忙的时候,可以先执行shrink space compact重组数据,然后不满的时候执行shrink space降低HWM释放空闲数据块。
- shrink必须开启对象的row movement功能(shrink index 不需要),alter table table_name enable row movement.但是要注意,该语句会造成引用table_name的对象(如存储过程、包、试图等)变为无效,执行完最好由utlrp.sql来编译无效对象。
- shrink不会使表的索引失效。但是move会,因此,move后必须重建索引,(alter table table_name move;alter index index_name rebuild)
补充:
--编译无效对象脚本utlrp.sql
>$ sqlplus /no log
SQL>connect sys/pwd@sid AS sysdba
SQL>@?/rdbms/admin/utlrp.sql
utlrp.sql脚本可以在数据库运行的状态下执行以编译、数据库中的invalid对象.
oracle建议在对数据库进行迁移、升级、降级后都运行一遍utlrp.sql以编译无效对象。
--打完patch后重建数据字典视图脚本catpatch.sql
为了保证系统的的数据词典的完整性和有效性,最好的打patch后在migrate状态下运行catpatch.sql
sql> shutdown immediate
sql> startup migrate
sql> @?/rdbms/admin/catpatch.sql
sql> shutdown immediate
sql> startup
为加快速度,可临时调大这2个参数:
show parameter shared_pool_size
show parameter large_pool_size
1.1 创建ASSM的表空间
SQL> set serveroutput on
SQL> create tablespace ASSM datafile '/oradata/ltest/assm.dbf' size 10m autoextend on SEGMENT SPACE MANAGEMENT AUTO;
Tablespace created
SQL> select tablespace_name,
2 block_size,
3 extent_management,
4 allocation_type,
5 segment_space_management
6 from dba_tablespaces
7 where tablespace_name = 'ASSM';
TABLESPACE_NAME BLOCK_SIZE EXTENT_MANAGEMENT ALLOCATION_TYPE SEGMENT_SPACE_MANAGEMENT
--------------- ---------- ----------------- --------------- ------------------------
ASSM 8192 LOCAL SYSTEM AUTO
1.2 建表
SQL> create table my_objects tablespace assm as select * from all_objects;
Table created
SQL> select count(*) from my_objects;
COUNT(*)
----------
49903
2 实验前的信息
SQL> exec show_space('MY_OBJECTS');
Total Blocks ..........................768
Total Bytes ..........................6291456
Total MBytes ..........................6
Unused Blocks ..........................62
Unused Bytes ..........................507904
Unused KBytes ..........................496
Last Used Ext FileId....................7
Last Used Ext BlockId...................649
Last Used Block.........................66
The segment is analyzed below
FS1 Blocks (0-25) ....................0
FS2 Blocks (25-50) ....................0
FS3 Blocks (50-75) ....................0
FS4 Blocks (75-100) ....................0
Unformatted Blocks ....................0
Full Blocks ....................686
PL/SQL procedure successfully completed
3 删除后的信息
然后我们随机地从table MY_OBJECTS中删除一部分数据:
SQL> delete from my_objects where object_name like '%C%';
17674 rows deleted
SQL> delete from my_objects where object_name like '%U%';
4687 rows deleted
SQL> delete from my_objects where object_name like '%A%';
7010 rows deleted
SQL> exec show_space('MY_OBJECTS');
Total Blocks ..........................768
Total Bytes ..........................6291456
Total MBytes ..........................6
Unused Blocks ..........................62
Unused Bytes ..........................507904
Unused KBytes ..........................496
Last Used Ext FileId....................7
Last Used Ext BlockId...................649
Last Used Block.........................66
The segment is analyzed below
FS1 Blocks (0-25) ....................0
FS2 Blocks (25-50) ....................212
FS3 Blocks (50-75) ....................181
FS4 Blocks (75-100) ....................245
Unformatted Blocks ....................0
Full Blocks ....................48
PL/SQL procedure successfully completed
这里,table my_objects的HWM下有706(768 - 62)个block,其中,free space为25-50%的block有205个,free space为50-75%的block有180个,free space为75-100%的block有229个,full space的block只有45个,这种情况下,我们需要对这个table的现有数据行进行重组。
4 shink操作
要使用assm上的shink,首先我们需要使该表支持行移动,可以用这样的命令来完成:
SQL> alter table my_objects enable row movement;
Table altered
现在,就可以来降低my_objects的HWM,回收空间了,使用命令:
SQL> alter table my_objects shrink space;
Table altered
SQL> exec show_space('MY_OBJECTS');
Total Blocks ..........................280
Total Bytes ..........................2293760
Total MBytes ..........................2.1875
Unused Blocks ..........................5
Unused Bytes ..........................40960
Unused KBytes ..........................40
Last Used Ext FileId....................7
Last Used Ext BlockId...................265
Last Used Block.........................19
The segment is analyzed below
FS1 Blocks (0-25) ....................0
FS2 Blocks (25-50) ....................1
FS3 Blocks (50-75) ....................1
FS4 Blocks (75-100) ....................0
Unformatted Blocks ....................0
Full Blocks ....................259
PL/SQL procedure successfully completed
在执行玩shrink命令后,此时表my_objects的HWM现在降到了276(280 - 5 + 1)的位置,而且HWM下的block的空间使用状况,full space的block有259个,free space 为25-50% 和50-75% Block只有1个。
5 shrink space原理剖析
5.1 实验环境
SQL> create table TEST_HWM (id int ,name char(2000)) tablespace ASSM;
Table created
SQL> insert into TEST_HWM values (1, 'aa');
1 row inserted
SQL> insert into TEST_HWM values (2, 'bb');
1 row inserted
SQL> insert into TEST_HWM values (3, 'cc');
1 row inserted
SQL> insert into TEST_HWM values (4, 'ds');
1 row inserted
SQL> insert into TEST_HWM values (5, 'dss');
1 row inserted
SQL> insert into TEST_HWM values (6, 'dss');
1 row inserted
SQL> insert into TEST_HWM values (7, 'ess');
1 row inserted
SQL> insert into TEST_HWM values (8, 'es');
1 row inserted
SQL> insert into TEST_HWM values (9, 'es');
1 row inserted
SQL> insert into TEST_HWM values (10, 'es');
1 row inserted
5.2 删除前rowid状态
SQL> select id,
2 name,
3 rowid,
4 dbms_rowid.rowid_object(rowid) object_id,
5 dbms_rowid.rowid_relative_fno(rowid) file_id,
6 dbms_rowid.rowid_block_number(rowid) block_id,
7 dbms_rowid.rowid_row_number(rowid) num
8 from test_hwm;
ID NAME ROWID OBJECT_ID FILE_ID BLOCK_ID NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
1 aa AAANAqAAHAAAAElAAA 53290 7 293 0
2 bb AAANAqAAHAAAAElAAB 53290 7 293 1
3 cc AAANAqAAHAAAAElAAC 53290 7 293 2
4 ds AAANAqAAHAAAAEmAAA 53290 7 294 0
5 dss AAANAqAAHAAAAEmAAB 53290 7 294 1
6 dss AAANAqAAHAAAAEmAAC 53290 7 294 2
7 ess AAANAqAAHAAAAEnAAA 53290 7 295 0
8 es AAANAqAAHAAAAEnAAB 53290 7 295 1
9 es AAANAqAAHAAAAEnAAC 53290 7 295 2
10 es AAANAqAAHAAAAEoAAA 53290 7 296 0
10 rows selected
5.3 删除后rowid状态
然后从table test_hwm中删除一些数据:
SQL> delete from TEST_HWM where id = 2;
1 row deleted
SQL> delete from TEST_HWM where id = 3;
1 row deleted
SQL> delete from TEST_HWM where id = 4;
1 row deleted
SQL> delete from TEST_HWM where id = 7;
1 row deleted
SQL> delete from TEST_HWM where id = 8;
1 row deleted
SQL> select id,
2 name,
3 rowid,
4 dbms_rowid.rowid_object(rowid) object_id,
5 dbms_rowid.rowid_relative_fno(rowid) file_id,
6 dbms_rowid.rowid_block_number(rowid) block_id,
7 dbms_rowid.rowid_row_number(rowid) num
8 from test_hwm;
ID NAME ROWID OBJECT_ID FILE_ID BLOCK_ID NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
1 aa AAANAqAAHAAAAElAAA 53290 7 293 0
5 dss AAANAqAAHAAAAEmAAB 53290 7 294 1
6 dss AAANAqAAHAAAAEmAAC 53290 7 294 2
9 es AAANAqAAHAAAAEnAAC 53290 7 295 2
10 es AAANAqAAHAAAAEoAAA 53290 7 296 0
从以上的信息,可知表test_hwm中,剩下的数据是分布在AAAAEl,AAAAEm,AAAAEn,AAAAEo这样四个连续的block中。
SQL> exec show_space('TEST_HWM');
Total Blocks ..........................8
Total Bytes ..........................65536
Total MBytes ..........................0.0625
Unused Blocks ..........................0
Unused Bytes ..........................0
Unused KBytes ..........................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................289
Last Used Block.........................8
The segment is analyzed below
FS1 Blocks (0-25) ....................0
FS2 Blocks (25-50) ....................1
FS3 Blocks (50-75) ....................3
FS4 Blocks (75-100) ....................1
Unformatted Blocks ....................0
Full Blocks ....................0
PL/SQL procedure successfully completed
通过show_space_assm我们可以看到目前这四个block的空间使用状况,AAAAEl,AAAAEn,AAAAEo上各有一行数据,可以猜测free space为50-75%的3个block是这三个block,那么free space为25-50%的1个block就是AAAAEm了,剩下free space为 75-100% 的3个block,是HWM下已格式化的尚未使用的block。
5.4 shrink后rowid状态
SQL> alter table my_objects enable row movement;
Table altered
SQL> alter table my_objects shrink space;
Table altered
SQL> select id,
2 name,
3 rowid,
4 dbms_rowid.rowid_object(rowid) object_id,
5 dbms_rowid.rowid_relative_fno(rowid) file_id,
6 dbms_rowid.rowid_block_number(rowid) block_id,
7 dbms_rowid.rowid_row_number(rowid) num
8 from test_hwm;
ID NAME ROWID OBJECT_ID FILE_ID BLOCK_ID NUM
------ ----- ------------------ ---------- ---------- ---------- ----------
9 es AAANAqAAHAAAAEkAAA 53290 7 292 0
10 es AAANAqAAHAAAAEkAAB 53290 7 292 1
1 aa AAANAqAAHAAAAElAAA 53290 7 293 0
5 dss AAANAqAAHAAAAEmAAB 53290 7 294 1
6 dss AAANAqAAHAAAAEmAAC 53290 7 294 2
当执行了shrink操作后,可以发现shrink操作与move不太一样。在move操作的时候,所有行的rowid都发生了变化,table所位于的block的区域也发生了变化,但是所有行物理存储的顺序都没有发生变化,所以我们得到的结论是,oracle以block为单位,进行了block间的数据copy。而在shrink后,部分行数据的rowid发生了变化,同时,部分行数据的物理存储的顺序也发生了变化,而table所位于的block的区域却没有变化(ID为1,5,6的rowid没有发生变化,ID为9,10两行数据,原来在AAAAEn,AAAAEo上都移到AAAAEk上)。以上说明,shrink只移动了table其中一部分的行数据,来完成释放空间,而且,这个过程是在table当前所使用的block中完成的。
6 shrink的注意点
1. move时产生的日志比shrink时少.参看http://blog.csdn.net/huang_xw/article/details/7016365
2. shrink在移动行数据时,也一起维护了index上相应行的数据rowid的信息,当然shrink过程中用来维护index的成本也会比较高。而表move后index的状态是UNUSABLE的,需要进行rebuild。参见http://blog.csdn.net/huang_xw/article/details/7016415
3. oracle是从后向前移动行数据,那么,shrink的操作就不会像move一样,shrink不需要使用额外的空闲空间。
Oracle中shrink space命令的更多相关文章
- Oracle中常用的命令,随着学习进度总结
原创作品,欢迎转载,转载请在文章显眼位置注明出处:https://www.cnblogs.com/sunshine5683/p/10016569.html 开始之前先注意:在linux中切换到sqlp ...
- Oracle中alter system命令参数之scope
SCOPE The SCOPE clause lets you specify when the change takes effect. Scope depends on whether you s ...
- oracle 中的truncate 和delete
一.查询表大小,块多少语句 Select SEGMENT_Name,BYTES,BLOCKS,Extents From dba_segments Where segment_name In('BAI_ ...
- oracle中imp命令详解 .
转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...
- oracle中imp命令具体解释
oracle中imp命令具体解释 Oracle的导入有用程序(Import utility)同意从数据库提取数据,而且将数据写入操作系统文件.imp使用的基本格式:imp[username[/pass ...
- Oracle中查询当前数据库中的所有表空间和对应的数据文件语句命令
Oracle中查询当前数据库中的所有表空间和对应的数据文件语句命令 ------------------------------------------------------------------ ...
- Oracle shrink space
一.开启表的行迁移 alter table table_name enable row movement; select 'alter table '||s.owner||'.'||s.table_n ...
- Oracle中HWM与数据库性能的探讨
Oracle中HWM与数据库性能的探讨 一.什么是高水位 HWM(high water mark),高水标记,这个概念在segment的存储内容中是比较重要的.简单来说,HWM就是一个segment中 ...
- Oracle中 HWM与数据库性能的探讨
链接:http://www.eygle.com/archives/2011/11/oracle_hwm_tuning.html 本文讨论的是oracle中关于table的HWM的内容,主要包括这样几个 ...
随机推荐
- 字符串转json数组
import net.sf.json.JSONArray;import net.sf.json.JSONObject; String content = inBankOdd.getContent(). ...
- 串口工具kermit(ubuntu)
安装 # sudo apt-get install ckermit 配置 kermit启动时,会首先查找~/.kermrc,然后再遍历/etc/kermit/kermrc # vi /etc/kerm ...
- go语言interface学习
Go 中的 interface 所具有的最基本的功能:作为一种 abstract type,实现各种 concrete type 的行为统一. interface是一种类型.只有是实例化后才能调用in ...
- orecle 查询数量 union合并 的排序问题
orecle 查询数量 union合并 之后按照从小到大排序了,这边需要不排序的 直接将union 改成union all 就解决了. 图就不传了,验证没问题
- c语言的函数指针和函数指针数组的简单demo
今天,简单记录一下,函数指针和函数指针数组的使用,废话不多说,直接贴上代码,里面有详细的注释,方便以后查阅. #include <cstdio> #include <Windows. ...
- OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)
简介 Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同. 首先,uniform是全局的(Global).全局意味着uniform变量必须在每个着 ...
- JAVA Calendar类获取上个月的第一天和最后一天
原文:https://www.cnblogs.com/QQParadise/articles/4936313.html 获取上个月第一天的方法: Calendar calendar = Calenda ...
- springboot @value 注解的使用
1,通过@value来注入对应的值,直接在字段上添加@value 获取application.properties文件中的值. @Configuration public class DemoConf ...
- c++初步认识
经过漫长的C学习终于踏入C++的知识库当中了,还是保持以前的习惯会一步步通过写博客的形式来记录点滴学习记录,这种学习方式是相当慢的,但是对我来说是最踏实的,不浮躁,一步一个脚印.C++是一门啥语言呢, ...
- canvas制图学习
<!DOCTYPE html> <html lang="zh-en"> <head> <meta charset="UTF-8& ...