You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-issues@hadoop.apache.org by "Colin Patrick McCabe (JIRA)" <ji...@apache.org> on 2013/02/15 07:45:13 UTC

[jira] [Commented] (HDFS-4504) DFSOutputStream#close doesn't always release resources (such as leases)

    [ https://issues.apache.org/jira/browse/HDFS-4504?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13578996#comment-13578996 ] 

Colin Patrick McCabe commented on HDFS-4504:
--------------------------------------------

Here is the code for {{DFSOutputStream#close}}:

{code}
  /**
   * Closes this output stream and releases any system 
   * resources associated with this stream.
   */
  @Override
  public synchronized void close() throws IOException {
    if (closed) {
      IOException e = lastException;
      if (e == null)
        return;
      else
        throw e;
    }

    try {
      flushBuffer();       // flush from all upper layers

      if (currentPacket != null) { 
        waitAndQueueCurrentPacket();
      }

      if (bytesCurBlock != 0) {
        // send an empty packet to mark the end of the block
        currentPacket = new Packet(0, 0, bytesCurBlock, 
            currentSeqno++, this.checksum.getChecksumSize());
        currentPacket.lastPacketInBlock = true;
        currentPacket.syncBlock = shouldSyncBlock;
      }

      flushInternal();             // flush all data to Datanodes
      // get last block before destroying the streamer
      ExtendedBlock lastBlock = streamer.getBlock();
      closeThreads(false);
      completeFile(lastBlock);
      dfsClient.endFileLease(src);
    } finally {
      closed = true;
    }
  }
{code}

As you can see, if {{DFSOutputStream#flushBuffer}} throws an {{IOException}}, {{DFSOutputStream#closed}} will be set to true, but we'll never call {{dfsClient.endFileLease}}.  Future attempts to close the {{DFSOutputStream}} will just hit the if statement which rethrows {{lastException}}.

The file can never be closed until we take down the whole client-- which is a problem for long-lived clients like HBase, Flume, etc.
                
> DFSOutputStream#close doesn't always release resources (such as leases)
> -----------------------------------------------------------------------
>
>                 Key: HDFS-4504
>                 URL: https://issues.apache.org/jira/browse/HDFS-4504
>             Project: Hadoop HDFS
>          Issue Type: Bug
>            Reporter: Colin Patrick McCabe
>
> {{DFSOutputStream#close}} can throw an {{IOException}} in some cases.  One example is if there is a pipeline error and then pipeline recovery fails.  Unfortunately, in this case, some of the resources used by the {{DFSOutputStream}} are leaked.  One particularly important resource is file leases.
> So it's possible for a long-lived HDFS client, such as Flume, to write many blocks to a file, but then fail to close it.  Unfortunately, the {{LeaseRenewerThread}} inside the client will continue to renew the lease for the "undead" file.  Future attempts to close the file will just rethrow the previous exception, and no progress can be made by the client.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira