MySQL→PostgreSQL 主从架构迁移方案(读写分离版)

目标:用 PostgreSQL 的 WAL + Streaming Replication 实现“写走主、读走从”,并提供生产可用的高可用与连接层方案,附配置模板与运维脚本示例。适配 PostgreSQL 16/17/18。 1. 架构总览 1.1 基础拓扑(最小可用) App(写) ─────────► Primary(主) ╲ ╲ WAL Stream ╲ App(读) ───────────► Standby1(从) ► Standby2(从) 写请求:直连主库。 读请求:直连从库(或通过中间层,见 §4)。 主从:物理复制(Streaming Replication),异步或半同步可选。 1.2 生产级拓扑(推荐) +-------------------+ | pgbouncer | 连接池(减少连接抖动) +-------------------+ │ +--------------+ | Pgpool-II | SQL解析级读写分离/健康检查/故障转移脚本 +--------------+ │ │ (Write) (Read) │ │ Primary ──┬── Standby1 └── Standby2 +-------------------+ | Patroni + etcd | 主从编排/自动故障切换/仲裁 +-------------------+ 可替换 Pgpool-II 为 HAProxy(协议层转发)+ 应用侧读写分离(双 DSN)。 可替换 Patroni 为 repmgr 或手工脚本(风险更高)。 2. 版本与参数基线 推荐版本:PostgreSQL 17(当前成熟稳定)或 18(新项目/前瞻特性)。 最小参数: wal_level = replica(或 logical 若需逻辑复制) max_wal_senders ≥ 从库数 + 维护冗余(例如 10) wal_keep_size:按网络/故障时间留足(例如 512MB~2GB) archive_mode = on + archive_command(若做增量备份/回放) 半同步:synchronous_commit = on + synchronous_standby_names = 'FIRST 1 (standby1, standby2)' 3. 数据层:主从复制配置模板(物理复制) 3.1 主库 postgresql.conf # 基础 listen_addresses = '*' port = 5432 # 复制/WAL wal_level = replica max_wal_senders = 10 max_wal_size = 4GB min_wal_size = 1GB wal_keep_size = 1024MB # 半同步(可选) # synchronous_commit = on # synchronous_standby_names = 'FIRST 1 (standby1, standby2)' # 性能观测(推荐开启) shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.max = 10000 pg_stat_statements.track = all # 归档(如采用 pgBackRest 则由其接管) # archive_mode = on # archive_command = 'test ! -f /var/backup/%f && cp %p /var/backup/%f' 3.2 主库 pg_hba.conf # 允许业务访问 host all appuser 10.0.0.0/16 scram-sha-256 # 允许复制连接(repl 角色) host replication repl 10.0.0.0/16 scram-sha-256 3.3 创建复制用户 CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'REPLACE_WITH_REPL_PASSWORD'; 3.4 从库基线拉起(pg_basebackup) 在 Standby 节点执行: ...

2025-10-09 · 5 分钟 · 913 字 · heyaohua

PostgreSQL Docker 部署常见问题与解决方案

汇总在使用 Docker 部署 PostgreSQL(含 PostGIS、pgvector、TimescaleDB)过程中常见的问题及可操作的解决方案,涵盖构建、扩展、连接、权限、性能与数据等方面。 目录 构建问题 扩展问题 连接问题 权限问题 性能问题 数据问题 调试技巧 预防措施 获取帮助 构建问题 Q1: Docker 构建时出现 “lsb_release: command not found” 问题描述: /bin/sh: 1: lsb_release: command not found /bin/sh: 1: apt-key: command not found 原因分析: 在 Debian/Ubuntu 基础镜像中,lsb_release 和 apt-key 命令可能不存在或已被弃用。 解决方案:改用从源码编译的方式安装 TimescaleDB: # 不使用包管理器安装,改为源码编译 RUN cd /tmp && \ git clone https://github.com/timescale/timescaledb.git && \ cd timescaledb && \ git checkout 2.13.0 && \ ./bootstrap && \ cd build && \ make && \ make install Q2: 编译时出现 “gssapi/gssapi.h: No such file or directory” 问题描述: ...

2025-10-09 · 3 分钟 · 603 字 · heyaohua

PostgreSQL Docker 部署指南

本指南详细介绍如何使用 Docker 部署一个包含 PostGIS、pgvector 和 TimescaleDB 扩展的 PostgreSQL 15 数据库。该方案解决了扩展兼容性问题,特别是 pgvector 的段错误问题。 项目结构 PgSQL/ ├── .env # 环境变量配置 ├── Dockerfile # PostgreSQL 镜像构建文件 ├── docker-compose.yml # Docker Compose 配置 ├── README.md # 项目说明 ├── config/ # 配置文件目录 │ ├── pg_hba.conf # 客户端认证配置 │ └── postgresql.conf # PostgreSQL 主配置 ├── data/ # 数据持久化目录 │ └── pgdata/ # PostgreSQL 数据目录 ├── init-scripts/ # 初始化脚本 │ └── 01-install-extensions.sql # 扩展安装脚本 ├── logs/ # 日志目录 └── test-examples.sql # 测试示例 快速开始 1. 环境准备 确保系统已安装: ...

