Tuesday 18 November 2014

Reclaim waste space in a table




To find out total space wasted in a table
========================================

--exec as the owner of the table/sys

Select table_name,tablespace_name,status,num_rows,chain_cnt,
blocks,empty_blocks,avg_row_len,
(blocks * 8192 )/1024/1024 "Used_Size_MB",
round(((num_rows * avg_row_len)/1024/1024),2) "Acutal_Data_Size_MB",
((blocks * 8192 )/1024/1024) - (round(((num_rows * avg_row_len)/1024/1024),2)) "Space_Wasted_MB"
FROM   user_tables
ORDER  BY 11 DESC;



Methods to reclaim wasted space in a table
==========================================

1. Alter table table_name move tablespace users; 

 --Move table to any other tablespace
 --Then back to the original tablespace
 --Note that this operation will change rowids of the rows
   because of this indexes on that table will go invalid, we need to rebuild all of them manually;
 --DML,DDL cannot be done during this time.


2. Create table as select * ...

   --This will create a table similar to the original one, But constraints and indexes should be taken care.

3. alter table table_name shrink space;
 
 --execute 'alter table table_name enable row movement;'
 --execute 'alter table table_name shrink space compact;'(This will rearrange the rows, this doest not required dml locks)
 --execute 'alter table table_name shrink space;'(actual shrinking operation, requires locks,DML cannot perform during the time)
 --Indexes remains valid
 --gather stats on the table 'exec dbms_stats.gather_table_stats(TAB_OWNER, 'MYTABLE', cascade => TRUE);'

4. DBMS_REDEFINITION  

 --Online redefinition (does not required any down time for the table)
 --create an interim table as per the requirement
 --check for the eligibility to do redefinition using DBMS_REDEFINITION.can_redef_table
 --start redefinition by using  DBMS_REDEFINITION.start_redef_table
 --Sync table with interim table by using DBMS_REDEFINITION.sync_interim_table
 --Copy dependent objects (such as triggers, indexes, grants, and constraints)
   using DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS
 --finfish redefinition  using DBMS_REDEFINITION.finish_redef_table


For more detail please visit:
http://avdeo.com/2012/10/28/redefining-tables-online-oracle-11g/

Wednesday 22 October 2014

How to convert a varchar column to "clob"



We can do it in three methods:

A. Online Redefinition
B. Create table as select * from
C. Alternate way, explained below.

A) Online Redefinition 

   
sql> create table t ( x int primary key, y varchar2(4000) );

Table created.

sql> insert into t values ( 1, 'hello' );

1 row created.

sql> commit;

Commit complete.

sql>
sql> create table t2( x int, y clob );

Table created.

sql> exec dbms_redefinition.start_redef_table( user, 'T', 'T2', 'x, to_clob(y) y' );

PL/SQL procedure successfully completed.

sql> pause

sql> variable nerrors number
sql> begin
 2          dbms_redefinition.copy_table_dependents
 3          ( user, 'T', 'T2',
 4            copy_indexes => dbms_redefinition.cons_orig_params,
 5            num_errors => :nerrors );
 6  end;
 7  /

PL/SQL procedure successfully completed.

sql> print nerrors

  NERRORS
 ----------
        0

sql> exec dbms_redefinition.finish_redef_table( user, 'T', 'T2' );

PL/SQL procedure successfully completed.

sql> drop table t2;

Table dropped.

sql> select dbms_metadata.get_ddl( 'TABLE', 'T' ) from dual;

DBMS_METADATA.GET_DDL('TABLE','T')
-------------------------------------------------------------

 CREATE TABLE "OPS$TKYTE"."T"
  (    "X" NUMBER(*,0),
       "Y" CLOB,
        CONSTRAINT "SYS_C0038059" PRIMARY KEY ("X")
 USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
 TABLESPACE "USERS"  ENABLE NOVALIDATE
  ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
 TABLESPACE "USERS"
LOB ("Y") STORE AS (
 TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
 NOCACHE LOGGING
 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT))

