高水位的影響及大並發插入的效能問題
一、資料區塊的插入時尋找可用塊的規則總結:
高水位與低高水位:低高水位與高水位之間存在的資料區塊的狀態可能是未格式化或格式的。低高水位以下的是格式化了的,可以被使用。
1.首先,插入一條資料,只會使用高水位以下的資料區塊。
高水點的位置:L1塊所包含資料區塊的邊界,要麼是區的邊界
2.第一次插入一行資料,格式化塊數?
並沒有一個一定的數值,從DUMP L1塊中看,有格式化5個,32個64個等。
3.插入一行資料,如何通過L3-->L2-->L1--資料區塊,這個過程來確定插入哪個塊?
在ASSM資料表空間下:一個行在不同會話上是被隨機插入高水位以下的不同的塊。
具體說明如下:
L3選擇L2,不隨機,根據L2 Hint for inserts: 0x01c00081 這一行,確定要選擇的L2。
在L2中,根據PID進行HASH,得到一個隨機值,根據此值選擇L1.--但是這受高水位影響,如果高水位範圍內只有一個區,事實上將只選擇這一個區對應的L1。
在L1中,根據PID進行HASH,得到一個隨機值,根據此值選擇資料區塊。
--實驗時要注意,在同一視窗下,sqlplus快速退出再登陸,使用的是同一SID,所以插入的行會在同一資料區塊。
4.多個會話各自插入一行資料,插入順序?
假設每行插入的資料所需要空間都不超過一個資料區塊:
同一會話向一張表中插入資料,是有序的,並且是插入同一個資料區塊。
如果多個會話向一張表中插入資料,是無序的,並且每個會話插入的資料在不同的資料區塊。
也就是:多個會話的插入是無序的,同一會話下插入有先後順序。讀取資料時,預設按ROWID,升序讀取。
實驗:同一會話插入兩條語句,再開一新會話插入一條,通過DBMS_ROWID查看行所在的資料區塊,會發現同一會話下插入同一塊,不同會話不插入同一塊。太簡單了,沒巾出來。
二、高水位及putfree值設定不當引起的效能問題--熱塊導致buffer busy waits等待事件
插入一條資料,只會使用高水位以下的資料區塊會引起的buffer busy waits效能問題?
首先,高水點的位置:L1塊所包含資料區塊的邊界,要麼是區的邊界。
而一個L1或者一個區所包含的資料區塊的個數是有限的。比如8KB在BLOCK時,系統自動管理區大小時,前16個區只有8個資料區塊,1-64 M時區大小為1M,128個塊。64M以後的區大小是8M,有1024個資料區塊。
在8M的區時,有1024個塊可以用,去除儲存中繼資料的庫,假如有1000個塊可用,此時就是能支援1000個並發插入操作,有更多並行作業的時候,就不可避免的要出現多個會話同時向同一個資料區塊進行操作,此時就出現了熱塊--等待事件buffer busy waits。
1000個並發其實已經很大了,多用在日誌型應用中。
如果並發超過1000個,並且buffer busy waits出現很多,已經影響到系統效能,有一個不太完美的解決方案是:在業務高峰來臨前,在表中大量插入一批資料,推高高水位的位置;然後再刪除資料,此時高水位之前有更多的資料區塊可供插入,就可以支援更高的並發了。
引起buffer busy waits等待事件,還有一種可能就是不合理的PCTFREE值。
因為在ASSM中,在L1中用五種狀態: 75-100% 50-75% 25-50% 0-25% FULL來表示資料區塊的空閑狀態,如果設定的值靠近這個監界值,比如PUTFREE是20%或24%,此時可能對資料區塊中資料進行幾行的插入、更新 或刪除就會導致資料區塊狀態的改變,而資料區塊狀態的改變,L1塊中也要發生相應的改變來記錄資料區塊的狀態。
因為一個L1塊管理多個資料區塊(比如8M區8KB資料區塊時一個L1管理1024個資料區塊),如果一個L1管理的多個資料區塊都要同時更新塊的空間狀態,也會引起L1塊的爭用--熱塊--等待事件buffer busy waits。
這個也能實驗,不過不太好實驗,要用一行資料比較長,配合PCTFREE的值,做到刪除一行和插入一行或幾行,塊狀態就發生變化,此時DUMP L1塊來驗證。
ASSM缺點:
ASSM下資料和索引的順序不一致,導致聚簇因子增大
三、實驗:驗證插入的行預設只能插入到高水位以下的資料區塊
思路:先建表,手動給表分配多個區。使用多個會話,每個會話插入一行資料,順便驗證資料區塊的插入順序
#############################33
BYS@ bys3>create table test11(aa int ,bb varchar2(10));
Table created.
BYS@ bys3>insert into test11 values(99,'first');
1 row created.
BYS@ bys3>commit;
Commit complete.
BYS@ bys3>alter table test11 allocate extent(size 1m);
Table altered.
BYS@ bys3>alter system checkpoint;
System altered.
BYS@ bys3>select header_file,header_block from dba_segments where segment_name='TEST11' and owner='BYS';
HEADER_FILE HEADER_BLOCK
----------- ------------
4 170
#####################