『OGG 03』Win7 配置 Oracle GoldenGate 一次性成功(包括Adapter Java)


安裝Oracle:

安裝 Oracle_11g 32位【Oracle 32位的話,OGG 也必須是 32位,否則會有0xc000007b無法正常啟動 錯誤】

安裝目錄為 D:\oracle\product\11.1.0\db1 【這個目錄要設置為 環境變量 ORACLEHOME】

設置環境變量:

JAVAHOME C:\Program Files\Java\jdk1.8.0121

ORACLEHOME D:\oracle\product\11.1.0\db1

ORACLE_SID ORCL

驗證環境變量:

獲取 ORACLESID : 打開 SQLPlus,登錄 SYS 賬戶,執行 select instancename from v$instance;

獲取 ORACLEHOME : 查找 Oracle安裝目錄,這個目錄有個特征:有一個子目錄名叫 RDBMS。就是說: %ORACLEHOME%\RDBMS\ 這個路徑要能正常打開即為配置成功。

Oracle數據庫創建用戶,授予 DBA權限

略(參見 《__Win7 配置 Oracle GoldenGate 踩坑指南》中的配置)

Oracle啟用日志存檔模式

略(參見 《__Win7 配置 Oracle GoldenGate 踩坑指南》中的配置)

安裝 OGG

安裝 32位的 OGG 11.1,用於數據庫之間的 同步 (和 Oracle 數據庫版本、位數一致)

安裝 64位的 OGG Adapter Java 12,用於Java程序適配(11.1 的版本會崩潰)

安裝 64位的 JDK 1.8 (OGG Adapter Java 因為是64位的)

http://www.oracle.com/technetwork/cn/middleware/goldengate/downloads/index.html

拖到頁面最后面

搜索 需要下載的 OGG

單擊“購物車”,選擇需要下載的版本

點擊 右下角的 “下載”,把OGG文件 放到 D盤

先說一下目標:

Oracle 數據庫中 有 兩個用戶(結構) ADMIN 和

每個用戶(結構) 都有結構完全一樣的 表: TB_TEST

目標1:我們要配置OGG,當 ADMIN.TBTEST 的數據變化時,ROOT.TBTEST 能自動同步這種變化(實現容災備份)

目標2:我們要配置OGG,當 ADMIN.TB_TEST 的數據變化時,Java程序可以捕獲到這種變化。

部署 OGG

上面4個目錄的意思:

  • dirdat 目標端的 Trail 文件目錄

  • s 源端(ADMIN.TB_TEST 的OGG服務,數據抽取)

  • t 目標端(ROOT.TB_TEST 的 OGG服務,數據備份)

  • javaue 目標端(從 D:\dirdat\ 中,將 Trail文件變化 交給Java程序處理)

編輯配置

源端配置:一個管理服務、兩個抽取進程

ext1.prm

extract ext1
userid admin,password oracle
rmthost 127.0.0.1, mgrport 7909
rmttrail D:/ogg/dirdat/r1  

grouptransops 1
maxtransops 1
flushsecs 0
eofdelay 0

dynamicresolution
gettruncates
table admin.*;

ext2

extract ext2
userid admin,password oracle
rmthost 127.0.0.1, mgrport 7909
rmttrail D:/ogg/dirdat/r2 

grouptransops 1
maxtransops 1
flushsecs 0
eofdelay 0

dynamicresolution
gettruncates
table admin.*;

mgr.prm

PORT 7809 
DYNAMICPORTLIST 7840-7850
目標端配置:一個管理服務、一個同步進程

rep1.prm

replicat rep1
userid root,password oracle
assumetargetdefs
reperror default,discard

grouptransops 1
maxtransops 1

discardfile D:/ogg/dirdat/repsz.dsc,append
map admin.*, target root.*;

mgr.prm

PORT 7909 
DYNAMICPORTLIST 7940-7950
Javaue配置:一個管理服務、一個Javaue進程

javaue.prm

Extract JAVAUE
SetEnv (GGS_USEREXIT_CONF = "dirprm/javaue.properties")
SourceDefs dirprm/source.def

--getEnv (JAVA_HOME)
--getEnv (LD_LIBRARY_PATH_12)  --邊境變量 LD_LIBRARY_PATH_12 指向的是 D:\ogg\javaue12\ggjava\resources\lib
--getEnv (PATH)

CUserExit ggjava_ue.dll CUSEREXIT PassThru IncludeUpdateBefores
GetUpdateBefores

-- NoCompressDeletes
-- NoCompressUpdates


Table ADMIN.*;

javaue.properties

### java.naming.provider.url=tcp://localhost:61616
### java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory

gg.handlerlist=sample
gg.handler.sample.type=sample.SampleHandler
# com.goldengate.atg.datasource.handler.ConsoleHandler


goldengate.userexit.timestamp=utc
goldengate.userexit.nochkpt=true
goldengate.userexit.writers=javawriter


goldengate.log.logname=cuserexit
goldengate.log.level=INFO
goldengate.log.tofile=true


