Fix tck - and all of memgraph in the process.
Summary: When running tck tests there was a peculiar behavior where sometimes some queries worked, and sometimes they failed. Nothing was failing when memgraph was restarted between each query (scenario) - which points to MATCH DETACH DELETE not working correctly. What was happening is the following: some transaction would update the record in version list and set it's expiry to it's id. Along with that some transaction would query the mentioned record - and would set the hints flags for that expiration transaction status (which was aborted - which is fine at this moment). After some while, because the record is not really deleted because it's not aborted some other transaction would modify it's expiry transaction (this time making the transaction commited), but because the hints flags were not updated - they would still return the status for the old transaction - which was aborted. This made some records available even though they were deleted. Reviewers: mislav.bradac, florijan, teon.banek, matej.gradicek, buda Reviewed By: buda Subscribers: buda, lion, pullbot Differential Revision: https://phabricator.memgraph.io/D370
This commit is contained in:
parent
8380d3694f
commit
22ea809c67
@ -54,6 +54,19 @@ class Hints {
|
||||
bits.fetch_or(ABORTED, order);
|
||||
}
|
||||
|
||||
void clear_commited(std::memory_order order = std::memory_order_seq_cst) {
|
||||
bits.fetch_and(~COMMITTED, order);
|
||||
}
|
||||
|
||||
void clear_aborted(std::memory_order order = std::memory_order_seq_cst) {
|
||||
bits.fetch_and(~ABORTED, order);
|
||||
}
|
||||
|
||||
void clear(std::memory_order order = std::memory_order_seq_cst) {
|
||||
clear_aborted(order);
|
||||
clear_commited(order);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<uint8_t> &bits;
|
||||
};
|
||||
|
@ -80,11 +80,13 @@ class Record : public Version<T> {
|
||||
}
|
||||
|
||||
void mark_created(const tx::Transaction &t) {
|
||||
debug_assert(tx.cre() == Id(0), "Marking node as created twice.");
|
||||
tx.cre(t.id);
|
||||
cmd.cre(t.cid);
|
||||
}
|
||||
|
||||
void mark_deleted(const tx::Transaction &t) {
|
||||
if (tx.exp() != Id(0)) hints.exp.clear();
|
||||
tx.exp(t.id);
|
||||
cmd.exp(t.cid);
|
||||
}
|
||||
|
@ -12,6 +12,26 @@
|
||||
|
||||
class TestClass : public mvcc::Record<TestClass> {};
|
||||
|
||||
TEST(MVCC, RecordExpiryUpdatedTwice) {
|
||||
tx::Engine engine;
|
||||
|
||||
auto t0 = engine.begin();
|
||||
mvcc::VersionList<TestClass> version_list(*t0);
|
||||
t0->commit();
|
||||
|
||||
auto t1 = engine.begin();
|
||||
version_list.update(*t1);
|
||||
t1->abort();
|
||||
|
||||
auto t2 = engine.begin();
|
||||
version_list.remove(*t2);
|
||||
t2->commit();
|
||||
|
||||
auto t3 = engine.begin();
|
||||
EXPECT_EQ(version_list.find(*t3), nullptr);
|
||||
t3->commit();
|
||||
}
|
||||
|
||||
TEST(MVCC, Deadlock) {
|
||||
tx::Engine engine;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user