{
  "date": "2017-02-21T20:40:31",
  "slug": "12cr2-lockdown-profiles-and-ora-01219",
  "link": "https://www.dbi-services.com/blog/12cr2-lockdown-profiles-and-ora-01219/",
  "title": {
    "rendered": "12cR2: lockdown profiles and ORA-01219"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nWhen you cannot open a database, you will get some users unhappy. When you cannot open multitenant database, then the number of unhappy users is multiplied by the number of PDBs. I like to encounter problems in my lab before seeing them in production. Here is a case where I&#8217;ve lost a file. I don&#8217;t care about the tablespace, but would like to put it offline and at least be able to open the database.<br />\n<!--more--></p>\n<h3>ORA-01113</h3>\n<p>So, it&#8217;s my lab, I dropped a file while the database was down. The file belongs to a PDB but I cannot open the CDB:</p>\n<pre><code>\nSQL&gt; startup\nORACLE instance started.\n&nbsp;\nTotal System Global Area 1577058304 bytes\nFixed Size                  8793208 bytes\nVariable Size            1124074376 bytes\nDatabase Buffers          436207616 bytes\nRedo Buffers                7983104 bytes\nDatabase mounted.\nORA-01113: file 23 needs media recovery\nORA-01110: data file 23: '/tmp/STATSPACK.dbf'\n</code></pre>\n<p>Yes this is a lab, I like to put datafiles in /tmp (lab only) and I was testing my Statspack scripts for an article to be published soon. I&#8217;ve removed the file and have no backup. I recommand to do nasty things on labs, because those things sometimes happen on production systems and better be prepared. This recommandation supposes you cannot mistake your lab prompt with a production one of course.</p>\n<h3>ORA-01157</h3>\n<p>The database is in mount. I cannot open it:</p>\n<pre><code>\nSQL&gt; alter database open; \nalter database open \n* \nERROR at line 1: \nORA-01157: cannot identify/lock data file 23 - see DBWR trace file \nORA-01110: data file 23: '/tmp/STATSPACK.dbf' \n</code></pre>\n<p>This is annoying. I would like to deal with this datafile later and open the CDB. I accept that the PDB it belongs to (PDB1 here) cannot be opened but I wish I can open the other ones quickly.</p>\n<h3>ORA-01219</h3>\n<p>Let&#8217;s go to the PDB and take the datafile offline:</p>\n<pre><code>\nSQL&gt; alter session set container=pdb1;\nSession altered.\n&nbsp;\nSQL&gt; alter database datafile 23 offline for drop;\nalter database datafile 23 offline for drop\n*\nERROR at line 1:\nORA-00604: error occurred at recursive SQL level 1\nORA-01219: database or pluggable database not open: queries allowed on fixed tables or views only\n</code></pre>\n<p>This is quite annoying. I know that the database is not open. I know that the pluggable database is not open. I want to put a datafile offline, and this is an operation that concerns only the controlfile. No need to have the database opened. Actually, I need to put this datafile offline in order to open the CDB.</p>\n<h3>SQL_TRACE</h3>\n<p>This is annoying, but you know why Oracle is the best database system: troubleshooting. I have an error produced by recursive SQL (ORA-00604) and I want to know the SQL statement that raised this error:</p>\n<pre><code>\nSQL&gt; alter session set sql_trace=true;\nalter session set sql_trace=true;\n*\nERROR at line 1:\nORA-00604: error occurred at recursive SQL level 1\nORA-01219: database or pluggable database not open: queries allowed on fixed tables or views only\n</code></pre>\n<p>Oh yes, I forgot that I cannot issue any SQL statement. But you know why Oracle is the best database system: troubleshooting.</p>\n<pre><code>\nSQL&gt; oradebug setmypid\nStatement processed.\nSQL&gt; oradebug EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12;\nStatement processed.\n&nbsp;\nSQL&gt; alter database datafile 23 offline for drop;\nalter database datafile 23 offline for drop\n*\nERROR at line 1:\nORA-00604: error occurred at recursive SQL level 1\nORA-01219: database or pluggable database not open: queries allowed on fixed tables or views only\n&nbsp;\nSQL&gt; oradebug EVENT 10046 TRACE NAME CONTEXT OFF;\nStatement processed.\nSQL&gt; oradebug TRACEFILE_NAME\n/u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_ora_20258.trc\n</code></pre>\n<p>Here is the trace:</p>\n<pre><code>\n*** 2017-02-21T13:36:51.239026+01:00 (PDB1(3))\n=====================\nPARSING IN CURSOR #140359700679600 len=34 dep=0 uid=0 oct=35 lid=0 tim=198187306591 hv=3069536809 ad='7b8db148' sqlid='dn9z45avgauj9'\nalter database datafile 12 offline\nEND OF STMT\nPARSE #140359700679600:c=3000,e=71171,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=198187306590\nWAIT #140359700679600: nam='PGA memory operation' ela= 30 p1=327680 p2=1 p3=0 obj#=-1 tim=198187307242\nWAIT #140359700679600: nam='control file sequential read' ela= 14 file#=0 block#=1 blocks=1 obj#=-1 tim=198187307612\nWAIT #140359700679600: nam='control file sequential read' ela= 13 file#=0 block#=16 blocks=1 obj#=-1 tim=198187307743\nWAIT #140359700679600: nam='control file sequential read' ela= 6 file#=0 block#=18 blocks=1 obj#=-1 tim=198187307796\nWAIT #140359700679600: nam='control file sequential read' ela= 9 file#=0 block#=1119 blocks=1 obj#=-1 tim=198187307832\n</code></pre>\n<p>This is expected. I&#8217;m in PDB1 (container id 3) and run my statement to put the datafile offline.<br />\nAnd then it switches to CDB$ROOT (container 0):</p>\n<pre><code>\n*** 2017-02-21T13:36:51.241022+01:00 (CDB$ROOT(1))\n=====================\nPARSING IN CURSOR #140359700655928 len=248 dep=1 uid=0 oct=3 lid=0 tim=198187308584 hv=1954812753 ad='7b67d9c8' sqlid='6qpmyqju884uj'\nselect ruletyp#, ruleval, status, ltime                                       from lockdown_prof$                                                           where prof#=:1 and level#=:2                                                  order by ltime\nEND OF STMT\nPARSE #140359700655928:c=2000,e=625,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=198187308583\n=====================\nPARSE ERROR #140359700655928:len=249 dep=1 uid=0 oct=3 lid=0 tim=198187308839 err=1219\nselect ruletyp#, ruleval, status, ltime                                       from lockdown_prof$                                                           where prof#=:1 and level#=:2                                                  order by ltime\n&nbsp;\n*** 2017-02-21T13:36:51.241872+01:00 (PDB1(3))\nEXEC #140359700679600:c=4000,e=2684,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=198187309428\nERROR #140359700679600:err=604 tim=198187309511\n</code></pre>\n<p>I have a parse error when reading LOCKDOWN_PROF$ in the root container. It is a table, a dictionary table stored in SYSTEM tablespace. The CDB is not open. It is not accessible, reason for the error message.</p>\n<p>Then, I remember that I&#8217;ve set a lockdown profile at CDB level. It doesn&#8217;t make sense for CDB$ROOT, but I&#8217;ve set it to get it as default for all new created PDBs. Any statement that may be disabled by a lockdown profile has to read the lockdown profile rules stored in root. And here I learn that this occurs when parsing the DDL statement, not at execution time.</p>\n<p>In my opinion this is a bug. Either I should not set pdb_lockdown at CDB level, or it shouldn&#8217;t be checked when the CDB is closed. Because then any DDL will fail. I&#8217;m not blocked by the lockdown profile here. Just because the lockdown profile cannot be read.</p>\n<h3>pdb_lockdown</h3>\n<p>Now I know how to workaround the problem: unset the lockdown profile, offline my datafile, open the CDB, open the PDB, drop the tablespace.</p>\n<pre><code>SQL&gt; alter system set pdb_lockdown='';\nSystem altered.\nSQL&gt; alter session set container=pdb1;\nSession altered.\nSQL&gt; alter database datafile 23 offline for drop;\nDatabase altered.\nSQL&gt; alter session set container=cdb$root;\nSession altered.\nSQL&gt; alter database open;</code></pre>\n<p>Lockdown profile is a very nice feature allowing fine grain control on what can be done by users on a PDB, even admins ones. But it is a new mecanism, leading to situations we have never seen before. Don&#8217;t forget the power (and fun) of troubleshooting.</p>\n",
    "protected": false
  }
}
