[
https://issues.apache.org/jira/browse/HBASE-26384?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
chenglei updated HBASE-26384:
-----------------------------
Description:
When {{CompactingMemStore}} prepares flushing, {{CompactingMemStore.snapshot}}
uses {{CompactionPipeline#version}} to track whether the
{{CompactionPipeline#pipeline}} has
changed since it acquired {{VersionedSegmentsList}} last time before emptying
{{CompactionPipeline#pipeline}}. However, when
{{CompactingMemStore#inMemoryCompaction}} executes
{{CompactionPipeline#flattenOneSegment}}, it does not change the
{{CompactionPipeline#version}} , which could causes the segment which has be
already collected to {{MemStoreSnapshot}} may still be remained in
CompactingMemStore.
Considing following thread sequence:
# When {{CompactingMemStore}} size exceeds
{{CompactingMemStore#getInmemoryFlushSize}},
the write thread adds a new {@link ImmutableSegment} to the head of
{{CompactingMemStore#pipeline}}
and start {@link CompactingMemStore.InMemoryCompactionRunnable}
asynchronously
in {@link CompactingMemStore#tryFlushInMemoryAndCompactingAsync}.
# The in memory compact thread starts and then stopping before
{{CompactingMemStore#flattenOneSegment}}
# The snapshot thread starts {{CompactingMemStore#getSnapshot}} concurrently,
after the snapshot thread
executing fllowing line 570 {{pipeline.getVersionedList}}, the in memory
compact thread continues.
{code:java}
565 private void pushPipelineToSnapshot() {
566 int iterationsCnt = 0;
567 boolean done = false;
568 while (!done) {
569 iterationsCnt++;
570 VersionedSegmentsList segments = pipeline.getVersionedList();
571 pushToSnapshot(segments.getStoreSegments());
572 // swap can return false in case the pipeline was updated by
ongoing compaction
573 // and the version increase, the chance of it happenning is
very low
574 // In Swap: don't close segments (they are in snapshot now) and
don't update the region size
575 done = pipeline.swap(segments, null, false, false);
.......
}
{code}
Assuming {{VersionedSegmentsList#version}} returned from
{{CompactingMemStore#getPipelineVersionedSegmentsList}}
* is v.
* 4. The snapshot thread stopping before {@link
CompactingMemStore#swapPipelineWithNull}
* 5. The in memory compact thread completes {@link
CompactingMemStore#flattenOneSegment},
* {@link CompactingMemStore#flattenOneSegment} does not change {@link
CompactionPipeline#version},
* {@link CompactionPipeline#version} is still v.
* 5. The snapshot thread continues {@link
CompactingMemStore#swapPipelineWithNull}, and because {@link
CompactionPipeline#version}
* is still v, {@link CompactingMemStore#swapPipelineWithNull} succeeds,
but the {@link ImmutableSegment}
* in {@link CompactionPipeline} has changed because {@link
CompactingMemStore#flattenOneSegment}, so
* the {@link ImmutableSegment} in {@link CompactionPipeline} is not
removed and is still remained in
* {@link CompactionPipeline}.
was:
When {{CompactingMemStore}} prepares flushing, {{CompactingMemStore.snapshot}}
uses {{CompactionPipeline#version}} to track whether the
{{CompactionPipeline#pipeline}} has
changed since it acquired {{VersionedSegmentsList}} last time before emptying
{{CompactionPipeline#pipeline}}. However, when
{{CompactingMemStore#inMemoryCompaction}} executes
{{CompactionPipeline#flattenOneSegment}}, it does not change the
{{CompactionPipeline#version}} , which could cause the
> Segment which already flushed to hfile may still be remained in
> CompactingMemStore
> ------------------------------------------------------------------------------------
>
> Key: HBASE-26384
> URL: https://issues.apache.org/jira/browse/HBASE-26384
> Project: HBase
> Issue Type: Bug
> Components: in-memory-compaction
> Affects Versions: 3.0.0-alpha-1, 2.4.7
> Reporter: chenglei
> Priority: Major
>
> When {{CompactingMemStore}} prepares flushing,
> {{CompactingMemStore.snapshot}} uses {{CompactionPipeline#version}} to track
> whether the {{CompactionPipeline#pipeline}} has
> changed since it acquired {{VersionedSegmentsList}} last time before
> emptying {{CompactionPipeline#pipeline}}. However, when
> {{CompactingMemStore#inMemoryCompaction}} executes
> {{CompactionPipeline#flattenOneSegment}}, it does not change the
> {{CompactionPipeline#version}} , which could causes the segment which has be
> already collected to {{MemStoreSnapshot}} may still be remained in
> CompactingMemStore.
> Considing following thread sequence:
> # When {{CompactingMemStore}} size exceeds
> {{CompactingMemStore#getInmemoryFlushSize}},
> the write thread adds a new {@link ImmutableSegment} to the head of
> {{CompactingMemStore#pipeline}}
> and start {@link CompactingMemStore.InMemoryCompactionRunnable}
> asynchronously
> in {@link CompactingMemStore#tryFlushInMemoryAndCompactingAsync}.
> # The in memory compact thread starts and then stopping before
> {{CompactingMemStore#flattenOneSegment}}
> # The snapshot thread starts {{CompactingMemStore#getSnapshot}} concurrently,
> after the snapshot thread
> executing fllowing line 570 {{pipeline.getVersionedList}}, the in memory
> compact thread continues.
> {code:java}
> 565 private void pushPipelineToSnapshot() {
> 566 int iterationsCnt = 0;
> 567 boolean done = false;
> 568 while (!done) {
> 569 iterationsCnt++;
> 570 VersionedSegmentsList segments =
> pipeline.getVersionedList();
> 571 pushToSnapshot(segments.getStoreSegments());
> 572 // swap can return false in case the pipeline was updated by
> ongoing compaction
> 573 // and the version increase, the chance of it happenning is
> very low
> 574 // In Swap: don't close segments (they are in snapshot now)
> and don't update the region size
> 575 done = pipeline.swap(segments, null, false, false);
> .......
> }
> {code}
> Assuming {{VersionedSegmentsList#version}} returned from
> {{CompactingMemStore#getPipelineVersionedSegmentsList}}
> * is v.
> * 4. The snapshot thread stopping before {@link
> CompactingMemStore#swapPipelineWithNull}
> * 5. The in memory compact thread completes {@link
> CompactingMemStore#flattenOneSegment},
> * {@link CompactingMemStore#flattenOneSegment} does not change {@link
> CompactionPipeline#version},
> * {@link CompactionPipeline#version} is still v.
> * 5. The snapshot thread continues {@link
> CompactingMemStore#swapPipelineWithNull}, and because {@link
> CompactionPipeline#version}
> * is still v, {@link CompactingMemStore#swapPipelineWithNull} succeeds,
> but the {@link ImmutableSegment}
> * in {@link CompactionPipeline} has changed because {@link
> CompactingMemStore#flattenOneSegment}, so
> * the {@link ImmutableSegment} in {@link CompactionPipeline} is not
> removed and is still remained in
> * {@link CompactionPipeline}.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)