简介
分段存储是 Informix® Dynamic Server™ 版本 7 及以后版本的新特性。
如果使用得当,它将极大提高整个 Informix Dynamic Server 的性能;但如果使用时粗心大意,它可能会给性能带来负面影响。本文将详细讨论并分析一个分段存储案例,并提供有关如何为 Informix Dynamic Server 规划和设计优秀分段存储策略的通用技巧。
本文将讨论:
分段存储:它的优点和局限性 案例研究 测试和结论
分段存储:它的优点和局限性
分段存储是一种将数据库表和索引巧妙地划分成更小单位(叫作“分段表”)的方法;每个分段表都是表或索引中的一组行或索引键。用于分段存储的算法叫作“分布模式”。Informix Dynamic Server 支持两种分布模式,轮循和基于表达式的分布模式。这两种分布模式可以通过 CREATE TABLE 和 CREATE INDEX SQL 语句(请参考 Informix Guide to SQL: Syntax 以获取更多详细信息)实现。轮循分布模式使用 Informix Dynamic Server 内部定义的规则将表分段存储。而基于表达式的分布模式则使用用户定义的规则将表和索引分段存储。它比轮循分布模式更灵活;用户可以定义自己的规则,如逻辑比较规则、散列规则或其它任意的规则。
Informix Dynamic Server 利用分段存储可以将每个分段表与单独的物理磁盘设备相关联,也就是说,Informix Dynamic Server 可以将完整的表或索引中的数据分散到多个磁盘上。
其想法是均衡磁盘 I/O 并使吞吐量最大化。这从许多方面改进了 Informix Dynamic Server 性能,其中一些包括:
更好的用户响应时间 “用户响应时间”的定义是对数据库表执行查询所使用的时间。如果 Informix Dynamic Server 可以并行处理查询,那么就可以改进响应时间。由于分段存储将一个表的数据分散到多个磁盘设备上,所以 Informix Dynamic Server 就可以在需要同时处理来自不同磁盘设备的多个查询时分配多个线程。这将极大改进用户响应时间,尤其是在与 Informix Dynamic Server 并行数据库查询机制共同使用时。
更好的并发性 “并发性”是指 Informix Dynamic Server 同时处理对同一个表的多个查询的能力。并发性控制对于那些可能有许多用户同时访问同一表的 OLTP 系统来说是一个重要问题。如果 Informix Dynamic Server 将一个表的所有数据都存储在同一个磁盘上,那么可能会发生争用。由于分段存储将表的数据分散到多个磁盘设备上,Informix Dynamic Server 能够同时扫描和检索存储在不同磁盘上的同一个表中的不同数据。这当然会减少访问同一个表中的数据所产生的争用。
更好的可用性 当把表和索引分段表分布到多个磁盘时,您还改进了磁盘发生故障期间的数据可用性。例如,如果一个磁盘坏掉了,那么该磁盘上的分段表就变成了不可用的,而其它磁盘上的分段表仍是好的,并且可供访问。因此,仍然可以成功执行不需要坏分段表上的数据的查询。
更好且更快的备份与恢复 分段存储提供了更细的备份与恢复颗粒度;可以只恢复坏掉的分段表,这肯定会减少恢复操作所需的时间。通过使用 ON-Bar™ 实用程序可以进一步提高备份与恢复的性能,因为它使用了并行处理机制。
但是,分段存储确实还有一些局限性。查询的性能可能会随着分段表数量的增加而以线性方式增加,但是这依赖于物理 CPU 的数量、总线带宽和系统上的可用磁盘存储器资源。当规划分段存储策略时,我们需要对此有足够的重视,否则分段存储既不会有助于改进也不会损害(既不提高也不降低)Informix Dynamic Server 性能。下面这个示例很好地说明了粗心的分段存储策略会如何损害 Informix 引擎性能的。
案例研究
研究对象是跟踪手机用户信息的通信数据库。这个系统构建在带有有限硬件资源的 Sun Enterprise 3500 系统上。该机器只有两个低速 CPU 和 512 MB 的 RAM。CPU 和内存的规格如下:
========================= CPU ========================= Brd CPU Module Run MHz Ecache MB CPU Impl CPU Mask 7 14 0 336 4.0 UltraSPARC-II 2.0 9 18 0 336 4.0 UltraSPARC-II 2.0 ========================= Memory ========================= Brd Bank MB Status Conditio Speed Intrlv Factor Intrlv With 7 0 256 Active OK 60ns 2-way A 9 0 256 Active OK 60ns 2-way A
系统有六个 9 GB 磁盘,它们都相互镜像;也就是说,我们只把数据写到三个磁盘上,其余三个磁盘用于镜像。数据库非常小;只有 2 GB 的数据。数据库有 130 个表,其中 66 个被分段存储。所有分段存储的表都使用相同的基于表达式的分布模式,此模式根据 mod 函数将表的数据分成 20 个分段表。以下就是这个分布模式:
按表达式分段存储 (mod(workspace_id , 20 ) = 0 ) in airgen_vers0_dbs , (mod(workspace_id , 20 ) = 1 ) in airgen_vers1_dbs , (mod(workspace_id , 20 ) = 2 ) in airgen_vers2_dbs , (mod(workspace_id , 20 ) = 3 ) in airgen_vers3_dbs , (mod(workspace_id , 20 ) = 4 ) in airgen_vers4_dbs , (mod(workspace_id , 20 ) = 5 ) in airgen_vers5_dbs , (mod(workspace_id , 20 ) = 6 ) in airgen_vers6_dbs , (mod(workspace_id , 20 ) = 7 ) in airgen_vers7_dbs , (mod(workspace_id , 20 ) = 8 ) in airgen_vers8_dbs , (mod(workspace_id , 20 ) = 9 ) in airgen_vers9_dbs , (mod(workspace_id , 20 ) = 10 ) in airgen_vers10_dbs , (mod(workspace_id , 20 ) = 11 ) in airgen_vers11_dbs , (mod(workspace_id , 20 ) = 12 ) in airgen_vers12_dbs , (mod(workspace_id , 20 ) = 13 ) in airgen_vers13_dbs , (mod(workspace_id , 20 ) = 14 ) in airgen_vers14_dbs , (mod(workspace_id , 20 ) = 15 ) in airgen_vers15_dbs , (mod(workspace_id , 20 ) = 16 ) in airgen_vers16_dbs , (mod(workspace_id , 20 ) = 17 ) in airgen_vers17_dbs , (mod(workspace_id , 20 ) = 18 ) in airgen_vers18_dbs , (mod(workspace_id , 20 ) = 19 ) in airgen_vers19_dbs
由于我更仔细地检查了系统,我发现被分段存储的表并不是巨大的表(有几百万行的表)。以下是被分段存储的表的清单,按大小(以字节为单位)以降序排序:
表 行数 行大小 总大小 ne 22414 212 4751768 cell 7368 302 2225136 neigh 44146 42 1854132 br 18682 64 1195648 srate 38934 30 1168020 ds 30204 28 845712 neline 12072 62 748464 acg 3546 194 687924 ccb 16848 34 572832 dlci 10782 38 409716 cha 12060 30 361800 bsclink 6604 38 250952 line 6036 38 229368 dlam 7338 27 198126 ilam 6434 27 173718 cellsp 5472 26 142272 bsccard 4250 33 140250 crnc 5472 25 136800 scib 3276 30 98280 pvc 3864 24 92736 msispa 3396 26 88296 acgline 3018 26 78468 freq 2514 30 75420 gpfunc 1016 27 27432 bsc 126 79 9954 bsccage 288 28 8064 xblcon 324 22 7128 dla 282 24 6768 omcxep 132 33 4356 rag 192 22 4224 mdg 24 103 2472 mdgglob 6 368 2208 cpxcdr 72 30 2160 omcxport 72 28 2016 ca 12 116 1392 bsctimer 6 230 1380 ila 86 15 1290 acgglob 6 204 1224 dapglob 6 200 1200 acgcpp 6 162 972 dap 6 158 948 mso 12 77 924 dapdsa 36 23 828 tz 12 68 816 dapclust 6 130 780 clussp 30 23 690 dsa 36 19 684 dapcpp 6 110 660 apd 12 54 648 apdport 36 18 648 pd 12 50 600 sp 0 20 600 dsac 24 24 576 iplink 24 24 576 cg 6 92 552 msorag 12 41 492 urba 6 71 426 bscglob 6 68 408 dappd 12 26 312 brglob 6 38 228 msc 12 19 228 clusterdomains 6 23 138 dapdomai 6 19 114 rnc 6 13 78 bscnail 0 31 0 cusalm 0 50 0
从以上的清单中,我们可以看到这些表都非常小;最大的一个也只不过 5 MB。只有六个表超过了 1 MB(大多数表都小于 100 KB),清单中的最后一些表几乎是空的。进一步调查显示了所有分段表都放在一个物理磁盘片上:
名称 文件名 airgen_vers0_dbs dblink1 airgen_vers1_dbs dblink1 airgen_vers2_dbs dblink1 airgen_vers3_dbs dblink1 airgen_vers4_dbs dblink1 airgen_vers5_dbs dblink1 airgen_vers6_dbs dblink1 airgen_vers7_dbs dblink1 airgen_vers8_dbs dblink1 airgen_vers9_dbs dblink1 airgen_vers10_dbs dblink1 airgen_vers11_dbs dblink1 airgen_vers12_dbs dblink1 airgen_vers13_dbs dblink1 airgen_vers14_dbs dblink1 airgen_vers15_dbs dblink1 airgen_vers16_dbs dblink1 airgen_vers17_dbs dblink1 airgen_vers18_dbs dblink1 airgen_vers19_dbs dblink1
如上所示,所有分段表都放在 dblink1 上,这是物理原始磁盘设备 c0t2d0s1 的符号链接。
根据以上的观察,我最初认为这种分段存储策略根本不会提高 Informix Dynamic Server 性能。实际上它给性能带来了负面影响。原因显而易见:当检索某个表中的数据时,Informix Dynamic Server 必须搜索 20 个不连续的数据库空间,而不是一个相连的区间,而且由于系统没有实现 Informix Dynamic Server 并行数据库查询(PDQ)机制,Informix Dynamic Server 必须串行执行所有那些搜索。我针对以下查询进行了测试,以验证这个假定是否正确:
select * from acg_8_0
acg_8_0 是构建在四个主表上的动态视图。以下是这个查询的执行计划:
Estimated Cost: 1826 Estimated # of Rows Returned: 236 1) root.acgglob: SEQUENTIAL SCAN (Serial, fragments: ALL) 2) root.acgcpp: INDEX PATH (1) Index Keys: workspace_id acgglob_inst (Serial, fragments: ALL) Lower Index Filter: (root.acgcpp.workspace_id = root.acgglob.workspace_id AND root.acgcpp.acgglob_inst = root.acgglob.acgglob_inst) 3) root.acg: INDEX PATH Filters: root.acg.preconfig_flag = 0 (1) Index Keys: workspace_id acgglob_inst (Serial, fragments: ALL) Lower Index Filter: (root.acg.workspace_id = root.acgglob.workspace_id AND root.acg.acgglob_inst = root.acgglob.acgglob_inst) 4) root.ne: INDEX PATH (1) Index Keys: workspace_id ne_inst (Serial, fragments: ALL) Lower Index Filter: (root.ne.workspace_id = root.acgglob.workspace_id AND root.ne.ne_inst = root.acg.acg_inst)
以上输出证明了 Informix Dynamic Server 并没有象预期那样得到分段存储的优势;它仍然搜索或扫描所有分段表来查找所需要的数据。实际上,这违背了分段存储的目的;分段存储的最终目标是通过直接访问包含所需数据的分段表来减少检索时间。
测试和结论
那么,消除表分段表会对性能有所帮助吗?会的。如果表没有分段,Informix Dynamic Server 就会在一个(而不是 20 个)数据库空间中搜索表的数据,这有助于提高检索数据的速度。而且,如果我们把一个表的所有数据都放在一个区间中,甚至还可以减少更多用于检索的时间,因为 Informix Dynamic Server 只可以扫描一个大的连续区间。
我们测试了我们的臆测。我们测量了在使用分段存储时应用程序的响应时间,然后在去掉了所有分段存储并且将许多小的表的区间合并成更少但更大的区间之后,再次测量这个时间。我们的测试产生了肯定的结果。下表概述了测试结果:
测试号 分段存储 无分段存储 差异 1 4 小时 30 分 2 小时 30 分 2 小时 2 4 小时 31 分 2 小时 33 分 1 小时 58 分 3 4 小时 35 分 2 小时 30 分 1 小时 55 分 4 4 小时 33 分 2 小时 32 分 1 小时 57 分 5 4 小时 40 分 2 小时 30 分 2 小时 10 分
如上表所示,在清除了表分段表和区间之后,响应时间明显改进了许多,大约超过了 50%。然后我们对生产系统应用了这个策略,性能得到了同样的改进。
从这个案例研究中我们可以学到什么呢?当规划分段存储时需要非常谨慎。从规划性能和分段存储的角度去考虑诸如 CPU、磁盘和内存之类的硬件资源。通常,分段存储有助于提高性能,因为它将 I/O 负载分散到多个磁盘上。但如果我们没有足够的硬件资源,它只会降低性能;在一个只有 2 个 CPU 的机器上将表分段存储成 20 个分段表肯定不是一个好的策略。而且,将所有分段表放在一个磁盘片上不会有助于分散磁盘 I/O 负载。实际上,这会使 Informix Dynamic Server 的检索过程更困难,因为它必须搜索所有 20 个分段表以查找它需要的数据,而不是一个数据库空间。
操作系统级别上的 RAID1 或条带划分也许是将 I/O 负载分散到可用磁盘的另一个选择。这也许适合于小的表(只有几千行的表),因为可以将这些小表保存在一个逻辑单元(数据库空间)中。性能指南和管理员指南向我们提供了规划和实现分段存储策略的一些好的准则。
关于作者 Jianing Fan 是摩托罗拉公司的软件工程师,专门研究关系数据库管理系统。他是 Informix 认证专家和 Oracle 认证专家,拥有 10 年以上的数据库和系统经验,曾经担任过开发人员、系统管理员和 DBA。Jianing 是 Tech Notes 忠实读者。可以通过 fan@eis.comm.mot.com 与 Jianing 联系。
| | |