dbTalk Databases Forums  

"Unable to allocate memory for transaction detail" in db->put under high load

comp.databases.berkeley-db comp.databases.berkeley-db


Discuss "Unable to allocate memory for transaction detail" in db->put under high load in the comp.databases.berkeley-db forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Steve Bougerolle
 
Posts: n/a

Default "Unable to allocate memory for transaction detail" in db->put under high load - 10-05-2004 , 03:23 PM







Ok, I've reached another stumbling point in my debugging and can't find
the answer anywhere, nor have any of my experimental solutions worked.

I'm running a threaded DB server which needs to be able to handle high
loads. When enough threads simultaneously try to access it to put a
record, some of them die with "cannot allocate memory' errors - upon
digging into errfile the detailed error is "Unable to allocate memory for
transaction detail". This happens at about the 97th thread, which makes
me wonder if I'm hitting some internal limit of 96 something-or-others.

I've tried increasing the number of locks/lockers/lock_objects to 64k,
with no difference. I've tried increasing the cache size (to 25MB), with
no difference. What could be causing this, or what else could I tweak to
fix it?

Interestingly, it always seems to fail at the exact same call (which is
not what I'd expect if it's simply gobbling too much of some resource).
The relevant code bit is:

memset(&dbkey,0,sizeof(dbkey));
memset(&dbdata,0,sizeof(dbdata));
key_string[0]='q';
memcpy(key_string+1,system_id,7);
dbkey.data=key_string;
dbkey.size=8;
dbdata.data=buffer;
dbdata.size=order_length;

if((rc=db_engn->put(db_engn,NULL,&dbkey,&dbdata,DB_AUTO_COMMIT))! =0) {
syslog(LOG_ERR,"Error queueing order to engine (%d: %s)",rc,db_strerror(rc));
send_packet(socket,1,&response);
return(-1);
}

buffer is a test string 5 characters long, and order_length is set to
5. Prior to this it reads a different key (which will probably be on a
different page) successfully, with no other DB ops in between. The
environment is transactional, opened thus (I've trimmed out the error
handling to just show the DB calls, the full code here runs without
problems):

if((rc=db_env_create(&db_env,0))) { ...
if((rc=db_env->set_shm_key(db_env,ftok("/var/lib/IR/db/",1)))) { ...
if((rc=db_env->set_cachesize(db_env,0,25000000,1))) { ...
db_env->set_errfile(db_env,stderr); ...
if((rc=db_env->set_verbose(db_env,DB_VERB_RECOVERY,1))) { ...
if((rc=db_env->set_lk_detect(db_env, DB_LOCK_YOUNGEST))) { ...
if((rc=db_env->set_lk_max_locks(db_env, 65535))) { ...
if((rc=db_env->set_lk_max_lockers(db_env, 65535))) { ...
if((rc=db_env->set_lk_max_objects(db_env, 65535))) { ...
if((rc=db_env->open(db_env,"/var/lib/IR/db/",
DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_MPOOL | DB_CREATE | DB_RECOVER
Quote:
DB_SYSTEM_MEM | DB_INIT_LOG | DB_THREAD, 0640))) { ...
if((rc=db_create(&db_engn,db_env,0))) { ...
if((rc=db_engn->set_pagesize(db_engn,4096))) { ...
if((rc=db_engn->set_flags(db_engn,DB_DUP))) { ...
if((rc=db_engn->open(db_engn,NULL,"engine.db",NULL,DB_BTREE,
DB_CREATE | DB_THREAD | DB_AUTO_COMMIT | DB_DIRTY_READ,0640))) {

--
Steve Bougerolle <sbougerolle (AT) imperialrealms (DOT) com>
http://www.imperialrealms.com http://www.imperialrealms.net
http://www.bougerolle.net
http://www.sebgitech.com



Reply With Quote
  #2  
Old   
Chris Newcombe
 
Posts: n/a

Default Re: "Unable to allocate memory for transaction detail" in db->put under high load - 10-05-2004 , 10:48 PM






Quote:
the detailed error is "Unable to allocate memory for
transaction detail". This happens at about the 97th thread, which makes
me wonder if I'm hitting some internal limit of 96 something-or-others.

I've tried increasing the number of locks/lockers/lock_objects to 64k,
with no difference. I've tried increasing the cache size (to 25MB), with
no difference. What could be causing this, or what else could I tweak to
fix it?

Hmmm, I have vague memories of this happening to me a couple of years
ago under similar degree of concurrency (300 threads).

I _think_ what fixed it for me was calling DbEnv::set_tx_max() with a
higher value. I think the default is something like 20.

However, I think this API is somewhat mis-named. It actually sets the
_minimum_ number of simultaneous open transaction handles. Sleepycat
told me that this value is used to size an inter-process memory pool,
and the actual size calculated is likely to allow 3x or even more
transactions than the number passed to this function. So you can't
use it to enforce an upper concurrency limit, you must do that
yourself.

So try bumping it to 100 or 200 and see if the error goes away.

http://www.sleepycat.com/docs/api_c/env_set_tx_max.html

Hope this helps.

Chris


Reply With Quote
  #3  
Old   
Steve Bougerolle
 
Posts: n/a

Default Re: "Unable to allocate memory for transaction detail" in db->put under high load - 10-06-2004 , 12:00 PM



On Tue, 05 Oct 2004 20:48:05 -0700, Chris Newcombe wrote:
Quote:
Hmmm, I have vague memories of this happening to me a couple of years
ago under similar degree of concurrency (300 threads).

I _think_ what fixed it for me was calling DbEnv::set_tx_max() with a
higher value. I think the default is something like 20.

So try bumping it to 100 or 200 and see if the error goes away.
That fixed the problem, thanks very much!

--
Steve Bougerolle <sbougerolle (AT) imperialrealms (DOT) com>
http://www.imperialrealms.com http://www.imperialrealms.net
http://www.bougerolle.net
http://www.sebgitech.com



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.