在对DB2数据库进行批量增删的时候, 如果数据量比较大会导致SQL0964N错误, DB2 Knowledge center(http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.messages.sql.doc/doc/msql00964c.html)对该错误的解释为"The transaction log for the database is full", 即事务日志满. 由于在进行增删操作的时候数据库需要记录事务日志以便在发生异常时能够回滚, 当批处理的数据量比较大超过了事务日志空间的容量就会发生这样的错误.
解决这个问题主要有两个方法
1, 对执行的操作取消事务日志
首先取消数据库的自动提交功能, 在命令行可以通过+C参数取消, 然后需要修改导致事务日志满的表tbl.
ALTER TABLE tbl ACTIVATE NOT LOGGED INITIALLY;
现在可以执行之前导致事务日志满的SQL语句了, 例如
DELETE FROM tbl
现在可以发现没有事务日志满的错误了, 最后再提交. 这是最为简单快速的方式.
ATTENTION: 但是必须要慎重使用这个方法, 因为当操作失败的时候将导致改表无法恢复.
有一次我需要从一个有1.4亿行的表里面删除大概3000W的数据, 执行完NOT LOGGED INITIALLY后开始删除数据, 由于删除时间太长我就强制取消了删除操作, 删除操作取消后DB2返回如下信息:
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL1476N 当前事务因错误 "-952" 而回滚。 SQLSTATE=40506
悲剧的是当我准备再次对这张表进行操作的时候DB2报如下信息:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL1477N For table "DB2INST1.IBASE_RAW2" an object "28" in table space "2"
cannot be accessed. SQLSTATE=55019
经查询DB2 Info Center, 得到的结果是...
The table had NOT LOGGED INITIALLY activated when the unit of work was rolled back.
解决办法是...
If the object is a table and it had NOT LOGGED INITIALLY activated, drop the table. If this table is required, re-create it
只能删除表, 哭瞎...
2, 增大日志空间
日志空间的大小=(LOGPRIIMARY + LOGSECOND) * LOGFILSIZ * 4K, 因此可以通过修改数据库的配置文件LOGPRIIMARY, LOGSECOND和LOGFILSIZ来增大事务日志空间. 其中更改LOGSECOND不需要断开DB连接, 是最为简单的方法是