Dienstag, 26. Juni 2018

when it runs on your computer ...

... please don't see it ready for customers.

I try to enable Database Vault on an existing 12.2 database.
A proper document to follow is How To Enable Database Vault in a 12c database ? (Doc ID 2112167.1)

At some point it tells to run
@$ORACLE_HOME/rdbms/admin/catmac.sql system temp <system_password>

unfortunately this fails with
CREATE USER dvsys IDENTIFIED BY "D_DVSYSPW"
*
ERROR at line 1:
ORA-28003: password verification for the specified password failed
ORA-20025: Password must contain at least 1 digit(s)
(you need to spool the results into a file to find it in the output stream)

The reason is obvious:
SQL> select * from dba_profiles where resource_name='PASSWORD_VERIFY_FUNCTION' and Profile='DEFAULT';

PROFILE                        RESOURCE_NAME                    RESOURCE LIMIT                                    COM
------------------------------ -------------------------------- -------- ---------------------------------------- ---
DEFAULT                        PASSWORD_VERIFY_FUNCTION         PASSWORD ORA12C_VERIFY_FUNCTION                   NO

and so is the solution:
alter profile default limit PASSWORD_VERIFY_FUNCTION null;
@$ORACLE_HOME/rdbms/admin/catmac.sql system temp <system_password>
alter profile default limit PASSWORD_VERIFY_FUNCTION ORA12C_VERIFY_FUNCTION;


Oracle requires to disable a security feature to enable another one.
In this sandbox environment it's not a specific, hand-made password verify function. It's the default one from oracle.
It would be very nice if oracle would test it's security features to run with each other.

There is no problem for me, but I'm wondering how serious (holistic) Oracle takes "security"?

Mittwoch, 20. Juni 2018

preupgrade.jar version number

Mike Dietrich is very motivated to convince everyone who wants to take Oracle database upgrades serious to use always the latest version of preupgrade.jar.

Some parts of Note:884522.1 - How to Download and Run Oracle's Database Pre-Upgrade Utility
 are misleading in my point of view:
If the upgrade-to version is 12.2 or higher, then save the file to your target $ORACLE_HOME/rdbms/admin directory and then unzip the file. It could be your source or target $ORACLE_HOME.
but this will be sorted out for sure in the new future.

For me deploying some files to an ORACLE_HOME (after it's own well defined deployment process) sounds creepy, and I'm interested how this will fit into the concept of read-only ORACLE_HOMEs in 18c+.

As I don't want to modify anything (even replacing with the identical files in case latest preupgrades.jar is deployed already) it's better to check the version of current preupgrade.jar.

If it is used already, the Build number is visible in
preupgrade.log:
Report generated by Oracle Database Pre-Upgrade Information Tool Version
12.2.0.1.0 Build: 14

Upgrade-To version: 12.2.0.1.0

=======================================
Status of the database prior to upgrade
=======================================
...

But if it is not executed (yet), you have to get the Build number from the jar file.
At the moment (Build 014) you can get it from preupgrade_package.sql by a simple statement:

unzip -p $PATH_TO_PREUPGRADE/preupgrade.jar preupgrade_package.sql | \
awk '$1 ~ /c_build/ { print $5 }' | tr -d \;

This can help to identify the current installation and if a (re-)installation is really required.



unfortunately there are some inconsistencies.
e.g. in preupgrade_181_cbuild_2_lf.zip:
if you unzip this file you will get a preupgrade_package.sql with c_build is 2
but the preupgrade_package.sql inside of preupgrade.jar shows c_build is 1

Mittwoch, 30. Mai 2018

flipping performance

Recently I had a request to check "if there is any problem with the database at <specific times>".
You can imagine, there was no problem. Nothing in alert.log, no tracefiles, no locks or oddities in ASH/AWR.

I had to ask back & forth to get some more information about the issue. The information I got was:
"we use a statement SELECT * FROM table(some_function('P1', 'P2')) - and it took longer than 10 sec at the given times". Of course there were no bind variables used but constants every time.
This situation helps a lot as obviously there is nothing to do with SQL_IDs now, and the real issue is (probably) within the function.
The function just generated 1 SELECT (no BINDs again - but PL/SQL did the "auto-binding").
With this SQL it's easy to identify the SQL_ID.
This SQL_ID has 3 childs with different plans. That is sufficient to check, if the specific times somehow match a flip of plans. This was done by a simle query:

with gash as (
select sql_id, sql_child_number, sample_time, LAG(sql_child_number, 1, 0) OVER (ORDER BY sample_time) AS prev_child
from gv$active_session_history
where sql_id='&sql_id'
order by sample_time
)
select *
from gash
where sql_child_number != prev_child
order by sample_time

For a longer observation dba_hist_active_sess_history can be used as well.

The result easily showed a flip between childs/plans at the given times.

(solution was to generate "outline-hints" with dbms_xplan.display_cursor for the good plan and so hint the SQL inside of some_function).

This was no complex task to analyze or big deal to execute. Just a small example where GUIs might not help so much. By the (little) information given it would have been pure luck to see the problematic pattern in a ASH-graph. As ther was nothing to filter, all the other "noise" in the DB would have wiped the information out.

Sometimes it's good to know the architecture and views, not only the GUI.

PS: The statement above is ugly. A MATCH_RECOGNIZE would be more elegant. Unfortunately this DB is 11.2

Montag, 28. Mai 2018

enabling Database Vault is complicated

Enabling Database Vault in a already running system can be laborious.

I recently tried to enable DV in a (copy of a ) production Oracle EBS DB.
The Documentation is pretty lear and easy:
https://docs.oracle.com/database/121/DVADM/getting_started.htm#DVADM002
But I fail at

BEGIN 
DVSYS.CONFIGURE_DV ( 
dvowner_uname => 'DBV_OWNER', 
dvacctmgr_uname => 'DBV_ACCTMGR'); 
END; 
/ 
with
ERROR at line 1: 
ORA-47500: Database Vault cannot be configured. 
ORA-06512: at "DVSYS.CONFIGURE_DV", line 23 
ORA-06512: at "DVSYS.CONFIGURE_DV", line 72 
ORA-06512: at line 2 
That's not very helpful and ORA-47500 suggests:
If this happens, deinstall and then reinstall Oracle Database Vault
Even after removal and re-installation, the symptoms still stay.

The problem here are some invalid objects in the database!

As it's unclear to my which objects are the problem, I asked Oracle.
Unfortunately the answer is not helping a lot:

It is possible that not all [objects] need to be valid before you can configure DV successfully but you definitely need to work on fixing these invalid object at this point because that is the reason for the error.
If this happens, deinstall and then reinstall Oracle Database Vault.

Of course the suggestion doesn't help, utlrp did not change anything.
As all the invalid objects doesn't belong to the DBA but some developed code, it will take some time until DV is enabled.

I don't have any solution right now than laborious wading through all invalid objects and fixing them. 

Montag, 30. April 2018

Tracing the Database Configuration Assistant

I am struggling with DBCA right now so a little tracing is advised.
Note Tracing the Database Configuration Assistant (DBCA) (Doc ID 188134.1) gives a nice suggestion to add these parameters:
-DTRACING.ENABLED=true -DTRACING.LEVEL=2
but it's no elegant solution to edit the shell script in $ORACLE_HOME/bin/dbca

I prefer my new swiss knife for java parameters. A simple environment variable:
_JAVA_OPTIONS= -DTRACING.ENABLED=true -DTRACING.LEVEL=3
This is very useful for any java program. As Oracle has many such programs, there is often use for _JAVA_OPTIONS

Sonntag, 1. April 2018

more fun with ages


On-call duties sometimes leads to interesting results.
I have to observe a restore running (or to be more precise wait for a tape library to find the right tapes and put them into drives.
This gives me time to catch up my news aggregator. And some time to play with interesting news.
One interesting post I stumbled across is

Franck Pachos After IoT, IoP makes its way to the database
There he mentions a new, yet undocumented function to_dog_year().
As I had some fun with ages in general, this promises to be even more entertainment!

If I had a dog with equivalent age then I'm old, what's it's birthday?
It's simple now:
SQL> alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';

select BX_YEAR_CALC.ADDITION(sysdate,   
         -1 * to_dog_year(BX_YEAR_CALC.DIFFERENCE(:MY_BIRTHDAY))) 
                                                as dogs_birthdate 
from dual;

DOGS_BIRTHDATE     
-------------------
2012-09-26 03:27:18

(I don't care about breed or this other parameter as it's only a hypothetical dog in my case).


As the library is still shuffling tapes I was guessing about the origin of this function.
Francks idea of Internet of Pets makes some sense to me, but such a very specific function?
I know stories about Oracle providing special versions of it's database to important customers. But that was back in something like Version 5 or 6 (long before my time) and more dedicated to performance issues of any kind. But maybe this is the case here also.
IF this important customer is doing any business with a huge amount of dogs and needs to calculate their "Age" all over the application, it might make sense to ask Oracle to code it in the core of the database. To have custom functions is very uncommon for me, but maybe we will see the next big thing soon, and Oracle tries to gain it's market share there?



Restore is done, but recovery takes it's time! I'm sure archivelogs are spread cross many tapes. This gave me time to do some (very simple!) performance tests with to_dog_year. It seems to be very easy to calculate  the "age" of a puppy, but this gets more expensive rapidly. At the input of 2 (or somewhere around - I increased input by 0.5) the complexity seems to drop and the effort increases only slightly.
It would be interesting to see the real formula, if it will ever get published, but at the input of 2 it seems to flip from a "calculation for young dogs" to "calculation for adult dogs".
If it's really for something like tracking dogs, I hope they (whoever they are) have a good capacity planning: I assume customers with young dogs will be more interested to join the service (whatever it will be) which makes the computation requirements slightly higher than average.

Anyhow, future will tell.
As the restore finished, I'll continue the night with better things to do...


Update:
If you are interested in more details about to_dog_year(), before you invest any effort there, please check date and time when this post was published.
I hope you liked it as much as we did.

Samstag, 31. März 2018

spfile parameters derived from cpu_count

In Oracle databases some spfile parameters are derived based on others, if they are not set explicit.
One of the main drivers I discovered is CPU_COUNT.
So I did some tests based in the past for version 11.1.0.7 and 12.1.0.2.
To simulate a machine with sufficient CPUs, I had to use a trick described in a previous post. Using _disable_cpu_check threw an ORA-7445:[ksucre] in 12.2 with cpu_count >126.

the script I used this time is basically (of course with 180 instead of 122 for 18.0).
#!/usr/bin/ksh  -x

integer i=1
while ((i <= 255));
do
  print " $i ";

  echo "*.audit_file_dest='/_some_dir_/BX1/adump'
*.audit_trail='db'
*.compatible='12.2.0.1.0'
*.control_files='/_some_dir_/BX1/controlfile/o1_mf_djd017z2_.ctl', '/_some_dir_/fast_recovery_area/BX1/BX1/controlfile/o1_mf_djd01834_.ctl'
*.db_block_size=8192
*.db_create_file_dest='/_some_dir_/oradata'
*.db_name='BX1'
*.db_recovery_file_dest='/_some_dir_/fast_recovery_area/BX1'
*.db_recovery_file_dest_size=7G
*.db_unique_name='BX1'
*.diagnostic_dest='/appl/oracle'
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=7g
*.undo_tablespace='UNDOTBS1'
*.max_string_size='EXTENDED'
#*._disable_cpu_check='TRUE'
*.cpu_count=$i" > /_some_dir_/cpus/initBX1_$i.ora

  echo "shutdown abort;
startup pfile='/_some_dir_/cpus/initBX1_$i.ora' ;

insert into init_parameters
select '12.2'     ,
       $i         ,
       a.ksppinm  ,
       b.ksppstvl ,
       c.ksppstvl
from x\$ksppi a, x\$ksppcv b, x\$ksppsv c
where a.indx = b.indx and a.indx = c.indx;

commit;

select distinct(\"CPUs\") from init_parameters;

shutdown;
exit;"> cpus/122doit$i.sql

sqlplus "/ as sysdba" @cpus/122doit$i.sql >cpus/122log$i.log

sleep 5

  (( i = i + 1));
done


11.1.0.712.1.0.212.2.0.118.0.0.0
_cursor_db_buffers_pinnedxxxx
_db_block_buffers xxxx
_db_block_lru_latches xxxx
__db_cache_sizexxxx
_db_file_exec_read_count xx
db_file_multiblock_read_countxx
_db_handlesxxx
db_writer_processesxxxx
dml_locksxxx
_enqueue_hashxxx
_enqueue_hash_chain_latchesxxxx
_enqueue_locksxxxx
_enqueue_resourcesxxx
_flashback_generation_buffer_sizexxxx
_gc_fast_index_split_waitx
_gcs_min_cr_slavesxx
_kghdsidx_countxx

_hang_resolution_scopexx
_ksmsq_hintmaxprocx
__large_pool_sizexxx
_lms_rollbacksxx
log_bufferxxxx
_log_parallelism_maxxxxx
_log_simultaneous_copiesxxxx
_max_log_write_parallelismxx
_max_outstanding_log_writesxxx
_max_pending_scn_bcastsxxx
_messagesxxx
_num_longop_child_latchesxxxx
_num_rlslavesxx
parallel_max_serversxxxx
_parallel_min_message_poolxxxx
parallel_min_serversxxx
parallel_servers_targetxxx
pga_aggregate_limitxxx
_pmon_max_slavesxx
_pmon_slaves_arr_sizexx
processesxxx
_px_proactive_slave_alloc_thresholdxxx
_session_allocation_latchesxxx
sessionsxxx
sga_max_sizexx
shared_pool_reserved_sizexxx
__shared_pool_sizexxxx
_shared_server_num_queuesxxxx
_small_table_thresholdxxxx
_spin_count xxxx
_sqlmon_max_plan
xxx
_super_shared_conversion_threshold
xx
transactions xxx
_use_single_log_writer xxx

To get a good picture of the changes, feel free to select parameters, versions or whatever you want below.
Raw data is available at GistHub.
The js app is available here.
(It's based on an idea PerfSheet.js by Luca Canali.

As some of the values are not numbers, I applied this mapping:
TRUE1
FALSE0
OFF0
ADAPTIVE -1
INSTANCE -2