2025-10-09 · 3 分钟 · 570 字 · heyaohua

MySQL与PostgreSQL全面对比与压测方案

一、MySQL与PostgreSQL对比分析 背景与概述 MySQL长期因轻量和高性能占市场主导,PostgreSQL凭借先进特性和稳定性近年快速崛起,尤其在云原生和复杂业务需求场景中表现出色。 核心技术对比 特性 MySQL PostgreSQL 数据一致性 MVCC,读已提交隔离,异步复制 完备MVCC,默认可重复读,逻辑/流复制 SQL标准兼容与扩展 支持有限,扩展围绕存储引擎 几乎完整支持SQL标准,支持丰富扩展 性能优化 读写分离,高并发读优势 并行查询,分区表,分布式支持日益完善 PostgreSQL使用度超MySQL原因 业务需求提升,复杂事务、分析需求增多 社区活跃,插件和扩展丰富 云服务快速支持,官方生态发展强劲 大型企业和专业领域采用增多 未来前景 数据库 优势场景 未来发展方向 MySQL 简单高并发读写,Web应用 高可用分布式,云原生集成 PostgreSQL 复杂事务,BI报表,地理空间 原生分布式,多模扩展,SQL标准领先 二、Python数据库操作用例 原生驱动 MySQL (PyMySQL) import pymysql conn = pymysql.connect(host='localhost', user='user', password='password', database='testdb') cursor = conn.cursor() cursor.execute("CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) UNIQUE)") cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s)", ('Alice', '[email protected]')) conn.commit() cursor.execute("SELECT * FROM users") print(cursor.fetchall()) cursor.close() conn.close() PostgreSQL (psycopg2) import psycopg2 conn = psycopg2.connect(host='localhost', user='user', password='password', dbname='testdb') cursor = conn.cursor() cursor.execute("CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT, email TEXT UNIQUE)") cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s)", ('Bob', '[email protected]')) conn.commit() cursor.execute("SELECT * FROM users") print(cursor.fetchall()) cursor.close() conn.close() ORM 示例:SQLAlchemy from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String(100)) email = Column(String(100), unique=True) DATABASE_URL = 'postgresql+psycopg2://user:password@localhost:5432/testdb' engine = create_engine(DATABASE_URL) Session = sessionmaker(bind=engine) session = Session() Base.metadata.create_all(engine) new_user = User(name='Carol', email='[email protected]') session.add(new_user) session.commit() users = session.query(User).all() for u in users: print(u.id, u.name, u.email) session.close() 三、数据库压测方案 压测总体流程 环境准备:部署数据库和测试客户端 场景设计:包含OLTP、高并发读写、复杂查询等 基线测试:默认配置性能测量 参数调优:调整配置重复测试 结果分析:整理吞吐、延迟和资源利用数据 自动化脚本:支持快速复用 主要压测工具与命令示例 Sysbench(MySQL) sysbench oltp_read_write \ --db-driver=mysql \ --mysql-host=DB_HOST \ --mysql-user=testuser \ --mysql-password=secret \ --mysql-db=testdb \ --tables=10 \ --table-size=1000000 \ prepare sysbench oltp_read_write --threads=100 --time=300 run sysbench oltp_read_write cleanup pgbench(PostgreSQL) pgbench -h DB_HOST -U testuser -d testdb -i -s 1000 pgbench -h DB_HOST -U testuser -d testdb -c 100 -T 300 -j 4 自定义Python异步压测示例 import asyncio import aiomysql DB_CONFIG = dict(host='DB_HOST', user='testuser', password='secret', db='testdb', minsize=10, maxsize=100) async def task(pool): async with pool.acquire() as conn: async with conn.cursor() as cur: await cur.execute("SELECT COUNT(*) FROM orders WHERE status='pending'") await cur.fetchone() await cur.execute("UPDATE users SET last_login=NOW() WHERE id=%s", (1,)) async def run_load(concurrency, duration): pool = await aiomysql.create_pool(**DB_CONFIG) end_time = asyncio.get_event_loop().time() + duration sem = asyncio.Semaphore(concurrency) async def worker(): async with sem: while asyncio.get_event_loop().time() < end_time: await task(pool) await asyncio.gather(*[worker() for _ in range(concurrency)]) pool.close() await pool.wait_closed() asyncio.run(run_load(concurrency=50, duration=300)) 四、一体化压测脚本模板 #!/bin/bash DB_TYPE=${1:-mysql} DB_HOST="127.0.0.1" DB_PORT_MYSQL=3306 DB_PORT_PG=5432 DB_USER="testuser" DB_PASS="secret" DB_NAME="testdb" CONCURRENCY=(10 50 100) DURATION=120 SCALE=100 function bench_mysql() { sysbench oltp_read_write \ --threads=$1 \ --time=$DURATION \ --db-driver=mysql \ --mysql-host=$DB_HOST \ --mysql-port=$DB_PORT_MYSQL \ --mysql-user=$DB_USER \ --mysql-password=$DB_PASS \ --mysql-db=$DB_NAME run | tee mysql_${1}c.log } function bench_pgsql() { pgbench -h $DB_HOST -p $DB_PORT_PG -U $DB_USER -d $DB_NAME -c $1 -T $DURATION -j $(nproc) | tee pg_${1}c.log } if [[ $DB_TYPE == "pgsql" ]]; then pgbench -h $DB_HOST -p $DB_PORT_PG -U $DB_USER -d $DB_NAME -i -s $SCALE fi for c in "${CONCURRENCY[@]}"; do if [[ $DB_TYPE == "mysql" ]]; then bench_mysql $c else bench_pgsql $c fi done echo "压测完成,查看 *_c.log 文件" 五、压测结果分析与扩展建议 提取日志中的TPS、延迟等数据,生成CSV 使用图表工具(Excel,Grafana,Matplotlib)绘制性能曲线 根据业务需求调整读写比、复杂查询和分布式架构测试 可集成监控系统,实现实时资源指标采样 以上内容系统梳理了MySQL与PostgreSQL的技术对比,Python数据库操作示例,以及一整套可执行的数据库压测方案与脚本,便于用户快速搭建测试环境,评估性能,指导优化与选型。

