PostgreSQL 作为世界上最领先的开源数据库,有一套强大的用户角色权限系统,和 MySQL 做一个对比:
但硬币的另一面则是对于简单场景来说增加了复杂度。在许多单应用场景,其实也不需要额外的 schema 层,也不需要额外的 owner。相信玩过 PG 的同学都碰到过类似 must be owner of table 的问题。
场景说明
我们就来说说简单的 PG 使用场景,数据库用户该如何配。所谓简单是指:
- PG 实例就一个数据库
- 数据库就一个默认的 public schema
- 所有的表都在这个 public schema 下
而使用数据库的场景,由人到数据库,和应用到数据库两部分组成:
人到数据库
- DBA 操作
- 数据库变更,DDL 和 DML 都有
- 数据库查询
应用到数据库
- 数据库变更,DDL 的话通常在应用启动前做,除此之外都是 DML
- 数据库查询
具体配置
最简单粗暴的当然是一个 superuser 搞定。本地安装 postgres 的话,第一个 postgres 用户其实就是这样的 superuser。
我们把人和应用拆开,如果应用在启动时还是需要变更 schema,则是下面这样
如果数据库 schema 变更发布已经和应用独立开来了,那么应用只需要有基本的数据库读写操作
到了这步如果除了 DBA 之外的人想访问数据库的话,直接把 DBA 用户交出去风险太大了,所以这时会选择引入像 Bytebase 这样的工具。DBA 在 Bytebase 上配置普通用户的数据库访问权限,而不用把用户名密码交出去。而且 schema 变更也可以在 Bytebase 上完成,这样大大减少了需要使用 DBA 账号直接操作数据库的情况,降低风险。
Pigsty 作为开箱即用的 PG 发行版,也预置了一套类似的默认角色。
额外注意
- 公有云数据库服务是不提供 superuser 的,他们只提供一个阉割版的 superuser,比如 Google Cloud SQL 里的 cloudsqlsuperuser
设置单独 migration 用户的原因一方面是为了方便监控,另一方面也使得我们可以给 migration 用户设置单独的默认连接参数,最常见设置的是 lock_timeout。要设置的原因是,做 DDL 时要加锁,加锁需要等待,而因为 PG 的队列机制,即使后面来的另外一条事务不需要 DDL 锁,一样会被 block 住。所以 migration 用户往往要设置一个 lock_timeout,避免长时间 block 后面的其他事务。
在 Postgres 里创建对象时,比如建表,建出来表的 owner 就是建表语句的执行者。所以当使用一个单独的 migration 用户来做 schema 变更时,表的 owner 也会是 migration。如果希望 owner 能反应具体的业务,比如说 payment 的话,那么可以再单独创建一个 payment 的角色,在 migration 执行的时候,使用 SET LOCAL ROLE 切换到 payment 再执行。
PostgreSQL 的用户角色体系还是有点复杂的,如果有什么其他额外建议和需要注意的地方,欢迎大家留言。
💡 更多资讯,请关注 Bytebase 公号:Bytebase