ORA-12514「リスナーは接続記述子でリクエストされたサービスを現在認識していません」の原因と対処法|リスナー正常・DB稼働中でも発生するケースを実機で再現

sqlplus で接続しようとすると ORA-12514 が返る。
リスナーを確認すると正常に稼働している。
データベースにサーバ上から直接ログインすると、こちらは問題なく接続できる…。

ORA-12514 は「リスナーは動いているが、指定されたサービス名がリスナーに登録されていない」ことを示すエラーです。
経路・リスナー・データベースのすべてが正常でも、「登録」が欠けているだけで発生します。
今回は、発生原因を3パターンに整理し、すべて実機で再現して切り分け手順を解説します。
リスナー自体が停止しているときの ORA-12541(TNS:リスナーがありません)との違いも整理します。


1. 症状

TNS 接続(@ホスト:ポート/サービス名)を試みると、待たされることなく ORA-12514 が返ります。

$ sqlplus system/oracle@localhost:1521/orcl19u

ERROR:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません

一方、同じサーバ上で BEQ 接続(リスナーを使わないローカル接続)を試みると、こちらは接続できる場合があります。

$ sqlplus / as sysdba

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.28.0.0.0
に接続されました。

「TNS 接続はエラーになるのに、サーバ上での直接ログインはできる」という組み合わせは、ORA-12541 でも発生します。
両者の違いはエラーメッセージの意味にあります。
ORA-12541 は「リスナーそのものに接続できない」、ORA-12514 は「リスナーには接続できたが、指定したサービス名が未登録」です。
つまり、ORA-12514 が出ている時点で、クライアントからリスナーまでのネットワークは正常です。


2. 原因の仕組み

接続の4段階と ORA-12514 の位置

Oracle への TNS 接続は、次の4段階で進みます。
ORA-12514 は、このうち④「リスナーがサービスへ転送する」段階の失敗です。

① 接続先の情報を解決する(クライアント内)
      │ エントリ名を tnsnames.ora 等で引けない → ORA-12154
      │ エントリ内ホスト名の名前解決に失敗 → ORA-12545
      ▼
② 接続先ホストに到達する(ネットワーク)
      │ 到達できない → ORA-12543(即時)/ ORA-12170(応答がなくタイムアウト)
      ▼
③ リスナーに接続する(ポート 1521)
      │ 接続を拒否される → ORA-12541
      ▼
④ リスナーがサービスへ転送する
      │ サービス名が未登録 → ORA-12514 ★本記事
      ▼
   接続成功

②のネットワークの失敗(ORA-12543)は別記事、③のリスナーの失敗(ORA-12541)も別記事で整理しています。

サービスの「登録」とは

リスナーは、取り次げるサービス名の一覧を保持しています。
この一覧は、データベース側のバックグラウンドプロセス LREG(12c 以降。11g までは PMON)が、リスナーに対して動的に登録することで作られます。
lsnrctl status の末尾に出る「サービスのサマリー」が、その一覧の現在の中身です。

$ lsnrctl status
(前半省略・関連行のみ抜粋)
サービスのサマリー...
サービス"orcl19u"には、1件のインスタンスがあります。
  インスタンス"orcl19u"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"v11c19u"には、1件のインスタンスがあります。
  インスタンス"v11c19u"、状態READYには、このサービスに対する1件のハンドラがあります...

接続文字列で指定できるのは、この一覧に載っている名前だけです。
一覧に無い名前が指定されると、リスナーは ORA-12514 を返します。
したがって ORA-12514 の切り分けは、「なぜこの一覧に、指定した名前が無いのか」を特定する作業になります。

一覧から名前が消える(または最初から無い)原因は、次の3パターンに整理できます。
いずれも実機(Oracle Database 19c(19.28 RU)・Oracle Linux 8.9)で再現して確認したものです。

#原因パターン起きやすい場面
1接続文字列のサービス名が間違っている接続設定の書き間違い・別環境の設定の流用・SID(インスタンス名)とサービス名の混同
2データベースが停止しているインスタンス障害・起動忘れ・メンテナンス後の起動漏れ
3リスナー起動直後で、登録がまだ済んでいないリスナー再起動の直後(約60秒間)

このほか、RAC などリスナーを複数使う構成では、登録先を決めるパラメータ(REMOTE_LISTENER・LOCAL_LISTENER)の欠落により、特定のリスナーだけ未登録になるケースがあります。


3. パターン1: 接続文字列のサービス名が間違っている

