From 4079f48aa68347716c4ece9e2d6191ddcfce3609 Mon Sep 17 00:00:00 2001 From: Zach York Date: Wed, 28 Feb 2018 10:40:38 -0800 Subject: [PATCH] [HBASE-20141] Fix TooManyFiles exception when RefreshingChannels HBASE-19435 implements a fix for reopening file channels when they are unnexpected closed to avoid disabling the BucketCache. However, it was missed that the the channels might not actually be completely closed (the write or read channel might still be open (see https://docs.oracle.com/javase/7/docs/api/java/nio/channels/ClosedChannelException.html) This commit closes any open channels before creating a new channel. --- .../hadoop/hbase/io/hfile/bucket/FileIOEngine.java | 16 +++++++++++++++- .../hadoop/hbase/io/hfile/bucket/TestFileIOEngine.java | 12 ++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/FileIOEngine.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/FileIOEngine.java index cf963f0..176b14c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/FileIOEngine.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/FileIOEngine.java @@ -274,7 +274,21 @@ public class FileIOEngine implements IOEngine { return fileNum; } - private void refreshFileConnection(int accessFileNum) throws FileNotFoundException { + @VisibleForTesting + FileChannel[] getFileChannels() { + return fileChannels; + } + + @VisibleForTesting + void refreshFileConnection(int accessFileNum) throws FileNotFoundException { + FileChannel fileChannel = fileChannels[accessFileNum]; + if (fileChannel != null) { + try { + fileChannel.close(); + } catch (IOException ioe) { + LOG.warn("Failed to close fileChannel before refreshing: ", ioe); + } + } rafs[accessFileNum] = new RandomAccessFile(filePaths[accessFileNum], "rw"); fileChannels[accessFileNum] = rafs[accessFileNum].getChannel(); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestFileIOEngine.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestFileIOEngine.java index 5086265..e590393 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestFileIOEngine.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestFileIOEngine.java @@ -18,10 +18,14 @@ package org.apache.hadoop.hbase.io.hfile.bucket; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.hbase.HBaseClassTestRule; @@ -138,4 +142,12 @@ public class TestFileIOEngine { ByteBuff data2 = deserializer.getDeserializedByteBuff(); assertArrayEquals(data1, data2.array()); } + + @Test + public void testRefreshFileConnectionClosesConnections() throws IOException { + FileChannel fileChannel = fileIOEngine.getFileChannels()[0]; + assertNotNull(fileChannel); + fileIOEngine.refreshFileConnection(0); + assertFalse(fileChannel.isOpen()); + } } -- 2.6.4