在heroku上访问pg_largeobject

bva*_*ken 5 database postgresql heroku

我正在尝试清理heroku上的postgres数据库,其中一些大型对象已经失控,我想删除不再使用的大型对象.

在我的开发机器上,我可以这样做:

select distinct loid from pg_largeobject 
Where loid Not In (select id from table )
Run Code Online (Sandbox Code Playgroud)

然后我跑:

SELECT lo_unlink(loid)
Run Code Online (Sandbox Code Playgroud)

在每个ID上.

但是在heroku上,我pg_largeobject甚至无法进行任何选择

select * from pg_largeobject limit 1;
Run Code Online (Sandbox Code Playgroud)

给我一个错误:

ERROR:  permission denied for relation pg_largeobject
Run Code Online (Sandbox Code Playgroud)

任何建议如何解决这个问题,或者实际上甚至为什么我们pg_largeobject在heroku中没有读取权限?

Dan*_*ité 8

自PostgreSQL 9.0以来,非超级用户无法访问pg_largeobject.这在发行说明中有记录:

使用GRANT/REVOKE(KaiGai Kohei)添加控制大对象(BLOB)权限的功能

以前,任何数据库用户都可以读取或修改任何大对象.现在可以为每个大对象授予和撤消读写权限,并跟踪大对象的所有权.

如果它适用于您的开发实例,则可能是因为它的版本8.4或更低版本,或者因为您以超级用户身份登录.

如果您无法以heroku的超级用户身份登录,我猜您可以转储远程数据库pg_dump,然后在本地重新加载,将泄漏的OID识别为本地超级用户,将它们放入带有lo_unlink命令的脚本中,最后播放针对heroku实例的脚本.

更新:

根据psql \dl命令如何查询数据库pg_catalog.pg_largeobject_metadata,通过此查询可以看到它可用于检索所有大对象的OID和所有权:

SELECT oid as "ID",
  pg_catalog.pg_get_userbyid(lomowner) as "Owner",
  pg_catalog.obj_description(oid, 'pg_largeobject') as "Description"
  FROM pg_catalog.pg_largeobject_metadata   ORDER BY oid
Run Code Online (Sandbox Code Playgroud)

因此,对于9.0+以上的非超级用户,可以将初始查询找到泄漏的大对象:

select oid from pg_largeobject_metadata
 Where oid Not In (select id from table )
Run Code Online (Sandbox Code Playgroud)

如果需要,lomowner可以添加条件以过滤特定用户拥有的大对象.