h1

bug 8525592 – SGA memory leak during db shutdown

June 25, 2009

10 days ago I posted regarding informational messages in trace files and how they seem to have increased with the advent of 11G. See http://jhdba.wordpress.com/2009/06/16/informational-trace-files-in-11g/

I referred to 3 messages, one of which I said I was going to raise a SR against. The trace file contained the line  “Updating SGAs in kzam_check_limit”
and the full trace showed

 Updating SGAs in kzam_check_limit
No rows for property:16, trail_type:12
Resetting MaxSize to default values for OS audit files
Resetting MaxSize to default values for XML audit files
No rows for property:17, trail_type:12
Resetting MaxAge to default values for OS audit files
Resetting MaxAge to default values for XML audit files
No rows for property:24, trail_type:15

The feedback from Oracle was that this was unpublished bug  8525592 – SGA MEMORY LEAK ERROR DURING THE DB SHUTDOWN and that there was no cause for concern.

Now this was appearing on an 11.1.0.7 database on HPUX Itanium and it is the only instance out of around 25 where it is appearing. Co-incidentally we have a  memory leak on that server and we have an ongoing SR open with Oracle. I have alerted my colleague who owns that SR and he will talk to Oracle and see if there is any match between the two issues.

In the meantime I have been able to get a bit more information on what bug 8525592 is about. Apparently it is not a serious issue and isn’t really a memory leak.  It’s to do freeing up shared pool when there are multiple subpools.  If there are child/parent handles split between subpools, it’s possible for the parent one not to be cleared properly.  In normal operation there’s a houskeeping routine that SMON does periodically that sorts this out but if the database is shutdown before that runs, it looks like a memory leak.  It’s only in 11.1.0.x and is not considered serious. Bug 8525592 leads me to bug 8586531 and base bug 7453413

h1

informational trace files in 11g

June 16, 2009

Since Oracle 11G there seems to be many more informational trace files generated than ever before. Perhaps I am noticing more but I will provide three examples in support of what I am saying.

kcrroda: calling ksfdrcres to create AL or RL

Just a warning but it is due to a bug in 11.1.0.6 (still not fixed in 11.1.0.7) that causes diagnostic warnings to be issued after an archivelog switch. Bug 6910132 for anyone who is interested

From the same database I see trace files with the following lines in

Updating SGAs in kzam_check_limit
No rows for property:16, trail_type:12
Resetting MaxSize to default values for OS audit files
Resetting MaxSize to default values for XML audit files
No rows for property:17, trail_type:12
Resetting MaxAge to default values for OS audit files
Resetting MaxAge to default values for XML audit files
No rows for property:24, trail_type:15

I cannot find any information on this at all but I do suspect that it is another diagnostic setting that has been left enabled within the code
I will raise an SR on this matter but I don’t think it is anything for me to be worried by

From another database (again 11.1.0.7) I see numerous trace files containing the line

qerfxGCol:KQFDTTIM – Error converting to LdiDateArray

Metalink note 577674.1 shows that it is yet another trace output than can be ignored
Applies to:
Oracle Server – Enterprise Edition – Version: 11.1.0.6
This problem can occur on any platform.

Symptoms
After upgraded to 11.1.0.6.0 or created a new database on this version, you noticed following repetitively message at MMON process trace:

“qerfxGCol:KQFDTTIM – Error converting to LdiDateArray”

There is no further errors at alert log.

Changes
Upgraded to 11.1.0.6.0.

Cause
This issue has been introduced in 11gR1 11.1.0.6.0 with the new view v$persistent_queues, where a ’select * from v$persistent_queues;’ reproduces the error when there is a ‘null’ value for one of timestamp
columns in that view. This behavior does *not* cause any data loss; performance impact nor any effect for use of ADDM/AWR tools.

This issue has been reported on following bugs:

