开源文档

工单短信触达需求文档

基于DDD领域驱动设计,实现工单短信自动触达、手动回复、回访处理及统计报表功能

📋 需求概述

项目背景

投诉工单系统需要新增短信通知功能,实现工单受理、结案、回访的短信触达,并改造直通率统计报表。

核心目标

  1. 自动发送受理短信:新建工单后自动发送受理通知
  2. 手动短信回复:支持处理人员手动发送结案通知短信
  3. 短信回访:工单结案后自动发送回访短信,处理客户回复
  4. 统计报表改造:基于主办机构计算直通办理率

🏗️ 领域模型设计

核心领域(Core Domain)

1. 投诉工单实体(ComplaintOrder)

// 核心字段
- orderId: 工单ID
- orderType: 工单类型12378监管转办消保转送咨询等
- contactName: 联系人姓名
- contactPhone: 联系人电话
- complainantPhone: 投诉人电话
- mainOrg: 主办机构总行/信用卡中心/分行/其他
- mainOperator: 主办人员
- isSmsReply: 是否短信回复/
- smsReplyTime: 回复时间
- isSmsVisit: 是否短信回访/
- visitDate: 回访日期
- visitTime: 回访时间
- visitResult: 回访效果满意/不满意
- processNotifyType: 处理决定告知方式短信/其他
- processNotifyTime: 处理决定告知时间

2. 短信交互实体(SmsInteraction)

- smsId: 短信记录ID
- orderId: 关联工单
- smsType: 短信类型受理通知/结案通知/回访
- templateId: 短信模板
- phone: 发送手机号
- customerName: 客户姓名
- sendTime: 短信发送时间
- sendOperator: 发送人
- replyContent: 客户回复内容
- replyTime: 客户回复时间

3. 短信模板实体(SmsTemplate)

- templateId: 模板ID
- templateName: 模板名称
- templateContent: 模板内容
- templateType: 类型受理/结案/回访
- approvedStatus: 业务审核状态
- visibleRoles: 可见角色总行/分行
- enabled: 是否启用

🎯 功能需求与开发任务

功能一:新建工单自动发送受理短信

📌 功能描述

投诉工单新建成功后,系统自动发送受理短信给联系人。

区块链技术核心:典当铺的启示

从沈万三的黄金当票到分布式账本的魔法,探索区块链如何用时间换取不可篡改的空间

📖 引言

比特币作为第一个成功的去中心化数字货币,其核心创新在于解决了**“双花问题”**(Double Spending Problem)。如何用通俗易懂的方式理解这个看似复杂的技术问题?

本文通过一个生动的典当铺比喻,带你深入理解区块链的双花防御机制、51%攻击原理,以及"时间换空间"的核心思想。


🎭 第一幕:古老的漏洞——中心化的困境

故事:沈万三的第一次欺诈

从前,有个叫沈万三的商人,他有一块祖传金砖。他找到"诚信典当铺1号",抵押金砖,换得一张**“当票A”和一笔钱。掌柜的把“沈万三抵押金砖一块”**记录在自己的账本上。

沈万三动了歪心思:他手巧,伪造了一张一模一样的**“当票A’”**。他跑到城另一头的"仁义典当铺2号",声称要典当同一块金砖。2号掌柜没见过这块金砖,查验当票似乎无误,便也给了他钱。

结果:傍晚,两家典当铺掌柜对账时,发现**“同一块金砖被典当了两次”**,大惊失色!虽然最终作废了第二次交易,但沈万三已经卷钱跑路,2号典当铺蒙受了损失。

技术对应:传统中心化系统的双花问题

典当铺场景技术对应问题本质
各家典当铺独立账本银行独立数据库信息不同步
伪造当票A'复制交易记录数据可复制
利用时间差网络延迟缺乏全局一致性
2号铺蒙受损失商家收到假币无法验证资产唯一性

核心问题:在中心化系统中,如果缺乏权威机构的统一验证,同一资产(数字资产)可以被多次花费,这就是**“双花问题”**的根源。


🔄 第二幕:革命性的发明——分布式大账本

故事:典当联盟的诞生

全城的典当铺吃尽苦头,终于联合起来,成立了一个**“典当联盟”**。他们制定了一套全新的规则:

1. 统一账本

全城100家典当铺,每家都持有一本完全相同的、实时同步的超级大账本

