Warum kann ich ein Objekt in meinem Amazon-Redshift-Cluster nicht DROP ablegen?

Lesedauer: 4 Minute
0

Ich kann keine Tabelle oder Ansicht in meinem Amazon-Redshift-Cluster löschen.

Kurzbeschreibung

Möglicherweise können Sie aus den folgenden Gründen kein Objekt, wie z. B. eine Tabelle oder eine Ansicht, in Ihrem Amazon Redshift-Cluster ablegen:

  • **Unzureichende Berechtigungen:**Der Benutzer hat nicht die Rechte, das Objekt zu löschen. Der Benutzer muss Eigentümer des Objekts sein oder über Administratorrechte verfügen.
  • **Objektabhängigkeit:**Eine andere Ansicht oder Tabelle bezieht sich auf die Tabellenspalten.
  • **Streit sperren:**Eine Transaktion sperrt das Objekt und führt dazu, dass der Drop-Vorgang hängen bleibt.

Behebung

Unzureichende Berechtigungen

In Amazon Redshift kann nur der Tabellenbesitzer, der Schemabesitzer oder ein Superuser eine Tabelle löschen.

Um Benutzerberechtigungen und Besitzrechte zu bestätigen, führe das Skript v_get_obj_priv_by_user.sql von der GitHub-Website aus:

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)
;

Führen Sie die folgende Abfrage aus, um den Besitzer der Beziehung zu finden:

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

**Hinweis:**Ersetzen Sie schema_name durch den Namen Ihres Schemas und relation_name durch den Namen Ihrer Beziehung.

Objektabhängigkeit

Ihr Dropvorgang schlägt möglicherweise mit der folgenden Fehlermeldung fehl:

„Ungültiger Vorgang: Tabelle/Ansicht kann nicht gelöscht werden, da andere Objekte davon abhängen“

Der Fehler Ungültiger Vorgang weist darauf hin, dass vom Zielobjekt Objektabhängigkeiten bestehen.

Um die Objekte zu identifizieren, die von der Zieltabelle abhängen, erstellen Sie die folgenden drei Ansichten:

  • Eine Ansicht zur Identifizierung der Einschränkungsabhängigkeit. Weitere Informationen findest du unter v_constraint_dependency.sql auf der GitHub-Website.
  • Eine Ansicht zur Identifizierung der abhängigen Ansichten. Weitere Informationen findest du unter v_view_dependency.sql auf der GitHub-Website.
  • Eine Objektansicht, die die beiden vorherigen Ansichten aggregiert. Weitere Informationen findest du unter v_object_dependency.sql auf der GitHub-Website.

Nachdem Sie die drei Ansichten erstellt haben, führen Sie das Skript v_object_dependency.sql aus, um die abhängigen Objekte des Zielobjekts abzurufen:

select * from admin.v_object_dependency where src_objectname=target object

**Hinweis:**Ersetzen Sie das Zielobjekt durch Ihr Zielobjekt.

Verwenden Sie den CASCADE-Parameter, um alle zugehörigen Objekte zusammen mit dem Zielobjekt zu löschen:

drop table target object cascade;

**Hinweis:**Ersetzen Sie das Zielobjekt durch Ihr Zielobjekt.

Lock-Konflikte

Wenn der Drop-Befehl hängt oder nichts ausgibt, wenn Sie einen Drop ausführen, dann ist das Objekt möglicherweise durch eine Transaktion gesperrt. Daher können Sie das AccessExclusiveLock für die Tabelle nicht erwerben. Das AccessExclusiveLock ist erforderlich, um ein Objekt zu löschen.

Verwenden Sie die folgende Syntax, um Sperren zu identifizieren:

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);

Verwenden Sie PG_TERMINATE_BACKEND, um die Sperren aufzuheben. Weitere Informationen zum Erkennen und Freigeben von Sperren in Amazon Redshift finden Sie unter Wie erkenne und lösche ich Sperren in Amazon Redshift?

AWS OFFICIAL
AWS OFFICIALAktualisiert vor 4 Monaten