从10g开始,oracle开始提供Shrink的命令,假如我们的表空间中支持自动段空间管理(ASSM),就可以使用这个特性缩小段,即降低HWM。这里需要强调一点,10g的这个新特性,仅对ASSM表空间有效,否则会报 ORA-10635: Invalid segment or tablespace type。

1 创建实验环境

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命令详解相关推荐

  1. Oracle中shrink space命令

    shrink_clause:   http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_3001.htm#i2192484 ...

  2. Fedora 中的 Yum 命令详解

    http://pengjiayou.com/blog/yum-fedora-in-order-detailed-explanation 总所周知,Redhat和Fedora的软 件安装命令是rpm,但 ...

  3. linux cut命令学习,Linux中的cut 命令详解

    今天小编要跟大家分享的文章是关于Linux中的cut 命令详解.cut 命令在Linux和Unix中的作用是从文件中的每一行中截取出一些部分,并输出到标准输出中.我们可以使用 cut 命令从一行字符串 ...

  4. USB CCID类协议中的APDU命令详解

    出处:http://blog.chinaunix.net/uid-29124653-id-4573075.html 原文地址:USB CCID类协议中的APDU命令详解 作者:jeffasdasd 最 ...

  5. 在oracle中使用存储过程,如何在ORACLE中使用JAVA存储过程(详解)

    如何在Oracle中使用Java存储过程 (详解) 一.如何缔造java存储过程? 通常有三种步骤来缔造java存储过程. 1.使用oracle的sql语句来缔造: e.g.使用create or r ...

  6. shell中的mput_FTP命令详解 及 shell中的使用

    FTP命令详解 FTP的命令格式为:ftp-v-u-d-i-n-g[IP地址]-v显示远程服务器的所有响应信息(verbose:详细,繁冗)-n限制ftp的自动登录,即不使用-d使用调试方式(debu ...

  7. linux中的tar命令详解,【Linux】tar命令详解

    tar命令详解 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用 ...

  8. oracle spool 分隔符_spool命令详解

    SQLPLUS SPOOL命令使用详解 SPOOL是 SQLPLUS的命令,必须在SQLPLUS中使用,主要完成以标准输出方式输出SQLPLUS的命令及执行结果,一般常用户格式化导出ORACLE表数据 ...

  9. Shell中的Sed命令详解

    简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space),接着用sed命令处理缓冲区中的内容,处 ...

最新文章

  1. redis java 性能_Redis 性能优化
  2. Sublime Text 2配置强大的IDE开发环境,运行java
  3. 课外知识----浏览器存储技术
  4. 阿里云服务器18个数据中心测试IP地址以及测试方法
  5. 杭电1978 How many ways
  6. 如何修改或新增visual studio 的模板
  7. 数据科学包4-pandas核心数据结构
  8. linux时间相关结构体和函数整理
  9. 用TensorFlow Lite 写个手写体识别 APP
  10. 基于beautifulSoup进行电影网站排名的获取与格式化输出
  11. 网卡添加VLAN TAG
  12. 07-图4 哈利·波特的考试(25 分)
  13. HR面试常见问题汇总
  14. Hibernate 第一个程序的问题Unknown entity(新手必看)
  15. iOS小技能:iOS15适配导航条主题: 背景颜色、标题颜色
  16. lowB三人组---冒泡排序原理和实现
  17. 我只想保持本色,和少年的心气。
  18. 深入理解原子操作-底层基础
  19. C语言中的常用循环语句
  20. Selenium QQ自动化登录

热门文章

  1. linux手误rm可能不需要跑路
  2. 128.3. Example 配置实例
  3. docker入门实践之数据卷管理
  4. 分类算法之邻近算法:KNN(应用篇)
  5. 前端每周清单第 39 期: OpenAI 与 gRPC, Gitlab 的 Vue 年度总结,GraphQL 技术栈漫游
  6. 第一部分:基础知识(第一章)File | New | Project
  7. Git合并最近的commit
  8. 史上最全面的程序员招聘建议
  9. 路由交换笔记(27)--ACL访问控制列表之练习
  10. 二分查找算法的C/C++实现