数据库内核: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 能够正确地调试你的程序。

更新 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 版本也没有兼容性问题,那么你可以尝试以下步骤:

  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  阅读(150)  评论(0)    收藏  举报