About this session
| Session | Details |
|---|---|
| Duration | 2–3 hours, including exercises |
| You will build | An Oracle Database Free container in ARCHIVELOG mode with RMAN backups in a fast recovery area, and a test tablespace you will break and repair |
| You will learn | Redo, archived logs and why ARCHIVELOG mode matters, the fast recovery area, RMAN configuration, full and archivelog backups, LIST and REPORT, restoring and recovering a PDB, validation, retention and obsolete backups |
| Prerequisites | Basic SQL and sqlplus; Docker or Podman installed |
Caution
In this lab you delete database files on purpose. Do it only in the lab container, never on a server that holds real data.
Module 1: the ideas you need first
Oracle records every change twice:
- In memory and then in datafiles (the data itself).
- In redo logs, a running journal of changes, written at commit.
Online redo logs are reused in a circle. In ARCHIVELOG mode, each filled redo log is copied to an archived log before reuse. With a backup plus every archived log since, Oracle can rebuild datafiles to any later point. That is media recovery.
| Mode | What you can recover |
|---|---|
| NOARCHIVELOG | Only to the time of the last (offline) backup. Changes since are lost |
| ARCHIVELOG | To the last commit, or any point in time, as long as backups and archived logs exist |
RMAN (Recovery Manager) is Oracle's backup tool. It knows which files to back up, records backups in the control file, checks blocks for corruption, and works out which backups and logs a restore needs.
The fast recovery area (FRA) is a disk location Oracle manages for backups and archived logs, with a size limit.
Module 2: start the lab database
docker run -d --name ora-lab -p 1521:1521 \
-e ORACLE_PWD='Lab#Pass2026' \
container-registry.oracle.com/database/free:latest
docker logs -f ora-lab # wait for "DATABASE IS READY TO USE!", then Ctrl+C
The image has a container database FREE with a pluggable database FREEPDB1. Open a shell in it:
docker exec -it ora-lab bash
sqlplus / as sysdba
SELECT name, log_mode FROM v$database;
SHOW PDBS
LOG_MODE is NOARCHIVELOG. Let's change that.
Module 3: ARCHIVELOG mode and the FRA
Still in sqlplus / as sysdba:
!mkdir -p /opt/oracle/oradata/fra
ALTER SYSTEM SET db_recovery_file_dest_size = 20G SCOPE=BOTH;
ALTER SYSTEM SET db_recovery_file_dest = '/opt/oracle/oradata/fra' SCOPE=BOTH;
SHUTDOWN IMMEDIATE
STARTUP MOUNT
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
ALTER PLUGGABLE DATABASE ALL OPEN;
ALTER PLUGGABLE DATABASE ALL SAVE STATE;
ARCHIVE LOG LIST
ARCHIVE LOG LIST should show Archive Mode and Archive destination USE_DB_RECOVERY_FILE_DEST. Force a log switch and see an archived log appear:
ALTER SYSTEM SWITCH LOGFILE;
SELECT name, sequence#, completion_time FROM v$archived_log ORDER BY sequence#;
Warning
In ARCHIVELOG mode, if the FRA fills up, the database stops accepting changes until space is freed. In real systems, monitor
V$RECOVERY_FILE_DESTand let RMAN delete obsolete backups.
Module 4: create test data
Connect to the PDB and make a tablespace you will later "lose":
ALTER SESSION SET CONTAINER = FREEPDB1;
CREATE TABLESPACE lab_data DATAFILE '/opt/oracle/oradata/FREE/FREEPDB1/lab_data01.dbf' SIZE 50M;
CREATE USER shop IDENTIFIED BY "Lab#Pass2026" DEFAULT TABLESPACE lab_data QUOTA UNLIMITED ON lab_data;
CREATE TABLE shop.orders (id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer VARCHAR2(50), amount NUMBER(10,2), created DATE DEFAULT SYSDATE);
INSERT INTO shop.orders (customer, amount) VALUES ('Asha', 120.50);
INSERT INTO shop.orders (customer, amount) VALUES ('Ben', 75);
COMMIT;
SELECT COUNT(*) FROM shop.orders;
EXIT
Check the path of the datafile if your image uses a different layout: SELECT file_name FROM dba_data_files WHERE tablespace_name = 'LAB_DATA';
Module 5: configure RMAN and take backups
From the container shell:
rman target /
RMAN> SHOW ALL;
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
| Setting | Why |
|---|---|
| Control file autobackup | After every backup, RMAN also backs up the control file and spfile, so you can rebuild even if they are lost |
| Recovery window of 7 days | RMAN keeps whatever is needed to recover to any point in the last 7 days; older backups become obsolete |
| Backup optimisation | Skips files that are already backed up and unchanged (such as archived logs) |
Take a full backup with the archived logs:
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
RMAN> LIST BACKUP SUMMARY;
RMAN> REPORT NEED BACKUP;
BACKUP DATABASE while the database is open is an online (hot) backup. It is only usable because the database is in ARCHIVELOG mode: the archived logs make the copied files consistent during recovery.
Module 6: changes after the backup
These rows exist only in redo and archived logs, not in the backup. Recovery must bring them back.
sqlplus / as sysdba
ALTER SESSION SET CONTAINER = FREEPDB1;
INSERT INTO shop.orders (customer, amount) VALUES ('Chen', 310.20);
INSERT INTO shop.orders (customer, amount) VALUES ('Dev', 42);
COMMIT;
SELECT COUNT(*) FROM shop.orders; -- 4
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER SYSTEM SWITCH LOGFILE;
EXIT
Module 7: break it
Delete the datafile while the database is running (lab only!):
rm /opt/oracle/oradata/FREE/FREEPDB1/lab_data01.dbf
sqlplus / as sysdba
ALTER SESSION SET CONTAINER = FREEPDB1;
ALTER SYSTEM FLUSH BUFFER_CACHE;
SELECT COUNT(*) FROM shop.orders;
You get errors like ORA-01116: error in opening database file and ORA-01110: data file ...: '.../lab_data01.dbf'. The rest of the database still works; only objects in that file are affected.
Module 8: restore and recover
Two choices: recover just the tablespace, or the whole PDB. For a beginner, PDB-level recovery is the simplest and most reliable. In RMAN, connected to the root:
RMAN> ALTER PLUGGABLE DATABASE freepdb1 CLOSE ABORT;
RMAN> RESTORE PLUGGABLE DATABASE freepdb1;
RMAN> RECOVER PLUGGABLE DATABASE freepdb1;
RMAN> ALTER PLUGGABLE DATABASE freepdb1 OPEN;
What happened:
- RESTORE copied the datafiles of
FREEPDB1back from the backup set. They are now "old", as of the backup. - RECOVER applied archived and online redo to roll them forward to the latest commit.
Check:
-- sqlplus / as sysdba
ALTER SESSION SET CONTAINER = FREEPDB1;
SELECT customer FROM shop.orders ORDER BY id; -- Asha, Ben, Chen, Dev
All four rows are back, including the two inserted after the backup. That is the point of ARCHIVELOG mode.
The tablespace-only alternative (less downtime: the rest of the PDB stays open):
-- in sqlplus, inside FREEPDB1: ALTER TABLESPACE lab_data OFFLINE IMMEDIATE;
RMAN> RESTORE TABLESPACE freepdb1:lab_data;
RMAN> RECOVER TABLESPACE freepdb1:lab_data;
-- in sqlplus, inside FREEPDB1: ALTER TABLESPACE lab_data ONLINE;
Module 9: check your backups are usable
A backup you've never tested is a hope, not a backup.
RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE; # reads every block, writes no backup
RMAN> RESTORE DATABASE VALIDATE; # reads the backups a restore would use
RMAN> CROSSCHECK BACKUP; # marks backups whose files are missing
RMAN> REPORT OBSOLETE;
RMAN> DELETE NOPROMPT OBSOLETE;
Look for corrupt blocks after validation:
SELECT * FROM v$database_block_corruption;
And FRA usage:
SELECT name, space_limit/1024/1024 AS limit_mb, space_used/1024/1024 AS used_mb
FROM v$recovery_file_dest;
Module 10: clean up
exit # leave the container shell
docker rm -f ora-lab
Exercises
- Take an incremental level 0 backup, insert rows, then a level 1 (
BACKUP INCREMENTAL LEVEL 1 DATABASE;). UseLIST BACKUPto compare sizes. - Delete the datafile again, but this time recover only the tablespace with the offline/restore/recover/online steps. Which approach had less impact?
- Run
RESTORE DATABASE PREVIEW;and explain what it lists. - Drop the
shop.orderstable (noPURGE), then get it back withFLASHBACK TABLE ... TO BEFORE DROP. Why didn't you need RMAN? - Simulate a full FRA by setting
db_recovery_file_dest_sizevery small and switching logs. What error appears in the alert log, and how do you fix it?
Knowledge check
- Why can't you take a consistent online backup in NOARCHIVELOG mode?
- What is the difference between RESTORE and RECOVER?
- What does control file autobackup protect you from?
- What does a recovery window of 7 days mean for which backups are kept?
- Why did the rows inserted after the backup survive?
- What happens to the database if the FRA is full in ARCHIVELOG mode?
Answers
- Files copied while the database is open are inconsistent. Only redo from archived logs can make them consistent, and NOARCHIVELOG mode doesn't keep it.
- RESTORE copies files back from backup. RECOVER applies redo to bring those files forward in time.
- Losing the control file and spfile, which hold the database structure and the RMAN backup records.
- RMAN keeps every backup and archived log needed to recover to any point in the last 7 days; anything older is obsolete and can be deleted.
- Their changes were in the redo logs and archived logs, which RECOVER applied after the restore.
- It can't archive redo logs, so once the online logs are full, sessions that change data hang until space is freed.
Summary
- ARCHIVELOG mode plus backups plus archived logs equals recovery to the last commit.
- Configure the FRA, control file autobackup and a retention policy before your first backup.
BACKUP DATABASE PLUS ARCHIVELOGis the basic daily backup; incrementals reduce size.- Restore puts files back; recover rolls them forward.
- Validate backups regularly and delete obsolete ones so the FRA never fills.
Further reading
- Oracle documentation: Backup and Recovery User's Guide (Getting Started with RMAN; Performing Complete Database Recovery).
- On this site: RMAN restore and recover runbook, designing an RMAN backup strategy, RMAN backups to OCI Object Storage, ORA-01555 snapshot too old.