为什么Cassandra 1.2中会发生数据损坏?

时间:2014-11-04 23:12:18

标签: cassandra

我几天前在Cassandra 1.2中删除了一个专栏: 放下整张桌子 2.重新创建没有列的表, 3.插入insert语句(不带列)。

我这样做的原因是因为Cassandra 1.2不支持" drop column"操作

今天,由于数据损坏问题,Ops团队通知了我。 我的问题:

  1. 根本原因是什么?
  2. 如何解决?

    ERROR [ReadStage:79] 2014-11-04 11:29:5521 CassandraDaemon.java(第191行)线程中的异常线程[ReadStage:79,5,main] org.apache.cassandra.io.sstable.CorruptSSTableException:org.apache.cassandra.db.ColumnSerializer $ CorruptColumnException:列名长度无效0(/data/cassandra/data/xxx/yyy/zzzferences.db,剩余1799885字节)     在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:110)     在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:40)     在com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)     在com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)     at org.apache.cassandra.db.columniterator.SSTableSliceIterator.hasNext(SSTableSliceIterator.java:90)     在org.apache.cassandra.db.filter.QueryFilter $ 2.getNext(QueryFilter.java:171)     在org.apache.cassandra.db.filter.QueryFilter $ 2.hasNext(QueryFilter.java:154)     at org.apache.cassandra.utils.MergeIterator $ OneToOne.computeNext(MergeIterator.java:199)     在com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)     在com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)     在org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:160)     在org.apache.cassandra.db.filter.QueryFilter.collat​​eColumns(QueryFilter.java:136)     在org.apache.cassandra.db.filter.QueryFilter.collat​​eOnDiskAtom(QueryFilter.java:84)     在org.apache.cassandra.db.Collat​​ionController.collectAllData(Collat​​ionController.java:291)     在org.apache.cassandra.db.Collat​​ionController.getTopLevelColumns(Collat​​ionController.java:65)     在org.apache.cassandra.db.ColumnFamilyStore.getTopLevelColumns(ColumnFamilyStore.java:1398)     在org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1214)     在org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1130)     在org.apache.cassandra.db.Table.getRow(Table.java:344)     在org.apache.cassandra.db.SliceFromReadCommand.getRow(SliceFromReadCommand.java:70)     在org.apache.cassandra.db.ReadVerbHandler.doVerb(ReadVerbHandler.java:44)     在org.apache.cassandra.net.MessageDeliveryTask.run(MessageDeliveryTask.java:56)     at java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(Unknown Source)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)     在java.lang.Thread.run(未知来源) 引起:org.apache.cassandra.db.ColumnSerializer $ CorruptColumnException:列名长度无效0(/data/cassandra/data/xxx/yyy/zzzferences.db,剩余1799885字节)     at org.apache.cassandra.db.ColumnSerializer $ CorruptColumnException.create(ColumnSerializer.java:148)     at org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:86)     at org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:73)     在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:106)     ......还有24个 ERROR [ReadStage:89] 2014-11-04 11:29:58,876 CassandraDaemon.java(第191行)线程中的异常线程[ReadStage:89,5,main] java.lang.OutOfMemoryError:Java堆空间     在org.apache.cassandra.io.util.RandomAccessReader.readBytes(RandomAccessReader.java:376)     在org.apache.cassandra.utils.ByteBufferUtil.read(ByteBufferUtil.java:392)     在org.apache.cassandra.utils.ByteBufferUtil.readWithLength(ByteBufferUtil.java:355)     在org.apache.cassandra.db.ColumnSerializer.deserializeColumnBody(ColumnSerializer.java:108)     at org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:92)     at org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:73)     在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:106)     在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:40)     在com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)     在com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)     at org.apache.cassandra.db.columniterator.SSTableSliceIterator.hasNext(SSTableSliceIterator.java:90)     在org.apache.cassandra.db.filter.QueryFilter $ 2.getNext(QueryFilter.java:171)     在org.apache.cassandra.db.filter.QueryFilter $ 2.hasNext(QueryFilter.java:154)     在org.apache.cassandra.utils.MergeIterator $ OneToOne.computeNext(MergeIterator.java:199)

1 个答案:

答案 0 :(得分:5)

C * 1.2支持cql表的列删除 - http://www.datastax.com/documentation/cql/3.0/cql/cql_using/use_delete.html

但是,我没有看到您描述的重新创建没有列的新表的过程有任何问题。以下是一些前进的步骤。

假设 -

  1. 您看到的腐败是在新表中而不是旧表中 (他们有相同的名字吗?)

  2. 您有一个复制因子和高数量的节点 足以使您能够使此节点脱机

  3. 您的客户端负载均衡策略已正确设置 当节点发生故障时,它将故障转移到另一个节点

  4. 程序 -

    1)使您的节点脱机

    nodetool drain
    

    这将刷新memtables并使您的节点停止接受请求。

    2)运行nodetool scrub

    nodetool scrub [keyspace][table]
    

    如果成功完成,那么您就完成了,通过重新启动cassandra并运行nodetool repair keyspace table

    来备份节点

    3)如果擦除错误(可能存在损坏错误),请尝试使用sstablescrub实用程序。 ssh进入你的盒子并运行:

    sstablescrub <keyspace> <table>

    注意,使用您用来启动cassandra的相同操作系统用户运行此命令。

    如果成功完成,那么您就完成了,通过重新启动cassandra并运行nodetool repair keyspace table

    来备份节点

    4)如果这不起作用(再次出现损坏错误),则必须删除SStable并使用修复从其他副本重建它:

    • 将罪魁祸首从您的数据目录下载到备份目录
    • 重启cassandra (一旦重建后删除它)
    • nodetool repair keyspace cf - 此修复需要时间。

    如果您能够重现这种腐败,请告诉我。