informix9.4表空间满问题,extent size小,重建表结构,设置extent size,倒数据到新表中:
1.
unload to 100000.unl select * from 表1
load from 100000.unl insert into 表2
2.
CREATE TABLE 表(
id SERIAL NOT NULL,
exe_id INTEGER,
exe_response LVARCHAR(3000),
exe_exception VARCHAR(10),
exe_fid INTEGER,
exe_man VARCHAR(160),
exe_manid VARCHAR(30),
exe_time VARCHAR(60),
display_name VARCHAR(255),
real_name VARCHAR(255),
remark VARCHAR(255),
PRIMARY KEY(id)
)
EXTENT SIZE 1100 NEXT SIZE 10240
LOCK MODE ROW
3.rename table 表1 to 表2
关于IBM Informix数据库中两个基本概念(任何大型数据库的Page和Extent的含义都是一样的,无论是Oracle,DB2,甚至垃圾的Microsoft SQL-Server):
Page:是一最基本的I/O单位。一个 page的大小是由OS来决定的,有2K的,也有4K的。我们拿2K的来举例说明。一个page有2048个bit,页头由24bit组成,页尾有一个 4bit的时间戳,也就是说每一个page剩余的空间只有2020个bit,另外在每一个page上还有一个槽表,一个槽表4bit,一条记录对应一个槽 表,这样在每一个page上存放的记录数就可以定下来。说这些的目的是为了说明在我们建表的时候尽量表不要建的太大,有的表一条记录的大小就超过了一个 page,这样在读取的效率上并不是太高。另外还有一个FILLFACTOR的参数决定了数据页的填充程度,如果此值设置的不是太合理,经常上现节点分裂 的情况,那对表的读取效率肯定是有影响的。
Extent:是磁盘上连续page的一组 集合。在每个extent内的page都是连续的,在表中默认的 extent的大小是16K,extent&的大小决定了表中数据存放的集中程度。如果数据存放的过与分散在做磁盘I/O的时间肯定会变长,一般 的情况下每个表的extent的大小建议不要超过50,如果太大,就需要做合理的调整。另外不能不提的是在随着extent数目的增长,每次分出的空间的 大小是不不一样的,在每到16的时候,就翻倍。例如第一个extent是16K,第17个extent就是32K,第33个就是64K了,在翻倍的增长。
首先,这是IBM官方PDF教程中关于Extent Size的叙述:
1. Estimate the number of rows that you want to store initially.
2. Add the widths of all columns in the table to calculate the row size.
Add four bytes for the slot table entry. The result is rowsize.
For each Text and Byte column, whether stored in the table or in a blobspace, add
56 bytes to the rowsize. Tables that contain LVARCHAR, TEXT, VARCHAR and
BLOB columns located in the table are impossible to size accurately. You can use
the maximum possible size or an average size, but the resulting row size is always
an estimate.
3. Subtract 28 from the total size of a page, pagesize, to account for the header and footer
timestamp that appears on the page. The result is the usable space on the page, pageuse.
4. If rowsize is less than or equal to pageuse:
number of data pages = number of rows/maxrows,
where
maxrows = min(pageuse/rowsize, 255)
If rowsize is greater than pageuse, the database server divides the row between pages.
The initial portion of the row is the homepage. Subsequent portions are stored in
remainder pages.
The size of the table is calculated as
number of data pages = number of homepages +
# of remainder pages
5. Calculate the total space required in kilobytes:
(number of data pages * pagesize)/1024
To calculate an appropriate NEXT SIZE value for successive extents allocated for the table,
apply steps 1 through 5, but instead of using the initial number of rows, use the number of rows
by which you anticipate the table will grow over a period of time. Also, be sure to consider how
much disk space you have available and whether or not you plan to add additional disks to the
system at a specific time.
这是ChinaUNIX上一"高人"的解释:
1,确定行数.(当前+增长)=总行数
2,确定每行长度:全字段长
3,rowsize=全字段长+4 bye(slot table)
4,确定每页可以存放多少rows:2020/rowsize
#2020=2048-28 是page减去(页头+timestamp)
5,确定需要多少页
First Extent=总行数/rows per pages
Next Extent=增长/rows per pages
6,确定空间
First Extent Size=First Extent *2(页大小)
Next Extent Size=Next Extent *2 (页大小)
IBM官方PDF教程上的一个例子:
Example
Assume that your table initially has 1,000,000 rows and is expected to grow
between 10 percent and 30 percent per year. Also, assume that you have budgeted
to purchase more disks in 12 months and that you will reload your database to
distribute it over existing and new devices at that time.
Given these assumptions, you might want to size additional extents to hold
100,000 rows. If your table grows at 10 percent per year, the database server only
allocates one extent during the year. If your table grows at 30 percent, the database server
might have to allocated 3 or 4 additional extents. In either case, the number of extents
allocated will be small enough to avoid affecting performance, or the need to reorganize your
table, before the scheduled maintenance period.
I本人觉得,要想真正搞懂,还要再看得细点儿...
以下是BM官方网站上的帮助文档中关于Extent Size的Calculating的叙述:
区段大小
区段(extent)是磁盘上一块物理位置连续的页面,用以存储数据库对象。在创建表时,默认的区段大小是 16 KB。这对于大多数据库表通常都太小。在填满了一个区段时,Informix 服务器将自动分配更多区段,直到它具有足够的区段来存储整个表中的数据。为了获得高性能,Informix 文档建议将一个表中的所有数据置于一、两个较大的区段中,而不是将它们置于许多较小的区段中。给出这样的建议有两个原因:
* 如果一个表有一个以上区段,则无法保证这些区段是连续的;区段可能分散在这个表驻留的整个数据库空间(dbspace)中。物理磁盘页面的连续性对于性能是至关重要的。当数据页面连续时,用于访问磁盘上数据的时间是最少的,数据库也可以连续读取行。如果表中有太多的区段,那么这些区段极有可能是交错的。这将大大损害性能,因为当您为某个表检索数据时,磁盘头需要查找同属于该表的大量非连续的区段,而非不是查找一个包含连续物理页面的大型区段。这极大地降低了磁盘寻址(disk-seeking)速度。
* 另一个原因是为了避免自动分配表的区段,这是一个代价极高的操作,将使用大量系统资源,例如 CPU 和内存。
为了实现 Informix 文档的建议,在创建表时,需要指定区段大小,不让 Informix 服务器使用 16 KB 的默认区段大小。CREATE TABLE 语句中的 EXTENT SIZE 和 NEXT SIZE 子句允许您指定 Informix 服务器将分配给所创建的每一个表的第一个和第二个区段大小。
但是,如何估算区段大小呢?这是一项很困难的任务,特别是对于 OLTP 数据库,要不断在这个数据库中更新和插入表。实质上,您需要知道该表将包含的行数、行的大小和系统的页大小。然后,必须对那些数字进行一些数学运算。 Informix 文档为我们提供了关于完成这项工作的详细指南:
* 确定每个索引的长度。
* 确定索引的总长度。
* 计算索引开销。
* 确定表的初始大小。
* 索引空间需要的大小。
* 将索引空间转换成千字节(kilobyte)。
* 确定以字节为单位的页大小;用它减去 28 就可以获得可用的页面空间。
* 确定行的长度。
* 确定一页上可以完整放置多少行。
* 确定初始表的数据页的数目。
* 初始表中数据页面所需的空间大小。
* 将数据大小转换成千字节(kilobyte)。
* 确定以千字节(kilobyte)为单位的初始区段大小。
* 确定表的增长。
* 下个区段的大小。
现在,让我们来浏览一个例子。根据这个指南为 item 表一步步估算第一个和第二个区段大小。以下是 item 表的结构:
列 数据类型 长度(以字节为单位)*
Item_num smallint 2
Order_num integer 4
Stock_num smallint 2
Manu_code char(3) 3
Quantity smallint 2
Total_price money(8) 5
* 您可以在 IBM Informix Dynamic Server Administrator's Reference, Version 9.4 中获得每种数据类型的长度。
现在,让我们假设该表在 order_num 上有一个索引,而且还有 stock_num 与 manu_code 上的复合索引。该表最初有 20,000 行,几个月内,它会增加 35,000 行。
以下是每项计算的结果:
步骤 描述 计算(以字节为单位)
1 确定每个索引长度 order_num 上的索引 = 4+9 = 13
stock_num 和 manu_code 上的索引 = 2+3+9 = 14
2 确定索引的总长度 13 + 14 = 27
3 计算索引开销 27 * 1.25 = 33.75
4 确定表的初始大小 20,000 行
5 所需的总的索引空间 20,000 * 33.75 = 675,000
6 将索引空间转换成千字节(kilobyte) 67,5000/1,024 = 660 (Kbytes)
7 确定以字节为单位的页大小
减去 28 以获得页面开销 2,048 - 28 = 2,020
8 确定行的长度 2 + 4 + 2 + 3 + 2 + 5 + 4 = 22
9 确定每页有多少整行 2020/22 = 91
10 确定初始表的数据页面数目 20,000/91 = 220
11 数据所需的总空间 220 * 2,048 = 450,560
12 将数据大小转换成千字节 450,560/1,024 = 440
13 确定初始区段大小 440 + 660 = 1,100
14 确定表的增长 增加 35,000 行
15 估算下个区段的大小 所需的索引空间 = 35,000 * 33.75 = 1,181,250
转换成 Kbytes = 1,181,250/1024 = 1,154
所需的附加数据页 = 35,000/91 = 385
转换成 bytes = 385 * 2,048 = 788,480
转换成 Kbytes = 788,480/1,024 = 770
所需的总空间 = 770 + 1,154 = 1,924
基于这些计算,就可以确定该表所需的第一个和下一个区段的大小,现在,您可以在 CREATE TABLE 语句中指定第一个和下一个区段的大小:
CREATE TABLE item(
Item_num smallint,
Order_num integer ,
Stock_num smallint,
Manu_code char(3) ,
Quantity smallint,
Total_price money(8))
EXTENT SIZE 1100 NEXT SIZE 1924;
在创建该表时,Informix 服务器将自动为该表分配前两个区段,并且如果您的估算正确,那么这两个区段即使不能包含该表的所有数据,也能包含其中的大部分数据。以上计算是极其机械的,并且易于在 Microsoft® Excel 电子数据表(spreadsheet)中实现,从而可以自动化整个过程。从上述计算中还可以发现,估算的基础就是表将包含的行数。这种估算当然是基于业务规则的,但很大程度上也取决于数据库中表之间的关系。例如,假设有两个表,customer 和 address,并知道有 100,000 位客户,每位客户最多可能有 4 个地址。因此,您可以很容易地计算出 address 表最多可能有 100,000 *4 行。
然后,该如何验证估算值,并查看该值与实际值是否接近呢?在创建表并装入数据之后,您可以使用 Informix oncheck 实用程序来获得该表的表空间(tblspace)报告。以下就是这条命令:
oncheck -pt prod1:item
示例输出如下:
TBLspace Report for prod1:item
Physical Address 9:652153
Creation date 08/31/2004 11:41:05
TBLspace Flags 802 Row Locking
TBLspace use 4 bit bit-maps
Maximum row size 220
Number of special columns 0
Number of keys 0
Number of extents 1
Current serial value 1
First extent size 1100
Next extent size 1924
Number of pages allocated 4107
Number of pages used 886
Number of data pages 885
Number of rows 7960
Partition partnum 7340289
Partition lockid 7340289
Extents
Logical Page Physical Page Size
0 9:299243 4107
以上输出告诉您,item 表仅有一个区段。如果表空间(tblspace)报告显示表中包含太多的区段,那么可以使用该统计数据来优化估算算法,然后使之更符合实际情况。
实际上,表空间(tblspace)报告包括两个部分,第一部分是关于表的区段信息,第二部分包含关于索引的区段信息。无法像对表那样直接为索引指定区段大小;在创建索引时,Informix 服务器将基于所指定的表区段大小,自动为索引分配区段。然而,您可以使用 oncheck 实用程序来查看索引获得了多少个区段。以下是示例输出:
Index item_idx1 fragment in DBspace prod1_idx
Physical Address 9:907200
Creation date 08/31/2004 12:48:45
TBLspace Flags 802 Row Locking
TBLspace use 4 bit bit-maps
Maximum row size 220
Number of special columns 0
Number of keys 1
Number of extents 1
Current serial value 1
First extent size 224
Next extent size 32
Number of pages allocated 224
Number of pages used 36
Number of data pages 0
Number of rows 0
Partition partnum 7340624
Partition lockid 7340289
Extents
Logical Page Physical Page Size
0 9:831443 224
以上输出显示索引 item_idx1 仅有一个区段。关于如何使用 oncheck 的详细信息,请参阅 IBM Informix Dynamic Server Administrator's Guide, Version 9.4。