我的数据库生成了很多孤立页面,我正试图找出原因。
我经常在我的 python 代码中使用fdb 驱动程序这样做:
cursor = connection.cursor()
for item in list:
try:
cursor.execute(sql_insert_statement, (item,))
except fdb.DatabaseError:
log(f"Exception: duplicate found in database for {item}")
continue
connection.commit()
由于违反主键唯一约束(这很好),我生成了很多异常,并且当列表中的所有项目都执行了它们的 INSERT 语句时,我只提交一次“主”事务。
这是正确的做事方式吗?或者我是否必须在每次发生异常后提交(带有一个无论其结果如何finally
都会在每次发生后触发的子句)?try
至少,从文档cursor.execute
来看,我怀疑我是否需要在每次之后提交。
当相关工作单元完成时,您总是需要提交或回滚事务。Firebird 事务不会因错误而自动中止(但通常会撤消导致错误的语句的影响)。如果您不提交或回滚并且连接关闭,打开的事务最终将被回滚,但这是低效的并且可能导致性能下降(取决于该事务保持打开状态的时间)。
所以,不,您不必在错误发生后立即提交(或回滚),而是在工作完成时提交,或者在需要中止工作单元时回滚。
但是,运行时间非常长的事务可能会给其他事务带来问题,因此请确保您的工作单元(事务)尽可能短(但不要短于完成工作所需的时间)。
但是,提交或回滚失败不会导致有关孤立页面的错误。孤立页面是 Firebird 分配数据库页面的结果,但未能将它们添加/注册到对象(表、索引等),这意味着它们存在并占用空间,但无法使用,因为没有任何东西指向它们。
这通常是 Firebird 在写入或分配错误中崩溃或被杀死的结果。您可能需要检查日志中的错误。