{
  "date": "2016-11-16T09:32:35",
  "slug": "12cr2-create_file_dest-for-pdb-isolation",
  "link": "https://www.dbi-services.com/blog/12cr2-create_file_dest-for-pdb-isolation/",
  "title": {
    "rendered": "12cR2: CREATE_FILE_DEST for PDB isolation"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nTwo years ago I filled an <a href=\"https://community.oracle.com/ideas/2495\" target=\"_blank\" rel=\"noopener noreferrer\">OTN idea</a> to &#8216;Constrain PDB datafiles into specific directory&#8217; and made it an enhancement request for 12<em>c</em> Release 2. When you provision a PDB, the PDB admin can create tablespaces and put datafiles anywhere in your system. Of course this is not acceptable in a cloud environment. 12.1 has a parameter for directories (PATH_PREFIX) and 12.2 brings CREATE_FILE_DEST for datafiles.<br />\n<!--more--></p>\n<h3>create_file_dest</h3>\n<p>Here is the new option when you create a pluggable database:</p>\n<pre><code>\nSQL&gt;  create pluggable database PDB1 admin user admin identified by password role=(DBA)\n      create_file_dest='/u02/app/oracle/oradata/CDB2/PDB1';\n&nbsp;\nPluggable database created.\n</code></pre>\n<p>Let&#8217;s see where are my datafiles:</p>\n<pre><code>\nSQL&gt; alter pluggable database PDB1 open;\nPluggable database altered.\nSQL&gt; alter session set container=PDB1;\nSession altered.\nSQL&gt; select name from v$datafile;\n&nbsp;\nNAME\n--------------------------------------------------------------------------------\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_system_d2od2o7b_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_sysaux_d2od2o7j_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_undotbs1_d2od2o7l_.dbf\n</code></pre>\n<p>My files have been created in the CREATE_FILE_DEST directory specified at PDB creation, and with an OMF structure.<br />\nSo maybe I don&#8217;t want to include the CDB name and the PDB name but only a mount point.</p>\n<p>If, as a local user, I try to create a datafile elsewhere I get an error:</p>\n<pre><code>\nSQL&gt; connect admin/password@//localhost/pdb1.opcoct.oraclecloud.internal\nConnected.\nSQL&gt; create tablespace APPDATA datafile '/tmp/appdata.dbf' size 5M;\ncreate tablespace APPDATA datafile '/tmp/appdata.dbf' size 5M\n*\nERROR at line 1:\nORA-65250: invalid path specified for file - /tmp/appdata.dbf\n</code></pre>\n<p>This is exactly what I wanted.</p>\n<p>Because I&#8217;m bound to this directory, I don&#8217;t need to give an absolute path:</p>\n<pre><code>\nSQL&gt; create tablespace APPDATA datafile 'appdata.dbf' size 5M;\n&nbsp;\nTablespace created.\n&nbsp;\nSQL&gt; select name from v$datafile;\n&nbsp;\nNAME\n-------------------------------------------------------------------------------------------------------------\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_system_d2od2o7b_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_sysaux_d2od2o7j_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_undotbs1_d2od2o7l_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/appdata.dbf\n</code></pre>\n<p>So you don&#8217;t need to use OMF there. If the PDB administrator wants to name the datafiles, he can, as long as they stays under the create_file_dest directory. You can create a datafile in a sub-directory of create_file_dest but it needs to exist of course.</p>\n<h3>db_create_file_dest</h3>\n<p>Here it just looks like OMF, so I check the db_create_file_dest parameter:</p>\n<pre><code>\nSQL&gt; show parameter file_dest\n&nbsp;\nNAME                                 TYPE        VALUE\n------------------------------------ ----------- ---------------------------------\ndb_create_file_dest                  string      /u02/app/oracle/oradata/CDB2/PDB1\n</code></pre>\n<p>and I try to change it (as local user):</p>\n<pre><code>\nSQL&gt; connect admin/password@//localhost/pdb1.opcoct.oraclecloud.internal;\nConnected.\nSQL&gt; alter system set db_create_file_dest='/tmp';\nalter system set db_create_file_dest='/tmp'\n*\nERROR at line 1:\nORA-32017: failure in updating SPFILE\nORA-01031: insufficient privileges\n&nbsp;\nSQL&gt; alter session set db_create_file_dest='/tmp';\nERROR:\nORA-02097: parameter cannot be modified because specified value is invalid\nORA-01031: insufficient privileges\n</code></pre>\n<p>No need to use lockdown profile here, it is verified at runtime that a local user cannot change it.</p>\n<p>If you are connected with a common user, here connected as sysdba, this is the way to change what has been specified at PDB creation time:</p>\n<pre><code>\nSQL&gt; show con_id\n&nbsp;\nCON_ID\n------------------------------\n3\n&nbsp;\nSQL&gt; alter system set db_create_file_dest='/tmp';\nSystem altered.\n&nbsp;\nSQL&gt; create tablespace APP1;\nTablespace created.\n&nbsp;\nSQL&gt; select name from v$datafile;\n&nbsp;\nNAME\n--------------------------------------------------------------------------------\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_system_d2od2o7b_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_sysaux_d2od2o7j_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_undotbs1_d2od2o7l_.dbf\n/u02/app/oracle/oradata/CDB2/PDB1/appdata.dbf\n/tmp/CDB2/415260E5D27B5D4BE0534E186A0A4CB8/datafile/o1_mf_app1_d2ohx5sp_.dbf\n</code></pre>\n<h3>But&#8230;</h3>\n<p>The behavior when you create the PDB with the CREATE_FILE_DEST clause is different than when you create it without, and set db_create_file_dest later. In the second case, the restriction does not occur and a local DBA can create a datafile wherever he wants. </p>\n<p>So I wanted to check whether this attribute is shipped when plugging PDBs. When looking at the pdb_descr_file xml file I don&#8217;t see anything different except the parameter:</p>\n<pre><code>\n   &lt;parameters&gt;\n      &lt;parameter&gt;processes=300\n      &lt;parameter&gt;nls_language='AMERICAN'\n      &lt;parameter&gt;nls_territory='AMERICA'\n      &lt;parameter&gt;filesystemio_options='setall'\n      &lt;parameter&gt;db_block_size=8192\n      &lt;parameter&gt;encrypt_new_tablespaces='CLOUD_ONLY'\n      &lt;parameter&gt;compatible='12.2.0'\n      &lt;parameter&gt;db_files=250\n      &lt;parameter&gt;open_cursors=300\n      &lt;parameter&gt;sql92_security=TRUE\n      &lt;parameter&gt;pga_aggregate_target=1775294400\n      &lt;parameter&gt;sec_protocol_error_trace_action='LOG'\n      &lt;parameter&gt;enable_pluggable_database=TRUE\n      &lt;spfile&gt;*.db_create_file_dest='/u02/app/oracle/oradata/CDB2/PDB1'\n    &lt;/parameters&gt;\n</code></pre>\n<p>So I tried to unplug/plug my PDB and the restriction is gone. So be careful.</p>\n<p>I&#8217;ve not find a documented way to check if restriction is enabled or not (except trying to create a file outside of db_create_file_dest). Please comment if you know.<br />\nHowever, it seems that that a flag in CONTAINER$ is unset when restriction is there:</p>\n<pre><code>\nSQL&gt; create pluggable database PDB1 admin user admin identified by password role=(DBA) create_file_dest='/u02/app/oracle/oradata/CDB2/PDB1';\nPluggable database created.\n&nbsp;\nSQL&gt; select con_id#,flags,decode(bitand(flags, 2147483648), 2147483648, 'YES', 'NO') from container$;\n&nbsp;\n   CON_ID#      FLAGS DEC\n---------- ---------- ---\n         1          0 NO\n         2 3221487616 YES\n         3 1610874880 NO\n</code></pre>\n<p>Creating the same PDB but without the create_file_dest clause has the same flag as &#8216;NO&#8217;</p>\n<pre><code>\ncreate pluggable database PDB1 admin user admin identified by password role=(DBA);\nPluggable database created.\n&nbsp;\nSQL&gt; select con_id#,flags,decode(bitand(flags, 2147483648), 2147483648, 'YES', 'NO') from container$;\n&nbsp;\n   CON_ID#      FLAGS DEC\n---------- ---------- ---\n         1          0 NO\n         2 3221487616 YES\n         3 1074003968 NO\n</code></pre>\n<p>I suppose that it is stored elsewhere because those flags are set only once PDB is opened.</p>\n",
    "protected": false
  }
}
