Oracle Clusterwareの起動の流れを追ってみました
この記事は、JPOUG Advent Calendar 2025 16日目の記事です。
15日目は せいげん さんの記事「お勉強のためにBaseDBでDataGuardの手動作成を頑張ってみた #oracle - Qiita」でした。
今年はOracle RACの接続ロード・バランシングの検証結果について書こうと思いましたが、やっぱりOracle Clusterwareの起動の流れについて書くことにしました。
参画中の案件でOracle Clusterwareが起動しないトラブルがあり、「データベースの起動の流れは理解しているが、Oracle Clusterwareの起動の流れは理解しきれていない」と感じたのがきっかけでした。
過去にもOracle Clusterwareの構成や起動の流れ(概要レベル)を調査したことがあったのですが、今回は実際の設定ファイルやログを確認しながらOracle Clusterwareの起動の流れを追ってみました。
よろしくお願いいたします。
Oracle Clusterwareは主にクラスタリソースの状態管理や監視、ノード間のメンバーシップ管理を行うクラスタウェアになります。
RACデータベースを構築する際に必要なOracle Grid Infrastructure製品の一部のコンポーネントになります。
Oracle Clusterwareの構成
12c(12.1)になりますが、全体的なクラスタリソースの構成は下記のようになります。

Oracle Clusterwareの起動の流れ(概要)
ざっくりですが、Oracle Clusterwareの起動の流れは下記のようになります。

Oracle Clusterwareの起動の流れ(詳細)
Oracle Clusterwareを起動する際、各デーモンが読み込むファイルは下記のようになります。

①OHASDがOLRからローカルノードの構成情報を取得し、Oracle Clusterwareスタック(GPNPD/CSSD/ASM/CRSD/EVMD)を起動する
②GPNPDがGPnPプロファイルからクラスタの構成情報を取得し、CRSスタック(CSSD/ASM/CRSD/EVMD)に提供する
③CSSDがGPnPプロファイルから投票ディスクの場所を取得・検索し、投票ディスクと通信を開始する(この時点でノードがクラスタに参加する)
④ASMがGPnPプロファイルからASMディスクの場所/ASM SPFILEの場所を取得し、ASMインスタンスを起動する
⑤CRSDが共有ディスクからOCRを参照して、クラスタリソース(SCAN、VIP、リスナーなど)を起動する
※EVMDは図に書いていませんが、ノードの起動/停止などOracle Clustwerware内部のイベントを管理するデーモンです。
※⑤はCSSDがCRSDと通信できる状態になった後に実施されます。
今回はクラスタを起動したときの設定ファイルやログを確認してみました。
検証環境

前提
・SCAN未使用
検証手順/検証ログ
1. 設定ファイル確認
各ノードでクラスタを起動する前に各種設定ファイルの中身を確認してみます。
・OLR(ローカルレジストリ)
OLRの場所はOracle Grid Infrastructureインストール時に生成される「/etc/oracle/olr.loc」、または「ocrcheck -local -config」で確認できます。
※下記はノード1の実行結果
[root@rac1 ~]# cat /etc/oracle/olr.loc
olrconfig_loc=/u01/app/12.1.0/grid/cdata/rac1.olr
crs_home=/u01/app/12.1.0/grid
[root@rac1 ~]# /u01/app/12.1.0/grid/bin/ocrcheck -local -config
Oracle Local Registry configuration is :
Device/File Name : /u01/app/12.1.0/grid/cdata/rac1.olr
OLRの中身はキーと値のペアのツリー構造になっており、「ocrdump -local」で確認できます。
膨大すぎて全部は載せれないですが、OHASスタック(OHAS Agent/CSSDMONITORなど)、GPnP、ノード固有の情報も記載されていました。
このことからOLRはOHASスタックの管理に必要な情報が記載されていることが分かります。
※下記はノード1の実行結果
(中略)
[SYSTEM.OHASD.SERVERS.rac1.CONFIG]
ORATEXT : ACTIVE_POOLS=Free ~INCARNATION=0~NAME=rac1~NODEID=0~PREV_ACTIVE_POOLS=Free ~STARTUP_FLAG=0~STATE=2~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
[SYSTEM.OHASD.SERVERS.rac1.INTERNAL]
ORATEXT : ACTIVE_CSS_ROLE=hub~CONFIGURED_CSS_ROLE=hub~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
(中略)
・GPnPプロファイル
クラスタ情報(ClusterUId、ClusterName)、ネットワーク情報(public、cluster_interconnect)、ストレージ情報(投票ディスク/ASMディスクの探索パス、ASM SPFILEの場所)が記載されていました。
「CSS-Profile」の「DiscoveryString="+asm"」はCSSDはASMから投票ディスクを探すという意味になります。
「ASM-Profile」の「DiscoveryString="/dev/oraasm*"」はASMディスクの探索パスで、「SPFile」はASMインスタンスを起動するためのASM SPFILEになります。
なお、ログはノード1の実行結果ですが、ノード2、ノード3も中身はノード1と同じでした。
※下記はノード1の実行結果
<?xml version="1.0" encoding="UTF-8"?>
<gpnp:GPnP-Profile Version="1.0" xmlns="http://www.grid-pnp.org/2005/11/gpnp-profile" xmlns:gpnp="http://www.grid-pnp.org/2005/11/gpnp-profile" xmlns:orcl="http://www.oracle.com/gpnp/2005/11/gpnp-profile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.grid-pnp.org/2005/11/gpnp-profile gpnp-profile.xsd" ProfileSequence="6" ClusterUId="80df78a6d825df5efffed9678520875a" ClusterName="rac-cluster" PALocation="">
<gpnp:Network-Profile>
<gpnp:HostNetwork id="gen" HostName="*">
<gpnp:Network id="net1" IP="192.168.56.0" Adapter="eth0" Use="public"/>
<gpnp:Network id="net2" IP="192.168.10.0" Adapter="eth1" Use="cluster_interconnect"/>
</gpnp:HostNetwork>
</gpnp:Network-Profile>
<orcl:CSS-Profile id="css" DiscoveryString="+asm" LeaseDuration="400"/>
<orcl:ASM-Profile id="asm" DiscoveryString="/dev/oraasm*" SPFile="+CRS/rac-cluster/ASMPARAMETERFILE/registry.253.1217937371" Mode="legacy"/>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
(中略)
</ds:Signature>
</gpnp:GPnP-Profile>
・OCR(クラスタレジストリ)
OCRの場所はOracle Grid Infrastructureインストール時に生成される「/etc/oracle/ocr.loc」、または「ocrcheck -config」で確認できます。
※下記はノード1の実行結果
[root@rac1 ~]# cat /etc/oracle/ocr.loc
#Device/file +CRS getting replaced by device +CRS/rac-cluster/OCRFILE/registry.255.1217937373
ocrconfig_loc=+CRS/rac-cluster/OCRFILE/registry.255.1217937373
local_only=false
[root@rac1 ~]# /u01/app/12.1.0/grid/bin/ocrcheck -config
Oracle Cluster Registry configuration is :
Device/File Name : +CRS
OCRの中身はキーと値のペアのツリー構造になっており、「ocrdump」で確認できます。
膨大すぎて全部は載せれないですが、Oracle Clusterwareスタック(CSSD/CRSD/EVMDなど)、データベース、ASM、ノードアプリケーションの情報も記載されていました。
このことからOCRはクラスタリソースの管理に必要な情報が記載されていることが分かります。
※下記はノード1の実行結果
(中略)
[SYSTEM.CRSD12.SERVERS.rac1.CONFIG]
ORATEXT : ACTIVE_POOLS=Generic ora.ORCL ~INCARNATION=659365055~NAME=rac1~NODEID=1~PREV_ACTIVE_POOLS=~STARTUP_FLAG=0~STATE=2~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
[SYSTEM.CRSD12.SERVERS.rac1.INTERNAL]
ORATEXT : ACTIVE_CSS_ROLE=hub~CONFIGURED_CSS_ROLE=hub~CPU_CLOCK_RATE=3192~CPU_COUNT=4~CPU_EQUIVALENCY=1000~CPU_HYPERTHREADING=0~DEPLOYMENT=other~MEMORY_SIZE=3953~PHYSICAL_HOSTNAME=~RESOURCE_USE_ENABLED=1~SERVER_LABEL=~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
(中略)
[SYSTEM.CRSD12.SERVERS.rac2.CONFIG]
ORATEXT : ACTIVE_POOLS=Generic ora.ORCL ~INCARNATION=659365056~NAME=rac2~NODEID=2~PREV_ACTIVE_POOLS=Generic ora.ORCL ~STARTUP_FLAG=0~STATE=2~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
[SYSTEM.CRSD12.SERVERS.rac2.INTERNAL]
ORATEXT : ACTIVE_CSS_ROLE=hub~CONFIGURED_CSS_ROLE=hub~CPU_CLOCK_RATE=3192~CPU_COUNT=4~CPU_EQUIVALENCY=1000~CPU_HYPERTHREADING=0~DEPLOYMENT=other~MEMORY_SIZE=3953~PHYSICAL_HOSTNAME=~RESOURCE_USE_ENABLED=1~SERVER_LABEL=~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
(中略)
[SYSTEM.CRSD12.SERVERS.rac3.CONFIG]
ORATEXT : ACTIVE_POOLS=Generic ora.ORCL ~INCARNATION=659365057~NAME=rac3~NODEID=3~PREV_ACTIVE_POOLS=Generic ora.ORCL ~STARTUP_FLAG=0~STATE=2~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
[SYSTEM.CRSD12.SERVERS.rac3.INTERNAL]
ORATEXT : ACTIVE_CSS_ROLE=hub~CONFIGURED_CSS_ROLE=hub~CPU_CLOCK_RATE=3192~CPU_COUNT=4~CPU_EQUIVALENCY=1000~CPU_HYPERTHREADING=0~DEPLOYMENT=other~MEMORY_SIZE=3953~PHYSICAL_HOSTNAME=~RESOURCE_USE_ENABLED=1~SERVER_LABEL=~
SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS, GROUP_PERMISSION : PROCR_NONE, OTHER_PERMISSION : PROCR_NONE, USER_NAME : root, GROUP_NAME : root}
(中略)
2. クラスタ起動ログ確認
各ノードでクラスタを起動したときのログを確認してみます。
・ノード1
# コマンド実行ログ
[2025-11-29 09:35:10.063] [root@rac1 ~]# /u01/app/12.1.0/grid/bin/crsctl start crs -wait
[2025-11-29 09:35:10.493] CRS-4123: Starting Oracle High Availability Services-managed resources
[2025-11-29 09:35:20.531] CRS-2672: 'ora.mdnsd'('rac1')の起動を試行しています
[2025-11-29 09:35:20.531] CRS-2672: 'ora.evmd'('rac1')の起動を試行しています
[2025-11-29 09:35:20.535] CRS-2676: 'ora.mdnsd'('rac1')の起動が成功しました
[2025-11-29 09:35:20.535] CRS-2676: 'ora.evmd'('rac1')の起動が成功しました
[2025-11-29 09:35:20.535] CRS-2672: 'ora.gpnpd'('rac1')の起動を試行しています
[2025-11-29 09:35:20.535] CRS-2676: 'ora.gpnpd'('rac1')の起動が成功しました
[2025-11-29 09:35:20.535] CRS-2672: 'ora.gipcd'('rac1')の起動を試行しています
[2025-11-29 09:35:21.357] CRS-2676: 'ora.gipcd'('rac1')の起動が成功しました
[2025-11-29 09:35:26.724] CRS-2672: 'ora.cssdmonitor'('rac1')の起動を試行しています
[2025-11-29 09:35:26.872] CRS-2676: 'ora.cssdmonitor'('rac1')の起動が成功しました
[2025-11-29 09:35:26.875] CRS-2672: 'ora.cssd'('rac1')の起動を試行しています
[2025-11-29 09:35:26.877] CRS-2672: 'ora.diskmon'('rac1')の起動を試行しています
[2025-11-29 09:35:26.889] CRS-2676: 'ora.diskmon'('rac1')の起動が成功しました
[2025-11-29 09:35:45.086] CRS-2676: 'ora.cssd'('rac1')の起動が成功しました
[2025-11-29 09:35:45.088] CRS-2672: 'ora.cluster_interconnect.haip'('rac1')の起動を試行しています
[2025-11-29 09:35:45.091] CRS-2672: 'ora.ctssd'('rac1')の起動を試行しています
[2025-11-29 09:35:47.105] CRS-2676: 'ora.ctssd'('rac1')の起動が成功しました
[2025-11-29 09:35:53.896] CRS-2676: 'ora.cluster_interconnect.haip'('rac1')の起動が成功しました
[2025-11-29 09:35:53.901] CRS-2672: 'ora.asm'('rac1')の起動を試行しています
[2025-11-29 09:36:13.641] CRS-2676: 'ora.asm'('rac1')の起動が成功しました
[2025-11-29 09:36:13.643] CRS-2672: 'ora.storage'('rac1')の起動を試行しています
[2025-11-29 09:36:13.787] CRS-2676: 'ora.storage'('rac1')の起動が成功しました
[2025-11-29 09:36:13.794] CRS-2672: 'ora.crf'('rac1')の起動を試行しています
[2025-11-29 09:36:14.807] CRS-2676: 'ora.crf'('rac1')の起動が成功しました
[2025-11-29 09:36:14.809] CRS-2672: 'ora.crsd'('rac1')の起動を試行しています
[2025-11-29 09:36:15.820] CRS-2676: 'ora.crsd'('rac1')の起動が成功しました
[2025-11-29 09:36:46.052] CRS-6023: Starting Oracle Cluster Ready Services-managed resources
[2025-11-29 09:36:46.054] CRS-6017: Processing resource auto-start for servers: rac1
[2025-11-29 09:36:46.054] CRS-2672: 'ora.MGMTLSNR'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2672: 'ora.net1.network'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2672: 'ora.oc4j'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2676: 'ora.net1.network'('rac1')の起動が成功しました
[2025-11-29 09:36:46.054] CRS-2672: 'ora.cvu'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2672: 'ora.ons'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2672: 'ora.rac1.vip'('rac1')の起動を試行しています
[2025-11-29 09:36:46.054] CRS-2672: 'ora.rac2.vip'('rac1')の起動を試行しています
[2025-11-29 09:36:46.067] CRS-2672: 'ora.rac3.vip'('rac1')の起動を試行しています
[2025-11-29 09:36:46.067] CRS-2672: 'ora.scan1.vip'('rac1')の起動を試行しています
[2025-11-29 09:36:46.067] CRS-2676: 'ora.cvu'('rac1')の起動が成功しました
[2025-11-29 09:36:46.067] CRS-2676: 'ora.rac1.vip'('rac1')の起動が成功しました
[2025-11-29 09:36:46.067] CRS-2676: 'ora.rac2.vip'('rac1')の起動が成功しました
[2025-11-29 09:36:46.067] CRS-2676: 'ora.rac3.vip'('rac1')の起動が成功しました
[2025-11-29 09:36:46.067] CRS-2676: 'ora.scan1.vip'('rac1')の起動が成功しました
[2025-11-29 09:36:46.067] CRS-2676: 'ora.MGMTLSNR'('rac1')の起動が成功しました
[2025-11-29 09:36:46.074] CRS-2676: 'ora.ons'('rac1')の起動が成功しました
[2025-11-29 09:36:46.074] CRS-2676: 'ora.oc4j'('rac1')の起動が成功しました
[2025-11-29 09:36:46.074] CRS-6017: Processing resource auto-start for servers: rac1,rac2,rac3
[2025-11-29 09:36:46.074] CRS-2672: 'ora.net1.network'('rac2')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2672: 'ora.net1.network'('rac3')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2672: 'ora.LISTENER_SCAN1.lsnr'('rac1')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2672: 'ora.LISTENER.lsnr'('rac1')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2676: 'ora.net1.network'('rac2')の起動が成功しました
[2025-11-29 09:36:46.074] CRS-2672: 'ora.ons'('rac2')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2676: 'ora.net1.network'('rac3')の起動が成功しました
[2025-11-29 09:36:46.074] CRS-2672: 'ora.ons'('rac3')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2673: 'ora.rac3.vip'('rac1')の停止を試行しています
[2025-11-29 09:36:46.074] CRS-2673: 'ora.rac2.vip'('rac1')の停止を試行しています
[2025-11-29 09:36:46.074] CRS-2677: 'ora.rac3.vip'('rac1')の停止が成功しました
[2025-11-29 09:36:46.074] CRS-2672: 'ora.rac3.vip'('rac3')の起動を試行しています
[2025-11-29 09:36:46.074] CRS-2677: 'ora.rac2.vip'('rac1')の停止が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.rac2.vip'('rac2')の起動を試行しています
[2025-11-29 09:36:46.085] CRS-2676: 'ora.rac3.vip'('rac3')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.LISTENER.lsnr'('rac3')の起動を試行しています
[2025-11-29 09:36:46.085] CRS-2676: 'ora.rac2.vip'('rac2')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.LISTENER.lsnr'('rac2')の起動を試行しています
[2025-11-29 09:36:46.085] CRS-2676: 'ora.ons'('rac3')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2676: 'ora.ons'('rac2')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2676: 'ora.LISTENER_SCAN1.lsnr'('rac1')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.mgmtdb'('rac1')の起動を試行しています
[2025-11-29 09:36:46.085] CRS-2676: 'ora.LISTENER.lsnr'('rac1')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.orcl.db'('rac1')の起動を試行しています
[2025-11-29 09:36:46.085] CRS-2676: 'ora.LISTENER.lsnr'('rac3')の起動が成功しました
[2025-11-29 09:36:46.085] CRS-2672: 'ora.orcl.db'('rac3')の起動を試行しています
[2025-11-29 09:36:46.294] CRS-2676: 'ora.LISTENER.lsnr'('rac2')の起動が成功しました
[2025-11-29 09:36:46.300] CRS-2672: 'ora.orcl.db'('rac2')の起動を試行しています
[2025-11-29 09:36:58.290] CRS-2676: 'ora.mgmtdb'('rac1')の起動が成功しました
[2025-11-29 09:37:05.346] CRS-2676: 'ora.orcl.db'('rac3')の起動が成功しました
[2025-11-29 09:37:05.524] CRS-2676: 'ora.orcl.db'('rac2')の起動が成功しました
[2025-11-29 09:37:05.627] CRS-2676: 'ora.orcl.db'('rac1')の起動が成功しました
[2025-11-29 09:37:05.655] CRS-6016: Resource auto-start has completed for server rac1
[2025-11-29 09:37:05.689] CRS-6016: Resource auto-start has completed for server rac2
[2025-11-29 09:37:05.689] CRS-6016: Resource auto-start has completed for server rac3
[2025-11-29 09:37:05.751] CRS-6024: Completed start of Oracle Cluster Ready Services-managed resources
[2025-11-29 09:37:05.868] CRS-4123: Oracle High Availability Services has been started.
# CRSアラートログ
2025-11-29 09:35:16.870 [OHASD(26399)]CRS-8500: Oracle Clusterware OHASDプロセスをオペレーティング・システム・プロセスID 26399で開始しています
2025-11-29 09:35:16.871 [OHASD(26399)]CRS-0714: Oracle Clusterwareリリース12.1.0.2.0。
2025-11-29 09:35:16.877 [OHASD(26399)]CRS-2112: OLRサービスがノードrac1で起動されました。
2025-11-29 09:35:16.893 [OHASD(26399)]CRS-1301: Oracle高可用性サービスがノードrac1で起動されました。
2025-11-29 09:35:16.898 [OHASD(26399)]CRS-8017: 場所: /etc/oracle/lastgaspに2件の再起動アドバイザ・ログ・ファイルがあります(0が通知され、0件のエラーが発生しました)
2025-11-29 09:35:17.151 [CSSDAGENT(26504)]CRS-8500: Oracle Clusterware CSSDAGENTプロセスをオペレーティング・システム・プロセスID 26504で開始しています
2025-11-29 09:35:17.173 [ORAAGENT(26501)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 26501で開始しています
2025-11-29 09:35:17.180 [CSSDMONITOR(26506)]CRS-8500: Oracle Clusterware CSSDMONITORプロセスをオペレーティング・システム・プロセスID 26506で開始しています
2025-11-29 09:35:17.179 [ORAROOTAGENT(26497)]CRS-8500: Oracle Clusterware ORAROOTAGENTプロセスをオペレーティング・システム・プロセスID 26497で開始しています
2025-11-29 09:35:17.478 [ORAAGENT(26562)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 26562で開始しています
2025-11-29 09:35:17.522 [MDNSD(26574)]CRS-8500: Oracle Clusterware MDNSDプロセスをオペレーティング・システム・プロセスID 26574で開始しています
2025-11-29 09:35:17.523 [EVMD(26577)]CRS-8500: Oracle Clusterware EVMDプロセスをオペレーティング・システム・プロセスID 26577で開始しています
2025-11-29 09:35:18.564 [GPNPD(26592)]CRS-8500: Oracle Clusterware GPNPDプロセスをオペレーティング・システム・プロセスID 26592で開始しています
2025-11-29 09:35:19.576 [GIPCD(26617)]CRS-8500: Oracle Clusterware GIPCDプロセスをオペレーティング・システム・プロセスID 26617で開始しています
2025-11-29 09:35:19.584 [GPNPD(26592)]CRS-2328: GPNPDがノードrac1で起動されました。
2025-11-29 09:35:25.952 [CSSDMONITOR(26658)]CRS-8500: Oracle Clusterware CSSDMONITORプロセスをオペレーティング・システム・プロセスID 26658で開始しています
2025-11-29 09:35:26.103 [CSSDAGENT(26674)]CRS-8500: Oracle Clusterware CSSDAGENTプロセスをオペレーティング・システム・プロセスID 26674で開始しています
2025-11-29 09:35:26.258 [OCSSD(26685)]CRS-8500: Oracle Clusterware OCSSDプロセスをオペレーティング・システム・プロセスID 26685で開始しています
2025-11-29 09:35:27.346 [OCSSD(26685)]CRS-1713: CSSDデーモンがhubモードで起動しています
2025-11-29 09:35:32.848 [OCSSD(26685)]CRS-1707: ノードrac1、番号1のリース取得が完了しました
2025-11-29 09:35:33.926 [OCSSD(26685)]CRS-1605: CSSD投票ファイルがオンラインです: /dev/sdb1。詳細は/u01/app/grid/diag/crs/rac1/crs/trace/ocssd.trcを参照してください。
2025-11-29 09:35:33.941 [OCSSD(26685)]CRS-1672: 現在使用可能な投票ファイル数1は必要な投票ファイル数の下限1を下回っています。
2025-11-29 09:35:41.637 [OCSSD(26685)]CRS-1601: CSSDの再構成が完了しました。アクティブ・ノードはrac1 rac2 rac3 です。
2025-11-29 09:35:44.344 [OCTSSD(26776)]CRS-8500: Oracle Clusterware OCTSSDプロセスをオペレーティング・システム・プロセスID 26776で開始しています
2025-11-29 09:35:45.459 [OCTSSD(26776)]CRS-2401: クラスタ時刻同期化サービスがホストrac1で起動されました。
2025-11-29 09:35:45.460 [OCTSSD(26776)]CRS-2407: 新しいクラスタ時刻同期化サービスの参照ノードはホストrac2です。
2025-11-29 09:35:45.688 [OCTSSD(26776)]CRS-2408: ホストrac1の時計は、平均クラスタ時刻と同期化するために、クラスタ時刻同期化サービスによって更新されました。
2025-11-29 09:36:13.112 [OSYSMOND(26997)]CRS-8500: Oracle Clusterware OSYSMONDプロセスをオペレーティング・システム・プロセスID 26997で開始しています
2025-11-29 09:36:14.201 [CRSD(27003)]CRS-8500: Oracle Clusterware CRSDプロセスをオペレーティング・システム・プロセスID 27003で開始しています
2025-11-29 09:36:14.533 [OLOGGERD(27030)]CRS-8500: Oracle Clusterware OLOGGERDプロセスをオペレーティング・システム・プロセスID 27030で開始しています
2025-11-29 09:36:15.541 [CRSD(27003)]CRS-1012: OCRサービスがノードrac1で起動されました。
2025-11-29 09:36:15.589 [CRSD(27003)]CRS-1201: CRSDがノードrac1で起動されました。
2025-11-29 09:36:16.123 [ORAAGENT(27109)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 27109で開始しています
2025-11-29 09:36:16.130 [ORAAGENT(27113)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 27113で開始しています
2025-11-29 09:36:16.188 [ORAROOTAGENT(27118)]CRS-8500: Oracle Clusterware ORAROOTAGENTプロセスをオペレーティング・システム・プロセスID 27118で開始しています
2025-11-29 09:36:19.325 [CRSD(27003)]CRS-2772: サーバー'rac1'はプール'Generic'に割り当てられています。
2025-11-29 09:36:19.325 [CRSD(27003)]CRS-2772: サーバー'rac1'はプール'ora.ORCL'に割り当てられています。
2025-11-29 09:36:19.752 [CRSCTL(27310)]CRS-4743: ファイル/u01/app/12.1.0/grid/oc4j/j2ee/home/OC4J_DBWLM_config/system-jazn-data.xmlはOCR(サイズ: 13365(新)、13378(旧)バイト)から更新されました
2025-11-29 09:36:36.283 [CRSD(27003)]CRS-2772: サーバー'rac2'はプール'Generic'に割り当てられています。
2025-11-29 09:36:36.283 [CRSD(27003)]CRS-2772: サーバー'rac2'はプール'ora.ORCL'に割り当てられています。
2025-11-29 09:36:36.283 [CRSD(27003)]CRS-2772: サーバー'rac3'はプール'Generic'に割り当てられています。
2025-11-29 09:36:36.284 [CRSD(27003)]CRS-2772: サーバー'rac3'はプール'ora.ORCL'に割り当てられています。
2025-11-29 09:36:41.605 [ORAAGENT(27521)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 27521で開始しています
2025-11-29 09:37:29.529 [CLSECHO(409)]CRS-10001: 29-Nov-25 09:37 AFD-9204: false
# ASMアラートログ
Sat Nov 29 09:36:02 2025
MEMORY_TARGET defaulting to 1128267776.
* instance_number obtained from CSS = 1, checking for the existence of node 0...
* node 0 does not exist. instance_number = 1
Starting ORACLE instance (normal) (OS id: 26861)
(中略)
Sat Nov 29 09:36:15 2025
NOTE: ASMB connected to ASM instance +ASM1 osid: 27047 (Flex mode; client id 0xffffffffffffffff)
# リスナーログ
Sat Nov 29 09:36:36 2025
システム・パラメータ・ファイルは/u01/app/12.1.0/grid/network/admin/listener.oraです。
ログ・メッセージを/u01/app/grid/diag/tnslsnr/rac1/listener/alert/log.xmlに書き込みました。
トレース情報を/u01/app/grid/diag/tnslsnr/rac1/listener/trace/ora_27487_140404446336448.trcに書き込みました。
トレース・レベルは現在0です。
pid=27487で起動しました
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(中略)
# DBアラートログ
Sat Nov 29 09:36:43 2025
Starting ORACLE instance (normal) (OS id: 27539)
(中略)
Sat Nov 29 09:37:03 2025
CJQ0 started with pid=66, OS id=30137
Completed: ALTER DATABASE OPEN /* db agent *//* {1:27131:2} */
・ノード2
# コマンド実行ログ
[2025-11-29 09:35:11.722] [root@rac2 ~]# /u01/app/12.1.0/grid/bin/crsctl start crs -wait
[2025-11-29 09:35:12.154] CRS-4123: Starting Oracle High Availability Services-managed resources
(中略)
[2025-11-29 09:35:54.164] CRS-2672: 'ora.asm'('rac2')の起動を試行しています
[2025-11-29 09:36:14.352] CRS-2676: 'ora.asm'('rac2')の起動が成功しました
[2025-11-29 09:36:14.356] CRS-2672: 'ora.storage'('rac2')の起動を試行しています
(中略)
[2025-11-29 09:37:05.786] CRS-4123: Oracle High Availability Services has been started.
# CRSアラートログ
2025-11-29 09:35:14.440 [OHASD(21430)]CRS-8500: Oracle Clusterware OHASDプロセスをオペレーティング・システム・プロセスID 21430で開始しています
2025-11-29 09:35:14.442 [OHASD(21430)]CRS-0714: Oracle Clusterwareリリース12.1.0.2.0。
2025-11-29 09:35:14.447 [OHASD(21430)]CRS-2112: OLRサービスがノードrac2で起動されました。
2025-11-29 09:35:14.469 [OHASD(21430)]CRS-1301: Oracle高可用性サービスがノードrac2で起動されました。
2025-11-29 09:35:14.469 [OHASD(21430)]CRS-8017: 場所: /etc/oracle/lastgaspに2件の再起動アドバイザ・ログ・ファイルがあります(0が通知され、0件のエラーが発生しました)
(中略)
2025-11-29 09:35:17.016 [GIPCD(21636)]CRS-8500: Oracle Clusterware GIPCDプロセスをオペレーティング・システム・プロセスID 21636で開始しています
2025-11-29 09:35:17.034 [GPNPD(21617)]CRS-2328: GPNPDがノードrac2で起動されました。
2025-11-29 09:35:23.418 [CSSDMONITOR(21670)]CRS-8500: Oracle Clusterware CSSDMONITORプロセスをオペレーティング・システム・プロセスID 21670で開始しています
2025-11-29 09:35:23.669 [CSSDAGENT(21686)]CRS-8500: Oracle Clusterware CSSDAGENTプロセスをオペレーティング・システム・プロセスID 21686で開始しています
2025-11-29 09:35:23.809 [OCSSD(21697)]CRS-8500: Oracle Clusterware OCSSDプロセスをオペレーティング・システム・プロセスID 21697で開始しています
2025-11-29 09:35:24.860 [OCSSD(21697)]CRS-1713: CSSDデーモンがhubモードで起動しています
2025-11-29 09:35:30.285 [OCSSD(21697)]CRS-1707: ノードrac2、番号2のリース取得が完了しました
(中略)
2025-11-29 09:36:16.241 [CRSD(22025)]CRS-1012: OCRサービスがノードrac2で起動されました。
2025-11-29 09:36:16.554 [CRSD(22025)]CRS-1201: CRSDがノードrac2で起動されました。
2025-11-29 09:36:17.197 [ORAAGENT(22176)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 22176で開始しています
(中略)
2025-11-29 09:37:29.225 [CLSECHO(26352)]CRS-10001: 29-Nov-25 09:37 AFD-9204: false
# ASMアラートログ
Sat Nov 29 09:36:02 2025
MEMORY_TARGET defaulting to 1128267776.
* instance_number obtained from CSS = 2, checking for the existence of node 0...
* node 0 does not exist. instance_number = 2
Starting ORACLE instance (normal) (OS id: 21891)
(中略)
Sat Nov 29 09:36:16 2025
NOTE: ASMB connected to ASM instance +ASM2 osid: 22077 (Flex mode; client id 0xffffffffffffffff)
# リスナーログ
Sat Nov 29 09:36:40 2025
システム・パラメータ・ファイルは/u01/app/12.1.0/grid/network/admin/listener.oraです。
ログ・メッセージを/u01/app/grid/diag/tnslsnr/rac2/listener/alert/log.xmlに書き込みました。
トレース情報を/u01/app/grid/diag/tnslsnr/rac2/listener/trace/ora_22367_140081442682304.trcに書き込みました。
トレース・レベルは現在0です。
pid=22367で起動しました
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(中略)
# DBアラートログ
Sat Nov 29 09:36:47 2025
Starting ORACLE instance (normal) (OS id: 22415)
(中略)
Sat Nov 29 09:37:03 2025
CJQ0 started with pid=60, OS id=23790
Completed: ALTER DATABASE OPEN /* db agent *//* {1:27131:2} */
・ノード3
# コマンド実行ログ
[2025-11-29 09:35:13.999] [root@rac3 ~]# /u01/app/12.1.0/grid/bin/crsctl start crs -wait
[2025-11-29 09:35:14.434] CRS-4123: Starting Oracle High Availability Services-managed resources
(中略)
[2025-11-29 09:35:55.722] CRS-2672: 'ora.asm'('rac3')の起動を試行しています
[2025-11-29 09:36:14.346] CRS-2676: 'ora.asm'('rac3')の起動が成功しました
[2025-11-29 09:36:14.350] CRS-2672: 'ora.storage'('rac3')の起動を試行しています
(中略)
[2025-11-29 09:37:05.788] CRS-4123: Oracle High Availability Services has been started.
# CRSアラートログ
2025-11-29 09:35:14.838 [OHASD(21264)]CRS-8500: Oracle Clusterware OHASDプロセスをオペレーティング・システム・プロセスID 21264で開始しています
2025-11-29 09:35:14.839 [OHASD(21264)]CRS-0714: Oracle Clusterwareリリース12.1.0.2.0。
2025-11-29 09:35:14.843 [OHASD(21264)]CRS-2112: OLRサービスがノードrac3で起動されました。
2025-11-29 09:35:14.856 [OHASD(21264)]CRS-1301: Oracle高可用性サービスがノードrac3で起動されました。
2025-11-29 09:35:14.857 [OHASD(21264)]CRS-8017: 場所: /etc/oracle/lastgaspに2件の再起動アドバイザ・ログ・ファイルがあります(0が通知され、0件のエラーが発生しました)
(中略)
2025-11-29 09:35:16.397 [GPNPD(21397)]CRS-8500: Oracle Clusterware GPNPDプロセスをオペレーティング・システム・プロセスID 21397で開始しています
2025-11-29 09:35:17.408 [GPNPD(21397)]CRS-2328: GPNPDがノードrac3で起動されました。
2025-11-29 09:35:17.410 [GIPCD(21415)]CRS-8500: Oracle Clusterware GIPCDプロセスをオペレーティング・システム・プロセスID 21415で開始しています
2025-11-29 09:35:23.598 [CSSDMONITOR(21456)]CRS-8500: Oracle Clusterware CSSDMONITORプロセスをオペレーティング・システム・プロセスID 21456で開始しています
2025-11-29 09:35:23.742 [CSSDAGENT(21472)]CRS-8500: Oracle Clusterware CSSDAGENTプロセスをオペレーティング・システム・プロセスID 21472で開始しています
2025-11-29 09:35:23.883 [OCSSD(21483)]CRS-8500: Oracle Clusterware OCSSDプロセスをオペレーティング・システム・プロセスID 21483で開始しています
2025-11-29 09:35:24.937 [OCSSD(21483)]CRS-1713: CSSDデーモンがhubモードで起動しています
2025-11-29 09:35:30.413 [OCSSD(21483)]CRS-1707: ノードrac3、番号3のリース取得が完了しました
(中略)
2025-11-29 09:36:16.283 [CRSD(21858)]CRS-1012: OCRサービスがノードrac3で起動されました。
2025-11-29 09:36:16.612 [CRSD(21858)]CRS-1201: CRSDがノードrac3で起動されました。
2025-11-29 09:36:17.231 [ORAAGENT(21961)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 21961で開始しています
2025-11-29 09:36:17.248 [ORAAGENT(21965)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 21965で開始しています
2025-11-29 09:36:17.277 [ORAROOTAGENT(21970)]CRS-8500: Oracle Clusterware ORAROOTAGENTプロセスをオペレーティング・システム・プロセスID 21970で開始しています
2025-11-29 09:36:45.176 [ORAAGENT(22212)]CRS-8500: Oracle Clusterware ORAAGENTプロセスをオペレーティング・システム・プロセスID 22212で開始しています
2025-11-29 09:37:29.247 [CLSECHO(26161)]CRS-10001: 29-Nov-25 09:37 AFD-9204: false
# ASMアラートログ
Sat Nov 29 09:36:04 2025
MEMORY_TARGET defaulting to 1128267776.
* instance_number obtained from CSS = 3, checking for the existence of node 0...
* node 0 does not exist. instance_number = 3
Starting ORACLE instance (normal) (OS id: 21678)
(中略)
Sat Nov 29 09:36:16 2025
NOTE: ASMB connected to ASM instance +ASM3 osid: 21897 (Flex mode; client id 0xffffffffffffffff)
# リスナーログ
Sat Nov 29 09:36:40 2025
システム・パラメータ・ファイルは/u01/app/12.1.0/grid/network/admin/listener.oraです。
ログ・メッセージを/u01/app/grid/diag/tnslsnr/rac3/listener/alert/log.xmlに書き込みました。
トレース情報を/u01/app/grid/diag/tnslsnr/rac3/listener/trace/ora_22175_139668172862912.trcに書き込みました。
トレース・レベルは現在0です。
pid=22175で起動しました
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(中略)
# DBアラートログ
Sat Nov 29 09:36:47 2025
Starting ORACLE instance (normal) (OS id: 22230)
(中略)
Sat Nov 29 09:37:02 2025
AQPC started with pid=59, OS id=23420
Starting background process CJQ0
Completed: ALTER DATABASE OPEN /* db agent *//* {1:27131:2} */
起動完了時刻を整理すると下記のようになりました。

上記からOHASD→GPNPD→CSSD→ASM→CRSD→クラスタリソースの順で起動していることが分かりました。(途中でエージェントが起動されていることも分かりました)
参考資料
執筆にあたり下記資料を参考にさせていただきました。ありがとうございました。
・オラクルマスター教科書 Oracle Expert RAC 11gR2
・Oracle Database 11g Release 2 RAC実践ガイド 基礎から学ぶRAC構築・管理
・Oracle高可用性サービス技術スタック
おわりに
Oracle Clusterwareの起動の流れは今まで何となくの理解しかなかったため、あらためて復習する良い機会になりました。
今年はOracle Database以外のRDBMS製品の守備範囲を広げるという意味でOSSデータベース(アソシエイトレベル)の試験に挑戦してみました。
来年はOSSデータベースのプロフェッショナルレベルにも挑戦してみようと思います。
Oracle 19cのRACやパフォーマンス・チューニングの日本語試験も配信されたらぜひ挑戦してみたいと思います。
最後までお読みいただきましてありがとうございました。
17日目の記事もお楽しみに!
OSS-DB Exam Silver 3.0 受験記
このたび、OSS-DB Exam Silver 3.0 を受験・合格しましたので、何番煎じか分かりませんが感想を書こうと思います。
また、Oracle Database と似て異なる機能も結構あり衝撃を受けたので、そこら辺についても書こうと思います。
本人のスペック
・PostgreSQLは業務未経験
・約5年前からOracle Database 設計・構築案件に従事(DBの勘所はそれなりにあり)
・ORACLE MASTER Gold DBA 2019 保有
どういう試験か
試験概要や試験範囲の詳細は公式サイトに記載されているため、割愛します。
個人の感想ですが、同じ Silver でも ORACLE MASTER Silver とは別物だと思いました。
(ORACLE MASTER Silver はOracle Database の運用に特化した内容になっていますが、OSS-DB Silver は正規化やトランザクション分離レベルなど理論的な内容も範囲になっています)
受験結果
何とか1回で合格できました。(合格ライン:64点 / スコア:86点)
一般知識:100%
運用管理:92%
開発/SQL:68%(思いのほか取れていなかったのでショックでした)
どうやって勉強したか
主に下記の方法で勉強しました。
・OSS教科書 OSS-DB Silver Ver.3.0対応(通称、緑本)
・OSS-DB Silver Ver3.0 試験対策問題集【LPI-Japan認定教材】Udemy版(アシスト社の教材)
緑本1周→アシスト社の問題集→1周し、あとは試験まで緑本とアシスト社の問題集の模擬問題をそれぞれ2周解きました。
巷では「Silver は Ping-t をぶん回していれば受かる!」と言われていますが、私はそもそもいつ受験できるか分からないため、サブスク型の教材は避けました。
各コマンドの細かいオプションは公式マニュアルも読みました。
正規化については上記2つの教材だけだと厳しかったため、ミックさんの「達人に学ぶDB設計徹底指南書」も読みました。
業務が忙しかったり、家族サービスしながら勉強していたため、勉強開始から受験まで約3ヶ月かかりました。
感想
今後もPostgreSQL 自体を業務で使用する予定はないのですが、正規化やトランザクション分離レベルなど一般的なデータベースの理論的な知識も身に付いた(はず)なので、受験して良かったと思いました。
あとはタイミング的に Oracle 案件が無いときは PostgreSQL 案件にも対応できるようになった(守備範囲を広げることができた)のは良かったと思います。
※上述していますが、ORACLE MASTER Silver の PostgreSQL 版と舐めてかかると痛い目にあいます。
Oracle Database と似て異なって衝撃を受けたもの
勉強を進めていく中で Oracle Database と似た機能なのに異なる仕様で驚いたものをいくつか書こうと思います。
1.アーキテクチャ
PostgreSQL は1つのDBクラスタ(データベース管理領域)に複数DBを格納する
※いわゆる制御ファイルやトランザクションログもDBクラスタ単位
2.DBユーザ
PostgreSQL はDBユーザとロールは同義で、DBユーザはDBクラスタ単位で存在する
※Oracle はDB単位で存在する
3.DB停止オプション
PostgreSQL はDBクラスタ単位で起動・停止する(DB単位ではできない)
・PostgreSQL の停止オプション
smart:Oracle の normal(デフォルト) に相当
fast(デフォルト):Oracle の immediate に相当
immediate:Oracle の abort に相当
※Oracle の transactional に相当するオプションはありません。
※Oracle と同じノリで immediate を使用すると緊急停止(クリーンアウトされない)扱いになります。
4.VACUUM
PostgreSQL は MVCC のうち、追記型アーキテクチャになるため、テーブルを更新するたび不要領域が増えます。
適宜 VACUUM で不要領域を再利用可能状態にするか VACUUM FULL で物理削除するなどのメンテナンスが必要になります。
※Oracle はUNDO で管理しています。
5.自動コミットがデフォルト
PostgreSQL は自動コミットがデフォルトになります。
初めて DML を実行したときに別セッションから DML 実行後のデータが見れたので驚きました。
※Oracle は自動コミットのデフォルトはオフ
6.ストリーミングレプリケーション
ストリーミングレプリケーション構成時、PostgreSQL はスタンバイDBでもデータは参照できます。
※Oracle はActive Data Guard ライセンスを購入しないと参照できない(通常のフィジカル・スタンバイはスタンバイDBは MOUNT のためデータ参照不可)
7.トランザクション分離レベル
PostgreSQL は Read Commited、Repeatable Read、Serializable をサポートしています。
※Oracle はRead Commited、Serializable をサポートしています。
8.アドバイザツール
PostgreSQL は製品インストール時はアドバイザツールが導入されていません(別途ツールの導入が必要)
※Oracle は製品インストール時にアドバイザツールも導入されています。
最後に
PostgreSQL は業務未経験のため前途多難ですが、DBA としてスキルアップするため、OSS-DB Gold も挑戦してみようと思います。(一向に OCI の勉強が進まない。。。)
UNDO表領域の拡張エラー(ORA-30036)を検証する
今回はUNDO表領域の拡張エラー(ORA-30036)について検証しました。
ORA-30036はUNDO表領域に使用可能な領域がなくなり、新たにエクステントを確保(=UNDOセグメント拡張)できない場合に発生します。
Oracleはデータ変更(更新、削除など)時に変更前のデータ(UNDOデータ)を生成し、UNDOセグメントに書き込んで一定期間保持します(UNDOデータは主にトランザクションのロールバックや読取り一貫性で使用します)
たとえば、DELETE文実行時に生成したUNDOデータをUNDOセグメントに書き込んでいる途中でUNDOセグメントがいっぱいになり、
新たにエクステントを確保しようとしたがUNDO表領域に使用可能な領域がないためUNDOセグメント拡張に失敗するというケースもあります。
1. Oracle側での対応案
1-1. UNDO表領域のサイズを拡張する
UNDO表領域のサイズを手動拡張する。ユーザが安全と見積もったサイズで拡張するためORA-30036の発生確率は低くなる
1-2. UNDO表領域の自動拡張をONにする
UNDOセグメント不足時、事前に定義した最大サイズまでUNDO表領域を一定サイズごとに自動拡張する。必要に応じて自動拡張するためORA-30036の発生確率は低くなる
1-3. UNDO保存の保証を無効にする
UNDO保存の保証とは、最小UNDO保存期間内のUNDOデータは上書きされないことを保証する機能。有効の場合、最小UNDO保存期間内のUNDOデータは上書されず、他の領域に書き込まれるためORA-30036の発生確率が高くなる
無効の場合、UNDOセグメント不足時は最小UNDO保存期間内のUNDOデータであっても上書きされるためORA-30036の発生確率は低くなる
1-4. 最小UNDO保存期間の値を小さくする
UNDO保存の保証が有効の場合、最小UNDO保存期間内のUNDOデータは上書きされないためエクステントの使用効率が悪くなる。
最小UNDO保存期間の値を小さくする(UNDOデータが上書きされない期間を短くする)ことでエクステントの使用効率が向上するためORA-30036の発生確率は低くなる
※自動拡張OFF、かつ、UNDO保存の保証が無効の場合、最小UNDO保存期間の値は無視される(UNDO保存期間はOracleで自動チューニングされる)
2 ユーザ側での対応案
2-1. データ処理件数を制御
データの処理件数を絞ってデータ変更する。1回のトランザクションで生成するUNDOデータが減るためORA-30036の発生確率は低くなる
2-2. TRUNCATE文を使用する
DELETE文ではなくTRUNCATE文でデータを削除(切り捨て)する。TRUNCATE文はUNDOデータを生成しないためORA-30036は発生しない
検証環境
OS:Oracle Linux 6.5
DB:Oracle Database 12c Release 1 (12.1.0.2.0) Enterprise Edition
前提
・自動UNDO管理
・UNDO保存の保証:無効
・UNDO保存期間:900秒 ※今回は自動拡張OFF、かつ、UNDO保存の保証が無効のため、この値は無視されます。
検証シナリオ
●パターン1
削除件数を指定せず、全データを一気に削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まらないパターン)
手順1-1.データ削除前のUNDO情報を確認
手順1-2.データを一気に削除
手順1-3.データ削除後のUNDO情報を確認
●パターン2
削除件数を指定し、全データを複数回に分けて削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まるパターン)
手順2-1.データ削除前のUNDO情報を確認
手順2-2.データを50,000件(約5MB)ずつ削除
手順2-3.データ削除後のUNDO情報を確認
検証結果
●パターン1
削除件数を指定せず、全データを一気に削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まらないパターン)
→全データ削除の途中でORA-30036が発生した。
●パターン2
削除件数を指定し、全データを複数回に分けて削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まるパターン)
→ORA-30036は発生せず、全データを削除できた。
検証ログ
●パターン1
削除件数を指定せず、全データを一気に削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まらないパターン)
SQL> --UNDO表領域の使用可能サイズと使用可能ブロック数
SQL> SELECT
2 TABLESPACE_NAME
3 , BYTES / 1024 / 1024 as TOTAL_MB
4 , BLOCKS
5 , USER_BYTES / 1024 / 1024 as AVAIL_MB
6 , USER_BLOCKS as AVAIL_BLKS
7 FROM
8 DBA_DATA_FILES
9 WHERE
10 TABLESPACE_NAME = 'UNDOTBS1';
TABLESPACE_NAME TOTAL_MB BLOCKS AVAIL_MB AVAIL_BLKS
------------------------- ------------------ ---------- ---------- ----------
UNDOTBS1 20.0 2560 19 2432
★実際ユーザーが使用可能サイズ(AVAIL_MB)は19MB、使用可能ブロック数(AVAIL_BLKS)は2432です。
SQL> --UNDO表領域(ACTIVE/UNEXPIREDのUNDOデータ)の使用状況
SQL> SELECT
2 DUE.TABLESPACE_NAME
3 , ROUND(DDF.TOTAL_BYTES / 1024 / 1024, 1) as TOTAL_MB
4 , ROUND(DUE.USED_BYTES / 1024 / 1024, 1) as USED_MB
5 , ROUND((DUE.USED_BYTES / DDF.TOTAL_BYTES) * 100, 2) as RATIO_PCT
6 FROM
7 (
8 SELECT
9 TABLESPACE_NAME
10 , SUM(BYTES) AS USED_BYTES
11 FROM
12 DBA_UNDO_EXTENTS
13 WHERE
14 STATUS IN('ACTIVE', 'UNEXPIRED')
15 AND TABLESPACE_NAME = 'UNDOTBS1'
16 GROUP BY
17 TABLESPACE_NAME
18 ) DUE,
19 (
20 SELECT
21 TABLESPACE_NAME
22 , SUM(BYTES) AS TOTAL_BYTES
23 FROM
24 DBA_DATA_FILES
25 WHERE
26 TABLESPACE_NAME = 'UNDOTBS1'
27 GROUP BY
28 TABLESPACE_NAME
29 ) DDF
30 WHERE
31 DUE.TABLESPACE_NAME = DDF.TABLESPACE_NAME
32 ORDER BY
33 DUE.TABLESPACE_NAME;
TABLESPACE_NAME TOTAL_MB USED_MB RATIO_PCT
------------------------- ------------------ ------------------ ---------
UNDOTBS1 20.0 0.6 3.10
★UNDO表領域の使用サイズ(USED_MB)は0.6MBです。
SQL> --UNDOデータのステータスごとのエクステント使用状況
SQL> SELECT
2 TABLESPACE_NAME
3 , STATUS
4 , COUNT(*) as USED_EXTS
5 , SUM(BYTES) / 1024 / 1024 as USED_MB
6 , SUM(BLOCKS) as USED_BLKS
7 FROM
8 DBA_UNDO_EXTENTS
9 GROUP BY
10 TABLESPACE_NAME
11 , STATUS
12 ORDER BY
13 TABLESPACE_NAME
14 , STATUS;
TABLESPACE_NAME STATUS USED_EXTS USED_MB USED_BLKS
------------------------- -------------------- ---------- ------------------ ----------
UNDOTBS1 EXPIRED 10 0.6 80
UNDOTBS1 UNEXPIRED 10 0.6 80
★EXPIRED/UNEXPIREDのUNDOデータがあり、それぞれ0.6MBずつ使用しています。
SQL> --UNDOセグメントの使用状況
SQL> SELECT
2 TABLESPACE_NAME
3 , SUM(BLOCKS) as USED_BLKS
4 , ROUND(SUM(BYTES) / 1024 / 1024, 1) as USED_MB
5 , SUM(EXTENTS) as USED_EXTS
6 FROM
7 DBA_SEGMENTS
8 WHERE
9 TABLESPACE_NAME = 'UNDOTBS1'
10 GROUP BY
11 TABLESPACE_NAME;
TABLESPACE_NAME USED_BLKS USED_MB USED_EXTS
------------------------- ---------- ------------------ ----------
UNDOTBS1 160 1.3 20
★使用ブロック数(USED_BLKS)は160、使用サイズ(USED_MB)は1.3MB、使用エクステント数(USED_EXTS)は20です。
SQL> --UNDOブロックの生成状況
SQL> SELECT
2 TO_CHAR(BEGIN_TIME,'YYYY-MM-DD HH24:MI:SS') BEGIN_TM
3 , TO_CHAR(END_TIME,'YYYY-MM-DD HH24:MI:SS') END_TM
4 , UNDOBLKS
5 , SSOLDERRCNT
6 , NOSPACEERRCNT
7 , TUNED_UNDORETENTION
8 FROM
9 V$UNDOSTAT
10 ORDER BY
11 END_TM DESC;
BEGIN_TM END_TM UNDOBLKS SSOLDERRCNT NOSPACEERRCNT TUNED_UNDORETENTION
-------------------- -------------------- ---------- ----------- ------------- -------------------
2023-07-28 16:10:00 2023-07-28 16:12:11 0 0 0 29847
★データ削除前のUNDOブロック生成数(UNDOBLKS)は0です(UNDOブロックは生成されていない)
手順1-2.データを一気に削除
SQL> --データ削除前の件数確認
SQL> SELECT COUNT(*) FROM APP_TBL;
COUNT(*)
----------
300000
★APP_TBL表には300,000件(約30MB)のデータが入っています。
SQL> --データ削除
SQL> DELETE FROM APP_TBL;
DELETE FROM APP_TBL
*
ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS1'
★削除件数を指定せず、APP_TBL表から300,000件(約30MB)のデータを一気に削除します(約30MBのUNDOデータが生成されます)
DELETE文で生成されたUNDOデータはUNDO表領域に収まらないため、ORA-30036が発生する想定です。
DELETE文実行後、しばらくしてORA-30036が発生しました。
SQL> --データ削除後の件数確認
SQL> SELECT COUNT(*) FROM APP_TBL;
COUNT(*)
----------
300000
★データ削除に失敗したため、APP_TBL表のデータ件数も変わっていません。
手順1-3.データ削除後のUNDO情報を確認
※UNDO情報の確認SQLは手順1-1で使用したものと同じです。
SQL> --UNDO表領域(UNDOデータのステータスACTIVE/UNEXPIRED)の使用状況
TABLESPACE_NAME TOTAL_MB USED_MB RATIO_PCT
------------------------- ------------------ ------------------ ---------
UNDOTBS1 20.0 18.6 93.10
★UNDO表領域の使用サイズ(USED_MB)は18.6MBです。
SQL> --UNDOデータのステータスごとのエクステント使用状況
TABLESPACE_NAME STATUS USED_EXTS USED_MB USED_BLKS
------------------------- --------- ---------- ------------------ ----------
UNDOTBS1 EXPIRED 6 0.4 48
UNDOTBS1 UNEXPIRED 103 18.6 2384
★EXPIRED/UNEXPIREDのUNDOデータが合計19MB使用しています。手順1-1で確認した使用可能サイズ(19MB)に達しています。
SQL> --UNDOセグメントの使用状況
TABLESPACE_NAME USED_BLKS USED_MB USED_EXTS
------------------------- ---------- ------------------ ----------
UNDOTBS1 2432 19.0 64
★使用ブロック数と使用サイズが、手順1-1で確認した使用可能ブロック数(2432)と使用可能サイズ(19MB)に達しており、
UNDOセグメントが枯渇していたということが分かります。
SQL> --UNDOブロック生成状況
BEGIN_TM END_TM UNDOBLKS SSOLDERRCNT NOSPACEERRCNT TUNED_UNDORETENTION
-------------------- -------------------- ---------- ----------- ------------- -------------------
2023-07-28 16:10:00 2023-07-28 16:14:37 2282 0 1 202
★データ削除時、UNDOブロックが2,282ブロック(約18MB)生成されたタイミングでUNDOセグメント拡張に失敗したため、
NOSPACEERRCNT列は1になりました(拡張に失敗するとインクリメントされる)
●パターン2
削除件数を指定し、全データを複数回に分けて削除(データ削除時に生成されたUNDOデータがUNDO表領域に収まるパターン)
※事前に検証用UNDO表領域を再作成しています。
手順2-1.データ削除前のUNDO情報を確認
※UNDO情報の確認SQLは手順1-1で使用したものと同じです。
SQL> --UNDO表領域(UNDOデータのステータスACTIVE/UNEXPIRED)の使用状況
TABLESPACE_NAME TOTAL_MB USED_MB RATIO_PCT
------------------------- ------------------ ------------------ ---------
UNDOTBS1 20.0 0.6 3.10
★UNDO表領域の使用サイズ(USED_MB)は0.6MBです。
SQL> --UNDOデータのステータスごとのエクステント使用状況
TABLESPACE_NAME STATUS USED_EXTS USED_MB USED_BLKS
------------------------- -------------------- ---------- ------------------ ----------
UNDOTBS1 EXPIRED 10 0.6 80
UNDOTBS1 UNEXPIRED 10 0.6 80
★EXPIRED/UNEXPIREDのUNDOデータがあり、それぞれ0.6MBずつ使用しています。
SQL> --UNDOセグメントの使用状況
TABLESPACE_NAME USED_BLKS USED_MB USED_EXTS
------------------------- ---------- ------------------ ----------
UNDOTBS1 160 1.3 20
★使用ブロック数(USED_BLKS)は160、使用サイズ(USED_MB)は1.3MB、使用エクステント数(USED_EXTS)は20です。
SQL> --UNDOブロック生成状況
BEGIN_TM END_TM UNDOBLKS SSOLDERRCNT NOSPACEERRCNT TUNED_UNDORETENTION
-------------------- -------------------- ---------- ----------- ------------- -------------------
2023-07-28 16:30:00 2023-07-28 16:33:27 0 0 0 1043
2023-07-28 16:20:00 2023-07-28 16:30:00 30 0 0 949
2023-07-28 16:10:00 2023-07-28 16:20:00 2287 0 1 486
★データ削除前のUNDOブロック生成数(UNDOBLKS)は0です(UNDOブロックは生成されていない)
手順2-2.データを50,000件(約5MB)ずつ削除
SQL> --データ削除前の件数確認
SQL> SELECT COUNT(*) FROM APP_TBL;
COUNT(*)
----------
300000
★APP_TBL表には300,000件(約30MB)のデータが入っています。
SQL> --データ削除
SQL> DELETE FROM APP_TBL WHERE ROWNUM <= 50000;
50000 rows deleted.
SQL> COMMIT;
Commit complete.
★1回のDELETE文で50,000件(約5MB)ずつ削除し、コミットします。この作業を全データ分(合計6回)繰り返します。
1回のDELETE文で生成されたUNDOデータはUNDO表領域に収まり、コミットすることでUNDOデータを上書きできる状態にするため、ORA-30036は発生しない想定です。
SQL> --データ削除後の件数確認(DELETE&COMMITを6回繰り返した後)
SQL> SELECT COUNT(*) FROM APP_TBL;
COUNT(*)
----------
0
★全データが削除されました。
手順2-3.データ削除後のUNDO情報を確認
※UNDO情報の確認SQLは手順1-1で使用したものと同じです。
SQL> --UNDO表領域(UNDOデータのステータスACTIVE/UNEXPIRED)の使用状況
TABLESPACE_NAME TOTAL_MB USED_MB RATIO_PCT
------------------------- ------------------ ------------------ ---------
UNDOTBS1 20.0 18.7 93.40
★UNDO表領域の使用サイズ(USED_MB)は18.7MBです。
手順1-3同様にUNDO表領域の使用状況を見るだけでは判断できないため、エクステント使用状況やセグメント使用状況も確認します。
SQL> --UNDOデータのステータスごとのエクステント使用状況
TABLESPACE_NAME STATUS USED_EXTS USED_MB USED_BLKS
------------------------- -------------------- ---------- ------------------ ----------
UNDOTBS1 EXPIRED 5 0.3 40
UNDOTBS1 UNEXPIRED 104 18.7 2392
★EXPIRED/UNEXPIREDのUNDOデータが合計19MB使用しています。今回も手順1-1で確認した使用可能サイズ(19MB)に達しています。
SQL> --UNDOセグメントの使用状況
TABLESPACE_NAME USED_BLKS USED_MB USED_EXTS
------------------------- ---------- ------------------ ----------
UNDOTBS1 2432 19.0 109
★使用ブロック数と使用サイズが、手順1-1で確認した使用可能ブロック数(2432)と使用可能サイズ(19MB)に達しており、
今回もUNDOセグメントが枯渇していたということが分かります。
しかし、使用エクステント数は109(ORA-30036発生時は64)となっており、UNDOセグメントが枯渇間近になりながらもエクステントを使い回せていたということが分かります。
SQL> --UNDOブロック生成状況
BEGIN_TM END_TM UNDOBLKS SSOLDERRCNT NOSPACEERRCNT TUNED_UNDORETENTION
-------------------- -------------------- ---------- ----------- ------------- -------------------
2023-07-28 16:30:00 2023-07-28 16:35:40 7898 0 0 74
2023-07-28 16:20:00 2023-07-28 16:30:00 30 0 0 949
2023-07-28 16:10:00 2023-07-28 16:20:00 2287 0 1 486
参考資料
オラクルマスター教科書 Silver DBA Oracle Database Administration I
https://blogs.oracle.com/otnjp/post/shibacho-028
Oracleのエクステント確保時の動作
今回はOracleのエクステント確保時の動作について検証しました。
Oracleはデータ登録やテーブル作成などのタイミングでエクステントを確保します。
登録したデータのサイズがエクステント割当てサイズより大きくなった場合、新しくエクステントを確保します(新しくエクステントが確保されたタイミングで表領域の使用量も増えます)
しかし、登録したデータのサイズがエクステント割当てサイズより小さい場合、データ自体は登録されているがエクステントは確保されず表領域の使用量も増えません。

検証環境
OS:Oracle Linux 6.5
DB:Oracle Database 12c Release 1 (12.1.0.2.0) Enterprise Edition
前提
・標準ブロックサイズ:8KB
・表領域の自動拡張:OFF
・エクステント管理方法:ローカル管理表領域
・エクステント割当てサイズ:均一(UNIFORM)※割当てサイズは1MB
・セグメント領域管理方法:自動セグメント領域管理
・bigfile表領域
検証手順
●パターン1
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より小さいパターン)
手順1-1.データ登録前の表領域の使用量を確認
手順1-2.データ登録(約500KB)
手順1-3.データ登録後の表領域の使用量を確認
●パターン2
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より大きいパターン)
手順2-1.データ登録前の表領域の使用量を確認
手順2-2.データ登録(約1.5MB)
手順2-3.データ登録後の表領域の使用量を確認
検証結果
●パターン1
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より小さいパターン)
→エクステントは確保されず、表領域の使用量も増えていないように見えた。
●パターン2
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より大きいパターン)
→新しくエクステントが確保され、表領域の使用量も増えた。
検証ログ
●パターン1
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より小さいパターン)
SQL> SELECT
2 DDF.TABLESPACE_NAME
3 , ROUND(DDF.TOTAL_BYTES / 1024 / 1024, 1) AS TOTAL_MB
4 , ROUND((DDF.TOTAL_BYTES - DFS.FREE_TOTAL_BYTES) / 1024 / 1024, 1) AS USED_MB
5 , ROUND(DFS.FREE_TOTAL_BYTES / 1024 / 1024, 1) AS FREE_MB
6 , ROUND(NVL((DDF.TOTAL_BYTES - DFS.FREE_TOTAL_BYTES) / DDF.TOTAL_BYTES * 100, 100), 2) AS RATIO_PCT
7 FROM
8 (
9 SELECT
10 TABLESPACE_NAME
11 , SUM(BYTES) TOTAL_BYTES
12 FROM
13 DBA_DATA_FILES
14 GROUP BY
15 TABLESPACE_NAME
16 ) DDF,
17 (
18 SELECT
19 TABLESPACE_NAME FREE_TABLESPACE_NAME
20 , SUM(BYTES) FREE_TOTAL_BYTES
21 FROM
22 DBA_FREE_SPACE
23 GROUP BY
24 TABLESPACE_NAME
25 ) DFS
26 WHERE
27 DDF.TABLESPACE_NAME = DFS.FREE_TABLESPACE_NAME(+)
28 AND DDF.TABLESPACE_NAME = 'APP_TS'
29 ORDER BY
30 DDF.TABLESPACE_NAME;
TABLESPACE_NAME TOTAL_MB USED_MB FREE_MB RATIO_PCT
------------------------------ ------------------ ------------------ ------------------ ---------
APP_TS 20.0 8.0 12.0 40.00
★データ登録前はAPP_TS表領域の使用量は8MBです。
SQL> --エクステント使用状況確認
SQL> SELECT
2 SEGMENT_NAME
3 , TABLESPACE_NAME
4 , BLOCKS
5 , ROUND(BYTES / 1024 / 1024, 1) AS USED_MB
6 , EXTENTS
7 FROM
8 DBA_SEGMENTS
9 WHERE
10 SEGMENT_NAME = 'APP_TBL';
SEGMENT_NAME TABLESPACE_NAME BLOCKS USED_MB EXTENTS
------------------------- ------------------------------ ---------- ------------------ ----------
APP_TBL APP_TS 128 1.0 1
★データ登録前はAPP_TBL表のエクステント確保サイズは1MBです。
1つのエクステントで128ブロック使用しているというのが分かります(エクステント割当てサイズ(1,024KB) / ブロックサイズ(8KB) = 128)
手順1-2.データ登録(約500KB)
SQL> INSERT INTO APP_TBL
2 SELECT LPAD(LEVEL, 50, '0'), 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' FROM DUAL CONNECT BY LEVEL <= 5000;
5000 rows created.
SQL> commit;
Commit complete.
★APP_TBL表に約500KB(100byteデータ×5,000回登録)のデータを登録します。
登録したデータサイズがエクステント割当てサイズより小さいため、表領域の使用量は増えていないように見える想定です。
手順1-3.データ登録後の表領域の使用量を確認
※表領域の使用量の確認SQLは手順1-1で使用したものと同じです。
TABLESPACE_NAME TOTAL_MB USED_MB FREE_MB RATIO_PCT
------------------------------ ------------------ ------------------ ------------------ ---------
APP_TS 20.0 8.0 12.0 40.00
※エクステント使用状況の確認SQLは手順1-1で使用したものと同じです。
SEGMENT_NAME TABLESPACE_NAME BLOCKS USED_MB EXTENTS
------------------------- ------------------------------ ---------- ------------------ ----------
APP_TBL APP_TS 128 1.0 1
★登録したデータはエクステント割当てサイズより小さいため、新たにエクステントは確保されず、表領域の使用量も増えていないように見えました。
●パターン2
データを複数件登録(登録したデータサイズがエクステント割当てサイズ(1MB)より大きいパターン)
※事前に検証用表領域・検証用テーブルを再作成し、検証用テーブルはデータが登録されていない状態にしています。
手順2-1.データ登録前の表領域の使用量を確認
※表領域の使用量の確認SQLは手順1-1で使用したものと同じです。
TABLESPACE_NAME TOTAL_MB USED_MB FREE_MB RATIO_PCT
------------------------------ ------------------ ------------------ ------------------ ---------
APP_TS 20.0 8.0 12.0 40.0
※エクステント使用状況の確認SQLは手順1-1で使用したものと同じです。
SEGMENT_NAME TABLESPACE_NAME BLOCKS USED_MB EXTENTS
------------------------- ------------------------------ ---------- ------------------ ----------
APP_TBL APP_TS 128 1.0 1
手順2-2.データ登録(約1.5MB)
SQL> INSERT INTO APP_TBL
2 SELECT LPAD(LEVEL, 50, '0'), 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' FROM DUAL CONNECT BY LEVEL <= 15000;
15000 rows created.
SQL> commit;
Commit complete.
★APP_TBL表に約1.5MB(100byteデータ×15,000回登録)のデータを登録します。
登録したデータサイズがエクステント割当てサイズより大きいため、表領域の使用量は増える想定です。
手順2-3.データ登録後の表領域の使用量を確認
※表領域の使用量の確認SQLは手順1-1で使用したものと同じです。
TABLESPACE_NAME TOTAL_MB USED_MB FREE_MB RATIO_PCT
------------------------------ ------------------ ------------------ ------------------ ---------
APP_TS 20.0 9.0 11.0 45.00
※エクステント使用状況の確認SQLは手順1-1で使用したものと同じです。
SEGMENT_NAME TABLESPACE_NAME BLOCKS USED_MB EXTENTS
------------------------- ------------------------------ ---------- ------------------ ----------
APP_TBL APP_TS 256 2.0 2
★登録したデータはエクステント割当てサイズより大きいため、新しくエクステントが1つ確保され、表領域の使用量も1MB増えました。
SELECTなのに更新処理?!~遅延ブロッククリーンアウトの動きに迫る~
この記事は、JPOUG Advent Calendar 2024 16日目の記事です。
15日目は Shinjiro Fujita さんの記事「Oracle Database 23ai 新機能「リアルタイムSQL計画管理 (SPM)」を試してみた #oracle - Qiita」でした。
今回はOracle Databaseの遅延ブロッククリーンアウトについて調査、検証してみました。
なぜ遅延ブロッククリーンアウトが気になったのか忘れたのですが、半年ぐらい前にとあるWebサイトで遅延ブロッククリーンアウトについて書かれている記事を見つけ、その不思議な動きに興味を持ったのだと思います。
しかし、仕組みが(私にとっては)非常に複雑で初めて読んだときはまったく理解できませんでした。
私自身は過去の業務で遅延ブロッククリーンアウトに遭遇したことはないのですが、Oracle界隈では割と有名な話だそうで、自身のナレッジの1つとして調査、検証してみました。
ブロッククリーンアウトとは?
遅延ブロッククリーンアウトについて調べる前にそもそもブロッククリーンアウトとは何か調べてみました。
ブロッククリーンアウトは、データブロックのITL(データブロックを更新しているトランザクションのリスト)に登録されているトランザクションの状態をコミット済みとして記録します。
※ブロッククリーンアウトとチェックポイントは同時には発生しないため、この時点ではバッファとデータファイルで同期されていない可能性があります。
【補足】
ITL(Interested Transaction List)
「Interested」という単語自体知らなかったので辞書で調べてみました。直訳すると「興味があるトランザクションの一覧」になります。
「Oracleが管理するトランザクションの一覧」といったニュアンスでしょうか。
ITLはデータブロックヘッダーに存在し、データブロックを更新しているトランザクションをエントリとして管理します。
なお、OracleはITLエントリの情報から未コミット/コミット済みを判断します。

