ITPub博客

首页 > 数据库 > Oracle > 【DBA】Oracle Database 11g: 面向 DBA 和开发人员的重要特性 数据库重放

【DBA】Oracle Database 11g: 面向 DBA 和开发人员的重要特性 数据库重放

Oracle 作者:xysoul_云龙 时间:2016-12-06 21:29:53 0 删除 编辑

数据库重放

了解如何使用数据库重放(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博客 ” ,链接:https://blog.itpub.net/29487349/viewspace-2129900/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
主要从事Oracle数据库 DBA相关工作,其他操作系统、中间件等也有涉及,热衷分享。岁月老将至,如有幸在江湖中留点踪迹,也是欣慰。 【文盲筱烨】好读书爱运动的IT技术爱好者 微博:文盲筱烨 微信公众号:筱烨视点

注册时间:2014-02-15

  • 博文量
    412
  • 访问量
    1104532