表空間的管理
--簡要文法:
CREATE [BIGFILE | SMALLFILE] [TEMPORARY] TABLESPACE tablespace name
DATAFILE datafile spec | TEMPFILE tempfile spec
[MINIMUM EXTENT minimum extent size]
[BLOCKSIZE blocksize]
[[COMPRESS|NOCOMPRESS] DEFAULT STORAGE (default storage clause)]
[LOGGING|NOLOGGING]
[FORCE LOGGING]
[ONLINE|OFFLINE]
[EXTENT MANAGEMENT DICTIONARY | LOCAL [AUTOALLOCATE|UNIFORM SIZE size]]
[SEGMENT SPACE MANAGEMENT MANUAL|AUTO]
[FLASHBACK ON|OFF]
注意标紅的部分,EXTENT管理,也就是所謂的表空間管理;而SEGMENT管理就是所謂的段空間管理。我們稍後會做一個段空間收縮的實驗。
字典管理:oracle 8i(不包括i),隻存在一種表空間的管理模式,即字典管理表空間(DMT),DMT是指oracle的空間配置設定或回收是通過資料庫中的資料字典表來記錄和管理的,用于管理的兩個資料字典表分别是:UET$(used
extents)和FET$(freeextents) 。其工作方式是:當建立一個新的段或者段在表空間時,oracle通過一系列的SQL語句來完成這個工作; 且和前面的兩個字典表有關,在繁忙的系統中會造成競争和等待(另一個DMT會帶來的問題是空間碎片)(DMT已經廢棄了)
本地管理(LMT): 在9i的R2版本後成了預設的選項
LMT在表空間的資料檔案頭部加入了一個位圖區域,在其中記錄每個extent的使用狀況
當extent被使用或者被釋放,oracle會更新頭部的記錄來反映這個變化,不産生復原資訊
因為僅僅操作資料檔案頭部的幾個資料塊,不用操作資料字典,LMT比DMT要快,尤其是在繁忙的時候更明顯
在每個表空間的資料檔案的頭部加入了一個位圖區域
一個段的第一個區的第一個塊是first level bitmap block
第二個塊是second level bitmap block
第三個塊才是段頭塊
這兩個塊是用來管理freeblock
若為自動配置設定,則Oracle會按照遞增算法來配置設定空間
如果選擇統一尺寸,還可以詳細指定每個區間的大小
dba_extents這個視圖可以看到哪些對象配置設定了多少區間
段空間管理:
從9i開始,段空間管理有兩種:
①MSSM:由你設定freelists、freelistgroups、pctused、pctfree、initrans等參數來控制如何配置設定、使用段中的空間
②ASSM:你隻需控制一個參數pctfree,其他參數即使建了也将被忽略
(1)freelist和freelistgroup
使用MSSM表空間管理時,Oracle會在freelist中為有自由空間的對象維護HWM以下的塊
freelist和freelistgroup在ASSM表空間中根本不存在,僅在MSSM表空間使用這個技術
(2)pctfree和pctused
pctfree告訴Oracle:塊上應該保留多大的空間來完成将來的更新
對于MSSM,她控制着塊何時放入freelist中,以及何時從freelist中取出。 如果大于pctfree,則這個塊會一直在freelist上
對于ASSM,因為ASSM根本不使用freelist。在ASSM中,pctused也将被忽略。
但她仍然會限制能否将一個新行插入到一個塊中 .
适當的設定pctfree有助于減小行遷移 .
⑶initrans
無論是ASSM or MSSM這個參數仍然有效
塊頭的事務槽的初始化大小有對象的initrans指定
實驗:shrink指令完成段收縮
從10g開始,oracle開始提供Shrink的指令,假如我們的表空間中支援自動段空間管理 (ASSM),就可以使用這個特性縮小段,即降低HWM.這裡需要強調一點,10g的這個新特性,僅對ASSM表空間有效,否則會報ORA-10635:
Invalid segment or tablespace type.
在這裡,我們來讨論如和對一個ASSM的segment回收浪費的空間.
同樣,我們用系統視圖all_objects來在tablespace ASSM上建立測試表my_objects,這一小節的内容,
實驗環境為oracle11.2.0.3:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
[oracle@lyg ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.3.0 Production on Thu Apr 10 14:31:45 2014
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
With the Partitioning, OLAP, Data Mining and Real Application Testing options
建立測試表空間:
SQL> CREATE TABLESPACE ASSMTEST
DATAFILE '/u01/app/oracle/oradata/test/assmtest01.dbf' size 50m 2 ;
Tablespace created.
SQL> create user assmtest identified by assm default tablespace ASSMTEST;
User created.
SQL> grant connect,resource to assmtest;
Grant succeeded.
建立測試使用者:
SQL> grant dba to assmtest;
SQL> conn assmtest/assm
Connected.
SQL> create table my_objects as select * from dba_objects;
Table created.
檢視表空間管理狀态:
select TABLESPACE_NAME,BLOCK_SIZE,EXTENT_MANAGEMENT,ALLOCATION_TYPE, SEGMENT_SPACE_MANAGEMENT
from dba_tablespaces where TABLESPACE_NAME = 'ASSMTEST';

然後我們随機地從table MY_OBJECTS中删除一部分資料:
SQL>select count(*) from my_objects;
COUNT(*)
----------
74582
SQL>delete from my_objects where object_name like '%C%';
27523 rows deleted.
SQL>delete from my_objects where object_name like '%U%';
6632 rows deleted.
SQL> delete from my_objects where object_name like '%A%';
10828 rows deleted.
現在我們使用show_space和show_space_assm來看看my_objects的資料存儲狀況:
SQL>exec show_space('MY_OBJECTS','ASSMTEST');
SQL> exec show_space('MY_OBJECTS','ASSMTEST');
Unformatted Blocks .................... 0
FS1 Blocks (0-25) .................... 0
FS2 Blocks (25-50) .................... 330
FS3 Blocks (50-75) .................... 270
FS4 Blocks (75-100) .................... 398
Full Blocks ....................
65
Total Blocks ........................... 1,152
Total Bytes ........................... 9,437,184
Total MBytes ........................... 9
Unused Blocks........................... 63
Unused Bytes ........................... 516,096
Last Used Ext FileId.................... 8
Last Used Ext BlockId.................. 1,152
Last Used Block......................... 65
PL/SQL procedure successfully completed.
SQL>exec show_space_assm('MY_OBJECTS','ASSMTEST');
SQL> exec show_space_assm('MY_OBJECTS','ASSMTEST');
free space 0-25% Blocks:................0
free space 25-50% Blocks:...............330
free space 50-75% Blocks:...............270
free space 75-100% Blocks:..............398
Full Blocks:............................65
Unformatted blocks:.....................0
這裡,table my_objects的HWM下有1151個block,其中,free space為25-50%的block有330個,free
space為50-75%的block有270個,free space為75-100%的block有398個,full space的block隻有65個,這種情況下,我們需要對這個table的現有資料行進行重組.
要使用assm上的shink,首先我們需要使該表支援行移動,可以用這樣的指令來完成:
SQL>alter
table my_objects enable row movement;
現在,就可以來降低my_objects的HWM,回收空間了,使用指令:
SQL> alter
table my_objects shrink space;
表已更改.
我們具體的看一下實驗的結果:
SQL>
exec show_space('MY_OBJECTS','ASSMTEST');
Unformatted Blocks .................... 0
FS2 Blocks (25-50) .................... 1
FS3 Blocks (50-75) .................... 1
FS4 Blocks (75-100) .................... 0
427
Total Blocks ........................... 448
Total Bytes ........................... 3,670,016
Total MBytes ........................... 3
Unused Blocks........................... 3
Unused Bytes ........................... 24,576
Last Used Ext FileId.................... 8
Last Used Ext BlockId................... 512
Last Used Block......................... 61
PL/SQL 過程已成功完成.
exec show_space_assm('MY_OBJECTS','ASSMTEST');
free space 25-50% Blocks:...............1
free space 50-75% Blocks:...............1
free space 75-100% Blocks:..............0
Full Blocks:.........................................427
PL/SQL 過程已成功完成.
在執行完shrink指令後,我們可以看到,table my_objects的HWM現在降到了447的位置,而且HWM下的block的空間使用狀況,full
space的block有249個,free space 為25-50%Block隻有1個.