Skip to content

Commit 13841f5

Browse files
ujjawal4046bbeaudreault
authored andcommitted
HBASE-25922 - Disabled sanity checks ignored on snapshot restore (#4533)
Co-authored-by: Ujjawal Kumar <u.kumar@ukumar-ltmit1s.internal.salesforce.com> Signed-off-by: Duo Zhang <zhangduo@apache.org> Signed-off-by: Bryan Beaudreault <bbeaudreault@apache.org> Conflicts: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
1 parent 51bedf6 commit 13841f5

File tree

4 files changed

+152
-110
lines changed

4 files changed

+152
-110
lines changed

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7212,13 +7212,17 @@ public static Region openHRegion(final Region other, final CancelableProgressabl
72127212
*/
72137213
private HRegion openHRegion(final CancelableProgressable reporter) throws IOException {
72147214
try {
7215+
CompoundConfiguration cConfig =
7216+
new CompoundConfiguration().add(conf).addBytesMap(htableDescriptor.getValues());
72157217
// Refuse to open the region if we are missing local compression support
7216-
TableDescriptorChecker.checkCompression(htableDescriptor);
7218+
TableDescriptorChecker.checkCompression(cConfig, htableDescriptor);
72177219
// Refuse to open the region if encryption configuration is incorrect or
72187220
// codec support is missing
7219-
TableDescriptorChecker.checkEncryption(conf, htableDescriptor);
7221+
LOG.debug("checking encryption for " + this.getRegionInfo().getEncodedName());
7222+
TableDescriptorChecker.checkEncryption(cConfig, htableDescriptor);
72207223
// Refuse to open the region if a required class cannot be loaded
7221-
TableDescriptorChecker.checkClassLoading(conf, htableDescriptor);
7224+
LOG.debug("checking classloading for " + this.getRegionInfo().getEncodedName());
7225+
TableDescriptorChecker.checkClassLoading(cConfig, htableDescriptor);
72227226
this.openSeqNum = initialize(reporter);
72237227
this.mvcc.advanceTo(openSeqNum);
72247228
// The openSeqNum must be increased every time when a region is assigned, as we rely on it to

hbase-server/src/main/java/org/apache/hadoop/hbase/util/TableDescriptorChecker.java

Lines changed: 130 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ public final class TableDescriptorChecker {
6060
private TableDescriptorChecker() {
6161
}
6262

63+
private static boolean shouldSanityCheck(final Configuration conf) {
64+
if (conf.getBoolean(TABLE_SANITY_CHECKS, DEFAULT_TABLE_SANITY_CHECKS)) {
65+
return true;
66+
}
67+
return false;
68+
}
69+
6370
/**
6471
* Checks whether the table conforms to some sane limits, and configured values (compression, etc)
6572
* work. Throws an exception if something is wrong.
@@ -68,15 +75,8 @@ public static void sanityCheck(final Configuration c, final TableDescriptor td)
6875
throws IOException {
6976
CompoundConfiguration conf = new CompoundConfiguration().add(c).addBytesMap(td.getValues());
7077

71-
// Setting this to true logs the warning instead of throwing exception
72-
boolean logWarn = false;
73-
if (!conf.getBoolean(TABLE_SANITY_CHECKS, DEFAULT_TABLE_SANITY_CHECKS)) {
74-
logWarn = true;
75-
}
76-
String tableVal = td.getValue(TABLE_SANITY_CHECKS);
77-
if (tableVal != null && !Boolean.valueOf(tableVal)) {
78-
logWarn = true;
79-
}
78+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
79+
boolean logWarn = !shouldSanityCheck(conf);
8080

8181
// check max file size
8282
long maxFileSizeLowerLimit = 2 * 1024 * 1024L; // 2M is the default lower limit
@@ -107,36 +107,20 @@ public static void sanityCheck(final Configuration c, final TableDescriptor td)
107107
}
108108

109109
// check that coprocessors and other specified plugin classes can be loaded
110-
try {
111-
checkClassLoading(conf, td);
112-
} catch (Exception ex) {
113-
warnOrThrowExceptionForFailure(logWarn, ex.getMessage(), null);
114-
}
110+
checkClassLoading(conf, td);
115111

116112
if (conf.getBoolean(MASTER_CHECK_COMPRESSION, DEFAULT_MASTER_CHECK_COMPRESSION)) {
117113
// check compression can be loaded
118-
try {
119-
checkCompression(td);
120-
} catch (IOException e) {
121-
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
122-
}
114+
checkCompression(conf, td);
123115
}
124116

125117
if (conf.getBoolean(MASTER_CHECK_ENCRYPTION, DEFAULT_MASTER_CHECK_ENCRYPTION)) {
126118
// check encryption can be loaded
127-
try {
128-
checkEncryption(conf, td);
129-
} catch (IOException e) {
130-
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
131-
}
119+
checkEncryption(conf, td);
132120
}
133121

134122
// Verify compaction policy
135-
try {
136-
checkCompactionPolicy(conf, td);
137-
} catch (IOException e) {
138-
warnOrThrowExceptionForFailure(false, e.getMessage(), e);
139-
}
123+
checkCompactionPolicy(conf, td);
140124
// check that we have at least 1 CF
141125
if (td.getColumnFamilyCount() == 0) {
142126
String message = "Table should have at least one column family.";
@@ -155,6 +139,12 @@ public static void sanityCheck(final Configuration c, final TableDescriptor td)
155139
warnOrThrowExceptionForFailure(false, "Meta table can't be set as read only.", null);
156140
}
157141

142+
// check replication scope
143+
checkReplicationScope(conf, td);
144+
145+
// check bloom filter type
146+
checkBloomFilterType(conf, td);
147+
158148
for (ColumnFamilyDescriptor hcd : td.getColumnFamilies()) {
159149
if (hcd.getTimeToLive() <= 0) {
160150
String message = "TTL for column family " + hcd.getNameAsString() + " must be positive.";
@@ -185,11 +175,6 @@ public static void sanityCheck(final Configuration c, final TableDescriptor td)
185175
warnOrThrowExceptionForFailure(logWarn, message, null);
186176
}
187177

188-
// check replication scope
189-
checkReplicationScope(hcd);
190-
// check bloom filter type
191-
checkBloomFilterType(hcd);
192-
193178
// check data replication factor, it can be 0(default value) when user has not explicitly
194179
// set the value, in this case we use default replication factor set in the file system.
195180
if (hcd.getDFSReplication() < 0) {
@@ -207,103 +192,144 @@ public static void sanityCheck(final Configuration c, final TableDescriptor td)
207192
}
208193
}
209194

210-
private static void checkReplicationScope(final ColumnFamilyDescriptor cfd) throws IOException {
211-
// check replication scope
212-
WALProtos.ScopeType scop = WALProtos.ScopeType.valueOf(cfd.getScope());
213-
if (scop == null) {
214-
String message = "Replication scope for column family " + cfd.getNameAsString() + " is "
215-
+ cfd.getScope() + " which is invalid.";
216-
217-
LOG.error(message);
218-
throw new DoNotRetryIOException(message);
219-
}
220-
}
221-
222-
private static void checkCompactionPolicy(Configuration conf, TableDescriptor td)
195+
private static void checkReplicationScope(final Configuration conf, final TableDescriptor td)
223196
throws IOException {
224-
// FIFO compaction has some requirements
225-
// Actually FCP ignores periodic major compactions
226-
String className = td.getValue(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY);
227-
if (className == null) {
228-
className = conf.get(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY,
229-
ExploringCompactionPolicy.class.getName());
230-
}
231-
232-
int blockingFileCount = HStore.DEFAULT_BLOCKING_STOREFILE_COUNT;
233-
String sv = td.getValue(HStore.BLOCKING_STOREFILES_KEY);
234-
if (sv != null) {
235-
blockingFileCount = Integer.parseInt(sv);
236-
} else {
237-
blockingFileCount = conf.getInt(HStore.BLOCKING_STOREFILES_KEY, blockingFileCount);
238-
}
239-
240-
for (ColumnFamilyDescriptor hcd : td.getColumnFamilies()) {
241-
String compactionPolicy =
242-
hcd.getConfigurationValue(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY);
243-
if (compactionPolicy == null) {
244-
compactionPolicy = className;
245-
}
246-
if (!compactionPolicy.equals(FIFOCompactionPolicy.class.getName())) {
247-
continue;
197+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
198+
boolean logWarn = !shouldSanityCheck(conf);
199+
try {
200+
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
201+
// check replication scope
202+
WALProtos.ScopeType scop = WALProtos.ScopeType.valueOf(cfd.getScope());
203+
if (scop == null) {
204+
String message = "Replication scope for column family " + cfd.getNameAsString() + " is "
205+
+ cfd.getScope() + " which is invalid.";
206+
207+
throw new DoNotRetryIOException(message);
208+
}
248209
}
249-
// FIFOCompaction
250-
String message = null;
210+
} catch (IOException e) {
211+
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
212+
}
251213

252-
// 1. Check TTL
253-
if (hcd.getTimeToLive() == ColumnFamilyDescriptorBuilder.DEFAULT_TTL) {
254-
message = "Default TTL is not supported for FIFO compaction";
255-
throw new IOException(message);
256-
}
214+
}
257215

258-
// 2. Check min versions
259-
if (hcd.getMinVersions() > 0) {
260-
message = "MIN_VERSION > 0 is not supported for FIFO compaction";
261-
throw new IOException(message);
216+
private static void checkCompactionPolicy(final Configuration conf, final TableDescriptor td)
217+
throws IOException {
218+
try {
219+
// FIFO compaction has some requirements
220+
// Actually FCP ignores periodic major compactions
221+
String className = td.getValue(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY);
222+
if (className == null) {
223+
className = conf.get(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY,
224+
ExploringCompactionPolicy.class.getName());
262225
}
263226

264-
// 3. blocking file count
265-
sv = hcd.getConfigurationValue(HStore.BLOCKING_STOREFILES_KEY);
227+
int blockingFileCount = HStore.DEFAULT_BLOCKING_STOREFILE_COUNT;
228+
String sv = td.getValue(HStore.BLOCKING_STOREFILES_KEY);
266229
if (sv != null) {
267230
blockingFileCount = Integer.parseInt(sv);
231+
} else {
232+
blockingFileCount = conf.getInt(HStore.BLOCKING_STOREFILES_KEY, blockingFileCount);
268233
}
269-
if (blockingFileCount < 1000) {
270-
message =
271-
"Blocking file count '" + HStore.BLOCKING_STOREFILES_KEY + "' " + blockingFileCount
272-
+ " is below recommended minimum of 1000 for column family " + hcd.getNameAsString();
273-
throw new IOException(message);
234+
235+
for (ColumnFamilyDescriptor hcd : td.getColumnFamilies()) {
236+
String compactionPolicy =
237+
hcd.getConfigurationValue(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY);
238+
if (compactionPolicy == null) {
239+
compactionPolicy = className;
240+
}
241+
if (!compactionPolicy.equals(FIFOCompactionPolicy.class.getName())) {
242+
continue;
243+
}
244+
// FIFOCompaction
245+
String message = null;
246+
247+
// 1. Check TTL
248+
if (hcd.getTimeToLive() == ColumnFamilyDescriptorBuilder.DEFAULT_TTL) {
249+
message = "Default TTL is not supported for FIFO compaction";
250+
throw new IOException(message);
251+
}
252+
253+
// 2. Check min versions
254+
if (hcd.getMinVersions() > 0) {
255+
message = "MIN_VERSION > 0 is not supported for FIFO compaction";
256+
throw new IOException(message);
257+
}
258+
259+
// 3. blocking file count
260+
sv = hcd.getConfigurationValue(HStore.BLOCKING_STOREFILES_KEY);
261+
if (sv != null) {
262+
blockingFileCount = Integer.parseInt(sv);
263+
}
264+
if (blockingFileCount < 1000) {
265+
message =
266+
"Blocking file count '" + HStore.BLOCKING_STOREFILES_KEY + "' " + blockingFileCount
267+
+ " is below recommended minimum of 1000 for column family " + hcd.getNameAsString();
268+
throw new IOException(message);
269+
}
274270
}
271+
} catch (IOException e) {
272+
warnOrThrowExceptionForFailure(false, e.getMessage(), e);
275273
}
276274
}
277275

278-
private static void checkBloomFilterType(ColumnFamilyDescriptor cfd) throws IOException {
279-
Configuration conf = new CompoundConfiguration().addStringMap(cfd.getConfiguration());
276+
private static void checkBloomFilterType(final Configuration conf, final TableDescriptor td)
277+
throws IOException {
278+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
279+
boolean logWarn = !shouldSanityCheck(conf);
280280
try {
281-
BloomFilterUtil.getBloomFilterParam(cfd.getBloomFilterType(), conf);
282-
} catch (IllegalArgumentException e) {
283-
throw new DoNotRetryIOException("Failed to get bloom filter param", e);
281+
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
282+
Configuration cfdConf = new CompoundConfiguration().addStringMap(cfd.getConfiguration());
283+
try {
284+
BloomFilterUtil.getBloomFilterParam(cfd.getBloomFilterType(), cfdConf);
285+
} catch (IllegalArgumentException e) {
286+
throw new DoNotRetryIOException("Failed to get bloom filter param", e);
287+
}
288+
}
289+
} catch (IOException e) {
290+
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
284291
}
285292
}
286293

287-
public static void checkCompression(final TableDescriptor td) throws IOException {
288-
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
289-
CompressionTest.testCompression(cfd.getCompressionType());
290-
CompressionTest.testCompression(cfd.getCompactionCompressionType());
291-
CompressionTest.testCompression(cfd.getMajorCompactionCompressionType());
292-
CompressionTest.testCompression(cfd.getMinorCompactionCompressionType());
294+
public static void checkCompression(final Configuration conf, final TableDescriptor td)
295+
throws IOException {
296+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
297+
boolean logWarn = !shouldSanityCheck(conf);
298+
try {
299+
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
300+
CompressionTest.testCompression(cfd.getCompressionType());
301+
CompressionTest.testCompression(cfd.getCompactionCompressionType());
302+
CompressionTest.testCompression(cfd.getMajorCompactionCompressionType());
303+
CompressionTest.testCompression(cfd.getMinorCompactionCompressionType());
304+
}
305+
} catch (IOException e) {
306+
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
293307
}
294308
}
295309

296310
public static void checkEncryption(final Configuration conf, final TableDescriptor td)
297311
throws IOException {
298-
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
299-
EncryptionTest.testEncryption(conf, cfd.getEncryptionType(), cfd.getEncryptionKey());
312+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
313+
boolean logWarn = !shouldSanityCheck(conf);
314+
try {
315+
for (ColumnFamilyDescriptor cfd : td.getColumnFamilies()) {
316+
EncryptionTest.testEncryption(conf, cfd.getEncryptionType(), cfd.getEncryptionKey());
317+
}
318+
} catch (IOException e) {
319+
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
300320
}
301321
}
302322

303323
public static void checkClassLoading(final Configuration conf, final TableDescriptor td)
304324
throws IOException {
305-
RegionSplitPolicy.getSplitPolicyClass(td, conf);
306-
RegionCoprocessorHost.testTableCoprocessorAttrs(conf, td);
325+
// Setting logs to warning instead of throwing exception if sanityChecks are disabled
326+
boolean logWarn = !shouldSanityCheck(conf);
327+
try {
328+
RegionSplitPolicy.getSplitPolicyClass(td, conf);
329+
RegionCoprocessorHost.testTableCoprocessorAttrs(conf, td);
330+
} catch (Exception e) {
331+
warnOrThrowExceptionForFailure(logWarn, e.getMessage(), e);
332+
}
307333
}
308334

309335
// HBASE-13350 - Helper method to log warning on sanity check failures if checks disabled.

hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerMetrics.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ public static void startCluster() throws Exception {
7474
LOG.info("Starting cluster");
7575
Configuration conf = TEST_UTIL.getConfiguration();
7676

77-
// Disable sanity check for coprocessor
78-
conf.setBoolean(TableDescriptorChecker.TABLE_SANITY_CHECKS, false);
77+
// Enable sanity check for coprocessor, so that region reopen fails on the RS
78+
conf.setBoolean(TableDescriptorChecker.TABLE_SANITY_CHECKS, true);
7979

8080
// set RIT stuck warning threshold to a small value
8181
conf.setInt(HConstants.METRICS_RIT_STUCK_WARNING_THRESHOLD, 20);
@@ -100,6 +100,8 @@ public static void startCluster() throws Exception {
100100
TEST_UTIL.startMiniCluster(1);
101101
CLUSTER = TEST_UTIL.getHBaseCluster();
102102
MASTER = CLUSTER.getMaster();
103+
// Disable sanity check for coprocessor, so that modify table runs on the HMaster
104+
MASTER.getConfiguration().setBoolean(TableDescriptorChecker.TABLE_SANITY_CHECKS, false);
103105
}
104106

105107
@AfterClass
@@ -133,7 +135,6 @@ public void testRITAssignmentManagerMetrics() throws Exception {
133135
amSource);
134136

135137
// alter table with a non-existing coprocessor
136-
137138
TableDescriptor htd = TableDescriptorBuilder.newBuilder(TABLENAME)
138139
.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY))
139140
.setCoprocessor(CoprocessorDescriptorBuilder.newBuilder("com.foo.FooRegionObserver")

hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestOpenRegionFailedMemoryLeak.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.concurrent.ScheduledExecutorService;
2828
import java.util.concurrent.ThreadPoolExecutor;
2929
import java.util.concurrent.TimeUnit;
30+
import org.apache.hadoop.conf.Configuration;
3031
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
3132
import org.apache.hadoop.hbase.HBaseClassTestRule;
3233
import org.apache.hadoop.hbase.HBaseTestingUtility;
@@ -40,9 +41,11 @@
4041
import org.apache.hadoop.hbase.testclassification.LargeTests;
4142
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
4243
import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
44+
import org.apache.hadoop.hbase.util.TableDescriptorChecker;
4345
import org.apache.hadoop.metrics2.MetricsExecutor;
4446
import org.junit.AfterClass;
4547
import org.junit.Assert;
48+
import org.junit.BeforeClass;
4649
import org.junit.ClassRule;
4750
import org.junit.Test;
4851
import org.junit.experimental.categories.Category;
@@ -60,6 +63,14 @@ public class TestOpenRegionFailedMemoryLeak {
6063

6164
private static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
6265

66+
@BeforeClass
67+
public static void startCluster() throws Exception {
68+
Configuration conf = TEST_UTIL.getConfiguration();
69+
70+
// Enable sanity check for coprocessor
71+
conf.setBoolean(TableDescriptorChecker.TABLE_SANITY_CHECKS, true);
72+
}
73+
6374
@AfterClass
6475
public static void tearDown() throws IOException {
6576
EnvironmentEdgeManagerTestHelper.reset();

0 commit comments

Comments
 (0)