【问题标题】:Creating new table with cqlsh on existing keyspace: Column family ID mismatch在现有键空间上使用 cqlsh 创建新表:列族 ID 不匹配
【发布时间】:2015-05-15 20:12:59
【问题描述】:

休斯顿,我们有问题。

尝试在现有 Cassandra (v2.1.3) 键空间上使用 cqlsh 创建新表会导致:

ServerError: 
<ErrorMessage code=0000 [Server error] message="java.lang.RuntimeException:
java.util.concurrent.ExecutionException: 
    java.lang.RuntimeException:      
        org.apache.cassandra.exceptions.ConfigurationException: Column family ID mismatch (found e8c03790-c952-11e4-a753-5981ea73cd7c; expected e8b14370-c952-11e4-a844-8f10bfb9c386)">

第一次创建尝试后,再次尝试将导致:

AlreadyExists:表 'ks.metrics' 已经存在

但检索键空间 desc tables; 的现有表列表将不会报告新表。

这个问题似乎与 Cassandra-8387 有关,只是只有一个客户端试图创建表:cqlsh

我们确实有一堆 Spark 作业,它们会在启动时创建键空间和表,可能会并行执行。这会导致键空间损坏吗?

创建一个新的键空间并向其中添加一个表按预期工作。

有什么想法吗?

更新

找到了解决方法:对键空间进行修复,然后表格将出现 (desc tables) 并且也可以正常工作。

【问题讨论】:

  • 很好的修复。我打算建议删除底层目录和文件......特别是如果架构不同。
  • 修复对我不起作用 $ nodetool repair -- testks [2015-07-04 03:28:54,612] 没有什么可以修复密钥空间“testks”
  • 在单节点集群上出现同样的错误,显然修复没用。无奈之下不得不重新开始。有更新吗?
  • 您应该发布您的更新作为您自己问题的答案,并选择它作为答案。这样人们就知道您已经解决了问题,而其他有相同问题的人也知道解决方案是什么(在页面上的正确位置)。
  • @gsteiner 正如我在问题中提到的,这是一种解决方法,而不是解决问题的方法。

标签: cassandra schema cqlsh


【解决方案1】:

简答: They have a race condition,他们认为他们在 1.1.8...

中解决了这个问题

长答案:

我一直在我的一个集群上收到该错误。我有测试机器的硬盘驱动器非常慢,当我在两台不同的计算机上有 4 个节点时,创建一两个表就足以得到错误。

下面是我安装的 Cassandra 3.7 的堆栈跟踪副本。虽然你的版本是 2.1.3,但我会很惊讶这部分代码改变了这么多。

正如我们所见,异常发生在validateCompatibility() 函数中。这就要求新旧版本的 MetaData 有这些相等的:

  • ksName(键空间名称)
  • cfName(列族名)
  • cfId(列族 UUID)
  • 标志(isSuper、isCounter、isDense、isCompound)
  • 比较器(键排序比较器)

如果这些值中的任何一个在新旧元数据之间不匹配,则该过程会引发异常。在我们的例子中,cfId 的值是不同的。

向上堆栈,我们有apply(),它立即调用validateCompatibility()

接下来是updateTable()。同样,它几乎立即调用apply()。首先它调用getCFMetaData() 来检索将要与新数据进行比较的当前列族数据(“旧”)。

接下来我们看到updateKeyspace()。该函数计算 diff 以了解发生了什么变化。然后它将其保存在每种类型的数据中。表在 Type 之后排在第二位...

在此之前,他们有 mergeSchema(),它计算在 Keyspace 级别发生了什么变化。然后,它会删除已删除的键空间,并为更新的键空间(以及新的键空间)生成新的键空间。最后,它们循环遍历每个调用 updateKeyspace() 的新键空间。

接下来在堆栈中我们看到一个有趣的函数:mergeSchemaAndAnnounceVersion()。一旦在内存和磁盘上更新了键空间,这将更新版本。架构的版本包括不兼容的 cfID,因此会生成异常。 Announce 部分是向其他节点发送八卦消息,告知该节点现在知道某个模式的新版本。

接下来我们会看到一个名为MigrationTask 的东西。这是用于在 Cassandra 节点之间迁移更改的消息。消息负载是突变的集合(由mergeSchema() 函数处理。)

堆栈的其余部分仅显示 run() 函数,它们是用于处理消息的各种类型的函数。

就我而言,对我来说,问题稍后会得到解决,一切都很好。我与架构最终同步无关。正如预期的那样。但是,它阻止我一次性创建所有表。因此,我对此的看法是迁移消息未按预期顺序到达。必须有一个通过重新发送事件来处理并产生混淆的超时。

所以,让我们首先看一下发送消息的代码,您可以在 MigrationManager 中看到该代码。在这里,我们有一个 MIGRATION_DELAY_IN_MS 参数与旧问题 Schema push/pull race 链接,这是为了避免竞争条件。嗯……给你。所以他们知道可能存在竞争条件,为了避免它,他们在那里增加了一点延迟。该修复的一部分包括版本检查。如果版本已经相同,请完全避免更新(即忽略该八卦)。

if (Schema.instance.getVersion().equals(currentVersion))
{
    logger.debug("not submitting migration task for {} because our versions match", endpoint);
    return;
}

我们所说的延迟是一分钟:

public static final int MIGRATION_DELAY_IN_MS = 60000;

人们会认为整整一分钟就足够了,但不知何故,我仍然总是得到错误。

事实是,他们的代码不希望发生多个更改一个接一个,包括像我这样的大延迟。所以如果我要创建一个表,然后做其他事情,我会很好。另一方面,当我想在那些慢速机器上连续创建 20 个表时,来自先前模式更改的八卦消息到达较晚(即在新的 CREATE TABLE 命令到达该节点之后。)那是我得到那个错误的时候.我猜最糟糕的部分是它是一个虚假错误(即它告诉我八卦是后来的,而不是我的架构无效并且八卦消息中的架构是旧的。)

org.apache.cassandra.exceptions.ConfigurationException: Column family ID mismatch (found 122a2d20-9e13-11e6-b830-55bace508971; expected 1213bef0-9e
    at org.apache.cassandra.config.CFMetaData.validateCompatibility(CFMetaData.java:790) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.config.CFMetaData.apply(CFMetaData.java:750) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.config.Schema.updateTable(Schema.java:661) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.updateKeyspace(SchemaKeyspace.java:1350) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.mergeSchema(SchemaKeyspace.java:1306) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.mergeSchemaAndAnnounceVersion(SchemaKeyspace.java:1256) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.service.MigrationTask$1.response(MigrationTask.java:92) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.net.ResponseVerbHandler.doVerb(ResponseVerbHandler.java:53) [apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.net.MessageDeliveryTask.run(MessageDeliveryTask.java:64) [apache-cassandra-3.9.jar:3.9]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_111]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]

【讨论】:

  • 实际上,有人说(CASSANDRA-5025«架构迁移往往会突然发生 - 所以这个补丁似乎可以减少问题但不能消除它。»所以我猜至少有人可能记得这仍然是一个(潜在的)问题。
  • 在我看来延迟只是一种黑客行为,而且他们在设计中没有正确解决接收这些请求的异步性质。您的设置暴露了这种从未得到修复的竞争条件。
  • 显然仍然存在于Cassandra 3.11.0
  • 3.11.3 - 同样的问题
【解决方案2】:

我错误地有两个不同的表模式具有相同的表名。所以这个问题发生了(我使用的是express-cassandra

【讨论】:

    猜你喜欢
    • 2016-12-22
    • 2013-08-13
    • 2018-06-04
    • 2013-09-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2021-08-15
    相关资源
    最近更新 更多