欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Oracle鎖表的解決方法及避免鎖表問(wèn)題的最佳實(shí)踐

 更新時(shí)間:2024年11月28日 10:21:45   作者:J.P.August  
在 Oracle 數(shù)據(jù)庫(kù)中,鎖表或鎖超時(shí)相信大家都不陌生,是一個(gè)常見(jiàn)的問(wèn)題,尤其是在執(zhí)行 DML(數(shù)據(jù)操作語(yǔ)言)語(yǔ)句時(shí),本文將詳細(xì)介紹如何解決鎖表問(wèn)題以及如何查找引起鎖表的 SQL 語(yǔ)句,并提供避免鎖表問(wèn)題的最佳實(shí)踐,需要的朋友可以參考下

背景介紹

在 Oracle 數(shù)據(jù)庫(kù)中,鎖表或鎖超時(shí)相信大家都不陌生,是一個(gè)常見(jiàn)的問(wèn)題,尤其是在執(zhí)行 DML(數(shù)據(jù)操作語(yǔ)言)語(yǔ)句時(shí)。當(dāng)一個(gè)會(huì)話對(duì)表或行進(jìn)行鎖定但未提交事務(wù)時(shí),其他會(huì)話可能會(huì)因?yàn)榈却i資源而出現(xiàn)超時(shí)。這種情況不僅會(huì)影響數(shù)據(jù)庫(kù)性能,還可能導(dǎo)致應(yīng)用程序異常(java.sql.SQLException: Lock wait timeout exceeded)。

本文將詳細(xì)介紹如何解決鎖表問(wèn)題以及如何查找引起鎖表的 SQL 語(yǔ)句,并提供避免鎖表問(wèn)題的最佳實(shí)踐。

鎖表的原因

  1. 獨(dú)占式封鎖機(jī)制:Oracle 使用獨(dú)占式封鎖機(jī)制來(lái)確保數(shù)據(jù)的一致性。當(dāng)一個(gè)會(huì)話對(duì)數(shù)據(jù)進(jìn)行修改時(shí),會(huì)對(duì)其加鎖,直到事務(wù)提交或回滾。
  2. 長(zhǎng)時(shí)間運(yùn)行的 SQL 語(yǔ)句:某些 SQL 語(yǔ)句可能由于性能問(wèn)題或其他原因而長(zhǎng)時(shí)間運(yùn)行,導(dǎo)致鎖資源一直被占用。
  3. 高并發(fā)場(chǎng)景:在高并發(fā)環(huán)境下,多個(gè)會(huì)話同時(shí)訪問(wèn)相同的數(shù)據(jù),可能會(huì)導(dǎo)致鎖競(jìng)爭(zhēng),從而引發(fā)死鎖。

解決鎖表的方法

臨時(shí)解決方案

  • 找出鎖資源競(jìng)爭(zhēng)的會(huì)話
SELECT L.SESSION_ID, S.SERIAL#, L.LOCKED_MODE AS "鎖模式", 
       L.ORACLE_USERNAME AS "所有者", L.OS_USER_NAME AS "登錄系統(tǒng)用戶(hù)名", 
       S.MACHINE AS "系統(tǒng)名", S.TERMINAL AS "終端用戶(hù)名", 
       O.OBJECT_NAME AS "被鎖表對(duì)象名", S.LOGON_TIME AS "登錄數(shù)據(jù)庫(kù)時(shí)間"
  FROM V$LOCKED_OBJECT L
  INNER JOIN ALL_OBJECTS O ON O.OBJECT_ID = L.OBJECT_ID
  INNER JOIN V$SESSION S ON S.SID = L.SESSION_ID;
  • sql強(qiáng)制結(jié)束會(huì)話
ALTER SYSTEM KILL SESSION 'SESSION_ID, SERIAL#';

示例

假設(shè) session1 修改了某條數(shù)據(jù)但未提交事務(wù),session2 查詢(xún)未提交事務(wù)的那條記錄時(shí)會(huì)被阻塞。

  • 查詢(xún)未提交事務(wù)的會(huì)話信息
SELECT L.SESSION_ID, S.SERIAL#, L.LOCKED_MODE AS "鎖模式", 
       L.ORACLE_USERNAME AS "所有者", L.OS_USER_NAME AS "登錄系統(tǒng)用戶(hù)名", 
       S.MACHINE AS "系統(tǒng)名", S.TERMINAL AS "終端用戶(hù)名", 
       O.OBJECT_NAME AS "被鎖表對(duì)象名", S.LOGON_TIME AS "登錄數(shù)據(jù)庫(kù)時(shí)間"
  FROM V$LOCKED_OBJECT L
  INNER JOIN ALL_OBJECTS O ON O.OBJECT_ID = L.OBJECT_ID
  INNER JOIN V$SESSION S ON S.SID = L.SESSION_ID;


 SESSION_ID	SERIAL#	鎖模式	所有者	登錄系統(tǒng)用戶(hù)名	系統(tǒng)名	終端用戶(hù)名	被鎖表對(duì)象名	登錄數(shù)據(jù)庫(kù)時(shí)間
