Streams performance is largely dependent on your environment; the number of target sites you are replicating data to, the volume of data, the number of transactions per second occurring on the source database, the transformation logic, the hardware, the network etc, etc. However, in a simple downstream capture environment between a source and target database, it is possible to achieve very low latency even in heavy data load situations.
Consider a unidirectional archivelog downstream capture configuration. In Oracle 11g, the capture and apply processes are combined. Here, the capture process acts as the propagation sender, transmitting Logical Change Records (LCRs) directly from the capture process to the apply process. In this mode, the buffered queue is optimised to improve efficiency.
Confirmation that Streams has adopted a combined capture and apply configuration can be seen in the target database instance alert log on Streams startup:
Streams
CAPTURE CP01 for TGT_SCHEMA_CAPTURE with pid=43, OS id=27358 is in combined capture
and apply mode.
Streams
downstream capture TGT_SCHEMA_CAPTURE uses downstream_real_time_mine: FALSE
Starting
persistent Logminer Session with sid = 7 for Streams Capture TGT_SCHEMA_CAPTURE
Even in this configuration, the data replication throughput and subsequent latency, is dependant on the source database archiving it’s redologs. Oracle 11g has addressed this issue by providing a database initialisation parameter; archive_lag_target. Setting this on the source database (in seconds) allows redo log archiving to occur at defined intervals. Not too small to cause the source database to log file switch too frequently, and not to large to cause an increase in propagation latency.
In a recent test, I set the archive_lag_target parameter to 180 seconds, which provides a best effort minimum of 3 minutes of propagation latency. I.e. an archive log file will be shipped from the source database to the target database’s foreign archive log destination every 3 minutes, regardless of data volumes. So, for an idle source database, Streams will be shipping relatively empty archive logs
To achieve an archive log downstream capture configuration as described, I set the following database parameters:
Source Database (SRC)
archive_lag_target
= 180
log_archive_config
= 'SEND, RECEIVE, DG_CONFIG=(SRC,TGT)'
log_archive_dest_1
= 'LOCATION=+FLASH VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=SRC'
log_archive_dest_2
= 'SERVICE=TGT ARCH NOREGISTER VALID_FOR=(ONLINE_LOGFILES, PRIMARY_ROLE)
TEMPLATE=+FLASH/TGT/FOREIGN_ARCHIVELOG/SRC/src_arch_%t_%s_%r.log DB_UNIQUE_NAME=TGT'
log_archive_dest_state_1
= 'enable'
log_archive_dest_state_2
= 'enable'
Target Database (TGT)
log_archive_config
= 'DG_CONFIG=(SRC,TGT)'
log_archive_dest_1
= 'LOCATION=+FLASH/'
log_archive_dest_state_1
= 'enable'
For the complete setup of Streams downstream capture, refer to the Oracle documentation: http://download.oracle.com/docs/cd/B28359_01/server.111/b28321/strms_capture.htm#i1013269
To achieve a faster Streams downstream capture process realising minimum propagation latency use a “Real-time downstream capture” process. This method provides a “best of both worlds” approach, allowing a real-time mine configuration that falls back to archive log mining when the apply process cannot keep up. In addition, the real-time mine process is re-enabled automatically when data throughput is less.
Real-time downstream capture also utilises the Oracle 11g feature; combined capture and apply. However, it requires additional configuration to enable it, including the creation of standby redo logs on the target database that are directly written to by the source database’s log writer (LGWR).
The steps to convert Streams to Real-time downstream capture are described below:
Target Database (TGT)
sqlplus '/as sysdba'
SQL>
alter database add standby logfile size 1024M;
Target Database (TGT)
sqlplus streams_admin/streams_admin
SQL> exec
dbms_capture_adm.stop_capture(capture_name=>'SRC_SCHEMA_CAPTURE')
Source Database (SRC)
archive_lag_target
= 0
log_archive_dest_2
= 'SERVICE=TGT ASYNC REOPEN=30 NOREGISTER VALID_FOR=(ONLINE_LOGFILES,
PRIMARY_ROLE) DB_UNIQUE_NAME=TGT'
Target Database (TGT)
log_archive_dest_1
= 'LOCATION=+FLASH VALID_FOR=(ONLINE_LOGFILES, ALL_ROLES)'
log_archive_dest_2
= 'LOCATION=+FLASH/TGT/foreign_archivelog/SRC VALID_FOR=(STANDBY_LOGFILES,
ALL_ROLES) '
log_archive_dest_state_2
= 'enable'
SQL>
BEGIN
dbms_capture_adm.set_parameter( capture_name
=> 'SRC_SCHEMA_CAPTURE',
parameter => 'downstream_real_time_mine',
VALUE => 'Y');
END;
/
SQL> exec
dbms_capture_adm.start_capture(capture_name=>'SRC_SCHEMA_CAPTURE')
Source Database (SRC)
sqlplus
/ as sysdba
SQL>
alter system archive log current;
SQL> select CAPTURE_NAME, STATE from
v$streams_capture;
CAPTURE_NAME STATE
------------------
-----------------
SRC_SCHEMA_CAPTURE CAPTURING
CHANGES
or the (new in 11gR2) following status when the source database is idle
CAPTURE_NAME STATE
------------------
-----------------
SRC_SCHEMA_CAPTURE WAITING FOR TRANSACTION
Alert log
Confirmation that Streams is using Real-time downstream capture can be seen in the target database instance alert log upon Streams startup:
Streams
CAPTURE CP01 for SRC_SCHEMA_CAPTURE with pid=106, OS id=7896 is in combined
capture and apply mode.
Streams
downstream capture SRC_SCHEMA_CAPTURE uses downstream_real_time_mine: TRUE
Starting
persistent Logminer Session with sid = 38 for Streams Capture
SRC_SCHEMA_CAPTURE
Also note the transition to
mine standby redo logs (Realtime mine) for thread 1 sequence 11
<snip>
RFS[17]: Selected log 20 for thread 1 sequence 11
dbid 2053587448 branch 708614321
LOGMINER: End mining logfile for session 38 thread 1
sequence 10, +FLASH/tgt/foreign_archivelog/src/tgt_1_10_708614321.dbf
LOGMINER: Begin mining logfile for session 38 thread
1 sequence 11, +FLASH/tgt/onlinelog/group_20.6324.704635273 ç HERE
</snip>
So you have successfully configured Real-time downstream capture, but this is not the whole story regarding Streams performance tuning, just a step in the right direction. Let’s take a look at the hardware specification of the target database (where Streams capture process is running) and tune some Capture process parameters accordingly.
Hardware specification
HP ProLiant DL585 G2
Server
4 x 2
Core CPUs
32 GB
RAM
EMC
DMX-4 SAN Storage Array
Having spent many weeks evaluating numerous configurations, the following Capture process initialisation parameters provided the best performance for a 1000 transaction per second load (tps), equating to approximately 7000 LCRs per second:
Streams Capture Parameters
DOWNSTREAM_REAL_TIME_MINE Y
PARALLELISM 2
_CHECKPOINT_FREQUENCY 1000
_SGA_SIZE 100
DML
Handler No
Error
Handler Yes
BEGIN
dbms_capture_adm.set_parameter( capture_name
=> 'SRC_SCHEMA_CAPTURE',
parameter => '_CHECKPOINT_FREQUENCY',
VALUE => '1000');
dbms_capture_adm.alter_capture( capture_name
=> 'SRC_SCHEMA_CAPTURE',
checkpoint_retention_time
=> 7);
dbms_capture_adm.set_parameter( capture_name
=> 'SRC_SCHEMA_CAPTURE',
parameter => 'PARALLELISM',
VALUE => '2');
dbms_capture_adm.set_parameter( capture_name
=> 'SRC_SCHEMA_CAPTURE',
parameter => '_SGA_SIZE',
VALUE => '100');
END;
/
DB Initialisation Parameters
streams_pool_size
(minimum) 4G
memory_target
24G
Streams Apply Parameters
COMMIT_SERIALIZATION
NONE
PARALLELISM
32
TXN_LCR_SPILL_THRESHOLD
1000
_HASH_TABLE_SIZE
20000000
_KGL_CACHE_SIZE
100
_TXN_BUFFER_SIZE
960
BEGIN
dbms_apply_adm.set_parameter(
apply_name => 'SRC_SCHEMA_APPLY',
parameter => 'disable_on_error',
VALUE => 'n');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => '_HASH_TABLE_SIZE',
VALUE => '20000000');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => 'parallelism',
VALUE => '&app_para');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => '_DYNAMIC_STMTS',
VALUE => 'Y');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => 'TXN_LCR_SPILL_THRESHOLD',
VALUE => '1000');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => '_txn_buffer_size',
VALUE => '960');
dbms_apply_adm.set_parameter( apply_name => 'SRC_SCHEMA_APPLY',
parameter => 'commit_serialization',
VALUE => 'NONE');
END;
/
For Oracle 11gR1, STRMMON functionality has been replaced by the Streams Performance Advisor distributed within the Streams product and implemented through DBMS_STREAMS_ADVISOR_ADM PL/SQL package.
Metalink Note: 732644.1 describes how to use the package in greater detail.
For my performance tests I found the DBMS_STREAMS_ADVISOR_ADM very useful for providing all the necessary information and statistics. The package contains just 1 procedure; ANALYZE_CURRENT_PERFORMANCE that takes a "snapshot" of the current Streams environment, a similar concept to AWR snaps.
N.B. Performance
statistics require a comparison between 2 Streams Advisor snapshots.
The script below provides a complete Streams performance report, calling the DBMS_STREAMS_ADVISOR_ADM. ANALYZE_CURRENT_PERFORMANCE procedure and executing a number of queries against the TP views that are populated by the procedure. The TP views are “Temporary Performance” Streams data dictionary views containing performance and session related statistics.
#!/bin/sh
#
# run_streams_advisor.sh
#
.
~/.bash_profile
sqlplus
streams_admin/streams_admin <<EOF
exec
DBMS_STREAMS_ADVISOR_ADM.ANALYZE_CURRENT_PERFORMANCE;
alter
session set nls_date_format='DD/MM/YYYY HH24:MI';
set
lines 1000 pages 1000
set
colsep '|'
COLUMN
PATH_ID HEADING 'Path ID' FORMAT 999
COLUMN
COMPONENT_ID HEADING 'Component ID' FORMAT 999
COLUMN
COMPONENT_NAME HEADING 'Name' FORMAT A40
COLUMN
COMPONENT_TYPE HEADING 'Type' FORMAT A12
COLUMN
STATISTIC_NAME HEADING 'Statistic' FORMAT A32
COLUMN
STATISTIC_VALUE HEADING 'Value' FORMAT 99999999.99
COLUMN
STATISTIC_UNIT HEADING 'Unit' FORMAT A30
COLUMN
ADVISOR_RUN_REASON FORMAT A25
COLUMN
BOTTLENECK_IDENTIFIED FORMAT A25
COLUMN
COMPONENT_DB FORMAT A20
COLUMN
SOURCE_COMPONENT_DB FORMAT A30
COLUMN
SOURCE_COMPONENT_NAME FORMAT A40
COLUMN
DESTINATION_COMPONENT_DB FORMAT A20
COLUMN
DESTINATION_COMPONENT_NAME FORMAT A40
COLUMN
GLOBAL_NAME format a25
COLUMN
VERSION format a10
COLUMN
COMPATIBILITY format a15
set
trimspool on
spool
/home/oracle/streams/streams_advisor/streams_advisor.txt append
select
* from DBA_STREAMS_TP_COMPONENT;
select
* from DBA_STREAMS_TP_COMPONENT_LINK;
select
* from DBA_STREAMS_TP_COMPONENT_STAT;
select
* from DBA_STREAMS_TP_DATABASE;
select
* from DBA_STREAMS_TP_PATH_BOTTLENECK;
select
* from DBA_STREAMS_TP_PATH_STAT;
spool
off
EOF
During my tests, I ran the run_streams_advisor.sh via linux crontab job at 5 minute intervals.
With an optimal Streams configuration, it is still possible that the capture process will not stay in Real-time mine, i.e. when the Apply process can’t keep up with the demand and the Capture process pauses in flow control, causing Streams to start mining the archived logs until it can “catchup”. This scenario “tips the scales” in terms of latency (the time taken for a transaction to be replicated on the target database).
During my Streams schema replication performance testing I was able to maintain a 7 second latency at 1000 tps workload. Anything above this would cause a linear growth in latency that would quickly recover (back to Real-time mine) once the workload reduced to 200 tps.
_______________________________________________________________________________
Did you find the article useful?
Please provide your feedback by voting now.
If you have a comment or question, please complete and submit the form below.
_______________________________________________________________________________