Oracle sql語句執行過程圖文分析


這個可以算是學習筆記吧, 是參照甲骨論老相老師的視頻做的:

http://www.jiagulun.com/thread-2674-1-1.html

1.數據庫文件
Oracle 數據庫文件大概可分為3種,分別是:
控制文件(control files): 存放數據庫本身物理結構信息
數據文件(data files): 存放數據庫數據啦~
日志文件(log files):  包括重做日志文件和歸檔日志文件, 記錄數據庫數據的變化.
如下圖:
 

2.數據庫實例

       但是用戶和應用程序是無法直接訪問數據庫文件的數據的, 這時Oracle服務器會啟動1(或多個..RAC集群啦)個實例.,用戶可以通過連接這個實例來訪問數據庫的數據.

       實例有兩個組成部分,分別是:
        系統全局內存區(SGA):服務器專門划分給Oracle實例使用的內存塊啦.
        Oracle進程: 包括服務器進程和后台進程, 后面會解析嘎啦.

2.1 系統全局內存區(SGA)
      
SGA可以分成6大塊,分別是 Java pool, shared pool, database buffer cache,large pool, streams pool, Redo log buffer
       注: 可用 v$sga這個視圖去查看sga各大塊大小.

       這篇文章介紹的是sql語句的執行流程,所以主要講解其中的3個大塊:
        共享緩沖區(shared pool)
       數據庫緩沖高速緩存(database buffer cache)
       重做日志緩沖區(redo log buffer)

       
     
         如下圖:

 
 
2.2
服務器進程
     當用戶(客戶端)要連接Oracle數據庫時, Oracle就會創建1個session(會話),並且在 服務器上創建1個專門處理這個session的進程,就是服務器進程啦.

如下圖


注意啊, 每當1個新用戶創建1個新的連接到數據庫,Oracle都會對應創建1條服務器進程的.


2.3 PGA(Program Global Area) 中文自己翻譯啦~

        對應上面的Server Process, Oracle會在服務器上對每一條Server Process分配一定大小的內存,就是PGA了, 注意有幾個session就會有幾個對應的SGA塊, 所以服務器對內存需求很大的啦~

可以用
select sum(pga_userd_mem) from v$process
語句來查看當前使用的總PGA大小.
如圖:



3.客戶端與服務器的SQL語句傳輸
     這時,用戶在客戶端輸入若干條SQL語句,例如1個普通的存儲過程,有讀和寫的動作.

     這條語句通過什么來傳輸呢,答案就是session啦,  那么服務器上用什么來接受這個sql語句呢,答案就是Server Process啊:

如圖:



server process會判斷sql語句是否合法(語法,權限)

  如果sql語法有錯,或者對應的表或視圖或Procedure沒有權限,就會直接返回錯誤信息啦,這個大家都懂的. 


2/3.server process根據sql語句生成執行計划(execute plan).

      Oracle是無法直接執行sql語句的,必須先生成執行計划,然后Oracle就會根據執行計划去執行了.
      而生成執行計划要訪問許多數據庫對象, 是1個比較消耗服務器資源(CPU,IO,Memory)的動作.

      而且因為同一條sql語句可能會有多個用戶多次重復的執行, 那么是否每次都生成一次執行計划呢?
     這時SGA里面的Shared pool就發揮作用了,說白了它會緩存sql的執行計划..

    所以server process會首先從Shared pool里面查找有無現成的執行計划, 如果有就直接采用.
   如果無, 就自己生成1個,然后看情況把這個執行計划放入shared pool.



server process根據執行計划 去取()數據.
       好了 當server process得到執行計划后就可以去取數據了.
       Oracle的數據放在哪里呢, 放在數據文件,這個大家都懂,但是server process是不是就直接去訪問數據文件呢?

      因為計算機的時間消耗主要都在物理IO,所以要盡量避免物理讀寫,所以SGA里面的database buffer cache起作用了.
      說明白點, database buffer cache就是用來緩沖Data files里的數據的.  這樣就可以避免了對數據文件的讀寫.

      所以server process得到執行計划后,第一步是首先去database buffer cache去找有沒有現成的數據. 如果有最好, 如果無或者緩存中數據不全的話就只能去訪問data files啦.  

      從data files獲得數據后, 也不是直接發給用戶客戶端,而是根據情況放入database buffer cache里面, 以便當前或其他用戶2次使用啦.



