手动复制 PostgreSQL:我可以确保用户的查询始终是确定性的吗?

问题描述 投票:0回答:1

我想知道运行多个从空状态初始化的 PostgreSQL 数据库实例是否可行,并通过对它们应用相同的查询序列来手动保持它们同步。基本上,我的问题是:查询中的(固有的)非确定性水平是什么,有没有办法限制它?

非确定性的一个明显来源是诸如 RANDOM() 之类的函数或访问当前系统时间的日期时间函数。我可以限制用户执行这些内置函数吗?

PostgreSQL 已经有了 VOLATILE 函数 的概念。这是否也适用于内置程序,我可以根据该模式撤销访问权限吗?

对于上下文,我正在尝试构建类似 rqlite 的东西,它在 Raft 共识协议之上实现 SQLite。他们重写查询,以便在服务器之间手动同步 RANDOM() 调用的输出。就我的目的而言,我不需要这种类型的机制(我怀疑它在 PostgreSQL 中会复杂得多),而且我宁愿摆脱所有非确定性函数。

postgresql distributed-system
1个回答
1
投票

从广义上讲,您希望有一个允许的操作和函数列表,而不是试图排除它们。正如您所发现的,这排除了任何访问环境的内容(时间、随机性等),除非您也同步该环境。还要考虑任何每个会话/用户

SET
选项。

您还需要禁止任何没有完全指定排序顺序的查询。如果您正在处理“按姓名排列的前 N 个人”,并且两个人具有相同的姓名,则两个实例可能会返回不同的结果。当然,这也适用于任何子查询。

最后,您需要对并发性进行非常精确的控制。如果不知道查询的开始和结束顺序,您就无法在多个节点上重现一组查询。

如果您允许安装扩展或自定义功能,您也需要审核这些。

您可能希望依靠两阶段提交协议来尝试确保所有服务器提交或回滚。

https://www.postgresql.org/docs/16/two-phase.html

© www.soinside.com 2019 - 2024. All rights reserved.