Skip to content

Commit 84c056b

Browse files
committed
HBASE-29627 Handle any block cache fetching errors when reading a block in HFileReaderImpl (#7341) (#7344)
Signed-off-by: Peter Somogyi <psomogyi@apache.org>
1 parent df1bfc0 commit 84c056b

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,32 @@ public HFileBlock getCachedBlock(BlockCacheKey cacheKey, boolean cacheBlock, boo
11801180
}
11811181
return cachedBlock;
11821182
}
1183+
} catch (Exception e) {
1184+
if (cachedBlock != null) {
1185+
returnAndEvictBlock(cache, cacheKey, cachedBlock);
1186+
}
1187+
LOG.warn("Failed retrieving block from cache with key {}. "
1188+
+ "\n Evicting this block from cache and will read it from file system. "
1189+
+ "\n Exception details: ", cacheKey, e);
1190+
if (LOG.isDebugEnabled()) {
1191+
LOG.debug("Further tracing details for failed block cache retrieval:"
1192+
+ "\n Complete File path - {}," + "\n Expected Block Type - {}, Actual Block Type - {},"
1193+
+ "\n Cache compressed - {}" + "\n Header size (after deserialized from cache) - {}"
1194+
+ "\n Size with header - {}" + "\n Uncompressed size without header - {} "
1195+
+ "\n Total byte buffer size - {}" + "\n Encoding code - {}", this.path,
1196+
expectedBlockType, (cachedBlock != null ? cachedBlock.getBlockType() : "N/A"),
1197+
(expectedBlockType != null
1198+
? cacheConf.shouldCacheCompressed(expectedBlockType.getCategory())
1199+
: "N/A"),
1200+
(cachedBlock != null ? cachedBlock.headerSize() : "N/A"),
1201+
(cachedBlock != null ? cachedBlock.getOnDiskSizeWithHeader() : "N/A"),
1202+
(cachedBlock != null ? cachedBlock.getUncompressedSizeWithoutHeader() : "N/A"),
1203+
(cachedBlock != null ? cachedBlock.getBufferReadOnly().limit() : "N/A"),
1204+
(cachedBlock != null
1205+
? cachedBlock.getBufferReadOnly().getShort(cachedBlock.headerSize())
1206+
: "N/A"));
1207+
}
1208+
return null;
11831209
} finally {
11841210
// Count bytes read as cached block is being returned
11851211
if (isScanMetricsEnabled && cachedBlock != null) {

hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestHFileReaderImpl.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@
1818
package org.apache.hadoop.hbase.io.hfile;
1919

2020
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertNotNull;
2122
import static org.junit.Assert.assertTrue;
23+
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.ArgumentMatchers.anyBoolean;
25+
import static org.mockito.Mockito.mock;
26+
import static org.mockito.Mockito.when;
2227

2328
import java.io.IOException;
2429
import java.util.concurrent.atomic.AtomicInteger;
@@ -116,6 +121,23 @@ public void testRecordBlockSize() throws IOException {
116121
}
117122
}
118123

124+
@Test
125+
public void testReadWorksWhenCacheCorrupt() throws Exception {
126+
BlockCache mockedCache = mock(BlockCache.class);
127+
when(mockedCache.getBlock(any(), anyBoolean(), anyBoolean(), anyBoolean()))
128+
.thenThrow(new RuntimeException("Injected error"));
129+
Path p = makeNewFile();
130+
FileSystem fs = TEST_UTIL.getTestFileSystem();
131+
Configuration conf = TEST_UTIL.getConfiguration();
132+
HFile.Reader reader = HFile.createReader(fs, p, new CacheConfig(conf, mockedCache), true, conf);
133+
long offset = 0;
134+
while (offset < reader.getTrailer().getLoadOnOpenDataOffset()) {
135+
HFileBlock block = reader.readBlock(offset, -1, false, true, false, true, null, null, false);
136+
assertNotNull(block);
137+
offset += block.getOnDiskSizeWithHeader();
138+
}
139+
}
140+
119141
@Test
120142
public void testSeekBefore() throws Exception {
121143
Path p = makeNewFile();

0 commit comments

Comments
 (0)