Multimaster Replication :How to resolve Replication Errors

Posted by Sagar Patil

While using multimaster replication often you would be bombarded with errors like “No data found”, “Unique Key Violated” etc .

These are purely data mismatch errors and a user intervention needed to resolve them.

I often come across these errors when we run applications at multiple sites which are part of same replication group/tables when they are designed to run at one replication site at any given time.

You can get list of these errors at DEFERROER view with transaction ids but there is no easy way to locate the parameters,columns and tables on which these errors occurred.

Thankfully there is a solution if you have EM installed.

Read more…

How to start database and Apps

Posted by Sagar Patil

(Release 12)

Login as database user
cd $ORACLE_HOME/appsutil/scripts/<SID_hostname>

./addbctl.sh start <Database Name> : To start Database

./addlnctl.sh start <Listener Name> : To start Listener

Login as apps user “applmgr”

cd $APPLCSF/scripts/<SID_hostname>
./adstrtal.sh apps/<apps_password>

You can stop the application by:
Login as apps user “applmgr”
./adstpall.sh apps/<apps_password>

For stopping listener and database:
./addlnctl.sh stop <listener_name> : Stop the listener

./addbctl.sh stop immediate : would carry “shutdown immediate” at database

================= Release 12 log ==============

[oracle@apps ~]$ . APPSVIS_ebs.env

Start database and listener before starting middle tier

Login as database user , Locate “addbctl.sh” and run this script

[oracle@apps ~]$ ./addbctl.sh

You are running addbctl.sh version 120.1

addbctl.sh: too few arguments specified.

addbctl.sh [start|stop] {normal|immediate|abort}

[oracle@apps ~]$ ./addbctl.sh start

You are running addbctl.sh version 120.1

Starting the database VIS …

SQL*Plus: Release 10.2.0.3.0 – Production on Sat Feb 14 13:07:25 2009

Copyright (c) 1982, 2006, Oracle. All Rights Reserved.

Connected to an idle instance.
ORACLE instance started.

Total System Global Area 159383552 bytes
Fixed Size 1260600 bytes
Variable Size 88081352 bytes
Database Buffers 58720256 bytes
Redo Buffers 11321344 bytes
Database mounted.
Database opened.
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 – Production
With the Partitioning, OLAP and Data Mining options

addbctl.sh: exiting with status 0

2. Start listener

[oracle@apps ~]$ cd /oradb/oracle/VIS/db/tech_st/10.2.0/appsutil/scripts/VIS_apps/
[oracle@apps VIS_apps]$ ./addlnctl.sh start VIS

You are running addlnctl.sh version 120.1

Logfile: /oradb/oracle/VIS/db/tech_st/10.2.0/appsutil/log/VIS_apps/addlnctl.txt

Starting listener process VIS …

addlnctl.sh: exiting with status 0
[oracle@apps VIS_apps]$

Let’s start the middle Tier

[applmgr@apps scripts]$ ./adstrtal.sh apps/apps

You are running adstrtal.sh version 120.13.12000000.3

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adopmnctl.sh start
script returned:
****************************************************

You are running adopmnctl.sh version 120.4.12000000.3

Starting Oracle Process Manager (OPMN) …

adopmnctl.sh: exiting with status 0

adopmnctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adopmnctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adapcctl.sh start
script returned:
****************************************************

You are running adapcctl.sh version 120.6.12000000.2

Starting OPMN managed Oracle HTTP Server (OHS) instance …

adapcctl.sh: exiting with status 150

adapcctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adapcctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adoacorectl.sh start
script returned:
****************************************************

You are running adoacorectl.sh version 120.11.12000000.2

Starting OPMN managed OACORE OC4J instance …

adoacorectl.sh: exiting with status 204

adoacorectl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adoacorectl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adformsctl.sh start
script returned:
****************************************************

You are running adformsctl.sh version 120.12.12000000.3

Starting OPMN managed FORMS OC4J instance …

adformsctl.sh: exiting with status 204

adformsctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adformsctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adoafmctl.sh start
script returned:
****************************************************

You are running adoafmctl.sh version 120.6.12000000.2

Starting OPMN managed OAFM OC4J instance …

adoafmctl.sh: exiting with status 204

adoafmctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adoafmctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adalnctl.sh start
script returned:
****************************************************

adalnctl.sh version 120.3

Checking for FNDFS executable.
Starting listener process APPS_VIS.

adalnctl.sh: exiting with status 0

adalnctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adalnctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/adcmctl.sh start
script returned:
****************************************************

You are running adcmctl.sh version 120.14

Starting concurrent manager for VIS …
Starting VIS_0214@VIS Internal Concurrent Manager
Default printer is noprint

adcmctl.sh: exiting with status 0

adcmctl.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adcmctl.txt for more information …

.end std out.

.end err out.

****************************************************

Executing service control script:
/orapps/oracle/VIS/inst/apps/VIS_apps/admin/scripts/jtffmctl.sh start
script returned:
****************************************************

You are running jtffmctl.sh version 120.3

Validating Fulfillment patch level via /orapps/oracle/VIS/apps/apps_st/comn/java/classes
Fulfillment patch level validated.
Starting Fulfillment Server for VIS on port 9300 …

jtffmctl.sh: exiting with status 0

.end std out.

.end err out.

****************************************************

adstrtal.sh: Exiting with status 4

adstrtal.sh: check the logfile /orapps/oracle/VIS/inst/apps/VIS_apps/logs/appl/admin/log/adstrtal.log for more information …

(Release 11)

Execute the following script in the sequence shown below
$ORACLE_HOME/appsutil/scripts/VIS_vision/addbctl.sh start

$ORACLE
_HOME/appsutil/scripts/VIS_vision/addlnctl.sh start VIS

/u01/oracle/viscomn/admin/scripts/VIS_vision/adstrtal.sh apps/apps

To stop the services execute the script in the following sequence.
/u01/oracle/viscomn/admin/scripts/VIS_vision/adstpall.sh apps/apps

$ORACLE_HOME/appsutil/scripts/VIS_vision/addlnctl.sh stop VIS

$ORACLE_HOME/appsutil/scripts/VIS_vision/addbctl.sh stop immediate

Replication views taking longer to return results/ Truncate views

Posted by Sagar Patil

We had to relocate one of the replication node to another location. During move, other master nodes had a huge queue build up i.e  more than 1.2 million waiting transactions recorded at deftran on 5 other nodes. When the server was finally back, transaction queues were replicated to original server but we hit performance problem.

I could see deftran had 0 entries at all 5 nodes but still taking 5 minutes to return result for “select count(*) from deftran”

select segment_name,sum(bytes)/1000000 “SIZE IN MB”
from dba_segments
where segment_name like ‘%DEF%’ group by segment_name order by 2 desc;

Showed DEF$_AQCALL is still more than 1GB in size and index on same table DEF$_TRANORDER in excess of 400MB.

I decided to truncate following system tables on all nodes to release space.

select count(*) from deferror;
COUNT(*)
———-
0
select count(*) from deftran;

COUNT(*)
———-
0

select count(*) from  system.DEF$_AQCALL;
select count(*) from  system.DEF$_AQERROR;
select count(*) from  system.DEF$_CALLDEST;
select count(*) from  system.DEF$_DEFAULTDEST;
select count(*) from  system.DEF$_ERROR;
select count(*) from  system.DEF$_ORIGIN;

truncate table system.DEF$_AQCALL;
truncate table system.DEF$_AQERROR;
truncate table system.DEF$_CALLDEST;
truncate table system.DEF$_DEFAULTDEST;
truncate table system.DEF$_ERROR;
truncate table system.DEF$_ORIGIN;

DEF$_AQCALL and DEF$_TRANORDER   dropped to 1 MB and queries are lightening fast.

DEFCALL Contains information about all deferred RPCs. Queries SYSTEM.DEF$_CALL table.

DEFCALLDEST Contains the destination database(s) for each deferred RPC in DEFCALL. Queries SYSTEM.DEF$_CALL, SYSTEM.DEF$_DESTINATION, SYSTEM.DEF$_CALLDEST, SYSTEM.DEF$_ERROR, and SYSTEM.REPCAT$_REPPROP.

DEFDEFAULTDEST Contains the default destinations for deferred RPCs. Queries SYSTEM.DEF$_DEFAULTDEST.

DEFERROR Contains error information for deferred calls that could not be applied at their destination. Queries DEF$_ERROR.

DEFERRORCOUNT Contains the count of errors for each destination. Queries SYSTEM.DEF$_ERROR.

DEFSCHEDULE Contains information about the scheduling of deferred jobs. Queries SYSTEM.DEF$_DESTINATION and SYS.JOB$.

DEFTRAN Contains information about all deferred calls. Queries SYSTEM.DEF$_CALL and SYS.USER$.

DEFTRANDEST Contains the destination database(s) for each deferred transaction. Queries SYSTEM.DEF$_CALL, SYSTEM.DEF$_DESTINATION, SYSTEM.DEF$_ERROR, SYSTEM.DEF$_CALLDEST, and SYSTEM.REPCAT$_REPPROP.

