概要
Vagrant + Oracle(19c)環境でPHP(PDO_OCI)から接続しようとした際、
ORA-12541: TNS:no listener エラーに悩まされたときの、
原因調査~解決手順までをまとめました。
発生したエラー
PHPからOracle接続時に以下のエラーが発生:
PDOException: SQLSTATE[HY000]: pdo_oci_handle_factory: ORA-12541: TNS:no listener
VM側で確認してみてもリスナーが起動していない・外部から繋がらない等の状況。
環境
- Windows ホスト
- Vagrant(CentOS系仮想マシン)
- Oracle Database 19c
- PHP(pdo_oci)
原因調査
1. リスナーサービスが起動しているか?
lsnrctl status
結果:
-
TNS:no listener- リスナーが起動していない
2. リスナーの起動
Oracleユーザーで
lsnrctl start
※"Permission denied"の場合はoracleユーザーで実行&ログディレクトリの権限修正が必要
(sudo chown -R oracle:oinstall ...)
3. listener.oraの内容確認
sudo cat /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/listener.ora
初期値:
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
これでは外部(Windowsなど)から接続不可。
解決策
1. listener.oraのHOSTを修正
以下のように変更!
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
または HOST に、VagrantのIP(例:192.168.33.23)を指定してもOK。
2. ログディレクトリの権限修正
リスナー起動時に
Linux Error: 13: Permission denied
が出たら、ディレクトリ(ファイル)がoracleユーザーで書き込めるか確認、修正:
sudo chown -R oracle:oinstall /u01/app/oracle/product/19.0.0/dbhome_1/network/log
sudo chmod 755 /u01/app/oracle/product/19.0.0/dbhome_1/network/log
3. リスナーの再起動
su - oracle
lsnrctl stop
lsnrctl start
lsnrctl status
Listening Endpoints Summary:
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
となれば外部からの接続OK!
4. データベースサービスがNo Servicesの場合
すぐにsupports no servicesと出ても、
DBインスタンスが未起動・リスナー登録待ちの場合が多い。
DBインスタンスが起動しているか確認:
ps -ef | grep pmon
なければ
export ORACLE_SID=ORCL
sqlplus / as sysdba
startup
5. PHP・Windowsからの接続確認
PHPなど外部からOracleへ、
oci:dbname=//192.168.33.23:1521/ORCL
のように接続すればOK。
まとめ
-
ORA-12541: TNS:no listenerの場合「リスナーが起動しているか」「HOST指定」「パーミッション」の確認がキモ - 外部アクセスはlistener.oraのHOSTを0.0.0.0かVMのIPに
- パーミッションエラーはchown、chmodで修正
- データベースインスタンスの起動も忘れずに!