private boolean flushRegion(HRegion region, boolean emergencyFlush, List<byte[]> families,
    FlushLifeCycleTracker tracker) {
    synchronized (this.regionsInQueue) {
      FlushRegionEntry fqe = this.regionsInQueue.remove(region);
      // Use the start time of the FlushRegionEntry if available
      if (fqe != null && emergencyFlush) {
        // Need to remove from region from delay queue. When NOT an
        // emergencyFlush, then item was removed via a flushQueue.poll.
        flushQueue.remove(fqe);
      }
    }

    tracker.beforeExecution();
    lock.readLock().lock();
    final CompactSplit compactSplitThread = server.getCompactSplitThread();
    try {
      notifyFlushRequest(region, emergencyFlush);
      FlushResult flushResult = region.flushcache(families, false, tracker);
      boolean shouldCompact = flushResult.isCompactionNeeded();
      // We just want to check the size
      boolean shouldSplit = region.checkSplit().isPresent();
      if (shouldSplit) {
        compactSplitThread.requestSplit(region);
      } else if (shouldCompact) {
        compactSplitThread.requestSystemCompaction(region, Thread.currentThread().getName());
      }
    } catch (DroppedSnapshotException ex) {
      // Cache flush can fail in a few places. If it fails in a critical
      // section, we get a DroppedSnapshotException and a replay of wal
      // is required. Currently the only way to do this is a restart of
      // the server. Abort because hdfs is probably bad (HBASE-644 is a case
      // where hdfs was bad but passed the hdfs check).
      server.abort("Replay of WAL required. Forcing server shutdown", ex);
      return false;
    } catch (IOException ex) {
      ex = ex instanceof RemoteException ? ((RemoteException) ex).unwrapRemoteException() : ex;
      LOG.error("Cache flush failed" + (region != null
        ? (" for region " + Bytes.toStringBinary(region.getRegionInfo().getRegionName()))
        : ""), ex);
      if (!server.checkFileSystem()) {
        return false;
      }
    } finally {
      lock.readLock().unlock();
      wakeUpIfBlocking();
      tracker.afterExecution();
    }
    return true;
  }
Flush a region.
@param region         Region to flush.
@param emergencyFlush Set if we are being force flushed. If true the region needs to be removed
                      from the flush queue. If false, when we were called from the main flusher
                      run loop and we got the entry to flush by calling poll on the flush queue
                      (which removed it).
@param families       stores of region to flush.
@return true if the region was successfully flushed, false otherwise. If false, there will be
        accompanying log messages explaining why the region was not flushed.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java