
May 20, 2008 - 1pm Central time zone
Reviewer: Richard Kheir from Germantown, MD

May 20, 2008 - 5pm Central time zone
Reviewer: Rick from Germantown, MD
The question was about resolving references "TO" the table being redifined.
This was NOT addressed!
Followup May 20, 2008 - 9pm Central time zone:
Rick
you wanted to turn a table T1 into a partitioned table.
Which part of THAT was not addressed, why would address something that is *moot* when you do it the easy, correct way?
and, well,
ops$tkyte%ORA10GR2> variable nerrors number
ops$tkyte%ORA10GR2> begin
2 dbms_redefinition.copy_table_dependents
3 ( user, 'T1', 'T2',
4 copy_indexes => dbms_redefinition.cons_orig_params,
5 num_errors => :nerrors );
6 end;
7 /
does that - it creates all of the constraints on the new partitoined table for you, grants and all.
with your create table/insert approach - you would have to copy indexes, grants, all constraints, etc. You don't simply "repoint things", you have to put them in place. You cannot "repoint" a foreign key at all, you have to recreate it.
And I, well, sort of demonstrated how to do that - online, no down time, safely.

May 20, 2008 - 9pm Central time zone
Reviewer: Rick
There was an internal error from my side with regards to creating local indexes. Your solution is
perfect and most straight forward!
Thanks Tom!
archieving a table
November 5, 2008 - 1pm Central time zone
Reviewer: Rajeshwaran Jeyabal
Hi Tom,
Can you please help me in this approch.
Create table t_part
(
x Number,
y DATE
);
insert into t_part values (1,sysdate);
insert into t_part values (2,sysdate-1);
insert into t_part values (3,sysdate-2);
insert into t_part values (4,sysdate-3);
insert into t_part values (5,sysdate-4);
insert into t_part values (6,sysdate-5);
insert into t_part values (7,sysdate-6);
insert into t_part values (8,sysdate-7);
insert into t_part values (9,sysdate-8);
insert into t_part values (10,sysdate-9);
scott@AFRSQA> select x,y, trunc(y-sysdate) from t_part;
X Y TRUNC(Y-SYSDATE)
---------- --------- ----------------
1 04-NOV-08 0
2 03-NOV-08 -1
3 02-NOV-08 -2
4 01-NOV-08 -3
5 31-OCT-08 -4
6 30-OCT-08 -5
6 30-OCT-08 -5
7 29-OCT-08 -6
8 28-OCT-08 -7
9 27-OCT-08 -8
10 26-OCT-08 -9
11 rows selected.
(a) The table "t_part" will be populated by every day Transactions. I need to Archive the data that
is 3 days old.
I taught to use PARTITION Concept in Oracle instead of going for history table approch.
Is this a right approch Let me know your taughts?
(b) But i am facing this below error. Can you please help me how to identify and partition 3 days
old data
(it is not allowing me to use (y-sysdate) as a partition key then how to identify 3 days old
data)?
(c) Also this partitioning should happen at the end of every day at Mid night.
scott@AFRSQA> Create table t_p1
2 (
3 x Number,
4 y DATE
5 )
6 partition by range(Trunc(y-sysdate))
7 (
8 partition p1 values less than (-2)
9 )
10 ;
partition by range(Trunc(y-sysdate))
*
ERROR at line 6:
ORA-00907: missing right parenthesis
Followup November 11, 2008 - 2pm Central time zone:
a) partitioning would be natural for this - and would not necessarily obviate a history table. The two concepts are not really 'tied together' and are definitely not mutually exclusive.
what is a history table? a table with old transactions you would like to have access to but have no reason to be in the live table.
how you do populate a history table? Well, you could
1) insert as select from live
2) delete from live
but that would be hugely expensive. You could instead:
1) alter table live exchange the oldpartition with an empty table
2) alter table history exchange anemptypartition with now-full-table
which would 'move' the old transactions from live to history without moving a byte - no redo, no undo (short of the dictionary updates), very fast.
b) you always use fixed dates, you would say "data less than to_date('some-date','some-format')
think about this, think about what using "sysdate" would mean - and what it would mean 5 seconds from now when sysdate changes. You set up your ranges based on days.
So, every day you would have a job to create tomorrows partition - alter table t add partition (or use interval partition in 11g to automate this)
SPOOL
November 18, 2008 - 5am Central time zone
Reviewer: Rajeshwaran Jeyabal
Tom !! Thanks a Ton.
I just want to know how to get the column names in spool file.
Normally, whenver we use spool file for listing the selected records, that will contain column name
and corresponding data.
But, if there is no record for a particular select query, the spool file only contains "no rows
selected".
Here is my question. Can we get the column names under which "no rows selected" message???
For example: A table contain 2 columns and i am running select query for a particular condn. it
doesn't contain any record.
column1 column2
no rows selected.
instead of only "no rows selected".
Please help me on this.
Awaiting for your valuable replies. Since it is critical in my project.
Followup November 18, 2008 - 7pm Central time zone:
see where you asked this previously, i answered over there
Using dbms_redefinition in Oracle 9i R2
November 20, 2008 - 5am Central time zone
Reviewer: Rajeshwaran Jeyabal
Hi Tom,
I am using dbms_redefinition to partition table in Oracle 9i. But facing this error. Can you
please help me what this error about and how this can be solved?
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE 9.2.0.1.0 Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production
SQL> Create table t1_part
2 as
3 select * from all_users;
Table created.
SQL> ALTER TABLE T1_PART ADD CONSTRAINT T1_PK PRIMARY KEY(USER_ID);
Table altered.
SQL> DESC T1_PART;
Name Null? Type
----------------------------------------- -------- ----------------------------
USERNAME NOT NULL VARCHAR2(30)
USER_ID NOT NULL NUMBER
CREATED NOT NULL DATE
SQL> Create table t2_part
2 (
3 User_name Varchar2(30) NOT NULL,
4 user_id Number NOT NULL,
5 Created DATE NOT NULL
6 )
7 partition by hash(user_id) partitions 4;
Table created.
SQL> DESC T2_PART;
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_NAME NOT NULL VARCHAR2(30)
USER_ID NOT NULL NUMBER
CREATED NOT NULL DATE
SQL> ALTER TABLE T2_PART ADD CONSTRAINT T2_PK PRIMARY KEY(USER_ID);
Table altered.
SQL> BEGIN
2
dbms_redefinition.abort_redef_table(uname=>'SCOTT',orig_table=>'T1_PART',int_table=>'T2_PART');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> begin
2 dbms_redefinition.can_redef_table(uname=>'SCOTT',tname=>'T1_PART');
3
dbms_redefinition.start_redef_table(uname=>'SCOTT',orig_table=>'T1_PART',int_table=>'T2_PART');
4
dbms_redefinition.finish_redef_table(uname=>'SCOTT',orig_table=>'T1_PART',int_table=>'T2_PART');
5 end;
6 /
begin
*
ERROR at line 1:
ORA-12060: shape of prebuilt table does not match definition query
ORA-06512: at "SYS.DBMS_REDEFINITION", line 8
ORA-06512: at "SYS.DBMS_REDEFINITION", line 146
ORA-06512: at line 3
SQL>
Followup November 24, 2008 - 11am Central time zone:
you changed column names - if you do that, you'd have to do a bit more work (column mapping)
if you use the same names, simple:
ops$tkyte%ORA9IR2> Create table t2_part
2 (
3 Username Varchar2(30) NOT NULL,
4 user_id Number NOT NULL,
5 Created DATE NOT NULL
6 )
7 partition by hash(user_id) partitions 4;
Table created.
ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> ALTER TABLE T2_PART ADD CONSTRAINT T2_PK PRIMARY KEY(USER_ID);
Table altered.
ops$tkyte%ORA9IR2> exec dbms_redefinition.can_redef_table(uname=>user, tname=>'T1_PART');
PL/SQL procedure successfully completed.
ops$tkyte%ORA9IR2> exec dbms_redefinition.start_redef_table(uname=>user,
orig_table=>'T1_PART',int_table=>'T2_PART' );
PL/SQL procedure successfully completed.
ops$tkyte%ORA9IR2> exec dbms_redefinition.finish_redef_table(uname=>user,
orig_table=>'T1_PART',int_table=>'T2_PART');
PL/SQL procedure successfully completed.
Partitions
November 25, 2008 - 6am Central time zone
Reviewer: Rajeshwaran, Jeyabal
Hats off to TOM !!!

