Tblspace --informix体系架构笔记

目标:

1、了解tblspace的各元素
2、理解database tblspace的用途
3、理解bitmap页的用途
4、理解rowids的用途
5、了解各种tblspace页

Tblspace的元素

Informix用户仅需要在SQL层管理数据库,将表看成是简单顺序连续的数据记录是很简洁的方式。但是Informix数据库管理员(DBA)需要了解表的RSAM(磁盘访问)层。
数据库是由以下物理元素的逻辑组合:
1,SQL级:任何系统目录数据都跟表有关(临时表例外)
2,RSAM级:一个或多个partition页(partition page)
3,RSAM级:区段(extents)
Tblspace(partition)是独立dbspace上RSAM级(RSAM-level)元素的逻辑组合(即包含partition page和extents)
请输入图片描述

这些元素如何协同工作?
Sqlexec线程首先需要通过读取表相关的系统目录信息以访问tblspace数据。在数据库中的每个表都在systables中存在相应的行记录。该记录包含表的名称,各种统计信息,以及partition编号(partnum)。
Partnum指明了表的partition page的物理位置。在partition page的信息中,包含该表各个区段的物理位置信息。从各个区段的位置,sqlexec线程可轻松找出tblspace的区段(extent)。

Database tblspace

在root dbspace上,partnum为0x100002的特殊tblspace用于保存数据库服务器上的所有database。其被称为database tblspace。它可以认为是特殊、内部的数据库表。Sysdatabases表存在于sysmaster库 ,可以访问但不能修改。(上图中的0x100002)
Database tblspace在初始时为4个页,在需要的情况下亦可以扩展区段(默认也为4页)。
Database tblspace包含数据库服务器上建立的数据库的所有信息。每行记录包含一个数据库的名称,属主,库创建时间,日志模式标识,以及在systables中的partnum。在systables中可以找到库,那么该库上所有的表都可以定位。
Database tblspace上包含数据库名(name)的唯一索引。

Tblspace extent分配

当tblspace上的第一个区段填充完后,数据库服务器尝试分配新的区段。新分配的区段的大小一般与配置参数(NEXT SIZE)相等。分配机制有以下因素:
当前已经分配的区段数;
存在的可用连续空间;
已经分配的区段的位置

区段大小翻倍
当tblspace的区段数不断增长时,数据库服务器尝试使partition page中的区段大小翻倍。每16次扩展后,大小翻倍。

空间不足于分配区段大小
如果数据库服务器无法在dbspace上的第一个chunk上找到预分配区段大小的空间,那么将在一个chunk上查找,并以此类推。如果服务器从dbspace上的chunk free list上找到预分配区段大小的空间,那么服务器将选用dbspace上的最大的连续空间。如果最大空间少于4页,此次分配失败并返回没有空闲的磁盘空间的信息。

已经存在的区段位置
当数据库服务器预分配的新区段与前一区段在位置上连续时,将不会创建一个新的区段,而是合并(注意:extent不能跨chunk,故那怕chunk在物理磁盘上的位置是连续的,也不会合并成一个extent)。

索引tblspace(index tblspace)

用户创建的索引存储的tblspace是与其基表分离的。索引tblspace可以跟数据tblspace在同一个dbspace上,也可以建立在不同的dbspace上。索引亦可分片在多个dbspace上。
索引有自己的tblspace,也有自己的partnum。可以通过oncheck -pT 加索引所属的表名称 查找索引的partnum,也可通过sysfragments表查找索引的partnum。
索引的区段大小不能配置,索引的区段大小由索引字段大小与表的区段大小值计算而来。索引的区段扩展规则与表相同。
不同的是,系统编目表(system catalog table)的索引是存在的表的tblspace中的,系统编目表的区段上包含数据页和索引页。

Bitmap pages(位图页)

服务器线程通过表的bitmap页快速定位足够的空间用于插入记录。服务器需要bitmap查找包括:
更新的tuple(row的内部结构)不再适合存在的slot;
索引操作分配新的/空闲的tblspace页,例:B树分离和索引建立
Tblspace使用情况报告;
索引和数据检查(oncheck)

并不是所有tblspace区段的开始都是bitmap(每个tblspace的第一个区段上的logical page 0均是bitmap),若是那样会浪费很多空间,实际上每个bitmap页可以描述上千页。

4-bit bitmap pages(4-bit bitmap页)
请输入图片描述
Informix数据库服务器使用4-bit bitmap来描述页的类型,共15种类型(4-bit map)
每个bitmap页可以描述的页的总数:
trunc(页大小 - 页头字节 - 时间戳字节) * 2 (2的含义是每字节2个bitmap)
故2k大小的bitmap页可描述的页的总数为:
trunc(2024 - 24 - 4) * 2 = 4032
4k大小的bitmap页可描述的页总数为:
trunk(4096 - 24 - 4) * 2 = 8128
注:Informix 7.2及以前版本使用2-bit bitmap页,故不支持varchar和blob字段

显示数据tblspace的bitmap页
请输入图片描述
图中显示的是oncheck -pp partnum logical_page_num(还记得这个用法吗?)。
在所有的tblspace中,逻辑页0是第一个bitmap页。较小的表,也许只有一个bitmap页;较大的表,可能有多个bitmap页。显示tblspace中的第一个bitmap页,需要确认表的partnum,然后使用oncheck -pp partnum 0 。
通常情况下,oncheck输出的前两行是页头部分(24字节)。然后显示一行或者多行包含32个值的行,每个值代表该表上的一个页。每行都是完整的32个值,不足32个值用0填充,不管表实际使用的是4个页还是64页。

显示index tblspace的bitmap页
请输入图片描述
Index tblspace可以包含bitmap页,索引页和未用页。索引页和bitmap页有相同的bitmap值8 (个人认为,实际上bitmap页实际上也就特殊的index页,bitmap页的功能与索引类似,不是吗?),区分它们的分别重点在于bitmap的前后关系。页0肯定是bitmap页,其它bitmap值为8的页为索引页。如果表不断增大,bitmap页完全填充后,将创建新的bitmap页。
显示index tblspace的bitmap页,需要首先知道索引的partnum。可以从索引归属表的oncheck -pT 输出中,或是sysfragments系统编目表中查找。

显示系统编目表的bitmap页(system catalog bitmap pages)
请输入图片描述
与普通表和索引不同,系统编目表和及其索引是在同一个tblspace中的。如上图中的systables的输出中,数据页和索引页在一起。

* 家数据页(Home data pages)
请输入图片描述
保留页(remainder page)和blobpage 由于也用于保存行记,故也可以称为数据页。但它们的页中的数据是second-tier,并没有 home row指向。索引使用rowid指向home row,而无法指向保留块或blob。
我们一直谈论的 data page 内部称为 home data page,目标是为了有效的区分home row和second-tier数据。
Rowid是一段4字节的编码,使用16进制时可直观的解析。Rowid的格式为0xPPPPPPSS,其中PPPPPP 3字节的含义为该行位于的逻辑页编号(logical page of tblspace),SS 1字节的含义为该页的slot编号。图上的0x302意为row位于逻辑页3上的slot 2。
Home data page包含页头(page header),slot table及包含数据行的slot。为了访问特定data page上的特定slot,数据库线程可以通过顺序扫描或者通过RSAM获取正确的rowid两种方式。

数据行(data row):字节流(byte stream)
在大多数情况下,Informix数据库数据行并不像C结构那种方式读、写、存储,而是以字节流的方式。当数据库读取行时,是基于表结构将字节分离到各字段中。该方式不仅仅节省存储空间,而且能使数据库引擎更易控制数据布局,使数据库源码和数据本身更易移植。
字节流是不包含边界数据的连续流,字节流是由字节组成的。在以下的示例中将更好的理解这个含义。

varchar字段存储
请输入图片描述
Varchar字段的存储方式很容易理解。记住两个规则,第一:由于varchar字段是可变的,故一个附加字节将加到该字段的前面用于存储字段的长度。这个字节(length字节)可存储的最大值为0xFF,即255,这也解释了为什么varchar字段的最大长度为255个字符。第二:当varchar有定义最小字段长度时,若是字段长度少于最小字段大小,则该行附加字段长度与最小字段长度的字节数(padd)。需要注意的是,padd是行的附加,而不是varchar字段的附加。 (第二个规则可以这样认为当varchar字段长度小于最小长度时,行附加该大小字节数,以使有足够的大小)
如上图所示(可以较好的理解 字节流的含义,各字段间其它字节来分隔各字段),示例中的表由integer,varchar(20,5),smallint三个字段组成,显示了3个记录(行)。第一行中前4个字节为integer占用的字节数,示例中的值为数字1,在integer字段后为varchar(20,5),其中第一个字节为0x3,即该字段大小为3,而后的0x61、0x62、0x63三个字节为该字段的内容,从ascii码转换为abc,在varchar字段后的是smallint,占用2个字节,值为1。由于varchar定义的最小字段大小为5,且当前字段仅包含3个字节,故行在最后增加padding,大小为最小字段大小与字段实际大小字节数的差值。需要注意的是padd的值是无任何意义的,不管是0x0还是0xee。从第二行和第三行可以看到,由于varchar的实际字段大小大于或者等于最小字段大小的值,故不再需要padding。

Varchar字段的前向指针(forward pointer)
请输入图片描述
行记录包含有varchar字段,当varchar字段更改时,若行所在的页有足够的空间够,则直接更改;若是所在页没有足够的空间,则该行记录移出home data page至remainder page中,并在原home data page的slot中增加4字节的前向指针(forward pointer)。
当一行移到remainder page时,访问该行需要调用4个指针:
1,访问原home page页上slot table的rowid;
2,原home page上的slot table的条目;
3,原home page上slot中的指向remainder page上rowid的前向指针(forward pointer);
4,remainder page上指向当前行记录的slot table的条目;
需要注意的是,slot table中的条目包含前向指针(forward pointer)时,slot table条目中的flag包含0x8000。(如上图中的0x8004)

大行中的前向指针(forward pointers for large rows)
请输入图片描述
当行大小大于页大小时,使用前向指针(forward pointer)代替home row中的记录是不现实的(行都大于页了,别的页也放不下。HUHU~)。实际的情况下,行的前4字节用于前向指针,之后是该home page上可存放的行信息。通常情况下,这4字节的前向指针的值是指向第一个remainder page上的rowid。

大remainder page(big remainder pages)
如果需要存储在remainder page中的记录大于remainder page的容量大小,那么remainder page中出现第二个4字节的前向指针(forward pointer),在前向指针之后存储可最大的记录,并以此类推,至记录完全存储于page中。这种含有前向指针的remainder page称为big remainder page。
需要注意的是,big remainder page上的slot table条目上的flag也含有0x8000。

含blob descriptor的home page
请输入图片描述
Informix支持2种大对象,简单大对象(simple large objects(blob),包括text和byte两种类型)和智能大对象(smart large objects(smart Los,或smart blobs),包括blob和clob两种类型)。其中 简单大对象可以存储在partirion page中。
Blob字段中的记录并不像非blob字段记录存储在home data page上。Blob可以存在独立配置的blobspace上,或是前向同tblspace上特殊的partition blobpage中。由于blob管理复杂,使用4字节的前向指针不足于描述blob的位置。故使用了56字节的descriptor替代占用blob字段的位置。即使blob字段的值为空,在home page上的该字段仍使用56字节的descriptor代替。

Partition Blob
Partition blobpage(在dbspace上的blobpage)与blobspace blobpage(在blobspace上的blobpage)有几个重要的不同点。partition blobpage与其它page类似,有相同的大小(BUFFSIZE);而blobspace blobpage的大小是可配置的(BUFFSIZE的位数)。Partition blobpage是在共享内存缓冲区中更新的,而blobspace blobpage不是。Partition blobpage的更改会写入逻辑日志,而blobspace blobpage是无日志的。

Blob descriptor的结构
请输入图片描述
可以使用oncheck -pD 查看含有blob字段的表(示例中为包含text字段的简单大对象的表),按顺序列出56-字节blob descriptor的含义。
Bytes Description
2 BLOB file descriptor (must be first)
2 BLOB column offset in row
4 BLOB tblspace number
4 Starting byte
4 Ending byte-0 for end of BLOB
4 Size of BLOB
4 Starting Sector of BLOB Page
4 Family ID
4 Family Volume
2 Medium - odd if removable
2 First BLOBPage BLOB stamp
2 Socket id of remote BLOB
2 Flags
4 Optical system identifier
4 Reserved for future use
4 Reserved for future use
4 Reserved for future use

其中,2-字节flags的含义如下:
Flag Type Displayed Description
0x0001 BLOBISNULL BLOB is NULL
0x0004 BSBLOB BLOB is stored in BLOBspace
0x0008 PNBLOB BLOB is stored in Tblspace

Partition blobpage
请输入图片描述
Partition blob包含一个或者多个blob块(piece)。当blob数据大于一个partition blobpage时将分割成多个blob块于多个partition page中,它们之间使用联接(chain)使用前向指针(forward pointer)。该机制与前面提到大行的remainder piece相似,不同在于最后一个blob piece位于其自己的blobpage上。
图中的partition blobpage含有2个blob piece,每个blob piece包含8字节blob前向指针和blob数据。

blob前向的8字节含义如下:
bstamp(2字节):
blobstamp是blob块的前2字节。blobstamp用于校验可能包含上百页的blob块联接的一致性。需要注意的是,blob块各联接上的blobstamp并不是相同的值。
blob块上的blobstamp应当与前一个blob块上的expected blobstamp一致,或者是与blob descriptor上的stamp一致(第一个blob 块)。否则将报ISAM错误: -164 ISAM error:TEXT or BYTE stamp is incorrect.

next blobpage(4字节):
该元素的组成和功能与以前提到的前向指针(forward pointer)极其相似。它包含的是blob 块联接的下一个blob 块的rowid。最后一个blob块的next blobpage的值固定为0xffffffff。

nbstamp(2字节):
下一个blob块的预期blobstamp(expected blobstamp)

标签: none

添加新评论

Free Web Hosting