Oracle迁移到PostgreSQL数据库-FGOracle2PG工具

Oracle迁移到PostgreSQL数据库-FGOracle2PG工具

一、程序介绍

1.1 概述

FGOracle2PG 是一款高性能、高可靠的 Oracle 数据库到 PostgreSQL 数据库迁移工具。它由风哥基于多年数据库运维与迁移实战经验开发。工具采用纯 Python 实现,支持命令行(CLI)与可视化 Web 控制台两种操作方式,能够覆盖从开发测试到生产环境的全场景数据库迁移需求。

本工具不仅能够完成表结构(DDL)的自动转换,还能将 Oracle 专有的 PL/SQL 存储过程、函数、包、触发器等对象转换为 PostgreSQL 兼容的 PL/pgSQL 代码,并支持全量数据的高效并行迁移。针对 TB 级大数据迁移场景,工具内置了流式游标、分批读取、断点续传、内存水位控制等机制,确保迁移过程稳定不中断。

1.2 设计目标

  1. 全对象覆盖: 支持 Oracle 所有主要数据库对象的迁移,包括表、视图、索引、序列、触发器、函数、存储过程、包、物化视图、同义词、自定义类型、分区表、表空间、目录、数据库链路、权限、用户等。
  2. 高保真转换: PL/SQL 到 PL/pgSQL 的转换覆盖 DBMS_OUTPUT、SYSDATE、NVL、DECODE、ROWNUM、(+) 外连接、CONNECT BY 等常见语法,最大限度减少人工干预。
  3. 大数据稳定迁移: 通过流式游标、键集分页、内存背压、断点续传等机制,支撑 TB 级表的无中断迁移。
  4. 多数据类型兼容: 正确处理 BLOB、CLOB、NCLOB、LONG、RAW、ROWID、DATE、TIMESTAMP、INTERVAL、NUMBER、BFILE 等 Oracle 特有数据类型,避免乱码与数据丢失。
  5. 双模式操作: 提供命令行与 Web 可视化两种操作方式,满足自动化运维与交互式操作的不同需求。
  6. 可观测性: 全程进度可视化、日志文件记录、错误收集、检查点状态查询,便于问题定位与排查。

1.3 作者信息

作者:风哥
官方网站: http://www.fgedu.net.cn , http://www.itpux.com
数据库教程: https://edu.51cto.com/lecturer/8020378.html

二、功能特性

2.1 对象迁移能力

对象类型 说明
TABLE 表结构 DDL,含列类型映射、主键、唯一约束、检查约束、外键、默认值、注释
DATA 表数据迁移,支持 COPY 批量导入与 INSERT 回退,自动重试
VIEW 视图定义转换,Oracle SQL 语法自动改写
INDEX 索引(B-Tree、位图、函数索引)转换
SEQUENCE 序列定义与当前值(SEQUENCE_VALUES)同步
TRIGGER 触发器转换,PL/SQL 语法改写
FUNCTION 函数 PL/SQL 转 PL/pgSQL
PROCEDURE 存储过程转换
PACKAGE 包拆分为 schema 命名空间 + 独立函数
MVIEW 物化视图定义与刷新策略
SYNONYM 同义词转视图
TYPE 自定义类型(RECORD、TABLE OF、VARRAY 等)
PARTITION 分区表策略(范围、列表、哈希)
TABLESPACE 表空间定义
DIRECTORY DIRECTORY 对象转 file_fdw
DBLINK 数据库链路转 postgres_fdw
GRANT 对象权限与系统权限
USER 用户创建与角色授予
FDW 外部表转 oracle_fdw

2.2 数据类型映射

工具内置完整的 Oracle 到 PostgreSQL 数据类型映射表,并支持以下智能推断:

  • NUMBER(p,0): 精度 p<=4 转 SMALLINT;p<=9 转 INT;p<=18 转 BIGINT;其余转 numeric
  • NUMBER 无精度: 转 numeric
  • DATE: 默认转 TIMESTAMP(Oracle DATE 含时分秒),可配置保留为 date
  • BLOB: 转 bytea,支持二进制安全导入
  • CLOB / NCLOB / LONG: 转 text,UTF-8 解码
  • RAW: 转 bytea
  • ROWID: 转 oid
  • BFILE: 转 text(路径)
  • VARCHAR2 / NVARCHAR2: 转 varchar,长度超过 4000 转 text
  • TIMESTAMP WITH TIME ZONE: 转 timestamptz
  • INTERVAL YEAR TO MONTH / DAY TO SECOND: 转 interval
  • 自定义类型替换: 通过 -D 参数可覆盖任意类型映射

2.3 PL/SQL 转 PL/pgSQL

Oracle 语法 PostgreSQL 语法
DBMS_OUTPUT.PUT_LINE RAISE NOTICE
SYSDATE / SYSTIMESTAMP CURRENT_TIMESTAMP
NVL / NVL2 COALESCE
DECODE CASE WHEN
ROWNUM ROW_NUMBER() OVER ()
(+) 外连接 LEFT / RIGHT JOIN
CONNECT BY WITH RECURSIVE
EXECUTE IMMEDIATE EXECUTE
DBMS_LOB.READ loread
UTL_FILE pg_read_file
TO_DATE / TO_CHAR TO_DATE / TO_CHAR(格式适配)
DUAL 无需(直接 SELECT)
用户自定义错误 RAISE EXCEPTION