遅延ブロッククリーンアウトとは?
上記の内容を前提として、遅延ブロッククリーンアウトについて調べてみました。
遅延ブロッククリーンアウトは、未コミット状態となっているデータブロックのITLエントリ(トランザクションの状態)をコミット発行したタイミングではなく、別トランザクションが次回該当データブロックにアクセスしたときにコミット済みに更新(記録)します。
バッチなどで大量のデータを処理する際、未コミットやコミット済みのデータブロックが溜まり続けることでバッファ・キャッシュ領域が枯渇する場合があります。
その場合、Oracleはバッファ・キャッシュ領域に空きを確保するため、トランザクションが未コミット/コミット済みに関わらずデータファイルに書き込みます。
コミット発行された場合、ITLエントリ(トランザクションの状態)をコミット済みに更新する必要がありますが、退避したデータブロックを再度バッファ・キャッシュ領域にロードせず、UNDOセグメントヘッダーのトランザクション表(TRN TBL)にコミット済みであることを記録しておきます。
しかし、この時点ではデータファイルのデータブロックのITLエントリは未コミット状態のままです。
ではデータファイルのデータブロックのITLエントリは誰がいつコミット済みに更新するのでしょうか?
それは次回該当データブロックにアクセスしたトランザクション(SELECT含む)です。
次回該当データブロックにアクセスしたトランザクションがトランザクション表を参照し、コミット発行済みであると判断し、データブロックのITLエントリをコミット済みに更新します。
更新処理(ITLの書き換え)が発生するため、たとえSELECTでもREDOデータが発生します。
なお、トランザクション表を参照する際、シングルブロックリードとなります。(Oracleの仕様)
こんがらがってきたので下記のように整理してみました。
・遅延ブロッククリーンアウトはバッファ・キャッシュ領域の枯渇により発生する
・コミット発行後、ITLエントリ更新のために退避したデータブロックを再度バッファ・キャッシュ領域にはロードしない(コミット済みであることをUNDOセグメントヘッダーに記録しておく)
・次回該当データブロックにアクセスしたトランザクションがITLエントリをコミット済みに更新する(REDOデータが発生する)
・トランザクション表へのアクセスはシングルブロックリードとなる(Oracle ExadataのSmart Scanも効かないという弊害がある)


文章や図だけだといまいちピンと来ないので、実際に検証してみました。
※図の例はUPDATEですが、検証はINSERTで実施しています。
検証環境
OS:Oracle Linux 7.9
DB:Oracle Database 19c Release Update 3 (19.3.0.0.0) Enterprise Edition
前提
・バッファ・キャッシュサイズは約1.5GB
・事前に検証用表領域、検証用テーブルは作成済み(表領域名:APP_TS、テーブル名:APL_TBL)
検証シナリオ
●パターン1(通常のブロッククリーンアウト)
手順1.トランザクション実行
手順2.コミット発行
手順3.バッファ・キャッシュのフラッシュ
手順4.ブロック・ダンプ取得
手順5.別セッションにて該当データブロックにアクセス(SELECT)
●パターン2(遅延ブロッククリーンアウト)
手順1.トランザクション実行
手順2.バッファ・キャッシュのフラッシュ
手順3.コミット発行
手順4.ブロック・ダンプ取得(遅延ブロッククリーンアウト発生前)
手順5.別セッションにて該当データブロックにアクセス
手順6.ブロック・ダンプ取得(遅延ブロッククリーンアウト発生後)
手順7.別セッションにて該当データブロックにアクセス(遅延ブロッククリーンアウトの解消確認)
検証ログ
●パターン1(通常のブロッククリーンアウト)
手順1.トランザクション実行
トランザクション(今回は検証用テーブルにデータINSERT(1000件))を開始します。
後述のITLエントリのトランザクションとの突合用にトランザクション情報も取得しておきます。
SQL> INSERT INTO APP_TBL SELECT LPAD(LEVEL, 1000, '0') FROM DUAL CONNECT BY LEVEL <= 1000;
1000 rows created.
SQL> --アクティブ・トランザクション確認
SQL> select
2 xid,
3 xidusn,
4 xidslot,
5 xidsqn,
6 ubablk,
7 ubasqn,
8 ubarec,
9 status,
10 start_ubablk,
11 start_ubasqn,
12 start_ubarec,
13 used_ublk,
14 used_urec,
15 start_scn
16 from
17 v$transaction
18 order by
19 xid;
XID XIDUSN XIDSLOT XIDSQN UBABLK UBASQN UBAREC STATUS START_UBABLK START_UBASQN START_UBAREC USED_UBLK USED_UREC START_SCN
---------------- ---------- ---------- ---------- ---------- ---------- ---------- --------------- ------------ ------------ ------------ ---------- ---------- ----------
0A0010009E040000 10 16 1182 1839 276 55 ACTIVE 1835 276 28 4 250 2711411
手順2.コミット発行
コミットを実行し、トランザクションを終了します。
Commit complete.
手順3.バッファ・キャッシュのフラッシュ
バッファ・キャッシュをフラッシュし、疑似的にコミット発行後にバッファ・キャッシュが枯渇した状態にします。
※未コミット/コミット済みに関わらずデータブロックはデータファイルに書き込まれます。
System altered.
手順4.ブロック・ダンプ取得
コミット発行後にバッファ・キャッシュをフラッシュした状態のデータブロックのITLを確認するため、検証用テーブルのデータブロックの情報をダンプします。
※検証ログのダンプ結果はトランザクションが存在するエントリのみ表示しています。
SQL> select
2 segment_name
3 , file_id
4 , extent_id
5 , block_id
6 , blocks --extent size(uniform) / block size
7 , round(bytes / 1024 / 1024, 2) as used_mb
8 from
9 dba_extents
10 where
11 segment_name = 'APP_TBL'
12 order by
13 extent_id,
14 block_id;
SEGMENT_NAME FILE_ID EXTENT_ID BLOCK_ID BLOCKS USED_MB
------------------------- ---------- ---------- ---------- ---------- -------------------
APP_TBL 5 0 8696 8 0.06
(中略)
APP_TBL 5 19 8848 8 0.06
SQL> --ブロック・ダンプ取得
SQL> alter session set tracefile_identifier = 'pt1';
Session altered.
SQL> alter system dump datafile 5 block min 8696 block max 8855;
System altered.
SQL> exit
[oracle@vm-oel7 ~]$ ls -ltr /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_*.trc
-rw-r----- 1 oracle oinstall 3663965 11月 14 10:26 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_11954_pt1.trc
[oracle@vm-oel7 ~]$ egrep "^ Itl|^0x0|^Block header dump" /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_11954_pt1.trc
Block header dump: 0x000021fb
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.010.0000049e 0x0100072b.0114.1c --U- 7 fsc 0x0000.00295f9b
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Block header dump: 0x000021fc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.010.0000049e 0x0100072b.0114.24 --U- 7 fsc 0x0000.00295f9b
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
(中略)
Block header dump: 0x0000228f
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.010.0000049e 0x0100072f.0114.32 --U- 7 fsc 0x0000.00295f9b
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.010.0000049e 0x0100072f.0114.37 --U- 6 fsc 0x0000.00295f9b
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
最初のブロックのエントリ番号 0x01 の Xid(0x000a.010.0000049e)のピリオドで区切られた値をそれぞれ10進表記にすると、アクティブ・トランザクションのXIDUSN、XIDSLOT、XIDSQNの値と一致していることが分かります。
Uba もピリオドで区切られた値をそれぞれ10進表記にすると、アクティブ・トランザクションの値と一致していることが分かります。
・0x0100072b は 0x01 を除いた値 (00072b)はSTART_UBABLK
・0114 はSTART_UBASQN
・1c はSTART_UBAREC
と一致していることが分かります。
なお、最後のブロックのエントリ番号 0x01 の
・0x0100072b は 0x01 を除いた値 (00072f)はUBABLK
・0114 はUBASQN
・37 はUBAREC
とXidは固定なのに対し、Ubaはブロック番号とレコード番号が可変になっています。
おそらくUNDOセグメントは循環利用なので可変になっているのではと思います。
上記からアクティブ・トランザクションはトランザクション開始時のUNDOデータとカレントのUNDOデータの両方を持っていることが分かりました。
(UNDOブロックもダンプしてみようと思ったのですが、そこまで検証時間を確保できませんでした…)
また、各エントリの Flag は --U-(コミット済み)になっていることも確認できました。
Scn にも値が入っており、エントリのトランザクションは終了していることも確認できました。
手順5.別セッションにて該当データブロックにアクセス
コミット発行後にバッファ・キャッシュをフラッシュした状態のデータブロックにアクセス(今回はSELECT)します。
アクセスしたときの実行統計や待機イベントも確認してみます。
SQL> set autotrace on
SQL> select count(*) from app_tbl;
COUNT(*)
----------
1000
Execution Plan
----------------------------------------------------------
Plan hash value: 1770987
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 42 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| APP_TBL | 1200 | 42 (0)| 00:00:01 |
----------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
Statistics
----------------------------------------------------------
6 recursive calls
0 db block gets
236 consistent gets
152 physical reads
0 redo size
550 bytes sent via SQL*Net to client
390 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select
2 wait_class,
3 event,
4 total_waits,
5 total_waits_fg
6 from
7 v$system_event
8 order by
9 wait_class,
10 total_waits desc;
WAIT_CLASS EVENT TOTAL_WAITS TOTAL_WAITS_FG
-------------------- ---------------------------------------- ----------- --------------
Administrative index (re)build lock or pin object 102 102
Administrative OFS operation completion 1 1
Commit log file sync 6 5
(中略)
User I/O db file sequential read 4610 2803
User I/O db file scattered read 292 118
User I/O Disk file operations I/O 236 70
単なるSELECTなのでREDOデータは発生していませんでした。
遅延ブロッククリーンアウトは発生していない想定のため、「db file sequential read」は他起因によるものと思います。
●パターン2(遅延ブロッククリーンアウト)
手順1.トランザクション発行
トランザクション(今回は検証用テーブルにデータINSERT(1000件))を開始します。
後述のITLエントリのトランザクションとの突合用にトランザクション情報も取得しておきます。
※パターン2検証前に状態をクリアするため、検証用テーブル再作成&DB再起動しています。
SQL> INSERT INTO APP_TBL SELECT LPAD(LEVEL, 1000, '0') FROM DUAL CONNECT BY LEVEL <= 1000;
1000 rows created.
SQL> --アクティブ・トランザクション確認
SQL> select
2 xid,
3 xidusn,
4 xidslot,
5 xidsqn,
6 ubablk,
7 ubasqn,
8 ubarec,
9 status,
10 start_ubablk,
11 start_ubasqn,
12 start_ubarec,
13 used_ublk,
14 used_urec,
15 start_scn
16 from
17 v$transaction
18 order by
19 xid;
XID XIDUSN XIDSLOT XIDSQN UBABLK UBASQN UBAREC STATUS START_UBABLK START_UBASQN START_UBAREC USED_UBLK USED_UREC START_SCN
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- ------------ ------------ ------------ ---------- ---------- ----------
04001B0012050000 4 27 1298 89968 337 58 ACTIVE 89956 337 31 4 250 2719034
手順2.バッファ・キャッシュのフラッシュ
バッファ・キャッシュをフラッシュし、疑似的にコミット発行前にバッファ・キャッシュが枯渇した状態にします。
※未コミット/コミット済みに関わらずデータブロックはデータファイルに書き込まれます。
System altered.
手順3.コミット発行
コミットを実行し、トランザクションを終了します。
Commit complete.
手順4.ブロック・ダンプ取得(遅延ブロッククリーンアウト発生前)
コミット発行前にバッファ・キャッシュをフラッシュした状態のデータブロックのITLを確認するため、検証用テーブルのデータブロックの情報をダンプします。
※検証ログのダンプ結果はトランザクションが存在するエントリのみ表示しています。
SQL> select
2 segment_name
3 , file_id
4 , extent_id
5 , block_id
6 , blocks --extent size(uniform) / block size
7 , round(bytes / 1024 / 1024, 2) as used_mb
8 from
9 dba_extents
10 where
11 segment_name = 'APP_TBL'
12 order by
13 extent_id,
14 block_id;
SEGMENT_NAME FILE_ID EXTENT_ID BLOCK_ID BLOCKS USED_MB
------------------------- ---------- ---------- ---------- ---------- -------------------
APP_TBL 5 0 8696 8 0.06
(中略)
APP_TBL 5 19 8848 8 0.06
SQL> --ブロック・ダンプ取得
SQL> alter session set tracefile_identifier = 'pt2_before_delayed_block_cleanout';
Session altered.
SQL> alter system dump datafile 5 block min 8696 block max 8855;
System altered.
[oracle@vm-oel7 ~]$ ls -ltr /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_*.trc
-rw-r----- 1 oracle oinstall 3663965 11月 14 10:26 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_11954_pt1.trc
-rw-r----- 1 oracle oinstall 10690 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12167.trc
-rw-r----- 1 oracle oinstall 20035 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12204.trc
-rw-r----- 1 oracle oinstall 1214 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12292.trc
-rw-r----- 1 oracle oinstall 1182 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12302.trc
-rw-r----- 1 oracle oinstall 3657511 11月 14 10:35 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12754_pt2_before_delayed_block_cleanout.trc
[oracle@vm-oel7 ~]$ egrep "^ Itl|^0x0|^Block header dump" /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12754_pt2_before_delayed_block_cleanout.trc
Block header dump: 0x000021fb
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f64.0151.23 ---- 7 fsc 0x0000.00000000
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Block header dump: 0x000021fc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f64.0151.25 ---- 7 fsc 0x0000.00000000
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
(中略)
Block header dump: 0x0000228f
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f70.0151.2e ---- 7 fsc 0x0000.00000000
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Block header dump: 0x00002296
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f70.0151.3a ---- 6 fsc 0x0000.00000000
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
XidやUbaの見方はパターン1で説明してみたので割愛します。
コミット発行したにも関わらず、エントリの Flag は ----(未コミット)になっていました。
また、Scn も値が入っておらず、トランザクションは終了していない状態になっていました。
手順5.別セッションにて該当データブロックにアクセス
コミット発行後にバッファ・キャッシュをフラッシュした状態のデータブロックにアクセス(今回はSELECT)します。
アクセスしたときの実行統計や待機イベントも確認してみます。
SQL> set autotrace on
SQL> select count(*) from app_tbl;
COUNT(*)
----------
1000
Execution Plan
----------------------------------------------------------
Plan hash value: 1770987
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 42 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| APP_TBL | 1200 | 42 (0)| 00:00:01 |
----------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
Statistics
----------------------------------------------------------
6 recursive calls
0 db block gets
379 consistent gets
152 physical reads
12628 redo size
550 bytes sent via SQL*Net to client
390 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select
2 wait_class,
3 event,
4 total_waits,
5 total_waits_fg
6 from
7 v$system_event
8 order by
9 wait_class,
10 total_waits desc;
WAIT_CLASS EVENT TOTAL_WAITS TOTAL_WAITS_FG
-------------------- ---------------------------------------- ----------- --------------
Administrative index (re)build lock or pin object 102 102
Administrative OFS operation completion 1 1
Commit log file sync 5 5
(中略)
User I/O db file sequential read 11591 7756
User I/O db file scattered read 301 117
User I/O Disk file operations I/O 249 71
単なるSELECTなのにREDOデータが生成されていることが確認できました。
また、フルスキャンなのにパターン1に比べ、「db file sequential read」が増えていることも確認できました。(UNDOセグメントにアクセスしている想定)
(AWRやASHレポートも見てみようと思ったのですが、そこまで検証時間を確保できませんでした…)
手順6.ブロック・ダンプ取得(遅延ブロッククリーンアウト発生後)
遅延ブロッククリーンアウト発生後のデータブロックのITLを確認するため、検証用テーブルを構成するブロックの情報をダンプします。
※検証ログのダンプ結果はトランザクションが存在するエントリのみ表示しています。
SQL> alter session set tracefile_identifier = 'pt2_after_delayed_block_cleanout';
Session altered.
SQL> alter system dump datafile 5 block min 8696 block max 8855;
System altered.
SQL> exit
[oracle@vm-oel7 ~]$ ls -ltr /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_*.trc
-rw-r----- 1 oracle oinstall 3663965 11月 14 10:26 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_11954_pt1.trc
-rw-r----- 1 oracle oinstall 10690 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12167.trc
-rw-r----- 1 oracle oinstall 20035 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12204.trc
-rw-r----- 1 oracle oinstall 1214 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12292.trc
-rw-r----- 1 oracle oinstall 1182 11月 14 10:28 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12302.trc
-rw-r----- 1 oracle oinstall 3657511 11月 14 10:35 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_12754_pt2_before_delayed_block_cleanout.trc
-rw-r----- 1 oracle oinstall 7416343 11月 14 10:38 /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_13005_pt2_after_delayed_block_cleanout.trc
[oracle@vm-oel7 ~]$ egrep "^ Itl|^0x0|^Block header dump" /u01/app/oracle/diag/rdbms/orcl19c/orcl19c/trace/orcl19c_ora_13005_pt2_after_delayed_block_cleanout.trc
Block header dump: 0x000021fb
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f64.0151.23 C--- 0 scn 0x0000000000297d7a
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Block header dump: 0x000021fc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f64.0151.25 C--- 0 scn 0x0000000000297d7a
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
(中略)
Block header dump: 0x0000228f
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f70.0151.2e C--- 0 scn 0x0000000000297d7a
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Block header dump: 0x00002296
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.01b.00000512 0x01015f70.0151.3a C--- 0 scn 0x0000000000297d7a
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
遅延ブロッククリーンアウトが発生したため、エントリの Flag は C---(コミット済み)になっていました。
また、Scn も値が入っており、トランザクションが終了した状態になっていました。
手順7.別セッションにて該当データブロックにアクセス(遅延ブロッククリーンアウトの解消確認)
遅延ブロッククリーンアウト発生後のデータブロックにアクセス(今回はSELECT)し、遅延ブロッククリーンアウトが解消されていることを確認します。
アクセスしたときの実行統計や待機イベントも確認してみます。
SQL> set autotrace on
SQL> select count(*) from app_tbl;
COUNT(*)
----------
1000
Execution Plan
----------------------------------------------------------
Plan hash value: 1770987
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 42 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| APP_TBL | 1200 | 42 (0)| 00:00:01 |
----------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
154 consistent gets
0 physical reads
0 redo size
550 bytes sent via SQL*Net to client
390 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select
2 wait_class,
3 event,
4 total_waits,
5 total_waits_fg
6 from
7 v$system_event
8 order by
9 wait_class,
10 total_waits desc;
WAIT_CLASS EVENT TOTAL_WAITS TOTAL_WAITS_FG
-------------------- ---------------------------------------- ----------- --------------
Administrative index (re)build lock or pin object 102 102
Administrative OFS operation completion 1 1
Commit log file sync 6 6
(中略)
User I/O db file sequential read 11911 7917
User I/O db file scattered read 301 117
User I/O Disk file operations I/O 283 96
遅延ブロッククリーンアウトが解消されたため、REDOデータは生成されていないことが確認できました。
「db file sequential read」が多少増えていますが、今回は遅延ブロッククリーンアウトは発生していない想定のため、他起因によるものと思います。
対応案
遅延ブロッククリーンアウトの原因は「バッファ・キャッシュ領域の枯渇」ということを前提に対応案を考えてみました。

インフラ、アプリ両方でそれぞれ対応案がありますが、どちらもメリット・デメリットがありますね。
参考サイト
執筆にあたり主に下記Webサイトを参考にさせていただきました。ありがとうございました。
フルスキャンで何故シングルブロックリードが発生するのか?(2/2) - DBひとりでできるもん
遅延ブロッククリーンアウトの性能対策/JPOUG Tech Talk Night #8 - Speaker Deck
OracleDatabaseのトランザクションと一貫性 - Speaker Deck
遅延ブロッククリーンアウト - オラクル・Oracleをマスターするための基本と仕組み
遅延ブロッククリーンアウトを観測する① - SQL*Plusの使いにくさは異常
おわりに
今回調べたことを整理するため記事にしましたが、今でも理解できていない箇所は多々残っており、見落としもあると思います。
たとえばITLのFlagの「U」と「C」の具体的な違いが分かっていなかったり…
機会があればぜひ製品サポートに聞いてみたいと思います。
今年度はシステム更改が始まり、Enterprise Managerも構築することになりました。
来年はEnterprise Manager関連の検証が多くなりそうです。
最後までお読みいただきましてありがとうございました。
17日目の記事もお楽しみに!
OracleのLifetime Support(ライフタイム・サポート・ポリシー)
今回はOracleのライフタイム・サポート・ポリシーについて調査しました。
※本記事は個人の学習目的でまとめた内容となります。製品のサポート対象については必ずOracleサポートへ確認して正確な情報を入手してください。
ライフタイム・サポート・ポリシー(Lifetime Support)とは
2006年3月1日に日本オラクルが発表したオラクル社の製品サポートの提供方針(ポリシー)です。
オラクル社の製品のライセンスとサポート契約をユーザが継続している間は無期限にサポートを提供します。
サポート契約を結んでいる場合、製品のアップデート、パッチの提供、さまざまな技術サポートなどを受けることができます。

Premier Support
米国オラクル本社の製品出荷開始日から5年間メンテナンスとサポートを提供します。
Premier Support期間終了時点でExtended Supportを選択していない場合、Premier Support期間終了後、自動的にSustaining Supportに移行されます。
Premier Support期間中にもかかわらずOracle製品と連携して使用する製品(例えばOS)のサポートが終了した場合、Premier Supportは終了し、Sustaining Supportでの対応となります。
Extended Support
一部のサポート対象項目に対してさらに3年間延長してPremier Supportと同等のサービスを提供します。
Extended Supportは最終PSRに対してのみ提供されます(たとえばOracle Database 10gR2であれば10.2.0.5にのみ提供される)
Extended Support期間中にもかかわらずOracle製品と連携して使用する製品(例えばOS)のサポートが終了した場合、Extended Supportは終了し、Sustaining Supportでの対応となります。
Sustaining Support
Premier SupportやExtended Supportに比べサポート対象項目に制限がありますが、ユーザがライセンスやサポート計画を継続している間は無期限で一部のサポート対象項目に対してメンテナンスとサポートを提供します。
プログラム修正やパッチなども提供されますがPremier Support期間中(Extended Supportを選択した場合、Extended Support期間中)に作成されたものに限定されます。
Extended Support終了後はExtended Supportを選択しなかったユーザに対してもExtended Support期間中に作成されたプログラム修正、パッチなどを提供します。

