Monday, March 05, 2007

Delete BPEL instances

Running a production environment generates a huge amount of BPEL instances. Unless you have specified that you do not use dehydration :-).

It is possible to purge the instances all at once, as described in the article here (It also describes how to reclaim your space). But this purges all the instances. This is nice during development. But in a production environment you want to have a controlled way. A nice way to do this is via good-old PLSQL. Use the package COLLAXA in the ORABPEL schema.

This package has some nice methods to call:

procedure delete_txs
Deletes all the transactions that belong to a particular cube instance.

procedure delete_ci
Deletes a cube instance and all rows in other Collaxa tables that reference the cube instance. Since we don't have referential integrity on the tables (for performance reasons), we need this method to help clean up the database easily.

You can make a query to select the BPEL instances to delete and call the package:

create or replace
PROCEDURE purge_instances
(
p_domain IN VARCHAR2 DEFAULT '%'
, p_process_name IN VARCHAR2 DEFAULT '%'
, p_revision IN VARCHAR2 DEFAULT '%'
, p_older_than IN NUMBER DEFAULT 999
)
IS
CURSOR c
(
b_domain IN VARCHAR2
, b_process_name IN VARCHAR2
, b_revision IN VARCHAR2
, b_older_than IN VARCHAR2
)
IS
SELECT
cie.cikey cikey
, dmn.domain_id domain_id
, cie.process_id process_id
, cie.revision_tag revision_tag
, cie.modify_date modify_date
, cie.domain_ref domain_ref
FROM
cube_instance cie
, domain dmn
WHERE cie.domain_ref = dmn.domain_ref
--
-- the name of the domain
AND dmn.domain_id LIKE b_domain
--
-- code 5 means completed
AND cie.modify_date < TRUNC(sysdate)-b_older_than
--
AND cie.process_id LIKE b_process_name
AND cie.revision_tag LIKE b_revision;
BEGIN
FOR r in c
(
p_domain
, p_process_name
, p_revision
, p_older_than
)
LOOP
DBMS_OUTPUT.PUT_LINE
(
'Purge '||r.process_id||'('||r.revision_tag||')'||
' at '||to_char(r.modify_date, 'YYYY-MM-DD HH24:MI:SS')
);
collaxa.DELETE_CI(r.cikey);
--
delete from wftask wfn where wfn.instanceid = r.cikey;
--
END LOOP;
--
-- delete invoke calls
-- invoked messages
DELETE FROM invoke_message_bin imn
WHERE EXISTS
(
SELECT 1
FROM invoke_message ime
, domain dmn
WHERE ime.message_guid = imn.message_guid
AND ime.domain_ref = dmn.domain_ref
AND dmn.domain_id LIKE p_domain
AND ime.state > 1
AND ime.process_id LIKE p_process_name
AND ime.revision_tag LIKE p_revision
AND ime.receive_date < TRUNC(sysdate)-p_older_than
);
--
DELETE FROM invoke_message ime
WHERE ime.domain_ref in
(
SELECT dmn.DOMAIN_REF
from domain dmn
WHERE dmn.domain_id LIKE p_domain
)
AND ime.state > 1
AND ime.process_id LIKE p_process_name
AND ime.revision_tag LIKE p_revision
AND ime.receive_date < TRUNC(sysdate)-p_older_than;
--
DBMS_OUTPUT.PUT_LINE ('-> #invoke msg '||SQL%ROWCOUNT);
--
--
-- delete callback calls
DELETE FROM dlv_message_bin dmb
WHERE EXISTS
(
SELECT 1
FROM dlv_message dme
, domain dmn
WHERE dme.message_guid = dmb.message_guid
AND dme.domain_ref = dmn.domain_ref
AND dmn.domain_id LIKE p_domain
AND dme.state > 1
AND dme.process_id LIKE p_process_name
AND dme.revision_tag LIKE p_revision
AND dme.receive_date < TRUNC(sysdate)-p_older_than
);
--
DELETE FROM dlv_message dme
WHERE dme.domain_ref IN
(
SELECT dmn.DOMAIN_REF
from domain dmn
WHERE dmn.domain_id LIKE p_domain
)
AND dme.state > 1
AND dme.process_id LIKE p_process_name
AND dme.revision_tag LIKE p_revision
AND dme.receive_date < TRUNC(sysdate)-p_older_than;
--
DBMS_OUTPUT.PUT_LINE ('-> #callback msg '||SQL%ROWCOUNT);
END;
/

16 comments:

Lon said...

Thanks for the script, Marc. I am not a DBA or DB programmer - so forgive me. But when I try to compile this, I get errors on two tables referenced in the script (dlv_message_bin and invoke_message_bin) - and indeed, these two tables do not appear to be in my ORABPEL database. I am running 10.1.3.1 SOA Suite. Was the PL/SQL procedure written for 10.1.3.1 or 10.1.2.0.2?
Thanks for any help.
Lon Nestrud
lon.nestrud at oracle.com

BradW said...

I too am curious about the 10.1.3.1 version of this? As there seems to be fewer tables that the script uses. Also, I am curious as to how I can also remove Workflow Services tasks at the same time? Are there any best practices for this?

Thanks,

BradW

BradW said...

So, I added an extra delete as the collaxa.delete_ci does not do this for us:

delete from wftask wfn where wfn.instanceid = r.cikey;

The API via the console does do this for us, but not the sp API.

I am still not sure what happened to the inbound and outbound message tables with the bin suffix. So, for 10.1.3.1 I removed them from the script.

Thought I'd share.

Marc Kelderman SOA Blog said...

I updated the script according to Brad comments.

Anonymous said...

Hi Marc, can you post the updated script?

Steve, UK said...

Note there is a patch to 10.1.3.3 to purge old data (6372741). Its a fairly dumb one that deletes everything older than a given date. Trying to do something more elaborate we have noticed that if you use the script in this article as a basis then rows in xml_document table are not removed.

Anonymous said...

Hi,

Because we are using "delete" command, I think the tablespace will still grow.. because the deleted row space won't be reused... IMHO

How can we manage the schema, so the tablespace won't grow?

Should we use a partitioned table? How's the implementation?

Thanks

Marc Kelderman SOA Blog said...

Use the approach as delete with bulk delete in my other article. There sql commands to reclaim the space.

Ra1deN said...

When i try to compile the process says that: PL/SQL: ORA-00942: table or view does not exist
That error appears when there is a FROM domain table its like doesn't exists

Marc Kelderman SOA Blog said...

What type of version of SOA Suite you are using?

Marc Kelderman SOA Blog said...

What type of version of SOA Suite you are using?

Ra1deN said...

Hello I must say that it was my mistake, i created a public synonym for cube_instance and all went good (Y)!!

Akei said...

Hi I am using a SOA 10.1.3.4 and my cuestion is: I need to do a full backup to the ORABPEL schema before do this activities, and es necesario make a indexes of the table AUDIT_TRAIL, after run the script from the BPELConsole? And, what is better, run this store procedure or execute the scrit from the console, if I need to purge all the instances

Ravi said...

Marc:
Could you pls. share the latest purge script you have. We are running on 10.1.3.4

Thanks,
Ravi

Marc Kelderman SOA Blog said...

Ig you are using 10.1.3.4 or 10.1.3.5 with the latest patch sets, you have the purgscripts in the OracleHome directory. Search in de BPEL directory.

Marc

mike.perkins said...

I am using the script for 10.1.3.5 found in the ora_home\bpel\... folder. It returns the count but when I call the purge it return "ERROR at line 1:
ORA-06575: Package or function PURGE_INSTANCES is in an invalid state"??

Post a Comment

Post a Comment