PostgreSQL 多数据库集簇配置及多数据库复制方法
1. 多数据库集簇配置
安装下载完postgresql后,系统此时包含一个postgres
用户和一个名为postgres
的默认数据库。
PostgreSQL 基本命令
-
服务管理命令
bash# 停止和启动及重启PostgreSQL服务 sudo systemctl stop postgresql sudo systemctl start postgresql sudo systemctl restart postgresql # 查看服务当前状态 sudo systemctl status postgresql # 设置服务开机自启动 sudo systemctl enable postgresql # 禁止服务开机自启动 sudo systemctl disable postgresql
systemctl
是 Linux 系统中用于管理系统服务的工具 -
客服端交互命令
bash# 连接到数据库 sudo -u postgres psql # 连接指定数据库 sudo -u postgres psql -d <database_name> # 退出 \q
-
数据库操作命令(psql客户端)
sql# 创建新数据库 CREATE DATABASE <database_name>; # 删除 DROP DATABASE <database_name>; # 列出 \l # 切换 \c <database_name>
-
用户及权限管理
sql# 创建 CREATE USER your_username WITH PASSWORD 'your_password'; # 删除 DROP USER your_username; # 授权 GRANT ALL PRIVILEGES ON DATABASE your_database_name TO your_username; # 撤销 REVOKE ALL PRIVILEGES ON DATABASE your_database_name FROM your_username;
自定义端口与数据库集簇
配置要设置端口等基本信息,需要先停止服务
bash
sudo systemctl stop postgresql
初始化集簇步骤:
bash
# 创建一个数据库集簇的数据目录 -p 递归创建
sudo mkdir -p /data/postgresql
# 赋权
sudo chown postgres:postgres /data/postgresql
# 当前用户使用postgres用户的身份初始化数据库集簇 -u 指定用户 -D 指定数据目录 -E 指定默认字符编码
sudo -u postgres /usr/lib/postgresql/<version>/bin/initdb -D /data/postgresql -E UTF8
initdb
是 PostgreSQL 数据库管理系统中的一个关键命令,主要用于初始化一个新的数据库集簇。
修改配置文件:
bash
sudo -u postgres vim <PG_HOME>/postgresql.conf
# 本例中<PG_HOME>为 /data/postgresql 即数据目录
# 设置值
listen_addresses = '*' # 允许远程访问
port = 5439 # 改成任意空闲端口
max_connections = 100 # 设置最大连接数
等价于:
bash
# -a 追加模式 tee 将标准输入复制到每个指定的文件
sudo -u postgres tee -a <PG_HOME>/postgresql.conf << EOF
listen_addresses = '*'
port = 5439
max_connections = 100
EOF
EOF
(Here Document)是一种在脚本中向文件追加内容或传递多行输入的便捷方法。
两种启动数据库集簇方式
1.手动
bash
# pg_ctl 根据-D 后的数据目录来定位要启动的数据库集簇。
sudo -u postgres /usr/lib/postgresql/<PostgreSQL-Version>/bin/pg_ctl start -D /data/postgresql
pg_ctl
是 PostgreSQL 提供的一个实用工具,用于控制 PostgreSQL 服务器的启动、停止、重启、重新加载配置等操作。注意和
systemctl
的比较:
pg_ctl
是 PostgreSQL 自带的命令行工具,主要用于对 PostgreSQL 数据库集簇进行精细的控制和管理。直接与 PostgreSQL 服务器进行交互,操作的核心是数据库集簇。systemctl
是 Linux 系统中systemd
系统和服务管理器的命令行工具,用于管理系统服务。它是操作系统层面的服务管理工具,对各种系统服务(包括 PostgreSQL 服务)进行统一管理。(见2)
2.一键启动
首先创建Systemd服务文件
bash
sudo vim /etc/systemd/system/postgresql-custom.service
# postgresql-custom 自定义名称,一个名称对应与一个数据库集簇
加入以下内容:
bash
[Unit]
Description=PostgreSQL Custom Instance # 对该服务的简要描述,方便用户了解服务的功能
After=network.target # 确保在网络服务启动后再启动 PostgreSQL 服务
[Service]
Type=forking # 服务使用 fork() 方式启动,即父进程启动子进程后退出
User=postgres
Group=postgres # 指定服务以 postgres 用户和 postgres 用户组的身份运行
Restart=on-failure # 服务因异常退出时,systemd 会自动尝试重启该服务
ExecStart=/usr/lib/postgresql/14/bin/pg_ctl start -D /data/postgresql # 启动服务时执行的命令
ExecStop=/usr/lib/postgresql/14/bin/pg_ctl stop -D /data/postgresql # 停止服务时执行的命令
[Install]
WantedBy=multi-user.target # 该服务在多用户模式下被启动
保存退出,命令行输入:
bash
sudo systemctl daemon-reload # 重新加载 systemd 配置
sudo systemctl start postgresql-custom # 若启动其他集簇,编辑对应systemd文件并启动即可
监听服务状态
bash
# 监听的端口号; ss 显示套接字统计信息的工具 -t tcp -u udp -l 显示处于监听状态的套接字 -n 数字形式显示地址和端口号 -p 显示使用该套接字的进程信息 | grep <port_id> 筛选出监听 5439 端口的套接字信息
sudo ss -tulnp | grep 5439
对应端口显示listen
即可。
2. 多数据库异步流复制
速通Docker安装
-
更换apt源
bashsudo apt update sudo apt install apt-transport-https \ ca-certificates \ curl \ software-properties-common \ gnupg \ lsb-release # **阿里源** curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加 apt 源: # 阿里 apt 源 echo "deb [arch=$(dpkg --print-architecture) \ signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt-get update
问题总结:
- sudo apt update 报错
E: 仓库 "https://apt.postgresql.org/pub/repos/apt xenial-pgdg Release" 没有 Release 文件
解决:
sudo rm /etc/apt/sources.list.d/pgdg.list
2. 安装curl
依赖报错: curl : 依赖: libcurl3-gnutls (= 7.47.0-1ubuntu2) 但是 7.47.0-1ubuntu2.15 正要被安装解决:强制安装指定版本:
sudo apt-get install libcurl3-gnutls=7.47.0-1ubuntu2
- sudo apt update 报错
-
安装Docker Engine
插件先不装
bashsudo apt-get install docker-ce \ docker-ce-cli \ containerd.io
-
更换镜像
bash# 设置registry mirror sudo vim /etc/docker/daemon.json # 加入以下内容 (最新镜像源 可以网上找资源) { "registry-mirrors": [ "https://docker.1ms.run", "https://docker.xuanyuan.me" ] } ## 重启Docker systemctl daemon-reload systemctl restart docker
-
测试
bashsudo docker run hello-world # 本地找不到镜像就会去镜像源拉去相关镜像 输出对应镜像信息
异步流复制
动机
简单来说就是为了防止大哥出事,搞几个备份顺便还能分担大哥的压力。
准备工作
下载pg的docker镜像:
bash
docker pull postgres
挂载数据卷同步数据:
bash
ocker volume create postgre-data
创建主库容器
bash
docker run -id --name=pg1 -v postgre-data:/var/lib/postgresql/data -p 5432:5432 -e POSTGRES_PASSWORD=123456 -e LANG=C.UTF-8 postgres
# dock run :基于指定的镜像创建并启动一个新的容器
# -d 保持后台运行 -i 保持标准输入流处于打开状态 --name 命名
# -v 挂载数据卷 -v <column_name>:<data_path> 数据卷名称及容器内数据目录
# -p <home_port>:<container_port> 将容器内部的端口映射到宿主机的端口 能通过宿主机的 5432 端口访问容器内运行的 PostgreSQL 服务
# postgres 镜像名称
相关配置(挂载数据卷内配置,不进入容器)
获取主机ip
bash
hostname # 主机名
hostname -i # 主机ip
打开配置文件,加入配置信息
bash
vim /var/lib/docker/volumes/postgre-data/_data/postgresql.conf
# 添加信息 普通模式 G 跳转底部
wal_level = replica
max_wal_senders = 3
hot_standby = on
# host replication all 127.0.0.1/32 md5
# pg_hba.conf 文件定义了哪些客户端可以连接到 PostgreSQL 服务器,以及它们使用何种认证方法进行身份验证。
sudo vim /var/lib/postgresql/data/pg_hba.conf
#添加
host replication all 127.0.0.1/16 md5
# 退出重启容器 docker ps -a 查看容器状态
sudo docker restart pg1
在主库中插入测试数据:
bash
# 进入容器并使用 psql 连接数据库
docker exec -it pg1 psql -U postgres
sql
-- 创建学生表
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT,
gender CHAR(1),
enrollment_date DATE
);-- 插入示例数据
INSERT INTO students (name, age, gender, enrollment_date)
VALUES
('张三', 20, 'M', '2024-09-01'),
('李四', 21, 'F', '2023-09-01'),
('王五', 22, 'M', '2022-09-01'),
('赵六', 19, 'F', '2025-01-15'),
('孙七', 23, 'M', '2022-03-20'),
('周八', 20, 'F', '2024-07-10'),
('吴九', 22, 'M', '2023-11-05'),
('郑十', 21, 'F', '2024-04-25'),
('王十一', 18, 'M', '2025-02-01'),
('李十二', 24, 'F', '2021-09-30'),
('张十三', 20, 'M', '2024-09-12'),
('刘十四', 22, 'F', '2023-06-18'),
('陈十五', 19, 'M', '2025-03-08');
# \q 退出psql
创建备库(pg_basebackup 初始化)
创建备库
bash
sudo docker run -d --name pg2 -e POSTGRES_PASSWORD=123456 postgres:latest bash -c "while true; do sleep 1; done"
# PostgreSQL 需要一个数据目录来存储数据库文件。如果没有挂载数据卷,PostgreSQL 服务将无法启动,因为默认的数据目录是空的。
# 当 PostgreSQL 服务无法启动时,容器会因为没有主进程而退出 无限循环脚本阻止容器退出
# bash -c:在容器内启动一个 Bash Shell,并执行后面的命令
查看pg1
ip:
bash
sudo docker exec -it pg1
apt-get update
apt-get install net-tools
ifconfig
exit
执行pg_basebackup
创建基础备份:
bash
# -h 主库ip或主机名 -U 连接到主库使用的用户名 -D 基础备份数据存储的目标目录 -R 自动生成恢复配置文件 备库在启动时连接到主库,并开始接收 WAL(预写式日志)流,从而实现流复制。 -X 指定如何处理WAL stream 通过流复制的方式实时获取主节点的 WAL 日志,确保备份数据的一致性。
sudo docker exec pg2 pg_basebackup -h <pg1_ip> -U postgres -D /var/lib/postgresql/data -P -R -X stream -v
# 172.17.0.2
pg_basebackup
是 PostgreSQL 提供的一个工具,用于创建 PostgreSQL 数据库集群的基础备份。基础备份是创建流复制环境的第一步,它会复制主节点上的所有数据文件,为从节点提供一个初始的数据副本。
启动备库:
bash
sudo docker exec pg2 su postgres -c "pg_ctl start -D /var/lib/postgresql/data"
主备一致性
接下来就是验收结果
-
主库检查
sql# 进入主库容器 psql进入pg交互 SELECT client_addr, state, sync_state, sent_lsn, write_lsn FROM pg_stat_replication; # 输出应备库IP等信息
-
备库检查
sql# 备库同理 SELECT pg_is_in_recovery(); # t 备库模式 SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn() # 与主库一致
-
数据一致性
sql# 主库写入 CREATE TABLE test (id SERIAL PRIMARY KEY, data TEXT); INSERT INTO test (data) VALUES ('HA test'); # 备库查询 SELECT * FROM test; # 数据一致
-
日志信息等