【Oracle DB】インスタンスとは

## はじめに

  Oracle の理解を深めるうえで欠かせない **インスタンス** についてまとめてみます。  

  Oracle DBの根幹のようなもので、DBA Silverでも最重要な要素といっても過言ではないと思うので、取りこぼしの無いようまとめてみますね。

使用している参考書は[オラクルマスター教科書 Silver DBA Oracle Database Administration I](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E6%95%99%E7%A7%91%E6%9B%B8-Silver-Oracle-Database-Administration/dp/4798166359/ref=pd_lpo_d_sccl_1/355-4986059-0425665?pd_rd_w=WbxbD&content-id=amzn1.sym.855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_p=855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_r=4J3P9MW23BE4XKRFSPJ2&pd_rd_wg=11F4O&pd_rd_r=e6f6c7fc-b54a-4766-8d44-4c192520cfa7&pd_rd_i=4798166359&psc=1)です。
  今回もここからまとめさせていただいております。
  
  ※誤りありましたら、ご指摘いただけますと幸いです。

## インスタンスとは
  簡単に言うと **Oracleの処理を担う常駐部分** のことを指します。
  構成要素としては、データベースを管理・操作するためのメモリ構造である **SGA（システムグローバル領域）** とプロセスの集合体である **バックグラウンドプロセス** で構成されています。 

  簡単な構成図としては下記のようになります。 

![instance.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715906/2d645fc1-0632-466e-6033-bc0c092523e8.jpeg)

  
  本旨とは外れるので細かい説明は割愛しますが、**SGA** ではDBの読み込みを効率化するためのキャッシュ機能、書き込みを効率化するためのバッファ機能、変更履歴を保持するREDOログ機能があります。

  **バックグラウンドプロセス** はOracle DBの裏方のような機能を担い、例えば上記でキャッシュしたデータの書き込みを行う **DBWn（データベースライター）** やREDOデータをファイルとして書き出す **LGWR（ログライター）** があったりします。その他にもインスタンスやセッションが異常終了した時に、よしなに色々やってくれる、まさしく縁の下の力持ちのような役割を担っています。

  データベースファイル内にも色々と細かい構成があるのですが、我々が想像する、いわゆるデータ本体が入っている箱だと思ってもらえればＯＫです。
  
  例外の構成もあるんですが、基本的に「インスタンス」と「データベースファイル」は1対1で対応しています。



### インスタンスの起動
  インスタンスの起動は「startup」コマンドを使用します。
  インスタンスの起動にはフェーズがあり、大きく分けて下記の4ステップに分かれます。

  1. **SHUTDOWN**
  名前からもわかるように、インスタンスは停止しており、DBもまだ起動していない状態です。
  もちろんファイルの読み込み等も行われていません。

  2. **NOMOUNT**
  **「初期化パラメータファイル」**の読み込みが行われ、インスタンスが起動します。
  インスタンスが起動したということはこの時点でSGAが割り当てられ、バックグラウンドプロセスも起動します。
  ちなみに、DBはまだOPENしておらず、この時点ではまだデータファイルにはアクセスできません。
  ※初期化パラメータファイルとは、インスタンスの動作特性を指定できる初期化パラメータが格納されているファイルです。

  3. **MOUNT**
  **制御ファイル** の読み込みが行われ、制御ファイルへの読み書きが可能になります。
  この段階でもDBはまだOPENしておらず、データファイルにはアクセスできません。
  ※制御ファイルとは、DBの構成情報、管理情報が書かれているファイルです。

  4. **OPEN**
  データファイル、REDOログファイルが読み込まれ、ここで初めてDBがオープンします。
  この段階になってはじめて、一般ユーザがデータファイルにアクセスできるようになります。

#### 注意点
- OPEN以外の3フェーズでは、管理権限のあるユーザのみしかアクセスできません。
- NOMOUNT状態ではデータベースの作成（CREATE DATABASE）、制御ファイルの作成（CREATE CONTROLFILE）を行う事が出来ます。（MOUNT状態では制御ファイルが読み込まれるのでその前のフェーズで作成を行う）
- MOUNT状態ではアーカイブログモードへの変更、DB全体のリカバリ処理を行う事ができます。
- 各ファイルの読み込みに障害が発生した場合、そのステップでインスタンスの起動処理が停止します。（初期化パラメータファイルの読み込みに失敗すればOPENで停止、制御ファイルの読み込みに失敗すればNOMOUNTで停止というような形）
  

## インスタンスの停止
  インスタンスの停止は「SHUTDOWN」コマンドを使用します。
  インスタンスの停止にはオプションを指定でき、下記4オプションを指定できます。

  1. **NORMAL**
  全てのユーザの接続が終了されるまで待機して、インスタンスの停止を行います。
  1つでも接続が残っている場合は、インスタンスは終了されません。

  2. **TRANSACTIONAL**
  実行中のトランザクションが終了するのを待機して、インスタンスの停止を行います。
  1つでも実行中のトランザクションがある場合は、インスタンスは終了されません。
  ※トランザクション ＝ 一連の変更処理を1つのまとまりとして扱い、変更途中で中途半端な状態が発生しないようにするための機能。

  3. **IMMEDIATE**
  実行中の処理を取り消したうえで、インスタンスの停止を行います。
  実行中のトランザクションは取り消し（ロールバック）されます。

  4. **ABORT**
  実行中の取り消し処理を行うことなく、即座にインスタンスの停止を行います。
  OSレベルでプロセスをKILLすることと同等なので、日常的には行いません。

#### 注意点
- ABORT以外の3オプションではチェックポイントと呼ばれる処理が実行されるので、データは整合性は維持されます。（ちなみにチェックポイントはバックグラウンドプロセスの一つで、DBWnに対して、キャッシュされたデータの書き込みを行うよう指示を出す役割を担います）




## （補足）管理情報の確認 
  Oracle DBの管理情報を確認するには、ビュー（仮想表）である **データディクショナリビュー** と**動的パフォーマンスビュー** が存在します。

  これらはSQL用いてアクセスが可能であり、似ている部分も多いのですが、以下の点で異なります。

  1. **ビュー名**
  データディクショナリビューは「DBA_」「ALL_」「USER_」で始まります。
  動的パフォーマンスビューは「V$」から始まります。

  2. **データの格納先**
  データディクショナリビューはデータディクショナリに格納されます。
  動的パフォーマンスビューはインスタンス（SGA）または制御ファイルに格納されます。

  3. **データの読み取り一貫性**
  データディクショナリビューは一貫性が保証されます。（元となるデータがデータファイルに格納されているため）
  動的パフォーマンスビューは一貫性が保証されません。（元となるデータがデータファイルに格納されていないため）

  4. **参照可能な起動状態**
  データディクショナリビューはOPEN状態でのみアクセス可能です。
  動的パフォーマンスビューはNOMOUNT、またはMOUNT状態でアクセス可能です。

#### 理解するために
一見覚えることが多いように思えますが、例えば3の読み取り一貫性について。

**データディクショナリビュー** に格納されているデータディクショナリはデータファイルに格納されているわけですから、一貫性がない状態では存在してはいけないはずです。

一方で**動的パフォーマンスビュー** は、元となるデータはインスタンス（SGA）や制御ファイルは上記で示した図にもあるように、データファイルに格納されていないため一貫性は保証できません。

また、4の参照可能な起動状態についても、 **データディクショナリビュー** に格納されているデータディクショナリはデータファイルに格納されているわけですから、OPEN状態でないとアクセスできないことは自明です。

一方で **動的パフォーマンスビュー** は、インスタンス（SGA）や制御ファイルにアクセスできればいいわけですから、インスタンス（SGA）にアクセスするならNOMOUNT状態、制御ファイルをにアクセスするならMOUNT状態で事足りることが分かるはずです。
  

## 最後に
  上記でも書いたように一見覚えることが多いように思えますが（めちゃくちゃ多いことには間違いないのですが）、理解が深まってくると繋がりが見えてきて、論理的に理解できる部分が増えてくるのがOracle DBAの面白い部分だと思ってます。

  DBの構成は共通している部分も多いので、Oracleを通して学んだことは他のDBでも引用できる部分もあると感じているので、引き続き理解を深められるよう頑張りたいです。（ちなみに今週土曜が試験本番なのであと少し追い込み頑張ります）