¿Por qué no puedo BORRAR un objeto en mi clúster de Amazon Redshift?

4 minutos de lectura
0

No puedo borrar una tabla o una vista en mi clúster de Amazon Redshift.

Breve descripción

Es posible que no pueda borrar un objeto en su clúster de Amazon Redshift, como una tabla o una vista, por los siguientes motivos:

  • Permisos insuficientes: el usuario no tiene los permisos para borrar el objeto. El usuario debe ser propietario del objeto o tener permisos de administrador.
  • Dependencia del objeto: otra vista o tabla hace referencia a las columnas de la tabla.
  • Contención de bloqueo: una transacción está bloqueando el objeto y, en consecuencia, también se bloquea la operación de borrado.

Solución

Permisos insuficientes

En Amazon Redshift, solo el propietario de la tabla, el propietario del esquema o un superusuario pueden borrar una tabla.

Para confirmar los permisos del usuario y si es el propietario, ejecute el script v_get_obj_priv_by_user.sql desde el sitio web de GitHub:

CREATE OR REPLACE VIEW admin.v_get_obj_priv_by_user
AS
SELECT
    *
FROM
    (
    SELECT
         schemaname
        ,objectname
        ,objectowner
        ,usename
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AS sel
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AS ins
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AS upd
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AS del
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AS ref
    FROM
        (
        SELECT schemaname, 't' AS obj_type, tablename AS objectname, tableowner as objectowner, QUOTE_IDENT(schemaname) || '.' || QUOTE_IDENT(tablename) AS fullobj FROM pg_tables
        WHERE schemaname !~ '^information_schema|catalog_history|pg_'
        UNION
        SELECT schemaname, 'v' AS obj_type, viewname AS objectname, viewowner as objectowner, QUOTE_IDENT(schemaname) || '.' || QUOTE_IDENT(viewname) AS fullobj FROM pg_views
        WHERE schemaname !~ '^information_schema|catalog_history|pg_'
        ) AS objs
        ,(SELECT * FROM pg_user) AS usrs
    ORDER BY fullobj
    )
WHERE (sel = true or ins = true or upd = true or del = true or ref = true)
;

Para encontrar al propietario de la relación, ejecute la siguiente consulta:

select schemaname,tablename, tableowner From pg_tables where schemaname='schema_name' and tablename='relation_name';

Nota: Sustituya schema_name por el nombre de su esquema, y relation_name por el nombre de la relación.

Dependencia de objetos

Es posible que la operación de borrado falle y aparezca el siguiente mensaje de error:

«Invalid operation: cannot drop table/view because other objects depend on it»

El error Invalid operation indica que hay dependencias de objetos en el objeto de destino.

Para identificar los objetos que dependen de la tabla de destino, cree las tres vistas siguientes:

  • Una vista para identificar la dependencia de la restricción. Para obtener más información, consulte v_constraint_dependency.sql en el sitio web de GitHub.
  • Una vista para identificar las vistas dependientes. Para obtener más información, consulte v_view_dependency.sql en el sitio web de GitHub.
  • Una vista de objetos que agrega las dos vistas anteriores. Para obtener más información, consulte v_object_dependency.sql en el sitio web de GitHub.

Después de crear las tres vistas, ejecute el script v_object_dependency.sql para obtener los objetos dependientes del objeto de destino:

select * from admin.v_object_dependency where src_objectname=target object

Nota: Sustituya target object por su objeto de destino.

Utilice el parámetro CASCADE para borrar todos los objetos relacionados junto con el objeto de destino:

drop table target object cascade;

Nota: Sustituya target object por su objeto de destino.

Contención de bloqueo

Si el comando drop se bloquea o no muestra nada cuando se borra, es posible que una transacción esté bloqueando el objeto. Como resultado, no podrá adquirir AccessExclusiveLock en la tabla. Para borrar un objeto, se necesita AccessExclusiveLock.

Para identificar los bloqueos, utilice la siguiente sintaxis:

select a.txn_owner, a.txn_db, a.xid, a.pid, a.txn_start, a.lock_mode, a.relation as table_id,nvl(trim(c."name"),d.relname) as tablename, a.granted,b.pid as blocking_pid ,datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' as txn_durationfrom svv_transactions a
left join (select pid,relation,granted from pg_locks group by 1,2,3) b
on a.relation=b.relation and a.granted='f' and b.granted='t'
left join (select * from stv_tbl_perm where slice=0) c
on a.relation=c.id
left join pg_class d on a.relation=d.oid
where  a.relation is not null;
And once you identify the locking transaction either COMMIT the blocking transaction or terminate the session of the blocking transaction if it is no longer necessary by :
select pg_terminate_backend(PID);

Utilice PG_TERMINATE_BACKEND para liberar los bloqueos. Para obtener más información sobre cómo detectar y liberar bloqueos en Amazon Redshift, consulte ¿Cómo puedo detectar y liberar bloqueos en Amazon Redshift?

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 4 meses