2015-06-19 49 views
0

数据库:卡桑德拉2.1.2(单节点)卡桑德拉需要重新启动时,ALTER TABLE ADD COLUMN表与现有的数据记录

数据库驱动程序:卡桑德拉驱动程序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 

错误看起来像它说的模型试图映射列“名”并不在数据库表中,而实际上它从视图的数据库点的存在。

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

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

问:

有没有一种方法我可以改变一个表,无需重新启动我的数据库?如果是这样,我该怎么做?如果没有,任何人都可以解释为什么需要重新启动数据库?

+0

我认为当你重新启动DB你不解决这个问题要么,你重新创建表后,你固定的问题。 – wherby

+0

我没有重新创建表格。我刚刚重新启动了数据库,似乎解决了这个问题。否则,我会失去所有的旧数据。 – dlee

+0

当您重新启动应用程序时,是否检查另一个java进程,以确定应用程序仍在运行? – wherby

回答

0

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

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

+0

所有进程在重新启动应用程序后终止。 更改空表上的模式正常工作,但当表包含数据时,它有一些问题,我不得不重新启动我的数据库。不知道为什么。 – dlee