运行“授予连接数据库”时“行太大(...)最大大小 8160”

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

我在使用 postgres 11 时遇到了奇怪的问题。

我正在创建一群用户,然后为他们分配一些角色,同时也让他们连接到某些数据库。

成功创建 2478 个角色后,当我尝试创建新用户时,出现此错误:

db=# create user foo;
CREATE ROLE
db=# grant connect on database db to foo;
ERROR:  row is too big: size 8168, maximum size 8160

数据库日志中显示相同的错误。

我检查了数据库卷是否空间不足,还有 1T 可用空间...

我无法想象 postgres 在运行简单的 grant 时会尝试插入超过 8k...?


编辑:

似乎已经有人问过类似的问题(模式的使用权限):

错误:行太大:大小 8168,最大大小 8164

因此,解决方案是创建一个角色,例如

connect_to_my_db
并授予连接到该角色的权限,然后不要向每个用户运行
GRANT connect
,而是执行
GRANT connect_to_my_db

postgresql
2个回答
4
投票

您自己找到了解决方案,让我补充一下错误原因的解释:

每个表行都存储在表的 8KB 块之一中,因此这是其大小限制。

普通表有一个 TOAST 表,其中可以离线存储长属性。这允许 PostgreSQL 存储很长的行。

现在系统目录表没有 TOAST 表,因此行大小限制为 8KB。

对象的访问控制列表存储在对象的目录中,因此表上的多个权限可能会超出限制。

很高兴 - 如果您必须单独管理数千个用户的权限,无论如何您最终都会陷入 DBA 地狱。


0
投票

因此,解决方案是创建一个角色,例如 connect_to_my_db 并授予连接到该角色的权限,然后不要运行 GRANT connect 到每个用户,而是执行 GRANT connect_to_my_db。

如果您处于 Python 环境中,则可以使用该包 https://github.com/uktrade/pg-sync-roles(全面披露:我曾经/正在大力参与制作)来执行此操作有点“透明”——它在幕后创造了中间角色。它(目前)可以对数据库 CONNECT、表 SELECT、模式 USAGE 和 CREATE 执行此操作。

因此,从对象的角度来看,只有one角色具有给定权限类型的GRANT,避免了GRANT时出现“行太大”错误。

这是一个早期阶段的项目,但您可以使用它来帮助管理数千个用户的权限,其中每个用户都需要自己的自定义权限集。

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