6.邏輯讀,物理讀與緩存命中率.
          由上圖得知,所謂 邏輯讀,就是從緩存(一般是內存)里讀取數據啦.  而 物理讀,也就是從磁盤(數據文件)里讀取數據啦.

          至於緩存命中率,就是取出數據的過程中     邏輯讀次數/ (邏輯讀次數+物理讀次數) 這個比率.

          當然這個比率越接近1越好, 因為物理讀相當費時間啦, 機械硬盤瓶頸嘛~ 除非有服務器用SSD做硬盤...無咩可能啦~

          當然命中率並不是數據庫健康的唯一指標,因為當邏輯讀十分巨大的時候, 即使物理讀也很大,這個比率也很好看的, 所以有時要關心 每秒物理讀(tps).

          可以在linux下使用iostat命令來查看當前磁盤的每秒物理讀啦~

8.  在緩存中修改數據.
       server process拿出數據放入緩存中,接下來就對數據進行修改啦.
       因為修改數據很可能會產生大量緩沖數據,所以這個動作實在Database buffer cache里完成的. 這個很容易理解.



9.  修改數據會產生重做日志.
       上面提到,日志是用來記錄數據庫的數據變化的,所以對數據改動產生一定量的日志數據.  那么這些日志是不是直接就寫到日志文件中呢.

       寫日志文件也是物理讀,所以SGA就有個Redo log buffer,就是日志緩存啦, 專門實時存放產生的日志數據啦~


10.  最終Server Process把返回數據或信息通過session傳回給用客戶端
      
Server Process 做完讀取和修改數據的動作后,就會將結果返給用戶了.



11.將數據緩存和日志緩存寫入磁盤 
        其實到上面那一步為止,  整個sql語句執行流程已經完成了.
        可能有人會問, Server process修改的數據和產生的日志還在SGA里面啊, 它們不用被寫入磁盤嗎?

        答案是肯定需要的, 但是這些動作已經不是sql執行流程之內, 而且這些動作也不是server process負責的, 他們分別由 DBWR 和  LGWR 這個兩個進程負責.

如圖:


DBWR:  Database writer,后台進程之一,負責將Database buffer cache里被修改的數據寫入數據文件.
LGWR:   Log writer,后台進程之一,負責將Redo log buffer里的日志數據寫入到日志文件.


12.為什么Oracle要將server process 和后台進程分開?

       如上圖,為什么寫入數據文件和日志文件要交給后台進程去完成呢.
       其實我們在流程可以發現, 服務器與用戶打交道的就只有1個進程,就是Server Process啊,  所以server Process的速度直接影響了用戶的感受, 無論后台進程多么繁忙,只要server process響應迅捷, 用戶還是覺得數據庫很快的. 相反,后台進程沒事做,服務器CPU很空閑, 但server process反應慢的話, 用戶就覺得數據庫慢了.

      所以就要盡量精簡server process的動作,  看看后台進程DBWR 和 LGWR進行的是什么動作, 磁盤寫動作啊! 呢個仲慢過物理讀啊.所以這些動作完全可以在sql流程執行完慢慢來嘛.

        Server Process唯一進行的物理操作就是物理讀,  這個是無辦法避免的, 因為數據都在磁盤上嘛... 除非有辦法預測用戶要提取的數據,提前拿出來.但也沒有那么大的內存啊.


13.順便介紹其余3大系統進程CKPT,SMON,PMON
都說Oracle有SGA6大池 3大數據庫文件, 5大系統進程.

其中DBWR 和 LGWR上面已經介紹過了. 現在其余3個

CKPT : Checkpoint  檢查點進程,負責更新控制文件和數據文件的頭部信息,  控件文件在這篇blog開頭就已經介紹過啦,至於數據文件的頭部信息?  頭部信息就是當前數據塊的狀態信息啦.

SMON :  system monitor 系統監視器, 負責監視維護SGA和后台進程啦,例如合並SGA里面的碎片.
PMON :  process monitor  進程監視器,  這里主要指服務器進程啦,例如一個用戶突然掉線了,但是該服務器進程還在服務器,Pmon會隔一段時間把該進程清理掉並且釋放SGA啦.




結束
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM