15 February 2013

Views, Datatypes and Nulls

Had an interesting little case come up today when helping a client re-write a view. This legacy application stored a date value as January 1, 1970 when they didn't have a date (basically using it as a de facto NULL). I did my best to lecture the client on why this was a horrible idea, but there was nothing we could do in the short term.

Anyway, he had a view that would use a DECODE function to convert a date of 1970/01/01 to NULL, otherwise just pass the date through. However, we noticed that the view schema said the field was defined as varchar2(18) instead of date. Here is my example using a view on DBA_OBJECTS:


SQL> create or replace view test_objects1 (object_name, created) as
  2  select object_name, decode (created
  3                          , to_date('1970/01/01','yyyy/mm/dd')
  4                          , null, created)
  5  from dba_objects;

View created.

SQL>
SQL> desc test_objects1;
 Name                                      Null?    Type
 ----------------------------------------- -------- -------------
 OBJECT_NAME                                        VARCHAR2(128)
 CREATED                                            VARCHAR2(18)

I suggested we wrap that NULL in a to_date function just to see what happens, and sure enough that gives us what we want:

SQL> create or replace view test_objects2 (object_name, created) as
  2  select object_name, decode (created
  3                          , to_date('1970/01/01','yyyy/mm/dd')
  4                          , to_date(null), created)
  5  from dba_objects;

View created.

SQL>
SQL> desc test_objects2;
 Name                                      Null?    Type
 ----------------------------------------- -------- -------------
 OBJECT_NAME                                        VARCHAR2(128)
 CREATED                                            DATE

It seems silly to wrap NULL in a TO_DATE, or do any function on a NULL value. One would hope that Oracle sees the NULL and short-circuits the function to avoid doing the unnecessary work.

Update: Looks like this is documented functionality in the DECODE function:
Oracle automatically converts expr and each search value to the datatype of the first search value before comparing. Oracle automatically converts the return value to the same datatype as the first result. If the first result has the datatype CHAR or if the first result is null, then Oracle converts the return value to the datatype VARCHAR2.

Update #2: Thanks to Sayan in the comments for tipping me off about NULLIF, which seems like the best option, doing exactly what we want without having to convert the type:

 SQL> create or replace view test_objects3 (object_name, created) as
  2  select object_name
  3          , nullif (created
  4                      , to_date('1970/01/01','yyyy/mm/dd'))
  5  from dba_objects;

View created.

SQL>
SQL> desc test_objects3;
 Name                                      Null?    Type
 ----------------------------------------- -------- -------------
 OBJECT_NAME                                        VARCHAR2(128)
 CREATED                                            DATE

02 February 2013

Learning to Love the ADR - Part 4: Incident Packaging Service

This post is the fourth (and final) in a short series about Oracle 11g ADR. These posts are based on the presentations I gave at the NoCOUG Summer Conference in August 2011 and at the RMOUG Training Days in February 2012.


IPS


Any DBA that has had to file a support request with Oracle Support will be violently nodding their head in agreement when I ask if they've ever had Oracle Support ask for log file after trace file after log file after trace file. It's hard to not be cynical, especially when they sometimes request a file that was already provided! In 11g, Oracle has made some of that work easier by providing the Incident Packaging Service, or IPS, with the ADR. IPS lets you quickly and easily gather up diagnostic files related to a given incident, problem, or timeframe. You can also create empty packages and add whatever files you see fit.

It all starts with the IPS CREATE PACKAGE command. This creates a logical package (no package files are created at this point) in the ADR. Various options include:


  • adrci> ips create package incident <incident_id>;
  • adrci> ips create package problem <problem_id>;
  • adrci> ips create package problemkey "problem_key_string";
  • adrci> ips create package seconds <seconds_before_now>;
  • adrci> ips create package time 'start_timestamp' to 'end_timestamp';
  • adrci> ips create package;

It is definitely worth your while to review the output of help ips create package to get details on these, as I won't be touching most of them any further. The last command listed creates an empty package, after which you can use the ips add incident or ips add file commands to add data to the package before generating it.

30 January 2013

Learning to Love the ADR - Part 3: Purging (Out With The Old)


This post is the third in a short series about Oracle 11g ADR. These posts are based on the presentations I gave at the NoCOUG Summer Conference in August 2011 and at the RMOUG Training Days in February 2012.

One of the benefits of the new ADR system is the automatic file maintenance (archiving and cleanup) that I mentioned earlier. Depending on the type of file it is, XML log and trace file maintenance is governed by either the long or short purge policy. The values of these policies can be observed from the ADRCI command "show control", e.g.:


adrci> show control

ADR Home = /home/oracle/app/oracle/diag/rdbms/orcl/orcl:
*************************************************************************
ADRID                SHORTP_POLICY        LONGP_POLICY         LAST_MOD_TIME                            LAST_AUTOPRG_TIME                        LAST_MANUPRG_TIME                        ADRDIR_VERSION       ADRSCHM_VERSION      ADRSCHMV_SUMMARY     ADRALERT_VERSION     CREATE_TIME
-------------------- -------------------- -------------------- ---------------------------------------- ---------------------------------------- ---------------------------------------- -------------------- -------------------- -------------------- -------------------- ----------------------------------------
1335663986           720                  8760                 2012-03-28 09:46:07.813608 -05:00        2012-09-18 22:19:08.939553 -05:00                                                 1                    2                    80                   1                    2012-03-28 09:46:07.813608 -05:00


