KingbaseES 命令行工具完全指南:ksql 常用操作与技巧

一、写在前面

做 DBA 这么多年,GUI 工具我用过不少,KStudio、Navicat、DBeaver 都挺好使。但真正到了生产环境------尤其是那种只能通过堡垒机跳进去的机房服务器------你会发现,能依赖的只有命令行。KingbaseES 自带的 ksql 就是这样一个趁手的命令行工具,功能丰富且针对国产环境做了不少优化。这篇文章把我日常工作中最常用的 ksql 操作整理出来,希望能帮你少踩几个坑。

二、连接数据库:别小看这一行命令

2.1 找到你的 ksql

KingbaseES 安装后,ksql 一般藏在两个地方:

bash 复制代码
# 服务端自带的
/opt/Kingbase/ES/V8/Server/bin/ksql

# 独立的客户端工具(推荐用这个)
/opt/Kingbase/ES/V8/ClientTools/bin/ksql

生产环境建议用 ClientTools 目录下的版本,不依赖服务端的库文件,拷贝到跳板机上也能直接用。如果你懒得记路径,直接加到环境变量:

bash 复制代码
echo 'export PATH=/opt/Kingbase/ES/V8/ClientTools/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

2.2 基础连接方式

最朴素的连接命令长这样:

bash 复制代码
ksql -U system -d test

-U 指定用户名,-d 指定数据库名。执行后会让你输密码,连上之后提示符变成这样:

bash 复制代码
ksql (V8.0)
Type "help" for help.
test=#

注意那个 #,它表示当前用户是超级用户。如果是普通用户,提示符会变成 =>,这个细节在写操作文档时很有用,一眼就能看出来权限级别。

2.3 远程连接与密码处理

本地 socket 连接有个坑:有时候不指定 -h 参数,KingbaseES 不会强制验密,输什么密码都能进。这在开发环境是方便,生产环境就是安全隐患了。稳妥的做法是始终指定主机地址:

bash 复制代码
ksql -U system -h 192.168.1.100 -p 54321 -W -d test

-W 是强制要求输入密码,-p 指定端口(金仓默认 54321,注意别跟其他数据库的默认端口搞混)。

如果你经常连同一个库,可以建一个密码文件免掉每次输入的麻烦:

bash 复制代码
# ~/.pgpass 文件,权限必须是 600
chmod 600 ~/.pgpass
cat ~/.pgpass

内容格式:主机名:端口:数据库名:用户名:密码,比如:

ruby 复制代码
192.168.1.100:54321:test:system:YourPassword123

2.4 环境变量偷懒法

如果你连的参数每次都一样,可以设几个环境变量:

ini 复制代码
export KINGBASE_HOST=192.168.1.100
export KINGBASE_PORT=54321
export KINGBASE_DATABASE=test
export KINGBASE_USER=system

设完之后,直接敲 ksql 就能连,连 -U-d 都不用写了。

三、交互模式:ksql 的核心战场

3.1 先搞清楚自己在哪

连进去之后,第一件事是确认环境,免得操作错了库:

sql 复制代码
-- 当前连接信息
\conninfo

-- 数据库版本
SELECT version();

-- 许可证剩余天数(这个很重要,别等到过期了才发现)
SELECT get_license_validdays();

\conninfo 的输出大概长这样:

vbnet 复制代码
You are connected to database "test" as user "system" on host "192.168.1.100" at port "54321".

3.2 数据库和对象的"地图"

在陌生的库里干活,就像进了一个没开灯的仓库,得先摸清布局。ksql 提供了一堆以 `` 开头的元命令,我称之为"地图工具":

diff 复制代码
-- 列出所有数据库
\l

-- 切换到另一个库
\c production_db

-- 列出当前库的所有模式(Schema)
\dn

-- 列出当前模式下的所有表
\dt

-- 列出所有索引
\di

-- 列出所有视图
\dv

-- 列出所有函数
\df

-- 查看某张表的结构
\d orders

-- 查看表的权限分配
\dp orders

-- 列出所有角色/用户
\du

这些命令支持模糊匹配,比如你想找所有以 user 开头的表:

css 复制代码
\dt user*

输出会过滤出 user_infouser_loguser_permission 之类的表。

3.3 结果格式化:让输出更符合你的习惯

默认的输出是表格对齐模式,字段多了之后会变得很难看。ksql 提供了几种格式化切换:

sql 复制代码
-- 扩展模式,每行一个字段,适合字段很多的宽表
\x

-- 再执行一次查询,看看效果
SELECT * FROM user_info WHERE user_id = 10001;

扩展模式的输出会变成这样:

css 复制代码
-[ RECORD 1 ]--------+--------------------------
user_id              | 10001
username             | zhangsan
email                | zhangsan@company.com
created_at           | 2024-03-15 09:23:17
last_login           | 2026-05-07 18:45:33
is_active            | t
department           | 技术研发部
phone                | 13800138000

比挤在一行里清晰多了。想切回表格模式,再执行一次 \x 就行。

其他常用的格式控制:

lua 复制代码
-- 只显示数据,不显示表头
\t

-- 切换 HTML 输出(有时候需要把查询结果贴到邮件里)
\H

-- 设置 CSV 格式
\pset format csv

-- 设置字段分隔符为制表符(方便粘贴到 Excel)
\pset fieldsep '\t'

-- 显示执行时间
\timing on

\timing on 是我必开的选项,优化 SQL 的时候心里得有个数:

sql 复制代码
\timing on
SELECT COUNT(*) FROM orders WHERE created_at > '2026-01-01';

输出末尾会多一行:

yaml 复制代码
Time: 1243.567 ms (00:01.244)

3.4 把结果存到文件

有时候查询结果太多,终端里翻不动,或者需要交给别人分析,可以重定向到文件:

sql 复制代码
-- 开始输出到文件
\o /tmp/query_result.txt

-- 执行查询
SELECT * FROM orders WHERE status = 'pending';

-- 关闭文件输出,回到终端
\o

更省事的做法是在 shell 层面直接重定向:

bash 复制代码
ksql -U system -d test -c "SELECT * FROM orders" -o /tmp/orders.csv

四、脚本执行:从手工到自动化

4.1 执行外部 SQL 文件

这是最常用的场景。假设你有一个 init_tables.sql 文件:

bash 复制代码
ksql -U system -d test -f init_tables.sql

如果想在交互模式里临时执行一个脚本:

arduino 复制代码
\i /home/kingbase/scripts/backup_check.sql

4.2 单行命令快速执行

不需要进交互模式,直接在 shell 里执行一条 SQL:

bash 复制代码
ksql -U system -d test -c "SELECT COUNT(*) FROM users"

输出:

markdown 复制代码
 count
-------
 15234
(1 row)

这个技巧在写 Shell 脚本时特别好用,比如做一个定时巡检:

bash 复制代码
#!/bin/bash
# daily_check.sh
DB_NAME="production"
USER="monitor"

# 检查连接数
CONN_COUNT=$(ksql -U $USER -d $DB_NAME -t -c "SELECT COUNT(*) FROM sys_stat_activity WHERE datname = '$DB_NAME'" | xargs)

if [ "$CONN_COUNT" -gt 400 ]; then
    echo "[WARNING] $(date) - 当前连接数: $CONN_COUNT,接近上限" >> /var/log/db_check.log
fi

4.3 变量与条件执行

ksql 支持变量定义,这在写可复用的脚本时很有用:

sql 复制代码
-- 定义变量
\set table_name 'orders'
\set start_date '2026-01-01'

-- 在 SQL 中使用变量
SELECT COUNT(*) FROM :table_name WHERE created_at > :'start_date';

注意语法细节::table_name 用于标识符(表名、列名),:'start_date' 用于字符串值。混用会报错,我第一次用的时候在这里卡了十分钟。

条件执行适合处理不同环境的差异化逻辑:

bash 复制代码
\if :DB_NAME = 'production'
    \echo '正在操作生产库,请谨慎!'
\elif :DB_NAME = 'test'
    \echo '测试环境,放心折腾'
\else
    \echo '未知环境'
\endif

4.4 错误处理:别让小错误搞崩整个脚本

默认情况下,ksql 遇到错误会继续往下执行,这在批处理脚本里很危险。建议开启严格模式:

ini 复制代码
ksql -U system -d test -v ON_ERROR_STOP=1 -f critical_update.sql

或者在脚本开头加:

csharp 复制代码
\set ON_ERROR_STOP on

这样一旦某条 SQL 失败,整个脚本会立刻退出,不会继续执行后面的语句,避免数据处于半完成状态。

五、一些不太起眼但很实用的高级技巧

5.1 历史命令与快速编辑

ksql 支持 Readline 库,上下箭头可以翻历史命令,Ctrl+R 可以反向搜索。更爽的是 \e 命令:

diff 复制代码
-- 用外部编辑器编辑上一条命令
\e

这会调用你系统默认的编辑器(通常是 vi 或 nano),编辑完保存退出后,ksql 会自动执行修改后的命令。写复杂 SQL 的时候比在原终端里来回删改舒服多了。

5.2 在 ksql 里执行系统命令

不需要退出 ksql 就能看系统信息:

bash 复制代码
-- 查看当前目录文件
! ls -lh

-- 查看磁盘空间(数据目录够不够?)
! df -h /opt/Kingbase/ES/V8/data

-- 切换工作目录
\cd /tmp

-- 查看当前工作目录
! pwd

这个 ! 命令我经常用来检查日志文件大小,或者临时拷贝备份文件。

5.3 大对象(LOB)操作

虽然现在的业务系统很少直接操作大对象了,但万一遇到老系统维护,这几个命令能救命:

lua 复制代码
-- 导入文件到大对象
\lo_import '/tmp/product_manual.pdf'

-- 查看所有大对象
\lo_list

-- 导出大对象到文件
\lo_export 12345 '/tmp/exported_manual.pdf'

-- 删除大对象
\lo_unlink 12345

5.4 自定义提示符

默认的 test=# 太单调了,可以改成更有信息量的样式:

arduino 复制代码
\set PROMPT1 '%n@%m %/%R%# '

效果:

perl 复制代码
system@dbserver production=#

%n 是用户名,%m 是主机名(截断域名),%/ 是当前数据库名,%R 是提示符符号,%# 是超级用户标识。如果你管理多个环境,强烈建议把环境信息加到提示符里,避免误操作。

更花哨一点的,带颜色:

ini 复制代码
\set PROMPT1 '%[%033[1;32m%]%n@%m%[%033[0m%] %/%R%# '

这样用户名和主机名是绿色的,在黑白终端里一眼就能定位。

5.5 自动提交控制

KingbaseES 默认是自动提交模式,每条 SQL 执行完就提交。如果你需要显式控制事务:

sql 复制代码
-- 关闭自动提交
\set AUTOCOMMIT off

-- 现在可以手动控制事务了
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 确认没问题再提交
COMMIT;
-- 或者发现问题回滚
-- ROLLBACK;

关闭自动提交后,退出 ksql 时如果有未提交的事务,会收到警告,避免漏提交。

六、KingbaseES 特有功能

6.1 兼容模式查看

金仓的一个卖点是兼容 Oracle 和 MySQL,你可以查看当前的兼容模式:

ini 复制代码
SHOW COMPATIBILITY_MODE;

返回值可能是 STD(标准模式)、ORA(Oracle 模式)或 MYSQL(MySQL 模式)。不同模式下,同样的 SQL 可能有不同的行为,迁移的时候尤其要注意。

6.2 查看已安装的扩展

复制代码
\dx

输出示例:

sql 复制代码
                                    List of installed extensions
      Name       | Version |   Schema   |                        Description
-----------------+---------+------------+-----------------------------------------------------------
plsql           | 1.0     | pg_catalog | PL/SQL procedural language
sys_stat_statements | 1.0 | public     | track execution statistics of all SQL statements
pgcrypto        | 1.3     | public     | cryptographic functions

sys_stat_statements 是性能分析的利器,默认可能没有启用,需要手动加载:

sql 复制代码
CREATE EXTENSION IF NOT EXISTS sys_stat_statements;

6.3 错误详情查看

SQL 报错时,默认信息有时候不够详细。用 \errverbose 可以看到更完整的信息:

vbnet 复制代码
SELECT * FROM non_existent_table;
-- ERROR:  relation "non_existent_table" does not exist

\errverbose

输出会包含 SQLSTATE 错误码、出错位置等详细信息,排错的时候很有用。

七、常见问题与排错

7.1 连接失败排查 checklist

遇到连不上的情况,按这个顺序检查:

  1. 服务有没有起

    perl 复制代码
    ps -ef | grep kingbase
  2. 端口对不对?

    perl 复制代码
    ss -tlnp | grep 54321
  3. 监听地址设了没? 检查 kingbase.conf 里的 listen_addresses,默认可能是 localhost,远程连需要改成 '*' 或具体 IP。

  4. 防火墙放行了吗

    css 复制代码
    firewall-cmd --list-ports
  5. 密码对不对? 注意 KingbaseES 的密码策略,默认可能有复杂度要求,而且区分大小写。

7.2 字符集乱码

遇到中文乱码,先查编码:

sql 复制代码
-- 服务端编码
SHOW server_encoding;

-- 客户端编码
SHOW client_encoding;

-- 修改客户端编码
\encoding UTF8

如果服务端是 UTF8,客户端是 GBK,中文基本会乱。统一成 UTF8 最省事。

7.3 权限问题

报错 permission denied for relation,先确认权限:

sql 复制代码
-- 查看当前用户
SELECT current_user;

-- 查看表权限
\dp table_name

-- 查看角色权限
\du username

有时候不是没权限,是搜索路径(search_path)不对,表在别的 Schema 里:

sql 复制代码
-- 查看当前搜索路径
SHOW search_path;

-- 临时切换
SET search_path TO app_schema, public;

八、实用命令速查表

最后整理一张速查表,建议收藏或者打印贴显示器旁边:

命令 作用
\l 列出所有数据库
\c dbname 切换数据库
\dt 列出当前模式下的表
\d tablename 查看表结构
\di 列出索引
\dv 列出视图
\df 列出函数
\dn 列出模式
\du 列出角色/用户
\dp 列出权限
\x 切换扩展显示模式
\t 切换只显示数据(无表头)
\timing on/off 开启/关闭执行时间显示
\o filename 输出结果到文件
\i filename 执行外部 SQL 文件
\e 用编辑器编辑上条命令
! command 执行系统命令
\cd dir 切换工作目录
\conninfo 显示当前连接信息
\q 退出 ksql
? 查看所有元命令帮助
\h SQL命令 查看 SQL 语法帮助

九、写在最后

ksql 这个工具,表面上看起来就是个黑框框,但用熟了之后效率比 GUI 高得多。特别是当你需要批量处理、写自动化脚本、或者在服务器直接排错的时候,命令行的优势是图形工具没法比的。

几个我个人觉得最值得养成习惯的操作:

  1. 连接时始终加 -h 参数,养成安全连接的习惯;
  2. \timing on,对 SQL 性能心里有数;
  3. 复杂操作先 \set AUTOCOMMIT off,给自己留回滚的余地;
  4. 用好 \o-f,把重复操作脚本化。

如果你是从 MySQL 的 mysql 客户端转过来的,刚开始可能会觉得 ksql 的元命令语法有点别扭(为啥都是反斜线?),但坚持用一周,基本就能形成肌肉记忆了。毕竟,命令行工具的设计逻辑一旦熟悉,效率提升是非常明显的。

如果这篇文章对你有帮助,点个赞或者收藏一下,下次找起来方便。有问题也可以留言,看到都会回。

相关推荐
dllxhcjla2 小时前
Spring全套
java·后端·spring
追逐时光者2 小时前
2026 年 .NET 客户端常用 MVVM 框架推荐
后端·.net
_Evan_Yao3 小时前
长上下文模型(1M token)会杀死RAG吗?—— 理性分析
人工智能·后端
Rik3 小时前
Cursor Rules 深度玩法:从全局配置到项目级规则,让 AI 真正理解你的项目
前端·后端
TYKJ0233 小时前
Day4、10个排查网络问题的命令行工具:每个配真实输出,建议收藏
后端
renhailab3 小时前
被免费星巴克咖啡"骗"进 TRAE SOLO,却意外解锁了移动端 AI 办公新姿势
后端
渐儿3 小时前
Agent Harness 工程指南
后端
李日灐3 小时前
【优选算法5】位运算经典算法面试题
后端·算法·面试·位运算
杨运交3 小时前
[014][web模块]构建可重复读取的请求体:Spring Boot 请求缓存过滤器设计与实现
后端