我打算将我的列从非冻结更改为冻结,我想知道是否有任何将冻结列更新为墓碑生成的指南。在一些博客中写道,更新冻结列会生成行墓碑,这是正确的吗?
想了解墓碑生成与冻结列更新的概念。
我假设您的意思是您打算“冻结”集合,因为您无法冻结列。无论如何,更新冻结集合不会生成墓碑。
设置非冻结集合的值会生成墓碑,因为要完全清除或擦除集合以前的值。 Cassandra 不会执行先读后写(轻量级事务的情况除外),因此它不知道是否存在保存集合元素的单元格,因此它需要写入逻辑删除,以便任何较旧的单元格不会返回读取请求。
相比之下,冻结集合被序列化为单个值而不是单个元素,因此整个值都会更新。由于冻结集合的值存储在一个单元格中,因此不需要墓碑来使较旧的预先存在的单元格无效。
如果您自己进行快速测试,您就可以自己解决这些问题。为了完整起见,我将用这个示例表来说明,其中包含冻结的
set
和常规 set
集合:
CREATE TABLE community.freeze_test (
pkey int PRIMARY KEY,
frozenset frozen<set<text>>,
setcol set<text>
)
首先,我们创建一个新分区:
INSERT INTO freeze_test (pkey, frozenset, setcol)
VALUES (1, {'apple', 'banana'}, {'avocado', 'blueberries'})
然后使用
nodetool flush
将memtable刷新到磁盘,转储SSTable的内容:
$ sstabledump nb-1-big-Data.db
[
{
"partition" : {
"key" : [ "1" ],
"position" : 0
},
"rows" : [
{
"type" : "row",
"position" : 18,
"liveness_info" : { "tstamp" : "2024-07-05T06:58:41.192323Z" },
"cells" : [
{ "name" : "frozenset", "value" : ["apple", "banana"] },
{ "name" : "setcol", "deletion_info" : { "marked_deleted" : "2024-07-05T06:58:41.192322Z", "local_delete_time" : "2024-07-05T06:58:41Z" } },
{ "name" : "setcol", "path" : [ "avocado" ], "value" : "" },
{ "name" : "setcol", "path" : [ "blueberries" ], "value" : "" }
]
}
]
}
]%
请注意,
frozenset
只是一个单元格值:
{ "name" : "frozenset", "value" : ["apple", "banana"] }
但是非冻结集合有一个墓碑标记,并且每个
set
元素跨越多个单元格:
{ "name" : "setcol", "deletion_info" : { "marked_deleted" : "2024-07-05T06:58:41.192322Z", "local_delete_time" : "2024-07-05T06:58:41Z" } },
{ "name" : "setcol", "path" : [ "avocado" ], "value" : "" },
{ "name" : "setcol", "path" : [ "blueberries" ], "value" : "" }
如果我们使用
frozenset
设置 UPDATE
,它会用新值覆盖单元格,并且没有逻辑删除:
UPDATE freeze_test SET frozenset = {'oranges'} WHERE pkey = 1;
"cells" : [
{ "name" : "frozenset", "value" : ["oranges"], "tstamp" : "2024-07-05T07:02:11.064353Z" }
]
如果我们更新非冻结集合:
UPDATE freeze_test SET setcol = {'grapes','strawberries'} WHERE pkey = 1;
请注意,墓碑也与新单元格一起生成:
"cells" : [
{ "name" : "setcol", "deletion_info" : { "marked_deleted" : "2024-07-05T07:03:42.962302Z", "local_delete_time" : "2024-07-05T07:03:42Z" } },
{ "name" : "setcol", "path" : [ "grapes" ], "value" : "", "tstamp" : "2024-07-05T07:03:42.962303Z" },
{ "name" : "setcol", "path" : [ "strawberries" ], "value" : "", "tstamp" : "2024-07-05T07:03:42.962303Z" }
]
最后,如果我使用
+=
运算符将一个元素添加到非冻结集合中:
UPDATE freeze_test SET setcol += {'mango'} WHERE pkey = 1;
SSTable 只有一个单元格:
"cells" : [
{ "name" : "setcol", "path" : [ "mango" ], "value" : "", "tstamp" : "2024-07-05T07:07:41.407898Z" }
]
从非冻结
set
集合中添加或删除元素不会生成逻辑删除,因为 Cassandra 不需要清除集合的现有内容。干杯!