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

Cassandra: Insert with older timestamp

(Cassandra 2.0.9,使用 CQL)

我不小心更新了 table 中的一行,该行正在管理自己的时间戳(100 * 特定序列号)。现在,因为我的时间戳是当前时间,所以 none 更新有效。我明白这是为什么,但我正在努力从中恢复过来。我很幸运,我可以删除这些行。

我已经将 gc_grace_seconds 设置为 0 并且 运行 table 其中 key=primarykey 删除行。之后,我在每个节点 上使用 nodetool flushnodetool compact 进行删除通过并压缩和擦除生成的墓碑。然后我将 gc_grace_seconds 倒退了 10 天,并尝试 插入 具有相同键但 使用时间戳 1 .

这行不通。只是想知道是否有人犯过类似的错误并解决了它?

我想我会试试这个练习。

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';

当我 SELECT 和 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 table 的 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

当我 SELECT 和 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 检查您的 table 以查看时间戳是如何通过的。如果您需要对这些步骤中的任何一个进行说明,请告诉我。

注意: 我只是将 flush/compact 作为示例或练习的一部分展示。我不得不提到 DataStax 建议用户 避免 手动 运行 nodetool compact 如果可能的话。

BryceAtNetwork23 的答案很可能是 "most correct",它确实附带一个警告,即 你必须 运行 每个节点上的 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  }' >just-ids.txt
cat just-ids.txt | gawk '{ print "delete from example_table where id='\''""'\'' and some_field = -1;" } >remove.cql
cqlsh ... -f remove.cql

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

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

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

如果您重复执行此操作,您当然可以删除 table 并使用 post-修复数据重新加载它。当您反复重新加载时,这是一个比 flush/compact.

更快的解决方案