当ALTER TABLE ADD COLUMN到具有现有数据记录的表时,Cassandra需要重新启动

时间:2015-06-19 18:28:23

标签: database cassandra cassandra-2.0 dropwizard datastax

数据库:Cassandra 2.1.2(单节点)

数据库驱动程序:Cassandra驱动程序2.1.6。

应用程序:DropWizard 0.7.1

我的数据库中有一个简单的表:

cqlsh:ugc> desc table person;

CREATE TABLE abc.person (
    id uuid PRIMARY KEY
) WITH bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

该表包含一些数据:

cqlsh:ugc> select * from person;

 id
--------------------------------------
 bf56c8b1-ed0b-44d6-bd45-0d55dd73fbe0

在我的DropWizard应用程序中,我有一个映射对象:

@Table(name = "person")
public class Person {
    @PartitionKey
    @Column(name ="id")
    UUID id;


    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }
}

一切都运作良好。我能够从DropWizard应用程序中检索数据。但是,当我

1)向表中添加新列“名称”

cqlsh:ugc> ALTER TABLE abc.person ADD name text;

cqlsh:ugc> desc table person;

CREATE TABLE abc.person (
    id uuid PRIMARY KEY,
    name text
) WITH bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

cqlsh:ugc> select * from person;

 id                                   | name
--------------------------------------+------
 bf56c8b1-ed0b-44d6-bd45-0d55dd73fbe0 | null

2)更新Person对象以映射新列

@Table(name = "person")
public class Person {
    @PartitionKey
    @Column(name ="id")
    UUID id;


    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    @Column(name = "name")
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3)重启DropWizard应用程序

应用程序抛出异常:

java.lang.IllegalArgumentException: "name" is not a column defined in this metadata

错误看起来像是在说模型试图映射数据库表中不存在的列'name',实际上它是从数据库的角度出发的。

但是,如果我重新启动数据库,它似乎可以解决问题。

看起来,当表包含现有记录时,alter table需要重新启动数据库。当表为空并添加新列时(不需要重新启动),不会发生此问题。我找不到[http://docs.datastax.com/en/cql/3.0/cql/cql_reference/alter_table_r.html]处理我情况的任何文档。

问题:

有没有办法可以在不重新启动数据库的情况下更改表格?如果是这样,我该怎么办?如果没有,任何人都可以解释为什么需要重启数据库吗?

1 个答案:

答案 0 :(得分:0)

在我这边,我不需要重启DB来更新架构。我不知道你如何重新启动你的应用程序。我建议你停止你的应用程序并搜索是否有任何进程仍在为应用程序运行并启动你的应用程序。

在重新启动应用程序时,似乎某些DB连接没有中断,而您停止数据库然后强制连接停止,然后更改工作。