API to Retrieve runtime Replication Parameters

Posted by Sagar Patil

We often get thousands of replication conflits/errors at current system. A resolution is generally looking at EM console and resolving each error manually.  Please see examples below.

This approach is working well until we have less than some thousands error x’actions at DEFERROR. Anything above that is causing a performance hit. Also DEFERROR /DEFTRANS get highly fragmented adding to the current problem. A solution would be writing a PLSQL API to retrieve runtime parameters as and when needed than using EM console to retrieve millions of rows.

SELECT argcount, schemaname, packagename, procname
FROM defcall WHERE  deferred_tran_id in
(select  deferred_tran_id from deftran where rownum <100)

ARGCOUNT	SCHEMANAME	PACKAGENAME	PROCNAME
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
17	CVD_SYSTEM	VOUCHER	REP_UPDATE
9	CVD_SYSTEM	VOUCHER_EVENT	REP_INSERT
SELECT e.destination, e.deferred_tran_id, e.origin_tran_db, e.origin_tran_id,
  e.start_time, count(e.callno)
FROM
 sys.deferror e, sys.defcall c WHERE e.deferred_tran_id = c.deferred_tran_id
  GROUP BY e.destination, e.deferred_tran_id, e.origin_tran_db,
  e.origin_tran_id, e.start_time ORDER BY 1
DESTINATION	DEFERRED_TRAN_ID	ORIGIN_TRAN_DB	ORIGIN_TRAN_ID	START_TIME	COUNT(E.CALLNO)CPI_O5CA.O2	105.45.83730	CPI_O5CB.O2	120.23.60368	09/11/2008 20:24:50	3
CPI_O5CA.O2	107.12.84097	CPI_O5CB.O2	121.41.62034	09/11/2008 20:24:51	1
CPI_O5CA.O2	107.13.84100	CPI_O5CB.O2	123.47.50472	09/11/2008 20:24:52	3
CPI_O5CA.O2	108.1.83596	CPI_O5CB.O2	123.42.50472	09/11/2008 20:24:52	1
SELECT error_msg FROM deferror
    WHERE deferred_tran_id = '107.12.84097' AND callno = 2

ERROR_MSG
ORA-01403: no data found
SELECT t.deferred_tran_id, d.dblink, t.start_time, count(c.callno)
               FROM sys.deftran t, sys.defcall c, sys.deftrandest d
            WHERE d.deferred_tran_id = t.deferred_tran_id
           AND c.deferred_tran_id = t.deferred_tran_id
          GROUP BY t.deferred_tran_id, t.start_time, d.dblink ORDER BY 3 desc
Find out the Argument Count and Call number :
select deferred_tran_id, callno, argcount, procname, packagename, schemaname
             from defcall;
Substitute Transaction ID, Argument Number and Call Number to locate parameter for that Call 

DECLARE
       atype       INTEGER;
       csform          NUMBER;
       arg_no      NUMBER;
       callno      NUMBER;
       tid         VARCHAR2(22);
       outval      VARCHAR2(2000);
BEGIN
    arg_no:=1;
    callno:='0';
    tid:='105.45.83730';
    atype:=dbms_defer_query.get_arg_type(callno, arg_no, tid);
    csform:=dbms_defer_query.get_arg_form(callno, arg_no, tid);
    IF atype = 2 THEN
      outval:=to_char(dbms_defer_query.get_number_arg(callno, arg_no, tid));
    ELSIF atype = 96 and
          csform = 1 THEN
      outval:=dbms_defer_query.get_char_arg(callno, arg_no, tid);
    ELSIF atype = 96 and
          csform = 2 THEN
      outval:=translate(dbms_defer_query.get_nchar_arg(callno, arg_no, tid) USING CHAR_CS);
    ELSIF atype= 1 and
          csform = 1 THEN
      outval:=dbms_defer_query.get_varchar2_arg(callno, arg_no, tid);
    ELSIF atype= 1 and
              csform = 2 THEN
      outval:=translate(dbms_defer_query.get_nvarchar2_arg(callno, arg_no, tid) USING CHAR_CS);
    ELSIF atype = 12 THEN
         outval:=to_char(dbms_defer_query.get_date_arg(callno, arg_no, tid), 'DD-MON-YYYY HH24:MI:SS');
    ELSIF atype = 23 THEN
         outval:=rawtohex(dbms_defer_query.get_raw_arg(callno, arg_no, tid));
    ELSIF atype = 11 THEN
         outval:=dbms_defer_query.get_rowid_arg(callno, arg_no, tid);
    ELSE
         outval:='-Binary Value-';
      -- RAISE NO_DATA_FOUND;
    END IF;
    dbms_output.put_line(outval);
END;

Rectify Differences Between Replicated Tables

Posted by Sagar Patil

Using the DIFFERENCES Procedure

The DIFFERENCES procedure compares two replicas of a table, and determines all rows in the first replica that are not in the second and all rows in the second that are not in the first. The output of this procedure is stored in two user-created tables. The first table stores the values of the missing rows, and the second table is used to indicate which site contains each row.

The RECTIFY procedure uses the information generated by the DIFFERENCES procedure to rectify the two tables. Any rows found in the first table and not in the second are inserted into the second table. Any rows found in the second table and not in the first are deleted from the second table.

To restore equivalency between all copies of a replicated table, complete the following steps:

1. Select one copy of the table to be the “reference” table. This copy will be used to update all other replicas of the table as needed.

2. Determine if it is necessary to check all rows and columns in the table for differences, or only a subset.

For example, it may not be necessary to check rows that have not been updated since the last time that you checked for differences. Although it is not necessary to check all columns, your column list must include all columns that make up the primary key (or that you designated as a substitute identity key) for the table.

3. After determining which columns you will be checking in the table, create two tables to hold the results of the comparison.

You must create one table that can hold the data for the columns being compared. For example, if you decide to compare the employee_id, salary, and department_id columns of the employees table, then your CREATE statement would need to be similar to the following:

CREATE TABLE hr.missing_rows_data (
  employee_id     NUMBER(6),
  salary          NUMBER(8,2),
  department_id   NUMBER(4));

You must also create a table that indicates where the row is found. This table must contain three columns with the datatypes shown in the following example:

CREATE TABLE hr.missing_rows_location (
  present     VARCHAR2(128),
  absent      VARCHAR2(128),
  r_id        ROWID);

4. Suspend replication activity for the replication group containing the tables that you want to compare. Although suspending replication activity for the group is not a requirement, rectifying tables that were not quiesced first can result in inconsistencies in your data.

BEGIN
   DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
      gname => 'hr_repg');
END;
/

5. At the site containing the “reference” table, call the DIFFERENCES procedure in the DBMS_RECTIFIER_DIFF package.

For example, if you wanted to compare the employees tables at the New York and San Francisco sites, then your procedure call would look similar to the following:

BEGIN
   DBMS_RECTIFIER_DIFF.DIFFERENCES (
      sname1              =>   'hr',
      oname1              =>   'employees',
      reference_site      =>   'ny.world',
      sname2              =>   'hr',
      oname2              =>   'employees',
      comparison_site     =>   'sf.world',
      where_clause        =>   '',
      column_list         =>   'employee_id,salary,department_id',
      missing_rows_sname  =>   'hr',
      missing_rows_oname1 =>   'missing_rows_data',
      missing_rows_oname2 =>   'missing_rows_location',
      missing_rows_site   =>   'ny.world',
      max_missing         =>    500,
      commit_rows         =>    50);
END;

6. Rectify the table at the “comparison” site to be equivalent to the table at the “reference” site by calling the RECTIFY procedure in the as shown in the DBMS_RECTIFIER_DIFF package following example:

BEGIN
   DBMS_RECTIFIER_DIFF.RECTIFY (
      sname1              =>   'hr',
      oname1              =>   'employees',
      reference_site      =>   'ny.world',
      sname2              =>   'hr',
      oname2              =>   'employees',
      comparison_site     =>   'sf.world',
      column_list         =>   'employee_id,salary,department_id',
      missing_rows_sname  =>   'hr',
      missing_rows_oname1 =>   'missing_rows_data',
      missing_rows_oname2 =>   'missing_rows_location',
      missing_rows_site   =>   'ny.world',
      commit_rows         =>    50);
END;
/

The RECTIFY procedure temporarily disables replication at the “comparison” site while it performs the necessary insertions and deletions, as you would not want to propagate these changes. RECTIFY first performs all of the necessary DELETE operations and then performs all of the INSERT operations. This ensures that there are no violations of a PRIMARY KEY constraint.

After you have successfully executed the RECTIFY procedure, your missing rows tables should be empty.

Loading or Re-Synchronising Data in a Replication Cluster

Posted by Sagar Patil

To strop replication and not to place a system into read only status please execute following steps.

Execute DBMS_REPUTIL.replication_OFF;

You need to execute this API at each site. This will disable all triggers and you can manually load data at respective sites.

Once the job is done enable Triggers using

Execute DBMS_REPUTIL.replication_On;

Now all further changes would be replicated.

What is a difference between QUISCED Group and Replication off?
A quisced group puts all sites under read only status while above API could be used on individual replication master sites.

If you want to sync Table Data at Multimaster Replicated Sites please see  this post

Replication Packages/Triggers Missing at new site : ORA-04067: stored procedure OBJECT_NAME$RP does not exist

Posted by Sagar Patil

I built a 6 node cluster using notes at http://www.oracledbasupport.co.uk/adding-a-new-master-node-in-an-existing-multi-master-cluster/

Everything was going OK but then noticed some tables are returning errors like

ORA-04067: not executed, stored procedure “SYSTEM.VOUCHER_NO$RP” does not exist
ORA-01085: preceding errors in deferred rpc to “SYSTEM.VOUCHER_NO$RP.REP_INSERT”
ORA-02063: preceding 2 lines from REPAA

Solution : Run following SQL to locate which tables are missing the much needed replication packages which should be generated as a part of GENERATE_REPLICATION_SUPPORT API. A replication support was pushed by Master Defn site when we add a new master/new objects into existing replication group.

— List if replication packages are available at Master as well as remote node
COLUMN group HEADING ‘Replication_Group’ FORMAT A20;
COLUMN count(*) HEADING ‘NUMBER_OF_TABLES’ FORMAT 9999999;
select gname Replication_Group,count(*) NUMBER_OF_TABLES
from REPCAT$_REPOBJECT where type= 2 group by gname order by 1;

REPLICATION_GROUP NUMBER_OF_TABLES
—————————— —————-
O1_A-B_ALL 14< BR> O1_ERROR_A-B 7

Above SQL will return how many objects have been replicated. Let’s make sure this is consistent with the remote site.

repA> select object_name from dba_objects where object_name like ‘%$R%’
minus
select object_name from dba_objects@repAA where object_name like ‘%$R%’;

OBJECT_NAME
——————————————————————————–
ACCOUNT$RP
OFFER$RP
OFFER$RP
OFFER$RP
SERVICE$RP
SUBSCRIBE$RP
SUBSCRIBE$RP
TRANSACTION$RP

8 rows selected, so 8 objects are missing replication support.

I can also use “select sname,oname,type,STATUS from DBA_REPOBJECT minus
select sname,oname,type,STATUS from DBA_REPOBJECT<at>remote_db;”

What does $RP package contain?
This package have following procedures
– rep_delete
– rep_insert
– rep_update

Let’s generate the packages missing at remote repAA site

At Master Defn Site > BEGIN
Master> DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (gname => ‘O1_BROKER_A-B’);
END;

Master> BEGIN
DBMS_REPCAT.generate_replication_package (sname => ‘BROKER_SYSTEM’,
oname =>’&1′);
END;

This went fine and did generate required packages. Above SQL returned no differences this time, still replication status was in “ERROR” at EM console

Next I tried generating a complete replication support as below.

Master/Remote DB> analyze table broker_system.account_status validate structure;

Table analyzed.
Master> BEGIN
dbms_repcat.generate_replication_support (
sname => ‘BROKER_SYSTEM’,
oname => ‘ACCOUNT_STATUS’,
type => ‘TABLE’,
distributed => TRUE);
END;
/
BEGIN
*
ERROR at line 1:
ORA-23308: object BROKER_SYSTEM.ACCOUNT_STATUS does not exist or is invalid
ORA-06512: at “SYS.DBMS_SYS_ERROR”, line 95
ORA-06512: at “SYS.DBMS_REPCAT_UTL”, line 2874

I also followed oracle Note:176913.1 and compared every stats on these tables. These databases were copied as offline backup and had exact mirror image of each other. I am using 3 sites A,AA,AAA and above error was reported from remote system AAA. A and AA were running OK.

At last I used following procedure to get them VALID

Master repA> BEGIN
DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (gname => ‘O1_BROKER_A-B’);
END;

Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘OFFER_CATEGORY’,’TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘OFFER_STATUS’, ‘TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘OFFER_SUB_CATEGORY’, ‘TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘SERVICE_PROVIDER’, ‘TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘SUBSCRIBER_OFFER’, ‘TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘SUBSCRIBER_PLAN’, ‘TABLE’);
Master repA> EXECUTE Dbms_Repcat.Drop_Master_Repobject(‘BROKER_SYSTEM’, ‘TRANSACTION_TYPE’, ‘TABLE’);

Disable all Foreign key constraints accessing these tables else truncate would fail with error “ORA-02266: unique/primary keys in table referenced by enabled foreign key”.

repAA/repAAA>truncate table OFFER_CATEGORY;
repAA/repAAA>truncate table OFFER_STATUS ;
repAA/repAAA>truncate table OFFER_SUB_CATEGORY ;
repAA/repAAA>truncate table SERVICE_PROVIDER ;
repAA/repAAA>truncate table SUBSCRIBER_OFFER ;
repAA/repAAA>truncate table SUBSCRIBER_PLAN ;
repAA/repAAA>truncate table TRANSACTION_TYPE ;

Master repA> BEGIN
DBMS_REPCAT.CREATE_MASTER_REPOBJECT (
gname => ‘O1_BROKER_A-B’,
type => ‘TABLE’,
oname => ‘&1’,
sname => ‘BROKER_SYSTEM’,
use_existing_object => TRUE,
copy_rows => TRUE);
END;
/
Enter value for 1: OFFER_CATEGORY
old 4: oname => ‘&1’,
new 4: oname => ‘OFFER_CATEGORY’,
Run above API for all tables

BEGIN
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
sname => ‘BROKER_SYSTEM’,
oname => ‘&1’,
type => ‘TABLE’,
min_communication => TRUE);
END;
/
Enter value for 1: OFFER_CATEGORY
old 4: oname => ‘&1’,
new 4: oname => ‘OFFER_CATEGORY’,
Run above API for all tables

Run DBMS_JOB dbms_repcat.do_deferred_repcat_admin(‘”O1_BROKER_A-B”‘, FALSE); to propogate the ADMINISTRATIVE requests. I often found Oracle EM doesn’t work well so run this job manually at all sites.

Average Amount of Time to Apply Transactions at Remote Sites

Posted by Sagar Patil

SELECT substr(DBLINK,1,25), AVG_LATENCY “Average Latency”
FROM DEFSCHEDULE
WHERE upper(DBLINK) like ‘&1’;

Average latency is the average number of seconds between the first call of a transaction on the current site and the confirmation that the transaction was applied at the remote site. The

SQL> SELECT substr(DBLINK,1,25), AVG_LATENCY “Average Latency”
2 FROM DEFSCHEDULE
3 WHERE upper(DBLINK) like ‘&1’;
Enter value for 1: CPI%
old 3: WHERE upper(DBLINK) like ‘&1’
new 3: WHERE upper(DBLINK) like ‘CPI%’

SUBSTR(DBLINK,1,25) Average Latency
————————- —————
CPI_L1_A.O2
CPI_L1_B.O2 546244624
CPI_L2_A.O2 546860293
CPI_L2_B.O2 546860298

Tracking the Rate of Transactions Entering the Deferred Transactions Queue

Posted by Sagar Patil

SQL will dispaly rate of x’actions entering at DEFTRAN Queue for last Hour

SQL> select to_char(trunc(start_time,’MI’),’DD-MON-YY HH24:MI:SS’),count(*) from deftran where start_time > sysdate -(1/24)
group by to_char(trunc(start_time,’MI’),’DD-MON-YY HH24:MI:SS’)
order by 1 desc

TO_CHAR(TRUNC(STAR   COUNT(*)
—————— ———-
15-DEC-08 20:32:00       1481
15-DEC-08 20:31:00       2510
15-DEC-08 20:30:00       2482
15-DEC-08 20:29:00       2543
15-DEC-08 20:28:00       2468
15-DEC-08 20:27:00       2458
15-DEC-08 20:26:00       2490
15-DEC-08 20:25:00       2505
15-DEC-08 20:24:00       2488
15-DEC-08 20:23:00       2443
15-DEC-08 20:22:00       2532
15-DEC-08 20:21:00       2555
15-DEC-08 20:20:00       2485
15-DEC-08 20:19:00        757

SQL> SELECT (R.TXNS_ENQUEUED / ((SYSDATE – I.STARTUP_TIME)*24*60*60)) “Average TPS”
2 FROM V$REPLQUEUE R, V$INSTANCE I;

Average TPS
———–
3.01341941

Tracking the Average Number of Row Changes in a Replication Transaction

Posted by Sagar Patil

SELECT DECODE(TXNS_ENQUEUED, 0, ‘No Transactions Enqueued’,
         (CALLS_ENQUEUED / TXNS_ENQUEUED)) “Average Number of Row Changes”
                  FROM V$REPLQUEUE;

SQL> SELECT (R.TXNS_ENQUEUED / ((SYSDATE – I.STARTUP_TIME)*24*60*60)) “Average TPS”
FROM V$REPLQUEUE R, V$INSTANCE I;

Average TPS
———–
3.01351231

Determining the Average Network Traffic Created to Propagate a Transaction

Posted by Sagar Patil

If this query returns ‘No transactions’ in both columns, then no transactions have been propagated to the specified remote site since the statistics were last cleared.

set linesize 120;
COLUMN AV_BYTES HEADING ‘Average Bytes’ FORMAT 999999999
COLUMN AV_TRIPS HEADING ‘Average Round Trips’ FORMAT 9999999
SELECT
substr(DBLINK,1,30) Server_Name , DECODE(TOTAL_TXN_COUNT, 0, ‘No Transactions’,
round((TOTAL_BYTES_SENT + TOTAL_BYTES_RECEIVED) / TOTAL_TXN_COUNT)) AV_BYTES,
DECODE(TOTAL_TXN_COUNT, 0, ‘No Transactions’, (TOTAL_ROUND_TRIPS / TOTAL_TXN_COUNT)) AV_TRIPS
FROM DEFSCHEDULE WHERE DBLINK like ‘%&1%’;

Listing General Information About the Error Transactions at a Replication Site

Posted by Sagar Patil

Find out total number of error X’actions

SELECT   COUNT ( * )
FROM   (SELECT   DEFERRED_TRAN_ID,
ORIGIN_TRAN_DB,
DESTINATION,
TO_CHAR (START_TIME, ‘DD-Mon-YYYY hh24:mi:ss’)
TIME_OF_ERROR,
ERROR_NUMBER,
ERROR_MSG
FROM   DEFERROR);

Locate Earliest date for the Error X’actions

SELECT   TO_CHAR (MAX (START_TIME), ‘DD-Mon-YYYY hh24:mi:ss’) TIME_OF_ERROR
FROM   DEFERROR;

Locate Latest date for the Error X’actions

SELECT   TO_CHAR (MIN (START_TIME), ‘DD-Mon-YYYY hh24:mi:ss’) TIME_OF_ERROR
FROM   DEFERROR;

Locate details of Error X’actions

COLUMN DBLINK HEADING ‘SERVER NAME’ FORMAT AAAAAA
COLUMN AVG_LATENCY  HEADING ‘Average Latency’ FORMAT 9999999
COLUMN DEFERRED_TRAN_ID HEADING ‘Deferred|Transaction|ID’ FORMAT A13
COLUMN ORIGIN_TRAN_DB HEADING ‘Origin|Database’ FORMAT A20
COLUMN DESTINATION HEADING ‘Destination|Database’ FORMAT A20
COLUMN TIME_OF_ERROR HEADING ‘Time of|Error’ FORMAT A12
COLUMN ERROR_NUMBER HEADING ‘Oracle|Error|Number’ FORMAT 999999
COLUMN ERROR_MSG HEADING ‘Oracle|Error|Message’ FORMAT A35
COLUMN RECEIVER HEADING ‘Receiver’ FORMAT A25

SELECT   DEFERRED_TRAN_ID,
ORIGIN_TRAN_DB,
DESTINATION,
TO_CHAR (START_TIME, ‘DD-Mon-YYYY hh24:mi:ss’) TIME_OF_ERROR,
ERROR_NUMBER,
ERROR_MSG
FROM   DEFERROR
ORDER BY   START_TIME;

Deferred                                                              Oracle Oracle
Transaction   Origin               Destination          Time of        Error Error
ID            Database             Database             Error         Number Message
————- ——————– ——————– ———— ——- ———————————–
7.26.5257664  CPI_L1_B.O2          CPI_L1_A.O2          30-Jul-2008     1403 ORA-01403: no data found
04:39:37

4.9.5280783   CPI_L1_B.O2          CPI_L1_A.O2          30-Jul-2008     1403 ORA-01403: no data found
04:39:46

4.19.5280577  CPI_L1_B.O2          CPI_L1_A.O2          30-Jul-2008     1403 ORA-01403: no data found

Delete Errors (Transaction Queue, Errors)

Posted by Sagar Patil

This call will delete all Errors from replication Queue i.e deferror & deftran

BEGIN
DBMS_DEFER_SYS.DELETE_ERROR( null, null);
END;
CPI_O1>>select count(*) from deferror;
COUNT(*)
----------
71000
CPI_O1>>BEGIN DBMS_DEFER_SYS.DELETE_ERROR( null, null); END;
PL/SQL procedure successfully completed.
CPI_O1VA>>commit;
Commit complete.
CPI_O1>>select count(*) from deferror;
COUNT(*)
----------
0

Also look at this slightly more complicated example. This example will first try to re-apply the error before deleting it:

spool apply_errors.sql
select 'exec dbms_defer_sys.execute_error(''' || deferred_tran_id ||''','''||
destination || ''')' from deferror;
spool off
@apply_errors commit;

spool delete_errors.sql
select 'exec dbms_defer_sys.delete_error(''' || deferred_tran_id ||''','''||
destination || ''')' from deferror;
spool off
@delete_errors commit;

Here’s how to delete all errors having XYZ.COM as a destination:

BEGIN
DBMS_DEFER_SYS.DELETE_ERROR(null, 'XYZ.COM' );
END;

Above API can only delete records. If you had built up a massive replication queue then Deftran, DefError, DefTranDest would grow to enormous size. Even after deleting all records a simple query “select count(*) from Deftrans, DefError£ can takes hours to return results. Under this case , please run following truncate to release space back to system.

truncate table SYSTEM.def$_aqerror

truncate table SYSTEM.def$_aqcall

select dblink,last_txn_count,last_error_number,total_txn_count,total_round_trips,
       total_bytes_received,total_bytes_sent,avg_throughput
       from DEFSCHEDULE where DBLINK like '&1'
DBLINK   LAST_TXN_COUNT    LAST_ERROR_NUMBER    TOTAL_TXN_COUNT    TOTAL_ROUND_TRIPS    TOTAL_BYTES_RECEIVED    TOTAL_BYTES_SENT    AVG_THROUGHPUT
TEST_O5VA    0    0    7779752    1032081    162998568    266832988    13.0574377737869
TEST_O5VC    0    0    7779798    292695    51866294    117581934    10.174205757076

BEGIN  DBMS_DEFER_SYS.CLEAR_PROP_STATISTICS (dblink => ‘TEST_O5VA’); END;

BEGIN  DBMS_DEFER_SYS.CLEAR_PROP_STATISTICS (dblink => ‘TEST_O5VB’); END;

DBLINK    LAST_TXN_COUNT    LAST_ERROR_NUMBER    TOTAL_TXN_COUNT    TOTAL_ROUND_TRIPS    TOTAL_BYTES_RECEIVED    TOTAL_BYTES_SENT    AVG_THROUGHPUT
TEST_O5VA    0    0    0    0    0    0    0
TEST_O5VC    0        0    0    0    0

Delete MASTER Node: Rollback ADD_NEW_MASTERS Procedure

Posted by Sagar Patil

I am trying to add a new master database into existing replication cluster using API DBMS_REPCAT.ADD_MASTER_DATABASE. The system returned error : ORA-23493: “REPC.US.ORACLE.COM” is not a new site for extension request “57C8B3C5C100528AE0440060B0C193C6”

Full Rrror : ERROR at line 1:
ORA-23493: “REPC.US.ORACLE.COM” is not a new site for extension request
“57A6AC50B2801525E0440060B0C193C6”
ORA-01403: no data found
ORA-06512: at “SYS.DBMS_REPCAT_ADD_MASTER”, line 2640
ORA-06512: at “SYS.DBMS_REPCAT”, line 1200
ORA-06512: at line 2

Please see post “add-a-new-node-using-add-master-database-group-quiescing-method

repA>select * from dba_repextensions;

.Master
Definition
EXTENSION_ID REQUEST Site?. EXP REPCATLOG_ID
——————————– ————— ———- — ————
EXTENSION_STA FLASHBACK_SCN BRE BRE PERCENTAGE_FOR_CATCHUP_MDEF
————- ————- — — —————————
CYCLE_SECONDS_MDEF PERCENTAGE_FOR_CATCHUP_NEW CYCLE_SECONDS_NEW
—————— ————————– —————–
57C8B3C5C100528AE0440060B0C193C6 ADD_NEW_MASTERS REPA.US.OR NO 17
ACLE.COM
INSTANTIATING 384340 NO NO 80
60 80 60

repB> select * from dba_repextensions;

.Master
Definition
EXTENSION_ID REQUEST Site?. EXP REPCATLOG_ID
——————————– ————— ———- — ————
EXTENSION_STA FLASHBACK_SCN BRE BRE PERCENTAGE_FOR_CATCHUP_MDEF
————- ————- — — —————————
CYCLE_SECONDS_MDEF PERCENTAGE_FOR_CATCHUP_NEW CYCLE_SECONDS_NEW
—————— ————————– —————–
57C8B3C5C100528AE0440060B0C193C6 ADD_NEW_MASTERS REPA.US.OR 15
ACLE.COM
INSTANTIATING NO NO 80
60 80 60

repC> select * from dba_repextensions;

no rows selected

Solution: BEGIN
DBMS_REPCAT.UNDO_ADD_NEW_MASTERS_REQUEST ( extension_id => ’57C8B3C5C100528AE0440060B0C193C6′ , drop_contents => FALSE);
END;

now

repA>select * from dba_repextensions;

no rows selected

repB>select * from dba_repextensions;

no rows selected

repC>select * from dba_repextensions;

no rows selected

Replication SQL Scripts

Posted by Sagar Patil

Count of Objects replicated in Database

SELECT   base_sname “OWNER”, COUNT (UNIQUE base_oname) NUMBER_OF_OBJECTS
FROM   REPCAT$_GENERATED
GROUP BY   base_sname;

List number of replicated objects with corresponding groups

SELECT   gname Replication_Group, COUNT ( * ) NUMBER_OF_TABLES
FROM   REPCAT$_REPOBJECT
WHERE   TYPE = 2
GROUP BY   gname
ORDER BY   1;                                                              — List number of replicated objects

SELECT   COUNT ( * ) NUMBER_OF_OBJECTS, TYPE TYPE_OF_OBJECT
FROM   REPCAT$_REPOBJECT
GROUP BY   TYPE;

List replication Group and Object Name

SELECT   gname Replication_Group, oname OBJECT_NAME
FROM   REPCAT$_REPOBJECT
WHERE   TYPE = 2
ORDER BY   1

Can I locate which tables, indexes and other objects are replicated?

SELECT   BASE_TYPE “Type of Object”,
COUNT (UNIQUE base_oname) NUMBER_OF_OBJECTS
FROM   REPCAT$_GENERATED
WHERE   BASE_TYPE = &1
GROUP BY   base_type;

where BASE_TYPE 1 INDEX
2 TABLE
4 VIEW
5 SYNONYM
6 SEQUENCE
7 PROCEDURE
8 FUNCTION
9 PACKAGE
10 PACKAGE BODY
12 TRIGGER
13 TYPE
14 TYPE BODY
32 INDEX TYPE

What is a size in MB of each replicated object?

SELECT   Segment_Name TABLE_NAME, ROUND (SUM (bytes) / 1000000) Size_In_MB
FROM   dba_segments
WHERE   segment_name IN (  SELECT   UNIQUE oname FROM REPCAT$_REPOBJECT)
GROUP BY   segment_name
ORDER BY   2 DESC;

Push Replication Group to NORMAL Status in an Exceptional Case

Posted by Sagar Patil

The dbms_repcat.resume_master_activity() package has an override parameter that defaults to FALSE. This parameter can be set to TRUE to allow the
group to become normal even if there are pending admin requests in DBA_REPCATLOG for this group.

This override should ONLY be used in extreme emergency situations, and ONLY when the ramifications and resolution of operating the replicated environment when those pending admin requests have not been applied are fully understood and acceptable. This parameter should not be used until you have contacted Oracle Support Services and addressed the situation. Use of this parameter can result in an invalidation of your replication environment, requiring the environment to be rebuild and / or resynchronised.

Drop/Delete Multi-Master Replication

Posted by Sagar Patil

Dropping Multi-master Replication

Execute following SQL at Master Defn Site (here repa)
$ sqlplus repadmin/repadmin@repa

REM Disable replication
execute dbms_repcat.suspend_master_activity(gname=>’SCOTT_REPG’);

REM Delete replication groups
execute dbms_repcat.drop_master_repobject(‘SCOTT’,’EMP’,’TABLE’);
execute dbms_repcat.drop_master_repobject(‘SCOTT’ ,’DEPT’,’TABLE’);
execute dbms_repcat.drop_master_repgroup(‘SCOTT_REPG’);
execute dbms_repcat.remove_master_databases(‘SCOTT_REPG’,’repb’);

REM Remove private database links to other master databases
drop database link repb;

connect sys/repb@repb

REM Remove the REPADMIN user
execute dbms_defer_sys.unregister_propagator (username=>’REPADMIN’);
execute dbms_repcat_admin.revoke_admin_any_schema(username=>’REPADMIN’);
drop user repadmin cascade;

REM Drop public database links to other master databases
drop public database link repb;

Delete all Errors from replication sites
Check if there are any errors “select * from deferror;”

select sname, master, status from sys.dba_repcat; – make sure the status is not QUISCED
select id, TIMESTAMP, Master Status from dba_repcatlog

Now if there are any values returned then use following API and replace ID in parameter with values returned above.
repA> exec dbms_repcat.purge_master_log(&ID,’repa’,’scott_repg’);
repB> exec dbms_repcat.purge_master_log(&ID,’repa’,’scott_repg’);

Add a new node using ADD_MASTER_DATABASE : Group Quiescing Method

Posted by Sagar Patil

I have 2 databases (repA and repB) which are part of multi master replication cluster server A and Server B. I now need to add another Server C with database name of repC. Consider this as a Live system and require a very minimum downtime.

Pre-Requisites :

Step 1> Check there are no pending X’actions at both sites repA,repB

Step 1> Find if there are any Transactions Currently Being Propagated to a Remote Master

repAA> SELECT /*+ ORDERED */ P.XID "Tran Being Propagated",
(MAX(C.CALLNO) + 1) "Number of Calls in Tran",
(P.SEQUENCE/MAX(C.CALLNO) + 1) * 100 "% Processed Calls"
FROM V$REPLPROP P, DEFCALL C
WHERE P.NAME LIKE '%SLAVE%'
AND upper(P.DBLINK) = 'REPB'
AND C.DEFERRED_TRAN_ID = P.XID
GROUP BY P.XID, P.SEQUENCE;

no rows selected

repBB> SELECT /*+ ORDERED */ P.XID "Tran Being Propagated",
(MAX(C.CALLNO) + 1) "Number of Calls in Tran",
(P.SEQUENCE/MAX(C.CALLNO) + 1) * 100 "% Processed Calls"
FROM V$REPLPROP P, DEFCALL C
WHERE P.NAME LIKE '%SLAVE%'
AND upper(P.DBLINK) = 'REPA'
AND C.DEFERRED_TRAN_ID = P.XID
GROUP BY P.XID, P.SEQUENCE;

no rows selected

Step 2> Listing the Number of Deferred Transactions for Each Destination Master Site

repAA> SELECT DBLINK DEST, COUNT(*) TRANS
FROM DEFTRANDEST D
GROUP BY DBLINK;

no rows selected

repBB> SELECT DBLINK DEST, COUNT(*) TRANS
FROM DEFTRANDEST D
GROUP BY DBLINK;

no rows selected

Step 3> Determining the Total Number of Transactions Queued for Propagation

SELECT COUNT(DISTINCT DEFERRED_TRAN_ID) “Transactions Queued” FROM DEFTRANDEST;

Transactions Queued
——————-
0

repAA>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL

repBB>>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL
repAA> Alter system set job_queue_processes=0 scope=both;

repBB> Alter system set job_queue_processes=0 scope=both;

repAA> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

repBB>>select sname, master, status from sys.dba_repcat;
SNAMEM STATUS
—————————— – ———
SCOTT_REPGY NORMAL
repAA>cd /opt/oracle/oradata
repAA>ls -l
total 4
drwxr-xr-x 2 oracle dba 1024 Sep 18 16:57 repA
drwxr-xr-x 2 oracle dba 1024 Sep 18 17:08 repB

repAA>ls -l
total 2468686
-rw-r—– 1 oracle dba 1871872 Sep 23 16:47 control01.ctl
-rw-r—– 1 oracle dba 1871872 Sep 23 16:47 control02.ctl
-rw-r—– 1 oracle dba 1871872 Sep 23 16:47 control03.ctl
-rw-r–r– 1 oracle dba 20975616 Sep 23 16:47 drsys01.dbf
-rw-Br–r– 1 oracle dba 143527936 Sep 23 16:47 example01.dbf
-rw-r–r– 1 oracle dba 26218496 Sep 23 16:47 indx01.dbf
-rw-r–r– 1 oracle dba 20975616 Sep 23 16:47 odm01.dbf
-rw-r—– 1 oracle dba 104858624 Sep 23 11:08 redo01.log
-rw-r—– 1 oracle dba 104858624 Sep 23 16:47 redo02.log
-rw-r—– 1 oracle dba 104858624 Sep 22 12:19 redo03.log
-rw-r–r– 1 oracle dba 346034176 Sep 23 16:47 system01.dbf
-rw-r–r– 1 oracle dba 99618816 Sep 18 17:10 temp01.dbf
-rw-r–r– 1 oracle dba 10489856 Sep 23 16:47 tools01.dbf
-rw-r–r– 1 oracle dba 209719296 Sep 23 16:47 undotbs01.dbf
-rw-r–r– 1 oracle dba 26218496 Sep 23 16:47 users01.dbf
-rw-r–r– 1 oracle dba 39981056 Sep 23 16:47 xdb01.dbf
Note : The same timestamp for all datafiles is same & means we have consistent backup set.

*** Prepare repCC instance as a new Master to be added into repication Cluster.

repAA>

cp -Rf repAA repCC
repAA>ls -l
total 6
drwxr-xr-x 2 oracle dba 1024 Sep 18 16:57 repAA
drwxr-xr-x 2 oracle dba 1024 Sep 18 17:08 repBB
drwxr-xr-x 2 oracle dba 1024 Sep 23 16:55 repCC

I have copied initrepB.ora init file as initrepC.ora and changed all datafile paths to repCC. I aos edited job_queue_processes and set it to 0;

repAA> alter database backup controlfile to trace;

Database altered.

repCC>export ORACLE_SID=repCC
repCC>set| grep ORACLE_SID
ORACLE_SID= repCC

$ orapwd file=orapwrepCC password=repcc entries=5

repCC> conn / as sysdba
Connected to an idle instance.

repCC> startup nomount pfile=’/opt/oracle/admin/repC/pfile/initrepC.ora’;
ORACLE instance started.

Total System Global Area 320563864 bytes
Fixed Size 735896 bytes
Variable Size 285212672 bytes
Database Buffers 33554432 bytes
Redo Buffers 1060864 bytes

repCC> show parameter job_queue

NAME TYPE VALUE
———————————— ———– ——————————
job_queue_processes integer 0

repCC> show parameter db_name

NAME TYPE VALUE
———————————— ———– ——————————
db_name string repAA

repCC> CREATE CONTROLFILE set DATABASE “repAA” NORESETLOGS ARCHIVELOG
MAXLOGFILES 50
MAXLOGMEMBERS 5
MAXDATAFILES 100
MAXINSTANCES 1
MAXLOGHISTORY 113
LOGFILE
GROUP 1 ‘/opt/oracle/oradata/repCC/redo01.log’ SIZE 100M,
GROUP 2 ‘/opt/oracle/oradata/repCC/redo02.log’ SIZE 100M,
GROUP 3 ‘/opt/oracle/oradata/repCC/redo03.log’ SIZE 100M
DATAFILE
‘/opt/oracle/oradata/repCC/system01.dbf’,
‘/opt/oracle/oradata/repCC/undotbs01.dbf’,
‘/opt/oracle/oradata/repCC/drsys01.dbf’,
‘/opt/oracle/oradata/repCC/example01.dbf’,
‘/opt/oracle/oradata/repCC/indx01.dbf’,
‘/opt/oracle/oradata/repCC/odm01.dbf’,
‘/opt/oracle/oradata/repCC/tools01.dbf’,
‘/opt/oracle/oradata/repCC/users01.dbf’,
‘/opt/oracle/oradata/repCC/xdb01.dbf’
CHARACTER SET WE8ISO8859P1;
/

repCC>alter database open NORESETLOGS;

Database altered.

repCC> ALTER TABLESPACE TEMPORARY ADD TEMPFILE ‘/opt/oracle/oradata/repCC/TEMPORARY2.dbf’
SIZE 5242880 REUSE AUTOEXTEND OFF; 2

Tablespace altered.

repCC>select instance from v$thread;

INSTANCE
—————-
repAA

At any cost do not drop replication objects using API "EXECUTE Dbms_Repcat.Drop_Master_Repobject('SCOTT', 'EMP', 'TABLE'); "
Just drop replication group - >
repCC>execute dbms_repcat.drop_master_repgroup('SCOTT_REPG');

Problem : At one event Oracle returned error so I used following API to drop Objects before Group.. Don't do this.
repCC>>execute dbms_repcat.drop_master_repgroup('SCOTT_REPG');
BEGIN dbms_repcat.drop_master_repgroup('SCOTT_REPG'); END;
*
ERROR at line 1:
ORA-23353: deferred RPC queue has entries for object group "PUBLIC"."SCOTT_REPG" so drop all individual objects before dropping group.

repCC>> EXECUTE Dbms_Repcat.Drop_Master_Repobject('SCOTT', 'EMP', 'TABLE');
repCC> EXECUTE Dbms_Repcat.Drop_Master_Repobject('SCOTT', 'DEPT', 'TABLE');
PL/SQL procedure successfully completed.

I dropped objects using above API which were then added to repCC administrative queue. When enabled replication ,it dropped objects at repBB.
Also this method failed to move group from QUIESCED to NORMAL condition which could prove a disaster on live system.
The trick here is dropping replication group by keeping DB name as repAA and then renaming database to repCC. Please make sure jobs are set to 0.
Rename repAA instance after dropping replication group to RepCC

repCC>CREATE CONTROLFILE set DATABASE “repCC” RESETLOGS ARCHIVELOG
MAXLOGFILES 50
MAXLOGMEMBERS 5
MAXDATAFILES 100
MAXINSTANCES 1
MAXLOGHISTORY 113
LOGFILE
GROUP 1 ‘/opt/oracle/oradata/repCC/redo01.log’ SIZE 100M,
GROUP 2 ‘/opt/oracle/oradata/repCC/redo02.log’ SIZE 100M,
GROUP 3 ‘/opt/oracle/oradata/repCC/redo03.log’ SIZE 100M
DATAFILE
‘/opt/oracle/oradata/repCC/system01.dbf’,
‘/opt/oracle/oradata/repCC/undotbs01.dbf’,
‘/opt/oracle/oradata/repCC/drsys01.dbf’,
‘/opt/oracle/oradata/repCC/example01.dbf’,
‘/opt/oracle/oradata/repCC/indx01.dbf’,
‘/opt/oracle/oradata/repCC/odm01.dbf’,
‘/opt/oracle/oradata/repCC/tools01.dbf’,
‘/opt/oracle/oradata/repCC/users01.dbf’,
‘/opt/oracle/oradata/repCC/xdb01.dbf’
CHARACTER SET WE8ISO8859P1;
repCC>>alter database rename global_name to repCC;

Database altered.

6. Add new database instance repCC at $ORACLE_HOME/network/admin/listener.ora

LSNRCTL>reload<br>Connectingto(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bmhp01.uk.pri.o2.com)(PORT=1521)))
The command completed successfully

7. Create fresh DB links from existing master sites to new one and vice versa. Create new links at new database repC. Note repC does have links pointing to repA.

repCC – Should have links for repAA, repBB
repAA – Should have links for repBB, repCC
repBB – Should have links for repAA, repCC

repCC>>alter database rename global_name to repCC;

Database altered.
repAA>conn sys/repa@repaa as sysdba
Connected.
repBB>create public database link repcc using ‘repcc’;

Database link created.

repBB>conn sys/repb@repbb as sysdba
Connected.
repB>create public database link repcc using ‘repcc’;

Database link created.

repBB>conn sys/repc@repcc as sysdba
Connected.

repC>create public database link repbb using ‘repbb’;
create public database link repb using ‘repb’
*
ERROR at line 1:
ORA-02082: a loopback database link must have a connection qualifier

repCC>alter database rename global_name to repCC;

Database altered.

repCC>create public database link repbb using ‘repbb’;

Database link created.

repAA>connect repadmin/repadmin@repaa

repAA>create database link repcc connect to repadmin identified by repadmin;

repBB>connect repadmin/repadmin@repbb

repBB>create database link repcc connect to repadmin identified by repadmin;

repBB>>select count(*) from tab@repcc;

COUNT(*)
———-
0
repCC>connect repadmin/repadmin@repcc

repCC>create database link repbb connect to repadmin identified by repadmin;

repCC>show parameter db_name

NAME TYPE VALUE
———————————— ———– ——————————
db_name string repCC

repCC>>select sname, master, status from sys.dba_repcat;

no rows selected
repAA>>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL

repAA>>BEGIN
DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY ( gname => ‘SCOTT_REPG’);
END;
/

PL/SQL procedure successfully completed.
repAA>>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y QUIESCED

repAA>>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
0
repAA>>show user
USER is “REPADMIN”
repAA>> BEGIN
DBMS_REPCAT.ADD_MASTER_DATABASE (
gname => ‘scott_repg’,
master => ‘repcc’,
use_existing_objects => TRUE,
copy_rows => FALSE,
propagation_mode => ‘ASYNCHRONOUS’);
END;
/
PL/SQL procedure successfully completed.

repAA>> SELECT GNAME, substr(DBLINK,1,20), MASTERDEF FROM DBA_REPSITES WHERE MASTER = ‘Y’ AND GNAME NOT IN (SELECT GNAME FROM DBA_REPSITES WHERE SNAPMASTER = ‘Y’) ORDER BY GNAME;

GNAME SUBSTR(DBLINK,1,20) M
—————————— ——————– –
SCOTT_REPG REPAA.US.ORACLE.COM Y
SCOTT_REPG REPBB.US.ORACLE.COM N
SCOTT_REPG REPCC.US.ORACLE.COM N

repAA>>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
9

repBB>>SELECT GNAME, substr(DBLINK,1,20), MASTERDEF FROM DBA_REPSITES WHERE MASTER = ‘Y’ AND GNAME NOT IN (SELECT GNAME FROM DBA_REPSITES WHERE SNAPMASTER = ‘Y’) ORDER BY GNAME;

GNAME SUBSTR(DBLINK,1,20) M
—————————— ——————– –
SCOTT_REPG REPBB.US.ORACLE.COM N
SCOTT_REPG REPAA.US.ORACLE.COM Y
SCOTT_REPG REPCC.US.ORACLE.COM N

repBB>>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
0

repCC>>SELECT GNAME, substr(DBLINK,1,20), MASTERDEF FROM DBA_REPSITES WHERE MASTER = ‘Y’ AND GNAME NOT IN (SELECT GNAME FROM DBA_REPSITES WHERE SNAPMASTER = ‘Y’) ORDER BY GNAME;

GNAME SUBSTR(DBLINK,1,20) M
—————————— ——————– –
SCOTT_REPG REPCC.US.ORACLE.COM N
SCOTT_REPG REPAA.US.ORACLE.COM Y
SCOTT_REPG REPBB.US.ORACLE.COM N

repCC>>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
6

repBB> select count(*) from REPCAT$_REPOBJECT;

COUNT(*)
———-
6
repAA>select count(*) from REPCAT$_REPOBJECT;

COUNT(*)
———-
6
repCC>select count(*) from REPCAT$_REPOBJECT;
COUNT(*)
———-
0

You should wait until the DBA_REPCATLOG view is empty. This view has temporary information that is cleared after successful execution.

Run do_deferred_repcat_admin Manually to push the Admin Queue. Execute the following SELECT statement in another SQL*Plus session to monitor the DBA_REPCATLOG view:

repAA>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
9
repBB>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
0
repCC>SELECT COUNT(*) FROM DBA_REPCATLOG WHERE GNAME = ‘SCOTT_REPG’;

COUNT(*)
———-
6

The easiset method to reoslve admin request is to use grid contorl else Oracle EM. I used it at instances repAA,BB,CC to resolve pending admin requests.

repAA> BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY (gname => ‘scott_repg’);
END;

repAA>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL

repBB>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL

repCC>>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y QUIESCED

I had to run dbms_defer_sys.push as well as do_deferred_repcat_admin at repAA/CC to get this group ito normal State

repCC>>select sname, master, status from sys.dba_repcat;

SNAME M STATUS
—————————— – ———
SCOTT_REPG Y NORMAL

repAA

repBB

repCC

Most important Checks after a new database is added into Replication Clustyer

1. Make sure the target (remote) database does have all replication support created for objects.
select sname,oname,type,STATUS from DBA_REPOBJECT minus
select sname,oname,type,STATUS from DBA_REPOBJECT<at>remote_db;

select object_name from dba_objects where object_name like ‘%$RP%’
minus
select object_name from dba_objects<@>remote_db where object_name like ‘%$RP%’;

If above SQL return any values menas there is a replication support missing at those objects at target database. Please use post

2. If you have used SQLPLUS “RECOVER until Change ” to carry recovery at new master  then DBID would be same for remote database as existing master. This would prove a problem for rman backup.
Please use nid utility to change DBID of target Database

Monitoring Performance in a Replication Environment

Posted by Sagar Patil

1. Tracking the Average Number of Row Changes in a Replication Transaction

SELECT   DECODE (TXNS_ENQUEUED,
 0, 'No Transactions Enqueued',
 (CALLS_ENQUEUED / TXNS_ENQUEUED))
 "Average Number of Row Changes"
 FROM   V$REPLQUEUE;

2. Tracking the Rate of Transactions Entering the Deferred Transactions Queue

SELECT   (R.TXNS_ENQUEUED / ( (SYSDATE - I.STARTUP_TIME) * 24 * 60 * 60))
 "Average TPS"
 FROM   V$REPLQUEUE R, V$INSTANCE I;

3. Determining the Average Network Traffic Created to Propagate a Transaction

set linesize 120;
COLUMN AV_BYTES HEADING 'Average Bytes' FORMAT 999999999
COLUMN AV_TRIPS HEADING 'Average Round Trips' FORMAT 9999999

SELECT   SUBSTR (DBLINK, 1, 30) Server_Name,
 DECODE (
 TOTAL_TXN_COUNT,
 0,
 'No Transactions',
 ROUND (
 (TOTAL_BYTES_SENT + TOTAL_BYTES_RECEIVED) / TOTAL_TXN_COUNT
 )
 )
 AV_BYTES,
 DECODE (TOTAL_TXN_COUNT,
 0, 'No Transactions',
 (TOTAL_ROUND_TRIPS / TOTAL_TXN_COUNT))
 AV_TRIPS
 FROM   DEFSCHEDULE
 WHERE   DBLINK LIKE '%C5%';

If this query returns ‘No transactions’ in both columns, then no transactions have been propagated to the specified remote site since the statistics were last cleared.

4. Determining the Average Amount of Time to Apply Transactions at Remote Sites

SELECT   AVG_LATENCY "Average Latency"
 FROM   DEFSCHEDULE
 WHERE   UPPER (DBLINK) LIKE 'REPB%';

Average latency is the average number of seconds between the first call of a transaction on the current site and the confirmation that the transaction was applied at the remote site. The

5. Clearing the Statistics for a Remote Master Site in the DEFSCHEDULE View

To clear the propagation statistics in the DEFSCHEDULE view for a particular remote master site, use

BEGIN
 DBMS_DEFER_SYS.CLEAR_PROP_STATISTICS (dblink => 'REPB');
END;

6. Determining the Transactions Currently Being Propagated to a Remote Master

SELECT                                                        /*+ ORDERED */
 P  .XID "Tran Being Propagated",
 (MAX (C.CALLNO) + 1) "Number of Calls in Tran",
 (P.SEQUENCE / MAX (C.CALLNO) + 1) * 100 "% Processed Calls"
 FROM   V$REPLPROP P, DEFCALL C
 WHERE       P.NAME LIKE '%SLAVE%'
 AND P.DBLINK = 'CEL1.WORLD'
 AND C.DEFERRED_TRAN_ID = P.XID
GROUP BY   P.XID, P.SEQUENCE;

Monitoring Purges of Successfully Propagated Transactions

Posted by Sagar Patil
  • Listing General Information About the Purge Job
  • Checking the Definition of the Purge Job
  • Determining the Amount of Time Since the Last Purge
  • Determining the Total Number of Purged Transactions

1. Listing General Information About the Purge Job

COLUMN JOB HEADING ‘Job ID’ FORMAT 999999
COLUMN PRIV_USER HEADING ‘Privilege|Schema’ FORMAT A10
COLUMN BROKEN HEADING ‘Broken?’ FORMAT A7
COLUMN next_start HEADING ‘Next Start’
COLUMN INTERVAL HEADING ‘Interval’ FORMAT A25

SELECT JOB,
PRIV_USER,
BROKEN,
TO_CHAR(NEXT_DATE, ‘DD.MM.YYYY:HH:MI:SS AM’) next_start,
INTERVAL
FROM DBA_JOBS
WHERE WHAT LIKE ‘%dbms_defer_sys.purge%’
ORDER BY 1;

2. Checking the Definition of the Purge Job

SELECT WHAT “Definition of the Purge Job”
FROM DBA_JOBS
WHERE WHAT LIKE ‘%dbms_defer_sys.purge%’ ORDER BY 1;

3. Determining the Amount of Time Since the Last Purge

SELECT ((SYSDATE – LAST_PURGE_TIME) / 60) “Minutes Since Last Purge”
FROM V$REPLQUEUE;

4. Determining the Total Number of Purged Transactions

SELECT TXNS_PURGED “Transactions Purged”
FROM V$REPLQUEUE;

Monitoring the Deferred Transactions Queue

Posted by Sagar Patil
  • Listing the Number of Deferred Transactions for Each Destination Master Site
  • Determining the Next Start Time and Interval for the Push Jobs
  • Determining the Total Number of Transactions Queued for Propagation

1. Listing the Number of Deferred Transactions for Each Destination Master Site

CONNECT repadmin/repadmin@repA

COLUMN DEST HEADING ‘Destination’ FORMAT A45
COLUMN TRANS HEADING ‘Def Trans’ FORMAT 9999

SELECT DBLINK DEST, COUNT(*) TRANS
FROM DEFTRANDEST D
GROUP BY DBLINK;

Destination Def Trans
——————————————— ———
repA 1

2. Determining the Next Start Time and Interval for the Push Jobs

CONNECT repadmin/repadmin@repA.WORLD

COLUMN JOB HEADING ‘Job ID’ FORMAT 999999
COLUMN DBLINK HEADING ‘Destination’ FORMAT A22
COLUMN next_start HEADING ‘Next Start’
COLUMN INTERVAL HEADING ‘Interval’ FORMAT A25

SELECT JOB,
DBLINK,
TO_CHAR(NEXT_DATE, ‘DD-MON-YYYY HH:MI:SS AM’) next_start,
INTERVAL
FROM DEFSCHEDULE
WHERE DBLINK != (SELECT GLOBAL_NAME FROM GLOBAL_NAME)
AND JOB IS NOT NULL
ORDER BY 1;

3. Determining the Total Number of Transactions Queued for Propagation

Run the following query to display the total number of transactions in the deferred transaction queue that are waiting to be propagated:

repA>sqlplus repadmin/repadmin@repA

SELECT COUNT(DISTINCT DEFERRED_TRAN_ID) “Transactions Queued”
FROM DEFTRANDEST;

Oracle Advanced Replication :Monitoring Administrative Requests

Posted by Sagar Patil

1. Listing General Information About Administrative Requests at the Master
2. Determining the Cause of Administrative Request Errors at the Master
3. Listing Information About the Job that Executes Administrative Requests at the Master

Listing General Information About Administrative Requests at the Master

COLUMN ID HEADING ‘Admin|Request|ID’ FORMAT 999999
COLUMN REQUEST HEADING ‘Request’ FORMAT A25
COLUMN STATUS HEADING ‘Status’ FORMAT A15
COLUMN MASTER HEADING ‘Master|Site’ FORMAT A25

SELECT ID, REQUEST, STATUS, MASTER FROM DBA_REPCATLOG;

Determining the Cause of Administrative Request Errors at the Master

COLUMN ID HEADING ‘Admin|Request|ID’ FORMAT 999999
COLUMN REQUEST HEADING ‘Request’ FORMAT A30
COLUMN ERRNUM HEADING ‘Error|Number’ FORMAT 999999
COLUMN MESSAGE HEADING ‘Error|Message’ FORMAT A32

SELECT ID, REQUEST, ERRNUM, MESSAGE
FROM DBA_REPCATLOG WHERE STATUS = ‘ERROR’;

Listing Information About the Job that Executes Administrative Requests at the Master

You can query the DBA_JOBS data dictionary view to list the following information about this job.

The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN porcedure executes the local outstanding deferred administrative procedures for the specified master group at the current master site, or (with assistance from job queues) for all master sites.

COLUMN JOB HEADING ‘Job ID’ FORMAT 999999
COLUMN PRIV_USER HEADING ‘Privilege|Schema’ FORMAT A10
COLUMN BROKEN HEADING ‘Broken?’ FORMAT A7
COLUMN next_start HEADING ‘Next Start’
COLUMN INTERVAL HEADING ‘Interval’ FORMAT A20

SELECT JOB,
PRIV_USER,
BROKEN,
TO_CHAR(NEXT_DATE,’DD.MM.YYYY:HH:MI:SS AM’) next_start,
INTERVAL
FROM DBA_JOBS
WHERE WHAT LIKE ‘%dbms_repcat.do_deferred_repcat_admin%’
ORDER BY 1;

List General Information About Master Groups & replication activity

Posted by Sagar Patil

You can retrieve following details :

  • The number of unpropagated deferred transaction-destination pairs. Each deferred transaction can have multiple destinations to which it will be propagated, and each destination is a single deferred transaction-destination pair.
  • The number of deferred transaction errors (error transactions) for each master group
  • The number of administrative requests for each master group
  • The number of administrative request errors for each master group

SELECT G.GNAME,
NVL(T.CNT1, 0) deftran,
NVL(IE.CNT2, 0) deftranerror,
NVL(A.CNT3, 0) adminreq,
NVL(B.CNT4, 0) adminreqerror
FROM
(SELECT DISTINCT GNAME FROM DBA_REPGROUP WHERE MASTER=’Y’) G,
(SELECT DISTINCT RO.GNAME, COUNT(DISTINCT D.DEFERRED_TRAN_ID) CNT1
FROM DBA_REPOBJECT RO, DEFCALL D, DEFTRANDEST TD
WHERE RO.SNAME = D.SCHEMANAME
AND RO.ONAME = D.PACKAGENAME
AND RO.TYPE IN (‘TABLE’, ‘PACKAGE’, ‘MATERIALIZED VIEW’)
AND TD.DEFERRED_TRAN_ID = D.DEFERRED_TRAN_ID
GROUP BY RO.GNAME ) T,
(SELECT DISTINCT RO.GNAME, COUNT(DISTINCT E.DEFERRED_TRAN_ID) CNT2
FROM DBA_REPOBJECT RO, DEFCALL D, DEFERROR E
WHERE RO.SNAME = D.SCHEMANAME
AND RO.ONAME = D.PACKAGENAME
AND RO.TYPE IN (‘TABLE’, ‘PACKAGE’, ‘MATERIALIZED VIEW’)
AND E.DEFERRED_TRAN_ID = D.DEFERRED_TRAN_ID
AND E.CALLNO = D.CALLNO
GROUP BY RO.GNAME ) IE,
(SELECT GNAME, COUNT(*) CNT3 FROM DBA_REPCATLOG GROUP BY GNAME) A,
(SELECT GNAME, COUNT(*) CNT4 FROM DBA_REPCATLOG
WHERE STATUS = ‘ERROR’
GROUP BY GNAME) B WHERE G.GNAME = IE.GNAME (+)
AND G.GNAME = T.GNAME (+)
AND G.GNAME = A.GNAME (+)
AND G.GNAME = B.GNAME (+) ORDER BY G.GNAME;

Oracle Advanced Replication | Listing the Master Sites Participating in a Master Group

Posted by Sagar Patil

COLUMN GNAME HEADING ‘Master Group’ FORMAT A20
COLUMN DBLINK HEADING ‘Sites’ FORMAT A25
COLUMN MASTERDEF HEADING ‘Master|Definition|Site?’ FORMAT A10

SELECT GNAME, DBLINK, MASTERDEF
FROM DBA_REPSITES
WHERE MASTER = ‘Y’
AND GNAME NOT IN (SELECT GNAME FROM DBA_REPSITES WHERE SNAPMASTER = ‘Y’)
ORDER BY GNAME;

An example of Conflict Resolution Method

Posted by Sagar Patil

Here I am going to configure Oracle to use latest timestamp method to settle conflict ON SCOTT.EMP table’s EMPNO column.

We need to

1. Define a column group for use by the resolution method.
2. Define the resolution method.
3. Add additional support as required.

1. Define the Column Group

repA> BEGIN
DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
gname => 'scott_repg');
END;

repa>execute dbms_repcat.make_column_group('SCOTT','EMP','EMP_COLGP','*');

In this example, we are defining a column group called EMP_COLGP on the EMP table in the SCOTT schema.
This column group will include every column in the table, since the ‘*’ is being used.
It is not necessary to include all columns in the column group. Since the EMPNO column can act as a primary key, we could have only defined EMPNO in our column group, which would have caused Oracle to resolve only conflicts on that column. By defining all columns in the column group, any conflict within the column group will use the conflict resolution method.

2. Define the Conflict Resolution Method

execute dbms_repcat.add_update_resolution(sname => 'SCOTT',
oname => 'EMP',
column_group => 'EMP_COLGP',
sequence => 1,
method => 'LATEST TIMESTAMP',
parameter_column_name => 'EMPNO');

Returned error
ERROR at line 1:
ORA-23325: parameter type is not TIME, TIME WITH TIME ZONE, TIMESTAMP,
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, DATE
ORA-06512: at “SYS.DBMS_REPCAT_CONF”, line 814
ORA-06512: at “SYS.DBMS_REPCAT_CONF”, line 1639
ORA-06512: at “SYS.DBMS_REPCAT”, line 307
ORA-06512: at line 2

Reason : EMPNO is not a DATETIME/TIMESTAMP field which Oracle could use in case of a Conflict. I will use SITE PRIORITY resolution method.

If we wanted to define a second method, we could use the same command, but replace the method parameters and change the sequence to equal two. Oracle will apply the two conflict resolution methods in the sequence order.

SQL> execute dbms_repcat.define_site_priority('scott_repg','SITE_PRI');
PL/SQL procedure successfully completed.

SQL> execute dbms_repcat.add_site_priority_site(‘scott_repg’,’SITE_PRI’,’repB’,10);
PL/SQL procedure successfully completed.

SQL> execute dbms_repcat.add_site_priority_site(‘scott_repg’,’SITE_PRI’,’repA’,100);
PL/SQL procedure successfully completed.

I set here repA as a primary site with strength of 100 while repB is only 10. In case of conflict Oracle should use values at SiteA.

repA>BEGIN
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
sname => 'scott',
oname => 'dept',
type => 'TABLE',
min_communication => TRUE);
END;

repA>BEGIN
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
sname => 'scott',
oname => 'emp',
type => 'TABLE',
min_communication => TRUE);
END;

repA> BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
gname => 'scott_repg');
END;

repA> update scott.emp set STATUS='SITE_A';

repA> select status from scott.emp;

STATUS
———-
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A

repB>update scott.emp set STATUS='SITE_B';

.repB>select status from scott.emp;

STATUS
———-
SITE_B
SITE_B
SITE_B
SITE_B
SITE_B
SITE_B
SITE_B
SITE_B
SITE_B

Execute manually job dbms_defer_sys.push or wait for INTERVAL to see an update.

repB> select status from scott.emp;

STATUS
———-
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A
SITE_A

Please see updated COLUMN value from SITE_B to SITE_A at Site_B as a result of site priority.

Top of Page

Top menu