1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.io.IOException;
23 import java.util.List;
24
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.HRegionInfo;
27 import org.apache.hadoop.hbase.NotServingRegionException;
28 import org.apache.hadoop.hbase.ServerName;
29 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
30 import org.apache.hadoop.hbase.client.HBaseAdmin;
31 import org.apache.hadoop.hbase.client.HConnection;
32 import org.apache.hadoop.hbase.client.HConnectionManager;
33 import org.apache.hadoop.hbase.ipc.HRegionInterface;
34 import org.apache.zookeeper.KeeperException;
35
36 public class HBaseFsckRepair {
37
38
39
40
41
42
43
44
45
46
47
48
49 public static void fixDupeAssignment(HBaseAdmin admin, HRegionInfo region,
50 List<ServerName> servers)
51 throws IOException, KeeperException, InterruptedException {
52
53 HRegionInfo actualRegion = new HRegionInfo(region);
54
55
56 for(ServerName server : servers) {
57 closeRegionSilentlyAndWait(admin.getConfiguration(), server, actualRegion);
58 }
59
60
61 forceOfflineInZK(admin, actualRegion);
62 }
63
64
65
66
67
68
69
70
71
72
73 public static void fixUnassigned(HBaseAdmin admin, HRegionInfo region)
74 throws IOException, KeeperException {
75 HRegionInfo actualRegion = new HRegionInfo(region);
76
77
78 forceOfflineInZK(admin, actualRegion);
79 }
80
81 private static void forceOfflineInZK(HBaseAdmin admin, final HRegionInfo region)
82 throws ZooKeeperConnectionException, KeeperException, IOException {
83 admin.assign(region.getRegionName());
84 }
85
86 private static void closeRegionSilentlyAndWait(Configuration conf,
87 ServerName server, HRegionInfo region) throws IOException,
88 InterruptedException {
89 HConnection connection = HConnectionManager.getConnection(conf);
90 boolean success = false;
91 try {
92 HRegionInterface rs =
93 connection.getHRegionConnection(server.getHostname(), server.getPort());
94 rs.closeRegion(region, false);
95 long timeout = conf.getLong("hbase.hbck.close.timeout", 120000);
96 long expiration = timeout + System.currentTimeMillis();
97 while (System.currentTimeMillis() < expiration) {
98 try {
99 HRegionInfo rsRegion = rs.getRegionInfo(region.getRegionName());
100 if (rsRegion == null)
101 throw new NotServingRegionException();
102 } catch (Exception e) {
103 success = true;
104 return;
105 }
106 Thread.sleep(1000);
107 }
108 throw new IOException("Region " + region + " failed to close within"
109 + " timeout " + timeout);
110 } finally {
111 try {
112 connection.close();
113 } catch (IOException ioe) {
114 if (success) {
115 throw ioe;
116 }
117 }
118 }
119 }
120 }