プロセス構成について

  1. oracle のプロセス概要
  2. oracle のプロセス相関図


oracle のプロセス概要

oracle には、以下のプロセスがあり、 それぞれが機能してデータベースを管理しています。

これらのプロセスは、sqlplus が init${ORACLE_SID}.ora の情報をもとに起動します。
oracle 8i よりほとんどのプロセスは、マルチスレッド構成です。
( OS レベルのマルチスレッド。MTS とは全く異なります)

プロセス名名前 機          能必須
oracle<SID> 専用サーバ データベースに接続し、要求を処理する
tnslsnr リスナー ネットワークを介しての oracle への要求を受け付ける
ora_dbwN データベース・ライタ 変更されたデータをデータベースに書き込む( 3秒間隔)
ora_lgwr REDO ログ・ライタ REDO ログバッファに登録された変更履歴をファイルに記録する
ora_ckpt チェックポイント データベースを変更する時、変更情報を更新する
ora_smon システム・モニタ データベースオープン時、一貫性を調べ、回復する
ora_pmon プロセス・モニタ プロセスが異常終了した時、それが使用していたリソースを制御する
ora_arcN アーカイバ REDO ログ・ファイルをアーカイブする *1
ora_iXNN_<SID> I/O スレーブ I/O 用スレーブプロセス
X=(1:DBWR 2:LGWR 3:ARCH 4:BACKUP)
*2
ora_reco リカバラ 分散トランザクションでの障害を自動解決する *3
ora_snpN スナップショット 表のスナップショットを自動的にリフレッシュします *3
ora_pNNN パラレル問い合わせサーバ パラレル問い合わせを処理するサーバ *3
ora_dNNN ディスパッチャ データベース接続を共用サーバに振り分ける *4
ora_sNNN 共用サーバ データベースに接続し、要求を処理する *4
ora_lckN ロック・プロセス 内部インスタンスをロック管理する *5
ora_lmdN ロック・マネージャ リモート・ロック要求処理を行う *5
ora_lmon ロック・モニタ グローバル・ロックに関連した回復処理をする *5
ora_qmnc AQ Coordinator QMN コーディネータープロセス *6
ora_qNNN Queue Slave QMN スレーブプロセス(旧 QMNn) *6
ora_mman Memory manager SGA メモリマネージャ *6
ora_rvwr Recovery Writer Flashback Database 用 *6
ora_ctwr Change Tracking Writer RMAN 用プロセス *6
ora_mmnl Memory Monitor Light AWR 機用プロセス *6
ora_mmon Memory Monitor AWR 用プロセス *6

ここで N は、1 〜 9 までの数字です。
*1 ARCHIVELOG モードで REDO ログを使ってかつ自動アーカイブの場合のみ
*2 DBWR_IO_SLAVES で0以外を指定した場合
*3 分散オプション
*4 MTS(Multi Thread Server) のみ
*5 OPS(Oracle Parallel Server) のみ
*6 oracle 10g からのプロセス




プロセスの相関図

  1. テスト環境と方法
  2. sqlplus での接続

テスト環境と方法

サイドホスト名 ORACLE_SID リスナーポートMTS リスナーポート
クライアント macA ora816

DB サーバmacNNN ora817 1530 2481
DB サーバmacMM ora816 1527 10817


クライアント
[macA816]

tnsnames.ora
macNNN817 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = macNNN)(PORT = 2481))
    (CONNECT_DATA = (SID = ora817))
  )

macNNN817d =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = macNNN)(PORT = 1530))
    (CONNECT_DATA = (SID = ora817)(SERVER = dedicated))
  )

ora816ipc =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(HOST = macA)(KEY = IPCTEST))
    )
    (CONNECT_DATA = (SID = ora816))
  ) 

サーバ
[macA816]

listener.ora
LISTENER816=
  (ADDRESS_LIST=
     (ADDRESS=(PROTOCOL=TCP)(HOST=macA)(PORT=1551))
     (ADDRESS=(PROTOCOL=IPC)(HOST=macA)(KEY=IPCTEST))
  )

SID_LIST_LISTENER816=
  (SID_LIST=
    (SID_DESC =
      (GLOBAL_DBNAME=ora816.macA.XXX.YYY.co.jp)
      (ORACLE_HOME=/home12/ora816/app/oracle/product/8.1.6)
      (SID_NAME=ora816)
    )
 ) 

