表空间高水位:
创建一个DMS的表空间的最小大小是6个EXTENT。对于DMS表空间,可以从表空间中删除容器或缩小容器的大小。使用ALTER TABLESPACE语句来完成此操作。仅当该操作删除的扩展数据块的数目小于或等于表空间中的高水位标记之上的可用扩展数据块的数目时,才允许删除或缩小容器,就是说只能够删除还没有使用到的EXTENT。
高水位标记是表空间中分配的最高页的页数。例如:表空间有1000页,EXTENTSIZE为10,则有100个EXTENT。如果第42个EXTENT是表空间中最高分配的EXTENT,则意味着高水位标记是42*10=420页。
举个例子来说明高水位的作用:
(1)首先创建一个测试用的数据库管理的表空间(DMS),如下所示:
[db2inst1@bogon tmp]$ db2 "create tablespace usrtest managed by database using (FILE '/opt/rusrsp1' 64M)"
DB20000I The SQL command completed successfully.
然后使用list tablespace show detail 命令查看一下表空间的使用情况:
[db2inst1@bogon tmp]$ db2 list tablespaces show detail
Tablespaces for Current Database
Tablespace ID = 4
Name = USRTEST
Type = Database managed space
Contents = All permanent data. Large table space.
State = 0x0000
Detailed explanation:
Normal
Total pages (总计页数) = 16384
Useable pages (可用页数) = 16352
Used pages (已用页数) = 96
Free pages (未用页数) = 16256
High water mark (pages) 高水位标记(页) = 96
Page size (bytes) = 4096
Extent size (pages) (扩展数据块大小(页)) = 32
Prefetch size (pages) = 32
Number of containers = 1
从上面的输出中我们可以看到,表空间在刚刚创建完就已经有32页(16384-16352)即一个扩展块不可用,这部分对应容器保留开销扩展块的部分;有96页即3个扩展块已使用,这部分对应表空间保留开销部分。
接下来,使用db2dart命令加DHWM选项检查一下表空间的使用情况。注意,必须要在实例正常停止的情况下执行db2dart命令,否则可能导致数据库崩溃。
#命令说明:db2dart后面加数据库名,表示分析该数据库下的东西,/dhwm 导出高水位标记信息,需要一个输入项:/tsi 表空间ID。
[db2inst1@bogon tmp]$ db2dart mytest /dhwm /tsi 4
命令的执行结果:
Database Name: MYTEST
Report name: MYTEST.RPT
Old report back-up: MYTEST.BAK
Database Subdirectory: /home/db2inst1/db2inst1/NODE0000/SQL00004/MEMBER0000
Operational Mode: Database Inspection Only (INSPECT)
MYTEST.RPT位于执行命令时的目录下,本例中是 /tmp下,查看这个文件:
______________________________________________________________________________
------------------------------------------------------------------------------
Action option: DHWM
Tablespace-ID: 4
Creating the agent environment...
High water mark processing - phase start.
NOTES:
All high water mark values and/or object sizes listed below are given in extents and not pages (unless explicitly stated).**所有的高水位和对象大小都是以EXTENT为单位而不是page**
The object ID and object type are shown for each extent listed.每个EXTENT显示一个对象ID和对象类型。
Extents marked with an asterisk (*) hold the first page of an object and these extents can only be moved by dropping and recreating that object.*型号代表对象的第一个数据页,这些EXTENT只能通过删除或重建对象来移动。
After following a step and before continuing on to the next one,disconnect and reconnect to the database.
High water mark: 96 pages, 3 extents (extents #0 - 2)
[0000] 65534 0x0e [0001] 65534 0x0e [0002] 65535 0x00
Dump high water mark processing - phase start.
Number of free extents below high water mark: 0
Number of used extents below high water mark: 3
... ...
从上面的输出可以看到,刚创建完时,数据库管理表空间只有3个表空间保留开销扩展数据块:
High water mark: 96 pages, 3 extents (extents #0 - 2)
[0000] 65534 0x0e [0001] 65534 0x0e [0002] 65535 0x00
(2).现在,我们在该表空间中创建一张表:
[db2inst1@bogon Desktop]$ db2 "create table t1 (id int not null,name char(30)) in usrtest"
DB20000I The SQL command completed successfully.
#使用list tablespaces再次查看表空间的使用情况
[db2inst1@bogon Desktop]$ db2 list tablespaces show detail
Tablespaces for Current Database
Tablespace ID = 4
Name = USRTEST
Type = Database managed space
Contents = All permanent data. Large table space.
State = 0x0000
Detailed explanation:
Normal
Total pages = 16384
Useable pages = 16352
Used pages (已用页数) = 160
Free pages = 16192
High water mark (pages) (高水位标记) = 160
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1
相比前面的输出,表空间中已用的扩展块增加到5个(160页)。用db2dart加SHWM选项,再次分析该表空间的使用情况:
High water mark: 160 pages, 5 extents (extents #0 - 4)
[0000] 65534 0x0e [0001] 65534 0x0e [0002] 65535 0x00 [0003] 4 0x40* [0004] 4 0x00*
Dump high water mark processing - phase start.
Number of free extents below high water mark: 0
Number of used extents below high water mark: 5
相比于第一次的输出,多了第四个EXTENT[0003] 4 0x40*
和第五个EXTENT: [0004] 4 0x00*
现在我们来解释[0003] 4 0x40*的含义
[0003]代表EXTENT 3,[0003]后紧跟的4代表对象4,4后面的0x4代表该扩展块存储的是该对象的EXTENT使用情况即EMP;0x4后面的0代表存储的是数据,0后面的*代表这是该对象的第一个扩展块。
现在我们来解释[0004] 4 0x00*的含义
[0004]代表EXTENT 4,[0004]后紧跟的4代表对象4,
4后面的0x0代表这是对象扩展块;0x0后面的0代表存储的是数据,0后面的*代表这是该对象的第一个扩展块。
(3).现在我们在表上创建一个索引:
[db2inst1@bogon Desktop]$ db2 "create index i1 on t1(id)"
DB20000I The SQL command completed successfully.
[db2inst1@bogon Desktop]$ db2 list tablespaces show detail
Total pages = 16384
Useable pages = 16352
Used pages (已用页数) = 224
Free pages = 16128
High water mark (pages)(高水位标记) = 224
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1
相比前面的输出,表空间中已用的扩展块增加到7个(224页)。db2dart再次分析该表空间的使用情况:
High water mark: 224 pages, 7 extents (extents #0 - 6)
[0000] 65534 0x0e [0001] 65534 0x0e [0002] 65535 0x00 [0003] 4 0x40* [0004] 4 0x00* [0005] 4 0x41* [0006] 4 0x01*
Dump high water mark processing - phase start.
Number of free extents below high water mark: 0
Number of used extents below high water mark: 7
相比前次的输出,表空间中又增加了下面两个扩展块:
[0005] 4 0x41* [0006] 4 0x01*
现在我们来解释[0005] 4 0x41*的含义:
[0005]代表EXTENT 5,[0005]后紧跟的4代表对象4,
4后面的0x4代表该扩展块存储的是该对象EXTENT的对应位图;
0x4后面的1代表存储的是索引,1后面的*代表这是该对象(扩展块对应图)的第一个扩展块。
现在我们来解释 [0006] 4 0x01* *的含义:
[0006]代表EXTENT 6,[0006]后紧跟的4代表对象4,
4后面的0x0代表这是对象扩展块;
0x0后面的1代表存储的是索引,1后面的*代表这是该对象的第一个扩展块。
(4).现在我们往该表中插入一些数据。
[db2inst1@bogon Desktop]$ db2 "insert into t1 with c1(col1) as (values(1) union all select c1.col1 +1 from c1 where c1.col1<50000) select c1.col1,'testing' from c1"
DB20000I The SQL command completed successfully.
# 必须要解释一下这个SQL,刚开始看到我还以为要去哪里找c1表愁死了。
# 这条语句的结果:插入的id从1到49999,name是‘testing’
[db2inst1@bogon Desktop]$ db2 list tablespaces show detail
Total pages = 16384
Useable pages = 16352
Used pages (已使用页数) = 960
Free pages = 15392
High water mark (pages)(高水位标记) = 960
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1
使用db2dart来看一下:
High water mark: 960 pages, 30 extents (extents #0 - 29)
[0000] 65534 0x0e [0001] 65534 0x0e [0002] 65535 0x00 [0003] 4 0x40*
[0004] 4 0x00* [0005] 4 0x41* [0006] 4 0x01* [0007] 4 0x00
[0008] 4 0x00 [0009] 4 0x01 [0010] 4 0x00 [0011] 4 0x00
[0012] 4 0x00 [0013] 4 0x01 [0014] 4 0x00 [0015] 4 0x00
[0016] 4 0x01 [0017] 4 0x00 [0018] 4 0x00 [0019] 4 0x00
[0020] 4 0x01 [0021] 4 0x00 [0022] 4 0x00 [0023] 4 0x00
[0024] 4 0x01 [0025] 4 0x00 [0026] 4 0x00 [0027] 4 0x01
[0028] 4 0x00 [0029] 4 0x00
Dump high water mark processing - phase start.
Number of free extents below high water mark: 0
Number of used extents below high water mark: 30
相比较上次的输出,表空间增加了下面的数据块:
[0007] 4 0x00
[0008] 4 0x00 [0009] 4 0x01 [0010] 4 0x00 [0011] 4 0x00
[0012] 4 0x00 [0013] 4 0x01 [0014] 4 0x00 [0015] 4 0x00
[0016] 4 0x01 [0017] 4 0x00 [0018] 4 0x00 [0019] 4 0x00
[0020] 4 0x01 [0021] 4 0x00 [0022] 4 0x00 [0023] 4 0x00
[0024] 4 0x01 [0025] 4 0x00 [0026] 4 0x00 [0027] 4 0x01
[0028] 4 0x00 [0029] 4 0x00
其中7,8,10,11,12,14,15,17,18,19,10,21,22,23,24,25,26,28,29存储的是数据
9,13,16, 20, 24,27存储的是索引。
当然这些块都不再是第一个扩展块。
通过上面这个例子,大家应该掌握了高水位和DMS表空间空间映射的信息。那么在实际操作中我们应该如何来管理高水位呢?
我们前面讲过,DB2数据库管理(DMS)表空间的高水位标记(HWM)是指该表空间曾经使用到的最大数据页数。如果使用“db2 list tablespaces show detail”命令看到某个DMS表空间的已用页数低于高水位标记,则可以通过如下方法降低高水位标记:
- 重组表空间的某个表
- 将某个表中的数据导出,然后将它删除,重新创建该表再将数据导入
对于 以上的方法,首先要找到持有高水位标记的那个表,这可以通过db2dart命令(在停止实例后方可使用)加上DHWM选项,提供表空间标识,然后从命令所产生的报告文件中获得。
而要了解通过对该表进行哪些操作可以降低HWM的建议,可使用db2dart加上LHWM选项,从产生的报告文件中获得。使用LHWM选项时,要求用户给出表空间的标识以及希望HWM降低到的页数(虽然不能保证HWM一定能讲到用户期望的值),如果该值为0,则表明由DB2将HWM降低到能够达到的最低值。
问题:那么删除数据的时候这条数据的数据页的空间怎么被回收的?
现在
[db2inst1@bogon Desktop]$ db2 "delete from t1 where id>1000"
DB20000I The SQL command completed successfully.
[db2inst1@bogon Desktop]$ db2 list tablespaces show detail
Total pages = 16384
Useable pages = 16352
Used pages (已使用的页) = 960
Free pages = 15392
High water mark (pages) = 960
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1
执行删除之后used page没有变化,分析原因。
(1)运行reorgchk分析表 T1 使用的 page 数量
[db2inst1@bogon tmp]$ db2 REORGCHK ON TABLE t1
Doing RUNSTATS ....
Table statistics:
F1: 100 * OVERFLOW / CARD < 5
F2: 100 * (Effective Space Utilization of Data Pages) > 70
F3: 100 * (Required Pages / Total Pages) > 80
SCHEMA.NAME CARD OV NP FP ACTBLK TSIZE F1 F2 F3 REORG
----------------------------------------------------------------------------------------
Table: DB2INST1.T1
1000 0 12 563 - 45000 0 2 2 -**
----------------------------------------------------------------------------------------
[db2inst1@bogon tmp]$ db2 "SELECT TABLEID, NPAGES, FPAGES FROM SYSCAT.TABLES WHERE TABNAME = 'T1'"
TABLEID NPAGES FPAGES
------- -------------------- --------------------
4 12 563
1 record(s) selected.
可以看到表t1现在只剩1000行数据了,占用了563页,只有12页上有数据。
这里有个问题,表空间 Used page 为 960,表 T1 使用了 563个,表空间创建时使用了 96 个 page,T1 的 EMP 用了 32 个 page,还有100多个 page 哪儿去了?这个问题,稍后分析。
使用db2dart来查看页:
[db2inst1@bogon tmp]$ db2 disconnect all
DB20000I The SQL DISCONNECT command completed successfully.
[db2inst1@bogon tmp]$ db2 deactivate db mytest
SQL1495W Deactivate database is successful, however, there is still a
connection to the database.
[db2inst1@bogon tmp]$ db2dart mytest /dd /tsi 4 /oi 4 /ps 0 /np 960 /v y /rptn t1.dart
t1.dart文件:
Page 0 of object 4 from table space 4.
BPS Page Header:
Page Data Offset = 48
Page Data Length = 4048
Page LSN = 000000000006FD0D
Object Page Number = 0
Pool Page Number = 128
Object ID = 4
Object Type = Data Object
Data Page Header:
Slot Count = 68
Total Free Space = 4
Total Reserve Space = 0
Youngest Reserve Space = 0
Youngest TID = 0000 0000 CF0A
Free Space Offset = 139
Maximum Record Size = 43
dpg_flags = 0x0
……
Slot 67:
Offset Location = 140 (x8C)
Record Length = 43 (x2B)
Record Type = Table Data Record (FIXEDVAR)
Record Flags = 0
Fixed part length value = 35
Column 1:
Fixed offset: 0
Type is Long Integer
Value = 64
Column 2:
Fixed offset: 4
Type is Fixed Length Character String
74657374 696E6720 20202020 20202020 testing
20202020 20202020 20202020 2020
Slots Summary: Total=68, In-use=68, Deleted=0.
……
然后看最后:
Page 11 of object 4 from table space 4.
BPS Page Header:
Page Data Offset = 48
Page Data Length = 4048
Page LSN = 000000000006FE30
Object Page Number = 11
Pool Page Number = 139
Object ID = 4
Object Type = Data Object
Data Page Header:
Slot Count = 89
Total Free Space = 1872
Total Reserve Space = 1849
Youngest Reserve Space = 1849
Youngest TID = 0000 0000 B90D
Free Space Offset = 243
Maximum Record Size = 43
dpg_flags = 0x0
Data Records:
Slot 0:
……
Slot 45:
Offset Location = 2050 (x802)
Record Length = 43 (x2B)
Record Type = Table Data Record (FIXEDVAR) (PUNC)
Record Flags = 0
Fixed part length value = 35
Column 1:
Fixed offset: 0
Type is Long Integer
Value = 1000
Column 2:
Fixed offset: 4
Type is Fixed Length Character String
74657374 696E6720 20202020 20202020 testing
20202020 20202020 20202020 2020
Slot 46:
Deleted Record
Slot 47:
Deleted Record
……
Slot 66:
Deleted Record
Slots Summary: Total=89, In-use=46, Deleted=43.
______________________________________
Page 12 of object 4 from table space 4.
BPS Page Header:
Page Data Offset = 48
Page Data Length = 4048
Page LSN = 000000000006FEE2
Object Page Number = 12
Pool Page Number = 140
Object ID = 4
Object Type = Data Object
Data Page Header:
Slot Count = 89
Total Free Space = 3850
Total Reserve Space = 3827
Youngest Reserve Space = 3827
Page 562 of object 4 from table space 4.
BPS Page Header:
Page Data Offset = 48
Page Data Length = 4048
Page LSN = 0000000000087CAA
Object Page Number = 562
Pool Page Number = 946
Object ID = 4
Object Type = Data Object
Data Page Header:
Slot Count = 29
Total Free Space = 3970
Total Reserve Space = 1247
Youngest Reserve Space = 1247
Youngest TID = 0000 0000 B90D
Free Space Offset = 2823
Maximum Record Size = 43
dpg_flags = 0x0
Data Records:
……
Slots Summary: Total=29, In-use=0, Deleted=29.
这个语句使用的是
'-+-----------------------------------+--fullselect-'
| .-,-----------------------. |
| V | |
'-WITH----common-table-expression-+-'
with c1(col1) as (values(1) union all select c1.col1 +1 from c1 where c1.col1<50000) select c1.col1,'testing' from c1;
common-table-expression:用跟随的fullselect 定义了一个通用表表达式来使用