Changeset: 86af0f9c98ea for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=86af0f9c98ea
Modified Files:
gdk/gdk_logger.c
Branch: default
Log Message:
Went through the logger with a fine(r) comb.
More (and hopefully better) error checking and recovery. When reading
the WAL, there are two types of error. See the comment in logger_readlog.
diffs (truncated from 705 to 300 lines):
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -99,13 +99,15 @@ typedef struct logformat_t {
lng nr;
} logformat;
+typedef enum {LOG_OK, LOG_EOF, LOG_ERR} log_return;
+
/* When reading an old format database, we may need to read the geom
* Well-known Binary (WKB) type differently. This variable is used to
* indicate that to the function wkbREAD during reading of the log. */
static int geomisoldversion;
static gdk_return bm_commit(logger *lg);
-static int tr_grow(trans *tr);
+static gdk_return tr_grow(trans *tr);
static BUN
log_find(BAT *b, BAT *d, int val)
@@ -193,7 +195,8 @@ log_read_string(logger *l)
buf = GDKmalloc(len);
if (buf == NULL) {
fprintf(stderr, "!ERROR: log_read_string: malloc failed\n");
- return NULL;
+ /* this is bad */
+ return (char *) -1;
}
if ((nr = mnstr_read(l->log, buf, 1, len)) != (ssize_t) len) {
@@ -221,17 +224,18 @@ log_write_string(logger *l, const char *
return GDK_SUCCEED;
}
-static void
+static log_return
log_read_clear(logger *lg, trans *tr, char *name)
{
if (lg->debug & 1)
fprintf(stderr, "#logger found log_read_clear %s\n", name);
-
- if (tr_grow(tr)) {
- tr->changes[tr->nr].type = LOG_CLEAR;
- tr->changes[tr->nr].name = GDKstrdup(name);
- tr->nr++;
- }
+ if (tr_grow(tr) != GDK_SUCCEED)
+ return LOG_ERR;
+ tr->changes[tr->nr].type = LOG_CLEAR;
+ if ((tr->changes[tr->nr].name = GDKstrdup(name)) == NULL)
+ return LOG_ERR;
+ tr->nr++;
+ return LOG_OK;
}
static int
@@ -274,7 +278,7 @@ la_bat_clear(logger *lg, logaction *la)
return GDK_SUCCEED;
}
-static gdk_return
+static log_return
log_read_seq(logger *lg, logformat *l)
{
int seq = (int) l->nr;
@@ -284,32 +288,32 @@ log_read_seq(logger *lg, logformat *l)
assert(l->nr <= (lng) INT_MAX);
if (mnstr_readLng(lg->log, &val) != 1) {
fprintf(stderr, "!ERROR: log_read_seq: read failed\n");
- return GDK_FAIL;
+ return LOG_EOF;
}
if ((p = log_find(lg->seqs_id, lg->dseqs, seq)) != BUN_NONE &&
p >= lg->seqs_id->batInserted) {
if (BUNinplace(lg->seqs_val, p, &val, FALSE) != GDK_SUCCEED)
- return GDK_FAIL;
+ return LOG_ERR;
} else {
if (p != BUN_NONE) {
oid pos = p;
if (BUNappend(lg->dseqs, &pos, FALSE) != GDK_SUCCEED)
- return GDK_FAIL;
+ return LOG_ERR;
}
if (BUNappend(lg->seqs_id, &seq, FALSE) != GDK_SUCCEED ||
BUNappend(lg->seqs_val, &val, FALSE) != GDK_SUCCEED)
- return GDK_FAIL;
+ return LOG_ERR;
}
- return GDK_SUCCEED;
+ return LOG_OK;
}
-static gdk_return
+static log_return
log_read_updates(logger *lg, trans *tr, logformat *l, char *name)
{
log_bid bid = logger_find_bat(lg, name);
BAT *b = BATdescriptor(bid);
- gdk_return res = GDK_SUCCEED;
+ log_return res = LOG_OK;
int ht = -1, tt = -1, tseq = 0;
if (lg->debug & 1)
@@ -353,50 +357,60 @@ log_read_updates(logger *lg, trans *tr,
if (l->flag == LOG_UPDATE) {
uid = COLnew(0, ht, (BUN) l->nr, PERSISTENT);
if (uid == NULL)
- return GDK_FAIL;
+ return LOG_ERR;
} else {
assert(ht == TYPE_void);
}
r = COLnew(0, tt, (BUN) l->nr, PERSISTENT);
if (r == NULL) {
BBPreclaim(uid);
- return GDK_FAIL;
+ return LOG_ERR;
}
if (tseq)
BATtseqbase(r, 0);
if (ht == TYPE_void && l->flag == LOG_INSERT) {
- for (; res == GDK_SUCCEED && l->nr > 0; l->nr--) {
+ for (; res == LOG_OK && l->nr > 0; l->nr--) {
void *t = rt(tv, lg->log, 1);
if (t == NULL) {
- res = GDK_FAIL;
+ /* see if failure was due to
+ * malloc or something less
+ * serious (in the current
+ * context) */
+ if (strstr(GDKerrbuf, "alloc") == NULL)
+ res = LOG_EOF;
+ else
+ res = LOG_ERR;
break;
}
if (BUNappend(r, t, TRUE) != GDK_SUCCEED)
- res = GDK_FAIL;
+ res = LOG_ERR;
if (t != tv)
GDKfree(t);
}
} else {
void *(*rh) (ptr, stream *, size_t) = ht == TYPE_void ?
BATatoms[TYPE_oid].atomRead : BATatoms[ht].atomRead;
- // FIXME unchecked_malloc ATOMnil can return NULL
-
void *hv = ATOMnil(ht);
if (hv == NULL)
- res = GDK_FAIL;
+ res = LOG_ERR;
- for (; res == GDK_SUCCEED && l->nr > 0; l->nr--) {
+ for (; res == LOG_OK && l->nr > 0; l->nr--) {
void *h = rh(hv, lg->log, 1);
void *t = rt(tv, lg->log, 1);
- if (h == NULL || t == NULL)
- res = GDK_FAIL;
- else if (BUNappend(uid, h, TRUE) != GDK_SUCCEED
||
- BUNappend(r, t, TRUE) != GDK_SUCCEED)
- res = GDK_FAIL;
+ if (h == NULL)
+ res = LOG_EOF;
+ else if (t == NULL) {
+ if (strstr(GDKerrbuf, "malloc") == NULL)
+ res = LOG_EOF;
+ else
+ res = LOG_ERR;
+ } else if (BUNappend(uid, h, TRUE) !=
GDK_SUCCEED ||
+ BUNappend(r, t, TRUE) != GDK_SUCCEED)
+ res = LOG_ERR;
if (t != tv)
GDKfree(t);
}
@@ -406,19 +420,25 @@ log_read_updates(logger *lg, trans *tr,
GDKfree(tv);
logbat_destroy(b);
- if (res == GDK_SUCCEED && tr_grow(tr)) {
- tr->changes[tr->nr].type = l->flag;
- tr->changes[tr->nr].nr = l->nr;
- tr->changes[tr->nr].ht = ht;
- tr->changes[tr->nr].tt = tt;
- tr->changes[tr->nr].name = GDKstrdup(name);
- tr->changes[tr->nr].b = r;
- tr->changes[tr->nr].uid = uid;
- tr->nr++;
+ if (res == LOG_OK) {
+ if (tr_grow(tr) == GDK_SUCCEED) {
+ tr->changes[tr->nr].type = l->flag;
+ tr->changes[tr->nr].nr = l->nr;
+ tr->changes[tr->nr].ht = ht;
+ tr->changes[tr->nr].tt = tt;
+ if ((tr->changes[tr->nr].name =
GDKstrdup(name)) == NULL) {
+ return LOG_ERR;
+ }
+ tr->changes[tr->nr].b = r;
+ tr->changes[tr->nr].uid = uid;
+ tr->nr++;
+ } else {
+ res = LOG_ERR;
+ }
}
} else {
/* bat missing ERROR or ignore ? currently error. */
- res = GDK_FAIL;
+ res = LOG_ERR;
}
return res;
}
@@ -485,15 +505,17 @@ la_bat_updates(logger *lg, logaction *la
return GDK_SUCCEED;
}
-static void
+static log_return
log_read_destroy(logger *lg, trans *tr, char *name)
{
(void) lg;
- if (tr_grow(tr)) {
+ if (tr_grow(tr) == GDK_SUCCEED) {
tr->changes[tr->nr].type = LOG_DESTROY;
- tr->changes[tr->nr].name = GDKstrdup(name);
+ if ((tr->changes[tr->nr].name = GDKstrdup(name)) == NULL)
+ return LOG_ERR;
tr->nr++;
}
+ return LOG_OK;
}
static gdk_return
@@ -524,62 +546,64 @@ la_bat_destroy(logger *lg, logaction *la
return GDK_SUCCEED;
}
-static gdk_return
+static log_return
log_read_create(logger *lg, trans *tr, char *name)
{
char *buf = log_read_string(lg);
+ int ht, tt;
+ char *ha, *ta;
+
if (lg->debug & 1)
fprintf(stderr, "#log_read_create %s\n", name);
- if (!buf) {
- return GDK_FAIL;
+ if (buf == NULL)
+ return LOG_EOF;
+ if (buf == (char *) -1)
+ return LOG_ERR;
+ ha = buf;
+ ta = strchr(buf, ',');
+ if (ta == NULL) {
+ fprintf(stderr, "!ERROR: log_read_create: inconsistent data
read\n");
+ return LOG_ERR;
+ }
+ *ta++ = 0; /* skip over , */
+ if (strcmp(ha, "wrd") == 0) {
+#if SIZEOF_SSIZE_T == SIZEOF_INT
+ ha = "int";
+#else
+ ha = "lng";
+#endif
+ }
+ if (strcmp(ha, "vid") == 0) {
+ ht = -1;
} else {
- int ht, tt;
- char *ha = buf, *ta = strchr(buf, ',');
+ ht = ATOMindex(ha);
+ }
+ if (strcmp(ta, "wrd") == 0) {
+#if SIZEOF_SSIZE_T == SIZEOF_INT
+ ta = "int";
+#else
+ ta = "lng";
+#endif
+ }
+ if (strcmp(ta, "vid") == 0) {
+ tt = -1;
+ } else {
+ tt = ATOMindex(ta);
+ }
+ GDKfree(buf);
+ if (tr_grow(tr) == GDK_SUCCEED) {
+ tr->changes[tr->nr].type = LOG_CREATE;
+ tr->changes[tr->nr].ht = ht;
+ tr->changes[tr->nr].tt = tt;
+ if ((tr->changes[tr->nr].name = GDKstrdup(name)) == NULL)
+ return LOG_ERR;
+ tr->changes[tr->nr].b = NULL;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list