2.4 大数据迁移特性

  1. 流式游标: 对超过 large_table_threshold(默认 100 万行)的表启用 oracledb 流式 fetch,避免一次性加载到内存。
  2. 键集分页: 优先使用主键键集分页(WHERE pk > last),复杂度 O(n),避免 OFFSET 大表的 O(n²) 性能问题。
  3. 断点续传: 每批数据写入后保存检查点(主键值或偏移量),中断后重启自动从上次位置继续。
  4. 内存背压: 生产者-消费者队列,当队列积压超过 queue_size 时阻塞读取,防止内存溢出。
  5. 并行迁移: 支持 Oracle 读取并行(-J)、PG 写入并行(-j)、并行表数(-P)三维并行。
  6. COPY 批量导入: 默认使用 PostgreSQL COPY FROM STDIN,比 INSERT 快 10 倍以上,失败自动回退 execute_values。
  7. 大表优先排序: 可选按表大小排序,大表优先迁移以便尽早发现问题。
  8. TB 级规模自适应: 根据预估数据量(100G-5TB)自动应用规模预设(small/medium/large/huge/massive),调整批大小、队列深度、并发度、内存阈值。
  9. 迁移前预检: --pre-check 执行磁盘空间、连接可达性、对象数量、系统内存检查,避免迁移中途失败。
  10. 内存压力监控: 后台线程定期采样 /proc/meminfo 与进程 RSS,达到软上限降速、硬上限强制降级(缩小批大小/并发),防止 OOM。
  11. Oracle 会话保活: 大数据量长查询期间每 60 秒执行 SELECT 1 FROM DUAL,避免被 Oracle resource manager 或防火墙 kill。
  12. PG 会话调优: 批量加载期间临时设置 maintenance_work_memsynchronous_commit=offmax_wal_size=4GBcheckpoint_timeout=30min,减少 WAL 切换与 checkpoint 抖动。
  13. ETA 预估: 实时统计吞吐量(行/秒)与剩余时间预估,便于运维判断进度。
  14. 优雅降级: 内存压力回调自动缩小 batch_insert_size、queue_size、concurrency、copy_chunk_size,压力恢复后自动还原。
  15. 大表分片: 支持 ORA_HASH / MOD 范式分片,将单表拆分为多个分片并行迁移,突破单线程读取瓶颈。

2.5 稳定性与容错

  1. NLS 编码强制 UTF-8: 所有 Oracle 会话设置 NLS_LANGUAGE=AMERICAN、NLS_DATE_FORMAT=ISO 标准,避免中文乱码。
  2. LOB 物化: Oracle LOB 定位器在游标关闭前读取为 bytes/str,避免 LOB 失效报错。
  3. 空字符串转 NULL: Oracle 中 '' 等价于 NULL,PG 不等价;工具自动将 '' 转为 NULL,保证语义一致。
  4. 重试机制: 可重试错误(连接断开、锁超时等)按指数退避自动重试,默认 3 次。
  5. 信号处理: 捕获 SIGINT/SIGTERM,优雅停止并保存检查点,避免数据不一致。
  6. 资源管理: 统一关闭连接池、游标、文件句柄,防止资源泄漏。
  7. 错误分类: 区分可重试错误与致命错误,避免无意义重试。
  8. 事务保护: 每批数据独立事务,失败时回滚当前批次但不影响已提交批次。

2.6 高级功能

  1. SCN 闪回查询: 通过 --scn 参数指定系统变更号,实现一致性快照读取或回滚后重试。
  2. CDC 增量同步: 记录 SCN 文件,支持基于日志的增量变更捕获配置。
  3. 数据库差异对比: TEST/TEST_COUNT/TEST_DATA 模式对比 Oracle 与 PG 的表结构与行数差异。
  4. 迁移评估报告: assess 子命令扫描 Oracle schema,生成迁移难度评分与人工干预清单。
  5. 项目模板生成: init_project 子命令生成标准迁移项目目录结构。
  6. Kettle 模板: KETTLE 类型生成 Pentaho Kettle ktr 文件,便于 ETL 工具集成。
  7. SQL 查询转换: QUERY 类型将 Oracle SQL 文件批量转为 PG 语法。
  8. 批量 SQL 执行: LOAD 类型并行执行 SQL 文件中的多条语句。
  9. 对象过滤: -a/--allow 白名单、-e/--exclude 黑名单,按对象名过滤。
  10. WHERE 条件: -W 全局 WHERE 条件、where_clauses 按表过滤数据。
  11. 列/表重命名: --rename-column、--rename-table 在迁移时重命名对象。
  12. DEFINED_PK: 为无主键表指定分片列,启用键集分页。
  13. FDW 集成: 支持 oracle_fdw 配置生成、外部表导入导出。

三、支持环境

3.1 操作系统

  • Linux(CentOS 7+、Ubuntu 18.04+、Debian 10+、Red Hat 7+、麒麟、统信 UOS)
  • Windows 10/11、Windows Server 2016+
  • macOS 10.15+

3.2 Python 环境

  • Python 3.8 及以上版本(推荐 3.9/3.10/3.11)
  • 依赖包:
    • oracledb >= 1.4.0(Oracle 驱动,thin 模式免客户端)
    • psycopg2-binary >= 2.9.0(PostgreSQL 驱动)
    • PyYAML >= 6.0(配置解析)
    • Flask >= 2.0.0(Web 可视化控制台)

3.3 数据库版本

  • 源端 Oracle: Oracle 11g R2 / 12c / 18c / 19c / 21c /26ai
  • 目标 PostgreSQL: PostgreSQL 10 / 11 / 12 / 13 / 14 / 15 / 16+
  • 兼容衍生库: HighGo、ChinaDB、openGauss、MogDB、PolarDB-PG、Greenplum、YugabyteDB

3.4 网络要求

  • Oracle 端口默认 1521 可达
  • PostgreSQL 端口默认 5432 可达
  • 网络延迟建议小于 10ms(大数据迁移场景)
  • 带宽建议大于 100Mbps

四、程序使用

4.1 安装

# 克隆或解压项目
cd /path/to/FGOracle2PG

# 安装依赖
pip install -r requirements.txt

# 验证安装
python3 fgoracle2pg.py --help

4.2 配置文件

复制 config.example.yml 为 config.yml,按实际环境修改:

oracle:
  host: "192.168.1.100"
  port: 1521
  username: "system"
  password: "oracle"
  database: "ORCL"
  schema: "SCOTT"
  mode: "thin"              # thin=免客户端; thick=需 Instant Client

postgresql:
  host: "192.168.1.200"
  port: 5432
  username: "postgres"
  password: "postgres"
  database: "target_db"
  schema: "public"

conversion:
  options:
    tableddl: true
    data: true
    indexes: true
    sequences: true
    # 其他对象按需开启
  limits:
    concurrency: 10
    batch_insert_size: 50000
    checkpoint_dir: "./.checkpoint"

4.3 命令行操作

4.3.1 全局参数

-c, --config    配置文件路径(默认 config.yml)
-h, --help      帮助信息
--version       版本信息

4.3.2 子命令

子命令 说明
test 测试 Oracle/PG 连接
convert 执行转换(DDL + 数据 + PL/SQL)
assess 评估迁移难度
report 生成评估报告
web 启动可视化控制台
plsql2pgsql PL/SQL 文件转 PL/pgSQL
assess_file 评估 PL/SQL 文件迁移难度
init_project 生成项目模板
diff 数据库差异对比

4.3.3 convert 子命令参数

-t, --type          导出类型(见下表)
-a, --allow         允许对象列表(逗号分隔)
-e, --exclude       排除对象列表(逗号分隔)
-b, --basedir       输出基准目录
-o, --outfile       输出文件名
-i, --input         输入 SQL 文件(QUERY/LOAD 用)
-L, --logfile       日志文件路径
-p, --parallel-jobs PG 写入并行度
-P, --parallel-tables 并行表数
-J, --oracle-readers  Oracle 读取并行度
-S, --scn           SCN 闪回查询
-D, --type-map      自定义类型映射
-O, --oracle-schema 覆盖 Oracle schema
-W, --where         数据导出 WHERE 条件
--no-blob           跳过 BLOB 列
--no-clob           跳过 CLOB 列
--rename-column     列重命名
--rename-table      表重命名
--defined-pk        定义主键列用于并行分片
--parallel-degree   Oracle 并行查询提示度
--defer-constraints 延迟约束检查
--no-function-check 关闭函数体检查
--data-order        数据导出顺序(name/size)

4.3.4 导出类型一览

类型 说明
TABLE 表结构
DATA / COPY / INSERT 数据
VIEW 视图
INDEX 索引
SEQUENCE 序列
TRIGGER 触发器
FUNCTION / PROCEDURE 函数/存储过程
PACKAGE
MVIEW 物化视图
SYNONYM 同义词
TYPE 自定义类型
PARTITION 分区
TABLESPACE 表空间
DIRECTORY 目录
DBLINK 数据库链路
GRANT 权限
USER 用户
FDW FDW 外部表
SHOW_VERSION 显示 Oracle 版本
SHOW_SCHEMA 显示 Schema 列表
SHOW_TABLE 显示表列表
SHOW_COLUMN 显示列与类型映射
SHOW_ENCODING 显示编码信息
SHOW_REPORT 生成迁移评估报告
TEST 数据库差异对比
TEST_COUNT 行数对比
TEST_VIEW 视图行数对比
TEST_DATA 数据内容校验
SEQUENCE_VALUES 序列值设置
LOAD 分发查询执行
QUERY SQL 查询转换
KETTLE Kettle ktr 模板生成
ALL 全部对象

4.4 可视化操作

4.4.1 启动 Web 控制台

前台运行(终端关闭即停止):

python3 fgoracle2pg.py web -c config.yml
# 或指定端口
python3 fgoracle2pg.py web -c config.yml --host 0.0.0.0 --port 5052

后台守护进程运行(推荐,终端关闭不影响):

# 启动(后台运行,PID 与日志记录到 .runtime/ 目录)
python3 web_manager.py start -c config.yml --port 5052

# 查看运行状态(PID、内存、CPU、运行时长、端口可达性)
python3 web_manager.py status --port 5052

# 查看日志(默认最后 100 行)
python3 web_manager.py log --port 5052
python3 web_manager.py log --port 5052 -n 500

# 停止
python3 web_manager.py stop --port 5052

# 重启
python3 web_manager.py restart -c config.yml --port 5052

# 调试模式启动
python3 web_manager.py start -c config.yml --port 5052 --debug

浏览器访问 http://服务器IP:5052

web_manager.py 子命令说明:

子命令 说明
start 后台启动 Web 控制台,PID 写入 .runtime/web_PORT.pid
stop 优雅停止(SIGTERM,超时后 SIGKILL)
restart 先停止再启动
status 查看运行状态、PID、内存、CPU、运行时长
log 查看最近日志(-n 指定行数)

4.4.2 Web 控制台功能

  1. 配置管理: 在线编辑 Oracle/PG 连接配置,保存与加载配置文件。
  2. 连接测试: 一键测试 Oracle 与 PostgreSQL 连接是否正常。
  3. 迁移评估: 触发评估扫描,查看迁移难度报告。
  4. 转换执行: 选择导出类型与对象过滤,启动转换任务,实时查看进度。
  5. 实时日志: 通过 SSE 推送实时转换日志到浏览器。
  6. 检查点管理: 查看断点续传状态,清除检查点重新开始。
  7. PL/SQL 工具: 在线转换 PL/SQL 代码或文件,评估迁移难度。
  8. 数据库对比: 对比 Oracle 与 PG 的表结构与行数差异。
  9. 对象浏览: 浏览 Oracle 的表、视图、函数列表。
  10. 项目模板: 生成标准迁移项目目录结构。

五、程序各种案例场景与操作过程

5.1 场景一: Oracle迁移到PostgreSQL数据库-全量迁移(命令行)

需求: 将 SCOTT schema 全部对象迁移到 PG 的 public schema。

# 1. 测试连接
python3 fgoracle2pg.py test -c config.yml

# 2. 评估迁移难度
python3 fgoracle2pg.py assess -c config.yml -o assessment.txt

# 3. 执行全量迁移
python3 fgoracle2pg.py convert -c config.yml -t ALL

# 4. 验证数据一致性
python3 fgoracle2pg.py convert -c config.yml -t TEST_COUNT

5.2 场景二: Oracle迁移到PostgreSQL数据库-仅迁移表结构(命令行)

python3 fgoracle2pg.py convert -c config.yml -t TABLE

5.3 场景三: Oracle迁移到PostgreSQL数据库-仅迁移指定表的数据(命令行)

# 仅迁移 EMP, DEPT, SALGRADE 三张表
python3 fgoracle2pg.py convert -c config.yml -t DATA -a EMP,DEPT,SALGRADE

5.4 场景四: Oracle迁移到PostgreSQL数据库-排除大表迁移(命令行)

# 排除 LOG_TABLE 和 TEMP_DATA
python3 fgoracle2pg.py convert -c config.yml -t DATA -e LOG_TABLE,TEMP_DATA

5.5 场景五: Oracle迁移到PostgreSQL数据库-大表并行迁移(命令行)

# 8 个 PG 写入线程,4 个 Oracle 读取线程,2 张表并行
python3 fgoracle2pg.py convert -c config.yml -t DATA \
    -p 8 -J 4 -P 2

5.6 场景六: Oracle迁移到PostgreSQL数据库-SCN 闪回一致性读取(命令行)

# 获取当前 SCN
python3 fgoracle2pg.py convert -c config.yml -t SHOW_VERSION

# 指定 SCN 闪回查询,保证一致性快照
python3 fgoracle2pg.py convert -c config.yml -t DATA -S 1234567890

5.7 场景七: Oracle迁移到PostgreSQL数据库-自定义类型映射(命令行)

# NUMBER 全部转 numeric,DATE 转 date
python3 fgoracle2pg.py convert -c config.yml -t TABLE \
    -D NUMBER:numeric,DATE:date

5.8 场景八: Oracle迁移到PostgreSQL数据库-跳过 LOB 列(命令行)

# 跳过 BLOB 和 CLOB 列(仅迁移普通列数据)
python3 fgoracle2pg.py convert -c config.yml -t DATA \
    --no-blob --no-clob

5.9 场景九: Oracle迁移到PostgreSQL数据库-带条件的数据迁移(命令行)

# 仅迁移 2024 年以后的数据
python3 fgoracle2pg.py convert -c config.yml -t DATA \
    -W "create_time >= TO_DATE('2024-01-01','YYYY-MM-DD')"

5.10 场景十: Oracle迁移到PostgreSQL数据库-列重命名(命令行)

# EMP 表的 EMPNO 列重命名为 emp_id
python3 fgoracle2pg.py convert -c config.yml -t ALL \
    --rename-column "EMP.EMPNO:emp_id"

5.11 场景十一: Oracle迁移到PostgreSQL数据库-PL/SQL 文件转换(命令行)

# 转换单个文件
python3 fgoracle2pg.py plsql2pgsql -c config.yml \
    -i procedure.prc -o procedure.sql

# 评估文件迁移难度
python3 fgoracle2pg.py assess_file -c config.yml -i procedure.prc

5.12 场景十二: Oracle迁移到PostgreSQL数据库-数据库差异对比(命令行)

# 全量对比
python3 fgoracle2pg.py convert -c config.yml -t TEST

# 仅行数对比
python3 fgoracle2pg.py convert -c config.yml -t TEST_COUNT

5.13 场景十三: 生成 Kettle 模板(命令行)

python3 fgoracle2pg.py convert -c config.yml -t KETTLE -b ./kettle_jobs

5.14 场景十四: 生成项目模板(命令行)

python3 fgoracle2pg.py init_project -c config.yml -o ./my_migration

5.15 场景十五: 断点续传(命令行)

# 首次迁移被中断
python3 fgoracle2pg.py convert -c config.yml -t DATA

# 直接重新执行,自动从断点继续
python3 fgoracle2pg.py convert -c config.yml -t DATA

# 清除检查点重新开始
rm -rf ./.checkpoint
python3 fgoracle2pg.py convert -c config.yml -t DATA

5.16 场景十六: Oracle迁移到PostgreSQL数据库-全量迁移(可视化操作)

  1. 启动 Web 控制台: python3 fgoracle2pg.py web -c config.yml
  2. 浏览器打开 http://localhost:5052
  3. 在「配置」页签确认 Oracle 与 PG 连接信息。
  4. 点击「测试连接」验证两端可达。
  5. 切换到「评估」页签,点击「开始评估」,查看难度报告。
  6. 切换到「转换」页签,选择导出类型为「ALL」。
  7. 点击「开始转换」,在「日志」页签实时查看进度。
  8. 转换完成后,切换到「对比」页签,执行差异对比。

5.17 场景十七: Oracle迁移到PostgreSQL数据库-PL/SQL 在线转换(可视化操作)

  1. 启动 Web 控制台。
  2. 切换到「PL/SQL 工具」页签。
  3. 在左侧文本框粘贴 PL/SQL 代码。
  4. 点击「转换」,右侧显示转换后的 PL/pgSQL。
  5. 可点击「评估」查看转换难度与人工修改建议。

5.18 场景十八: 检查点管理(可视化操作)

  1. 启动 Web 控制台。
  2. 切换到「检查点」页签。
  3. 查看各表的迁移进度(已迁移行数/总行数)。
  4. 如需重新迁移某张表,点击「清除」删除该表检查点。

5.19 场景十九: 查看数据库对象(可视化操作)

  1. 启动 Web 控制台。
  2. 切换到「对象浏览」页签。
  3. 选择对象类型(表/视图/函数)。
  4. 浏览 Oracle 中的对象列表与定义。

5.20 场景二十: 仅迁移存储过程(可视化操作)

  1. 启动 Web 控制台。
  2. 在「转换」页签选择导出类型为「FUNCTION」。
  3. 在「允许对象」中输入需迁移的函数名(逗号分隔)。
  4. 点击「开始转换」。

5.21 场景二十一: Oracle迁移到PostgreSQL数据库-100GB 数据库迁移(命令行)

需求: 将约 100GB 的 Oracle 业务库迁移到 PostgreSQL,包含若干千万行级大表。

步骤:

# 1. 迁移前预检(检查磁盘空间、连接、对象数量)
python3 fgoracle2pg.py convert -c config.yml --estimated-gb 100 --pre-check

# 2. 启用规模预设 large(100-500GB)并执行迁移
python3 fgoracle2pg.py convert -c config.yml \
    --estimated-gb 100 \
    --auto-scale \
    --data-order size \
    -j 10

# 3. 如中途中断,直接重新执行即可自动断点续传
python3 fgoracle2pg.py convert -c config.yml \
    --estimated-gb 100 \
    --auto-scale \
    --data-order size \
    -j 10

关键点:

  • --auto-scale 自动将 memory_limit_mb 调到 2048、copy_chunk_size 调到 100000
  • --data-order size 让大表优先迁移,尽早暴露问题
  • 断点续传默认启用(checkpoint_dir 配置项),中断后重启自动继续

5.22 场景二十二: Oracle迁移到PostgreSQL数据库-1TB 数据库迁移(命令行)

需求: 将约 1TB 的 Oracle 数据仓库迁移到 PostgreSQL,包含多张亿行级事实表。

步骤:

# 1. 先仅迁移表结构(避免数据迁移时才发现 DDL 问题)
python3 fgoracle2pg.py convert -c config.yml --type TABLE

# 2. 迁移前预检
python3 fgoracle2pg.py convert -c config.yml \
    --estimated-gb 1024 --pre-check

# 3. 分批迁移数据(按表分组,先迁大表)
# 3.1 先迁移最大的事实表(启用并行读取)
python3 fgoracle2pg.py convert -c config.yml \
    --type DATA \
    --allow FACT_SALES,FACT_ORDERS \
    --estimated-gb 800 \
    --auto-scale \
    --data-order size \
    -j 12 \
    -J 2

# 3.2 再迁移中小表
python3 fgoracle2pg.py convert -c config.yml \
    --type DATA \
    --exclude FACT_SALES,FACT_ORDERS \
    --estimated-gb 200 \
    --auto-scale \
    -j 8

# 4. 迁移索引、约束、视图等后续对象
python3 fgoracle2pg.py convert -c config.yml --type INDEX
python3 fgoracle2pg.py convert -c config.yml --type VIEW
python3 fgoracle2pg.py convert -c config.yml --type FUNCTION
python3 fgoracle2pg.py convert -c config.yml --type SEQUENCE
python3 fgoracle2pg.py convert -c config.yml --type TRIGGER

# 5. 数据一致性校验
python3 fgoracle2pg.py convert -c config.yml --type TEST_COUNT

关键点:

  • --scale-preset huge--auto-scale 自动将 oracle_readers 调到 2、memory_limit_mb 调到 4096
  • 分阶段迁移:先 DDL,再大表数据,再中小表数据,最后索引/约束
  • 索引在数据迁移后创建,比先建索引再插数据快数倍
  • PG 端建议预先调大 max_wal_sizemaintenance_work_mem

5.23 场景二十三: Oracle迁移到PostgreSQL数据库-5TB 超大数据库迁移(命令行)

需求: 将约 5TB 的 Oracle 生产库迁移到 PostgreSQL,单表最大 2TB,需在 48 小时内完成。

步骤:

# 1. 预检(确认磁盘空间 >= 7.5TB = 5TB * 1.5 倍冗余)
python3 fgoracle2pg.py convert -c config.yml \
    --estimated-gb 5120 --pre-check

# 2. 迁移表结构
python3 fgoracle2pg.py convert -c config.yml --type TABLE

# 3. 直接指定 massive 预设(极限模式)
python3 fgoracle2pg.py convert -c config.yml \
    --type DATA \
    --scale-preset massive \
    --data-order size \
    -j 8 \
    -J 4 \
    -P 2

# 4. 迁移过程中断后,断点续传
python3 fgoracle2pg.py convert -c config.yml \
    --type DATA \
    --scale-preset massive \
    --data-order size \
    -j 8 \
    -J 4 \
    -P 2

# 5. 后续对象
python3 fgoracle2pg.py convert -c config.yml --type INDEX
python3 fgoracle2pg.py convert -c config.yml --type CONSTRAINT
python3 fgoracle2pg.py convert -c config.yml --type VIEW
python3 fgoracle2pg.py convert -c config.yml --type FUNCTION
python3 fgoracle2pg.py convert -c config.yml --type SEQUENCE
python3 fgoracle2pg.py convert -c config.yml --type TRIGGER

# 6. 数据校验
python3 fgoracle2pg.py convert -c config.yml --type TEST_COUNT
python3 fgoracle2pg.py convert -c config.yml --type TEST_DATA --allow CRITICAL_TABLE

massive 预设参数:

参数 说明
batch_insert_size 100000 单批写入行数
queue_size 8 生产者-消费者队列深度
memory_limit_mb 4096 内存软上限
memory_hard_limit_mb 8192 内存硬上限
copy_chunk_size 200000 COPY 单次行数
concurrency 8 PG 写入并发(降低,避免 Oracle 压力)
oracle_readers 4 Oracle 读取并行度
parallel_tables 2 同时迁移表数
huge_table_threshold 1,000,000 100 万行即走流式管道

5TB 迁移运维建议:

  • PG 端预先调整: max_wal_size=16GBcheckpoint_timeout=30minwal_compression=on
  • 监控 PG WAL 目录增长,避免磁盘写满
  • 迁移期间禁用 PG 自动 vacuum: ALTER TABLE xxx SET (autovacuum_enabled = false)
  • 迁移完成后手动 ANALYZE 全部表
  • 准备归档: 5TB 数据迁移期间 Oracle 归档日志可能达数 TB

5.24 场景二十四: Oracle迁移到PostgreSQL数据库-大数据迁移(可视化操作)

需求: 通过 Web 控制台迁移 500GB 数据库。

步骤:

# 1. 后台启动 Web 控制台
python3 web_manager.py start -c config.yml --port 5052

# 2. 查看状态
python3 web_manager.py status --port 5052
  1. 浏览器访问 http://服务器IP:5052
  2. 在「配置」页签确认 Oracle/PG 连接参数正确,点击「测试连接」。
  3. 在「评估」页签点击「开始评估」,查看对象数量与迁移难度。
  4. 在「转换」页签:
    • 导出类型选择「ALL」
    • 在「预估数据量(GB)」输入 500
    • 勾选「自动规模调优」
    • 数据顺序选择「按大小」
    • 点击「开始转换」
  5. 在「日志」页签实时查看进度,包括:
    • 当前阶段(表结构/数据/索引/...)
    • 各表迁移行数与百分比
    • 内存使用与吞吐量
  6. 如需中断,点击「停止」;恢复时直接重新点击「开始转换」,自动断点续传。
  7. 转换完成后,在「对比」页签执行行数对比验证。
