You may want to reorganize your auditing table if you optionally delete records from it regularly. In the following steps it is described.
1)Enable restricted session.
In order to ensure consistency in the auditing table temporary disable auditing activity. You can do this by opening database with STARTUP RESTRICT or during open make the system as restricted session.
SQL> connect / as sysdba
Connected.
SQL> alter system enable restricted session;
System altered.
Check if sessions are still connected by,
SQL> select sid, serial#, username from v$session;
If necessary kill these sessions with,
SQL> alter system kill session 'sid , serial#';
2)Copy SYS.AUD$ table.
SQL>CREATE TABLE audit_record TABLESPACE USERS as select * from SYS.AUD$;
You now can take a dump of audit_record.
3)Truncate SYS.AUD$ table.
SQL> truncate table sys.aud$;
Table truncated.
SQL> select count(*) from SYS.AUD$;
COUNT(*)
--------
0
4)Copy the rows back to SYS.AUD$.
SQL> insert into sys.aud$ select * from audit_record;
You can also import it if you exported it in step 2.
5)Drop the audit_record table(optional).
SQL>DROP TABLE audit_record;
Showing posts with label FAQ. Show all posts
Showing posts with label FAQ. Show all posts
Thursday, January 15, 2009
How to truncate or delete rows from audit trail table sys.aud$
1)Only appropriate privileged user can do delete operation on SYS.AUD$ table. The user must have either of the following privileges.
-SYS user.
-DELETE ANY TABLE system privilege. (If O7_DICTIONARY_ACCESSIBILITY=TRUE)
-A user to whom SYS has granted the object privilege DELETE on SYS.AUD$ table.
2)Before deleting any rows you may want to archive the table. You can achive this by creating a table from SYS.AUD$ and export that. Don't export SYS.AUD$ directly.
SQL>CREATE TABLE AUDIT_RECORD TABLESPACE users as select * from SYS.AUD$;
Now export the table as,
SQL> host exp tables=AUDIT_RECORD file=audit_record.dmp
3)To delete all records from audit trail table SYS.AUD$ issue,
SQL>DELETE FROM SYS.AUD$;
To delete all records of particular audited table from the audit trail issue,
SQL>DELETE FROM sys.aud$ WHERE obj$name='&table_nmae';
But deleting in this way will not reduce size on the system tablespace or aud$ table. In order to reduce size follow section 4.
4)Truncate audit table to reduce size.
SQL>CONN / as sysdba
SQL>TRUNCATE TABLE sys.aud$;
Truncate uses the DROP STORAGE clause but keeps only minextents extents, thus only 1 extent.
-SYS user.
-DELETE ANY TABLE system privilege. (If O7_DICTIONARY_ACCESSIBILITY=TRUE)
-A user to whom SYS has granted the object privilege DELETE on SYS.AUD$ table.
2)Before deleting any rows you may want to archive the table. You can achive this by creating a table from SYS.AUD$ and export that. Don't export SYS.AUD$ directly.
SQL>CREATE TABLE AUDIT_RECORD TABLESPACE users as select * from SYS.AUD$;
Now export the table as,
SQL> host exp tables=AUDIT_RECORD file=audit_record.dmp
3)To delete all records from audit trail table SYS.AUD$ issue,
SQL>DELETE FROM SYS.AUD$;
To delete all records of particular audited table from the audit trail issue,
SQL>DELETE FROM sys.aud$ WHERE obj$name='&table_nmae';
But deleting in this way will not reduce size on the system tablespace or aud$ table. In order to reduce size follow section 4.
4)Truncate audit table to reduce size.
SQL>CONN / as sysdba
SQL>TRUNCATE TABLE sys.aud$;
Truncate uses the DROP STORAGE clause but keeps only minextents extents, thus only 1 extent.
How to Reorganize Audit trail SYS.AUD$ Table
You may want to reorganize your auditing table if you optionally delete records from it regularly. In the following steps it is described.
1)Enable restricted session.
In order to ensure consistency in the auditing table temporary disable auditing activity. You can do this by opening database with STARTUP RESTRICT or during open make the system as restricted session.
SQL> connect / as sysdba
Connected.
SQL> alter system enable restricted session;
System altered.
Check if sessions are still connected by,
SQL> select sid, serial#, username from v$session;
If necessary kill these sessions with,
SQL> alter system kill session 'sid , serial#';
2)Copy SYS.AUD$ table.
SQL>CREATE TABLE audit_record TABLESPACE USERS as select * from SYS.AUD$;
You now can take a dump of audit_record.
3)Truncate SYS.AUD$ table.
SQL> truncate table sys.aud$;
Table truncated.
SQL> select count(*) from SYS.AUD$;
COUNT(*)
--------
0
4)Copy the rows back to SYS.AUD$.
SQL> insert into sys.aud$ select * from audit_record;
You can also import it if you exported it in step 2.
5)Drop the audit_record table(optional).
SQL>DROP TABLE audit_record;
1)Enable restricted session.
In order to ensure consistency in the auditing table temporary disable auditing activity. You can do this by opening database with STARTUP RESTRICT or during open make the system as restricted session.
SQL> connect / as sysdba
Connected.
SQL> alter system enable restricted session;
System altered.
Check if sessions are still connected by,
SQL> select sid, serial#, username from v$session;
If necessary kill these sessions with,
SQL> alter system kill session 'sid , serial#';
2)Copy SYS.AUD$ table.
SQL>CREATE TABLE audit_record TABLESPACE USERS as select * from SYS.AUD$;
You now can take a dump of audit_record.
3)Truncate SYS.AUD$ table.
SQL> truncate table sys.aud$;
Table truncated.
SQL> select count(*) from SYS.AUD$;
COUNT(*)
--------
0
4)Copy the rows back to SYS.AUD$.
SQL> insert into sys.aud$ select * from audit_record;
You can also import it if you exported it in step 2.
5)Drop the audit_record table(optional).
SQL>DROP TABLE audit_record;
How to truncate or delete rows from audit trail table sys.aud$
1)Only appropriate privileged user can do delete operation on SYS.AUD$ table. The user must have either of the following privileges.
-SYS user.
-DELETE ANY TABLE system privilege. (If O7_DICTIONARY_ACCESSIBILITY=TRUE)
-A user to whom SYS has granted the object privilege DELETE on SYS.AUD$ table.
2)Before deleting any rows you may want to archive the table. You can achive this by creating a table from SYS.AUD$ and export that. Don't export SYS.AUD$ directly.
SQL>CREATE TABLE AUDIT_RECORD TABLESPACE users as select * from SYS.AUD$;
Now export the table as,
SQL> host exp tables=AUDIT_RECORD file=audit_record.dmp
3)To delete all records from audit trail table SYS.AUD$ issue,
SQL>DELETE FROM SYS.AUD$;
To delete all records of particular audited table from the audit trail issue,
SQL>DELETE FROM sys.aud$ WHERE obj$name='&table_nmae';
But deleting in this way will not reduce size on the system tablespace or aud$ table. In order to reduce size follow section 4.
4)Truncate audit table to reduce size.
SQL>CONN / as sysdba
SQL>TRUNCATE TABLE sys.aud$;
Truncate uses the DROP STORAGE clause but keeps only minextents extents, thus only 1 extent.
-SYS user.
-DELETE ANY TABLE system privilege. (If O7_DICTIONARY_ACCESSIBILITY=TRUE)
-A user to whom SYS has granted the object privilege DELETE on SYS.AUD$ table.
2)Before deleting any rows you may want to archive the table. You can achive this by creating a table from SYS.AUD$ and export that. Don't export SYS.AUD$ directly.
SQL>CREATE TABLE AUDIT_RECORD TABLESPACE users as select * from SYS.AUD$;
Now export the table as,
SQL> host exp tables=AUDIT_RECORD file=audit_record.dmp
3)To delete all records from audit trail table SYS.AUD$ issue,
SQL>DELETE FROM SYS.AUD$;
To delete all records of particular audited table from the audit trail issue,
SQL>DELETE FROM sys.aud$ WHERE obj$name='&table_nmae';
But deleting in this way will not reduce size on the system tablespace or aud$ table. In order to reduce size follow section 4.
4)Truncate audit table to reduce size.
SQL>CONN / as sysdba
SQL>TRUNCATE TABLE sys.aud$;
Truncate uses the DROP STORAGE clause but keeps only minextents extents, thus only 1 extent.
How to make partitioning in Oracle more Quickly
As the table size grows and full table scans happens more frequently then there is no alternative than partitioning in oracle. Partition greatly enhance performance of a query. I will start my partitioning system simply with an example.
In my database the following query took 30~35 seconds to complete. After partitioning the performance increased amazingly and it then took only 1 second.
My query was,
SELECT DISTINCT fs.type, fs.id
, fs.pid, fs.cid
, fs.cr_id, fs.created_date
FROM summary fs where fs.id in
(select fa.id from forms fa where fa.sar in
(select la.sar from login la where la.login_id=1 and fa.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') and fs.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') )
)and mode=0;
After seeing above query I decide to make range partition on column created_date both in summary table and forms table.
Below is the list of procedures of making partition of forms table
1)Get a creation script of the original Table.
I get it by using DBMS_METADATA package.
SQL>SET LONG 99999
SQL>SELECT DBMS_METADATA.GET_DDL('TABLE','FORMS') FROM DUAL;
CREATE TABLE "PROD"."FORMS"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA"
2)Get the creation script of the associated Indexes of the table.
SQL> select dbms_metadata.get_ddl('INDEX',index_name) from dba_indexes where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('INDEX',INDEX_NAME)
--------------------------------------------------------------------------------
CREATE INDEX "PROD"."FA_DATE" ON "PROD"."FORMS" ("CREATED_DATE")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
CREATE INDEX "PROD"."TF_SAR_I" ON "PROD"."FORMS" ("SAR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
3)Get the creation script of the associated Constraints.
SQL> select dbms_metadata.get_ddl('CONSTRAINT',constraint_name)from dba_constraints where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('CONSTRAINT',CONSTRAINT_NAME)
--------------------------------------------------------------------------------
ALTER TABLE "PROD"."FORMS" MODIFY ("ID" NOT NULL ENABLE)
ALTER TABLE "PROD"."FORMS" MODIFY ("CREATED_DATE" NOT NULL ENABLE)
4)Now create a temporary Partitioned Table
Define the range of date to make a partitioned table. Here I made 11 partitions. It's structure will be same as of FORMS table. I named here of partition table as FORMS_PART.
CREATE TABLE "FORMS_PART"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
)partition by range (created_date)
(
partition fa_part1 values less than (to_date('01-JAN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part2 values less than (to_date('01-JUN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part3 values less than (to_date('01-SEP-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part4 values less than (to_date('01-DEC-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part5 values less than (to_date('01-MAR-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part6 values less than (to_date('01-JUN-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part7 values less than (to_date('01-SEP-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part8 values less than (to_date('01-DEC-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part9 values less than (to_date('01-MAR-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part10 values less than (to_date('01-JUN-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part11 values less than (maxvalue) tablespace DATA02);
5)Load data into the temporary partitioned table.
In order to minimize to load time greatly I gave append and nologging hints. Append hints will not generate undo data and nologging hint will generate a minimal redo log. So my data load will be faster.
insert /*+APPEND NOLOGGING */ into FORMS_PART select * from forms;
78474831 rows created.
6) After load data into paritioned table rename original table to a new one. Here I gave it a name from FORMS to FROMS_BAK. You later can dropped it. Also rename the temporary partitioned table to original table name.
SQL> rename forms to forms_bak;
Table renamed.
SQL> rename forms_part to forms;
Table renamed.
7)Rebuild the index as well as create constraints if any.
alter index FA_DATE rebuild;
alter index TF_SAR_I rebuild;
8)Gather partitioned table statistics.
EXEC DBMS_STATS.gather_table_stats('PROD', 'FORMS', cascade => TRUE);
Now have a test your original query and compare performance with the one not partitioned.
In my database the following query took 30~35 seconds to complete. After partitioning the performance increased amazingly and it then took only 1 second.
My query was,
SELECT DISTINCT fs.type, fs.id
, fs.pid, fs.cid
, fs.cr_id, fs.created_date
FROM summary fs where fs.id in
(select fa.id from forms fa where fa.sar in
(select la.sar from login la where la.login_id=1 and fa.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') and fs.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') )
)and mode=0;
After seeing above query I decide to make range partition on column created_date both in summary table and forms table.
Below is the list of procedures of making partition of forms table
1)Get a creation script of the original Table.
I get it by using DBMS_METADATA package.
SQL>SET LONG 99999
SQL>SELECT DBMS_METADATA.GET_DDL('TABLE','FORMS') FROM DUAL;
CREATE TABLE "PROD"."FORMS"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA"
2)Get the creation script of the associated Indexes of the table.
SQL> select dbms_metadata.get_ddl('INDEX',index_name) from dba_indexes where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('INDEX',INDEX_NAME)
--------------------------------------------------------------------------------
CREATE INDEX "PROD"."FA_DATE" ON "PROD"."FORMS" ("CREATED_DATE")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
CREATE INDEX "PROD"."TF_SAR_I" ON "PROD"."FORMS" ("SAR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
3)Get the creation script of the associated Constraints.
SQL> select dbms_metadata.get_ddl('CONSTRAINT',constraint_name)from dba_constraints where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('CONSTRAINT',CONSTRAINT_NAME)
--------------------------------------------------------------------------------
ALTER TABLE "PROD"."FORMS" MODIFY ("ID" NOT NULL ENABLE)
ALTER TABLE "PROD"."FORMS" MODIFY ("CREATED_DATE" NOT NULL ENABLE)
4)Now create a temporary Partitioned Table
Define the range of date to make a partitioned table. Here I made 11 partitions. It's structure will be same as of FORMS table. I named here of partition table as FORMS_PART.
CREATE TABLE "FORMS_PART"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
)partition by range (created_date)
(
partition fa_part1 values less than (to_date('01-JAN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part2 values less than (to_date('01-JUN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part3 values less than (to_date('01-SEP-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part4 values less than (to_date('01-DEC-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part5 values less than (to_date('01-MAR-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part6 values less than (to_date('01-JUN-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part7 values less than (to_date('01-SEP-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part8 values less than (to_date('01-DEC-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part9 values less than (to_date('01-MAR-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part10 values less than (to_date('01-JUN-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part11 values less than (maxvalue) tablespace DATA02);
5)Load data into the temporary partitioned table.
In order to minimize to load time greatly I gave append and nologging hints. Append hints will not generate undo data and nologging hint will generate a minimal redo log. So my data load will be faster.
insert /*+APPEND NOLOGGING */ into FORMS_PART select * from forms;
78474831 rows created.
6) After load data into paritioned table rename original table to a new one. Here I gave it a name from FORMS to FROMS_BAK. You later can dropped it. Also rename the temporary partitioned table to original table name.
SQL> rename forms to forms_bak;
Table renamed.
SQL> rename forms_part to forms;
Table renamed.
7)Rebuild the index as well as create constraints if any.
alter index FA_DATE rebuild;
alter index TF_SAR_I rebuild;
8)Gather partitioned table statistics.
EXEC DBMS_STATS.gather_table_stats('PROD', 'FORMS', cascade => TRUE);
Now have a test your original query and compare performance with the one not partitioned.
How to make partitioning in Oracle more Quickly
As the table size grows and full table scans happens more frequently then there is no alternative than partitioning in oracle. Partition greatly enhance performance of a query. I will start my partitioning system simply with an example.
In my database the following query took 30~35 seconds to complete. After partitioning the performance increased amazingly and it then took only 1 second.
My query was,
SELECT DISTINCT fs.type, fs.id
, fs.pid, fs.cid
, fs.cr_id, fs.created_date
FROM summary fs where fs.id in
(select fa.id from forms fa where fa.sar in
(select la.sar from login la where la.login_id=1 and fa.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') and fs.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') )
)and mode=0;
After seeing above query I decide to make range partition on column created_date both in summary table and forms table.
Below is the list of procedures of making partition of forms table
1)Get a creation script of the original Table.
I get it by using DBMS_METADATA package.
SQL>SET LONG 99999
SQL>SELECT DBMS_METADATA.GET_DDL('TABLE','FORMS') FROM DUAL;
CREATE TABLE "PROD"."FORMS"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA"
2)Get the creation script of the associated Indexes of the table.
SQL> select dbms_metadata.get_ddl('INDEX',index_name) from dba_indexes where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('INDEX',INDEX_NAME)
--------------------------------------------------------------------------------
CREATE INDEX "PROD"."FA_DATE" ON "PROD"."FORMS" ("CREATED_DATE")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
CREATE INDEX "PROD"."TF_SAR_I" ON "PROD"."FORMS" ("SAR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
3)Get the creation script of the associated Constraints.
SQL> select dbms_metadata.get_ddl('CONSTRAINT',constraint_name)from dba_constraints where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('CONSTRAINT',CONSTRAINT_NAME)
--------------------------------------------------------------------------------
ALTER TABLE "PROD"."FORMS" MODIFY ("ID" NOT NULL ENABLE)
ALTER TABLE "PROD"."FORMS" MODIFY ("CREATED_DATE" NOT NULL ENABLE)
4)Now create a temporary Partitioned Table
Define the range of date to make a partitioned table. Here I made 11 partitions. It's structure will be same as of FORMS table. I named here of partition table as FORMS_PART.
CREATE TABLE "FORMS_PART"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
)partition by range (created_date)
(
partition fa_part1 values less than (to_date('01-JAN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part2 values less than (to_date('01-JUN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part3 values less than (to_date('01-SEP-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part4 values less than (to_date('01-DEC-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part5 values less than (to_date('01-MAR-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part6 values less than (to_date('01-JUN-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part7 values less than (to_date('01-SEP-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part8 values less than (to_date('01-DEC-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part9 values less than (to_date('01-MAR-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part10 values less than (to_date('01-JUN-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part11 values less than (maxvalue) tablespace DATA02);
5)Load data into the temporary partitioned table.
In order to minimize to load time greatly I gave append and nologging hints. Append hints will not generate undo data and nologging hint will generate a minimal redo log. So my data load will be faster.
insert /*+APPEND NOLOGGING */ into FORMS_PART select * from forms;
78474831 rows created.
6) After load data into paritioned table rename original table to a new one. Here I gave it a name from FORMS to FROMS_BAK. You later can dropped it. Also rename the temporary partitioned table to original table name.
SQL> rename forms to forms_bak;
Table renamed.
SQL> rename forms_part to forms;
Table renamed.
7)Rebuild the index as well as create constraints if any.
alter index FA_DATE rebuild;
alter index TF_SAR_I rebuild;
8)Gather partitioned table statistics.
EXEC DBMS_STATS.gather_table_stats('PROD', 'FORMS', cascade => TRUE);
Now have a test your original query and compare performance with the one not partitioned.
In my database the following query took 30~35 seconds to complete. After partitioning the performance increased amazingly and it then took only 1 second.
My query was,
SELECT DISTINCT fs.type, fs.id
, fs.pid, fs.cid
, fs.cr_id, fs.created_date
FROM summary fs where fs.id in
(select fa.id from forms fa where fa.sar in
(select la.sar from login la where la.login_id=1 and fa.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') and fs.created_date BETWEEN to_date('1-MAY-2008') AND to_date('21-SEP-2008') )
)and mode=0;
After seeing above query I decide to make range partition on column created_date both in summary table and forms table.
Below is the list of procedures of making partition of forms table
1)Get a creation script of the original Table.
I get it by using DBMS_METADATA package.
SQL>SET LONG 99999
SQL>SELECT DBMS_METADATA.GET_DDL('TABLE','FORMS') FROM DUAL;
CREATE TABLE "PROD"."FORMS"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA"
2)Get the creation script of the associated Indexes of the table.
SQL> select dbms_metadata.get_ddl('INDEX',index_name) from dba_indexes where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('INDEX',INDEX_NAME)
--------------------------------------------------------------------------------
CREATE INDEX "PROD"."FA_DATE" ON "PROD"."FORMS" ("CREATED_DATE")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
CREATE INDEX "PROD"."TF_SAR_I" ON "PROD"."FORMS" ("SAR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 10485760 NEXT 10485760 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA02"
3)Get the creation script of the associated Constraints.
SQL> select dbms_metadata.get_ddl('CONSTRAINT',constraint_name)from dba_constraints where owner='PROD' and table_name='FORMS';
DBMS_METADATA.GET_DDL('CONSTRAINT',CONSTRAINT_NAME)
--------------------------------------------------------------------------------
ALTER TABLE "PROD"."FORMS" MODIFY ("ID" NOT NULL ENABLE)
ALTER TABLE "PROD"."FORMS" MODIFY ("CREATED_DATE" NOT NULL ENABLE)
4)Now create a temporary Partitioned Table
Define the range of date to make a partitioned table. Here I made 11 partitions. It's structure will be same as of FORMS table. I named here of partition table as FORMS_PART.
CREATE TABLE "FORMS_PART"
( "ID" NUMBER NOT NULL ENABLE,
"SAR" VARCHAR2(32) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (3) NOT NULL ENABLE
)partition by range (created_date)
(
partition fa_part1 values less than (to_date('01-JAN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part2 values less than (to_date('01-JUN-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part3 values less than (to_date('01-SEP-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part4 values less than (to_date('01-DEC-2006','DD-MON-YYYY')) tablespace DATA02,
partition fa_part5 values less than (to_date('01-MAR-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part6 values less than (to_date('01-JUN-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part7 values less than (to_date('01-SEP-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part8 values less than (to_date('01-DEC-2007','DD-MON-YYYY')) tablespace DATA02,
partition fa_part9 values less than (to_date('01-MAR-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part10 values less than (to_date('01-JUN-2008','DD-MON-YYYY')) tablespace DATA02,
partition fa_part11 values less than (maxvalue) tablespace DATA02);
5)Load data into the temporary partitioned table.
In order to minimize to load time greatly I gave append and nologging hints. Append hints will not generate undo data and nologging hint will generate a minimal redo log. So my data load will be faster.
insert /*+APPEND NOLOGGING */ into FORMS_PART select * from forms;
78474831 rows created.
6) After load data into paritioned table rename original table to a new one. Here I gave it a name from FORMS to FROMS_BAK. You later can dropped it. Also rename the temporary partitioned table to original table name.
SQL> rename forms to forms_bak;
Table renamed.
SQL> rename forms_part to forms;
Table renamed.
7)Rebuild the index as well as create constraints if any.
alter index FA_DATE rebuild;
alter index TF_SAR_I rebuild;
8)Gather partitioned table statistics.
EXEC DBMS_STATS.gather_table_stats('PROD', 'FORMS', cascade => TRUE);
Now have a test your original query and compare performance with the one not partitioned.
Tuesday, January 13, 2009
How to move LOB data to another tablespace
We know with the ALTER TABLE .. MOVE clause we can relocate data of a nonpartitioned table or of a partition of a partitioned table into a new segment.
If you want to make no other changes to the table other than rebuilding it then your statement is simply,
SQL>ALTER TABLE table_name MOVE;
Or if you want to move it to another tablespace then specify,
SQL>ALTER TABLE table_name MOVE TABLESPACE tablespace_name;
With this statement it does not affect any of the lob segments associated with the lob columns in the table.
If you want to move only lob segment to a new tablespace then your command will be,
ALTER TABLE table_name MOVE LOB(lob_columnname) STORE AS (TABLESPACE new_tablespace_name);
Along with the log segment you can also move the table as well as storage attribute of table and log by following query,
ALTER TABLE table_name MOVE
TABLESPACE new_tablespace STORAGE(new_storage)
LOB (lobcol) STORE AS
(TABLESPACE new_tablespace STORAGE (new_storage));
If you want to move all the lobs contained in a tablespace of a particular user then you can follow .
Let's have a look lob column_name and table_name of the specified tablespace of owner SHAIK.
Now execute the script move_table.scr after modifying it.
SQL>@move_table.scr
If you want to make no other changes to the table other than rebuilding it then your statement is simply,
SQL>ALTER TABLE table_name MOVE;
Or if you want to move it to another tablespace then specify,
SQL>ALTER TABLE table_name MOVE TABLESPACE tablespace_name;
With this statement it does not affect any of the lob segments associated with the lob columns in the table.
If you want to move only lob segment to a new tablespace then your command will be,
ALTER TABLE table_name MOVE LOB(lob_columnname) STORE AS (TABLESPACE new_tablespace_name);
Along with the log segment you can also move the table as well as storage attribute of table and log by following query,
ALTER TABLE table_name MOVE
TABLESPACE new_tablespace STORAGE(new_storage)
LOB (lobcol) STORE AS
(TABLESPACE new_tablespace STORAGE (new_storage));
If you want to move all the lobs contained in a tablespace of a particular user then you can follow .
Let's have a look lob column_name and table_name of the specified tablespace of owner SHAIK.
SQL> col COLUMN_NAME format a20
SQL> col TABLE_NAME format a20
SQL> select owner, table_name, column_name from dba_lobs where segment_name in (select segment_name from dba_segments where tablespace_name='USERS' and segment_type='LOBSEGMENT' and owner='SHAIK');
OWNER TABLE_NAME COLUMN_NAME
------------------------------ -------------------- --------------------
SHAIK TEST_LONG_LOB B
SHAIK LOB_TAB COL2_LOB
SHAIK LOB_TAB2 COL3
SHAIK LOB_TAB2 COL2_LOB
set pagesize 0
set heading off
set lines 130
set feedback off
set verify off
set echo off
set termout off
spool move_table.scr
select 'alter table '||owner||'.'||table_name ||' move lob (' ||column_name||')' ||
'store as (tablespace DATA02);' from dba_lobs where segment_name in (select segment_name from dba_segments where tablespace_name='USERS' and owner='SHAIK' and segment_type='LOBSEGMENT');
spool off
Now execute the script move_table.scr after modifying it.
SQL>@move_table.scr
How to move LOB data to another tablespace
We know with the ALTER TABLE .. MOVE clause we can relocate data of a nonpartitioned table or of a partition of a partitioned table into a new segment.
If you want to make no other changes to the table other than rebuilding it then your statement is simply,
SQL>ALTER TABLE table_name MOVE;
Or if you want to move it to another tablespace then specify,
SQL>ALTER TABLE table_name MOVE TABLESPACE tablespace_name;
With this statement it does not affect any of the lob segments associated with the lob columns in the table.
If you want to move only lob segment to a new tablespace then your command will be,
ALTER TABLE table_name MOVE LOB(lob_columnname) STORE AS (TABLESPACE new_tablespace_name);
Along with the log segment you can also move the table as well as storage attribute of table and log by following query,
ALTER TABLE table_name MOVE
TABLESPACE new_tablespace STORAGE(new_storage)
LOB (lobcol) STORE AS
(TABLESPACE new_tablespace STORAGE (new_storage));
If you want to move all the lobs contained in a tablespace of a particular user then you can follow .
Let's have a look lob column_name and table_name of the specified tablespace of owner SHAIK.
Now execute the script move_table.scr after modifying it.
SQL>@move_table.scr
If you want to make no other changes to the table other than rebuilding it then your statement is simply,
SQL>ALTER TABLE table_name MOVE;
Or if you want to move it to another tablespace then specify,
SQL>ALTER TABLE table_name MOVE TABLESPACE tablespace_name;
With this statement it does not affect any of the lob segments associated with the lob columns in the table.
If you want to move only lob segment to a new tablespace then your command will be,
ALTER TABLE table_name MOVE LOB(lob_columnname) STORE AS (TABLESPACE new_tablespace_name);
Along with the log segment you can also move the table as well as storage attribute of table and log by following query,
ALTER TABLE table_name MOVE
TABLESPACE new_tablespace STORAGE(new_storage)
LOB (lobcol) STORE AS
(TABLESPACE new_tablespace STORAGE (new_storage));
If you want to move all the lobs contained in a tablespace of a particular user then you can follow .
Let's have a look lob column_name and table_name of the specified tablespace of owner SHAIK.
SQL> col COLUMN_NAME format a20
SQL> col TABLE_NAME format a20
SQL> select owner, table_name, column_name from dba_lobs where segment_name in (select segment_name from dba_segments where tablespace_name='USERS' and segment_type='LOBSEGMENT' and owner='SHAIK');
OWNER TABLE_NAME COLUMN_NAME
------------------------------ -------------------- --------------------
SHAIK TEST_LONG_LOB B
SHAIK LOB_TAB COL2_LOB
SHAIK LOB_TAB2 COL3
SHAIK LOB_TAB2 COL2_LOB
set pagesize 0
set heading off
set lines 130
set feedback off
set verify off
set echo off
set termout off
spool move_table.scr
select 'alter table '||owner||'.'||table_name ||' move lob (' ||column_name||')' ||
'store as (tablespace DATA02);' from dba_lobs where segment_name in (select segment_name from dba_segments where tablespace_name='USERS' and owner='SHAIK' and segment_type='LOBSEGMENT');
spool off
Now execute the script move_table.scr after modifying it.
SQL>@move_table.scr
How to catalog and uncatalog a backup to RMAN repository
Catalog Backup
Whenever we take any backup through RMAN, in the repository information of the backup is recorded. The RMAN respository can be either controlfile or recovery catalog. However if I take a backup through OS command then RMAN does not aware of that and hence recorded are not reflected in the repository. This is also true whenever we create a new controlfile or a backup taken by RMAN is transferred to another place using OS command then controlfile/recovery catalog does not know about the prior backups of the database. So in order to restore database with a new created controlfile we need to inform RMAN about the backups taken before so that it can pick one to restore.
This task can be done by catalog command in RMAN. With catalog command it can
-Add information of backup pieces and image copies in the repository that are on disk.
-Record a datafile copy as a level 0 incremental backup in the RMAN repository.
-Record of a datafile copy that was taken by OS.
But CATALOG command has some restrictions. It can't do the following.
-Can't catalog a file that belong to different database.
-Can't catalog a backup piece that exists on an sbt device.
Examples of Catalog command
1)Catalog an archive log: To catalog two archived logs named /oracle/oradata/shaik/arc001_223.arc and /oracle/oradata/shaik/arc001_224.arc the command is,
RMAN>CATALOG ARCHIVELOG '/oracle/oradata/shaik/arc001_223.arc', '/oracle/oradata/shaik/arc001_224.arc';
2)Catalog a file copy as an incremental backup: To catalog datafile copy '/oradata/backup/users01.dbf' as an incremental level 0 backup your command will be,
RMAN>CATALOG DATAFILECOPY '/oradata/backup/users01.dbf' LEVEL 0;
Note that this datafile copy was taken backup either using the RMAN BACKUP AS COPY command, or by using operating system utilities in conjunction with ALTER TABLESPACE BEGIN/END BACKUP.
3)Catalog multiple copies in a directory: To catalog all valid backups from directory /tmp/backups issue,
RMAN>CATALOG START WITH '/tmp/backups' NOPROMPT;
4)Catalog files in the flash recovery area: To catalog all files in the currently enabled flash recovery area without prompting the user for each one issue,
RMAN>CATALOG RECOVERY AREA NOPROMPT;
5)Catalog backup pieces: To catalog backup piece /oradata2/o4jccf4 issue,
RMAN>CATALOG BACKUPPIECE '/oradata2/o4jccf4';
Uncatalog Backup
In many cases you need to uncatalog command. Suppose you do not want a specific backup or copy to be eligible to be restored but also do not want to delete it.
To uncatalog all archived logs issue,
RMAN>CHANGE ARCHIVELOG ALL UNCATALOG;
To uncataog tablespace USERS issue,
RMAN>CHANGE BACKUP OF TABLESPACE USERS UNCATALOG;
To uncatalog a backuppiece name /oradata2/oft7qq issue,
RMAN>CHANGE BACKUPPIECE '/oradata2/oft7qq' UNCATALOG;
Whenever we take any backup through RMAN, in the repository information of the backup is recorded. The RMAN respository can be either controlfile or recovery catalog. However if I take a backup through OS command then RMAN does not aware of that and hence recorded are not reflected in the repository. This is also true whenever we create a new controlfile or a backup taken by RMAN is transferred to another place using OS command then controlfile/recovery catalog does not know about the prior backups of the database. So in order to restore database with a new created controlfile we need to inform RMAN about the backups taken before so that it can pick one to restore.
This task can be done by catalog command in RMAN. With catalog command it can
-Add information of backup pieces and image copies in the repository that are on disk.
-Record a datafile copy as a level 0 incremental backup in the RMAN repository.
-Record of a datafile copy that was taken by OS.
But CATALOG command has some restrictions. It can't do the following.
-Can't catalog a file that belong to different database.
-Can't catalog a backup piece that exists on an sbt device.
Examples of Catalog command
1)Catalog an archive log: To catalog two archived logs named /oracle/oradata/shaik/arc001_223.arc and /oracle/oradata/shaik/arc001_224.arc the command is,
RMAN>CATALOG ARCHIVELOG '/oracle/oradata/shaik/arc001_223.arc', '/oracle/oradata/shaik/arc001_224.arc';
2)Catalog a file copy as an incremental backup: To catalog datafile copy '/oradata/backup/users01.dbf' as an incremental level 0 backup your command will be,
RMAN>CATALOG DATAFILECOPY '/oradata/backup/users01.dbf' LEVEL 0;
Note that this datafile copy was taken backup either using the RMAN BACKUP AS COPY command, or by using operating system utilities in conjunction with ALTER TABLESPACE BEGIN/END BACKUP.
3)Catalog multiple copies in a directory: To catalog all valid backups from directory /tmp/backups issue,
RMAN>CATALOG START WITH '/tmp/backups' NOPROMPT;
4)Catalog files in the flash recovery area: To catalog all files in the currently enabled flash recovery area without prompting the user for each one issue,
RMAN>CATALOG RECOVERY AREA NOPROMPT;
5)Catalog backup pieces: To catalog backup piece /oradata2/o4jccf4 issue,
RMAN>CATALOG BACKUPPIECE '/oradata2/o4jccf4';
Uncatalog Backup
In many cases you need to uncatalog command. Suppose you do not want a specific backup or copy to be eligible to be restored but also do not want to delete it.
To uncatalog all archived logs issue,
RMAN>CHANGE ARCHIVELOG ALL UNCATALOG;
To uncataog tablespace USERS issue,
RMAN>CHANGE BACKUP OF TABLESPACE USERS UNCATALOG;
To uncatalog a backuppiece name /oradata2/oft7qq issue,
RMAN>CHANGE BACKUPPIECE '/oradata2/oft7qq' UNCATALOG;
How to catalog and uncatalog a backup to RMAN repository
Catalog Backup
Whenever we take any backup through RMAN, in the repository information of the backup is recorded. The RMAN respository can be either controlfile or recovery catalog. However if I take a backup through OS command then RMAN does not aware of that and hence recorded are not reflected in the repository. This is also true whenever we create a new controlfile or a backup taken by RMAN is transferred to another place using OS command then controlfile/recovery catalog does not know about the prior backups of the database. So in order to restore database with a new created controlfile we need to inform RMAN about the backups taken before so that it can pick one to restore.
This task can be done by catalog command in RMAN. With catalog command it can
-Add information of backup pieces and image copies in the repository that are on disk.
-Record a datafile copy as a level 0 incremental backup in the RMAN repository.
-Record of a datafile copy that was taken by OS.
But CATALOG command has some restrictions. It can't do the following.
-Can't catalog a file that belong to different database.
-Can't catalog a backup piece that exists on an sbt device.
Examples of Catalog command
1)Catalog an archive log: To catalog two archived logs named /oracle/oradata/shaik/arc001_223.arc and /oracle/oradata/shaik/arc001_224.arc the command is,
RMAN>CATALOG ARCHIVELOG '/oracle/oradata/shaik/arc001_223.arc', '/oracle/oradata/shaik/arc001_224.arc';
2)Catalog a file copy as an incremental backup: To catalog datafile copy '/oradata/backup/users01.dbf' as an incremental level 0 backup your command will be,
RMAN>CATALOG DATAFILECOPY '/oradata/backup/users01.dbf' LEVEL 0;
Note that this datafile copy was taken backup either using the RMAN BACKUP AS COPY command, or by using operating system utilities in conjunction with ALTER TABLESPACE BEGIN/END BACKUP.
3)Catalog multiple copies in a directory: To catalog all valid backups from directory /tmp/backups issue,
RMAN>CATALOG START WITH '/tmp/backups' NOPROMPT;
4)Catalog files in the flash recovery area: To catalog all files in the currently enabled flash recovery area without prompting the user for each one issue,
RMAN>CATALOG RECOVERY AREA NOPROMPT;
5)Catalog backup pieces: To catalog backup piece /oradata2/o4jccf4 issue,
RMAN>CATALOG BACKUPPIECE '/oradata2/o4jccf4';
Uncatalog Backup
In many cases you need to uncatalog command. Suppose you do not want a specific backup or copy to be eligible to be restored but also do not want to delete it.
To uncatalog all archived logs issue,
RMAN>CHANGE ARCHIVELOG ALL UNCATALOG;
To uncataog tablespace USERS issue,
RMAN>CHANGE BACKUP OF TABLESPACE USERS UNCATALOG;
To uncatalog a backuppiece name /oradata2/oft7qq issue,
RMAN>CHANGE BACKUPPIECE '/oradata2/oft7qq' UNCATALOG;
Whenever we take any backup through RMAN, in the repository information of the backup is recorded. The RMAN respository can be either controlfile or recovery catalog. However if I take a backup through OS command then RMAN does not aware of that and hence recorded are not reflected in the repository. This is also true whenever we create a new controlfile or a backup taken by RMAN is transferred to another place using OS command then controlfile/recovery catalog does not know about the prior backups of the database. So in order to restore database with a new created controlfile we need to inform RMAN about the backups taken before so that it can pick one to restore.
This task can be done by catalog command in RMAN. With catalog command it can
-Add information of backup pieces and image copies in the repository that are on disk.
-Record a datafile copy as a level 0 incremental backup in the RMAN repository.
-Record of a datafile copy that was taken by OS.
But CATALOG command has some restrictions. It can't do the following.
-Can't catalog a file that belong to different database.
-Can't catalog a backup piece that exists on an sbt device.
Examples of Catalog command
1)Catalog an archive log: To catalog two archived logs named /oracle/oradata/shaik/arc001_223.arc and /oracle/oradata/shaik/arc001_224.arc the command is,
RMAN>CATALOG ARCHIVELOG '/oracle/oradata/shaik/arc001_223.arc', '/oracle/oradata/shaik/arc001_224.arc';
2)Catalog a file copy as an incremental backup: To catalog datafile copy '/oradata/backup/users01.dbf' as an incremental level 0 backup your command will be,
RMAN>CATALOG DATAFILECOPY '/oradata/backup/users01.dbf' LEVEL 0;
Note that this datafile copy was taken backup either using the RMAN BACKUP AS COPY command, or by using operating system utilities in conjunction with ALTER TABLESPACE BEGIN/END BACKUP.
3)Catalog multiple copies in a directory: To catalog all valid backups from directory /tmp/backups issue,
RMAN>CATALOG START WITH '/tmp/backups' NOPROMPT;
4)Catalog files in the flash recovery area: To catalog all files in the currently enabled flash recovery area without prompting the user for each one issue,
RMAN>CATALOG RECOVERY AREA NOPROMPT;
5)Catalog backup pieces: To catalog backup piece /oradata2/o4jccf4 issue,
RMAN>CATALOG BACKUPPIECE '/oradata2/o4jccf4';
Uncatalog Backup
In many cases you need to uncatalog command. Suppose you do not want a specific backup or copy to be eligible to be restored but also do not want to delete it.
To uncatalog all archived logs issue,
RMAN>CHANGE ARCHIVELOG ALL UNCATALOG;
To uncataog tablespace USERS issue,
RMAN>CHANGE BACKUP OF TABLESPACE USERS UNCATALOG;
To uncatalog a backuppiece name /oradata2/oft7qq issue,
RMAN>CHANGE BACKUPPIECE '/oradata2/oft7qq' UNCATALOG;
Monday, January 12, 2009
How to avoid of recreating pfile or spfile if any error in spfile
Suppose I have done some wrong-edit inside spfile using ALTER SYSTEM SET ... SCOPE=SPFILE from database. Now the next startup process of my database will fail with oracle errors. The conventional approach of solution to this problem is,
1)Connect to SQL*plus as sysdba
2)Create pfile from the spfile.
3)Edit the pfile and correct the parameter settings.
4)Create spfile from the edited correct pfile.
5)Startup your database with the spfile.
But we can omit these steps easily by just creating a pfile and invoke the name of the spfile inside the pfile. After invoking spfile parameter inside pfile in the next line specify the name of the parameter which is cause problem of startup. In this case we gave multiple values of the parameter and oracle will use the last one. So override the invalid parameter value with the valid one and thus will startup the create. After startup we can set valid value in the spfile.
The following example will make you a clear idea.
Step 1:
I have set background_dump_dest parameter to an invalid location in the spfile.
SQL> alter system set background_dump_dest='/oradata2/testing' scope=spfile;
System altered.
Now shutdown the database and start it up.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00444: background process "MMAN" failed while starting
ORA-07446: sdnfy: bad value '' for parameter .
Step 2:
Startup fails as we set invalid location to background_dump_dest. Now create a pfile with an entry of spfile and give the location of the spfile. After specify specify the parameter which cause problem(background_dump_dest) and use the valid value. This setting will override the setting inside spfile and thus will help to startup the database.
SQL> !vi /oradata2/mypfile.ora
spfile=/oracle/app/oracle/product/10.2.0/db_1/dbs/spfileshaik.ora
background_dump_dest='/oradata1'
Step 3:
Now start the database with newly created pfile. In fact spfile.
SQL> startup pfile=/oradata2/mypfile.ora
ORACLE instance started.
Total System Global Area 234881024 bytes
Fixed Size 2019800 bytes
Variable Size 113249832 bytes
Database Buffers 113246208 bytes
Redo Buffers 6365184 bytes
Database mounted.
Database opened.
Step 4:
And it worked!!! Now set valid value to the parameter background_dump_dest inside spfile.
SQL> alter system set background_dump_dest='/oradata1' scope=spfile;
System altered.
In this way we can minimize our steps as well as downtime.
1)Connect to SQL*plus as sysdba
2)Create pfile from the spfile.
3)Edit the pfile and correct the parameter settings.
4)Create spfile from the edited correct pfile.
5)Startup your database with the spfile.
But we can omit these steps easily by just creating a pfile and invoke the name of the spfile inside the pfile. After invoking spfile parameter inside pfile in the next line specify the name of the parameter which is cause problem of startup. In this case we gave multiple values of the parameter and oracle will use the last one. So override the invalid parameter value with the valid one and thus will startup the create. After startup we can set valid value in the spfile.
The following example will make you a clear idea.
Step 1:
I have set background_dump_dest parameter to an invalid location in the spfile.
SQL> alter system set background_dump_dest='/oradata2/testing' scope=spfile;
System altered.
Now shutdown the database and start it up.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00444: background process "MMAN" failed while starting
ORA-07446: sdnfy: bad value '' for parameter .
Step 2:
Startup fails as we set invalid location to background_dump_dest. Now create a pfile with an entry of spfile and give the location of the spfile. After specify specify the parameter which cause problem(background_dump_dest) and use the valid value. This setting will override the setting inside spfile and thus will help to startup the database.
SQL> !vi /oradata2/mypfile.ora
spfile=/oracle/app/oracle/product/10.2.0/db_1/dbs/spfileshaik.ora
background_dump_dest='/oradata1'
Step 3:
Now start the database with newly created pfile. In fact spfile.
SQL> startup pfile=/oradata2/mypfile.ora
ORACLE instance started.
Total System Global Area 234881024 bytes
Fixed Size 2019800 bytes
Variable Size 113249832 bytes
Database Buffers 113246208 bytes
Redo Buffers 6365184 bytes
Database mounted.
Database opened.
Step 4:
And it worked!!! Now set valid value to the parameter background_dump_dest inside spfile.
SQL> show parameter background_dump_dest
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oradata1
SQL> alter system set background_dump_dest='/oradata1' scope=spfile;
System altered.
In this way we can minimize our steps as well as downtime.
How to avoid of recreating pfile or spfile if any error in spfile
Suppose I have done some wrong-edit inside spfile using ALTER SYSTEM SET ... SCOPE=SPFILE from database. Now the next startup process of my database will fail with oracle errors. The conventional approach of solution to this problem is,
1)Connect to SQL*plus as sysdba
2)Create pfile from the spfile.
3)Edit the pfile and correct the parameter settings.
4)Create spfile from the edited correct pfile.
5)Startup your database with the spfile.
But we can omit these steps easily by just creating a pfile and invoke the name of the spfile inside the pfile. After invoking spfile parameter inside pfile in the next line specify the name of the parameter which is cause problem of startup. In this case we gave multiple values of the parameter and oracle will use the last one. So override the invalid parameter value with the valid one and thus will startup the create. After startup we can set valid value in the spfile.
The following example will make you a clear idea.
Step 1:
I have set background_dump_dest parameter to an invalid location in the spfile.
SQL> alter system set background_dump_dest='/oradata2/testing' scope=spfile;
System altered.
Now shutdown the database and start it up.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00444: background process "MMAN" failed while starting
ORA-07446: sdnfy: bad value '' for parameter .
Step 2:
Startup fails as we set invalid location to background_dump_dest. Now create a pfile with an entry of spfile and give the location of the spfile. After specify specify the parameter which cause problem(background_dump_dest) and use the valid value. This setting will override the setting inside spfile and thus will help to startup the database.
SQL> !vi /oradata2/mypfile.ora
spfile=/oracle/app/oracle/product/10.2.0/db_1/dbs/spfileshaik.ora
background_dump_dest='/oradata1'
Step 3:
Now start the database with newly created pfile. In fact spfile.
SQL> startup pfile=/oradata2/mypfile.ora
ORACLE instance started.
Total System Global Area 234881024 bytes
Fixed Size 2019800 bytes
Variable Size 113249832 bytes
Database Buffers 113246208 bytes
Redo Buffers 6365184 bytes
Database mounted.
Database opened.
Step 4:
And it worked!!! Now set valid value to the parameter background_dump_dest inside spfile.
SQL> alter system set background_dump_dest='/oradata1' scope=spfile;
System altered.
In this way we can minimize our steps as well as downtime.
1)Connect to SQL*plus as sysdba
2)Create pfile from the spfile.
3)Edit the pfile and correct the parameter settings.
4)Create spfile from the edited correct pfile.
5)Startup your database with the spfile.
But we can omit these steps easily by just creating a pfile and invoke the name of the spfile inside the pfile. After invoking spfile parameter inside pfile in the next line specify the name of the parameter which is cause problem of startup. In this case we gave multiple values of the parameter and oracle will use the last one. So override the invalid parameter value with the valid one and thus will startup the create. After startup we can set valid value in the spfile.
The following example will make you a clear idea.
Step 1:
I have set background_dump_dest parameter to an invalid location in the spfile.
SQL> alter system set background_dump_dest='/oradata2/testing' scope=spfile;
System altered.
Now shutdown the database and start it up.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00444: background process "MMAN" failed while starting
ORA-07446: sdnfy: bad value '' for parameter .
Step 2:
Startup fails as we set invalid location to background_dump_dest. Now create a pfile with an entry of spfile and give the location of the spfile. After specify specify the parameter which cause problem(background_dump_dest) and use the valid value. This setting will override the setting inside spfile and thus will help to startup the database.
SQL> !vi /oradata2/mypfile.ora
spfile=/oracle/app/oracle/product/10.2.0/db_1/dbs/spfileshaik.ora
background_dump_dest='/oradata1'
Step 3:
Now start the database with newly created pfile. In fact spfile.
SQL> startup pfile=/oradata2/mypfile.ora
ORACLE instance started.
Total System Global Area 234881024 bytes
Fixed Size 2019800 bytes
Variable Size 113249832 bytes
Database Buffers 113246208 bytes
Redo Buffers 6365184 bytes
Database mounted.
Database opened.
Step 4:
And it worked!!! Now set valid value to the parameter background_dump_dest inside spfile.
SQL> show parameter background_dump_dest
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oradata1
SQL> alter system set background_dump_dest='/oradata1' scope=spfile;
System altered.
In this way we can minimize our steps as well as downtime.
How to get port number list of EM and isqlplus
You can get your portlist information of enterprise manger or isqlplus or others web services in the location of $ORACLE_HOME/install/portlist.ini.
On my system the output is,
bash-3.00$ cat /oracle/app/oracle/product/10.2.0/db_1/install/portlist.ini
iSQL*Plus HTTP port number =5560
Enterprise Manager Console HTTP Port (DBASE) = 1158
Enterprise Manager Agent Port (DBASE) = 3938
Enterprise Manager Console HTTP Port (shaikdba) = 5500
Enterprise Manager Agent Port (shaikdba) = 1830
Enterprise Manager Console HTTP Port (shaik) = 5501
Enterprise Manager Agent Port (shaik) = 1831
But note that the ports that are listed in portlist.ini file were assigned during the installation. This file is not updated if port numbers are changed after the installation.
On my system the output is,
bash-3.00$ cat /oracle/app/oracle/product/10.2.0/db_1/install/portlist.ini
iSQL*Plus HTTP port number =5560
Enterprise Manager Console HTTP Port (DBASE) = 1158
Enterprise Manager Agent Port (DBASE) = 3938
Enterprise Manager Console HTTP Port (shaikdba) = 5500
Enterprise Manager Agent Port (shaikdba) = 1830
Enterprise Manager Console HTTP Port (shaik) = 5501
Enterprise Manager Agent Port (shaik) = 1831
But note that the ports that are listed in portlist.ini file were assigned during the installation. This file is not updated if port numbers are changed after the installation.
How to get port number list of EM and isqlplus
You can get your portlist information of enterprise manger or isqlplus or others web services in the location of $ORACLE_HOME/install/portlist.ini.
On my system the output is,
bash-3.00$ cat /oracle/app/oracle/product/10.2.0/db_1/install/portlist.ini
iSQL*Plus HTTP port number =5560
Enterprise Manager Console HTTP Port (DBASE) = 1158
Enterprise Manager Agent Port (DBASE) = 3938
Enterprise Manager Console HTTP Port (shaikdba) = 5500
Enterprise Manager Agent Port (shaikdba) = 1830
Enterprise Manager Console HTTP Port (shaik) = 5501
Enterprise Manager Agent Port (shaik) = 1831
But note that the ports that are listed in portlist.ini file were assigned during the installation. This file is not updated if port numbers are changed after the installation.
On my system the output is,
bash-3.00$ cat /oracle/app/oracle/product/10.2.0/db_1/install/portlist.ini
iSQL*Plus HTTP port number =5560
Enterprise Manager Console HTTP Port (DBASE) = 1158
Enterprise Manager Agent Port (DBASE) = 3938
Enterprise Manager Console HTTP Port (shaikdba) = 5500
Enterprise Manager Agent Port (shaikdba) = 1830
Enterprise Manager Console HTTP Port (shaik) = 5501
Enterprise Manager Agent Port (shaik) = 1831
But note that the ports that are listed in portlist.ini file were assigned during the installation. This file is not updated if port numbers are changed after the installation.
How to recover or recreate temporary tablespace in 10g
In database you may discover that your temporary tablespace is deleted from OS or it might got corrupted. In order to get it back you might think about recover it. The recovery process is simply recover the temporary file from backup and roll the file forward using archived log files if you are in archivelog mode.
Another solution is simply drop the temporary tablespace and then create a new one and assign new one to the database users.
In order to do that follow the steps here.
1)Find out the temporary datafiles.
2)Make the affected temporary files offline.
SQL> Alter database tempfile 1,2,4 offline;
Database altered.
3)Create a new temporary tablespace and make it database default tablespace.
SQL> create temporary tablespace temp01 tempfile '/oradata2/temp.dbf' size 10M;
Tablespace created.
SQL> alter database default temporary tablespace temp01;
Database altered.
3)Check for users who are not pointed to this default temporary tablespaces. Make this default for those users also.
4)Explicitly assign temporary tablespace for users TEST2 and SHAIK
SQL> alter user shaik temporary tablespace temp01;
User altered.
SQL> alter user test2 temporary tablespace temp01;
User altered.
3)Drop the old temporary tablespace.
SQL> drop tablespace temp;
Tablespace dropped.
SQL> drop tablespace temp2;
Tablespace dropped.
SQL> drop tablespace temp3;
Tablespace dropped.
Another solution is simply drop the temporary tablespace and then create a new one and assign new one to the database users.
In order to do that follow the steps here.
1)Find out the temporary datafiles.
SQL> col file_name format a50
SQL> set linesize 200
SQL> select file_name,file_id, tablespace_name from dba_temp_files;
FILE_NAME FILE_ID TABLESPACE_NAME
-------------------------------------------------- ---------- ------------------------------
/oradata2/temp2.dbf 1 TEMP2
/oradata2/temp.dbf 2 TEMP
/oradata2/temp3.dbf 4 TEMP3
2)Make the affected temporary files offline.
SQL> Alter database tempfile 1,2,4 offline;
Database altered.
3)Create a new temporary tablespace and make it database default tablespace.
SQL> create temporary tablespace temp01 tempfile '/oradata2/temp.dbf' size 10M;
Tablespace created.
SQL> alter database default temporary tablespace temp01;
Database altered.
3)Check for users who are not pointed to this default temporary tablespaces. Make this default for those users also.
SQL> select temporary_tablespace , username from dba_users where temporary_tablespace<>'TEMP01';
TEMPORARY_TABLESPACE USERNAME
------------------------------ ------------------------------
TEMP TEST2
TEMP2 SHAIK
4)Explicitly assign temporary tablespace for users TEST2 and SHAIK
SQL> alter user shaik temporary tablespace temp01;
User altered.
SQL> alter user test2 temporary tablespace temp01;
User altered.
3)Drop the old temporary tablespace.
SQL> drop tablespace temp;
Tablespace dropped.
SQL> drop tablespace temp2;
Tablespace dropped.
SQL> drop tablespace temp3;
Tablespace dropped.
How to recover or recreate temporary tablespace in 10g
In database you may discover that your temporary tablespace is deleted from OS or it might got corrupted. In order to get it back you might think about recover it. The recovery process is simply recover the temporary file from backup and roll the file forward using archived log files if you are in archivelog mode.
Another solution is simply drop the temporary tablespace and then create a new one and assign new one to the database users.
In order to do that follow the steps here.
1)Find out the temporary datafiles.
2)Make the affected temporary files offline.
SQL> Alter database tempfile 1,2,4 offline;
Database altered.
3)Create a new temporary tablespace and make it database default tablespace.
SQL> create temporary tablespace temp01 tempfile '/oradata2/temp.dbf' size 10M;
Tablespace created.
SQL> alter database default temporary tablespace temp01;
Database altered.
3)Check for users who are not pointed to this default temporary tablespaces. Make this default for those users also.
4)Explicitly assign temporary tablespace for users TEST2 and SHAIK
SQL> alter user shaik temporary tablespace temp01;
User altered.
SQL> alter user test2 temporary tablespace temp01;
User altered.
3)Drop the old temporary tablespace.
SQL> drop tablespace temp;
Tablespace dropped.
SQL> drop tablespace temp2;
Tablespace dropped.
SQL> drop tablespace temp3;
Tablespace dropped.
Another solution is simply drop the temporary tablespace and then create a new one and assign new one to the database users.
In order to do that follow the steps here.
1)Find out the temporary datafiles.
SQL> col file_name format a50
SQL> set linesize 200
SQL> select file_name,file_id, tablespace_name from dba_temp_files;
FILE_NAME FILE_ID TABLESPACE_NAME
-------------------------------------------------- ---------- ------------------------------
/oradata2/temp2.dbf 1 TEMP2
/oradata2/temp.dbf 2 TEMP
/oradata2/temp3.dbf 4 TEMP3
2)Make the affected temporary files offline.
SQL> Alter database tempfile 1,2,4 offline;
Database altered.
3)Create a new temporary tablespace and make it database default tablespace.
SQL> create temporary tablespace temp01 tempfile '/oradata2/temp.dbf' size 10M;
Tablespace created.
SQL> alter database default temporary tablespace temp01;
Database altered.
3)Check for users who are not pointed to this default temporary tablespaces. Make this default for those users also.
SQL> select temporary_tablespace , username from dba_users where temporary_tablespace<>'TEMP01';
TEMPORARY_TABLESPACE USERNAME
------------------------------ ------------------------------
TEMP TEST2
TEMP2 SHAIK
4)Explicitly assign temporary tablespace for users TEST2 and SHAIK
SQL> alter user shaik temporary tablespace temp01;
User altered.
SQL> alter user test2 temporary tablespace temp01;
User altered.
3)Drop the old temporary tablespace.
SQL> drop tablespace temp;
Tablespace dropped.
SQL> drop tablespace temp2;
Tablespace dropped.
SQL> drop tablespace temp3;
Tablespace dropped.
How to generate External Table from sql loader
External table to load data rather than Sql*Loader because in external table we can load data parallel. In this post I will show how we can generate external table easily with help of sql loader. With this method we can easily get rid of writing too many codes for external tables.
Suppose my data file is 3.txt which is under C drive on my windows machine and contains a single record,
1, momin
The next step is to create a control file for SQL loader. I named it control.ctl made it as follows,
LOAD DATA
infile 'c:\3.txt'
into table std
fields terminated by ','
(id , name)
Now invoke the Sql loader as below. Note that addition word that need is external_table=generate_only. With this keyword only externa table will be created but will not load any data actually on table.
sqlldr user_id/password control=c:\control.ctl.txt log=5.txt external_table=generate_only
After invoking I open the log file and important contents from logfile is,
CREATE DIRECTORY statements needed for files
------------------------------------------------------------------------
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'C:\'
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'c:\'
CREATE TABLE statement for external table:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_STD"
(
"ID" NUMBER,
"NAME" VARCHAR2(10)
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8MSWIN1252
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'3.bad'
LOGFILE 'c:\5.txt_xt'
READSIZE 1048576
FIELDS TERMINATED BY "," LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
"ID" CHAR(255)
TERMINATED BY ",",
"NAME" CHAR(255)
TERMINATED BY ","
)
)
location
(
'3.txt'
)
)REJECT LIMIT UNLIMITED
INSERT statements used to load internal tables:
------------------------------------------------------------------------
INSERT /*+ append */ INTO STD
(
ID,
NAME
)
SELECT
"ID",
"NAME"
FROM "SYS_SQLLDR_X_EXT_STD"
statements to cleanup objects created by previous statements:
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_STD"
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
Suppose my data file is 3.txt which is under C drive on my windows machine and contains a single record,
1, momin
The next step is to create a control file for SQL loader. I named it control.ctl made it as follows,
LOAD DATA
infile 'c:\3.txt'
into table std
fields terminated by ','
(id , name)
Now invoke the Sql loader as below. Note that addition word that need is external_table=generate_only. With this keyword only externa table will be created but will not load any data actually on table.
sqlldr user_id/password control=c:\control.ctl.txt log=5.txt external_table=generate_only
After invoking I open the log file and important contents from logfile is,
CREATE DIRECTORY statements needed for files
------------------------------------------------------------------------
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'C:\'
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'c:\'
CREATE TABLE statement for external table:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_STD"
(
"ID" NUMBER,
"NAME" VARCHAR2(10)
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8MSWIN1252
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'3.bad'
LOGFILE 'c:\5.txt_xt'
READSIZE 1048576
FIELDS TERMINATED BY "," LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
"ID" CHAR(255)
TERMINATED BY ",",
"NAME" CHAR(255)
TERMINATED BY ","
)
)
location
(
'3.txt'
)
)REJECT LIMIT UNLIMITED
INSERT statements used to load internal tables:
------------------------------------------------------------------------
INSERT /*+ append */ INTO STD
(
ID,
NAME
)
SELECT
"ID",
"NAME"
FROM "SYS_SQLLDR_X_EXT_STD"
statements to cleanup objects created by previous statements:
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_STD"
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
How to generate External Table from sql loader
External table to load data rather than Sql*Loader because in external table we can load data parallel. In this post I will show how we can generate external table easily with help of sql loader. With this method we can easily get rid of writing too many codes for external tables.
Suppose my data file is 3.txt which is under C drive on my windows machine and contains a single record,
1, momin
The next step is to create a control file for SQL loader. I named it control.ctl made it as follows,
LOAD DATA
infile 'c:\3.txt'
into table std
fields terminated by ','
(id , name)
Now invoke the Sql loader as below. Note that addition word that need is external_table=generate_only. With this keyword only externa table will be created but will not load any data actually on table.
sqlldr user_id/password control=c:\control.ctl.txt log=5.txt external_table=generate_only
After invoking I open the log file and important contents from logfile is,
CREATE DIRECTORY statements needed for files
------------------------------------------------------------------------
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'C:\'
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'c:\'
CREATE TABLE statement for external table:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_STD"
(
"ID" NUMBER,
"NAME" VARCHAR2(10)
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8MSWIN1252
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'3.bad'
LOGFILE 'c:\5.txt_xt'
READSIZE 1048576
FIELDS TERMINATED BY "," LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
"ID" CHAR(255)
TERMINATED BY ",",
"NAME" CHAR(255)
TERMINATED BY ","
)
)
location
(
'3.txt'
)
)REJECT LIMIT UNLIMITED
INSERT statements used to load internal tables:
------------------------------------------------------------------------
INSERT /*+ append */ INTO STD
(
ID,
NAME
)
SELECT
"ID",
"NAME"
FROM "SYS_SQLLDR_X_EXT_STD"
statements to cleanup objects created by previous statements:
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_STD"
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
Suppose my data file is 3.txt which is under C drive on my windows machine and contains a single record,
1, momin
The next step is to create a control file for SQL loader. I named it control.ctl made it as follows,
LOAD DATA
infile 'c:\3.txt'
into table std
fields terminated by ','
(id , name)
Now invoke the Sql loader as below. Note that addition word that need is external_table=generate_only. With this keyword only externa table will be created but will not load any data actually on table.
sqlldr user_id/password control=c:\control.ctl.txt log=5.txt external_table=generate_only
After invoking I open the log file and important contents from logfile is,
CREATE DIRECTORY statements needed for files
------------------------------------------------------------------------
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'C:\'
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'c:\'
CREATE TABLE statement for external table:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_STD"
(
"ID" NUMBER,
"NAME" VARCHAR2(10)
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8MSWIN1252
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'3.bad'
LOGFILE 'c:\5.txt_xt'
READSIZE 1048576
FIELDS TERMINATED BY "," LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
"ID" CHAR(255)
TERMINATED BY ",",
"NAME" CHAR(255)
TERMINATED BY ","
)
)
location
(
'3.txt'
)
)REJECT LIMIT UNLIMITED
INSERT statements used to load internal tables:
------------------------------------------------------------------------
INSERT /*+ append */ INTO STD
(
ID,
NAME
)
SELECT
"ID",
"NAME"
FROM "SYS_SQLLDR_X_EXT_STD"
statements to cleanup objects created by previous statements:
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_STD"
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
Dropping all objects in a schema
If you decide to delete all objects of a certain schema then better drop the schema. It will save timing as well as easy process. However inside a schema a user can manually drop all his objects. Below is the procedure about how a user can drop all object under his schema.
1)Connect to database as the user that you want to drop all his objects.
Suppose I want to drop test schema objects.
$sqlplus test/test
2)Script for dropping all objects.
declare
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name from user_objects
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','PROCEDURE','FUNCTION',
'SYNONYM', 'MATERIALIZED VIEW')
order by object_type;
cursor c_get_objects_type is select object_type, '"'||object_name||'"' obj_name from user_objects where object_type in ('TYPE');
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
for object_rec in c_get_objects_type loop
begin execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
end;
/
3)Purge the recyclebin objects.
SQL>PURGE RECYCLEBIN;
4)Drop the queues if you use advanced queuing.
declare
cursor active_queues is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'QUEUE';
cursor active_queue_tables is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'TABLE';
begin
for v_queue in active_queues loop
DBMS_AQADM.STOP_QUEUE (queue_name => v_queue.object_name);
DBMS_AQADM.DROP_QUEUE (queue_name => v_queue.object_name);
end loop;
for v_table in active_queue_tables loop
DBMS_AQADM.DROP_QUEUE_TABLE (queue_table => v_table.object_name, force => TRUE);
end loop;
end;
/
5)Check for if any objects inside schema.
Be sure no rows return after issuing following query.
SQL> select * from user_objects;
no rows selected
1)Connect to database as the user that you want to drop all his objects.
Suppose I want to drop test schema objects.
$sqlplus test/test
2)Script for dropping all objects.
declare
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name from user_objects
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','PROCEDURE','FUNCTION',
'SYNONYM', 'MATERIALIZED VIEW')
order by object_type;
cursor c_get_objects_type is select object_type, '"'||object_name||'"' obj_name from user_objects where object_type in ('TYPE');
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
for object_rec in c_get_objects_type loop
begin execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
end;
/
3)Purge the recyclebin objects.
SQL>PURGE RECYCLEBIN;
4)Drop the queues if you use advanced queuing.
declare
cursor active_queues is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'QUEUE';
cursor active_queue_tables is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'TABLE';
begin
for v_queue in active_queues loop
DBMS_AQADM.STOP_QUEUE (queue_name => v_queue.object_name);
DBMS_AQADM.DROP_QUEUE (queue_name => v_queue.object_name);
end loop;
for v_table in active_queue_tables loop
DBMS_AQADM.DROP_QUEUE_TABLE (queue_table => v_table.object_name, force => TRUE);
end loop;
end;
/
5)Check for if any objects inside schema.
Be sure no rows return after issuing following query.
SQL> select * from user_objects;
no rows selected
Dropping all objects in a schema
If you decide to delete all objects of a certain schema then better drop the schema. It will save timing as well as easy process. However inside a schema a user can manually drop all his objects. Below is the procedure about how a user can drop all object under his schema.
1)Connect to database as the user that you want to drop all his objects.
Suppose I want to drop test schema objects.
$sqlplus test/test
2)Script for dropping all objects.
declare
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name from user_objects
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','PROCEDURE','FUNCTION',
'SYNONYM', 'MATERIALIZED VIEW')
order by object_type;
cursor c_get_objects_type is select object_type, '"'||object_name||'"' obj_name from user_objects where object_type in ('TYPE');
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
for object_rec in c_get_objects_type loop
begin execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
end;
/
3)Purge the recyclebin objects.
SQL>PURGE RECYCLEBIN;
4)Drop the queues if you use advanced queuing.
declare
cursor active_queues is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'QUEUE';
cursor active_queue_tables is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'TABLE';
begin
for v_queue in active_queues loop
DBMS_AQADM.STOP_QUEUE (queue_name => v_queue.object_name);
DBMS_AQADM.DROP_QUEUE (queue_name => v_queue.object_name);
end loop;
for v_table in active_queue_tables loop
DBMS_AQADM.DROP_QUEUE_TABLE (queue_table => v_table.object_name, force => TRUE);
end loop;
end;
/
5)Check for if any objects inside schema.
Be sure no rows return after issuing following query.
SQL> select * from user_objects;
no rows selected
1)Connect to database as the user that you want to drop all his objects.
Suppose I want to drop test schema objects.
$sqlplus test/test
2)Script for dropping all objects.
declare
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name from user_objects
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','PROCEDURE','FUNCTION',
'SYNONYM', 'MATERIALIZED VIEW')
order by object_type;
cursor c_get_objects_type is select object_type, '"'||object_name||'"' obj_name from user_objects where object_type in ('TYPE');
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
for object_rec in c_get_objects_type loop
begin execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
end;
/
3)Purge the recyclebin objects.
SQL>PURGE RECYCLEBIN;
4)Drop the queues if you use advanced queuing.
declare
cursor active_queues is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'QUEUE';
cursor active_queue_tables is select OBJECT_NAME from user_objects where OBJECT_TYPE = 'TABLE';
begin
for v_queue in active_queues loop
DBMS_AQADM.STOP_QUEUE (queue_name => v_queue.object_name);
DBMS_AQADM.DROP_QUEUE (queue_name => v_queue.object_name);
end loop;
for v_table in active_queue_tables loop
DBMS_AQADM.DROP_QUEUE_TABLE (queue_table => v_table.object_name, force => TRUE);
end loop;
end;
/
5)Check for if any objects inside schema.
Be sure no rows return after issuing following query.
SQL> select * from user_objects;
no rows selected
Subscribe to:
Posts (Atom)