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

jan*_*ith 1 cassandra

我几天前在Cassandra 1.2中删除了一个列:1.删除整个表,2.重新创建表,没有列,3.插入insert语句(没有列).

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

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

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

    错误[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:org.apache.cassandra.db.columniterator.SimpleSliceReader中无效的列名长度为0(/data/cassandra/data/xxx/yyy/zzzferences.db,剩余1799885个字节). 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)在org.apache.cassandra.db.columniterator.SSTableSliceIterator.hasNext(SSTableSliceIterator.java:90)在org.apache.cassandra.db.filter.QueryFilter位于org.apache.cassandra.utils的org.apache.cassandra.db.filter.QueryFilter $ 2.hasNext(QueryFilter.java:154)$ 2.getNext(QueryFilter.java:171).meerIterator $ 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的org.apache.cassandra.db.filter.QueryFilter.collat​​eColumns(QueryFilter.java:136). 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)atg.apache.cassandra.db.Table.getRow(T able.java:344)在org.apache.cassandra.db.SliceFromReadCommand.getRow(SliceFromReadCommand.java:70)在org.apache.cassandra.db.ReadVerbHandler.doVerb(ReadVerbHandler.java:44)在org.apache.cassandra java.util.concurrent.ThreadPoolExecutor中的.net.MessageDeliveryTask.run(MessageDeliveryTask.java:56)java.lang上的java.util.concurrent.ThreadPoolExecutor $ Worker.run(未知来源)中的$ Worker.runTask(未知来源). Thread.run(未知来源)由以下原因引起:org.apache.cassandra.db.ColumnSerializer $ CorruptColumnException:无效的列名长度为0(/data/cassandra/data/xxx/yyy/zzzferences.db,剩余1799885字节)at at org.apache.cassandra.db.ColumnSerializer $ CorruptColumnException.create(ColumnSerializer.java:148)位于org.apache.cassandra.db的org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:86).在org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:106)的OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:73).. .24 more ERROR [ReadStage:89] 2014-11-04 11:29:58,876 CassandraDaemon.java(第191行)线程中的异常Thread [ReadStage:89,5,main] java.lang.OutOfMemoryError:org中的Java堆空间.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)在org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:92)的组织. 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)at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)at co m.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)位于org.apache.cassandra.db.filter的org.apache.cassandra.db.columniterator.SSTableSliceIterator.hasNext(SSTableSliceIterator.java:90). 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)

pha*_*act 5

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

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

假设 -

  1. 你看到的腐败是在新表中而不是旧表中(它们是否具有相同的名称?)

  2. 您具有复制因子和足够高的节点数,以便您可以使此节点脱机

  3. 您的客户端的负载平衡策略已正确设置,以便在节点关闭时它将故障转移到另一个节点

程序 -

1)使您的节点脱机

nodetool drain
Run Code Online (Sandbox Code Playgroud)

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

2)运行nodetool scrub

nodetool scrub [keyspace][table]
Run Code Online (Sandbox Code Playgroud)

如果此操作成功完成,那么您就完成了,通过重新启动cassandra并运行nodetool来备份节点 repair keyspace table

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

sstablescrub <keyspace> <table>

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

如果此操作成功完成,那么您就完成了,通过重新启动cassandra并运行nodetool来备份节点 repair keyspace table

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

  • mv罪犯sstable从您的数据目录到备份目录
  • 重启cassandra(重建后再删除)
  • nodetool repair keyspace cf - 这种修复需要时间.

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