1. 程式人生 > >從擺脫Data Guard手工搭建及維護的煩惱說起

從擺脫Data Guard手工搭建及維護的煩惱說起

講師介紹

楊建榮

楊建榮

搜狐暢遊高階DBA

DBAplus社群聯合發起人。現就職於搜狐暢遊,OracleACE-A、YEP成員,超7年資料庫開發和運維經驗,擅長電信資料業務、資料庫遷移和效能調優。

持Oracle10GOCP,OCM,MySQLOCP認證,《OracleDBA工作筆記》作者。

本次分享將分為以下幾部分:

  • 半自動化搭建DataGuard
  • 用不用DGBroker
  • 幾個實用場景演練
  • 與時俱進:Oracle12cDataGuard改進
  • 診斷案例:備庫批量查詢失敗的案例分析
  • 資料遷移中巧用DataGuard

一、半自動化搭建DataGuard

說實話,單純搭建DataGuard的工作現在已經沒什麼技術含量了,而且手工搭建耗時,很可能會有很多的問題,所以我有個想法就是改進,也就是把它半自動化。

大體來說,搭建DataGuard有下面的一些問題:

  • 搭建DataGuard看似工作量巨大
  • 配置繁多(主庫端,備庫端)
  • 問題瑣碎(如果配置不當,很容易陷入各種問題漩渦)
  • 規範化,標準化混亂,備庫各有各的特點
  • 主機名混亂
  • Db_unique_name混亂
  • 資料庫引數不統一
  • 主備的listener.ora,tnsnames.ora中的host有的用IP,有的用主機名
  • Profile檔案不統一

為什麼是半自動化,初衷如下:

  1. 就是為了安全
  2. 主庫就是主庫,不要輕視任何微小的操作
  3. 主庫不規範的地方改動要謹慎
  4. 備庫不規範的地方改動要到位

半自動化的主要目標和套路如下:

安裝前的配置佔用70~80%的時間,所以半自動化的目標主要是配置,就是能簡化配置,簡化安裝。

搭建備庫的兩種常用方式:

基於備庫搭建備庫

rman備份->restore->recover(10g)

基於duplicate的方式

線上搭建(11g)

說到這裡有些羞愧,我自己在內部目前是使用這種方式,效果還不錯,但是因為環境的差異,後期的指令碼沒有流程化,容錯校驗也不多,所以一直沒有開放出來,近期會開放出來,大家保持關注吧。

二、用不用DGBroker

DGBroker是Oracle為DataGuard維護提供的一個很不錯的工具,從我的實際使用來看,早期的版本中似乎大家都還是存在一定的思維定式,認為手工維護已經足夠了。完全可以脫離開這些工具來直觀的使用命令列的方式來維護,這個觀點沒錯,不過存在一主多備的環境,環境較為複雜的情況,這樣一個能夠讓你更輕鬆的工具,如果不用實在是太可惜了。

DGBroker在資料庫端需要啟用一個後臺程序DMON來維護,這個後臺程序啟動,需要設定dg_broker_start為true即可,如果要停止,只需要設定這個引數為false即可。從系統資源的角度來考慮,那幾乎可以忽略不計。

從搭建的便捷性上來看,DataGuard的搭建有了DGBroker已經幾乎沒有了技術含量。

當然DGBroker畢竟只是一個工具而已,如果不懂DataGuard的基本原理,不熟悉手工維護,那麼還是先把那個坑踩平了再來玩這個工具。工具永遠就是一個媒介。好與不好,明心自鑑,過度依賴工具與完全脫離工具,都是兩個不可取的極端。

我是從手工的管理方式過渡到DGBroker的,上了這條船,其實發現還是值得的,所以有不少朋友也問我是否應該在生產環境中使用DGBroker,我的回答是放心用吧。上面我要講的半自動化搭建主要就是希望用DGBroker的方式來完成最後的配置。

三、幾個實用場景演練

1.如何演練Failover

有一天看到有一個網友提了一個問題,描述很簡短:測試DG時,主庫不能宕機,如何測試failover?