技术对应分布式账本(Distributed Ledger)

  • 每个节点(典当铺)维护完整的账本副本
  • 通过共识机制保持数据一致性
  • 去中心化,无单一控制点

2. 当票即交易

任何一笔典当(交易),都不再是简单的当票,而是一条全网广播的**“交易记录”**。

例如:

交易ID:001
沈万三的金砖编号888,从[沈万三地址]抵押至[诚信1号地址]
时间戳:2024-01-01 10:00:00
签名:0x3a5f2b...

技术对应UTXO(未花费交易输出)

  • 每笔交易记录资产的转移
  • 交易用加密签名保证真实性
  • 全网广播,所有节点可见

3. 挖矿竞争(合账)

他们引入一种叫**“合账”的竞赛。每十分钟,各家掌柜会竞相把这段时间收到的交易记录打包成一个“区块”**(相当于一页账)。谁先解出一道超级难的数学题(工作量证明),谁就有权把这一页账(区块)发给所有人。

技术对应工作量证明(Proof of Work)

  • 矿工(掌柜)竞争打包交易
  • 解决哈希难题(数学题)获得记账权
  • 平均10分钟产生一个区块(比特币)

4. 链式记账

新的一页账必须牢牢钉在上一页账的后面,并用数学封印(哈希值)串联起来,形成一条**“区块链”**。想改其中一页,就必须重做后面所有的页,并重新赢得每次的竞赛。

技术对应区块链(Blockchain)

  • 每个区块包含前一个区块的哈希值
  • 形成不可篡改的链式结构
  • 篡改历史记录的成本呈指数级增长

架构对比

传统中心化系统          vs          区块链系统
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
单一账本(易被攻击)             分布式账本(100家店)
独立验证(信息差)               全网共识(统一验证)
可篡改(信任中心)               不可篡改(数学保证)
单点故障                         去中心化容错

⚔️ 第三幕:沈万三的终极挑战——51%攻击

故事:控制多数算力的攻击

沈万三不甘心,他决定挑战整个联盟系统。他想把典当给1号铺的金砖,再偷偷"典当"一次。

区块链将现实世界的硬度刻入数字灵魂

在浮屠一生的数字长河中,区块链让我们相信:有些东西,一旦发生,就应永存

一、当数据库"变硬":从增删改查到只能"生长"

大多数程序员的第一反应是:区块链不就是个分布式数据库吗?

确实,但这是个只能生长、不能修改的数据库。每一笔交易一旦被确认,就像现实中的"一手交钱、一手交货"——钱货两清,无法反悔。这种特性,我们称之为 “买定离手"的数字化

想象一下:如果现实世界的物理定律允许你随意修改已经发生的化学反应,世界会变成什么样子?区块链正是在数字世界里重建了这种不可逆性,让电子记录获得了物质世界的"硬度”。

传统数据库 vs 区块链

特性传统数据库区块链
数据操作增删改查(CRUD)只能追加(Append-only)
历史修改可以回滚、删除历史不可篡改
信任来源中心化机构数学和密码学
数据状态可变的、柔软的不可变的、坚硬的

二、“区块"与"链”:数字世界的岩石与地层

区块是什么?它不是一个简单的数据容器,而是一个时间胶囊。每个区块都封装了特定时间段内发生的所有交易,就像地质层中的岩石,记录着那个时代的所有故事。

又是什么?它是将这些时间胶囊按时间顺序焊接在一起的钢索。每个新区块都包含前一个区块的"数字指纹"(哈希值),形成了一种依赖关系:要修改历史中的任何一笔交易,就必须把之后所有的区块全部重做一遍。

这就像现实中的因果链:你今天做的决定,会基于昨天的经历;而昨天的经历,又基于前天的选择……想要改变过去的某一个瞬间,就必须改变之后所有的时空连续体。

区块的"时间胶囊"特性

区块 N-1                   区块 N                    区块 N+1
┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│ 交易1       │         │ 交易1       │         │ 交易1       │
│ 交易2       │         │ 交易2       │         │ 交易2       │
│ 交易3       │         │ 交易3       │         │ 交易3       │
│ ...         │         │ ...         │         │ ...         │
│ 前区块哈希  │ ──────→ │ 前区块哈希  │ ──────→ │ 前区块哈希  │
│ 时间戳      │         │ 时间戳      │         │ 时间戳      │
│ 随机数      │         │ 随机数      │         │ 随机数      │
└─────────────┘         └─────────────┘         └─────────────┘
     ↑                        ↑                        ↑
   历史                      现在                     未来

