Files
comun/docs/depanare-pack-update.md
Marius Mutu a290a51276 docs: emailurile actualizarii si compatibilitatea scripturilor cu 10g/11g
Log-ul de actualizare (PACK_UPDATE.EmailLog, din baza) si buletinul informativ
(trimis de serverul de update) sunt doua fluxuri diferite, cu destinatari
configurati in locuri diferite.

Scripturile de migrare se scriu la nivelul Oracle 10.2 si trebuie sa ruleze
si pe 11.x; tabel cu versiunea minima a constructiilor uzuale si limitele XE.

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

142 lines
7.7 KiB
Markdown

# Depanare actualizare ROA (CONTAFIN_ORACLE.PACK_UPDATE)
Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORACLE.UPDATEROA_ZILNIC`
-> `PACK_UPDATE.UpdateROA`, in 3 etape secventiale: **UpdateApp** (descarca arhivele programelor) ->
**UpdateScripts** (umple `UPD_DATABASE`) -> **UpdateDatabaseSqlPlus** (aplica scripturile pe scheme).
O etapa esuata le opreste pe toate urmatoarele.
## Unde te uiti, in ordine
| Ce | Unde |
|---|---|
| pana unde a ajuns fiecare rulare | `UPD_ISTORIC` (`stare`: 0=start, 1=aplicatii, 2=scripturi, 3=aplicare, 4=incheiat; `dataora_end` gol = neincheiata) |
| cauza reala a esecului | `UPD_LOG` (`dataora_start` = rularea, `secventa`+`dataora` = ordinea; `explicatie` e CLOB) |
| ce a raportat jobul | `dba_scheduler_job_run_details` (`log_date`, `status`, `additional_info`) |
| ce versiuni s-au descarcat | `UPD_PROGRAME` |
| scripturi disponibile / aplicate | `UPD_DATABASE.script_date` vs `<schema>.VERSIUNE.data_script` |
| **erorile din aplicarea scripturilor** | **`C:\DMPDIR\script_master.log` pe serverul de baze de date** |
Un sir de rulari oprite la aceeasi `stare` da direct etapa vinovata, iar prima zi din sir da data de
la care s-a schimbat ceva.
## Capcane
- **`UPD_LOG` se goleste la fiecare rulare.** Nu ai istoric: iei log-ul rularii curente, altfel
relansezi ca sa-l reproduci.
- **Eroarea din `additional_info` a jobului e de obicei falsa.** Pe orice esec se apeleaza `EmailLog`,
iar daca SMTP-ul e picat ridica `ORA-20000` care inlocuieste eroarea originala. Cauza adevarata e
in `UPD_LOG`.
- **`UpdateApp` abandoneaza tot la primul program nedescarcat** (`exit` din bucla, `CT_INSUCCES`) —
deci si programele de dupa el in lista, si ambele etape de baza de date. Un singur fisier
indisponibil blocheaza actualizarile la infinit, tacut.
- **`GetStare` refuza o rulare noua** cat timp precedenta e neincheiata si nu a trecut o ora.
Se deblocheaza cu `exec contafin_oracle.pack_update.IncheiereActualizare`.
- Programele `%USERREPORTS%` merg toate in directorul `UPD_USERREPORTS`, nu in `UPD_<nume_program>`.
## Aplicarea scripturilor (script_master.log)
Etapa 3 nu ruleaza scripturile din PL/SQL, ci genereaza in `DMPDIR` (`C:\DMPDIR`) cate un
`script_<SCHEMA>.sql` plus `script_master.sql`, pe care le da unui **SQL\*Plus extern**, cu iesirea
in `C:\DMPDIR\script_master.log` (`script_master2.log` = pasii de la final).
**Erorile de aici NU ajung in `UPD_LOG`.** O rulare care esueaza la un script arata perfect curata
in baza: `UPD_LOG` fara nicio eroare, doar `UpdateSchemaSQLPLUS ... / UpdateDatabaseSQLPLUS END`.
Semnele indirecte sunt ca rularea ramane la `stare = 3` fara `dataora_end`, iar
`<schema>.VERSIUNE` nu mai avanseaza. Scriptul vinovat e primul din `UPD_DATABASE` de dupa ultima
versiune inregistrata acolo, iar mesajul real e doar in `script_master.log`.
Scripturile au `WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK`, deci primul esec opreste tot lantul
si se repeta identic la fiecare rulare pana e reparat.
Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe directorul
`DMPDIR` (`fopen(...,'R',32767)` + `get_line` in bucla; tine ultimele N linii intr-un tablou —
partea utila e la sfarsit).
## Descarcarea (UpdateApp)
Cu `server_info.POWERSHELLDOWNLOAD = '1'`, `PACK_UTILS.DownloadFileOS` scrie un `.ps1` cu `curl` in
`DMPDIR`, il lanseaza cu `sys.ExecuteScriptOS` si asteapta aparitia fisierului in directorul Oracle
`UPD_<PROGRAM>`. Daca **folderul de pe disc lipseste**, curl esueaza mut si in log apare doar
`Fisierul NU s-a salvat pe disc.` — verifica intai directorul, nu reteaua.
Verificari rapide (read-only, din `contafin_oracle`):
```sql
-- calea configurata
select directory_name, directory_path from all_directories where directory_name like 'UPD%';
-- fisierul chiar exista pe disc?
select dbms_lob.fileexists(bfilename('UPD_ROACONT','ROACONT-2.11.70.zip')) from dual;
```
```sql
-- directorul exista si e scriibil? ORA-29283 = cale OS inexistenta sau fara drept de scriere
declare f utl_file.file_type; begin
f := utl_file.fopen('UPD_USERREPORTS','__probe.txt','W'); utl_file.fclose(f);
utl_file.fremove('UPD_USERREPORTS','__probe.txt');
end;
/
```
URL-ul se testeaza direct cu `curl` de pe orice masina (`optiuni.UPD_URL_APP`, cu `|CUSTOMERID|`
inlocuit din `sys.auth_detalii.detalii`); daca da 200, problema e local pe server.
## Comenzi OS pe serverul de baze de date
`sys.ExecuteScriptOS(<powershell>, <cale .ps1>)` creeaza un job scheduler `executable`**asincron**,
deci rezultatul se verifica prin polling, nu imediat. Scriptul se scrie cu
`pack_utils_file.clob2fileX(<clob>, 'DMPDIR', '<nume>.ps1')`. Utila cand ai doar acces Oracle
(ex. tunel SSH), fara RDP:
```sql
declare lcPS server_info.value%type; begin
select value into lcPS from server_info where upper(name)='POWERSHELLPATH';
pack_utils_file.filedelete('DMPDIR','x.ps1');
pack_utils_file.clob2fileX('New-Item -ItemType Directory -Force -Path ''D:\...'' | Out-Null',
'DMPDIR','x.ps1');
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\x.ps1');
end;
/
```
## Emailuri: log de actualizare vs buletin informativ
Sunt **doua emailuri diferite, trimise de doua masini diferite** — se confunda usor.
| | Log de actualizare | Buletin informativ |
|---|---|---|
| Cine trimite | baza de date, `PACK_UPDATE.EmailLog` (`UTL_SMTP` direct catre `EMAIL_SMTP:EMAIL_PORT`, `AUTH LOGIN`) | **serverul de update** (ASP.NET); baza doar face un GET pe `optiuni.UPD_URL_BULETININF` (cu `|CUSTOMERID|`) prin `PACK_UTILS.URL2Clob`, din `UpdateApp` |
| Destinatari | `server_info.EMAIL_TO` + `EMAIL_CC` | configurati pe serverul de update, **nu** in `server_info` (ex. `office@romfast.ro`) |
| Subiect / continut | `Actualizare ROA dd.mm.yyyy hh24:mi:ss`; liniile din `UPD_LOG`, text simplu separat cu TAB | compus de serverul de update |
| In `UPD_LOG` | erorile SMTP: `EROARE: utl_smpt ERROR CODE ...` | raspunsul HTTP, verbatim (ex. `ERR-1-BULETIN INFORMATIV NU S-A TRIMIS. MOTIVUL: Error: 1429`) |
Detalii care conteaza la depanare:
- **`EMAIL_CC` nu produce un antet `Cc:`.** Codul il concateneaza cu virgula la `EMAIL_TO` si trimite
`RCPT TO` pentru toti; antetul e un singur `To: <toti>`. Deci un email primit *in Cc* nu vine de la
`EmailLog`.
- **`EMAIL_FROM` e per server de client** (`roaupdate-<client>@romfast.ro`) si difera de contul
autentificat, care e acelasi peste tot (`EMAIL_USERNAME = roaupdate@romfast.ro`). Expeditorul e
singurul indiciu din email despre serverul care l-a trimis. Daca `EMAIL_FROM` lipseste, se compune
din `UTL_INADDR.get_host_name`.
- **Un buletin esuat nu opreste nimic**: raspunsul `ERR-1-...` e text normal, se scrie in `UPD_LOG` si
actualizarea merge mai departe. Doar exceptiile HTTP ajung ca `ERR: <url> ...`.
- **Un SMTP picat, in schimb, opreste tot** — `EmailLog` ridica `ORA-20000` care mascheaza eroarea
reala (vezi „Capcane" mai sus). E singurul loc din lantul de email care are voie sa arunce.
## Configurare (CONTAFIN_ORACLE)
- `server_info`: `POWERSHELLDOWNLOAD`, `POWERSHELLPATH`, `POWERSHELLTIMEOUT`, `CURLPATH`,
`SQLPLUSPATH`, `EMAIL_METHOD`/`EMAIL_SMTP`/`EMAIL_PORT`/`EMAIL_USERNAME`/`EMAIL_PASSWORD`/
`EMAIL_FROM`/`EMAIL_TO`.
- `optiuni`: `UPD_URL_APP`, `UPD_URL_DATABASE`, `UPD_URL_BULETININF` (daca lipsesc, pachetul
foloseste URL-uri implicite din cod).
## Conectare la serverul unui client
Tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in `D:\ROA\instantclient_19_18\tnsnames.ora`
(ex. `ROA_ROMCONSTRUCT`), utilizator `contafin_oracle`. Vezi `oracle_export.md` pentru client si
capcana de encoding; parolele stau in `docs/local/` al proiectului, neversionat.
Serverele de client pot fi Oracle 10g: unele coloane din `dba_scheduler_*` lipsesc
(`dba_scheduler_running_jobs.last_start_date`) — foloseste `dba_scheduler_job_run_details`.