Example #1
0
/*
 * A function that performs a series of writes to a
 * Berkeley DB database. The information written
 * to the database is largely nonsensical, but the
 * mechanism of transactional commit/abort and
 * deadlock detection is illustrated here.
 */
void *
writer_thread(void *args)
{
    DB *dbp;
    DB_ENV *envp;

    DBT key, value;
    DB_TXN *txn;
    int i, j, payload, ret, thread_num;
    int retry_count, max_retries = 20;   /* Max retry on a deadlock */
    char *key_strings[] = {"key 1", "key 2", "key 3", "key 4",
			   "key 5", "key 6", "key 7", "key 8",
			   "key 9", "key 10"};

    dbp = (DB *)args;
    envp = dbp->get_env(dbp);

    /* Get the thread number */
    (void)mutex_lock(&thread_num_lock);
    global_thread_num++;
    thread_num = global_thread_num;
    (void)mutex_unlock(&thread_num_lock);

    /* Initialize the random number generator */
    srand(thread_num);

    /* Write 50 times and then quit */
    for (i = 0; i < 50; i++) {
	retry_count = 0; /* Used for deadlock retries */

	/*
	 * Some think it is bad form to loop with a goto statement, but
	 * we do it anyway because it is the simplest and clearest way
	 * to achieve our abort/retry operation.
	 */
retry:
	/* Begin our transaction. We group multiple writes in
	 * this thread under a single transaction so as to
	 * (1) show that you can atomically perform multiple writes
	 * at a time, and (2) to increase the chances of a
	 * deadlock occurring so that we can observe our
	 * deadlock detection at work.
	 *
	 * Normally we would want to avoid the potential for deadlocks,
	 * so for this workload the correct thing would be to perform our
	 * puts with autocommit. But that would excessively simplify our
	 * example, so we do the "wrong" thing here instead.
	 */
	ret = envp->txn_begin(envp, NULL, &txn, 0);
	if (ret != 0) {
	    envp->err(envp, ret, "txn_begin failed");
	    return ((void *)EXIT_FAILURE);
	}
	for (j = 0; j < 10; j++) {
	    /* Set up our key and values DBTs */
	    memset(&key, 0, sizeof(DBT));
	    key.data = key_strings[j];
	    key.size = (u_int32_t)strlen(key_strings[j]) + 1;

	    memset(&value, 0, sizeof(DBT));
	    payload = rand() + i;
	    value.data = &payload;
	    value.size = sizeof(int);

	    /* Perform the database put. */
	    switch (ret = dbp->put(dbp, txn, &key, &value, 0)) {
		case 0:
		    break;
		/*
		 * Our database is configured for sorted duplicates,
		 * so there is a potential for a KEYEXIST error return.
		 * If we get one, simply ignore it and continue on.
		 *
		 * Note that you will see KEYEXIST errors only after you
		 * have run this program at least once.
		 */
		case DB_KEYEXIST:
		    printf("Got keyexists.\n");
		    break;
		/*
		 * Here's where we perform deadlock detection. If
		 * DB_LOCK_DEADLOCK is returned by the put operation,
		 * then this thread has been chosen to break a deadlock.
		 * It must abort its operation, and optionally retry the
		 * put.
		 */
		case DB_LOCK_DEADLOCK:
		    /*
		     * First thing that we MUST do is abort the
		     * transaction.
		     */
		    (void)txn->abort(txn);
		    /*
		     * Now we decide if we want to retry the operation.
		     * If we have retried less than max_retries,
		     * increment the retry count and goto retry.
		     */
		    if (retry_count < max_retries) {
			printf("Writer %i: Got DB_LOCK_DEADLOCK.\n",
			    thread_num);
			printf("Writer %i: Retrying write operation.\n",
			    thread_num);
			retry_count++;
			goto retry;
		    }
		    /*
		     * Otherwise, just give up.
		     */
		    printf("Writer %i: ", thread_num);
		    printf("Got DB_LOCK_DEADLOCK and out of retries.\n");
		    printf("Writer %i: Giving up.\n", thread_num);
		    return ((void *)EXIT_FAILURE);
		/*
		 * If a generic error occurs, we simply abort the
		 * transaction and exit the thread completely.
		 */
		default:
		    envp->err(envp, ret, "db put failed");
		    ret = txn->abort(txn);
		    if (ret != 0)
			envp->err(envp, ret,
			    "txn abort failed");
		    return ((void *)EXIT_FAILURE);
	     } /** End case statement **/

	}   /** End for loop **/

	/*
	 * print the number of records found in the database.
	 * See count_records() for usage information.
	 */
	printf("Thread %i. Record count: %i\n", thread_num,
	    count_records(dbp, NULL));

	/*
	 * If all goes well, we can commit the transaction and
	 * exit the thread.
	 */
	ret = txn->commit(txn, 0);
	if (ret != 0) {
	    envp->err(envp, ret, "txn commit failed");
	    return ((void *)EXIT_FAILURE);
	}
    }
    return ((void *)EXIT_SUCCESS);
}
Example #2
0
static void
op_ds_bulk(u_int ops, u_int *totalp)
{
	DB_ENV *dbenv;
	DB *dbp;
	DBC *dbc;
	DBT key, data;
	u_int32_t len, klen;
	u_int i, total;
	char *keybuf, *databuf;
	void *pointer, *dp, *kp;
	DB_MPOOL_STAT  *gsp;

	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
	DB_BENCH_ASSERT((databuf = malloc(bulkbufsize)) != NULL);

	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = keybuf;
	key.size = keysize;

	data.data = databuf;
	data.size = datasize;
	memset(databuf, 'b', datasize);

	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
	dbenv = dbp->dbenv;
	dbp->set_errfile(dbp, stderr);

	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 1) == 0);
	DB_BENCH_ASSERT(
	    dbp->open(dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0);

	for (i = 1; i <= numitems; ++i) {
		(void)snprintf(keybuf, keysize, "%7d", i);
		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
	}

#if 0
	fp = fopen("before", "w");
	dbp->set_msgfile(dbp, fp);
	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0);
#endif

	DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0);

	data.ulen = bulkbufsize;
	data.flags = DB_DBT_USERMEM;

	(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

	TIMER_START;
	for (total = 0; ops > 0; --ops) {
		DB_BENCH_ASSERT(dbc->c_get(
		    dbc, &key, &data, DB_FIRST | DB_MULTIPLE_KEY) == 0);
		DB_MULTIPLE_INIT(pointer, &data);
		while (pointer != NULL) {
			DB_MULTIPLE_KEY_NEXT(pointer, &data, kp, klen, dp, len);
			if (kp != NULL)
				++total;
		}
	}
	TIMER_STOP;
	*totalp = total;

	if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
	    DB_BENCH_ASSERT(gsp->st_cache_miss == 0);

#if 0
	fp = fopen("before", "w");
	dbp->set_msgfile(dbp, fp);
	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0);
#endif

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	COMPQUIET(dp, NULL);
	COMPQUIET(klen, 0);
	COMPQUIET(len, 0);
}
Example #3
0
static int 
bdb_init_tx_handle(struct storage* s, char* db_env_path)
{
	int result;
	DB_ENV* dbenv; 
	
	//Create environment handle
	result = db_env_create(&dbenv, 0);
	if (result != 0) {
		paxos_log_error("DB_ENV creation failed: %s", db_strerror(result));
		return -1;
	}
	
	//Durability mode
	if (!paxos_config.bdb_sync)
		result = dbenv->set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1);
	
	if (result != 0) {
		paxos_log_error("DB_ENV set_flags failed: %s", db_strerror(result));
		return -1;
	}
	
	//Redirect errors to sdout
	dbenv->set_errfile(dbenv, stdout);

	//Set the size of the memory cache
	result = dbenv->set_cachesize(dbenv, 0, paxos_config.bdb_cachesize, 1);
	if (result != 0) {
		paxos_log_error("DB_ENV set_cachesize failed: %s",
			db_strerror(result));
		return -1;
	}
	
	//TODO see page size impact
	//Set page size for this db
	// result = dbp->set_pagesize(dbp, pagesize);
	// assert(result  == 0);

	//FIXME set log size


	// Environment open flags
	int flags;
	flags =
		DB_CREATE       |  /* Create if not existing */ 
		DB_RECOVER      |  /* Run normal recovery. */
		DB_INIT_LOCK    |  /* Initialize the locking subsystem */
		DB_INIT_LOG     |  /* Initialize the logging subsystem */
		DB_INIT_TXN     |  /* Initialize the transactional subsystem. */
		DB_THREAD       |  /* Cause the environment to be free-threaded */  
		DB_REGISTER 	|
		DB_INIT_MPOOL;     /* Initialize the memory pool (in-memory cache) */

	//Open the DB environment
	result = dbenv->open(dbenv, 
		db_env_path,            /* Environment directory */
		flags,                  /* Open flags */
		0);                     /* Default file permissions */

	if (result != 0) {
		paxos_log_error("DB_ENV open failed: %s", db_strerror(result));
		return -1;
	}

	paxos_log_info("Berkeley DB storage opened successfully");
	
	s->env = dbenv;
	return 0;
}
Example #4
0
File: db3.c Project: xrg/RPM
static int db_init(dbiIndex dbi, const char * dbhome,
		const char * dbfile,
		const char * dbsubfile,
		DB_ENV ** dbenvp)
{
    rpmdb rpmdb = dbi->dbi_rpmdb;
    DB_ENV *dbenv = NULL;
    int eflags;
    int rc;

    if (dbenvp == NULL)
	return 1;

    /* XXX HACK */
    if (rpmdb->db_errfile == NULL)
	rpmdb->db_errfile = stderr;

    eflags = (dbi->dbi_oeflags | dbi->dbi_eflags);
    if (eflags & DB_JOINENV) eflags &= DB_JOINENV;

    if (dbfile) {
	char *dbiflags = prDbiOpenFlags(eflags, 1);
	rpmlog(RPMLOG_DEBUG, "opening  db environment %s/%s %s\n",
		dbhome, dbfile, dbiflags);
	free(dbiflags);
    }

    /* XXX Can't do RPC w/o host. */
    if (dbi->dbi_host == NULL)
	dbi->dbi_ecflags &= ~DB_CLIENT;

    /* XXX Set a default shm_key. */
    if ((dbi->dbi_eflags & DB_SYSTEM_MEM) && dbi->dbi_shmkey == 0) {
#if defined(HAVE_FTOK)
	dbi->dbi_shmkey = ftok(dbhome, 0);
#else
	dbi->dbi_shmkey = 0x44631380;
#endif
    }

    rc = db_env_create(&dbenv, dbi->dbi_ecflags);
    rc = cvtdberr(dbi, "db_env_create", rc, _debug);
    if (dbenv == NULL || rc)
	goto errxit;

  { int xx;

 /* 4.1: dbenv->set_app_dispatch(???) */
 /* 4.1: dbenv->set_alloc(???) */
 /* 4.1: dbenv->set_data_dir(???) */
 /* 4.1: dbenv->set_encrypt(???) */

    dbenv->set_errcall(dbenv, (void *) rpmdb->db_errcall);
    dbenv->set_errfile(dbenv, rpmdb->db_errfile);
    dbenv->set_errpfx(dbenv, rpmdb->db_errpfx);

 /* 4.1: dbenv->set_feedback(???) */
 /* 4.1: dbenv->set_flags(???) */

 /* dbenv->set_paniccall(???) */

#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5)
    /* 
     * These enable automatic stale lock removal. 
     * thread_count 8 is some kind of "magic minimum" value...
     */
    dbenv->set_thread_count(dbenv, 8);
    dbenv->set_isalive(dbenv, db3isalive);
#endif

    if ((dbi->dbi_ecflags & DB_CLIENT) && dbi->dbi_host) {
	const char * home;
	int retry = 0;

	if ((home = strrchr(dbhome, '/')) != NULL)
	    dbhome = ++home;

	while (retry++ < 5) {
	    xx = dbenv->set_rpc_server(dbenv, NULL, dbi->dbi_host,
		dbi->dbi_cl_timeout, dbi->dbi_sv_timeout, 0);
	    xx = cvtdberr(dbi, "dbenv->set_server", xx, _debug);
	    if (!xx)
		break;
	    (void) sleep(15);
	}
    } else {
#if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
	xx = dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT,
		(dbi->dbi_verbose & DB_VERB_CHKPOINT));
#endif
	xx = dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
		(dbi->dbi_verbose & DB_VERB_DEADLOCK));
	xx = dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
		(dbi->dbi_verbose & DB_VERB_RECOVERY));
	xx = dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
		(dbi->dbi_verbose & DB_VERB_WAITSFOR));

	if (dbi->dbi_mmapsize) {
	    xx = dbenv->set_mp_mmapsize(dbenv, dbi->dbi_mmapsize);
	    xx = cvtdberr(dbi, "dbenv->set_mp_mmapsize", xx, _debug);
	}
	if (dbi->dbi_tmpdir) {
	    const char * root;
	    char * tmpdir;

	    root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
	    if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
		root = NULL;
	    tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
	    xx = dbenv->set_tmp_dir(dbenv, tmpdir);
	    xx = cvtdberr(dbi, "dbenv->set_tmp_dir", xx, _debug);
	    tmpdir = _free(tmpdir);
	}
    }

 /* dbenv->set_lk_conflicts(???) */
 /* dbenv->set_lk_detect(???) */
 /* 4.1: dbenv->set_lk_max_lockers(???) */
 /* 4.1: dbenv->set_lk_max_locks(???) */
 /* 4.1: dbenv->set_lk_max_objects(???) */

 /* 4.1: dbenv->set_lg_bsize(???) */
 /* 4.1: dbenv->set_lg_dir(???) */
 /* 4.1: dbenv->set_lg_max(???) */
 /* 4.1: dbenv->set_lg_regionmax(???) */

    if (dbi->dbi_cachesize) {
	xx = dbenv->set_cachesize(dbenv, 0, dbi->dbi_cachesize, 0);
	xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug);
    }

 /* 4.1 dbenv->set_timeout(???) */
 /* dbenv->set_tx_max(???) */
 /* 4.1: dbenv->set_tx_timestamp(???) */
 /* dbenv->set_tx_recover(???) */

 /* dbenv->set_rep_transport(???) */
 /* dbenv->set_rep_limit(???) */

    if (dbi->dbi_no_fsync) {
	xx = db_env_set_func_fsync(db3_fsync_disable);
	xx = cvtdberr(dbi, "db_env_set_func_fsync", xx, _debug);
    }

    if (dbi->dbi_shmkey) {
	xx = dbenv->set_shm_key(dbenv, dbi->dbi_shmkey);
	xx = cvtdberr(dbi, "dbenv->set_shm_key", xx, _debug);
    }
  }

    rc = (dbenv->open)(dbenv, dbhome, eflags, dbi->dbi_perms);
    rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
    if (rc)
	goto errxit;

#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5)
    /* stale lock removal */
    rc = dbenv->failchk(dbenv, 0);
    rc = cvtdberr(dbi, "dbenv->failchk", rc, _debug);
    if (rc)
	goto errxit;
#endif

    *dbenvp = dbenv;

    return 0;

errxit:
    if (dbenv) {
	int xx;
	xx = dbenv->close(dbenv, 0);
	xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
    }
    return rc;
}
Example #5
0
int
b_txn(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB_ENV *dbenv;
	DB_TXN *txn;
	int tabort, ch, i, count;

	count = 1000;
	tabort = 0;
	while ((ch = getopt(argc, argv, "ac:")) != EOF)
		switch (ch) {
		case 'a':
			tabort = 1;
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

	/* Create the environment. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    NULL, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0);
#endif

	/* Start and commit/abort a transaction count times. */
	TIMER_START;
	if (tabort)
		for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
			DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(txn_abort(txn) == 0);
#else
			DB_BENCH_ASSERT(
			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(txn->abort(txn) == 0);
#endif
		}
	else
		for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
			DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(txn_commit(txn, 0) == 0);
#else
			DB_BENCH_ASSERT(
			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
#endif
		}
	TIMER_STOP;

	printf("# %d empty transaction start/%s pairs\n",
	    count, tabort ? "abort" : "commit");
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	return (0);
}
Example #6
0
static void insert_db(const char *file, const uint8_t type)
{
   DB *db = NULL;
   DBT key, data;
   DB_ENV *env;
   union {
      IP_LIST ip_list;
      DOMAIN_LIST dom_list;
   } u;
   u_int32_t i, j;
   char buf[350];
   FILE *fd = NULL;
   
   memset(buf, '\0', sizeof(buf));
   
   fd = fopen(file, "r");
   
   if ((i = db_env_create(&env, 0)) != 0) {
        fprintf(stderr, "db_input: %s\n", db_strerror(i));
        return;
   }
    
   if ((i = env->open(env, DB_ENVIRONMENT,
              DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_THREAD, 0)) != 0) {
       fprintf(stderr, "environment open: %s\n", DB_ENVIRONMENT);
       goto err;
   }
    
   if ((i = db_create(&db, env, 0)) != 0) {
       fprintf(stderr, "database create\n");
       goto err;
   }
    
   if (!strcmp(file, "ip_list"))
     strncpy(buf, IP_DB_NAME, 32);
   else
     strncpy(buf, DOMAIN_DB_NAME, 32);
    
   if ((i = db->open(db, NULL, buf, NULL, DB_BTREE,
              DB_CREATE | DB_THREAD, 0644)) != 0) {
       fprintf(stderr, "DB->open: %s\n", buf);
       goto err;
   }
   
   uint32_t idnum = 0;
   //get idnum
   memset(&key, 0, sizeof(DBT));
   memset(&data, 0, sizeof(DBT));
   
   if (!strcmp(file, "dom_list")) {
      key.data = ID_NUM;
      key.size = 2;
      data.data = &idnum;
      data.ulen = sizeof(uint32_t);
      data.flags = DB_DBT_USERMEM;
            
      i = db->get(db, NULL, &key, &data, 0);
      if (i != 0)
         idnum = 0;
      else
         idnum++;
   }
      
   while (fgets(buf, 350, fd)) {
      j = strlen(buf);
      memset(buf +(j-1), '\0', 1);
      
      if (!strcmp(file, "ip_list")) {
         memset(&u.ip_list, 0, sizeof(IP_LIST));
         
         u.ip_list.id = 0;
         u.ip_list.type = type;
         u.ip_list.flag = DB_ENABLE | DB_WHOLE_MATCH;
      } else {
         memset(&u.dom_list, 0, sizeof(DOMAIN_LIST));
         idnum++;
         
         u.dom_list.id = idnum;
         u.dom_list.ttl = time(NULL);
         u.dom_list.type = type;
         u.dom_list.flag = DB_ENABLE | DB_WHOLE_MATCH;
      }
            
      memset(&key, 0, sizeof(DBT));
      memset(&data, 0, sizeof(DBT));
           
      if (!strcmp(file, "ip_list")) {
         u_int32_t addr;
         if (inet_pton(AF_INET, buf, &addr)) {
            key.data = &addr;
            key.size = sizeof(uint32_t);
         
            data.data = &u.ip_list;
            data.size = sizeof(IP_LIST);
         }
      } else {
         mirror(buf);
         
         key.data = buf;
         key.size = j;
      
         data.data = &u.dom_list;
         data.size = sizeof(DOMAIN_LIST);
      }
         
      j = db->put(db, NULL, &key, &data, DB_NOOVERWRITE);
      if (j == DB_KEYEXIST)
         fprintf(stderr, "Put failed because key %s already exists\n", buf);
   }
   
   fclose(fd);
   // save ID_NUM
   if (!strcmp(file, "dom_list")) {
      memset(&key, 0, sizeof(DBT));
      memset(&data, 0, sizeof(DBT));
      
      key.data = ID_NUM;
      key.size = 2;
      data.data = &idnum;
      data.size = sizeof(uint32_t);
      
      // cek jika blom ada maka put, kalau sudah ada maka overwrite
      j = db->put(db, NULL, &key, &data, DB_OVERWRITE_DUP);
   }
   
   config_db(env);
   
   err:
   if (db)
      db->close(db, 0);
   if (env)
      env->close(env, 0);
      
   printf("Done.\n");
}
int TestDbPreOpenSetterAndGetter(CuTest *ct) {
	DB_ENV *dbenv;
	DB *db, *env_db, *hash_db, *heap_db, *queue_db, *recno_db;
	const char **part_dirs;
	u_int32_t encrypt_flags, heap_set_bytes, heap_set_gbytes,
	    heap_get_bytes, heap_get_gbytes;
	int nowait, onoff;
	
	/* ================ General and Btree Configuration =============== */

	CuAssert(ct, "db_create", create_db_handle(&db, NULL) == 0);

	/*
	 * Test DB->set_cachesize(), DB->get_cachesize().
	 * We use specific values to avoid adjustment.
	 */
	CHECK_3_DIGIT_VALUES(db, set_cachesize, get_cachesize,
	    u_int32_t, 3, u_int32_t, 1048576, int, 5);

	/* Test DB->set_encrypt(), DB->get_encrypt_flags(). */
	CuAssert(ct, "db->set_encrypt",
	    db->set_encrypt(db, passwd, DB_ENCRYPT_AES) == 0);
	CuAssert(ct, "db->get_encrypt_flags",
	    db->get_encrypt_flags(db, &encrypt_flags) == 0);
	CuAssert(ct, "check encrypt flags", encrypt_flags == DB_ENCRYPT_AES);

	/* Test DB->set_errfile(), DB->get_errfile(). */
	CHECK_1_PTR_VALUE_VOID(db, set_errfile, get_errfile, FILE, errfile);

	/* Test DB->set_errpfx(), DB->get_errpfx().*/
	CHECK_1_STR_VALUE_VOID(db, set_errpfx, get_errpfx, "dbp1");

	/* Test DB->set_flags(), DB->get_flags(). */
	CHECK_FLAG_VALUE(db, set_flags, get_flags,
	    u_int32_t, DB_CHKSUM | DB_RECNUM | DB_REVSPLITOFF);

	/* Test DB->set_lk_exclusive(), DB->get_lk_exclusive(). */
	CuAssert(ct, "db->set_lk_exclusive", db->set_lk_exclusive(db, 1) == 0);
	CuAssert(ct, "db->get_lk_exclusive",
	    db->get_lk_exclusive(db, &onoff, &nowait) == 0);
	CuAssert(ct, "check lk_exclusive onoff", onoff == 1);
	CuAssert(ct, "check lk_exclusive nowait", nowait == 1);

	/*
	 * Test DB->set_lorder(), DB->get_lorder().
	 * The only acceptable values are 1234 and 4321.
	 */
	CHECK_1_DIGIT_VALUE(db, set_lorder, get_lorder, int, 1234);
	CHECK_1_DIGIT_VALUE(db, set_lorder, get_lorder, int, 4321);

	/* Test DB->set_msgfile(), DB->get_msgfile(). */
	CHECK_1_PTR_VALUE_VOID(db, set_msgfile, get_msgfile, FILE, msgfile);

	/*
	 * Test DB->set_pagesize(), DB->get_pagesize().
	 * The pagesize should be 512-55536, and be power of two.
	 */
	CHECK_1_DIGIT_VALUE(db, set_pagesize, get_pagesize, u_int32_t, 512);
	CHECK_1_DIGIT_VALUE(db, set_pagesize, get_pagesize, u_int32_t, 65536);

	/*
	 * Test DB->set_bt_minkey(), DB->get_bt_minkey().
	 * The minkey value should be 2 at least.
	 */
	CHECK_1_DIGIT_VALUE(db, set_bt_minkey, get_bt_minkey, u_int32_t, 17);

	CuAssert(ct, "db->close", close_db_handle(db) == 0);

	/* =================== Recno-only Configuration ===================== */

	CuAssert(ct, "db_create", create_db_handle(&recno_db, NULL) == 0);

	/* Test DB->set_flags(), DB->get_flags(). */
	CHECK_FLAG_VALUE(recno_db, set_flags, get_flags,
	    u_int32_t, DB_RENUMBER | DB_SNAPSHOT);

	/* Test DB->set_re_delim(), DB->get_re_delim(). */
	CHECK_1_DIGIT_VALUE(recno_db, set_re_delim, get_re_delim,
	    int, rand());

	/* Test DB->set_re_len(), DB->get_re_len(). */
	CHECK_1_DIGIT_VALUE(recno_db, set_re_len, get_re_len,
	    u_int32_t, rand());

	/* Test DB->set_re_pad(), DB->get_re_pad(). */
	CHECK_1_DIGIT_VALUE(recno_db, set_re_pad, get_re_pad, int, rand());

	/* Test DB->set_re_source(), DB->get_re_source(). */
	CHECK_1_STR_VALUE(recno_db, set_re_source, get_re_source, "re_source1");

	CuAssert(ct, "recno_db->close", close_db_handle(recno_db) == 0);

	/* ==================== Hash-only Configuration ===================== */

	CuAssert(ct, "db_create", create_db_handle(&hash_db, NULL) == 0);

	/* Test DB->set_flags(), DB->get_flags(). */
	CHECK_FLAG_VALUE(hash_db, set_flags, get_flags,
	    u_int32_t, DB_DUP | DB_DUPSORT | DB_REVSPLITOFF);

	/* Test DB->set_h_ffactor(), DB->get_h_ffactor(). */
	CHECK_1_DIGIT_VALUE(hash_db, set_h_ffactor, get_h_ffactor,
	    u_int32_t, rand());

	/* Test DB->set_h_nelem(), DB->get_h_nelem(). */
	CHECK_1_DIGIT_VALUE(hash_db, set_h_nelem, get_h_nelem,
	    u_int32_t, rand());

	CuAssert(ct, "hash_db->close", close_db_handle(hash_db) == 0);

	/* =================== Queue-only Configuration ===================== */

	CuAssert(ct, "db_create", create_db_handle(&queue_db, NULL) == 0);

	/* Test DB->set_flags(), DB->get_flags(). */
	CHECK_FLAG_VALUE(queue_db, set_flags, get_flags, u_int32_t, DB_INORDER);

	/* Test DB->set_q_extentsize(), DB->get_q_extentsize(). */
	CHECK_1_DIGIT_VALUE(queue_db, set_q_extentsize, get_q_extentsize,
	    u_int32_t, rand());

	CuAssert(ct, "queue_db->close", close_db_handle(queue_db) == 0);

	/* ==================== Heap-only Configuration ===================== */
	CuAssert(ct, "db_create", create_db_handle(&heap_db, NULL) == 0);

	/* Test DB->set_heapsize(), DB->get_heapsize(). */
	heap_set_gbytes = 3;
	heap_set_bytes = 1048576;
	heap_get_gbytes = heap_get_bytes = 0;
	CuAssert(ct, "DB->set_heapsize", heap_db->set_heapsize(heap_db,
	    heap_set_gbytes, heap_set_bytes, 0) == 0);
	CuAssert(ct, "DB->get_heapsize", heap_db->get_heapsize(heap_db,
	    &heap_get_gbytes, &heap_get_bytes) == 0);
	CuAssert(ct, "Check heap gbytes", heap_set_gbytes == heap_get_gbytes);
	CuAssert(ct, "Check heap bytes", heap_set_bytes == heap_get_bytes);

	/* Test DB->set_heap_regionsize(), DB->get_heap_regionsize(). */
	CHECK_1_DIGIT_VALUE(heap_db, set_heap_regionsize, get_heap_regionsize,
	    u_int32_t, rand());

	CuAssert(ct, "heap_db->close", close_db_handle(heap_db) == 0);

	/*
	 * The following configurations require the database
	 * be opened in an environment.
	 */
	CuAssert(ct, "db_env_create", create_dbenv_handle(&dbenv) == 0);
	CuAssert(ct, "dbenv->set_flags(DB_ENCRYPT)", dbenv->set_encrypt(dbenv,
	    passwd, DB_ENCRYPT_AES) == 0);	
	CuAssert(ct, "add_dirs_to_dbenv",
	    add_dirs_to_dbenv(dbenv, data_dirs) == 0);
	CuAssert(ct, "dbenv->open", dbenv->open(dbenv, TEST_ENV,
	    DB_CREATE | DB_INIT_MPOOL | DB_INIT_TXN, 0644) == 0);
	CuAssert(ct, "db_create", create_db_handle(&env_db, dbenv) == 0);

	/* Test DB->set_flags(), DB->get_flags(). */
	CHECK_FLAG_VALUE(env_db, set_flags, get_flags,
	    u_int32_t, DB_ENCRYPT | DB_TXN_NOT_DURABLE);

	/* Test DB->set_create_dir(), DB->get_create_dir(). */
	CHECK_1_STR_VALUE(env_db, set_create_dir, get_create_dir, data_dirs[0]);

	/* Test DB->set_partition_dirs(), DB->get_partition_dirs(). */
	CuAssert(ct, "env_db->set_partition_dirs",
	    env_db->set_partition_dirs(env_db, &data_dirs[1]) == 0);
	CuAssert(ct, "env_db->get_partition_dirs",
	    env_db->get_partition_dirs(env_db, &part_dirs) == 0);
	CuAssert(ct, "cmp_dirs", cmp_dirs(&data_dirs[1], part_dirs) == 0);

	CuAssert(ct, "env_db->close", close_db_handle(env_db) == 0);
	CuAssert(ct, "dbenv->close", close_dbenv_handle(dbenv) == 0);

	return (0);
}
Example #8
0
int main(int argc, char **argv)
{
	std::string path2DbEnv;
	std::string theContainer = "namespaceExampleData.dbxml";
	for ( int i=1; i<argc; i++ )
	{
		if ( argv[i][0] == '-' )
		{
			switch(argv[i][1])
			{
			case 'h':
				path2DbEnv = argv[++i];
				break;
			default:
				usage();
			}
		}
	}

	if (! path2DbEnv.length() )
		usage();

	// Berkeley DB environment flags
	u_int32_t envFlags = DB_RECOVER|DB_CREATE|DB_INIT_MPOOL|
		DB_INIT_LOCK|DB_INIT_TXN|DB_INIT_LOG;
	// Berkeley DB cache size (64 MB).  The default is quite small
	u_int32_t envCacheSize = 64*1024*1024;

	// Create and open a Berkeley DB Transactional Environment.
	int dberr;
	DB_ENV *dbEnv = 0;
	dberr = db_env_create(&dbEnv, 0);
	if (dberr == 0) {
		dbEnv->set_cachesize(dbEnv, 0, envCacheSize, 1);
		dberr = dbEnv->open(dbEnv, path2DbEnv.c_str(), envFlags, 0);
	}
	if (dberr) {
		std::cout << "Unable to create environment handle due to the following error: " <<
			db_strerror(dberr) << std::endl;
		if (dbEnv) dbEnv->close(dbEnv, 0);
		return -1;
	}

	//Have the XmlManager adopt the db environment
	XmlManager mgr(dbEnv, DBXML_ADOPT_DBENV);

	//Configure the container to use transactions
	XmlContainerConfig config;
	config.setTransactional(true);

	//Open a container in the db environment
	XmlContainer container = mgr.openContainer(theContainer, config);

	//Create a context and declare the namespaces
	XmlQueryContext context = mgr.createQueryContext();
	context.setNamespace( "fruits", "http://groceryItem.dbxml/fruits");
	context.setNamespace( "vegetables", "http://groceryItem.dbxml/vegetables");
	context.setNamespace( "desserts", "http://groceryItem.dbxml/desserts");

	//create a transaction
	XmlTransaction txn = mgr.createTransaction();

	//get details on Zulu Nuts
	getDetails( txn, mgr, container, "/fruits:item[fn:string(product) = 'Zulu Nut']", context);

	//get details on all fruits that start with 'A'
	getDetails( txn, mgr, container, "/vegetables:item[starts-with(fn:string(product),'A')]", context);

	//commit transaction
	txn.commit();

	return 0;
}
Example #9
0
int DbWrapper::load(std::istream *in, unsigned long *lineno)
{
	int version, ret, t_ret;
	DBTYPE dbtype;
	char *subdb = 0;
	u_int32_t read_flags, tflags;
	DBT key, data;
	db_recno_t recno, datarecno;
	DB_ENV *dbenv = environment_;
	
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));

	if ((ret = __db_rheader(dbenv, db_, &dbtype,
				&subdb, &version, &read_flags, read_callback, in, lineno)) != 0)
		goto err;

	/* We always print with keys */
	if (!(read_flags & DB_READ_HASKEYS)) {
		db_->errx(db_, "Invalid DbXml dump: keys missing");
		ret = EINVAL;
		goto err;
	}

	if ((ret = open(NULL, dbtype, DB_CREATE|DB_EXCL)) != 0)
		goto err;

	/* Initialize the key/data pair. */
	if (dbtype == DB_RECNO || dbtype == DB_QUEUE) {
		key.size = sizeof(recno);
		key.data = &datarecno;
	} else {
		key.ulen = 1024;
		key.data = (void *)malloc(key.ulen);
	}
	data.ulen = 1024;
	data.data = (void *)malloc(data.ulen);
	if (key.data == NULL || data.data == NULL) {
		db_->err(db_, ENOMEM, NULL);
		goto err;
	}
	
	// work around gcc optimizer issue that seems to modify
	// read_flags (4.1.1 on 64-bit linux)
	tflags = read_flags;
	/* Get each key/data pair and add them to the database. */
	for (recno = 1;; ++recno) {
		if ((ret = __db_rdbt(dbenv, &key, &data,
				     tflags, read_callback, in, lineno)) != 0) {
			if (ret == EOF)
				ret = 0;
			break;
		}

		switch (ret = db_->put(db_, NULL, &key, &data, 0)) {
		case 0:
			break;
		case DB_KEYEXIST:
			db_->errx(db_, "line %d: key already exists, not loaded:", *lineno);
			dbenv->prdbt(&key, tflags & DB_READ_PRINTABLE,
				     0, &std::cerr, pr_callback, 0);
			break;
		default:
			db_->err(db_, ret, NULL);
			goto err;
		}
	}

 err:	/* Close the database. */
	if ((t_ret = close(0)) != 0 && ret == 0)
		ret = t_ret;

	/* Free allocated memory. */
	if (subdb != NULL)
		free(subdb);
	if (key.data != NULL && dbtype != DB_RECNO && dbtype != DB_QUEUE)
		free(key.data);
	if (data.data != NULL)
		free(data.data);

	return (ret);
}
static void open_db(bdb_drv_t* pdrv, ErlIOVec *ev) {

    drv_cfg* pcfg;

    DB* pdb;
    DB_ENV* penv;
    u_int32_t open_flags, page_size_bytes, cache_size_bytes, bulk_get_buffer_size_bytes;
    int ret;

    ErlDrvBinary* data = ev->binv[1];

    char *bytes = data->orig_bytes;

    int txn_enabled         = bytes[1];
    int db_type             = bytes[2];

    cache_size_bytes           = (uint32_t) ntohl(* ((uint32_t*) (bytes + 4) ));
    page_size_bytes            = (uint32_t) ntohl(* ((uint32_t*) (bytes + 4 + 4) ));
    bulk_get_buffer_size_bytes = (uint32_t) ntohl(* ((uint32_t*) (bytes + 4 + 4 + 4) ));

    char* lv_start = bytes + 4 + 4 + 4 + 4;

    char *db_name_len_bytes = lv_start;
    char *db_name_bytes     = lv_start + 4;
    uint32_t db_name_length = (uint32_t) ntohl(* ((uint32_t*) db_name_len_bytes) );

    char *data_dir_len_bytes = db_name_bytes + db_name_length;
    char *data_dir_bytes     = data_dir_len_bytes + 4;
    uint32_t data_dir_length = (uint32_t) ntohl(* ((uint32_t*) data_dir_len_bytes) );

    pcfg = (drv_cfg*) malloc(sizeof(drv_cfg));

    pcfg->buffer = (char*) malloc(bulk_get_buffer_size_bytes);
    if (pcfg->buffer == NULL) {
        return_error_tuple(pdrv, "Could not allocate memory for operation!");
        return;
    }  

    pcfg->penv = NULL;
    pcfg->pdb  = NULL;

    pcfg->txn_enabled = txn_enabled;

    pcfg->data_dir             = malloc(data_dir_length + 1);
    pcfg->db_name              = malloc(db_name_length + 1);
    pcfg->page_size_bytes      = page_size_bytes;

    pcfg->data_dir[data_dir_length] = 0;
    pcfg->db_name[db_name_length] = 0;

    if (db_type == 'B') {
        pcfg->db_type = DB_BTREE;
    } else {
        pcfg->db_type = DB_HASH;
    }

    memcpy(pcfg->data_dir, data_dir_bytes, data_dir_length);
    memcpy(pcfg->db_name, db_name_bytes, db_name_length);

    pcfg->bulk_get_buffer_size_bytes = bulk_get_buffer_size_bytes;

    ret = db_env_create(&penv, 0);
    if (ret != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    } 

    penv->app_private = pcfg;

    
    open_flags = DB_CREATE | DB_INIT_MPOOL;

    if (pcfg->txn_enabled) {
        open_flags |= DB_INIT_LOCK | DB_THREAD | DB_INIT_TXN | DB_INIT_LOG | DB_REGISTER | DB_RECOVER;
    }

    //penv->set_msgcall(penv, (FILE*)stderr);
    //penv->set_verbose(penv, DB_VERB_DEADLOCK | DB_VERB_RECOVERY, 1);

    ret = penv->set_cachesize(penv, 0, cache_size_bytes, 1);
    if (ret != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    ret = penv->open(penv, pcfg->data_dir, open_flags, 0);
    if (ret != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    //Only open the table if not in replication mode.... for rep mode the table will be opened in event handler ...

    ret = db_create(&pdb, penv, 0);
    if (ret != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    if (pcfg->db_type == DB_BTREE) {

        ret = pdb->set_flags(pdb, DB_RECNUM);
        if (ret != 0) {
            return_error_tuple(pdrv, db_strerror(ret));
            return;
        }
    }

    ret = pdb->set_pagesize(pdb, page_size_bytes);
    if (ret != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    pdb->set_errpfx(pdb, pcfg->db_name);

    pcfg->db_open_flags = DB_CREATE;
 
    if (pcfg->txn_enabled) {
        pcfg->db_open_flags |= DB_THREAD; 
    }

    if ((ret = pdb->open(pdb, NULL, pcfg->db_name, pcfg->db_name, pcfg->db_type, pcfg->db_open_flags, 0)) != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    pcfg->pdb  = pdb;

    pcfg->penv = penv;

    pdrv->pcfg = pcfg;

    return_ok(pdrv);

    return;

}
Example #11
0
int main(int argc, char **argv)
{
    // Deal with command line arguments
    const char *path2DbEnv = 0;
    u_int32_t envFlags = (DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL);
    u_int32_t txnEnvFlags =	(DB_INIT_TXN|DB_INIT_LOCK|DB_INIT_LOG);
    u_int32_t dbxmlFlags = DBXML_ALLOW_EXTERNAL_ACCESS;
    vector<string> scripts;
    int verbose = 0;
    bool transactionMode = false;
    bool dbPrivate = false;
    bool envCreate = false;
    const char *progName = argv[0];
    const char *password = 0;
    int cacheSize = 64;
    int ch;
    int ret = 0;

    while ((ch = getopt(argc, argv, "?h:hs:tvxVP:cz:")) != -1) {
        switch (ch) {
        case 'h': {
            path2DbEnv = optarg;
            break;
        }
        case 'z': {
            cacheSize = atoi(optarg);
            break;
        }
        case 'c': {
            envFlags &= ~DB_PRIVATE;
            envCreate = true;
            break;
        }
        case 'x': {
            dbxmlFlags &= ~DBXML_ALLOW_EXTERNAL_ACCESS;
            break;
        }
        case 't': {
            transactionMode = true;
            envFlags |= txnEnvFlags;
            break;
        }
        case 's': {
            scripts.push_back(optarg);
            break;
        }
        case 'v': {
            ++verbose;
            break;
        }
        case 'V': {
            printf("%s\n", DbXml::dbxml_version(NULL, NULL, NULL));
            printf("%s\n", db_version(NULL, NULL, NULL));
            exit(0);
        }
        case 'P': {
            password = optarg;
            break;
        }
        case '?':
        default: {
            usage(progName, 0);
            break;
        }
        }
    }

    // Turn on logging if extra verbose is specified
    if(verbose > 1) {
        setLogLevel(LEVEL_ALL, true);
        setLogCategory(CATEGORY_ALL, true);
        setLogCategory(CATEGORY_NODESTORE, verbose > 2);
        verboseErrors = true;
    }

    SigBlock sb; // block signals, resend at end of scope
    try {
        // Create a DB environment, and XmlManager
        DB_ENV *dbenv;
        int dberr = 0;
        dberr = db_env_create(&dbenv, 0);
        if (dberr) {
            cout << "Error creating environment: " << dberr << endl;
            exit(-1);
        }
        if (password)
            dbenv->set_encrypt(dbenv, password, DB_ENCRYPT_AES);
        dbenv->set_errcall(dbenv, errcall);
        dbenv->set_cachesize(dbenv, 0, cacheSize * 1024 * 1024, 1);
        dbenv->set_lk_max_lockers(dbenv, 10000);
        dbenv->set_lk_max_locks(dbenv, 10000);
        dbenv->set_lk_max_objects(dbenv, 10000);
        if (!dbPrivate) {
            dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT);
            if (verbose && !envCreate) {
                cout <<
                     "Attempting to join environment: "
                     << (path2DbEnv ? path2DbEnv : ".")
                     << endl;
            }
            dberr = dbenv->open(dbenv, path2DbEnv, DB_USE_ENVIRON, 0);
            if (dberr != 0) {
                if (dberr == DB_VERSION_MISMATCH) {
                    cerr << "Error opening environment "
                         << (path2DbEnv ? path2DbEnv : ".")
                         << ": " << "environment version mismatch" << endl;
                    exit(-1);
                }
                if (verbose) {
                    if(envCreate) {
                        cerr << "Creating environment: "
                             << (path2DbEnv ? path2DbEnv : ".")
                             << endl;
                    } else {
                        cerr << "Unable to join environment "
                             << (path2DbEnv ? path2DbEnv : ".")
                             << ", creating a DB_PRIVATE environment" << endl;
                    }
                }
                dberr = dbenv->open(dbenv, path2DbEnv,
                                    envFlags, 0);
            } else {
                cout <<	"Joined existing environment"
                     << endl;
                u_int32_t eflags = 0;
                dbenv->get_open_flags(dbenv, &eflags);
                if (eflags & DB_INIT_TXN)
                    transactionMode = true;
                else {
                    if (verbose && (transactionMode == true))
                        cout << "Joined a non-transactional environment, turning off transaction mode" << endl;
                    transactionMode = false;
                }
            }
        } else {
            dberr = dbenv->open(dbenv, path2DbEnv,
                                envFlags, 0);
        }
        if (dberr != 0) {
            cerr << "Error opening environment "
                 << (path2DbEnv ? path2DbEnv : ".")
                 << ", error is " << dberr << endl;
            exit(-1);
        }
        XmlManager db(dbenv, dbxmlFlags|DBXML_ADOPT_DBENV);

        // Create the environment
        Environment env(db, sb);
        env.transactions() = transactionMode;

        // Create the Shell object
        DefaultShell shell;

        // Run scripts, if specified
        if(!scripts.empty()) {
            env.interactive() = false;
            env.verbose() = (verbose != 0);

            for(vector<string>::iterator i = scripts.begin();
                    i != scripts.end() && !env.quit(); ++i) {
                ifstream scriptFile(i->c_str(), ios::in);
                if(!scriptFile) {
                    cerr << progName << ": cannot open script file: " << *i << endl;
                } else {
                    env.streamName() = *i;
                    env.lineNo() = 0;
                    shell.mainLoop(scriptFile, env);
                    scriptFile.close();
                }
            }
        }

        // Perform the queries
        if(!env.quit()) {
            env.interactive() = true;
            env.verbose() = true;
            env.streamName() = "stdin";
            env.lineNo() = 0;

            do {
                shell.mainLoop(cin, env);
                if(env.sigBlock().isInterrupted())
                    env.sigBlock().reset();
            } while(!env.quit() && !cin.eof());
        }
    }
    catch(exception &e) {
        cerr << progName << ": error at lowest level: " << e.what() << endl;
        ret = 1;
    }
    catch(...) {
        cerr << progName << ": error at lowest level: " << endl;
        ret = 1;
    }
    return ret;
}
Example #12
0
/*
** Copy nPage pages from the source b-tree to the destination.
*/
int sqlite3_backup_step(sqlite3_backup *p, int nPage) {
	int returnCode, pages;
	Parse parse;
	DB_ENV *dbenv;
	BtShared *pBtDest, *pBtSrc;

	pBtDest = pBtSrc = NULL;

	if (p->rc != SQLITE_OK || nPage == 0)
		return p->rc;

	sqlite3_mutex_enter(p->pSrcDb->mutex);
	sqlite3_mutex_enter(p->pDestDb->mutex);

	/*
	 * Make sure the schema has been read in, so the keyInfo
	 * can be retrieved for the indexes.  No-op if already read.
	 * If the schema has not been read then an update must have
	 * changed it, so backup will restart.
	 */
	memset(&parse, 0, sizeof(parse));
	parse.db = p->pSrcDb;
	p->rc = sqlite3ReadSchema(&parse);
	if (p->rc != SQLITE_OK)
		goto err;

	/*
	 * This process updated the source database, so
	 * the backup process has to restart.
	 */
	if (p->pSrc->updateDuringBackup > p->lastUpdate) {
		p->rc = SQLITE_LOCKED;
		if ((p->rc = backupCleanup(p)) != SQLITE_OK)
			goto err;
		else
			backupReset(p);
	}

	pages = nPage;

	if (!p->cleaned) {
		const char *home;
		const char inmem[9] = ":memory:";
		int storage;

		pBtDest = p->pDest->pBt;
		storage = p->pDest->pBt->dbStorage;
		if (storage == DB_STORE_NAMED)
			p->openDest = 1;
		if (strcmp(p->destName, "temp") == 0)
			p->pDest->schema = NULL;
		else 
			p->pDestDb->aDb[p->iDb].pSchema = NULL;
			
		p->rc = btreeDeleteEnvironment(p->pDest, p->fullName, 1);
		if (storage == DB_STORE_INMEM && strcmp(p->destName, "temp")
		    != 0)
			home = inmem;
		else
			home = p->fullName;
		if (p->rc != SQLITE_BUSY)
			p->pDest = p->pDestDb->aDb[p->iDb].pBt = NULL;
		if (p->rc != SQLITE_OK)
			goto err;
		/*
		 * Call sqlite3OpenTempDatabase instead of
		 * sqlite3BtreeOpen, because sqlite3OpenTempDatabase
		 * automatically chooses the right flags before calling
		 * sqlite3BtreeOpen.
		 */
		if (strcmp(p->destName, "temp") == 0) {
			memset(&parse, 0, sizeof(parse));
			parse.db = p->pDestDb;
			p->rc = sqlite3OpenTempDatabase(&parse);
			p->pDest = p->pDestDb->aDb[p->iDb].pBt;
			if (p->pDest && p->iDb != 1)
				p->pDest->schema =
				    p->pDestDb->aDb[p->iDb].pSchema;
		} else {
			p->rc = sqlite3BtreeOpen(NULL, home, p->pDestDb,
			    &p->pDest, SQLITE_DEFAULT_CACHE_SIZE |
			    SQLITE_OPEN_MAIN_DB, p->pDestDb->openFlags);
			p->pDestDb->aDb[p->iDb].pBt = p->pDest;
			if (p->pDest) {
				p->pDestDb->aDb[p->iDb].pSchema = 
				    sqlite3SchemaGet(p->pDestDb, p->pDest);
				if (p->pDestDb->aDb[p->iDb].pSchema == NULL)
					p->rc = SQLITE_NOMEM;
			}
		}

		if (p->pDest)
			p->pDest->nBackup++;
#ifdef SQLITE_HAS_CODEC
		/*
		 * In the case of a temporary source database, use the
		 * encryption of the main database.
		 */
		if (strcmp(p->srcName, "temp") == 0) {
			 int iDb = sqlite3FindDbName(p->pSrcDb, "main");
			 pBtSrc = p->pSrcDb->aDb[iDb].pBt->pBt;
		} else
			 pBtSrc = p->pSrc->pBt;
		if (p->rc == SQLITE_OK) {
			if (p->iDb == 0)
				p->rc = sqlite3_key(p->pDestDb,
				    pBtSrc->encrypt_pwd,
				    pBtSrc->encrypt_pwd_len);
			else
				p->rc = sqlite3CodecAttach(p->pDestDb, p->iDb,
				    pBtSrc->encrypt_pwd,
				    pBtSrc->encrypt_pwd_len);
		}
#endif
		if (p->rc != SQLITE_OK)
			goto err;
		p->cleaned = 1;
	}

	/*
	 * Begin a transaction, unfortuantely the lock on
	 * the schema has to be released to allow the sqlite_master
	 * table to be cleared, which could allow another thread to
	 * alter it, however accessing the backup database during
	 * backup is already an illegal condition with undefined
	 * results.
	 */
	if (!sqlite3BtreeIsInTrans(p->pDest)) {
		if (!p->pDest->connected) {
			p->rc = btreeOpenEnvironment(p->pDest, 1);
			if (p->rc != SQLITE_OK)
				goto err;
		}
		if ((p->rc = btreeBeginTransInternal(p->pDest, 2))
			!= SQLITE_OK)
			goto err;
	}
	/* Only this process should be accessing the backup environment. */
	if (p->pDest->pBt->nRef > 1) {
		p->rc = SQLITE_BUSY;
		goto err;
	}

	/*
	 * Begin a transaction, a lock error or update could have caused
	 * it to be released in a previous call to step.
	 */
	if (!p->srcTxn) {
		dbenv = p->pSrc->pBt->dbenv;
		if ((p->rc = dberr2sqlite(dbenv->txn_begin(dbenv,
		    p->pSrc->family_txn, &p->srcTxn, 0), NULL)) != SQLITE_OK)
			goto err;
	}

	/*
	 * An update could have dropped or created a table, so recalculate
	 * the list of tables.
	 */
	if (!p->tables) {
		if ((p->rc = btreeGetPageCount(p->pSrc,
		    &p->tables, &p->nPagecount, p->srcTxn)) != SQLITE_OK) {
				sqlite3Error(p->pSrcDb, p->rc, 0);
				goto err;
		}
		p->nRemaining = p->nPagecount;
	}

	/* Copy the pages. */
	p->rc = btreeCopyPages(p, &pages);
	if (p->rc == SQLITE_DONE) {
		p->nRemaining = 0;
		sqlite3ResetOneSchema(p->pDestDb, p->iDb);
		memset(&parse, 0, sizeof(parse));
		parse.db = p->pDestDb;
		p->rc = sqlite3ReadSchema(&parse);
		if (p->rc == SQLITE_OK)
			p->rc = SQLITE_DONE;
	} else if (p->rc != SQLITE_OK)
		goto err;

	/*
	 * The number of pages left to copy is an estimate, so
	 * do not let the number go to zero unless we are really
	 * done.
	 */
	if (p->rc != SQLITE_DONE) {
		if ((u32)pages >= p->nRemaining)
			p->nRemaining = 1;
		else
			p->nRemaining -= pages;
	}

err:	/*
	 * This process updated the source database, so
	 * the backup process has to restart.
	 */
	if (p->pSrc->updateDuringBackup > p->lastUpdate &&
	    (p->rc == SQLITE_OK || p->rc == SQLITE_DONE)) {
		int cleanCode;
		returnCode = p->rc;
		p->rc = SQLITE_LOCKED;
		if ((cleanCode = backupCleanup(p)) != SQLITE_OK)
			returnCode = p->rc = cleanCode;
		else
			backupReset(p);
	} else {
		returnCode = backupCleanup(p);
		if (returnCode == SQLITE_OK ||
		    (p->rc != SQLITE_OK && p->rc != SQLITE_DONE))
			returnCode = p->rc;
		else
			p->rc = returnCode;
	}
	/*
	 * On a locked or busy error the backup process is rolled back,
	 * but can be restarted by the user.
	 */
	if ( returnCode == SQLITE_LOCKED || returnCode == SQLITE_BUSY )
		backupReset(p);
	else if ( returnCode != SQLITE_OK && returnCode != SQLITE_DONE ) {
		sqlite3Error(p->pDestDb, p->rc, 0);
	}
	sqlite3_mutex_leave(p->pDestDb->mutex);
	sqlite3_mutex_leave(p->pSrcDb->mutex);
	return (returnCode);
}
Example #13
0
int main(int argc, char **argv)
{
	std::string path2DbEnv;
	std::string theContainer = "namespaceExampleData.dbxml";
	for ( int i=1; i<argc; i++ )
	{
		if ( argv[i][0] == '-' )
		{
			switch(argv[i][1])
			{
			case 'h':
				path2DbEnv = argv[++i];
				break;
			default:
				usage();
			}
		}
	}

	if (! path2DbEnv.length() )
		usage();

	// Berkeley DB environment flags
	u_int32_t envFlags = DB_RECOVER|DB_CREATE|DB_INIT_MPOOL|
		DB_INIT_LOCK|DB_INIT_TXN|DB_INIT_LOG;
	// Berkeley DB cache size (64 MB).  The default is quite small
	u_int32_t envCacheSize = 64*1024*1024;

	// Create and open a Berkeley DB Transactional Environment.
	int dberr;
	DB_ENV *dbEnv = 0;
	dberr = db_env_create(&dbEnv, 0);
	if (dberr == 0) {
		dbEnv->set_cachesize(dbEnv, 0, envCacheSize, 1);
		dberr = dbEnv->open(dbEnv, path2DbEnv.c_str(), envFlags, 0);
	}
	if (dberr) {
		std::cout << "Unable to create environment handle due to the following error: " <<
			db_strerror(dberr) << std::endl;
		if (dbEnv) dbEnv->close(dbEnv, 0);
		return -1;
	}

	//Have the XmlManager adopt the db environment
	XmlManager db(dbEnv, DBXML_ADOPT_DBENV);

	//Configure the container to use transactions
	XmlContainerConfig config;
	config.setTransactional(true);

	//Open a container in the db environment
	XmlContainer container = db.openContainer(theContainer, config);

	//Get a transaction
	XmlTransaction txn = db.createTransaction();
	XmlUpdateContext uc = db.createUpdateContext();

	//add an string equality index for the "product" element node.
	deleteIndex( container, "", "product", "node-element-equality-string", txn, uc );

	//Do these deletes in two different transactions
	// for no particular reason.
	txn.commit();
	txn = db.createTransaction();

	//add an edge presence index for the product node
	deleteIndex( container, "", "product", "edge-element-presence-none", txn, uc );

	txn.commit();

	return 0;
}
Example #14
0
int
main(int argc, char *argv[])
{
    /* Initialize our handles */
    DB *dbp = NULL;
    DB_ENV *envp = NULL;

    thread_t writer_threads[NUMWRITERS];
    int ch, i, ret, ret_t;
    u_int32_t env_flags;
    char *db_home_dir;
    /* Application name */
    const char *prog_name = "txn_guide";
    /* Database file name */
    const char *file_name = "mydb.db";

    /* Parse the command line arguments */
#ifdef _WIN32
    db_home_dir = ".\\";
#else
    db_home_dir = "./";
#endif
    while ((ch = getopt(argc, argv, "h:")) != EOF)
	switch (ch) {
	case 'h':
	    db_home_dir = optarg;
	    break;
	case '?':
	default:
	    return (usage());
	}

    /* Create the environment */
    ret = db_env_create(&envp, 0);
    if (ret != 0) {
	fprintf(stderr, "Error creating environment handle: %s\n",
	    db_strerror(ret));
	goto err;
    }

     /*
     * Indicate that we want db to perform lock detection internally.
     * Also indicate that the transaction with the fewest number of
     * write locks will receive the deadlock notification in
     * the event of a deadlock.
     */
    ret = envp->set_lk_detect(envp, DB_LOCK_MINWRITE);
    if (ret != 0) {
	fprintf(stderr, "Error setting lock detect: %s\n",
	    db_strerror(ret));
	goto err;
    }

    env_flags =
      DB_CREATE     |  /* Create the environment if it does not exist */
      DB_RECOVER    |  /* Run normal recovery. */
      DB_INIT_LOCK  |  /* Initialize the locking subsystem */
      DB_INIT_LOG   |  /* Initialize the logging subsystem */
      DB_INIT_TXN   |  /* Initialize the transactional subsystem. This
			* also turns on logging. */
      DB_INIT_MPOOL |  /* Initialize the memory pool (in-memory cache) */
      DB_THREAD;       /* Cause the environment to be free-threaded */

    /* Now actually open the environment */
    ret = envp->open(envp, db_home_dir, env_flags, 0);
    if (ret != 0) {
	fprintf(stderr, "Error opening environment: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /*
     * If we had utility threads (for running checkpoints or
     * deadlock detection, for example) we would spawn those
     * here. However, for a simple example such as this,
     * that is not required.
     */

    /* Open the database */
    ret = open_db(&dbp, prog_name, file_name,
      envp, DB_DUPSORT);
    if (ret != 0)
	goto err;

    /* Initialize a mutex. Used to help provide thread ids. */
    (void)mutex_init(&thread_num_lock, NULL);

    /* Start the writer threads. */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_create(
	   &writer_threads[i], NULL, writer_thread, (void *)dbp);

    /* Join the writers */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_join(writer_threads[i], NULL);

err:
    /* Close our database handle, if it was opened. */
    if (dbp != NULL) {
	ret_t = dbp->close(dbp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "%s database close failed: %s\n",
		file_name, db_strerror(ret_t));
	    ret = ret_t;
	}
    }

    /* Close our environment, if it was opened. */
    if (envp != NULL) {
	ret_t = envp->close(envp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "environment close failed: %s\n",
		db_strerror(ret_t));
		ret = ret_t;
	}
    }

    /* Final status message and return. */
    printf("I'm all done.\n");
    return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
int
b_recover(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB *dbp;
	DBT key, data;
	DB_ENV *dbenv;
	DB_TXN *txn;
	u_int32_t cachesize;
	int ch, i, count;

	/*
	 * Recover was too slow before release 4.0 that it's not worth
	 * running the test.
	 */
#if DB_VERSION_MAJOR < 4
	return (0);
#endif
	cachesize = MEGABYTE;
	count = 1000;
	while ((ch = getopt(argc, argv, "C:c:")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

	/* Create the environment. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0);

#define	OFLAGS								\
	(DB_CREATE | DB_INIT_LOCK |					\
	DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE)
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, NULL, OFLAGS, 0666) == 0);
#endif
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
#endif
#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
#endif

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
	DB_BENCH_ASSERT(dbp->open(dbp, NULL,
	    TESTFILE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0666) == 0);
#else
	DB_BENCH_ASSERT(
	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
#endif

	/* Initialize the data. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.size = data.size = 20;
	key.data = data.data = "01234567890123456789";

	/* Start/commit a transaction count times. */
	for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
		DB_BENCH_ASSERT(
		    txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
		DB_BENCH_ASSERT(txn_commit(txn, 0) == 0);
#else
		DB_BENCH_ASSERT(
		    dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
		DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
#endif
	}

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	/* Create a new DB_ENV handle. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
	DB_BENCH_ASSERT(
	    dbenv->set_cachesize(dbenv, 0, 1048576 /* 1MB */, 0) == 0);

	/* Now run recovery. */
	TIMER_START;
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(
	    dbenv, TESTDIR, NULL, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
	DB_BENCH_ASSERT(
	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
	DB_BENCH_ASSERT(
	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
	TIMER_STOP;

	/*
	 * We divide the time by the number of transactions, so an "operation"
	 * is the recovery of a single transaction.
	 */
	printf("# recovery after %d transactions\n", count);
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	return (0);
}
Example #16
0
int
main(int argc, char *argv[])
{
    DB_ENV *dbenv;
    extern char *optarg;
    const char *home;
    char ch, *host, *portstr;
    int local_is_set, ret, totalsites;
    u_int16_t port;
    /* Used to track whether this is a replica or a master. */
    APP_DATA my_app_data;

    dbenv = NULL;
    ret = local_is_set = totalsites = 0;
    home = NULL;

    my_app_data.is_master = 0;  /* Assume that we start as a replica */

    if ((ret = create_env(progname, &dbenv)) != 0)
	goto err;

    /* Make APP_DATA available through the environment handle. */
    dbenv->app_private = &my_app_data;

    /* Default priority is 100. */
    dbenv->rep_set_priority(dbenv, 100);
    /* Permanent messages require at least one ack. */
    dbenv->repmgr_set_ack_policy(dbenv, DB_REPMGR_ACKS_ONE);
    /* Give 500 microseconds to receive the ack. */
    dbenv->rep_set_timeout(dbenv, DB_REP_ACK_TIMEOUT, 500);

    /* Collect the command line options. */
    while ((ch = getopt(argc, argv, "h:l:n:p:r:")) != EOF)
	switch (ch) {
	case 'h':
	    home = optarg;
	    break;
	/* Set the host and port used by this environment. */
	case 'l':
	    host = strtok(optarg, ":");
	    if ((portstr = strtok(NULL, ":")) == NULL) {
		fprintf(stderr, "Bad host specification.\n");
		goto err;
	    }
	    port = (unsigned short)atoi(portstr);
	    if (dbenv->repmgr_set_local_site(dbenv, host, port, 0) != 0) {
		fprintf(stderr,
		    "Could not set local address %s.\n", host);
		goto err;
	    }
	    local_is_set = 1;
	    break;
	/* Set the number of sites in this replication group. */
	case 'n':
	    totalsites = atoi(optarg);
	    if ((ret = dbenv->rep_set_nsites(dbenv, totalsites)) != 0)
		dbenv->err(dbenv, ret, "set_nsites");
	    break;
	/* Set this replica's election priority. */
	case 'p':
	    dbenv->rep_set_priority(dbenv, atoi(optarg));
	    break;
	/* Identify another site in the replication group. */
	case 'r':
	    host = strtok(optarg, ":");
	    if ((portstr = strtok(NULL, ":")) == NULL) {
		fprintf(stderr, "Bad host specification.\n");
		goto err;
	    }
	    port = (unsigned short)atoi(portstr);
	    if (dbenv->repmgr_add_remote_site(dbenv, host, port, 0, 0) != 0) {
		fprintf(stderr,
		    "Could not add site %s.\n", host);
		goto err;
	    }
	    break;
	case '?':
	default:
	    usage();
	}

    /* Error check command line. */
    if (home == NULL || !local_is_set || !totalsites)
	usage();

    if ((ret = env_init(dbenv, home)) != 0)
	goto err;

    if ((ret = dbenv->repmgr_start(dbenv, 3, DB_REP_ELECTION)) != 0)
	goto err;

    if ((ret = doloop(dbenv)) != 0) {
	dbenv->err(dbenv, ret, "Application failed");
	goto err;
    }

err: if (dbenv != NULL)
	(void)dbenv->close(dbenv, 0);

    return (ret);

}
Example #17
0
int
wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
{
	/*
	 * List of the WT_DATA_SOURCE methods -- it's static so it breaks at
	 * compile-time should the structure change underneath us.
	 */
	static WT_DATA_SOURCE wtds = {
		NULL,				/* No session.alter */
		kvs_session_create,		/* session.create */
		NULL,				/* No session.compaction */
		kvs_session_drop,		/* session.drop */
		kvs_session_open_cursor,	/* session.open_cursor */
		kvs_session_rename,		/* session.rename */
		NULL,				/* No session.salvage */
		NULL,				/* No session.size */
		kvs_session_truncate,		/* session.truncate */
		NULL,				/* No range_truncate */
		kvs_session_verify,		/* session.verify */
		NULL,				/* session.checkpoint */
		kvs_terminate,			/* termination */
		NULL				/* lsm_pre_merge */
	};
	DATA_SOURCE *ds;
	DB_ENV *dbenv;
	WT_EXTENSION_API *wt_api;
	size_t len;
	int ret = 0;
	const char *home;
	char *path;

	(void)config;				/* Unused parameters */

	ds = NULL;
	dbenv = NULL;
	path = NULL;
						/* Acquire the extension API */
	wt_api = connection->get_extension_api(connection);

	/* Allocate the local data-source structure. */
	if ((ds = calloc(1, sizeof(DATA_SOURCE))) == NULL)
		return (os_errno());
	ds->wt_api = wt_api;
						/* Configure the global lock */
	if ((ret = lock_init(wt_api, NULL, &ds->rwlock)) != 0)
		goto err;

	ds->wtds = wtds;			/* Configure the methods */

						/* Berkeley DB environment */
	if ((ret = db_env_create(&dbenv, 0)) != 0) {
		ESET(wt_api,
		    NULL, WT_ERROR, "db_env_create: %s", db_strerror(ret));
		goto err;
	}
	dbenv->set_errpfx(dbenv, "bdb");
	dbenv->set_errfile(dbenv, stderr);

	home = connection->get_home(connection);
	len = strlen(home) + 10;
	if ((path = malloc(len)) == NULL)
		goto err;
	(void)snprintf(path, len, "%s/KVS", home);
	if ((ret = dbenv->open(dbenv, path,
	    DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | DB_PRIVATE, 0)) != 0) {
		ESET(wt_api,
		    NULL, WT_ERROR, "DbEnv.open: %s", db_strerror(ret));
		goto err;
	}
	ds->dbenv = dbenv;

	if ((ret =				/* Add the data source */
	    connection->add_data_source(
	    connection, "kvsbdb:", (WT_DATA_SOURCE *)ds, NULL)) != 0) {
		ESET(wt_api, NULL, ret, "WT_CONNECTION.add_data_source");
		goto err;
	}

	if (0) {
err:		if (dbenv != NULL)
			(void)dbenv->close(dbenv, 0);
		free(ds);
	}
	free(path);
	return (ret);
}
Example #18
0
int
b_open(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB_ENV *dbenv;
	DB *dbp;
	DBTYPE type;
	int ch, i, count;
	char *fname, *dbname, *ts;

	type = DB_BTREE;
	count = 1000;
	fname = dbname = NULL;
	ts = "Btree";
	while ((ch = getopt(argc, argv, "c:dft:")) != EOF)
		switch (ch) {
		case 'c':
			count = atoi(optarg);
			break;
		case 'd':
			dbname = "dbname";
			break;
		case 'f':
			fname = "filename";
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (b_util_have_hash())
					return (0);
				ts = "Hash";
				type = DB_HASH;
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (usage());
			}
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

#if DB_VERSION_MAJOR < 4
	/*
	 * Don't run in-memory database tests on versions less than 3, it
	 * takes forever and eats memory.
	 */
	if (fname == NULL && dbname == NULL)
		return (0);
#endif
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 4
	/*
	 * Named in-memory databases weren't available until 4.4.
	 */
	if (fname == NULL && dbname != NULL)
		return (0);
#endif

	/* Create the environment. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
#endif

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);

#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
	DB_BENCH_ASSERT(dbp->open(
	    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbp->open(
	    dbp, fname, dbname, type, DB_CREATE, 0666) == 0);
#endif
	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	/* Open the database count times. */
	TIMER_START;
	for (i = 0; i < count; ++i) {
		DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
		DB_BENCH_ASSERT(dbp->open(
		    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0);
#else
		DB_BENCH_ASSERT(dbp->open(
		    dbp, fname, dbname, type, DB_CREATE, 0666) == 0);
#endif
		DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	}
	TIMER_STOP;

	printf("# %d %s %sdatabase open/close pairs\n",
	    count, ts,
	    fname == NULL ?
		(dbname == NULL ? "in-memory " : "named in-memory ") :
		(dbname == NULL ? "" : "sub-"));
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	return (0);
}
Example #19
0
void
op_tds(u_int ops, int update, u_int32_t flags)
{
	DB *dbp;
	DBT key, data;
	DB_ENV *dbenv;
	DB_TXN *txn;
	char *keybuf, *databuf;
	DB_MPOOL_STAT  *gsp;

	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL);

	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = keybuf;
	key.size = keysize;
	memset(keybuf, 'a', keysize);

	data.data = databuf;
	data.size = datasize;
	memset(databuf, 'b', datasize);

	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);

	dbenv->set_errfile(dbenv, stderr);

#ifdef DB_AUTO_COMMIT
	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0);
#endif
	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, flags, 1) == 0);
#ifdef DB_LOG_INMEMORY
	if (!(flags & DB_LOG_INMEMORY))
#endif
		DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0);
	DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0);
	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR",
	    DB_CREATE | DB_PRIVATE | DB_INIT_LOCK |
	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0);

	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
	DB_BENCH_ASSERT(
	    dbp->open(dbp, NULL, "a", NULL, DB_BTREE, DB_CREATE, 0666) == 0);

	if (update) {
		dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		TIMER_STOP;

		dbenv->memp_stat(dbenv, &gsp, NULL, 0);
		DB_BENCH_ASSERT(gsp->st_page_out == 0);
	} else {
		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
		dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops) {
			DB_BENCH_ASSERT(
			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(
			    dbp->get(dbp, NULL, &key, &data, 0) == 0);
			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
		}
		TIMER_STOP;

		dbenv->memp_stat(dbenv, &gsp, NULL, 0);
		DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
	}

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
}
Example #20
0
static int bdb_la_storage_object_store_delete(la_storage_object_store *store)
{
    const char *dbname;
    const char *seqdbname;
    const char *home;
    const char *parts[2];
    DB_TXN *txn;
    DB_ENV *env = store->env->env;
    int ret;
    
    if ((ret = store->db->get_dbname(store->db, &dbname, NULL)) != 0)
    {
        syslog(LOG_NOTICE, "could not get main db name: %d", ret);
        return -1;
    }
    if ((ret = store->db->get_dbname(store->seq_db, &seqdbname, NULL)) != 0)
    {
        syslog(LOG_NOTICE, "could not get sequence db name: %d", ret);
        return -1;
    }
    if ((ret = env->get_home(env, &home)) != 0)
    {
        syslog(LOG_NOTICE, "could not get db home %d", ret);
        return -1;
    }
    parts[0] = home;
    parts[1] = dbname;
    dbname = string_join("/", parts, 2);
    parts[1] = seqdbname;
    seqdbname = string_join("/", parts, 2);
    
    syslog(LOG_NOTICE, "deleting db %s and sequence db %s", dbname, seqdbname);
    
    la_storage_close(store);
    
    if ((ret = txn_begin(env, NULL, &txn, DB_TXN_NOWAIT | DB_TXN_WRITE_NOSYNC)) != 0)
    {
        syslog(LOG_NOTICE, "delete db begin transaction %d", ret);
        free(dbname);
        free(seqdbname);
        return -1;
    }
    
    syslog(LOG_NOTICE, "env %p txn %p home %s name %s", env, txn, home, dbname);
    
    if ((ret = env->dbremove(env, txn, dbname, NULL, 0)) != 0)
    {
        syslog(LOG_NOTICE, "deleting main DB: %d", ret);
        txn_abort(txn);
        return -1;
    }
    syslog(LOG_NOTICE, "env %p txn %p home %s name %s", env, txn, home, seqdbname);
    if ((ret = env->dbremove(env, txn, seqdbname, NULL, 0)) != 0)
    {
        syslog(LOG_NOTICE, "deleting sequence DB: %d", ret);
        txn_abort(txn);
        return -1;
    }
    txn_commit(txn, DB_TXN_NOSYNC);
    return 0;
}
int TestMpoolFilePreOpenSetterAndGetter(CuTest *ct) {
	DB_ENV *dbenv;
	DB_MPOOLFILE *mpf;
	u_int8_t get_fileid[DB_FILE_ID_LEN], set_fileid[DB_FILE_ID_LEN];
	DB_CACHE_PRIORITY cache_priorities[] = {
		DB_PRIORITY_VERY_LOW,
		DB_PRIORITY_LOW,
		DB_PRIORITY_DEFAULT,
		DB_PRIORITY_HIGH,
		DB_PRIORITY_VERY_HIGH
	};
	u_int32_t mpool_flags;
	size_t len;
	DBT pgcookie_get, pgcookie_set;
	
	CuAssert(ct, "db_env_create", create_dbenv_handle(&dbenv) == 0);
	CuAssert(ct, "dbenv->open", dbenv->open(dbenv, TEST_ENV,
	    DB_CREATE | DB_INIT_MPOOL, 0644) == 0);
	CuAssert(ct, "dbenv->memp_fcreate", create_mp_handle(&mpf, dbenv) == 0);

	/* Test DB_MPOOLFILE->set_clear_len(), DB_MPOOLFILE->get_clear_len(). */
	CHECK_1_DIGIT_VALUE(mpf, set_clear_len, get_clear_len,
	    u_int32_t, rand());

	/* Test DB_MPOOLFILE->set_fileid(), DB_MPOOLFILE->get_fileid(). */
	len = sizeof(DB_ENV) > DB_FILE_ID_LEN ? DB_FILE_ID_LEN : sizeof(DB_ENV);
	memset(get_fileid, 0, DB_FILE_ID_LEN);
	memcpy(set_fileid, dbenv, len);
	CuAssert(ct, "mpf->set_fileid", mpf->set_fileid(mpf, set_fileid) == 0);
	CuAssert(ct, "mpf->get_fileid", mpf->get_fileid(mpf, get_fileid) == 0);
	CuAssert(ct, "check fileid", memcmp(set_fileid, get_fileid, len) == 0);

	/* Test DB_MPOOLFILE->set_flags(), DB_MPOOLFILE->get_flags(). */
	mpool_flags = 0;
	CuAssert(ct, "mpf->set_flags",
	    mpf->set_flags(mpf, DB_MPOOL_NOFILE, 1) == 0);
	CuAssert(ct, "mpf->set_flags",
	    mpf->set_flags(mpf, DB_MPOOL_UNLINK, 1) == 0);
	CuAssert(ct, "mpf->get_flags",
	    mpf->get_flags(mpf, &mpool_flags) == 0);
	CuAssert(ct, "check flags",
	    mpool_flags == (DB_MPOOL_NOFILE | DB_MPOOL_UNLINK));
	CuAssert(ct, "mpf->set_flags",
	    mpf->set_flags(mpf, DB_MPOOL_NOFILE, 0) == 0);
	CuAssert(ct, "mpf->set_flags",
	    mpf->set_flags(mpf, DB_MPOOL_UNLINK, 0) == 0);
	CuAssert(ct, "mpf->get_flags", mpf->get_flags(mpf, &mpool_flags) == 0);
	CuAssert(ct, "check flags", mpool_flags == 0);

	/* Test DB_MPOOLFILE->set_ftype(), DB_MPOOLFILE->get_ftype(). */
	CHECK_1_DIGIT_VALUE(mpf, set_ftype, get_ftype, int, rand());

	/*
	 * Test DB_MPOOLFILE->set_lsn_offset(),
	 * DB_MPOOLFILE->get_lsn_offset().
	 */
	CHECK_1_DIGIT_VALUE(mpf, set_lsn_offset, get_lsn_offset,
	    int32_t, rand());

	/*
	 * Test DB_MPOOLFILE->set_maxsize(), DB_MPOOLFILE->get_maxsize().
	 * We use specific values to avoid adjustment.
	 */
	CHECK_2_DIGIT_VALUES(mpf, set_maxsize, get_maxsize,
	    u_int32_t, 2, u_int32_t, 1048576);

	/* Test DB_MPOOLFILE->set_pgcookie(), DB_MPOOLFILE->get_pgcookie(). */
	memset(&pgcookie_set, 0, sizeof(DBT));
	memset(&pgcookie_get, 0, sizeof(DBT));
	pgcookie_set.data = set_fileid;
	pgcookie_set.size = DB_FILE_ID_LEN;
	CuAssert(ct, "mpf->set_pgcookie",
	    mpf->set_pgcookie(mpf, &pgcookie_set) == 0);
	CuAssert(ct, "mpf->get_pgcookie",
	    mpf->get_pgcookie(mpf, &pgcookie_get) == 0);
	CuAssert(ct, "check pgcookie size",
	    pgcookie_get.size == pgcookie_set.size);
	CuAssert(ct, "check pgcookie data", memcmp(pgcookie_get.data,
	    pgcookie_set.data, pgcookie_set.size) == 0);

	/* Test DB_MPOOLFILE->set_priority(), DB_MPOOLFILE->get_priority(). */
	CHECK_1_DIGIT_VALUES(mpf, set_priority, get_priority, DB_CACHE_PRIORITY,
	    cache_priorities);

	CuAssert(ct, "mpf->close", close_mp_handle(mpf) == 0);
	CuAssert(ct, "dbenv->close", close_dbenv_handle(dbenv) == 0);
	return (0);
}
Example #22
0
File: t.c Project: kanbang/Colt
int
main()
{
	const u_int8_t *lk_conflicts;
	DB_ENV *dbenv;
	db_timeout_t timeout;
	u_int32_t a, b, c, v;
	int nmodes, lk_modes;
	u_int8_t conflicts[40];

	dbenv = NULL;

	/* tx_max: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_tx_max(dbenv, 37) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_TXN, 0666) == 0);
	assert(dbenv->get_tx_max(dbenv, &v) == 0);
	assert(v == 37);
	ENV
	assert(dbenv->set_tx_max(dbenv, 63) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_tx_max(dbenv, &v) == 0);
	assert(v == 37);

	/* lg_max: reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lg_max(dbenv, 37 * 1024 * 1024) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOG, 0666) == 0);
	assert(dbenv->get_lg_max(dbenv, &v) == 0);
	assert(v == 37 * 1024 * 1024);
	ENV
	assert(dbenv->set_lg_max(dbenv, 63 * 1024 * 1024) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lg_max(dbenv, &v) == 0);
	assert(v == 63 * 1024 * 1024);

	/* lg_bsize: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lg_bsize(dbenv, 37 * 1024) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOG, 0666) == 0);
	assert(dbenv->get_lg_bsize(dbenv, &v) == 0);
	assert(v == 37 * 1024);
	ENV
	assert(dbenv->set_lg_bsize(dbenv, 63 * 1024) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lg_bsize(dbenv, &v) == 0);
	assert(v == 37 * 1024);

	/* lg_regionmax: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lg_regionmax(dbenv, 137 * 1024) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOG, 0666) == 0);
	assert(dbenv->get_lg_regionmax(dbenv, &v) == 0);
	assert(v == 137 * 1024);
	ENV
	assert(dbenv->set_lg_regionmax(dbenv, 163 * 1024) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lg_regionmax(dbenv, &v) == 0);
	assert(v == 137 * 1024);

	/* lk_get_lk_conflicts: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	memset(conflicts, 'a', sizeof(conflicts));
	nmodes = 6;
	assert(dbenv->set_lk_conflicts(dbenv, conflicts, nmodes) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_lk_conflicts(dbenv, &lk_conflicts, &lk_modes) == 0);
	assert(lk_conflicts[0] == 'a');
	assert(lk_modes == 6);
	ENV
	memset(conflicts, 'b', sizeof(conflicts));
	nmodes = 8;
	assert(dbenv->set_lk_conflicts(dbenv, conflicts, nmodes) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lk_conflicts(dbenv, &lk_conflicts, &lk_modes) == 0);
	assert(lk_conflicts[0] == 'a');
	assert(lk_modes == 6);

	/* lk_detect: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lk_detect(dbenv, DB_LOCK_MAXLOCKS) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_lk_detect(dbenv, &v) == 0);
	assert(v == DB_LOCK_MAXLOCKS);
	ENV
	assert(dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lk_detect(dbenv, &v) == 0);
	assert(v == DB_LOCK_MAXLOCKS);

	/* lk_max_locks: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lk_max_locks(dbenv, 37) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_lk_max_locks(dbenv, &v) == 0);
	assert(v == 37);
	ENV
	assert(dbenv->set_lk_max_locks(dbenv, 63) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lk_max_locks(dbenv, &v) == 0);
	assert(v == 37);

	/* lk_max_lockers: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lk_max_lockers(dbenv, 37) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_lk_max_lockers(dbenv, &v) == 0);
	assert(v == 37);
	ENV
	assert(dbenv->set_lk_max_lockers(dbenv, 63) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lk_max_lockers(dbenv, &v) == 0);
	assert(v == 37);

	/* lk_max_objects: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_lk_max_objects(dbenv, 37) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_lk_max_objects(dbenv, &v) == 0);
	assert(v == 37);
	ENV
	assert(dbenv->set_lk_max_objects(dbenv, 63) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_lk_max_objects(dbenv, &v) == 0);
	assert(v == 37);

	/* lock timeout: reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_timeout(dbenv, 37, DB_SET_LOCK_TIMEOUT) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_timeout(dbenv, &timeout, DB_SET_LOCK_TIMEOUT) == 0);
	assert(timeout == 37);
	ENV
	assert(dbenv->set_timeout(dbenv, 63, DB_SET_LOCK_TIMEOUT) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_timeout(dbenv, &timeout, DB_SET_LOCK_TIMEOUT) == 0);
	assert(timeout == 63);

	/* txn timeout: reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_timeout(dbenv, 37, DB_SET_TXN_TIMEOUT) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_LOCK, 0666) == 0);
	assert(dbenv->get_timeout(dbenv, &timeout, DB_SET_TXN_TIMEOUT) == 0);
	assert(timeout == 37);
	ENV
	assert(dbenv->set_timeout(dbenv, 63, DB_SET_TXN_TIMEOUT) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_timeout(dbenv, &timeout, DB_SET_TXN_TIMEOUT) == 0);
	assert(timeout == 63);

	/* cache size: NOT reset at run-time. */
	system("rm -rf TESTDIR; mkdir TESTDIR");
	ENV
	assert(dbenv->set_cachesize(dbenv, 1, 37, 3) == 0);
	assert(dbenv->open(dbenv,
	    "TESTDIR", DB_CREATE | DB_INIT_MPOOL, 0666) == 0);
	assert(dbenv->get_cachesize(dbenv, &a, &b, &c) == 0);
	assert(a == 1 && b == 37 && c == 3);
	ENV
	assert(dbenv->set_cachesize(dbenv, 2, 63, 1) == 0);
	assert(dbenv->open(dbenv, "TESTDIR", DB_JOINENV, 0666) == 0);
	assert(dbenv->get_cachesize(dbenv, &a, &b, &c) == 0);
	assert(a == 1 && b == 37 && c == 3);

	return (0);
}
Example #23
0
File: db3.c Project: xrg/RPM
static int db3close(dbiIndex dbi, unsigned int flags)
{
    rpmdb rpmdb = dbi->dbi_rpmdb;
    const char * root;
    const char * home;
    char * dbhome;
    const char * dbfile;
    const char * dbsubfile;
    DB * db = dbi->dbi_db;
    int _printit;
    int rc = 0, xx;

    flags = 0;	/* XXX unused */

    /*
     * Get the prefix/root component and directory path.
     */
    root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
    if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
	root = NULL;
    home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);

    dbhome = rpmGenPath(root, home, NULL);
    if (dbi->dbi_temporary) {
	dbfile = NULL;
	dbsubfile = NULL;
    } else {
#ifdef	HACK	/* XXX necessary to support dbsubfile */
	dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
	dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : rpmTagGetName(dbi->dbi_rpmtag));
#else
	dbfile = (dbi->dbi_file ? dbi->dbi_file : rpmTagGetName(dbi->dbi_rpmtag));
	dbsubfile = NULL;
#endif
    }

    if (db) {
	rc = db->close(db, 0);
	/* XXX ignore not found error messages. */
	_printit = (rc == ENOENT ? 0 : _debug);
	rc = cvtdberr(dbi, "db->close", rc, _printit);
	db = dbi->dbi_db = NULL;

	rpmlog(RPMLOG_DEBUG, "closed   db index       %s/%s\n",
		dbhome, (dbfile ? dbfile : rpmTagGetName(dbi->dbi_rpmtag)));

    }

    if (rpmdb->db_dbenv != NULL && dbi->dbi_use_dbenv) {
	if (rpmdb->db_opens == 1) {
	    xx = db_fini(dbi, (dbhome ? dbhome : ""), dbfile, dbsubfile);
	    rpmdb->db_dbenv = NULL;
	}
	rpmdb->db_opens--;
    }

    if (dbi->dbi_verify_on_close && !dbi->dbi_temporary) {
	DB_ENV * dbenv = NULL;

	rc = db_env_create(&dbenv, 0);
	rc = cvtdberr(dbi, "db_env_create", rc, _debug);
	if (rc || dbenv == NULL) goto exit;

	dbenv->set_errcall(dbenv, (void *) rpmdb->db_errcall);
	dbenv->set_errfile(dbenv, rpmdb->db_errfile);
	dbenv->set_errpfx(dbenv, rpmdb->db_errpfx);
 /*	dbenv->set_paniccall(???) */
#if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
	xx = dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT,
		(dbi->dbi_verbose & DB_VERB_CHKPOINT));
#endif
	xx = dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
		(dbi->dbi_verbose & DB_VERB_DEADLOCK));
	xx = dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
		(dbi->dbi_verbose & DB_VERB_RECOVERY));
	xx = dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
		(dbi->dbi_verbose & DB_VERB_WAITSFOR));

	if (dbi->dbi_tmpdir) {
	    char * tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
	    rc = dbenv->set_tmp_dir(dbenv, tmpdir);
	    rc = cvtdberr(dbi, "dbenv->set_tmp_dir", rc, _debug);
	    tmpdir = _free(tmpdir);
	    if (rc) goto exit;
	}
	    
	rc = (dbenv->open)(dbenv, dbhome,
            DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0);
	rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
	if (rc) goto exit;

	rc = db_create(&db, dbenv, 0);
	rc = cvtdberr(dbi, "db_create", rc, _debug);

	if (db != NULL) {
		char * dbf = rpmGetPath(dbhome, "/", dbfile, NULL);

		rc = db->verify(db, dbf, NULL, NULL, flags);
		rc = cvtdberr(dbi, "db->verify", rc, _debug);

		rpmlog(RPMLOG_DEBUG, "verified db index       %s/%s\n",
			(dbhome ? dbhome : ""),
			(dbfile ? dbfile : rpmTagGetName(dbi->dbi_rpmtag)));

	        /*
		 * The DB handle may not be accessed again after
		 * DB->verify is called, regardless of its return.
		 */
		db = NULL;
		dbf = _free(dbf);
	}
	xx = dbenv->close(dbenv, 0);
	xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
	if (rc == 0 && xx) rc = xx;
    }

exit:
    dbi->dbi_db = NULL;

    free(dbhome);

    dbi = db3Free(dbi);

    return rc;
}
Example #24
0
int main(int argc, char *argv[])
{

DB_ENV *myEnv; /* Env structure handle */
DB *dbp; /* DB structure handle */
u_int32_t db_flags; /* database open flags */
u_int32_t env_flags; /* env open flags */
int ret; /* function return value */
/*
Create an environment object and initialize it for error
reporting.
*/
ret = db_env_create(&myEnv, 0);
if (ret != 0) {
fprintf(stderr, "Error creating env handle: %s\n", db_strerror(ret));
return -1;
}
/* Open the environment. */
env_flags = DB_CREATE | /* If the environment does not exist,
* create it. */
DB_INIT_MPOOL; /* Initialize the in-memory cache. */
ret = myEnv->open(myEnv, /* DB_ENV ptr */
"/export1/testEnv", /* env home directory */
env_flags, /* Open flags */
0); /* File mode (default) */
if (ret != 0) {
fprintf(stderr, "Environment open failed: %s", db_strerror(ret));
return -1;
}

/*
Once an environment is opened, you can open databases in it. Note that by default databases
are stored in the environment's home directory, or relative to that directory if you provide any
sort of a path in the database's file name:
Library Version 11.2.5.3 Databases
12/19/2011 Getting Started with DB Page 16
/*
* Initialize the DB structure. Pass the pointer
* to the environment in which this DB is opened.
*/
ret = db_create(&dbp, myEnv, 0);
if (ret != 0) {
/* Error handling goes here */
}
/* Database open flags */
db_flags = DB_CREATE; /* If the database does not exist,
* create it.*/
/* open the database */
ret = dbp->open(dbp, /* DB structure pointer */
NULL, /* Transaction pointer */
"my_db.db", /* On-disk file that holds the database. */
NULL, /* Optional logical database name */
DB_BTREE, /* Database access method */
db_flags, /* Open flags */
0); /* File mode (using defaults) */
if (ret != 0) {
/* Error handling goes here */
}

/*
When you are done with an environment, you must close it. It is recommended that before
closing an environment, you close any open databases.
*/
/*
* Close the database and environment
*/
if (dbp != NULL) {
dbp->close(dbp, 0);
}
if (myEnv != NULL) {
myEnv->close(myEnv, 0);
}

}
Example #25
0
static void
op_tds(u_int ops, int update, u_int32_t env_flags, u_int32_t log_flags)
{
	DB *dbp;
	DBT key, data;
	DB_ENV *dbenv;
	DB_MPOOL_STAT  *gsp;
	DB_TXN *txn;
	char *keybuf, *databuf;

	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL);

	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = keybuf;
	key.size = keysize;
	memset(keybuf, 'a', keysize);

	data.data = databuf;
	data.size = datasize;
	memset(databuf, 'b', datasize);

	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);

	dbenv->set_errfile(dbenv, stderr);

	/* General environment configuration. */
#ifdef DB_AUTO_COMMIT
	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0);
#endif
	if (env_flags != 0)
		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, env_flags, 1) == 0);

	/* Logging configuration. */
	if (log_flags != 0)
#if DB_VERSION_MINOR >= 7 || DB_VERSION_MAJOR > 4
		DB_BENCH_ASSERT(
		    dbenv->log_set_config(dbenv, log_flags, 1) == 0);
#else
		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, log_flags, 1) == 0);
#endif
#ifdef DB_LOG_INMEMORY
	if (!(log_flags & DB_LOG_INMEMORY))
#endif
#ifdef DB_LOG_IN_MEMORY
	if (!(log_flags & DB_LOG_IN_MEMORY))
#endif
		DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0);
	DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0);

	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR",
	    DB_CREATE | DB_PRIVATE | DB_INIT_LOCK |
	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0);

	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
	DB_BENCH_ASSERT(dbp->open(
	    dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);

	if (update) {
		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		TIMER_STOP;

		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
			DB_BENCH_ASSERT(gsp->st_page_out == 0);
	} else {
		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops) {
			DB_BENCH_ASSERT(
			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(
			    dbp->get(dbp, NULL, &key, &data, 0) == 0);
			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
		}
		TIMER_STOP;

		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
			DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
	}

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
}
Example #26
0
/*
 *  This should be done before the program is open for business.
 *  As such, it does not need to be reentrant.
 */
int
open_db_env(char *topdir)
{
	DB_ENV		*tmpenv = NULL;
	int		st;
	struct stat64	sbuf;
	char		logdir[MAXPATHLEN+1];
	char		tmpdir[MAXPATHLEN+1];
	char		*dirarr[3];
	int		i;

	if (topdir == NULL) {
		return (-1);
	}

	snprintf(logdir, sizeof (tmpdir), "%s/.logs", topdir);
	snprintf(tmpdir, sizeof (tmpdir), "%s/.tmp", topdir);

	dirarr[0] = topdir;
	dirarr[1] = logdir;
	dirarr[2] = tmpdir;

	/* first, set up the environment */
	st = db_env_create(&tmpenv, 0);

	if (st != 0) {
		return (st);
	}

	/* make sure the directories exist */
	for (i = 0; i < 3; i++) {
		st = stat64(dirarr[i], &sbuf);
		if ((st != 0) && (errno == ENOENT)) {
			st = mkdirp(dirarr[i], 0744);
			if (st == 0) {
				st = stat64(dirarr[i], &sbuf);
			}
		}
		if ((st == 0) && (!S_ISDIR(sbuf.st_mode))) {
			st = -1;
			break;
		}
	}

	if (st != 0) {
		return (st);
	}

	st = tmpenv->set_data_dir(tmpenv, topdir);
	if (st != 0) {
		return (st);
	}
	st = tmpenv->set_lg_dir(tmpenv, logdir);
	if (st != 0) {
		return (st);
	}

	st = tmpenv->set_tmp_dir(tmpenv, tmpdir);
	if (st != 0) {
		return (st);
	}

	st = tmpenv->set_flags(tmpenv, env_fl, 1);
	if (st != 0) {
		return (st);
	}

	/* overall database cache size */
	st = tmpenv->set_cachesize(tmpenv, 0, (60 * MEGA), 1);

	st = tmpenv->set_shm_key(tmpenv, FSM_SHM_MASTER_KEY);
	if (st != 0) {
		return (st);
	}

	/* log buffer in memory */
	st = tmpenv->set_lg_bsize(tmpenv, (30 * MEGA));
	if (st != 0) {
		return (st);
	}

	/* set up additional error logging */
	tmpenv->set_errcall(tmpenv, fsmdb_log_err);

	/* Increase the number of locks available */
	tmpenv->set_lk_max_locks(tmpenv, 10000);
	tmpenv->set_lk_max_lockers(tmpenv, 10000);
	tmpenv->set_lk_max_objects(tmpenv, 10000);

	/* Increase the number of concurrent transactions available */
	/* Note:  Default in 4.4-20 is '20'.  In later versions it's 100 */
	tmpenv->set_tx_max(tmpenv, 100);

	st = tmpenv->open(tmpenv, topdir, env_ofl, 0644);
	if (st != 0) {
		/* check for a major failure */
		if (st == DB_RUNRECOVERY) {
			st = tmpenv->open(tmpenv, topdir, env_ffl, 0644);
		}
		/* log catastrophic failure and remove all db files. */
		if (st == DB_RUNRECOVERY) {
			fsmdb_log_err(dbEnv, NULL,
			    "Database files corrupt, cannot recover.  "
			    "Files will be removed.  Please re-index any "
			    "recovery points to regenerate the database.");
			fsmdb_remove_all(topdir);
		}
	}

	if (st != 0) {
		return (st);
	}

	/* clear out unneeded log files */
	tmpenv->log_archive(tmpenv, NULL, DB_ARCH_REMOVE);

	/* all set, ready to use */
	dbEnv = tmpenv;

	return (st);
}
Example #27
0
void *
trickle_thread(void *arg)
{
    DB_ENV *dbenv;
    int ret;
    int my_pid = (int)getpid();

    dbenv = arg;
    
    if(init_log(my_pid))
    {  
	exit(1);
    }
    
    write_log("TRICKLE %d: starting\n", my_pid);


    /* Trickle every 5 seconds. */
    for (;; poll(0,0,5000))
    {
	int nwritten = 0;
	switch (ret = dbenv->memp_trickle(dbenv, CLEAN_PERCENT, &nwritten)) 
	{
	case 0:
	  write_log("TRICKLE %d: write %d pages\n", my_pid, nwritten);
	  break;
	default:
	    write_log("TRICKLE %d: trickle error - %s\n",
		      my_pid, db_strerror(ret));
	    break;
	}
	
	if(pthread_mutex_lock(&trickle_mutex))
	{
	    write_log("TRICKLE %d: pthread_mutex_lock error - %s\n",
		      my_pid, strerror(errno));
	    goto error;
	}
	
	if(trickle_exit_flag)
	{
	    /* The thread was told to exit */
	    if(pthread_mutex_unlock(&trickle_mutex))
	    {
		write_log("TRICKLE %d: pthread_mutex_unlock error - %s\n",
			  my_pid, strerror(errno));
		goto error;
	    }
	    write_log("TRICKLE %d: exiting gracefully\n", my_pid);
	    goto done;
	}
	if(pthread_mutex_unlock(&trickle_mutex))
	{
	    write_log("TRICKLE %d: pthread_mutex_unlock error - %s\n",
		      my_pid, strerror(errno));
	    goto error;
	}
    }
    
 error:
    write_log("TRICKLE %d: exiting from ERROR\n", my_pid);
 done:
    return (void *)0;
}
Example #28
0
int
cache_init(cache_t *c, void (*freevalue)(void *value))
{
	memset(c, '\0', sizeof(*c));

	int ret;


	DB_ENV *dbenv;

  	ret = db_env_create(&dbenv, 0);
  	      dbenv->err(dbenv,ret,"err db_env_create ");

	dbenv->set_errfile(dbenv, stderr);
		dbenv->err(dbenv,ret,"err set_errfile ");

        if ((ret = dbenv->set_shm_key(dbenv, 664)) != 0) {
		dbenv->err(dbenv,ret,"err set_shm_key ");

		return 0;
        }


  	ret = dbenv->open(dbenv,bfile(_temp_path),DB_CREATE | DB_INIT_MPOOL | DB_INIT_CDB ,0);
  	     dbenv->err(dbenv,ret,"err db_env_open ");


        /* Create and initialize database object */
        if ((ret = db_create(&c->c_data, dbenv, 0)) != 0) {
                fprintf(stderr,
                     "%s: db_create: %s\n", "bbdocument", db_strerror(ret));
 		return 0;
        }


	#ifdef DEBUG
	dbenv->stat_print(dbenv, DB_STAT_ALL);
	#endif

        /* open the database. */
        if ((ret = c->c_data->open(c->c_data, NULL, "libcachedb", NULL, DB_BTREE, DB_CREATE, 0)) != 0) {
                        c->c_data->err(c->c_data, ret, "db open");
                        //goto err1;
                        //dette skjer nor collection mappen ikke er opprettet enda, typisk forde vi ikke har lagret et dokument der enda
                        #ifdef DEBUG
                        printf("can't dbp->open(), but db_create() was sucessful!\n");
                        #endif

                        return 0;
        }


	#ifdef DEBUG
	c->c_data->stat_print(c->c_data, DB_STAT_ALL);
	#endif

	pthread_mutex_init(&c->c_lock, NULL);
	c->c_freevalue = freevalue;

	return 1;
}
Example #29
0
/*
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
** a pointer to the new sqlite3_backup object.
**
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
** pDestDb  Database to write to
** zDestDb  Name of database within pDestDb
** pSrcDb   Database connection to read from
** zSrcDb   Name of database within pSrcDb
*/
sqlite3_backup *sqlite3_backup_init(sqlite3* pDestDb, const char *zDestDb,
    sqlite3* pSrcDb, const char *zSrcDb)
{
	sqlite3_backup *p;                    /* Value to return */
	Parse parse;
	DB_ENV *dbenv;
	int ret;

	p = NULL;
	ret = 0;

	if (!pDestDb || !pSrcDb)
		return 0;

	sqlite3_mutex_enter(pSrcDb->mutex);
	sqlite3_mutex_enter(pDestDb->mutex);
	if (pSrcDb == pDestDb) {
		sqlite3Error(pDestDb, SQLITE_ERROR,
		    "source and destination must be distinct");
		goto err;
	}

	/* Allocate space for a new sqlite3_backup object */
	p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
	if (!p) {
		sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
		goto err;
	}

	memset(p, 0, sizeof(sqlite3_backup));
	p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
	p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
	p->pDestDb = pDestDb;
	p->pSrcDb = pSrcDb;

	if (0 == p->pSrc) {
		p->rc = p->pSrcDb->errCode;
		goto err;
	}
	if (0 == p->pDest) {
		p->rc = p->pDestDb->errCode;
		goto err;
	}

	p->iDb = sqlite3FindDbName(pDestDb, zDestDb);

	p->srcName = sqlite3_malloc((int)strlen(zSrcDb) + 1);
	p->destName = sqlite3_malloc((int)strlen(zDestDb) + 1);
	if (0 == p->srcName || 0 == p->destName) {
		p->rc = SQLITE_NOMEM;
		goto err;
	}
	strncpy(p->srcName, zSrcDb, strlen(zSrcDb) + 1);
	strncpy(p->destName, zDestDb, strlen(zDestDb) + 1);

	if (p->pDest->pBt->full_name) {
		const char *fullName = p->pDest->pBt->full_name;
		p->fullName = sqlite3_malloc((int)strlen(fullName) + 1);
		if (!p->fullName) {
			p->rc = SQLITE_NOMEM;
			goto err;
		}
		strncpy(p->fullName, fullName, strlen(fullName) + 1);
	}

	/*
	 * Make sure the schema has been read in, so the keyInfo
	 * can be retrieved for the indexes.  No-op if already read.
	 */
	memset(&parse, 0, sizeof(parse));
	parse.db = p->pSrcDb;
	p->rc = sqlite3ReadSchema(&parse);
	if (p->rc != SQLITE_OK) {
		if (parse.zErrMsg != NULL)
			sqlite3DbFree(p->pSrcDb, parse.zErrMsg);
		goto err;
	}

	/* Begin a transaction on the source. */
	if (!p->pSrc->connected) {
		if ((p->rc = btreeOpenEnvironment(p->pSrc, 1)) != SQLITE_OK)
			goto err;
	}
	dbenv = p->pSrc->pBt->dbenv;
	p->rc = dberr2sqlite(dbenv->txn_begin(dbenv, p->pSrc->family_txn,
	    &p->srcTxn, 0), NULL);
	if (p->rc != SQLITE_OK) {
		sqlite3Error(pSrcDb, p->rc, 0);
		goto err;
	}

	/*
	 * Get the page count and list of tables to copy. This will
	 * result in a read lock on the schema table, held in the
	 * read transaction.
	 */
	if ((p->rc = btreeGetPageCount(p->pSrc,
	    &p->tables, &p->nPagecount, p->srcTxn)) != SQLITE_OK) {
		sqlite3Error(pSrcDb, p->rc, 0);
		goto err;
	}

	p->nRemaining = p->nPagecount;
	p->pSrc->nBackup++;
	p->pDest->nBackup++;
	p->lastUpdate = p->pSrc->updateDuringBackup;

	goto done;

err:	if (p != 0) {
		if (pDestDb->errCode == SQLITE_OK)
			sqlite3Error(pDestDb, p->rc, 0);
		if (p->srcTxn)
			p->srcTxn->abort(p->srcTxn);
		if (p->srcName != 0)
			sqlite3_free(p->srcName);
		if (p->destName != 0)
			sqlite3_free(p->destName);
		if (p->fullName != 0)
			sqlite3_free(p->fullName);
		if (p->tables != 0)
			sqlite3_free(p->tables);
		sqlite3_free(p);
		p = NULL;
	}
done:	sqlite3_mutex_leave(pDestDb->mutex);
	sqlite3_mutex_leave(pSrcDb->mutex);
	return p;
}
Example #30
0
int TestKeyExistErrorReturn(CuTest *ct) {
	DB *pdbp;
	DB *sdbp;
	DB_ENV *dbenv;

	const char *sec_db_file = "secondary.db";
	const char *pri_db_file = "primary.db";
	const char *env_dir = "TESTDIR";
	int i;
	thread_t writer_threads[NUMWRITERS];
	u_int32_t db_flags, env_flags;

	pdbp = sdbp = NULL;
	dbenv = NULL;
	db_flags = DB_CREATE | DB_AUTO_COMMIT | DB_READ_UNCOMMITTED;
	env_flags = DB_CREATE | DB_RECOVER | DB_INIT_LOCK | DB_INIT_LOG |
	    DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD;

	TestEnvConfigTestSetup(ct);

	CuAssert(ct, "db_env_create", db_env_create(&dbenv, 0) == 0);

	dbenv->set_errfile(dbenv, stderr);
	dbenv->set_errpfx(dbenv, "TestKeyExistErrorReturn");

	/* Run deadlock detector on every lock conflict. */
	CuAssert(ct, "dbenv->set_lk_detect",
	    dbenv->set_lk_detect(dbenv, DB_LOCK_MINWRITE) == 0);

	CuAssert(ct, "dbenv->open",
	    dbenv->open(dbenv, env_dir, env_flags, 0) == 0);

	CuAssert(ct, "db_create", db_create(&pdbp, dbenv, 0) == 0);
	CuAssert(ct, "pdbp->open", pdbp->open(pdbp, NULL,
	    pri_db_file, NULL, DB_BTREE, db_flags, 0) == 0);

	CuAssert(ct, "db_create", db_create(&sdbp, dbenv, 0) == 0);
	CuAssert(ct, "sdbp->set_flags", sdbp->set_flags(sdbp,
	    DB_DUPSORT) == 0);
	CuAssert(ct, "sdbp->open", sdbp->open(sdbp, NULL, sec_db_file,
	    NULL, DB_BTREE, db_flags, 0) == 0);

	CuAssert(ct, "DB->associate", pdbp->associate(pdbp, NULL, sdbp,
	    assoc_callback, DB_AUTO_COMMIT) == 0);

	/* Initialize a mutex. Used to help provide thread ids. */
	(void)mutex_init(&thread_num_lock, NULL);

	for (i = 0; i < NUMWRITERS; ++i)
		(void)thread_create(&writer_threads[i], NULL,
		    writer_thread, (void *)pdbp);

	for (i = 0; i < NUMWRITERS; ++i)
		(void)thread_join(writer_threads[i], NULL);

	if (sdbp != NULL) 
		CuAssert(ct, "sdbp->close", sdbp->close(sdbp, 0) == 0);
	if (pdbp != NULL)
		CuAssert(ct, "pdbp->close", pdbp->close(pdbp, 0) == 0);
	if (dbenv != NULL)
		CuAssert(ct, "dbenv->close", dbenv->close(dbenv, 0) == 0);

	TestEnvConfigTestTeardown(ct);

	return (EXIT_SUCCESS);
}