void obj_create_unique(int force) { WT_SESSION *session; int ret; char new_uri[64]; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "conn.session"); /* Generate a unique object name. */ if ((ret = pthread_rwlock_wrlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_wrlock single"); testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%u", uri, ++uid)); if ((ret = pthread_rwlock_unlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_unlock single"); if ((ret = session->create(session, new_uri, config)) != 0) testutil_die(ret, "session.create"); __wt_yield(); while ((ret = session->drop( session, new_uri, force ? "force" : NULL)) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); if ((ret = session->close(session, NULL)) != 0) testutil_die(ret, "session.close"); }
/* * Create a guaranteed unique table and open and close a bulk cursor on it. */ void op_bulk_unique(void *arg) { TEST_OPTS *opts; TEST_PER_THREAD_OPTS *args; WT_CURSOR *c; WT_RAND_STATE rnd; WT_SESSION *session; int ret; char new_uri[64]; args = (TEST_PER_THREAD_OPTS *)arg; opts = args->testopts; __wt_random_init_seed(NULL, &rnd); testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); /* Generate a unique object name. */ testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%" PRIu64, opts->uri, __wt_atomic_add64(&opts->unique_id, 1))); testutil_check(session->create(session, new_uri, DEFAULT_TABLE_SCHEMA)); __wt_yield(); /* * Opening a bulk cursor may have raced with a forced checkpoint * which created a checkpoint of the empty file, and triggers an EINVAL. */ if ((ret = session->open_cursor( session, new_uri, NULL, "bulk,checkpoint_wait=false", &c)) == 0) { testutil_check(c->close(c)); } else if (ret != EINVAL && ret != EBUSY) testutil_die(ret, "session.open_cursor bulk unique: %s", new_uri); while ((ret = session->drop(session, new_uri, __wt_random(&rnd) & 1 ? "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); else /* * The EBUSY is expected when we run with * checkpoint_wait set to false, so we increment the * counter while in this loop to avoid false positives. */ args->thread_counter++; testutil_check(session->close(session, NULL)); args->thread_counter++; }
int main(int argc, char *argv[]) { int ret; WT_CONNECTION *conn; WT_SESSION *session; (void)argc; (void)argv; fprintf(stderr, SEPARATOR "wiredtiger_open\n"); if ((ret = wiredtiger_open(".", NULL, "create", &conn)) != 0) fail(ret); usleep(100); fflush(stderr); fprintf(stderr, SEPARATOR "open_session\n"); fflush(stderr); if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) fail(ret); usleep(100); fflush(stderr); fprintf(stderr, SEPARATOR "create\n"); fflush(stderr); if ((ret = session->create( session, "table:hello", "key_format=S,value_format=S")) != 0) fail(ret); usleep(100); fprintf(stderr, SEPARATOR "rename\n"); if ((ret = session->rename( session, "table:hello", "table:world", NULL)) != 0) fail(ret); fflush(stdout); fprintf(stderr, SEPARATOR "drop\n"); fflush(stdout); if ((ret = session->drop(session, "table:world", NULL)) != 0) fail(ret); fprintf(stderr, SEPARATOR "WT_CONNECTION::close\n"); if ((ret = conn->close(conn, NULL)) != 0) fail(ret); return (0); }
void obj_drop(void) { WT_SESSION *session; int ret; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) die("conn.session", ret); if ((ret = session->drop(session, uri, NULL)) != 0) if (ret != ENOENT && ret != EBUSY) die("session.drop", ret); if ((ret = session->close(session, NULL)) != 0) die("session.close", ret); }
void obj_drop(int force) { WT_SESSION *session; int ret; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "conn.session"); if ((ret = session->drop(session, uri, force ? "force" : NULL)) != 0) if (ret != ENOENT && ret != EBUSY) testutil_die(ret, "session.drop"); if ((ret = session->close(session, NULL)) != 0) testutil_die(ret, "session.close"); }
void obj_bulk_unique(int force) { WT_CURSOR *c; WT_SESSION *session; int ret; char new_uri[64]; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "conn.session"); /* Generate a unique object name. */ if ((ret = pthread_rwlock_wrlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_wrlock single"); testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%u", uri, ++uid)); if ((ret = pthread_rwlock_unlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_unlock single"); if ((ret = session->create(session, new_uri, config)) != 0) testutil_die(ret, "session.create: %s", new_uri); __wt_yield(); /* * Opening a bulk cursor may have raced with a forced checkpoint * which created a checkpoint of the empty file, and triggers an EINVAL */ if ((ret = session->open_cursor( session, new_uri, NULL, "bulk", &c)) == 0) { if ((ret = c->close(c)) != 0) testutil_die(ret, "cursor.close"); } else if (ret != EINVAL) testutil_die(ret, "session.open_cursor bulk unique: %s, new_uri"); while ((ret = session->drop( session, new_uri, force ? "force" : NULL)) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); if ((ret = session->close(session, NULL)) != 0) testutil_die(ret, "session.close"); }
int setup(char *name, const char *kf, const char *vf, const char *cconfig, WT_CURSOR **cursor){ WT_SESSION *session; int creating, ret; char tconfig[64]; creating = (kf != NULL); if((ret = wiredtiger_open(NULL, NULL, "create", &conn) != 0) || (ret = conn->open_session(conn, NULL, NULL, &session)) != 0) return ret; /* If we get a configuration, create the table. */ if(creating) { (void)session->drop(session, name, "force"); snprintf(tconfig, sizeof(tconfig), "key_format=%s,value_format=%s", kf, vf); if ((ret = session->create(session, name, tconfig)) != 0) return ret; } return session->open_cursor(session, name, NULL, cconfig, cursor); }
/* * Create and drop a unique guaranteed table. */ void op_create_unique(void *arg) { TEST_OPTS *opts; TEST_PER_THREAD_OPTS *args; WT_RAND_STATE rnd; WT_SESSION *session; int ret; char new_uri[64]; args = (TEST_PER_THREAD_OPTS *)arg; opts = args->testopts; __wt_random_init_seed(NULL, &rnd); testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); /* Generate a unique object name. */ testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%" PRIu64, opts->uri, __wt_atomic_add64(&opts->unique_id, 1))); testutil_check(session->create(session, new_uri, DEFAULT_TABLE_SCHEMA)); __wt_yield(); while ((ret = session->drop(session, new_uri, __wt_random(&rnd) & 1 ? "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); else /* * The EBUSY is expected when we run with * checkpoint_wait set to false, so we increment the * counter while in this loop to avoid false positives. */ args->thread_counter++; testutil_check(session->close(session, NULL)); args->thread_counter++; }
/* * Drop a table. */ void op_drop(void *arg) { TEST_OPTS *opts; TEST_PER_THREAD_OPTS *args; WT_RAND_STATE rnd; WT_SESSION *session; int ret; args = (TEST_PER_THREAD_OPTS *)arg; opts = args->testopts; __wt_random_init_seed(NULL, &rnd); testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); if ((ret = session->drop(session, opts->uri, __wt_random(&rnd) & 1 ? "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0) if (ret != ENOENT && ret != EBUSY) testutil_die(ret, "session.drop"); testutil_check(session->close(session, NULL)); args->thread_counter++; }
static void * ops(void *arg) { TINFO *tinfo; WT_CONNECTION *conn; WT_CURSOR *cursor, *cursor_insert; WT_SESSION *session; WT_ITEM key, value; uint64_t cnt, keyno, sync_op, thread_ops; uint32_t op; uint8_t *keybuf, *valbuf; u_int np; int dir, insert, notfound, ret, sync_drop; char sync_name[64]; conn = g.wts_conn; tinfo = arg; /* Set up the default key and value buffers. */ memset(&key, 0, sizeof(key)); key_gen_setup(&keybuf); memset(&value, 0, sizeof(value)); val_gen_setup(&valbuf); /* Open a session. */ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) die(ret, "connection.open_session"); /* * Open two cursors: one configured for overwriting and one configured * for append if we're dealing with a column-store. * * The reason is when testing with existing records, we don't track if * a record was deleted or not, which means we must use cursor->insert * with overwriting configured. But, in column-store files where we're * testing with new, appended records, we don't want to have to specify * the record number, which requires an append configuration. */ cursor = cursor_insert = NULL; if ((ret = session->open_cursor(session, WT_TABLENAME, NULL, "overwrite", &cursor)) != 0) die(ret, "session.open_cursor"); if ((g.c_file_type == FIX || g.c_file_type == VAR) && (ret = session->open_cursor(session, WT_TABLENAME, NULL, "append", &cursor_insert)) != 0) die(ret, "session.open_cursor"); /* Each thread does its share of the total operations. */ thread_ops = g.c_ops / g.c_threads; /* Pick an operation where we'll do a sync and create the name. */ sync_drop = 0; sync_op = MMRAND(1, thread_ops); snprintf(sync_name, sizeof(sync_name), "snapshot=thread-%d", tinfo->id); for (cnt = 0; cnt < thread_ops; ++cnt) { if (SINGLETHREADED && cnt % 100 == 0) track("read/write ops", 0ULL, tinfo); if (cnt == sync_op) { if (sync_drop && (int)MMRAND(1, 4) == 1) { if ((ret = session->drop( session, WT_TABLENAME, sync_name)) != 0) die(ret, "session.drop: %s: %s", WT_TABLENAME, sync_name); sync_drop = 0; } else { if ((ret = session->checkpoint( session, sync_name)) != 0) die(ret, "session.checkpoint: %s", sync_name); sync_drop = 1; } /* * Pick the next sync operation, try for roughly five * snapshot operations per thread run. */ sync_op += MMRAND(1, thread_ops) / 5; } insert = notfound = 0; keyno = MMRAND(1, g.rows); key.data = keybuf; value.data = valbuf; /* * Perform some number of operations: the percentage of deletes, * inserts and writes are specified, reads are the rest. The * percentages don't have to add up to 100, a high percentage * of deletes will mean fewer inserts and writes. A read * operation always follows a modification to confirm it worked. */ op = (uint32_t)(wts_rand() % 100); if (op < g.c_delete_pct) { ++tinfo->remove; switch (g.c_file_type) { case ROW: /* * If deleting a non-existent record, the cursor * won't be positioned, and so can't do a next. */ row_remove(cursor, &key, keyno, ¬found); break; case FIX: case VAR: col_remove(cursor, &key, keyno, ¬found); break; } } else if (op < g.c_delete_pct + g.c_insert_pct) { ++tinfo->insert; switch (g.c_file_type) { case ROW: row_update(cursor, &key, &value, keyno, 1); break; case FIX: case VAR: /* * Reset the standard cursor so it doesn't keep * pages pinned. */ if ((ret = cursor->reset(cursor)) != 0) die(ret, "cursor.reset"); col_insert(cursor_insert, &key, &value, &keyno); insert = 1; break; } } else if ( op < g.c_delete_pct + g.c_insert_pct + g.c_write_pct) { ++tinfo->update; switch (g.c_file_type) { case ROW: row_update(cursor, &key, &value, keyno, 0); break; case FIX: case VAR: col_update(cursor, &key, &value, keyno); break; } } else { ++tinfo->search; read_row(cursor, &key, keyno); continue; } /* * If we did any operation, we've set the cursor, do a small * number of next/prev cursor operations in a random direction. */ dir = (int)MMRAND(0, 1); for (np = 0; np < MMRAND(1, 8); ++np) { if (notfound) break; nextprev( insert ? cursor_insert : cursor, dir, ¬found); } if (insert && (ret = cursor_insert->reset(cursor_insert)) != 0) die(ret, "cursor.reset"); /* Read the value we modified to confirm the operation. */ read_row(cursor, &key, keyno); } if ((ret = session->close(session, NULL)) != 0) die(ret, "session.close"); free(keybuf); free(valbuf); tinfo->state = TINFO_COMPLETE; return (NULL); }
/* * build -- * Build a row- or column-store page in a file. */ void build(int ikey, int ivalue, int cnt) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_ITEM key, value; WT_SESSION *session; char config[256], kbuf[64], vbuf[64]; int new_slvg; /* * Disable logging: we're modifying files directly, we don't want to * run recovery. */ CHECK(wiredtiger_open( NULL, NULL, "create,log=(enabled=false)", &conn) == 0); CHECK(conn->open_session(conn, NULL, NULL, &session) == 0); CHECK(session->drop(session, "file:" LOAD, "force") == 0); switch (page_type) { case WT_PAGE_COL_FIX: (void)snprintf(config, sizeof(config), "key_format=r,value_format=7t," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; case WT_PAGE_COL_VAR: (void)snprintf(config, sizeof(config), "key_format=r," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; case WT_PAGE_ROW_LEAF: (void)snprintf(config, sizeof(config), "key_format=u," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; default: assert(0); } CHECK(session->create(session, "file:" LOAD, config) == 0); CHECK(session->open_cursor( session, "file:" LOAD, NULL, "bulk,append", &cursor) == 0); for (; cnt > 0; --cnt, ++ikey, ++ivalue) { switch (page_type) { /* Build the key. */ case WT_PAGE_COL_FIX: case WT_PAGE_COL_VAR: break; case WT_PAGE_ROW_LEAF: snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey); key.data = kbuf; key.size = 20; cursor->set_key(cursor, &key); break; } switch (page_type) { /* Build the value. */ case WT_PAGE_COL_FIX: cursor->set_value(cursor, ivalue & 0x7f); break; case WT_PAGE_COL_VAR: case WT_PAGE_ROW_LEAF: snprintf(vbuf, sizeof(vbuf), "%010d VALUE----", value_unique ? ivalue : 37); value.data = vbuf; value.size = 20; cursor->set_value(cursor, &value); } CHECK(cursor->insert(cursor) == 0); } /* * The first time through this routine we create the salvage file and * then remove it (all we want is the appropriate schema entry, we're * creating the salvage file itself by hand). */ new_slvg = !file_exists(SLVG); if (new_slvg) { CHECK(session->drop(session, "file:" SLVG, "force") == 0); CHECK(session->create(session, "file:" SLVG, config) == 0); } CHECK(conn->close(conn, 0) == 0); if (new_slvg) (void)remove(SLVG); }
/* * build -- * Build a row- or column-store page in a file. */ void build(int ikey, int ivalue, int cnt) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_ITEM key, value; WT_SESSION *session; char config[256], kbuf[64], vbuf[64]; int new_slvg; assert(wiredtiger_open(NULL, NULL, "create", &conn) == 0); assert(conn->open_session(conn, NULL, NULL, &session) == 0); assert(session->drop(session, "file:" LOAD, "force") == 0); switch (page_type) { case WT_PAGE_COL_FIX: (void)snprintf(config, sizeof(config), "key_format=r,value_format=7t," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; case WT_PAGE_COL_VAR: (void)snprintf(config, sizeof(config), "key_format=r," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; case WT_PAGE_ROW_LEAF: (void)snprintf(config, sizeof(config), "key_format=u," "allocation_size=%d," "internal_page_max=%d,internal_item_max=%d," "leaf_page_max=%d,leaf_item_max=%d", PSIZE, PSIZE, OSIZE, PSIZE, OSIZE); break; default: assert(0); } assert(session->create(session, "file:" LOAD, config) == 0); assert(session->open_cursor( session, "file:" LOAD, NULL, "bulk", &cursor) == 0); for (; cnt > 0; --cnt, ++ikey, ++ivalue) { switch (page_type) { /* Build the key. */ case WT_PAGE_COL_FIX: case WT_PAGE_COL_VAR: break; case WT_PAGE_ROW_LEAF: snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey); key.data = kbuf; key.size = 20; cursor->set_key(cursor, &key); break; } switch (page_type) { /* Build the value. */ case WT_PAGE_COL_FIX: cursor->set_value(cursor, ivalue & 0x7f); break; case WT_PAGE_COL_VAR: case WT_PAGE_ROW_LEAF: snprintf(vbuf, sizeof(vbuf), "%010d VALUE----", value_unique ? ivalue : 37); value.data = vbuf; value.size = 20; cursor->set_value(cursor, &value); } assert(cursor->insert(cursor) == 0); } /* * The first time through this routine we put a matching configuration * in for the salvage file. */ new_slvg = (access(SLVG, F_OK) != 0); if (new_slvg) { assert(session->drop(session, "file:" SLVG, "force") == 0); assert(session->create(session, "file:" SLVG, config) == 0); } assert(conn->close(conn, 0) == 0); /* * We created the salvage file above, but all we want is the schema, * we're creating the salvage file by hand. */ if (new_slvg) (void)remove(SLVG); }
/* * Regularly create, open a cursor and drop a table. * Measure how long each step takes, and flag an error if it exceeds the * configured maximum. */ static void * cycle_idle_tables(void *arg) { struct timespec start, stop; CONFIG *cfg; WT_SESSION *session; WT_CURSOR *cursor; int cycle_count, ret; char uri[512]; cfg = (CONFIG *)arg; cycle_count = 0; if ((ret = cfg->conn->open_session( cfg->conn, NULL, cfg->sess_config, &session)) != 0) { lprintf(cfg, ret, 0, "Error opening a session on %s", cfg->home); return (NULL); } for (cycle_count = 0; cfg->idle_cycle_run; ++cycle_count) { snprintf(uri, 512, "%s_cycle%07d", cfg->uris[0], cycle_count); /* Don't busy cycle in this loop. */ __wt_sleep(1, 0); /* Setup a start timer. */ if ((ret = __wt_epoch(NULL, &start)) != 0) { lprintf(cfg, ret, 0, "Get time failed in cycle_idle_tables."); cfg->error = ret; return (NULL); } /* Create a table. */ if ((ret = session->create( session, uri, cfg->table_config)) != 0) { if (ret == EBUSY) continue; lprintf(cfg, ret, 0, "Table create failed in cycle_idle_tables."); cfg->error = ret; return (NULL); } if (check_timing(cfg, "create", start, &stop) != 0) return (NULL); start = stop; /* Open and close cursor. */ if ((ret = session->open_cursor( session, uri, NULL, NULL, &cursor)) != 0) { lprintf(cfg, ret, 0, "Cursor open failed in cycle_idle_tables."); cfg->error = ret; return (NULL); } if ((ret = cursor->close(cursor)) != 0) { lprintf(cfg, ret, 0, "Cursor close failed in cycle_idle_tables."); cfg->error = ret; return (NULL); } if (check_timing(cfg, "cursor", start, &stop) != 0) return (NULL); start = stop; /* * Drop the table. Keep retrying on EBUSY failure - it is an * expected return when checkpoints are happening. */ while ((ret = session->drop( session, uri, "force,checkpoint_wait=false")) == EBUSY) __wt_sleep(1, 0); if (ret != 0 && ret != EBUSY) { lprintf(cfg, ret, 0, "Table drop failed in cycle_idle_tables."); cfg->error = ret; return (NULL); } if (check_timing(cfg, "drop", start, &stop) != 0) return (NULL); } return (NULL); }