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.regionserver.handler;
21
22 import java.io.IOException;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.HRegionInfo;
27 import org.apache.hadoop.hbase.Server;
28 import org.apache.hadoop.hbase.executor.EventHandler;
29 import org.apache.hadoop.hbase.regionserver.HRegion;
30 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
31 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
32 import org.apache.zookeeper.KeeperException;
33
34
35
36
37 public class CloseRegionHandler extends EventHandler {
38
39
40
41
42
43 private static final Log LOG = LogFactory.getLog(CloseRegionHandler.class);
44
45 private final int FAILED = -1;
46
47 private final RegionServerServices rsServices;
48
49 private final HRegionInfo regionInfo;
50
51
52
53 private final boolean abort;
54
55
56
57
58
59 private final boolean zk;
60
61
62 public CloseRegionHandler(final Server server,
63 final RegionServerServices rsServices, HRegionInfo regionInfo) {
64 this(server, rsServices, regionInfo, false, true);
65 }
66
67
68
69
70
71
72
73
74
75 public CloseRegionHandler(final Server server,
76 final RegionServerServices rsServices,
77 final HRegionInfo regionInfo, final boolean abort, final boolean zk) {
78 this(server, rsServices, regionInfo, abort, zk, EventType.M_RS_CLOSE_REGION);
79 }
80
81 protected CloseRegionHandler(final Server server,
82 final RegionServerServices rsServices, HRegionInfo regionInfo,
83 boolean abort, final boolean zk, EventType eventType) {
84 super(server, eventType);
85 this.server = server;
86 this.rsServices = rsServices;
87 this.regionInfo = regionInfo;
88 this.abort = abort;
89 this.zk = zk;
90 }
91
92 public HRegionInfo getRegionInfo() {
93 return regionInfo;
94 }
95
96 @Override
97 public void process() {
98 try {
99 String name = regionInfo.getRegionNameAsString();
100 LOG.debug("Processing close of " + name);
101 String encodedRegionName = regionInfo.getEncodedName();
102
103 HRegion region = this.rsServices.getFromOnlineRegions(encodedRegionName);
104 if (region == null) {
105 LOG.warn("Received CLOSE for region " + name +
106 " but currently not serving");
107 return;
108 }
109
110 int expectedVersion = FAILED;
111 if (this.zk) {
112 expectedVersion = setClosingState();
113 if (expectedVersion == FAILED) return;
114 }
115
116
117 try {
118
119
120 if (region.close(abort) == null) {
121
122
123
124 LOG.warn("Can't close region: was already closed during close(): " +
125 regionInfo.getRegionNameAsString());
126 return;
127 }
128 } catch (IOException e) {
129 LOG.error("Unrecoverable exception while closing region " +
130 regionInfo.getRegionNameAsString() + ", still finishing close", e);
131 }
132
133 this.rsServices.removeFromOnlineRegions(regionInfo.getEncodedName());
134
135 if (this.zk) setClosedState(expectedVersion, region);
136
137
138 LOG.debug("Closed region " + region.getRegionNameAsString());
139 } finally {
140 this.rsServices.getRegionsInTransitionInRS().
141 remove(this.regionInfo.getEncodedNameAsBytes());
142 }
143 }
144
145
146
147
148
149 private void setClosedState(final int expectedVersion, final HRegion region) {
150 try {
151 if (ZKAssign.transitionNodeClosed(server.getZooKeeper(), regionInfo,
152 server.getServerName(), expectedVersion) == FAILED) {
153 LOG.warn("Completed the CLOSE of a region but when transitioning from " +
154 " CLOSING to CLOSED got a version mismatch, someone else clashed " +
155 "so now unassigning");
156 region.close();
157 return;
158 }
159 } catch (NullPointerException e) {
160
161 LOG.warn("NPE during close -- catching and continuing...", e);
162 } catch (KeeperException e) {
163 LOG.error("Failed transitioning node from CLOSING to CLOSED", e);
164 return;
165 } catch (IOException e) {
166 LOG.error("Failed to close region after failing to transition", e);
167 return;
168 }
169 }
170
171
172
173
174
175 private int setClosingState() {
176 int expectedVersion = FAILED;
177 try {
178 if ((expectedVersion = ZKAssign.createNodeClosing(
179 server.getZooKeeper(), regionInfo, server.getServerName())) == FAILED) {
180 LOG.warn("Error creating node in CLOSING state, aborting close of " +
181 regionInfo.getRegionNameAsString());
182 }
183 } catch (KeeperException e) {
184 LOG.warn("Error creating node in CLOSING state, aborting close of " +
185 regionInfo.getRegionNameAsString());
186 }
187 return expectedVersion;
188 }
189 }