• Skip Headers

    Oracle® Database Advanced Replication Management API Reference
    10g Release 1 (10.1)

    Part Number B10733-01
    Go to Documentation Home
    Home
    Go to Book List
    Book List

    Contents
    Go to Index
    Index
    Go to Master Index Master Index Go to Feedback page
    Feedback
    < /td>
    Go to previous page
    Previous
    Go to next page
    Next
    View PDF

    9
    Managing Replic ation Objects and Queues

    This chapter illustrates how to manage the replication objects and queues in your replication environment using the replication management API.

    This chapter contains these topics:

    Altering a Replicated Object

    As your database needs change, you may need to modify the characteristics of your replicated objects. It is important that you do not di rectly execute DDL to alter your replicated objects. Doing so may cause your replication environment to fail.

    Altering a Replicated Object in a Qu iesced Master Group

    Use the ALTER_MASTER_REPOBJECT proced ure in the DBMS_REPCAT package to alter the characteristics of your replicated objects in a quiesced master group. From the example following, notice that you simply include the necessary DDL within the procedure call (see the ddl_text para meter).

    If any master site is lower than 9.0.1 compatibility level, then you must use the fol lowing procedure. That is, the master group must be quiesced to modify a replicated object. You control the compatibility level of a database with the COMPATIBLE initialization parameter.

    Meet the following requir ements to complete these actions:

    Executed As: Replication Admi nistrator

    Executed At: Master Definition Site

    Replication Status: Quiesced

    Complete th e following steps to alter a replicated object in a quiesced master group.


    Note:
    /************************* BEGINNING OF SC
    RIPT ******************************
    
    Step 1 Con nect to the master definition site as the replication administrator.
    */
    
    SET ECHO ON
    
    SPOOL alter_rep_object.out
    
    CONNECT repadmin/repadmin@orc1.world
    
    /*
    
    Step 2 If necessary, then quiesce the master group.

    See the "ALTER_MASTER_REPOBJECT Procedure" for in formation about when quiesce is not required.

    */
    
    BEG
    IN
    DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
          gname => '
    hr_repg');
    END;
    /
    
    /*
    
    Step 3 In a separate SQL*Plus session, check the status of the master group y ou are quiescing.

    Do not proceed until the group's status is QUIESCED.

    To check the status, run the following query:

    SELECT G
    NAME, STATUS FROM DBA_REPGROUP;
    
    */
    
    PAUSE Press <
    RETURN> to continue when the master group's status is QUIESCED.
    
    /*
    
    Step 4 Alter the replicated object.
    */
    
    BEGIN
    DBMS_REPCAT.ALTER_
    MASTER_REPOBJECT (
          sname => 'hr',
          oname => 'employees',
          type => 'TABLE',
          ddl_text => 'ALTER TABLE hr.employees ADD (timestamp DATE)');
    END;
    /
    
    /*
    
    Step 5 Regenerate replication support for the altered object.
    */
    
    BEGIN 
    DBMS_REPCAT.GENERATE_R
    EPLICATION_SUPPORT (
          sname => 'hr',
          oname => 'employees', 
          type => 'TABLE',
          min_communication => TRUE); 
    END;
    
    /
    
    /*
    
    Step 6 In a separate SQL*Plus session, check if DBA_REPCATLOG is empty.

    Do not pr oceed until this view is empty.

    Execute the following SELECT statement in anothe r SQL*Plus session to monitor the DBA_REPCATLOG view:

    SELECT * FROM DBA_REPCATLO
    G WHERE GNAME = 'HR_REPG';
    
    */
    
    PAUSE Press <RETUR
    N> to continue when DBA_REPCATLOG is empty.
    
    /*
    
    Step 7 Resume replication activity.
    */
    <
    a name="30747">
    BEGIN
    DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
          gname => 'hr_repg');
    END;
    /
    
    SET ECHO OFF
    
    SPOOL OFF
    
    /*******************
    ****** END OF SCRIPT **********************************/
    

    Modifying Tables without Replicating the Modifications

    You may have a situation in which you need to modify a replicated object, but you do not want this modification replicated to the other sites in the replication environment. For example, you may want to disable replication in the following situations:

    • When you are using proc edural replication to propagate a change, always disable row-level replication at the start of your procedure.
    • You may need to disable replication in triggers defined on replicated tables to avoid replicating trig ger actions multiple times. See "Ensuring That Replicated Triggers Fire Only Once".
    • Sometimes when you manually resolve a conflict, you may not wan t to replicate this modification to the other copies of the table.

    You may need to do t his, for example, if you need to correct the state of a record at one site so that a conflicting replicated update will succeed when you reexecute the error transaction. Or, you may use an unreplicated modification to undo the effects of a transaction at its origin site because the transaction could not be applied at the destination site. In this example, you can use the Replication Management to ol to delete the conflicting transaction from the destination site.

    To modify tables without replicating the modifications, use the REPLICATION_ON and REPLICATION_OFF procedures in the DBMS_REPU TIL package. These procedures take no arguments and are used as flags by the generated replication triggers.


    Note:

    To enable and disable replication, you must have the EXECUTE privilege on the DBMS_REPUTI L package.


    Disabling Replication

    The DBMS _REPUTIL.REPLICATION_OFF procedure sets the state of an internal replication variable for the current session to false. Because all replicated triggers check the state of this variable before queuing any transactions, modifications made to the re plicated tables that use row-level replication do not result in any queued deferred transactions.


    Caution:

    Turning replication on or off affects only the current session. That is, other users currently connected to the same server are not restricted from placi ng committed changes in the deferred transaction queue.


    If you a re using procedural replication, then call REPLICATION_OFF at the start of your procedure, as shown in the following exa mple. This ensures that the replication facility does not attempt to use row-level replication to propagate the changes that you make .

    CREATE OR REPLACE PACKAGE update AS
      PROCEDURE update_emp(adjustment I
    N NUMBER);
    END;
    /
    
    CREATE OR REPLACE PACKAGE BODY upd
    ate AS
      PROCEDURE update_emp(adjustment IN NUMBER) IS
      BEGIN
       --turn
    off row-level replication for set update
       DBMS_REPUTIL.REPLICATION_OFF;
       UPDATE emp . . .
    ;
       --re-enable replication
       DBMS_REPUTIL.REPLICATION_ON;
      EXCEPTION
    WHEN OTHERS THEN
       . . . 
       DBMS_REPUTIL.REPLICATION_ON;
      END;
    END;
    /
    

    Reenabling Replication

    After resolving a ny conflicts, or at the end of your replicated procedure, be certain to call DBMS_REPUTIL.REPLICATION_ON to resume norma l replication of changes to your replicated tables or materialized views. This procedure takes no arguments. Calling REPLICATIO N_ON sets the internal replication variable to true.

    Ensuring That Replicated Triggers Fire Only Once

    Converting a LONG Column to a LOB Column in a Rep licated Table

    LOB columns can be replicated, but LONG columns cannot be replicated. You can convert the datatype of a LONG column to a CLOB column and the datat ype of a LONG_RAW column to a BLOB column.

    Converting a LONG< /code> column to a LOB column can result in increased network bandwidth requirements because the data in such a column is replicated after conversion. Make sure you have adequate network bandwidth before completing the procedure in this section.

    See Also:

    Oracle Database Application Developer's Guide - Large Objects for more information about applications and LONG to LOB conversion

    < a name="31408">

    Complete the following steps to convert a LONG column to a LOB column in a replicated table:

    Step 1 Make sure the data in the LONG col umn is consistent at all replication sites.

    If a table containing a LONG column is configured as a master table, then Oracle does not replicate changes to the data in the LONG column. Therefor e, the data in the LONG column may not match at all of your replication sites. You must make sure the data in the LONG column matches at all master sites before proceeding.

    Step 2 Connect to the master definition site as the replication administrator.
    CONNECT repadmin/repadmin@orc1.world
    
    Step 3 If the replication status is normal, then change the status to quiesced.
    BEG
    IN
    DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
          gname => '
    sales_mg');
    END;
    /
    
    Step 4 Convert the LONG column to a LOB column.
    BEGIN
    DBMS_REPCAT.ALTER_MASTER_REPOBJECT (
          sname => 'staff',
          oname => 'positions',
          type => 'TABLE',
          ddl_text => 'ALTER TA
    BLE staff.positions MODIFY (job_desc CLOB)');
    END;
    /
    
    

    A LONG_RAW column can be converted to a BLOB column using a similar ALTER TABLE statement.

    Step 5 Regenera te replication support for the altered master table.
    BEGIN 
    DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
          sname => 'staff',
          oname => 'positions', 
          type => 'TABLE',
          min_communication =>
    TRUE); 
    END;
    /
    
    Step 6 Resume replication.
    BEGIN
    DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
          gname => 'sales_mg');
    END;
    /
    
    Step 7 If materialized views are b ased on the altered table at any of the master sites, then rebuild these materialized views.

    Determining Differences Between Replicated Ta bles

    It is possible for the differences to arise in replicated tables. When administering a replication environment, you may want to check, periodically, whether the contents of two replicated tables are identical. The following procedures in the DBMS_RECTIFIER_DIFF package let you identify, and optionally rectify, the di fferences between two tables.

    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 r ows in the second that are not in the first. The output of this procedure is stored in two user-created tables. The first table store s the values of the missing rows, and the second table is used to indicate which site contains each row.

    Using the RECTIFY Procedure

    < !--/TOC=h2-->

    The RECTIFY procedure uses the information generated by the DIFF ERENCES procedure to rectify the two tables. Any rows found in the first table and not in the second are inserted into the sec ond 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:

    Step 1 Select one copy of the table to be the "reference" table.
    < a name="33608">

    This copy will be used to update all other replicas of the table as needed.

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

    For example, it may not be necessary to ch eck rows that have not been updated since the last time that you checked for differences. Although it is not necessary to check all c olumns, 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.

    Step 3 After determining which col umns 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 th e employee_id, salary, and department_id columns of the employees table, then you r CREATE statement would need to be similar to the following:

    CREATE TABLE hr.mi
    ssing_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);
    
    Step 4 Suspend replication activity for the replication group containing the tables that you want to c ompare.

    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.

    CO
    NNECT repadmin/repadmin
    
    BEGIN
    DBMS_REPCAT.S
    USPEND_MASTER_ACTIVITY (
          gname => 'hr_repg');
    END;
    /
    
    Step 5 At the site containing the "reference" table, call the DIFFERENCES procedure.

    For example, if you wanted to compare the emplo yees 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',
    <
    /a>      reference_site      =>   'ny.world',
          sname2              =>   'hr',
    
      oname2              =>   'employees',
          comparison_site     =>   'mv4.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.wo
    rld',
          max_missing         =>    500,
          commit_rows         =>    50);
    END;
    /
    
    

    Figure 9-1 shows an example of two replicas of the employee table and what the resulting missing rows tables wo uld look like if you executed the DIFFERENCES procedure on these replicas.

    Figure 9-1 Determining Differences Between Replicas

    Text description of repma003.gif follows

    Text description of the ill ustration repma003.gif

    Notice that the two missing rows tables are related by the R OWID and r_id columns.

    Step 6 Rectify the table at the "comparison" site to be equivalent to the table at the "reference" site.
    BEGIN
    DBMS_RECTIFIER_DIFF.RECTIFY (
          snam
    e1              =>   'hr',
          oname1              =>   'employees',
          reference_
    site      =>   'ny.world',
          sname2              =>   'hr',
          oname2
       =>   'employees',
          comparison_site     =>   'mv4.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 procedur e temporarily disables replication at the "comparison" site while it performs the necessary insertions and deletions, as you would no t want to propagate these changes. RECTIFY first performs all of the necessary DELETE operations and then p erforms 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.


    Caution:

    If you have any additional constraints on the "comp arison" table, then you must ensure that they are not violated when you call RECTIFY. You may need to update the table d irectly using the information in the missing rows table. If so, then be sure to DELETE the appropriate rows from the mis sing rows tables.


    St ep 7 Repeat Steps 5 and 6 for the remaining copies of the replicate d table.

    Remember to use the same "reference" table each time to ensure that all copi es are identical when you complete this procedure.

    Step 8 Resume replication activity for the master group.
    BEGIN
    
    DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
          gname => 'hr_repg');
    END;
    /
    

    Managing the Deferred Transactions Queue

    Typic ally, Advanced Replication is configured to push and purge the deferred transaction queue automatically. At times, however, you may n eed to push or purge the deferred transaction queue manually. The process for pushing the deferred transaction queue is the same at m aster sites and materialized view sites.

    Pushing the Deferred Transaction Queue

    Mas ter sites are configured to push the deferred transaction queue automatically at set intervals. At materialized view sites, if you do not automatically propagate the transactions in your deferred transaction queue during the refresh of your materialized view, then y ou must complete the following steps to propagate changes made to the updatable materialized view to its master table or master mater ialized view.

    This example illustrates pushing the deferred transaction queue at a materializ ed view site, but the process is the same at master sites and materialized view sites.

    Executed As: Materialized View Administrator

    Exe cuted At: Materialized View Site

    Complete the following steps:

    < /a>
    Step 1 Connect to the materialized view site as the materialized view administrator.
    CONNECT mviewadmin/mviewadmin@mv1.world
    
    < h5 class="LST">Step 2 Execute the following SELECT statement to view the deferred transacti ons and their destinations.

    Propagation of the deferred transaction queue is based on the destination of the transaction. Each distinct destination and the number of transactions pending for the destination will be dis played.

    SELECT DISTINCT(dblink), COUNT(deferred_tran_id) 
       FROM deftran
    dest GROUP BY dblink;
    
    Step 3 Execute the DBMS_ DEFER_SYS.PUSH function for each site that is listed as a destination for a deferred transaction.
    DECLARE
       temp INTEGER;
    BEGIN
       temp := DBMS_DEFER_SYS.PUSH (
          destination => 'orc1.world',
          stop_on_erro
    r => FALSE,
          delay_seconds => 0,
          parallelism => 0);
    E
    ND;
    /
    
    

    Run the PUSH procedure for eac h destination that was returned in the SELECT statement you ran in Step 2.

    Purging the Deferred Tran saction Queue

    If your system is not set to automatically purge the suc cessfully propagated transactions in your deferred transaction queue periodically, then you must complete the following steps to purg e them manually.

    This example illustrates purging the deferred transaction queue at a materia lized view site, but the process is the same at master sites and materialized view sites.

    Executed As: Materialized View Administrator

    Executed At: Materialized View Site

    Complete the following steps:

    Step 1 Connect to the materialized view site as the materialized vi ew administrator.
    CONNECT mviewadmin/mviewadmin@mv1.world
    
    Step 2 Purge the deferred transaction queue.
    DECLARE
       temp INTEGER;
    BEGIN
       temp := DBMS_DEFER_SYS.PURGE (
          purge_method => DBMS_DEFER_SYS.PURGE_METHOD_QUICK);
    END;
    /
    

    Not e:

    If you use the purge_method_quick parameter, deferred transaction s and deferred procedure calls that have been successfully pushed may remain in the DEFTRAN and DEFCALL dat a dictionary views for longer than expected before they are purged. See the "Usage Notes" for DBMS_DEFER_SYS.PURGE for details.


    Using the AnyData Type to Determine the Val ue of an Argument in a Deferred Call

    If you are using column objects, collections, or REFs in a replicated table, then you can use the GET_AnyData_ARG function in the DBMS _DEFER_QUERY package to determine the value of an argument in a deferred call that involves one of these user-defined types.

    The following example illustrates how to use the GET_AnyData_ARG function. This e xample uses the following user-defined types in the oe sample schema.

    CREATE TYP
    E phone_list_typ AS VARRAY(5) OF VARCHAR2(25);
    /
    
    CREATE TYPE warehouse_t
    yp AS OBJECT
        (warehouse_id       NUMBER(3), 
         warehouse_name     VARCHAR2(35), 
         location_id        NUMBER(4)
        );
    /
    
    CREATE TYPE inventory_typ AS OBJECT
        (product_id          NUMBER(6), 
         warehouse
               warehouse_typ,
         quantity_on_hand    NUMBER(8)
        );
    /
    
    CREATE TYPE inventory_list_typ AS TABLE OF inventory_typ;
    /
    
    

    The following procedure retrieves the argument value for collection, object, and REF instances of calls stored in the deferred transactions queue. This procedure assumes that the call number and transacti on id are available.

    The user who creates the procedure must have EXECUTE privil ege on the DBMS_DEFER_QUERY package and must have CREATE PROCEDURE privilege. This example use s the oe sample schema. Therefore, to run the example, you must grant the oe user these privileges.

    CONNECT SYSTEM/MANAGER AS SYSDBA GRANT EXECUTE ON DBMS_DEFE R_QUERY TO oe; GRANT CREATE PROCEDURE TO oe; CONNEC T oe/oe@orc1.world CREATE OR REPLACE PROCEDURE get_userdef_arg AS call _no NUMBER := 0; txn_id VARCHAR2(128) := 'xx.xx.xx'; anydata_val Sys.AnyData; t SYS.AnyType; data_pl phone_list_typ; -- varray data_ntt inventory_list_typ; -- nested table type data_p warehouse_typ; -- object type ref1 REF inventory_typ; -- REF type rval PLS_INTEGER; -- return value < a name="32404"> tc PLS_INTEGER; -- return value prec PLS_INTEGER; -- preci sion scale PLS_INTEGER; -- scale len PLS_INTEGER; -- length csid PLS_INTEGER; -- character set id csfrm PLS_INTEGER; -- character set form cnt PLS_INTEGER; -- count of varray elements or number of < /a> -- object attributes sname VARCHAR2(35); -- schema name type_name VARCHAR2(35); -- type name version VARCHAR2(35); BEGIN FOR i IN 1 .. 5 LOOP anydata_val := DBMS_DEFER_QUERY.GET_AnyData_ARG(call_no, i , txn_id); -- Get the type information, including type name. tc := anydata_val.GetT ype(t); tc := t.GetInfo(prec, scale, len, csid, csfrm, sname, type_name, version, cnt); -- Based on the type name, convert the anydata value to the appropriate -- user-defined types. IF type_name = 'PHONE_LIST_TYP' THEN -- The any data_val contains phone_list_typ varray instance. rval := anydata_val.GetCollection(data_pl); -- Do something with data_pl. ELSIF type_name = 'INVENTORY_LIST_TYP' THEN -- anydata_val contains inventory_list_typ nested table instance. rval := anydata_val.GetCollectio n(data_ntt); -- Do something with data_ntt. ELSIF type_name = 'WAREHOUSE_TYP' THE N -- The anydata_val contains warehouse_typ object instance. rval := anydata_va l.GetObject(data_p); -- Do something with data_p. ELSIF type_name = 'INVENTORY_TY P' THEN -- The anydata_val contains a reference to inventory_typ object instance. rval := anydata_val.GetRef(ref1); -- Do something with ref1. END IF; END LOOP; END; /

    Managing the Error Queue

    As an ad ministrator of a replication environment, you should regularly monitor the error queue to determine if any deferred transactions were not successfully applied at the target master site.

    To check the error queue, issue the foll owing SELECT statement (as the replication administrator) when connected to the target master site:

    SELECT * FROM deferror;
    
    

    If the error queue contai ns errors, then you should resolve the error condition and reexecute the deferred transaction. You have two options when reexecuting a deferred transaction: you can reexecute in the security context of the user who received the deferred transaction, or you can reexe cute the deferred transaction with an alternate security context.


    Caution:

    If you have multiple error transactions and you want to make sure they are reexecuted in the correct order, then you can specify NULL for the deferred_tran_id parameter in the procedures in the following sections. If you do not specify NULL, then reexecuting individual transacti ons in the wrong order can cause conflicts.


    Reexecuting Error Transaction as the Receiver

    The following procedure reexecutes a specified deferred transaction in the security context of th e user who received the deferred transaction. This procedure should not be executed until the error situation has been resolved.

    Meet the following requirements to complete these actions:

    Executed As: Replication Administrator

    E xecuted At: Site Containing Errors

    Replication Status: Normal

    Complete the following steps:

    Step 1 Connect to the master site as the replication administrator.
    CONNECT repadmin/repadmin@orc2.world
    
    Step 2 Reexecute the error transaction.
    BEGIN
    DBMS_DEFER_SYS.EXECUTE_ERROR (
          deferred_tran_id => '1.12.2904',
    
       destination => 'ORC2.WORLD');
    END;
    /
    

    Reexecuting Error Transaction as Alternate User

    The following procedure reexecutes a specified deferred transaction in the securit y context of the currently connected user. This procedure should not be executed until the error situation has been resolved.

    Meet the following requirements to complete these actions:

    < strong class="Bold">Executed As: Connected User

    Executed At: Site Containing Errors

    Replication Status: Normal

    Complete the following steps:

    Step 1 Connect to the master site as the alternate user.
    CONNECT hr/hr
    @orc2.world
    
    Step 2 Reexecute the error transac tion.
    BEGIN
    DBMS_DEFER_SYS.EXECUTE_E
    RROR_AS_USER (
          deferred_tran_id => '1.12.2904',
          destination => 'ORC2.WO
    RLD');
    END;
    /