Chinaunix首页 | 论坛 | 博客
  • 博客访问: 265311
  • 博文数量: 42
  • 博客积分: 1445
  • 博客等级: 上尉
  • 技术积分: 485
  • 用 户 组: 普通用户
  • 注册时间: 2005-05-05 16:21
文章分类

全部博文(42)

文章存档

2011年(1)

2009年(5)

2008年(1)

2007年(1)

2006年(28)

2005年(6)

我的朋友

分类: LINUX

2006-05-19 15:31:31

级别: 初级

Geoffrey Bergren

2002 年 7 月 01 日

每个系统都需要针对其特定用途和用户进行调优。本文将研究决定检查点时间间隔和检查点持续时间的参数,并将提供用于检查点调优的特定示例和练习。本文将帮助您理解调优检查点的过程,以便您针对需要达到的目标适当地调优自己的系统。

这篇文章以前在 Informix Tech Notes 季刊中发表过。Tech Notes 文档集涵盖从 1991 年到 2001 年期间的文章。要获取 1998 年或之前文章的重印本,可通过 与技术支持(Technical Support)联系

在联机事务处理系统中,检查点在系统失败的情况下提供了恢复后所要具备的状态。因此,检查点调优成了一项重要工作。

检查点的用途是将所有已修改页从共享内存缓冲区高速缓存写到磁盘,以便为恢复提供物理一致的点。在确定检查点如何出现时,必须考虑两个时间值。

第一个是检查点时间间隔。这是两个检查点间的时间量。这一时间值的重要性在于它关系到在失败的情况下用于恢复所需的时间。检查点间的时间间隔越长,恢复时间也就越长。

第 二个要考虑的时间值是检查点持续时间。在检查点期间,所有已修改页都将从缓冲区高速缓存写到磁盘。大部分检查点时间都只用于这一活动。在检查点阶段,不允 许执行临界的代码段 — 那些需要修改共享内存缓冲区高速缓存(我们正试图将其写到磁盘)的代码。因此,在检查点阶段,不允许修改共享内存缓冲区高速缓存。由于数据库用户将这种情 况视为暂停(或挂起),因此检查点持续时间需要保持为最小。

本文将研究决定检查点时间间隔和检查点持续时间的参数,并将提供用于检查点调优的特定示例和练习。





回页首


检查点时间间隔由以下参数决定:

  • 实际检查点时间间隔
  • 物理日志的大小

检 查点间的实际时间间隔可以从消息日志文件(online.log)获得。系统中出现的每个检查点在消息日志文件中都有时间记录。要获取检查点时间间隔,可 查找两个连续的检查点,然后用较大的时间值减去较小的时间值。对一整天中多对检查点执行该操作,就可以充分了解平均检查点时间间隔。

该 时间间隔应接近检查点时间间隔参数。如果它非常小,而且始终很小,请增加物理日志文件的大小。您会希望物理日志的大小与检查点时间间隔协调一致。有时候, 在活动峰值期间,检查点时间间隔可能会小于检查点时间间隔参数。那没有问题。请记住,检查点时间间隔关系到快速恢复的恢复时间。在活动峰值期间,较小的时 间间隔比较合适,因为在失败的情况下有更多的恢复工作要做。

要监控物理日志文件使用了多少,可使用 onstat -1并参考物理日志文件行。在接近检查点时间时,如果已使用的页数从未达到物理日志文件中总页数的 75%,那么请减小物理日志文件的大小。因为您正在浪费不需要的磁盘空间。





回页首


检查点持续时间由以下参数决定:

  • 需要写到磁盘的已修改页的数目。
    • 检查点间 LRU 写操作的数目
    • 应用程序的性质
  • 将那些页写到磁盘所需的 I/O 数量。
    • 使用的驱动器数目
    • 写操作的随机性质
  • 从数据库引擎到硬件的请求速度。
    • 页清除程序的数目
    • AIO VP 的数目

所有检查点的持续时间都记录在消息日志文件中。您将在消息日志文件中每个检查点之后找到其持续时间。请监控日志文件,确保大部分检查点在可接受的时间(通常小于五秒)内完成。如果它们在可接受的时间内没有完成,请继续阅读以了解处理办法。





回页首


从磁盘驱动器到数据库引擎进行逆向分析,可能的检查点持续时间瓶颈如下所示:

  • 磁盘设备
  • 磁盘控制器
  • CPU
  • AIO VP
  • CPU VP
  • 页清除程序
  • LRU 队列的数目
  • 缓冲区高速缓存中已修改页的数目

可以用几个 UNIX 实用程序(包括 sariostatglance)监控磁盘驱动器。如果您正试图向其写数据的磁盘驱动器已经百分之百地投入工作,那么您可以做以下两件事情:

  • 将数据更均匀地分布在您能使用的磁盘上(即数据库重组),或者
  • 购买更多磁盘并重组磁盘 I/O。

或者,您可以忍受较差的性能。

磁盘控制器的行为与磁盘很相似。如果控制器已经最大程度地参与工作,那么您就无法让更多的数据通过。将 I/O 分布在多个控制器中,或购买更多的控制器(如果必须如此的话)。

可以使用 sarvmstatglance监控物理 CPU。如果您的 CPU 在所有的时间都百分之百地参与工作,那么您无法更快地将数据写到磁盘。将应用程序卸载至客户机机器以减少争用,或者添加更多或更快的 CPU。假如硬件没有最大程度地参与工作,那么您可以调优 Informix 引擎以获得更佳性能。

接下来要查看的地方是 AIO VP。它们能跟上来自引擎内部的请求以实际地执行磁盘写操作吗?监控 onstat -g ioq并 留意 AIO VP 与 GFD(GFD 是块的已打开文件处理程序)的队列长度和最大队列长度。如果这些队列中的任何一个有较大的最大长度(>25)或一致长度(>10),则 I/O 请求发生得不够快。只要硬件没有饱和,添加更多 AIO VP(或者添加 CPU VP,如果正在使用内核 AIO 的话)应当增加某个时间能被处理的请求数目,并缩短队列的长度。

如果 AIO 队列没有滞后,而性能仍不是所期望的,则请求可能没有足够快地到达队列。添加更多的页清除程序(它们负责向队列提出请求)可以更快地输出那些请求。可以用 onstat -F检查页清除程序的状态。如果页清除程序是活动的,但没有用请求使队列保持活动,请添加更多的页清除程序。

LRU 队列的数目也会起作用。在最少情况下,要确保每个 CPU VP 有一个 LRU 队列。要更改缓冲区高速缓存,CPU VP 将在它们正在访问的 LRU 队列上放置互斥锁(mutex)。如果队列的数量少于 CPU VP 数量,那么您会遇到争用问题。如果使用较大的缓冲区高速缓存,那么更多的 LRU 队列将使每个队列的长度更短。这也可能稍稍提高性能。

最后,检查点持续时间将以在检查点阶段需要写到磁盘的已修改页 数目为基础。减少检查点持续时间的最好方法是让写到磁盘的已修改页更少。告诉最终用户只能修改他们当前要改变的页的 10% 不是一个好的方法。同样,限制缓冲区的数量将严格限制读高速缓存。结果,系统其余部分的性能将降低。必须找到别的方法来处理这个问题。





回页首


让我们研究 OLTP 系统的一些参数:

  • 要求响应时间较短(小于两秒)。
  • 对数据的访问是通过索引随机进行的。
  • 请求中所影响的行数较小。
  • 数据将被修改(插入、更新和删除)。
  • 检查点持续时间必须短(小于五秒)。
  • 快速恢复时间必须短(10 到 15 分钟)。
  • 读缓冲区高速缓存百分比占 95% 或更高。

在 符合以上参数的情况下,我建议在将页输入内存以进行插入、更新和删除所需的随机读之间,可以进行随机写入 — 不会有明显的性能退化。如果用户在进行随机读操作,则少数的随机写操作不应该会使响应时间变慢很多。尽管在检查点阶段进行写操作对于系统整体而言更有效 率,但较长的检查点持续时间对于最终用户是一个重大问题。

检查点调优很好地示范了用户对系统性能的感觉与总体系统性能之间的差距。

需要设置几个参数,它们允许您在检查点间将已修改的缓冲区写入磁盘。这些参数是 LRU MIN DIRTY 和 LRU MAX DIRTY。为了说明它们,下面是一个比拟:

假如我们还是小孩子,我们都会面对房间将要变脏这一事实。我们的母亲会允许房间的脏乱达到某一程度,当达到该程度后她们就会说一些批评的话,大意是“这样脏的地方你还住得下吗?不收拾好房间哪儿也不许去!”您听到后会咕哝几句,“没有那么脏”,但您还是把房间打扫了。

然而,打扫得多干净有一个限度。您知道只有房间有那么干净了您才能离开。而且,由于天性懒惰,所以当做到那个清洁程度您就停止了。您把衣服放到抽屉和壁橱中,但少许玩具还是胡乱扔在地板上。另外,假设您是个少年,您回头睡觉,偶尔醒来看看有什么有趣的事可干。

在 必须进行打扫之前的最大脏乱程度(已修改的缓冲池页)由 LRU MAX DIRTY 参数控制。LRU MIN DIRTY 参数则控制在停止清理之前要使缓冲区达到的清洁程度。页清除程序(小孩子)就是负责提出写请求的线程。它们会一直睡眠,直到达到 LRU MAX DIRTY 参数并且被 CPU VP(母亲)唤醒为止。

页清除程序随后清理缓冲区(房间),将已修改页写到磁盘(放好衣服和玩具),直到达到 LRU MIN DIRTY 为止,然后回头睡觉。





回页首


让我们来研究一个检查点问题的示例,看看如何利用以上的知识来帮助我们。在有 100 位并发用户的 OLTP 系统上,我们有检查点持续时间的问题。目前,我们每隔五分钟执行检查点,并且检查点需要 30 秒完成。我们通过查看消息日志文件来获得这一信息。

首先,计算:
(60 分钟/小时) / (1 检查点/5 分钟) = 12 检查点/小时
12 检查点/小时 * 30 秒(持续时间) = 6 分钟/小时(检查点持续时间)。

这相当于数据库引擎有 10% 的空闲时间,它正每小时花六分钟将页从缓冲区高速缓存写到磁盘。在这段时间,您的用户不能做很多事情。在八小时轮班期间,每个用户有 48 分钟的时间在等待系统(相当于一天 80 个人时的损失)。试着向人力资源部说明这一点。

让我们从 Informix 方面来诊断这个问题。首先,使用 onstat -F确定正在执行什么类型的写操作。这将显示块、LRU 或前台写操作是否出现得最多。在活动的 OLTP 系统中最好是 LRU 写操作多于块写操作。输出将与下面相似:


Fg Writes LRU Writes Chunk Writes
0 0 2189
address flusher state data
c0408444 0 I 0 = 0X0
states: Exit Idle Chunk Lru

下一步是确定 LRU MIN 和 MAX DIRTY 参数的设置值。可在 onconfig 文件中查找或使用 onstat -c来找到它们的值。


LRUS 8 # Number of LRU queues
LRU_MAX_DIRTY 60 # LRU percent dirty begin cleaning limit
LRU_MIN_DIRTY 50 # LRU percent dirty end cleaning limit

以上的参数对于 OLTP 系统似乎太高(请参阅下面的“用于 DSS 系统的检查点调优”一节)。在接近或达到检查点时间时用 onstat -bonstat -R选项观察系统。这两个输出都将显示缓冲区高速缓存中已修改页和未修改页的数目。当检查点出现时,头信息将显示 CKPT REQ。为了充分了解已修改页的平均数目在系统中所占的百分比,需要在一段时间内对该信息进行观察。

如果已修改页的百分比小于 LRU MAX DIRTY 百分比,则引擎没有进行 LRU 写操作。所有写操作都在检查点时间发生。

onstat -R输出:


8 buffer LRU queue pairs
# f/m length % of pair total
0 F 153 83.2% 184
1 m 31 16.8%
2 f 148 81.3% 182
3 m 34 18.7%
4 f 152 81.3% 187
5 m 35 18.7%
6 f 146 79.3% 184
7 m 38 20.7%
8 f 151 82.5% 183
9 m 32 17.5%
10 f 144 79.1% 182
11 m 38 20.9%
12 f 145 78.8% 184
13 m 39 21.2%
14 f 150 80.6% 186
15 m 36 19.4%
283 dirty, 1472 queued, 1500 total, 2048 hash buckets, 2048 buffer size
start clean at 60% (of pair total) dirty, or 112 buffs dirty, stop at 50%

为了缩短检查点持续时间,我们需要减少 检查点时间写操作的数目。我们观察到 LRU 队列在接近检查点时间时 20% 为“脏的”。如果将 LRU MAX DIRTY 参数改为 10%,将 LRU MIN DIRTY 参数改为 5%,则我们应看到在检查点之间出现的写操作的页是在检查点时间进行写操作的页的一半。在检查点时间使用 onstat -bonstat -R再次做出更改并观察缓冲区高速缓存。

如果已修改页的数目停留在 LRU MAX DIRTY 参数之上,则需要检查其它方面。您要确保以下几点:

  • 使用 sariostat确保磁盘驱动器没有饱和
  • 使用 sar确保 CPU 没有饱和
  • 使用 onstat -g ioq确保 AIO VP 没有饱和
  • 确保有足够的页清除程序

如果其它方面都没有问题,则需添加更多页清除程序。

一旦已修改缓冲区的数目保持在 LRU MAX DIRTY 以下或接近它,请再次查看检查点的持续时间。如果正在被写出的页的数目是更改前的页数目的一半,则检查点持续时间应大约是原来的一半;在本示例中,应从 30 秒改为 15 秒。

现在我们来研究检查点时间间隔。检查点间的时间间隔用于恢复时间的计算。时间间隔越长,在电源错误等情况下恢复所需的时间就(可能)越长。五分钟似乎过于频繁。让我们把它增加到 15 分钟。尽管这对于快速恢复仍是一段合理的时间,但让我们看看它在检查点时间的表现:

检查点时间间隔:15 分钟(每小时四个检查点)
检查点持续时间:15 秒
总消耗时间:1 分钟/小时(空闲时间占 1.6%,而最初是 10%)

可 以进一步降低 LRU MAX 和 MIN DIRTY 参数,以便在检查点有更小的持续时间。将 LRU MAX DIRTY 减少到 2%,将 LRU MIN DIRTY 减少到 1%,可以将检查点持续时间降到最低。但是,还需要足够的页清除程序、LRU 队列、AIO VP、驱动器控制器和物理磁盘驱动器才能使检查点持续时间低于两秒。

检查点时间间隔:15 分钟(每小时四个检查点)
检查点持续时间:两秒
总消耗时间:8 秒/小时(空闲时间占 0.2%,而最初是 10%)

权衡方法是因为 LRU MIN 和 MAX DIRTY 参数降低,所以整体 I/O 效率降低。然而,应继续减少检查点持续时间,减少的数量基于您特定的应用程序和配置。无论如何,权衡方法应公平地平衡减少的 I/O 速率与检查点之间的用户响应时间。

用户的感觉是一个重要因素。如果系统整体上完成了相同数量或稍多一点的工作,但用户感觉到的停滞时间较少,那么他们就很高兴。如果用户高兴了,那么系统就已调优好。





回页首


决策支持系统(DSS)检查点调优比 OLTP 检查点调优稍稍容易一些。DSS 系统往往有以下特征:

  • 对数据的访问是连续的
  • 数据通常是只读的
  • 所读取的行数通常是表的大部分或全部行
  • 快速恢复时间并不重要,因为对数据的修改很少
  • 常常不考虑检查点持续时间,因为查询会在一段延长的时间内运行

有 了决策支持系统,您会希望使磁盘驱动器头持续读,而不希望出现干扰的写操作。因此,您要使块写操作最大化,而使检查点的数目最小化。让检查点在每小时出现 可能是较好的时间间隔。让所有的写操作在检查点时间出现需要将 LRU MIN 和 MAX DIRTY 参数都设置得较高(分别为 50% 和 60%)。

在主要的系统事件(如索引构建、数据装入或者批量更新或删除)之后一定要执行手工检查点。这在这些事件之一失败的情况下能防止恢复时间延长。





回页首


以下是性能调优练习,使用的是 Wisconsin 基准数据库和数据。

  • Informix Dynamic Server(7.x)
  • 用于 dbspaces的 50 MB 磁盘空间
  • 20 MB 共享内存
  • 通过共享内存与五位用户的连接
  • 运行练习的脚本和程序:
    • wisc.sql创建带索引的数据库
    • load_data装入合适数量的数据(大约 16 MB)
    • start_all启动五个模拟的 OLTP 用户
    • kill_all停止所有用户并给出运行统计信息
    • oltp.ec模拟 OLTP 用户的 ESQL/C 程序
    • load_tab.ec生成并装入数据的 ESQL/C 程序
    • compile编译 ESQL/C 程序

使用缺省参数创建联机引擎(复制 onconfig.std)。更改 rootdbs路径并初始化系统。通过 dbaccess运行 wisc.sql,从而创建 Wisconsin 数据库。

运行 compile以编译 oltp.ec 和 load_tab.ec 程序。通过运行 load_data装入用于仿真的所有数据。

运行 start_all。这将启动仿真。在某个时间(两个检查点)监控系统 10 分钟,然后用 kill_all停止它。记录 kill_all 的统计信息。这些信息是运行用去的时间和用户在 oltp.ec 程序中能够完成的循环次数。

在仿真期间,请观察以下内容:

  • 读高速缓存的百分比
  • 脏缓冲区百分比
  • 写操作类型
  • 页清除程序活动
  • 物理日志利用率
  • 检查点时间间隔
  • 检查点持续时间

并调优以下参数:

  • 缓冲区
  • 物理日志大小
  • 检查点时间间隔
  • AIO VP
  • 页清除程序
  • LRU MIN 和 MAX DIRTY
  • LRU 队列

直到符合下面的最终用户需求:

  • 读高速缓存百分比占 98% 或更多
  • 检查点时间间隔为五分钟
  • 检查点持续时间为两秒或更少

以下结果是使用 HP9000 G30 1 CPU 获得的。

第一次运行
初始参数的结果的基线:

缓冲区 1500
LRU MIN50
LRU MAX60
检查点时间间隔300
物理日志大小1000
页清除程序1
AIO VP6
LRU 队列8
结果
读高速缓存96.94%
检查点时间间隔45 秒
检查点持续时间4 秒
占用时间8:59
循环次数4664

第二次运行
增加缓冲区以使读高速缓存达到 98% 或更高。使用 onstat -p观察缓冲区读高速缓存。

缓冲区 5000
LRU MIN50
LRU MAX60
检查点时间间隔300
物理日志大小1000
页清除程序1
AIO VP6
LRU 队列8
结果
读高速缓存99.20%
检查点时间间隔45 秒
检查点持续时间4 秒
占用时间10:18
循环次数5942

第三次运行
增加物理日志文件的大小以获得 5 分钟的检查点时间间隔。在五分钟的时间间隔完毕以前,物理日志填充了 75%。使用 onstat -l进行观察。

缓冲区 5000
LRU MIN50
LRU MAX60
检查点时间间隔300
物理日志大小10000
页清除程序1
AIO VP6
LRU 队列8
结果
读高速缓存99.35%
检查点时间间隔5 分钟
检查点持续时间16 秒
占用时间9:45
循环次数6382


减少 LRU MIN 和 MAX DIRTY 以获得检查点间的 LRU 写操作。使用 onstat -F观察 LRU 写操作与块写操作。

缓冲区 5000
LRU MIN5
LRU MAX10
检查点时间间隔300
物理日志大小10000
页清除程序1
AIO VP6
LRU 队列8
结果
读高速缓存99.23%
检查点时间间隔5 分钟
检查点持续时间14 秒
占用时间10:08
循环次数6104

第五次运行
增加页清除程序的数目以对 LRU 写操作提出写请求。持续时间没有较大改变。页清除程序不能完成足够的工作。请添加更多页清除程序。使用 onstat -F查看页清除程序活动,并使用 onstat -R观察它们的效率。请确保脏页所占的百分比低于 LRU MAX DIRTY。

缓冲区 5000
LRU MIN5
LRU MAX10
检查点时间间隔300
物理日志大小10000
页清除程序6
AIO VP6
LRU 队列8
结果
读高速缓存98.88%
检查点时间间隔5 分钟
检查点持续时间4 秒
占用时间10:08
循环次数5786


进一步减少 LRU MIN 和 MAX DIRTY 以达到两秒的检查点持续时间。

缓冲区 5000
LRU MIN1
LRU MAX3
检查点时间间隔300
物理日志大小10000
页清除程序6
AIO VP6
LRU 队列8
结果
读高速缓存98.73%
检查点时间间隔5 分钟
检查点持续时间2 秒
占用时间9:59
循环次数5570


比较运行

Timeouts/Hour 表示在检查点出现时一小时内用户线程所经历的暂挂时间的总量。

Loops/Sec 表示仿真运行期间的系统性能(或吞吐量)。这是一秒钟内 oltp.ec 程序中执行的循环次数。

我 们从这些结果可以看出,在总吞吐量上有一些系统性能的损失。但是,用户感觉到的停止时间也大大缩短。用户可能不会注意到每秒内循环的八分之一的减少,但他 们会注意到按下回车键时 16 秒的暂停。对于系统级别上调优得更好的引擎,较长的时间间隔和稍长一点的持续时间并且有较少的页清除程序会更好(正如以上的 第四次运行,其中有三个页清除程序和 15 分钟的时间间隔)。但是,根据该练习的目标, 第六次运行提供了我们需要的结果。





回页首


需要针对每个系统的特定使用情况和用户来调优系统。既然您理解了调优检查点的过程,就可以按照要实现的目标来适当地调优系统。





回页首






回页首



Geoffrey Bergren has authored this article

阅读(1256) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~