{
  "date": "2017-05-29T18:59:56",
  "slug": "which-privilege-for-create-pluggable-database-from-db-link",
  "link": "https://www.dbi-services.com/blog/which-privilege-for-create-pluggable-database-from-db-link/",
  "title": {
    "rendered": "Which privilege for CREATE PLUGGABLE DATABASE from DB LINK?"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nWhen cloning a PDB from a remote CDB you need to define a database link to be used in the CREATE PLUGGABLE DATABASE &#8230; FROM &#8230;@&#8230; command. The documentation is not completely clear about the privileges required on the source for the user defined in the database link, so here are the different possibilities.</p>\n<h3>Remote clone</h3>\n<p>Here is what the documentation says:<a href=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/CapturePDBPrivsClone.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/CapturePDBPrivsClone.png\" alt=\"CapturePDBPrivsClone\" width=\"1024\" height=\"156\" class=\"alignnone size-large wp-image-16886\" /></a></p>\n<p>So you can connect to the CDB or to the PDB.</p>\n<p>In order to connect to the CDB you need a common user with the CREATE SESSION system privilege:</p>\n<pre><code>\nSQL&gt; create user C##DBA identified by oracle;\nUser C##DBA created.\nSQL&gt; grant create session to C##DBA container=current;\nGrant succeeded.\n</code></pre>\n<p>No need for CONTAINER=ALL here because you connect only to the CDB$ROOT.</p>\n<p>Then you need the CREATE PLUGGABLE DATABASE system privilege on the PDB. You can grant it from the CDB$ROOT with the CONTAINER=ALL but it is sufficient to grant it locally on the source PDB:</p>\n<pre><code>\nSQL&gt; alter session set container=PDB1;\nSession altered.\nSQL&gt; grant create pluggable database to C##DBA container=current;\nGrant succeeded.\n</code></pre>\n<p>Note that, not documented, but the SYSOPER administrative privilege can replace the CREATE PLUGGABLE DATABASE so we can run the following instead of the previous one:</p>\n<pre><code>\nSQL&gt; alter session set container=PDB1;\nSession altered.\ngrant sysoper to C##DBA container=current;\nGrant succeeded.\n</code></pre>\n<p>Both ways are usable for cloning, you create a database link to this common user, on the destination, and run the CLONE PLUGGABLE DATABASE:</p>\n<pre><code>\nSQL&gt; create database link CDB1A connect to C##DBA identified by oracle using '//localhost/CDB1A';\nDatabase link CDB1A created.\nSQL&gt; create pluggable database PDB1CLONE from PDB1@CDB1A file_name_convert=('CDB1A/PDB1','CDB2A/PDB1CLONE');\nPluggable database PDB1CLONE created.\nSQL&gt; alter  pluggable database PDB1CLONE open;\nPluggable database PDB1CLONE altered.\n</code></pre>\n<p>This was using a common user but you can also define the user locally on the source PDB:</p>\n<pre><code>\nSQL&gt; alter session set container=PDB1;\nSession altered.\nSQL&gt; create user PDBDBA identified by oracle;\nUser PDBDBA created.\nSQL&gt; grant create session to PDBDBA container=current;\nGrant succeeded.\nSQL&gt; grant create pluggable database to PDBDBA container=current;\nGrant succeeded.\n</code></pre>\n<p>There again you have the alternative to use SYSOPER instead of CREATE PLUGGABLE DATABASE:</p>\n<pre><code>\nSQL&gt; alter session set container=PDB1;\nSession altered.\nSQL&gt; create user PDBDBA identified by oracle;\nUser PDBDBA created.\nSQL&gt; grant create session to PDBDBA container=current;\nGrant succeeded.\nSQL&gt; grant sysoper to PDBDBA container=current;\nGrant succeeded.\n</code></pre>\n<p>With one of those, you can clone from the target with a database link connecting to the local user only:</p>\n<pre><code>\nSQL&gt; create database link CDB1A connect to PDBDBA identified by oracle using '//localhost/PDB1';\nDatabase link CDB1A created.\nSQL&gt; create pluggable database PDB1CLONE from PDB1@CDB1A file_name_convert=('CDB1A/PDB1','CDB2A/PDB1CLONE');\nPluggable database PDB1CLONE created.\nSQL&gt; alter  pluggable database PDB1CLONE open;\nPluggable database PDB1CLONE altered.\n</code></pre>\n<p>Then which alternative to use? The choice of the common or local user is up to you. I probably use a common user to do system administration, and cloning is one of them. But if you are in a PDBaaS environment where you are the PDB administrator, then you can clone your PDB to another CDB that you manage. This can mean cloning a PDB from the Cloud to a CDB on your laptop.</p>\n<h3> PDB Relocate</h3>\n<p>Things are different with the RELOCATE option where you drop the source PDB and redirect the connection to the new one. This is definitely a system administration task to do at CDB level and requires a common user. Trying it from a database link connecting to a local user will raise the following error:</p>\n<pre><code>\nORA-17628: Oracle error 65338 returned by remote Oracle server\n&nbsp;\n65338, 00000, \"unable to create pluggable database\"\n// *Cause:  An attempt was made to relocate a pluggable database using a\n//          database link to the source pluggable database.\n// *Action: Use a database link that points to the source multitenant container\n//          database root and retry the operation.\n</code></pre>\n<p>Here is what the documentation says:<a href=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/CapturePDBPrivsRelocate.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/CapturePDBPrivsRelocate.png\" alt=\"CapturePDBPrivsRelocate\" width=\"1024\" height=\"185\" class=\"alignnone size-large wp-image-16888\" /></a></p>\n<p>So, we need to have a common user on the source CDB, with CREATE SESSION privilege, and it makes sense to use an administrative privilege:</p>\n<pre><code>\nSQL&gt; create user C##DBA identified by oracle;\nUser C##DBA created.\nSQL&gt; grant create session to C##DBA container=current;\nGrant succeeded.\nSQL&gt; alter session set container=PDB1;\nSession altered.\ngrant sysoper to C##DBA container=current;\nGrant succeeded.\n</code></pre>\n<p>The documentation mentions that you can use either SYSDBA or SYSOPER, but from my tests (and <a href=\"https://www.toadworld.com/platforms/oracle/w/wiki/11750.near-zero-downtime-pdb-relocation-in-oracle-database-12cr2\" target=\"_blank\" rel=\"noopener noreferrer\">Deiby Gómez ones</a>) only SYSOPER works without raising an &#8216;insufficient privileges&#8217;. The documentation mentions that CREATE PLUGGABLE DATABASE is also necessary. Actually, it is not. And, with a relocate, it cannot be an alternative to SYSOPER. The user must be a common user, the CREATE SESSION must be granted commonly, but the SYSOPER can be locally for the PDB we relocate.</p>\n<h3>In summary</h3>\n<p>To clone a remote PDB you can use a common or local user, with SYSOPER or CREATE PLUGGABLE DATABASE privilege. To relocate a PDB you need a common user with SYSOPER.</p>\n",
    "protected": false
  }
}
