こんにちは、おうどんです🍜
新人さん「OPEN_CURSORS を増やしたいんですけど、DB の再起動っていります?」
おうどん「いい質問だね。……ちょっと待ってね」
おうどん(心の声)「……どっちだっけ」
(会話は説明用の架空の場面です)
正直に言います。 この「再起動いる?いらない?」、おうどんも何度も迷ったことがある疑問です。
PROCESSES は? CPU_COUNT は? そのたびに検索して、ブログを3つ開いて、書いてあることが微妙に違って、そっと閉じる。
新人さん「じゃあ、念のため再起動しておきます?」
おうどん「本番で『念のため』の再起動は、だいたい念のためじゃ済まないんだよ……」
……念のための再起動で、念入りに怒られる。よくある話です。
でも、実はこの答え、Oracle 自身が持っています。 しかも1行の SELECT で教えてくれます。
今回は、うどん屋のお品書きにたとえて、「再起動が必要か」を自分で調べる方法を見ていきます。
最初に、初心者向けのチェックリストです。
- 変更する前に、
V$PARAMETERのISSYS_MODIFIABLE列を見る IMMEDIATEなら今すぐ、DEFERREDなら次のセッションから、FALSEならインスタンスの再起動後に反映- 変えたあとは
SHOW PARAMETERだけでなく、V$SYSTEM_PARAMETERでも確かめる
この記事の検証は、今回の検証環境(Oracle Database 19c 19.3、シングルインスタンス・CDB 構成)で、SQL*Plus から実行したものです。
答えは V$PARAMETER の ISSYS_MODIFIABLE 列に書いてある
うどん屋のお品書きには、3種類あります。
| お品書き | 書き換えたら | Oracle でいうと |
|---|---|---|
| 壁の黒板(今日のおすすめ) | いま食べているお客さんにも、すぐ見える | IMMEDIATE |
| 入口で渡すメニュー表 | 次に入ってくるお客さんから | DEFERRED |
| 店の看板 | 一度お店を閉めて、付け替えてから | FALSE |
この「どのお品書きか」が、V$PARAMETER というビューの ISSYS_MODIFIABLE 列に書いてあるんです。
Oracle Database 19c のリファレンス(V$PARAMETER)では、こう決まっています。
| ISSYS_MODIFIABLE | ALTER SYSTEM で変えられる? | いつ効く? |
|---|---|---|
IMMEDIATE | 変えられる(PFILE 起動でも SPFILE 起動でも) | すぐ |
DEFERRED | 変えられる(PFILE 起動でも SPFILE 起動でも) | 以降のセッションから |
FALSE | SPFILE で起動しているときだけ変えられる | 次のインスタンスから |
用語を少しだけ。
- 初期化パラメータ:Oracle の動き方を決める設定値(OPEN_CURSORS、PROCESSES など)
- インスタンス:Oracle が動いている本体(メモリとプロセス)。「DB の再起動」は、ふつうこれの再起動です
- セッション:1つの接続。SQL*Plus を1つ開くと1セッション
- SPFILE(サーバー・パラメータ・ファイル):設定値を保存しておくファイル。再起動したときに読まれます。昔ながらのテキスト版は PFILE
つまり、FALSE の看板は、お店を閉めないと付け替えられない。
そういうことです。 お客さんが食べている最中に、はしごを持って看板を外しはじめたら、それはもう営業妨害です。
調べ方はこれだけ。
select name, value, issys_modifiable, isses_modifiable
from v$parameter
where name in ('open_cursors', 'processes', 'sort_area_size');
NAME VALUE ISSYS_MODIFIABLE ISSES_MODIFIABLE
---------------- -------- ---------------- ----------------
processes 320 FALSE FALSE
sort_area_size 65536 DEFERRED TRUE
open_cursors 300 IMMEDIATE FALSE
3 rows selected.
(今回の検証環境の CDB$ROOT に SYSDBA で接続し、SQL*Plus で col で列幅をそろえて実行した結果です)
冒頭の新人さんの OPEN_CURSORS は IMMEDIATE。黒板です。再起動はいりません。 PROCESSES は FALSE。看板です。再起動が必要です。
新人さん「えっ、じゃあ今までの検索、なんだったんですか」
おうどん「……旅だね」
……答えは、ずっと目の前のビューに書いてあったわけです。
ちなみに ISSES_MODIFIABLE は、ALTER SESSION(自分のセッションだけ変える)で変えられるかどうかです。こちらは「自分の席のテーブルに、自分用のメモを置けるか」くらいの話で、再起動とは別の軸です。
公式ドキュメントの各パラメータのページにも「Modifiable」という欄があって、同じことが書いてあります。たとえば PROCESSES は Modifiable が No、OPEN_CURSORS は ALTER SYSTEM、SORT_AREA_SIZE は ALTER SESSION, ALTER SYSTEM ... DEFERRED です。
おうどん「ドキュメントとビュー、両方に書いてある。親切だね」
Oracle「はい。なので今まで聞かれるたびに、ちょっと寂しかったです」
……DB に寂しい思いをさせていた。反省します。
IMMEDIATE は「いま食べている人の黒板」まで書き換わる
黒板のおすすめを書き換えると、もう座っているお客さんからも見えます。 IMMEDIATE は、いま接続しているセッションの値まで、その場で変わります。
OPEN_CURSORS(1セッションが同時に開けるカーソルの上限)を、300 から 400 に変えてみました。
alter system set open_cursors = 400 scope = memory;
System altered.
同じセッションのまま、自分のセッションの値(V$PARAMETER)と、インスタンス全体の値(V$SYSTEM_PARAMETER)を並べてみます。
select p.name, p.value, s.value sys_value, p.ismodified
from v$parameter p join v$system_parameter s on s.name = p.name
where p.name in ('open_cursors','sort_area_size','open_links') order by p.name;
NAME VALUE SYS_VALUE ISMODIFIED
---------------- ---------- ---------- ----------
open_cursors 400 400 SYSTEM_MOD
open_links 4 4 FALSE
sort_area_size 65536 131072 SYSTEM_MOD
3 rows selected.
(今回の検証環境で、この章から次の次の章までの ALTER SYSTEM を同じセッションで続けて実行したあとの結果です。sort_area_size と open_links の行は、あとの章で説明します)
open_cursors は、自分のセッションの値も 400 になっています。 ISMODIFIED の SYSTEM_MOD は、リファレンスによると ALTER SYSTEM で変更されたしるしで、そのとき接続中のすべてのセッションの値も変わる、と説明されています。
新人さん「じゃあ IMMEDIATE なら、本番でいつでも気軽に変えていいんですね」
おうどん「黒板を書き換えた瞬間に、『そのおすすめ、さっき頼んだのと違う』って言い出すお客さんもいるからね」
……「再起動がいらない」と「影響がない」は、別の話です。 すぐ効くということは、動いている処理にもすぐ効く、ということでもあります。変更の時間帯と、戻し方は、IMMEDIATE でも用意しておきましょう。
ちなみに SCOPE = MEMORY は「メモリの上だけ変える(再起動したら元に戻る)」という意味です。SCOPE は次の看板の章でもう一度出てきます。
おうどん「じゃあ黒板は、毎日書き換え放題だね」
Oracle「チョークは、本番環境ではわりと高価です」
……変更管理の申請書のことを言っているなら、その通りです。
DEFERRED は「次に来たお客さん」から。今の自分は古いメニューのまま
入口で渡すメニュー表を刷り直しても、もう席にいるお客さんの手元のメニューは古いままです。 DEFERRED は、これから接続するセッションから効きます。
SORT_AREA_SIZE(ソートに使うメモリの上限)で試します。 なお、ここでは設定値の反映タイミングを見ています。ソート作業領域が自動管理(WORKAREA_SIZE_POLICY = AUTO)の場合、実際のメモリ量は自動調整されるため、SORT_AREA_SIZE の変更がそのままソートのメモリ量を変えるわけではありません(WORKAREA_SIZE_POLICY のリファレンス)。 まず、DEFERRED を書かずに変えると。
alter system set sort_area_size = 131072 scope = memory;
alter system set sort_area_size = 131072 scope = memory
*
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this option
怒られました。 ALTER SYSTEM のリファレンスには、ISSYS_MODIFIABLE が DEFERRED のパラメータは DEFERRED を書かなければならない、とあります。
Oracle「メニュー表の刷り直しですね。『次のお客さんから』と一筆いただけますか」
おうどん「……書かないとダメなの?」
Oracle「書かないと、いま食べている人の分まで刷り直すつもりだと思うので」
……念押しの確認が、ちゃんとエラーという形で返ってくる。まじめな番頭さんです。
DEFERRED を書くと通ります。
alter system set sort_area_size = 131072 deferred scope = memory;
System altered.
さっきの章の表をもう一度見てください。sort_area_size の行は、自分のセッションの値(VALUE)が 65536 のまま、インスタンス全体の値(SYS_VALUE)が 131072 でした。 変更した本人のセッションには、効いていないんです。
そこで、SQL*Plus をもう1つ起動して、新しいセッションで同じ SELECT を実行しました。
NAME VALUE SYS_VALUE ISMODIFIED
---------------- ---------- ---------- ----------
open_cursors 400 400 SYSTEM_MOD
open_links 4 4 FALSE
sort_area_size 131072 131072 SYSTEM_MOD
3 rows selected.
(今回の検証環境で、新しく接続したセッションから、前の章と同じ SELECT を実行した結果です)
新しいセッションでは 131072。 これが「以降のセッションから」の意味です。
新人さん「じゃあ、アプリの接続プールで朝からずっとつながっているセッションは……」
おうどん「開店からずっと座っている常連さんだね。古いメニューのままだよ」
……常連さんほど、新メニューに気づかない。うどん屋でも DB でも同じです。
接続プール(アプリが接続を使い回すしくみ)を使っているシステムでは、DEFERRED の変更が全部の処理に行き渡るのは、接続がつなぎ直されたあとです。いつ行き渡るかは、アプリ側の設定しだいです。
FALSE は看板。ALTER SYSTEM は「成功」するのに、値は変わらない
さて、看板です。 FALSE のパラメータは、インスタンスを再起動しないと反映されません。
ここで一番の落とし穴があります。 FALSE のパラメータでも、ALTER SYSTEM は成功することがあります。
OPEN_LINKS(1セッションが同時に開けるデータベース・リンクの数。今回の環境では FALSE)で、3通り試しました。
alter system set open_links = 8;
alter system set open_links = 8
*
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified
alter system set open_links = 8 scope = memory;
alter system set open_links = 8 scope = memory
*
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified
alter system set open_links = 8 scope = spfile;
System altered.
(どれも今回の検証環境の CDB$ROOT で、SPFILE で起動したインスタンスに対して実行した結果です)
1つ目、SCOPE を書かないとエラー。 ALTER SYSTEM のリファレンスによると、SPFILE で起動しているときの SCOPE の既定は BOTH(メモリと SPFILE の両方)です。そして静的パラメータ(変更できないと書かれたパラメータ)には MEMORY も BOTH も指定できず、SPFILE を指定しなければなりません。 つまり、何も書かないと「今すぐ看板を付け替えて」と頼んだことになって、断られるわけです。
3つ目の SCOPE = SPFILE は成功。 では、値は変わったのか。さっきの表の open_links の行は、VALUE も SYS_VALUE も 4 のままでした。 SPFILE の中身を見るビュー V$SPPARAMETER を見ると。
select name, value, isspecified from v$spparameter where name in ('open_cursors','sort_area_size','open_links') order by name;
NAME VALUE ISSPEC
---------------- ---------- ------
open_cursors 300 TRUE
open_links 8 TRUE
sort_area_size FALSE
3 rows selected.
SPFILE の open_links は 8。動いている値は 4。 「System altered.」は、看板を発注しました、という意味なんです。付け替えは、次にお店を開けるとき(インスタンスの再起動)です。
新人さん「System altered って出たので、変更完了で報告しちゃいました」
おうどん「看板屋さんに電話しただけで、『看板変わりました!』って言っちゃったね」
……電話はした。看板は昨日のまま。報告書だけが未来に生きています。
ついでに、open_cursors の行も見てください。動いている値は 400 なのに、SPFILE は 300。 これは前の章で SCOPE = MEMORY で変えたからです。このまま再起動すると、300 に戻ります。
おうどん「つまり、黒板は書き換えたけど、明日の朝には昨日の黒板が戻ってくる」
Oracle「はい。毎朝、SPFILE を読んで開店しますので」
……忠実すぎて、ちょっとホラーです。
(今回の検証で変えた open_cursors・sort_area_size は元の値に戻し、open_links は ALTER SYSTEM RESET で SPFILE から消して、元の状態に戻したことを確認しています)
🔰 ここまで読めば今日から困らない
- 再起動が必要かは、
V$PARAMETERのISSYS_MODIFIABLEで分かるIMMEDIATE:すぐ効く。今いるセッションにも効くDEFERRED:DEFERREDを書いて変える。これから接続するセッションから効くFALSE:SCOPE = SPFILEで変えて、インスタンスの再起動後に効く
- 「System altered.」は、反映完了の合図ではない
- 再起動がいらなくても、影響がないとは限らない
ここから先は中級者向け。確認の仕方と、CDB・PDB での注意です。
SHOW PARAMETER は「自分の席から見えるメニュー」しか見せない
変更のあと、SHOW PARAMETER で確認する人は多いと思います。おうどんもそうです。 でも、SHOW PARAMETER が見せてくれるのは、自分のセッションの値でした。
DEFERRED のパラメータを変えた直後に、同じセッションで SHOW PARAMETER と V$SYSTEM_PARAMETER を並べてみました。
alter system set sort_area_size = 131072 deferred scope = memory; show parameter sort_area_size select name, value from v$system_parameter where name = 'sort_area_size';
System altered.
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sort_area_size integer 65536
NAME VALUE
---------------- ----------
sort_area_size 131072
1 row selected.
(今回の検証環境で、同じセッションで続けて実行した結果です。このあと 65536 に戻しています)
SHOW PARAMETER は 65536。インスタンス全体は 131072。 リファレンスでも、V$PARAMETER はセッションで有効な値、V$SYSTEM_PARAMETER はインスタンスで有効な値で、新しいセッションはインスタンスの値を引き継ぐ、と区別されています。今回の結果からは、SHOW PARAMETER もセッション側の値を出していると分かります。
新人さん「SHOW PARAMETER で見たら変わってなかったので、もう1回 ALTER SYSTEM しました」
おうどん「メニュー表を2回刷ったね」
新人さん「3回目もいきますか?」
……刷るたびに、自分の手元のメニューだけは古いまま。永遠に終わらない印刷所です。
確認の場所は、変えたものに合わせて使い分けます。
| 確認したいこと | 見る場所 |
|---|---|
| インスタンス全体で、いま有効な値 | V$SYSTEM_PARAMETER |
| 自分のセッションで有効な値 | V$PARAMETER、SHOW PARAMETER |
| 再起動後に使われる値(SPFILE の中身) | V$SPPARAMETER |
V$SPPARAMETER は、リファレンスによると、SPFILE を使わずに起動したインスタンスでは、全部の行の ISSPECIFIED が FALSE になります。SPFILE で起動しているかどうかは、先に確かめておきましょう(あとの完成 SQL に入れています)。
おうどん「つまり、黒板・メニュー表・看板の発注書。見る場所が3つある」
Oracle「4つ目に、お客さんの記憶もあります」
……それはアプリのキャッシュの話なので、また今度にしてください。
CDB・PDB では「どの階で変えるか」も確かめる
CDB(コンテナ・データベース。親)と PDB(プラガブル・データベース。親の中にある子のデータベース)の構成では、もう1つ見る列があります。 ISPDB_MODIFIABLE。PDB の中で変えられるかどうかです。
うどん屋でいうと、ビルの1階が本店(CDB$ROOT)、2階以上がのれん分けしたお店(PDB)。 看板の一部は、ビル全体で1枚しかありません。
PDB19 に切り替えて、ISPDB_MODIFIABLE が FALSE の DB_CACHE_ADVICE を、今と同じ値 ON に設定してみました。
alter session set container = pdb19; alter system set db_cache_advice = ON scope = memory;
Session altered.
alter system set db_cache_advice = ON scope = memory
*
ERROR at line 1:
ORA-65040: operation not allowed from within a pluggable database
(今回の検証環境で実行した結果です。このあいだに show con_name と現在値の確認をはさんでいますが、ここでは省いています)
ORA-65040。「PDB の中ではできません」。 ISSYS_MODIFIABLE が IMMEDIATE でも、PDB の中からは変えられないパラメータがあるんです。
新人さん「2階のお店から、ビルの看板を付け替えようとしました」
おうどん「管理会社に止められたね」
……テナントが勝手にビルの看板を替えたら、そりゃ止められます。
PDB の中で変えたときの反映のしかたも、CDB$ROOT とは少し違います。ALTER SYSTEM のリファレンスでは、PDB に接続して変えるときは、こう説明されています。
| SCOPE | PDB の中で変えたとき |
|---|---|
MEMORY | その PDB ですぐ有効。PDB を閉じて開き直すと、CDB$ROOT の値に戻る |
SPFILE | その PDB 用に保存。PDB を閉じて開き直すか、CDB を再起動したときに有効 |
BOTH | すぐ有効になり、保存もされる。その PDB だけに効く |
なお、DEFERRED のパラメータをメモリに反映する場合は、この表の「すぐ」ではなく、新しいセッションから有効になります。
「再起動」の対象が、インスタンス全体なのか、PDB の閉じ開きなのか。ここも、作業計画で分けて書いておきたいところです(PDB の閉じ開きは今回は試していません。リファレンスの記述に基づきます)。
おうどん「つまり2階のお店は、ビル全体を止めなくても、自分の店だけシャッターを下ろせばいい場合がある」
Oracle「そのとき2階のお客さんは、一度外に出ていただきます」
……ビルは動いていても、2階のお客さんには立派な閉店です。
完成版:変更前に流す確認 SQL と、作業メモのひな形
ここまでを1本の SQL にまとめました。 今いるコンテナ、値、変え方の目安をまとめて出します。
set lines 200 pages 200 feedback on tab off
col con for a10
col name for a16
col value for a8
col ses for a5
col sys for a9
col pdb for a5
col started_with for a12
col how_to_apply for a40
select sys_context('USERENV','CON_NAME') con,
p.name,
p.value,
p.isses_modifiable ses,
p.issys_modifiable sys,
p.ispdb_modifiable pdb,
case
when sys_context('USERENV','CON_NAME') <> 'CDB$ROOT'
and p.ispdb_modifiable = 'FALSE' then 'not in this PDB (set in CDB$ROOT)'
when p.issys_modifiable = 'IMMEDIATE' then 'now: running sessions too'
when p.issys_modifiable = 'DEFERRED' then 'DEFERRED: new sessions only'
else 'SCOPE=SPFILE, then restart'
end how_to_apply
from v$parameter p
where p.name in ('open_cursors','processes','sort_area_size','open_links','db_cache_advice')
order by p.name;
select case when value is null then 'PFILE' else 'SPFILE' end started_with
from v$parameter where name = 'spfile';
CDB$ROOT での結果です。
CON NAME VALUE SES SYS PDB HOW_TO_APPLY
---------- ---------------- -------- ----- --------- ----- ----------------------------------------
CDB$ROOT db_cache_advice ON FALSE IMMEDIATE FALSE now: running sessions too
CDB$ROOT open_cursors 300 FALSE IMMEDIATE TRUE now: running sessions too
CDB$ROOT open_links 4 FALSE FALSE TRUE SCOPE=SPFILE, then restart
CDB$ROOT processes 320 FALSE FALSE FALSE SCOPE=SPFILE, then restart
CDB$ROOT sort_area_size 65536 TRUE DEFERRED TRUE DEFERRED: new sessions only
5 rows selected.
STARTED_WITH
------------
SPFILE
1 row selected.
同じ SELECT を、alter session set container = pdb19; のあとに実行した結果です。
CON NAME VALUE SES SYS PDB HOW_TO_APPLY
---------- ---------------- -------- ----- --------- ----- ----------------------------------------
PDB19 db_cache_advice ON FALSE IMMEDIATE FALSE not in this PDB (set in CDB$ROOT)
PDB19 open_cursors 300 FALSE IMMEDIATE TRUE now: running sessions too
PDB19 open_links 4 FALSE FALSE TRUE SCOPE=SPFILE, then restart
PDB19 processes 320 FALSE FALSE FALSE not in this PDB (set in CDB$ROOT)
PDB19 sort_area_size 65536 TRUE DEFERRED TRUE DEFERRED: new sessions only
5 rows selected.
(今回の検証環境で、SYSDBA で実行した結果です。where の名前を、変えたいパラメータに書き換えて使ってください)
注意が2つあります。
then restartの「再起動」は、CDB$ROOT ならインスタンスの再起動、PDB の中ならリファレンス上は PDB の閉じ開きでも反映されます(前の章の表)spfileの値が空なら PFILE 起動です。リファレンスによると、PFILE 起動ではSCOPE = MEMORYしか指定できず、FALSE のパラメータは ALTER SYSTEM では変えられません。PFILE を直接編集して再起動する作業になります
新人さん「この SQL があれば、もう迷いませんね!」
おうどん「いや、SQL の判定はあくまで目安。最後は人間がドキュメントを読む」
新人さん「……SQL さん、責任とってくれないんですか」
……SQL は「黒板です」とは言ってくれますが、「書き換えて大丈夫です」とは言ってくれません。
変更作業のメモは、確認用と変更用を分けて、この形で書いておくと抜けが減ります。
■ 対象:open_cursors(CDB$ROOT / インスタンス全体)
■ 種類:ISSYS_MODIFIABLE = IMMEDIATE、ISPDB_MODIFIABLE = TRUE、SPFILE 起動
■ 変更前の値:V$SYSTEM_PARAMETER = 300、V$SPPARAMETER = 300(ISSPECIFIED = TRUE)
■ 変更:alter system set open_cursors = 400 scope = both;
■ 反映:すぐ(接続中のセッションにも)。再起動不要。影響:カーソル上限が上がる
■ 変更後の確認:V$SYSTEM_PARAMETER と V$SPPARAMETER がどちらも 400
■ 戻し方:alter system set open_cursors = 300 scope = both;
(変更前に SPFILE に書かれていなかったパラメータなら alter system reset <名前> scope = spfile;)
(作業メモのひな形です。この中の scope = both の行そのものは、今回は実行していません。検証では scope = memory で変更し、scope = memory で戻しました)
戻し方の ALTER SYSTEM RESET ... SCOPE = SPFILE は、今回の検証で open_links を元に戻すときに実行し、V$SPPARAMETER の ISSPECIFIED が FALSE に戻ったことを確かめています。
おうどん「戻し方まで書くの、面倒だね」
Oracle「戻し方を書いていない作業は、だいたい戻すときに一番時間がかかります」
……DB に、運用の真理を言われてしまいました。
ここから先は上級者向け。読み飛ばしてもOKです。
ビューの列だけで決めてはいけない例:SESSIONS と ISMODIFIED
ここまで「ビューを見れば分かる」と言ってきました。 でも、ビューの列だけで決めると外れる例も、今回の検証で見つかりました。
1つ目、SESSIONS。 今回の環境の CDB$ROOT では、ISSYS_MODIFIABLE が IMMEDIATE でした(さっきの確認 SQL の前に、14個のパラメータを並べたときの結果)。
sessions 504 FALSE IMMEDIATE TRUE FALSE TRUE
(今回の検証環境で、V$PARAMETER の name・value・ISSES_MODIFIABLE・ISSYS_MODIFIABLE・ISPDB_MODIFIABLE・ISMODIFIED・ISDEFAULT を並べた出力から、sessions の1行だけを抜き出したものです)
ところが CDB$ROOT で、今と同じ値を設定しようとすると。
alter system set sessions = 504 scope = memory;
alter system set sessions = 504 scope = memory
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00046: cannot modify sessions parameter
変えられません。 SESSIONS のリファレンスを見ると、ALTER SYSTEM で変えられるのは PDB の中で、その PDB の SESSIONS を変えるときだけで、非 CDB や CDB$ROOT では変えられない、と書かれています。 IMMEDIATE の表示は、PDB で変えられることを反映しているのかもしれませんが、その理由はドキュメントでは確認できませんでした。いずれにしても、ビューの列とドキュメントの Modifiable 欄の両方を見るのが安全です。
おうどん「黒板って書いてあったのに、1階では書けない黒板だった」
Oracle「2階以上専用の黒板です。1階には額縁だけ飾ってあります」
……額縁だけの黒板。紛らわしさの最高傑作です。
2つ目、ISMODIFIED は戻しても残る。 今回の検証では、一度 open_cursors と sort_area_size を変えて元の値に戻したあと、もう一度最初から実験しました。そのときの「変更前」の結果がこれです。
NAME VALUE SYS_VALUE ISMODIFIED
---------------- ---------- ---------- ----------
open_cursors 300 300 SYSTEM_MOD
open_links 4 4 FALSE
sort_area_size 65536 65536 SYSTEM_MOD
3 rows selected.
(今回の検証環境で、変更して元の値に戻したあと、インスタンスを再起動せずに実行した結果です)
値は元どおりなのに、SYSTEM_MOD。 リファレンスの説明は「インスタンス起動後に変更されたか」なので、元の値に戻しても、変更したという記録は再起動まで残るわけです。 ISMODIFIED で「今の値が既定値と違うか」を判定しようとすると外れます。今の値は VALUE、SPFILE の値は V$SPPARAMETER で、別々に比べましょう。
新人さん「黒板を元のおすすめに書き直したのに、消した跡が残ってます」
おうどん「チョークの跡は、閉店後に拭くまで消えないんだよ」
……拭くのはインスタンスの再起動です。跡のためだけに再起動はしないでください。
上級者向けの補足:19.3 の数え方、RAC、パッチの差
今回の環境の内訳。 ISSYS_MODIFIABLE を数えると、19.3 の CDB$ROOT ではこうなりました。
ISSYS_MODIFIABLE COUNT(*)
---------------- ----------
DEFERRED 11
FALSE 120
IMMEDIATE 312
(今回の検証環境で、select issys_modifiable, count(*) from v$parameter group by issys_modifiable order by 1; を実行した結果です)
黒板が312枚、メニュー表が11冊、看板が120枚。 DEFERRED は少数派で、今回の環境では SORT_AREA_SIZE のほか、RECYCLEBIN、SESSION_CACHED_CURSORS、AUDIT_FILE_DEST などが入っていました。
おうどん「黒板312枚の店、壁が足りない」
Oracle「天井にも書いてあります」
……首が痛くなる店です。
この数は 19.3(パッチを当てていない初期リリース)の、今回の構成での値です。RU(リリース・アップデート。定期的なパッチ)でパラメータが増えたり、性質が変わったりする可能性はあるので、本番では自分の環境のビューで確かめてください。
RAC(複数のサーバーで1つの DB を動かす構成)。 今回の環境はシングルインスタンスなので、RAC は試していません。リファレンス上は次の点が関係します。
V$PARAMETERのISINSTANCE_MODIFIABLE:インスタンスごとに違う値にできるか- ALTER SYSTEM のリファレンスでは、
MEMORYとBOTHは全インスタンスのメモリを変え、インスタンスごとに設定した値を上書きする、と説明されています。ただし、対象はSID句でも指定でき、SID = '<インスタンス名>'ならそのインスタンスだけです。この記事のように SPFILE 起動でSIDを省略すると、既定はSID = '*'です
RAC でインスタンスごとの値を持っている環境では、「全部そろえたつもりが、再起動したら個別の値に戻った」が起こりえます。このあたりは別の記事で掘り下げる予定です。
おうどん「チェーン店の黒板を、本部から一斉に書き換えたら」
Oracle「翌朝、各店の店長が自分の字で書き直していることがあります」
……本部と現場の関係は、DB でもむずかしい。
ALTER SESSION との関係。 ISSES_MODIFIABLE が FALSE のパラメータを ALTER SESSION で変えようとすると、今回の環境では OPEN_CURSORS で ORA-02096 になりました。
alter session set open_cursors = 500;
alter session set open_cursors = 500
*
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this option
DEFERRED を書き忘れたときと同じエラー番号です。ORA-02096 は「その書き方では変えられない」という意味なので、出たら ISSES_MODIFIABLE と ISSYS_MODIFIABLE の両方を見直すのが早道です。ORA-02095 は「そもそも(その範囲では)変えられない」で、静的パラメータを SCOPE = SPFILE なしで変えようとしたときに出ました。
| 今回見たエラー | 出た場面 | 見直すところ |
|---|---|---|
| ORA-02095 | FALSE のパラメータを SCOPE なし・MEMORY で変更 | SCOPE = SPFILE にして再起動を計画する |
| ORA-02096 | DEFERRED を書かずに変更、ALTER SESSION 不可のものをセッションで変更 | DEFERRED の有無、ALTER SYSTEM か ALTER SESSION か |
| ORA-65040 | PDB の中で、PDB では変えられないものを変更 | CDB$ROOT で変える(影響は全 PDB) |
| ORA-02097 + ORA-00046 | CDB$ROOT で SESSIONS を変更 | ドキュメントの Modifiable 欄を確認 |
新人さん「エラー番号、全部覚えなきゃダメですか」
おうどん「覚えなくていい。この表をブックマークして、うどんでも食べてて」
……おうどんの記事への誘導が露骨すぎる。でも、それで十分です。
🍜 まとめ:お品書きの種類を見てから、書き換える
冒頭の新人さんの質問は、「OPEN_CURSORS を増やすのに、再起動はいるか」でした。
答えは、V$PARAMETER の ISSYS_MODIFIABLE が IMMEDIATE なので、いりません。ただし、すぐ全セッションに効くので、影響は考える。 次からは、こう答えられます。
おうどん「ISSYS_MODIFIABLE を見てごらん。黒板なら今すぐ、メニュー表なら次のお客さんから、看板なら閉店後」
新人さん「……で、変えたあとは?」
おうどん「SHOW PARAMETER だけで安心しない。V$SYSTEM_PARAMETER と V$SPPARAMETER も見る」
新人さん「完璧です。じゃあ念のため、再起動もしておきます?」
……話を最初に戻さないでください。
Oracle「わたしは、聞いてもらえれば、いつでも答えますので」
おうどん「次からは、検索より先に聞くね」
……ようやく、番頭さんの寂しさが報われました。
再起動が必要かは、検索より先に、DB 自身に聞く。そして「System altered.」は、看板の発注書であって、付け替え完了の報告ではありません。
まずは、次に変えるパラメータの名前で、最初の SELECT を1回流してみてください。 黒板だったら、ちょっとだけ肩の力を抜いて、かけうどんでもどうぞ🍜
参考資料
- Oracle Database 19c Reference:V$PARAMETER — V$PARAMETER がセッションで有効な値であること、ISSES_MODIFIABLE・ISSYS_MODIFIABLE(IMMEDIATE・DEFERRED・FALSE の意味)・ISPDB_MODIFIABLE・ISINSTANCE_MODIFIABLE・ISMODIFIED の意味
- Oracle Database 19c Reference:V$SYSTEM_PARAMETER — インスタンスで有効な値であること、新しいセッションがこの値を引き継ぐこと
- Oracle Database 19c Reference:V$SPPARAMETER — SPFILE の中身を表示すること、SPFILE を使わずに起動すると ISSPECIFIED がすべて FALSE になること
- Oracle Database 19c SQL Language Reference:ALTER SYSTEM — DEFERRED の指定が必要な場合、SCOPE の MEMORY・SPFILE・BOTH と既定値、静的パラメータは SPFILE を指定すること、PDB で変更したときの反映、RAC での MEMORY・BOTH の扱い
- Oracle Database 19c Reference:Reading the Parameter Descriptions — 各パラメータのページの Modifiable・Modifiable in a PDB 欄の読み方
- Oracle Database 19c Reference:PROCESSES・OPEN_CURSORS・SORT_AREA_SIZE・SESSIONS — 各パラメータの Modifiable 欄、SESSIONS は PDB の中でだけ ALTER SYSTEM で変えられること
確認日:2026-10-08。

コメント