■参考資料
Oracle Response Center: ソフトウェア | NEC
ソフトウェア | Lifetime Support Policy | Oracle 日本
新・門外不出のOracle現場ワザ エキスパートが明かす運用・管理の極意
■おわりに
大抵のプロジェクトではサポート契約を結んでいるプロジェクトが多いと思いますが、製品アップグレードやパッチ提供などサポート契約の期間を意識した運用スケジュールの計画が重要です。
運用スケジュールの意識があまり無い状態でプロジェクトを進めてPremier SupportやExtended Supportの期間を過ぎてしまうと、障害発生時などユーザが期待するサービスが受けられないリスクもあります。
Oracleのパッチ
今回はOracleのパッチについて調査しました。
パッチとは
オラクル社が提供する製品のセキュリティホールや不具合(バグ)を修正するものです。
パッチは製品のリリース(バージョン)ごとに提供されていますが、12cR1までと12cR2以降で提供されるパッチの種類が変わりました。

なお、パッチはMOS(My Oracle Support)からダウンロードする必要があります(つまり、サポート契約しないと入手できません)
【補足】
Long Term Support
製品の特定のバージョンを長期間安定的にサポートする
サポート期間は開発元の方針や製品の種類によって異なるが、LTSは数年に設定することが多い
なお、通常のサポート期間(STS:Short Term Support)は数ヶ月から1年前後が多い
リリース(バージョン)番号
従来型リリースモデルと年次リリースモデルでリリース番号の読み方が変わりました。

