WSL配置PostgreSql开发环境

4030 字
20 分钟
WSL配置PostgreSql开发环境

目标描述#

本教程的目标是配置一套 PostgreSql 的本地开发调试环境。

本教程所需的前置环境和目标环境为:

操作系统:Windows + WSL Ubuntu 22.04

IDE:VS Code

即,我们将在 Windows + WSL Ubuntu 22.04 的环境中,使用 VS Code IDE 进行 PostgreSql 的调试开发。

我们推荐将 PostgreSql 安装至 WSL 中,在 Windows 中使用 VSC Remote 连接 WSL 进行开发调试。因为 WSL 的配置非常简单,且能够直接在 Windows 系统上使用 Linux ,而 Linux 的环境配置非常简单;在 Windows 上使用 VSC 方便快捷,能够地减少学习 Linux 的学习成本。

配置步骤#

由于我们的目标不是为开源社区做贡献,而是为了解决我们的个性化问题,因此追求最新版本的 PG 可能会得不偿失(最新版本的软件往往可能会出现较大的变更,不利于初步学习。如果你有研究成果开源化的需求,可以考虑使用最新版本的 PG 源码)。

在这里我选用了 v17.0 的 PG 源码进行学习, v17.0 是 PG 目前最后一个大版本更新,同时兼容我需要研究的插件,如果你想研究的插件或功能有特定版本需求,这一步需要明确你下载的源码版本。

alt text
alt text

1、克隆源码至 WSL 并使用 VSC Remote 打开项目#

这一步可以根据需求选择克隆最新版本的 github 版本的源码,也可以考虑直接下载某个版本的源码。

1.1 github#

如果你需要向社区提出贡献,那最好选择直接克隆指定版本,重度开发之后的分支冲突是不可接受的:

$ git clone https://github.com/postgres/postgres.git
$ cd postgres
## 一般更改代码都在特定的Branch上进行
$ git checkout -b FEATTURE-NAME
$ EDIT YOUR CODE
$ git commit -a
$ git diff --patience master my-feature > ../my-feature.patch

1.2 官网版本目录#

我们选择 17.0 版本直接下载,将下载的压缩包放置于 WSL,如下图:

alt text
alt text

alt text
alt text

1.3 使用 VSC Remote 打开任意 WSL 文件夹作为项目根目录:#

接着,直接使用命令行或使用 VSC 远程连接 WSL 再打开命令行。这里只写如何用 VSC 连接 WSL 并打开文件夹和命令行:

alt text
alt text

alt text
alt text

alt text
alt text

然后执行解压命令:

tar -xf postgresql-17.0.tar.gz

接着,打开一个新的 VSC 窗口,重复上面的连接步骤,将解压的 PG 文件夹直接打开。

2、编译#

2.1 VSC 插件安装#

推荐安装:

alt text
alt text
alt text
alt text

2.2 pg 编译依赖库安装#

pg 需要安装下列库,可以在这里直接输入命令行安装;也可以按照 2.4 章节的 VSC -> tasks ,在准备编译时一键安装。

sudo apt install -y libsystemd-dev libxml2-dev libssl-dev libicu-dev zlib1g-dev libreadline-dev pkg-config

2.3 编写 VSC 的编译配置文件#

VS Code 中的任务 Task 可以配置为运行脚本和启动进程,以便可以在 VS Code 中使用许多现有工具,而无需输入命令行或编写新代码。工作区或文件夹特定任务是从工作区的 .vscode 文件夹中的 tasks.json 文件配置的。

我们需要打开 PG 源码根目录作为 VSC 的项目目录,然后 ctrl + shift + p 打开 VSC 的 Command Palette,然后按下图创建 Task 模板:

alt text
alt text

alt text
alt text

alt text
alt text

然后修改 tasks.json 为:

下面提供了两个配置文件,推荐使用后者。后者可以一键完成环境配置等任务。

2.3.1 官方简单示例#

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"presentation" : { "reveal": "always" },
"tasks": [
{
"label": "Configure",
"type": "shell",
"command": "./configure --enable-depend --enable-cassert --enable-debug",
"problemMatcher": [
"$eslint-compact"
]
},
{
"label": "Make All",
"type": "shell",
"command": "make -j10 all",
"problemMatcher": [
"$eslint-compact"
]
},
{
"label": "Make Clean All",
"type": "shell",
"command": "make clean",
"problemMatcher": [
"$eslint-compact"
]
},
{
"label": "Make Install",
"type": "shell",
"command": "make install"
}
]
}

这个 JSON 摘取于 http://www.postgres.cn/v2/news/viewone/1/459 ,提供了四个任务的配置:

1、Configure 是编译前的配置文件生成
2、Make All 是编译全部代码
3、Make Clean All 是清空所以编译结果
4、Make Install 是编译并安装 PG

对于我们开发人员来说,一般只需要使用前三个 Task ,使用的步骤是:

1、在第一次 Make All 之前,执行一次 Configure 任务,之后无需执行 Configure 。
2、每次有代码变更后,执行 Make All 。如果遇到了不可解决的编译错误,尝试 Make Clean All 后重新 Make All。

执行任务的方法是:

打开 Command Palette ,选择 Tasks: Run Task,最后选择对应的 Configure、Make 或者 make install 命令来进行 PostgreSQL 的编译等任务。

2.3.2 比较完整的配置#

{
"tasks": [
{
"type": "shell",
"label": "install_depends",
"command": "sudo apt install -y libsystemd-dev libxml2-dev libssl-dev libicu-dev zlib1g-dev libreadline-dev pkg-config",
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Task install depends."
},
{
"type": "shell",
"label": "build_env",
"command": "mkdir build && mkdir -p pgsql/data",
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Task add folders."
},
{
"type": "shell",
"label": "build_config",
"command": "../configure",
"args": [
"--prefix=${workspaceFolder}/pgsql",
"--with-icu",
"--with-openssl",
"--with-systemd",
"--with-libxml",
"--enable-debug"
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task Build MakeFile."
},
{
"type": "shell",
"label": "make",
"command": "make",
"args": [
"-j12"
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task build."
},
{
"type": "shell",
"label": "make_install",
"command": "make",
"args": [
"install"
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task install database."
},
{
"type": "shell",
"label": "init_db",
"command": "pgsql/bin/initdb",
"args": [
"-D",
"pgsql/data"
],
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Task init default database."
},
{
"type": "shell",
"label": "clean_db",
"command": "make uninstall && make clean && rm -rf ../pgsql && rm -rf ../build",
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task clean database."
},
{
"type": "shell",
"label": "build_db_conf",
"dependsOn": [
"build_env",
"build_config"
],
"dependsOrder": "sequence",
"detail": "Task add folders."
},
{
"type": "shell",
"label": "build_db",
"dependsOn": [
"make",
"make_install",
"init_db"
],
"dependsOrder": "sequence",
"detail": "Task add folders."
},
{
"type": "shell",
"label": "rebuild_db",
"dependsOn": [
"make",
"make_install"
],
"dependsOrder": "sequence",
"detail": "Task add folders."
},
],
"version": "2.0.0"
}

摘自 https://www.cnblogs.com/microestc/p/17079518.html

2.4 编译#

我们在这里使用第二份 tasks.json 直接进行一系列的编译,经过实测后,该脚本还存在一些小问题。

1、我选用的 pg 版本还需要 bison flex 两个库。因此我修改了上述的 tasks.json 文件,添加了一些注释,并在安装依赖任务中添加了两个库的安装。

2、init_db 任务在系统第一次安装 pg 时还存在一些用户权限问题,pg 不推荐 root 用户进行初始化数据库,所以我选择了新建一个专门的 postgres 用户进行初始化 pg ,编写了对应的 task。并修改 init_db 这个 task 进行了适配。

2.4.1 新建 postgres 专用用户,将 PG 源码目录移动到该用户目录下#

创建用户我提供了三种方法,选取其一就可以。我推荐第2个,直接在命令行中执行即可,比较简单。

1、编写创建用户脚本:

#!/bin/bash
# 检查是否存在 postgres 用户,如果不存在则创建它
if ! id postgres &>/dev/null; then
sudo useradd -m -s /bin/bash postgres
echo "Postgres user created."
else
echo "Postgres user already exists."
fi

2、手动检查并创建(推荐、自定义密码):

id postgres
sudo useradd -m -s /bin/bash postgres
sudo passwd postgres

3、使用我的 VSC task 直接创建:

2.4.2 章节的任务配置,让我们可以直接在 VSC 中以任务的形式创建 postgres 用户,按照直接执行 setup_postgres_user 任务即可。在 VSC 中执行 tasks.json 中编写的 task 的方法如下:

我们打开任意一个 WSL 目录作为 VSC 的项目根目录,按照 2.3 的教学创建 tasks.json 文件。然后在 VSC 中,按 ctrl + shift + p 打开 Command Palette ,创新新的 tasks 配置,然后将下面内容覆盖进去:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "setup_postgres_user", // 为 PG 新建一个用户,名为 postgres
"type": "shell",
"command": "sudo",
"args": [
"bash", "-c",
"if ! id postgres &>/dev/null; then sudo useradd -m -s /bin/bash postgres; fi"
],
"detail": "Create the postgres user and set up the necessary directories"
},
]
}