リスナーもデータベースも完全に正常な状態で、登録に無いサービス名を指定したケースです。
上の「サービスのサマリー」の状態(orcl19u と v11c19u が READY)で、存在しないサービス名を指定して再現しました。

$ sqlplus system/oracle@localhost:1521/nosuchservice

ERROR:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません

リスナー側に問題はありません。
対処は、接続文字列や tnsnames.ora の SERVICE_NAME を、登録されている名前に合わせることです。
正しい名前は、リスナー側なら lsnrctl status のサービスのサマリーで、データベース側なら次の問い合わせで確認できます。

SQL> select name from v$services;

なお、一覧のうち SYS$ で始まる名前と XDB が付く名前は内部用のため、通常の接続には使いません。


4. パターン2: データベースが停止している

サービス名の綴りは正しいのに、データベースが停止しているケースです。
登録はデータベース側の LREG が行うため、データベースが停止すると、その登録はリスナーから消えます。

実機で確認します。
まず、データベース(orcl19u)を停止します。

SQL> shutdown immediate
データベースがクローズされました。
データベースがディスマウントされました。
ORACLEインスタンスがシャットダウンされました。

この状態でリスナーを確認すると、リスナー自体は稼働を続けたまま、orcl19u のサービスだけが一覧から消えています。

$ lsnrctl status
(前半省略・関連行のみ抜粋)
稼働時間                  0 日 15 時間 35 分 46 秒
サービスのサマリー...
サービス"sp19u001"には、1件のインスタンスがあります。
  インスタンス"v11c19u"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"v11c19u"には、1件のインスタンスがあります。
  インスタンス"v11c19u"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"v11c19uXDB"には、1件のインスタンスがあります。
  インスタンス"v11c19u"、状態READYには、このサービスに対する1件のハンドラがあります...
コマンドは正常に終了しました。

このサーバでは2つのデータベース(orcl19u と v11c19u)が動いており、停止した orcl19u の登録だけが消え、稼働中の v11c19u の登録は残っています。
リスナーの稼働時間が継続していることからも、リスナー側には何の変化も起きていないことが分かります。

この状態で orcl19u へ TNS 接続を試みると、ORA-12514 が返ります。

$ sqlplus system/oracle@localhost:1521/orcl19u

ERROR:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません

パターン1(綴り間違い)とまったく同じエラーですが、原因は異なります。
両者は、BEQ 接続(sqlplus / as sysdba)でデータベースが稼働しているかを見れば切り分けられます。
停止していた場合の対処は、データベースの起動です。

SQL> startup
ORACLEインスタンスが起動しました。
(メモリサイズ表示は省略)
データベースがマウントされました。
データベースがオープンされました。

起動後、LREG が登録を行うと、同じ接続文字列で接続できるようになります。

$ sqlplus system/oracle@localhost:1521/orcl19u

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.28.0.0.0
に接続されました。

5. パターン3: リスナー起動直後で、登録がまだ済んでいない

リスナーを再起動した直後は、データベースが稼働していても一時的に ORA-12514 になります。
LREG による登録は約60秒周期のため、リスナー起動から登録が済むまでの間、リスナーの一覧は空のままだからです。

実機では、リスナー起動から接続成功までの経過を次のように観測しました。

経過事象
0秒lsnrctl start(リスナー起動)
〜約60秒TNS 接続を3回試行 → 3回とも ORA-12514
約61秒全サービスが READY で登録される
直後同じ接続文字列で接続成功

このパターンは障害ではないため、対処は「待つ」で足ります。
すぐに復旧を確認したい場合は、データベース側から即時登録を指示できます。

SQL> alter system register;

システムが変更されました。

このコマンドは LREG にリスナーへの登録を即時実行させるだけで、データベースの動作には影響しません。


6. Q&A

Q: ORA-12514 と ORA-12541 はどう見分ければよいですか?

A: 失敗した段階が異なります。

エラー状態リスナーの状態
ORA-12541リスナーそのものに接続できない停止・ポート違い・待受アドレス違いなど
ORA-12514リスナーには接続できたが、サービス名が未登録稼働している

ORA-12514 が出ている時点でリスナーは応答しているので、lsnrctl stop/start のようなリスナー側の操作は原則不要です。
確認すべきはサービスの登録(本記事)で、リスナー側の原因は ORA-12541 の記事で整理しています。

なお、この2つはエラー番号の数字の並びが似ているため(12514/12541)、番号だけを見ると読み違えやすい点にも注意してください。
意味はほぼ正反対(12541=リスナー側を疑う/12514=リスナーは正常で登録側を疑う)なので、読み違えると調査の向き先を間違えます。
メッセージ本文(「リスナーがありません」=12541/「サービスを現在認識していません」=12514)まで確認するのが確実です。

