[
https://issues.apache.org/jira/browse/CASSANDRA-7801?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Sylvain Lebresne updated CASSANDRA-7801:
----------------------------------------
Attachment: 7801.txt
What I think happens is simply that the insert timestamp ends up not being
bigger than the previous delete. Conditional operations have their own way to
assigning timestamps that is completely separated from the "normal" mechanism.
So nothing prevents an insert to get the same timestamp than a previous delete
(or even a smaller one, if the system clock goes backward due to a ntp
adjustment, but equal timestamps is enough (and much more likely) since deletes
win over inserts for equal timestamps).
I haven't tested it but I suspect that if the delete uses {{IF EXISTS}} (so it
goes through the paxos path), then the test will always pass. And in fact, in
the general case of a multi-node cluster, using {{IF EXISTS}} is the *only* way
to make this work reliably (the same way that if you try this test without
conditions this kind of test will not be guaranteed to work in a multi-node
cluster unless you manually provide strictly increasing timestamps, even at
CL.ALL).
That said, it's possible to make this pass in the case the client sticks to a
single node, by hooking both the standard and the paxos mechanism for timestamp
assignments together. I'm attaching a patch that does this. It's a tad verbose
because we need to pass the {{ClientState}} in many places we used not to, but
the main changes are really just in {{StorageProxy.beingAndRepairPaxos}} and in
{{ClientState}}. I'll note that I haven't tested it so if [~efrnman] and/or
[~philipthompson] you guys could validate that I'm not on crack and it does fix
our test cases, that would be great.
I will note however that I'm only mildly in favor of messing with something as
critical as timestamp generation in the 2.0 branch: as said above, the only
proper way to guarantee ordering of the operations in general is to use {{IF
EXISTS}} for the delete and I think we can leave it to that, at least for 2.0.
> A successful INSERT with CAS does not always store data in the DB after a
> DELETE
> --------------------------------------------------------------------------------
>
> Key: CASSANDRA-7801
> URL: https://issues.apache.org/jira/browse/CASSANDRA-7801
> Project: Cassandra
> Issue Type: Bug
> Components: Core
> Environment: PC with Windows 7 and on Linux installation.
> Have seen the fault on Cassandra 2.0.9 and Cassandra 2.1.0-rc5
> Reporter: Martin Fransson
> Assignee: Sylvain Lebresne
> Attachments: 7801.txt, cas.zip
>
>
> When I run a loop with CQL statements to DELETE, INSERT with CAS and then a
> GET.
> The INSERT opertion is successful (Applied), but no data is stored in the
> database. I have checked the database manually after the test to verify that
> the DB is empty.
> for (int i = 0; i < 10000; ++i)
> {
> try
> {
> t.del();
> t.cas();
> t.select();
> }
> catch (Exception e)
> {
> System.err.println("i=" + i);
> e.printStackTrace();
> break;
> }
> }
> myCluster =
> Cluster.builder().addContactPoint("localhost").withPort(12742).build();
> mySession = myCluster.connect();
> mySession.execute("CREATE KEYSPACE IF NOT EXISTS castest WITH
> REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };");
> mySession.execute("CREATE TABLE IF NOT EXISTS castest.users (userid
> text PRIMARY KEY, name text)");
> myInsert = mySession.prepare("INSERT INTO castest.users (userid,
> name) values ('user1', 'calle') IF NOT EXISTS");
> myDelete = mySession.prepare("DELETE FROM castest.users where
> userid='user1'");
> myGet = mySession.prepare("SELECT * FROM castest.users where
> userid='user1'");
> }
> I can reproduce the fault with the attached program on a PC with windows 7.
> You need a cassandra runing and you need to set the port in the program.
--
This message was sent by Atlassian JIRA
(v6.2#6252)