mercoledì 13 febbraio 2019

Multi-Threading

Come si realizza il multithreading in OpenEdge(*)

Progress OpenEdge gestisce il multithreading? No,  Progress AVM è un processo monothread.

In questo primo post illustro quelle che, invece, sono le utilities OpenEdge multi-threaded ed i processi "abili" al multithreading.

- DBTOOL Utility. Tool di diagnostica e report su record format, index space, SQL width, ecc.
- Binary dump e Phase 2 del processo di idxbuild sono stati migliorati per gestire il multi-threading.
- Il processo broker/server per i client ABL (_mprosrv) non è multi-threaded. Può generare più processi  server, ciascuno in grado di servire più client, configurabili tramite i parametri di intermediazione -Mn-Ma del database).
- Il client Progress (_progres, _prowin32) essendo single-thread non permette di progettare applicazioni ABL multi-thread. Una possibilità, a seconda delle esigenze, può essere quella di usare chiamate ad AppServer in modalità asincrona. L'AppServer Broker è un processo java e genera più thread che il sistema operativo può allocare attraverso diverse CPU.Ogni AppServer Agent, essendo un processo _progress, tuttavia, verrà assegnato dal sistema operativo ad una CPU, ma non attraverso più CPU.

* Il presente post tratta della versione OpenEdge 10. Per le versioni successive https://knowledgebase.progress.com/articles/Article/P73663
giovedì 7 febbraio 2019
venerdì 29 maggio 2015

Transazioni - Transaction processing

Normal Transaction Processing

Forward processing
Le normali attività svolte da una applicazione, mentre sta accedendo e cambiando
il database, sono chiamate forward processing. In genere queste attività comprendono inizio e commit di transazione, ricerca e recupero dati, modifica dati esistenti,  aggiunta di nuovi e cancellazione di vecchi dati. 
Ogni cambiamento logico è eseguito apportando modifiche a uno o più blocchi del database. La modifica a un singolo blocco provoca un cambiamento fisico ed esegue un'operazione come la seguente :
nel blocco 409.824 sostituire i primi 8 byte con "!@#$%^&*"

Durante l'elaborazione roll forward i record di log vengono generati per registrare ogni cambiamento fisico del database. La tipica sequenza di eventi è la seguente:
1. Il blocco del db che contiene i dati da modificare si trova nel database buffer pool o viene letto da disco se non è già presente.
2. Il buffer pool è locked in modalità di update (exclusive lock) per evitare un altro processo di accesso o modifica a tale blocco, fino al completamento della modifica.
3. Un undo-redo log record, che descrive la modifica da effettuare, è creato in memoria.
4. Il record di log è memorizzato nel successivo spazio disponibile del buffer di registro corrente. Se lo spazio non è disponibile, il buffer è accodato per la scrittura dal BI writer e un log buffer libero diviene il buffer corrente. Se non ci sono buffer log liberi, il buffer più vecchio viene scritto su disco.
5. La modifica viene apportata al blocco del database, utilizzando solo i dati nel record di log ed i dati nel blocco.
6. Il lock sul buffer è rilasciato.

Quando un'operazione logica colpisce più di un blocco, i passaggi sopra descritti sono
eseguiti su ogni blocco. Un record di log undo-redo viene generato per ogni
blocco.

Rollback delle transazioni
Quando un'applicazione decide di annullare una transazione piuttosto che committarla, viene avviata una rollback transaction. Ciò si verifica quando l'applicazione esegue un'istruzione UNDO attraverso il codice 4GL, un utente interattivo preme il tasto "stop" sulla tastiera, un evento di lock wait è cancellato da un utente interattivo, o quando si verifica un lock wait time out. Il trattamento richiesto per effettuare un rollback è gestito automaticamente senza la necessità di alcun intervento applicativo.
Per eseguire il rollback di una transazione attiva, il database manager legge, in ordine inverso, tutto i records di log generati dalla transazione, fino al punto in cui è iniziata. Gli effetti di ogni variazione sono invertiti e i valori originali dei dati sono ripristinati. Mentre vengono annullate tutte le modifiche, il database è in stato di modifica, nuovamente. Queste nuove modifiche vengono registrate anche loro. Ciò genera un log record durante l'operazione di rollback proprio come durante un processo di normale modifica del database.
La sequenza di eventi scatenati da un processo di rollback è la stessa descritta in precedenza per l'elaborazione in avanti (forward). I record log identifica quali blocchi devono essere modificati e contiene anche tutti i dati necessari per eseguire l'operazione di annullamento.

Le transazioni possono essere ripristinate (rollback) in modo esplicito su richiesta dell’applicazione o dell'utente, o automaticamente dal database manager quando si verifica un errore e l'applicazione non è più in grado di comunicare con il database.
venerdì 22 maggio 2015

Transazioni - il concetto di logging


IL CONCETTO DI LOGGING

Il database manager di Progress realizza le proprietà di atomicità e durabilità di una transazione, utilizzando una tecnica di logging undo-redo, in combinazione con una write-ahead logging.
Dal momento che le modifiche del database avvengono per mezzo di una o più transazioni, notazioni o descrizioni di tali variazioni sono registrate su disco in un tipo di file di log delle transazioni, conosciuto come undo-redo log file. Quando si verifica un errore durante una transazione, questi record di log sono usati per effettuare il rollback della transazione, eliminando tutti i suoi effetti sul database (ripristino di tutti i dati ai loro valori precedenti). Gli stessi record di log sono usati al verificarsi di un crash recovery, per ripristinare il database in uno stato consistente.

Vi è un secondo log opzionale, chiamato redo log (discusso in seguito), che può essere utilizzato per migliorare l'affidabilità del sistema registrando il log delle transazioni in due fasi.

Il log undo-redo
Il log undo-redo è chiamato il "file di pre-immagine (before-image)" o "file BI". Il BI file contiene un registro di tutte le modifiche al database più recenti. Il database manager scrive uno o più record di log, riguardanti le modifiche, nel BI file prima di effettuare la modifica. Sebbene sia chiamato il before-image file, il log undo-redo file non contiene in realtà una pre-immagine del database. 
Esso contiene dati che vengono utilizzati per:
- Annullare o invertire gli effetti di una transazione che non è stata ancora commitata.
- Ripristinare il database in uno stato consistente dopo un crash, ripetendo (redo) le modifiche fatte in precedenza. Lo stesso insieme di modifiche potrebbe essere ripetuto più di una volta perché un guasto potrebbe verificarsi durante una fase di rcovery.
- Conservare gli effetti delle transazioni committate, anche in caso di fallimento
subito dopo il completamento della transazione.
- Consentire il riutilizzo incrementale di spazio nel file di undo-redo log quando i record non sono più necessari, riducendo al minimo la dimensione del file.
- Limitare la quantità di dati che devono essere elaborati, e il tempo richiesto per
farlo, durante il ripristino da un failure.
A seconda del tipo di operazione in corso sul database , ciò che è necessario per soddisfare tali requisiti potrebbe essere una copia dei dati prima di essere modificati, una copia dei nuovi dati, una combinazione dei due, o forse altre informazioni. Ci sono oltre 50 diversi tipi di record di log e ogni tipo contiene dati diversi.


Il BI file log può essere rappresentato da un singolo file o da più file (BI extents) che fanno parte di una struttura di database multi-file.

Redoing a change


L’informazione registrata nel file di log è tale che si può combinare i dati registrati nel log con i dati nella versione “vecchia” di un database block, per produrre una nuova versione aggiornata. Ad esempio, quando un record viene aggiornato, il record di log
conterrebbe vecchi e nuovi valori di solo quelle parti che hanno subito una modifica. I nuovi valori sarebbero fusi nel vecchio record per rifare (redo) una modifica.

Undoing a change


Lo stesso file log di registrazione, che è stato utilizzato per effettuare la modifica iniziale, può essere utilizzato per annullare un'operazione in combinazione con la nuova versione di un database block, per produrre la vecchia versione del record. Continuando l'esempio precedente, i vecchi valori sarebbero consolidati con il nuovo record per annullare una modifica.
Si noti che quando una modifica è annullata, si genera un nuovo record di log che descrive l'annullamento. Questo è necessario perché può verificarsi un errore prima che la copia, residente su disco, del database sia aggiornata a valle dello scatenarsi dell’evento di undo.

Il redo log
Il redo log è chiamato il "log dopo-immagine (after-image)" o "file AI". Il file AI contiene l’immagine di tutte  le modifiche che si sono verificate dopo un backup completo dell'intero database.
Lo scopo del AI log file è di fornire un meccanismo per il recupero dei dati da un eventuale incidente che distrugge tutto o in parte il database e/o il file di BI. Per recuperare i dati è necessario effettuare un ripristino del database e poi applicare tutte le modifiche che sono state fatte dai tempi del backup.
Il processo di riapplicare le modifiche si chiama roll-forward. Durante questo processo, il database manager legge i record nel file di AI e ripete ogni modifica di database, nello stesso ordine in cui sono state eseguite originariamente. Alla fine del processo di roll-forward, il database sarà nello stesso stato in cui si trovava appena prima l’errore si verificasse.
L’AI file log può essere rappresentato da un singolo file o da più file (AI extents) che fanno parte di una struttura di database multi-file.

Deferred Writes
L'esistenza del log undo-redo consente al database manager di mantenere in memoria le modifiche al database a tempo indeterminato, con una politica di gestione del buffer "steal/no force". I blocchi del database possono essere scritti su disco ogni volta che è conveniente. Le modifiche vengono mantenute in un'area di memoria chiamata database buffer pool e non devono essere scritte su disco, quando vengono apportate,  né quando la transazione che le ha effettuate è commited. È sufficiente che il transaction log record esista sul disco. Questo concetto è noto, in gergo, come "scritture differite (deferred writes)". Il meccanismo consente alte prestazioni ed ottimizzazione delle operazioni di scrittura su disco; i database blocks nel buffer pool possono essere aggiornati più volte prima di essere scritti su disco. Il database manager può scegliere il tempo e l'ordine in cui scrivere i dati, infatti, i blocchi aggiornati possono essere scritti prima che la transazione sia committata, o dopo, a seconda di quale momento è il più adatto. In effetti, il transaction log record consente di trasformare il processo di update sul database da random (più lento) a scrittura sequenziale (più veloce).

Write-ahead logging

Quando si utilizza la tecnica write-ahead, le registrazioni di tutte le modifiche del database sono scritte nel log, prima che siano applicate in memoria e su disco. In questo modo i dati nel undo-redo log (before-image log), possono essere usati per ripetere o rifare tutte le modifiche che possono essere perse prima di essere scritte nel database. Senza il log record, le modifiche non possono essere annullate se l'operazione di roll-back si rende necessaria. Il database non può essere ripristinato in uno stato coerente e sarà inutilizzabile. Affinché la tecnica di registrazione write-ahead funzioni correttamente, tutte le scritture nel log file devono essere effettuate in modo sincrono; ciò significa che quando il database manager scrive un buffer log su disco (utilizzando un chiamata di sistema write(), o qualcosa di simile), i dati devono essere effettivamente scritti su disco e non solo salvati in memoria. Per questo motivo i file di database, BI, AI non devono essere memorizzati su file system remoti montati attraverso le reti. 
venerdì 8 maggio 2015

Transazioni - Parte 1

Questo post è la prima parte di una breve guida, atta a descrivere come il Progress database engine utilizza le transazioni per migliorare affidabilità e prestazioni del database. Conoscere questi argomenti permette di essere meglio attrezzati per sfruttare appieno il Progress RDBMS.

Il concetto di transazione è fondamentale per il funzionamento dei sistemi di basi di dati.
Le transazioni sono un meccanismo di gestione degli errori e un meccanismo di strutturazione dei programmi.
Come meccanismo di gestione dell’errore, permettono di fare una quantità arbitraria di lavoro in una unità di tempo e poi cambiare idea. Quando si lavora all'interno di una transazione si può dire al sistema di ripristinare la situazione al momento iniziale; oppure si può dire di rendere ufficiali le modifiche.
Quando una transazione è in esecuzione si dice essere in stato active. Quando una transazione è completata diciamo che è committed. Se si verifica un errore prima che la transazione sia completa, il sistema annulla automaticamente qualsiasi lavoro che non può essere terminato a causa del fallimento. Il processo di annullare gli effetti di una operazione incompleta si chiama rollback.
Come il meccanismo di strutturazione di un programma, le transazioni hanno confini ben definiti dove incapsulare le operazioni su database eseguite da un’applicazione.
L’incapsulamento in una transazione deve essere accompagnato dall'incapsulamento nell'applicazione.
Le transazioni hanno quattro proprietà di base (proprietà ACID): atomicità,
consistenza, isolamento e durabilità. Queste proprietà sono strettamente correlate tra loro
e sono descritte di seguito.

Atomicità
La proprietà atomicità dice che le transazioni sono “tutto o niente”.
Le transazioni spesso apportano diverse modifiche ad un database. Questi cambiamenti correlati sono una unità logica di lavoro che deve essere eseguita insieme. Ad esempio, per trasferire denaro da un conto bancario ad un altro, i fondi devono essere dedotti dal primo conto e aggiunti al secondo. Queste operazioni devono essere eseguite come un'unità. 

Consistenza
La proprietà consistenza dice che le operazioni trasformano il database da un
stato coerente ad un altro.
La nozione di coerenza si riferisce sia alla coerenza del database fisico (cioè che le strutture interne del database, come gli indici, i records, ecc, sono validi e coerenti) che alla coerenza del database logico (cioè che i dati contenuti nel database sono validi dal punto di vista di un'applicazione).
La consistenza fisica è gestita interamente dal database manger. Si tratta di un prerequisito per la consistenza logica.
La consistenza logica, d'altra parte, è gestita sia dal database manager,
attraverso meccanismi quali regole di convalida, trigger, vincoli di integrità, ecc, che dalle azioni dell'applicazione.
Affinché la trasformazione da uno stato ad un altro sia valida , il database manager e l’applicazione devono eseguire le azioni opportune per garantire la consistenza.
Bisogna ricordare che durante l’esecuzione di una transazione, lo stato del database può essere incoerente. La coerenza deve esistere solo quando una transazione si conclude.

Isolamento
La proprietà di isolamento dà, ad ogni transazione, l'illusione che essa sia l'unica in esecuzione.
Gli effetti delle diverse transazioni, contemporaneamente in esecuzione, non devono essere visibili a ciascuna altra. Tutte le modifiche apportate da una transazione sono considerate provvisorie, mentre è ancora in esecuzione. Diventano "ufficiali" o permanenti solo quando la transazione si conclude con successo (commit  rollback).
Pertanto è importante che una transazione non prenda decisioni basate sulle modifiche apportate da un’altra. 
Il database manager provvede al concetto di isolamento attraverso l'uso di un meccanismo di two-phase locking. Questo argomento esula dallo scopo di questa guida.

Durabilità
La proprietà durabilità dice una volta committato, sempre committato.

Quando una transazione è committata, i suoi effetti sulla base di dati sono permanenti. Non possono essere annullati anche se si verifica un guasto. Gli effetti di una transazione committata possono essere invertiti eseguendo una seconda transazione che annulla gli effetti della prima.