数据库内核: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

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 能够正确地调试你的程序。

更新 miDebuggerPathprogram 属性之后,重新启动调试器,并检查是否仍然出现相同的错误。

首先,我在容器里可以用 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",这应该是程序的正确路径。你可以在容器中手动运行该程序,以确保它可以正常运行,并且没有遇到任何错误。

如果程序可以正常运行,那么你需要检查一下其他属性,例如 miDebuggerPathsetupCommands 是否设置正确,或者检查你的 VS Code 版本是否与你的操作系统和容器中的 GDB 版本兼容。

targetArchitecture 已经是 x86_64,program 的路径也是正确的,miDebuggerPath 也没有问题,setupCommands 也没有问题,GDB 版本 8.3,vscode1.76.0

ChatGPT

如果你已经确认了 targetArchitectureprogrammiDebuggerPathsetupCommands 的设置都是正确的,而且你的 GDB 版本和 VS Code 版本也没有兼容性问题,那么你可以尝试以下步骤:

  1. 确认你的程序能否在容器内正确运行。可以在容器中手动运行程序,以确保它没有遇到任何错误。
  2. 确认容器内的 GDB 是否可以与程序正确交互。在容器中使用 GDB 单独运行程序,以确保 GDB 能够正确启动并与程序交互。
  3. 如果容器内的 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 中镜像环境搭建。

posted @ 2023-02-24 21:31  FireOnFire  阅读(115)  评论(0)    收藏  举报