Home

【DB2 数据库】09 模拟故障排查系列:DB2 实例未启动与启动失败排查实验

一、这篇文章要解决什么问题

前面的几篇实验,我已经把这条线基本跑顺了:

  • 表空间打满
  • ADD / EXTEND / AUTORESIZE
  • 容器权限异常
  • 容器路径异常
  • LOG FULL

但到了真实值班场景里,还有一类更基础、也更高频的问题:

实例根本没起来

这类问题和前面那些“表空间满”“日志满”不一样。

因为前面那些问题通常是:

  • 实例已经启动
  • 数据库也能连
  • 只是业务在某个环节报错

而这次要验证的,是更靠前的一层:

DB2 实例本身没启动,或者压根启动不起来时,系统会是什么表现。

所以这篇实验我重点想弄清楚 4 件事:

  • 实例未启动时,操作系统层面会看到什么
  • 业务连接时会报什么错
  • “实例没启动”和“实例启动失败”到底有什么区别
  • 出现这类问题后,最直接的恢复动作是什么

二、实验环境

  • 操作系统:SUSE Linux Enterprise Server 12 SP5
  • DB2 版本:DB2 v9.7.0.6 Fix Pack 6
  • 主机名:DB2Server
  • 实例:db2inst1
  • 数据库:TESTDB
  • 关键配置文件:/home/db2inst1/sqllib/db2nodes.cfg

这次实验我没有再围绕某个单独表空间做文章,而是直接围绕整个实例来做。

原因很简单:

实例层故障一旦发生,影响范围天然就比单库、单表空间更大。

三、实验前先打快照

因为这次要主动停实例、改实例配置文件,所以正式开始前我先打了一个快照:

13-准备做DB2实例未启动与启动失败排查实验

这样做的意义很明确:

  • 这次会主动让实例停掉
  • 还会故意制造一次 db2start 失败
  • 如果恢复动作做乱了,快照可以快速回到干净起点

四、故障前先确认基线状态

在真正制造故障前,我先确认当前实例和数据库都是正常的。

1. 实例进程存在

执行:

ps -ef | egrep 'db2sysc|db2wdog|db2fmcd' | grep -v grep

当时实际看到:

root     12359     1  1 15:47 pts/0    00:00:00 db2wdog 0
db2inst1 12361 12359  1 15:47 pts/0    00:00:00 db2sysc 0

这说明:

  • db2wdog
  • db2sysc 也在

也就是说,实例当前是启动着的。

2. 数据库可以正常连接

执行:

db2 connect to TESTDB
db2 terminate

返回结果:

   Database Connection Information

 Database server        = DB2/LINUXX8664 9.7.6
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTDB

DB20000I  The TERMINATE command completed successfully.

这说明:

  • 实例正常
  • TESTDB 也正常

所以这次实验的起点很清楚:

当前环境是健康的。

3. 实例节点配置文件内容正常

后面为了做“启动失败”实验,我还先看了 db2nodes.cfg 当前内容:

cat ~/sqllib/db2nodes.cfg
ls -l ~/sqllib/db2nodes.cfg

实际内容是:

0 DB2Server 0

文件信息是:

-r--r--r-- 1 db2inst1 db2iadm1 14 3月 20 16:39 /home/db2inst1/sqllib/db2nodes.cfg

为了后面可逆操作,我先做了备份:

cp ~/sqllib/db2nodes.cfg ~/sqllib/db2nodes.cfg.bak
ls -l ~/sqllib/db2nodes.cfg*

备份完成后:

-r--r--r-- 1 db2inst1 db2iadm1 14 3月 20 16:39 /home/db2inst1/sqllib/db2nodes.cfg
-r--r--r-- 1 db2inst1 db2iadm1 14 4月 15 15:54 /home/db2inst1/sqllib/db2nodes.cfg.bak

五、第一阶段:先验证“实例未启动”到底是什么现象

这一步我不靠崩溃、不靠异常退出,而是用最标准的方式直接停实例:

db2stop

返回:

2026-04-15 15:45:09     0   0   SQL1064N  DB2STOP processing was successful.
SQL1064N  DB2STOP processing was successful.

这个返回值很重要,因为它说明:

这次不是实例自己坏掉了,而是我明确把它正常停下来了。

六、实例停掉后,OS 层和 DB2 层分别是什么表现

1. 操作系统层:关键进程直接消失

停实例后,我马上再看一次进程:

ps -ef | egrep 'db2sysc|db2wdog|db2fmcd' | grep -v grep

这次没有任何输出。

这说明:

  • db2wdog 不在了
  • db2sysc 也不在了

也就是说,从 OS 层看,实例确实已经停掉。

2. DB2 层:活动数据库也看不到了

然后我继续执行:

db2 list active databases

返回:

SQL1032N  No start database manager command was issued.  SQLSTATE=57019

这一句就是这轮实验最关键的报错之一。

它说明的不是:

某个数据库有问题

而是:

数据库管理器根本就没有启动。

3. 业务连接层:连 TESTDB 也直接失败

再执行:

db2 connect to TESTDB

返回结果同样是:

SQL1032N  No start database manager command was issued.  SQLSTATE=57019

这就把证据链闭环了:

  1. 进程没了
  2. 活动数据库看不到
  3. 连库直接报 SQL1032N

也就是说,这时候故障已经不是“单个数据库不可用”,而是:

整个实例没起来。

七、一个很容易踩的小坑:别把语法错误当成故障

这次实验里,我中间还顺手踩了一个很典型的初学者小坑。

我一开始误敲了:

db2 list activate db

以及:

db2 list active database

返回的是:

SQL0104N  An unexpected token "activate" was found following "LIST".  Expected 
tokens may include:  "ACTIVE".  SQLSTATE=42601

和:

SQL0104N  An unexpected token "database" was found following "ACTIVE".  
Expected tokens may include:  "DATABASES".  SQLSTATE=42601

这两个错误非常值得记一下,因为它们不是 DB2 故障现象,而只是:

命令写法不对。

标准写法只能是:

db2 list active databases

这个细节在排障时很重要,否则很容易把“语法错误”误判成“实例报错”。

八、第一阶段的恢复动作

既然这次故障是我主动 db2stop 出来的,那么恢复当然也非常直接:

db2start

返回:

04/15/2026 15:47:03     0   0   SQL1063N  DB2START processing was successful.
SQL1063N  DB2START processing was successful.

恢复后再看进程:

root     12359     1  1 15:47 pts/0    00:00:00 db2wdog 0
db2inst1 12361 12359  1 15:47 pts/0    00:00:00 db2sysc 0

再连库验证:

db2 connect to TESTDB
db2 terminate

结果也恢复正常:

   Database Connection Information

 Database server        = DB2/LINUXX8664 9.7.6
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTDB

DB20000I  The TERMINATE command completed successfully.

到这里,第一部分实验已经完成。

九、第二阶段:人为构造一次 db2start 失败

如果只做到“实例未启动”,其实还不够。

因为生产里还有另一类很典型的场景是:

DB2 不是单纯没启动,而是你执行了 db2start,它也起不来。

为了把这个现象单独跑出来,我这次选的注入点是:

db2nodes.cfg

原因很简单:

  • 它是实例级关键配置文件
  • 启动实例时一定会读它
  • 只要先备份,再故意改坏,实验可逆性很好

十、我是怎么把 db2nodes.cfg 故意改坏的

先把实例再次正常停掉:

db2stop

返回:

2026-04-15 15:56:03     0   0   SQL1064N  DB2STOP processing was successful.
SQL1064N  DB2STOP processing was successful.

停掉后再看进程:

ps -ef | egrep 'db2sysc|db2wdog|db2fmcd' | grep -v grep

这时同样已经没有输出。

然后我把原来的:

0 DB2Server 0

故意改成了:

echo "0 DB2Server_BAD 0" > ~/sqllib/db2nodes.cfg

再确认文件内容:

cat ~/sqllib/db2nodes.cfg

结果变成:

0 DB2Server_BAD 0

这一步的本质就是:

把实例节点配置里的主机名故意改成一个错误值。

十一、db2start 失败时,实际报了什么错

配置改坏后,我直接尝试启动实例:

db2start

这次不再是 SQL1063N,而是直接报:

SQL6031N  Error in the db2nodes.cfg file at line number "1".  Reason code "10".

这就是第二部分实验的核心现象。

和第一阶段的 SQL1032N 相比,这个错误的层级更靠前。

因为它说明:

DB2 在启动实例之前,就已经发现实例关键配置文件本身有问题。

1. 进程层面:实例依然起不来

此时再看进程:

ps -ef | egrep 'db2sysc|db2wdog|db2fmcd' | grep -v grep

仍然没有输出。

说明:

实例根本没成功启动。

2. 连接层面:连 TESTDB 也直接报配置错误

我继续执行:

db2 connect to TESTDB

返回的也不再是 SQL1032N,而是:

SQL6031N  Error in the db2nodes.cfg file at line number "1".  Reason code 
"10".

这一点非常有学习价值。

因为它说明:

  • 如果只是实例没启动,常见的是 SQL1032N
  • 如果实例关键配置本身就坏了,连连接动作都可能直接报配置文件错误

也就是说:

SQL6031NSQL1032N 虽然都表现为“连不上库”,但它们的根因层级并不一样。

十二、这次启动失败是怎么恢复的

恢复动作非常直接:

1. 用备份文件恢复 db2nodes.cfg

cp -f ~/sqllib/db2nodes.cfg.bak ~/sqllib/db2nodes.cfg

恢复后再次确认文件内容:

cat ~/sqllib/db2nodes.cfg

内容重新变回:

0 DB2Server 0

2. 重新启动实例

然后再次执行:

db2start

这次返回恢复正常:

04/15/2026 16:00:14     0   0   SQL1063N  DB2START processing was successful.
SQL1063N  DB2START processing was successful.

3. 再次看进程

ps -ef | egrep 'db2sysc|db2wdog|db2fmcd' | grep -v grep

输出:

root     12621     1  3 16:00 pts/0    00:00:00 db2wdog 0
db2inst1 12623 12621  3 16:00 pts/0    00:00:00 db2sysc 0

4. 再次验证数据库连接

db2 connect to TESTDB
db2 terminate

结果恢复正常:

   Database Connection Information

 Database server        = DB2/LINUXX8664 9.7.6
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTDB

DB20000I  The TERMINATE command completed successfully.

到这里,第二部分实验也闭环了。

十三、这次实验到底证明了什么

到这里,这次“实例未启动与启动失败”实验,已经把我最想验证的几个点都跑出来了。

1. db2stop 停掉的是整个实例,不是某个单独数据库

这一点从现象就能看出来:

  • db2sysc 进程消失
  • db2 list active databases 直接报错
  • db2 connect to TESTDB 也失败

2. 实例单纯没启动时,典型错误码是 SQL1032N

也就是:

SQL1032N  No start database manager command was issued.  SQLSTATE=57019

这类报错更接近:

实例当前没起来,但配置本身不一定坏。

3. 实例启动失败时,错误码可能比 SQL1032N 更靠前

这次我故意改坏 db2nodes.cfg 后,出现的是:

SQL6031N  Error in the db2nodes.cfg file at line number "1".  Reason code "10".

这说明:

DB2 在启动前检查实例关键配置时,就已经发现问题了。

4. 判断这类问题,最好同时看三层

我觉得这次实验最值得初学者记住的,不是某一条命令,而是这条判断链:

  1. 进程层db2sysc / db2wdog 在不在
  2. 实例层db2 list active databases 返回什么
  3. 连接层db2 connect to TESTDB 报什么错

这三层合起来看,判断会比单看一条错误码稳得多。

十四、实验结束后的收尾

这次实验做完后,收尾动作其实很简单:

  • db2nodes.cfg 恢复为原始内容
  • 确认 db2start 成功
  • 再连一次 TESTDB
  • 最后 db2 terminate

也就是说,实验结束时,环境应该回到:

  • 实例正常
  • TESTDB 可连
  • db2nodes.cfg 内容正常

这次我没有额外删数据库对象,因为这轮实验主要动的是实例状态和实例配置文件,不是表或表空间。

十五、把这篇文章压缩成三句话

最后把这次实验压缩成三句话:

  1. 实例没启动时,最典型的错误码之一是 SQL1032N
  2. 如果实例关键配置文件 db2nodes.cfg 被改坏,db2start 可能直接报 SQL6031N
  3. 处理这类问题时,最好同时从进程、实例命令和数据库连接三层去判断。

十六、下一篇最自然写什么

如果继续沿着 DB2 运维故障排查这条线往下写,下一篇最自然的方向,我觉得有两个:

  • NUM_LOG_SPAN / 长事务限制实验
  • 数据库连接数、应用句柄与 force application 实验

如果更偏值班实战,我会更想继续写:

【DB2 数据库】10 模拟故障排查系列:长事务占用日志与应用强制断开实验

因为做到这里:

  • 表空间
  • 容器
  • 日志
  • 实例启动

这几类高频故障已经基本都有代表实验了。

下一步继续往“应用句柄、连接管理、强制断连”走,会非常自然。

Linux DB2 数据库