2024-12-15 · 3 分钟 · 445 字 · heyaohua

PostgreSQL Docker开发环境配置指南

PostgreSQL Docker开发环境配置指南 本文档详细介绍如何使用Docker搭建PostgreSQL开发环境,包括环境配置、启动方式、维护方法等内容。 目录结构 PgSQL_Docker/ ├── .env # 环境变量配置文件 ├── README.md # 项目说明文档 ├── config/ # 配置文件目录 │ ├── pg_hba.conf # 访问控制配置 │ └── postgresql.conf # PostgreSQL主配置文件 ├── data/ # 数据存储目录 └── logs/ # 日志文件目录 配置文件说明 1. docker-compose.yml version: '3.8' services: postgres: container_name: postgres-server image: postgres:15 environment: - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} ports: - "${POSTGRES_PORT}:5432" volumes: - ./data:/var/lib/postgresql/data - ./logs:/var/log/postgresql - ./config/postgresql.conf:/etc/postgresql/postgresql.conf - ./config/pg_hba.conf:/etc/postgresql/pg_hba.conf command: postgres -c 'config_file=/etc/postgresql/postgresql.conf' networks: - postgres-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 start_period: 10s networks: postgres-network: driver: bridge 2. .env 环境变量配置 # PostgreSQL 配置环境变量 POSTGRES_DB=test_db # 数据库名称 POSTGRES_USER=data # 默认超级用户 POSTGRES_PASSWORD=your_password # 用户密码 POSTGRES_PORT=5432 # 端口映射 3. postgresql.conf 主要配置 # 连接设置 listen_addresses = '*' port = 5432 max_connections = 100 # 内存设置 shared_buffers = 128MB work_mem = 4MB maintenance_work_mem = 64MB effective_cache_size = 512MB # 写入设置 wal_level = replica max_wal_size = 1GB min_wal_size = 80MB # 日志设置 log_destination = 'stderr' logging_collector = on log_directory = '/var/log/postgresql' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' log_rotation_age = 1d log_rotation_size = 10MB # 区域设置 datestyle = 'iso, mdy' timezone = 'UTC' lc_messages = 'en_US.utf8' 4. pg_hba.conf 访问控制配置 # TYPE DATABASE USER ADDRESS METHOD local all all trust host all all 127.0.0.1/32 scram-sha-256 host all all ::1/128 scram-sha-256 host all all 0.0.0.0/0 scram-sha-256 使用说明 1. 启动服务 # 启动服务 docker-compose up -d # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs postgres 2. 连接数据库 # 使用超级用户连接 docker-compose exec postgres psql -U data -d test_db # 查看用户列表和权限 \du # 查看数据库列表 \l # 退出psql \q 3. 停止服务 # 停止服务 docker-compose down 用户和权限管理 PostgreSQL使用角色(Role)概念来管理用户权限。在我们的配置中: ...

2024-03-19 · 2 分钟 · 380 字 · heyaohua