看到标题里写着“GBase 8s 内部用户创建”,估计不少刚接触国产数据库的朋友第一反应是:这不就是CREATE USER一条语句的事吗?实际真上手搞过 GBase 8s 的人都知道,这个“内部用户”和 MySQL、Oracle 里的用户概念不完全是一回事。它牵扯到数据库自身的认证机制、操作系统用户映射、sqlhosts 配置、甚至 Informix 时代遗留下来的一套权限习惯。我把最近在项目里创建内部用户、分配权限、排查认证问题的完整过程整理出来,尽量把容易踩的坑一次说清楚,适合刚接触 GBase 8s 的 DBA、运维,以及需要自己搭测试环境做开发的同学。
1. 内部用户设计思路与整体方案拆解
1.1 为什么 GBase 8s 要单独搞一套“内部用户”
先捋一个基础概念:GBase 8s 在血缘上继承自 Informix 的体系架构,早期版本最常用的认证方式叫“操作系统用户映射”,也就是数据库不单独维护密码,而是直接信任操作系统的登录用户。你在 Linux 上有一个informix账号,数据库里也对应一个同名用户,两边靠$GBASEDBTUSER之类的环境变量对上号,客户端一连接,数据库就认为“你就是这个操作系统用户”,不再校验口令。
这套机制胜在简单、部署快,但问题也很明显:一旦操作系统账号密码泄露,数据库等于门户大开;多业务系统共用一个informix超级账号的情况更是家常便饭,权限难以隔离。所以 GBase 8s 后来引入了真正意义上的“内部用户”,也就是完全由数据库自身维护、与操作系统账号解耦的数据库账号。用户密码存在数据库内部,认证时数据库自己校验,不依赖外部系统。这个设计思路和 Oracle 的本地认证用户、MySQL 的独立用户体系基本一致,只是语法细节和权限模型还带着老 Informix 的影子。
1.2 内部用户和外部映射用户的核心区别
我用项目里实际遇到的一个场景来说明:当时我们有一套测试环境,操作系统账号只有informix和root,但前端应用需要以三个不同身份连接同一个实例做权限隔离测试。如果用传统操作系统用户映射,就得在 Linux 里创建三个系统账号,再逐一配置映射关系,麻烦不说,还容易把系统账号和数据库账号绑死。改成内部用户之后,直接在数据库里CREATE USER三个账号,密码全由数据库管理,操作系统层完全不用动。
两者差异我整理成一张表,方便对照:
| 对比项 | 操作系统映射用户 | 内部用户(数据库管理) |
|---|---|---|
| 认证方式 | 依赖操作系统账号,数据库不校验密码 | 数据库内部存储密码,独立认证 |
| 创建入口 | 需要系统层账号配合,再映射 | 直接在 SQL 中用 CREATE USER 创建 |
| 密码管理 | 跟随系统密码策略 | 数据库 ALTER USER 管理 |
| 适用场景 | 内部可信网络、单机管理 | 多业务隔离、远程访问、权限细分 |
| 隔离性 | 弱,系统账号一旦失控影响数据库 | 强,数据库账号独立于系统 |
| 维护成本 | 需要系统管理员配合 | DBA 独立完成 |
从维护角度看,我强烈建议新项目优先用内部用户。尤其是远程访问场景,客户端机器上和数据库服务器根本没有共享账号体系,依赖操作系统映射几乎是给自己埋雷。内部用户把“数据库账号”和“系统账号”彻底剥离开,权限边界清晰得多。
2. 创建内部用户前的环境准备与前置检查
2.1 确认实例已启用内部用户认证能力
创建内部用户之前,先确认当前实例运行方式支持这一特性。GBase 8s 的实例默认由informix这个操作系统用户启动,ONCONFIG配置文件里有一个关键参数决定认证行为。我在不同版本上见过两种常见配置路径,一种是在$GBASEDBTDIR/etc下的sqlhosts文件里声明连接协议,另一种则是通过onmode -wf动态调整安全相关配置。
最直接的办法是连上实例后执行一条 SQL 查看版本和认证模式:
SELECT DBINFO('version', 'full') FROM systables WHERE tabid = 1;如果版本支持内部用户,通常默认就开启了数据库本地认证,直接执行CREATE USER不会报“此功能未启用”之类的错误。如果报错,优先查ONCONFIG中与安全认证相关的参数是否被注释或设成了禁用值。常见的做法是参考官方文档确认该版本 GBase 8s 对“用户认证”功能的开关名称,再通过onmode -wf在线调整,调整后无需重启实例。
注意:修改认证相关参数前,先备份
$GBASEDBTDIR/etc下的配置文件,我习惯在改动前加时间戳复制一份,防止手滑改错又无法回滚。
2.2 用 dbaccess 建立初始连接
创建用户属于管理操作,推荐使用dbaccess命令行工具以 DBA 权限连接。连接前要确认两件事:一是环境变量INFORMIXSERVER是否指向目标实例名,二是当前系统用户是否能正常访问实例。我第一次在一台新环境上操作时,直接在普通用户下敲dbaccess,结果报了一堆共享内存连接错误,最后发现是没切换到informix用户、也没 source 实例的环境变量文件。
规范的连接步骤是:
# 切换到 informix 系统用户 su - informix # 加载实例环境变量,常见文件名如 gbasedbtserver.env 或 profile.gbasedbt . /opt/GBASE/gbase/etc/gbasedbt.env # 确认实例名 echo $INFORMIXSERVER # 连接默认数据库并执行 SQL(sysmaster 或 sysuser 均可) dbaccess sysmaster这里有个细节:dbaccess进入交互界面后,默认连接的是当前INFORMIXSERVER指定的实例,但不代表你就有管理员权限。在 GBase 8s 中,初始的超级用户一般是informix,如果当前操作系统用户不是informix,连接后执行CREATE USER大概率会报“没有 DBA 权限”。所以最好的起手式就是切到informix用户再操作,省去后面一堆权限排查。
2.3 规划账号命名与密码策略
不要小看命名和密码规划,这步偷懒后面全是坑。GBase 8s 的标识符大小写规则和操作系统不太一样,默认情况下数据库对象名会按大写处理,但用户名字符串的敏感性在不同版本上表现又有差异。我在实际项目里统一用“小写字母加下划线”的命名风格,比如app_readonly、app_rw_user,避免因为大小写问题导致应用连接时“用户不存在”的幻觉报错。
密码策略方面,至少要求 8 位以上、包含字母和数字,不能太简单。虽然 GBase 8s 的本地认证不像 Oracle 那样默认带复杂的 profile 策略,但作为 DBA 自己有责任把常用账号密码强度提上去,尤其那些开放给应用服务器连接的业务账号。测试环境可以放宽,生产环境务必严谨。
3. 内部用户创建的实操全流程
3.1 使用 CREATE USER 创建数据库内部账号
GBase 8s 的CREATE USER语法和主流数据库略有差异,但核心思路一致。我以一个实际需求为例:创建只读账号app_read,密码设为Read@2024。
在dbaccess交互界面中执行:
CREATE USER app_read WITH PASSWORD 'Read@2024' PROPERTIES USER DEFAULT;不同小版本对PROPERTIES子句的支持程度可能不一样,有的版本语法是:
CREATE USER app_read IDENTIFIED BY 'Read@2024';如果第一条语句报语法错误,就试试第二条。这里想强调一个排查思路:遇到语法报错时,先查官方文档中对应版本的语法图,而不是反复猜测。GBase 8s 的语法兼容 Informix 比较明显,关键词、子句顺序都比较“古早”,和 MySQL 那种宽松写法差别很大。
创建成功后,用新用户连接测试:
dbaccess sysmaster - - <<EOF CONNECT TO sysmaster USER 'app_read' USING 'Read@2024'; EOF注意:GBase 8s 的密码如果包含
@、#这类特殊字符,在不同客户端工具和 shell 环境下可能需要转义,建议在脚本中用单引号包住密码,避免被 shell 解释掉。
3.2 验证用户并处理首次登录的常见报错
创建完用户,我习惯立刻做一轮验证,而不是直接丢给应用同事。验证的核心就一句话:确认这个账号能连上实例,且权限符合预期。
用dbaccess连接时,如果报User cannot connect to database,别急着怀疑密码,先确认三件事:
- 用户是否被赋予了
CONNECT权限(GBase 8s 默认CREATE USER后不会自动给任何数据库访问权限) - 目标数据库是否存在
- 当前
INFORMIXSERVER是否指向正确实例
注意看第一条,这点和其他数据库很不一样。MySQL 里CREATE USER后用户至少能登录,GBase 8s 里如果只建账号不授权,用户连CONNECT权限都没有,哪怕密码完全正确也登不进去。我第一次在新版本上踩的就是这个坑,专门花时间记录一下。
所以创建完用户后,下一步必须立刻授权:
GRANT CONNECT TO app_read;如果是业务读写账号,还要加上RESOURCE甚至DBA权限,具体看你的权限矩阵设计。
3.3 DBA、RESOURCE、CONNECT 权限分级与选择
GBase 8s 的权限模型分为三个层级,我把它们之间的差异和适用场景已经整理成表格,这里想补充一些实战经验:
| 权限级别 | 功能范围 | 适合场景 |
|---|---|---|
| CONNECT | 登录实例、访问已授权数据库,但不具备建表等 DDL 权限 | 只读报表账号、查询用户 |
| RESOURCE | 具备 CONNECT 全部能力,可以在授权库中建表、建索引 | 业务开发账号、读写应用 |
| DBA | 拥有数据库内几乎所有管理操作权限 | 运维账号、高级管理账号 |
实际授权时,细心的同事可能会问:为什么读账号不直接给RESOURCE?因为RESOURCE能建表,意味着这个账号一旦被拖库或被应用误用,就能在库里创建对象,留下安全隐患。只读账号给CONNECT就足够了,配合后续的SELECT授权完成数据访问。而 DBA 权限更要谨慎发放,任何 DBA 账号的操作都会绕过一部分普通权限检查,出问题后审计定位难,安全边界也容易失控。
我建议的最小权限实践是:应用账号用CONNECT或RESOURCE即可,只有 DBA 或运维人员才用 DBA 权限;每个业务模块单独建账号,避免共用账号导致后期审计和追责困难。
4. 权限分配、角色管理与使用技巧
4.1 按场景精细化授权:从 SELECT 到存储过程执行权限
内部用户创建完成后,才进入真正的重头戏:授权。GBase 8s 的授权粒度比一般想象中更细,除了库级权限,还有表级、列级、甚至存储过程执行权限。以只读账号为例,只给CONNECT还不够,需要单独对目标表授权:
GRANT SELECT ON customer TO app_read; GRANT SELECT ON orders TO app_read;这里推荐一个高效做法:连上目标数据库后,用一条 SQL 拼接出批量授权脚本。比如要把某 schema(此处以常见业务模式为例)下所有表的SELECT权限一次性授予只读账号,可以用:
SELECT 'GRANT SELECT ON ' || tabname || ' TO app_read;' FROM systables WHERE tabid > 99 AND tabtype = 'T';把查询结果导出为 SQL 文件,再批量执行。这个方法比手工一条条GRANT高效得多,也避免漏表。
如果是给应用配读写账号,除了表级INSERT、UPDATE、DELETE,还要考虑序列、存储过程的权限:
GRANT INSERT, UPDATE, DELETE ON customer TO app_rw_user; GRANT EXECUTE ON proc_update_customer TO app_rw_user;4.2 利用角色(ROLE)统一管理权限
当账号数量多起来,逐个GRANT会变成纯体力活,而且容易有一天突然发现漏授权。GBase 8s 支持角色(ROLE),建议把角色作为授权单位,而不是直接对人授权。
创建一个角色并授权:
CREATE ROLE read_only_role; GRANT SELECT ON customer TO read_only_role; GRANT SELECT ON orders TO read_only_role;再把用户加入角色:
GRANT read_only_role TO app_read;后续新人加入,只要执行一次角色授予,所有表的查询权限全部自动生效。权限调整时也只需要改角色上的授权,不用一个个用户去收权限。我后来管理的几套环境都是这套玩法,省心不少。
需要注意,角色名和用户名在同一命名空间下不能重复,角色授权和回收的语法也遵循标准的GRANT ROLE TO USER与REVOKE ROLE FROM USER,和 Oracle 的用法有几分相似。
4.3 ALTER USER、DROP USER 与密码变更实操
日常运维中,账号生命周期管理比创建更考验基本功。密码定期更换是常见需求,GBase 8s 的语法是:
ALTER USER app_read WITH PASSWORD 'NewPass@2025';有些版本可能支持其他属性调整,但密码变更是最常用的。我的经验是:每次改完密码立刻更新应用侧的连接配置,并安排一次带新密码的连通性测试,避免出现“账号己改密,但应用仍用旧密码重试导致锁死”的情况。虽然 GBase 8s 本地认证不一定有明确的失败锁定策略,但频繁失败的日志会刷满 online.log,影响故障排查。
删除用户的语法更简单:
DROP USER app_read;不过删除前一定要确认这个用户没有被对象依赖,比如他拥有的表、序列、触发器,否则直接DROP USER会报依赖错误。稳妥做法是先把他的对象转移给其他用户,或者建一个临时 DBA 账号接管,再删除原账号。
5. 实际使用中的常见问题与排查记录
5.1 用户创建成功但连接被拒,日志怎么定位
创建用户本身不难,难的是连接不上时如何快速定位。我遇到过的典型场景是:新用户从应用服务器远程连接实例,提示认证失败,但dbaccess在数据库服务器本机却能正常登录。
排查顺序我固定为三步走:先看 online.log 中的认证记录,再排查sqlhosts的协议配置,最后检查客户端侧的环境变量和服务名。online.log是 GBase 8s 排查问题最重要的日志文件,路径一般在$GBASEDBTDIR/tmp或日志目录下,也可以用onstat -m直接查看最近消息。
onstat -m | tail -50日志里出现类似Client authentication failed的记录时,我会先分清是密码错误,还是用户根本不存在。这时可以在服务器本地用该账号试一次dbaccess,如果本地可以而远程不行,基本可以判断是网络认证或协议配置的问题,而不是账号本身有问题。
5.2 用户创建成功但连接被拒,日志怎么定位
上面提到的方法虽然常用,但 GBase 8s 的认证链路还涉及另一层容易被忽视的环节:$GBASEDBTDIR/etc下的sqlhosts文件以及实例的LISTEN配置。远程客户端连接时,服务名要对应sqlhosts中配置的协议和主机名,如果应用连接串里写的别名不对,或主机名解析问题导致连不上,也会表现为类似认证失败的错误。
排查命令是:
cat $GBASEDBTDIR/etc/sqlhosts如果sqlhosts中使用了onsoctcp这类 TCP 协议项,还要检查监听端口是否被防火墙拦截。我在测试环境就犯过漏开端口的低级错误,本地连得欢,远程全超时。所以每次远程连接失败,我都会顺手检查端口连通性:
telnet <服务器IP> <端口>端口通、服务名对、日志没有明显报错,再回头审视用户名密码,不要一上来就怀疑账号建错了。
5.3 忘记密码与 DBA 强制重置
最后分享一个救急场景:业务同事把应用账号密码忘了,而生产环境又不能随便重启。GBase 8s 内部用户的密码重置,本质上是 DBA 权限用户执行ALTER USER即可,并不会影响现有连接。
操作方式:
- 以
informix或 DBA 权限用户连接sysmaster - 执行
ALTER USER app_rw_user WITH PASSWORD '临时密码' - 通知业务方用新密码登录,首次登录后建议强制业务方再改一次
这里有个小优化建议:改成临时密码后,不要直接通过不安全的聊天工具发给业务。我通常把临时密码放在内部密码管理平台,限期 24 小时有效,业务方登录后立即改密。别问为什么,干过生产环境的都懂,密码明文满天飞是最常见的安全隐患。
6. 安全加固与个人实操心得
6.1 内部用户的安全基线建议
账号体系搭好之后,安全加固不能落下。结合我自己的维护经验,整理出几条基线规则:
- 每个应用模块独立建号,严禁共用超级账号连库
- 只读账号一律只授
CONNECT加表级SELECT - DBA 权限只保留最小必要人数,定期复核授权清单
- 密码定期轮换,至少保证 90 天一次的节奏
- 从应用侧限制连接来源 IP,能不开公网就不开公网
- 操作前先备份配置文件,操作后立刻验证登录
这些规则本身不难,难在坚持。我把账号清单和授权关系维护在一张表格里,每次变更都同步更新,半年一次权限审计,才能保证不出大乱子。
6.2 最后分享一条我踩过坑换来的经验
GBase 8s 内部用户使用中,最容易阴沟翻船的不是建用户,而是“以为建完就万事大吉”。没有CONNECT授权的用户、忘了批量授权只读权限的角色、改了密码没通知应用的案例,我都遇过。现在我总结出一条铁律:新建任何账号,必须走完“建号-授权-验证登录-验证权限-记录归档”这五步闭环。宁可每一步多花一分钟,也不要事后在业务群里被@一整天。
如果你刚接触 GBase 8s,建议先拿测试环境从dbaccess建一个只读用户跑通全流程,再逐步尝试角色和批量授权,把账号体系这几板斧练熟,后面管理多实例就顺了。