Pourquoi les utilisateurs Amazon Redshift supprimés apparaissent-ils toujours dans la table pg_class, mais pas dans la table pg_user ?
Brève description
Les utilisateurs supprimés peuvent toujours apparaître dans la table pg_class lorsque l'utilisateur supprimé possède un objet dans une autre base de données du cluster. La commande DROP USER vérifie uniquement la base de données actuelle pour les objets détenus par l'utilisateur qui est sur le point d'être supprimé. Si l'utilisateur possède un objet dans une autre base de données, aucune erreur n'est déclenchée. Au lieu de cela, l'utilisateur supprimé conserve la propriété de l'objet et usesysid apparaît toujours dans la table pg_class.
Solution
Exécutez la commande suivante sur chaque base de données de votre cluster. Cette commande vérifie les objets détenus par des utilisateurs supprimés.
select distinct schemaname, tablename, tableowner from pg_tables where tableowner like '%unknown%';
Si un utilisateur supprimé possède toujours des objets dans une base de données, vous obtenez un résultat similaire à ce qui suit. Le propriétaire de table est « inconnu », car le propriétaire a été supprimé de la table pg_user, où les noms d'utilisateur sont stockés.
demo_localdb=# select distinct schemaname, tablename, tableowner from pg_tables where tableowner like '%unknown%';
schemaname | tablename | tableowner
------------+-----------------+-------------------
demo_local | orders_nocomp_2 | unknown (UID=114)
demo_local | orders_nocomp_3 | unknown (UID=115)
(2 rows)
Utilisez la commande ALTER TABLE pour transférer la propriété des objets. Dans l'exemple suivant, le nouveau propriétaire est userc.
alter table demo_local.orders_nocomp_2 owner to userc;
Prévention
Avant de supprimer un utilisateur, exécutez la requête suivante pour trouver les objets qui lui appartiennent. (Pour ce faire, vous pouvez également utiliser la vue v_find_dropuser_objs.) Dans l'exemple suivant, l'utilisateur est labuser.
SELECT decode(pgc.relkind,
'r','Table',
'v','View'
) ,
pgu.usename,
pgu.usesysid,
nc.nspname,
pgc.relname,
'alter table ' || QUOTE_IDENT(nc.nspname) || '.' || QUOTE_IDENT(pgc.relname) || ' owner to '
FROM pg_class pgc,
pg_user pgu,
pg_namespace nc
WHERE pgc.relnamespace = nc.oid
AND pgc.relkind IN ('r','v')
AND pgu.usesysid = pgc.relowner
AND nc.nspname NOT ILIKE 'pg\_temp\_%'
AND pgu.usename = 'labuser'
Cette requête peut ne pas trouver d'utilisateurs qui possèdent des schémas créés avec une commande similaire à la suivante. Dans cet exemple, labuser est le propriétaire du schéma.
create schema demo_local authorization labuser;
Les utilisateurs avec des autorisations de niveau schéma ne peuvent pas être supprimés, sauf si le schéma est transféré à un nouveau propriétaire. Voici un exemple de transfert de propriété vers userc :
alter table demo_local.orders_nocomp_2 owner to userc;
Informations connexes
Comment résoudre l'erreur « user cannot be dropped » (l'utilisateur ne peut pas être supprimé) dans Amazon Redshift ?
Interrogation des tables de catalogue
Afficher les utilisateurs de base de données