错误:无法删除角色“user1”,因为某些对象依赖于它

Joe*_*ins 6 postgresql google-cloud-sql postgresql-9.6

在我的 Google Cloud SQL 数据库实例 (Postgres 9.6) 上,我无法通过 GCP Console 删除通过 GCP Console 创建的用户/角色。当我尝试时,控制台显示一条通知,显示“用户已删除”,然后经过进一步检查,我发现操作失败并出现“未知错误”。实例的错误日志显示以下错误:

06:42:36.347 UTC [199]: [1-1] db=cloudsqladmin,user=cloudsqlagent ERROR:  role "user1" cannot be dropped because some objects depend on it
06:42:36.347 UTC [199]: [2-1] db=cloudsqladmin,user=cloudsqlagent DETAIL:  privileges for database mydb
24 objects in database mydb
Run Code Online (Sandbox Code Playgroud)

可以通过运行看到 24 个对象

06:42:36.347 UTC [199]: [1-1] db=cloudsqladmin,user=cloudsqlagent ERROR:  role "user1" cannot be dropped because some objects depend on it
06:42:36.347 UTC [199]: [2-1] db=cloudsqladmin,user=cloudsqlagent DETAIL:  privileges for database mydb
24 objects in database mydb
Run Code Online (Sandbox Code Playgroud)

按照https://cloud.google.com/sql/docs/postgres/create-manage-users#deleting_users的建议,我知道postgres在删除用户之前我必须将所有权重新分配给另一个角色 ( ),但是当我尝试时运行以下脚本(来自/sf/ask/3587951811/):

SELECT distinct table_name
FROM information_schema.role_table_grants
WHERE grantee = 'user1'
Run Code Online (Sandbox Code Playgroud)

由于 Cloud SQL 没有提供我的用户状态 ( https://cloud.google.com/sql/docs/postgres/users#superuser_restrictionsREASSIGN ),我在命令 ( )上遇到权限错误。我还不确定如何向 Cloud SQL 数据库实例中的用户授予状态;我的假设是我不能。ERROR: permission denied to reassign objectsSUPERUSERSUPERUSER

使用 Cloud Shell 的 gcloud 命令时也会出现此问题。输出类似:

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;
DROP USER user1;
Run Code Online (Sandbox Code Playgroud)

重要信息:

  • Postgres 版本9.6
  • 只读副本已附加到此实例
  • 是的,我尝试过将其关闭然后再次打开。不,重新启动主实例和只读副本并不能解决此问题。
  • 该实例上的所有数据库模式迁移和数据迁移都是使用 Flask-Alembic 完成的,配置非常标准
  • 我可以验证没有用户在我们的 Cloud Build 配置中更改了 Alembic 流程之外的架构
  • 用户是在 GCP 控制台中创建的
  • 未对用户、权限或对象所有权进行任何手动更改

Mel*_*kij 3

06:42:36.347 UTC [199]: [2-1] db= cloudsqladmin ,user=cloudsqlagent 详细信息:数据库 mydb 数据库mydb中 24 个对象的权限

PostgreSQL 中未实现跨数据库查询。PostgreSQL 将看到与指定的某些依赖关系pg_catalog.pg_shdepend.dbid,但无法查询该数据库的系统目录以确定它们是哪些对象。因此,postgresql 确实仅在其他数据库的错误详细信息中提示数据库名称。(这也是 PostgreSQL 没有的原因drop user ... cascade- 我们无法修改甚至无法从另一个数据库读取对象描述)

但是,如果您连接到详细信息中指定的数据库并尝试删除用户,您将获得更详细的描述:

postgres=# drop user user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  3 objects in database m2
postgres=# \connect m2 
You are now connected to database "m2" as user "postgres".
m2=# drop user user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for table foo
privileges for table foofk
owner of table test
Run Code Online (Sandbox Code Playgroud)

在这种情况下user1,是一个表的所有者(REASSIGN OWNED将很容易解决这个问题)和另外两个表的一些权限(REASSIGN OWNED不会触及这个)。

不同的对象需要某些命令(revoke权限、alter default privileges默认权限等),不幸的是,即使在一个数据库中,也没有万能的环来管理所有依赖项。