Skip to content

How to Create an Oracle RMAN Backup - Full & Incremental

Oracle Recovery Manager (RMAN) is the standard tool for Oracle database backups. It integrates with the database to provide block-change tracking, incremental backups, compression, and automatic catalog maintenance. This guide covers all backup types with production-ready scripts.

  • RMAN is installed with Oracle Database — no separate installation needed
  • Connect as SYSDBA or a user with SYSBACKUP privilege
  • The Fast Recovery Area (FRA) or a backup destination must be configured
  • The database should be in ARCHIVELOG mode for online backups
Terminal window
# Connect to RMAN
rman target / # Connect to local instance as SYSDBA
rman target sys@ORCL # Connect to remote instance
rman target / catalog rman/rman@RCAT # Connect with recovery catalog
-- Verify database is in ARCHIVELOG mode
SELECT log_mode FROM v$database;
-- Check FRA configuration
SHOW PARAMETER db_recovery_file_dest;
SHOW PARAMETER db_recovery_file_dest_size;
-- Check RMAN configuration
RMAN> SHOW ALL;

Step 1: Configure RMAN Before First Backup

Section titled “Step 1: Configure RMAN Before First Backup”
-- Set backup retention policy (keep 14 days or 2 recovery window)
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 14 DAYS;
-- Set compression (requires Advanced Compression Option for MEDIUM/HIGH)
RMAN> CONFIGURE COMPRESSION ALGORITHM 'BASIC'; -- No license needed
-- RMAN> CONFIGURE COMPRESSION ALGORITHM 'MEDIUM'; -- Requires ACO
-- Configure backup optimization (skip already-backed-up files)
RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
-- Configure parallelism (use 4 channels for parallel backup)
RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO BACKUPSET;
-- Enable automatic channel configuration
RMAN> CONFIGURE DEFAULT DEVICE TYPE TO DISK;
RMAN> CONFIGURE CHANNEL DEVICE TYPE DISK
FORMAT '/u02/backup/ORCL/%d_%T_%U';
-- Enable block change tracking (dramatically speeds up incremental backups)
ALTER DATABASE ENABLE BLOCK CHANGE TRACKING
USING FILE '/u01/oradata/ORCL/bct.dbf';

A Level 0 incremental backup is the baseline for incremental backup strategies. It backs up every used block — similar to a full backup but usable as an incremental base.

Terminal window
# Run from OS as oracle user
rman target /
-- Full database backup
RMAN> BACKUP DATABASE
PLUS ARCHIVELOG DELETE INPUT
TAG 'FULL_WEEKLY';
-- Full backup with compression (no ACO license needed for BASIC)
RMAN> BACKUP
COMPRESSED BACKUPSET DATABASE
PLUS ARCHIVELOG DELETE INPUT
TAG 'FULL_COMPRESSED'
FORMAT '/u02/backup/ORCL/full_%d_%T_%U';
-- Level 0 incremental (foundation for incremental strategy)
RMAN> BACKUP INCREMENTAL LEVEL 0
DATABASE
PLUS ARCHIVELOG DELETE INPUT
TAG 'L0_WEEKLY'
FORMAT '/u02/backup/ORCL/l0_%d_%T_%U';

Step 3: Incremental Level 1 Backup (Daily)

Section titled “Step 3: Incremental Level 1 Backup (Daily)”

Level 1 incrementals back up only blocks changed since the last Level 0 or Level 1 backup — far smaller and faster than a full backup.

-- Cumulative Level 1 (backs up changes since last Level 0)
-- Larger than differential but simpler to recover from
RMAN> BACKUP INCREMENTAL LEVEL 1 CUMULATIVE
DATABASE
PLUS ARCHIVELOG DELETE INPUT
TAG 'L1_CUMULATIVE_DAILY'
FORMAT '/u02/backup/ORCL/l1c_%d_%T_%U';
-- Differential Level 1 (backs up changes since last Level 0 OR Level 1)
-- Smaller backups but requires more backup sets during recovery
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE
PLUS ARCHIVELOG DELETE INPUT
TAG 'L1_DIFFERENTIAL_DAILY'
FORMAT '/u02/backup/ORCL/l1d_%d_%T_%U';

Archived logs are required for media recovery and point-in-time recovery. Back them up separately or as part of database backups.

-- Back up all archived logs
RMAN> BACKUP ARCHIVELOG ALL
DELETE INPUT
FORMAT '/u02/backup/ORCL/arch_%d_%T_%U';
-- Back up archived logs from a specific time
RMAN> BACKUP ARCHIVELOG
FROM TIME 'SYSDATE-1'
UNTIL TIME 'SYSDATE'
DELETE INPUT;
-- Back up the current redo log (force an archive first)
RMAN> ALTER SYSTEM ARCHIVE LOG CURRENT;
RMAN> BACKUP ARCHIVELOG ALL DELETE INPUT;
-- Back up control file explicitly
RMAN> BACKUP CURRENT CONTROLFILE;
-- Back up SPFILE
RMAN> BACKUP SPFILE;
-- Autobackup of control file and SPFILE after every backup
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP FORMAT
FOR DEVICE TYPE DISK TO '/u02/backup/ORCL/ctrl_%F';
-- Back up a specific tablespace
RMAN> BACKUP TABLESPACE app_data, app_idx
FORMAT '/u02/backup/ORCL/ts_%d_%T_%U';
-- Back up specific datafiles
RMAN> BACKUP DATAFILE 5, 6
FORMAT '/u02/backup/ORCL/df_%d_%T_%U';

