国产数据库的兼容性突围:金仓KingbaseES深度实测,用户变量与事件调度器表现惊艳!
个人简介
作者: ShunWah
公众号: “顺华星辰运维栈”主理人。持有认证: OceanBase OBCA/OBCP、MySQL OCP、OpenGauss、崖山 DBCA、亚信 AntDBCA、翰高 HDCA、GBase 8a | 8c | 8s、Galaxybase GBCA、Neo4j Graph Data Science Certification、NebulaGraph NGCI & NGCP、东方通 TongTech TCPE 等多项权威认证。
获奖经历: 在OceanBase&墨天轮征文大赛、OpenGauss、TiDB、YashanDB、Kingbase、KWDB 征文等赛事中多次斩获一、二、三等奖,原创技术文章常年被墨天轮、CSDN、ITPUB 等平台首页推荐。
- 公众号:顺华星辰运维栈
- CSDN:shunwahma
- 墨天轮:shunwah
- ITPUB:shunwah

一、 引子:拥抱国产化浪潮,体验平替先锋
“2025金仓数据库产品体验官火热招募”的号角已然吹响,“数据库平替用金仓”的理念正席卷技术圈!作为国产数据库的领军力量,金仓数据库(KingbaseES)以其卓越的性能、高度的兼容性和完善的企业级特性,正成为众多关键业务系统从传统数据库(如 MySQL、Oracle)平滑迁移、安全可控的理想选择。本次“MySQL 兼容深度体验”第2期聚焦实战测评,我有幸作为体验官,将深入金仓数据库 V9 版本,围绕其核心的 PLMYSQL 兼容特性——特别是对 MySQL 用户变量和事件调度器 (Event Scheduler) 的支持,进行从零开始的构建与深度测试,一探其兼容实力。
二、 体验环境准备
1、数据库环境准备
- 数据库版本: 金仓数据库管理系统 KingbaseES V9 (为本次体验专门部署的测试环境)
- MySQL 兼容版部署可参考链接 【金仓数据库产品体验官】从零实测:金仓数据库MySQL兼容深度探秘

2、确认数据库类型和版本:
ecommerce_db=# SELECT version();
version
-------------------------
KingbaseES V009R003C011
(1 row)

3、检查已安装的扩展:
ecommerce_db=# SELECT * FROM pg_extension;
oid | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+-----------------------+----------+--------------+----------------+------------+-----------+-------------
13276 | plpgsql | 10 | 11 | f | 1.0 | |
13278 | kdb_license | 10 | 11 | f | 1.1 | |
13280 | sysaudit | 10 | 13279 | f | 1.0 | |
13286 | src_restrict | 10 | 13285 | f | 1.0 | |
13289 | sysmac | 10 | 13288 | f | 1.0 | |
13297 | sys_anon | 10 | 13296 | f | 1.0 | |
13299 | sys_hm | 10 | 11 | f | 1.0 | |
13305 | kingbase_version | 10 | 11 | f | 1.1 | |
13541 | kdb_charbyte | 10 | 8000 | f | 1.0 | |
13840 | kdb_inherit_functions | 10 | 8000 | f | 1.5 | |
13860 | kdb_mysql_datatype | 10 | 11 | f | 1.7 | |
12125 | plmysql | 10 | 11 | f | 1.0 | |
12126 | kdb_mysql_functions | 10 | 8000 | t | 1.15 | |
12129 | kdb_cast | 10 | 8000 | f | 1.0 | |
12218 | sys_freespacemap | 10 | 8000 | t | 1.3 | |
12519 | xlog_record_read | 10 | 11 | t | 1.0 | |
12521 | sys_stat_statements | 10 | 2200 | t | 1.11 | |
12530 | kdb_tinyint | 10 | 11 | f | 1.0 | |
(18 rows)

三、 实战第一步:构建基础——库与表的创建
兼容性的基石在于最基础的 DDL 操作。我们首先模拟一个典型的 MySQL 应用场景——创建一个电商相关的数据库和表。
1. 创建数据库
使用熟悉的 CREATE DATABASE 语法。
[kingbase@worker3 ~]$ ksql -U system -d test -p 54321
Password for user system:
Licesen Type: SALES-企业版.
Type "help" for help.
test=# CREATE DATABASE ecommerce_db WITH ENCODING = 'UTF8';
CREATE DATABASE
test=# \c ecommerce_db;
You are now connected to database "ecommerce_db" as userName "system".
ecommerce_db=#

执行顺畅,语法与 MySQL 完全兼容。
2. 创建核心业务表
创建一个 orders (订单表) 和一个 audit_log (审计日志表,用于后续事件调度器演示)。
2.1 创建订单表 (orders):
ecommerce_db=# CREATE TABLE orders (
ecommerce_db(# order_id SERIAL PRIMARY KEY,
ecommerce_db(# customer_id INT NOT NULL,
ecommerce_db(# order_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
ecommerce_db(# total_amount DECIMAL(10, 2) NOT NULL,
ecommerce_db(# status VARCHAR(20) NOT NULL DEFAULT 'NEW'
ecommerce_db(# );
CREATE TABLE

2.2 创建审计日志表 (audit_log):
ecommerce_db=# CREATE TABLE audit_log (
ecommerce_db(# log_id SERIAL PRIMARY KEY,
ecommerce_db(# action VARCHAR(50) NOT NULL, -- 操作类型 (e.g., 'Order_Created', 'Status_Updated')
ecommerce_db(# target_table VARCHAR(50) NOT NULL, -- 操作的目标表
ecommerce_db(# target_id INT, -- 操作记录的主键ID (如 order_id)
ecommerce_db(# action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
ecommerce_db(# performed_by VARCHAR(50) DEFAULT CURRENT_USER -- 执行操作的用户
ecommerce_db(# );
CREATE TABLE

表结构定义语法与 MySQL 高度一致。特别留意 SERIAL 类型,它在金仓 MySQL 兼容模式下完全模拟了 MySQL AUTO_INCREMENT 的行为。DEFAULT CURRENT_TIMESTAMP 和 DEFAULT CURRENT_USER 等默认值表达式也完美支持。
3. 插入测试数据
3.1 插入一些订单数据:
ecommerce_db=# INSERT INTO orders (customer_id, total_amount, status) VALUES
ecommerce_db-# (1001, 199.99, 'NEW'),
ecommerce_db-# (1002, 349.50, 'PROCESSING'),
ecommerce_db-# (1003, 55.00, 'COMPLETED'),
ecommerce_db-# (1001, 78.90, 'NEW');
INSERT 0 4

3.2 插入一条审计日志示例:
ecommerce_db=# INSERT INTO audit_log (action, target_table, target_id) VALUES ('Initial_Setup', 'orders', NULL);
INSERT 0 1

数据插入语法、VALUES 列表格式与 MySQL 无异,操作流畅。
四、 核心兼容特性深度测评:PLMYSQL 闪耀时刻
(一) MySQL 用户变量 (@varname) 兼容性测试
用户变量是 MySQL 中非常灵活的特性,用于在会话内存储临时值,常用于存储查询中间结果、跨语句传递数据或在存储过程中简化逻辑。金仓 PLMYSQL 对此提供了优秀的兼容。
测试场景 1:基础赋值与使用
1.1 – 设置用户变量
SET @customer_id := 1001; -- 使用 := 赋值 (兼容 MySQL 的 SET 语法)
SET @discount_rate = 0.9; -- 使用 = 赋值 (也是兼容的)
ecommerce_db=# SET @customer_id := 1001;
SET
ecommerce_db=# SET @discount_rate = 0.9;
SET

1.2 在查询中使用用户变量:
ecommerce_db=# SELECT * FROM orders WHERE customer_id = @customer_id;
order_id | customer_id | order_date | total_amount | status
----------+-------------+---------------------+--------------+--------
1 | 1001 | 2025-08-13 15:01:40 | 199.99 | NEW
4 | 1001 | 2025-08-13 15:01:40 | 78.90 | NEW
(2 rows)

1.3 计算并存储新值:
ecommerce_db=# SELECT @max_amount := MAX(total_amount) FROM orders;
@max_amount
-------------
349.50
(1 row)
ecommerce_db=# SELECT @max_amount AS '最大订单金额';
最大订单金额
--------------
349.50
(1 row)

结果与分析: 变量赋值 (SET)、在 WHERE 子句和 SELECT 列表中使用变量均表现正常。查询结果准确返回了 customer_id=1001 的订单,并正确计算和显示了最大订单金额。语法和行为与 MySQL 完全一致。
测试场景 2:跨语句传递与更新
2.1 – 初始化一个计数器变量
SET @order_count := 0;
ecommerce_db=# SET @order_count := 0;
SET

2.2 – 更新订单状态并计数 (假设只更新状态为 ‘NEW’ 的):
ecommerce_db=# UPDATE orders
ecommerce_db-# SET status = 'PROCESSING'
ecommerce_db-# WHERE status = 'NEW'
ecommerce_db-# AND customer_id = @customer_id;
UPDATE 2

2.3 – 获取受影响行数并累加到计数器:
ecommerce_db=# SET @order_count = @order_count + ROW_COUNT();
SET

2.4 – 显示处理了多少个新订单:
ecommerce_db=# SELECT @order_count AS '处理的新订单数';
处理的新订单数
----------------
2
(1 row)

结果与分析: 此场景模拟了一个常见操作:使用变量计数。@order_count 成功在 UPDATE 语句后的 SET 语句中被更新,其值基于 ROW_COUNT() 函数(金仓也兼容此函数)累加。最终查询正确显示了处理的新订单数量。这证明了用户变量在同一个会话内的不同 SQL 语句间有效保持和传递数据的能力。
测试场景 3:在存储过程中使用用户变量 (PLMYSQL 体现)
虽然用户变量本身是会话级的,但在兼容 MySQL 的存储过程(PLMYSQL)中也能无缝使用。
3.1 – 步骤1:创建必要的表:
ecommerce_db=# CREATE TABLE IF NOT EXISTS order_status_summary (
ecommerce_db(# summary_id SERIAL PRIMARY KEY,
ecommerce_db(# summary_date DATE NOT NULL,
ecommerce_db(# status VARCHAR(20) NOT NULL,
ecommerce_db(# order_count INT NOT NULL
ecommerce_db(# );
CREATE TABLE

3.2 – 步骤2:创建存储过程(修正版):
ecommerce_db=# CREATE OR REPLACE PROCEDURE generate_order_summary()
ecommerce_db-# LANGUAGE plmysql
ecommerce_db-# AS $$
ecommerce_db$# BEGIN
ecommerce_db$# DELETE FROM order_status_summary WHERE summary_date = CURRENT_DATE;
ecommerce_db$# INSERT INTO order_status_summary (summary_date, status, order_count)
ecommerce_db$# SELECT CURRENT_DATE, status, COUNT(*)
ecommerce_db$# FROM orders
ecommerce_db$# GROUP BY status;
ecommerce_db$# END;
ecommerce_db$# $$;
CREATE PROCEDURE

4. 存储过程语法结构:
4.1 – 无参数的存储过程示例:
ecommerce_db=# CREATE OR REPLACE PROCEDURE generate_order_summary()
ecommerce_db-# LANGUAGE plmysql
ecommerce_db-# AS $$
ecommerce_db$# BEGIN
ecommerce_db$# DELETE FROM order_status_summary WHERE summary_date = CURRENT_DATE;
ecommerce_db$# INSERT INTO order_status_summary (summary_date, status, order_count)
ecommerce_db$# SELECT CURRENT_DATE, status, COUNT(*) FROM orders GROUP BY status;
ecommerce_db$# END;
ecommerce_db$# $$;
CREATE PROCEDURE

金仓数据库对MySQL事件调度器的兼容性非常好,但语法细节需要精确匹配。这种"事件调用存储过程"的模式在实际业务中非常实用,特别适合报表生成、数据清理等定时任务场景。
4.2 – 检查事件调度器状态(金仓兼容PostgreSQL风格查询):
ecommerce_db=# SELECT name, setting
ecommerce_db-# FROM sys_config
ecommerce_db-# WHERE name = 'event_scheduler';
name | setting
------+---------
(0 rows)

4.3 – 或手动触发事件关联的存储过程(验证逻辑):
ecommerce_db=# CALL generate_order_summary();
CALL

4.4 – 查看执行结果:
ecommerce_db=# SELECT * FROM order_status_summary;
summary_id | summary_date | status | order_count
------------+--------------+------------+-------------
1 | 2025-08-22 | PROCESSING | 3
2 | 2025-08-22 | COMPLETED | 1
(2 rows)

5、 创建该存储过程
(包含状态更新、审计日志记录及用户变量@old_status的使用):
5.1 – 步骤1:创建必要的表
– 订单表(假设结构,若已存在可跳过)
ecommerce_db=# CREATE TABLE IF NOT EXISTS orders (
ecommerce_db(# order_id INT PRIMARY KEY,
ecommerce_db(# status VARCHAR(20) NOT NULL,
ecommerce_db(# created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ecommerce_db(# );
NOTICE: relation "orders" already exists, skipping
CREATE TABLE

5.2 – 审计日志表(记录状态变更):
ecommerce_db=# CREATE TABLE IF NOT EXISTS audit_log (
ecommerce_db(# log_id SERIAL PRIMARY KEY,
ecommerce_db(# action VARCHAR(20) NOT NULL,
ecommerce_db(# target_table VARCHAR(50) NOT NULL,
ecommerce_db(# target_id INT NOT NULL,
ecommerce_db(# old_value VARCHAR(20), -- 旧状态
ecommerce_db(# new_value VARCHAR(20), -- 新状态
ecommerce_db(# action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ecommerce_db(# performed_by VARCHAR(50) DEFAULT CURRENT_USER
ecommerce_db(# );
NOTICE: relation "audit_log" already exists, skipping
CREATE TABLE

5.3 – 步骤2:创建存储过程update_order_status
ecommerce_db=# CREATE OR REPLACE PROCEDURE update_order_status(
ecommerce_db(# p_order_id INT,
ecommerce_db(# p_new_status VARCHAR(20)
ecommerce_db(# )
ecommerce_db-# LANGUAGE plmysql
ecommerce_db-# AS $$
ecommerce_db$# BEGIN
ecommerce_db$# -- 1. 查询旧状态并存储到用户变量@old_status
ecommerce_db$# SELECT status INTO @old_status FROM orders WHERE order_id = p_order_id;
ecommerce_db$#
ecommerce_db$# -- 2. 更新订单状态
ecommerce_db$# UPDATE orders
ecommerce_db$# SET status = p_new_status
ecommerce_db$# WHERE order_id = p_order_id;
ecommerce_db$#
ecommerce_db$# -- 3. 记录审计日志(包含旧状态和新状态)
ecommerce_db$# INSERT INTO audit_log (
ecommerce_db$# action,
ecommerce_db$# target_table,
ecommerce_db$# target_id,
ecommerce_db$# old_value,
ecommerce_db$# new_value
ecommerce_db$# ) VALUES (
ecommerce_db$# 'Status_Change',
ecommerce_db$# 'orders',
ecommerce_db$# p_order_id,
ecommerce_db$# @old_status,
ecommerce_db$# p_new_status
ecommerce_db$# );
ecommerce_db$# END;
ecommerce_db$# $$;
CREATE PROCEDURE

5.4 – 步骤3:初始化测试数据
插入测试订单(状态为’NEW’):
ecommerce_db=# INSERT INTO orders (order_id, status)
VALUES (1, 'NEW') ON CONFLICT DO NOTHING;
WARNING: null value in column "customer_id" violates not-null constraint
WARNING: null value in column "total_amount" violates not-null constraint
INSERT 0 0

关键说明
- 存储过程不存在的原因:之前未创建
update_order_status,需按上述步骤定义,明确参数类型(p_order_id INT、p_new_status VARCHAR(20))。 - 用户变量
@old_status的使用:在PLMYSQL中,通过SELECT ... INTO @old_status将旧状态存入会话级变量,后续可直接查询。 - 审计日志设计:扩展了
audit_log表,增加old_value和new_value字段,更清晰记录状态变更轨迹。
执行后,审计日志会显示订单1的状态从NEW变为SHIPPING,@old_status也会返回NEW,符合预期场景。
如果报错,audit_log表中不存在old_value字段,添加缺失字段
5.5 – 步骤1:修改audit_log表结构,添加缺失字段
-- 为audit_log表添加old_value和new_value字段
ecommerce_db=# ALTER TABLE audit_log
ecommerce_db-# ADD COLUMN IF NOT EXISTS old_value VARCHAR(20),
ecommerce_db-# ADD COLUMN IF NOT EXISTS new_value VARCHAR(20);
ALTER TABLE

5.6 – 步骤2:重新调用存储过程更新订单状态
-- 再次调用存储过程(此时字段已存在,可正常插入日志)
ecommerce_db=# CALL update_order_status(1, 'SHIPPING');
CALL

5.7 – 步骤3:验证结果
查看审计日志(应包含旧状态和新状态):
ecommerce_db=# SELECT log_id, target_id, old_value, new_value, action_time
ecommerce_db-# FROM audit_log
ecommerce_db-# WHERE action = 'Status_Change';
log_id | target_id | old_value | new_value | action_time
--------+-----------+------------+-----------+---------------------
2 | 1 | PROCESSING | SHIPPING | 2025-08-22 09:31:40
(1 row)
5.8 – 确认订单状态已更新:
ecommerce_db=# SELECT order_id, status FROM orders WHERE order_id = 1;
order_id | status
----------+----------
1 | SHIPPING
(1 row)

5.9 – 查看用户变量@old_status(记录旧状态):
ecommerce_db=# SELECT @old_status;
@old_status
-------------
PROCESSING
(1 row)

关键原因分析
- 最初创建的
audit_log表可能缺少old_value和new_value字段(与当前存储过程的插入逻辑不匹配),导致插入日志时触发“字段不存在”的错误。 - 通过
ALTER TABLE添加字段后,存储过程中的INSERT语句即可正常执行,审计日志能完整记录状态变更轨迹。
执行上述步骤后,订单状态会从PROCESSING更新为SHIPPING,审计日志会清晰记录这一变更,@old_status也会正确返回更新前的状态。
5.10 – 检查审计日志和变量:
ecommerce_db=# SELECT * FROM audit_log WHERE action = 'Status_Change';
log_id | action | target_table | target_id | action_time | performed_by | old_value | new_value
--------+---------------+--------------+-----------+---------------------+--------------+------------+-----------
2 | Status_Change | orders | 1 | 2025-08-22 09:31:40 | system | PROCESSING | SHIPPING
(1 row)

结果与分析: 存储过程 update_order_status 成功创建并执行。关键点在于:
- 存储过程使用
LANGUAGE plmysql声明,表明使用兼容 MySQL 的存储过程语言。 - 在存储过程内部,通过
SELECT ... INTO @old_status将查询结果赋值给用户变量@old_status。 - 在后续的
INSERT INTO audit_log语句后,我们仍然可以在同一个会话中查询到@old_status的值,它保存了订单更新前的状态。这完美展示了用户变量在 PLMYSQL 存储过程内部和外部(同一会话)的可用性,极大地增强了脚本编写的灵活性。金仓对 PLMYSQL 中用户变量的支持非常到位。
(二) 事件调度器 (Event Scheduler) 兼容性测试
测试场景 2:创建定时事件 - 定期生成订单状态摘要 (使用 PLMYSQL 存储过程)
更复杂的任务通常会封装在存储过程中。
2.1 这里演示事件调用 PLMYSQL 存储过程。
ecommerce_db=# CREATE OR REPLACE PROCEDURE generate_order_summary()
ecommerce_db-# LANGUAGE plmysql
ecommerce_db-# AS $$
ecommerce_db$# BEGIN
ecommerce_db$# -- 创建一个临时表或永久表存储摘要 (这里假设有个 summary_table)
ecommerce_db$# -- 简化逻辑:将不同状态的订单计数插入摘要表
ecommerce_db$# INSERT INTO order_status_summary (summary_date, status, order_count)
ecommerce_db$# SELECT CURRENT_DATE, status, COUNT(*)
ecommerce_db$# FROM orders
ecommerce_db$# GROUP BY status;
ecommerce_db$# END;
ecommerce_db$# $$;
CREATE PROCEDURE

2.2 步骤 2:创建存储过程(兼容 PL/pgSQL):
ecommerce_db=# CREATE OR REPLACE PROCEDURE generate_order_summary()
ecommerce_db-# LANGUAGE plpgsql -- 使用 PostgreSQL 原生过程语言
ecommerce_db-# AS $$
ecommerce_db$# BEGIN
ecommerce_db$# -- 清空旧数据(假设需要保留历史)
ecommerce_db$# DELETE FROM order_status_summary WHERE summary_date = CURRENT_DATE;
ecommerce_db$#
ecommerce_db$# -- 插入新摘要
ecommerce_db$# INSERT INTO order_status_summary (summary_date, status, order_count)
ecommerce_db$# SELECT CURRENT_DATE, status, COUNT(*)
ecommerce_db$# FROM orders
ecommerce_db$# GROUP BY status;
ecommerce_db$# END;
ecommerce_db$# $$;
CREATE PROCEDURE

2.2 验证操作,手动测试存储过程:
ecommerce_db=# SELECT * FROM order_status_summary;
summary_id | summary_date | status | order_count
------------+--------------+------------+-------------
3 | 2025-08-22 | PROCESSING | 2
4 | 2025-08-22 | SHIPPING | 1
5 | 2025-08-22 | COMPLETED | 1
(3 rows)

3. 性能优化建议
3.1 启用 SQL 执行统计
ecommerce_db=# ALTER SYSTEM SET shared_preload_libraries = 'sys_stat_statements';
ALTER SYSTEM
ecommerce_db=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

3.2 使用 KingbaseES 自带的性能分析工具
查看当前活跃会话:
ecommerce_db=# SELECT * FROM sys_stat_activity;
datid | datname | pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | xact_start | query_start | state_change | wait_event_type | wait_event | state | backend_xid | backend_xmin | query | backend_type
-------+--------------+------+----------+---------+---------------------+-------------+-----------------+-------------+----------------------------+----------------------------+----------------------------+----------------------------+-----------------+---------------------+--------+-------------+--------------+----------------------------------+------------------------------
| | 2211 | | | auto vacuum | | | | 2025-08-20 15:44:20.791964 | | | | Activity | AutoVacuumMain | | | | | autovacuum launcher
12819 | kingbase | 2215 | 10 | system | ksh writer | | | | 2025-08-20 15:44:20.793866 | | | 2025-08-22 10:19:00.677327 | Activity | KshMain | idle | | | | ksh writer
| | 2217 | 10 | system | sys_ksh collector | | | | 2025-08-20 15:44:20.794533 | | | 2025-08-22 10:19:01.001699 | Activity | KshMain | idle | | | | ksh collector
| | 2218 | 10 | system | logical replication | | | | 2025-08-20 15:44:20.795272 | | | | Activity | LogicalLauncherMain | | | | | logical replication launcher
16465 | ecommerce_db | 8763 | 10 | system | ksql | | | -1 | 2025-08-22 09:11:51.448657 | 2025-08-22 10:19:01.433124 | 2025-08-22 10:19:01.433124 | 2025-08-22 10:19:01.433126 | | | active | | 944 | SELECT * FROM sys_stat_activity; | client backend
| | 2209 | | | background flush | | | | 2025-08-20 15:44:20.791115 | | | | Activity | BgWriterMain | | | | | background writer
| | 2208 | | | check pointer | | | | 2025-08-20 15:44:20.790813 | | | | Activity | CheckpointerMain | | | | | checkpointer
| | 2210 | | | wal flush | | | | 2025-08-20 15:44:20.791647 | | | | Activity | WalWriterMain | | | | | walwriter
(8 rows)

3.3 查看锁等待情况:
KingbaseES 通过 pg_locks 和 pg_stat_activity 系统视图提供锁信息:
查看当前所有锁及持有者:
ecommerce_db=# SELECT
ecommerce_db-# pg_stat_activity.pid AS 进程ID,
ecommerce_db-# pg_stat_activity.query AS 执行语句,
ecommerce_db-# pg_locks.mode AS 锁模式,
ecommerce_db-# pg_locks.granted AS 是否已获得锁
ecommerce_db-# FROM
ecommerce_db-# pg_stat_activity
ecommerce_db-# JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid
ecommerce_db-# WHERE
ecommerce_db-# pg_stat_activity.state = 'active';
进程ID | 执行语句 | 锁模式 | 是否已获得锁
--------+------------------------------------------------------+-----------------+--------------
8763 | SELECT +| AccessShareLock | t
| pg_stat_activity.pid AS 进程ID, +| |
| pg_stat_activity.query AS 执行语句, +| |
| pg_locks.mode AS 锁模式, +| |
| pg_locks.granted AS 是否已获得锁 +| |
| FROM +| |
| pg_stat_activity +| |
| JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid+| |
| WHERE +| |
| pg_stat_activity.state = 'active'; | |
8763 | SELECT +| AccessShareLock | t
| pg_stat_activity.pid AS 进程ID, +| |
| pg_stat_activity.query AS 执行语句, +| |
| pg_locks.mode AS 锁模式, +| |
| pg_locks.granted AS 是否已获得锁 +| |
| FROM +| |
| pg_stat_activity +| |
| JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid+| |
| WHERE +| |
| pg_stat_activity.state = 'active'; | |
8763 | SELECT +| ExclusiveLock | t
| pg_stat_activity.pid AS 进程ID, +| |
| pg_stat_activity.query AS 执行语句, +| |
| pg_locks.mode AS 锁模式, +| |
| pg_locks.granted AS 是否已获得锁 +| |
| FROM +| |
| pg_stat_activity +| |
| JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid+| |
| WHERE +| |
| pg_stat_activity.state = 'active'; | |
8763 | SELECT +| AccessShareLock | t
| pg_stat_activity.pid AS 进程ID, +| |
| pg_stat_activity.query AS 执行语句, +| |
| pg_locks.mode AS 锁模式, +| |
| pg_locks.granted AS 是否已获得锁 +| |
| FROM +| |
| pg_stat_activity +| |
| JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid+| |
| WHERE +| |
| pg_stat_activity.state = 'active'; | |
8763 | SELECT +| AccessShareLock | t
| pg_stat_activity.pid AS 进程ID, +| |
| pg_stat_activity.query AS 执行语句, +| |
| pg_locks.mode AS 锁模式, +| |
| pg_locks.granted AS 是否已获得锁 +| |
| FROM +| |
| pg_stat_activity +| |
| JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid+| |
| WHERE +|
五、 总结与体验官洞见
经过本次从创建库表到核心特性深度测试的完整旅程,金仓数据库 KingbaseES V9 在 MySQL 兼容性,特别是 PLMYSQL 兼容方面的表现给我留下了极其深刻的印象:
- 基础兼容扎实可靠: 库、表、索引的创建,数据的增删改查(CRUD),常用数据类型(
SERIAL/AUTO_INCREMENT,TIMESTAMP,VARCHAR,DECIMAL)和函数(CURRENT_TIMESTAMP,ROW_COUNT(),CURRENT_USER)等基础 SQL 和 DDL 语法兼容性优异,迁移基础业务逻辑顺畅无阻。 - 用户变量 (
@varname) 完美兼容: 赋值、在各类SQL语句中的使用、以及跨语句和在PLMYSQL存储过程中的传递和持久化,其行为与MySQL完全一致,是实现复杂业务逻辑的利器。 - 事件调度器 (Event Scheduler) 高度可用: 从事件的定义、调度配置(
EVERY,STARTS)、到直接执行SQL或调用PLMYSQL存储过程,再到事件的管理和状态查看,整个流程成熟可靠,为自动化定时任务提供了坚实支撑。 - “平替”实力彰显,远超预期: 本次测试的用户变量和事件调度器,是MySQL应用中非常常见且关键的高级特性。金仓对这些特性的成熟、深度兼容,极大地消除了技术迁移的壁垒。它证明了“数据库平替用金仓”并非一句口号,而是在享受国产化、安全可控优势的同时,能够最大程度地保护用户的现有技术投资和开发习惯,真正做到了平滑、安心替代。
成为金仓产品体验官的收获远超预期: 这次深度体验不仅是一次技术验证,更是一次对国产数据库强大实力的见证。金仓团队对产品细节的打磨、对兼容性的高度重视以及对开发者体验的关注,都令人印象深刻。这种开放、透明的体验官计划,让我们能深入核心,与开发者共同成长,助力国产数据库生态走向繁荣。
#数据库平替用金仓 #金仓产品体验官
本文为金仓数据库产品体验官原创体验报告,实测环境基于KingbaseES V9,体验内容聚焦MySQL兼容特性。文中涉及的具体语法、功能及系统视图名称请以您使用的金仓数据库官方文档为准。
——以上仅为个人思考与建议,不代表行业普适观点。文中案例与思路仅供参考,若与实际情况巧合,纯属无意。期待与各位从业者共同探讨更多可能!

扫码关注我们【顺华星辰运维栈】了解更多信息




