2013-02-22 28 views
5

Sto cercando di pulire il mio database postgres su heroku dove alcuni oggetti di grandi dimensioni sono andati fuori controllo e voglio rimuovere oggetti di grandi dimensioni che non sono più usati.accesso pg_largeobject su heroku

Sulla mia macchina dev, che posso fare:

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

poi corro:

SELECT lo_unlink(loid) 

su ciascuno di tali ID.

Ma Heroku, non posso correre alcun seleziona il pg_largeobject, come anche

select * from pg_largeobject limit 1; 

mi dà un errore:

ERROR: permission denied for relation pg_largeobject 

Eventuali suggerimenti su come ovviare a questo, o in realtà anche perché non abbiamo accesso in lettura su pg_largeobject in heroku?

+0

Cosa mostra '\ dp + pg_catalog.pg_largeobject'? –

+0

Schema | Nome | Tipo | Privilegi di accesso | Privilegi di accesso alla colonna ------------ + ---------------- + ------- + -------- ----------- + -------------------------- pg_catalog | pg_largeobject | tabella | | – bvanklinken

+0

scusa non molto visibile, ma nessun accesso privato – bvanklinken

risposta

8

Da PostgreSQL 9.0, un utente non superutente non può accedere a pg_largeobject. Questo è documentato nelle note di rilascio:

Add the ability to control large object (BLOB) permissions with GRANT/REVOKE (KaiGai Kohei)

Formerly, any database user could read or modify any large object. Read and write permissions can now be granted and revoked per large object, and the ownership of large objects is tracked.

Se funziona sul vostro esempio di sviluppo, è sia perché è la versione 8.4 o inferiore, o perché sei loggato come superutente.

Se non è possibile eseguire il login come superutente su Heroku, penso che si potrebbe eseguire il dump del database remoto con pg_dump, poi ricaricarlo a livello locale, di identificare gli OID trapelato come superuser locale, metterli in uno script con il lo_unlink comandi, e infine riprodurre questo script contro l'istanza di heroku.

Aggiornamento:

Sulla base come il comando psql \dl interroga il database, sembra che pg_catalog.pg_largeobject_metadata può essere utilizzato per recuperare i OID e la proprietà di tutti gli oggetti di grandi dimensioni, attraverso questa interrogazione:

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 

Così la vostra query iniziale trovare gli oggetti di grandi dimensioni trapelate potrebbero essere cambiati per i non-superuser con 9.0+ in:

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

e, se necessario, una condizione su lomowner potrebbe essere aggiunta al filtro sugli oggetti di grandi dimensioni di proprietà di un utente specifico.

+0

ok, sono su in dev. non c'è modo di elencare gli ID di oggetti di grandi dimensioni a cui l'utente corrente ha accesso? – bvanklinken

+0

@bvanklinken: sembra che ci sia, ho aggiornato la risposta. –

+0

ah grazie. In realtà avevo guardato la tabella dei metadati. ma la documentazione (http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject-metadata.html) e la query select * di pg_largeobject_metadata non suggeriscono nulla su un campo di oid - quindi mi sono completamente perso quella. – bvanklinken