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 String name = regionInfo.getRegionNameAsString();
99 LOG.debug("Processing close of " + name);
100 String encodedRegionName = regionInfo.getEncodedName();
101
102 HRegion region = this.rsServices.getFromOnlineRegions(encodedRegionName);
103 if (region == null) {
104 LOG.warn("Received CLOSE for region " + name + " but currently not serving");
105 return;
106 }
107
108 int expectedVersion = FAILED;
109 if (this.zk) {
110 expectedVersion = setClosingState();
111 if (expectedVersion == FAILED) return;
112 }
113
114
115 try {
116
117
118 if (region.close(abort) == null) {
119
120
121
122 LOG.warn("Can't close region: was already closed during close(): " +
123 regionInfo.getRegionNameAsString());
124 return;
125 }
126 } catch (IOException e) {
127 LOG.error("Unrecoverable exception while closing region " +
128 regionInfo.getRegionNameAsString() + ", still finishing close", e);
129 }
130
131 this.rsServices.removeFromOnlineRegions(regionInfo.getEncodedName());
132
133 if (this.zk) setClosedState(expectedVersion, region);
134
135
136 LOG.debug("Closed region " + region.getRegionNameAsString());
137 }
138
139
140
141
142
143 private void setClosedState(final int expectedVersion, final HRegion region) {
144 try {
145 if (ZKAssign.transitionNodeClosed(server.getZooKeeper(), regionInfo,
146 server.getServerName(), expectedVersion) == FAILED) {
147 LOG.warn("Completed the CLOSE of a region but when transitioning from " +
148 " CLOSING to CLOSED got a version mismatch, someone else clashed " +
149 "so now unassigning");
150 region.close();
151 return;
152 }
153 } catch (NullPointerException e) {
154
155 LOG.warn("NPE during close -- catching and continuing...", e);
156 } catch (KeeperException e) {
157 LOG.error("Failed transitioning node from CLOSING to CLOSED", e);
158 return;
159 } catch (IOException e) {
160 LOG.error("Failed to close region after failing to transition", e);
161 return;
162 }
163 }
164
165
166
167
168
169 private int setClosingState() {
170 int expectedVersion = FAILED;
171 try {
172 if ((expectedVersion = ZKAssign.createNodeClosing(
173 server.getZooKeeper(), regionInfo, server.getServerName())) == FAILED) {
174 LOG.warn("Error creating node in CLOSING state, aborting close of " +
175 regionInfo.getRegionNameAsString());
176 }
177 } catch (KeeperException e) {
178 LOG.warn("Error creating node in CLOSING state, aborting close of " +
179 regionInfo.getRegionNameAsString());
180 }
181 return expectedVersion;
182 }
183 }