Tabs

Thursday, January 22, 2015

Difference Between Unique Indexes and Unique Constraints

There is a very general confusion that whenever we create a unique key constraint or primary key then a corresponding index is created . Primary key and Unique key  creates the unique indexes , but this is not always true .  Lets have a look ...

SQL> create table T1 (id number ) ;
Table created.

SQL> alter table T1 add constraint  T_ID_IDX  unique(id) ;
Table altered.

SQL> select index_name,table_name,uniqueness from dba_indexes where table_name='T1';
INDEX_NAME TABLE_NAME UNIQUENES
---------- ---------- ---------
T_ID_IDX    T1        UNIQUE

SQL> select constraint_name,constraint_type ,table_name from dba_constraints where table_name='T1' and owner='HR' ;
CONSTRAINT_NAME  C   TABLE_NAME
--------------- ---- ----------
T_ID_IDX         U     T1

Here, we see that when we have created a table unique index get created . Now have another look ..

SQL> create table T2(id number);
Table created.

SQL>create unique index T2_id_idx on T2(id);
Index created.

SQL> select index_name,table_name,uniqueness from dba_indexes where table_name='T2'  ;
INDEX_NAME TABLE_NAME UNIQUENES
---------- ---------- ---------------
T2_ID_IDX    T2        UNIQUE

SQL>  select constraint_name,constraint_type ,table_name from dba_constraints where table_name='T2' and owner='HR' ;
no rows selected

SQL> alter table T2 add constraint T2_ID_IDX unique(id);
Table altered.

Now, we expecting  two indexes i.e;  one from the unique index and other from unique constraints . let's look on the below query :

SQL> select constraint_name,constraint_type ,table_name from dba_constraints where table_name='T2' and owner='HR' ;
CONSTRAINT_NAME  C   TABLE_NAME
--------------- ---- ----------
T2_ID_IDX        U     T2

SQL> drop index T2_ID_IDX;
drop index T2_ID_IDX
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key

Above query show only one indexes  . Hence from the above demo, we can only say that  " a unique constraint does not necessarily create an index or a unique constraint does not necessarily create a UNIQUE index "  .

If  we want a unique index in place, it is suggested we should explicitly create it by  using CREATE UNIQUE INDEX .  A primary key or unique constraint is not guaranteed to create a new index, nor is the index they create guaranteed to be a unique index.  Therefore, if  we desire a unique index to be created for query performance issues, we should explicitly create one. 

A question may arises that why do we need a unique constraint when we already have a unique index?
The reason are

1. ) The difference between a unique index and a unique  constraint starts with the fact that the constraint is a rule while the index is a database object that is used to provide improved performance in the retrieval of rows from a table. It is a physical object that takes space and is created with the DDL command  .

2.) we can use either a unique OR non-unique index to support a unique constraint. Constraints are metadata, more metadata is good. We can define a foreign key to a unique constraint, not so a unique index. 

3.) A constraint has different meaning to an index. It gives the optimiser more information and allows us to have foreign keys on the column  whereas a unique index doesn't. But most importantly because  it is the right way to do it.

User Managed Hot Backups in Oracle

A cold backup does have the somewhat bad side effect of wiping out our shared pool, our buffer cache and preventing our users from logging in to do work. Our database is  like a car, it runs better when it is warmed up.  If  we want to cold start it - be  prepared for rough running when we restart as we have to rebuild that shared pool, that  buffer cache and so on . I would never pick cold over hot given the chance.  No benefit, only downsides (Acc. to Tkye). The only kind of backup we do on our production systems here is hot .


There are two ways to perform Oracle backup and recovery : 

1.)  Recovery Manager (RMAN) : It is an Oracle utility that can backup, restore, and recover database files. It is a feature of the Oracle database server and does not require separate installation.
2.) User-Managed backup and recovery : We use operating system commands for backups and SQL*Plus for recovery. This method is  called user-managed backup and recovery and  is fully supported by Oracle, although use of RMAN is highly recommended because it is more robust and greatly simplifies administration.

There are basically two types of  backup .The backup are as 


1.) Consistent Backup :  This is also know as Cold Backup . A consistent backup is one in which the files being backed up contain all changes up to the same system change number (SCN). This means that the files in the backup contain all the data taken from a same point in time .
2.) Inconsistent Backup :  This is also known as Hot backup . An inconsistent backup is a backup in which the files being backed up do not contain all the changes made at all the SCNs . This can occur because the datafiles are being modified as backups are being taken. 

There are  some DBAs which prefer oracle user-managed backups.They put their database into backup mode prior to backing  up and take it out of backup mode after backup. If  we 're going to perform user-managed backups, we must back up all of the following file : 
  • Datafiles
  • Control files
  • Online redo logs (if performing a cold backup)
  • The parameter file (not mandatory )
  • Archived redo logs
  • Password file if used

The below diagram shows the Whole Database Backup Options :  
A hot backup requires quite a bit more work than cold backup.Below are steps required for Hot backup.


Step 1 :  Check the log mode of the database  Whenever we go for hot backup then the database must be in archivelog  mode . 
SQL> SELECT LOG_MODE FROM V$DATABASE ;
LOG_MODE
---------------
ARCHIVELOG

Step 2 :  Put the database into backup mode  If we are using the oracle 10gR2 or later , then we can put the entire database into backup mode and if we are using the oracle prior to 10gR2 ,then we have to put each tablespace in backup mode . In my case , I am having 11gR2 . 
SQL> alter database begin backup ; 
Database altered.
In case of oracle prior to 10gR2 use the below command as 
SQL> set echo off 
SQL> set heading off 
SQL>  set feedback off 
SQL> set termout  off 
SQL> spool backmode.sql 
SQL> select 'alter tablespace  '||name||'  begin backup ;'   "Tablespace in backup mode"  from v$tablespace;
SQL> spool off 
SQL>  @C:\backmode.sql 


Step 3 :  Backup all the datafiles  Copy all the datafile using the operating system command and Paste it on the desired backup location .Meanwhile,we can verify the status of the datafile by using the v$backup view  to check the status of the datafiles.
SQL> select  *  from  v$backup ; 
     FILE# STATUS                CHANGE# TIME
---------- ------------------ ---------- ---------
         1 ACTIVE                3967181 03-APR-12
         2 ACTIVE                3967187 03-APR-12
         3 ACTIVE                3967193 03-APR-12
         4 ACTIVE                3967199 03-APR-12
         5 ACTIVE                3967205 03-APR-12
         6 ACTIVE                3967211 03-APR-12
         7 ACTIVE                3967217 03-APR-12
         8 ACTIVE                3967223 03-APR-12
         9 ACTIVE                3967229 03-APR-12
The Column STATUS=ACTIVE  shows that the datafiles are in backup mode . 


Step  4  : Take out the database from backup mode  If we are using 10gR2 or above version of oracle , we use the below command to take out the database from backup mode as 
SQL> alter database end backup ; 
Database Altered 
If we are having version prior to 10gR2 , then we use the below command as above : 
SQL> set echo off 
SQL> set heading off 
SQL> set feedback off 
SQL> set termout  off 
SQL> spool end_mode.sql 
SQL> select  'alter tablespace  '||name||'  end backup ;'   "tablespace in backup mode"  from v$tablespace ; 
SQL> spool off 
SQL> @C:\endmode.sql 


Step 5 :  Switch the redolog file and backup archivelogs   After taking the database out of Hot Backup we must switch logfile (preferably more than once) and backup the archivelogs generated .We may backup archivelogs while the database is in backup mode but we must also backup the first archivelog(s) after the end backup. The best method to do both is to run the SQL command alter system archive log current. This switches the logfile but does not return the prompt until the previous redo log has been archived. We can run alter system switch logfile, but then we won't be sure that the latest redo log has been archived before we move on to the next step. 
SQL> alter system archive log current ; 
System altered.
SQL>
System altered.
Now backup the archivelogs to the backup location .


Step 6  : Back up the control file  Now , we can backup the controlfile as binary file and as human readable .We should use both methods to back up the control file; either one may come in handy at different times . The commands are as 
(Human readable)
SQL> alter database backup controlfile to trace ;  or 
Database altered.
SQL> alter database backup controlfile to trace as '<backup location>' ; 
Database altered.
(Binary format)
SQL> alter database backup controlfile to '<backup location>' ; 
Database altered.


Step 7 : Backup the passwordfile and spfile  We can backup the passwordfile and spfile though it is not mandatory.


Some Points Worth Remembering 
  • We  need to backup all the archived log files, these files are very important to do recovery. 
  • It is advisable to backup all of  tablespaces (except read-only tablespaces), else complete recovery is not possible.
  • Backup of online redo log files are not required, as the online log file has the end of backup marker and would cause corruption if used in recovery.
  • It is Preferable to start the hot backups at low activity time.
  • When hot backups are in progress we  "cannot" shutdown the database in NORMAL or IMMEDIATE mode (and it is also not desirable to ABORT).

Tuesday, January 20, 2015

Understanding Oracle password hashing

This is an explanation of how the password hashing works on Oracle databases across 9i and 10g. For the explanation two users are chosen on a 10g and in a 9i database, namely user1 and user2 and their encrypted passwords are displayed. The test is first done on a 10g database

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.3.0 - Productio
NLSRTL Version 10.2.0.3.0 - Production

SQL> select username,password from dba_users where username like 'USER%';

USERNAME PASSWORD
------------------------------ ------------------------------
USER1 BBE7786A584F9103
USER2 1718E5DBB8F89784

Now both the user1 and user2 have their own usernames as their passwords as shown below.

SQL> conn user1/user1
Connected.
SQL>
SQL> conn user2/user2
Connected.

The password of user2 is changed to that of 'user1', just to see how the password encryption mechanism works.

SQL> conn /as sysdba
Connected.
SQL>
SQL> alter user user2 identified by user1;

User altered.

User2's old password does not work anymore, but the new password is in effect now as shown below.

SQL> conn user2/user2
ERROR:
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.
SQL> conn user2/user1
Connected.
SQL>

When querying the passwords of user1 and user2 this time, shows up different values for both the users inspite of the fact that both the users have the same password assigned to them.

SQL> conn /as sysdba
Connected.
SQL>
SQL> select username,password from dba_users where username like 'USER%';
USERNAME PASSWORD
------------------------------ ------------------------------
USER1 BBE7786A584F9103
USER2 83566E16913442F3

This shows that Oracle does not only encrypts just the password but also takes into account some other factor with the password for encryption. This other factor could be assumed as the username as such.

The above was tested on a 10g database,the same which one tested on a 9i database shows no difference in the password encryption mechanism which is evident from the output shown below.

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production
CORE 9.2.0.8.0 Production
TNS for IBM/AIX RISC System/6000: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production

SQL> create user user1 identified by user1;

User created.

SQL> grant connect,resource to user1;

Grant succeeded.

SQL> create user user2 identified by user1;

User created.

SQL> grant connect,resource to user2;

Grant succeeded.

SQL> select username,password from dba_users where username like '%USER%';

USERNAME PASSWORD
------------------------------ ------------------------------
USER1 BBE7786A584F9103
USER2 83566E16913442F3

SQL> conn user1/user1
Connected.
SQL>
SQL> conn user2/user2
ERROR:
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.
SQL>
SQL> conn user2/user1
Connected.
SQL>
SQL> conn /as sysdba
Connected.
SQL>
SQL> alter user user2 identified by user2;
User altered.

SQL> select username,password from dba_users where username like '%USER%';
USERNAME PASSWORD
------------------------------ ------------------------------
USER1 BBE7786A584F9103
USER2 1718E5DBB8F89784 <--- The password here is
'user2' which shows
the same encrypted
text in the first query
output at the top of this page.