Oracle 12.2 PDB relocate: Verschieben einer PDB auf einen anderen Server

21. Januar 2018 Aus Von Markus Flechtner

Mit Oracle 12c Release 2 kamen viele neue Features im Bereich “Oracle Multitenant”. Eine dieser neuen Funktionen ist “PDB relocate”, das Verschieben einer PDB von einer CDB in eine andere PDB. Dies kann sogar mit minimaler Auszeit geschehen und ohne dass eine Änderung der Client-Konfiguration erforderlich ist. Schauen wir uns einmal an, wie es funktioniert:

Wir haben zwei Server, vm111 und vm112 mit zwei Container-Datenbanken, CDB111 und CDB112. In der CDB111 legen wir eine Pluggable Database (PDBRELOC) an, die wir dann auf den anderen Server, in die andere CDB (CDB112) verschieben wollen.

Voraussetzung für ein “PDB relocate” ist, dass beide CDBs mit Local Undo arbeiten (Default in Oracle 12.2) und dass die Ausgangsdatenbank im Archivelog-Modus betrieben wird.

Schritt 1: Anlegen der PDB in CDB111

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> REM     =============================================================
SQL> REM     CREATE PDB FOR Relocation (PDBRELOC) IN SOURCE CDB CDB111
SQL> REM     =============================================================
SQL> 
SQL> CONNECT sys/manager@cdb111.markusdba.local AS sysdba
Connected.
SQL> 
SQL> 
SQL> CREATE pluggable DATABASE
  2  PDBRELOC admin USER admin IDENTIFIED BY manager roles=(DBA)
  3  file_name_convert=('PDBSEED','PDBRELOC')
  4  DEFAULT tablespace users datafile '/u01/oradata/CDB111/PDBRELOC/users01.dbf' SIZE 10M;
 
Pluggable DATABASE created.
 
SQL> 
SQL> ALTER pluggable DATABASE PDBRELOC OPEN;
 
Pluggable DATABASE altered.

Schritt 2: Cross-Listener-Registrierung Quelle –> Ziel

Dieser Schritt ist notwendig, damit später – nach dem Relocate – ein Connection-Forwarding erfolgen kann. Connection-Forwarding sorgt dafür, dass Clients, die mit einer alten Oracle-Net-Konfiguration (tnsnames.ora) auf die PDB zugreifen wollen, zum zweiten Server weitergeleitet werden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SQL> REM     =============================================================
SQL> REM     CROSS listener registration SOURCE TO target
SQL> REM     =============================================================
SQL> CONNECT sys/manager@cdb111.markusdba.local AS sysdba
Connected.
SQL> 
SQL> ALTER system SET listener_networks='((NAME=network1)(LOCAL_LISTENER=LISTENER_CDB111.markusdba.local)(REMOTE_LISTENER=LISTENER_CDB112.markusdba.local))';
 
System altered.
 
SQL> ALTER system register;
 
System altered.
 
SQL> SHOW parameter listener
 
NAME                                 TYPE        VALUE                                                                  
------------------------------------ ----------- ------------------------------                                         
listener_networks                    string      ((NAME=network1)(LOCAL_LISTENE                                         
                                                 R=LISTENER_CDB111.markusdba.lo                                         
                                                 cal)(REMOTE_LISTENER=LISTENER_                                         
                                                 CDB112.markusdba.local))                                               
local_listener                       string      LISTENER_CDB111.markusdba.loca                                         
                                                 l                                                                      
remote_listener                      string                                                                             
SQL>

Schritt 3: Vorbereitungen: Common User in der Ausgangs-CDB anlegen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SQL> REM     =============================================================
SQL> REM     CREATE Common USER IN SOURCE CDB CDB111
SQL> REM     =============================================================
SQL> CONNECT sys/manager@cdb111.markusdba.local AS sysdba
Connected.
SQL> 
SQL> ALTER SESSION SET container=CDB$ROOT;
 
SESSION altered.
 
SQL> 
SQL> CREATE USER c##cloneuser IDENTIFIED BY manager
  2  DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp
  3  CONTAINER = ALL;
 
