在 Derby(一种用 Java 编写的嵌入式数据库,主要用于测试或原型设计)中,有“freeze”和“unfreeze”命令可以在在线备份期间使用。“冻结”只会阻止所有数据库访问,直到调用“解冻”。这对于使用外部程序进行备份非常有用,如果外部程序比使用 Derby 的内部备份解决方案快得多,您可能会这样做。对于我的用例,我可以使用一些内置的文件系统实用程序几乎立即拍摄快照,因此它是一个恒定时间操作(不是O(length of DB files)
)。
我正在将一个已经超过 Derby 的应用程序迁移到 PostgreSQL,我想知道那里是否有任何类似的东西可以用来停顿所有连接。另外,我更想知道我的应用程序内部的序列化点是什么,这样我就不会陷入某种尴尬的状态,因此能够暂停/恢复所有其他访问对我来说真的很不错。
由于 PostgreSQL 有一个事务日志,我可以不“冻结”就创建快照,但是快照需要通过 PostgreSQL 的恢复机制运行才能使用它,否则存储在磁盘上的内容将与我拉取的内容相同普通文件系统上的插件。这种解决方案并不理想。
编辑我了解到这pg_start_backup()
是关闭的,但它不会导致传入事务阻塞,直到匹配调用pg_stop_backup()
,迫使我进行时间点恢复,以pg_start_backup()
返回从文件系统快照返回的事务 ID 。不必实际关闭 PostgreSQL 来获得它会很好(也许有一个伪关闭命令可以保持连接打开?)。
我想我们的PostgreSQL 9.4的事务级数据库迁移READ COMMITTED
要么REPEATABLE READ
或SERIALIZABLE
。在任何一种情况下,我都会遇到一组新的格式错误:
(for both)
ERROR: could not serialize access due to concurrent update
(just for SERIALIZABLE)
ERROR: could not serialize access due to read/write dependencies among transactions
Run Code Online (Sandbox Code Playgroud)
在阅读了 SSI 上的 wiki 页面和文档后,我彻底了解了可能导致这些错误的错误条件、如何处理它们,甚至是避免它们的最佳实践。
但是,我看不到从 PostgreSQL 可以提供的任何调试输出或任何调试信息中确定导致它们的数据依赖性的方法。有没有办法从数据库中获取这些信息,要么在回滚时执行额外的查询,要么通过某种日志机制?
有了这些信息,我就可以进行应用程序级别的更改(锁定、不同的查询等),从而消除一些数据竞争以避免过多的回滚。