Status of 64-bit TDB

ronnie sahlberg ronniesahlberg at gmail.com
Wed Jun 17 00:31:00 GMT 2009


Fragmentation of TDB databases is a big problem in CTDB.
For very busy systems it usually does not take that long until the databases
are so fragmented
they become very slow.

For this reason ctdb has a commandline utility "ctdb repack" that does this
kind defragmentation.

Please see the ctdb git tree : tools/ctdb_vacuum.c:ctdb_repack_tdb for an
example how this is done in CTDB.

Example code:


struct traverse_state {
    bool error;
    struct tdb_context *dest_db;
};

/*
  traverse function for repacking
 */
static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA
data, void *private)
{
    struct traverse_state *state = (struct traverse_state *)private;
    if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) {
        state->error = true;
        return -1;
    }
    return 0;
}

/*
  repack a tdb
 */
static int ctdb_repack_tdb(struct tdb_context *tdb)
{
    struct tdb_context *tmp_db;
    struct traverse_state state;

    if (tdb_transaction_start(tdb) != 0) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to start transaction\n"));
        return -1;
    }

    tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL,
O_RDWR|O_CREAT, 0);
    if (tmp_db == NULL) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to create tmp_db\n"));
        tdb_transaction_cancel(tdb);
        return -1;
    }
    state.error = false;
    state.dest_db = tmp_db;

    if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to traverse copying out\n"));
        tdb_transaction_cancel(tdb);
        tdb_close(tmp_db);
        return -1;
    }

    if (state.error) {
        DEBUG(DEBUG_ERR,(__location__ " Error during traversal\n"));
        tdb_transaction_cancel(tdb);
        tdb_close(tmp_db);
        return -1;
    }

    if (tdb_wipe_all(tdb) != 0) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to wipe database\n"));
        tdb_transaction_cancel(tdb);
        tdb_close(tmp_db);
        return -1;
    }

    state.error = false;
    state.dest_db = tdb;

    if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to traverse copying
back\n"));
        tdb_transaction_cancel(tdb);
        tdb_close(tmp_db);
        return -1;
    }

    if (state.error) {
        DEBUG(DEBUG_ERR,(__location__ " Error during second traversal\n"));
        tdb_transaction_cancel(tdb);
        tdb_close(tmp_db);
        return -1;
    }

    tdb_close(tmp_db);

    if (tdb_transaction_commit(tdb) != 0) {
        DEBUG(DEBUG_ERR,(__location__ " Failed to commit\n"));
        return -1;
    }

    return 0;
}






On Tue, Jun 16, 2009 at 11:35 PM, Volker Lendecke <Volker.Lendecke at sernet.de
> wrote:

> On Tue, Jun 16, 2009 at 09:21:36AM -0400, yaberger at ca.ibm.com wrote:
> > this might not be the solution for John's problem but I think a TDB
> > defragmenter/shrinker is something that is missing around TDBs.
> >
> > Currently, the only way to reduce the size of a TDB is to stop Samba and
> > delete the non-persistant TDBs.
>
> You can always do a tdbbackup of the persistent ones.
>
> > Has it been discussed in the past?
> > Is this something that makes sense and would be doable?
>
> Sure. It will need to be coded up very carefully though if
> it shall work while the tdb is in use.
>
> Volker
>


More information about the samba-technical mailing list