{
  "date": "2016-11-11T05:19:32",
  "slug": "oracle-12cr2-pluggable-database-relocation",
  "link": "https://www.dbi-services.com/blog/oracle-12cr2-pluggable-database-relocation/",
  "title": {
    "rendered": "Oracle 12cR2: Pluggable database relocation"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nHere is, in my opinion, the most beautiful feature of the multitenant architecture. You know how I love Transportable Tablespaces. But here:</p>\n<ul>\n<li>No need to put the source in read/only</li>\n<li>No need to export/import the metadata logically</li>\n<li>No need for any option: available even in Standard Edition</li>\n</ul>\n<p><!--more--></p>\n<h3>Standard Edition</h3>\n<p>I am in Standard Edition here in both source and target, no option required for this:</p>\n<pre><code>\nSQL*Plus: Release 12.2.0.1.0 Production on Thu Nov 10 13:40:05 2016\nCopyright (c) 1982, 2016, Oracle.  All rights reserved.\n&nbsp;\nConnected to:\nOracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production\n</code></pre>\n<h3>Source: PDB1 on CDB1</h3>\n<p>On server opc1 I have a container database CDB1 with one pluggable database PDB1 where I create a new table:</p>\n<pre><code>\n23:40:20 (opc1)CDB1 SQL&gt;alter session set container=PDB1;\nSession altered.\n23:40:20 (opc1)CDB1 SQL&gt;create table DEMO as select current_timestamp insert_timestamp,instance_name from v$instance;\nTable created.\n23:40:21 (opc1)CDB1 SQL&gt;insert into DEMO select current_timestamp,instance_name from v$instance;\n1 row created.\n23:40:21 (opc1)CDB1 SQL&gt;select * from DEMO;\n&nbsp;\nINSERT_TIMESTAMP                    INSTANCE_NAME\n----------------------------------- ----------------\n10-NOV-16 11.40.20.902761 PM +00:00 CDB1\n10-NOV-16 11.40.21.966815 PM +00:00 CDB1\n</code></pre>\n<h3>Export encryption key</h3>\n<p>I&#8217;m in Oracle Public Cloud where tablespaces are encrypted. To ship a pluggable database I must export the keys. Here is the query to get them:</p>\n<pre><code>\n23:40:23 (opc1)CDB1 SQL&gt;select key_id from v$encryption_keys where creator_pdbname='PDB1';\n&nbsp;\nKEY_ID\n------------------------------------------------------------------------------\nAWlnBaUXG0/gv4evS9Ywu8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n</code></pre>\n<p>And I can filter with this query to export it:</p>\n<pre><code>\n23:40:23 (opc1)CDB1 SQL&gt;administer key management export encryption keys with secret \"oracle\" to '/tmp/cdb2pdb1.p12' identified by \"Ach1z0#d\" with identifier in (select key_id from v$encryption_keys where creator_pdbname='PDB1');\nadminister key management export encryption keys with secret \"oracle\" to '/tmp/cdb2pdb1.p12' identified by \"Ach1z0#d\" with identifier in (select key_id from v$encryption_keys where creator_pdbname='PDB1')\n*\nERROR at line 1:\nORA-28417: password-based keystore is not open\n</code></pre>\n<p>I can&#8217;t do that with auto-login wallet.</p>\n<pre><code>\n23:40:23 (opc1)CDB1 SQL&gt;select wrl_type,wrl_parameter,wallet_type from v$encryption_wallet;\n&nbsp;\nWRL_TYPE WRL_PARAMETER                          WALLET_TY\n-------- -------------------------------------- ---------\nFILE     /u01/app/oracle/admin/CDB1/tde_wallet/ AUTOLOGIN\n</code></pre>\n<p> Let&#8217;s open the wallet with password:</p>\n<pre><code>\n23:40:23 (opc1)CDB1 SQL&gt;administer key management set keystore close;\nkeystore altered.\n23:40:23 (opc1)CDB1 SQL&gt;administer key management set keystore open identified by \"Ach1z0#d\";\nkeystore altered.\n23:40:23 (opc1)CDB1 SQL&gt;select wrl_type,wrl_parameter,wallet_type from v$encryption_wallet;\n&nbsp;\nWRL_TYPE WRL_PARAMETER                          WALLET_TY\n-------- -------------------------------------- ---------\nFILE     /u01/app/oracle/admin/CDB1/tde_wallet/ PASSWORD\n</code></pre>\n<p>and re-try my export:</p>\n<pre><code>\n23:40:23 (opc1)CDB1 SQL&gt;administer key management export encryption keys with secret \"oracle\" to '/tmp/cdb2pdb1.p12' identified by \"Ach1z0#d\" with identifier in (select key_id from v$encryption_keys where creator_pdbname='PDB1');\nkeystore altered.\n</code></pre>\n<p>This file must be copied to the destination server. I did it with scp. You can also use dbms_file_transfer as you will need a database link anyway for the remote clone.</p>\n<h3>Import encryption key</h3>\n<p>On the destination server, where I have no CDB (I&#8217;m limited to one PDB here without the multitenant option)</p>\n<pre><code>\n23:40:31 (opc2)CDB2 SQL&gt;show pdbs\n&nbsp;\n    CON_ID CON_NAME                       OPEN MODE  RESTRICTED\n---------- ------------------------------ ---------- ----------\n         2 PDB$SEED                       READ ONLY  NO\n</code></pre>\n<p>I have to import the encryption key:</p>\n<pre><code>\n23:40:31 (opc2)CDB2 SQL&gt;administer key management set keystore open identified by \"Ach1z0#d\";\nkeystore altered.\n&nbsp;\n23:40:31 (opc2)CDB2 SQL&gt;administer key management import encryption keys with secret \"oracle\" from '/tmp/cdb2pdb1.p12' identified by \"Ach1z0#d\";\nkeystore altered.\n</code></pre>\n<p>I&#8217;m now ready to relocate my PDB as I&#8217;m sure I&#8217;ll be ready to open it.</p>\n<h3>Database link</h3>\n<p>The remote clone is done through a DB link. I&#8217;ve a TNS entry named CDB1:</p>\n<pre><code>\n23:40:31 (opc2)CDB2 SQL&gt;select dbms_tns.resolve_tnsname('CDB1') from dual;\n&nbsp;\nDBMS_TNS.RESOLVE_TNSNAME('CDB1')\n--------------------------------------------------------------------------------\n(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=opc1)(PORT=1521))(CONNECT_DAT\nA=(SERVER=DEDICATED)(SERVICE_NAME=CDB1.opcoct.oraclecloud.internal)(CID=(PROGRAM\n=oracle)(HOST=SE222.compute-opcoct.oraclecloud.internal)(USER=oracle))))\n&nbsp;\n23:40:31 (opc2)CDB2 SQL&gt;create database link CDB1 connect to C##DBA identified by oracle using 'CDB1';\nDatabase link created.\n</code></pre>\n<h3>DML on source</h3>\n<p>In order to show that the source doesn&#8217;t have to be read only as in previous release, I&#8217;m running the following inserts every 5 minutes:</p>\n<pre><code>\n23:40:44 (opc1)CDB1 SQL&gt;commit;\nCommit complete.\n23:40:44 (opc1)CDB1 SQL&gt;insert into DEMO select current_timestamp,instance_name from v$instance;\n1 row created.\n23:40:44 (opc1)CDB1 SQL&gt;select * from DEMO;\n&nbsp;\nINSERT_TIMESTAMP                    INSTANCE_NAME\n----------------------------------- ----------------\n10-NOV-16 11.40.20.902761 PM +00:00 CDB1\n10-NOV-16 11.40.21.966815 PM +00:00 CDB1\n10-NOV-16 11.40.29.136529 PM +00:00 CDB1\n10-NOV-16 11.40.34.214467 PM +00:00 CDB1\n10-NOV-16 11.40.39.304515 PM +00:00 CDB1\n10-NOV-16 11.40.44.376796 PM +00:00 CDB1\n6 rows selected.\n</code></pre>\n<h3>PDB remote clone</h3>\n<p>Here is the syntax.<br />\nI need to provide the masterkey of the source wallet.<br />\nThe RELOCATE is this new feature where the source PDB will be relocated to the destination when the clone is opened.</p>\n<pre><code>\n23:40:48 (opc2)CDB2 SQL&gt;create pluggable database PDB1 from PDB1@CDB1 keystore identified by \"Ach1z0#d\" relocate;\nPluggable database created.\n23:41:08 (opc2)CDB2 SQL&gt;\n</code></pre>\n<p>It took some time, shipping the datafiles through the DB link, but this is online.<br />\nI was still inserting during this time:</p>\n<pre><code>\n23:41:04 (opc1)CDB1 SQL&gt;select * from DEMO;\n&nbsp;\nINSERT_TIMESTAMP                    INSTANCE_NAME\n----------------------------------- ----------------\n10-NOV-16 11.40.20.902761 PM +00:00 CDB1\n10-NOV-16 11.40.21.966815 PM +00:00 CDB1\n10-NOV-16 11.40.29.136529 PM +00:00 CDB1\n10-NOV-16 11.40.34.214467 PM +00:00 CDB1\n10-NOV-16 11.40.39.304515 PM +00:00 CDB1\n10-NOV-16 11.40.44.376796 PM +00:00 CDB1\n10-NOV-16 11.40.49.454661 PM +00:00 CDB1\n10-NOV-16 11.40.54.532699 PM +00:00 CDB1\n10-NOV-16 11.40.59.614745 PM +00:00 CDB1\n10-NOV-16 11.41.04.692784 PM +00:00 CDB1\n&nbsp;\n10 rows selected.\n</code></pre>\n<p>Note that you need to be in ARCHIVELOG and LOCAL UNDO to be able to do this because syncronisation will be made by media recovery when we open the clone.</p>\n<h3>Open the clone</h3>\n<p>Now, the theory is that when we open the clone, DML is quiesced on source during the recovery of the target and sessions can continue on the target once opened.</p>\n<pre><code>\n23:41:09 (opc2)CDB2 SQL&gt;alter pluggable database PDB1 open;\nalter pluggable database PDB1 open\n*\nERROR at line 1:\nORA-00060: deadlock detected while waiting for resource\n23:41:26 (opc2)CDB2 SQL&gt;\n</code></pre>\n<p>Bad luck. Every time I tested this scenario, the first open after the relocate fails in deadlock and the session on the source crashes:</p>\n<pre><code>\n23:41:09 (opc1)CDB1 SQL&gt;select * from DEMO;\n&nbsp;\nINSERT_TIMESTAMP                    INSTANCE_NAME\n----------------------------------- ----------------\n10-NOV-16 11.40.20.902761 PM +00:00 CDB1\n10-NOV-16 11.40.21.966815 PM +00:00 CDB1\n10-NOV-16 11.40.29.136529 PM +00:00 CDB1\n10-NOV-16 11.40.34.214467 PM +00:00 CDB1\n10-NOV-16 11.40.39.304515 PM +00:00 CDB1\n10-NOV-16 11.40.44.376796 PM +00:00 CDB1\n10-NOV-16 11.40.49.454661 PM +00:00 CDB1\n10-NOV-16 11.40.54.532699 PM +00:00 CDB1\n10-NOV-16 11.40.59.614745 PM +00:00 CDB1\n10-NOV-16 11.41.04.692784 PM +00:00 CDB1\n10-NOV-16 11.41.09.773300 PM +00:00 CDB1\n&nbsp;\n11 rows selected.\n&nbsp;\n23:41:14 (opc1)CDB1 SQL&gt; commit;\nERROR:\nORA-03114: not connected to ORACLE\n</code></pre>\n<p>It&#8217;s a good occasion to look at the traces.<br />\nWe can see some messages about the recovery:</p>\n<pre><code>\n*** 2016-11-10T23:41:12.660402+00:00 (PDB1(3))\nMedia Recovery Log /u03/app/oracle/fast_recovery_area/CDB1/foreign_archivelog/PDB1/2016_11_10/o1_mf_1_24_2025109931_.arc\nLog read is SYNCHRONOUS though disk_asynch_io is enabled!\n</code></pre>\n<p>Those FOREIGN ARCHIVED LOG is a new type of file that you will see in the FRA in 12.2.</p>\n<p>So I lost my session on source and now if I try again it works:</p>\n<pre><code>\n23:42:20 (opc2)CDB2 SQL&gt;alter pluggable database PDB1 open;\nPluggable database altered.\n23:42:24 (opc2)CDB2 SQL&gt;select * from DEMO;\n&nbsp;\nINSERT_TIMESTAMP                    INSTANCE_NAME\n----------------------------------- ----------------\n10-NOV-16 11.40.20.902761 PM +00:00 CDB1\n10-NOV-16 11.40.21.966815 PM +00:00 CDB1\n10-NOV-16 11.40.29.136529 PM +00:00 CDB1\n10-NOV-16 11.40.34.214467 PM +00:00 CDB1\n10-NOV-16 11.40.39.304515 PM +00:00 CDB1\n10-NOV-16 11.40.44.376796 PM +00:00 CDB1\n10-NOV-16 11.40.49.454661 PM +00:00 CDB1\n10-NOV-16 11.40.54.532699 PM +00:00 CDB1\n10-NOV-16 11.40.59.614745 PM +00:00 CDB1\n10-NOV-16 11.41.04.692784 PM +00:00 CDB1\n&nbsp;\n10 rows selected.\n</code></pre>\n<p>All the inserts that were commited on the source are there.<br />\nEven with this deadlock bug (SR 3-13618219421), it&#8217;s the easiest and fastest way to migrate a database, with the minimum of downtime. Especially in Standard Edition where transportable tablespaces import is not enabled.<br />\nWithout the deadlock bug, the sessions on the source are supposed to be still running , only paused during the recovery, and then continue on the destination.</p>\n",
    "protected": false
  }
}
