Warum Services für PDBs wichtig sind

Einführung

Das Konzept der Services für den Aufbau einer Verbindung zu Oracle Datenbanken ist nicht neu. Wir empfehlen generell, für jede Datenbank einen separaten Service für die Applikationen zu erstellen und nicht den Standard-Service zu verwenden. Neben der Notwendigkeit für HA-Lösungen ist es auch ansonsten sehr praktikabel, denn so lassen sich beispielsweise Applikationen durch Stoppen des Service aussperren während administrative Tätigkeiten über den Standard-Service nach wie vor möglich sind. Mit der Multitenant-Architektur gewinnt das nun noch an Bedeutung. Der Standard-Service einer Pluggable Datenbank (PDB) startet zwar nur, wenn die PDB auch wirklich geöffnet wird was für die HA-Lösungen eigentlich ausreichend ist, dafür entsteht ein neues Problem mit dem Standard-Service, dass wir Ihnen in diesem Beitrag näher erklären wollen.

Verhalten mit einem Container

Wir wollen das Verhalten an einem Beispiel erläutern. Ausgangspunkt ist eine Container-Datenbank (CDB) in der Version 19.10 mit drei PDBs. Dazu gibt es einen Listener, der den Verbindungsaufbau mit den Clients einleitet. Aus Datenbanksicht ergibt sich daher folgendes Bild:

 

SQL> select name from v$database;

NAME
---------
MMICDB

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 MMI1                           READ WRITE NO
         4 MMI2                           READ WRITE NO
         6 MMI3                           READ WRITE NO

 

Am Listener sind entsprechend die Standard-Services registriert. Der Übersichtlichkeit halber haben wir die Ausgabe auf die wesentlichen Teile reduziert.

 

$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 24-NOV-2021 09:01:19

Copyright (c) 1991, 2021, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date                19-NOV-2021 12:16:12
Uptime                    4 days 20 hr. 45 min. 7 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/19.12.0.0/oracle/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/odax5-base-00/listener/alert/log.xml
Listening Endpoints Summary...
[...]
Services Summary...

[...]

Service "mmi1.support.robotron.de" has 1 instance(s).
  Instance "MMICDB", status READY, has 1 handler(s) for this service...

[...]

The command completed successfully

 

Wie nicht anders zu erwarten hat der Standard-Service der PDB "MMI1" die CDB "MMICDB" zugeordnet. Soweit ist das Verhalten völlig normal und in Ordnung. Doch spannend wird es, wenn wir nun eine weitere CDB auf dem gleichen Server erstellen.

Mehrere CDBs auf einem Server

Mehrere CDBs auf einem Server

Wir führen das Beispiel fort indem wir eine weitere CDB "MMICDB2" hernehmen, die eine Kopie der PDB "MMI1" aus der CDB "MMICDB", die als Testumgebung eine Kopie der PDB "MMI1" erhalten soll. Die Kopie wird als Full Clone über einen Datenbanklink erstellt. Das geht recht schnell und einfach.

 

SQL> select name from v$database;

NAME
---------
MMICDB2

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDBAPP                         READ WRITE NO


SQL> create pluggable database mmi1 from mmi1@mmicdb;

Pluggable database created.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDBAPP                         READ WRITE NO
         4 MMI1                           MOUNTED
SQL> alter pluggable database mmi1 open;

Pluggable database altered.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDBAPP                         READ WRITE NO
         4 MMI1                           READ WRITE NO

 

Spannend wird es nun, wenn wir uns die am Listener registrierten Services einmal näher ansehen. 

 

$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 24-NOV-2021 10:53:58

Copyright (c) 1991, 2021, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date                19-NOV-2021 12:16:12
Uptime                    4 days 22 hr. 37 min. 46 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/19.12.0.0/oracle/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/odax5-base-00/listener/alert/log.xml
Listening Endpoints Summary...
[...]
Services Summary...

[...]

Service "mmi1.support.robotron.de" has 2 instance(s).
  Instance "MMICDB", status READY, has 1 handler(s) for this service...
  Instance "MMICDB2", status READY, has 1 handler(s) for this service...

[...]

The command completed successfully

 

 Hier wird es nun kriminell. Da in beiden CDBs nun eine PDB mit dem Namen "MMI1" existiert, werden natürlich auch die entsprechenden Standard-Services für diese PDBs am Listener angemeldet. Es entstehen also folgerichtig zwei Servicehandler für den Standard-Service mit dem Namen "mmi1.support.robotron.de". 

Die Sicht des Clients

Diese zwei Servicehandler sind für die Client-Verbindungen nun eine mittlere Katastrophe. Denn der Client verwendet zum Verbindungsaufbau die Angaben für Hostname, Port und Servicename und wendet sich damit an den Listener. Der Listener kann nun nicht entscheiden, auf welche CDB die Verbindung gelenkt werden soll, er macht also eine Art Load Balancing und schickt die Verbindung mal hierhin und mal dahin. 

 

C:\>sqlplus schema_owner/owner@db-server:1521/mmi1.support.robotron.de

SQL*Plus: Release 19.0.0.0.0 - Production on Mi Nov 24 10:55:46 2021
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Letzte erfolgreiche Anmeldezeit: Di Nov 23 2021 13:51:29 +01:00

Verbunden mit:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0

SQL> select name from v$database;

NAME
---------
MMICDB

SQL> exit
Verbindung zu Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0 beendet

C:\>sqlplus schema_owner/owner@db-server:1521/mmi1.support.robotron.de

SQL*Plus: Release 19.0.0.0.0 - Production on Mi Nov 24 10:56:05 2021
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Letzte erfolgreiche Anmeldezeit: Di Nov 23 2021 13:51:29 +01:00

Verbunden mit:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0

SQL> select name from v$database;

NAME
---------
MMICDB2

 

Das ist auch logisch, denn gleicher Servicename bedeutet aus Oracle-Sicht auch gleiche Funktionalität. Das ist für unsere Beispiel mit der Produktiv- und Testumgebung bei weitem nicht der Fall. Hier würden nun Inkonsistenzen entstehen, wenn die Verbindungen mal hier und mal da landen.

Die Lösung

Die Lösung für dieses Problem ist einfach. Entweder sorgt man dafür, dass die PDBs immer eindeutige Namen erhalten oder man erstellt einen Service für jede PDB. Letzteres ist ganz klar die Empfehlung, wie schon in der Einleitung erklärt. Hier im Beispiel erstellen wir einfach einen Service pro PDB, der in der Grid Infrastructure registriert und gestartet wird.

 

$ srvctl add service -db mmicdb -pdb mmi1 -service mmi1_orig
$ srvctl start service -db mmicdb  -service mmi1_orig
$ srvctl add service -db mmicdb2 -pdb mmi1 -service mmi1_clone
$ srvctl start service -db mmicdb2  -service mmi1_clone

 

Entsprechend werden diese beiden Services nun im Listener registriert und wir haben wieder die Möglichkeit, uns gezielt zur gewünschten PDB zu verbinden.

 

$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 24-NOV-2021 11:41:11

Copyright (c) 1991, 2021, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date                19-NOV-2021 12:16:12
Uptime                    4 days 23 hr. 24 min. 59 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/19.12.0.0/oracle/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/odax5-base-00/listener/alert/log.xml
Listening Endpoints Summary...
[...]
Services Summary...

[...]

Service "mmi1.support.robotron.de" has 2 instance(s).
  Instance "MMICDB", status READY, has 1 handler(s) for this service...
  Instance "MMICDB2", status READY, has 1 handler(s) for this service...
Service "mmi1_clone.support.robotron.de" has 1 instance(s).
  Instance "MMICDB2", status READY, has 1 handler(s) for this service...
Service "mmi1_orig.support.robotron.de" has 1 instance(s).
  Instance "MMICDB", status READY, has 1 handler(s) for this service...

[...]

The command completed successfully

 

Die Verbindung vom Client klappt nun wieder zuverlässig zur gewünschten PDB, sofern man den neu erstellten Service verwendet.

 

C:\>sqlplus schema_owner/owner@db-server:1521/mmi1_orig.support.robotron.de

SQL*Plus: Release 19.0.0.0.0 - Production on Mi Nov 24 11:42:36 2021
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Letzte erfolgreiche Anmeldezeit: Mi Nov 24 2021 10:55:48 +01:00

Verbunden mit:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0

SQL> select name from v$database;

NAME
---------
MMICDB

 

C:\>sqlplus schema_owner/owner@db-server:1521/mmi1_clone.support.robotron.de

SQL*Plus: Release 19.0.0.0.0 - Production on Mi Nov 24 11:42:48 2021
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Letzte erfolgreiche Anmeldezeit: Mi Nov 24 2021 10:56:06 +01:00

Verbunden mit:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0

SQL> select name from v$database;

NAME
---------
MMICDB2

 

 

Zusammenfassung

Zusammenfassend können wir nur wieder die Empfehlung aus der Einleitung wiederholen. Services sind ein nicht zu unterschätzendes und teils zwingend erforderliches Werkzeug um Client-Verbindungen dahin zu lenken, wo sie hingehören. Das gilt nicht nur für Cluster- oder Standby-Lösungen sondern eben auch für ganz einfache Standalone Systeme.

Verwandte Blogbeiträge:

Kommentare

Keine Kommentare

Kommentar schreiben

* Diese Felder sind erforderlich