剖析shrink 操作原理

在上一篇介绍了move 的操作,这篇介绍下shrink 操作:

 

在oracle 10g之后,推出了,shrink 操作,使用shrink 操作的时候索引可以不失效,这个对应用系统的影响要小不少。

SQL> create table daodao (id int, name char(2000)) tablespace users;  

Table created.

SQL> insert into daodao select rownum,'ddd' from dba_objects where rownum <=50;

50 rows created.

SQL> commit;

Commit complete.


SQL> show user;
USER is "SYS"
SQL> select header_file,header_block from dba_segments where segment_name ='DAODAO';

HEADER_FILE HEADER_BLOCK
----------- ------------
          4         2387


SQL> set pages 2000;
SQL> select Dbms_Rowid.rowid_block_number(rowid),count(1)  from daodao group by  Dbms_Rowid.rowid_block_number(rowid) ;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(1)
------------------------------------ ----------
                                2388          3
                                2389          3
                                2398          3
                                2390          3
                                2393          3
                                2395          3
                                2399          3
                                2400          3
                                2404          3
                                2405          3
                                2391          3
                                2397          3
                                2392          3
                                2406          3
                                2407          2
                                2394          3
                                2396          3

17 rows selected.

SQL> select header_file,header_block from dba_segments where segment_name ='DAODAO';

HEADER_FILE HEADER_BLOCK
----------- ------------
          4         2387

SQL> exec show_space('DAODAO');
Unformatted Blocks .....................               0
FS1 Blocks (0-25) ......................               0
FS2 Blocks (25-50) .....................               1          --- 该块为2407 存储2行的块,现在还剩余25%-50%的剩余空间
FS3 Blocks (50-75) .....................               0
FS4 Blocks (75-100).....................               3          --- 3个为已格式化的空块
Full Blocks ............................              16          --- 16个为已经满的块
Total Blocks............................              24          --- 消耗的总块数为24个
Total Bytes.............................         196,608     
Total MBytes............................               0
Unused Blocks...........................               0
Unused Bytes............................               0
Last Used Ext BlockId...................           2,401          --- 最后使用的区头的blockid 对应dba_extents 的block_id
Last Used Block.........................               8

PL/SQL procedure successfully completed.

SQL> alter table daodao enable row movement;

Table altered.

SQL> delete from daodao where mod(id,2)=1;

25 rows deleted.

SQL> commit;

Commit complete.

SQL> select Dbms_Rowid.rowid_block_number(rowid),count(1)  from daodao group by  Dbms_Rowid.rowid_block_number(rowid) ;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(1)
------------------------------------ ----------
                                2388          1
                                2389          1
                                2398          2
                                2390          2
                                2393          2
                                2395          1
                                2399          1
                                2400          2
                                2404          2
                                2405          1
                                2391          1
                                2397          1
                                2392          2
                                2406          2
                                2402          1
                                2394          1
                                2396          2

17 rows selected.

SQL> exec show_space('DAODAO');
Unformatted Blocks .....................               0
FS1 Blocks (0-25) ......................               0
FS2 Blocks (25-50) .....................               8
FS3 Blocks (50-75) .....................               9
FS4 Blocks (75-100).....................               3
Full Blocks ............................               0
Total Blocks............................              24
Total Bytes.............................         196,608
Total MBytes............................               0
Unused Blocks...........................               0
Unused Bytes............................               0
Last Used Ext BlockId...................           2,401
Last Used Block.........................               8

PL/SQL procedure successfully completed.

SQL> alter table daodao shrink space compact;

Table altered.

SQL> select Dbms_Rowid.rowid_block_number(rowid),count(1)  from daodao group by  Dbms_Rowid.rowid_block_number(rowid) ;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(1)
------------------------------------ ----------
                                2388          4
                                2389          4
                                2390          4
                                2393          4
                                2391          4
                                2392          4
                                2394          1

7 rows selected.

SQL> select header_file,header_block from dba_segments where segment_name ='DAODAO';

HEADER_FILE HEADER_BLOCK
----------- ------------
          4         2387


-- 从这里可以看到和move 操作完全不一样,这里段头没有改变,move 为什么需要多一倍空间,就是因为move 执行的是创建一个表,迁移,然后再
删除原表的操作,而shrink 则不一样,他完全是在自己的表里面进行操作,所以他不需要多一倍空间。

SQL> exec show_space('DAODAO');
Unformatted Blocks .....................               0
FS1 Blocks (0-25) ......................               1
FS2 Blocks (25-50) .....................               0
FS3 Blocks (50-75) .....................               1
FS4 Blocks (75-100).....................              13
Full Blocks ............................               5
Total Blocks............................              24           ---高水位没有降低
Total Bytes.............................         196,608
Total MBytes............................               0
Unused Blocks...........................               0
Unused Bytes............................               0
Last Used Ext BlockId...................           2,401          ---最后一个区块没有移动
Last Used Block.........................               8

PL/SQL procedure successfully completed.

--- 这里就是为什么说shrink space compact  是轻量级的shrink ,只是使得数据块之间更加夯实了,实际上高水位没有降低。

SQL> alter table daodao shrink space ;

Table altered.

SQL> exec show_space('DAODAO');
Unformatted Blocks .....................               0
FS1 Blocks (0-25) ......................               0
FS2 Blocks (25-50) .....................               0
FS3 Blocks (50-75) .....................               0
FS4 Blocks (75-100).....................               1
Full Blocks ............................               6
Total Blocks............................              16
Total Bytes.............................         131,072
Total MBytes............................               0
Unused Blocks...........................               6
Unused Bytes............................          49,152
Last Used Ext BlockId...................           2,393
Last Used Block.........................               2

PL/SQL procedure successfully completed.

SQL> select header_file,header_block from dba_segments where segment_name ='DAODAO';

HEADER_FILE HEADER_BLOCK
----------- ------------
          4         2387

---段头没有改变,说明对象并没有变化,说明shrink 只是对表对象进行操作,所以它也不需要额外一倍空间。

ps:  move的操作速度远远快于shrink 操作 ,不是一般的快,不是一个数量级的,而且shrink 会产生大量的undo 和redo 操作。

 

你可能感兴趣的:(剖析shrink 操作原理)