在heroku上访问pg_largeobject

时间:2013-02-22 00:14:06

标签: database postgresql heroku

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

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

select distinct loid from pg_largeobject 
Where loid Not In (select id from table )

然后我跑:

SELECT lo_unlink(loid)

每个ID。

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

select * from pg_largeobject limit 1;

给了我一个错误:

ERROR:  permission denied for relation pg_largeobject

有关如何解决此问题的任何建议,或者甚至是我们在heroku中pg_largeobject没有读取权限的原因?

1 个答案:

答案 0 :(得分:8)

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

  

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

     

以前,任何数据库用户都可以读取或修改任何大对象。   现在可以根据大型授予和撤销读写权限   对象,跟踪大对象的所有权。

如果它适用于您的开发实例,则可能是因为它的版本为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

因此,对于9.0以上的非超级用户,您的初始查询可以更改泄漏的大对象:

select oid from pg_largeobject_metadata
 Where oid Not In (select id from table )

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