Uploaded image for project: 'HBase'
  1. HBase
  2. HBASE-18158

Two running in-memory compaction threads may lose data

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 3.0.0-alpha-1, 2.0.0
    • 2.0.0
    • None
    • None
    • Reviewed

    Description

      CompactingMemStore.java
        private void stopCompaction() {
          if (inMemoryFlushInProgress.get()) {
            compactor.stop();
            inMemoryFlushInProgress.set(false);
          }
        }
      

      The stopCompaction() set inMemoryFlushInProgress to false so there may be two in-memory compaction threads which execute simultaneously. If there are two running InMemoryFlushRunnable, the later InMemoryFlushRunnable may change the versionedList.

      MemStoreCompactor.java
        public boolean start() throws IOException {
          if (!compactingMemStore.hasImmutableSegments()) { // no compaction on empty pipeline
            return false;
          }
      
          // get a snapshot of the list of the segments from the pipeline,
          // this local copy of the list is marked with specific version
          versionedList = compactingMemStore.getImmutableSegments();
      

      And the first InMemoryFlushRunnable will use the chagned versionedList to remove the corresponding segments.

      MemStoreCompactor#doCompaction
            if (!isInterrupted.get()) {
              if (resultSwapped = compactingMemStore.swapCompactedSegments(
                  versionedList, result, (action==Action.MERGE))) {
                // update the wal so it can be truncated and not get too long
                compactingMemStore.updateLowestUnflushedSequenceIdInWAL(true); // only if greater
              }
            }
      

      In conclusion, first InMemoryFlushRunnable will remove the worng segment. And the later InMemoryFlushRunnable may introduce NPE because first InMemoryFlushRunnable set versionedList to null after compaction.

      Exception in thread "RpcServer.default.FPBQ.Fifo.handler=3,queue=0,port=45712-inmemoryCompactions-1496563908038" java.lang.NullPointerException
              at org.apache.hadoop.hbase.regionserver.CompactionPipeline.swap(CompactionPipeline.java:119)
              at org.apache.hadoop.hbase.regionserver.CompactingMemStore.swapCompactedSegments(CompactingMemStore.java:283)
              at org.apache.hadoop.hbase.regionserver.MemStoreCompactor.doCompaction(MemStoreCompactor.java:212)
              at org.apache.hadoop.hbase.regionserver.MemStoreCompactor.start(MemStoreCompactor.java:122)
              at org.apache.hadoop.hbase.regionserver.CompactingMemStore.flushInMemory(CompactingMemStore.java:388)
              at org.apache.hadoop.hbase.regionserver.CompactingMemStore$InMemoryFlushRunnable.run(CompactingMemStore.java:500)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      

      Attachments

        1. HBASE-18158.v0.patch
          9 kB
          Chia-Ping Tsai
        2. HBASE-18158.v1.patch
          9 kB
          Chia-Ping Tsai
        3. HBASE-18158.v2.patch
          9 kB
          Chia-Ping Tsai
        4. HBASE-18158.v2.patch
          9 kB
          Chia-Ping Tsai
        5. HBASE-18158.v3.patch
          9 kB
          Chia-Ping Tsai
        6. HBASE-18158.v4.patch
          9 kB
          Chia-Ping Tsai

        Issue Links

          Activity

            People

              chia7712 Chia-Ping Tsai
              chia7712 Chia-Ping Tsai
              Votes:
              0 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: