一、环境说明
本次备份环境如下:
操作系统:Windows Server 2012
数据库版本:Oracle Database 11.2
备份工具:expdp
备份方式:Schema 级逻辑导出
本地备份目录:D:\dbbackup2026
异地备份方式:Windows 共享目录
本地保留时间:3 天
异地保留时间:7 天
本方案主要实现:
1. 自动导出指定 Schema;
2. 自动生成备份文件和日志;
3. 自动复制备份文件到异地共享目录;
4. 自动清理本地过期备份;
5. 自动清理异地过期备份;
6. 配合 Windows 计划任务实现每天定时执行。
本次实际执行中,Oracle 11.2 的 expdp 导出任务正常完成,两个 Schema 均成功生成 .dmp 文件,并通过 robocopy 成功复制到异地共享目录,复制失败数为 0。
二、确认 Oracle DIRECTORY 对象
expdp 使用的目录不是普通 Windows 变量,而是 Oracle 数据库内部的 DIRECTORY 对象。
脚本中使用:
directory=EXPDP_BAK
需要先确认数据库中 EXPDP_BAK 指向的真实路径:
select directory_name, directory_path
from dba_directories
where directory_name = 'EXPDP_BAK';
建议结果为:
D:\dbbackup2026
如果不存在,可以创建:
create or replace directory EXPDP_BAK as 'D:\dbbackup2026';
如果使用普通用户执行 expdp,需要授权:
grant read, write on directory EXPDP_BAK to 用户名;
如果脚本使用:
userid="/ as sysdba"
通常不需要额外授权,但 DIRECTORY 路径必须正确。
三、最终版备份脚本
脚本名称建议:
backup_expdp.bat
发布版脚本如下,IP、账号、密码均已脱敏:
@echo off
setlocal enabledelayedexpansion
rem =====================================================
rem Oracle 11.2 expdp 自动备份脚本
rem 操作系统:Windows Server 2012
rem 数据库版本:Oracle Database 11.2
rem 备份方式:expdp schema 逻辑导出
rem 本地保留:3 天
rem 异地保留:7 天
rem =====================================================
rem ===== Oracle 环境 =====
set ORACLE_SID=ORCL
set ORACLE_HOME=D:\app\Administrator\product\11.2.0\dbhome_1
set PATH=%ORACLE_HOME%\bin;%PATH%
rem ===== 本地目录 =====
set BASE_DIR=D:\dbbackup2026
set LOCAL_RETENTION_DAYS=3
rem ===== 异地共享目录 =====
set REMOTE_DIR=\\xxx.xxx.xxx.xxx\xxx.xxx.xxx.xxx_oracle11g
set REMOTE_RETENTION_DAYS=7
set REMOTE_USER=xxx.xxx.xxx.xxx\administrator
set REMOTE_PASS=******
if not exist "%BASE_DIR%" mkdir "%BASE_DIR%"
rem ===== 生成时间戳 =====
for /f %%i in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DTS=%%i
echo [!DTS!] ===== Oracle expdp backup start ===== > "%BASE_DIR%\backup_!DTS!.log"
rem ===== 生成 IMIP_OIL 参数文件 =====
(
echo userid="/ as sysdba"
echo directory=EXPDP_BAK
echo schemas=IMIP_OIL
echo dumpfile=imipoil_!DTS!_%%U.dmp
echo logfile=imipoil_!DTS!.log
echo parallel=1
echo filesize=4G
echo metrics=y
) > "%BASE_DIR%\imipoil_!DTS!.par"
rem ===== 生成 IMIP_WH 参数文件 =====
(
echo userid="/ as sysdba"
echo directory=EXPDP_BAK
echo schemas=IMIP_WH
echo dumpfile=imip_wh_!DTS!_%%U.dmp
echo logfile=imip_wh_!DTS!.log
echo parallel=1
echo filesize=4G
echo metrics=y
) > "%BASE_DIR%\imip_wh_!DTS!.par"
rem ===== 导出 IMIP_OIL =====
echo [!DTS!] start export IMIP_OIL >> "%BASE_DIR%\backup_!DTS!.log"
"%ORACLE_HOME%\bin\expdp.exe" parfile="%BASE_DIR%\imipoil_!DTS!.par" >> "%BASE_DIR%\backup_!DTS!.log" 2>&1
if errorlevel 1 (
echo [!DTS!] IMIP_OIL export FAILED >> "%BASE_DIR%\backup_!DTS!.log"
) else (
echo [!DTS!] IMIP_OIL export OK >> "%BASE_DIR%\backup_!DTS!.log"
)
rem ===== 导出 IMIP_WH =====
echo [!DTS!] start export IMIP_WH >> "%BASE_DIR%\backup_!DTS!.log"
"%ORACLE_HOME%\bin\expdp.exe" parfile="%BASE_DIR%\imip_wh_!DTS!.par" >> "%BASE_DIR%\backup_!DTS!.log" 2>&1
if errorlevel 1 (
echo [!DTS!] IMIP_WH export FAILED >> "%BASE_DIR%\backup_!DTS!.log"
) else (
echo [!DTS!] IMIP_WH export OK >> "%BASE_DIR%\backup_!DTS!.log"
)
rem ===== 删除本次临时 par 文件 =====
del /f /q "%BASE_DIR%\imipoil_!DTS!.par" >nul 2>nul
del /f /q "%BASE_DIR%\imip_wh_!DTS!.par" >nul 2>nul
rem ===== 连接异地共享 =====
echo [!DTS!] connect remote share >> "%BASE_DIR%\backup_!DTS!.log"
net use "%REMOTE_DIR%" /delete >nul 2>nul
net use "%REMOTE_DIR%" /user:%REMOTE_USER% "%REMOTE_PASS%" /persistent:no >> "%BASE_DIR%\backup_!DTS!.log" 2>&1
if errorlevel 1 (
echo [!DTS!] remote share login FAILED >> "%BASE_DIR%\backup_!DTS!.log"
) else (
echo [!DTS!] remote share login OK >> "%BASE_DIR%\backup_!DTS!.log"
)
rem ===== 复制本次最新生成文件到异地共享 =====
echo [!DTS!] start copy latest files to remote share >> "%BASE_DIR%\backup_!DTS!.log"
robocopy "%BASE_DIR%" "%REMOTE_DIR%" "imipoil_!DTS!_*.dmp" "imip_wh_!DTS!_*.dmp" "imipoil_!DTS!.log" "imip_wh_!DTS!.log" "backup_!DTS!.log" /Z /R:2 /W:5 /NP >> "%BASE_DIR%\backup_!DTS!.log" 2>&1
if errorlevel 8 (
echo [!DTS!] remote copy FAILED >> "%BASE_DIR%\backup_!DTS!.log"
) else (
echo [!DTS!] remote copy OK >> "%BASE_DIR%\backup_!DTS!.log"
)
rem ===== 清理本地 3 天前的备份文件和日志 =====
rem ===== 静默清理本地保留期以前的备份文件和日志 =====
forfiles /p "%BASE_DIR%" /m "imipoil_*" /d -%LOCAL_RETENTION_DAYS% /c "cmd /c del /f /q @path" >nul 2>nul
forfiles /p "%BASE_DIR%" /m "imip_wh_*" /d -%LOCAL_RETENTION_DAYS% /c "cmd /c del /f /q @path" >nul 2>nul
forfiles /p "%BASE_DIR%" /m "backup_*" /d -%LOCAL_RETENTION_DAYS% /c "cmd /c del /f /q @path" >nul 2>nul
rem ===== 清理异地 7 天前的备份文件和日志 =====
powershell -NoProfile -Command ^
"Get-ChildItem '%REMOTE_DIR%' -File | Where-Object { (($_.Name -like 'imipoil_*') -or ($_.Name -like 'imip_wh_*') -or ($_.Name -like 'backup_*')) -and $_.LastWriteTime -lt (Get-Date).AddDays(-%REMOTE_RETENTION_DAYS%)} | Remove-Item -Force" >> "%BASE_DIR%\backup_!DTS!.log" 2>&1
rem ===== 断开异地共享 =====
net use "%REMOTE_DIR%" /delete >nul 2>nul
echo [!DTS!] ===== Oracle expdp backup end ===== >> "%BASE_DIR%\backup_!DTS!.log"
endlocal
exit /b
三、脱敏位置说明
原脚本中只需要脱敏这三处:
set REMOTE_DIR=\\xxx.xxx.xxx.xxx\xxx.xxx.xxx.xxx_oracle11g
set REMOTE_USER=xxx.xxx.xxx.xxx\administrator
set REMOTE_PASS=******
含义如下:
REMOTE_DIR 异地共享目录,里面包含服务器 IP,需要脱敏
REMOTE_USER 连接异地共享目录的账号,里面包含服务器 IP,需要脱敏
REMOTE_PASS 异地共享目录密码,必须脱敏
四、实际环境使用时需要替换的内容
发布文章可以用脱敏版。
真正部署时,需要把下面几项替换成真实值。
1. Oracle 实例名
set ORACLE_SID=ORCL
根据实际实例名修改。
2. Oracle 软件目录
set ORACLE_HOME=D:\app\Administrator\product\11.2.0\dbhome_1
根据实际 Oracle 11.2 安装路径修改。
3. 异地共享目录
发布版:
set REMOTE_DIR=\\异地备份服务器IP\共享目录名
实际使用时改成真实共享路径,例如:
set REMOTE_DIR=\\xxx.xxx.xxx.xxx\oracle_backup
文章里不要暴露真实 IP。
4. 异地共享账号
发布版:
set REMOTE_USER=异地备份服务器IP\备份用户
实际使用时改成真实账号。
5. 异地共享密码
发布版:
set REMOTE_PASS=******
实际使用时改成真实密码。
文章、截图、日志里都不要暴露密码,这个是底线,别让安全同事半夜给你"爱的电话"。
6. Schema 名称
发布版中使用:
schemas=SCHEMA_A
schemas=SCHEMA_B
实际使用时改成真实业务 Schema。
如果只有一个 Schema,删除第二段导出即可。
五、本地和异地保留策略
脚本中本地保留时间为:
set LOCAL_RETENTION_DAYS=3
表示本地备份保留 3 天。
异地保留时间为:
set REMOTE_RETENTION_DAYS=7
表示异地备份保留 7 天。
本地清理使用 Windows 自带的 forfiles:
forfiles /p "%BASE_DIR%" /m "schema_a_*" /d -%LOCAL_RETENTION_DAYS% /c "cmd /c del /f /q @path" >nul 2>nul
这表示清理本地目录下超过保留天数的文件。
由于使用了:
>nul 2>nul
所以这是静默清理,不会输出删除明细,适合计划任务每天自动执行。
六、配置 Windows 计划任务
可以使用 Windows Server 2012 的"任务计划程序",参考以下文章。
七、备份结果判断
正常情况下,主日志中应该看到类似内容:
SCHEMA_A export OK
SCHEMA_B export OK
remote share login OK
remote copy OK
如果 robocopy 统计结果中:
失败 0
并且脚本日志显示:
remote copy OK
说明本次异地复制正常。