其實這個需求從業務層面來說是合理的,一個數據量很大的核心資料庫,如果需要做災難演練,就希望在備庫上做一下演練工作,而這個演練其實又不想影響到目前的主庫,而且又希望能夠儘可能模擬真實的情況,我想這樣對於運維部門來說是最具有考核力度,而對於開發業務部門來說是最受歡迎的,因為他們什麼都不需要改動。

而從技術角度來看,似乎有一些地方需要考量,如果備庫Failover為主庫,那麼這個主庫肯定是可以進行讀寫操作的,如果把它再切回備庫,資料一致性怎麼保證,怎麼能保證是從上次的斷點開始恢復。如果可以做,那真是一大福利。

我們先講講思路,還是閃回,但是閃回的玩法有一些差別,和reinstate的方式有一些區別。假設是一主一備的環境,備庫開啟了閃回資料庫功能

閃回

我們不動原來的主庫,把備庫Failover為主庫。

Failover

然後這個時候Failover的主庫可讀可寫,當然最後還是要切換回備庫接收歸檔,可以使用閃回,同時還需要切換角色,這個地方需要好好琢磨一番該怎麼處理。

備庫

然後我們需要切換為備庫,切換的命令就是關鍵,不是使用switchover的方式。
SQL> alter database convert to physical standby;

2.Switchover下的回退

再舉一個更極端的案例,做資料庫的切換Switchover,然後發現了問題,需要回退,恢復到原來更早的狀態,這個能不能辦到,有了閃回,照樣可以。

大體的思路就是下面的形式:

首先是一個主備庫的環境:

主庫存

switchover是計劃內的任務,就是主切備,備切主。

switchover

這個時候發現切換出現了問題,我們需要緊急回退,需要回退到切換前的狀態,要知道此時的主庫已經不是原來的主庫,備庫也不是原來的備庫了。閃回是否依舊可行,備庫是否可以依舊選擇一個新的斷點可以重新同步?

備庫

實際上這種方案還是可行的,但是建議是可以作為PLAN B來用,當然希望最好不要有這種情況發生。

3.跳歸檔恢復

有一套一主兩備的10gR2環境,一個異機備庫一直在READ ONLY狀態,也就意味著資料庫在開啟之後一直沒有應用歸檔,然後在某一天發現時,已經延遲了好幾個月。無論怎樣,還得慶幸發現了這個問題。

目前來看一種行之有效的方法就是重搭備庫,但是這種修復方式需要大量的磁碟空間,而且需要恢復的時間較長,怎麼改進呢,可以考慮通過基於SCN的增量備份來跳歸檔恢復。目前的環境是一主兩備,再怎麼改進呢,我們可以基於備庫1來完成基於SCN的增量備份,在備庫2完成恢復,對於主庫幾乎是完全透明,無影響的。

整個示意圖如下,通過在Standby1上面基於SCN匯出增量備份,拷貝到備庫2上去恢復,最後再和主庫匯合即可。

SCN

裡面的核心用法就是增量備份恢復,說白了好像就那麼回事,不過對於工作有幫助就行。

四、與時俱進:Oracle 12c Data Guard改進

Oracle的Data Guard技術在11g中有了Active Data Guard,就產生了很多的技術解決方案,比如讀寫分離,多活的技術支撐等,客戶對於這個特性的喜愛程度很大程度上驅動了資料庫的升級。

個人的體驗,12c裡面的改進有兩個亮點,一個就是Far Sync,另外一個就是validate。

先說說Far Sync。以下是來自官方部落格提供的一張圖,看起來很威武霸氣。

Far Sync

這個Far Sync到底是個什麼東東,主要就是為了解決遠距離的資料傳輸延遲,而在中間節點建立的一個虛例項,這個例項很特別,只有引數檔案,密碼檔案和控制檔案,而且需要特別強調的是沒有資料檔案。

當然這個特性是一個補充,你如果使用原本的Active Data Guard也全然沒有問題。而這個特性可以通過中間節點來過渡,達到了官方所宣稱的0資料丟失。

這個特性是不是非常牛叉呢,其實如果大家瞭解Data Guard的一些知識,本身備庫的RFS可以在不存在資料檔案的情況下,在mount狀態下依然接受歸檔。

