Sunday, August 22, 2010

Managing Control Files



Every Oracle Database has a control file, which is a small binary file that records the physical structure of the database. The control file includes:

·         The database name
·         Names and locations of associated datafiles and redo log files
·         The timestamp of the database creation
·         The current log sequence number
·         Checkpoint information
It is strongly recommended that you multiplex control files  i.e. Have at least two control files one in one hard disk and another one located in another disk, in a database.  In this way if control file becomes corrupt in one disk the another copy will be available and you don’t have to do recovery of control file.
You can  multiplex control file at the time of creating a database and later on also. If you have not multiplexed control file at the time of creating a database you can do it now by following given procedure.

Multiplexing Control File

Steps:
      1.      Shutdown the Database.
SQL>SHUTDOWN IMMEDIATE;

    2.      Copy the control file from old location to new location using operating system command. For example.
$cp /u01/oracle/ica/control.ora  /u02/oracle/ica/control.ora

    3.      Now open the parameter file and specify the new location like this
CONTROL_FILES=/u01/oracle/ica/control.ora
Change it to
CONTROL_FILES=/u01/oracle/ica/control.ora,/u02/oracle/ica/control.ora

    4.      Start the Database
Now Oracle will start updating both the control files and, if one control file is lost you can copy  it from another location.

Changing the Name of a Database

If you ever want to change the name of database or want to change the setting of MAXDATAFILES, MAXLOGFILES, MAXLOGMEMBERS then you have to create a new control file.

Creating A New Control File

Follow the given steps to create a new controlfile
Steps
1.      First generate the create controlfile statement
SQL>alter database backup controlfile to trace;
After giving this statement oracle will write the CREATE CONTROLFILE statement in a trace file. The trace file will be randomly named something like ORA23212.TRC and it is created in USER_DUMP_DEST directory.
2.      Go to the USER_DUMP_DEST directory and open the latest trace file in text editor. This file will contain the CREATE CONTROLFILE statement. It will have two sets of statement one with RESETLOGS and another without RESETLOGS. Since we are changing the name of the Database we have to use RESETLOGS option of CREATE CONTROLFILE statement. Now copy and paste the statement in a file. Let it be c.sql

3.      Now open the c.sql file in text editor and set the database name from ica to prod shown in an example below
CREATE CONTROLFILE
   SET DATABASE prod   
   LOGFILE GROUP 1 ('/u01/oracle/ica/redo01_01.log',
                    '/u01/oracle/ica/redo01_02.log'),
           GROUP 2 ('/u01/oracle/ica/redo02_01.log',
                    '/u01/oracle/ica/redo02_02.log'),
           GROUP 3 ('/u01/oracle/ica/redo03_01.log',
                    '/u01/oracle/ica/redo03_02.log')
   RESETLOGS
   DATAFILE '/u01/oracle/ica/system01.dbf' SIZE 3M,
            '/u01/oracle/ica/rbs01.dbs' SIZE 5M,
            '/u01/oracle/ica/users01.dbs' SIZE 5M,
            '/u01/oracle/ica/temp01.dbs' SIZE 5M
   MAXLOGFILES 50
   MAXLOGMEMBERS 3
   MAXLOGHISTORY 400
   MAXDATAFILES 200
   MAXINSTANCES 6
   ARCHIVELOG;

4.      Start and do not mount the database.
SQL>STARTUP NOMOUNT;

5.      Now execute c.sql script
SQL> @/u01/oracle/c.sql

6.      Now open the database with RESETLOGS
SQL>ALTER DATABASE OPEN RESETLOGS;

Cloning an Oracle Database.

You have a Production database running in one server. The company management wants to develop some new modules and they have hired some programmers to do that. Now these programmers require access to the Production database and they want to make changes to it. You as a DBA can’t give direct access to Production database so you want to create a copy of this database on another server and wants to give developers access to it.
Let us see an example of cloning a database
We have a database running the production server with the following files
PARAMETER FILE located in /u01/oracle/ica/initica.ora

CONTROL FILES=/u01/oracle/ica/control.ora
BACKGROUND_DUMP_DEST=/u01/oracle/ica/bdump
USER_DUMP_DEST=/u01/oracle/ica/udump
CORE_DUMP_DEST=/u01/oracle/ica/cdump
LOG_ARCHIVE_DEST_1=”location=/u01/oracle/ica/arc1”

DATAFILES =
     /u01/oracle/ica/sys.dbf
     /u01/oracle/ica/usr.dbf
     /u01/oracle/ica/rbs.dbf
     /u01/oracle/ica/tmp.dbf
     /u01/oracle/ica/sysaux.dbf
