該片博文使用與入門學習表空間的理論,本文背景是10G-11.2G。關注博主後續推出表空間的管理!
表空間的特性與作用
表空間的特性
表空間是數據庫中最大的邏輯結構,用來存放數據的數據。表空間是由至少一個數據文件組成。一個數據文件只能屬於一個表空間,一個表空間只能屬於一個數據庫。存放數據庫對象(表、索引、視圖、過程、函數等)
表空間的作用
控制數據庫所佔用的磁盤空間;
控制用戶所佔用的表空間配額;
將不同表的數據、分區表的不同分區的數據放到不同表空間(或相同表空間不同的數據文件)中可以提高I/O性能。還放利於備份、管理等工作;
將一個表的數據和索引分別存放在不同的表空間(或相同表空間不同的數據文件)可以提高I/O性能;
可以設置只讀狀態保持大量的靜態數據;
可以按表空間來備份恢復;
表空間的結構
表空間可以從以下兩個結構來切入瞭解。
邏輯:表空間實際是由一個或多個數據文件組成,數據文件是存儲在相同或不同物理磁盤上可以看到的文件。從下圖中可以清楚的看到物理結構的關係,其實從物理結構來理解,數據庫中所有的數據就是存儲在數據文件中。
對於數據庫來說表空間就是最大的邏輯結構。在表空間中最先的單位是Oracle塊,而一系列連續的塊組成一個區,多個區組成段,多個段組成表空間。
從邏輯理解表空間可以由下圖來解析,表空間中最小的單位就是Oracle塊,一系列連續的塊分組爲區間,多個區間組成一個段。段是表空間中邏輯上最大的單位。反過來理解就是表空間邏輯由段空間組成,段空間主要是管理所有Oracle塊的,而一個段中的塊特別多,每次管理一個塊空間過於耗時,所以我們將段中一系列連續塊分組爲區間來管理。
塊:實際存儲數據的地方。在定義了每次擴展區的大小其實就是定義多少個塊給一個區。
區間:一系列連續編號塊的集合。段每次擴展空間都是一個區間一個區間的擴展的空間。
段:由一個個區間組成。在創TABLE、INDEX、LOBINDEX、INDEX PARTITION、NESTED TABLE、TABLE PARTITION、ROLLBACK、LOB PARTITION、LOBSEGMENT、CLUSTER、TYPE2 UNDO時就會爲其分配一個段。
表空間類型
系統表空間
系統表空間包括SYSTEM表空間和SYSAUX表空間這兩個必須存在的,其餘的都是非系統表空間。系統表空間是數據庫必須有的表空間,在建庫時自動創建的。一般存放Oracle的數據字典和字典數據。
永久表空間
永久表空間主要存放永久保存的數據,如果系統數據、應用系統的數據。每個用戶都會擁有一個永久表空間,用於存方案對象的數據。除了撤銷表空間和臨時表空間其它的都是永久表空間。在BDCA建庫後系統也會自動創建一個USERS永久表空間。
當創建用戶時沒有指定默認的永久表空間時,系統默認指定使用USERS永久表空間。(用下面命令可以查看默認指定的永久表空間)
(select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';)
臨時表空間
用於存放臨時數據,當在執行group by、order by、create index等功能的sql語句時,會產生大量的臨時數據。這些臨時數據會存放在PGA中,當PGA不夠用時就會在存放到臨時表空間中。在BDCA建庫後系統也會自動創建一個TEMP臨時久表空間。
當創建用戶時沒有指定臨時表空間時,系統默認指定使用TEMP臨時表空間。(用下面命令可以查看默認指定的臨時表空間)
select * from database_properties where property_name='DEFAULT_PERMANENT_TABLESPACE';
撤銷表空間
撤銷表空間,一般存儲、管理撤銷數據。Oracle使用撤銷數據來回退事務、提供數據的讀一致性、幫助數據庫從邏輯錯誤中恢復、實現閃回查詢(Flashbackup Query)
Oracle可以創建多個UNDO表空間,但是同時只能允許一個激活的UNDO表空間。
通過以下命令來查看正在使用的UNDO表空間
show parameter undo_tablespace;
通過以下命令來設置使用的UNDO表空間
alter system set undo_tablespace='UNDOTBS2' scope=both;
大文件表空間(BIGFILE)和小文件表空間(SMALLFILE)
大文件表空間只能有一個數據文件(或臨時文件)。數據文件可以包括4G個塊,如果每個數據塊設置爲8KB,那麼大文件表空間最大可以達到32TB(4*1024*1024*8KB)。
小文件表空間可以擁有最多1022個數據文件。小文件可以包括4M個塊,如果每個數據塊設置爲8KB,那麼單個數據文件最大可達到32G(4*1024*1024*1024*8KB)。
表空間的狀態
處於不同模式的表空間,他的使用方式有所不同。通過人爲改變表空間狀態,可以控制表空間的可用性、安全性,也能爲備份、恢復、遷移等工作提供準備和保證。
讀寫(read-write)
默認情況下的表空間都是讀寫狀態,任何具有權限的用戶都可以對該表空間中的數據進行讀寫。
只讀(read-only)
設置爲只讀狀態後,任何用戶只能查詢該表空間中的數據。設置爲改狀態一般都是歷史數據只供查詢使用。提高了數據庫的安全性,在備份時只用備份一次就可以了。減少了DBA的管理負擔。
脫機(offline)
設置爲脫機狀態後,則代表該表空間的數據不讓用戶訪問。一般用於數據庫維護,數據文件損壞導致無法啓動數據或者更改數據文件位置。如果脫機的表空間想恢復使用只需要在設置回聯機即可。設置脫機有四種模式供選擇
正常(normal)
該模式是設置表空間脫機的默認模式,表空間以正常方式切換到脫機狀態。使用該模式脫機後Oracle會自動執行checkpoint檢查點將髒緩存寫入到數據文件中,然後在關閉表空間的所有數據文件如果中間沒發生任何錯誤,則可以進入normal脫機模式。所以下次聯機不需要進行數據庫恢復。(也就是說如果表空間或表空間的數據文件已經損壞則無法進入normal脫機模式)
臨時(temporary)
該模式讓表空間以臨時方式切換到脫機狀態。該模式不需要所有數據文件都是聯機的、可用的,但是Oracle會執行檢查點。在執行檢查點過程中因爲數據文件處於不可用狀態Oracle也會忽略這些錯誤進入temporary脫機模式。所以一般使用這個模式下次聯機可能需要做數據庫恢復。
立即(immediate)
使用該脫機模式則屬於強制進入脫機模式,不管數據文件是否聯機、可用,也不會執行檢查點直接進入脫機模式。所以下次聯機必須要做數據庫恢復。
用於恢復(for recovery)
該脫機模式表示將表空間以恢復方式切換到脫機狀態。一般用於對錶空間進行基於時間的恢復。
注意:SYSTEM表空間不能設置爲只讀狀態、脫機狀態,因爲數據庫運行過程中始終會用到SYSTEM表空間。臨時表空間也不能設置爲制度狀態。
表空間區、段的管理方式
區管理方式
區管理方式分爲如下兩種
一、字典管理方式(dictionary-managed tablasepace,DMT)
字典管理方式是傳統管理方式,是爲了與早期版本兼容而保留的區管理方式。字典管理方式是使用數據字典來管理存儲空間的分配,就是說當表空間中分配新的區或者回收已分配區的時候,oracle都會對數據字典中的相關信息查詢更新,速度較慢。
二、本地管理方式(local-managed tablespace,LMT)
本地管理方式是一種新方式,是一種新的改進的管理方式,Oracle強烈建議是用本地管理方式代替數據字典管理方式,並且在Oracle9i 以後默認使用的該管理方式。
在本地管理方式下,表空間中區的分配與回收的管理都被存儲在表空間的數據文件中,表空間在每個數據文件中維護一個“位圖(bitmap)”結構,用於記錄所有區的分配情況。(每個位圖消耗64KB的表空間)
在本地管理方式中還有兩個選項來指定表空間的區的分配方式。
統一(UNIFORM):統一分配,指定所有表空間的區大小相同,默認都是1M。不能對UNDO表空間使用該選項
自動(AUTOALLOCATE或SYSTEM):自動分配,由Oracle系統來自動管理區的大小(默認)
本地管理方式自動模式自動分配區大小與表的關係。當表大小不超過64KB時,表中每個分區大小爲64K;當表的大小達到1MB時,表中區每個區的大小爲1MB;當表的大小超過64MB小於1000MB時,區大小都是8M;當表數據大於1000MB時,系統在分配磁盤空間時一次分配64MB。
本地管理方式中段管理方式
在本地管理方式的表空間中,除了可以使用UNIFORM或AUTOALLOCATE來指定區的分配方式,還可以指定段空間的管理方式。段空間管理方式主要是指Oracle用來管理段中已用數據塊和空閒數據塊的機制。段管理可以用下列兩種方式來管理。
MANUAL(手動):使用空閒列表(free list)來管理空閒的空閒數據塊。該方式是爲了與以前版本兼容而保留的
手工管理塊
pctfree:保留空餘百分百(保留空餘如果少於這個百分百,則認爲已經不是可用塊)
pctused:允許使用百分比(如果裏面數據超過這個百分比,則在free list中則記錄它是已經使用完的,如果需要存數據會找下一個空餘塊。)
AUTO(自動):使用位圖(bitmap)來管理已用和空閒數據庫。通過位圖中單元的取值來判斷數據塊是否可用。
自動管理塊:
自動管理塊的原理是,將一個塊的空間分fs1、fs2、fs3、fs4四個狀態,使用空間達到0%-25%、25%-50%、50%-75%、75%-100%時會打一個對應的標記,當空間已經使用到75%-100%時時會打上fs1狀態,打上fs1狀態的塊在bitmap中該塊就顯示爲已使用狀態。如果塊中有數據被刪除,自動管理方式又會根據使用空間來確定是否需要重新定義狀態,重新定義了標籤,那麼在bitmap中也會得到更新。
ps1:位圖和空閒列表
位圖(bitmap):在數據文件中消耗64KB在每個段頭來記錄區或段是否使用,記錄方式是爲每個區或段保留一位。該位爲1或0時來代表正在使用或空閒。
空閒列表(free list):把段中所有的數據庫都被放入到一個空閒列表中,當需要使用時在該列表中進行搜索。
ps2:段爲什麼要留空間
段留空餘空間主要是保留給update使用,在後續如果update數據時他就會將數據直接往空餘塊空間中插入。如果保留空間存儲不下update的這一行數據時候這時候會產生行移動或者遷移,也就是說會把這一行數據一起遷移到一個能存儲的下的塊中。如果沒有一個塊能存儲的下的話那麼就會把這個行分片存儲在兩個或多個塊當中這個又叫行鏈接。理論上來講肯定是一行數據儘量存儲在最少塊中較好(也就是說一個塊能搞定就不要用兩個),因爲這樣在讀寫時是就只需要將一個塊加載到內存中即可。如果多個塊就增加了磁盤I/O,也增加了內存的開銷。原理來說肯定是一個塊裏面數據來的快。
不管是移動行或者行鏈接他的rowid是不會變的,所以在訪問該移動或鏈接的行都會訪問原來的塊,然後通過原來塊中的rowid鏈接指到存儲數據所在塊。所以會產生兩次讀塊的I/O過程。但是在後續使用中如果rowid所在塊中通過整理碎片或者有數據刪除後剩餘空間能存放的下已經遷移出去的行的數據時,它會在遷移回來。
延遲段
在11.2之前建表時候立馬就會分配一個段(也就是段的第一個區間),也就是說在建表的時候,在數據字典中添加信息之後,立馬給該表在表空間中分配一個段。在11.2之後出現了延遲分配段這個功能(deferred_segment_creation = true 默認開啓),就是在建表的時候只更新數據字典信息不分配段,等實際插入信息時在分配段。如果表使用延遲創建段那麼該表的索引段也會延遲創建。
延遲段只能用作於以下三種:一、非分區表、非分區索引;二、IOTs 索引組織表、CLUSTER 表、其它的特殊表;三、本地管理表空間中的表
如果你要把本地管理表空間中使用了延遲表的表移動到,數據字典管理的表空間中,你需要將該表刪除在重建。
延遲段的好處
索引失效後釋放段空間,但是數據繼續保留,在rebuild之後又能恢復所有信息,使用
創建索引,指定讓它失效:create index test_i1 on zhanky.cs(l1) unusable;
更改索引狀態爲失敗:alter index test_i unusable;
重建索引:alter index test_i rebuild;
段區管理常用命令
使用該命令查看是否開啓延遲分配段:
show parameter deferred_segment_creation
建表時指定延遲分配段:
create table zhanky.d (l1 number,l2 number) segment creation immediate;
建表時指定參數立馬分配段:
create table zhanky.c (l1 number,l2 number)
segment creation deferred;
查詢段信息:
select * from dba_segments where segment_name='CS';
查詢區間信息:
select * from dba_extents where segment_name='CS';
整理段
先回收數據,不回收HWM。(整理碎片空間,系統的刪除插入讓碎片空間快填滿)
alter table 表名 shrink space compact;
回收HWM。(業務少的時候弄)
alter table 表名 shrink space;
HWM:添加數據時,最後一個塊的塊號
整理段好處:提高性能、提高利用率、減少行鏈接行移動、索引自動重建
管理表空間的準則
確認表空間的大小
確定表空間的大小一般根據表空間中所有表的大小來確定。下面來介紹確認表的大小和表空間的大小。
確定表的大小:
我們通過查詢視圖USER_TAB_COLUMNS來得知以下參數
表的大小=最大行長*行數*(1+PCTFREE/100)*預留百分比
確定表空間的大小:通過表空間下所有表的估值大小來做初始大小,後續觀察監視使用情況增長情況在調整。
表壓縮
表壓縮,實現在插入時就壓縮存儲到數據庫上,(對系統幾乎無影響,只會小號很小的CPU)。在建表時指定語句確定表是否開啓壓縮技術。壓縮主要分爲兩種(BASIC、OLTP),Oracle的壓縮在讀取時是可以直接讀取的,不需要解壓縮。減少了塊的使用,其實也是減少了I/O增加了數據庫的效率也減少了存儲的空間。
如果建的表需要壓縮時只需要在創建時增加命令即可:{COMPRESS [ BASIC | FOR { OLTP } ] | NOCOMPRESS },如果不指定默認是NOCOMPRESS 不壓縮。
BASIC:壓縮比例可達到十倍,但是該方式只支持數據倉庫系統,在建表時加COMPRESS BASIC。在老版本中使用命令COMPRESS FOR DIRECT_LOADOPERATIONS。支持(DSS),只支持批量裝載數據壓縮。
BASIC壓縮原理:當寫入數據到塊的時候還不會壓縮,當一個塊達到PCTFREE時就開始壓縮,壓縮完了繼續往裏面插入數據,當達到PCTFREE時在壓縮。當使用BASIC時PCTFREE默認就變成0了。
OLTP:壓縮比例可達到二至四倍COMPRESS FOR OLTP,老版本中是使用命令COMPRESS FOR ALL OPERATIONS。支持(OLTP、DSS)
OLTP壓縮原:在寫入到塊中時對該塊內部數據進行運算,對重複值壓縮來較少空間的佔用。
11.2.0以後有compression advisor(壓縮專家)工具DBMS_COMPRSSION
表壓縮測試命令
查看錶是否開啓壓縮
select t.table_name,t.compression,t.compress_for from dba_tables t where tbale_name='cs';
創建OLTP壓縮表
create table zhanky.csa compress for oltp as (select * from zhanky.cs where 1=2);
插入數據(大概一百萬條)
insert into zhanky.csa (select * from zhanky.cs)
查看塊使用情況
select t.BYTES,t.blocks,t.blocks*8/1024/1024 from dba_segments t where t.segment_name='CSA'; select t.BYTES,t.blocks,t.blocks*8/1024/1024 from dba_segments t where t.segment_name='CS';
如果查詢沒找到塊的使用情況,執行一下表分析
analyze table zhanky.csa compute statistics;
表空間的配置
表空間的配置實質性考慮如何創建層次結構的表空間(以便將表創建在相對應的表空間中,減少競爭),以及將表空間中的數據文件安排放在哪個磁盤中。
將用戶數據和數據字典數據分別存放,避免數據字典對象和方案對象被保存在同一個數據文件中而產生I/O衝突。
將一個應用程序的數據與另個應用程序的數據分別存放, 保證各個應用程序的數據的獨立性,防止如果一個表空間必須被脫機,則多個應用程序都受到影響的情況。
在不同的磁盤驅動器上存儲不同表空間的數據文件,以減少I/O競爭,平均分配I/O操作。
將撤銷數據與用戶數據分別存放,防止單個磁盤的故障造成數據的永久丟失。
當其他表空間保持聯機時,可以使某個表空間脫機,以便對數據庫的一部分 進行單獨的備份恢復,提供更好的整體可用性。
能夠將某個表空間設置爲只讀狀態,從而將數據庫的一部分設置爲只讀狀態。
能夠爲某種特殊用途專門設置一個表空間,比如臨時表空間、撤銷表空間等,以優化表空間的使用效率,如快速更新動作、只讀動作。
能夠更加靈活地爲用戶設置表空間配額。
某些操作系統對一個進程 可以同時打開的文件數進行了限制。這些限制會影響同時聯機的表空間數量。因此,爲避免超過操作系統的限制,在建立數據庫時,DBA應當仔細地規劃所需表空間的數量,儘量做到爲不同類型的應用創建獨立的表空間,並且只創建滿足需求的足夠的表空間。
在創建表空間時,應當爲表空間創建幾個較大的數據文件或者將數據文件設置爲自動增長方式,而不要爲表空間創建許多很小的數據文件。