Berkeley DB считается отлаженой и надежной библиотекой. Однако, при исполнении нижеперведенного кода возникает непонятная ошибка. При очередном начале транзакции на консоль выводится: "Unable to allocate memory for transaction detail", и программа ававрийно завершается. Анализ логов, предоставляемых библиотекой, показывает значительное превышение выделений памяти над освобождениями памяти из блока памяти для нужд транзакций. Кто-нибудь может объяснить, что происходит? Может, я что-то неправильно делаю? Очень нужна помощь!
#include <db.h> //Berkeley DB 4.7.25
#include <assert.h>
#include <exception>
struct bdb_exception:
public std::exception
{
int code;
bdb_exception(const char* a):
std::exception(a),
code(0)
{
}
bdb_exception(const char* a, int a_code):
std::exception(a),
code(a_code)
{
}
};
#define BDB_CALL(a)\
{\
int res((a));\
if(res!=0)\
throw bdb_exception(db_strerror(res), res);\
}
int main(int argc, char* argv[])
{
DB_ENV* g_enviroment(NULL);
BDB_CALL(db_env_create(&g_enviroment, 0));
g_enviroment->open
( g_enviroment,
".\\",
DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE,
0
);
assert(g_enviroment!=NULL);
//------------------------
DB* recno1(NULL);
BDB_CALL(db_create(&recno1, g_enviroment, 0));
BDB_CALL(recno1->set_re_len(recno1, 4));
BDB_CALL
( recno1->open
( recno1,
NULL,
".\\m_can_fq1",
NULL,
DB_RECNO,
DB_CREATE|DB_AUTO_COMMIT,
0
)
);
assert(recno1!=NULL);
//------------------------
DB* btree1(NULL);
db_create(&btree1, g_enviroment, 0);
BDB_CALL
( btree1->open
( btree1,
NULL,
".\\m_can_prm1",
NULL,
DB_BTREE,
DB_CREATE|DB_AUTO_COMMIT,
0
)
);
assert(btree1!=NULL);
//------------------------
DB* recno2(NULL);
BDB_CALL(db_create(&recno2, g_enviroment, 0));
BDB_CALL(recno2->set_re_len(recno2, 4));
BDB_CALL
( recno2->open
( recno2,
NULL,
".\\m_can_fq1",
NULL,
DB_RECNO,
DB_CREATE|DB_AUTO_COMMIT,
0
)
);
assert(recno2!=NULL);
//------------------------
DB* btree2(NULL);
BDB_CALL(db_create(&btree2, g_enviroment, 0));
BDB_CALL
( btree2->open
( btree2,
NULL,
".\\m_can_prm2",
NULL,
DB_BTREE,
DB_CREATE|DB_AUTO_COMMIT,
0
)
);
assert(btree2!=NULL);
//------------------------
DB* recno3(NULL);
BDB_CALL(db_create(&recno3, g_enviroment, 0));
BDB_CALL(recno3->set_re_len(recno3, 4));
BDB_CALL
( recno3->open
( recno3,
NULL,
".\\ind1",
NULL,
DB_RECNO,
DB_CREATE|DB_AUTO_COMMIT|DB_MULTIVERSION, //(!sic)
0
)
);
assert(recno3!=NULL);
//------------------------
while(1)
{
DB_TXN* txn(NULL);
int err_code;
// Unable to allocate memory for transaction detail
if((err_code=g_enviroment->txn_begin(g_enviroment, NULL, &txn, 0))!=0)
throw bdb_exception(db_strerror(err_code));
int a, b;
DBT key;
key.data=&a;
key.size=0;
key.ulen=sizeof(a);
key.dlen=0;
key.doff=0;
key.flags=DB_DBT_USERMEM;
DBT data;
data.data=&b;
data.size=0;
data.ulen=sizeof(b);
data.dlen=0;
data.doff=0;
data.flags=DB_DBT_USERMEM;
//1
{
data.size=1;
BDB_CALL(recno3->put(recno3, txn, &key, &data, DB_APPEND));
}
//2
{
key.size=sizeof(a);
btree1->get(btree1, txn, &key, &data, 0);
}
//3
{
DBC *c;
BDB_CALL(recno1->cursor(recno1, txn, &c, 0));
BDB_CALL(c->close(c));
}
//4
{
key.size=sizeof(b);
btree2->get(btree2, txn, &key, &data, 0);
}
//5
{
DBC *c;
BDB_CALL(recno2->cursor(recno2, txn, &c, 0));
BDB_CALL(c->close(c));
}
txn->commit(txn, 0);
}
return 0;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
05.08.09 16:41: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
up
... << RSDN@Home 1.1.4 stable rev. 510>>
Применил четрые доступных патча для текущей версии, но проблема не исчезла.
... << RSDN@Home 1.1.4 stable rev. 510>>
Здравствуйте, x905, Вы писали:
X>http://www.oracle.com/technology/products/berkeley-db/faq/db_faq.html смотрел ?
Смотрел. Там вроде есть "Berkeley DB occasionally returns the error: "Unable to allocate memory for transaction detail". What does that mean?" Но это не мой случай, т.к. в моей программе в один момент времени существует только одна активная транзакция.
... << RSDN@Home 1.1.4 stable rev. 510>>
Здравствуйте, x905, Вы писали:
X>hi
X>на вопрос не знаю ответа, разве что в devel рассылку ихнею написать
Написал к ним на форум. Сейчас бодаюсь там с каким-то челом из Оракла. Он пытается меня убедить, что я что-то сделал неправильно(больше похоже на отписку). Я пытаюсь его убедить, что происходит что-то странное, а я ничего нелегального не делаю. Саппорт, как я понял, работает только для тех кто денюшки заплатил — просит ввести какой-то номер.
X>хотел узнать — почему выбор пал именно на Berkeley?
Надежность(гыгы), наличие транзакций, поддержка различных способов организации данных, скорость. В общем, я использую его из-за поддержки транзакций. Объемы данных и скорость обработки мне в текущей задачи не нужны.
... << RSDN@Home 1.1.4 stable rev. 510>>