View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.util.hbck;
19  
20  import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.assertErrors;
21  import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.doFsck;
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.util.Arrays;
26  import java.util.List;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.NamespaceDescriptor;
32  import org.apache.hadoop.hbase.TableName;
33  import org.apache.hadoop.hbase.testclassification.MediumTests;
34  import org.apache.hadoop.hbase.client.Admin;
35  import org.apache.hadoop.hbase.client.Connection;
36  import org.apache.hadoop.hbase.client.ConnectionFactory;
37  import org.apache.hadoop.hbase.util.Bytes;
38  import org.apache.hadoop.hbase.util.HBaseFsck;
39  import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE;
40  import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
41  import org.junit.Test;
42  import org.junit.experimental.categories.Category;
43  
44  /**
45   * This builds a table, removes info from meta, and then rebuilds meta.
46   */
47  @Category(MediumTests.class)
48  public class TestOfflineMetaRebuildBase extends OfflineMetaRebuildTestCore {
49    private static final Log LOG = LogFactory.getLog(TestOfflineMetaRebuildBase.class);
50  
51    @Test(timeout = 120000)
52    public void testMetaRebuild() throws Exception {
53      wipeOutMeta();
54  
55      // is meta really messed up?
56      assertEquals(1, scanMeta());
57      assertErrors(doFsck(conf, false),
58          new ERROR_CODE[] {
59              ERROR_CODE.NOT_IN_META_OR_DEPLOYED,
60              ERROR_CODE.NOT_IN_META_OR_DEPLOYED,
61              ERROR_CODE.NOT_IN_META_OR_DEPLOYED,
62              ERROR_CODE.NOT_IN_META_OR_DEPLOYED});
63      // Note, would like to check # of tables, but this takes a while to time
64      // out.
65  
66      // shutdown the minicluster
67      TEST_UTIL.shutdownMiniHBaseCluster();
68      TEST_UTIL.shutdownMiniZKCluster();
69  
70      // rebuild meta table from scratch
71      HBaseFsck fsck = new HBaseFsck(conf);
72      assertTrue(fsck.rebuildMeta(false));
73  
74      // bring up the minicluster
75      TEST_UTIL.startMiniZKCluster();
76      TEST_UTIL.restartHBaseCluster(3);
77      validateMetaAndUserTableRows(1, 5);
78    }
79  
80    @Test(timeout = 300000)
81    public void testHMasterStartupOnMetaRebuild() throws Exception {
82      // shutdown the minicluster
83      TEST_UTIL.shutdownMiniHBaseCluster();
84  
85      // Assign meta in master and restart HBase cluster
86      TEST_UTIL.getConfiguration().set("hbase.balancer.tablesOnMaster", "hbase:meta");
87      // Set namespace initialization timeout
88      TEST_UTIL.getConfiguration().set("hbase.master.namespace.init.timeout", "150000");
89      TEST_UTIL.restartHBaseCluster(3);
90      TEST_UTIL.getMiniHBaseCluster().waitForActiveAndReadyMaster();
91  
92      try {
93        // Create namespace
94        TEST_UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create("ns1").build());
95        TEST_UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create("ns2").build());
96        // Create tables
97        TEST_UTIL.createTable(TableName.valueOf("ns1:testHMasterStartupOnMetaRebuild"),
98          Bytes.toBytes("cf1"));
99        TEST_UTIL.createTable(TableName.valueOf("ns2:testHMasterStartupOnMetaRebuild"),
100         Bytes.toBytes("cf1"));
101 
102       // Flush meta
103       TEST_UTIL.flush(TableName.META_TABLE_NAME);
104 
105       // HMaster graceful shutdown
106       TEST_UTIL.getHBaseCluster().getMaster().shutdown();
107 
108       // Kill region servers
109       List<RegionServerThread> regionServerThreads =
110           TEST_UTIL.getHBaseCluster().getRegionServerThreads();
111       for (RegionServerThread regionServerThread : regionServerThreads) {
112         TEST_UTIL.getHBaseCluster()
113             .killRegionServer(regionServerThread.getRegionServer().getServerName());
114       }
115 
116       // rebuild meta table from scratch
117       HBaseFsck fsck = new HBaseFsck(conf);
118       assertTrue(fsck.rebuildMeta(false));
119 
120       // bring up the minicluster
121       TEST_UTIL.restartHBaseCluster(3);
122       validateMetaAndUserTableRows(3, 7);
123     } finally {
124       // Remove table and namesapce
125       TEST_UTIL.deleteTable("ns1:testHMasterStartupOnMetaRebuild");
126       TEST_UTIL.deleteTable("ns2:testHMasterStartupOnMetaRebuild");
127       TEST_UTIL.getHBaseAdmin().deleteNamespace("ns1");
128       TEST_UTIL.getHBaseAdmin().deleteNamespace("ns2");
129     }
130   }
131 
132   /*
133    * Validate meta table region count and user table rows.
134    */
135   private void validateMetaAndUserTableRows(int totalTableCount, int totalRegionCount)
136       throws Exception {
137     try (Connection connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
138       Admin admin = connection.getAdmin();
139       admin.enableTable(table);
140       LOG.info("Waiting for no more RIT");
141       TEST_UTIL.waitUntilNoRegionsInTransition(60000);
142       LOG.info("No more RIT in ZK, now doing final test verification");
143 
144       // everything is good again.
145       assertEquals(totalRegionCount, scanMeta());
146       HTableDescriptor[] htbls = admin.listTables();
147       LOG.info("Tables present after restart: " + Arrays.toString(htbls));
148       assertEquals(totalTableCount, htbls.length);
149     }
150 
151     assertErrors(doFsck(conf, false), new ERROR_CODE[] {});
152     LOG.info("Table " + table + " has " + tableRowCount(conf, table) + " entries.");
153     assertEquals(16, tableRowCount(conf, table));
154   }
155 }