----------  ------- ----- ------ ------------- ----- --------- --------- ------------
29	84	3 IN	test	WORKGROUP\LA...	LAPTOP-9FDC2903	LIN_USER	2023/2/26 11:08:08
  • 強(qiáng)制結(jié)束 session1
ALTER SYSTEM KILL SESSION '29, 84';
  • 驗(yàn)證 session2 的執(zhí)行情況
    • 強(qiáng)制結(jié)束 session1 后,session2 的等待會(huì)立即終止并執(zhí)行。

查找被鎖對(duì)象

  • 查詢(xún)被鎖對(duì)象數(shù)目
SELECT COUNT(1) FROM V$LOCKED_OBJECT;
  • 查詢(xún)被鎖對(duì)象
SELECT B.OWNER, B.OBJECT_NAME, A.SESSION_ID, A.LOCKED_MODE
  FROM V$LOCKED_OBJECT A, DBA_OBJECTS B
 WHERE B.OBJECT_ID = A.OBJECT_ID;
  • 查詢(xún)被鎖對(duì)象的連接
SELECT T2.USERNAME, T2.SID, T2.SERIAL, T2.LOGON_TIME
  FROM V$LOCKED_OBJECT T1, V$SESSION T2
 WHERE T1.SESSION_ID = T2.SID
 ORDER BY T2.LOGON_TIME;
  • 關(guān)閉被鎖對(duì)象連接
ALTER SYSTEM KILL SESSION '253, 9542';

查看當(dāng)前系統(tǒng)中鎖表情況

  • 查詢(xún)所有被鎖對(duì)象
SELECT * FROM V$LOCKED_OBJECT;
  • 查詢(xún)?cè)敿?xì)的鎖表情況
SELECT SESS.SID, SESS.SERIAL#, LO.ORACLE_USERNAME, LO.OS_USER_NAME, AO.OBJECT_NAME, LO.LOCKED_MODE
  FROM V$LOCKED_OBJECT LO, DBA_OBJECTS AO, V$SESSION SESS, V$PROCESS P
 WHERE AO.OBJECT_ID = LO.OBJECT_ID
   AND LO.SESSION_ID = SESS.SID;

查找引起鎖表的 SQL 語(yǔ)句

  • 查詢(xún)引起鎖表的 SQL 語(yǔ)句
SELECT L.SESSION_ID SID, S.SERIAL#, L.LOCKED_MODE, L.ORACLE_USERNAME, S.USER#, L.OS_USER_NAME, S.MACHINE, S.TERMINAL, A.SQL_TEXT, A.ACTION
  FROM V$SQLAREA A, V$SESSION S, V$LOCKED_OBJECT L
 WHERE L.SESSION_ID = S.SID
   AND S.PREV_SQL_ADDR = A.ADDRESS
 ORDER BY SID, S.SERIAL#;
  • 查看所有被阻塞的會(huì)話
SET LINE 200;
COL TERMINAL FORMAT A10;
COL PROGRAM FORMAT A20;
COL USERNAME FORMAT A10;
COL MACHINE FORMAT A10;
COL SQL_TEXT FORMAT A40;
SELECT A.SID, A.SERIAL#, A.USERNAME, A.COMMAND, A.LOCKWAIT, A.STATUS, A.MACHINE, A.TERMINAL, A.PROGRAM, A.SECONDS_IN_WAIT, B.SQL_TEXT
  FROM V$SESSION A, V$SQL B
 WHERE B.SQL_ID = A.SQL_ID
   AND (A.BLOCKING_INSTANCE IS NOT NULL AND A.BLOCKING_SESSION IS NOT NULL);
  • 展示阻塞的樹(shù)形結(jié)構(gòu)
WITH lk AS (
  SELECT BLOCKING_INSTANCE || '.' || BLOCKING_SESSION AS blocker, INST_ID || '.' || SID AS waiter
    FROM GV$SESSION
   WHERE BLOCKING_INSTANCE IS NOT NULL AND BLOCKING_SESSION IS NOT NULL
)
SELECT LPAD('  ', 2 * (LEVEL - 1)) || WAITER LOCK_TREE
  FROM (
    SELECT * FROM lk
    UNION ALL
    SELECT DISTINCT 'root', BLOCKER FROM lk
    WHERE BLOCKER NOT IN (SELECT WAITER FROM lk)
  )
CONNECT BY PRIOR WAITER = BLOCKER
START WITH BLOCKER = 'root';
  • 展示阻塞的樹(shù)形結(jié)構(gòu),并輸出阻塞語(yǔ)句、被阻塞語(yǔ)句,并給出殺會(huì)話語(yǔ)句
WITH lk AS (
  SELECT A.BLOCKING_INSTANCE || '.' || A.BLOCKING_SESSION AS blocker,
         A.INST_ID || '.' || A.SID AS waiter,
         (SELECT B.SQL_TEXT || '  ALTER SYSTEM KILL SESSION ''' || C.SID || ', ' || C.SERIAL# || ''''
            FROM GV$SQLAREA B, GV$SESSION C
           WHERE A.BLOCKING_INSTANCE = C.INST_ID
             AND C.SID = A.BLOCKING_SESSION
             AND (C.SQL_ID = B.SQL_ID OR C.PREV_SQL_ID = B.SQL_ID)) AS kill_block_sql,
         (SELECT B.SQL_TEXT || '  ALTER SYSTEM KILL SESSION ''' || A.SID || ', ' || A.SERIAL# || ''''
            FROM GV$SQLAREA B
           WHERE A.INST_ID = B.INST_ID
             AND A.SQL_ID = B.SQL_ID) AS kill_waiter_sql
    FROM GV$SESSION A
   WHERE A.BLOCKING_INSTANCE IS NOT NULL AND A.BLOCKING_SESSION IS NOT NULL
)
SELECT LPAD('  ', 2 * (LEVEL - 1)) || WAITER || '  ' || KILL_WAITER_SQL LOCK_TREE
  FROM (
    SELECT BLOCKER, WAITER, KILL_WAITER_SQL FROM lk
    UNION ALL
    SELECT DISTINCT 'root', BLOCKER, KILL_BLOCK_SQL FROM lk
    WHERE BLOCKER NOT IN (SELECT WAITER FROM lk)
  )
CONNECT BY PRIOR WAITER = BLOCKER
START WITH BLOCKER = 'root';
  • 直接顯示阻塞關(guān)系
COL BLOCK_MSG FOR A80
SELECT C.TERMINAL || ' (''' || A.SID || ',' || C.SERIAL# || ''') is blocking ' || B.SID BLOCK_MSG
  FROM V$LOCK A, V$LOCK B, V$SESSION C
 WHERE A.ID1 = B.ID1
   AND A.ID2 = B.ID2
   AND A.BLOCK > 0
   AND A.SID <> B.SID
   AND A.SID = C.SID;

避免鎖表問(wèn)題的最佳實(shí)踐

1. 優(yōu)化 SQL 語(yǔ)句

  • 減少鎖定范圍:盡量使用行級(jí)鎖而不是表級(jí)鎖。例如,使用 SELECT ... FOR UPDATE 時(shí),只鎖定需要更新的行。
  • 避免長(zhǎng)時(shí)間運(yùn)行的事務(wù):確保事務(wù)盡可能短,盡快提交或回滾事務(wù),減少鎖的持有時(shí)間。
  • 批量處理:對(duì)于大量數(shù)據(jù)的操作,考慮分批處理,以減少單個(gè)事務(wù)的持續(xù)時(shí)間和鎖的持有時(shí)間。

2. 使用合適的隔離級(jí)別

  • 調(diào)整隔離級(jí)別:根據(jù)應(yīng)用需求選擇合適的隔離級(jí)別。例如,使用 READ COMMITTED 而不是 SERIALIZABLE,以減少鎖的競(jìng)爭(zhēng)。
  • 避免不必要的鎖:在某些情況下,可以使用 NOLOCK 提示來(lái)避免讀取操作時(shí)的鎖,但這可能會(huì)導(dǎo)致臟讀。

3. 優(yōu)化索引

  • 創(chuàng)建適當(dāng)?shù)乃饕?/strong>:確保經(jīng)常查詢(xún)的列上有適當(dāng)?shù)乃饕?,以減少全表掃描和鎖的競(jìng)爭(zhēng)。
  • 維護(hù)索引:定期重建和重組索引,以保持其效率。

4. 使用分區(qū)表

  • 分區(qū)表:對(duì)于大型表,可以使用分區(qū)技術(shù)來(lái)減少鎖的競(jìng)爭(zhēng)。分區(qū)表可以將數(shù)據(jù)分成多個(gè)部分,每個(gè)部分可以獨(dú)立地進(jìn)行操作,從而減少鎖的影響。

5. 優(yōu)化應(yīng)用程序邏輯

  • 減少并發(fā)沖突:設(shè)計(jì)應(yīng)用程序邏輯時(shí),盡量減少對(duì)同一數(shù)據(jù)的并發(fā)訪問(wèn)。例如,通過(guò)使用隊(duì)列或其他機(jī)制來(lái)序列化對(duì)共享資源的訪問(wèn)。
  • 使用樂(lè)觀鎖:對(duì)于一些非關(guān)鍵性操作,可以使用樂(lè)觀鎖(如版本號(hào)控制)來(lái)替代悲觀鎖,減少鎖的競(jìng)爭(zhēng)。

6. 監(jiān)控和調(diào)優(yōu)

  • 監(jiān)控鎖情況:定期監(jiān)控?cái)?shù)據(jù)庫(kù)中的鎖情況,使用 V$LOCKED_OBJECTV$SESSION 和 V$SQLAREA 等視圖來(lái)識(shí)別潛在的鎖問(wèn)題。
  • 設(shè)置超時(shí):為會(huì)話設(shè)置合理的鎖等待超時(shí)時(shí)間,防止某個(gè)會(huì)話長(zhǎng)時(shí)間占用鎖資源??梢酝ㄟ^(guò) ALTER SYSTEM SET LOCK_TIMEOUT = <seconds> 來(lái)設(shè)置。

7. 使用數(shù)據(jù)庫(kù)特性

  • 閃回技術(shù):利用 Oracle 的閃回技術(shù)(如 Flashback Query)來(lái)恢復(fù)數(shù)據(jù),而不是依賴(lài)于復(fù)雜的事務(wù)回滾。
  • 在線重定義:使用在線重定義(Online Redefinition)來(lái)修改表結(jié)構(gòu),而不影響現(xiàn)有事務(wù)。

8. 事務(wù)管理

  • 最小化事務(wù)大小:盡量將大事務(wù)拆分為多個(gè)小事務(wù),以減少鎖的持有時(shí)間。
  • 使用保存點(diǎn):在長(zhǎng)事務(wù)中使用保存點(diǎn)(SAVEPOINT),以便在發(fā)生錯(cuò)誤時(shí)可以回滾到特定點(diǎn),而不是整個(gè)事務(wù)。

9. 數(shù)據(jù)庫(kù)配置

  • 調(diào)整參數(shù):根據(jù)實(shí)際情況調(diào)整數(shù)據(jù)庫(kù)參數(shù),如 UNDO_RETENTION、DB_FILE_MULTIBLOCK_READ_COUNT 等,以?xún)?yōu)化數(shù)據(jù)庫(kù)性能。
  • 使用并行處理:對(duì)于大規(guī)模數(shù)據(jù)操作,可以考慮使用并行處理來(lái)提高性能和減少鎖的競(jìng)爭(zhēng)。

10. 定期維護(hù)

  • 定期分析和優(yōu)化:定期分析數(shù)據(jù)庫(kù)性能,找出瓶頸并進(jìn)行優(yōu)化。
  • 清理無(wú)用數(shù)據(jù):定期清理不再需要的數(shù)據(jù),減少表的大小,從而減少鎖的競(jìng)爭(zhēng)。

總結(jié)

通過(guò)上述步驟,可以有效地解決 Oracle 數(shù)據(jù)庫(kù)中的鎖表問(wèn)題,并找到引起鎖表的 SQL 語(yǔ)句。同時(shí),通過(guò)實(shí)施最佳實(shí)踐,可以顯著減少鎖表問(wèn)題的發(fā)生,提高系統(tǒng)的并發(fā)性能和穩(wěn)定性。

