PostgreSQL不停机迁移数据

通常涉及到数据迁移,常规操作都是停服务更新。不停机迁移数据是相对比较高级的操作。

不停机数据迁移在本质上,可以视作由三个操作组成:

  • 复制:将目标表从源库逻辑复制到宿库。
  • 改读:将应用读取路径由源库迁移到宿库上。
  • 改写:将应用写入路径由源库迁移到宿库上。

但在实际执行中,这三个步骤可能会有不一样的表现形式。

逻辑复制

使用逻辑复制是比较稳妥的做法,也有几种不同的做法:应用层逻辑复制,数据库自带的逻辑复制(PostgreSQL 10 之后的逻辑订阅),使用第三方逻辑复制插件(例如pglogical)。

几种逻辑复制的方法各有优劣,我们采用了应用层逻辑复制的方式。具体包括四个步骤:

一、复制
  • 在新库中fork老库目标表的模式,以及所有依赖的函数、序列、权限、属主等对象。
  • 应用添加双写逻辑,同时向新库与老库中写入同样数据。
    • 同时向新库与老库写入
  • 保证增量数据正确写入两个一样的库中。
  • 应用需要正确处理全量数据不存在下的删改逻辑。例如改UPDATE为UPSERT,忽略DELETE。
  • 应用读取仍然走老库。
  • 出现问题时,回滚应用至原来的单写版本。

二、同步

  • 老表加上表级排它锁 LOCK TABLE <xxx> IN EXCLUSIVE MODE,阻塞所有写入。
  • 执行全量同步 pg_dump | psql
  • 校验数据一致性,判断迁移是否成功。
  • 出现问题时,简单清空新库中的对应表。
  1. 改读
    • 应用修改为从新库中读取数据。
    • 出现问题时,回滚至从老库中读取的版本。
  2. 单写
    • 观察一段时间无误后,应用修改为仅写入新库。
    • 出现问题时,回滚至双写版本。

说明

关键在于阻塞全量同步期间对老表的写入。这可以通过表级排它锁实现。

在对表进行了分片的情况下,锁表对业务造成的影响非常小。

一张逻辑表拆分成8192个分区,实际上一次只需要处理一个分区。

阻塞对八千分之一的数据写入约几秒到十几秒,业务上通常是可以接受的。

但如果是单张非常大的表,也许就需要特殊处理了。

ETL函数

以下Bash函数接受三个参数,源库URL,宿库URL,以及待迁移的表名。

假设是源宿库都可连接,且目标表都存在。

复制代码
function etl(){
    local src_url=${1}
    local dst_url=${2}
    local table_name=${3}

    rm -rf "/tmp/etl-${table_name}.done"
    
    psql ${src_url} -1qAtc "LOCK TABLE ${table_name} IN EXCLUSIVE MODE;COPY ${table_name} TO STDOUT;" \
    | psql ${dst_url} -1qAtc "LOCK TABLE ${table_name} IN EXCLUSIVE MODE; TRUNCATE ${table_name}; COPY ${table_name} FROM STDIN;"
    
    touch "/tmp/etl-${table_name}.done"
}

实际上虽然锁定了源表与宿表,但在实际测试中,管道退出时前后两个psql进程退出的timing并不是完全同步的。管道前面的进程比后面一个进程早了0.1秒退出。在负载很大的情况下,可能会产生数据不一致。

另一种更科学的做法是按照某一唯一约束列进行切分,锁定相应的行,更新后释放

物理复制

物理复制是通过回放WAL日志实现的复制,是数据库集簇层面的复制。

基于物理复制的迁移粒度很粗,仅适用于垂直分裂库时使用,会有极短暂的服务不可用。

使用物理复制进行数据迁移的流程如下:

  • 复制,从主库拖出一台从库,保持流式复制。
  • 改读:将应用读取路径从主库改为从库,但写入仍然写入主库。
    • 如果有问题,将应用回滚至读主库版本。
  • 改写:将从库提升为主库,阻塞老库的写入,并立即重启应用,切换写入路径至新主库上。
    • 将不需要的表和库删除。
    • 这一步无法回滚(回滚会损失写入新库的数据)
相关推荐
dishugj1 小时前
HANA集群状态监控
数据库·系统架构
小蒜学长2 小时前
基于Java的公司采购系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·公司采购系统
lee_tianbai2 小时前
Java SSM 电影票预定系统|完整前后端项目,开箱即用(源码分享)
java·开发语言·数据库
SM_YHJ2 小时前
RFID通道门禁与资产台账联动的自动登记技术实现方案
大数据·数据库·人工智能
PaperData2 小时前
2014-2024年省级居民消费结构升级
数据库
砚底藏山河2 小时前
python量化入门:多周期数据对齐统一时间轴
java·数据库·python·金融·maven
Java后端的Ai之路2 小时前
昇腾NPU显存管理避坑指南:从npu-smi输出精准识别空闲卡的底层逻辑与实战
服务器·网络·数据库·npu·大模型服务
禾小西2 小时前
05丨Redis 内存快照:宕机后,如何实现快速恢复?
数据库·redis·缓存
笃行3502 小时前
数据同步软件:KFS 在 KingbaseES 项目里到底解决了什么
数据库
AOI小白新手上路3 小时前
视频去雨·论文蒸馏笔记:从物理先验到状态空间模型
数据库·笔记·音视频