13
votes

I'm developing a little web application for studying Apache Cassandra and Java EE 6. Cassandra version is 1.1.6.

Have a problem driving me mad... I created a table with a counter (using cqlsh v. 3.0.0)

CREATE TABLE test (
  author varchar PRIMARY KEY,
  tot counter
)

and put some values this way:

update test set tot = tot +1 where author = 'myAuthor';

the column family is perfectly updated

author   | tot
----------+-----
myAuthor |   1

BUT, if you try to delete this row and then update again (with the same key), then nothing happens! The table is no more updated and I can't figure why: it seems to me that once you used a key than you can't use it anymore. I looked for clues in datasax documentation (http://www.datastax.com/docs/1.1/references/cql/cql_lexicon) but didn't manage to find a solution.

Can someone help me? Thank in advance

2
If i want to change the value of the counter, I have to update the counter update table set counter = counter -1 but my question is: why can't I use a delete key no more?besil

2 Answers

18
votes

Cassandra has some strict limits on deleting counters. You cannot really delete a counter and then use it again in any short period of time. From the Cassandra wiki:

Counter removal is intrinsically limited. For instance, if you issue very quickly the sequence "increment, remove, increment" it is possible for the removal to be lost (if for some reason the remove happens to be the last received messages). Hence, removal of counters is provided for definitive removal only, that is when the deleted counter is not increment afterwards. This holds for row deletion too: if you delete a row of counters, incrementing any counter in that row (that existed before the deletion) will result in an undetermined behavior. Note that if you need to reset a counter, one option (that is unfortunately not concurrent safe) could be to read its value and add -value.

2
votes

The solution to re-adding a deleted counter key is to purge all record of it from the table:

nodetool repair $table
cqlsh -c "ALTER TABLE $table WITH gc_grace_seconds=1;"
sleep 1
nodetool compact $table

As you can imagine, this is not practical in a real system and should probably be reserved for emergencies if an important counter is somehow accidentally deleted.

It is better to ensure that can never happen.