当前位置: 首页 > article >正文

PostgreSQL 多数据库集簇配置及多数据库复制方法【流程+代码实例】

PostgreSQL 多数据库集簇配置及多数据库复制方法

1. 多数据库集簇配置

安装下载完postgresql后,系统此时包含一个postgres用户和一个名为postgres的默认数据库。

PostgreSQL 基本命令

  • 服务管理命令

    # 停止和启动及重启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 系统中用于管理系统服务的工具

  • 客服端交互命令

    # 连接到数据库
    sudo -u postgres psql
    
    # 连接指定数据库
    sudo -u postgres psql -d <database_name>
    
    # 退出
    \q
    
  • 数据库操作命令(psql客户端)

    # 创建新数据库
    CREATE DATABASE <database_name>;
    
    # 删除
    DROP DATABASE <database_name>;
    
    # 列出
    \l
    
    # 切换
    \c <database_name>
    
  • 用户及权限管理

    # 创建
    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;
    

自定义端口与数据库集簇

配置要设置端口等基本信息,需要先停止服务

sudo systemctl stop postgresql

初始化集簇步骤:

# 创建一个数据库集簇的数据目录 -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 数据库管理系统中的一个关键命令,主要用于初始化一个新的数据库集簇

修改配置文件:

sudo -u postgres vim <PG_HOME>/postgresql.conf
# 本例中<PG_HOME>为 /data/postgresql 即数据目录

# 设置值
listen_addresses = '*'   # 允许远程访问
port = 5439    # 改成任意空闲端口          
max_connections = 100 # 设置最大连接数

等价于:

# -a 追加模式 tee 将标准输入复制到每个指定的文件
sudo -u postgres tee -a <PG_HOME>/postgresql.conf << EOF
listen_addresses = '*'   
port = 5439            
max_connections = 100   
EOF

EOF(Here Document)是一种在脚本中向文件追加内容或传递多行输入的便捷方法。

两种启动数据库集簇方式

1.手动
# 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服务文件

sudo vim /etc/systemd/system/postgresql-custom.service
# postgresql-custom 自定义名称,一个名称对应与一个数据库集簇

加入以下内容:

[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  # 该服务在多用户模式下被启动

保存退出,命令行输入:

sudo systemctl daemon-reload   # 重新加载 systemd 配置
sudo systemctl start postgresql-custom # 若启动其他集簇,编辑对应systemd文件并启动即可

监听服务状态

# 监听的端口号; ss 显示套接字统计信息的工具 -t tcp -u udp -l 显示处于监听状态的套接字 -n 数字形式显示地址和端口号 -p 显示使用该套接字的进程信息  | grep <port_id>  筛选出监听 5439 端口的套接字信息
sudo ss -tulnp | grep 5439

对应端口显示listen 即可。

2. 多数据库异步流复制

速通Docker安装

  • 更换apt源

     sudo 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
    

    问题总结:

    1. sudo apt update 报错E: 仓库 “https://apt.postgresql.org/pub/repos/apt xenial-pgdg Release” 没有 Release 文件

    解决:sudo rm /etc/apt/sources.list.d/pgdg.list

    1. 安装curl依赖报错: curl : 依赖: libcurl3-gnutls (= 7.47.0-1ubuntu2) 但是 7.47.0-1ubuntu2.15 正要被安装

    解决:强制安装指定版本:sudo apt-get install libcurl3-gnutls=7.47.0-1ubuntu2

  • 安装Docker Engine

    插件先不装

     sudo apt-get install docker-ce \
                    docker-ce-cli \
                    containerd.io 
    
  • 更换镜像

    # 设置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
    
  • 测试

    sudo docker run hello-world
    # 本地找不到镜像就会去镜像源拉去相关镜像 输出对应镜像信息
    

异步流复制

动机

简单来说就是为了防止大哥出事,搞几个备份顺便还能分担大哥的压力。

准备工作

下载pg的docker镜像:

docker pull postgres

挂载数据卷同步数据:

ocker volume create postgre-data
创建主库容器
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

hostname  # 主机名
hostname -i # 主机ip

打开配置文件,加入配置信息

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

在主库中插入测试数据:

# 进入容器并使用 psql 连接数据库
docker exec -it pg1 psql -U postgres
-- 创建学生表
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 初始化)

创建备库

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,并执行后面的命令

查看pg1ip:

sudo docker exec -it pg1

apt-get update
apt-get install net-tools
ifconfig

exit

执行pg_basebackup创建基础备份:

# -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 数据库集群的基础备份。基础备份是创建流复制环境的第一步,它会复制主节点上的所有数据文件,为从节点提供一个初始的数据副本。-R 选项,备库会尝试通过网络连接到主库,连接成功后发送请求,主库将新生成的WAL日志持续发送给备库(流复制),备库根据WAL日志顺序执行,实现和主库的同步。

启动备库:

sudo docker exec pg2 su postgres -c "pg_ctl start -D /var/lib/postgresql/data"

主备一致性

接下来就是验收结果

  • 主库检查

    # 进入主库容器 psql进入pg交互
    SELECT client_addr, state, sync_state, sent_lsn, write_lsn  FROM pg_stat_replication;
    # 输出应备库IP等信息
    
  • 备库检查

    # 备库同理
    SELECT pg_is_in_recovery(); # t 备库模式
    SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn() # 与主库一致
    
  • 数据一致性

    # 主库写入
    CREATE TABLE test (id SERIAL PRIMARY KEY, data TEXT);
    INSERT INTO test (data) VALUES ('HA test');
    
    # 备库查询
    SELECT * FROM test;  # 数据一致
    
  • 日志信息等


http://www.kler.cn/a/590691.html

相关文章:

  • Redis,从数据结构到集群的知识总结
  • 基于javaweb的SpringBoot智能相册管理系统图片相册系统设计与实现(源码+文档+部署讲解)
  • 分布式锁: 并发时,redis如何避免删别人的锁
  • 如何用DeepSeek进行项目管理?AI重构项目全生命周期的实践指南
  • C51 Proteus仿真实验17:数码管显示4×4键盘矩阵按键
  • 力扣No.376.摆动序列
  • 【从零开始学习计算机科学】设计模式(一)设计模式概述
  • 蓝桥杯嵌入式赛道复习笔记2(按键控制LED灯,双击按键,单击按键,长按按键)
  • Mysql篇——SQL优化
  • Excel进阶篇:数据透视表详解 数据透视表进阶 切片器 配色
  • 如何使用HACS一键集成米家与果家设备到HomeAssistant玩转智能家居
  • 《我的Python觉醒之路》之转型Python(十五)——控制流
  • 智能化营销:唤醒沉睡客户,驱动企业利润增长
  • C++Qt开发流程图效果,包括保存、加载功能
  • 使用redis客户端中对于json数据格式的存储和读取
  • DR-CAN 卡尔曼滤波笔记
  • leetcode每日一题:使字符串平衡的最小交换次数
  • 【软件工程】06_软件设计
  • Carto 无尽旅图 for Mac v1.0.7.6 (51528)冒险解谜游戏 支持M、Intel芯片
  • 微软 AI 发布 LongRoPE2:近乎无损地将大型语言模型上下文窗口扩展至 128K 标记,保持 97% 短上下文准确性