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

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

MySQL Docker开发环境配置指南

如何使用Docker启动MySQL开发环境 目录结构 MySQL_Docker/ ├── docker-compose.yml # Docker Compose 配置文件 ├── .env # 环境变量配置 ├── config/ │ └── my.cnf # MySQL 配置文件 ├── data/ # MySQL 数据目录 (挂载) └── logs/ # MySQL 日志目录 (挂载) 配置文件说明 1. docker-compose.yml 配置要点 version: '3.8' services: mysql: image: mysql:8.0 container_name: mysql-server restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123} MYSQL_DATABASE: ${MYSQL_DATABASE:-testdb} MYSQL_USER: ${MYSQL_USER:-testuser} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-testpass} ports: - "${MYSQL_PORT:-3306}:3306" volumes: - ./data:/var/lib/mysql - ./logs:/var/log/mysql - ./config/my.cnf:/etc/mysql/conf.d/my.cnf 重要配置说明: restart: unless-stopped - 容器异常退出时自动重启 environment - 环境变量配置,支持从.env文件读取 volumes - 数据持久化配置,确保数据安全 ports - 端口映射,允许外部访问 2. MySQL配置文件 (my.cnf) 要点 [mysqld] # 基本设置 port = 3306 bind-address = 0.0.0.0 default-storage-engine = InnoDB # 字符集设置(重要) character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # 连接设置 max_connections = 200 max_connect_errors = 10 # 缓冲区设置 innodb_buffer_pool_size = 256M innodb_log_file_size = 64M innodb_log_buffer_size = 16M # 日志设置 log-error = /var/log/mysql/error.log slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 配置注意事项: ...

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