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
689 lines
28 KiB
Markdown
689 lines
28 KiB
Markdown
# 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) |
|