Q: lsnrctl status のサービス一覧に名前があるのに ORA-12514 になります。なぜですか?

A: 一覧を確認したリスナーと、実際に接続を受けたリスナーが、別のリスナーだった可能性があります。

前提として、リスナーは1台のサーバに1つとは限りません。
例えば、1台のサーバに複数のデータベースを構成し、データベースごとにリスナーを分けている環境があります(本番用データベースは1521番のリスナー・検証用データベースは1522番の別リスナー、のような分け方です)。
サービスの登録はリスナーごとに別々に行われるため、「リスナーAには登録済みだが、リスナーBには未登録」という状態が起こります。

この状態で、lsnrctl status で一覧を見たのがリスナーA、クライアントの接続文字列が向いていたのがリスナーBだと、「一覧に名前があるのに ORA-12514」に見えます。
確認のポイントは、接続文字列の HOST とポートがどのリスナーを指しているかです。
リスナーが複数ある環境では lsnrctl status <リスナー名> のようにリスナー名を指定して、接続先と同じリスナーの一覧を確認してください。
なお、lsnrctl status はリスナー名を省略すると、LISTENER という名前のデフォルトのリスナーを確認します。
名前を省略して打つ習慣のまま複数リスナーの環境を調べると、気づかずデフォルトの LISTENER だけを見てしまうため、注意してください。

Q: alter system register はどういうコマンドですか?実行しても安全ですか?

A: データベース側の LREG プロセスに、リスナーへのサービス登録を即時実行させるコマンドです。
通常は約60秒周期で自動的に行われる登録を、その場で実行させるだけなので、データベースの動作には影響しません。
リスナー再起動直後の一時的な ORA-12514(パターン3)や、登録パラメータを変更した直後の反映確認に使えます。

Q: サービスの登録は PMON が行うのではないのですか?

A: 11g までは PMON の仕事でしたが、12c で登録専任の LREG プロセスに分離されました。
PMON がプロセス監視の本業と兼務していた登録の役割を、LREG が引き継いだ形です。
古い解説記事や書籍では「PMON がリスナーに登録する」と書かれていることがありますが、12c 以降の環境で登録の動きを追うときは LREG(プロセス名 ora_lreg_<SID>)を確認してください。

Q: 接続文字列のサービス名には何を指定すればよいですか? SID とは違うのですか?

A: lsnrctl status のサービスのサマリー、またはデータベースで select name from v$services に出る名前を指定します。
デフォルトではデータベース名と同じ名前のサービスが作られますが、PDB への接続は PDB のサービス名を使うなど、SID(インスタンス名)と一致しない場面があります。
例えば、本記事の検証環境のリスナーには次の登録があります。

サービス"sp19u001"には、1件のインスタンスがあります。
  インスタンス"v11c19u"、状態READYには、このサービスに対する1件のハンドラがあります...

サービス名 sp19u001 は、インスタンス v11c19u の上で動く PDB のサービス名で、SID(v11c19u)とは一致しません。
この PDB に接続するときに指定するのは、SID ではなくサービス名 sp19u001 の方です。
思い込みで SID を指定せず、登録されている名前を確認してから指定してください。


7. まとめ

ORA-12514 は「リスナーは稼働しているが、指定されたサービス名が登録されていない」エラーです。
経路・リスナー・データベースがすべて正常でも、登録が欠けているだけで発生します。
切り分けの入口は lsnrctl status のサービスのサマリーに、指定した名前があるかどうかの1点です。

ORA-12514 切り分けフロー

TNS接続で ORA-12514
        │
        ▼
接続先リスナーで lsnrctl status
「サービスのサマリー」に指定した名前はあるか
        │
        ├─ ある → 一覧を見たリスナーと接続先のリスナーが
        │          別の可能性(Q&A 参照)
        │          接続文字列の HOST・PORT が指すリスナーを
        │          lsnrctl status <リスナー名> で確認
        │
        └─ ない
                │
                ▼
        サーバ上で sqlplus / as sysdba
        データベースは稼働しているか
                │
                ├─ 停止している → パターン2
                │                  startup で起動
                │
                └─ 稼働している
                        │
                        ├─ v$services に無い名前を指定していた
                        │    → パターン1(サービス名の間違い)
                        │      登録されている名前に修正
                        │
                        └─ リスナーを再起動した直後
                             → パターン3(登録待ち)
                               約60秒待つ/alter system register