【问题标题】:Why is data corruption happen in Cassandra 1.2?为什么 Cassandra 1.2 会发生数据损坏?
【发布时间】:2015-01-01 00:48:42
【问题描述】:

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

之所以这样做,是因为 Cassandra 1.2 不支持“drop column”操作。

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

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

    错误 [ReadStage:79] 2014-11-04 11:29:55,021 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/zzz-Data.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) 在 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) 在 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) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 java.lang.Thread.run(未知来源) 原因:org.apache.cassandra.db.ColumnSerializer$CorruptColumnException:无效列名长度 0(/data/cassandra/data/xxx/yyy/zzz-Data.db,剩余 1799885 字节) 在 org.apache.cassandra.db.ColumnSerializer$CorruptColumnException.create(ColumnSerializer.java:148) 在 org.apache.cassandra.db.OnDiskAtom$Serializer.deserializeFromSSTable(OnDiskAtom.java:86) 在 org.apache.cassandra.db.OnDiskAtom$Serializer.deserializeFromSSTable(OnDiskAtom.java:73) 在 org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:106) ... 24 更多 错误 [ReadStage:89] 2014-11-04 11:29:58,076 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) 在 org.apache.cassandra.db.OnDiskAtom$Serializer.deserializeFromSSTable(OnDiskAtom.java:92) 在 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) 在 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)

【问题讨论】:

标签: cassandra


【解决方案1】:

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

但是,从您描述的在没有您的列的情况下重新创建新表的过程中,我没有发现任何问题。这里有一些前进的步骤。

假设 -

  1. 您看到的损坏出现在新表中,而不是旧表中 (他们有相同的名字吗?)

  2. 您的复制因子和节点数很高 足以让您能够使该节点脱机

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

程序 -

1) 让您的节点离线

nodetool drain

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

2) 运行 nodetool 清理

nodetool scrub [keyspace][table]

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

3) 如果清理出错(可能带有损坏错误),请尝试 sstablescrub 实用程序。 ssh 进入你的盒子并运行:

sstablescrub <keyspace> <table>

注意,使用与启动 cassandra 相同的操作系统用户运行。

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

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

  • 将罪魁祸首 sstable 从数据目录移动到备份目录
  • 重启卡桑德拉 (重建后删除)
  • nodetool repair keyspace cf -- 修复需要时间。

如果您能够重现此损坏,请告诉我。

【讨论】:

  • 我的运维工程师发现了这个问题。这是由于密钥缓存。在她的调查中,她使 keycache 无效,并删除/重新创建表,这一次一切正常。
猜你喜欢
  • 2019-10-23
  • 1970-01-01
  • 2021-12-11
  • 2010-10-31
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多