对表 pg_statistic
的访问仅限于超级用户,因此普通用户无法从中了解到其他用户表的具体内容。某些选择性估算函数会使用用户提供的操作符(查询中出现的或相关的操作符)来分析存储的统计信息。例如,为了确定存储的最常见值是否适用,选择性估算器将必须运行相应 =
操作符来比较查询中的常量与存储的值。因此 pg_statistic
中的数据可能会被传递给用户定义的函数。一个精心构造的操作符可以故意泄露传递的操作数(例如,通过记录它们或将它们写入另一个表),或者在错误消息中显示其值而意外泄露它们,在任何一种情况下都可能将 pg_statistic
中的数据暴露给不应看到它的用户。
为了防止这种情况,以下规则适用于所有内置的选择性估算函数。在规划查询时,为了能够使用存储的统计信息,当前用户必须拥有该表或相关列的 SELECT
权限,或者使用的操作符必须是 LEAKPROOF
(更准确地说,是操作符所基于的函数)。如果不是,则选择性估算器将表现为没有可用统计信息,规划器将继续使用默认或后备假设。 psql 程序的 \do+
元命令有助于确定哪些操作符被标记为 leakproof。
如果用户对表或列没有所需的权限,那么在许多情况下,查询最终会收到一个权限被拒绝的错误,在这种情况下,这个机制在实践中是不可见的。但是,如果用户正在从安全屏障视图中读取,那么规划器可能希望检查用户通常无法访问的底层表的统计信息。在这种情况下,操作符应该是 leakproof 的,否则将不使用统计信息。除了计划可能不是最优之外,没有直接的反馈。如果怀疑是这种情况,可以尝试以更特权的用户身份运行查询,看看是否会产生不同的计划。
此限制仅适用于规划器需要对 pg_statistic
中的一个或多个值执行用户定义的操作符的情况。因此,规划器被允许使用通用的统计信息,例如 NULL 值的比例或列中不同值的数量,而无需考虑访问权限。
第三方扩展中包含的选择性估算函数,如果可能使用用户定义的函数对统计信息进行操作,则应遵循相同的安全规则。请参考 PostgreSQL 源代码以获取指导。
如果您在文档中发现任何不正确、与您对特定功能的使用经验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。