db2数据库常见问题处理
1 数据库实例挂起
现象:
数据库操作无返回,应用程序无响应,查看数据库实例发现挂起。
分析:
1、执行ps -ef|grep db2sysc 确认系统中是否存在db2sysc 进程,判断数据库实例是否出现异常。
2、执行db2gcf -s -p 分区号-i 实例名确认实例状态是否为Available。
处理:
1、执行如下命令收集db2fodc -hang 数据:
db2fodc –hang –alldbs
2、如果收集的时间过长,可适当减小收集范围:
db2pd –stack all –repeat 5
db2pd –latch –repeat 5
3、使用DB2 数据库系统用户执行db2_kill 命令杀掉DB2 进程,使用ps –ef|grep db2 命令确认DB2 进程已全部清除,然后执行db2start 命令启动数据库,再执行
db2 connect to db_name;
db2 "select * from syscat.bufferpools"
验证DB2 数据库操作正常。
4、重新启动DB2 后再使用db2support 收集相关信息:
db2support /tmp/db2data -d <db_name> -a -g -l -r -s
5、在AIX 系统中可执行snap -gc 命令、在Linux 系统可执行support –a 命令收集操作系统信息,以帮助分析数据库实例进程为何出现异常。
2 数据库实例崩溃
现象:
DB2 进程异常结束,无法提供服务。
分析:
执行ps –ef |grep db2sysc 发现DB2 进程消失。
处理:
1、使用DB2 数据库系统用户执行db2start 命令启动数据库,并执行
db2 connect to db_name;
db2 "select * from syscat.bufferpools"
验证DB2 数据库操作正常。
2、执行db2support . –d db_name -c –s –f 命令收集数据,执行
db2trc on -t -f server.dmp;
db2trc fmt server.dmp server.fmt;
db2trc flw -t server.dmp server.flw
命令开启db2trc,监控问题是否重现,收集trace 数据。
3 数据库连接数满
现象:
应用程序连接数据库时出现SQL1040N The maximum number of applications is already connected to the database 报错,无法建立新的数据库连接。
分析:
1、执行db2 get db cfg for sample | grep –i maxappls 查看当前数据库maxappls 参数值。
2、执行db2pd –db db_name –app 或者db2 list applications |wc –l 检查应用程序的总连接数是否已超过数据库最大允许连接数。
处理:
执行db2 update db cfg for sample using maxappls automatic 命令更新maxappls 参数,使之自动增长。
4 数据库事务日志满
现象:
单个交易处理数据量大,导致日志满情况发生。
分析:
执行如下查询,可检查占用日志较大的交易:
db2 "SELECT SUBSTR(DB_NAME,1,8) AS DB_NAME, AGENT_ID, ROWS_READ,ROWS_WRITTEN, UOW_LOG_SPACE_USED, UOW_START_TIME, UOW_STOP_TIME,ELAPSED_EXEC_TIME_S FROM SYSIBMADM.SNAPAPPL"
处理:
1、若数据库日志满,DB2 将强制回滚事务。可通过db2pd –db db_name –apinfo 数据库名察看应用状态,应该处于rollback 状态。
2、DB2 数据库有2 个参数可以控制每个交易使用的日志量,避免单个交易占用索引日志情况, 可执行
db2 update dbm cfg using MAX_LOG 80 和db2 update dbm cfg usingNUM_LOG_SPAN 80
设置该参数为80%,避免单个大交易的情况。
3、规避方法:
当数据库日志空间存在用尽风险时,可以通过在线增加logsecond 参数来增加可用的日志空间,避免出现日志空间满的情况。在扩展此参数前,需确认数据库日志所在的文件系统有空闲空间。
确认数据库的日志路径:
db2 get db cfg for <dbname> |grep "Path to log files"
增加logsecond:
单分区环境:
db2 update db cfg using logsecond <num>
注:num 为参数logsecond 的新的值。
多分区环境:
db2_all "db2 update db cfg using logsecond <num>"
注:num 为参数logsecond 的新的值。
5 数据库事务日志误删
现象:
数据库活动日志被误删除。
分析:
进入DB2 活动日志目录下,检查发现日志文件已经被误删除。
处理:
通过最新的数据库备份进行恢复,执行恢复之后前滚日志。命令:
db2 RESTORE DATABASE 数据库名 FROM 备份文件位置" TAKEN AT 时间戳 to 待恢复的实例名" logtarget 日志目录REPLACE EXISTING redirect
注:日志重置后,强烈建议数据库重建,避免存在隐患。
6 数据库表空间满
现象:
巡检发现数据库日志中出现如下错误信息:
FUNCTION: DB2 UDB, buffer pool services, sqlbDMScheckObjAlloc, probe:830
MESSAGE : ZRC=0x85020021=-2063466463=SQLB_END_OF_CONTAINER "DMS Containerspace full"
分析:
1、执行如下SQL 语句,确认表空间使用率:
$db2 "connect to 数据库名 user 用户 using 密码
$db2 "select substr(a.tbsp_name,1,18) as name,substr(a.tbsp_type,1,10) as
tbstype,a.TBSP_USING_AUTO_STORAGE as AUTO_STORAGE,substr(a.tbsp_state,1,8) as
state,a.tbsp_total_size_kb/1024 as TotalMB ,a.TBSP_PAGE_TOP*a.TBSP_PAGE_SIZE/1024/1024 as
top_size_mb,a.tbsp_used_size_kb/1024 as UsedMB, a.TBSP_UTILIZATION_PERCENT as
UsedPer ,b.CONTAINER_NAME from sysibmadm.tbsp_utilization a, sysibmadm.SNAPCONTAINER
b where tbsp_type='DMS' and a.TBSP_ID=b.TBSP_ID order by AUTO_STORAGE,UsedPer desc"
2、执行如下命令确认容器类型:
单分区环境
$db2pd -d <db> -tab
多分区环境:
$db2_all "db2pd -d <db> -tab"
处理:
执行
$db2 "alter tablespace <name> extend(all NG)"
扩容表空间。
注:表空间增加的大小为容器数量*N,N 为每个容器增加的大小。
7 数据库表空间状态异常
现象:
系统监控报警数据库表空间状态异常。
分析:
1、由于存储、操作或者权限等原因,会导致DB2 表空间状态异常。此时,可查询表空间16 进制的状态值。命令:
$db2 list tablespaces show detail|grep -i state
2、根据返回的16 进制值,确认表空间状态。命令:
$db2tbst <tablespace state>
3、表空间状态信息对应的描述:
Return code |
Description |
描述 |
0x0 |
Normal |
正常 |
0x1 |
Quiesced: SHARE |
静止态共享 |
0x2 |
Quiesced: UPDATE |
静止态更新 |
0x4 |
Quiesced: EXCLUSIVE |
静止态排它 |
0x8 |
Load pending |
载入挂起 |
0x10 |
Delete pending |
删除挂起 |
0x20 |
Backup pending |
备份挂起 |
0x40 |
Roll forward in progress |
正在回滚 |
0x80 |
Roll forward pending |
回滚挂起 |
0x100 |
Restore pending |
存储挂起 |
0x100 |
Recovery pending (not used) |
恢复挂起 |
0x200 |
Disable pending |
禁用挂起 |
0x400 |
Reorg in progress |
正在重组 |
0x800 |
Backup in progress |
正在备份 |
0x1000 |
Storage must be defined |
存储器未被指定 |
0x2000 |
Restore in progress |
正在恢复 |
0x4000 |
Offline and not accessible |
表空间不可访问 |
0x8000 |
Drop pending |
删除挂起 |
0x2000000 |
Storage may be defined |
存储器需被指定 |
0x4000000 |
StorDef is in 'final' state |
存储器终止 |
0x8000000 |
StorDef was changed prior to rollforward |
存储器被改变至回滚状态 |
0x10000000 |
DMS rebalancer is active |
表空间的容器重新分布 |
0x20000000 |
TBS deletion in progress |
表空间删除 |
0x40000000 |
TBS creation in progress |
表空间建立 |
处理:
常见异常状态的处理方式:
状态 |
状态值 |
原因 |
状态描述及处理方式 |
Backup Pending |
0x20 |
归档日志下进行LOAD 操作导致 |
对状态异常的表空间执行备份,命令: db2 backup database db_name tablespace(syscatspace, userspace1) to/dbbackupdir |
Offline and Not Accessible |
0x4000 |
1.表空间使用的物理设备不可访问 2.物理设备权限不对 |
修复物理设备问题,保证权限正确,然后修改表空间为online 状态,命令: db2 ALTER TABLESPACE <name> SWITCH ONLINE |
Restore Pending |
0x100 |
恢复过程中,表空间对应的物理设备不可用,表空间就处于这种状态。 |
必须恢复单个表空间(或者是整 个数据库)。命令: db2 restore database db_name tablespace (XXX) 如果是归档日志,则前滚日志,命令: db2 rollfoward db db_name to end of logs and complete |
Roll Forward Pending |
0x80 |
由于物理设备不可用或者权限问题, 导致CRASH RECOVERY 时日志无法前滚,出现上述问题; |
必须前滚数据库,命令: db2 rollfoward db db_name to end of logs and complete |
Storage Must be Defined |
0x1000 |
在将恢复操作重定向到新数据库期间,如果省略了设置表空间容器的阶段,或者,如果在设置表空间容器的阶段期间无法获得指定的容器,那么数据库的表空间就会处于这种状态。 |
需要重新制定表空间使用的容器,命令: db2 SET TABLESPACE CONTAINERS FOR 1 USING (容器名) |
8 数据库表或数据误删
现象:
数据库中的表或数据被误删除。
分析:
与操作人员确认误删除发生的时间以及被删除的数据内容。
处理:
1、如果该表或数据所在的表空间不大,恢复时间较短,且该表所在的表空间已启用DROPPED TABLE RECOVERY 选项,建议采用数据库前滚恢复的方式恢复表或数据。可通过如下命令查询字典表SYSCAT.TABLESPACES 来验证表空间是否已开启DROPPED TABLE RECOVERY选项:
db2 "select tbspace,drop_recovery from syscat.tablespaces"
TBSPACE DROP_RECOVERY
---------------------- ------------------
SYSCATSPACE N
TEMPSPACE1 N
USERSPACE1 Y
ALANSPACE1 Y
ALANSPACE2 Y
SYSTOOLSPACE Y
2、尝试恢复数据库:
(a)、执行db2 restore database irmdb from D:\IBM\alanbak taken at 20100628154742 into irmdb命令,将会显示SQL2539W 警告!正在复原至与备份映像数据库相同的现有数据库。
数据库文件将被删除。想要继续吗?(y/n)
回答Y。
DB20000I RESTORE DATABASE 命令成功完成。
(b)、执行db2 list history dropped table all for irmdb从历史文件中检索已经丢失表对象的ID。列示irmdb 的历史记录文件:
匹配的文件条目数= 1
Op 对象时间戳记+序列类型设备最早日志当前日志备份标识
-- --- ------------------ ---- --- ------------ ------------ ----------
D T 20100628154949 000000000000f40200030004
----------------------------------------------------
"DB2ADMIN"."ALANTEST1" 驻留在1 表空间中:00001 ALANSPACE1
----------------------------------------------------
注释:DROP TABLE
开始时间:20100628154949
结束时间:20100628154949
状态:A
----------------------------------------------------
EID:13
DDL: CREATE TABLE "DB2ADMIN"."ALANTEST1" ( "ID" INTEGER , "NAME" VARCHAR(10) ) IN "ALANSPACE1" ;
----------------------------------------------------
其中我们可以查看一下备份标识:000000000000f40200030004,这个信息对于恢复表非常重要。
(c)、Rollforward数据库到日志结尾,同时生成恢复导入文件(我们需要利用上面的备份标识000000000000f40200030004来恢复数据库,同时准备出一个导出目录D:\IBM\exporttab)。执行如下命令:
db2 "rollforward database irmdb to end of logs and stop tablespace (alanspace1) online recover
dropped table 000000000000f40200030004 to D:\IBM\exporttab"
前滚状态
输入数据库别名= irmdb
节点数已返回状态= 1
节点号= 0
前滚状态= 未暂挂
下一个要读取的日志文件=
已处理的日志文件= S0000002.LOG - S0000004.LOG
上次落实的事务= 2010-06-28-07.49.50.000000 UTC
DB20000I ROLLFORWARD 命令成功完成。
(d)、此时我们可以看到在D:\IBM\exporttab\NODE0000目录下生成了一个data文件,内容就是我们表中丢失的数据。然后,我们用LIST HISTORY中的DDL来重建表结构并IMPORT相应的数据,如下:
DDL: CREATE TABLE "DB2ADMIN"."ALANTEST1" ( "ID" INTEGER , "NAME" VARCHAR(10) ) IN "ALANSPACE1" ;
db2 CREATE TABLE "DB2ADMIN"."ALANTEST1" ( "ID" INTEGER , "NAME" VARCHAR(10) )
DB20000I SQL 命令成功完成。
db2 import from D:\IBM\exporttab\NODE0000\data of del insert into db2admin.alantest1
SQL3109N 实用程序正在开始从文件"D:\IBM\exporttab\NODE0000\data" 装入数据。
SQL3110N 实用程序已完成处理。从输入文件读了"5" 行。
SQL3221W ...开始COMMIT WORK。输入记录计数= "5"。
SQL3222W ...对任何数据库更改的COMMIT 都成功。
SQL3149N 处理了输入文件中的"5" 行。已将"5" 行成功插入表中。拒绝了"0" 行。
读取行数= 5
跳过行数= 0
插入行数= 5
更新行数= 0
拒绝行数= 0
落实行数= 5
3、如果该表所在的表空间很大,恢复时间远大于停机窗口,建议根据之前的建表语句重建表,并利用最新的逻辑备份导入最新的备份数据,手工补做数据丢失的时间段业务。
9 死锁或超时,导致当前事务回滚
现象:
当前事务因死锁或超时而回滚,提示信息如下:
SQL0911N The current transaction has been rolled back because of a deadlock or timeout. Reason code "2"
分析:
根据报错的具体信息,可以判定,原因为死锁导致超时。
处理:
为了帮助避免死锁或锁定超时,可以采用如下两种方法
1、对长时间运行的应用程序或有可能遇到死锁的应用程序频繁发出COMMIT 操作(若有可能的话)。
2、修改数据库参数,适当地增大锁超时时间(此处60 秒为例),命令如下:
db2 update db cfg using LOCKTIMEOUT 60