【问题标题】:In Cassandra, why dropping a column from tables defined with compact storage not allowed?在 Cassandra 中,为什么不允许从使用紧凑存储定义的表中删除列?
【发布时间】:2020-12-24 00:54:12
【问题描述】:

根据 datastx 文档 here,我们无法从使用 COMPACT STORAGE 选项定义的表中删除列。这是什么原因?

【问题讨论】:

    标签: cassandra cql3 cassandra-cli


    【解决方案1】:

    这可以追溯到 CQL3 的原始实现,并进行了更改以允许它在原始基于 Thrift 的存储引擎之上抽象出“类似 SQL”的宽行结构。最终,架构管理归结为底层结构是 table 还是 column_family

    例如,我将使用旧安装的 Apache Cassandra (2.1.19) 创建两个表:

    CREATE TABLE student (
      studentid TEXT PRIMARY KEY,
      fname TEXT,
      name TEXT);
    
    CREATE TABLE studentcomp (
      studentid TEXT PRIMARY KEY,
      fname TEXT,
      name TEXT)
    WITH COMPACT STORAGE;
    

    我将在每个表中插入一行:

    INSERT INTO student (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');
    INSERT INTO studentcomp (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');
    

    然后我将使用旧的 cassandra-cli 工具查看表格:

    [default@stackoverflow] list student;
    Using default limit of 100
    Using default cell limit of 100
    -------------------
    RowKey: janderson
    => (name=, value=, timestamp=1599248215128672)
    => (name=fname, value=4a6f726479, timestamp=1599248215128672)
    => (name=lname, value=416e646572736f6e, timestamp=1599248215128672)
    
    [default@stackoverflow] list studentcomp;
    Using default limit of 100
    Using default cell limit of 100
    -------------------
    RowKey: janderson
    => (name=fname, value=Jordy, timestamp=1599248302715066)
    => (name=lname, value=Anderson, timestamp=1599248302715066)
    

    您看到第一个结果中的空/“ghost”列值了吗?该空列值是 CQL3 在列值和表元数据之间的链接。如果不存在,则不能使用 CQL 管理表的列。

    用于类型转换的比较器是通过 Thrift 真正公开的所有内容。这种元数据控制/暴露的缺乏使得 Cassandra 在 CQL 之前的日子里被认为是“无模式的”。如果我在 cassandra-cli 中运行 describe studentcomp,我可以看到使用的比较器(验证类):

    Column Metadata:
      Column Name: lname
        Validation Class: org.apache.cassandra.db.marshal.UTF8Type
      Column Name: fname
        Validation Class: org.apache.cassandra.db.marshal.UTF8Type
    

    但如果我尝试describe student,我会看到:

    WARNING: CQL3 tables are intentionally omitted from 'describe' output.
    See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details.
    
    Sorry, no Keyspace nor (non-CQL3) ColumnFamily was found with name: student (if this is a CQL3 table, you should use cqlsh instead)
    

    基本上,表和列族是强制进入同一个存储桶的不同实体。添加WITH COMPACT STORAGE 实质上使表成为列族。 随之而来的是,除了对比较器的访问之外,缺少任何模式管理(添加或删除列)。

    编辑 20200905

    我们可以以某种方式/某种方式(hack)从表中删除列吗?

    可能能够做到这一点。 Sylvain Lebresne 写了A Thrift to CQL3 Upgrade Guide,它将为您提供一些必要的细节。我还建议通读上面提到的 Jira 票证 (CASSANDRA-4377),因为它涵盖了许多使这变得困难的深入技术挑战。

    【讨论】:

    • 我们能否以某种方式/某种方式(hack)从表中删除列。在添加列之前,我有系统表的旧备份。我正在考虑关闭我的所有节点并从 schema_columns 目录中的备份恢复旧的 sstables。但它没有工作?
    • @ManishKhandelwal 已编辑。祝你好运!
    • 试过(回滚系统表)并成功,但我很担心在生产中申请。我正在考虑删除表并使用相同的名称重新创建并插入数据。
    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 2016-07-08
    相关资源
    最近更新 更多