Oracle
10g New Features
The G stands for Grid Computing. A common missconception seems to be
that grid is just the new name for RAC (having improved RAC) This is
not the case. 10g comes with both RAC and grid. One will be able to
install 10g with RAC only, with grid only, without either and with
both. There is a profound difference between grid and RAC. 10g is said
to have 149 new features. 10g provides a wealth of features that can be
used to automate almost every aspect of its database administration. It
is important to note that these automation features are optional, and
they are not intended to replace standard DBA activities. Rather, the
Oracle10g automation features are aimed at shops that do not have the
manpower or expertise to manually perform the tasks.
Oracle Enhancements by Oracle Release
New Utilities in Oracle10g release 10.1.0:
• Oracle10g Grid – RAC enhanced for Oracle10g dynamic
scalability with server blades
(extra-cost option)
• Completely reworked 10g Enterprise Manager (OEM)
• AWR and ASH tables incorporated into OEM
Performance Pack and Diagnostic Pack options (extra-cost option)
• Automated Session History (ASH) materializes the
Oracle Wait Interface over time (extra-cost
option)
• Data Pump replaces imp utility with impdp
• Automatic Database Diagnostic Monitor (ADDM) (extra-cost option)
• Automatic Storage Management (ASM) introduced
Stripe And Mirror Everywhere (SAME) standard
• Automatic Workload Repository (AWR) replaces
STATSPACK (extra-cost option)
• SQLTuning Advisor
• SQLAccess Advisor
• Rolling database upgrades (using Oracle10g RAC)
• dbms_scheduler package replaces dbms_job for
scheduling
OEM Partition Manager introduced
Miscellaneous Oracle10g enhancements:
• Set Database Default Tablespace syntax
• Run Faster PL/SQL Programs because The new PL/SQL
optimizing compiler and Implicit array fetching. So even if you use
For x in (select * from table)
Loop
Process data;
End loop;
PL/SQL is silently "array fetching" 100 rows at a time.
• Rename Tablespace command
• Introduced RECYCLEBIN command for storing objects
before they are dropped. Required new PURGE command for maintenance.
• sqlplus / as sysdba accessibility without quote
marks
• SYSAUX tablespace
• Multiple Temporary Tablespaces supported to reduce
stress on sorting in TEMP
• RMAN introduces compression for backups
• New drop database syntax
• New alter database begin backup syntax and alter
database end backup. You don't need to specify the tablespaces
one by one!!
• Oracle10g Data Guard Broker introduced
• Oracle10g RAC supports secure Redo Log transport
• Flashback enhancements for flashback database and
flashback table syntax
• SQL Apply feature
• VPD (FGAC, RLS) supports both row-level and
column-level VPD
• Cross Platform Transportable Tablespaces
• External Table unload utility
• SQL Regular Expression Support with the evaluate
syntax
• New ROW TIMESTAMP column
• Improvement to SSL handshake speed
• Automatic Database Tuning of Checkpoints, Undo
Segments and shared memory
• Automated invoking of dbms_stats for CBO statistics
collection
• RAC introduces Integrated Cluster ware
• Oracle Application Builder supports HTML DB
• Browser Based Data Workshop and SQL Workshop
• PL/SQL Compiler enhanced for compile-time Warnings
in utl_mail and utl_compress
• VPD (FGAC, RLS) supports both row-level and
column-level VPD
So, if your 10g database does not require detailed, expert tuning, then
the automated features might be a good choice. They are targeted at
these market segments:
- Small shops: Small installations that can't afford a trained
Oracle DBA.
- Shops with over-worked DBAs: Large shops with hundreds of
instances where the DBA does not have time to properly tune each
system.
Statistics Collection
These
new feature
include
collection of data dictionary statistics (
which is now recommended as a best practice by
Oracle) ,
new behaviors associated with
the dbms_stats
package,
and new features
related to monitoring tables in the database. The
Rule Based Optimizer (RBO) is
desupported with 10g. Also, 10g includes new features that enhance the
generation of
object level statistics within the database. Let’s take a look.
Data
Dictionary Statistics
Collection
Oracle
recommends
that
you analyze the data dictionary. You can collect these statistics by
using
either the dbms_stats.gather_schema_stats
or
dbms_stats.gather_database_stats
Oracle-supplied
procedures, as shown here:
Exec
dbms_stats.gather_schema_stats(’SYS’)
The
gather_schema_stats
and
gather_database_stats
procedures
are
NOT new in Oracle 10 g, but using them to collect data
dictionary
statistics is new, as there are some new parameters that are available
with
these
procedures. Oracle 10g also offers two new procedures in the dbms_stats
package.
First, the dbms_stats.gather_dictionary_stats
procedure
facilitates analysis of the data dictionary.
Second the dbms_stats.delete_dictionary_
stats procedure
allows you to remove data dictionary stats.
Here is an example of the use of the dbms_stats.gather_dictionary_stats
procedure:
exec
dbms_stats.gather_dictionary_stats;
This
example gathers statistics from
the SYS and SYSTEM schemas as well as any other schemas that are
related to
RDBMS components (e.g., OUTLN or DBSNMP).
Any
user with SYSDBA privileges can analyze the data dictionary.
Gathering
Fixed Table
Statistics
A
new parameter to the dbms_stats.gather_database_stats
and
dbms_stats.gather_database_stats
packages
is gather_fixed.
This parameter is set to false
by
default, which disallows statistics collection for
fixed data dictionary tables (e.g., x$tables). Oracle suggests that you
analyze
fixed tables only once during a typical system workload. You should do
this as
soon as possible after your upgrade to Oracle 10 g, but again
it
should be under a normal workload. Here is an example of the use of the
gather_fixed
argument
within the dbms_stats.gather_schema_stats
procedure:
Exec
dbms_stats.gather_schema_stats(’SYS’,gather_fixed=>TRUE)
Yet
another new procedure, dbms_stats.gather_fixed_objects_stats,
has been provided in Oracle 10g to collect object
statistics on fixed objects. It also has a brother, delete_fixed_objects_stats,
which
will remove the object statistics. Second cousins and new Oracle
10
gprovided procedures include dbms_stats.export_fixed_objects_stats
and
dbms_stats.import_fixed_
objects_stats.
These allow you to export and import
statistics to user-defined statistics tables, just as you could with
normal
table statistics previously. This allows your data dictionary fixed
statistics
to be exported out of and imported into other databases as required.
One other
note: the dbms_stats
Oracle-supplied
package also supports analyzing specific data
dictionary tables.
When
to Collect Dictionary
Statistics
Oracle
recommends the following
strategy with regard to analyzing the data dictionary in Oracle
10g:
1.
Analyze
normal data dictionary objects (not fixed dictionary
objects) using the same interval that you currently use when analyzing
other
objects. Use gather_database_stats,
gather_schema_stats,
or gather_dictionary_stats
to
perform this action. Here is an example:
Exec
dbms_stats.gather_schema_stats(’SYS’,gather_fixed=>TRUE)
2.
Analyze
fixed objects only once, unless the workload footprint
changes. Generally, use the dbms_stats.gather_fixed_object_stats
supplied
procedure when connected as SYS or any other
SYSDBA privileged user. Here is an example:
Exec
dbms_stats.gather_fixed_objects_stats(’ALL’);
Automatic
Optimizer Statistics Collection
By default Oracle 10g automatically gathers optimizer statistics using
a scheduled job called GATHER_STATS_JOB. By default this job runs
within a maintenance windows between 10 P.M. to 6 A.M. week nights and
all day on weekends. The job calls the
DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC internal procedure which
gathers statistics for tables with either empty or stale statistics,
similar to the DBMS_STATS.GATHER_DATABASE_STATS procedure using the
GATHER AUTO option. The main difference is that the internal job
prioritizes the work such that tables most urgently requiring
statistics updates are processed first.
The GATHER_DATABASE_STATS_JOB_PROC procedure collects statistics on
database objects when the object has no previously gathered statistics
or the existing statistics are stale because the underlying object has
been modified significantly (more than 10% of the rows).The
DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC is an internal procedure, but
its operates in a very similar fashion to the
DBMS_STATS.GATHER_DATABASE_STATS procedure using the GATHER AUTO
option. The primary difference is that the
DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC procedure prioritizes the
database objects that require statistics, so that those objects which
most need updated statistics are processed first. This ensures that the
most-needed statistics are gathered before the maintenance window
closes.
In some cases automatically gathering statistics can cause problems.
Highly volatile tables and load tables may have their statistics
gathered when there is an unrepresentative number of rows present.
These situations can be avoided by using one of two methods:
* The current statistics can be deleted and locked
to prevent DBMS_STATS from gathering new statistics. If the
OPTIMIZER_DYNAMIC_SAMPLING parameter is set to 2 (the default) or
higher the necessary statistics will be gathered as part of the query
optimization stage (See Dynamic Sampling):
BEGIN
DBMS_STATS.delete_table_stats('MY_SCHEMA','LOAD_TABLE');
DBMS_STATS.lock_table_stats('MY_SCHEMA','LOAD_TABLE');
END;
/
* The statistics can be gathered then locked at a
time when the table contains the appropriate data:
BEGIN
DBMS_STATS.gather_table_stats('MY_SCHEMA','LOAD_TABLE');
DBMS_STATS.lock_table_stats('MY_SCHEMA','LOAD_TABLE');
END;
/
System statistics and statistics for fixed object, such as dynamic
performance tables, are not gathered automatically.
Dynamic
Sampling
Dynamic sampling enables the server to improve performance by:
* Estimate single-table predicate selectivities
where available statistics are missing or may lead to bad estimations.
* Estimate statatistics for tables and indexes with
missing statistics.
* Estimate statatistics for tables and indexes with
out of date statistics.
Dynamic sampling is controled by the OPTIMIZER_DYNAMIC_SAMPLING
parameter which accepts values from "0" (off) to "10" (agressive
sampling) with a default value of "2". At compile-time Oracle
determines if dynamic sampling would improve query performance. If so
it issues recursive statements to estimate the necessary statistics.
Dynamic sampling can be beneficial when:
* The sample time is small compared to the overall
query execution time.
* Dynamic sampling results in a better performing
query.
* The query may be executed multiple times.
In addition to the OPTIMIZER_DYNAMIC_SAMPLING system parameter the
dynamic sampling level can be set using the DYNAMIC_SAMPLING optimizer
hint for specific queries like:
SELECT /*+ dynamic_sampling(emp 10) */
empno,
ename, job, sal
FROM emp
WHERE deptno = 30;
The results of dynamic sampling are repeatable provided no rows are
inserted, updated or deleted from the sampled table. The
OPTIMIZER_FEATURES_ENABLE parameter will turns off dynamic sampling if
it is set to a version earlier than 9.2.0.
New
DBMS_STATS Behaviors
Oracle
has introduced some new
arguments that you can use with the dbms_stats
package
in Oracle Database 10g. The granularity
parameter
is used in several dbms_stats
subprograms
(e.g., gather_table_stats
and
gather_schema_stats)
to indicate the
granularity of the statistics that you want to collect, particularly
for
partitioned tables. For example, you can opt to only gather global
statistics
on a partitioned table, or you can opt to gather global and
partition-level
statistics. The granularity
parameter
comes with an auto
option.
When auto
is
used, Oracle collects global, partition-level, and sub-partition-level
statistics for a range-list partitioned table. For other partitioned
tables,
only global and partition-level statistics will be gathered. A second granularity
option,
global
and partition,
will gather the
global and partition-level statistics but no sub-partition-level
statistics,
regardless of the type of partitioning employed on the table. Here are
some
examples of using these new options:
Exec
dbms_stats.gather_table_stats(’my_user’,’my_tab’,granularity=>’AUTO’);
Exec
dbms_stats.gather_table_stats(’my_user’,’my_tab’,
granularity=>’GLOBAL
AND PARTITION’);
New
options are also available with
the degree
parameter,
which
allows you to parallelize the statistics-gathering process. Using the
new auto_degree
option,
Oracle will determine
the degree of parallelism that should be used when analyzing the table.
Simply
use the predefined value, dbms_stats.auto_degree,
in the degree
parameter.
Oracle will then decide
the degree of parallelism to use. It may choose to use either
no
parallelism or a default degree
of parallelism, which is dependent on the number of CPUs and the value
of
various database parameter settings. Here is an example of the use of
the new degree
option:
Exec
dbms_stats.gather_table_stats
(’my_user’,’my_tab’,degree=>dbms_stats.auto_degree);
Finally,
the stattype
parameter
is a new parameter
that allows you the option of gathering both data and caching
statistics (which
is the default) or only data statistics or only caching statistics.
Valid
options are all,
cache,
or data,
depending on the type of statistics you wish to gather. Here
is an example of the use of the stattype
parameter:
Exec
dbms_stats.gather_table_stats
(’my_user’,’my_tab’,stattype=>’ALL’);
You can query details about these jobs by selecting data from
dba_scheduler_jobs:
JOB_NAME
START
STATE COUNT COUNT LAST START
RUN TIME
--------------------
------------------ ----- ----- ------- -------------------
--------
PURGE_LOG
11-AUG-04 03:00 AM SCHED
513 0 05-OCT-06 03:00
AM 00:00:00
GATHER_STATS_JOB
SCHED 194 0
04-OCT-06 11:00 PM 06:23:54
ADV_SHRINK_1988719
SCHED 152 0
04-OCT-06 11:00 PM 00:00:04
ADV_SHRINK_2709655
SCHED 151 1
04-OCT-06 11:00 PM 01:39:04
MY_JOB
18-FEB-06 12:00 AM SCHED
244 24 05-OCT-06 04:00 AM
00:41:57
ADV_SHRINK_2457725
SCHED 151 0
04-OCT-06 11:00 PM 00:58:33
ADV_SQLACCESS2599661
SCHED 148 148 04-OCT-06 11:00
PM 00:00:00
The PURGE_LOG job has run 513 times since 11-AUG-04 and
GATHER_STATS_JOB has 194 runs. The number of days does not add up, as
the number of days between August, 2004 and October, 2006 is on the
order of 770 plus days. One set of days which is fairly accurate is for
MY_JOB at 244. At time of this article, there have been 230 days since
18-FEB-06, so the extra runs (both good and bad) are probably due to
manual invocations (testing, ad hoc, etc.) of the job.
Recall that the nightly maintenance window is only eight hours, and the
RUN TIME column shows that more than eight hours are required. It is
possible that some jobs do not run because they are lower in priority
(as determined by Oracle). There is an attribute/setting which may be
the culprit of why a particular run count may off. As explained in the
tuning guide:
The stop_on_window_close attribute controls whether the
GATHER_STATS_JOB continues when the maintenance window closes. The
default setting for the stop_on_window_close attribute is TRUE, causing
Scheduler to terminate GATHER_STATS_JOB when the maintenance window
closes.
The view also is telling in that it identifies jobs with serious
problems (read as “does not work at all”) such as the SQL access
advisory job at the bottom. If you don't have alerts setup to notify
you when a job succeeds (or fails), it is probably worthwhile to
periodically inspect the STATE of a job via DBA_SCHEDULER_JOBS.
Disabling a job, for example, is as simple as executing (in a PL/SQL
block if you want) dbms_scheduler.disable(‘Enter_Job_Name'); in a
SQL*Plus session (qualify with owner name if necessary). To disable the
forever-failing ADV_SQLACCESS2599661 job (this is owned by SYS):
SQL> set serveroutput on
SQL> exec
dbms_scheduler.disable('ADV_SQLACCESS2599661');
Are you stuck with the 10-6 and weekend schedule for GATHER_STATS_JOB?
Let's look at some of the details of the job via DBA_SCHEDULER_WINDOWS.
WINDOW_NAME
NEXT_START_DATE COMMENTS
----------------
--------------------- -------------------------------------
WEEKNIGHT_WINDOW 05-OCT-06
10.00.00 PM Weeknight window for maintenance task
WEEKEND_WINDOW
07-OCT-06 12.00.00 AM Weekend window for maintenance task
The attribute that cannot be changed is WINDOW_NAME. Also included in
Chapter 27 is information about altering a window. It is possible to
increase or decrease the amount of time for the maintenance window.
You alter a window using the SET_ATTRIBUTE procedure or Enterprise
Manager. With the exception of WINDOW_NAME, all the attributes of a
window can be changed when it is altered. The attributes of a window
are available in the *_SCHEDULER_WINDOWS views.
When a window is altered, it does not affect an active window. The
changes only take effect the next time the window opens.
All windows can be altered. If you alter a window that is disabled, it
will remain disabled after it is altered. An enabled window will be
automatically disabled, altered, and then reenabled, if the validity
checks performed during the enable process are successful.
Flushing
the Buffer Cache
Prior
to Oracle Database 10g, the only way to flush the database buffer
cache was to shut down the database and restart it. Oracle Database 10g
now allows you to flush the database buffer cache with the alter system
command using the flush buffer_cache parameter. The FLUSH Buffer Cache
clause is useful if you need to measure
the performance of rewritten queries or a suite of queries from
identical starting points. Use the following statement to flush the
buffer cache.
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH SHARED POOL;
However,
note that this clause is intended for use only on a test
database. It is not advisable to use this clause on a production
database, because subsequent queries will have no hits, only misses.
Database Resource Manager New
Features
The
Database Resource Manager in
Oracle Database 10g offers a few new features that you need to be aware
of:
■
The
ability
to revert to the original consumer group at the end of an operation
that caused
a change of consumer groups
■
The
ability
to set idle timeout values for consumer groups
■
The
ability
to create mappings for the automatic assignment of sessions to specific
consumer groups
Each
of these topics is discussed,
in turn, in more detail in the following sections.
Reverting
Back to the Original Consumer Group
Prior
to Oracle Database 10g, if a
SQL call caused a session to be put into a different consumer group
(for
example, because a long-running query exceeded a SWITCH_TIME directive
value in
the consumer group), then that session would remain assigned to the new
resource
group until it was ended. Oracle Database 10g allows you to use the new
SWITCH_BACK_AT_CALL_END directive to indicate that the session should
be
reverted back to the original consumer group once the call that caused
it to
switch consumer groups (or the top call) is complete. This is very
useful for
n-tier applications that create a pool of sessions in the database for
clients
to share. Previously, after the consumer group had been changed, all
subsequent
connections would be penalized based on the settings of the consumer
group
resource plan. The new SWITCH_BACK_AT_CALL_END directive allows the
session to
be reset, thus eliminating the impact to future sessions. Here is an
example of
the use of this new feature:
EXEC
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(PLAN => 'main_plan',
GROUP_OR_SUBPLAN => 'goonline',
COMMENT => 'Online sessions', CPU_P1 => 80,
SWITCH_GROUP => 'ad-hoc',
SWITCH_TIME => 3,SWITCH_ESTIMATE => TRUE,
SWITCH_BACK_AT_CALL_END=>TRUE);
In
this case, I have created a plan
directive that is a part of an overall plan called MAIN_PLAN. This
particular
plan directive is designed to limit the impact of online ad-hoc users
(or
perhaps applications that are throwing out a great deal of dynamic SQL
that’s
hard to tune) if they issue queries that take a long time (in this
example, 3
seconds). This directive causes a switch to a consumer group called
ad-hoc,
which would likely further limit CPU and might also provide for an
overall
run-time limit on executions in this particular plan/resource group.
Since I
have included the SWITCH_BACK_AT_CALL_END directive in this plan
directive, the
consumer group will revert back to the original plan after the
completion of
the long-running operation.
Setting
the Idle Timeout
Oracle
Database 10g allows you to limit
the maximum time that a session is allowed to remain idle. The max_idle_time
parameter
allows
you to define a maximum amount of time that a given session can sit
idle, as is
shown in the upcoming example. PMON will check the session once a
minute and
kill any session that has been idle for the amount of time defined in
the plan.
EXEC
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(PLAN => 'main_plan',
GROUP_OR_SUBPLAN
=> 'online', max_idle_time=>300,
comment=> ’Set
max_idle_time’);
Creating
Mappings for Automatic Assignment of Sessions to
Consumer Groups
The
dbms_resource_manager.set_group_mapping
procedure
allows you to map a specific consumer group to a given
session based on either login or run-time attributes.
These
attributes include:
■
The
username
■
The
service
name
■
The
client
OS username
■
The
client
program name
■
The
client
machine
■
The
module
name
■
The
module
name action
You
then have to determine what
session attributes you want to map to a given consumer group. In this
example,
I have mapped the client machine called tiger to the resource consumer
group
LOW_PRIORITY:
Exec
dbms_resource_manager.set_group_mapping
(DBMS_RESOURCE_MANAGER.CLIENT_MACHINE,‘tiger’,’low_priority’);
Thus,
if anyone logs in to the
database from the machine named tiger, they will be assigned to the
consumer
group LOW_PRIORITY, which will have already been created.
Often
times, there can be a number
of mappings that apply to a given session, and a priority has to be
defined.
This is done by using the procedure dbms_resource_manager.set_mapping_priority.
This example creates two mappings:
Dbms_resource_manager.set_group_mapping
(DBMS_RESOURCE_MANAGER.CLIENT_MACHINE,
‘tiger’,’low_priority’);
Dbms_resource_manager.set_group_mapping
(DBMS_RESOURCE_MANAGER.ORACLE_USER,
‘NUMBER_ONE’,’high_priority’);
In
this case, anyone signing in from
tiger is assigned to the LOW_PRIORITY consumer group, but where will
the user
NUMBER_ONE be assigned? Well, right now it’s hard to tell. So, to make
sure
that NUMBER_ONE is always set to be assigned to the high-priority
resource
consumer group, I can use the provided procedure called dbms_resource_manager.set_mapping_priority:
Dbms_resource_manager.set_mapping_priority(ORACLE_USER=>1,
CLIENT_MACHINE=>2,
EXPLICIT=>3, MODULE_NAME=>4, SERVICE_NAME=>5,
CLIENT_OS_USER=>6,
CLIENT_PROGRAM=>7, MODULE_NAME_ACTION=>8);
This
code will cause Oracle to
prioritize consumer group selection based first on username and then on
the
client machine name. So, now the user NUMBER_ONE will always get the
higher-priority consumer group assignment. Be aware that regardless of
consumer
group assignments, a user must still be given switching privileges into
a given
consumer group. If the user has not been granted such privileges, then
sessions
will not be switched.
Scheduler Changes
Oracle
Database 10g offers a brand
new job-scheduling facility, known as The Scheduler, controlled via the
new package dbms_scheduler.
This package
replaces the dbms_job
(but
that one is still available).
The
new scheduler offers much added
functionality over the dbms_job
package.
The Scheduler enables you to execute a variety of
stored code (such as PL/SQL), a native binary executable, and OS
scripts (so you can get rid of cron jobs).
The object that is being run by The Scheduler is known as the program.
The
program is more than just the name; it includes related metadata about
the
program, such as the arguments to be passed to it and the type of
program that
is being run.
Different
users can use a program at
different times, eliminating the need to have to redefine the program
every
time you wish to schedule a job. Programs can be stored in program
libraries, which
allows for easy reuse of program code by other users. Each program,
when
scheduled, is assigned to a job. A job can also just contain an
anonymous
PL/SQL block instead of a program. The job is a combination of the
program (or
anonymous PL/SQL block) and the schedule associated with the program,
which
defines when the job is to run. Also associated with the job is other
metadata
related to the job, such as the job class and the window or window
group. The
job class is a category of jobs that share various characteristics,
such as
resource consumer group assignments and assignments to a common,
specific,
service name. The job class is related to the job window. The job
window, or
window group, essentially allows the job to take advantage of specific
resource
plans. For example, if the schedule for a job is for it to run every
hour, the
job window will allow it to run under one resource group in the morning
and a
different resource group in the evening. That way, you can control the
resources the job can consume at different times throughout the day.
Oracle
provides two different interfaces into The Scheduler. The first is the dbms_scheduler
package
and the
second is through the Oracle Enterprise Manager (OEM).
More information HERE
Practical
Use of the
Scheduler
There
are a few steps to follow when
you want to assign a job to The Scheduler:
■
Create
the
program (optional).
■
Create
the
job.
Creating a Program in the
Scheduler
Creating
a program is the optional
first step when creating a scheduled operation. This operation may
actually
take four steps:
1.
Create
the program itself.
2.
Define
the program arguments.
3.
Create
the job.
4.
Define
job arguments.
The
following sections explain each
of these steps in turn.
1.Creating
the Program To
create a program, so that you can schedule it, you use the
PL/SQL-supplied procedure dbms_scheduler.create_program.
To use this package in your own schema, you must have the create
job privilege.
To use it to
create jobs in other schemas, you need the create
any job privilege.
If you are going to define an external
job, then you need the create external job privilege. By
default, a program is created in a disabled
state (which can be overridden by setting the enabled
parameter
of the create_program
procedure
to TRUE). First, let’s look at the definition
of the
dbms_scheduler.create_program
procedure:
DBMS_SCHEDULER.CREATE_PROGRAM
(
program_name
IN VARCHAR2,
program_type
IN VARCHAR2,
program_action
IN VARCHAR2,
number_of_arguments
IN PLS_INTEGER
DEFAULT 0,
enabled
IN BOOLEAN DEFAULT FALSE,
comments
IN VARCHAR2 DEFAULT NULL);
Let’s
look at a description
of the parameters
for the create_program
procedure:
Parameter
Name Description
program_name
Identifies
the name of the program. This is an internally
assigned name, which represents the program_action
that
will be executed.
program_type
Identifies
the type of executable being scheduled. Currently, the following are
valid
values: PLSQL_BLOCK, STORED_PROCEDURE, and EXECUTABLE.
program_action
Indicates
the procedure, executable name, or PL/SQL anonymous block associated
with the
program.
number_of_arguments
Identifies
the number of arguments required for the program
(ignored if program_type
is
PLSQL_BLOCK).
Enabled
Indicates
whether
the program should be enabled when created.
Comments
Allows
freeform comments describing the program or what it does.
Here
are some examples of the
creation of programs:
BEGIN
dbms_scheduler.create_program(
program_name
=> 'delete_records',
program_action
=> '/opt/oracle/maint/bin/nightly_delete_records.sh',
program_type
=> 'EXECUTABLE',
number_of_arguments=>2);
END;
You can enable this program as follows:
execute
DBMS_SCHEDULER.ENABLE ('delete_records');
You can disable this program as follows:
execute
DBMS_SCHEDULER.DISABLE ('delete_records');
Note
that Oracle does not check for the existence of the
program when the create_program
procedure
is executed. Thus, you can create your program even if
the underlying executable doesn't exist. You can create a program for
an
anonymous PL/SQL block as well, as demonstrated in this example:
BEGIN
dbms_scheduler.create_program(
program_name =>
'sp_delete_records',
program_action =>
'DECLARE rec_count
number;
BEGIN
DELETE FROM
old_records
WHERE record_date
< sysdate – 5;
rec_count:=sqlcommand%ROWCOUNT;
insert into
records_removed
(date,
table,
how_many, job_ran) VALUES
(sysdate, 'OLD_RECORDS', rec_count, scheduler$_job_start);
COMMIT;
END;',
program_type =>
'EXECUTABLE');
END;
In
the case of this anonymous block,
I used one of several supplied special variable names in my code (in
this case,
scheduler$_job_start). These variables are described briefly in the
following
table:
| Variable
Name |
Description |
| scheduler$_job_name |
Provides
the name of the job
being executed |
| scheduler$_job_owner |
Provides
the name of the owner of
the job |
| scheduler$_job_start |
Provides
the start time of the
job |
| scheduler$_window_start |
Indicates
the start time of the
window associated with the job |
| scheduler$_window_end |
Indicates
the end time of the window associated with the job |
OEM
also provides an interface to
create programs that you can use if you prefer that method.
You
can drop a program with the dbms_scheduler.drop_program
procedure,
as shown in this example:
Exec
dbms_scheduler.drop_program('delete_records');
2.Defining
the Program
Arguments Many
programs have arguments (parameters) that need to be included when that
program is called. You can
associate arguments with a program by using the dbms_scheduler.define_program_
argument procedure.
Using the previous program example, delete_records,
I can add some arguments to
the program as follows:
BEGIN
dbms_scheduler.define_program_argument(
program_name
=> 'delete_records',
argument_name
=> 'delete_date',
argument_position=>1,
argument_type=>'date',
default_value=>
'to_char(sysdate
- 5, ''mm/dd/yyyy'')' );
end;
/
To
be able to call this program, you
need the alter
any job or
create
any job privilege.
Additionally, calling this problem does not change
the state of the associated job (enabled or disabled). You can replace
an
argument by simply calling the define_
program_argument procedure
and replacing an existing
argument position.
3.Creating
the Job and Calendar Syntax
To
actually get The Scheduler to do
something, which is kind of the idea, you need to create a job. The job
can
either run a program that you have created (refer to the previous
section) or
run its own job, which is defined when the job is defined. The job
consists of
these principle definitions:
■
The
schedule This
is when the job is supposed to do whatever it's supposed to
do. The schedule consists of a start time, an end time, and an
expression that
indicates the frequency of job repetition.
■
The
associated job argument (or the what) This
is what the job is supposed to do. This can be a
pre-created PL/SQL or Java program, anonymous PL/SQL, or even an
external
executable (for example, a shell script or C program call).
■
Other
metadata associated with the job This
includes such things as the job's class and priority,
job-related comments, and the job's restartability.
Jobs are created with the dbms_scheduler.create_job
package,
as
shown in this example:
Exec
dbms_scheduler.create_job(
job_name=>'CLEAR_DAILY',
job_type=>'STORED_PROCEDURE',
job_action=>'JOBS.SP_CLEAR_DAILY',
start_date=>NULL,
repeat_interval=>'TRUNC(SYSDATE) + 1/24',
comments=>'Hourly Clearout Job');
This
example creates a scheduled job
that executes immediately and then will run every hour thereafter. This
job is
assigned a name called CLEAR_DAILY. When The Scheduler runs the job, a
PL/SQL
stored procedure called sp_clear_daily
is
executed. Perhaps another example is in order. In this case,
I will create a scheduled job that fires off an external shell script:
Exec
dbms_scheduler.create_job(
job_name=>'RUN_BACKUP',
job_type=>'EXECUTABLE',
job_action=>'/opt/oracle/admin/jobs/run_job.sh',
start_date=>'to_date('04-30-2003
20:00:00','mm-dd-yyyy
hh24:mi_ss'),
repeat_interval=>'TRUNC(SYSDATE) + 23/24',
comments=>'Daily Backup');
The
repeat_interval
attribute
defines
how often and when the job will repeat. If the repeat_interval
is
NULL (the
default), the job executes only one time and then is removed. When
determining
the interval, you have two options. First, you can use the older PL/SQL
time
expressions for defining the program execution intervals.
Oracle
Database 10g now offers a new
feature, Calendar Expressions, which you can use in lieu of the old
PL/SQL time
expressions. There are three different types of components: the
frequency
(which is mandatory), the specifier, and the interval. Frequencies
indicate how
often the job should run. The following frequencies are available:
Yearly
Monthly Weekly Daily Hourly
Minutely Secondly
The repeat_interval calendaring expression has three parts:
* The Frequency clause is made of the following elements: YEARLY,
MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY,
* The repeat interval range is from 1 to 99
* The other Frequency clause is made of the following elements:
BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR, BYMINUTE,
BYSECOND
Here are some examples of the use of calendaring expressions:
* To run a job every Tuesday at 11:24, you could use any of the
following (they are all equivalent):
FREQ=DAILY; BYDAY=TUE; BYHOUR=11; BYMINUTE=24;
FREQ=WEEKLY; BYDAY=TUE; BYHOUR=11; BYMINUTE=24;
FREQ=YEARLY; BYDAY=TUE; BYHOUR=11; BYMINUTE=24;
* Every March and June of the year:
REPEAT_INTERVAL=> `FREQ=YEARLY; BYMONTH=3,6`
* Every 20th day of the month:
REPEAT_INTERVAL=> `FREQ=MONTHLY; BYMONTHDAY=20`
* Every Sunday of the week:
REPEAT_INTERVAL=> 'FREQ=WEEKLY; BYDAY=SUN'
* Every 60 days:
REPEAT_INTERVAL=> 'FREQ=DAILY; INTERVAL=60'
* Every 6 hours:
REPEAT_INTERVAL=> 'FREQ=HOURLY; INTERVAL=6'
* Every 10 minutes:
REPEAT_INTERVAL=> 'FREQ=MINUTELY;INTERVAL=10'
* Every 30 seconds:
REPEAT_INTERVAL=> 'FREQ=SECONDLY;INTERVAL=30'
Here are some examples of using PL/SQL expressions:
REPEAT_INTERVAL=> 'SYSDATE –1'
REPERT_INTERVAL=> 'SYSDATE + 36/24'
Additional
parameters, the specifier
and interval, define in more detail how frequently the job should run.
4.Defining
the Job Arguments
If
you are scheduling a job that is not associated with a
program, then that job may be a program that accepts arguments. If this
is the
case, you need to use the dbms_scheduler.set_job_argument_value
procedure.
Executing this procedure will not enable or
disable any given job. Here is an example of setting some parameters
for a job.
In this case, I am indicating to the RUN_BACKUP job that it should
include an
argument of ‘TABLESPACE USERS', which might indicate that the backup
job should
back up the USERS tablespace.
exec
dbms_scheduler.set_job_argument_value
( job_name =>'RUN_BACKUP',
argument_name=>'BACKUP_JOB_ARG1',
argument_value=>'TABLESPACE USERS');
Create and
Drop a Schedule
You can use the create_schedule procedure to create a schedule for your
job.
In this procedure, start_date specifies the date on which the schedule
becomes active, and end_date specifies that the schedule becomes
inactive after the specified date. repeat_interval is an expression
using either the calendar syntax or PL/SQL syntax, which tells how
often a job should be repeated.
The following steps are used to create a schedule:
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name =>
'HOURLY_SCHEDULE',
start_date
=> 'TRUNC(SYSDATE)+23/24'
repeat_interval
=> 'FREQ=HOURLY; INTERVAL=1');
END;
/
You can drop a schedule by performing the following steps:
BEGIN
DBMS_SCHEDULER.DROP_SCHEDULE (
schedule_name => 'HOURLY_SCHEDULE',
force => FALSE);
END;
/
Create,
Run, Stop, Copy, and Drop a Job
Like Program, when a Job is created, it is disabled by default.
You need to explicitly enable a Job so it will become active and
scheduled. A Job can be created with the following four formats:
- With Program, With Schedule
- With Program, Without Schedule
- Without Program, With Schedule
- Without Program, Without Schedule
Example 1:
Use the following to create a Job using a predefined Program and
Schedule:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name
=> 'BACKUP_JOB_01',
program_name
=> 'BACKUP_PROGRAM',
schedule_name
=> 'BACKUP_SCHEDULE');
END;
/
Example 2:
Use the following to create a Job using a predefined Program without a
predefined Schedule:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name
=> 'BACKUP_JOB_02',
program_name
=> 'BACKUP_PROGRAM',
start_date
=> 'TRUNC(SYSDATE)+23/24',
repeat_interval
=> 'FREQ=WEEKLY; BYDAY=SUN');
END;
/
Example 3:
Use the following to create a Job using a predefined Schedule without a
predefined Program:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name
=> 'BACKUP_JOB_03',
schedule_name
=> 'BACKUP_SCHEDULE',
job_type
=> 'EXECUTABLE',
job_action
=> '/dba/scripts/weekly_backup.sh');
END;
/
Example 4:
Use the following to create a Job without a predefined Program and
Schedule:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name
=> 'BACKUP_JOB_04',
job_type
=> 'EXECUTABLE',
job_action
=> '/dba/scripts/weekly_backup.sh',
start_date
=> 'TRUNC(SYSDATE)+23/24'
repeat_interval
=> 'FREQ=WEEKLY; BYDAY=SUN');
END;
/
Here is the syntax to run, stop, copy, and drop a Job:
DBMS_SCHEDULER.RUN_JOB( job_name
in varchar2);
DBMS_SCHEDULER.STOP_JOB (
job_name in varchar2,
force in Boolean default false);
The copy_job procedures copies all attributes of an existing job to a
new job.
DBMS_SCHEDULER.COPY_JOB(
old_job
in varchar2,
new_job
in varchar2);
DBMS_SCHEDULER.DROP_JOB(
job_name
in varchar2,
force
in Boolean default false);
Other
Job Scheduler
Functionality
The
new job scheduler also allows
you to define job classes, which allow you to define a category of jobs
that
share common resource usage requirements and other characteristics. One
job can
belong to only one job class, though you can change the job class that
a given
job is assigned to. Any defined job class can belong to a single
resource
consumer group, and to a single service at any given time. Job classes,
then,
allow you to assign jobs of different priorities. For example,
administrative
jobs (such as backups) might be assigned to an administrative class
that is
assigned to a resource group that allows for unconstrained activity.
Other
jobs, with a lesser priority, may be assigned to job classes that are
assigned
to resource groups that constrain the overall operational overhead of
the job,
so that those jobs do not inordinately interfere with other,
higher-priority
jobs. Thus, job classes help you to manage the amount of resources that
a given
job can consume.
To
create a job class, you use the dbms_scheduler.create_job_class
procedure.
All classes belong to the SYS schema, and to create
one requires the manage
scheduler privilege.
Here is an example of defining a job class:
exec
dbms_scheduler.create_job_class(
job_class_name=>'CLASS_ADMIN',
resource_consumer_group=>'ADMIN_JOBS',
service=>'SERVCE_B');
This
job class will be called
CLASS_ADMIN. It is assigned to a resource consumer group (that will
have
already been created) called ADMIN_JOBS, which will no doubt give
administrative jobs pretty unfettered access to resources. This job
class is
also assigned to a specific service, SERVICE_B, so the administrator
can define
which service the job class is associated with.
Once
the job class is defined, you
can define which jobs are members of that class when you create the
jobs.
Alternatively, you can use the dbms_scheduler.set_
attribute procedure
to assign an existing job
to that class.
Example:
Converting DB jobs to Scheduler
Let's say we have a job in DBA_JOBS that we want to convert to the
Scheduler.
select job, log_user, next_date, next_sec, interval, what
from dba_jobs
where job=152152;
JOB LOG_USER NEXT_DATE NEXT_SEC INTERVAL WHAT
---------- ---------- ---------- -------- ------------------------- --------------------
152152 SCOTT 05/01/2006 01:00:00 trunc(sysdate+1) + 1/24 SCOTTS_PROC;
This job belongs to SCOTT, and executes SCOTTS_PROC every day at 1
am. Let's look at how to create and run a similar job in the Scheduler.
The rough equivalents to DBMS_JOB.SUBMIT and DBMS_JOB.RUN are:
| DBMS_JOB |
DBMS_SCHEDULER |
| dbms_job.run |
dbms_scheduler.run_job |
| dbms_job.submit |
dbms_scheduler.create_job |
DBMS_SCHEDULER.CREATE_JOB is an overloaded procedure; in this
example, we'll look at just one of many ways to call it. Here's the
call:
begin
dbms_scheduler.create_job
(job_name => 'SCOTT.RUN_SCOTTS_PROC',
job_type => 'STORED_PROCEDURE',
job_action=> 'SCOTT.SCOTTS_PROC',
start_date=> trunc(sysdate+1)+1/24,
repeat_interval=> 'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI,SAT; BYHOUR=1;',
enabled=>true,
auto_drop=>false,
comments=>'Converted from job 152152');
end;
There are a lot of things to notice here; let's go through the call
line by line.
- Instead of a number, the job's identified by the name you pass as
job_name.
Job names follow the standard Oracle naming conventions. SYS can create
a job for anyone. So, job_name => 'SCOTT.RUN_SCOTTS_PROC' creates a
job in SCOTT's schema named RUN_SCOTTS_PROC .
- You need to specify the job
type.
As in the old job scheduling mechanism, you can schedule anonymous
blocks (job_type: 'PLSQL_BLOCK') or stored procedures (job_type:
'STORED_PROCEDURE'). You can also schedule programs that run outside
the database (job_type: 'EXECUTABLE') or schedule "job chains"
(job_type: 'CHAIN'). A job chain is a sequence of jobs.
- job_action is
the equivalent of "what" in dbms_job.submit. Note that if you're
scheduling a stored procedure, you don't put a semicolon after the
procedure name, as you did in dbms_job.submit . Note also that if you
want to pass arguments to a stored procedure, like
UPDATE_INDEXES('SCOTT'), you have to either wrap the stored procedure
in an anonymous pl/sql block, or set the arguments with a separate call
to SET_JOB_ARGUMENT_VALUE - a topic we won't cover here.
- start_date is
the first date the job will execute. Note that if you specify the
repeat_interval using calendaring syntax, which we'll cover shortly, start-date
is used as a reference only - the job won't actually execute until the
next date that matches your repeat_interval. For example, if you set
the repeat interval to every Thursday, and pass a start date that's on
a Tuesday, then the job will execute on the first Thursday following
the start date.
- This call passes repeat_interval
in calendaring syntax, which
we'll discuss below. You could also pass it just as you had it in
DBA_JOBS, as 'trunc(sysdate+1) + 1/24'.
- In DBMS_SCHEDULER, unlike DBMS_JOB, the default is that
new jobs are disabled. If you want your job to be enabled as soon as
you create it, as it would have been with DBMS_JOB, then pass enabled=>true.
- You can control whether or not a one-time job is dropped after
it's run by setting auto_drop
to FALSE.
- You can pass in comments, which are displayed alongside the job
in the static data dictionary view that shows Scheduler jobs.
After you run this call to create_job, there's one more thing to
notice: you don't have to COMMIT. The results are immediately visible
to all users in the DBA_SCHEDULER_JOBS table:
OWNER JOB_NAME JOB_ACTION START_DATE REPEAT_INTERVAL STATE COMMENTS
----- --------------- ----------------- ---------- --------------- --------- -------------------------
SCOTT RUN_SCOTTS_PROC SCOTT.SCOTTS_PROC 05/08/2006 FREQ=DAILY; BYD SCHEDULED Converted from job 152152
What if you want to run this job right away? Use
dbms_scheduler.run_job:
connect scott/tiger
begin
DBMS_SCHEDULER.RUN_JOB (
job_name => 'RUN_SCOTTS_PROC',
use_current_session => false);
end;
/
Note that the default for use_current_session
is TRUE -- that is, if you don't pass this parameter, RUN_SCOTTS_PROC
will run synchronously, ie.
in your current session, instead of running asynchronously, ie. being picked up
and run by a job slave.
Job Run Log
While a job is running, it won't show up in DBA_JOBS_RUNNING; instead,
it's in DBA_SCHEDULER_RUNNING_JOBS. Once the job has executed, log rows
are written to DBA_SCHEDULER_JOB_LOG and DBA_SCHEDULER_JOB_RUN_DETAILS.
These tables record the exit status (success, failure) of each job run,
the run dates and duration, and provide any additional details such as
error messages, who stopped a stopped job, etc.
More Job Tools
If you're going to move jobs to the Scheduler, you'll need to know how
to change their next run dates (or other attributes), how to disable
and reenable them, and how to kill a running job. Fortunately, these
are all easy tasks in DBMS_SCHEDULER. Here are the rough equivalents to
the DBMS_JOB commands:
| DBMS_JOB |
Purpose |
DBMS_SCHEDULER |
| dbms_job.next_date |
Change the next time a job will run |
dbms_scheduler.set_atrribute - change the repeat_interval or
start_date |
| dbms_job.what |
Change the program a job runs |
dbms_scheduler.set_atrribute - change job_action |
| dbms_job.interval |
Change how often a job runs |
dbms_scheduler.set_atrribute - change repeat_interval |
| dbms_job.change |
Change job attributes |
dbms_scheduler.set_atrribute - change the appropriate
attribute |
| dbms_job.broken |
Mark a job as BROKEN, or unmark it |
dbms_scheduler.disable / dbms_scheduler.enable |
| alter system kill session... |
Stop a running job |
dbms_scheduler.stop_job |
Special
Notes
- To review the execution times of a job:
SELECT JOB_NAME, STATUS, ERROR#
FROM user_SCHEDULER_JOB_RUN_DETAILS;
- To review the errors of a Job:
select status, error#,
substr(additional_info,1,500)
from
user_scheduler_job_run_details ;
- By default, XE on Windows sets up the scheduler service to disabled.
Enable and start it
- If you are trying to setup a Windows .bat job, you may need to
perform the following:
job_action=>'c:\windows\system32\cmd.exe /c C:\AA\Gen_Del_Images.bat
> nul',
User-Configurable Default
Tablespaces
Oracle
offers default tablespaces in Oracle Database 10g. Once you configure a
default user
tablespace, all new users will be assigned to that tablespace rather
than the
SYSTEM tablespace. Syntax:
ALTER
DATABASE DEFAULT TABLESPACE <tsname>;
Temporary Tablespace Groups
Oracle
10g now allows you
to define temporary tablespace groups, which are logical groupings of
tablespaces. This
allows you to assign temporary tablespaces to those groups, and
then
assign this tablespace group as the default temporary tablespace for
the
database. In essence, tablespace groups allow you to combine temporary
tablespaces
into one tablespace pool that is available for use to the database.
Assigning
Temporary
Tablespaces to Tablespace Groups
You
can assign a temporary
tablespace to a tablespace group in one of two ways. First, you can
assign it
to a tablespace group when you create the tablespace via the create
tablespace command.
Second,
you can add a tablespace to a tablespace group via the alter
tablespace command.
An
example of each of these operations is listed next (note that OMF is
configured
in this example):
Create
temporary tablespace
temp_tbs_01 tempfile '.../oradata/temp01.dbf' tablespace group
tbs_group_01;
alter
tablespace temp_tbs_01
tablespace group tbs_group_02;
There
is no limit to the number of
tablespaces that can be assigned to a tablespace group. The tablespace
group
shares the same namespace as normal tablespaces, so tablespace names
and
tablespace group names are mutually exclusive. You can also remove a
tablespace
from a group by using the alter
tablespace command
and using empty quotes as an argument to the tablespace
group parameter,
as
shown in this example:
Alter
tablespace temp3 tablespace
group '';
Defining
a Tablespace Group
as the Default Temporary Tablespace
After
you have created the
tablespace group and assigned a set of tablespaces to that group, you
can
assign that group of temporary tablespaces (or that tablespace group)
as the
default temporary tablespace for the system, or as a temporary
tablespace group
for specific users.
You
can do this in the create
database statement
when
you create the database, or you can use the