This is an excerpt from the bestselling book
Oracle Grid & Real Application Clusters. To get immediate
access to the code depot of working RAC scripts, buy it
directly from the publisher and save more than 30%.
Also see these important notes on the
disable table lock command.
For RAC, table locks are
coordinated through global inter-instance communication. Due to the
fact that properly designed applications do not need to lock entire
tables, table locks can be disabled to improve locking efficiency
with minimal adverse side effects. Essentially, there are two
methods for disabling table locks:
* Disabling table locks for
* Setting dml_locks to zero.
The following sections will
examine these methods.
Disabling Table Locks for
To prevent users from acquiring
individual table locks, the following statement can be used:
table_name DISABLE TABLE LOCK
When users attempt to lock
tables with disabled locks, they will receive an error. To re-enable
table locking after a transaction, the following statement can be
table_name ENABLE TABLE LOCK
Using this syntax forces all
currently executing transactions to commit before enabling the table
lock. The statement does not wait for new transactions to start
after issuing the ENABLE statement. The disadvantage to this
statement is that it must be executed for all tables that may
experience improper locking.
To determine whether a table in
the schema has its table lock enabled or disabled, the table_lock
column in the user_tables data dictionary table should be queried.
If SELECT privilege is on dba_tables, the table lock state of other
user's tables can be queried as well. The all_tables views can be
used to see the locking state of tables for which a user has been
granted SELECT privileges.
Setting dml_locks to Zero
Using the dml_locks
initialization parameter, table locks can be set for an entire
instance. This will disable the DROP TABLE, CREATE INDEX and LOCK
TABLE commands. If these commands are not needed, dml_locks should
be set to zero to minimize lock conversions and achieve maximum
performance. DDL statements cannot be executed against tables with
SQL*Loader checks the flag to
ensure that there is not a non-parallel direct load running against
the same table. The use of direct load forces Oracle to create new
extents for each session.
If dml_locks are set to zero on
one instance, it must be set it to zero on all instances. If
non-zero values are used with the dml_locks parameter, the values
need not be identical on all instances.
Performance for Object
Creation in Real Application Clusters
In any Oracle database, DDL
statements should be used for maintenance tasks, not during normal
system operations. For example, global temporary tables or PL/SQL
tables should be used rather than permanent tables for reports. If
this guideline is followed, in most systems, the frequency of DDL
statements should be low.
If the application has to create
objects frequently, performance degradation to the RAC environment
will occur. This is due to the fact that object creation requires
inter-instance coordination. A large ratio of dlm_conflicts to
dlm_requests on the dc_object_ids row cache in v$rowcache, the same
SELECT as was used for sequences will work here as well, along with
excessive wait times for the row cache lock event in v$system_event,
is indicative that multiple instances in the cluster are issuing
excessive amounts of concurrent DDL statements.
About the only method to improve
object creation performance in these situations is to set event
10297 so that it caches object_id values. This will improve
concurrent object creation by eliminating the recursive DDL and some
of the intra-instance pinging. To set event 10297, the following
line can be added to the initialization parameter file:
trace name context forever, level 1"
If the additional level argument
is set to one, the caching behavior is automatically adjustable
internally. Otherwise, the level can be set to the desired cache