javawriter.stats.display=TRUE
javawriter.stats.full=TRUE

# javaue.prm 我們之所以注釋掉了 getEnv (LD_LIBRARY_PATH_12) 是因為:我們手動把路徑配置在了下面代碼中
javawriter.bootoptions=-Djava.class.path=.;dirprm;ggjava/resources/classes;ggjava/resources/lib;ggjava/ggjava.jar;dirprm/fastjson-1.2.7.jar;dirprm/custom.jar -Dlog4j.configuration=log4j.properties
mgr.prm
PORT 7509 
DYNAMICPORTLIST 7540-7550
生成 source.def 文件(Javaue 運行需要)

在 D:\Temp\創建一個 source.prm 文件

D:\Temp\source.prm

defsfile D:\Temp\source.def, purge
userid admin,password oracle
table admin.*;

運行命令行:

用Eclipse 編寫Java插件:

打開 Eclipse 新建“Java項目”custom12,新建一個包 sample,新建一個類 SampleHandler.java 將如下代碼 復制到 SampleHandler.java 中

package sample;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

//這是 OGG 11 的 import 
//import com.goldengate.atg.datasource.AbstractHandler;
//import com.goldengate.atg.datasource.DsConfiguration;
//import com.goldengate.atg.datasource.DsEvent;
//import com.goldengate.atg.datasource.GGDataSource.Status;
//import com.goldengate.atg.datasource.handler.*;
//import com.goldengate.atg.datasource.meta.DsMetaData;
//import com.goldengate.atg.datasource.test.DsTestUtils.Logger;
//import com.goldengate.atg.datasource.meta.*;
//import com.goldengate.atg.datasource.*;

//這是 OGG 12 的 import 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oracle.goldengate.datasource.AbstractHandler;
import oracle.goldengate.datasource.DsColumn;
import oracle.goldengate.datasource.DsConfiguration;
import oracle.goldengate.datasource.DsEvent;
import oracle.goldengate.datasource.DsOperation;
import oracle.goldengate.datasource.DsOperation.OpType;
import oracle.goldengate.datasource.DsTransaction;
import oracle.goldengate.datasource.GGTranID;
import oracle.goldengate.datasource.meta.ColumnMetaData;
import oracle.goldengate.datasource.meta.DsMetaData;
import oracle.goldengate.datasource.meta.TableMetaData;
import oracle.goldengate.datasource.meta.TableName;
import oracle.goldengate.datasource.GGDataSource.Status;



public class SampleHandler extends AbstractHandler {    
    //OGG 11 和 OGG 12 的 日志好像不一樣, OGG 12 似乎要寫 LoggerFactory.getLogger(SampleHandler.class);
    //private final Logger logger = Log4jLogger.getLogger(SampleHandler.class);
    private final Logger logger = LoggerFactory.getLogger(SampleHandler.class);


    @Override
    public void init(DsConfiguration conf, DsMetaData metaData) {
        super.init(conf,  metaData);
        logger.info("init!");
        WriteStringToFile("D:\\SampleHandler.log", "SampleHandler.init(*)");
    }
    @Override
    public Status transactionCommit(DsEvent e, DsTransaction tx) {


//      DsMetaData meta = e.getMetaData();
//      //System.out.println(meta);
//      
//      Set<TableName> tableNames = meta.getTableNames();
//      for(TableName tableName : tableNames){
//          String tableStr = "";
//          tableStr = tableStr + tableName+" : ";
//
//          TableMetaData metaData = meta.getTableMetaData(tableName);
//          ArrayList<ColumnMetaData> columns = metaData.getColumnMetaData();
//          for(ColumnMetaData column : columns){               
//              tableStr = tableStr + "\r\n   " + column.getColumnName() + " | "+column.getDataType().toString();
//          }
//          
//          System.out.println(tableStr+"\r\n");            
//          //System.out.println(metaData);
//      }
//      
//        //GGTranID tranId = e.getTargetCheckpointInfo();
//        //System.out.println(tranId);
//      
//      System.out.println(tx.getSize());
//      System.out.println(tx.getTotalOps());
//      System.out.println(tx.getReadTime());
//      System.out.println(tx.getTransactionBeginTime());
//      
//      
//      Object eventSource = e.getEventSource();
//      System.out.println(eventSource);
//      
//      DsOperation lastOp = tx.getLastOperation();
//      System.out.println(lastOp);
//      
//      
//      List<DsOperation> listOp = tx.getOperations();
//      System.out.println(listOp.size());
//      //System.out.println(listOp.get(0).getColumn(0).getBeforeValue());
//      for(DsOperation op : listOp){
//          System.out.println(op.getTableName());
//      }




        Status  superResult = super.transactionCommit(e, tx);
        logger.info("transactionCommit!");
        WriteStringToFile("D:\\SampleHandler.log", "SampleHandler.transactionCommit(*) => "+superResult); 
        return superResult;
    }

