Cassandra:使用较旧的时间戳插入

时间:2015-06-09 22:29:17

标签: cassandra cql3

(Cassandra 2.0.9,使用CQL)

我意外地更新了表中管理自己的时间戳(100 *特定序列号)的行。现在,因为我的时间戳是当前时间,所以没有任何更新正在运行。我明白为什么会这样,但我试图从中恢复过来。我很幸运能够删除这些行。

我已将 gc_grace_seconds 设置为0并运行中删除其中key = primarykey 删除行。之后,我在每个节点上使用了 nodetool flush nodetool compact ,以使删除通过并获得生成的墓碑压缩并抹去。然后我将 gc_grace_seconds 恢复了10天,并尝试使用相同的密钥插入行,但使用时间戳1

这不起作用。只是想知道是否有人犯了类似的错误并解决了它?

2 个答案:

答案 0 :(得分:3)

我以为我会尝试一下这个练习。

aploetz@cqlsh:presentation> SELECT * FROm bladerunners WHERE id='B26354';
 id     | data                | name         | ts                       | type
--------+---------------------+--------------+--------------------------+--------------
 B26354 | Filed and monitored | Rick Deckard | 2015-02-16 12:00:03-0600 | Blade Runner

(1 rows)

以下是使用cassandra-cli

查看数据的存储方式
[default@presentation] get bladerunners[B26354];
=> (name=, value=, timestamp=1427744637894310)
=> (name=data, value=46696c656420616e64206d6f6e69746f7265642e, timestamp=1427744637894310)
=> (name=name, value=5269636b204465636b617264, timestamp=1427744637894310)
=> (name=ts, value=0000014b938c09a2, timestamp=1427744637894310)
=> (name=type, value=426c6164652052756e6e6572, timestamp=1427744637894310)
Returned 5 results.
Elapsed time: 7.67 msec(s).

我现在将删除此行的data列,生成一个墓碑:

DELETE data FROM bladerunners WHERE id='B26354';

当我使用tracing on进行选择时,我可以看到该列显示" null"我有一块墓碑。

aploetz@cqlsh:presentation> SELECT * FROM bladerunners WHERe id='B26354';

 id     | data | name         | ts                       | type
--------+------+--------------+--------------------------+--------------
 B26354 | null | Rick Deckard | 2015-02-16 12:00:03-0600 | Blade Runner

...

Read 1 live and 1 tombstoned cells [SharedPool-Worker-2] | 2015-06-10 08:42:25.858000 | 192.168.23.129 |           2173

所以我会将bladerunners表格gc_grace_seconds设为零:

ALTER TABLE bladerunners WITH gc_grace_seconds=0;

从(Linux)命令行,我将刷新并压缩我的presentation密钥空间:

aploetz@dockingBay94:/local/dsc-cassandra-2.1.4$ bin/nodetool flush
aploetz@dockingBay94:/local/dsc-cassandra-2.1.4$ bin/nodetool compact presentation

当我使用tracing on进行选择时,我可以看到data列仍然是" null,"但是现在墓碑已经消失了。

我现在将重新插入时间戳为1的data列:

INSERT INTO bladerunners (id, data) VALUES ('B26354','Filed and monitored') USING TIMESTAMP 1;

使用cassandra-cli查询时,现在就是我所看到的:

[default@presentation] get bladerunners[B26354];
=> (name=, value=, timestamp=1427744637894310)
=> (name=data, value=46696c656420616e64206d6f6e69746f726564, timestamp=1)
=> (name=name, value=5269636b204465636b617264, timestamp=1427744637894310)
=> (name=ts, value=0000014b938c09a2, timestamp=1427744637894310)
=> (name=type, value=426c6164652052756e6e6572, timestamp=1427744637894310)
Returned 5 results.
Elapsed time: 4.7 msec(s).

请注意,data列现在的时间戳为1。

尝试使用tracing on运行您的查询,看看您的墓碑是否真的消失了。另外,通过cassandra-cli检查您的表格,看看时间戳是如何通过的。如果您需要澄清任何这些步骤,请与我们联系。

注意:我只是在示例或练习中显示了flush / compact。我不得不提一下,如果可能的话,DataStax建议用户 避免 手动运行nodetool compact

答案 1 :(得分:1)

BryceAtNetwork23的回答可能是“最正确的”,它确实附带了一个警告,你必须在每个节点上运行nodetool flush和nodetool compact (或者从我对3节点Cassandra的测试看来簇)。这可能需要很长时间。

作为另一种解决方案(对于将来访问此处的人),您可以获取最终要删除的行。

cqlsh> select id from example_table where some_field = -1 allow filtering;

然后将其转储到用于删除相关行的文件中。

cat cassandra-output | sort | uniq | grep '^ ' | grep -v id | gawk '{ print $1 }' >just-ids.txt
cat just-ids.txt | gawk '{ print "delete from example_table where id='\''"$1"'\'' and some_field = -1;" } >remove.cql
cqlsh ... -f remove.cql

我发现Cassandra Dump然后我用它来转储剩余的数据。 之后,我可以删除并重新创建表(如果需要,还可以重建索引),然后重新加载数据。

最后,我可以插入我拥有的行,但是有新的时间戳:

cat just-ids.txt | gawk '{ print "insert into example_table (id,some_field) values('\''"$1"'\'', -1) using timestamp 0;" }' >repair.cql
cqlsh ... -f repair.cql

如果您反复这样做,您当然可以放下表格并使用修复后的数据重新加载。当你反复重装时,它比冲洗/紧凑更快。