oracle數據庫內核,深入內核:Oracle數據庫里SELECT操作Hang解析

0f99d913a52f477e9d5fe5a590e652b9.png

崔華,網名 dbsnake

Oracle ACE Director,ACOUG 核心專家

編輯手記:感謝崔華授權我們獨家轉載其精品文章,也歡迎大家向“Oracle”社區投稿。

我們都知道在?Oracle?數據庫里是“讀不阻塞寫,寫不阻塞讀”,那么是否可以認為在正常情況下,select?操作是怎樣都能執行,始終不會被?hang?住的呢?注意這里提到的是正常情況下,不包括那些由于?latch?被?hold?住、或者?bug?等相關異常導致的?select?操作 hang?住的情況。

答案是:不可以這樣認為的。

我們來舉一個反例。

首先我們來分析一下在?sql?硬解析時在相關表對象上?library cache lock?的持有情況。這里我用到了10049事件,用10049事件,最重要的就是要知道如何設置它所對應的?level?值。

10049的level值可能會有如下一些組合:

a95c8d411d706223e2d7464d05a7b8d1.png

這里因為我要跟蹤?sql?硬解析時相關表對象的?library cache lock?的持有情況,所以這里level?值取0x0210=0x0200|0x0010,即這里?level?值取528。

SQL> select to_number(‘210′,’XXXX’)

from dual;

c84b839815a16e97681504ab7c24a7f0.png

先在11.2.0.1里使用一下10049事件:C:\Documents and Settings\cuihua>sqlplus /nolog

SQL*Plus: Release 11.2.0.1.0 Production on星期三?6月?27 21:39:37 2012

Copyright (c) 1982, 2010, Oracle.??All rights reserved.

SQL> conn / as sysdba;

已連接。

SQL> oradebug setmypid

已處理的語句

SQL> oradebug event 10049 trace

name context forever,level 528

已處理的語句

SQL> select count(*) from scott.emp;

COUNT(*)

———-

14

SQL> oradebug tracefile_name

c:\app\cuihua\diag\rdbms\cuihua112\

cuihua112\trace\cuihua112_ora_2292.trc

這個TRACE文件沒有任何內容,看起來似乎是10049事件對11gR2無效或者?Oracle?改變了10049事件在11gR2中的?level?的定義(這個我不確定)。

我們換一個10gR2的版本:

SQL> select * from v$version;

8f8abe59cdb6a987f18537c7fa64a62d.pngSQL> oradebug setmypid

已處理的語句

SQL> oradebug event 10049 trace

name context forever,level 528

已處理的語句

SQL> select count(*) from scott.emp;

COUNT(*)

———-

13

SQL> oradebug tracefile_name

d:\oracle\admin\cuihua\udump\cuihua_ora_5012.trc

從上述?trace?文件(d:\oracle\admin\cuihua\udump\cuihua_ora_5012.trc)中從前到后可以看到如下內容:

fabc847b667bef200fab11bf2104728a.png

9fdaac74a286105087b271641f0f3186.png

即針對上述?cursor?是以?NULL?模式持有?library cache lock,

針對表?scott.emp?是以?share?模式持有?library cache lock。

也就是說,只要我事先以?exclusive?模式在表?scott.emp上持有?library cache lock,那么后續的以硬解析方式執行的針對該表的所有sql(包括?select?語句)都將被?hang?住。

現在我們來測一下對一個表增加一個主鍵時的?library cache lock?的持有情況。SQL> create table t2 as select * from emp;

Table created

SQL> select count(*) from t2;

COUNT(*)

———-

13

SQL> conn / as sysdba;

已連接。

SQL> oradebug setmypid

已處理的語句

SQL> oradebug event 10049 trace name

context forever,level 528

已處理的語句

SQL> alter table scott.t2 add constraint PK_T2

primary key (EMPNO);

表已更改。

SQL> oradebug tracefile_name

d:\oracle\admin\cuihua\udump\cuihua_ora_6120.trc

從這個trace文件(d:\oracle\admin\cuihua\udump\cuihua_ora_6120.trc)中我們可以看出對表t2的?library cache lock?的先后持有模式為:

17583f74bf7cff3216d591f0d1c113fa.png

4f1994ffa808ce683ef2a6b87aea24a5.png

cf1e5732c7229a54aef9e4a2d6e1cd6a.png

即大部分時間?library cache lock?的持有模式都是N,只有在一頭一尾的時候才是X。

但請注意這種情況下?select?操作是會被hang住的。

