Sample listener.ora with Static SID_LIST and Extproc

Sample listener.ora with Static SID_LIST and Extproc

Purpose

The listener.ora file is the server-side configuration for the Oracle Net listener — the process that accepts incoming client connections and hands them off to a database server process. The sample below — taken straight from the shutdownabort.com DBA Quick Guides (Andrew Barry, 2007–2013, preserved via the Wayback Machine as the anchor source for this post) — shows two fundamental patterns: a LISTENER block that names the network endpoints the listener listens on, and a SID_LIST_LISTENER block that statically registers two services: a regular database and the PLSExtProc agent for PL/SQL external procedures.

Code

 1LISTENER =
 2  (DESCRIPTION_LIST =
 3    (DESCRIPTION =
 4      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
 5      (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1521))
 6    )
 7  )
 8
 9SID_LIST_LISTENER =
10  (SID_LIST =
11    (SID_DESC =
12      (GLOBAL_DBNAME = scr10)
13      (ORACLE_HOME   = /u01/app/oracle/product/10.2.0/db_1)
14      (SID_NAME      = scr10)
15    )
16    (SID_DESC =
17      (SID_NAME    = PLSExtProc)
18      (ORACLE_HOME = /u01/app/oracle/product/10gASM)
19      (PROGRAM     = extproc)
20    )
21  )

Breakdown of Code

There are two top-level entries: LISTENER (the network endpoints) and SID_LIST_LISTENER (the static services).

LISTENER block — what to listen on:

  • DESCRIPTION_LIST — wraps one or more DESCRIPTION blocks. Each DESCRIPTION is one set of addresses the listener should accept connections on.
  • (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) — a same-host inter-process channel. This is what the database uses internally to talk to the extproc agent; clients on the network never use it.
  • (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1521)) — the TCP endpoint clients connect to. Standard port 1521.

SID_LIST_LISTENER block — static service registration:

  • SID_LIST — wraps one or more SID_DESC blocks. Each SID_DESC registers one service the listener should advertise.
  • The first SID_DESC registers the database scr10. It binds the global database name, the ORACLE_HOME path, and the SID. Static registration like this is needed for tools that connect before the database is open — RMAN to a mounted (not open) database, Data Guard broker, and remote STARTUP/SHUTDOWN.
  • The second SID_DESC registers the PLSExtProc agent. PROGRAM = extproc tells the listener: when a connection asks for PLSExtProc, spawn the extproc binary from the named ORACLE_HOME and route the connection to it. This is how PL/SQL external procedure calls reach a C/Java shared library.

How It Works

When the listener starts (lsnrctl start LISTENER), it reads listener.ora, opens every ADDRESS in the LISTENER block, and starts advertising every service registered under SID_LIST_LISTENER. Run lsnrctl status and you will see the IPC and TCP endpoints listed plus both services (scr10 and PLSExtProc).

There are two independent ways services land on a listener:

  • Static registration — entries in SID_LIST_LISTENER. Always present, even when the database is down.
  • Dynamic registration — PMON inside the database registers the service automatically once the database opens. Controlled by the SERVICE_NAMES and LOCAL_LISTENER init parameters. PMON re-registers periodically; the registration disappears when the database shuts down.

Most modern databases need only dynamic registration. The static block is still required when:

  • A client must connect to the database in MOUNT or NOMOUNT state (RMAN restoring a control file, Data Guard role transitions).
  • A non-database service must be reachable via the listener — extproc is the canonical example. Heterogeneous Services agents (hsodbc, dg4odbc) use the same pattern.

Key Points

  • listener.ora lives in $TNS_ADMIN — the same search path as tnsnames.ora. Default is $ORACLE_HOME/network/admin.
  • Restart the listener after any editlsnrctl reload re-reads the file without dropping existing connections; lsnrctl stop followed by lsnrctl start is a full bounce.
  • The listener runs as the oracle OS user by default — and must have read access on every ORACLE_HOME it spawns processes from.
  • GLOBAL_DBNAME is what the client matches against — when a client connects with (SERVICE_NAME = scr10), the listener looks for a GLOBAL_DBNAME (or a dynamically registered service) of scr10.
  • extproc is a security-sensitive endpoint — never expose it on a network address. Keep it on IPC only, as in the sample above.

Smoke Test with lsnrctl

 1$ lsnrctl status
 2
 3LSNRCTL for Linux: Version 21.0.0.0.0
 4Connecting to (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1521)))
 5STATUS of the LISTENER
 6------------------------
 7Alias                     LISTENER
 8Version                   TNSLSNR for Linux: Version 21.0.0.0.0
 9Start Date                03-MAY-2026 10:00:00
10Listening Endpoints Summary...
11  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
12  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=bloo)(PORT=1521)))
13Services Summary...
14Service "scr10" has 1 instance(s).
15  Instance "scr10", status UNKNOWN, has 1 handler(s) for this service...
16Service "PLSExtProc" has 1 instance(s).
17  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
18The command completed successfully

The status UNKNOWN for scr10 means statically registered — the listener cannot ask the database for live status because the registration came from listener.ora, not from PMON. After the database opens, PMON dynamically registers the same service and the status flips to READY.

Common Variations

For RAC and Data Guard the static block usually still names the database for role transitions:

1SID_LIST_LISTENER =
2  (SID_LIST =
3    (SID_DESC =
4      (GLOBAL_DBNAME = scr10_DGMGRL)
5      (ORACLE_HOME   = /u01/app/oracle/product/19c)
6      (SID_NAME      = scr10)
7    )
8  )

The _DGMGRL suffix on GLOBAL_DBNAME is the convention Data Guard Broker uses for its management connections.

For containers (CDB/PDB) in 12c+, dynamic registration handles every PDB automatically. Static GLOBAL_DBNAME entries are still useful at the CDB level for the same RMAN/Data Guard reasons.

Important Considerations

The listener does not need to live on the same host as the database, and a single listener can serve many databases on many hosts. In RAC the SCAN listener is a logically separate component that delegates to local listeners. None of that changes the listener.ora grammar shown above — only the address values and the number of SID_DESC blocks.

If lsnrctl status returns TNS-12541: TNS:no listener, the listener is not running at the address the command is connecting to. Default address is (ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)); override with lsnrctl status LISTENER (named) or set LOCAL_LISTENER for the lsnrctl session.

The original entries above target an Oracle 10gR2 ORACLE_HOME path. The grammar has not changed in 21c — drop the file into a current-version network/admin directory unchanged, then update the ORACLE_HOME paths.

References

Posts in this series