日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle:select 或 inactive 会话语句产生锁?

發布時間:2024/8/26 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle:select 或 inactive 会话语句产生锁? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近發生的幾起 enq: TX - row lock contention 等待事件很怪,通過 blocking session id 查看,不是語句是 select,就是會話是 inactive 的。

實驗

準備工作

  • 進入 hr 用戶,同時查看會話 id,下面會稱為?會話 38

    1

    2

    3

    4

    SQL>?select?userenv('sid')?from?dual;

    USERENV('SID')

    --------------

    ????????3

  • 創建測試表

    1

    create?table?emp_bak?as?select?*?from?employees

  • 創建被鎖會話,同時查看會話 id,下面會稱為?會話 28

    1

    2

    3

    4

    SQL>?select?userenv('sid')?from?dual;

    USERENV('SID')

    --------------

    ????????28

  • 測試

  • 會話 38 產生鎖操作,注意,此處不進行提交操作,且操作完不進行 exit 操作

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    SQL>?SELECT?employee_id,?first_name,?last_name,?salary

    ??2????FROM?emp_bak

    ??3???WHERE?employee_id?=?166;

    EMPLOYEE_ID?FIRST_NAME???????????? ?????LAST_NAME???????????????????? ????SALARY

    -----------?----------------------------------------?--------------------------------------------------?----------

    ????166?Sundar???????????? ?????Ande????????????????????? ??????6400

    SQL>?update?emp_bak

    ??2?????set?salary?=?salary?+?100

    ??3???where?employee_id?=?166;

    1?row?updated

  • 會話 28,為了區分操作語句,此處我們執行 delete 操作,此時會出現 hang,暫且不去管它

    1

    2

    SQL>?delete?from?emp_bak

    ??2???where?employee_id?=?166

  • 此時,我們新啟會話查一下鎖情況

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    col?event?for?a30

    col?username?for?a8

    col?process?for?a7

    col?machine?for?a7

    col?program?for?a30

    col?sql?for?a80

    SELECT?a.sid,

    ???????b.status,

    ???????b.event,

    ???????b.USERNAME,

    ???????b.PROCESS,

    ???????b.MACHINE,

    ???????b.program,

    ???????CASE

    ?????????WHEN?rawtohex(b.SQL_ADDRESS)?<>?'00'?THEN

    ??????????'CURR'

    ?????????ELSE

    ??????????'PREV'

    ???????END?STAT,

    ???????c.sql_text?"SQL"

    ??FROM?v$lock?a,?v$session?b,?v$sql?c

    ?WHERE?(a.id1,?a.id2)?IN?(SELECT?ID1,?ID2

    ????????????????????????????FROM?gv$lock

    ???????????????????????????WHERE?TYPE?=?'TX'

    ?????????????????????????????AND?request?>?0)

    ???AND?a.sid?=?b.sid

    ???AND?CASE

    ?????????WHEN?rawtohex(b.SQL_ADDRESS)?<>?'00'?THEN

    ??????????b.SQL_ADDRESS

    ?????????ELSE

    ??????????b.PREV_SQL_ADDR

    ???????END?=?c.address

    ???AND?CASE

    ?????????WHEN?b.SQL_HASH_VALUE?>?0?THEN

    ??????????b.SQL_HASH_VALUE

    ?????????ELSE

    ??????????b.PREV_HASH_VALUE

    END?=?c.hash_value;

    由于長時間未對數據庫進行操作,所以會話狀態為 INACTIVE 狀態,鎖的語句為 update

  • 那么此時,我們在會話 38 上執行 select 語句,查詢的狀態是怎樣的呢?

    1

    2

    3

    4

    5

    6

    SQL>?SELECT?employee_id,?first_name,?last_name,?salary

    ??2????FROM?emp_bak

    ??3???WHERE?employee_id?=?166;

    EMPLOYEE_ID?FIRST_NAME???????????? ?????LAST_NAME???????????????????? ????SALARY

    -----------?----------------------------------------?--------------------------------------------------?----------

    ????166?Sundar???????????? ?????Ande????????????????????? ??????6500

  • 我們此時可以再關聯 v$transaction,來查看具體信息

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    SELECT?a.sid,

    ???????b.status,

    ???????b.event,

    ???????b.USERNAME,

    ???????b.PROCESS,

    ???????b.MACHINE,

    ???????b.program,

    ???????CASE

    ?????????WHEN?rawtohex(b.SQL_ADDRESS)?<>?'00'?THEN

    ??????????'CURR'

    ?????????ELSE

    ??????????'PREV'

    ???????END?STAT,

    ???????c.sql_text?"SQL",

    ???????d.start_time,

    ???????d.status,

    ???????d.xid,

    ???????d.USED_UBLK,

    ???????d.USED_UREC

    ??FROM?v$lock?a,?v$session?b,?v$sql?c,?v$transaction?d

    ?WHERE?(a.id1,?a.id2)?IN?(SELECT?ID1,?ID2

    ????????????????????????????FROM?gv$lock

    ???????????????????????????WHERE?TYPE?=?'TX'

    ?????????????????????????????AND?request?>?0)

    ???AND?a.sid?=?b.sid

    ???AND?CASE

    ?????????WHEN?rawtohex(b.SQL_ADDRESS)?<>?'00'?THEN

    ??????????b.SQL_ADDRESS

    ?????????ELSE

    ??????????b.PREV_SQL_ADDR

    ???????END?=?c.address

    ???AND?CASE

    ?????????WHEN?b.SQL_HASH_VALUE?>?0?THEN

    ??????????b.SQL_HASH_VALUE

    ?????????ELSE

    ??????????b.PREV_HASH_VALUE

    ???????END?=?c.hash_value

    ???AND?rawtohex(d.addr(+))?=?b.taddr;

  • 結論

  • blocking session id 記錄的是誰鎖的自己

  • sqltext 記錄的是當前執行的語句,而并非是被哪句鎖住了

  • inactive 僅表示處于此狀態的會話沒有正在執行,但由于之前執行的語句,依然會產生鎖

  • v$transaction 可以獲取事務的狀態以及進度,重復查詢 USED_UBLK、USED_UREC 這兩個值,可以看到變化,可以估計事務的進度,尤其是長時間的回滾操作,當這兩個值為0,回滾也就完成了。

  • 總結

    以上是生活随笔為你收集整理的Oracle:select 或 inactive 会话语句产生锁?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。