Wednesday, April 6, 2011

Understanding the SCN

In order to understand how Oracle performs recovery, it’s first necessary to understand Oracle’s SCN (System Change Number ) in terms of the various places where it can be stored and how it’s used for instance and media recovery.

The SCN is an internal number maintained by the database management system (DBMS) to log changes made to a database. The SCN increases over time as changes are made to the database by Structured Query Language (SQL). By understanding how the SCN is used, we can understand how Oracle recovery works. Oracle enables us to examine the current SCN using the following SQL as 

SQL> select dbms_flashback.get_system_change_number from dual ; 


Whenever an application commits a transaction, the log writer process (LGWR) writes records from the redo log buffers in the System Global Area (SGA) to the online redo logs on disk. LGWR also writes the transaction’s  SCN to the online redo log file. The success of this atomic write event determines whether our transaction succeeds, and it requires a synchronous (wait-until-completed) write to disk


Note : The need for a synchronous write upon commit is one of the reasons why the online redo log can become a bottleneck for applications and why we should commit as infrequently as is practical. In general, Oracle writes asynchronously to the database datafiles for performance reasons, but commits require a synchronous write because they must be guaranteed at the time they occur.

SCN and Checkpoints : 
A checkpoint occurs when all modified database buffers in the Oracle SGA are written out to datafiles by the database writer (DBWn) process. The checkpoint process (CKPT) updates all datafiles and control files with the SCN at the time of the checkpoint and signals DBWn to write out the blocks. A successful checkpoint guarantees that all database changes up to the checkpoint SCN have been recorded in the datafiles. As a result, only those changes made after the checkpoint need to be applied during recovery. Checkpoints occur automatically as follows:

  • Whenever a redo log switch takes place.
  • Whenever the time set by the LOG_CHECKPOINT_TIMEOUT initialization parameter is reached.
  • Whenever the amount of redo written reaches the number of bytes associated with the LOG_CHECKPOINT_INTERVAL.
Typically, LOG_CHECKPOINT_INTERVAL is chosen so that checkpoints only occur on log switches. Oracle stores the SCN associated with the checkpoint in four places: three of them in the control file and one in the datafile header for each datafile.

The System Checkpoint SCN :
After a checkpoint completes, Oracle stores the system checkpoint SCN in the control file. We can access the checkpoint SCN using the following SQL as

SQL> select checkpoint_change# from v$database ; 
      CHECKPOINT_CHANGE#
        ------------------------------
              292767

The Datafile Checkpoint SCN :
After a checkpoint completes, Oracle stores the SCN individually in the control file for each datafile. The following SQL shows the datafile checkpoint SCN for a single datafile in the control file:

SQL> select   name,  checkpoint_change#   from  v$datafile  where  name  like  '%USER%'  ; 
 NAME                                               CHECKPOINT_CHANGE#
--------------------------------------------          --------------------
/u02/oradata/OMFD1/users01.dbf                  292767

The Start SCN :
Oracle stores the checkpoint SCN value in the header of each datafile. This is referred to as the start SCN because it is used at instance startup time to check if recovery is required. The following SQL shows the checkpoint SCN in the datafile header for a single datafile:

SQL> select name,checkpoint_change# from v$datafile_header where name like '%USERS01%' ;
 NAME                                                           CHECKPOINT_CHANGE#
---------------------------------------------          --------------------------
/u02/oradata/OMFD1/users01.dbf                           292767

The Stop SCN : 
The stop SCN is held in the control file for each datafile. The following SQL shows the stop SCN for a single datafile when the database is open for normal use:

SQL> select name,last_change# from v$datafile where name like  '%USERS01%' ;
 NAME                                                             LAST_CHANGE#
----------------------------------------------                ------------
/u02/oradata/OMFD1/users01.dbf  

During normal database operation, the stop SCN is NULL for all datafiles that are online in read-write mode. SCN Values while the Database Is Up Following a checkpoint while the database is up and open for use, the system checkpoint in the control file, the datafile checkpoint SCN in the control file, and the start SCN in each datafile header all match. The stop SCN for each datafile in the control file is NULL. SCN after a Clean Shutdown After a clean database shutdown resulting from a SHUTDOWN IMMEDIATE or  SHUTDOWN NORMAL of the database, followed by STARTUP MOUNT, the previous queries on v$database and v$datafile return the following:

SQL> select checkpoint_change# from v$database ; 
      CHECKPOINT_CHANGE#
    -----------------------------
                  293184

SQL> select  name,checkpoint_change#, last_change#   from v$datafile where  name  like  '%USER%';
 NAME                                                    CHECKPOINT_CHANGE#   LAST_CHANGE#
