暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PG14一主一从部署(pg_basebackup方式)

原创 董小姐 2024-09-09
490

官方文档摘录

连续存档可用于创建高可用性(HA)集群配置,其中一个或多个备用服务器可在主服务器出现故障时接管操作。这种能力通常被称为热备用或日志传送。

主服务器和备用服务器协同工作以提供此功能,尽管这两个服务器只是松散耦合的。主服务器以连续存档模式运行,而每个备用服务器以连续恢复模式运行,从主服务器阅读WAL文件。启用此功能不需要更改数据库表,因此与其他一些复制解决方案相比,它提供了较低的管理开销。此配置对主服务器的性能影响也相对较低。

将WAL记录从一个数据库服务器直接移动到另一个数据库服务器通常称为日志传送。PostgreSQL通过每次传输一个文件(WAL段)来实现基于文件的日志传送。WAL文件(16 MB)可以轻松、廉价地运送到任何距离,无论是相邻的系统、同一站点的另一个系统,还是地球仪另一端的另一个系统。此技术所需的带宽根据主服务器的事务速率而变化。基于记录的日志传送更精细,并且通过网络连接以增量方式流式传输WAL更改。

应当注意,日志传送是异步的,即,WAL记录在事务提交之后被传送。因此,如果主服务器发生灾难性故障,则存在数据丢失的窗口;尚未发送的事务将丢失。在基于文件的日志传送中,可以使用archive_timeout参数来限制数据丢失窗口的大小,该参数可以设置为几秒。然而,这样的低设置将大大增加文件传送所需的带宽。流式复制允许更小的数据丢失窗口。

创建主服务器和备用服务器,以便它们尽可能相似,至少从数据库服务器的角度来看是这样。特别是,与表空间关联的路径名将不加修改地传递,因此如果使用该特性,主服务器和备用服务器必须具有相同的表空间挂载路径。请记住,如果在主服务器上执行CREATE TABLESPACE,则必须在执行命令之前在主服务器和所有备用服务器上创建它所需的任何新挂载点。硬件不需要完全相同,但经验表明,在应用程序和系统的生命周期内,维护两个相同的系统要比维护两个不同的系统容易。在任何情况下,硬件架构必须是相同的,比如说,从32位到64位的系统是不起作用的。

一般来说,运行不同主要PostgreSQL版本的服务器之间的日志传送是不可能的。PostgreSQL全球开发组的政策是在次要版本升级期间不更改磁盘格式,因此在主服务器和备用服务器上运行不同的次要版本级别可能会成功。但是,没有提供正式的支持,建议您尽可能将主服务器和备用服务器保持在相同的版本级别。当更新到新的次要版本时,最安全的策略是首先更新备用服务器-新的次要版本更有可能从以前的次要版本读取WAL文件,反之亦然。

如果启动服务器时数据目录中存在standby.signal文件,则服务器进入待机模式。

在备用模式下,服务器持续应用从主服务器接收的WAL。备用服务器可以从WAL存档中读取WAL,也可以通过TCP连接直接从主服务器读取WAL(流式复制)。备用服务器还将尝试恢复在备用群集的pg_wal目录中找到的任何WAL。这通常发生在服务器重启之后,当备用服务器再次重放重启之前从主服务器流传输的WAL时,但您也可以随时手动将文件复制到pg_wal以重放它们。

启动时,备用服务器首先调用restore_command恢复存档位置中所有可用的WAL。一旦它到达那里可用的WAL的末尾并且restore_command失败,它将尝试恢复pg_wal目录中可用的任何WAL。如果失败,并且已经配置了流式复制,备用服务器将尝试连接到主服务器,并从archive或pg_wal中找到的最后一个有效记录开始流式WAL。如果此操作失败或未配置流式复制,或者连接后来断开,则备用服务器将返回步骤1,并尝试再次从存档中恢复文件。这种从存档、pg_wal和通过流复制的重试循环一直持续到服务器停止或升级。

当运行pg_ctl promote、调用pg_promote()或找到触发器文件(promote_trigger_file)时,退出待机模式,服务器切换到正常操作。在故障转移之前,归档文件或pg_wal中立即可用的任何WAL都将被恢复,但不会尝试连接到主服务器。

在主服务器上将连续存档设置为可从备用服务器访问的存档目录。即使在主服务器关闭时,也应该可以从备用服务器访问存档位置,即,它应该驻留在备用服务器本身或另一个受信任的服务器上,而不是主服务器上。

在主服务器上将连续存档设置为可从备用服务器访问的存档目录。即使在主服务器关闭时,也应该可以从备用服务器访问存档位置,即,它应该驻留在备用服务器本身或另一个受信任的服务器上,而不是主服务器上。

如果要使用流式复制,请在主服务器上设置身份验证,以允许从备用服务器进行复制连接;也就是说,创建一个角色并在pg_hba.conf中提供一个或多个合适的条目,并将数据库字段设置为复制。还要确保在主服务器的配置文件中将max_wal_maximum设置为足够大的值。如果将使用复制插槽,请确保max_replication_slots也设置得足够高。

执行基本备份的最简单方法是使用pg_basebackup工具。它可以将基本备份创建为常规文件或tar存档。如果需要比pg_basebackup提供的更大的灵活性,您还可以使用低级API进行基本备份。

不必担心进行基本备份所需的时间。但是,如果您在禁用full_page_writes的情况下正常运行服务器,则可能会注意到在备份运行时性能下降,因为在备份模式下实际上强制启用了full_page_writes

要使用备份,您需要保留在文件系统备份期间和之后生成的所有WAL段文件。为了帮助您执行此操作,基本备份过程创建一个备份历史文件,该文件立即存储到WAL存档区域中。此文件以文件系统备份所需的第一个WAL段文件命名。例如,如果起始WAL文件为0000000100001234000055CD,则备份历史文件将命名为类似 0000000100001234000055CD.007C9330.backup 的名称。(The文件名的第二部分代表WAL文件中的确切位置,通常可以忽略。一旦您安全地存档了文件系统备份和备份过程中使用的WAL段文件(如备份历史文件中所指定的),则恢复文件系统备份时不再需要名称在数字上较小的所有存档WAL段,并且可以将其删除。 但是,您应该考虑保留多个备份集,以绝对确保可以恢复数据。

备份历史文件只是一个小文本文件。它包含您提供给pg_basebackup的标签字符串,以及备份的开始和结束时间以及WAL段。如果您使用标签来标识关联的转储文件,则存档的历史文件足以告诉您要还原哪个转储文件。

由于您必须将所有存档的WAL文件保留到上次基本备份,因此基本备份之间的间隔通常应根据您希望在存档的WAL文件上花费多少存储空间来选择。如果有必要恢复,您还应该考虑准备花多长时间进行恢复-系统将不得不重播所有这些WAL段,如果距离上次基本备份已经过去很长时间,这可能需要一段时间。

PostgreSQL流复制默认是异步的。如果主服务器崩溃,则提交的某些事务可能尚未复制到备用服务器,从而导致数据丢失。数据丢失量与故障切换时的复制延迟成正比。

服务器规划

主机名

主机IP和端口

角色

PostgreSQL版本

操作系统

pgmaster

192.168.40.200 5432

主服务器

14.2

Centos7.9 x86_64

pgslave

192.168.40.201 5432

备服务器

14.2

Centos7.9 x86_64

操作系统配置

2个节点均操作。

环境准备需要使用root用户进行操作。本文档以CentOS7.9发行版操作系统为例,命令如下。如若是其他的linux发行版,准备工作这一块内容操作步骤是差不多的,linux命令需要调整。

前期准备

生产环境级别的数据库安装考虑的问题比较多,考虑的方面如下:

首先是安全问题,能不能用root安装?防火墙策略怎么设置?数据库打开文件以及连接数会不会超过linux默认打开文件句柄数的限制?

其次是合理规划,数据放在哪个目录?这个目录是否是全公司统一的?linux发行版不一样,软件安装目录是否一致?数据目录是否是单独挂载磁盘?单独挂载的磁盘是否做了RAID数据冗余或者LVM?

然后是运维方便的考虑,是否配置了合理的环境变量,如果不配置你是不是每次执行命令都要敲全路径?是否PostgreSQL具备开机自启动功能?

数据库用户是否经过合理规划,你的数据操作(增删改查)用户是否能新建表,truncat表,删除表?具备这些功能的数据操作用户是否会导致人为误操作风险增加?

数据库安装之后,是否具备企业级的统一管理、故障监控?流程上如何申请?

安装包下载

生产环境的postgresql安装一般会使用源码编译的方式进行安装,使用源码编译的安装方式有如下好处:

公司的服务器什么型号,什么操作系统版本的都有。如果使用yum或者apt-get安装,很难统一版本,不同的操作系统发行版带的postgreSQL源是不一样的。即使搞成统一的,不同的操作系统之间也无法统一安装目录的位置、lib存放位置等。

postgresql源码编译的方式进行安装,可以灵活的选择需要安装的版本,需要哪一个版本就下载哪一个版本。而使用yum或者apt-get进行安装只能源库指定的若干版本。源码安装,想指定什么目录就指定什么目录,全公司所有的PostgreSQL都在这个目录,这也是规范的一种。

所以为了适应更多的场景,为了达到公司内运维统一的标准,一般生产环境会使用postgresql源码编译的方式进行安装。

PostgreSql官方源码安装包的下载地址是:www.postgresql.org/download/

x86:

arm:

找到如上图所示的“file browser”,点击进入file browser页面,下载以“tar.gz”结尾的安装包即可。

目前单位用的有pg10和pg14两个版本,如下:

postgresql-10.22.tar.gz

postgresql-14.2.tar.gz

配置本地yum源

--上传操作系统镜像到/opt目录
[root@localhost ~]# ls -l /opt | grep Cen*
-rw-r--r--.  1 root root 4712300544 Aug  8 05:27 CentOS-7-x86_64-DVD-2009.iso
--挂载镜像
[root@localhost ~]# mount /opt/CentOS-7-x86_64-DVD-2009.iso /mnt/
[root@localhost ~]# df -h | grep mnt
/dev/loop0      4.4G  4.4G     0 100% /mnt
--设置开机挂载
cat << EOF >> /etc/fstab
/dev/loop0    /mnt        iso9660 loop            0 0
EOF
--配置本地yum源文件
mkdir -p /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
cat >> /etc/yum.repos.d/os.repo <<"EOF"
[OS1]
name=OS
baseurl=file:///mnt
enabled=1
gpgcheck=0
EOF

安装依赖包

首先需要安装一些必要的依赖,PostgreSQL安装的过程需要使用到这些linux包。

yum install -y zlib zlib-devel libaio cmake make gcc gcc-c++ readline readline-devel perl \
bison flex libyaml  net-tools expect  openssh-clients tcl openssl  openssl-devel \
ncurses-devel  python python-devel openldap pam systemtap-sdt-devel perl-ExtUtils-Embed \
libxml2 libxml2-devel libxslt libxslt-devel lz4 uuid  uuid-devel

如果显示无可用的lz4 uuid uuid-devel,执行3.1.3.步骤

安装uuid和lz4的组件(可选)

分别上传📎lz4-1.8.3-1.el7.x86_64.rpm📎uuid-1.6.2-26.el7.x86_64.rpm📎uuid-devel-1.6.2-26.el7.x86_64.rpm至/opt目录下

su - root
cd /opt
#归档压缩需要的lz4组件(必须)
rpm -ivh lz4-1.8.3-1.el7.x86_64.rpm

#PG库uuid函数依赖的组件(可选,需要用到uuid函数安装,不然跳过)
rpm -ivh uuid-1.6.2-26.el7.x86_64.rpm
rpm -ivh uuid-devel-1.6.2-26.el7.x86_64.rpm

设置主机名

--节点1 主库
hostnamectl set-hostname pgmaster
exec bash

--节点2 备库
hostnamectl set-hostname pgslave
exec bash

创建postgre用户

groupadd -g 5001 postgres
useradd -G postgres -g 5001 postgres
echo "postgres"|passwd --stdin  postgres

--修改操作系统用户postgres用户永不过期
chage -M 99999 postgres

关闭防火墙

禁用和启用二选一

--禁用防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service 
--启用防火墙
firewall-cmd --zone=public --add-port=5432/tcp --permanent
firewall-cmd --zone=public --add-port=22/tcp --permanent
firewall-cmd --reload
--禁用防火墙区域偏移
sed -i 's/^AllowZoneDrifting=yes/AllowZoneDrifting=no/' /etc/firewalld/firewalld.conf 

关闭selinux

sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
setenforce 0 

修改操作系统打开最大文件句柄数

cat >> /etc/security/limits.conf << "EOF"
#add by postgres
postgres    soft    nproc    65536
postgres    hard    nproc    65536
postgres    soft    nofile   65536
postgres    hard    nofile   65536
postgres    soft    stack    1024000
postgres    hard    stack    1024000
EOF

该配置在关闭linux访问终端session重新登录之后生效,ulimit -n的值会变成65535 。进行这一步操作的目的是防止linux操作系统内打开文件句柄数量的限制,避免不必要的故障。

修改磁盘调度(可选)

视情况更改sda

--查看磁盘
df -h 

--修改磁盘调度
echo deadline > /sys/block/sda/queue/scheduler

修改磁盘预读(可选)

视情况更改sda

/sbin/blockdev --setra 8192 /dev/sda

查看磁盘预读(可选)

视情况更改sda

/sbin/blockdev --getra  /dev/sda

设置系统内核参数

cp /etc/sysctl.conf /etc/sysctl.confbak
cat >> /etc/sysctl.conf <<EOF
#add by postgres
#关闭sysrq功能
kernel.sysrq = 0
#关闭路由转发
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
#处理无源路由的包
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# 确保无人能修改路由表
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
#关闭ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
#内核放弃建立连接之前发送SYN 包的数量
net.ipv4.tcp_syn_retries = 2
#内核放弃建立连接之前发送SYNACK 包的数量
net.ipv4.tcp_synack_retries = 2
#当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 5
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_max_tw_buckets = 6000
#启用timewait 快速回收
net.ipv4.tcp_tw_recycle = 1
#开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 10
# 开启SYN洪水攻击保护
net.ipv4.tcp_syncookies = 1
#限制仅仅是为了防止简单的DoS 攻击
net.ipv4.tcp_max_orphans = 3276800
#未收到客户端确认信息的连接请求的最大值
net.ipv4.tcp_max_syn_backlog = 16384
#限制仅仅是为了防止简单的DoS 攻击
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
fs.file-max = 1024000
#允许系统打开的端口范围
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.route.gc_timeout = 100
#系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128
net.core.somaxconn=1024
#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 262144
EOF

关闭 numa和禁用透明大页

sed -i "s/quiet/quiet numa=off transparent_hugepage=never/g"  /etc/default/grub 
grub2-mkconfig -o /etc/grub2.cfg

关闭进程间通信

#CentOS openEuler操作系统默认为关闭,可以跳过该步骤
sed -i 's/#RemoveIPC=no/RemoveIPC=no/g' /etc/systemd/logind.conf
systemctl daemon-reload
systemctl restart systemd-logind

创建必要的目录

--安装目录(该后面解压步骤生成不用手动创建)
/pgdb/pgsql
--数据目录
/pgdb/data
--归档目录
/pgdb/pg_archive
--备份目录
/pgdb/pg_backup
--临时目录(用于存放导入导出文件)
/pgdb/tmp
--脚本目录
/pgdb/scripts

mkdir -p /pgdb/{data,pg_archive,pg_backup,scripts,tmp}

生产环境建议,postgresql安装和数据存放目录是服务器单独挂载的一块磁盘,。这样做的好处:一是方便数据备份(硬件层面或软件层面),二是操作系统出现的问题,不影响数据安全。

上传并解压安装介质

--上传安装介质至/opt
[root@localhost opt]# ls -l /opt | grep pos*
-rw-r--r--. 1 root root   28794023 Aug 19 14:03 postgresql-14.2.tar.gz
--解压
[root@localhost opt]# tar -zxf /opt/post*.gz -C /pgdb
[root@localhost opt]# mv /pgdb/post* /pgdb/pgsql
[root@localhost opt]# chown -R postgres:postgres /pgdb

主节点部署PG库

编译安装

su - postgres
cd /pgdb/pgsql

./configure --prefix=/pgdb/pgsql --with-uuid=ossp
或
./configure --prefix=/pgdb/pgsql --with-pgport=5432 --with-openssl --with-perl \
--with-python --with-blocksize=128 --with-wal-blocksize=128 --with-wal-segsize=100 \
--with-readline --with-libxml --with-libxslt --with-uuid=ossp

gmake world -j2
gmake install-world -j2
--with-blocksize  设置块尺寸,以 K 字节计。这是表内存储和I/O的单位。默认值(8K字节)适合于大多数情况,但是在特殊情况下可能其他值更有用。这个值必须是2的幂并且在 1 和 32 (K字节)之间。注意修改这个值需要一次 initdb。
--with-wal-blocksize=128  设置WAL 块尺寸,以 K 字节计。这是 WAL 日志存储和I/O的单位。默认值(8K 字节)适合于大多数情况,但是在特殊情况下其他值更好有用。这个值必须是2的幂并且在 1 到 64(K字节)之间。注意修改这个值需要一次 initdb。
--with-wal-segsize=100
--with-perl --with-python:使用Perl和Python语法的过程语言来编写自定义函数。

gmake一次性将文档及附加模块全部进行编译和安装,保证所有数据库软件的一致性,避免给后期维护操作带来麻烦

补充:查下参数

--当前块大小blocksize  对应--with-blocksize
postgres=# SELECT current_setting('block_size');
 current_setting 
-----------------
 8192
(1 row)

--当前wal-blocksize   对应 --with-wal-segsize
postgres=# SELECT current_setting('wal_segment_size');
 current_setting 
-----------------
 16MB
(1 row)

--当前wal-segsize  对应 --with-wal-blocksize
postgres=# SELECT current_setting('wal_block_size');
 current_setting 
-----------------
 8192
(1 row)

配置环境变量

记得更改export PGHOST后面的ip地址为备库的

cp /home/postgres/.bash_profile  /home/postgres/.bash_profilebak
echo "##postgres user env configuration" >> /home/postgres/.bash_profile
sed -i 's/^export PATH/#export PATH/'  /home/postgres/.bash_profile
echo "#add by postgres" >>  /home/postgres/.bash_profile
echo 'export PGHOME=/pgdb/pgsql' >>  /home/postgres/.bash_profile
echo 'export PGDATA=/pgdb/data' >>  /home/postgres/.bash_profile
echo 'export PGHOST=192.168.40.201' >>  /home/postgres/.bash_profile
echo 'export PGPORT=5432' >>  /home/postgres/.bash_profile
echo 'export PGDATABASE=postgres' >>  /home/postgres/.bash_profile
echo 'export PGUSER=postgres' >>  /home/postgres/.bash_profile
echo 'export PGPASSWORD=postgres' >>  /home/postgres/.bash_profile
echo 'export PATH=$PGHOME/bin:$PATH' >>  /home/postgres/.bash_profile
echo 'export MANPATH=$PGHOME/share/man:$MANPATH' >>  /home/postgres/.bash_profile
echo 'export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH' >>  /home/postgres/.bash_profile
echo 'export LANG="en_US.UTF-8"' >>  /home/postgres/.bash_profile
echo 'export DATE=`date +"%Y%m%d%H%M"`' >>  /home/postgres/.bash_profile
source /home/postgres/.bash_profile	

数据库初始化

su - postgres
echo "postgres" > /home/postgres/.pgpass
chmod 0600 /home/postgres/.pgpass
/pgdb/pgsql/bin/initdb  --username=postgres --pwfile=/home/postgres/.pgpass \
-D /pgdb/data \
--encoding=UTF8 \
--lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8

参数说明:
--lc-collate: 字符串排序的顺序
--lc-ctype:字符分类

配置文件:

位置:数据目录PGDATA目录

/pgdb/data/postgresql.conf --数据库参数

/pgdb/data/pg_hba.conf --用户访问权限文件

参数配置

数据库参数配置

启用归档需将wal_level配置参数设置为replica或更高,archive_mode设置为on,并在archive_command配置参数中指定要使用的shell命令

--更改配置文件
cp /pgdb/data/postgresql.conf /pgdb/data/postgresql.confbak
cat >> /pgdb/data/postgresql.conf   << "EOF"
listen_addresses = '*'
port = 5432
max_connections = 1000   #max_connections*work_mem 上千个连接,建议配置连接池
superuser_reserved_connections=10  #为超级用户保留的连接数
#开启归档
archive_mode = on
archive_command ='test ! -f /pgdb/pg_archive/%f && cp %p /pgdb/pg_archive/%f'
#保留 7 天的日志  日志大于1G生成新文件
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-.%a.log'
log_truncate_on_rotation = on
log_rotation_age = 1440
log_rotation_size = 1GB
#内存参数
shared_buffers = 1024MB  #物理内存1/4,小于1/2
effective_cache_size = 3GB  #查询优化器可用的OS CACHE实际不占用内存 物理内存1/3~1/2
work_mem = 30MB #在写入临时磁盘文件之前查询操作(例如排序或哈希表)可使用的最大内存容量  # max(min(规格内存/4096, 64MB), 4MB)
maintenance_work_mem = 256MB # min( 8G, (主机内存*1/8)/max_parallel_maintenance_workers )
temp_buffers = 256MB 
vacuum_cost_limit = 500  #清理delete后的空间,此时对io影响较大,增加该值可以缩小对性能的影响
max_parallel_maintenance_workers = 1    #CPU核数/4 
max_parallel_workers_per_gather = 1     #CPU核数/4  每个执行节点的最大并行处理过程数,应用并行查询时设置该值大于1,不建议超过主机cores-2 
max_parallel_workers = 4     #CPU核数 
max_worker_processes = 4    #CPU核数 
min_wal_size = 1GB      #建议值shared_buffers/2
max_wal_size = 2GB    #该值越小,wal日志写入量越大,wal日志恢复时间越长
checkpoint_timeout = 1min 
checkpoint_completion_target = 0.9  #去掉注释
#流复制参数
max_wal_senders = 10
wal_level = replica
EOF

# 数据库能够接受的最大请求连接并发数

max_connections = 100

# 数据库服务器将使用的共享内存缓冲区量。建议值:数据库独立服务器的1/4内存。

shared_buffers =1GB

补充:

PgSQL 的 WAL(Write-Ahead Logging)机制用于保证数据库的数据一致性和持久性。wal_level 用于指定 WAL 日志的详细程度和记录内容。

minimal:最小日志记录级别,只记录 WAL 日志中必需的信息,例如事务开始和结束等。这种设置适合对 WAL 日志大小有较高要求但是对数据恢复速度要求不高的场景。

replica:复制级别,除了记录 minimal 级别的日志信息外,还会记录所有对数据进行更改的操作,包括 DDL 和 DML 语句。这种设置适合在主备复制场景中使用,能够保证备库能够与主库保持一致。

logical:逻辑复制级别,除了记录 replica 级别的日志信息外,还会记录逻辑复制相关的信息,例如逻辑复制流所需的元数据。这种设置适合在逻辑备份、数据同步等场景中使用。

用户访问权限配置

cp /pgdb/data/pg_hba.conf  /pgdb/data/pg_hba.conf_bak
cat >> /pgdb/data/pg_hba.conf  << "EOF"
#配置远程访问
host      all             all             0.0.0.0/0                 md5
EOF

内容即用于远程访问,指定了可以访问postgreSql数据库的远程用户的ip范围, 0.0.0.0/0 表示所有ip都可以。如果你希望指定ip段,可以像这样去配置192.168.3.1/24(表示的ip范围是:192.168.3.1到192.168.3.255)。md5表示数据库访问密码使用md5的加密方式发送。

启停数据库

--启动命令
pg_ctl start -D /pgdb/data
--重启命令
pg_ctl restart  -D /pgdb/data
--查看数据库运行状态
pg_ctl status  -D /pgdb/data
--停止数据库
pg_ctl stop  -D /pgdb/data

验证归档正常

--手动切归档验证归档文件生成正常
/pgdb/pgsql/bin/psql -Upostgres -W -d postgres -h127.0.0.1 -p5432 -c "select pg_switch_wal();"

创建数据库和用户(可选)

--初始化postgres用户密码
alter user postgres with password '你设置的密码';
--创建新用户
create user top_sjjs with encrypted password 'top_sjjs';
alter user top_sjjs with superuser;
--创建数据库
create database mix_db owner top_sjjs;
grant all privileges on database mix_db to top_sjjs;
grant all privileges on all tables in schema public to top_sjjs; --(可选)
--创建程序用户,用于操作数据库表里面的数据,完成增删改查
create user top_sjjs with encrypted password 'top_sjjs';
GRANT  update,delete,insert,select  ON  ALL TABLES IN SCHEMA public TO top_sjjs;

开机自启动

为了让PostgreSQL在以后每次服务器重启之后,都能够自动启动,写一个自启动配置文件。下面的命令需要使用root用户执行

cat > /usr/lib/systemd/system/postgres.service << "EOF"
[Unit]
Description=PostgreSQL database server
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGPORT=5432
Environment=PGDATA=/pgdb/data
OOMScoreAdjust=-1000
ExecStart=/pgdb/pgsql/bin/pg_ctl start -D $PGDATA
ExecStop=/pgdb/pgsql/pg_ctl stop -D $PGDATA -s -m fast
ExecReload=/pgdb/pgsql/bin/pg_ctl reload -D $PGDATA -s
TimeoutSec=300
[Install]
WantedBy=multi-user.target
EOF
chmod +x /usr/lib/systemd/system/postgres.service
systemctl daemon-reload
systemctl start postgres.service
systemctl enable postgres.service
ps -ef | grep postgres

安装uuid-ossp(可选)

我单位项目有用到uuid-ossp扩展,若你的项目上用不到,该步骤可忽略。

检查是否已安装扩展uuid-ossp

select * from pg_extension;
或
\dx

--输出结果如下:
postgres=# \dx
                 List of installed extensions
  Name   | Version |   Schema   |         Description          
---------+---------+------------+------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
(1 row)

postgres=# select * from pg_extension;
  oid  | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition 
-------+---------+----------+--------------+----------------+------------+-----------+--------------
 13876 | plpgsql |       10 |           11 | f              | 1.0        |           | 
(1 row)

可以看到postgresql目前没有安装uuid-ossp扩展。

检查是否有可用来安装的扩展uuid-ossp

--查看当前可用的扩展
postgres=# select * from pg_available_extensions;
        name        | default_version | installed_version |                                comment                                 
--------------------+-----------------+-------------------+------------------------------------------------------------------------
 plpgsql            | 1.0             | 1.0               | PL/pgSQL procedural language
 plperl             | 1.0             |                   | PL/Perl procedural language
 plperlu            | 1.0             |                   | PL/PerlU untrusted procedural language
 plpython2u         | 1.0             |                   | PL/Python2U untrusted procedural language
 plpythonu          | 1.0             |                   | PL/PythonU untrusted procedural language
 adminpack          | 2.1             |                   | administrative functions for PostgreSQL
 amcheck            | 1.3             |                   | functions for verifying relation integrity
 bloom              | 1.0             |                   | bloom access method - signature file based index
 btree_gin          | 1.3             |                   | support for indexing common datatypes in GIN
 btree_gist         | 1.6             |                   | support for indexing common datatypes in GiST
 citext             | 1.6             |                   | data type for case-insensitive character strings
 cube               | 1.5             |                   | data type for multidimensional cubes
 dblink             | 1.2             |                   | connect to other PostgreSQL databases from within a database
 dict_int           | 1.0             |                   | text search dictionary template for integers
 dict_xsyn          | 1.0             |                   | text search dictionary template for extended synonym processing
 earthdistance      | 1.1             |                   | calculate great-circle distances on the surface of the Earth
 file_fdw           | 1.0             |                   | foreign-data wrapper for flat file access
 fuzzystrmatch      | 1.1             |                   | determine similarities and distance between strings
 hstore             | 1.8             |                   | data type for storing sets of (key, value) pairs
 intagg             | 1.1             |                   | integer aggregator and enumerator (obsolete)
 intarray           | 1.5             |                   | functions, operators, and index support for 1-D arrays of integers
 isn                | 1.2             |                   | data types for international product numbering standards
 lo                 | 1.1             |                   | Large Object maintenance
 ltree              | 1.2             |                   | data type for hierarchical tree-like structures
 old_snapshot       | 1.0             |                   | utilities in support of old_snapshot_threshold
 pageinspect        | 1.9             |                   | inspect the contents of database pages at a low level
 pg_buffercache     | 1.3             |                   | examine the shared buffer cache
 pg_freespacemap    | 1.2             |                   | examine the free space map (FSM)
 seg                | 1.4             |                   | data type for representing line segments or floating-point intervals
 pg_prewarm         | 1.2             |                   | prewarm relation data
 pg_stat_statements | 1.9             |                   | track planning and execution statistics of all SQL statements executed
 pg_surgery         | 1.0             |                   | extension to perform surgery on a damaged relation
 pg_trgm            | 1.6             |                   | text similarity measurement and index searching based on trigrams
 pgcrypto           | 1.3             |                   | cryptographic functions
 pgrowlocks         | 1.2             |                   | show row-level locking information
 pgstattuple        | 1.5             |                   | show tuple-level statistics
 pg_visibility      | 1.2             |                   | examine the visibility map (VM) and page-level visibility info
 postgres_fdw       | 1.1             |                   | foreign-data wrapper for remote PostgreSQL servers
 autoinc            | 1.0             |                   | functions for autoincrementing fields
 insert_username    | 1.0             |                   | functions for tracking who changed a table
 moddatetime        | 1.0             |                   | functions for tracking last modification time
 refint             | 1.0             |                   | functions for implementing referential integrity (obsolete)
 tablefunc          | 1.0             |                   | functions that manipulate whole tables, including crosstab
 tcn                | 1.0             |                   | Triggered change notifications
 tsm_system_rows    | 1.0             |                   | TABLESAMPLE method which accepts number of rows as a limit
 tsm_system_time    | 1.0             |                   | TABLESAMPLE method which accepts time in milliseconds as a limit
 unaccent           | 1.1             |                   | text search dictionary that removes accents
 sslinfo            | 1.2             |                   | information about SSL certificates
 xml2               | 1.1             |                   | XPath querying and XSLT
 bool_plperlu       | 1.0             |                   | transform between bool and plperlu
 bool_plperl        | 1.0             |                   | transform between bool and plperl
 hstore_plperl      | 1.0             |                   | transform between hstore and plperl
 hstore_plperlu     | 1.0             |                   | transform between hstore and plperlu
 jsonb_plperlu      | 1.0             |                   | transform between jsonb and plperlu
 jsonb_plperl       | 1.0             |                   | transform between jsonb and plperl
 hstore_plpythonu   | 1.0             |                   | transform between hstore and plpythonu
 hstore_plpython2u  | 1.0             |                   | transform between hstore and plpython2u
 hstore_plpython3u  | 1.0             |                   | transform between hstore and plpython3u
 jsonb_plpythonu    | 1.0             |                   | transform between jsonb and plpythonu
 jsonb_plpython2u   | 1.0             |                   | transform between jsonb and plpython2u
 jsonb_plpython3u   | 1.0             |                   | transform between jsonb and plpython3u
 ltree_plpythonu    | 1.0             |                   | transform between ltree and plpythonu
 ltree_plpython2u   | 1.0             |                   | transform between ltree and plpython2u
 ltree_plpython3u   | 1.0             |                   | transform between ltree and plpython3u
(64 rows)

可以看到postgres目前并没有可用的uuid-ossp扩展。

此时,直接创建uuid-ossp会报错,如:

postgres=# create extension "uuid-ossp";
ERROR:  could not open extension control file "/data/pgdb/pgsql/share/extension/uuid-ossp.control": No such file or directory
postgres=# 

注意:
要用双引号将uuid-ossp引起来,因为有个中划线“-”。

PG源码文件下编译安装扩展

安装uuid依赖包

uuid官网OSSP: OSSP uuid

安装uuid有2种方式,视情况选择适合自己的场景。

方式1:rpm方式安装uuid

不联网场景下, uuid-devel需下载上传安装,iso中没有

uuid-devel-1.6.2-26.el7.x86_64.rpm 下载地址:http://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/uuid-devel-1.6.2-26.el7.x86_64.rpm

su - root
yum -y install e2fsprogs-devel uuid uuid-devel libuuid-devel
rpm -ivh uuid-1.6.2-26.el7.x86_64.rpm
rpm -ivh uuid-devel-1.6.2-26.el7.x86_64.rpm
方式2:源码方式安装uuid

📎uuid-1-6-2-tar.gz

上传至/opt

tar -xvf /opt/uuid-1-6-2-tar.gz
./configure
make
make install

执行编译配置

该操作只是在已安装完PG后,把uuid-ossp编译安装进了PG,不影响现有库。

操作系统版本低的场景下需要单独安装uuid。若上面已经按照过uuid组件则跳过rpm -ivh步骤,若上面编译时包含--with-uuid=ossp 则跳过./configure --prefix=/data/pgdb/pgsql --with-uuid=ossp 步骤。

cd /data/pgdb/pgsql
./configure --prefix=/data/pgdb/pgsql --with-uuid=ossp   #prefix 安装目录

若编译时已经包含--with-uuid=ossp 则跳过该步骤。

#进入扩展目录
cd /data/pgdb/pgsql/contrib/uuid-ossp
#编译安装
make && make install

问题处理

--问题描述
cd /data/pgdb/pgsql
./configure --prefix=/data/pgdb/pgsql --with-uuid=ossp
configure: using python 2.6.6 (r266:84292, May 22 2015, 08:34:51) 
configure: error: Python version 2.6 is too old (version 2.7 or later is required)

--解决办法
升级python

创建扩展

查看可用扩展
postgres=# select * from pg_available_extensions;
...
uuid-ossp          | 1.1             |                   | generate universally unique identifiers (UUIDs)

可以看到已经有扩展uuid-ossp了。下面可以创建了。

创建扩展
postgres=# create extension "uuid-ossp";
CREATE EXTENSION

使用扩展

安装扩展成功以后,就可以使用函数uuid_generate_v4()来生产uuid了。

postgres=# select uuid_generate_v4();
           uuid_generate_v4           
--------------------------------------
 c05ad6c7-ea34-4d36-8d09-4097cd7bae65
(1 row)

常见问题

登录提示连接socket失败

[postgres@localhost data]$ psql
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?
解决办法:
1.psql 后面加上端口号  psql -p 5439
2.在环境变量/home/postgres/.bash_profile中加上一句,添加完source下
echo 'export PGPORT=54328 #自己添加的环境变量' >> /home/postgres/.bash_profile
source /home/postgres/.bash_profile

编译报错

问题1:
configure: error: could not determine flags for linking embedded Perl.
This probably means that ExtUtils::Embed or ExtUtils::MakeMaker is not
installed.
安装:yum install perl-ExtUtils-Embed

问题2:
configure: error: OpenSSL Crypto library not found
安装:yum -y install openssl-devel 

 
问题3:
configure: error: could not determine flags for linking embedded Perl.
This probably means that ExtUtils::Embed or ExtUtils::MakeMaker is not
installed.
解决方法:
yum install perl-ExtUtils-Embed
 
问题4:
configure: error: readline library not found
If you have readline already installed, see config.log for details on the
failure. It is possible the compiler isn't looking in the proper directory.
Use --without-readline to disable readline support.
解决方法:
yum install readline readline-devel
问题5:
checking for inflate in -lz... no
configure: error: zlib library not found
If you have zlib already installed, see config.log for details on the
failure. It is possible the compiler isn't looking in the proper directory.
Use --without-zlib to disable zlib support.
解决方法:
yum install zlib zlib-devel
 
 
问题6:
checking for CRYPTO_new_ex_data in -lcrypto... no
configure: error: library 'crypto' is required for OpenSSL
解决方法:
yum install openssl openssl-devel
 
问题7:
checking for pam_start in -lpam... no
configure: error: library 'pam' is required for PAM
解决方法:
yum install pam pam-devel
 
问题8:
checking for xmlSaveToBuffer in -lxml2... no
configure: error: library 'xml2' (version >= 2.6.23) is required for XML support
解决方法:
yum install libxml2 libxml2-devel
 
问题9:
checking for xsltCleanupGlobals in -lxslt... no
configure: error: library 'xslt' is required for XSLT support
解决方法:
yum install libxslt libxslt-devel
 
 
问题10:
configure: error: Tcl shell not found
解决方法:
yum install tcl tcl-devel
 
 
问题11:
checking for ldap.h... no
configure: error: header file is required for LDAP
解决方法:
yum install openldap openldap-devel
 
问题12:
checking for Python.h... no
configure: error: header file <Python.h> is required for Python
解决方法:
yum install python python-devel
 
问题13:
Error when bootstrapping CMake:
Cannot find appropriate C++ compiler on this system.
Please specify one using environment variable CXX.
See cmake_bootstrap.log for compilers attempted.
解决方法:
yum install gcc-c++

启动报错"max_stack_depth" must not exceed 7680kB

--问题描述:启库报错:
[root@top132:/pgdb/data]$ systemctl start postgres
Job for postgres.service failed because the control process exited with error code. See "systemctl status postgres.service" and "journalctl -xe" for details.
[root@top132:/pgdb/data]$ journalctl -xe
Oct 09 04:12:48 top132 systemd[1]: Configuration file /usr/lib/systemd/system/postgres.service is marked executable. Please remove executable permission bits. Proceeding anyway.
Oct 09 04:12:56 top132 oracledb_exporter[29984]: ts=2023-10-09T08:12:56.802Z caller=collector.go:262 level=error Errorpingingoracle:="missing port in address"
Oct 09 04:13:11 top132 oracledb_exporter[29984]: ts=2023-10-09T08:13:11.805Z caller=collector.go:262 level=error Errorpingingoracle:="missing port in address"
Oct 09 04:13:26 top132 oracledb_exporter[29984]: ts=2023-10-09T08:13:26.803Z caller=collector.go:262 level=error Errorpingingoracle:="missing port in address"
Oct 09 04:13:41 top132 oracledb_exporter[29984]: ts=2023-10-09T08:13:41.806Z caller=collector.go:262 level=error Errorpingingoracle:="missing port in address"
Oct 09 04:13:56 top132 oracledb_exporter[29984]: ts=2023-10-09T08:13:56.802Z caller=collector.go:262 level=error Errorpingingoracle:="missing port in address"
Oct 09 04:14:04 top132 polkitd[727]: Registered Authentication Agent for unix-process:9141:161465164 (system bus name :1.6876 [/usr/bin/pkttyagent --notify-fd 5 --fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, loca
Oct 09 04:14:04 top132 systemd[1]: Starting PostgreSQL database server...
-- Subject: Unit postgres.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit postgres.service has begun starting up.
Oct 09 04:14:04 top132 pg_ctl[9147]: waiting for server to start....2023-10-09 08:14:04.952 GMT [9151] LOG:  invalid value for parameter "max_stack_depth": 8192
Oct 09 04:14:04 top132 pg_ctl[9147]: 2023-10-09 08:14:04.952 GMT [9151] DETAIL:  "max_stack_depth" must not exceed 7680kB.
Oct 09 04:14:04 top132 pg_ctl[9147]: 2023-10-09 08:14:04.952 GMT [9151] HINT:  Increase the platform's stack depth limit via "ulimit -s" or local equivalent.
Oct 09 04:14:04 top132 pg_ctl[9147]: 2023-10-09 04:14:04.953 EDT [9151] FATAL:  configuration file "/pgdb/data/postgresql.conf" contains errors
Oct 09 04:14:05 top132 pg_ctl[9147]: stopped waiting
Oct 09 04:14:05 top132 pg_ctl[9147]: pg_ctl: could not start server
Oct 09 04:14:05 top132 pg_ctl[9147]: Examine the log output.
Oct 09 04:14:05 top132 systemd[1]: postgres.service: control process exited, code=exited status=1

--问题原因
查看磁盘预读
[root@localhost ~]# /sbin/blockdev --getra  /dev/sda
8192

--解决办法
max_stack_depth修改小于7680kB 启动成功

https://blog.csdn.net/javastart/article/details/72476747

创建用于与从库同步的用户(可选)

创建专门负责从库同步的用户(可选),不想创建专门用户可以使用你主库的登录用户。

本文档采用默认管理员用户postgres。

create user replication with replication password 'replication';

补充:

必须显式地为角色授予启动流式复制的权限(超级用户除外,因为超级用户会绕过所有权限检查)。用于流式复制的角色也必须具有LOGIN权限。要创建这样的角色,请使用 CREATE ROLE name REPLICATION LOGIN

设置复制的访问权限

设置复制的访问权限非常重要,只有受信任的用户才能读取WAL流,因为很容易从中提取特权信息。备用服务器必须以具有REPLICATION权限的帐户或超级用户身份向主服务器进行身份验证。建议创建具有复制登录权限的专用用户帐户进行复制。虽然REPLICATION特权提供了非常高的权限,但它不允许用户修改主系统上的任何数据,而SUPERUSER特权则可以。

复制的客户端身份验证由数据库字段中指定复制pg_hba.conf记录控制。例如,如果备用服务器在主机IP192.168.40.201上运行,并且用于复制的帐户名为replication,则管理员可以将以下行添加到主服务器上的pg_hba.conf文件中。

cp /pgdb/data/pg_hba.conf /pgdb/data/pg_hba.conf_bak
echo "host    replication     postgres   192.168.40.201/32        md5" >> /pgdb/data/pg_hba.conf
psql -c "select pg_reload_conf()"

创建复制槽

SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
SELECT slot_name, slot_type, active FROM pg_replication_slots;

要将备用设备配置为使用此插槽,应在备用设备上配置primary_slot_name

备节点仅安装PG软件

编译安装

su - postgres
cd /pgdb/pgsql

./configure --prefix=/pgdb/pgsql --with-uuid=ossp
或
./configure --prefix=/pgdb/pgsql --with-pgport=5432 --with-openssl --with-perl \
--with-python --with-blocksize=128 --with-wal-blocksize=128 --with-wal-segsize=100 \
--with-readline --with-libxml --with-libxslt --with-uuid=ossp

gmake world -j2
gmake install-world -j2
--with-blocksize  设置块尺寸,以 K 字节计。这是表内存储和I/O的单位。默认值(8K字节)适合于大多数情况,但是在特殊情况下可能其他值更有用。这个值必须是2的幂并且在 1 和 32 (K字节)之间。注意修改这个值需要一次 initdb。
--with-wal-blocksize=128  设置WAL 块尺寸,以 K 字节计。这是 WAL 日志存储和I/O的单位。默认值(8K 字节)适合于大多数情况,但是在特殊情况下其他值更好有用。这个值必须是2的幂并且在 1 到 64(K字节)之间。注意修改这个值需要一次 initdb。
--with-wal-segsize=100
--with-perl --with-python:使用Perl和Python语法的过程语言来编写自定义函数。

gmake一次性将文档及附加模块全部进行编译和安装,保证所有数据库软件的一致性,避免给后期维护操作带来麻烦

补充:查下参数

--当前块大小blocksize  对应--with-blocksize
postgres=# SELECT current_setting('block_size');
 current_setting 
-----------------
 8192
(1 row)

--当前wal-blocksize   对应 --with-wal-segsize
postgres=# SELECT current_setting('wal_segment_size');
 current_setting 
-----------------
 16MB
(1 row)

--当前wal-segsize  对应 --with-wal-blocksize
postgres=# SELECT current_setting('wal_block_size');
 current_setting 
-----------------
 8192
(1 row)

配置环境变量

cp /home/postgres/.bash_profile  /home/postgres/.bash_profilebak
echo "##postgres user env configuration" >> /home/postgres/.bash_profile
sed -i 's/^export PATH/#export PATH/'  /home/postgres/.bash_profile
echo "#add by postgres" >>  /home/postgres/.bash_profile
echo 'export PGHOME=/pgdb/pgsql' >>  /home/postgres/.bash_profile
echo 'export PGDATA=/pgdb/data' >>  /home/postgres/.bash_profile
echo 'export PGHOST=192.168.40.200' >>  /home/postgres/.bash_profile
echo 'export PGPORT=5432' >>  /home/postgres/.bash_profile
echo 'export PGDATABASE=postgres' >>  /home/postgres/.bash_profile
echo 'export PGUSER=postgres' >>  /home/postgres/.bash_profile
echo 'export PGPASSWORD=postgres' >>  /home/postgres/.bash_profile
echo 'export PATH=$PGHOME/bin:$PATH' >>  /home/postgres/.bash_profile
echo 'export MANPATH=$PGHOME/share/man:$MANPATH' >>  /home/postgres/.bash_profile
echo 'export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH' >>  /home/postgres/.bash_profile
echo 'export LANG="en_US.UTF-8"' >>  /home/postgres/.bash_profile
echo 'export DATE=`date +"%Y%m%d%H%M"`' >>  /home/postgres/.bash_profile
source /home/postgres/.bash_profile	

配置密码

~/.pgpass文件中设置密码

su - postgres
echo "postgres" > /home/postgres/.pgpass
chmod 0600 /home/postgres/.pgpass

制作基本备份

官方文档摘要

执行基本备份的最简单方法是使用pg_basebackup工具。它可以将基本备份创建为常规文件或tar存档。如果需要比pg_basebackup提供的更大的灵活性,您还可以使用低级API进行基本备份。

不必担心进行基本备份所需的时间。但是,如果您在禁用full_page_writes的情况下正常运行服务器,则可能会注意到在备份运行时性能下降,因为在备份模式下实际上强制启用了full_page_writes,默认开启

要使用备份,您需要保留在文件系统备份期间和之后生成的所有WAL段文件。为了帮助您执行此操作,基本备份过程创建一个备份历史文件,该文件立即存储到WAL存档区域中。此文件以文件系统备份所需的第一个WAL段文件命名。例如,如果起始WAL文件为0000000100001234000055CD,则备份历史文件将命名为类似 0000000100001234000055CD.007C9330.backup 的名称。(The文件名的第二部分代表WAL文件中的确切位置,通常可以忽略。一旦您安全地存档了文件系统备份和备份过程中使用的WAL段文件(如备份历史文件中所指定的),则恢复文件系统备份时不再需要名称在数字上较小的所有存档WAL段,并且可以将其删除。 但是,您应该考虑保留多个备份集,以绝对确保可以恢复数据。

备份历史文件只是一个小文本文件。它包含您提供给pg_basebackup的标签字符串,以及备份的开始和结束时间以及WAL段。如果您使用标签来标识关联的转储文件,则存档的历史文件足以告诉您要还原哪个转储文件。

由于您必须将所有存档的WAL文件保留到上次基本备份,因此基本备份之间的间隔通常应根据您希望在存档的WAL文件上花费多少存储空间来选择。如果有必要恢复,您还应该考虑准备花多长时间进行恢复-系统将不得不重播所有这些WAL段,如果距离上次基本备份已经过去很长时间,这可能需要一段时间。

pg_basebackup-对PostgreSQL集群进行基本备份

pg_basebackup用于对正在运行的PostgreSQL数据库集群进行基本备份。备份不会影响数据库的其他客户端,并且可以用于时间点恢复,也可以用作日志传送或流复制备用服务器的起点。

pg_basebackup创建数据库集群文件的精确副本,同时确保服务器自动进入和退出备份模式。备份总是对整个数据库集群进行;不可能备份单个数据库或数据库对象。对于选择性备份,必须使用另一个工具,如pg_dump

备份通过使用复制协议的常规PostgreSQL连接进行。必须使用具有REPLICATION权限或超级用户的用户ID进行连接,并且pg_hba.conf必须允许复制连接。服务器还必须配置max_wal_allocation设置足够高,以提供至少一个walsender用于备份,另一个用于WAL流(如果使用)。

可以同时运行多个pg_basebackup,但从性能的角度来看,通常只进行一次备份并复制结果会更好。

pg_basebackup不仅可以从主服务器而且可以从备用服务器进行基本备份。要从备用设备进行备份,请设置备用设备,使其可以接受复制连接(即,设置max_wal_standbyhot_standby,并适当配置其pg_hba.conf)。您还需要在主服务器上启用full_page_writes,默认开启。

每当pg_basebackup进行基本备份时,服务器的pg_stat_progress_basebackup视图将报告备份的进度。

制作基本备份

pg_basebackup -h 192.168.40.200 -U postgres -c fast -F p -P -Xs -R -D /pgdb/data -l backup_label -v

输出如下:

--制作基本备份
[postgres@pgslave data]$ pg_basebackup -h 192.168.40.200 -U postgres -c fast -F p -P -Xs -R -D /pgdb/data -l backup_label -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/5000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_1854"
26283/26283 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/5000100
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed

--更改目录权限
su - root
chown -R postgres:postgres /pgdb/data/
chmod -R 700 /pgdb/data/

查看数据目录,会发现数据目录下比主库多了一个standby.signal文件

如果启动服务器时数据目录中存在standby.signal文件,则服务器进入待机模式。

在备用模式下,服务器持续应用从主服务器接收的WAL。备用服务器可以从WAL存档中读取WAL,也可以通过TCP连接直接从主服务器读取WAL(流式复制)。备用服务器还将尝试恢复在备用群集的pg_wal目录中找到的任何WAL。这通常发生在服务器重启之后,当备用服务器再次重放重启之前从主服务器流传输的WAL时,但您也可以随时手动将文件复制到pg_wal以重放它们。

启动时,备用服务器首先调用restore_command恢复存档位置中所有可用的WAL。一旦它到达那里可用的WAL的末尾并且restore_command失败,它将尝试恢复pg_wal目录中可用的任何WAL。如果失败,并且已经配置了流式复制,备用服务器将尝试连接到主服务器,并从archive或pg_wal中找到的最后一个有效记录开始流式WAL。如果此操作失败或未配置流式复制,或者连接后来断开,则备用服务器将返回步骤1,并尝试再次从存档中恢复文件。这种从存档、pg_wal和通过流复制的重试循环一直持续到服务器停止或升级。

当运行pg_ctl promote、调用pg_promote()或找到触发器文件(promote_trigger_file)时,退出待机模式,服务器切换到正常操作。在故障转移之前,归档文件或pg_wal中立即可用的任何WAL都将被恢复,但不会尝试连接到主服务器。

注意事项

从备用备份中进行备份有一些限制:

备份历史记录文件不是在备份的数据库群集中创建的。

pg_basebackup不能强制备份在备份结束时切换到新的WAL文件。当您使用-X none时,如果主服务器上的写入活动很低,pg_basebackup可能需要等待很长时间才能切换和归档备份所需的最后一个WAL文件。在这种情况下,在主服务器上运行pg_switch_wal可能会很有用,以便触发立即WAL文件切换。

如果在备份过程中将备用备份提升为主备份,则备份将失败。

备份所需的所有WAL记录必须包含足够的整页写入,这要求您在主文件上启用full_page_writes,并且不要使用pg_compresslog等工具作为archive_command来从WAL文件中删除整页写入。

postgresql.conf添加主库和复制槽信息

主服务器的主机名和端口号、连接用户名和密码在primary_conninfo中指定。备用服务器上的postgresql.conf文件添加主库信息


echo "primary_conninfo = 'host=192.168.40.200 port=5432 user=postgres password=postgres'" >> /pgdb/data/postgresql.conf 
echo "primary_slot_name = 'node_a_slot'" >> /pgdb/data/postgresql.conf 

启动备库

pg_ctl start

查看进程

主库

walsender进程

[postgres@pgmaster ~]$ ps -ef | grep walsender
postgres   1870   1663  0 15:24 ?        00:00:00 postgres: walsender postgres 192.168.40.201(33132) streaming 0/6034AF8

备库

walreceiver进程

[postgres@pgslave data]$ ps -ef | grep walreceiver
postgres  13262  13256  0 15:24 ?        00:00:01 postgres: walreceiver streaming 0/6034B30

验证数据同步

主库创建业务用户和表

--创建新用户
create user top_sjjs with  password 'top_sjjs';
alter user top_sjjs with superuser;
--创建数据库
create database mix_db owner top_sjjs;
grant all privileges on database mix_db to top_sjjs;
grant all privileges on all tables in schema public to top_sjjs; --(可选)
--创建业务数据
psql -U top_sjjs -W mix_db
create table test(id int);
insert into test values(10);
select * from test;

输出如下:

mix_db=# select * from test;
 id
----
 10
(1 row)

备库查看数据

psql -U top_sjjs -W mix_db
select * from test;

输出如下:

mix_db=# select * from test;
 id
----
 10
(1 row)

运维

pg_stat_replication视图

流复制的一个重要健康指标是在主服务器中生成但尚未在备用服务器中应用的WAL记录的数量。您可以通过比较主服务器上的当前WAL写入位置与备用服务器接收到的最后一个WAL位置来计算此延迟。可以分别使用主服务器上的pg_current_wal_lsn和备用服务器的pg_last_wal_receive_lsn检索这些位置。待机状态下的最后一个WAL接收位置也显示在WAL接收器进程的进程状态中,使用ps命令显示。

可以通过pg_stat_replication视图检索WAL发送方进程的列表。pg_current_wal_lsn和视图的sent_lsn字段之间的较大差异可能表明主服务器负载较重,而备用服务器上的sent_lsnpg_last_wal_receive_lsn之间的差异可能表明网络延迟,或者备用服务器负载较重。

在热备用时,WAL接收器进程的状态可以通过pg_stat_wal_receiver视图检索。pg_last_wal_replay_lsn和视图的flushed_lsn之间的较大差异表明接收WAL的速度比重放WAL的速度快。

查看主库

可以通过pg_stat_replication视图检索WAL发送方进程的列表。pg_current_wal_lsn和视图的sent_lsn字段之间的较大差异可能表明主服务器负载较重。

pg_stat_replication视图主库有输出,备库无输出。

--查看当前wal_lsn
postgres=# select pg_current_wal_lsn();
-[ RECORD 1 ]------+----------
pg_current_wal_lsn | 0/6034C18

--查看pg_stat_replication视图
[postgres@pgmaster ~]$ psql
psql (14.2)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 1870
usesysid         | 10
usename          | postgres
application_name | walreceiver
client_addr      | 192.168.40.201
client_hostname  |
client_port      | 33132
backend_start    | 2024-09-09 15:24:38.705963+08
backend_xmin     |
state            | streaming
sent_lsn         | 0/6034C18
write_lsn        | 0/6034C18
flush_lsn        | 0/6034C18
replay_lsn       | 0/6034C18
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2024-09-09 16:01:58.592683+08

查看备库

pg_stat_replication视图

备用服务器上的sent_lsnpg_last_wal_receive_lsn之间的差异可能表明网络延迟,或者备用服务器负载较重。

备库上查询pg_stat_replication视图无输出。

pg_stat_wal_receiver视图

postgres=# select pg_last_wal_receive_lsn();
 pg_last_wal_receive_lsn
-------------------------
 0/6034C18
(1 row)

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
(0 rows)

postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 13262
status                | streaming
receive_start_lsn     | 0/6000000
receive_start_tli     | 1
written_lsn           | 0/6034C18
flushed_lsn           | 0/6034C18
received_tli          | 1
last_msg_send_time    | 2024-09-09 16:08:59.98003+08
last_msg_receipt_time | 2024-09-09 16:08:59.186962+08
latest_end_lsn        | 0/6034C18
latest_end_time       | 2024-09-09 15:59:59.223998+08
slot_name             | node_a_slot
sender_host           | 192.168.40.200
sender_port           | 5432
conninfo              | user=postgres password=******** channel_binding=disable dbname=replication host=192.168.40.200 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any

复制槽

复制插槽提供了一种自动化的方法,以确保主服务器在所有备用服务器接收到WAL段之前不会删除这些段,并且主服务器不会删除可能导致恢复冲突的行,即使备用服务器断开连接也是如此。

不使用复制插槽,可以使用wal_keep_size或使用archive_command将数据段存储在归档文件中来防止删除旧的WAL数据段。但是,这些方法通常会导致保留比所需更多的WAL段,而复制插槽仅保留已知需要的段数。另一方面,复制插槽可以保留如此多的WAL段,以至于它们会填满为pg_wal分配的空间;max_slot_wal_keep_size限制复制插槽保留的WAL文件的大小。

类似地,hot_standby_feedbackvacuum_defer_cleanup_age提供保护,防止相关行被vacuum删除,但前者在备用设备未连接的任何时间段内都不提供保护,后者通常需要设置为高值以提供足够的保护。复制插槽克服了这些缺点。

查询和操作复制插槽

每个复制插槽都有一个名称,可以包含小写字母、数字和下划线字符。

可以在pg_replication_slots视图中查看现有复制插槽及其状态。

可以通过流复制协议或SQL函数创建和删除插槽。

创建复制槽

postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
  slot_name  | lsn
-------------+-----
 node_a_slot |

postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
  slot_name  | slot_type | active 
-------------+-----------+--------
 node_a_slot | physical  | f
(1 row)

要将备用设备配置为使用此插槽,应在备用设备上配置primary_slot_name。如下:

primary_conninfo = 'host=192.168.40.200 port=5432 user=postgres password=postgres'
primary_slot_name = 'node_a_slot'
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论