1 Reply Latest reply: Jun 5, 2012 10:05 AM by 941575 RSS

    TDS: Cleaning up after crash with open transactions

    941575
      I am evaluating TDS and have a pretty basic question. I have a test app that looks like this (error handling omitted).

      // main opens/creates the env, checks for 'exit' on the command line, and then calls WriteBTree
      void WriteBTree(DbEnv &env, bool exitSuddenly)
      {
        Db table(&env,0);
        int dbResult = table.open(0, "table1.db", 0, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0);

        DbTxn *txn = NULL;
        env.txn_begin(NULL, &txn, 0);

        char *data = "hello world";
        for(int i=0; i<100; ++i)
        {
          Dbt dbtKey(&key, sizeof(int));
          Dbt dbtData(data, strlen(data));
          dbResult = table.put(txn, &dbtKey, &dbtData, 0);
        }
        if(exitSuddenly)
        {
          cerr << "Exiting in middle of transaction" << endl ;
      exit(-1);
      }
      dbResult = txn->commit(0);
      // cleanup here
      }

      If I kill the app via the exit flag while a transaction is pending, the table remains locked. I can see this with db_stat. Later instances of the app hang waiting for the lock to clear. The hang occurs on the first put in the loop. Who or what will eventually remove this lock? How does my app clean up from this crash?

      I configure isalive and set_thread_id on the environment. I also configure 30 second transaction and lock timeouts. I open the env with these flags

      DB_CREATE | // If the environment does not exist, create it.
      DB_INIT_LOCK | // Initialize locking
      DB_INIT_LOG | // Initialize logging
      DB_INIT_MPOOL | // Initialize the cache
      DB_INIT_TXN | // Initialize transactions
      DB_REGISTER |
      DB_RECOVER |
      DB_THREAD |
      DB_FAILCHK;

      H^2