    @Override
    public Status operationAdded(DsEvent e, DsTransaction tx, DsOperation dsOperation) {

        DsMetaData meta = e.getMetaData();
        //System.out.println(meta);

//      Set<TableName> tableNames = meta.getTableNames();
//      for(TableName tableName : tableNames){
//          String tableStr = "";
//          tableStr = tableStr + tableName+" : ";
//
//          TableMetaData metaData = meta.getTableMetaData(tableName);
//          ArrayList<ColumnMetaData> columns = metaData.getColumnMetaData();
//          for(ColumnMetaData column : columns){               
//              tableStr = tableStr + "\r\n   " + column.getColumnName() + " | "+column.getDataType().toString();
//          }
//          
//          System.out.println(tableStr+"\r\n");            
//          //System.out.println(metaData);
//      }

        System.out.println("---------------------------------------");

        OpType opType = dsOperation.getOperationType();
        System.out.println(opType);

        TableName tableName = dsOperation.getTableName();
        System.out.println(tableName.getFullName());

        TableMetaData metaData = meta.getTableMetaData(tableName);
        ArrayList<ColumnMetaData> columnMetas = metaData.getColumnMetaData();
        List<DsColumn> columns = dsOperation.getColumns();
        for(int i=0; i<columnMetas.size(); i++){                
            ColumnMetaData columnMeta = columnMetas.get(i);
            DsColumn column = columns.get(i);
            System.out.println("    " + columnMeta.getColumnName() + "\t | \t"+ column.getAfterValue() + (column.isChanged()? "\t >>> \t" +column.getAfterValue():""));
        }

        System.out.println("---------------------------------------");


        Status superResult = super.operationAdded(e, tx, dsOperation);
        logger.info("operationAdded!");
        WriteStringToFile("D:\\SampleHandler.log", "SampleHandler.operationAdded(*) => "+superResult); 
        return superResult;
    }

    //@Override  
    //public DataSourceListener.State   getState() {
    //  return super.getState();
    //}

    @Override
    public void destroy() {
        super.destroy();
        WriteStringToFile("D:\\SampleHandler.log", "SampleHandler.destroy(*)"); 
        logger.info("destroy!");
    }
    @Override
    public String reportStatus() {
        String superResult = "OK"; //super.reportStatus(); 調用父類函數,程序就會崩潰。
        WriteStringToFile("D:\\SampleHandler.log", "SampleHandler.reportStatus(*) => "+superResult);
        return superResult;
        //return "status report...===";
    }  




    public static void WriteStringToFile(String filePath, String text) {   
        try {     
            System.out.println("AAAAAAAAAAAAAAAAA :" + text); 
            FileWriter writer = new FileWriter(filePath, true);     
            writer.write("\r\n"+text);       
            writer.close();     
        } catch (IOException e) {     
            //e.printStackTrace();  
            System.out.println(e.getMessage()); 
        } 
    }     

}

*下面截圖的包名 sample 錯寫成了 simple *

添加外部jar包引用,具體包括

ggjava\ggjava.jar

ggjava\resources\lib 目錄下的全部 jar 包

至此,OGG整個配置環節,需要准備的 文件都已經准備完成,接下來准備啟動 OGG。

啟動源端OGG:

啟動源端OGG:

進入 D:\ogg\s\ 目錄,雙擊 ggsci.exe,運行如下命令

> create subdirs

> dblogin userid admin,password oracle

> add trandata admin.*

> add extract ext1, tranlog, begin now

> add rmttrail D:/ogg/dirdat/r1 extract ext1

> add extract ext2, tranlog, begin now

> add rmttrail D:/ogg/dirdat/r2 extract ext2

> start mgr

> start ext1

> start ext2

啟動目標端OGG:

進入 D:\ogg\t\ 目錄,雙擊 ggsci.exe,運行如下命令

> create subdirs

> add replicat rep1 exttrail D:/ogg/dirdat/r1, nodbcheckpoint

> start mgr

> start rep1

驗證 源端>目標端 的同步:

如果 ext1 ext2 因為 rep1 沒有啟動而自動停止,則需要 重新啟動一次 源端的 ext1 ext2

我們向 ADMIN.TBTEST 插入一行記錄,理論上 ROOT.TBTEST 也會對應的 同步一行記錄

啟動OGG Javaue:

進入 D:\ogg\javaue12\ 目錄,雙擊 ggsci.exe,運行如下命令

最后的話:

至此:OGG(Oracle GoldenGate)同步配置 和 Adaper Java 程序適配 已經全部完成。

建議:嚴格按照上面的步驟,所有名稱 都盡量不要變化 —— 先把第一次 全部跑通。

等全部跑通后,你再試着修改 其中的 各個部分的名稱 —— 對照 prm 文件配置,試着理解 OGG配置原理。

 

如果配置過程中,出現任何詭異BUG,

歡迎參考

__Win7 配置 Oracle GoldenGate 踩坑指南》 和 《__Win7 配置 Oracle GoldenGate Adapter Java 踩坑指南》 兩篇踩坑文章。

—— 事實上,OGG配置的坑很多,總有一款適合你,兩篇《踩坑指南》 你逃不掉的。

 

舒小龍 2018-06-04


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM