Tuesday, 26 July 2016

Resize your Oracle datafiles down to the minimum without ORA-03297

Your datafiles have grown in the past but now you want to reclaim as much space as possible, because you are short on filesystem space, or you want to move some files without moving empty blocks, or your backup size is too large. ALTER DATABASE DATAFILE … RESIZE can reclaim the space at the end of the datafile, down to the latest allocated extent.
But if you try to get lower, you will get:
ORA-03297: file contains used data beyond requested RESIZE value


So, how do you find this minimum value, which is the datafile’s high water mark?
You have the brute solution: try a value. If it passes, then try a lower value. If it failed, then try a higher one.
Or there is the smart solution: find the datafile high water mark.
You can query DBA_EXTENTS to know that. But did you try on a database with a lot of datafiles? It runs forever. Because DBA_EXTENTS is doing a lot of joins that you don’t need here. So my query directly reads SYS.X$KTFBUE which is the underlying fixed table that gives extent allocation in Locally Managed Tablespaces.
Note that the query may take a few minutes when you have a lot of tables, because the information is on disk, in each segment header, in the bitmaps used by LMT tablepaces. And you have to read all of them.
Here is my query:

set linesize 1000 pagesize 0 feedback off trimspool on with hwm as ( -- get highest block id from each datafiles ( from x$ktfbue as we don't need all joins from dba_extents ) select /*+ materialize */ ktfbuesegtsn ts#,ktfbuefno relative_fno,max(ktfbuebno+ktfbueblks-1) hwm_blocks from sys.x$ktfbue group by ktfbuefno,ktfbuesegtsn ), hwmts as ( -- join ts# with tablespace_name select name tablespace_name,relative_fno,hwm_blocks from hwm join v$tablespace using(ts#) ), hwmdf as ( -- join with datafiles, put 5M minimum for datafiles with no extents select file_name,nvl(hwm_blocks*(bytes/blocks),5*1024*1024) hwm_bytes,bytes,autoextensible,maxbytes from hwmts right join dba_data_files using(tablespace_name,relative_fno) ) select case when autoextensible='YES' and maxbytes>=bytes then -- we generate resize statements only if autoextensible can grow back to current size '/* reclaim '||to_char(ceil((bytes-hwm_bytes)/1024/1024),999999) ||'M from '||to_char(ceil(bytes/1024/1024),999999)||'M */ ' ||'alter database datafile '''||file_name||''' resize '||ceil(hwm_bytes/1024/1024)||'M;' else -- generate only a comment when autoextensible is off '/* reclaim '||to_char(ceil((bytes-hwm_bytes)/1024/1024),999999) ||'M from '||to_char(ceil(bytes/1024/1024),999999) ||'M after setting autoextensible maxsize higher than current size for file ' || file_name||' */' end SQL from hwmdf where bytes-hwm_bytes>1024*1024 -- resize only if at least 1MB can be reclaimed order by bytes-hwm_bytes desc /



and here is a sample output:


/* reclaim    3986M from    5169M */ alter database datafile '/u01/oradata/DB1USV/datafile/o1_mf_undotbs1_o9pfojva_.dbf' resize 1183M;
/* reclaim    3275M from   15864M */ alter database datafile '/u01/oradata/DB1USV/datafile/o1_mf_apcpy_o5pfojni_.dbf' resize 12589M;
/* reclaim    2998M from    3655M */ alter database datafile '/u01/oradata/DB1USV/datafile/o1_mf_cpy_qt_oepfok3n_.dbf' resize 657M;
/* reclaim    2066M from    2250M */ alter database datafile '/u01/oradata/DB1USV/datafile/o1_mf_undotbs2_olpfokc9_.dbf' resize 185M;
/* reclaim     896M from    4000M */ alter database datafile '/u01/oradata/DB1USV/datafile/o1_mf_cpy_ocpfok3n_.dbf' resize 3105M;


You get directly the resize statements, with the reclaimable space in comments.
A few remarks about my query:
  • I generate the resize statements only for datafiles which are autoextensible. This is because I want to be sure that the datafiles can grow back to their original size if needed.
  • When datafile is not autoextensible, or maxsize is not higher than the current size, I only generate a comment.
  • When a datafile has no extents at all I generate a resize to 5MB. I would like to find the minimum possible size (without getting ORA-3214) but my test do not validate yet what is documented in MOS. If anyone has an idea, please share.
  • There is probably a way to get that high water mark in a cheaper way. Because the alter statement gives the ORA-03297 much quicker. Information is probably available in the datafile headers, without going to segment headers, but I don’t know if it is exposed in a safe way. If you have an idea, once again, please share.




Sunday, 24 July 2016

SWITCHOVER and SWITCHBACK in Data guard

SWITCHOVER and SWITCHBACK in Data guard

Switching Over to a Physical Standby Database

SWITCHOVER STEPS:-

PRIMARY
-------
check DR SYNC STATUS
http://select-star-from.blogspot.in/2013/09/data-guard-sync-status.html

SQL>archive log list
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>alter database commit to switchover to physical standby with session shutdown;
SQL>shutdown immediate
SQL>startup nomount
SQL>alter database mount standby database;
SQL>alter system set log_archive_dest_state_2=defer scope=both;
SQL>select name,open_mode,database_role,switchover_status from v$database;
SQL>show parameter log_archive_dest_state_2;

STANDBY
-------
SQL>archive log list
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>alter database commit to switchover to primary;
SQL>shutdown immediate
SQL>startup

OLD PRIMARY ----->New STANDBY
-----------
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>recover managed standby database disconnect;
SQL>select process,status,sequence# from v$managed_standby;

OLD STANDBY ----->New PRIMARY
-----------
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>show parameter log_archive_dest_state_2;
SQL>alter system set log_archive_dest_state_2=enable scope=both;
SQL>alter system switch logfile;
SQL>alter system switch logfile;
SQL>alter system switch logfile;
SQL>alter system switch logfile;
SQL>select status, gap_status from v$archive_dest_status where dest_id = 2;  --------11gr2 onwards

check DR SYNC STATUS

http://select-star-from.blogspot.in/2013/09/data-guard-sync-status.html

SWITCHBACK STEPS:-

OLD STANDBY ----->New PRIMARY
-----------
check DR SYNC STATUS
http://select-star-from.blogspot.in/2013/09/data-guard-sync-status.html

SQL>archive log list
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>alter database commit to switchover to physical standby with session shutdown;
SQL>shutdown immediate
SQL>startup nomount
SQL>alter database mount standby database;
SQL>alter system set log_archive_dest_state_2=defer scope=both;
SQL>select name,open_mode,database_role,switchover_status from v$database;
SQL>show parameter log_archive_dest_state_2;

OLD PRIMARY ----->New STANDBY
-----------
SQL>archive log list
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>alter database commit to switchover to primary;
SQL>shutdown immediate
SQL>startup

OLD STANDBY ----->New PRIMARY ----->ORIGINAL STANDBY
-----------
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>recover managed standby database disconnect;
SQL>select process,status,sequence# from v$managed_standby;

OLD PRIMARY ----->New STANDBY ----->ORIGINAL STANDBY
-----------
SQL>select name,instance_name,open_mode,database_role,switchover_status from v$database,v$instance;
SQL>show parameter log_archive_dest_state_2;
SQL>alter system set log_archive_dest_state_2=enable scope=both;
SQL>alter system switch logfile;
SQL>alter system switch logfile;
SQL>alter system switch logfile;
SQL>select status, gap_status from v$archive_dest_status where dest_id = 2; --------11gr2 onwards

check DR SYNC STATUS
http://select-star-from.blogspot.in/2013/09/data-guard-sync-status.html

SOURCE : Internet

Reference(s):
http://emrebaransel.blogspot.in/2008/08/dataguard-switchover-guide-physical_09.html
http://subhendrasahu.blogspot.in/2012/05/switchover-from-primaryto-standby.html

http://shivanandarao.wordpress.com/2012/08/28/dataguard-failover/



In RAC Environment

Hi Guys,

Today I performed RAC Switchover / Switchback for 2 Node Primary with 2 Node Standby on OEL. I expected some issues, but it was totally smooth. Giving you steps for the same, so it will be useful to you. Even this would be my first contribution to Oracle Forums.

DB Name     DB Unique Name     Host Name     Instance Name
--------------------------------------------------------------------------------------
live     live     linux1     live1
live     live     linux2     live2
live     livestdby     linux3     livestdby1
live     livestdby     linux4     livestdby2


Verify that each database is properly configured for the role it is about to assume and the standby database is in mounted state. 
(Verify all Dataguard parameters on each node for Primary & Standby)

Like,
Log_archive_dest_1
Log_archive_dest_2
Log_archive_dest_state_1
Log_archive_dest_state_2
Fal_client
Fal_server
Local_listener
Remote_listener
Standby_archive_Dest
Standby_archive_management
service_names
db_unique_name
instance_name
db_file_name_convert
log_file_name_convert

Verify that both Primary RAC & Dataguard RAC are functioning properly and both are in Sync
On Primary, 
Select thread#,max(sequence#) from v$archived_log group by thread#;
On Standby,
Select thread#,max(sequence#) from v$log_history group by thread#;

Before performing a switchover from a RAC primary shut down all but one primary instance (they can be restarted after the switchover has completed). 
./srvctl stop instance –d live –i live1
or
sql>shutdown immediate
Before performing a switchover or a failover to a RAC standby shut down all but one standby instance (they can be restarted after the role transition has completed). 
./srvctl stop instance –d live –i livestdby1
or
sql>shutdown immediate;

On the primary database initiate the switchover: 
alter database commit to switchover to physical standby with session shutdown;
Shutdown former Primary database & Startup in Mount State.
Shut immediate;
Startup mount;
select name,db_unique_name, log_mode,open_mode,controlfile_type,switchover_status,database_role from v$database;

Make log_Archive_Dest_state_2 to DEFER
alter system set log_archive_dest_state_2='DEFER' sid='*';

On the (old) standby database, 
select name,log_mode,open_mode,controlfile_type,switchover_status,database_role from v$database;

On the (old) standby database switch to new primary role: 
alter database commit to switchover to primary; 
shut immediate;
startup;

On new Primary database,
select name,log_mode,open_mode,controlfile_type,switchover_status,database_role from v$database;
Make log_Archive_Dest_state_2 to ENABLE
alter system set log_archive_dest_state_2='ENABLE' sid='*';
Add tempfiles in New Primary database.
Do some archivelog switches on new primary database & verify that archives are getting transferred to Standby database.

On new primary, 
select error from v$archive_Dest_status;
select max(sequence#) from v$archived_log;

On new Standby, Start Redo Apply

alter database recover managed standby database using current logfile disconnect;

Select max(sequence#) from v$log_history; (should be matching with Primary)



Now Start RAC databases services (both Primary – in open & Standby – in mount)
On new Primary Server.
./srvctl start instance –d live –i livestdby2
Verify using ./crs_stat –t
Check that database is opened in R/W mode.
On new Standby Server.      
./srvctl start instance –d live –i live2 –o mount

Now add TAF services on new Primary (former Standby) Server.
By Command Prompt,
./srvctl add service -d live -s srvc_livestdby -r livestdby1,livestdby2 -P BASIC
OR
By GUI,
dbca -> Oracle Read Application Cluster database -> Service Management -> select database -> add services, details (Preferred / Available), TAF Policy (Basic / Preconnect) - > Finish

Start the services,
./srvctl start service -d live

Verify the same,
./crs_stat -t

Perform TAF testing, to make sure Load Balancing & Failover.