Beiträge getaggt mit 12c New Features
Initialization Parameter Handling for Pluggable Databases in #Oracle 12c
In a Multitenant Database, the handling of initialization parameters has changed. This post shows some major differences. The playing field:
$ sqlplus / as sysdba SQL*Plus: Release 12.1.0.1.0 Production on Tue Jan 14 21:44:10 2014 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> select name,open_mode,con_id from v$pdbs; NAME OPEN_MODE CON_ID ------------------------------ ---------- ---------- PDB$SEED READ ONLY 2 PDB1 MOUNTED 3
Apart from the mandatory pluggable seed database, there is one pluggable database which is presently not opened. Can I modify initialization parameters for pdb1 now?
SQL> alter session set container=pdb1;
Session altered.
SQL> alter system set ddl_lock_timeout=30;
alter system set ddl_lock_timeout=30
*
ERROR at line 1:
ORA-01219: database or pluggable database not open: queries allowed on fixed
tables or views only
SQL> alter system set ddl_lock_timeout=30 scope=spfile;
System altered.
In spite of the syntax, this did not modify the spfile:
SQL> show parameter spfile
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string /u01/app/oracle/product/12.1.0
/dbhome_1/dbs/spfilecdb1.ora
SQL> host strings /u01/app/oracle/product/12.1.0/dbhome_1/dbs/spfilecdb1.ora
cdb1.__data_transfer_cache_size=0
cdb1.__db_cache_size=251658240
cdb1.__java_pool_size=4194304
cdb1.__large_pool_size=4194304
cdb1.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
cdb1.__pga_aggregate_target=167772160
cdb1.__sga_target=503316480
cdb1.__shared_io_pool_size=20971520
cdb1.__shared_pool_size=209715200
cdb1.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/cdb1/adump'
*.audit_trail='db'
*.compatible='12.1.0.0.0'
*.control_files='/u01/app/oracl
e/oradata/cdb1/control01.ctl','/u01/app/oracle/fast_recovery_area/cdb1/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='cdb1'
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
*.db_recovery_file_dest_size=4800m
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=cdb1XDB)'
*.enable_pluggable_database=true
*.open_cursors=300
*.pga_aggregate_target=160m
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=480m
*.undo_tablesp
ace='UNDOTBS1'
Initialization parameters for pluggable databases are not kept in the spfile – if they are not inherited from the container database, that is. Instead, they are stored in a dictionary table of the container database. The documented view V$SYSTEM_PARAMETER displays them. But only if the pluggable database is opened:
SQL> connect / as sysdba Connected. SQL> select name,value,con_id from v$system_parameter where name='ddl_lock_timeout'; NAME VALUE CON_ID ------------------------------ ---------------------------------------- ------ ddl_lock_timeout 0 0 SQL> select a.name,value$,con_id from pdb_spfile$ a join v$pdbs b on (a.pdb_uid=b.con_uid); NAME VALUE$ CON_ID ------------------------------ ---------------------------------------- ------ ddl_lock_timeout 30 3
The undocumented table PDB_SPFILE$ is internally queried and the parameters are set accordingly when the pluggable database is opened:
SQL> alter pluggable database pdb1 open; Pluggable database altered. SQL> select name,value,con_id from v$system_parameter where name='ddl_lock_timeout'; NAME VALUE CON_ID ------------------------------ ---------------------------------------- ------ ddl_lock_timeout 0 0 ddl_lock_timeout 30 3
Attention, show parameter displays different results, depending on the current container now:
SQL> show con_name CON_NAME ------------------------------ CDB$ROOT SQL> show parameter ddl_lock_timeout NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ ddl_lock_timeout integer 0 SQL> alter session set container=pdb1; Session altered. SQL> show parameter ddl_lock_timeout NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ ddl_lock_timeout integer 30
Upon unplugging the pluggable database, an xml file is generated, containing the description of the pluggable database. I thought that this file contains also the modified initialization parameters of that pluggable database, but that doesn’t seem to be the case. I checked it for the parameters DDL_LOCK_TIMEOUT and RESUMABLE_TIMEOUT and both do not show in the xml file. Instead, they got stored in the system tablespace of the unplugged database! Again, that is not documented and may change in the future.
Isn’t that fun to play with this exciting new stuff? At least I enjoyed it, and I hope you found it useful 🙂
#Oracle Database whoami for Multitenant
As an enhancement to the Oracle Database whoami for versions before 12c, this also shows the Container Name to which the session is connected:
[oracle@linuxbox ~]$ sqlplus / as sysdba SQL*Plus: Release 12.1.0.1.0 Production on Wed Jan 8 12:34:04 2014 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> @whoami USER: SYS SESSION ID: 253 CURRENT_SCHEMA: SYS INSTANCE NAME: cdb1 CDB NAME: cdb1 CONTAINER NAME: CDB$ROOT DATABASE ROLE: PRIMARY OS USER: oracle CLIENT IP ADDRESS: SERVER HOSTNAME: linuxbox CLIENT HOSTNAME: linuxbox PL/SQL procedure successfully completed. SQL> connect system/oracle_4U@pdb1 Connected. SQL> @whoami USER: SYSTEM SESSION ID: 253 CURRENT_SCHEMA: SYSTEM INSTANCE NAME: cdb1 CDB NAME: cdb1 CONTAINER NAME: PDB1 DATABASE ROLE: PRIMARY OS USER: oracle CLIENT IP ADDRESS: 555.555.5.555 SERVER HOSTNAME: linuxbox CLIENT HOSTNAME: linuxbox PL/SQL procedure successfully completed.
The content of whoami.sql:
set serveroutput on
begin
dbms_output.put_line('USER: '||sys_context('userenv','session_user'));
dbms_output.put_line('SESSION ID: '||sys_context('userenv','sid'));
dbms_output.put_line('CURRENT_SCHEMA: '||sys_context('userenv','current_schema'));
dbms_output.put_line('INSTANCE NAME: '||sys_context('userenv','instance_name'));
dbms_output.put_line('CDB NAME: '||sys_context('userenv','cdb_name'));
dbms_output.put_line('CONTAINER NAME: '||sys_context('userenv','con_name'));
dbms_output.put_line('DATABASE ROLE: '||sys_context('userenv','database_role'));
dbms_output.put_line('OS USER: '||sys_context('userenv','os_user'));
dbms_output.put_line('CLIENT IP ADDRESS: '||sys_context('userenv','ip_address'));
dbms_output.put_line('SERVER HOSTNAME: '||sys_context('userenv','server_host'));
dbms_output.put_line('CLIENT HOSTNAME: '||sys_context('userenv','host'));
end;
/
Shortcut to get the name of the current container is:
SQL> show con_name CON_NAME ------------------------------ PDB1
You may find that useful in a multitenant environment with many Pluggable Databases within one Container Database 🙂
ADO Storage Tiering with customized function: Example
An exciting feature of 12c is Automatic Data Optimization (ADO). It can automate Compression Tiering and Storage Tiering. The documentation mentions that Storage Tiering can be based on a customized function, but there is no example for it. Therefore this posting.
[oracle@uhesse ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.1.0 Production on Mon Dec 9 10:33:17 2013
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> grant dba to adam identified by adam;
Grant succeeded.
SQL> connect adam/adam
Connected.
SQL> create tablespace tbs1 datafile '/home/oracle/prima/tbs1.dbf' size 10m;
Tablespace created.
SQL> create tablespace tbs2 datafile '/home/oracle/prima/tbs2.dbf' size 10m;
Tablespace created.
SQL> create table t (n number) partition by range (n)
(partition p values less than (2) tablespace tbs1);
Table created.
Nothing special so far, just two tablespaces and a partitioned table. My customized ADO policy is very simple and uses a working table:
SQL> create table adoflag (n number); Table created.
SQL> insert into t values (1); 1 row created. SQL> commit; Commit complete. SQL> insert into adoflag values (0); 1 row created. SQL> commit; Commit complete. SQL> create or replace function adofunc (object_number in number) return boolean as v_n number; begin select n into v_n from adoflag; if (v_n=1) then return true; else return false; end if; end; / Function created.
Now that function is attached to an ADO policy that is placed on the partition p – notice that Storage Tiering policies can be on the segment level only:
SQL> alter table t modify partition p ilm add policy tier to tbs2 on adofunc; Table altered. SQL> col policy_name for a10 SQL> select policy_name,enabled from dba_ilmpolicies; POLICY_NAM ENABLE ---------- ------ P1 YES
The name of the policy is provided automatically. ADO Tiering requires the following initialization parameter setting, regardless that the customized policy is not based on access respectively modification frequency of the partition p:
SQL> alter system set heat_map=on; System altered.
Attention: Setting this already means you need the Advanced Compression Option! And to me it seems funny that this parameter can be modified on the session level, but that’s how it is. I want to cause now the Storage Tiering, so I update the flag to 1, but that would lead to automatic action only when the next Auto Task maintenance window opens. Therefore I trigger the ADO Tiering manually.
SQL> update adoflag set n=1;
1 row updated.
SQL> commit;
Commit complete.
SQL> select tablespace_name from user_tab_partitions where table_name='T';
TABLESPACE_NAME
------------------------------
TBS1
SQL> declare
v_executionid number;
begin
dbms_ilm.execute_ilm (ilm_scope=>dbms_ilm.scope_schema,
execution_mode=>dbms_ilm.ilm_execution_offline,
task_id=>v_executionid);
end;
/
PL/SQL procedure successfully completed.
SQL> select task_id,policy_name,selected_for_execution from dba_ilmevaluationdetails;
TASK_ID POLICY_NAM SELECTED_FOR_EXECUTION
---------- ---------- ------------------------------------------
7 P1 SELECTED FOR EXECUTION
SQL> select tablespace_name from user_tab_partitions where table_name='T';
TABLESPACE_NAME
------------------------------
TBS2
It is possible to add a Storage Tiering policy to a non-partitioned table, but that is probably not a good idea. My observation at least with the current 12.1.0.1 is that open transactions on the non-partitioned table will cause the Storage Tiering to fail silently. Usually, the Storage Tiering will be a unique action on the segment. For testing purposes, though, you may want to trigger it multiple times. But the policy gets silently disabled after the first tiering although dba_ilmpolicies shows it as enabled:
SQL> select policy_name,enabled from dba_ilmpolicies;
POLICY_NAM ENABLE
---------- ------
P1 YES
SQL> alter table t move partition p tablespace tbs1 online;
Table altered.
SQL> declare
v_executionid number;
begin
dbms_ilm.execute_ilm (ilm_scope=>dbms_ilm.scope_schema,
execution_mode=>dbms_ilm.ilm_execution_offline,
task_id=>v_executionid);
end;
/
PL/SQL procedure successfully completed.
SQL> select tablespace_name from user_tab_partitions where table_name='T';
TABLESPACE_NAME
------------------------------
TBS1
SQL> select task_id,policy_name,selected_for_execution from dba_ilmevaluationdetails;
TASK_ID POLICY_NAM SELECTED_FOR_EXECUTION
---------- ---------- ------------------------------------------
44 P1 POLICY DISABLED
7 P1 SELECTED FOR EXECUTION
SQL> alter table t modify partition p ilm enable_all;
Table altered.
SQL> declare
v_executionid number;
begin
dbms_ilm.execute_ilm (ilm_scope=>dbms_ilm.scope_schema,
execution_mode=>dbms_ilm.ilm_execution_offline,
task_id=>v_executionid);
end;
/
PL/SQL procedure successfully completed.
SQL> select tablespace_name from user_tab_partitions where table_name='T';
TABLESPACE_NAME
------------------------------
TBS2
SQL> select task_id,policy_name,selected_for_execution from dba_ilmevaluationdetails;
TASK_ID POLICY_NAM SELECTED_FOR_EXECUTION
---------- ---------- ------------------------------------------
45 P1 SELECTED FOR EXECUTION
44 P1 POLICY DISABLED
7 P1 SELECTED FOR EXECUTION
I hope this helps to get an understanding of customized ADO policy functions and to stay clear of some of the pitfalls associated with that topic. As always: Don’t believe it, test it! 🙂
