In-Memory database - Ingegneria Informatica

Facoltà di Ingegneria
Corso di Studi in Ingegneria Informatica
Elaborato finale in Basi di Dati
In-Memory database
Anno Accademico 2012/2013
Candidato:
Maritato Luigi
Matr. N46/762
A Monica,
infinitamente grazie.
Indice
Capitolo 1:MMDB vs DBMS
1.1 Un po di storia…………………………………………………………….4
1.2 Scenario applicativo………………………………………………………5
1.3 Confronto…………………………………………………………………5
1.4 Supporto Acid…………………………………………………………….6
1.4.1 On line backup………………………………………………………….7
1.4.2 Transaction logging………………………………………………….…7
1.4.3 NVRAM………………………………………………………………..7
Capitolo 2:In memory database
2.1 Architettura……………………………………………………………….8
2.2Query e relazioni………………………………………………………….9
2.2.1 Liste temporanee……………………………………………………….9
2.3 Main Memory index structure…………………………………………..10
2.3.1 Strutture indice esistenti……………………………………………….10
2.4 T-Tree……………………………………………………………………12
2.5 T-Tree:Algoritmi di ricerca e aggiornamento…………………………...14
2.5.1 Algoritmo di ricerca…………………………………………………...14
2.5.2 Algoritmo di inserimento……………………………………………...14
2.5.3 Algoritmo di eliminazione…………………………………………….15
2.6 Rebalancing……………………………………………………………...16
2.7 Performance degli algoritmi e delle strutture dati……………………….20
Capitolo 3:Recovery
3.1 Introduzione………………………………………………………………….25
3.2 Logging………………………………………………………………………26
3.3 Reloding………………………………………………………………….…..26
Capitolo 1
MMDB vs DBMS
Introduzione
Con il termine in-memory database(IMBD),detto anche sistema di basi dati in
memoria centrale(MMDB) si intende un database che utilizza la memoria principale
per la memorizzazione dei dati. I database in memoria centrale sono molto più veloci
di quelli su memorie di massa, ma possono gestire moli di dati molto inferiori, a patto
che ci sia comunque un modo per recuperarli in caso di guasti mediante ad esempio
tecniche di ripristino.
Vedremo nel seguito che un IMDB può essere implementato anche con strutture
differenti da quelle utilizzate per l'approccio relazionale (tabelle), quali quelle
suggerite dal modello reticolare (puntatori) e dal modello gerarchico (alberi) .
1.1 Un po di storia
Inizialmente gli sviluppatori dei sistemi embedded realizzavano delle soluzioni per la
gestione dei dati. Con l’avvento della concorrenza sul mercato che richiedeva
dispositivi sempre più intelligenti, le applicazioni dovevano essere dotate di
caratteristiche funzionali sempre più complesse per la gestione dei dati. La difficoltà
nella gestione dei dati ed il costo portarono gli sviluppatori di sistemi embedded a
progettare database commerciali.
I primi DBMS tradizionali erano caratterizzati dall’avere una logica di caching molto
complessa per aumentare le prestazioni, e con tante funzioni inutili per il dispositivo
che faceva uso di database embedded.
Successivamente queste caratteristiche portarono allo sviluppo di applicazioni che
superavano il concetto di memoria disposizione
memoria disponibile e che fossero in grado di sfruttare meglio le risorse della CPU.
Quindi nacquero database in memoria principale specificamente per soddisfare le
esigenze di prestazioni e di disponibilità delle risorse nei sistemi embedded.
1.2 Scenario applicativo
Un sistema di gestione dei dati in memoria principale offre enormi garanzie in
termini di prestazioni a vantaggio di tutte quelle applicazioni che necessitano di
accedere in maniera rapida ai dati.
Esempio:
-le applicazioni real time dove sono richieste performance molto elevate in
termini di throughput e soprattutto latenza;
-possono essere utili anche per lo sviluppo di Database tradizionali residenti
sul disco allo scopo di fare testing.
1.3 Confronto
Con i MMDB non esiste più il concetto di I/O verso i dischi bensì di tratta di database
tradizionali caricati in memoria principale. Le differenze riguardano:
-il casching
-Overhead dovuto al trasferimento dei dati
-elaborazione delle transazioni
1.3.1 Il Cashing
In generale tutti i DBMS supportano meccanismi di casching al fine di mantenere i
record più utilizzati in memoria principale x ridurre il numero di accessi al disco.
Se questa attività non viene più considerata si escludono sostanzialmente 2 problemi:
-la sincronizzazione ,usata per garantire la consistenza dei dati presenti in
memoria con quelli presenti sul disco;
-louckup nella casche al fine di determinare se il record richiesto si trovi nella
casche.
Quindi non considerando la casche in un IMBD non si ha più la difficoltà nel gestire
la complessità di questa operazione riducendo di conseguenza anche il lavoro che la
CPU deve fare quando si hanno a che fare DMBS completamente sviluppati in
memoria.
1.3.2 Overhead dovuto al trasferimento dei dati
Mentre nei DB tradizionali l’overhead dovuto al trasferimento tra casche DB e il
disco in MDB attraverso i puntatoti e quindi attraverso le API è possibile accedere ai
dati residenti nel database
1.3.3 Elaborazione delle transazioni
In un database orientato ai dischi, il processo di ripristino quando si verifica un abort
delle transazioni è basato su un file di log aggiornato ogni volta che essa viene
eseguita. Per garantire l’integrità della transazioni, IMBD conserva un immagine
dell’oggetto aggiornata e in caso di abort un IMDB si impegna a ripristinarla.
1.4 Supporto ACID
Nell'ambito dei database, ACID deriva dall'acronimo inglese Atomicity,
Consistency, Isolation, e Durability (Atomicità, Coerenza, Isolamento e Durabilità)
ed indica le proprietà logiche che devono avere le transazioni.
Affinchè le transazioni operino in modo corretto sui dati è necessario che i
meccanismi che le implementano soddisfino queste quattro proprietà:
atomicità: la transazione è indivisibile nella sua esecuzione e la sua esecuzione
deve essere o totale o nulla, non sono ammesse esecuzioni parziali;
•
coerenza: quando inizia una transazione il database si trova in uno stato
coerente e quando la transazione termina il database deve essere in un altro
stato coerente, ovvero non deve violare eventuali vincoli di integrità, quindi
non devono verificarsi contraddizioni (inconsistenza) tra i dati archiviati nel
DB;
•
isolamento: ogni transazione deve essere eseguita in modo isolato e
indipendente dalle altre transazioni, l'eventuale fallimento di una transazione
non deve interferire con le altre transazioni in esecuzione;
•
durabilità: detta anche persistenza, si riferisce al fatto che una volta che una
transazione abbia richiesto un commit work, i cambiamenti apportati non
dovranno essere più persi. Per evitare che nel lasso di tempo fra il momento in
cui la base di dati si impegna a scrivere le modifiche e quello in cui li scrive
effettivamente si verifichino perdite di dati dovuti a malfunzionamenti,
vengono tenuti dei registri di log dove sono annotate tutte le operazioni sul DB.
Le prime tre caratteristiche sono solitamente supportati da un IMBD, al contrario
della durabilità perché la memoria principale è una memoria volatile e perde tutti i
dati memorizzati durante un reset.
Con le loro elevate prestazioni IMDB sono una buona soluzione per le time-critical
applications, ma quando sorge la necessità della durata non è più una soluzione
adeguata.
Per ottenere la durabilità nei database in memoria principale ci sono diverse
soluzioni:
-On-Line Backup.
-Registrazione delle transazioni (Transaction logging)
-RAM non volatile (NVRAM)
1.4.1 On-Line Backup
On-line backup è un backup eseguito mentre il database è on-line ed è disponibile per
la lettura/scrittura. Questa è la soluzione più semplice ma offre una durabilità molto
bassa
1.4.2 Transaction Logging
Una transazione log è la storia delle azioni eseguite da un database managment
system. Al fine di garantire la proprietà ACID per incidenti o guasti sul hardware il
log deve essere scritto in una memoria non-volatile, solitamente un hard disk. Se il
sistema fallisce e poi viene riavviato l’immagine del database può essere ripristinata
da questo log file.
Il processo di ripristino funziona in modo simile ai DBMS tradizionali, dove in caso
di guasto il sistema di RECOVERY è incaricato di riportare il database ad uno stato
corretto (stato del DB precedente a transazioni di modifica che non sono state
terminate con successo)precedente al guasto.
Tuttavia questa tecnica comporta l’utilizzo di memorie persistenti come un disco
rigido che è un collo di bottiglia specialmente durante la ripresa del database.
Nonostante questo aspetto IMDB sono ancora più veloci rispetto ai tradizionali
DBMS perché il logging delle transazioni richiede una operazione di scrittura nel file
system ,mentre con i database basati sui dischi non solo bisogna scrivere sul log ma
bisogna tener conto anche dei dati e gli indici.
1.4.3 NVRAM
Per ottenere la durabilità ,IMDB può supportare una ram non volatile (NVRAM): di
solito una RAM statica sostenuta con alimentazione a batteria, o una EEPROM.
In questo modo il DBMS sarà in grado di recuperare i dati anche dopo un reboot.
Questa rappresenta una opzione molto interessante per la durabilità di un IMDB
perché NVRAM in contrasto con le soluzioni precedenti non comporta la latenza
relativa ai dischi né overhead nella comunicazione.
Capitolo 2
In-Memory database
2.1 Architettura
Il cambiamento più notevole ed evidente tra i metodi di accesso
di un MMDB e DRDB, è la mancanza del buffer manager per MMDB.
Da un punto di vista architetturale la necessità di un buffer manager in un DBMS è
nata poiché spesso la gestione dei dati è enorme e nel corso delle elaborazioni può
capitare che lo spazio richiesto per i blocchi di dati sia maggiore della spazio di
memoria disponibile. Nel DRDB il buffer manager è presente per fornire una
comunicazione efficiente tra la memoria e il disco, per la memorizzazione dei dati in
memoria e lo swapping verso il disco.( Si ricorda che) . Poichè tutti gli accessi in
MMDB sono in memoria, il buffer manager non è necessario.
L’assenza di una buffer manager comporta enormi vantaggi in termini di operazioni
,di risorse utilizzate e tempi di calcolo perchè viene meno la necessità di una copia
dei dati dal disco e del mapping degli indirizzi sul disco a indirizzi di memoria.
Anche la struttura degli indici progettati per la memoria principale sono diverse da
quelli progettati per i sistema basati sui dischi. Il primo obbiettivo per una struttura
degli indici nei database orientati ai dischi è quello di minimizzare il numero di
accessi al disco e occupare meno spazio possibile su di esso. La struttura degli indici
in memoria principale è contenuta in memoria principale ,non considerando per nulla
il disco.
L’obiettivo di un indice in memoria principale è ridurre il tempo di calcolo
complessivo e contemporaneamente utilizzare meno memoria possibile. Poichè le
relazioni sono presenti in memoria non è necessario un indice per memorizzare il
valore degli attributi. Invece i puntatori alle tuple possono essere memorizzati da
qualche parte nella heap ed essere utilizzati per ricavare il valore degli attributi
quando se ne ha bisogno. Vantaggi:
-un puntatore a una singola tupla fornisce l’indice di accesso sia al valore di un
attributo della tupla sia all’intera tupla, riducendo la dimensione dell’indice;
-spostare i puntatori è più conveniente che spostare il valore degli attributi
quando gli eventuali aggiornamenti richiedono delle operazioni sugli indici.
2.2 Query e Relazioni
Quando si esegue una query su un MMDB piuttosto che su un DRDB, il fattore
dominante non è il numero di operazioni di I/O verso il disco ma piuttosto il tempo
della CPU.
Come si accede alle relazioni? Attraverso gli indici(Ogni relazione deve avere
almeno un indice).Le tuple in una partizione della memoria vengono individuate
attraverso un indirizzo di memoria e ciò richiede che non possano cambiare
locazione una volta memorizzate sul database. Per una campo di lunghezza variabile,
la tupla stessa presenterà un puntatore a quel campo allocato nell’area heap. In alcuni
casi la tupla potrebbe portare all’overflow dell’area di memoria heap,
impossibilitando l’accesso a quella tupla e di conseguenza portare allo spostamento
della tupla in un'altra area di memoria .Dato che le tuple in memoria possono essere
accedute in maniera randomica è possibile utilizzare i puntatori. Per esempio ,la
chiave esterna (attributo che riferisce a tuple di altre relazioni) può essere sostituita da
un campo puntatore a un tupla(nel caso di relazione 1-1 il campo presenterà un unico
puntatore, nel caso di una relazione 1-n presenterà una lista di puntatori).Quindi con
MM_DBMS la chiave esterna può essere semplicemente sostituita da un puntatore.
Ciò mi consente una gestione efficiente dello spazio in memoria perché i puntatori
sono tipi di dati che rappresentano la posizione.
2.2.1 Le liste temporanee
Gli MMDB utilizzano la struttura Lista Temporanea per salvare il risultato delle
query sulle relazioni. Essa è costituita da una lista di puntatori a tuple con output
della query. Il puntatore punta alla relazione(i) sorgente dal quale la relazione
temporanea è nata e il risultato della descrizione identifica i campi che sono
contenuti nella relazione che rappresenta la lista temporanea. Anche in questo caso
per accedere è possibile associare un indice.
Ad esempio, se le relazioni Employee e il Departiment di Figura 1 sono unite dal
campo id del Dipartiment, alla fine ogni tupla risultante nella lista temporanea
verrebbe a memorizzare una coppia di puntatori a tupla ( una che punta alla tupla di
Employee e l’altro alla tupla del Dipartiment), e nella Result Descriptor troviamo la
lista dei campi presenti nel Result Relation .
Figura 1
2.3 Main memory index structure
Le strutture dati index si distinguono in 2 tipi:
-quelli che conservano l’ordinamento naturale dei dati;
-quelli che conservano un ordinamento casuale dei dati.
2.3.1 Strutture indice esistenti
Array :
utilizzati in particolare nei progetti IBM-ODE. La caratteristica è che occupano
poco spazio a condizione che la dimensione sia nota in anticipo;
AVL Tree:
è una struttura dati autobilanciante basata sugli alberi di ricerca binaria. La
ricerca in esso è efficiente perchè si svolge esattamente come quella applicata
agli alberi binari di ricerca, di conseguenza non viene perso del tempo in
calcoli aritmetici per la determinazione degli indici. Dall’altro lato un AVL
Tree occupa spazio, perché ogni nodo contiene il dato, un puntatore a un
figlio sinistro, uno a un figlio destro, e le informazioni di bilanciamento (Vedi
figura 2) .
Gli algoritmi di inserimento e cancellazione in un AVL-Tree bilanciano l'albero
riordinando i nodi dei sottoalberi (attraverso cioè una rotazione);la struttura
AVL-Tree è considerata bilanciata se, per ogni nodo, la profondità o
l’altezza dei due sottoalberi differisce al più di uno(invece nel B-Tree la
profondità deve essere uguale);
B-Tree:
Tale struttura è nota come struttura dati esterna alla memoria. La sua
caratteristica più evidente è che la dimensione del nodo può essere molto
grande per consentire a ogni nodo di contenere più valori.
La ricerca di un elemento è una ricerca binaria ma non è sempre fattibile
perchè dipende dalla dimensione di ogni nodo. Se nell’AVL-Tree il problema
era lo spazio, il B-Tree è molto più efficiente in tal senso perché le foglie
contengono solo dati(Vedi figura 3).
Per quanto riguarda le operazioni di inserimento e cancellazione di un B-Tree
esse mantengono l'albero bilanciato dividendo o unendo i nodi e spostando i
dati all'interno o tra nodi; nel caso degli indici che si utilizzano in un B-Tree in
memoria principale ,solo i puntatori ai dati vengono spostati.
Dove è possibile utilizzare questa struttura? Perchè? Dato che lo spazio
occupato è poco(la dimensione dei puntatori è piccola e i nodi foglia
mantengono solo i dati),la ricerca è rapida(i nodi vengono ricercati tramite una
ricerca binaria) e l’aggiornamento di un nodo è rapido(la spostamento dei dati
riguarda un nodo) la struttura è adatta per essere utilizzata per i database in
memoria principale;
Chained Bucket Hashing
E’ una struttura statica usata sia in memoria che sul disco. La staticità della
struttura mi consente di accedere molto rapidamente e riorganizzare i dati
efficientemente. Tuttavia questo vantaggio è anche il suo svantaggio perché se
è statica può avere un pessimo comportamento in un ambiente dinamico dato
che la dimensione della tabella di hash deve essere nota o stimata prima che la
tabella si riempa;
Extendible Hashing
impiega una tabella di hash dinamica dove la dimensione cresce con
l’aumentare dei dati, quindi in questo caso non occorre conoscere in anticipo la
dimensione della tabella.
2.4 T-Tree
E’ un evoluzione di un AVL-Tree e di un B-Tree. Si tratta di una struttura dati ad
albero binario dove in ogni nodo ci sono molti elementi. Prende i vantaggi sia di
AVL-Tree per la ricerca binaria che di un B-Tree che possiede buone caratteristiche di
memorizzazione e aggiornamento.
Mentre il nodo di un AVL-Tree ha due puntatori figli più un informazione di
bilanciamento e un dato, un nodo T-Tree è identico ma si distingue per il numero di
dati(vedi figura). Lo spostamento dei dati viene richiesto per inserimento e
l’eliminazione, ma in genere si applica solo all’interno dei nodi.
Per quanto riguarda le operazioni che si possono fare sulla struttura oltre
all’inserimento, la cancellazione e la ricerca c’è da aggiungere l’operazione di
rotazione per ottenere il bilanciamento dell’albero che si fa allo stesso modo di come
la si applica su un AVL-Tree(argomento oggetto di interesse nella sezioni successive).
Terminologia
Ci sono 3 differenti tipi di T-Node(Figura 4):
o
o
o
Un T-Node che ha 2 sottoalberi viene chiamato internal node;
Un T-Node che possiede un puntatore figlio non nullo e l’altro nullo
viene chiamato half-leaf node.
Un nodo che ha due puntatori nulli viene chiamato leaf-node.
Per ogni nodo interno A abbiamo una foglia corrispondete(o half-leaf Node) che
conserva il valore ,rappresenta il predecessore del minimo valore in A, e c’è un leaf
Node(o half-leaf Node) che conserva il successore al massimo valore in A. Il valore
del predecessore viene chiamato the Greatest Lower Bound del nodo interno A, e il
valore del successore viene chiamato Least Upper Bound di A(Figura 5).
Dal momento che i dati in un T-Node vengono memorizzati in modo ordinato, il suo
elemento più a sinistra è l'elemento più piccolo del nodo e il suo elemento più a
destra è il più grande.
2.5 T-Tree: Algoritmi di ricerca e di aggiornamento
2.5.1 Algoritmo di ricerca
In un T Tree la ricerca è simile alla ricerca negli alberi binari. La differenza
sostanziale è che i confronti vengono effettuati con il valore massimo e il valore
minimo del nodo piuttosto che con un singolo valore del nodo di un albero binario.
I passi per la ricerca sono i seguenti:
1)La ricerca comincia sempre dal nodo radice dell’albero;
2)se il valore ricercato è più piccolo del più piccolo valore del nodo la ricerca
prosegue lungo il sottoalbero di sinistra. Altrimenti se il valore è più grande del
massimo valore del nodo, allora la ricerca prosegue nel sottoalbero di destra.
Altrimenti la ricerca viene effettuata nel nodo puntato.
Può capitare che la ricerca non vada a buon fine per i seguenti motivi:
-O quando il nodo viene trovato ma non viene trovato il valore;
-Oppure quando il nodo non viene trovato perché il valore ricercato non cade
in nessun intervallo di valori del nodo
2.5.2 Algoritmo di inserimento
L’algoritmo di inserimento comincia con una ricerca. In particolare il percorso dalla
radice alla foglia viene salvato sullo stack.
Se il T-Tree non è bilanciato dopo un inserimento o una cancellazione, esistono delle
particolari operazioni di riequilibrio che controllano i nodi tra il nodo radice ed il
figlio dove è avvenuto l’inserimento o la cancellazione.
L’algoritmo di inserimento opera nel seguente modo:
1)ricerca il nodo limite ,si salva il nodo e la direzione(destra o sinistra) effettuata a
ogni livello sullo stack;
2)se il nodo viene trovato ,bisogna verificare se c’è lo spazio per un altro elemento.
In caso affermativo si inserisce il nodo e ci si ferma. Altrimenti, bisogna rimuovere
l’elemento più piccolo dal nodo, inserire il vecchio ,inserire il valore ,e rendere
l’elemento più piccolo il nuovo valore inserito.
- A questo punto si fanno le stesse operazioni del punto 1(nel caso peggiore,
l’elemento più piccolo verrà inserito in una foglia diventando il new greatest
lower bound value per questo nodo);
3)Se la ricerca giunge alla fine dell’albero e non è stato trovato nessuno nodo che
delimita il valore dell’inserimento, inserisci il valore nell’ultimo nodo(nodo foglia o
mezza foglia).
-Se il valore viene inserito, esso diventa il massimo o il minimo del nodo;
In caso contrario, crea un nuovo figlio(quindi il valore inserito diventa il primo
elemento del nuovo figlio);
4)Se viene aggiunto un altro nodo foglia, bisogna controllare il bilanciamento
dell’albero attraverso il percorso salvato sullo stack.
-Per ogni nodo nel percorso di ricerca(partendo dalla foglia alla radice),se due
sottoalberi di un nodo differiscono per la profondità di uno o più livelli ,deve
essere effettuata una rotazione. Una vola che la rotazione è stata effettuata
l’albero viene ribilanciato e l’elaborazione termina
Si fa notare che quando il valore minimo viene rimosso e va ad aggiungersi a un nodo
foglia, l’inserimento del valore nella foglia non richiede alcuno spostamento dei dati
perché diventa il valore più a destra della foglia; se invece veniva rimosso il valore
massimo dal nodo bisognava inserirlo come elemento più a sinistra del nodo foglia
cosa che richiede un spostamento dei dati all’interno del nodo. Quindi rimuovendo il
valore minimo invece del massimo si evita questo spostamento dei dati.
2.5.3 Algoritmo di eliminazione
L'algoritmo di cancellazione è simile all'algoritmo di inserimento nel senso che
l'elemento da cancellare viene cercato, il percorso di ricerca viene salvato sullo stack,
ed eventualmente si effettua il rebalancing.
L’algoritmo opera in questo modo:
1)Trova il nodo che delimita il valore da cancellare ,salvando il percorso di ricerca
sullo stack. Ricerca il valore da eliminare all’interno di questo nodo riportando un
errore se il valore non viene trovato;
2) Se la cancellazione non causerà un underflow (cioè se il nodo ha più del numero
minimo consentito di elementi prima della cancellazione), quindi è sufficiente
eliminare il valore e fermarsi; Altrimenti, se si tratta di un nodo interno, bisogna
eliminare il valore e prendere in prestito il più grande limite inferiore di questo nodo
da una foglia o mezza foglia per riportare il numero di elementi del nodo al minimo;
salva il percorso di ricerca sullo stack durante la ricerca del limite inferiore più
grande .
Nel caso in cui si tratta di una foglia o una mezza foglia, basta semplicemente
cancellare l’elemento(half-leaves vengono gestite al passo 3);
3)A questo punto lo stack conterrà un percorso dalla radice alla foglia o mezza foglia
in cui un elemento è stato rimosso. Se il nodo in cima allo stack (cioè l’ultimo nodo
memorizzato)è una mezza foglia e possiede un numero di elementi inferiore al
numero minimo, allora bisognerà prendere un elemento dal suo unico figlio e
memorizzare il figlio sullo stack;
4)Se la foglia in cima allo stack non è vuota bisogna fermarsi, altrimenti occorre
liberare il nodo e procedere in questo modo per ribilanciare l’albero:
° Per ogni nodo lungo il percorso dalla foglia fino alla radice, se i due
sottoalberi del nodo differiscono in altezza per più di uno, allora bisogna
eseguire un'operazione di rotazione (vedi in sezioni successive). Poiché una
rotazione ad un nodo può provocare uno squilibrio per un nodo più in alto nella
struttura, il controllo del bilanciamento per l'eliminazione deve esaminare tutti i
nodi del percorso di ricerca;
2.6 Rebalancing
L’equilibrio di un T-Tree viene verificato ogni volta che una foglia viene aggiunta o
cancellata, esattamente come indicato quando abbiamo parlato di algoritmi di
cancellazione e inserimento. Il percorso di ricerca memorizzato sullo stack viene
controllato dalla radice alla foglia-per ogni nodo del percorso, se il nodo con 2
sottoalberi presentano una profondità maggiore di uno allora è necessaria un
operazione di rotazione.
Nel caso di un inserimento, al più una rotazione è necessaria per ribilanciare l’albero,
e dopo la prima rotazione il processo termina. Una rotazione su un nodo può
innescare uno squilibrio per un nodo più in alto nella struttura in caso di
cancellazione, in questo modo elaborazione continua lungo tutto il percorso fino alla
radice.
La figura 6 mostra una rotazione LL e una rotazione LR più complessa nel caso di
un inserimento. Questi sono 2 dei 4 tipi di rotazione utilizzate per ribilanciare un
AVL-Tree o un T- Tree(Gli algoritmi per la Rotazione RR e RL sono simmetrici a LL
e LR e non vengono mostrati).
Figura 6
Quando viene realizzata una rotazione LR o RL e il nodo C è una foglia (quindi
entrambi i nodi A e B sono mezze foglie), una rotazione sposterebbe C in una
posizione di nodo interna(vedi la figura 7).
Figura 7
Il ribilanciamento dopo la cancellazione è identico al ribilanciamento dopo
l’inserimento , ma la causa dello squilibrio nell'albero è che un sottoalbero è cresciuto
di meno rispetto a quello più lungo. La Figura 8 mostra le rotazioni LL e LR nel
caso di un'operazione di cancellazione.
Figura 8
2.7 Performance degli algoritmi e delle strutture dati
Inserimento
Il grafico 9 mostra i risultati del test di inserimento.
In particolare si osserva che il costo di un serie di inserimenti dipende dal tempo di
ricerca e dal numero di spostamenti che vengono effettuati per inserire un dato
elemento .
Il costo di inserimento per la struttura array non viene illustrato perché è dieci volte
maggiore rispetto a tutti gli altri indici dovuto a un enorme spostamento di dati
quando esso è molto grande.
Gli indici di una tabella hash non richiedono movimento di dati perchè il nuovo
elemento viene semplicemente accodato ai valori nel nodo di conseguenza il tempo
di ricerca di questi indici è quindi costante e dipende dalla dimensione del nodo;
-se aumenta la dimensione del nodo aumenta anche il tempo di ricerca.
Invece per il T-Tree, il costo della ricerca è O(log2 N),dove N rappresenta il numero
di elementi, di conseguenza all’aumentare del numero di elementi nel nodo cresce il
tempo di inserimento(dal grafico si osserva che la variazione è molto piccola per
valori grandi di N).
La ricerca all’interno di un albero AVL è più rapida della ricerca compiuta in un BTree, ma il B-Tree riesce ad avere un ribilanciamento più rapido rispetto al B-Tree.
-Il T-Tree ha i costi di inserimento del B-Tree(dal momento che può scorrere i
dati all’interno del nodo)e i costi di ricerca dell’albero AVL(perché la ricerca è
binaria).
Conclusione: Il T -Tree offre performance ottime nell’inserimento
Grafico 9
Ricerca
Il grafico 10 mostra i risultati della ricerca. La ricerca nel T-Tree è simile alla ricerca
negli alberi AVL. Nel momento in cui viene individuato il nodo corretto, si applica la
ricerca binaria su tale nodo. Ciò rende il costo della ricerca di un elemento in un TTree leggermente superiore alla ricerca in un albero AVL.
Grafico 10
Eliminazione
Grafico mostra i risultati del test della cancellazione. In particolare per ogni struttura
è stato applicato l’algoritmo al fine di eliminare metà degli elementi. Le strutture di
hashing sono le migliori in termini tempi di eliminazione.
Dal grafico 11 si osserva che i tempi di eliminazione del B-Tree si riducono per nodi
di dimensione maggiori, invece per i T-Tree il tempo di eliminazione degli elementi
è direttamente proporzionale al numero degli elementi presenti in ogni nodo.
Costi di memorizzazione di ogni struttura
Il grafico 12 mostra il costo totale medio di memorizzazione (in byte) per ciascuna
delle strutture di dati. Il costo totale di memorizzazione è semplicemente il numero
totale di byte necessari per contenere i dati della struttura.
L’albero AVL e la struttura Array rappresentano rispettivamente il limite superiore e
il limite inferiore dei costi di memorizzazione la differenza è determinante dal fatto
che in un nodo del AVL-Tree non c’è solo il valore del dato ma ci sono anche
informazioni come le informazioni di controllo.
Il B-Tree e il T-Tree hanno dei costi di memorizzazione quasi identici dal momento
che strutturalmente sono piuttosto uguali.
Grafico 12
Conclusioni
Perché per i database in memoria principale si usa la struttura T-Tree?
Gli alberi AVL hanno una buona ricerca e tempi di esecuzione molto onesti nelle
operazioni di aggiornamento quali inserimento e cancellazione ,ma hanno elevati
costi di memorizzazione per cui non sono così tanto adatti ai database in memoria
principale .
Gli array hanno un tempo ricerca ragionevole e dei costi di memorizzazione bassi per
via della loro struttura, ma ogni attività di aggiornamento comporta tempi di
esecuzione molto elevati rispetto alle altre strutture T-Tree e B-Tree, hanno bassi
costi di memorizzazione ma non sempre .Il tutto è legato alla dimensione dei nodi che
solo per alcuni valori offre buone prestazioni .
Il T-Tree sembra essere il migliore per il semplice motivo che si comporta in maniera
molto buona in tutte le operazioni che si fanno su di esso e anche in termini di costi di
memorizzazione(Figura 13)
Figura 13 - Confronto fra gli indici
Capitolo 3
Recovery
Introduzione
In un database di memoria principale (MMDB) la copia principale del database
risiede nella memoria voltatile. Di conseguenza i sistemi MMDB sono più vulnerabili
ai guasti rispetto database tradizionali residenti sul disco. Una copia di backup del
database deve essere mantenuta in memoria secondaria per un eventuale ripristino.
Molto importante durante il recovery di un database in memoria principale è che il
tempo di recupero aumenta quasi linearmente con l'aumento delle dimensioni del
database cioè aumenta all’aumentare del numero di tuple nel database.
La percezione di dove risiedono i dati è fondamentale. Mentre per un DBMS i dati
vengono memorizzati su disco e sono necessarie delle operazioni di I/O per accedere
ai dati ,nei sistemi MMDB non è necessario eseguire le operazioni di I / O. Pertanto,
essi sono adatti per applicazioni che richiedono un throughput alto e un tempo di
risposta veloce.
Una architettura generale MMDB consiste di una memoria principale implementata
tramite una RAM standard e talvolta anche una memoria non volatile . La memoria
principale contiene la copia principale del database, mentre la memoria stabile tiene il
registro e una copia di backup del database. La memoria non volatile è destinata
anche a contenere aggiornamenti eseguiti attraverso le transazioni mentre il log
contiene le informazioni relativi a questi aggiornamenti .E’ evidente che per
soddisfare le elevate prestazioni richieste in presenza molte applicazioni in tempo
reale, i MMDB sono naturalmente più vulnerabili a fallimenti rispetto ai DRDB. Di
conseguenza, il recovery di un componente di un MMDB deve essere adeguatamente
progettato, implementato e mantenuto.
Le attività di recovery, hanno il solo scopo di riportare il database in uno stato
consistente dopo un crash di sistema che si è verificato durante il funzionamento. E’
il recovery manager di un sistema di elaborazione delle transazioni responsabile di
mantenere la consistenza del sistema di database a seguito di crash del sistema e
delle transazioni.
Tre sono gli aspetti del recovery del sottosistema che servono a garantire a un
MMDB la possibilità di recuperare da qualsiasi guasto: logging, checkpoint e
reloding. Il Logging conserva un registro delle attività di aggiornamento che si
verificano durante l'esecuzione di una transazione. Il Checkpointing “scatta una foto”
del database periodicamente e lo copia su un dispositivo di archiviazione per scopi di
backup. A seguito di un crash di sistema, la ricarica ripristina il database in uno stato
consistente. In particolare viene ricaricata nella memoria principale la copia di
backup che è stata registrata durante l'ultimo checkpoint.
Nel seguito saranno affrontati il Logging e il Reloding nei database in memoria
principale ma non il Ckeckpoint per motivi implementativi.
3.2 Logging
Nel logging MMDB, l’ informazioni di registro può essere registrata a due diversi
livelli di astrazione, soprannominati physical logging e logic logging. I record del
livello fisico mantengono, per ogni aggiornamento, lo stato delle modifiche del
database e la posizione fisica (ad esempio id pagina e offset) a cui viene applicato
l'aggiornamento. I record del livello logico registrano le transizione di stato del
database e la posizione logica interessata dall'aggiornamento.
Lo svantaggio della registrazione logica è determinato dalla sua complessità sia
durante la normale elaborazione che durante il recupero poichè devono essere prese
misure per garantire che ogni azione commessa venga eseguita esattamente una volta
e allo stesso modo.
Il Write Ahead Logging (WAL) è il tipo di protocollo di logging più
utilizzato, in cui i dati di log devono essere scritti nella memoria non
volatile prima che l'aggiornamento possa riguardare il database. Il protocollo WAL
assicura che gli effetti delle transazioni che non sono andati a buon fine(uncommited)
possono essere annullati.
Per le transazioni committed, il DBMS deve sempre riflettere gli aggiornamenti
indipendentemente dai crash di sistema. In questo modo, quando un transazione va a
buon fine, l’ informazioni REDO che è stato scritto da tale transazione dovrebbe
essere memorizzata su di una memoria non volatile.
3.3 Reloading
Rappresenta una della parti più importanti del processo di ripristino.
Lo scopo del Reloading è quello di garantire che il database sia consistente dopo un
crash. Il database viene caricato dall'ultima immagine controllata e le operazioni di
undo(annullamento) e redo(ripetizione) vengono applicate per ripristinare al più
recente stato coerente. Gli schemi di reloading esistenti possono essere suddivisi in
due classi distinte per complessità e efficienza: simple reloading e cuncurrent
reloading. Nel reloding semplice, il sistema non riprende il suo normale
funzionamento fino a quando l'intero database viene ripristinato nella memoria
principale. Nel reloading parallelo, le attività di ricarica e di elaborazione delle
transazioni vengono eseguiti in parallelo.
Conclusioni
E’ stato spiegato che gli IMBD, sono sistemi di basi dati in memoria centrale che
utilizzano la memoria principale per la memorizzazione dei dati. Inoltre sono veloci
di quelli su memorie di massa, ma possono gestire moli di dati molto inferiori, a patto
che ci sia comunque un modo per recuperarli in caso di guasti mediante ad esempio
tecniche di ripristino.
Successivamente è stato affrontato anche il problema di come sonio implementate le
strutture dati nei IMDB attraverso non un approccio relazionale (tabelle)ma tramite i
puntatori e gli alberi .
Infine sono state affrontate alcune tecniche di ripristino per recuperare il sistema da
aventuali malfunzionamenti
Riferimenti
[1] http://www.mcobject.com/in_memory_database
[2] http://www.odbms.org/blog/2012/03/in-memory-database-systems-interviewwith-steve-graves-mcobject/
[3]A study of index for Main Memory Database Managment System di Lehman e
Micheal
[4]Recovery system for main memory database di Gupta Anaurg,Han Chen
[5]MMDB Micheal Lobert e Anders Pedersen
[6]Query processing in Main memory Database Management System
Ringraziamenti
Ringrazio tutti I professori con cui ho avuto il piacere di sostenere gli esami fino ad
oggi ,in particolare il prof . Picariello Antonio che mi ha dato anche il piacere di
sostenere un l’esame di basi dati con lui. Ringrazio la mia ragazza Monica che
veramente merita una statua per quello che ha fatto per me durante questi anni ,i miei
genitori che mi hanno dato la possibilità di realizzare questo sogno e infine tutti i miei
amici che mi sono stati accanto.
Grazie a Tutti
Maritato Luigi