另外我們說說Cascade standby,在一主多備的環境中,當standby與primary的距離較遠需要通過WAN來傳輸Redo時,為減少傳輸過程中對primary的壓力及網路頻寬的佔用,僅讓其中的一個standby從primary直接接收redo。

兩者的結合和改進,就是Far Sync了,所以我沒有說是一個技術上很大的一個創新,但是卻能夠給實際工作帶來了不少的實惠。

如果已經有了Active Data Guard的環境,啟用Far Sync那就很簡單了。

下面是一個典型的DG配置情況,使用了DG Broker來統一配置管理。主庫是testdb,備庫是testdb2。

DG配置

需要特別強調的是,Far Sync的新增一個關鍵就是控制檔案,這個和備庫控制檔案有所區別。

控制檔案

我剛開始玩的時候大意了,結果因為這個問題給折騰了不少時間。需引以為戒。

正確的姿勢是在主庫生成Far Sync的控制檔案:

Far Sync

很重要的一個檢查項就是檢查v$database,輸出全然不同。

v$database

再次新增Far Sync節點:

Far Sync

當然Far Sync例項本身的資源消耗很小,不需要再給它很高的配置,作為中繼節點,保證網路的暢通更加重要。

然後說說validate,這個改進比較貼心,如果需要switchover,是否可行,可以用validate來做一個檢查。我對比了12c和11g中的DG Broker命令,唯一較大的差別就是validate,這個預檢查還是一個很實用的改進。

validate

五、診斷案例:備庫批量查詢失敗的案例分析

然後給大家分享一個備庫批量查詢失敗的案例,希望對大家分析問題有幫助。

資料庫環境是10gR2,一主兩備。其中一個備庫上每天凌晨會開放一個視窗執行一些批量的查詢,會通過crontab來呼叫DGBroker來在READ-ONLY和ONLINE之間切換。

但是有一天開發的同學突然找到我說,最近幾天開始批量查詢會頻頻報錯,希望我幫忙檢視一下。

錯誤日誌如下,可以看到是一條查詢語句。

[2016.03.0604:10:02.352]org.springframework.jdbc.UncategorizedSQLException:PreparedStatementCallback;uncategorizedSQLExceptionforSQL[selectbind_flagfromtest_billingwherecn_master=?];SQLstate[60000];errorcode[604];ORA-00604:erroroccurredatrecursiveSQLlevel1

[2016.03.0604:10:02.352]ORA-16000:databaseopenforread-onlyaccess

[2016.03.0604:10:02.352];nestedexceptionisjava.sql.SQLException:ORA-00604:erroroccurredatrecursiveSQLlevel1

[2016.03.0604:10:02.352]ORA-16000:databaseopenforread-onlyaccess

[2016.03.0604:10:02.352]

而從資料庫層面沒有任何的日誌報錯。

在備庫想看看這個問題是否發生。於是根據日誌中的語句使用DBA使用者(屬主是使用者acc)查詢了一下,發現沒有任何問題。

selectbind_flagfromacc.test_billingwherecn_master=?語句可以順利輸出結果。

自己也嘗試了dml的情況,錯誤資訊也會有所不同。

SQL>updateacc.test_billingsetbind_flag=0wherecn_master=’660078174′;

updatetest_billingsetbind_flag=0wherecn_master=’660078174′

*

ERRORatline1:

ORA-01552:cannotusesystemrollbacksegmentfornon-systemtablespace’ACC_DATA’

開始理一理思路,之前從來沒有反饋過這個問題,而問題是在最近發生的。那麼應用端是否在最近有什麼變化呢,得到的反饋是在1月中下旬有一次變更,但是這都過去好久了,不足以佐證現在的問題。

而從資料庫層面,如果存在問題,那看似只有bug的可能性了,但是查了MOS一圈,發現了幾種可能的場景,但是都和目前的情況不符合,目前查到有兩種場景,一種是略微複雜的查詢,一種是帶有dblink的查詢。參考連結如下:

DblinkonPhysicalstandby-ORA-16000(DocID1296288.1)

