Recovery er et seriøst emne enhver DBA, og som man hele tiden bør finpudse. Nedenstående giver et billede af forretningsgangen for en online recovery af en Oracle database. Jeg vil senere komme ind på RMAN, offline backups, mistede log- og datafiler m.v.

Nedenstående er en øvelse jeg gør hver måned, hvor jeg recover produktions data, ned i en test instans. Selve øvelsen tager en 4-5 timer hvis alt er gået godt, og drejer sig om ca. 180G data. Typisk recover jeg produktions systemer ned i underliggende miljøer en 2-8 gange pr. måned - men for denne sker det kun 1 gang.

I vores setup har vi opdelt, dels; udvikling og systemtest på en maskine, dels brugertest samt produktion på en anden. Det er SUN solaris, og denne Oracle database er en 8.1.7 (så man skal lige huse dobbelt plinger ved sqlplus / as sysdba).

Dagligt tages online backups af produktion, der senere i døgnet ligges på tape. Da størrelsen er anselig har vi valgt at gøre det på denne måde lige pt. (dvs. de sidste mange år), men der overvejes pt. et RMAN setup for alt der hedder produktion.

I afdelingen for ønsker, modtager jeg forud for en recovery, et ønske om at der skal genetableres data frem til f.eks, dags dato klokken 07:00. Da vores online backups tages klokken 02:10 om aftenen - betyder det dels at jeg skal have fat i den online backup fra en NSR tape, samt archivelogs fra hvor backupen stoppede og frem til klokken 07:00 så jeg kan ligge ændringer fra den periode på - og dermed opfylde afdelingen for ønskers, ønske.

Sagen for en online backup er; Du foretager enten manuelt eller via et script følgende for hvert tablespace;

  1. ALTER TABLESPACE tablespace_navn BEGIN BACKUP
  2. Kopier de til tablespacet tilhørende datafiler til disk/tape
  3. ALTER TABLESPACE tablespace_navn END BACKUP

Det du så checker i din alert file er hvornår backupen sluttede - sidste END BACKUP - og noterer dig SEQ nummeret for logfilen; her fra og frem til det tidspunkt du ønsker at lave recovery til skal du bruge dine archive logs.

Som i andre miljøer har jeg scripts, der i løbet af natten melder tilbage, om online backupen er kørt til tape. Hvis det ikke er tilfældet - bliver jeg nødt til at hente en tidligere backup, og dermed endnu flere archivelogs, samt længere recovery tid. Det er mere af hensyn til, jeg med rimelig sikkerhed, kan fortælle afdeling for ønsker, om hvornår jeg forventer at være klar. Faktisk har vi en herinde der vel har udført Danmarks længeste recovery; med 2 år og et par måneders archivelogs på et system engang, i forbindelse med recovery af en database.

Rent praktisk starter jeg på den eksisterende udviklings database med at finde datafiler, og så gør jeg egentlig det samme på produktion. Er der sket ændringer (kommet nye datafiler) skal vi på produktion lave en alter database backup controlfile to trace, så vores nye test indeholder en kontrolfil der matcher datafiler på produktion.

  1. select name from v$datafile
  2. ALTER DATABASE BACKUP CONTROLFILE TO TRACE;

Min udvikling kører desuden med remote_password_file=exclusive, og det tilføjer vi lige et # foran i init.ora filen således.

  • sed s/remote_login_passwordfile=exclusive/#remote_login_passwordfile=exclusive/$pwd/initORACLE_SID.ora > $pwd/ny_initORACLE_SID.ora

Med andre ord, find forekomsten af remote_login_passwordfile og sæt et # foran, og når det er gjort via SED skrives det til en ny fil.

remote_login_passwordfile betyder iøvrigt at oracle kigger efter en password fil, og om denne er delt mellem databaser. Man kan sætte parameteren til none, execlusive, internal og shared. Vores er sat til exclusive dvs. password filen tilhører 1 database, og en hvilken somhelst bruger kan tilføres password filen.

  1. mv $pwd/ny_initORACLE_SID.ora $pwd/initORACLE_SID.ora

Når remote_login_password file er udkommenteret - vha. sed, flytter vi den nye fil over som værende den aktuelle init fil.

Herefter er det bare at slette de fysiske filer, hvor databasen ligger. Det betyder rm af *.dbf, *.log og *.ctl.

Fysisk ligger min database således

  • [mount_point/oradata/ORACLE_SID].

Efter sletning henter jeg sidste online backup fra vores tape. Jeg vælger at placere denne i

  •  [mount_point/oradata/ORACLE_SID/ORACLE_SID_PRODUKTION]

Selve hentningen fra tape foregår via et script således (NCR).

  1. { recover -c maskinnavn -s tapestation -u -q -t $1/$2/$3 -vvv -d destination -a source } > recover.log

Ovenstående går der en rum tid med og udføres iøvrigt som del af et script. De parametre $1/$2/$3 der indgår, er dato for hvornår jeg vil have backupen fra f.eks 03 25 2007 for at hente backupen fra igår.

  1. F.eks kalder jeg ovenstående således ./start_med_at_hente_backup.sh 03 25 2007

