Skip to content

76.3. 规划器统计信息和安全性#

对表pg_statistic的访问仅限于超级用户,因此普通用户无法从中了解其他用户表的内容。一些选择性估计函数将使用用户提供的运算符(查询中出现的运算符或相关运算符)来分析存储的统计信息。例如,为了确定存储的最常见值是否适用,选择性估计器必须运行适当的=运算符,以将查询中的常量与存储的值进行比较。因此,pg_statistic中的数据可能会传递给用户定义的运算符。精心设计的运算符可以故意泄露传递的操作数(例如,通过记录它们或将它们写入其他表),或者通过在错误消息中显示它们的值而意外泄露它们,在任何一种情况下都可能将pg_statistic中的数据泄露给不应该看到它的用户。

为了防止这种情况,以下内容适用于所有内置选择性估计函数。在规划查询时,为了能够使用存储的统计信息,当前用户必须对表或相关列具有SELECT权限,或者所使用的运算符必须是LEAKPROOF(更准确地说,是运算符所基于的函数)。如果不是,则选择性估计器将表现得好像没有可用统计信息,并且计划程序将继续使用默认或后备假设。

如果用户没有对表或列所需的权限,那么在许多情况下,查询最终将收到权限被拒绝的错误,在这种情况下,此机制在实践中是不可见的。但是,如果用户正在从安全屏障视图中读取,那么计划程序可能希望检查对用户来说无法访问的底层表的统计信息。在这种情况下,运算符应该是防泄漏的,否则不会使用统计信息。除了计划可能不是最优的之外,没有关于此的直接反馈。如果有人怀疑这是这种情况,他们可以尝试以更有权限的用户身份运行查询,以查看是否会产生不同的计划。

此限制仅适用于计划程序需要对pg_statistic中的一个或多个值执行用户定义的运算符的情况。因此,计划程序被允许使用通用统计信息,例如空值的比例或列中不同值的数量,而不管访问权限如何。

可能对具有用户定义运算符的统计信息进行操作的第三方扩展中包含的选择性估计函数应遵循相同的安全规则。请参阅 PostgreSQL 源代码以获取指导。