Save this as /opt/oracle/scripts/rman_weekly_backup.rman and schedule with cron.

# Connect to RMAN and run this script
# rman target / @/opt/oracle/scripts/rman_weekly_backup.rman log /opt/oracle/logs/rman_weekly_$(date +%Y%m%d).log
RUN {
-- Allocate 4 parallel channels
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK
FORMAT '/u02/backup/ORCL/%d_%T_%U';
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK
FORMAT '/u02/backup/ORCL/%d_%T_%U';
ALLOCATE CHANNEL ch3 DEVICE TYPE DISK
FORMAT '/u02/backup/ORCL/%d_%T_%U';
ALLOCATE CHANNEL ch4 DEVICE TYPE DISK
FORMAT '/u02/backup/ORCL/%d_%T_%U';
-- Level 0 (full baseline) backup
BACKUP INCREMENTAL LEVEL 0
COMPRESSED BACKUPSET DATABASE
INCLUDE CURRENT CONTROLFILE
PLUS ARCHIVELOG DELETE ALL INPUT
TAG 'WEEKLY_LEVEL0';
-- Release channels
RELEASE CHANNEL ch1;
RELEASE CHANNEL ch2;
RELEASE CHANNEL ch3;
RELEASE CHANNEL ch4;
}
-- Crosscheck and delete obsolete backups
CROSSCHECK BACKUP;
DELETE NOPROMPT OBSOLETE;
DELETE NOPROMPT EXPIRED BACKUP;

Multisection Backup (for Very Large Datafiles)

Section titled “Multisection Backup (for Very Large Datafiles)”
-- Split large datafiles into sections for parallel backup
RMAN> BACKUP SECTION SIZE 10G DATABASE
TAG 'MULTISECTION_BACKUP';
-- Configure tape channel (requires media manager like NetBackup/DataDomain)
RMAN> CONFIGURE CHANNEL DEVICE TYPE SBT
PARMS 'ENV=(NB_ORA_SERV=netbackup_server)';
RMAN> BACKUP DEVICE TYPE SBT
DATABASE PLUS ARCHIVELOG
TAG 'TAPE_WEEKLY';
-- Validate that all blocks are valid without actually writing backup
RMAN> BACKUP VALIDATE DATABASE;
-- Validate archived logs
RMAN> BACKUP VALIDATE ARCHIVELOG ALL;
-- Detailed validation with corruption check
RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE;

Not configuring CONTROLFILE AUTOBACKUP — Without autobackup, if you lose the control file AND the database, you have no control file to start recovery. Always enable it.

Letting FRA fill up — RMAN will fail and the database will hang trying to archive logs if the FRA is 100% full. Monitor FRA usage and set db_recovery_file_dest_size appropriately.

Forgetting to back up archived logs — A database backup without the corresponding archived logs cannot be recovered to a point in time. Always include PLUS ARCHIVELOG or schedule separate archivelog backups.

Using FULL instead of INCREMENTAL LEVEL 0BACKUP DATABASE (full) cannot be used as the base for incrementals. Use BACKUP INCREMENTAL LEVEL 0 DATABASE as your weekly baseline.

Not testing restore — Unvalidated backups are just files. Regularly test RESTORE ... VALIDATE and full restore-to-test-environment to confirm your backups are usable.

Forgetting DELETE INPUT — Without DELETE INPUT on archivelog backups, archived logs accumulate and fill the archive destination or FRA.

-- Check backup status from RMAN
RMAN> LIST BACKUP SUMMARY;
RMAN> LIST BACKUP OF DATABASE;
-- Check for failed backups
SELECT session_key, session_recid, status,
start_time, end_time,
input_bytes/1024/1024/1024 AS input_gb,
output_bytes/1024/1024/1024 AS output_gb
FROM v$rman_backup_job_details
WHERE start_time > SYSDATE - 7
ORDER BY start_time DESC;
-- Check that all datafiles have been backed up recently
SELECT file#, name, completion_time,
ROUND((SYSDATE - completion_time) * 24, 1) AS hours_ago
FROM v$backup_datafile
WHERE completion_time = (
SELECT MAX(completion_time) FROM v$backup_datafile b2
WHERE b2.file# = v$backup_datafile.file#
)
ORDER BY hours_ago DESC NULLS FIRST;
-- Check FRA usage
SELECT name, space_limit/1024/1024/1024 AS limit_gb,
space_used/1024/1024/1024 AS used_gb,
ROUND(space_used/space_limit*100, 1) AS used_pct
FROM v$recovery_file_dest;