Oracle迁移到PostgreSQL数据库-FGOracle2PG工具
Oracle迁移到PostgreSQL数据库-FGOracle2PG工具
一、程序介绍
1.1 概述
FGOracle2PG 是一款高性能、高可靠的 Oracle 数据库到 PostgreSQL 数据库迁移工具。它由风哥基于多年数据库运维与迁移实战经验开发。工具采用纯 Python 实现,支持命令行(CLI)与可视化 Web 控制台两种操作方式,能够覆盖从开发测试到生产环境的全场景数据库迁移需求。
本工具不仅能够完成表结构(DDL)的自动转换,还能将 Oracle 专有的 PL/SQL 存储过程、函数、包、触发器等对象转换为 PostgreSQL 兼容的 PL/pgSQL 代码,并支持全量数据的高效并行迁移。针对 TB 级大数据迁移场景,工具内置了流式游标、分批读取、断点续传、内存水位控制等机制,确保迁移过程稳定不中断。
1.2 设计目标
- 全对象覆盖: 支持 Oracle 所有主要数据库对象的迁移,包括表、视图、索引、序列、触发器、函数、存储过程、包、物化视图、同义词、自定义类型、分区表、表空间、目录、数据库链路、权限、用户等。
- 高保真转换: PL/SQL 到 PL/pgSQL 的转换覆盖 DBMS_OUTPUT、SYSDATE、NVL、DECODE、ROWNUM、(+) 外连接、CONNECT BY 等常见语法,最大限度减少人工干预。
- 大数据稳定迁移: 通过流式游标、键集分页、内存背压、断点续传等机制,支撑 TB 级表的无中断迁移。
- 多数据类型兼容: 正确处理 BLOB、CLOB、NCLOB、LONG、RAW、ROWID、DATE、TIMESTAMP、INTERVAL、NUMBER、BFILE 等 Oracle 特有数据类型,避免乱码与数据丢失。
- 双模式操作: 提供命令行与 Web 可视化两种操作方式,满足自动化运维与交互式操作的不同需求。
- 可观测性: 全程进度可视化、日志文件记录、错误收集、检查点状态查询,便于问题定位与排查。
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 大数据迁移特性
- 流式游标: 对超过 large_table_threshold(默认 100 万行)的表启用 oracledb 流式 fetch,避免一次性加载到内存。
- 键集分页: 优先使用主键键集分页(WHERE pk > last),复杂度 O(n),避免 OFFSET 大表的 O(n²) 性能问题。
- 断点续传: 每批数据写入后保存检查点(主键值或偏移量),中断后重启自动从上次位置继续。
- 内存背压: 生产者-消费者队列,当队列积压超过 queue_size 时阻塞读取,防止内存溢出。
- 并行迁移: 支持 Oracle 读取并行(-J)、PG 写入并行(-j)、并行表数(-P)三维并行。
- COPY 批量导入: 默认使用 PostgreSQL COPY FROM STDIN,比 INSERT 快 10 倍以上,失败自动回退 execute_values。
- 大表优先排序: 可选按表大小排序,大表优先迁移以便尽早发现问题。
- TB 级规模自适应: 根据预估数据量(100G-5TB)自动应用规模预设(small/medium/large/huge/massive),调整批大小、队列深度、并发度、内存阈值。
- 迁移前预检:
--pre-check执行磁盘空间、连接可达性、对象数量、系统内存检查,避免迁移中途失败。 - 内存压力监控: 后台线程定期采样
/proc/meminfo与进程 RSS,达到软上限降速、硬上限强制降级(缩小批大小/并发),防止 OOM。 - Oracle 会话保活: 大数据量长查询期间每 60 秒执行
SELECT 1 FROM DUAL,避免被 Oracle resource manager 或防火墙 kill。 - PG 会话调优: 批量加载期间临时设置
maintenance_work_mem、synchronous_commit=off、max_wal_size=4GB、checkpoint_timeout=30min,减少 WAL 切换与 checkpoint 抖动。 - ETA 预估: 实时统计吞吐量(行/秒)与剩余时间预估,便于运维判断进度。
- 优雅降级: 内存压力回调自动缩小 batch_insert_size、queue_size、concurrency、copy_chunk_size,压力恢复后自动还原。
- 大表分片: 支持 ORA_HASH / MOD 范式分片,将单表拆分为多个分片并行迁移,突破单线程读取瓶颈。
2.5 稳定性与容错
- NLS 编码强制 UTF-8: 所有 Oracle 会话设置 NLS_LANGUAGE=AMERICAN、NLS_DATE_FORMAT=ISO 标准,避免中文乱码。
- LOB 物化: Oracle LOB 定位器在游标关闭前读取为 bytes/str,避免 LOB 失效报错。
- 空字符串转 NULL: Oracle 中 '' 等价于 NULL,PG 不等价;工具自动将 '' 转为 NULL,保证语义一致。
- 重试机制: 可重试错误(连接断开、锁超时等)按指数退避自动重试,默认 3 次。
- 信号处理: 捕获 SIGINT/SIGTERM,优雅停止并保存检查点,避免数据不一致。
- 资源管理: 统一关闭连接池、游标、文件句柄,防止资源泄漏。
- 错误分类: 区分可重试错误与致命错误,避免无意义重试。
- 事务保护: 每批数据独立事务,失败时回滚当前批次但不影响已提交批次。
2.6 高级功能
- SCN 闪回查询: 通过 --scn 参数指定系统变更号,实现一致性快照读取或回滚后重试。
- CDC 增量同步: 记录 SCN 文件,支持基于日志的增量变更捕获配置。
- 数据库差异对比: TEST/TEST_COUNT/TEST_DATA 模式对比 Oracle 与 PG 的表结构与行数差异。
- 迁移评估报告: assess 子命令扫描 Oracle schema,生成迁移难度评分与人工干预清单。
- 项目模板生成: init_project 子命令生成标准迁移项目目录结构。
- Kettle 模板: KETTLE 类型生成 Pentaho Kettle ktr 文件,便于 ETL 工具集成。
- SQL 查询转换: QUERY 类型将 Oracle SQL 文件批量转为 PG 语法。
- 批量 SQL 执行: LOAD 类型并行执行 SQL 文件中的多条语句。
- 对象过滤: -a/--allow 白名单、-e/--exclude 黑名单,按对象名过滤。
- WHERE 条件: -W 全局 WHERE 条件、where_clauses 按表过滤数据。
- 列/表重命名: --rename-column、--rename-table 在迁移时重命名对象。
- DEFINED_PK: 为无主键表指定分片列,启用键集分页。
- 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 控制台功能
- 配置管理: 在线编辑 Oracle/PG 连接配置,保存与加载配置文件。
- 连接测试: 一键测试 Oracle 与 PostgreSQL 连接是否正常。
- 迁移评估: 触发评估扫描,查看迁移难度报告。
- 转换执行: 选择导出类型与对象过滤,启动转换任务,实时查看进度。
- 实时日志: 通过 SSE 推送实时转换日志到浏览器。
- 检查点管理: 查看断点续传状态,清除检查点重新开始。
- PL/SQL 工具: 在线转换 PL/SQL 代码或文件,评估迁移难度。
- 数据库对比: 对比 Oracle 与 PG 的表结构与行数差异。
- 对象浏览: 浏览 Oracle 的表、视图、函数列表。
- 项目模板: 生成标准迁移项目目录结构。
五、程序各种案例场景与操作过程
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数据库-全量迁移(可视化操作)
- 启动 Web 控制台:
python3 fgoracle2pg.py web -c config.yml - 浏览器打开 http://localhost:5052
- 在「配置」页签确认 Oracle 与 PG 连接信息。
- 点击「测试连接」验证两端可达。
- 切换到「评估」页签,点击「开始评估」,查看难度报告。
- 切换到「转换」页签,选择导出类型为「ALL」。
- 点击「开始转换」,在「日志」页签实时查看进度。
- 转换完成后,切换到「对比」页签,执行差异对比。
5.17 场景十七: Oracle迁移到PostgreSQL数据库-PL/SQL 在线转换(可视化操作)
- 启动 Web 控制台。
- 切换到「PL/SQL 工具」页签。
- 在左侧文本框粘贴 PL/SQL 代码。
- 点击「转换」,右侧显示转换后的 PL/pgSQL。
- 可点击「评估」查看转换难度与人工修改建议。
5.18 场景十八: 检查点管理(可视化操作)
- 启动 Web 控制台。
- 切换到「检查点」页签。
- 查看各表的迁移进度(已迁移行数/总行数)。
- 如需重新迁移某张表,点击「清除」删除该表检查点。
5.19 场景十九: 查看数据库对象(可视化操作)
- 启动 Web 控制台。
- 切换到「对象浏览」页签。
- 选择对象类型(表/视图/函数)。
- 浏览 Oracle 中的对象列表与定义。
5.20 场景二十: 仅迁移存储过程(可视化操作)
- 启动 Web 控制台。
- 在「转换」页签选择导出类型为「FUNCTION」。
- 在「允许对象」中输入需迁移的函数名(逗号分隔)。
- 点击「开始转换」。
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_size、maintenance_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=16GB、checkpoint_timeout=30min、wal_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
- 浏览器访问 http://服务器IP:5052
- 在「配置」页签确认 Oracle/PG 连接参数正确,点击「测试连接」。
- 在「评估」页签点击「开始评估」,查看对象数量与迁移难度。
- 在「转换」页签:
- 导出类型选择「ALL」
- 在「预估数据量(GB)」输入 500
- 勾选「自动规模调优」
- 数据顺序选择「按大小」
- 点击「开始转换」
- 在「日志」页签实时查看进度,包括:
- 当前阶段(表结构/数据/索引/...)
- 各表迁移行数与百分比
- 内存使用与吞吐量
- 如需中断,点击「停止」;恢复时直接重新点击「开始转换」,自动断点续传。
- 转换完成后,在「对比」页签执行行数对比验证。
# 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 huge或massive应用极限参数。 - 检查 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(不影响正在进行的命令行迁移)。

浙公网安备 33010602011771号