# 3. 迁移完成后停止 Web 控制台
python3 web_manager.py stop --port 5052

5.25 场景二十五: Oracle迁移到PostgreSQL数据库-大表分片并行迁移(命令行)

需求: 单表 5 亿行(约 500GB),需在 6 小时内完成迁移。

步骤:

# 1. 迁移表结构
python3 fgoracle2pg.py convert -c config.yml --type TABLE --allow BIG_TABLE

# 2. 使用 defined_pk 指定分片列(无主键时)
# 3. 使用并行读取与多会话
python3 fgoracle2pg.py convert -c config.yml \
    --type DATA \
    --allow BIG_TABLE \
    --defined-pk "BIG_TABLE:ID" \
    --scale-preset huge \
    -j 8 \
    -J 4 \
    -P 1

# 4. 迁移索引
python3 fgoracle2pg.py convert -c config.yml --type INDEX --allow BIG_TABLE

关键点:

  • -J 4 启用 4 个 Oracle 读取线程,配合键集分页实现并行读取
  • --defined-pk 为无主键表指定分片列,启用键集分页
  • 单表迁移时 -P 1(不并行多表),将并行度全部用于单表读取

六、常用问题与排查

6.1 连接问题

Q1: Oracle 连接报错 "ORA-12541: TNS:no listener"

  • 检查 Oracle 监听器是否启动: lsnrctl status
  • 检查 host 与 port 配置是否正确。
  • 检查防火墙是否放行 1521 端口。

Q2: Oracle 连接报错 "ORA-12154: TNS:无法解析指定的连接标识符"

  • 确认 database 配置的是 SID 还是服务名。
  • 若使用服务名,设置 service_name 字段或 database 以 / 开头。
  • thin 模式无需 tnsnames.ora,直接用 host:port/service_name。

Q3: PostgreSQL 连接报错 "connection refused"

  • 检查 pg_hba.conf 是否允许来源 IP。
  • 检查 postgresql.conf 中 listen_addresses 是否为 '*'。
  • 确认密码与端口配置正确。

Q4: oracledb 报错 "DPY-4005: cannot connect to database"

  • thin 模式不支持某些老版本 Oracle(11.2.0.1)。
  • 升级 Oracle 到 11.2.0.4+ 或使用 thick 模式。
  • thick 模式需安装 Instant Client 并配置 lib_dir。

6.2 编码问题

Q5: 迁移后中文乱码

  • 确认 Oracle 数据库字符集为 AL32UTF8 或 ZHS16GBK。
  • 工具会自动设置 NLS 为 UTF-8,无需手动配置 NLS_LANG。
  • 若仍乱码,检查终端编码与日志文件编码是否为 UTF-8。
  • 查看: python3 fgoracle2pg.py convert -c config.yml -t SHOW_ENCODING

Q6: CLOB 字段内容截断

  • 确认未启用 --no-clob。
  • 检查目标列类型是否为 text(非 varchar)。
  • 查看 errors.log 是否有 LOB 读取错误。

6.3 数据迁移问题

Q7: 大表迁移内存溢出 (OOM)

  • 降低 batch_insert_size(如 10000)。
  • 降低 concurrency 并行度。
  • 启用 streaming_cursor(默认已启用)。
  • 降低 queue_size(如 2)减少队列积压。
  • 设置 memory_hard_limit_mb 限制内存上限。

Q8: COPY 报错 "invalid byte sequence for encoding UTF8"

  • 数据中包含非 UTF-8 字节,多为 Windows 编码脏数据。
  • 使用 -t SHOW_ENCODING 检查 Oracle 字符集。
  • 清洗源数据中的非法字符后重试。

Q9: 迁移中断后如何续传

  • 直接重新执行相同命令,工具自动从检查点继续。
  • 检查点目录默认为 ./.checkpoint,勿手动删除。
  • 若需重新开始,删除检查点目录后重试。

Q10: 数据行数不一致

  • 使用 TEST_COUNT 对比行数。
  • 检查 WHERE 条件是否过滤了数据。
  • 检查 empty_string_as_null 是否影响唯一约束。
  • 检查 Oracle 是否有未提交事务(一致性读取问题)。

6.4 PL/SQL 转换问题

Q11: 函数创建报错 "syntax error at or near"

  • 使用 assess_file 评估文件难度,查看需人工修改的项。
  • 常见问题: Oracle 包变量、自治事务、DBMS_SQL 动态游标需手工适配。
  • 关闭函数体检查: --no-function-check,先创建再调试。

Q12: 触发器转换后不工作

  • Oracle 触发器可跨行触发,PG 需用语句级触发器或 FOR EACH ROW。
  • 检查 :NEW / :OLD 引用是否正确转换。
  • 复合触发器需拆分为多个触发器。

6.5 性能问题

