Age | Commit message (Collapse) | Author | Files | Lines |
|
When doing a non-locking fetch on a record of a persistent db when no
transaction is running, the old behaviour was to fetch locally and
do a ctdb call when the record was not found in the local db.
The call is useless for persistent dbs anyway since they are only
written to using transactions and hence kept in sync, but it is
also harmful, because a ctdb call will bump the record RSN when it
does actually migrate the record from one node to another.
Recently, ctdb has been changed to make all calls do a migration.
This uncovered the client misbehaviour for persistent dbs, because
now _each_ non-locking fetch will render the persistent db inconsistent:
A subsequent transaction which touches the record in question will
fail because the RSNs are out of sync.
This patch fixes this old bug.
Autobuild-User: Michael Adam <obnox@samba.org>
Autobuild-Date: Fri Mar 25 01:26:32 CET 2011 on sn-devel-104
|
|
Eventually we'll get this right...
|
|
|
|
|
|
This is mainly a debugging aid for post-mortem analysis in case a cluster file
system is slow.
|
|
|
|
|
|
The key for reading and writing was inconsistent due to a
off by one data length.
Michael
|
|
This skips update of the __db_sequence_number__ record when nothing else has
been written. There are transactions that are just openend and then nothing
is written until transaction_commit is called. This is for instance the case
with registry initialization routines: They start a transaction and only
write somthing when the registry has not been initialized yet.
So this change will skip many db_seqnum bumps and TRANS3_COMMIT roundtrips.
Michael
|
|
I carefully prepared the return value only to "return 0;" at the bottom. :-(
This may well have hit us for instance in the nested cancel case
and produced random errors.
Michael
|
|
The logic bug was that if a record was found in the marshall buffer,
then always the ctdb header of tha last record in the marshall buffer
was returned, and not the ctdb header of the last occurrence of the
requested record.
This is fixed by introducing an additional temporary variable.
Michael
|
|
Michael
|
|
Michael
|
|
Don't treat this as an error but return seqnum 0 instead.
Michael
|
|
For persistent databases, 64bit integer is kept in a special record
__db_sequence_number__. This record is incremented with each completed
transaction.
The retry mechanism for failing TRANS3_COMMIT controls inside the
db_ctdb_transaction_commit() function now relies one a modified
behaviour of ctdbd's treatment of persistent databases in recoveries.
Recently, a special treatment for persistent databases had been
introduced in ctdb (1.0.108) to work around the problems with the
orinal design of persistent transactions.
Now with the rewrite we need to revert to the old behaviour that
ctdb always takes the newest copies of all records.
This change also paves the way for a next step, which will make
recovery use the db seqnum to tell which node has the newest copy
of a persistent db and use that node's copy. This will greatly
reduce the amount of data transferred with each recovery.
Michael
|
|
The return values calculated by the callers were wrong anyways since
the new marshalling code does not set the local tdbs tdb error code.
Michael
|
|
Michael
|
|
This simplifies the transaction code a lot:
* transaction_start essentially consists of acquiring a global lock.
* No write operations at all are performed on the local database
until the transaction is committed: Every store operation is just
going into the marshall buffer.
* The commit operation calls a new simplified TRANS3_COMMIT control
in ctdb which rolls out thae changes to all nodes including the
node that is performing the transaction.
Michael
|
|
This is to cope with timeouts when recoveries and transactions collide.
Maybe 100 is too hight, but 10 or even 20 have been too low in a
very busy environment.
Michael
|
|
so that it is correctly handled by recoveries.
Also set the dmaster explicitly.
Michael
|
|
for the case that another local process has started a transaction
bewteen releasing the transaction_lock record and starting the
transaction.
Michael
|
|
in db_ctdb_transaction_fetch_start() for error conditions when re-fetching
the transaction_lock record inside the transaction
Michael
|
|
node.
In ctdb_transaction_commit(), when the trans2_commit control fails, there
is a race condition in the 1 second sleep between the local transaction_cancel
and the call to ctdb_replay_transaction(): The database is not locked, and
neither is the transaction_lock record. So another client can start and possibly
complete a new transaction in this gap, but only on the same node: The locking
of the transaction_lock record on a different node which involves migration of
the record to the other node has been disabled by introduction of the
transaction_active flag on the db which closes precisely this gap from the start
of the commit until the call to TRANS2_FINISH or TRANS2_ERROR.
But this mechanism does not cover the case where a process on the same node
tries to start a transaction: There is no obstacle to locking the transaction_lock
record because the record does not need to be migrated.
This commit closes this race condition in ctdb_transaction_fetch_start()
by using the new ctdb_ctrl_transaction_active() call to ask the local
ctdb daemon whether it has a transaction running on the database.
If so, the check is repeated until the running transaction is done.
This does introduce an additional call to the local ctdbd when starting
transactions, but it does close the (hopefully) last race condition.
Michael
|
|
CTDB_CONTROL_TRANS2_COMMIT
Michael
|
|
There are two races in concurrent transactions on a single node.
One in starting a transaction and one with replay during commit.
This commit closes the first race by storing the client pid in the
transaction-lock record and comparing the stored pid against its own
pid after releasing the lock and refetching the record inside the
transaction.
Michael
|
|
Michael
|
|
Michael
|
|
This fetches a record from the db and splits out the ctdb header.
Michael
|
|
and use it in db_ctdb_store() and db_ctdb_transaction_store().
Michael
|
|
Michael
|
|
an existing record
not only when creating a record.
This matches commit e9194a130327d6b05a8ab90bd976475b0e93b06d from ctdb-master.
Michael
|
|
Michael
|
|
Michael
|
|
metze
|
|
|
|
|
|
|
|
(This used to be commit 010c7101e59477f0d5f3bf11c17f474ec6f79cc1)
|
|
(This used to be commit dd9e4e6db04acf20f6ef7705955358c7ca442bbd)
|
|
allowed for tdb. This is needed for the registry db backend.
(This used to be commit 4b04ec29c76df837a7909725bbbf4c79d5abdb4d)
|
|
(This used to be commit a2f70fc175b748ef160a998d0563c28381ea3466)
|
|
out of sync
(This used to be commit 571ec7893c8b40959c005d510c039e3f231ffc67)
|
|
thinking it was a failure of a transaction cancel
(This used to be commit 22dbe158ed62ae47bbcb41bba3db345294f75437)
|
|
(This used to be commit fe6a03e7b11cd859fddae5ba924ea5e071b8ccea)
|
|
1) when all nodes write the same value to the record, or when writing
a value that is already there, we can skip the write and save
ourselves a network transactions
2) when all remote nodes fail an update, and we then fail a replay, we
don't need to trigger a recovery. This solves a corner case where
we could get into a recovery loop
(This used to be commit 2481bfce4307274806584b0d8e295cc7f638e184)
|
|
could lead to it blocking forever
(This used to be commit a633390d3a7cb04a7c4e14cba9c533621793287e)
|
|
(This used to be commit ba64a757f86fb60994e12e81416083ac0fa11c21)
|
|
(This used to be commit 76fbe56e827193d939676da23a580aa0f9394dd1)
|
|
(This used to be commit 037516f1362c8d64da1d47a0cdaf83198d3eaeaf)
|
|
(This used to be commit 2e85cbe88b3d1674b915f62e02be7d005fddaa39)
|