パッチの種類
12cR1まで(従来型リリースモデル)と12cR2以降(年次リリースモデル)で提供されるパッチの種類が変わっています。
●12cR1まで(従来型リリースモデル)
PSR、PSU、SPU、個別パッチなどが提供されます。
パッチの修正量は大きいものから「PSR > PSU > SPU > 個別パッチ」となります。
PSR(Patch Set Release)
年次またはそれ以上(原則1~2年ごと)に提供される最も基本的な重要パッチ
主に下記の内容が含まれている
・セキュリティホール修正
・不具合(バグ)修正(バグフィックス)
・新機能
・オプティマイザ修正
・新規パラメータ
PSR適用後、リリース番号の4桁目のバージョン番号が変わる
(例)11.2.0.4.0の場合、4がバージョン番号
PSU(Patch Set Update)
毎年四半期ごと(1月/4月/7月/10月)に提供される累積パッチ
主に下記の内容が含まれている
・セキュリティホール修正
・不具合(バグ)修正(バグフィックス)
パッチ適用後、リリース番号の5桁目のバージョン番号が変わる
(例)11.2.0.4.0の場合、0がバージョン番号
SPU(Security Patch Update、旧Critical Patch Update)
毎年四半期ごと(1月/4月/7月/10月)に提供される累積パッチ
PSUからセキュリティホール修正のみ抽出したパッチ
主に下記の内容が含まれている
・セキュリティホール修正
SPU適用後、OPatch(opatch lsinventoryコマンド)で適用したSPU番号を確認できる
※SPUはPSUに含まれることが多いため、PSUを適用した場合、別途SPUを適用するか確認が必要
※12.1.0.1以降はSPUはPSUに含まれるため、SPU単体で提供されない
個別パッチ(Interim Patch、PSE)
不定期で提供されるパッチ
1つの不具合に対して特別に提供されるパッチ
PSRやPSUの修正に含まれていない不具合が発生しているが、次のパッチリリースまでデータベースを運用することが困難な場合、Oracleサポートから特別に提供される
個別パッチを適用した場合、他のパッチ適用時にコンフリクト(競合)が発生する可能性がある
たとえば個別パッチAが適用済みで個別パッチBを適用しようとしたが、パッチBで修正されるモジュールがパッチAと同じモジュールだったため、コンフリクトが発生するなど
パッチは同じモジュールを含むパッチを複数適用できない(適用済みパッチと同じモジュールを含むパッチを適用するとコンフリクトが発生する)
将来的に個別パッチはPSRやPSUなどに含まれる場合もあるため、緊急時を除き、積極的に適用しないでも良いと思います
個別パッチ適用後、OPatch(opatch lsinventoryコマンド)で適用した個別パッチ番号を確認できる
BP(Bundle Patch)
Oracle ExadataやOracle Database Appliance、Windowsなど特定のプラットフォーム向け提供される累積パッチ
Windows Bundle Patch(Patch X)
Windowsに提供される累積パッチ
WindowsではPSUやSPU、個別パッチは提供されていない
代わりに上記の修正が含まれているWindows Bundle Patchが提供されている
DBBP(Database Proactive Bundle Patch)
ExadataやDatabase Applianceなどに提供される累積パッチ
Grid Infrastructureとデータベースの両方に対する修正を含む
●12cR2以降(年次リリースモデル)
RU、RUR、個別パッチなどが提供されます。

RU(Release Updates)
毎年四半期ごと(1月/4月/7月/10月)に提供される累積パッチ
特定のリリースに対する追加の修正が含まれる
従来型リリースモデルのPSUと同様の位置づけとなっているが、RUはオプティマイザに対する修正も含まれる
主に下記の内容が含まれている
・セキュリティホール修正
・不具合(バグ)修正(バグフィックス)
・オプティマイザ修正
RUR(Release Update Revisions)
毎年四半期ごと(1月/4月/7月/10月)に提供される累積パッチ
特定のRUに対する追加の修正が含まれる
特定のRUに対して最大2つ提供される
主に下記の内容が含まれている
・セキュリティホール修正
Oracle 12cR2ファミリー
従来型リリースモデルは同一のリリースにおいて複数のリリース番号を持つパッチセットが提供されていた。
(例)
11gR2の場合
初期リリース:11.2.0.1
パッチセット:11.2.0.2 → 11.2.0.3 → 11.2.0.4
12cR2以降
12cR2(12.2.0.1):従来型リリースモデルの初期リリース相当
18c:従来型リリースモデルのパッチセットの12.2.0.2相当
19c:従来型リリースモデルのパッチセットの12.2.0.3相当
12cR2以降は18c、19cと呼ばれているが、従来型リリースモデルと密接な関係があるため、Oracle12cR2ファミリーとも呼ばれる
パッチ提供期間
パッチはPremier Support期間中(リリースから5年間)、Extended Supportを契約している場合はExtended Support期間中(リリースから最長8年間)は提供されます
※パッチの提供可否については必ずOracleサポートへ確認して正確な情報を入手してください
パッチ適用方法
適用するパッチの種類で適用方法や適用ツールが異なります。
OpatchはOracle Database製品に含まれていますが、MOSから最新版をダウンロードすることを推奨されています(OPatchのバージョンが古いとパッチ適用に失敗する可能性もある)

【補足】
アウトオブプレース
新規に製品ホーム作成後、パッチをインストールする方法
インストール完了後、既存ホームで稼働しているサービスを停止し、製品ホームを切り替える
・インプレースに比べ、サービス停止時間が短い
・新規ホームを作成するため、新規パッチを格納する領域も必要
インプレース
既存ホームで稼働しているサービス停止後、既存の製品ホームにパッチをインストール(上書き)する方法
・アウトオブプレースに比べ、サービス停止時間が長い
・新規パッチ格納用の領域は不要
OPatch(Oracleパッチ適用ユーティリティ)
Oracle製品ホームにパッチを適用したり、適用済みパッチを管理するツールです。
主に下記の機能があります
・パッチの適用
・パッチのロールバック(適用済みパッチの取り消し)
・コンフリクト(競合)チェック
パッチ適用時は下記のコマンドを使用します。
opatchコマンド
Oracleホームに対してパッチを適用する
パッチ適用対象Oracleホームの所有者(たとえばoracleユーザ)で実行する
datapatchコマンド
opatchコマンド実行後、パッチ適用に伴う修正をデータベースに適用する
データベースの内部構造を変更するSQLスクリプトが実行される
opatchautoコマンド
複数の製品ホームに対して一括でパッチを適用する
たとえばRestart環境やRAC環境などGrid Infrastructure製品とOracle Database製品が導入されている場合、GridホームとOracleホームに対して一括でパッチを適用する(datapatchも自動で実行される)
rootユーザで実行する
ローリングアップグレード(デフォルト)で適用するため、RAC環境の場合、パッチ適用に伴う停止時間を短縮できる
※Windowsでは使用不可
【補足】ローリングアップグレード
複数ノードで構成されるクラスタ環境において1ノードずつパッチを適用する方法(シングル環境、Restart環境では使用不可)
パッチ適用に伴うサービス停止時間を最小限に抑えることができるため、可用性の観点で有効な方法
1ノードずつパッチを適用するため、一時的にノード間で新しいパッチと古いパッチが混在する状況になる
※ローリングアップグレードできるパッチとできないパッチがあるため、適用時はパッチのREADMEをよく読むこと(異なるバージョンが混在できるパッチのみ適用可能)
個人ではサポート契約していないため、パッチのダウンロード、パッチ適用の検証はできませんが、Oracle製品インストール直後のパッチバージョンだけ確認してみます。
■検証環境
OS:Oracle Linux 6.5
DB/GI:Oracle Database 12c Release 1 (12.1.0.2.0) Enterprise Edition
※2ノードRAC(管理者管理型DB)
■前提
・PSR 12.1.0.2.0のみ適用済み(フルインストール)
・上記以外のパッチ適用なし
※フルインストール:11.2.0.2以降のPSRの提供方法。Oracle製品のインストールと同時にPSRも自動適用するため、ベースリリースはインストール不要となる。
(例)12cR1をインストールする場合、予めベースリリース12.1.0.1.0にPSR 12.1.0.2.0が適用された状態でダウンロードできるため、ベースリリース12.1.0.1.0をダウンロード後、PSR 12.1.0.2.0を適用するという処理が省略できる。ただし、ベースリリースとPSRがセットになっているため、ファイルサイズも大きくなる
■検証パターン
①製品のパッチバージョン確認(Gridホーム)
②製品のパッチバージョン確認(Oracleホーム)
■検証
①製品のパッチバージョン確認(Gridホーム)
Grid Infrastructure製品(Gridホーム)に適用されているパッチバージョンを確認します
【検証手順】
1. パッチバージョン確認
【作業ログ】
[grid@node1 ~]$ opatch lsinventory
Oracle Interim Patch Installerバージョン12.1.0.1.3
Copyright (c) 2023, Oracle Corporation. All rights reserved。
Oracle Home : /u01/app/12.1.0/grid
Central Inventory : /u01/app/oraInventory
from : /u01/app/12.1.0/grid/oraInst.loc
OPatch version : 12.1.0.1.3
OUI version : 12.1.0.2.0
Log file location : /u01/app/12.1.0/grid/cfgtoollogs/opatch/opatch2023-04-21_11-41-25午前_1.log
Lsinventory Output file location : /u01/app/12.1.0/grid/cfgtoollogs/opatch/lsinv/lsinventory2023-04-21_11-41-25午前.txt
--------------------------------------------------------------------------------
インストールされた最上位製品(1):
Oracle Grid Infrastructure 12c 12.1.0.2.0
このOracleホームには1の製品がインストールされています。
このOracleホームには仮パッチがインストールされていません。
--------------------------------------------------------------------------------
★PSR 12.1.0.2.0が適用されている。PSUなどは適用していないため、「このOracleホームには仮パッチがインストールされていません。」と出ている
②製品のパッチバージョン確認(Oracleホーム)
Database製品(Oracleホーム)に適用されているパッチバージョンを確認します
【検証手順】
1. パッチバージョン確認
【作業ログ】
[oracle@OTDCNA01 ~]$ opatch lsinventory
Oracle Interim Patch Installerバージョン12.1.0.1.3
Copyright (c) 2023, Oracle Corporation. All rights reserved。
Oracle Home : /opt/app/oracle/product/12.1.0/dbhome_1
Central Inventory : /opt/app/oraInventory
from : /opt/app/oracle/product/12.1.0/dbhome_1/oraInst.loc
OPatch version : 12.1.0.1.3
OUI version : 12.1.0.2.0
Log file location : /opt/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2023-04-21_10-52-15午前_1.log
Lsinventory Output file location : /opt/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/lsinv/lsinventory2023-04-21_10-52-15午前.txt
--------------------------------------------------------------------------------
インストールされた最上位製品(1):
Oracle Database 12c 12.1.0.2.0
このOracleホームには1の製品がインストールされています。
このOracleホームには仮パッチがインストールされていません。
--------------------------------------------------------------------------------
★PSR12.1.0.2.0が適用されている。PSUなどは適用していないため、「このOracleホームには仮パッチがインストールされていません。」と出ている
※SQLでもバージョンは確認できますが、確認できるのはPSRのみでPSUなどのバージョンは確認できません
SQL> select BANNER from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE 12.1.0.2.0 Production
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
■参考資料
OPatchautoを使用したパッチ適用オーケストレーション
OPatchを使用したバイナリ・パッチ適用
Oracle Databaseのリリース番号の概要
用語集
Oracle Databaseのリリース番号について
https://www.oracle.com/webfolder/technetwork/jp/ondemand/ddd2014/B2-4.pdf(パッチ計画のベスト・プラクティスとパッチ適用時の性能トラブルを未然に防ぐ現場ワザ)
Oracle Database 最新情報と年次リリースモデルに関して - Speaker Deck
データベース・パッチセットの種類と特徴について | NTTデータ先端技術株式会社
オラクルマスター教科書 Gold DBA Oracle Database AdministrationⅡ
オラクルマスター教科書 Oracle Expert RAC 11g R2編
絵で見てわかるシステム構築のためのOracle設計
■おわりに
従来型リリースモデルはパッチの種類によって提供時期が不定期だったり、種類が多かったり分かりにくい印象でした。
年次リリースモデルはパッチの種類に関係なく提供時期が定期的となり、従来型リリースモデルに比べ種類も少なくなったため、分かりやすくなった印象です。
結果不正などのバグフィックスやオプティマイザ修正を伴うパッチを適用した場合、アプリケーション(SQL)の実行計画に影響が出る可能性があるため、アプリケーションの再テストが推奨されています。
なお、RURはRU19.16.0で廃止され、19.17.0以降はMRP(Monthly Recommended Patches)としてパッチ提供するスタイルに変わりました。
※現時点でMRPはLinuxプラットフォームのみ対応しており、他のプラットフォームでRUに含まれていない修正は個別パッチを適用する必要があります。