Capitolo 6 Esercizio 6.1 Si consideri la base dati: PRODUZIONE (NumeroSerie, TipoParte, Modello, Qta, Macchina) PRELIEVO (NumeroSerie, Lotto, Cliente, Venditore, Ammontare) CLIENTE (Nome, Città Indirizzo) VENDITORE (Nome, Città Indirizzo) Progettare la frammentazione orizzontale delle tabelle PRODUZIONE e PRELIEVO in base al tipo di parte (che assume quattro valori: Tastiera, Schermo, CPU e Cablaggio ), prevedendo quattro stabilimenti di produzione disposti a Milano, Torino, Roma e Napoli, e delle tabelle CLIENTE e VENDITORE in base a tre bacini di vendita, centrati su Torino, Milano e Roma; si supponga che le vendite siano distribuite per bacini geografici (quindi, clienti di Milano sono serviti solo da venditori di Milano; si assuma che il bacino di vendita di Roma comprenda anche Napoli) e che ciascuna area geografica abbia una propria base di dati (cioè che sia disponibile una base di dati a Milano, Torino, Roma e Napoli). Esprimere a livello di trasparenza di frammentazione, di allocazione e di linguaggio le interrogazioni: 1. Determinare la quantità disponibile del prodotto 77Y6878 2. Determinare i clienti che hanno comprato qualche lotto dal rivenditore Bianchi, che ha ufficio a Roma. 3. Determinare le macchine utilizzate per la produzione dei pezzi di tipo Tastiera venduti al cliente Rossi. 4. Modificare l indirizzo del cliente Rossi, che si trasferisce da Via Po 45 di Milano a Viale Trastevere 150 di Roma 5. Calcolare la somma degli importi degli ordini ricevuti a Milano, Torino e Roma (si noti che anche le funzioni aggregate sono disponibili) Inventare poi, ipotizzando di usare il DBMS di Milano, una richiesta remota, una transazione remota, una transazione distribuita e una richiesta distribuita. Frammentazione orizzontale della tabella PRODUZIONE (4 tabelle) PRODUZIONE _1 = σ TipoParte= Tastiera (PRODUZIONE) PRODUZIONE _2= σ TipoParte= Schermo (PRODUZIONE) PRODUZIONE _3= σ TipoParte= CPU (PRODUZIONE) PRODUZIONE _4= σ TipoParte= Cablaggio (PRODUZIONE) Frammentazione orizzontale della tabella PRELIEVO (4 tabelle) PRELIEVO_1= Π NumeroSerie, Lotto, Cliente, Venditore, Ammontare (σ TipoParte= Tastiera (PRELIEVO NumeroSerie = SN SN NumeroSerie (PRODUZIONE)))
PRELIEVO_2= Π NumeroSerie, Lotto, Cliente, Venditore, Ammontare (σ TipoParte= Schermo (PRELIEVO NumeroSerie = SN SN NumeroSerie (PRODUZIONE))) PRELIEVO_3= Π NumeroSerie, Lotto, Cliente, Venditore, Ammontare (σ TipoParte= CPU (PRELIEVO NumeroSerie = SN SN NumeroSerie (PRODUZIONE))) PRELIEVO_4= Π NumeroSerie, Lotto, Cliente, Venditore, Ammontare (σ TipoParte= Cablaggio (PRELIEVO NumeroSerie = SN SN NumeroSerie (PRODUZIONE))) Frammentazione orizzontale della tabella CLIENTE (3 tabelle) CLIENTE_1= σ Città = Torino (CLIENTE) CLIENTE_2= σ Città = Milano (CLIENTE) CLIENTE_3= σ Città = Roma V Città = Napoli (CLIENTE) Frammentazione orizzontale della tabella VENDITORE VENDITORE_1= σ Città = Torino (VENDITORE) VENDITORE _2= σ Città = Milano (VENDITORE) VENDITORE _3= σ Città = Roma V Città = Napoli (VENDITORE) Le tabelle PRODUZIONE_1, PRELIEVO_1, CLIENTE_1, VENDITORE_1 potranno essere allocate a Torino (Torino.Azienda.it) Le tabelle PRODUZIONE_2, PRELIEVO_2, CLIENTE_2, VENDITORE_2 potranno essere allocate a Milano (Milano.Azienda.it) Le tabelle PRODUZIONE_3, PRELIEVO_3, CLIENTE_3, VENDITORE_3 potranno essere allocate a Roma (Roma.Azienda.it) Le tabelle PRODUZIONE_4, PRELIEVO_4 potranno essere allocate a Napoli (Napoli.Azienda.it) Punto 1: Trasparenza di frammentazione: Procedure QueryDispo1 ( :Quan) from PRODUZIONE
Trasparenza di allocazione: Procedure QueryDispo2 ( :Quan) from PRODUZIONE_1 from PRODUZIONE_2 from PRODUZIONE_3 from PRODUZIONE_4 Trasparenza di linguaggio: Procedure QueryDispo3 ( :Quan) from PRODUZIONE_1@Torino.Azienda.it from PRODUZIONE_2@Milano.Azienda.it from PRODUZIONE_3@Roma.Azienda.it from PRODUZIONE_4@Napoli.Azienda.it Punto 2: Trasparenza di frammentazione: Procedure QueryLotto1 ( :Cl) from PRELIEVO
Trasparenza di allocazione: Procedure QueryLotto2 ( :Cl) from PRELIEVO_1 from PRELIEVO_2 from PRELIEVO_3 from PRELIEVO_4 Trasparenza di linguaggio: Procedure QueryLotto3 ( :Cl) from PRELIEVO_1@Torino.Azienda.it from PRELIEVO_2@Milano.Azienda.it from PRELIEVO_3@Roma.Azienda.it from PRELIEVO_4@Napoli.Azienda.it Punto 3: Trasparenza di frammentazione: Procedure QueryMacchinePerTastiere1 ( :mac) select Macchine into :mac from PRODUZIONE join PRELIEVO On PRODUZIONE.NumeroSerie = PRELIEVO.NumeroSerie where Cliente = Rossi and TipoParte = Tastiera
Trasparenza di allocazione: Procedure QueryMacchinePerTastiere2 ( :mac) select Macchine into :mac from PRODUZIONE_1 join PRELIEVO_1 On PRODUZIONE_1.NumeroSerie = PRELIEVO_1.NumeroSerie where Cliente = Rossi Trasparenza di linguaggio: Procedure QueryMacchinePerTastiere3 ( :mac) select Macchine into :mac from PRODUZIONE_1@Torino.Azienda.it join PRELIEVO_1@Torino.Azienda.it On PRODUZIONE_1.NumeroSerie = PRELIEVO_1.NumeroSerie where Cliente = Rossi Punto 4: Trasparenza di frammentazione: Procedure ModificaIndirizzo1 update CLIENTE set Indirizzo= Via Po 45, Città= Milano where Nome = Rossi Trasparenza di allocazione: Procedure ModificaIndirizzo2 delete from CLIENTE_3 where Nome = Rossi ; insert into CLIENTE_2 (Nome, Indirizzo, Città) values ( Rossi, Via Po 45, Milano ) Trasparenza di linguaggio: Procedure ModificaIndirizzo2 delete from CLIENTE_3@Roma.Azienda.it where Nome = Rossi ; insert into CLIENTE_2@Milano.Azienda.it (Nome, Indirizzo, Città) values ( Rossi, Via Po 45, Milano )
Punto 5: Trasparenza di frammentazione: Procedure Ordini1 select Citta, sum(ammontare) from PRELIEVO join VENDITORE on Venditore = Nome group by Città Trasparenza di allocazione: Procedure Ordini2 create view PRELIEVO as PRELIEVO_1 union PRELIEVO_2 union PRELIEVO_3 union PRELIEVO_4 select Citta, sum(ammontare) from PRELIEVO join VENDITORE_1 on Venditore = Nome group by Città union select Citta, sum(ammontare) from PRELIEVO join VENDITORE_2 on Venditore = Nome group by Città union select Citta, sum(ammontare) from PRELIEVO join VENDITORE_3 on Venditore = Nome group by Città Trasparenza di linguaggio: Procedure Ordini2 create view PRELIEVO as PRELIEVO_1@Torino.Azienda.it union PRELIEVO_2@Milano.Azienda.it union PRELIEVO_3@Roma.Azienda.it union PRELIEVO_4@Napoli.Azienda.it select Citta, sum(ammontare) from PRELIEVO join VENDITORE_1@Torino.Azienda.it on Venditore = Nome group by Città union select Citta, sum(ammontare) from PRELIEVO join VENDITORE_2@ Milano.Azienda.it on Venditore = Nome group by Città union select Citta, sum(ammontare) from PRELIEVO join VENDITORE_3@Roma.Azienda.it on Venditore = Nome
group by Città Richiesta Remota select * from PRODUZIONE_2 where Qta > 100 Transazione Remota update CLIENTE_2 set Indirizzo = Via Fogazzaro 11 where Nome = Verdi Transazione Distribuita delete from CLIENTE_2 where Nome = Bianchi insert into CLIENTE_1 (Nome, Indirizzo, Città) values ( Bianchi, Via Ponente 45, Milano ) Richiesta Distribuita select Nome from PRELIEVO_1 join CLIENTE_3 on Cliente = Nome where NumeroSerie = 458X411 Esercizio 6.2 Assegnare i timestamp agli eventi descritti in figura 3.20 con il metodo di Lamport, e indicare quali eventi sono pseudo-simultanei, cioè sono eventi che non possono essere ordinati in base ai messaggi scambiati. Figura 6.20
I timestamp sono indicati nella seguente figura. Gli eventi pseudo-simultanei sono: 1.1, 1.2 e 1.3 1.1 e 2.2 2.1 e 3.2 5.1 e 5.2 3.2 e 4.3 7.2 e 8.3 Esercizio 6.3 Date le condizioni di attesa illustrate in figura 3.21, determinare con l algoritmo di ricerca distribuita le condizioni di deadlock, con due diverse ipotesi di condizione di attesa relative al nodo 4. DBMS1 t 1 t 5 t 6 E4 E4 E2 DBMS2 t 3 t 2 t 5 E1 E3 DBMS3 t 4 E4 t 2 E2 DBMS4, versione 1 t 6 t 4 t 1 E1 E1 E3 DBMS4, versione 2 t 4 t 1 t 6 E3 E1 E1 Figura 6.21
Prima versione: In questa situazione, le condizioni di attesa del sistema sono: 1) E4 t 1 t 6 E4 E2 t 5 t 6 E4 2) E3 t 2 t 5 E1 4) E1 t 6 t 1 E1 E3 t 4 t 1 E1 Supponendo di inviare le sole condizioni di attesa E in t i t j E out dove i>j, il DBMS4 spedisce le sue condizioni di attesa al DBMS1 che scopre il deadlock. DBMS1 t 4 t 1 t 5 E2 E3 E4 t 6 E4 Il deadlock coinvolge le transazioni < t 1, t 5, t 6 > e per risolverlo si dovrà eseguire il rollback su una di esse. Seconda versione: In questa situazione, le condizioni di attesa del sistema sono: 1) E4 t 1 t 6 E4 E2 t 5 t 6 E4 2) E3 t 2 t 5 E1 Supponendo di inviare le sole condizioni di attesa E in t i t j E out dove i>j, nessun DBMS invia le proprie condizioni di attesa. Non ci sono deadlock.
Esercizio 6.4 Descrivere come si modifica il protocollo di ripresa a caldo tendo presente che alcune sottotransazioni distribuite possono essere in stato di ready. Protocollo di ripresa a caldo in sistemi distribuiti: 1) Si accede all ultimo blocco del log e si ripercorre il log all indietro fino al record di checkpoint. Si costruiscono 3 insiemi, detti di UNDO, di REDO e di READY. Gli insiemi REDO e READY sono vuoti, mentre quello di UNDO contiene le transazioni indicare nel record di checkpoint. 2) Si ripercorre il log in avanti, aggiungendo all insieme di UNDO tutte le transazioni di cui è presente il record di begin. Se viene rilevato un record ready, la corrispondente transazione viene spostata in READY. Se viene trovato un record di commit si sposta la transazione corrispondente nell insieme di REDO (viene rimossa da READY o da UNDO). Se si trova un record abort e la transazione corrispondente si trova in READY, essa viene tolta da READY e messa in UNDO. 3) Se l insieme READY non è vuoto, il sistema deve chiedere al TM (Transaction Manager) l esito delle transazioni di questo insieme, che si trovano in uno stato incerto. Il TM indica quali transazioni hanno effettuato il commit e quali l abort. Queste transazioni saranno quindi trasferite negli insiemi di REDO o di UNDO e i rispettivi record scritti nel log. 4) Il protocollo continua come in un sistema non distribuito. Esercizio 6.5 Applicare il protocollo di ripresa a caldo dopo la caduta di un nodo assumendo un algoritmo di commit a due fasi, a fronte del seguente input (ove r(t i ) indica la presenza del record di ready): B(T 1 ), B(T 2 ), B(T 3 ), I(T 1,O 1,A 1 ), D(T 2,O 2,B 2 ), B(T 4 ), R(T 1 ), U(T 4,O 3,B 3,A 3 ), C(T 1 ), CK(T 2,T 3,T 4 ), B(T 5 ), B(T 6 ), U(T 5,O 5,B 5,A 5 ), R(T 5 ), B(T 7 ), U(T 7,O 6,B 6,A 6 ), B(T 8 ), U(T 6,O 1,B 7,A 7 ), A(T 7 ), R(T 6 ), guasto 1) Il log viene ripercorso all indietro sino al record di checkpoint CK(T 2,T 3,T 4 ) e si creano i tre insiemi di UNDO, REDO e READY. UNDO = { T 2,T 3,T 4 } REDO = {} READY = {} 2) Il record viene percorso in avanti, aggiornandogli insiemi. B(T 5 ) UNDO = { T 2,T 3,T 4,T 5 } REDO = {} READY = {} B(T 6 ) UNDO = { T 2,T 3,T 4,T 5,T 6 } REDO = {} READY = {} R(T 5 ) UNDO = { T 2,T 3,T 4,T 6 } REDO = {} READY = {T 5 } B(T 7 ) UNDO = { T 2,T 3,T 4,T 6,T 7 } REDO = {} READY = {T 5 }
B(T 8 ) UNDO = { T 2,T 3,T 4,T 6,T 7,T 8 } REDO = {} READY = {T 5 } A(T 7 ) UNDO = { T 2,T 3,T 4,T 6,T 7,T 8 } REDO = {} READY = {T 5 } R(T 6 ) UNDO = { T 2,T 3,T 4 T 7,T 8 } REDO = {} READY = {T 5,T 6 } 3) A questo punto dovremmo chiedere al Transaction Manager l esito delle transazioni in stato di READY. Supponendo che il TM indichi un global commit per T 5 e T 6 otteniamo: UNDO = { T 2,T 3,T 4 T 7,T 8 } REDO = {T 5,T 6 } I record C(T 5 ) e C(T 6 ) sono scritti nel log. 4) Il record viene ripercorso all indietro sino a D(T 2,O 2,B 2 ), eseguendo le operazioni di UNDO. O 6 = B 6 O 3 = B 3 Insert O 2 = B 2 5) Infine il log viene percorso in avanti e vengono eseguite le operazioni di REDO. O 5 = A 5 O 1 = A 7 Esercizio 6.6 Applicare il protocollo di ripresa a caldo dopo la caduta di un nodo assumendo un algoritmo di commit a tre fasi, a fronte del seguente input (ove PC(T i ) indica la presenza di un record di precommit): B(T 1 ), B(T 2 ), B(T 3 ), I(T 1,O 1,A 1 ), D(T 2,O 2,B 2 ), B(T 4 ), R(T 1 ), U(T 4,O 3,B 3,A 3 ), PC(T 1 ), C(T 1 ), CK(T 2,T 3,T 4 ), B(T 5 ), B(T 6 ), U(T 5,O 5,B 5,A 5 ), R(T 5 ), B(T 7 ), U(T 7,O 6,B 6,A 6 ), U(T 6,O 3,B 7,A 7 ), B(T 8 ), PC(T 5 ), A(T 7 ), R(T 6 ), guasto. Soluzione : 1) Come negli altri protocolli di ripresa a caldo per prima cosa si ripercorre all indietro il log sino a record di checkpoint, in questo caso CK(T 2,T 3,T 4 ). Vengono creati 4 insiemi: UNDO, REDO, READY e PRE-COMMIT: L insieme UNDO contiene le transazioni indicate dal record di checkpoint, mentre gli altri insiemi sono vuoti. UNDO = {T 2,T 3,T 4 } REDO = {} READY = {} PRE-COMIT = {} 2) Il log viene percorso in avanti. Se si trova in record di commit la transazione viene messa nell insieme REDO. Se si incontra un abort la transazione viene posta nell insieme UNDO. Se si trova il record ready la transazione va in READY. Infine, se si trova l insieme pre-commit, la transazione viene messa nell insieme PRE- COMMIT. B(T 5 ) UNDO = {T 2,T 3,T 4,T 5 } REDO = {} READY = {} PRE-COMIT = {} B(T 6 ) UNDO = {T 2,T 3,T 4,T 5,T 6 } REDO = {} READY = {} PRE-COMIT = {}
R(T 5 ) UNDO = {T 2,T 3,T 4,T 6 } REDO = {} READY = {T 5 } PRE-COMIT = {} B(T 7 ) UNDO = {T 2,T 3,T 4,T 6,T 7 } REDO = {} READY = {T 5 } PRE-COMIT = {} B(T 8 ) UNDO = {T 2,T 3,T 4,T 6,T 7,T 8 } REDO = {} READY = {T 5 } PRE-COMIT = {} PC(T 5 ) UNDO = {T 2,T 3,T 4,T 6,T 7,T 8 } REDO = {} READY = {} PRE-COMIT = {T 5 } A(T 7 ) UNDO = {T 2,T 3,T 4,T 6,T 7,T 8 } REDO = {} READY = {} PRE-COMIT = {T 5 } R(T 6 ) UNDO = {T 2,T 3,T 4,T 7,T 8 } REDO = {} READY = {T 6 } PRE-COMIT = {T 5 } 3) Il sistema deve consultare il TM per conoscere l esito delle transazioni negli insiemi di READY e PRE-COMMIT. Per ogni transazione nell insieme PRE-COMMIT il TM può rispondere con commit, abort o ancora con pre-commit; nei primi due casi le transazioni vengono messe nei rispettivi insiemi, altrimenti il sistema può riprendere il protocollo a tre fasi, 3PC. Per ogni transazione nell insieme READY il sistema può rispondere ancosa con commit, abort o pre-commit. In caso di pre-commit la transazione viene collocata nell insieme PRE-COMMIT e il protocollo 3PC ripreso. 4) Quando l esito di ogni transazione è conosciuto, il protocollo di ripresa a caldo continua con le operazioni di undo e redo. Se il coordinatore non risponde entro un tempo specifico il sistema fa partire il CFP (Coordinator Failure Protocol), ovvero si elegge un nuovo TM ed esso decide l esito delle transazioni in dubbio. Esercizio 6.7 Dato un sistema distribuito con 8 nodi, assegnare un quorum necessario per decidere commit e un quorum necessario per decidere abort in modo da massimizzare la probabilità di raggiungere una decisione di commit qualora vi siano 4 partizioni con 2 nodi ciascuna. Questo caso può verificarsi quando viene utilizzato un protocollo di commit a 3 fasi. Quando avviene il partizionamento della rete ogni partizione continua per conto proprio l esecuzione del protocollo. Alla ripresa delle trasmissioni di rete il TM chiede agli RM e agli RM che erano stati eletti TM l esito delle transazioni e in base ai quorum predefiniti prende una decisione globale. Per il commit il quorum deve essere pari a 2, mentre per l abort il quorum è pari a 7, che è stato calcolato un base al numero di nodi più uno meno il quorum di commit, in modo tale da non avere conflitti. Esercizio 6.8 Descrivere uno schema di esecuzione delle seguenti interrogazioni che massimizzino il parallelismo inter-query: 1. Estrarre la somma della quantità delle produzioni, raggruppate in base a tipo e modello delle parti. 2. Estrarre la media delle parti vendute dai venditori, raggruppate in base a tipo e modello delle parti.
Nell esercizio 6.1 si effettuava una frammentazione orizzontale sulle tabelle PRODUZIONE e PRELIEVO in base ai differenti valori di TipoParte. 1) In accordo con questa frammentazione, la prima query può essere eseguita con 4 differenti query, ognuna delle quali è applicata a una delle tabelle PRODUZIONE_1, PRODUZIONE_2, PRODUZIONE_3, PRODUZIONE_4. select sum(qta), Modello, TipoParte from PRODUZIONE_1 gruop by Modello, TipoParte select sum(qta), Modello, TipoParte from PRODUZIONE_2 gruop by Modello, TipoParte select sum(qta), Modello, TipoParte from PRODUZIONE_3 gruop by Modello, TipoParte select sum(qta), Modello, TipoParte from PRODUZIONE_4 gruop by Modello, TipoParte Si noti che ogni tabella contiene un solo valore in TipoParte. 2) Sullo stesso schema la query può essere: select avg(ammontare), Modello, TipoParte from PRELIEVO_1 join PRODUZIONE_1 on PRELIEVO_1.NumeroSerie = PRODUZIONE_1.NumeroSerie group by Modello, TipoParte select avg(ammontare), Modello, TipoParte from PRELIEVO_2 join PRODUZIONE_2 on PRELIEVO_2.NumeroSerie = PRODUZIONE_2.NumeroSerie group by Modello, TipoParte select avg(ammontare), Modello, TipoParte from PRELIEVO_3 join PRODUZIONE_3 on PRELIEVO_3.NumeroSerie = PRODUZIONE_3.NumeroSerie group by Modello, TipoParte select avg(ammontare), Modello, TipoParte from PRELIEVO_4 join PRODUZIONE_4 on PRELIEVO_4.NumeroSerie = PRODUZIONE_4.NumeroSerie group by Modello, TipoParte
Nella situazione descritta nell esercizio 6.1, ogni query potrà essere eseguita su un differente DBMS. Per massimizzare il parallelismo inter-query, ogni query potrebbe essere ulteriormente frammentata in accordo con i diversi valori dell attributo Modello. Esercizio 6.9 Descrivere un esempio di comportamento di base di dati replicata in cui si verifichi un disallineamento fra i dati. Riferendoci allo schema del database descritto nell esercizio 3.1, supponiamo che ogni frammento della tabella PRODUZIONE sia allocato su tutti DBMS. Ogni DBMS usa solo un nodo e spedisce tutte le modifiche sul suo frammento agli altri DBMS. In questo modo ogni ha una copia dell intero database. In caso di guasto su un DBMS il database è ancora completamente accessibile dagli altri sistemi. Se tutte le query vengono correttamente reindirizzate, il guasto è trasparente al Client della base dati. Comunque, se si verifica un guasto nella rete, questo può generare un partizionamento della rete, per esempio con due sottoreti. In questa situazione si può verificare un disallineamento dei dati. Ad esempio, supponendo che la tabella PRODUZIONE contenga la seguente tupla: NumeroSerie TipoParte Modello Qta Macchina 12345 CPU Pentium IV 1000 A Se due transazioni vogliono entrambe prelevare 800 pezzi dall attributo quantità, una delle due transazioni non terminerà correttamente (in genere quella arrivata dopo); ma se le due transazioni si presentano su due DBMS che non sono connessi (come nel caso di partizionamento della rete), nessuna delle due fallirà e i dati contenuti nel database saranno disallineati e quindi inconsistenti. Esercizio 6.10 Descrivere un esempio di comportamento di base di dati con replicazione simmetrica in cui si verifichi una inconsistenza dei dati. Nella replicazione simmetrica ogni DBMS ha una copia dell intero database. Ogni modifica deve essere effettuata su qualunque copia e si ha quindi una situazione alla pari (peer to peer) fra le copie. Questa situazione può produrre gli stessi effetti di un unico DBMS senza il controllo di concorrenza. Le due transazioni descritte nell esercizio 6.9 producono un inconsistenza anche senza guasti sulla rete, se i cambiamenti non vengono comunicati immediatamente alle altre copie.