首页 > 解决方案 > 运行“更改表”时出错最初未记录”通过 Java

问题描述

表中有数百万条记录需要删除,但我需要注销事务日志,因为我使用 Alter Table 最初未记录但它抛出错误并使表无法访问。表中没有分区,但表中包含索引和序列。自动提交也关闭。 错误:DB2 SQL 错误:SQLCODE=-911,SQLSTATE=40001,SQLERRMC=68,DRIVER=3.65.77

只有通过java运行时才会出现上述错误,如果从客户端运行则不会出现任何错误。需要知道在哪些情况下查询可能会失败,或者在运行此查询之前需要确保什么。如何在代码中处理这种情况。

标签: javajdbcdb2database-administration

解决方案


在寻求 Db2 方面的帮助时,请始终将 Db2 服务器版本和平台(Z/OS、i 系列、Linux/Unix/Windows)放在您的问题中,因为答案可能取决于这些事实。

带有 sqlerrmc 68 的 sqlcode -911 是锁定超时。这不是僵局。您的作业可能不是唯一同时访问该表的作业。监视函数和管理视图让您可以随时查看存在哪些锁(例如 SNAPLOCK 和 SNAP_GET_LOCK 表函数等)。

有关以下建议的详细信息,请参阅 Db2 知识中心,以自学。

为您的事务将表放入未记录的初始状态是高风险的,特别是如果您是新手,因为如果您的事务失败,那么您可能会丢失整个表。

如果您坚持使用这种方法,请采取预防措施并排练时间点恢复,以防您的行为造成损害。仔细验证您的备份和恢复步骤。

禁用自动提交后,可以以独占模式锁定表,但如果目标表是热表,这可能会导致生产服务中断。如果您拥有相关权限,也可以强制关闭持有锁的应用程序。

如果有任何其他正在运行的作业(即不是您自己的代码)在您尝试更改该表时访问该表,而 -911 几乎是不可避免的。你的方法可能是不明智的。

批量删除可以通过其他方式实现,这取决于你要权衡取舍。这是一个经常被问到的问题。它也不是 RDBMS 特定的。考虑做更多的研究,因为这是一个广泛讨论的话题。

批量删除的替代方法包括:

  • 批处理记录的删除,每批提交一次,可调整的批量大小(以确保您避免 -964 事务日志已满的情况)。这需要编写一个循环,并且您应该考虑“设置当前超时而不等待”以及稍后自动重试任何失败的批次(例如,由于锁定而失败的批次)。这种方法会缓慢而逐渐地删除行,但会增加并发性。您正在用长时间缓慢的执行来换取对其他正在运行的作业的最小影响。

  • 创建一个相同的影子表,在其中只插入您希望保留的行。然后在目标表上使用 truncate table ... immediate(这是一个未记录的操作),最后将保留行从影子表恢复到目标表中。一个不太安全的变体是只导出要保留的行,然后导入替换

  • 根据 Db2 许可证和清除频率,将数据(或部分数据)迁移到范围分区表中,并使用分离可能是更好的长期解决方案

有关上述建议的详细信息,请参阅在线 Db2 知识中心。


推荐阅读