【DBA】Oracle Database 11g: 面向 DBA 和開發人員的重要特性 資料庫重放

xysoul_雲龍發表於2016-12-06

資料庫重放

瞭解如何使用資料庫重放(Oracle Database 11 g 中一個閃亮登場的全新工具)來捕獲完整的資料庫負載,以便您可以隨意進行“重放”。



需要在資料庫中進行更改時 — 無論是進行微小的改動(如變更初始化引數和資料庫屬性)還是進行不可避免的較大改動(如應用補丁集),您最關心什麼?對於到 Oracle Database 11 g 的升級,您最關心的是什麼?

對我而言,我最關心的是更改是否會帶來“破壞性”風險。即使微小的改動也有可能引發多米諾骨牌效應,最終導致嚴重後果。

為了將這種風險降至最低,許多廠商在類似於生產環境的控制環境中進行更改,應用類似於生產系統的負載並觀察隨之產生的影響。複製生產系統非常簡單(至少從技術層面上講),但再現負載卻是另一回事。說起來容易做起來難。

多數機構會採用一些可自動執行以模擬真實使用者活動的第三方負載生成工具進行嘗試。大多數情況下,這種方法是可行的,但始終無法真正忠實地再現生產資料庫負載。這些第三方工具只是透過不同引數執行預編寫的查詢若干次;您必須向這些工具提供查詢並給定其可以隨機使用的引數範圍。這並不能代表您的生產系統負載,而僅僅是執行了一小部分執行了若干次的生產負載,因此,這只是對 1% 的應用程式程式碼進行了測試。最糟糕的是,這些工具要求您自己提供所有來自生產負載的查詢,對於小型應用程式而言,這可能需要數週或數月,對於複雜些的應用程式,則可能需要多達一年的時間。

如果可以,在資料庫本身內記錄所有資料庫操作(與 DML 相關的操作及其他操作),而後按這些操作出現的真實順序進行重放,難道不是一種更好的方法嗎?

資料庫重放概述

Oracle Database 11 g 將為您帶來諸多好處。新的資料庫重放工具好似資料庫內的 DVR。使用這個獨特的方法,可以如實地以二進位制檔案格式捕獲 SQL 級以下的所有資料庫活動,然後在同一資料庫或不同資料庫內進行重放(這正是在進行資料庫更改之前您希望做的)。您還可以自定義捕獲流程,以包括或排除某些特定型別的活動。

資料庫重放與另一個工具 SQL Performance Analyzer 共同構成了 Oracle Database 11 g 的 Real Application Testing 選件。這兩個工具之間的主要不同在於涉及的範圍:資料庫重放適用於捕獲和重放資料庫內的所有(符合某些過濾條件)活動,而 SQL Performance Analyzer 可用於捕獲特定的 SQL 語句並對其進行重放。(在資料庫重放中,您無法檢視或訪問捕獲到的特定 SQL,而在 SQL Performance Analyzer 中則可以)。後者的一個顯著優勢是 SQL 調優,因為您可以調整由應用程式執行的 SQL 語句並評估其影響。(本系列即將推出有關 SQL Performance Analyzer 介紹的文章。)

理論上,資料庫重放的工作順序如下圖所示。

圖 1

啟動一個記錄資料庫活動的捕獲流程。

  • 稍後,停止捕獲流程,將這些捕獲檔案移至 /replay directory/ 目錄中的測試系統。
  • 這些捕獲檔案將在測試資料庫上應用。


那麼,資料庫重放可以提供哪些第三方工具不能提供的優勢?一些工具僅重放若干您提供的複合語句。而資料庫重放不需要您提供 SQL 語句。由於它將捕獲 SQL 之下的所有活動,因此您不會遺漏任何可能導致效能問題的關鍵操作。此外,您可以有選擇地(針對特定使用者、程式等)進行捕獲,還可在捕獲負載時指定時間期限,可以重放導致問題的特定負載,而不是整個資料庫。

