[ https://issues.apache.org/jira/browse/CASSANDRA-13747?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Aleksey Yeschenko updated CASSANDRA-13747: ------------------------------------------ Summary: Fix AssertionError in short read protection (was: Fix short read protection) > Fix AssertionError in short read protection > ------------------------------------------- > > Key: CASSANDRA-13747 > URL: https://issues.apache.org/jira/browse/CASSANDRA-13747 > Project: Cassandra > Issue Type: Bug > Components: Coordination > Reporter: Aleksey Yeschenko > Assignee: Aleksey Yeschenko > Fix For: 3.0.x, 3.11.x > > > {{ShortReadRowProtection.moreContents()}} expects that by the time we get to > that method, the global post-reconciliation counter was already applied to > the current partition. However, sometimes it won’t get applied, and the > global counter continues counting with {{rowInCurrentPartition}} value not > reset from previous partition, which in the most obvious case would trigger > the assertion we are observing - {{assert > !postReconciliationCounter.isDoneForPartition();}}. In other cases it’s > possible because of this lack of reset to query a node for too few extra > rows, causing unnecessary SRP data requests. > Why is the counter not always applied to the current partition? > The merged {{PartitionIterator}} returned from {{DataResolver.resolve()}} has > two transformations applied to it, in the following order: > {{Filter}} - to purge non-live data from partitions, and to discard empty > partitions altogether (except for Thrift) > {{Counter}}, to count and stop iteration > Problem is, {{Filter}} ’s {{applyToPartition()}} code that discards empty > partitions ({{closeIfEmpty()}} method) would sometimes consume the iterator, > triggering short read protection *before* {{Counter}} ’s > {{applyToPartition()}} gets called and resets its {{rowInCurrentPartition}} > sub-counter. > We should not be consuming iterators until all transformations are applied to > them. For transformations it means that they cannot consume iterators unless > they are the last transformation on the stack. > The linked branch fixes the problem by splitting {{Filter}} into two > transformations. The original - {{Filter}} - that does filtering within > partitions - and a separate {{EmptyPartitionsDiscarder}}, that discards empty > partitions from {{PartitionIterators}}. Thus {{DataResolve.resolve()}}, when > constructing its {{PartitionIterator}}, now does merge first, then applies > {{Filter}}, then {{Counter}}, and only then, as its last (third) > transformation - the {{EmptyPartitionsDiscarder}}. Being the last one > applied, it’s legal for it to consume the iterator, and triggering > {{moreContents()}} is now no longer a problem. > Fixes: [3.0|https://github.com/iamaleksey/cassandra/commits/13747-3.0], > [3.11|https://github.com/iamaleksey/cassandra/commits/13747-3.11], > [4.0|https://github.com/iamaleksey/cassandra/commits/13747-4.0]. dtest > [here|https://github.com/iamaleksey/cassandra-dtest/commits/13747]. -- This message was sent by Atlassian JIRA (v6.4.14#64029) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org