天天看點

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

<b></b>

講師介紹  

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

楊建榮

搜狐暢遊進階dba

dbaplus社群聯合發起人。現就職于搜狐暢遊,oracle ace-a、yep成員,超7年資料庫開發和運維經驗,擅長電信資料業務、資料庫遷移和性能調優。

持oracle 10g ocp,ocm,mysql ocp認證,《oracle dba工作筆記》作者。

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

半自動化搭建data guard

用不用dg broker

幾個實用場景演練

與時俱進:oracle 12c data guard改進

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

資料遷移中巧用data guard

一、半自動化搭建data guard

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

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

搭建data guard看似工作量巨大

配置繁多(主庫端,備庫端)

問題瑣碎(如果配置不當,很容易陷入各種問題漩渦)

規範化,标準化混亂,備庫各有各的特點

主機名混亂

db_unique_name混亂

資料庫參數不統一

主備的listener.ora,tnsnames.ora中的host有的用ip,有的用主機名

profile檔案不統一

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

就是為了安全

主庫就是主庫,不要輕視任何微小的操作

主庫不規範的地方改動要謹慎

備庫不規範的地方改動要到位

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

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

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

基于備庫搭建備庫

rman備份 -&gt; restore  -&gt; recover(10g)

基于duplicate的方式 

線上搭建(11g)

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

二、用不用dg broker

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

dg broker在資料庫端需要啟用一個背景程序dmon來維護,這個背景程序啟動,需要設定dg_broker_start為true即可,如果要停止,隻需要設定這個參數為false即可。從系統資源的角度來考慮,那幾乎可以忽略不計。

從搭建的便捷性上來看,data guard的搭建有了dg broker已經幾乎沒有了技術含量。

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

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

三、幾個實用場景演練

1如何演練failover

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

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

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

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

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

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

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

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

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

然後我們需要切換為備庫,切換的指令就是關鍵,不是使用switchover的方式。

sql&gt; alter database convert to physical standby;

2switchover下的回退

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

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

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

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

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

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

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

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

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

3跳歸檔恢複

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

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

整個示意圖如下,通過在standby1上面基于scn導出增量備份,拷貝到備庫2上去恢複,最後再和主庫彙合即可。

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

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

四、與時俱進:oracle 12c data guard改進

oracle的data guard技術在11g中有了active data guard,就産生了很多的技術解決方案,比如讀寫分離,多活的技術支撐等,客戶對于這個特性的喜愛程度很大程度上驅動了資料庫的更新。

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

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

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

這個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。

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

需要特别強調的是,far sync的添加一個關鍵就是控制檔案,這個和備庫控制檔案有所差別。

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

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

正确的姿勢是在主庫生成far sync的控制檔案:

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

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

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

再次添加far sync節點:

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

當然far sync執行個體本身的資源消耗很小,不需要再給它很高的配置,作為中繼節點,保證網絡的暢通更加重要。

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

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

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

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

資料庫環境是10gr2,一主兩備。其中一個備庫上每天淩晨會開放一個視窗運作一些批量的查詢,會通過crontab來調用dg broker來在read-only和online之間切換。

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

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

[2016.03.06 04:10:02.352]org.springframework.jdbc.uncategorizedsqlexception: preparedstatementcallback; uncategorized sqlexception for sql [select bind_flag from test_billing where cn_master=?]; sql state [60000]; error code [604]; ora-00604: error occurred at recursive sql level 1

[2016.03.06 04:10:02.352]ora-16000: database open for read-only access

[2016.03.06 04:10:02.352]; nested exception is java.sql.sqlexception: ora-00604: error occurred at recursive sql level 1

[2016.03.06 04:10:02.352]

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

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

select bind_flag from acc.test_billing where cn_master=?  語句可以順利輸出結果。

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

sql&gt; update acc.test_billing set  bind_flag=0 where cn_master='660078174';

update test_billing set  bind_flag=0 where cn_master='660078174'

       *

error at line 1:

ora-01552: cannot use system rollback segment for non-system tablespace 'acc_data'

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

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

dblink on physical standby - ora-16000 (doc id 1296288.1)

ora-16000 with a semantic query on a read-only database (doc id 1928638.1)

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

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

第二天通過日志看到應用運作之後,檢視系統級,沒有任何的抖動,資料庫層面也可以看到應用是連接配接進來了。 在反複确認調用的細節之後,我切換到指定的使用者,再次嘗試;然後再次運作這個報錯的語句,終于得到了期望之中的報錯。

sql&gt; select bind_flag from test_billing where cn_master= '660078174';

select bind_flag from test_billing where cn_master= '660078174'

                      *

ora-00604: error occurred at recursive sql level 1

ora-16000: database open for read-only access

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

sql&gt; select bind_flag from acc.test_billing where cn_master= '660078174';

 bind_flag

----------

    689537

這個問題是怎麼回事呢?

test_shink下的都是同義詞,指向acc這個owner使用者,那麼這個同義詞有什麼特别的呢。進一步檢視,發現同義詞test_billing狀态是invalid的。

而問題的修複就更簡單了,在主庫運作下面的sql即可。

&gt; select count(*)from test_shink.test_billing where cn_master= '660078174';

  count(*)

    1

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

六、資料遷移中巧用data guard

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

比如一套硬體環境是solaris,oracle 10gr2 單執行個體,資料量在800g左右。想遷移到另外一台伺服器上。大體的需求如下:

借助這次維護的時機,能夠把資料庫更新至11g

更新的過程需要盡可能保留一個較短的時間視窗,計劃在2個小時以内完成

有較好的解決方案去演練整個過程,多次總結,提高遷移的效率,保證品質

有完善的回退計劃,能夠支援回退場景下業務平滑過渡

目前對于跨平台沒有明确的要求,可以繼續使用solaris,也可以考慮跨平台,但是影響範圍要小。

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

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

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

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

然後在備庫導入傳輸表空間的中繼資料至新的11g庫,資料檔案路徑依舊不變,因為傳輸表空間隻傳輸表資料,對于存儲過程,函數,視圖,同義詞,db link,權限等都無法同步,是以可以在這個基礎上選擇性導出全庫的指定schema的資訊,導入目标庫中,因為是ddl的導入,這個過程持續時間也會很快。

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

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

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2016-11-04</b>