Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-16 Thread Patrick Ohly
On Mo, 2011-05-16 at 13:05 +0200, Milan Crha wrote:
> On Mon, 2011-05-16 at 11:35 +0200, Patrick Ohly wrote:
> > And it works beautifully. One word added to the source code and the
> > stress test passes reliably and quickly :-)
> > 
> > Patch attached. Okay to submit into master (not tested there, though)
> > and gnome-2-32 branches (which is where I have tested it)?
> 
> Yes please, master, gnome-3-0 and if you want then gnome-2-32 too.
> Thanks.

Okay, done.

-- 
Bye, Patrick Ohly
--  
patrick.o...@gmx.de
http://www.estamos.de/


___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-16 Thread Milan Crha
On Mon, 2011-05-16 at 11:35 +0200, Patrick Ohly wrote:
> And it works beautifully. One word added to the source code and the
> stress test passes reliably and quickly :-)
> 
> Patch attached. Okay to submit into master (not tested there, though)
> and gnome-2-32 branches (which is where I have tested it)?

Yes please, master, gnome-3-0 and if you want then gnome-2-32 too.
Thanks.
Milan

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-16 Thread Patrick Ohly
[Milan, can you please keep other people on CC?

I know that you personally prefer to not be CCed on mailing list emails
and I try to remember that in my own replies, but others are not on the
list and may depend on being CCed. For example, I don't know whether
Chris is subscribed.]

On Mo, 2011-05-16 at 11:12 +0200, Patrick Ohly wrote:
> It might be easier to set DB_INIT_CDB, which enforces multiple
> reads/single writer access without deadlocks. I'll give that a try.

And it works beautifully. One word added to the source code and the
stress test passes reliably and quickly :-)

Patch attached. Okay to submit into master (not tested there, though)
and gnome-2-32 branches (which is where I have tested it)?

-- 
Bye, Patrick Ohly
--  
patrick.o...@gmx.de
http://www.estamos.de/

>From 2b4cff9230a049d5ad7fe86873aba9a7bba35af1 Mon Sep 17 00:00:00 2001
From: Patrick Ohly 
Date: Mon, 16 May 2011 11:21:04 +0200
Subject: [PATCH] addressbook file backend: libdb must be initialized for concurrent read/write

Very bad performance (100% CPU load, several minutes run time) were
seen for multiple concurrent writes. gdb shows that libdb is
apparently busy polling while writing.

The libdb API docs for DB_ENV->open() imply that either DB_INIT_CDB or
DB_INIT_LOCK must be used in apps which are not read-only, like
EDS. This patch adds DB_INIT_CDB because it is simple and fixes the
performance problem.

In some rare cases, DB_INIT_LOCK might provide better performance by
allowing concurrent writes of independent data, but that seems too
complicated for not enough gain right now (must check for deadlocks).
---
 addressbook/backends/file/e-book-backend-file.c |   13 -
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index d21c527..372ade5 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -1146,7 +1146,18 @@ e_book_backend_file_load_source (EBookBackend   *backend,
 (gpointer (*)(gpointer , gsize))g_try_realloc,
 g_free);
 
-		db_error = (*env->open) (env, NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
+		/*
+		 * We need either DB_INIT_CDB or DB_INIT_LOCK, because we will have
+		 * multiple threads reading and writing concurrently without
+		 * any locking above libdb.
+		 *
+		 * DB_INIT_CDB enforces multiple reader/single writer by locking inside
+		 * the database. It is used instead of DB_INIT_LOCK because DB_INIT_LOCK
+		 * may deadlock, which would have to be called in a separate thread.
+		 * Considered too complicated for not enough gain (= concurrent writes)
+		 * at this point.
+		 */
+		db_error = (*env->open) (env, NULL, DB_INIT_CDB | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
 		if (db_error != 0) {
 			env->close(env, 0);
 			g_warning ("db_env_open failed with %s", db_strerror (db_error));
-- 
1.7.2.5

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-16 Thread Patrick Ohly
On Mo, 2011-05-16 at 08:11 +0200, Milan Crha wrote:
> On Fri, 2011-05-13 at 15:44 +0200, Patrick Ohly wrote:
> > In libebook, I get a "Timeout was reached" because the asynchronous
> > operation doesn't complete quickly enough. Same for the attempt to
> > delete the contacts. The gError->code is 24, which is indeed
> > E_BOOK_ERROR_NOT_SUPPORTED. 
> 
>   Hi,
> as long as it's GError, you cannot compare only GError::code, because
> the correct way to identify the error is using the whole pair
> GError::domain and GError::code. Your domain for "Timeout was reached"
> is most likely G_IO_ERROR with a code G_IO_ERROR_TIMED_OUT.

Indeed, that explains it. In principle I know that, I just forgot to
check in this case ;-}

> The new eclient stuff will not suffer of this (unless some backend will
> block main thread for too long).

The EClient may not time out, but taking several minutes of 100% CPU
time just to safe a handful of contacts just can't be right.

> I've no idea about libdb, thus only referring to the error. I have one
> notice though, the EBook calls are served and processed mostly as soon
> as they come, and they can come "in parallel" too. The backend itself
> may make sure that it'll not make any trouble, like by some busy lock.

libdb is supposed to be thread-safe, so in theory shouldn't need such a
lock. Either libdb is broken or EDS is not using it correctly (wrong
environment, for example).

Looking at the DB API [1] I see this flag for opening the environment:

DB_INIT_LOCK 

Initialize the locking subsystem. This subsystem should be used
when multiple processes or threads are going to be reading and
writing a Berkeley DB database, so that they do not interfere
with each other. If all threads are accessing the database(s)
read-only, locking is unnecessary. When the DB_INIT_LOCK flag is
specified, it is usually necessary to run a deadlock detector,
as well. See db_deadlock and DB_ENV->lock_detect() for more
information. 

EDS does not pass this flag, although it has concurrent reads *and*
writes. The behavior in that case is undefined as far as I can tell. The
downside of using DB_INIT_LOCK is that deadlocks are possible and need
to be checked by regularly calling lock_detect().

It might be easier to set DB_INIT_CDB, which enforces multiple
reads/single writer access without deadlocks. I'll give that a try.

[1] 
http://download.oracle.com/docs/cd/E17076_02/html/api_reference/C/envopen.html

-- 
Bye, Patrick Ohly
--  
patrick.o...@gmx.de
http://www.estamos.de/


___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-15 Thread Milan Crha
On Fri, 2011-05-13 at 15:44 +0200, Patrick Ohly wrote:
> In libebook, I get a "Timeout was reached" because the asynchronous
> operation doesn't complete quickly enough. Same for the attempt to
> delete the contacts. The gError->code is 24, which is indeed
> E_BOOK_ERROR_NOT_SUPPORTED. 

Hi,
as long as it's GError, you cannot compare only GError::code, because
the correct way to identify the error is using the whole pair
GError::domain and GError::code. Your domain for "Timeout was reached"
is most likely G_IO_ERROR with a code G_IO_ERROR_TIMED_OUT. This means,
for GDBus calls, that the call didn't finish in a default time, the
server side didn't reply to the method invocation on time. (As Patrick
suggested too).

The new eclient stuff will not suffer of this (unless some backend will
block main thread for too long). As a workaround, in 3.0, was added
e_data_server_util_set_dbus_call_timeout(), which can be called by
clients.

I've no idea about libdb, thus only referring to the error. I have one
notice though, the EBook calls are served and processed mostly as soon
as they come, and they can come "in parallel" too. The backend itself
may make sure that it'll not make any trouble, like by some busy lock.
The sync calendar backend does this differently, it has a flag for using
such internal busy lock, thus no call can overlap with another, if the
backend implementation wishes to do so. I guess this kind of
functionality might be useful when added to EBookBackendSync too.
Bye,
Milan

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] libdb performance issue? (was: Re: libebook: errors when using asynchronous contact addition/removal functions)

2011-05-13 Thread sean finney
On Fri, May 13, 2011 at 03:44:08PM +0200, Patrick Ohly wrote:
> I tried the LD_PRELOAD=libeatmydata.so workaround suggested in the mail
> above and it does avoid the problem.

If eatmydata removes the bottleneck, then it's likely that either (a)
each operation is corresponding to an fsync/fsyncdata/sync call (i.e.
each update corresponds to some kind of commit/flush), or (b)
the database file is opened O_SYNC, resulting in something similar.  I
don't know eds or libdb well enough to know if eds is doing something
out of the ordinary with the api and/or whether this is "working as designed"
and/or whether there's a way to remove the synchronous behavior.

> Is there anyone around who understand libdb well enough to shed some
> light on this? What is a proper fix?

Again from the armchair here (have not even looked at the code, feel free
to LART me as a result), if there's no way to avoid the synchronous
writes with the libdb api, i guess you could consider batching the async
additions together and submitting them as a group?

Alternatively, maybe this is another argument for moving forward with
the sqlite backend support? :)

sean
___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers