摘要

下午开始弄的。手头就一台 2 核 1.9 GiB 的腾讯云轻量服务器,平时跑博客,这次拿来当测试机。金仓 V9R1C10 的镜像 731 MB,从官方 OSS 拉,头一回还被防盗链拦了,加上 Referer 才下来。docker load 然后 docker run,ksql 就通了,版本 V009R001C010。后来建了张 1 万行的订单表,试了试 ROWNUM、序列、VARCHAR2、NUMBER 这些 Oracle 常用的东西,都能跑,就 DBMS_RANDOM 默认没装。最后 EXPLAIN ANALYZE 对比了一下,分组聚合没索引 6.966 ms,加了索引 2.104 ms。过程记录在下面。

一、为什么要写这篇

我平时用的是 MySQL 和 PostgreSQL,金仓只听说过,没碰过。征文活动开了,正好借这个机会把 V9R1C10 拉起来跑跑。手头这台机器内存不大,金仓起来后常驻六七百兆,剩下的地方不多。机器小也有小的好处,坑藏不住,踩到就是踩到,写出来大家少走弯路。

二、装的时候翻了翻容器

镜像加载完,我进容器看了看目录。/home/kingbase 下面,install 里是金仓的二进制,ksql 也在那儿;userdata 是挂出来的数据卷,后面建库就落在它上面。宿主机这边,Docker 把 54321 端口映射进容器,数据卷对应宿主的 /opt/kingbase/data。

Oracle 兼容模式是开着的,后面建表我就按 Oracle 的习惯写了。

三、这趟一共七件事

环境确认、拉镜像、加载镜像、启动容器、连库看版本、建演示表、索引前后对比,就这七件,挨着来。每件做完我截一张图,再写两句看到了什么。

场景

做什么

关键命令

图

场景一

确认机器能不能跑

uname、os-release、lscpu、free、docker --version

图 2

场景二

拉镜像并校验

curl + md5sum

图 3

场景三

加载镜像

docker load + docker tag

图 4

场景四

启动容器挂数据卷

mkdir data + docker run + docker ps

图 5

场景五

连库看版本

ksql -V + SELECT version() + 库列表

图 6

场景六

建订单表验证 Oracle 兼容

CREATE SCHEMA/TABLE/SEQUENCE + INSERT + ROWNUM 查询

图 7

场景七

索引前后性能对比

EXPLAIN ANALYZE + CREATE INDEX + 计时

图 8

场景一:先看看机器

uname -a、docker --version,各来一遍,看机器状态。

free -h 出来 1.9 GiB,我心里嘀咕了一下,这内存跑 V9R1C10 行不行。真跑起来,常驻 700 MiB 上下,加上系统和 Docker,小 1 GiB 没了,剩下的给系统缓冲。能用,就是别再同时开别的重容器了。

场景二:拉镜像,头一回被拦

curl 拉官方 OSS 上的 V9R1C10 镜像 tar 包,第一次直接 403,错误页写着"You are denied by bucket referer policy"。金仓的 OSS 开了防盗链,不带 Referer 头就不给下。

加上 Referer: https://www.kingbase.com.cn/ 再拉,通了。md5sum 算出来 26bb99891becc52f533488aac5fabfb6,我留了个记录,下次下载完先验一下,省得文件坏了到 docker load 才发现。

场景三:镜像名太长

加载完的镜像叫 kingbase_v009r001c010b0004_single_x86:v1,这一长串每次敲 docker run 都费劲。我 docker tag 成了 kingbase:v1。

docker images 里两个名字都在,image id 是同一个。原来的 tag 我没删,留着以后查版本号方便,也不占什么。

场景四:ksql 连不上,慌了

这一步最折腾。命令先放这:

数据卷建好、chown 完,docker ps 看到 Up 5 seconds,我还挺高兴。接着 docker exec kingbase ksql ...,第一次连就报错:

ksql: error: could not connect to server: FATAL:  could not open file "global/sys_filenode.map": Permission denied

docker logs kingbase 里 initdb 是成功的,server started 也打了,ksql 就是连不上。我坐那想了半天。后来反应过来,宿主机上这个数据卷 chown 成了 1001:1001,是 lighthouse 用户的,可容器里 kingbase 用户 uid 是 1000。两边对不上,700 权限的目录,ksql 读不了。

修复就一行:sudo chown -R 1000:1000 /opt/kingbase/data && sudo docker restart kingbase。再连,通了。这个教训我记下了,下次先查容器里用户的 uid,再对着 chown。

场景五:ksql 通了

ksql -V,KingbaseES V009R001C010,跟镜像标签对得上。SELECT version(); 也是 V009R001C010。库列表 5 个:test、kingbase、template1、template0、security,跟 PostgreSQL 差不多。

有个细节:ksql 的真实路径是 /home/kingbase/install/kingbase/bin/ksql,中间带 install/。我一开始照文档找 kingbase/bin,扑了个空,折腾了一会儿才发现。

场景六:演示表通了,DBMS_RANDOM 翻车

建订单演示表 demo.t_order,字段按 Oracle 习惯:NUMBER(10,2)、VARCHAR2(64)、CHAR(1)、TIMESTAMP DEFAULT SYSTIMESTAMP。

第一次 INSERT,我照着 Oracle 的写法抄了个,用 DBMS_RANDOM.VALUE 生成金额:

INSERT INTO demo.t_order SELECT 10000+g, '客户'||LPAD(g,5,'0'),
  ROUND(DBMS_RANDOM.VALUE(50,5000),2), ...

报错:schema or package "dbms_random" does not exist。V9R1C10 默认不装这个包,得手动加载。我换成 PG 的写法 ROUND((random()*4950+50)::numeric,2),就过了。1 万行灌进去,SELECT … WHERE ROWNUM <= 5 拿前 5 条,分页正常,中文字符串也正常。FETCH FIRST 3 ROWS ONLY 这种标准语法,直接就能用。

Oracle 兼容是真做了功夫,但 DBMS_RANDOM 不在默认包里。平时用 Oracle 的同事,估计会在这卡一下,业务里真依赖的话,部署的时候记得手动加载。

场景七:索引前后的差距

性能这块我最上心。EXPLAIN ANALYZE 会把规划代价和实际执行时间一起打出来,比光看 EXPLAIN 实在。

实测结果(1 万行 t_order,2 vCPU / 1.9 GiB 资源受限环境):

SQL

计划

Execution Time

实测耗时

分组聚合(无索引)

Seq Scan on t_order

6.966 ms

—

分组聚合(有索引)

Bitmap Index Scan on idx_order_status + Bitmap Heap Scan

2.104 ms

—

等值查询(status='S')

—

—

4.179 ms(含客户端解析)

加了索引,聚合从 6.966 ms 掉到 2.104 ms。status 就 N/S 两个值,金仓走了 Bitmap Index Scan,没走 B-Tree,跟我猜的一样。

机器内存就 1.9 GiB,这几万行的表基本都在内存里躺着,Seq Scan 本来就快,毫秒级的事。3.31 倍这个数,看着不算夸张。等哪天表长到几百万行,差距就不是一个量级的事了。

四、数据汇总

维度

实测结果

出处

部署门槛

4 步完成,单容器资源占用约 600~800 MiB

图 3~5

Oracle 兼容

ROWNUM / 序列 / VARCHAR2 / NUMBER / SYSTIMESTAMP / FETCH FIRST 全部可用;DBMS_RANDOM 需手动加载

图 7

性能起点

1 万行 Seq Scan 分组聚合 6.966 ms

图 8

性能上限

同等条件下加索引后 2.104 ms(3.31×)

图 8

资源占用

实测 1.9 GiB 内存可正常运行 V9R1C10

图 2

五、写在最后

这趟跑下来,几件事印象挺深。部署是真省事,4 步就起来了,比装 Oracle 那个安装包加一堆依赖轻快太多。Oracle 兼容也实打实,ROWNUM、序列这些常规的都能跑,就 DBMS_RANDOM 要自己装,这个坑踩一次就记住了。数据卷权限那个事最曲折,看到 Permission denied 我还怀疑过镜像,排查下来是 uid 的事,下次先把用户查清楚再 chown,省得折腾。

更多推荐