数据库内核:PostgreSQL源码安装
注意
使用 Centos7 在后续用本地 VScode 远程调试容器里的程序会出现错误,在容器里用 GDB 调试程序时就报了如下错误:
(gdb) r
Starting program: /home/postgres/helloworld
warning: Could not trace the inferior process.
Error: warning: ptrace: Function not implemented During startup program exited with code 127.
尝试了很久依旧没法基于 Centos7 解决问题,尝试解决这个 Bug 的过程可以拉到最下面,以下使用 Centos7 安装 PG 仅供参考。
准备虚拟机
这里我使用 Docker 的 CentOS7 的镜像去创建容器。
下载 CentOS7 镜像
(base) quanjunyi@Tys-MacBook-Pro ~ % docker pull daocloud.io/library/centos:7
7: Pulling from library/centos
75f829a71a1c: Pull complete
Digest: sha256:fe2347002c630d5d61bf2f28f21246ad1c21cc6fd343e70b4cf1e5102f8711a9
Status: Downloaded newer image for daocloud.io/library/centos:7
daocloud.io/library/centos:7
创建子网
创建容器时需要设置固定 IP,所以先要在 docker 中创建固定 IP 的子网。
(base) quanjunyi@Tys-MacBook-Pro ~ % docker network create --subnet=172.30.0.0/16 PostgreSQL
b1432a4717f33aac1c617295049257c4ad954f38af49863c79401bbe62a04f2b
创建容器
(base) quanjunyi@Tys-MacBook-Pro ~ % docker run -d --privileged -ti --platform linux/amd64 --name postgresql -h postgresql -p 18089:18089 -p 9871:9871 --net PostgreSQL --ip 172.30.0.2 daocloud.io/library/centos:7 /usr/sbin/init
76580124594aef0d61d6965e73255fcef5a43d0491f1e6e43af8161849bdd755
# 进入容器
(base) quanjunyi@Tys-MacBook-Pro ~ % docker exec -it postgresql /bin/bash
[root@postgresql /]# yum -y install openssh openssh-server openssh-clients
源码安装
免密登录
# 安装openssh
[root@postgresql /]# yum -y install openssh openssh-server openssh-clients
# 开启服务
[root@postgresql /]# systemctl start sshd
# 设置 StrictHostKeyChecking:no
[root@postgresql /]# vi /etc/ssh/ssh_config
# 重启服务
[root@postgresql /]# systemctl restart sshd
创建用户及用户组
# 创建postgres用户组
[root@postgresql postgresql-12.5]# groupadd postgres
# 创建postgres用户,用户位于postgres组内
[root@postgresql postgresql-12.5]# useradd -g postgres postgres
# 为postgres用户设置密码,密码为12345678
[root@postgresql postgresql-12.5]# passwd postgres
安装依赖
[root@postgresql /]# yum install gcc
[root@postgresql /]# yum install readline-devel.x86_64
[root@postgresql /]# yum install zlib-devel.x86_64
# 安装解压zip格式的压缩包所需的依赖
[root@postgresql /]# yum install -y unzip zip
# 安装vim工具,便于文件编辑
[root@postgresql PGDev]# yum -y install vim
# 安装以下依赖,否则执行configure会卡在了“checking for DocBook XML V4.2”
[root@postgresql postgresql-12.5]# yum install docbook-dtds docbook-style-xsl fop libxslt -y
# 使用make所需依赖
[root@postgresql postgresql-12.5]# yum -y install gcc gcc-c++ autoconf automake
[root@postgresql postgresql-12.5]# yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
使用 postgres 用户管理 PostgreSQL
# 切换用户
[root@postgresql /]# su postgres
# 回到用户目录
[postgres@postgresql /]$ cd ~
上传安装包
(base) quanjunyi@Tys-MacBook-Pro ~ % docker cp PGDev.zip postgresql:/home/postgres/
解压安装包
# 解压PGDev.zip到/opt目录下
[postgres@postgresql ~]$ unzip PGDev.zip
创建所需文件目录
# 进入PGDev文件夹
[postgres@postgresql ~]$ cd PGDev/
# 创建pghome文件夹,用于存储PostgreSQL本身
[postgres@postgresql PGDev]$ mkdir pghome
# 创建data文件夹,用于存储PostgreSQL所产生的数据
[postgres@postgresql PGDev]$ mkdir data
配置 env-debug 文件
# 修改配置文件
[postgres@postgresql PGDev]$ vim env-debug
# 将前面配置好的路径导入当前shell的环境变量中,没有任何输出则表示执行成功
[postgres@postgresql PGDev]$ source env-debug
配置
[postgres@postgresql PGDev]$ cd postgresql-12.5/
# 配置:确保接下来的构建和安装过程所需要的依赖准备好,并且搞清楚使用这些依赖需要的东西
[postgres@postgresql postgresql-12.5]# ./configure --prefix=$PGHOME --enable-debug
构建
# 这里假设机器4核心,如果不是可自行更改。写错了也不会影响构建结果,也可以不加-j4
[postgres@postgresql postgresql-12.5]# make -j4
安装
[postgres@postgresql postgresql-12.5]# make install
运行
# 初始化数据库
[postgres@postgresql postgresql-12.5]$ initdb
# 启动PostgreSQL服务
[postgres@postgresql postgresql-12.5]$ pg_ctl -D /home/postgres/PGDev/data/ -l logfile start
# 停止PostgreSQL服务
[postgres@postgresql postgresql-12.5]$ pg_ctl -D /home/postgres/PGDev/data/ -l logfile stop
# 重启PostgreSQL服务
[postgres@postgresql postgresql-12.5]$ pg_ctl -D /home/postgres/PGDev/data/ -l logfile restart
# 查看PostgreSQL状态
[postgres@postgresql postgresql-12.5]$ pg_ctl -D /home/postgres/PGDev/data/ -l logfile status
# 创建数据库test
[postgres@postgresql postgresql-12.5]$ createdb test
# 连接数据库test
[postgres@postgresql postgresql-12.5]$ psql test
psql (12.5)
Type "help" for help.
test=#
总结
- PostgreSQL 本体会在
/home/postgres/PGDev/pghome
中 - PostgreSQL 数据会在
/home/postgres/PGDev/data
中 - 后续如果对源代码作出修改,只需要在
/home/postgres/postgresql-12.5
中再次执行 make 与 make install 即可
尝试过程
由于这类问题无法在搜索引擎中找到答案,就尝试用 ChatGPT 来帮忙解决,说实话 ChatGPT 真不错。
ChatGPT
根据你提供的 launch.json
文件,你正在使用 cppdbg
配置类型来进行调试,但是在该配置中,你将 "miDebuggerPath"
设置为了 "/usr/local/bin/gdb"
,这可能不是适用于你的容器中的 GDB 调试器的路径。请确认容器中 GDB 的实际路径并将其更新到 miDebuggerPath
属性中。
此外,你在 program
属性中设置的路径 /home/postgres/helloworld
,可能也需要根据你的容器中实际的可执行文件路径进行更新。确保该路径指向正确的可执行文件。
最后,如果你的容器中的 GDB 是交叉编译的,则还需要根据目标板架构更新 "targetArchitecture"
属性,以便 GDB 能够正确地调试你的程序。
更新 miDebuggerPath
和 program
属性之后,重新启动调试器,并检查是否仍然出现相同的错误。
我
首先,我在容器里可以用 gdb 调试 helloworld 程序,并且 program 的路径是正确的,miDebuggerPath 也没有问题,如何看容器里的 GDB 是不是交叉编译的,如果是,targetArchitecture 应该改为什么
ChatGPT
如果你在容器中使用的是交叉编译的 GDB,则在 targetArchitecture
属性中应该指定你要调试的目标架构。这是因为交叉编译的 GDB 是用于调试目标架构的,而不是用于主机架构的。
要确定容器中的 GDB 是否是交叉编译的,可以运行以下命令来查看 GDB 的版本信息:gdb --version
如果 GDB 是交叉编译的,则版本信息中应该包含目标架构的信息。例如,如果你要调试的目标架构是 ARM64,则版本信息可能如下所示:GNU gdb (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2
在这种情况下,你应该将 targetArchitecture
属性设置为 "arm64"
。如果你不确定要调试的目标架构,请检查你的容器中编译的程序的架构。可以使用 file
命令查看可执行文件的架构信息:file /path/to/your/program
在输出中,架构信息通常在括号中显示,例如 (ARM aarch64)
, (Intel 80386)
, (x86-64)
, 等等。将该信息用作 targetArchitecture
属性的值即可。
例如,如果你的容器中的 GDB 是用于 ARM64 架构的交叉编译 GDB,并且你要调试的程序也是针对 ARM64 架构编译的,则可以将 targetArchitecture
设置为 "arm64"
:"targetArchitecture": "arm64"
我
[postgres@postgresql ~]$ file helloworld
helloworld: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=05948a8e196a8542453e6e733036dac17b474e06, not stripped
ChatGPT
根据你提供的文件类型,helloworld
是一个针对 x86-64 架构编译的可执行文件,因此在 launch.json
文件中将 targetArchitecture
设置为 "x86_64"
是正确的。
你可以检查一下是否正确指定了 program
属性,即你要调试的程序的完整路径。在你的 launch.json
文件中,你将 program
属性设置为 "/home/postgres/helloworld"
,这应该是程序的正确路径。你可以在容器中手动运行该程序,以确保它可以正常运行,并且没有遇到任何错误。
如果程序可以正常运行,那么你需要检查一下其他属性,例如 miDebuggerPath
和 setupCommands
是否设置正确,或者检查你的 VS Code 版本是否与你的操作系统和容器中的 GDB 版本兼容。
我
targetArchitecture 已经是 x86_64,program 的路径也是正确的,miDebuggerPath 也没有问题,setupCommands 也没有问题,GDB 版本 8.3,vscode1.76.0
ChatGPT
如果你已经确认了 targetArchitecture
、program
、miDebuggerPath
、setupCommands
的设置都是正确的,而且你的 GDB 版本和 VS Code 版本也没有兼容性问题,那么你可以尝试以下步骤:
- 确认你的程序能否在容器内正确运行。可以在容器中手动运行程序,以确保它没有遇到任何错误。
- 确认容器内的 GDB 是否可以与程序正确交互。在容器中使用 GDB 单独运行程序,以确保 GDB 能够正确启动并与程序交互。
- 如果容器内的 GDB 可以与程序正确交互,你可以尝试在 VS Code 中打开容器内的终端,然后手动使用 GDB 调试程序。这可以帮助你确定是否存在 VS Code 中的配置问题。
如果以上步骤都没有解决问题,你可以尝试在 VS Code 中查看调试器输出窗口(Debug Console),看看是否有任何有用的信息。你也可以尝试在 VS Code 中启用调试日志,以获取更多详细信息。你可以通过在 launch.json
文件中设置 "trace": "verbose"
来启用调试日志。
我
程序可以运行,但是在容器中用 gdb 调试时
(gdb) r
Starting program: /home/postgres/helloworld
warning: Could not trace the inferior process.
Error: warning: ptrace: Function not implemented During startup program exited with code 127.
ChatGPT
这个错误可能是由于 Docker 容器中的安全机制导致的。在默认情况下,Docker 会禁用 ptrace 系统调用,这会影响到 GDB 的使用。
要解决这个问题,可以在 Docker 运行时使用 --cap-add
选项来添加 SYS_PTRACE
功能,使得容器内的进程可以使用 ptrace 系统调用。例如,使用以下命令启动容器:docker run --cap-add=SYS_PTRACE ...
如果您正在使用 Docker Compose,则可以将 cap_add 选项添加到您的 docker-compose.yml
文件中。例如:
services:
myservice:
...
cap_add:
- SYS_PTRACE
请注意,启用 SYS_PTRACE 功能可能会增加容器的安全风险,因此建议只在必要时使用。
我
我的容器是 centos7,容器启动时已经加了 --privileged
让权限打开了,在容器中用gdb调试时,
(gdb) r
Starting program: /home/postgres/helloworld
warning: Could not trace the inferior process.
Error: warning: ptrace: Function not implemented During startup program exited with code 127.
ChatGPT
这个错误提示通常是由于在容器中运行 gdb
时没有足够的权限或没有正确的配置导致的。
我
最后我给 postgres 用户运行 GDB 的权限后依旧无法启动,还是因为 Centos7 没有办法使用 Ptrace 系统调用。最后,放弃 Centos7,在 Ubuntu 中镜像环境搭建。