1. 为什么我还在坚持源码编译安装PostgreSQL 12.0
先说一个很多刚入门的朋友会问的问题:明明Linux发行版自带的软件源里就有PostgreSQL,或者有Docker镜像可用,为什么还要折腾源码编译安装?我自己的答案是——这不是折腾,是对环境掌控力的要求。当你需要在离线网络环境、特定硬件平台、或者需要定制某些编译参数时,源码安装几乎是唯一可靠的选择。
PostgreSQL 12.0虽然不是最新版本,但在很多企业生产环境中依然是主力版本。这个版本引入了不少实质性改进,比如可重复读的vacuum性能优化、通用表达式(CTE)的增量排序,还有分区表的性能大幅提升。更重要的是,对于国产化替代、信创环境适配这些场景,很多组织都会指定在特定CPU架构和操作系统版本上部署PostgreSQL 12.x,这时候发行版自带的版本可能根本不是12.0,版本对不上,就只能源码编译。
还有一层考虑是安装路径的可控性。源码编译安装时,二进制文件、数据目录、配置文件、日志文件的存放位置都由你说了算,这对后续做备份脚本、监控采集、安全加固都非常重要。用发行版自带的安装方式,文件散落在系统各处,要改路径很麻烦。这篇文章我会完整走一遍PostgreSQL 12.0在Linux环境下的源码安装部署流程,其中包含我在实际项目实施中踩过的坑、补充的细节和调优思路,希望对你有实质性帮助。
2. 版本选择背后的现实考量
2.1 为什么是12.0而不是更新的版本
PostgreSQL的版本演进速度很快,截至目前新版本已经迭代了很多代。但选择12.0的原因往往不是“最新”而是“最合适”。首先,12.0是支持在线reindex的基准版本(在12.0之前在线reindex需要依赖第三方插件),这在生产库维护中相当实用。其次,12.0的分区表改进使得分区裁剪和分区聚合的计划生成效率显著提高,很多从老版本(如9.x、10.x)升级上来的系统,性能提升是肉眼可见的。
更重要的是,源码编译安装12.0在后期的大版本升级路径上是清晰且平滑的。官方文档明确指出从12.x可以借助pg_upgrade工具直接升级到更新的版本,比如14、15、16,升级路径经过大量验证,风险相对可控。相比之下,如果直接从10.x跳到16.x,升级跨度太大,很多行为变化集中爆发,排错的复杂度会成倍上升。
2.2 和二进制包安装的对比
有人会问,直接用apt install postgresql-12或者yum install postgresql12不就行了?确实,软件包管理器安装有它的优势,比如依赖自动处理、启动脚本自动生成。但它也存在明显的局限性:
- 版本依赖仓库维护状况:软件源里的版本往往是固定的,不一定有12.0这个小版本号,有时是12.7、12.15等,不是你想精确安装12.0就可以的。
- 目录结构不统一:不同的发行版对配置文件、数据目录的默认路径定义不同,在CentOS上是
/var/lib/pgsql/12/data,在Ubuntu上又是/var/lib/postgresql/12/main,这套路径换一个环境就要重新适应。 - 包含若干额外扩展包:很多时候需要的插件没有对应打包,比如PostGIS、TimescaleDB这些,用源码编译反而更容易自行处理。
源码编译安装的核心优势在于参数可定制、目录可定制、行为可预期。比如你可以通过configure参数决定是否启用--with-python、--with-perl、--with-icu、--with-ssl等特性,这些都是生产环境中真正需要的东西。下面进入正题,我先从环境准备开始讲。
3. 环境准备与依赖检查
3.1 编译环境的必备组件
开始之前,首先要确保Linux系统具备编译工具链。PostgreSQL 12.0使用C语言编写,编译过程依赖GCC、Make等工具。同时它还需要一些开发库,比如readline-devel(命令行历史功能)、zlib-devel(压缩支持)等。
我以CentOS 7.8 x86_64环境为例来说明,因为这套流程我跑过很多次,最有把握。如果你用的是Ubuntu/Debian系,把对应的包名替换成build-essential、libreadline-dev、zlib1g-dev即可。
# CentOS/RHEL系列 yum install -y gcc gcc-c++ make readline-devel zlib-devel libxml2-devel openssl-devel# Ubuntu/Debian系列 apt update apt install -y build-essential libreadline-dev zlib1g-dev libxml2-dev libssl-dev这里有个值得注意的点:openssl-devel或libssl-dev一定要装。如果不装,后续configure的时候--with-openssl选项就无法启用,远程连接走SSL加密通道的能力就缺失了。很多生产环境的合规检查里,这一条是硬性要求。如果你还计划在PostgreSQL里跑PL/Python、PL/Perl等过程语言,还需要额外装对应的开发包,比如python3-devel、perl-ExtUtils-Embed。
实际经验告诉我,缺依赖的时候最常见的情况是configure步骤直接报错退出。与其反复试错,不如先一次性装齐全。下面这张表是我整理的最小依赖清单:
| 组件 | 作用 | 缺失后果 |
|---|---|---|
| gcc、make | 编译核心工具 | 无法编译 |
| readline-devel | 命令行编辑和历史记录 | configure报错,psql体验差 |
| zlib-devel | 数据压缩支持 | pg_dump备份压缩不可用 |
| openssl-devel | SSL加密连接 | 无法启用SSL |
| libxml2-devel | XML数据类型支持 | configure无法启用libxml2 |
| python3-devel | PL/Python过程语言支持 | 无法启用Python扩展 |
3.2 创建一个专用的操作系统用户
PostgreSQL的官方安全规范是绝不允许以root用户运行数据库服务器。原因不复杂:如果数据库被攻击,攻击者能拿到root权限,整个系统就会沦陷;而以普通用户运行时,攻击者拿到的权限会被限制在一个普通用户范围内。这不是危言耸听,我见过不少因为用root启动数据库造成的安全问题。
groupadd postgres useradd -g postgres -m -s /bin/bash postgres passwd postgres创建好用户后,后续所有操作身份切换到postgres用户下进行。养成这个习惯,后面少很多麻烦。
3.3 确定安装目录与数据目录
目录规划这块,我建议在项目初始就定好规范。我常用的划分方式是:
- 软件安装目录:
/usr/local/pgsql12 - 数据目录:
/data/pgsql12/data - 日志目录:
/data/pgsql12/log
数据目录和数据文件独立挂载磁盘,是生产环境的常见做法。这样做的目的是避免系统盘被数据撑爆,同时也便于后续做磁盘扩容和备份策略。数据目录如果放在系统盘上,一旦系统盘IO性能受限,数据库性能也会跟着受影响。
创建目录并设置权限:
mkdir -p /usr/local/pgsql12 mkdir -p /data/pgsql12/data mkdir -p /data/pgsql12/log chown -R postgres:postgres /usr/local/pgsql12 chown -R postgres:postgres /data/pgsql12注意:这两个目录的所有者必须改成postgres用户,不然后续初始化数据库时因为权限不足会直接报could not open directory类似的错误。
4. 源码下载与编译安装全流程
4.1 获取源码包
PostgreSQL的官方下载地址是https://www.postgresql.org/ftp/source/v12.0/,这里能找到所有官方发布的版本源码。你也可以从国内镜像站下载,速度更快。源码包的文件名一般是postgresql-12.0.tar.gz。
cd /tmp wget https://ftp.postgresql.org/pub/source/v12.0/postgresql-12.0.tar.gz tar -zxvf postgresql-12.0.tar.gz cd postgresql-12.0这里提醒一点——下载后建议先做md5校验。官网页面会给每个源码包提供md5和sha256值,下载完用md5sum postgresql-12.0.tar.gz对比一下。虽然是开源软件,但防止下载损坏或者被篡改,这一步还是值得做的。
如果你在的服务器网络环境访问官方源速度极慢,可以考虑使用华为云、阿里云或者清华镜像站的PostgreSQL源码镜像。源码包的完整性校验方式是一样的。
4.2 configure参数的选择逻辑
进入解压后的源码目录,执行configure脚本。这是整个安装过程中最具定制性的一步。我的推荐参数如下:
./configure --prefix=/usr/local/pgsql12 \ --with-pgport=5432 \ --with-openssl \ --with-libxml \ --with-perl \ --with-python \ --with-icu \ --with-systemd逐个解释这几个参数的含义和选择理由:
--prefix=/usr/local/pgsql12:安装路径。所有二进制文件、库文件、头文件都会安装到这个目录下,后续卸载时只需删除该目录即可,干净利落。--with-pgport=5432:指定默认的数据库端口。PostgreSQL的默认端口就是5432,明确写出来是便于确认,也防止将来用默认配置时产生困惑。--with-openssl:启用SSL支持,远程传输时数据加密,这是安全基线要求。--with-libxml:启用XML数据类型的支持。虽然现在JSON用得多,但也保不齐有业务用到XML,有备无患。--with-perl和--with-python:启用PL/Perl和PL/Python过程语言支持。很多数据分析任务会用到PL/Python,在函数内部直接调用Python生态的库,这个能力在生产中价值不小。--with-icu:启用ICU(International Components for Unicode)国际化支持,对多语言排序、字符集处理更稳定,尤其处理中文排序时比默认的libc排序更符合预期。--with-systemd:支持systemd集成,这样后续可以把PostgreSQL注册为systemd服务,统一管理、开机自启都会很方便。
这里有个小陷阱,启用了--with-python后,configure会去检查Python的头文件和库文件是否存在,如果系统里只有Python 2.x而没有Python 3.x的开发包,或者装的是python3但缺少对应的python3-devel,都会在这里报错。我平时在CentOS 7环境会特意确认:yum install -y python3-devel。同时在configure前设置PYTHON=/usr/bin/python3,强制指定版本。
4.3 编译安装与常见错误处理
configure执行完成后,如果没有报错,就可以进入编译和安装环节了。这里我按并行编译执行,充分利用多核CPU优势:
make -j 4 make install-j 4的意思是启用4个编译任务并行执行。如果你的服务器CPU核数更多,可以适当调大这个数字,比如-j 8。如果内存资源紧张,并行任务太多可能导致内存耗尽,这时候降低并行数或者干脆不加-j参数。
编译安装过程中,我在不同机器上遇到频率最高的错误有这么几类:
- c compiler cannot create executables:基本可以断定是GCC没装好,比如装了
gcc但没有gcc-c++,或者系统里存在多个版本的GCC导致链接混乱。处理办法是重新检查编译工具链。 - readline library not found:缺失
readline-devel库,按上面环境准备阶段装好即可。 - could not find suitable Python development headers:缺少Python开发头文件。在CentOS上执行
yum install -y python3-devel,Ubuntu上执行apt install -y python3-dev。 - ICU library not found:缺少ICU开发包。CentOS执行
yum install -y libicu-devel,Ubuntu执行apt install -y libicu-dev。
编译完成后,make install会把所有文件复制到/usr/local/pgsql12目录下,这一步基本是一帆风顺的。安装完成后确认一下:
ls /usr/local/pgsql12/bin/能看到postgres、initdb、pg_ctl、psql这些可执行文件,基本就到位了。
5. 初始化数据目录与首次启动
5.1 环境变量配置
为了让postgres用户日常操作时不用总是输入完整路径,配置环境变量是必要的。编辑~/.bashrc文件:
vi /home/postgres/.bashrc追加以下内容:
export PGHOME=/usr/local/pgsql12 export PGDATA=/data/pgsql12/data export PATH=$PGHOME/bin:$PATH export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH执行source ~/.bashrc让配置立即生效。这里我多说一句为什么要单独设置PGDATA这个环境变量——PostgreSQL的很多工具(比如pg_ctl、pg_basebackup)在未显式指定数据目录时,会读取这个变量。提前设置好,后面不少命令省略了-D参数也不会找错路径。
5.2 initdb初始化数据库
初始化数据库这一步是最容易被新手搞砸的一步,因为一旦失败,后面的所有操作都无法继续。建议先明白这件事的原理:initdb的作用是创建一个基础的数据目录,其中包含系统表、默认数据库(postgres和template1)、配置文件模板(postgresql.conf、pg_hba.conf)等。它并不创建一个具体的业务数据库,先有个完整的基础架构。
此时必须切换到postgres用户操作:
su - postgres initdb -D /data/pgsql12/data --encoding=UTF8 --locale=en_US.UTF-8 --auth=trust参数解释:
-D:指定数据目录位置。--encoding=UTF8:设置默认数据库编码为UTF-8。除非你有非常特殊的理由,否则永远不要绕开UTF-8。在生产环境里因为编码不统一导致的乱码问题,排查起来让人极其崩溃。--locale=en_US.UTF-8:设置系统的locale,影响字符串排序规则和字符分类行为。这里要注意——Linux的locale设置会直接影响PostgreSQL的文本比较行为。如果你的操作系统没有安装这个locale,会报错,需要用localedef命令生成,或者改用--locale=C或--locale=C.UTF-8作为替代方案。--auth=trust:本地连接的认证方式设为trust(免密码)。这一项只是为了让首次启动测试更容易通过,后续生产环境配置中必须改成md5或scram-sha-256。
初始化成功的标志是看到类似Success. You can now start the database server using:这样的提示,并且data目录下出现了PG_VERSION文件、base/目录、global/目录等内容。
5.3 首次启动数据库并验证
启动方式一:使用pg_ctl
pg_ctl -D /data/pgsql12/data -l /data/pgsql12/log/pgsql.log start-l参数指定日志文件的路径。启动后可以通过以下命令验证进程是否存活:
ps -ef | grep postgres正常情况下你会看到多个进程,包括postgres主进程和一些辅助进程(checkpointer、background writer、walwriter等)。看到这些说明核心进程已经跑起来了。
然后尝试连接一下:
psql -U postgres -d postgres如果一切正常,你会进入psql的交互界面。首次启动还有一件重要的事——设置数据库超级用户的密码:
ALTER USER postgres WITH PASSWORD '你的强密码';校验之后退出:
\q到这里,一个最小可用的PostgreSQL 12.0实例已经跑起来了。但生产环境远远没结束,接下来要处理服务化管理、远程访问配置和日常运维工具的部署。
6. systemd服务化管理的落地配置
6.1 为什么需要服务化管理
默认的pg_ctl start方式启动数据库后,进程挂在当前会话下,一旦终端断开或服务器重启,数据库不会自动恢复。在开发环境勉强可以接受,但在生产环境这样搞很容易出事故。把PostgreSQL注册为systemd服务后,可以实现开机自启、崩溃自动拉起、统一日志管理、通过systemctl status postgresql随时查看状态,运维体验完全不同。
6.2 编写systemd unit文件
由于我们是源码编译安装,发行版不会自动携带对应的systemd服务文件,需要自己写一个。在/etc/systemd/system/postgresql-12.service文件中写入:
[Unit] Description=PostgreSQL 12.0 database server After=network.target [Service] Type=forking User=postgres Group=postgres Environment=PGDATA=/data/pgsql12/data ExecStart=/usr/local/pgsql12/bin/pg_ctl -D /data/pgsql12/data -l /data/pgsql12/log/pgsql.log start ExecStop=/usr/local/pgsql12/bin/pg_ctl -D /data/pgsql12/data stop ExecReload=/usr/local/pgsql12/bin/pg_ctl -D /data/pgsql12/data reload PIDFile=/data/pgsql12/data/postmaster.pid Restart=always RestartSec=10 TimeoutSec=300 [Install] WantedBy=multi-user.target这里有几个关键点:
Type=forking:表示启动命令在执行后会将进程转为后台守护进程,systemd会跟踪主进程的PID文件来判断服务是否启动成功。PostgreSQL正是这种工作模式,所以要这么配。PIDFile=/data/pgsql12/data/postmaster.pid:PostgreSQL在启动时会在数据目录下生成一个postmaster.pid文件,记录主进程PID。systemd根据这个文件判断服务的运行状态。Restart=always:如果数据库进程意外退出,10秒后自动拉起。这一项在无人值守的生产环境中极其重要,数据库崩了能自动恢复,而不是等到用户发现才处理。TimeoutSec=300:有些大实例在启动时需要较长时间进行恢复(比如崩溃恢复),默认的90秒超时时间经常不够,调大是踩过坑之后得出的经验。
配置好之后,依次执行:
systemctl daemon-reload systemctl enable postgresql-12 systemctl start postgresql-12 systemctl status postgresql-12需要注意的是,使用systemd管理后,不要再手动用pg_ctl start去启动数据库,否则systemd会认为状态异常,管理上会出现混乱。我在迁移到systemd管理时,会先pg_ctl stop停掉手动启动的实例,再统一走systemctl。
7. 远程访问配置与防火墙放行
7.1 postgresql.conf监听地址调整
默认情况下,PostgreSQL只监听本机回环地址(127.0.0.1),外部机器无法直接连接。要让其他机器通过网络访问数据库,需要修改配置文件。
编辑/data/pgsql12/data/postgresql.conf,找到并修改以下参数:
listen_addresses = '*' port = 5432将监听地址设为*表示监听所有网卡地址。如果只想让特定IP访问,可以写具体的IP地址,比如'192.168.1.10'。这里我建议出于安全考虑,优先明确指定内网IP,而不是简单放通全部网卡。
修改完配置后,重启数据库使配置生效:
systemctl restart postgresql-127.2 pg_hba.conf认证规则配置
PostgreSQL的访问控制体系是通过pg_hba.conf文件实现的,这个文件定义了哪些主机、哪些用户、访问哪些数据库、用哪种认证方式。默认配置里只有本地连接,远程连接需要追加规则。
编辑/data/pgsql12/data/pg_hba.conf,在文件末尾追加:
# 允许内网192.168.1.0/24网段的所有IP以scram-sha-256方式连接所有数据库 host all all 192.168.1.0/24 scram-sha-256 # 允许内网10.0.0.0/8网段的所有IP以scram-sha-256方式连接所有数据库 host all all 10.0.0.0/8 scram-sha-256认证方式我统一推荐scram-sha-256。这是目前PostgreSQL支持的最安全的密码认证协议,比旧的md5认证强度高得多。默认安装的PostgreSQL 12.0已经支持这种认证方式,不需要额外编译参数。
修改完pg_hba.conf后,执行以下命令使配置生效,无需重启:
systemctl reload postgresql-12reload和restart的区别在于,reload只是重新加载配置文件,不影响正在运行的会话,适合这个场景。对生产环境来说,能reload解决的问题就尽量不要重启。
7.3 防火墙与云安全组放行
远程连接失败的案例中,有相当高的比例是数据库配置本身没有问题,但系统防火墙阻断了端口。在CentOS 7上,默认的firewalld防火墙一般是开启的,需要放行5432端口:
firewall-cmd --permanent --add-port=5432/tcp firewall-cmd --reload如果你用的是云服务器,还要检查云服务商的安全组规则,在控制台里把5432端口的入方向流量放行。这个步骤在阿里云、腾讯云、华为云等平台上是独立于服务器系统的,很容易被忽略。
7.4 远程连接测试
在客户端机器上,用psql命令测试连接:
psql -h 192.168.1.100 -p 5432 -U postgres -d postgres输入正确的密码后能进入psql交互界面,说明远程连接已经打通。如果连接报错,常见情况我整理成下面的排查表:
| 报错信息 | 原因 | 解决办法 |
|---|---|---|
| Connection refused | 数据库未监听,或防火墙拦截 | 检查监听地址配置、防火墙规则 |
| No route to host | 网络不通或安全组未放行 | 检查网段、ping通性、云安全组规则 |
| password authentication failed | 密码错误或认证方式不对 | 重置密码,检查pg_hba.conf认证方式 |
| no pg_hba.conf entry for host | pg_hba.conf未放行该IP | 追加对应网段的访问规则 |
8. 基础运维命令与排错方法
8.1 psql常用操作和日常检查
数据库部署完成后,日常的巡检和运维操作是必不可少的。我把最常用的命令整理在这里,方便对照执行。
查看数据库列表、大小和连接数:
-- 查看所有数据库 \l -- 查看当前实例所有数据库占用空间 SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database; -- 查看当前连接信息 SELECT datname, usename, client_addr, state FROM pg_stat_activity;查看PostgreSQL运行参数和状态:
-- 查看关键配置参数 SHOW shared_buffers; SHOW max_connections; SHOW listen_addresses; -- 查看数据库启动时间 SELECT pg_postmaster_start_time();日常巡检时重点关注慢查询和长事务。慢查询可以用pg_stat_statements插件来跟踪,长事务可以通过pg_stat_activity中的xact_start字段判断。生产环境经常遇到的问题是某个应用连接一直挂着不提交事务,导致vacuum无法清理旧数据,表膨胀严重。出现这种迹象时,需要及时定位并处理。
8.2 日志管理要点
PostgreSQL的系统日志默认会写到后端日志文件里,我们前面已经在启动命令里指定了日志路径/data/pgsql12/log/pgsql.log。但在高负载生产环境中,单一切割的日志文件会越来越大,不便于排查问题。建议在postgresql.conf中配置日志轮转:
logging_collector = on log_directory = 'log' log_filename = 'postgresql-%a.log' log_truncate_on_rotation = on log_rotation_age = 1d log_rotation_size = 100MB按天生成日志文件,同时限制单个文件大小。这样日志管理起来清晰很多,后续接入集中式日志采集平台(比如ELK或Loki)也方便。
8.3 常见运行故障的排查思路
数据库运行中遇到故障时,我的排查顺序基本都是先看日志,再查资源,后用手工命令验证。
PostgreSQL日志文件里会记录所有错误信息,找到对应时间点的报错是最直接的方式。比如启动失败的日志里会明确告诉你数据目录权限错误、磁盘空间不足、端口被占用等具体原因。系统层面用df -h看磁盘空间,用free -h看内存,用top看CPU。PostgreSQL是对IO和内存都比较敏感的服务,磁盘满了会导致数据库直接罢工,这是线上最常见的事故原因之一。
举一个我实际遇到过的例子:某次数据库突然无法写入,应用侧报could not write to file "pg_wal/xlogtemp" No space left on device。查完df -h发现数据目录所在的磁盘没有满,但df -i显示inode已经耗尽。原因是一个脚本大量创建小文件但没有清理,把inode资源耗光了。这种情况下即使有剩余磁盘空间,数据库也无法创建新文件。后来处理办法是找出无用的小文件清理掉,对相关应用做了磁盘配额。
9. 安全加固与日常维护经验补充
9.1 不要忽略basic的加固措施
部署刚完成,很多人就会立刻投入业务开发,但安全加固这一步不能省。我通常按以下顺序进行加固:
首先,修改默认的超级用户密码,这个在前面已经提过,就不再重复。其次,创建业务专用账号,而不要让业务系统直接使用postgres超级用户连接数据库。最小权限原则是数据库安全管理的基本要求。创建业务账号的方式:
CREATE USER app_user WITH PASSWORD '安全的密码'; CREATE DATABASE app_db OWNER app_user;然后回收超级用户的远程登录权限。生产环境的PostgreSQL,postgres用户最好只留在本地(Unix socket)或者在受控的堡垒机上使用,远程连接一律用业务账号。对应在pg_hba.conf里可以这么配置:
# 本机socket连接,postgres用户可登录 local all postgres peer local all all scram-sha-256 # 远程仅允许业务账号连接 host all app_user 192.168.1.0/24 scram-sha-256 host all postgres 127.0.0.1/32 scram-sha-256这样配置后,远程就算想用postgres用户也连不上,整体安全等级会明显提高。
9.2 数据备份的核心思路
PostgreSQL的备份方案有很多种,最基本的是使用pg_dump进行逻辑备份:
pg_dump -U app_user -h localhost -d app_db -F c -f /backup/app_db_$(date +%Y%m%d).dump-F c指定自定义格式,这种格式可以使用pg_restore进行选择性恢复,灵活性高。配合crontab定期执行,可以形成基本的备份机制。
更高级的是基于WAL连续归档的PITR(时间点恢复)方案,这个能支持恢复到指定时间点,应对误操作场景非常关键。虽然在本文中不展开讲,但你要知道源码编译的PostgreSQL同样支持这些功能,相关归档参数(archive_mode、archive_command)在postgresql.conf中都能找到。
9.3 常见配置参数调优方向
刚部署完的PostgreSQL默认参数偏向保守,并不算最优。针对不同业务场景,以下几个参数值得根据机器实际规格调整:
shared_buffers:PostgreSQL自身的共享缓冲区大小,一般建议设为物理内存的25%左右。比如32GB内存的机器,可以设置约8GB。注意设得过大可能会导致操作系统换页,性能反而下降。work_mem:单个排序或哈希操作能使用的内存上限。这个值不是越大越好,因为它是每个查询每个排序操作都可能分配的,设置过大时并发高场景下内存容易被打满。maintenance_work_mem:VACUUM、创建索引等维护操作使用的内存,建议比work_mem设得大一些,有助于加快索引重建速度。effective_cache_size:操作系统文件缓存大小的估计值,一般设为物理内存的50%~75%。这个参数影响查询规划器对索引扫描和顺序扫描的决策倾向。
改动这些参数后,重启数据库才能全部生效(work_mem和effective_cache_size属于可以reload的参数,但shared_buffers必须重启)。调优没有万能公式,务必要结合你自己系统的负载测试结果来调节。
9.4 版本演进与后续升级提醒
如果你打算借这篇博文在自己的环境中落地PostgreSQL 12.0,我建议你在熟悉基本操作之后再加一个意识:PostgreSQL 12这个系列虽然是经典版本,但也会慢慢进入维护期的尾声。在用12.0完成学习和项目原型之后,要关注官方的安全公告和补丁更新,及时升级到12.x系列的最高小版本,甚至在条件允许的时机规划升到更高的主版本。
升级到更高版本时,pg_upgrade工具可以很大程度简化操作,但升级前一定要先做完整备份,并在测试环境走一遍流程,不要直接在生产环境动刀。我个人的习惯是无论多自信,正式升级前都至少演练两遍,一遍是纯命令流程验证,一遍是模拟真实数据量的压力演练。
最后再分享一个我自己的小习惯:每次部署完成后,把数据库的安装路径、数据目录、配置参数、初始化时间、采用的编译参数和当时踩过的坑都记录在一个本地文件里。等过几个月再回来看,这些信息往往帮大忙——定位问题、审计合规、交接给同事都靠它。
PostgreSQL 12.0在Linux下的源码安装部署,核心流程就是这样。你可能会在不同版本的Linux或者不同硬件架构上遇到一些细节差异,但大的框架和思路完全通用。按照这套流程走下来,一个稳定、安全、可控的PostgreSQL环境就落地了,后面就是按照业务需求逐步深入使用的阶段了。