Bug 6780602 – TRACEFILES WITH ‘QERFXGCOL:KQFDTTIM – ERROR CONVERTING TO LDIDATEARRAY’
Bug 6921602 – QERFXGCOL:KQFDTTIM – ERROR CONVERTING TO LDIDATEARRAY

Solution
It has been fixed in 11.2.

h1

HPUX_SCHED_NOAGE parameter, improve OLTP throughput

May 27, 2009

Sometimes it is easy to miss the simple stuff and I must admit that although I have managed Oracle on HPUX over many years I have not in the last few years (mostly Solaris and Linux).
Having started work at a solely HP site in the last year I never bothered to read the Installation guide as a tried and tested set of practise were in place.

Recently we were having problems with a Peoplesoft database and we went the whole hog in re-striping disk and re-evaluating everything. A HP specialist mentioned the init.ora parameter HPUX_SCHED_NOAGE which I had not come across before. On investigation the parameter was in place on our 10.2.0.3 databases but set to 0. Looking at some 11g databases I was surprised to see that it had been set also but with the recommended value of 178. Obviously it is now enabled by default on 11g on HPUX

So what does it do. Well in a non Unix specialist way I can describe it as ensuring that all the database processes run at the same priority and therefore do not get aged out as new processes come along and look for resource. Older processes are more likely to stay on the CPU which results in less context switching. On a busy system it is likely that the lgwr process will perform better as it gets more time on the CPU and is not switched out as often to make way for a process that is waiting in the normal time-share manner. It is not expected that gains will be seen in OLTP systems rather than DSS systems as there will be more process competing for resource than in a DSS system where fewer longer running processes will be the norm.

Whilst writing this up I came across I came across a blog that describes it all in a much more technical manner than I can, complete with diagrams Christian Bilien

Metalink note 217990.1 (Mar 2009) states This could be suited to online transaction processing (OLTP) environments because OLTP environments can cause competition for critical resources. Overall performance improvements of 5 to 10% for OLTP applications.

If the parameter setting is out of range, Oracle sets the parameter to a permissible value and continues with the SCHED_NOAGE policy with the new value.

It also generates a message in the alert_sid.log file about the new setting. Oracle Corporation recommends that you set the parameter to the required priority level for Oracle processes.

The Oracle manual also shows you how to set the unix pre-reqs for the HPUX_SCHED_NOAGE init.ora parameter to work

To permit Oracle Database to use the SCHED_NOAGE scheduling policy, the OSDBA group (typically, the dba group) must have the RTSCHED and RTPRIO privileges to change the scheduling policy and set the priority level for Oracle processes. To give the dba group these privileges:

1. Log in as the root user.

2. Using any text editor, open the /etc/privgroup file, or create it if necessary.

3. Add or edit the following line, which begins with the name of the OSDBA group, specifying the privileges RTPRIO and RTSCHED that you want to grant to this group every time the system restarts:

4. Save the file, and quit the text editor.

5. Enter the following command to grant the privileges to the OSDBA group:
# /usr/sbin/setprivgrp -f /etc/privgroup

Enter the following command to verify that the privileges are set correctly:

# /usr/sbin/getprivgrp dba

So did it make any difference to us. I can only give an example of how it helped a specific problem for us. On a   Peoplesoft HR system we made 2 changes, bad practise I know but time constraints forced it upon us. We added the scheduling parameter and also reduced the filecache_min and filecache_max kernel parameters from 3%,5 % to 1%,2%. These parameters control the amount of physical memory used for caching file I/O data and we were tight on memory anyway. On a specific time and labour batch processing benchmark we saw an immediate improvement of 12% which was very acceptable.

PS to show the process in Glance use ’s’ then select any PID associated with the database and note in the left hand column that scheduler=NOAGE and Priority=178

HP_SCHED_NOAGE

h1

Purging statistics from the SYSAUX tablespace

May 19, 2009

