本文主要是向讀者介紹如何通過 ogg 為 oracle 數據庫的變更操作實時同步到大數據產品 kafka 上。
開始介紹前,先為讀者介紹一下環境背景
- 機器ip 和其對應的服務
192.168.88.166【ogg目標端】【ogg的mgr(端口1357), rep_test】
192.168.88.128【ogg源端】 【oracle, ogg的mgr(端口9001), ext_test, dpe_test, zookeeper, kafka】
- 軟件版本
oracle 版本,11g release 2
kafka 版本,2.11-0.10.1.0
zookeeper 版本, 3.3.6
ogg源端JVM 版本, 1.7
ogg目標端JVM 版本,1.8 (必須1.8 以上,否者ogg無法啟動)
ogg 因為下載時沒有留意版本,所以直接貼文件名,應該能夠對應版本
ogg 源端安裝包文件名,123010_fbo_ggs_Linux_x64_shiphome,文件大小:543200432
ogg 目標端安裝包文件名,123110_ggs_Adapters_Linux_x64,文件大小:81812011
開始介紹部署與配置步驟。
使用system用戶登陸oracle 的sqlplus
sqlplus "system/oracle" as sysdba
- 首先檢查oracle 是否已經開啟 Archive logging
archive log list;
如果顯示以下錯誤,則證明沒有開啟
ORA-01031: insufficient privileges
用戶可以使用以下命令查看oracle 是否已經開啟了 自動歸檔模式
select name,log_mode from v$database;
LOG_MODE 顯示 NOARCHIVELOG 則代表沒有開啟
開啟 Archive logging ,需要先停止數據庫,執行以下命令
shutdown immediate;
然后將數據庫啟動到 mount 狀態
startup mount
更改歸檔模式,啟動 日志自動歸檔
ALTER DATABASE ARCHIVELOG;
以下一篇博客對oracle 啟動和停止數據庫的狀態介紹得非常清楚,大家可以參考一下
http://blog.csdn.net/lutinghuan/article/details/7484062
這個使用如果用戶想了解日志歸檔是否真的已經開啟,以及查看歸檔日志存儲在什么路徑,可以再次執行
archive log list
例如作者機器就是顯示
Database log mode Archive Mode Automatic archival Enabled Archive destination /home/oracle/app/oracle/product/11.2.0/dbhome_1/dbs/arch Oldest online log sequence 51 Next log sequence to archive 53 Current log sequence 53
如果用戶希望修改歸檔日志的存儲路徑,可以執行以下命令
alter system set log_archive_dest='用戶希望的路徑,但是需要oracle程序可以讀寫'
修改好之后,就是重新打開oracle 的 database
alter database open
在shell中用戶需要先創建好日志歸檔目錄,例如作者的歸檔目錄為 /home/oracle/app/oracle/product/11.2.0/dbhome_1/dbs/arch,則該目錄需要預先創建
mkdir -p /home/oracle/app/oracle/product/11.2.0/dbhome_1/dbs/arch
測試歸檔
alter system switch logfile
然后用戶可以在 /home/oracle/app/oracle/product/11.2.0/dbhome_1/dbs/arch 目錄下看到新的歸檔日志。
用戶也可以使用sql 命令查看歸檔情況,但是作者沒有仔細查看這個輸出
select * from v$archived_log
到這里,oracle 如何開啟日志自動歸檔的方法就介紹完畢了。
- 檢查是否開啟forcelogging和 minimal supplemental logging
注意:如果不指定Primary key 和unique 屬性,OGG將不會傳送PK字段或Unique indiex字段信息。這樣,下游的應用,在處理update數據時將失去依據
SELECT supplemental_log_data_min,force_logging FROM v$database;
像作者的環境就沒有開啟(屏幕輸出NO),所以我們還需要執行開啟命令,執行完畢后,我們再來查看 forcelogging和 minimal supplemental logging 的開啟情況
alter database add supplemental log data (primary key) columns; alter database add supplemental log data (unique) columns; alter database force logging; alter system switch logfile;
檢查開啟情況,顯示如下則代表ok
SUPPLEME FOR -------- --- IMPLICIT YES
在oracle 中開啟 enable_goldengate_replication 參數
alter system set ENABLE_GOLDENGATE_REPLICATION=true;
- 創建 ogg 用戶
創建OGG 用戶,用戶名為ogg,密碼也為ogg
create user ogg identified by ogg; grant connect,resource to ogg; grant select any dictionary to ogg; grant select any table to ogg;
- 在Oracle 源端部署OGG 服務
作者的Oracle 服務部署在 oracle 系統用戶下,所以打算 ogg 也同樣部署在 oracle 用戶下,相關的用戶和路徑可以參考:http://www.cnblogs.com/chenfool/p/7411626.html
創建 ogg 目錄
/home/oracle/ogg
將 ogg 軟件拷貝到 /home/oracle/ogg 目錄下,並且解壓
cp /mnt/hgfs/mnt/orace_ogg/123010_fbo_ggs_Linux_x64_shiphome.zip /home/oracle/ogg
unzip 123010_fbo_ggs_Linux_x64_shiphome.zip
修改ogg 的配置文件 /home/oracle/ogg/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp, 注意:作者設置環境變量的文件 ~/.bash_profile 已經設置好了 ORACLE_HOME 變量,詳細可以查看:http://www.cnblogs.com/chenfool/p/7411626.html
INSTALL_OPTION=ORA11g SOFTWARE_LOCATION=/home/oracle/oggapp START_MANAGER=false MANAGER_PORT=9001 DATABASE_LOCATION=${ORACLE_HOME}
運行安裝 OGG 程序
cd /home/oracle/ogg/fbo_ggs_Linux_x64_shiphome/Disk1
./runInstaller -silent -responseFile /home/oracle/ogg/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp
修改oracle 用戶的配置文件 ~/.bash_profile,主要是增加OGG_HOME 內容
export ORACLE_BASE=/home/oracle/app export ORACLE_HOME=${ORACLE_BASE}/oracle/product/11.2.0/dbhome_1 export ORACLE_HOME_LISTNER=${ORACLE_HOME} export OGG_HOME=/home/oracle/oggapp export ORACLE_SID=orcl export PATH=${PATH}:${ORACLE_HOME}/bin:${OGG_HOME} export LD_LIBRARY_PATH=${ORACLE_HOME}/lib:/usr/lib:${OGG_HOME} export DISPLAY=:0.0
登陸 ogg 控制台
cd /home/oracle/oggapp
./ggsci
給ogg 創建目錄,注意:此操作是在 ggsci 中執行
create subdirs
作者執行后,屏幕輸出
Parameter file /home/oracle/oggapp/dirprm: created. Report file /home/oracle/oggapp/dirrpt: created. Checkpoint file /home/oracle/oggapp/dirchk: created. Process status files /home/oracle/oggapp/dirpcs: created. SQL script files /home/oracle/oggapp/dirsql: created. Database definitions files /home/oracle/oggapp/dirdef: created. Extract data files /home/oracle/oggapp/dirdat: created. Temporary files /home/oracle/oggapp/dirtmp: created. Credential store files /home/oracle/oggapp/dircrd: created. Masterkey wallet files /home/oracle/oggapp/dirwlt: created. Dump files /home/oracle/oggapp/dirdmp: created.
配置源端manager進程,注意:此操作是在 ggsci 中執行
edit params mgr
然后操作會調到 VI 上,用戶再輸入以下內容后保存退出
port 9001 autostart er * autorestart er *
啟動 manager ,注意:此操作是在 ggsci 中執行
start mgr
查看manager 的狀態,可以看到 MANAGER 為RUNNING,注意:此操作是在 ggsci 中執行
info all
編輯ext_test服務,該服務是專門用來抽取oracle 新增日志的進程,注意:此操作是在 ggsci 中執行
edit params ext_test
然后操作會調到 VI 上,用戶再輸入以下內容后保存退出
EXTRACT ext_test Setenv (NLS_LANG="AMERICAN_AMERICA.UTF8") USERID ogg, PASSWORD ogg gettruncates DISCARDFILE ./dirrpt/ext_test.dsc, APPEND, MEGABYTES 1024 DBOPTIONS ALLOWUNUSEDCOLUMN REPORTCOUNT EVERY 1 MINUTES, RATE FETCHOPTIONS NOUSESNAPSHOT TRANLOGOPTIONS DBLOGREADER EXTTRAIL ./dirdat/ex WILDCARDRESOLVE DYNAMIC GETUPDATEBEFORES NOCOMPRESSUPDATES NOCOMPRESSDELETES dynamicresolution table scott.test;
然后執行命令創建ext_test 的服務,並且指定將抽取到的日志存放在 ./dirdat/ 目錄下,並且文件名以ex 開頭,注意:此操作是在 ggsci 中執行
add extract ext_test, TRANLOG, BEGIN NOW ADD EXTTRAIL ./dirdat/ex , EXTRACT ext_test, MEGABYTES 200
注意,指定的目錄末尾一定只能是兩個字符,否則報錯如下
file portion must be two characters.
啟動該日志抽取服務,注意:此操作是在 ggsci 中執行
start ext_test
日志抽取部分的配置就ok了,下面開始配置日志發送的服務dpe_test
同樣的先編輯服務的配置
edit param dpe_test
然后界面會進入VI 模式,在文件上填寫以下內容后保存退出,同樣的dirdat 路徑下的文件名只能夠用兩個字符,否則會報告錯誤
EXTRACT dpe_test PASSTHRU RMTHOST 192.168.88.162, MGRPORT 1357 RMTTRAIL ./dirdat/re TABLE scott.test;
這里必須要和大家介紹一下,因為作者在這里卡了很久。
第一,RMTHOST 這個IP 地址,是遠端接收日志的服務的IP地址
第二,MGRPORT 端口是遠端接收日志的MGR 服務端口,這里千萬不要搞混淆了。
第三,RMTTAIL 這個是遠端接收日志的路徑,並非本機的,即是在 88.162 機器上的dirdata 目錄上的存放接收到的日志路徑
后面的步驟就是,將ext_test 抽取到的日志存放路徑 配置給 dpe_test 發送日志服務,注意:此操作是在 ggsci 中執行
ADD EXTRACT dpe_test, EXTTRAILSOURCE ./dirdat/ex ADD RMTTRAIL ./dirdat/re, EXTRACT dpe_test, MEGABYTES 200
大家注意,紅色字體是ext_test 的路徑,綠色字體是發送到遠端服務的路徑
配置好dpe_test 服務后,還不能夠立馬啟動,因為遠端接收的MGR 服務還沒有起來,所以這塊還遺留一個小尾巴
- 部署目標端的ogg
在目標端機器(192.168.88.162)上事先創建oracle:oracle 用戶組和用戶
groupadd oracle useradd -s /bin/bash -m -g oracle oracle passwd oracle
切換oracle 用戶,為ogg adapter 創建目錄
mkdir /home/oracle/ogg_adapter
拷貝ogg adapter 壓縮包,並且解壓
cp /mnt/hgfs/mnt/orace_ogg/123110_ggs_Adapters_Linux_x64.zip /home/oracle/ogg_adapter ; unzip 123110_ggs_Adapters_Linux_x64.zip
將解壓的 ogg_adapter/ggs_Adapters_Linux_x64.tar 文件拷貝到 /home/oracle/ogg 目錄(如果不存在此目錄,請事先創建)
cp ogg_adapter/ggs_Adapters_Linux_x64.tar /home/oracle/ogg
在 /home/oracle/ogg 目錄下解壓 ggs_Adapters_Linux_x64.tar.gz 文件
tar xvf ggs_Adapters_Linux_x64.tar.gz
為oracle 用戶設置JDK 和 ogg 的環境變量
export JAVA_HOME=/opt/jdk1.8.0_144 export CLASSPATH=${JAVA_HOME}/lib/tools.jar:${JAVA_HOME}/lib/dt.jar export PATH=${JAVA_HOME}/bin:${PATH} export OGG_HOME=/home/oracle/oggapp export PATH=$PATH:$OGG_HOME export LD_LIBRARY_PATH=$OGG_HOME:$JAVA_HOME/jre/lib/amd64/libjsig.so:$JAVA_HOME/jre/lib/amd64/server/libjvm.so:$JAVA_HOME/jre/lib/amd64/server:$JAVA_HOME/jre/lib/amd64
如果不設置JDK的LD_LIBRARY_PATH環境變量,會在啟動后面的rep_test 服務時,報錯
ERROR OGG-15050 Error loading Java VM runtime library
用戶也要注意 /etc/hosts 的設置,一定需要將機器的hostname 和 IP 地址配置好映射關系,否者也會出現錯誤
ERROR OGG-15161 Could not initialize the connection with MGR MGR (No route to host).
如果用戶出現此錯誤,需要先重啟目標端的mgr 服務,直接在 ggsci 命令窗口執行 stop mgr 命令是不能夠停止mgr 服務的,還需要用戶在shell 中通過 kill -15 PID 的方法停止mgr。
用戶正確修改 /etc/hosts 配置文件后,再重啟 目標端的 mgr 和 rep_test 服務,然后需要 重新啟動 源端 的 dpe_test 服務,因為目標段的 mgr 服務一旦停止, dpe_test 就可能出現異常。
拷貝模板文件
cp /home/oracle/ogg/AdapterExamples/big-data/kafka/* /home/oracle/ogg/dirprm/
啟動 ggsci 控制程序
/home/oracle/ogg/ggsci
創建目錄,注意:此操作是在 ggsci 中執行
create subdirs
配置源端manager進程,注意:此操作是在 ggsci 中執行
edit params mgr
然后出現VI 界面,輸入以下內容后保存退出
port 1357 autostart er * autorestart er *
讀者們注意了,在目標段的MGR 配置中,端口號設置是需要和 源端的 dpe_test 配合的,這個讀者注意。
啟動manager 進程,並且確認,注意:此操作是在 ggsci 中執行
start mgr
確認命令,如果正常運行,則顯示 MANAGER RUNNING ,注意:此操作是在 ggsci 中執行
info all
修改接收服務配置,注意:此操作是在 ggsci 中執行
edit params rep_test
修改內容如下
REPLICAT rep_test TARGETDB LIBFILE libggjava.so SET property=dirprm/kafka.props GETTRUNCATES SOURCEDEFS dirdef/source.def REPORTCOUNT EVERY 1 MINUTES, RATE GROUPTRANSOPS 10000 MAP scott.*, TARGET scott.*;
dirprm/kafka.props 是kafka 的配置文件,下面會介紹到
dirdef/source.def 是源端的表結構定義文件,這個暫時還沒有介紹到,等一下會介紹。
然后就是添加rep_test 該服務,並且指定 dirdat/re 路徑作為 rep_test 服務的日志來源,讀者可以留意一下,dirdat/re 路徑,實際上就是遠端dpe_test 指定的路徑。
因為rep_test 的服務作用就是將 日志文件解析,然后再做相應的處理,例如本例子就是將解析后的日志發送到kafka 上
為 ogg 增加rep_test 服務,注意:此操作是在 ggsci 中執行
add replicat rep_test, exttrail ./dirdat/re
修改/home/oracle/ogg/dirprm/kafka.props,主要修改以下內容
gg.handlerlist = kafkahandler
gg.handler.kafkahandler.type=kafka
gg.handler.kafkahandler.TopicMappingTemplate=chentest
#gg.handler.kafkahandler.TopicName=chentest
gg.handler.kafkahandler.KafkaProducerConfigFile=./dirprm/custom_kafka_producer.properties
gg.handler.kafkahandler.format=json
gg.handler.kafkahandler.BlockingSend =false
gg.handler.kafkahandler.includeTokens=false
gg.handler.kafkahandler.mode=tx
goldengate.userexit.timestamp=utc
goldengate.userexit.writers=javawriter
javawriter.stats.display=TRUE
javawriter.stats.full=TRUE
gg.log=log4j
gg.log.level=INFO
gg.report.time=30sec
#Sample gg.classpath for Apache Kafka
gg.classpath=dirprm/:/home/oracle/ogg/ggjava/resources/lib/*:/home/oracle/kafka_lib/*
#Sample gg.classpath for HDP
javawriter.bootoptions=-Xmx512m -Xms32m -Djava.class.path=ggjava/ggjava.jar
這里有幾點需要讀者們注意的。
1 gg.handler.kafkahandler.format 參數需要填寫 json ,如果填寫text 或者其他,會由於源端oracle 中執行update sql 命令,從而導致 日志解析失敗,因為text 無法表示出修改記錄的形式
2 gg.handler.kafkahandler.mode 參數填寫 tx,表示解析后的日志是可讀的
3 gg.classpath 參數重點需要填寫兩個路徑,分別是 ogg for kafka 的驅動路徑,另外一個是kafka 產品的lib 驅動路徑(該路徑讀者可以在KAFKA_HOME 目錄下尋找,直接拷貝過來即可)
4 kafka 中的topicName 要使用 gg.handler.kafkahandler.TopicMappingTemplate 參數,而不能夠使用gg.handler.kafkahandler.TopicName 參數(ogg 的kafka 模版中的參數竟然是錯誤的,簡直令人發指),否者rep_test 進程將啟動失敗。
修改連接kafka 的配置
vi /home/oracle/ogg/dirprm/custom_kafka_producer.properties
主要修改內容,在作者的測試中,並沒有選擇開啟gzip 壓縮模式,所以不知道該參數是否生效(反正我看到有文章說該參數會導致ogg 起不來)。
bootstrap.servers 參數是指定 用戶已經部署好的 kafka 連接ip和端口
bootstrap.servers=192.168.88.128:9092
rep_test 的服務配置已經基本完了,但是 源端表結構的配置還沒有開始做,所以也暫時對 rep_test 服務留一個小尾巴。
- 源端表結構文件初始化
請讀者回到 源端 的ggsci 客戶端的交互命令窗口上來,執行以下命令,創建一個新的初始化源端表結構的配置文件,注意:此操作是在 ggsci 中執行
edit param defgen
此時界面會跳轉到VI界面上,用戶直接在上面編輯以下內容。
userid 和 password 參數是 oracle 數據庫中的用戶名和密碼登錄方式
table 參數就是需要初始化的表名
DEFSFILE dirdef/source.def, PURGE
USERID ogg, PASSWORD ogg
TABLE scott.test ;
然后用戶在 linux shell 窗口下執行以下命令(源端執行shell 命令)
defgen paramfile dirprm/defgen.prm
然后把在源端新生成的 dirdef/source.def 文件scp 到 目標端 的 dirdef/source.def
- 將遺留的尾巴收割
我們首先來啟動rep_test 服務(目標端的ggsci 執行),注意:此操作是在 ggsci 中執行
start rep_test
再來啟動 dpe_test 服務(源端的ggsci 執行),注意:此操作是在 ggsci 中執行
start dpe_test
用戶也可以分別在源端和目標端的 ggsci 中查看rep_test 和 dpe_test 服務的啟動狀態
info all
- 零散的技巧點
《一》、如果用戶希望查看 ext_test 、dpe_test 和 rep_test 服務的啟動日志,可以在各自機器ogg 的dirrpt 目錄下查看對應服務的啟動日志
《二》、如果rep_test服務發生錯誤,並且dirrpt/REP_TEST_info_log4j.log 日志錯誤如下:
ERROR 2017-09-05 18:30:26,628 [main] A failure occurred sending a message to Kafka. org.apache.kafka.common.errors.RecordTooLargeException: The message is 6839357 bytes when serialized which is larger than the maximum request size you have configured with the max.request.size configuration. WARN 2017-09-05 18:30:26,630 [main] Error sending event to listener kafkahandler, status: ABEND, event: Commit transaction
那么用戶可以在 dirprm/custom_kafka_producer.properties 配置文件中增加一行配置,該配置可以避免rep_test 向kafka 發送消息時,由於消息過大而報錯
max.request.size=???
該錯誤解決方法來源於博客:http://www.ateam-oracle.com/oracle-goldengate-big-data-adapter-apache-kafka-producer/
《三》、如果遇到字符集問題,應該明白,設置數據同步的字符集應該以目標端的字符集為准,詳細可以參考以下博客:
http://blog.163.com/myy10146@126/blog/static/11355718620134175728388/
同時,這里記錄一下GBK和UTF8 的寫法
AMERICAN_AMERICA.ZHS16GBK
AMERICAN_AMERICA.AL32UTF8
《四》、在啟動ext_test服務時,如果遇到以下錯誤
ERROR OGG-00446 No valid log files for current redo sequence 367, thread 1, error retrieving redo file name for sequence 367, archived = 0, use_alternate = 0Not able to establish initial position for begin time 2013-03-27 15:32:46. ERROR OGG-01668 PROCESS ABENDING.
則為 ext_test 服務的配置文件增加一行配置
TRANLOGOPTIONS DBLOGREADER
《五》、刪除ext_test 、 dpe_test 、 rep_test 服務的方法,主要是作者對於ogg 的配置不熟悉,如果環境出現了進城無法啟動,則可以通過刪除服務然后重新配置
delete extract dpe_test
delete extract ext_test
delete replicat rep_test
用戶如果刪除服務后,一定要記得將 dirdat/ex* 和 dirdat/re* 的相關文件刪除,否者會在后面增加服務時出錯。
刪除服務不會刪除原有服務的配置文件,所以后面重新增加服務就比較簡單,執行以下命令即可,當然這些命令就是上面配置的添加命令
add extract ext_test , tranlog , begin now add exttrail ./dirdat/ex , extract ext_test , megabytes 200 add extract dpe_test , exttrailsource ./dirdat/ex add rmttrail ./dirdat/re, extract dpe_test, megabytes 200 add replicat rep_test , exttrail ./dirdat/re
《六》 目標端和源端的hostname 一定要不一樣,否則在啟動 rep_test 時會由於無法連接kafka 而報錯,並且應該將目標端和源端的IP 地址和 hostname 都正確配置在 /etc/hosts 文件中
《七》 用戶想支持truncate 功能,則還需要在 ext_test 和 rep_test 的配置文件上增加以下參數,如果不想要該信息,則可以移除該參數
GETTRUNCATES
《八》如果用戶在同步源端數據時,只希望同步部分列字段值,可以在ext_test 服務配置文件上做標識,例如test 表的表結構為 name varchar(10), id int,如果用戶不想同步id 字段值,可以填寫如下配置,紅色部分關鍵字代表不同步的列
EXTRACT ext_test Setenv (NLS_LANG="AMERICAN_AMERICA.UTF8") USERID ogg, PASSWORD ogg gettruncates DISCARDFILE ./dirrpt/ext_test.dsc, APPEND, MEGABYTES 1024 DBOPTIONS ALLOWUNUSEDCOLUMN REPORTCOUNT EVERY 1 MINUTES, RATE FETCHOPTIONS NOUSESNAPSHOT EXTTRAIL ./dirdat/ex WILDCARDRESOLVE DYNAMIC GETUPDATEBEFORES NOCOMPRESSUPDATES NOCOMPRESSDELETES dynamicresolution table ogg.test, colsexcept(id);
參考博客:
http://blog.csdn.net/warren_zqw/article/details/52894586
http://guojuanjun.blog.51cto.com/277646/295454/
http://www.cnblogs.com/soysauce/p/7411314.html
http://blog.csdn.net/shipeng1022/article/details/50720690
http://www.qiuyb.com/archives/436