接着 ctrl + shift + p 打开 Command Palette ,选择运行任务:

alt text
alt text

然后直接选择我们刚刚配置好的任务运行即可:

alt text
alt text

上述三个方法选一即可,建立完用户后,我们可以看到 home 目录下多出了一个 postgres 目录。这是 postgres 用户的个人目录。创建完了用户,记得把我们的 PG 压缩包移动到用户目录,然后解压!

tar -xf postgresql-17.0.tar.gz

如下图:

alt text
alt text
alt text
alt text

2.4.2 使用 postgres 用户编译并初始化 pg#

这是我添加了注释和修改后的完整 tasks.json :

{
"tasks": [
{
"type": "shell",
"label": "install_depends", // 1、apt 安装编译所需依赖
"command": "apt-get update && sudo apt install -y gcc libsystemd-dev libxml2-dev libssl-dev libicu-dev zlib1g-dev libreadline-dev pkg-config bison flex gdb lldb python3 python2 python3-lldb-14", // 新增了gcc bison flex gdb lldb python 依赖
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Task install depends."
},
{
"type": "shell",
"label": "build_env", // 建立build和数据库数据存放目录
"command": "sudo",
"args": [
"bash", "-c",
"mkdir -p ${workspaceFolder}/build && mkdir -p ${workspaceFolder}/build/data && chown -R postgres:postgres /home/postgres"
],
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Task add folders."
},
{
"type": "shell",
"label": "build_config", // 生成构建配置,以 debug 模式构建
"command": "../configure",
"args": [
"--prefix=${workspaceFolder}/build",
"--with-icu",
"--with-openssl",
"--with-systemd",
"--with-libxml",
"--enable-debug",
"--enable-cassert",
"--enable-depend",
"CFLAGS= -ggdb -O0 -g3 -Wall -fno-omit-frame-pointer" // 新增 g3 参数,支持调试器
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task Build MakeFile."
},
{
"type": "shell",
"label": "make",
"command": "make",
"args": [
"-j12" // 使用12核构建、主机性能不足时会造成卡顿
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task build."
},
{
"type": "shell",
"label": "make_install", // 安装数据库, make install
"command": "make",
"args": [
"install"
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task install database."
},
// {
// "label": "setup_postgres_user", // 为 PG 新建一个用户,名为 postgres,赋予该用户 数据目录 的权限
// "type": "shell",
// "command": "sudo",
// "args": [
// "bash", "-c",
// "if ! id postgres &>/dev/null; then sudo useradd -m -s /bin/bash postgres && sudo chown -R postgres:postgres build/pgsql/data && sudo chmod -R 700 build/pgsql/data; else sudo chown -R postgres:postgres build/pgsql/data && sudo chmod -R 777 build/pgsql/data; fi"
// ],
// "detail": "Create the postgres user and set up the necessary directories"
// },
{
"label": "init_db", // 初始化 PG db 到当前目录的 pgsql/data 文件夹下
"type": "shell",
"command": "sudo",
"args": [
"-u", "postgres", // 指定以 postgres 用户执行,如果你已经有其它用户,可以直接将 postgres 替换为你的用户,以避免权限问题。如果修改了,还需要同步修改 setup_postgres_user 任务中的 postgres
"build/bin/initdb",
"-D", "build/data"
],
// "dependsOn": "setup_postgres_user",
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Initialize PostgreSQL database with initdb"
},
{
"type": "shell",
"label": "clean_db", // 5、卸载现在安装的本数据库,然后删除所有相关文件
"command": "make uninstall && make clean && rm -rf ../pgsql && rm -rf ../build",
"options": {
"cwd": "${workspaceFolder}/build"
},
"detail": "Task clean database."
},
{
"type": "shell",
"label": "build_db_conf", // 2、构建DB配置,包含了 build_env 和 build_config 两个子任务
"dependsOn": [
"build_env",
"build_config"
],
"dependsOrder": "sequence",
"detail": "Task add folders."
},
{
"type": "shell",
"label": "build_db", // 3、构建数据库,包含了 编译、安装、初始化、配置监听端口、配饰系统环境变量、启动数据库主程序 子任务
"dependsOn": [
"make",
"make_install",
"init_db",
"config_listen_port",
"add_env_to_postgres",
"start_or_restart_pg"
],
"dependsOrder": "sequence",
"detail": "Main task, build and start pg main program."
},
{
"type": "shell",
"label": "rebuild_db", // 4、重新构建数据库并重启
"dependsOn": [
"make",
"make_install",
"start_or_restart_pg"
],
"dependsOrder": "sequence",
"detail": "Task add folders."
},
{
"label": "switch_to_postgres",
"type": "shell",
"command": "sudo -u postgres bash -c 'echo Switched to postgres user.'",
"problemMatcher": []
},
{
"type": "shell",
"label": "config_listen_port", // 配置数据库监听端口为5432,配置并重启后生效,可以直接使用 psql 作为客户端程序连接数据库
"command": "echo -e '\n# start listening ,config by dingning\nlisten_addresses = 'localhost'\nport = 5432' | sudo tee -a postgresql.conf",
"options": {
"cwd": "${workspaceFolder}/build/data"
},
"detail": "Task config pg's listening port in data/postgresql.conf."
},
{
"type": "shell", // export postgres 用户的环境变量,使其可以直接使用 psql 而不是 /pgsql/bin.psql 连接数据库
"label": "export_sys_env",
"command": "sudo -u postgres sh -c 'export PATH=${workspaceFolder}/build/bin && export PGHOST=127.0.0.1 && export PGPORT=5432 && export LD_LIBRARY_PATH=${workspaceFolder}/build/lib'",
"options": {
"cwd": "${workspaceFolder}/build/data"
},
"detail": "Task config pg's system environment variable."
},
{
"type": "shell",
"label": "add_env_to_postgres", // 添加环境变量到 postgres 用户的启动脚本
"command": "sudo -u postgres bash -c \"echo -e '\\n# PostgreSQL environment variables\\nexport PATH=${workspaceFolder}/build/bin\\nexport PGHOST=127.0.0.1\\nexport PGPORT=5432\\nexport LD_LIBRARY_PATH=${workspaceFolder}/build/lib\\nexport PGHOME=${workspaceFolder}/build\\nexport PGDATA=${workspaceFolder}/build/data' >> ~/.bashrc && source ~/.bashrc\"",
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Add PostgreSQL environment variables to the postgres user's .bashrc file."
},
{
"type": "shell",
"label": "start_or_restart_pg", // 启动 pg,日志文件写入 ${workspaceFolder}/pgsql/data/postmaster.log, 如果已经启动则重启
"command": "sudo -u postgres sh -c 'build/bin/pg_ctl -D build/data -l ${workspaceFolder}/build/data/postmaster.log status > /dev/null 2>&1 && build/bin/pg_ctl -D build/data -l ${workspaceFolder}/build/data/postmaster.log restart || build/bin/pg_ctl -D build/data -l ${workspaceFolder}/build/data/postmaster.log start'",
"options": {
"cwd": "${workspaceFolder}"
},
"detail": "Start pg, if pg has been started, restart it."
}
],
"version": "2.0.0"
}

你只需要按照 1.3 的步骤打开我们刚刚在 postgres 用户下解压的 PG 源码文件夹作为根目录,然后按照 2.3 的教学创建 tasks.json 文件,最后使用上面的这个 tasks.json 覆盖默认的 tasks.json 模板,即可使用这份 tasks.json。

安装依赖、编译安装、初始化 PG 的流程为下面三个任务,依次执行即可:

install_depends # 一次性任务,第一次安装时执行一次即可
build_db_conf # 生成 pg 构建配置文件,主要设置 编译要求 debug ,无代码优化,安装目录。
build_db # 编译构建 pg ,初始化 pg 到数据目录 build/data ,注册可执行文件的路径到用户的环境变量中

值得说一下的是,我写的这份 tasks.json 基本全覆盖了从依赖安装到编译、启动、重启、卸载的全流程任务。

build_db 任务将初始化 pg 到 build/data 目录,并将相关的依赖变量添加到用户 postgres 的环境变量中

执行完 build_db 任务,你就可以通过 createdb test 创建 test 数据库,通过 psql test 直接连接到 test 数据库 了

如需重新安装,只需要执行 clean_db 任务然后重新执行 build_db_conf 和 build_db 即可。

2.4.3 验证是否完成安装#

执行完我们上述的 build_db 任务后,应当能够看到:

alt text
alt text

然后我们可以在命令行中直接尝试启动:

su - postgres
cd postgresql-17.0
pg_ctl -D pgsql/data -l logfile start

如下图,启动成功:

alt text
alt text

检查进程状态:

ps aux | grep postgres

alt text
alt text

新建测试数据库并连接:

createdb test
psql test

alt text
alt text

到这里,我们就完成了 pg 的编译和初始化,可以配置 debug 环境了!

3、调试#

我推荐使用 GDB 进行调试,原因是 WSL 上由 apt 安装的 GDB 和 LLDB 都有问题,我只找了 GDB 的解决方案。

3.1 新建并编辑 调试配置文件#

ctrl + shift + p ,然后选择 Debug: Open launch.json ,选择 lldb/gdb 。因为 PG 并没有使用 cmake ,所以我们直接选择 lldb/gdb 调试器即可:

alt text
alt text

然后使用下面的调试配置文件,推荐使用 GDB ,亲测 WSL 上直接使用 apt 安装的 lldb 也不能完成调试:

LLDB#

{
"version": "0.2.0",
"configurations": [
{
"name": "(CodeLLDB) Attach", // 需要使用 CodeLLDB 插件进行调试
"type": "lldb",
"request": "attach",
"program": "${workspaceFolder}/build/bin/postgres",
"pid": "${command:pickProcess}"
}
]
}

GDB#

{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 附加 pg", // 需要使用 ms-vscode.cpptools 插件进行调试
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/build/bin/postgres",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"preLaunchTask": "switch_to_postgres",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

3.2 安装调试器#

gdb#

从 apt 官方下载的 gdb 无法直接适配 WSL ,原因是 gdb 在读取程序内存区时使用了 /proc/PID/mem 文件,但 WSL1 和 WSL2 都不支持这种内存管理方式,如下图:

alt text
alt text

因此你需要额外下载安装 WSL 社区的修复版本 GDB:

cd /home/postgres
sudo apt remove gdb
sudo apt install libgmp-dev
wget https://ftp.gnu.org/gnu/gdb/gdb-13.1.tar.xz
tar -xf gdb-13.1.tar.xz
cd gdb-13.1/
./configure
make -j8
sudo make install

https://github.com/microsoft/WSL/issues/8516

调试#

alt text
alt text

这些程序是我们编译得到的可执行程序,我们可以通过 attach 进程的方式进行调试。

在调试之前,可以考虑将刚刚编译得到的 bin 程序目录使用下面的指令添加到 Linux 的环境变量中,这样可以直接使用这种格式的指令 psql 代替 postgresql-17.0 目录中使用 pgsql/bin/psql 指令。我已经在 task 的 build_db 任务里一键完成了环境变量的添加,如果你成功完成了 build_db 任务,那么这一步可以忽略。

export PATH=$PATH:/home/postgres/postgresql-17.0/pgsql/bin
export PGHOST=127.0.0.1
export PGPORT=5432

创建新数据库的程序是 pgsql/bin/createdb ,具体指令为:

pgsql/bin/createdb test

这样就创建了一个名为 test 的数据库,接着我们使用 psql 连接到数据库:

pgsql/bin/psql test
select pg_backend_pid();

如下图,我们使用 psql 连接到数据库后,调用 pg 的 select pg_backend_pid(); 函数查询到当前连接的 pg 后端程序的进程号:

alt text
alt text

然后我们可以通过 attach 进程的方法进行调试:

alt text
alt text

alt text
alt text

参考资料#

https://wiki.postgresql.org/wiki/So,_you_want_to_be_a_developer%3F http://www.postgres.cn/v2/news/viewone/1/459 https://blog.frognew.com/2023/11/install-postgresql-16-from-source-code.html https://github.com/microsoft/WSL/issues/8516

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

WSL配置PostgreSql开发环境
https://blog.2228472062.workers.dev/posts/postgresql/wsl配置postgresql开发环境/
作者
达令鹿
发布于
2026-05-16
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
达令鹿
Hello, I'm DarlingDeer.
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
11
分类
1
标签
3
总字数
31,864
运行时长
0
最后活动
0 天前
站点信息
构建平台
Cloudflare Workers
博客版本
Firefly v6.12.1
文章许可
CC BY-NC-SA 4.0

文章目录