Whenever statistics in the dictionary are modified, old versions of statistics are saved automatically for future restoring. The old statistics are purged automatically at regular intervals based on the statistics history retention setting and the time of recent statistics gathering performed in the system. Retention is configurable using the ALTER_STATS_HISTORY_RETENTION procedure. The default value is 31 days.
That is normally not too big an issue but in our Peoplesoft environments we run a lot of gather_stats jobs and if the retention period is not managed then the SYSAUX tablespaces can grow very large. In one of our systems the SYSAUX tablespace was 37Gb with over 32Gb consisting of the stats tables and assoc iated indexes. This blog entry will provide the scripts to diagnose and correct excessive tablespace growth due to retained statistics

 set linesize 120
set pagesize 100

COLUMN "Item" FORMAT A25
COLUMN "Space Used (GB)" FORMAT 999.99
COLUMN "Schema" FORMAT A25
COLUMN "Move Procedure" FORMAT A40

SELECT	occupant_name "Item",
	space_usage_kbytes/1048576 "Space Used (GB)",
	schema_name "Schema",
	move_procedure "Move Procedure"
FROM v$sysaux_occupants
ORDER BY 1
/
Item                      Space Used (GB) Schema                    Move Procedure
------------------------- --------------- ------------------------- ----------------------------------------
AO                                    .00 SYS                       DBMS_AW.MOVE_AWMETA
EM                                    .08 SYSMAN                    emd_maintenance.move_em_tblspc
EM_MONITORING_USER                    .00 DBSNMP
EXPRESSION_FILTER                     .00 EXFSYS
JOB_SCHEDULER                         .00 SYS
LOGMNR                                .01 SYSTEM                    SYS.DBMS_LOGMNR_D.SET_TABLESPACE
LOGSTDBY                              .00 SYSTEM                    SYS.DBMS_LOGSTDBY.SET_TABLESPACE
ODM                                   .00 DMSYS                     MOVE_ODM
ORDIM                                 .00 ORDSYS
ORDIM/PLUGINS                         .00 ORDPLUGINS
ORDIM/SQLMM                           .00 SI_INFORMTN_SCHEMA
SDO                                   .00 MDSYS                     MDSYS.MOVE_SDO
SM/ADVISOR                            .02 SYS
SM/AWR                                .15 SYS
SM/OPTSTAT                          11.44 SYS
SM/OTHER                              .02 SYS
STATSPACK                             .00 PERFSTAT
STREAMS                               .00 SYS
TEXT                                  .00 CTXSYS                    DRI_MOVE_CTXSYS
TSM                                   .00 TSMSYS
ULTRASEARCH                           .00 WKSYS                     MOVE_WK
ULTRASEARCH_DEMO_USER                 .00 WK_TEST                   MOVE_WK
WM                                    .00 WMSYS                     DBMS_WM.move_proc
XDB                                   .00 XDB                       XDB.DBMS_XDB.MOVEXDB_TABLESPACE
XSAMD                                 .00 OLAPSYS                   DBMS_AMD.Move_OLAP_Catalog
XSOQHIST                              .00 SYS                       DBMS_XSOQ.OlapiMoveProc

How long old stats are kept

 select dbms_stats.get_stats_history_retention from dual;

Set retention of old stats to 10 days

 exec dbms_stats.alter_stats_history_retention(10);

Purge stats older than 10 days (best to do this in stages if there is a lot of data (sysdate-30,sydate-25 etc)

 exec DBMS_STATS.PURGE_STATS(SYSDATE-10);

Show available stats that have not been purged

 select dbms_stats.get_stats_history_availability from dual;

Show how big the tables are and rebuild after stats have been purged


col Mb form 9,999,999
col SEGMENT_NAME form a40
col SEGMENT_TYPE form a6
set lines 120
select sum(bytes/1024/1024) Mb, segment_name,segment_type from dba_segments
where  tablespace_name = 'SYSAUX'
and segment_name like 'WRI$_OPTSTAT%'
and segment_type='TABLE'
group by segment_name,segment_type order by 1 asc

        MB SEGMENT_NAME                             SEGMEN
---------- ---------------------------------------- ------
         0 WRI$_OPTSTAT_OPR                         TABLE
         0 WRI$_OPTSTAT_AUX_HISTORY                 TABLE
        88 WRI$_OPTSTAT_TAB_HISTORY                 TABLE
       126 WRI$_OPTSTAT_IND_HISTORY                 TABLE
       158 WRI$_OPTSTAT_HISTGRM_HISTORY             TABLE
     4,482 WRI$_OPTSTAT_HISTHEAD_HISTORY            TABLE

Show how big the indexes are ready for a rebuild after stats have been purged


col Mb form 9,999,999
col SEGMENT_NAME form a40
col SEGMENT_TYPE form a6
set lines 120
select sum(bytes/1024/1024) Mb, segment_name,segment_type from dba_segments
where  tablespace_name = 'SYSAUX'
and segment_name like '%OPT%'
and segment_type='INDEX'
group by segment_name,segment_type order by 1 asc
/

        MB SEGMENT_NAME                             SEGMEN
---------- ---------------------------------------- ------
         0 WRH$_OPTIMIZER_ENV_PK                    INDEX
         0 I_WRI$_OPTSTAT_OPR_STIME                 INDEX
         0 I_WRI$_OPTSTAT_AUX_ST                    INDEX
        88 I_WRI$_OPTSTAT_TAB_ST                    INDEX
       105 I_WRI$_OPTSTAT_IND_ST                    INDEX
       105 I_WRI$_OPTSTAT_H_ST                      INDEX
       195 I_WRI$_OPTSTAT_TAB_OBJ#_ST               INDEX
       213 I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST           INDEX
       214 I_WRI$_OPTSTAT_IND_OBJ#_ST               INDEX
     2,055 I_WRI$_OPTSTAT_HH_ST                     INDEX
     3,883 I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST            INDEX

Note that you cannot enable row movement and shrink the tables as the indexes are function based

 alter table WRI$_OPTSTAT_IND_HISTORY enable row movement;
alter table WRI$_OPTSTAT_IND_HISTORY shrink space;
*
ERROR at line 1:
ORA-10631: SHRINK clause should not be specified for this object
 select 'alter table '||segment_name||'  move tablespace SYSAUX;' from dba_segments where tablespace_name = 'SYSAUX'
and segment_name like '%OPT%' and segment_type='TABLE'

Run the rebuild table commands – note that this does cause any gather_stats jobs to fail

alter table WRI$_OPTSTAT_TAB_HISTORY  move tablespace sysaux;
alter table WRI$_OPTSTAT_IND_HISTORY  move tablespace sysaux;
alter table WRI$_OPTSTAT_HISTHEAD_HISTORY  move tablespace sysaux;
alter table WRI$_OPTSTAT_HISTGRM_HISTORY  move tablespace sysaux;
alter table WRI$_OPTSTAT_AUX_HISTORY  move tablespace sysaux;
alter table WRI$_OPTSTAT_OPR  move tablespace sysaux;
alter table WRH$_OPTIMIZER_ENV  move tablespace sysaux;

Script to generate rebuild statements

 select 'alter index '||segment_name||'  rebuild online parallel (degree 14);' from dba_segments where tablespace_name = 'SYSAUX'
and segment_name like '%OPT%' and segment_type='INDEX'

Once completed it is best to check that the indexes (indices) are usable

 select  di.index_name,di.index_type,di.status  from  dba_indexes di
where  di.tablespace_name = 'SYSAUX'
and di.index_name like '%OPT%'
order by 1 asc
/

SQL>
INDEX_NAME                     INDEX_TYPE                  STATUS
------------------------------ --------------------------- --------
I_WRI$_OPTSTAT_AUX_ST          FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST  FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_HH_ST           FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_H_ST            FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_IND_OBJ#_ST     FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_IND_ST          FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_OPR_STIME       FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_TAB_OBJ#_ST     FUNCTION-BASED NORMAL       VALID
I_WRI$_OPTSTAT_TAB_ST          FUNCTION-BASED NORMAL       VALID
WRH$_OPTIMIZER_ENV_PK          NORMAL                      VALID

Finally lets see what space has been saved with a retention date of 1 day and a gather schema stats for the SYSASDM schema

 exec dbms_stats.alter_stats_history_retention(1);
select dbms_stats.get_stats_history_retention from dual;

        MB SEGMENT_NAME                             SEGMEN
---------- ---------------------------------------- ------
         0 WRI$_OPTSTAT_OPR                         TABLE
         0 WRI$_OPTSTAT_AUX_HISTORY                 TABLE
         3 WRI$_OPTSTAT_TAB_HISTORY                 TABLE
         4 WRI$_OPTSTAT_IND_HISTORY                 TABLE
         8 WRI$_OPTSTAT_HISTGRM_HISTORY             TABLE
       104 WRI$_OPTSTAT_HISTHEAD_HISTORY            TABLE

        MB SEGMENT_NAME                             SEGMEN
---------- ---------------------------------------- ------
         0 WRH$_OPTIMIZER_ENV_PK                    INDEX
         0 I_WRI$_OPTSTAT_OPR_STIME                 INDEX
         0 I_WRI$_OPTSTAT_AUX_ST                    INDEX
         2 I_WRI$_OPTSTAT_IND_ST                    INDEX
         2 I_WRI$_OPTSTAT_TAB_ST                    INDEX
         3 I_WRI$_OPTSTAT_TAB_OBJ#_ST               INDEX
         4 I_WRI$_OPTSTAT_IND_OBJ#_ST               INDEX
         5 I_WRI$_OPTSTAT_H_ST                      INDEX
         9 I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST           INDEX
        41 I_WRI$_OPTSTAT_HH_ST                     INDEX
        96 I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST            INDEX
h1

Purging ADR log and trace files automatically

May 13, 2009

The following script was put together by a colleague, David Sutton, and shows a way to create a script to tidy up the logs and trace files generated in 11G. Note that the purge time is in seconds and this keep s 30 days online. This is probably too many on some of our systems and this is likely to be reduced to 14 days although we will keep incident history for longer

This is called each day from cron (or it could be run from dbms_scheduler, either directly or via an OEM job) 

 

#!/usr/bin/ksh
#
#
#
# Description
# Shell script to interact with the ADR through ADRCI and purge ADR contents
#
# Tunables
###
LOCKFILE=/tmp/mor_adrci_purge_.lck

###

######
# Start Of Functions
#
# tidyup – common fuction called if error has occured
tidyup () {
        rm -f ${LOCKFILE}
        echo “ERROR: Purge aborted at `date` with exit code ${ERR}”
        exit ${ERR}
}

######
# End Of Functions

### Main Program

# Check user is oracle
USERID=`/usr/bin/id -u -nr`
if [ $? -ne 0 ]
then
        echo “ERROR: unable to determine uid”
        exit 99
fi
if [ "${USERID}" != "oracle" ]
then
        echo “ERROR: This script must be run as oracle”
        exit 98
fi

echo “INFO: Purge started at `date`”

# Check if lockfile exists
if [ -f ${LOCKFILE} ]
then
        echo “ERROR: Lock file already exists”
        echo “       Purge already active or incorrectly terminated”
        echo “       If you are sure tidy isn’t active, please remove “
        echo “       ${LOCKFILE}”
        exit 97
fi

# Create lock file
touch ${LOCKFILE} 2>/dev/null
if [ $? -ne 0 ]
then
        echo “ERROR: Unable to create lock file”
        exit 96
fi

# Purge ADR contents
echo “INFO: adrci purge started at `date`”
/app/oracle/product/11.1.0/db_1/bin/adrci exec=”show homes”|grep -v : | while read file_line
do
  echo “INFO: adrci purging diagnostic destination ” $file_line
  echo “INFO: purging ALERT older than 90 days ….”
  /app/oracle/product/11.1.0/db_1/bin/adrci exec=”set homepath $file_line;purge -age 129600 -type ALERT”
  echo “INFO: purging INCIDENT older than 30 days ….”
  /app/oracle/product/11.1.0/db_1/bin/adrci exec=”set homepath $file_line;purge -age 43200 -type INCIDENT”
  echo “INFO: purging TRACE older than 30 days ….”
  /app/oracle/product/11.1.0/db_1/bin/adrci exec=”set homepath $file_line;purge -age 43200 -type TRACE”
  echo “INFO: purging CDUMP older than 30 days ….”
  /app/oracle/product/11.1.0/db_1/bin/adrci exec=”set homepath $file_line;purge -age 43200 -type CDUMP”
  echo “INFO: purging HM older than 30 days ….”
  /app/oracle/product/11.1.0/db_1/bin/adrci exec=”set homepath $file_line;purge -age 43200 -type HM”
  echo “”
  echo “”
done

echo
echo “INFO: adrci purge finished at `date`”

# All completed
rm -f ${LOCKFILE}
echo “SUCC: Purge completed successfully at `date`”

exit 0

h1

Autostart using the ‘W’ flag in oratab

May 12, 2009

In 10.2.0.2 an option arrived to manage the automatic startup and shutdown of the databases. This is documented in the manual and also in Metalink note 788502.1.
It  is probably easier to reproduce the key paragraph here

Database entries in the oratab file are displayed in the following format:

SID:ORACLE_HOME:{Y|N|W}

In this example, the values Y and N specify whether you want the scripts to start up or shut down the database, respectively. For each database for which you want to automate shutdown and startup, first determine the instance identifier (SID) for that database, which is identified by the SID in the first field.

Then, change the last field for each to Y.

You can set dbstart to autostart a single-instance database that uses an Automatic Storage Management installation that is auto-started by Oracle Clusterware. This is the default behavior for an Automatic Storage Management cluster. If you want to do this, then you must change the oratab entry of the database and the Automatic Storage Management installation to use a third field with the value W and N, respectively. These values specify that dbstart auto-starts the database only after the Automatic Storage Management instance is started.

However on playing around with these settings on a server with ASM and 11.1.0.7 installed complete with a single instance database I could not see any way that the functionality was working.

Looking around on the net there does not seem to be much information out there and nothing on Metalink

In our environment we have a standard that we set up the oratab in the following manner

DATABASE SID that will be the default ORACLE_SID and ORACLE_HOME when you login
DATABASE_SID1 – if available
DATABASE_SID2 – if available
+ASM – the asm instance entry
agent10g – the ORACLE_HOME for the grid agent.

I suspect that if the ‘W’ flag in oratab did work then we would need to change that standard to get the ASM entry in as the first entry.

If anyone has any more feedback please feel free to comment

h1

DBMS_DATAPUMP using the API

May 6, 2009

My challenge was to move a schema from one database to another, simple enough one would assume however I had several limitations. I could not use transportable tables because the charactersets
were different and I did not want to go through a conversion routine but the main limitation was the size (2Tb) and the fact that there were multiple partitions complete with four subpartitions per partition.
I decided to use export and a single file export took 15 hours and created a 700Mb datafile. The import was less than 50% through after 24 hours so I knew I needed a more efficient method.I had already arranged for a large filesystem to be mounted on the
source database and the idea was to export to that area and then get it remounted on the target server. This was to be repeated against the production database at a later date so it was worth getting everything scripted.

I generated 4 export parameter files to take out 3 big tables and ‘all the rest’

userid=xxxx
directory=movetbs
dumpfile=odsprod_odsalltherest.dmp
schemas=odsprod
exclude=TABLE:”IN (’ODS_SLS_TRAN_HEADER’,'ODS_SLS_PAYMENT_DETAIL’,'ODS_SLS_ITEM_DETAIL’)”
#exclude=TABLE:”LIKE ‘ODS_TEMP_STAGE%’”
logfile=ALLTHEREST.log
content=METADATA_ONLY

userid=xxxx
directory=movetbs
dumpfile=odsprod_odsslscheck.dmp
schemas=odsprod
include=TABLE:”IN (’ODS_SLS_CHECK_ERRORS’)”
logfile=ODS_SLS_CHECK_ERRORS.log
content=METADATA_ONLY

userid=xxxx
directory=movetbs
dumpfile=odsprod_odstran.dmp
schemas=odsprod
include=TABLE:”IN (’ODS_SLS_TRAN_HEADER’)”
logfile=ODS_SLS_TRAN_HEADER.log

content=METADATA_ONLY

Note that the above examples have the content=metatdata_only parameter as I wanted to get everything working before I started the exports. I also used the I had already experimented with a command line syntax but discounted it because the line got too long and rather hard to manage. An example is here though

nohup expdp xxxx directory=movetbs dumpfile=odsprod_odstempstage.dmp schemas=odsprod include=TABLE:\”LIKE \(\’ODS_TEMP_STAGE%\’\)\” logfile=TEMPSTAGE.log &

So far so good but I then realised that the large table (ODS_SLS_ITEM_DETAIL) was over 4 billion rows in size and created a 600Gbfile by itself and was going to be the biggest bottleneck.I did some experimentation with a query parameter to the export but it took too long to scan the data and was not very efficient. Example provided

userid=xxxx
directory=movetbs
dumpfile=odsprod_odsitemdetquery.dmp
schemas=odsprod
include=TABLE:”IN (’ODS_SLS_ITEM_DETAIL’)”
query=ODSPROD.ODS_SLS_ITEM_DETAIL:” where id_pk <= 5000000″
logfile=ODSITEMDETQUERY.log

I then decided to export by partition but could not find a way of specifying the partition list using expdp. That is probably because such an option does not exist even in 11.1.0.7 and I needed to use the dbms_datapump API. This was documented in Metalink note 470027.1. To cut to the chase I ended up with 4 export sql files which split up the partitions based on dates, 2008a, 2008b, 2009a,2009b

cat exp2009a.sql

declare
h1 number;

begin
h1 := dbms_datapump.open (operation => ‘EXPORT’,job_mode => ‘TABLE’);

dbms_datapump.add_file (handle => h1,
filename => ‘exp2009a%U.DMP’,
directory => ‘MOVETBS’,
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE);

dbms_datapump.add_file (handle => h1,
directory => ‘MOVETBS’,
filename => ‘EXP2009a.log’,
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);

dbms_datapump.metadata_filter (handle => h1, name => ‘SCHEMA_EXPR’,
value => ‘IN (”ODSPROD”)’);

dbms_datapump.metadata_filter (handle => h1,
name => ‘NAME_EXPR’,
value => ‘IN (”ODS_SLS_ITEM_DETAIL”)’);

dbms_datapump.set_parallel( handle => h1, degree => 6);

dbms_datapump.data_filter (handle => h1,
name => ‘PARTITION_LIST’,
value => ”’ODS_SLS_ITEM_DETAIL_20090101”, ”ODS_SLS_ITEM_DETAIL_20090102”, more here ‘’ODS_SLS_ITEM_DETAIL_20090227”, ”ODS_SLS_ITEM_DETAIL_20090228”’,
table_name => ‘ODS_SLS_ITEM_DETAIL’,
schema_name => ‘ODSPROD’);

dbms_datapump.start_job (handle => h1);
dbms_datapump.detach (handle => h1);
end;
/

Running these 4 jobs in parallel as well as the 3 exports listed above I managed to get the data exported in ~2.5 hours which was a considerable improvement on the original 15 hours. I then moved the mountpoint onto the target server and ran impdb jobs as well as sql scripts to load the data.
Examples below
cat ALLTHEREST.imp

userid=xxxx
directory=movetbs
dumpfile=odsprod_odsalltherest.dmp
full=y
logfile=ALLTHERESTimp.log

cat imp2009a.imp

declare
k1 number;

begin
k1 := dbms_datapump.open (operation => ‘IMPORT’,job_mode => ‘TABLE’);

dbms_datapump.add_file (handle => k1,
filename => ‘exp2009a%U.DMP’,
directory => ‘MOVETBS’,
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE);

dbms_datapump.add_file (handle => k1,
directory => ‘MOVETBS’,
filename => ‘IMP2009a.log’,
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);

dbms_datapump.metadata_filter (handle => k1, name => ‘SCHEMA_EXPR’,
value => ‘IN (”ODSPROD”)’);

dbms_datapump.metadata_filter (handle => k1,
name => ‘NAME_EXPR’,
value => ‘IN (”ODS_SLS_ITEM_DETAIL”)’);
dbms_datapump.set_parallel( handle => k1, degree => 6);
dbms_datapump.set_parameter (k1, ‘TABLE_EXISTS_ACTION’, ‘APPEND’);

dbms_datapump.data_filter (handle => k1,
name => ‘PARTITION_LIST’,
value => ”’ODS_SLS_ITEM_DETAIL_20090101”, ”ODS_SLS_ITEM_DETAIL_20090102”, MORE HERE ”ODS_SLS_ITEM_DETAIL_20090227”, ”ODS_SLS_ITEM_DETAIL_20090228”’,
table_name => ‘ODS_SLS_ITEM_DETAIL’,
schema_name => ‘ODSPROD’);

dbms_datapump.start_job (handle => k1);
dbms_datapump.detach (handle => k1);
end;
/

Note the additional line to ensure that the load is not skipped as the table already exists

dbms_datapump.set_parameter (k1, ‘TABLE_EXISTS_ACTION’, ‘APPEND’);

The total load seem to take around 6 hours now which has reduced from the estimated 48-60 hours that was seen initially. However I am seeing a lot of enq: TM contention as I have 6 worker processes for 4 imports, all running against the ODS_SLS_ITEM_DETAIL table. Still trying to work out how to address that and possible optimise the number of worker processes by changing the PARALLEL parameter. We have 16 cpus but I am more tempted to reduce rather than increase the workers to give less contention. However this load will only happen twice so perhaps I do not need to spend too much time fine-tuning.
I hope that this entry has been useful. I had never used the datapump API before so it was a learning curve for me.

PS This is useful script to show progress on the expdp/impdp jobs

set lines 120
col opname for a25 trunc
col username for a15 trunc
col target for a20
col sid for 999999
col serial# for 999999
col %DONE for a8
select b.username,a.sid,b.opname,b.target,round(b.SOFAR*100 / b.TOTALWORK,0) || ‘%’ as “%DONE”,
b.TIME_REMAINING,to_char(b.start_time,’YYYY/MM/DD HH24:MI:SS’) START_TIME
from V$SESSION_LONGOPS b,V$SESSION a where a.sid=b.sid and TIME_REMAINING 0 order by b.SOFAR/b.TOTALWORK;

h1

How to format a wordpress blog – question

May 6, 2009

I type an an entry up in Word, nicely formatted with all code indented and with a 25% grey background. Font size set to 10pt.

I paste the entry into WP using the ‘Paste from Word’ icon and all the formatting is lost and I have every line of code triplespaced by the look of things.

I often spend more time formatting an entry here than I do actually creating it (yes I know, they read like I have rushed them through).

Does anybody have any ideas or even the contents of a word style that they use that copies into WP succcessfully 

 

TIA

John