Πώς επαναφέρουμε μία Oracle Database που βρίσκεται σε archive-log mode με RMAN Restore

- Πώς επαναφέρουμε μία Oracle Database που βρίσκεται σε archive-log mode με RMAN Restore - 1 Δεκέμβριος 2025
- Πώς μπορούμε να συνδέσουμε SQL Server με άλλον SQL Server με τη χρήση Linked Server - 3 Νοέμβριος 2025
- Πώς απελευθερώνουμε δεσμευμένο χώρο από datafiles / tempfiles μίας βάσης δεδομένων της Oracle - 1 Σεπτέμβριος 2025
Σε προηγούμενο άρθρο είχαμε δει πως παίρνουμε backup μια βάση δεδομένων της Oracle με RMAN, σε αυτό το άρθρο θα δούμε μια απλή περίπτωση ανάκτησης των δεδομένων με RMAN Restore. Υπάρχουν πολλες υποπεριπτώσεις με διαφορετικά βήματα η κάθε μία εμείς θα δούμε τα βήματα για ανακτήσουμε την βάση δεδομένων στο ίδιο μηχάνημα με το ίδιο όνομα.
Τα βήματα
Για αρχή τρέχουμε το παρακάτω query ώστε να δούμε τα ονόματα, την τοποθεσία και την ώρα που έχει γίνει το κάθε backup, στην περίπτωση μας θα υποθέσουμε οτι θέλουμε να γυρίσουμε την βάση δεδομένων στις 16/01/2025 15:29:00 :
select to_char(end_time, 'DY dd/mm/yyyy hh24:mi:ss') ended_time, duration,
status, type, size_mb
from (SELECT /*+ RULE */
dt.start_time strt_time, dt.end_time end_time, dt.time_taken_display duration,
dt.status, dt.input_type || decode(input_type, 'DB INCR',
' level ' || to_char(bsd.incr_level),
'') type,
to_char(dt.output_bytes/1024/1024, '999g999g990d00', 'NLS_NUMERIC_CHARACTERS=,.') as SIZE_MB
from v$rman_backup_job_details dt,
(select /*+ RULE */ session_stamp, session_recid, min(incremental_level) incr_level
from v$backup_set_details
group by session_stamp, session_recid) bsd
where dt.session_stamp = bsd.session_stamp
and dt.session_recid = bsd.session_recid
union all
select null, p.completion_time, null, null, p.handle,
to_char(d.blocks * d.block_size/1024/1024, '999g999g990d00', 'NLS_NUMERIC_CHARACTERS=,.') size_mb
from v$backup_piece p, v$backup_datafile d
where d.set_stamp = p.set_stamp
and d.set_count = p.set_count
and d.file# = 0)
where end_time >= sysdate - 7 -- last 7 days
order by end_time desc nulls last
/

Πριν επαναφέρουμε την βάση δεδομένων θα πρέπει να σβήσουμε όλα τα αρχεία της απο το λειτουργικό σύστημα, οπότε πριν την κατεβάσουμε τρέχουμε το παρακάτω query ώστε να μας κάνει generate τις εντολές:
select 1 as type, 'rm "'||name||'"' os_cmd from v$controlfile union all select 2, 'rm "'||member||'"' from v$logfile union all select 3, 'rm "'||name||'"' from v$datafile union all select 4, 'rm "'||name||'"' from v$tempfile union all select 5, 'rm -rf "'|| value ||'"' from v$parameter where name like '%_dump_dest' ||case when (select to_number(lpad(version, instr(version, '.', 1, 1)-1)) from v$instance) > 10 then 'garb' else '' end union all select 6, 'mkdir -p "'|| value ||'"' from v$parameter where name like '%_dump_dest' ||case when (select to_number(lpad(version, instr(version, '.', 1, 1)-1)) from v$instance) > 10 then 'garb' else '' end union all select 7, '# rm -rf "'||substr(value, 1, instr(value, dir_sep, -1)-1) ||'"' from v$parameter, (select decode(substr(name, 2, 2), ':\', '\', '\\', '\', '/') as dir_sep from v$datafile where rownum=1) b where name like 'core_dump_dest' ||case when (select to_number(lpad(version, instr(version, '.', 1, 1)-1)) from v$instance) < 11 then 'garb' else '' end union all select 8, '# mkdir -p "'||substr(value, 1, instr(value, dir_sep, -1)-1) ||'"' from v$parameter, (select decode(substr(name, 2, 2), ':\', '\', '\\', '\', '/') as dir_sep from v$datafile where rownum=1) b where name like 'core_dump_dest' ||case when (select to_number(lpad(version, instr(version, '.', 1, 1)-1)) from v$instance) < 11 then 'garb' else '' end

Κατεβάσουμε την βάση δεδομένων αφού πρώτα δημιουργήσουμε ένα pfile από το spfile και διαγράφουμε τα αρχεία της με τις εντολές που κάναμε generate πριν:
sqlplus / as sysdba create pfile from spfile; shutdown immediate; exit
Έπειτα σηκώνουμε σε nomount state με το pfile:
sqlplus / as sysdba startup nomount pfile=$ORACLE_HOME/dbs/initoradev.ora; exit;
Συνδεόμαστε στον RMAN και επαναφέρουμε το controlfile αν χρειάζεται:
rman target / restore controlfile from '/oracle/app/backup/20250116__controldb__ce3fd0vj_1_1'; exit
Βλέπουμε ότι το επαναφέραμε επιτυχώς:
Starting restore at 16/01/025 15:53
using channel ORA_DISK_1
channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:00
output file name=/oracle/app/oracle/product/19.3.0/dbhome_1/dbs/cntrloradev.dbf
Finished restore at 16/01/025 15:53
Ανοίγουμε την βάση δεδομένων σε mount state και κάνουμε catalog το location που περιέχει τα backups:
alter database mount; catalog start with '/oracle/app/backup';
Το restore
Τρέχουμε το παρακάτω command στον RMAN ώστε να κάνουμε restore, σε περίπτωση που τα επαναφέρουμε σε άλλο path τότε κάνουμε set newname το κάθε αριθμό datafile στο νεό path:
run{
allocate channel t1 type disk;
##SET NEWNAME FOR tempfile 1 to '/u01/app/oracle/oradata/.../TEMP01.DBF';
##set newname for datafile 1 to '/u01/app/oracle/oradata/.../SYSTEM01.DBF';
restore database;
switch datafile all;
switch tempfile all;
}
exit;
allocated channel: t1
channel t1: SID=151 device type=DISK
Starting restore at 16/01/025 15:58
channel t1: starting datafile backup set restore
channel t1: specifying datafile(s) to restore from backup set
channel t1: restoring datafile 00001 to /oracle/oradata/ORADEV/system01.dbf
channel t1: restoring datafile 00002 to /oracle/oradata/ORADEV/audit_ts_002.dbf
channel t1: restoring datafile 00003 to /oracle/oradata/ORADEV/sysaux01.dbf
channel t1: restoring datafile 00004 to /oracle/oradata/ORADEV/undotbs01.dbf
channel t1: restoring datafile 00005 to /oracle/oradata/ORADEV/test.dbf
channel t1: restoring datafile 00007 to /oracle/oradata/ORADEV/users01.dbf
channel t1: reading from backup piece /oracle/app/backup/20250116__fulldb__cd3fd0vd_1_1
channel t1: piece handle=/oracle/app/backup/20250116__fulldb__cd3fd0vd_1_1 tag=TAG20250116T151909
channel t1: restored backup piece 1
channel t1: reading from backup piece /oracle/app/backup/20250116__fulldb__cd3fd0vd_2_1
channel t1: piece handle=/oracle/app/backup/20250116__fulldb__cd3fd0vd_2_1 tag=TAG20250116T151909
channel t1: restored backup piece 2
channel t1: reading from backup piece /oracle/app/backup/20250116__fulldb__cd3fd0vd_3_1
channel t1: piece handle=/oracle/app/backup/20250116__fulldb__cd3fd0vd_3_1 tag=TAG20250116T151909
channel t1: restored backup piece 3
channel t1: reading from backup piece /oracle/app/backup/20250116__fulldb__cd3fd0vd_4_1
channel t1: piece handle=/oracle/app/backup/20250116__fulldb__cd3fd0vd_4_1 tag=TAG20250116T151909
channel t1: restored backup piece 4
channel t1: restore complete, elapsed time: 00:00:04
Finished restore at 16/01/025 15:58
released channel: t1
Αφού ολοκληρωθεί με το παρακάτω query βλέπουμε το χρονικό σημείο που βρίσκεται η βάση δεδομένων:
set linesize 512 trimspool on pages 1000 column nxtchng format 99999999999999999999 column checkpoint_time format a20 column fuzzy format a5 column cnt format 999999 select /*+ RULE */ status, checkpoint_change# nxtchng, to_char(checkpoint_time, 'DD/MM/YYYY HH24:MI:SS') as checkpoint_time, fuzzy, count(*) as cnt from v$datafile_header group by status, checkpoint_change#, checkpoint_time, fuzzy order by status, checkpoint_change#, checkpoint_time, fuzzy;
Βλέπουμε ότι βρίσκεται στη χρονική στιγμή 15:19:09 και εμείς θέλουμε να την πάμε 10 λεπτά αργότερα. Για να γινει αυτό θα πρέπει να κάνουμε recovery με set until time:
STATUS NXTCHNG CHECKPOINT_TIME FUZZY CNT
------- --------------------- -------------------- ----- -------
ONLINE 23933495 16/01/2025 15:19:09 NO 6
Το recovery
Για να κάνουμε recovery και να φτάση η βάση δεδομένων στην χρονική στιγμή 15:29:00 συνδεόμαστε στον RMAN και τρέχουμε το παρακάτω με την παράμετρο set until time:
rman target /
run
{
allocate channel ch01 type disk;
set archivelog destination to '/oracle/fast_recovery_area/ORADEV/archivelog';
set until time "to_date('16/01/2025 15:29:00','dd/mm/yyyy hh24:mi:ss')";
recover database;
}
exit;
Starting recover at 16/01/025 17:26
starting media recovery
channel ch01: starting archived log restore to user-specified destination
archived log destination=/oracle/fast_recovery_area/ORADEV/archivelog
channel ch01: restoring archived log
archived log thread=1 sequence=121
channel ch01: restoring archived log
archived log thread=1 sequence=122
channel ch01: restoring archived log
archived log thread=1 sequence=123
channel ch01: reading from backup piece /oracle/app/backup/20250116___archivesdb_ci3fd1m7_1_1
channel ch01: piece handle=/oracle/app/backup/20250116___archivesdb_ci3fd1m7_1_1 tag=TAG20250116T153119
channel ch01: restored backup piece 1
channel ch01: restore complete, elapsed time: 00:00:01
archived log file name=/oracle/fast_recovery_area/ORADEV/archivelog/1_121_1163221998.dbf thread=1 sequence=121
archived log file name=/oracle/fast_recovery_area/ORADEV/archivelog/1_122_1163221998.dbf thread=1 sequence=122
archived log file name=/oracle/fast_recovery_area/ORADEV/archivelog/1_123_1163221998.dbf thread=1 sequence=123
media recovery complete, elapsed time: 00:00:01
Finished recover at 16/01/025 17:26
released channel: ch01
Αφού ολοκληρωθεί το recovery επιβεβαιώνουμε τη χρονική στιγμή της βάσης δεδομένων με το query που τρέξαμε πριν:
set linesize 512 trimspool on pages 1000 column nxtchng format 99999999999999999999 column checkpoint_time format a20 column fuzzy format a5 column cnt format 999999 select /*+ RULE */ status, checkpoint_change# nxtchng, to_char(checkpoint_time, 'DD/MM/YYYY HH24:MI:SS') as checkpoint_time, fuzzy, count(*) as cnt from v$datafile_header group by status, checkpoint_change#, checkpoint_time, fuzzy order by status, checkpoint_change#, checkpoint_time, fuzzy;
STATUS NXTCHNG CHECKPOINT_TIME FUZZY CNT
------- --------------------- -------------------- ----- -------
ONLINE 23936249 16/01/2025 15:29:00 NO 6
Αφού ολοκληρωθεί την ανοίγουμε σε open state με την παράμετρο resetlogs και αν πάνε όλα καλά την κάνουμε επανεκκίνηση:
sqlplus / as sysdba alter database open resetlogs; shutdown immediate; startup; exit;