因為一開頭的X是?kglget,結尾才?kgllkdl(kgllkdl大致是?kgl lock delete?的意思,表示釋放相應的?library cache lock),并且它們的?KGL Lock addr?相同:

38f74ef20a795d0205ecaca09fd9822e.png

這也就意味著在添加主鍵的整個過程中,Oracle始終會以?exclusive?模式在表?scott.t2?上持有?library cache lock,直到最后主鍵添加完畢了才釋放。

所以在?win32上的10.2.0.1中,在添加主鍵的過程中會一直阻塞查詢(select)操作。

我們來測一下,同時開3個session。

Session 1:SQL> create table t3(id number);

Table created

SQL> declare

2????i number;

3??begin

4????for i in 1..3000000 loop

5?????insert into t3 values (i);

6????end loop i;

7????commit;

8??end;

9??/

PL/SQL procedure successfully completed

Session 2:SQL> select * from v$mystat

where rownum<2;

fcc2910a93464f35c208211620ba502a.png

在?session 1中開始執行添加主鍵操作:Session 1:

SQL> alter table scott.t3 add constraint PK_T3 primary key (id);

……開始執行

轉到?session 2執行查詢操作:

Session 2:SQL> select * from t3

where rownum<10;

……這里?hang?住了

轉到?session 3并執行對?session2的等待事件的查詢:

Session 3:SQL> select t.event,t.state,t.seconds_in_wait

from v$session t

where sid=138;

d276d78a405cbebd3514f870c80bc21d.png

從中可以看到?session 2在等待?library cache lock,同時它的STATE為waiting,SECONDS_IN_WAIT的值在遞增。

這就驗證了我們的結論:在?win32上的10.2.0.1中,在對表增加主鍵的過程中會一直阻塞對這個表的查詢(select)操作。

現在我們再問一個問題:是不是所有對表的DDL操作,在DDL操作的執行過程中都會阻塞對這個表的select操作?

答案是:不是這樣的。

我們來舉一個反例。

現在我們來測一下對表?drop一個column?時?library cache lock?的持有情況:

SQL> desc t1;

6a35ff9cff7d34b6235fd6a59613c1fc.png

SQL> select count(*) from t1;

76123178585220601b35c8cfe89a5c53.png

同時開兩個session。

在session 1中打開10049事件后drop表t1的列object_type:

Session 1:SQL> conn / as sysdba;

已連接。

SQL> oradebug setmypid

已處理的語句

SQL> oradebug event 10049 trace

name context forever,level 528

已處理的語句

SQL> alter table scott.t1 drop

column OBJECT_TYPE;

表已更改。

SQL> oradebug tracefile_name

d:\oracle\admin\cuihua\udump\

cuihua_ora_5020.trc

session 2在?session 1執行?drop column?操作的同時查詢表t1,結果是?select?操作并沒有被?hang?住,且能看到正在被?drop?的列?object_type:

Session 2:

SQL> select owner,object_name,object_type

from t1

where rownum<10;

9b371ac9dc15a151ab08d7e199393291.png

從?session 1所產生的?trace?文件

(d:\oracle\admin\cuihua\udump\cuihua_ora_5020.trc)中我們可以看出對表t1的?library cache lock?的先后持有模式為:

b9a84453c4cdd5e8a4fc9146f833bf18.png

即大部分時間對表?scott.t1?的?library cache lock?的持有模式都是S,最后才是X,所以這就可以解釋為什么在對表?scott.t1?執行?drop column?操作的時候對它的select語句能夠同時執行。

從?trace?文件來看,drop column?并不是不會阻塞?select?操作,只是阻塞的時間點要恰好是Oracle以X模式持有library cache lock時。

最后我們來測一下對一個表增加一個?unique constraint時library cache lock的持有情況SQL> conn / as sysdba;

已連接。

SQL> oradebug setmypid

已處理的語句

SQL> oradebug event 10049 trace

name context forever,

level 528

已處理的語句

SQL> alter table scott.t2 add constraint UK_T2_EMPNO

unique (EMPNO, ENAME);

表已更改。

SQL> oradebug tracefile_name

d:\oracle\admin\cuihua\udump\cuihua_ora_5240.trc

從這個trace文件中我們可以看出對表?scott.t2?的?library cache lock?的先后持有模式為:

a2bf0870fdfd6c08f6389e1c8a8e69c7.png

f049c59e9e00d930309b42ff67e67ba1.png

