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中没有读取权限?
自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可以添加条件以过滤特定用户拥有的大对象.