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.master.handler;
21
22 import java.io.IOException;
23 import java.util.List;
24 import java.util.concurrent.ExecutorService;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.HRegionInfo;
29 import org.apache.hadoop.hbase.Server;
30 import org.apache.hadoop.hbase.TableNotEnabledException;
31 import org.apache.hadoop.hbase.TableNotFoundException;
32 import org.apache.hadoop.hbase.catalog.CatalogTracker;
33 import org.apache.hadoop.hbase.catalog.MetaReader;
34 import org.apache.hadoop.hbase.executor.EventHandler;
35 import org.apache.hadoop.hbase.master.AssignmentManager;
36 import org.apache.hadoop.hbase.master.BulkAssigner;
37 import org.apache.hadoop.hbase.util.Bytes;
38 import org.apache.zookeeper.KeeperException;
39
40
41
42
43 public class DisableTableHandler extends EventHandler {
44 private static final Log LOG = LogFactory.getLog(DisableTableHandler.class);
45 private final byte [] tableName;
46 private final String tableNameStr;
47 private final AssignmentManager assignmentManager;
48
49 public DisableTableHandler(Server server, byte [] tableName,
50 CatalogTracker catalogTracker, AssignmentManager assignmentManager,
51 boolean skipTableStateCheck)
52 throws TableNotFoundException, TableNotEnabledException, IOException {
53 super(server, EventType.C_M_DISABLE_TABLE);
54 this.tableName = tableName;
55 this.tableNameStr = Bytes.toString(this.tableName);
56 this.assignmentManager = assignmentManager;
57
58
59
60
61 if (!MetaReader.tableExists(catalogTracker, this.tableNameStr)) {
62 throw new TableNotFoundException(this.tableNameStr);
63 }
64
65
66
67
68
69 if (!skipTableStateCheck)
70 {
71 try {
72 if (!this.assignmentManager.getZKTable().checkEnabledAndSetDisablingTable
73 (this.tableNameStr)) {
74 LOG.info("Table " + tableNameStr + " isn't enabled; skipping disable");
75 throw new TableNotEnabledException(this.tableNameStr);
76 }
77 } catch (KeeperException e) {
78 throw new IOException("Unable to ensure that the table will be" +
79 " disabling because of a ZooKeeper issue", e);
80 }
81 }
82 }
83
84 @Override
85 public String toString() {
86 String name = "UnknownServerName";
87 if(server != null && server.getServerName() != null) {
88 name = server.getServerName().toString();
89 }
90 return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" +
91 tableNameStr;
92 }
93
94 @Override
95 public void process() {
96 try {
97 LOG.info("Attemping to disable table " + this.tableNameStr);
98 handleDisableTable();
99 } catch (IOException e) {
100 LOG.error("Error trying to disable table " + this.tableNameStr, e);
101 } catch (KeeperException e) {
102 LOG.error("Error trying to disable table " + this.tableNameStr, e);
103 }
104 }
105
106 private void handleDisableTable() throws IOException, KeeperException {
107
108 this.assignmentManager.getZKTable().setDisablingTable(this.tableNameStr);
109 boolean done = false;
110 while (true) {
111
112
113
114
115 final List<HRegionInfo> regions =
116 this.assignmentManager.getRegionsOfTable(tableName);
117 if (regions.size() == 0) {
118 done = true;
119 break;
120 }
121 LOG.info("Offlining " + regions.size() + " regions.");
122 BulkDisabler bd = new BulkDisabler(this.server, regions);
123 try {
124 if (bd.bulkAssign()) {
125 done = true;
126 break;
127 }
128 } catch (InterruptedException e) {
129 LOG.warn("Disable was interrupted");
130
131 Thread.currentThread().interrupt();
132 break;
133 }
134 }
135
136 if (done) this.assignmentManager.getZKTable().setDisabledTable(this.tableNameStr);
137 LOG.info("Disabled table is done=" + done);
138 }
139
140
141
142
143 class BulkDisabler extends BulkAssigner {
144 private final List<HRegionInfo> regions;
145
146 BulkDisabler(final Server server, final List<HRegionInfo> regions) {
147 super(server);
148 this.regions = regions;
149 }
150
151 @Override
152 protected void populatePool(ExecutorService pool) {
153 for (HRegionInfo region: regions) {
154 if (assignmentManager.isRegionInTransition(region) != null) continue;
155 final HRegionInfo hri = region;
156 pool.execute(new Runnable() {
157 public void run() {
158 assignmentManager.unassign(hri);
159 }
160 });
161 }
162 }
163
164 @Override
165 protected boolean waitUntilDone(long timeout)
166 throws InterruptedException {
167 long startTime = System.currentTimeMillis();
168 long remaining = timeout;
169 List<HRegionInfo> regions = null;
170 while (!server.isStopped() && remaining > 0) {
171 Thread.sleep(waitingTimeForEvents);
172 regions = assignmentManager.getRegionsOfTable(tableName);
173 LOG.debug("Disable waiting until done; " + remaining + " ms remaining; " + regions);
174 if (regions.isEmpty()) break;
175 remaining = timeout - (System.currentTimeMillis() - startTime);
176 }
177 return regions != null && regions.isEmpty();
178 }
179 }
180 }