Oracleの初期化パラメータ変更で再起動が必要か調べる方法|V$PARAMETERのISSYS_MODIFIABLE(IMMEDIATE・DEFERRED・FALSE)とORA-02095・ORA-02096の意味(19c)

Oracleの初期化パラメータ変更で再起動が必要か調べる方法

こんにちは、おうどんです🍜

新人さん「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_MODIFIABLEALTER SYSTEM で変えられる?いつ効く?
IMMEDIATE変えられる(PFILE 起動でも SPFILE 起動でも)すぐ
DEFERRED変えられる(PFILE 起動でも SPFILE 起動でも)以降のセッションから
FALSESPFILE で起動しているときだけ変えられる次のインスタンスから

用語を少しだけ。

  • 初期化パラメータ: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 に接続して変えるときは、こう説明されています。

SCOPEPDB の中で変えたとき
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-02095FALSE のパラメータを SCOPE なし・MEMORY で変更SCOPE = SPFILE にして再起動を計画する
ORA-02096DEFERRED を書かずに変更、ALTER SESSION 不可のものをセッションで変更DEFERRED の有無、ALTER SYSTEM か ALTER SESSION か
ORA-65040PDB の中で、PDB では変えられないものを変更CDB$ROOT で変える(影響は全 PDB)
ORA-02097 + ORA-00046CDB$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回流してみてください。 黒板だったら、ちょっとだけ肩の力を抜いて、かけうどんでもどうぞ🍜

参考資料

確認日:2026-10-08。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

おうどん|癒しと創作をたのしむ雑食クリエイター
写経アプリやクレイセラピー、優しい和風デザインがすき。
ZARDと刀剣と文字に癒されて、今はアプリ作ってます。

コメント

コメントする

目次