9.3.3
d) r1(A), r2(A), w1(B),w2(B), r1(B), r2(B), w2(C), w1(D)
l1(A), r1(A), u1(A), l2(A), r2(A), u2(A), l1(B), w1(B), l2(B) Denied, r1(B), u1(B),
l2(B), w2(B), r2(B), u2(B),l2(C), w2(C), u2(C), l1(D) w1(D), u1(D)
e) r1(A), r2(A), r1(B), r2(B), r3(A),r4(B),w1(A),w2(B)
l1(A), r1(A), l2(A) Denied, l1(B), r1(B), u1(B), l3(A) Denied, l4(B) r4(B) u4(B), w1(A), u1(A), l2(A), r2(A), u2(A), l2(B), r2(B), l3(A), r3(A), u3(A), w2(B), u2(B)
9.4.1
Note: Almost everyone tried to interpret the schedules as static events—i.e. you tried to assign the locks regardless of the scheduler’s runtime behavior. This is not possible, as a schedule, by definition, is a run-time occurrence (statically, you have a bunch of transactions)
b) r1(A), r2(B),r3(C),w1(B),w2(C),w3(A)
s1(A), r1(A), s2(B), r2(B), s3(C), r3(C), x1(B) Denied, x2(C) Denied, x3(A) Denied
e) r1(A), r2(B), r3(C), r1(B), r2(C), r3(A), w1(A), w2(B), w3(C)
x1(A), r1(A), x2(B), r2(B), x3(C), r3(C), s1(B) Denied, s2(C)
Denied, s3(A) Denied
9.4.6
b)
|
X |
Y |
Angle |
Magnitude |
X |
No |
Yes |
No |
No |
Y |
yes |
No |
No |
No |
Angle |
No |
No |
No |
yes |
Magnitude |
No |
No |
yes |
No |
c)
|
X |
Y |
Angle |
Magnitude |
X |
yes |
Yes |
No |
No |
Y |
yes |
yes |
No |
No |
Angle |
No |
No |
yes |
yes |
Magnitude |
No |
No |
yes |
yes |
10.1.2
d) r2(A), r3(A), r1(A), w1(B), r3(B), w2(C), r3(C)
T1 has to be rolled back.
T3 has to be rolled back as it read an incorrect value. No other transactions are affected.
10.3.1
r1(A), r2(B), w1(C), w2(D), r3(C), w1(B), w4(D), w2(A)
T1 |
T2 |
T3 |
T4 |
Graph |
s1(A) r1(A) x1(C) w1(C) x1(B) Denied |
s2(B) r2(B) x2(D) w2(D) x2(A) Denied |
s3(C) Denied |
x4(D) Denied |
T3ŕT1 T1ŕT2 T4ŕT2 T2ŕT1 |
Abort T1. Locks on A and C are reliesed.
T1 |
T2 |
T3 |
T4 |
Graph |
s1(A) r1(A) x1(C) w1(C) x1(B) Denied ABORT Restart T1 |
s2(B) r2(B) x2(D) w2(D) x2(A) Denied x2(A), w2(A), u2(A),u2(D),u2(B) |
s3(C) Denied s3(C) r3(C) u3(C) |
x4(D) Denied x4(D), w4(D), u4(D) |
T3ŕT1 T1ŕT2 T4ŕT2 T2ŕT1 |
8.2.7
d)
<START S>
<S,A,60>
<COMMIT S>
<START T>
<T,A,10>
<START U>
<U,B,20>
<T,C,30>
<START V>
<U,D,40>
<START CKPT(U,V,T)>
<V,F,70>
<COMMIT U>
<T,E,50>
<COMMIT T>
<V,B,80>
<COMMIT V>
ii) Crash can occur before the <END CKPT> since with undo logging <end ckpt> will come after the <commit v>. We need to scan back to the starting point of the earliest of U,V and T, which is <START T> if crash occurs prior to <COMMIT T> or back to <START V> if crash occurs after <COMMIT T>
(we only undo transactions for which we haven’t seen a commit, depending on where the crash occurred)
e)
<START S>
<S,A,60>
<COMMIT S>
<START T>
<T,A,10>
<START U>
<U,B,20>
<T,C,30>
<START V>
<U,D,40>
<V,F,70>
<COMMIT U>
<T,E,50>
<START CHKPT(V,T)>
<COMMIT T>
<V,B,80>
<COMMIT V>
ii). Again, the <END CKPT> belongs after the commit, so a crash would occur before the <END CKPT>. We need to scan back to at most <START T>
8.4.5
<START S>
<S,A,60,61>
<COMMIT S>
<START T>
<T,A,61,62>
<START U>
<U,B,20,21>
<T,C,30,31>
<START V>
<U,D,40,41>
<START CKPT(U,V,T)>
<V,F,70,71>
<COMMIT U>
<T,E,50,51>
<COMMIT T>
<V,B,21,22>
<END CKPT>
<COMMIT V>
d)
(i) <END CKPT> can be written any time after the <START CKPT>
(ii)Active transactions are U,V,T. Hence the start
checkpoint record has
the form <START CKPOINT(U,V,T)>. Assume crash happens after <END
CKPOINT>
has been written. The possible subcases are:
[A] Crash happened before <COMMIT U>: need to undo effect of U,V, and T.
Hence, we need to go back to the earliest record involving U,V, or T. This
will be <START T>.
[B} Crash happens after <COMMIT U> but before <COMMIT T>: need to
undo
effect of V and T and redo actions (after CKPOINT) of U. Thus, we need to go
back to <START T>.
[C} Crash happens after <COMMIT T> but before <COMMIT V>: need to
undo
effect of only V and redo actions (after CKPOINT) of T and U. Therefore,
need to go back to <START V>.
[D} Crash happens after <COMMIT V>: No undo needed. We need to only redo
steps. Hence, we need to go back to <START CKPOINT(U,V,T)>
If crash happens before <END CKPOINT>, then we will need to go back all
the
way to the start of the previous checkpoint or the beginning of the log
whichever is later. In this case, that will be <START S>.
e)
i) <END CKPT> can be written any time after the <START CKPT>
ii) Active transactions are T and V. Hence the checkpoint record
written is <START CKPOINT(V,T)>. Using the same line of reasoning as
above,
when the crash happens after <END CKPOINT>, the possible scenarios are
[B},
[C] and [D] (although start checkpoint looks like <START CKPOINT (V,T)>.
If
crash happens before <END CKPOINT>, then we need to go back to <START
S> as
in the previous case.
[Comment: Note that in undo/redo
logging, flushing dirty pages to disk can
follow independently as long as Rule UR1 in Page 452 is followed. Read also
Example 8.13 carefully to understand the above solution]
3.4.4
Assumptions:
A test takes 40 bytes: 10 bytes for the name, 8 bytes for the date, and a result field of 22 bytes , stored with probability p. A test contains an average of n results.
p% of the time, a record will hold results of size 22n, (1-p)%, the size will be 0.
We only need one pointer per record.
4+22np
4.1.5
The data file is sequential, sorted on the index attribute (assume primary index).
To acess data: retrieve the first block that holds a record with the correct key and scan sequentially
I/O to retrieve data:
(for a, b and c)
In 1/3 of the cases, we will do just 1 I/O. We will need a second I/O in 1/3 of the cases, with a probability of 1/3. A third I/O in 1/3 of the cases, with probability of 2/3.
ŕ Data: 1+(1/3)*(1/3)+(1/3)*(2/3)=1.33 I/Os
Retrieval of index blocks:
Perform a binary search on the index. Finding the correct value takes log B, where B is the number of blocks in the index file.
Assume x distinct values in the index file.
a) Records: x/3+2*x/3+3*x/3=2x.
For 2x records, we need 2x key/pointer pairs (as per problem specification)
Since a block holds 10 keys, we have 2*x/10 index blocks, i.e. log (x/5) I/O’s to retrieve the index.
b) Similar to a), but now we have 1 pointer per block, rather than per record. Each block has 3 records so we have 2x/3 data blocks and keys. Each index block holds 10 keys, so we have 2x/30 index blocks.
I/O cost is log (x/15)
Note: You might need an additional I/O for data retrieval as with sparse index you might need to fetch an extra block
c) I/O is same as b).
4.2.2
The file is not sequential any more. We assume that there are many distinct values that are well distributed over the file, i.e. no block holds 2 records with the same key.
Data I/O: 1/3+2*1/3+3*1/3=2 I/Os
Index: the index is a sequential file. Therefore, to get three values we need to fetch at most 2 blocks. 1/3 of the cases, 1 I/O, 1/3 of the cases, a second I/O with a probability of 1/10, in 1/3 of the cases, a third I/O with a probability of 2/10:
1+(1/3)*(1/10)+(1/3)*(2/10)=1.1 I/Os
Total: 3.1 I/Os