summaryrefslogtreecommitdiffstats
path: root/ctdb/include
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2009-07-21 11:30:38 +0200
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2009-07-29 11:12:39 +1000
commit4cd06a330e37ce5888949153e52057deb1da5b43 (patch)
tree095c8ec83fef82d05a955bd147c80c28d607bccd /ctdb/include
parent188ab0f96c1b78cb0ea4eb5c6d0407916ddf6719 (diff)
downloadsamba-4cd06a330e37ce5888949153e52057deb1da5b43.tar.gz
samba-4cd06a330e37ce5888949153e52057deb1da5b43.tar.xz
samba-4cd06a330e37ce5888949153e52057deb1da5b43.zip
Fix persistent transaction commit race condition.
In ctdb_client.c:ctdb_transaction_commit(), after a failed TRANS2_COMMIT control call (for instance due to the 1-second being exceeded waiting for a busy node's reply), there is a 1-second gap between the transaction_cancel() and replay_transaction() calls in which there is no lock on the persistent db. And due to the lack of global state indicating that a transaction is in progress in ctdbd, other nodes may succeed to start transactions on the db in this gap and even worse work on top of the possibly already pushed changes. So the data diverges on the several nodes. This change fixes this by introducing global state for a transaction commit being active in the ctdb_db_context struct and in a db_id field in the client so that a client keeps track of _which_ tdb it as transaction commit running on. These data are set by ctdb upon entering the trans2_commit control and they are cleared in the trans2_error or trans2_finished controls. This makes it impossible to start a nother transaction or migrate a record to a different node while a transaction is active on a persistent tdb, including the retry loop. This approach is dead lock free and still allows recovery process to be started in the retry-gap between cancel and replay. Also note, that this solution does not require any change in the client side. This was debugged and developed together with Stefan Metzmacher <metze@samba.org> - thanks! Michael (This used to be ctdb commit f88103516e5ad723062fb95fcb07a128f1069d69)
Diffstat (limited to 'ctdb/include')
-rw-r--r--ctdb/include/ctdb_private.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index a668c88a9e..a55dce9286 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -155,6 +155,7 @@ struct ctdb_client {
uint32_t client_id;
pid_t pid;
struct ctdb_tcp_list *tcp_list;
+ uint32_t db_id;
uint32_t num_persistent_updates;
};
@@ -439,6 +440,7 @@ struct ctdb_db_context {
uint32_t seqnum;
struct timed_event *te;
struct ctdb_traverse_local_handle *traverse;
+ bool transaction_active;
};