Oracle面試寶典-鎖篇

chenoracle發表於2020-03-04

Oracle 面試寶典 - 鎖篇


請問 Oracle 資料庫鎖的作用是什麼?

多使用者系統併發訪問並修改資料時,保護資料的一致性和完整性。

鎖是一種機制,多個事務同時訪問一個資料庫物件時,該機制可以實現對併發的控制。

Oracle 正是使用鎖機制來實現系統的高併發,利用不同型別的排它鎖或者共享鎖來管理併發會話對資料的操作。資料庫是一個多使用者使用的共享資源。當多個使用者併發地存取修改同一資料時,若對併發操作不加控制就可能會讀取和儲存不正確的資料,破壞資料庫的一致性和完整性。Oracle 資料庫通過其鎖機制在事務之間提供資料併發性、一致性和完整性。鎖定是自動發生的,通常不需要使用者操作。

請問Oracle 鎖儲存在哪裡?

oracle 資料庫中,不存在真正意義上屬於某個物件或資料的鎖。 oracle 鎖的資訊是資料塊的一個物理屬性,而不是邏輯上屬於某個表或某個行。 Oracle 的鎖機制是一種輕量級的鎖定機制,不是通過構建鎖列表來進行資料的鎖定管理,而是直接將鎖作為資料塊的屬性,儲存在資料塊首部。在 Oracle 資料庫中,它並不是對某個表加上鎖或者某幾行加上鎖,   鎖是以資料塊的一個屬性存在的。 也就是說, 每個資料塊本身就儲存著自己資料塊中資料的資訊,這個地方叫 ITL Interested Transaction List ), 凡是在這個資料塊上有活動的事務,它的資訊就會記錄在這裡面供後續的操作查詢,一保證事務的一致性。

請問Oracle 鎖有哪些類別?分別介紹下?

一:根據獲取鎖的方式,鎖分為以下兩種

排它鎖(Exclusive Locks ,即 X 鎖)和共享鎖( Share Locks ,即 S 鎖)。

1.1 排它鎖 事務設定排它鎖後,該事務單獨獲得此資源,另一事務不能在此事務提交之前獲得相同物件的共享鎖或排它鎖。

可以理解為寫鎖,這種鎖是防止資源的共享,用於修改資料。如果一個事物給某個資料加了排它鎖,其它事物就不能對它再加任何鎖,直到事物完結,排它鎖釋放。

1.2 共享鎖 共享鎖使一個事務對特定資料庫資源進行共享訪問 另一事務也可對此資源進行訪問或獲得相同共享鎖。共享鎖為事務提供高併發性 容易造成死鎖和資料更新丟失。

可以理解為讀鎖,加了共享鎖的資料,只能共享讀,不能再給它加排它鎖進行寫的操作。

二:根據系統併發情況,鎖分為以下兩種

悲觀鎖和樂觀鎖。

2.1 悲觀鎖

所謂的悲觀鎖:顧名思義,就是很悲觀,每次去 修改 資料的時候都認為別人 修改 相同的書 ,所以每次 修改 資料的時候都會上鎖。這樣別人 修改 資料的時候就要等待直到鎖的釋放。以保證資料的一致性。

悲觀鎖有 兩種方式 ( SQL 語句的區別來看 ):

1.  執行 select xxx for update 操作時,資料會被鎖定,只有執行comit rollover 才會釋放

2.  執行 select xxx for update nowait 操作時,資料也會被鎖定,其他人訪問時或返回ORA-00054 錯誤,內容是資源正忙,需要採取相應的業務措施進行處理。

2.2 樂觀鎖

所謂的樂觀鎖: 就是很樂觀,每次去修改資料的時候都認為別人不會去修改相同的資料,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料。

因此,需要在提交時保證資料一致性,如果不一致,則返回錯誤,由程式本身的邏輯進行處理。

樂觀鎖的實現主要有三種方式:

a. 通過比較提交前後的資料是否發生變化來判斷是否存在資料衝突

b. 通過在表中增加版本戳列,來標示是否發生了變化

c. 通過比對錶的時間戳來判斷是否出現了版本變化

可以通過trigger 或儲存過程實現該樂觀鎖。

oracle 在資料更新時通常時候的是 樂觀 鎖,任何一個以UPDATE...SET 開始並且不是以 SELECT...FOR UPDATE 進行操作的命令就是一個樂觀鎖的例子。

悲觀鎖和樂觀鎖使用場景:

1.  如果系統併發量不大且不允許髒讀,可以使用悲觀鎖解決併發問題。

2.  如果系統併發非常大的話,悲觀鎖會帶來很大效能問題,所以一般採用樂觀鎖。

3.  如果系統讀比較多,寫比較少,也應該使用樂觀鎖,可以提高吞吐量

三: 根據保護物件的不同,Oracle 資料庫鎖可以分為以下幾大類

(1) DML lock data locks ,資料鎖):用於保護資料的完整性;

(2) DDL lock dictionary locks ,字典鎖):用於保護資料庫物件的結構(例如表、檢視、索引的結構定義);

(3) System Locks :保護內部資料庫結構 , 例如 Latches,mutexes,internal locks

3.1 DML

DML ( 也稱為資料鎖 ) 保證了多個使用者併發訪問的資料的完整性。

DML 語句自動獲取下列型別的鎖 :

3.1.1 行鎖(TX)

行級鎖是粒度最細的DML 鎖,主要用來控制資料行的修改、刪除操作。當對錶中的某行資料進行修改時,需要對其加上行級排他鎖,防止其他事物也對其進行修改,等資料修改完,事物提交時,自動釋放。

3.1.2 表鎖(TM)

TM 鎖用於確保在修改表的內容時,表的結構不會改變,例如防止在 DML 語句執行期間相關的表被移除。當使用者對錶執行 DDL DML 操作時,將獲取一個此表的表級鎖。

當事務獲得行鎖後,此事務也將自動獲得該行的表鎖, 以防止其它事務進行 DDL 語句影響記錄行的更新。

TM 鎖包括了 SS SX (RX) S SRX(SSX) X 等多種模式,在資料庫中用 0 6 來表示。不同的 SQL 操作產生不同型別的 TM .

R ROW 行, S SHARE 共享, X e x clusive 排他,獨佔鎖的意思

鎖模式:0   鎖描述: none

說明:沒有鎖, 一般的 SELECT ,在表和行上都是 0 級鎖

鎖模式:1   鎖描述: NULL

說明:Select 有時會在 v$locked_object 出現。   其實起不了鎖定的作用,他就是有一個通知的功能,根本阻止不了 DDL ,類似把執行計劃中的物件通知物件所屬的會話。

鎖模式:2   鎖描述: SS(Row-S) 行級共享鎖

說明:表結構共享鎖,只跟X 衝突,因為其他都是共享鎖, RX,SRX 雖然也有 X, 但是是行的 X, 表上還是共享的意思, 2 級鎖在表級別和 0-5 級不衝突。

這個鎖,也稱為子共享表鎖(SS) ,表示持有表上鎖的事務已經鎖定了表中的行,並打算更新它們。行共享鎖是表鎖中限制最少的一種模式,它為表提供了最高程度的併發性。

相關操作:Select for update,Lock For Update,Lock Row Share 

鎖模式:3   鎖描述: SX(Row-X) 行級排他鎖

說明:表結構共享鎖+ 被操作的記錄的排它鎖(若有 DML 操作),這個鎖,也稱為 subexclusive table lock (SX) ,通常表示持有這個鎖的事務已經更新了錶行或發出了 SELECT for update SX 鎖允許其他事務併發地查詢、插入、更新、刪除或鎖定同一表中的行。因此, SX 鎖允許多個事務同時獲得同一表的 SX 和子共享表鎖。

相關操作:Insert, Update, Delete, Lock Row Exclusive

鎖模式:4   鎖描述: S(Share) 共享鎖

說明:表結構共享鎖+ 所有記錄共享鎖(隱含),事務持有的共享表鎖允許其他事務查詢該表 (SELECT for update 除外 ) ,但僅當單個事務持有共享表鎖時才允許更新。因為多個事務可能同時持有一個共享表鎖,持有這個鎖不足以確保一個事務可以修改表。

相關操作:Create Index, Lock Share

鎖模式:5   鎖描述: SRX(S/Row-X) 共享行級排他鎖

說明:表結構共享鎖+ 所有記錄排它鎖(隱含),這個鎖也稱為 share-subexclusive table lock (SSX) ,比共享鎖的限制更嚴格。一次只有一個事務可以獲得給定表上的 SSX 鎖。事務持有的 SSX 鎖允許其他事務查詢表 ( 除了 SELECT for update) 但不更新表。

相關操作:Lock Share Row Exclusive 

鎖模式:6   鎖描述: X(Exclusive) 排他鎖

說明:表結構排它鎖,這個鎖是最嚴格的,禁止其他事務執行任何型別的DML 語句或在表上放置任何型別的鎖。

相關操作:Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive

這幾種模式看上去是不是感覺特別亂,不好理解,網上有一個通俗易懂的例子如下:

http://blog.itpub.net/30126024/viewspace-2156232/

參考Maclean 的講座,用一個珠寶店來做比喻說明

珠寶店可以給大家免費參觀,可以讓你預定,可以試用後覺得好再買,可以把店都買下來

0 類人 ,免費參觀珠寶店的人

1 類人 ,免費參觀珠寶店的老弱病殘孕的客人

2 類人 ,預定了試用期,先買來幾天,如果試用後覺得好再買

3 類人 ,直接到店裡的目的就是立即購買

4 類人 ,把整個店的珠寶包下來,讓別人參觀,預定,但是不能買賣(這在ORACLE 中叫只讀鎖,只允許別人讀,也就是隻允許第 0 1 2 類人來珠寶店,讓別人只讀方式的參觀,不允許買賣,再來個第 4 類人,還是允許的,因為大家雖然都想包,但是大家的目的都是分享,而不是獨佔,所以是可以相容的)

5 類人 ,它跟第4 類人的區別只有一條,就是第 5 類人包下整個珠寶店後,另一個第 5 類人就不允許再包了 ( 這在 ORACLE 中叫寫鎖定 ) ,也就是第 5 類人是單通道的,你在珠寶店裡只能找到 1 個第 5 類人,不可能找出第 2 個第 5 類人,但是第 5 類人把珠寶店包下來後,仍然可以讓第 0 1 2 類人蔘觀,但不允許買賣

6 類人 ,它把整個珠寶店盤下來,不允許任何人有目的的參觀,只允許免費參觀,它是獨佔的,只允許0,1 類人蔘觀,其他人都不允許

-- 以上第 2 類人預定的,所以第 3 類跟 6 類人不相容

-- 以上第 3 類人是要買珠寶的,所以第 3 類跟 4 5 6 類人都不相容

3.2 DDL

當正在進行的DDL 操作作用於或引用物件時,資料字典( DDL )鎖保護模式物件的定義。

DDL 操作期間,只有修改或引用的單個架構物件才會被鎖定。資料庫從不鎖定整個資料字典。

Oracle 資料庫代表任何需要 DDL 鎖的 DDL 事務自動獲取 DDL 鎖。使用者不能顯式請求 DDL 鎖。例如,如果使用者建立了一個儲存過程,那麼 Oracle 資料庫會自動為過程定義中引用的所有模式物件獲取 DDL 鎖。 DDL 鎖防止在過程編譯完成之前更改或刪除這些物件。

3.2.1 DDL 排他

排他DDL 鎖阻止其他會話獲得 DDL DML 鎖。

大多數DDL 操作需要對一個資源使用獨佔 DDL 鎖,以防止對其他 DDL 操作的破壞干擾,這些操作可能修改或引用相同的模式物件。例如,當 ALTER TABLE 新增一個列時, DROP TABLE 不允許刪除一個表,反之亦然。

3.2.2 DDL 共享鎖

資源的共享DDL 鎖可以防止對衝突的 DDL 操作的破壞性干擾,但允許對類似的 DDL 操作進行資料併發。

這些鎖會保護所引用物件的結構,使之不會被其他會話修改,但是允許修改資料。

例如,在執行CREATE PROCEDURE 語句時,包含的事務為所有引用的表獲取共享 DDL 鎖。其他事務可以併發地建立引用相同表的過程,並獲取相同表上的併發共享 DDL 鎖,但是任何事務都不能獲得任何引用表上的獨佔 DDL 鎖。

共享DDL 鎖在 DDL 語句執行和自動提交期間有效。因此,持有共享 DDL 鎖的事務可以保證引用的模式物件的定義在事務期間保持不變。

3.2.3 DDL 可分解的解析鎖

一個解析鎖被稱為一個可分解的解析鎖,因為它不禁止任何DDL 操作,並且可以被分解為允許衝突的 DDL 操作。

這些鎖允許一個物件(如共享池中快取的一個查詢計劃)向另外某個物件註冊其依賴性。如果在被依賴的物件上執行DDL,Oracle會檢視已經對該物件註冊了依賴性的物件列表,並使這些物件無效。因此,這些鎖是“可 分解的 ”,它們不防止DDL出現。

3.3 系統鎖

Oracle 資料庫使用各種型別的系統鎖來保護內部資料庫和記憶體結構。這些機制對於使用者來說是透明的。

3.3.1 閂鎖 Latches

閂鎖是一種簡單的低階序列化機制,用於協調對共享資料結構、物件和檔案的多使用者訪問。

一般來說,latch 由三種記憶體元素成: pid (程式 id ),記憶體地址和記憶體長度。 Latch 保證對共享資料結構的排它性訪問,以此來保證記憶體結構的完整性不受到損壞。在多個會話同時修改或者檢視( inspect sga 中同一個記憶體結構時,必須序列化訪問以 保證 sga 中資料結構的完整性,latch 不會造成阻塞,是隻會等待。 當前一個程式釋放latch 後,如果其他多個程式同時請求的話,他們之間將出現競爭,沒有一個入隊機制, 一旦前面程式釋放 鎖定 ,後面的程式就蜂擁而上,沒有先來後到的概念,並且這一切都發生的非常快,因為Latch 的特點是快而短暫。

latch 爭用多半要考慮系統及資料庫自身設計問題,如繫結變數,熱塊及引數設定是否合理。

如多使用者對主鍵的刪除或者修改,是否有使用者使用select for update 這樣的語法,外來鍵是否建立索引等。

閂鎖保護共享記憶體資源在被多個程式訪問時不受損壞。具體來說,鎖存保護資料結構不受以下情況的影響:

•多個會話併發修改

當被一個會話讀取的同時被另一個會話修改

當訪問時釋放重新分配記憶體

通常,在SGA 中單個閂保護多個物件,例如,後臺程式(例如 DBWn LGWR )從共享池( shared pool )分配記憶體建立資料結構,為了分配這些記憶體,這些程式用一個共享池閂來序列化訪問,防止兩個程式同時檢查或修改共享池。記憶體被分配後,其它程式可能需要訪問共享池,例如庫快取(library cache ),用於解析,這時,程式閂只鎖庫快取,不鎖整個共享池。

與佇列鎖(如行鎖)不同,閂不允許session 排隊。當一個閂鎖可用時,發起請求的第一個session 獲取到閂。當一個程式在一個迴圈中重複地請求一個閂,叫做 Latch spinning ,而一個程式等待請求閂期間睡眠釋放 CPU ,則叫做 latch sleeping

通常,一個Oracle 程式在操作或檢視一個資料結構時只獲取閂極短的時間,例如,當處理一個僱員的薪水更新時,資料庫可以獲取和釋放幾千次鎖。閂的實現依賴於作業系統,特別是對於怎麼處理閂的等待。

閂的增加意味著並行度的減少,例如,過多的硬操作會競爭庫快取閂。V$LATCH 檢視包含了每種閂使用的統計資訊,包括請求和等待每個閂鎖的次數。

3.3.2 互斥鎖 Mutexes

Mutex 作為 Latch 的替代品,具有更快速獲得,更小等優勢。

獲取一個mutex 進需要大約 30~35 個指令, 而 Latch 則需要 150~200 個指令。一個 mutex 結構的大小大約為 16 bytes ,而在 10.2 版本中一個 latch 需要 112 bytes ,在更早的版本中是 200 bytes  

互斥物件( 互斥物件 ) 是一種低階別的機制,它可以防止記憶體中的物件在被併發程式訪問時老化或損壞。互斥鎖類似於閂,但閂通常保護一組物件,而互斥鎖保護單個物件。

互斥鎖有幾個好處:

•互斥鎖可以減少爭用。

因為一個閂保護多個物件,所以當多個程式試圖同時訪問這些物件時,它可能成為瓶頸。通過序列化對單個物件而不是組的訪問,互斥鎖減速了競爭。

•互斥鎖消耗的記憶體比 閂更少。

•在共享模式下,互斥鎖允許多個會話併發引用

3.3.3 內部鎖 Internal Locks

內部鎖是比閂和互斥鎖更高階、更復雜的機制,可用於各種目的。

資料庫使用以下型別的內部鎖:

•字典快取鎖

這些鎖的持續時間非常短,當字典快取的條目被修改或使用時,它們保證被解析的語句不會看到不一致的物件定義。字典快取鎖可以是共享的,也可以是獨佔的。共享鎖在解析完成時釋放,而獨佔鎖在DDL 操作完成時釋放。

•檔案和日誌管理鎖

這些鎖保護各種檔案。例如,一種內部鎖保護控制檔案保證一次只有一個程式可以修改它。另一個鎖協調線上重做日誌檔案的使用和歸檔。資料檔案被鎖定,以確保多個例項以共享模式掛載資料庫,或一個例項以獨佔模式掛載資料庫。因為檔案鎖和日誌鎖指示檔案的狀態,所以這些鎖必須保持很長時間。

•表空間和撤銷段鎖

這些鎖保護表空間和撤銷段。例如,訪問資料庫的所有例項必須就表空間是聯機還是離線達成一致。undo 段被鎖定,保證只有一個資料庫例項可以寫入undo

 

參考資料:

https://docs.oracle.com/en/database/oracle/oracle-database/20/cncpt/index.html

https://baijiahao.baidu.com/s?id=1633934567936531363&wfr=spider&for=pc

https://www.cnblogs.com/jiyuqi/p/3701716.html

https://www.cnblogs.com/yingsong/p/7645965.html

https://blog.csdn.net/zdp072/article/details/25008873

https://www.cnblogs.com/sopost/archive/2011/11/17/2253352.html

https://www.askmaclean.com/archives/understanding-oracle-mutex.html

http://blog.itpub.net/30126024/viewspace-2156232/?t=1537068073785

 

歡迎關注我的微信公眾號"IT Chen" ,共同學習,共同成長!!!




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29785807/viewspace-2678573/,如需轉載,請註明出處,否則將追究法律責任。

相關文章