Windows Server 2012 环境下 Oracle 11.2 使用 expdp 实现自动备份、异地复制与定期清理_20260504

一、环境说明

本次备份环境如下:

复制代码
操作系统: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 的"任务计划程序",参考以下文章。

Windows Server 2016 Datacenter上创建计划任务程序https://blog.csdn.net/weixin_45806267/article/details/150485928?ops_request_misc=elastic_search_misc&request_id=23db9bf48a2746a02ae5493f11c89592&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~ElasticSearch~search_v2-1-150485928-null-null.nonecase&utm_term=Windows%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1&spm=1018.2226.3001.4450

七、备份结果判断

正常情况下,主日志中应该看到类似内容:

复制代码
SCHEMA_A export OK
SCHEMA_B export OK
remote share login OK
remote copy OK

如果 robocopy 统计结果中:

复制代码
失败 0

并且脚本日志显示:

复制代码
remote copy OK

说明本次异地复制正常。

相关推荐
能喵烧香1 小时前
跨越系统的开源尝试:KDE Windows版本全解析
linux·windows·开源
nbwenren1 小时前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
小风吹啊吹~2 小时前
vscode的tunnel链接(Linux 服务器 + Windows 本地电脑版本)
服务器·vscode·microsoft·远程工作
AI玫瑰助手2 小时前
Python入门:Windows/macOS/Linux系统安装Python教程
windows·python·macos
Rick19932 小时前
sql慢查询优化
数据库
智算菩萨2 小时前
OpenAI Codex 国内使用完全指南:Windows/macOS/Linux 三平台详细安装配置教程(现在最新的有gpt-5.3-codex和gpt-5.4)
linux·windows·gpt·macos·ai·ai编程·codex
Yupureki2 小时前
《Linux网络编程》4.应用层HTTP协议
linux·服务器·c语言·网络·c++·http
IT邦德2 小时前
OGG 26ai实时同步Oracle
数据库·oracle
星光开发者2 小时前
基于springboot电动汽车租赁管理系统-计算机毕设 附源码 11217
javascript·spring boot·mysql·django·php·html5·express