[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.
This commit is contained in:
Zach York 2018-02-28 10:40:38 -08:00
parent 79d47dd57a
commit 6bf967adfb
2 changed files with 22 additions and 2 deletions

View File

@ -19,7 +19,6 @@
package org.apache.hadoop.hbase.io.hfile.bucket;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
@ -274,7 +273,17 @@ 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 IOException {
FileChannel fileChannel = fileChannels[accessFileNum];
if (fileChannel != null) {
fileChannel.close();
}
rafs[accessFileNum] = new RandomAccessFile(filePaths[accessFileNum], "rw");
fileChannels[accessFileNum] = rafs[accessFileNum].getChannel();
}

View File

@ -18,10 +18,13 @@
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.FileChannel;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hbase.HBaseClassTestRule;
@ -138,4 +141,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());
}
}