chuigda / mdb

Reimplemented APUE DB, with standard C library and binary storage format

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

(MDB) distinguish between recoverable and non-recoverable errors

chuigda opened this issue · comments

As is known before, there're two kinds of errors:

  strcpy(pathbuf, options.db_name);
  strcat(pathbuf, ".db.super");
  db->fp_superblock = fopen(pathbuf, "w");
  if (db->fp_superblock == NULL) {
    mdb_free(db);
    return mdb_status(MDB_ERR_OPEN_FILE,
                      "cannot open superblock file as write");
  }

The error above is recoverable. If one cannot fopen a database super file as write, there is exactly no loss. However, the following error, is non-recoverable

    mdb_ptr_t index_ptr;
    mdb_status_t index_alloc_status = mdb_index_alloc(db, &index_ptr);
    STAT_CHECK_RET(index_alloc_status, {;});
    mdb_ptr_t value_ptr;
    mdb_status_t data_alloc_status = mdb_data_alloc(db, value_size, &value_ptr);
    STAT_CHECK_RET(data_alloc_status, {
                     (void)mdb_index_free(db, index_ptr);
                   });
    mdb_status_t data_write_status = mdb_write_data(db, value_ptr, value,
                                                    value_size);
    STAT_CHECK_RET(data_write_status, {
                     (void)mdb_data_free(db, value_ptr, value_size);
                     (void)mdb_index_free(db, index_ptr);
                   });
    mdb_status_t index_write_status = mdb_write_index(db, index_ptr, key,
                                                      value_ptr, value_size);
    STAT_CHECK_RET(index_write_status, {
                     (void)mdb_data_free(db, value_ptr, value_size);
                     (void)mdb_index_free(db, index_ptr);
                   });
    mdb_status_t ptr_update_status = mdb_write_nextptr(db, save_ptr, index_ptr);
    STAT_CHECK_RET(ptr_update_status, {
                     (void)mdb_data_free(db, value_ptr, value_size);
                     (void)mdb_index_free(db, index_ptr);
                   });

There will be inconsistency in database files if any of the allocation/write step fails, and the corresponding rollback steps fails too.
It is really necessary to distinguish between recoverable and non-recoverable (critical) errors. A bitmask would be fine.