------------------------------------------             ------------------------              --------------
/u02/oradata/OMFD1/users01.dbf                      293184                     293184

SQL> select name,checkpoint_change# from v$datafile_header where name like '%USERS%' ;
 NAME                                                          CHECKPOINT_CHANGE#
--------------------------------------------       -----------------------------
/u02/oradata/OMFD1/users01.dbf                             293184

During a clean shutdown, a checkpoint is performed and the stop SCN for each datafile is set to the start  SCN from the datafile header. Upon startup, Oracle checks the start SCN in the file header with the datafile checkpoint SCN. If they match, Oracle checks the start SCN in the datafile header with the datafile stop SCN in the control file. If they match, the database can be opened because all block changes  have been applied, no changes were lost on shutdown, and therefore no recovery is required on startup. After the database is opened, the datafile stop SCN in the control file once again changes to NULL to indicate  that the datafile is open for normal use.


SCN after an Instance Crash :
The previous example showed the behavior of the SCN after a clean shutdown. To demonstrate the behavior of the checkpoints after an instance crash, the following SQL creates a table (which performs an implicit commit) and inserts a row of data into it without a commit:

SQL> create   table   x(x number)   tablespace   users ;  
SQL> insert   into   x   values  (100)  ; 

If the instance is crashed by using SHUTDOWN ABORT, the previous queries on v$database and v$datafile return the following after the database is started up in mount mode :

SQL> select checkpoint_change# from v$database;
  CHECKPOINT_CHANGE#
   --------------------------------
              293185

SQL> select name,checkpoint_change#,last_change# from v$datafile where name like  '%USER%'  ;
NAME                                                       CHECKPOINT_CHANGE#   LAST_CHANGE#
-----------------------------------                   ---------------------------          -------------------
/u02/oradata/OMFD1/users01.dbf                  293185        

In this case, the stop SCN is not set, which is indicated by the NULL value in the LAST_CHANGE# column. This information enables Oracle, at the time of the next startup, to determine that the instance crashed because the checkpoint on shutdown was not performed. If it had been performed, the LAST_CHANGE# and CHECKPOINT_CHANGE# values would match for each datafile as they did during a clean shutdown. If an instance crashes at shutdown, then instance crash recovery is required the next time the instance starts up.

Recovery from an Instance Crash :

Upon the next instance startup that takes place after SHUTDOWN ABORT or a DBMS crash, the Oracle DBMS detects that the stop SCN for datafiles is not set in the control file during startup. Oracle then performs   crash recovery. During crash recovery, Oracle applies redo log records from the online redo  logs in a process referred to as roll forward to ensure that all transactions committed before the crash are applied to the datafiles. Following roll forward, active transactions that did not commit are   identified from the rollback segments and are undone before the blocks involved in the active transactions  can be accessed . This process is referred to as roll back. In our example, the following transaction was active but not committed at the time of the SHUTDOWN ABORT, so it needs to be rolled back:


SQL> insert into x values(100);

After  instance startup,  the X table exists,  but  remains empty. Instance     recovery happens    automatically at database startup without   database administrator (DBA) intervention.   It may   take   a while because   of the    need to    apply     large    amounts   of outstanding redo changes to data    blocks    for transactions   that completed and those that didn’t complete and require roll back.

Recovery from a Media Failure :
Up   until   this   point, the  checkpoint   start   SCN in  the  datafile  header  has always  matched  the datafile checkpoint  SCN  number held  in  the control file. This is reasonable  because  during a  checkpoint,  the  datafile  checkpoint  SCN in  the control  file and  the start SCN  in the  datafile  header are  both   updated, along  with   the  system  checkpoint  SCN.  The  following  SQL  shows  the  start  SCN  from  the  datafile header  and  datafile  checkpoint SCN from  the  control file  for the  same file:

SQL> select 'controlfile' "SCN location",name,checkpoint_change# from v$datafile where name like '%USER%'
union
select 'file header',name,checkpoint_change# from v$datafile_header where name like '%USER%' ;

SCN location                      NAME                                        CHECKPOINT_CHANGE#
--------------     -------------------------------------------       --------------------
controlfile          /u02/oradata/OMFD1/users01.dbf                      293188
file header        /u02/oradata/OMFD1/users01.dbf                       293188

Unlike the v$datafile view, there is no stop SCN column in the v$datafile_header view because v$datafile_header is not used at instance startup time to indicate that an instance crash occurred. However, the v$datafile_header does provide the Oracle DBMS with the information it requires to perform media recovery. At instance startup, the datafile checkpoint SCN in the control file and the start SCN in the datafile header are checked for equality. If they don’t match, it is a signal that media recovery is required.

