こんにちは、おうどんです🍜
ななみさん、CPU_COUNT を 8 にしたら、Oracle に断られた
何と言われました?
ORA-02097。しかも2回
理由は?
……2回とも、言ってくれなかった
(会話と、この記事の作業の場面は、説明用に作ったものです)
うどん屋さんのカウンターで「8玉ください」と頼んだら、店員さんに「そのご注文は承れません。そのご注文は承れません」と2回言われた。
理由は言わない。
メニューにも載っているし、昨日は通ったのに。
Oracle の CPU_COUNT(Oracle が使ってよい CPU の数の設定)を変えようとして ORA-02097 が出たときは、だいたいこんな気持ちになります。
実はこの「理由」、Oracle はちゃんと書いています。
カウンターではなく、厨房の日誌、つまりアラートログ(データベースの出来事を時刻つきで残す記録)に。
この記事では、CPU_COUNT が変えられないときに、どこから何の順番で調べるかをまとめます。
CPU_COUNT とは何か、OCPU や OS の CPU の数とどう違うか、インスタンス・ケージング(CPU の使用量の上限)の話は、OracleのCPU_COUNTとOSのCPU数・OCPUは何が違う?に書いたので、ここでは「変えられないとき」に絞ります。
検証は、今回の検証環境(Oracle Database 19c 19.3、シングルインスタンス・CDB 構成、論理 CPU 4つ)で実行しました。
ORA-02097 は「値がダメ」としか言わない
画面に出るのは、これだけです。
alter system set cpu_count = 8 scope = memory;
alter system set cpu_count = 8 scope = memory
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-02097: parameter cannot be modified because specified value is invalid
(今回の検証環境の CDB$ROOT で実行した結果です。ORA-02097 が2行出ているのも、出力のままです)
意味は「パラメータは変更できるが、指定した値が受け入れられない」。
何が受け入れられないのか、どこと比べてダメなのかは、この画面には出てきません。
2回言ってるってことは、大事なことなんですね!
大事なことなら、1回でいいから理由を言ってほしい。
同じ ORA-02097 でも、今回の検証では理由が2種類ありました(あとで実際に見ます)。
- OS の CPU の数を超えている
- PDB で、CDB 全体の CPU_COUNT を超えている
画面だけ見ていると、この2つは見分けがつきません。
「OCPU は増やしたはずなのに」と、クラウドのコンソールを何回も開き直すことになります。おうどんなら3回は開きます。3回開いても、数字は変わりません。
「変えられない」は、エラー番号でまず3つに分ける
CPU_COUNT を変えようとして断られるとき、エラー番号は1種類ではありません。
まず番号で、話の入口を分けます。
今回の検証環境で、断られる書き方を順に流しました。
set lines 200 pages 200 tab off feedback on
col name for a14
col value for a60
col message_text for a100
col ts for a8
prompt ===== 1 session
alter session set cpu_count = 2;
prompt ===== 2 not integer
alter system set cpu_count = 2.5 scope = memory;
prompt ===== 3 over OS
alter system set cpu_count = 8 scope = memory;
prompt ===== 4 PDB over CDB
alter system set cpu_count = 2 scope = memory;
alter session set container = pdb19;
alter system set cpu_count = 3 scope = memory;
alter session set container = cdb$root;
alter system reset cpu_count scope = memory;
prompt ===== alert log
select to_char(originating_timestamp, 'HH24:MI:SS') ts, message_text
from v$diag_alert_ext
where originating_timestamp > systimestamp - interval '2' minute
and message_text like 'ORA-2097%'
order by originating_timestamp;
select value from v$diag_info where name = 'Diag Trace';
select name, value, isdefault, ismodified from v$parameter where name = 'cpu_count';
exit
===== 1 session
alter session set cpu_count = 2
*
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this option
===== 2 not integer
alter system set cpu_count = 2.5 scope = memory
*
ERROR at line 1:
ORA-02017: integer value required
===== 3 over OS
alter system set cpu_count = 8 scope = memory
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-02097: parameter cannot be modified because specified value is invalid
===== 4 PDB over CDB
System altered.
Session altered.
alter system set cpu_count = 3 scope = memory
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-02097: parameter cannot be modified because specified value is invalid
Session altered.
System altered.
===== alert log
TS MESSAGE_TEXT
-------- ----------------------------------------------------------------------------------------------------
08:16:52 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
08:16:52 ORA-2097: CPU_COUNT for pdb 3 cannot be set to 3 because it exceeds 2, the CPU_COUNT for the CDB
2 rows selected.
VALUE
------------------------------------------------------------
C:\APP\<user>\diag\rdbms\cdb19\cdb19\trace
1 row selected.
NAME VALUE ISDEFAULT ISMODIFIED
-------------- ------------------------------------------------------------ --------- ----------
cpu_count 4 TRUE FALSE
1 row selected.
(今回の検証環境の CDB$ROOT から / as sysdba で実行した結果です。パスの一部を伏せています。最後の行で、CPU_COUNT が元の 4・既定のままに戻っていることを確かめています)
整理すると、こうです。
| 画面のエラー | 今回の場面 | まず疑うこと |
|---|---|---|
| ORA-02096 | ALTER SESSION で変えようとした | CPU_COUNT はセッション単位では変えられない(ISSES_MODIFIABLE が FALSE)。ALTER SYSTEM で変えるものです |
| ORA-02017 | 2.5 のように整数でない値 | 値の書き方。CPU_COUNT は整数のパラメータ |
| ORA-02097 | 値そのものが受け入れられない | 理由はアラートログを見る。今回の検証では「OS の CPU の数を超えた」「CDB の CPU_COUNT を超えた」の2種類 |
アラートログの行は、画面とまるで別人です。
CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS(OS が報告している CPU の数 4 を超えるので 8 にはできない)CPU_COUNT for pdb 3 cannot be set to 3 because it exceeds 2, the CPU_COUNT for the CDB(CON_ID 3 の PDB の CPU_COUNT は、CDB の CPU_COUNT 2 を超えるので 3 にはできない)
店員「そのご注文は承れません。そのご注文は承れません」
厨房の日誌「8玉は無理。てぼ(麺を茹でるかご)が4つしかない」
カウンターでは2回謝って、日誌には理由を1回だけ書く。几帳面なのか不親切なのか、判断に迷うお店です。
ちなみに、エラーの下の * の位置も、番号ごとに違っていました。
ORA-02096 は cpu_count の下、ORA-02017 は値の 2.5 の下、ORA-02097 は行の先頭。
Oracle が「ここが気に入らない」と指さしている場所なので、ちょっとしたヒントになります。
じゃあ、* が先頭なら、文の全部が気に入らないってことですか
全部ではないです。気に入らないのは値だけ。たぶん、指をさす場所を決めかねただけです。
🔰 ここまで読めば今日から困らない
- CPU_COUNT の変更で ORA-02097 が出たら、画面ではなくアラートログに理由が出ていないか見る(今回の検証環境では出ていた)
- ORA-02096 なら
ALTER SESSIONで変えようとしていないか、ORA-02017 なら値が整数かを見る - OS の CPU の数(
V$OSSTATのNUM_CPUS)を超える値は、動いたままでは設定できない - PDB の中で変えるときは、OS の数ではなく CDB の CPU_COUNT を超えていないかも見る
4行なら覚えられそうです!
覚えなくて大丈夫です。日誌の場所だけ覚えてください。
読者「4つ目の PDB の話だけ、急に難しい」
大丈夫、下の章でテイクアウト窓口のたとえを使って説明します。
ここまでで、「なぜ断られたか」の見当はつきます。
ここから先は中級者向け:確認用の SQL を1本にまとめる
変えられなかったときに、上から順に見るための SQL です。
何も変更しない、確認だけのスクリプトにしてあります。
-- cpu_count_check.sql : CPU_COUNT が変えられないときの確認用(変更はしない)
set lines 200 pages 200 tab off feedback on
col con_name for a10
col instance_name for a13
col name for a10
col value for a6
col sid for a6
col stat_name for a14
col message_text for a100
col ts for a19
prompt ===== 1. いまどこにつながっているか
select sys_context('USERENV', 'CON_NAME') con_name, instance_name from v$instance;
prompt ===== 2. CPU_COUNT の性質と、いまの値
select name, value, isdefault, isses_modifiable, issys_modifiable, ispdb_modifiable
from v$parameter where name = 'cpu_count';
prompt ===== 3. 次の起動で読まれる値(SPFILE)
select sid, name, value, isspecified from v$spparameter where name = 'cpu_count';
prompt ===== 4. インスタンスごとの OS の CPU 数と CPU_COUNT
select o.inst_id, o.stat_name, to_char(o.value) value
from gv$osstat o where o.stat_name in ('NUM_CPUS', 'NUM_CPU_CORES')
order by o.inst_id, o.stat_name;
select inst_id, con_id, name, value from gv$system_parameter
where name = 'cpu_count' order by inst_id, con_id;
prompt ===== 5. 直近1時間の ORA-2097 の理由(アラートログ)
select to_char(originating_timestamp, 'YYYY-MM-DD HH24:MI:SS') ts, message_text
from v$diag_alert_ext
where originating_timestamp > systimestamp - interval '1' hour
and message_text like 'ORA-2097%'
order by originating_timestamp;
exit
===== 1. いまどこにつながっているか
CON_NAME INSTANCE_NAME
---------- -------------
CDB$ROOT cdb19
1 row selected.
===== 2. CPU_COUNT の性質と、いまの値
NAME VALUE ISDEFAULT ISSES ISSYS_MOD ISPDB
---------- ------ --------- ----- --------- -----
cpu_count 4 TRUE FALSE IMMEDIATE TRUE
1 row selected.
===== 3. 次の起動で読まれる値(SPFILE)
SID NAME VALUE ISSPEC
------ ---------- ------ ------
* cpu_count FALSE
1 row selected.
===== 4. インスタンスごとの OS の CPU 数と CPU_COUNT
INST_ID STAT_NAME VALUE
---------- -------------- ------
1 NUM_CPUS 4
1 NUM_CPU_CORES 2
2 rows selected.
INST_ID CON_ID NAME VALUE
---------- ---------- ---------- ------
1 0 cpu_count 4
1 row selected.
===== 5. 直近1時間の ORA-2097 の理由(アラートログ)
TS MESSAGE_TEXT
------------------- ----------------------------------------------------------------------------------------------------
2026-10-29 08:11:56 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
2026-10-29 08:11:56 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
2026-10-29 08:11:56 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
2026-10-29 08:12:15 ORA-2097: CPU_COUNT for pdb 3 cannot be set to 3 because it exceeds 2, the CPU_COUNT for the CDB
2026-10-29 08:12:15 ORA-2097: CPU_COUNT for pdb 3 cannot be set to 8 because it exceeds 2, the CPU_COUNT for the CDB
2026-10-29 08:14:40 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
2026-10-29 08:16:52 ORA-2097: CPU_COUNT cannot be set to 8 because it exceeds 4, the number of CPUs reported by the OS
2026-10-29 08:16:52 ORA-2097: CPU_COUNT for pdb 3 cannot be set to 3 because it exceeds 2, the CPU_COUNT for the CDB
8 rows selected.
(今回の検証環境の CDB$ROOT で、この記事の検証の途中で何度か断られたあとに実行した結果です。8行あるのは、検証で同じ失敗を何回も試したからです)
8回断られてる。カウンターの店員さんに顔を覚えられた
店員「8玉の人、また来た」
1時間に8回も同じ注文をする客は、たぶん検証の人かおうどんです。
読み方:5つの番号ごとに、何を確かめるか
| 番号 | 見るもの | こうなっていたら |
|---|---|---|
| 1 | CON_NAME | CDB$ROOT ではなく PDB の名前なら、上限は CDB の CPU_COUNT のほうかもしれない(下の章) |
| 2 | ISSES_MODIFIABLE と ISSYS_MODIFIABLE | CPU_COUNT は FALSE と IMMEDIATE。ALTER SESSION ではなく ALTER SYSTEM で、動いたまま変えられるパラメータ |
| 3 | V$SPPARAMETER の VALUE | 空なら SPFILE に書かれていない。値があるなら、次の起動でその値が読まれる(ただし頭打ちあり。下の章) |
| 4 | インスタンスごとの NUM_CPUS | 変えたい値がこの数を超えていたら、動いたままでは設定できない。RAC なら行がインスタンスの数だけ出る |
| 5 | アラートログの ORA-2097 の行 | 理由の文章。number of CPUs reported by the OS なら OS の数、CPU_COUNT for the CDB なら CDB の値と比べられている |
4 の NUM_CPUS は、OS がいま報告している数です。
クラウドで OCPU を増やしても、OS から見える数が変わっていなければ、Oracle から見ても増えていません。「増やしたはず」のときは、ここで「Oracle から見て増えたか」を先に確かめます。
コンソールでは増えてます!
コンソールは注文伝票。てぼが厨房に届いたかは、厨房で数える
伝票を何枚書いても、かごは増えません。
アラートログをファイルで見るとき
V$DIAG_ALERT_EXT は、ADR(Oracle の診断情報の置き場所)にある XML 形式のアラートログの中身を見せるビューです。
SQL で引けない環境(権限がない、など)なら、ファイルを直接見ます。テキスト形式のアラートログの場所は V$DIAG_INFO の Diag Trace に出ます(上の結果の C:\APP\<user>\diag\rdbms\cdb19\cdb19\trace)。
管理者ガイドでは、アラートログの中身を機械で読み取るなら、テキスト版ではなく XML 版を使うように勧めています。テキスト版の形式はリリースで変わることがあるためです。
ファイルで探すときは、ORA-2097 で検索します。画面の ORA-02097 とは、0 が1つ少ない書き方でした(今回の検証環境のアラートログでは)。
02097 で検索して、0件だった
0 を1つ減らすと、ちゃんと出てきます。0 の数だけで、半日迷子になれる。
今回、アラートログに出なかったもの
同じ検証の中で、ORA-02096(ALTER SESSION)と ORA-02017(整数でない値)は、アラートログを検索しても1件も見つかりませんでした(直近1時間で 2096 か 2017 を含む行を数えて 0 件)。
今回の検証環境では、理由の行がアラートログに残ったのは ORA-02097 だけです。
この2つは、画面のエラーだけで原因が分かる種類なので、困りはしません。
中級者の落とし穴:PDB の上限は、OS ではなく CDB の CPU_COUNT
CPU_COUNT は PDB の中でも変えられます(ISPDB_MODIFIABLE が TRUE)。
上の検証の 4 番目では、CDB$ROOT の CPU_COUNT を 2 にしてから、PDB19 の中で 3 にしようとしました。
OS の CPU は 4 つあります。3 は OS の数を超えていません。
それでも ORA-02097 でした。アラートログの理由は exceeds 2, the CPU_COUNT for the CDB。
つまり今回の検証では、PDB の CPU_COUNT は、OS の数ではなく、そのとき CDB 全体に設定されている CPU_COUNT と比べられていました。
お店全体で、てぼは2つ。テイクアウト窓口だけ3つ使います!
店員「お店に2つしかないので、窓口に3つは渡せません」
正論すぎて、言い返せない。
この順番で作業すると引っかかります。
- 夜間に、CDB の CPU_COUNT を小さくしておく(試験やリソースの調整で)
- 翌朝、別の人が PDB の CPU_COUNT を、OS の数より小さい値に上げようとする
- ORA-02097。OS の数は足りているので、首をかしげる
翌朝の人「OS には 4 つある。なのに 3 がダメ。Oracle が数え間違えてる?」
数え間違えているのは、たいてい夜のうちに書かれなかった引き継ぎメモのほうです。
確認の SQL の 1 番(どこにつながっているか)と、4 番の GV$SYSTEM_PARAMETER(CON_ID 0 の行が CDB 全体の値)を並べて見ると、すぐ分かります。
今回は、CDB の値を 2 にした状態で PDB に 3 と 8 を試し、どちらもこの理由で断られました(確認の SQL の 5 番の結果の 08:12:15 の2行)。
この上限のことは、CPU_COUNT のリファレンスには書かれていなかったので、19c の公式ドキュメントで確かめられた話ではなく、今回の検証環境で見えた動きとして書いています。
中級者の落とし穴:SCOPE=SPFILE なら通る。でも起動すると、黙って頭打ち
動いたままで ORA-02097 になるなら、SPFILE(サーバーが起動時に読む設定ファイル)にだけ書けばいいのでは。
と考える人のために、試しました(再起動します)。
set lines 200 pages 200 tab off feedback on
col name for a14
col value for a10
col sid for a6
col message_text for a80
col ts for a8
alter system set cpu_count = 8 scope = spfile;
select sid, name, value, isspecified from v$spparameter where name = 'cpu_count';
select name, value, isdefault from v$parameter where name = 'cpu_count';
shutdown immediate
startup
select name, value, isdefault from v$parameter where name = 'cpu_count';
select sid, name, value, isspecified from v$spparameter where name = 'cpu_count';
select to_char(originating_timestamp, 'HH24:MI:SS') ts, message_text
from v$diag_alert_ext
where originating_timestamp > systimestamp - interval '3' minute
and lower(message_text) like '%cpu%'
order by originating_timestamp;
prompt ===== revert
alter system reset cpu_count scope = spfile;
shutdown immediate
startup
select name, value, isdefault, ismodified from v$parameter where name = 'cpu_count';
select sid, name, value, isspecified from v$spparameter where name = 'cpu_count';
select name, open_mode from v$pdbs order by con_id;
exit
System altered.
SID NAME VALUE ISSPEC
------ -------------- ---------- ------
* cpu_count 8 TRUE
1 row selected.
NAME VALUE ISDEFAULT
-------------- ---------- ---------
cpu_count 4 TRUE
1 row selected.
Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.
Total System Global Area 2147483144 bytes
Fixed Size 9268744 bytes
Variable Size 503316480 bytes
Database Buffers 1627389952 bytes
Redo Buffers 7507968 bytes
Database mounted.
Database opened.
NAME VALUE ISDEFAULT
-------------- ---------- ---------
cpu_count 4 FALSE
1 row selected.
SID NAME VALUE ISSPEC
------ -------------- ---------- ------
* cpu_count 8 TRUE
1 row selected.
TS MESSAGE_TEXT
-------- --------------------------------------------------------------------------------
08:18:24 ALTER SYSTEM SET cpu_count=8 SCOPE=SPFILE;
08:19:21 Initial number of CPU is 4
08:19:30 CPU : 4 - type 86642 physical cores
08:19:30 cpu_count = 4
4 rows selected.
===== revert
System altered.
Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.
Total System Global Area 2147483144 bytes
Fixed Size 9268744 bytes
Variable Size 503316480 bytes
Database Buffers 1627389952 bytes
Redo Buffers 7507968 bytes
Database mounted.
Database opened.
NAME VALUE ISDEFAULT ISMODIFIED
-------------- ---------- --------- ----------
cpu_count 4 TRUE FALSE
1 row selected.
SID NAME VALUE ISSPEC
------ -------------- ---------- ------
* cpu_count FALSE
1 row selected.
NAME OPEN_MODE
-------------- ----------
PDB$SEED READ ONLY
PDB19 READ WRITE
2 rows selected.
(今回の検証環境の CDB$ROOT で実行した結果です。後半の revert で SPFILE から cpu_count を消して再起動し、元の状態に戻しています)
起きたことを並べます。
SCOPE = SPFILEの 8 は、エラーなしで通った。V$SPPARAMETERは 8- 再起動すると、
V$PARAMETERの cpu_count は 4。ただしISDEFAULTはFALSE(自分で値を指定した扱い) - 再起動したあとも、
V$SPPARAMETERは 8 のまま - アラートログには、起動時の設定一覧に
cpu_count = 4と出るだけ。8 を 4 に下げた、という行は、cpuを含む行を探した範囲では見つからなかった
リファレンスには、初期化パラメータファイルに CPU の数より大きい値を書いた場合は、CPU の数で頭打ちになる、とあります。今回はその動きを、そのまま確かめられました。
店員「8玉、予約で承りました!」
翌日の店員「てぼが4つなので、4玉で出しておきました。何も言わずに」
予約票は8玉のまま。言ってくれたら、玉の数で揉めずに済んだのに。
困るのは、SPFILE と実際の値が食い違ったまま残ることです。SHOW PARAMETER は 4、SPFILE は 8。
次に見た人「どっちが本当なの?」
どっちも本当なのが、いちばん困る。
それと、これはリファレンスの書き方から考えたことで、今回は試していません。
SPFILE に 8 が残ったまま、あとで OS の CPU が 8 以上に増えてから再起動すると、そのときは頭打ちにならずに 8 で動き出すはずです。いつの間にか設定が効きはじめる、時限式の設定になります。
SCOPE=SPFILE は、ORA-02097 の逃げ道にしない。OS の数が増えたことを確かめてから、動いたまま変えるのが素直です。
変更するときの手順:確認用と変更用を分ける
確認用は、上の cpu_count_check.sql です。変更用はこちら。
前提
- 変更前に、
cpu_count_check.sqlの結果(とくに 2・3・4)を保存しておく - 変えたい値が、変える場所の上限(CDB$ROOT なら
NUM_CPUS、PDB なら CDB の CPU_COUNT)以下であること
影響範囲
- リファレンスによると、オプティマイザ(SQL の実行計画を決める仕組み)、パラレル・クエリ、リソース・マネージャなどが、CPU の数をもとに設定される。値を変えると、これらの前提が変わる
- 0 以外の値を入れると、OS の CPU の数が変わっても自動では追いかけなくなる(リファレンスでは、動的な CPU の再構成が無効になる、と書かれている)
固定にしておけば、勝手に変わらなくて安心ですね!
勝手に変わらないかわりに、CPU を増やしても勝手には増えません。安心と放置は、紙一重です。
RESOURCE_MANAGER_PLANが設定されていると、CPU の使用量の上限としても効く(インスタンス・ケージング)。詳しくはCPU_COUNT と OCPU の記事へ
反映時期
ISSYS_MODIFIABLEがIMMEDIATEなので、ALTER SYSTEMで動いたまま反映されるSCOPE = MEMORYは再起動で消える。SCOPE = BOTHは SPFILE にも残る
-- 変更(CDB$ROOT で、まずメモリーだけ)
alter system set cpu_count = 2 scope = memory;
-- 戻す(変更前が既定値で、SPFILE にも書いていなかった場合)
alter system reset cpu_count scope = memory;
今回の検証環境で実行したのは、この SCOPE = MEMORY の変更と RESET です(上の「3つに分ける」の章のスクリプトの中で流しています)。
受け入れられる値での SCOPE = BOTH と、そのあとの戻し方(ALTER SYSTEM RESET cpu_count SCOPE = BOTH など)は、今回は実行していません。
変更後の確認
cpu_count_check.sqlをもう一度流し、2 の値、3 の SPFILE、4 のGV$SYSTEM_PARAMETERが狙いどおりかを見る- 5 に新しい ORA-2097 の行が増えていないかを見る
戻し方
- 今回のように
SCOPE = MEMORYだけで変更した場合、戻し先は変更前の 2 番のメモリー値。変更前が既定値ならRESET ... SCOPE = MEMORY、明示的な値ならその値をSET ... SCOPE = MEMORYで設定し直す。SPFILE は変更しない - SPFILE も変更した場合は、変更前の 3 番の保存値・
ISSPECIFIED・SIDも別に復元する。メモリー値と保存値が違っていた場合、1つの値をSCOPE = BOTHで入れても元の状態には戻らない
手順、長くない? 1行で変えて1行で戻すだけなのに
その1行の前に、元の値のメモが要るんです。メモがないと、戻し先が分からない。戻す1行より、元の値のメモのほうが大事です。
ここから先は上級者向け。読み飛ばしてもOKです:RAC・GV$・アラートログの見え方
RAC では、インスタンスごとに数える
GV$ のビューは、RAC(複数のサーバーで1つのデータベースを動かす構成)では、すべてのインスタンスの V$ の情報をまとめて返し、INST_ID 列でどのインスタンスの行かを示します。cpu_count_check.sql の 4 番で GV$OSSTAT と GV$SYSTEM_PARAMETER を使っているのは、このためです。今回の検証環境はシングルインスタンスなので、INST_ID は 1 だけでした。
RAC では、サーバーごとに CPU の数が違うこともあります。
1号機は 8、2号機は 4。この状態で全インスタンスに 8 を入れようとすれば、2号機で断られるはずです(RAC は今回は実行できないので、確かめていません)。
リファレンスでは、CPU_COUNT は RAC のすべてのインスタンスで同じ値を使うべき、とされています。
「どのインスタンスで断られたか」と「インスタンスごとの NUM_CPUS」を並べて見ると、どこの CPU を増やし忘れたかが見えます。
2号機の CPU が足りないなら、2号機だけ CPU_COUNT を 4 にすればいいですね!
それ、同じ値にしようねって言われてるやつ
設定はできても、すすめられていない。この差がつらい。
ALTER SYSTEM の SID 句は、SID = '*' ならインスタンスごとの個別の設定を持っていない全インスタンスに、SID = 'インスタンス名' ならそのインスタンスだけに効きます。SPFILE で起動していて SID を省略すると '*' 扱いです。
RAC で「一部のインスタンスだけ値が違う」ときは、V$SPPARAMETER の SID 列に、* 以外の行が残っていないかも見ます。
V$DIAG_ALERT_EXT は「いまのコンテナ」のアラートログ
リファレンスでは、V$DIAG_ALERT_EXT は、いまのコンテナ(PDB)についての XML 形式のアラートログの中身を見せる、と書かれています。
今回は CDB$ROOT から引いて、PDB19 の中で出た ORA-2097 の行(CPU_COUNT for pdb 3)も見えました。PDB につないで引いたときの見え方は、今回は試していません。
PDB の担当者が自分の PDB から引いて、もし理由の行が見つからなかったら、CDB$ROOT から引いてもらうか、ファイルを見るのが確実です。
PDB 担当者「日誌を見せてください」
店員「テイクアウト窓口の分だけなら」
全部見たいなら、店長(CDB の管理者)に頼む流れになります。
19.3 と RU 適用後、ほかのリリース
今回の検証は、パッチを当てていない 19.3 です。
アラートログの文言(cannot be set to 8 because it exceeds 4 など)や、画面に ORA-02097 が2行出る出方が、RU(定期的なパッチ)を当てたあとや別のリリースでも同じかは、確かめていません。
検索するなら文言そのものより、ORA-2097 と CPU_COUNT の2語で探すほうが外れにくいはずです。
それと、0(既定値)のままなら、Oracle は OS が報告する CPU の数を見続けて、その数を使います。
固定の値を入れたシステムで OCPU を増やしたときは、CPU_COUNT を自分で上げる必要がある、ということです。逆に 0 のままなら、OS から見える数が増えた時点で追いかけます(今回の検証環境では CPU を増やせないので、追いかける動きは確かめていません)。
0 にしておけば勝手に増える。最高の設定じゃん
ただし、インスタンス・ケージングで CPU の上限にしたいなら、既定値のままでは上限として効きません(CPU_COUNT と OCPU の記事で確かめた話です)。便利な既定値ほど、使い道を選ぶ。
冒頭のカウンターに、もう一度
「そのご注文は承れません。そのご注文は承れません」。
次に2回言われたら、カウンターで粘らずに、厨房の日誌を開きましょう。
ORA-02097 の理由は、画面ではなくアラートログに書いてある。
OS の CPU の数か、CDB の CPU_COUNT か。どちらと比べられたかが分かれば、次にやることは決まります。
今日は確認用の SQL を先に作ってから変えましたね。いい順番です
褒められた。8回断られたかいがあった
断られた回数は、褒められた理由ではありません。
じゃあ次は、9回目に挑戦します!
挑戦しなくていいです。まずは cpu_count_check.sql の 5 番だけでも、手元のデータベースで流してみてください。断られた記録が、ちゃんと残っているはずです🍜
参考資料
- Oracle Database 19c リファレンス:CPU_COUNT — 既定値 0 は OS の CPU の数を見続ける、0 以外で動的な再構成が無効になる、CPU の数より大きい値はエラーで、パラメータファイルに書いた場合は頭打ち、PDB で変更可、RAC では全インスタンスで同じ値、オプティマイザなどが CPU の数をもとに設定される
- Oracle Database 19c SQL 言語リファレンス:ALTER SYSTEM — SCOPE の MEMORY・SPFILE・BOTH の反映時期、SID 句の ‘*’ と個別のインスタンス、SID 省略時の扱い
- Oracle Database 19c リファレンス:V$DIAG_ALERT_EXT — ADR の XML 形式のアラートログの中身を、いまのコンテナについて見せるビュー、ORIGINATING_TIMESTAMP と MESSAGE_TEXT
- Oracle Database 19c 管理者ガイド:問題の診断と解決 — アラートログの中身、テキスト版と XML 版、解析には XML 版を勧めること、V$DIAG_INFO の Diag Trace
- Oracle Database 19c リファレンス:動的パフォーマンス・ビューについて(GV$ ビュー) — RAC で GV$ が全インスタンスの情報を返すこと、INST_ID 列
2026年10月時点の内容です。










コメント