[ 
https://issues.apache.org/jira/browse/CASSANDRA-21607?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18108413#comment-18108413
 ] 

Jon Haddad commented on CASSANDRA-21607:
----------------------------------------

Looking closer at this, it also affects the read path. No compaction is needed. 
The read path serializes a {{{}ReadResponse{}}}, which runs the same row merge 
that compaction runs.

Minimal reproducer. Run it from the source root against a single node. It uses 
a fresh keyspace on each run, so it can be run repeatedly:
{code:java}
KS=npe_$(date +%s)

bin/cqlsh -e "
CREATE KEYSPACE $KS WITH replication = 
{'class':'SimpleStrategy','replication_factor':1};
CREATE TABLE $KS.t (pk int PRIMARY KEY, m map<int,int>);
UPDATE $KS.t USING TIMESTAMP 4102444800000000 SET m = m + {1:1} WHERE pk = 0;"

bin/nodetool flush $KS t

bin/cqlsh -e "
UPDATE $KS.t USING TIMESTAMP 4102444800000001 SET m = m + {1:2} WHERE pk = 0;
ALTER TABLE $KS.t DROP m;
SELECT * FROM $KS.t;"
{code}
The client sees:
{code:java}
ReadFailure: Error from server: code=1300 [Replica(s) failed to execute read
{code}
The node logs:
{code:java}
java.lang.NullPointerException: Cannot invoke
  "ComplexColumnData$Builder.newColumn(ColumnMetadata)" because "this.comple
      at 
org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.getReduced(Row.java:853)
      at org.apache.cassandra.db.rows.Row$Merger.merge(Row.java:770)
      at 
...UnfilteredRowIterators$UnfilteredRowMergeIterator$MergeReducer.grators.java:579)
      at org.apache.cassandra.db.ReadResponse$LocalDataResponse.build(ReadRe
{code}
 

> NullPointerException in reads and compaction when a dropped non-frozen 
> collection still holds cells newer than the drop
> -----------------------------------------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-21607
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21607
>             Project: Apache Cassandra
>          Issue Type: Bug
>          Components: Local/Compaction
>            Reporter: Jon Haddad
>            Priority: Normal
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> Found while adding test coverage to cursor compaction for collections in 
> CASSANDRA-21463.
> Drop a non-frozen collection column.  If any sstable written before the drop 
> holds a cell of that column with a timestamp above the drop time, compaction 
> of that table throws a NullPointerException and does not complete.  Every 
> later attempt hits the same rows, so the table cannot compact again.  
> A far-future timestamp makes this easy to demonstrate, but it is not 
> required.  Clock skew, or a client that supplies its own timestamps, reaches 
> the same state. 
> {noformat}
> CREATE KEYSPACE npe WITH replication = 
> {'class':'SimpleStrategy','replication_factor':1};
> CREATE TABLE npe.t (pk bigint, ck bigint, v1 bigint, m map<text,bigint>, 
> PRIMARY KEY (pk, ck));
> {noformat}
> {noformat}
> nodetool disableautocompaction npe t
> {noformat}
> {noformat}
> UPDATE npe.t USING TIMESTAMP 4102444800000000 SET m = m + {'a':1} WHERE pk=0 
> AND ck=0;
> {noformat}
> {noformat}
> nodetool flush npe t
> {noformat}
> {noformat}
> UPDATE npe.t USING TIMESTAMP 4102444800000001 SET m = m + {'a':2} WHERE pk=0 
> AND ck=0;
> {noformat}
> {noformat}
> nodetool flush npe t
> {noformat}
> {noformat}
> ALTER TABLE npe.t DROP m;
> {noformat}
> {noformat}
> nodetool compact npe t
> error: null
> -- StackTrace --
> java.lang.NullPointerException
>       at 
> org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.getReduced(Row.java:919)
>       at 
> org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.getReduced(Row.java:854)
>       at 
> org.apache.cassandra.utils.RowMergeIterator$ManyToOne.consume(RowMergeIterator.java:254)
>       at 
> org.apache.cassandra.utils.RowMergeIterator$ManyToOne.computeNext(RowMergeIterator.java:193)
>       at 
> org.apache.cassandra.utils.AbstractIterator.hasNext(AbstractIterator.java:47)
>       at org.apache.cassandra.db.rows.Row$Merger.merge(Row.java:812)
>       at 
> org.apache.cassandra.db.rows.UnfilteredRowIterators$UnfilteredRowMergeIterator$MergeReducer.getReduced(UnfilteredRowIterators.java:590)
>       at 
> org.apache.cassandra.db.rows.UnfilteredRowIterators$UnfilteredRowMergeIterator$MergeReducer.getReduced(UnfilteredRowIterators.java:543)
>       at 
> org.apache.cassandra.utils.UnfilteredMergeIterator$ManyToOne.consume(UnfilteredMergeIterator.java:254)
>       at 
> org.apache.cassandra.utils.UnfilteredMergeIterator$ManyToOne.computeNext(UnfilteredMergeIterator.java:193)
>       at 
> org.apache.cassandra.utils.AbstractIterator.hasNext(AbstractIterator.java:47)
>       at 
> org.apache.cassandra.db.rows.UnfilteredRowIterators$UnfilteredRowMergeIterator.computeNext(UnfilteredRowIterators.java:525)
>       at 
> org.apache.cassandra.db.rows.UnfilteredRowIterators$UnfilteredRowMergeIterator.computeNext(UnfilteredRowIterators.java:398)
>       at 
> org.apache.cassandra.utils.AbstractIterator.hasNext(AbstractIterator.java:47)
>       at org.apache.cassandra.db.transform.BaseRows.hasNext(BaseRows.java:137)
>       at 
> org.apache.cassandra.db.transform.UnfilteredRows.isEmpty(UnfilteredRows.java:74)
>       at 
> org.apache.cassandra.db.partitions.PurgeFunction.applyToPartition(PurgeFunction.java:91)
>       at 
> org.apache.cassandra.db.partitions.PurgeFunction.applyToPartition(PurgeFunction.java:32)
>       at 
> org.apache.cassandra.db.transform.BasePartitions.hasNext(BasePartitions.java:94)
>       at 
> org.apache.cassandra.db.compaction.CompactionIterator.hasNext(CompactionIterator.java:431)
>       at 
> org.apache.cassandra.db.compaction.IteratorCompactionPipeline.processNextPartitionKey(IteratorCompactionPipeline.java:77)
>       at 
> org.apache.cassandra.db.compaction.CompactionTask.runMayThrow(CompactionTask.java:292)
>       at 
> org.apache.cassandra.utils.WrappedRunnable.run(WrappedRunnable.java:26)
>       at 
> org.apache.cassandra.db.compaction.CompactionTask.executeInternal(CompactionTask.java:121)
>       at 
> org.apache.cassandra.db.compaction.AbstractCompactionTask.execute(AbstractCompactionTask.java:110)
>       at 
> org.apache.cassandra.db.compaction.CompactionManager$9.runMayThrow(CompactionManager.java:1195)
>       at 
> org.apache.cassandra.utils.WrappedRunnable.run(WrappedRunnable.java:26)
>       at 
> org.apache.cassandra.concurrent.FutureTask$3.call(FutureTask.java:141)
>       at org.apache.cassandra.concurrent.FutureTask.call(FutureTask.java:61)
>       at org.apache.cassandra.concurrent.FutureTask.run(FutureTask.java:71)
>       at 
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
>       at 
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
>       at 
> io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
>       at java.base/java.lang.Thread.run(Thread.java:1583)
>       at 
> org.apache.cassandra.concurrent.CassandraThread.run(CassandraThread.java:97)
> {noformat}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to