For example, media recovery is required if a media failure has occurred and the original datafile has been replaced with a backup copy. In this case, the start SCN in the backup copy is less than the checkpoint SCN value in the control file, and Oracle requests archived redo logs—generated at the time of previous log switches—in order to reapply the changes required to bring the datafile up to the current point in time.

In order to recover the database from a media failure, we must run the database in ARCHIVELOG mode to ensure that all database changes from the online redo logs are stored permanently in archived redo log files. In order to enable ARCHIVELOG mode, we must run the command ALTERDATABASE ARCHIVELOG when the database is in a mounted state.

We can identify files that need recovery after we have replaced a datafile with an older version by starting the instance in mount mode and running the following SQL:

SQL> select file#,change# from v$recover_file;
     FILE#         CHANGE#
   ----------     ----------
         4            313401

In this example, file 4 is the datafile in the USERS tablespace. By reexecuting the previous SQL to display the datafile checkpoint SCN in the control file and the start SCN in the datafile header, we can see that the start SCN is older due to the restore of the backup datafile that has taken place:

SQL> select 'controlfile' "SCN location",name,checkpoint_change#
from v$datafile where name like '%USER%'
union
select 'file header',name,checkpoint_change#
from v$datafile_header where name like '%USER%';

SCN location           NAME                                                   CHECKPOINT_CHANGE#
--------------    -------------------------------------------      --------------------
controlfile        /u02/oradata/OMFD1/users01.dbf                         313551
file header       /u02/oradata/OMFD1/users01.dbf                         313401

If we were to attempt to open the database, we  would receive errors like the following:
ORA-01113: file 4 needs media recovery
ORA-01110: datafile 4: '/u02/oradata/OMFD1/users01.dbf'

We   can recover the   database by issuing   RECOVER   DATABASE   from SQL*Plus while the   database  is in a mounted state. If  the  changes  needed  to  recover the  database  to the point in time   before the crash are  in an archived redo log,  then we will be prompted to accept the suggested name:

ORA-00279: change 313401 generated at 11/10/2001 18:50:23 needed for thread
ORA-00289: suggestion : /u02/oradata/OMFD1/arch/T0001S0000000072.ARC
ORA-00280: change 313401 for thread 1 is in sequence #72

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

If  we respond to  the prompt  using  AUTO, Oracle  applies  any archived  redo logs  it needs,  followed  by any  necessary changes  in the online redo logs, to bring the database right up to the last committed transaction before the  media failure that caused  the  requirement for  the  restore.

So far, we’ve considered  recovery scenarios  where the  goal is  to  recover  the database to  the most recent  transaction. This  is known as complete recovery. The RECOVER DATABASE command has several  other  options  that  enable  us to  recover  from a  backup to a point in  time before  the  most  recent  transaction  by  rolling  forward and then stopping the application of the redo log changes at a specified point. This is known as  incomplete recovery. We can specify a time or an SCN as the recovery point. For example,

RMAN> recover database until time '2001-11-10:18:52:00';
RMAN> recover database until change 313459;

Before  we perform incomplete recovery,  it’s recommended  that we restore  a complete database backup first. After incomplete recovery, we must open the mounted database with ALTER DATABASE OPEN RESETLOGS. This creates a new incarnation of the database and clears the contents of the existing redo logs to make sure they can’t be applied.

Recovery from a Media Failure Using a Backup Control File :

In  the previous example, we had access to a current control file at the time of the media failure. This  means that  none  of the  start SCN  values  in the datafile  headers exceeded  the system checkpoint  SCN number in  the control file.  To recap,  the  system  checkpoint  number  is  given  by  the  following  :

SQL> select checkpoint_change# from v$database;

We   might  be wondering  why  Oracle  needs to maintain  the last system   checkpoint value in the control file  as  well  as  checkpoint  SCNs  in the control file for each datafile (as used in the previous example). There are two reasons  for this. The first  is  that  we  might  have  read-only  tablespaces  in  our  database. In this  case, the database  checkpoint  SCN increases, and  the checkpoint  SCN for the datafiles in the read-only tablespace remains frozen in the control file.

The  following  SQL  report  output  shows  a  database  with a read-write tablespace (USERS)               and  read-only  tablespace (TEST). The  start SCN  in the file  header  and the checkpoint SCN in the control  file for  TEST  are less  than the system checkpoint value. Once a tablespace is read only, checkpoints  have no  effect on the files in it. The other read-write tablespace has checkpoint values that match the system checkpoint:

SCN location         NAME                             CHECKPOINT_CHANGE#
-------------------- ---------------------------------- ----------------
controlfile          SYSTEM checkpoint                           355390
file header          /u02/oradata/OD2/users01.dbf                355390
file in controlfile  /u02/oradata/OD2/users01.dbf                355390
file header          /u02/oradata/OD2/test01.dbf                 355383
file in controlfile  /u02/oradata/OD2/test01.dbf                 355383

The   second  reason  for  the  maintenance  of multiple  checkpoint  SCNs   in  the  control  file  is  that we might  not have  a current  control  file available  at  recovery   time. In  this  case, we need to restore  an earlier   control  file  before  we can perform a recovery. The system checkpoint in the control file may indicate  an earlier  change  than  the  start  SCN  in  the  datafile  headers.

The following SQL shows an example where the system checkpoint SCN and datafile checkpoint SCN indicate an earlier change than the start SCN in the datafile header:

SQL> select 'controlfile' "SCN location",'SYSTEM checkpoint' name,checkpoint_change# 
from v$database 
union
select 'file in controlfile',name,checkpoint_change# 
from v$datafile where name like 'users01%' 
union
select 'file header',name,checkpoint_change# 
from v$datafile_header where name like '%USER%' ; 

SCN location                 NAME                                 CHECKPOINT_CHANGE#
------------------- ------------------------------           ------------------
controlfile               SYSTEM checkpoint                            333765
file header             /u02/oradata/OD2/users01.dbf                 355253
file in controlfile    /u02/oradata/OD2/users01.dbf                 333765

If we try to recover a database in the usual way in this situation, Oracle detects that the control file is older than some of the datafiles, as indicated by the checkpoint SCN values in the datafile headers, and reports the following message:

SQL> recover database ; 
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done

If  we  want to proceed with  recovery in this situation, we need to indicate to Oracle that  a noncurrent control  file  possibly containing  mismatches  in the SCN  values  identified  by  the   previous  error  messages  is  about to  be specified  for recovery  by  using  the  following command:

RMAN> recover database using BACKUP CONTROLFILE  ; 

Reference:   http://www.dbapool.com/


Enjoy     :-) 


How to Comapare two Tables Data Difference

Comparing two table is a common task in day to day life of DBA . The Table which has to be compare may on same database or on different database . If the tables are in different database then we can use the database link to compare the two table . Let's have a look on the below tables . 

SQL> select *   from  (
( select * from dept1
  minus                                    //  all rows that are in T1 but not in T2
  select * from dept2 )
union all
( select * from dept2 
  minus                                  // all rows that are in T2 but not in T1
  select * from dept1 )
)




Enjoy    :-) 




Tuesday, April 5, 2011

Setting Up AUTOTRACE in SQL*Plus

AUTOTRACE is a facility  within  SQL*Plus that  shows us the explain  plan of  the  queries that we  have executed  and the resources they used. This topic makes extensive  use  of  the AUTOTRACE facility.There is more than  one way to  get AUTOTRACE configured. This is what I like to do to get AUTOTRACE working :
1.) cd  $ORACLE_HOME\rdbms\admin
2.) log into SQL*Plus as SYSTEM
3.) Run @utlxplan
4.) run the below command 


SQL> create public synonym plan_table for plan_table ; 
SQL> grant all on plan_table to public ;
We can  automatically get  a report  on the  execution path  used by the  SQL optimizer  and  the statement execution statistics. The report is  generated  after  successful  SQL DML ( i.e., select,delete,update,merge and insert ) statements. It  is  useful  for monitoring and  tuning the  performance of these  statements. We can control the  report by  setting  AUTOTRACE  system  variable.

1.) SET AUTOTRACE OFF : No AUTOTRACE report is generated. This is the default.
2.) SET AUTOTRACE ON : The AUTOTRACE report includes both the optimizer execution path and the SQL statement execution statistics. Here is an demo 
SQL> set autotrace on 
SQL>select e.last_name,e.salary,j.job_title from employees e , jobs j where e.job_id=j.job_id and e.salary> 12000 ;
LAST_NAME              SALARY               JOB_TITLE
----------------             ----------          -----------------------
King                           24000              President
Kochhar                     17000              Administration Vice President
De Haan                    17000              Administration Vice President
Russell                      14000               Sales Manager
Partners                    13500               Sales Manager
Hartstein                   13000               Marketing Manager
6 rows selected.


The statement can be automatically traced when it is run :
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES'
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'JOBS'
   4    2       INDEX (RANGE SCAN) OF 'EMP_JOB_IX' (NON-UNIQUE)

Statistics
----------------------------------------------------------
          0  recursive calls
          2  db block gets
         34  consistent gets
          0  physical reads
          0  redo size
        848  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          6  rows processed


3.) SET AUTOTRACE ON STATISTICS :  The AUTOTRACE report shows only the SQL statement execution statistics.
SQL>set autotrace on statistics
SQL>select e.last_name,e.salary,j.job_title from employees e , jobs j where e.job_id=j.job_id and e.salary> 12000 ;

LAST_NAME              SALARY              JOB_TITLE
----------------            ----------            -----------------------
King                           24000              President
Kochhar                     17000              Administration Vice President
De Haan                    17000               Administration Vice President
Russell                      14000               Sales Manager
Partners                    13500               Sales Manager
Hartstein                   13000               Marketing Manager
6 rows selected.

Statistics
----------------------------------------------------------
          0  recursive calls
          2  db block gets
         34  consistent gets
          0  physical reads
          0  redo size
        848  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          6  rows processed

4.) SET AUTOTRACE ON EXPLAIN : The AUTOTRACE report shows only the optimizer execution Path.
SQL> set autotrace on explain 
SQL> select e.last_name,e.salary,j.job_title from employees e , jobs j where e.job_id=j.job_id and e.salary> 12000 ;
LAST_NAME              SALARY             JOB_TITLE
----------------          ----------           -----------------------
King                           24000              President
Kochhar                     17000              Administration Vice President
De Haan                    17000               Administration Vice President
Russell                      14000               Sales Manager
Partners                    13500               Sales Manager
Hartstein                   13000               Marketing Manager
6 rows selected.

Execution Plan :
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES'
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'JOBS'
   4    2       INDEX (RANGE SCAN) OF 'EMP_JOB_IX' (NON-UNIQUE)
5.) SET AUTOTRACE TRACEONLY : This is like SET AUTOTRACE ON, but it suppresses the printing of the user’s query output, if any.
SQL >  set autotrace traceonly 
Execution Plan 
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES'
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'JOBS' 
   4    2       INDEX (RANGE SCAN) OF 'EMP_JOB_IX' (NON-UNIQUE)
Statistics : 
---------------------------------------------------------
          0  recursive calls
          2  db block gets
         34  consistent gets
          0  physical reads
          0  redo size
        848  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
6  rows processed

Enjoy       :)

What is Database Link ?

A database link is a pointer that defines a one-way communication path from an Oracle Database server to another database server. The link pointer is actually defined as an entry in a data dictionary table. A database link is a schema object in one database that enables you to access objects on another database.

To create a private database link, we must have the create database link system privilege. To create a public database link, we  must have the  create public database link  system privilege. Also, we must have the CREATE SESSION system privilege on the remote Oracle database . Before creating it, we must collect the following information:
1.)  A net service name that our local database instance can use to connect to the remote instance and
2.) A valid username and password on the remote database.


The net service name is necessary for every database link. The username and password that we specify when defining a database link are used to establish the connection to the remote instance. The Credentials of database links are : 
Primary Server   =  Noida 
Remote  Server =  Delhi 


1.) Connect to datbase as 
C:\> sqlplus sys/xxxx@delhi as sysdba 


2.) Create a user
SQL> create user abc identified by abc
  2  default tablespace users
  3  quota unlimited on users;
User created.


3.) Grant the privileges required for database link 
SQL> grant create public database link , create session, create table  to abc;
Grant succeeded.


4.) Connect with "ABC" user and create a table for testing purpose as
SQL> conn abc/abc@delhi
Connected.
SQL> create table test1 (id number);
Table created.
SQL> insert into test1 values(&T);
Enter value for t: 23
old   1: insert into test1 values(&T)
new   1: insert into test1 values(23)
1 row created.
SQL>
Enter value for t: 345
old   1: insert into test1 values(&T)
new   1: insert into test1 values(345)
1 row created.
SQL>
Enter value for t: 32
old   1: insert into test1 values(&T)
new   1: insert into test1 values(32)
1 row created.
SQL> commit ;
Commit complete.


SQL> select * from test1 ; 
         ID
----------
        23
       345
        32
SQL> exit


5.) Connect with primary database as
c:\>sqlplus sys/XXXX@noida as sysdba 


6.) Create a Public database link and access the remote table(test1) as
SQL> create public database link d_link connect to abc identified by abc  using  'DELHI' ; 
Database link created 


SQL> select * from abc.test1@d_link ; 
        ID
----------
        23
       345
        32


Hence , we access the remote table by using the database link .


Enjoy     :-)