ORA-16000WithASemanticQueryOnARead-onlyDatabase(DocID1928638.1)

目前的情況是這個語句非常簡單,實在找不出來可能的原因了。

開發的同事也催的比較緊,但是感覺從資料庫層面得到的資訊著實有限。無奈之下,開啟了手工debug方式。就從alert日誌中的那個關於temp的報錯開始分析。(在11g會有備庫取樣資料,這個問題解決就會容易很多了)

第二天通過日誌看到應用執行之後,檢視系統級,沒有任何的抖動,資料庫層面也可以看到應用是連線進來了。在反覆確認呼叫的細節之後,我切換到指定的使用者,再次嘗試;然後再次執行這個報錯的語句,終於得到了期望之中的報錯。

SQL>selectbind_flagfromtest_billingwherecn_master=’660078174′;

selectbind_flagfromtest_billingwherecn_master=’660078174′

*

ERRORatline1:

ORA-00604:erroroccurredatrecursiveSQLlevel1

ORA-16000:databaseopenforread-onlyaccess

採用owenr使用者的方式來檢視,就沒有問題了。

SQL>selectbind_flagfromacc.test_billingwherecn_master=’660078174′;

BIND_FLAG

———-

689537

這個問題是怎麼回事呢?

TEST_SHINK下的都是同義詞,指向ACC這個owner使用者,那麼這個同義詞有什麼特別的呢。進一步檢視,發現同義詞test_billing狀態是INVALID的。

而問題的修復就更簡單了,在主庫執行下面的SQL即可。

>selectcount(*)fromTEST_SHINK.TEST_BILLINGwherecn_master=’660078174′;

COUNT(*)

———-

1

因為這個使用者應用只在備庫使用,所以就導致了這個看起來奇怪的問題,看來都是事出有因,耐心一些,細緻一些還是會有發現。對於這個問題更多的細節就不贅述了。

六、資料遷移中巧用DataGuard

DataGuard是資料遷移中一個很重要的方式,但是一大硬傷就是不可以直接升級資料庫。可以簡化來說,資料庫升級的本質是升級資料字典,大批量資料庫的情況下快速遷移資料,通過DataGuard來完成,然後匯入資料字典資訊其實也是一個不錯的方式。

比如一套硬體環境是Solaris,Oracle10gR2單例項,資料量在800G左右。想遷移到另外一臺伺服器上。大體的需求如下:

  1. 藉助這次維護的時機,能夠把資料庫升級至11g
  2. 升級的過程需要儘可能保留一個較短的時間視窗,計劃在2個小時以內完成
  3. 有較好的解決方案去演練整個過程,多次總結,提高遷移的效率,保證質量
  4. 有完善的回退計劃,能夠支援回退場景下業務平滑過渡
  5. 目前對於跨平臺沒有明確的要求,可以繼續使用Solaris,也可以考慮跨平臺,但是影響範圍要小。

這種情況下,就可以充分藉助DataGuard來完成,我們可以在備庫環境建立一個11g的資料庫,db_name,字符集不變。

Data Guard

在備庫端進行Switchover/Failover(具體選哪個,可以根據需求來定)後,匯出傳輸表空間的元資料。這個時候對資料檔案沒有做任何操作,匯出完成後,停掉備庫端10g的資料庫。

元資料

然後在備庫匯入傳輸表空間的元資料至新的11g庫,資料檔案路徑依舊不變,因為傳輸表空間只傳輸表資料,對於儲存過程,函式,檢視,同義詞,DB link,許可權等都無法同步,所以可以在這個基礎上選擇性匯出全庫的指定schema的資訊,匯入目標庫中,因為是DDL的匯入,這個過程持續時間也會很快。

匯入後就完成了基本的遷移,相比比Datapump,XTTS的傳輸同步資料的時長,這個過程可以控制在一個很短的時間內。

Datapump

最後為個人的新書做一個宣傳,《Oracle DBA工作筆記》是我個人筆記的精華選集,希望大家多多捧場,學習交流,共同進步。

Oracle DBA工作筆記

文章出處:DBAplus社群(訂閱號ID: dbaplus)