摘要:从使用中感受兼容模式带来的麻烦,并不是所有的数据都需要去做兼容模式。
Highgo数据库注册为服务
[root@localhost hgupload]# cd /opt/highgo/hgdb-v9.0/
[root@localhost hgdb-v9.0]# cd scripts/
[root@localhost scripts]# ll
总用量 24
-rwxrwxr-x 1 highgo highgo 565 1月 8 10:32 env.sh
-rwxrwxr-x 1 highgo highgo 2276 8月 8 11:43 register_db_service.sh
-rwxrwxr-x 1 highgo highgo 654 1月 8 10:32 runsql.sh
-rwxrwxr-x 1 highgo highgo 800 8月 8 11:43 service_status.sh
-rwxrwxr-x 1 highgo highgo 837 8月 8 11:43 unregister_db_service.sh
-rwxrwxr-x 1 highgo highgo 472 8月 8 11:43 unset_env.sh
[root@localhost scripts]#
[highgo@localhost scripts]$ ll
总用量 24
-rwxrwxr-x 1 highgo highgo 565 1月 8 10:32 env.sh
-rwxrwxr-x 1 highgo highgo 2276 8月 8 11:43 register_db_service.sh
-rwxrwxr-x 1 highgo highgo 654 1月 8 10:32 runsql.sh
-rwxrwxr-x 1 highgo highgo 800 8月 8 11:43 service_status.sh
-rwxrwxr-x 1 highgo highgo 837 8月 8 11:43 unregister_db_service.sh
-rwxrwxr-x 1 highgo highgo 472 8月 8 11:43 unset_env.sh
[highgo@localhost scripts]$
[highgo@localhost scripts]$ cat register_db_service.sh
#!/bin/bash -e
if [ "$#" -ne "4" ]; then
echo "Usage: $0 <DB_HOME> <DB_DATA> <SERVICE_NAME> <USER>"
exit 1
fi
DB_HOME=$1
DB_DATA=$2
SERVICE_NAME=$3
USER=$4
SYSTEMD_PATH="/lib/systemd/system"
SYSTEMD_SERVICE_FILE="$SYSTEMD_PATH/$SERVICE_NAME.service"
INITD_PATH="/etc/init.d"
INITD_SERVICE_FILE="$INITD_PATH/$SERVICE_NAME"
check_service_exist() {
if [[ -f "$SYSTEMD_SERVICE_FILE" || -f "$INITD_SERVICE_FILE" ]]; then
echo "Service '$SERVICE_NAME' already exists."
exit 2
fi
}
# Configure service for systemd
systemd_service() {
cat > "$SYSTEMD_SERVICE_FILE" << EOF
[Unit]
Description=HighGo database service
Requires=network.target local-fs.target
After=network.target local-fs.target
[Service]
User=$USER
Type=forking
ExecStart=$DB_HOME/bin/pg_ctl start -D $DB_DATA
ExecStop=$DB_HOME/bin/pg_ctl stop -D $DB_DATA
TimeoutSec=60
[Install]
WantedBy=multi-user.target graphical.target
EOF
}
# Configure service for System V init
initd_service() {
cat > "$INITD_SERVICE_FILE" << EOF
#!/bin/bash -xe
# chkconfig: 2345 99 01
# description: HighGo database service
### BEGIN INIT INFO
# Provides: highgo
# Required-Start: \$local_fs \$network
# Required-Stop: \$local_fs \$network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: HGDB
# Description: HighGo database service
### END INIT INFO
case "\$1" in
start)
$DB_HOME/bin/pg_ctl start -D $DB_DATA
;;
stop)
$DB_HOME/bin/pg_ctl stop -D $DB_DATA
;;
restart)
$DB_HOME/bin/pg_ctl restart -D $DB_DATA
;;
status)
$DB_HOME/bin/pg_ctl status -D $DB_DATA
;;
*)
echo "Usage: service $SERVICE_NAME {start|stop|restart|status}"
;;
esac
EOF
}
check_service_exist
# Register Service
if [ -d "$SYSTEMD_PATH" ]; then
if [ "$(getenforce 2>/dev/null ||:)" = "Enforcing" ]; then
chcon -R -t bin_t "$DB_HOME/bin"
fi
systemd_service
systemctl enable "$SERVICE_NAME.service"
systemctl daemon-reload
systemctl start "$SERVICE_NAME.service"
elif [ -d "$INITD_PATH" ]; then
initd_service
chmod +x "$INITD_SERVICE_FILE"
chkconfig "$SERVICE_NAME" on
service "$SERVICE_NAME" start
fi
echo "Successfully registered '$SERVICE_NAME' service."
[highgo@localhost scripts]$ ll
--- 注销服务
[highgo@localhost scripts]$ cat unregister_db_service.sh
#!/bin/bash -e
if [ "$#" -ne "1" ]; then
echo "Usage: $0 <SERVICE_NAME>"
exit 1
fi
SERVICE_NAME=$1
SYSTEMD_SERVICE_FILE="/lib/systemd/system/$SERVICE_NAME.service"
INITD_SERVICE_FILE="/etc/init.d/$SERVICE_NAME"
if [ -f "$SYSTEMD_SERVICE_FILE" ]; then
systemctl stop "$SERVICE_NAME.service"
systemctl disable "$SERVICE_NAME.service"
rm -f "/etc/systemd/system/multi-user.target.wants/$SERVICE_NAME.service"
rm -f "/etc/systemd/system/graphical.target.wants/$SERVICE_NAME.service"
rm -f "$SYSTEMD_SERVICE_FILE"
systemctl daemon-reload
elif [ -f "$INITD_SERVICE_FILE" ]; then
service "$SERVICE_NAME" stop
update-rc.d -f "$SERVICE_NAME" remove
rm -f "$INITD_SERVICE_FILE"
else
echo "Service '$SERVICE_NAME' not found."
exit 2
fi
echo "Successfully uninstalled '$SERVICE_NAME' service."
[highgo@localhost scripts]$ ll
--- 设置环境变量
[highgo@localhost scripts]$ cat env.sh
#!/bin/bash
INSTALL_DIR=/opt/highgo/hgdb-v9.0
# Path manipulation
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
export PATH=$PATH:$1
else
export PATH=$1:$PATH
fi
esac
}
if [ -d "$INSTALL_DIR/tools/migration" ]; then
pathmunge "$INSTALL_DIR/jdk/bin"
export HG_MIGRATION_HOME=$INSTALL_DIR/tools/migration
fi
# include database
if [ -d "$INSTALL_DIR/bin" ]; then
pathmunge "$INSTALL_DIR/bin"
fi
unset -f pathmunge
[highgo@localhost scripts]$ ll
--- 取消环境变量
[highgo@localhost scripts]$ cat unset_env.sh
#!/bin/bash
ENV_ID="# highgo environment"
BASHRC="$HOME/.bashrc"
BASH_PROFILE="$HOME/.bash_profile"
PROFILE="$HOME/.profile"
unset_env() {
local CONFIG_FILE=$1
if [ -f "$CONFIG_FILE" ]; then
if grep -q "$ENV_ID" "$CONFIG_FILE"; then
sed -i "/${ENV_ID}/{N;d;}" "$CONFIG_FILE"
sed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' "$CONFIG_FILE"
fi
fi
}
unset_env "$BASHRC"
unset_env "$BASH_PROFILE"
unset_env "$PROFILE"
unset -f unset_env
[highgo@localhost scripts]$ ll
--- 注册数据库
[highgo@localhost scripts]$ ./register_db_service.sh
Usage: ./register_db_service.sh <DB_HOME> <DB_DATA> <SERVICE_NAME> <USER>
[highgo@localhost scripts]$ ./register_db_service.sh /opt/highgo/hgdb-v9.0 /opt/highgo/hgdb-v9.0/data highgo highgo
./register_db_service.sh:行27: /lib/systemd/system/highgo.service: 权限不够
[highgo@localhost scripts]$
[root@localhost scripts]# ./register_db_service.sh /opt/highgo/hgdb-v9.0 /opt/highgo/hgdb-v9.0/data highgo highgo
Created symlink /etc/systemd/system/multi-user.target.wants/highgo.service → /usr/lib/systemd/system/highgo.service.
Created symlink /etc/systemd/system/graphical.target.wants/highgo.service → /usr/lib/systemd/system/highgo.service.
Successfully registered 'highgo' service.
[root@localhost scripts]#
[root@localhost scripts]#
[root@localhost scripts]#
[root@localhost scripts]#
[root@localhost scripts]# systemctl status highgo
● highgo.service - HighGo database service
Loaded: loaded (/usr/lib/systemd/system/highgo.service; enabled; vendor pres>
Active: active (running) since Thu 2026-01-08 10:39:59 CST; 14s ago
Process: 42061 ExecStart=/opt/highgo/hgdb-v9.0/bin/pg_ctl start -D /opt/highg>
Main PID: 42063 (postgres)
Tasks: 8
Memory: 31.3M
CGroup: /system.slice/highgo.service
├─42063 /opt/highgo/hgdb-v9.0/bin/postgres -D /opt/highgo/hgdb-v9.0/>
├─42065 postgres: checkpointer
├─42066 postgres: background writer
├─42067 postgres: walwriter
├─42068 postgres: autovacuum launcher
├─42069 postgres: stats collector
├─42070 postgres: pg_audit launcher
└─42071 postgres: logical replication launcher
1月 08 10:39:59 localhost.localdomain pg_ctl[42063]: 2026-01-08 10:39:59.281 CS>
1月 08 10:39:59 localhost.localdomain pg_ctl[42063]: 2026-01-08 10:39:59.281 CS>
1月 08 10:39:59 localhost.localdomain pg_ctl[42063]: 2026-01-08 10:39:59.281 CS>
1月 08 10:39:59 localhost.localdomain pg_ctl[42063]: 2026-01-08 10:39:59.283 CS>
1月 08 10:39:59 localhost.localdomain pg_ctl[42063]: 2026-01-08 10:39:59.285 CS>
1月 08 10:39:59 localhost.localdomain pg_ctl[42064]: 2026-01-08 10:39:59.336 CS>
[root@localhost scripts]# ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=5029,fd=5))
LISTEN 0 244 127.0.0.1:5866 0.0.0.0:* users:(("postgres",pid=42063,fd=6))
LISTEN 0 244 127.0.0.1:1521 0.0.0.0:* users:(("postgres",pid=42063,fd=8))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=5029,fd=6))
LISTEN 0 244 [::1]:5866 [::]:* users:(("postgres",pid=42063,fd=5))
LISTEN 0 244 [::1]:1521 [::]:* users:(("postgres",pid=42063,fd=7))
[root@localhost scripts]#
IvorySQL 初始化及兼容模式
IvorySQL 初始化模式选择
IvorySQL 在初始化过程中支持两种数据库模式:
- PG 模式:保持与原生 PostgreSQL 的兼容性
- Oracle 模式(默认):提供 Oracle 语法兼容及增强功能
用户可通过 initdb 命令参数指定初始化模式,实现不同场景下的兼容性需求。
initdb 在开始阶段会解析输入的命令行参数。
| 参数 | 功能描述 | 可选值 | 默认值 |
|---|---|---|---|
| -m | 指定数据库模式 | oracle/pg | oracle |
| -C | 设置 Oracle 兼容的大小写转换模式 | interchange/normal/lowercase | interchange |
文件路径初始化
执行 setup_data_file_paths() 函数完成关键文件路径配置:if (DB_PG == database_mode) set_input(&bki_file, "postgres.bki");else set_input(&bki_file, "postgres_oracle.bki");
路径检查机制:
- 验证 BKI 文件的存在性(postgres_oracle.bki postgres.bki)
- 确认配置文件模板的可用性
- 建立与数据库模式对应的系统目录结构
数据目录初始化流程
通过 initialize_data_directory() 函数完成核心初始化操作:
目录结构创建
调用 create_data_directory()创建主数据目录(PGDATA)。
通过 create_xlog_or_symlink() 建立 WAL 日志目录。
循环创建 base,global 等标准子目录。
配置文件初始化
调用 set_null_conf() 创建空的 postgresql.conf。
Oracle 模式下额外创建 ivorysql.conf 配置文件。
调用 setup_config() 将配置信息写入 postgresql.conf。在写入配置时,如果是 Oracle 模式,则会额外向 ivorysql.conf 中写入配置信息。
模板数据库引导
执行 bootstrap_template1() 加载对应模式的 BKI 文件初始化 template1 模板数据库,在此期间,IvorySQL 会将数据库模式(oracle/pg)和大小写转换模式写入到 pg_control 文件中。后面数据库启动时会将这些信息读取出来并设置相应的 GUC 变量。
load_plisql():安装兼容 Oracle PL/SQL 的 PL/iSQL 过程语言
load_ivorysql_ora():加载核心 Oracle 兼容层扩展
make_ivorysql():创建默认的 ivorysql 数据库
Oracle 兼容用户名处理
当数据库模式是 Oracle 时,会对用户名进行强制小写转换。
技术细节与扩展
在 PostgreSQL 中,“bki” 是 “Backend Interface” 的简写。Backend Interface 是 PostgreSQL 内部用于引导(bootstrap)数据库系统的一组工具和文件集合。
Backend Interface 主要用于初始化 PostgreSQL 数据库系统的基础结构,包括系统目录(system catalog)、系统表(system table)以及其他必要的系统对象。这些系统目录和表存储了 PostgreSQL 数据库系统的元数据信息,如数据库对象、表结构、索引信息等。
genbki.pl 处理系统表文件如 pg_class.h,pg_namespace.h,pg_proc.h 等,并生成 postgres.bki 供 initdb 加载,主要是加载初始化数据,如创建系统表,系统函数和预定义类型等。
在 initdb 前的编译阶段,会通过 genbki.pl 生成 postgres.bki 和 postgres_oracle.bki,postgres.bki 保持 PostgreSQL 原样,postgres_ora.bki
在 PostgreSQL 的基础上增加 Oracle 兼容的系统对象。

参考文档:https://www.modb.pro/db/1919577161774673920
highdb v9.0 数据库初始化
- 默认的兼容模式
[highgo@localhost data]$ initdb -D /opt/highgo/hgdb-v9.0/data
属于此数据库系统的文件宿主为用户 "highgo".
此用户也必须为服务器进程的宿主.
数据库簇将使用本地化语言 "zh_CN.UTF-8"进行初始化.
默认的数据库编码已经相应的设置为 "UTF8".
initdb: 无法为本地化语言环境"zh_CN.UTF-8"找到合适的文本搜索配置
缺省的文本搜索配置将会被设置到"simple"
禁止为数据页生成校验和.
Cluster file encryption is disabled.
修复已存在目录 /opt/highgo/hgdb-v9.0/data 的权限 ... 成功
正在创建子目录 ... 成功
选择动态共享内存实现 ......posix
选择默认最大联接数 (max_connections) ... 100
选择默认共享缓冲区大小 (shared_buffers) ... 128MB
选择默认时区 ... Asia/Shanghai
创建配置文件 ... 成功
正在运行自举脚本 ...成功
正在执行自举后初始化 ...成功
同步数据到磁盘...成功
initdb: 警告: 为本地连接启用"trust"身份验证
你可以通过编辑 pg_hba.conf 更改或你下次
执行 initdb 时使用 -A或者--auth-local和--auth-host选项.
成功。您现在可以用下面的命令开启数据库服务器:
pg_ctl -D /opt/highgo/hgdb-v9.0/data -l 日志文件 start
[highgo@localhost data]$
[highgo@localhost data]$ ll
总用量 64
drwx------ 5 highgo highgo 57 1月 8 11:39 base
drwx------ 2 highgo highgo 4096 1月 8 11:39 global
-rw------- 1 highgo highgo 967 1月 8 11:39 ivorysql.oracle.conf
drwx------ 3 highgo highgo 28 1月 8 11:39 pgaudit
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_commit_ts
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_cryptokeys
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_dynshmem
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_fdwxact
-rw------- 1 highgo highgo 4789 1月 8 11:39 pg_hba.conf
-rw------- 1 highgo highgo 1636 1月 8 11:39 pg_ident.conf
drwx------ 4 highgo highgo 84 1月 8 11:39 pg_logical
drwx------ 4 highgo highgo 48 1月 8 11:39 pg_multixact
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_notify
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_replslot
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_serial
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_snapshots
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_stat
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_stat_tmp
drwx------ 2 highgo highgo 26 1月 8 11:39 pg_subtrans
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_tblspc
drwx------ 2 highgo highgo 10 1月 8 11:39 pg_twophase
-rw------- 1 highgo highgo 3 1月 8 11:39 PG_VERSION
drwx------ 3 highgo highgo 108 1月 8 11:39 pg_wal
drwx------ 2 highgo highgo 26 1月 8 11:39 pg_xact
-rw------- 1 highgo highgo 88 1月 8 11:39 postgresql.auto.conf
-rw------- 1 highgo highgo 30592 1月 8 11:39 postgresql.conf
-rw------- 1 highgo highgo 933 1月 8 11:39 sec_pg.conf
[highgo@localhost data]$
[root@localhost data]# cat ivorysql.oracle.conf
#------------------------------------------------------------------------------
#Oracle COMPATIBLE Mode GUC parameters
#------------------------------------------------------------------------------
#ivorysql.listen_addresses = 'localhost' # what IP address(es) of Oracle mode to listen on;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
# (change requires restart)
#ivorysql.port = 1521 # (change requires restart)
ivorysql.enable_emptystring_to_NULL = 'on'
shared_preload_libraries = 'gb18030_2022, liboracle_parser, ivorysql_ora, pg_object, restricted_dba, pg_audit, sqlite_fdw, credcheck' # (change requires restart)
#ivorysql.default_collation_is_c = on
#ivorysql.enable_blankspace_compare = on # set to ignore blank space while in query
#ivorysql.enable_ora_default_collation = off
#ivorysql.subquery_with_raw_collation = on # Replace pseudo-collation back in Set subquery[root@localhost data]# vim postgresql.conf
[root@localhost data]#
- 使用pg模式
[highgo@localhost data]$ initdb -m pg -D /opt/highgo/hgdb-v9.0/data
属于此数据库系统的文件宿主为用户 "highgo".
此用户也必须为服务器进程的宿主.
数据库簇将使用本地化语言 "zh_CN.UTF-8"进行初始化.
默认的数据库编码已经相应的设置为 "UTF8".
initdb: 无法为本地化语言环境"zh_CN.UTF-8"找到合适的文本搜索配置
缺省的文本搜索配置将会被设置到"simple"
禁止为数据页生成校验和.
Cluster file encryption is disabled.
修复已存在目录 /opt/highgo/hgdb-v9.0/data 的权限 ... 成功
正在创建子目录 ... 成功
选择动态共享内存实现 ......posix
选择默认最大联接数 (max_connections) ... 100
选择默认共享缓冲区大小 (shared_buffers) ... 128MB
选择默认时区 ... Asia/Shanghai
创建配置文件 ... 成功
正在运行自举脚本 ...成功
正在执行自举后初始化 ...成功
同步数据到磁盘...成功
initdb: 警告: 为本地连接启用"trust"身份验证
你可以通过编辑 pg_hba.conf 更改或你下次
执行 initdb 时使用 -A或者--auth-local和--auth-host选项.
成功。您现在可以用下面的命令开启数据库服务器:
pg_ctl -D /opt/highgo/hgdb-v9.0/data -l 日志文件 start
[highgo@localhost data]$ ll
总用量 68
drwx------ 5 highgo highgo 57 1月 8 11:37 base
drwx------ 2 highgo highgo 4096 1月 8 11:37 global
drwx------ 3 highgo highgo 28 1月 8 11:37 pgaudit
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_commit_ts
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_cryptokeys
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_dynshmem
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_fdwxact
-rw------- 1 highgo highgo 4789 1月 8 11:37 pg_hba.conf
-rw------- 1 highgo highgo 1636 1月 8 11:37 pg_ident.conf
drwx------ 4 highgo highgo 84 1月 8 11:37 pg_logical
drwx------ 4 highgo highgo 48 1月 8 11:37 pg_multixact
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_notify
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_replslot
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_serial
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_snapshots
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_stat
drwx------ 2 highgo highgo 33 1月 8 11:37 pg_stat_tmp
drwx------ 2 highgo highgo 26 1月 8 11:37 pg_subtrans
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_tblspc
drwx------ 2 highgo highgo 10 1月 8 11:37 pg_twophase
-rw------- 1 highgo highgo 3 1月 8 11:37 PG_VERSION
drwx------ 3 highgo highgo 72 1月 8 11:37 pg_wal
drwx------ 2 highgo highgo 26 1月 8 11:37 pg_xact
-rw------- 1 highgo highgo 88 1月 8 11:37 postgresql.auto.conf
-rw------- 1 highgo highgo 30594 1月 8 11:37 postgresql.conf
-rw------- 1 highgo highgo 69 1月 8 11:37 postmaster.opts
-rw------- 1 highgo highgo 94 1月 8 11:37 postmaster.pid
-rw------- 1 highgo highgo 933 1月 8 11:37 sec_pg.conf
[highgo@localhost data]$
IvorySQL 与 Highgo
IvorySQL (Ivory 译为,象牙) 是由瀚高 (Highgo) 发起的基于 PostgreSQL 的衍生开源项目,采用 Apache-2.0 license,100% 兼容原生 PostgreSQL。IvorySQL 导入并增强了 Orafce 扩展插件,以此支持、兼容 Oracle 的诸多特性,如 PACKAGE、数据类型、转换函数等。IvorySQL 增加了 compatible_mode 开关,可以切换 PostgreSQL 和 Oracle 兼容模式。在 Oracle 兼容性方面,IvorySQL 还增加了独有的 PL/iSQL 过程语言,以此来支持 Oracle 的 PL/SQL 语法和 Oracle 风格的 PACKAGES。在即将发布的 IvorySQL v3.0 中,将支持双端口,即端口 5333 用于 IvorySQL 连接,端口 1521 用于 Oracle 模式连接。
2021 年 12 月 15 日,发布了 IvorySQL 的第一个版本。今年 6 月 28 日,发布了 IvorySQL 2.3,下图为目前 IvorySQL 的发布时间线。

参考文档:https://blog.itpub.net/31492144/viewspace-3021687/
作为国产中数据中,相对比较早的厂商,瀚高的发展不如金仓,达梦,高斯db,希望他发展的越来越好。




