[
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]