溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么

發(fā)布時(shí)間:2021-12-20 09:36:08 來源:億速云 閱讀:195 作者:iii 欄目:數(shù)據(jù)庫(kù)

這篇文章主要講解了“DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么”吧!

一、感知表結(jié)構(gòu)變更

對(duì)于感知表結(jié)構(gòu)變更,Oracle已經(jīng)通過DDL trigger為我們提供了很好的支持,接下來我們要考慮的是如何讓DBus感知到表結(jié)構(gòu)變更? 我們討論出以下兩種方案:

1.1 RPC方案

在DDL trigger中調(diào)用DBus提供的REST服務(wù),將表結(jié)構(gòu)變更事件發(fā)送給DBus。

該方案思路簡(jiǎn)單容易實(shí)現(xiàn),但也有一些明顯的弊端,比如DBus需要提供高可用、低延時(shí)的REST服務(wù),否則可能會(huì)使數(shù)據(jù)庫(kù)中的DDL操作變得緩慢甚至執(zhí)行出現(xiàn)錯(cuò)誤; DBus 的REST服務(wù)器對(duì)有數(shù)據(jù)實(shí)時(shí)同步需求的所有數(shù)據(jù)庫(kù)都必須開通防火墻策略,這將給DBus的部署帶來很大的麻煩。

1.2 OGG實(shí)時(shí)同步方案

在DDL trigger中將表結(jié)構(gòu)變更事件存儲(chǔ)到一張Event表里,然后通過OGG實(shí)時(shí)的從日志中將數(shù)據(jù)同步到Kafka,從而感知表結(jié)構(gòu)變更事件。

該方案實(shí)現(xiàn)相對(duì)復(fù)雜但具有很多優(yōu)點(diǎn),比如對(duì)數(shù)據(jù)庫(kù)的侵入性相對(duì)較小,DDL執(zhí)行時(shí)只是將數(shù)據(jù)寫入到Event表中,相對(duì)網(wǎng)絡(luò)通信來說,其延時(shí)更低、可靠性更高;更明顯的優(yōu)勢(shì)是這種方案基于數(shù)據(jù)庫(kù)日志實(shí)現(xiàn),能夠使用Event表的數(shù)據(jù),嚴(yán)格的將表結(jié)構(gòu)變更前后的數(shù)據(jù)區(qū)分開。

舉例來說,對(duì)于表:test來說,依次執(zhí)行insert → alter → insert 三個(gè)操作,因?yàn)镺GG讀取數(shù)據(jù)庫(kù)日志存在延時(shí),如果利用RPC方案,可能出現(xiàn)這樣的一種情況:DBus REST服務(wù)接收到alter事件之后,第一個(gè)insert的記錄才被OGG捕獲并發(fā)送給DBus,此時(shí)DBus會(huì)認(rèn)為這條數(shù)據(jù)中包含alter變化后的數(shù)據(jù)。這是一個(gè)很嚴(yán)重的問題,而OGG實(shí)時(shí)同步方案無論數(shù)據(jù)還是時(shí)間均通過OGG讀取日志的方案實(shí)現(xiàn),可以完美的避免這種問題的發(fā)生。

對(duì)比兩種方案OGG實(shí)時(shí)同步方案優(yōu)勢(shì)明顯,最終我們采用此方案。

然而,采用這種方案也并非一帆風(fēng)順,按照該方案的總體思路實(shí)現(xiàn)以后,我們遇到了一個(gè)很奇怪的問題:通過DDL trigger寫到Event表中的數(shù)據(jù)無法被OGG讀取,在經(jīng)歷多番嘗試無解之后,我們?cè)噲D到OGG的文檔中尋找答案,而最終的結(jié)果卻是:DML or DDL operations performed from within a DDL trigger are not captured.

這個(gè)答案讓問題變得更棘手,但這是最佳方案,我們沒有理由放棄。于是我們開始嘗試在DDL trigger中調(diào)用存儲(chǔ)過程,在存儲(chǔ)過程中執(zhí)行Event表的insert操作,但由于存儲(chǔ)過程和DDL trigger仍然屬于同一個(gè)事務(wù),因此Event表的數(shù)據(jù)依然不能被OGG捕獲,但通過這個(gè)嘗試我們覺得只要在另外一個(gè)事務(wù)中寫Event表就能解決我們面臨的問題,于是我們又想到了RPC,但RPC缺點(diǎn)太過明顯。那么有沒有其他可以替代的方案呢?

