You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PostgreSQL只读用户可创建临时表:原因排查与解决咨询

为什么只读用户还能创建临时表?怎么解决?

问题根源

PostgreSQL里有个很容易被忽略的默认权限规则:所有新建角色默认会继承public角色的权限,而public角色默认拥有数据库的TEMP(临时表创建)权限。你之前的操作里,只撤销了postgres角色的TEMP权限,既没处理publicTEMP权限,也没直接限制read_access的相关权限,所以这个只读用户依然能通过继承public的权限创建临时表。

另外要注意:临时表是在会话专属的pg_temp模式中创建的,只要用户拥有数据库的TEMP权限,就自动获得对自己会话pg_temp模式的CREATE权限——这也是为什么你之前针对public Schema的REVOKE CREATE操作没拦住它的原因。

解决步骤

  • 1. 先确认当前权限状态(可选但推荐)
    执行以下命令查看read_access的角色属性:

    SELECT rolname, rolcanlogin, rolcreaterole, rolcreatedb, rolsuper, rolreplication, rolbypassrls FROM pg_roles WHERE rolname = 'read_access';
    

    再查看目标数据库的TEMP权限分配:

    SELECT grantee, privilege_type 
    FROM information_schema.table_privileges 
    WHERE table_catalog = '你的数据库名' 
    AND privilege_type = 'TEMPORARY';
    
  • 2. 撤销read_access的TEMP权限
    直接针对这个用户撤销数据库的临时表创建权限:

    REVOKE TEMP ON DATABASE 你的数据库名 FROM read_access;
    
  • 3. (可选)彻底限制所有普通用户的TEMP权限
    如果你的数据库里不需要其他普通用户创建临时表,可以直接撤销public角色的TEMP权限,这样所有继承public的角色都会失去这个权限:

    REVOKE TEMP ON DATABASE 你的数据库名 FROM public;
    
  • 4. 验证效果
    切换到read_access用户,尝试创建临时表:

    CREATE TEMP TABLE test_temp (id int);
    

    如果权限设置正确,会收到类似ERROR: permission denied to create temporary table的报错,说明限制生效了。

补充说明

  • 如果你之后新建其他角色,记得要么单独撤销它们的TEMP权限,要么保持public的TEMP权限被撤销状态,避免重复踩坑。
  • 临时表的权限控制只和数据库级的TEMP权限有关,和Schema级的CREATE权限无关,所以之前针对public Schema的权限设置不会影响临时表的创建逻辑。

内容的提问来源于stack exchange,提问作者purplefloyd

火山引擎 最新活动