篡改成本:要修改区块 N-1 中的一笔交易,需要:

典籍篇

聚社区之智,传技术之火

◀ 返回

源码安装PostgreSQL稳定版本(Linux)

📋 准备工作

1. 查看最新稳定版本

# 访问PostgreSQL官网或使用命令查看
curl -s https://www.postgresql.org/ftp/source/ | grep -E 'href="v[0-9]+\.[0-9]+/"' | tail -5

# 当前长期支持版本(LTS)
# PostgreSQL 16.x (最新稳定版)
# PostgreSQL 15.x (长期支持)
# PostgreSQL 14.x (长期支持到2026年)
# PostgreSQL 13.x (长期支持到2025年)

2. 安装编译依赖

# Ubuntu/Debian
sudo apt update
sudo apt install -y \
    build-essential \
    libreadline-dev \
    zlib1g-dev \
    flex bison \
    libxml2-dev \
    libxslt-dev \
    libssl-dev \
    libssl-dev \
    libpam0g-dev \
    libldap-dev \
    libperl-dev \
    libicu-dev \
    tcl-dev \
    python3-dev \
    git \
    wget \
    curl

# CentOS/RHEL/Rocky/AlmaLinux
sudo yum groupinstall -y "Development Tools"
sudo yum install -y \
    readline-devel \
    zlib-devel \
    flex bison \
    libxml2-devel \
    libxslt-devel \
    openssl-devel \
    pam-devel \
    openldap-devel \
    perl-devel \
    perl-ExtUtils-Embed \
    tcl-devel \
    python3-devel \
    git \
    wget
vi /etc/sysctl.conf
#最大共享内存段大小
kernel.shmmax = 68719476736(默认) 
 #可以使用的共享内存的总量
kernel.shmall = 4294967296(默认)
#整个系统共享内存段的最大数目
kernel.shmmni = 4096 
#每个信号对象集的最大信号对象数
kernel.sem = 50100 64128000 50100 1280 
#文件句柄的最大数量。
fs.file-max = 7672460 
#应用程序可使用的IPv4端口范围
net.ipv4.ip_local_port_range = 9000 65000 
#套接字接收缓冲区大小的缺省值
net.core.rmem_default = 1048576 
#套接字发送缓冲区大小的缺省
net.core.wmem_default = 262144#套接字发送缓冲区大小的最大值
net.core.wmem_max = 1048576 

# sysctl -p #配置生效

🚀 源码安装PostgreSQL 16.2(当前稳定版)

步骤1:创建专用用户和目录

# 创建postgres系统用户和组
sudo groupadd -r postgres
sudo useradd -r -g postgres -s /bin/bash -d /usr/local/pgsql -m -k /dev/null postgres

# 创建安装目录和数据目录
sudo mkdir -p /usr/local/pgsql/{data,logs,backup}
sudo chown -R postgres:postgres /usr/local/pgsql
sudo chmod 750 /usr/local/pgsql

# 创建源码目录
sudo mkdir -p /opt/postgresql_src
sudo chown $(whoami):$(whoami) /opt/postgresql_src
cd /opt/postgresql_src

步骤2:下载源码

# 下载PostgreSQL 16.2(截至2024年3月的最新稳定版)
wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.gz

# 或者使用国内镜像(清华源)
# wget https://mirrors.tuna.tsinghua.edu.cn/postgresql/source/v16.2/postgresql-16.2.tar.gz

# 验证下载完整性(可选)
wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.gz.sha256
sha256sum -c postgresql-16.2.tar.gz.sha256

# 解压源码
tar -zxvf postgresql-16.2.tar.gz
cd postgresql-16.2

步骤3:配置编译选项

# 查看所有配置选项
./configure --help

# 创建编译目录(推荐)
mkdir build && cd build

# 基本配置(适用于大多数情况)
../configure \
    --prefix=/usr/local/pgsql \
    --with-pgport=5432 \
    --with-perl \
    --with-python \
    --with-tcl \
    --with-openssl \
    --with-pam \
    -with-uuid=ossp \
    --with-ldap \
    --with-libxml \
    --with-libxslt \
    --with-icu \
    --enable-thread-safety \
    --enable-debug \
    --enable-nls \
    --with-system-tzdata=/usr/share/zoneinfo
    

   

# 或者精简配置(最小化安装)
# ../configure --prefix=/usr/local/pgsql --with-openssl

步骤4:编译和安装

# 查看CPU核心数,决定并行编译数
nproc

# 编译(使用4个并行任务,根据CPU核心数调整)
make -j4

# 可选:运行回归测试(需要较长时间)
# make check

# 安装到系统
sudo make install

# 安装contrib模块(扩展工具)
cd contrib
make -j4
sudo make install
cd ..

步骤5:配置环境变量

# 为postgres用户配置环境变量
sudo tee -a /usr/local/pgsql/.bash_profile << 'EOF'
export PGHOME=/usr/local/pgsql
export PGDATA=/usr/local/pgsql/data
export PATH=$PGHOME/bin:$PATH
export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH
export MANPATH=$PGHOME/share/man:$MANPATH
EOF

# 为当前用户配置环境变量
echo 'export PATH=/usr/local/pgsql/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

# 验证安装
/usr/local/pgsql/bin/postgres --version

⚙️ 初始化数据库和配置

步骤6:初始化数据库

# 切换到postgres用户
sudo su - postgres

# 初始化数据库集群
initdb -D /usr/local/pgsql/data -E UTF8 --locale=C -U postgres

# 或者使用详细参数
initdb \
  -D /usr/local/pgsql/data \
  -E UTF8 \
  --locale=en_US.UTF-8 \
  --lc-collate=C \
  --lc-ctype=en_US.UTF-8 \
  --username=postgres \
  --pwprompt

# 设置密码(记下这个密码)
# 输入并确认postgres用户的密码

步骤7:配置postgresql.conf

# 备份原始配置
cp /usr/local/pgsql/data/postgresql.conf /usr/local/pgsql/data/postgresql.conf.original

# 编辑主配置文件
nano /usr/local/pgsql/data/postgresql.conf
# 修改以下参数(根据服务器配置调整)
listen_addresses = '*'          # 允许远程连接
port = 5432                     # 监听端口
max_connections = 100           # 最大连接数
shared_buffers = 128MB          # 共享缓冲区大小(建议为内存的25%)
work_mem = 4MB                  # 每个查询的工作内存
maintenance_work_mem = 64MB     # 维护操作的内存
dynamic_shared_memory_type = posix  # 动态共享内存类型
wal_level = replica             # WAL级别
synchronous_commit = on         # 同步提交
wal_buffers = -1                # WAL缓冲区(-1表示自动)
checkpoint_timeout = 5min       # 检查点超时时间
max_wal_size = 1GB              # 最大WAL大小
min_wal_size = 80MB             # 最小WAL大小
archive_mode = off              # 归档模式
archive_command = '/bin/date'   # 归档命令(关闭时随意设置)
logging_collector = on          # 启用日志收集
log_directory = 'pg_log'        # 日志目录
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'  # 日志文件名格式
log_rotation_age = 1d           # 日志轮转时间
log_rotation_size = 10MB        # 日志轮转大小
log_truncate_on_rotation = on   # 轮转时截断
log_line_prefix = '%m [%p] %q%u@%d '  # 日志前缀
log_timezone = 'Asia/Shanghai'  # 日志时区
timezone = 'Asia/Shanghai'      # 时区
datestyle = 'iso, ymd'          # 日期格式
lc_messages = 'en_US.UTF-8'     # 消息语言
lc_monetary = 'en_US.UTF-8'     # 货币格式
lc_numeric = 'en_US.UTF-8'      # 数字格式
lc_time = 'en_US.UTF-8'         # 时间格式
default_text_search_config = 'pg_catalog.english'  # 全文搜索配置

步骤8:配置客户端认证

# 编辑pg_hba.conf
nano /usr/local/pgsql/data/pg_hba.conf
# 允许本地连接(md5需要密码,trust不需要密码)
local   all             postgres                                peer
local   all             all                                     md5
host    all             all             127.0.0.1/32            md5

# 允许特定IP段连接
host    all             all             192.168.1.0/24          md5

# 允许所有IP连接(生产环境慎用)
host    all             all             0.0.0.0/0               md5

