[ https://issues.apache.org/jira/browse/CASSANDRA-10536?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sam Tunnicliffe reassigned CASSANDRA-10536: ------------------------------------------- Assignee: Sam Tunnicliffe (was: Sylvain Lebresne) > Batch statements with multiple updates to partition error when table is > indexed > ------------------------------------------------------------------------------- > > Key: CASSANDRA-10536 > URL: https://issues.apache.org/jira/browse/CASSANDRA-10536 > Project: Cassandra > Issue Type: Bug > Components: Core > Reporter: Tyler Hobbs > Assignee: Sam Tunnicliffe > Fix For: 3.0.0 rc2 > > > If a {{BATCH}} statement contains multiple {{UPDATE}} statements that update > the same partition, and a secondary index exists on that table, the batch > statement will error: > {noformat} > ServerError: <ErrorMessage code=0000 [Server error] > message="java.lang.IllegalStateException: An update should not be written > again once it has been read"> > {noformat} > with the following traceback in the logs: > {noformat} > ERROR 20:53:46 Unexpected exception during request > java.lang.IllegalStateException: An update should not be written again once > it has been read > at > org.apache.cassandra.db.partitions.PartitionUpdate.assertNotBuilt(PartitionUpdate.java:504) > ~[main/:na] > at > org.apache.cassandra.db.partitions.PartitionUpdate.add(PartitionUpdate.java:535) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.UpdateStatement.addUpdateForKey(UpdateStatement.java:96) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.ModificationStatement.addUpdates(ModificationStatement.java:667) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.getMutations(BatchStatement.java:234) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:335) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:321) > ~[main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:316) > ~[main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:205) > ~[main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:471) > ~[main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:448) > ~[main/:na] > at > org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:130) > ~[main/:na] > at > org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:507) > [main/:na] > at > org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:401) > [main/:na] > at > io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext.access$700(AbstractChannelHandlerContext.java:32) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext$8.run(AbstractChannelHandlerContext.java:324) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) > [na:1.8.0_45] > at > org.apache.cassandra.concurrent.AbstractTracingAwareExecutorService$FutureTask.run(AbstractTracingAwareExecutorService.java:164) > [main/:na] > at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:105) > [main/:na] > at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] > {noformat} > This is due to {{SecondaryIndexManager.validate()}} triggering a build of the > {{PartitionUpdate}} (stacktrace from debugging the build() call): > {noformat} > at > org.apache.cassandra.db.partitions.PartitionUpdate.build(PartitionUpdate.java:571) > [main/:na] > at > org.apache.cassandra.db.partitions.PartitionUpdate.maybeBuild(PartitionUpdate.java:561) > [main/:na] > at > org.apache.cassandra.db.partitions.PartitionUpdate.iterator(PartitionUpdate.java:418) > [main/:na] > at > org.apache.cassandra.index.internal.CassandraIndex.validateRows(CassandraIndex.java:560) > [main/:na] > at > org.apache.cassandra.index.internal.CassandraIndex.validate(CassandraIndex.java:314) > [main/:na] > at > org.apache.cassandra.index.SecondaryIndexManager.lambda$validate$75(SecondaryIndexManager.java:642) > [main/:na] > at > org.apache.cassandra.index.SecondaryIndexManager$$Lambda$166/1388080038.accept(Unknown > Source) [main/:na] > at > java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) > [na:1.8.0_45] > at > java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) > [na:1.8.0_45] > at > java.util.concurrent.ConcurrentHashMap$ValueSpliterator.forEachRemaining(ConcurrentHashMap.java:3566) > [na:1.8.0_45] > at > java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) > [na:1.8.0_45] > at > java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) > [na:1.8.0_45] > at > java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) > [na:1.8.0_45] > at > java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) > [na:1.8.0_45] > at > java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) > [na:1.8.0_45] > at > java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) > [na:1.8.0_45] > at > org.apache.cassandra.index.SecondaryIndexManager.validate(SecondaryIndexManager.java:642) > [main/:na] > at > org.apache.cassandra.cql3.UpdateParameters.validateIndexedColumns(UpdateParameters.java:105) > [main/:na] > at > org.apache.cassandra.cql3.statements.UpdateStatement.addUpdateForKey(UpdateStatement.java:107) > [main/:na] > at > org.apache.cassandra.cql3.statements.ModificationStatement.addUpdates(ModificationStatement.java:667) > [main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.getMutations(BatchStatement.java:234) > [main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:335) > [main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:321) > [main/:na] > at > org.apache.cassandra.cql3.statements.BatchStatement.execute(BatchStatement.java:316) > [main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:205) > [main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:471) > [main/:na] > at > org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:448) > [main/:na] > at > org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:130) > [main/:na] > at > org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:507) > [main/:na] > at > org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:401) > [main/:na] > at > io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext.access$700(AbstractChannelHandlerContext.java:32) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > io.netty.channel.AbstractChannelHandlerContext$8.run(AbstractChannelHandlerContext.java:324) > [netty-all-4.0.23.Final.jar:4.0.23.Final] > at > java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) > [na:1.8.0_45] > at > org.apache.cassandra.concurrent.AbstractTracingAwareExecutorService$FutureTask.run(AbstractTracingAwareExecutorService.java:164) > [main/:na] > at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:105) > [main/:na] > at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] > {noformat} > You can reproduce the issue with a table and index like this: > {noformat} > CREATE TABLE foo (a int, b int, c int, d int, PRIMARY KEY (a, b)); > CREATE INDEX ON foo(c); > {noformat} > and a batch update like this: > {noformat} > BEGIN BATCH > UPDATE foo SET c = 0 WHERE a = 0 AND b = 0; > UPDATE foo SET d = 0 WHERE a = 0 AND b = 0; > APPLY BATCH > {noformat} > Assigning [~slebresne] for now, since he probably has the best idea of how to > avoid this. -- This message was sent by Atlassian JIRA (v6.3.4#6332)