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

Reply via email to