# 示例:只允许特定用户从特定IP访问特定数据库
# host    exam_db         app_user        192.168.1.100/32       md5

步骤9:创建系统服务

# 退出postgres用户
exit

# 创建systemd服务文件
sudo tee /etc/systemd/system/postgresql.service << 'EOF'
[Unit]
Description=PostgreSQL Database Server
After=network.target

[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGDATA=/usr/local/pgsql/data
OOMScoreAdjust=-1000
ExecStart=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} start
ExecStop=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} stop
ExecReload=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} reload
TimeoutSec=300

[Install]
WantedBy=multi-user.target
EOF

# 或者使用simple类型(推荐)
sudo tee /etc/systemd/system/postgresql.service << 'EOF'
[Unit]
Description=PostgreSQL Database Server
After=network.target

[Service]
Type=simple
User=postgres
Group=postgres
Environment=PGDATA=/usr/local/pgsql/data
Environment=PGPORT=5432
OOMScoreAdjust=-1000
ExecStart=/usr/local/pgsql/bin/postgres -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=300

[Install]
WantedBy=multi-user.target
EOF

步骤10:启动服务

# 重新加载systemd配置
sudo systemctl daemon-reload

# 启动PostgreSQL服务
sudo systemctl start postgresql

# 设置开机自启
sudo systemctl enable postgresql

# 查看服务状态
sudo systemctl status postgresql

# 查看日志
sudo journalctl -u postgresql -f

🔧 验证和基础配置

步骤11:验证安装

# 连接到数据库
psql -h localhost -U postgres -d postgres

# 在psql中执行
SELECT version();
SELECT current_user;
SHOW data_directory;
SHOW config_file;
\q  # 退出

步骤12:创建数据库和用户

# 切换到postgres用户
sudo su - postgres

# 创建测试数据库
createdb test_db

# 创建应用用户
createuser -P -d -e app_user
# 输入密码:AppPass123

# 连接到数据库并授权
psql -d test_db <<EOF
-- 创建schema
CREATE SCHEMA IF NOT EXISTS app_schema;

-- 创建测试表
CREATE TABLE app_schema.users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入测试数据
INSERT INTO app_schema.users (username, email) VALUES
('admin', 'admin@example.com'),
('user1', 'user1@example.com');

-- 授权给应用用户
GRANT ALL PRIVILEGES ON DATABASE test_db TO app_user;
GRANT ALL PRIVILEGES ON SCHEMA app_schema TO app_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA app_schema TO app_user;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA app_schema TO app_user;

-- 查看表
SELECT * FROM app_schema.users;
EOF

步骤13:安装常用扩展

# 安装pg_stat_statements(性能监控)
psql -U postgres -d test_db <<EOF
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS uuid-ossp;
CREATE EXTENSION IF NOT EXISTS btree_gin;
CREATE EXTENSION IF NOT EXISTS btree_gist;
SELECT * FROM pg_available_extensions ORDER BY name;
EOF

🛠️ 高级配置和优化

内存优化配置

# 根据服务器内存调整配置
sudo nano /usr/local/pgsql/data/postgresql.conf
# 内存相关优化(8GB内存服务器示例)
shared_buffers = 2GB           # 内存的25%
work_mem = 16MB                # 每个查询的工作内存
maintenance_work_mem = 512MB   # 维护操作内存
effective_cache_size = 6GB     # 可用于缓存的磁盘空间估计值

# 性能优化
max_connections = 200          # 根据应用需求调整
checkpoint_completion_target = 0.9
random_page_cost = 1.1         # SSD设为1.1,HDD设为4.0
effective_io_concurrency = 200 # SSD可以设高,HDD设低

# WAL优化
wal_buffers = 16MB
min_wal_size = 1GB
max_wal_size = 4GB

配置归档和备份

# 创建归档目录
sudo mkdir -p /usr/local/pgsql/archive
sudo chown postgres:postgres /usr/local/pgsql/archive

# 配置归档
sudo nano /usr/local/pgsql/data/postgresql.conf
# 启用归档
archive_mode = on
archive_command = 'test ! -f /usr/local/pgsql/archive/%f && cp %p /usr/local/pgsql/archive/%f'
archive_timeout = 3600  # 每小时强制归档

📊 监控和维护脚本

创建监控脚本

# 创建数据库健康检查脚本
sudo tee /usr/local/bin/check_postgres.sh << 'EOF'
#!/bin/bash
# PostgreSQL健康检查脚本

PGHOME=/usr/local/pgsql
PGDATA=/usr/local/pgsql/data
PGPORT=5432

echo "=== PostgreSQL健康检查 $(date) ==="

# 检查服务状态
systemctl is-active postgresql > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "✓ 服务状态: 运行中"
else
    echo "✗ 服务状态: 停止"
    exit 1
fi

# 检查连接
$PGHOME/bin/pg_isready -p $PGPORT -h localhost -U postgres
if [ $? -eq 0 ]; then
    echo "✓ 数据库连接: 正常"
else
    echo "✗ 数据库连接: 失败"
fi

# 检查磁盘空间
df -h $PGDATA | tail -1

# 检查数据库大小
echo "数据库大小:"
$PGHOME/bin/psql -h localhost -U postgres -d postgres -c "
SELECT 
    datname as \"数据库\",
    pg_size_pretty(pg_database_size(datname)) as \"大小\"
FROM pg_database 
ORDER BY pg_database_size(datname) DESC;
"

echo "=== 检查完成 ==="
EOF

sudo chmod +x /usr/local/bin/check_postgres.sh
sudo chown postgres:postgres /usr/local/bin/check_postgres.sh

创建备份脚本

# 创建备份脚本
sudo tee /usr/local/bin/backup_postgres.sh << 'EOF'
#!/bin/bash
# PostgreSQL备份脚本

BACKUP_DIR="/usr/local/pgsql/backup"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE

echo "开始备份: $(date)"

# 备份所有数据库
/usr/local/pgsql/bin/pg_dumpall -h localhost -U postgres \
    | gzip > $BACKUP_DIR/$DATE/full_backup_$DATE.sql.gz

# 备份单个重要数据库(可选)
/usr/local/pgsql/bin/pg_dump -h localhost -U postgres test_db \
    -F c -f $BACKUP_DIR/$DATE/test_db_$DATE.dump

echo "备份完成: $(date)"
echo "备份文件:"
ls -lh $BACKUP_DIR/$DATE/

# 清理旧备份
find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;

echo "已清理超过${RETENTION_DAYS}天的备份"
EOF

sudo chmod +x /usr/local/bin/backup_postgres.sh
sudo chown postgres:postgres /usr/local/bin/backup_postgres.sh

🎯 安装其他稳定版本

安装PostgreSQL 15.7(LTS版本)

cd /opt/postgresql_src
wget https://ftp.postgresql.org/pub/source/v15.7/postgresql-15.7.tar.gz
tar -zxvf postgresql-15.7.tar.gz
cd postgresql-15.7
mkdir build && cd build

# 配置(与16.2类似)
../configure \
    --prefix=/usr/local/pgsql15 \
    --with-pgport=5433 \
    --with-openssl \
    --with-perl \
    --with-python

make -j$(nproc)
sudo make install

安装PostgreSQL 14.12(长期支持)

cd /opt/postgresql_src
wget https://ftp.postgresql.org/pub/source/v14.12/postgresql-14.12.tar.gz
tar -zxvf postgresql-14.12.tar.gz
cd postgresql-14.12
mkdir build && cd build

../configure --prefix=/usr/local/pgsql14 --with-openssl
make -j$(nproc)
sudo make install

⚠️ 故障排除

常见问题解决

# 1. 编译错误:缺少依赖
# 重新安装所有依赖后清理重试
make distclean

# 2. 启动失败:端口被占用
netstat -tlnp | grep 5432
sudo lsof -i :5432

# 3. 连接失败:认证问题
# 检查pg_hba.conf配置

# 4. 内存不足:调整编译并行度
make -j2  # 使用更少的并行任务

# 5. 查看详细错误日志
tail -f /usr/local/pgsql/data/log/postgresql-*.log

📝 总结

安装步骤回顾

  1. 安装依赖:确保编译环境完整
  2. 下载源码:选择稳定版本(推荐16.2或15.7)
  3. 配置编译:根据需求选择编译选项
  4. 编译安装:使用并行编译提高速度
  5. 初始化数据库:设置数据目录和编码
  6. 配置参数:优化性能和安全
  7. 创建服务:使用systemd管理
  8. 验证测试:确保安装成功

版本选择建议

  • 生产环境:PostgreSQL 15.x(LTS支持到2027年)
  • 学习测试:PostgreSQL 16.x(最新特性)
  • 兼容性要求:PostgreSQL 14.x(支持到2026年)

关键配置文件

  • /usr/local/pgsql/data/postgresql.conf - 主配置文件
  • /usr/local/pgsql/data/pg_hba.conf - 客户端认证
  • /etc/systemd/system/postgresql.service - 服务文件

通过源码安装可以获得更好的性能和定制性,适合生产环境和对性能有要求的场景。

典籍篇

聚社区之智,传技术之火

◀ 返回

postgresql 的组成结构

内存

  • Local memory area:由每个后端进程分配给自己使用。

  • Share memory area: 由 postgresql 服务器的所有进程使用。

postgresql-memory

  • work_mem: 执行器执行 order bydistinctjoin tableshash-join操作时使用。

  • maintenance_work_mem: vacuum 归整、reindex重建索引,时使用。

  • temp_buffers: 临时表使用。

  • shared_buffer_pool: 从持久化的存储加载表页和索引页到此。

  • wal_buffer: 防止服务异常停止导致数据没有落盘,创建了 wal 缓冲区,相当于 redo log。

  • commit log: 记录所有的事务状态如:再处理,已提交、回退,保持事务的一致性。相当于 undo log。

进程

PostgreSQL 采用 C/S 模式,系统为每个连接的客户端分配一个服务进程 Postgres postgresql-process

当运行 pg_ctl 命令进入 Postgres 程序时,其进程创建流程如下:

PostMaster

postgresql-process1

  • PostMaster:进程是整个数据库实例的总控进程,负责启动关闭该数据实例。并且在服务进程出现错误时完成系统的恢复,还要在系统奔溃的时候重启系统。它是运行在服务器上的总控进程,同时也负责整个系统范围内的操作,例如中断操作与信号处理。但是 Postmaster 本身并不执行这些操作,而是指派一个子进程在适当的时间处理它们。Postmaster 进程在起始时会创建共享内存与信号库,用于与子进程的通信,同时也能在某个子进程奔溃的时候重置共享内存即可恢复。

Postmaster 守护进程的执行流程如下

postgres-porcess2

SysLogger

  • SysLogger:(系统日志)进程,日志信息是数据库管理员获取数据库系统运行状态的有效手段。在数据库出现故障时,日志信息是非常有用的。把数据库日志信息集中输出到一个位置将极大方便管理员维护数据库系统。然而,日志输出将产生大量数据(特别是在比较高的调试级别上),单文件保存时不利于日志文件的操作。因此,在SysLogger的配置选项中可以设置日志文件的大小,SysLogger会在日志文件达到指定的大小时关闭当前日志文件,产生新的日志文件。
# - Where to Log -

log_destination = 'stderr'              # Valid values are combinations of
                                        # stderr, csvlog, jsonlog, syslog, and
                                        # eventlog, depending on platform.
                                        # csvlog and jsonlog require
                                        # logging_collector to be on.

# This is used when logging to stderr:
logging_collector = on          # Enable capturing of stderr, jsonlog,
                                        # and csvlog into log files. Required
                                        # to be on for csvlogs and jsonlogs.
                                        # (change requires restart)

# These are only used if logging_collector is on:
#log_directory = 'log'                  # directory where log files are written,
                                        # can be absolute or relative to PGDATA
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'        # log file name pattern,
                                        # can include strftime() escapes
#log_file_mode = 0600                   # creation mode for log files,
                                        # begin with 0 to use octal notation
#log_rotation_age = 1d                  # Automatic rotation of logfiles will
                                        # happen after that time.  0 disables.
#log_rotation_size = 10MB               # Automatic rotation of logfiles will
                                        # happen after that much log output.
                                        # 0 disables.
#log_truncate_on_rotation = off         # If on, an existing log file with the
                                        # same name as the new log file will be
                                        # truncated rather than appended to.
                                        # But such truncation only occurs on
                                        # time-driven rotation, not on restarts
                                        # or size-driven rotation.  Default is
                                        # off, meaning append to existing files
                                        # in all cases.

log_destination:配置日志输出目标,根据不同的运行平台会设置不同的值,Linux下默认为stderr。