例如,您注意到月末利息計算程式導致問題出現,並猜想更改引數將簡化流程。您必須做的是捕獲月末程式執行期間內的負載,在測試系統上對引數進行更改,然後在該測試系統上重放捕獲檔案。如果效能有所提升,則表明此解決方案可行。如果效能沒有提升,這也僅僅是個測試系統而已。您不會妨礙到生產資料庫的執行。

在我看來,單為了使用該工具,也值得升級到 Oracle Database 11 g。下面將介紹該工具的工作原理。

捕獲

第一個任務是捕獲資料庫中的負載。所有任務都可透過命令列或 Oracle Enterprise Manager Database Control 完成,但本文將使用後者。

  1. 捕獲到的負載儲存在系統中的檔案上,這些檔案是名副其實的“攝像機”內的“磁帶”。該目錄應當為空。因此,第一個任務是建立目錄(如果還沒有此目錄)。對於本例,建立的目錄名為 /home/oracle/dbcapture。 
      $ cd /home/oracle
      $ mkdir dbcapture
  2. 在資料庫中為該目錄建立一個目錄物件:
    SQL> create directory dbcapture as '/home/oracle/dbcapture';
          
    Directory created.
  3. 現在,可以開始捕獲了。為了演示真實場景,將建立一個簡單的測試工具,該工具將生成許多 INSERT 語句並插入到一個名為 TRANS 的表中。
    create table trans (
            trans_id        number,
            cust_name       varchar2(20),
            trans_dt        date,
            trans_amt       number(8,2),
            store_id        number(2)
    )
    /


    下面是一個可完成此任務的小的 PL/SQL 程式碼片斷。該程式碼片斷將生成 1,000 條插入語句並進行執行。(注意,此程式碼片段將生成 1,000 條不同的插入語句,而不是在同樣的語句或程式中執行 1,000 次插入操作。)

    declare
      l_stmt varchar2(2000);
    begin
      for ctr in 1..1000 loop
         l_stmt := 'insert into trans values ('||
            trans_id_seq.nextval||','||
            ''''||dbms_random.string('U',20)||''','||
            'sysdate - '||
            round(dbms_random.value(1,365))||','||
            round(dbms_random.value(1,99999999),2)||','||
            round(dbms_random.value(1,99))||')';
         dbms_output.put_line(l_stmt);
         execute immediate l_stmt;
         commit;
      end loop;
    end;
  4. 只建立包含以上內容的檔案;不要執行。將該檔案命名為 add_trans.sql。(以上所有步驟僅對於此課程都是必要的。如果沒有目錄物件,則在生產環境中執行操作時無需這些步驟。)
  5. 在現實情況中,您可能會在不同的資料庫上執行重放。但是,在此處,針對我們的目的,您將只是閃回同一資料庫並重放那裡的活動。您可以透過建立名為 GOLD 的恢復點來標記該場所。
    SQL> create restore point gold;


    現在,準備開始捕獲。導航到 Oracle Enterprise Manager Database Control 中的 Database Replay 主頁面。在該主頁中,選擇 Software and Support(如下圖所示,標記為“1”)

    圖 2
  6. 單擊  Database Replay(在  Real Application Testing 下面)啟動 Database Replay 頁面(如下所示)。 

    圖 3
  7. 在左側窗格中,您將看到一系列活動。選擇第一個活動 ( Step 1:Capture Workload),方式是單擊它旁邊的  Go to Task 圖示。
  8. 下一個螢幕將顯示三個您應在啟動捕獲流程之前仔細檢查並確認的假設: 

    • 有足夠的磁碟空間來儲存捕獲的負載
    • 在使用了擴充套件的情況下,重放持續時間為 6 秒,與之相比,非擴充套件情況下為 5 秒
    • 平均活動會話數和使用者呼叫數分別為 0.84 和 1120,而這些數字在非擴充套件情況下為 0.29 和 112。順便說一下,在捕獲期間,使用者呼叫數也是 112,與非擴充套件情況相同。因為擴充套件係數為 10,因此使用者呼叫的數量增加到 10 倍。

    您可以清楚地看到,擴充套件倍增器按照倍增係數增加了使用者會話的數量。該測試不僅如實地重放了生產環境中捕獲的活動,而且還增加了這些活動的數量以檢查系統是否能夠處理該測試。

    您應牢記一些重要事情:捕獲的負載只是一個 SELECT 查詢。如果已有 DML,那麼僅一組重放發出了這些語句,而其他僅重放 SELECT。5 個不同的重放客戶端執行同一條刪除語句將不會造成 5 次刪除,而 5 條插入語句可能會由於主鍵違規導致四個故障。

    此外,還請考慮以下情況:假設從生產系統中捕獲了所有負載,並在測試系統中重放了這些負載。經過幾輪測試和調優後,將測試系統升級為生產系統。假設某個應用程式仍需要進一步的模式更改(如附加索引或不同分割槽),您當然希望確保這些更改會增強效能,更重要的是,不會導致其他問題。在模式更改後再次重放負載是確認您所考慮的問題的最有效方法。

    如何確保僅重放特定使用者(例如 SH)的活動?一種方法是從生產環境中重新捕獲負載,具體來說就新增一個僅捕獲 SH 的活動的篩選器,然後在測試系統上重放新捕獲的負載。但是,該方法可能由於以下多種原因而不可行:

    • 由於舊生產環境不再工作,而新生產環境(舊測試環境)沒有與 SH 模式相關的任何活動,甚至可能導致無法捕獲新負載。

    • 其他邏輯方面的挑戰(如變更控制限制)

    可以做些什麼呢?

    在 Oracle Database 11 g 第 2 版中,有一個簡單選擇:在重放階段只重放選擇的負載。這樣,不僅可以在捕獲期間應用篩選器,還可以在重放期間應用篩選器。我們來了解一下其工作原理。

    在重放期間,您可以建立並使用篩選器。我們來建立一個篩選器以便僅使用 SH 使用者:

    begin
            dbms_workload_replay.add_filter (
                    fname      => 'SH_ONLY',
                    fattribute => 'USER',
                    fvalue     => 'SH'
            );
    end;
    /


    您可以對眾多使用者定義任意數量的篩選器。此外,您還可以對不同屬性(不只是使用者名稱)定義篩選器。在引數 FATTRIBUTE 中可以使用以下值,在 FVALUE 引數中可以使用您感興趣的值。以下是屬性的可能值:

    USER 
     the usernames of the calling users
    MODULE 
     the module
    ACTION 
     the action
    PROGRAM 
     the program
    SERVICE 
     service_name of the calling user
    CONNECTION_STRING 
     the connect string used (like the one you use in tnsnames.ora file)


    新增篩選器之後,建立一個篩選器集:

    begin
            dbms_workload_replay.create_filter_set (
                    replay_dir       => 'RATCATURE',
                    filter_set       => 'SH_ONLY',
                    default_action   => 'INCLUDE'
            );
    end;
    /


    注意,引數 default_action 設定為 INCLUDE,這是預設值。它指定篩選器集的預設操作。在本例中,INCLUDE 意味著包含篩選器,即 SH 使用者包含在重放的負載中。如果您希望相反的結果,即執行除 SH 以外的所有使用者的操作,那麼您應使用 EXCLUDE 作為此引數的值。

    建立篩選器集之後,就可在重放中使用它了。資料庫初始化之後(在重放之前):

    begin
            dbms_workload_replay.initialize_replay (
                    replay_name     => 'REPLAY1',
                    replay_dir      => 'RATCATURE'
    );
    end;
    /


    您可使用篩選器集:

    begin
            dbms_workload_replay.use_filter_set (
                    filter_set     => 'SH_ONLY'
            );
    end;
    /


    當您執行選擇性測試(即針對模式、服務名稱等的測試)時,重放負載子集這一功能非常有用。它使您不必多次捕獲負載。理想情況下,您只需要一次捕獲整個生產負載,然後有選擇性地重放,從而單獨測試各種元件。

     

    用例

    資料庫引數更改 — 假如,您要更改引數 db_file_multiblock_read_count 的預設值,那麼是從 16 改為 256 還是 128?亦或是將其設為 64 或 32?選擇有限,但影響可能無限;更改此值會對最佳化器帶來極大影響,對某個查詢有益的更改可能會破壞另外 100 個查詢。如何確定該引數的最佳值?

    資料庫重放可輕鬆應對這種情況。您可以從生產系統捕獲負載,而後將捕獲的負載移至不同的測試系統中,並將 db_file_multiblock_read_count 設為 32,然後重放負載。之後,您可以將資料庫閃回至初始狀態,將該值設為 64,並重放相同的負載。您可以針對該引數所有可能的值重複執行這一過程:閃回、設定值、重放捕獲的負載。每次重放時,您可執行重放前後的 AWR 報告並進行比較。然後選擇可帶來最佳整體結果的引數值。如果沒有資料庫重放,則根本不可能確定出最佳值。

    作業系統升級 — 您計劃升級作業系統或只是應用一個小補丁來修復 I/O 問題,但您如何能確保它不會帶來任何破壞或帶來一些其他問題?很簡單:只要捕獲負載並在應用補丁的測試系統中對其進行重放。該方法同樣也適用於核心引數更改。

    應用補丁 — 假設您發現一個錯誤,並且有相應的補丁可用。但您無法確保其會對現有操作產生何種影響,當然,您也可以和企業中 1000 位其他使用者共同找出答案。資料庫重放將為您解決這一難題。

    除錯 — 總是會有一些會帶來意外結果的令人討厭的程式。幸運的是,有了資料庫重放,除錯變得前所未有的輕鬆。只需在程式執行期間捕獲負載,並移至一個新系統,更改程式邏輯以加入一些除錯資訊,而後重放負載、分析輸出並解決問題。如果第一次並未奏效,不要失去信心。重複該過程(從重放開始;無需再次捕獲)直至找到解決方案。

    物件更改 — 您希望新增索引或將索引從 b 樹轉換為點陣圖。這會對 INSERT 語句產生何種影響?會在何處產生影響?不要猜測;只需捕獲負載並在測試系統中進行重放即可。

    資料庫升級 — 這是夢寐以求的更改確保。升級至 Oracle Database 11 g 的時代已經到來。最大的問題是:您所有的應用程式都會正常執行甚至是表現更好嗎?無需多慮,只要從 Oracle Database 10 g 捕獲負載並在 Oracle Database 11 g 中進行重放即可。您不是在新版本上測試一些複合事務,而是在測試應用程式每天都在使用的 SQL。如果有些事情並未按計劃進行,則在新系統中對其進行調整,直至您獲得完全滿意的結果。

    平臺更改 — 假設您希望將資料庫平臺從 Solaris 遷移到 HP-UX(其中沒有提供適用於檔案系統的非同步 I/O)。效能是否還會一樣?為什麼要猜測?只要捕獲 Solaris 中的負載並在 HP-UX 中進行重放即可。

    轉換到 Oracle Real Application Clusters (RAC) — 這是一個普遍問題:您計劃將資料庫從單一例項轉換為 RAC 例項。應用程式表現是否如初?獲取答案的唯一方法是執行實際的負載,對其進行捕獲,而後在 RAC 資料庫中進行重放。

    總結

    更改從來都是困難重重,但也不再是無法忍受。您可以透過使用新的資料庫重放工具捕獲終端使用者放入系統中的確切活動,而後在測試系統上進行重放,以精確地衡量更改影響來降低多數風險,而這些都只需幾下滑鼠點選和鍵盤敲擊即可實現。請記住,您還可以測試應用程式的功能,並不僅僅限於效能。

    原文地址:



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29487349/viewspace-2129900/,如需轉載,請註明出處,否則將追究法律責任。

相關文章