[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#9039) key corruption using mdb_put and differing data
Full_Name: Jonny Wilkes
Version: 2.4.2
OS: Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (67.160.82.31)
The following code shows key corruption.
I am probably using the API wrong, but I don't see how. I apologize in advance
for not having a clue.
And now, on to the test. It can be compiled and run like so:
gcc t1.c -llmdb && ./a.out
--------- t1.c starts here ---------
/*
The output of this program using liblmdb0 v0.9.21-1 on Ubuntu is:
--- dump ---
key12345
key67890
--- dump ---
key12345
y12345
Why? What happened to key67890?
*/
#include <lmdb.h>
#if USE_SOURCE
#include "midl.c"
#include "mdb.c"
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define P(K) printf("%s\n", (char *)K.mv_data)
#define X(x) do { int _x = x; if (_x) fprintf(stderr, "%d %s\n", _x,
mdb_strerror(_x)); } while (0)
const char *path = "/tmp/lmdb-why.tmp";
MDB_env *env;
/*
* setup creates /tmp/lmdb-why.tmp with 2 keys with the data "hey":
*
* 1. key12345 : hey
* 2. key67890 : hey
*/
int
setup(void)
{
unlink(path);
if (!env) {
X(mdb_env_create(&env));
X(mdb_env_open(env, path, MDB_NOSUBDIR, 0664));
}
MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn));
MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi));
const char *keys[] = {
"key12345",
"key67890"
};
for (unsigned i = 0; i < 2; ++i) {
MDB_val key, data;
key.mv_data = (void *)keys[i];
key.mv_size = strlen(keys[i])+1;
data.mv_data = "hey";
data.mv_size = 4;
X(mdb_put(txn, dbi, &key, &data, 0));
}
X(mdb_txn_commit(txn));
return 0;
}
int
dump(void)
{
printf("--- dump ---\n");
MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn));
MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi));
MDB_cursor *cursor; X(mdb_cursor_open(txn, dbi, &cursor));
MDB_val key;
int rc;
while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) {
P(key);
}
mdb_cursor_close(cursor);
if (MDB_NOTFOUND != rc)
return rc;
mdb_txn_abort(txn);
return 0;
}
/*
* change_data change the data for each key to "there" using mdb_put.
* After it completes, the keys are corrupt.
*/
int
change_data(void)
{
MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn));
MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi));
MDB_cursor *cursor; X(mdb_cursor_open(txn, dbi, &cursor));
MDB_val key;
int rc;
while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) {
MDB_val data;
data.mv_data = (void *)"there";
data.mv_size = 6; /* ! */
X(mdb_put(txn, dbi, &key, &data, 0));
}
mdb_cursor_close(cursor);
if (MDB_NOTFOUND != rc)
return rc;
X(mdb_txn_commit(txn));
return 0;
}
int main(void)
{
X(setup());
X(dump());
X(change_data());
X(dump());
return 0;
}