Make fetch_locked more scalable
authorVolker Lendecke <vl@samba.org>
Wed, 9 Dec 2009 14:11:45 +0000 (15:11 +0100)
committerMichael Adam <obnox@samba.org>
Fri, 11 Dec 2009 23:45:39 +0000 (00:45 +0100)
commit5736e17c139c9a8049e235429aeae0c6c9d0e93d
treeb55543c685bf2a634474ab17eabfd6e104bc09f7
parent844aa6300ee4d87561e698001ebc15ac1e455528
Make fetch_locked more scalable

This patch improves the handling of the fetch_lock operation on non-persistent
databases that ctdb clients have to do very frequently.

The normal flow how this goes is the following:

1. Client does a local fetch_lock on the database

2. Client looks if the local node is dmaster.
   If yes, everything is fine
   If no, continue here

3. Client unlocks the local record

4. Client issues a "get me the record" call to ctdbd

5. ctdbd goes out and fetches the dmaster role

6. ctdbd tells the client to retry

7. Client starts over again

The problem is between step 6 and 7: Before the client has had the chance to
retry (i.e. catch the record with a fetch_locked), another node might have come
asking ctdbd to migrate away the record again. This is a real problem, I've
seen >20 loops of this kind in real workloads.

This patch does the following: Whenever ctdb receives a record as result of
step 5, it puts the key on a "holdback list". As long as a key is on this list,
a request to migrate away the dmaster is put on hold. It is the client's duty
to issue the "CTDB_CONTROL_GOTIT" control when it has successfully done step 2
after having asked ctdb to fetch the record. This will release the key from the
"holdback list" and re-issue all dmaster migration requests.

As a safeguard against malicious clients, once a second (default 1000msecs,
tunable "HoldbackCleanupInterval" in milliseconds) ctdbd goes over the list of
held back keys, deletes them and releases all held back migration requests.
include/ctdb_private.h
server/ctdb_call.c
server/ctdb_control.c
server/ctdb_daemon.c
server/ctdb_recover.c
server/ctdb_recoverd.c
server/ctdb_tunables.c