ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

openGauss安装配置与gsql连接排错全流程

openGauss安装配置与gsql连接排错全流程

简介:面向计算机科学与技术、软件工程专业学生的《数据库系统原理实验》配套报告书,对应课程实验环节,可用于预习实验流程、整理报告结构与复习数据库操作要点。压缩包内为1个docx文档,约3.23MB,按实验一至实验九组织,涵盖认识DBMS、创建数据库表与索引、交互式SQL、视图、完整性控制、安全性控制、事务与并发控制、备份恢复及JDBC连接数据库等主题。文档结合openGauss与gsql工具,记录实验目的、内容、操作过程、常见问题与更正思路,并附结果分析及截图、图表排版要求,便于对照完成实验记录和检查关键步骤。已有1527人学习,适合需要规范实验报告、梳理SQL与数据库管理流程的读者参考。

1. 装 openGauss 数据库这件事,常见故障点几乎都不在 SQL 上

第一次照着实验指导书搭 openGauss 数据库环境,十个人里有七个会在“装完连不上”这一步卡半天:gsql 敲下去报端口拒绝,su - omm 之后提示 command not found,或者建表时中文 CHECK 约束直接把行插不进去。这套《数据库系统原理实验》报告书里排了九个实验,从认识 DBMS、建库建表建索引,到视图、完整性、安全性、事务并发、备份恢复,最后一个用 JDBC 连库收尾;九个实验共用同一条基本链路:openGauss 数据库实例能起来,gsql 能连进去。环境起不来,后面八个实验连第一步都无法进行。这篇按我自己的装法,把 openGauss 数据库安装、环境搭建、参数配置和装坏之后的救法一次写透,适合刚拿到实验任务、机器还是干净系统的同学,也适合想把这套环境一次装好反复用的人。

2. 装法选型与环境预检:openGauss 三种安装方式的取舍

报告书里明确列了三种装法:弹性云主机上装、虚拟机一键装、先装 openEuler 再装 openGauss。原文没有限定具体小版本,只写了“如 openGauss”,所以选型这件事得自己做,选错了后面每一步都在补窟窿。

2.1 三种装法的成本对照

先把三条路的差别摆出来,再决定动手。我给自己的判断标准是:能不能反复重装、出问题能不能看到日志、以及要不要碰内核参数。

安装方式需要准备什么大概耗时适合谁主要风险
云主机上装已开好的实例、能登录的账号30~50 分钟手头机器配置低、只想跑通 SQL网络与权限边界不清,日志不好捞
虚拟机一键装虚拟机软件、官方极简版安装包20~40 分钟首次做实验、想快速看到 gsql 提示符安装脚本跑完以为成功了,其实实例没起
装 openEuler 再装系统镜像、分区、依赖包2 小时以上想搞清目录结构、后面还要调参数内核参数、依赖、防火墙,任一项漏了都起不来

我一般推荐第二种起步:极简版用一个 install.sh 把单机实例拉起来,端口、用户、数据目录都是脚本定好的,不容易在细节上跑偏。等这套跑通了,再回头做第三种,才知道每一步在干什么。第一种适合临时救急,但云端的安全组、白名单和本地虚拟机完全不是一回事,做完实验想搬到本机,等于重来一遍。

有一点要提前说清:极简版安装脚本跑完会打印一串提示,其中包含连接命令和端口。很多人看到“install success”就关掉终端了,实际上实例是否启动、omm 用户能不能连,是两件独立的事。脚本成功只代表文件铺完了。

2.2 装之前先把这五项对齐

不管走哪条路,装之前的预检都是同一套。系统层面报告里写的是 Windows 或 openEuler;如果选 Windows,实际上是装客户端或者连远程实例,服务端还是得在 Linux 上,所以真正要准备的是那台 Linux 机器。

# 1. 看内存和 swap,openGauss 单机实例对内存有下限要求 free -g # 2. 看数据目录所在分区的剩余空间,至少留出 20G df -h /opt # 3. 看内核参数是否已经调过 sysctl kernel.sem kernel.shmall kernel.shmmax vm.overcommit_memory # 4. 看防火墙状态,端口没放开本地也连不上 systemctl status firewalld # 5. 看 Python 版本,安装脚本和运维工具都依赖它 python3 --version

前两条是硬性条件,内存不够装到一半会失败,磁盘不够会在初始化数据目录时报错,而且报错信息往往看不出是空间问题。第三条最容易被跳过:数据库要用的共享内存段、信号量,系统默认值通常偏小,安装脚本执行时有概率直接失败。常见做法是把下面这组写进/etc/sysctl.conf,然后sysctl -p生效。

# 数据库主机的常规内核参数,写入后执行 sysctl -p kernel.sem = 250 32000 100 128 kernel.shmall = 1073741824 kernel.shmmax = 4398046511104 net.ipv4.ip_local_port_range = 9000 65500 vm.overcommit_memory = 0

参数说明:kernel.sem四个值分别是信号量集合数、每个集合的信号量数、单次 semop 调用允许的操作数、系统级信号量总数;kernel.shmall是共享内存总页数,kernel.shmmax是单个共享内存段上限,单位是字节;vm.overcommit_memory设 0 表示内核按启发式判断内存超额分配。这组值不是唯一答案,不同版本手册给的推荐值有出入,落地时以自己手上那版安装指南为准,但方向是对的:这几个值只能调大不能调小。

第四条要注意,防火墙和 SELinux 同时开着的时候,症状是本地 omm 用户能连、别的机器连不上,很多人会误判成配置没生效。第五条则关系到安装脚本能不能跑,Python 2 和 Python 3 的脚本不通用,这个坑在老的 openEuler 镜像上很常见。

2.3 安装目录、omm 用户与安装后目录结构

openGauss 有一个和其他数据库不太一样的地方:它不允许用 root 直接跑数据库进程,安装时会创建一个专用的操作系统用户 omm,之后所有实例操作都得切到这个用户下做。极简版安装脚本会自动建这个用户,手动装的话需要自己useradd。

安装目录按安装时--prefix指定的路径走,常见的做法是放/opt/software/openGauss。装完之后目录结构大致是这样:

# 以 omm 用户查看安装后的关键路径 ls -l $GAUSSHOME # 程序目录,bin 下面就是 gs_om、gsql、gs_guc ls -l $GAUSSDATA # 数据目录,postgresql.conf、pg_hba.conf 都在这 ls $GAUSSHOME/bin | head # 确认 gsql、gs_om、gs_guc、gs_dump 都在

$GAUSSHOME是程序目录,$GAUSSDATA是实例数据目录,这两个环境变量在 omm 用户的.bashrc里应该已经写好了。安装脚本经常漏配LD_LIBRARY_PATH,导致 gsql 能启动但连不上,报找不到动态库。装完先echo $GAUSSHOME $GAUSSDATA $LD_LIBRARY_PATH,三个都有值再往下走,这是最省事的自检。

3. 启动与连接链路:gs_om 与 gsql 参数怎么填

环境铺完只是把文件放到了磁盘上,实例是不是活的、能不能连,是另一条链路。这一段是整套环境里最容易反复出问题的地方,我把它拆成四步。

3.1 su - omm 之后要确认的三个环境变量

切换到 omm 用户这件事,命令写法有讲究。su omm和su - omm差一个横杠,前者不加载目标用户的环境变量,后者会。环境变量没加载,gs_om和gsql就会报 command not found。

# 必须带横杠,加载 omm 用户的完整登录环境 su - omm # 登录后立刻确认三项 echo $GAUSSHOME echo $GAUSSDATA echo $LD_LIBRARY_PATH which gsql

如果which gsql找不到,有两个处理办法:一是把$GAUSSHOME/bin加进 PATH 并source ~/.bashrc;二是直接用绝对路径/opt/software/openGauss/bin/gsql,能连上就说明只是 PATH 问题,不是实例问题。区分这一点很重要,很多人一看命令找不到就以为数据库没装好,重装一遍,白费一小时。

3.2 gs_om 的状态查询与启停

gs_om是 openGauss 自带的运维工具,-t后面跟动作类型。先查状态再启动,不要上来就 start。

# 查看实例详细状态,能看到节点、数据目录和进程号 gs_om -t status --detail # 启动实例 gs_om -t start # 停止实例 gs_om -t stop # 重启,改完配置后用这个,不要手动 kill 进程 gs_om -t restart

--detail打印出来的信息里,重点看两处:一个是实例状态是不是 Normal,另一个是数据目录路径对不对。状态显示正常但端口不通,问题在监听地址或防火墙;状态本身不正常,就得去看$GAUSSDATA/pg_log下最新的日志文件,里面通常直接写了哪一步失败了。

我要强调一句:不要用kill -9去停数据库进程。openGauss 有多进程协同,进程被杀掉之后共享内存段可能残留,下次启动会卡在初始化阶段,症状是 gs_om -t start 一直不返回。真遇到了,先看ipcs -m有没有残留段,确认没有实例在跑之后再清理,别上来就删数据目录。

3.3 gsql 连接参数逐个拆解

连接命令报告里给的是gsql -d postgres -p 26000 -r。这里每个参数都不是装饰品,得知道它管什么,出问题才知道改哪个。

参数含义不填的后果
-d目标数据库名默认连与用户名同名的库,往往不存在,直接报错
-p数据库端口默认 5432,而 openGauss 装出来是 26000 这类自定义端口,必然连错
-h服务端地址默认走本地套接字,远程连必须显式指定
-U连接用户名默认用当前操作系统用户,omm 之外的库用户必须带上
-W密码,可交互输入不带会进入交互提示,脚本里调用时建议用环境变量或.pgpass
-r交互模式相关不影响认证,省掉也能连上
# 本地连接默认库,端口按安装时打印的值填 gsql -d postgres -p 26000 -r # 远程连接:指定地址、库名、用户 gsql -h 192.168.0.10 -p 26000 -d postgres -U omm -W # 连接成功后确认版本,能打出版本号说明链路是通的 select version();

-r这个参数在报告里跟着命令出现,作用是让 gsql 走 readline 交互,上下键翻历史、退格正常,不同版本的帮助手册措辞略有差异。它不参与认证,所以看到别人的命令里没带这个参数也不用慌,连接能不能成功不取决于它。

第一次连进去,建议先跑四条确认命令,把环境摸清楚再建表:\l看库列表,\dn看模式,\db看表空间,select version()看版本。如果\l能列出来一堆系统库,说明实例是真活着,后面的操作就有底了。

3.4 远程连不上时先改的两处配置

本地 omm 能连、自己电脑上的客户端连不上,这是环境搭建里最常见的分界线问题。原因通常就两个:实例只监听了本机回环地址,或者连接白名单里没放行你的网段。

# 改监听地址,openGauss 用 gs_guc 改参数比手改配置文件稳妥 gs_guc set -N all -I all -c "listen_addresses = '*'" # 改完必须重启才生效 gs_om -t restart

-N all -I all表示对全部节点、全部实例生效,单机环境下就是那一个实例。参数名和 PostgreSQL 一致,但改法建议走 gs_guc,因为它会校验参数合法性,写错名字会直接拒绝,不会让实例下次起不来。

第二处是$GAUSSDATA/pg_hba.conf,这个文件控制“谁能从哪个地址、用什么认证方式连哪个库”。

# 允许 192.168.0.0/24 网段用密码认证连所有库 host all all 192.168.0.0/24 sha256

格式是四段或五段:连接类型、数据库、用户、来源地址、认证方式。host表示走 TCP,all是通配,最后一列sha256是 openGauss 支持的认证方式之一。改完不需要重启,但要让改动生效,可以执行gs_ctl reload或者直接重启实例。加完还连不通,回头查防火墙和云上的安全组,这两层经常被忘掉。

4. 建库建表建索引:表空间、schema、约束的落地顺序

连接通了之后就进入实验二的内容:建表空间、建库、建模式、建表、建索引。这一步的难点不在语法,在顺序。顺序错了,要么建表失败,要么改起来很别扭。

4.1 表空间与数据库:目录要先建出来

表空间在 openGauss 里对应一个物理目录。报告里用的写法是相对路径,相对于实例数据目录,所以目录得先手动建好,否则建表空间会直接报错说目录不存在。

# 以 omm 用户身份,在数据目录下准备表空间目录 mkdir -p $GAUSSDATA/tablespace/tablespace_1 ls -ld $GAUSSDATA/tablespace/tablespace_1
-- 相对路径写法,路径相对于实例数据目录 CREATE TABLESPACE tpcds_local RELATIVE LOCATION 'tablespace/tablespace_1'; -- 建库时显式指定表空间和编码,别指望默认值 CREATE DATABASE db_sc WITH TABLESPACE = tpcds_local ENCODING = 'UTF8'; -- 改名 ALTER DATABASE db_sc RENAME TO db_school; -- 切换过去 \c db_school

RELATIVE LOCATION和绝对路径写法是两回事,前者不允许指向数据目录之外,这是 openGauss 的一个安全限制,报错信息里会写得很明白。ENCODING = 'UTF8'建议显式带上,因为表里要存中文(性别字段就是中文),编码不对的话,后面 CHECK 约束会以很奇怪的方式失败。

一句话提醒:ALTER DATABASE ... RENAME TO改的是库名,不是表空间名;改库名之后\c要跟着换新名字,很多人还去连旧库,报库不存在,然后怀疑改名没成功。

4.2 模式与五张表:外键留到最后统一加

建表这一段,报告书里给的表结构不完全一致,Teachers 表里有 Dno,Departments 表里有 Dheadno 指向 Teachers,两张表互相引用。如果按“建表时就把外键写全”的思路走,第一张表就会因为引用对象不存在而失败。

我一般这么处理:先把所有表建出来,主键、非空、CHECK 这些单表约束写在 CREATE TABLE 里,跨表的外键用 ALTER TABLE 补。

-- 教师表:单表约束写在建表语句里 CREATE TABLE Teachers ( Tno CHAR(20) PRIMARY KEY, Tname CHAR(20) NOT NULL, Sex CHAR(20) CHECK (Sex = '男' OR Sex = '女'), Birthday DATE, Title CHAR(20), Dno CHAR(20) ); -- 院系表:先不加外键 CREATE TABLE Departments ( Dno CHAR(20) PRIMARY KEY, Dname CHAR(20), Dheadno CHAR(20) ); -- 学生表:Dno 指向院系,同样是后补外键 CREATE TABLE Students ( Sno CHAR(20) PRIMARY KEY, Sname CHAR(20) NOT NULL, Sex CHAR(20) CHECK (Sex = '男' OR Sex = '女'), Birthday DATE, Enrollyear CHAR(20), Speciality CHAR(20), Dno CHAR(20) ); -- 课程表:学时和学分用 SMALLINT 足够 CREATE TABLE Courses ( Cno CHAR(20) PRIMARY KEY, Cname CHAR(20) NOT NULL, Period SMALLINT, Credit SMALLINT );

SMALLINT的选择在报告里专门辨析过:有符号范围到 32767,无符号到 65535,学时和学分这种小数值,用它比用 INT 省一半存储。这不是微优化,建表时顺手的事,表数据量大了就能看出差别。

四张表建完,再用一条 ALTER 把外键补上:

-- 两张表都落地之后再补外键,避免相互引用导致建表失败 ALTER TABLE Departments ADD CONSTRAINT fk_dept_head FOREIGN KEY (Dheadno) REFERENCES Teachers(Tno); ALTER TABLE Students ADD CONSTRAINT fk_student_dept FOREIGN KEY (Dno) REFERENCES Departments(Dno); -- 选课表 SC:Sno 和 Cno 组合起来才是主键 CREATE TABLE SC ( Sno CHAR(20), Cno CHAR(20), Grade SMALLINT, PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Students(Sno), FOREIGN KEY (Cno) REFERENCES Courses(Cno) );

这里有个取舍要说清:约束名fk_student_dept是我自己起的,不起名字 openGauss 会自动生成一串,后面想删约束时得先去\d+里查名字,很麻烦。手写名字是一条值得坚持的习惯,出事的时候少一步排查。

建完用\dt看表列表,用\d+ Teachers看表结构,重点核对主键、外键、CHECK 有没有真的落下。\d+的输出信息量很大,字段类型、约束、索引、表空间归属都在里面,一个命令顶好几次查询。

4.3 CHAR(20) 和中文 CHECK 带来的两个隐性坑

报告里的表结构用的是CHAR(20),这是定长类型。定长意味着你插入'U001',实际存的是补满 20 位的字符串,查询显示时尾部空格容易被前端吞掉,看起来一切正常。但做等值比较、或者往 VARCHAR 字段里搬数据时,尾空格就成了不匹配的元凶。

我建议实验阶段照报告写 CHAR,但在自己项目里改成 VARCHAR,别问为什么,踩过就知道。真要保留 CHAR,插入和查询时统一用同样长度的字面量,别一半带空格一半不带。

第二个坑是中文 CHECK 约束。CHECK (Sex = '男' OR Sex = '女')这条约束依赖数据库编码,如果建库时没显式指定 UTF8,客户端终端的编码又和库不一致,插入中文会报约束冲突,或者报编码转换失败。症状是明明写的是“男”,就是不通过。排查顺序是:先看\l里库的编码,再看终端echo $LANG,两边对不上就先改客户端。

4.4 索引创建与 \di 验证

索引这一段报告里只给了一个例子:在 Students 的 Dno 上建索引。落地时要注意,主键本身会自动建立索引,不用重复建。

-- 在 Students.Dno 上建普通索引,用于加速按院系查学生 CREATE INDEX Student_Dept ON Students(Dno); -- 查看当前库所有索引 \di -- 查看某张表的索引和约束详情 \d+ Students

\di列出来的是名字、所在表、是否唯一。核对的时候要能对应上:主键索引是自动生成的,名字一般是“表名_pkey”这种形态,加上自己建的student_dept,一共几条,心里要有数。数不对就说明某条 CREATE INDEX 没执行成功,gsql 里命令是逐条提交的,中间一条报错不影响前后,很容易漏看。

建索引这步有个常见的误用:给每个字段都建一条。索引是拿写入性能换查询性能,表数据量小的时候看不出好处,反倒让插入变慢。实验里按报告建一两条就够了,重点是会用\di验证它确实存在。

5. 常见问题排查:连不上、找不到命令、建表报错的五条记录

环境类问题最难的地方不是修,是定位。下面这五条是我自己以及身边人反复遇到的,按现象、原因、解决三段记。

5.1 现象:gsql 报连接被拒绝;原因:实例没起或端口不对

敲gsql -d postgres -p 26000 -r,返回类似“could not connect to server: Connection refused”。第一反应往往是配置错了,实际上八成是实例根本没启动。

先gs_om -t status --detail看状态,状态不是 Normal 就gs_om -t start,起不来就看$GAUSSDATA/pg_log下最新的日志。状态正常还连不上,再核对端口:安装脚本跑完会打印实际端口,不一定是你以为的那个值。端口确认了还不行,才轮到查监听地址和防火墙。

5.2 现象:su - omm 后提示 gsql: command not found;原因:环境变量没加载

问题出在切换方式上。su omm不加载登录环境,su - omm才加载。已经切过去了,就手动确认$GAUSSHOME/bin在不在 PATH 里。

临时解决办法是直接用绝对路径/opt/software/openGauss/bin/gsql。长期做法是检查 omm 用户的.bashrc,把 GAUSSHOME、GAUSSDATA、LD_LIBRARY_PATH、PATH 四项补齐,然后source ~/.bashrc。注意别把这几行写进/etc/profile,那是全局的,其他用户也会带上数据库的库路径,容易引出别的问题。

5.3 现象:建表空间报目录不存在;原因:相对路径的基准目录没建

CREATE TABLESPACE tpcds_local RELATIVE LOCATION 'tablespace/tablespace_1'报错说目录不存在。原因是相对路径以实例数据目录为基准,那个子目录得先建出来,数据库不会帮你创建。

# 先建目录,再建表空间 mkdir -p $GAUSSDATA/tablespace/tablespace_1

建完确认权限属于 omm,属主不对的话建表空间会报权限不足,这两种报错信息长得很像,别混。

5.4 现象:建表报外键引用失败;原因:表的创建顺序不对

Teachers 和 Departments 互相引用,谁先建都缺对方。解决思路不是调整顺序,是把外键从 CREATE TABLE 里摘出来,等所有表都建完再统一 ALTER 补上。这也是我前面坚持“先建表后加约束”的原因,不是为了好看,是为了能一次跑通。

补外键时如果报“constraint already exists”,说明之前某次执行已经加成功了,用\d+ 表名看一眼,别重复加。

5.5 现象:实例起不来,gs_om -t start 卡住;原因:上次异常退出留下残留

手动 kill 过进程、或者虚拟机直接断电,下次启动会卡在初始化阶段,命令不返回也不报错。先看共享内存段有没有残留。

# 查看残留的共享内存段 ipcs -m # 确认没有实例在运行之后,谨慎清理 ipcrm -m <shmid>

清理之前必须先确认进程真的都没了,ps -ef | grep gauss看一眼。数据目录千万别手抖删掉,那是唯一恢复不了的东西。这一条我放在最后,因为它是唯一可能把环境搞成不可恢复状态的操作。

6. 跑通验证:拿九条元命令把环境过一遍

装完之后判断“到底能不能用”,我不用建表来验,用元命令跑一遍更快,也更全面。九条命令覆盖库、模式、表、索引、表空间、用户、角色七个维度,两分钟出结果。

-- 1. 帮助,确认 gsql 交互正常 \? -- 2. 库列表,确认目标库在里面 \l -- 3. 切库,确认权限没问题 \c db_school -- 4. 模式列表,确认 public 和自建模式都在 \dn -- 5. 表空间,确认自建表空间已注册 \db -- 6. 表列表 \dt -- 7. 索引列表 \di -- 8. 表结构详情,重点看约束和索引 \d+ Students -- 9. 退出 \q

对着结果核一张表,比翻日志快得多:

检查项期望结果不符合说明什么
\l能看到 db_school建库没成功或连错实例
\dn有 public 和 book_eg模式没建,或建在别的库
\db有 tpcds_local表空间建失败,表可能落在默认空间
\dt五张表齐全中间某条 CREATE 报错被忽略
\di主键索引 + 自建索引CREATE INDEX 没执行
\d+ Students主键、外键、CHECK 都在ALTER 加约束那步漏了

除了元命令,还可以用系统表交叉验证,比看界面输出更可靠:

-- 系统表查库列表,和 \l 的结果对一下 SELECT datname FROM pg_database; -- 查用户和角色,用户是具体账号,角色是权限集合 SELECT * FROM pg_roles;

pg_user和pg_roles这两个视图能直接查;pg_authid里带口令哈希,普通用户权限不够,查不到是正常的,别以为是环境坏了。

真正意义上的“跑通”,是能完成一次完整的写入回读:往 Teachers 插一行带中文性别的数据,查出来,再更新一次,最后删掉。中文能进能出,CHECK 不误伤,说明编码、约束、权限三条链路都是通的。到这一步,后面做视图、事务、备份恢复、JDBC 连接,都是在这个地基上叠。

从那以后我每次装完 openGauss,都会先在 omm 用户下把这九条元命令和一次中文写入走一遍,再动第一张业务表——环境这东西,宁可多花五分钟确认,也别在建表建到一半的时候才发现连的是个没起的实例。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进