December 11, 2008 - 7am Central time zone
Reviewer: A reader
According to Database Concepts at one place it says:
Partitioning is useful for many different types of applications, particularly applications that
manage large volumes of
data. OLTP systems often benefit from improvements in manageability and availability, while data
warehousing systems benefit
from performance and manageability.
Then at other place it says:
Partitioning offers these advantages:
Partitioning improves query performance. In many cases, the results of a query can be achieved by
accessing a subset of
partitions, rather than the entire table. For some queries, this technique (called partition
pruning) can provide
order-of-magnitude gains in performance.
According to Expert one on one Oracle your suggestion is :
Reduces contention on high insert OLTP systems (such as an audit trail table) by
spreading the inserts out across many separate partitions (spreads the hot spots
around).
We have one table on OLTP with records aroud 10978888. Should we implement Pratitioning on it?
Followup December 11, 2008 - 8am Central time zone:
you tell me. Honestly - you are the only one that can answer this. (and by the way, 11 million rows is meaningless - that gives NO clue as to the size, we could be taking 100mb or 100gb or a terabyte - but we don't know.... everyone needs to stop saying "X rows" and start saying "Y <T|G|M>bytes")
You know now the physics behind partitioning.
You know now what you can hope to achieve:
o increased availability - by spreading the data out over many partitions - if you suffer a media failure, only a small subset of the data might become unavailable. is this relevant to you, does this apply in your case, do you need this, is this something you need to design into your system, is this your major number one goal?
if not, move onto the next point
o ease of administration - by making the things you manage smaller. is this relevant to you, do you purge data by date, would a range partition on date make sense, do you need to reorganize data/indexes for whatever reason, would the fact the big table is now a series of small tables be relevant to you, would it make your life better?
if not, move onto the next point
o improved DML performance. For warehouse - partition pruning. For OLTP - possible reduced contention. are you a warehouse that could make use of this? are you a transactional system suffering from contention on a single segment - be that an hot right hand side of an index populated by a DATE or a SEQUENCE or a table with massive concurrent inserts
if not..... we are done

December 11, 2008 - 10am Central time zone
Reviewer: A reader
Thanks a lot for your details reply.
We are OLTP system using Oracle 10g release1, OS Red Hat AS 3 update 3. Database contains 4 CPU and
4 GM memory. The problem we are facing is when the some of reports which use tables (A 800MB, B
200MB, C 500MB) executes, it takes to finish about 20-30 minutes. In this period this report
process consumes one CPU 100% and in the mean time rest of the application becomes slow down. The
ADDM report generated for this time show high Physical/Logical IO. One of Our DBA is suggesting
that we should use partitioning on these tables to resolve the issue.
Followup December 11, 2008 - 7pm Central time zone:
ask the dba "why, will the report be able to use partitioning in order to eliminate a large portion of the data? and if so, how does this partitioning scheme affect the OLTP application - because if we are not careful - it will make OLTP run really really slow - unless we actually design it to work with OLTP and support the partition elimination"
Unless your dba has does this design and analysis, they are only just starting.
If you went to them and they said "hmmm, lots of IO, lets partition" - run away.
If you went to them and they studied the problem and have a design that leads to an X% reduction in IO's and does not negatively affect the OLTP system - then hats off to them, they did it right.
those are fairly small tables - a more likely option is "tune queries" if you ask me
so, which case are we dealing with - case1: silver bullet, I heard partitioning is fast=true or case2: we have studied it and can tell you what to expect when you implement our DESIGN..
dbms_redefinition question
October 4, 2009 - 11pm Central time zone
Reviewer: A reader from Houston, Texas
Hi Tom,
I have an audit_trail table that is used by our application to log almost all changes to the
network inventory that we keep. The table is 1.5 billion rows (size is about 100 GB). It has two
composite indexes each 80 GB in size. The table gets 20 to 30 thousands rows in a minute in a busy
period. If I use dbms_redefinition to partition it, will such insert rate be possible at all? Or
will I have to get an application downtime to run dbms_redefinition?
Thank you.
Followup October 8, 2009 - 6am Central time zone:
well, since this is an audit trail - you have another alternative I think.
Let me make this rather safe assumption:
your audit trail is an audit trail in the conventional sense - the data that is already inserted will *never* change - you do not update nor delete it. In fact - it is almost certain that your application does not really read it either - you use it for fact finding after the fact (rarely).
Therefore, an option for you would be:
a) create your new partitioned, but empty, audit trail - new_audit_trail. It'll be partitioned by date range I believe
b) pause your application for 1 second while you
c) rename current_audit_trail to old_audit_trail, then rename new_audit_trail to current_audit_trail
d) unpause your application
Now - your application will be populating this new table - you can, at your leisure, break your old audit trail up
create table temp_audit_trail
partition
as
select * from old_audit_trail;
drop old_audit_trail;
index temp_audit_trail
you now have your old data partitioned (heck, you could even transport the old audit trail to another machine to do this - you'll have the data on production if you need it - you have another machine to work on - after you are done you can transport this newly partitioned data back into production)
now all you need is a non-partitioned table T that looks just like your partitioned table(s). You will do an exchange to move the partitions from temp_audit_trail to current_audit_trail
alter table temp_audit_trail exchange partition part_jan_2005 with t including indexes novalidation..... whatever other options you want ....;
alter table current_audit_trail exchange partition part_jan_2005 with t .....;
do that for every partition and you'll have moved your data in likely the most efficient fashion possible - all direct path, all online (except for that one second pause), all can be done without redo or undo generation - in parallel if you like.
Think about the nature of your data and how it is used - in this case I believe that'll open up possibilities for moving the data not normally available.
partitioning for existing tables
January 23, 2010 - 7am Central time zone
Reviewer: su from uk
hi tom,
i am doing partitioning for existing table.actually this table is in paradox database.i have
migrated that table using ms access in oracle.i want to know hash partitioning for this table.i
have got answer for how to do range partitioning.but i am not getting the hash partitioning using
ID.how to create tablespace for this table.and how i can transfer the data from partitioning table
to non partition table.
ex: create table person(personid number,pname varchar2(10))
partition by HASH(personid)
(
Partition p1 tablespacet1
)
Followup January 25, 2010 - 6am Central time zone:
this makes no sense.
Do you understand HOW you want to partition? and more importantly WHY you want to partition?
dbms_redefinition in 11g
July 20, 2010 - 10am Central time zone
Reviewer: Developer
Hello Tom,
I am using Oracle 11.1.0.7 version. I want to use dbms_redefinition to move to using Tablespace Transparent Data Encryption (TDE). So I create new encrypted tablespaces and move the tables/indexes to the new encrypted tablespaces using dbms_redefinition. I observed 3 shortcomings of dbms_redefinition and they are as follows:
1) It does not copy column comments. (I think this is a bug.)
2) It does not copy table statistics even after I set COPY_STATISTICS to TRUE. I tested this to move a range partitioned table.
3) I cannot specify anywhere the new tablespace name for the indexes. I can't really use copy_indexes parameter of the copy_table_dependents procedure.
What do you think?
Followup July 23, 2010 - 7am Central time zone:
1) they probably would not classify as bug but rather as enhancement request. I could see that go either way.
2) I confirmed this is a bug - it worked in 10gr2 for partitioned tables but stopped working in 11gr1. I filed bug 9937133 for this
3) that is expected and why we have manual and automatic copy methods. You would create the indexes with different parameters manually and then invoke copy_table_dependents to get everything else using ignore_errors=> true. Query dba_redefinition_errors after copy table dependents to make sure everything got copied correctly.
partition exchange failure
September 17, 2010 - 9am Central time zone
Reviewer: asim from Wilmington DE
Hi Tom,
I had a question about partition exchange. I have been having failures when trying to exchange a
table partition with a staging table (both has primary/foreign keys). When ever the partitin
exchange script is run, the initial run always fails with the below error but the 2nd run is always
successful. Any clues?? WHat should my diagnosis steps be. Thanks in advance.
-600-Error at step- ExchangePartition action ,procedure exchange_partition ORA-00600: internal
error code, arguments: [16609]
, [0x70000001A4E9220], [3905], [0], [], [], [], []
Followup September 17, 2010 - 12pm Central time zone:
ora-600 => please contact support, it should not happen.
Read only partitions
October 28, 2010 - 9am Central time zone
Reviewer: Rajeshwaran, Jeyabal
Quote from Oracle product documentation.
<quote>
Once you add the new partition, you can drop the trailing month with the DROP PARTITION statement. The alternative to using the DROP PARTITION statement can be to archive the partition and make it read only, but this works only when your partitions are in separate tablespaces.
</quote>
http://download.oracle.com/docs/cd/B19306_01/server.102/b14223/parpart.htm#sthref178
rajesh@10GR2> create table t(
2 x
3 )partition by range(x)
4 (
5 partition p1 values less than(2) tablespace INDX,
6 partition p2 values less than(3) tablespace tools,
7 partition p_max values less than(maxvalue) tablespace users
8 )
9 AS
10 select rownum
11 from all_objects
12 where rownum <= 5;
Table created.
Elapsed: 00:00:00.17
rajesh@10GR2>
rajesh@10GR2> exec dbms_stats.gather_table_stats(user,'T');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.25
rajesh@10GR2>
rajesh@10GR2> alter table t move partition p1 tablespace tools read only;
alter table t move partition p1 tablespace tools read only
*
ERROR at line 1:
ORA-14020: this physical attribute may not be specified for a table partition
Elapsed: 00:00:00.01
rajesh@10GR2>
rajesh@10GR2> alter table t move partition p1 tablespace tools;
Table altered.
Elapsed: 00:00:00.21
rajesh@10GR2> alter table t modify partition p1 read only;
alter table t modify partition p1 read only
*
ERROR at line 1:
ORA-14049: invalid ALTER TABLE MODIFY PARTITION option
Elapsed: 00:00:00.00
rajesh@10GR2>
Tom:
Is that not possible to make partitions Read only? Can you please help me how to achieve this?
Followup October 28, 2010 - 12pm Central time zone:
their intent was to have you most the partition (or just have the partition be in a tablespace by itself already) AND THEN mark the tablespace the partition is in read only.
You would set the tablespace readonly.
dbms_redefinition with data guard logical standby
February 7, 2011 - 1pm Central time zone
Reviewer: Richard from WI
Tom, can you point me to something in the docs (we are on 10.2.0.4) about the
feasibility/availability of using dbms_redefinition on tables protected by data guard in a logical
standby environment?
Partition an existing table
July 7, 2011 - 8am Central time zone
Reviewer: Rob Campbell from Atlanta, GA
This process is very useful. I'm using it to prune data from some very large tables. Thanks for the
information.
|