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.
Kommentare
Keine Kommentare