Q13: 迁移速度慢

  • 提高 concurrency 并行度(如 10-20)。
  • 提高 oracle_readers 读取并行度。
  • 确认使用 COPY 而非 INSERT(查看日志)。
  • 提高 batch_insert_size(如 100000)。
  • 使用 --data-order size 大表优先。
  • 检查网络带宽是否瓶颈。

Q14: Oracle 端 CPU 飙高

  • 降低 oracle_readers 并行度。
  • 降低 parallel_degree(Oracle 并行查询提示)。
  • 在非高峰期执行迁移。

Q15: PG 端磁盘 IO 瓶颈

  • 临时提高 maintenance_work_mem 加速索引创建。
  • 分阶段迁移:先数据后索引。
  • 考虑在迁移期间临时关闭 fsync(仅测试环境)。

6.6 其他问题

Q16: Web 控制台无法访问

  • 确认监听地址为 0.0.0.0 而非 127.0.0.1。
  • 检查防火墙是否放行 5052 端口。
  • 查看 Web 启动日志是否有端口冲突。

Q17: 检查点目录损坏

  • 删除 ./.checkpoint 目录重新开始。
  • 检查磁盘空间是否充足。

Q18: 如何查看详细日志

  • 日志文件默认为 ./conversion.log。
  • 错误日志默认为 ./errors.log。
  • Web 控制台「日志」页签实时查看。

Q19: 如何只导出 DDL 不执行

  • 使用 -t TABLE -o output.sql 输出到文件。
  • 或设置 conversion.options.data: false。

Q20: 如何支持 Greenplum / YugabyteDB

  • 配置 mpp.enabled: true。
  • mpp.database: greenplum 或 yugabyte。
  • 工具会自动适配分布式特性。

6.7 大数据迁移问题(100G-5TB)

Q21: 迁移过程中 OOM(内存溢出)

  • 使用 --memory-limit 1024 --memory-hard-limit 2048 降低内存阈值。
  • 降低 batch_insert_size(如 50000 → 20000)。
  • 降低 queue_size(如 4 → 2)。
  • 启用 --auto-scale 让工具自动选择合适参数。
  • 检查是否有特别宽的表(列数多、LOB 列大),使用 --no-blob --no-clob 跳过 LOB。

Q22: 迁移过程中 Oracle 连接断开(ORA-03113/03114)

  • 工具内置 Oracle 会话保活(每 60 秒 SELECT 1 FROM DUAL)。
  • 检查 Oracle sqlnet.ora 的 SQLNET.EXPIRE_TIME 设置。
  • 检查防火墙空闲连接超时设置。
  • 降低 oracle_readers 并行度,减轻 Oracle 连接压力。
  • 使用断点续传:中断后直接重新执行,自动继续。

Q23: PG 端 WAL 目录写满磁盘

  • 临时调大 max_wal_size(如 SET max_wal_size='16GB')。
  • 调大 checkpoint_timeout(如 SET checkpoint_timeout='30min')。
  • 迁移期间关闭 synchronous_commit(工具自动设置)。
  • 检查 PG 归档是否正常(如启用了归档模式)。
  • 分批迁移,避免单次写入过多数据。

Q24: 迁移速度远低于预期

  • 使用 --pre-check 确认磁盘 IO 与网络带宽。
  • 确认 PG 使用 COPY 而非 INSERT(查看日志)。
  • 提高并发度: -j 12 -J 4 -P 2
  • 使用 --scale-preset hugemassive 应用极限参数。
  • 检查 Oracle 端是否存在锁等待或长事务。
  • 检查 PG 端是否存在 autovacuum 阻塞(迁移期间可临时禁用)。
  • 使用 --data-order size 让大表优先,避免小表挤占并发槽。

Q25: 断点续传失败或不识别

  • 确认 limits.checkpoint_dir 配置项已设置且目录可写。
  • 检查点目录磁盘空间是否充足。
  • 检查点文件为 JSON 格式,可手动查看内容。
  • 如损坏,删除该表的检查点文件,该表将重新迁移。
  • 全量清除: 删除整个 .checkpoint 目录重新开始。

Q26: 5TB 迁移中途磁盘空间不足

  • 预检时使用 --estimated-gb 5120 --pre-check 确认空间(需要 1.5 倍冗余)。
  • PG 端检查 pg_wal 目录大小,必要时增大 max_wal_size
  • 清理 PG 端临时表、旧数据。
  • 分阶段迁移:先迁移部分大表,确认空间后再继续。
  • 考虑在迁移期间临时禁用 PG 归档(需评估数据安全)。

Q27: Web 控制台在大数据迁移期间无响应

  • 使用 web_manager.py 后台运行而非前台 web 命令。
  • 使用 web_manager.py status 检查进程内存与 CPU。
  • 使用 web_manager.py log -n 500 查看最新日志。
  • 大数据迁移期间 SSE 事件可能积压,降低 Web 刷新频率。
  • 必要时重启 Web 控制台: web_manager.py restart(不影响正在进行的命令行迁移)。

作者:风哥
官方网站: http://www.fgedu.net.cn , http://www.itpux.com
数据库教程: https://edu.51cto.com/lecturer/8020378.html

posted @ 2026-08-31 19:30  风哥数据库教程  阅读(4)  评论(0)    收藏  举报