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:
Marius
2026-01-27 17:28:53 +02:00
parent 4d51d5b2d2
commit a567f75f25
51 changed files with 233 additions and 1706 deletions

View File

@@ -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 |
---

View 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

View 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 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*

View 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*

View 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 |
| FR5FR7 | Frontend web modular (HTML/JS/CSS) + API JSON standard |
| FR8, FR9 | FastAPI gateway cu CORS, HTTPS și suport query param `message` |
| FR11FR15 | Microserviciu Telegram bazat pe python-telegram-bot conectat la același backend |
| NFR1NFR3 | Containere Docker separate, auto-restart Proxmox, load shedding și cache răspunsuri |
| NFR4NFR7 | 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, Lets 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 (06 luni)
- **Luna 01**: Implementare client web + gateway API + RAG minim (Chroma + Claude), ingestie documentație de bază.
- **Luna 12**: Adăugare session store distribuit, logging centralizat, pipeline ingestie automat.
- **Luna 23**: Lansare Telegram bot cu comenzi de bază, sincronizare sesiuni, fallback complet erori.
- **Luna 34**: Introducere metrics/alerting, optimizare performanță, cache răspunsuri.
- **Luna 46**: Extindere knowledge base, analytics dashboard, pregătire pentru scaling (replici, load balancing).

View File

@@ -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
---

View 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

View 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 ""

View 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 ""

View 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 ""

View 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

View 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 ""

View 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 ""

View 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 ""

View 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 ""

View 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 ""

View 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! 🚀**

View 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! 🚀**

View 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! 🚀**

View 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;

View 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;

File diff suppressed because it is too large Load Diff

View 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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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;

View 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

View 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*

View 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):
![DR Test Report](https://example.com/dr-test-email.png)
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

View 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

View File

@@ -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

View File

@@ -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`

View 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

View 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

View 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 ""

View File

@@ -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 ""

View 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 ""

View 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

View File

@@ -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 "$@"

View 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%

View 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;
}

View 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%

View 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
}

View 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

View 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
}

View 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 "$@"