LOGFILE=
     /u01/oracle/ica/log1.ora
     /u01/oracle/ica/log2.ora
Now you want to copy this database to SERVER  2 and in SERVER 2 you don’t have /u01 filesystem. In SERVER 2 you have /d01 filesystem.
To Clone this Database on SERVER 2 do the following.
Steps :-
1.      In SERVER 2 install the same version of o/s and same version Oracle as in SERVER 1.

2.      In SERVER 1 generate CREATE CONTROLFILE statement by typing the following command

SQL>alter database backup controlfile to trace;

Now, go to the USER_DUMP_DEST directory and open the latest trace file. This file will contain steps and as well as CREATE CONTROLFILE statement. Copy the CREATE CONTROLFILE statement and paste in a file. Let the filename be cr.sql

The CREATE CONTROLFILE Statement will look like this.
CREATE CONTROLFILE
   SET DATABASE prod   
   LOGFILE GROUP 1 ('/u01/oracle/ica/log1.ora'
           GROUP 2 ('/u01/oracle/ica/log2.ora'
  DATAFILE '/u01/oracle/ica/sys.dbf' SIZE 300M,
            '/u01/oracle/ica/rbs.dbf' SIZE 50M,
            '/u01/oracle/ica/usr.dbf' SIZE 50M,
            '/u01/oracle/ica/tmp.dbf' SIZE 50M,
            ‘/u01/oracle/ica/sysaux.dbf’ size 100M;
   MAXLOGFILES 50
   MAXLOGMEMBERS 3
   MAXLOGHISTORY 400
   MAXDATAFILES 200
   MAXINSTANCES 6
   ARCHIVELOG;

3.      In SERVER 2 create the following directories
$cd /d01/oracle
$mkdir ica
$mkdir arc1
$cd ica
$mkdir bdump udump cdump

Shutdown the database on SERVER 1 and transfer all datafiles, logfiles and  control file to SERVER 2 in /d01/oracle/ica directory.

Copy parameter file to SERVER 2 in /d01/oracle/dbs directory and copy all archive log files to SERVER 2 in /d01/oracle/ica/arc1 directory. Copy the cr.sql script file to /d01/oracle/ica directory.

4.      Open the parameter file SERVER 2 and change the following parameters

CONTROL FILES=//d01/oracle/ica/control.ora
BACKGROUND_DUMP_DEST=//d01/oracle/ica/bdump
USER_DUMP_DEST=//d01/oracle/ica/udump
CORE_DUMP_DEST=//d01/oracle/ica/cdump
LOG_ARCHIVE_DEST_1=”location=//d01/oracle/ica/arc1”

5.      Now, open the cr.sql file in text editor and change the locations like this
CREATE CONTROLFILE
   SET DATABASE prod   
   LOGFILE GROUP 1 ('//d01/oracle/ica/log1.ora'
           GROUP 2 ('//d01/oracle/ica/log2.ora'
  DATAFILE '//d01/oracle/ica/sys.dbf' SIZE 300M,
            '//d01/oracle/ica/rbs.dbf' SIZE 50M,
            '//d01/oracle/ica/usr.dbf' SIZE 50M,
            '//d01/oracle/ica/tmp.dbf' SIZE 50M,
            ‘//d01/oracle/ica/sysaux.dbf’ size 100M;
   MAXLOGFILES 50
   MAXLOGMEMBERS 3
   MAXLOGHISTORY 400
   MAXDATAFILES 200
   MAXINSTANCES 6
   ARCHIVELOG;
In SERVER 2 export ORACLE_SID environment variable and start the instance
$export ORACLE_SID=ica
$sqlplus
Enter User:/ as sysdba
SQL> startup nomount;
6.      Run cr.sql script to create the controlfile
SQL>@/d01/oracle/ica/cr.sql
7.      Open the database
SQL>alter database open;

Managing REDO LOGFILES



Every Oracle database must have at least 2 redo logfile groups. Oracle writes all statements except, SELECT statement, to the logfiles. This is done because Oracle performs deferred batch writes i.e. it does write changes to disk per statement instead it performs write in batches. So in this case if a user updates a row, Oracle will change the row in db_buffer_cache and records the statement in the logfile and give the message to the user that  row is updated. Actually the row is not yet written back to the datafile but still it give the message to the user that row is updated. After 3 seconds the row is actually written to the datafile. This is known as deferred batch writes. 
Since Oracle defers writing to the datafile there is chance of power failure or system crash before the row is written to the disk. That’s why Oracle writes the statement in redo logfile so that in case of power failure or system crash oracle can re-execute the statements next time when you open the database.

Adding a New Redo Logfile Group

To add a new Redo Logfile group to the database give the following command
SQL>alter database add logfile group 3
‘/u01/oracle/ica/log3.ora’ size 10M;
Note: You can add groups to a database up to the MAXLOGFILES setting you have specified at the time of creating the database. If you want to change MAXLOGFILE setting you have to create a new controlfile.

Adding Members to an existing group

To add new member to an existing group give the following command
SQL>alter database add logfile member
‘/u01/oracle/ica/log11.ora’ to group 1;
Note: You can add members to a group up to the MAXLOGMEMBERS setting you have specified at the time of creating the database. If you want to change MAXLOGMEMBERS setting you have create a new controlfile
Important: Is it strongly recommended that you multiplex logfiles i.e. have at least two log members, one member in one disk and another in second disk, in a database.

Dropping Members from a group

You can drop member from a log group only if the group is having more than one member and if it is not the current group. If you want to drop members from the current group, force a log switch or wait so that log switch occurs and another group becomes current. To force a log switch give the following command
SQL>alter system switch logfile;
The following command can be used to drop a logfile member
SQL>alter database drop logfile member ‘/u01/oracle/ica/log11.ora’;
Note: When you drop logfiles the files are not deleted from the disk. You have to use O/S command to delete the files from disk.

Dropping Logfile Group

Similarly, you can also drop logfile group only if the database is having more than two groups and if it is not the current group.
SQL>alter database drop logfile group 3;
Note: When you drop logfiles the files are not deleted from the disk. You have to use O/S command to delete the files from disk.

Resizing Logfiles

You cannot resize logfiles. If you want to resize a logfile create a new logfile group with the new size and subsequently drop the old logfile group.

Renaming or Relocating Logfiles

To Rename or Relocate Logfiles perform the following steps
For Example, suppose you want to move a logfile from ‘/u01/oracle/ica/log1.ora’ to ‘/u02/oracle/ica/log1.ora’, then do the following
Steps
1.      Shutdown the database
SQL>shutdown immediate;

2.      Move the logfile from Old location to new location using operating system command
$mv /u01/oracle/ica/log1.ora  /u02/oracle/ica/log1.ora

3.      Start and mount the database
SQL>startup mount

4.      Now give the following command to change the location in controlfile
SQL>alter database rename file ‘/u01/oracle/ica/log1.ora’ to ‘/u02/oracle/ica/log2.ora’;
5.      Open the database
SQL>alter database open;

Clearing REDO LOGFILES

A redo log file might become corrupted while the database is open, and ultimately stop database activity because archiving cannot continue. In this situation the ALTER DATABASE CLEAR LOGFILE statement can be used reinitialize the file without shutting down the database.
The following statement clears the log files in redo log group number 3:
ALTER DATABASE CLEAR LOGFILE GROUP 3;

This statement overcomes two situations where dropping redo logs is not possible:
  • If there are only two log groups
  • The corrupt redo log file belongs to the current group
If the corrupt redo log file has not been archived, use the UNARCHIVED keyword in the statement.
ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 3;

This statement clears the corrupted redo logs and avoids archiving them. The cleared redo logs are available for use even though they were not archived.
If you clear a log file that is needed for recovery of a backup, then you can no longer recover from that backup. The database writes a message in the alert log describing the backups from which you cannot recover

Viewing Information About Logfiles

To See how many logfile groups are there and their status type the following query.
SQL>SELECT * FROM V$LOG;
GROUP# THREAD#   SEQ   BYTES  MEMBERS  ARC STATUS     FIRST_CHANGE# FIRST_TIM
------ ------- ----- -------  -------  --- ---------  ------------- ---------
     1       1 20605 1048576        1  YES ACTIVE          61515628 21-JUN-07
     2       1 20606 1048576        1  NO  CURRENT         41517595 21-JUN-07
     3       1 20603 1048576        1  YES INACTIVE        31511666 21-JUN-07
     4       1 20604 1048576        1  YES INACTIVE        21513647 21-JUN-07

To See how many members are there and where they are located give the following query
SQL>SELECT * FROM V$LOGFILE;
GROUP#   STATUS  MEMBER
------  -------  ----------------------------------
     1           /U01/ORACLE/ICA/LOG1.ORA
     2           /U01/ORACLE/ICA/LOG2.ORA