Files
ROMFASTSQL/proxmox/lxc108-oracle/roa-windows-setup/README.md
Marius 31c4065bd2 fix(roa): aliasul TNS lipsea din Oracle Home, iar actualizarea esua tacut
Constatat la VADECO pe 2026-08-28: pe serverul acela actualizarea ROA nu
aplicase NICIODATA un script, desi jobul raporta succes de la instalare.

PACK_UPDATE nu aplica el scripturile - genereaza D:\DMPDIR\script_master.sql
si lanseaza un sqlplus EXTERN, apoi se termina. Deci UPDATEROA_ZILNIC
raporteaza starea lansarii, nu a actualizarii: SUCCEEDED in ~5 secunde chiar
si cand nu s-a aplicat nimic. Scriptul generat incepe cu
"CONNECT CONTAFIN_ORACLE/...@ROA" (aliasul vine din NOM_FIRME.NUME_SERVER)
si are WHENEVER SQLERROR EXIT, deci iese la prima linie daca aliasul nu se
rezolva.

Lantul cauzal: sqlplus-ul lansat de baza mosteneste mediul serviciului
Oracle. La o instalare noua instanta porneste INAINTE ca 01-setup-database
sa scrie TNS_ADMIN de masina, deci serviciul nu il are si cade pe
tnsnames.ora din Oracle Home. La 21c XE home-ul e read-only, deci fisierul
real e in product\21c\homes\OraDB21Home1\network\admin, iar acolo Oracle
genereaza doar XE, LISTENER_XE si ORACLR_CONNECTION_DATA - fara ROA.
Rezultat: ORA-12154, tacut. Perfid: tnsping ROA REUSESTE dintr-o sesiune
interactiva, pentru ca aceea are TNS_ADMIN.

Eroarea era mascata dublu - jobul zicea SUCCEEDED, iar emailul de raportare
nu pleaca oricum (ORA-29279, SMTP-ul romfast nu anunta AUTH).

01-setup-database.ps1 scrie acum aliasul si in tnsnames.ora al Oracle
Home-ului, cu acelasi IP din LAN. Blocul se IMBINA in fisierul existent:
XE, LISTENER_XE si ORACLR_CONNECTION_DATA raman neatinse, pentru ca de ele
depind extproc si inregistrarea instantei la listener. Cu backup si
idempotent - regexul consuma si comentariile lipite deasupra lui "ROA =",
altfel antetul se dubla la fiecare rulare (prins de test).

Testat unitar (fisier Oracle fara ROA, idempotenta peste 4 rulari, ROA
preexistent cu alt IP la mijloc, fisier inexistent, paranteze echilibrate,
fara BOM) si end-to-end pe o copie a fisierului real de pe serverul VADECO:
tnsping ROA OK, sqlplus CONTAFIN_ORACLE@ROA conectat in XEPDB1, zero ORA-,
XE si LISTENER_XE inca se rezolva.

docs/lectii-actualizare-roa-alias-tns.md are diagnosticul complet, inclusiv
cum verifici ca actualizarea chiar s-a aplicat: script_master.log si
SCHEMA.versiune, NU statusul jobului. Contine si capcana ca randurile din
SCHEMA.versiune vin cu dump-ul la import, deci o schema proaspat importata
pare la zi fara ca actualizarea sa fi rulat vreodata local.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9Sa54oFKpE2XhD6A7NTch
2026-08-28 15:04:10 +03:00

689 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Instalarea ROA pe Oracle 21c / Windows
Kit de instalare și migrare a sistemului ROA pe un server Windows cu Oracle 21c
(Express Edition sau Standard Edition). Se rulează pe serverul clientului.
Oracle **nu** se instalează de aici — vezi întâi [`docs/00-INSTALL-ORACLE-XE.md`](docs/00-INSTALL-ORACLE-XE.md)
sau [`docs/00-INSTALL-ORACLE-SE.md`](docs/00-INSTALL-ORACLE-SE.md).
---
## Cerințe
- Windows Server 2016+ / Windows 10-11 Pro, cu drepturi de **administrator**
- Oracle 21c XE sau SE deja instalat, cu parola SYS/SYSTEM `romfastsoft`
- PowerShell 5.1+
- Spațiu: minimum 20 GB liberi (XE e limitat oricum la 12 GB date utilizator)
- Fișierele DMP șablon (vezi [Fișierele DMP](#fișierele-dmp))
---
## Alege scenariul
| # | Situația | Ce rulezi | Downtime |
|---|---|---|---|
| **A** | Migrare de pe un server vechi, cu utilizatori care lucrează | `FAZA1.cmd` ziua, `FAZA2.cmd` seara | minute |
| **B** | Client nou, fără date anterioare | `FAZA1.cmd <Id> /faralicente` | irelevant |
| **C** | Migrare, dar downtime-ul nu contează | `INSTALEAZA.cmd migrare <Id>` + 3 pași manuali | ore |
Dacă eziți: **A**. E fluxul complet și cel mai bine acoperit de verificări.
---
## A. Migrarea în două faze
### De ce merge așa
Pe `CONTAFIN_ORACLE` nu se lucrează activ — e schema comună, cu drepturi,
nomenclatoare, `NOM_FIRME` și tabela de actualizări. Se schimbă rar. Schemele
de **firmă** sunt cele în care se scrie tot timpul.
Deci contafin-ul poate fi exportat de pe serverul vechi în timpul programului,
iar tot ce depinde de el — obiecte SYS, sinonime, granturi, `SERVER_INFO`,
directoare, joburi, IIS, licențe — se poate face ziua, cu utilizatorii pe
serverul vechi. Seara rămâne doar importul firmelor.
### Faza 1 — în timpul programului
```bat
REM 1. Exporta DOAR contafin_oracle de pe serverul vechi
expdp system/parola@XE SCHEMAS=CONTAFIN_ORACLE DIRECTORY=DMPDIR ^
DUMPFILE=contafin_oracle.dmp LOGFILE=exp_contafin.log
REM 2. Pune-l in DMPDIR\ din kit, peste sablon. Lasa FIRMANOUA.dmp pe loc.
REM 3. Ruleaza faza 1
FAZA1.cmd 138 /vechi:10.0.0.5 /parolavechi:parola-SYS-veche /serviciuvechi:XE
```
Ce se întâmplă, în ordine:
| Pas | Script | Ce face |
|---|---|---|
| 1 | — | copiază DMP-urile în `C:\DMPDIR` + drepturi pentru serviciul Oracle |
| 2 | `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, `sqlnet.ora` + `tnsnames.ora` în `TNS_ADMIN`, `LOCAL_LISTENER` literal |
| 3 | `02-create-sys-objects.ps1` | obiectele SYS: `AUTH_PACK`, `NEWSCHEMA`, `INFO`, `AUTH_SERII`… |
| 4 | `03-import-contafin.ps1` | importă `CONTAFIN_ORACLE` **al clientului** |
| 5 | `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` |
| 6 | `09-copy-licenses.ps1` | **licențele** de pe serverul vechi |
| 7 | `08-post-install-config.ps1` | `ROAUPDATE`, `SERVER_INFO`, joburi, SMTP, Id client |
| 8 | `10` + `11` | publicarea în IIS, exportul zilnic |
| 9 | `07-verify-installation.ps1` | verificare |
La final, verificarea va spune **„N company schemas are missing"**. E normal —
firmele vin abia în faza 2.
**Opțiuni `FAZA1.cmd`:**
| Opțiune | Efect |
|---|---|
| `/smtp:<server>` | server SMTP (implicit `mail.romfast.ro`) |
| `/vechi:<gazda>` | serverul vechi, pentru licențe |
| `/serviciuvechi:<nume>` | serviciul de pe serverul vechi (implicit `XE`) |
| `/parolavechi:<parola>` | parola SYS de pe serverul vechi |
| `/licente:<fișier.sql>` | licențe dintr-un fișier, în loc de rețea |
| `/roaupdate:<cale>` | rădăcina oglinzii (implicit `D:\ROAUPDATE`) |
| `/export:<cale>` | director export (implicit `D:\ROA\EXPORT_ORADMP`) |
| `/faralicente` `/faraiis` `/farabackup` | sar peste pasul 09 / 10 / 11 |
### Între faze
- Utilizatorii lucrează mai departe pe serverul **vechi**.
- Nu porni joburile de actualizare pe serverul nou.
- Poți testa aplicația pe serverul nou — merge, doar că fără date de firmă.
- **Dacă se adaugă o firmă nouă sau se modifică nomenclatoare pe serverul
vechi**, faza 2 trebuie rulată cu `/reimportcontafin`, altfel `NOM_FIRME`
rămâne în urmă și firma nouă nu se importă.
### Faza 2 — după program
```bat
REM 1. Exporta schemele de firma de pe serverul vechi
expdp system/parola@XE SCHEMAS=FIRMA1,FIRMA2,FIRMA3 DIRECTORY=DMPDIR ^
DUMPFILE=%U_firme.dmp LOGFILE=exp_firme.log
REM Lista schemelor:
REM SELECT schema FROM CONTAFIN_ORACLE.NOM_FIRME WHERE sters = 0;
REM 2. Pune DMP-urile in C:\DMPDIR (sau da /dmp:<cale>)
REM 3. Ruleaza faza 2
FAZA2.cmd 138
```
| Pas | Ce face |
|---|---|
| 1 | copiază DMP-urile firmelor în `C:\DMPDIR` |
| 2 | *opțional* `/reimportcontafin`: `drop-contafin.ps1` → `01` → `03` → `04` |
| 3 | `05-import-companies.ps1` — schemele de firmă |
| 4 | `08-post-install-config.ps1` **din nou** |
| 5 | `11-setup-backup-export.ps1 -SchemaOnly` — regenerează `schema.txt` |
| 6 | `07-verify-installation.ps1` |
**De ce se reia pasul 08:** `SERVER_INFO` este o **tabelă în `CONTAFIN_ORACLE`**,
nu în `SYS`. Când vine contafin-ul clientului peste, aduce cu el `SERVER_INFO`
de pe serverul vechi — căi vechi, parole vechi, SMTP vechi. Fără reluare,
actualizările ar căuta fișiere pe calea serverului vechi.
Din același motiv se pierd joburile `UPDATEROA_ZILNIC` / `UPDATERTVAI_ZILNIC`
la `/reimportcontafin` — sunt owned de `CONTAFIN_ORACLE`. Pasul 08 le recreează,
**dezactivate**. Dacă trebuie să meargă, activează-le manual la final.
Licențele **nu** se pierd: `SYS.AUTH_SERII` și `SYS.AUTH_DETALII` trăiesc în `SYS`.
---
## B. Client nou
```bat
FAZA1.cmd 138 /faralicente
```
DMPDIR conține doar șabloanele: `contafin_oracle.dmp` (cu `NOM_FIRME` goală) și
`FIRMANOUA.dmp`. Nu există fază 2.
**Prima firmă se creează DIN APLICAȚIA ROA, nu din scripturi.** Aplicația scrie
firma în `CONTAFIN_ORACLE.NOM_FIRME` și apelează `SYS.NEWSCHEMA`, care îi importă
structura din `C:\DMPDIR\FIRMANOUA.dmp`.
Echivalentul mai vechi, fără IIS și fără export zilnic:
`INSTALEAZA.cmd curat 138`
---
## C. Migrare într-o singură rulare
```bat
INSTALEAZA.cmd migrare 138 mail.romfast.ro
```
Toate DMP-urile (contafin-ul clientului + firmele + `FIRMANOUA.dmp`) trebuie să
fie în `DMPDIR\` înainte.
`INSTALEAZA.cmd` **nu** copiază licențele, **nu** publică în IIS și **nu**
configurează exportul zilnic. După el, manual:
```powershell
Run.cmd 09-copy-licenses.ps1 -OldHost 10.0.0.5 -OldSysPassword parola -Replace
Run.cmd 10-setup-roaupdate-iis.ps1
Run.cmd 11-setup-backup-export.ps1
```
---
## Scripturile
| Script | Ce face | Când |
|---|---|---|
| `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, configurarea de rețea pentru clienți vechi | mereu |
| `02-create-sys-objects.ps1` | `AUTH_PACK`, `NEWSCHEMA`, `EXECUTESCRIPTOS`, `INFO`, `UTL_MAIL` | mereu |
| `03-import-contafin.ps1` | import `CONTAFIN_ORACLE` din DMP | mereu |
| `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` | mereu |
| `05-import-companies.ps1` | schemele de firmă, citind parolele din `NOM_FIRME` | migrare |
| `06-add-company.ps1` | adaugă o firmă pe un server deja instalat | ocazional |
| `07-verify-installation.ps1` | verificare completă, inclusiv **probă de conectare cu Instant Client-ul vechi**; cod 0 = instalare bună | mereu |
| `08-post-install-config.ps1` | `ROAUPDATE`, `SERVER_INFO`, joburi, SMTP, Id client | mereu |
| `09-copy-licenses.ps1` | `AUTH_SERII` + `AUTH_DETALII` de pe serverul vechi | migrare |
| `10-setup-roaupdate-iis.ps1` | directoare de modul + publicare `/roaupdate` în IIS | mereu |
| `11-setup-backup-export.ps1` | `EXPORT_ORADMP`, `backupora.exe`, task zilnic | mereu |
| `drop-contafin.ps1` | șterge `CONTAFIN_ORACLE` (doar pentru `/reimportcontafin`) | faza 2 |
| `99-uninstall-roa.ps1` | curăță tot, pentru re-testare | testare |
`Run.cmd <script> [parametri]` rulează unul singur, rezolvând `ExecutionPolicy`.
---
## Structura kitului
```
roa-windows-setup/
├── FAZA1.cmd # faza 1 - in timpul programului
├── FAZA2.cmd # faza 2 - dupa program
├── INSTALEAZA.cmd # instalare intr-o singura rulare
├── Run.cmd # ruleaza un singur script
├── RunAll.cmd # varianta interactiva a lui INSTALEAZA
├── config.example.ps1 # sablon de configurare (copiaza ca config.ps1)
│
├── DMPDIR/ # doar in kitul construit, nu in repo
│ ├── contafin_oracle.dmp
│ └── FIRMANOUA.dmp
│
├── backup/
│ ├── backupora.exe # exportatorul VFP, 49 KB, versionat aici
│ └── setari.ini.template # sablon cu marcaje {{...}}
│
├── docs/
│ ├── 00-INSTALL-ORACLE-XE.md
│ └── 00-INSTALL-ORACLE-SE.md
│
├── scripts/
│ ├── 01..11, 99, drop-contafin.ps1
│ └── lib/
│ ├── logging-functions.ps1
│ └── oracle-functions.ps1
│
├── sql/
│ ├── create-tablespace.sql, create-user-*.sql, configure-profile.sql
│ ├── sys-objects.sql # obiectele SYS
│ ├── sys-grants.sql # granturi SYS + dictionar pentru PACK_DIAG_SPATIU
│ ├── synonyms-public.sql, grants-public.sql
│ ├── directories-roaupdate.sql, server-info-init.sql, scheduler-jobs.sql
│ ├── auth-detalii-init.sql, export-licente.sql
│ ├── verify-objects.sql, uninstall-roa.sql, run-all-sys.sql
│ ├── ExecuteScriptOS.prc, UpdateSQLPLUS.prc
│ └── sys-updates/ # patch-uri sys_* post-instalare
│
├── config/sqlnet.ora # compatibilitate Instant Client 10/11
├── par/ # fisiere de parametri Data Pump
├── logs/ # logurile fiecarui pas
└── test/clone-vm300.sh # clonare VM de test pe Proxmox
```
---
## Fișierele DMP
| Fișier | Ce e | Mărime |
|---|---|---|
| `contafin_oracle.dmp` | schema comună: drepturi, actualizări, `NOM_FIRME` | 50–280 MB |
| `FIRMANOUA.dmp` | **șablon de firmă goală** | ~24 MB |
| `<FIRMA>.dmp` | o schemă de firmă existentă (doar la migrare) | 100–500 MB |
> **`FIRMANOUA.dmp` trebuie să ajungă în `C:\DMPDIR` la ORICE instalare.**
> Nu e folosit de pașii 01–08, ci mult mai târziu: când clientul adaugă o firmă
> nouă din aplicație, `SYS.NEWSCHEMA` îl caută în directorul Oracle `DMPDIR`
> ([`sql/sys-objects.sql`](sql/sys-objects.sql), `lcSchemaSursa := 'FIRMANOUA'`).
> Dacă lipsește, adăugarea firmei pică în `DBMS_DATAPUMP.ADD_FILE` — peste luni
> de la instalare, când nimeni nu mai leagă eroarea de instalare.
> `07-verify-installation.ps1` raportează lipsa ca eroare.
### De unde iei șabloanele
Ambele stau pe **LXC 108** (10.0.20.121), în containerul `oracle-xe`. Sunt **trei**
niveluri de scos, nu unul: container Docker → LXC 108 → host pvemini → stația ta.
`docker cp` te scoate doar din container, de aceea e nevoie și de `pct pull`.
```bash
ssh root@10.0.20.201 "pct exec 108 -- docker cp oracle-xe:/tmp/oracle-import-roa2/firmanoua.dmp /tmp/firmanoua.dmp"
ssh root@10.0.20.201 "pct pull 108 /tmp/firmanoua.dmp /tmp/firmanoua.dmp"
scp root@10.0.20.201:/tmp/firmanoua.dmp ./FIRMANOUA.dmp
```
Identic pentru `contafin_oracle.dmp`. Numele pe destinație trebuie să fie exact
**`FIRMANOUA.dmp`** — `SYS.NEWSCHEMA` îl construiește ca `lcSchemaSursa || '.dmp'`.
Mai simplu: [`../scripts/build-client-kit.ps1`](../scripts/build-client-kit.ps1)
face exportul, aduce arhivele, redenumește DMP-urile și împachetează tot kitul.
---
## Licențele
Licențele **nu** vin din DMP-uri. Stau în `SYS.AUTH_SERII` (seriile, `RAW(128)`,
decriptate de `AUTH_PACK`) și `SYS.AUTH_DETALII` (Id-ul de client). Obiectele SYS
nu călătoresc în DMP-ul de schemă.
Fără ele, aplicația pornește și apoi refuză fiecare modul cu
*„Nu aveti licenta pentru …"*.
```powershell
# Prin retea, de pe serverul vechi (doar SELECT - serverul vechi nu se modifica)
Run.cmd 09-copy-licenses.ps1 -OldHost 10.0.0.5 -OldSysPassword parola -Replace
# Daca serverul vechi nu e accesibil din cel nou: ruleaza PE SERVERUL VECHI
sqlplus -S "sys/parola@localhost:1521/XE as sysdba" @sql\export-licente.sql > licente.sql
# apoi, pe serverul nou:
Run.cmd 09-copy-licenses.ps1 -FromFile licente.sql -Replace
```
Scriptul salvează licențele curente de pe serverul nou în
`logs\licente-backup-server-nou_<data>.sql`, în același format — se re-importă
cu `-FromFile` dacă ceva merge prost. După import recreează `SEQ_AUTH_SERII`
peste `MAX(ID_SERIE)+1`, altfel prima licență adăugată ulterior ar încălca
`PK_AUTH_SERII`.
`08-post-install-config.ps1` scrie doar `AUTH_DETALII` (Id-ul de client). O bază
cu Id de client dar fără serii e cazul tipic de migrare făcută pe jumătate —
`07-verify-installation.ps1` îl raportează.
---
## Actualizarea aplicațiilor
Mecanismul are **două etaje**:
1. **Serverul clientului trage de la ROMFAST.** Jobul
`CONTAFIN_ORACLE.UPDATEROA_ZILNIC` apelează `PACK_UPDATE.UPDATEROA`, care
descarcă de la `SERVER_INFO.UPD_URL_APP` (`https://update.romfast.ro/roa/`)
în `D:\ROAUPDATE`.
2. **Stațiile trag de la serverul clientului**, prin HTTP. Pentru asta
`D:\ROAUPDATE` trebuie publicat în IIS la `http://localhost/roaupdate/`.
Fără etajul 2, etajul 1 funcționează și nu se vede nimic: stațiile rămân pe
versiunile vechi la nesfârșit.
```powershell
Run.cmd 10-setup-roaupdate-iis.ps1
```
Scriptul instalează rolul IIS dacă lipsește (`Install-WindowsFeature` pe Server,
`Enable-WindowsOptionalFeature` pe Windows Pro — poate cere restart), creează
aplicația `/roaupdate` în *Default Web Site*, activează directory browsing,
adaugă tipurile MIME pentru `.zip`/`.xml`, dă `IIS_IUSRS` drept de citire și
verifică la final că URL-ul răspunde 200.
**Structura `D:\ROAUPDATE`:**
| Element | Conținut |
|---|---|
| `<CLIENT>.xml` | manifest cu modulele și versiunile pentru clientul respectiv |
| `_ARHIVE/<MODUL>/` | ZIP-urile per versiune (`ROACONT-2.11.49.ZIP`) |
| `<MODUL>/` | binarele curente ale modulului |
| `_UPDATE/` | buffer de pregătire |
`08-post-install-config.ps1` creează cele 55 de obiecte Oracle `DIRECTORY`
(`UPD_*`) care arată în `_ARHIVE\<MODUL>`. `10-setup-roaupdate-iis.ps1` creează
directoarele fizice de modul de la nivelul de sus. **Dacă adaugi un modul, adaugă-l
în ambele scripturi.**
Joburile se creează **dezactivate**. Ca să meargă:
```sql
EXEC DBMS_SCHEDULER.ENABLE('CONTAFIN_ORACLE.UPDATEROA_ZILNIC');
EXEC DBMS_SCHEDULER.ENABLE('CONTAFIN_ORACLE.UPDATERTVAI_ZILNIC');
```
> **`SUCCEEDED` la jobul de update NU înseamnă că s-a aplicat ceva.** Jobul doar
> lansează un `sqlplus` extern și se termină în ~5 secunde. Dacă aliasul TNS din
> `NOM_FIRME.NUME_SERVER` (de regulă `ROA`) nu se rezolvă **în mediul serviciului
> Oracle**, scriptul generat iese la prima linie cu `ORA-12154` și actualizarea nu
> rulează niciodată — tăcut, pentru că jobul raportează succes, iar emailul de
> eroare nu pleacă. `01-setup-database.ps1` scrie aliasul și în `tnsnames.ora` al
> Oracle Home-ului tocmai pentru asta. Verifică `D:\DMPDIR\script_master.log` și
> `SCHEMA.versiune`, nu statusul jobului. Ghidul complet:
> [`../../../docs/lectii-actualizare-roa-alias-tns.md`](../../../docs/lectii-actualizare-roa-alias-tns.md).
Serverul ROMFAST de update e documentat în
[`../../vm201-windows/docs/vm201-roa-update-server.md`](../../vm201-windows/docs/vm201-roa-update-server.md).
---
## Exportul zilnic
```powershell
Run.cmd 11-setup-backup-export.ps1
```
Pregătește `D:\ROA\EXPORT_ORADMP`:
- copiază `backupora.exe` din `backup\` (**fără el, pasul se oprește cu eroare**);
- generează `setari.ini` din `backup\setari.ini.template`, înlocuind
marcajele `{{...}}` cu valorile reale;
- generează `schema.txt`: `CONTAFIN_ORACLE` + firmele active din `NOM_FIRME`
(sau îl copiază de pe serverul vechi cu `-SchemaFromPath`);
- creează obiectul Oracle `DIRECTORY BACKUP_ORACLE` și dă drepturi serviciului
Oracle pe folder;
- înregistrează task-ul zilnic **ROA Export Oracle** în Windows Task Scheduler.
> Formatul lui `setari.ini` **nu** e cimentat în cod — șablonul e un fișier de
> date, iar scriptul doar substituie marcajele. Când ai un `setari.ini` real
> care merge, îl pui peste șablon și înlocuiești valorile cu marcajele. Nu
> modifica PowerShell-ul.
Reluare după faza 2, când firmele există (nu atinge `setari.ini` sau task-ul):
```powershell
Run.cmd 11-setup-backup-export.ps1 -SchemaOnly
```
Verifică prima rulare înainte să pleci de la client:
```powershell
Start-ScheduledTask -TaskName "ROA Export Oracle"
Get-ScheduledTaskInfo -TaskName "ROA Export Oracle"
```
---
## Parole standard
| Utilizator | Parolă | Observații |
|---|---|---|
| `SYS` | `romfastsoft` | SYSDBA |
| `SYSTEM` | `romfastsoft` | DBA |
| `CONTAFIN_ORACLE` | `ROMFASTSOFT` | schema comună |
| schemele de firmă | din `NOM_FIRME.parola` | citite automat de pasul 05 |
Se schimbă cu `config.ps1` (copiază `config.example.ps1`) sau cu parametri pe
fiecare script. **`config.ps1` nu se comite** — poate conține parolele altui client.
---
## XE față de SE
| | XE (gratuit) | SE (licențiat) |
|---|---|---|
| Arhitectură | CDB + PDB | non-CDB |
| Serviciu | `XEPDB1` | `ROA` |
| Datafiles | `C:\app\oracle\oradata\XE\XEPDB1\` | `C:\app\oracle\oradata\ROA\` |
| Limite | 2 threads, 2 GB RAM, **12 GB date** | fără limite |
| Potrivit pentru | testare, clienți mici | producție |
> **La XE conectează-te întotdeauna la `XEPDB1`, niciodată la `XE` (CDB root).**
La instalarea SE: „Create and configure a single instance database", **debifezi**
„Create as Container database", global database name `ROA`.
---
## Capcana scripturilor `sys_*` la migrare
Obiectele deținute de `SYS` **nu călătoresc în DMP-ul de schemă**. În schimb,
tabela de versiuni a lui `PACK_MIGRARE` trăiește în `CONTAFIN_ORACLE` și **vine
cu DMP-ul** — iar scripturile `sys_*` își înregistrează acolo aplicarea
(`pack_migrare.UpdateVersiune(..., 'SYS')`).
Consecința: pe baza nouă, `ROAACTUALIZARI` vede scripturile `sys_*` drept deja
aplicate și le sare, deși în `SYS` nu există nimic. De aceea obiectele și
granturile SYS se pun **la instalare**, prin pașii 02 și 04, și nu se așteaptă
de la actualizator.
| Script sursă (`D:\roa\database\SCRIPTURI_CLAR\`) | Unde e aici |
|---|---|
| `sys_2026_01_14_01_AUTH_PACK` | `sql/sys-objects.sql` |
| `sys_2026_08_08_02_SYS_INFO_TABLESPACE_PURJARE` | `sql/sys-objects.sql` + `sql/scheduler-jobs.sql` |
| `sys_2026_08_03_05_DIAG_SPATIU_GRANT` | `sql/sys-grants.sql`, secțiunea `[5/5]` |
| `sys_2026_08_03_07_DIAG_SPATIU_GRANT2` | `sql/sys-grants.sql`, secțiunea `[5/5]` |
| `sys_2026_08_06_07_DIAG_SPATIU_GRANT3` | `sql/sys-grants.sql`, secțiunea `[5/5]` |
Secțiunea `[5/5]` acordă `SELECT` **direct** pe 18 vederi de dicționar către
`CONTAFIN_ORACLE`. Grantul prin rolul `DBA` nu ajunge: rolurile nu se aplică în
pachetele cu drepturi de definitor, iar `CONTAFIN_ORACLE.PACK_DIAG_SPATIU` este
exact așa. Fără ele pachetul rămâne `INVALID` și jobul `DIAGSPATIU_ZILNIC` nu
rulează.
Un `sys_*` nou fie se consolidează în `sys-objects.sql` / `sys-grants.sql` /
`scheduler-jobs.sql`, fie se pune în [`sql/sys-updates/`](sql/sys-updates/README.md)
ca patch post-instalare.
---
## Dezinstalare
```powershell
Run.cmd 99-uninstall-roa.ps1 -Force
```
Ciclul de re-testare: `99-uninstall-roa.ps1 -Force` → `FAZA1.cmd` → `07-verify-installation.ps1`.
> `99-uninstall-roa.ps1` trebuie să iasă cu **codul 0**. Orice alt cod înseamnă
> că au rămas obiecte în bază — uzual o sesiune activă ținea userul ocupat.
> Nu porni instalarea peste ele.
---
## Depanare
### Pasul 03 iese cu codul 5
**Normal.** E codul Data Pump pentru „completed with errors", din `ORA-31684`
(userul există deja, creat de pasul 01) și `ORA-39082` (warning-uri de compilare,
rezolvate la pasul 04). `FAZA1.cmd`, `FAZA2.cmd` și `INSTALEAZA.cmd` îl tratează
corect.
### ORA-12609: importul „eșuează" deși a reușit
**Simptom:** pasul 03 sau 05 se termină cu `UDI-12609 / ORA-12609: TNS: Receive
timeout occurred`, raportează `Objects imported: 0` și iese cu cod nenul. Dar în
logul Data Pump din `C:\DMPDIR` scrie `Job "SYSTEM"."SYS_IMPORT_SCHEMA_01" completed`.
**Cauză:** `SQLNET.RECV_TIMEOUT` din `sqlnet.ora`. Fișierul e citit și de clienții
de pe aceeași mașină (`impdp`, `expdp`, `sqlplus`), iar în timpul unui import
serverul poate lucra minute întregi fără să trimită vreun pachet — creare de
indecși, constrângeri. Clientul `impdp` moare, jobul de pe server continuă și se
termină cu bine, iar scriptul numără obiectele imediat după moartea clientului și
găsește 0.
Pe 21c fișierul care contează e cel din **read-only home**:
`C:\app\<user>\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora`, nu cel
din `dbhomeXE`.
```powershell
$f = "C:\app\romfast\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora"
(Get-Content $f) | Where-Object { $_ -notmatch 'SQLNET\.(RECV|SEND)_TIMEOUT' } | Set-Content $f
```
`SQLNET.INBOUND_CONNECT_TIMEOUT` poate rămâne — limitează doar handshake-ul.
Importul care „a eșuat" nu trebuie refăcut dacă logul spune `completed`; rulează
doar `07-verify-installation.ps1`.
### ORA-28040 / ORA-01017 / ORA-12514 — cele trei erori de conectare
Toate trei au fost întâlnite la VADECO și **niciuna nu arată spre cauza ei**.
Ghidul complet, cu dovezile: [`../../../docs/lectii-conectare-client-oracle.md`](../../../docs/lectii-conectare-client-oracle.md).
Rezumatul:
**Verifică întâi unde se citește `sqlnet.ora`.** Dacă `TNS_ADMIN` de mașină e
setat (ROAClient îl pune pe folderul propriului Instant Client), acela câștigă —
și pentru clienți, și pentru procesele bazei, de la următoarea pornire a
serviciului Oracle. Fișierul din Oracle Home devine irelevant.
```powershell
[Environment]::GetEnvironmentVariable('TNS_ADMIN','Machine')
```
### ORA-28040: No matching authentication protocol
`sqlnet.ora` lipsește din locul de unde citește instanța, deci
`ALLOWED_LOGON_VERSION_SERVER` cade pe implicitul 21c (`12`).
```powershell
.\scripts\01-setup-database.ps1 # scrie sqlnet.ora in ambele locuri
```
### ORA-01017: invalid username/password
Cu `ALLOWED_LOGON_VERSION_SERVER=8`, serverul autentifică orice client pre-12c pe
baza verificatorului **10G**. Un cont fără `10G` în `PASSWORD_VERSIONS` primește
`ORA-01017` — **parola e corectă**, lipsește verificatorul. Se repară rescriind
aceeași parolă:
```sql
-- utilizatori locali (din PDB)
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "ROMFASTSOFT";
ALTER USER <FIRMA> IDENTIFIED BY "<parola>";
-- utilizatori comuni (din CDB$ROOT)
ALTER USER SYSTEM IDENTIFIED BY "romfastsoft" CONTAINER=ALL;
```
Pentru `SYSTEM`, `PASSWORD_VERSIONS` citit din PDB rămâne `11G 12C` chiar și după
reparație — rândul local nu se împrospătează. Singura verificare validă e o
conectare adevărată.
### ORA-12514: listener does not know of service
Întâi PDB-ul — pentru XE trebuie deschis și starea salvată:
```sql
ALTER PLUGGABLE DATABASE XEPDB1 OPEN;
ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE;
```
Dacă baza e `OPEN`, listenerul e pornit și totuși `lsnrctl status` arată doar
`CLRExtProc`, atunci **instanța nu s-a înregistrat**. La XE, `LOCAL_LISTENER` e
implicit aliasul `LISTENER_XE`, care se rezolvă din `tnsnames.ora` — deci depinde
de `TNS_ADMIN`. După un restart cu alt `TNS_ADMIN`, aliasul nu se mai rezolvă și
**toți** clienții primesc `ORA-12514`.
```sql
SELECT value FROM v$parameter WHERE name = 'local_listener'; -- alias = fragil
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=<ip_lan>)(PORT=1521))' SCOPE=BOTH;
ALTER SYSTEM REGISTER;
```
### Erori la import
| Eroare | Rezolvare |
|---|---|
| `ORA-00959: tablespace 'ROA' does not exist` | `impdp … REMAP_TABLESPACE=ROA:USERS` |
| `ORA-00959: tablespace 'USERS' does not exist` (PDB nou) | `impdp … REMAP_TABLESPACE=USERS:ROA` |
| `ORA-39405: … TSTZ version newer` | folosește DMP-uri exportate din Oracle 18c (TSTZ 31), nu 21c (TSTZ 35) |
| `ORA-39002` / eroare la deschiderea fișierului | serviciul Oracle nu are drepturi pe `C:\DMPDIR` — `icacls C:\DMPDIR /grant "NT SERVICE\OracleServiceXE:(OI)(CI)F" /T` |
| `ORA-39002` + `ORA-39070: Unable to open the log file` + `ORA-29283` | `DIRECTORY DMPDIR` nu arată unde crezi — vezi mai jos |
### `DIRECTORY DMPDIR` s-a mutat singur
**Simptom:** importul contafin-ului (pasul 03) reușește, dar importul firmelor
(pasul 05, de obicei în altă zi) pică pe toate schemele cu
`ORA-39070 / ORA-29283`, iar schemele rămân goale.
**Cauză, până pe 2026-08-25:** `sql/sys-grants.sql`, rulat de pasul **04**, făcea
`CREATE OR REPLACE DIRECTORY DMPDIR AS 'C:\DMPDIR'` necondiționat. Pasul 04
rulează *după* 03, deci importul contafin-ului apuca să reușească, iar obiectul
era mutat imediat după. Pe mașinile unde `C:` nu e accesibil procesului Oracle,
eșecul apărea abia ore mai târziu, fără nicio legătură vizibilă cu pasul care îl
provocase. Corectat: calea existentă se păstrează.
**Verificare** — calea din dicționar nu e o dovadă, contează dacă baza chiar
poate scrie acolo. `07-verify-installation.ps1` face acum o rundă `UTL_FILE`.
Manual:
```sql
SELECT directory_path FROM dba_directories WHERE directory_name = 'DMPDIR';
```
```powershell
Run.cmd 01-setup-database.ps1 -DmpDir D:\DMPDIR # repune calea si o verifica
```
### ORA-12954: baza depășește 12 GB (doar XE)
Ghid complet: [`../clienti/oracle-xe-21c/depanare-ora-12954-spatiu.md`](../clienti/oracle-xe-21c/depanare-ora-12954-spatiu.md).
Prevenție, la orice instalare XE nouă (conectat la `XEPDB1` ca SYS):
```sql
EXEC DBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'sql tuning advisor', operation => NULL, window_name => NULL);
EXEC DBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'auto space advisor', operation => NULL, window_name => NULL);
NOAUDIT POLICY ORA_SECURECONFIG;
NOAUDIT POLICY ORA_LOGON_FAILURES;
EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention => 8*24*60, interval => 60);
EXEC DBMS_STATS.ALTER_STATS_HISTORY_RETENTION(7);
GRANT EXECUTE ON SYS.DBMS_LOCK TO CONTAFIN_ORACLE;
```
### Serviciile nu pornesc
```powershell
net stop OracleServiceXE ; net start OracleServiceXE
net stop OracleOraDB21Home1TNSListener ; net start OracleOraDB21Home1TNSListener
```
Servicii relevante: `OracleServiceXE` (XE) sau `OracleServiceROA` (SE), și
`OracleOraDB21Home1TNSListener`.
### `drop-contafin.ps1` dă ORA-01940
Userul are sesiuni deschise. Oprește aplicațiile sau reia cu `-KillSessions`
(`FAZA2.cmd /reimportcontafin` îl dă deja).
---
## Conectare
```bash
# XE - la PDB, niciodata la CDB root
sqlplus system/romfastsoft@localhost:1521/XEPDB1
sqlplus "sys/romfastsoft@localhost:1521/XEPDB1 as sysdba"
# SE
sqlplus system/romfastsoft@localhost:1521/ROA
```
TNS, pentru clienții care au nevoie de `tnsnames.ora`:
```
ROA =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = <server>)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = XEPDB1))
)
```
Logurile fiecărui pas: `logs\<script>_<data>.log`.
---
## Documente legate
| Subiect | Fișier |
|---|---|
| Care director se folosește la instalare/migrare | [`../docs/instalare-si-migrare-oracle.md`](../docs/instalare-si-migrare-oracle.md) |
| Construirea kitului pentru client | [`../scripts/build-client-kit.ps1`](../scripts/build-client-kit.ps1) |
| Serverul ROMFAST de update | [`../../vm201-windows/docs/vm201-roa-update-server.md`](../../vm201-windows/docs/vm201-roa-update-server.md) |
| VM 302 — mediul de test pentru acest kit | [`../../vm302-oracle-test/README.md`](../../vm302-oracle-test/README.md) |
| Cazuri clienți (depanare DB) | [`../clienti/README.md`](../clienti/README.md) |
| Diagnostic spațiu la clienți | [`../../../docs/diagnostic-spatiu-clienti.md`](../../../docs/diagnostic-spatiu-clienti.md) |
| Reguli de scris SQL de migrare | [`../../../system_instructions/system_prompt.md`](../../../system_instructions/system_prompt.md) |