Home » SQL & PL/SQL » SQL & PL/SQL » Oracle problems in split partition
Oracle problems in split partition [message #148141] Tue, 22 November 2005 22:04 Go to next message
war123
Messages: 8
Registered: November 2005
Junior Member
Please help me
I have a need to split partition when insert new row. So I do it in Before insert trigger.

CREATE TABLE TempTable
(
ID NUMBER (12) NOT NULL
)
PARTITION BY RANGE (ID)
(
PARTITION TempTable_R VALUES LESS THAN (MAXVALUE)
)

CREATE OR REPLACE TRIGGER TempTableBefInsTrigger
BEFORE INSERT ON TempTable
REFERENCING NEW AS newRow
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
Insert_PROC(:newRow.ID);
END TempTable;


CREATE OR REPLACE PROCEDURE Insert_PROC (ID NUMBER) AS
PRAGMA AUTONOMOUS_TRANSACTION;
msgResult NVARCHAR2(1000);
sqlString VARCHAR2(1000);
BEGIN
sqlString := 'ALTER TABLE TempTable ADD PARTITION TempTable_R AT (ID) INTO ( PARTITION TempTable_' || ID || ', PARTITION TempTable_R)';
BEGIN
execute immediate sqlString;
EXCEPTION
WHEN OTHERS THEN msgResult := SQLERRM;
dbms_output.put_line('Error TempTable table: ' || msgResult);
END;
END;

If I insert:
INSERT INTO TempTable VALUES(1);
COMMIT;
INSERT INTO TempTable VALUES(100);
COMMIT;

-> Split OK for all;

But If I insert:
INSERT INTO TempTable VALUES(1);
INSERT INTO TempTable VALUES(100);
COMMIT;

Error: ORA-00054: resource busy and acquire with NOWAIT specified

So, how do I can split partition any time when i insert new record.

Thanks
Re: Oracle problems in split partition [message #148170 is a reply to message #148141] Wed, 23 November 2005 00:14 Go to previous messageGo to next message
rleishman
Messages: 3728
Registered: October 2005
Location: Melbourne, Australia
Senior Member
A DDL operation (ALTER, DROP, etc) on a table tries to lock the ENTIRE table in exclusive mode. The INSERT statement will lock the table in SHARE mode, so you cannot get the EXCLUSIVE lock you need. Even if you could lock it, you would get a mutating table error.

Upshot: you can't do what you're trying to do. Which is a good thing, because it's a horrible (yet un-nervingly interesting)concept. If you have a table big enough to be partitioned then you don't want a trigger on it with that sort of overhead anyway, because there are going to be tons of inserts.

However, if you choose to press on regardless, there are two things you could try.
1. You could use the FOR EACH ROW trigger to temporarily store the rowids in a nested table declared in a PACKAGE SPEC (persistent within the session), and then try to split the partition in an after-statement trigger (ie. no FOR EACH ROW clause) by reading the data in the nested table and taking action as required. You will probably come across the same locking problem though, so this will probably be a wash-out.

2. You could create a view as SELECT * FROM TempTable, and insert into the table via the view. Rather than letting Oracle handle the INSERTs, write an INSTEAD OF INSERT trigger to do it manually. The INTEAD OF INSERT trigger would insert the row, commit, then perform the SPLIT.
I don't know how this will go - commits in triggers seem like a bad idea. But I've never tried it, so it might just work.

Let me re-iterate - this whole thing is a terrible idea. I stongly recommend you do not proceed down this path. There is something fundamenally wrong with a design that requires this kind of approach.
I only provide the ideas above because what you have proprosed is an interesting theoretical question - not because I want to see you go for it.

_____________
Ross Leishman
Re: Oracle problems in split partition [message #148201 is a reply to message #148141] Wed, 23 November 2005 01:17 Go to previous messageGo to next message
war123
Messages: 8
Registered: November 2005
Junior Member
Thanks for reply.

You could use the FOR EACH ROW trigger to temporarily store the rowids in a nested table declared in a PACKAGE SPEC (persistent within the session), and then try to split the partition in an after-statement trigger (ie. no FOR EACH ROW clause) by reading the data in the nested table and taking action as required. You will probably come across the same locking problem though, so this will probably be a wash-out.

Can you explain more it for me?

I have 4 SQL command:

ALTER TABLE TempTable ADD PARTITION TempTable_R AT (10) INTO ( PARTITION TempTable_1, PARTITION TempTable_R);
INSERT INTO TempTable VALUES(1);
ALTER TABLE TempTable ADD PARTITION TempTable_R AT (100) INTO ( PARTITION TempTable_2, PARTITION TempTable_R);
INSERT INTO TempTable VALUES(50);
COMMIT;
-> That's OK too.

How it is difference with Split and insert in a trigger?
Re: Oracle problems in split partition [message #148367 is a reply to message #148201] Wed, 23 November 2005 16:47 Go to previous messageGo to next message
rleishman
Messages: 3728
Registered: October 2005
Location: Melbourne, Australia
Senior Member
Are those ADDs in your example are supposed to be SPLITs?

The difference between your example and the trigger, is that the trigger doesn't work Smile For the reasons I described above.

The way you are doing it with 4 statements is still not a great idea, unless there are many thousands of INSERT between each SPLIT. Even then, its not such a hot idea.

The thing about partitions is that you shouldn't be mucking about with them in application code; they should ideally be left up to the DBA. Most applications would create the partitions they need without a MAXVALUE partition, and then create new partitions above the previous highest value as required.

Adding a partition above the previous highest value is fast. Splitting an existing partition means a lot of IO - ie. v.slow.

If you are splitting partitions, it means that they were not sized correctly in the first place. Sizing (and managing segment sizes) should be done in conjunction with the DBA when a table is deployed, not re-sized arbitrarily on the fly.

I see that you are eager to pursue this despite this advice (and that's your perogative, I'm not the boss of you Smile ). If you want to know more about the statement-level trigger possibility (remember, I don't even know if it would work), then see here.
_____________
Ross Leishman
Re: Oracle problems in split partition [message #148402 is a reply to message #148141] Thu, 24 November 2005 00:58 Go to previous messageGo to next message
war123
Messages: 8
Registered: November 2005
Junior Member
Thanks alot rleishman.

For adding new partition, I have thought about it, but my boss doesn't want to do it.

Do you have any other ideas?
Please suggest them to me.

Thanks
Re: Oracle problems in split partition [message #148513 is a reply to message #148402] Thu, 24 November 2005 16:17 Go to previous messageGo to next message
rleishman
Messages: 3728
Registered: October 2005
Location: Melbourne, Australia
Senior Member
war123 wrote on Thu, 24 November 2005 17:58

...my boss doesn't want to do it.

Do you have any other ideas?


You just knew this one was coming....Smile

Suggestion 1: Get a new boss.
Suggestion 2: Encourage your boss not to meddle in database matters.

Seriously though, why does your boss want you to create a design that will send IO through the roof?

Answer me this:
1. How many rows will be in the table?
2. How many rows will be inserted daily/monthly?
3. What is your criteria for splitting partitions? Your examples make it look like you are doing it for every row. You must have some other criteria. eg. Split when a partition exceeds 5M rows.

_____________
Ross Leishman
Re: Oracle problems in split partition [message #148771 is a reply to message #148141] Mon, 28 November 2005 01:22 Go to previous message
war123
Messages: 8
Registered: November 2005
Junior Member
Thanks rleishman. Laughing
I have resolve the problems by replace Oracle 10G Release 1 with Oracle 10G Release2.

Maybe that is the error of Oracle 10G Release 1.
Cool
Previous Topic: How can I change output message in Trigger
Next Topic: Query Problem
Goto Forum:
  


Current Time: Mon Apr 28 17:59:50 CDT 2025