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
—
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
