Oracle數據庫進程之后臺進程詳解
上次我們介紹了:Oracle數據庫進程之服務器進程詳解,本文我們主要介紹一下Oracle數據庫的后臺進程的相關知識,我們知道,Oracle實例包括兩部分:SGA 和一組后臺進程。后臺進程執行保證數據庫運行所需的實際維護任務。
例如,有一個進程為我們維護塊緩沖區緩存,根據需要將塊寫出到數據文件。另一個進程負責當在線重做日志文件寫滿時將它復制到一個歸檔目標。另外還有一個進程負責在異常中止進程后完成清理,等等。每個進程都專注于自己的任務,但是會與所有其他進程協同工作。例如,負責寫日志文件的進程填滿一個日志后轉向下一個日志時,它會通知負責對填滿的日志文件進行歸檔的進程,告訴它有活干了。
可以使用一個V$視圖查看所有可能的Oracle 后臺進程,確定你的系統中正在使用哪些后臺進程:
- SQL> select paddr, name, descriptionfrom v$bgprocess order by paddr desc;
- PADDR NAME DESCRIPTION
- -------- ---------------------------------------------------------------------
- 3621D49C QMNC AQ Coordinator
- 3621CEE8 ARC2 Archival Process 2
- 3621C934 ARC1 Archival Process 1
- 3621C380 ARC0 Archival Process 0
- 3621A148 MMNL Manageability Monitor Process 2
- 36219B94 MMON Manageability Monitor Process
- 362195E0 CJQ0 Job Queue Coordinator
- 3621902C RECO distributed recovery
- 36218A78 SMON System Monitor Process
- 362184C4 CKPT checkpoint
- 36217F10 LGWR Redo etc.
- PADDR NAME DESCRIPTION
- -------- ---------------------------------------------------------------------
- 3621795C DBW0 db writer process 0
- 362173A8 MMAN Memory Manager
- 36216DF4 PSP0 process spawner 0
- 36216840 PMON process cleanup
- 00 DIAG diagnosibility process
- 00 FMON File Mapping Monitor Process
- 00 LMON global enqueue servicemonitor
- 00 LMD0 global enqueue servicedaemon 0
- .....
- 00 ASMB ASM Background
- 00 GMON diskgroup monitor
- 157 rows selected.
注意:這個視圖中PADDR 不是00 的行都是系統上配置和運行的進程(線程)。有兩類后臺進程:有一個中心(focused)任務的進程(如前所述)和完成各種其他任務的進程(即工具進程)。
例如,內部作業隊列( jobqueue)有一個工具后臺進程,可以通過DBMS_JOB 包使用它。這個進程會監視作業隊列,并運行其中的作業。在很多方面,這就像一個專用服務器進程,但是沒有客戶連接。
下面會分析各種后臺進程,先來看有中心任務的進程,然后再介紹工具進程。
中心后臺進程
圖5-4 展示了有一個中心(focused)用途的Oracle 后臺進程。
啟動實例時也許不會看到所有這些進程,但是其中一些主要的進程肯定存在。如果在ARCHIVELOG 模式下,你可能只會看到ARCn(歸檔進程),并啟用自動歸檔。如果運行了Oracle RAC,這種Oracle 配置允許一個集群中不同機器上的多個實例裝載并打開相同的物理數據庫,就只會看到LMD0、LCKn、LMON 和LMSn。
意為簡潔起見,圖5-4 中沒有畫出共享服務器調度器(Dnnn)和共享服務器(Snnn)進程。因此,圖5-4 大致展示了啟動Oracle 實例并裝載和打開一個數據庫時可能看到哪些進程。例如,在我的Linux 系統上,啟動實例后,有以下進程:
- [oracle@db1 ~]$ ps -ef|grep 'ora_.*_dave*'
- oracle 4123 1 0 20:13 ? 00:00:05 ora_pmon_dave1
- oracle 4125 1 0 20:13 ? 00:00:05 ora_psp0_dave1
- oracle 4127 1 0 20:13 ? 00:00:02 ora_mman_dave1
- oracle 4129 1 0 20:13 ? 00:00:05 ora_dbw0_dave1
- oracle 4131 1 0 20:13 ? 00:00:21 ora_lgwr_dave1
- oracle 4133 1 0 20:13 ? 00:00:13 ora_ckpt_dave1
- oracle 4135 1 1 20:13 ? 00:01:12 ora_smon_dave1
- oracle 4137 1 0 20:13 ? 00:00:04 ora_reco_dave1
- oracle 4139 1 0 20:13 ? 00:00:16 ora_cjq0_dave1
- oracle 4141 1 1 20:13 ? 00:01:33 ora_mmon_dave1
- oracle 4143 1 0 20:13 ? 00:00:08 ora_mmnl_dave1
- oracle 4145 1 0 20:13 ? 00:00:00 ora_d000_dave1
- oracle 4147 1 0 20:13 ? 00:00:00 ora_s000_dave1
- oracle 4156 1 0 20:13 ? 00:00:01 ora_arc0_dave1
- oracle 4158 1 0 20:13 ? 00:00:05 ora_arc1_dave1
- oracle 4163 1 0 20:14 ? 00:00:03 ora_qmnc_dave1
- oracle 4167 1 0 20:15 ? 00:00:24 ora_q000_dave1
- oracle 4169 1 020:15 ? 00:00:00 ora_q001_dave1
- oracle 5109 1 1 21:48 ? 00:00:00 ora_j000_dave1
- oracle 5141 5111 0 21:49 pts/4 00:00:00 grep ora_.*_dave2*
這些進程命名規則:進程名都以ora_開頭。后面是4 個字符,表示進程的具體名字,再后面是ORACLE_SID,(站點標識符)。
在UNIX 上,可以很容易地標識出Oracle后臺進程,并將其與一個特定的實例關聯(在Windows 上則沒有這么容易,因為在Windows 上這些后臺進程實際上只是一個更大進程中的線程)。
這些進程實際上都是同一個二進制可執行程序,對于每個“程序”,并沒有一個單獨的可執行文件。你可以盡可能地查找一下,但是不論在磁盤的哪個位置上肯定都找不到一個arc0 二進制可執行程序,同樣也找不到LGWR或DBW0。這些進程實際上都是oracle(也就是所運行的二進制可執行程序的名字)。它們只是在啟動時對自己建立別名,以便更容易地標識各個進程。這樣就能在UNIX 平臺上高效地共享大量對象代碼。Windows上就沒有什么特別的了,因為它們只是進程中的線程,因此,當然只是一個大的二進制文件。
自動存儲管理后臺(Automatic Storage Management Background,ASMB)進程:ASMB 進程在使用了ASM 的數據庫實例中運行。它負責與管理存儲的ASM 實例通信、向ASM 實例提供更新的統計信息,并向ASM 實例提供一個“心跳”,讓ASM 實例知道它還活著,而且仍在運行。
重新平衡(Rebalance,RBAL)進程:RBAL 進程也在使用了ASM 的數據庫實例中運行。向ASM磁盤組增加或去除磁盤時,RBAL 進程負責處理重新平衡請求(即重新分布負載的請求)。
以下進程出現在Oracle RAC 實例中。RAC 是一種Oracle 配置,即集群中的多個實例可以裝載和打開一個數據庫,其中每個實例在一個單獨的節點上運行(通常節點是一個單獨的物理計算機)。這樣,你就能有多個實例訪問(以一種全讀寫方式)同樣的一組數據庫文件。
RAC 的主要目標有兩個:
高度可用性:利用Oracle RAC,如果集群中的一個節點/計算機由于軟件、硬件或人為錯誤而失敗,其他節點可以繼續工作,還可以通過其他節點訪問數據庫。你也許會喪失一些計算能力,但是不會因此而無法訪問數據庫。
可擴縮性:無需購買更大的機器來處理越來越大的工作負載(這稱為垂直擴縮),RAC 允許以另一種方式增加資源,即在集群中增加更多的機器(稱為水平擴縮)。舉例來說,不必把你的4 CPU 機器擴縮為有8 個或16 個CPU,通過利用RAC,你可以選擇增加另外一個相對廉價的4 CPU機器(或多臺這樣的機器)。
以下進程是RAC 環境所特有的:
鎖監視器(Lockmonitor,LMON)進程:LMON 監視集群中的所有實例,檢測是否有實例失敗。這有利于恢復失敗實例持有的全局鎖。它還負責在實例離開或加入集群時重新配置鎖和其他資源(實例失敗時會離開集群,恢復為在線時又會加入集群,或者可能有新實例實時地增加到集群中)。
鎖管理器守護(Lockmanager daemon,LMD)進程:LMD 進程為全局緩存服務(保持塊緩沖區在實例間一致)處理鎖管理器服務請求。它主要作為代理(broker)向一個隊列發出資源請求,這個隊列由LMSn 進程處理。LMD 會處理全局死鎖的檢測/解析,并監視全局環境中的鎖超時。
鎖管理器服務器(Lockmanager server,LMSn)進程:前面已經提到,在一個RAC 環境中,各個Oracle 實例在集群中的不同機器上運行,它們都以一種讀寫方式訪問同樣的一組數據庫文件。為了達到這個目的,SGA 塊緩沖區緩存相互之間必須保持一致。這也是LMSn 進程的主要目標之一。在以前版本的Oracle 并行服務器(Oracle Parallel Server,OPS)中,這是通過ping實現的。也就是說,如果集群中的一個節點需要塊的一個讀一致視圖,而這個塊以一種獨占模式被另一個節點鎖定,數據的交換就要通過磁盤刷新輸出來完成(塊被ping)。如果本來只是要讀取數據,這個操作(ping)的代價就太昂貴了。現在則不同,利用LMSn,可以在集群的高速連接上通過非常快速的緩存到緩存交換來完成數據交換。每個實例可以有多達10 個LMSn 進程。
鎖(Lock,LCK0)進程:這個進程的功能與前面所述的LMD 進程非常相似,但是它處理所有全局資源的請求,而不只是數據庫塊緩沖區的請求。
可診斷性守護(Diagnosabilitydaemon,DIAG)進程:DIAG 只能用于RAC 環境中。它負責監視實例的總體“健康情況”,并捕獲處理實例失敗時所需的信息。
工具后臺進程
這些后臺進程全都是可選的,可以根據你的需要來選用。它們提供了一些工具,不過這些工具并不是每天運行數據庫所必需的,除非你自己要使用(如作業隊列),或者你要利用使用了這些工具的特性(如新增的Oracle 10g 診斷功能)。
在UNIX 中,這些進程可以像其他后臺進程一樣可見,如果你執行ps 命令,就能看到這些進程。
- [oracle@db1 ~]$ ps -ef|grep 'ora_.*_dave*'
- oracle 4123 1 0 20:13 ? 00:00:05 ora_pmon_dave1
- oracle 4125 1 0 20:13 ? 00:00:05 ora_psp0_dave1
- oracle 4127 1 0 20:13 ? 00:00:02 ora_mman_dave1
- oracle 4129 1 0 20:13 ? 00:00:05 ora_dbw0_dave1
- oracle 4131 1 0 20:13 ? 00:00:21 ora_lgwr_dave1
- oracle 4133 1 0 20:13 ? 00:00:13 ora_ckpt_dave1
- oracle 4135 1 1 20:13 ? 00:01:12 ora_smon_dave1
- oracle 4137 1 0 20:13 ? 00:00:04 ora_reco_dave1
- oracle 4139 1 0 20:13 ? 00:00:16 ora_cjq0_dave1
- oracle 4141 1 1 20:13 ? 00:01:33 ora_mmon_dave1
- oracle 4143 1 0 20:13 ? 00:00:08 ora_mmnl_dave1
- oracle 4145 1 0 20:13 ? 00:00:00 ora_d000_dave1
- oracle 4147 1 0 20:13 ? 00:00:00 ora_s000_dave1
- oracle 4156 1 0 20:13 ? 00:00:01 ora_arc0_dave1
- oracle 4158 1 0 20:13 ? 00:00:05 ora_arc1_dave1
- oracle 4163 1 0 20:14 ? 00:00:03 ora_qmnc_dave1
- oracle 4167 1 0 20:15 ? 00:00:24 ora_q000_dave1
- oracle 4169 1 020:15 ? 00:00:00 ora_q001_dave1
- oracle 5109 1 1 21:48 ? 00:00:00 ora_j000_dave1
- oracle 5141 5111 0 21:49 pts/4 00:00:00 grep ora_.*_dave*
CJQ0 和Jnnn 進程:作業隊列
在第一個7.0 版本中,Oracle 通過一種稱為快照(snapshot)的數據庫對象來提供復制特性。作業隊列就是刷新快照(或將快照置為當前快照)時使用的內部機制。
作業隊列進程監視一個作業表,這個作業表告訴它何時需要刷新系統中的各個快照。在Oracle 7.1中,Oracle 公司通過一個名為DBMS_JOB 的數據庫包來提供這個功能。所以,原先7.0 中與快照相關的進程到了7.1及以后版本中變成了“作業隊列”。后來,控制作業隊列行為的參數(檢查的頻度,以及應該有
多少個隊列進程)的名字也發生了變化,從SNAPSHOT_REFRESH_INTERVAL 和SNAPSHOT_REFRESH_PROCESSES變成了JOB_QUEUE_INTERVAL 和JOB_QUEUE_PROCESSES。在當前的版本中,只有JOB_QUEUE_PROCESSES 參數的設置是用戶可調的。
最多可以有1000 個作業隊列進程。名字分別是J000,J001,…,J999。這些進程在復制中大量使用,并作為物化視圖刷新進程的一部分。基于流的復制(Oracle9iRelease 2 中新增的特性)使用AQ 來完成復制,因此不使用作業隊列進程。
開發人員還經常使用作業隊列來調度一次性(后臺)作業或反復出現的作業,例如,在后臺發送一封電子郵件,或者在后臺完成一個長時間運行的批處理。通過在后臺做這些工作,就能達到這樣一種效果:盡管一個任務耗時很長,但在性急的最終用戶看來所花費的時間并不多(他會認為任務運行得快多了,但事實上可能并非如此)。這與Oracle 用LGWR 和DBWn 進程所做的工作類似,他們在后臺做大量工作,所以你不必實時地等待它們完成所有任務。
Jnnn 進程與共享服務器很相似,但是也有專用服務器中的某些方面。它們處理完一個作業之后再處理下一個作業,從這個意義上講是共享的,但是它們管理內存的方式更像是一個專用服務器(其UGA 內存在PGA 中,而不是在SGA 中)。每個作業隊列進程一次只運行一個作業,一個接一個地運行,直至完成。正因為如此,如果我們想同時運行多個作業,就需要多個進程。這里不存在多線程或作業的搶占。一旦運行一個作業,就會一直運行到完成(或失敗)。
你會注意到,經過一段時間,Jnnn 進程會不斷地來來去去,也就是說,如果配置了最多1 000 個Jnnn進程,并不會看到真的有1 000 個進程隨數據庫啟動。相反,開始時只會啟動一個進程,即作業隊列協調器(CJQ0),它在作業隊列表中看到需要運行的作業時,會啟動Jnnn 進程。如果Jnnn 進程完成其工作,并發現沒有要處理的新作業,此時Jnnn 進程就會退出,也就是說,會消失。因此,如果將大多數作業都調度為在凌晨2:00運行(沒有人在場),你可能永遠也看不到這些Jnnn 進程。
QMNC 和Qnnn:高級隊列
QMNC進程對于AQ 表來說就相當于CJQ0 進程之于作業表。QMNC 進程會監視高級隊列,并警告從隊列中刪除等待消息的“出隊進程”(dequeuer):已經有一個消息變為可用。QMNC和Qnnn 還要負責隊列傳播(propagation),也就是說,能夠將在一個數據庫中入隊(增加)的消息移到另一個數據庫的隊列中,從而實現出隊(dequeueing)。
Qnnn 進程對于QMNC 進程就相當于Jnnn 進程與CJQ0 進程的關系。QMNC 進程要通知Qnnn 進程需要完成什么工作,Qnnn 進程則會處理這些工作。
QMNC 和Qnnn 進程是可選的后臺進程。參數AQ_TM_PROCESSES 可以指定最多創建10 個這樣的進程(分別名為Q000,…,Q009),以及一個QMNC 進程。如果AQ_TM_PROCESSES 設置為0,就沒有QMNC或Qnnn 進程。
不同于作業隊列所用的Jnnn進程,Qnnn 進程是持久的。如果將AQ_TM_PROCESSES 設置為10,數據庫啟動時可以看到10 個Qnnn 進程和一個QMNC 進程,而且在實例的整個生存期中這些進程都存在。
EMNn:事件監視器進程(Event Monitor Process)
EMNn進程是AQ 體系結構的一部分,用于通知對某些消息感興趣的隊列訂購者。通知會異步地完成。
可以用一些Oracle 調用接口(Oracle Call Interface,OCI)函數來注冊消息通知的回調。回調是OCI 程序中的一個函數,只要隊列中有了訂購者感興趣的消息,就會自動地調用這個函數。EMNn 后臺進程用于通知訂購者, 第一次向實例發出通知時會自動啟動EMNn 進程。然后應用可以發出一個顯式的message_receive(dequeue)來獲取消息。
MMAN:內存管理器(Memory Manager)
這個進程是Oracle 10g 中新增的,自動設置SGA 大小特性會使用這個進程。MMAN 進程用于協調共享內存中各組件(默認緩沖區池、共享池、Java 池和大池)的大小設置和大小調整。
MMON、MMNL 和Mnnn:可管理性監視器(Manageability Monitor)
這些進程用于填充自動工作負載存儲庫(Automatic WorkloadRepository,AWR),這是Oracle 10g中新增的一個特性。
MMNL進程會根據調度從SGA 將統計結果刷新輸出至數據庫表。
MMON進程用于“自動檢測”數據庫性能問題,并實現新增的自調整特性。 Mnnn 進程類似于作業隊列的Jnnn 或Qnnn 進程;MMON 進程會請求這些從屬進程代表它完成工作。Mnnn 進程本質上是臨時性的,它們將根據需要來來去去。
CTWR:修改跟蹤進程(Change Tracking Process)
這是Oracle 10g 數據庫中新增的一個可選進程。CTWR 進程負責維護新的修改跟蹤文件。
RVWR:恢復寫入器(Recovery Writer)
這個進程也是Oracle 10g 數據庫中新增的一個可選進程,負責維護閃回恢復區中塊的“前”映像,要與FLASHBACKDATABASE 命令一起使用。
其他工具后臺進程
還有另外一些工具進程沒有列出。例如,Oracle Data Guard 有一組與之相關的進程,有利于將重做信息從一個數據庫移送到另一個數據庫,并應用這些重做信息。還有一些進程與Oracle 10g 新增的數據泵工具有關,在某些數據泵操作中會看到這些進程。另外還有一些流申請和捕獲進程。不過,以上所列已經基本涵蓋了你可能遇到的大多數常用的后臺進程。
關于Oracle數據庫進程之后臺進程的相關知識就介紹到這里了,希望本次的介紹能夠對您有所收獲!
【編輯推薦】