翻译: Oralce官方文档-- Data Blocks, Extents, and Segments
生活随笔
收集整理的這篇文章主要介紹了
翻译: Oralce官方文档-- Data Blocks, Extents, and Segments
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Data Blocks, Extents, and Segments? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?--數據塊,區,與段
原文:
docs.oracle.com/cd/B28359_01/server.111/b28318/logical.htm#i8531
這一章描述了Oracle數據庫存儲結構的邏輯,性質和聯系。包含了下列概要:1.Data Blocks, Extents, 和Segments的介紹2.Data Blocks 的概述3.Extents 的概述4.Segments 的概述
1.Data Blocks, Extents, 和Segments的介紹Oracle為數據中所有數據都分配對應的邏輯空間, 而邏輯空間的單位就包括Data Blocks, entents, and Segments.圖例2.1 描述了它們之間的關系
作為最小存儲單元, oracle會將數據存入Data blocks中(數據塊,也有人稱為 logical blocks, Oracle blocks 或pages), 1個Data blocks 對應1個指定大小的字節數(block size 通常在創建數據庫時指定)的硬盤物理空間。也就說每個data block 大小都是一樣的,上圖中是2kb.
上一層的存儲單位叫Extents(中文名一般叫區), 1個 extents 通常是一定數量的相鄰的data blocks 組成, 用于存放指定類型的數據。?
再上一層的存儲單位就叫做Segments了(段), ?1個Segments 是有一組extents組成的,而對應每1個extent都被分配存放指定的數據類型,而且它們都在同1個表空間中。例如,每1個table 都存儲在它自己的data segment中(數據段), 而每1個index 都存儲在它自己的index?segement?中(索引段).如果表或索引是分區(partitioned)存儲的,那么對應每1個分區會擁有自己的segment.
每個Segement 和它包含的extents都只能存放在1個表空間(table space)中, ?如果表空間包含若干個數據文件(data file). 那么1個Segement 是可以包含存放在不同數據文件的extents的。 也就是說,segement是可以跨數據文件存儲的,而extents只能放在1個數據文件中。
雖然你可以額外添加1個extent, 但它的blocks未必會同時分配,如果你將1個extent分配到1個指定的實例(數據庫對象)中,那么它的blocks會馬上分配并加到可用塊列表中(free list). ?然而如果你不是將1個extent 分配到指定實例中的話,那么它的block只會等到高水位線(high water mark)移動時才分配。高水位線是1個segment中已用和未用空間的界限。
2.Data Blocks 的概述在Oracle的存儲空間管理中, 1個數據庫的數據文件內的存儲單位叫Data blocks, 1個Data block 是數據庫中最小的數據存儲單位。然而,所有數據在操作系統中的物理存儲單位是字節(byte). 每1個操作系統都有它自定義的塊大小(block size). Oracle會將數據存放在oracle自定義的data blocks中, 而不是操作系統本身的系統塊(blocks).
Oracle標準Block size 是由數據庫初始參數DB_BLOCK_SIZE指定的。除此之外,你還可以指定最多5個非標準的Block size, 你應該將oracle Block size 設成操作系統Block size的倍數, 以最大限度地避免多余的I/O。Oracle data blocks 是oralce可以使用和分配的最小的存儲單位/
2.1 Data Block 的結構。Oracle數據庫的Data blocks的結構是類似的。不論它們存放的是table,index或者clustered data(簇表)。圖例2.2 表示了data block的結構。
這一小節我們討論下面這些Data Block的組成部分.
2.1.1 數據塊頭(含標準內容與可變內容)??????????????????????? #Header(Common and Variable)? ??
2.1.2 表目錄區 ????????????????????????????????????????????????????????????? #Table Directory
2.1.3 行目錄區 ????????????????????????????????????????????????????????????? #Row Directory
2.1.4 頭部信息 ????????????????????????????????????????????????????????????? #OverHead
2.1.5 行數據區?????????????????????????????????????????????????????????????? #Row Data
2.1.6 可用空間區 ????????????????????????????????????????????????????????????? #Free Space
2.1.1 數據塊頭(含標準內容和可變內容)
數據塊頭包含基本的Data Block信息,例如Block的地址和所屬段的類型.(例如,數據段\索引段)
2.1.2 表目錄區
這部分包含Data Block中的數據行所屬表的信息.
2.1.3 行目錄區
這部分包含Data Block中的數據行的信息.(每一條數據行(或數據行的一部分)的地址).
注: 1個data block可能包含一條或多條完整的數據行,或者一條數據行的一部分.
當數據塊行目錄被分配后,即使對應數據行被刪除,這部分空間也不會被回收. 例如,1個數據塊曾經包含多達50條數據,但被清空后,行目錄區人仍然保留100 bytes的行目錄數據. 只有當有新的數據行被插入的這個Data Blocks, Oralce才會對該行目錄空間重新分配利用.
2.1.4 頭部信息
數據塊頭,表目錄區,行目錄區被共同地成為頭部信息.? 有些Data block的頭部信息是固定大小的. 而頭部信息的總大小是可變的(也就是說有寫是可變的).平均來講, 頭部信息的固定和可變部分總共為84-107 bytes.
2.1.5 行數據區
這部分包含數據表或索引的內容, 數據行可以跨Data Blocks存儲.
2.1.6 可用空間區
可用空間是預留給新數據行的插入或者現有數據行的更改(例如將1個Null值改為1個非Null值)
如果1個Data Blocks是屬于Data segment存放表數據, 或 Index segement而存放索引數據。那么它的可用空間還會存放transaction entry(事務條目),在每一次對數據塊中的一行或多行進行 insert/update/delete 和select.. for update操作時,可用空間就需要存放一條transaction entry. transaction entries的所需空間取決于擦作系統,在大部分操作系統里是23 bytes左右。
2.2 可用空間管理
可用空間可以由系統自動管理或者手動管理。
數據庫 segments 里面的可用空間可以被系統自動管理, segment 內的可用/已用空間用Bitmap形式記錄(tracked using bitmap), 與用列表(free list)管理不同,segment 空間自動管理具有如下優點:
????? * 易與使用
????? * 更優秀的空間利用率,特別是對于那些每行數據大小差異大的對象來說。
????? * 對并行訪問情況變化進行更好的實時調整。
????? * 多實例運行時,有更優秀的性能和空間利用率。(Better multi-instance behavior in terms of performance/space utilization)
當用戶創建1個本地管理的表空間時,可以設定自動segment空間管理。這個設定會應用到這個表空間創建的segment.
2.2.1 Data block 中可用空間的有效性和優化
有兩種操作語句可以為1個或多個Data blocks增加可用空間:? 分別是Delete語句和某些Update語句(將已存在的值更新為占更小空間安的值). 釋放出的空間有隨后符合以下兩個條件的insert語句所使用。
???????? * 如果insert語句在釋放空間的語句之后,而且和釋放空間的語句在同1個事務內,那么這些insert語句可以使用釋放出來的空間。
???????? * 如果insert語句和釋放空間的語句在不同的事務中(或者由不同的用戶提交),那么只有當釋放語句的事務提交之后,且insert語句必須使用這些釋放空間,? 這些釋放空間才會被Insert語句所使用。
在1個Data Block中,loin987z空間相鄰, Oralce只會遇到下列兩種情況才會合并可用空間。
1)inert或update語句選中1個足夠存放新數據的可用空間。
2) 本身可用空間過于分散,數據無法寫入1個連續的可用空間里。
Oracle之所以在這些情況才會做合并可用空間的動作。是因為頻繁進行合并動作進性時會影響數據性能。
2.2.2 行鏈接和行遷移 Row Chaining and Migrating
有兩種情況會導致1個數據行太大,不能放入1單個Data Block中.? 第一種情況,當一個數據行在第一次插入數據庫時就由于本身size太大而不能全部放入1個Data Block中,在此情況下,Oralce會將這個數據行存放在由1個Segment中的一組Data Blocks組成的鏈接(chain)中。行鏈接的形成大部分是由于大容量的數據行,例如數據行中有類型是LONG 或 LONG,在這情況下行鏈接是不可避免的。(除非加大Block Size).
然而,第二種情況是,有1個數據行原本已經完全存放在1個Data Block中, 但是由于Update動作, 數據行的總大小變大了。 而那個數據的可用空間此時已被占滿(可能由其他數據行占滿)。 在這種情況下,oracle會將這條數據行遷移(migrate)到(整條)到1個新的Data Block中。Oracle會在舊Data block中數據行原位置保存1個指針指向那個新的Data Block。 原rowid 保持不變。
當行遷移或行鏈接發生時,對有關于這個一行的I/O性能會下將, 因為數據庫必須掃描額外的Data Block來檢索數據行的全部信息。
?
2.2.2 PCTFREE, PCTUSED, and Row Chainning?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? -- Pctfree, pctused 和 行鏈接
下面這小part是我自己添加的
======================================================
Segment 管理方式有兩種:(管理Block)
1 MSSM(Manual Segment Space Management)
2 ASSM(Auto Systemt Space Management)
1 MSSM(Manual Segment Space Management)
通過在segment的段頭分配自由列表(freelist) 來管理block
通過兩個參數 pctfree pctused來管理block如何進出freelist
pctfree 值表示預留多少%的block空間用于更新
pctused 值表示低于這個值是,block會重新加入到freelist上
通過dba_tables,dba_indexes查看freelist,pctfree,pctused等參數的設置
2 ASSM(Auto Systemt Space Management)
通過在segment的段頭分配位圖(bitmap) 來管理block
不再需要freelist
不在需要pctused,因為不需要從freelist上摘除block。
可以在user_tablespaces 這個視圖查看Segment_Space_Management 列,
獲得模式類型。
======================================================
在手動管理(MSSM)的表空間中,有兩個空間管理參數, PCTFREE 和 PCTUSED,允許用戶通過這兩個參數在某1個segment中進行insert 和 update操作時,對該segment 中所有data blocks的可用空間進行管理。用戶可以在創建或修改一張數據表或簇表(有屬于自己的segment)時設定這兩個參數,用戶也可以在創建或修改index(有屬于自己的segment) 時指定數據存儲參數(Storege paramter) PCTFREE 。
df
下面包含下列內容.
??????????? * PCTFREE 參數
??????????? * PCTUSED 參數
??????????? * PCTFREE和PCTUSED 是怎么一起工作的
??????????? ------------------------------------------------------------------------------------------
?????????????? 注:我們討論的范疇不包括LOB 數據類型(BLOB,CLOB,NCLOB和BFILE),它們不會使用PCTFREE參數
?????????????????? 或free list(可用塊列表).
?
2.2.3 PCTFREE 參數
用戶可以用PCTFREE 參數來設置Data Block中預留給update操作的可用空間百分比,用來為已存在數據的長度增長做準備。
例如, 假如你執行Create table語句時加入這1個參數
PCTFREE 20
這樣就聲明了,在這個表(表空間的對應segment)中的每1個Data blocks中, 會保留20%的可用空間預留給Update操作造成的數據長度增長,新的數據行會存儲入Row Data Area, 而相應的信息會存儲入Overhead Area(2.1.4 頭部信息)的可變部分,直到Row data和overhead的總容量達到Data block容量的80%.
圖例2.3 闡明了PCTFREE的作用:
?
2.2.4 PCTUSED 參數
PCTUSED 設置了1個最小百分比,當Data Blocks的已用空間(row data + overhead)占總空間的比率小于PCTUSED時,才允許新數據行插入到這個Data Block中。 當Data block的已用空間到達PCTFREE的限制時, Oralce 就不允許新數據行的插入,直到已用空間的比率下降到PCTUSED設定的比率. 否則Oracle只會用那些可用空間提供給已存在數據行的update操作。
例如,當你創建1個數據表同時指定如下參數
PCTUSED 40
這個表(表空間的對應segment)中的每1個Data blocks中, 除非已用空間比率在39%或者更低(假設那個Data block的可用空間曾經下降到達PCTFREE的限制)。
?
2.2.5 PCTFREE 和 PCTUSED 共同起作用的
在1個segmenet中,PCTFREE 和 PCTUSED 會共同作用以優化Data blocks的空間使用。
圖例2-5 顯示了這個兩個參數的相互作用。
?
圖1:數據行能一直插入值到已用空間到達80%, 這是因為PCTFREE 設定要保留20%的可用空間預留給已存在行的Update操作。
圖2: 更新造成的數據長度增長會占用這些保留的空間,新的數據行不允許插入,值到已用空間降到(更新或刪除)39%或更低。
圖3:當已用空間降到40%以下時,新數據行又可以插入到這個Data Block中了。
圖4:數據行能一直插入值到已用空間到達80%, ..這個邏輯一直循環下去。
在1個新使用的Data block中,數據行Insert的操作可以使用的空間是Data Blocks總空間 減去 頭部信息和PCTFREE的和。而update已存在數據行的操作能使用Data block中任何可用空間,因此update操作一樣有機會令可用空間減少低于PCTFREE的限制,PCTFREE保留的空間是為了Update操作準備的,而不是Insert。
對于每1個數據和索引Segment,oracle都會維護一個或多個Free List -- 分配給該Segment的數據區(extends),而且可用空間大于PCTFREE的Data Blocks列表. 這些Data Block可以被插入新數據行. 當你提交一條insert語句,Oralce就會檢查Free List中的第1個Data Block,如果它是可用的,就會使用它。 若它的可用空間不足以容納那條insert語句,而且該Data Block的可用空間已經超過PCTUSED(如上圖,例如已用41%,超出PCTUSED的40%),ORACLE就會將該Data Block移出Free List.1個segment里允許有多個Free list,這樣減少了并發Insert操作時對單個Free list的爭用。
當用戶提交1個Delete或update操作,Oracle就會執行這些語句然后會檢查對應Data Blocks中的已用空間是否已經低于PCTUSED,如果是,則將Data Block則進入Free list成為該事務第首個可以使用的Data Block。當對應事務被提交,該Data Block 可以被其他事務使用。
3 Extents概述? (overview of extents)
1個Extent 就是數據庫中由1組連續的Data Blocks組成的存儲邏輯單位. 1個或多個Extents組成1個Segment,當1個Segment中的extents被用完,oracle會分配新的extend給該segment.
這一節包含如下內容:
??? * Extents何時被分配
??? * Extents數量和大小的決定
??? * Extents怎樣被分配
??? * Extents何時被回收
3.1 Extents 何時被分配
當你創建1張表時,Oralce會為哪張表的segment分配1個有一組指定數量Data blocks組成的initial extent(初始區), 即使當時還沒有數據行插入,那些相應的Data Blocks還是會預留為那張表的數據行使用.
如果上面的initial extent的空間用完了,而且需要更多的空間來裝在表數據,那么oracle就會分配1個incremental extent(增加的區),1個incremental extent是1個后續的extent,容量大于或等于該表segment中之前的extents.
出于方便維護的目的,每個segment中頭1個Data block會存儲該segment中的地址信息。
?????????????? -------------------------------------------------------------------------------------------------------------------
???????????????注:這一章使用于Serial operations(串行操作,也就是1個1個來的意思),即是
那些之有1個服務進程,運行1條sql語句的操作。 對于那些被多個服務進程并發執行
的sql語句(parallel SQL statements),entents的分配會有點不同。
?????????????? -------------------------------------------------------------------------------------------------------------------
??????????
3.2 Extents數量和大小的決定
每個segment中,Storage paramter(存儲參數)可以表示出extends的定義。Storage Parameter適用于所有類型的segments. 它們可哦就控制了oracle應該怎樣分配數據庫可用空間給1個segment. 例如你可以在執行Create table 語句時使用Storage 字句來指定segment中初始預留空間的大小,也可以限制分配給segment的extents數量。如果你沒有指定Storage paramter, 那么系統會使用表空間的默認Storage parameter.
用戶可以使用由數據字典(dictionary)來管理的表空間,那些表空間會依賴數據字典來監控空間利用情況,也可以使用本地管理(locally managerd)的表空間, 那些表空間會用位圖(bitmap)來標記已用空間(而不是用數據字典)。因為本地管理方式有更好的性能而且更容易管理,所以當用戶沒有指定extent的管理方式時,除了System的永久表空間(permanent tablespaces)默認使用本地管理方式。
?????????? 注:上述管理類型可以在user_tablespaces 中的 extent_management 列查詢.
1個本地管理模式的表空間的extends要么是固定大小的(所有extends的size是一致的),要么是由系統自動決定大小而且大小非固定的。當你創建1個表空間,UNIFORM 和 AUTOALLOCATE(系同管理)子句可用來決定分配類型。
????????? * 對于固定大小的extends, 你可以指定1個值或者使用默認的size,默認是1MB,
要確保每1個extends至少含有5個Data blocks 的大小, 本地管理的
臨時表空間(Temporary tablespaces)只能使用這種分配方式(固定大小)。
??
????????? * 對于系統自動管理的extends, oracle自己會為additional extents決定最優的size,
而1個extends的size的最小值是64kb. 如果一張表空間創建時包含字句
"segment space management auto", 而且數據庫的
Block size大于等于16KB,那么oracle在使對應的segment創建最小值
為1MB 的extends. 上面所說的是永久性表空間的默認值。
在本地管理方式的表空間中,存儲參數 INITIAL,NEXT,PCTINCREASE和MINEXTENTS不能被設定于表空間這一層,但是,他們可以在segment這個層面上設定。在這種情況下,INITIAL,NEXT,PCTINCREASE和MINEXTENTS這4個參數會一起計算segment的初始大小值。segment的初始大小值計算完后, 隨后內部算法會決定segment里每1個extents的大小。
3.3 Extents怎樣被分配.
Oracle使用不同的算法去分配Extents, 取決于他們是數據字典管理類型還是本地管理類型的。
在本地管理類型的表空間中,oracle為了給1個新分配的extent尋找可用空間,會首先選中表空間的1個候選的Data file(數據文件),然后會檢查這個datafile的bitmap,尋找所需數量連續的Data blocks. 若該datafile里沒有足夠的連續空間,則會選擇另1個datafile繼續查找。
????????? 注:Oracle強烈建議你使用本地管理類型的表空間。
3.4 Extents何時被回收
Oracle提供1個Segment Advisor(顧問)工具, 會基于1個對象內的空間碎片,幫助你了解該對象內是否有空間可以用來回收再利用。
通常,1個segment內的extends不會返回表空間中,除非你刪除存放在該segment的數據庫對象(使用Drop table 或 Drop cluster語句)。
但是下面的情況是例外:
?
????? * 一張table或cluster的owner,或者1個擁有Delete任何東西權限的user,可以
????? 截斷(truncate)1張table或cluster(使用TRUNCATE...DROP STORAGE語句)
????? * 1個數據庫管理員(DBA) 可以通過下面的SQL語句來回收未使用的extents. Orz..
??????? ALTER TABLE table_name DEALLOCATE UNUSED;
????? * Orace會定期從1個回滾段(rollback segment)回收1個或多個extents.
? ? ? ? 前提是那個segment的參數OPTIMAL size已被設定
???
當extends被釋放,Oracle會修改相應datafile 的Bitmap(for 本地管理類型表空間),或者修改相應datafile的dictionary(for 數據字典管理類型的表空間)來表明被回收的extents是可用的. extends內任何Data blocks內的數據會被釋放,從而extends也不能被訪問。
這一節包含以下topics:
???????
????? * 非簇表的extends???? #extends in Nonclustered Tables
????? * 簇表的extends??????? #extends in Clustered Tables
????? * 具體視圖及其日志中的extends? #extents in Materialized Views and Their Logs
????? * 索引中的extent
????? * Temporary Segments 中的 extents
????? * Rollback Segments 中的 extents
3.4.1 非簇表的extents???? #extends in Nonclusterd Tables
只要1張表還存在于數據庫中,那么分配給該表的segment的Data blocks會一直保留在那,除非這張表被trancate了。若1個data block還有可用空間,oracle會將新數據行插到它里面。即使你用把該表的所有行都Delete了, oracle也不回收該表的data blocks 而用于表空間的其他對象。
當你把這張表drop掉之后,當別的extents需要新空間時會回收原本該表的空間。 ---- oracle 會回收這張表的data segments 和 index segments里所有的extents, 并供同一個表空間內的其他方案對象(schema objects)使用。
在數據字典管理類型的表空間中,當1個segment所需的extents長度大于可用的extents長度時,oracle會尋找并將回收的extents合拼成1個大的連續extent. ?這就是extents合拼(coalescing). extents 合拼在本地管理類型(locally managed tablespace)的表空間中并不是必需的,因為所有連續空間都能被分配給1個新的extent, 而不管這些空間是不是從1個或多個extents中回收的.
3.4.2 簇表的extents???? #extends in Clusterd Tables
簇表的數據存放在專門的為簇而建立的segment中. 所以當你drop掉簇里的1張表, 對應的segment就會預留給簇里的另一張表,沒有任何extents被回收. 你亦都可以truncate 簇(除了哈希簇)來釋放extents.
3.4.3 具體視圖及其日志中的extends? #extents in Materialized Views and Their LogsOralce回收具體尸體及其日志中的extents的方式是和表和簇的方式一樣的.
3.4.4 索引中的extent
只要1個index 還存在,oracle都會為其保留住分配給它的index segement. 當你drop掉這個index 或者對應的表或簇, oralce 會回收這些extents, 分配給對應的表空間用于其他地方.
3.4.5 Temporary Segments(臨時段) 中的 extents
當oracle執行完1個用到temporary Segment的語句時, Oracle會自動drop掉那個temporary segment, 并收回里面的extents給對應的表空間.
當用戶執行1個單一排序(single sort)語句時,會在1個temporary tablespace(臨時表空間) 建立自己的temporary segments , 執行完后會釋放那些extents到表空間中.
但是在Multiple sorts(多重排序)中, 可使用temporary tablespaces中專門指定給排序用的segments. 這些sort segments 對于那個instance(實例)只能分配1次, 排序之后它們不會被回收, 但是為會被其他Multiple sorts排序.
1張臨時表里的temporary segment 可以含有1個trancaction(事務)或session(會話)的多條SQL語句的數據. 當事務或會話結束后oracle會drop那個temporary segment,并回收其中的extents給對應的表空間.
3.4.5 Rollback Segments(回滾段) 中的 extents
Oracle會定期檢查數據庫中的Rollback segments, 看看它們是否已經超過了最佳的大小(optimal size),如果1個Rollback Segment的size超過了optimal size(也就是說里面有太多extents了), 那么oracle會自動回收它里面的1個或多個extents.
4 Segment概述? (overview of Segment)
1個segments 就是在表空間內由一些包含所有特定邏輯結構的extents組成的存儲結構. 例如, 對于每一張表, oracle會分配1個或多個extents形成該表的Data segment,? 而對于每1個index, oracle會分配1個或多個extents形成該index的index segment.
這一章節包含如下topics:
????????
?????????? * Data Segments 介紹
?????????? * Index Segments 介紹
?????????? * Temporary Segments 介紹
?????????? * Undo Segments 介紹 和 Automatic Undo Management
???
4.1 Data Segments 介紹
Oracle中1個Data Segment 包含下列對象的所有數據.
?????????? * 1張table, 而它不是分區表且不是簇表.
?????????? * 1張分區表里面的1個分區
?????????? * 1個簇(含多張表)
當你執行創建1張table 或 cluster的語句時Oracle就會為其創建對應的Data segment.
表或簇的存儲參數決定了對應的Data segment的 extents 是怎樣分配的. 用戶可以直接在Create 或 Alter 語句中設定這些存儲參數. 這些參數會影響其Data segment中數據檢索和存儲的效率.
???????????????????????????? ---------------------------------------------------------------------
??????????????????????????? 注:Oracle為物化視圖(materialized view)創建segment的方式是和tables和cluster
?????????????????? 一樣的.
??????????????????????????? ---------------------------------------------------------------------
4.2 Index Segments 介紹
對于1個非分區索引,oracle會存有1個對應的index segment來存放它的所有數據,對于1個分區的索引,每個分區都有1個對應的index segment存放它的數據.
當用戶執行創建索引的語句時,oracle會為該索引或索引分區建立Index segment. 用戶可以指定index segment的extents的存儲參數 和指定創建index segment的表空間.(1張表和它的索引可以使用不同的表空間).這些參數會影響其Data segment中數據檢索和存儲的效率.
4.3 Temporary Segments 介紹
當用戶執行查詢時, Oracle通常要為Sql語句的分析和執行的中間階段(intermediate stages)準備臨時空間. Oralce會自動分配這些硬盤空間并稱之為Temporary Segment. 例如, Oracle 需要1個Temporary Segment用于排序的數據庫空間. 如果該排序操作可以在內存內完成或者oracle找到另1中使用索引去排序的方法, 則oracle不會創建Temporary segment.
這一小節包含如下topics:
????????????? * 需要 Temporary Segments的操作
????????????? * 臨時表和他們的索引的Segments.
????????????? * Temporary segments 是怎樣分配的.
4.3.1 需要Temporary Segments的操作
下列語句有時會需要用到Temporary segments:
???????????
????????????? * CREATE INDEX
????????????? * SELECT ... ORDER BY
????????????? * SELECT ... DISTINCT
????????????? * SELECT ... GROUP BY
????????????? * SELECT ... UNION????????????? #聯集
????????????? * SELECT ... INTERSECT?????? # 交集
????????????? * SELECT ... MINUS????????????? #差集,? 即是存在與第一張表中并且不存在第二表的記錄.
有些沒用到索引的連接或關聯子查詢也會需要用到temporary segment. 例如, 如果1個查詢含有1個DISTINCT條件,1個GROUP BY 和 1個ORDER BY , Oracle可能會需要多達兩個Temporary segments.
4.3.1 Temporary Segments 是怎樣分配的
Oracle會按照各需求分配各種不同的Temporary segment.
這一小小節 包含如下兩個topics
? ? ? ? ? ? ? ? * 為查詢分配Temporary segments
? ? ? ? ? ? ? ? * 為臨時表和索引分配Temporary segments. ???????????????
4.3.1.1 為查詢分配Temporary segments
當用戶在1個會話(session)期間內執行SQL語句, 若需要,Oralce 在其中1個臨時表空間按需分配Temporary segments. 用戶可以在CREATE USER or ALTER USER 語句中使用 Temporary Tablespace 來指定該用戶所使用的臨時表空間.
??????????????????????????? ---------------------------------------------------------------------
??????????????????????????? 注:你不能分配1個永久性表空間作為1個用戶的臨時表空間.
?????????????????? 該屬性存放在 user_tablespaces 的 CONTENTS列中.
??????????????????????????? ---------------------------------------------------------------------????????????
如果沒有為用戶指定1個臨時表空間,那么用戶的臨時表空間就是系統的臨時表空間(TEMP).? 表空間的默認存儲特征(characteristics)決定了其temporary segments內的extents的存儲特征.? 當用戶執行完sql語句, oracle會移除掉對應temporary segments.
因為對temporary segments的分配和回收相當頻繁, 為那些temporary segments創建至少1個特別表空間,可以分散對磁盤的讀寫, 也可以避免在SYSTEM或其他存有temporary segments表空間因為這個原因產生的碎片.
???????????????????????????
? ? ? ? ? ? ? ? ? ? ? ? ? ?? ---------------------------------------------------------------------
??????????????????????????? 注:SYSTEM 表空間(名字為SYSTEM)是本地管理類型, 用戶創建1個數據庫時必須定義
?????????????????????????????????? 1個臨時表空間. 1個本地管理類型的SYSTEM表空間不能被作為默認的臨時存表空間.
??????????????????????????? ---------------------------------------------------------------------????????????
用于排序而對temporary segment的改動不會被寫入redo log(重做日志), 除非是對temporay segment做關于空間管理的操作.
4.3.1.2 為臨時表和索引分配Temporary segments
當用戶執行對臨時表的第一條insert into語句(這個可以是1個由CREATE TABLE AS SELECT 語句引起內部insert操作)時,Oracle 就會為其分配1個temporary segment.? 當第一個INSERT 執行時, Oracle為其對于的臨時表和索引分配 segments, 同時創建root page 和所有的LOB segments.
用于臨時表的segments被分配于表臨時表創建者的臨時表空間中.
對于事務創建(transaction-specific)的臨時表, oracle會在事務結束時移除其temporary segments. 對于會話創建的臨時表(session-specific) , 其temporary segments則會在會話結束時被移除. 如果其他事務活會話也用到那張臨時表,則那些segments 仍然保留該臨時表的數據.
4.4 Undo Segments 介紹 和 Automatic Undo Management (回滾段與自動撤銷管理)
Oracle 維護著對數據庫撤銷改動的信息. 這些信息由事務動作的記錄構成, 這就被共同認為是Undo. Undo 存放在Undo 表空間
的undo segments中. Oracle 利用Undo信息去做下列的操作.
????????????? * 回滾1個活動的事務(active transaction)
????????????? * 回復1個被中止的事務(terminated transaction)? #按我的理解這里不是指執行完的事物.而是掛掉的事務.
????????????? * 提供一致性讀 (Provide read consistency)
????????????? * 修復邏輯錯誤 (Recovery from logical corruptions)
截圖是我自己截的Undo 表空間和臨時表空間
當1個Rollback語句被提交時, Undo 的記錄就會被用來回滾由未提交事務造成的數據庫改動.? 而當在數據庫修復時,Undo的記錄是用來回滾 從重做日志(redo log)到數據文件的任何未提交的改動. 當個1個用戶訪問正在被其他用戶修改的數據時, Undo記錄通過維護這個用戶的前映像(before Image)來提供讀一致性. 可以查閱這篇文章得到更多信息"Oracle怎樣管理數據的并發性和一致性".
????????????????????????????? -----------------------------------------------------------------------------
???????????????????????????? 前映象? -- Before Image
????????????????????????????? 對表進行insert,update,delete時候,另外一個session仍然可以從Orace回滾段或者
???????????????????????????? 還原表空間中讀取該表的前映象(before image), 所以Oracle同一時刻不同的session
???????????????????????????? 有讀不一致的現象。
???????????????????????????? -----------------------------------------------------------------------------
Oracle 提供1個全自動的機制, 被成為自動撤銷管理(Automatic undo management),用來管理Undo的信息和空間. 在這中管理模式下,所有當前的sessions, 這個服務會自動管理undo 表空間內的undo segments和space.
自動撤銷管理會消除管理 rollback segment空間的復雜度. 此外,對于用于滿足長時間執行的查詢可能用到的undo 信息.這個系統會為其自我調整來提供盡可能好的撤銷周期(retention). 自動撤銷管理被默認用戶新安裝的oracle數據庫, 數據哭安裝進程會自動創建1個undo 表空間.
oracle包含1個Undo 顧問, 會提供自動建立用戶Undo 環境的幫助和建議.
這一節包含如下topics:
????????????? * 手動撤銷管理
????????????? * Undo 限額 (undo Quata)
????????????? * 自動 撤銷周期 (Auto Undo Retenion)
4.4.1 手動撤銷管理
1個數據庫系統可以運行在手動撤銷管理模式下. 在這個模式下,undo 空間通過roollback segments來管理, 而不會用到undo 表空間.
早期版本的oracle默認設定手動撤銷管理模式. 若要改成自動撤銷管理模式, 用戶必須首先創建1個Undo 表空間,然后修改1個初始化參數. 如果你的oracle數據庫版本是9i或者更后, 而你想將其改為自動撤銷管理模式,請參閱
Oracle升級指南
??????????????? -----------------------------------------------------------------------------------
??????????????? 注:
??????????????? rollback segment的空間管理相當復雜, Oracle強烈建議你使用自動撤銷管理模式.
?????????????? ------------------------------------------------------------------------------------
4.4.2 Undo 限額 (undo Quata)
在自動撤銷管理模式下, 系統會專門控制事務到undo segments的分配, 還會控制undo segments的空間分配. 1個出問題的事務可能會消耗相當打的undo空間, 而導致整個系統癱瘓. 資源管理制定 UNOD_POOL 對大事務來說是1個更直觀管理方式, 他會讓DBA對用用戶進行分組,每一組都有不同的最大undo 空間限制. 當1個用戶組已經消耗的undo空間已經到達上限, 這個組內的用戶就不能做進一步的更新動作, 直到該組其他用戶完成了部分事務而釋放出占用的Undo空間.
UNDO_POOL的默認值是 無限制 的, 所以用戶默認被允許使用undo 表空間內的所有undo 空間. DBA 可以制定1個用戶UNDO_POOL設定限制.
4.4.3 自動撤銷周期 (Auto Undo Retenion)
當一個事務被提交之后, 就不再需要Undo數據去回滾或者修復事務了. 盡管這樣, 為了一致性讀的目的, 長時間執行的查詢可能會用到就的undo信息去制造Data blocks的舊映像. 此外, 若干Oracle閃回(oracle閃回技術介紹)特性是否成功, 也取決于舊undo信息的可用性. 由于這些原因,? 盡量保存舊的undo信息就相當重要了. 如果其undo 表空間還存有足夠的空間被新事務使用,那么舊的undo數據就可以被保留. 當可用空間變少, 數據庫會開始覆蓋那些被提交事務的undo信息.
Oracle會為當前undo 表空間自動調整系統來提供盡可能好的撤銷周期(retention), 數據庫收集用戶使用統計信息, 同時會根據這些信息和Undo表空間的大小來調整undo撤銷周期. 如果該undo 表空間 被設定為 AUTOEXTEND option(自動擴展)而沒有設定最大size.? undo retention 的調整會有些不同. 再這種情況下, 數據會調整自動撤銷周期,使其略長于 最系統的最長查詢時間所需, 如果空間允許的話...
終于翻譯完了,真長啊 淚奔~
?? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ??
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
原文:
docs.oracle.com/cd/B28359_01/server.111/b28318/logical.htm#i8531
這一章描述了Oracle數據庫存儲結構的邏輯,性質和聯系。包含了下列概要:1.Data Blocks, Extents, 和Segments的介紹2.Data Blocks 的概述3.Extents 的概述4.Segments 的概述
1.Data Blocks, Extents, 和Segments的介紹Oracle為數據中所有數據都分配對應的邏輯空間, 而邏輯空間的單位就包括Data Blocks, entents, and Segments.圖例2.1 描述了它們之間的關系
作為最小存儲單元, oracle會將數據存入Data blocks中(數據塊,也有人稱為 logical blocks, Oracle blocks 或pages), 1個Data blocks 對應1個指定大小的字節數(block size 通常在創建數據庫時指定)的硬盤物理空間。也就說每個data block 大小都是一樣的,上圖中是2kb.
上一層的存儲單位叫Extents(中文名一般叫區), 1個 extents 通常是一定數量的相鄰的data blocks 組成, 用于存放指定類型的數據。?
再上一層的存儲單位就叫做Segments了(段), ?1個Segments 是有一組extents組成的,而對應每1個extent都被分配存放指定的數據類型,而且它們都在同1個表空間中。例如,每1個table 都存儲在它自己的data segment中(數據段), 而每1個index 都存儲在它自己的index?segement?中(索引段).如果表或索引是分區(partitioned)存儲的,那么對應每1個分區會擁有自己的segment.
每個Segement 和它包含的extents都只能存放在1個表空間(table space)中, ?如果表空間包含若干個數據文件(data file). 那么1個Segement 是可以包含存放在不同數據文件的extents的。 也就是說,segement是可以跨數據文件存儲的,而extents只能放在1個數據文件中。
雖然你可以額外添加1個extent, 但它的blocks未必會同時分配,如果你將1個extent分配到1個指定的實例(數據庫對象)中,那么它的blocks會馬上分配并加到可用塊列表中(free list). ?然而如果你不是將1個extent 分配到指定實例中的話,那么它的block只會等到高水位線(high water mark)移動時才分配。高水位線是1個segment中已用和未用空間的界限。
2.Data Blocks 的概述在Oracle的存儲空間管理中, 1個數據庫的數據文件內的存儲單位叫Data blocks, 1個Data block 是數據庫中最小的數據存儲單位。然而,所有數據在操作系統中的物理存儲單位是字節(byte). 每1個操作系統都有它自定義的塊大小(block size). Oracle會將數據存放在oracle自定義的data blocks中, 而不是操作系統本身的系統塊(blocks).
Oracle標準Block size 是由數據庫初始參數DB_BLOCK_SIZE指定的。除此之外,你還可以指定最多5個非標準的Block size, 你應該將oracle Block size 設成操作系統Block size的倍數, 以最大限度地避免多余的I/O。Oracle data blocks 是oralce可以使用和分配的最小的存儲單位/
2.1 Data Block 的結構。Oracle數據庫的Data blocks的結構是類似的。不論它們存放的是table,index或者clustered data(簇表)。圖例2.2 表示了data block的結構。
這一小節我們討論下面這些Data Block的組成部分.
2.1.1 數據塊頭(含標準內容與可變內容)??????????????????????? #Header(Common and Variable)? ??
2.1.2 表目錄區 ????????????????????????????????????????????????????????????? #Table Directory
2.1.3 行目錄區 ????????????????????????????????????????????????????????????? #Row Directory
2.1.4 頭部信息 ????????????????????????????????????????????????????????????? #OverHead
2.1.5 行數據區?????????????????????????????????????????????????????????????? #Row Data
2.1.6 可用空間區 ????????????????????????????????????????????????????????????? #Free Space
2.1.1 數據塊頭(含標準內容和可變內容)
數據塊頭包含基本的Data Block信息,例如Block的地址和所屬段的類型.(例如,數據段\索引段)
2.1.2 表目錄區
這部分包含Data Block中的數據行所屬表的信息.
2.1.3 行目錄區
這部分包含Data Block中的數據行的信息.(每一條數據行(或數據行的一部分)的地址).
注: 1個data block可能包含一條或多條完整的數據行,或者一條數據行的一部分.
當數據塊行目錄被分配后,即使對應數據行被刪除,這部分空間也不會被回收. 例如,1個數據塊曾經包含多達50條數據,但被清空后,行目錄區人仍然保留100 bytes的行目錄數據. 只有當有新的數據行被插入的這個Data Blocks, Oralce才會對該行目錄空間重新分配利用.
2.1.4 頭部信息
數據塊頭,表目錄區,行目錄區被共同地成為頭部信息.? 有些Data block的頭部信息是固定大小的. 而頭部信息的總大小是可變的(也就是說有寫是可變的).平均來講, 頭部信息的固定和可變部分總共為84-107 bytes.
2.1.5 行數據區
這部分包含數據表或索引的內容, 數據行可以跨Data Blocks存儲.
2.1.6 可用空間區
可用空間是預留給新數據行的插入或者現有數據行的更改(例如將1個Null值改為1個非Null值)
如果1個Data Blocks是屬于Data segment存放表數據, 或 Index segement而存放索引數據。那么它的可用空間還會存放transaction entry(事務條目),在每一次對數據塊中的一行或多行進行 insert/update/delete 和select.. for update操作時,可用空間就需要存放一條transaction entry. transaction entries的所需空間取決于擦作系統,在大部分操作系統里是23 bytes左右。
2.2 可用空間管理
可用空間可以由系統自動管理或者手動管理。
數據庫 segments 里面的可用空間可以被系統自動管理, segment 內的可用/已用空間用Bitmap形式記錄(tracked using bitmap), 與用列表(free list)管理不同,segment 空間自動管理具有如下優點:
????? * 易與使用
????? * 更優秀的空間利用率,特別是對于那些每行數據大小差異大的對象來說。
????? * 對并行訪問情況變化進行更好的實時調整。
????? * 多實例運行時,有更優秀的性能和空間利用率。(Better multi-instance behavior in terms of performance/space utilization)
當用戶創建1個本地管理的表空間時,可以設定自動segment空間管理。這個設定會應用到這個表空間創建的segment.
2.2.1 Data block 中可用空間的有效性和優化
有兩種操作語句可以為1個或多個Data blocks增加可用空間:? 分別是Delete語句和某些Update語句(將已存在的值更新為占更小空間安的值). 釋放出的空間有隨后符合以下兩個條件的insert語句所使用。
???????? * 如果insert語句在釋放空間的語句之后,而且和釋放空間的語句在同1個事務內,那么這些insert語句可以使用釋放出來的空間。
???????? * 如果insert語句和釋放空間的語句在不同的事務中(或者由不同的用戶提交),那么只有當釋放語句的事務提交之后,且insert語句必須使用這些釋放空間,? 這些釋放空間才會被Insert語句所使用。
在1個Data Block中,loin987z空間相鄰, Oralce只會遇到下列兩種情況才會合并可用空間。
1)inert或update語句選中1個足夠存放新數據的可用空間。
2) 本身可用空間過于分散,數據無法寫入1個連續的可用空間里。
Oracle之所以在這些情況才會做合并可用空間的動作。是因為頻繁進行合并動作進性時會影響數據性能。
2.2.2 行鏈接和行遷移 Row Chaining and Migrating
有兩種情況會導致1個數據行太大,不能放入1單個Data Block中.? 第一種情況,當一個數據行在第一次插入數據庫時就由于本身size太大而不能全部放入1個Data Block中,在此情況下,Oralce會將這個數據行存放在由1個Segment中的一組Data Blocks組成的鏈接(chain)中。行鏈接的形成大部分是由于大容量的數據行,例如數據行中有類型是LONG 或 LONG,在這情況下行鏈接是不可避免的。(除非加大Block Size).
然而,第二種情況是,有1個數據行原本已經完全存放在1個Data Block中, 但是由于Update動作, 數據行的總大小變大了。 而那個數據的可用空間此時已被占滿(可能由其他數據行占滿)。 在這種情況下,oracle會將這條數據行遷移(migrate)到(整條)到1個新的Data Block中。Oracle會在舊Data block中數據行原位置保存1個指針指向那個新的Data Block。 原rowid 保持不變。
當行遷移或行鏈接發生時,對有關于這個一行的I/O性能會下將, 因為數據庫必須掃描額外的Data Block來檢索數據行的全部信息。
?
2.2.2 PCTFREE, PCTUSED, and Row Chainning?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? -- Pctfree, pctused 和 行鏈接
下面這小part是我自己添加的
======================================================
Segment 管理方式有兩種:(管理Block)
1 MSSM(Manual Segment Space Management)
2 ASSM(Auto Systemt Space Management)
1 MSSM(Manual Segment Space Management)
通過在segment的段頭分配自由列表(freelist) 來管理block
通過兩個參數 pctfree pctused來管理block如何進出freelist
pctfree 值表示預留多少%的block空間用于更新
pctused 值表示低于這個值是,block會重新加入到freelist上
通過dba_tables,dba_indexes查看freelist,pctfree,pctused等參數的設置
2 ASSM(Auto Systemt Space Management)
通過在segment的段頭分配位圖(bitmap) 來管理block
不再需要freelist
不在需要pctused,因為不需要從freelist上摘除block。
可以在user_tablespaces 這個視圖查看Segment_Space_Management 列,
獲得模式類型。
======================================================
在手動管理(MSSM)的表空間中,有兩個空間管理參數, PCTFREE 和 PCTUSED,允許用戶通過這兩個參數在某1個segment中進行insert 和 update操作時,對該segment 中所有data blocks的可用空間進行管理。用戶可以在創建或修改一張數據表或簇表(有屬于自己的segment)時設定這兩個參數,用戶也可以在創建或修改index(有屬于自己的segment) 時指定數據存儲參數(Storege paramter) PCTFREE 。
df
下面包含下列內容.
??????????? * PCTFREE 參數
??????????? * PCTUSED 參數
??????????? * PCTFREE和PCTUSED 是怎么一起工作的
??????????? ------------------------------------------------------------------------------------------
?????????????? 注:我們討論的范疇不包括LOB 數據類型(BLOB,CLOB,NCLOB和BFILE),它們不會使用PCTFREE參數
?????????????????? 或free list(可用塊列表).
?
2.2.3 PCTFREE 參數
用戶可以用PCTFREE 參數來設置Data Block中預留給update操作的可用空間百分比,用來為已存在數據的長度增長做準備。
例如, 假如你執行Create table語句時加入這1個參數
PCTFREE 20
這樣就聲明了,在這個表(表空間的對應segment)中的每1個Data blocks中, 會保留20%的可用空間預留給Update操作造成的數據長度增長,新的數據行會存儲入Row Data Area, 而相應的信息會存儲入Overhead Area(2.1.4 頭部信息)的可變部分,直到Row data和overhead的總容量達到Data block容量的80%.
圖例2.3 闡明了PCTFREE的作用:
?
2.2.4 PCTUSED 參數
PCTUSED 設置了1個最小百分比,當Data Blocks的已用空間(row data + overhead)占總空間的比率小于PCTUSED時,才允許新數據行插入到這個Data Block中。 當Data block的已用空間到達PCTFREE的限制時, Oralce 就不允許新數據行的插入,直到已用空間的比率下降到PCTUSED設定的比率. 否則Oracle只會用那些可用空間提供給已存在數據行的update操作。
例如,當你創建1個數據表同時指定如下參數
PCTUSED 40
這個表(表空間的對應segment)中的每1個Data blocks中, 除非已用空間比率在39%或者更低(假設那個Data block的可用空間曾經下降到達PCTFREE的限制)。
?
2.2.5 PCTFREE 和 PCTUSED 共同起作用的
在1個segmenet中,PCTFREE 和 PCTUSED 會共同作用以優化Data blocks的空間使用。
圖例2-5 顯示了這個兩個參數的相互作用。
?
圖1:數據行能一直插入值到已用空間到達80%, 這是因為PCTFREE 設定要保留20%的可用空間預留給已存在行的Update操作。
圖2: 更新造成的數據長度增長會占用這些保留的空間,新的數據行不允許插入,值到已用空間降到(更新或刪除)39%或更低。
圖3:當已用空間降到40%以下時,新數據行又可以插入到這個Data Block中了。
圖4:數據行能一直插入值到已用空間到達80%, ..這個邏輯一直循環下去。
在1個新使用的Data block中,數據行Insert的操作可以使用的空間是Data Blocks總空間 減去 頭部信息和PCTFREE的和。而update已存在數據行的操作能使用Data block中任何可用空間,因此update操作一樣有機會令可用空間減少低于PCTFREE的限制,PCTFREE保留的空間是為了Update操作準備的,而不是Insert。
對于每1個數據和索引Segment,oracle都會維護一個或多個Free List -- 分配給該Segment的數據區(extends),而且可用空間大于PCTFREE的Data Blocks列表. 這些Data Block可以被插入新數據行. 當你提交一條insert語句,Oralce就會檢查Free List中的第1個Data Block,如果它是可用的,就會使用它。 若它的可用空間不足以容納那條insert語句,而且該Data Block的可用空間已經超過PCTUSED(如上圖,例如已用41%,超出PCTUSED的40%),ORACLE就會將該Data Block移出Free List.1個segment里允許有多個Free list,這樣減少了并發Insert操作時對單個Free list的爭用。
當用戶提交1個Delete或update操作,Oracle就會執行這些語句然后會檢查對應Data Blocks中的已用空間是否已經低于PCTUSED,如果是,則將Data Block則進入Free list成為該事務第首個可以使用的Data Block。當對應事務被提交,該Data Block 可以被其他事務使用。
3 Extents概述? (overview of extents)
1個Extent 就是數據庫中由1組連續的Data Blocks組成的存儲邏輯單位. 1個或多個Extents組成1個Segment,當1個Segment中的extents被用完,oracle會分配新的extend給該segment.
這一節包含如下內容:
??? * Extents何時被分配
??? * Extents數量和大小的決定
??? * Extents怎樣被分配
??? * Extents何時被回收
3.1 Extents 何時被分配
當你創建1張表時,Oralce會為哪張表的segment分配1個有一組指定數量Data blocks組成的initial extent(初始區), 即使當時還沒有數據行插入,那些相應的Data Blocks還是會預留為那張表的數據行使用.
如果上面的initial extent的空間用完了,而且需要更多的空間來裝在表數據,那么oracle就會分配1個incremental extent(增加的區),1個incremental extent是1個后續的extent,容量大于或等于該表segment中之前的extents.
出于方便維護的目的,每個segment中頭1個Data block會存儲該segment中的地址信息。
?????????????? -------------------------------------------------------------------------------------------------------------------
???????????????注:這一章使用于Serial operations(串行操作,也就是1個1個來的意思),即是
那些之有1個服務進程,運行1條sql語句的操作。 對于那些被多個服務進程并發執行
的sql語句(parallel SQL statements),entents的分配會有點不同。
?????????????? -------------------------------------------------------------------------------------------------------------------
??????????
3.2 Extents數量和大小的決定
每個segment中,Storage paramter(存儲參數)可以表示出extends的定義。Storage Parameter適用于所有類型的segments. 它們可哦就控制了oracle應該怎樣分配數據庫可用空間給1個segment. 例如你可以在執行Create table 語句時使用Storage 字句來指定segment中初始預留空間的大小,也可以限制分配給segment的extents數量。如果你沒有指定Storage paramter, 那么系統會使用表空間的默認Storage parameter.
用戶可以使用由數據字典(dictionary)來管理的表空間,那些表空間會依賴數據字典來監控空間利用情況,也可以使用本地管理(locally managerd)的表空間, 那些表空間會用位圖(bitmap)來標記已用空間(而不是用數據字典)。因為本地管理方式有更好的性能而且更容易管理,所以當用戶沒有指定extent的管理方式時,除了System的永久表空間(permanent tablespaces)默認使用本地管理方式。
?????????? 注:上述管理類型可以在user_tablespaces 中的 extent_management 列查詢.
1個本地管理模式的表空間的extends要么是固定大小的(所有extends的size是一致的),要么是由系統自動決定大小而且大小非固定的。當你創建1個表空間,UNIFORM 和 AUTOALLOCATE(系同管理)子句可用來決定分配類型。
????????? * 對于固定大小的extends, 你可以指定1個值或者使用默認的size,默認是1MB,
要確保每1個extends至少含有5個Data blocks 的大小, 本地管理的
臨時表空間(Temporary tablespaces)只能使用這種分配方式(固定大小)。
??
????????? * 對于系統自動管理的extends, oracle自己會為additional extents決定最優的size,
而1個extends的size的最小值是64kb. 如果一張表空間創建時包含字句
"segment space management auto", 而且數據庫的
Block size大于等于16KB,那么oracle在使對應的segment創建最小值
為1MB 的extends. 上面所說的是永久性表空間的默認值。
在本地管理方式的表空間中,存儲參數 INITIAL,NEXT,PCTINCREASE和MINEXTENTS不能被設定于表空間這一層,但是,他們可以在segment這個層面上設定。在這種情況下,INITIAL,NEXT,PCTINCREASE和MINEXTENTS這4個參數會一起計算segment的初始大小值。segment的初始大小值計算完后, 隨后內部算法會決定segment里每1個extents的大小。
3.3 Extents怎樣被分配.
Oracle使用不同的算法去分配Extents, 取決于他們是數據字典管理類型還是本地管理類型的。
在本地管理類型的表空間中,oracle為了給1個新分配的extent尋找可用空間,會首先選中表空間的1個候選的Data file(數據文件),然后會檢查這個datafile的bitmap,尋找所需數量連續的Data blocks. 若該datafile里沒有足夠的連續空間,則會選擇另1個datafile繼續查找。
????????? 注:Oracle強烈建議你使用本地管理類型的表空間。
3.4 Extents何時被回收
Oracle提供1個Segment Advisor(顧問)工具, 會基于1個對象內的空間碎片,幫助你了解該對象內是否有空間可以用來回收再利用。
通常,1個segment內的extends不會返回表空間中,除非你刪除存放在該segment的數據庫對象(使用Drop table 或 Drop cluster語句)。
但是下面的情況是例外:
?
????? * 一張table或cluster的owner,或者1個擁有Delete任何東西權限的user,可以
????? 截斷(truncate)1張table或cluster(使用TRUNCATE...DROP STORAGE語句)
????? * 1個數據庫管理員(DBA) 可以通過下面的SQL語句來回收未使用的extents. Orz..
??????? ALTER TABLE table_name DEALLOCATE UNUSED;
????? * Orace會定期從1個回滾段(rollback segment)回收1個或多個extents.
? ? ? ? 前提是那個segment的參數OPTIMAL size已被設定
???
當extends被釋放,Oracle會修改相應datafile 的Bitmap(for 本地管理類型表空間),或者修改相應datafile的dictionary(for 數據字典管理類型的表空間)來表明被回收的extents是可用的. extends內任何Data blocks內的數據會被釋放,從而extends也不能被訪問。
這一節包含以下topics:
???????
????? * 非簇表的extends???? #extends in Nonclustered Tables
????? * 簇表的extends??????? #extends in Clustered Tables
????? * 具體視圖及其日志中的extends? #extents in Materialized Views and Their Logs
????? * 索引中的extent
????? * Temporary Segments 中的 extents
????? * Rollback Segments 中的 extents
3.4.1 非簇表的extents???? #extends in Nonclusterd Tables
只要1張表還存在于數據庫中,那么分配給該表的segment的Data blocks會一直保留在那,除非這張表被trancate了。若1個data block還有可用空間,oracle會將新數據行插到它里面。即使你用把該表的所有行都Delete了, oracle也不回收該表的data blocks 而用于表空間的其他對象。
當你把這張表drop掉之后,當別的extents需要新空間時會回收原本該表的空間。 ---- oracle 會回收這張表的data segments 和 index segments里所有的extents, 并供同一個表空間內的其他方案對象(schema objects)使用。
在數據字典管理類型的表空間中,當1個segment所需的extents長度大于可用的extents長度時,oracle會尋找并將回收的extents合拼成1個大的連續extent. ?這就是extents合拼(coalescing). extents 合拼在本地管理類型(locally managed tablespace)的表空間中并不是必需的,因為所有連續空間都能被分配給1個新的extent, 而不管這些空間是不是從1個或多個extents中回收的.
3.4.2 簇表的extents???? #extends in Clusterd Tables
簇表的數據存放在專門的為簇而建立的segment中. 所以當你drop掉簇里的1張表, 對應的segment就會預留給簇里的另一張表,沒有任何extents被回收. 你亦都可以truncate 簇(除了哈希簇)來釋放extents.
3.4.3 具體視圖及其日志中的extends? #extents in Materialized Views and Their LogsOralce回收具體尸體及其日志中的extents的方式是和表和簇的方式一樣的.
3.4.4 索引中的extent
只要1個index 還存在,oracle都會為其保留住分配給它的index segement. 當你drop掉這個index 或者對應的表或簇, oralce 會回收這些extents, 分配給對應的表空間用于其他地方.
3.4.5 Temporary Segments(臨時段) 中的 extents
當oracle執行完1個用到temporary Segment的語句時, Oracle會自動drop掉那個temporary segment, 并收回里面的extents給對應的表空間.
當用戶執行1個單一排序(single sort)語句時,會在1個temporary tablespace(臨時表空間) 建立自己的temporary segments , 執行完后會釋放那些extents到表空間中.
但是在Multiple sorts(多重排序)中, 可使用temporary tablespaces中專門指定給排序用的segments. 這些sort segments 對于那個instance(實例)只能分配1次, 排序之后它們不會被回收, 但是為會被其他Multiple sorts排序.
1張臨時表里的temporary segment 可以含有1個trancaction(事務)或session(會話)的多條SQL語句的數據. 當事務或會話結束后oracle會drop那個temporary segment,并回收其中的extents給對應的表空間.
3.4.5 Rollback Segments(回滾段) 中的 extents
Oracle會定期檢查數據庫中的Rollback segments, 看看它們是否已經超過了最佳的大小(optimal size),如果1個Rollback Segment的size超過了optimal size(也就是說里面有太多extents了), 那么oracle會自動回收它里面的1個或多個extents.
4 Segment概述? (overview of Segment)
1個segments 就是在表空間內由一些包含所有特定邏輯結構的extents組成的存儲結構. 例如, 對于每一張表, oracle會分配1個或多個extents形成該表的Data segment,? 而對于每1個index, oracle會分配1個或多個extents形成該index的index segment.
這一章節包含如下topics:
????????
?????????? * Data Segments 介紹
?????????? * Index Segments 介紹
?????????? * Temporary Segments 介紹
?????????? * Undo Segments 介紹 和 Automatic Undo Management
???
4.1 Data Segments 介紹
Oracle中1個Data Segment 包含下列對象的所有數據.
?????????? * 1張table, 而它不是分區表且不是簇表.
?????????? * 1張分區表里面的1個分區
?????????? * 1個簇(含多張表)
當你執行創建1張table 或 cluster的語句時Oracle就會為其創建對應的Data segment.
表或簇的存儲參數決定了對應的Data segment的 extents 是怎樣分配的. 用戶可以直接在Create 或 Alter 語句中設定這些存儲參數. 這些參數會影響其Data segment中數據檢索和存儲的效率.
???????????????????????????? ---------------------------------------------------------------------
??????????????????????????? 注:Oracle為物化視圖(materialized view)創建segment的方式是和tables和cluster
?????????????????? 一樣的.
??????????????????????????? ---------------------------------------------------------------------
4.2 Index Segments 介紹
對于1個非分區索引,oracle會存有1個對應的index segment來存放它的所有數據,對于1個分區的索引,每個分區都有1個對應的index segment存放它的數據.
當用戶執行創建索引的語句時,oracle會為該索引或索引分區建立Index segment. 用戶可以指定index segment的extents的存儲參數 和指定創建index segment的表空間.(1張表和它的索引可以使用不同的表空間).這些參數會影響其Data segment中數據檢索和存儲的效率.
4.3 Temporary Segments 介紹
當用戶執行查詢時, Oracle通常要為Sql語句的分析和執行的中間階段(intermediate stages)準備臨時空間. Oralce會自動分配這些硬盤空間并稱之為Temporary Segment. 例如, Oracle 需要1個Temporary Segment用于排序的數據庫空間. 如果該排序操作可以在內存內完成或者oracle找到另1中使用索引去排序的方法, 則oracle不會創建Temporary segment.
這一小節包含如下topics:
????????????? * 需要 Temporary Segments的操作
????????????? * 臨時表和他們的索引的Segments.
????????????? * Temporary segments 是怎樣分配的.
4.3.1 需要Temporary Segments的操作
下列語句有時會需要用到Temporary segments:
???????????
????????????? * CREATE INDEX
????????????? * SELECT ... ORDER BY
????????????? * SELECT ... DISTINCT
????????????? * SELECT ... GROUP BY
????????????? * SELECT ... UNION????????????? #聯集
????????????? * SELECT ... INTERSECT?????? # 交集
????????????? * SELECT ... MINUS????????????? #差集,? 即是存在與第一張表中并且不存在第二表的記錄.
有些沒用到索引的連接或關聯子查詢也會需要用到temporary segment. 例如, 如果1個查詢含有1個DISTINCT條件,1個GROUP BY 和 1個ORDER BY , Oracle可能會需要多達兩個Temporary segments.
4.3.1 Temporary Segments 是怎樣分配的
Oracle會按照各需求分配各種不同的Temporary segment.
這一小小節 包含如下兩個topics
? ? ? ? ? ? ? ? * 為查詢分配Temporary segments
? ? ? ? ? ? ? ? * 為臨時表和索引分配Temporary segments. ???????????????
4.3.1.1 為查詢分配Temporary segments
當用戶在1個會話(session)期間內執行SQL語句, 若需要,Oralce 在其中1個臨時表空間按需分配Temporary segments. 用戶可以在CREATE USER or ALTER USER 語句中使用 Temporary Tablespace 來指定該用戶所使用的臨時表空間.
??????????????????????????? ---------------------------------------------------------------------
??????????????????????????? 注:你不能分配1個永久性表空間作為1個用戶的臨時表空間.
?????????????????? 該屬性存放在 user_tablespaces 的 CONTENTS列中.
??????????????????????????? ---------------------------------------------------------------------????????????
如果沒有為用戶指定1個臨時表空間,那么用戶的臨時表空間就是系統的臨時表空間(TEMP).? 表空間的默認存儲特征(characteristics)決定了其temporary segments內的extents的存儲特征.? 當用戶執行完sql語句, oracle會移除掉對應temporary segments.
因為對temporary segments的分配和回收相當頻繁, 為那些temporary segments創建至少1個特別表空間,可以分散對磁盤的讀寫, 也可以避免在SYSTEM或其他存有temporary segments表空間因為這個原因產生的碎片.
???????????????????????????
? ? ? ? ? ? ? ? ? ? ? ? ? ?? ---------------------------------------------------------------------
??????????????????????????? 注:SYSTEM 表空間(名字為SYSTEM)是本地管理類型, 用戶創建1個數據庫時必須定義
?????????????????????????????????? 1個臨時表空間. 1個本地管理類型的SYSTEM表空間不能被作為默認的臨時存表空間.
??????????????????????????? ---------------------------------------------------------------------????????????
用于排序而對temporary segment的改動不會被寫入redo log(重做日志), 除非是對temporay segment做關于空間管理的操作.
4.3.1.2 為臨時表和索引分配Temporary segments
當用戶執行對臨時表的第一條insert into語句(這個可以是1個由CREATE TABLE AS SELECT 語句引起內部insert操作)時,Oracle 就會為其分配1個temporary segment.? 當第一個INSERT 執行時, Oracle為其對于的臨時表和索引分配 segments, 同時創建root page 和所有的LOB segments.
用于臨時表的segments被分配于表臨時表創建者的臨時表空間中.
對于事務創建(transaction-specific)的臨時表, oracle會在事務結束時移除其temporary segments. 對于會話創建的臨時表(session-specific) , 其temporary segments則會在會話結束時被移除. 如果其他事務活會話也用到那張臨時表,則那些segments 仍然保留該臨時表的數據.
4.4 Undo Segments 介紹 和 Automatic Undo Management (回滾段與自動撤銷管理)
Oracle 維護著對數據庫撤銷改動的信息. 這些信息由事務動作的記錄構成, 這就被共同認為是Undo. Undo 存放在Undo 表空間
的undo segments中. Oracle 利用Undo信息去做下列的操作.
????????????? * 回滾1個活動的事務(active transaction)
????????????? * 回復1個被中止的事務(terminated transaction)? #按我的理解這里不是指執行完的事物.而是掛掉的事務.
????????????? * 提供一致性讀 (Provide read consistency)
????????????? * 修復邏輯錯誤 (Recovery from logical corruptions)
截圖是我自己截的Undo 表空間和臨時表空間
當1個Rollback語句被提交時, Undo 的記錄就會被用來回滾由未提交事務造成的數據庫改動.? 而當在數據庫修復時,Undo的記錄是用來回滾 從重做日志(redo log)到數據文件的任何未提交的改動. 當個1個用戶訪問正在被其他用戶修改的數據時, Undo記錄通過維護這個用戶的前映像(before Image)來提供讀一致性. 可以查閱這篇文章得到更多信息"Oracle怎樣管理數據的并發性和一致性".
????????????????????????????? -----------------------------------------------------------------------------
???????????????????????????? 前映象? -- Before Image
????????????????????????????? 對表進行insert,update,delete時候,另外一個session仍然可以從Orace回滾段或者
???????????????????????????? 還原表空間中讀取該表的前映象(before image), 所以Oracle同一時刻不同的session
???????????????????????????? 有讀不一致的現象。
???????????????????????????? -----------------------------------------------------------------------------
Oracle 提供1個全自動的機制, 被成為自動撤銷管理(Automatic undo management),用來管理Undo的信息和空間. 在這中管理模式下,所有當前的sessions, 這個服務會自動管理undo 表空間內的undo segments和space.
自動撤銷管理會消除管理 rollback segment空間的復雜度. 此外,對于用于滿足長時間執行的查詢可能用到的undo 信息.這個系統會為其自我調整來提供盡可能好的撤銷周期(retention). 自動撤銷管理被默認用戶新安裝的oracle數據庫, 數據哭安裝進程會自動創建1個undo 表空間.
oracle包含1個Undo 顧問, 會提供自動建立用戶Undo 環境的幫助和建議.
這一節包含如下topics:
????????????? * 手動撤銷管理
????????????? * Undo 限額 (undo Quata)
????????????? * 自動 撤銷周期 (Auto Undo Retenion)
4.4.1 手動撤銷管理
1個數據庫系統可以運行在手動撤銷管理模式下. 在這個模式下,undo 空間通過roollback segments來管理, 而不會用到undo 表空間.
早期版本的oracle默認設定手動撤銷管理模式. 若要改成自動撤銷管理模式, 用戶必須首先創建1個Undo 表空間,然后修改1個初始化參數. 如果你的oracle數據庫版本是9i或者更后, 而你想將其改為自動撤銷管理模式,請參閱
Oracle升級指南
??????????????? -----------------------------------------------------------------------------------
??????????????? 注:
??????????????? rollback segment的空間管理相當復雜, Oracle強烈建議你使用自動撤銷管理模式.
?????????????? ------------------------------------------------------------------------------------
4.4.2 Undo 限額 (undo Quata)
在自動撤銷管理模式下, 系統會專門控制事務到undo segments的分配, 還會控制undo segments的空間分配. 1個出問題的事務可能會消耗相當打的undo空間, 而導致整個系統癱瘓. 資源管理制定 UNOD_POOL 對大事務來說是1個更直觀管理方式, 他會讓DBA對用用戶進行分組,每一組都有不同的最大undo 空間限制. 當1個用戶組已經消耗的undo空間已經到達上限, 這個組內的用戶就不能做進一步的更新動作, 直到該組其他用戶完成了部分事務而釋放出占用的Undo空間.
UNDO_POOL的默認值是 無限制 的, 所以用戶默認被允許使用undo 表空間內的所有undo 空間. DBA 可以制定1個用戶UNDO_POOL設定限制.
4.4.3 自動撤銷周期 (Auto Undo Retenion)
當一個事務被提交之后, 就不再需要Undo數據去回滾或者修復事務了. 盡管這樣, 為了一致性讀的目的, 長時間執行的查詢可能會用到就的undo信息去制造Data blocks的舊映像. 此外, 若干Oracle閃回(oracle閃回技術介紹)特性是否成功, 也取決于舊undo信息的可用性. 由于這些原因,? 盡量保存舊的undo信息就相當重要了. 如果其undo 表空間還存有足夠的空間被新事務使用,那么舊的undo數據就可以被保留. 當可用空間變少, 數據庫會開始覆蓋那些被提交事務的undo信息.
Oracle會為當前undo 表空間自動調整系統來提供盡可能好的撤銷周期(retention), 數據庫收集用戶使用統計信息, 同時會根據這些信息和Undo表空間的大小來調整undo撤銷周期. 如果該undo 表空間 被設定為 AUTOEXTEND option(自動擴展)而沒有設定最大size.? undo retention 的調整會有些不同. 再這種情況下, 數據會調整自動撤銷周期,使其略長于 最系統的最長查詢時間所需, 如果空間允許的話...
終于翻譯完了,真長啊 淚奔~
?? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ??
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的翻译: Oralce官方文档-- Data Blocks, Extents, and Segments的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转: Oracle 索引详解
- 下一篇: Oracle簇表介绍 (clustere