做数据库运维的人基本都接过这种需求生产库在A机房分析平台或者灾备环境在B机房业务方丢过来一句话“把这几套核心业务schema的数据导到那边去”然后留下一堆待办就消失了。这种工作落到执行层就是典型的expdp异地导出。异地导出和本地导出最大的区别不在于命令本身而在于整个链路多了主机间传输、权限映射、版本匹配这些绕不开的环节。我写这篇文章就是想把这套异地导出的完整思路捋清楚什么时候该用哪种方案、参数怎么设、踩过哪些坑、目标端的验收入口在哪里。如果你正在折腾数据迁移、异地同步、机房搬迁这类事的DBA或数据工程师这篇文章应该能帮你少走几个月的弯路。新手看了也能明白整个expdp异地导出的底层逻辑而不是只停留在照抄命令的层面。1. 异地导出用在哪儿先看清需求再动手1.1 三类最常见的异地导出需求第一种是灾备恢复演练。很多公司的核心业务库在总部机房灾备库在另一个城市或者同一个城市的另一个机房。平时数据同步走的是DG或者日志实时传输但每年总要做一两次恢复演练这时候就需要把生产库的逻辑数据导出来送到灾备环境去验证恢复流程。逻辑导出和物理备份的区别在于expdp导出的dmp文件可以脱离原库环境独立存在拿到哪台机器都能导入非常适合演练时对数据的“搬运”。第二种是分析环境和报表平台。生产库承担的是OLTP业务不可能让报表查询直接压在上面。常规做法是每天或者每周从生产库导出一份数据到分析库。分析库可能部署在同一机房的另一套环境也可能在异地机房。这种场景的典型特点是数据量不小、频率固定、目标库表结构大体一致。用expdp异地导出比直接用dblink跨库查询要稳得多也不会因为长事务拖垮两端数据库。第三种是迁移和机房搬迁。老机房到期了业务要整体迁到新机房或者从传统架构迁移到云环境。这种时候数据泵导出往往是第一梯队方案因为它能在不停业务太长时间的前提下把结构、数据、权限、约束全部带过去。异地导出在这种情况下不只是一个技术动作更像是一个归档动作dmp文件作为迁移期间的关键产物能让你在目标端导入时反复重试出了问题随时可以重来。1.2 异地导出和本地导出的本质区别很多第一次做异地导出的人会把这件事想成“本地导出命令后面多传一个路径参数”实际上完全不是这么回事。本地导出时expdp进程从数据库里读数据写到同一个数据库服务器磁盘上所有操作都在一台机器内部完成。异地导出则至少跨越两台主机、一段网络和一个存储边界。目录对象必须指向数据库服务器本地的文件系统路径这个路径如果是远程存储挂载过来的那得先把远程存储挂载好否则数据泵根本看不到目录。导出文件的所有者通常是oracle账号传到目标端后目标端的oracle账号必须能读这个文件权限映射一乱就导入失败。目标库版本和源库版本不一致时dmp文件不能直接导入expdp需要显式指定VERSION参数。传输过程有校验问题dmp文件在跨机房传输时一旦损坏导入端常常报的不是简单的“文件损坏”而是各种莫名其妙的ORA错误。所以异地导出的本质是“数据库导出 文件传输 目标端导入”三段式工程每一段都有自己的坑。先把这三段的链路想明白再动手敲命令才不会被中间某个环节卡住。2. 动手前先理清目录、权限、网络和版本兼容2.1 数据泵目录对象的定位逻辑expdp里的DIRECTORY参数指向的是Oracle数据库实例中的一个目录对象DIRECTORY OBJECT这个对象做两件事一是把外部路径映射成一个逻辑名二是把对应的文件系统权限授给数据库用户。很多人写expdp命令时喜欢用绝对路径比如expdp ... dumpfile/data/dump/xxx.dmp这样做其实并不规范因为Oracle数据泵要求DUMPFILE参数配合目录对象使用就算你直接写绝对路径底层还是要走一个默认目录对象或者显式指定的目录对象。在异地导出场景下这个目录对象指向的路径尤其关键。它指向的一定是数据库服务器本地的路径而不是你DBA手里那台操作电脑的路径。如果远程存储没有挂载到数据库服务器就算你在客户端指定了一个本地路径expdp也写不进去。创建目录对象的完整过程是这样的先说数据库层面CREATE DIRECTORY dump_dir AS /u01/expdp_remote; GRANT READ, WRITE ON DIRECTORY dump_dir TO exp_user;这里有个非常经典的坑SQL里创建目录对象名dump_dir时不加引号会被Oracle自动转换成大写。expdp命令行里的DIRECTORY参数同样会被转成大写。如果你创建时用了小写或者混合大小写加双引号后面expdp里写目录名就必须加双引号保持大小写一致否则就会报ORA-39087 directory name is invalid。我见过不止一个同事因为这个报错查了半天权限问题最后发现只是目录名大小写对不上。目录对象创建完之后还要在操作系统层面把对应路径建好并且确保oracle用户有权限访问mkdir -p /u01/expdp_remote chown oracle:oinstall /u01/expdp_remote chmod 775 /u01/expdp_remote记住一个原则数据库层面的权限和操作系统层面的权限是两层。只授了数据库权限文件系统没权限expdp照样会报ORA-39002或者ORA-39070。这个排在前面是异地导出绝大多数权限报错的根源。2.2 网络与存储通路的三个选择异地导出在架构上其实就三条路。第一条是把目标机房的存储以共享方式挂载到源库服务器上expdp直接写到共享存储数据落地即异地。第二条是在目标库上创建指向源库的dblink用NETWORK_LINK参数让expdp在目标端直接读源库数据生成dmp文件在目标端本地。第三条是源库先导出到本地磁盘再把dmp文件用rsync或者scp传到目标机房最后在目标端impdp导入。这三条路没有绝对的好坏完全取决于数据量、网络带宽、源库负载容忍度和目标端配置。比如共享存储方案虽然省掉了中间传输环节但要求跨机房的存储链路足够稳定否则expdp进程会随着NFS的卡顿一起hang住。dblink方案省掉文件本身但数据抽取要走数据库链路网络往返比本地磁盘慢很多几百GB的数据量基本不现实。先导后传方案多个一步文件搬运但胜在稳定可控dmp文件还能留作备份。我自己的倾向是数据量超过100GB优先先导后传数据量小、对实时性有要求的可以考虑NETWORK_LINK存储链路质量特别好、又想省去传输时间的共享存储直写也不错。后面第三章会详细展开这三种方案怎么选型。2.3 权限检查清单动手之前我建议你按下面这个清单过一遍每一项都不难查但漏掉任何一项后面都可能来回折腾。数据库权限方面导出的账号需要有EXP_FULL_DATABASE角色或者至少拥有自己schema下对象的导出权限。如果A账号想导出B账号的schema而A账号没有EXP_FULL_DATABASE角色就会碰到ORA-39168或者对象找不到的报错。授权确认可以用这条SQLSELECT grantee, granted_role FROM dba_role_privs WHERE grantee EXP_USER;操作系统权限方面确认oracle系统账号对导出目录有读写权限。如果是NFS挂载还要确认共享路径允许oracle的uid写入。很多NFS服务器默认开启了root_squash如果挂载目录的文件属主映射不对即使数据库层面看目录没问题expdp一旦写文件就会遇到权限拒绝。网络端口方面数据库监听端口1521要通如果是NFS还要放通2049如果走ssh传输要确认22端口。云环境里的安全组规则、传统机房的防火墙策略都要提前验证。最直接的验证办法是在源库服务器上telnet一下目标端IP和端口telnet 目标机IP 1521网络层面不通的话后面的一切都会变成“看似能连库但文件传不过去”的诡异问题。3. 三种异地导出方案怎么选共享存储、dblink直导、先导后传3.1 共享存储直写最快但依赖存储链路共享存储直写就是把目标机房能访问的存储挂载到源库服务器上expdp直接写这个挂载目录。比如目标机房有一台NAS或者存储设备导出一台/data/expdp_share目录并在源库服务器上做一个NFS挂载mount -t nfs -o rw,bg,hard,nfsvers4 存储服务器IP:/data/expdp_share /u01/expdp_remote挂载完成后数据泵对这个目录的感知和本地目录几乎没有区别。expdp写完dmp文件目标机房的服务器只要也挂载同一个目录即可直接读取并进行impdp导入。整个过程最省环节没有文件传输这一步速度上限极高。但这个方案的隐忧在于expdp的写入是持续的即使NFS瞬时抖动也可能让expdp进程长期卡住或者直接报ORA-39006/ORA-39065这类内部错误。跨机房的NFS链路如果延迟高、抖动多我非常不建议用这个方案。同时要注意NFS的权限映射许多存储默认把uid映射成nobody这时候oracle用户写不了文件排错起来非常隐蔽。3.2 目标端dblink直导适合小数据量和实时性要求dblink直导这条路是在目标库上创建一个指向源库的数据库链接然后直接在目标库上执行expdp通过NETWORK_LINK参数从源库拉数据。目标端生成dmp文件写入目标端的目录对象。先要建dblink目标库执行CREATE DATABASE LINK TO_SRC CONNECT TO exp_user IDENTIFIED BY 密码 USING 源库TNS名称;测试链接是否能通SELECT COUNT(*) FROM dualTO_SRC;然后在目标库上执行expdpexpdp exp_user/密码目标库 \ directorydump_dir \ dumpfileremote_%U.dmp \ logfileremote_expdp.log \ network_linkTO_SRC \ schemassource_schema \ parallel4 \ compressionall这条命令本质上是把目标库当成expdp的执行端数据从源库一张一张表读取跨数据库链接传输到目标库后写入dmp文件。好处是你不需要在源库做任何操作也不需要搬运文件目标端拿到dmp文件之后直接impdp导入即可。坏处也很明显。dblink方式的数据抽取效率远低于本地导出因为每条记录都要经过数据库链接协议、SQL解析、网络传输。几十GB的数据量还能接受上了几百GB基本等不起。另外这种方式会占用源库大量会话资源和网络带宽源库是生产系统的话要控制并行度一般建议parallel不超过4。如果源库和目标库字符集不一致这种跨库抽取还会直接放大乱码风险。我实际用过network_link导过一个不到20GB的schema用了将近一个半小时。换成先导后传半小时导完加传完。所以这个方案只适合小数据量、临时应急不适合作为常规大库异地导出手段。3.3 源端先导出再传输最稳的方案适合大文件先导后传其实是大多数正规团队在用的方案。源库expdp导出到本地磁盘dmp文件用rsync或scp传到目标机房再做一次校验最后在目标端impdp导入。整个过程可以拆成三个阶段第一阶段源库执行expdp生成dmp文件和log文件。这阶段和本地导出完全一致源库的压力和影响可以精确控制。第二阶段用rsync传输dmp文件到目标服务器。第三阶段目标服务器上创建目录对象impdp导入。这个方案的优势在于每步之间都有明确的边界出了问题可以定位到具体环节。比如expdp成功但传输后导入报错那大概率是文件损坏重新传一遍就行。而且dmp文件保留在本地天然是一份逻辑备份后续目标端怎么折腾都不影响源库。它的代价是磁盘空间翻倍、总耗时增加。源库要同时容下原数据、dmp文件和压缩包的临时空间目标端也要预留类似大小的空间。传输时间取决于专线带宽几百GB的数据如果带宽只有百兆那确实要等很久。这种场景下先压缩再传输往往是更好的选择一块压缩参数设置合理的话dmp文件能缩小到原来的三分之一甚至更低。3.4 方案对比表对比项共享存储直写dblink直导先导后传适用数据量小到中等小50GB以下大百GB到数TB对源库影响写入负载集中在源库源库会话和IO被网络拉走可控导出完即可释放网络依赖高NFS链路质量决定成败高每条数据都走网络中等传输阶段才有网络压力传输环节无无需要rsync/scp传输失败恢复相对麻烦需要重新执行expdp重传文件即可最灵活推荐场景存储稳定链路质量极好数据量小应急同步生产环境常规数据迁移/备份如果你不知道该选哪个我直接说结论数据库运维场景下先导后传是最通用、最能控盘的方案。不是说它性能最好而是出了问题你知道该往哪儿查。实际生产环境里“可预期”和“可排查”比“快”更重要。4. 一个200GB级案例从expdp参数到impdp验证的完整流程4.1 场景与准备工作前面把原理讲透了这一章用一个实际案例走一遍完整流程方便直接抄作业。某公司生产环境在机房A新部署的分析环境在机房B。业务方要求把生产库中app_biz和app_user两个schema的全量数据导出到机房B的分析库数据总量估算约200GB源库是Oracle 19c目标库也是19c两套库之间有一条千兆专线。准备工作按顺序做了三件事。第一源库创建导出目录并授权。第二目标库创建导入目录并授权。第三确认专线带宽和防火墙端口。业务表大部分是订单、用户、日志类数据可压缩性比较高所以决定在expdp阶段使用压缩参数减少传输数据量。源库和目标库上分别执行CREATE DIRECTORY dump_dir AS /u01/expdp_work; GRANT READ, WRITE ON DIRECTORY dump_dir TO exp_user;操作系统层面确认目录存在且属主正确mkdir -p /u01/expdp_work chown oracle:oinstall /u01/expdp_work按我的经验如果导出的schema里有大字段或者CLOB类型spool出去前先查一下总行数和大字段占比这影响后面COMPRESSION参数怎么选。数据类型以行记录为主的话COMPRESSIONALL效果就很理想如果数据本身已经是压缩过的或者图片二进制之类压缩率会低很多。4.2 expdp导出命令与参数逐个拆解源库上执行导出expdp exp_user/密码源库 \ directorydump_dir \ schemasapp_biz,app_user \ dumpfilebiz_%U.dmp \ logfileexpdp_biz.log \ parallel4 \ compressionall \ filesize10G这里每个参数都值得说清楚。directorydump_dir指定了导出目录必须和数据库里的目录对象名一致注意大小写。schemas指定要导出的用户如果目标是整库这里可以换成fully但生产环境导出指定schema更常见影响范围小、权限好控制。dumpfilebiz_%U.dmp里的%U是通配符配合并行参数使用。数据泵开并行时一个主进程会派生多个工作进程每个进程负责一批表同时写多个dmp文件。如果没有%U通配符多个并行进程会争抢同一个文件导出任务直接报错。用filesize10G限制每个文件大小是为了后续传输和导入时分文件处理更灵活也避免单个文件过大导致文件系统无法承载。parallel4控制导出并行度一般不超过数据库服务器CPU核数的两倍。这个项目所在的服务器是16核4个并行进程既能充分利用资源又不会因为IO井喷把生产库拖垮。我第一次做类似项目时为了图快把parallel设成8结果生产库监控亮了一排警告被运维通报批评。所以并行度不是越大越好生产环境2到4比较稳分析环境可以放到6到8。compressionall表示数据和元数据全部压缩。200GB的数据在没压缩时大约会导出成180GB的dmp文件开了压缩后实际只有大约70GB。代价是导出过程中CPU占用会升高但对于大多数服务器来说压缩的开销远比网络传输慢带来的痛苦小得多。导出执行完第一件事不是看文件数量而是看expdp_biz.log的结尾Job EXP_USER.SYS_EXPORT_SCHEMA_01 successfully completed at ...看到successfully completed才是真成功。日志尾部没有这句话哪怕前面输出了一堆表都是成功的这个导出任务也大概率是有问题的。4.3 文件传输与校验导出完成后源库的/u01/expdp_work目录下会生成一批biz_*.dmp文件和expdp_biz.log。传输阶段我用rsync替代scp原因是rsync支持断点续传、差量传输和远程校验对于大文件跨机房传输极其友好rsync -avzP --partial /u01/expdp_work/biz_*.dmp oracle目标服务器IP:/u01/expdp_work/参数解释-a归档模式保留文件属性和权限-v显示过程-z传压缩-P相当于--partial --progress支持断点续传并显示进度。--partial表示即使传输中断已经传完的部分也保留下次重传时只补剩余部分。这项配置对于专线不稳定的环境来说等于保命符没有它一个40GB的文件断了就得从头传。传输完成后必须做校验。虽然rsync的校验机制能发现大部分问题但跨机房传输经过多层网络设备偶尔会有文件位翻转的情况。最保险的做法是源库和目标库分别计算md5值并比对md5sum /u01/expdp_work/biz_*.dmp source_checksum.txt # 传输到目标端后执行 md5sum -c source_checksum.txt这一步多花几分钟但能帮你排除掉“导入失败是不是文件损坏”这个疑问。实际工作中我有一次跳过校验结果impdp报了ORA-31603排查了半天才发现是dmp文件在传输过程中丢了几KB数据重传后问题立刻消失。4.4 目标端导入与验证文件到达目标库服务器后目标库执行impdp导入impdp exp_user/密码目标库 \ directorydump_dir \ dumpfilebiz_%U.dmp \ logfileimpdp_biz.log \ schemasapp_biz,app_user \ parallel4 \ transformsegment_attributes:n \ table_exists_actionskip导入参数里几个比较关键transformsegment_attributes:n是忽略源端的表空间和存储属性让导入的表自动落到目标库默认表空间避免因为表空间名称不一致导致导入失败。table_exists_actionskip表示目标端已存在的表直接跳过。如果是迁移场景更常见的是用truncate或者replace一定要根据业务需求来别无脑跳过。导入完成后验证工作一点也不能省。我先跑几条SQL确认对象数量和数据行数SELECT owner, COUNT(*) FROM dba_tables WHERE owner IN (APP_BIZ,APP_USER) GROUP BY owner;再抽查几张核心大表的行数和源库进行对比。整个过程虽然费时间但能非常有效地发现那些“没报错但数据不对”的隐藏问题。最后记得刷新目标库统计信息EXEC DBMS_STATS.GATHER_SCHEMA_STATS(APP_BIZ); EXEC DBMS_STATS.GATHER_SCHEMA_STATS(APP_USER);不刷新统计信息目标库的新表上完全没有统计信息优化器可能选出极差的执行计划同样一条SQL在源库跑0.1秒在目标库跑上10秒都不奇怪。5. 异地导出常见报错排查与避坑心得5.1 报错速查表报错信息可能原因解决办法ORA-39002 ORA-39070无法打开日志文件检查目录对象指向的路径是否存在oracle用户是否有写权限ORA-39087: directory name is invalid目录对象不存在或大小写不匹配确认CREATE DIRECTORY语句里的名字expdp时目录名加双引号保持大小写ORA-31603: object not foundschema/表对象不存在或导出用户权限不足确认对象名确认用户有EXP_FULL_DATABASE角色ORA-39166: object was skippedEXCLUDE和INCLUDE参数冲突检查expdp参数里是否同时排除了又包含了某个对象ORA-01455: column overflows数据类型转换问题或字符集不一致检查两端字符集设置必要时用NLS_LANG统一ORA-01652: unable to extend temp临时表空间不足增加临时表空间文件或降低并行度ORA-01950: no privileges on tablespace目标用户缺少表空间配额给目标用户授权或者用REMAP_TABLESPACE换表空间ORA-39006: internal error数据泵内部异常常见于版本BUG查看alert日志尝试降低parallel或升级补丁这张表基本覆盖了我做异地导出时遇到过的90%问题。其中ORA-39087和ORA-31603是最容易误导人的因为它们表面上看像是权限问题或者对象不存在问题实际上很多次都是目录名大小写没对上或者导出的schema名写错了。排错顺序建议是先看目录对象是否存在再看权限最后看对象能否在源库查到。5.2 几个非常容易忽略的细节导出前先估算磁盘空间。我一般用estimate_onlyy参数跑一遍快速估算然后再加上compressionall的经验压缩比基本能判断磁盘够不够。这条务必记住。某次项目里没做估算直接开到parallel8导出到一半发现磁盘满了expdp进程直接卡死源库生产业务被拖了将近一个小时教训非常深刻。dmp文件的命名规范要提前规划。如果使用%U通配符生成多个文件import时也要用同样的通配符匹配否则impdp只识别一个文件会立刻报找不到文件。这个坑在新手里出现率极高总以为导入时可以一个个挨着写文件名实际上只需要一个通配符就解决了。字符集问题在跨机房、跨版本场景下要提前干预。源库是AL32UTF8目标库如果是ZHS16GBK导入时中文字符可能出现截断或者乱码。解决思路不是等导入后补救而是导出前对比两端字符集SELECT userenv(language) FROM dual;如果两者不一致最稳妥的办法是先把目标库字符集调整为和源库一致或者导入后用REMAP相关参数处理。字符集问题隐蔽性极强几乎不会报错只在数据内容上出问题验证阶段必须非常仔细。版本兼容也是老生常谈但总有人忽略。Oracle的dmp文件只能往上兼容不能往下兼容。源库是19c目标库如果只有11g导入的时候就会报ORA-39044之类的问题。这种情况下expdp时应该显式指定version11.2.0这个参数会把dmp文件的格式控制在目标库能理解的范围内但会限制某些源库特有数据类型的使用需要在交付前做兼容性测试。5.3 数据一致性校验清单导入完成不代表万事大吉。我自己列了一个校验清单每次做完异地导出都照着走一遍对象数量核对dba_tables、dba_indexes、dba_views、dba_procedures按owner统计源库和目标库对比。数据行数核对抽取数据量最大的5到10张表分别查COUNT(*)并对比。无效对象检查查dba_objects中status值为INVALID的对象如果有通常是权限或者依赖对象缺失导致要逐个处理。外键与约束状态查dba_constraints确认外键约束没有处于DISABLED状态。数据泵导入有时为了加速会禁用约束导入完成后没启用的话业务后续写入数据很容易出问题。统计信息刷新按4.4节的SQL执行。这一步是数据泵导入流程的收尾动作也是性能保障的关键。这套清单做完我才会在交付群里说一句“数据已导入并验证完成”。在这之前任何结论都只是“数据看起来好像导完了”。6. 几个提升异地导出效率的小技巧6.1 把导出流程封装成脚本并自动告警命令写熟了之后我习惯把整个导出流程包进Shell脚本。异地导出的执行时间通常很长夜里跑的话总不能全程盯着。脚本里做好时间戳日志和失败标志出问题立刻退出并触发通知。#!/bin/bash export ORACLE_SIDORCL export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH export NLS_LANGAMERICAN_AMERICA.AL32UTF8 DATE_TAG$(date %Y%m%d_%H%M%S) EXP_LOG/u01/expdp_work/expdp_${DATE_TAG}.log expdp exp_user/密码源库 \ directorydump_dir \ schemasapp_biz,app_user \ dumpfilebiz_%U.dmp \ logfile${EXP_LOG} \ parallel4 \ compressionall if [ $? -ne 0 ]; then echo expdp failed, please check ${EXP_LOG} # 这里可以接上邮件或者IM通知脚本 exit 1 fi # 传输步骤 rsync -avzP --partial /u01/expdp_work/biz_*.dmp oracle目标服务器IP:/u01/expdp_work/ # 目标端导入由目标库脚本继续执行或者通过远程一条命令触发脚本里预先设置好环境变量NLS_LANG能避免很多奇奇怪怪的字符集问题。另外日志名必须带时间戳否则下次执行时日志文件被覆盖出了问题想回顾都没得回顾。6.2 按业务时间窗口分批导出减少锁与资源争用全量一次性导出在数据量大的情况下不仅耗时长而且会在源库产生持续的读压力和数据泵自身的临时段资源消耗。实际工作中我更倾向于按业务维度拆开导出。比如把订单表、用户表、日志表分别用一个expdp任务处理每个任务控制自己的并行度时间窗口错开跑。如果业务允许还可以用QUERY参数按时间范围分批expdp exp_user/密码源库 \ directorydump_dir \ tablesapp_biz.t_order \ dumpfileorder_%U.dmp \ queryWHERE order_date DATE 2024-01-01 AND order_date DATE 2024-02-01这种方式的好处是每个批次的量都可控出错时只需要重跑对应批次不需要动整库的导出任务。劣势是生成多个dmp文件导入端要按批次多次impdp。但对于几百GB甚至TB级的大库来说分批是唯一稳妥的选择。6.3 大文件远程传输的断点续传细节前面提到rsync的--partial参数能断点续传实际使用中还可以更进一步。两个机房之间的专线即使再稳定跨几百公里传输几十GB的文件中途小概率会断一次。加上--append-verify参数后rsync会先对比两端文件块只传输有差异的部分并且完成后再次校验文件完整性rsync -avzP --append-verify /u01/expdp_work/biz_*.dmp oracle目标服务器IP:/u01/expdp_work/这个参数对dmp文件这种大文件来说非常实用。需要特别提醒的是如果源端dmp文件在传输过程中还在生成比如expdp还没结束就启动传输--append-verify会出现两端文件不一致的误判所以导出任务和传输任务之间一定要做好串行控制。按经验来说等expdp完全结束后再启动传输比“边导边传”省心得多总耗时差不了多少但省掉了大量校验失败的麻烦。做了这么多次异地导出我最大的感受是命令本身只是最表层的东西真正决定任务顺不顺的是动手之前有没有把目录对象、权限、网络、版本、字符集这些底层链路彻底想清楚。另一条深刻体会是dmp文件的log日志一定要保存好。expdp的log记录了每张表导出的行数和耗时impdp的log记录了每个对象的导入状态任何数据异常第一现场都在这些日志里。我现在的习惯是把每次导出的日志按“日期任务名”归档存半年以上再清理。这个习惯看着不起眼但真等到业务方来问“某月某日的数据为什么对不上”的时候你会感谢自己当初留了这些log。