5

DB2 "The transaction log for the database is full" 问题的解决

 2 years ago
source link: https://yanbin.blog/db2-the-transaction-log-for-the-database-is-full-fix/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

DB2 "The transaction log for the database is full" 问题的解决

2022-02-16 — Yanbin

在使用 DB2 的 Community 版本的 Docker 镜像 ibmcom/db2 进行测试,启动 Docker 容器的命令是

$ docker run -name db2server --privileged=true -p 50000:50000 \
    -e LICENSE=accept \
    -e DB2INSTANCE=db2user \
    -e DB2INST1_PASSWORD=password123 \
    -e DBNAME=test \
    ibmcom/db2

当使用多线程以及 JDBC 的 Batch Update 时,出现 "The transaction log for the database is full" 问题,一旦出现这个问题时,用数据库客户端连接后即使执行一条简单的 insert/update 语句也会报同样的错误。于是只能减少线程数和 Batch Update 时的记录来勉强过关,但性能上与其他数据库就有很大的差别了。

问题在哪里

因为在产品数据库中用 10 个线程,Batch Size 设置为 500 应该不会过分,所以必须找到 transaction log 限制在哪里。

DB2 的操作需用 db2 命令,在 Docker 容器中要切换到 ${DB2INSTANCE} 环境变量代表的用户,我们这里是 db2user, 因此我们登陆到 db2server Docker 容器中

$ docker exec -it db2server sh -c "su - db2user"
$ export DBNAME=test

我们进入到 Docker 容器中后就可以执行 db2 命令了,查看 log file 相应的数据库配置

$ db2 get db cfg | grep -i "log file"
Log file size (4KB) (LOGFILSIZ) = 1024
Number of primary log files (LOGPRIMARY) = 16
Number of secondary log files (LOGSECOND) = 22
Changed path to log files (NEWLOGPATH) =
Path to log files = /database/data/db2user/NODE0000/SQL00001/LOGSTREAM0000/
First active log file = S0000000.LOG
Num. of active log files for 1 active UOW(NUM_LOG_SPAN) = 0
Percent log file reclaimed before soft chckpt (SOFTMAX) = 0

这里我们看到日志文件大小(LOGFILESIZ) 为 1024, 其实质就是在目录 Path to log files 下的一个个文件大小不能超过 1K 大小,真的是一个稍微大的事物就容纳不下。

修改日志大小上限

我们要对它的值进行修改,另两个配置 LOGPRIMARY 和 LOGSECOND 必要时也改一改。使用命令

$ db2 update db cfg using LOGFILSIZ 10240
$ db2 update db cfg using LOGPRIMARY 100
$ db2 update db cfg using LOGSECOND 100

改完后可用 db2 get db cfg | grep -i "log file" 立即看到修改后的值,但要生效的话必须重启数据库实例。

重启数据库实例

$ db2 force applications all
$ db2stop force
$ db2start

说明:如果没数据库连接,db2stop 就能停止数据库,否则会提示

QL1025N The database manager was not stopped because databases are still active.

db2stop force 强制停掉数据库,先用 db2 force applications all 断掉数据库连接后,其实紧接着的 db2stop 就不需要 force 了

待数据库重新启动后就能支持更大的事物,更多客户端连接及更大的 Batch Update Size 了。

最后总结一下

挑出几个必须的步骤

  1. 进到数据库服务器并切换到数据库用户
  2. db2 get db cfg for test | grep LOGFILSIZ 查看日志文件大小限制
  3. db2 update db cfg for test using LOGFILSIZ 10240
  4. db2stop force
  5. db2start

执行 db2 命令时的补充:

db2 update db cfg 命令可带上数据库名称(比如未设置 DBNAME 环境变量的情况下)

$ db2 update db cfg for test using LOGFILSIZ 10240

如果没有设置 DBNAME=test 环境变量就执行 db2 get db cfg 命令会提示

SQL1024N A database connection does not exist. SQLSTATE=08003

不想设置  DBNAME 环境变量操作该数据库的办法可以分两步

  1. 先执行 db2 进行 db2 的提示符 "db2 =>"
  2. 在 "db2 =>" 提示符下执行 "connect to test"
  3. 继续在 "db2 =>"  提示符下执行 "get db cfg" 命令

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK