2026/2/15 12:37:07
网站建设
项目流程
网站转小程序工具,二级黄冈站,郑州百度快照优化排名,wordpress编辑器修改电科金仓权限管理实战#xff1a;那些让我加班到凌晨的权限“陷阱”上周五晚上10点#xff0c;我正准备下班#xff0c;开发组长小王火急火燎地跑过来#xff1a;“哥#xff0c;我们的报表系统崩了#xff0c;用户说查不到数据#xff01;”我一看#xff0c;又是权限…电科金仓权限管理实战那些让我加班到凌晨的权限“陷阱”上周五晚上10点我正准备下班开发组长小王火急火燎地跑过来“哥我们的报表系统崩了用户说查不到数据”我一看又是权限问题——视图访问授权没做对。这已经是我们迁移到电科金仓后遇到的第N个权限问题了。今天我把这些坑一个个挖出来填平了给大家看。开头那个让我加班到凌晨的周五说实话我干了八年数据库运维从Oracle到MySQL啥场面没见过。但去年公司决定用电科金仓KES替换Oracle我在权限管理上真是栽了不少跟头。就说上周五那个事吧。我们的报表系统里有个核心视图业务部门每天都要用。结果那天下午突然所有用户都报“权限不足”。我查了半天发现是有人误操作把schema权限给改了。这个经历让我意识到金仓的权限体系很强大但也很“较真”一个细节没注意整个系统都可能出问题。今天我就讲讲三个最常见的权限“陷阱”都是我们团队用真金白银换来的经验。陷阱一视图访问授权——你以为授权了其实没有问题现场“这个视图我能建为啥别人不能查”我们有个数据分析师小张他在自己的schema里建了个视图然后想让其他部门的同事也能查。他觉得很简单“不就是给个查询权限嘛”结果操作完同事还是报错。我让他演示一下操作过程-- 小张ud用户建了个视图\c-udCREATEVIEWud.sales_viewASSELECT*FROMsales_dataWHEREregion华东;-- 他觉得自己已经授权了GRANTSELECTONud.sales_viewTOreport_user;看起来没问题对吧但report_user还是查不了。错误信息是ERROR: permission denied for schema ud问题根源schema权限是道“门”我告诉小张“你给了人家进房间的钥匙视图权限但没开门啊”在金仓里schema就像一个个房间。你要进房间拿东西查询视图需要两把钥匙房间的门禁卡schema的USAGE权限具体物品的取用权视图的SELECT权限正确操作两步授权法我教小张正确的授权流程第一步先开门授权schema访问-- 需要schema的owner或者有授权权限的人来操作\c-system-- 用system用户因为schema owner是system-- 给report_user发门禁卡GRANTUSAGEONSCHEMAudTOreport_user;第二步再授权物品授权视图查询-- 小张可以自己操作因为他是视图owner\c-udGRANTSELECTONud.sales_viewTOreport_user;这两步都做完report_user才能正常查询。进阶技巧批量授权和角色管理后来我们发现这种需求很常见。与其每次都手动操作不如建立一套权限管理体系。方案一创建只读角色-- 创建一个专门用于查询的角色CREATEROLE report_viewer NOLOGIN;-- 批量授权所有视图GRANTSELECTONALLTABLESINSCHEMAudTOreport_viewer;-- 注意这个ALL TABLES包括视图-- 把角色赋给用户GRANTreport_viewerTOreport_user1,report_user2,report_user3;方案二设置默认权限如果我们希望未来新建的视图也能自动授权可以设置默认权限-- 设置默认权限以后ud用户在ud schema下建的所有表/视图-- report_viewer角色都能查ALTERDEFAULTPRIVILEGESFORUSERudINSCHEMAudGRANTSELECTONTABLESTOreport_viewer;这个功能特别有用设好之后就不用每次手动授权了。真实案例我们搞砸过一次有一次我们给一个新员工授权忘了给schema权限。结果这位同事试了半天都查不了数据还以为系统坏了差点提了紧急工单。后来我们做了个授权检查清单每次授权都按这个来检查用户是否需要schema权限检查用户是否需要具体对象权限验证授权是否生效通知用户测试陷阱二权限简写——那些神秘字母的含义问题现场“arwdDxt是啥外星语吗”刚用金仓的时候我最头疼的就是看权限信息。比如这样的udarwdDxt/ud role01r/ud我问团队里的小李“你能看懂这啥意思吗”小李一脸懵“王哥这比摩斯密码还难懂啊”解密每个字母都有含义其实这是金仓的权限简写系统。我后来专门研究了文档搞明白了每个字母的意思a- INSERT追加r- SELECT读取w- UPDATE写入d- DELETE删除D- TRUNCATE清空x- REFERENCES外键引用t- TRIGGER触发器所以arwdDxt就是拥有所有权限r就是只有查询权限。实战如何查看和分析权限查看表权限-- 最简单的查法\dp 表名-- 或者用SQL查SELECTrelnameAS表名,relaclAS权限信息FROMsys_classWHERErelnamesales_data;查看schema权限SELECTnspnameASschema名,sys_catalog.sys_get_userbyid(nspowner)AS所有者,nspaclAS权限信息FROMsys_namespaceWHEREnspnameud;查看数据库权限SELECTdatnameAS数据库名,sys_catalog.sys_get_userbyid(datdba)AS所有者,dataclAS权限信息FROMsys_database;小技巧写个解析函数为了让团队都能看懂我写了个权限解析函数CREATEORREPLACEFUNCTIONdecode_privileges(priv_textTEXT)RETURNSTABLE(privilege_nameTEXT,privilege_descTEXT)AS$$DECLAREpriv_mappingTEXT[][]:ARRAY[[a,INSERT插入数据],[r,SELECT查询数据],[w,UPDATE更新数据],[d,DELETE删除数据],[D,TRUNCATE清空表],[x,REFERENCES外键引用],[t,TRIGGER触发器操作]];iINT;chCHAR;BEGIN-- 遍历权限字符串的每个字符FORiIN1..length(priv_text)LOOPch :substring(priv_textFROMiFOR1);-- 查找对应的权限描述FORjIN1..array_length(priv_mapping,1)LOOPIFpriv_mapping[j][1]chTHENprivilege_name :ch;privilege_desc :priv_mapping[j][2];RETURNNEXT;EXIT;ENDIF;ENDLOOP;ENDLOOP;END;$$LANGUAGEplpgsql;-- 使用示例SELECT*FROMdecode_privileges(arwd);现在团队里谁看不懂权限简写就跑一下这个函数一目了然。经验教训权限审计很重要我们曾经遇到过权限泄露问题。有人给一个临时账户授予了过大权限后来忘了回收。幸亏我们定期做权限审计-- 每月一次的权限审计脚本SELECT高风险过度授权AS问题类型,grantee::regroleAS用户,table_schema||.||table_nameAS对象,privilege_typeAS权限FROMinformation_schema.role_table_grantsWHEREgranteeNOTIN(system,sso,sao)-- 排除管理员ANDprivilege_typeIN(DELETE,TRUNCATE,REFERENCES,TRIGGER)ANDtable_schemaNOTLIKEpg_%ANDtable_schema!information_schemaORDERBYgrantee,table_schema,table_name;陷阱三VACUUM权限——普通用户的“禁区”问题现场“我连清理表都不行吗”这是我们运维小刘遇到的问题。他发现某个表膨胀得厉害想手动VACUUM一下结果\c-app_user VACUUM sales_data;-- 结果WARNING: skippingsales_data--- only table or database owner can vacuum it小刘很郁闷“我好歹也是这个表的owner怎么连清理都不行”真相VACUUM是个特权操作我告诉小刘“VACUUM在金仓里是个特殊操作普通用户确实干不了。”为什么呢因为VACUUM涉及到底层存储结构的调整有一定风险。金仓设计时只允许两种人执行VACUUM表的owner超级用户superuser解决方案几种变通方法方法一让表的owner来执行这是最简单的办法。如果app_user是表的owner理论上可以执行。但如果还是不行可能是因为有其他限制。方法二临时提权谨慎使用-- 用system用户临时授权\c-systemGRANTsystemTOapp_user;-- 让app_user临时拥有system权限-- app_user执行VACUUM\c-app_user VACUUM sales_data;-- 用完马上回收\c-systemREVOKEsystemFROMapp_user;方法三设置超级用户不推荐ALTERUSERapp_userWITHSUPERUSER;但这个方法太危险了一旦给用户超级权限他就能为所欲为包括删除整个数据库。我们的实践建立VACUUM管理流程我们公司最后定了一套规矩普通用户不准手动VACUUM全部交给自动VACUUM机制紧急情况走流程确实需要手动VACUUM时提工单给DBA团队DBA统一操作每周一早上DBA检查表膨胀情况统一执行VACUUM我们还写了个监控脚本自动发现需要VACUUM的表-- 监控表膨胀的脚本CREATEORREPLACEFUNCTIONcheck_table_bloat()RETURNSTABLE(schema_nameTEXT,table_nameTEXT,row_countBIGINT,dead_row_countBIGINT,bloat_ratioNUMERIC(5,2),need_vacuumBOOLEAN)AS$$BEGINRETURNQUERYSELECTschemaname::TEXT,tablename::TEXT,n_live_tup,n_dead_tup,CASEWHENn_live_tup0THEN0ELSEROUND(n_dead_tup*100.0/n_live_tup,2)ENDASbloat_ratio,(n_dead_tup1000ANDn_dead_tupn_live_tup*0.2)ASneed_vacuumFROMsys_stat_user_tablesWHEREn_dead_tup0ORDERBYbloat_ratioDESC;END;$$LANGUAGEplpgsql;-- 每天检查一次SELECTcron.schedule(check-bloat-daily,0 2 * * *,$$INSERTINTOvacuum_logSELECT*,CURRENT_TIMESTAMPFROMcheck_table_bloat()WHEREneed_vacuumtrue$$);血的教训一次VACUUM事故去年我们有个新来的DBA想提高性能给一个业务用户临时加了超级权限执行VACUUM。结果完事后忘了回收权限。一个月后这个用户误操作删除了一个重要表。虽然最后从备份恢复了但业务停了两个小时损失不小。从此以后我们立下铁规绝不给人超级权限VACUUM必须走流程。权限管理最佳实践我们总结的“三要三不要”通过这三年的实践我们总结了金仓权限管理的“三要三不要”三要1. 要分层授权-- 不好的做法一次性给所有权限GRANTALLONSCHEMAsalesTOsales_user;-- 好的做法分层授权GRANTUSAGEONSCHEMAsalesTOsales_user;-- 基础权限GRANTSELECTONsales.customerTOsales_user;-- 具体表权限GRANTINSERT,UPDATEONsales.orderTOsales_user;-- 特定操作的权限2. 要用角色管理不要直接给用户授权而是通过角色-- 创建角色CREATEROLE sales_read_only;CREATEROLE sales_read_write;-- 给角色授权GRANTSELECTONALLTABLESINSCHEMAsalesTOsales_read_only;GRANTSELECT,INSERT,UPDATEONALLTABLESINSCHEMAsalesTOsales_read_write;-- 把角色给用户GRANTsales_read_onlyTOuser1;GRANTsales_read_writeTOuser2;3. 要定期审计每月做一次权限审计-- 审计脚本CREATETABLEpermission_audit_log(audit_idSERIALPRIMARYKEY,audit_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMP,object_typeTEXT,object_nameTEXT,granteeTEXT,privilegesTEXT,auditorTEXT);-- 每月1号自动运行SELECTcron.schedule(permission-audit,0 0 1 * *,$$INSERTINTOpermission_audit_log(object_type,object_name,grantee,privileges,auditor)SELECTTABLE,schemaname||.||tablename,grantee,privilege_type,CURRENT_USERFROMinformation_schema.role_table_grantsWHEREgranteeNOTIN(system,sso,sao);$$);三不要1. 不要给人超级权限-- 千万别这么干ALTERUSERapp_userWITHSUPERUSER;2. 不要用ALL PRIVILEGES-- 太危险了GRANTALLPRIVILEGESONDATABASEapp_dbTOapp_user;-- 应该细化授权GRANTCONNECTONDATABASEapp_dbTOapp_user;GRANTCREATEONSCHEMAapp_schemaTOapp_admin;3. 不要忘记回收权限-- 员工离职时一定要做REVOKEALLPRIVILEGESONALLTABLESINSCHEMAsalesFROMformer_employee;REVOKEALLPRIVILEGESONSCHEMAsalesFROMformer_employee;REVOKECONNECTONDATABASEapp_dbFROMformer_employee;DROPUSERformer_employee;写在最后权限管理是门学问从Oracle转到电科金仓我在权限管理上确实花了些时间适应。但说实话适应之后发现金仓的权限体系设计得挺合理的——严格但清晰复杂但可控。现在回想那些加班到凌晨的日子虽然辛苦但值得。因为我们建立了一套安全、可控、易管理的权限体系。如果你也在用金仓或者在考虑用金仓我建议你一定要理解三权分立system、sso、sao各司其职一定要从简单开始先给最小权限不够再加一定要有文档每个权限变动都要记录一定要定期审查权限就像房间久了不打扫会乱最后如果你在权限管理上遇到了问题或者有更好的实践经验欢迎到金仓技术探索社区https://kingbase.com.cn/explore交流。那里有很多实战案例和技术文章说不定能帮你少走弯路。权限管理这条路我们走过来了。虽然踩过坑、加过班但最终建成了一套让业务安心、让运维省心的权限体系。希望我们的经验能帮你走得更稳、更快。