It’s convinent to post blog via email. After struggling for a while, got the plugin postie to do this functionalities. Which mean more posting from me going forward.
Archive for the ‘Oracle Administration’ Category
You don’t need tns or ldap entry to connect to your db from your desktop. 10g uses service name and 11g uses sid.
C:\Documents and Settings>tnsping hostname:1141/emrep
TNS Ping Utility for 32-bit Windows: Version 11.2.0.1.0 – Production on 24-FEB-2
011 18:42:59
Copyright (c) 1997, 2010, Oracle. All rights reserved.
Used parameter files:
c:\tns\sqlnet.ora
Used EZCONNECT adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=emrep))(ADDRESS=(PROTOCOL=TCP)(HOST=xxxxxxxxx)(PORT=1141)))
OK (440 msec)
C:\Documents and Settings\>sqlplus dbsnmp/*******@hostname:1141/emrep
SQL*Plus: Release 11.2.0.1.0 Production on Thu Feb 24 18:44:30 2011
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining Scoring Engine
and Real Application Testing options
SQL> select host_name from v$instance;
HOST_NAME
—————————————————————-
hostname
SQL> show parameter db_name
NAME TYPE
———————————— ——————————–
VALUE
——————————
db_name string
emrep
to work you need below entry in your sqlnet.ora,
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
If you want top 200 sql in your report
dbms_workload_repository.modify_snapshot_settings (topnsql=> 200)
If you want a particular sql even if it’s not in your top list.
dbms_workload_repository.add_colored_sql(:sql_id)
trace one or more sql id
alter session set events ‘sql_trace [sql: sql_id1 |sql_id2]‘
I know about the last one.
New 11gR2 feature. Seems interesting. Can it be a alternate to active-passive cluster or Dataguard? May not be for DG, as DG protects you in cases like corruption.
http://download.oracle.com/docs/cd/E11882_01/rac.112/e16795/onenode.htm
impdp will do a direct load import. This is one way to confirm
SQL> select sum(bytes/1024/1024) from dba_segments where segment_name='T';
SUM(BYTES/1024/1024)
--------------------
176.1875
SQL> truncate table t;
Table truncated.
SQL> alter table t COMPRESS FOR OLTP ;
Table altered.
Note: compress for all operation is deprecated in 11gR2 instead it will be compress for oltp
SQL> host impdp directory=data_pump_dir dumpfile=xyz.dmp tables='test.t' table_e xists_action=append Import: Release 11.2.0.1.0 - Production on Thu Oct 14 21:30:33 2010 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. Username: / as sysdba Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Produc tion With the Partitioning and Real Application Testing options Master table "SYS"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded Starting "SYS"."SYS_IMPORT_TABLE_01": /******** AS SYSDBA directory=data_pump_d ir dumpfile=xyz.dmp tables='test.t' table_exists_action=append Processing object type TABLE_EXPORT/TABLE/TABLE ORA-39152: Table "TEST"."T" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append Processing object type TABLE_EXPORT/TABLE/TABLE_DATA . . imported "TEST"."T" 149.2 MB 1689984 rows Job "SYS"."SYS_IMPORT_TABLE_01" completed with 1 error(s) at 21:31:03
Let us check the size now.
SQL> select sum(bytes/1024/1024) from dba_segments where segment_name='T';
SUM(BYTES/1024/1024)
--------------------
72.1875
From 176mb the size is reduced to 72mb. Not let us try the direct load after truncating the table,
SQL> alter table t compress for DIRECT_LOAD OPERATIONS;
Table altered.
SQL> host impdp directory=data_pump_dir dumpfile=xyz.dmp tables='test.t' table_e
xists_action=append status=2
Import: Release 11.2.0.1.0 - Production on Thu Oct 14 21:32:28 2010
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Username: / as sysdba
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Produc
tion
With the Partitioning and Real Application Testing options
Master table "SYS"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "SYS"."SYS_IMPORT_TABLE_01": /******** AS SYSDBA directory=data_pump_d
ir dumpfile=xyz.dmp tables='test.t' table_exists_action=append
Processing object type TABLE_EXPORT/TABLE/TABLE
ORA-39152: Table "TEST"."T" exists. Data will be appended to existing table but
all dependent metadata will be skipped due to table_exists_action of append
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Job "SYS"."SYS_IMPORT_TABLE_01" completed with 1 error(s) at 21:43:55
SQL> select sum(bytes/1024/1024) from dba_segments where segment_name='T';
SUM(BYTES/1024/1024)
--------------------
72.1875
Now the size has reduced from 176mb
SQL> alter table t nocompress;
Table altered.
SQL> host impdp directory=data_pump_dir dumpfile=xyz.dmp tables='test.t' table_e
xists_action=append status=2
SQL> select sum(bytes/1024/1024) from dba_segments where segment_name='T';
SUM(BYTES/1024/1024)
--------------------
176.1875
Without compression it’s 176mb.
If your DB is applied with patch#8198906, then beware that you may run into corruption when extending the table manually.
This patch is obselete now. You have to uninstall and install 9711859.
If your shop is managing 1000s of DBs then how to find out on which installation this patch is applied.
If these DBs are managed in OEM, then you can use below query
select * from mgmt_inv_patch_fixed_bug where bug_number=8198906;
 We did see our mview going slow. When we traced the session we found our job is waiting for a while in sumdelta$.
if automic_refresh=false due to direct load operation sumdelta$ don’t purge. There are some bug registered for this.
This is the workaround.
CREATE MATERIALIZED VIEW dummy_mview TABLESPACE tbs_data NOLOGGING refresh complete start with sysdate next (sysdate+(1/1440)) WITH ROWID AS select sysdate,col1 from mview mv10 WHERE 1=2 ;
In the select add “sysdate” so that refresh is assumed as complex and refresh every time.
exec DBMS_MVIEW.REFRESH('DUMMY_MVIEW','C');
select count(*) from sys.sumdelta$ where tableobj# in (select obj# from sys.obj$ where name=upper('DUMMY_MVIEW');
the count of this query should reduce to zero.
We got an requirement to schedule a script after BD6+1. Means next day to BD6, which can be a holiday. But incase between BD1 to BD6 federal holiday falls, it needs to be moved to next day.
Create schedule for all the holidays,
begin dbms_scheduler.create_schedule( schedule_name => 'NYD_FRI', repeat_interval => 'FREQ=YEARLY;BYDATE=1231;BYDAY=FRI', comments => 'Friday alternative for New Year''s Day'); dbms_scheduler.create_schedule( schedule_name => 'NYD_MON', repeat_interval => 'FREQ=YEARLY;BYDATE=0102;BYDAY=MON', comments => 'Monday alternative for New Year''s Day'); dbms_scheduler.create_schedule( schedule_name => 'NewYearsDay', repeat_interval => 'FREQ=YEARLY;BYDATE=0101;BYDAY=MON,TUE,WED,THU,FRI;' || 'INCLUDE=NYD_FRI,NYD_MON', comments => 'New Year''s Day'); dbms_scheduler.create_schedule( schedule_name => 'MartinLutherKing', repeat_interval => 'FREQ=MONTHLY;BYMONTH=JAN;BYDAY=3MON', comments => 'Martin Luther King Day'); dbms_scheduler.create_schedule( schedule_name => 'PresidentsDay', repeat_interval => 'FREQ=MONTHLY;BYMONTH=FEB;BYDAY=3MON', comments => 'President''s Day'); dbms_scheduler.create_schedule( schedule_name => 'MemorialDay', repeat_interval => 'FREQ=MONTHLY;BYMONTH=MAY;BYDAY=-1MON', comments => 'Memorial Day'); dbms_scheduler.create_schedule( schedule_name => 'ID_FRI', repeat_interval => 'FREQ=YEARLY;BYDATE=0703;BYDAY=FRI', comments => 'Friday alternative for Independence Day'); dbms_scheduler.create_schedule( schedule_name => 'ID_MON', repeat_interval => 'FREQ=YEARLY;BYDATE=0705;BYDAY=MON', comments => 'Monday alternative for Independence Day'); dbms_scheduler.create_schedule( schedule_name => 'IndependenceDay', repeat_interval => 'FREQ=YEARLY;BYDATE=0704;BYDAY=MON,TUE,WED,THU,FRI;' || 'INCLUDE=ID_FRI,ID_MON', comments => 'Independence Day'); dbms_scheduler.create_schedule( schedule_name => 'LaborDay', repeat_interval => 'FREQ=MONTHLY;BYMONTH=SEP;BYDAY=1MON', comments => 'Labor Day'); dbms_scheduler.create_schedule( schedule_name => 'ColumbusDay', repeat_interval => 'FREQ=MONTHLY;BYMONTH=OCT;BYDAY=2MON', comments => 'Columbus Day'); dbms_scheduler.create_schedule( schedule_name => 'VD_FRI', repeat_interval => 'FREQ=YEARLY;BYDATE=1110;BYDAY=FRI', comments => 'Friday alternative for Veterans Day'); dbms_scheduler.create_schedule( schedule_name => 'VD_MON', repeat_interval => 'FREQ=YEARLY;BYDATE=1112;BYDAY=MON', comments => 'Monday alternative for Veterans Day'); dbms_scheduler.create_schedule( schedule_name => 'VeteransDay', repeat_interval => 'FREQ=YEARLY;BYDATE=1111;BYDAY=MON,TUE,WED,THU,FRI;' || 'INCLUDE=VD_FRI,VD_MON', comments => 'Veterans Day'); dbms_scheduler.create_schedule( schedule_name => 'Thanksgiving', repeat_interval => 'FREQ=MONTHLY;BYMONTH=NOV;BYDAY=4THU', comments => 'Thanksgiving'); dbms_scheduler.create_schedule( schedule_name => 'XMS_FRI', repeat_interval => 'FREQ=YEARLY;BYDATE=1224;BYDAY=FRI', comments => 'Friday alternative for Christmas'); dbms_scheduler.create_schedule( schedule_name => 'XMS_MON', repeat_interval => 'FREQ=YEARLY;BYDATE=1226;BYDAY=MON', comments => 'Monday alternative for Christmas'); dbms_scheduler.create_schedule( schedule_name => 'Christmas', repeat_interval => 'FREQ=YEARLY;BYDATE=1225;BYDAY=MON,TUE,WED,THU,FRI;' || 'INCLUDE=XMS_FRI,XMS_MON', comments => 'Christmas'); end; /
– create a schedule which clubs all the schedule created above.
begin dbms_scheduler.create_schedule( schedule_name => 'FederalHolidays', repeat_interval => 'NewYearsDay,MartinLutherKing,PresidentsDay,' || 'MemorialDay,IndependenceDay,LaborDay,ColumbusDay,VeteransDay,' || 'Thanksgiving,Christmas', comments => 'Federal Holidays'); end; /
– Job which needs to be scheduled
create or replace procedure stats_run_after_BD6 as begin ---- some job; end; /
— Create a job, note the “EXCLUDE” and “BYSETPOS” option
BEGIN dbms_scheduler.create_job( job_name => 'Stats_Run_After_BD6+1' ,job_type => 'PLSQL_BLOCK' ,job_action => 'begin stats_run_after_BD6; end; ' ,repeat_interval => 'FREQ=MONTHLY; BYDAY=MON,TUE,WED,THU,FRI; byhour=14;byminute=30;bysecond=0; EXCLUDE=FederalHolidays; BYSETPOS=7' ,enabled => TRUE ,comments => 'Run Stats Gather next day of BD6'); END; /
What are all the dates this job is going to execute. We can use the below procedure.
create or replace procedure print_dates
is
nr_of_dates pls_integer :=30;
start_date timestamp with time zone := sysdate;
date_after timestamp with time zone := start_date - interval '1' second;
next_execution_date timestamp with time zone;
correct_execution_date timestamp with time zone;
begin
for i in 1 .. nr_of_dates
loop
dbms_scheduler.evaluate_calendar_string
('FREQ=MONTHLY; BYDAY=MON,TUE,WED,THU,FRI; byhour=14;byminute=30;bysecond=0; EXCLUDE=FederalHolidays; BYSETPOS=6', start_date, date_after, next_execution_date);
correct_execution_date := next_execution_date + interval '1' day;
DBMS_OUTPUT.PUT_LINE(correct_execution_date);
date_after := next_execution_date;
end loop;
end;
/
sometime the BD6+ 1 date will be weekend. If you want to execute in the weekend you can add “interval ’1′ day”,
correct_execution_date := next_execution_date + interval ’1′ day;
else remove that.
Read couple of interesting topic on proxy login in oracle.
http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_19.shtml
http://jonathanlewis.wordpress.com/2006/12/18/proxy-users/
We have an requirement, where we need to purge portion of data from huge table. After much discussion, we have decided go to like
1. create temp table
2. populate only relevant data from main table to temp table
3. drop main table.
4. rename temp table to main table and recreate missing indexes.
there are various approach to do this. But instead we have gone with something like split the big table in to logical split using rowid and with each logical split populate the temp table parallel.
create table scuser.tab1_bk as select * from scuser.tab1 where 1=2;
alter table scuser.tab1_bk nologging;
truncate table scuser.tab1_bk;
Drop table split_rowid purge;
CREATE TABLE split_rowid as select distinct grp,
first_value(relative_fno) over
(partition by grp order by relative_fno, block_id
rows between unbounded preceding and unbounded following) lo_fno,
first_value(block_id ) over
(partition by grp order by relative_fno, block_id
rows between unbounded preceding and unbounded following) lo_block,
last_value(relative_fno) over
(partition by grp order by relative_fno, block_id
rows between unbounded preceding and unbounded following) hi_fno,
last_value(block_id+blocks-1) over
(partition by grp order by relative_fno, block_id
rows between unbounded preceding and unbounded following) hi_block,
sum(blocks) over (partition by grp) sum_blocks
from (
select relative_fno,
block_id,
blocks,
trunc( (sum(blocks) over (order by relative_fno, block_id)-0.01) /
(sum(blocks) over ()/&chunk) ) grp
from dba_extents
where segment_name = ('TAB1')
and owner = '&owner' order by block_id
)
/
Create or replace procedure purge_clock(p_no number,lo_rowid rowid,hi_rowid rowid) as
type array is table of scuser.tab1_bk%rowtype;
l_data array;
cursor c is select /+* first_rows */ * from tab1 a where (exists
(select 1 from probsummarym1
where probsummarym1.numberprgn = a.key_char
and a.type = 'problem')
or a.datetime_last_upd > (sysdate-3)
or type <> 'problem')
and substr(name,0,7) <> 'JPASRPT' and rowid between lo_rowid and hi_rowid;;
lv_cnt number:=0;
lv_cnt1 number:=0;
BEGIN
open c;
loop
fetch c bulk collect into l_data LIMIT 10000;
lv_cnt:=lv_cnt+1;
lv_cnt1 := lv_cnt*10000;
dbms_application_info.set_client_info(p_no||' of Clock:'||lv_cnt1);
forall i in 1 .. l_data.count
Insert into scuser.tab1_bk values l_data(i);
COMMIT;
exit when c%notfound;
END LOOP;
CLOSE c;
commit;
END;
/
alter system set job_queue_processes=20;
set serveroutput on;
Declare
cursor c1 is
select rownum no,
dbms_rowid.rowid_create(1,
(select data_object_id from dba_objects where object_name='tab1' and object_type='TABLE'),lo_fno,lo_block,0) lo_rowid,
dbms_rowid.rowid_create(1,
(select data_object_id from dba_objects where object_name='tab1' and object_type='TABLE'),hi_fno,hi_block,32767) hi_rowid
from split_rowid order by no;
lv_job number;
begin
for i in c1 loop
dbms_job.submit(lv_job,'purge_clock('||i.no||','||chr(39)||i.lo_rowid||chr(39)||','||chr(39)||i.hi_rowid||chr(39)||');');
dbms_output.put_line('Job#'||lv_job);
commit;
end loop;
commit;
end;
/
A client mailed us with a query, which crashes with 4031 error. It’s a complex query has Nl and Hash joins. While diagonising i found that the problem lies with the below two line of where condition.
ANDÂ ( (GL_MONTH_ACTV_BAL.BUS_UNIT_ID)=SAP_BUS_UNIT_MO_ASIS.BUS_UNIT_ID and SAP_BUS_UNIT_MO_ASIS.BUS_UNIT_CD_TYPE in (‘XYZ123′ ,’ABC’)Â )
 AND ( (GL_MONTH_ACTV_BAL.GLAS_BUS_UNIT_ASIS_ID)=GLAS_BUSINESS_UNIT.BUS_UNIT_ID  AND GLAS_BUSINESS_UNIT.BUS_UNIT_CD_TYPE IN (‘ABC123′ ,’ABC’) )
When i change the query to
ANDÂ ( (to_number(GL_MONTH_ACTV_BAL.BUS_UNIT_ID))=SAP_BUS_UNIT_MO_ASIS.BUS_UNIT_ID and SAP_BUS_UNIT_MO_ASIS.BUS_UNIT_CD_TYPE in (‘XYZ123′ ,’ABC’)Â )
 AND ( (to_number(GL_MONTH_ACTV_BAL.GLAS_BUS_UNIT_ASIS_ID))=GLAS_BUSINESS_UNIT.BUS_UNIT_ID  AND GLAS_BUSINESS_UNIT.BUS_UNIT_CD_TYPE IN (‘ABC123′ ,’ABC’) )
It worked. The funny thing here is the column GL_MONTH_ACTV_BAL.BUS_UNIT_ID is of number datatype. We were not able to even get the explain plan user “Set autot trace exp”, as the query crashes with 4031 error.
On error and trial of this query, we found that ‘star_transformation_enabled’ is the culprit. It’s pure luck i found this one. I have to change this value from true to false.
I can’t set this at db level or session level, as it might have impact on other queries. That’s where we used /*+opt_param*/ hint
SELECT /*+ OPT_PARAM(‘star_transformation_enabled’,'false’) */
One of the excercise we do every year in our shop is to request business to add more storage. This year we are following a different approach. We are going to stop monitoring tablespace usage in OEM and concentrate only on used and available space on each mount point. To do that, we are putting all the tablespace in autoextend on, except temp and undo.
Once we have removed tablepsace usage monitoring in OEM, we did the shrink of each datafile to remove extra allocated space. So at any point of time tablespace usage will look 100%, with the exception that autoextend is on. Currently we have done this excercise in dev environment, we got a amazing savings for around 4TB savings.
Advantage:
Effective use of storage. Each tablespace grow only when there is space pressure.
Extra ticket generated for tablespace usage alert can be avoided.
Disadvt:
OS mountpoint should be monitored very closely. If any alert, needs to be acted immediatly. As in some cases we need to purchase extra storage.
Ok, this works only for non undo and temp tablespace. We have put the undo and temp in autoextend off mode. So, we need to monitor these two tablespace. While monitoring these two tablespace, we need to consider expired,unexpired extents. We created two user managed metric alert in OEM for these two tablespace. Below is the script which we have used.
Metric Name Temp Usage
Metric Type NUMBER
SQL Query Output Two Columns
SQL Query select * from (select z.tablespace_name||’ Used %’,z.Perc_used from (select x.tablespace_name,trunc((v_usage_gb/v_total_gb)*100,2) Perc_Used from (select tablespace_name,trunc(sum(bytes/1024/1024/1024),2) v_total_gb from dba_temp_files group by tablespace_name) x, (select tablespace,trunc(sum(blocks*8192/1024/1024/1024),2) v_usage_gb from v$sort_usage group by tablespace) y where x.tablespace_name=y.tablespace order by Perc_used DESC ) z where rownum = 1 union all select ’0′,0 from dual ) x1 where rownum = 1
Metric Name Undo Usage
Metric Type NUMBER
SQL Query Output Two Columns
SQL Query select y.tablespace_name,trunc((y.total_gb/z.grand_total_gb)*100,2) Perc_Used from (select x.tablespace_name, trunc(x.total_bytes/1024/1024/1024,2) Total_Gb from (select tablespace_name, (nvl(sum(bytes),0)) total_bytes from dba_undo_extents where status in (‘ACTIVE’,'UNEXPIRED’) group by tablespace_name order by 2 desc) x where rownum=1) y, (select tablespace_name,sum(bytes/1024/1024/1024) grand_total_gb from dba_data_files group by tablespace_name) z where y.tablespace_name = z.tablespace_name
select View1.ACCT_CST_CTR_BK_CD, View1.ACCT_CST_CTR_BK_DESC, WCPADM.CAL.FULL_DT_DESC, sum(WCPADM.WCP_BAS_FCT.TOT_PROD_EXPEN_AM), sum(WCPADM.WCP_BAS_FCT.PROD_REV_AM) FROM View1, WCPADM.CAL, WCPADM.WCP_BAS_FCT WHERE ( WCPADM.WCP_BAS_FCT.PSTN_ID=View1.PSTN_ID) AND ( WCPADM.CAL.CAL_ID=WCPADM.WCP_BAS_FCT.EFF_DT_ID ) AND (View1.ACCT_CST_CTR_BK_CD In ( '0014036','0029284','0009570','0025336' ) AND WCPADM.CAL.FULL_DT_DESC In ( '2007 FULL YEAR','2006 FULL YEAR','SEP 2008 YTD' ) ) GROUP BY View1.ACCT_CST_CTR_BK_CD, View1.ACCT_CST_CTR_BK_DESC, WCPADM.CAL.FULL_DT_DESC / select * ERROR at line 1: ORA-03113: end-of-file on communication channel
I promptly raised SR, oracle suggested few patches, then events and then some underscore parameters. Nothing worked.
These query is getting generated from BO, so we have been instructed by business to tune without touching it.
We tried various options, but nothing worked. Then i took the query out and run it in sqlplus by adding (select * from View1 where rownum > 0) in place of view as inline query. This worked.
This clearly showed there is some issue with view merging.
We set the parameter “_comple_view_merging”=false. But even this didn’t help. The by setting “_simple_view_merging”=false. We are able to address this issue.
Visitors Count