B. Create new_table as select * from the old (using to_lob on the column) and then add index, constrains etc the new table, then drop old, rename new to old.


C. There is an alternative solution which always preserves the order of columns.
The idea is to first convert the varchar2 column to a long and then to convert that long to a clob.

alter table t add y_copy varchar2(4000);
update t set y_copy = y;
commit;
update t set y = null;
commit;
alter table t modify y long;
alter table t modify y clob;
update t set y = y_copy;
commit;
alter table t drop column y_copy;

Archive Log Information





 Size of the archives available on disk

===================================

Select round(sum(BLOCK_SIZE * BLOCKS)/1024/1024/1024,2 ) "Size_of_arc_on_disk_GB"
From v$archived_log
Where status  like 'A';

How many days archives are there on disk and their time info

==========================================================
Select Min(completion_time) "Lowest_arc_found_on_disk",
Max(completion_Time) "Highest_arc_found_on_disk",
Round(max(completion_Time)  - min(completion_time),2) "No_of_Days_Aric_on_disk"
From v$archived_log
Where status  like 'A';

No of archives generated/day, size & freqency

===========================================
Select trunc(completion_time) "Date",
To_char(trunc(completion_time),'Day') "Day",
Count(*) "No_of_arc" ,
Round(1440/count(*),2) "Frquency_arc_created_Min",
Round(sum(block_size * blocks)/1024/1024/1024,2) "Size_disk_GB"
From v$archived_Log
Group by trunc(completion_time)
Order by trunc(completion_time) desc;

Monday 15 September 2014

Undo Space Information....!!!




Total Undo
**************
select a.tablespace_name, sizemb, usagemb, (sizemb - usagemb) freemb
from (select sum(bytes) / 1024 / 1024 sizemb, b.tablespace_name
from dba_data_files a, dba_tablespaces b
where a.tablespace_name = b.tablespace_name
and b.contents = 'UNDO'
group by b.tablespace_name) a,
(select c.tablespace_name, sum(bytes) / 1024 / 1024 usagemb
from dba_undo_extents c
where status <> 'EXPIRED'
group by c.tablespace_name) b
where a.tablespace_name = b.tablespace_name;

        OR

select file_name, bytes/1024/1024/1024 "bytes in_gb", autoextensible, maxbytes/1024/1024/1024 "maxbytes in_gb"
from dba_data_files where tablespace_name='UNDOTBS1';


Undo Datafile Information
****************************
 select dt.tablespace_name, dt.contents, ddf.file_name, ddf.bytes/1024/1024/1024 size_gb
from dba_tablespaces dt, dba_data_files ddf
where dt.tablespace_name = ddf.tablespace_name
and dt.contents like 'UNDO';


Total Usage of Undo
***************************
select
      ( select sum(bytes)/1024/1024 from dba_data_files
       where tablespace_name like 'UND%' )  undo_allocated_MB,
    ( select sum(bytes)/1024/1024 from dba_free_space
       where tablespace_name like 'UND%')  undo_free_MB,
    ( select sum(bytes)/1024/1024 from dba_undo_extents
       where tablespace_name like 'UND%') undo_used_MB    
from dual;
 
         OR

select tablespace_name,  sum(blocks) * 8192/1024/1024 "undo_usage_in_MB"
    from dba_undo_extents
   group    by tablespace_name;
 
 
Undo usage detailed info
****************************
 
select    tablespace_name, status, sum(blocks) * 8192/1024/1024 size_in_MB,
count(*) as "HOW_MANY_txtns"
from    dba_undo_extents
group    by tablespace_name ,status;


Who Is Using Undo & How Much
******************************************
select ses.username , substr(ses.program, 1, 19) program,
tra.used_ublk
from v$session ses, v$transaction tra
where ses.saddr = tra.ses_addr;

         OR

