標籤:style blog http color os 使用 java io strong
[原文連結] http://nvd11.blog.163.com/blog/static/200018312201301310585758/
[原文視頻] 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。
:
4. server process 會判斷 sql 語句是否合法(文法,許可權)。如果 sql 文法有錯,或者對應的表或視圖或 Procedure 沒有許可權,就會直接返回錯誤資訊啦。
5. server process根據 sql 語句產生執行計劃(execute plan).
Oracle 是無法直接執行 sql 語句的,必須先產生執行計畫,然後 Oracle 就會根據執行計畫去執行了。而產生執行計畫要訪問許多資料庫物件, 是一個比較消耗伺服器資源(CPU,IO,Memory)的動作。
而且因為同一條 sql 語句可能會有多個使用者多次重複的執行, 那麼是否每次都產生一次執行計畫呢? 這時 SGA 裡面的 Shared pool 就發揮作用了,它會緩衝 sql 的執行計畫。
所以 server process 會首先從 Shared pool 裡面尋找有無現成的執行計畫, 如果有就直接採用。如果無, 就自己產生一個,然後看情況把這個執行計畫放入shared pool。
6. 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 裡面, 以便當前或其他使用者多次使用啦。
7. 邏輯讀、物理讀與快取命中率.
由得知,所謂
邏輯讀,就是從緩衝(一般是記憶體)裡讀取資料。而
物理讀,也就是從磁碟(資料檔案)裡讀取資料啦。
至於快取命中率,就是取出資料的過程中 邏輯讀次數/ (邏輯讀次數+物理讀次數) 這個比率。當然這個比率越接近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 和後台進程分開?
為什麼寫入資料檔案和記錄檔要交給後台進程去完成呢? 其實我們在流程可以發現, 伺服器與使用者打交道的就只有一個進程,就是Server Process, 所以 server Process 的速度直接影響了使用者的感受。無論後台進程多麼繁忙,只要 server process 響應迅捷, 使用者還是覺得資料庫很快的。 相反,後台進程沒事做,伺服器 CPU 很空閑,但 server process 反應慢的話, 使用者就覺得資料庫慢了。
所以就要盡量精簡 server process 的動作, 看看後台進程 DBWR 和 LGWR 進行的是什麼動作, 磁碟寫動作啊! 所以這些動作完全可以在sql流程執行完慢慢來嘛。
Server Process 唯一進行的物理操作就是物理讀, 這個是無辦法避免的, 因為資料都在磁碟上嘛。除非有辦法預測使用者要提取的資料,提前拿出來。但也沒有那麼大的記憶體啊。
13. 順便介紹其餘3大系統進程 CKPT, SMON, PMON
都說 Oracle 有 SGA 6 大池,3 大資料庫檔案, 5 大系統進程。其中DBWR 和 LGWR上面已經介紹過了。剩下其餘3個:
CKPT : Checkpoint 檢查點進程,負責更新控制檔案和資料檔案的頭部資訊, 控制項檔案在這篇blog開頭就已經介紹過啦。至於資料檔案的頭部資訊就是當前資料區塊的狀態資訊啦。
SMON : system monitor 系統監視器,負責監視維護 SGA 和後台進程啦,例如合并SGA裡面的片段。
PMON : process monitor 進程監視器, 這裡主要指伺服器處理序啦。例如一個使用者突然掉線了,但是該伺服器處理序還在伺服器,Pmon會隔一段時間把該進程清理掉並且釋放SGA 啦。
最後感謝老相老師用心做的教學視頻, 真的很通俗易懂, 截個圖。哈哈
[轉] Oracle sql 語句執行過程圖文分析