postgresql源码编译安装(ubuntu)
源码编译安装是PG在linux上最常见的安装方式,可以灵活的选择版本并实现单机多版本或单机多实例部署。
源码包下载:https://www.postgresql.org/ftp/source/
本文安装的PG版本为postgres 17.7版本(不再建议使用PG 12之前的版本),源码安装时对操作系统版本没有强制要求,但是参考ubuntu 22.04 LTS系统自身的apt list postgres*我们可以看到其支持的默认版本为PG 14,而PG 18 apt安装文档显示支持的最低OS版本为ubuntu 22.04 LTS,因此建议至少使用ubuntu 22.04版本,这样可以确保编译安装依赖的包版本满足要求。
关于安装前的系统内核参数和ulimit资源限制,ubuntu 22.04 LTS上的默认配置已经"usually good enough",因此一般我们无需修改,如需要了解可以查看:https://www.postgresql.org/docs/17/kernel-resources.html
一、处理依赖
https://www.postgresql.org/docs/17/install-requirements.html
apt install build-essential pkg-config libicu-dev bison flex zlib1g-dev libreadline-dev libssl-dev liblz4-dev libzstd-dev uuid-dev
// 更多依赖可以根据./configure的报错或缺失信息进行安装
// 源码安装可以生成PG运行和运维所需的一切基础工具,因此卸载掉自带的pg包避免干扰,如有其他明显的PG包可以一并卸载
apt remove postgresql-client-common postgresql-common
二、编译安装
configure选项决定编译安装的PG支持的功能:https://www.postgresql.org/docs/17/install-make.html#CONFIGURE-OPTIONS
除非有特殊需求,一般以下options就可以满足生产需求,--prefix可以指定安装位置(默认位置为/usr/local/pgsql),此配置项在多版本安装时有用:
# 注意一般来说没必要添加--with-uuid=e2fs,我是因为历史原因有特殊的兼容需求才指定了--with-uuid=e2fs,PG本身的uuid机制能满足你的uuid需求。
./configure --prefix=/usr/local/pgsql -with-openssl --with-lz4 --with-zstd --with-uuid=e2fs
make && make install
# 安装官方扩展(可选)
cd contrib && make && make install
# 如make编译失败可使用make clean清空编译成果,重新执行上述make指令
# 如需重新./configure,则先make distclean清空编译成果+configure成果,仅清空make成果则make clean即可
# 直接make && make intall-world可能会出现doc目录编译失败,doc安装需要apt install额外的依赖,但doc本身没什么用,所以我选择去除doc安装,即:cd contrib && make && make install
三、设置环境变量
安装完毕后建议设置下环境变量确保使用顺畅:
vi /etc/profile
LD_LIBRARY_PATH=/usr/local/pgsql/lib
export LD_LIBRARY_PATH
PATH=$PATH:/usr/local/pgsql/bin
export PATH
# 验证环境变量是否生效
source /etc/profile
psql -V
四、创建postgres用户(必须)
上述操作使用root完成后,我们创建一个postgres用户用于具体的数据存放:
useradd postgres -d /home/postgres // 如已经存在则忽略
五、创建配置文件、数据目录、启动文件
在创建下述文件们之前,我们首先理清一个概念:pg cluster,官网明确说明pg cluster其实就是一个pg实例,因为可以包含多个database所以叫做cluster,这一概念与其他产品的cluster概念有区别,需要说明一下。
然后就是Debian/Ubuntu下apt安装的pg目前默认的启动方式依赖一个名为pg_ctlcluste的指令,此指令来源于postgresql-common包,它在启动PG时默认的配置文件寻址路径为/etc/postgresql/<version>/<clusterName>,因此这种方式启动的PG的其配置文件路径是有要求的,本文不遵循此约定因为我们不使用pg_ctlcluster而是直接使用postgres指定配置文件启动。
5.1 配置文件
源码编译安装不会自动生成配置文件,但我们可以参考apt安装产生的配置文件,主要有3个其他不管:pg_hba.conf、pg_ident.conf、postgresql.conf,分别用于用户网络权限管理、系统用户映射文件、PG核心配置文件。
我们的计划是进行单机多实例部署2个实例,分别是5432和5433端口,因此为每个实例创建配置文件目录用于存放上述2个配置文件:
mkdir -p /etc/postgresql/5432/conf.d
mkdir -p /etc/postgresql/5433/conf.d
chown -R postgres.postgres /etc/postgresql
注意:下述配置文件的权限应当是postgres!
pg_hba.conf:配置如下,本地只允许默认的postgres用户免密登录,其他一律走md5(密码)。
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host all all 0.0.0.0/0 md5
host all all ::0/0 md5
host replication repl 192.168.0.0/16 md5
# replication需要单独添加hba记录,将addr设置为你的生产网段即可
pg_ident.conf:置空即可。
postgresql.conf:PG核心配置文件(包含了流复制相关配置,之后可直接用于主从环境),篇幅所限只保留非默认以及重要的配置,配置详细说明参考apt安装自动生成的配置文件。
单机多实例部署时需要修改的只有FILE LOCATIONS部分和端口号。
#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
data_directory = '/data/postgresql/5432'
hba_file = '/etc/postgresql/5432/pg_hba.conf'
ident_file = '/etc/postgresql/5432/pg_ident.conf'
external_pid_file = '/var/run/postgresql/5432.pid'
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
listen_addresses = '*' # what IP address(es) to listen on;
port = 5432 # (change requires restart)
max_connections = 2000 # (change requires restart)
superuser_reserved_connections = 3 # (change requires restart)
unix_socket_directories = '/var/run/postgresql,/tmp'
ssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
#------------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#------------------------------------------------------------------------------
shared_buffers = 8GB # min 128kB
dynamic_shared_memory_type = posix
#------------------------------------------------------------------------------
# WRITE-AHEAD LOG
#------------------------------------------------------------------------------
wal_level = replica # minimal, replica, or logical
wal_compression = on # enable compression of full-page writes
max_wal_size = 1GB
min_wal_size = 80MB
#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
max_wal_senders = 10 # max number of walsender processes
hot_standby = on # "off" disallows queries during recovery
wal_keep_size = 8GB
archive_mode = on
archive_command = 'cp %p /data/postgresql/5432_arch/%f'
#------------------------------------------------------------------------------
# QUERY TUNING
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# REPORTING AND LOGGING
#------------------------------------------------------------------------------
log_directory = 'pg_log'
log_filename = 'postgresql-%a.log' # log file name pattern
log_truncate_on_rotation = on
log_rotation_age = 1d # Automatic rotation of logfiles will
# happen after that time. 0 disables.
log_line_prefix = '%m [%p] %q%u@%d '
log_timezone = 'Asia/Shanghai'
#------------------------------------------------------------------------------
# PROCESS TITLE
#------------------------------------------------------------------------------
cluster_name = '5432' # added to process titles if nonempty
#------------------------------------------------------------------------------
# STATISTICS
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#------------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS
#------------------------------------------------------------------------------
datestyle = 'iso, mdy'
timezone = 'Asia/Shanghai'
lc_messages = 'C.UTF-8' # locale for system error message
lc_monetary = 'C.UTF-8' # locale for monetary formatting
lc_numeric = 'C.UTF-8' # locale for number formatting
lc_time = 'C.UTF-8' # locale for time formatting
default_text_search_config = 'pg_catalog.english'
#------------------------------------------------------------------------------
# LOCK MANAGEMENT
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# VERSION AND PLATFORM COMPATIBILITY
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# ERROR HANDLING
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# CONFIG FILE INCLUDES
#------------------------------------------------------------------------------
include_dir = 'conf.d' # include files ending in '.conf' from
# a directory, e.g., 'conf.d'
#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
# Add settings for extensions here
5.2 数据目录
编辑好2个实例的配置文件后,我们根据配置文件中指定的位置创建目录:
mkdir -p /data/postgresql/5432
mkdir -p /data/postgresql/5433
mkdir -p /data/postgresql/5432_arch
mkdir -p /data/postgresql/5433_arch
chown -R postgres.postgres /data/postgresql
5.3 启动文件
使用systemd管理实例的启停,相同版本的多个实例可以共用一个service文件:vi /lib/systemd/system/postgresql@.service
[Unit]
Description=PostgreSQL Cluster %i
AssertPathExists=/etc/postgresql/%i/postgresql.conf
After=network.target
[Service]
Type=simple
User=postgres
Group=postgres
# pg_ctl只能实现在-D目录下自动寻找配置文件,无法实现配置文件、数据目录分离,因此我们启动时使用postgres指令+Type=simple启动,关闭时再用pg_ctl -D stop即可
ExecStart=/usr/local/pgsql/bin/postgres -c config_file=/etc/postgresql/%i/postgresql.conf
# reload一般不推荐,配置变更优先使用SQL:SELECT pg_reload_conf();
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/usr/local/pgsql/bin/pg_ctl stop -D /data/postgresql/%i -m fast
TimeoutSec=300
OOMScoreAdjust=-900
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
六、数据目录初始化
我们把所有的配置文件、启动文件等都准备好了,那么能直接systemctl启动服务了吗?还不行,我们需要先初始化一遍数据目录,生成基础的诸如系统库等对象(你非你是直接恢复全备,那么无需初始化)。
su - postgres -c "/usr/local/pgsql/bin/initdb -D /data/postgresql/5432"
七、启动服务
systemctl start postgresql@5432.service
systemctl start postgresql@5433.service
# 因为pg内置的默认管理员账户为postgres,而我们针对同名的系统用户postgres在hba文件中设置了peer,因此使用此系统账户可以直接走socket免密登录
# 注意这么做的前提:
# 1、pg_hba文件中设置了`local all postgres peer`, 表示与内置角色postgres同名的系统用户可以通过本地socket直接登录
# 2、socket .s.PGSQL.5432需要存在,如果不是默认目录,那么需要使用-h指定socket目录
su - postgres
$ psql -p 5432
psql (17.7)
Type "help" for help.
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/tmp" at port "5432".
默认postgres没有密码,只能使用本地socket登录,此时你可以设置/修改他的密码以便远程登录使用。
至此我们的单机双PG实例部署完毕,接下来可以考虑为这两个实例创建standby了。

浙公网安备 33010602011771号