サーバ
[macA:ora817]

listener.ora
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = macA)(PORT = 1530))
      )
  )
) 

サーバ
[macA:ora817]

initora817.ora
mts_servers =1
mts_max_servers = 2
mts_dispatchers = "(PROTOCOL=TCP)(DISPATCHERS=1)"
mts_max_dispatchers = 2
local_listener = "(ADDRESS=(PROTOCOL=TCP)(HOST=macA)(PORT=1530))"
    

クライアント
[macA:ora817]

tnsnames.ora
macA817S =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = macA)(PORT = 1530))
    )
    (CONNECT_DATA =
       (SID = ora817)(SERVER=SHARED)
    )
  )
    

各例の図の ⇔|⇔ は、ネットワーク接続を意味し、 ここでパケットを取得しました。




sqlplus での接続

  1. sqlplus での専用サーバ接続
    1. sqlplus から接続文字列で別のマシンに接続する場合
    2. sqlplus からデータベースリンクで別のマシンに接続する場合
  2. sqlplus での MTS サーバ接続
    1. sqlplus から MTS サーバ (oracle 8i) に接続する場合
    2. sqlplus からポート指定の MTS サーバ (oracle 8i) に接続する場合
    3. sqlplus から MTS サーバ (oracle 9i) に接続する場合
  3. sqlplus から IPC で自マシンに接続する場合
    1. sqlplus から ipc で 専用サーバに接続する場合
    2. sqlplus から ipc で MTS サーバに接続する場合




sqlplus での専用サーバ接続

  1. sqlplus から接続文字列で別のマシンに接続する場合

    > sqlplus taka/taka@macNNN817d
    

    macA:ora816 macNNN:ora817
    クライアント ポート DB サーバ データベース
    sqlplus ⇔|⇔ 1530 tnslsnr
    code 表


    fork

    ⇔|⇔ 1530 oracleora817

    ↑↓


    SGA



    ↑↓


    ora_dbw0_ora817





  2. sqlplus からデータベースリンクで別のマシンに接続する場合

    sqlplus taka/taka                macA:ora816
    SQL> create database link macNNN817d connect to taka
      2> identified by taka using 'macNNN817d';
    SQL> select * from code@macNNN817d;
    

    macA:ora816 macNNN:ora817
    クライアント ポート DB サーバ データベース
    sqlplus



    code 表
    fork




    oracleora816 ⇔|⇔ 1530 tnslsnr


    fork

    ⇔|⇔ 1530 oracleora817


    ↑↓



    SGA




    ↑↓



    ora_dbw0_ora817





sqlplus での MTS サーバ接続

  1. sqlplus から MTS サーバに接続する場合

    > sqlplus scott/tiger@macNNN817
    

    macA:ora816 macNNN:ora817
    クライアント ポート ポート DB サーバ データベース
    sqlplus 32625 ⇔|⇔ 2481 tnslsnr
    port 変更 2481



    code 表







    32625 ⇔|⇔ 2481 ora_d000_ora817    ora_s000_ora817



    ↑↓

    ↑↓





    SGA





    ↑↓






    ora_dbw0_ora817

    ディスパッチャ (ora_d000_ora817) がクライアントからの要求を受け取り、 SGA 内のバーチャルサーキットの要求キューにそれを書き、 MTS サーバ (ora_s000_ora817) をキックします。 MTS サーバはバーチャルサーキットの要求キューから要求を受け取り、 結果を SGA のバーチャルサーキットの出力キューに残します。 これをディスパッチャが読み、クライアントに渡します。





  2. sqlplus からポート指定の MTS サーバに接続する場合

     macMM : initORA816.ora 
    
    mts_dispatchers="(ADDRESS=(PROTOCOL=TCP)(port=8171))"
    mts_dispatchers="(ADDRESS=(PROTOCOL=TCP)(port=8172))"
    mts_dispatchers="(ADDRESS=(PROTOCOL=TCP)(port=8173))"
    mts_max_dispatchers = 3
    mts_max_servers = 5
    local_listener = "(address=(protocol=tcp)(host=macMM)(port=10817))"
    
     macMM : listener.ora 
    
    LISTENERmts =
      (ADDRESS_LIST =
          (ADDRESS= (PROTOCOL= TCP)(Host= macMM)(Port= 10817))
      )
    
    SID_LIST_LISTENERmts =
      (SID_LIST =
        (SID_DESC =
          (ORACLE_HOME= /home3/ora816/app/oracle/product/8.1.6)
          (SID_NAME = ora816)
        )
      )
    

    >  sqlplus taka/taka@macMM816mts
    

    macA:ora816 macMM:ora816
    クライアント ポート ポート DB サーバ データベース
    sqlplus 64789 ⇔|⇔ 10817 tnslsnr
    port 変更 8172



    code 表







    64790 ⇔|⇔ 8172 ora_d000_ora816    ora_s000_ora816



    ↑↓

    ↑↓





    SGA





    ↑↓






    ora_dbw0_ora816