即大部分時間都是N,一頭一尾才是X,這個和添加主鍵操作一樣,在此不再贅述。

結論:不要隨便在生產環境對大表執行DDL操作(如添加唯一性約束等),可能會導致針對這個表的所有?sql(包括select操作)在執行DDL操作的時間段都?hang?住。如何加入"云和恩墨大講堂"微信群

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529349.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle 如何形成死鎖,Oracle數據表中的死鎖情況解決方法

在進行數據庫管理的過程中,經常會出現數據表被用戶的一些不合理操作而導致表被鎖定的情況,以下主要介紹如何查找哪些表被哪個用戶所鎖定,以及如何解除鎖定:1.查找被鎖定的表:select object_name,session_id,os_user_name,oracle_username,process,locked_mode,statusfrom v$loc…

php 分布式數據庫查詢,分布式數據庫 · Thinkphp5.0完全開發手冊 · 看云

# 分布式數據庫ThinkPHP內置了分布式數據庫的支持&#xff0c;包括主從式數據庫的讀寫分離&#xff0c;但是分布式數據庫必須是相同的數據庫類型。配置database.deploy 為1 可以采用分布式數據庫支持。如果采用分布式數據庫&#xff0c;定義數據庫配置信息的方式如下&#xff1…

matlab 電力系統動態仿真,基于Matlab的電力系統動態仿真分析

本文通過兩個簡單實例介紹了利用 !"#$"% &’(! )*, -./對電力系統進行仿真研究的方法! 包括"熱工自動調節控制系統的仿真分析和電力電器系統的仿真分析# 0 熱工調節控制系統仿真分析 對熱工調節控制系統的性能分析包括靜態特性和動態特性兩個方面# 這里主要…

oracle read by other session,AWR報告中,read by other session ,如何解決?

你看你的top sql里全是動態采樣的sql&#xff0c;默認10g以后optimizer_dynamic_sampling參數為level 2&#xff0c;一般為缺失統計信息會造成每次使用動態采樣&#xff0c;雖然動態采樣會在表頻繁發生大批量改變時&#xff0c;一般可以生成更好的執行計劃&#xff0c;但是也不…

oracle insert into as select,比較create table as select * 與 insert into table select *

實驗環境&#xff1a;SYSaaron> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionPL/SQL Release 11.2.0.1.0 - ProductionCORE …

unix 安裝oracle,linux上安裝Oracle

當前位置:我的異常網 Linux/Unix linux上安裝Oraclelinux上安裝Oraclewww.myexceptions.net 網友分享于&#xff1a;2013-09-03 瀏覽&#xff1a;26次linux下安裝Oracle1.Linux下安裝 jdk(Linux)建議從sun的主頁上下載bin文件,運行后在/usr/會建立好java目錄的Linux下相關命…

linux ftp用戶指定多個目錄,linux ftp服務器下用戶限制目錄的方法

我們使用服務器都要站在安全方面進行考慮&#xff0c;有必要將ftp服務下的用戶限制在適當的范圍內&#xff0c;那么linux ftp服務器下用戶限制目錄的方法有哪些呢?一起跟著愛站技術頻道小編的步伐來了解一下吧!linux ftp服務器下用戶只能在自己目錄下的方法&#xff1a;第一步…

查找空目錄Linux,Linux中find批量刪除空文件及空文件夾腳本

find . -name "*" -type f -size 0c | xargs -n 1 rm -f #linux下批量刪除空文件(大小等于0的文件)刪除指定大小的文件&#xff0c;只要修改對應的 -size 參數就行&#xff1a;find . -name "*" -type f -size 1024c | xargs -n 1 rm -f #刪除1k大小的文件…

linux關閉timewait端口,linux 如何強制關閉 time_wait 連接

匿名用戶1級2016-04-16 回答# netstat -an|awk /tcp/ {print $6}|sort|uniq -c68 CLOSE_WAIT2 CLOSING136 ESTABLISHED38 FIN_WAIT116 FIN_WAIT22 LAST_ACK8 LISTEN71 SYN_RECV2936 TIME_WAIT#狀態&#xff1a;描述CLOSED&#xff1a;無連接是活動的或正在進行LISTEN&#xff1…

memset頭文件 linux,error: ‘memset’ was not declared in this scope

http://blog.sina.com.cn/s/blog_79d599dc0100r2vz.html昨天一同事把代碼準備重新全新布置到新的環境上去的時候&#xff0c;代碼報錯了&#xff0c;先開始報錯如下&#xff1a;error: ‘memset’ was not declared in this scopeerror: ‘strcat’ was not declared in this s…

