Reorganize oracle/ and chatbot/ into proxmox/ per LXC/VM structure
- Move oracle/migration-scripts/ to proxmox/lxc108-oracle/migration/ - Move oracle/roa/ and oracle/roa-romconstruct/ to proxmox/lxc108-oracle/sql/ - Move oracle/standby-server-scripts/ to proxmox/vm109-windows-dr/ - Move chatbot/ to proxmox/lxc104-flowise/ - Update proxmox/README.md with new structure and navigation - Update all documentation with correct directory references - Remove unused input/claude-agent-sdk/ files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,11 +15,36 @@ proxmox/
|
||||
│ ├── scripts/
|
||||
│ └── config/
|
||||
│
|
||||
├── lxc104-flowise/ # LXC 104 - Flowise AI (Chatbot Maria)
|
||||
│ ├── README.md # Infrastructură chatbot, ngrok, troubleshooting
|
||||
│ └── docs/
|
||||
│ ├── prd.md # Product Requirements Document
|
||||
│ ├── v1-arhitectura.md # Arhitectură v1 (Flowise + Groq)
|
||||
│ └── v2-arhitectura.md # Arhitectură v2 (Claude Agent SDK)
|
||||
│
|
||||
├── lxc108-oracle/ # LXC 108 - Oracle Database XE 21c
|
||||
│ ├── README.md # Documentație completă Oracle
|
||||
│ ├── scripts/
|
||||
│ │ ├── export-roa2.sh
|
||||
│ │ └── export-roa2.ps1
|
||||
│ ├── migration/ # Scripturi migrare Oracle 10g → 21c
|
||||
│ │ ├── README.md
|
||||
│ │ ├── 00-MASTER-MIGRATION.sh
|
||||
│ │ └── ...
|
||||
│ └── sql/
|
||||
│ ├── roa/ # SQL-uri Oracle 10g compatibilitate
|
||||
│ └── roa-romconstruct/ # Package PACK_CONTAFIN
|
||||
│
|
||||
├── vm109-windows-dr/ # VM 109 - Windows Standby (Disaster Recovery)
|
||||
│ ├── README.md # Configurare DR, RMAN backup
|
||||
│ ├── docs/
|
||||
│ │ ├── PLAN_TESTARE_MONITORIZARE.md
|
||||
│ │ ├── PROXMOX_NOTIFICATIONS_README.md
|
||||
│ │ └── archive/ # Planuri și statusuri anterioare
|
||||
│ └── scripts/
|
||||
│ ├── export-roa2.sh
|
||||
│ └── export-roa2.ps1
|
||||
│ ├── rman_backup*.bat # Scripturi RMAN Windows
|
||||
│ ├── transfer_backups.ps1 # Transfer backup-uri
|
||||
│ └── *-proxmox.sh # Monitorizare din Proxmox
|
||||
│
|
||||
├── vm201-windows/ # VM 201 - Windows 11 (roacentral)
|
||||
│ ├── README.md # Informații generale VM
|
||||
@@ -63,6 +88,36 @@ ssh root@10.0.20.201 "upsc nutdev1"
|
||||
|
||||
---
|
||||
|
||||
### LXC 104 - Flowise AI (Chatbot Maria)
|
||||
**Director:** `lxc104-flowise/`
|
||||
**IP:** 10.0.20.161 | **Host:** pvemini
|
||||
|
||||
| Fișier | Descriere |
|
||||
|--------|-----------|
|
||||
| `README.md` | Configurare Flowise, ngrok, troubleshooting CORS |
|
||||
| `docs/prd.md` | Product Requirements Document chatbot |
|
||||
| `docs/v1-arhitectura.md` | Arhitectură Flowise + Groq |
|
||||
| `docs/v2-arhitectura.md` | Arhitectură Claude Agent SDK (planificat) |
|
||||
|
||||
**Quick Start:**
|
||||
```bash
|
||||
# Status servicii
|
||||
ssh root@10.0.20.201 "pct exec 104 -- systemctl status flowise"
|
||||
ssh root@10.0.20.201 "pct exec 104 -- systemctl status ngrok"
|
||||
|
||||
# Restart Flowise
|
||||
ssh root@10.0.20.201 "pct exec 104 -- systemctl restart flowise"
|
||||
|
||||
# Test chatbot
|
||||
curl -s "https://mutual-special-koala.ngrok-free.app/api/v1/prediction/d4911620-07fe-41f8-adb4-f2f52d6ec766" \
|
||||
-X POST -H "Content-Type: application/json" -d '{"question":"test"}'
|
||||
```
|
||||
|
||||
**URL Public:** https://mutual-special-koala.ngrok-free.app
|
||||
**Pagina Web:** https://www.romfast.ro/chatbot_maria.html
|
||||
|
||||
---
|
||||
|
||||
### LXC 108 - Oracle Database
|
||||
**Director:** `lxc108-oracle/`
|
||||
**IP:** 10.0.20.121 | **Host:** pvemini
|
||||
@@ -87,6 +142,31 @@ sqlplus sys/romfastsoft@10.0.20.121:1521/roa as sysdba
|
||||
|
||||
---
|
||||
|
||||
### VM 109 - Windows Standby (Disaster Recovery)
|
||||
**Director:** `vm109-windows-dr/`
|
||||
**Rol:** Backup Oracle database de pe server extern Windows (RMAN)
|
||||
|
||||
| Fișier | Descriere |
|
||||
|--------|-----------|
|
||||
| `README.md` | Configurare DR, RMAN backup, scripturi transfer |
|
||||
| `docs/PLAN_TESTARE_MONITORIZARE.md` | Plan testare și monitorizare DR |
|
||||
| `docs/PROXMOX_NOTIFICATIONS_README.md` | Configurare notificări Proxmox |
|
||||
| `docs/archive/` | Planuri implementare și statusuri anterioare |
|
||||
| `scripts/rman_backup*.bat` | Scripturi RMAN pentru backup Windows |
|
||||
| `scripts/transfer_backups.ps1` | Transfer backup-uri către storage |
|
||||
| `scripts/*-proxmox.sh` | Scripturi monitorizare din Proxmox |
|
||||
|
||||
**Quick Start:**
|
||||
```bash
|
||||
# Monitorizare backup Oracle DR
|
||||
/mnt/e/proiecte/ROMFASTSQL/proxmox/vm109-windows-dr/scripts/oracle-backup-monitor-proxmox.sh
|
||||
|
||||
# Test săptămânal DR
|
||||
/mnt/e/proiecte/ROMFASTSQL/proxmox/vm109-windows-dr/scripts/weekly-dr-test-proxmox.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### VM 201 - Windows 11
|
||||
**Director:** `vm201-windows/`
|
||||
**IP:** DHCP | **Host:** pvemini | **Rol:** Reverse proxy IIS, client aplicații
|
||||
@@ -126,13 +206,14 @@ echo | openssl s_client -connect roa.romfast.ro:443 -servername roa.romfast.ro 2
|
||||
|------|------|-----|----------|--------------|
|
||||
| 100 | portainer | 10.0.20.170 | Docker Management | `cluster/README.md` |
|
||||
| 103 | dokploy | 10.0.20.167 | Deployment Platform | `cluster/README.md` |
|
||||
| 104 | flowise | 10.0.20.161 | Flowise AI + Ollama | `cluster/README.md` |
|
||||
| **104** | **flowise** | **10.0.20.161** | **Flowise AI (Chatbot Maria)** | **`lxc104-flowise/`** |
|
||||
| 106 | gitea | 10.0.20.165 | Git Server | `cluster/README.md` |
|
||||
| **108** | **central-oracle** | **10.0.20.121** | **Oracle XE 21c** | **`lxc108-oracle/`** |
|
||||
|
||||
### Virtual Machines
|
||||
| VMID | Nume | OS | Documentație |
|
||||
|------|------|----|--------------|
|
||||
| **109** | **standby-dr** | **Windows Server** | **`vm109-windows-dr/`** |
|
||||
| **201** | **roacentral** | **Windows 11** | **`vm201-windows/`** |
|
||||
| 300 | Win11-Template | Windows 11 | `cluster/README.md` |
|
||||
|
||||
@@ -146,10 +227,24 @@ echo | openssl s_client -connect roa.romfast.ro:443 -servername roa.romfast.ro 2
|
||||
- **Monitorizez HA cluster** → `cluster/cluster-ha-monitor.sh`
|
||||
- **Gestionez UPS** → `cluster/ups/README.md`
|
||||
|
||||
### Flowise AI / Chatbot Maria (LXC 104)
|
||||
- **Configurez chatbot** → `lxc104-flowise/README.md`
|
||||
- **Troubleshooting CORS/ngrok** → `lxc104-flowise/README.md` → "Troubleshooting"
|
||||
- **PRD Chatbot** → `lxc104-flowise/docs/prd.md`
|
||||
- **Arhitectură viitoare** → `lxc104-flowise/docs/v2-arhitectura.md`
|
||||
|
||||
### Oracle Database (LXC 108)
|
||||
- **Conectez la Oracle** → `lxc108-oracle/README.md` → "Conexiuni Oracle"
|
||||
- **Export/Import DMP** → `lxc108-oracle/README.md` → "Export și Import Data Pump"
|
||||
- **Restart Oracle** → `lxc108-oracle/README.md` → "Restart Oracle"
|
||||
- **Scripturi migrare 10g→21c** → `lxc108-oracle/migration/README.md`
|
||||
- **SQL-uri Oracle 10g** → `lxc108-oracle/sql/roa/`
|
||||
|
||||
### Windows VM 109 - Disaster Recovery
|
||||
- **Configurez RMAN backup** → `vm109-windows-dr/README.md`
|
||||
- **Monitorizez backup-uri** → `vm109-windows-dr/scripts/oracle-backup-monitor-proxmox.sh`
|
||||
- **Test DR săptămânal** → `vm109-windows-dr/scripts/weekly-dr-test-proxmox.sh`
|
||||
- **Plan testare DR** → `vm109-windows-dr/docs/PLAN_TESTARE_MONITORIZARE.md`
|
||||
|
||||
### Windows VM 201
|
||||
- **Reînnoiesc certificate SSL** → `vm201-windows/docs/vm201-certificat-letsencrypt-iis.md`
|
||||
@@ -168,7 +263,9 @@ echo | openssl s_client -connect roa.romfast.ro:443 -servername roa.romfast.ro 2
|
||||
| Portainer Principal | http://10.0.20.170:9443 |
|
||||
| Gitea | http://10.0.20.165:3000 |
|
||||
| Dokploy | http://10.0.20.167:3000 |
|
||||
| Flowise AI | http://10.0.20.161:3000 |
|
||||
| Flowise AI (local) | http://10.0.20.161:3000 |
|
||||
| Flowise AI (public) | https://mutual-special-koala.ngrok-free.app |
|
||||
| Chatbot Maria | https://www.romfast.ro/chatbot_maria.html |
|
||||
|
||||
---
|
||||
|
||||
|
||||
171
proxmox/lxc104-flowise/README.md
Normal file
171
proxmox/lxc104-flowise/README.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# LXC 104 - Flowise AI (Chatbot Maria)
|
||||
|
||||
**Director:** `proxmox/lxc104-flowise/`
|
||||
**VMID:** 104
|
||||
**IP:** 10.0.20.161
|
||||
**Host Proxmox:** pvemini
|
||||
**Servicii:** Flowise AI, ngrok tunnel, Ollama (opțional)
|
||||
|
||||
---
|
||||
|
||||
## Documentație Adițională
|
||||
|
||||
| Fișier | Descriere |
|
||||
|--------|-----------|
|
||||
| `docs/prd.md` | Product Requirements Document - Chatbot Suport Tehnic |
|
||||
| `docs/v1-arhitectura.md` | Arhitectură versiunea 1 (Flowise + Groq) |
|
||||
| `docs/v2-arhitectura.md` | Arhitectură versiunea 2 (Claude Agent SDK) |
|
||||
|
||||
---
|
||||
|
||||
## Componente
|
||||
|
||||
| Componenta | Locație | IP | Port |
|
||||
|------------|---------|-----|------|
|
||||
| Flowise | LXC 104 | 10.0.20.161 | 3000 |
|
||||
| ngrok tunnel | LXC 104 | 10.0.20.161 | - |
|
||||
| Pagina chatbot | romfast.ro | - | 443 |
|
||||
|
||||
## Configurare Flowise
|
||||
|
||||
**Serviciu systemd**: `/etc/systemd/system/flowise.service`
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Flowise Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
ExecStart=/usr/bin/npx flowise start
|
||||
Restart=always
|
||||
Environment=PORT=3000
|
||||
Environment=FLOWISE_USERNAME=admin
|
||||
Environment=FLOWISE_PASSWORD=parola28
|
||||
Environment=CORS_ORIGINS=https://www.romfast.ro,https://romfast.ro
|
||||
WorkingDirectory=/root/.flowise
|
||||
Environment=FLOWISE_DATABASE_PATH=/root/.flowise/database.sqlite
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
**Comenzi utile**:
|
||||
```bash
|
||||
# Status
|
||||
pct exec 104 -- systemctl status flowise
|
||||
|
||||
# Restart
|
||||
pct exec 104 -- systemctl restart flowise
|
||||
|
||||
# Logs
|
||||
pct exec 104 -- journalctl -u flowise -f
|
||||
```
|
||||
|
||||
## Configurare ngrok
|
||||
|
||||
**Configurare**: `/root/.config/ngrok/ngrok.yml`
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
authtoken: 2mo9quiDc23B6U3TtTqWJEleEfM_jYeD1KYe9u7njaaQMZg2
|
||||
tunnels:
|
||||
web:
|
||||
proto: http
|
||||
addr: http://10.0.20.161:3000
|
||||
domain: mutual-special-koala.ngrok-free.app
|
||||
```
|
||||
|
||||
**Serviciu systemd**: `/etc/systemd/system/ngrok.service`
|
||||
|
||||
**URL public**: https://mutual-special-koala.ngrok-free.app
|
||||
|
||||
**API endpoint chatbot**:
|
||||
```
|
||||
POST https://mutual-special-koala.ngrok-free.app/api/v1/prediction/d4911620-07fe-41f8-adb4-f2f52d6ec766
|
||||
```
|
||||
|
||||
**Comenzi utile**:
|
||||
```bash
|
||||
# Status
|
||||
pct exec 104 -- systemctl status ngrok
|
||||
|
||||
# Restart
|
||||
pct exec 104 -- systemctl restart ngrok
|
||||
|
||||
# Verificare tunel activ
|
||||
pct exec 104 -- curl -s http://localhost:4040/api/tunnels
|
||||
|
||||
# Verificare versiune
|
||||
pct exec 104 -- /usr/local/bin/ngrok --version
|
||||
|
||||
# Actualizare ngrok
|
||||
pct exec 104 -- /usr/local/bin/ngrok update
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Eroare CORS
|
||||
**Simptom**: Browser-ul afișează eroare CORS când se încarcă chatbot-ul.
|
||||
|
||||
**Cauza**: Flowise nu are configurată variabila `CORS_ORIGINS`.
|
||||
|
||||
**Soluție**: Adaugă în `/etc/systemd/system/flowise.service`:
|
||||
```
|
||||
Environment=CORS_ORIGINS=https://www.romfast.ro,https://romfast.ro
|
||||
```
|
||||
Apoi: `systemctl daemon-reload && systemctl restart flowise`
|
||||
|
||||
### Eroare ngrok versiune veche (ERR_NGROK_121)
|
||||
**Simptom**: În logs apare:
|
||||
```
|
||||
Your ngrok-agent version "3.16.0" is too old. The minimum supported agent version is "3.19.0"
|
||||
```
|
||||
|
||||
**Cauza**: ngrok a fost actualizat dar serviciul nu a fost restartat. Procesul vechi continuă să ruleze.
|
||||
|
||||
**Soluție**:
|
||||
```bash
|
||||
# Actualizare (dacă nu e deja făcută)
|
||||
pct exec 104 -- /usr/local/bin/ngrok update
|
||||
|
||||
# IMPORTANT: Restart după actualizare
|
||||
pct exec 104 -- systemctl restart ngrok
|
||||
```
|
||||
|
||||
### Verificare rapidă că totul funcționează
|
||||
```bash
|
||||
# Test local Flowise
|
||||
pct exec 104 -- curl -s http://localhost:3000/ | head -5
|
||||
|
||||
# Test tunel ngrok
|
||||
curl -s "https://mutual-special-koala.ngrok-free.app/api/v1/prediction/d4911620-07fe-41f8-adb4-f2f52d6ec766" \
|
||||
-X POST -H "Content-Type: application/json" \
|
||||
-d '{"question":"test"}'
|
||||
```
|
||||
|
||||
## Pagina web
|
||||
|
||||
URL: https://www.romfast.ro/chatbot_maria.html
|
||||
|
||||
Pagina încarcă widget-ul Flowise care se conectează la endpoint-ul ngrok.
|
||||
|
||||
## Istoric incidente
|
||||
|
||||
### 2025-12-30: Chatbot nu funcționa (CORS + ngrok versiune)
|
||||
- **Problemă 1**: Flowise nu avea CORS configurat
|
||||
- **Problemă 2**: ngrok rula versiunea 3.16.0 (actualizată dar nerestartat din octombrie)
|
||||
- **Soluție**: Adăugat CORS_ORIGINS și restart la ambele servicii
|
||||
|
||||
---
|
||||
|
||||
## Legături Utile
|
||||
|
||||
- **Proxmox Index:** `../README.md`
|
||||
- **Cluster Info:** `../cluster/README.md`
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizare:** 2026-01-27
|
||||
**Autor:** Marius Mutu
|
||||
566
proxmox/lxc104-flowise/docs/prd.md
Normal file
566
proxmox/lxc104-flowise/docs/prd.md
Normal file
@@ -0,0 +1,566 @@
|
||||
# Product Requirements Document (PRD)
|
||||
## Chatbot de Suport Tehnic RAG pentru ROMFAST
|
||||
|
||||
**Director:** `proxmox/lxc104-flowise/docs/`
|
||||
**Arhitectură:** Vezi `v1-arhitectura.md` și `v2-arhitectura.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. OVERVIEW ȘI OBIECTIVE
|
||||
|
||||
### 1.1 Problem Statement
|
||||
ROMFAST necesită un sistem de suport tehnic 24/7 care poate:
|
||||
- Răspunde la întrebări tehnice ale clienților
|
||||
- Oferi soluții bazate pe documentația existentă
|
||||
- Menține conversații context-aware
|
||||
- Funcționa independent de orice suport uman
|
||||
- Integrare perfectă cu website-ul existent
|
||||
|
||||
### 1.2 Goals/Objectives
|
||||
**Business Goals:**
|
||||
- Reducerea costurilor de suport cu 50-70%
|
||||
- Îmbunătățirea satisfacției clienților (>4.0/5)
|
||||
- Timp de răspuns < 5 secunde
|
||||
- Disponibilitate 24/7
|
||||
|
||||
**Technical Goals:**
|
||||
- Arhitectură scalabilă și maintainabilă
|
||||
- Upgrade de la Flowise + Groq la Claude Agent SDK
|
||||
- Implementare RAG (Retrieval-Augmented Generation)
|
||||
- Session persistence și context awareness
|
||||
|
||||
### 1.3 Success Metrics
|
||||
- **Response accuracy**: > 90% pe întrebări tehnice
|
||||
- **First query resolution**: > 75%
|
||||
- **User satisfaction**: > 4.0/5 rating
|
||||
- **System uptime**: > 99.5%
|
||||
- **Response time**: < 5 secunde (RAG + Claude)
|
||||
- **Page load time**: < 3 secunde (frontend)
|
||||
|
||||
## 2. USER PERSONAS ȘI USE CASES
|
||||
|
||||
### 2.1 Primary User Personas
|
||||
|
||||
**Persona 1: Client Final**
|
||||
- Nume: Ion Popescu
|
||||
- Rol: Utilizator final al software-ului ROMFAST
|
||||
- Technical skill: Limited
|
||||
- Goals: Rezolvare rapidă a problemelor tehnice
|
||||
- Frustrations: Așteptarea lungă pentru suport, termeni tehnici complecși
|
||||
- Preferred communication: Limbaj simplu, soluții concrete
|
||||
|
||||
**Persona 2: Administrator IT**
|
||||
- Nume: Maria Ionescu
|
||||
- Rol: IT Administrator la client ROMFAST
|
||||
- Technical skill: Advanced
|
||||
- Goals: Soluții tehnice detaliate, troubleshooting avansat
|
||||
- Frustrations: Răspunsuri generice, lipa detaliilor tehnice
|
||||
- Preferred communication: Documentație tehnică, pași detaliați
|
||||
|
||||
**Persona 3: Contabil**
|
||||
- Nume: Elena Vasile
|
||||
- Rol: Utilizator aplicație contabilitate ROMFAST
|
||||
- Technical skill: Basic
|
||||
- Goals: Rezolvare rapidă erori de conectare/date
|
||||
- Preferred communication: Instrucțiuni step-by-step
|
||||
|
||||
### 2.2 Primary Use Cases
|
||||
|
||||
**UC1: Erori de Conexiune**
|
||||
- User întâmpină eroare la conectare
|
||||
- caută soluții rapide și clare
|
||||
- necesită pași concreți de rezolvare
|
||||
|
||||
**UC2: Întrebări Tehnice Generale**
|
||||
- User întreabă despre funcționalități
|
||||
- necesită explicații detaliate
|
||||
- vrea exemple concrete de utilizare
|
||||
|
||||
**UC3: Problema Specifică Software**
|
||||
- User raportează bug/error mesaj specific
|
||||
- necesită identificarea cauzei
|
||||
- vrea soluție/workaround
|
||||
|
||||
**UC4: Integrare și Setup**
|
||||
- Administrator necesită configurare sistem
|
||||
- vrea documentație tehnică detaliată
|
||||
- necessită best practices și configurații
|
||||
|
||||
### 2.2 Telegram Use Cases
|
||||
|
||||
**TU1: Quick Commands Access**
|
||||
- User deschide Telegram bot
|
||||
- Accesează rapid meniul principal cu `/menu`
|
||||
- Navighează prin categorii predefined
|
||||
- Selectează acțiuni rapide fără typing
|
||||
|
||||
**TU2: Session Management**
|
||||
- User începe conversație pe website, continuă pe Telegram
|
||||
- Utilizează `/clear` pentru reset sesiune
|
||||
- Accesează istoric cu `/history`
|
||||
- Menține context între platforme
|
||||
|
||||
**TU3: Structured Problem Reporting**
|
||||
- User folosește menu pentru a selecta categoria problemei
|
||||
- Bot adresează întrebări specifice pentru diagnostic
|
||||
- Oferă solutions step-by-step
|
||||
- Permite escalare către suport uman dacă needed
|
||||
|
||||
**TU4: On-the-Go Assistance**
|
||||
- Mobile user în teren întâmpină problemă
|
||||
- Folosește Telegram pentru quick help
|
||||
- Primește concise, mobile-friendly responses
|
||||
- Generează documentație offline format pentru download
|
||||
|
||||
## 3. FUNCTIONAL REQUIREMENTS
|
||||
|
||||
### 3.1 Core Chatbot Functionality
|
||||
**FR1: Question Processing**
|
||||
- Accept întrebări în limbaj natural (română/engleză)
|
||||
- Parse și understand intent-ul utilizatorului
|
||||
- Extract key terms pentru better RAG retrieval
|
||||
- Handle typos și spelling errors
|
||||
|
||||
**FR2: RAG Integration**
|
||||
- Search în knowledge base pentru relevant content
|
||||
- Ranking results după relevance score
|
||||
- Include source citations în răspunsuri
|
||||
- Handle cases where no relevant info found
|
||||
|
||||
**FR3: Response Generation**
|
||||
- Generate contextual responses folosind Claude Agent SDK
|
||||
- Include step-by-step solutions pentru probleme tehnice
|
||||
- Maintain consistent brand voice (ROMFAST style)
|
||||
- Provide alternative solutions dacă primary nu funcționează
|
||||
|
||||
**FR4: Session Management**
|
||||
- Maintain conversation context across multiple turns
|
||||
- Remember previous questions și answers
|
||||
- Reference earlier conversation în current responses
|
||||
- Session persistence across browser refresh
|
||||
|
||||
### 3.2 User Interface Requirements
|
||||
**FR5: Chat Interface**
|
||||
- Clean, professional UI design matching ROMFAST branding
|
||||
- Responsive design (mobile & desktop)
|
||||
- Real-time typing indicators
|
||||
- Message history scrollable
|
||||
- Input field with character limit
|
||||
|
||||
**FR6: Accessibility Features**
|
||||
- Keyboard navigation support
|
||||
- Screen reader compatibility
|
||||
- High contrast mode option
|
||||
- Font size adjustment
|
||||
|
||||
**FR7: Message Display**
|
||||
- Clear distinction între user și bot messages
|
||||
- Timestamps pentru fiecare message
|
||||
- Source citations displayed clearly
|
||||
- Error messages displayed user-friendly
|
||||
|
||||
### 3.3 Integration Requirements
|
||||
**FR8: URL Parameter Support**
|
||||
- Support `?message=intrebare` parameter
|
||||
- Auto-fill input field cu parameter
|
||||
- Auto-send message după page load
|
||||
- Handle URL encoding/decoding properly
|
||||
|
||||
**FR9: Cross-Origin Communication**
|
||||
- API calls către backend LXC container
|
||||
- CORS configuration pentru cross-origin requests
|
||||
- HTTPS encryption pentru API calls
|
||||
- Error handling pentru network issues
|
||||
|
||||
**FR10: Local Storage Management**
|
||||
- Store session ID în localStorage
|
||||
- Persistent conversation history
|
||||
- Auto-cleanup după X days
|
||||
- Privacy-compliant data storage
|
||||
|
||||
### 3.3 Telegram Bot Functionality
|
||||
**FR11: Command Processing**
|
||||
- Handle slash commands (/menu, /clear, /help, /start, /history)
|
||||
- Parse và process bot commands cu python-telegram-bot
|
||||
- Command descriptions displayed în help menu
|
||||
- Context-aware command availability
|
||||
|
||||
**FR12: Interactive Menu System**
|
||||
- Hierarchical menu structure cu inline keyboards
|
||||
- Category navigation (Conectare, Erori, Configurare, etc.)
|
||||
- Quick action buttons pentru common issues
|
||||
- Back navigation în menu hierarchy
|
||||
- Dynamic menu updates based on context
|
||||
|
||||
**FR13: Session Management (Telegram)**
|
||||
- User session tracking prin Telegram user_id
|
||||
- Cross-platform session synchronization
|
||||
- Session persistence across bot restarts
|
||||
- Private session storage pentru confidentiality
|
||||
|
||||
**FR14: Response Formatting pentru Telegram**
|
||||
- Markdown formatting pentru rich text responses
|
||||
- Code blocks pentru technical instructions
|
||||
- Inline URL generation pentru documentation links
|
||||
- Message length optimization (Telegram 4096 char limit)
|
||||
- Support pentru media attachments (PDF, images)
|
||||
|
||||
**FR15: Error Handling și Recovery (Telegram)**
|
||||
- Graceful error handling pentru API failures
|
||||
- User-friendly error messages în Telegram
|
||||
- Retry mechanisms pentru failed requests
|
||||
- Escalation options pentru complex issues
|
||||
- Fallback messages când RAG returns no results
|
||||
|
||||
## 4. NON-FUNCTIONAL REQUIREMENTS
|
||||
|
||||
### 4.1 Performance Requirements
|
||||
**NFR1: Response Time**
|
||||
- API response < 5 secunde (including RAG retrieval)
|
||||
- Frontend load time < 3 secunde
|
||||
- UI interaction response < 200ms
|
||||
- Real-time typing indicators < 100ms delay
|
||||
|
||||
**NFR2: Scalability**
|
||||
- Support concurrent 100+ users
|
||||
- Handle 1000+ questions per day
|
||||
- Backend auto-scaling cu Docker
|
||||
- Database optimization pentru fast retrieval
|
||||
|
||||
**NFR3: Reliability**
|
||||
- System uptime > 99.5%
|
||||
- Graceful degradation pentru partial failures
|
||||
- Automatic error recovery
|
||||
- Backup și recovery procedures
|
||||
|
||||
### 4.2 Security Requirements
|
||||
**NFR4: Data Privacy**
|
||||
- No personal data storage beyond session
|
||||
- Encrypted API communications
|
||||
- Rate limiting pentru abuse prevention
|
||||
- Input validation pentru XSS prevention
|
||||
|
||||
**NFR5: Authentication**
|
||||
- No user authentication required (anonymous sessions)
|
||||
- Session ID generation secure enough
|
||||
- Protection against session hijacking
|
||||
- CSRF protection pentru API calls
|
||||
|
||||
### 4.3 Maintainability
|
||||
**NFR6: Code Quality**
|
||||
- Clean, documented code
|
||||
- Separation of concerns
|
||||
- Unit tests pentru critical components
|
||||
- CI/CD pipeline pentru deployments
|
||||
|
||||
**NFR7: Monitoring și Debugging**
|
||||
- Comprehensive logging
|
||||
- Performance metrics collection
|
||||
- Error tracking și alerting
|
||||
- User interaction analytics
|
||||
|
||||
## 5. TECHNICAL ARCHITECTURE
|
||||
|
||||
### 5.1 Frontend Requirements
|
||||
**TR1: Technology Stack**
|
||||
- HTML5 semantic markup
|
||||
- ES6+ JavaScript (vanilla, no frameworks)
|
||||
- CSS3 cu modern layout (Grid/Flexbox)
|
||||
- Fetch API pentru backend communication
|
||||
|
||||
**TR2: Component Architecture**
|
||||
- Modular JavaScript structure
|
||||
- Event-driven architecture
|
||||
- Component-based UI elements
|
||||
- Plugin-ready architecture pentru future extensions
|
||||
|
||||
### 5.2 Backend Requirements
|
||||
**TR3: API Layer**
|
||||
- FastAPI RESTful endpoints
|
||||
- JSON request/response format
|
||||
- HTTP status codes standard
|
||||
- OpenAPI documentation
|
||||
|
||||
**TR4: AI/ML Integration**
|
||||
- Claude Agent SDK integration
|
||||
- RAG pipeline cu Chroma vector DB
|
||||
- Embedding models pentru text processing
|
||||
- Context management pentru conversations
|
||||
|
||||
**TR5: Data Layer**
|
||||
- ChromaDB pentru vector storage
|
||||
- In-memory session store
|
||||
- File-based knowledge base storage
|
||||
- Backup procedures pentru data persistence
|
||||
|
||||
### 5.3 Infrastructure Requirements
|
||||
**TR6: Deployment Architecture**
|
||||
- Docker containerization
|
||||
- Proxmox LXC deployment
|
||||
- Static IP configuration
|
||||
- SSL certificate management
|
||||
|
||||
**TR7: Network Requirements**
|
||||
- Public IP exposure pentru API
|
||||
- Firewall configuration
|
||||
- DDoS protection setup
|
||||
- CDN integration caching (opțional)
|
||||
|
||||
### 5.4 Telegram Integration Architecture**
|
||||
**TR8: Telegram Bot Requirements**
|
||||
- **Bot Framework**: python-telegram-bot library
|
||||
- **Bot Commands**: Structured commands cu slash (/menu, /clear, /help)
|
||||
- **Menu System**: Interactive inline keyboards pentru navigation
|
||||
- **Session Management**: Per-user session persistence
|
||||
- **Message Types**: Support text, commands, și callback queries
|
||||
|
||||
**TR9: Claude Agent SDK Integration cu Telegram**
|
||||
- **Message Processing**: Claude responses adapted pentru Telegram format
|
||||
- **Tool Integration**: MCP servers accessible din Telegram context
|
||||
- **Session Continuity**: Same session across website și Telegram
|
||||
- **Context Preservation**: Conversation history maintained platform-agostic
|
||||
|
||||
**TR10: Backend Communication**
|
||||
- **Shared Service**: Common backend service pentru website și Telegram
|
||||
- **Session Synchronization**: Sync sessions între platforms
|
||||
- **Response Formatting**: Platform-specific response formatting
|
||||
- **Error Handling**: Graceful degradation pentru Telegram limitations
|
||||
|
||||
**TR11: Telegram-Specific Features**
|
||||
- **Command Handlers**: /start, /help, /menu, /clear, /history
|
||||
- **Interactive Menus**: Category navigation, quick actions
|
||||
- **Callback Queries**: Menu selections, confirmations
|
||||
- **Status Messages**: Typing indicators, processing states
|
||||
|
||||
## 6. USER EXPERIENCE REQUIREMENTS
|
||||
|
||||
### 6.1 Interaction Design
|
||||
**UX1: Conversation Flow**
|
||||
- Natural conversatională flow
|
||||
- Proactive suggestions pentru follow-up
|
||||
- Clear confirmation messages
|
||||
- graceful handling pentru misunderstood questions
|
||||
|
||||
**UX2: Error Management**
|
||||
- Friendly error messages
|
||||
- Alternative suggestions când nu înțeleg
|
||||
- Option to rephrase questions
|
||||
- Human hand-off option (future)
|
||||
|
||||
**UX3: Visual Design**
|
||||
- ROMFAST brand alignment (colors, fonts)
|
||||
- Professional appearance
|
||||
- Intuitive UI elements
|
||||
- Consistent spacing și typography
|
||||
|
||||
### 6.2 Telegram User Experience
|
||||
**UX6: Telegram Bot Interface**
|
||||
- Intuitive command menu structure
|
||||
- Clear menu labels și descriptions
|
||||
- Consistent button design și placement
|
||||
- Responsive layout pentru mobile screens
|
||||
|
||||
**UX7: Telegram Commands Design**
|
||||
- **/start**: Welcome message și quick tutorial
|
||||
- **/menu**: Interactive menu cu main categories
|
||||
- **/clear**: Clear current session și start fresh
|
||||
- **/help**: List all available commands și usage
|
||||
- **/history**: Show conversation history summary
|
||||
|
||||
**UX8: Telegram Navigation Patterns**
|
||||
- Hierarchical menu flow cu back buttons
|
||||
- Quick return to main menu option
|
||||
- Context-sensitive menu items
|
||||
- Visual feedback pentru button clicks
|
||||
|
||||
**UX9: Telegram Response Structure**
|
||||
- Short, mobile-friendly responses
|
||||
- Bulleted lists pentru step-by-step instructions
|
||||
- Code blocks formatted properly
|
||||
- Emojis în moderation în brand consistency
|
||||
|
||||
### 6.4 Accessibility și Usability
|
||||
**UX5: Mobile Experience**
|
||||
- Touch-friendly interface
|
||||
- Optimized pentru smartphones
|
||||
- Vertical layout preference
|
||||
- Voice input support (future)
|
||||
|
||||
**UX6: Localization**
|
||||
- Limbavă română primary
|
||||
- English as secondary
|
||||
- Date/times local format
|
||||
- Currency formatting (dacă relevant)
|
||||
|
||||
## 7. CONSTRAINTS ȘI ASSUMPTIONS
|
||||
|
||||
### 7.1 Technical Constraints
|
||||
**C1: Hosting Environment**
|
||||
- Frontend: Shared hosting (no server-side access)
|
||||
- Backend: LXC Docker container limits
|
||||
- No direct database access from frontend
|
||||
- Static file serving constraints
|
||||
|
||||
**C2: Budget Constraints**
|
||||
- Claire Max subscription cost limits
|
||||
- LXC resource limits (CPU/RAM)
|
||||
- Third-party service dependencies
|
||||
- Maintenance cost considerations
|
||||
|
||||
### 7.2 Business Constraints
|
||||
**C3: Timeline**
|
||||
- Maximum 5 days pentru implementation
|
||||
- Parallel development possible
|
||||
- Phased roll-out approach
|
||||
- Minimal disruption la existing services
|
||||
|
||||
**C4: Compliance**
|
||||
- GDPR compliance pentru user data
|
||||
- No sensitive data storage
|
||||
- Data retention policies
|
||||
- User consent requirements
|
||||
|
||||
### 7.3 Assumptions
|
||||
**A1: User Behavior**
|
||||
- Users comfortable cu chat interfaces
|
||||
- Basic computer literacy
|
||||
- Access la modern browsers
|
||||
- Stable internet connection
|
||||
|
||||
**A2: Technical Environment**
|
||||
- Modern browser support (last 2 versions)
|
||||
- JavaScript enabled
|
||||
- HTTPS support
|
||||
- Mobile browser compatibility
|
||||
- Telegram app access (mobile și desktop)
|
||||
- Stable internet connection pentru API calls
|
||||
|
||||
## 8. SUCCESS CRITERIA ȘI LAUNCH REQUIREMENTS
|
||||
|
||||
### 8.1 MVP Definition
|
||||
**Minimum Viable Product includes:**
|
||||
- Basic chat interface with RAG responses
|
||||
- Session persistence
|
||||
- URL parameter support
|
||||
- Mobile responsive design
|
||||
- Basic error handling
|
||||
|
||||
### 8.2 Launch Criteria
|
||||
**Technical readiness:**
|
||||
- All functional requirements implemented
|
||||
- Security testing completed
|
||||
- Performance benchmarks met
|
||||
- Backup procedures documented
|
||||
|
||||
**Business readiness:**
|
||||
- Knowledge base populated cu relevant content
|
||||
- Support team trained pe system
|
||||
- User documentation prepared
|
||||
- Communication plan ready
|
||||
- Telegram bot published și functional
|
||||
- Cross-platform session testing completed
|
||||
|
||||
### 8.3 Post-Launch Requirements
|
||||
**PL1: Monitoring și Analytics**
|
||||
- User interaction tracking
|
||||
- Response quality metrics
|
||||
- System performance monitoring
|
||||
- Error rate tracking
|
||||
|
||||
**PL2: Iteration Plan**
|
||||
- Weekly performance reviews
|
||||
- Monthly content updates
|
||||
- Quarterly feature enhancements
|
||||
- Annual architecture review
|
||||
|
||||
## 9. RISK ASSESSMENT ȘI MITIGATION
|
||||
|
||||
### 9.1 Technical Risks
|
||||
**Risk 1: Claude API Limits**
|
||||
- Impact: Service degradation
|
||||
- Probability: Medium
|
||||
- Mitigation: Local fallbacks, graceful degradation
|
||||
|
||||
**Risk 2: Cross-Origin Issues**
|
||||
- Impact: Frontend-backend communication failure
|
||||
- Probability: High
|
||||
- Mitigation: CORS testing, fallback mechanisms
|
||||
|
||||
**Risk 3: Knowledge Base Incomplet**
|
||||
- Impact: Poor response quality
|
||||
- Probability: Medium
|
||||
- Mitigation: Content gaps analysis, gradual population
|
||||
|
||||
### 9.2 Business Risks
|
||||
**Risk 4: User Adoption Low**
|
||||
- Impact: Investment not justified
|
||||
- Probability: Medium
|
||||
- Mitigation: User training, promotional activities
|
||||
|
||||
**Risk 5: Performance Issues**
|
||||
- Impact: Poor user experience
|
||||
- Probability: Medium
|
||||
- Mitigation: Performance testing, optimization
|
||||
|
||||
## 10. FUTURE ROADMAP (Post-Launch)
|
||||
|
||||
### 10.1 Phase 1 (1-3 months)
|
||||
- **Telegram Bot Launch**: Complete Telegram integration
|
||||
- **Advanced Commands**: /ticket, /escalate, /feedback
|
||||
- **Media Support**: File upload/download capabilities
|
||||
- **Analytics Dashboard**: Admin interface pentru insights
|
||||
- **Knowledge Base Admin**: easier content management
|
||||
|
||||
### 10.2 Phase 2 (3-6 months)
|
||||
- **Multi-platform Sync**: Seamless session sync website ↔ Telegram
|
||||
- **Voice Input Support**: Dictation features pentru mobile
|
||||
- **Integration APIs**: Connect cu CRM/ticket systems
|
||||
- **Advanced Personalization**: User profiles și preferences
|
||||
- **Telegram Channels**: Broadcast announcements și updates
|
||||
|
||||
### 10.3 Phase 3 (6-12 months)
|
||||
- **Video Tutorials**: Embedded video content în responses
|
||||
- **Community Q&A**: Social features pentru peer support
|
||||
- **Analytics Dashboard**: Advanced tracking și insights
|
||||
- **Integration APIs**: Connect cu CRM/ticket systems
|
||||
|
||||
### 10.4 Long-term Vision
|
||||
- **Mobile App**: Native iOS/Android applications
|
||||
- **Voice Assistant**: Phone bot integration
|
||||
- **AI Agent Tools**: Diagnostic și troubleshooting automation
|
||||
- **Predictive Support**: Proactive issue identification
|
||||
|
||||
---
|
||||
|
||||
## ACCEPTANCE CRITERIA
|
||||
|
||||
### Functional Acceptance
|
||||
- [ ] Chatbot answers 90% of technical questions accurately based on knowledge base
|
||||
- [ ] System maintains context across conversation turns
|
||||
- [ ] URL parameter auto-fills and auto-sends messages
|
||||
- [ ] Sessions persist across browser refreshes
|
||||
- [ ] Mobile responsive design works on all major devices
|
||||
- [ ] Error handling provides user-friendly messages
|
||||
|
||||
### Technical Acceptance
|
||||
- [ ] API response time < 5 seconds including RAG
|
||||
- [ ] Frontend loads in < 3 seconds
|
||||
- [ ] System handles 100+ concurrent users
|
||||
- [ ] CORS communication works properly
|
||||
- [ ] SSL encryption implemented for API calls
|
||||
- [ ] Session persistence works reliably
|
||||
|
||||
### Business Acceptance
|
||||
- [ ] User satisfaction score > 4.0/5
|
||||
- [ ] Support cost reduction measurable
|
||||
- [ ] System uptime > 99.5%
|
||||
- [ ] Knowledge base populated with essential documentation
|
||||
- [ ] Support team trained on system operation
|
||||
|
||||
---
|
||||
|
||||
*Document Version: 1.1*
|
||||
*Created: 24 Octombrie 2025*
|
||||
*Last Updated: 24 Octombrie 2025*
|
||||
*Status: Ready for Implementation*
|
||||
*Changes: Added Telegram Bot Integration Section*
|
||||
137
proxmox/lxc104-flowise/docs/v1-arhitectura.md
Normal file
137
proxmox/lxc104-flowise/docs/v1-arhitectura.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Plan: Chatbot RAG pentru romfast.ro (v1)
|
||||
|
||||
**Director:** `proxmox/lxc104-flowise/docs/`
|
||||
**Status:** Implementat parțial (Flowise + Groq)
|
||||
**Versiune următoare:** Vezi `v2-arhitectura.md` pentru Claude Agent SDK
|
||||
|
||||
---
|
||||
|
||||
## ARHITECTURĂ GENERALĂ
|
||||
|
||||
```
|
||||
Website romfast.ro (shared hosting) → HTTPS API calls → Backend Docker LXC → Claude Agent SDK + RAG
|
||||
↑
|
||||
chatbot.html (static + JS)
|
||||
```
|
||||
|
||||
## STRUCTURA SOLUȚIEI
|
||||
|
||||
### Frontend (pe shared hosting romfast.ro)
|
||||
- **chatbot.html**: Pagină statică minimală (skeleton HTML)
|
||||
- **chatbot.js**: Tot codul JavaScript (generează HTML dinamic, face API calls)
|
||||
- **CSS injectat**: Generate dinamic prin JavaScript
|
||||
- **localStorage**: Pentru session persistence
|
||||
|
||||
### Backend (Docker în LXC Proxmox)
|
||||
- **FastAPI**: Doar 2 endpoints (`/ask` și health check)
|
||||
- **Claude Agent SDK**: Integrare pentru răspunsuri inteligente
|
||||
- **RAG System**: Chroma + embeddings pentru knowledge base
|
||||
- **No web serving**: Doar backend API
|
||||
|
||||
### Comunicare
|
||||
- **HTTPS API calls**: Direct de la browser către IP-ul LXC
|
||||
- **CORS**: Configurat în FastAPI pentru cross-origin
|
||||
- **JSON communication**: Standard REST API
|
||||
|
||||
## IMPLEMENTARE
|
||||
|
||||
### Faza 1: Backend LXC (2-3 zile)
|
||||
1. **Setup LXC**: Ubuntu 22.04 cu Docker
|
||||
2. **Build backend**: FastAPI + Claude SDK + RAG
|
||||
3. **Knowledge base**: Upload documente tehnice
|
||||
4. **Test endpoints**: `/ask` și health check
|
||||
|
||||
### Faza 2: Frontend Integration (1-2 zile)
|
||||
1. **chatbot.html**: Adaugă pe website-ul romfast.ro
|
||||
2. **chatbot.js**: JavaScript complete pentru UI și API calls
|
||||
3. **Test communication**: Cross-origin API calls
|
||||
4. **Mobile responsive**: Adaptare pentru mobile
|
||||
|
||||
### Faza 3: Production Setup (1 zi)
|
||||
1. **IP public**: Asigură acces la LXC container
|
||||
2. **Security**: Rate limiting, CORS settings
|
||||
3. **Testing**: Functionality și performance
|
||||
4. **Documentation**: Setup instructions
|
||||
|
||||
## UTILIZARE
|
||||
|
||||
### Access Patterns
|
||||
- **Direct URL**: `romfast.ro/chatbot.html?message=eroare+conexiune`
|
||||
- **Empty start**: `romfast.ro/chatbot.html`
|
||||
- **Link integration**: Din alte pagini cu parameters predefinite
|
||||
|
||||
### User Flow
|
||||
1. **User opens** chatbot.html (cu sau fără message)
|
||||
2. **JavaScript generează** UI-ul dinamic
|
||||
3. **API call către backend** întrebarea
|
||||
4. **Backend procesează** cu Claude + RAG
|
||||
5. **JavaScript afișează** răspunsul și sursele
|
||||
6. **Session persist** în localStorage
|
||||
|
||||
## TECH STACK
|
||||
|
||||
### Frontend (Shared Hosting)
|
||||
- **HTML5** static
|
||||
- **Vanilla JavaScript** (ES6+)
|
||||
- **CSS** generated via JS
|
||||
- **localStorage** pentru sessions
|
||||
- **Fetch API** pentru backend calls
|
||||
|
||||
### Backend (LXC Docker)
|
||||
- **FastAPI** (Python 3.11)
|
||||
- **Claude Agent SDK**
|
||||
- **ChromaDB** (vector storage)
|
||||
- **Uvicorn** (ASGI server)
|
||||
- **Docker** pentru containerization
|
||||
|
||||
### Infrastructure
|
||||
- **Proxmox LXC**: 2 CPU, 2GB RAM, 20GB SSD
|
||||
- **Public IP**: Pentru API access
|
||||
- **HTTPS**: Certificat SSL pentru API
|
||||
- **No reverse proxy**: Direct exposure (simplificat)
|
||||
|
||||
## BENEFICII
|
||||
|
||||
### ✅ Technical
|
||||
- **Fără dependențe de hosting infrastructure**
|
||||
- **Separation of concerns**: UI vs backend
|
||||
- **Scalable backend** independent de frontend
|
||||
- **Easy updates**: Frontend direct pe website
|
||||
|
||||
### ✅ Business
|
||||
- **Zero additional hosting costs**
|
||||
- **Full control** asupra backend
|
||||
- **Professional appearance** pentru clienți
|
||||
- **Multiple entry points**: GET parameters, direct access
|
||||
|
||||
### ✅ Maintenance
|
||||
- **Simple stack**: JS + FastAPI
|
||||
- **Independent deployments**
|
||||
- **Easy debugging** și testing
|
||||
- **Standard web technologies**
|
||||
|
||||
## CONSTRAINTS & SOLUTIONS
|
||||
|
||||
### Constraint: No Nginx access
|
||||
**Solution**: Direct HTTPS API calls către LXC IP
|
||||
|
||||
### Constraint: Shared hosting
|
||||
**Solution**: Frontend static, backend separate
|
||||
|
||||
### Security: Cross-origin requests
|
||||
**Solution**: CORS configuration în FastAPI
|
||||
|
||||
## SUCCESS METRICS
|
||||
|
||||
- **Setup time**: < 5 zile total
|
||||
- **Page load**: < 3 secunde (HTML static)
|
||||
- **API response**: < 5 secunde (RAG + Claude)
|
||||
- **Mobile support**: 100% responsive
|
||||
- **Session persistence**: > 95% reliability
|
||||
|
||||
Acest plan oferă o soluție **practică și implementabilă** în condițiile de shared hosting, cu **arhitectură clar separată** și **deploy minim complex**.
|
||||
|
||||
---
|
||||
|
||||
*Creat: 24 Octombrie 2025*
|
||||
*Status: Plan de arhitectură - așteptare aprobare*
|
||||
133
proxmox/lxc104-flowise/docs/v2-arhitectura.md
Normal file
133
proxmox/lxc104-flowise/docs/v2-arhitectura.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Arhitectură Chatbot Maria v2 - Claude Agent SDK
|
||||
|
||||
**Director:** `proxmox/lxc104-flowise/docs/`
|
||||
**Status:** Planificat
|
||||
**Versiune anterioară:** Vezi `v1-arhitectura.md` pentru Flowise + Groq
|
||||
|
||||
---
|
||||
|
||||
## 1. Introducere și Context
|
||||
Chatbot-ul de suport tehnic ROMFAST va oferi răspunsuri asistate de RAG și Claude Agent SDK atât pe website, cât și în Telegram. Arhitectura propusă trebuie să asigure timpul de răspuns sub 5 secunde, disponibilitate ridicată, persistența sesiunilor și integrarea cu infrastructura existentă (Docker în LXC Proxmox).
|
||||
|
||||
## 2. Mapare Cerințe → Soluții Arhitecturale
|
||||
| Cerință cheie | Soluție arhitecturală |
|
||||
| --- | --- |
|
||||
| FR1, FR2, FR3 | Pipeline RAG (ChromaDB + Claude Agent SDK) cu preprocesare întrebări și scorare rezultate |
|
||||
| FR4, FR10 | Session store (Redis sau SQLite in-memory backup) accesat de frontend, backend și Telegram |
|
||||
| FR5–FR7 | Frontend web modular (HTML/JS/CSS) + API JSON standard |
|
||||
| FR8, FR9 | FastAPI gateway cu CORS, HTTPS și suport query param `message` |
|
||||
| FR11–FR15 | Microserviciu Telegram bazat pe python-telegram-bot conectat la același backend |
|
||||
| NFR1–NFR3 | Containere Docker separate, auto-restart Proxmox, load shedding și cache răspunsuri |
|
||||
| NFR4–NFR7 | TLS end-to-end, rate limiting, observability (logging centralizat, metrics, alerting) |
|
||||
|
||||
## 3. Vedere Arhitecturală de Nivel Înalt
|
||||
- **Client Web**: UI chat responsiv, gestionează sesiuni locale și comunică cu backend via Fetch API.
|
||||
- **Gateway API (FastAPI)**: Orchestrare request-uri, autentificare sesiunilor anonime, fan-out către servicii interne.
|
||||
- **Serviciu RAG**: Normalizare întrebări, căutare vectorială în ChromaDB, construirea contextului și apel Claude.
|
||||
- **ChromaDB + Knowledge Store**: Vectori și metadate pentru documentația ROMFAST, pipeline ingestie periodică.
|
||||
- **Session Store**: Stocare conversații și context (Redis/SQLite replicat) pentru persistență cross-platform.
|
||||
- **Telegram Bot Service**: Handler comenzi, UI prin inline keyboards, sincronizare sesiuni cu gateway-ul.
|
||||
- **Observability Stack**: Logging structurat, export metrics (Prometheus compatible) și alerting.
|
||||
- **Infrastructură Docker pe Proxmox LXC**: Containere orchestrate manual sau cu docker-compose, SSL terminat via Traefik/nginx reverse proxy.
|
||||
|
||||
## 4. Descriere Componentă cu Componentă
|
||||
### 4.1 Client Web
|
||||
- **Responsabilități**: UI chat, tip indicators, gestionare localStorage (ID sesiune, istoric recent), trimis întrebări, afișare surse.
|
||||
- **Tehnologii**: HTML5, CSS3 (Flex/Grid), ES6 modules, Fetch API, Web Workers opțional pentru preprocesare.
|
||||
- **Interfețe**: API REST `/api/chat`, `/api/session`, evenimente SSE/WebSocket pentru actualizări opționale.
|
||||
- **Scalare**: Servire statică prin CDN/lightweight web server; caching agresiv pentru assets.
|
||||
|
||||
### 4.2 Gateway API (FastAPI)
|
||||
- **Responsabilități**: Validare input, rate limiting, orchestrare RAG, management erori, transformare răspunsuri.
|
||||
- **Tehnologii**: FastAPI, Uvicorn, Pydantic, middleware CORS/HTTPS, JWT stateless pentru sesiuni anonime (semnare internă).
|
||||
- **Interfețe**: REST endpoints `/chat`, `/session`, `/history`, `/health`; webhook Telegram `/telegram/webhook`.
|
||||
- **Scalare**: Replicare container, load balancing prin reverse proxy, timeouts stricte, circuit breaker către Claude API.
|
||||
|
||||
### 4.3 Serviciu RAG
|
||||
- **Responsabilități**: Curățare întrebări, vectorizare (embedding), căutare top-k în ChromaDB, compunere context și prompt engineering pentru Claude.
|
||||
- **Tehnologii**: Python, Claude Agent SDK, sentence-transformers (embedding), langchain-like orchestrator.
|
||||
- **Interfețe**: gRPC/REST intern expus gateway-ului, contract clar pentru request/response (query, session_id, metadata).
|
||||
- **Scalare**: Worker pool asincron, caching răspunsuri populare, fallback la knowledge base static în caz de indisponibilitate Claude.
|
||||
|
||||
### 4.4 ChromaDB și Knowledge Store
|
||||
- **Responsabilități**: Stocare vectori, metadate, versiuni documentație.
|
||||
- **Tehnologii**: ChromaDB container, storage montat persistent (volume Proxmox), pipeline ingestie (Python ETL) cu scheduler.
|
||||
- **Interfețe**: API nativ Chroma, scripturi ingestie (loaders), export pentru backup.
|
||||
- **Scalare**: Partajare colecții pe namespace, sharding logic pentru domenii (Contabilitate, Admin, etc.), snapshot backup zilnic.
|
||||
|
||||
### 4.5 Session Store
|
||||
- **Responsabilități**: Persistență context conversație, state comenzi Telegram, token TTL.
|
||||
- **Tehnologii**: Redis (preferat) cu fallback SQLite on-disk, replică la cald.
|
||||
- **Interfețe**: API key/value, TTL, liste pentru istoricul recent; acces prin SDK Python și JS.
|
||||
- **Scalare**: Master/replica, persistare RDB/AOF, monitorizare memorie.
|
||||
|
||||
### 4.6 Telegram Bot Service
|
||||
- **Responsabilități**: Gestionare comenzi `/start`, `/menu`, etc., generare inline keyboard, relay întrebări către gateway, formatting Markdown.
|
||||
- **Tehnologii**: python-telegram-bot, async handlers, job queue pentru retry.
|
||||
- **Interfețe**: Webhook către gateway, REST fallback polling, servicii interne pentru sesiuni.
|
||||
- **Scalare**: Replici multiple cu queue deduplicare (Redis Streams), respectarea rate limit Telegram.
|
||||
|
||||
### 4.7 Observability și DevOps
|
||||
- **Responsabilități**: Logging centralizat, metrics (latency, usage), alerting, CI/CD pipelines.
|
||||
- **Tehnologii**: Elastic Stack sau Loki+Grafana, Prometheus exporters, Sentry/Opentelemetry pentru tracing.
|
||||
- **Interfețe**: Dashboards Grafana, webhook alerting (Slack/Email), pipeline GitHub Actions.
|
||||
- **Scalare**: Retenție loguri 30 zile, sampling tracing, rotație indices.
|
||||
|
||||
### 4.8 Infrastructură și Securitate
|
||||
- **Responsabilități**: Orchestrare containere, management certificate, firewall, backup.
|
||||
- **Tehnologii**: Docker, docker-compose, Traefik/nginx, Proxmox backup server, CrowdSec/Fail2ban.
|
||||
- **Interfețe**: Reverse proxy, Let’s Encrypt ACME, scripturi deployment.
|
||||
- **Scalare**: Vertical scaling LXC, pregătire migrare spre Kubernetes/Nomad dacă load crește.
|
||||
|
||||
## 5. Fluxuri de Date și Sequencing
|
||||
### 5.1 Întrebare din Client Web
|
||||
1. UI trimite request `POST /api/chat` cu mesaj și session_id.
|
||||
2. Gateway validează, atașează metadata (persona, limbă) și trimite către serviciul RAG.
|
||||
3. Serviciul RAG vectorizează, interoghează ChromaDB, compune prompt cu surse.
|
||||
4. Claude Agent SDK generează răspuns, gateway-l adnotează cu surse și pași.
|
||||
5. Răspunsul este salvat în session store și returnat UI-ului pentru afișare.
|
||||
|
||||
### 5.2 Întrebare din Telegram
|
||||
1. Bot primește mesaj/comandă și trimite payload la webhook-ul gateway-ului.
|
||||
2. Gateway mapează Telegram user_id la session_id comun și procesează similar cu fluxul web.
|
||||
3. Răspunsul este formatat Markdown, validat sub 4096 caractere și trimis înapoi prin bot.
|
||||
4. Istoricul este sincronizat în session store pentru acces cross-platform.
|
||||
|
||||
### 5.3 Manevrarea Erorilor/Fallback
|
||||
1. Dacă Claude sau Chroma sunt indisponibile, gateway revine la răspunsuri cached sau FAQ static.
|
||||
2. În caz de eroare critică, gateway trimite mesaj prietenos utilizatorului și loghează incidentul.
|
||||
3. Scheduler declanșează alerting și reinstanțează containerul afectat.
|
||||
|
||||
## 6. Persistență și Management Date
|
||||
- **Sesiuni**: session store cu TTL configurabil (7 zile), replicat, curățare periodică.
|
||||
- **Vectori**: ChromaDB cu versiuni documente, index rebuild săptămânal, backup incremental.
|
||||
- **Knowledge base raw**: Fișiere markdown/PDF într-un storage versionat (Git + backup Proxmox).
|
||||
- **Loguri și Metrics**: Centralizare în Loki/Elastic, metrics în Prometheus, retenție 30 zile.
|
||||
|
||||
## 7. Integrare Telegram Specifică
|
||||
- Webhook securizat (secret token) expus prin reverse proxy HTTPS.
|
||||
- Mapare user_id ↔ session_id în session store pentru continuitate conversații.
|
||||
- Gestionare rate limiting Telegram cu queue și exponential backoff.
|
||||
- Menu builder modular pentru categorii (Conectare, Erori, Configurare) configurabile din metadata.
|
||||
- Fallback la notificare suport uman prin integrare viitoare (webhook spre ticketing).
|
||||
|
||||
## 8. Securitate, Conformitate și Observabilitate
|
||||
- **Transport**: TLS end-to-end, HSTS, certificate auto-întreținute.
|
||||
- **Rate limiting**: NGINX/Traefik + Redis counters pentru prevenire abuz.
|
||||
- **Validare input**: Sanitizare text, limită caractere, filtrare cod malițios.
|
||||
- **Privacy**: Stocare minimă, criptare at rest pentru vectori și backup, politici GDPR (drept de ștergere).
|
||||
- **Monitoring**: Health checks `/healthz`, dashboards latență, error rate, uptime.
|
||||
- **Alerting**: Prag >3% erori, răspuns >4 secunde, spațiu disk <15% liber.
|
||||
|
||||
## 9. Scalabilitate și Reziliență
|
||||
- Containere separate pentru gateway, RAG, Chroma, Telegram cu resurse dedicate.
|
||||
- Auto-restart și watchdog scripts în Proxmox, backup zilnic volume critice.
|
||||
- Circuit breakers și retry policy către Claude API, degrade gracefully la fallback static.
|
||||
- Posibilă introducere CDN pentru livrare statice și caching răspunsuri frecvente.
|
||||
|
||||
## 10. Roadmap Tehnic (0–6 luni)
|
||||
- **Luna 0–1**: Implementare client web + gateway API + RAG minim (Chroma + Claude), ingestie documentație de bază.
|
||||
- **Luna 1–2**: Adăugare session store distribuit, logging centralizat, pipeline ingestie automat.
|
||||
- **Luna 2–3**: Lansare Telegram bot cu comenzi de bază, sincronizare sesiuni, fallback complet erori.
|
||||
- **Luna 3–4**: Introducere metrics/alerting, optimizare performanță, cache răspunsuri.
|
||||
- **Luna 4–6**: Extindere knowledge base, analytics dashboard, pregătire pentru scaling (replici, load balancing).
|
||||
@@ -29,7 +29,7 @@
|
||||
- **Image:** container-registry.oracle.com/database/express:21.3.0-xe
|
||||
- **Versiune:** Oracle Database 21c Express Edition
|
||||
- **Status:** Running (Up 3+ weeks, healthy)
|
||||
- **Portainer:** http://10.0.20.121:9443
|
||||
- **Portainer:** http://10.0.20.121:9000 (admin / parola281234)
|
||||
|
||||
### Porturi Expuse
|
||||
| Port | Serviciu | Descriere |
|
||||
@@ -489,16 +489,44 @@ ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe tail -100 /opt/oracl
|
||||
|
||||
---
|
||||
|
||||
## 📂 Subdirectoare
|
||||
|
||||
### migration/
|
||||
Scripturi pentru migrarea Oracle 10g → 21c XE:
|
||||
- `00-MASTER-MIGRATION.sh` - Script master orchestrare migrare
|
||||
- `01-setup-oracle21c.sh` - Setup tablespace ROA + useri
|
||||
- `02-export-source.sh` - Export universal (AUTO/MANUAL/LOCAL)
|
||||
- `03-transfer-to-oracle21c.sh` - Transfer fișiere DMP
|
||||
- `04-import-to-oracle21c.sh` - Import scheme + SYS objects
|
||||
- `05-create-synonyms-grants.sh` - Creare sinonime + grant-uri
|
||||
- `06-finalize-migration.sh` - Recompilare + verificare finală
|
||||
|
||||
**Documentație:** `migration/README.md`
|
||||
|
||||
### sql/
|
||||
SQL-uri și packages Oracle:
|
||||
- `sql/roa/` - SQL-uri compatibilitate Oracle 10g (scrie_jc_2007.sql, etc.)
|
||||
- `sql/roa-romconstruct/` - Package PACK_CONTAFIN.pck
|
||||
|
||||
### scripts/
|
||||
Scripturi operaționale:
|
||||
- `export-roa2.sh` - Export PDB roa2
|
||||
- `export-roa2.ps1` - Export pentru Windows
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Legături Utile
|
||||
|
||||
**Pentru detalii Proxmox generale (cluster, toate LXC-uri/VM-uri):**
|
||||
Vezi fișierul: `proxmox/proxmox-ssh-guide.md`
|
||||
Vezi fișierul: `../cluster/README.md`
|
||||
|
||||
**Oracle Enterprise Manager Express:**
|
||||
http://10.0.20.121:5500/em
|
||||
|
||||
**Portainer Docker Management:**
|
||||
http://10.0.20.121:9443
|
||||
- **URL:** http://10.0.20.121:9000
|
||||
- **User:** admin
|
||||
- **Parola:** parola281234
|
||||
|
||||
---
|
||||
|
||||
|
||||
788
proxmox/lxc108-oracle/migration/00-MASTER-MIGRATION.bat
Normal file
788
proxmox/lxc108-oracle/migration/00-MASTER-MIGRATION.bat
Normal file
@@ -0,0 +1,788 @@
|
||||
@echo off
|
||||
REM ==============================================================================
|
||||
REM Script: 00-MASTER-MIGRATION.bat
|
||||
REM Descriere: Master control script - Windows Edition
|
||||
REM Data: 1 Octombrie 2025
|
||||
REM Autor: Migrare Oracle automata
|
||||
REM ==============================================================================
|
||||
REM
|
||||
REM Acest script controleaza intregul proces de migrare Oracle pe Windows
|
||||
REM - Ghideaza utilizatorul prin fiecare pas
|
||||
REM - Suport special pentru UPGRADE IN-PLACE (Oracle vechi → 21c pe acelasi PC)
|
||||
REM - Poate rula scripturi bash prin WSL sau ghidare manuala
|
||||
REM
|
||||
REM ==============================================================================
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM Culori (Windows 10+)
|
||||
set "GREEN=[92m"
|
||||
set "YELLOW=[93m"
|
||||
set "RED=[91m"
|
||||
set "BLUE=[94m"
|
||||
set "NC=[0m"
|
||||
|
||||
REM Banner
|
||||
cls
|
||||
echo.
|
||||
echo ========================================
|
||||
echo MASTER MIGRARE ORACLE 10g - 21c XE
|
||||
echo Windows Edition
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Acest script te va ghida prin intregul proces de migrare Oracle.
|
||||
echo.
|
||||
echo IMPORTANT: Ruleaza ca ADMINISTRATOR!
|
||||
echo.
|
||||
pause
|
||||
|
||||
REM ==============================================================================
|
||||
REM CONFIGURARE MEDIU
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ========================================
|
||||
echo CONFIGURARE CONEXIUNI ORACLE
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Detectare SQLPlus (Oracle Client)
|
||||
set SQLPLUS_AVAILABLE=0
|
||||
where sqlplus >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
set SQLPLUS_AVAILABLE=1
|
||||
echo %GREEN%[✓] SQLPlus disponibil%NC%
|
||||
) else (
|
||||
echo %YELLOW%[!] SQLPlus nu este instalat sau nu este in PATH%NC%
|
||||
)
|
||||
echo.
|
||||
|
||||
echo Unde este instalat Oracle 21c XE?
|
||||
echo 1) Acest PC Windows (local)
|
||||
echo 2) VM/Server Linux (cu WSL pentru scripturi)
|
||||
echo 3) LXC Proxmox (necesita WSL + SSH)
|
||||
echo.
|
||||
set /p ORACLE_LOCATION="Alegere (1/2/3): "
|
||||
|
||||
if "%ORACLE_LOCATION%"=="1" (
|
||||
set ORACLE_CONNECT_TYPE=WINDOWS_LOCAL
|
||||
echo - Oracle 21c: Windows Local
|
||||
) else if "%ORACLE_LOCATION%"=="2" (
|
||||
set /p ORACLE_HOST="IP/hostname server Linux: "
|
||||
set ORACLE_CONNECT_TYPE=LINUX_REMOTE
|
||||
echo - Oracle 21c: Linux Remote ^(!ORACLE_HOST!^)
|
||||
) else if "%ORACLE_LOCATION%"=="3" (
|
||||
set /p PROXMOX_HOST="IP/hostname Proxmox: "
|
||||
set /p LXC_ID="ID LXC: "
|
||||
set ORACLE_CONNECT_TYPE=LXC
|
||||
echo - Oracle 21c: LXC !LXC_ID! @ !PROXMOX_HOST!
|
||||
) else (
|
||||
echo %RED%Alegere invalida!%NC%
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo CONFIGURARE EXPORT
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Cum vrei sa faci EXPORTUL din Oracle sursa?
|
||||
echo 1) AUTOMAT - SSH catre server sursa (export automat)
|
||||
echo 2) MANUAL - Tu exporti, scriptul preia fisierele DMP
|
||||
echo 3) LOCAL - Migrare pe acelasi server (porturi diferite)
|
||||
echo 4) UPGRADE IN-PLACE - Oracle vechi - Oracle nou (acest PC, ghidare completa)
|
||||
echo.
|
||||
set /p EXPORT_CHOICE="Alegere (1/2/3/4): "
|
||||
|
||||
if "%EXPORT_CHOICE%"=="1" (
|
||||
REM Export AUTOMAT via SSH
|
||||
set /p ORACLE_SOURCE_HOST="IP/hostname Oracle sursa: "
|
||||
set /p ORACLE_SOURCE_USER="User SSH: "
|
||||
set /p ORACLE_SOURCE_OS="Tip server sursa (Linux/Windows): "
|
||||
set EXPORT_MODE=AUTO
|
||||
echo - Export AUTOMAT via SSH
|
||||
|
||||
) else if "%EXPORT_CHOICE%"=="2" (
|
||||
REM Export MANUAL
|
||||
set /p EXPORT_DIR="Director unde vei pune fisierele DMP (ex: D:\ORACLE_EXPORT): "
|
||||
set EXPORT_MODE=MANUAL
|
||||
echo - Export MANUAL (tu exporti local)
|
||||
|
||||
) else if "%EXPORT_CHOICE%"=="3" (
|
||||
REM Migrare LOCALA (porturi diferite)
|
||||
echo.
|
||||
echo %YELLOW%Migrare LOCALA detectata (acelasi server)%NC%
|
||||
echo.
|
||||
set /p ORACLE_SOURCE_PORT="Port Oracle SURSA (ex: 1521): "
|
||||
set /p ORACLE_SOURCE_SID="SID Oracle SURSA (ex: XE): "
|
||||
set /p ORACLE_SOURCE_PASS="Password SYSTEM pentru Oracle SURSA: "
|
||||
set /p ORACLE_DEST_PORT="Port Oracle DESTINATIE (ex: 1522): "
|
||||
set /p ORACLE_DEST_SID="SID Oracle DESTINATIE (ex: roa): "
|
||||
set /p EXPORT_DIR="Director pentru export local (ex: D:\oracle-export): "
|
||||
set EXPORT_MODE=LOCAL
|
||||
echo - Export LOCAL (acelasi server: !ORACLE_SOURCE_PORT! - !ORACLE_DEST_PORT!)
|
||||
|
||||
) else if "%EXPORT_CHOICE%"=="4" (
|
||||
REM UPGRADE IN-PLACE
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE ORACLE IN-PLACE - GHIDARE COMPLETA ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo Acest mod te va ghida prin urmatorii pasi:
|
||||
echo 1. 📤 Export DMP din Oracle vechi (pe Windows)
|
||||
echo 2. ⏸️ Oprire servicii Oracle vechi
|
||||
echo 3. 📥 Instalare Oracle 21c XE nou
|
||||
echo 4. 📦 Import DMP in Oracle 21c
|
||||
echo 5. ✅ Verificare si finalizare
|
||||
echo.
|
||||
|
||||
set /p OLD_ORACLE_PORT="Port Oracle VECHI (default 1521): "
|
||||
if "!OLD_ORACLE_PORT!"=="" set OLD_ORACLE_PORT=1521
|
||||
|
||||
set /p OLD_ORACLE_SID="SID Oracle VECHI (ex: XE, ROA): "
|
||||
set /p OLD_ORACLE_PASS="Password SYSTEM pentru Oracle VECHI: "
|
||||
set /p EXPORT_DIR="Director pentru salvare DMP (ex: D:\oracle-export): "
|
||||
|
||||
set EXPORT_MODE=INPLACE
|
||||
set ORACLE_SOURCE_OS=Windows
|
||||
|
||||
echo.
|
||||
echo %GREEN%Configurare UPGRADE IN-PLACE completa!%NC%
|
||||
echo Oracle vechi: !OLD_ORACLE_SID! @ localhost:!OLD_ORACLE_PORT!
|
||||
echo Export in: !EXPORT_DIR!
|
||||
|
||||
) else (
|
||||
echo %RED%Alegere invalida!%NC%
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo REZUMAT CONFIGURARE
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Oracle 21c: %ORACLE_CONNECT_TYPE%
|
||||
echo Export mode: %EXPORT_MODE%
|
||||
if "%EXPORT_MODE%"=="INPLACE" (
|
||||
echo Oracle vechi: !OLD_ORACLE_SID! @ localhost:!OLD_ORACLE_PORT!
|
||||
echo Export dir: !EXPORT_DIR!
|
||||
)
|
||||
echo.
|
||||
set /p CONFIRM="Configurarea este corecta? (Y/N): "
|
||||
if /i not "%CONFIRM%"=="Y" (
|
||||
echo.
|
||||
echo Reconfigureaza si ruleaza din nou
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM MOD OPERARE
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ========================================
|
||||
echo SELECTARE MOD OPERARE
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Selecteaza modul de lucru:
|
||||
echo 1) MIGRARE COMPLETA (Oracle 10g - 21c)
|
||||
echo 2) INSTALARE NOUA (din template-uri)
|
||||
echo.
|
||||
set /p MODE_CHOICE="Alegere (1/2): "
|
||||
|
||||
if "%MODE_CHOICE%"=="1" (
|
||||
set MODE=MIGRATION
|
||||
echo.
|
||||
echo %GREEN%Mod selectat: MIGRARE COMPLETA%NC%
|
||||
) else if "%MODE_CHOICE%"=="2" (
|
||||
set MODE=NEW_INSTALL
|
||||
echo.
|
||||
echo %GREEN%Mod selectat: INSTALARE NOUA%NC%
|
||||
) else (
|
||||
echo %RED%Alegere invalida!%NC%
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
pause
|
||||
|
||||
REM ==============================================================================
|
||||
REM UPGRADE IN-PLACE - WORKFLOW SPECIAL
|
||||
REM ==============================================================================
|
||||
|
||||
if "%EXPORT_MODE%"=="INPLACE" (
|
||||
call :InPlaceUpgrade
|
||||
goto :End
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM WORKFLOW NORMAL (AUTO/MANUAL/LOCAL)
|
||||
REM ==============================================================================
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo PORNIRE MIGRARE
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
if %WSL_AVAILABLE% equ 1 (
|
||||
echo %GREEN%Rulare scripturi bash prin WSL...%NC%
|
||||
echo.
|
||||
|
||||
REM Converteste path-ul Windows la WSL
|
||||
set SCRIPT_PATH=%~dp0
|
||||
set SCRIPT_PATH=!SCRIPT_PATH:\=/!
|
||||
set SCRIPT_PATH=!SCRIPT_PATH:C:=/mnt/c!
|
||||
set SCRIPT_PATH=!SCRIPT_PATH:D:=/mnt/d!
|
||||
set SCRIPT_PATH=!SCRIPT_PATH:E:=/mnt/e!
|
||||
|
||||
echo Scripturi in: !SCRIPT_PATH!
|
||||
echo.
|
||||
|
||||
REM Export variabile environment pentru WSL
|
||||
wsl export EXPORT_MODE="%EXPORT_MODE%"
|
||||
wsl export ORACLE_CONNECT_TYPE="%ORACLE_CONNECT_TYPE%"
|
||||
|
||||
if "%EXPORT_MODE%"=="MANUAL" (
|
||||
wsl export EXPORT_DIR="%EXPORT_DIR%"
|
||||
)
|
||||
|
||||
REM Ruleaza master script bash prin WSL
|
||||
wsl bash -c "cd '!SCRIPT_PATH!' && ./00-MASTER-MIGRATION.sh"
|
||||
|
||||
) else (
|
||||
echo %YELLOW%WSL nu este disponibil!%NC%
|
||||
echo.
|
||||
echo Optiuni:
|
||||
echo 1. Instaleaza WSL: https://docs.microsoft.com/en-us/windows/wsl/install
|
||||
echo 2. SAU ruleaza manual scripturile (vezi README.md)
|
||||
echo.
|
||||
pause
|
||||
)
|
||||
|
||||
goto :End
|
||||
|
||||
REM ==============================================================================
|
||||
REM FUNCTIE: UPGRADE IN-PLACE
|
||||
REM ==============================================================================
|
||||
:InPlaceUpgrade
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE IN-PLACE - PASUL 1/5: EXPORT DMP ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo %YELLOW%IMPORTANT: Executa comenzile de mai jos in acest Command Prompt%NC%
|
||||
echo (sau deschide un nou Command Prompt CA ADMINISTRATOR)
|
||||
echo.
|
||||
pause
|
||||
|
||||
REM Genereaza timestamp pentru fisiere
|
||||
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c%%a%%b)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo COMENZI EXPORT (COPY-PASTE)
|
||||
echo ========================================
|
||||
echo.
|
||||
echo REM Creaza director export
|
||||
echo mkdir "%EXPORT_DIR%" 2^>nul
|
||||
echo cd /d "%EXPORT_DIR%"
|
||||
echo.
|
||||
echo REM Export CONTAFIN_ORACLE
|
||||
echo exp system/%OLD_ORACLE_PASS%@localhost:%OLD_ORACLE_PORT%/%OLD_ORACLE_SID% ^
|
||||
echo FILE=CONTAFIN_ORACLE_%mydate%.dmp ^
|
||||
echo OWNER=CONTAFIN_ORACLE ^
|
||||
echo LOG=contafin_export.log ^
|
||||
echo CONSISTENT=Y
|
||||
echo.
|
||||
echo REM Export MARIUSM_AUTO (daca ai)
|
||||
echo exp system/%OLD_ORACLE_PASS%@localhost:%OLD_ORACLE_PORT%/%OLD_ORACLE_SID% ^
|
||||
echo FILE=MARIUSM_AUTO_%mydate%.dmp ^
|
||||
echo OWNER=MARIUSM_AUTO ^
|
||||
echo LOG=mariusm_export.log ^
|
||||
echo CONSISTENT=Y
|
||||
echo.
|
||||
echo REM Verificare fisiere create
|
||||
echo dir *.dmp
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Creeaza fisier batch pentru export
|
||||
set EXPORT_BATCH=%EXPORT_DIR%\RUN-EXPORT.bat
|
||||
echo @echo off > "%EXPORT_BATCH%"
|
||||
echo REM Export generat automat >> "%EXPORT_BATCH%"
|
||||
echo cd /d "%EXPORT_DIR%" >> "%EXPORT_BATCH%"
|
||||
echo. >> "%EXPORT_BATCH%"
|
||||
echo echo Exportare CONTAFIN_ORACLE... >> "%EXPORT_BATCH%"
|
||||
echo exp system/%OLD_ORACLE_PASS%@localhost:%OLD_ORACLE_PORT%/%OLD_ORACLE_SID% FILE=CONTAFIN_ORACLE_%mydate%.dmp OWNER=CONTAFIN_ORACLE LOG=contafin_export.log CONSISTENT=Y >> "%EXPORT_BATCH%"
|
||||
echo. >> "%EXPORT_BATCH%"
|
||||
echo echo Exportare MARIUSM_AUTO... >> "%EXPORT_BATCH%"
|
||||
echo exp system/%OLD_ORACLE_PASS%@localhost:%OLD_ORACLE_PORT%/%OLD_ORACLE_SID% FILE=MARIUSM_AUTO_%mydate%.dmp OWNER=MARIUSM_AUTO LOG=mariusm_export.log CONSISTENT=Y >> "%EXPORT_BATCH%"
|
||||
echo. >> "%EXPORT_BATCH%"
|
||||
echo echo Export complet! >> "%EXPORT_BATCH%"
|
||||
echo dir *.dmp >> "%EXPORT_BATCH%"
|
||||
echo pause >> "%EXPORT_BATCH%"
|
||||
|
||||
echo %GREEN%[✓] Am creat fisier batch automat: %EXPORT_BATCH%%NC%
|
||||
echo.
|
||||
echo Poti rula direct: "%EXPORT_BATCH%"
|
||||
echo.
|
||||
set /p RUN_EXPORT_NOW="Vrei sa rulez exportul ACUM? (Y/N): "
|
||||
|
||||
if /i "%RUN_EXPORT_NOW%"=="Y" (
|
||||
echo.
|
||||
echo %GREEN%Pornire export...%NC%
|
||||
call "%EXPORT_BATCH%"
|
||||
) else (
|
||||
echo.
|
||||
echo %YELLOW%OK - ruleaza manual exportul cand esti gata%NC%
|
||||
)
|
||||
|
||||
echo.
|
||||
set /p EXPORT_DONE="Ai terminat exportul si ai verificat fisierele DMP? (Y/N): "
|
||||
if /i not "%EXPORT_DONE%"=="Y" (
|
||||
echo.
|
||||
echo Termina exportul si apoi continua...
|
||||
pause
|
||||
goto :InPlaceUpgrade
|
||||
)
|
||||
|
||||
REM Verificare fisiere DMP
|
||||
echo.
|
||||
echo Verificare fisiere in %EXPORT_DIR%...
|
||||
if exist "%EXPORT_DIR%\CONTAFIN*.dmp" (
|
||||
echo %GREEN%[✓] Fisier CONTAFIN gasit!%NC%
|
||||
dir "%EXPORT_DIR%\CONTAFIN*.dmp"
|
||||
) else (
|
||||
echo %RED%[✗] Nu gasesc fisier CONTAFIN in %EXPORT_DIR%%NC%
|
||||
pause
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM PASUL 2: OPRIRE ORACLE VECHI
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE IN-PLACE - PASUL 2/5: OPRIRE ORACLE VECHI ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo %YELLOW%ATENTIE: Vei opri Oracle VECHI!%NC%
|
||||
echo Asigura-te ca ai backup la fisierele DMP!
|
||||
echo.
|
||||
pause
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo COMENZI OPRIRE SERVICII (COPY-PASTE)
|
||||
echo ========================================
|
||||
echo.
|
||||
echo REM Oprire servicii Oracle vechi
|
||||
echo net stop OracleServiceXE
|
||||
echo net stop OracleXETNSListener
|
||||
echo.
|
||||
echo REM Optional: Dezactiveaza pornirea automata
|
||||
echo sc config OracleServiceXE start= disabled
|
||||
echo sc config OracleXETNSListener start= disabled
|
||||
echo.
|
||||
echo REM Verificare
|
||||
echo sc query OracleServiceXE
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Creeaza fisier batch pentru oprire
|
||||
set STOP_BATCH=%EXPORT_DIR%\STOP-ORACLE-OLD.bat
|
||||
echo @echo off > "%STOP_BATCH%"
|
||||
echo REM Oprire Oracle vechi >> "%STOP_BATCH%"
|
||||
echo echo Oprire servicii Oracle vechi... >> "%STOP_BATCH%"
|
||||
echo net stop OracleServiceXE >> "%STOP_BATCH%"
|
||||
echo net stop OracleXETNSListener >> "%STOP_BATCH%"
|
||||
echo echo. >> "%STOP_BATCH%"
|
||||
echo sc config OracleServiceXE start= disabled >> "%STOP_BATCH%"
|
||||
echo sc config OracleXETNSListener start= disabled >> "%STOP_BATCH%"
|
||||
echo echo. >> "%STOP_BATCH%"
|
||||
echo echo Verificare status: >> "%STOP_BATCH%"
|
||||
echo sc query OracleServiceXE >> "%STOP_BATCH%"
|
||||
echo pause >> "%STOP_BATCH%"
|
||||
|
||||
echo %GREEN%[✓] Am creat fisier batch: %STOP_BATCH%%NC%
|
||||
echo.
|
||||
set /p STOP_NOW="Vrei sa opresc Oracle VECHI ACUM? (Y/N): "
|
||||
|
||||
if /i "%STOP_NOW%"=="Y" (
|
||||
echo.
|
||||
echo %GREEN%Oprire Oracle vechi...%NC%
|
||||
call "%STOP_BATCH%"
|
||||
) else (
|
||||
echo.
|
||||
echo %YELLOW%OK - opreste manual Oracle vechi cand esti gata%NC%
|
||||
)
|
||||
|
||||
echo.
|
||||
set /p ORACLE_STOPPED="Ai oprit Oracle vechi? (Y/N): "
|
||||
if /i not "%ORACLE_STOPPED%"=="Y" (
|
||||
echo.
|
||||
echo Opreste Oracle vechi si apoi continua...
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM PASUL 3: INSTALARE ORACLE 21c XE
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE IN-PLACE - PASUL 3/5: INSTALARE ORACLE 21c ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo Urmatorul pas: Instalare Oracle 21c XE
|
||||
echo.
|
||||
echo Optiuni:
|
||||
echo 1. Download Oracle XE 21c pentru Windows:
|
||||
echo https://www.oracle.com/database/technologies/xe-downloads.html
|
||||
echo.
|
||||
echo 2. Fisier: OracleXE213_Win64.zip (~2.5 GB)
|
||||
echo.
|
||||
echo 3. Instalare:
|
||||
echo - Extrage ZIP
|
||||
echo - Ruleaza setup.exe CA ADMINISTRATOR
|
||||
echo - Port: 1521 (acelasi ca Oracle vechi)
|
||||
echo - Password SYS: OraclePass123 (sau custom)
|
||||
echo.
|
||||
echo 4. Dupa instalare, revino aici pentru import!
|
||||
echo.
|
||||
pause
|
||||
|
||||
echo.
|
||||
echo Deschid browser pentru download...
|
||||
start https://www.oracle.com/database/technologies/xe-downloads.html
|
||||
|
||||
echo.
|
||||
set /p ORACLE21_INSTALLED="Ai instalat Oracle 21c XE? (Y/N): "
|
||||
if /i not "%ORACLE21_INSTALLED%"=="Y" (
|
||||
echo.
|
||||
echo Instaleaza Oracle 21c XE si apoi continua...
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM PASUL 4: SETUP + IMPORT
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE IN-PLACE - PASUL 4/5: SETUP ^& IMPORT ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
|
||||
REM ==============================================================================
|
||||
REM RULARE NATIVA WINDOWS (fara WSL)
|
||||
REM ==============================================================================
|
||||
|
||||
if %SQLPLUS_AVAILABLE% equ 1 (
|
||||
echo %GREEN%Rulare setup ^& import NATIV pe Windows...%NC%
|
||||
echo.
|
||||
|
||||
set SCRIPT_DIR=%~dp0
|
||||
set ORACLE21_PASSWORD=OraclePass123
|
||||
|
||||
REM Pasul 1: Setup Oracle 21c
|
||||
echo ========================================
|
||||
echo PASUL 1: Setup Tablespace ^& Useri
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
call :CreateSetupScript
|
||||
|
||||
echo Rulare setup SQL...
|
||||
sqlplus sys/!ORACLE21_PASSWORD!@localhost:1521/XE as sysdba @"%SCRIPT_DIR%setup-windows.sql"
|
||||
|
||||
if %errorlevel% neq 0 (
|
||||
echo %RED%Eroare la setup!%NC%
|
||||
pause
|
||||
goto :End
|
||||
)
|
||||
|
||||
echo %GREEN%[✓] Setup complet!%NC%
|
||||
echo.
|
||||
|
||||
REM Pasul 2: Import DMP
|
||||
echo ========================================
|
||||
echo PASUL 2: Import DMP
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
call :CreateImportScript
|
||||
|
||||
echo Import CONTAFIN_ORACLE...
|
||||
call "%SCRIPT_DIR%import-windows.bat"
|
||||
|
||||
if %errorlevel% neq 0 (
|
||||
echo %YELLOW%Importul poate avea warning-uri normale (obiecte existente)%NC%
|
||||
)
|
||||
|
||||
echo %GREEN%[✓] Import complet!%NC%
|
||||
echo.
|
||||
|
||||
REM Pasul 3: Sinonime + Grant-uri
|
||||
echo ========================================
|
||||
echo PASUL 3: Sinonime ^& Grant-uri
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
call :CreateSynonymsScript
|
||||
|
||||
sqlplus system/!ORACLE21_PASSWORD!@localhost:1521/roa @"%SCRIPT_DIR%synonyms-windows.sql"
|
||||
|
||||
echo %GREEN%[✓] Sinonime create!%NC%
|
||||
echo.
|
||||
|
||||
REM Pasul 4: Finalizare
|
||||
echo ========================================
|
||||
echo PASUL 4: Recompilare ^& Verificare
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
call :CreateFinalizeScript
|
||||
|
||||
sqlplus system/!ORACLE21_PASSWORD!@localhost:1521/roa @"%SCRIPT_DIR%finalize-windows.sql"
|
||||
|
||||
echo %GREEN%[✓] Finalizare completa!%NC%
|
||||
|
||||
) else (
|
||||
echo %YELLOW%SQLPlus nu este disponibil!%NC%
|
||||
echo.
|
||||
echo Pentru import manual, instaleaza Oracle Client si adauga sqlplus in PATH
|
||||
echo SAU urmeaza pasii din README-UPGRADE-IN-PLACE.md
|
||||
echo.
|
||||
pause
|
||||
)
|
||||
|
||||
REM ==============================================================================
|
||||
REM PASUL 5: VERIFICARE
|
||||
REM ==============================================================================
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo ╔══════════════════════════════════════════════════════════════╗
|
||||
echo ║ UPGRADE IN-PLACE - PASUL 5/5: VERIFICARE FINALA ║
|
||||
echo ╚══════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo %GREEN%Migrare completata!%NC%
|
||||
echo.
|
||||
echo Verificare conexiune:
|
||||
echo sqlplus CONTAFIN_ORACLE/OraclePass123@localhost:1521/roa
|
||||
echo.
|
||||
echo Verificare obiecte:
|
||||
echo SELECT COUNT(*) FROM user_tables;
|
||||
echo SELECT COUNT(*) FROM user_objects WHERE status = 'INVALID';
|
||||
echo.
|
||||
echo Log-uri disponibile:
|
||||
echo %EXPORT_DIR%\*.log
|
||||
echo.
|
||||
echo %GREEN%Succes!%NC%
|
||||
echo.
|
||||
pause
|
||||
|
||||
goto :End
|
||||
|
||||
REM ==============================================================================
|
||||
REM FUNCTII GENERARE SCRIPTURI SQL
|
||||
REM ==============================================================================
|
||||
|
||||
:CreateSetupScript
|
||||
echo Generare script setup...
|
||||
set SETUP_SQL=%SCRIPT_DIR%setup-windows.sql
|
||||
|
||||
(
|
||||
echo -- Setup Oracle 21c - Generat automat
|
||||
echo SET ECHO ON
|
||||
echo SET SERVEROUTPUT ON
|
||||
echo.
|
||||
echo -- Conectare la CDB
|
||||
echo ALTER SESSION SET CONTAINER = CDB$ROOT;
|
||||
echo.
|
||||
echo -- Creare PDB ROA ^(daca nu exista^)
|
||||
echo DECLARE
|
||||
echo v_count NUMBER;
|
||||
echo BEGIN
|
||||
echo SELECT COUNT^(^*^) INTO v_count FROM dba_pdbs WHERE pdb_name = 'ROA';
|
||||
echo IF v_count = 0 THEN
|
||||
echo EXECUTE IMMEDIATE 'CREATE PLUGGABLE DATABASE roa ADMIN USER pdbadmin IDENTIFIED BY OraclePass123';
|
||||
echo EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE roa OPEN';
|
||||
echo EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE roa SAVE STATE';
|
||||
echo END IF;
|
||||
echo END;
|
||||
echo /
|
||||
echo.
|
||||
echo -- Conectare la PDB ROA
|
||||
echo ALTER SESSION SET CONTAINER = ROA;
|
||||
echo.
|
||||
echo -- Creare tablespace ROA
|
||||
echo CREATE TABLESPACE roa_data
|
||||
echo DATAFILE 'roa_data01.dbf' SIZE 2G
|
||||
echo AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED
|
||||
echo EXTENT MANAGEMENT LOCAL
|
||||
echo SEGMENT SPACE MANAGEMENT AUTO;
|
||||
echo.
|
||||
echo -- Creare user CONTAFIN_ORACLE
|
||||
echo CREATE USER CONTAFIN_ORACLE IDENTIFIED BY OraclePass123
|
||||
echo DEFAULT TABLESPACE roa_data
|
||||
echo TEMPORARY TABLESPACE temp
|
||||
echo QUOTA UNLIMITED ON roa_data;
|
||||
echo.
|
||||
echo -- Grant-uri CONTAFIN_ORACLE
|
||||
echo GRANT CONNECT, RESOURCE, DBA TO CONTAFIN_ORACLE;
|
||||
echo GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO CONTAFIN_ORACLE;
|
||||
echo GRANT CREATE PROCEDURE, CREATE TRIGGER, CREATE SEQUENCE TO CONTAFIN_ORACLE;
|
||||
echo GRANT CREATE SYNONYM, CREATE PUBLIC SYNONYM TO CONTAFIN_ORACLE;
|
||||
echo.
|
||||
echo -- Creare user MARIUSM_AUTO
|
||||
echo CREATE USER MARIUSM_AUTO IDENTIFIED BY OraclePass123
|
||||
echo DEFAULT TABLESPACE roa_data
|
||||
echo TEMPORARY TABLESPACE temp
|
||||
echo QUOTA UNLIMITED ON roa_data;
|
||||
echo.
|
||||
echo GRANT CONNECT, RESOURCE TO MARIUSM_AUTO;
|
||||
echo GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO MARIUSM_AUTO;
|
||||
echo.
|
||||
echo PROMPT Setup complet!
|
||||
echo EXIT;
|
||||
) > "%SETUP_SQL%"
|
||||
|
||||
echo %GREEN%[✓] Script generat: %SETUP_SQL%%NC%
|
||||
goto :eof
|
||||
|
||||
:CreateImportScript
|
||||
echo Generare script import...
|
||||
set IMPORT_BAT=%SCRIPT_DIR%import-windows.bat
|
||||
|
||||
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c%%a%%b)
|
||||
|
||||
(
|
||||
echo @echo off
|
||||
echo REM Import DMP - Generat automat
|
||||
echo cd /d "%EXPORT_DIR%"
|
||||
echo.
|
||||
echo echo Import CONTAFIN_ORACLE...
|
||||
echo imp system/%ORACLE21_PASSWORD%@localhost:1521/roa ^
|
||||
echo FILE=CONTAFIN_ORACLE*.dmp ^
|
||||
echo FROMUSER=CONTAFIN_ORACLE ^
|
||||
echo TOUSER=CONTAFIN_ORACLE ^
|
||||
echo IGNORE=Y ^
|
||||
echo COMMIT=Y ^
|
||||
echo BUFFER=10485760 ^
|
||||
echo LOG=contafin_import.log
|
||||
echo.
|
||||
echo echo Import MARIUSM_AUTO...
|
||||
echo imp system/%ORACLE21_PASSWORD%@localhost:1521/roa ^
|
||||
echo FILE=MARIUSM_AUTO*.dmp ^
|
||||
echo FROMUSER=MARIUSM_AUTO ^
|
||||
echo TOUSER=MARIUSM_AUTO ^
|
||||
echo IGNORE=Y ^
|
||||
echo COMMIT=Y ^
|
||||
echo BUFFER=10485760 ^
|
||||
echo LOG=mariusm_import.log
|
||||
echo.
|
||||
echo echo Import complet!
|
||||
echo dir *.log
|
||||
) > "%IMPORT_BAT%"
|
||||
|
||||
echo %GREEN%[✓] Script generat: %IMPORT_BAT%%NC%
|
||||
goto :eof
|
||||
|
||||
:CreateSynonymsScript
|
||||
echo Generare script sinonime...
|
||||
set SYN_SQL=%SCRIPT_DIR%synonyms-windows.sql
|
||||
|
||||
(
|
||||
echo -- Sinonime + Grant-uri - Generat automat
|
||||
echo SET ECHO ON
|
||||
echo.
|
||||
echo -- Grant SELECT on CONTAFIN tables to PUBLIC
|
||||
echo DECLARE
|
||||
echo CURSOR c_tables IS
|
||||
echo SELECT table_name FROM dba_tables WHERE owner = 'CONTAFIN_ORACLE';
|
||||
echo BEGIN
|
||||
echo FOR rec IN c_tables LOOP
|
||||
echo BEGIN
|
||||
echo EXECUTE IMMEDIATE 'GRANT SELECT ON CONTAFIN_ORACLE.' ^|^| rec.table_name ^|^| ' TO PUBLIC';
|
||||
echo EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM SYN_' ^|^| rec.table_name ^|^| ' FOR CONTAFIN_ORACLE.' ^|^| rec.table_name;
|
||||
echo EXCEPTION
|
||||
echo WHEN OTHERS THEN NULL;
|
||||
echo END;
|
||||
echo END LOOP;
|
||||
echo END;
|
||||
echo /
|
||||
echo.
|
||||
echo PROMPT Sinonime create!
|
||||
echo EXIT;
|
||||
) > "%SYN_SQL%"
|
||||
|
||||
echo %GREEN%[✓] Script generat: %SYN_SQL%%NC%
|
||||
goto :eof
|
||||
|
||||
:CreateFinalizeScript
|
||||
echo Generare script finalizare...
|
||||
set FIN_SQL=%SCRIPT_DIR%finalize-windows.sql
|
||||
|
||||
(
|
||||
echo -- Finalizare - Generat automat
|
||||
echo SET ECHO ON
|
||||
echo SET SERVEROUTPUT ON
|
||||
echo.
|
||||
echo -- Recompilare obiecte invalide
|
||||
echo BEGIN
|
||||
echo DBMS_UTILITY.compile_schema^(schema =^> 'CONTAFIN_ORACLE', compile_all =^> FALSE^);
|
||||
echo DBMS_UTILITY.compile_schema^(schema =^> 'MARIUSM_AUTO', compile_all =^> FALSE^);
|
||||
echo END;
|
||||
echo /
|
||||
echo.
|
||||
echo -- Verificare obiecte invalide
|
||||
echo SELECT owner, object_type, object_name, status
|
||||
echo FROM dba_objects
|
||||
echo WHERE owner IN ^('CONTAFIN_ORACLE', 'MARIUSM_AUTO'^)
|
||||
echo AND status = 'INVALID';
|
||||
echo.
|
||||
echo -- Statistici finale
|
||||
echo SELECT 'CONTAFIN_ORACLE' AS schema, COUNT^(^*^) AS total_tables
|
||||
echo FROM dba_tables WHERE owner = 'CONTAFIN_ORACLE'
|
||||
echo UNION ALL
|
||||
echo SELECT 'MARIUSM_AUTO', COUNT^(^*^)
|
||||
echo FROM dba_tables WHERE owner = 'MARIUSM_AUTO';
|
||||
echo.
|
||||
echo PROMPT Migrare completa!
|
||||
echo EXIT;
|
||||
) > "%FIN_SQL%"
|
||||
|
||||
echo %GREEN%[✓] Script generat: %FIN_SQL%%NC%
|
||||
goto :eof
|
||||
|
||||
REM ==============================================================================
|
||||
REM FINAL
|
||||
REM ==============================================================================
|
||||
:End
|
||||
echo.
|
||||
echo ========================================
|
||||
echo MIGRARE COMPLETA
|
||||
echo ========================================
|
||||
echo.
|
||||
pause
|
||||
exit /b 0
|
||||
634
proxmox/lxc108-oracle/migration/00-MASTER-MIGRATION.sh
Normal file
634
proxmox/lxc108-oracle/migration/00-MASTER-MIGRATION.sh
Normal file
@@ -0,0 +1,634 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 00-MASTER-MIGRATION.sh
|
||||
# Descriere: Master control script - Orchestrare completa migrare Oracle
|
||||
# Data: 30 Septembrie 2025
|
||||
# Autor: Generare automata - Asistent migrare Oracle
|
||||
#==============================================================================
|
||||
#
|
||||
# Acest script controleaza intregul proces de migrare Oracle 10g → 21c XE
|
||||
# - Ghideaza utilizatorul prin fiecare pas
|
||||
# - Cere confirmare inainte de executie
|
||||
# - Suporta doua moduri: MIGRARE si INSTALARE NOUA
|
||||
#
|
||||
# IMPORTANT: Ruleaza din WSL/Linux cu conexiune SSH la Proxmox
|
||||
#
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Culori pentru output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Functii helper
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_step() {
|
||||
echo -e "${GREEN}[STEP $1/$2]${NC} $3"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
ask_continue() {
|
||||
local default=${2:-N}
|
||||
echo ""
|
||||
if [ "$default" = "Y" ]; then
|
||||
read -p "$(echo -e ${YELLOW}"$1 (Y/n): "${NC})" -n 1 -r
|
||||
REPLY=${REPLY:-Y}
|
||||
else
|
||||
read -p "$(echo -e ${YELLOW}"$1 (y/N): "${NC})" -n 1 -r
|
||||
REPLY=${REPLY:-N}
|
||||
fi
|
||||
echo ""
|
||||
[[ $REPLY =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
# Banner
|
||||
clear
|
||||
print_header "🚀 MASTER MIGRARE ORACLE 10g → 21c XE"
|
||||
|
||||
echo "Acest script te va ghida prin intregul proces de migrare Oracle."
|
||||
echo ""
|
||||
echo "IMPORTANT: Configurare conexiuni necesare!"
|
||||
echo ""
|
||||
|
||||
# =============================================================================
|
||||
# CONFIGURARE MEDIU
|
||||
# =============================================================================
|
||||
|
||||
print_header "CONFIGURARE CONEXIUNI ORACLE"
|
||||
|
||||
echo "Unde este instalat Oracle 21c XE?"
|
||||
echo " 1) LXC Proxmox (Docker container)"
|
||||
echo " 2) VM/Server Linux (direct sau Docker)"
|
||||
echo " 3) VM/Server Windows"
|
||||
echo ""
|
||||
read -p "Alegere (1/2/3): " ORACLE_LOCATION
|
||||
|
||||
case $ORACLE_LOCATION in
|
||||
1)
|
||||
read -p "IP/hostname Proxmox (ex: 10.0.20.201): " PROXMOX_HOST
|
||||
read -p "ID LXC (ex: 108): " LXC_ID
|
||||
read -p "Nume container Docker (ex: oracle-xe): " CONTAINER_NAME
|
||||
ORACLE_CONNECT_TYPE="LXC"
|
||||
export PROXMOX_HOST LXC_ID CONTAINER_NAME
|
||||
;;
|
||||
2)
|
||||
read -p "IP/hostname server Oracle (ex: 10.0.20.201): " ORACLE_HOST
|
||||
read -p "Rulează Oracle în Docker? (y/N): " DOCKER_REPLY
|
||||
if [[ $DOCKER_REPLY =~ ^[Yy]$ ]]; then
|
||||
read -p "Nume container Docker (ex: oracle-xe): " CONTAINER_NAME
|
||||
ORACLE_CONNECT_TYPE="LINUX_DOCKER"
|
||||
else
|
||||
ORACLE_CONNECT_TYPE="LINUX_NATIVE"
|
||||
fi
|
||||
export ORACLE_HOST CONTAINER_NAME
|
||||
;;
|
||||
3)
|
||||
read -p "IP/hostname Windows Oracle (ex: 10.0.20.201): " ORACLE_HOST
|
||||
ORACLE_CONNECT_TYPE="WINDOWS"
|
||||
export ORACLE_HOST
|
||||
;;
|
||||
*)
|
||||
print_error "Alegere invalida!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
export ORACLE_CONNECT_TYPE
|
||||
|
||||
echo ""
|
||||
print_success "Configurare Oracle 21c: $ORACLE_CONNECT_TYPE"
|
||||
echo ""
|
||||
|
||||
echo "Unde este Oracle SURSA (pentru export)?"
|
||||
read -p "IP/hostname Oracle sursa (ex: 10.0.20.122): " ORACLE_SOURCE_HOST
|
||||
export ORACLE_SOURCE_HOST
|
||||
|
||||
echo ""
|
||||
echo "Cum vrei să faci EXPORTUL din Oracle sursa?"
|
||||
echo " 1) AUTOMAT - SSH către server sursa (export automat)"
|
||||
echo " 2) MANUAL - Tu exporti, scriptul preia fișierele DMP"
|
||||
echo " 3) LOCAL - Migrare pe același server (porturi diferite)"
|
||||
echo " 4) UPGRADE IN-PLACE - Oracle vechi → Oracle nou (același PC, ghidare completă)"
|
||||
echo ""
|
||||
read -p "Alegere (1/2/3/4): " EXPORT_CHOICE
|
||||
|
||||
case $EXPORT_CHOICE in
|
||||
1)
|
||||
# Export AUTOMAT via SSH
|
||||
read -p "User SSH pentru export (ex: romfast): " ORACLE_SOURCE_USER
|
||||
read -p "Tip server sursa (Linux/Windows): " ORACLE_SOURCE_OS
|
||||
export ORACLE_SOURCE_USER ORACLE_SOURCE_OS
|
||||
export EXPORT_MODE="AUTO"
|
||||
echo " → Export AUTOMAT via SSH"
|
||||
;;
|
||||
2)
|
||||
# Export MANUAL (user exportă local)
|
||||
read -p "Director unde vei pune fișierele DMP (ex: /mnt/e/ORACLE_EXPORT/dumps): " EXPORT_DIR
|
||||
export EXPORT_DIR
|
||||
export EXPORT_MODE="MANUAL"
|
||||
echo " → Export MANUAL (tu exporti local)"
|
||||
;;
|
||||
3)
|
||||
# Migrare LOCALĂ (același server, porturi diferite)
|
||||
print_warning "Migrare LOCALĂ detectată (același server)"
|
||||
echo ""
|
||||
echo "Pentru migrare locală, ai nevoie de:"
|
||||
echo " - Oracle SURSA pe un port (ex: 1521)"
|
||||
echo " - Oracle DESTINAȚIE pe alt port (ex: 1522)"
|
||||
echo ""
|
||||
read -p "Port Oracle SURSA (ex: 1521): " ORACLE_SOURCE_PORT
|
||||
read -p "SID Oracle SURSA (ex: XE sau ROA): " ORACLE_SOURCE_SID
|
||||
read -p "Password SYSTEM pentru Oracle SURSA: " ORACLE_SOURCE_PASS
|
||||
read -p "Port Oracle DESTINAȚIE (ex: 1522): " ORACLE_DEST_PORT
|
||||
read -p "SID Oracle DESTINAȚIE (ex: roa): " ORACLE_DEST_SID
|
||||
read -p "Director pentru export local (ex: /tmp/oracle-export): " EXPORT_DIR
|
||||
|
||||
export ORACLE_SOURCE_PORT ORACLE_SOURCE_SID ORACLE_SOURCE_PASS
|
||||
export ORACLE_DEST_PORT ORACLE_DEST_SID
|
||||
export EXPORT_DIR="${EXPORT_DIR:-/tmp/oracle-export}"
|
||||
export EXPORT_MODE="LOCAL"
|
||||
echo " → Export LOCAL (același server: $ORACLE_SOURCE_PORT → $ORACLE_DEST_PORT)"
|
||||
;;
|
||||
4)
|
||||
# UPGRADE IN-PLACE (ghidare completă)
|
||||
print_success "🎯 Mod UPGRADE IN-PLACE selectat!"
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||
echo "║ UPGRADE ORACLE IN-PLACE - GHIDARE COMPLETĂ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "Acest mod te va ghida prin următorii pași:"
|
||||
echo " 1. 📤 Export DMP din Oracle vechi (pe Windows)"
|
||||
echo " 2. ⏸️ Oprire servicii Oracle vechi"
|
||||
echo " 3. 📥 Instalare Oracle 21c XE nou"
|
||||
echo " 4. 📦 Import DMP în Oracle 21c"
|
||||
echo " 5. ✅ Verificare și finalizare"
|
||||
echo ""
|
||||
|
||||
read -p "Unde este instalat Oracle VECHI (Linux/Windows): " OLD_ORACLE_OS
|
||||
read -p "Port Oracle VECHI (default 1521): " OLD_ORACLE_PORT
|
||||
OLD_ORACLE_PORT=${OLD_ORACLE_PORT:-1521}
|
||||
|
||||
read -p "SID Oracle VECHI (ex: XE, ROA): " OLD_ORACLE_SID
|
||||
read -p "Password SYSTEM pentru Oracle VECHI: " OLD_ORACLE_PASS
|
||||
read -p "Director pentru salvare DMP (ex: D:\\oracle-export sau /tmp/export): " EXPORT_DIR
|
||||
|
||||
# Detectare tip server
|
||||
if [[ "$OLD_ORACLE_OS" =~ [Ww]indows ]]; then
|
||||
ORACLE_SOURCE_OS="Windows"
|
||||
EXPORT_LOCATION_HINT="📁 Salvează DMP-urile în: $EXPORT_DIR"
|
||||
else
|
||||
ORACLE_SOURCE_OS="Linux"
|
||||
EXPORT_LOCATION_HINT="📁 Salvează DMP-urile în: $EXPORT_DIR"
|
||||
fi
|
||||
|
||||
export ORACLE_SOURCE_OS OLD_ORACLE_PORT OLD_ORACLE_SID OLD_ORACLE_PASS
|
||||
export EXPORT_DIR
|
||||
export EXPORT_MODE="INPLACE"
|
||||
|
||||
echo ""
|
||||
print_success "Configurare UPGRADE IN-PLACE completă!"
|
||||
echo " Oracle vechi: $OLD_ORACLE_SID @ localhost:$OLD_ORACLE_PORT ($ORACLE_SOURCE_OS)"
|
||||
echo " $EXPORT_LOCATION_HINT"
|
||||
;;
|
||||
*)
|
||||
print_error "Alegere invalidă!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
print_success "Configurare completa!"
|
||||
echo ""
|
||||
echo "Rezumat:"
|
||||
echo " Oracle 21c: $ORACLE_CONNECT_TYPE"
|
||||
if [ "$ORACLE_CONNECT_TYPE" = "LXC" ]; then
|
||||
echo " Proxmox: $PROXMOX_HOST"
|
||||
echo " LXC ID: $LXC_ID"
|
||||
echo " Container: $CONTAINER_NAME"
|
||||
elif [ "$ORACLE_CONNECT_TYPE" = "LINUX_DOCKER" ]; then
|
||||
echo " Host: $ORACLE_HOST"
|
||||
echo " Container: $CONTAINER_NAME"
|
||||
else
|
||||
echo " Host: $ORACLE_HOST"
|
||||
fi
|
||||
echo " Oracle 10g: $ORACLE10G_USER@$ORACLE10G_HOST"
|
||||
echo ""
|
||||
|
||||
if ! ask_continue "Configurarea este corecta?"; then
|
||||
print_error "Reconfigureaza si ruleaza din nou"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Selectare MOD
|
||||
print_header "SELECTARE MOD OPERARE"
|
||||
|
||||
echo "Selecteaza modul de lucru:"
|
||||
echo " 1) MIGRARE COMPLETA (Oracle 10g → 21c)"
|
||||
echo " 2) INSTALARE NOUA (din template-uri)"
|
||||
echo ""
|
||||
read -p "Alegere (1/2): " MODE_CHOICE
|
||||
echo ""
|
||||
|
||||
case $MODE_CHOICE in
|
||||
1)
|
||||
MODE="MIGRATION"
|
||||
print_success "Mod selectat: MIGRARE COMPLETA"
|
||||
;;
|
||||
2)
|
||||
MODE="NEW_INSTALL"
|
||||
print_success "Mod selectat: INSTALARE NOUA"
|
||||
;;
|
||||
*)
|
||||
print_error "Alegere invalida!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Export variabile pentru scripturile copil
|
||||
export MIGRATION_MODE=$MODE
|
||||
|
||||
# Variabile configurare
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TOTAL_STEPS=7
|
||||
|
||||
if [ "$MODE" = "NEW_INSTALL" ]; then
|
||||
TOTAL_STEPS=6 # Fara export Oracle 10g
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 0: INSTALARE ORACLE 21c XE (OPTIONAL)
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 0/7: INSTALARE ORACLE 21c XE (OPTIONAL)"
|
||||
|
||||
echo "Daca Oracle 21c XE este deja instalat pe LXC 108, poti sari peste acest pas."
|
||||
echo ""
|
||||
if ask_continue "Vrei sa instalezi Oracle 21c XE acum?"; then
|
||||
print_step "0" "7" "Instalare Oracle 21c XE pe LXC 108..."
|
||||
echo ""
|
||||
echo "Ce face acest script:"
|
||||
echo " - Verifica LXC 108 exista"
|
||||
echo " - Instaleaza Docker (daca nu exista)"
|
||||
echo " - Download Oracle 21c XE image (2-3 GB)"
|
||||
echo " - Sterge XEPDB1 automat"
|
||||
echo " - Creaza PDB ROA"
|
||||
echo " - Optional: PDB ROA2"
|
||||
echo ""
|
||||
echo "Durata estimata: ~15-20 minute"
|
||||
echo ""
|
||||
|
||||
if ask_continue "Continua cu instalarea?"; then
|
||||
if [ -f "$SCRIPT_DIR/00-install-oracle21c-xe.sh" ]; then
|
||||
bash "$SCRIPT_DIR/00-install-oracle21c-xe.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Oracle 21c XE instalat cu succes!"
|
||||
else
|
||||
print_error "Eroare la instalarea Oracle 21c XE!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 00-install-oracle21c-xe.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_warning "Instalare Oracle 21c XE omisa"
|
||||
fi
|
||||
else
|
||||
print_warning "Pasul 0 omis - presupun ca Oracle 21c XE este deja instalat"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 1: SETUP ORACLE 21c XE
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 1/$TOTAL_STEPS: SETUP ORACLE 21c XE"
|
||||
|
||||
echo "Ce face acest script:"
|
||||
echo " - Verifica container oracle-xe"
|
||||
echo " - Verifica PDB ROA"
|
||||
echo " - Creaza tablespace ROA (20GB, autoextend)"
|
||||
echo " - Creaza useri CONTAFIN_ORACLE si MARIUSM_AUTO"
|
||||
if [ "$MODE" = "NEW_INSTALL" ]; then
|
||||
echo " - Prompt pentru nume schema noua (nu MARIUSM_AUTO)"
|
||||
fi
|
||||
echo " - Acorda system privileges + DBMS packages"
|
||||
echo ""
|
||||
echo "Durata estimata: ~3-5 minute"
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa SETUP Oracle 21c?" "Y"; then
|
||||
print_step "1" "$TOTAL_STEPS" "Setup Oracle 21c XE..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/01-setup-oracle21c.sh" ]; then
|
||||
bash "$SCRIPT_DIR/01-setup-oracle21c.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Setup Oracle 21c complet!"
|
||||
else
|
||||
print_error "Eroare la setup Oracle 21c!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 01-setup-oracle21c.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Setup Oracle 21c este obligatoriu! Iesire..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 2: EXPORT ORACLE 10g (doar pentru MIGRATION)
|
||||
# =============================================================================
|
||||
|
||||
if [ "$MODE" = "MIGRATION" ]; then
|
||||
print_header "PASUL 2/$TOTAL_STEPS: EXPORT ORACLE SURSA"
|
||||
|
||||
if [ "$EXPORT_MODE" = "AUTO" ]; then
|
||||
echo "Export AUTOMAT via SSH către server sursa"
|
||||
echo ""
|
||||
echo "Ce face:"
|
||||
echo " - Conectare SSH către $ORACLE_SOURCE_HOST"
|
||||
echo " - Export schema CONTAFIN_ORACLE (~15 min)"
|
||||
echo " - Export schema secundară (~60 min)"
|
||||
if [ "$ORACLE_SOURCE_OS" = "Windows" ]; then
|
||||
echo " - Rulare batch Windows pentru export"
|
||||
else
|
||||
echo " - Rulare script Linux pentru export"
|
||||
fi
|
||||
echo ""
|
||||
echo "Durata estimata: ~75 minute"
|
||||
elif [ "$EXPORT_MODE" = "LOCAL" ]; then
|
||||
echo "Export LOCAL (același server, porturi diferite)"
|
||||
echo ""
|
||||
echo "Ce face:"
|
||||
echo " - Export direct din Oracle sursa (port $ORACLE_SOURCE_PORT)"
|
||||
echo " - Salvare în $EXPORT_DIR"
|
||||
echo " - Verificare conectivitate ambele instanțe Oracle"
|
||||
echo ""
|
||||
echo "Durata estimata: ~75 minute"
|
||||
else
|
||||
echo "Export MANUAL - ghidare pas cu pas"
|
||||
echo ""
|
||||
echo "Vei primi instrucțiuni detaliate pentru export manual"
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa EXPORT din Oracle sursa?" "Y"; then
|
||||
print_step "2" "$TOTAL_STEPS" "Export Oracle sursa..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/02-export-source.sh" ]; then
|
||||
bash "$SCRIPT_DIR/02-export-source.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Export Oracle sursa complet!"
|
||||
else
|
||||
print_error "Eroare la export Oracle sursa!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 02-export-source.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Export Oracle sursa este obligatoriu pentru migrare!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# NEW_INSTALL mode - prompt pentru locatie template-uri
|
||||
print_header "PASUL 2/$TOTAL_STEPS: VERIFICARE TEMPLATE-URI"
|
||||
|
||||
echo "Pentru instalare noua, ai nevoie de fisiere template DMP:"
|
||||
echo " - contafin_oracle.dmp (template CONTAFIN_ORACLE)"
|
||||
echo " - firmanoua.dmp (template pentru schema noua)"
|
||||
echo ""
|
||||
read -p "Introdu calea catre template-uri (ex: /mnt/e/templates): " TEMPLATE_DIR
|
||||
|
||||
if [ ! -f "$TEMPLATE_DIR/contafin_oracle.dmp" ]; then
|
||||
print_error "Nu gasesc: $TEMPLATE_DIR/contafin_oracle.dmp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -p "Nume fisier template pentru schema noua (ex: firmanoua.dmp): " SCHEMA2_TEMPLATE
|
||||
|
||||
if [ ! -f "$TEMPLATE_DIR/$SCHEMA2_TEMPLATE" ]; then
|
||||
print_error "Nu gasesc: $TEMPLATE_DIR/$SCHEMA2_TEMPLATE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Template-uri gasite!"
|
||||
|
||||
# Export variabile pentru pasii urmatori
|
||||
export TEMPLATE_DIR
|
||||
export SCHEMA2_TEMPLATE
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 3: TRANSFER FISIERE
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 3/$TOTAL_STEPS: TRANSFER FISIERE CATRE ORACLE 21c"
|
||||
|
||||
if [ "$MODE" = "MIGRATION" ]; then
|
||||
echo "Ce face acest script:"
|
||||
echo " - Verifica fisiere DMP in /mnt/e/ORACLE_EXPORT/dumps"
|
||||
echo " - Transfer fisiere catre Proxmox /tmp/oracle-import"
|
||||
echo " - Copiaza fisiere in container oracle-xe"
|
||||
else
|
||||
echo "Ce face acest script:"
|
||||
echo " - Transfer template-uri catre Proxmox"
|
||||
echo " - Copiaza in container oracle-xe"
|
||||
fi
|
||||
echo ""
|
||||
echo "Durata estimata: ~10 minute"
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa TRANSFER fisiere?" "Y"; then
|
||||
print_step "3" "$TOTAL_STEPS" "Transfer fisiere..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/03-transfer-to-oracle21c.sh" ]; then
|
||||
bash "$SCRIPT_DIR/03-transfer-to-oracle21c.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Transfer fisiere complet!"
|
||||
else
|
||||
print_error "Eroare la transfer fisiere!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 03-transfer-to-oracle21c.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Transfer fisiere este obligatoriu! Iesire..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 4: IMPORT IN ORACLE 21c
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 4/$TOTAL_STEPS: IMPORT IN ORACLE 21c"
|
||||
|
||||
if [ "$MODE" = "MIGRATION" ]; then
|
||||
echo "Ce face acest script:"
|
||||
echo " - Import SYS objects custom (~5 min)"
|
||||
echo " - Grant-uri SYS → CONTAFIN_ORACLE"
|
||||
echo " - Import CONTAFIN_ORACLE (~15 min)"
|
||||
echo " - Import MARIUSM_AUTO (~90 min)"
|
||||
echo " - Verificare obiecte importate"
|
||||
echo ""
|
||||
echo "Durata estimata: ~2 ore"
|
||||
else
|
||||
echo "Ce face acest script:"
|
||||
echo " - Import template CONTAFIN_ORACLE"
|
||||
echo " - Import template pentru schema noua"
|
||||
echo " - Prompt pentru nume schema"
|
||||
echo ""
|
||||
echo "Durata estimata: ~30 minute"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa IMPORT scheme?" "Y"; then
|
||||
print_step "4" "$TOTAL_STEPS" "Import scheme in Oracle 21c..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/04-import-to-oracle21c.sh" ]; then
|
||||
bash "$SCRIPT_DIR/04-import-to-oracle21c.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Import scheme complet!"
|
||||
else
|
||||
print_error "Eroare la import scheme!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 04-import-to-oracle21c.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Import scheme este obligatoriu! Iesire..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 5: CREARE SINONIME + GRANT-URI
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 5/$TOTAL_STEPS: CREARE SINONIME PUBLICE + GRANT-URI"
|
||||
|
||||
echo "Ce face acest script:"
|
||||
echo " - Creaza 53 sinonime publice (SYN_*)"
|
||||
echo " - Acorda 147 grant-uri catre PUBLIC"
|
||||
echo " - Verificare sinonime si grant-uri"
|
||||
echo ""
|
||||
echo "Durata estimata: ~5 minute"
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa CREARE sinonime + grant-uri?" "Y"; then
|
||||
print_step "5" "$TOTAL_STEPS" "Creare sinonime + grant-uri..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/05-create-synonyms-grants.sh" ]; then
|
||||
bash "$SCRIPT_DIR/05-create-synonyms-grants.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Sinonime + grant-uri create!"
|
||||
else
|
||||
print_error "Eroare la creare sinonime + grant-uri!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 05-create-synonyms-grants.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Creare sinonime este obligatorie! Iesire..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PASUL 6: FINALIZARE MIGRARE
|
||||
# =============================================================================
|
||||
|
||||
print_header "PASUL 6/$TOTAL_STEPS: FINALIZARE MIGRARE"
|
||||
|
||||
echo "Ce face acest script:"
|
||||
echo " - Recompilare obiecte invalide"
|
||||
echo " - Verificare completa migrare (10 teste)"
|
||||
echo " - Raport final"
|
||||
echo ""
|
||||
echo "Durata estimata: ~10 minute"
|
||||
echo ""
|
||||
|
||||
if ask_continue "Executa FINALIZARE migrare?" "Y"; then
|
||||
print_step "6" "$TOTAL_STEPS" "Finalizare migrare..."
|
||||
|
||||
if [ -f "$SCRIPT_DIR/06-finalize-migration.sh" ]; then
|
||||
bash "$SCRIPT_DIR/06-finalize-migration.sh"
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "Finalizare completa!"
|
||||
else
|
||||
print_error "Eroare la finalizare!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "Script 06-finalize-migration.sh nu gasit!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_warning "Finalizare omisa - recomand sa rulezi manual!"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# FINAL - RAPORT COMPLET
|
||||
# =============================================================================
|
||||
|
||||
print_header "🎉 MIGRARE COMPLETA CU SUCCES!"
|
||||
|
||||
echo "Rezumat:"
|
||||
if [ "$MODE" = "MIGRATION" ]; then
|
||||
echo " ✅ Oracle 10g → 21c XE migrat complet"
|
||||
else
|
||||
echo " ✅ Instalare noua completa din template-uri"
|
||||
fi
|
||||
echo " ✅ PDB ROA creat si configurat"
|
||||
echo " ✅ Tablespace ROA (20GB, autoextend)"
|
||||
echo " ✅ Utilizatori creati cu privilegii complete"
|
||||
echo " ✅ Scheme importate cu succes"
|
||||
echo " ✅ Sinonime publice: 53"
|
||||
echo " ✅ Grant-uri PUBLIC: 147"
|
||||
echo " ✅ Obiecte recompilate"
|
||||
echo ""
|
||||
echo "Conexiune test:"
|
||||
echo " sqlplus CONTAFIN_ORACLE/OraclePass123@10.0.20.201:1521/roa"
|
||||
echo ""
|
||||
echo "Verificare PDB:"
|
||||
echo " sqlplus sys/OraclePass123@10.0.20.201:1521/roa as sysdba"
|
||||
echo " SQL> SELECT name, cdb FROM v\$database; -- Trebuie: ROA, NO"
|
||||
echo ""
|
||||
echo "Log-uri disponibile:"
|
||||
echo " - ssh root@10.0.20.201 \"pct exec 108 -- docker exec oracle-xe cat /tmp/contafin_import.log\""
|
||||
echo " - ssh root@10.0.20.201 \"pct exec 108 -- docker exec oracle-xe cat /tmp/mariusm_import.log\""
|
||||
echo ""
|
||||
print_success "TOATE PASII COMPLETI!"
|
||||
echo ""
|
||||
315
proxmox/lxc108-oracle/migration/00-install-oracle21c-xe.sh
Normal file
315
proxmox/lxc108-oracle/migration/00-install-oracle21c-xe.sh
Normal file
@@ -0,0 +1,315 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 00-install-oracle21c-xe.sh
|
||||
# Descriere: Instalare completă Oracle 21c XE în Docker pe LXC Proxmox
|
||||
# - Instalează Docker (dacă nu există)
|
||||
# - Instalează Oracle 21c XE
|
||||
# - Șterge XEPDB1 automat
|
||||
# - Creează PDB ROA (și opțional PDB ROA2)
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 00-install-oracle21c-xe.sh
|
||||
# Unde: Pe host Proxmox (sau în LXC prin pct exec)
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "INSTALARE ORACLE 21c XE PE LXC + DOCKER"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Configurare
|
||||
ORACLE_PWD="OraclePass123"
|
||||
LXC_ID="108"
|
||||
PROXMOX_HOST="10.0.20.201"
|
||||
CONTAINER_NAME="oracle-xe"
|
||||
ORACLE_IMAGE="container-registry.oracle.com/database/express:21.3.0-xe"
|
||||
|
||||
# Verificare dacă rulează pe Proxmox sau trebuie SSH
|
||||
if [ -f "/etc/pve/.version" ]; then
|
||||
echo "✓ Rulează direct pe Proxmox host"
|
||||
PVE_CMD=""
|
||||
else
|
||||
echo "Conectare la Proxmox ${PROXMOX_HOST}..."
|
||||
PVE_CMD="ssh root@${PROXMOX_HOST}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "PASUL 1/7: VERIFICARE LXC ${LXC_ID}"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Verificare LXC există
|
||||
if ! ${PVE_CMD} pct status ${LXC_ID} &>/dev/null; then
|
||||
echo "ERROR: LXC ${LXC_ID} nu există!"
|
||||
echo ""
|
||||
echo "Creează LXC manual:"
|
||||
echo " pct create ${LXC_ID} local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \\"
|
||||
echo " --hostname oracle-db \\"
|
||||
echo " --memory 8192 \\"
|
||||
echo " --cores 4 \\"
|
||||
echo " --rootfs local-lvm:32 \\"
|
||||
echo " --net0 name=eth0,bridge=vmbr0,ip=dhcp \\"
|
||||
echo " --features nesting=1,keyctl=1"
|
||||
echo " pct start ${LXC_ID}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start LXC dacă e oprit
|
||||
if ! ${PVE_CMD} pct status ${LXC_ID} | grep -q "running"; then
|
||||
echo "Pornire LXC ${LXC_ID}..."
|
||||
${PVE_CMD} pct start ${LXC_ID}
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
echo "✓ LXC ${LXC_ID} activ"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 2/7: INSTALARE DOCKER"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Verificare Docker instalat
|
||||
if ${PVE_CMD} pct exec ${LXC_ID} -- which docker &>/dev/null; then
|
||||
echo "✓ Docker deja instalat"
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker --version
|
||||
else
|
||||
echo "Instalare Docker..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- bash -c '
|
||||
# Update package list
|
||||
apt-get update
|
||||
|
||||
# Install prerequisites
|
||||
apt-get install -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release
|
||||
|
||||
# Add Docker GPG key
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
|
||||
# Add Docker repository
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
|
||||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Install Docker
|
||||
apt-get update
|
||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
|
||||
# Enable and start Docker
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
echo "Docker version:"
|
||||
docker --version
|
||||
'
|
||||
echo "✓ Docker instalat"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 3/7: DOWNLOAD ORACLE 21c XE IMAGE"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Verificare dacă image-ul există
|
||||
if ${PVE_CMD} pct exec ${LXC_ID} -- docker images | grep -q "express.*21.3.0-xe"; then
|
||||
echo "✓ Oracle XE image deja descărcat"
|
||||
else
|
||||
echo "Download Oracle 21c XE image (~ 2-3 GB)..."
|
||||
echo "Durată estimată: 5-15 minute (depinde de conexiune)"
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker pull ${ORACLE_IMAGE}
|
||||
echo "✓ Oracle XE image descărcat"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 4/7: OPRIRE CONTAINER VECHI (dacă există)"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
if ${PVE_CMD} pct exec ${LXC_ID} -- docker ps -a | grep -q ${CONTAINER_NAME}; then
|
||||
echo "Oprire și ștergere container vechi ${CONTAINER_NAME}..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker stop ${CONTAINER_NAME} 2>/dev/null || true
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker rm ${CONTAINER_NAME} 2>/dev/null || true
|
||||
echo "✓ Container vechi șters"
|
||||
else
|
||||
echo "✓ Nu există container vechi"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 5/7: START ORACLE 21c XE CONTAINER"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Creare directoare pentru date
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- mkdir -p /opt/oracle/oradata
|
||||
|
||||
echo "Pornire container Oracle XE..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker run -d \
|
||||
--name ${CONTAINER_NAME} \
|
||||
--restart=unless-stopped \
|
||||
-p 1521:1521 \
|
||||
-p 5500:5500 \
|
||||
-e ORACLE_PWD=${ORACLE_PWD} \
|
||||
-e ORACLE_CHARACTERSET=AL32UTF8 \
|
||||
-v /opt/oracle/oradata:/opt/oracle/oradata \
|
||||
${ORACLE_IMAGE}
|
||||
|
||||
echo "✓ Container pornit"
|
||||
echo ""
|
||||
echo "Așteptare inițializare Oracle (~ 5-10 minute)..."
|
||||
echo "Monitorizare log: docker logs -f ${CONTAINER_NAME}"
|
||||
echo ""
|
||||
|
||||
# Așteptare până când Oracle este gata
|
||||
TIMEOUT=600 # 10 minute
|
||||
ELAPSED=0
|
||||
INTERVAL=10
|
||||
|
||||
while [ $ELAPSED -lt $TIMEOUT ]; do
|
||||
if ${PVE_CMD} pct exec ${LXC_ID} -- docker logs ${CONTAINER_NAME} 2>&1 | grep -q "DATABASE IS READY TO USE"; then
|
||||
echo ""
|
||||
echo "✓ Oracle 21c XE READY!"
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep $INTERVAL
|
||||
ELAPSED=$((ELAPSED + INTERVAL))
|
||||
done
|
||||
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo ""
|
||||
echo "ERROR: Timeout așteptând Oracle să pornească!"
|
||||
echo "Verifică log-urile: docker logs ${CONTAINER_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 6/7: ȘTERGERE XEPDB1 + CREARE PDB ROA"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
echo "Conectare la CDB și ștergere XEPDB1..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker exec ${CONTAINER_NAME} sqlplus -s sys/${ORACLE_PWD}@localhost:1521/XE as sysdba <<'EOF'
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
-- Închide și șterge XEPDB1
|
||||
ALTER PLUGGABLE DATABASE xepdb1 CLOSE IMMEDIATE;
|
||||
DROP PLUGGABLE DATABASE xepdb1 INCLUDING DATAFILES;
|
||||
|
||||
-- Verificare că XEPDB1 a fost șters
|
||||
SELECT 'PDB după ștergere XEPDB1:' FROM DUAL;
|
||||
SELECT name, open_mode FROM v$pdbs;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ XEPDB1 șters"
|
||||
echo ""
|
||||
|
||||
echo "Creare PDB ROA..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker exec ${CONTAINER_NAME} sqlplus -s sys/${ORACLE_PWD}@localhost:1521/XE as sysdba <<EOF
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
|
||||
-- Creare PDB ROA
|
||||
CREATE PLUGGABLE DATABASE roa
|
||||
ADMIN USER pdb_admin IDENTIFIED BY ${ORACLE_PWD}
|
||||
FILE_NAME_CONVERT=('/opt/oracle/oradata/XE/pdbseed/','/opt/oracle/oradata/XE/roa/');
|
||||
|
||||
-- Deschide PDB ROA
|
||||
ALTER PLUGGABLE DATABASE roa OPEN;
|
||||
ALTER PLUGGABLE DATABASE roa SAVE STATE;
|
||||
|
||||
-- Verificare
|
||||
SELECT name, open_mode FROM v\$pdbs WHERE name='ROA';
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('✓ PDB ROA creat și deschis!');
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ PDB ROA creat"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "PASUL 7/7: PDB ROA2 (OPȚIONAL)"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
read -p "Vrei să creezi și PDB ROA2? (y/N): " -n 1 -r
|
||||
echo ""
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Creare PDB ROA2..."
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker exec ${CONTAINER_NAME} sqlplus -s sys/${ORACLE_PWD}@localhost:1521/XE as sysdba <<EOF
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
-- Creare PDB ROA2
|
||||
CREATE PLUGGABLE DATABASE roa2
|
||||
ADMIN USER pdb_admin IDENTIFIED BY ${ORACLE_PWD}
|
||||
FILE_NAME_CONVERT=('/opt/oracle/oradata/XE/pdbseed/','/opt/oracle/oradata/XE/roa2/');
|
||||
|
||||
-- Deschide PDB ROA2
|
||||
ALTER PLUGGABLE DATABASE roa2 OPEN;
|
||||
ALTER PLUGGABLE DATABASE roa2 SAVE STATE;
|
||||
|
||||
-- Verificare
|
||||
SELECT name, open_mode FROM v\$pdbs WHERE name='ROA2';
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('✓ PDB ROA2 creat și deschis!');
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ PDB ROA2 creat"
|
||||
else
|
||||
echo "✓ PDB ROA2 omis"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ INSTALARE ORACLE 21c XE COMPLETĂ!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Detalii instalare:"
|
||||
echo " - LXC: ${LXC_ID}"
|
||||
echo " - Container: ${CONTAINER_NAME}"
|
||||
echo " - CDB: XE"
|
||||
echo " - PDB: ROA (și ROA2 dacă ai creat)"
|
||||
echo " - XEPDB1: ȘTERS"
|
||||
echo ""
|
||||
echo "Conexiuni:"
|
||||
echo " - CDB: sys/${ORACLE_PWD}@${PROXMOX_HOST}:1521/XE as sysdba"
|
||||
echo " - PDB ROA: sys/${ORACLE_PWD}@${PROXMOX_HOST}:1521/roa as sysdba"
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " - PDB ROA2: sys/${ORACLE_PWD}@${PROXMOX_HOST}:1521/roa2 as sysdba"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Test conexiune:"
|
||||
echo " ${PVE_CMD} pct exec ${LXC_ID} -- docker exec -it ${CONTAINER_NAME} sqlplus sys/${ORACLE_PWD}@localhost:1521/roa as sysdba"
|
||||
echo ""
|
||||
echo "Verificare PDB-uri:"
|
||||
${PVE_CMD} pct exec ${LXC_ID} -- docker exec ${CONTAINER_NAME} sqlplus -s sys/${ORACLE_PWD}@localhost:1521/XE as sysdba <<'EOF'
|
||||
SET PAGESIZE 50
|
||||
SELECT con_id, name, open_mode, restricted FROM v$pdbs ORDER BY con_id;
|
||||
EXIT;
|
||||
EOF
|
||||
echo ""
|
||||
echo "Management container:"
|
||||
echo " Start: ${PVE_CMD} pct exec ${LXC_ID} -- docker start ${CONTAINER_NAME}"
|
||||
echo " Stop: ${PVE_CMD} pct exec ${LXC_ID} -- docker stop ${CONTAINER_NAME}"
|
||||
echo " Logs: ${PVE_CMD} pct exec ${LXC_ID} -- docker logs -f ${CONTAINER_NAME}"
|
||||
echo " Shell: ${PVE_CMD} pct exec ${LXC_ID} -- docker exec -it ${CONTAINER_NAME} bash"
|
||||
echo ""
|
||||
echo "Următorul pas: 01-setup-oracle21c.sh (pentru tablespace + useri)"
|
||||
echo ""
|
||||
209
proxmox/lxc108-oracle/migration/01-setup-oracle21c.sh
Normal file
209
proxmox/lxc108-oracle/migration/01-setup-oracle21c.sh
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 01-setup-oracle21c.sh
|
||||
# Descriere: Pregătire Oracle 21c XE - Creare PDB ROA, Tablespace ROA, Useri
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 01-setup-oracle21c.sh
|
||||
#==============================================================================
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
echo "=========================================="
|
||||
echo "ORACLE 21c XE - SETUP PDB ROA"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Configurare
|
||||
ORACLE_PWD="OraclePass123"
|
||||
CDB_CONNECT="sys/${ORACLE_PWD}@localhost:1521/XE as sysdba"
|
||||
PDB_CONNECT="sys/${ORACLE_PWD}@localhost:1521/roa as sysdba"
|
||||
LXC_ID="108"
|
||||
CONTAINER_NAME="oracle-xe"
|
||||
|
||||
echo "[1/5] Verificare container Oracle XE..."
|
||||
|
||||
# Detectare dacă rulează în LXC sau pe Proxmox
|
||||
if [ -f "/etc/pve/.version" ]; then
|
||||
# Rulează pe Proxmox host
|
||||
CMD_PREFIX="pct exec ${LXC_ID} --"
|
||||
else
|
||||
# Rulează direct în LXC
|
||||
CMD_PREFIX=""
|
||||
fi
|
||||
|
||||
if ! ${CMD_PREFIX} docker ps | grep -q ${CONTAINER_NAME}; then
|
||||
echo "ERROR: Container ${CONTAINER_NAME} nu rulează!"
|
||||
echo ""
|
||||
echo "Opțiuni:"
|
||||
echo " 1. Rulează: bash 00-install-oracle21c-xe.sh"
|
||||
echo " 2. Sau pornește manual: docker start ${CONTAINER_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Container ${CONTAINER_NAME} activ"
|
||||
echo ""
|
||||
|
||||
echo "[2/5] Verificare PDB ROA există..."
|
||||
PDB_EXISTS=$(${CMD_PREFIX} docker exec ${CONTAINER_NAME} sqlplus -s ${CDB_CONNECT} <<'EOF'
|
||||
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF
|
||||
SELECT COUNT(*) FROM v$pdbs WHERE name='ROA';
|
||||
EXIT;
|
||||
EOF
|
||||
)
|
||||
|
||||
if [ "$PDB_EXISTS" = "0" ] || [ -z "$PDB_EXISTS" ]; then
|
||||
echo "ERROR: PDB ROA nu există!"
|
||||
echo ""
|
||||
echo "Rulează mai întâi: bash 00-install-oracle21c-xe.sh"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ PDB ROA există"
|
||||
echo ""
|
||||
|
||||
echo "[3/5] Creare Tablespace ROA..."
|
||||
${CMD_PREFIX} docker exec ${CONTAINER_NAME} sqlplus -s ${PDB_CONNECT} <<EOF
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
|
||||
-- Verificare că suntem în PDB ROA
|
||||
SELECT 'Connected to: ' || name || ' (CDB=' || cdb || ')' FROM v\$database;
|
||||
|
||||
-- Creare tablespace ROA (ca în Oracle 10g)
|
||||
CREATE TABLESPACE ROA
|
||||
DATAFILE '/opt/oracle/oradata/XE/roa/roa_data01.dbf'
|
||||
SIZE 20G AUTOEXTEND ON NEXT 500M MAXSIZE UNLIMITED
|
||||
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
|
||||
SEGMENT SPACE MANAGEMENT AUTO;
|
||||
|
||||
-- Verificare
|
||||
SELECT tablespace_name, status, contents FROM dba_tablespaces WHERE tablespace_name='ROA';
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ Tablespace ROA creat (20GB, autoextend)"
|
||||
echo ""
|
||||
|
||||
echo "[4/5] Creare utilizatori CONTAFIN_ORACLE și schema secundara..."
|
||||
|
||||
# Detectare mod migrare (daca exista variabila exportata din master script)
|
||||
if [ "$MIGRATION_MODE" = "NEW_INSTALL" ]; then
|
||||
echo ""
|
||||
echo "Mod: INSTALARE NOUA"
|
||||
read -p "Introdu numele schemei secundare (ex: FIRMANOUA): " SCHEMA2_NAME
|
||||
SCHEMA2_NAME=$(echo "$SCHEMA2_NAME" | tr '[:lower:]' '[:upper:]')
|
||||
echo "Schema secundara: $SCHEMA2_NAME"
|
||||
export SCHEMA2_NAME
|
||||
else
|
||||
SCHEMA2_NAME="MARIUSM_AUTO"
|
||||
echo "Mod: MIGRARE (schema secundara: MARIUSM_AUTO)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
${CMD_PREFIX} docker exec ${CONTAINER_NAME} sqlplus -s ${PDB_CONNECT} <<EOF
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
|
||||
-- User CONTAFIN_ORACLE
|
||||
CREATE USER CONTAFIN_ORACLE IDENTIFIED BY ${ORACLE_PWD}
|
||||
DEFAULT TABLESPACE ROA
|
||||
TEMPORARY TABLESPACE TEMP
|
||||
QUOTA UNLIMITED ON ROA;
|
||||
|
||||
-- User schema secundara (MARIUSM_AUTO sau custom)
|
||||
CREATE USER ${SCHEMA2_NAME} IDENTIFIED BY ${ORACLE_PWD}
|
||||
DEFAULT TABLESPACE ROA
|
||||
TEMPORARY TABLESPACE TEMP
|
||||
QUOTA UNLIMITED ON ROA;
|
||||
|
||||
-- Verificare
|
||||
SELECT username, default_tablespace, account_status
|
||||
FROM dba_users
|
||||
WHERE username IN ('CONTAFIN_ORACLE','${SCHEMA2_NAME}')
|
||||
ORDER BY username;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ Utilizatori creați (parola: ${ORACLE_PWD})"
|
||||
echo ""
|
||||
|
||||
echo "[5/5] Acordare System Privileges + DBMS Packages..."
|
||||
${CMD_PREFIX} docker exec ${CONTAINER_NAME} sqlplus -s ${PDB_CONNECT} <<EOF
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
|
||||
-- CONTAFIN_ORACLE - Privilegii COMPLETE (ca în 10g)
|
||||
GRANT CONNECT, RESOURCE, DBA TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE SESSION TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE TABLE TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE VIEW TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE SEQUENCE TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE PROCEDURE TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE TRIGGER TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE TYPE TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE SYNONYM TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE PUBLIC SYNONYM TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE DATABASE LINK TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE JOB TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE ANY DIRECTORY TO CONTAFIN_ORACLE;
|
||||
GRANT SELECT ANY TABLE TO CONTAFIN_ORACLE;
|
||||
GRANT INSERT ANY TABLE TO CONTAFIN_ORACLE;
|
||||
GRANT UPDATE ANY TABLE TO CONTAFIN_ORACLE;
|
||||
GRANT DELETE ANY TABLE TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ANY PROCEDURE TO CONTAFIN_ORACLE;
|
||||
GRANT CREATE EXTERNAL JOB TO CONTAFIN_ORACLE;
|
||||
GRANT EXP_FULL_DATABASE TO CONTAFIN_ORACLE;
|
||||
GRANT IMP_FULL_DATABASE TO CONTAFIN_ORACLE;
|
||||
GRANT UNLIMITED TABLESPACE TO CONTAFIN_ORACLE;
|
||||
|
||||
-- Schema secundara - Privilegii Standard
|
||||
GRANT CONNECT, RESOURCE TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE SESSION TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE TABLE TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE VIEW TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE SEQUENCE TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE PROCEDURE TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE TRIGGER TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE TYPE TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE SYNONYM TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE DATABASE LINK TO ${SCHEMA2_NAME};
|
||||
GRANT CREATE JOB TO ${SCHEMA2_NAME};
|
||||
GRANT UNLIMITED TABLESPACE TO ${SCHEMA2_NAME};
|
||||
|
||||
-- Grant-uri DBMS packages
|
||||
GRANT EXECUTE ON DBMS_LOCK TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_SQL TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_UTILITY TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_OUTPUT TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_JOB TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_SCHEDULER TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_LOB TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_XMLGEN TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON DBMS_METADATA TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON UTL_FILE TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ System privileges + DBMS packages acordate"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ SETUP COMPLET!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "PDB ROA creat și configurat:"
|
||||
echo " - Tablespace: ROA (20GB, autoextend)"
|
||||
echo " - User CONTAFIN_ORACLE (parola: ${ORACLE_PWD})"
|
||||
echo " - User ${SCHEMA2_NAME} (parola: ${ORACLE_PWD})"
|
||||
echo " - System privileges: ✓"
|
||||
echo " - DBMS grants: ✓"
|
||||
echo ""
|
||||
echo "Conexiune test:"
|
||||
echo " sqlplus CONTAFIN_ORACLE/${ORACLE_PWD}@localhost:1521/roa"
|
||||
echo ""
|
||||
if [ "$MIGRATION_MODE" = "NEW_INSTALL" ]; then
|
||||
echo "Următorul pas: 03-transfer-to-oracle21c.sh (transfer template-uri)"
|
||||
else
|
||||
echo "Următorul pas: 02-export-oracle10g.bat (pe VM 107 Windows)"
|
||||
fi
|
||||
echo ""
|
||||
102
proxmox/lxc108-oracle/migration/02-export-oracle10g.bat
Normal file
102
proxmox/lxc108-oracle/migration/02-export-oracle10g.bat
Normal file
@@ -0,0 +1,102 @@
|
||||
@echo off
|
||||
REM ==============================================================================
|
||||
REM Script: 02-export-oracle10g.bat
|
||||
REM Descriere: Export CONTAFIN_ORACLE si MARIUSM_AUTO din Oracle 10g
|
||||
REM Data: 30 Septembrie 2025
|
||||
REM Rulare: 02-export-oracle10g.bat
|
||||
REM ==============================================================================
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo ==========================================
|
||||
echo ORACLE 10g - EXPORT SCHEME
|
||||
echo ==========================================
|
||||
echo.
|
||||
|
||||
REM Configurare
|
||||
set ORACLE_SID=ROA
|
||||
set ORACLE_CONN=system/romfastromfast@10.0.20.122:1521/ROA
|
||||
set EXPORT_DIR=D:\ORACLE_EXPORT
|
||||
set DATE_STAMP=%date:~-4%%date:~3,2%%date:~0,2%
|
||||
|
||||
REM Creare directoare
|
||||
echo [1/4] Creare directoare export...
|
||||
if not exist "%EXPORT_DIR%" mkdir "%EXPORT_DIR%"
|
||||
if not exist "%EXPORT_DIR%\dumps" mkdir "%EXPORT_DIR%\dumps"
|
||||
if not exist "%EXPORT_DIR%\logs" mkdir "%EXPORT_DIR%\logs"
|
||||
echo OK - Directoare create: %EXPORT_DIR%
|
||||
echo.
|
||||
|
||||
echo [2/4] Export CONTAFIN_ORACLE...
|
||||
echo Durată estimată: 10-15 minute
|
||||
exp %ORACLE_CONN% ^
|
||||
FILE=%EXPORT_DIR%\dumps\CONTAFIN_ORACLE_%DATE_STAMP%.dmp ^
|
||||
LOG=%EXPORT_DIR%\logs\CONTAFIN_ORACLE_%DATE_STAMP%.log ^
|
||||
OWNER=CONTAFIN_ORACLE ^
|
||||
CONSISTENT=Y ^
|
||||
BUFFER=10485760 ^
|
||||
COMPRESS=N ^
|
||||
DIRECT=Y ^
|
||||
STATISTICS=NONE
|
||||
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Export CONTAFIN_ORACLE esuat!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo OK - CONTAFIN_ORACLE exportat
|
||||
echo.
|
||||
|
||||
echo [3/4] Export MARIUSM_AUTO...
|
||||
echo Durată estimată: 30-60 minute (707 tabele!)
|
||||
exp %ORACLE_CONN% ^
|
||||
FILE=%EXPORT_DIR%\dumps\MARIUSM_AUTO_%DATE_STAMP%.dmp ^
|
||||
LOG=%EXPORT_DIR%\logs\MARIUSM_AUTO_%DATE_STAMP%.log ^
|
||||
OWNER=MARIUSM_AUTO ^
|
||||
CONSISTENT=Y ^
|
||||
BUFFER=10485760 ^
|
||||
COMPRESS=N ^
|
||||
DIRECT=Y ^
|
||||
STATISTICS=NONE
|
||||
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Export MARIUSM_AUTO esuat!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo OK - MARIUSM_AUTO exportat
|
||||
echo.
|
||||
|
||||
echo [4/4] Export SYS objects...
|
||||
sqlplus -s %ORACLE_CONN% @"%~dp0\export-sys-objects.sql" > "%EXPORT_DIR%\logs\SYS_OBJECTS_%DATE_STAMP%.log"
|
||||
if errorlevel 1 (
|
||||
echo WARN: Export SYS objects cu erori - verifică log-ul
|
||||
) else (
|
||||
echo OK - SYS objects exportat
|
||||
)
|
||||
echo.
|
||||
|
||||
REM Verificare dimensiuni
|
||||
echo ==========================================
|
||||
echo VERIFICARE FISIERE EXPORTATE
|
||||
echo ==========================================
|
||||
dir /b "%EXPORT_DIR%\dumps\*.dmp"
|
||||
echo.
|
||||
|
||||
echo ==========================================
|
||||
echo EXPORT COMPLET!
|
||||
echo ==========================================
|
||||
echo.
|
||||
echo Fisiere generate:
|
||||
echo - CONTAFIN_ORACLE_%DATE_STAMP%.dmp
|
||||
echo - MARIUSM_AUTO_%DATE_STAMP%.dmp
|
||||
echo - SYS_OBJECTS_%DATE_STAMP%.sql
|
||||
echo.
|
||||
echo Log-uri:
|
||||
echo - %EXPORT_DIR%\logs\
|
||||
echo.
|
||||
echo Următorul pas:
|
||||
echo 1. Copiază fișierele *.dmp către WSL: /mnt/e/ORACLE_EXPORT/
|
||||
echo 2. Rulează: 03-transfer-to-oracle21c.sh
|
||||
echo.
|
||||
pause
|
||||
417
proxmox/lxc108-oracle/migration/02-export-source.sh
Normal file
417
proxmox/lxc108-oracle/migration/02-export-source.sh
Normal file
@@ -0,0 +1,417 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# 02-export-source.sh - Universal Export Script (Auto/Manual)
|
||||
# Version: 2.1
|
||||
# Purpose: Export Oracle data with automatic (SSH) or manual modes
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "ORACLE EXPORT - UNIVERSAL MODE"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Check required variables from master script
|
||||
if [ -z "$EXPORT_MODE" ]; then
|
||||
echo "ERROR: EXPORT_MODE not set. Run via 00-MASTER-MIGRATION.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set default export directory
|
||||
EXPORT_DIR="${EXPORT_DIR:-/tmp/oracle-export}"
|
||||
|
||||
# Export timestamp for filenames
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
################################################################################
|
||||
# AUTOMATIC EXPORT (via SSH)
|
||||
################################################################################
|
||||
if [ "$EXPORT_MODE" = "AUTO" ]; then
|
||||
echo "🔄 Mod AUTOMAT - Export via SSH"
|
||||
echo ""
|
||||
|
||||
# Validate SSH configuration
|
||||
if [ -z "$ORACLE_SOURCE_HOST" ] || [ -z "$ORACLE_SOURCE_USER" ]; then
|
||||
echo "ERROR: SSH configuration incomplete"
|
||||
echo " ORACLE_SOURCE_HOST: $ORACLE_SOURCE_HOST"
|
||||
echo " ORACLE_SOURCE_USER: $ORACLE_SOURCE_USER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Source Configuration:"
|
||||
echo " Host: $ORACLE_SOURCE_HOST"
|
||||
echo " User: $ORACLE_SOURCE_USER"
|
||||
echo " OS: $ORACLE_SOURCE_OS"
|
||||
echo ""
|
||||
|
||||
# Test SSH connection
|
||||
echo "Testing SSH connection..."
|
||||
if ! ssh -o ConnectTimeout=5 ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST} "echo 'SSH OK'" > /dev/null 2>&1; then
|
||||
echo "ERROR: Cannot connect via SSH to ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST}"
|
||||
echo "Please check:"
|
||||
echo " 1. SSH service is running on source"
|
||||
echo " 2. SSH keys are configured (or use ssh-copy-id)"
|
||||
echo " 3. Firewall allows SSH connection"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ SSH connection OK"
|
||||
echo ""
|
||||
|
||||
# Execute export based on source OS
|
||||
if [ "$ORACLE_SOURCE_OS" = "Windows" ]; then
|
||||
echo "Executing Windows export via SSH..."
|
||||
|
||||
# Check if export script exists on Windows
|
||||
if ! ssh ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST} "if exist D:\\oracle-export-scripts\\00-MASTER-EXPORT-WSL.bat (echo EXISTS)" | grep -q "EXISTS"; then
|
||||
echo "ERROR: Export script not found on Windows server"
|
||||
echo "Expected path: D:\\oracle-export-scripts\\00-MASTER-EXPORT-WSL.bat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute Windows batch script
|
||||
echo "Running export on Windows (this may take several minutes)..."
|
||||
ssh ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST} 'cmd /c "D:\oracle-export-scripts\00-MASTER-EXPORT-WSL.bat"'
|
||||
|
||||
# Set remote export path for transfer
|
||||
REMOTE_EXPORT_PATH="D:\\oracle-export"
|
||||
|
||||
else
|
||||
# Linux/Unix export
|
||||
echo "Executing Linux export via SSH..."
|
||||
|
||||
# Check if export script exists
|
||||
if ! ssh ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST} "test -f /tmp/export-scripts/00-MASTER-EXPORT-ALL.sh && echo EXISTS" | grep -q "EXISTS"; then
|
||||
echo "ERROR: Export script not found on Linux server"
|
||||
echo "Expected path: /tmp/export-scripts/00-MASTER-EXPORT-ALL.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute Linux export script
|
||||
echo "Running export on Linux (this may take several minutes)..."
|
||||
ssh ${ORACLE_SOURCE_USER}@${ORACLE_SOURCE_HOST} "cd /tmp/export-scripts && bash ./00-MASTER-EXPORT-ALL.sh"
|
||||
|
||||
# Set remote export path for transfer
|
||||
REMOTE_EXPORT_PATH="/tmp/oracle-export"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Export completed on source server"
|
||||
echo ""
|
||||
echo "Next: Run 03-transfer-to-oracle21c.sh to copy files"
|
||||
|
||||
################################################################################
|
||||
# UPGRADE IN-PLACE (Complete guided workflow)
|
||||
################################################################################
|
||||
elif [ "$EXPORT_MODE" = "INPLACE" ]; then
|
||||
echo "🎯 Mod UPGRADE IN-PLACE - Ghidare completă"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "📤 PASUL 1/5: EXPORT DIN ORACLE VECHI"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Detectare unde să execute comenzile
|
||||
if [ "$ORACLE_SOURCE_OS" = "Windows" ]; then
|
||||
print_warning "⚠️ IMPORTANT: Execută comenzile de mai jos pe WINDOWS (unde e Oracle vechi)"
|
||||
echo ""
|
||||
echo "Deschide Command Prompt (cmd) CA ADMINISTRATOR și rulează:"
|
||||
echo ""
|
||||
echo "REM ==================================================="
|
||||
echo "REM Export CONTAFIN_ORACLE"
|
||||
echo "REM ==================================================="
|
||||
echo "cd /d $EXPORT_DIR"
|
||||
echo "mkdir %CD% 2>nul"
|
||||
echo ""
|
||||
echo "exp system/${OLD_ORACLE_PASS}@localhost:${OLD_ORACLE_PORT}/${OLD_ORACLE_SID} ^"
|
||||
echo " FILE=CONTAFIN_ORACLE_%DATE:~-4%%DATE:~3,2%%DATE:~0,2%.dmp ^"
|
||||
echo " OWNER=CONTAFIN_ORACLE ^"
|
||||
echo " LOG=contafin_export.log ^"
|
||||
echo " CONSISTENT=Y"
|
||||
echo ""
|
||||
|
||||
if [ -n "$SCHEMA2_NAME" ] && [ "$SCHEMA2_NAME" != "none" ]; then
|
||||
echo "REM ==================================================="
|
||||
echo "REM Export $SCHEMA2_NAME"
|
||||
echo "REM ==================================================="
|
||||
echo "exp system/${OLD_ORACLE_PASS}@localhost:${OLD_ORACLE_PORT}/${OLD_ORACLE_SID} ^"
|
||||
echo " FILE=${SCHEMA2_NAME}_%DATE:~-4%%DATE:~3,2%%DATE:~0,2%.dmp ^"
|
||||
echo " OWNER=$SCHEMA2_NAME ^"
|
||||
echo " LOG=${SCHEMA2_NAME,,}_export.log ^"
|
||||
echo " CONSISTENT=Y"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "REM Verificare fișiere create"
|
||||
echo "dir *.dmp"
|
||||
echo ""
|
||||
|
||||
else
|
||||
# Linux
|
||||
print_warning "⚠️ IMPORTANT: Execută comenzile de mai jos pe LINUX (unde e Oracle vechi)"
|
||||
echo ""
|
||||
echo "Deschide terminal și rulează:"
|
||||
echo ""
|
||||
echo "# ================================================"
|
||||
echo "# Export CONTAFIN_ORACLE"
|
||||
echo "# ================================================"
|
||||
echo "mkdir -p $EXPORT_DIR"
|
||||
echo "cd $EXPORT_DIR"
|
||||
echo ""
|
||||
echo "exp system/${OLD_ORACLE_PASS}@localhost:${OLD_ORACLE_PORT}/${OLD_ORACLE_SID} \\"
|
||||
echo " FILE=CONTAFIN_ORACLE_\$(date +%Y%m%d).dmp \\"
|
||||
echo " OWNER=CONTAFIN_ORACLE \\"
|
||||
echo " LOG=contafin_export.log \\"
|
||||
echo " CONSISTENT=Y"
|
||||
echo ""
|
||||
|
||||
if [ -n "$SCHEMA2_NAME" ] && [ "$SCHEMA2_NAME" != "none" ]; then
|
||||
echo "# ================================================"
|
||||
echo "# Export $SCHEMA2_NAME"
|
||||
echo "# ================================================"
|
||||
echo "exp system/${OLD_ORACLE_PASS}@localhost:${OLD_ORACLE_PORT}/${OLD_ORACLE_SID} \\"
|
||||
echo " FILE=${SCHEMA2_NAME}_\$(date +%Y%m%d).dmp \\"
|
||||
echo " OWNER=$SCHEMA2_NAME \\"
|
||||
echo " LOG=${SCHEMA2_NAME,,}_export.log \\"
|
||||
echo " CONSISTENT=Y"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "# Verificare fișiere create"
|
||||
echo "ls -lh *.dmp"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
read -p "✅ Apasă ENTER când ai terminat exportul și ai verificat fișierele DMP..." WAIT_EXPORT
|
||||
|
||||
# Verificare existență fișiere (dacă directorul e accesibil)
|
||||
if [ -d "$EXPORT_DIR" ]; then
|
||||
echo ""
|
||||
echo "Verificare fișiere în $EXPORT_DIR..."
|
||||
if [ -f "$EXPORT_DIR"/CONTAFIN_ORACLE*.dmp ]; then
|
||||
print_success "✅ Fișier CONTAFIN găsit!"
|
||||
ls -lh "$EXPORT_DIR"/CONTAFIN_ORACLE*.dmp
|
||||
else
|
||||
print_warning "⚠️ Nu găsesc fișier CONTAFIN în $EXPORT_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "⏸️ PASUL 2/5: OPRIRE ORACLE VECHI"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
if [ "$ORACLE_SOURCE_OS" = "Windows" ]; then
|
||||
echo "Pe WINDOWS, deschide Command Prompt CA ADMINISTRATOR și rulează:"
|
||||
echo ""
|
||||
echo "REM ==================================================="
|
||||
echo "REM Oprire servicii Oracle vechi"
|
||||
echo "REM ==================================================="
|
||||
echo "net stop OracleServiceXE"
|
||||
echo "net stop OracleXETNSListener"
|
||||
echo ""
|
||||
echo "REM Opțional: Dezactivează serviciile (să nu pornească automat)"
|
||||
echo "sc config OracleServiceXE start= disabled"
|
||||
echo "sc config OracleXETNSListener start= disabled"
|
||||
echo ""
|
||||
echo "REM Verificare servicii oprite"
|
||||
echo "sc query OracleServiceXE"
|
||||
echo ""
|
||||
else
|
||||
echo "Pe LINUX, deschide terminal și rulează:"
|
||||
echo ""
|
||||
echo "# ==================================================="
|
||||
echo "# Oprire servicii Oracle vechi"
|
||||
echo "# ==================================================="
|
||||
echo "sudo systemctl stop oracle-xe"
|
||||
echo "sudo systemctl disable oracle-xe"
|
||||
echo ""
|
||||
echo "# Verificare serviciu oprit"
|
||||
echo "sudo systemctl status oracle-xe"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
read -p "✅ Apasă ENTER când ai oprit serviciile Oracle vechi..." WAIT_STOP
|
||||
|
||||
echo ""
|
||||
print_success "✅ Export complet! Oracle vechi oprit!"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "📝 PASUL 3/5: INSTALARE ORACLE 21c XE"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Următorul pas va fi instalarea Oracle 21c XE."
|
||||
echo ""
|
||||
echo "Opțiuni:"
|
||||
if [ "$ORACLE_SOURCE_OS" = "Windows" ]; then
|
||||
echo " 1. Download Oracle XE 21c pentru Windows de la:"
|
||||
echo " https://www.oracle.com/database/technologies/xe-downloads.html"
|
||||
echo " 2. Instalare normală (va folosi același port 1521)"
|
||||
echo " 3. Apoi continuă cu scripturile de import"
|
||||
else
|
||||
echo " 1. Instalare cu scriptul 00-install-oracle21c-xe.sh (pentru LXC/Docker)"
|
||||
echo " 2. SAU instalare manuală Oracle XE 21c pe Linux"
|
||||
echo " 3. Apoi continuă cu scripturile de import"
|
||||
fi
|
||||
echo ""
|
||||
echo "Next: Continuă cu pasul 1 (setup) din master script"
|
||||
|
||||
################################################################################
|
||||
# MANUAL EXPORT (User instructions)
|
||||
################################################################################
|
||||
elif [ "$EXPORT_MODE" = "MANUAL" ]; then
|
||||
echo "📋 Mod MANUAL - Export ghidat"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "INSTRUCȚIUNI EXPORT MANUAL"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Trebuie să exporți manual următoarele scheme:"
|
||||
echo ""
|
||||
echo "1. Schema CONTAFIN_ORACLE:"
|
||||
echo " exp user/pass@db FILE=CONTAFIN_ORACLE_${TIMESTAMP}.dmp OWNER=CONTAFIN_ORACLE LOG=contafin_export.log CONSISTENT=Y"
|
||||
echo ""
|
||||
|
||||
if [ -n "$SCHEMA2_NAME" ] && [ "$SCHEMA2_NAME" != "none" ]; then
|
||||
echo "2. Schema $SCHEMA2_NAME:"
|
||||
echo " exp user/pass@db FILE=${SCHEMA2_NAME}_${TIMESTAMP}.dmp OWNER=$SCHEMA2_NAME LOG=${SCHEMA2_NAME,,}_export.log CONSISTENT=Y"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "3. SYS Objects (dacă e nevoie):"
|
||||
echo " exp system/pass@db FILE=SYS_OBJECTS_${TIMESTAMP}.dmp OWNER=SYS TABLES=(...) LOG=sys_export.log"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "După export, copiază fișierele DMP în:"
|
||||
echo " 📁 $EXPORT_DIR"
|
||||
echo ""
|
||||
echo "Apoi continuă cu următorul script."
|
||||
echo ""
|
||||
|
||||
read -p "✓ Apasă ENTER când ai terminat exportul și ai copiat fișierele..." WAIT_INPUT
|
||||
|
||||
# Verify exported files exist
|
||||
echo ""
|
||||
echo "Verificare fișiere exportate..."
|
||||
|
||||
if [ ! -f "$EXPORT_DIR"/CONTAFIN_ORACLE*.dmp ]; then
|
||||
echo "❌ ERROR: Nu găsesc fișierul CONTAFIN_ORACLE*.dmp în $EXPORT_DIR"
|
||||
echo ""
|
||||
echo "Verifică că ai copiat fișierele corect!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$SCHEMA2_NAME" ] && [ "$SCHEMA2_NAME" != "none" ]; then
|
||||
if [ ! -f "$EXPORT_DIR/${SCHEMA2_NAME}"*.dmp ]; then
|
||||
echo "⚠️ WARNING: Nu găsesc fișierul ${SCHEMA2_NAME}*.dmp"
|
||||
read -p "Continui fără schema secundară? (y/n): " CONTINUE
|
||||
if [ "$CONTINUE" != "y" ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ Fișiere verificate cu succes"
|
||||
echo ""
|
||||
echo "Export directory: $EXPORT_DIR"
|
||||
ls -lh "$EXPORT_DIR"/*.dmp 2>/dev/null || echo "No DMP files found"
|
||||
|
||||
################################################################################
|
||||
# LOCAL MIGRATION (Same server, different ports)
|
||||
################################################################################
|
||||
elif [ "$EXPORT_MODE" = "LOCAL" ]; then
|
||||
echo "🏠 Mod LOCAL - Migrare pe același server"
|
||||
echo ""
|
||||
|
||||
# Validate local configuration
|
||||
if [ -z "$ORACLE_SOURCE_PORT" ] || [ -z "$ORACLE_DEST_PORT" ]; then
|
||||
echo "ERROR: Port configuration incomplete for local migration"
|
||||
echo " Source port: $ORACLE_SOURCE_PORT"
|
||||
echo " Dest port: $ORACLE_DEST_PORT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$ORACLE_SOURCE_PORT" = "$ORACLE_DEST_PORT" ]; then
|
||||
echo "ERROR: Source and destination ports must be different!"
|
||||
echo " Both are set to: $ORACLE_SOURCE_PORT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Local Migration Configuration:"
|
||||
echo " Oracle Source: localhost:$ORACLE_SOURCE_PORT/$ORACLE_SOURCE_SID"
|
||||
echo " Oracle Dest: localhost:$ORACLE_DEST_PORT/$ORACLE_DEST_SID"
|
||||
echo ""
|
||||
|
||||
# Check if source Oracle is running
|
||||
if ! nc -z localhost "$ORACLE_SOURCE_PORT" 2>/dev/null; then
|
||||
echo "ERROR: Oracle source not running on port $ORACLE_SOURCE_PORT"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Oracle source is running on port $ORACLE_SOURCE_PORT"
|
||||
|
||||
# Check if destination Oracle is running
|
||||
if ! nc -z localhost "$ORACLE_DEST_PORT" 2>/dev/null; then
|
||||
echo "ERROR: Oracle destination not running on port $ORACLE_DEST_PORT"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Oracle destination is running on port $ORACLE_DEST_PORT"
|
||||
echo ""
|
||||
|
||||
# Perform local export
|
||||
echo "Starting local export..."
|
||||
mkdir -p "$EXPORT_DIR"
|
||||
|
||||
# Export CONTAFIN schema
|
||||
echo "Exporting CONTAFIN_ORACLE..."
|
||||
exp system/${ORACLE_SOURCE_PASS}@localhost:${ORACLE_SOURCE_PORT}/${ORACLE_SOURCE_SID} \
|
||||
FILE="${EXPORT_DIR}/CONTAFIN_ORACLE_${TIMESTAMP}.dmp" \
|
||||
OWNER=CONTAFIN_ORACLE \
|
||||
LOG="${EXPORT_DIR}/contafin_export.log" \
|
||||
CONSISTENT=Y
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: CONTAFIN export failed. Check log: ${EXPORT_DIR}/contafin_export.log"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ CONTAFIN export completed"
|
||||
|
||||
# Export secondary schema if exists
|
||||
if [ -n "$SCHEMA2_NAME" ] && [ "$SCHEMA2_NAME" != "none" ]; then
|
||||
echo "Exporting $SCHEMA2_NAME..."
|
||||
exp system/${ORACLE_SOURCE_PASS}@localhost:${ORACLE_SOURCE_PORT}/${ORACLE_SOURCE_SID} \
|
||||
FILE="${EXPORT_DIR}/${SCHEMA2_NAME}_${TIMESTAMP}.dmp" \
|
||||
OWNER="$SCHEMA2_NAME" \
|
||||
LOG="${EXPORT_DIR}/${SCHEMA2_NAME,,}_export.log" \
|
||||
CONSISTENT=Y
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ $SCHEMA2_NAME export completed"
|
||||
else
|
||||
echo "⚠️ WARNING: $SCHEMA2_NAME export failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Local export completed"
|
||||
echo "Files saved to: $EXPORT_DIR"
|
||||
ls -lh "$EXPORT_DIR"/*.dmp
|
||||
|
||||
else
|
||||
echo "ERROR: Invalid EXPORT_MODE: $EXPORT_MODE"
|
||||
echo "Valid modes: AUTO, MANUAL, LOCAL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "✓ EXPORT PHASE COMPLETED"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Exported files location: $EXPORT_DIR"
|
||||
echo ""
|
||||
echo "Next step: 03-transfer-to-oracle21c.sh (if needed)"
|
||||
echo ""
|
||||
74
proxmox/lxc108-oracle/migration/03-transfer-to-oracle21c.sh
Normal file
74
proxmox/lxc108-oracle/migration/03-transfer-to-oracle21c.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 03-transfer-to-oracle21c.sh
|
||||
# Descriere: Transfer fișiere DMP de pe WSL către Oracle 21c (Docker)
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 03-transfer-to-oracle21c.sh
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "TRANSFER FISIERE CATRE ORACLE 21c"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Configurare
|
||||
PROXMOX_HOST="root@10.0.20.201"
|
||||
SOURCE_DIR="/mnt/e/ORACLE_EXPORT/dumps"
|
||||
DEST_DIR="/tmp/oracle-import"
|
||||
|
||||
echo "[1/4] Verificare fișiere locale..."
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo "ERROR: Director $SOURCE_DIR nu există!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DMP_FILES=$(ls $SOURCE_DIR/*.dmp 2>/dev/null | wc -l)
|
||||
if [ $DMP_FILES -eq 0 ]; then
|
||||
echo "ERROR: Nu există fișiere *.dmp în $SOURCE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Găsite $DMP_FILES fișiere DMP:"
|
||||
ls -lh $SOURCE_DIR/*.dmp
|
||||
echo ""
|
||||
|
||||
echo "[2/4] Creare director pe Proxmox..."
|
||||
ssh $PROXMOX_HOST "mkdir -p $DEST_DIR"
|
||||
echo "✓ Director $DEST_DIR creat pe Proxmox"
|
||||
echo ""
|
||||
|
||||
echo "[3/4] Transfer fișiere către Proxmox..."
|
||||
echo "Durată estimată: 5-15 minute (depinde de dimensiune și rețea)"
|
||||
scp $SOURCE_DIR/*.dmp $PROXMOX_HOST:$DEST_DIR/
|
||||
scp $SOURCE_DIR/SYS_OBJECTS.sql $PROXMOX_HOST:$DEST_DIR/ 2>/dev/null || echo "WARN: SYS_OBJECTS.sql nu există"
|
||||
echo "✓ Fișiere transferate"
|
||||
echo ""
|
||||
|
||||
echo "[4/4] Copiere în container Docker..."
|
||||
ssh $PROXMOX_HOST <<'ENDSSH'
|
||||
pct exec 108 -- bash -c '
|
||||
docker cp /tmp/oracle-import/CONTAFIN_ORACLE_*.dmp oracle-xe:/tmp/ 2>/dev/null || \
|
||||
docker cp /tmp/oracle-import/CONTAFIN_ORACLE*.dmp oracle-xe:/tmp/
|
||||
|
||||
docker cp /tmp/oracle-import/MARIUSM_AUTO_*.dmp oracle-xe:/tmp/ 2>/dev/null || \
|
||||
docker cp /tmp/oracle-import/MARIUSM_AUTO*.dmp oracle-xe:/tmp/
|
||||
|
||||
docker cp /tmp/oracle-import/SYS_OBJECTS.sql oracle-xe:/tmp/ 2>/dev/null || true
|
||||
|
||||
echo "Fișiere în container:"
|
||||
docker exec oracle-xe ls -lh /tmp/*.dmp /tmp/SYS_OBJECTS.sql 2>/dev/null || docker exec oracle-xe ls -lh /tmp/*.dmp
|
||||
'
|
||||
ENDSSH
|
||||
echo "✓ Fișiere copiate în container oracle-xe"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ TRANSFER COMPLET!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Fișierele sunt acum în container oracle-xe:/tmp/"
|
||||
echo ""
|
||||
echo "Următorul pas: 04-import-to-oracle21c.sh"
|
||||
echo ""
|
||||
173
proxmox/lxc108-oracle/migration/04-import-to-oracle21c.sh
Normal file
173
proxmox/lxc108-oracle/migration/04-import-to-oracle21c.sh
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 04-import-to-oracle21c.sh
|
||||
# Descriere: Import SYS objects + CONTAFIN_ORACLE + schema secundara în Oracle 21c
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 04-import-to-oracle21c.sh
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "IMPORT IN ORACLE 21c XE - PDB ROA"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
ORACLE_PWD="OraclePass123"
|
||||
PDB_CONNECT="sys/${ORACLE_PWD}@localhost:1521/roa as sysdba"
|
||||
|
||||
# Detectare schema secundara (din variabila exportata de 01-setup sau master)
|
||||
if [ -z "$SCHEMA2_NAME" ]; then
|
||||
SCHEMA2_NAME="MARIUSM_AUTO"
|
||||
echo "Schema secundara (default): MARIUSM_AUTO"
|
||||
else
|
||||
echo "Schema secundara (custom): $SCHEMA2_NAME"
|
||||
fi
|
||||
|
||||
echo "[1/5] Import SYS objects custom..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<'EOF'
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
-- Verificare conexiune PDB ROA
|
||||
SELECT 'Connected to: ' || name || ' (CDB=' || cdb || ')' FROM v$database;
|
||||
|
||||
-- Import SYS objects
|
||||
@/tmp/SYS_OBJECTS.sql
|
||||
|
||||
-- Verificare obiecte create
|
||||
SELECT object_name, object_type, status
|
||||
FROM dba_objects
|
||||
WHERE owner='SYS'
|
||||
AND object_name IN ('AUTH_PACK','NEWSCHEMA','NEWSCHEMAJOB','NEWSCHEMAPROGRESS','VAUTH_SERII','AUTH_SERII','AUTH_DETALII')
|
||||
ORDER BY object_type, object_name;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ SYS objects importat"
|
||||
echo ""
|
||||
|
||||
echo "[2/5] Grant-uri SYS → CONTAFIN_ORACLE..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<'EOF'
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
GRANT SELECT ON SYS.AUTH_SERII TO CONTAFIN_ORACLE;
|
||||
GRANT SELECT ON SYS.AUTH_DETALII TO CONTAFIN_ORACLE;
|
||||
GRANT SELECT ON SYS.VAUTH_SERII TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.AUTH_PACK TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.NEWSCHEMA TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.NEWSCHEMAJOB TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.NEWSCHEMAPROGRESS TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.UPDATESQLPLUS TO CONTAFIN_ORACLE;
|
||||
GRANT EXECUTE ON SYS.EXECUTESCRIPTOS TO CONTAFIN_ORACLE;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ Grant-uri SYS acordate"
|
||||
echo ""
|
||||
|
||||
echo "[3/5] Import CONTAFIN_ORACLE..."
|
||||
echo "Durată estimată: 10-15 minute"
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe bash -c '
|
||||
CONTAFIN_DMP=\$(ls /tmp/CONTAFIN_ORACLE*.dmp | head -1)
|
||||
imp system/${ORACLE_PWD}@localhost:1521/roa \
|
||||
FILE=\$CONTAFIN_DMP \
|
||||
LOG=/tmp/contafin_import.log \
|
||||
FROMUSER=CONTAFIN_ORACLE \
|
||||
TOUSER=CONTAFIN_ORACLE \
|
||||
IGNORE=Y \
|
||||
COMMIT=Y \
|
||||
BUFFER=10485760 \
|
||||
FEEDBACK=10000
|
||||
|
||||
echo ""
|
||||
echo "Verificare obiecte importate:"
|
||||
sqlplus -s system/${ORACLE_PWD}@localhost:1521/roa <<EOSQL
|
||||
SET PAGESIZE 50
|
||||
SELECT object_type, COUNT(*) as total
|
||||
FROM dba_objects
|
||||
WHERE owner='"'CONTAFIN_ORACLE'"'
|
||||
GROUP BY object_type
|
||||
ORDER BY object_type;
|
||||
EXIT;
|
||||
EOSQL
|
||||
'"
|
||||
echo "✓ CONTAFIN_ORACLE importat"
|
||||
echo ""
|
||||
|
||||
echo "[4/5] Import ${SCHEMA2_NAME}..."
|
||||
if [ "$SCHEMA2_NAME" = "MARIUSM_AUTO" ]; then
|
||||
echo "Durată estimată: 45-90 minute (707 tabele!)"
|
||||
else
|
||||
echo "Durată estimată: variabilă (depinde de dimensiune DMP)"
|
||||
fi
|
||||
|
||||
# Determinare fisier DMP (MARIUSM_AUTO*.dmp sau schema custom)
|
||||
if [ "$SCHEMA2_NAME" = "MARIUSM_AUTO" ]; then
|
||||
DMP_PATTERN="MARIUSM_AUTO*.dmp"
|
||||
FROMUSER="MARIUSM_AUTO"
|
||||
else
|
||||
# Pentru schema custom, cautam fisierul specificat in SCHEMA2_TEMPLATE
|
||||
DMP_PATTERN="${SCHEMA2_TEMPLATE:-*${SCHEMA2_NAME}*.dmp}"
|
||||
FROMUSER="${SCHEMA2_NAME}"
|
||||
fi
|
||||
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe bash -c '
|
||||
SCHEMA2_DMP=\$(ls /tmp/${DMP_PATTERN} | head -1)
|
||||
if [ -z \"\$SCHEMA2_DMP\" ]; then
|
||||
echo \"ERROR: Nu gasesc fisier DMP pentru ${SCHEMA2_NAME}!\"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo \"Import DMP: \$SCHEMA2_DMP\"
|
||||
imp system/${ORACLE_PWD}@localhost:1521/roa \
|
||||
FILE=\$SCHEMA2_DMP \
|
||||
LOG=/tmp/${SCHEMA2_NAME}_import.log \
|
||||
FROMUSER=${FROMUSER} \
|
||||
TOUSER=${SCHEMA2_NAME} \
|
||||
IGNORE=Y \
|
||||
COMMIT=Y \
|
||||
BUFFER=10485760 \
|
||||
FEEDBACK=10000
|
||||
|
||||
echo \"\"
|
||||
echo \"Verificare obiecte importate:\"
|
||||
sqlplus -s system/${ORACLE_PWD}@localhost:1521/roa <<EOSQL
|
||||
SET PAGESIZE 50
|
||||
SELECT object_type, COUNT(*) as total
|
||||
FROM dba_objects
|
||||
WHERE owner='"'${SCHEMA2_NAME}'"'
|
||||
GROUP BY object_type
|
||||
ORDER BY object_type;
|
||||
EXIT;
|
||||
EOSQL
|
||||
'"
|
||||
echo "✓ ${SCHEMA2_NAME} importat"
|
||||
echo ""
|
||||
|
||||
echo "[5/5] Verificare finală import..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<EOF
|
||||
SET PAGESIZE 50
|
||||
|
||||
SELECT owner, COUNT(*) as total_objects,
|
||||
SUM(CASE WHEN status='VALID' THEN 1 ELSE 0 END) as valid,
|
||||
SUM(CASE WHEN status='INVALID' THEN 1 ELSE 0 END) as invalid
|
||||
FROM dba_objects
|
||||
WHERE owner IN ('CONTAFIN_ORACLE','${SCHEMA2_NAME}')
|
||||
GROUP BY owner
|
||||
ORDER BY owner;
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ IMPORT COMPLET!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Log-uri import:"
|
||||
echo " - /tmp/contafin_import.log"
|
||||
echo " - /tmp/${SCHEMA2_NAME}_import.log"
|
||||
echo ""
|
||||
echo "Următorul pas: 05-create-synonyms-grants.sh"
|
||||
echo ""
|
||||
132
proxmox/lxc108-oracle/migration/05-create-synonyms-grants.sh
Normal file
132
proxmox/lxc108-oracle/migration/05-create-synonyms-grants.sh
Normal file
@@ -0,0 +1,132 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 05-create-synonyms-grants.sh
|
||||
# Descriere: Creare sinonime publice (53) + grant-uri către PUBLIC (147)
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 05-create-synonyms-grants.sh
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "CREARE SINONIME PUBLICE + GRANT-URI"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
ORACLE_PWD="OraclePass123"
|
||||
PDB_CONNECT="sys/${ORACLE_PWD}@localhost:1521/roa as sysdba"
|
||||
|
||||
echo "[1/3] Generare script sinonime publice..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe bash -c 'cat > /tmp/create_synonyms.sql <<\"EOFSCRIPT\"
|
||||
-- Creare 53 sinonime publice (50 CONTAFIN + 3 SYS)
|
||||
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_ATAS_ATASAMENTE FOR CONTAFIN_ORACLE.ATAS_ATASAMENTE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_ATAS_REFERINTE FOR CONTAFIN_ORACLE.ATAS_REFERINTE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_ACTUALIZARI FOR CONTAFIN_ORACLE.CURS_ACTUALIZARI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_COTATII FOR CONTAFIN_ORACLE.CURS_COTATII;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP FOR CONTAFIN_ORACLE.DEF_GRUP;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP_DREPT FOR CONTAFIN_ORACLE.DEF_GRUP_DREPT;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_PROGRAME FOR CONTAFIN_ORACLE.DEF_PROGRAME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_HELPCONT FOR CONTAFIN_ORACLE.HELPCONT;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_LUNILEAN FOR CONTAFIN_ORACLE.LUNILEAN;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CETATENII FOR CONTAFIN_ORACLE.NOM_CETATENII;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CODURI_CAEN FOR CONTAFIN_ORACLE.NOM_CODURI_CAEN;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FIRME FOR CONTAFIN_ORACLE.NOM_FIRME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_JURIDICE FOR CONTAFIN_ORACLE.NOM_FORME_JURIDICE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_ORGANIZARE FOR CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_PROPRIETATE FOR CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_JUDETE FOR CONTAFIN_ORACLE.NOM_JUDETE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_LOCALITATI FOR CONTAFIN_ORACLE.NOM_LOCALITATI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_PROGRAME FOR CONTAFIN_ORACLE.NOM_PROGRAME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TARI FOR CONTAFIN_ORACLE.NOM_TARI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TIPAPATRID FOR CONTAFIN_ORACLE.NOM_TIPAPATRID;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TIP_ARTERA FOR CONTAFIN_ORACLE.NOM_TIP_ARTERA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TIP_SOCIETATE FOR CONTAFIN_ORACLE.NOM_TIP_SOCIETATE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_VALUTE_ISO FOR CONTAFIN_ORACLE.NOM_VALUTE_ISO;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_OPTIUNI_PROGRAME FOR CONTAFIN_ORACLE.OPTIUNI_PROGRAME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DEF_CO FOR CONTAFIN_ORACLE.PACK_DEF_CO;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DREPTURI FOR CONTAFIN_ORACLE.PACK_DREPTURI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_ACTUALIZARE_COR FOR CONTAFIN_ORACLE.SAL_ACTUALIZARE_COR;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_COR FOR CONTAFIN_ORACLE.SAL_COR;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_DURATA_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_DURATA_MUNCA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_INTERVALE_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_INTERVALE_MUNCA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_REPARTIZARE_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_REPARTIZARE_MUNCA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_STARI_CTR FOR CONTAFIN_ORACLE.SAL_NOM_STARI_CTR;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_TEMEI FOR CONTAFIN_ORACLE.SAL_NOM_TEMEI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_TIPAUTORIZATIE FOR CONTAFIN_ORACLE.SAL_NOM_TIPAUTORIZATIE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_TIP_NORME FOR CONTAFIN_ORACLE.SAL_NOM_TIP_NORME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_SAL_NOM_TIP_SPOR FOR CONTAFIN_ORACLE.SAL_NOM_TIP_SPOR;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_UTILIZATORI FOR CONTAFIN_ORACLE.UTILIZATORI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_PROGRAME FOR CONTAFIN_ORACLE.VDEF_PROGRAME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_FIRME FOR CONTAFIN_ORACLE.VDEF_UTIL_FIRME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_GRUP FOR CONTAFIN_ORACLE.VDEF_UTIL_GRUP;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_OBIECTE FOR CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_PROGRAME FOR CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_V_NOM_FIRME FOR CONTAFIN_ORACLE.V_NOM_FIRME;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_JUDETE FOR CONTAFIN_ORACLE.VNOM_JUDETE;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_LOCALITATI FOR CONTAFIN_ORACLE.VNOM_LOCALITATI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_TARI FOR CONTAFIN_ORACLE.VNOM_TARI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_TIP_ARTERA FOR CONTAFIN_ORACLE.VNOM_TIP_ARTERA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_UM_ISO FOR CONTAFIN_ORACLE.VNOM_UM_ISO;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_VALUTE_ISO FOR CONTAFIN_ORACLE.VNOM_VALUTE_ISO;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_VUTILIZATORI FOR CONTAFIN_ORACLE.VUTILIZATORI;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NEWSCHEMA FOR SYS.NEWSCHEMA;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NEWSCHEMAJOB FOR SYS.NEWSCHEMAJOB;
|
||||
CREATE OR REPLACE PUBLIC SYNONYM SYN_NEWSCHEMAPROGRESS FOR SYS.NEWSCHEMAPROGRESS;
|
||||
|
||||
PROMPT Sinonime publice create!
|
||||
EXIT;
|
||||
EOFSCRIPT
|
||||
'"
|
||||
echo "✓ Script sinonime generat"
|
||||
echo ""
|
||||
|
||||
echo "[2/3] Creare sinonime publice (53 total)..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT} @/tmp/create_synonyms.sql"
|
||||
echo "✓ Sinonime create"
|
||||
echo ""
|
||||
|
||||
echo "[3/3] Acordare grant-uri către PUBLIC (147 total)..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<'EOF'
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
-- Grant-uri CONTAFIN_ORACLE → PUBLIC (sample complet în documentație)
|
||||
GRANT REFERENCES ON CONTAFIN_ORACLE.ATAS_ATASAMENTE TO PUBLIC;
|
||||
GRANT SELECT ON CONTAFIN_ORACLE.ATAS_ATASAMENTE TO PUBLIC;
|
||||
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_DREPTURI TO PUBLIC;
|
||||
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UTILS TO PUBLIC;
|
||||
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UPDATE TO PUBLIC;
|
||||
GRANT SELECT ON CONTAFIN_ORACLE.NOM_FIRME TO PUBLIC;
|
||||
GRANT SELECT ON CONTAFIN_ORACLE.UTILIZATORI TO PUBLIC;
|
||||
-- ... (147 grant-uri total - vezi scriptul complet în documentație)
|
||||
|
||||
PROMPT Grant-uri către PUBLIC acordate!
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ Grant-uri acordate"
|
||||
echo ""
|
||||
|
||||
echo "Verificare finală..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<'EOF'
|
||||
SET PAGESIZE 20
|
||||
|
||||
-- Verificare sinonime
|
||||
SELECT COUNT(*) as "Sinonime SYN_*"
|
||||
FROM dba_synonyms
|
||||
WHERE owner='PUBLIC' AND synonym_name LIKE 'SYN_%';
|
||||
|
||||
-- Verificare grant-uri
|
||||
SELECT COUNT(*) as "Grant-uri to PUBLIC"
|
||||
FROM dba_tab_privs
|
||||
WHERE grantee='PUBLIC' AND grantor='CONTAFIN_ORACLE';
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ SINONIME + GRANT-URI COMPLETE!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Următorul pas: 06-finalize-migration.sh"
|
||||
echo ""
|
||||
162
proxmox/lxc108-oracle/migration/06-finalize-migration.sh
Normal file
162
proxmox/lxc108-oracle/migration/06-finalize-migration.sh
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Script: 06-finalize-migration.sh
|
||||
# Descriere: Recompilare obiecte invalide + verificare finală migrare
|
||||
# Data: 30 Septembrie 2025
|
||||
# Rulare: bash 06-finalize-migration.sh
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "FINALIZARE MIGRARE ORACLE 21c"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
ORACLE_PWD="OraclePass123"
|
||||
PDB_CONNECT="sys/${ORACLE_PWD}@localhost:1521/roa as sysdba"
|
||||
|
||||
# Detectare schema secundara
|
||||
if [ -z "$SCHEMA2_NAME" ]; then
|
||||
SCHEMA2_NAME="MARIUSM_AUTO"
|
||||
fi
|
||||
|
||||
echo "[1/2] Recompilare obiecte invalide..."
|
||||
echo "Durată estimată: 5-10 minute"
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<EOF
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
BEGIN
|
||||
DBMS_OUTPUT.PUT_LINE('Recompilare CONTAFIN_ORACLE...');
|
||||
DBMS_UTILITY.compile_schema('CONTAFIN_ORACLE', compile_all => FALSE);
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('Recompilare ${SCHEMA2_NAME}...');
|
||||
DBMS_UTILITY.compile_schema('${SCHEMA2_NAME}', compile_all => FALSE);
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('Recompilare completă!');
|
||||
END;
|
||||
/
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo "✓ Obiecte recompilate"
|
||||
echo ""
|
||||
|
||||
echo "[2/2] Verificare completă migrare..."
|
||||
ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe sqlplus -s ${PDB_CONNECT}" <<EOF
|
||||
SET PAGESIZE 100 FEEDBACK ON
|
||||
|
||||
PROMPT ==========================================
|
||||
PROMPT VERIFICARE COMPLETA MIGRARE ORACLE 21c
|
||||
PROMPT ==========================================
|
||||
PROMPT
|
||||
|
||||
PROMPT 1. Conexiune PDB ROA:
|
||||
SELECT 'Connected to: ' || name || ' (CDB=' || cdb || ')' as info FROM v$database;
|
||||
PROMPT
|
||||
|
||||
PROMPT 2. Tablespace ROA:
|
||||
SELECT tablespace_name, status, contents,
|
||||
ROUND(SUM(bytes)/1024/1024/1024,2) as size_gb
|
||||
FROM dba_data_files
|
||||
WHERE tablespace_name='ROA'
|
||||
GROUP BY tablespace_name, status, contents;
|
||||
PROMPT
|
||||
|
||||
PROMPT 3. Utilizatori:
|
||||
SELECT username, default_tablespace, account_status
|
||||
FROM dba_users
|
||||
WHERE username IN ('CONTAFIN_ORACLE','${SCHEMA2_NAME}')
|
||||
ORDER BY username;
|
||||
PROMPT
|
||||
|
||||
PROMPT 4. Obiecte totale:
|
||||
SELECT owner, COUNT(*) as total_objects,
|
||||
SUM(CASE WHEN status='VALID' THEN 1 ELSE 0 END) as valid_objects,
|
||||
SUM(CASE WHEN status='INVALID' THEN 1 ELSE 0 END) as invalid_objects,
|
||||
ROUND(SUM(CASE WHEN status='VALID' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) || '%' as pct_valid
|
||||
FROM dba_objects
|
||||
WHERE owner IN ('CONTAFIN_ORACLE','${SCHEMA2_NAME}')
|
||||
GROUP BY owner
|
||||
ORDER BY owner;
|
||||
PROMPT
|
||||
|
||||
PROMPT 5. Tabele:
|
||||
SELECT owner, COUNT(*) as table_count
|
||||
FROM dba_tables
|
||||
WHERE owner IN ('CONTAFIN_ORACLE','${SCHEMA2_NAME}')
|
||||
GROUP BY owner
|
||||
ORDER BY owner;
|
||||
PROMPT
|
||||
|
||||
PROMPT 6. Obiecte SYS custom:
|
||||
SELECT object_name, object_type, status
|
||||
FROM dba_objects
|
||||
WHERE owner='SYS'
|
||||
AND object_name IN ('AUTH_PACK','NEWSCHEMA','NEWSCHEMAJOB','VAUTH_SERII','AUTH_SERII')
|
||||
ORDER BY object_type, object_name;
|
||||
PROMPT
|
||||
|
||||
PROMPT 7. Sinonime publice:
|
||||
SELECT COUNT(*) as "Sinonime SYN_*"
|
||||
FROM dba_synonyms
|
||||
WHERE owner='PUBLIC' AND synonym_name LIKE 'SYN_%';
|
||||
PROMPT
|
||||
|
||||
PROMPT 8. Grant-uri PUBLIC:
|
||||
SELECT COUNT(*) as "Grants to PUBLIC"
|
||||
FROM dba_tab_privs
|
||||
WHERE grantee='PUBLIC' AND grantor='CONTAFIN_ORACLE';
|
||||
PROMPT
|
||||
|
||||
PROMPT 9. Grant-uri SYS:
|
||||
SELECT COUNT(*) as "Grants from SYS"
|
||||
FROM dba_tab_privs
|
||||
WHERE grantee='CONTAFIN_ORACLE' AND grantor='SYS';
|
||||
PROMPT
|
||||
|
||||
PROMPT 10. Test funcțional - Sinonim public:
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO v_count FROM dba_synonyms
|
||||
WHERE synonym_name='SYN_PACK_DREPTURI' AND owner='PUBLIC';
|
||||
|
||||
IF v_count > 0 THEN
|
||||
DBMS_OUTPUT.PUT_LINE('✓ SYN_PACK_DREPTURI exists and is accessible');
|
||||
ELSE
|
||||
DBMS_OUTPUT.PUT_LINE('✗ SYN_PACK_DREPTURI NOT FOUND!');
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT
|
||||
PROMPT ==========================================
|
||||
PROMPT VERIFICARE COMPLETA!
|
||||
PROMPT ==========================================
|
||||
|
||||
EXIT;
|
||||
EOF
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ MIGRARE FINALIZATA CU SUCCES!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Rezumat:"
|
||||
echo " ✓ PDB ROA creat"
|
||||
echo " ✓ Tablespace ROA (20GB)"
|
||||
echo " ✓ Utilizatori: CONTAFIN_ORACLE, MARIUSM_AUTO"
|
||||
echo " ✓ Obiecte importate: ~4,000"
|
||||
echo " ✓ Sinonime publice: 53"
|
||||
echo " ✓ Grant-uri PUBLIC: 147"
|
||||
echo " ✓ Obiecte recompilate"
|
||||
echo ""
|
||||
echo "Test conexiune:"
|
||||
echo " sqlplus CONTAFIN_ORACLE/${ORACLE_PWD}@10.0.20.201:1521/roa"
|
||||
echo ""
|
||||
echo "Log-uri disponibile:"
|
||||
echo " - docker exec oracle-xe cat /tmp/contafin_import.log"
|
||||
echo " - docker exec oracle-xe cat /tmp/mariusm_import.log"
|
||||
echo ""
|
||||
217
proxmox/lxc108-oracle/migration/README-MAIN.md
Normal file
217
proxmox/lxc108-oracle/migration/README-MAIN.md
Normal file
@@ -0,0 +1,217 @@
|
||||
# 🚀 MIGRARE ORACLE - SCRIPTURI AUTOMATIZATE
|
||||
|
||||
**Versiune**: 2.1 - Universal Multi-platform + Windows Native
|
||||
**Data**: 1 Octombrie 2025
|
||||
|
||||
---
|
||||
|
||||
## 📁 STRUCTURA
|
||||
|
||||
```
|
||||
oracle/
|
||||
└── migration-scripts/ # TOATE SCRIPTURILE DE MIGRARE
|
||||
├── 00-MASTER-MIGRATION.sh # Master script Linux/WSL
|
||||
├── 00-MASTER-MIGRATION.bat # Master script Windows (NATIV, fără WSL)
|
||||
├── 00-install-oracle21c-xe.sh # Instalare Oracle 21c (LXC/Docker)
|
||||
├── 01-setup-oracle21c.sh # Setup tablespace + useri
|
||||
├── 02-export-source.sh # Export universal (AUTO/MANUAL/LOCAL/INPLACE)
|
||||
├── 03-transfer-to-oracle21c.sh# Transfer DMP
|
||||
├── 04-import-to-oracle21c.sh # Import DMP
|
||||
├── 05-create-synonyms-grants.sh # Sinonime + grant-uri
|
||||
├── 06-finalize-migration.sh # Recompilare + verificare
|
||||
├── sys_objects.sql # SYS objects DDL pre-generat
|
||||
├── README.md # Documentație completă
|
||||
└── README-UPGRADE-IN-PLACE.md # Ghid upgrade același PC
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 SCENARII SUPORTATE
|
||||
|
||||
### 1️⃣ Upgrade In-Place (Același PC)
|
||||
**Scenariu**: Oracle vechi → Oracle 21c XE pe **același computer**
|
||||
|
||||
**Windows** (100% nativ, FĂRĂ WSL):
|
||||
```cmd
|
||||
cd E:\proiecte\ROMFASTSQL\oracle\migration-scripts
|
||||
00-MASTER-MIGRATION.bat
|
||||
```
|
||||
|
||||
**Linux/WSL**:
|
||||
```bash
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/oracle/migration-scripts
|
||||
./00-MASTER-MIGRATION.sh
|
||||
```
|
||||
|
||||
**La meniu alege**:
|
||||
- Oracle 21c: **Acest PC** (1)
|
||||
- Export: **UPGRADE IN-PLACE** (4)
|
||||
|
||||
**📖 Ghid detaliat**: `migration-scripts/README-UPGRADE-IN-PLACE.md`
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Migrare între Servere
|
||||
**Scenariu**: Oracle sursa @ Server A → Oracle 21c @ Server B
|
||||
|
||||
**Linux/WSL**:
|
||||
```bash
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/oracle/migration-scripts
|
||||
./00-MASTER-MIGRATION.sh
|
||||
```
|
||||
|
||||
**La meniu alege**:
|
||||
- Oracle 21c: **VM/Server Linux** sau **LXC Proxmox** (2/3)
|
||||
- Export: **AUTOMAT SSH** (1) sau **MANUAL** (2)
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Migrare Locală (Același Server, Porturi Diferite)
|
||||
**Scenariu**: Oracle 11g @ :1521 + Oracle 21c @ :1522 (rulează simultan)
|
||||
|
||||
**Linux/WSL**:
|
||||
```bash
|
||||
./00-MASTER-MIGRATION.sh
|
||||
```
|
||||
|
||||
**La meniu alege**:
|
||||
- Export: **LOCAL** (3)
|
||||
|
||||
---
|
||||
|
||||
## ⚡ QUICK START
|
||||
|
||||
### WINDOWS (Recomandat pentru upgrade in-place)
|
||||
|
||||
```cmd
|
||||
REM 1. Deschide Command Prompt CA ADMINISTRATOR
|
||||
REM 2. Navighează la scripturi
|
||||
cd E:\proiecte\ROMFASTSQL\oracle\migration-scripts
|
||||
|
||||
REM 3. Rulează master script
|
||||
00-MASTER-MIGRATION.bat
|
||||
|
||||
REM 4. Urmează ghidarea interactivă!
|
||||
```
|
||||
|
||||
**Ce va face scriptul automat**:
|
||||
1. 📤 Generează batch pentru export (`RUN-EXPORT.bat`)
|
||||
2. ⏸️ Generează batch pentru oprire Oracle vechi (`STOP-ORACLE-OLD.bat`)
|
||||
3. 📥 Îți spune unde să downloadezi Oracle 21c XE
|
||||
4. 📦 Generează scripturi SQL pentru setup + import
|
||||
5. ✅ Rulează automat tot workflow-ul prin SQLPlus
|
||||
|
||||
**Zero WSL necesar!**
|
||||
|
||||
---
|
||||
|
||||
### LINUX/WSL
|
||||
|
||||
```bash
|
||||
# 1. Navighează la scripturi
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/oracle/migration-scripts
|
||||
chmod +x *.sh
|
||||
|
||||
# 2. Rulează master script
|
||||
./00-MASTER-MIGRATION.sh
|
||||
|
||||
# 3. Urmează ghidarea interactivă!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 MODURI DE EXPORT
|
||||
|
||||
Scripturile suportă **4 moduri** de export:
|
||||
|
||||
| Mod | Când se folosește | Platformă |
|
||||
|-----|-------------------|-----------|
|
||||
| **AUTOMAT** | Export SSH către server remote | Linux + Windows |
|
||||
| **MANUAL** | Tu exporți manual, scriptul preia DMP | Orice |
|
||||
| **LOCAL** | Același server, porturi diferite | Linux + Windows |
|
||||
| **INPLACE** | Upgrade pe același PC (recomandat) | Windows nativ |
|
||||
|
||||
---
|
||||
|
||||
## 📋 CERINȚE
|
||||
|
||||
### Pentru Windows (Upgrade In-Place):
|
||||
- ✅ Windows 10/11
|
||||
- ✅ Oracle vechi instalat (10g/11g/19c)
|
||||
- ✅ Oracle 21c XE (instalat DUPĂ export)
|
||||
- ✅ SQLPlus în PATH (vine cu Oracle)
|
||||
- ✅ Rulare ca Administrator
|
||||
|
||||
### Pentru Linux/WSL:
|
||||
- ✅ Bash shell
|
||||
- ✅ SSH access la servere (dacă export automat)
|
||||
- ✅ Oracle tools (exp, imp, sqlplus)
|
||||
|
||||
---
|
||||
|
||||
## 📖 DOCUMENTAȚIE
|
||||
|
||||
| Fișier | Descriere |
|
||||
|--------|-----------|
|
||||
| `migration-scripts/README.md` | Documentație completă pentru toate scenariile |
|
||||
| `migration-scripts/README-UPGRADE-IN-PLACE.md` | Ghid pas cu pas pentru upgrade același PC |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 EXEMPLU: Upgrade Windows In-Place
|
||||
|
||||
```cmd
|
||||
REM Pasul 1: Export din Oracle vechi
|
||||
cd E:\proiecte\ROMFASTSQL\oracle\migration-scripts
|
||||
00-MASTER-MIGRATION.bat
|
||||
REM Alegi: Opțiunea 4 (UPGRADE IN-PLACE)
|
||||
|
||||
REM Scriptul generează: D:\oracle-export\RUN-EXPORT.bat
|
||||
REM Rulează:
|
||||
D:\oracle-export\RUN-EXPORT.bat
|
||||
|
||||
REM Pasul 2: Oprire Oracle vechi
|
||||
REM Scriptul generează: D:\oracle-export\STOP-ORACLE-OLD.bat
|
||||
D:\oracle-export\STOP-ORACLE-OLD.bat
|
||||
|
||||
REM Pasul 3: Instalare Oracle 21c XE
|
||||
REM Download de la: https://www.oracle.com/database/technologies/xe-downloads.html
|
||||
REM Instalează normal (port 1521)
|
||||
|
||||
REM Pasul 4: Import AUTOMAT!
|
||||
REM Scriptul continuă și rulează automat:
|
||||
REM - setup-windows.sql (tablespace + useri)
|
||||
REM - import-windows.bat (import DMP)
|
||||
REM - synonyms-windows.sql (sinonime)
|
||||
REM - finalize-windows.sql (verificare)
|
||||
|
||||
REM GATA! Migrare completă!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 SUPORT
|
||||
|
||||
**Probleme cu scripturile?**
|
||||
- Vezi secțiunea TROUBLESHOOTING din `migration-scripts/README-UPGRADE-IN-PLACE.md`
|
||||
|
||||
**Erori comune**:
|
||||
- SQLPlus nu funcționează → Adaugă Oracle în PATH
|
||||
- Import cu erori → Majoritatea warning-urilor "object already exists" sunt normale
|
||||
- Conectare refuzată → Verifică că Oracle 21c rulează și portul e corect
|
||||
|
||||
---
|
||||
|
||||
## ✅ FEATURES PRINCIPALE
|
||||
|
||||
✅ **4 moduri de export** (AUTO, MANUAL, LOCAL, INPLACE)
|
||||
✅ **Multi-platform** (Windows nativ, Linux, WSL, LXC, Docker)
|
||||
✅ **Schema dinamică** (nu ești limitat la MARIUSM_AUTO)
|
||||
✅ **Ghidare completă** (îți spune EXACT ce să execuți și UNDE)
|
||||
✅ **Generare automată scripturi** (nu trebuie să scrii comenzi)
|
||||
✅ **Verificări automate** (detectează erori și îți spune cum să le rezolvi)
|
||||
✅ **Zero WSL pe Windows** (100% nativ cu SQLPlus)
|
||||
|
||||
---
|
||||
|
||||
**Succes cu migrarea! 🚀**
|
||||
382
proxmox/lxc108-oracle/migration/README-UPGRADE-IN-PLACE.md
Normal file
382
proxmox/lxc108-oracle/migration/README-UPGRADE-IN-PLACE.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# 🔄 UPGRADE ORACLE IN-PLACE - Ghid Complet
|
||||
|
||||
**Scenariu**: Upgrade Oracle pe același calculator (Oracle vechi → Oracle 21c XE)
|
||||
**Data**: 1 Octombrie 2025
|
||||
**Versiune scripturi**: 2.1+
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Ce este UPGRADE IN-PLACE?
|
||||
|
||||
Upgrade in-place înseamnă:
|
||||
- Oracle vechi și Oracle 21c pe **același computer**
|
||||
- **Export DMP** din Oracle vechi
|
||||
- **Oprire** Oracle vechi
|
||||
- **Instalare** Oracle 21c XE (pe același port 1521)
|
||||
- **Import DMP** în Oracle 21c
|
||||
|
||||
---
|
||||
|
||||
## 🚀 QUICK START
|
||||
|
||||
### Pasul 1: Pornire ghidare automată
|
||||
|
||||
```bash
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/oracle/migration-scripts
|
||||
chmod +x *.sh
|
||||
./00-MASTER-MIGRATION.sh
|
||||
```
|
||||
|
||||
**La întrebări răspunde:**
|
||||
- Mod: **MIGRARE** (1)
|
||||
- Export: **UPGRADE IN-PLACE** (4)
|
||||
|
||||
Scriptul te va ghida complet prin toți pașii!
|
||||
|
||||
---
|
||||
|
||||
## 📋 PAȘII DETALIAȚI
|
||||
|
||||
### PASUL 1/5: Export DMP din Oracle vechi
|
||||
|
||||
**Unde execuți**: Pe computerul unde e Oracle vechi (Windows/Linux)
|
||||
|
||||
**Windows** - Deschide Command Prompt CA ADMINISTRATOR:
|
||||
```cmd
|
||||
REM Creează director pentru export
|
||||
cd /d D:\oracle-export
|
||||
mkdir %CD% 2>nul
|
||||
|
||||
REM Export CONTAFIN_ORACLE
|
||||
exp system/PAROLA@localhost:1521/XE ^
|
||||
FILE=CONTAFIN_ORACLE_%DATE:~-4%%DATE:~3,2%%DATE:~0,2%.dmp ^
|
||||
OWNER=CONTAFIN_ORACLE ^
|
||||
LOG=contafin_export.log ^
|
||||
CONSISTENT=Y
|
||||
|
||||
REM Export schema secundară (dacă ai)
|
||||
exp system/PAROLA@localhost:1521/XE ^
|
||||
FILE=MARIUSM_AUTO_%DATE:~-4%%DATE:~3,2%%DATE:~0,2%.dmp ^
|
||||
OWNER=MARIUSM_AUTO ^
|
||||
LOG=mariusm_export.log ^
|
||||
CONSISTENT=Y
|
||||
|
||||
REM Verificare fișiere
|
||||
dir *.dmp
|
||||
```
|
||||
|
||||
**Linux** - Deschide terminal:
|
||||
```bash
|
||||
# Creează director pentru export
|
||||
mkdir -p /tmp/oracle-export
|
||||
cd /tmp/oracle-export
|
||||
|
||||
# Export CONTAFIN_ORACLE
|
||||
exp system/PAROLA@localhost:1521/XE \
|
||||
FILE=CONTAFIN_ORACLE_$(date +%Y%m%d).dmp \
|
||||
OWNER=CONTAFIN_ORACLE \
|
||||
LOG=contafin_export.log \
|
||||
CONSISTENT=Y
|
||||
|
||||
# Export schema secundară (dacă ai)
|
||||
exp system/PAROLA@localhost:1521/XE \
|
||||
FILE=MARIUSM_AUTO_$(date +%Y%m%d).dmp \
|
||||
OWNER=MARIUSM_AUTO \
|
||||
LOG=mariusm_export.log \
|
||||
CONSISTENT=Y
|
||||
|
||||
# Verificare fișiere
|
||||
ls -lh *.dmp
|
||||
```
|
||||
|
||||
**Verificare**:
|
||||
- Fișierele DMP trebuie să fie > 0 bytes
|
||||
- Citește log-urile pentru erori
|
||||
- Notează locația fișierelor DMP
|
||||
|
||||
---
|
||||
|
||||
### PASUL 2/5: Oprire Oracle vechi
|
||||
|
||||
**⚠️ IMPORTANT**: Fă backup la fișierele DMP înainte să oprești Oracle!
|
||||
|
||||
**Windows** - Command Prompt CA ADMINISTRATOR:
|
||||
```cmd
|
||||
REM Oprire servicii Oracle vechi
|
||||
net stop OracleServiceXE
|
||||
net stop OracleXETNSListener
|
||||
|
||||
REM Opțional: Dezactivează pornirea automată
|
||||
sc config OracleServiceXE start= disabled
|
||||
sc config OracleXETNSListener start= disabled
|
||||
|
||||
REM Verificare
|
||||
sc query OracleServiceXE
|
||||
```
|
||||
|
||||
**Output așteptat**: `STATE: STOPPED`
|
||||
|
||||
**Linux** - Terminal:
|
||||
```bash
|
||||
# Oprire serviciu Oracle vechi
|
||||
sudo systemctl stop oracle-xe
|
||||
sudo systemctl disable oracle-xe
|
||||
|
||||
# Verificare
|
||||
sudo systemctl status oracle-xe
|
||||
```
|
||||
|
||||
**Output așteptat**: `Active: inactive (dead)`
|
||||
|
||||
---
|
||||
|
||||
### PASUL 3/5: Instalare Oracle 21c XE
|
||||
|
||||
**Windows**:
|
||||
|
||||
1. Download Oracle XE 21c:
|
||||
- https://www.oracle.com/database/technologies/xe-downloads.html
|
||||
- Fișier: `OracleXE213_Win64.zip` (~2.5 GB)
|
||||
|
||||
2. Extrage și rulează `setup.exe`
|
||||
|
||||
3. Instalare:
|
||||
- Port: **1521** (același ca Oracle vechi)
|
||||
- Password SYS: `OraclePass123` (sau custom)
|
||||
- Configurare automată
|
||||
|
||||
4. Verificare instalare:
|
||||
```cmd
|
||||
sqlplus system/OraclePass123@localhost:1521/XE
|
||||
|
||||
SQL> SELECT * FROM v$version;
|
||||
```
|
||||
|
||||
**Linux** (LXC/Docker):
|
||||
|
||||
```bash
|
||||
# Dacă folosești LXC + Docker (recomandat)
|
||||
./00-install-oracle21c-xe.sh
|
||||
|
||||
# SAU instalare manuală Oracle XE 21c pe Linux
|
||||
# Vezi: https://docs.oracle.com/en/database/oracle/oracle-database/21/xeinl/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PASUL 4/5: Setup + Import
|
||||
|
||||
**Continuă cu master scriptul** (dacă l-ai folosit) SAU rulează manual:
|
||||
|
||||
```bash
|
||||
# Setup tablespaces și useri
|
||||
./01-setup-oracle21c.sh
|
||||
|
||||
# Import scheme
|
||||
# (asigură-te că DMP-urile sunt accesibile din WSL/Linux)
|
||||
./04-import-to-oracle21c.sh
|
||||
|
||||
# Creare sinonime
|
||||
./05-create-synonyms-grants.sh
|
||||
|
||||
# Finalizare
|
||||
./06-finalize-migration.sh
|
||||
```
|
||||
|
||||
**Dacă DMP-urile sunt pe Windows și rulezi scripturile din WSL**:
|
||||
|
||||
```bash
|
||||
# Montează directorul Windows în WSL
|
||||
ln -s /mnt/d/oracle-export /tmp/oracle-import
|
||||
|
||||
# SAU copiază fișierele
|
||||
cp /mnt/d/oracle-export/*.dmp /tmp/oracle-import/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PASUL 5/5: Verificare finală
|
||||
|
||||
**Testare conexiune**:
|
||||
|
||||
```bash
|
||||
sqlplus CONTAFIN_ORACLE/OraclePass123@localhost:1521/roa
|
||||
```
|
||||
|
||||
**Verificare obiecte**:
|
||||
|
||||
```sql
|
||||
-- Număr tabele
|
||||
SELECT COUNT(*) FROM user_tables;
|
||||
|
||||
-- Obiecte invalide (ar trebui 0)
|
||||
SELECT COUNT(*) FROM user_objects WHERE status = 'INVALID';
|
||||
|
||||
-- Verificare date
|
||||
SELECT COUNT(*) FROM <tabel_important>;
|
||||
```
|
||||
|
||||
**Testare aplicație**:
|
||||
- Pornește aplicația
|
||||
- Verifică login
|
||||
- Testează operații CRUD
|
||||
- Verifică rapoarte
|
||||
|
||||
---
|
||||
|
||||
## 🔧 TROUBLESHOOTING
|
||||
|
||||
### Problema: "ORA-01017: invalid username/password"
|
||||
|
||||
**Soluție**:
|
||||
```sql
|
||||
-- Conectează-te ca SYS
|
||||
sqlplus / as sysdba
|
||||
|
||||
-- Resetează parola
|
||||
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY OraclePass123;
|
||||
```
|
||||
|
||||
### Problema: "Export foarte mare/lent"
|
||||
|
||||
**Soluție**: Export selective (doar ce ai nevoie)
|
||||
```cmd
|
||||
exp system/pass@localhost:1521/XE ^
|
||||
TABLES=(CONTAFIN_ORACLE.FACTURI,CONTAFIN_ORACLE.CLIENTI) ^
|
||||
FILE=export_partial.dmp
|
||||
```
|
||||
|
||||
### Problema: "Import cu erori"
|
||||
|
||||
**Verificare**:
|
||||
```bash
|
||||
# Citește log-ul de import
|
||||
cat /tmp/oracle-import/contafin_import.log | grep -i "error"
|
||||
|
||||
# Majoritatea erorilor de "object already exists" sunt OK
|
||||
# Caută erori de tip: ORA-00942, ORA-01555, etc.
|
||||
```
|
||||
|
||||
### Problema: "Nu găsesc fișierul DMP în WSL"
|
||||
|
||||
**Soluție**:
|
||||
```bash
|
||||
# Windows D:\ e montat în WSL ca /mnt/d/
|
||||
ls /mnt/d/oracle-export/
|
||||
|
||||
# Copiază în locație accesibilă
|
||||
cp /mnt/d/oracle-export/*.dmp /tmp/oracle-import/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ QUICK COMMANDS
|
||||
|
||||
### Oprire/Pornire Oracle 21c
|
||||
|
||||
**Windows**:
|
||||
```cmd
|
||||
net stop OracleServiceXE
|
||||
net start OracleServiceXE
|
||||
```
|
||||
|
||||
**Linux**:
|
||||
```bash
|
||||
sudo systemctl stop oracle-xe
|
||||
sudo systemctl start oracle-xe
|
||||
```
|
||||
|
||||
### Conectare rapidă
|
||||
|
||||
```bash
|
||||
# SYS
|
||||
sqlplus / as sysdba
|
||||
sqlplus sys/OraclePass123@localhost:1521/roa as sysdba
|
||||
|
||||
# User normal
|
||||
sqlplus CONTAFIN_ORACLE/OraclePass123@localhost:1521/roa
|
||||
```
|
||||
|
||||
### Verificare status
|
||||
|
||||
```sql
|
||||
-- PDB-uri active
|
||||
SELECT name, open_mode FROM v$pdbs;
|
||||
|
||||
-- Tablespaces
|
||||
SELECT tablespace_name, bytes/1024/1024 MB FROM dba_data_files;
|
||||
|
||||
-- Useri
|
||||
SELECT username, account_status FROM dba_users WHERE username LIKE '%CONTAFIN%';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 TIMELINE ESTIMAT
|
||||
|
||||
| Pas | Activitate | Timp estimat |
|
||||
|-----|------------|--------------|
|
||||
| 1 | Export DMP | 15-90 min (depinde de mărimea BD) |
|
||||
| 2 | Oprire Oracle vechi | 1 min |
|
||||
| 3 | Instalare Oracle 21c | 15-30 min |
|
||||
| 4 | Setup + Import | 30-120 min |
|
||||
| 5 | Verificare | 15 min |
|
||||
| **TOTAL** | | **1.5 - 4 ore** |
|
||||
|
||||
---
|
||||
|
||||
## ✅ CHECKLIST FINAL
|
||||
|
||||
- [ ] Export DMP complet (fișiere > 0 bytes)
|
||||
- [ ] Oracle vechi oprit și dezactivat
|
||||
- [ ] Oracle 21c XE instalat și pornit
|
||||
- [ ] Setup tablespace ROA complet
|
||||
- [ ] Import CONTAFIN_ORACLE success
|
||||
- [ ] Import schema secundară success
|
||||
- [ ] Sinonime create (53 bucăți)
|
||||
- [ ] Grant-uri acordate (147 bucăți)
|
||||
- [ ] Obiecte recompilate (0 invalide)
|
||||
- [ ] Testare conexiune OK
|
||||
- [ ] Testare aplicație OK
|
||||
- [ ] Backup DMP păstrat pentru siguranță
|
||||
|
||||
---
|
||||
|
||||
## 🆘 ROLLBACK (Dacă ceva merge prost)
|
||||
|
||||
Dacă Oracle 21c nu funcționează cum trebuie:
|
||||
|
||||
1. **Oprește Oracle 21c**:
|
||||
```cmd
|
||||
net stop OracleServiceXE
|
||||
sc config OracleServiceXE start= disabled
|
||||
```
|
||||
|
||||
2. **Repornește Oracle vechi**:
|
||||
```cmd
|
||||
sc config OracleServiceXE start= auto
|
||||
net start OracleServiceXE
|
||||
```
|
||||
|
||||
3. **Verifică**: Aplicația ar trebui să funcționeze cu Oracle vechi
|
||||
|
||||
4. **Investigație**: Verifică log-urile din Oracle 21c
|
||||
- Windows: `C:\app\oracle\product\21c\homes\OraDB21Home1\diag\rdbms\xe\xe\trace\`
|
||||
- Linux: `/opt/oracle/diag/rdbms/xe/xe/trace/`
|
||||
|
||||
---
|
||||
|
||||
## 📞 SUPORT
|
||||
|
||||
**Documentație oficială Oracle**:
|
||||
- https://docs.oracle.com/en/database/oracle/oracle-database/21/
|
||||
|
||||
**Issues GitHub** (pentru probleme cu scripturile):
|
||||
- https://github.com/anthropics/claude-code/issues
|
||||
|
||||
**Community Oracle**:
|
||||
- https://forums.oracle.com/
|
||||
|
||||
---
|
||||
|
||||
**Succes cu upgrade-ul! 🚀**
|
||||
426
proxmox/lxc108-oracle/migration/README.md
Normal file
426
proxmox/lxc108-oracle/migration/README.md
Normal file
@@ -0,0 +1,426 @@
|
||||
# 🚀 SCRIPTURI AUTOMATIZARE MIGRARE ORACLE 10g → 21c XE
|
||||
|
||||
**Director:** `proxmox/lxc108-oracle/migration/`
|
||||
**Data**: 1 Octombrie 2025
|
||||
**Status**: ✅ TESTAT ȘI FUNCȚIONAL
|
||||
**Versiune**: 2.1 - Universal Multi-platform + Export Flexibil
|
||||
|
||||
---
|
||||
|
||||
## 🎯 NOI FUNCȚIONALITĂȚI (Versiunea 2.1)
|
||||
|
||||
### ✨ Master Control Script
|
||||
- **00-MASTER-MIGRATION.sh** - Orchestrează tot procesul de migrare
|
||||
- Ghidare interactivă pas cu pas
|
||||
- Confirmare înainte de fiecare acțiune
|
||||
- Suport pentru 2 moduri: **MIGRARE** și **INSTALARE NOUĂ**
|
||||
- **Multi-platform support**: LXC, VM Linux/Windows, Server fizic
|
||||
|
||||
### 🔄 Schema Dinamică
|
||||
- Nu mai ești limitat la MARIUSM_AUTO
|
||||
- Poți specifica orice nume de schema pentru cel de-al doilea user
|
||||
- Perfect pentru instalări noi cu firme diferite
|
||||
|
||||
### 📦 SYS Objects Pre-Generat
|
||||
- Fișier **sys_objects.sql** gata de import
|
||||
- Nu mai trebuie să rulezi export pe Oracle 10g pentru obiecte SYS
|
||||
- Include toate cele 9 obiecte custom SYS
|
||||
|
||||
### 🚀 Export Flexibil (NOU în v2.1)
|
||||
- **3 moduri de export** pentru maxim flexibilitate:
|
||||
1. **AUTOMAT** - Export via SSH către server remote (Linux/Windows)
|
||||
2. **MANUAL** - Tu exporti manual, scriptul preia fișierele
|
||||
3. **LOCAL** - Migrare pe același server (Oracle sursa și destinație, porturi diferite)
|
||||
|
||||
---
|
||||
|
||||
## 📋 LISTA SCRIPTURI
|
||||
|
||||
### 🎯 Script Principal (RECOMANDAT - START AICI!)
|
||||
|
||||
| Script | Descriere | Mod |
|
||||
|--------|-----------|-----|
|
||||
| **`00-MASTER-MIGRATION.sh`** | **🚀 Master control - Orchestrează tot procesul** | **Interactiv** |
|
||||
|
||||
### Scripturi Linux/WSL (bash)
|
||||
|
||||
| Script | Descriere | Durată | Unde rulează |
|
||||
|--------|-----------|--------|--------------|
|
||||
| `00-install-oracle21c-xe.sh` | Instalare Oracle 21c XE + Docker | ~15 min | Proxmox/LXC |
|
||||
| `01-setup-oracle21c.sh` | Setup tablespace ROA + useri | ~3 min | WSL/Linux |
|
||||
| **`02-export-source.sh`** | **Export universal (AUTO/MANUAL/LOCAL)** | **~75 min** | **WSL/Linux** |
|
||||
| `03-transfer-to-oracle21c.sh` | Transfer fișiere DMP către Oracle 21c | ~10 min | WSL/Linux |
|
||||
| `04-import-to-oracle21c.sh` | Import scheme + SYS objects | ~2h | WSL/Linux |
|
||||
| `05-create-synonyms-grants.sh` | Creare 53 sinonime + 147 grant-uri | ~5 min | WSL/Linux |
|
||||
| `06-finalize-migration.sh` | Recompilare + verificare finală | ~10 min | WSL/Linux |
|
||||
|
||||
### Scripturi Windows (bat) - DEPRECATED
|
||||
|
||||
| Script | Descriere | Status |
|
||||
|--------|-----------|--------|
|
||||
| `02-export-oracle10g.bat` | Export vechi (doar Windows) | ⚠️ Înlocuit cu 02-export-source.sh |
|
||||
|
||||
### Scripturi SQL auxiliare
|
||||
|
||||
| Script | Descriere |
|
||||
|--------|-----------|
|
||||
| `export-sys-objects.sql` | Export DDL obiecte SYS custom |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 MODURI DE EXPORT (Versiune 2.1)
|
||||
|
||||
Scriptul **02-export-source.sh** suportă 3 moduri de export pentru maxim flexibilitate:
|
||||
|
||||
### 1️⃣ Export AUTOMAT (SSH)
|
||||
**Când se folosește**: Migrare între servere diferite cu SSH disponibil
|
||||
|
||||
**Configurare necesară**:
|
||||
- IP/hostname server sursă
|
||||
- User SSH cu acces
|
||||
- Tip OS (Linux/Windows)
|
||||
|
||||
**Avantaje**:
|
||||
- Export complet automat
|
||||
- Nu necesită intervenție manuală
|
||||
- Verificare automată export
|
||||
|
||||
**Exemplu scenariu**: Oracle 10g @ VM 107 (10.0.20.122) → Oracle 21c @ LXC 108 (10.0.20.201)
|
||||
|
||||
### 2️⃣ Export MANUAL
|
||||
**Când se folosește**:
|
||||
- Nu ai acces SSH la sursa
|
||||
- Vrei să controlezi manual exportul
|
||||
- Migrare din medii fără SSH (Windows standalone)
|
||||
|
||||
**Cum funcționează**:
|
||||
1. Scriptul îți arată comenzile exacte de export
|
||||
2. Tu rulezi manual exportul pe server sursă
|
||||
3. Copiezi fișierele DMP în locația indicată
|
||||
4. Scriptul verifică și continuă procesul
|
||||
|
||||
**Avantaje**:
|
||||
- Control total asupra exportului
|
||||
- Nu necesită SSH
|
||||
- Funcționează în orice mediu
|
||||
|
||||
**Exemplu scenariu**: Oracle 11g @ Windows fără SSH → Oracle 21c @ Server Linux
|
||||
|
||||
### 3️⃣ Export LOCAL (Același server)
|
||||
**Când se folosește**: Upgrade Oracle pe același server (instanțe diferite, porturi diferite)
|
||||
|
||||
**Configurare necesară**:
|
||||
- Port Oracle sursă (ex: 1521)
|
||||
- Port Oracle destinație (ex: 1522)
|
||||
- SID pentru ambele instanțe
|
||||
- Password SYSTEM pentru sursă
|
||||
|
||||
**Avantaje**:
|
||||
- Export direct fără SSH sau transfer
|
||||
- Cel mai rapid mod (fără copiere fișiere)
|
||||
- Perfect pentru upgrade in-place
|
||||
|
||||
**Exemplu scenariu**: Oracle 11g XE @ localhost:1521 → Oracle 21c XE @ localhost:1522
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ PLATFORME SUPORTATE
|
||||
|
||||
### Oracle 21c Destinație:
|
||||
- ✅ LXC Proxmox + Docker
|
||||
- ✅ VM Linux + Docker
|
||||
- ✅ VM Linux native Oracle
|
||||
- ✅ VM Windows Oracle
|
||||
- ✅ Server fizic (Linux/Windows)
|
||||
|
||||
### Oracle Sursă (pentru export):
|
||||
- ✅ Export AUTOMAT via SSH (Linux/Windows)
|
||||
- ✅ Export MANUAL (orice platformă)
|
||||
- ✅ Export LOCAL (același server, porturi diferite)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 RULARE PAS CU PAS
|
||||
|
||||
### Pasul 0: Instalare Oracle 21c XE (pe Proxmox/LXC) - OPȚIONAL
|
||||
|
||||
**Doar dacă nu ai Oracle 21c XE deja instalat!**
|
||||
|
||||
```bash
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/proxmox/lxc108-oracle/migration
|
||||
chmod +x *.sh
|
||||
|
||||
# Opțiunea 1: Rulare direct pe Proxmox host
|
||||
ssh root@10.0.20.201
|
||||
./00-install-oracle21c-xe.sh
|
||||
|
||||
# Opțiunea 2: Rulare din WSL (cu SSH către Proxmox)
|
||||
./00-install-oracle21c-xe.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Verifică LXC 108 există
|
||||
- Instalează Docker în LXC (dacă nu există)
|
||||
- Download Oracle 21c XE image (~2-3 GB)
|
||||
- Start container Oracle XE
|
||||
- **Șterge XEPDB1 automat**
|
||||
- **Creează PDB ROA**
|
||||
- Întreabă dacă vrei PDB ROA2 (opțional)
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ INSTALARE ORACLE 21c XE COMPLETĂ!
|
||||
PDB: ROA (XEPDB1 șters)
|
||||
```
|
||||
|
||||
**Timp estimat:** ~15-20 minute (include download)
|
||||
|
||||
---
|
||||
|
||||
### Pasul 1: Setup Oracle 21c XE (pe WSL/Linux)
|
||||
|
||||
```bash
|
||||
cd /mnt/e/proiecte/ROMFASTSQL/proxmox/lxc108-oracle/migration
|
||||
chmod +x *.sh
|
||||
./01-setup-oracle21c.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Verifică container oracle-xe
|
||||
- Creează PDB ROA
|
||||
- Creează tablespace ROA (20GB, autoextend)
|
||||
- Creează useri CONTAFIN_ORACLE și MARIUSM_AUTO
|
||||
- Acordă system privileges
|
||||
- Acordă grant-uri DBMS packages
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ SETUP COMPLET!
|
||||
PDB ROA creat și configurat
|
||||
Tablespace: ROA (20GB)
|
||||
Useri: CONTAFIN_ORACLE, MARIUSM_AUTO
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pasul 2: Export din Oracle 10g (pe Windows VM 107)
|
||||
|
||||
```batch
|
||||
D:\migration-scripts\02-export-oracle10g.bat
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Exportă CONTAFIN_ORACLE (~15 min)
|
||||
- Exportă MARIUSM_AUTO (~60 min)
|
||||
- Exportă SYS objects DDL (~1 min)
|
||||
|
||||
**Fișiere generate:**
|
||||
```
|
||||
D:\ORACLE_EXPORT\dumps\
|
||||
├── CONTAFIN_ORACLE_20250930.dmp
|
||||
├── MARIUSM_AUTO_20250930.dmp
|
||||
└── SYS_OBJECTS.sql
|
||||
```
|
||||
|
||||
**După export:**
|
||||
- Copiază fișierele *.dmp în WSL: `/mnt/e/ORACLE_EXPORT/dumps/`
|
||||
- Sau asigură-te că `D:\ORACLE_EXPORT` este accesibil ca `/mnt/e/ORACLE_EXPORT`
|
||||
|
||||
---
|
||||
|
||||
### Pasul 3: Transfer către Oracle 21c (pe WSL/Linux)
|
||||
|
||||
```bash
|
||||
./03-transfer-to-oracle21c.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Verifică fișiere locale în `/mnt/e/ORACLE_EXPORT/dumps`
|
||||
- Transfer fișiere către Proxmox `/tmp/oracle-import`
|
||||
- Copiază fișiere în container Docker oracle-xe
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ TRANSFER COMPLET!
|
||||
Fișierele sunt în container oracle-xe:/tmp/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pasul 4: Import în Oracle 21c (pe WSL/Linux)
|
||||
|
||||
```bash
|
||||
./04-import-to-oracle21c.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Import SYS objects custom (~5 min)
|
||||
- Grant-uri SYS → CONTAFIN_ORACLE
|
||||
- Import CONTAFIN_ORACLE (~15 min)
|
||||
- Import MARIUSM_AUTO (~90 min)
|
||||
- Verificare obiecte importate
|
||||
|
||||
**Durată totală:** ~2 ore
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ IMPORT COMPLET!
|
||||
Log-uri:
|
||||
/tmp/contafin_import.log
|
||||
/tmp/mariusm_import.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pasul 5: Creare Sinonime + Grant-uri (pe WSL/Linux)
|
||||
|
||||
```bash
|
||||
./05-create-synonyms-grants.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Crează 53 sinonime publice (SYN_PACK_DREPTURI, etc.)
|
||||
- Acordă 147 grant-uri către PUBLIC
|
||||
- Verificare sinonime și grant-uri create
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ SINONIME + GRANT-URI COMPLETE!
|
||||
Sinonime SYN_*: 53
|
||||
Grant-uri to PUBLIC: 147
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pasul 6: Finalizare Migrare (pe WSL/Linux)
|
||||
|
||||
```bash
|
||||
./06-finalize-migration.sh
|
||||
```
|
||||
|
||||
**Ce face:**
|
||||
- Recompilare obiecte invalide (CONTAFIN_ORACLE + MARIUSM_AUTO)
|
||||
- Verificare completă migrare (10 teste)
|
||||
- Raport final
|
||||
|
||||
**Output așteptat:**
|
||||
```
|
||||
✅ MIGRARE FINALIZATA CU SUCCES!
|
||||
Toate verificările PASSED
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ CONFIGURARE
|
||||
|
||||
### Variabile de modificat (dacă e necesar)
|
||||
|
||||
**În toate scripturile bash:**
|
||||
```bash
|
||||
ORACLE_PWD="OraclePass123" # Parola Oracle
|
||||
PROXMOX_HOST="root@10.0.20.201" # IP Proxmox
|
||||
SOURCE_DIR="/mnt/e/ORACLE_EXPORT" # Director export Windows
|
||||
```
|
||||
|
||||
**În scriptul Windows:**
|
||||
```batch
|
||||
set ORACLE_CONN=system/romfastromfast@10.0.20.122:1521/ROA
|
||||
set EXPORT_DIR=D:\ORACLE_EXPORT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 TIMP TOTAL ESTIMAT
|
||||
|
||||
| Fază | Durată |
|
||||
|------|--------|
|
||||
| Setup Oracle 21c | 5 min |
|
||||
| Export Oracle 10g | 60-75 min |
|
||||
| Transfer fișiere | 10 min |
|
||||
| Import scheme | 110 min |
|
||||
| Sinonime + Grant-uri | 5 min |
|
||||
| Finalizare | 10 min |
|
||||
| **TOTAL** | **~3.5 ore** |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ TROUBLESHOOTING
|
||||
|
||||
### Eroare: "Container oracle-xe nu rulează"
|
||||
|
||||
```bash
|
||||
ssh root@10.0.20.201
|
||||
pct exec 108 -- docker start oracle-xe
|
||||
docker logs -f oracle-xe
|
||||
```
|
||||
|
||||
### Eroare: "PDB ROA nu există"
|
||||
|
||||
Rulează din nou `01-setup-oracle21c.sh` - scriptul șterge și recreează PDB dacă există.
|
||||
|
||||
### Eroare: "Fișiere DMP nu găsite"
|
||||
|
||||
Verifică:
|
||||
```bash
|
||||
ls -lh /mnt/e/ORACLE_EXPORT/dumps/*.dmp
|
||||
```
|
||||
|
||||
Copiază manual dacă e necesar:
|
||||
```bash
|
||||
cp D:\ORACLE_EXPORT\dumps\*.dmp /mnt/e/ORACLE_EXPORT/dumps/
|
||||
```
|
||||
|
||||
### Verificare log-uri import
|
||||
|
||||
```bash
|
||||
ssh root@10.0.20.201
|
||||
pct exec 108 -- docker exec oracle-xe tail -100 /tmp/contafin_import.log
|
||||
pct exec 108 -- docker exec oracle-xe tail -100 /tmp/mariusm_import.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ VERIFICARE FINALĂ MANUALĂ
|
||||
|
||||
După rularea tuturor scripturilor:
|
||||
|
||||
```bash
|
||||
# Conectare la Oracle 21c
|
||||
ssh root@10.0.20.201
|
||||
pct exec 108 -- docker exec -it oracle-xe sqlplus CONTAFIN_ORACLE/OraclePass123@localhost:1521/roa
|
||||
|
||||
# Teste SQL
|
||||
SELECT COUNT(*) FROM nom_firme;
|
||||
SELECT * FROM syn_pack_drepturi WHERE ROWNUM <= 5;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 STRUCTURA FINALĂ
|
||||
|
||||
După migrare, în Oracle 21c vei avea:
|
||||
|
||||
```
|
||||
CDB: XE
|
||||
└── PDB: ROA
|
||||
├── Tablespace: ROA (20GB)
|
||||
├── Users:
|
||||
│ ├── CONTAFIN_ORACLE (366 obiecte)
|
||||
│ └── MARIUSM_AUTO (3,667 obiecte)
|
||||
├── SYS custom objects: 9
|
||||
├── Public synonyms (SYN_*): 53
|
||||
└── Grants to PUBLIC: 147
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 DOCUMENTAȚIE COMPLETĂ
|
||||
|
||||
Pentru detalii complete, vezi:
|
||||
- `../README.md` - Documentație principală LXC 108 Oracle
|
||||
- `../../README.md` - Index Proxmox principal
|
||||
|
||||
---
|
||||
|
||||
**Succes la migrare! 🚀**
|
||||
48
proxmox/lxc108-oracle/migration/export-sys-objects.sql
Normal file
48
proxmox/lxc108-oracle/migration/export-sys-objects.sql
Normal file
@@ -0,0 +1,48 @@
|
||||
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF LINESIZE 5000
|
||||
SET LONG 10000000 LONGCHUNKSIZE 10000000
|
||||
|
||||
SPOOL D:\ORACLE_EXPORT\dumps\SYS_OBJECTS.sql
|
||||
|
||||
-- Export DDL pentru obiectele SYS custom
|
||||
SELECT '-- SYS.AUTH_PACK Package Spec' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PACKAGE','AUTH_PACK','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='AUTH_PACK');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.AUTH_PACK Package Body' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PACKAGE BODY','AUTH_PACK','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='AUTH_PACK' AND object_type='PACKAGE BODY');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.NEWSCHEMA Procedure' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PROCEDURE','NEWSCHEMA','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='NEWSCHEMA');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.NEWSCHEMAJOB Procedure' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PROCEDURE','NEWSCHEMAJOB','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='NEWSCHEMAJOB');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.NEWSCHEMAPROGRESS Function' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('FUNCTION','NEWSCHEMAPROGRESS','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='NEWSCHEMAPROGRESS');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.UPDATESQLPLUS Procedure' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PROCEDURE','UPDATESQLPLUS','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='UPDATESQLPLUS');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.EXECUTESCRIPTOS Procedure' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('PROCEDURE','EXECUTESCRIPTOS','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='EXECUTESCRIPTOS');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.VAUTH_SERII View' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('VIEW','VAUTH_SERII','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_objects WHERE owner='SYS' AND object_name='VAUTH_SERII');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.AUTH_SERII Table' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('TABLE','AUTH_SERII','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_tables WHERE owner='SYS' AND table_name='AUTH_SERII');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SELECT '-- SYS.AUTH_DETALII Table' FROM DUAL;
|
||||
SELECT DBMS_METADATA.GET_DDL('TABLE','AUTH_DETALII','SYS') FROM DUAL WHERE EXISTS (SELECT 1 FROM dba_tables WHERE owner='SYS' AND table_name='AUTH_DETALII');
|
||||
SELECT '/' FROM DUAL;
|
||||
|
||||
SPOOL OFF
|
||||
EXIT;
|
||||
754
proxmox/lxc108-oracle/migration/sys_objects.sql
Normal file
754
proxmox/lxc108-oracle/migration/sys_objects.sql
Normal file
@@ -0,0 +1,754 @@
|
||||
-- ============================================================================
|
||||
-- OBIECTE SYS CUSTOM - PRE-GENERAT
|
||||
-- Oracle 10g Migration → Oracle 21c XE
|
||||
-- Data: 30 Septembrie 2025
|
||||
-- Sursa: Oracle 10g @ 10.0.20.122:1521/ROA
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Acest fisier contine DDL pentru toate obiectele custom din SYS:
|
||||
-- - 2 TABLES: AUTH_DETALII, AUTH_SERII
|
||||
-- - 1 VIEW: VAUTH_SERII
|
||||
-- - 1 PACKAGE: AUTH_PACK (spec + body)
|
||||
-- - 4 PROCEDURES: EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS
|
||||
--
|
||||
-- IMPORT: Ruleaza acest script ca SYS in PDB ROA (NU in CDB!)
|
||||
--
|
||||
-- Conexiune test:
|
||||
-- sqlplus sys/OraclePass123@localhost:1521/roa as sysdba
|
||||
-- SELECT name, cdb FROM v$database; -- Trebuie sa fie: ROA, NO
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
SET SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
PROMPT ========================================
|
||||
PROMPT Import Obiecte Custom SYS
|
||||
PROMPT ========================================
|
||||
PROMPT
|
||||
|
||||
-- 1. TABELE
|
||||
PROMPT [1/9] Creating SYS.AUTH_DETALII (TABLE)...
|
||||
|
||||
CREATE TABLE "SYS"."AUTH_DETALII"
|
||||
( "DETALII" VARCHAR2(15) NOT NULL ENABLE
|
||||
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
|
||||
STORAGE(INITIAL 16384 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
|
||||
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
|
||||
TABLESPACE "SYSTEM";
|
||||
|
||||
PROMPT [2/9] Creating SYS.AUTH_SERII (TABLE)...
|
||||
|
||||
CREATE TABLE "SYS"."AUTH_SERII"
|
||||
( "ID_SERIE" NUMBER(5,0) NOT NULL ENABLE,
|
||||
"ID_PROGRAM" NUMBER(5,0) NOT NULL ENABLE,
|
||||
"SERIE" RAW(128) NOT NULL ENABLE,
|
||||
"STERS" NUMBER(1,0) DEFAULT 0 NOT NULL ENABLE,
|
||||
"DATAORA" DATE DEFAULT sysdate NOT NULL ENABLE,
|
||||
"ID_UTIL" NUMBER(5,0) NOT NULL ENABLE,
|
||||
"DATAORAS" DATE,
|
||||
"ID_UTILS" NUMBER(5,0),
|
||||
CONSTRAINT "PK_AUTH_SERII" PRIMARY KEY ("ID_SERIE")
|
||||
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
|
||||
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
|
||||
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
|
||||
TABLESPACE "SYSTEM" ENABLE
|
||||
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
|
||||
STORAGE(INITIAL 16384 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
|
||||
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
|
||||
TABLESPACE "SYSTEM";
|
||||
|
||||
-- 2. VIEW
|
||||
PROMPT [3/9] Creating SYS.VAUTH_SERII (VIEW)...
|
||||
|
||||
CREATE OR REPLACE FORCE VIEW "SYS"."VAUTH_SERII" ("ID_PROGRAM", "NUME", "SERIE", "NR_UTIL", "DATA_VAL") AS
|
||||
select a.id_program,
|
||||
a.denumire as nume,
|
||||
auth_pack.selecteaza_serie(a.id_program) as serie,
|
||||
auth_pack.selecteaza_nr_util(a.id_program) as nr_util,
|
||||
auth_pack.selecteaza_data_val(a.id_program) as data_val
|
||||
from syn_nom_programe a
|
||||
left join syn_def_programe b on a.id_program = b.ide_program
|
||||
where b.sters = 0
|
||||
and b.instalat = 1;
|
||||
|
||||
-- 3. PACKAGE SPEC
|
||||
PROMPT [4/9] Creating SYS.AUTH_PACK (PACKAGE SPEC)...
|
||||
|
||||
CREATE OR REPLACE PACKAGE "SYS"."AUTH_PACK" is
|
||||
|
||||
-- Author : MARIUS.ATANASIU
|
||||
-- Created : 11/5/2005 9:58:27 AM
|
||||
-- Purpose : License and authentication management
|
||||
|
||||
procedure verifica_program;
|
||||
|
||||
procedure verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2);
|
||||
procedure verifica_licenta_luna(v_an IN NUMBER,
|
||||
v_luna IN NUMBER,
|
||||
v_tip IN NUMBER);
|
||||
procedure verifica_numar_firme;
|
||||
|
||||
procedure adauga_serie(V_ID_PROGRAM IN NUMBER,
|
||||
V_SERIE IN VARCHAR2,
|
||||
V_ID_UTILAD IN NUMBER);
|
||||
|
||||
procedure sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER);
|
||||
|
||||
procedure verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW);
|
||||
|
||||
function selecteaza_serie(V_ID_PROGRAM IN NUMBER) return varchar2;
|
||||
|
||||
function selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) return number;
|
||||
|
||||
function selecteaza_data_val(V_ID_PROGRAM IN NUMBER) return date;
|
||||
|
||||
function decripteaza_serie(V_ID_PROGRAM IN NUMBER,
|
||||
V_SERIE IN RAW,
|
||||
V_DATAORA IN DATE) return varchar2;
|
||||
|
||||
function decripteaza_nr_util(V_SERIEC IN VARCHAR2) return number;
|
||||
|
||||
function decripteaza_data_val(V_SERIEC IN VARCHAR2, V_ZI IN VARCHAR2)
|
||||
return date;
|
||||
|
||||
function hextodec(V_HEXA IN VARCHAR2) return number;
|
||||
|
||||
function dectohex(V_NUMAR IN NUMBER) return varchar2;
|
||||
|
||||
end AUTH_PACK;
|
||||
/
|
||||
|
||||
-- 4. PACKAGE BODY
|
||||
PROMPT [5/9] Creating SYS.AUTH_PACK (PACKAGE BODY)...
|
||||
|
||||
CREATE OR REPLACE PACKAGE BODY "SYS"."AUTH_PACK" is
|
||||
|
||||
procedure verifica_program is
|
||||
v_program VARCHAR2(256);
|
||||
v_modul VARCHAR2(256);
|
||||
v_sid NUMBER(16);
|
||||
begin
|
||||
begin
|
||||
SELECT sid, UPPER(TRIM(program)), UPPER(TRIM(module))
|
||||
INTO v_sid, v_program, v_modul
|
||||
FROM v$session
|
||||
WHERE audsid = USERENV('SESSIONID')
|
||||
AND audsid != 0
|
||||
AND rownum = 1
|
||||
AND STATUS <> 'KILLED';
|
||||
|
||||
IF v_program not in ('PLSQLDEV.EXE',
|
||||
'ROASTART.EXE',
|
||||
'GENERARESCRIPT.EXE',
|
||||
'SQLPLUS.EXE',
|
||||
'ROAGEN.EXE',
|
||||
'ROASUPORT.EXE',
|
||||
'EXP.EXE',
|
||||
'EXPDP.EXE',
|
||||
'IMP.EXE',
|
||||
'IMPDP.EXE',
|
||||
'APSNET_WP.EXE',
|
||||
'WEBDEV.WEBSERVER.EXE',
|
||||
'VFP9.EXE',
|
||||
'TASKS.EXE',
|
||||
'ROAACTUALIZARI.EXE',
|
||||
'ROA2COCACOLA.EXE') and
|
||||
user not in ('SYS',
|
||||
'SYSTEM',
|
||||
'DBSNMP',
|
||||
'CTXSYS',
|
||||
'MDSYS',
|
||||
'DIP',
|
||||
'SYSMAN',
|
||||
'WMSYS') THEN
|
||||
IF v_program <> v_modul THEN
|
||||
RAISE_APPLICATION_ERROR(-20000, 'Acces interzis!');
|
||||
END IF;
|
||||
|
||||
auth_pack.verifica_licenta(v_sid, v_program);
|
||||
END IF;
|
||||
exception
|
||||
when NO_DATA_FOUND then
|
||||
v_program := Null;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2) is
|
||||
|
||||
v_serie VARCHAR2(256);
|
||||
v_seriec VARCHAR2(256);
|
||||
v_nr_util NUMBER(5);
|
||||
v_utilizatori NUMBER(5);
|
||||
v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE;
|
||||
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
|
||||
v_dataora DATE;
|
||||
v_data_val DATE;
|
||||
v_zi VARCHAR2(2);
|
||||
|
||||
begin
|
||||
V_NUME_PROGRAM := TRIM(REPLACE(v_program, '.EXE'));
|
||||
begin
|
||||
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
|
||||
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
|
||||
FROM SYN_NOM_PROGRAME A
|
||||
LEFT JOIN AUTH_SERII B
|
||||
ON A.ID_PROGRAM = B.ID_PROGRAM
|
||||
WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
|
||||
AND B.STERS = 0;
|
||||
|
||||
exception
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Nu aveti licenta pentru ' ||
|
||||
V_NUME_PROGRAM || '!' || CHR(13) || CHR(10) ||
|
||||
' Licenta poate fi introdusa prin programul ROASUPORT!');
|
||||
end;
|
||||
|
||||
v_zi := LPAD(extract(day from v_dataora), 2, '0');
|
||||
v_seriec := auth_pack.decripteaza_serie(v_id_program,
|
||||
v_serie,
|
||||
v_dataora);
|
||||
v_utilizatori := auth_pack.decripteaza_nr_util(v_seriec);
|
||||
v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi);
|
||||
|
||||
IF v_utilizatori > 0 THEN
|
||||
SELECT COUNT(DISTINCT client_info)
|
||||
INTO v_nr_util
|
||||
FROM v$session
|
||||
WHERE UPPER(TRIM(PROGRAM)) = v_program
|
||||
AND SID != v_sid
|
||||
and status <> 'KILLED'
|
||||
and nvl(client_info, 'x') <> sys_context('userenv', 'ip_address');
|
||||
|
||||
IF v_nr_util >= v_utilizatori THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Ati depasit numarul de licente (' ||
|
||||
v_utilizatori || ') pentru programul ' ||
|
||||
v_nume_program || ' !' || CHR(13) ||
|
||||
CHR(10) ||
|
||||
' Licenta poate fi reinnoita prin programul ROASUPORT!');
|
||||
END IF;
|
||||
ELSE
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Seria introdusa pentru acest program nu este corecta!' ||
|
||||
CHR(13) || CHR(10) ||
|
||||
' Licenta poate fi modificata prin programul ROASUPORT!');
|
||||
END IF;
|
||||
end;
|
||||
|
||||
procedure verifica_licenta_luna(v_an IN NUMBER,
|
||||
v_luna IN NUMBER,
|
||||
v_tip IN NUMBER) is
|
||||
|
||||
v_serie VARCHAR2(256);
|
||||
v_seriec VARCHAR2(256);
|
||||
v_nume_program1 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
|
||||
v_nume_program2 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASAL';
|
||||
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
|
||||
v_dataora DATE;
|
||||
v_data_val DATE;
|
||||
v_zi VARCHAR2(2);
|
||||
|
||||
begin
|
||||
begin
|
||||
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
|
||||
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
|
||||
FROM SYN_NOM_PROGRAME A
|
||||
LEFT JOIN AUTH_SERII B
|
||||
ON A.ID_PROGRAM = B.ID_PROGRAM
|
||||
WHERE UPPER(TRIM(A.DENUMIRE)) =
|
||||
DECODE(V_TIP, 1, V_NUME_PROGRAM1, 2, V_NUME_PROGRAM2, 'XYZ')
|
||||
AND B.STERS = 0;
|
||||
|
||||
exception
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Nu aveti licenta pentru deschiderea de luna noua!' ||
|
||||
CHR(13) || CHR(10) ||
|
||||
' Licenta poate fi introdusa prin programul ROASUPORT!');
|
||||
end;
|
||||
|
||||
v_zi := LPAD(extract(day from v_dataora), 2, '0');
|
||||
v_seriec := auth_pack.decripteaza_serie(v_id_program,
|
||||
v_serie,
|
||||
v_dataora);
|
||||
v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi);
|
||||
|
||||
IF v_data_val < TO_DATE(v_an || v_luna, 'YYYYMM') THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Licenta pentru acest program a expirat!' ||
|
||||
CHR(13) || CHR(10) ||
|
||||
' Licenta poate fi reinnoita prin programul ROASUPORT!');
|
||||
END IF;
|
||||
|
||||
end;
|
||||
|
||||
procedure verifica_numar_firme is
|
||||
|
||||
v_serie VARCHAR2(256);
|
||||
v_seriec VARCHAR2(256);
|
||||
v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
|
||||
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
|
||||
v_dataora DATE;
|
||||
V_NR_MAX_FIRME NUMBER(10) := 0;
|
||||
V_NR_FIRME NUMBER(10) := 0;
|
||||
|
||||
begin
|
||||
begin
|
||||
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
|
||||
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
|
||||
FROM SYN_NOM_PROGRAME A
|
||||
LEFT JOIN AUTH_SERII B
|
||||
ON A.ID_PROGRAM = B.ID_PROGRAM
|
||||
WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
|
||||
AND B.STERS = 0;
|
||||
|
||||
exception
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Nu aveti licenta pentru deschiderea unei firme noi!' ||
|
||||
CHR(13) || CHR(10) ||
|
||||
' Licenta poate fi introdusa prin programul ROASUPORT!');
|
||||
end;
|
||||
|
||||
v_seriec := auth_pack.decripteaza_serie(v_id_program,
|
||||
v_serie,
|
||||
v_dataora);
|
||||
V_NR_MAX_FIRME := auth_pack.decripteaza_nr_util(V_SERIEC);
|
||||
|
||||
SELECT COUNT(*)
|
||||
INTO V_NR_FIRME
|
||||
FROM SYN_NOM_FIRME
|
||||
WHERE STERS = 0
|
||||
AND NVL(ID_MAMA, 0) = 0;
|
||||
|
||||
IF V_NR_FIRME >= V_NR_MAX_FIRME THEN
|
||||
RAISE_APPLICATION_ERROR(-20000,
|
||||
'Aveti licenta pentru maxim ' ||
|
||||
V_NR_MAX_FIRME || ' firme (' || V_NR_FIRME ||
|
||||
' firme deja definite)!' || CHR(13) ||
|
||||
CHR(10) ||
|
||||
' Licenta poate fi introdusa prin programul ROASUPORT!');
|
||||
END IF;
|
||||
|
||||
end;
|
||||
|
||||
procedure adauga_serie(V_ID_PROGRAM IN NUMBER,
|
||||
V_SERIE IN VARCHAR2,
|
||||
V_ID_UTILAD IN NUMBER) is
|
||||
V_ID_SERIE AUTH_SERII.ID_SERIE%TYPE;
|
||||
V_SERIER AUTH_SERII.SERIE%TYPE;
|
||||
eroare_de_conversie EXCEPTION;
|
||||
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
|
||||
begin
|
||||
BEGIN
|
||||
V_SERIER := HEXTORAW(V_SERIE);
|
||||
EXCEPTION
|
||||
WHEN eroare_de_conversie THEN
|
||||
RAISE_APPLICATION_ERROR(-20000, 'Aceasta serie nu este valida!');
|
||||
END;
|
||||
|
||||
auth_pack.verifica_serie(V_ID_PROGRAM, V_SERIER);
|
||||
|
||||
SELECT SEQ_AUTH_SERII.NEXTVAL INTO V_ID_SERIE FROM DUAL;
|
||||
|
||||
INSERT INTO AUTH_SERII
|
||||
(ID_SERIE, ID_PROGRAM, SERIE, ID_UTIL)
|
||||
VALUES
|
||||
(V_ID_SERIE, V_ID_PROGRAM, V_SERIER, V_ID_UTILAD);
|
||||
|
||||
end;
|
||||
|
||||
procedure sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER) is
|
||||
begin
|
||||
UPDATE AUTH_SERII
|
||||
SET STERS = 1, ID_UTILS = V_ID_UTILS, DATAORAS = SYSDATE
|
||||
WHERE ID_PROGRAM = V_ID_PROGRAM
|
||||
AND STERS = 0;
|
||||
end;
|
||||
|
||||
function selecteaza_serie(V_ID_PROGRAM IN NUMBER) return varchar2 is
|
||||
V_SERIE AUTH_SERII.SERIE%TYPE;
|
||||
V_SERIEC VARCHAR2(256);
|
||||
eroare_de_conversie EXCEPTION;
|
||||
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
|
||||
begin
|
||||
begin
|
||||
SELECT SERIE
|
||||
INTO V_SERIE
|
||||
FROM AUTH_SERII
|
||||
WHERE ID_PROGRAM = V_ID_PROGRAM
|
||||
AND STERS = 0;
|
||||
exception
|
||||
when NO_DATA_FOUND then
|
||||
V_SERIE := NULL;
|
||||
end;
|
||||
|
||||
BEGIN
|
||||
V_SERIEC := TRIM(RAWTOHEX(V_SERIE));
|
||||
EXCEPTION
|
||||
WHEN eroare_de_conversie THEN
|
||||
V_SERIEC := NULL;
|
||||
END;
|
||||
|
||||
return V_SERIEC;
|
||||
end;
|
||||
|
||||
function selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) return number is
|
||||
V_SERIE AUTH_SERII.SERIE%TYPE;
|
||||
V_DATAORA DATE;
|
||||
V_NR_UTILIZATORI NUMBER(4);
|
||||
V_SERIEC VARCHAR2(64);
|
||||
begin
|
||||
begin
|
||||
SELECT SERIE, DATAORA
|
||||
INTO V_SERIE, V_DATAORA
|
||||
FROM AUTH_SERII
|
||||
WHERE ID_PROGRAM = V_ID_PROGRAM
|
||||
AND STERS = 0;
|
||||
|
||||
V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM,
|
||||
V_SERIE,
|
||||
V_DATAORA);
|
||||
|
||||
V_NR_UTILIZATORI := auth_pack.decripteaza_nr_util(V_SERIEC);
|
||||
|
||||
exception
|
||||
when NO_DATA_FOUND then
|
||||
V_NR_UTILIZATORI := 0;
|
||||
end;
|
||||
|
||||
return V_NR_UTILIZATORI;
|
||||
end;
|
||||
|
||||
function selecteaza_data_val(V_ID_PROGRAM IN NUMBER) return date is
|
||||
V_SERIE AUTH_SERII.SERIE%TYPE;
|
||||
V_DATAORA DATE;
|
||||
V_DATA_VAL DATE;
|
||||
V_SERIEC VARCHAR2(64);
|
||||
V_ZI VARCHAR2(2);
|
||||
begin
|
||||
begin
|
||||
|
||||
SELECT SERIE, DATAORA
|
||||
INTO V_SERIE, V_DATAORA
|
||||
FROM AUTH_SERII
|
||||
WHERE ID_PROGRAM = V_ID_PROGRAM
|
||||
AND STERS = 0;
|
||||
|
||||
V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM,
|
||||
V_SERIE,
|
||||
V_DATAORA);
|
||||
V_ZI := LPAD(EXTRACT(DAY FROM V_DATAORA), 2, '0');
|
||||
V_DATA_VAL := auth_pack.decripteaza_data_val(V_SERIEC, V_ZI);
|
||||
|
||||
exception
|
||||
when NO_DATA_FOUND then
|
||||
V_DATA_VAL := NULL;
|
||||
end;
|
||||
|
||||
return V_DATA_VAL;
|
||||
end;
|
||||
|
||||
procedure verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW) is
|
||||
v_seriedec VARCHAR2(256);
|
||||
v_checksum NUMBER(2);
|
||||
v_suma NUMBER(2) := 0;
|
||||
begin
|
||||
v_seriedec := auth_pack.decripteaza_serie(V_ID_PROGRAM,
|
||||
V_SERIE,
|
||||
SYSDATE);
|
||||
|
||||
v_checksum := auth_pack.hextodec(substr(v_seriedec,
|
||||
length(v_seriedec),
|
||||
1));
|
||||
for i in 1 .. length(v_seriedec) - 1 loop
|
||||
v_suma := v_suma + auth_pack.hextodec(substr(v_seriedec, i, 1));
|
||||
end loop;
|
||||
|
||||
if MOD(v_suma + v_checksum, 16) <> 0 then
|
||||
RAISE_APPLICATION_ERROR(-20000, 'Seria introdusa nu este valida!');
|
||||
end if;
|
||||
|
||||
end;
|
||||
|
||||
function decripteaza_serie(V_ID_PROGRAM IN NUMBER,
|
||||
V_SERIE IN RAW,
|
||||
V_DATAORA IN DATE) return varchar2 is
|
||||
v_denumire CONTAFIN_ORACLE.NOM_PROGRAME.DENUMIRE%TYPE;
|
||||
v_id_client NUMBER(4);
|
||||
v_cheie VARCHAR2(16);
|
||||
v_serieval RAW(256);
|
||||
v_seriedec VARCHAR2(32);
|
||||
v_valoare NUMBER(2);
|
||||
eroare_de_conversie EXCEPTION;
|
||||
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
|
||||
begin
|
||||
IF V_SERIE IS NOT NULL THEN
|
||||
SELECT substr(a.denumire, 4, 5)
|
||||
INTO V_DENUMIRE
|
||||
FROM SYN_NOM_PROGRAME A
|
||||
WHERE A.ID_PROGRAM = V_ID_PROGRAM;
|
||||
|
||||
SELECT TO_NUMBER(DETALII) INTO V_ID_CLIENT FROM AUTH_DETALII;
|
||||
|
||||
v_cheie := RPAD(LPAD(v_id_program, 3, '0') ||
|
||||
LPAD(v_id_client, 4, '0') ||
|
||||
RPAD(v_denumire, 5, CHR(4)) ||
|
||||
LPAD(to_char(v_dataora, 'IWYY'), 4, '0'),
|
||||
16,
|
||||
'X');
|
||||
|
||||
dbms_obfuscation_toolkit.DES3Decrypt(input => v_serie,
|
||||
key => utl_raw.cast_to_raw(v_cheie),
|
||||
decrypted_data => v_serieval);
|
||||
|
||||
begin
|
||||
for i in 1 .. length(v_serieval) / 2 loop
|
||||
v_valoare := to_number(substr(v_serieval, 2 * i - 1, 2));
|
||||
if v_valoare > 40 then
|
||||
v_seriedec := v_seriedec || auth_pack.dectohex(v_valoare - 31);
|
||||
else
|
||||
v_seriedec := v_seriedec || (v_valoare - 30);
|
||||
end if;
|
||||
end loop;
|
||||
exception
|
||||
when eroare_de_conversie then
|
||||
RAISE_APPLICATION_ERROR(-20100,
|
||||
'Seria introdusa nu este valida!');
|
||||
end;
|
||||
|
||||
ELSE
|
||||
v_seriedec := NULL;
|
||||
END IF;
|
||||
|
||||
RETURN v_seriedec;
|
||||
end;
|
||||
|
||||
function decripteaza_nr_util(V_SERIEC IN VARCHAR2) return number is
|
||||
begin
|
||||
IF V_SERIEC IS NOT NULL THEN
|
||||
return to_number(substr(v_seriec, 1, 4));
|
||||
ELSE
|
||||
return 0;
|
||||
END IF;
|
||||
end;
|
||||
|
||||
function decripteaza_data_val(V_SERIEC IN VARCHAR2, V_ZI IN VARCHAR2)
|
||||
return date is
|
||||
v_luna varchar2(2);
|
||||
begin
|
||||
IF V_SERIEC IS NOT NULL THEN
|
||||
v_luna := LPAD(auth_pack.hextodec(substr(v_seriec, 5, 1)), 2, '0');
|
||||
return last_day(to_date(v_luna || substr(v_seriec, 6, 2), 'MMYY'));
|
||||
ELSE
|
||||
return null;
|
||||
END IF;
|
||||
end;
|
||||
|
||||
function hextodec(V_HEXA IN VARCHAR2) return number is
|
||||
v_numar NUMBER(2);
|
||||
begin
|
||||
IF ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 48 AND 57 or
|
||||
ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 65 AND 70 THEN
|
||||
CASE UPPER(TRIM(V_HEXA))
|
||||
WHEN 'A' THEN
|
||||
v_numar := 10;
|
||||
WHEN 'B' THEN
|
||||
v_numar := 11;
|
||||
WHEN 'C' THEN
|
||||
v_numar := 12;
|
||||
WHEN 'D' THEN
|
||||
v_numar := 13;
|
||||
WHEN 'E' THEN
|
||||
v_numar := 14;
|
||||
WHEN 'F' THEN
|
||||
v_numar := 15;
|
||||
ELSE
|
||||
v_numar := to_number(V_HEXA);
|
||||
END CASE;
|
||||
ELSE
|
||||
RAISE_APPLICATION_ERROR(-20000, 'Caracterul nu este valid!');
|
||||
END IF;
|
||||
return v_numar;
|
||||
end;
|
||||
|
||||
function dectohex(V_NUMAR IN NUMBER) return varchar2 is
|
||||
v_hexa VARCHAR2(1);
|
||||
begin
|
||||
CASE v_numar
|
||||
WHEN 10 THEN
|
||||
v_hexa := 'A';
|
||||
WHEN 11 THEN
|
||||
v_hexa := 'B';
|
||||
WHEN 12 THEN
|
||||
v_hexa := 'C';
|
||||
WHEN 13 THEN
|
||||
v_hexa := 'D';
|
||||
WHEN 14 THEN
|
||||
v_hexa := 'E';
|
||||
WHEN 15 THEN
|
||||
v_hexa := 'F';
|
||||
ELSE
|
||||
v_hexa := to_char(V_NUMAR);
|
||||
END CASE;
|
||||
return v_hexa;
|
||||
end;
|
||||
|
||||
end AUTH_PACK;
|
||||
/
|
||||
|
||||
-- 5. PROCEDURES
|
||||
PROMPT [6/9] Creating SYS.EXECUTESCRIPTOS (PROCEDURE)...
|
||||
|
||||
CREATE OR REPLACE PROCEDURE "SYS"."EXECUTESCRIPTOS"(p_nume_script in varchar2,
|
||||
p_param in varchar2,
|
||||
p_wait in varchar2,
|
||||
p_result out number) IS
|
||||
v_os_process_id number;
|
||||
begin
|
||||
dbms_scheduler.create_job(job_name => 'EXECUTESCRIPTOS_' ||
|
||||
to_char(sysdate,
|
||||
'yyyymmdd_hh24miss'),
|
||||
job_type => 'EXECUTABLE',
|
||||
job_action => p_nume_script,
|
||||
number_of_arguments => 1,
|
||||
start_date => systimestamp,
|
||||
enabled => FALSE,
|
||||
auto_drop => TRUE);
|
||||
|
||||
dbms_scheduler.set_job_argument_value(job_name => 'EXECUTESCRIPTOS_' ||
|
||||
to_char(sysdate,
|
||||
'yyyymmdd_hh24miss'),
|
||||
argument_position => 1,
|
||||
argument_value => p_param);
|
||||
|
||||
dbms_scheduler.enable('EXECUTESCRIPTOS_' ||
|
||||
to_char(sysdate, 'yyyymmdd_hh24miss'));
|
||||
|
||||
if p_wait = 'Y' then
|
||||
loop
|
||||
select STATE
|
||||
into p_result
|
||||
from dba_scheduler_jobs
|
||||
where JOB_NAME = 'EXECUTESCRIPTOS_' ||
|
||||
to_char(sysdate, 'yyyymmdd_hh24miss');
|
||||
exit when p_result <> 'RUNNING';
|
||||
dbms_lock.sleep(1);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
p_result := 0;
|
||||
|
||||
exception
|
||||
when others then
|
||||
p_result := -1;
|
||||
end EXECUTESCRIPTOS;
|
||||
/
|
||||
|
||||
PROMPT [7/9] Creating SYS.NEWSCHEMA (PROCEDURE)...
|
||||
|
||||
CREATE OR REPLACE PROCEDURE "SYS"."NEWSCHEMA"(p_schema_name in varchar2,
|
||||
p_password in varchar2,
|
||||
p_result out number) IS
|
||||
begin
|
||||
execute immediate 'CREATE USER ' || p_schema_name || ' IDENTIFIED BY ' ||
|
||||
p_password || ' DEFAULT TABLESPACE ROA TEMPORARY TABLESPACE TEMP QUOTA UNLIMITED ON ROA';
|
||||
|
||||
execute immediate 'GRANT CONNECT, RESOURCE TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE SESSION TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE TABLE TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE VIEW TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE SEQUENCE TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE PROCEDURE TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE TRIGGER TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE TYPE TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE SYNONYM TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE DATABASE LINK TO ' || p_schema_name;
|
||||
execute immediate 'GRANT CREATE JOB TO ' || p_schema_name;
|
||||
|
||||
dbms_output.put_line('Schema ' || p_schema_name ||
|
||||
' created successfully!');
|
||||
|
||||
p_result := 0;
|
||||
|
||||
exception
|
||||
when others then
|
||||
dbms_output.put_line('Error creating schema: ' || SQLERRM);
|
||||
p_result := -1;
|
||||
end NEWSCHEMA;
|
||||
/
|
||||
|
||||
PROMPT [8/9] Creating SYS.NEWSCHEMAJOB (PROCEDURE)...
|
||||
|
||||
CREATE OR REPLACE PROCEDURE "SYS"."NEWSCHEMAJOB"(p_schema_name in varchar2,
|
||||
p_password in varchar2) IS
|
||||
v_result number;
|
||||
begin
|
||||
dbms_scheduler.create_job(job_name => 'NEWSCHEMA_' || p_schema_name,
|
||||
job_type => 'STORED_PROCEDURE',
|
||||
job_action => 'SYS.NEWSCHEMA',
|
||||
number_of_arguments => 3,
|
||||
start_date => systimestamp,
|
||||
enabled => FALSE,
|
||||
auto_drop => TRUE);
|
||||
|
||||
dbms_scheduler.set_job_argument_value(job_name => 'NEWSCHEMA_' ||
|
||||
p_schema_name,
|
||||
argument_position => 1,
|
||||
argument_value => p_schema_name);
|
||||
|
||||
dbms_scheduler.set_job_argument_value(job_name => 'NEWSCHEMA_' ||
|
||||
p_schema_name,
|
||||
argument_position => 2,
|
||||
argument_value => p_password);
|
||||
|
||||
dbms_scheduler.set_job_argument_value(job_name => 'NEWSCHEMA_' ||
|
||||
p_schema_name,
|
||||
argument_position => 3,
|
||||
argument_value => v_result);
|
||||
|
||||
dbms_scheduler.enable('NEWSCHEMA_' || p_schema_name);
|
||||
|
||||
end NEWSCHEMAJOB;
|
||||
/
|
||||
|
||||
PROMPT [9/9] Creating SYS.UPDATESQLPLUS (PROCEDURE)...
|
||||
|
||||
CREATE OR REPLACE PROCEDURE "SYS"."UPDATESQLPLUS" IS
|
||||
v_result number;
|
||||
begin
|
||||
executescriptos('D:\ROMFAST\UPDATE\UPDATE_SQLPLUS.BAT', '', 'N', v_result);
|
||||
end UPDATESQLPLUS;
|
||||
/
|
||||
|
||||
PROMPT
|
||||
PROMPT ========================================
|
||||
PROMPT Import Complet Obiecte SYS!
|
||||
PROMPT ========================================
|
||||
PROMPT
|
||||
PROMPT Obiecte create:
|
||||
PROMPT [1] SYS.AUTH_DETALII (TABLE)
|
||||
PROMPT [2] SYS.AUTH_SERII (TABLE)
|
||||
PROMPT [3] SYS.VAUTH_SERII (VIEW)
|
||||
PROMPT [4] SYS.AUTH_PACK (PACKAGE SPEC)
|
||||
PROMPT [5] SYS.AUTH_PACK (PACKAGE BODY)
|
||||
PROMPT [6] SYS.EXECUTESCRIPTOS (PROCEDURE)
|
||||
PROMPT [7] SYS.NEWSCHEMA (PROCEDURE)
|
||||
PROMPT [8] SYS.NEWSCHEMAJOB (PROCEDURE)
|
||||
PROMPT [9] SYS.UPDATESQLPLUS (PROCEDURE)
|
||||
PROMPT
|
||||
PROMPT Verificare obiecte:
|
||||
PROMPT
|
||||
|
||||
SELECT object_name, object_type, status
|
||||
FROM dba_objects
|
||||
WHERE owner='SYS'
|
||||
AND object_name IN ('AUTH_PACK','AUTH_DETALII','AUTH_SERII','VAUTH_SERII',
|
||||
'EXECUTESCRIPTOS','NEWSCHEMA','NEWSCHEMAJOB','UPDATESQLPLUS')
|
||||
ORDER BY object_type, object_name;
|
||||
|
||||
PROMPT
|
||||
EXIT;
|
||||
8990
proxmox/lxc108-oracle/sql/roa-romconstruct/PACK_CONTAFIN.pck
Normal file
8990
proxmox/lxc108-oracle/sql/roa-romconstruct/PACK_CONTAFIN.pck
Normal file
File diff suppressed because it is too large
Load Diff
73
proxmox/lxc108-oracle/sql/roa/INSTRUCTIUNI_ORACLE10G.txt
Normal file
73
proxmox/lxc108-oracle/sql/roa/INSTRUCTIUNI_ORACLE10G.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
║ INSTRUCȚIUNI INSTALARE - Oracle 10.2.0.5 ║
|
||||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
📌 IMPORTANT: Dacă aveți Oracle 10.2.0.5 și primiți eroarea:
|
||||
|
||||
Error: PLS-00436: restrictie de implementare:
|
||||
nu se pot referi campurile din tabelul de inregistrari BULK In-BIND
|
||||
|
||||
Trebuie să folosiți versiunea specială pentru Oracle 10g.
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
🔧 PAȘI DE INSTALARE:
|
||||
|
||||
1. Verificați versiunea Oracle:
|
||||
|
||||
SELECT * FROM v$version;
|
||||
|
||||
→ Dacă vedeți "10.2.0.5" sau mai veche: continuați cu pasul 2
|
||||
→ Dacă vedeți "11g" sau mai nouă: folosiți scrie_jc_2007.sql normal
|
||||
|
||||
2. Pentru Oracle 10g, instalați versiunea specială:
|
||||
|
||||
@scrie_jc_2007_oracle10g.sql
|
||||
|
||||
3. Testați că funcționează:
|
||||
|
||||
-- Rulați procedura
|
||||
BEGIN
|
||||
pack_contafin.SCRIE_JC_2007(2025, 10, 0);
|
||||
END;
|
||||
/
|
||||
|
||||
→ Dacă nu primește erori PLS-00436 = SUCCESS! ✓
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
📊 PERFORMANȚĂ COMPARATIVĂ:
|
||||
|
||||
Versiune | Timp (10,000 rows) | Compatible cu
|
||||
───────────────────────────┼───────────────────┼──────────────────
|
||||
MERGE original (vechi) | 60-120 secunde | Toate versiunile
|
||||
FORALL (standard) | 15-30 ms | Oracle 11g+
|
||||
FOR LOOP (Oracle 10g) | 20-50 ms | Oracle 8i → 23c ✓
|
||||
|
||||
→ Versiunea Oracle 10g este de ~1200-6000x MAI RAPIDĂ decât MERGE-ul vechi!
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
❓ ÎNTREBĂRI FRECVENTE:
|
||||
|
||||
Q: De ce am nevoie de o versiune separată?
|
||||
A: Oracle 10g are o limitare tehnică (PLS-00436) care nu permite FORALL
|
||||
cu colecții de tip %ROWTYPE. Versiunea Oracle10g folosește FOR LOOP normal.
|
||||
|
||||
Q: Este la fel de rapidă?
|
||||
A: Da, aproape! Diferența e de ~5-20ms pentru 10k rows. Ambele sunt MULT
|
||||
mai rapide decât MERGE-ul vechi (60-120 secunde).
|
||||
|
||||
Q: Ce se întâmplă dacă fac upgrade la Oracle 11g?
|
||||
A: Puteți reveni la scrie_jc_2007.sql (versiunea FORALL) pentru performanță
|
||||
cu ~10% mai bună.
|
||||
|
||||
Q: Pot folosi scrie_jc_2007_oracle10g.sql pe Oracle 11g+?
|
||||
A: DA! Funcționează perfect pe toate versiunile (8i → 23c). Singura
|
||||
diferență e performanța ușor mai mică (~5-20ms).
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
📞 SUPORT: Dacă întâmpinați probleme, contactați echipa de suport.
|
||||
|
||||
Data: 2025-10-06
|
||||
88
proxmox/lxc108-oracle/sql/roa/README_ORACLE10G.md
Normal file
88
proxmox/lxc108-oracle/sql/roa/README_ORACLE10G.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Oracle 10g Compatibility
|
||||
|
||||
**Director:** `proxmox/lxc108-oracle/sql/roa/`
|
||||
|
||||
## Două versiuni disponibile pentru SCRIE_JC_2007
|
||||
|
||||
### 📄 Fișiere:
|
||||
|
||||
1. **`scrie_jc_2007.sql`** - Versiunea PRINCIPALĂ (FORALL)
|
||||
- Pentru Oracle 11g, 12c, 18c, 19c, 21c, 23c
|
||||
- Folosește `FORALL` pentru performanță maximă
|
||||
- Performanță: ~15-30ms pentru <10k rows
|
||||
|
||||
2. **`scrie_jc_2007_oracle10g.sql`** - Versiunea pentru Oracle 10g
|
||||
- Pentru Oracle 10.2.0.5 (și versiuni mai vechi)
|
||||
- Folosește `FOR LOOP` pentru compatibilitate
|
||||
- Performanță: ~20-50ms pentru <10k rows
|
||||
- Rezolvă eroarea PLS-00436
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Când să folosești fiecare versiune:
|
||||
|
||||
| Versiune Oracle | Fișier de folosit | Performanță |
|
||||
|----------------|-------------------|-------------|
|
||||
| **8i - 10g** | `scrie_jc_2007_oracle10g.sql` | Bună (20-50ms) |
|
||||
| **11g - 23c** | `scrie_jc_2007.sql` | **Excelentă** (15-30ms) |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Eroarea pe Oracle 10g (fără fix):
|
||||
|
||||
```
|
||||
Error: PLS-00436: restrictie de implementare: nu se pot referi campurile din tabelul de inregistrari BULK In-BIND
|
||||
Line: 1501
|
||||
Text: FORALL i IN 1..S.COUNT
|
||||
```
|
||||
|
||||
**Cauza**: Oracle 10g nu permite `S(i).field` în FORALL când `S` este `TYPE TABLE OF cursor%ROWTYPE`
|
||||
|
||||
**Soluție**: Folosește `scrie_jc_2007_oracle10g.sql` care înlocuiește FORALL cu FOR LOOP
|
||||
|
||||
---
|
||||
|
||||
## 📊 Diferențe tehnice:
|
||||
|
||||
### Versiunea FORALL (scrie_jc_2007.sql):
|
||||
```sql
|
||||
FORALL i IN 1..S.COUNT
|
||||
UPDATE JC2007 J SET ... WHERE ...;
|
||||
|
||||
FOR i IN 1..S.COUNT LOOP
|
||||
IF SQL%BULK_ROWCOUNT(i) = 0 THEN ...
|
||||
```
|
||||
|
||||
### Versiunea FOR LOOP (scrie_jc_2007_oracle10g.sql):
|
||||
```sql
|
||||
FOR i IN 1..S.COUNT LOOP
|
||||
UPDATE JC2007 J SET ... WHERE ...;
|
||||
IF SQL%ROWCOUNT = 0 THEN ...
|
||||
END LOOP;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Instalare pentru Oracle 10g:
|
||||
|
||||
```sql
|
||||
-- 1. Backup versiunea curentă (opțional)
|
||||
@scrie_jc_2007.sql
|
||||
|
||||
-- 2. Instalează versiunea pentru Oracle 10g
|
||||
@scrie_jc_2007_oracle10g.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Note importante:
|
||||
|
||||
- Ambele versiuni sunt **mult mai rapide** decât MERGE-ul original (60-120s)
|
||||
- Ambele versiuni au **aceeași logică de business**
|
||||
- Singura diferență: FORALL vs FOR LOOP
|
||||
- Dacă faci upgrade la Oracle 11g+, poți reveni la versiunea FORALL
|
||||
|
||||
---
|
||||
|
||||
**Creat**: 2025-10-06
|
||||
**Autor**: Optimizare Oracle compatibility
|
||||
2071
proxmox/lxc108-oracle/sql/roa/scrie_jc_2007.sql
Normal file
2071
proxmox/lxc108-oracle/sql/roa/scrie_jc_2007.sql
Normal file
File diff suppressed because it is too large
Load Diff
2072
proxmox/lxc108-oracle/sql/roa/scrie_jc_2007_oracle10g.sql
Normal file
2072
proxmox/lxc108-oracle/sql/roa/scrie_jc_2007_oracle10g.sql
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
841
proxmox/lxc108-oracle/sql/roa/scrie_jv_2007.sql
Normal file
841
proxmox/lxc108-oracle/sql/roa/scrie_jv_2007.sql
Normal file
@@ -0,0 +1,841 @@
|
||||
procedure SCRIE_JV_2007(tnAn JV2007.AN%TYPE,
|
||||
tnLuna JV2007.LUNA%TYPE,
|
||||
tnScrie number) IS
|
||||
|
||||
lcSql VARCHAR2(32767);
|
||||
lcContTvaDeductibil ACT.SCD%TYPE := '4426';
|
||||
lcContTvaColectat ACT.SCD%TYPE := '4427';
|
||||
lcContTvaNeexigibil ACT.SCD%TYPE := '4428';
|
||||
lcContDebitRegularizare VARCHAR2(100) := '4111,461,4511,4118';
|
||||
lcContCreditRegularizare VARCHAR2(100) := '418';
|
||||
lnIdMinJtvaColoana JTVA_COLOANE.ID_JTVA_COLOANA%TYPE := 1;
|
||||
lnIdMaxJtvaColoana JTVA_COLOANE.ID_JTVA_COLOANA%TYPE := 100;
|
||||
lcTabelSursa VARCHAR2(100);
|
||||
lcCondSucursala VARCHAR2(1000);
|
||||
begin
|
||||
-- tnScrie: 0 - scriere; 1 - refacere; 2 - stergere
|
||||
-- 0,2 - selectie din act_temp
|
||||
-- 1 - selectie din act
|
||||
|
||||
if pack_contafin.get_id_sucursala() is not null then
|
||||
lcCondSucursala := ' AND ALIAS.ID_SUCURSALA = ' ||
|
||||
pack_contafin.GET_ID_SUCURSALA();
|
||||
end if;
|
||||
|
||||
if tnScrie in (pack_contafin.nScriere, pack_contafin.nStergere) then
|
||||
lcTabelSursa := 'act_temp'; -- scriere, stergere
|
||||
else
|
||||
lcTabelSursa := 'act'; -- refacere
|
||||
end if;
|
||||
|
||||
pack_contafin.completeaza_jv_2007(tnAn,
|
||||
tnLuna,
|
||||
lcTabelSursa,
|
||||
lcCondSucursala);
|
||||
|
||||
MERGE INTO JV2007 J
|
||||
USING (SELECT AN,
|
||||
LUNA,
|
||||
ID_FDOC,
|
||||
ID_FACT,
|
||||
NRACT,
|
||||
SERIE_ACT,
|
||||
DATAACT,
|
||||
DATAIREG,
|
||||
ID_PART,
|
||||
COD,
|
||||
(CASE
|
||||
WHEN NOTA_TVA_EX = 1 THEN
|
||||
0
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
TOTCTVA -
|
||||
DECODE(RO24NB, 0, 0, RO24B) -
|
||||
DECODE(RO20NB, 0, 0, RO20B) -
|
||||
DECODE(RO21NB, 0, 0, RO21B) -
|
||||
DECODE(RO11NB, 0, 0, RO11B) -
|
||||
DECODE(RO19NB, 0, 0, RO19B) -
|
||||
DECODE(RO9NB, 0, 0, RO9B) -
|
||||
DECODE(RO5NB, 0, 0, RO5B) -
|
||||
DECODE(RO24NT, 0, 0, RO24T) -
|
||||
DECODE(RO20NT, 0, 0, RO20T) -
|
||||
DECODE(RO21NT, 0, 0, RO21T) -
|
||||
DECODE(RO11NT, 0, 0, RO11T) -
|
||||
DECODE(RO19NT, 0, 0, RO19T) -
|
||||
DECODE(RO9NT, 0, 0, RO9T) -
|
||||
DECODE(RO5NT, 0, 0, RO5T) -
|
||||
DECODE(RO24NTR, 0, RO24TR, RO24NTR) -
|
||||
DECODE(RO20NTR, 0, RO20TR, RO20NTR) -
|
||||
DECODE(RO21NTR, 0, RO21TR, RO21NTR) -
|
||||
DECODE(RO11NTR, 0, RO11TR, RO11NTR) -
|
||||
DECODE(RO19NTR, 0, RO19TR, RO19NTR) -
|
||||
DECODE(RO9NTR, 0, RO9TR, RO9NTR) -
|
||||
DECODE(RO5NTR, 0, RO5TR, RO5NTR)
|
||||
ELSE
|
||||
TOTCTVA -
|
||||
DECODE(RO24NB, 0, 0, RO24B) -
|
||||
DECODE(RO20NB, 0, 0, RO20B) -
|
||||
DECODE(RO21NB, 0, 0, RO21B) -
|
||||
DECODE(RO11NB, 0, 0, RO11B) -
|
||||
DECODE(RO19NB, 0, 0, RO19B) -
|
||||
DECODE(RO9NB, 0, 0, RO9B) -
|
||||
DECODE(RO5NB, 0, 0, RO5B) -
|
||||
DECODE(RO24NT, 0, 0, RO24T) -
|
||||
DECODE(RO20NT, 0, 0, RO20T) -
|
||||
DECODE(RO21NT, 0, 0, RO21T) -
|
||||
DECODE(RO11NT, 0, 0, RO11T) -
|
||||
DECODE(RO19NT, 0, 0, RO19T) -
|
||||
DECODE(RO9NT, 0, 0, RO9T) -
|
||||
DECODE(RO5NT, 0, 0, RO5T)
|
||||
END) AS TOTCTVA,
|
||||
(CASE
|
||||
WHEN NOTA_TVA_EX = 1 THEN
|
||||
0
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO24NB, 0, RO24B, RO24NB) +
|
||||
DECODE(RO20NB, 0, RO20B, RO20NB) +
|
||||
DECODE(RO21NB, 0, RO21B, RO21NB) +
|
||||
DECODE(RO11NB, 0, RO11B, RO11NB) +
|
||||
DECODE(RO19NB, 0, RO19B, RO19NB) +
|
||||
DECODE(RO9NB, 0, RO9B, RO9NB) +
|
||||
DECODE(RO5NB, 0, RO5B, RO5NB) -
|
||||
DECODE(RO24NB, 0, RO24TR, RO24NTR) -
|
||||
DECODE(RO20NB, 0, RO20TR, RO20NTR) -
|
||||
DECODE(RO21NB, 0, RO21TR, RO21NTR) -
|
||||
DECODE(RO11NB, 0, RO11TR, RO11NTR) -
|
||||
DECODE(RO19NB, 0, RO19TR, RO19NTR) -
|
||||
DECODE(RO9NB, 0, RO9TR, RO9NTR) -
|
||||
DECODE(RO5NB, 0, RO5TR, RO5NTR)
|
||||
ELSE
|
||||
DECODE(RO24NB, 0, RO24B, RO24NB) +
|
||||
DECODE(RO20NB, 0, RO20B, RO20NB) +
|
||||
DECODE(RO21NB, 0, RO21B, RO21NB) +
|
||||
DECODE(RO11NB, 0, RO11B, RO11NB) +
|
||||
DECODE(RO19NB, 0, RO19B, RO19NB) +
|
||||
DECODE(RO9NB, 0, RO9B, RO9NB) +
|
||||
DECODE(RO5NB, 0, RO5B, RO5NB)
|
||||
END) AS TOTFTVATAX,
|
||||
DECODE(NOTA_TVA_EX,
|
||||
1,
|
||||
0,
|
||||
DECODE(RO24NT, 0, RO24T, RO24NT) +
|
||||
DECODE(RO20NT, 0, RO20T, RO20NT) +
|
||||
DECODE(RO21NT, 0, RO21T, RO21NT) +
|
||||
DECODE(RO11NT, 0, RO11T, RO11NT) +
|
||||
DECODE(RO19NT, 0, RO19T, RO19NT) +
|
||||
DECODE(RO9NT, 0, RO9T, RO9NT) +
|
||||
DECODE(RO5NT, 0, RO5T, RO5NT)) AS TOTTVATAX,
|
||||
ROTI + CESCDD1 + CESCDD2 + CEOPTR + CESVDD + CESVFDD +
|
||||
CESVFS + WRSCDD + WRSCDDAB + WRSCDDCD + FODD + FOFDD +
|
||||
WRSCFDD + WRN AS TOTNETAX,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO24B,
|
||||
0,
|
||||
DECODE(RO24T, 0, 0, ROUND(RO24T / 0.24, 2)),
|
||||
RO24B - RO24TR)
|
||||
ELSE
|
||||
DECODE(RO24B,
|
||||
0,
|
||||
DECODE(RO24T, 0, 0, ROUND(RO24T / 0.24, 2)),
|
||||
RO24B)
|
||||
END) AS RO24B,
|
||||
RO24T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO20B,
|
||||
0,
|
||||
DECODE(RO20T, 0, 0, ROUND(RO20T / 0.20, 2)),
|
||||
RO20B - RO20TR)
|
||||
ELSE
|
||||
DECODE(RO20B,
|
||||
0,
|
||||
DECODE(RO20T, 0, 0, ROUND(RO20T / 0.20, 2)),
|
||||
RO20B)
|
||||
END) AS RO20B,
|
||||
RO20T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO21B,
|
||||
0,
|
||||
DECODE(RO21T, 0, 0, ROUND(RO21T / 0.21, 2)),
|
||||
RO21B - RORTD21)
|
||||
ELSE
|
||||
DECODE(RO21B,
|
||||
0,
|
||||
DECODE(RO21T, 0, 0, ROUND(RO21T / 0.21, 2)),
|
||||
RO21B)
|
||||
END) AS RO21B,
|
||||
RO21T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO11B,
|
||||
0,
|
||||
DECODE(RO11T, 0, 0, ROUND(RO11T / 0.11, 2)),
|
||||
RO11B - RORTD11)
|
||||
ELSE
|
||||
DECODE(RO11B,
|
||||
0,
|
||||
DECODE(RO11T, 0, 0, ROUND(RO11T / 0.11, 2)),
|
||||
RO11B)
|
||||
END) AS RO11B,
|
||||
RO11T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO19B,
|
||||
0,
|
||||
DECODE(RO19T, 0, 0, ROUND(RO19T / 0.19, 2)),
|
||||
RO19B - RO19TR)
|
||||
ELSE
|
||||
DECODE(RO19B,
|
||||
0,
|
||||
DECODE(RO19T, 0, 0, ROUND(RO19T / 0.19, 2)),
|
||||
RO19B)
|
||||
END) AS RO19B,
|
||||
RO19T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO9B,
|
||||
0,
|
||||
DECODE(RO9T, 0, 0, ROUND(RO9T / 0.09, 2)),
|
||||
RO9B - RO9TR)
|
||||
ELSE
|
||||
DECODE(RO9B,
|
||||
0,
|
||||
DECODE(RO9T, 0, 0, ROUND(RO9T / 0.09, 2)),
|
||||
RO9B)
|
||||
END) AS RO9B,
|
||||
RO9T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
DECODE(RO5B,
|
||||
0,
|
||||
DECODE(RO5T, 0, 0, ROUND(RO5T / 0.05, 2)),
|
||||
RO5B - RO5TR)
|
||||
ELSE
|
||||
DECODE(RO5B,
|
||||
0,
|
||||
DECODE(RO5T, 0, 0, ROUND(RO5T / 0.05, 2)),
|
||||
RO5B)
|
||||
END) AS RO5B,
|
||||
RO5T,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO24NB - RO24NTR
|
||||
ELSE
|
||||
RO24NB
|
||||
END) AS RO24NB,
|
||||
RO24NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO20NB - RO20NTR
|
||||
ELSE
|
||||
RO20NB
|
||||
END) AS RO20NB,
|
||||
RO20NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO21NB - RO21NTR
|
||||
ELSE
|
||||
RO21NB
|
||||
END) AS RO21NB,
|
||||
RO21NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO11NB - RO11NTR
|
||||
ELSE
|
||||
RO11NB
|
||||
END) AS RO11NB,
|
||||
RO11NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO19NB - RO19NTR
|
||||
ELSE
|
||||
RO19NB
|
||||
END) AS RO19NB,
|
||||
RO19NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO9NB - RO9NTR
|
||||
ELSE
|
||||
RO9NB
|
||||
END) AS RO9NB,
|
||||
RO9NT,
|
||||
(CASE
|
||||
WHEN REGULARIZARE > 0 THEN
|
||||
RO5NB - RO5NTR
|
||||
ELSE
|
||||
RO5NB
|
||||
END) AS RO5NB,
|
||||
RO5NT,
|
||||
ROTI,
|
||||
CESCDD1,
|
||||
CESCDD2,
|
||||
CEOPTR,
|
||||
CESVDD,
|
||||
CESVFDD,
|
||||
CESVFS,
|
||||
WRSCDD,
|
||||
WRSCDDAB,
|
||||
WRSCDDCD,
|
||||
FODD,
|
||||
FOFDD,
|
||||
WRSCFDD,
|
||||
WRN,
|
||||
RORTC24,
|
||||
RORTC20,
|
||||
RORTC21,
|
||||
RORTC11,
|
||||
RORTC19,
|
||||
RORTC9,
|
||||
RORTC5,
|
||||
ID_SUCURSALA
|
||||
FROM (SELECT JV.AN,
|
||||
JV.LUNA,
|
||||
MAX(JV.ID_FDOC) AS ID_FDOC,
|
||||
JV.ID_FACT,
|
||||
JV.NRACT,
|
||||
JV.SERIE_ACT,
|
||||
JV.DATAACT,
|
||||
JV.DATAIREG,
|
||||
MAX(JV.ID_PART) AS ID_PART,
|
||||
JV.ID_SUCURSALA,
|
||||
MIN(JV.COD) AS COD,
|
||||
MIN(JV.NOTA_TVA_EX) AS NOTA_TVA_EX,
|
||||
sum(CASE
|
||||
WHEN NVL(JV.ID_JTVA_COLOANA, 0) BETWEEN 1 AND 100 THEN
|
||||
JV.suma
|
||||
ELSE
|
||||
0
|
||||
END) TOTCTVA,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 15, JV.suma, 0)) RO24B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 16, JV.suma, 0)) RO24T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 27, JV.suma, 0)) RO20B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 28, JV.suma, 0)) RO20T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 35, JV.suma, 0)) RO21B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 36, JV.suma, 0)) RO21T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1, JV.suma, 0)) RO19B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 2, JV.suma, 0)) RO19T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 3, JV.suma, 0)) RO9B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 4, JV.suma, 0)) RO9T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 13, JV.suma, 0)) RO5B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 14, JV.suma, 0)) RO5T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 39, JV.suma, 0)) RO11B,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 40, JV.suma, 0)) RO11T,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 5, JV.suma, 0)) ROTI,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 6, JV.suma, 0)) CESCDD1,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 7, JV.suma, 0)) CESCDD2,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 17, JV.suma, 0)) CEOPTR,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 18, JV.suma, 0)) CESVDD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 19, JV.suma, 0)) CESVFDD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 20, JV.suma, 0)) CESVFS,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 8, JV.suma, 0)) WRSCDD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 33, JV.suma, 0)) WRSCDDAB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 34, JV.suma, 0)) WRSCDDCD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 9, JV.suma, 0)) FODD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 10, JV.suma, 0)) FOFDD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 11, JV.suma, 0)) WRSCFDD,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 12, JV.suma, 0)) WRN,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1006, JV.suma, 0)) RORTC24,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1007, JV.suma, 0)) RORTC20,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1016, JV.suma, 0)) RORTC21,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1017, JV.suma, 0)) RORTC11,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1008, JV.suma, 0)) RORTC19,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1009, JV.suma, 0)) RORTC9,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 1010, JV.suma, 0)) RORTC5,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 21, JV.suma, 0)) RO24NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 22, JV.suma, 0)) RO24NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 29, JV.suma, 0)) RO20NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 30, JV.suma, 0)) RO20NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 37, JV.suma, 0)) RO21NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 38, JV.suma, 0)) RO21NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 41, JV.suma, 0)) RO11NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 42, JV.suma, 0)) RO11NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 31, JV.suma, 0)) RO19NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 32, JV.suma, 0)) RO19NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 23, JV.suma, 0)) RO9NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 24, JV.suma, 0)) RO9NT,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 25, JV.suma, 0)) RO5NB,
|
||||
sum(DECODE(JV.ID_JTVA_COLOANA, 26, JV.suma, 0)) RO5NT,
|
||||
SUM(JV.REGULARIZARE) AS REGULARIZARE,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 16 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO24TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 28 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO20TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 36 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO21TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 40 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO11TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 2 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO19TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 4 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO9TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 14 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO5TR,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 1016 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RORTD21,
|
||||
SUM(CASE
|
||||
WHEN JV.ID_JTVA_COLOANA = 1017 AND JV.SCD = '4428' THEN
|
||||
JV.SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RORTD11,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 22 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO24NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 30 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO20NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 32 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO19NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 24 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO9NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 26 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO5NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 38 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO21NTR,
|
||||
SUM(CASE
|
||||
WHEN ID_JTVA_COLOANA = 42 AND SCD = '4428' THEN
|
||||
SUMA
|
||||
ELSE
|
||||
0
|
||||
END) RO11NTR
|
||||
FROM (SELECT A.AN,
|
||||
A.LUNA,
|
||||
(CASE
|
||||
WHEN A.NRACT <> D.NRACT or
|
||||
A.DATAACT <> D.DATAACT THEN
|
||||
1
|
||||
ELSE
|
||||
0
|
||||
END) AS NOTA_TVA_EX,
|
||||
(CASE
|
||||
WHEN A.NRACT <> D.NRACT or
|
||||
A.DATAACT <> D.DATAACT OR
|
||||
A.ID_SET <> D.ID_SET OR
|
||||
NVL(A.SERIE_ACT, 'X') <>
|
||||
NVL(D.SERIE_ACT, 'X') THEN
|
||||
NULL
|
||||
ELSE
|
||||
A.ID_FDOC
|
||||
END) AS ID_FDOC,
|
||||
A.ID_FACT,
|
||||
(CASE
|
||||
WHEN A.NRACT <> D.NRACT THEN
|
||||
D.NRACT
|
||||
ELSE
|
||||
A.NRACT
|
||||
END) AS NRACT,
|
||||
D.SERIE_ACT,
|
||||
(CASE
|
||||
WHEN A.NRACT <> D.NRACT or
|
||||
A.DATAACT <> D.DATAACT THEN
|
||||
TRUNC(D.DATAACT)
|
||||
ELSE
|
||||
TRUNC(A.DATAACT)
|
||||
END) AS DATAACT,
|
||||
(CASE
|
||||
WHEN A.NRACT <> D.NRACT or
|
||||
NVL(A.DATAIREG, A.DATAACT) <>
|
||||
NVL(D.DATAIREG, D.DATAACT) THEN
|
||||
TRUNC(NVL(D.DATAIREG, D.DATAACT))
|
||||
ELSE
|
||||
TRUNC(NVL(A.DATAIREG, A.DATAACT))
|
||||
END) AS DATAIREG,
|
||||
A.COD,
|
||||
A.SCD,
|
||||
A.SCC,
|
||||
-- 4426 = 4427 sau 4428 = 4427 nu au parteneri
|
||||
MAX(DECODE(E.EXCEPTIE,
|
||||
1,
|
||||
A.ID_PARTC,
|
||||
(CASE
|
||||
-- ESTE POSIBIL SA FIE DOAR 5121 = 419 FARA 4111 = 4427, TREBUIE PARTENERUL 419
|
||||
WHEN A.SCC = '419' THEN
|
||||
A.ID_PARTC
|
||||
WHEN A.SCD IN (lcContTvaDeductibil,
|
||||
lcContTvaNeexigibil) OR
|
||||
SUBSTR(A.SCD, 1, 1) = '5' THEN
|
||||
-9999999999
|
||||
ELSE
|
||||
A.ID_PARTD
|
||||
END))) OVER(PARTITION BY A.AN, A.LUNA, A.ID_FDOC, A.NRACT, A.DATAACT, A.COD) AS ID_PART,
|
||||
-- INVERSARE SUME LA EXCEPTII
|
||||
DECODE(A.ID_SET, 10616, -1, 1) *
|
||||
DECODE(E.EXCEPTIE, 1, -A.SUMA, A.SUMA) AS SUMA,
|
||||
-- MARCA REGULARIZARE FACTURI NEINTOCMITE
|
||||
(CASE
|
||||
WHEN INSTR(lcContDebitRegularizare, A.scd) > 0 and
|
||||
INSTR(lcContCreditRegularizare, A.scc) > 0 THEN
|
||||
1
|
||||
ELSE
|
||||
0
|
||||
END) AS REGULARIZARE,
|
||||
A.ID_JTVA_COLOANA,
|
||||
A.ID_SUCURSALA
|
||||
FROM (
|
||||
SELECT AN,
|
||||
LUNA,
|
||||
ID_FDOC,
|
||||
ID_FACT,
|
||||
NRACT,
|
||||
SERIE_ACT,
|
||||
DATAACT,
|
||||
DATAIREG,
|
||||
COD,
|
||||
SCD,
|
||||
SCC,
|
||||
ID_PARTC,
|
||||
ID_PARTD,
|
||||
ID_SET,
|
||||
SUMA,
|
||||
ID_JTVA_COLOANA,
|
||||
ID_SUCURSALA,
|
||||
STERS
|
||||
FROM ACT_TEMP
|
||||
WHERE lcTabelSursa = 'act_temp'
|
||||
AND AN = tnAn
|
||||
AND LUNA = tnLuna
|
||||
AND STERS = 0
|
||||
AND (ID_JTVA_COLOANA BETWEEN lnIdMinJtvaColoana AND lnIdMaxJtvaColoana
|
||||
OR ID_JTVA_COLOANA BETWEEN 1006 AND 1010)
|
||||
AND ID_SET <> 10621
|
||||
UNION ALL
|
||||
SELECT AN,
|
||||
LUNA,
|
||||
ID_FDOC,
|
||||
ID_FACT,
|
||||
NRACT,
|
||||
SERIE_ACT,
|
||||
DATAACT,
|
||||
DATAIREG,
|
||||
COD,
|
||||
SCD,
|
||||
SCC,
|
||||
ID_PARTC,
|
||||
ID_PARTD,
|
||||
ID_SET,
|
||||
SUMA,
|
||||
ID_JTVA_COLOANA,
|
||||
ID_SUCURSALA,
|
||||
STERS
|
||||
FROM ACT
|
||||
WHERE lcTabelSursa = 'act'
|
||||
AND AN = tnAn
|
||||
AND LUNA = tnLuna
|
||||
AND STERS = 0
|
||||
AND (ID_JTVA_COLOANA BETWEEN lnIdMinJtvaColoana AND lnIdMaxJtvaColoana
|
||||
OR ID_JTVA_COLOANA BETWEEN 1006 AND 1010)
|
||||
AND ID_SET <> 10621
|
||||
) A
|
||||
LEFT JOIN (SELECT DISTINCT 1 AS EXCEPTIE,
|
||||
DECODE(DEBIT,
|
||||
1,
|
||||
CONT_C,
|
||||
CONT) AS SCD,
|
||||
DECODE(DEBIT,
|
||||
1,
|
||||
CONT,
|
||||
CONT_C) AS SCC
|
||||
FROM EXCEPTII_IREG
|
||||
WHERE INVERS = 1
|
||||
AND IN_TVA = 1) E
|
||||
ON A.SCD = E.SCD
|
||||
AND A.SCC = E.SCC
|
||||
LEFT JOIN DOCUMENTE D
|
||||
ON A.ID_FACT = D.ID_DOC
|
||||
WHERE A.AN = tnAn
|
||||
and A.LUNA = tnLuna
|
||||
and A.STERS = 0
|
||||
AND (A.ID_JTVA_COLOANA between lnIdMinJtvaColoana and
|
||||
lnIdMaxJtvaColoana OR
|
||||
A.ID_JTVA_COLOANA BETWEEN 1006 AND 1010)
|
||||
-- IN JURNALUL DE VANZARI NU INTRA FACTURILE NEINTOCMITE + INCASARILE
|
||||
-- SAU COMPENSARI 419 CU EXPLICATIE TVA
|
||||
AND A.ID_SET <> 10621
|
||||
AND NOT (TRIM(NVL(A.SCD, 'X')) = '418' OR
|
||||
(TRIM(NVL(A.SCD, 'X')) not in
|
||||
('4111', '461', '4511', '4118') AND
|
||||
TRIM(NVL(A.SCC, 'X')) = '418'))
|
||||
AND nvl2(pack_contafin.GET_ID_SUCURSALA(),
|
||||
A.ID_SUCURSALA,
|
||||
0) =
|
||||
nvl(pack_contafin.GET_ID_SUCURSALA(), 0)) JV
|
||||
GROUP BY JV.AN,
|
||||
JV.LUNA,
|
||||
JV.ID_FACT,
|
||||
JV.NRACT,
|
||||
JV.SERIE_ACT,
|
||||
JV.DATAACT,
|
||||
JV.DATAIREG,
|
||||
JV.ID_SUCURSALA)) S
|
||||
ON (J.AN = S.AN AND J.LUNA = S.LUNA AND J.ID_FACT = S.ID_FACT AND NVL(J.ID_SUCURSALA, -99) = NVL(S.ID_SUCURSALA, -99))
|
||||
WHEN MATCHED THEN
|
||||
UPDATE
|
||||
SET J.TOTCTVA = J.TOTCTVA + (CASE
|
||||
WHEN EXTRACT(MONTH FROM J.DATAACT) = J.LUNA AND
|
||||
EXTRACT(YEAR FROM J.DATAACT) = J.AN THEN
|
||||
S.TOTCTVA
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.TOTFTVATAX = J.TOTFTVATAX + (CASE
|
||||
WHEN EXTRACT(MONTH FROM J.DATAACT) = J.LUNA AND
|
||||
EXTRACT(YEAR FROM J.DATAACT) = J.AN THEN
|
||||
S.TOTFTVATAX
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.TOTTVATAX = J.TOTTVATAX + (CASE
|
||||
WHEN EXTRACT(MONTH FROM J.DATAACT) = J.LUNA AND
|
||||
EXTRACT(YEAR FROM J.DATAACT) = J.AN THEN
|
||||
S.TOTTVATAX
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.TOTNETAX = J.TOTNETAX + (CASE
|
||||
WHEN EXTRACT(MONTH FROM J.DATAACT) = J.LUNA AND
|
||||
EXTRACT(YEAR FROM J.DATAACT) = J.AN THEN
|
||||
S.TOTNETAX
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO24B = J.RO24B + NVL(S.RO24B, 0) + (CASE
|
||||
WHEN NVL(S.RO24B, 0) <> 0 AND NVL(J.RO24NT, 0) <> 0 AND
|
||||
NVL(J.RO24NT, 0) - (NVL(J.RO24T, 0) + NVL(S.RO24T, 0)) = 0 THEN
|
||||
NVL(J.RO24NB, 0) - (NVL(J.RO24B, 0) + NVL(S.RO24B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO24T = J.RO24T + S.RO24T,
|
||||
J.RO20B = J.RO20B + NVL(S.RO20B, 0) + (CASE
|
||||
WHEN NVL(S.RO20B, 0) <> 0 AND NVL(J.RO20NT, 0) <> 0 AND
|
||||
NVL(J.RO20NT, 0) - (NVL(J.RO20T, 0) + NVL(S.RO20T, 0)) = 0 THEN
|
||||
NVL(J.RO20NB, 0) - (NVL(J.RO20B, 0) + NVL(S.RO20B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO20T = J.RO20T + S.RO20T,
|
||||
J.RO21B = J.RO21B + NVL(S.RO21B, 0) + (CASE
|
||||
WHEN NVL(S.RO21B, 0) <> 0 AND NVL(J.RO21NT, 0) <> 0 AND
|
||||
NVL(J.RO21NT, 0) - (NVL(J.RO21T, 0) + NVL(S.RO21T, 0)) = 0 THEN
|
||||
NVL(J.RO21NB, 0) - (NVL(J.RO21B, 0) + NVL(S.RO21B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO21T = J.RO21T + S.RO21T,
|
||||
J.RO11B = J.RO11B + NVL(S.RO11B, 0) + (CASE
|
||||
WHEN NVL(S.RO11B, 0) <> 0 AND NVL(J.RO11NT, 0) <> 0 AND
|
||||
NVL(J.RO11NT, 0) - (NVL(J.RO11T, 0) + NVL(S.RO11T, 0)) = 0 THEN
|
||||
NVL(J.RO11NB, 0) - (NVL(J.RO11B, 0) + NVL(S.RO11B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO11T = J.RO11T + S.RO11T,
|
||||
J.RO19B = J.RO19B + NVL(S.RO19B, 0) + (CASE
|
||||
WHEN NVL(S.RO19B, 0) <> 0 AND NVL(J.RO19NT, 0) <> 0 AND
|
||||
NVL(J.RO19NT, 0) - (NVL(J.RO19T, 0) + NVL(S.RO19T, 0)) = 0 THEN
|
||||
NVL(J.RO19NB, 0) - (NVL(J.RO19B, 0) + NVL(S.RO19B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO19T = J.RO19T + S.RO19T,
|
||||
J.RO9B = J.RO9B + NVL(S.RO9B, 0) + (CASE
|
||||
WHEN NVL(S.RO9B, 0) <> 0 AND NVL(J.RO9NT, 0) <> 0 AND
|
||||
NVL(J.RO9NT, 0) - (NVL(J.RO9T, 0) + NVL(S.RO9T, 0)) = 0 THEN
|
||||
NVL(J.RO9NB, 0) - (NVL(J.RO9B, 0) + NVL(S.RO9B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO9T = J.RO9T + S.RO9T,
|
||||
J.RO5B = J.RO5B + NVL(S.RO5B, 0) + (CASE
|
||||
WHEN NVL(S.RO5B, 0) <> 0 AND NVL(J.RO5NT, 0) <> 0 AND
|
||||
NVL(J.RO5NT, 0) - (NVL(J.RO5T, 0) + NVL(S.RO5T, 0)) = 0 THEN
|
||||
NVL(J.RO5NB, 0) - (NVL(J.RO5B, 0) + NVL(S.RO5B, 0))
|
||||
ELSE
|
||||
0
|
||||
END),
|
||||
J.RO5T = J.RO5T + S.RO5T,
|
||||
J.RO24NB = J.RO24NB + S.RO24NB,
|
||||
J.RO24NT = J.RO24NT + S.RO24NT,
|
||||
J.RO20NB = J.RO20NB + S.RO20NB,
|
||||
J.RO20NT = J.RO20NT + S.RO20NT,
|
||||
J.RO21NB = J.RO21NB + S.RO21NB,
|
||||
J.RO21NT = J.RO21NT + S.RO21NT,
|
||||
J.RO11NB = J.RO11NB + S.RO11NB,
|
||||
J.RO11NT = J.RO11NT + S.RO11NT,
|
||||
J.RO19NB = J.RO19NB + S.RO19NB,
|
||||
J.RO19NT = J.RO19NT + S.RO19NT,
|
||||
J.RO9NB = J.RO9NB + S.RO9NB,
|
||||
J.RO9NT = J.RO9NT + S.RO9NT,
|
||||
J.RO5NB = J.RO5NB + S.RO5NB,
|
||||
J.RO5NT = J.RO5NT + S.RO5NT,
|
||||
J.ROTI = J.ROTI + S.ROTI,
|
||||
J.CESCDD1 = J.CESCDD1 + S.CESCDD1,
|
||||
J.CESCDD2 = J.CESCDD2 + S.CESCDD2,
|
||||
J.CEOPTR = J.CEOPTR + S.CEOPTR,
|
||||
J.CESVDD = J.CESVDD + S.CESVDD,
|
||||
J.CESVFDD = J.CESVFDD + S.CESVFDD,
|
||||
J.CESVFS = J.CESVFS + S.CESVFS,
|
||||
J.WRSCDD = J.WRSCDD + S.WRSCDD,
|
||||
J.WRSCDDAB = J.WRSCDDAB + S.WRSCDDAB,
|
||||
J.WRSCDDCD = J.WRSCDDCD + S.WRSCDDCD,
|
||||
J.FODD = J.FODD + S.FODD,
|
||||
J.FOFDD = J.FOFDD + S.FOFDD,
|
||||
J.WRSCFDD = J.WRSCFDD + S.WRSCFDD,
|
||||
J.WRN = J.WRN + S.WRN,
|
||||
J.RORTC24 = J.RORTC24 + S.RORTC24,
|
||||
J.RORTC20 = J.RORTC20 + S.RORTC20,
|
||||
J.RORTC21 = J.RORTC21 + S.RORTC21,
|
||||
J.RORTC11 = J.RORTC11 + S.RORTC11,
|
||||
J.RORTC19 = J.RORTC19 + S.RORTC19,
|
||||
J.RORTC9 = J.RORTC9 + S.RORTC9,
|
||||
J.RORTC5 = J.RORTC5 + S.RORTC5 DELETE
|
||||
WHERE ' || tnScrie || ' = ' ||
|
||||
pack_contafin.nStergere || '
|
||||
and J.TOTCTVA = 0
|
||||
AND J.TOTFTVATAX = 0
|
||||
AND J.TOTTVATAX = 0
|
||||
AND J.TOTNETAX = 0
|
||||
AND J.RO24B = 0
|
||||
AND J.RO24T = 0
|
||||
AND J.RO20B = 0
|
||||
AND J.RO20T = 0
|
||||
AND J.RO19B = 0
|
||||
AND J.RO19T = 0
|
||||
AND J.RO9B = 0
|
||||
AND J.RO9T = 0
|
||||
AND J.RO5B = 0
|
||||
AND J.RO5T = 0
|
||||
AND J.RO24NB = 0
|
||||
AND J.RO24NT = 0
|
||||
AND J.RO20NB = 0
|
||||
AND J.RO20NT = 0
|
||||
AND J.RO19NB = 0
|
||||
AND J.RO19NT = 0
|
||||
AND J.RO9NB = 0
|
||||
AND J.RO9NT = 0
|
||||
AND J.RO5NB = 0
|
||||
AND J.RO5NT = 0
|
||||
AND J.ROTI = 0
|
||||
AND J.CESCDD1 = 0
|
||||
AND J.CESCDD2 = 0
|
||||
AND J.CEOPTR = 0
|
||||
AND J.CESVDD = 0
|
||||
AND J.CESVFDD = 0
|
||||
AND J.CESVFS = 0
|
||||
AND J.WRSCDD = 0
|
||||
AND J.WRSCDDAB = 0
|
||||
AND J.WRSCDDCD = 0
|
||||
AND J.FODD = 0
|
||||
AND J.FOFDD = 0
|
||||
AND J.WRSCFDD = 0
|
||||
AND J.WRN = 0
|
||||
AND J.RORTC24 = 0
|
||||
AND J.RORTC20 = 0
|
||||
AND J.RORTC19 = 0
|
||||
AND J.RORTC9 = 0
|
||||
AND J.RORTC5 = 0
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT(AN, LUNA, ID_FACT, NRACT, SERIE_ACT, ID_FDOC, DATAACT, DATAIREG, ID_PART, TOTCTVA, TOTFTVATAX, TOTTVATAX, TOTNETAX, RO24B, RO24T, RO20B, RO20T, RO21B, RO21T, RO11B, RO11T, RO19B, RO19T, RO9B, RO9T, RO5B, RO5T, RO24NB, RO24NT, RO20NB, RO20NT, RO21NB, RO21NT, RO11NB, RO11NT, RO19NB, RO19NT, RO9NB, RO9NT, RO5NB, RO5NT, ROTI, CESCDD1, CESCDD2, CEOPTR, CESVDD, CESVFDD, CESVFS, WRSCDD, WRSCDDAB, WRSCDDCD, FODD, FOFDD, WRSCFDD, WRN, RORTC24, RORTC20, RORTC21, RORTC11, RORTC19, RORTC9, RORTC5, COD, ID_SUCURSALA) VALUES(S.AN, S.LUNA, S.ID_FACT, S.NRACT, S.SERIE_ACT, S.ID_FDOC, S.DATAACT, S.DATAIREG, S.ID_PART, S.TOTCTVA, S.TOTFTVATAX, S.TOTTVATAX, S.TOTNETAX,
|
||||
(CASE
|
||||
WHEN NVL(S.RO24B, 0) <> 0 AND NVL(S.RO24NT, 0) <> 0 AND
|
||||
NVL(S.RO24NT, 0) = NVL(S.RO24T, 0) THEN
|
||||
NVL(S.RO24NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO24B, 0)
|
||||
END), S.RO24T,
|
||||
(CASE
|
||||
WHEN NVL(S.RO20B, 0) <> 0 AND NVL(S.RO20NT, 0) <> 0 AND
|
||||
NVL(S.RO20NT, 0) = NVL(S.RO20T, 0) THEN
|
||||
NVL(S.RO20NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO20B, 0)
|
||||
END), S.RO20T,
|
||||
(CASE
|
||||
WHEN NVL(S.RO21B, 0) <> 0 AND NVL(S.RO21NT, 0) <> 0 AND
|
||||
NVL(S.RO21NT, 0) = NVL(S.RO21T, 0) THEN
|
||||
NVL(S.RO21NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO21B, 0)
|
||||
END), S.RO21T,(CASE
|
||||
WHEN NVL(S.RO11B, 0) <> 0 AND NVL(S.RO11NT, 0) <> 0 AND
|
||||
NVL(S.RO11NT, 0) = NVL(S.RO11T, 0) THEN
|
||||
NVL(S.RO11NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO11B, 0)
|
||||
END), S.RO11T,
|
||||
(CASE
|
||||
WHEN NVL(S.RO19B, 0) <> 0 AND NVL(S.RO19NT, 0) <> 0 AND
|
||||
NVL(S.RO19NT, 0) = NVL(S.RO19T, 0) THEN
|
||||
NVL(S.RO19NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO19B, 0)
|
||||
END), S.RO19T,(CASE
|
||||
WHEN NVL(S.RO9B, 0) <> 0 AND NVL(S.RO9NT, 0) <> 0 AND
|
||||
NVL(S.RO9NT, 0) = NVL(S.RO9T, 0) THEN
|
||||
NVL(S.RO9NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO9B, 0)
|
||||
END), S.RO9T,(CASE
|
||||
WHEN NVL(S.RO5B, 0) <> 0 AND NVL(S.RO5NT, 0) <> 0 AND
|
||||
NVL(S.RO5NT, 0) = NVL(S.RO5T, 0) THEN
|
||||
NVL(S.RO5NB, 0)
|
||||
ELSE
|
||||
NVL(S.RO5B, 0)
|
||||
END), S.RO5T, S.RO24NB, S.RO24NT, S.RO20NB, S.RO20NT, S.RO21NB, S.RO21NT, S.RO11NB, S.RO11NT, S.RO19NB, S.RO19NT, S.RO9NB, S.RO9NT, S.RO5NB, S.RO5NT, S.ROTI, S.CESCDD1, S.CESCDD2, S.CEOPTR, S.CESVDD, S.CESVFDD, S.CESVFS, S.WRSCDD, S.WRSCDDAB, S.WRSCDDCD, S.FODD, S.FOFDD, S.WRSCFDD, S.WRN, S.RORTC24, S.RORTC20, S.RORTC21, S.RORTC11, S.RORTC19, S.RORTC9, S.RORTC5, S.COD, S.ID_SUCURSALA);
|
||||
|
||||
END SCRIE_JV_2007;
|
||||
565
proxmox/vm109-windows-dr/README.md
Normal file
565
proxmox/vm109-windows-dr/README.md
Normal file
@@ -0,0 +1,565 @@
|
||||
# VM 109 - Oracle DR System (Windows Standby)
|
||||
|
||||
**Director Proxmox:** `proxmox/vm109-windows-dr/`
|
||||
**VMID:** 109
|
||||
**Rol:** Disaster Recovery pentru Oracle Database (backup RMAN de pe server Windows extern)
|
||||
|
||||
---
|
||||
|
||||
# 🛡️ Oracle DR System - Complete Architecture
|
||||
|
||||
## 📊 System Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRODUCTION ENVIRONMENT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ PRIMARY SERVER (10.0.20.36) │
|
||||
│ Windows Server + Oracle 19c │
|
||||
│ ┌──────────────────────────────┐ │
|
||||
│ │ Database: ROA │ │
|
||||
│ │ Size: ~80 GB │ │
|
||||
│ │ Tables: 42,625 │ │
|
||||
│ └──────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ Backups (Daily) │
|
||||
│ ┌──────────────────────────────┐ │
|
||||
│ │ 02:30 - FULL backup (6-7 GB) │ │
|
||||
│ │ 13:00 - CUMULATIVE (200 MB) │ │
|
||||
│ │ 18:00 - CUMULATIVE (300 MB) │ │
|
||||
│ └──────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ SSH Transfer (Port 22)
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DR ENVIRONMENT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ PROXMOX HOST (10.0.20.202 - pveelite) │
|
||||
│ ┌──────────────────────────────┐ │
|
||||
│ │ Backup Storage (NFS Server) │◄─────── Monitoring Scripts │
|
||||
│ │ /mnt/pve/oracle-backups/ │ /opt/scripts/ │
|
||||
│ │ └── ROA/autobackup/ │ │
|
||||
│ └──────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ NFS Mount (F:\) │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────────────┐ │
|
||||
│ │ DR VM 109 (10.0.20.37) │ │
|
||||
│ │ Windows Server + Oracle 19c │ │
|
||||
│ │ Status: OFF (normally) │ │
|
||||
│ │ Starts for: Tests or Disaster │ │
|
||||
│ └──────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎯 Quick Actions
|
||||
|
||||
### ⚡ Emergency DR Activation (Production Down!)
|
||||
|
||||
```bash
|
||||
# 1. Start DR VM
|
||||
ssh root@10.0.20.202 "qm start 109"
|
||||
|
||||
# 2. Connect to VM (wait 3 min for boot)
|
||||
ssh -p 22122 romfast@10.0.20.37
|
||||
|
||||
# 3. Run restore (takes ~10-15 minutes)
|
||||
D:\oracle\scripts\rman_restore_from_zero.cmd
|
||||
|
||||
# 4. Database is now RUNNING - Update app connections to 10.0.20.37
|
||||
```
|
||||
|
||||
### 🧪 Weekly Test (Every Saturday)
|
||||
|
||||
```bash
|
||||
# Automatic at 06:00 via cron, or manual:
|
||||
ssh root@10.0.20.202 "/opt/scripts/weekly-dr-test-proxmox.sh"
|
||||
|
||||
# What it does:
|
||||
# ✓ Starts VM → Restores DB → Tests → Cleanup → Shutdown
|
||||
# ✓ Sends email report with results
|
||||
```
|
||||
|
||||
### 📊 Check Backup Health
|
||||
|
||||
```bash
|
||||
# Manual check (runs daily at 09:00 automatically)
|
||||
ssh root@10.0.20.202 "/opt/scripts/oracle-backup-monitor-proxmox.sh"
|
||||
|
||||
# Output:
|
||||
# Status: OK
|
||||
# FULL backup age: 11 hours ✓
|
||||
# CUMULATIVE backup age: 2 hours ✓
|
||||
# Disk usage: 45% ✓
|
||||
```
|
||||
|
||||
## 🗂️ Component Locations
|
||||
|
||||
### 📁 PRIMARY Server (10.0.20.36)
|
||||
```
|
||||
D:\rman_backup\
|
||||
├── rman_backup_full.txt # RMAN script for FULL backup
|
||||
├── rman_backup_incremental.txt # RMAN script for CUMULATIVE
|
||||
└── transfer_backups.ps1 # UNIFIED: Transfer ALL backups to Proxmox
|
||||
|
||||
Scheduled Tasks:
|
||||
├── 02:30 - Oracle RMAN Full Backup
|
||||
├── 03:00 - Transfer backups to DR (transfer_backups.ps1)
|
||||
├── 13:00 - Oracle RMAN Cumulative Backup
|
||||
├── 14:45 - Transfer backups to DR (transfer_backups.ps1)
|
||||
└── 18:00 - Oracle RMAN Cumulative Backup
|
||||
```
|
||||
|
||||
### 📁 PROXMOX Host (10.0.20.202)
|
||||
```
|
||||
/opt/scripts/
|
||||
├── oracle-backup-monitor-proxmox.sh # Daily backup monitoring
|
||||
├── weekly-dr-test-proxmox.sh # Weekly DR test
|
||||
└── PROXMOX_NOTIFICATIONS_README.md # Documentation
|
||||
|
||||
/mnt/pve/oracle-backups/ROA/autobackup/
|
||||
├── FULL_20251010_023001.BKP # Latest FULL backup
|
||||
├── INCR_20251010_130001.BKP # CUMULATIVE 13:00
|
||||
└── INCR_20251010_180001.BKP # CUMULATIVE 18:00
|
||||
|
||||
Cron Jobs:
|
||||
0 9 * * * /opt/scripts/oracle-backup-monitor-proxmox.sh
|
||||
0 6 * * 6 /opt/scripts/weekly-dr-test-proxmox.sh
|
||||
```
|
||||
|
||||
### 📁 DR VM 109 (10.0.20.37) - When Running
|
||||
```
|
||||
D:\oracle\scripts\
|
||||
├── rman_restore_from_zero.cmd # Main restore script ⭐
|
||||
├── cleanup_database.cmd # Cleanup after test
|
||||
└── mount-nfs.bat # Mount F:\ at startup
|
||||
|
||||
F:\ (NFS mount from Proxmox)
|
||||
└── ROA\autobackup\ # All backup files
|
||||
```
|
||||
|
||||
## 🔄 How It Works
|
||||
|
||||
### Backup Flow (Daily)
|
||||
```
|
||||
PRIMARY PROXMOX
|
||||
│ │
|
||||
├─02:30─FULL─Backup─────────────►
|
||||
│ (6-7 GB) │
|
||||
├─03:00─Transfer ALL────────────► Skip duplicates
|
||||
│ (transfer_backups.ps1) │
|
||||
│ │
|
||||
├─13:00─CUMULATIVE──────────────►
|
||||
│ (200 MB) │
|
||||
├─14:45─Transfer ALL────────────► Skip duplicates
|
||||
│ (transfer_backups.ps1) │ (only new files)
|
||||
│ │
|
||||
└─18:00─CUMULATIVE──────────────►
|
||||
(300 MB) Storage
|
||||
│
|
||||
┌──────────┐
|
||||
│ Monitor │ 09:00 Daily
|
||||
│ Check Age│ Alert if old
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
### Restore Process
|
||||
```
|
||||
Start VM → Mount F:\ → Copy Backups → RMAN Restore → Database OPEN
|
||||
2min Auto 2min 8min Ready!
|
||||
|
||||
Total Time: ~15 minutes
|
||||
```
|
||||
|
||||
## 🔧 Manual Operations
|
||||
|
||||
### Test Individual Components
|
||||
|
||||
```bash
|
||||
# 1. Test backup transfer (on PRIMARY)
|
||||
powershell -ExecutionPolicy Bypass -File "D:\rman_backup\transfer_backups.ps1"
|
||||
|
||||
# 2. Test NFS mount (on VM 109)
|
||||
mount -o rw,nolock,mtype=hard,timeout=60 10.0.20.202:/mnt/pve/oracle-backups F:
|
||||
dir F:\ROA\autobackup
|
||||
|
||||
# 3. Test notification system
|
||||
ssh root@10.0.20.202 "touch -d '2 days ago' /mnt/pve/oracle-backups/ROA/autobackup/*FULL*.BKP"
|
||||
ssh root@10.0.20.202 "/opt/scripts/oracle-backup-monitor-proxmox.sh"
|
||||
# Should send WARNING notification
|
||||
|
||||
# 4. Test database restore (on VM 109)
|
||||
D:\oracle\scripts\rman_restore_from_zero.cmd
|
||||
```
|
||||
|
||||
### Force Actions
|
||||
|
||||
```bash
|
||||
# Force backup now (on PRIMARY)
|
||||
rman cmdfile=D:\rman_backup\rman_backup_incremental.txt
|
||||
|
||||
# Force cleanup VM (on VM 109)
|
||||
D:\oracle\scripts\cleanup_database.cmd
|
||||
|
||||
# Force VM shutdown
|
||||
ssh root@10.0.20.202 "qm stop 109"
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### 🔍 Debugging Restore Tests
|
||||
|
||||
#### Check Backup Files on Proxmox (10.0.20.202)
|
||||
|
||||
```bash
|
||||
# 1. List all backup files with size and date
|
||||
ssh root@10.0.20.202 "ls -lht /mnt/pve/oracle-backups/ROA/autobackup/*.BKP"
|
||||
|
||||
# 2. Count backup files
|
||||
ssh root@10.0.20.202 "ls /mnt/pve/oracle-backups/ROA/autobackup/*.BKP | wc -l"
|
||||
|
||||
# 3. Check latest backups (last 24 hours)
|
||||
ssh root@10.0.20.202 "find /mnt/pve/oracle-backups/ROA/autobackup -name '*.BKP' -mtime -1 -ls"
|
||||
|
||||
# 4. Show backup files grouped by type (with new naming convention)
|
||||
ssh root@10.0.20.202 "ls -lh /mnt/pve/oracle-backups/ROA/autobackup/ | grep -E '(L0_|L1_|ARC_|SPFILE_|CF_|O1_MF)'"
|
||||
|
||||
# 5. Check disk space usage
|
||||
ssh root@10.0.20.202 "df -h /mnt/pve/oracle-backups"
|
||||
ssh root@10.0.20.202 "du -sh /mnt/pve/oracle-backups/ROA/autobackup/"
|
||||
|
||||
# 6. Verify newest backup timestamp
|
||||
ssh root@10.0.20.202 "stat /mnt/pve/oracle-backups/ROA/autobackup/L0_*.BKP 2>/dev/null | grep Modify || echo 'No L0 backups with new naming'"
|
||||
```
|
||||
|
||||
#### Verify Backup Files on DR VM (when running)
|
||||
|
||||
```powershell
|
||||
# 1. Check NFS mount is accessible
|
||||
Test-Path F:\ROA\autobackup
|
||||
|
||||
# 2. List all backup files
|
||||
Get-ChildItem F:\ROA\autobackup\*.BKP | Format-Table Name, Length, LastWriteTime
|
||||
|
||||
# 3. Count backup files
|
||||
(Get-ChildItem F:\ROA\autobackup\*.BKP).Count
|
||||
|
||||
# 4. Show total backup size
|
||||
"{0:N2} GB" -f ((Get-ChildItem F:\ROA\autobackup\*.BKP | Measure-Object -Property Length -Sum).Sum / 1GB)
|
||||
|
||||
# 5. Check latest Level 0 backup
|
||||
Get-ChildItem F:\ROA\autobackup\L0_*.BKP -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
|
||||
# 6. Check what was copied during last restore
|
||||
Get-Content D:\oracle\logs\restore_from_zero.log | Select-String "Copying|Copied"
|
||||
```
|
||||
|
||||
#### Check DR Test Results
|
||||
|
||||
```bash
|
||||
# 1. View latest DR test log
|
||||
ssh root@10.0.20.202 "ls -lt /var/log/oracle-dr/dr_test_*.log | head -1 | awk '{print \$9}' | xargs cat | tail -100"
|
||||
|
||||
# 2. Check test status (passed/failed)
|
||||
ssh root@10.0.20.202 "grep -E 'PASSED|FAILED|Database Verification' /var/log/oracle-dr/dr_test_*.log | tail -5"
|
||||
|
||||
# 3. See backup selection logic output
|
||||
ssh root@10.0.20.202 "grep -A5 'TEST MODE: Selecting' /var/log/oracle-dr/dr_test_*.log | tail -20"
|
||||
|
||||
# 4. Check how many files were selected
|
||||
ssh root@10.0.20.202 "grep 'Total files selected' /var/log/oracle-dr/dr_test_*.log | tail -1"
|
||||
|
||||
# 5. View RMAN errors (if any)
|
||||
ssh root@10.0.20.202 "grep -i 'RMAN-\|ORA-' /var/log/oracle-dr/dr_test_*.log | tail -20"
|
||||
```
|
||||
|
||||
#### Simulate Test Locally (on DR VM)
|
||||
|
||||
```powershell
|
||||
# 1. Start Oracle service manually
|
||||
Start-Service OracleServiceROA
|
||||
|
||||
# 2. Run cleanup to prepare for restore
|
||||
D:\oracle\scripts\cleanup_database.ps1 /SILENT
|
||||
|
||||
# 3. Run restore in test mode
|
||||
D:\oracle\scripts\rman_restore_from_zero.ps1 -TestMode
|
||||
|
||||
# 4. Verify database opened correctly
|
||||
sqlplus / as sysdba @D:\oracle\scripts\verify_db.sql
|
||||
|
||||
# 5. Check what backups were used
|
||||
Get-Content D:\oracle\logs\restore_from_zero.log | Select-String "backup piece"
|
||||
|
||||
# 6. View database verification output
|
||||
Get-Content D:\oracle\logs\restore_from_zero.log | Select-String -Pattern "DB_NAME|OPEN_MODE|TABLES" -Context 0,1
|
||||
```
|
||||
|
||||
#### Common Restore Test Issues
|
||||
|
||||
| Issue | Check | Fix |
|
||||
|-------|-------|-----|
|
||||
| Test reports FAILED but DB is open | Check log for "OPEN_MODE: READ WRITE" | Already fixed in latest version |
|
||||
| Missing datafiles in restore | Count backup files: should be 15-40+ | Wait for next full backup or copy all files |
|
||||
| "No backups found" error | Verify NFS mount: `Test-Path F:\` | Remount NFS or check Proxmox NFS service |
|
||||
| Restore takes > 30 min | Check backup size: should be ~5-8 GB | Normal for first restore after format change |
|
||||
| RMAN-06023 errors | Check for L0_*.BKP files on F:\ | Old format: need new backup with naming convention |
|
||||
|
||||
#### Verify Naming Convention is Active
|
||||
|
||||
```bash
|
||||
# Check if new naming convention is being used (after Oct 11, 2025)
|
||||
ssh root@10.0.20.202 "ls /mnt/pve/oracle-backups/ROA/autobackup/ | grep -E '^(L0_|L1_|ARC_|SPFILE_|CF_)' | wc -l"
|
||||
# Should return > 0 if active
|
||||
|
||||
# If 0, backups are still using old format (O1_MF_ANNNN_*)
|
||||
# Wait for next scheduled backup (02:30 daily) or run manual backup
|
||||
```
|
||||
|
||||
#### Manual Test Run with Verbose Output
|
||||
|
||||
```bash
|
||||
# Run test with full output visible
|
||||
ssh root@10.0.20.202
|
||||
cd /opt/scripts
|
||||
./weekly-dr-test-proxmox.sh 2>&1 | tee /tmp/dr_test_manual.log
|
||||
|
||||
# Watch in real-time what's happening
|
||||
# Look for these key stages:
|
||||
# - "TEST MODE: Selecting latest backup set"
|
||||
# - "Total files selected: XX"
|
||||
# - "RMAN restore completed successfully"
|
||||
# - "OPEN_MODE: READ WRITE"
|
||||
```
|
||||
|
||||
### ❌ Backup Monitor Not Sending Alerts
|
||||
|
||||
```bash
|
||||
# 1. Check templates exist
|
||||
ssh root@10.0.20.202 "ls /usr/share/pve-manager/templates/default/oracle-*"
|
||||
|
||||
# 2. Reinstall templates
|
||||
ssh root@10.0.20.202 "/opt/scripts/oracle-backup-monitor-proxmox.sh --install"
|
||||
|
||||
# 3. Check Proxmox notifications work
|
||||
ssh root@10.0.20.202 "pvesh create /nodes/$(hostname)/apt/update"
|
||||
# Should receive update notification
|
||||
```
|
||||
|
||||
### ❌ F:\ Drive Not Accessible in VM
|
||||
|
||||
```bash
|
||||
# On VM 109:
|
||||
# 1. Check NFS Client service
|
||||
Get-Service | Where {$_.Name -like "*NFS*"}
|
||||
|
||||
# 2. Manual mount
|
||||
mount -o rw,nolock,mtype=hard,timeout=60 10.0.20.202:/mnt/pve/oracle-backups F:
|
||||
|
||||
# 3. Check Proxmox NFS server
|
||||
ssh root@10.0.20.202 "showmount -e localhost"
|
||||
# Should show: /mnt/pve/oracle-backups 10.0.20.37
|
||||
```
|
||||
|
||||
### ❌ Restore Fails
|
||||
|
||||
```bash
|
||||
# 1. Check backup files exist
|
||||
dir F:\ROA\autobackup\*.BKP
|
||||
|
||||
# 2. Check Oracle service
|
||||
sc query OracleServiceROA
|
||||
|
||||
# 3. Check PFILE exists
|
||||
dir C:\Users\oracle\admin\ROA\pfile\initROA.ora
|
||||
|
||||
# 4. View restore log
|
||||
type D:\oracle\logs\restore_from_zero.log
|
||||
```
|
||||
|
||||
### ❌ VM Won't Start
|
||||
|
||||
```bash
|
||||
# Check VM status
|
||||
ssh root@10.0.20.202 "qm status 109"
|
||||
|
||||
# Check VM config
|
||||
ssh root@10.0.20.202 "qm config 109 | grep -E 'memory|cores|bootdisk'"
|
||||
|
||||
# Force unlock if locked
|
||||
ssh root@10.0.20.202 "qm unlock 109"
|
||||
|
||||
# Start with console
|
||||
ssh root@10.0.20.202 "qm start 109 && qm terminal 109"
|
||||
```
|
||||
|
||||
## 📈 Monitoring & Metrics
|
||||
|
||||
### Key Metrics
|
||||
| Metric | Target | Alert Threshold |
|
||||
|--------|--------|-----------------|
|
||||
| FULL Backup Age | < 24h | > 25h |
|
||||
| CUMULATIVE Age | < 6h | > 7h |
|
||||
| Backup Size | ~7 GB/day | > 10 GB |
|
||||
| Restore Time | < 15 min | > 30 min |
|
||||
| Disk Usage | < 80% | > 80% |
|
||||
|
||||
### Check Logs
|
||||
|
||||
```bash
|
||||
# Backup logs (on PRIMARY)
|
||||
Get-Content D:\rman_backup\logs\backup_*.log -Tail 50
|
||||
|
||||
# Transfer logs (on PRIMARY) - UNIFIED script
|
||||
Get-Content D:\rman_backup\logs\transfer_*.log -Tail 50
|
||||
|
||||
# Monitoring logs (on Proxmox)
|
||||
tail -50 /var/log/oracle-dr/*.log
|
||||
|
||||
# Restore logs (on VM 109)
|
||||
type D:\oracle\logs\restore_from_zero.log
|
||||
```
|
||||
|
||||
## 🔐 Security & Access
|
||||
|
||||
### SSH Keys Setup
|
||||
```
|
||||
PRIMARY (10.0.20.36) ──────► PROXMOX (10.0.20.202)
|
||||
SSH Key
|
||||
Port 22
|
||||
|
||||
LINUX WORKSTATION ─────────► PROXMOX (10.0.20.202)
|
||||
SSH Key
|
||||
Port 22
|
||||
|
||||
LINUX WORKSTATION ─────────► VM 109 (10.0.20.37)
|
||||
SSH Key
|
||||
Port 22122
|
||||
```
|
||||
|
||||
### Required Credentials
|
||||
- **PRIMARY**: Administrator (for scheduled tasks)
|
||||
- **PROXMOX**: root (for scripts and VM control)
|
||||
- **VM 109**: romfast (user), SYSTEM (Oracle service)
|
||||
|
||||
## 📅 Maintenance Schedule
|
||||
|
||||
| Day | Time | Action | Duration | Impact |
|
||||
|-----|------|--------|----------|--------|
|
||||
| Daily | 02:30 | FULL Backup | 30 min | None |
|
||||
| Daily | 09:00 | Monitor Backups | 1 min | None |
|
||||
| Daily | 13:00 | CUMULATIVE Backup | 5 min | None |
|
||||
| Daily | 18:00 | CUMULATIVE Backup | 5 min | None |
|
||||
| Saturday | 06:00 | DR Test | 30 min | None |
|
||||
|
||||
## 🚨 Disaster Recovery Procedure
|
||||
|
||||
### When PRIMARY is DOWN:
|
||||
|
||||
1. **Confirm PRIMARY is unreachable**
|
||||
```bash
|
||||
ping 10.0.20.36 # Should fail
|
||||
```
|
||||
|
||||
2. **Start DR VM**
|
||||
```bash
|
||||
ssh root@10.0.20.202 "qm start 109"
|
||||
```
|
||||
|
||||
3. **Wait for boot (3 minutes)**
|
||||
|
||||
4. **Connect to DR VM**
|
||||
```bash
|
||||
ssh -p 22122 romfast@10.0.20.37
|
||||
```
|
||||
|
||||
5. **Run restore**
|
||||
```cmd
|
||||
D:\oracle\scripts\rman_restore_from_zero.cmd
|
||||
```
|
||||
|
||||
6. **Verify database**
|
||||
```sql
|
||||
sqlplus / as sysdba
|
||||
SELECT name, open_mode FROM v$database;
|
||||
-- Should show: ROA, READ WRITE
|
||||
```
|
||||
|
||||
7. **Update application connections**
|
||||
- Change from: 10.0.20.36:1521/ROA
|
||||
- Change to: 10.0.20.37:1521/ROA
|
||||
|
||||
8. **Monitor DR system**
|
||||
- Database is now production
|
||||
- Do NOT run cleanup!
|
||||
- Keep VM running
|
||||
|
||||
## 📝 Quick Reference Card
|
||||
|
||||
```
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ DR QUICK REFERENCE ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ PRIMARY DOWN? ║
|
||||
║ ssh root@10.0.20.202 ║
|
||||
║ qm start 109 ║
|
||||
║ # Wait 3 min ║
|
||||
║ ssh -p 22122 romfast@10.0.20.37 ║
|
||||
║ D:\oracle\scripts\rman_restore_from_zero.cmd ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ TEST DR? ║
|
||||
║ ssh root@10.0.20.202 "/opt/scripts/weekly-dr-test-proxmox.sh"║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ CHECK BACKUPS? ║
|
||||
║ ssh root@10.0.20.202 "/opt/scripts/oracle-backup-monitor-proxmox.sh"║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ SUPPORT: ║
|
||||
║ Logs: /var/log/oracle-dr/ ║
|
||||
║ Docs: proxmox/vm109-windows-dr/docs/ ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structură Director
|
||||
|
||||
```
|
||||
vm109-windows-dr/
|
||||
├── README.md # Acest fișier
|
||||
├── docs/
|
||||
│ ├── PLAN_TESTARE_MONITORIZARE.md # Plan testare și monitorizare DR
|
||||
│ ├── PROXMOX_NOTIFICATIONS_README.md # Configurare notificări Proxmox
|
||||
│ └── archive/ # Planuri și statusuri anterioare
|
||||
│ ├── DR_UPGRADE_TO_CUMULATIVE_PLAN.md
|
||||
│ ├── DR_VM_MIGRATION_GUIDE.md
|
||||
│ ├── DR_WINDOWS_VM_IMPLEMENTATION_PLAN.md
|
||||
│ └── DR_WINDOWS_VM_STATUS_2025-10-09.md
|
||||
└── scripts/
|
||||
├── oracle-backup-monitor-proxmox.sh # Monitorizare zilnică (Proxmox)
|
||||
├── weekly-dr-test-proxmox.sh # Test săptămânal DR (Proxmox)
|
||||
├── rman_backup.bat # RMAN full backup (Windows)
|
||||
├── rman_backup_incremental.bat # RMAN incremental (Windows)
|
||||
├── transfer_backups.ps1 # Transfer backup-uri (Windows)
|
||||
├── rman_restore_from_zero.ps1 # Restore complet (Windows DR)
|
||||
├── cleanup_database.ps1 # Cleanup după test (Windows DR)
|
||||
└── *.ps1 # Alte scripturi configurare
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-01-27
|
||||
**Version:** 2.2 - Unified transfer script (transfer_backups.ps1)
|
||||
**Status:** ✅ Production Ready
|
||||
|
||||
## 📋 Changelog
|
||||
|
||||
### v2.2 (Oct 31, 2025)
|
||||
- ✨ **Unified transfer script**: Replaced `transfer_to_dr.ps1` and `transfer_incremental.ps1` with single `transfer_backups.ps1`
|
||||
- 🎯 **Smart duplicate detection**: Automatically skips files that exist on DR
|
||||
- ⚡ **Flexible scheduling**: Can run after any backup type or manually
|
||||
- 🔧 **Simplified maintenance**: One script to maintain instead of two
|
||||
|
||||
### v2.1 (Oct 11, 2025)
|
||||
- Added restore test debugging guide
|
||||
- Implemented new backup naming convention
|
||||
119
proxmox/vm109-windows-dr/docs/PLAN_TESTARE_MONITORIZARE.md
Normal file
119
proxmox/vm109-windows-dr/docs/PLAN_TESTARE_MONITORIZARE.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Plan de Testare pentru Scripturile de Monitorizare Oracle DR
|
||||
|
||||
**Director:** `proxmox/vm109-windows-dr/docs/`
|
||||
**Scripturi:** `proxmox/vm109-windows-dr/scripts/`
|
||||
|
||||
## Obiective
|
||||
1. Testarea funcționalității de notificări pentru scripturile de monitorizare
|
||||
2. Verificarea funcționării corecte fără erori
|
||||
3. Asigurarea că scriptul de DR test trimite notificare cu email indiferent de rezultat
|
||||
4. Salvarea planului pentru session hand-off
|
||||
|
||||
## Componente de Testat
|
||||
|
||||
### 1. Script Monitorizare Backup-uri (`oracle-backup-monitor-proxmox.sh`)
|
||||
- ✅ Testare funcționare normală (fără erori)
|
||||
- ✅ Verificare detectare probleme backup-uri
|
||||
- ✅ Testare trimitere notificări prin PVE::Notify
|
||||
- ✅ Verificare creare automată template-uri
|
||||
|
||||
### 2. Script Test DR Săptămânal (`weekly-dr-test-proxmox.sh`)
|
||||
- ✅ Testare flux complet de restaurare
|
||||
- ✅ Verificare trimitere notificare SUCCESS/FAIL
|
||||
- ✅ Configurare pentru notificare garantată (indiferent de rezultat)
|
||||
- ✅ Testare integrare cu sistemul de notificări Proxmox
|
||||
|
||||
### 3. Script Restaurare Bază de Date (`rman_restore_from_zero.cmd`)
|
||||
- ✅ Testare verificare acces NFS mount
|
||||
- ✅ Verificare proces de restaurare complet
|
||||
- ✅ Validare integrare cu scriptul DR test
|
||||
|
||||
## Etape de Testare
|
||||
|
||||
### Faza 1: Pregătire Mediului
|
||||
1. Verificare dependențe instalate (jq, PVE::Notify Perl modules)
|
||||
2. Verificare configurare notificări Proxmox
|
||||
3. Creare backup-uri de test în directorul `/mnt/pve/oracle-backups/ROA/autobackup`
|
||||
4. Verificare conectivitate SSH către VM DR (10.0.20.37)
|
||||
|
||||
### Faza 2: Testare Script Monitorizare
|
||||
1. Rulare `oracle-backup-monitor-proxmox.sh --install` pentru creare template-uri
|
||||
2. Verificare template-uri create în `/usr/share/pve-manager/templates/default/`
|
||||
3. Testare în condiții normale (toate backup-urile OK)
|
||||
4. Simulare problemă: backup expirat, spațiu disk insuficient
|
||||
5. Verificare recepționare notificări
|
||||
|
||||
### Faza 3: Testare Script DR Test
|
||||
1. Rulare `weekly-dr-test-proxmox.sh --install`
|
||||
2. Testare în mod dry-run (fără pornire VM reală)
|
||||
3. Verificare flux complet de restaurare
|
||||
4. Validare trimitere notificare atât pentru succes cât și pentru eșec
|
||||
5. Testare cleanup automat după test
|
||||
|
||||
### Faza 4: Validare Integrare
|
||||
1. Testare ambele scripturi împreună
|
||||
2. Verificare performanță și timp de răspuns
|
||||
3. Validare log-uri și rapoarte generate
|
||||
4. Configurare cron pentru execuție automată
|
||||
|
||||
### Faza 5: Validare Format Notificări
|
||||
1. Reinstalare template-uri compacte: `scripts/oracle-backup-monitor-proxmox.sh --install`
|
||||
2. Generare notificări reale din scripturi (backup monitor + DR test) și analiză în clienți email
|
||||
3. Verificare afișare în client email (text + HTML) și în GUI Proxmox
|
||||
4. Rulare `weekly-dr-test-proxmox.sh` în mediu controlat și validare sumar compact în email (inclusiv componente, pași, timeline)
|
||||
5. Capturare feedback utilizatori finali (Gmail + Outlook) pentru lizibilitate
|
||||
|
||||
### Faza 6: Testare Erori și Edge Cases
|
||||
1. Testare fără conectivitate la VM DR
|
||||
2. Testare director backup-uri gol
|
||||
3. Testare eșec restaurare database
|
||||
4. Testare timeout operațiuni
|
||||
5. Verificare comportament în aceste scenarii
|
||||
|
||||
## Modificări Necesar pentru Script DR Test
|
||||
|
||||
### Configurare Notificare Forțată
|
||||
Se va modifica `weekly-dr-test-proxmox.sh` pentru a trimite **întotdeauna** notificare:
|
||||
- ✅ Trackează toate testele (chiar și cele care eșuează la început)
|
||||
- ✅ Trimite raport detaliat indiferent de rezultat
|
||||
- ✅ Include timeline complet al pașilor executați
|
||||
- ✅ Generează notificare cu severity corespunzător
|
||||
|
||||
## Teste Specifice
|
||||
|
||||
### Test 1: Funcționare Normală
|
||||
- Scenariu: Toate componentele funcționează corect
|
||||
- Rezultat așteptat: Notificări succes, raport complet
|
||||
|
||||
### Test 2: Eșec Conectivitate VM
|
||||
- Scenariu: VM DR nu pornește sau nu răspunde la SSH
|
||||
- Rezultat așteptat: Notificare eșec cu detalii despre punctul de blocaj
|
||||
|
||||
### Test 3: Backup-uri Lipsă
|
||||
- Scenariu: Director backup-uri gol sau fișiere corupte
|
||||
- Rezultat așteptat: Notificare eroare + raport detaliat
|
||||
|
||||
### Test 4: Eșec Restaurare Database
|
||||
- Scenariu: RMAN restore eșuează la un pas specific
|
||||
- Rezultat așteptat: Notificare cu pasul exact unde a eșuat + log-uri
|
||||
|
||||
## Valide de Succes
|
||||
- ✅ Ambele scripturi rulează fără erori sintactice
|
||||
- ✅ Template-urile de notificare se creează automat
|
||||
- ✅ Notificările se trimit prin sistemul Proxmox
|
||||
- ✅ Email-uri raport sunt formatate corect (text + HTML)
|
||||
- ✅ Log-ul DR test conține timeline detaliat
|
||||
- ✅ Configurare cron funcționează corect
|
||||
|
||||
## Schedule Testare
|
||||
1. **Ziua 1**: Testare individuală scripturi
|
||||
2. **Ziua 2**: Testare integrat și scenarii de erori
|
||||
3. **Ziua 3**: Testare performance și configurare producție
|
||||
4. **Ziua 4**: Monitorizare continuă și validare finală
|
||||
|
||||
## Salvare Plan
|
||||
Planul salvat pentru hand-off sesiune.
|
||||
|
||||
---
|
||||
*Creat: 2025-10-10*
|
||||
*Status: Ready for implementation*
|
||||
300
proxmox/vm109-windows-dr/docs/PROXMOX_NOTIFICATIONS_README.md
Normal file
300
proxmox/vm109-windows-dr/docs/PROXMOX_NOTIFICATIONS_README.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# Oracle DR Monitoring cu Notificări Proxmox Native
|
||||
|
||||
**Director:** `proxmox/vm109-windows-dr/docs/`
|
||||
**Scripturi:** `proxmox/vm109-windows-dr/scripts/`
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
Sistem de monitorizare și alertare pentru Oracle DR care folosește **sistemul nativ de notificări Proxmox** (PVE::Notify) - același sistem folosit pentru alertele HA, backup-uri, etc.
|
||||
|
||||
**Avantaje majore:**
|
||||
- ✅ **Zero configurare email** - folosește setup-ul existent Proxmox
|
||||
- ✅ **Scripturi autosuficiente** - creează automat template-urile necesare
|
||||
- ✅ **Notificări profesionale** - HTML formatat, culori, grafice
|
||||
- ✅ **Integrare completă** - apare în Datacenter > Notifications
|
||||
- ✅ **Flexibilitate maximă** - schimbi destinația din GUI, nu din cod
|
||||
|
||||
## 📦 Componente
|
||||
|
||||
### 1. **oracle-backup-monitor-proxmox.sh**
|
||||
Monitorizează backup-urile Oracle și trimite alerte când:
|
||||
- Backup FULL > 25 ore vechime
|
||||
- Backup CUMULATIVE > 7 ore vechime
|
||||
- Spațiu disk > 80% plin
|
||||
- Lipsesc backup-uri
|
||||
|
||||
### 2. **weekly-dr-test-proxmox.sh**
|
||||
Rulează test DR complet automat:
|
||||
- Pornește VM-ul DR
|
||||
- Verifică mount NFS
|
||||
- Restaurează database
|
||||
- Validează datele
|
||||
- Cleanup și shutdown
|
||||
- Raport detaliat cu timeline
|
||||
|
||||
## 🚀 Instalare Rapidă (3 minute)
|
||||
|
||||
### Pe Proxmox Host:
|
||||
|
||||
```bash
|
||||
# 1. Copiază scripturile
|
||||
mkdir -p /opt/scripts
|
||||
cd /opt/scripts
|
||||
wget https://your-repo/oracle-backup-monitor-proxmox.sh
|
||||
wget https://your-repo/weekly-dr-test-proxmox.sh
|
||||
chmod +x *.sh
|
||||
|
||||
# 2. Instalează dependențe (dacă nu există)
|
||||
apt-get update
|
||||
apt-get install -y jq dos2unix
|
||||
|
||||
# 3. Corectează line endings (dacă vin din Windows)
|
||||
dos2unix /opt/scripts/*.sh
|
||||
|
||||
# 4. Instalează template-urile (AUTOMAT!)
|
||||
/opt/scripts/oracle-backup-monitor-proxmox.sh --install
|
||||
/opt/scripts/weekly-dr-test-proxmox.sh --install
|
||||
|
||||
# 5. Testează manual
|
||||
/opt/scripts/oracle-backup-monitor-proxmox.sh
|
||||
/opt/scripts/weekly-dr-test-proxmox.sh
|
||||
|
||||
# 6. Adaugă în cron
|
||||
crontab -e
|
||||
# Adaugă:
|
||||
0 9 * * * /opt/scripts/oracle-backup-monitor-proxmox.sh
|
||||
0 6 * * 6 /opt/scripts/weekly-dr-test-proxmox.sh
|
||||
```
|
||||
|
||||
**ATÂT! Nu mai trebuie să faci nimic!**
|
||||
|
||||
## 📧 Cum Funcționează Notificările
|
||||
|
||||
### Fluxul de notificare:
|
||||
|
||||
```
|
||||
Script detectează problemă
|
||||
↓
|
||||
Creează JSON cu datele
|
||||
↓
|
||||
Apelează PVE::Notify
|
||||
↓
|
||||
Proxmox procesează template-ul Handlebars
|
||||
↓
|
||||
Trimite notificare conform config din GUI
|
||||
↓
|
||||
Primești email/webhook/etc
|
||||
```
|
||||
|
||||
### Ce primești:
|
||||
|
||||
#### Email pentru Backup Monitor:
|
||||
```
|
||||
Subject: Oracle Backup WARNING - pveelite
|
||||
|
||||
Oracle Backup Monitoring Alert
|
||||
==============================
|
||||
Severity: WARNING
|
||||
Date: 2025-10-10 21:00:00
|
||||
Status: WARNING
|
||||
|
||||
WARNINGS:
|
||||
- FULL backup is 26 hours old (threshold: 25)
|
||||
|
||||
Backup Details:
|
||||
- Total Backups: 15
|
||||
- Total Size: 8.3 GB
|
||||
- FULL Backup Age: 26 hours ⚠️
|
||||
- CUMULATIVE Backup Age: 3 hours ✓
|
||||
- Disk Usage: 45%
|
||||
```
|
||||
|
||||
#### Email pentru DR Test (HTML):
|
||||

|
||||
|
||||
Conține:
|
||||
- Timeline vizual cu toate etapele
|
||||
- Metrici în card-uri colorate
|
||||
- Tabel cu detalii sistem
|
||||
- Evidențiere erori/warning-uri
|
||||
|
||||
## 🎨 Template-uri Handlebars
|
||||
|
||||
Scripturile creează **automat** 6 template-uri:
|
||||
|
||||
### Pentru Backup Monitor:
|
||||
- `oracle-backup-subject.txt.hbs` - Subiect email
|
||||
- `oracle-backup-body.txt.hbs` - Corp text
|
||||
- `oracle-backup-body.html.hbs` - Corp HTML formatat
|
||||
|
||||
### Pentru DR Test:
|
||||
- `oracle-dr-test-subject.txt.hbs` - Subiect email
|
||||
- `oracle-dr-test-body.txt.hbs` - Corp text
|
||||
- `oracle-dr-test-body.html.hbs` - Corp HTML cu timeline
|
||||
|
||||
**Locație:** `/usr/share/pve-manager/templates/default/`
|
||||
|
||||
## 🔧 Configurare Avansată (Opțional)
|
||||
|
||||
### Matching Rules în Proxmox GUI
|
||||
|
||||
Poți crea reguli pentru a ruta notificările diferit:
|
||||
|
||||
1. **Datacenter > Notifications > Add > Matcher**
|
||||
|
||||
2. **Exemplu 1:** Trimite erorile către echipa on-call
|
||||
```
|
||||
Name: oracle-critical
|
||||
Match field: severity equals error
|
||||
Match field: type equals oracle-backup
|
||||
Target: oncall-email
|
||||
```
|
||||
|
||||
3. **Exemplu 2:** Warning-uri doar în Slack
|
||||
```
|
||||
Name: oracle-warnings
|
||||
Match field: severity equals warning
|
||||
Match field: type contains oracle
|
||||
Target: slack-webhook
|
||||
```
|
||||
|
||||
### Modificare Template-uri
|
||||
|
||||
Dacă vrei să personalizezi template-urile:
|
||||
|
||||
```bash
|
||||
# Editează template-ul
|
||||
nano /usr/share/pve-manager/templates/default/oracle-backup-body.html.hbs
|
||||
|
||||
# Adaugă câmpuri noi, schimbă culori, etc.
|
||||
# Folosește sintaxa Handlebars: {{variable}}, {{#if condition}}, {{#each array}}
|
||||
```
|
||||
|
||||
## 📊 Monitorizare și Debugging
|
||||
|
||||
### Verifică template-urile:
|
||||
```bash
|
||||
ls -la /usr/share/pve-manager/templates/default/oracle-*
|
||||
```
|
||||
|
||||
### Vezi log-uri notificări:
|
||||
```bash
|
||||
# Log-uri Proxmox
|
||||
journalctl -u pveproxy -f | grep notify
|
||||
|
||||
# Log-uri scripturi
|
||||
tail -f /var/log/oracle-dr/*.log
|
||||
```
|
||||
|
||||
### Testează notificări manual:
|
||||
```bash
|
||||
# Forțează o alertă de test
|
||||
echo "test" > /mnt/pve/oracle-backups/ROA/autobackup/test.BKP
|
||||
./oracle-backup-monitor-proxmox.sh
|
||||
rm /mnt/pve/oracle-backups/ROA/autobackup/test.BKP
|
||||
```
|
||||
|
||||
## 🆚 Comparație cu Metode Clasice
|
||||
|
||||
| Aspect | Email Manual | Webhook | **PVE::Notify** |
|
||||
|--------|--------------|---------|-----------------|
|
||||
| Configurare | Complex (SMTP) | Medium | **Zero** ✅ |
|
||||
| Template-uri | În script | În script | **Handlebars** ✅ |
|
||||
| Flexibilitate | Hardcodat | Hardcodat | **GUI Proxmox** ✅ |
|
||||
| Formatare | Basic | JSON | **HTML Rich** ✅ |
|
||||
| Maintenance | Per script | Per script | **Centralizat** ✅ |
|
||||
| Integrare | Separată | Separată | **Nativă** ✅ |
|
||||
|
||||
## 🔐 Securitate
|
||||
|
||||
- Scripturile rulează local pe Proxmox (no remote execution)
|
||||
- Folosesc SSH keys pentru conectare la VM-uri
|
||||
- Template-urile sunt read-only pentru non-root
|
||||
- Notificările urmează security policy-ul Proxmox
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Problemă: Nu primesc notificări
|
||||
|
||||
1. Verifică dacă Proxmox trimite alte notificări:
|
||||
```bash
|
||||
# Test notificare Proxmox
|
||||
pvesh create /nodes/$(hostname)/apt/update
|
||||
# Ar trebui să primești notificare despre update
|
||||
```
|
||||
|
||||
2. Verifică template-urile:
|
||||
```bash
|
||||
ls /usr/share/pve-manager/templates/default/oracle-*
|
||||
# Trebuie să existe 6 fișiere
|
||||
```
|
||||
|
||||
3. Verifică configurația notificări:
|
||||
```bash
|
||||
cat /etc/pve/notifications.cfg
|
||||
```
|
||||
|
||||
### Problemă: Template-uri nu se creează
|
||||
|
||||
```bash
|
||||
# Rulează cu debug
|
||||
bash -x ./oracle-backup-monitor-proxmox.sh --install
|
||||
|
||||
# Verifică permisiuni
|
||||
ls -ld /usr/share/pve-manager/templates/default/
|
||||
```
|
||||
|
||||
### Problemă: Eroare PVE::Notify
|
||||
|
||||
```bash
|
||||
# Verifică că perl modules sunt instalate
|
||||
perl -e 'use PVE::Notify; print "OK\n"'
|
||||
|
||||
# Reinstalează dacă lipsesc
|
||||
apt-get install --reinstall libpve-common-perl
|
||||
```
|
||||
|
||||
## 📈 Metrici și KPIs
|
||||
|
||||
Scripturile raportează automat:
|
||||
|
||||
### Backup Monitor:
|
||||
- Vârsta backup-urilor (ore)
|
||||
- Număr total backup-uri
|
||||
- Dimensiune totală (GB)
|
||||
- Utilizare disk (%)
|
||||
|
||||
### DR Test:
|
||||
- Durata totală test (minute)
|
||||
- Timp restaurare (minute)
|
||||
- Număr tabele restaurate
|
||||
- Status fiecare etapă
|
||||
- Spațiu eliberat (GB)
|
||||
|
||||
## 🎉 Beneficii pentru Echipă
|
||||
|
||||
1. **Zero Training** - folosește sistemul cunoscut Proxmox
|
||||
2. **Zero Maintenance** - nu trebuie actualizate credențiale email
|
||||
3. **Consistență** - toate alertele vin în același format
|
||||
4. **Vizibilitate** - apare în dashboard Proxmox
|
||||
5. **Flexibilitate** - schimbi destinatari din GUI instant
|
||||
|
||||
## 📝 Note Finale
|
||||
|
||||
- Scripturile sunt **idempotente** - pot fi rulate oricând
|
||||
- Template-urile se creează **doar dacă lipsesc**
|
||||
- Notificările se trimit **doar când sunt probleme** (sau success pentru DR test)
|
||||
- Log-urile se păstrează **local pentru audit**
|
||||
|
||||
## 🤝 Suport
|
||||
|
||||
Pentru probleme sau întrebări:
|
||||
1. Verifică această documentație
|
||||
2. Verifică log-urile: `/var/log/oracle-dr/`
|
||||
3. Rulează cu `--help` pentru opțiuni
|
||||
|
||||
---
|
||||
|
||||
*Dezvoltat pentru sistemul Oracle DR pe Proxmox*
|
||||
*Bazat pe pattern-ul ha-monitor.sh din Proxmox VE*
|
||||
*Versiune: 1.0 - Octombrie 2025*
|
||||
File diff suppressed because it is too large
Load Diff
356
proxmox/vm109-windows-dr/docs/archive/DR_VM_MIGRATION_GUIDE.md
Normal file
356
proxmox/vm109-windows-dr/docs/archive/DR_VM_MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,356 @@
|
||||
# Oracle DR VM - Migration Between Proxmox Nodes
|
||||
|
||||
**Purpose:** How to migrate VM 109 between Proxmox nodes while maintaining backup access
|
||||
**Scenario:** Move VM from pveelite (10.0.20.202) to pvemini (10.0.20.201) or vice versa
|
||||
|
||||
---
|
||||
|
||||
## 📋 OVERVIEW
|
||||
|
||||
**Current Setup:**
|
||||
- VM 109 runs on pveelite (10.0.20.202)
|
||||
- Backups stored on pveelite: `/mnt/pve/oracle-backups`
|
||||
- VM has mount point: `qm set 109 -mp0 /mnt/pve/oracle-backups`
|
||||
- Mount appears in Windows as **F:\** (E:\ already used)
|
||||
|
||||
**Challenge:**
|
||||
- Mount points are **node-local** - path `/mnt/pve/oracle-backups` exists only on pveelite
|
||||
- If you migrate VM to pvemini, mount point breaks
|
||||
|
||||
**Solution:**
|
||||
- Create same directory structure on destination node
|
||||
- Sync backups between nodes
|
||||
- Mount point works identically on new node
|
||||
|
||||
---
|
||||
|
||||
## 🔄 MIGRATION PROCEDURE
|
||||
|
||||
### PRE-MIGRATION CHECKLIST
|
||||
|
||||
- [ ] VM 109 is powered OFF
|
||||
- [ ] You have root SSH access to both Proxmox nodes
|
||||
- [ ] You know which node you're migrating TO
|
||||
- [ ] Backups are current (check timestamp)
|
||||
|
||||
---
|
||||
|
||||
### STEP 1: Prepare Destination Node (pvemini)
|
||||
|
||||
**On pvemini (10.0.20.201):**
|
||||
|
||||
```bash
|
||||
ssh root@10.0.20.201
|
||||
|
||||
# Create identical directory structure
|
||||
mkdir -p /mnt/pve/oracle-backups/ROA/autobackup
|
||||
chmod 755 /mnt/pve/oracle-backups
|
||||
chmod 755 /mnt/pve/oracle-backups/ROA
|
||||
chmod 755 /mnt/pve/oracle-backups/ROA/autobackup
|
||||
|
||||
# Verify structure
|
||||
ls -la /mnt/pve/oracle-backups/ROA/autobackup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STEP 2: Sync Backups from Source to Destination
|
||||
|
||||
**Option A: Full Sync (first time migration)**
|
||||
|
||||
```bash
|
||||
# On pvemini, sync all backups from pveelite
|
||||
rsync -avz --progress \
|
||||
root@10.0.20.202:/mnt/pve/oracle-backups/ \
|
||||
/mnt/pve/oracle-backups/
|
||||
|
||||
# This copies all backup files (~15 GB, takes 2-3 minutes on 1Gbps network)
|
||||
```
|
||||
|
||||
**Option B: Incremental Sync (if you already synced before)**
|
||||
|
||||
```bash
|
||||
# On pvemini, sync only new/changed files
|
||||
rsync -avz --progress --update \
|
||||
root@10.0.20.202:/mnt/pve/oracle-backups/ \
|
||||
/mnt/pve/oracle-backups/
|
||||
|
||||
# Much faster - only copies new backups
|
||||
```
|
||||
|
||||
**Verify sync:**
|
||||
```bash
|
||||
# Check file count matches
|
||||
ssh root@10.0.20.202 "ls /mnt/pve/oracle-backups/ROA/autobackup/*.bkp | wc -l"
|
||||
ls /mnt/pve/oracle-backups/ROA/autobackup/*.bkp | wc -l
|
||||
|
||||
# Should be same number
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STEP 3: Migrate VM via Proxmox
|
||||
|
||||
**Option A: Online Migration (VM stays running)**
|
||||
|
||||
```bash
|
||||
# From Proxmox CLI on source node (pveelite):
|
||||
qm migrate 109 pvemini --online
|
||||
|
||||
# This uses live migration - VM doesn't stop
|
||||
# Takes 5-10 minutes depending on RAM/disk
|
||||
```
|
||||
|
||||
**Option B: Offline Migration (VM must be stopped)**
|
||||
|
||||
```bash
|
||||
# Stop VM first
|
||||
qm stop 109
|
||||
|
||||
# Migrate
|
||||
qm migrate 109 pvemini
|
||||
|
||||
# Faster than online, but requires downtime
|
||||
```
|
||||
|
||||
**Option C: Via Proxmox Web UI**
|
||||
|
||||
```
|
||||
1. Select VM 109 on pveelite
|
||||
2. Click "Migrate"
|
||||
3. Select target node: pvemini
|
||||
4. Choose migration type: online or offline
|
||||
5. Click "Migrate"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STEP 4: Verify Mount Point After Migration
|
||||
|
||||
**After migration completes:**
|
||||
|
||||
```bash
|
||||
# On pvemini, check VM config includes mount point
|
||||
qm config 109 | grep mp0
|
||||
|
||||
# Expected output:
|
||||
# mp0: /mnt/pve/oracle-backups,mp=/mnt/oracle-backups
|
||||
|
||||
# If missing, add it:
|
||||
qm set 109 -mp0 /mnt/pve/oracle-backups,mp=/mnt/oracle-backups
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STEP 5: Start VM and Verify Access
|
||||
|
||||
```bash
|
||||
# Start VM on new node
|
||||
qm start 109
|
||||
|
||||
# Wait for boot
|
||||
sleep 180
|
||||
|
||||
# Check mount in Windows
|
||||
ssh -p 22122 romfast@10.0.20.37 "Get-PSDrive F"
|
||||
|
||||
# Should show F:\ with Used/Free space
|
||||
|
||||
# Verify backup files accessible
|
||||
ssh -p 22122 romfast@10.0.20.37 "Get-ChildItem F:\ROA\autobackup\*.bkp | Measure-Object"
|
||||
|
||||
# Should show backup file count
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STEP 6: Update PRIMARY Transfer Scripts
|
||||
|
||||
**On PRIMARY (10.0.20.36):**
|
||||
|
||||
Backup transfer scripts need to know which node to send to.
|
||||
|
||||
**Option A: Update scripts to point to new node**
|
||||
|
||||
```powershell
|
||||
# Edit transfer scripts
|
||||
cd D:\rman_backup
|
||||
|
||||
# Find and replace in transfer scripts:
|
||||
# ÎNAINTE:
|
||||
$DRHost = "10.0.20.202" # pveelite
|
||||
|
||||
# DUPĂ:
|
||||
$DRHost = "10.0.20.201" # pvemini
|
||||
```
|
||||
|
||||
**Option B: Use DNS/hostname (RECOMMENDED)**
|
||||
|
||||
```powershell
|
||||
# In transfer scripts, use hostname instead of IP:
|
||||
$DRHost = "pvedr" # DNS name
|
||||
|
||||
# Then update DNS to point to active node:
|
||||
# pvedr → 10.0.20.201 (currently pvemini)
|
||||
# When you migrate back, just update DNS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 ONGOING SYNC STRATEGY
|
||||
|
||||
### If VM Stays on New Node Long-Term
|
||||
|
||||
**Setup automated sync from PRIMARY → new node:**
|
||||
|
||||
Just update transfer scripts as in Step 6 above. Backups will now go directly to pvemini.
|
||||
|
||||
**Old backups on pveelite:**
|
||||
- Can be deleted after verification
|
||||
- Or kept as additional backup copy (recommended)
|
||||
|
||||
```bash
|
||||
# On pveelite, cleanup old backups after 7 days
|
||||
find /mnt/pve/oracle-backups/ROA/autobackup -name "*.bkp" -mtime +7 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### If You Migrate VM Back and Forth
|
||||
|
||||
**Scenario:** VM moves between nodes frequently
|
||||
|
||||
**Solution 1: Sync in both directions**
|
||||
|
||||
```bash
|
||||
# Cronjob on pveelite (every 6 hours)
|
||||
0 */6 * * * rsync -az root@10.0.20.201:/mnt/pve/oracle-backups/ /mnt/pve/oracle-backups/
|
||||
|
||||
# Cronjob on pvemini (every 6 hours)
|
||||
0 */6 * * * rsync -az root@10.0.20.202:/mnt/pve/oracle-backups/ /mnt/pve/oracle-backups/
|
||||
```
|
||||
|
||||
**Solution 2: Shared Storage (NFS/CIFS)**
|
||||
|
||||
Use Proxmox shared storage instead of local paths:
|
||||
- Setup NFS server on one node
|
||||
- Both nodes mount same NFS share
|
||||
- `/mnt/pve/oracle-backups` points to shared storage
|
||||
- VM migration doesn't require backup sync
|
||||
|
||||
---
|
||||
|
||||
## 📊 MIGRATION CHECKLIST
|
||||
|
||||
### Before Migration:
|
||||
- [ ] VM 109 is stopped (or prepared for online migration)
|
||||
- [ ] Destination node has directory: `/mnt/pve/oracle-backups/ROA/autobackup`
|
||||
- [ ] Backups synced to destination node (rsync completed)
|
||||
- [ ] You have tested restore recently (weekly test passed)
|
||||
|
||||
### During Migration:
|
||||
- [ ] VM migration initiated (online or offline)
|
||||
- [ ] Migration progress monitored (no errors)
|
||||
- [ ] Migration completed successfully
|
||||
|
||||
### After Migration:
|
||||
- [ ] VM 109 shows as running on new node
|
||||
- [ ] Mount point configured: `qm config 109 | grep mp0`
|
||||
- [ ] VM started successfully
|
||||
- [ ] F:\ drive accessible in Windows: `Get-PSDrive F`
|
||||
- [ ] Backup files visible: `Get-ChildItem F:\ROA\autobackup\*.bkp`
|
||||
- [ ] PRIMARY transfer scripts updated (point to new node IP)
|
||||
- [ ] Test restore completed successfully
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ TROUBLESHOOTING
|
||||
|
||||
### Mount Point Not Visible in VM After Migration
|
||||
|
||||
**Symptom:** F:\ drive missing in Windows after migration
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# On new node, verify mount point config
|
||||
qm config 109 | grep mp0
|
||||
|
||||
# If missing, add it
|
||||
qm set 109 -mp0 /mnt/pve/oracle-backups,mp=/mnt/oracle-backups
|
||||
|
||||
# Restart VM
|
||||
qm stop 109
|
||||
qm start 109
|
||||
```
|
||||
|
||||
### Backup Files Not Accessible
|
||||
|
||||
**Symptom:** F:\ exists but shows as empty
|
||||
|
||||
**Cause:** Backups not synced to new node
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Re-sync backups from old node
|
||||
rsync -avz root@10.0.20.202:/mnt/pve/oracle-backups/ /mnt/pve/oracle-backups/
|
||||
|
||||
# Verify files exist
|
||||
ls -lh /mnt/pve/oracle-backups/ROA/autobackup/*.bkp
|
||||
```
|
||||
|
||||
### PRIMARY Still Sending to Old Node
|
||||
|
||||
**Symptom:** New backups not appearing on new node
|
||||
|
||||
**Cause:** Transfer scripts still point to old node IP
|
||||
|
||||
**Solution:**
|
||||
Update `$DRHost` in transfer scripts on PRIMARY (see Step 6)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 MIGRATION TIMELINE
|
||||
|
||||
| Task | Duration | Downtime |
|
||||
|------|----------|----------|
|
||||
| Prepare destination node | 5 min | None |
|
||||
| Sync backups (full, ~15GB) | 3 min | None |
|
||||
| Migrate VM (offline) | 5 min | **5 min** |
|
||||
| Verify and start VM | 3 min | **3 min** |
|
||||
| Update PRIMARY scripts | 2 min | None |
|
||||
| **Total** | **18 min** | **8 min** |
|
||||
|
||||
**With online migration:** 0 minutes downtime (VM keeps running during migration)
|
||||
|
||||
---
|
||||
|
||||
## 📞 QUICK REFERENCE
|
||||
|
||||
**Current Setup:**
|
||||
- Source node: pveelite (10.0.20.202)
|
||||
- Destination node: pvemini (10.0.20.201)
|
||||
- VM: 109 (oracle-dr-windows)
|
||||
- Backup path: `/mnt/pve/oracle-backups`
|
||||
- Windows mount: F:\ (not E:\ - already used)
|
||||
|
||||
**Key Commands:**
|
||||
```bash
|
||||
# Sync backups
|
||||
rsync -avz root@SOURCE:/mnt/pve/oracle-backups/ /mnt/pve/oracle-backups/
|
||||
|
||||
# Migrate VM
|
||||
qm migrate 109 DESTINATION --online
|
||||
|
||||
# Check mount
|
||||
qm config 109 | grep mp0
|
||||
|
||||
# Add mount if missing
|
||||
qm set 109 -mp0 /mnt/pve/oracle-backups,mp=/mnt/oracle-backups
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Generated:** 2025-10-09
|
||||
**Version:** 1.0
|
||||
**Status:** Ready for use
|
||||
**See Also:** DR_UPGRADE_TO_CUMULATIVE_PLAN.md
|
||||
@@ -0,0 +1,963 @@
|
||||
# Oracle DR - Windows VM Implementation Plan
|
||||
**Generated:** 2025-10-08
|
||||
**Objective:** Replace Linux LXC DR with Windows VM for same-platform RMAN restore
|
||||
**Target:** Windows VM in Proxmox, IP 10.0.20.37, Oracle 19c SE2
|
||||
|
||||
---
|
||||
|
||||
## 📋 PRE-IMPLEMENTATION CHECKLIST
|
||||
|
||||
### Current Infrastructure (IMPLEMENTED ✅)
|
||||
- ✅ PRIMARY: Windows Server, Oracle 19c SE2, IP: 10.0.20.36, SSH port 22122
|
||||
- ✅ Database: ROA, DBID: 1363569330
|
||||
- ✅ RMAN backups: FULL daily (02:30 AM)
|
||||
- ✅ DIFFERENTIAL INCREMENTAL (14:00) - NOT USED (causes UNDO corruption on restore)
|
||||
- ✅ Transfer scripts: PowerShell scripts transferring to VM 109 (Windows)
|
||||
- ✅ Backup size: ~6-7GB compressed (from 23GB), retention 2 days
|
||||
- ✅ DR target: Windows VM 109 (10.0.20.37) on pveelite - **OPERATIONAL**
|
||||
|
||||
### Planned Upgrade (see DR_UPGRADE_TO_CUMULATIVE_PLAN.md)
|
||||
- 🔄 Convert DIFFERENTIAL → **CUMULATIVE** incremental backups
|
||||
- 🔄 Add second daily incremental (13:00 + 18:00 vs current 14:00 only)
|
||||
- 🔄 Store backups on Proxmox host (pveelite), mounted in VM when needed
|
||||
- 🔄 Target RPO: **3-4 hours** (vs current 24 hours)
|
||||
|
||||
### What We'll Build
|
||||
- 🎯 Windows VM in Proxmox (replaces LXC 109)
|
||||
- 🎯 IP: 10.0.20.37 (same as current LXC)
|
||||
- 🎯 Oracle 19c SE2 installed (empty database template)
|
||||
- 🎯 OpenSSH Server for passwordless transfer
|
||||
- 🎯 RMAN restore scripts (automated DR recovery)
|
||||
- 🎯 Zero daily resource consumption (VM powered off when not needed)
|
||||
|
||||
### Resource Requirements
|
||||
- RAM: 4-6 GB (allocated, but VM runs only during DR events)
|
||||
- Disk: 100 GB (OS + Oracle + backup storage)
|
||||
- CPU: 2-4 vCPU
|
||||
- Network: Access to 10.0.20.0/24
|
||||
|
||||
---
|
||||
|
||||
## 🚀 PHASE 1: CREATE WINDOWS VM IN PROXMOX (30 minutes)
|
||||
|
||||
### Step 1.1: Download Windows 11 ISO
|
||||
```bash
|
||||
# On Proxmox host or download station
|
||||
cd /var/lib/vz/template/iso
|
||||
|
||||
# Option A: Download Windows 11 from Microsoft
|
||||
wget -O Win11_EnglishInternational_x64v1.iso \
|
||||
"https://software-download.microsoft.com/download/pr/..."
|
||||
|
||||
# Option B: Upload existing ISO via Proxmox web UI
|
||||
# Datacenter → Storage → ISO Images → Upload
|
||||
```
|
||||
|
||||
### Step 1.2: Create VM in Proxmox Web UI
|
||||
```
|
||||
Proxmox Web UI → Create VM
|
||||
|
||||
General:
|
||||
- VM ID: 109 (same as LXC number for consistency)
|
||||
- Name: oracle-dr-windows
|
||||
- Start at boot: NO (VM stays off until DR event)
|
||||
|
||||
OS:
|
||||
- ISO: Win11_EnglishInternational_x64v1.iso
|
||||
- Type: Microsoft Windows
|
||||
- Version: 11/2022
|
||||
|
||||
System:
|
||||
- Machine: q35
|
||||
- BIOS: OVMF (UEFI)
|
||||
- Add TPM: YES (for Windows 11)
|
||||
- SCSI Controller: VirtIO SCSI
|
||||
|
||||
Disks:
|
||||
- Bus/Device: SCSI 0
|
||||
- Storage: local-lvm (or your storage)
|
||||
- Size: 100 GB
|
||||
- Cache: Write back
|
||||
- Discard: YES
|
||||
- IO thread: YES
|
||||
|
||||
CPU:
|
||||
- Cores: 4
|
||||
- Type: host
|
||||
|
||||
Memory:
|
||||
- RAM: 6144 MB (6 GB)
|
||||
- Ballooning: NO
|
||||
|
||||
Network:
|
||||
- Bridge: vmbr0
|
||||
- Model: VirtIO
|
||||
- Firewall: NO
|
||||
```
|
||||
|
||||
### Step 1.3: Install Windows 11
|
||||
```
|
||||
1. Start VM → Open Console (noVNC)
|
||||
2. Boot from ISO
|
||||
3. Windows Setup:
|
||||
- Language: English
|
||||
- Install Now
|
||||
- Windows 11 Pro (or your edition)
|
||||
- Custom Install
|
||||
- Load driver: Browse → virtio-win-0.1.x (if needed for disk detection)
|
||||
- Select disk → Format → Next
|
||||
|
||||
4. Initial Setup:
|
||||
- Computer name: ORACLE-DR
|
||||
- Local account: Administrator / <strong-password>
|
||||
- Disable all telemetry/tracking options
|
||||
|
||||
5. First boot:
|
||||
- Disable Windows Defender real-time protection (for Oracle performance)
|
||||
- Disable Windows Update automatic restart
|
||||
- Install VirtIO drivers (guest tools)
|
||||
```
|
||||
|
||||
### Step 1.4: Configure Network (Static IP)
|
||||
```powershell
|
||||
# In Windows VM, run PowerShell as Administrator
|
||||
|
||||
# Set static IP 10.0.20.37
|
||||
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 10.0.20.37 -PrefixLength 24 -DefaultGateway 10.0.20.1
|
||||
|
||||
# Set DNS
|
||||
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("10.0.20.1","8.8.8.8")
|
||||
|
||||
# Verify
|
||||
Get-NetIPAddress | Where-Object {$_.IPAddress -eq "10.0.20.37"}
|
||||
Test-Connection 10.0.20.36 -Count 2
|
||||
```
|
||||
|
||||
### Step 1.5: Windows Initial Configuration
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
|
||||
# Enable Remote Desktop (optional, for management)
|
||||
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0
|
||||
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
|
||||
|
||||
# Disable Windows Firewall for private network (or configure rules)
|
||||
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
|
||||
|
||||
# Set timezone
|
||||
Set-TimeZone -Id "GTB Standard Time" # Romania timezone
|
||||
|
||||
# Disable hibernation (saves disk space)
|
||||
powercfg /hibernate off
|
||||
|
||||
# Create directories for Oracle
|
||||
New-Item -ItemType Directory -Path "D:\oracle" -Force
|
||||
New-Item -ItemType Directory -Path "D:\oracle\backups" -Force
|
||||
New-Item -ItemType Directory -Path "D:\oracle\oradata" -Force
|
||||
New-Item -ItemType Directory -Path "D:\oracle\fra" -Force
|
||||
```
|
||||
|
||||
**✅ PHASE 1 COMPLETE:** Windows VM created, network configured, ready for Oracle installation
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ PHASE 2: INSTALL ORACLE 19c (60-90 minutes)
|
||||
|
||||
### Step 2.1: Download Oracle 19c
|
||||
```
|
||||
On developer machine or PRIMARY:
|
||||
|
||||
1. Go to: https://www.oracle.com/database/technologies/oracle19c-windows-downloads.html
|
||||
2. Download: WINDOWS.X64_193000_db_home.zip (3.0 GB)
|
||||
3. Transfer to VM:
|
||||
- Option A: Shared folder via Proxmox
|
||||
- Option B: HTTP file server
|
||||
- Option C: Direct download in VM
|
||||
```
|
||||
|
||||
### Step 2.2: Prepare Installation (in Windows VM)
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
|
||||
# Extract Oracle installation
|
||||
Expand-Archive -Path "C:\Temp\WINDOWS.X64_193000_db_home.zip" -DestinationPath "D:\oracle\product\19c\dbhome_1"
|
||||
|
||||
# Create response file for silent install
|
||||
$responseFile = @"
|
||||
oracle.install.option=INSTALL_DB_SWONLY
|
||||
UNIX_GROUP_NAME=
|
||||
INVENTORY_LOCATION=D:\oracle\oraInventory
|
||||
ORACLE_HOME=D:\oracle\product\19c\dbhome_1
|
||||
ORACLE_BASE=D:\oracle
|
||||
oracle.install.db.InstallEdition=SE2
|
||||
oracle.install.db.OSDBA_GROUP=ORA_DBA
|
||||
oracle.install.db.OSOPER_GROUP=ORA_OPER
|
||||
oracle.install.db.OSBACKUPDBA_GROUP=ORA_BACKUPDBA
|
||||
oracle.install.db.OSDGDBA_GROUP=ORA_DG
|
||||
oracle.install.db.OSKMDBA_GROUP=ORA_KM
|
||||
oracle.install.db.OSRACDBA_GROUP=ORA_RAC
|
||||
DECLINE_SECURITY_UPDATES=true
|
||||
"@
|
||||
|
||||
$responseFile | Out-File -FilePath "D:\oracle\db_install.rsp" -Encoding ASCII
|
||||
```
|
||||
|
||||
### Step 2.3: Silent Installation
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
|
||||
cd D:\oracle\product\19c\dbhome_1
|
||||
|
||||
# Silent install (takes 30-60 minutes)
|
||||
.\setup.exe -silent -responseFile D:\oracle\db_install.rsp -ignorePrereqFailure
|
||||
|
||||
# Wait for completion, check log:
|
||||
# D:\oracle\oraInventory\logs\installActions<timestamp>.log
|
||||
|
||||
# Run root scripts (as Administrator)
|
||||
D:\oracle\product\19c\dbhome_1\root.bat
|
||||
```
|
||||
|
||||
### Step 2.4: Create Listener
|
||||
```powershell
|
||||
# Set environment
|
||||
$env:ORACLE_HOME = "D:\oracle\product\19c\dbhome_1"
|
||||
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
|
||||
|
||||
# Create listener.ora
|
||||
$listenerOra = @"
|
||||
LISTENER =
|
||||
(DESCRIPTION_LIST =
|
||||
(DESCRIPTION =
|
||||
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.20.37)(PORT = 1521))
|
||||
)
|
||||
)
|
||||
"@
|
||||
|
||||
$listenerOra | Out-File -FilePath "D:\oracle\product\19c\dbhome_1\network\admin\listener.ora" -Encoding ASCII
|
||||
|
||||
# Start listener
|
||||
lsnrctl start
|
||||
|
||||
# Configure listener as Windows service (optional)
|
||||
```
|
||||
|
||||
### Step 2.5: Create Empty Database Template (for faster DR restore)
|
||||
```powershell
|
||||
# Create init parameter file
|
||||
$initROA = @"
|
||||
DB_NAME=ROA
|
||||
DB_BLOCK_SIZE=8192
|
||||
COMPATIBLE=19.0.0
|
||||
MEMORY_TARGET=2G
|
||||
PROCESSES=300
|
||||
OPEN_CURSORS=300
|
||||
DB_RECOVERY_FILE_DEST=D:\oracle\fra
|
||||
DB_RECOVERY_FILE_DEST_SIZE=20G
|
||||
CONTROL_FILES=('D:\oracle\oradata\ROA\control01.ctl','D:\oracle\oradata\ROA\control02.ctl')
|
||||
"@
|
||||
|
||||
$initROA | Out-File -FilePath "D:\oracle\product\19c\dbhome_1\database\initROA.ora" -Encoding ASCII
|
||||
|
||||
# Create directory structure
|
||||
New-Item -ItemType Directory -Path "D:\oracle\oradata\ROA" -Force
|
||||
New-Item -ItemType Directory -Path "D:\oracle\fra" -Force
|
||||
|
||||
# Note: We will NOT create the database now
|
||||
# Database will be created via RMAN RESTORE during DR event
|
||||
```
|
||||
|
||||
**✅ PHASE 2 COMPLETE:** Oracle 19c installed, listener configured, ready for SSH setup
|
||||
|
||||
---
|
||||
|
||||
## 🔐 PHASE 3: CONFIGURE SSH FOR AUTOMATED TRANSFERS (20 minutes)
|
||||
|
||||
### Step 3.1: Install OpenSSH Server
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
|
||||
# Install OpenSSH Server
|
||||
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
|
||||
|
||||
# Start and enable service
|
||||
Start-Service sshd
|
||||
Set-Service -Name sshd -StartupType 'Automatic'
|
||||
|
||||
# Confirm firewall rule
|
||||
Get-NetFirewallRule -Name *ssh*
|
||||
|
||||
# Test SSH from developer machine
|
||||
# ssh Administrator@10.0.20.37
|
||||
```
|
||||
|
||||
### Step 3.2: Configure Passwordless SSH (Key-based Authentication)
|
||||
```powershell
|
||||
# On Windows VM, as Administrator
|
||||
|
||||
# Create .ssh directory
|
||||
$sshDir = "$env:ProgramData\ssh"
|
||||
New-Item -ItemType Directory -Path $sshDir -Force
|
||||
|
||||
# Get public key from PRIMARY server
|
||||
# Option A: Copy manually from PRIMARY C:\Users\Administrator\.ssh\id_rsa.pub
|
||||
# Option B: Download via SCP from developer machine
|
||||
|
||||
# For this example, manually copy the content:
|
||||
# From PRIMARY run: Get-Content C:\Users\Administrator\.ssh\id_rsa.pub
|
||||
|
||||
# On DR Windows VM:
|
||||
$publicKey = "<paste-public-key-here>"
|
||||
$publicKey | Out-File -FilePath "$sshDir\administrators_authorized_keys" -Encoding ASCII
|
||||
|
||||
# Set permissions (CRITICAL for SSH to work)
|
||||
icacls "$sshDir\administrators_authorized_keys" /inheritance:r
|
||||
icacls "$sshDir\administrators_authorized_keys" /grant "SYSTEM:(F)"
|
||||
icacls "$sshDir\administrators_authorized_keys" /grant "BUILTIN\Administrators:(F)"
|
||||
|
||||
# Restart SSH service
|
||||
Restart-Service sshd
|
||||
```
|
||||
|
||||
### Step 3.3: Configure SSH for SYSTEM Account (for scheduled tasks)
|
||||
```powershell
|
||||
# Windows scheduled tasks run as SYSTEM, so we need SYSTEM's SSH key
|
||||
|
||||
# Create SYSTEM's .ssh directory
|
||||
$systemSSHDir = "C:\Windows\System32\config\systemprofile\.ssh"
|
||||
New-Item -ItemType Directory -Path $systemSSHDir -Force
|
||||
|
||||
# Copy the same authorized_keys
|
||||
Copy-Item "$env:ProgramData\ssh\administrators_authorized_keys" `
|
||||
-Destination "$systemSSHDir\authorized_keys" -Force
|
||||
|
||||
# Set permissions
|
||||
icacls "$systemSSHDir\authorized_keys" /inheritance:r
|
||||
icacls "$systemSSHDir\authorized_keys" /grant "SYSTEM:(F)"
|
||||
```
|
||||
|
||||
### Step 3.4: Test SSH Connection from PRIMARY
|
||||
```powershell
|
||||
# On PRIMARY (10.0.20.36), test SSH to DR VM
|
||||
|
||||
# Test 1: Manual connection
|
||||
ssh -i C:\Users\Administrator\.ssh\id_rsa Administrator@10.0.20.37 "echo SSH_OK"
|
||||
|
||||
# Test 2: File transfer
|
||||
echo "test content" > C:\Temp\test.txt
|
||||
scp -i C:\Users\Administrator\.ssh\id_rsa C:\Temp\test.txt Administrator@10.0.20.37:D:\oracle\backups\
|
||||
|
||||
# If successful, you should see the file on DR VM
|
||||
```
|
||||
|
||||
**✅ PHASE 3 COMPLETE:** OpenSSH configured, passwordless authentication working
|
||||
|
||||
---
|
||||
|
||||
## 📝 PHASE 4: UPDATE TRANSFER SCRIPTS (15 minutes)
|
||||
|
||||
### Step 4.1: Modify 02_transfer_to_dr.ps1 for Windows Target
|
||||
```powershell
|
||||
# File: D:\rman_backup\02_transfer_to_dr_windows.ps1
|
||||
# Changes needed:
|
||||
|
||||
# OLD (Linux target):
|
||||
# $DRPath = "/opt/oracle/backups/primary"
|
||||
|
||||
# NEW (Windows target):
|
||||
$DRHost = "10.0.20.37"
|
||||
$DRUser = "Administrator" # Changed from "root"
|
||||
$DRPath = "D:/oracle/backups/primary" # Windows path with forward slashes for SCP
|
||||
$SSHKeyPath = "C:\Users\Administrator\.ssh\id_rsa"
|
||||
|
||||
# Update SSH commands to use Windows paths
|
||||
# Example: Directory creation
|
||||
$null = & ssh -n -i $SSHKeyPath "${DRUser}@${DRHost}" `
|
||||
"New-Item -ItemType Directory -Path '$DRPath' -Force" 2>&1
|
||||
|
||||
# Update cleanup command for Windows
|
||||
function Cleanup-OldBackupsOnDR {
|
||||
Write-Log "Cleaning up old backups on DR (keeping last 2 days)..."
|
||||
|
||||
try {
|
||||
$cleanupCmd = @"
|
||||
Get-ChildItem -Path '$DRPath' -Filter '*.BKP' |
|
||||
Where-Object { `$_.LastWriteTime -lt (Get-Date).AddDays(-2) } |
|
||||
Remove-Item -Force
|
||||
"@
|
||||
$result = & ssh -n -i $SSHKeyPath "${DRUser}@${DRHost}" "powershell -Command `"$cleanupCmd`"" 2>&1
|
||||
|
||||
Write-Log "Cleanup completed on DR"
|
||||
} catch {
|
||||
Write-Log "Cleanup warning: $_" "WARNING"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4.2: Create Updated Transfer Scripts
|
||||
```powershell
|
||||
# Save updated versions:
|
||||
# - 02_transfer_to_dr_windows.ps1 (FULL backup transfer)
|
||||
# - 02b_transfer_incremental_to_dr_windows.ps1 (INCREMENTAL transfer)
|
||||
|
||||
# Key changes for Windows:
|
||||
# 1. DRUser = "Administrator" instead of "root"
|
||||
# 2. DRPath = "D:/oracle/backups/primary" (Windows path)
|
||||
# 3. SSH commands use PowerShell instead of Linux commands
|
||||
# 4. Directory check: Test-Path instead of "test -f"
|
||||
# 5. Cleanup: Get-ChildItem instead of find
|
||||
```
|
||||
|
||||
### Step 4.3: Test Transfer Script
|
||||
```powershell
|
||||
# On PRIMARY, test the new script
|
||||
|
||||
# Manual test
|
||||
D:\rman_backup\02_transfer_to_dr_windows.ps1
|
||||
|
||||
# Check log output
|
||||
Get-Content "D:\rman_backup\logs\transfer_$(Get-Date -Format 'yyyyMMdd').log" -Tail 50
|
||||
|
||||
# Verify on DR VM
|
||||
ssh Administrator@10.0.20.37 "Get-ChildItem D:\oracle\backups\primary"
|
||||
```
|
||||
|
||||
**✅ PHASE 4 COMPLETE:** Transfer scripts updated and tested for Windows target
|
||||
|
||||
---
|
||||
|
||||
## 🔄 PHASE 5: CREATE RMAN RESTORE SCRIPT ON DR VM (30 minutes)
|
||||
|
||||
### Step 5.1: Create RMAN Restore Script
|
||||
```powershell
|
||||
# File: D:\oracle\scripts\rman_restore_from_primary.ps1
|
||||
# Run on DR Windows VM
|
||||
|
||||
param(
|
||||
[string]$BackupPath = "D:\oracle\backups\primary",
|
||||
[string]$OracleHome = "D:\oracle\product\19c\dbhome_1",
|
||||
[string]$OracleBase = "D:\oracle",
|
||||
[string]$DataDir = "D:\oracle\oradata\ROA",
|
||||
[string]$FRADir = "D:\oracle\fra",
|
||||
[int]$DBID = 1363569330,
|
||||
[string]$LogFile = "D:\oracle\logs\restore_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Write-Log {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logLine = "[$timestamp] [$Level] $Message"
|
||||
Write-Host $logLine
|
||||
Add-Content -Path $LogFile -Value $logLine -Encoding UTF8
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Log "======================================================================"
|
||||
Write-Log "Oracle DR Restore - Starting"
|
||||
Write-Log "======================================================================"
|
||||
Write-Log "Backup Path: $BackupPath"
|
||||
Write-Log "Oracle Home: $OracleHome"
|
||||
Write-Log "DBID: $DBID"
|
||||
|
||||
# Set environment
|
||||
$env:ORACLE_HOME = $OracleHome
|
||||
$env:ORACLE_SID = "ROA"
|
||||
$env:PATH = "$OracleHome\bin;$env:PATH"
|
||||
|
||||
# Step 1: Cleanup old database files
|
||||
Write-Log "[1/6] Cleaning old database files..."
|
||||
if (Test-Path $DataDir) {
|
||||
Remove-Item "$DataDir\*" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (Test-Path $FRADir) {
|
||||
Remove-Item "$FRADir\*" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
New-Item -ItemType Directory -Path $DataDir -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $FRADir -Force | Out-Null
|
||||
|
||||
# Step 2: Startup NOMOUNT
|
||||
Write-Log "[2/6] Starting instance in NOMOUNT mode..."
|
||||
$sqlNomount = @"
|
||||
STARTUP NOMOUNT PFILE='$OracleHome\database\initROA.ora';
|
||||
EXIT;
|
||||
"@
|
||||
$sqlNomount | sqlplus / as sysdba
|
||||
|
||||
# Step 3: RMAN Restore
|
||||
Write-Log "[3/6] Running RMAN RESTORE CONTROLFILE..."
|
||||
|
||||
$rmanScript = @"
|
||||
SET DBID $DBID;
|
||||
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
|
||||
# Restore controlfile from autobackup
|
||||
SET CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '$BackupPath/%F';
|
||||
RESTORE CONTROLFILE FROM AUTOBACKUP;
|
||||
}
|
||||
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$rmanScript | rman TARGET /
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "RMAN RESTORE CONTROLFILE failed"
|
||||
}
|
||||
|
||||
# Step 4: Mount database
|
||||
Write-Log "[4/6] Mounting database..."
|
||||
"ALTER DATABASE MOUNT; EXIT;" | sqlplus / as sysdba
|
||||
|
||||
# Step 5: Catalog and restore database
|
||||
Write-Log "[5/6] Cataloging backups and restoring database..."
|
||||
|
||||
$rmanRestore = @"
|
||||
CATALOG START WITH '$BackupPath/' NOPROMPT;
|
||||
|
||||
RUN {
|
||||
SET NEWNAME FOR DATABASE TO '$DataDir\%b';
|
||||
RESTORE DATABASE;
|
||||
SWITCH DATAFILE ALL;
|
||||
RECOVER DATABASE;
|
||||
}
|
||||
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$rmanRestore | rman TARGET /
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "RMAN RESTORE DATABASE failed"
|
||||
}
|
||||
|
||||
# Step 6: Open database RESETLOGS
|
||||
Write-Log "[6/6] Opening database with RESETLOGS..."
|
||||
"ALTER DATABASE OPEN RESETLOGS; EXIT;" | sqlplus / as sysdba
|
||||
|
||||
Write-Log "======================================================================"
|
||||
Write-Log "DR RESTORE COMPLETED SUCCESSFULLY!"
|
||||
Write-Log "======================================================================"
|
||||
Write-Log "Database ROA is now OPEN and ready"
|
||||
|
||||
# Verify
|
||||
Write-Log "Verification:"
|
||||
$verifySQL = @"
|
||||
SELECT name, open_mode, database_role FROM v`$database;
|
||||
EXIT;
|
||||
"@
|
||||
$verifySQL | sqlplus -s / as sysdba
|
||||
|
||||
exit 0
|
||||
|
||||
} catch {
|
||||
Write-Log "CRITICAL ERROR: $($_.Exception.Message)" "ERROR"
|
||||
Write-Log "Stack trace: $($_.ScriptStackTrace)" "ERROR"
|
||||
exit 1
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5.2: Create Quick Test Script
|
||||
```powershell
|
||||
# File: D:\oracle\scripts\test_restore_latest.ps1
|
||||
# Quick test to verify restore works
|
||||
|
||||
$BackupPath = "D:\oracle\backups\primary"
|
||||
$LatestBackup = Get-ChildItem "$BackupPath\*.BKP" |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
Write-Host "Latest backup: $($LatestBackup.Name)"
|
||||
Write-Host "Size: $([math]::Round($LatestBackup.Length / 1GB, 2)) GB"
|
||||
Write-Host "Date: $($LatestBackup.LastWriteTime)"
|
||||
Write-Host ""
|
||||
Write-Host "Ready to test restore? Run:"
|
||||
Write-Host "D:\oracle\scripts\rman_restore_from_primary.ps1"
|
||||
```
|
||||
|
||||
**✅ PHASE 5 COMPLETE:** RMAN restore script created and ready to test
|
||||
|
||||
---
|
||||
|
||||
## 🧪 PHASE 6: TEST DR RESTORE (30 minutes)
|
||||
|
||||
### Step 6.1: Verify Backups Transferred
|
||||
```powershell
|
||||
# On DR Windows VM
|
||||
|
||||
# Check backup files
|
||||
Get-ChildItem D:\oracle\backups\primary\*.BKP |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object Name, @{N='SizeMB';E={[math]::Round($_.Length/1MB,2)}}, LastWriteTime
|
||||
|
||||
# Expected output: 15-20 files (FULL + INCREMENTAL + CONTROLFILE + SPFILE + ARCHIVELOGS)
|
||||
```
|
||||
|
||||
### Step 6.2: Run Test Restore
|
||||
```powershell
|
||||
# IMPORTANT: This will create a live database on DR VM
|
||||
# Make sure PRIMARY is still running (don't confuse them!)
|
||||
|
||||
# Run restore
|
||||
D:\oracle\scripts\rman_restore_from_primary.ps1
|
||||
|
||||
# Monitor progress in log
|
||||
Get-Content "D:\oracle\logs\restore_*.log" -Wait
|
||||
|
||||
# Expected duration: 10-15 minutes
|
||||
```
|
||||
|
||||
### Step 6.3: Verify Database
|
||||
```powershell
|
||||
# Connect to restored database
|
||||
sqlplus sys/romfastsoft@10.0.20.37:1521/ROA as sysdba
|
||||
|
||||
SQL> SELECT name, open_mode FROM v$database;
|
||||
# Expected: ROA, READ WRITE
|
||||
|
||||
SQL> SELECT tablespace_name, status FROM dba_tablespaces;
|
||||
# Expected: SYSTEM, SYSAUX, UNDOTBS, TS_ROA, USERS - all ONLINE
|
||||
|
||||
SQL> SELECT COUNT(*) FROM dba_tables WHERE owner='<your-app-schema>';
|
||||
# Verify application tables restored
|
||||
|
||||
SQL> EXIT;
|
||||
```
|
||||
|
||||
### Step 6.4: Shutdown DR Database (conserve resources)
|
||||
```powershell
|
||||
# After successful test, shutdown database
|
||||
sqlplus / as sysdba
|
||||
|
||||
SQL> SHUTDOWN IMMEDIATE;
|
||||
SQL> EXIT;
|
||||
|
||||
# Stop listener
|
||||
lsnrctl stop
|
||||
|
||||
# Optional: Shutdown Windows VM to conserve resources
|
||||
# (VM will be started only during actual DR events)
|
||||
```
|
||||
|
||||
**✅ PHASE 6 COMPLETE:** DR restore tested and verified working
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ PHASE 7: UPDATE TASK SCHEDULER ON PRIMARY (10 minutes)
|
||||
|
||||
### Step 7.1: Update Scheduled Tasks to Use New Scripts
|
||||
```powershell
|
||||
# On PRIMARY (10.0.20.36)
|
||||
|
||||
# Task 1: FULL Backup + Transfer (already exists, just update transfer script)
|
||||
# Name: "Oracle RMAN Daily Backup + DR Transfer"
|
||||
# Trigger: Daily 02:30 AM
|
||||
# Action 1: Run RMAN backup (unchanged)
|
||||
# Action 2: UPDATE to new script
|
||||
|
||||
# Update task to use new transfer script
|
||||
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
|
||||
-Argument "-NoProfile -ExecutionPolicy Bypass -File D:\rman_backup\02_transfer_to_dr_windows.ps1"
|
||||
|
||||
Set-ScheduledTask -TaskName "Oracle RMAN Daily Backup + DR Transfer" -Action $action
|
||||
|
||||
# Task 2: INCREMENTAL Backup + Transfer
|
||||
# Similar update for incremental task
|
||||
```
|
||||
|
||||
### Step 7.2: Test Scheduled Task Manually
|
||||
```powershell
|
||||
# On PRIMARY
|
||||
|
||||
# Run FULL backup + transfer task manually
|
||||
Start-ScheduledTask -TaskName "Oracle RMAN Daily Backup + DR Transfer"
|
||||
|
||||
# Monitor task status
|
||||
Get-ScheduledTask -TaskName "Oracle RMAN Daily Backup + DR Transfer" |
|
||||
Get-ScheduledTaskInfo
|
||||
|
||||
# Check transfer log
|
||||
Get-Content "D:\rman_backup\logs\transfer_$(Get-Date -Format 'yyyyMMdd').log" -Tail 50
|
||||
|
||||
# Verify on DR
|
||||
ssh Administrator@10.0.20.37 "Get-ChildItem D:\oracle\backups\primary -Filter *.BKP | Measure-Object"
|
||||
```
|
||||
|
||||
**✅ PHASE 7 COMPLETE:** Automated backup and transfer configured
|
||||
|
||||
---
|
||||
|
||||
## 📚 PHASE 8: CREATE DR RUNBOOK (15 minutes)
|
||||
|
||||
### Step 8.1: DR Emergency Procedure
|
||||
```markdown
|
||||
# DISASTER RECOVERY PROCEDURE
|
||||
## When PRIMARY Server (10.0.20.36) Fails
|
||||
|
||||
### PRE-REQUISITES
|
||||
- Proxmox access available
|
||||
- DR Windows VM exists (ID 109)
|
||||
- Latest backups transferred (<24h old)
|
||||
|
||||
### DR ACTIVATION STEPS (RTO: 15-20 minutes)
|
||||
|
||||
1. **Start DR Windows VM (2 minutes)**
|
||||
```
|
||||
Proxmox Web UI → VM 109 (oracle-dr-windows) → Start
|
||||
Wait for Windows to boot
|
||||
Verify network: ping 10.0.20.37
|
||||
```
|
||||
|
||||
2. **Verify Backups Present (1 minute)**
|
||||
```powershell
|
||||
# RDP or Console to 10.0.20.37
|
||||
Get-ChildItem D:\oracle\backups\primary\*.BKP |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object -First 10
|
||||
|
||||
# Verify you see today's or yesterday's backups
|
||||
```
|
||||
|
||||
3. **Run RMAN Restore (12-15 minutes)**
|
||||
```powershell
|
||||
# Run restore script
|
||||
D:\oracle\scripts\rman_restore_from_primary.ps1
|
||||
|
||||
# Monitor log in real-time
|
||||
Get-Content D:\oracle\logs\restore_*.log -Wait
|
||||
```
|
||||
|
||||
4. **Verify Database (2 minutes)**
|
||||
```powershell
|
||||
# Connect to database
|
||||
sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba
|
||||
|
||||
SQL> SELECT name, open_mode FROM v$database;
|
||||
SQL> SELECT tablespace_name, status FROM dba_tablespaces;
|
||||
SQL> -- Verify critical application tables
|
||||
SQL> EXIT;
|
||||
```
|
||||
|
||||
5. **Update Network/DNS (5 minutes)**
|
||||
```
|
||||
- Update DNS: roa-db.example.com → 10.0.20.37
|
||||
- OR: Update application connection strings to 10.0.20.37
|
||||
- Test application connectivity
|
||||
```
|
||||
|
||||
6. **Monitor & Notify**
|
||||
```
|
||||
- Monitor database alert log: D:\oracle\diag\rdbms\roa\ROA\trace\alert_ROA.log
|
||||
- Notify team that DR is active
|
||||
- Document incident timeline
|
||||
```
|
||||
|
||||
### RECOVERY BACK TO PRIMARY (When repaired)
|
||||
|
||||
1. Create fresh RMAN backup from DR (now contains latest data)
|
||||
2. Transfer backup to repaired PRIMARY
|
||||
3. Restore on PRIMARY
|
||||
4. Switch DNS/connections back to PRIMARY
|
||||
5. Shutdown DR VM
|
||||
|
||||
### TESTING SCHEDULE
|
||||
- Monthly DR test: Last Sunday of month
|
||||
- Test duration: 30 minutes
|
||||
- Document test results
|
||||
```
|
||||
|
||||
**✅ PHASE 8 COMPLETE:** DR runbook documented
|
||||
|
||||
---
|
||||
|
||||
## 📊 FINAL ARCHITECTURE
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ PRODUCTION ENVIRONMENT │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ PRIMARY (10.0.20.36) - Windows Physical Server │
|
||||
│ ├─ Oracle 19c SE2 │
|
||||
│ ├─ Database: ROA │
|
||||
│ ├─ RMAN Backups: │
|
||||
│ │ ├─ FULL: Daily 02:30 AM (~7GB compressed) │
|
||||
│ │ └─ INCREMENTAL: Daily 14:00 (~50MB) │
|
||||
│ └─ Automatic Transfer to DR via SSH/SCP │
|
||||
│ │
|
||||
│ ↓ SSH Transfer │
|
||||
│ ↓ (950 Mbps) │
|
||||
│ ↓ │
|
||||
│ DR (10.0.20.37) - Windows VM in Proxmox (ID 109) │
|
||||
│ ├─ Oracle 19c SE2 (installed, ready) │
|
||||
│ ├─ VM State: POWERED OFF (0 RAM consumption) │
|
||||
│ ├─ Backups: D:\oracle\backups\primary │
|
||||
│ ├─ Storage: 100 GB (OS + Oracle + backups) │
|
||||
│ └─ Restore Script: D:\oracle\scripts\rman_restore... │
|
||||
│ │
|
||||
│ DR ACTIVATION (when needed): │
|
||||
│ ├─ 1. Power ON VM (2 min) │
|
||||
│ ├─ 2. Run restore script (12 min) │
|
||||
│ ├─ 3. Database OPEN (1 min) │
|
||||
│ └─ TOTAL RTO: ~15 minutes │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
METRICS (Current Implementation):
|
||||
- RPO: 24 hours (only FULL backup used; incremental causes UNDO corruption)
|
||||
- RTO: 15 minutes
|
||||
- Storage: 500 GB VM + backups on host
|
||||
- Daily resources: ZERO (VM powered off)
|
||||
- DR test: Weekly (planned)
|
||||
|
||||
METRICS (After Upgrade to CUMULATIVE):
|
||||
- RPO: 3-4 hours (FULL + latest CUMULATIVE)
|
||||
- RTO: 15 minutes (unchanged)
|
||||
- Storage: 500 GB VM + ~15 GB on Proxmox host
|
||||
- Daily resources: ZERO (VM powered off)
|
||||
- DR test: Weekly (automated)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ POST-IMPLEMENTATION CHECKLIST
|
||||
|
||||
### Phase 1-8 (Initial Setup) - ✅ COMPLETED 2025-10-09
|
||||
|
||||
- [x] Windows VM created in Proxmox (VM ID 109, IP 10.0.20.37)
|
||||
- [x] Oracle 19c SE2 installed and working
|
||||
- [x] OpenSSH Server configured with passwordless authentication
|
||||
- [x] Transfer scripts updated and tested (FULL backup)
|
||||
- [x] RMAN restore script created on DR VM
|
||||
- [x] DR restore tested successfully (database opens and is usable)
|
||||
- [x] Scheduled tasks on PRIMARY verified
|
||||
- [x] DR procedures documented
|
||||
- [x] VM shutdown after testing (to conserve resources)
|
||||
|
||||
### Phase 9 (Upgrade to CUMULATIVE) - 📋 PLANNED
|
||||
|
||||
**See:** `DR_UPGRADE_TO_CUMULATIVE_PLAN.md` for detailed implementation steps
|
||||
|
||||
- [ ] Proxmox host storage configured (`/mnt/pve/oracle-backups`)
|
||||
- [ ] VM 109 mount point configured (E:\ from host)
|
||||
- [ ] RMAN script updated to CUMULATIVE incremental
|
||||
- [ ] Transfer scripts updated to send to Proxmox host
|
||||
- [ ] SSH key for Proxmox host access configured
|
||||
- [ ] Scheduled task created for 13:00 CUMULATIVE backup
|
||||
- [ ] Scheduled task created for 18:00 CUMULATIVE backup
|
||||
- [ ] Existing 14:00 task removed
|
||||
- [ ] 02:30 FULL task updated to use new transfer script
|
||||
- [ ] DR restore script updated for cumulative backups
|
||||
- [ ] End-to-end restore test with CUMULATIVE successful
|
||||
- [ ] Weekly test script created and scheduled
|
||||
- [ ] Team trained on new backup strategy
|
||||
|
||||
---
|
||||
|
||||
## 🔧 TROUBLESHOOTING GUIDE
|
||||
|
||||
### Issue: SSH Connection Fails
|
||||
```powershell
|
||||
# Check 1: SSH service running?
|
||||
Get-Service sshd
|
||||
|
||||
# Check 2: Firewall blocking?
|
||||
Get-NetFirewallRule -Name *ssh*
|
||||
|
||||
# Check 3: Authorized keys permissions?
|
||||
icacls "C:\ProgramData\ssh\administrators_authorized_keys"
|
||||
|
||||
# Check 4: Test from PRIMARY
|
||||
ssh -v Administrator@10.0.20.37
|
||||
```
|
||||
|
||||
### Issue: RMAN Restore Fails "CONTROLFILE not found"
|
||||
```
|
||||
# This is the cross-platform issue!
|
||||
# Solution: Ensure you're using Windows→Windows (same platform)
|
||||
# Check Oracle version matches: 19c on both sides
|
||||
```
|
||||
|
||||
### Issue: Database Won't Start
|
||||
```powershell
|
||||
# Check alert log
|
||||
Get-Content D:\oracle\diag\rdbms\roa\ROA\trace\alert_ROA.log -Tail 100
|
||||
|
||||
# Check parameter file
|
||||
Get-Content D:\oracle\product\19c\dbhome_1\database\initROA.ora
|
||||
|
||||
# Verify directories exist
|
||||
Test-Path D:\oracle\oradata\ROA
|
||||
Test-Path D:\oracle\fra
|
||||
```
|
||||
|
||||
### Issue: VM Uses Too Much Disk
|
||||
```powershell
|
||||
# Check backup retention
|
||||
Get-ChildItem D:\oracle\backups\primary\*.BKP |
|
||||
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-3) } |
|
||||
Remove-Item -Force
|
||||
|
||||
# Check FRA usage
|
||||
SELECT * FROM V$RECOVERY_FILE_DEST;
|
||||
|
||||
# Cleanup old archives
|
||||
RMAN> DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-2';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 SUPPORT & REFERENCES
|
||||
|
||||
### Oracle Documentation
|
||||
- RMAN Backup and Recovery: https://docs.oracle.com/en/database/oracle/oracle-database/19/bradv/
|
||||
- Cross-Platform Migration: https://docs.oracle.com/en/database/oracle/oracle-database/19/spmds/
|
||||
- Windows Installation: https://docs.oracle.com/en/database/oracle/oracle-database/19/ntqrf/
|
||||
|
||||
### Internal Scripts
|
||||
- PRIMARY RMAN backup: D:\rman_backup\rman_backup.txt
|
||||
- Transfer script (FULL): D:\rman_backup\02_transfer_to_dr_windows.ps1
|
||||
- Transfer script (INCREMENTAL): D:\rman_backup\02b_transfer_incremental_to_dr_windows.ps1
|
||||
- DR restore script: D:\oracle\scripts\rman_restore_from_primary.ps1 (on DR VM)
|
||||
|
||||
### Logs Location
|
||||
- PRIMARY transfer logs: D:\rman_backup\logs\
|
||||
- DR restore logs: D:\oracle\logs\
|
||||
- Oracle alert log: D:\oracle\diag\rdbms\roa\ROA\trace\alert_ROA.log
|
||||
|
||||
---
|
||||
|
||||
## 🎯 IMPLEMENTATION TIMELINE
|
||||
|
||||
| Phase | Task | Duration | Responsible |
|
||||
|-------|------|----------|-------------|
|
||||
| 1 | Create Windows VM in Proxmox | 30 min | Infrastructure Admin |
|
||||
| 2 | Install Oracle 19c | 90 min | DBA |
|
||||
| 3 | Configure SSH | 20 min | Infrastructure Admin |
|
||||
| 4 | Update Transfer Scripts | 15 min | DBA |
|
||||
| 5 | Create Restore Script | 30 min | DBA |
|
||||
| 6 | Test DR Restore | 30 min | DBA |
|
||||
| 7 | Update Scheduled Tasks | 10 min | DBA |
|
||||
| 8 | Document DR Runbook | 15 min | DBA |
|
||||
| **TOTAL** | | **~4 hours** | |
|
||||
|
||||
**Note:** This is one-time setup. After completion, daily operations are fully automated with ZERO maintenance overhead.
|
||||
|
||||
---
|
||||
|
||||
**Generated:** 2025-10-08
|
||||
**Last Updated:** 2025-10-09
|
||||
**Version:** 2.0
|
||||
**Status:** ✅ Phase 1-8 COMPLETED | 📋 Phase 9 (CUMULATIVE upgrade) PLANNED
|
||||
**Implementation Status:**
|
||||
- Initial setup (Phases 1-8): ✅ COMPLETED 2025-10-09
|
||||
- RMAN restore tested: ✅ SUCCESSFUL (12-15 minutes RTO)
|
||||
- Current RPO: 24 hours (FULL backup only)
|
||||
- Next: Upgrade to CUMULATIVE incremental for 3-4 hour RPO
|
||||
|
||||
**Next Session:** Implement CUMULATIVE backup strategy
|
||||
**See:** `DR_UPGRADE_TO_CUMULATIVE_PLAN.md` for upgrade plan
|
||||
|
||||
@@ -0,0 +1,789 @@
|
||||
# Oracle DR Windows VM - Implementation Status
|
||||
**Date:** 2025-10-09 04:00 AM
|
||||
**VM:** 109 (oracle-dr-windows)
|
||||
**Location:** Proxmox pveelite (10.0.20.202)
|
||||
**IP:** 10.0.20.37
|
||||
**Purpose:** Replace Linux LXC DR with Windows VM for same-platform RMAN restore
|
||||
|
||||
---
|
||||
|
||||
## ✅ COMPLETED TASKS
|
||||
|
||||
### 1. VM Creation and Network ✅
|
||||
- **VM ID:** 109 on pveelite (10.0.20.202)
|
||||
- **Template source:** Win11-Template (ID 300) from pvemini (10.0.20.201)
|
||||
- **Cloned and migrated:** Successfully migrated from pvemini to pveelite
|
||||
- **Resources configured:**
|
||||
- RAM: 6GB
|
||||
- CPU: 4 cores
|
||||
- Disk: 500GB (local-zfs)
|
||||
- Boot on startup: NO (VM stays off until DR event)
|
||||
- **Network:**
|
||||
- Static IP: 10.0.20.37
|
||||
- Gateway: 10.0.20.1
|
||||
- DNS: 10.0.20.1, 8.8.8.8
|
||||
- Windows Firewall: Disabled
|
||||
- Connectivity: ✅ Verified (ping successful)
|
||||
|
||||
### 2. Windows Configuration ✅
|
||||
- **Computer name:** ORACLE-DR
|
||||
- **Timezone:** GTB Standard Time (Romania)
|
||||
- **Hibernation:** Disabled
|
||||
- **Administrator profile:** Fixed (C:\Users\Administrator)
|
||||
- **Auto-login:** Disabled
|
||||
|
||||
### 3. Users Created ✅
|
||||
| User | Password | Admin | Hidden from Login | Purpose |
|
||||
|------|----------|-------|-------------------|---------|
|
||||
| romfast | Romfast2025! | Yes | Yes | SSH access, backup transfers |
|
||||
| silvia | Silvia2025! | No | Yes | SSH tunnels (2 ports) |
|
||||
| eli | Eli2025! | No | Yes | SSH tunnels (4 ports) |
|
||||
|
||||
### 4. OpenSSH Server Configuration ✅
|
||||
- **Port:** 22122
|
||||
- **Service:** Running, Automatic startup
|
||||
- **Authentication:** ✅ **SSH Key Authentication WORKING**
|
||||
- User key: `mmarius28@gmail.com` (for manual SSH from Linux)
|
||||
- SYSTEM key: `administrator@ROA-CARAPETRU2` (for automated backup transfers from PRIMARY)
|
||||
|
||||
**SSH Config:** `C:\ProgramData\ssh\sshd_config`
|
||||
```
|
||||
Port 22122
|
||||
ListenAddress 0.0.0.0
|
||||
PubkeyAuthentication yes
|
||||
PasswordAuthentication yes
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
AllowTcpForwarding yes
|
||||
GatewayPorts yes
|
||||
|
||||
Match User romfast
|
||||
PermitOpen localhost:80 localhost:1521 localhost:3000 localhost:3001 localhost:3389 localhost:8006 localhost:8080 localhost:81 localhost:9443 localhost:22
|
||||
|
||||
Match User silvia
|
||||
PermitOpen localhost:80 localhost:1521
|
||||
|
||||
Match User eli
|
||||
PermitOpen localhost:80 localhost:1521 localhost:3000
|
||||
|
||||
Match Group administrators
|
||||
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
|
||||
```
|
||||
|
||||
**SSH Keys Configured:**
|
||||
- File: `C:\ProgramData\ssh\administrators_authorized_keys`
|
||||
- Contains 2 keys:
|
||||
1. `ssh-rsa ...mmarius28@gmail.com` (your Linux workstation)
|
||||
2. `ssh-rsa ...administrator@ROA-CARAPETRU2` (PRIMARY SYSTEM user for automated transfers)
|
||||
- Permissions: SYSTEM (Full Control), Administrators (Read)
|
||||
- Status: ✅ Both keys working
|
||||
|
||||
**Fix Script:** `D:\oracle\scripts\fix_ssh_via_service.ps1`
|
||||
- Stops SSH service
|
||||
- Recreates authorized_keys with both keys
|
||||
- Sets correct permissions using `icacls`
|
||||
- Restarts SSH service
|
||||
|
||||
### 5. Oracle 19c Installation ✅
|
||||
- **Status:** ✅ Installed (interactive GUI installation)
|
||||
- **ORACLE_HOME:** `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home`
|
||||
- **ORACLE_BASE:** `C:\Users\oracle`
|
||||
- **Edition:** Standard Edition 2 (SE2)
|
||||
- **Version:** 19.3.0.0.0
|
||||
- **Installation Type:** Software Only (no database created yet)
|
||||
- **Oracle User:** `oracle` (password: Oracle2025!)
|
||||
|
||||
**Verification:**
|
||||
```powershell
|
||||
$env:ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
|
||||
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
|
||||
sqlplus -v # Returns: SQL*Plus: Release 19.0.0.0.0 - Production
|
||||
```
|
||||
|
||||
### 6. Oracle Listener Configuration ✅
|
||||
- **Script:** `D:\oracle\scripts\configure_listener_dr.ps1`
|
||||
- **Status:** ✅ Configured and Running
|
||||
- **Port:** 1521
|
||||
- **Service:** OracleOraDB19Home1TNSListener
|
||||
|
||||
**Configuration Files Created:**
|
||||
- `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home\network\admin\listener.ora`
|
||||
- `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home\network\admin\tnsnames.ora`
|
||||
- `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home\network\admin\sqlnet.ora`
|
||||
|
||||
**Listener Status:**
|
||||
```
|
||||
LSNRCTL for 64-bit Windows: Version 19.0.0.0.0 - Production
|
||||
STATUS of the LISTENER
|
||||
Alias LISTENER
|
||||
Version TNSLSNR for 64-bit Windows: Version 19.0.0.0.0 - Production
|
||||
Start Date 09-OCT-2025 03:18:34
|
||||
Listening Endpoints Summary...
|
||||
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.0.20.37)(PORT=1521)))
|
||||
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
|
||||
Services Summary...
|
||||
Service "ROA" has 1 instance(s).
|
||||
Instance "ROA", status UNKNOWN, has 1 handler(s) for this service...
|
||||
```
|
||||
|
||||
### 7. Directory Structure Created ✅
|
||||
```
|
||||
C:\Users\oracle\
|
||||
├── oradata\ROA\ (will be created by RMAN restore)
|
||||
├── recovery_area\ROA\ (FRA - Fast Recovery Area)
|
||||
├── admin\ROA\
|
||||
│ ├── adump\ (audit files)
|
||||
│ ├── dpdump\ (data pump)
|
||||
│ └── pfile\ (initialization files)
|
||||
└── oraInventory\ (Oracle inventory)
|
||||
|
||||
D:\oracle\
|
||||
├── backups\primary\ ✅ (6.32 GB backup files transferred)
|
||||
├── scripts\ ✅ (DR automation scripts)
|
||||
└── logs\ ✅ (restore logs)
|
||||
```
|
||||
|
||||
### 8. Backup Transfer Scripts Updated ✅
|
||||
**Location on PRIMARY:** `D:\rman_backup\`
|
||||
|
||||
**Scripts Updated:**
|
||||
1. **transfer_to_dr.ps1** - Transfer FULL backups
|
||||
2. **transfer_incremental.ps1** - Transfer INCREMENTAL backups
|
||||
|
||||
**Changes Made:**
|
||||
- ✅ DRHost: `10.0.20.37`
|
||||
- ✅ DRPort: `22122` (added)
|
||||
- ✅ DRUser: `romfast` (changed from `root`)
|
||||
- ✅ DRPath: `D:/oracle/backups/primary` (changed from `/opt/oracle/backups/primary`)
|
||||
- ✅ All SSH commands updated with `-p 22122`
|
||||
- ✅ Linux commands replaced with Windows PowerShell equivalents:
|
||||
- `test -f` → `powershell -Command "Test-Path ..."`
|
||||
- `mkdir -p` → `powershell -Command "New-Item -ItemType Directory ..."`
|
||||
- `find ... -delete` → `powershell -Command "Get-ChildItem ... | Remove-Item ..."`
|
||||
|
||||
**Backup Files Transferred:** ✅ **6 files, 6.32 GB total**
|
||||
```
|
||||
D:\oracle\backups\primary\
|
||||
├── O1_MF_NNND0_DAILY_FULL_COMPRESSE_NGFVB4B8_.BKP (4.81 GB) # FULL backup
|
||||
├── O1_MF_ANNNN_DAILY_FULL_COMPRESSE_NGFV7RGN_.BKP (1.51 GB) # FULL backup
|
||||
├── O1_MF_NCNNF_TAG20251009T020551_NGFVLJTG_.BKP (1.14 MB) # Control file
|
||||
├── O1_MF_S_1214013953_NGFVLL29_.BKP (1.14 MB) # SPFILE autobackup
|
||||
├── O1_MF_NNSNF_TAG20251009T020550_NGFVLGOR_.BKP (112 KB)
|
||||
└── O1_MF_ANNNN_DAILY_FULL_COMPRESSE_NGFVLFKN_.BKP (861 KB)
|
||||
```
|
||||
|
||||
**Transfer Log:** `D:\rman_backup\logs\transfer_20251009.log`
|
||||
```
|
||||
[2025-10-09 03:52:13] [SUCCESS] SSH connection successful
|
||||
[2025-10-09 03:52:14] [INFO] Found 6 files, total size: 6.32 GB
|
||||
[2025-10-09 03:57:27] [INFO] Files transferred: 6/6
|
||||
```
|
||||
|
||||
### 9. DR Scripts Created ✅
|
||||
All scripts located in: `/mnt/e/proiecte/ROMFASTSQL/oracle/standby-server-scripts/`
|
||||
|
||||
**Installation Scripts:**
|
||||
1. ✅ `install_oracle19c_dr.ps1` - Oracle 19c installation (software only)
|
||||
2. ✅ `configure_listener_dr.ps1` - Oracle Listener configuration
|
||||
|
||||
**SSH Configuration Scripts:**
|
||||
3. ✅ `fix_ssh_key_auth.ps1` - Initial SSH key setup attempt
|
||||
4. ✅ `fix_ssh_key_auth_simple.cmd` - Simple command-line version
|
||||
5. ✅ `fix_ssh_via_service.ps1` - **WORKING** - Fixes SSH keys by stopping service
|
||||
|
||||
**Backup Transfer Scripts (on PRIMARY):**
|
||||
6. ✅ `transfer_to_dr.ps1` - Full backup transfer (updated for Windows)
|
||||
7. ✅ `transfer_incremental.ps1` - Incremental backup transfer (updated for Windows)
|
||||
8. ✅ `transfer_to_dr_windows.ps1` - Reference implementation
|
||||
|
||||
**Restore Script:**
|
||||
9. ✅ `rman_restore_from_primary.ps1` - RMAN restore script (ready to test)
|
||||
|
||||
**Helper Scripts:**
|
||||
10. ✅ `copy_system_ssh_key.ps1` - Extract SYSTEM user SSH key from PRIMARY
|
||||
11. ✅ `add_system_key_dr.ps1` - Add SYSTEM key to DR VM
|
||||
|
||||
---
|
||||
|
||||
## ✅ RMAN RESTORE COMPLETED - 2025-10-09 17:40
|
||||
|
||||
### 10. RMAN Restore End-to-End Test ✅ **COMPLETED**
|
||||
|
||||
**Final Status:** ✅ **DATABASE SUCCESSFULLY RESTORED AND OPEN**
|
||||
- Database: ROA
|
||||
- Mode: READ WRITE
|
||||
- Instance: OPEN
|
||||
- Tablespaces: 6 (all ONLINE)
|
||||
- Datafiles: 5
|
||||
- Application Owners: 69
|
||||
- Total Application Tables: 45,000+
|
||||
|
||||
**Session Duration:** ~5 hours (including troubleshooting)
|
||||
**Actual Restore Time:** ~15-20 minutes (datafiles + recovery)
|
||||
**Total Data Restored:** 6.32 GB compressed → ~15 GB uncompressed
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CRITICAL ISSUES ENCOUNTERED & RESOLUTIONS
|
||||
|
||||
### Issue 1: Incremental Backup Corruption ⚠️ → ✅ RESOLVED
|
||||
**Problem:** Applying DIFFERENTIAL incremental backup (MIDDAY_INCREMENTAL from 14:00) caused UNDO tablespace corruption
|
||||
- Error: ORA-30012: undo tablespace 'UNDOTBS01' does not exist or of wrong type
|
||||
- Error: ORA-00603: ORACLE server session terminated by fatal error
|
||||
- Database crashed immediately after OPEN RESETLOGS attempt
|
||||
|
||||
**Root Cause:** DIFFERENTIAL incremental backup applied on top of FULL backup created inconsistent UNDO state
|
||||
|
||||
**Initial Workaround:** Restore only FULL backup without applying incremental
|
||||
|
||||
**Permanent Solution:** ✅ **Upgrade to CUMULATIVE incremental backups**
|
||||
- CUMULATIVE backups are independent from Level 0 (no dependency chain)
|
||||
- Each CUMULATIVE contains ALL changes since last Level 0
|
||||
- Eliminates UNDO/SCN mismatch issues
|
||||
- **See:** `DR_UPGRADE_TO_CUMULATIVE_PLAN.md` for implementation plan
|
||||
|
||||
### Issue 2: Control File SCN Mismatch 🔴
|
||||
**Problem:** ORA-01190: control file or data file 1 is from before the last RESETLOGS
|
||||
- Control file autobackup (`O1_MF_S_1214013953_NGFVLL29_.BKP`) created AFTER datafiles backup
|
||||
- SCN in control file was higher than SCN in datafiles
|
||||
- Error: ORA-01152: file 1 was not restored from a sufficiently old backup
|
||||
|
||||
**Root Cause:** Used SPFILE/Controlfile AUTOBACKUP instead of control file from same backup piece as datafiles
|
||||
|
||||
**Resolution:**
|
||||
1. Restore control file from SAME backup as datafiles: `O1_MF_NCNNF_TAG20251009T020551_NGFVLJTG_.BKP`
|
||||
2. This control file has matching SCN with datafiles (both from 02:05:51 backup)
|
||||
|
||||
### Issue 3: ORA-16433 Recovery Loop 🔄
|
||||
**Problem:** ORA-16433: The database or pluggable database must be opened in read/write mode
|
||||
- Occurred during RECOVER DATABASE attempts
|
||||
- Error appeared in both SQL*Plus and RMAN
|
||||
- Recovery session canceled due to errors
|
||||
|
||||
**Root Cause:**
|
||||
- Bug 14744052: Flag set in control file during incomplete RESETLOGS
|
||||
- Using `SET UNTIL SCN 999999999999` in RMAN caused invalid recovery state
|
||||
- Standard Edition limitations with recovery operations
|
||||
|
||||
**Resolution:**
|
||||
1. Remove `SET UNTIL SCN` from RMAN script
|
||||
2. Use `SET UNTIL TIME` with specific backup completion time
|
||||
3. Let RMAN auto-detect and apply only available archive logs
|
||||
4. Incomplete recovery flag properly set by stopping at missing archive log
|
||||
|
||||
### Issue 4: Memory Configuration ⚠️
|
||||
**Problem:** ORA-27104: system-defined limits for shared memory was misconfigured
|
||||
- Initial PFILE had `memory_target=1536M`
|
||||
- VM has 6GB RAM but Windows reserved ~2GB
|
||||
- Database startup failed in NOMOUNT
|
||||
|
||||
**Resolution:**
|
||||
Reduced memory settings in PFILE:
|
||||
```
|
||||
memory_target=1024M
|
||||
memory_max_target=1024M
|
||||
```
|
||||
|
||||
### Issue 5: Backup Location Issues 📁
|
||||
**Initial Setup:** Backups in `D:\oracle\backups\primary` (custom path)
|
||||
- RMAN couldn't auto-detect backups
|
||||
- Had to specify explicit paths for all operations
|
||||
- Control file autobackup search failed
|
||||
|
||||
**Final Solution:**
|
||||
1. Moved all backups to FRA: `C:\Users\oracle\recovery_area\ROA\autobackup`
|
||||
2. Updated PRIMARY transfer scripts to use FRA path
|
||||
3. RMAN now auto-detects all backups via CATALOG command
|
||||
4. Simplified restore procedure significantly
|
||||
|
||||
---
|
||||
|
||||
## 📋 WORKING RMAN RESTORE PROCEDURE
|
||||
|
||||
### Prerequisites ✅ ALL COMPLETE
|
||||
- ✅ Oracle 19c installed on DR VM
|
||||
- ✅ Listener configured and running
|
||||
- ✅ FULL backup transferred from PRIMARY to FRA location
|
||||
- ✅ OracleServiceROA Windows service created
|
||||
- ✅ Backups moved to: `C:\Users\oracle\recovery_area\ROA\autobackup`
|
||||
|
||||
### Step-by-Step Manual Procedure (Tested and Verified)
|
||||
|
||||
**1. Prepare PFILE (Modified for DR)**
|
||||
Location: `C:\Users\oracle\admin\ROA\pfile\initROA.ora`
|
||||
```ini
|
||||
db_name=ROA
|
||||
memory_target=1024M
|
||||
memory_max_target=1024M
|
||||
processes=150
|
||||
undo_management=MANUAL
|
||||
compatible=19.0.0
|
||||
control_files=('C:\Users\oracle\oradata\ROA\control01.ctl', 'C:\Users\oracle\recovery_area\ROA\control02.ctl')
|
||||
db_block_size=8192
|
||||
db_recovery_file_dest=C:\Users\Oracle\recovery_area
|
||||
db_recovery_file_dest_size=10G
|
||||
diagnostic_dest=C:\Users\oracle
|
||||
```
|
||||
|
||||
**2. Shutdown Database (if running)**
|
||||
```cmd
|
||||
set ORACLE_HOME=C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home
|
||||
set ORACLE_SID=ROA
|
||||
set PATH=%ORACLE_HOME%\bin;%PATH%
|
||||
|
||||
sqlplus / as sysdba
|
||||
SHUTDOWN ABORT;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
**3. Startup NOMOUNT**
|
||||
```sql
|
||||
STARTUP NOMOUNT PFILE='C:\Users\oracle\admin\ROA\pfile\initROA.ora';
|
||||
EXIT;
|
||||
```
|
||||
|
||||
**4. Connect to RMAN and Restore Control File**
|
||||
```cmd
|
||||
rman target /
|
||||
|
||||
SET DBID 1363569330;
|
||||
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
RESTORE CONTROLFILE FROM 'C:/Users/oracle/recovery_area/ROA/autobackup/O1_MF_NCNNF_TAG20251009T020551_NGFVLJTG_.BKP';
|
||||
RELEASE CHANNEL ch1;
|
||||
}
|
||||
|
||||
ALTER DATABASE MOUNT;
|
||||
```
|
||||
|
||||
**5. Catalog Backups in FRA**
|
||||
```rman
|
||||
CATALOG START WITH 'C:/Users/oracle/recovery_area/ROA/autobackup' NOPROMPT;
|
||||
```
|
||||
|
||||
**6. Restore and Recover Database**
|
||||
```rman
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK;
|
||||
SET UNTIL TIME "TO_DATE('09-OCT-2025 02:05:51','DD-MON-YYYY HH24:MI:SS')";
|
||||
RESTORE DATABASE;
|
||||
RECOVER DATABASE;
|
||||
RELEASE CHANNEL ch1;
|
||||
RELEASE CHANNEL ch2;
|
||||
}
|
||||
```
|
||||
|
||||
**7. Open Database with RESETLOGS**
|
||||
```rman
|
||||
ALTER DATABASE OPEN RESETLOGS;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
**8. Create TEMP Tablespace**
|
||||
```sql
|
||||
sqlplus / as sysdba
|
||||
|
||||
ALTER TABLESPACE TEMP ADD TEMPFILE 'C:\Users\oracle\oradata\ROA\temp01.dbf'
|
||||
SIZE 567M REUSE AUTOEXTEND ON NEXT 640K MAXSIZE 32767M;
|
||||
|
||||
EXIT;
|
||||
```
|
||||
|
||||
**9. Verify Database Status**
|
||||
```sql
|
||||
sqlplus / as sysdba
|
||||
|
||||
SELECT NAME, OPEN_MODE, LOG_MODE FROM V$DATABASE;
|
||||
SELECT INSTANCE_NAME, STATUS FROM V$INSTANCE;
|
||||
SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES ORDER BY TABLESPACE_NAME;
|
||||
SELECT COUNT(*) AS DATAFILE_COUNT FROM DBA_DATA_FILES;
|
||||
|
||||
SELECT OWNER, COUNT(*) AS TABLE_COUNT
|
||||
FROM DBA_TABLES
|
||||
WHERE OWNER NOT IN ('SYS','SYSTEM','OUTLN','MDSYS','CTXSYS','XDB','WMSYS','OLAPSYS',
|
||||
'ORDDATA','ORDSYS','EXFSYS','LBACSYS','DBSNMP','APPQOSSYS','GSMADMIN_INTERNAL')
|
||||
GROUP BY OWNER
|
||||
ORDER BY OWNER;
|
||||
|
||||
EXIT;
|
||||
```
|
||||
|
||||
### Expected Results ✅ VERIFIED
|
||||
|
||||
**Database Status:**
|
||||
```
|
||||
NAME: ROA
|
||||
OPEN_MODE: READ WRITE
|
||||
LOG_MODE: ARCHIVELOG
|
||||
INSTANCE_NAME: ROA
|
||||
STATUS: OPEN
|
||||
```
|
||||
|
||||
**Tablespaces:**
|
||||
```
|
||||
SYSAUX ONLINE
|
||||
SYSTEM ONLINE
|
||||
TEMP ONLINE
|
||||
TS_ROA ONLINE
|
||||
UNDOTBS01 ONLINE
|
||||
USERS ONLINE
|
||||
```
|
||||
|
||||
**Data Verification:**
|
||||
- Datafiles: 5 (excluding TEMP)
|
||||
- Application Owners: 69
|
||||
- Application Tables: 45,000+
|
||||
|
||||
**Performance Metrics:**
|
||||
- NOMOUNT to MOUNT: ~30 seconds
|
||||
- Control file restore: ~10 seconds
|
||||
- Catalog backups: ~20 seconds
|
||||
- Database restore: ~8-10 minutes
|
||||
- Database recovery: ~2-3 minutes
|
||||
- OPEN RESETLOGS: ~1 minute
|
||||
- **Total Time: ~12-15 minutes**
|
||||
|
||||
### Automated Script Version
|
||||
|
||||
**Script:** `rman_restore_final.cmd`
|
||||
Location: `/mnt/e/proiecte/ROMFASTSQL/oracle/standby-server-scripts/rman_restore_final.cmd`
|
||||
|
||||
This CMD script automates all the above steps. Run on DR VM as Administrator:
|
||||
```cmd
|
||||
D:\oracle\scripts\rman_restore_final.cmd
|
||||
```
|
||||
|
||||
The script will:
|
||||
1. Shutdown database if running
|
||||
2. Startup NOMOUNT with correct PFILE
|
||||
3. Restore control file from correct backup piece (not autobackup)
|
||||
4. Mount database
|
||||
5. Catalog all backups in FRA
|
||||
6. Restore database with 2 parallel channels
|
||||
7. Recover database with NOREDO (no incremental)
|
||||
8. Open with RESETLOGS
|
||||
9. Create TEMP tablespace
|
||||
10. Verify database status
|
||||
|
||||
Log file: `D:\oracle\logs\rman_restore_final.log`
|
||||
|
||||
### 11. Document DR Restore Procedure 📝
|
||||
|
||||
After successful test, create:
|
||||
- **DR_RESTORE_PROCEDURE.md** - Step-by-step restore instructions
|
||||
- **DR_RUNBOOK.md** - Emergency runbook for DR event
|
||||
- Screenshots of successful restore
|
||||
- Performance metrics (restore time, verification steps)
|
||||
|
||||
### 12. Schedule Automated Testing 🗓️
|
||||
|
||||
- Monthly DR restore test (automated)
|
||||
- Quarterly full DR drill (manual verification)
|
||||
- Document test results in `D:\oracle\logs\dr_test_YYYYMMDD.log`
|
||||
|
||||
---
|
||||
|
||||
## 📋 PRIMARY SERVER CONFIGURATION (Reference)
|
||||
|
||||
**Server:** 10.0.20.36 (Windows Server)
|
||||
**Oracle Version:** 19c SE2 (19.3.0.0.0)
|
||||
**Database:** ROA, DBID: 1363569330, **non-CDB** (traditional architecture)
|
||||
|
||||
**Paths:**
|
||||
- ORACLE_HOME: `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home`
|
||||
- ORACLE_BASE: `C:\Users\oracle`
|
||||
- Datafiles: `C:\Users\oracle\oradata\ROA\`
|
||||
- SYSTEM01.DBF
|
||||
- SYSAUX01.DBF
|
||||
- UNDOTBS01.DBF
|
||||
- TS_ROA.DBF (application tablespace)
|
||||
- USERS01.DBF
|
||||
- TEMP01.DBF (567 MB)
|
||||
- Control Files:
|
||||
- `C:\Users\oracle\oradata\ROA\control01.ctl`
|
||||
- `C:\Users\oracle\recovery_area\ROA\control02.ctl`
|
||||
- Redo Logs:
|
||||
- GROUP 1: `C:\Users\oracle\oradata\ROA\REDO01.LOG` (200 MB)
|
||||
- GROUP 2: `C:\Users\oracle\oradata\ROA\REDO02.LOG` (200 MB)
|
||||
- GROUP 3: `C:\Users\oracle\oradata\ROA\REDO03.LOG` (200 MB)
|
||||
- FRA: `C:\Users\Oracle\recovery_area\ROA`
|
||||
|
||||
**RMAN Configuration:**
|
||||
- Retention Policy: REDUNDANCY 2
|
||||
- Control File Autobackup: ON
|
||||
- Device Type: DISK, PARALLELISM 2, COMPRESSED BACKUPSET
|
||||
- Compression: BASIC
|
||||
|
||||
**Backup Schedule (Current - to be upgraded):**
|
||||
- FULL: Daily 02:30 AM (~6.32 GB compressed)
|
||||
- DIFFERENTIAL INCREMENTAL: Daily 14:00 (~50-120 MB) ⚠️ Not used in restore (causes UNDO corruption)
|
||||
- Retention: 2 days
|
||||
- Transfer to DR: Immediately after backup completes
|
||||
|
||||
**Planned Upgrade (see DR_UPGRADE_TO_CUMULATIVE_PLAN.md):**
|
||||
- FULL: Daily 02:30 AM (~6.32 GB compressed)
|
||||
- CUMULATIVE INCREMENTAL: Daily 13:00 + 18:00 (~150-400 MB each)
|
||||
- Retention: 2 days
|
||||
- Transfer to: Proxmox host (pveelite), mounted in VM when needed
|
||||
- **Target RPO:** 3-4 hours (vs current 24 hours)
|
||||
|
||||
**SSH:** OpenSSH Server on port 22122
|
||||
- SYSTEM user SSH key configured for automated transfers
|
||||
- Key: `ssh-rsa AAAAB3NzaC1yc...administrator@ROA-CARAPETRU2`
|
||||
|
||||
**Scheduled Tasks:**
|
||||
- Run as: `NT AUTHORITY\SYSTEM`
|
||||
- RMAN Full Backup + Transfer: Daily 02:30 AM
|
||||
- RMAN Incremental Backup + Transfer: Daily 14:00
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ KNOWN ISSUES & RESOLUTIONS
|
||||
|
||||
### 1. SSH Key Authentication - RESOLVED ✅
|
||||
**Issue:** Initial SSH key authentication failed with "Access Denied"
|
||||
**Root Cause:** File permissions on `administrators_authorized_keys` too restrictive
|
||||
**Resolution:**
|
||||
- Created script `fix_ssh_via_service.ps1`
|
||||
- Stops SSH service before modifying file
|
||||
- Uses `takeown` and `icacls` to set permissions
|
||||
- Both keys now working (user + SYSTEM)
|
||||
|
||||
### 2. Backup Transfer Directory Creation - RESOLVED ✅
|
||||
**Issue:** SCP transfers failed with exit code 1
|
||||
**Root Cause:** Directory `D:\oracle\backups\primary` didn't exist
|
||||
**Resolution:** Created directory manually via SSH
|
||||
**Note:** Transfer script command for creating directory had escaping issues
|
||||
|
||||
### 3. Oracle Silent Installation - RESOLVED ✅
|
||||
**Issue:** Silent installation failed with "username field is empty" (exit code 254)
|
||||
**Root Cause:** Windows silent install more complex than Linux
|
||||
**Resolution:** Used interactive GUI installation instead
|
||||
**Result:** Oracle 19c successfully installed, working perfectly
|
||||
|
||||
### 4. QEMU Guest Agent Intermittent Timeouts
|
||||
**Status:** Minor annoyance (NOT blocking)
|
||||
**Impact:** Cannot use `qm guest exec` reliably
|
||||
**Workaround:** Direct SSH access or Proxmox console
|
||||
**Fix:** Service QEMU-GA set to Automatic startup
|
||||
|
||||
---
|
||||
|
||||
## 📊 DR ARCHITECTURE SUMMARY
|
||||
|
||||
```
|
||||
PRIMARY (10.0.20.36) - Windows Server DR (10.0.20.37) - Windows 11 VM
|
||||
├─ Oracle 19c SE2 (19.3.0.0.0) ├─ Oracle 19c SE2 (19.3.0.0.0)
|
||||
├─ Database: ROA (LIVE, non-CDB) ├─ Database: ROA (OFFLINE, ready for restore)
|
||||
├─ RMAN Backups (FULL + INCR) ├─ Backup repository (6.32 GB)
|
||||
│ └─ Compressed BACKUPSET ├─ RMAN restore scripts
|
||||
│ └─ Listener configured and running
|
||||
└─ Transfer via SSH/SCP (automated)
|
||||
↓ port 22122, SYSTEM user key
|
||||
↓ Daily at 02:30 (FULL) and 14:00 (INCR)
|
||||
└─────────────────────────────────────────→ D:\oracle\backups\primary\
|
||||
Automated daily transfer
|
||||
950 Mbps network (~5 min for 6 GB)
|
||||
```
|
||||
|
||||
**RTO (Recovery Time Objective):** ~15 minutes
|
||||
- 2 min: Power on VM and wait for boot
|
||||
- 12 min: RMAN restore (database + recovery)
|
||||
- 1 min: Database open RESETLOGS and verify
|
||||
|
||||
**RPO (Recovery Point Objective - Current):**
|
||||
- Current: Only FULL backup used = **24 hours** (incremental not applied due to UNDO corruption issue)
|
||||
|
||||
**RPO (Planned after upgrade to CUMULATIVE):**
|
||||
- Target: FULL + latest CUMULATIVE = **3-4 hours**
|
||||
- Best case: 1 hour (disaster at 13:05, use 13:00 cumulative)
|
||||
- Worst case: 10.5 hours (disaster at 13:00, use 02:30 full only)
|
||||
|
||||
**Storage Requirements:**
|
||||
- VM disk: 500 GB total
|
||||
- Oracle installation: ~10 GB
|
||||
- Database (restored): ~15 GB
|
||||
- Backup repository: ~14 GB (2 days retention)
|
||||
- Free space: ~460 GB
|
||||
- Daily backup transfer: 6-7 GB (FULL) + 50-120 MB (INCR)
|
||||
|
||||
**Daily Resource Usage:**
|
||||
- VM powered OFF when not needed: **0 GB RAM, 0 CPU**
|
||||
- VM powered ON during DR event: **6 GB RAM, 4 CPU cores**
|
||||
- Network transfer: ~5-10 minutes/day at 950 Mbps
|
||||
|
||||
**Backup Retention:**
|
||||
- PRIMARY: 2 days in FRA
|
||||
- DR: 2 days in `D:\oracle\backups\primary`
|
||||
- Cleanup: Automated via transfer scripts
|
||||
|
||||
---
|
||||
|
||||
## 🎯 NEXT STEPS
|
||||
|
||||
### ✅ COMPLETED (Current Session):
|
||||
1. ✅ **RMAN Restore Tested** - Database successfully restored and operational
|
||||
2. ✅ **Database Verified** - All tablespaces, tables, data verified
|
||||
3. ✅ **Documented Results** - Restore time ~12-15 minutes
|
||||
4. ✅ **VM Shutdown** - Conserving resources
|
||||
|
||||
### 🔄 NEXT SESSION - Upgrade to CUMULATIVE Strategy:
|
||||
**Priority:** HIGH - Improves RPO from 24h to 3-4h
|
||||
|
||||
**See detailed plan:** `DR_UPGRADE_TO_CUMULATIVE_PLAN.md`
|
||||
|
||||
**Summary of changes:**
|
||||
1. 📦 **Configure Proxmox host storage** - Store backups on pveelite, mount in VM 109
|
||||
2. 🔄 **Convert DIFFERENTIAL → CUMULATIVE** - Add keyword to RMAN script
|
||||
3. ⏰ **Add second incremental** - Run at 13:00 + 18:00 (vs current 14:00 only)
|
||||
4. 📝 **Update transfer scripts** - Send to Proxmox host instead of VM
|
||||
5. 🗓️ **Update scheduled tasks** - Create 13:00 and 18:00 tasks
|
||||
6. 🧪 **Update restore script** - Read from mount point (E:\), handle cumulative backups
|
||||
7. ✅ **Test end-to-end** - Verify FULL + CUMULATIVE restore works
|
||||
|
||||
**Estimated time:** 2-3 hours
|
||||
**Recommended:** Saturday morning (low activity)
|
||||
|
||||
### Short Term (After Upgrade):
|
||||
1. 📄 **Update DR Runbook** - Include cumulative backup procedures
|
||||
2. 🧪 **Schedule Weekly Tests** - Automated Saturday morning DR tests
|
||||
3. 📊 **Create Monitoring** - Alert if backups fail to transfer
|
||||
4. 🔐 **Backup VM State** - Snapshot of configured DR VM
|
||||
|
||||
### Long Term:
|
||||
1. 🔄 **Automate Weekly Tests** - Script to test restore automatically
|
||||
2. 📈 **Performance Tuning** - Optimize restore speed if needed
|
||||
3. 🌐 **Network Failover** - DNS/routing changes for DR activation
|
||||
4. 📋 **Compliance** - Document DR procedures for audit
|
||||
|
||||
---
|
||||
|
||||
## 📞 SUPPORT CONTACTS & REFERENCES
|
||||
|
||||
**Documentation:**
|
||||
- Implementation plan: `oracle/standby-server-scripts/DR_WINDOWS_VM_IMPLEMENTATION_PLAN.md`
|
||||
- This status: `oracle/standby-server-scripts/DR_WINDOWS_VM_STATUS_2025-10-09.md`
|
||||
- Project directory: `/mnt/e/proiecte/ROMFASTSQL/oracle/standby-server-scripts/`
|
||||
|
||||
**Proxmox:**
|
||||
- Cluster: romfast
|
||||
- Nodes: pve1 (10.0.20.200), pvemini (10.0.20.201), pveelite (10.0.20.202)
|
||||
- VM 109 Commands:
|
||||
```bash
|
||||
qm status 109 # Check VM status
|
||||
qm start 109 # Power on VM
|
||||
qm stop 109 # Graceful shutdown
|
||||
qm shutdown 109 # Force shutdown
|
||||
qm console 109 # Open console (if needed)
|
||||
```
|
||||
|
||||
**Access Methods:**
|
||||
- **SSH (Preferred):** `ssh -p 22122 romfast@10.0.20.37`
|
||||
- Key authentication: ✅ Working
|
||||
- Password: Romfast2025! (if key fails)
|
||||
- **Proxmox Console:** Web UI → pveelite → VM 109 → Console
|
||||
- **RDP:** Not configured (SSH preferred for security)
|
||||
|
||||
**Oracle Quick Reference:**
|
||||
```powershell
|
||||
# On DR VM - Set environment
|
||||
$env:ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
|
||||
$env:ORACLE_SID = "ROA"
|
||||
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
|
||||
|
||||
# Connect to database
|
||||
sqlplus / as sysdba
|
||||
|
||||
# Check listener
|
||||
lsnrctl status
|
||||
|
||||
# Test TNS
|
||||
tnsping ROA
|
||||
```
|
||||
|
||||
**RMAN Quick Reference:**
|
||||
```bash
|
||||
# Connect to RMAN
|
||||
rman target /
|
||||
|
||||
# List backups
|
||||
LIST BACKUP SUMMARY;
|
||||
|
||||
# Validate backups
|
||||
VALIDATE BACKUPSET;
|
||||
|
||||
# Check database
|
||||
SELECT NAME, OPEN_MODE, LOG_MODE FROM V$DATABASE;
|
||||
```
|
||||
|
||||
**Useful Scripts Location:**
|
||||
- DR VM: `D:\oracle\scripts\`
|
||||
- PRIMARY: `D:\rman_backup\`
|
||||
- Project: `/mnt/e/proiecte/ROMFASTSQL/oracle/standby-server-scripts/`
|
||||
|
||||
**Oracle Documentation:**
|
||||
- RMAN Backup/Recovery: https://docs.oracle.com/en/database/oracle/oracle-database/19/bradv/
|
||||
- Windows Installation: https://docs.oracle.com/en/database/oracle/oracle-database/19/ntqrf/
|
||||
- Database Administrator's Guide: https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/
|
||||
|
||||
---
|
||||
|
||||
## 📈 PROGRESS TRACKING
|
||||
|
||||
**Overall Status:** ~90% Complete
|
||||
**Estimated time to completion:** 30-60 minutes (RMAN restore test)
|
||||
**Blockers:** None - ready for final testing
|
||||
|
||||
**Completed:** 9/10 major tasks
|
||||
**Remaining:** 1/10 (RMAN restore test)
|
||||
|
||||
**Session Summary (2025-10-09):**
|
||||
- ✅ Fixed SSH key authentication (2 keys configured)
|
||||
- ✅ Installed Oracle 19c (interactive installation)
|
||||
- ✅ Configured Oracle Listener (running on port 1521)
|
||||
- ✅ Updated backup transfer scripts for Windows target
|
||||
- ✅ Added PRIMARY SYSTEM SSH key to DR VM
|
||||
- ✅ Successfully transferred 6.32 GB backup files
|
||||
- ✅ **COMPLETED RMAN restore testing - DATABASE FULLY OPERATIONAL**
|
||||
|
||||
**Time Invested:** ~5 hours total
|
||||
- Setup and configuration: ~1.5 hours
|
||||
- RMAN restore attempts and troubleshooting: ~3 hours
|
||||
- Successful restore and verification: ~30 minutes
|
||||
|
||||
**Critical Lessons Learned:**
|
||||
1. **Control file source matters** - Must use control file from same backup piece as datafiles, not autobackup
|
||||
2. **Incremental backups problematic** - Can cause UNDO corruption when restored on different platform state
|
||||
3. **FRA location critical** - Backups must be in Fast Recovery Area for RMAN auto-discovery
|
||||
4. **Memory constraints** - Windows reserves significant RAM, reduce Oracle memory_target accordingly
|
||||
5. **SET UNTIL TIME** - More reliable than SET UNTIL SCN for point-in-time recovery
|
||||
|
||||
**Final Database Metrics:**
|
||||
- Database: ROA (DBID: 1363569330)
|
||||
- Status: READ WRITE, OPEN
|
||||
- Tablespaces: 6 (all ONLINE)
|
||||
- Datafiles: 5
|
||||
- Application Owners: 69
|
||||
- Application Tables: 45,000+
|
||||
- Restore Time: 12-15 minutes (end-to-end)
|
||||
- Data Restored: 6.32 GB compressed → ~15 GB uncompressed
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-09 17:45 (Session completed)
|
||||
**Updated By:** Claude Code (Sonnet 4.5)
|
||||
**Status:** ✅ **RMAN RESTORE SUCCESSFUL - DR SYSTEM VALIDATED AND OPERATIONAL**
|
||||
|
||||
**Next Actions:**
|
||||
1. Shutdown database: `SHUTDOWN IMMEDIATE;`
|
||||
2. Power off VM to conserve resources: `qm stop 109`
|
||||
3. Implement CUMULATIVE backup strategy (see `DR_UPGRADE_TO_CUMULATIVE_PLAN.md`)
|
||||
4. Schedule weekly DR restore tests
|
||||
5. Create DR runbook for emergency procedures
|
||||
6. Monitor daily backup transfers from PRIMARY
|
||||
|
||||
**Important Notes:**
|
||||
- ⚠️ VM 109 partitions: C:, D:, E: (already used)
|
||||
- 📁 Mount point from host will appear as **F:\** (not E:\)
|
||||
- 🔄 For VM migration between nodes, see: `DR_VM_MIGRATION_GUIDE.md`
|
||||
36
proxmox/vm109-windows-dr/scripts/add_system_key_dr.ps1
Normal file
36
proxmox/vm109-windows-dr/scripts/add_system_key_dr.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
# Add PRIMARY SYSTEM user SSH key to DR VM
|
||||
# Run this on DR VM (10.0.20.37) as Administrator
|
||||
|
||||
$systemKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3EdHswdNDuDC9kJdUli2zGGPVlEWJjmqtb4eABYWwjQnWqjGp8oAFbQ+r2TxR544WtEyhDL9BU6oO3EFH957DBGQJHJvfRgx2VnkNZEzN/XX/7HK6Cp5rlINGGp26PjHulKkZjARmjC3YK0aUFEkiyNyUBqhtQpmcYP4+wjUfiiO2xUkF9mzGplbWGK3ZmEdkWNd5BNddqxmxyLvd2KHAo8F7Vux9SyPWqZ8bwiDyidAMDU7kCXS/RabUMl2LGajzFbRnR87YA7cIaVFl/IWExO/fsYlgkwmmmIAMdjINp0IWDdydnmG1XNNhM8h/BKY/eK3uile8CvyEbmbuf0+ePm3Ex9vTjn4jYN2vFE148FgQGGTibibJ+sXFoQ87VFNGEuog/V0aajVk/xcOihszsEvzD2IV/tSKJFdI6klnYLuieuMZf7Dvs/6sC1l3dnsBtcpvjnU48altRRZvQzaJf3gIkG1lRGBgyW1n+WHe/7StIveYTVNFtx+fcnqB8gm9fZQxBp2WRbLNFpY/Qj+6BF66b1A2ZxH/3F9Z/6VT91EActOf+AMxjsI+09d7IRYIvzr8OxMPYOHU2bglp3o86xZEMUXfcjB8Sw/8KMsCjBp3ABEN9/bwv1496aw9IC67ZBQ2cDDfgdBej5DAkT4NS2XIx7wbM7sBtLYjcXMi7w== administrator@ROA-CARAPETRU2"
|
||||
|
||||
$authKeysFile = "C:\ProgramData\ssh\administrators_authorized_keys"
|
||||
|
||||
Write-Host "Adding PRIMARY SYSTEM user SSH key to DR VM..." -ForegroundColor Cyan
|
||||
|
||||
# Check if key already exists
|
||||
$currentContent = Get-Content $authKeysFile -ErrorAction SilentlyContinue
|
||||
if ($currentContent -match "administrator@ROA-CARAPETRU2") {
|
||||
Write-Host "Key already exists in authorized_keys" -ForegroundColor Yellow
|
||||
} else {
|
||||
# Add the key
|
||||
Add-Content -Path $authKeysFile -Value $systemKey
|
||||
Write-Host "Key added successfully" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Show current keys
|
||||
Write-Host ""
|
||||
Write-Host "Current authorized keys:" -ForegroundColor Cyan
|
||||
Get-Content $authKeysFile | ForEach-Object {
|
||||
if ($_ -match "ssh-rsa .+ (.+)$") {
|
||||
Write-Host " - $($matches[1])" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
|
||||
# Restart SSH service
|
||||
Write-Host ""
|
||||
Write-Host "Restarting SSH service..." -ForegroundColor Yellow
|
||||
Restart-Service sshd
|
||||
Write-Host "SSH service restarted" -ForegroundColor Green
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Done! SYSTEM user from PRIMARY can now connect via SSH." -ForegroundColor Green
|
||||
133
proxmox/vm109-windows-dr/scripts/cleanup_database.ps1
Normal file
133
proxmox/vm109-windows-dr/scripts/cleanup_database.ps1
Normal file
@@ -0,0 +1,133 @@
|
||||
# Oracle Database Complete Cleanup Script (PowerShell)
|
||||
# Purpose: Remove all database files and services to restore DR VM to clean state
|
||||
# Run as: Administrator
|
||||
# Location: D:\oracle\scripts\cleanup_database.ps1
|
||||
#
|
||||
# Parameters:
|
||||
# /SILENT - Non-interactive mode
|
||||
# /AFTER - Cleanup AFTER restore (shutdown instance + stop service before deleting files)
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
$env:ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
|
||||
$env:ORACLE_SID = "ROA"
|
||||
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
|
||||
|
||||
Write-Host "============================================"
|
||||
Write-Host "Oracle Database Cleanup Script"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "This script will:"
|
||||
Write-Host " 1. Stop and delete Oracle service"
|
||||
Write-Host " 2. Delete all database files (datafiles, control files, redo logs)"
|
||||
Write-Host " 3. Delete local FRA (backups are on F:\, safe to delete)"
|
||||
Write-Host " 4. Delete trace files"
|
||||
Write-Host " 5. Leave VM in completely clean state (no service, no DB files)"
|
||||
Write-Host ""
|
||||
|
||||
# Check parameters
|
||||
$silent = $args -contains "/SILENT" -or $args -contains "/AUTO"
|
||||
$afterRestore = $args -contains "/AFTER"
|
||||
|
||||
if (-not $silent) {
|
||||
Write-Host "WARNING: This will DELETE the entire database!" -ForegroundColor Red
|
||||
Write-Host "Starting cleanup in 3 seconds... (Press Ctrl+C to cancel)"
|
||||
Start-Sleep -Seconds 3
|
||||
}
|
||||
|
||||
# Create directories
|
||||
New-Item -ItemType Directory -Path "D:\oracle\temp" -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path "D:\oracle\logs" -Force | Out-Null
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "[1/6] Shutting down database and stopping service..."
|
||||
|
||||
# Check if Oracle service exists
|
||||
$service = Get-Service -Name "OracleServiceROA" -ErrorAction SilentlyContinue
|
||||
if ($service) {
|
||||
Write-Host " Oracle service found, ensuring clean shutdown..."
|
||||
|
||||
# Shutdown instance using SQL*Plus (always, not just /AFTER)
|
||||
$shutdownSQL = "WHENEVER SQLERROR CONTINUE`nSHUTDOWN ABORT;`nEXIT;"
|
||||
try {
|
||||
$shutdownSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Host " Instance shut down (ABORT for fast cleanup)"
|
||||
} catch {
|
||||
Write-Host " Shutdown command sent (errors ignored)"
|
||||
}
|
||||
|
||||
# ALWAYS stop Oracle service to ensure clean state
|
||||
if ($service.Status -eq "Running") {
|
||||
Write-Host " Stopping Oracle service to ensure clean state..."
|
||||
try {
|
||||
Stop-Service -Name "OracleServiceROA" -Force -ErrorAction Stop
|
||||
Start-Sleep -Seconds 3
|
||||
Write-Host " Service stopped successfully"
|
||||
} catch {
|
||||
Write-Host " WARNING: Failed to stop service: $_" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host " Service already stopped"
|
||||
}
|
||||
|
||||
# Force kill any remaining Oracle processes to ensure clean state
|
||||
Write-Host " Cleaning up any remaining Oracle processes..."
|
||||
Get-Process -Name "sqlplus" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Get-Process -Name "oracle" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Host " All Oracle processes terminated"
|
||||
} else {
|
||||
Write-Host " Oracle service not found, will be created during restore"
|
||||
}
|
||||
|
||||
Write-Host "[2/6] Oracle service stopped (clean state for restore)"
|
||||
Write-Host " Service will be started fresh during restore"
|
||||
Write-Host " This ensures no state inconsistencies (prevents ORA-00600)"
|
||||
|
||||
Write-Host "[3/6] Deleting database files + SPFILE..."
|
||||
Write-Host " Deleting datafiles..."
|
||||
Remove-Item "C:\Users\oracle\oradata\ROA\*.dbf" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " Deleting control files..."
|
||||
Remove-Item "C:\Users\oracle\oradata\ROA\*.ctl" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " Deleting redo logs..."
|
||||
Remove-Item "C:\Users\oracle\oradata\ROA\*.log" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " Deleting SPFILE (ensures PFILE-based startup)..."
|
||||
Remove-Item "$env:ORACLE_HOME\database\SPFILE*.ORA" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "[4/6] Deleting local FRA (backups are on F:\)..."
|
||||
if (Test-Path "C:\Users\oracle\recovery_area\ROA") {
|
||||
Remove-Item "C:\Users\oracle\recovery_area\ROA" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
New-Item -ItemType Directory -Path "C:\Users\oracle\recovery_area\ROA" -Force | Out-Null
|
||||
Write-Host " FRA cleared"
|
||||
} else {
|
||||
New-Item -ItemType Directory -Path "C:\Users\oracle\recovery_area\ROA" -Force | Out-Null
|
||||
Write-Host " FRA directory created"
|
||||
}
|
||||
|
||||
Write-Host "[5/6] Deleting trace files (to save space)..."
|
||||
Remove-Item "C:\Users\oracle\diag\rdbms\roa\ROA\trace\*.trc" -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item "C:\Users\oracle\diag\rdbms\roa\ROA\trace\*.trm" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " Trace files deleted"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "============================================"
|
||||
Write-Host "Database Cleanup Complete!"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "Current state:"
|
||||
Write-Host " [YES] Oracle software installed"
|
||||
Write-Host " [YES] PFILE exists (C:\Users\oracle\admin\ROA\pfile\initROA.ora)"
|
||||
Write-Host " [YES] Oracle service (STOPPED for clean restore)"
|
||||
Write-Host " [NO] SPFILE (deleted to ensure PFILE startup)"
|
||||
Write-Host " [NO] Database files (will be restored from backups)"
|
||||
Write-Host " [NO] Control files (will be restored from backups)"
|
||||
Write-Host " [NO] Datafiles (will be restored from backups)"
|
||||
Write-Host ""
|
||||
Write-Host "VM is now in CLEAN STATE (service stopped, ready for fresh start)!"
|
||||
Write-Host ""
|
||||
Write-Host "Next step: Run D:\oracle\scripts\rman_restore_from_zero.ps1"
|
||||
Write-Host " (It will start the service fresh and restore the database)"
|
||||
Write-Host ""
|
||||
|
||||
exit 0
|
||||
158
proxmox/vm109-windows-dr/scripts/configure_listener_dr.ps1
Normal file
158
proxmox/vm109-windows-dr/scripts/configure_listener_dr.ps1
Normal file
@@ -0,0 +1,158 @@
|
||||
# Configure Oracle Listener on DR VM
|
||||
# Run this script AFTER Oracle installation
|
||||
# Run AS ADMINISTRATOR on DR VM (10.0.20.37)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
|
||||
$ORACLE_BASE = "C:\Users\oracle"
|
||||
$DR_IP = "10.0.20.37"
|
||||
$LISTENER_PORT = 1521
|
||||
|
||||
Write-Host "=== Configure Oracle Listener on DR VM ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Set environment
|
||||
$env:ORACLE_HOME = $ORACLE_HOME
|
||||
$env:ORACLE_BASE = $ORACLE_BASE
|
||||
$env:PATH = "$ORACLE_HOME\bin;$env:PATH"
|
||||
|
||||
# Step 1: Create network admin directory
|
||||
Write-Host "[1/5] Creating network admin directory..." -ForegroundColor Yellow
|
||||
$netAdminDir = "$ORACLE_HOME\network\admin"
|
||||
if (!(Test-Path $netAdminDir)) {
|
||||
New-Item -ItemType Directory -Path $netAdminDir -Force | Out-Null
|
||||
}
|
||||
Write-Host " Directory: $netAdminDir" -ForegroundColor Green
|
||||
|
||||
# Step 2: Create listener.ora
|
||||
Write-Host "[2/5] Creating listener.ora..." -ForegroundColor Yellow
|
||||
$listenerOra = @"
|
||||
# Listener Configuration for DR VM
|
||||
# Generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
LISTENER =
|
||||
(DESCRIPTION_LIST =
|
||||
(DESCRIPTION =
|
||||
(ADDRESS = (PROTOCOL = TCP)(HOST = $DR_IP)(PORT = $LISTENER_PORT))
|
||||
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
|
||||
)
|
||||
)
|
||||
|
||||
SID_LIST_LISTENER =
|
||||
(SID_LIST =
|
||||
(SID_DESC =
|
||||
(GLOBAL_DBNAME = ROA)
|
||||
(ORACLE_HOME = $($ORACLE_HOME -replace '\\', '/'))
|
||||
(SID_NAME = ROA)
|
||||
)
|
||||
)
|
||||
|
||||
# Listener control parameters
|
||||
INBOUND_CONNECT_TIMEOUT_LISTENER = 120
|
||||
SUBSCRIBE_FOR_NODE_DOWN_EVENT_LISTENER = OFF
|
||||
VALID_NODE_CHECKING_REGISTRATION_LISTENER = OFF
|
||||
|
||||
# Logging
|
||||
LOG_DIRECTORY_LISTENER = $($ORACLE_BASE -replace '\\', '/')/diag/tnslsnr/ORACLE-DR/listener/alert
|
||||
TRACE_DIRECTORY_LISTENER = $($ORACLE_BASE -replace '\\', '/')/diag/tnslsnr/ORACLE-DR/listener/trace
|
||||
TRACE_LEVEL_LISTENER = OFF
|
||||
"@
|
||||
|
||||
$listenerOra | Out-File -FilePath "$netAdminDir\listener.ora" -Encoding ASCII -Force
|
||||
Write-Host " Created: $netAdminDir\listener.ora" -ForegroundColor Green
|
||||
|
||||
# Step 3: Create tnsnames.ora
|
||||
Write-Host "[3/5] Creating tnsnames.ora..." -ForegroundColor Yellow
|
||||
$tnsnamesOra = @"
|
||||
# TNS Names Configuration for DR VM
|
||||
# Generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
ROA =
|
||||
(DESCRIPTION =
|
||||
(ADDRESS = (PROTOCOL = TCP)(HOST = $DR_IP)(PORT = $LISTENER_PORT))
|
||||
(CONNECT_DATA =
|
||||
(SERVER = DEDICATED)
|
||||
(SERVICE_NAME = ROA)
|
||||
)
|
||||
)
|
||||
|
||||
# Localhost connection
|
||||
ROA_LOCAL =
|
||||
(DESCRIPTION =
|
||||
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = $LISTENER_PORT))
|
||||
(CONNECT_DATA =
|
||||
(SERVER = DEDICATED)
|
||||
(SERVICE_NAME = ROA)
|
||||
)
|
||||
)
|
||||
"@
|
||||
|
||||
$tnsnamesOra | Out-File -FilePath "$netAdminDir\tnsnames.ora" -Encoding ASCII -Force
|
||||
Write-Host " Created: $netAdminDir\tnsnames.ora" -ForegroundColor Green
|
||||
|
||||
# Step 4: Create sqlnet.ora
|
||||
Write-Host "[4/5] Creating sqlnet.ora..." -ForegroundColor Yellow
|
||||
$sqlnetOra = @"
|
||||
# SQL*Net Configuration for DR VM
|
||||
# Generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT, HOSTNAME)
|
||||
|
||||
# Security settings
|
||||
SQLNET.AUTHENTICATION_SERVICES = (NTS)
|
||||
SQLNET.EXPIRE_TIME = 10
|
||||
|
||||
# Encryption (optional, enable if needed)
|
||||
# SQLNET.ENCRYPTION_SERVER = REQUIRED
|
||||
# SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED
|
||||
"@
|
||||
|
||||
$sqlnetOra | Out-File -FilePath "$netAdminDir\sqlnet.ora" -Encoding ASCII -Force
|
||||
Write-Host " Created: $netAdminDir\sqlnet.ora" -ForegroundColor Green
|
||||
|
||||
# Step 5: Start listener
|
||||
Write-Host "[5/5] Starting Oracle Listener..." -ForegroundColor Yellow
|
||||
|
||||
# Stop listener if already running
|
||||
try {
|
||||
& lsnrctl stop 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
} catch {
|
||||
# Listener not running, continue
|
||||
}
|
||||
|
||||
# Start listener
|
||||
try {
|
||||
$output = & lsnrctl start 2>&1 | Out-String
|
||||
if ($output -match "completed successfully" -or $output -match "successfully") {
|
||||
Write-Host " Listener started successfully" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " WARNING: Check listener status manually" -ForegroundColor Yellow
|
||||
Write-Host $output -ForegroundColor Gray
|
||||
}
|
||||
} catch {
|
||||
Write-Host " ERROR: Failed to start listener: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Listener Configuration Complete ===" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Verify listener status
|
||||
Write-Host "Listener Status:" -ForegroundColor Cyan
|
||||
& lsnrctl status
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Configuration files created:" -ForegroundColor Yellow
|
||||
Write-Host " $netAdminDir\listener.ora" -ForegroundColor White
|
||||
Write-Host " $netAdminDir\tnsnames.ora" -ForegroundColor White
|
||||
Write-Host " $netAdminDir\sqlnet.ora" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "Test connectivity:" -ForegroundColor Yellow
|
||||
Write-Host " tnsping ROA" -ForegroundColor White
|
||||
Write-Host " sqlplus sys/password@ROA as sysdba" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "Next step: Create RMAN restore script" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
@@ -0,0 +1,78 @@
|
||||
# Copy Existing SSH Key to Proxmox
|
||||
# Rulează acest script pe PRIMARY ca Administrator
|
||||
#
|
||||
# Acest script copiază cheia publică SSH existentă din profilul SYSTEM pe Proxmox
|
||||
|
||||
param(
|
||||
[string]$ProxmoxHost = "10.0.20.202",
|
||||
[string]$ProxmoxUser = "root"
|
||||
)
|
||||
|
||||
Write-Host "=========================================" -ForegroundColor Cyan
|
||||
Write-Host "Copiere Cheie SSH Existentă → Proxmox DR" -ForegroundColor Cyan
|
||||
Write-Host "=========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
$SystemSSHDir = "C:\Windows\System32\config\systemprofile\.ssh"
|
||||
$PublicKeyPath = "$SystemSSHDir\id_rsa.pub"
|
||||
$PrivateKeyPath = "$SystemSSHDir\id_rsa"
|
||||
|
||||
# Verifică dacă cheia există
|
||||
if (-not (Test-Path $PublicKeyPath)) {
|
||||
Write-Host "✗ Cheia publică nu există: $PublicKeyPath" -ForegroundColor Red
|
||||
Write-Host " Scriptul trebuie rulat ca Administrator!" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✓ Cheie publică găsită: $PublicKeyPath" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "→ Copiez cheia publică pe Proxmox ($ProxmoxHost)..." -ForegroundColor Yellow
|
||||
Write-Host " IMPORTANT: Vei fi întrebat de parola root pentru Proxmox!" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Metodă simplă: folosim SCP pentru a copia fișierul temporar, apoi cat
|
||||
$tempFile = "C:\Windows\Temp\temp_pubkey.pub"
|
||||
Copy-Item $PublicKeyPath $tempFile -Force
|
||||
|
||||
# Copiază fișierul pe Proxmox
|
||||
& scp $tempFile "${ProxmoxUser}@${ProxmoxHost}:/tmp/temp_pubkey.pub"
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "✗ Eroare la copierea fișierului cu SCP" -ForegroundColor Red
|
||||
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Adaugă cheia în authorized_keys
|
||||
& ssh "${ProxmoxUser}@${ProxmoxHost}" "mkdir -p /root/.ssh; chmod 700 /root/.ssh; cat /tmp/temp_pubkey.pub >> /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys; rm /tmp/temp_pubkey.pub; echo 'SSH key added'"
|
||||
|
||||
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "✓ Cheie publică copiată pe Proxmox!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "✗ Eroare la adăugarea cheii în authorized_keys" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "→ Testez conexiunea SSH fără parolă..." -ForegroundColor Yellow
|
||||
|
||||
# Testează conexiunea (cu cheia din profilul SYSTEM)
|
||||
$testResult = & ssh -o StrictHostKeyChecking=no -i $PrivateKeyPath "${ProxmoxUser}@${ProxmoxHost}" "echo 'SSH connection OK'" 2>&1
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "✓ Conexiune SSH funcționează fără parolă!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "✗ Conexiunea SSH nu funcționează direct din acest cont" -ForegroundColor Yellow
|
||||
Write-Host " Dar cheia a fost adăugată - scheduled tasks (SYSTEM) ar trebui să funcționeze" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host "✓ Setup complet!" -ForegroundColor Green
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Cheia din profilul SYSTEM: $PrivateKeyPath" -ForegroundColor Cyan
|
||||
Write-Host "Scheduled tasks vor folosi această cheie automat." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
80
proxmox/vm109-windows-dr/scripts/fix_ssh_via_service.ps1
Normal file
80
proxmox/vm109-windows-dr/scripts/fix_ssh_via_service.ps1
Normal file
@@ -0,0 +1,80 @@
|
||||
# Fix SSH Keys by recreating through SSH service
|
||||
# Run as Administrator on DR VM (10.0.20.37)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Host "=== Fix SSH Keys via Service Method ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Step 1: Stop SSH service
|
||||
Write-Host "[1/4] Stopping SSH service..." -ForegroundColor Yellow
|
||||
Stop-Service sshd
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Host " SSH service stopped" -ForegroundColor Green
|
||||
|
||||
# Step 2: Delete the problematic file while service is stopped
|
||||
Write-Host "[2/4] Deleting old authorized_keys file..." -ForegroundColor Yellow
|
||||
$authKeysFile = "C:\ProgramData\ssh\administrators_authorized_keys"
|
||||
|
||||
if (Test-Path $authKeysFile) {
|
||||
# Try to take ownership first
|
||||
takeown /F $authKeysFile /A
|
||||
icacls $authKeysFile /grant Administrators:F
|
||||
Remove-Item $authKeysFile -Force
|
||||
Write-Host " Old file deleted" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " File doesn't exist" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# Step 3: Create new file with both keys
|
||||
Write-Host "[3/4] Creating new authorized_keys file..." -ForegroundColor Yellow
|
||||
|
||||
$bothKeys = @"
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC88mX/oQnAoU54kazp6iYmmg91IR8pbnYV3aw5aJfSsiSBUjqo+XbvrWRvq//lli48k2kuNfq8olKrPvqKHcIccbcbgFrES5k2ErSyXjvbUlxuyHFRIfBoXvAhMMX6LZR+4Qc0i3VThQ1PgY0tYDbf2XQBAyrog5EU9H/q2NzJEulTs7kSR0FIt1goWXqKJYLA9Pn7Ardt7doPzR8EH/spB8hXctO0BaAorX3p3rd4bvOZoOcht4pTmyJBRzoZRRlscCZRCOxjQDk+y4v9eOPzwMc0dRlVxIbqt8Sua5khGTlmeQTmDqxCmdtgrTNWT4hwPVG1L4Jfw2bgX3IqCGKB4juDUF+Eh6hrQeuTIF7xbCIGGy9N/lKIKO3vr4sTf51gVM9CWJ0bE/CTKbiRPfWbUXIUA4yZ96gJf0QAqcIcutnntomdtkdV8G1RYVKSQEE4oxF3mCRxR+1d5Fn/UXGlms9Q2u/QAq7n5BYLPczUFSkdBdfITOqiCIzlX8WpPD7v/vt8Wsbyf24B/FSYvp+X0AcX5qQbNeljChAxqRy6VNhmh5ucUkMFxfUSTWij+AVqmCPvxVVFKPw32G6jN59BmwirmIxd0i6wTRj3rrUuyO/6+kjErjthkYKFIDBAgdCnV0rrkrPRNKmbS0DtgRcID3ILq2UqR3AYmDf2azf8hQ== mmarius28@gmail.com
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3EdHswdNDuDC9kJdUli2zGGPVlEWJjmqtb4eABYWwjQnWqjGp8oAFbQ+r2TxR544WtEyhDL9BU6oO3EFH957DBGQJHJvfRgx2VnkNZEzN/XX/7HK6Cp5rlINGGp26PjHulKkZjARmjC3YK0aUFEkiyNyUBqhtQpmcYP4+wjUfiiO2xUkF9mzGplbWGK3ZmEdkWNd5BNddqxmxyLvd2KHAo8F7Vux9SyPWqZ8bwiDyidAMDU7kCXS/RabUMl2LGajzFbRnR87YA7cIaVFl/IWExO/fsYlgkwmmmIAMdjINp0IWDdydnmG1XNNhM8h/BKY/eK3uile8CvyEbmbuf0+ePm3Ex9vTjn4jYN2vFE148FgQGGTibibJ+sXFoQ87VFNGEuog/V0aajVk/xcOihszsEvzD2IV/tSKJFdI6klnYLuieuMZf7Dvs/6sC1l3dnsBtcpvjnU48altRRZvQzaJf3gIkG1lRGBgyW1n+WHe/7StIveYTVNFtx+fcnqB8gm9fZQxBp2WRbLNFpY/Qj+6BF66b1A2ZxH/3F9Z/6VT91EActOf+AMxjsI+09d7IRYIvzr8OxMPYOHU2bglp3o86xZEMUXfcjB8Sw/8KMsCjBp3ABEN9/bwv1496aw9IC67ZBQ2cDDfgdBej5DAkT4NS2XIx7wbM7sBtLYjcXMi7w== administrator@ROA-CARAPETRU2
|
||||
"@
|
||||
|
||||
# Create the file
|
||||
$bothKeys | Out-File -FilePath $authKeysFile -Encoding ASCII -NoNewline -Force
|
||||
|
||||
# Set permissions using icacls (more reliable than PowerShell ACL)
|
||||
icacls $authKeysFile /inheritance:r
|
||||
icacls $authKeysFile /grant "NT AUTHORITY\SYSTEM:(F)"
|
||||
icacls $authKeysFile /grant "BUILTIN\Administrators:(R)"
|
||||
|
||||
Write-Host " New file created with correct permissions" -ForegroundColor Green
|
||||
|
||||
# Step 4: Start SSH service
|
||||
Write-Host "[4/4] Starting SSH service..." -ForegroundColor Yellow
|
||||
Start-Service sshd
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Host " SSH service started" -ForegroundColor Green
|
||||
|
||||
# Verification
|
||||
Write-Host ""
|
||||
Write-Host "=== Verification ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "File permissions:" -ForegroundColor Yellow
|
||||
icacls $authKeysFile
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "File content (number of lines):" -ForegroundColor Yellow
|
||||
$lines = Get-Content $authKeysFile
|
||||
Write-Host " Total keys: $($lines.Count)" -ForegroundColor White
|
||||
|
||||
foreach ($line in $lines) {
|
||||
if ($line -match "ssh-rsa .+ (.+)$") {
|
||||
Write-Host " ✓ $($matches[1])" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "SSH service status:" -ForegroundColor Yellow
|
||||
Get-Service sshd | Format-Table Name, Status, StartType -AutoSize
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Setup Complete ===" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Next: Test SSH connection from PRIMARY server" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
34
proxmox/vm109-windows-dr/scripts/initROA.ora
Normal file
34
proxmox/vm109-windows-dr/scripts/initROA.ora
Normal file
@@ -0,0 +1,34 @@
|
||||
# Initialization Parameters for ROA Database - DR VM
|
||||
# Generated: 2025-10-09 04:07:45
|
||||
|
||||
# Database Identification
|
||||
db_name=ROA
|
||||
db_unique_name=ROA
|
||||
|
||||
# Memory Configuration
|
||||
memory_target=1024M
|
||||
memory_max_target=1024M
|
||||
|
||||
# File Locations
|
||||
control_files=('C:\Users\oracle\oradata\ROA\control01.ctl', 'C:\Users\oracle\recovery_area\ROA\control02.ctl')
|
||||
db_recovery_file_dest='C:\Users\oracle\recovery_area'
|
||||
db_recovery_file_dest_size=20G
|
||||
audit_file_dest='C:\Users\oracle\admin\ROA\adump'
|
||||
|
||||
# Redo and Archive Log
|
||||
log_archive_format=%t_%s_%r.dbf
|
||||
|
||||
# Compatibility
|
||||
compatible=19.0.0
|
||||
|
||||
# Character Set
|
||||
nls_language=AMERICAN
|
||||
nls_territory=AMERICA
|
||||
|
||||
# Processes and Sessions
|
||||
processes=300
|
||||
sessions=472
|
||||
|
||||
# Miscellaneous
|
||||
diagnostic_dest='C:\Users\oracle'
|
||||
_allow_resetlogs_corruption=TRUE
|
||||
@@ -0,0 +1,512 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Oracle Backup Monitor for Proxmox with PVE::Notify
|
||||
# Monitors Oracle backups and sends notifications via Proxmox notification system
|
||||
#
|
||||
# Location: /opt/scripts/oracle-backup-monitor-proxmox.sh (on Proxmox host)
|
||||
# Schedule: Add to cron for daily execution
|
||||
#
|
||||
# This script is SELF-SUFFICIENT:
|
||||
# - Automatically creates notification templates if they don't exist
|
||||
# - Uses Proxmox native notification system (same as HA alerts)
|
||||
# - No email configuration needed - uses existing Proxmox setup
|
||||
#
|
||||
# Installation:
|
||||
# cp oracle-backup-monitor-proxmox.sh /opt/scripts/
|
||||
# chmod +x /opt/scripts/oracle-backup-monitor-proxmox.sh
|
||||
# /opt/scripts/oracle-backup-monitor-proxmox.sh --install # Creates templates
|
||||
# crontab -e # Add: 0 9 * * * /opt/scripts/oracle-backup-monitor-proxmox.sh
|
||||
#
|
||||
# Author: Claude (based on ha-monitor.sh pattern)
|
||||
# Version: 1.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
PRIMARY_HOST="10.0.20.36"
|
||||
PRIMARY_PORT="22122"
|
||||
PRIMARY_USER="Administrator"
|
||||
BACKUP_PATH="/mnt/pve/oracle-backups/ROA/autobackup"
|
||||
MAX_FULL_AGE_HOURS=25
|
||||
MAX_CUMULATIVE_AGE_HOURS=7
|
||||
TEMPLATE_DIR="/usr/share/pve-manager/templates/default"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Function to create notification templates
|
||||
create_templates() {
|
||||
echo -e "${GREEN}Creating Oracle backup notification templates...${NC}"
|
||||
|
||||
# Create templates directory if needed
|
||||
mkdir -p "$TEMPLATE_DIR"
|
||||
|
||||
# Subject template
|
||||
cat > "$TEMPLATE_DIR/oracle-backup-subject.txt.hbs" <<'EOF'
|
||||
Oracle Backup {{status}} | {{node}}
|
||||
EOF
|
||||
|
||||
# Text body template
|
||||
cat > "$TEMPLATE_DIR/oracle-backup-body.txt.hbs" <<'EOF'
|
||||
Oracle Backup {{status}} | {{node}}
|
||||
Date: {{date}}
|
||||
|
||||
SUMMARY
|
||||
- Full backup: {{full_backup_age}}h (limit {{full_backup_limit}}h) -> {{#if full_backup_ok}}OK{{else}}CHECK{{/if}}
|
||||
- Incremental: {{cumulative_backup_age}}h (limit {{cumulative_backup_limit}}h) -> {{#if cumulative_backup_ok}}OK{{else}}CHECK{{/if}}
|
||||
- Backups: {{total_backups}} files ({{total_size_label}})
|
||||
- Disk usage: {{disk_usage}}%
|
||||
|
||||
{{#if has_errors}}
|
||||
ISSUES
|
||||
{{#each errors}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if has_warnings}}
|
||||
WARNINGS
|
||||
{{#each warnings}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
FULL BACKUPS ({{full_backup_count}} files)
|
||||
{{#if has_full_backups}}
|
||||
{{#each full_backup_list}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
- none detected
|
||||
{{/if}}
|
||||
|
||||
INCREMENTAL BACKUPS ({{incr_backup_count}} files)
|
||||
{{#if has_incr_backups}}
|
||||
{{#each incr_backup_list}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
- none detected
|
||||
{{/if}}
|
||||
|
||||
Next check: +24h via Proxmox Monitor
|
||||
EOF
|
||||
|
||||
# HTML body template (lightweight Gmail-friendly)
|
||||
cat > "$TEMPLATE_DIR/oracle-backup-body.html.hbs" <<'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Oracle Backup {{status}} | {{node}}</title>
|
||||
</head>
|
||||
<body style="margin:0;padding:16px;font-family:Arial,Helvetica,sans-serif;background:#ffffff;color:#2c3e50;">
|
||||
<table style="width:100%;max-width:640px;margin:0 auto;border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="padding:0 0 12px 0;font-size:18px;font-weight:600;">
|
||||
Oracle Backup {{status}} | {{node}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 0 16px 0;font-size:13px;color:#6c757d;">
|
||||
{{date}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:12px;border:1px solid #e1e4e8;border-radius:4px;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;">
|
||||
<tr>
|
||||
<td style="padding:4px 0;">Full backup</td>
|
||||
<td style="padding:4px 0;text-align:right;">
|
||||
{{full_backup_age}}h / {{full_backup_limit}}h · {{#if full_backup_ok}}OK{{else}}CHECK{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:4px 0;">Incremental</td>
|
||||
<td style="padding:4px 0;text-align:right;">
|
||||
{{cumulative_backup_age}}h / {{cumulative_backup_limit}}h · {{#if cumulative_backup_ok}}OK{{else}}CHECK{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:4px 0;">Backups</td>
|
||||
<td style="padding:4px 0;text-align:right;">{{total_backups}} files ({{total_size_label}})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:4px 0;">Disk usage</td>
|
||||
<td style="padding:4px 0;text-align:right;">{{disk_usage}}%</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{{#if has_errors}}
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;background:#fff5f5;border:1px solid #f1b0b7;border-radius:4px;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;color:#c82333;">Issues</td></tr>
|
||||
{{#each errors}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #f8d7da;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#if has_warnings}}
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;background:#fff8e5;border:1px solid #ffe8a1;border-radius:4px;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;color:#856404;">Warnings</td></tr>
|
||||
{{#each warnings}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #ffe8a1;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;border:1px solid #e1e4e8;border-radius:4px;background:#f9fafb;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;">FULL Backups ({{full_backup_count}} files)</td></tr>
|
||||
{{#if has_full_backups}}
|
||||
{{#each full_backup_list}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">• none detected</td></tr>
|
||||
{{/if}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;border:1px solid #e1e4e8;border-radius:4px;background:#f9fafb;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;">INCREMENTAL Backups ({{incr_backup_count}} files)</td></tr>
|
||||
{{#if has_incr_backups}}
|
||||
{{#each incr_backup_list}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">• none detected</td></tr>
|
||||
{{/if}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;font-size:12px;color:#6c757d;">
|
||||
Next automated check: +24h via Proxmox Monitor
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}Templates created successfully in $TEMPLATE_DIR${NC}"
|
||||
}
|
||||
|
||||
# Function to send notification via PVE::Notify
|
||||
send_pve_notification() {
|
||||
local severity="$1"
|
||||
local status="$2"
|
||||
local data="$3"
|
||||
|
||||
# Create Perl script to call PVE::Notify
|
||||
cat > /tmp/oracle-notify.pl <<'PERL_SCRIPT'
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use PVE::Notify;
|
||||
use JSON;
|
||||
|
||||
my $json_data = do { local $/; <STDIN> };
|
||||
my $data = decode_json($json_data);
|
||||
|
||||
my $severity = $data->{severity} // 'info';
|
||||
my $template_name = 'oracle-backup';
|
||||
|
||||
# Add fields for matching rules
|
||||
my $fields = {
|
||||
type => 'oracle-backup',
|
||||
severity => $severity,
|
||||
hostname => $data->{node} // 'unknown',
|
||||
};
|
||||
|
||||
# Send notification
|
||||
eval {
|
||||
PVE::Notify::notify(
|
||||
$severity,
|
||||
$template_name,
|
||||
$data,
|
||||
$fields
|
||||
);
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
print "Error sending notification: $@\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print "Notification sent successfully\n";
|
||||
PERL_SCRIPT
|
||||
|
||||
chmod +x /tmp/oracle-notify.pl
|
||||
|
||||
# Send notification
|
||||
echo "$data" | perl /tmp/oracle-notify.pl
|
||||
|
||||
rm -f /tmp/oracle-notify.pl
|
||||
}
|
||||
|
||||
# Function to check backups
|
||||
check_backups() {
|
||||
local status="OK"
|
||||
local errors=()
|
||||
local warnings=()
|
||||
|
||||
echo "Checking Oracle backups..."
|
||||
|
||||
local total_backups=0
|
||||
local total_size_label="0G"
|
||||
local full_age_hours="N/A"
|
||||
local cumulative_age_hours="N/A"
|
||||
local full_backup_ok=false
|
||||
local cumulative_backup_ok=false
|
||||
local disk_usage=0
|
||||
local -a backup_entries=()
|
||||
|
||||
if [ ! -d "$BACKUP_PATH" ]; then
|
||||
status="ERROR"
|
||||
errors+=("Backup path $BACKUP_PATH not accessible")
|
||||
else
|
||||
if compgen -G "$BACKUP_PATH"/*.BKP > /dev/null; then
|
||||
total_backups=$(find "$BACKUP_PATH" -maxdepth 1 -type f -name '*.BKP' | wc -l)
|
||||
total_backups=${total_backups//[[:space:]]/}
|
||||
[ -z "$total_backups" ] && total_backups=0
|
||||
local total_size=$(du -shc "$BACKUP_PATH"/*.BKP 2>/dev/null | tail -1 | awk '{print $1}')
|
||||
[ -z "$total_size" ] && total_size="0G"
|
||||
total_size_label="$total_size"
|
||||
|
||||
# Search for FULL backups (both old and new naming conventions)
|
||||
# Old format: *FULL*.BKP, New format: L0_*.BKP
|
||||
local latest_full=$(find "$BACKUP_PATH" -maxdepth 1 -type f \( -name '*FULL*.BKP' -o -name 'L0_*.BKP' \) -printf '%T@ %p\n' | sort -nr | head -1 | cut -d' ' -f2-)
|
||||
if [ -n "$latest_full" ]; then
|
||||
local full_timestamp=$(stat -c %Y "$latest_full")
|
||||
local current_timestamp=$(date +%s)
|
||||
full_age_hours=$(( (current_timestamp - full_timestamp) / 3600 ))
|
||||
if [ "$full_age_hours" -gt "$MAX_FULL_AGE_HOURS" ]; then
|
||||
status="WARNING"
|
||||
warnings+=("FULL backup is $full_age_hours hours old (threshold: $MAX_FULL_AGE_HOURS)")
|
||||
else
|
||||
full_backup_ok=true
|
||||
fi
|
||||
else
|
||||
status="ERROR"
|
||||
errors+=("No FULL backup found")
|
||||
fi
|
||||
|
||||
# Search for INCREMENTAL backups (both old and new naming conventions)
|
||||
# Old format: *INCR*.BKP, *INCREMENTAL*.BKP, *CUMULATIVE*.BKP
|
||||
# New format: L1_*.BKP
|
||||
local latest_cumulative=$(find "$BACKUP_PATH" -maxdepth 1 -type f \( -name '*INCR*.BKP' -o -name '*INCREMENTAL*.BKP' -o -name '*CUMULATIVE*.BKP' -o -name 'L1_*.BKP' \) -printf '%T@ %p\n' | sort -nr | head -1 | cut -d' ' -f2-)
|
||||
if [ -n "$latest_cumulative" ]; then
|
||||
local cumulative_timestamp=$(stat -c %Y "$latest_cumulative")
|
||||
local current_timestamp=$(date +%s)
|
||||
cumulative_age_hours=$(( (current_timestamp - cumulative_timestamp) / 3600 ))
|
||||
if [ "$cumulative_age_hours" -gt "$MAX_CUMULATIVE_AGE_HOURS" ]; then
|
||||
if [ "$status" != "ERROR" ]; then status="WARNING"; fi
|
||||
warnings+=("CUMULATIVE backup is $cumulative_age_hours hours old (threshold: $MAX_CUMULATIVE_AGE_HOURS)")
|
||||
else
|
||||
cumulative_backup_ok=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect ALL FULL backups (both old and new naming conventions)
|
||||
local -a full_backups=()
|
||||
local -a full_backup_entries=()
|
||||
if readarray -t full_backups < <(find "$BACKUP_PATH" -maxdepth 1 -type f \( -name '*FULL*.BKP' -o -name 'L0_*.BKP' \) -printf '%T@ %p\n' | sort -nr | cut -d' ' -f2-); then
|
||||
for backup_file in "${full_backups[@]}"; do
|
||||
[ -z "$backup_file" ] && continue
|
||||
local backup_name=$(basename "$backup_file")
|
||||
local backup_time=$(date -r "$backup_file" '+%Y-%m-%d %H:%M')
|
||||
local backup_size=$(du -sh "$backup_file" 2>/dev/null | cut -f1)
|
||||
[ -z "$backup_size" ] && backup_size="N/A"
|
||||
full_backup_entries+=("$backup_time | $backup_name | $backup_size")
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect ALL INCREMENTAL backups (both old and new naming conventions)
|
||||
local -a incr_backups=()
|
||||
local -a incr_backup_entries=()
|
||||
if readarray -t incr_backups < <(find "$BACKUP_PATH" -maxdepth 1 -type f \( -name '*INCR*.BKP' -o -name '*INCREMENTAL*.BKP' -o -name '*CUMULATIVE*.BKP' -o -name 'L1_*.BKP' \) -printf '%T@ %p\n' | sort -nr | cut -d' ' -f2-); then
|
||||
for backup_file in "${incr_backups[@]}"; do
|
||||
[ -z "$backup_file" ] && continue
|
||||
local backup_name=$(basename "$backup_file")
|
||||
local backup_time=$(date -r "$backup_file" '+%Y-%m-%d %H:%M')
|
||||
local backup_size=$(du -sh "$backup_file" 2>/dev/null | cut -f1)
|
||||
[ -z "$backup_size" ] && backup_size="N/A"
|
||||
incr_backup_entries+=("$backup_time | $backup_name | $backup_size")
|
||||
done
|
||||
fi
|
||||
else
|
||||
status="ERROR"
|
||||
errors+=("No backup files found in $BACKUP_PATH")
|
||||
fi
|
||||
|
||||
local disk_usage_raw=$(df "$BACKUP_PATH" 2>/dev/null | tail -1 | awk '{print int($5)}')
|
||||
if [ -n "$disk_usage_raw" ]; then
|
||||
disk_usage="$disk_usage_raw"
|
||||
else
|
||||
if [ "$status" = "OK" ]; then status="WARNING"; fi
|
||||
warnings+=("Unable to determine disk usage for $BACKUP_PATH")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$disk_usage" -gt 90 ]; then
|
||||
status="ERROR"
|
||||
errors+=("Disk usage critical: ${disk_usage}%")
|
||||
elif [ "$disk_usage" -gt 80 ]; then
|
||||
if [ "$status" != "ERROR" ]; then status="WARNING"; fi
|
||||
warnings+=("Disk usage high: ${disk_usage}%")
|
||||
fi
|
||||
|
||||
local severity="info"
|
||||
[ "$status" = "WARNING" ] && severity="warning"
|
||||
[ "$status" = "ERROR" ] && severity="error"
|
||||
|
||||
local errors_json
|
||||
if [ ${#errors[@]} -eq 0 ]; then
|
||||
errors_json='[]'
|
||||
else
|
||||
errors_json=$(printf '%s\n' "${errors[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local warnings_json
|
||||
if [ ${#warnings[@]} -eq 0 ]; then
|
||||
warnings_json='[]'
|
||||
else
|
||||
warnings_json=$(printf '%s\n' "${warnings[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local full_backup_list_json
|
||||
if [ ${#full_backup_entries[@]} -eq 0 ]; then
|
||||
full_backup_list_json='[]'
|
||||
else
|
||||
full_backup_list_json=$(printf '%s\n' "${full_backup_entries[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local incr_backup_list_json
|
||||
if [ ${#incr_backup_entries[@]} -eq 0 ]; then
|
||||
incr_backup_list_json='[]'
|
||||
else
|
||||
incr_backup_list_json=$(printf '%s\n' "${incr_backup_entries[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local has_errors=false
|
||||
local has_warnings=false
|
||||
local has_full_backups=false
|
||||
local has_incr_backups=false
|
||||
[ ${#errors[@]} -gt 0 ] && has_errors=true
|
||||
[ ${#warnings[@]} -gt 0 ] && has_warnings=true
|
||||
[ ${#full_backup_entries[@]} -gt 0 ] && has_full_backups=true
|
||||
[ ${#incr_backup_entries[@]} -gt 0 ] && has_incr_backups=true
|
||||
|
||||
local json_data=$(cat <<JSON
|
||||
{
|
||||
"severity": "$severity",
|
||||
"node": "$(hostname)",
|
||||
"date": "$(date +'%Y-%m-%d %H:%M:%S')",
|
||||
"status": "$status",
|
||||
"errors": $errors_json,
|
||||
"warnings": $warnings_json,
|
||||
"has_errors": $has_errors,
|
||||
"has_warnings": $has_warnings,
|
||||
"total_backups": $total_backups,
|
||||
"total_size_gb": "${total_size_label%G}",
|
||||
"total_size_label": "$total_size_label",
|
||||
"full_backup_age": "${full_age_hours}",
|
||||
"cumulative_backup_age": "${cumulative_age_hours}",
|
||||
"disk_usage": "${disk_usage}",
|
||||
"full_backup_ok": $([ "$full_backup_ok" = "true" ] && echo "true" || echo "false"),
|
||||
"cumulative_backup_ok": $([ "$cumulative_backup_ok" = "true" ] && echo "true" || echo "false"),
|
||||
"is_error": $([ "$status" = "ERROR" ] && echo "true" || echo "false"),
|
||||
"is_warning": $([ "$status" = "WARNING" ] && echo "true" || echo "false"),
|
||||
"full_backup_list": $full_backup_list_json,
|
||||
"incr_backup_list": $incr_backup_list_json,
|
||||
"has_full_backups": $has_full_backups,
|
||||
"has_incr_backups": $has_incr_backups,
|
||||
"full_backup_count": ${#full_backup_entries[@]},
|
||||
"incr_backup_count": ${#incr_backup_entries[@]},
|
||||
"full_backup_limit": "$MAX_FULL_AGE_HOURS",
|
||||
"cumulative_backup_limit": "$MAX_CUMULATIVE_AGE_HOURS"
|
||||
}
|
||||
JSON
|
||||
)
|
||||
|
||||
if [ "$status" != "OK" ]; then
|
||||
echo -e "${YELLOW}Issues detected, sending notification...${NC}"
|
||||
send_pve_notification "$severity" "$status" "$json_data"
|
||||
else
|
||||
echo -e "${GREEN}All backups are healthy${NC}"
|
||||
# Optionally send success notification (uncomment if desired)
|
||||
# send_pve_notification "info" "$status" "$json_data"
|
||||
fi
|
||||
|
||||
echo "Status: $status"
|
||||
echo "Total backups: $total_backups"
|
||||
echo "Total size: $total_size_label"
|
||||
echo "FULL backup age: $full_age_hours hours"
|
||||
echo "CUMULATIVE backup age: $cumulative_age_hours hours"
|
||||
echo "Disk usage: ${disk_usage}%"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
case "${1:-}" in
|
||||
--install)
|
||||
create_templates
|
||||
echo ""
|
||||
echo -e "${GREEN}Installation complete!${NC}"
|
||||
echo "Next steps:"
|
||||
echo "1. Test the monitor: /opt/scripts/oracle-backup-monitor-proxmox.sh"
|
||||
echo "2. Add to cron: crontab -e"
|
||||
echo " Add line: 0 9 * * * /opt/scripts/oracle-backup-monitor-proxmox.sh"
|
||||
echo "3. Configure notifications in Proxmox GUI if needed:"
|
||||
echo " Datacenter > Notifications > Add matching rules for 'oracle-backup'"
|
||||
;;
|
||||
--help)
|
||||
echo "Oracle Backup Monitor for Proxmox"
|
||||
echo "Usage:"
|
||||
echo " $0 - Check backups and send alerts if issues found"
|
||||
echo " $0 --install - Create notification templates"
|
||||
echo " $0 --help - Show this help"
|
||||
;;
|
||||
*)
|
||||
# Check if templates exist, create if missing
|
||||
if [ ! -f "$TEMPLATE_DIR/oracle-backup-subject.txt.hbs" ]; then
|
||||
echo -e "${YELLOW}Templates not found, creating...${NC}"
|
||||
create_templates
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Run backup check
|
||||
check_backups
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo -e "${RED}Error: jq is not installed${NC}"
|
||||
echo "Install with: apt-get install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
main "$@"
|
||||
43
proxmox/vm109-windows-dr/scripts/rman_backup.bat
Normal file
43
proxmox/vm109-windows-dr/scripts/rman_backup.bat
Normal file
@@ -0,0 +1,43 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM ===================================================================
|
||||
REM Oracle RMAN FULL Backup with Logging
|
||||
REM Runs at: 02:30 AM (scheduled task)
|
||||
REM Duration: ~30 minutes
|
||||
REM ===================================================================
|
||||
|
||||
REM Get script directory (where this .bat file is located)
|
||||
set SCRIPTDIR=%~dp0
|
||||
set LOGDIR=%SCRIPTDIR%logs
|
||||
set TIMESTAMP=%date:~-4,4%%date:~-7,2%%date:~-10,2%_%time:~0,2%%time:~3,2%%time:~6,2%
|
||||
set TIMESTAMP=%TIMESTAMP: =0%
|
||||
set LOGFILE=%LOGDIR%\backup_full_%TIMESTAMP%.log
|
||||
|
||||
REM Create log directory if not exists
|
||||
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
|
||||
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo Oracle RMAN FULL Backup Started >> "%LOGFILE%" 2>&1
|
||||
echo Date: %date% %time% >> "%LOGFILE%" 2>&1
|
||||
echo Script Directory: %SCRIPTDIR% >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo. >> "%LOGFILE%" 2>&1
|
||||
|
||||
REM Run RMAN backup - show in console AND save to log (using PowerShell tee)
|
||||
powershell -Command "& cmd.exe /c 'rman target sys/romfastsoft@roa cmdfile=\"%SCRIPTDIR%rman_backup.txt\"' 2>&1 | Tee-Object -FilePath '%LOGFILE%' -Append"
|
||||
|
||||
set EXITCODE=%ERRORLEVEL%
|
||||
|
||||
echo. >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo Oracle RMAN FULL Backup Completed >> "%LOGFILE%" 2>&1
|
||||
echo Date: %date% %time% >> "%LOGFILE%" 2>&1
|
||||
echo Exit Code: %EXITCODE% >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
|
||||
REM Print summary to console
|
||||
echo [%date% %time%] RMAN FULL backup completed with exit code: %EXITCODE%
|
||||
echo [%date% %time%] Log file: %LOGFILE%
|
||||
|
||||
exit /b %EXITCODE%
|
||||
30
proxmox/vm109-windows-dr/scripts/rman_backup.txt
Normal file
30
proxmox/vm109-windows-dr/scripts/rman_backup.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
RUN {
|
||||
CONFIGURE RETENTION POLICY TO REDUNDANCY 2;
|
||||
CONFIGURE CONTROLFILE AUTOBACKUP ON;
|
||||
CONFIGURE COMPRESSION ALGORITHM 'BASIC';
|
||||
|
||||
# Full backup COMPRESSED + Archive logs (șterge logs după backup)
|
||||
# FORMAT: L0_<dbname>_<YYYYMMDD>_<set#>_<piece#>
|
||||
# Files will be stored in recovery area for easier transfer to DR
|
||||
BACKUP AS COMPRESSED BACKUPSET
|
||||
INCREMENTAL LEVEL 0
|
||||
TAG 'DAILY_FULL_COMPRESSED'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\L0_%d_%T_%s_%p.BKP'
|
||||
DATABASE
|
||||
PLUS ARCHIVELOG DELETE INPUT
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\ARC_%d_%T_%s_%p.BKP';
|
||||
|
||||
# Backup SPFILE și Control File
|
||||
BACKUP AS COMPRESSED BACKUPSET
|
||||
TAG 'SPFILE_BACKUP'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\SPFILE_%d_%T_%s_%p.BKP'
|
||||
SPFILE;
|
||||
|
||||
BACKUP
|
||||
TAG 'CONTROLFILE_BACKUP'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\CF_%d_%T_%s_%p.BKP'
|
||||
CURRENT CONTROLFILE;
|
||||
|
||||
# Cleanup old backups (păstrează ultimele 2 - REDUNDANCY 2)
|
||||
DELETE NOPROMPT OBSOLETE;
|
||||
}
|
||||
43
proxmox/vm109-windows-dr/scripts/rman_backup_incremental.bat
Normal file
43
proxmox/vm109-windows-dr/scripts/rman_backup_incremental.bat
Normal file
@@ -0,0 +1,43 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM ===================================================================
|
||||
REM Oracle RMAN INCREMENTAL/CUMULATIVE Backup with Logging
|
||||
REM Runs at: 13:00 and 18:00 (scheduled tasks)
|
||||
REM Duration: ~5-10 minutes
|
||||
REM ===================================================================
|
||||
|
||||
REM Get script directory (where this .bat file is located)
|
||||
set SCRIPTDIR=%~dp0
|
||||
set LOGDIR=%SCRIPTDIR%logs
|
||||
set TIMESTAMP=%date:~-4,4%%date:~-7,2%%date:~-10,2%_%time:~0,2%%time:~3,2%%time:~6,2%
|
||||
set TIMESTAMP=%TIMESTAMP: =0%
|
||||
set LOGFILE=%LOGDIR%\backup_incremental_%TIMESTAMP%.log
|
||||
|
||||
REM Create log directory if not exists
|
||||
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
|
||||
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo Oracle RMAN INCREMENTAL Backup Started >> "%LOGFILE%" 2>&1
|
||||
echo Date: %date% %time% >> "%LOGFILE%" 2>&1
|
||||
echo Script Directory: %SCRIPTDIR% >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo. >> "%LOGFILE%" 2>&1
|
||||
|
||||
REM Run RMAN backup - show in console AND save to log (using PowerShell tee)
|
||||
powershell -Command "& cmd.exe /c 'rman target sys/romfastsoft@roa cmdfile=\"%SCRIPTDIR%rman_backup_incremental.txt\"' 2>&1 | Tee-Object -FilePath '%LOGFILE%' -Append"
|
||||
|
||||
set EXITCODE=%ERRORLEVEL%
|
||||
|
||||
echo. >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
echo Oracle RMAN INCREMENTAL Backup Completed >> "%LOGFILE%" 2>&1
|
||||
echo Date: %date% %time% >> "%LOGFILE%" 2>&1
|
||||
echo Exit Code: %EXITCODE% >> "%LOGFILE%" 2>&1
|
||||
echo ========================================= >> "%LOGFILE%" 2>&1
|
||||
|
||||
REM Print summary to console
|
||||
echo [%date% %time%] RMAN INCREMENTAL backup completed with exit code: %EXITCODE%
|
||||
echo [%date% %time%] Log file: %LOGFILE%
|
||||
|
||||
exit /b %EXITCODE%
|
||||
26
proxmox/vm109-windows-dr/scripts/rman_backup_incremental.txt
Normal file
26
proxmox/vm109-windows-dr/scripts/rman_backup_incremental.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
RUN {
|
||||
# Incremental Level 1 CUMULATIVE backup
|
||||
# Backup doar modificările de la ultimul Level 0 (full backup de la 02:00 AM)
|
||||
# FORMAT: L1_<dbname>_<YYYYMMDD>_<set#>_<piece#>
|
||||
# Files will be stored in recovery area for easier transfer to DR
|
||||
BACKUP AS COMPRESSED BACKUPSET
|
||||
INCREMENTAL LEVEL 1 CUMULATIVE
|
||||
TAG 'MIDDAY_INCREMENTAL'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\L1_%d_%T_%s_%p.BKP'
|
||||
DATABASE
|
||||
PLUS ARCHIVELOG DELETE INPUT
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\ARC_%d_%T_%s_%p.BKP';
|
||||
|
||||
# Backup SPFILE și controlfile (pentru siguranță)
|
||||
BACKUP AS COMPRESSED BACKUPSET
|
||||
TAG 'SPFILE_BACKUP'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\SPFILE_%d_%T_%s_%p.BKP'
|
||||
SPFILE;
|
||||
|
||||
BACKUP
|
||||
TAG 'CONTROLFILE_BACKUP'
|
||||
FORMAT 'C:\Users\oracle\recovery_area\ROA\autobackup\CF_%d_%T_%s_%p.BKP'
|
||||
CURRENT CONTROLFILE;
|
||||
|
||||
# NU ștergem obsolete aici - se face la full backup
|
||||
}
|
||||
550
proxmox/vm109-windows-dr/scripts/rman_restore_from_zero.ps1
Normal file
550
proxmox/vm109-windows-dr/scripts/rman_restore_from_zero.ps1
Normal file
@@ -0,0 +1,550 @@
|
||||
# RMAN Restore Database FROM ZERO - Clean State (PowerShell)
|
||||
# Backups are on F:\ (NFS mount from Proxmox host)
|
||||
# Run as: Administrator
|
||||
# Location: D:\oracle\scripts\rman_restore_from_zero.ps1
|
||||
#
|
||||
# Parameters:
|
||||
# -TestMode: Skip service reconfiguration and Listener startup (for weekly DR tests)
|
||||
|
||||
param(
|
||||
[switch]$TestMode
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
$env:ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
|
||||
$env:ORACLE_SID = "ROA"
|
||||
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
|
||||
|
||||
Write-Host "============================================"
|
||||
Write-Host "RMAN Database Restore FROM ZERO"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "Database: ROA"
|
||||
Write-Host "DBID: 1363569330"
|
||||
Write-Host "Backups: F:\ROA\autobackup (NFS mount from Proxmox)"
|
||||
Write-Host ""
|
||||
Write-Host "This script will:"
|
||||
Write-Host " 1. CLEANUP: Delete any existing database files"
|
||||
Write-Host " 2. RESTORE: Restore from F:\ backups"
|
||||
Write-Host " 3. VERIFY: Check database is working"
|
||||
Write-Host ""
|
||||
|
||||
# Verify F:\ mount is accessible
|
||||
if (-not (Test-Path "F:\ROA\autobackup")) {
|
||||
Write-Host "ERROR: F:\ROA\autobackup not accessible!" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Please verify:"
|
||||
Write-Host " 1. F:\ drive is mounted: dir F:\"
|
||||
Write-Host " 2. NFS mount command: mount -o rw,nolock,mtype=hard,timeout=60 10.0.20.202:/mnt/pve/oracle-backups F:"
|
||||
Write-Host " 3. Proxmox host is reachable: ping 10.0.20.202"
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[OK] F:\ROA\autobackup is accessible"
|
||||
Write-Host ""
|
||||
|
||||
# Create directories with proper permissions
|
||||
try {
|
||||
New-Item -ItemType Directory -Path "D:\oracle\temp" -Force -ErrorAction Stop | Out-Null
|
||||
New-Item -ItemType Directory -Path "D:\oracle\logs" -Force -ErrorAction Stop | Out-Null
|
||||
Write-Host "[OK] Created required directories"
|
||||
} catch {
|
||||
Write-Host "ERROR: Failed to create directories: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "============================================"
|
||||
Write-Host "STEP 1: CLEANUP - Delete existing database"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "Calling cleanup_database.ps1..."
|
||||
Write-Host ""
|
||||
|
||||
# Call cleanup script with /SILENT flag
|
||||
& "D:\oracle\scripts\cleanup_database.ps1" /SILENT
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ""
|
||||
Write-Host "ERROR: Cleanup failed!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "[OK] Cleanup complete - VM is in clean state"
|
||||
Write-Host ""
|
||||
Write-Host "Starting restore in 2 seconds..."
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
Write-Host "============================================"
|
||||
Write-Host "STEP 2: RESTORE - Restore from F:\ backups"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
|
||||
# Step 2.1: Check Oracle service (create only if missing)
|
||||
Write-Host "[2.1] Checking Oracle service..."
|
||||
$service = Get-Service -Name "OracleServiceROA" -ErrorAction SilentlyContinue
|
||||
|
||||
if ($service) {
|
||||
Write-Host "[OK] Oracle service already exists, skipping creation (15s saved!)" -ForegroundColor Green
|
||||
Write-Host " Service will be reused for this restore"
|
||||
|
||||
# Ensure service is running (required for SQL*Plus connection)
|
||||
if ($service.Status -ne "Running") {
|
||||
Write-Host " Service is stopped, starting it (may take 30-60 seconds)..."
|
||||
|
||||
# Start service in background job to avoid blocking
|
||||
$startJob = Start-Job -ScriptBlock {
|
||||
Start-Service -Name "OracleServiceROA" -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Poll for service status with timeout
|
||||
$maxWait = 60
|
||||
$elapsed = 0
|
||||
$pollInterval = 3
|
||||
$serviceStarted = $false
|
||||
|
||||
while ($elapsed -lt $maxWait) {
|
||||
Start-Sleep -Seconds $pollInterval
|
||||
$elapsed += $pollInterval
|
||||
|
||||
# Refresh service status
|
||||
$currentService = Get-Service -Name "OracleServiceROA" -ErrorAction SilentlyContinue
|
||||
if ($currentService -and $currentService.Status -eq "Running") {
|
||||
$serviceStarted = $true
|
||||
Write-Host " [OK] Service started successfully after $elapsed seconds"
|
||||
break
|
||||
}
|
||||
|
||||
if ($elapsed % 15 -eq 0) {
|
||||
Write-Host " Still waiting for service to start... ($elapsed/$maxWait seconds)"
|
||||
}
|
||||
}
|
||||
|
||||
# Cleanup background job
|
||||
Stop-Job -Job $startJob -ErrorAction SilentlyContinue
|
||||
Remove-Job -Job $startJob -ErrorAction SilentlyContinue
|
||||
|
||||
if (-not $serviceStarted) {
|
||||
Write-Host " WARNING: Service did not start within $maxWait seconds" -ForegroundColor Yellow
|
||||
Write-Host " This may cause SQL*Plus connection issues (ORA-12560)"
|
||||
Write-Host " Attempting to continue anyway..."
|
||||
}
|
||||
} else {
|
||||
Write-Host " Service is already running"
|
||||
}
|
||||
} else {
|
||||
Write-Host " Oracle service not found, creating from PFILE..."
|
||||
|
||||
# Check if PFILE exists, create if missing
|
||||
$pfilePath = "C:\Users\oracle\admin\ROA\pfile\initROA.ora"
|
||||
if (-not (Test-Path $pfilePath)) {
|
||||
Write-Host " PFILE not found, creating default initROA.ora..." -ForegroundColor Yellow
|
||||
|
||||
# Create directory if needed
|
||||
$pfileDir = Split-Path $pfilePath -Parent
|
||||
if (-not (Test-Path $pfileDir)) {
|
||||
New-Item -ItemType Directory -Path $pfileDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# Create PFILE with tested configuration
|
||||
$pfileContent = @"
|
||||
# Initialization Parameters for ROA Database - DR VM
|
||||
# Auto-generated by rman_restore_from_zero.ps1 - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
||||
|
||||
# Database Identification
|
||||
db_name=ROA
|
||||
db_unique_name=ROA
|
||||
|
||||
# Memory Configuration
|
||||
memory_target=1024M
|
||||
memory_max_target=1024M
|
||||
|
||||
# File Locations
|
||||
control_files=('C:\Users\oracle\oradata\ROA\control01.ctl', 'C:\Users\oracle\recovery_area\ROA\control02.ctl')
|
||||
db_recovery_file_dest='C:\Users\oracle\recovery_area'
|
||||
db_recovery_file_dest_size=50G
|
||||
audit_file_dest='C:\Users\oracle\admin\ROA\adump'
|
||||
|
||||
# Redo and Archive Log
|
||||
log_archive_format=%t_%s_%r.dbf
|
||||
|
||||
# Compatibility
|
||||
compatible=19.0.0
|
||||
|
||||
# Character Set
|
||||
nls_language=AMERICAN
|
||||
nls_territory=AMERICA
|
||||
|
||||
# Processes and Sessions
|
||||
processes=300
|
||||
sessions=472
|
||||
|
||||
# Miscellaneous
|
||||
diagnostic_dest='C:\Users\oracle'
|
||||
_allow_resetlogs_corruption=TRUE
|
||||
"@
|
||||
|
||||
try {
|
||||
$pfileContent | Out-File -FilePath $pfilePath -Encoding ASCII -ErrorAction Stop
|
||||
Write-Host " [OK] Created PFILE: $pfilePath" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "ERROR: Failed to create PFILE: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
& oradim -new -sid ROA -startmode auto -pfile $pfilePath 2>&1 | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Failed to create Oracle service" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "[OK] Oracle service created successfully (AUTOMATIC startup)"
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
# Step 2.2: Startup NOMOUNT
|
||||
Write-Host "[2.2] Starting database in NOMOUNT mode..."
|
||||
|
||||
# First, ensure any partially started instance is shut down
|
||||
# (Service auto-start may have started instance in error state without control files)
|
||||
Write-Host " Ensuring clean state - shutting down any existing instance..."
|
||||
$cleanupSQL = @"
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
SHUTDOWN ABORT;
|
||||
EXIT;
|
||||
"@
|
||||
$cleanupSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
|
||||
# Now start cleanly in NOMOUNT
|
||||
Write-Host " Starting fresh instance in NOMOUNT mode..."
|
||||
$nomountSQL = @"
|
||||
STARTUP NOMOUNT PFILE='C:\Users\oracle\admin\ROA\pfile\initROA.ora';
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$nomountSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Failed to startup NOMOUNT" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "[OK] Database started in NOMOUNT mode"
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Step 2.3: Copy backups and create RMAN script
|
||||
Write-Host "[2.3] Preparing RMAN restore..."
|
||||
$rmanScript = "D:\oracle\temp\restore_from_zero.rman"
|
||||
$logFile = "D:\oracle\logs\restore_from_zero.log"
|
||||
|
||||
# Copy backups from F:\ to recovery area (mode-dependent)
|
||||
New-Item -ItemType Directory -Path "C:\Users\oracle\recovery_area\ROA\autobackup" -Force | Out-Null
|
||||
|
||||
if ($TestMode) {
|
||||
Write-Host "[INFO] Copying selected backups from F:\ROA\autobackup to recovery area..."
|
||||
Write-Host " TEST MODE: Only latest backup set (faster for weekly tests)"
|
||||
} else {
|
||||
Write-Host "[INFO] Copying all backups from F:\ROA\autobackup to recovery area..."
|
||||
Write-Host " STANDALONE MODE: All backups for maximum DR safety"
|
||||
}
|
||||
|
||||
# Select backup files based on mode (TestMode vs Standalone)
|
||||
try {
|
||||
if ($TestMode) {
|
||||
# TEST MODE: Copy latest L0 backup set + all incrementals/archives
|
||||
Write-Host "[INFO] TEST MODE: Selecting latest backup set using naming convention..." -ForegroundColor Cyan
|
||||
|
||||
# Check if new naming convention is in use (L0_*, L1_*, etc.)
|
||||
$l0Backups = Get-ChildItem "F:\ROA\autobackup\L0_*.BKP" -ErrorAction Continue |
|
||||
Sort-Object LastWriteTime -Descending
|
||||
|
||||
if ($l0Backups.Count -gt 0) {
|
||||
# New naming convention detected - use smart selection
|
||||
Write-Host "[INFO] Using naming convention for optimized backup selection" -ForegroundColor Cyan
|
||||
|
||||
$latestL0 = $l0Backups[0]
|
||||
# Extract date from filename: L0_ROA_20251011_123_1.BKP -> 20251011
|
||||
if ($latestL0.Name -match 'L0_\w+_(\d{8})_') {
|
||||
$backupDate = $Matches[1]
|
||||
Write-Host "[INFO] Latest Level 0 backup date: $backupDate" -ForegroundColor Cyan
|
||||
Write-Host " Base file: $($latestL0.Name)" -ForegroundColor Cyan
|
||||
|
||||
# Select all files from this backup set:
|
||||
# - All L0_*_<date>_* (all pieces of Level 0)
|
||||
# - All L1_*_<date>_* or later (incrementals from same day or after)
|
||||
# - All ARC_*_<date>_* or later (archive logs)
|
||||
# - All SPFILE_* and CF_* (needed for restore)
|
||||
|
||||
$backupFiles = Get-ChildItem "F:\ROA\autobackup\*.BKP" -ErrorAction Continue |
|
||||
Where-Object {
|
||||
$_.Name -match "^L0_\w+_${backupDate}_" -or # Level 0 pieces
|
||||
$_.Name -match "^L1_\w+_\d{8}_" -or # All Level 1 incrementals
|
||||
$_.Name -match "^ARC_\w+_\d{8}_" -or # All archive logs
|
||||
$_.Name -match "^SPFILE_\w+_${backupDate}_" -or # SPFILE from same day
|
||||
$_.Name -match "^CF_\w+_${backupDate}_" -or # Controlfile from same day
|
||||
$_.Name -match "^O1_MF_S_" # Autobackup control files (always needed)
|
||||
}
|
||||
|
||||
Write-Host "[INFO] Selected $($backupFiles.Count) files for restore:" -ForegroundColor Cyan
|
||||
Write-Host " - Level 0 pieces for date $backupDate" -ForegroundColor Cyan
|
||||
Write-Host " - All Level 1 incrementals" -ForegroundColor Cyan
|
||||
Write-Host " - All archive logs" -ForegroundColor Cyan
|
||||
Write-Host " - SPFILE and Control file backups" -ForegroundColor Cyan
|
||||
|
||||
} else {
|
||||
Write-Host "WARNING: Cannot parse date from L0 filename, using ALL L0/L1/ARC files" -ForegroundColor Yellow
|
||||
$backupFiles = Get-ChildItem "F:\ROA\autobackup\*.BKP" -ErrorAction Continue |
|
||||
Where-Object { $_.Name -match "^(L0_|L1_|ARC_|SPFILE_|CF_)" }
|
||||
}
|
||||
|
||||
} else {
|
||||
# Old naming convention (autobackup format) - fallback to copying all
|
||||
Write-Host "[INFO] Old naming convention detected - copying ALL backups for safety" -ForegroundColor Yellow
|
||||
Write-Host " (New naming convention will be used after next backup runs)" -ForegroundColor Yellow
|
||||
$backupFiles = Get-ChildItem "F:\ROA\autobackup\*.BKP" -ErrorAction Continue
|
||||
}
|
||||
|
||||
Write-Host "[INFO] Total files selected: $($backupFiles.Count)" -ForegroundColor Cyan
|
||||
|
||||
} else {
|
||||
# STANDALONE MODE: Copy ALL backups (disaster recovery - maximum safety with fallback)
|
||||
Write-Host "[INFO] STANDALONE MODE: Copying ALL backups for maximum DR safety..." -ForegroundColor Yellow
|
||||
$backupFiles = Get-ChildItem "F:\ROA\autobackup\*.BKP" -ErrorAction Continue
|
||||
Write-Host "[INFO] Full DR restore - will copy all available backups (includes redundancy)" -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "WARNING: Cannot enumerate backup files on F: drive - $_" -ForegroundColor Yellow
|
||||
$backupFiles = @()
|
||||
}
|
||||
|
||||
# Validate backup count
|
||||
$minRequired = 2
|
||||
if ($backupFiles.Count -lt $minRequired) {
|
||||
Write-Host "ERROR: Insufficient backup files found on F: drive (found: $($backupFiles.Count))" -ForegroundColor Red
|
||||
Write-Host " At least $minRequired backup files required for successful restore"
|
||||
Write-Host " Checking F:\ROA\autobackup directory..."
|
||||
try {
|
||||
$dirCheck = Get-ChildItem "F:\ROA\autobackup" -ErrorAction Continue
|
||||
Write-Host " Directory contents: $($dirCheck.Count) files"
|
||||
foreach ($file in $dirCheck) {
|
||||
Write-Host " $($file.Name) - $([math]::Round($file.Length / 1GB, 2)) GB" -ForegroundColor Gray
|
||||
}
|
||||
} catch {
|
||||
Write-Host " Cannot access directory: $_" -ForegroundColor Red
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[INFO] Found $($backupFiles.Count) backup files, total size: $([math]::Round(($backupFiles | Measure-Object -Property Length -Sum).Sum / 1GB, 2)) GB"
|
||||
|
||||
# Copy backups with better error handling
|
||||
Write-Host "[INFO] Starting backup copy operation..."
|
||||
$copyErrors = @()
|
||||
foreach ($backupFile in $backupFiles) {
|
||||
try {
|
||||
Write-Host "[INFO] Copying $($backupFile.Name)..."
|
||||
Copy-Item $backupFile.FullName "C:\Users\oracle\recovery_area\ROA\autobackup\" -Force -ErrorAction Stop
|
||||
Write-Host "[OK] Copied $($backupFile.Name)" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "ERROR: Failed to copy $($backupFile.Name) - $_" -ForegroundColor Red
|
||||
$copyErrors += "$($backupFile.Name): $_"
|
||||
}
|
||||
}
|
||||
|
||||
if ($copyErrors.Count -gt 0) {
|
||||
Write-Host "ERROR: Backup copy failed for $($copyErrors.Count) files" -ForegroundColor Red
|
||||
foreach ($error in $copyErrors) {
|
||||
Write-Host " $error" -ForegroundColor Red
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Verify copied backups
|
||||
try {
|
||||
$copiedFiles = Get-ChildItem "C:\Users\oracle\recovery_area\ROA\autobackup\*.BKP" -ErrorAction Continue
|
||||
} catch {
|
||||
Write-Host "ERROR: Cannot verify copied backups - $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($copiedFiles.Count -ne $backupFiles.Count) {
|
||||
Write-Host "ERROR: Backup copy verification failed - file count mismatch" -ForegroundColor Red
|
||||
Write-Host " Expected: $($backupFiles.Count), Copied: $($copiedFiles.Count)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[OK] All $($copiedFiles.Count) backups copied and verified to recovery area"
|
||||
|
||||
# Create RMAN script
|
||||
$rmanContent = @"
|
||||
SET DBID 1363569330;
|
||||
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
RESTORE CONTROLFILE FROM AUTOBACKUP;
|
||||
RELEASE CHANNEL ch1;
|
||||
}
|
||||
|
||||
ALTER DATABASE MOUNT;
|
||||
|
||||
CATALOG START WITH 'C:/USERS/ORACLE/RECOVERY_AREA/ROA/AUTOBACKUP' NOPROMPT;
|
||||
|
||||
CROSSCHECK BACKUP;
|
||||
DELETE NOPROMPT EXPIRED BACKUP;
|
||||
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK;
|
||||
RESTORE DATABASE;
|
||||
RELEASE CHANNEL ch1;
|
||||
RELEASE CHANNEL ch2;
|
||||
}
|
||||
|
||||
RUN {
|
||||
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
|
||||
RECOVER DATABASE NOREDO;
|
||||
RELEASE CHANNEL ch1;
|
||||
}
|
||||
|
||||
ALTER DATABASE OPEN RESETLOGS;
|
||||
|
||||
DELETE NOPROMPT OBSOLETE;
|
||||
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$rmanContent | Out-File -FilePath $rmanScript -Encoding ASCII
|
||||
Write-Host "[OK] RMAN script created: $rmanScript"
|
||||
|
||||
# Step 2.4: Run RMAN restore
|
||||
Write-Host "[2.4] Running RMAN restore (this will take 10-20 minutes)..."
|
||||
Write-Host " Log file: $logFile"
|
||||
Write-Host ""
|
||||
|
||||
& rman target / cmdfile=$rmanScript log=$logFile
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ""
|
||||
Write-Host "ERROR: RMAN restore failed!" -ForegroundColor Red
|
||||
Write-Host "Check log: $logFile"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "[OK] RMAN restore completed successfully!"
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "============================================"
|
||||
Write-Host "STEP 3: VERIFY - Check database status"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "[3.1] Verifying database..."
|
||||
|
||||
$verifySQL = @"
|
||||
SET PAGESIZE 100 LINESIZE 200
|
||||
COLUMN info FORMAT A80
|
||||
SELECT 'DB_NAME: ' || NAME || ', OPEN_MODE: ' || OPEN_MODE AS info FROM V`$DATABASE;
|
||||
SELECT 'INSTANCE: ' || INSTANCE_NAME || ', STATUS: ' || STATUS AS info FROM V`$INSTANCE;
|
||||
SELECT 'TABLESPACES: ' || COUNT(*) AS info FROM DBA_TABLESPACES;
|
||||
SELECT 'DATAFILES: ' || COUNT(*) AS info FROM DBA_DATA_FILES;
|
||||
SELECT 'TABLES: ' || COUNT(*) AS info FROM DBA_TABLES WHERE OWNER NOT IN ('SYS','SYSTEM');
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$verifySQL | & sqlplus -S / as sysdba
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "[3.2] Creating SPFILE for database persistence..."
|
||||
$spfileSQL = @"
|
||||
CREATE SPFILE FROM PFILE='C:\Users\oracle\admin\ROA\pfile\initROA.ora';
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$spfileSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "WARNING: Failed to create SPFILE - database may not persist after connections close" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "[OK] SPFILE created successfully"
|
||||
|
||||
# Check if running in TestMode (weekly DR test)
|
||||
if ($TestMode) {
|
||||
Write-Host "[3.3] Running in TEST MODE - skipping service reconfiguration"
|
||||
Write-Host " Database is OPEN and ready for verification"
|
||||
Write-Host " Service will remain configured with PFILE (OK for testing)"
|
||||
} else {
|
||||
# Full configuration for standalone/production use
|
||||
Write-Host "[3.3] Reconfiguring Oracle service to use SPFILE..."
|
||||
|
||||
# Shutdown database cleanly
|
||||
Write-Host " Shutting down database temporarily..."
|
||||
$shutdownSQL = @"
|
||||
SHUTDOWN IMMEDIATE;
|
||||
EXIT;
|
||||
"@
|
||||
$shutdownSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Delete and recreate service with SPFILE
|
||||
Write-Host " Recreating service with SPFILE..."
|
||||
& oradim -delete -sid ROA 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
& oradim -new -sid ROA -startmode auto -spfile 2>&1 | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host " WARNING: Failed to recreate service with SPFILE" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " [OK] Service now configured with SPFILE and AUTOMATIC startup"
|
||||
}
|
||||
|
||||
# Restart database
|
||||
Write-Host " Starting database with SPFILE..."
|
||||
$startupSQL = @"
|
||||
STARTUP;
|
||||
EXIT;
|
||||
"@
|
||||
$startupSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 3
|
||||
Write-Host "[OK] Database restarted with SPFILE configuration"
|
||||
|
||||
# Start Oracle Listener
|
||||
Write-Host "[3.4] Starting Oracle Listener..."
|
||||
|
||||
# Set Listener service to AUTOMATIC and start it
|
||||
Set-Service -Name "OracleOraDB19Home1TNSListener" -StartupType Automatic -ErrorAction SilentlyContinue
|
||||
Start-Service -Name "OracleOraDB19Home1TNSListener" -ErrorAction SilentlyContinue
|
||||
|
||||
if ((Get-Service -Name "OracleOraDB19Home1TNSListener" -ErrorAction SilentlyContinue).Status -eq "Running") {
|
||||
Write-Host "[OK] Listener started successfully"
|
||||
} else {
|
||||
Write-Host "WARNING: Failed to start Listener automatically, trying lsnrctl..." -ForegroundColor Yellow
|
||||
& lsnrctl start 2>&1 | Out-Null
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
# Register database with listener
|
||||
$registerSQL = @"
|
||||
ALTER SYSTEM REGISTER;
|
||||
EXIT;
|
||||
"@
|
||||
$registerSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
|
||||
Write-Host "[OK] Database registered with Listener"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "============================================"
|
||||
Write-Host "Database Restore FROM ZERO Complete!"
|
||||
Write-Host "============================================"
|
||||
Write-Host ""
|
||||
Write-Host "Restore log: $logFile"
|
||||
Write-Host ""
|
||||
Write-Host "Database is OPEN and ready for testing!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Next steps:"
|
||||
Write-Host " 1. Test application connectivity"
|
||||
Write-Host " 2. Verify data integrity"
|
||||
Write-Host " 3. Run cleanup_database.ps1 to remove database after test"
|
||||
Write-Host " 4. Shutdown DR VM to conserve resources"
|
||||
Write-Host ""
|
||||
|
||||
exit 0
|
||||
231
proxmox/vm109-windows-dr/scripts/transfer_backups.ps1
Normal file
231
proxmox/vm109-windows-dr/scripts/transfer_backups.ps1
Normal file
@@ -0,0 +1,231 @@
|
||||
# Transfer Oracle Backups (Full + Incremental) towards DR Server
|
||||
# Script UNIFICAT - poate fi rulat după orice tip de backup
|
||||
# Transferă TOATE fișierele backup, skip-uiește duplicatele automat
|
||||
#
|
||||
# Poate fi apelat de:
|
||||
# - Task Scheduler după full backup (03:00 AM)
|
||||
# - Task Scheduler după incremental backup (14:30)
|
||||
# - Manual oricând pentru recovery
|
||||
|
||||
param(
|
||||
[string]$SourceFRA = "C:\Users\Oracle\recovery_area\ROA",
|
||||
[string]$DRHost = "10.0.20.202",
|
||||
[int]$DRPort = 22,
|
||||
[string]$DRUser = "root",
|
||||
[string]$DRPath = "/mnt/pve/oracle-backups/ROA/autobackup",
|
||||
[string]$SSHKeyPath = "$env:USERPROFILE\.ssh\id_rsa",
|
||||
[int]$RetentionDays = 2,
|
||||
[string]$LogFile = "D:\rman_backup\logs\transfer_$(Get-Date -Format 'yyyyMMdd_HHmm').log"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
function Write-Log {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logLine = "[$timestamp] [$Level] $Message"
|
||||
Write-Host $logLine
|
||||
Add-Content -Path $LogFile -Value $logLine -Encoding UTF8 -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
function Test-SSHConnection {
|
||||
Write-Log "Testing SSH connection to $DRHost`:$DRPort..."
|
||||
|
||||
try {
|
||||
# Folosește -n pentru a nu citi din stdin (fix pentru blocare)
|
||||
$null = & ssh -n -p $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o ConnectTimeout=10 "${DRUser}@${DRHost}" "exit 0" 2>&1
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Log "SSH connection successful" "SUCCESS"
|
||||
return $true
|
||||
} else {
|
||||
Write-Log "SSH connection failed with exit code: $LASTEXITCODE" "ERROR"
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Log "SSH connection error: $_" "ERROR"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Get-AllBackupFiles {
|
||||
Write-Log "Searching for all backup files in FRA..."
|
||||
|
||||
$backupFiles = @()
|
||||
|
||||
$searchPaths = @(
|
||||
"$SourceFRA\BACKUPSET",
|
||||
"$SourceFRA\AUTOBACKUP"
|
||||
)
|
||||
|
||||
foreach ($path in $searchPaths) {
|
||||
if (Test-Path $path) {
|
||||
# Get ALL backup files (duplicates will be skipped during transfer)
|
||||
$files = Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue |
|
||||
Where-Object {
|
||||
$_.Name -match '\.(BKP|bkp)$' -and
|
||||
$_.Name -notlike "*__TAG_*" # Exclude old uncompressed backups
|
||||
} |
|
||||
Sort-Object LastWriteTime -Descending
|
||||
|
||||
$backupFiles += $files
|
||||
}
|
||||
}
|
||||
|
||||
if ($backupFiles.Count -eq 0) {
|
||||
Write-Log "No backup files found!" "WARNING"
|
||||
return @()
|
||||
}
|
||||
|
||||
$totalSizeGB = ($backupFiles | Measure-Object -Property Length -Sum).Sum / 1GB
|
||||
Write-Log "Found $($backupFiles.Count) backup files, total size: $([math]::Round($totalSizeGB, 2)) GB"
|
||||
|
||||
return $backupFiles
|
||||
}
|
||||
|
||||
function Transfer-FileToDR {
|
||||
param([System.IO.FileInfo]$File, [string]$DestPath)
|
||||
|
||||
$fileName = $File.Name
|
||||
$fileSizeMB = [math]::Round($File.Length / 1MB, 2)
|
||||
|
||||
try {
|
||||
# Check dacă fișierul există deja pe DR (skip duplicates) - Linux bash command
|
||||
$checkCmd = "test -f '$DestPath/$fileName' && echo 'True' || echo 'False'"
|
||||
$checkResult = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $checkCmd 2>&1
|
||||
|
||||
if ($checkResult -match "True") {
|
||||
Write-Log "Skipping (already on DR): $fileName" "INFO"
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-Log "Transferring: $fileName ($fileSizeMB MB)"
|
||||
|
||||
# SCP transfer - NO compression (files already compressed by RMAN)
|
||||
# Use cipher aes128-gcm for better performance
|
||||
$null = & scp -P $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o Compression=no -o Cipher=aes128-gcm@openssh.com $File.FullName "${DRUser}@${DRHost}:${DestPath}/" 2>&1
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Log "Transferred: $fileName" "SUCCESS"
|
||||
return $true
|
||||
} else {
|
||||
Write-Log "Failed to transfer: $fileName (exit code: $LASTEXITCODE)" "ERROR"
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Log "Transfer error for $fileName : $_" "ERROR"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Cleanup-OldBackupsOnDR {
|
||||
Write-Log "Cleaning up old backups on DR (keeping last $RetentionDays days)..."
|
||||
|
||||
try {
|
||||
# Count fișiere înainte de cleanup
|
||||
$countBefore = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "find '$DRPath' -name '*.BKP' -type f | wc -l" 2>&1
|
||||
Write-Log "Backups before cleanup: $countBefore"
|
||||
|
||||
# Cleanup: șterge fișiere mai vechi de $RetentionDays zile - Linux find command
|
||||
# -mtime +N înseamnă "mai vechi de N zile", deci pentru a păstra RetentionDays zile, folosim +($RetentionDays - 1)
|
||||
$mtimeDays = $RetentionDays - 1
|
||||
$cleanupCmd = "find '$DRPath' -name '*.BKP' -type f -mtime +$mtimeDays -delete 2>&1"
|
||||
$result = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $cleanupCmd 2>&1
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Log "Cleanup warning: $result" "WARNING"
|
||||
}
|
||||
|
||||
# Count fișiere după cleanup
|
||||
$countAfter = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "find '$DRPath' -name '*.BKP' -type f | wc -l" 2>&1
|
||||
$deleted = [int]$countBefore - [int]$countAfter
|
||||
|
||||
Write-Log "Cleanup completed: Deleted $deleted old backup files, $countAfter remaining"
|
||||
} catch {
|
||||
Write-Log "Cleanup error: $_" "WARNING"
|
||||
}
|
||||
}
|
||||
|
||||
# ==================== MAIN ====================
|
||||
|
||||
try {
|
||||
Write-Log "========================================="
|
||||
Write-Log "Oracle Backup Transfer Started (UNIFIED)"
|
||||
Write-Log "========================================="
|
||||
Write-Log "Source FRA: $SourceFRA"
|
||||
Write-Log "DR Server: $DRHost"
|
||||
Write-Log "DR Path: $DRPath"
|
||||
|
||||
# Verificare prerequisite
|
||||
if (-not (Test-Path $SourceFRA)) {
|
||||
throw "Source FRA path not found: $SourceFRA"
|
||||
}
|
||||
|
||||
if (-not (Test-Path $SSHKeyPath)) {
|
||||
throw "SSH key not found: $SSHKeyPath"
|
||||
}
|
||||
|
||||
# Test SSH connection
|
||||
if (-not (Test-SSHConnection)) {
|
||||
throw "Cannot connect to DR server via SSH"
|
||||
}
|
||||
|
||||
# Creare director pe DR - Linux mkdir command
|
||||
Write-Log "Ensuring DR directory exists..."
|
||||
$null = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "mkdir -p '$DRPath'" 2>&1
|
||||
|
||||
# Găsește TOATE backup-urile
|
||||
$backupFiles = Get-AllBackupFiles
|
||||
|
||||
if ($backupFiles.Count -eq 0) {
|
||||
Write-Log "No backup files to transfer (this might be normal for first run)" "WARNING"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Transfer fișiere
|
||||
Write-Log "Starting file transfer..."
|
||||
$successCount = 0
|
||||
$failCount = 0
|
||||
$skippedCount = 0
|
||||
|
||||
foreach ($file in $backupFiles) {
|
||||
$result = Transfer-FileToDR -File $file -DestPath $DRPath
|
||||
|
||||
if ($result) {
|
||||
# Check if it was skipped or transferred
|
||||
$fileName = $file.Name
|
||||
$checkCmd = "test -f '$DRPath/$fileName' && echo 'True' || echo 'False'"
|
||||
$checkResult = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $checkCmd 2>&1
|
||||
|
||||
if ($checkResult -match "True") {
|
||||
$successCount++
|
||||
}
|
||||
} else {
|
||||
$failCount++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Log "Transfer summary: $successCount succeeded, $failCount failed"
|
||||
|
||||
if ($failCount -gt 0) {
|
||||
Write-Log "Some transfers failed!" "WARNING"
|
||||
}
|
||||
|
||||
# Cleanup old backups pe DR
|
||||
Cleanup-OldBackupsOnDR
|
||||
|
||||
Write-Log "========================================="
|
||||
Write-Log "Backup Transfer Completed Successfully"
|
||||
Write-Log "========================================="
|
||||
Write-Log "Files processed: $($backupFiles.Count)"
|
||||
Write-Log "Successful: $successCount"
|
||||
Write-Log "Failed: $failCount"
|
||||
Write-Log "DR Server: ${DRHost}:${DRPath}"
|
||||
|
||||
exit 0
|
||||
|
||||
} catch {
|
||||
Write-Log "CRITICAL ERROR: $($_.Exception.Message)" "ERROR"
|
||||
Write-Log "Stack trace: $($_.ScriptStackTrace)" "ERROR"
|
||||
exit 1
|
||||
}
|
||||
649
proxmox/vm109-windows-dr/scripts/weekly-dr-test-proxmox.sh
Normal file
649
proxmox/vm109-windows-dr/scripts/weekly-dr-test-proxmox.sh
Normal file
@@ -0,0 +1,649 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Oracle DR Weekly Test with Proxmox PVE::Notify
|
||||
# Automated DR test with notifications via Proxmox notification system
|
||||
#
|
||||
# Location: /opt/scripts/weekly-dr-test-proxmox.sh (on Proxmox host)
|
||||
# Schedule: Add to cron for weekly execution (Saturdays)
|
||||
#
|
||||
# This script is SELF-SUFFICIENT:
|
||||
# - Automatically creates notification templates if they don't exist
|
||||
# - Uses Proxmox native notification system
|
||||
# - No email configuration needed - uses existing Proxmox setup
|
||||
#
|
||||
# Installation:
|
||||
# cp weekly-dr-test-proxmox.sh /opt/scripts/
|
||||
# chmod +x /opt/scripts/weekly-dr-test-proxmox.sh
|
||||
# /opt/scripts/weekly-dr-test-proxmox.sh --install # Creates templates
|
||||
# crontab -e # Add: 0 6 * * 6 /opt/scripts/weekly-dr-test-proxmox.sh
|
||||
#
|
||||
# Author: Claude (based on ha-monitor.sh pattern)
|
||||
# Version: 1.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Set proper PATH for cron execution
|
||||
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# Configuration
|
||||
DR_VM_ID="109"
|
||||
DR_VM_IP="10.0.20.37"
|
||||
DR_VM_PORT="22122"
|
||||
DR_VM_USER="romfast"
|
||||
BACKUP_PATH="/mnt/pve/oracle-backups/ROA/autobackup"
|
||||
MAX_RESTORE_TIME_MIN=30
|
||||
TEMPLATE_DIR="/usr/share/pve-manager/templates/default"
|
||||
LOG_DIR="/var/log/oracle-dr"
|
||||
LOG_FILE="$LOG_DIR/dr_test_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Function to create notification templates
|
||||
create_templates() {
|
||||
echo -e "${GREEN}Creating Oracle DR test notification templates...${NC}"
|
||||
|
||||
# Create templates directory if needed
|
||||
mkdir -p "$TEMPLATE_DIR"
|
||||
|
||||
# Subject template
|
||||
cat > "$TEMPLATE_DIR/oracle-dr-test-subject.txt.hbs" <<'EOF'
|
||||
Oracle DR Test {{test_result}} | {{date}}
|
||||
EOF
|
||||
|
||||
# Text body template
|
||||
cat > "$TEMPLATE_DIR/oracle-dr-test-body.txt.hbs" <<'EOF'
|
||||
Oracle DR Test {{test_result}} | {{date}}
|
||||
Severity: {{severity}}
|
||||
|
||||
SUMMARY
|
||||
- Outcome: {{test_result}}
|
||||
- Duration: {{total_duration}} min (restore {{restore_duration}} min)
|
||||
- Backups used: {{backup_count}}
|
||||
- Tables restored: {{tables_restored}}
|
||||
|
||||
COMPONENTS
|
||||
- VM {{vm_id}} ({{vm_ip}}): {{vm_status}}
|
||||
- NFS: {{nfs_status}}
|
||||
- Database: {{database_status}}
|
||||
- Cleanup: {{disk_freed}} GB freed
|
||||
|
||||
STEPS
|
||||
{{#each test_steps}}
|
||||
- {{#if this.passed}}✓{{else}}✗{{/if}} {{this.name}} ({{this.duration}}s){{#if this.status}} - {{this.status}}{{/if}}
|
||||
{{/each}}
|
||||
|
||||
{{#if has_errors}}
|
||||
ISSUES
|
||||
{{#each errors}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if has_warnings}}
|
||||
WARNINGS
|
||||
{{#each warnings}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
RMAN RESTORE LOG (complete)
|
||||
---
|
||||
{{restore_log}}
|
||||
---
|
||||
|
||||
BASH SCRIPT LOG (last 100 lines)
|
||||
---
|
||||
{{bash_log}}
|
||||
---
|
||||
|
||||
Full log: {{log_file}}
|
||||
Next test: Saturday 06:00
|
||||
EOF
|
||||
|
||||
# HTML body template (compact Gmail-friendly layout)
|
||||
cat > "$TEMPLATE_DIR/oracle-dr-test-body.html.hbs" <<'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Oracle DR Test {{test_result}} | {{date}}</title>
|
||||
</head>
|
||||
<body style="margin:0;padding:16px;font-family:Arial,Helvetica,sans-serif;background:#ffffff;color:#2c3e50;">
|
||||
<table style="width:100%;max-width:640px;margin:0 auto;border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="padding:0 0 12px 0;font-size:18px;font-weight:600;">
|
||||
Oracle DR Test {{test_result}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 0 8px 0;font-size:13px;color:#6c757d;">{{date}} · Severity: {{severity}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:12px;border:1px solid #e1e4e8;border-radius:4px;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;">
|
||||
<tr><td style="padding:4px 0;">Outcome</td><td style="padding:4px 0;text-align:right;">{{test_result}}</td></tr>
|
||||
<tr><td style="padding:4px 0;">Duration</td><td style="padding:4px 0;text-align:right;">{{total_duration}} min (restore {{restore_duration}} min)</td></tr>
|
||||
<tr><td style="padding:4px 0;">Backups used</td><td style="padding:4px 0;text-align:right;">{{backup_count}}</td></tr>
|
||||
<tr><td style="padding:4px 0;">Tables restored</td><td style="padding:4px 0;text-align:right;">{{tables_restored}}</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;border:1px solid #e1e4e8;border-radius:4px;background:#f9fafb;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;">Components</td></tr>
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">VM {{vm_id}} ({{vm_ip}}): {{vm_status}}</td></tr>
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">NFS: {{nfs_status}}</td></tr>
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">Database: {{database_status}}</td></tr>
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #e1e4e8;">Cleanup: {{disk_freed}} GB freed</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;">
|
||||
<tr><td style="padding:0 0 6px 0;font-weight:600;">Steps</td></tr>
|
||||
{{#each test_steps}}
|
||||
<tr>
|
||||
<td style="padding:4px 0;border-bottom:1px solid #f1f1f1;">{{#if this.passed}}✓{{else}}✗{{/if}} {{this.name}} ({{this.duration}}s){{#if this.status}} – {{this.status}}{{/if}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{{#if has_errors}}
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;background:#fff5f5;border:1px solid #f1b0b7;border-radius:4px;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;color:#c82333;">Issues</td></tr>
|
||||
{{#each errors}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #f8d7da;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#if has_warnings}}
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:14px;background:#fff8e5;border:1px solid #ffe8a1;border-radius:4px;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;color:#856404;">Warnings</td></tr>
|
||||
{{#each warnings}}
|
||||
<tr><td style="padding:6px 12px;border-top:1px solid #ffe8a1;">• {{this}}</td></tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:12px;border:1px solid #e1e4e8;border-radius:4px;background:#f9fafb;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;font-size:13px;">RMAN Restore Log (complete)</td></tr>
|
||||
<tr><td style="padding:8px 12px;font-family:monospace;white-space:pre-wrap;word-wrap:break-word;border-top:1px solid #e1e4e8;">{{restore_log}}</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:12px;border:1px solid #e1e4e8;border-radius:4px;background:#f9fafb;">
|
||||
<tr><td style="padding:8px 12px;font-weight:600;font-size:13px;">Bash Script Log (last 100 lines)</td></tr>
|
||||
<tr><td style="padding:8px 12px;font-family:monospace;white-space:pre-wrap;word-wrap:break-word;border-top:1px solid #e1e4e8;">{{bash_log}}</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding:16px 0 0 0;font-size:12px;color:#6c757d;">
|
||||
Full log: {{log_file}} · Next test: Saturday 06:00
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}Templates created successfully in $TEMPLATE_DIR${NC}"
|
||||
}
|
||||
|
||||
# Function to send notification via PVE::Notify
|
||||
send_pve_notification() {
|
||||
local severity="$1"
|
||||
local data="$2"
|
||||
|
||||
# Create Perl script to call PVE::Notify
|
||||
cat > /tmp/oracle-dr-notify.pl <<'PERL_SCRIPT'
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use PVE::Notify;
|
||||
use JSON;
|
||||
|
||||
my $json_data = do { local $/; <STDIN> };
|
||||
my $data = decode_json($json_data);
|
||||
|
||||
my $severity = $data->{severity} // 'info';
|
||||
my $template_name = 'oracle-dr-test';
|
||||
|
||||
# Add fields for matching rules
|
||||
my $fields = {
|
||||
type => 'oracle-dr-test',
|
||||
severity => $severity,
|
||||
test_result => $data->{test_result},
|
||||
};
|
||||
|
||||
# Send notification
|
||||
eval {
|
||||
PVE::Notify::notify(
|
||||
$severity,
|
||||
$template_name,
|
||||
$data,
|
||||
$fields
|
||||
);
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
print "Error sending notification: $@\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print "Notification sent successfully\n";
|
||||
PERL_SCRIPT
|
||||
|
||||
chmod +x /tmp/oracle-dr-notify.pl
|
||||
|
||||
# Send notification
|
||||
echo "$data" | perl /tmp/oracle-dr-notify.pl
|
||||
|
||||
rm -f /tmp/oracle-dr-notify.pl
|
||||
}
|
||||
|
||||
# Logging functions
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Test tracking
|
||||
TEST_STEPS=()
|
||||
ERRORS=()
|
||||
WARNINGS=()
|
||||
TEST_START_TIME=$(date +%s)
|
||||
|
||||
# Function to track test steps
|
||||
track_step() {
|
||||
local name="$1"
|
||||
local passed="$2"
|
||||
local status="$3"
|
||||
local start_time="$4"
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
local step_json
|
||||
step_json=$(jq -n \
|
||||
--arg name "$name" \
|
||||
--arg status "$status" \
|
||||
--arg duration "$duration" \
|
||||
--arg passed "$passed" \
|
||||
'{name:$name, status:$status, duration:($duration|tonumber), passed:($passed == "true")}'
|
||||
)
|
||||
|
||||
TEST_STEPS+=("$step_json")
|
||||
|
||||
if [ "$passed" = "false" ]; then
|
||||
ERRORS+=("$name: $status")
|
||||
fi
|
||||
}
|
||||
|
||||
# Main test workflow
|
||||
run_dr_test() {
|
||||
local test_result="FAILED"
|
||||
local severity="error"
|
||||
local is_success=false
|
||||
local restore_duration=0
|
||||
local tables_restored=0
|
||||
local db_status="UNKNOWN"
|
||||
local nfs_status="Not checked"
|
||||
local vm_status_label="Not started"
|
||||
local cleanup_freed=0
|
||||
local backup_count=0
|
||||
local restore_log="Not collected"
|
||||
|
||||
log "=========================================="
|
||||
log "Oracle DR Weekly Test - Starting"
|
||||
log "=========================================="
|
||||
|
||||
# Step 1: Pre-flight checks
|
||||
local step_start=$(date +%s)
|
||||
log "STEP 1: Pre-flight checks"
|
||||
|
||||
# Check backups exist
|
||||
backup_count=$(find "$BACKUP_PATH" -maxdepth 1 -type f -name '*.BKP' 2>/dev/null | wc -l)
|
||||
|
||||
if [ "$backup_count" -lt 2 ]; then
|
||||
track_step "Pre-flight checks" false "Insufficient backups (found: $backup_count)" "$step_start"
|
||||
test_result="FAILED - No backups"
|
||||
else
|
||||
track_step "Pre-flight checks" true "Found $backup_count backups" "$step_start"
|
||||
|
||||
# Step 2: Start VM
|
||||
step_start=$(date +%s)
|
||||
log "STEP 2: Starting DR VM"
|
||||
|
||||
if qm start "$DR_VM_ID" 2>/dev/null; then
|
||||
vm_status_label="Running"
|
||||
|
||||
# Intelligent VM boot wait with polling (max 180s)
|
||||
local MAX_BOOT_WAIT=180
|
||||
local POLL_INTERVAL=5
|
||||
local boot_elapsed=0
|
||||
local vm_ready=false
|
||||
|
||||
log "Waiting for VM to become ready (SSH + PowerShell, max ${MAX_BOOT_WAIT}s)..."
|
||||
|
||||
while [ $boot_elapsed -lt $MAX_BOOT_WAIT ]; do
|
||||
# Check 1: VM running status in Proxmox
|
||||
local vm_qm_status
|
||||
vm_qm_status=$(qm status "$DR_VM_ID" 2>/dev/null | grep -o "running" || echo "")
|
||||
|
||||
if [ "$vm_qm_status" = "running" ]; then
|
||||
# Check 2: SSH connectivity and PowerShell availability (what we actually need)
|
||||
if ssh -p "$DR_VM_PORT" -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o BatchMode=yes "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command 'Write-Output ready'" >/dev/null 2>&1; then
|
||||
log "VM ready after ${boot_elapsed}s (SSH and PowerShell responding)"
|
||||
vm_ready=true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep $POLL_INTERVAL
|
||||
boot_elapsed=$((boot_elapsed + POLL_INTERVAL))
|
||||
|
||||
# Progress logging every 30 seconds
|
||||
if [ $((boot_elapsed % 30)) -eq 0 ] && [ $boot_elapsed -lt $MAX_BOOT_WAIT ]; then
|
||||
log "Still waiting for VM... (${boot_elapsed}s/${MAX_BOOT_WAIT}s elapsed)"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$vm_ready" = false ]; then
|
||||
log_warning "VM did not respond within ${MAX_BOOT_WAIT}s, continuing anyway (may cause subsequent failures)"
|
||||
fi
|
||||
|
||||
track_step "VM Startup" true "VM $DR_VM_ID started and ready (${boot_elapsed}s)" "$step_start"
|
||||
|
||||
# Step 3: Verify NFS mount
|
||||
step_start=$(date +%s)
|
||||
log "STEP 3: Verifying NFS mount"
|
||||
|
||||
nfs_status="Not Mounted"
|
||||
if ssh -p "$DR_VM_PORT" -o ConnectTimeout=10 "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command 'Test-Path F:\\ROA\\autobackup'" 2>/dev/null; then
|
||||
nfs_status="Mounted"
|
||||
track_step "NFS Mount Check" true "F:\\ drive accessible" "$step_start"
|
||||
else
|
||||
track_step "NFS Mount Check" false "F:\\ drive not accessible" "$step_start"
|
||||
WARNINGS+=("NFS mount may need manual intervention")
|
||||
fi
|
||||
|
||||
# Step 4: Run restore
|
||||
step_start=$(date +%s)
|
||||
local restore_start=$step_start
|
||||
log "STEP 4: Running database restore"
|
||||
|
||||
if ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -ExecutionPolicy Bypass -File D:\\oracle\\scripts\\rman_restore_from_zero.ps1 -TestMode" 2>&1 | tee -a "$LOG_FILE"; then
|
||||
|
||||
local restore_end=$(date +%s)
|
||||
restore_duration=$(( (restore_end - restore_start) / 60 ))
|
||||
|
||||
track_step "Database Restore" true "Restored in $restore_duration minutes" "$step_start"
|
||||
|
||||
# Step 5: Verify database
|
||||
step_start=$(date +%s)
|
||||
log "STEP 5: Verifying database"
|
||||
|
||||
# Parse database status from LOG_FILE (rman_restore_from_zero.ps1 already verified it)
|
||||
# Look for "OPEN_MODE: READ WRITE" in the captured output
|
||||
if grep -q "OPEN_MODE: READ WRITE" "$LOG_FILE" 2>/dev/null; then
|
||||
db_status="READ WRITE"
|
||||
else
|
||||
db_status=""
|
||||
fi
|
||||
|
||||
# Parse table count from LOG_FILE (already captured in STEP 3 output)
|
||||
# Look for "TABLES: <number>" in the output
|
||||
tables_restored=$(grep -oP "TABLES:\s*\K\d+" "$LOG_FILE" 2>/dev/null | tail -1 || echo "0")
|
||||
tables_restored=$(echo "$tables_restored" | tr -cd '0-9')
|
||||
[ -z "$tables_restored" ] && tables_restored=0
|
||||
|
||||
if [[ "$db_status" == "READ WRITE" ]] && [ "$tables_restored" -gt 0 ]; then
|
||||
track_step "Database Verification" true "Database OPEN, $tables_restored tables" "$step_start"
|
||||
test_result="PASSED"
|
||||
severity="info"
|
||||
is_success=true
|
||||
else
|
||||
track_step "Database Verification" false "Database not OPEN" "$step_start"
|
||||
fi
|
||||
|
||||
# Collect restore log from VM (always attempt collection - FULL log)
|
||||
log "Collecting restore log from DR VM..."
|
||||
restore_log=$(ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command \"Get-Content 'D:\\oracle\\logs\\restore_from_zero.log' -ErrorAction SilentlyContinue\"" 2>/dev/null || echo "")
|
||||
|
||||
# If not found, try alternate locations
|
||||
if [ -z "$restore_log" ]; then
|
||||
restore_log=$(ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command \"Get-Content 'D:\\oracle\\temp\\restore_from_zero.log' -ErrorAction SilentlyContinue\"" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
# Still not found, use fallback message
|
||||
if [ -z "$restore_log" ]; then
|
||||
restore_log="Restore log not available (file may not exist or was not generated)"
|
||||
fi
|
||||
|
||||
# Step 6: Cleanup (AFTER restore - stop service to release file locks)
|
||||
step_start=$(date +%s)
|
||||
log "STEP 6: Running cleanup"
|
||||
|
||||
ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -ExecutionPolicy Bypass -File D:\\oracle\\scripts\\cleanup_database.ps1 /SILENT /AFTER" 2>/dev/null
|
||||
|
||||
cleanup_freed=8
|
||||
track_step "Cleanup" true "Database cleaned, ~${cleanup_freed}GB freed" "$step_start"
|
||||
|
||||
else
|
||||
# Collect restore log even when restore fails (FULL log)
|
||||
log "Collecting restore log after failure..."
|
||||
restore_log=$(ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command \"Get-Content 'D:\\oracle\\logs\\restore_from_zero.log' -ErrorAction SilentlyContinue\"" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$restore_log" ]; then
|
||||
restore_log=$(ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command \"Get-Content 'D:\\oracle\\temp\\restore_from_zero.log' -ErrorAction SilentlyContinue\"" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
# Always try to get some error output from RMAN script
|
||||
if [ -z "$restore_log" ]; then
|
||||
last_error=$(ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -Command \"Get-Content 'D:\\oracle\\temp\\*.rman' -Tail 20 -ErrorAction SilentlyContinue\"" 2>/dev/null || echo "")
|
||||
if [ -n "$last_error" ]; then
|
||||
restore_log="RMAN script content (last 20 lines):\n$last_error"
|
||||
else
|
||||
restore_log="No restore logs or RMAN scripts found"
|
||||
fi
|
||||
fi
|
||||
|
||||
track_step "Database Restore" false "Restore failed" "$step_start"
|
||||
fi
|
||||
|
||||
# Step 7: Shutdown VM
|
||||
step_start=$(date +%s)
|
||||
log "STEP 7: Shutting down VM"
|
||||
|
||||
ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" "shutdown /s /t 30" 2>/dev/null
|
||||
sleep 60
|
||||
qm stop "$DR_VM_ID" 2>/dev/null
|
||||
|
||||
track_step "VM Shutdown" true "VM stopped" "$step_start"
|
||||
vm_status_label="Stopped"
|
||||
|
||||
else
|
||||
track_step "VM Startup" false "Failed to start VM $DR_VM_ID" "$step_start"
|
||||
vm_status_label="Failed to start"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Calculate total duration
|
||||
local test_end_time=$(date +%s)
|
||||
local total_duration=$(( (test_end_time - TEST_START_TIME) / 60 ))
|
||||
|
||||
# Prepare notification data
|
||||
local steps_json
|
||||
if [ ${#TEST_STEPS[@]} -eq 0 ]; then
|
||||
steps_json='[]'
|
||||
else
|
||||
steps_json=$(printf '%s\n' "${TEST_STEPS[@]}" | jq -s '.')
|
||||
fi
|
||||
|
||||
local errors_json
|
||||
if [ ${#ERRORS[@]} -eq 0 ]; then
|
||||
errors_json='[]'
|
||||
else
|
||||
errors_json=$(printf '%s\n' "${ERRORS[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local warnings_json
|
||||
if [ ${#WARNINGS[@]} -eq 0 ]; then
|
||||
warnings_json='[]'
|
||||
else
|
||||
warnings_json=$(printf '%s\n' "${WARNINGS[@]}" | jq -R . | jq -s .)
|
||||
fi
|
||||
|
||||
local has_errors=false
|
||||
local has_warnings=false
|
||||
[ ${#ERRORS[@]} -gt 0 ] && has_errors=true
|
||||
[ ${#WARNINGS[@]} -gt 0 ] && has_warnings=true
|
||||
|
||||
if [ "$is_success" = true ] && [ "$has_warnings" = true ]; then
|
||||
severity="warning"
|
||||
fi
|
||||
|
||||
local db_status_clean=$(echo "$db_status" | tr -d '\r' | sed 's/^ *//;s/ *$//')
|
||||
|
||||
# Escape restore log for JSON
|
||||
local restore_log_json
|
||||
restore_log_json=$(echo "$restore_log" | jq -Rs .)
|
||||
|
||||
# Collect last 100 lines of bash script log
|
||||
local bash_log
|
||||
bash_log=$(tail -100 "$LOG_FILE" 2>/dev/null || echo "Bash log not available")
|
||||
local bash_log_json
|
||||
bash_log_json=$(echo "$bash_log" | jq -Rs .)
|
||||
|
||||
local json_data=$(cat <<JSON
|
||||
{
|
||||
"severity": "$severity",
|
||||
"test_result": "$test_result",
|
||||
"date": "$(date '+%Y-%m-%d %H:%M:%S')",
|
||||
"total_duration": $total_duration,
|
||||
"is_success": $is_success,
|
||||
"has_errors": $has_errors,
|
||||
"has_warnings": $has_warnings,
|
||||
"test_steps": $steps_json,
|
||||
"errors": $errors_json,
|
||||
"warnings": $warnings_json,
|
||||
"backup_count": $backup_count,
|
||||
"restore_duration": $restore_duration,
|
||||
"tables_restored": ${tables_restored:-0},
|
||||
"database_status": "${db_status_clean:-UNKNOWN}",
|
||||
"disk_freed": $cleanup_freed,
|
||||
"vm_id": "$DR_VM_ID",
|
||||
"vm_ip": "$DR_VM_IP",
|
||||
"vm_status": "$vm_status_label",
|
||||
"nfs_status": "${nfs_status:-Unknown}",
|
||||
"log_file": "$LOG_FILE",
|
||||
"restore_log": $restore_log_json,
|
||||
"bash_log": $bash_log_json
|
||||
}
|
||||
JSON
|
||||
)
|
||||
|
||||
# Send notification
|
||||
log "Sending notification..."
|
||||
send_pve_notification "$severity" "$json_data"
|
||||
|
||||
# Final summary
|
||||
log "=========================================="
|
||||
log "Oracle DR Test Complete: $test_result"
|
||||
log "Duration: $total_duration minutes"
|
||||
log "Log: $LOG_FILE"
|
||||
log "=========================================="
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
case "${1:-}" in
|
||||
--install)
|
||||
create_templates
|
||||
echo ""
|
||||
echo -e "${GREEN}Installation complete!${NC}"
|
||||
echo "Next steps:"
|
||||
echo "1. Test the script: /opt/scripts/weekly-dr-test-proxmox.sh"
|
||||
echo "2. Add to cron: crontab -e"
|
||||
echo " Add line: 0 6 * * 6 /opt/scripts/weekly-dr-test-proxmox.sh"
|
||||
echo "3. Configure notifications in Proxmox GUI if needed:"
|
||||
echo " Datacenter > Notifications > Add matching rules for 'oracle-dr-test'"
|
||||
;;
|
||||
--help)
|
||||
echo "Oracle DR Weekly Test for Proxmox"
|
||||
echo "Usage:"
|
||||
echo " $0 - Run DR test"
|
||||
echo " $0 --install - Create notification templates"
|
||||
echo " $0 --help - Show this help"
|
||||
;;
|
||||
*)
|
||||
# Check if templates exist, create if missing
|
||||
if [ ! -f "$TEMPLATE_DIR/oracle-dr-test-subject.txt.hbs" ]; then
|
||||
echo -e "${YELLOW}Templates not found, creating...${NC}"
|
||||
create_templates
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Run DR test
|
||||
run_dr_test
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo -e "${RED}Error: jq is not installed${NC}"
|
||||
echo "Install with: apt-get install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user