Saturday, January 19, 2013

Oracle 11.1 and above read-only tables

In Oracle 11.1 and above you can use alter table clause to change table to read-only or read-write mode.

Change table to read-only:
SQL> alter table test_table read only;

After this users can't run deletes, inserts or updates for changed table.

Change table to read-write:

SQL> alter table test_table read write;

After this users can again run deletes, inserts or updates for this table.

You can check table mode from user_tables, all_tables or dba_tables views (check the READ_ONLY column).

Invisible Index Oracle 11.1 and above.

Starting in Oracle 11.1 is it possible to test index before starting to use it with all sessions. And it is also possible to test affect of index dropping before actually dropping the index.  These can be done with invisible index feature which allows you to set optimizer seeing index only in the session you are using.

Here is a couple of examples how to do this:

Create invisible index:


SQL> CREATE INDEX test_invis_idx ON test_table (column_name) INVISIBLE;

There is new init param 'optimizer_use_invisible_indexes' which tells if optimizer sees the invisible indexes. And default values for this parameter is false ( so optimizer does not see invisible indexes by default and because of this queries does not use this kind of indexes). You can set this parameter true for the session you are using and test new index with only that session:
SQL> ALTER SESSION SET optimizer_use_invisible_indexes=true;

Then run queries that are using new index and if everything works like you want then change index visible and all sessions start to use new index because optimizer sees this index ( all new indexes are visible by default ):

SQL> ALTER INDEX test_invis_idx  VISIBLE;

And same way you can test affect of dropping index. First change index you like to drop invisible and see if queries are starting to working poorly. If they are change index back to visible. And if they are working ok without the index you can drop it safely.

SQL> ALTER INDEX test_invis_idx  INVISIBLE;
SQL> DROP INDEX test_invis_idx;


You can check index state from the user_indexes , all_indexes or dba_indexes views like this:

SQL> select index_name,VISIBILITY from user_indexes where index_name='test_invis_idx';
INDEX_NAME                     VISIBILIT
------------------------------ ---------
TEST_INVIS_IDX           VISIBLE








Sunday, January 6, 2013

Lock table clause changes in Oracle 11.1 and above.

In Oracle 11.1 and above you can set wait time for LOCK TABLE clause.
Default value for lock table clause is WAIT . And with that lock table clause will wait as long it gets the lock for the table. But you can give also waith time for lock table clause with command like this:
LOCK TABLE <table_name> IN <lock_mode> MODE WAIT <seconds to wait>;
For example:
SQL> LOCK TABLE test1 IN exclusive MODE WAIT 60;


And if you use NOWAIT instead of WAIT then lock table clause will give error straight away if it does not get table lock for table.

DDL Lock timeout in Oracle 11.1 and above.

If you need to run DDL command (for example modify column size) for highly used (modified) table.  It could be difficult to get DDL command throught. To easier this in Oracle 11.1 and above you can use following command to set time which DDL command will wait to get lock in the table:
alter session set ddl_lock_timeout=<seconds_that_DDL_will_wait>;
for example set DDL to wait 60 seconds to get the lock in the table:
SQL> alter session set ddl_lock_timeout=60;

After this you can run DDL command to make table modification and DDL command will wait for 60 seconds to get table lock to make it changes. If it does not get table lock for that time it will give error. 

NOTE! Default value for ddl_lock_timeout is 0 (NOWAIT).
So it gives error straight if it does not get lock in the tables.

Saturday, January 5, 2013

Shrink TEMP Tablespace or Tempfile in Oracle 11.1 and above.

In Oracle 11.1 and above versions you can shrink TEMP tablespace and/or Tempfiles.

With dba_temp_free_space view you can check temp tablespace space usage:
SQL> SELECT * FROM dba_temp_free_space;

With command:
ALTER TABLESPACE <temp_tablespace_name> SHRINK SPACE KEEP <size_for_temp_tablespace>M;
You can shrink temp tablespace to certain size.

For example to shrink temp tablespace to 40M:
SQL> ALTER TABLESPACE temp SHRINK SPACE KEEP 40M;

And if you want to shrink certain tempfile you can do it with following command:
ALTER TABLESPACE <temp_tablespace_name> SHRINK TEMPFILE <'path_to_tempfile_and_tempfile_name'> KEEP <size_for_tempfile>M;

For example to shrink test_temp01.dbf tempfile to 40M :
SQL> ALTER TABLESPACE temp SHRINK TEMPFILE '/u01/app/oracle/oradata/testdb/test_temp01.dbf' KEEP 40M;


If you don't set the KEEP clause in the end of the shrink clause then tablespace or tempfile will be shrinked as small as possible (1M).

Sunday, November 18, 2012

Create Oracle password file

In Oracle there is two ways to authenticate database administrators. OS authentication or with Oracle password file. If you have set 'shared or 'exclusive' in remote_login_passwordfile init parameter then Oracle password file is used. 'exclusive' is the default value.
And the default place for password file is on unix:
$ORACLE_HOME/dbs/orapw$ORACLE_SID
and on windows:
%ORACLE_HOME%\database\PWD%ORACLE_SID%.ora


You can create oracle password file with orapwd utility (as oracle user and $ORACLE_SID and $ORACLE_HOME env parameters set):
orapwd file=orapwtestdb password=xxxxx

you can also use 'entries' option when you create paasword file. this options tells how many user can be added into the file:
orapwd file=orapwtestdb password=xxxxx entries=5


If you give user SYSDBA or SYSOPER privilege that user will be added into the password file automatically.

You can check password file users from sqlplus  v$pwfile_users  view:
select * from  v$pwfile_users;

Oracle Database Availability Changes.

There are several ways to affect Oracle database availability.

1. First when you start the database you can start it in mount or in nomount state. 
SQL> STARTUP NOMOUNT;
SQL> STARTUP MOUNT;

These states are used with administrating operations. For example with nomount state you can run restore jobs for controlfiles with RMAN and with mount state you can change database settings such as archiving. But with these states you database is answering only locally and only for certain commands.

For opening database to general use run following (this is same as: alter database open read write; ):
SQL> ALTER DATABASE OPEN;
If you wan't to open the database only READ access you can do it with this (this doesn't allow any writes):

SQL> ALTER DATABASE OPEN READ ONLY;



You can also use (RESTRICT can be also used with open, mount and nomount):

SQL> STARTUP RESTRICT;
With restricted mode only users with RESTRICTED SESSION system privilege can connect into database and only local connections are available. Only database administrators should have this privilege.



2. Second you can use logon and logoff triggers to make restrictions for user sessions connecting into database or disconnecting:
Remember that connection restriction made by these kind of trigger does not affect database administrator users unless you exclude ADMINISTER DATABASE TRIGGER privilege from that dba user.
Syntax goes like this:
#Logon trigger:
SQL> CREATE OR REPLACE TRIGGER <trigger_name> 
           AFTER LOGON ON <schema_name>
           BEGIN
               <trigger actions>
          END;

#Logoff trigger:
SQL> CREATE OR REPLACE TRIGGER <trigger_name> 
           BEFORE LOGOFF ON <schema_name>
           BEGIN
               <trigger actions>
          END;

More info can be find for example here:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#TDDDG52900


3. Third you can use sqlnet.ora (this works on Oracle11g with older version you need to use 
protocol.ora config file) to make IP restriction for database connections:

Add following lines in sqlnet.ora file:
#This creates a hard failure when host name in exclude/invited list fail to resolve IP address:
tcp.validnode_checking = YES
#To specify which clients are denied access to the database:  
tcp.excluded_nodes = {list of IP_addresses}
#To specify which clients are allowed access to the database:
tcp.invited_nodes = {list of IP_addresses}

After you have done these changes you have to restart the listener:
lsnrctl status
lsnrctl stop
lsnrctl start
lsnrctl status



4. Fourth you can use your firewall settings (or iptables locally) to restrict database availability.