惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
量子位
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
V
Visual Studio Blog
雷峰网
雷峰网
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
有赞技术团队
有赞技术团队
博客园 - 叶小钗
Microsoft Azure Blog
Microsoft Azure Blog
T
The Blog of Author Tim Ferriss
U
Unit 42
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog

博客园 - 风哥数据库教程

数据库教程FGMT20‑Oracle容灾体系架构与数据库升级迁移方案 数据库教程FGMT19‑Oracle多租户容器架构与新特性总结 数据库教程FGMT18‑Oracle‑EMCC智能化集中运维管理系统 数据库教程FGMT17‑Oracle性能优化之故障诊断与性能优化 数据库教程FGMT16‑Oracle性能优化之操作系统诊断与分析 数据库教程FGMT15‑Oracle性能优化之物化视图与任务管理 数据库教程FGMT14‑Oracle性能优化之资源限制与资源管理 数据库教程FGMT13‑Oracle性能优化之数据仓库与分区表 数据库教程FGMT12‑Oracle性能诊断与综合分析 数据库教程FGMT11‑Oracle性能优化之性能收集与报告分析 数据库教程FGMT10‑Oracle性能优化之统计信息管理与维护 数据库教程FGMT09‑Oracle性能优化之执行计划与基线管理 数据库教程FGMT08‑Oracle性能优化之基准测试与案例分析 数据库教程FGMT06‑Oracle数据库日常管理维护操作 数据库教程FGMT07‑Oracle数据库备份恢复与数据迁移 数据库教程FGMT05‑Oracle数据库SQL语言开发与应用实战 数据库教程FGMT03‑生产环境Linux+Oracle19c+ASM安装配置与项目实战 数据库教程FGMT01‑Oracle数据库基础知识与版本特性 数据库教程FGMT00‑教程学习大纲与学习指南(第一部) MySQL 8/9集群InnoDB Cluster自动化安装过程-Fgedu MySQL8/9 MGR组复制集群安装自动化全过程-Fgedu MySQL8/9主从复制集群安装自动化全过程-Fgedu MySQL8.x/9.x数据库安装自动化全过程-Fgedu 异构数据库迁移全过程-FGO2ODB工具 从国外数据库迁移到国产数据库全过程-FGO2CDB工具 MySQL迁移到PostgreSQL数据库-FGMySQL2PG工具 Oracle 26ai数据库一键自动安装 for Fgedu Oracle 19c数据库一键自动安装 for Fgedu 数据库数据文件误删恢复工具FGFDU(FGEDU File DUL) 华为高斯数据库恢复工具FGOGDU(FGEDU openGauss DUL)
Oracle迁移到PostgreSQL数据库-FGOracle2PG工具
风哥数据库教程 · 2026-08-31 · via 博客园 - 风哥数据库教程

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_mem`、`synchronous_commit=off`、`max_wal_size=4GB`、`checkpoint_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 安装

```bash

# 克隆或解压项目

cd /path/to/FGOracle2PG

# 安装依赖

pip install -r requirements.txt

# 验证安装

python3 fgoracle2pg.py --help

```

### 4.2 配置文件

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

```yaml

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 控制台

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

```bash

python3 fgoracle2pg.py web -c config.yml

# 或指定端口

python3 fgoracle2pg.py web -c config.yml --host 0.0.0.0 --port 5052

```

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

```bash

# 启动(后台运行,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。

```bash

# 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数据库-仅迁移表结构(命令行)

```bash

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

```

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

```bash

# 仅迁移 EMP, DEPT, SALGRADE 三张表

python3 fgoracle2pg.py convert -c config.yml -t DATA -a EMP,DEPT,SALGRADE

```

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

```bash

# 排除 LOG_TABLE 和 TEMP_DATA

python3 fgoracle2pg.py convert -c config.yml -t DATA -e LOG_TABLE,TEMP_DATA

```

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

```bash

# 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 闪回一致性读取(命令行)

```bash

# 获取当前 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数据库-自定义类型映射(命令行)

```bash

# NUMBER 全部转 numeric,DATE 转 date

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

    -D NUMBER:numeric,DATE:date

```

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

```bash

# 跳过 BLOB 和 CLOB 列(仅迁移普通列数据)

python3 fgoracle2pg.py convert -c config.yml -t DATA \

    --no-blob --no-clob

```

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

```bash

# 仅迁移 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数据库-列重命名(命令行)

```bash

# 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 文件转换(命令行)

```bash

# 转换单个文件

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数据库-数据库差异对比(命令行)

```bash

# 全量对比

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

# 仅行数对比

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

```

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

```bash

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

```

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

```bash

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

```

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

```bash

# 首次迁移被中断

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,包含若干千万行级大表。

**步骤**:

```bash

# 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,包含多张亿行级事实表。

**步骤**:

```bash

# 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 小时内完成。

**步骤**:

```bash

# 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 数据库。

**步骤**:

```bash

# 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. 转换完成后,在「对比」页签执行行数对比验证。

```bash

# 3. 迁移完成后停止 Web 控制台

python3 web_manager.py stop --port 5052

```

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

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

**步骤**:

```bash

# 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`(不影响正在进行的命令行迁移)。

作者:风哥

官方网站:  http://www.fgedu.net.cn ,   http://www.itpux.com

数据库教程:   https://edu.51cto.com/lecturer/8020378.html

---