以上就是Oracle鎖表的解決方法及避免鎖表問(wèn)題的最佳實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于Oracle鎖表的解決及避免的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • oracle 11g數(shù)據(jù)庫(kù)安全加固注意事項(xiàng)

    oracle 11g數(shù)據(jù)庫(kù)安全加固注意事項(xiàng)

    這篇文章主要介紹了oracle11g數(shù)據(jù)庫(kù)安全加固須謹(jǐn)慎 ,需要的朋友可以參考下
    2015-08-08
  • Oracle rac環(huán)境的數(shù)據(jù)庫(kù)導(dǎo)入操作步驟

    Oracle rac環(huán)境的數(shù)據(jù)庫(kù)導(dǎo)入操作步驟

    Oracle RAC是一種基于共享存儲(chǔ)和共享數(shù)據(jù)庫(kù)的集群解決方案,可以將多個(gè) Oracle 數(shù)據(jù)庫(kù)實(shí)例連接成一個(gè)邏輯上的單一數(shù)據(jù)庫(kù),提供高可用性、靈活性和可伸縮性,本文給大家介紹Oracle rac環(huán)境的數(shù)據(jù)庫(kù)導(dǎo)入操作,感興趣的朋友一起看看吧
    2023-06-06
  • Oracle通過(guò)procedure調(diào)用webservice接口的全過(guò)程

    Oracle通過(guò)procedure調(diào)用webservice接口的全過(guò)程

    存儲(chǔ)過(guò)程是一組為了完成特定功能的sql語(yǔ)句集合,經(jīng)過(guò)編譯后存儲(chǔ)在數(shù)據(jù)庫(kù)中,用戶(hù)通過(guò)制定存儲(chǔ)過(guò)程的名字并給出參數(shù)(如果該過(guò)程帶有參數(shù))來(lái)執(zhí)行他,本文介紹了Oracle通過(guò)procedure調(diào)用webservice接口的全過(guò)程,需要的朋友可以參考下
    2024-07-07
  • 解析jdbc處理oracle的clob字段的詳解

    解析jdbc處理oracle的clob字段的詳解

    本篇文章是對(duì)jdbc處理oracle的clob字段進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • navicat導(dǎo)入oracle導(dǎo)出的dmp文件

    navicat導(dǎo)入oracle導(dǎo)出的dmp文件

    現(xiàn)在工作中常用Oracle數(shù)據(jù)庫(kù),但是查詢(xún)工具還是Navicat最好用,不論是數(shù)據(jù)導(dǎo)入導(dǎo)出,還是執(zhí)行語(yǔ)句,都很清晰明了,下面這篇文章主要給大家介紹了關(guān)于navicat導(dǎo)入oracle導(dǎo)出的dmp文件的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Oracle截取JSON字符串內(nèi)容的方法

    Oracle截取JSON字符串內(nèi)容的方法

    這篇文章主要介紹了Oracle截取JSON字符串內(nèi)容 ,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • oracle 存儲(chǔ)過(guò)程返回 結(jié)果集 table形式的案例

    oracle 存儲(chǔ)過(guò)程返回 結(jié)果集 table形式的案例

    這篇文章主要介紹了oracle 存儲(chǔ)過(guò)程返回 結(jié)果集 table形式的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Oracle監(jiān)控?cái)?shù)據(jù)庫(kù)性能的方法步驟

    Oracle監(jiān)控?cái)?shù)據(jù)庫(kù)性能的方法步驟

    監(jiān)控?cái)?shù)據(jù)庫(kù)性能是確保數(shù)據(jù)庫(kù)系統(tǒng)高效運(yùn)行并快速響應(yīng)用戶(hù)請(qǐng)求的關(guān)鍵步驟,有效的數(shù)據(jù)庫(kù)性能監(jiān)控可以幫助識(shí)別和解決性能瓶頸,預(yù)測(cè)潛在問(wèn)題,并優(yōu)化資源使用,以下是詳細(xì)的步驟和代碼示例,指導(dǎo)你如何監(jiān)控?cái)?shù)據(jù)庫(kù)性能,需要的朋友可以參考下
    2024-08-08
  • Oracle表空間大小如何查看及擴(kuò)增

    Oracle表空間大小如何查看及擴(kuò)增

    Oracle數(shù)據(jù)庫(kù)中,表空間是存儲(chǔ)數(shù)據(jù)對(duì)象的關(guān)鍵結(jié)構(gòu),管理表空間包括監(jiān)控其大小并根據(jù)需要進(jìn)行擴(kuò)展,以確保數(shù)據(jù)庫(kù)運(yùn)行高效,查看表空間大小,可以通過(guò)SQL查詢(xún)或使用Oracle Enterprise Manager,擴(kuò)展表空間的方法有手動(dòng)增加數(shù)據(jù)文件
    2024-10-10
  • Oracle(90)數(shù)據(jù)庫(kù)如何創(chuàng)建用戶(hù)(User)

    Oracle(90)數(shù)據(jù)庫(kù)如何創(chuàng)建用戶(hù)(User)

    這篇文章主要介紹了在Oracle數(shù)據(jù)庫(kù)中創(chuàng)建用戶(hù)的過(guò)程,包括連接到數(shù)據(jù)庫(kù)、創(chuàng)建用戶(hù)、分配權(quán)限、分配表空間和設(shè)置賬戶(hù)狀態(tài),提供了詳細(xì)的步驟和代碼示例,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12

最新評(píng)論