在现有键空间上使用cqlsh创建新表:列族ID不匹配

maa*_*asg 22 schema cassandra cqlsh

休斯顿,我们有一个问题.

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

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)">
Run Code Online (Sandbox Code Playgroud)

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

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

但是检索密钥空间的现有表列表desc tables;将不会报告新表.

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

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

创建新的键空间并向其添加表可以按预期工作.

有任何想法吗?

UPDATE

找到一个解决方法:在键空间上发出修复,表格将出现(desc tables)并且也可以正常运行.

Ale*_*lke 8

简短的回答: 他们有竞争条件,他们认为他们在1.1.8中解决了......


答案很长:

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

下面我从Cassandra 3.7安装中获得了堆栈跟踪的副本.虽然你的版本是2.1.3,但我会惊讶于这部分代码改变了那么多.

我们可以看到,异常发生在validateCompatibility()函数中.这要求MetaData的新旧版本具有以下相同:

  • ksName(键空间名称)
  • cfName(columnfamily名称)
  • cfId(columnfamily UUID)
  • flags(isSuper,isCounter,isDense,isCompound)
  • 比较器(键排序比较器)

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

上升堆栈,我们立即apply()调用validateCompatibility().

接下来我们有updateTable().同样,它apply()几乎立即调用.首先,它调用getCFMetaData()以检索将与新数据进行比较的当前列族数据("旧").

接下来我们看到updateKeyspace().该函数计算a diff以了解更改的内容.然后它将其保存在每种类型的数据中.表格在Type之后排名第二...

在此之前,他们有mergeSchema()计算在Keyspace级别改变的内容.然后删除已删除的键空间,并为更新的键空间(以及新的键空间)生成新的键空间.最后,它们遍历新的密钥空间,updateKeyspace()为每个密钥空间调用它们.

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

接下来我们看到一些名为MigrationTask.这是用于在Cassandra节点之间迁移更改的消息.消息有效负载是一组突变(由mergeSchema()函数处理的突变).

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

在我的情况下,对我来说,问题稍后得到解决,一切都很顺利.我最终无法与模式进行同步.正如所料.但是,它阻止我一次创建所有表.所以,我的看法是迁移消息没有按预期的顺序到达.必须有一个超时,通过重新发送事件并产生混淆来处理.

那么,让我们先看看发送消息的代码,你会在MigrationManager中看到一个.这里我们有一个MIGRATION_DELAY_IN_MS参数链接旧问题,Schema推/拉竞赛,这是为了避免竞争条件.嗯......你走了.因此他们意识到存在可能的竞争条件,并试图避免它,他们在那里增加了一点延迟.该修复程序的一部分包括版本检查.如果版本已经相等,则完全避免更新(即忽略该八卦).

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

我们谈论的延迟是一分钟:

public static final int MIGRATION_DELAY_IN_MS = 60000;
Run Code Online (Sandbox Code Playgroud)

人们会认为一分钟就足够了,但不知怎的,我仍然总是得到错误.

事实是,他们的代码并不期望一个接一个地发生多个变化,包括像我这样的大延迟.所以,如果我要创建一个表,然后做其他事情,我会很好.另一方面,当我想在那些慢速机器上连续创建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]
Run Code Online (Sandbox Code Playgroud)

  • 显然仍然出现在``Cassandra 3.11.0``中 (5认同)
  • 3.11.3 - 同样的问题 (3认同)