天天看點

Oracle實時資料抽取項目問題總結Oracle實時資料抽取項目問題總結

Oracle實時資料抽取項目問題總結

項目背景介紹

項目主要是将Oracle、MySQL、SQLServer、Db2等其他資料庫的實時變更資料同步到其他異構資料庫中。本篇文章主要是讨論oracle的實時采集,通過Logminer捕獲歸檔日志,然後将提取後的資料推送到Kafka中。

項目使用的技術架構

使用的核心架構:https://github.com/debezium/debezium 用于捕獲歸檔日志,然後推送到kafka中。

Debezium架構是基于Kafka Connect實作的,分為source端和sink端。

source: 負責将源庫的資料放入kafka中;

sink: 負責将kafka的資料落入目标庫中;

source和sink的排程管理統一交給kafka connect來負責。

如何擷取歸檔日志

Debezium實作的Oracle source端,将資料同步到kafka中,有Logminer和XStream兩種實作方式,其中Logminer是oracle資料庫自帶的,不需要額外收費;而XStream需要額外收費的。是以,今天主要介紹的是Logminer的方式擷取歸檔日志。

Logminer擷取歸檔日志的步驟

這裡隻介紹一個大概的步驟,具體詳細步驟請參考Oracle官方文檔,裡面有比較詳細的步驟。

  1. 首先需要開啟oracle資料庫歸檔日志;
  2. 使用Logminer程式

    DBMS_LOGMNR.ADD_LOGFILE

    增加需要采集的日志,這一步很重要,也是今天問題的核心。
  3. 調用開始采集

    DBMS_LOGMNR.START_LOGMNR

    程式;
  4. 查詢

    V$LOGMNR_CONTENTS

    視圖,進而擷取歸檔檔案中的資料;
  5. 調用

    DBMS_LOGMNR.END_LOGMNR

    程式結束.

Oracle歸檔日志和重做日志

因為實時資料采集主要是作用在歸檔日志和重做日志上,如果對這兩種日志不了解,将導緻Logminer出現的錯誤無法有一個清晰的認知,進而無法解決現場實際面臨的各種問題。

重做日志

也被稱為redo log,主要是用來進行資料庫恢複的,你對資料庫表的任何資料操作,都會首先将變更寫入重做日志中,用來在資料庫當機時能及時恢複資料,裡面記錄了資料的詳細變更記錄。預設資料庫會有3個重做日志檔案,可以通過查詢V$LOGFILE擷取。這3個重做日志檔案是輪流使用的,當第一個用滿後将切換到第二個、當第二個用滿之後切換到第三個,當第三個用滿之後切換到第一個,切換之後目标重做日志就被覆寫了,也就是丢失了。例如當第一個用滿後将切換到第二個,那麼原來第二個重做日志上的資料就丢失了。當然,這個重做日志的檔案大小和個數都是可以配置的。

特點:及時寫入,自動循環覆寫

歸檔日志

歸檔日志主要是重做日志的一個備份,也可以用來進行資料的恢複,也可以用來進行資料庫的同步。由于重做日志會循環使用,并且還會出現覆寫丢失的情況,是以,需要将重做日志放到别的地方進行備份存儲,這也就誕生了歸檔日志。歸檔日志預設是不開啟的,需要配置資料庫才能使用,并且需要占用許多存儲,是以需要及時的清理。重做日志會定時的存儲成歸檔日志,并且在切換的時候也會存儲到歸檔日志中,防止重做日志丢失。

特大:自動觸發寫入、可永久存儲

問題:ora-01291: missing logfile

有了Logminer和歸檔日志和重做日志的簡單介紹之後就可以進入今天的正題了,我們在實時抽取oracle歸檔日志的時候發現,當資料量很大的時候經常會出現oracle錯誤:ora-01291: missing logfile,提示找不到重做日志檔案了。

首先我們需要分析Logminer的第二步:DBMS_LOGMNR.ADD_LOGFILE,這一步不僅需要将歸檔日志添加到Logminer引擎中,還需要将重做日志也需要添加進來,因為歸檔日志的資料并不是及時的,需要配合歸檔日志 + 重做日志才能保證及時性,但是重做日志又有被覆寫的可能,是以就會出現ora-01291錯誤。了解了問題原因,那麼我們如何解決問題呢?既然隻有在資料量很大的時候才會出現,那麼我們可以将重做日志的個數增加到10個,每個檔案大小增加到5G。這個調整需要謹慎操作,官方的說法是最好将重做日志的切換時間控制在半小時左右。這樣就不會出現ora-01291的錯誤了,因為重做日志的切換頻率降低了、檔案個數也增加了。例如Logminer目前正在讀取重做日志5 + 歸檔日志,隻有當oracle此時立馬把 重做日志5,6,7,8,9,0,1,2,3,4,5(以10個重做日志為例)全部寫滿才會導緻重做日志5丢失,而此時每個記錄檔的大小為5G,總共需要寫入50G的資料,你不可能那麼快寫入50GB,當你寫入的時候Logminer已經讀取完了,是以就不會再出現找不到重做日志的問題了。

問題:日志定位耗時

當資料庫産生了大量歸檔日志的時候,Logminer需要定位到某一個表的起始SCN點很耗時。這個問題可以調整配置來實作,Debezium有大量的配置用來控制SCN點的增量範圍和每次擷取時間設定等,需要根據自身的場景進行合理調整。

配置名 預設值 描述

log.mining.batch.size.min

1000

The minimum SCN interval size that this connector attempts to read from redo/archive logs. Active batch size is also increased/decreased by this amount for tuning connector throughput when needed.

log.mining.batch.size.max

100000

The maximum SCN interval size that this connector uses when reading from redo/archive logs.

log.mining.batch.size.default

20000

The starting SCN interval size that the connector uses for reading data from redo/archive logs.

log.mining.sleep.time.min.ms

The minimum amount of time that the connector sleeps after reading data from redo/archive logs and before starting reading data again. Value is in milliseconds.

log.mining.sleep.time.max.ms

3000

The maximum amount of time that the connector ill sleeps after reading data from redo/archive logs and before starting reading data again. Value is in milliseconds.

log.mining.sleep.time.default.ms

1000

The starting amount of time that the connector sleeps after reading data from redo/archive logs and before starting reading data again. Value is in milliseconds.

log.mining.sleep.time.increment.ms

200

The maximum amount of time up or down that the connector uses to tune the optimal sleep time when reading data from logminer. Value is in milliseconds.

log.mining.view.fetch.size

10000

The number of content records that the connector fetches from the LogMiner content view.

log.mining.archive.log.hours

The number of hours in the past from SYSDATE to mine archive logs. When the default setting ( ) is used, the connector mines all archive logs.