㈠ 單執行個體Oracle locking機制
locking機制的三大組成部分:
① resource structure
Oracle對于每個需要“并發通路”的資源,都在SGA中用一個資料結構來描述它
這個結構叫resource structure
這個資料結構有三個成員:owner、waiter和converter
這是3個指針
指向由lock structure組成的連結清單的指針
其中,converter和waiter有些差別:
如果某個操作先後需要兩種不同模式的鎖,比如,先S,後X,則程序會先請求S,獲得後lock structure會挂在owner上,
當需要X時,進行必須先釋放S,然後再次申請X
但是可能無法立即獲得
這時這個請求會被立即挂在converter下
converter的優先級高于waiter
根據v$lock的lmode和request可以判斷他三:
● lmode > 0,request =0 → owner
● lmode = 0,request >0 → waiter
● lmode > 0,request >0 → converter
② lock structure
每當程序要通路共享資源時,必須先鎖定該資源
鎖定實際就是從SGA中申請一個lock structure
在其中記錄lmode 、PID等
然後看能否立刻獲得該資源的通路權
● 如果能,則把lock structure挂到resource structure的owner連結清單中
● 否則,把這個lock structure挂到resource structure的waiter連結清單中
③ enqueue算法
按先入先出原則配置設定鎖
㈡ 行級鎖
以上的locking機制需要resource、lock兩種資料結構,适合粗粒度資源,但對于資料記錄等細粒度的通路,無論從
記憶體需求還是維護成本,都是一個惡夢
Oracle的行級鎖就是在這種場合下閃亮登場的
行級鎖不是Oracle一般意義上的鎖
雖然有鎖的功能,但是沒有鎖的開銷
行級鎖根本沒有相關開銷,對1千萬行鎖定所需的資源數與對1行鎖定所需的資源數完全相同,這是個常量:0和1
在Oracle的每行資料上,都有一個标志位來表示該行資料是否被鎖定,要檢視某一行是否被鎖定,必須直接找到這一行,
而不要指望能從哪個清單得到答案
我們dump一個資料塊,其transaction header的trc檔案摘錄如下:
Block header dump: 0x01000197
Object id on Block? Y
seg/obj: 0xcd8a csc: 0x00.a26fe itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000191 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0001.005.00000100 0x0080000f.00ae.23 --U- 1 fsc 0x0000.000a2707
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
其中 Lck字段就是行級鎖的表示:1加鎖,0不加鎖
data header的部分trc摘錄如下:
tab 0, row 0, @0x1f93
tl: 5 fb: --H-FL-- lb: 0x1 cc: 1
col 0: [ 1] 61
其中 lb => ITL number
其實,lb就是Itl
并發通路時,事務通過這個lb找到Itl,進而确定Lck的值,若為1,則挂到隊列池
是以,當使用者被阻塞時,不是被某條記錄的行級鎖阻塞,而是被TX鎖阻塞
下面用實驗證明之:
session_A
[email protected]> drop table t purge;
Table dropped.
[email protected]> create table demo (id number,name varchar2(10));
Table created.
[email protected]> insert into demo values(1,'bin');
1 row created.
[email protected]> insert into demo values(2,'think');
1 row created.
[email protected]> insert into demo values(3,'water');
1 row created.
[email protected]> commit;
Commit complete.
[email protected]> select * from demo;
ID NAME
---------- ----------
1 bin
2 think
3 water
[email protected]> savepoint a;
Savepoint created.
[email protected]> update demo set name='think big' where id=2;
1 row updated.
session_B
在session_B,并發修改同一條記錄,會話被阻塞
[email protected]> update demo set name='think big' where id=2;
--被阻塞
作為一名DBA,常見的一個場景之一:
建立表空間:
create tablespace Think
datafile '/u01/app/oracle/oradata/orcl/think.dbf' size 100M
autoextend on next 10M maxsize 4096M
extent management local uniform size 256K
segment space management auto;
建立使用者:
create user bin
default tablespace Think
temporary tablespace temp;
授予權限:
grant connect,resource to bin;
revoke unlimited tablespace from bin;
alter user bin quota unlimited on Think;
在這個場景中,有兩條語句:
① extent management local uniform size 256K
② segment space management auto
其中,前者是區管理;後者則是段空間管理
㈠ 區管理
區管理實際上就是表空間的管理
8i以前,是字典管理表空間,當建立或删除對象時,Oracle的空間配置設定或回收是通過資料字典來記錄和管理
在高并發系統中,這會導緻性能衰減、空間碎片等難題
這已經是門過去的技術,這裡就不贅述了。
8i開始,Oracle引入本地表空間管理
在每個表空間的資料檔案的頭部加入了一個位圖區域
一個段的第一個區的第一個塊是first level bitmap block
第二個塊是second level bitmap block
第三個塊才是段頭塊
這兩個塊是用來管理free block
文法:
extent management local { autoallocate | uniform size n K/M}
是自動配置設定還是統一尺寸
若為自動配置設定,則Oracle會按照遞增算法來配置設定空間
如果選擇統一尺寸,還可以詳細指定每個區間的大小
dba_extents這個視圖可以看到哪些對象配置設定了多少區間
㈡ 段空間管理
Oracle以區間為機關将空間配置設定給對象段,而段内則是以block為機關進行空間使用和管理
我們以幾個參數來了解段空間管理
[email protected]> select extent_management,segment_space_management from dba_tablespaces;
EXTENT_MAN SEGMEN
---------- ------
LOCAL MANUAL
LOCAL MANUAL
LOCAL AUTO
LOCAL MANUAL
LOCAL MANUAL
從9i開始,段空間管理有兩種:
① MSSM:由你設定freelists、freelist groups、pctused、pctfree、initrans等參數來控制如何配置設定、使用段中的空間
② ASSM:你隻需控制一個參數pctfree,其他參數即使建了也将被忽略
⑴ freelist
使用MSSM表空間管理時,Oracle會在freelist中為有自由空間的對象維護HWM以下的塊
freelist和freelist group在ASSM表空間中根本不存在,僅在MSSM表空間使用這個技術
⑵ pctfree 和 pctused
pctfree告訴Oracle:塊上應該保留多大的空間來完成将來的更新
對于MSSM,她控制着塊何時放入freelist中,以及何時從freelist中取出。
如果大于pctfree,則這個塊會一直在freelist上
對于ASSM,因為ASSM根本不使用freelist。在ASSM中,pctused也将被忽略。
但她仍然會限制能否将一個新行插入到一個塊中
适當的設定pctfree有助于減小行遷移
⑶ initrans
無論是ASSM or MSSM這個參數仍然有效
塊頭的事務槽的初始化大小有對象的initrans指定