## 什么是 PostgreSQL PostgreSQL 是一款强调数据可靠性、SQL 能力和可扩展性的开源关系型数据库,尤其适合对数据一致性和复杂业务处理要求较高的系统。 ## PostgreSQL 的主要优势 1. 数据可靠性非常强 ```sql BEGIN; UPDATE account SET balance = balance - 100 WHERE id = 1; UPDATE account SET balance = balance + 100 WHERE id = 2; COMMIT; ``` 2. 复杂 SQL 能力非常强 ```sql WITH ... SELECT ... JOIN ... GROUP BY ... HAVING ... WINDOW FUNCTION ... ``` 3. JSONB 非常好用 ```sql CREATE TABLE users ( id BIGSERIAL PRIMARY KEY, name TEXT, profile JSONB -- { "age": 30, "city": "Shanghai", "tags": ["vip", "developer"] } ); SELECT * FROM users WHERE profile->>'city' = 'Shanghai'; ``` 4. 数据类型非常丰富 5. 扩展生态很强 6. 主从复制和高可用能力成熟 7. MVCC 并发控制成熟 ## 主从复制 **Streaming Replication(流复制)** 是 PostgreSQL 原生提供的主从复制机制,也是 PostgreSQL 做高可用、热备最常见的基础方案。 ``` 服务器 A 服务器 B PostgreSQL Primary PostgreSQL Standby │ │ │ INSERT / UPDATE / DELETE │ ▼ │ 产生 WAL │ │ │ └──── Streaming WAL ────────────►│ ▼ 重放 WAL │ ▼ 数据保持一致 ``` **docker-compose 文件** ```yaml services: postgres: image: postgres:16.13-bookworm container_name: postgres restart: always networks: - common_network ports: - 5432:5432 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: postgres volumes: - postgres:/var/lib/postgresql/data command: - postgres - -c - wal_level=replica - -c - max_wal_senders=10 - -c - max_replication_slots=10 - -c - wal_keep_size=1024MB volumes: postgres: ``` **服务器 A,Primary(主库)** ```sh # 启动主库 docker compose up -d # 进入 postgres docker exec -it postgres psql -U postgres # 创建复制用户 CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD '密码'; # 退出 exit # 查找数据目录,通常是 /var/lib/postgresql/data/pg_hba.conf docker exec postgres psql -U postgres -c "SHOW hba_file;" # 进入容器 docker exec -it postgres bash # 修改主库 echo "host replication replicator 192.168.33.0/24 scram-sha-256" \ >> /var/lib/postgresql/data/pg_hba.conf # 退出 exit # 重新加载 pg_hba docker exec postgres psql -U postgres -c "SELECT pg_reload_conf();" # 检查主库监听,通常返回 * docker exec postgres psql -U postgres -c "SHOW listen_addresses;" ``` **服务器 B,Standby(从库)** ```sh # 创建 volume,这里的 database 一般是当前 docker-compose 文件所在的目录名 docker volume create database_postgres # 初始化从库,全量备份 docker run --rm \ -e PGPASSWORD='密码' \ -v database_postgres:/var/lib/postgresql/data \ postgres:16.13-bookworm \ pg_basebackup \ -h 服务器地址 \ -U replicator \ -D /var/lib/postgresql/data \ -Fp \ -Xs \ -P \ -R # 启动从库 docker compose up -d # 查看日志,检查从库状态 docker logs -f postgres # 正常应该出现类似: # started streaming WAL from primary ``` **检查主从状态** ```sh # 检查主备状态,分别在 服务器A、服务器B 执行 docker exec postgres \ psql -U postgres \ -c "SELECT pg_is_in_recovery();" # 返回值 f (false):表示数据库实例处于正常运行状态(通常是主库)可以进行读写操作 # 返回值 t (true):表示数据库实例正在进行 WAL 日志重放,处于恢复阶段或只读备库状态。 # 主库检查复制状态 docker exec postgres \ psql -U postgres \ -c " SELECT application_name, client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication; " # client_addr | state | sync_state # ---------------+-----------+----------- # 192.168.33.133 | streaming | async # 看到 state 为 streaming,说明配置成功了 ```