After one more write, the segment could look like this:
The segment summary block points to where the next
segment summary block will be written. Either that block does not contain
a segment summary block (the format would not match) or it does contain a
segment summary block. If the latter is true, roll-forward must be able to
determine whether it was written before or after the last checkpoint. A simple
timestamp can be used to determine this.
It has a very serious impact on recovery - roll-forward cannot determine whether all of the segment pages were written or not. If they were not, then some of the disk pages will contain garbage. A simple technique to detect such cases is to include in the segment summary block a checksum of the pages in the segment. If the checksum doesn't match, then some pages were not written out.
void InsertNode (Node* first, last, new) {
Node *at = first;
while (at != NULL && at->key > new->key) at = at->next;
if (at == NULL) { // Insert as last node in list
new->prev = last;
new->next = NULL;
if (last == NULL) first = new;
else last->next = new;
last = new;
}
else { // Insert before at
new->prev = at->prev;
new->next = at;
if (at->prev == NULL) first = new;
else at->prev->next = new;
at->prev = new;
}
}
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define bufSize 8192
#define passes 5
char buf[bufSize];
int main (int argc, char **argv) {
int count, pass;
int nblocks;
int file;
int rstatus;
hrtime_t rt_elapsed[passes+1];
if (argc != 3) {
printf("Need file name and number of MB to read.\n");
exit(1);
}
nblocks = atoi(argv[2]);
if (nblocks <= 0) {
printf("%s is not an integer that is at least 1.\n", argv[2]);
exit(1);
}
nblocks = nblocks * 256;
file = open(argv[1], O_RDONLY);
if (file < 0) {
printf("Could not open file %s.\n", argv[1]);
exit(1);
}
printf("Reading first %s MB of %s.\n", argv[2], argv[1]);
pass = passes;
rt_elapsed[0] = gethrtime();
for (pass = 0; pass < passes; pass++) {
count = nblocks;
while (count-- > 0) {
rstatus = read(file, buf, bufSize);
if (rstatus < bufSize) {
printf("Read returned with status %d", rstatus);
exit(1);
}
}
rt_elapsed[pass+1] =gethrtime();
lseek(file, 0, SEEK_SET);
}
for (pass = passes; pass > 0; pass--)
rt_elapsed[pass] = rt_elapsed[pass] - rt_elapsed[pass-1];
for (pass = 1; pass <= passes; pass++)
printf("The average time to read a block in pass %d was %lld usec.\n",
pass, rt_elapsed[pass]/(1000*nblocks));
close(file);
exit(0);
}