select to_char (s.sid) || ',' || to_char (s.serial#) sid_serial,
nvl (s.username, 'none') orauser,osuser, s.program, r.name undoseg,
t.used_ublk * to_number (x.value) / 1024 || 'k' "undo",
t1.tablespace_name
from sys.v_$rollname r, sys.v_$session s,
sys.v_$transaction t, sys.v_$parameter x, dba_rollback_segs t1
where s.taddr = t.addr
and r.usn = t.xidusn(+)
and x.name = 'db_block_size'
and t1.segment_id = r.usn
and t1.tablespace_name = 'UNDOTBS1';
 
         OR

 select a.name,b.status ,d.osuser ,d.username , d.sid , d.serial#
from   v$rollname a,v$rollstat b, v$transaction c , v$session d
where  a.usn = b.usn
and    a.usn = c.xidusn
and    c.ses_addr = d.saddr
and    a.name in ( select segment_name
          from dba_segments
          where tablespace_name = 'UNDOTBS1);
       
Undo Using Sess Info 
*********************************

select s.sid , s.username ,t.status,t.start_time,t.noundo,t.ptx,t.name, t.used_ublk
from v$transaction t , v$session s
where 1 = 1
and t.ses_addr = s.saddr;
 
         OR

select distinct rpad(s.sid,3) "sid",s.username,
e.segment_name,
t.start_time "start",
rpad(t.status,9) "status",
round((t.used_ublk*8)/1024) "size used(mb)"
--t.used_ublk||' blocks and '||t.used_urec||' records' "rollback usage"
from dba_data_files df,
dba_extents e,
v$session s,
v$transaction t
where df.tablespace_name = e.tablespace_name and
df.file_id = ubafil and
s.saddr = t.ses_addr and
t.ubablk between e.block_id and e.block_id+e.blocks and
e.segment_type in( 'ROLLBACK','TYPE2 UNDO');


Find The Active Txns Using Undo
*******************************************
select s.username,s.osuser,s.sid,s.serial#, t.xidusn, t.ubafil, t.ubablk, t.used_ublk
from v$session s, v$transaction t
where s.saddr = t.ses_addr


Pending & Active Txns
**********************************

select a.name,b.status
from   v$rollname a,v$rollstat b
where  a.usn = b.usn
and    a.name in (  select segment_name
        from dba_segments
        where tablespace_name = 'UNDOTBS1'   );


Note: If pending txns or active txns are there we cannot drop that tablespaces.


Suggestion for undo size needed ......using Advisory:
***********************************************************

 SELECT (UR * (UPS * DBS)) + (DBS * 24) AS "Bytes"
FROM (SELECT value AS UR FROM v$parameter WHERE name = 'undo_retention'),
(SELECT (SUM(undoblks)/SUM(((end_time - begin_time)*86400))) AS UPS FROM v$undostat),
(select block_size as DBS from dba_tablespaces where
tablespace_name= (select upper(value) from v$parameter where name = 'undo_tablespace'));






Temp Table space Info....!!




Temp space info
********************

 SELECT A.tablespace_name tablespace, D.mb_total,
 SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_used,
 D.mb_total - SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_free
 FROM v$sort_segment A,
 (
 SELECT B.name, C.block_size, SUM (C.bytes) / 1024 / 1024 mb_total
 FROM v$tablespace B, v$tempfile C
 WHERE B.ts#= C.ts#
GROUP BY B.name, C.block_size
 ) D
 WHERE A.tablespace_name = D.name
 GROUP by A.tablespace_name, D.mb_total
     

Who is using Temp
***********************

SELECT   b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , ROUND (  (  ( b.blocks * p.VALUE ) / 1024 / 1024 ), 2 ) size_mb
       , a.SID
       , a.serial#
       , a.username
       , a.osuser
       , a.program
       ,a.machine
       ,a.sql_id
       ,a.prev_sql_id
       , a.status
 from v$session a , v$sort_usage b, v$process c, v$parameter p
 where p.name= 'db_block_size' and a.saddr = b.session_addr
 and  a.paddr = c.addr
order by b.tablespace, 4 desc, b.segfile#, b.segblk#, b.blocks;




**********

Wednesday 10 September 2014

User account is locked frequently in oracle returns ORA-28000...!!




  • Find the default profile of the database user.
  • Check the value for FAILED_LOGIN_ATTEMPTS in the profile.
  • Edit the profile and change the value / or create a new profile with new value.
  • Assigned to the user.

Select profile from dba_users where username = 'USERNAME';
Select resource_name, resource_type, limit From dba_profiles Where profile='DEFAULT';

Look at the parameter FAILED_LOGIN_ATTEMPTS ,  by default it is 10 prior 11g it used to be "unlimited".

If you like to change the profile option edit the specific (here default) profile, but editing in default profile is not suggested for security reasons.

It is a good idea to create a new profile with options of that in the default profile and change the FAILED_LOGIN_ATTEMPTS to "unlimited".

***** To Create a Profile *****

Create Profile Default_new Limit
composite_limit kernel unlimited
sessions_per_user kernel unlimited
cpu_per_session kernel unlimited
cpu_per_call kernel unlimited
logical_reads_per_session kernel unlimited
logical_reads_per_call kernel unlimited
idle_time kernel unlimited
connect_time kernel unlimited
private_sga kernel unlimited
failed_login_attempts password unlimited
password_life_time password unlimited
password_reuse_time password unlimited
password_reuse_max password unlimited
password_verify_function password null
password_lock_time password unlimited
password_grace_time password unlimited;

***** Assign Profile to a user *****
Alter user mylogin  profile Default_new;

Now you would not face the issue of user account locking frequently.


To check who has tried to loggin with wrong password..

*****Execute the below query *****
Select username, userhost, terminal, timestamp, action_name,             
          logoff_time, sessionid, os_process, returncode
From  dba_audit_session
Order by timestamp desc;


Note: The column  Return code is the error we get as ORA-XXXX
for example if returncode is  28000 which means ORA-28000
Error ORA-28000 means "User Accout Locked"
Error ORA-1017  means "invalid username/password; logon denied"


***** For more detail info *****
Select  os_username, username, userhost, terminal, timestamp,
           owner, obj_name,action, action_name, logoff_time,
           comment_text, sessionid, returncode, os_process, sql_text
From dba_audit_trail
Where username like 'username'
Order by timestamp desc;

**********

Sunday 7 September 2014

All currently active user process information in a database..!




select
p.spid os_process_Id,
'alter system kill session ' || ''''||s.sid||','||s.serial#||''' immediate;' Kill_command,
nvl (p.pname,'user process') process_name,
nvl(s.username,'BG') USERNAME,
s.SID,
s.SERIAL#,
ss.PX_SERVERS_EXECUTIONS,
s.STATUS,
s.OSUSER,
s.MACHINE,
s.blocking_session,
s.blocking_session_status,
s.state,
s.event,
s.wait_class,
round(s.WAIT_TIME_MICRO/1000000) Wait_time_inSec,
s.service_name,
s.PROGRAM,
s.module,
s.logon_time,
s.sql_id current_sql_id,
nvl(s.SQL_id,PREV_sql_id) last_exc_sql_id,
nvl2(BLOCKING_SESSION,s.sid||' Is Blocked by: '||blocking_Session,'No Block') blocking_status,
ss.sql_text,ss.sql_fulltext
from v$session s,v$process p,v$sqlarea ss
where s.paddr=p.addr
and ss.sql_id(+)=s.sql_id
and s.username not in ('SYS','SYSTEM','SYSMAN','DBSNMP')
--and s.event not like 'SQL*Net message from client'
and p.pname  is null
order by 5;



**********

Tuesday 2 September 2014

Joining of some V$views....!!





Sometimes its very hard to join certain v$ viewes to get relevent information in oracle.

Here is some examples of joining v$ views  which are used by DBAs most frequtntly,


V$session + v$process
**********************
Use:
1)For finding session trace files
2)To find OS id (SPID)
3)Info about User & BG Processes

select p.*,s.*
from V$process p,V$session s
where s.paddr = p.addr and s.status


v$session + v$sqltext
**********************
Use: which query the session is executing

select ses.*,st.*
from v$session ses, v$sqltext st
where st.address = ses.sql_address
and st.hash_value=ses.sql_hash_value


v$session + v$sql
***********************
Use:
1)SQL Query details in which the session is executing

select sess.*,ss.*
from v$session sess,v$sql ss.
where sess.sql_id   = ss.sql_id


V$session + v$process + v$sql
*****************************
Use: More details about a session.

select s.*,p.*,ss.*
from v$session s,v$process p,v$sqlarea ss
where s.paddr=p.addr
and ss.sql_id(+)=s.sql_id



************

Tuesday 26 August 2014

What is happenng inside the DB





To find out all the activities in side database in detail

Login as sys and execute the below query:

select
p.spid os_process_id,
'alter system kill session ' || ''''||s.sid||','||s.serial#||''' immediate;' Kill_command,
nvl (p.pname,'user process') process_name,
nvl(s.username,'BG') USERNAME,
s.sid,
s.serial#,
ss.px_servers_executions,
s.status,
s.osuser,
s.machine,
s.blocking_session,
s.blocking_session_status,
s.state,
s.event,
s.wait_class,
round(s.wait_time_micro/1000000) wait_time_insec,
s.service_name,
s.program,
s.module,
s.logon_time,
s.sql_id current_sql_id,
nvl(s.sql_id,prev_sql_id) last_exc_sql_id,
nvl2(BLOCKING_SESSION,s.sid||' Is Blocked by: '||blocking_Session,'No Block') blocking_status,
ss.sql_text,ss.sql_fulltext
from v$session s,v$process p,v$sqlarea ss
where s.paddr=p.addr
and ss.sql_id(+)=s.sql_id
--and s.username like 'USERNAME'
--and s.osuser != 'OSUSER_NAME'
--and s.machine like '%MACHINTNAME%'
order by 5;



**************









Monday 25 August 2014

When to rebuild index ?



Index is one of interesting objects in database, which always attract DBAs and Developers to fine tune their queries. Because index is just like salt in food. It should be used optimized quantity. Some time index doesn't show actual expected performance. In those cases we need to check whether index need to be rebuild or not.

There are certain cafeterias for rebuilding an index:

The number of deleted leaf nodes :-
The number of index nodes that have been logically deleted as a result of  row deletes. Remember that Oracle leaves "dead" index nodes in the index when rows are deleted. This is done to speed up SQL deletes, since Oracle does not have to re balance the index tree when rows are deleted.

Index height :-  The number of levels that are spawned by the index as a result in row inserts. When a large amount of rows are added to a table, Oracle may spawn additional levels of an index to accommodate the new rows. Hence, an Oracle index may have four levels, but only in those areas of the index tree where the massive inserts have occurred. Oracle indexes can support many millions of entries in three levels.

Gets per index access :- The amount of logical I/O that is required to fetch a row with the index. As you may know, a logical "get" is not necessarily a physical I/O since much of the index may reside in the Oracle buffer cache. Unfortunately, Oracle does not make it easy to capture this information. In Oracle we must issue these commands:

ANALYZE INDEX index_name COMPUTE STATISTICS;
ANALYZE INDEX index_name VALIDATE STRUCTURE;

After you analyze the report above, you may want to consider rebuilding any index where the height is more than three levels, since three levels will support millions of index entries.

As you may know, you can easily rebuild an Oracle index with the command:

ALTER INDEX index_name REBUILD;



      ********************