sqlplus から IPC で自マシンに接続する場合

IPC で接続する場合は UNIX Domain socket を使います。 今回は oracle 9.2.0.5 でテストしました。
solaris の場合、/var/tmp/.oracle/ の下にファイルとして作ります。 (その他の UNIX では /tmp/.oracle です)

sock のファイル名は tnslsnr の場合は "s" に続けて listener.ora の protocol=ipc で指定した KEY がつきます。 これらの sock は、tnslsnr 起動時に作られます。

一旦作成し connect()/accept() で新しいファイルデスクリプタを取得すると、 そのデスクリプタを使って read(),write() でお互いにデータをやりとりできます。

クライアント
[mac:ora92032]

tnsnames.ora
ora92032_ipc =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = IPC)(KEY = TAKA_IPC))
    (CONNECT_DATA = (SID = ora92032))
  )

ora92032_dipc =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = IPC)(KEY = mac_ipc))
    (CONNECT_DATA = (SID = ora92032))
    (SERVER = SHARED)
  ) 
サーバ
[mac:ora92032]

initora92032.ora
*.dispatchers='(ADDRESS=(PROTOCOL=TCP)(HOST=mac))(dispatchers=7)',
*.dispatchers='(ADDRESS=(PROTOCOL=IPC)(key=mac_ipc))(dispatchers=1)'
*.max_dispatchers=8
*.mts_max_servers=2
*.mts_servers=1 
サーバ
[mac:ora92032]

listener.ora
LISTENER_ipc =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = TAKA_IPC))
      )
    )
 )

SID_LIST_LISTENER_ipc =
 (SID_LIST =
  (SID_DESC =
   (ORACLE_HOME = /home06/ora92032/app/oracle/product/9.2.0)
   (SID_NAME = ora92032)
  )
 )

LISTENER_dipc =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = mac_ipc))
      )
