电科金仓权限管理踩坑记:从“啥都干不了”到“安全可控”的蜕变
电科金仓权限管理踩坑记:从“啥都干不了”到“安全可控”的蜕变
我永远忘不了那天早上,安全管理员sso急冲冲跑来找我:“完了完了,审计员sao账户被锁死了,审计工作全停了!” 这就是我们迁移到电科金仓后遭遇的第一个权限管理危机。今天,我把这三年来在金仓权限管理上踩过的坑、总结的经验,毫无保留地分享给你。
开篇:那个让人头皮发麻的早晨
三年前,我们公司决定把核心数据库从Oracle迁移到电科金仓KES。我当时是数据库团队的负责人,心想:“不就是换个数据库嘛,能有啥难的?”结果,权限管理这一块就给了我们一个结结实实的下马威。
记得系统刚上线那会儿,各种权限问题层出不穷:开发人员抱怨“这个表明明是我的,为啥不能删?”运维人员吐槽“用户被锁死了,我都没权限解锁!”安全团队更是天天追着我问:“三权分立到底怎么分啊?”
今天这篇文章,我就从三个最典型的场景出发,带你看看我们是怎么一步步解决这些问题的。相信我,看完这些,你在金仓上的权限管理之路会顺畅很多。
一、sao账户被锁定:一场意料之外的“权限风暴”
故事背景:审计工作突然瘫痪
那是系统上线后的第二个月,一个普通的周二早上。我正在喝咖啡,安全管理员小张冲进我办公室,脸色煞白:“王哥,出大事了!审计员sao账户登录不上了,所有审计工作都停了!”
我一开始还没当回事:“输错密码了吧?让他再试一次。”
“试了十几次了!提示账户被锁定!”小张把笔记本电脑推到我面前。
我一看,还真是:
FATAL: The user "sao" is locked.
这下我咖啡也喝不下去了——要知道,我们的金融业务系统,审计记录是合规的生命线。审计工作停一天,风险报告就晚一天,监管部门那边可没法交代。
问题诊断:原来是这个插件搞的鬼
我们首先检查了账户状态:
-- 用system管理员账户登录
\c security system
-- 查看sao账户状态
SELECT rolname, rolcanlogin, rolconnlimit
FROM sys_roles
WHERE rolname = 'sao';
结果显示sao账户是正常的。这就奇怪了,账户没被禁用,怎么就锁定了呢?
折腾了一个小时,我们才想起来:为了满足安全要求,我们启用了账户异常登录锁定插件。赶紧查一下配置:
-- 检查插件是否加载
SELECT name, setting FROM sys_settings
WHERE name LIKE '%audlog%';
-- 查看具体参数
show sys_audlog.max_error_user_connect_times;
show sys_audlog.error_user_connect_times;
show sys_audlog.error_user_connect_interval;
看到结果我们傻眼了:错误连接次数限制是3次,而审计员昨晚加班测试,不小心输错了三次密码!
解决方案:安全管理员sso的“特权时刻”
问题找到了,怎么解决呢?这里就体现出金仓三权分立的精妙之处了。sao账户是审计管理员,system是系统管理员,但解锁这个事,必须由安全管理员sso来做。
-- 第一步:安全管理员sso登录
\c security sso
输入密码...
-- 第二步:解锁sao账户
ALTER USER sao WITH LOGIN;
-- 第三步:验证解锁成功
\c security sao
输入密码...
-- 这次成功登录了!
整个过程不到五分钟,但给我们的教训是深刻的:权限设计得再安全,如果使用的人不懂规则,照样会出问题。
经验总结:我们做的三件事
- 制定密码尝试规则:重要账户每天最多试错2次,超过就找安全管理员
- 建立应急解锁流程:制作了详细的解锁操作手册,发给所有管理员
- 定期权限审计:每周检查一次重要账户的登录状态
现在,这个“惊险”的经历已经成了我们新员工培训的经典案例。
二、用户间的权限迷宫:一个表引发的“血案”
故事背景:“这表明明是我建的,为啥我不能用?”
权限管理的第二个大坑,是用户之间的对象访问问题。这事儿发生在我们业务高峰期。
业务部门的小李在wydb2数据库里建了个重要的报表表,第二天要用这个表做数据分析。结果第二天一早,他气冲冲地来找我:“王哥,我昨天建的表,今天怎么就查不了了?!”
我让他演示一下,果然:
-- 小李用自己的账户wy2登录
\c wydb2 wy2
-- 查询昨天建的表
SELECT * FROM testsc.t5;
-- 结果:ERROR: permission denied for schema testsc
小李一脸委屈:“这表明明是我建的啊!你看,owner就是我!”
问题诊断:schema owner ≠ table owner
我们仔细检查了权限结构,发现了问题所在:
-- 查看schema的owner
\dn testsc
-- 结果:testsc | wy
-- 查看表的owner
\dt testsc.t5
-- 结果:testsc | t5 | table | wy
看到没?schema的owner是wy(另一个用户),而表的owner也是wy,不是建表的小李(wy2)。这就是问题根源!
小李更懵了:“不对啊,我昨天建表的时候,明明是登录的wy2账户!”
我们查看了建表历史,发现小李建表时是这么做的:
-- 他先把自己加入wy角色
GRANT "wy" TO wy2;
-- 然后用这个权限建表
CREATE TABLE testsc.t5(a int);
建完之后,他又退出了wy角色:
REVOKE "wy" FROM wy2;
这一进一出,表的owner就变成了wy,而小李自己反而没权限了!
解决方案:权限的“组合拳”
解决这个问题,我们打了套组合拳:
第一步:先授权schema使用权限
-- 用schema的owner(wy)登录授权
\c wydb2 wy
GRANT USAGE ON SCHEMA testsc TO wy2;
第二步:再授权表的具体权限
GRANT SELECT ON testsc.t5 TO wy2;
第三步:如果需要更多权限
-- 授权插入、更新、删除等
GRANT INSERT, UPDATE, DELETE ON testsc.t5 TO wy2;
-- 或者干脆给所有权限
GRANT ALL PRIVILEGES ON testsc.t5 TO wy2;
做完这三步,小李终于能访问自己的表了。但他又问了句:“那我以后在这个schema里建新表,还要每次都这么麻烦吗?”
进阶方案:默认权限的妙用
这个问题问得好!我们确实不想每次都手动授权。金仓提供了一个很好的功能:默认权限。
-- 设置默认权限,以后wy用户在testsc下建的表,wy2都能查
ALTER DEFAULT PRIVILEGES FOR USER wy IN SCHEMA testsc
GRANT SELECT ON TABLES TO wy2;
-- 如果想授权更多操作
ALTER DEFAULT PRIVILEGES FOR USER wy IN SCHEMA testsc
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO wy2;
设置完默认权限后,wy以后在testsc下创建的任何表,wy2都能自动拥有指定权限。这个功能我们后来用在了很多协作开发的场景里。
经验总结:四个“一定”原则
通过这次事件,我们总结了用户权限管理的四个原则:
- 建表前一定要确认schema:别在别人的schema里建表
- 授权一定要分两步走:先授schema使用权,再授对象操作权
- 协作一定要用默认权限:减少重复授权工作
- 变更一定要通知相关人:权限变动要同步给所有受影响的人
三、schema空间限额:一次磁盘爆满的惨痛教训
故事背景:生产环境突然宕机
最惊险的一次权限管理事故,发生在去年双十一大促期间。凌晨两点,监控系统疯狂告警:生产数据库磁盘使用率95%!
我们赶紧登录检查,发现是一个报表schema把磁盘写满了。这个schema是给数据分析团队用的,他们正在跑一个重要的促销分析任务。
-- 查看各schema空间使用
SELECT
nspname AS schema_name,
sys_size_pretty(sum(sys_total_relation_size(sys_class.oid))) AS total_size
FROM
sys_class
JOIN sys_namespace ON sys_namespace.oid = sys_class.relnamespace
WHERE
nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
GROUP BY
nspname
ORDER BY
sum(sys_total_relation_size(sys_class.oid)) DESC;
结果让人震惊:report_schema一个schema就占了500GB,占总空间的70%!
问题根源:无限制的权限
我们回顾了一下这个schema的权限设置:
-- 当初是这么授权的
GRANT ALL ON SCHEMA report_schema TO data_team;
“ALL”权限包含了创建对象的权利,但没有空间限制。数据分析团队为了方便,在这个schema里创建了大量临时表、中间表,结果把磁盘撑爆了。
解决方案:间接控制schema空间
金仓目前没有直接的schema空间限额功能,但我们摸索出了一套间接控制的方法。
第一步:创建限额表空间
-- 先创建表空间配额插件(如果没装的话)
CREATE EXTENSION sys_tablespace_quota;
-- 创建一个有空间限制的表空间
CREATE TABLESPACE report_ts
LOCATION '/kingbase/data/report_tablespace'
WITH (quota = '100GB'); -- 限制100GB
第二步:把schema的表移到限额表空间
-- 设置schema的默认表空间
ALTER SCHEMA report_schema
SET default_tablespace = report_ts;
-- 现有表也移动过去
ALTER TABLE report_schema.table1
SET TABLESPACE report_ts;
ALTER TABLE report_schema.table2
SET TABLESPACE report_ts;
-- ... 其他表同理
第三步:监控空间使用
我们写了个监控脚本,每小时检查一次:
-- 创建监控表
CREATE TABLE schema_space_monitor (
monitor_id SERIAL PRIMARY KEY,
schema_name VARCHAR(100),
used_space BIGINT,
quota_space BIGINT,
usage_percent NUMERIC(5,2),
monitor_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 监控函数
CREATE OR REPLACE FUNCTION monitor_schema_space()
RETURNS void AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN
SELECT
nspname,
sum(sys_total_relation_size(sys_class.oid)) as used,
ts.quota
FROM
sys_class c
JOIN sys_namespace n ON n.oid = c.relnamespace
JOIN sys_tablespace_quota.ts_quota ts ON ts.spcname = (
SELECT spcname FROM sys_tablespace
WHERE oid = c.reltablespace
)
WHERE nspname = 'report_schema'
GROUP BY nspname, ts.quota
LOOP
INSERT INTO schema_space_monitor
(schema_name, used_space, quota_space, usage_percent)
VALUES (
rec.nspname,
rec.used,
rec.quota,
ROUND(rec.used * 100.0 / rec.quota, 2)
);
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- 设置定时任务
SELECT cron.schedule('monitor-space', '0 * * * *',
'SELECT monitor_schema_space();');
第四步:设置告警规则
当空间使用超过80%时,自动发邮件告警;超过90%时,限制该schema的写入操作。
预防措施:权限最小化原则
这次事故后,我们彻底修改了权限授予策略:
-- 不再使用ALL权限
-- GRANT ALL ON SCHEMA xxx TO yyy; -- 禁止!
-- 改为最小必要权限
GRANT USAGE ON SCHEMA report_schema TO data_team;
GRANT CREATE ON SCHEMA report_schema TO data_team_admin; -- 只有管理员能建表
-- 具体表权限单独控制
GRANT SELECT ON report_schema.sales_data TO data_analyst;
GRANT SELECT, INSERT ON report_schema.temp_table TO data_engineer;
经验总结:空间管理的三个要点
- 没有直接限制就间接控制:通过表空间配额间接控制schema空间
- 监控比限制更重要:及时发现异常,避免问题发生
- 权限一定要细化:“ALL”权限是万恶之源
四、金仓三权分立的实践心得
通过这三年的实践,我们对金仓的三权分立有了深刻的理解。这不是一个简单的权限划分,而是一套完整的安全体系。
三个角色的定位
-
系统管理员(system):数据库的“大管家”
- 负责日常运维
- 管理普通用户和对象
- 但不能审计别人,也不能制定安全规则
-
安全管理员(sso):安全的“守门人”
- 制定安全策略
- 管理用户锁定/解锁
- 监督其他管理员
- 但不能操作业务数据
-
审计管理员(sao):行为的“记录者”
- 记录所有操作日志
- 监督系统行为
- 但不能修改数据,也不能管理用户
我们的最佳实践
用户创建流程:
-- 1. system创建用户
CREATE USER new_user WITH PASSWORD 'xxx';
-- 2. sso设置安全策略
-- (通过安全控制台配置)
-- 3. 业务授权(由业务管理员负责)
GRANT CONNECT ON DATABASE app_db TO new_user;
GRANT USAGE ON SCHEMA app_schema TO new_user;
GRANT SELECT ON app_schema.table1 TO new_user;
权限审计流程:
-- sao定期执行审计
-- 检查异常登录
SELECT * FROM sys_audit_log
WHERE event_type = 'login_failed'
AND event_time > NOW() - INTERVAL '1 day';
-- 检查权限变更
SELECT * FROM sys_audit_log
WHERE object_type = 'role'
AND event_type LIKE '%grant%'
AND event_time > NOW() - INTERVAL '7 days';
容易踩的坑
- 角色继承陷阱:A继承B,B继承C,权限可能传递得超出预期
- public schema权限:默认所有人都有权限,要及时收紧
- 默认权限的遗忘:设置了默认权限,后来忘了,出问题时找不到原因
- 权限回收不彻底:REVOKE之后,可能还有通过其他角色的间接权限
结语:权限管理是一门艺术
三年下来,我从一个金仓权限的“小白”,变成了团队里的“权限专家”。这个过程让我深刻认识到:权限管理不是技术活,而是管理艺术。
技术上的问题都有解决方案,难的是如何在安全和便利之间找到平衡,如何在权限控制和业务效率之间做出取舍。
最后,给正在或准备使用电科金仓的朋友几个建议:
- 一定要理解三权分立:这不是限制,是保护
- 权限授予要“最小化”:能只读就不要写,能写单表就不要给全库
- 一定要有审计:权限变更都要记录,出了问题能追溯
- 定期审查权限:人员变动、业务调整后,权限也要相应调整
如果你在权限管理上遇到了问题,或者有更好的实践经验,欢迎到金仓技术探索社区(https://kingbase.com.cn/explore)交流分享。那里有很多像我一样从坑里爬出来的“过来人”,我们的经验也许能帮你少走些弯路。
权限管理这条路,我们走过来了。虽然磕磕绊绊,但最终建立了一套既安全又实用的权限体系。希望我们的经验,能照亮你前行的路。

浙公网安备 33010602011771号