Adds end-to-end procedure for moving production back from DR (10.0.20.37) to a repaired/reinstalled PRIMARY (10.0.20.36): final RMAN backup on DR in restricted/read-only mode, RMAN restore on PRIMARY, app connection switch, scheduled-task reactivation, VM 109 stop. Companion PowerShell script handles the restore with sanity checks (IP, NFS, backup freshness) and aborts if Oracle major version != 19, since failback to 21c would need an extra dictionary upgrade step (~30-60 min) that adds untested risk during the critical window — recommended path is 19c failback then upgrade later in a planned window. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
363 lines
14 KiB
Markdown
363 lines
14 KiB
Markdown
# Failback DR → PRIMARY (procedura inversă)
|
|
|
|
Procedura de revenire de pe serverul DR (VM 109, `10.0.20.37`) pe serverul de producție reparat sau reinstalat (PRIMARY, `10.0.20.36`).
|
|
|
|
> **Context**: Această procedură se aplică DUPĂ ce DR a preluat producția (vezi `README.md` § "Emergency DR Activation"). Aplicațiile rulează pe DR (`10.0.20.37:1521/ROA`), PRIMARY a fost reparat sau reinstalat de la zero, și acum trebuie mutată producția înapoi pe PRIMARY.
|
|
|
|
---
|
|
|
|
## ⚠️ ATENȚIE: Pe PRIMARY instalează Oracle **19c** (recomandat ferm pentru failback)
|
|
|
|
Backup-urile RMAN existente sunt luate din Oracle **19.3** (`ORACLE_HOME = WINDOWS.X64_193000_db_home`, `compatible=19.0.0`).
|
|
|
|
**Instalează Oracle Database 19c:**
|
|
- Versiune: **Oracle Database 19c** (19.3 base + ultimul Release Update)
|
|
- Edition: aceeași cu cea originală — verifică pe DR cu `SELECT banner FROM v$version;`
|
|
- Installer: `WINDOWS.X64_193000_db_home.zip` (Oracle eDelivery / OTN)
|
|
- Path identic cu DR pentru ca scriptul de restore să funcționeze fără modificări
|
|
|
|
**De ce NU 21c (sau 23ai) la failback:**
|
|
|
|
Tehnic, RMAN 21c **poate** citi backup-uri 19c (controlfile + datafiles + archivelogs se restore). DAR: datafile headers rămân 19c → `ALTER DATABASE OPEN RESETLOGS` eșuează în mod normal. Path-ul corect pe 21c este:
|
|
|
|
```
|
|
RESTORE CONTROLFILE → RESTORE DATABASE → RECOVER DATABASE
|
|
→ STARTUP UPGRADE (NU OPEN normal)
|
|
→ dbupgrade (sau catctl.pl catupgrd.sql) ~30-60 min
|
|
→ ALTER DATABASE OPEN RESETLOGS
|
|
→ @utlrp.sql (recompile invalid objects)
|
|
→ ALTER SYSTEM SET COMPATIBLE='21.0.0' SCOPE=SPFILE (ireversibil, după validare)
|
|
```
|
|
|
|
**Probleme cu acest drum la failback:**
|
|
- +30-60 min downtime extra în fereastra critică
|
|
- Pasul de upgrade dictionary nu a fost testat pe acest dataset
|
|
- Eventuale obiecte/PL-SQL incompatibile descoperite după upgrade — sub presiune
|
|
- Dacă upgrade-ul eșuează parțial, roll-back complicat (DR e încă opțiune, dar pierzi timp)
|
|
|
|
**Recomandare ferm:**
|
|
- **Failback acut** → instalează 19c. Identic cu DR. Drum testat săptămânal. Fără surprize.
|
|
- **Migrare la 21c** → operație separată, planificată, după ce producția e stabilă pe PRIMARY 19c. Două opțiuni:
|
|
- **DBUA in-place upgrade** 19c → 21c — păstrează DBID, downtime planificat
|
|
- **Data Pump** (expdp/impdp full) — mai curat, dar pierzi DBID + statistici
|
|
|
|
Scriptul `rman_restore_to_primary.ps1` are check explicit pe major version și abortează dacă găsește ≠ 19, ca să nu se pornească cu jumătate de plan în fereastra de criză.
|
|
|
|
---
|
|
|
|
## 1. Precondiții
|
|
|
|
| Cerință | Verificare |
|
|
|---------|------------|
|
|
| PRIMARY (10.0.20.36) accesibil pe rețea | `ping 10.0.20.36` |
|
|
| Oracle 19c instalat pe PRIMARY (versiune identică cu DR) | `sqlplus -V` pe PRIMARY |
|
|
| `ORACLE_SID=ROA`, `ORACLE_HOME` la aceeași cale ca pe DR | vezi `proxmox/lxc108-oracle/roa-windows-setup/` |
|
|
| Aplicațiile pot fi puse în mentenanță (downtime ~30 min) | window planificat |
|
|
| NFS share `oracle-backups` accesibil de pe PRIMARY (sau plan B: copy via SMB/SCP) | `mount -o ... 10.0.20.202:/mnt/pve/oracle-backups F:` |
|
|
| Cont SYSDBA disponibil pe PRIMARY (proaspăt instalat = `system/manager` sau parola setată la instalare) | `sqlplus / as sysdba` |
|
|
| Backup ZFS replica pveelite → pve1 a dataset-ului `oracle-backups` rulează | `zfs list -t snapshot \| grep oracle-backups` |
|
|
|
|
---
|
|
|
|
## 2. Pași — overview
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ FAZA 1: PREPARE — DR în mentenanță, backup final │
|
|
│ 1. Anunț downtime aplicații │
|
|
│ 2. Read-only pe DR │
|
|
│ 3. RMAN full backup pe DR → NFS │
|
|
│ 4. Switch + archivelog pentru tranzacții finale │
|
|
├──────────────────────────────────────────────────────────────┤
|
|
│ FAZA 2: RESTORE — restore pe PRIMARY nou │
|
|
│ 5. Mount NFS pe PRIMARY (sau copy backup-uri) │
|
|
│ 6. Cleanup PRIMARY (dacă reinstalare a creat DB demo) │
|
|
│ 7. Rulare rman_restore_to_primary.ps1 │
|
|
│ 8. Verify DB OPEN + tabele │
|
|
├──────────────────────────────────────────────────────────────┤
|
|
│ FAZA 3: SWITCH — comutare aplicații, reset infra │
|
|
│ 9. Update connection strings: 10.0.20.37 → 10.0.20.36 │
|
|
│ 10. Test conectivitate aplicații │
|
|
│ 11. Reactivează scheduled tasks RMAN backup pe PRIMARY │
|
|
│ 12. Stop VM 109 (`qm stop 109`), readuce în `state=stopped`│
|
|
│ 13. Verifică ZFS replica + flow nou backup-uri pe NFS │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## FAZA 1 — Prepare
|
|
|
|
### Pas 1: Anunț downtime aplicații
|
|
|
|
Tot traficul de scriere trebuie oprit în timpul backup-ului final. Notifică utilizatorii și planifică un window de ~30 min.
|
|
|
|
### Pas 2: Read-only pe DR (10.0.20.37)
|
|
|
|
```sql
|
|
-- Conectare la DR
|
|
sqlplus / as sysdba
|
|
|
|
-- Verifică tranzacții active
|
|
SELECT username, status, count(*) FROM v$session WHERE type='USER' GROUP BY username,status;
|
|
|
|
-- Pune DB în restricted mode (doar SYSDBA poate scrie)
|
|
ALTER SYSTEM ENABLE RESTRICTED SESSION;
|
|
|
|
-- Sau, mai sigur: read-only mode (necesită shutdown + mount)
|
|
SHUTDOWN IMMEDIATE;
|
|
STARTUP MOUNT;
|
|
ALTER DATABASE OPEN READ ONLY;
|
|
```
|
|
|
|
> **Atenție**: read-only mode oprește scrierile complet, dar și aplicațiile vor primi erori la INSERT/UPDATE. Restricted session e mai blând dacă aplicațiile pot tolera disconectare scurtă.
|
|
|
|
### Pas 3: RMAN full backup pe DR
|
|
|
|
```cmd
|
|
REM Pe DR VM (10.0.20.37) - dacă e încă în restricted/read-only
|
|
D:\oracle\scripts\rman_backup.bat
|
|
```
|
|
|
|
Backup-ul este scris pe `F:\ROA\autobackup` (NFS mount din `10.0.20.202:/mnt/pve/oracle-backups`).
|
|
|
|
### Pas 4: Switch + archivelog pentru tranzacții finale
|
|
|
|
Dacă DB e încă în READ WRITE, capturează ultimele archivelogs:
|
|
|
|
```sql
|
|
ALTER SYSTEM SWITCH LOGFILE;
|
|
ALTER SYSTEM ARCHIVE LOG CURRENT;
|
|
|
|
-- Backup archivelog
|
|
-- în RMAN:
|
|
RMAN> BACKUP ARCHIVELOG ALL DELETE INPUT;
|
|
```
|
|
|
|
Notează **SCN-ul curent** — necesar pentru verificare ulterioară:
|
|
|
|
```sql
|
|
SELECT CURRENT_SCN FROM v$database;
|
|
-- Notează valoarea, ex: 12345678
|
|
```
|
|
|
|
### Pas 5: Verifică backup-urile pe NFS
|
|
|
|
```bash
|
|
ssh root@10.0.20.202 "ls -lt /mnt/pve/oracle-backups/ROA/autobackup/ | head -20"
|
|
```
|
|
|
|
Trebuie să vezi backup-urile recente (data/ora din pasul 3-4).
|
|
|
|
---
|
|
|
|
## FAZA 2 — Restore pe PRIMARY
|
|
|
|
### Pas 6: Mount NFS pe PRIMARY (sau copy backup-uri)
|
|
|
|
**Opțiunea A (recomandată): NFS mount direct pe PRIMARY**
|
|
|
|
Pe Windows PRIMARY:
|
|
|
|
```powershell
|
|
# Activare NFS Client (o singură dată, dacă nu e instalat)
|
|
Install-WindowsFeature -Name NFS-Client
|
|
|
|
# Mount NFS share ca F:
|
|
mount -o anon,nolock,mtype=hard,timeout=60 10.0.20.202:/mnt/pve/oracle-backups F:
|
|
|
|
# Verifică
|
|
dir F:\ROA\autobackup
|
|
```
|
|
|
|
**Opțiunea B (fallback): Copy via SMB/SCP**
|
|
|
|
Dacă NFS nu funcționează pe PRIMARY (rar):
|
|
|
|
```powershell
|
|
# Pe PRIMARY, copy de pe DR VM care are F:\ montat:
|
|
robocopy \\10.0.20.37\F$\ROA\autobackup F:\ROA\autobackup /MIR /Z
|
|
```
|
|
|
|
### Pas 7: Cleanup PRIMARY (dacă reinstalare a creat DB demo)
|
|
|
|
Dacă instalarea Oracle a creat o DB demo (ex: ORCL), șterge-o ca să eviți conflicte:
|
|
|
|
```cmd
|
|
REM Pe PRIMARY
|
|
sqlplus / as sysdba
|
|
SHUTDOWN ABORT;
|
|
EXIT;
|
|
|
|
oradim -delete -sid ORCL
|
|
```
|
|
|
|
Apoi rulează `cleanup_database.ps1` de pe DR (copiat în prealabil pe PRIMARY) sau doar șterge directoarele oradata/recovery_area existente pentru SID `ROA` (atenție: dacă PRIMARY are un `OracleServiceROA` rezidual de la instalare anterioară, oprește și șterge serviciul cu `oradim -delete -sid ROA`).
|
|
|
|
### Pas 8: Rulează scriptul de restore
|
|
|
|
```cmd
|
|
REM Pe PRIMARY (10.0.20.36)
|
|
powershell -ExecutionPolicy Bypass -File D:\oracle\scripts\rman_restore_to_primary.ps1
|
|
```
|
|
|
|
Scriptul `rman_restore_to_primary.ps1` (vezi `proxmox/vm109-windows-dr/scripts/`):
|
|
- Folosește același DBID `1363569330`
|
|
- Restore din `F:\ROA\autobackup`
|
|
- Configurează listener pe `10.0.20.36:1521`
|
|
- Setează SPFILE și service `OracleServiceROA` pe AUTOMATIC
|
|
|
|
### Pas 9: Verifică DB
|
|
|
|
```sql
|
|
sqlplus / as sysdba
|
|
|
|
SELECT name, open_mode, dbid FROM v$database;
|
|
-- Așteptat: ROA, READ WRITE, 1363569330
|
|
|
|
SELECT current_scn FROM v$database;
|
|
-- Trebuie să fie >= SCN-ul notat în pasul 4
|
|
|
|
SELECT count(*) FROM dba_tables WHERE owner NOT IN ('SYS','SYSTEM','XDB','GSMADMIN_INTERNAL','APPQOSSYS','OUTLN','DBSNMP','WMSYS','OLAPSYS','MDSYS','CTXSYS','EXFSYS','ORDSYS','LBACSYS');
|
|
-- Compară cu count-ul de pe DR (înainte de read-only)
|
|
|
|
-- Test scriere
|
|
CREATE TABLE test_failback_check (id NUMBER, ts DATE);
|
|
INSERT INTO test_failback_check VALUES (1, SYSDATE);
|
|
COMMIT;
|
|
SELECT * FROM test_failback_check;
|
|
DROP TABLE test_failback_check PURGE;
|
|
```
|
|
|
|
### Pas 10: Reset RMAN catalog
|
|
|
|
După `OPEN RESETLOGS`, marchează incarnation-ul nou:
|
|
|
|
```cmd
|
|
rman target /
|
|
|
|
RMAN> LIST INCARNATION;
|
|
RMAN> RESET DATABASE TO INCARNATION <număr_nouă_incarnation>;
|
|
RMAN> CROSSCHECK BACKUP;
|
|
RMAN> DELETE NOPROMPT EXPIRED BACKUP;
|
|
```
|
|
|
|
---
|
|
|
|
## FAZA 3 — Switch & cleanup
|
|
|
|
### Pas 11: Update connection strings aplicații
|
|
|
|
Schimbă în toate aplicațiile:
|
|
|
|
```
|
|
ÎNAINTE: 10.0.20.37:1521/ROA (DR)
|
|
DUPĂ: 10.0.20.36:1521/ROA (PRIMARY restaurat)
|
|
```
|
|
|
|
Locuri de modificat (conform `vm109-windows-dr/README.md`):
|
|
- Aplicații client (TNS_ADMIN sau connection strings hardcoded)
|
|
- Reverse proxy IIS (VM 201) — dacă rutează către Oracle
|
|
- Flowise (LXC 104) — variabile de mediu Oracle
|
|
- Scheduled tasks/cron-uri ce conectează la Oracle
|
|
|
|
### Pas 12: Test conectivitate
|
|
|
|
```bash
|
|
# De pe Claude Agent (10.0.20.171)
|
|
sqlplus user/pass@10.0.20.36:1521/ROA
|
|
|
|
# Test din aplicație principală — un read + un write minor
|
|
```
|
|
|
|
### Pas 13: Reactivează scheduled tasks RMAN pe PRIMARY
|
|
|
|
Pe PRIMARY (Windows Task Scheduler):
|
|
- `Oracle RMAN Full Backup` — săptămânal (rulează `D:\oracle\scripts\rman_backup.bat`)
|
|
- `Oracle RMAN Incremental` — zilnic (rulează `D:\oracle\scripts\rman_backup_incremental.bat`)
|
|
- `Oracle Backup Transfer` — după fiecare backup (rulează `D:\oracle\scripts\transfer_backups.ps1`)
|
|
|
|
Verifică că rulează corect:
|
|
|
|
```cmd
|
|
REM Forțează un transfer de test
|
|
powershell -File D:\oracle\scripts\transfer_backups.ps1
|
|
|
|
REM Verifică pe Proxmox că au ajuns
|
|
ssh root@10.0.20.202 "ls -lt /mnt/pve/oracle-backups/ROA/autobackup/ | head -5"
|
|
```
|
|
|
|
### Pas 14: Oprire VM 109, revenire la state normal
|
|
|
|
```bash
|
|
# Pe pveelite
|
|
ssh root@10.0.20.203 "qm stop 109"
|
|
|
|
# Verifică HA config: VM 109 trebuie să rămână state=stopped, nofailback=1
|
|
ssh root@10.0.20.203 "ha-manager config | grep -A2 vm:109"
|
|
# Așteptat:
|
|
# state stopped
|
|
# group ha-prefer-pveelite
|
|
# nofailback 1
|
|
```
|
|
|
|
### Pas 15: Verifică ZFS replicare backup-uri
|
|
|
|
```bash
|
|
# Snapshot-urile noi de pe pveelite trebuie să apară pe pve1
|
|
ssh root@10.0.20.201 "zfs list -t snapshot rpool/oracle-backups | tail -10"
|
|
|
|
# Verifică job-ul de replicare
|
|
ssh root@10.0.20.203 "cat /var/log/oracle-dr/replication.log | tail -20"
|
|
```
|
|
|
|
### Pas 16: Reactivează test săptămânal DR
|
|
|
|
Test-ul săptămânal din cron (Sâmbătă 06:00) va rula automat. Verifică prima rulare după failback ca să confirmi că backup-urile noi de pe PRIMARY sunt restaurabile pe VM 109:
|
|
|
|
```bash
|
|
# Sâmbăta următoare, după 06:00
|
|
ssh root@10.0.20.203 "ls -lt /var/log/oracle-dr/dr_test_*.log | head -1"
|
|
# Apoi tail pentru "PASSED"
|
|
```
|
|
|
|
---
|
|
|
|
## Roll-back (dacă failback eșuează)
|
|
|
|
Dacă restore pe PRIMARY eșuează sau verificarea găsește lipsuri de date:
|
|
|
|
1. **NU șterge** baza de pe DR — e încă fallback-ul tău
|
|
2. Pune aplicațiile înapoi pe `10.0.20.37:1521/ROA` (DR)
|
|
3. Repornește scrierile pe DR (`ALTER SYSTEM DISABLE RESTRICTED SESSION;` sau `STARTUP` normal dacă era read-only)
|
|
4. Investigare separată pe PRIMARY — doar după ce înțelegi cauza, încearcă din nou
|
|
|
|
---
|
|
|
|
## Anexă A — Diferențe între DR test și failback real
|
|
|
|
| Aspect | DR test săptămânal | Failback real |
|
|
|--------|---------------------|---------------|
|
|
| Sursă backup | NFS, ultimele backup-uri din `F:\` | NFS, **backup proaspăt** făcut de DR în pas 3 |
|
|
| TestMode flag | `-TestMode` (skip listener config) | **NU** TestMode (full config + listener) |
|
|
| Cleanup post-restore | DA — `cleanup_database.ps1 /AFTER` | **NU** — DB e producția acum |
|
|
| Stop VM/server după | DA — `qm stop 109` | **NU** — server rămâne up |
|
|
| Connection strings | nu se schimbă | se schimbă pe PRIMARY |
|
|
| Scheduled tasks RMAN | nu se ating | se reactivează pe PRIMARY |
|
|
|
|
## Anexă B — Estimări durată
|
|
|
|
| Pas | Durată estimată |
|
|
|-----|-----------------|
|
|
| Pas 2-4: Read-only + final backup pe DR | 5-10 min (depinde mărime DB) |
|
|
| Pas 6: NFS mount + verify | 2 min |
|
|
| Pas 7-8: Cleanup + restore script | 15-25 min (RMAN restore din 139 backup files) |
|
|
| Pas 9-10: Verify + RMAN catalog reset | 5 min |
|
|
| Pas 11-12: Switch aplicații + test | 5-10 min |
|
|
| **Total downtime** | **~30-50 min** |
|
|
|
|
---
|
|
|
|
**Last updated**: 2026-04-25
|
|
**Status**: Procedura nu a fost încă executată end-to-end — testează într-un environment de probă (vezi VM 302) înainte de un failback real.
|