實(shí)際上oracle數(shù)據(jù)庫(kù)里可以使用多種語言來編寫存儲(chǔ)過程,Oracle 8i開始支持java編寫存儲(chǔ)過程,于是我們立即開始實(shí)現(xiàn)java存儲(chǔ)過程,通過JDBC連接數(shù)據(jù)庫(kù)實(shí)現(xiàn)Event表的寫入并提交事務(wù),最終通過實(shí)踐驗(yàn)證了這種辦法的可行性,OGG成功的獲取到了DDL trigger調(diào)用java存儲(chǔ)過程寫入到Event表的數(shù)據(jù)。

然而,這種實(shí)現(xiàn)并不算完美。當(dāng)我們?cè)谏a(chǎn)環(huán)境部署DDL trigger的時(shí)候,發(fā)現(xiàn)數(shù)據(jù)庫(kù)服務(wù)器中并沒有安裝執(zhí)行java所需要的組件,每次部署都需要DBA同學(xué)安裝執(zhí)行java存儲(chǔ)過程所需要的組件,我們?cè)噲D找到一個(gè)不使用java存儲(chǔ)過程的方案。這里要感謝韓鋒老師對(duì)我們的幫助,韓老師在聽了我 們的實(shí)現(xiàn)原理之后,啟發(fā)我們自治事務(wù)應(yīng)該可以解決這個(gè)問題,我們即刻動(dòng)手開始改造DDL trigger,使之支持自治事務(wù),經(jīng)過改造之后該方案才算完美,最終實(shí)現(xiàn)邏輯如圖1所示:

DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么

二、處理表結(jié)構(gòu)變更事件

DBus已經(jīng)具備通過事件方式感知表結(jié)構(gòu)變更的能力,接下來詳細(xì)說明一下表結(jié)構(gòu)變更事件該如何處理。

下圖描述了Event的完整處理流程:

DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么

Event中描述了發(fā)生結(jié)構(gòu)變更的表名、該表所屬的schema以及元數(shù)據(jù)版本號(hào),DBus接受并解析Event之后,根據(jù)表名、schema以及版本號(hào)調(diào)用元數(shù)據(jù)抓取模塊獲取該表的元數(shù)據(jù)(包括表的字段類型、長(zhǎng)度以及注釋等)信息,實(shí)際上DDL trigger和alter語句在一個(gè)事務(wù)中執(zhí)行,這樣在trigger執(zhí)行過程中無法從oracle的數(shù)據(jù)字典里獲取到修改之后表結(jié)構(gòu)元數(shù)據(jù),我們寫入到meta_history表中的元數(shù)據(jù)只是執(zhí)行alter語句之前的元數(shù)據(jù)信息(因此我們給這個(gè)表取名為table_meta_his),要得到完整的元數(shù)據(jù)信息需要聯(lián)合table_meta_his和數(shù)據(jù)字典進(jìn)行查詢,示意SQL如下:

DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么

這個(gè)SQL的結(jié)果有兩種可能:

1)只包含all_tab_cols視圖中的數(shù)據(jù)

2)既包含all_tab_cols視圖中的數(shù)據(jù)又包含table_meta_his表的數(shù)據(jù)(is_current字段的作用是區(qū)別該字段的來源)

結(jié)果A表明在table_meta_his表中沒有找到數(shù)據(jù),這說明在生成表結(jié)構(gòu)變更Event至元數(shù)據(jù)抓取程序成功獲取元數(shù)據(jù)期間沒有再次發(fā)生表結(jié)構(gòu)變更,結(jié)果B則說明在此期間又發(fā)生過一次或多次表結(jié)構(gòu)變更。 

為什么要使用union all?

單獨(dú)使用上圖中的兩個(gè)SQL可能導(dǎo)致元數(shù)據(jù)獲取程序獲取到錯(cuò)誤的結(jié)果,例如:接到表結(jié)構(gòu)變更Event 1后,我們調(diào)用SQL 1 查詢table_meta_his結(jié)果集為空,在調(diào)用SQL 2之前表結(jié)構(gòu)再次發(fā)生變更(命名為Event 2),這種情況下我們通過SQL 2 查詢到的結(jié)果實(shí)際上是再次變更后的結(jié)果,使用這個(gè)結(jié)果產(chǎn)生的元數(shù)據(jù)去解析Event 1和Event 2之間的數(shù)據(jù),如果兩次表結(jié)構(gòu)變更是不兼容的,那么必然會(huì)導(dǎo)致解析失敗。

感謝各位的閱讀,以上就是“DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)DBus數(shù)據(jù)庫(kù)表結(jié)構(gòu)變更處理方法是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI