SQL0286N.DB2表空間的pagesize問題

superdba發表於2017-07-19

 今天在一個DB2環境中匯入一批表結構,結果在中途報錯退出

SQL0286N  A default table space could not be found with a page size of at 
least "16384" that authorization ID "DB2INST1" is authorized to use. 

 由於對DB2也不是很熟悉,首先根據報錯上文找到DDL指令碼中的SQL語句,大概是這樣的

CREATE TABLE BOND_BASE_INFO ( ... BACK_MEMO VARCHAR(500), CCY_NET_FULL_CN_NM VARCHAR(1024), ERLY_RDM_CNDTN VARCHAR(4000), ERLY_CASH_CNDTN VARCHAR(4000), ...)

 那麼其實報錯說的很清楚了,表空間的pagesize不夠,而建立這張表至少需要16K的page。

檢視了一下當前database的表空間

db2 => select TBSPACE, OWNER, PAGESIZE from syscat.tablespaces

TBSPACE                        OWNER                          PAGESIZE   
------------------------------ ------------------------------ -----------
SYSCATSPACE                    SYSIBM                                4096
TEMPSPACE1                     SYSIBM                                4096
USERSPACE1                     SYSIBM                                4096
SYSTOOLSPACE                   DB2INST1                              4096
SYSTOOLSTMPSPACE               DB2INST1                              4096

 從這裡可以看到,所有的表空間都是系統預設建立的,並且使用的pagesize也是預設的4K

官方文件相關內容如下:

 When a database is created, three table spaces are defined: (1) SYSCATSPACE for the system catalog tables, (2) TEMPSPACE1 for system temporary tables created during database processing, and (3) USERSPACE1 for user-defined tables and indexes. You can also create additional user table spaces at the same time.
 Using the CREATE DATABASE command, you can specify the page size for the default buffer pool and the initial table spaces. This default also represents the default page size for all future CREATE BUFFERPOOL and CREATE TABLESPACE statements. If you do not specify the page size when creating the database, the default page size is 4 KB.

 那麼在例項建立時(即create database),系統會預設為此database建立三個表空間,並且在不指定任意引數的情況下,所有引數都會使用預設值。並且除了文件提到的SYSCATSPACE、TEMPSPACE1、USERSPACE1這三個表空間外,本例中還出現了兩個systool表空間,這是在例項中第一次使用管理排程工具的時候建立的。另外這裡需要特別注意的是,pagesize預設值為4KB。
 首先我嘗試通過DDL指令來更改定義,不過V9.7貌似是不支援直接更改pagesize.

 To alter a table space using the command line, use the ALTER TABLESPACE statement.

 Depending on the type of table space, you can do things such as:
● Increasing the size of the table space by adding additional containers
● Resizing existing containers
● Dropping containers
● Rebalance the table space to start making use of new containers, or to move data out of dropped containers
● Lower the high water mark for the table space
● Reduce the overall size of the table space.

 看來是隻支援容器大小調整刪除,以及碎片清理操作。
 既然不能修改表空間的話,那就只能新建database或者tablespace了,由於受到Oracle的影響,認為使用者和tablespace是存在繫結關係的,那麼對於oracle的思維,需要新建個使用者,然後將老的資料導過來?

 不過在這點上,DB2的機制還是有很大差別的。DB2裡,我的理解是,表空間是和例項繫結的,例項也就是databases,使用者只需有使用database的相關許可權就行了,物理儲存方面不做嚴格的區分,不過DB2裡建表語句可以通過in子句來選擇自己想要使用的表空間。那麼其實在管理上,分的不像oracle那麼細,oracle裡同一個例項的不同schema是可以使用自己單獨的表空間的,並且使用者必須繫結一個表空間。

 解決方式其實是很簡單的,在這個database裡新建立一個滿足要求的表空間就夠了,不過這裡需要注意的是,buffer pool和表空間的pagesize大小需要對應。

#建立pagesize為32K的bufferpool
db2 => create BUFFERPOOL bigbuffer SIZE 5000 PAGESIZE 32K
DB20000I  The SQL command completed successfully.

#建立pagesize為32K的tablespace,同時使用新建立的bufferpool
db2 => CREATE TABLESPACE bigtablespace PAGESIZE 32K BUFFERPOOL bigbuffer
DB20000I  The SQL command completed successfully.

現在再來看一下表空間的情況

db2 => select TBSPACE, OWNER, PAGESIZE from syscat.tablespaces

TBSPACE                       OWNER                          PAGESIZE   
-------------------    ------ --------------           ----- -----------
SYSCATSPACE                   SYSIBM                                4096
TEMPSPACE1                    SYSIBM                                4096
USERSPACE1                    SYSIBM                                4096
SYSTOOLSPACE                  DB2INST1                              4096
SYSTOOLSTMPSPACE              DB2INST1                              4096
BIGTABLESPACE                 DB2INST1                             32768

接下來再來建立這張表,就OK了

db2 => CREATE TABLE BOND_BASE_INFO ( SRNO INTEGER NOT NULL , ANCMNT_DATE DATE,  ...)
DB20000I  The SQL command completed successfully.

 不過,如果你不想要使用多個表空間的話,也可以將之前tablespace中的資料匯入到新的tablespace中,這裡DB2支援直接匯入到指定的tablespace,db2 databasename import -ts tablespace_name。


相關文章