WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: DB2/Informix
2012-03-25 10:59:01
DB2 9.7:临时表压缩
简介: 压缩是 DB2 的一个重要特性,但临时表压缩可能是压缩家族中容易被人忽视的一个。本文介绍了 DB2 V9.7 版本中的临时表压缩的基本原理和监控方法,为用户揭开临时表压缩的神秘面纱,给使用临时表压缩的用户提供了参考和借鉴。
前言
DB2 LUW 从 9.1 版本开始为用户提供了一种简单方便的压缩技术,行压缩,用来对磁盘数据进行压缩。9.5 版本增强了行压缩技术,使用户可以在避免离线重组(offline reorg)的同时对数据进行压缩,我们称这种压缩技术为 Automatic Dictionary Creation(ADC)。DB2 V9.7 扩展了行压缩技术的适用范围,使得临时表上的数据也可以被压缩。
临时表包括系统临时表和用户临时表。系统临时表是由数据库系统创建的,对用户来说是不可见的,主要用于数据库在排序或连接时存放临时数据。用户临时表包括已创建的全局临时表(CREATE GLOBAL TEMPORARY TABLE,CGTT)和已声明的全局临时表(DECLARE GLOBAL TEMPORARY TABLE,DGTT)。CGTT 与 DGTT 之间的主要差异在于 CGTT 的定义是持久存储在 DB2 目录下的,而 DGTT 在创建后仅在用户会话(session)期间保存。当使用 DGTT 的应用程序终止或者断开数据库的时候,DGTT 里的数据被删除,该表也会被隐式的删除。CGTT 在会话中创建并且在会话终止后仍然持久保存。CGTT 的定义由所有并发会话共享,即使其内容是各会话所私有的。
那么临时表压缩究竟如何工作;如何启用临时表压缩;需要何种方法去监控临时表压缩的信息?本文分析了临时表压缩的基本原理和启用压缩的限制条件,并通过实验详细阐述了如何应用 db2pd 命令来监控临时表压缩信息。
临时表压缩介绍
减少存储开销是企业用户在降低成本,提高效率方面需要考虑的。对存储在磁盘上的数据进行压缩成为大家广为采用的方法。磁盘上的数据可以是永久存储的,也可以是为了存放应用程序执行过程中所产生的中间数据而临时存储的。在 DB2 V9.7 以前的数据库版本中,我们已经有了一些对永久表进行压缩的方法;从 9.7 版本开始,临时表压缩的算法也被引入。
对临时表进行压缩并没有采用新的技术,它使用和行压缩相同的算法。也就是说扩大了行压缩算法支持的范围。由于 ADC 也是行压缩算法的一种改进,所以同样也适用于临时表压缩。一旦用户使用了包含行压缩特性的数据库版本,不需要用户特别指定,压缩特性便会自动应用于临时表。
临时表的生存时间都非常短,仅仅存在于一个事务(也称为工作单元,unit of work,UOW)的执行过程中,所以压缩数据所使用的压缩字典不会被写入日至或者被永久存储。这种策略减少了压缩的一些额外负担,但同时也会有一些副作用:如果一个查询在不同的 UOW 中被执行了很多次,那么每一次都需要重新建立一个压缩字典。
临时表压缩的主要目的在于通过减少临时磁盘空间的使用量来降低存储开销;同时还要求不能对系统的性能带来很大影响。为了达到这个目的,临时表压缩仅仅在临时表足够大,磁盘 I/O 的节省可以抵消压缩的额外开销时才会被应用。为了更加有效的使用临时表压缩,数据库管理器不会对所有的临时表都进行压缩。如果一些临时表中的记录长度非常短,比如(RID sort),那么系统不会从压缩带来好处,该临时表也就不会被压缩。同时临时表压缩只会对存储在磁盘上的数据进行压缩,也就是说如果临时表的数据没有被写入磁盘,那么即使数据量足够大,临时表压缩也不会被启用。
下面我们来具体的看一下使用临时表压缩到底要满足哪些限制条件。
临时表压缩的限定条件
当用户执行某个 SQL 语句时,DB2 优化器首先会估算哪些临时表能够节省存储空间、并且能够提高性能。如果某个临时表能够带来性能的提升,那么该临时表就会成为“候选”表。此时该临时表不会被马上压缩,只有当插入足够多的数据时才会触发压缩。
系统临时表和用户临时表选择“候选”表的条件不同。系统临时表要考虑如下几方面内容:
1 查询的类型。目前系统临时表压缩支持 sort,table queues,XML 等查询类型
2 记录的最小长度。从压缩的实际效果考虑,系统临时表中的记录长度必须大于 20 字节才会被考虑压缩。
3 表的期望大小。触发临时表压缩要求指定的表中有足够多的数据。DB2 优化器会根据查询类型对临时表的大小进行估算:如果能够估算出表的大小,那么会将其与系统设定的最小值进行比较以决定是否使用压缩;如果优化器无法估算出表的大小,那么 DB2 优化器将忽略此项。
用户临时表的触发条件比较简单,只需要满足记录的最小长度限制就可以成为“候选”表。
由于临时表压缩采用和行压缩相同的算法,所以“候选”临时表的数据必须超过指定的阈值才可以建立压缩字典。DB2 V9.5 的 ADC 技术需要至少 2 兆数据用来建立压缩字典。临时表压缩也同样需要使用磁盘上的 2 兆数据作为样本来建立压缩字典。
监控临时表压缩
在 DB2 V9.7 中,db2pd 被用来监控临时表压缩的信息:temptable 作为一个新的选项被用来显示临时表压缩的历史信息;两个其他选项,tablespaces ,tcbstats 被用来显示一些额外的信息。
下面我们结合一个具体的实例来讲解以上三个参数如何使用以及如何从结果数据中得到我们希望的信息。
准备工作
我们使用的测试数据有 2000000 条记录,每条记录的长度大概 150 字节,由 5 列组成;总共有将近 300 兆字节的数据。
清单 1. 临时表压缩所使用的数据
=> wc -l loaddata.del 2000000 loaddata.del
=> ls -l loaddata.del -rw-r--r-- 1 lizhoubj pdxdb2 299800002 2011-10-27 20:33 loaddata.del
=> head -5 loaddata.del vlcometghiqvvfumhvgvkkeayttdwjwutdkxtjttfakhugfwiqabcaefjml,99,vijr,1, abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
avykvfrywdeuutwgvrddymethqnfnekpqhwrigywokovnfcgpsumuvruajl,99,sanm,1, abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
nrboldhdytkitubkylepqkdatjtxusoglmtrpisdppbprnqstjcucisbilt,86,sayc,4, abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
allkbvfwtcofvdpkyywqxxogkaqubokxaqmggfyseoogtjfqvgqjcylefdd,21,hemi,5, abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
xvaoprfokbsoeortxfeuigiksbquotccgxpjeqxihrwwusmqhkdsncbegus,86,ccep,4, abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz |
下面我们创建一个 DGTT,并插入 2000000 条记录。
清单 2. 创建临时表并插入数据
数据库初始化的时候并不会创建默认的临时表空间,所以用户在使用全局临时表时,必须创建一个用户临时表空间。 1)创建全局临时表空间
创建一个 16k 页大小的自动存储类型的数据库: create database paylesst automatic storage yes on /home/lizhoubj/temptable using codeset utf-8 territory us pagesize 16 K DB20000I The CREATE DATABASE command completed successfully.
connect to paylesst
Database Connection Information
Database server = DB2/LINUXX8664 9.7.0 SQL authorization ID = LIZHOUBJ Local database alias = PAYLESST
创建一个含有 500 个 16K 页大小的缓冲区 bp16k: CREATE BUFFERPOOL bp16k SIZE 500 PAGESIZE 16K DB20000I The SQL command completed successfully.
创建一个页大小为 16K 字节的 DMS 类型的全局临时表空间 CREATE USER TEMPORARY TABLESPACE usr_tbsp PAGESIZE 16K MANAGED BY DATABASE USING (FILE '/home/lizhoubj/temptable/tbsp' 50000) PREFETCHSIZE 16K BUFFERPOOL bp16k DB20000I The SQL command completed successfully.
2)声明全局临时表: DECLARE GLOBAL TEMPORARY TABLE SESSION.TEST_TEMP ( COL1 VARCHAR(64), COL2 INTEGER, COL3 VARCHAR(64), COL4 INTEGER, COL5 VARCHAR(256) ) IN usr_tbsp ; DB20000I The SQL command completed successfully.
3)声明一个永久表,并 Load 2 百万条记录到永久表内: CREATE TABLE TEST ( COL1 VARCHAR(64), COL2 INTEGER, COL3 VARCHAR(64), COL4 INTEGER, COL5 VARCHAR(256) ) ; DB20000I The SQL command completed successfully.
LOAD FROM /home/lizhoubj/temptable/loaddata.del OF DEL INSERT INTO TEST;
4)把数据从永久表中读出并插入临时表: INSERT INTO SESSION.TEST_TEMP SELECT * FROM TEST; DB20000I The SQL command completed successfully. |
到此为止我们已经完成对临时表的操作,临时表的压缩信息也已经存储在系统内存中。下面我们通过 db2pd 的 3 个参数来说明如何获取临时表压缩信息。
新参数:– temptable
现在我们执行下面的语句来获取临时表的压缩信息:
清单 3. db2pd – temptable 的输出结果
db2pd -db paylesst -temptable System Temp Table Stats: Number of System Temp Tables : 0 Comp Eligible Sys Temps : 0 Compressed Sys Temps : 0 Total Sys Temp Bytes Stored : 0 Total Sys Temp Bytes Saved : 0 Total Sys Temp Compressed Rows : 0 Total Sys Temp Table Rows: : 0
User Temp Table Stats: Number of User Temp Tables : 1 Comp Eligible User Temps : 1 Compressed User Temps : 1 Total User Temp Bytes Stored : 92406045 Total User Temp Bytes Saved : 247641431 Total User Temp Compressed Rows : 1988131 Total User Temp Table Rows: : 2000000 |
为了更加方便的理解以上输出的含义,我们把每行输出的解释汇集成如下表格:
表 1. db2pd – temptable 输出结果的含义
名词 |
定义 |
Number of Temp Tables |
临时表的数量 |
Comp Eligible Temps |
数据库管理器认为适合压缩的“候选”临时表数量 |
Compressed Temps |
实际上被压缩的临时表 |
Total Temp Bytes Stored |
存储在磁盘上数据的字节数。这些数据可能来自被压缩的临时表也可能来自未被压缩的临时表 |
Total Bytes Saved |
压缩临时表所节省的字节数 |
Total Compressed Rows |
所有被压缩过的记录的总数 |
Total Temp Table Rows |
插入到临时表的记录总数。这些临时表可以是被压缩的,也可以是没有压缩的 |
值得注意的是结果数据是一个累计的值,它们反映的是自数据库启动以来数据的总和。此外上述的结果数据是一个历史值,也就是仅仅当临时表被删除以后,db2pd -temptable 的输出结果才会被更新。如果想得到当前仍然活跃的临时表压缩信息,需要使用 db2pd 的 tcbstats 参数来获得。我们将在后面的内容中讨论 tcbstats 参数。
因为我们所建立的临时表为 DGTT,在使用 db2pd 命令之前该表已经被删除,所以从 db2pd -temptable 的输出结果中可以看到该 DGTT 表的压缩信息。
通过清单 3,我们可以看到有 1 个临时表被压缩;在总共 2 百万条记录中,有将近 199 万条记录被压缩。我们可以通过以下公式计算出临时表的压缩效果:
% Compression = ( Total Bytes Saved ) / ( Total Bytes Saved + Total Stored Temp Bytes )
在上述实例中我们总共节省了 247641431/(247641431+92406045)=72.8% 的磁盘空间。
修改的参数:– tablespaces
db2pd 在“tablespaces”参数的输出中增加了“Max HWM”列,用来指示自实例启动以来最大的高水位数。此选项仅仅对 DMS 类型的表空间有效。“HWM”列表示当前临时表所需要的磁盘空间,而“Max HWM”显示的是此表空间所使用过的最大的磁盘空间。
清单 4. db2pd – tablespaces 的输出结果
db2pd -db paylesst -tablespaces
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 00:04:41 – Date 10/27/2011 20:44:37
Tablespace Configuration: Address Id Type Content PageSz ExtentSz Auto Prefetch BufID BufIDDisk FSC NumCntrs MaxStripe LastConsecPg Name 0x00002AE2CBFDB380 0 DMS Regular 16384 4 Yes 4 1 1 Off 1 0 3 SYSCATSPACE 0x00002AE2CC018740 1 SMS SysTmp 16384 32 Yes 32 1 1 On 1 0 31 TEMPSPACE1 0x00002AE2CC023BC0 2 DMS Large 16384 32 Yes 32 1 1 Off 1 0 31 USERSPACE1 0x00002AE2CC02CF40 3 DMS Large 16384 4 Yes 4 1 1 Off 1 0 3 SYSTOOLSPACE 0x00002AE30ED0AFC0 4 DMS UsrTmp 16384 32 No 1 2 2 Off 1 0 31 USR_TBSP
Tablespace Statistics: Address Id TotalPgs UsablePgs UsedPgs PndFreePgs FreePgs HWM Max HWM State MinRecTime NQuiescers PathsDropped 0x00002AE2CBFDB380 0 9536 9532 9480 0 52 9480 9480 0x00000000 0 0 No 0x00002AE2CC018740 1 1 1 1 0 0 0 0 0x00000000 0 0 No 0x00002AE2CC023BC0 2 33728 33696 33696 0 0 33696 33696 0x00000000 0 0 No 0x00002AE2CC02CF40 3 128 124 88 0 36 88 88 0x00000000 0 0 No 0x00002AE30ED0AFC0 4 50000 49952 6016 0 43936 6016 6016 0x00000000 0 0 No |
修改的参数:-tcbstats
我们在应用 tcbstats 参数的输出结果中增加了三列:
1 SchemaNm – 表的 schema 名字。
2 StoredBytes – 此项和 db2pd – temptable 输出的“Total stored temp bytes”一致,表示存储在磁盘上数据的字节数 .
3 BytesSaved – 此项和 db2pd – temptable 输出的“Total bytes saved”相同,表示压缩临时表所节省的字节数。
通过 temptable 参数的介绍我们知道应用 tcbstats 参数可以用来显示当前仍然活跃的临时表的压缩信息。为了更好的说明此参数的用法,我们将在临时表操作过程中和操作完成后执行此 db2pd – tcbstats,看看应用此参数会有什么样的结果变化。
清单 5. 在临时表操作过程中 db2pd – tcbstats 的输出结果
我们在运行清单 2 第 4 步操作过程中反复执行以下命令
第一次运行: => db2pd -db paylesst -tcbstats tbspaceid=4
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 00:00:33 – Date 10/28/2011 11:01:40
TCB Table Information: Address TbspaceID TableID PartID MasterTbs MasterTab TableName SchemaNm ObjClass DataSize LfSize LobSize XMLSize 0x00002B96BF3113C0 4 2 n/a 4 2 TEST_TEMP SESSION Temp 431 0 0 0
TCB Table Stats: Address TableName SchemaNm Scans UDI RTSUDI PgReorgs NoChgUpdts Reads FscrUpdates Inserts Updates Deletes OvFlReads OvFlCrtes PgDictsCrt CCLogReads StoreBytes BytesSaved 0x00002B96BF3113C0 TEST_TEMP SESSION 1 0 115298 0 0 11869 0 115298 0 0 0 0 0 0 6767674 12880462
第二次运行:
=> db2pd -db paylesst -tcbstats tbspaceid=4
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 00:00:52 – Date 10/28/2011 11:01:59
TCB Table Information: Address TbspaceID TableID PartID MasterTbs MasterTab TableName SchemaNm ObjClass DataSize LfSize LobSize XMLSize 0x00002B96BF3113C0 4 2 n/a 4 2 TEST_TEMP SESSION Temp 1543 0 0 0
TCB Table Stats: Address TableName SchemaNm Scans UDI RTSUDI PgReorgs NoChgUpdts Reads FscrUpdates Inserts Updates Deletes OvFlReads OvFlCrtes PgDictsCrt CCLogReads StoreBytes BytesSaved 0x00002B96BF3113C0 TEST_TEMP SESSION 1 0 497272 0 0 11869 0 497272 0 0 0 0 0 0 24116467 60467249
第三次运行:
=> db2pd -db paylesst -tcbstats tbspaceid=4
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 00:01:27 – Date 10/28/2011 11:02:34
TCB Table Information: Address TbspaceID TableID PartID MasterTbs MasterTab TableName SchemaNm ObjClass DataSize LfSize LobSize XMLSize 0x00002B96BF3113C0 4 2 n/a 4 2 TEST_TEMP SESSION Temp 3525 0 0 0
TCB Table Stats: Address TableName SchemaNm Scans UDI RTSUDI PgReorgs NoChgUpdts Reads FscrUpdates Inserts Updates Deletes OvFlReads OvFlCrtes PgDictsCrt CCLogReads StoreBytes BytesSaved 0x00002B96BF3113C0 TEST_TEMP SESSION 1 0 1178211 0 0 11869 0 1178211 0 0 0 0 0 0 55056791 145286555
第四次运行:
=> db2pd -db paylesst -tcbstats tbspaceid=4
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 00:01:53 – Date 10/28/2011 11:03:00
TCB Table Information: Address TbspaceID TableID PartID MasterTbs MasterTab TableName SchemaNm ObjClass DataSize LfSize LobSize XMLSize 0x00002B96BF3113C0 4 2 n/a 4 2 TEST_TEMP SESSION Temp 5021 0 0 0
TCB Table Stats: Address TableName SchemaNm Scans UDI RTSUDI PgReorgs NoChgUpdts Reads FscrUpdates Inserts Updates Deletes OvFlReads OvFlCrtes PgDictsCrt CCLogReads StoreBytes BytesSaved 0x00002B96BF3113C0 TEST_TEMP SESSION 1 0 1691743 0 0 11869 0 1691743 0 0 0 0 0 0 78393405 209250381 |
清单 6. 完成临时表操作之后 db2pd – tcbstats 的输出结果
=> db2pd -db paylesst -tcbstats tbspaceid=4
Database Member 0 -- Database PAYLESST -- Active -- Up 0 days 14:15:39 – Date 10/28/2011 10:55:36
TCB Table Information: Address TbspaceID TableID PartID MasterTbs MasterTab TableName SchemaNm ObjClass DataSize LfSize LobSize XMLSize 0x00002AE31005A540 4 2 n/a 4 2 TEST_TEMP SESSION Temp 1 0 0 0
TCB Table Stats: Address TableName SchemaNm Scans UDI RTSUDI PgReorgs NoChgUpdts Reads FscrUpdates Inserts Updates Deletes OvFlReads OvFlCrtes PgDictsCrt CCLogReads StoreBytes BytesSaved 0x00002AE31005A540 TEST_TEMP SESSION 2 0 2000000 0 0 11869 0 2000000 0 0 0 0 0 0 0 0 |
从清单 5 和清单 6 中我们可以看出 db2pd -tcbstats 可以显示活跃的临时表的压缩信息;而一旦临时表被删除,那么结果中的临时表压缩信息将被清空。
总结
临时表压缩在用户使用临时表的过程中发挥了很大的作用,它可以应用在系统临时表和用户临时表,并且可以得到和永久表一样的压缩效果。但并不是所有的临时表都可以被压缩,只有那些记录比较长,数据量足够大的临时表才会被压缩。临时表压缩仅仅会压缩磁盘上的数据,缓存中的数据不会被压缩。
我们通过 db2pd -temptable 命令可以有效的监控临时表压缩的历史信息;通过 db2pd -tcbstats 命令可以监控活跃的临时表的压缩信息。
http://www.ibm.com/developerworks/cn/data/library/techarticle/dm-1203zhoul/index.html