linux中ls文件內存大小,Linux下用ls和du命令查看文件以及文件夾大小

webdriver零碎知識點#零碎知識點,用于記錄平時遇到的比較雜的知識點 driver.current_url 獲取當前url phantomjs 實現無瀏覽器界面自動化測試(driver webdriver.Phanto ...ORACLE刪除當前用戶下所有的表的方法1.如果有刪除用戶的權限,則可以: drop user user_name cascade; 加…

linux物理內存地址與iomem,一種Linux系統物理內存鏡像文件分析方法_4

模塊信息&#xff0c;如圖7所示&#xff0c;給出了本發明的實施例中 模塊結構關系圖&#xff0c;modules變量指向某一個已加載模塊結構體module地址&#xff0c;所有已加載模 塊其module形成一個雙向鏈表&#xff0c;如圖7所示&#xff0c;據此可以獲取到所有已加載模塊。[0099…

linux設備分層優點,Linux設備驅動的分層設計思想

代碼清單8第2行獲取platform_data&#xff0c;而platform_data實際上是定義GPIO按鍵硬件信息的數組&#xff0c;第31行的for循環工具這些信息申請GPIO并初始化中斷&#xff0c;對于LDD6140電路板而言&#xff0c;這些信息如代碼清單10。代碼清單10 LDD6410開發板GPIO按鍵的plat…

linux 關閉桌面環境,Ubuntu 14.04上的Cinnamon桌面環境PPA被關閉

今天Cinnamon桌面環境的開發者宣布關閉Cinnamon桌面環境的PPA&#xff0c;這意味著以后在Ubuntu上安裝Cinnamon桌面環境將變得很難。關于為什么要關閉PPA&#xff0c;Cinnamon PPA的維護者Gwendal Le Bihan做出了以下解釋&#xff1a;“穩定的Cinnamon PPA將不再提供&#xff0…

linux sd卡讀寫出錯,linux系統SD卡讀寫問題

請教有過linux系統SD卡讀寫經驗的前輩。我的項目是對FPGA上的SD卡部分做測試&#xff0c;在測試過程中發現在對SD卡所有領域進行讀寫操作時1、bus width 選擇1-bit的速度4-bit是差不多的&#xff0c;這與我預想的不同&#xff0c;想知道問題出在哪里?(理論上4bit 速度應該是1-…

genymotion linux 32,Ubuntu Linux 32bit - 不是Genymotion虛擬設備

因為4天我沒有找到解決方案我的genymotion有問題 我正在使用Ubuntu 12.04 32位(architecure&#xff1a;i686)并安裝android studio并將genymotion的插件放入其中succefully ......現在我的問題&#xff0c;當點擊genymotion設備管理器&#xff0c;列表是空的&#xff0c;當我試…

grub linux rootfs,rootfs文件系統(筆記)(草稿)

文件系統簡介文件系統就是個軟件&#xff0c;幫用戶來管理一些二進制的信息&#xff0c;管理外存上存儲的這些二進制各種文件在內存中都是以二進制的形式來存在的&#xff0c;如果沒有文件系統&#xff0c;用戶就需要自己去決定這些二進制的東西是什么&#xff0c;需要自己去和…

linux 如何查看屬性,linux?下查看系統屬性

linux 下查看系統屬性(2009-06-28 19:01:34)標簽&#xff1a;linux雜談分類&#xff1a;OSlinux下查看系統屬性1、查看cpu信息查看所有cpu信息&#xff1a;cat /proc/cpuinfo查看cpu類型&#xff1a; grep "model name" /proc/cpuinfo2、查看內存信息&#xff1a;查看…

幼兒學數數的c語言程序,【資源學習】c語言程序代碼,登錄幼兒園200個小朋友的數據...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓編寫程序&#xff0c;登錄幼兒園200個小朋友的數據&#xff1a;姓名、性別、年齡、身高、體重、出生日期&#xff0c;分別按年齡排序后輸出。要求&#xff1a;(1)登錄數據用函數input()(2)按身高排序用函數sort()(3)輸出排序結果用…

c語言傳入參數不正確,請高手看看一下程序怎么回事啊?老是提示傳參數錯誤...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#includevoid main(){ void average(float, int);void search(float,int);static float score[][4]{{65,67,70,60},{80,87,90,81},{99,90,100,98}};average(score,12);search(score,2);}void average(float *p,int n){float *p_end…