cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sylvain Lebresne (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CASSANDRA-7801) A successful INSERT with CAS does not always store data in the DB after a DELETE
Date Thu, 28 Aug 2014 09:37:58 GMT

     [ 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)

Mime
View raw message