暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

海量数据库 Vastbase G100 V2.2 DBA 日常操作运维手册

原创 暮雨 2026-09-24
71

海量数据库 Vastbase G100 V2.2 DBA 日常操作运维手册

覆盖范围:数据库启停、用户管理(创建/改密/锁定/删除)、授权与取消授权、建库、建表、视图、索引、默认授权。

阅读约定:代码块中带 # 前缀的行表示以 root 用户输入的命令,带 $ 前缀的行表示以 vastbase 系统用户输入的命令(业务用户连接通过 PGPASSWORD 环境变量区分并在命令中注明),其余行均为实际输出。文中所有口令一律以 ****** 表示,执行时替换为实际口令即可。


一、环境与软件说明

1.1 硬件与操作系统

项目 值
主机名 / IP kyinLinx / 10.168.1.175
操作系统 Kylin Linux Advanced Server V10 (Sun)
CPU 8 核 Intel® Xeon® CPU E5-2699 v4 @ 2.20GHz
内存 16 GB(实际 15 Gi)
数据盘 /dev/mapper/kals-backup,xfs,30G,挂载 /backup
# free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       3.2Gi       2.8Gi        59Mi       9.3Gi        11Gi
Swap:         7.9Gi       204Mi       7.7Gi

# df -h /backup
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/kals-backup   30G  1.7G   29G    6% /backup

1.2 数据库软件版本

$ vsql --version
vsql (Vastbase G100 V2.2 (Build 19) Release) compiled at 2026-06-27 14:26:11 commit 32736 last mr

$ vb_ctl --version
vb_ctl (Vastbase G100 V2.2 (Build 19) Release) compiled at 2026-06-27 14:26:11 commit 32736 last mr

连接进去再看内核版本与兼容模式——G100 的内核版本号沿 PostgreSQL 报告,兼容模式 A 即 Oracle 兼容:

$ vsql -d postgres -p 5432 -Atc 'select version();'
PostgreSQL 9.2.4 on x86_64-pc-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit

$ vsql -d postgres -p 5432 -Atc 'show sql_compatibility;'
A

1.3 实例关键信息

项目 值
systemd 服务名 vastbase-server(enabled,开机自启)
数据目录 /backup/vastbase/data
软件目录 /home/vastbase/local/vastbase
监听端口 5432(listen_addresses=‘*’)
兼容模式 A(Oracle 兼容)
License 90 天试用版,有效期至 2026-12-08(/etc/vastbase/.license)

systemd 单元定义值得贴出来,后面启停章节的两个坑都藏在里面:

# systemctl cat vastbase-server
# /etc/systemd/system/vastbase-server.service
[Unit]
Description=Vastbase G100 Database Server
After=network.target

[Service]
Type=forking
User=vastbase
Group=vastbase
ExecStart=/bin/bash -lc "/home/vastbase/local/vastbase/bin/vb_ctl start -D /backup/vastbase/data -t 120"
ExecStop=/bin/bash -lc "/home/vastbase/local/vastbase/bin/vb_ctl stop -D /backup/vastbase/data -m fast -t 120"
ExecReload=/bin/bash -lc "/home/vastbase/local/vastbase/bin/vb_ctl restart -D /backup/vastbase/data -t 120"
TimeoutSec=300

[Install]
WantedBy=multi-user.target

看清楚了:Type=forking,ExecStart/ExecStop 都是拿 bash -lc 包了一层 vb_ctl。也就是说 systemd 只是 vb_ctl 的壳,这个结构决定了后面"手工 vb_ctl 与 systemctl 混用会互踩"的坑。

1.4 三权分立账户

G100 默认三权分立:初始化超级用户 vastbase(安全设计默认禁止远程登录)、系统管理员 vbadmin、安全管理员 vbsso、审计管理员 vbaudit。用 pg_roles 盘点实例角色(口令不在系统表里,不存在泄露问题):

$ vsql -d postgres -p 5432 -c "select rolname, rolsuper, rolcreaterole, rolcreatedb, rolcanlogin, rolconnlimit from pg_roles order by rolname;"
         rolname          | rolsuper | rolcreaterole | rolcreatedb | rolcanlogin | rolconnlimit 
--------------------------+----------+---------------+-------------+-------------+--------------
 bizapp                   | f        | f             | f           | t           |           -1
 gs_role_account_lock     | f        | f             | f           | f           |           -1
 gs_role_copy_files       | f        | f             | f           | f           |           -1
 gs_role_directory_create | f        | f             | f           | f           |           -1
 gs_role_directory_drop   | f        | f             | f           | f           |           -1
 gs_role_pldebugger       | f        | f             | f           | f           |           -1
 gs_role_replication      | f        | f             | f           | f           |           -1
 gs_role_signal_backend   | f        | f             | f           | f           |           -1
 gs_role_tablespace       | f        | f             | f           | f           |           -1
 vastbase                 | t        | t             | t           | t           |           -1
 vb_read_all_settings     | f        | f             | f           | f           |           -1
 vbadmin                  | t        | t             | t           | t           |           -1
 vbaudit                  | f        | t             | f           | t           |           -1
 vbsso                    | f        | t             | f           | t           |           -1
(14 行记录)

14 个角色里 8 个 gs_role_* 是系统内置功能角色(不能登录),真正管事的是四个人:vastbase(超级用户,本机免密)、vbadmin(远程运维用)、vbsso/vbaudit(安全与审计,rolcreaderole=t 但 rolsuper=f,权责被刻意收窄——这就是三权分立的落点)。

本次手册的操作账号是一对演示用户:业务用户 ops_demo、只读用户 ops_ro(下文创建),全程不碰四权账户。

1.5 口令策略(改密前必须知道)

改密演示之前先把口令策略参数摸清,否则报错都看不懂。这些值直接从 pg_settings 取:

$ vsql -d postgres -p 5432 -Atc "select name||' = '||setting from pg_settings where name like 'password%' or name in ('enable_separation_of_duty','vb_enable_separation_of_duty') order by name;"
参数 值 含义
password_min_length / max_length 8 / 32 口令长度区间
password_min_digital / lowercase / uppercase / special 0 / 0 / 0 / 0 未强制字符类别(password_policy=1 只做基本校验)
password_policy 1 口令复杂度策略等级
password_reuse_max 3 最近 3 次用过的口令不许再用
password_reuse_time 90 90 天内用过的口令不许再用
password_lock_time 1440 连续失败锁定时长(分钟),1440=24 小时
password_effect_time 36500 口令有效期(天)
password_notify_time 7 到期前 7 天开始提醒
password_encryption_type 1 存储加密方式:md5
password_force_alter off 不强制首次登录改密
enable_separation_of_duty off 三权分立增强开关(本实例为安装器默认关闭状态)

记住 password_reuse_max=3 和 password_reuse_time=90,改密章节会亲眼看到它们怎么拦人。


二、前置检查

每次做 DBA 操作前,先花 10 秒确认实例活着、版本对、监听在:

# systemctl is-active vastbase-server
active
# systemctl is-enabled vastbase-server
enabled

# ss -lntp | grep ':5432'
LISTEN    0         3000               0.0.0.0:5432             0.0.0.0:*        users:(("vastbase",pid=1191142,fd=14))                                         
LISTEN    0         3000                  [::]:5432                [::]:*        users:(("vastbase",pid=1191142,fd=15))                                         

$ vsql -d postgres -p 5432 -Atc 'select pg_postmaster_start_time();'
2026-09-13 23:51:50.476836+08

判定点:is-active 返回 active、5432 有 vastbase 进程监听、启动时间与最近一次启停操作吻合,三样齐了才继续。

盘点现有数据库:

$ vsql -d postgres -p 5432 -c '\l'
                                    数据库库列表
   名称    |  拥有者  | 字元编码 |  校对规则   |    Ctype    |       存取权限        
-----------+----------+----------+-------------+-------------+-----------------------
 bizdb     | bizapp   | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =Tc/bizapp           +
           |          |          |             |             | bizapp=CTc/bizapp    +
           |          |          |             |             | bizapp=APm/bizapp
 postgres  | vastbase | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | 
 template0 | vastbase | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/vastbase          +
           |          |          |             |             | vastbase=CTc/vastbase
 template1 | vastbase | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/vastbase          +
           |          |          |             |             | vastbase=CTc/vastbase
 vastbase  | vastbase | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | 
(5 行记录)

存取权限(datacl)这一列后面讲授权时要用:=Tc/bizapp 表示 PUBLIC 对 bizdb 有 T(临时表)和 c(连接)权限,bizapp=CTc/bizapp 表示属主全权。数据库列表是后续建库、授权章节的基线。

2.1 认证机制:文件写 trust,实测却要密码

pg_hba.conf 内容如下:

# grep -v '^#' /backup/vastbase/data/pg_hba.conf | grep -v '^[[:space:]]*$'
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
host all all 0.0.0.0/0 md5

按这份文件,本地 socket 和 127.0.0.1 应该免密。但实测普通用户本地直连照样要口令——不输、乱输都被拒:

$ vsql -d opsdb -p 5432 -U ops_demo -Atc 'select current_user;' </dev/null
用户 ops_demo 的密码:
vsql: 致命错误:  用户名或密码错误,登录拒绝
(exit=2)

而 vastbase 操作系统用户登录 vsql 却全程免密。查环境变量就明白了:

$ echo "PGHOST=[$PGHOST] PGUSER=[$PGUSER] PGPORT=[$PGPORT]"
PGHOST=[] PGUSER=[vastbase] PGPORT=[5432]

安装时给 vastbase 用户的 profile 里固化了 PGUSER=vastbase,配合本地 trust 规则实现管理员本机免密;换成其他用户名(如 ops_demo)就落到口令校验上。结论以实测为准:这台实例上除 vastbase 本机免密外,任何用户任何通道都要口令。另外,PostgreSQL 用来核对 hba 的 pg_hba_file_rules 视图在 G100 这个内核上不存在,想在线核对规则只能看文件本身:

$ vsql -d postgres -p 5432 -c "select * from pg_hba_file_rules;"
错误:  关系 "pg_hba_file_rules" 不存在在 node1

这是与原生 PG 运维习惯的第一个差异,提前记住,省得排查时怀疑人生。

远程连接走 md5,PGPASSWORD 环境变量传口令(vsql 会提醒一句安全风险,脚本场景可接受,交互场景建议口令手工输入):

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb -Atc 'select current_user;'
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
ops_demo

三、数据库启停

启停是 DBA 最常见也最不能出事的操作。这台实例有两条路径:systemd 托管(systemctl,ExecStart/ExecStop 的本质还是调 vb_ctl)和 vb_ctl 手工直操。日常一律走 systemctl,vb_ctl 只在 systemd 异常时救场——原因看完 3.4 节的事故现场就懂。

3.1 启动:systemctl start

先看"库是停着的"长什么样(is-active 返回非 0、状态 inactive(dead)、端口无监听):

# systemctl is-active vastbase-server
inactive
(exit=3)

# systemctl status vastbase-server --no-pager
● vastbase-server.service - Vastbase G100 Database Server
   Loaded: loaded (/etc/systemd/system/vastbase-server.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Fri 2026-09-11 21:10:22 CST; 2 days ago
 Main PID: 355697 (code=exited, status=0/SUCCESS)

# ss -lntp | grep ':5432'
(无监听)

启动:

# systemctl start vastbase-server
(exit=0)

命令本身没有输出,验证要靠自己,三步走:

# systemctl status vastbase-server --no-pager
● vastbase-server.service - Vastbase G100 Database Server
   Loaded: loaded (/etc/systemd/system/vastbase-server.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2026-09-13 23:51:51 CST; 3s ago
  Process: 1190256 ExecStart=/bin/bash -lc /home/vastbase/local/vastbase/bin/vb_ctl start -D /backup/vastbase/data -t 120 (code=exited, status=0/SUCCESS)
 Main PID: 1190277 (vastbase)
    Tasks: 69 (limit: 100245)

# ss -lntp | grep ':5432'
LISTEN    0         3000               0.0.0.0:5432             0.0.0.0:*        users:(("vastbase",pid=1190277,fd=14))                                         
LISTEN    0         3000                  [::]:5432                [::]:*        users:(("vastbase",pid=1190277,fd=15))                                         

$ vb_ctl status -D /backup/vastbase/data
[2026-09-13 23:51:54.915][1190359][][vb_ctl]: vb_ctl status,数据目录是 /backup/vastbase/data 
vb_ctl: 正在运行服务器进程(PID: 1190277)
/home/vastbase/local/vastbase/bin/vastbase "-D" "/backup/vastbase/data"

判定点:Active: active (running)、5432 双栈监听、vb_ctl status 报出主进程 PID。从敲下命令到可连接,实测 7 秒左右(23:51:48 发起 → 23:51:55 vsql 通)。

3.2 停库:systemctl stop 与"停了之后客户端什么样"

停库前先确认没有长事务在跑(pg_stat_activity 里除自己外没有 active 查询),然后停:

# systemctl stop vastbase-server
(exit=0,fast 模式,回滚未决事务后退出)

# systemctl is-active vastbase-server
inactive
(exit=3)

# ss -lntp | grep ':5432'
(5432 无监听)

停库瞬间客户端的报错长这样,值班时认准它:

$ vsql -d postgres -p 5432 -Atc 'select 1;'
连接到失败 Unknown:5432.
(exit=2)

本次演练从 stop 到重新可连接,实际中断 8 秒(23:53:57 → 23:54:05),全程数据无损。

3.3 重启:systemctl restart

参数改完 postgresql.conf 后的常规动作,一条命令完成停+启:

# systemctl restart vastbase-server
(exit=0)

# systemctl is-active vastbase-server
active

$ vsql -d postgres -p 5432 -Atc 'select pg_postmaster_start_time();'
2026-09-14 09:57:37.807289+08

判定点:pg_postmaster_start_time() 变成刚才的时间点,说明实例真的换了新进程,不是假活。

3.4 vb_ctl 手工启停(辅线):能干,但别和 systemd 混用

systemd 挂了的极端场景才用这条路径,而且用完必须想清楚状态归谁管。先停掉 systemd 托管的库,然后用 vastbase 用户手工拉起:

# systemctl stop vastbase-server
# systemctl is-active vastbase-server
inactive

$ vb_ctl start -D /backup/vastbase/data -t 60
[2026-09-14 07:33:45.588][1207892][][vb_ctl]: vb_ctl started,数据目录是 /backup/vastbase/data 
[2026-09-14 07:33:45.754][1207892][][vb_ctl]: 等待服务端进程启动 ...
(中间为 License 加载、内存规划等常规启动日志,与判断无关,此处省略)
许可证信息:
License 序列号:e72d8ca4-6AA1599D
License 类型:临时
License 过期时间:2026-12-08 21:05:33
license文件目录:/etc/vastbase/.license
[2026-09-14 07:33:48.227][1207892][][vb_ctl]:  完成
[2026-09-14 07:33:48.227][1207892][][vb_ctl]: 服务端进程已经启动 (/backup/vastbase/data)

# ss -lntp | grep ':5432'
LISTEN    0         3000               0.0.0.0:5432             0.0.0.0:*        users:(("vastbase",pid=1207913,fd=14))                                         

库确实活了(PID 1207913)。但此时问 systemd,它一脸茫然:

# systemctl is-active vastbase-server
inactive
(exit=3)

因为手工 vb_ctl 起的进程没经过 ExecStart,systemd 的账本上这个服务还是死的。危险在这里才开始——如果值班同事看到 inactive 顺手补了一刀 systemctl start,systemd 的处理顺序是:发现 ExecStart 的 vb_ctl 报"目录已在运行"→ 按失败处理 → 顺手执行 ExecStop 把你手工拉起的库停掉。实测现场:

# systemctl start vastbase-server
(exit=0,但库被停了)

# systemctl status vastbase-server --no-pager
● vastbase-server.service - Vastbase G100 Database Server
   Loaded: loaded (/etc/systemd/system/vastbase-server.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Mon 2026-09-14 07:33:52 CST; 8ms ago
  Process: 1208037 ExecStop=/bin/bash -lc /home/vastbase/local/vastbase/bin/vb_ctl stop -D /backup/vastbase/data -m fast -t 120 (code=exited, status=0/SUCCESS)
  Process: 1208014 ExecStart=/bin/bash -lc /home/vastbase/local/vastbase/bin/vb_ctl start -D /backup/vastbase/data -t 120 (code=exited, status=0/SUCCESS)
 Main PID: 1191142 (code=exited, status=0/SUCCESS)

看清楚这两行:ExecStart 和 ExecStop 双双 SUCCESS,服务却是 inactive(dead)——systemd 认为它"启动失败后清理成功",实际效果是把正在运行的库干掉了。此时再想用 vb_ctl 收尾,PID 文件已经被 ExecStop 清走,报错又不一样:

$ vb_ctl stop -D /backup/vastbase/data -m fast -t 60
[2026-09-14 07:33:52.556][1208063][][vb_ctl]: vb_ctl stopped ,数据目录是 /backup/vastbase/data 
[2026-09-14 07:33:52.556][1208063][][vb_ctl]:  PID 文件 "/backup/vastbase/data/postmaster.pid" 不存在
[2026-09-14 07:33:52.556][1208063][][vb_ctl]: 服务进程是否正在运行?
(exit=1)

正确归位姿势:既然库已被停掉,直接交回 systemd:

# systemctl start vastbase-server
(exit=0)

# systemctl is-active vastbase-server
active

$ vsql -d postgres -p 5432 -Atc 'select pg_postmaster_start_time();'
2026-09-14 07:33:54.049923+08

三条铁律:

  1. systemctl is-active 显示 inactive 不代表进程不在,先 ss -lntp | grep 5432 + vb_ctl status 核实再动手;
  2. 手工 vb_ctl 起的库,要么用 vb_ctl 停,要么先 vb_ctl 停干净再 systemctl start,绝不倒手混用;
  3. 判断库里有没有进程,认 PID 文件 /backup/vastbase/data/postmaster.pid 和端口监听,别信单一来源。

3.5 开机自启

服务已 enable,装机后验证一次即可:

# systemctl is-enabled vastbase-server
enabled

四、用户管理

管理动作全部以 vastbase 用户本机免密执行(生产上等价于用 vbadmin 远程执行,语法相同)。建用户只举 ops_demo(业务读写)和 ops_ro(只读校验)两个例子,口令以 ****** 代称。

4.1 创建用户

$ vsql -d postgres -p 5432 -c "CREATE USER ops_demo WITH PASSWORD '******';"
CREATE ROLE

$ vsql -d postgres -p 5432 -c "CREATE USER ops_ro WITH PASSWORD '******';"
CREATE ROLE

注意回显是 CREATE ROLE 而不是 CREATE USER——USER 本质就是带登录属性的 ROLE。立即核验属性:

$ vsql -d postgres -p 5432 -c "select rolname,rolsuper,rolcreaterole,rolcreatedb,rolcanlogin from pg_roles where rolname like 'ops%' order by rolname;"
 rolname  | rolsuper | rolcreaterole | rolcreatedb | rolcanlogin 
----------+----------+---------------+-------------+-------------
 ops_demo | f        | f             | f           | t
 ops_ro   | f        | f             | f           | t
(2 行记录)

判定点:rolcanlogin=t,其余全 f——最小权限起步,建库建角色属性后面单独授予。

口令不满足策略会被当场拒绝,比如长度不足 8 位:

$ vsql -d postgres -p 5432 -c "CREATE USER bad_demo WITH PASSWORD '******';"
错误:  密码必须包含至少8个字符。
(vsql 对 SQL 层错误默认返回 0,bad_demo 实际未创建,靠回显判断成败)

4.2 改密(管理员改 vs 用户本人改)

管理员改(忘记旧口令场景):

$ vsql -d postgres -p 5432 -c "ALTER USER ops_demo WITH PASSWORD '******';"
ALTER ROLE

改完立即用新口令验证,旧口令应当被拒:

$ PGPASSWORD='旧口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb -Atc 'select 1;'
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
vsql: 致命错误:  用户名或密码错误,登录拒绝
(exit=2)

$ PGPASSWORD='新口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb -Atc 'select count(*) as emp_rows from ops.emp;'
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
 emp_rows 
----------
        5
(1 行记录)

用户本人改:语法是 Oracle 风格的 IDENTIFIED BY,实测这台实例上必须带 REPLACE 旧口令,不带直接被拒。这是本次实操踩到的实打实的坑(G100 V2.2 Build19 32736 实测行为),现场还原:

$ PGPASSWORD='旧口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "ALTER USER ops_demo IDENTIFIED BY '新口令';"
错误:  旧密码不能为空,请用'replace'语法输入旧密码。
(stdout 显示 exit=0,实际口令未变——见下方红线)

写对的样子:

$ PGPASSWORD='旧口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "ALTER USER ops_demo IDENTIFIED BY '新口令' REPLACE '旧口令';"
ALTER ROLE

$ PGPASSWORD='旧口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb -Atc "select 'should-not-see';"
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
vsql: 致命错误:  用户名或密码错误,登录拒绝
(exit=2,旧口令已失效)

$ PGPASSWORD='新口令' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb -Atc 'select current_user;'
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
ops_demo
(exit=0)

同一个会话里还撞上口令复用策略的现行——改回最近用过的口令被拒:

错误:  新密码不能和旧密码相同

对应 1.5 节的 password_reuse_max=3 / password_reuse_time=90:最近 3 个口令、90 天内用过的都换不回去。

红线:vsql 遇到 SQL 层错误时 exit code 依然是 0(实测:连接失败/账户锁定返回 2,SQL 报错默认返回 0,加 -v ON_ERROR_STOP=1 才返回 3)。上面的错误改密脚本要是只看退出码就会漏掉。自动化脚本判定成败必须看回显文本或加 ON_ERROR_STOP,这条贯穿全文所有操作。

4.3 锁定与解锁

登录失败连续超限自动锁定(锁定时长=1.5 节的 password_lock_time=1440 分钟),人工锁定解锁用 ACCOUNT 子句:

$ vsql -d postgres -p 5432 -c "ALTER USER ops_ro ACCOUNT LOCK;"
ALTER ROLE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb -Atc 'select 1;'
警告: 使用PGPASSWORD环境变量连接数据库存在安全风险
vsql: 致命错误:  账户被锁定
(exit=2)

$ vsql -d postgres -p 5432 -c "ALTER USER ops_ro ACCOUNT UNLOCK;"
ALTER ROLE

判定点:锁定后报错文本是"账户被锁定"而不是"用户名或密码错误"——值班时靠这句话区分"密码错了"还是"账号被锁了"。

4.4 删除用户:先处理依赖

有依赖对象的用户直接删会被拒,报错把依赖列得明明白白:

$ vsql -d postgres -p 5432 -c "DROP USER ops_demo;"
错误:  无法删除"ops_demo"因为有其它对象依赖它
描述:  数据库 opsdb的属主
       在数据库 opsdb中的3个对象

标准删除流程:先把名下对象(库/表/视图)移交或删除,再删人。完整走一遍一次性账号的生灭:

$ vsql -d postgres -p 5432 -c "CREATE USER ops_tmp WITH PASSWORD '******';"
CREATE ROLE
$ vsql -d postgres -p 5432 -c "CREATE DATABASE opsdb_tmp OWNER ops_tmp;"
CREATE DATABASE
$ vsql -d postgres -p 5432 -Atc "select datname from pg_database where datname='opsdb_tmp';"
opsdb_tmp
$ vsql -d postgres -p 5432 -c "DROP DATABASE opsdb_tmp;"
DROP DATABASE
$ vsql -d postgres -p 5432 -c "DROP USER ops_tmp;"
DROP ROLE

顺序必须是先删库(或 REASSIGN/移交对象)后删人,反过来就是上面的依赖报错。

4.5 改名与属主转移(顺手补充)

库的属主转移用 ALTER DATABASE ... OWNER TO,配合删人场景把对象移交出去再删用户,比逐个 DROP 稳妥。实测 opsdb 的属主本来就是 ops_demo,同属主执行语法验证:

$ vsql -d postgres -p 5432 -c "ALTER DATABASE opsdb OWNER TO ops_demo;"
ALTER DATABASE

$ vsql -d postgres -p 5432 -c "select datname,datdba::regrole as owner from pg_database where datname='opsdb';"
 datname |  owner   
---------+----------
 opsdb   | ops_demo
(1 行记录)

五、创建数据库与 schema

5.1 建库

CREATE DATABASE 不能在事务块里执行,直接单条发:

$ vsql -d postgres -p 5432 -c "CREATE DATABASE opsdb OWNER ops_demo ENCODING 'UTF8';"
CREATE DATABASE

$ vsql -d postgres -p 5432 -c "select datname,datdba::regrole as owner,datacl from pg_database where datname='opsdb';"
 datname |  owner   |                        datacl                         
---------+----------+-------------------------------------------------------
 opsdb   | ops_demo | {=T/ops_demo,ops_demo=CTc/ops_demo}
(1 行记录)

判定点:owner 是建库时指定的用户;datacl 初始只有属主全权(CTc)和 PUBLIC 的默认项(=T/),权限从零开始,后面 6.1 会把 PUBLIC 的 CONNECT 收掉做库级隔离。

5.2 建 schema 与 search_path

业务对象建议收进业务 schema,不散在 public:

$ vsql -d opsdb -p 5432 -c "CREATE SCHEMA ops AUTHORIZATION ops_demo;"
CREATE SCHEMA

会话内切 schema 用 SET search_path TO ops;,写 SQL 就不用带前缀了。后文 ops_demo 的所有操作都以此为前提。

六、建表、视图、索引(业务用户实操)

这一节全部用业务用户 ops_demo 自己动手(经 md5 + PGPASSWORD 连接),属主归位,不需要管理员代劳。

6.1 建表与插数

$ SET search_path TO ops;
$ CREATE TABLE emp (
      id        int PRIMARY KEY,
      name      varchar(50) NOT NULL,
      dept      varchar(30),
      salary    numeric(10,2),
      hire_date date NOT NULL
  );
CREATE TABLE
注意:  CREATE TABLE / PRIMARY KEY 将要为表 "emp" 创建隐含索引 "emp_pkey"

$ INSERT INTO emp VALUES
   (1,'张三','运维',8500.00,'2024-03-01'),
   (2,'李四','开发',9200.00,'2023-07-15'),
   (3,'王五','运维',7600.00,'2025-01-10'),
   (4,'赵六','测试',6800.00,'2024-11-20');
INSERT 0 4

主键自带隐含索引 emp_pkey,回显里明确提示——这意味着主键列不用再手工建索引。

6.2 建索引

$ CREATE INDEX idx_emp_dept   ON emp(dept);
CREATE INDEX
$ CREATE INDEX idx_emp_salary ON emp(salary);
CREATE INDEX

索引定义核验:

$ \di
                         关联列表
 架构模式 |      名称      | 型别 |  拥有者  | 表  | 存储 
----------+----------------+------+----------+-----+------
 ops      | emp_pkey       | 索引 | ops_demo | emp | 
 ops      | idx_emp_dept   | 索引 | ops_demo | emp | 
 ops      | idx_emp_salary | 索引 | ops_demo | emp | 
(3 行记录)

等价 SQL 视角(自动化脚本用这个更稳):

$ select indexname, indexdef from pg_indexes where schemaname='ops' order by indexname;
   indexname    |                                     indexdef                                     
----------------+-----------------------------------------------------------------------------------
 emp_pkey       | CREATE UNIQUE INDEX emp_pkey ON ops.emp USING btree (id) TABLESPACE pg_default
 idx_emp_dept   | CREATE INDEX idx_emp_dept ON ops.emp USING btree (dept) TABLESPACE pg_default
 idx_emp_salary | CREATE INDEX idx_emp_salary ON ops.emp USING btree (salary) TABLESPACE pg_default
(3 行记录)

6.3 建视图

$ CREATE VIEW v_emp_high AS
    SELECT id, name, dept, salary FROM emp WHERE salary >= 8000;
CREATE VIEW

$ SELECT * FROM v_emp_high ORDER BY id;
 id | name | dept | salary  
----+------+------+---------
  1 | 张三 | 运维 | 8500.00
  2 | 李四 | 开发 | 9200.00
(2 行记录)

判定点:4 行原始数据过滤后剩 2 行(≥8000),视图逻辑正确。视图在 G100 里就是 pg_class 里 relkind=‘v’ 的关系,属主跟建它的用户走:

$ \dv
                    关联列表
 架构模式 |    名称    | 型别 |  拥有者  | 存储 
----------+------------+------+----------+------
 ops      | v_emp_high | 视图 | ops_demo | 
(1 行记录)

6.4 对象结构总览

\d emp 一次看全表结构、列属性和索引:

$ \d emp
            表 "ops.emp"
   栏位    |     型别      | 修饰词 
-----------+---------------+--------
 id        | integer       | 非空
 name      | varchar(50)   | 非空
 dept      | varchar(30)   | 
 salary    | numeric(10,2) | 
 hire_date | date          | 非空
索引:
    "emp_pkey" PRIMARY KEY, btree (id) TABLESPACE pg_default
    "idx_emp_dept" btree (dept) TABLESPACE pg_default
    "idx_emp_salary" btree (salary) TABLESPACE pg_default

6.5 删除演练:索引/视图/表

临时对象建了就删,删完必须回查确认:

$ CREATE TABLE emp_tmp (id int, note varchar(20));
CREATE TABLE
$ CREATE INDEX idx_emp_tmp_id ON emp_tmp(id);
CREATE INDEX
$ CREATE VIEW v_emp_tmp AS SELECT * FROM emp_tmp;
CREATE VIEW

$ \dv
                    关联列表
 架构模式 |    名称    | 型别 |  拥有者  | 存储 
----------+------------+------+----------+------
 ops      | v_emp_high | 视图 | ops_demo | 
 ops      | v_emp_tmp  | 视图 | ops_demo | 
(2 行记录)

$ DROP INDEX idx_emp_tmp_id;
DROP INDEX
$ DROP VIEW  v_emp_tmp;
DROP VIEW
$ DROP TABLE emp_tmp;
DROP TABLE

$ \dv
                    关联列表
 架构模式 |    名称    | 型别 |  拥有者  | 存储 
----------+------------+------+----------+------
 ops      | v_emp_high | 视图 | ops_demo | 
(1 行记录)

注意 DROP VIEW 回显里 DROP VIEW v_emp_tmp 中间多了一个空格——vsql 原样输出,别当成自己敲错了。删除顺序上,视图依赖表时先删视图或加 CASCADE,直接 DROP TABLE 带着依赖视图会报错。

6.6 留存对象终态核验

$ select tablename, tableowner from pg_tables where schemaname='ops' order by tablename;
 tablename | tableowner 
-----------+------------
 emp       | ops_demo
(1 行记录)

$ select viewname, viewowner from pg_views where schemaname='ops' order by viewname;
  viewname  | viewowner 
------------+-----------
 v_emp_high | ops_demo
(1 行记录)

七、授权与取消授权

权限在 G100 里分三层:库级(CONNECT/CREATE)、schema 级(USAGE/CREATE)、表级(SELECT/INSERT/UPDATE/DELETE…)。排查权限问题时必须逐层往下查,少一层就是"权限不够",报错却不告诉你缺的是哪一层——7.5 节用真实翻车现场说明这一点。

7.1 库级:收回 PUBLIC 的 CONNECT,做库级隔离

新建库默认 PUBLIC 可连,敏感库要收掉:

$ vsql -d opsdb -p 5432 -c "REVOKE CONNECT ON DATABASE opsdb FROM PUBLIC;"
REVOKE

$ vsql -d opsdb -p 5432 -c "GRANT CONNECT ON DATABASE opsdb TO ops_ro;"
GRANT

$ vsql -d postgres -p 5432 -c "select datname,datdba::regrole as owner,datacl from pg_database where datname='opsdb';"
 datname |  owner   |                        datacl                         
---------+----------+-------------------------------------------------------
 opsdb   | ops_demo | {=T/ops_demo,ops_demo=CTc/ops_demo,ops_ro=c/ops_demo}
(1 行记录)

datacl 里 =T/ 只剩默认临时表权限,ops_ro=c/ 是单独授予的连接权——从此没有显式授权的用户连 opsdb 直接被拒。

7.2 表级授权与验证(预期成功段)

给 ops_ro 配只读:先给 schema USAGE(进得去 schema),再给表 SELECT(读得了表):

$ vsql -d opsdb -p 5432 -c "GRANT USAGE ON SCHEMA ops TO ops_ro;"
GRANT
$ vsql -d opsdb -p 5432 -c "GRANT SELECT ON ALL TABLES IN SCHEMA ops TO ops_ro;"
GRANT

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select id,name,dept,salary from ops.emp order by id limit 2;"
 id | name | dept | salary  
----+------+------+---------
  1 | 张三 | 运维 | 8500.00
  2 | 李四 | 开发 | 9200.00
(2 行记录)

追加写权限并验证:

$ vsql -d opsdb -p 5432 -c "GRANT INSERT,UPDATE ON ops.emp TO ops_ro;"
GRANT

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "insert into ops.emp values (5,'钱七','运维',8000.00,'2025-02-01');"
INSERT 0 1

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "update ops.emp set salary=8100.00 where id=5;"
UPDATE 1

7.3 取消授权(预期失败段,失败回显即证据)

REVOKE 之后同样的 SQL 立刻被拒——这段失败回显是授权生效的最好证据:

$ vsql -d opsdb -p 5432 -c "REVOKE INSERT,UPDATE ON ops.emp FROM ops_ro;"
REVOKE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "insert into ops.emp values (6,'孙八','测试',7000.00,'2025-03-01');"
错误:  对关系 emp 权限不够
描述:  N/A

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "delete from ops.emp where id=5;"
错误:  对关系 emp 权限不够
描述:  N/A

把 SELECT 和 schema USAGE 也收掉,读也读不了:

$ vsql -d opsdb -p 5432 -c "REVOKE SELECT ON ALL TABLES IN SCHEMA ops FROM ops_ro;"
REVOKE
$ vsql -d opsdb -p 5432 -c "REVOKE USAGE ON SCHEMA ops FROM ops_ro;"
REVOKE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select * from ops.emp limit 1;"
错误:  对模式 ops 权限不够
第1行select * from ops.emp limit 1;
                   ^
描述:  N/A

看这个报错的落点:报的是"对模式 ops 权限不够",不再是表——USAGE 收掉后连 schema 都进不去,表级报错根本轮不到出现。这正是分层排查的现场教材。

授权残留用 relacl 核对,REVOKE 后 ops_ro 的授权项消失、只剩属主:

$ vsql -d opsdb -p 5432 -c "select relname, relacl from pg_class where oid='ops.emp'::regclass;"
 relname |           relacl            
---------+-----------------------------
 emp     | {ops_demo=arwdDxt/ops_demo}
(1 行记录)

acl 缩写对照:a=INSERT, r=SELECT, w=UPDATE, d=DELETE, D=TRUNCATE, x=REFERENCES, t=TRIGGER。属主 implicitly 全权所以属主项永远在。

7.4 授权基线重建

演示完权限收紧,把 ops_ro 恢复成"只读"基线(后文默认授权验证要用):

$ vsql -d opsdb -p 5432 -c "GRANT USAGE ON SCHEMA ops TO ops_ro;"
GRANT
$ vsql -d opsdb -p 5432 -c "GRANT SELECT ON ops.emp TO ops_ro;"
GRANT

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select * from ops.dept_dic order by id;"
 id | dname 
----+-------
  1 | 运维
  2 | 开发
(2 行记录)

7.5 默认授权(ALTER DEFAULT PRIVILEGES):谁执行就对谁的将来对象生效

新表自动授权不想每次手工 GRANT,用默认授权。这里有一个实测出来的大坑:默认授权按"执行者"记账,只对执行者本人将来创建的对象生效。用 vastbase 管理员替 ops_demo 设置,然后 ops_demo 建新表——授权不生效:

$ vsql -d opsdb -p 5432 -c "ALTER DEFAULT PRIVILEGES IN SCHEMA ops GRANT SELECT ON TABLES TO ops_ro;"
ALTER DEFAULT PRIVILEGES

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "create table ops.dept_dic3(id int, dname varchar(30));"
CREATE TABLE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select * from ops.dept_dic3 order by id;"
错误:  对关系 dept_dic3 权限不够
描述:  N/A

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "select relname,relacl from pg_class where oid='ops.dept_dic3'::regclass;"
 relname  | relacl 
----------+--------
 dept_dic3 | 
(1 行记录)

relacl 是空的——管理员设的默认授权挂在管理员名下,跟 ops_demo 建的表无关。正确姿势:由对象创建者本人(ops_demo)执行:

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "ALTER DEFAULT PRIVILEGES IN SCHEMA ops GRANT SELECT ON TABLES TO ops_ro;"
ALTER DEFAULT PRIVILEGES

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "create table ops.dept_dic5(id int, dname varchar(30));"
CREATE TABLE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select * from ops.dept_dic5 order by id;"
 id | dname 
----+-------
(0 行记录)

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "select relname,relacl from pg_class where oid='ops.dept_dic5'::regclass;"
 relname  |                    relacl                     
----------+-----------------------------------------------
 dept_dic5 | {ops_demo=arwdDxt/ops_demo,ops_ro=r/ops_demo}
(1 行记录)

判定点:ops_ro 不经任何单独 GRANT 直接读到新表(空表也返回列头),relacl 里 ops_ro=r/ops_demo 自动出现。

取消默认授权同样由本人执行,再建的新表就不再带授权:

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "ALTER DEFAULT PRIVILEGES IN SCHEMA ops REVOKE SELECT ON TABLES FROM ops_ro;"
ALTER DEFAULT PRIVILEGES

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_demo -d opsdb \
    -c "create table ops.dept_dic6(id int);"
CREATE TABLE

$ PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U ops_ro -d opsdb \
    -c "select * from ops.dept_dic6 limit 1;"
错误:  对关系 dept_dic6 权限不够
描述:  N/A

补一句 dba 层面的教训:7.4 之前那次"ADP 授了却不生效"的排查里,schema USAGE 恰好处于被收回状态,两个原因叠加。权限验证失败时先把变量隔离——确认每一层权限的现状(datacl / nspacl / relacl)再下结论,一次只验一个假设。

7.6 权限排查三板斧

授权问题的排查顺序固定成口诀:

-- 第一板斧:库级,看 CONNECT(datacl)
select datname, datacl from pg_database where datname='opsdb';
-- 第二板斧:schema 级,看 USAGE(nspacl)
select nspname, nspacl from pg_namespace where nspname='ops';
-- 第三板斧:表级,看目标权限(relacl)
select relname, relacl from pg_class where oid='ops.emp'::regclass;

三层 ACL 都有授权项还报权限不够,才去查行级安全/审计策略。

八、实操中真实踩到的坑与解决办法

以下坑全部是本次在真机上撞出来的,每条按"现象 → 排查 → 原因 → 解决"交代,并定性:是我的操作失误、环境/配置问题,还是产品行为差异。版本统一为 Vastbase G100 V2.2 Build 19 (commit 32736),下文不再重复。

坑 1:pg_hba.conf 写着 trust,普通用户实测却要密码 —— 产品行为差异

现象:hba 文件明晃晃写着本地与 127.0.0.1 均 trust(2.1 节),但 ops_demo 本地 socket 直连被要求口令、口令错就被拒;ops_ro 用旧口令走 127.0.0.1 也被拒。trust 规则下这些本应免密直通。

排查:对照 vastbase 用户全程免密——它的 profile 里固化了 PGUSER=vastbase;普通用户无论本地还是回环 TCP 都落口令校验。

原因(定性):产品对 trust 的实现与原生 PostgreSQL 文档语义不一致(G100 对本地认证做了加固或另有策略开关,就这台实例的实测行为而言,除 vastbase 本机免密外一律要口令)。

解决:不迷信文件,运维脚本一律按"非 vastbase 用户都要口令"设计,统一走 PGPASSWORD + -h 127.0.0.1(md5 通道),实测稳定。

坑 2:pg_hba_file_rules 视图不存在 —— 产品功能差异

现象:想在线核对运行中实例的 hba 规则(PG 10+ 的标准姿势):

$ vsql -d postgres -p 5432 -c "select * from pg_hba_file_rules;"
错误:  关系 "pg_hba_file_rules" 不存在在 node1

原因:G100 当前内核(报 PostgreSQL 9.2.4 谱系)没有引入该视图。

解决:核对 hba 只能看文件本身 + 实测连接行为,改完记得重载并验证。

坑 3:vsql 对 SQL 错误返回退出码 0 —— 自动化脚本的头号陷阱

现象:授权被收回后 ops_ro 的查询在回显里明明白白报"权限不够",shell 里 $? 却是 0;改密报错"旧密码不能为空"那次同样 exit=0,口令实际没改成功。

排查:一组对照实验钉死退出码行为:

场景 退出码
正常 SQL 0
SQL 报错(不存在的表/权限不够/改密语法错) 0
SQL 报错 + -v ON_ERROR_STOP=1 3
连接失败(实例没起/口令错/账户锁定) 2

原因(定性):产品默认行为,vsql 只把"连接级致命错误"映射为非零退出码,SQL 层错误不影响退出码。

解决:脚本里 vsql 一律加 -v ON_ERROR_STOP=1,或者干脆以回显文本判定成败。不看退出码直接判成功,是 G100 自动化翻车的第一现场。

坑 4:用户本人改密必须带 REPLACE —— 产品语法要求

现象:ALTER USER xxx IDENTIFIED BY '新口令' 不带 REPLACE,报"旧密码不能为空,请用’replace’语法输入旧密码",且 vsql 退出码为 0(叠加坑 3,很容易以为改成功了)。

原因(定性):Oracle 风格改密语法的强制校验:本人改密必须自证旧口令。管理员改密(ALTER USER ... WITH PASSWORD)不需要 REPLACE。

解决:本人改密补上 REPLACE '旧口令';改完立刻用新口令登录验证、旧口令验证被拒,两步都做才算改完。另外口令复用策略会拦"新密码不能和旧密码相同"(reuse_max=3 / reuse_time=90),轮换口令时别想着换回去。

坑 5:默认授权"管理员代设不生效" —— 沿袭 PG 的语义,新手必踩

现象:7.5 节的完整对照:管理员 vastbase 执行 ALTER DEFAULT PRIVILEGES ... GRANT SELECT ON TABLES TO ops_ro,之后 ops_demo 建的新表 relacl 为空,ops_ro 照样"权限不够";换成 ops_demo 本人执行同样语句,新表自动带上授权。

原因:默认授权按执行者记账,只作用于执行者本人将来创建的对象——这与原生 PostgreSQL 语义一致,不算缺陷,但"管理员替业务用户配置默认授权"这个直觉动作必踩。

解决:默认授权由对象属主本人执行;若业务用户做不到,管理脚本里用 ALTER DEFAULT PRIVILEGES FOR ROLE ops_demo ... 显式指定目标角色(本实例未实测该写法,用前自行验证)。

坑 6:手工 vb_ctl 与 systemctl 混用互踩 —— 操作失误 + 单元文件设计

现象:3.4 节全程复盘:vb_ctl 手工拉起后 systemd 视角仍 inactive;此时 systemctl start 不但不报"已在运行",反而触发 ExecStop 把运行中的库停掉,status 里 ExecStart/ExecStop 双双 SUCCESS、服务 inactive(dead);之后再 vb_ctl stop 又报"PID 文件不存在"(exit=1)。

原因:systemd 单元 Type=forking + ExecStop 无条件执行 vb_ctl stop 的设计,叠加"手工启动后 systemctl start"这个操作失误,两股力量互踩。

解决:3.4 节末尾的三条铁律——动手前多源核实(is-active + ss + vb_ctl status);手工起的用手工停;日常只走 systemctl。

坑 7:vsql 没有 -w 选项 —— 产品差异

现象:按 PG 习惯加 -w(永不交互提问)想复现认证失败:

$ vsql -d opsdb -p 5432 -U ops_demo -w -Atc 'select 1;'
vsql: 不适用的选项 -- w
尝试 "vsql --help" 以得到更多资讯。

原因:G100 vsql 裁掉了这个选项。

解决:非交互场景避免触发提问,用 PGPASSWORD 显式传口令(或脚本里重定向 stdin 关闭交互)。

坑 8:启动日志里的 cgroup / gaussdb.version 告警 —— 噪音,勿慌

现象:vb_ctl 启动日志里刷"未能解析 cgroup 配置文件""未能打开特性控制文件 gaussdb.version"等警告。

原因:容器/cgroup 特性与特性控制文件在本机未配置,属启动噪音。

解决:实测这些警告不影响实例启动与服务(启动后 vsql 连通、端口监听正常),确认"服务端进程已经启动"行和端口即可,不用逐条消音。


九、常见问题排错速查

现象 根因 解决
连接到失败 Unknown:5432. 实例未启动或端口不对 systemctl status vastbase-server + ss -lntp | grep 5432
vsql: 致命错误: 用户名或密码错误,登录拒绝 口令错/口令已被轮换 管理员 ALTER USER ... WITH PASSWORD 重置
vsql: 致命错误: 账户被锁定 连续失败触发锁定(1440 分钟) 等待超时或管理员 ACCOUNT UNLOCK
错误: 密码必须包含至少8个字符。 口令策略(min_length=8) 换满足长度的口令
错误: 旧密码不能为空,请用'replace'语法输入旧密码。 本人改密缺 REPLACE IDENTIFIED BY '新' REPLACE '旧'
错误: 新密码不能和旧密码相同 口令复用策略(3 次/90 天) 用没用过的新口令
错误: 对关系 xxx 权限不够 表级权限缺失 GRANT 对应表权限
错误: 对模式 xxx 权限不够 schema USAGE 缺失 GRANT USAGE ON SCHEMA ... TO ...
错误: 无法删除"xxx"因为有其它对象依赖它 名下还有库/表/视图 先删库/移交属主再 DROP USER
脚本里 SQL 明明报错 exit 却是 0 vsql 退出码行为(坑 3) 加 -v ON_ERROR_STOP=1
systemctl status 显示双 SUCCESS 却 inactive vb_ctl/systemd 混用互踩(坑 6) 核实端口后交回 systemctl start

十、附录:DBA 日常操作速查

# ---------- 启停 ---------- systemctl start vastbase-server # 启动 systemctl stop vastbase-server # 停库(fast) systemctl restart vastbase-server # 重启 systemctl is-active vastbase-server # 状态确认(active/inactive) systemctl is-enabled vastbase-server # 开机自启确认 vb_ctl status -D /backup/vastbase/data # 数据目录视角(root/vastbase 均可看) vb_ctl start -D /backup/vastbase/data -t 60 # 手工拉起(救场用,见坑6) vb_ctl stop -D /backup/vastbase/data -m fast -t 60 # ---------- 连接 ---------- su - vastbase # 本机免密(管理员) vsql -d postgres -p 5432 PGPASSWORD='******' vsql -h 127.0.0.1 -p 5432 -U 业务用户 -d 库名 # md5 通道 # ---------- 用户 ---------- CREATE USER ops_demo WITH PASSWORD '******'; ALTER USER ops_demo WITH PASSWORD '******'; # 管理员改密 ALTER USER ops_demo IDENTIFIED BY '新******' REPLACE '旧******'; # 本人改密 ALTER USER ops_ro ACCOUNT LOCK; / ACCOUNT UNLOCK; DROP USER ops_tmp; # 先删/移交名下对象 # ---------- 库/schema ---------- CREATE DATABASE opsdb OWNER ops_demo ENCODING 'UTF8'; ALTER DATABASE opsdb OWNER TO ops_demo; CREATE SCHEMA ops AUTHORIZATION ops_demo; # ---------- 表/视图/索引 ---------- CREATE TABLE emp (id int PRIMARY KEY, name varchar(50) NOT NULL); CREATE INDEX idx_emp_dept ON emp(dept); CREATE VIEW v_emp_high AS SELECT id,name FROM emp WHERE salary>=8000; DROP INDEX idx_emp_tmp_id; DROP VIEW v_emp_tmp; DROP TABLE emp_tmp; # ---------- 授权/取消 ---------- REVOKE CONNECT ON DATABASE opsdb FROM PUBLIC; GRANT CONNECT ON DATABASE opsdb TO ops_ro; GRANT USAGE ON SCHEMA ops TO ops_ro; GRANT SELECT ON ALL TABLES IN SCHEMA ops TO ops_ro; GRANT INSERT,UPDATE ON ops.emp TO ops_ro; REVOKE INSERT,UPDATE ON ops.emp FROM ops_ro; -- 默认授权:由属主本人执行(见坑5) ALTER DEFAULT PRIVILEGES IN SCHEMA ops GRANT SELECT ON TABLES TO ops_ro; ALTER DEFAULT PRIVILEGES IN SCHEMA ops REVOKE SELECT ON TABLES FROM ops_ro; # ---------- 排查三板斧 ---------- select datname,datacl from pg_database where datname='opsdb'; select nspname,nspacl from pg_namespace where nspname='ops'; select relname,relacl from pg_class where oid='ops.emp'::regclass;

十一、终态快照

演练结束后的机器终态(复核依据):演示库 opsdb 与演示用户 ops_demo/ops_ro 保留在机上,四权账户与 bizdb 未做任何变更。

$ vsql -d postgres -p 5432 -c "select rolname,rolcanlogin from pg_roles where rolname like 'ops%' order by rolname;"
 rolname  | rolcanlogin 
----------+-------------
 ops_demo | t
 ops_ro   | t
(2 行记录)

$ vsql -d opsdb -p 5432 -c "select relname,relkind,relacl from pg_class where relnamespace='ops'::regnamespace and relkind in ('r','v') order by relname;"
  relname   | relkind |                    relacl                     
------------+---------+-----------------------------------------------
 dept_dic   | r       | {ops_demo=arwdDxt/ops_demo,ops_ro=r/ops_demo}
 emp        | r       | {ops_demo=arwdDxt/ops_demo,ops_ro=r/ops_demo}
 v_emp_high | v       | {ops_demo=arwdDxt/ops_demo}
(3 行记录)

$ vsql -d postgres -p 5432 -Atc 'select pg_postmaster_start_time();'
2026-09-14 09:57:37.807289+08

实例由 systemctl 托管运行中,端口 5432,开机自启 enabled,License 有效期至 2026-12-08。


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论