USER created.
 
SQL> 
SQL> GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE, SYSOPER
  2  TO c##cloneuser CONTAINER = ALL;
 
GRANT succeeded.

Schritt 4: Vorbereitung: Public-Database-Link von der Ziel- zur Ausgangs-CDB

1
2
3
4
5
6
7
8
9
10
11
12
13
SQL> REM     =======================================================================
SQL> REM     CREATE Public DATABASE Link FROM SOURCE CDB CDB111 TO Target CDB CDB112
SQL> REM     =======================================================================
SQL> 
SQL> 
SQL> CONNECT sys/manager@cdb112.markusdba.local AS sysdba
Connected.
SQL> 
SQL> CREATE public DATABASE link cdb111.markusdba.local
  2  CONNECT TO c##cloneuser IDENTIFIED BY manager
  3  USING 'CDB111.markusdba.local';
 
DATABASE link created.

Damit sind die Vorbereitungen abgeschlossen.

Schritt 5: Verschieben der PDB

Jetzt verschieben wir die PDB:

1
2
3
4
5
6
7
8
9
10
11
SQL> REM     =======================================================================
SQL> REM     Relocate PDB PDBRELOC
SQL> REM     =======================================================================
SQL> 
SQL> CREATE PLUGGABLE DATABASE PDBRELOC
  2  FROM PDBRELOC@CDB111.markusdba.local
  3  RELOCATE AVAILABILITY MAX
  4  file_name_convert=
  5  ('/u01/oradata/CDB111/PDBRELOC/','/u01/oradata/CDB112/PDBRELOC/');
 
Pluggable DATABASE created.

Das Vorgehen entspricht im Wesentlichen dem “remote cloning” einer PDB.
Der Parameter “RELOCATE AVAILABILITY MAX” sorgt dafür, dass später das “Connection Forwarding” aktiviert wird.
“RELOCATE AVAILABILITY NORMAL” ist die Relocate-Variante, die ohne dieses Forwarding arbeitet.

Sobald der Befehl ausgeführt ist, sind die Dateien der PDB auf den Server vm112 kopiert.
Die PDB ist weiterhin auf dem Server vm111 geöffnet und die Benutzer können dort arbeiten.

Wie ist jetzt der Status der PDB?

In der Ausgangs-CDB:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> REM     =======================================================================
SQL> REM     CHECK the STATUS OF the PDB PDBRELOC IN the SOURCE CDB CDB111
SQL> REM     =======================================================================
SQL> 
SQL> CONNECT sys/manager@cdb111.markusdba.local AS sysdba
Connected.
SQL> 
SQL> COLUMN pdb_name FORMAT a15
SQL> 
SQL> SELECT
  2  	 pdb_id,
  3  	 pdb_name,
  4  	 STATUS,
  5  	 foreign_pdb_id
  6  FROM
  7  	 dba_pdbs;
 
    PDB_ID PDB_NAME        STATUS     FOREIGN_PDB_ID                                                                    
---------- --------------- ---------- --------------                                                                    
         2 PDB$SEED        NORMAL                  0                                                                    
         4 PDBRELOC        NORMAL                  2

Und wie sieht es auf der Ziel-CDB aus?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> REM     =======================================================================
SQL> REM     CHECK the STATUS OF the PDB PDBRELOC IN the Target CDB CDB112
SQL> REM     =======================================================================
SQL> 
SQL> CONNECT sys/manager@cdb112.markusdba.local AS sysdba
Connected.
SQL> 
SQL> COLUMN pdb_name FORMAT a15
SQL> 
SQL> SELECT
  2  	 pdb_id,
  3  	 pdb_name,
  4  	 STATUS,
  5  	 foreign_pdb_id
  6  FROM
  7  	 dba_pdbs;
 
    PDB_ID PDB_NAME        STATUS     FOREIGN_PDB_ID                                                                    
---------- --------------- ---------- --------------                                                                    
         2 PDB$SEED        NORMAL                  0                                                                    
         3 PDBRELOC        RELOCATING              4

Die FOREIGN_PDB_ID verweist auf die PDB_ID der Ausgangs-CDB.

 

Schritt 6: Öffnen der PDB in der Ziel-CDB

1
2
3
4
5
6
7
SQL> REM     =============================================================
SQL> REM     OPEN the PDB PDBRELOC ON the Target CDB CDB112
SQL> REM     =============================================================
SQL> 
SQL> ALTER pluggable DATABASE PDBRELOC OPEN;
 
Pluggable DATABASE altered.

Oracle öffnet nicht nur die PDB auf dem neuen Server, sondern schließt auch die PDB in der Ausgangs-CDB.
Transaktionen die dort abgeschlossen waren, werden auf den neuen Server übertragen (Redolog-Transfer), nicht-abgeschlossene Transaktionen werden zurückgerollt (UNDO).
Client-Verbindungen müssen sich neu anmelden, wenn nicht ein Service mit Transparent Application Failover (TAF) verwendet wird.

Wie sieht jetzt die Listener-Konfiguration aus?
Interessant ist dabei der Server vm111:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
oracle@vm111:~/ [rdbms12201] lsnrctl services
 
LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 21-JAN-2018 14:53:00
 
Copyright (c) 1991, 2016, Oracle.  All rights reserved.
 
Connecting to (ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))
Services Summary...
 
[..]
 
Service "pdbreloc.markusdba.local" has 1 instance(s).
  Instance "CDB111", status READY, has 2 handler(s) for this service...
    Handler(s):
      "D000" established:0 refused:0 current:0 max:1022 state:ready
         DISPATCHER 
         (ADDRESS=(PROTOCOL=tcp)(HOST=vm111.markusdba.local)(PORT=24448))
      "COMMON" established:0 refused:0 state:ready
         FORWARD SERVER
         (ADDRESS=(PROTOCOL=TCP)(HOST=vm112.markusdba.local)(PORT=1521))
The command completed successfully

Auf dem Server ist der Service der PDB also weiterhin vorhanden, allerdings mit einer Weiterleitung “Forward Server” auf den Server vm112.

Und wie ist der Status der PDB PDBRELOC?

Auf dem Ausgangsserver vm111/CDB111:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SQL> REM     =======================================================================
SQL> REM     CHECK the STATUS OF the PDB PDBRELOC IN the SOURCE CDB CDB111
SQL> REM     =======================================================================
SQL> 
SQL> CONNECT sys/manager@cdb111.markusdba.local AS sysdba
Connected.
SQL> COLUMN pdb_name FORMAT a15
SQL> 
SQL> SELECT
  2  	 pdb_id,
  3  	 pdb_name,
  4  	 STATUS,
  5  	 foreign_pdb_id
  6  FROM
  7  	 dba_pdbs;
 
    PDB_ID PDB_NAME        STATUS     FOREIGN_PDB_ID                                                                    
---------- --------------- ---------- --------------                                                                    
         2 PDB$SEED        NORMAL                  0                                                                    
         4 PDBRELOC        RELOCATED               2

Auf dem Zielserver vm112/CDB112:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL> SELECT
  2  	 pdb_id,
  3  	 pdb_name,
  4  	 STATUS,
  5  	 foreign_pdb_id
  6  FROM
  7  	 dba_pdbs;
 
    PDB_ID PDB_NAME        STATUS     FOREIGN_PDB_ID                                                                    
---------- --------------- ---------- --------------                                                                    
         2 PDB$SEED        NORMAL                  0                                                                    
         3 PDBRELOC        NORMAL                  4                                                                    
 
SQL>

 

 

“PDB relocate” ist somit eine einfache Möglichkeit, eine PDB fast ohne Downtime auf einen anderen Server oder in eine andere CDB zu verschieben. Aber ganz ohne einen erneuten Verbindungsaufbau der Clients geht es leider nicht. Hier hilft dann Transparent Application Failover, den Neu-Aufbau der Verbindung zu automatisieren.

Werbung (Amazon-Partner-Link)