SID_LIST_LISTENER_dipc =
 (SID_LIST =
  (SID_DESC =
   (ORACLE_HOME = /home06/ora92032/app/oracle/product/9.2.0)
    (SID_NAME = ora92032)
  )
) 

  1. sqlplus から ipc で 専用サーバに接続する場合

    sock は、UNIX Domain socket です。 はじめに sqlplus と tnslsnr との間のやりとりで、/var/tmp/.oracle/sTAKA_IPC という名前の UNIX Domain socket 名をもらいます。
    次に sqlplus は専用サーバの UNIX Domain socket 名で socket をオープンし、 専用サーバとやり取りします。

    > sqlplus scott/tiger@ora92032_ipc
    

    mac:ora92032
    クライアント側 sock sock DB サーバ側 データベース
    sqlplus sTAKA_IPC ←→ sTAKA_IPC tnslsnr
    code 表



    fork

    sTAKA_IPC ←→ sTAKA_IPC oracleora92032



    ↑↓




    SGA





    ↑↓



    ora_dbw0_ora92032




  2. sqlplus から ipc で MTS サーバに接続する場合

    > sqlplus scott/tiger@ora92032_dipc
    

    sock は、UNIX Domain socket で solaris の場合、/var/tmp/.oracle/ の下に作られます。
    はじめに sqlplus と dispatcher との間で、/var/tmp/.oracle/smac_ipc という名前の socket を使って、やり取りします。

    mac:ora92032
    クライアント sock sock DB サーバ データベース
    sqlplus smac_ipc ←→ smac_ipc ora_d007_ora92032
    ora_s000_ora92032 code 表



    ↑↓
    ↑↓




    SGA





    ↑↓





    ora_dbw0_ora92032

    以下は、各プロセスのシステムコールのトレースです。

    sqlplus : 12=/var/tmp/.oracle/smac_ipc
    16967:  execve("/home06/ora92032/app/oracle/product/9.2.0/bin/sqlplus", 0xFFBEF2E4, 0xFFBEF2F0)  argc = 2
      :
    16967:  access("/var/tmp/.oracle", 0)                   = 0
    16967:  so_socket(1, 2, 0, "", 1)                       = 12
    16967:  access("/var/tmp/.oracle/smac_ipc", 0)          = 0
    16967:  connect(12, 0xFFBE73A0, 110, 1)                 = 0
    16967:  fcntl(12, F_SETFD, 0x00000001)                  = 0
      :
    16967:  write(12, "\0C2\0\001\0\0\001 801 ,".., 194)    = 194
    16967:  brk(0x00233A30)                                 = 0
    16967:  brk(0x00235A30)                                 = 0
    16967:  read(12, "\0  \0\002\0\0\001 8\b01".., 4112)    = 32
    16967:  getpid()                                        = 16967 [16966]
    16967:  write(12, "\09C\0\006\0\0\0\0\0DEAD".., 156)    = 156
    16967:  read(12, "\07F\0\006\0\0\0\0\0DEAD".., 4112)    = 127
      :
    16967:  write(12, "\0\n\0\006\0\0\0\0 @", 10)           = 10
    16967:  close(12)                                       = 0
    16967:  sigaction(SIGINT, 0xFFBEB5A0, 0xFFBEB6CC)       = 0
    16967:  close(9)                                        = 0
    16967:  close(10)                                       = 0
    16967:  close(7)                                        = 0
    16967:  close(8)                                        = 0
    16967:  close(3)                                        = 0
    16967:  close(4)                                        = 0
    16967:  close(5)                                        = 0
    16967:  close(6)                                        = 0
    16967:  llseek(0, 0, SEEK_CUR)                          = 14355
    16967:  _exit(0)
    
    ora_d007_ora92032 : 13=UDP localhost:51911 14/15=/var/tmp/.oracle/smac_ipc 
    16820:  poll(0x030EC60C, 2, 60000)      (sleeping...)
    16820:  poll(0x030EC60C, 2, 60000)                      = 1
    16820:  getsockname(14, 0xFFBEDA24, 0xFFBEDA94, 1)      = 0
    16820:  accept(14, 0xFFBEDA24, 0xFFBEDA94, 1)           = 15
      :
    16820:  read(15, "\0C2\0\001\0\0\001 801 ,".., 32783)   = 194
    16820:  ioctl(15, FIONBIO, 0xFFBEDF78)                  = 0
    16820:  write(15, "\0  \0\002\0\0\001 8\b01".., 32)     = 32
      :
    16820:  poll(0x030EC60C, 3, 60000)                      = 1
    16820:  read(15, "\0  \0\006\0\0\0\0\00106".., 4112)    = 32
    16820:  sendto(13, " P", 1, 0, 0x030ECD58, 16)          = 1
    16820:  poll(0x030EC60C, 3, 60000)                      = 1
    16820:  read(13, " P", 2000)                            = 1
    16820:  write(15, "0103\0\006\0\0\0\0\00106".., 259)    = 259
      :
    16820:  read(15, "\0\n\0\006\0\0\0\0 @", 4112)          = 10
    16820:  sigprocmask(SIG_BLOCK, 0xFFBEE024, 0x00000000)  = 0
    16820:  setitimer(ITIMER_REAL, 0xFFBEDFAC, 0x00000000)  = 0
    16820:  sigprocmask(SIG_UNBLOCK, 0xFFBEE024, 0x00000000) = 0
    16820:  ioctl(15, FIONBIO, 0xFFBEDE60)                  = 0
    16820:  close(15)                                       = 0
    16820:  poll(0x030EC60C, 2, 60000)      (sleeping...)
    
    ora_s000_ora92032 : 13=UDP localhost:51903 
    16804:  poll(0x03165004, 1, 30000)      (sleeping...)
    16804:  poll(0x03165004, 1, 30000)                      = 1
    16804:  read(13, " P", 2000)                            = 1
    16804:  sendto(13, " P", 1, 0, 0x03165750, 16)          = 1
      :
    16804:  sendto(13, " P", 1, 0, 0x03165750, 16)          = 1
    16804:  poll(0x03165004, 1, 30000)      (sleeping...)