在上一篇介绍了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 操作。