[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:
parent
79d47dd57a
commit
6bf967adfb
|
@ -19,7 +19,6 @@
|
||||||
package org.apache.hadoop.hbase.io.hfile.bucket;
|
package org.apache.hadoop.hbase.io.hfile.bucket;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -274,7 +273,17 @@ public class FileIOEngine implements IOEngine {
|
||||||
return fileNum;
|
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");
|
rafs[accessFileNum] = new RandomAccessFile(filePaths[accessFileNum], "rw");
|
||||||
fileChannels[accessFileNum] = rafs[accessFileNum].getChannel();
|
fileChannels[accessFileNum] = rafs[accessFileNum].getChannel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
package org.apache.hadoop.hbase.io.hfile.bucket;
|
package org.apache.hadoop.hbase.io.hfile.bucket;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||||
|
@ -138,4 +141,12 @@ public class TestFileIOEngine {
|
||||||
ByteBuff data2 = deserializer.getDeserializedByteBuff();
|
ByteBuff data2 = deserializer.getDeserializedByteBuff();
|
||||||
assertArrayEquals(data1, data2.array());
|
assertArrayEquals(data1, data2.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRefreshFileConnectionClosesConnections() throws IOException {
|
||||||
|
FileChannel fileChannel = fileIOEngine.getFileChannels()[0];
|
||||||
|
assertNotNull(fileChannel);
|
||||||
|
fileIOEngine.refreshFileConnection(0);
|
||||||
|
assertFalse(fileChannel.isOpen());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue