25 May, 2008

Passwords are One Way Hashes, Not Encrypted

Here's a simple demonstration of how Oracle Database passwords are One Way Hashes, not Encrypted.


SQL>
SQL> create user HEMA identified by SOMEBODY_2 ;

User created.

SQL> create user HEMASOME identified by BODY_2 ;

User created.

SQL> create user HEMASOMEBOD identified by Y_2 ;

User created.

SQL>
SQL> create user HEMAS identified by OMEBODY_3 ;

User created.

SQL>
SQL> select username, password from dba_users
2 where
3 (username != 'HEMANT')
4 and
5 (
6 (username like 'HEMA%')
7 )
8 order by username;

USERNAME PASSWORD
------------------------------ ------------------------------
HEMA 8E8C633A6DAEC8E4
HEMAS 9DB550C5CAA21E55
HEMASOME 8E8C633A6DAEC8E4
HEMASOMEBOD 8E8C633A6DAEC8E4

SQL>


The "password" that is stored in DBA_USERS is actually a Hash of
the Username + Password (with an Oracle secret "magic" salt).
Thus, since "HEMA" + "SOMEBODY_2" is the same as "HEMASOME" + "BODY_2" and also "HEMASOMEBOD" + "Y_2" (in all cases it is "HEMASOMEBODY_2" !), the so-called password visible in DBA_USERS is the same for all three database accounts.

However, for the account "HEMAS" since the concatenation of the username with the password results in a different string "HEMASOMEBODY_3" (only the last character is different !), the resulting "Hash" is obviously quite different and so is the "password" in DBA_USERS !

When a user enters his Username and Password, Oracle does not attempt any encryption of the password for comparision with the stored password or decryption of the stored password with the user-supplied password. It simply computes the Hash value for Username+Password and compares that with the stored Hash value.

That is how users with very different usernames and passwords can seemingly have the "same" password stored in DBA_USERS -- it is not really a password but a Hash.

20 May, 2008

APPEND, NOLOGGING and Indexes

Running some tests on 10gR2, I find that the presence of Indexes can have a very significant impact on Direct Path Inserts done with the APPEND Hint, even if the target table is NOLOGGING.

Thus, for example, a Normal INSERT on an unindexed table is :

SQL> insert /* normal insert */ into test_append ta
2 select * from source_table;

301974 rows created.

Elapsed: 00:00:03.22
SQL> commit;

Commit complete.

Elapsed: 00:00:00.01
SQL> select sn.name, s.value
2 from v$statname sn, v$mystat s
3 where sn.statistic#=s.statistic#
4 and sn.name in ('CPU used by this session', 'consistent gets', 'db block changes', 'db block gets', 'physical reads direct','physical writes direct','redo entries', 'redo size','undo change vector size')
5 order by sn.name;

NAME VALUE
---------------------------------------------------------------- ---------------
CPU used by this session 145
consistent gets 12,608
db block changes 30,725
db block gets 36,672
physical reads direct 0
physical writes direct 0
redo entries 22,796
redo size 33,808,976
undo change vector size 1,122,508

While an INSERT with the table set to NOLOGGING is :

SQL> insert /*+ APPEND */ into test_append ta
2 select * from source_table;

301980 rows created.

Elapsed: 00:00:01.61
SQL> commit;

Commit complete.

Elapsed: 00:00:00.03
SQL> select sn.name, s.value
2 from v$statname sn, v$mystat s
3 where sn.statistic#=s.statistic#
4 and sn.name in ('CPU used by this session', 'consistent gets', 'db block changes', 'db block gets', 'physical reads direct','physical writes direct','redo entries', 'redo size','undo change vector size')
5 order by sn.name;

NAME VALUE
---------------------------------------------------------------- ---------------
CPU used by this session 129
consistent gets 4,353
db block changes 194
db block gets 4,353
physical reads direct 0
physical writes direct 4,146
redo entries 260
redo size 26,816
undo change vector size 4,664

However, if I have a "large" (multi column, concatenated index with a large key size) Index on the target table I get :

SQL> insert /*+ APPEND */ into test_append ta
2 select * from source_table;

