1. 项目缘起:为什么数据迁移是DBA的“成人礼”
如果你在Oracle数据库领域待过一段时间,一定会认同一个观点:没独立主导过一次完整的数据迁移,你的DBA生涯是不完整的。这听起来有点夸张,但事实如此。数据迁移,尤其是Oracle这种重量级数据库的迁移,它不像写个存储过程或者调个索引那么简单。它是一场涉及技术、流程、风险控制和心理素质的综合考验。你不仅要懂数据库本身,还得懂操作系统、存储、网络,甚至要会点项目管理。
我最近刚完成一个从Oracle 11g单实例到19c RAC(Real Application Clusters)的迁移项目,源端还是跑在Linux上的ASM存储。整个过程踩了不少坑,也积累了一些实战心得。今天不聊那些高大上的理论,就从一个一线实施者的角度,掰开揉碎了讲讲,当你拿到“Oracle数据迁移”这个任务时,脑子里应该先过哪些事,手上应该按什么步骤来,以及哪些地方最容易“翻车”。
数据迁移的核心目标很简单:把数据从一个地方安全、完整、高效地搬到另一个地方,并且确保业务能平滑切换。但“简单”的目标背后,是极其复杂的实现路径。你可能为了一个字符集问题折腾一整天,也可能因为一个不起眼的参数没设对,导致迁移速度慢如蜗牛。所以,这篇文章我会围绕一次典型的、严肃的生产环境Oracle迁移来展开,涵盖从评估规划、环境准备、迁移实施到验证割接的全流程。无论你是要升级版本(比如11g到19c)、更换平台(比如AIX到Linux)、还是改变架构(单实例到RAC),这里面的核心逻辑都是相通的。
2. 迁移前的战略评估:搞清楚你到底要面对什么
在动手敲任何命令之前,花在评估和规划上的时间至少应该占整个项目周期的30%。这一步没做好,后面全是坑。
2.1 迁移动因与目标澄清
首先得问自己:我们为什么要迁移?这个问题的答案决定了迁移的边界和优先级。
- 版本升级:比如从11.2.0.4升级到19c。主要驱动力可能是原版本停止支持(EOL)、需要新特性(如多租户、自动索引)或安全合规要求。这时,兼容性是头等大事。
- 硬件/平台更换:比如从小机+旧存储迁移到x86服务器+新存储或云平台。主要目标是提升性能、降低TCO或拥抱云化。性能基准测试和驱动兼容性成为关键。
- 架构改造:比如从单实例迁移到RAC,或者整合到CDB/PDB。目标是提高可用性、实现资源隔离或简化管理。需要重点评估应用连接方式的改造量。
- 数据库整合或拆分:这可能是最复杂的一种,涉及数据的重新分布和逻辑重构。
以我这次项目为例,动因是“硬件老旧+版本过时+追求高可用”,所以目标是“从Linux上的Oracle 11g单实例(ASM)迁移到新硬件平台的Oracle 19c RAC”。目标必须具体、可衡量,例如:“在4小时业务时间窗口内,完成5TB数据的迁移和切换,确保数据零丢失,业务功能回退测试通过率100%”。
2.2 源端环境深度巡检
了解你的“老家”是搬家的第一步。你需要一份详细的源端体检报告。
数据库基本信息:
-- 版本和组件 SELECT * FROM v$version; SELECT comp_name, version, status FROM dba_registry; -- 字符集(超级重要!) SELECT parameter, value FROM nls_database_parameters WHERE parameter LIKE '%CHARACTERSET'; -- 数据库大小及增长情况 SELECT SUM(bytes)/1024/1024/1024 AS size_gb FROM dba_data_files; -- 查看表空间使用率 SELECT tablespace_name, round(SUM(bytes) / 1024 / 1024 / 1024, 2) total_gb, round(SUM(bytes - NVL(free_bytes, 0)) / 1024 / 1024 / 1024, 2) used_gb, round((SUM(bytes - NVL(free_bytes, 0)) / SUM(bytes)) * 100, 2) pct_used FROM (SELECT tablespace_name, file_id, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name, file_id) df LEFT JOIN (SELECT tablespace_name, file_id, SUM(bytes) free_bytes FROM dba_free_space GROUP BY tablespace_name, file_id) fs USING (tablespace_name, file_id) GROUP BY tablespace_name ORDER BY pct_used DESC;对象与依赖关系梳理:
- 对象数量:统计用户、表、索引、视图、序列、存储过程、触发器等数量。这关系到迁移工作量和复杂度。
- 无效对象:提前编译,避免迁移后报错。
SELECT owner, object_type, object_name, status FROM dba_objects WHERE status = 'INVALID'; - 依赖关系:特别是视图、物化视图、存储过程之间的依赖,确保迁移后顺序正确。
应用特征分析:
- 连接方式:应用用的是哪种驱动?TNSNAMES?Easy Connect?是否使用了连接池(如C3P0, DBCP, HikariCP)?迁移到RAC时,可能需要配置SCAN IP和负载均衡。
- SQL特征:通过AWR/Statspack报告,了解TOP SQL、硬解析情况、是否存在笛卡尔积等性能问题。有些问题在旧版本上勉强运行,在新版本优化器下可能暴露。
- 特殊功能使用:是否使用了Advanced Queuing、Streams、Change Data Capture等?这些功能在不同版本间迁移可能需要特殊处理。
存储与ASM细节:如果是ASM存储,需要了解磁盘组配置、冗余方式、AU大小等,为目标端ASM规划提供依据。
2.3 迁移技术选型:没有最好,只有最合适
这是技术决策的核心。每种方法都有其适用场景和优缺点。
| 迁移方法 | 核心原理 | 适用场景 | 优点 | 缺点与注意事项 |
|---|---|---|---|---|
| 数据泵 (Data Pump) | 逻辑导出/导入。通过expdp/impdp工具将元数据和数据以逻辑形式导出为dump文件,再导入目标库。 | 跨版本升级(如11g到19c)、跨平台迁移(如AIX到Linux)、数据库精简(只迁移部分数据)、字符集转换。 | 灵活性强:可选择性迁移(SCHEMA, TABLE, TABLESPACE)。可并行,提升速度。支持网络模式直接导入,省去中间文件。主流选择,功能成熟。 | 停机时间长:导出+传输+导入时间总和。大库可能耗时很久。对象依赖:需要处理对象存在性、权限、依赖顺序。LOB大对象处理慢。 |
| RMAN (Recovery Manager) | 物理备份恢复。备份源库数据文件、控制文件等,在目标库恢复。 | 同版本或向上兼容版本的迁移(如19.3到19.16)、平台字节序相同(如Linux到Linux)的迁移、要求最短停机时间的场景。 | 速度快:尤其是对于特大数据库,物理复制比逻辑导出快。停机时间短:可进行增量备份,最后只需一个短暂的恢复和归档日志应用窗口。数据一致性好。 | 灵活性差:通常是全库迁移,难以过滤数据。平台限制:跨平台(如Solaris到Linux)需使用RMAN CONVERT转换文件格式,较复杂。目标端环境需与源端高度相似(目录结构等)。 |
| GoldenGate / CDC | 基于日志的实时数据复制。捕获源端重做日志或归档日志的变化,在目标端实时应用。 | 双活架构、滚动升级(业务几乎零停机)、异构数据库同步。 | 近乎零停机:可在业务运行时同步,切换窗口极短。支持双向同步。 | 配置复杂,成本高(商业软件)。对源端性能有轻微影响。需要处理初始数据装载(通常配合Data Pump)。 |
| 可传输表空间 (TTS) | 物理移动数据文件。将表空间设为只读,拷贝其数据文件到目标端,并导入元数据。 | 迁移单个或几个大型表空间,且允许该表空间短期只读的场景。 | 速度极快:因为只是文件拷贝。减少停机:相对于逻辑导出,元数据导入很快。 | 限制多:要求源和目标数据库字节序相同、版本兼容、字符集一致。表空间必须自包含(Self-contained)。迁移期间表空间只读。 |
| 数据库链接 (DBLINK) + CTAS | 通过数据库链接,在目标库直接查询源库数据并创建表。 | 迁移少量表或进行数据子集迁移。 | 简单直接,无需中间文件。适合小规模、临时性迁移。 | 性能差,网络开销大。不适合大表或全库迁移。事务一致性难保证。 |
选择建议:对于常见的版本升级+平台迁移,数据泵(Data Pump)通常是平衡了灵活性、可靠性和复杂度的首选。如果数据库特别大(几十TB以上)且允许的同版本迁移,RMAN是更快的选择。如果追求分钟级甚至秒级停机,则必须考虑GoldenGate。
我这次迁移,因为是从11g到19c(跨版本),且需要将数据从旧ASM迁移到新存储规划的ASM,同时还要对部分历史数据进行归档清理,所以选择了数据泵。它的过滤和重映射功能(REMAP_TABLESPACE,REMAP_SCHEMA)能很好地满足我的需求。
3. 迁移沙盘:目标环境准备与预处理
目标环境不是等迁移那天才搭建的。一个稳定、合规的目标环境是迁移成功的基石。
3.1 目标数据库软件安装与配置
以Oracle 19c为例,在Linux上的安装虽然文档丰富,但细节决定成败。
- 软件包下载与校验:从Oracle官网下载
LINUX.X64_193000_db_home.zip。务必核对sha256校验和,避免安装包损坏。网传的百度云盘或各种“绿色版”安装包,强烈不建议在生产环境使用,可能存在被篡改或捆绑的风险。 - 操作系统配置:内核参数、用户限制(
/etc/security/limits.conf)、用户和组(oracle, dba)、目录权限等,严格按照Oracle官方文档Preinstallation Requirements进行。一个常见的坑是/etc/sysctl.conf中的shmmax、shmall参数设置过小,影响SGA分配。 - 安装选项:对于迁移目标库,通常选择“仅安装数据库软件”,稍后再通过数据泵或RMAN创建数据库。这样更干净。在安装过程中,
oracle用户的$ORACLE_HOME环境变量必须正确设置。 - 创建监听器 (Listener):使用
netca配置监听。如果目标端是RAC,需要配置SCAN监听和节点VIP监听。 - 创建数据库实例:使用
dbca(数据库配置助手)。这里有几个关键选择:- 数据库类型:选择“一般用途或事务处理”。
- 存储类型:如果沿用ASM,需要提前配置好ASM实例和磁盘组。我的目标端是新ASM,我创建了一个
+DATA磁盘组用于数据,一个+RECO磁盘组用于快速恢复区。 - 数据库标识:全局数据库名、SID。规划好与源端的区别或联系。
- 字符集:必须与源端保持一致,除非你明确知道如何转换且能承担风险。在
dbca的“高级选项”中指定。 - 内存与参数:初始参数文件(
pfile或spfile)可以根据源端的pfile进行调整,但不要直接拷贝,因为版本不同。重点关注compatible参数(应设为19.0.0)、db_block_size(通常保持与源端一致,如8k)、以及sga_target/pga_aggregate_target等内存参数。 - 创建模式:取消勾选“创建带样本方案的数据库”,我们不需要示例数据。
创建完成后,得到一个纯净的、只有系统表空间和用户的数据库实例。这就是我们数据的新家。
3.2 源端数据预处理:搬家前的“断舍离”
直接迁移所有数据往往是低效且危险的。迁移是进行数据治理的绝佳时机。
- 识别并归档历史数据:查询业务表的时间字段,将比如3年前、5年前的冷数据迁移到历史表或归档库。这能显著减少迁移数据量,提升速度。可以使用分区表交换(Partition Exchange)技术高效完成。
- 清理测试/临时数据:检查是否有测试用户、临时表的数据可以清除。
- 编译无效对象:在源端执行
@?/rdbms/admin/utlrp.sql,尽可能修复无效对象。把问题暴露在迁移前。 - 收集统计信息:在源端对主要业务表重新收集统计信息。
DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE);。这能确保数据泵导出的统计信息是准确的,有利于目标端优化器做出正确判断。 - 备份源库:在开始任何迁移操作前,务必对源数据库进行一次全量RMAN备份。这是你最后的救命稻草。
4. 核心迁移实战:以数据泵(Data Pump)为例的完整流程
假设我们选择数据泵进行迁移。以下是分步详解。
4.1 设计迁移目录与权限规划
在源端和目标端的服务器上,规划一个足够大的文件系统目录用于存放dump文件。例如/u01/app/oracle/dump_dir。确保oracle用户对该目录有读写权限。
# 在源端和目标端执行 mkdir -p /u01/app/oracle/dump_dir chown oracle:oinstall /u01/app/oracle/dump_dir chmod 775 /u01/app/oracle/dump_dir在数据库中创建目录对象,并授权给执行迁移的用户(通常是具有DBA权限的用户)。
-- 在源端和目标端分别执行 CREATE OR REPLACE DIRECTORY dpump_dir AS '/u01/app/oracle/dump_dir'; GRANT READ, WRITE ON DIRECTORY dpump_dir TO system; -- 或用专门的迁移用户4.2 编写数据泵导出参数文件
使用参数文件(parfile)比在命令行写一长串参数更清晰、易于维护和复用。创建一个文件expdp_full.par:
# expdp_full.par - 全库导出参数文件 DIRECTORY=dpump_dir DUMPFILE=expdp_full_%U.dmp LOGFILE=expdp_full.log FULL=Y COMPRESSION=ALL PARALLEL=4 CLUSTER=N EXCLUDE=STATISTICS FLASHBACK_TIME="SYSTIMESTAMP"FULL=Y:导出全库。你也可以用SCHEMAS=USER1,USER2或TABLESPACES=TS_DATA来导出部分。COMPRESSION=ALL:压缩数据,节省空间和传输时间。PARALLEL=4:启用4个并行进程,大幅提升导出速度。这个值通常设置为CPU核心数的2倍左右,但也要考虑I/O能力。CLUSTER=N:如果源库是RAC,但你想从单个节点导出,指定此项。EXCLUDE=STATISTICS:关键技巧。不导出统计信息,因为我们在导入时会重新收集。这能减少dump文件大小,并避免源端可能过时或不准确的统计信息影响目标端。FLASHBACK_TIME:确保导出数据的一致性时间点。对于活跃的生产库,使用FLASHBACK_SCN更精确,但需要提前确定一个SCN。
4.3 执行导出并监控
在源端服务器,使用oracle用户执行:
nohup expdp system/<password> parfile=expdp_full.par > expdp_full.out 2>&1 &使用tail -f expdp_full.out或查看日志文件expdp_full.log来监控进度。重点关注Worker Status部分,查看并行进程的状态。也可以通过数据泵的交互式命令监控:
-- 在导出会话中,或者另起一个sqlplus连接 -- 首先找到导出作业名 SELECT job_name, operation, job_mode, state FROM dba_datapump_jobs; -- 然后附加到作业 Export> status Export> parallel=4 -- 可以动态调整并行度导出完成后,检查日志末尾是否有ORA-错误。常见的警告如“对象不存在”可能可以忽略,但需要逐一确认。
4.4 传输dump文件到目标端
对于大文件,使用scp、rsync或nc(netcat)进行传输。如果网络带宽充足,rsync带压缩和断点续传是更好的选择。
# 在目标端执行,从源端拉取 rsync -avzP oracle@source_host:/u01/app/oracle/dump_dir/expdp_full*.dmp /u01/app/oracle/dump_dir/ rsync -avzP oracle@source_host:/u01/app/oracle/dump_dir/expdp_full.log /u01/app/oracle/dump_dir/传输前后,务必用md5sum或sha256sum校验文件完整性。
4.5 目标端预处理与导入
在目标端导入前,需要创建对应的用户和表空间。如果源端和目标端的表空间名、用户名需要改变,这正是使用REMAP功能的时候。
创建表空间:根据源端的表空间规划,在目标端ASM或文件系统上创建。注意数据文件路径和大小。
CREATE TABLESPACE users DATAFILE '+DATA' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITED;创建用户并授权:
CREATE USER app_user IDENTIFIED BY <new_password> DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users; GRANT CONNECT, RESOURCE TO app_user; -- 根据实际需要授予更多权限编写数据泵导入参数文件:
impdp_full.par# impdp_full.par - 全库导入参数文件 DIRECTORY=dpump_dir DUMPFILE=expdp_full_%U.dmp LOGFILE=impdp_full.log FULL=Y PARALLEL=4 CLUSTER=N REMAP_TABLESPACE=SOURCE_TS:TARGET_TS REMAP_SCHEMA=SOURCE_USER:TARGET_USER TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y TABLE_EXISTS_ACTION=REPLACEREMAP_TABLESPACE:如果目标端表空间名不同,用这个参数重映射。例如REMAP_TABLESPACE=USERS_OLD:USERS_NEW。REMAP_SCHEMA:将对象从一个用户迁移到另一个用户。例如REMAP_SCHEMA=HR:HR_NEW。TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y:性能关键参数。在导入期间禁用归档日志,可以极大提升导入速度。前提是你有把握导入过程不会失败,或者可以接受失败后从头再来。对于大型迁移,强烈建议开启。TABLE_EXISTS_ACTION:指定当表已存在时的动作。REPLACE会删除已存在的表然后重建。APPEND会追加数据。TRUNCATE会清空表再插入。根据场景选择。
执行导入并监控:
nohup impdp system/<password> parfile=impdp_full.par > impdp_full.out 2>&1 &监控方式与导出类似。导入过程中,可以观察目标数据库的告警日志(
alert_<sid>.log)和服务器I/O状态。
4.6 导入后必要操作
导入完成不代表万事大吉。
编译无效对象:在目标库执行编译脚本。
@?/rdbms/admin/utlrp.sql检查是否还有无效对象:
SELECT COUNT(*) FROM dba_objects WHERE status = 'INVALID';如果仍有大量无效对象,需要根据
DBA_ERRORS视图逐一排查,通常是依赖关系或权限问题。重新收集统计信息:导入时我们排除了统计信息,现在需要为目标库收集全新的、准确的统计信息。建议在业务低峰期进行。
EXEC DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE, cascade=>TRUE, degree=>DBMS_STATS.AUTO_DEGREE);对于超大表,可以按表并行收集。
重建索引:对于通过
TABLE_EXISTS_ACTION=REPLACE方式导入的表,其索引是随表定义一起创建的,但可能不是最优的。特别是当表空间发生变化后,考虑在线重建索引以优化存储结构。ALTER INDEX <index_name> REBUILD ONLINE;验证关键对象:检查序列的当前值是否正常(可能需要用
DBMS_METADATA获取源端序列的last_number并修正)。检查物化视图日志、高级队列等特殊对象的状态。
5. 迁移验证与业务割接:临门一脚的严谨
数据导进去了,不代表迁移成功了。必须经过严格的验证,才能放心切换业务。
5.1 数据一致性校验
这是最核心的验证。不能只靠“感觉”。
记录数比对:对核心业务表,在源端和目标端分别查询记录数。
-- 在源端和目标端分别执行,对比结果 SELECT table_name, num_rows FROM dba_tables WHERE owner='APP_USER' AND table_name IN ('ORDER_TABLE', 'USER_TABLE');NUM_ROWS是统计信息,可能不准。更准确的方法是直接COUNT(*),但对于大表耗时长。可以抽样比对,或者使用DBMS_COMPARISON包(11g以后)进行更高效的比对。关键数据抽样:随机抽取一些主键ID,在两边查询所有字段,确保数据完全一致。可以写一个简单的PL/SQL脚本完成。
校验和比对:对于大表,计算数据行的校验和(如使用
ORA_HASH函数)进行比对,比逐行比较快。SELECT SUM(ORA_HASH(column1 || column2 || ...)) AS hash_val FROM big_table;
5.2 功能与性能验证
- 应用连接测试:使用生产应用相同的连接字符串(修改IP/主机名为目标端),进行完整的业务流程测试。包括登录、查询、下单、报表等所有关键功能。
- 权限验证:确保应用用户具有所有必要的对象权限和系统权限。
- 性能基准测试:执行一些典型的复杂查询或批处理作业,对比在源端和目标端的执行时间和资源消耗。可以使用
SQL_TRACE、AWR报告进行对比。目标端的性能不应比源端有显著下降(升级情况下通常期望有提升)。
5.3 制定并演练割接方案
割接(Cutover)是最后一步,也是风险最高的一步。必须有一个详细的、分钟级的操作手册(Runbook)。
- 割接窗口:与业务部门确定一个足够长的、影响最小的停机时间窗口(例如凌晨2点到6点)。
- 操作步骤清单:
- 通知各方,停止源端应用。
- 在源端数据库执行最后一次检查,确保没有活跃会话。
- 锁定源端数据库(
ALTER SYSTEM ENABLE RESTRICTED SESSION;),防止新数据写入。 - 执行源端数据库的最终增量导出或获取最后的SCN。如果使用数据泵,可以做一个最后的增量导出(
INCREMENTAL参数)。如果使用RMAN,这是做最后一次增量备份的时候。 - 将这部分“最后的数据”应用到目标端。
- 在目标端执行最终的数据同步验证。
- 切换应用配置(如连接字符串、负载均衡配置等),指向新数据库。
- 启动部分应用,进行快速冒烟测试。
- 测试通过后,全面开放应用访问。
- 监控目标端数据库性能和应用日志。
- 回滚方案:如果割接失败,必须能快速回退。通常的回滚方案就是将应用连接切回源端数据库。因此,在割接期间,源端数据库必须保持完好,不能立即下线或重建。
5.4 割接后监控与优化
割接成功后的头几天是监控的关键期。
- 监控告警日志:实时查看
alert_<sid>.log,排查任何ORA错误。 - 监控性能:关注AWR报告中的TOP事件、TOP SQL。新环境、新版本可能暴露出新的性能瓶颈。
- 监控空间增长:检查表空间使用率,确保自动扩展正常工作,避免空间耗尽。
- 应用反馈:紧密联系应用团队,收集任何关于速度变慢、功能异常的报告。
6. 常见“深坑”与填坑经验
迁移路上,有些坑你几乎一定会遇到。这里分享几个我踩过或帮人填过的典型大坑。
6.1 字符集不一致导致的乱码与导入失败
这是跨国企业或老旧系统迁移中最常见的问题。源端是ZHS16GBK,目标端是AL32UTF8,直接导入,中文全变问号。
解决方案:
- 预防优于治疗:在目标端创建数据库时,字符集必须与源端一致。如果不一致,且必须转换,请在导出阶段使用数据泵的
CHARACTERSET参数指定正确的字符集导出,或者在导入时进行转换(更复杂)。 - 转换处理:如果已经创建了字符集不同的目标库,一个相对安全的方法是:先在目标端创建一个与源端字符集一致的数据库(作为中转),导入数据,然后使用
ALTER DATABASE CHARACTER SET语句(有风险,需在INTERNAL_USE下进行)或通过数据泵的CHARSET转换功能,再导出导入一次。这个过程非常繁琐且容易出错,强烈建议在测试环境充分验证。 - 工具辅助:可以使用
csscan工具(字符集扫描器)来评估字符集转换的风险。
6.2 大表(特别是含LOB列)迁移速度极慢
当你发现一个几百GB的大表,导出导入像蜗牛一样,并行度开到最大也没用,很可能是因为LOB列。
原因与解决方案: 数据泵处理LOB列时默认使用串行流,即使设置了PARALLEL。从11.2.0.4开始,可以通过设置LOB_STORAGE参数和启用SECUREFILE来改善,但最根本的加速方法是:
- 使用
ACCESS_METHOD=EXTERNAL_TABLE:在导入时,指定使用外部表方式加载数据,对含LOB的表有奇效。# 在impdp参数文件中针对特定表或全库 TRANSFORM=LOB_STORAGE:SECUREFILE ACCESS_METHOD=EXTERNAL_TABLE - 分批处理:对于超巨型表,可以考虑按时间分区或逻辑条件(如主键范围)分批导出导入。
- 网络模式:如果源和目标网络通畅,使用
NETWORK_LINK参数直接导入,避免生成巨大的dump文件,有时反而更快。
6.3 权限和对象依赖关系错乱
导入后,应用报错“表或视图不存在”,但明明表都在。很可能是权限没导全,或者公共同义词(PUBLIC SYNONYM)、视图依赖的对象不存在。
解决方案:
- 导出时包含权限:确保
expdp参数中包含FULL=Y或INCLUDE=GRANT。 - 处理公共同义词:
FULL模式导出会包含公共同义词,但有时需要单独处理。导入后检查DBA_SYNONYMS。 - 按正确顺序导入:如果分用户导入,应先导入基础用户(如表空间所有者、被依赖的对象所有者),再导入依赖它们的用户。数据泵的
SCHEMAS模式会尝试处理依赖,但复杂情况下可能仍需手动干预。 - 使用
SQLFILE参数:在导入前,可以先使用impdp ... SQLFILE=ddl.sql只生成DDL语句文件。检查这个文件,可以提前发现对象创建顺序和依赖问题,手动调整后再进行实际导入。
6.4 迁移后性能不升反降
高高兴兴割接完,业务部门投诉系统变卡了。这可能是因为:
- 统计信息问题:导入时排除了统计信息,导入后没收集或收集不准确。务必在业务低峰期收集全库统计信息。
- 优化器版本差异:19c的优化器(CBO)比11g更复杂、更智能,但也可能因为某些SQL写法不标准而选错执行计划。检查AWR报告中的“SQL ordered by Elapsed Time”,对变慢的SQL重新分析。可能需要使用
SQL Plan Management (SPM)或SQL Profile来固定好的执行计划。 - 参数差异:新版本的默认参数值可能不同。例如
optimizer_index_cost_adj,optimizer_index_caching等参数,在11g可能被手动调整过,在19c需要重新评估。比较源端和目标端的spfile参数,但不要盲目拷贝,要参考19c的最佳实践。
迁移是一场战役,胜利属于准备最充分、细节最考究、预案最周全的团队。它没有银弹,每一个成功的迁移案例,都是对DBA技术功底、风险意识和沟通协调能力的全面检验。把每一次迁移都当成第一次那样去谨慎规划,把文档写得再细一点,把测试做得再充分一点,把回滚方案准备得再稳妥一点,你就能在深夜的割接窗口里,多一份淡定和从容。