I've highlighted the column names and values in red. It doesn't format very well in the terminal either.

Let's break it down.

29 January 2013

Learning to Love the ADR - Part 2: Diagnostic Files and ADRCI

This post is the second in a short series about Oracle 11g ADR. These posts are based on the presentations I gave at the NoCOUG Summer Conference in August 2011 and at the RMOUG Training Days in February 2012.

Wherever the DIAGNOSTIC_DEST is (remember that the default is the $ORACLE_BASE value), Oracle will create a "diag" directory underneath it. Under this you'll find directories based on instance type, for example "rdbms" or "asm" or "tnslsnr". Dig deeper to find directories per database/instance and then the alert, trace, incident, etc. files. What is new with the ADR is the use of XML files for the alert log, as "log.xml" in the "alert" directory. The human-readable alert_XXX.log that you're used to is now in the "trace" directory. One important distinction is that the XML files are maintained by Oracle, archived once they reach 10Mb in size and purged based on policy settings that you can define. The trace files, just as with previous versions, require you to set up some sort of regular rotation/archiving/purging to prevent them from growing out of control. There are other advantages to the XML files, as we'll see in future posts.

SO. MANY. FILES.

Another not-so-fun surprise for those upgrading to Oracle 11g is that the new version generates a LOT more trace data than before. If you monitor those directories for size, your thresholds are likely to be blown away. Some of this was tamed in 11gR2, thankfully. One way to help cut back on some of trace (trc/trm suffixes) file generation is to set the hidden parameter _disable_health_check to TRUE. As with any hidden/underscore parameter, do NOT set this without approval from Oracle support (at least not in production). Another way which is easier, is to run regular PURGE jobs via adrci, which we will get to in another post.

Problems and Incidents

Oracle and the ADR nicely track problems and incidents. It is important to note that they are not one and the same. Problems are critical errors in the database (eg ORA-00600, 07445, 04031, etc). An incident is a single occurrence of a problem. When an incident occurs, Oracle creates incident trace files in addition to the normal alert log message and error trace file. You'll see this noted after the "Incident details in:" line in the alert log. For example:

Incident details in: /home/oracle/app/oracle/diag/rdbms/orcl/orcl/incident/incdir_12201/orcl_ora_18457_i12201.trc


However, there is a smarter way to look for incidents and alerts than scraping the human-readable alert log like some kind of animal. We'll use the ADRCI.

26 October 2012

Learning to Love the ADR - Part 1: Location, Location, Location!

This post is the first in a short series about Oracle 11g ADR. These posts are based on the presentations I gave at the NoCOUG Summer Conference in August 2011 and at the RMOUG Training Days in February 2012.

The Automatic Diagnostic Repository, or "ADR", is a location on disk where an Oracle instance keeps many files of diagnostic data that tools like Enterprise Manager or ADR Command Interpreter (adrci) use for gathering and presenting information to the user. When we refer to diagnostic files, we are talking about:
  • Alert logs (RDBMS instance, ASM instance, Listener)
  • Trace files (e.g. 10046 or 10053 as well as system-generated)
  • Core dumps
Now in prior versions of Oracle, you would expect to find these files under $ORACLE_BASE/admin/$ORACLE_SID in bdump, cdump or udump, by default. You could always specify different locations with the %_DUMP_DEST initialization parameters, of course. The log files would grow ad infinitum if not properly rotated, compressed, archived and/or truncated, possibly causing some headaches with disk space management.

As of Oracle 11g, however, much (but not all) of this is managed by the instance now. As an added bonus, Oracle moved the locations of these files, as I'm sure many of you with alert log monitoring software have found out by now. The thing that catches most DBAs off-guard when upgrading to 11g is the change in location for these files, especially the alert log.

16 February 2012

Me at RMOUG

Here's a quick picture of me during my RMOUG 2012 presentation, giving a tour of the Oracle 11g ADR:

Thanks to Kellyn Pot'Vin for the picture!

15 February 2012

A NoCOUG to Remember

This post is long overdue, as I was supposed to blog about my appearance at NoCOUG before I left (sorry, Vanessa!). However in my efforts to rehearse and adjust my presentation, blogging about it just fell to the wayside. However now that NoCOUG 2011 Summer Conference is in the books, I'd like to take a few minutes to share my experience not only as an attendee, but also as a first-time speaker.

When I found out that NoCOUG had accepted my abstract, "Oracle 11g: Learning to Love the ADR", I was both ecstatic and terrified. This meant that I actually had to prepare the presentation and speak in front of peers. Surely they would throw me into San Francisco Bay if I didn't bring my A-game, so I set out to do just that.