301974 rows created.

Elapsed: 00:00:24.45
SQL> commit;

Commit complete.

Elapsed: 00:00:00.18
SQL> select sn.name, s.value
2 from v$statname sn, v$mystat s
3 where sn.statistic#=s.statistic#
4 and sn.name in ('CPU used by this session', 'consistent gets', 'db block changes', 'db block gets', 'physical reads direct','physical writes direct','redo entries', 'redo size','undo change vector size')
5 order by sn.name;

NAME VALUE
---------------------------------------------------------------- ---------------
CPU used by this session 1,107
consistent gets 21,592
db block changes 186,229
db block gets 194,635
physical reads direct 4,775
physical writes direct 8,921
redo entries 100,228
redo size 152,819,412
undo change vector size 72,298,884


When a Direct Path INSERT is executed Index Maintenance is deferred. However, Index Maintenance itself generates Undo and is NOT a NoLogging operation.

Thus, my INSERT that normally generates 33MB of Redo and can be optimized to 26KB with NOLOGGING set at the Table level and APPEND as a Hint (directive), becomes a 152MB Redo Generator if I have an Index.

YMMV, depending on the table columns, Index key length etc. But it is important to note that an Index can really hurt your happiness when you are doing bulk loads.

08 May, 2008

RMAN Consistent ("COLD" ?) Backup and Restore

The RMAN documentation differentiates between "inconsistent" and "consistent" backups on the basis of whether the database is OPEN or not (respectively) during the Backup.
The nomenclature "inconsistent backup" makes me nervous. Why not call it the good old "HOT" Backup ?

To do a consistent" backup with RMAN, the database must be mounted as RMAN needs to access and update the controlfiles. With an OS scripted backup pre-RMAN, the database was truly "COLD" -- there would be no Oracle processes running.
RMAN does not backup the Online Redo Log files. With an OS scripted backup, you had the option -- you could choose to include these files in your backup if you were careful about how you planned to use Cold Backups for Roll-Forward recoveries with ArchiveLog.

Since RMAN does not backup the Online Redo Log files, you must, perforce, OPEN RESETLOGS on a Restore. With a scripted backup, if you also included your Online Redo Log files in your backup and restore (provided that you did not plan to apply any ArchiveLogs), you could simply STARTUP the database and continue LogSequenceNumbers again. (Of course, you might be duplicating LogSequenceNumbers if the database had been active in ArchiveLog mode since the backup, so you have to be careful to distinguish the two "streams" of ArchiveLogs).


Here below is the simplest "consistent" Backup and Restore using RMAN :



C:\>rman

Recovery Manager: Release 10.2.0.3.0 - Production on Thu May 8 22:20:17 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

RMAN> connect target /

connected to target database (not started)

RMAN> startup mount

Oracle instance started
database mounted

Total System Global Area 536870912 bytes

Fixed Size 1291652 bytes
Variable Size 297798268 bytes
Database Buffers 234881024 bytes
Redo Buffers 2899968 bytes

RMAN> backup database;

Starting backup at 08-MAY-08
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=58 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00001 name=C:\OR10G2DB\SYSTEM01.DBF
input datafile fno=00003 name=C:\OR10G2DB\SYSAUX01.DBF
input datafile fno=00002 name=F:\OR10G2DB\TEST_TBS_01.DBF
input datafile fno=00004 name=C:\OR10G2DB\USERS01.DBF
input datafile fno=00005 name=C:\OR10G2DB\EXAMPLE01.DBF
input datafile fno=00007 name=C:\OR10G2DB\UNDO.DBF
channel ORA_DISK_1: starting piece 1 at 08-MAY-08
channel ORA_DISK_1: finished piece 1 at 08-MAY-08
piece handle=C:\OR10G2DB_FLASH\OR10G2DB\BACKUPSET\2008_05_08\O1_MF_NNNDF_TAG200
0508T222041_42631X6C_.BKP tag=TAG20080508T222041 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:01:47
Finished backup at 08-MAY-08

Starting Control File and SPFILE Autobackup at 08-MAY-08
piece handle=C:\OR10G2DB_FLASH\OR10G2DB\AUTOBACKUP\2008_05_08\O1_MF_S_654214767
426358M1_.BKP comment=NONE
Finished Control File and SPFILE Autobackup at 08-MAY-08

RMAN>
RMAN> shutdown

database dismounted
Oracle instance shut down

RMAN>

******************* BACKUP COMPLETED *****************
******************************************************

========= database files deleted ====================
++++++++++++++++++++++++++++++++++++++++++++++++++++++
======================================================



C:\>rman target /

Recovery Manager: Release 10.2.0.3.0 - Production on Thu May 8 22:32:07 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

connected to target database (not started)

RMAN> startup nomount

Oracle instance started

Total System Global Area 536870912 bytes

Fixed Size 1291652 bytes
Variable Size 301992572 bytes
Database Buffers 230686720 bytes
Redo Buffers 2899968 bytes

RMAN>
RMAN> restore controlfile from autobackup;

Starting restore at 08-MAY-08
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=57 devtype=DISK

recovery area destination: \OR10G2DB_FLASH
database name (or database unique name) used for search: OR10G2DB
channel ORA_DISK_1: autobackup found in the recovery area
channel ORA_DISK_1: autobackup found: C:\OR10G2DB_FLASH\OR10G2DB\AUTOBACKUP\2008
_05_08\O1_MF_S_654214767_426358M1_.BKP
channel ORA_DISK_1: control file restore from autobackup complete
output filename=C:\OR10G2DB\CONTROL01.CTL
output filename=C:\OR10G2DB\CONTROL02.CTL
output filename=C:\OR10G2DB\CONTROL03.CTL
Finished restore at 08-MAY-08

RMAN>
RMAN> restore database;

Starting restore at 08-MAY-08
using channel ORA_DISK_1
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of restore command at 05/08/2008 22:33:28
ORA-01507: database not mounted

RMAN> alter database mount;

database mounted
released channel: ORA_DISK_1

RMAN>
RMAN> restore database;

Starting restore at 08-MAY-08
Starting implicit crosscheck backup at 08-MAY-08
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=57 devtype=DISK
Crosschecked 45 objects
Finished implicit crosscheck backup at 08-MAY-08

Starting implicit crosscheck copy at 08-MAY-08
using channel ORA_DISK_1
Finished implicit crosscheck copy at 08-MAY-08

searching for all files in the recovery area
cataloging files...
cataloging done

List of Cataloged Files
=======================
File Name: C:\OR10G2DB_FLASH\OR10G2DB\AUTOBACKUP\2008_05_08\O1_MF_S_654214767_42
6358M1_.BKP

using channel ORA_DISK_1

skipping datafile 2; already restored to file F:\OR10G2DB\TEST_TBS_01.DBF
channel ORA_DISK_1: starting datafile backupset restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
restoring datafile 00001 to C:\OR10G2DB\SYSTEM01.DBF
restoring datafile 00003 to C:\OR10G2DB\SYSAUX01.DBF
restoring datafile 00004 to C:\OR10G2DB\USERS01.DBF
restoring datafile 00005 to C:\OR10G2DB\EXAMPLE01.DBF
restoring datafile 00007 to C:\OR10G2DB\UNDO.DBF
channel ORA_DISK_1: reading from backup piece C:\OR10G2DB_FLASH\OR10G2DB\BACKUPS
ET\2008_05_08\O1_MF_NNNDF_TAG20080508T222041_42631X6C_.BKP
channel ORA_DISK_1: restored backup piece 1
piece handle=C:\OR10G2DB_FLASH\OR10G2DB\BACKUPSET\2008_05_08\O1_MF_NNNDF_TAG2008
0508T222041_42631X6C_.BKP tag=TAG20080508T222041
channel ORA_DISK_1: restore complete, elapsed time: 00:02:05
Finished restore at 08-MAY-08

RMAN>
RMAN> alter database open;

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of alter db command at 05/08/2008 22:36:48
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

RMAN>
RMAN> alter database open resetlogs;

database opened

RMAN>



The OPEN RESETLOGS is necessary because RMAN does not backup and restore
Online Redo Logs.