目录
一、PostgreSQL特征
-
函数:通过函数,可以在数据库服务器端执行指令程序
-
索引:用户可以自定义索引方法,或使用内置的B树,哈希表与GiST索引
-
触发器:触发器是由SQL语句查询所触发的事件。如:一个INSERT语句可能触发一个检查数据完整性的触发器。触发器通常由insert或update语句触发
-
多版本并发控制:PostgreSQL使用多版本并发控制(MVCC,Multiversion concurrency control)系统进行并发控制,该系统向每一个用户提供了一个数据库的"快照",用户在事务内所作的每个修改,对于其他的用户都不可见,知道该事务成功提交
-
规则:规则(RULE)允许一个查询能被重写,通常用来实现对视图(VIEW)的操作,如插入(INSERT),更新(UPDATE),删除(DELETE)
-
数据类型:包括文本,任意精度的数值数组,json数据,枚举类型,xml数据等
-
全文检索:通过Tsearch2或OpenFTS,8.3版本中内嵌Tsearch2
-
NoSQL:JSON,JSONB,XML,HStore 原生支持,至 NoSQL 数据库的外部数据包装器
-
数据仓库:能平滑迁移至同属PostgreSQL生态的GreenPlum,DeepGreen,HAWK 等,使用 FDW 进行 ETL
二、PostgreSQL逻辑架构
| 逻辑架构 | POSTGRES | MYSQL |
|---|---|---|
| 实例 | 多进程 | 当进程多线程 |
| 数据库 | 一个实例下可以创建多个db,各个db下相互隔离 | 一个实例下可以创建多个db,同实例下各db可相互访问 |
| 模式 | 一个db下可创建多个schema,各个schema下可以互相访问 | 没有schema的概念,或者schema就等于db |
| 表/视图 | table、view | table、view |
| 行 | tuple | row |
| 表空间 | 默认表空间,自定义表空间 | 独立表空间,共享表空间 |
三、部署操作
(1)所有节点通用准备工作(三台机子都要执行)
1.关闭防火墙和 SELinux
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 临时关闭SELinux
setenforce 0
# 永久关闭SELinux(重启生效)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
2.安装编译依赖
yum install -y gcc gcc-c++ make zlib-devel readline-devel openssl-devel libxml2-devel libxslt-devel perl-ExtUtils-Embed
3.创建PostgreSQL用户与目录
# 创建用户
useradd -m -s /bin/bash postgres
# 设置密码(建议设置,按提示输入)
passwd postgres
# 创建安装目录和数据目录
mkdir -p /usr/local/pgsql13 # 安装目录
mkdir -p /data/pgdata13 # 数据目录
chown -R postgres:postgres /usr/local/pgsql13 /data/pgdata13
chmod 700 /data/pgdata13
4.源码编译安装PostgreSQL 13.4
# 上传安装包到 /usr/local 目录(也可自定义路径)
cd /usr/local
# 解压安装包
tar -zxvf postgresql-13.4.tar.gz
cd postgresql-13.4
# 配置编译参数(指定安装目录)
./configure --prefix=/usr/local/pgsql13
# 编译(-j 后跟CPU核心数,加快编译速度)
make -j 4
# 安装
make install
5.配置环境变量(postgres用户)
su - postgres
# 编辑环境变量文件
vim ~/.bash_profile
# 添加以下内容
export PGHOME=/usr/local/pgsql13
export PGDATA=/data/pgdata13
export PATH=$PGHOME/bin:$PATH
# 生效环境变量
source ~/.bash_profile
# 验证(输出版本号则正常)
psql --version
exit # 回到root用户
(2)主库配置
1.初始化数据库
su - postgres
# 初始化(指定UTF8编码)
initdb -D $PGDATA -E UTF8 --locale=en_US.UTF-8 -U postgres -W
# 注:-W 会提示设置postgres用户密码,务必记住
exit
2.修改主库配置文件
修改postgresql.conf
vim /data/pgdata13/postgresql.conf
# 修改以下关键参数(找到对应行,取消注释并修改)
listen_addresses = '*' # 允许所有IP访问
port = 5432 # 默认端口,可自定义
max_connections = 100 # 最大连接数,根据需求调整
wal_level = replica # 流复制必须的wal级别
max_wal_senders = 10 # 最大wal发送进程数(大于从库数量)
wal_keep_size = 16MB # 保留的wal日志大小,防止从库同步断连
wal_sender_timeout = 60s # wal发送超时时间
archive_mode = on # 开启归档(可选,增强数据恢复能力)
archive_command = 'cp %p /data/pgarchive/%f' # 归档命令(需先创建目录)
hot_standby = off # 主库关闭热备
创建归档目录(如果开启了归档)
mkdir -p /data/pgarchive
chown -R postgres:postgres /data/pgarchive
chmod 700 /data/pgarchive
修改pg_hba.conf(访问控制)
vim /data/pgdata13/pg_hba.conf
# 在文件末尾添加以下内容(允许从库访问、本地访问)
# 本地信任访问
local all all trust
# IPv4本地访问
host all all 127.0.0.1/32 trust
# 允许从库节点访问(流复制专用)
host replication repl 172.16.121.212/32 md5
host replication repl 172.16.121.64/32 md5
# 允许所有IP访问数据库(生产环境建议缩小范围)
host all all 0.0.0.0/0 md5
3.创建流复制专用用户
su - postgres
# 启动主库
pg_ctl start
# 登录数据库创建repl用户(用于从库同步)
psql -U postgres -d postgres
# 执行SQL(替换为你的密码,如Repl@123456)
CREATE ROLE repl REPLICATION LOGIN ENCRYPTED PASSWORD '你的repl密码';
\q # 退出
# 验证启动状态
pg_ctl status
exit
4.设置主库开机自启
# 创建systemd服务文件
vim /usr/lib/systemd/system/postgresql-13.service
# 添加以下内容
[Unit]
Description=PostgreSQL 13 database server
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGDATA=/data/pgdata13
ExecStart=/usr/local/pgsql13/bin/pg_ctl start -D ${PGDATA} -s -w -t 300
ExecStop=/usr/local/pgsql13/bin/pg_ctl stop -D ${PGDATA} -s -m fast
ExecReload=/usr/local/pgsql13/bin/pg_ctl reload -D ${PGDATA} -s
TimeoutSec=300
[Install]
WantedBy=multi-user.target
# 重新加载服务配置
systemctl daemon-reload
# 设置开机自启
systemctl enable postgresql-13
(3)从库配置
1.从库同步数据(基础备份)
su - postgres
# 删除空的data目录(避免冲突)
rm -rf $PGDATA/*
# 从主库拉取数据(替换为你的repl密码和主库IP)
pg_basebackup -h 172.16.120.188 -U repl -p 5432 -D $PGDATA -Fp -Xs -P -R -W
# 参数说明:
# -h:主库IP
# -U:流复制用户
# -D:目标数据目录
# -Fp:输出格式为plain+pg_wal
# -Xs:同步wal日志
# -P:显示进度
# -R:自动生成recovery.conf(PostgreSQL12+为standby.signal)
# -W:提示输入repl密码
exit
2.修改从库配置文件
修改postgresql.conf
vim /data/pgdata13/postgresql.conf
# 确保以下参数正确(主库已配置的基础上,补充/修改)
hot_standby = on # 从库开启热备(允许只读查询)
max_standby_streaming_delay = 30s # 流复制延迟最大值
wal_receiver_timeout = 60s # wal接收超时时间
hot_standby_feedback = on # 向主库反馈从库状态,避免主库清理未同步的wal
验证standby.signal文件(postgresql 12+)
pg_basebackup 的 -R 参数会自动生成 standby.signal 文件,验证是否存在:
ls /data/pgdata13/standby.signal
# 若不存在,手动创建:
touch /data/pgdata13/standby.signal
修改psotgresql.auto.conf(自动生成的同步配置)
vim /data/pgdata13/postgresql.auto.conf
# 确认以下内容存在(-R 参数自动生成,无需手动改)
primary_conninfo = 'user=repl password=你的repl密码 host=172.16.120.188 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
3.启动从库并设置开启自动
# 同主库步骤,创建systemd服务文件(已创建则跳过)
# 启动从库
su - postgres
pg_ctl start
# 验证状态
pg_ctl status
exit
# 设置开机自启(同主库)
systemctl enable postgresql-13
四、验证集群状态
1.主库验证
su - postgres
psql -U postgres -d postgres
# 查看流复制状态(能看到两个从库的信息则正常)
SELECT usename, application_name, client_addr, state FROM pg_stat_replication;
# 正常输出示例:
# usename | application_name | client_addr | state
# ---------+------------------+---------------+-----------
# repl | walreceiver | 172.16.121.212| streaming
# repl | walreceiver | 172.16.121.64 | streaming
\q
2.从库验证
su - postgres
psql -U postgres -d postgres
# 连接数据库,检查是否处于恢复(同步)状态
psql -U postgres -d postgres -c "SELECT pg_is_in_recovery();"
# 正常输出:pg_is_in_recovery
# ---------------
# t
# (1 row)
# "t"表示处于从库同步状态,正确。
# 查看同步详细信息(可选)
psql -U postgres -d postgres -c "SELECT * FROM pg_stat_wal_receiver;"
# 正常应看到"streaming"状态,主库IP正确
# 测试只读(从库执行建表会报错,符合预期)
CREATE TABLE test (id int);
# 报错:ERROR: cannot execute CREATE TABLE in a read-only transaction
\q

3.数据同步测试
# 在主库创建表并插入数据
su - postgres
psql -U postgres -d postgres
CREATE TABLE test_sync (id int, name varchar(20));
INSERT INTO test_sync VALUES (1, 'pg_cluster');
\q
# 在从库查询
su - postgres
psql -U postgres -d postgres
SELECT * FROM test_sync;
# 输出 (1, 'pg_cluster') 表示同步成功
\q

五、常见问题处理
1.主从连接失败:检查防火墙 / SELinux、pg_hba.conf 权限配置、repl 用户密码是否正确;
2.同步中断:检查主库 wal_keep_size 是否足够,从库 primary_conninfo 配置是否正确;
3.编译失败:确保依赖包全部安装,CentOS 8 需启用 PowerTools 仓库(dnf config-manager --set-enabled PowerTools)