Cassandra:使用较旧的时间戳插入
Cassandra: Insert with older timestamp
(Cassandra 2.0.9,使用 CQL)
我不小心更新了 table 中的一行,该行正在管理自己的时间戳(100 * 特定序列号)。现在,因为我的时间戳是当前时间,所以 none 更新有效。我明白这是为什么,但我正在努力从中恢复过来。我很幸运,我可以删除这些行。
我已经将 gc_grace_seconds 设置为 0 并且 运行 从 table 其中 key=primarykey 删除行。之后,我在每个节点 上使用 nodetool flush 和 nodetool 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.
更快的解决方案
(Cassandra 2.0.9,使用 CQL)
我不小心更新了 table 中的一行,该行正在管理自己的时间戳(100 * 特定序列号)。现在,因为我的时间戳是当前时间,所以 none 更新有效。我明白这是为什么,但我正在努力从中恢复过来。我很幸运,我可以删除这些行。
我已经将 gc_grace_seconds 设置为 0 并且 运行 从 table 其中 key=primarykey 删除行。之后,我在每个节点 上使用 nodetool flush 和 nodetool 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.
更快的解决方案