Alt imens dette foregår,går jeg lige over på produktions maskinen og finder min alert.log fil for denne produktions database. Jeg åbner alertORACLE_SID.log med VI og finder tidspunktet fra hvornår backupen fra igår stoppede/blev færdig - altså den der hentes ovenfor. Dette skal jeg senere benytte for hvilke archivelogs, jeg skal hente til recover. Husk her at jeg jo gerne vil recover frem til Klokken 07.

- Thread 1 advanced to log sequence 158059

Ligeledes går jeg ned i archive_log_dest og checker sekvens for kloken 07:00 imorges. 

 -rw-rw----   1 oracle   dba      16135475 Mar 26 07:10 ORACLE_SID_158125.arc.Z

Nu har jeg sådan nogenlunde start archive og slut archive, som jeg skal bruge til efterfølgende recovery.

Når nu alle filer er hentet er det på tide at flytte dem fra [mount_point/oradata/ORACLE_SID/ORACLE_SID_PRODUKTION] til [mount_point/oradata/ORACLE_SID], og hvis du er placeret i sidstnævnte katalog.

  1. mv mount_point/oradata/ORACLE_SID/ORACLE_SID_PRODUKTION/*.dbf .

De filer jeg nu har flyttet et niveau op har et format der hedder; ORACLE_SID_PRODUKTIONnavn.dbf - så der er en lille øvelse i også at omdøbe filerne til den aktuelle ORACLE_SID for udvikling f.eks kunne man gøre dette:

ls ORACLE_SID_PRODUKTION_* 2>/dev/null
| while read fil
do
  echo mv $fil ORACLE_SID $fil >>rename_datafiles

done

Herefter kunne man så hente filen rename_datafiles ind i f.eks VI og lave søg og erstat på følgende

  • 1,$s/ORACLE_SID ORACLE_SID_PRODUKTION/ORACLE_SID/g

Hvis der er kommet nye datafiler til produktion, er det nødvendigt lige og gå på produktions maskinen og lave en

  • ALTER DATABASE BACKUP CONTROLFILE TO TRACE;

Efterfølgende kan dette dump findes i User dump destination og kopieres over til test maskinen - jeg vælger typisk at kalde dette dump for ctrnlPROD.sql.  Produktion og udvikling har dog nogen forskellige setups; path, ORACLE SIDer m.fl dette kan gøres via et script eller manuelt. Gør man det via et script kan man virkelig udnytte SED. F.eks kunne vi lave en fil vi kaldte for ret_kontrol.sh der indeholdt denne linie

  1.  sed -f ret_kontrol_parm ctrnlPROD.sql>ctrnlPROD1.sql

Næste step er at lave en parameter fil SED kan læse der indeholder søge og erstat kommandoer ala

  1. s/ORACLE_SID_PRODUKTION/ORACLE_SID/g
    s/path_på_produktion_til_datafiler/path_på_testsystem_til_datafiler/g

og så fremdeles - det er ret smart syntes jeg.

Når ovenstående er færdigt har jeg mig en ny kontrolfil, og den vil jeg benytte mig af med det samme:

  • sqlplus '/as sysdba'
    Startup nomount
    @ctrnlPROD1.sql;

Ovenstående sql script laver kontrolfil(erne) samt åbner databasen. Det sidste er egentlig bare at hente vores archives. Det var jo et par stykker jf. ovenstående; fra  158059 til 158125. I tilfælde af flere gør jeg flere ting.

  1. Dels placerer jeg mig i archive log destination (den finder du i din init.ora), og starter med at lave archive recovery fra min tape fra og med archive 158059 og til og med 158125.
  2. Dels omdøber jeg archives fra archiveORACLE_SID_PRODUKTIONsekvensnummer.arc.Z til ORACLE_SID_UDVIKLINGsekvensnummer.arc.Z (Ligesom med datafilerne fra før kan man lave et script der laver dette arbejde).
  3. og til slut laver jeg en uncompress på alle sammen.

Så er vi klar til en egentlig recover, der er en enkelt process - altså når man har sin online backup incl archive logs. Vi

  • recover database until time 2007-03-26:07:00:00 using backup controlfile ;

Når recover er overstået er det nødvendigt at åbne databasen med resetlogs ellers ryger i nok ind i en ORA-01113: file 1 needs media recovery.

  1. sqlplus '/ as sysdba'
  2. alter database open resetlogs

Efterfølgende er det nødvendigt - da vi taler udvikling dels at starte og stoppe basen, for lige at se det virker. Få sat databasen i NOARCHIVELOG mode, slå # fra i init.ora filen vedr. remote_login_passwordfile, rydde op i archive log filer, samt datafiler m.v. 

Herefter er vores recovery færdig og jeg vender tilbage til afdelingen for ønsker, med at nu kan udvikling igen tilgås.