1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.coordination;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.CoordinatedStateManager;
24 import org.apache.hadoop.hbase.HRegionInfo;
25 import org.apache.hadoop.hbase.ServerName;
26 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
27 import org.apache.hadoop.hbase.regionserver.HRegion;
28 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
29 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
30 import org.apache.zookeeper.KeeperException;
31
32 import java.io.IOException;
33
34
35
36
37 @InterfaceAudience.Private
38 public class ZkCloseRegionCoordination implements CloseRegionCoordination {
39 private static final Log LOG = LogFactory.getLog(ZkCloseRegionCoordination.class);
40
41 private final static int FAILED_VERSION = -1;
42
43 private CoordinatedStateManager csm;
44 private final ZooKeeperWatcher watcher;
45
46 public ZkCloseRegionCoordination(CoordinatedStateManager csm, ZooKeeperWatcher watcher) {
47 this.csm = csm;
48 this.watcher = watcher;
49 }
50
51
52
53
54
55 @Override
56 public boolean checkClosingState(HRegionInfo regionInfo, CloseRegionDetails crd) {
57 ZkCloseRegionDetails zkCrd = (ZkCloseRegionDetails) crd;
58
59 try {
60 return zkCrd.isPublishStatusInZk() && !ZKAssign.checkClosingState(watcher,
61 regionInfo, ((ZkCloseRegionDetails) crd).getExpectedVersion());
62 } catch (KeeperException ke) {
63 csm.getServer().abort("Unrecoverable exception while checking state with zk " +
64 regionInfo.getRegionNameAsString() + ", still finishing close", ke);
65 throw new RuntimeException(ke);
66 }
67 }
68
69
70
71
72 @Override
73 public void setClosedState(HRegion region, ServerName sn, CloseRegionDetails crd) {
74 ZkCloseRegionDetails zkCrd = (ZkCloseRegionDetails) crd;
75 String name = region.getRegionInfo().getRegionNameAsString();
76
77 if (zkCrd.isPublishStatusInZk()) {
78 if (setClosedState(region,sn, zkCrd)) {
79 LOG.debug("Set closed state in zk for " + name + " on " + sn);
80 } else {
81 LOG.debug("Set closed state in zk UNSUCCESSFUL for " + name + " on " + sn);
82 }
83 }
84 }
85
86
87
88
89 @Override
90 public CloseRegionDetails parseFromProtoRequest(AdminProtos.CloseRegionRequest request) {
91 ZkCloseRegionCoordination.ZkCloseRegionDetails zkCrd =
92 new ZkCloseRegionCoordination.ZkCloseRegionDetails();
93 zkCrd.setPublishStatusInZk(request.getTransitionInZK());
94 int versionOfClosingNode = -1;
95 if (request.hasVersionOfClosingNode()) {
96 versionOfClosingNode = request.getVersionOfClosingNode();
97 }
98 zkCrd.setExpectedVersion(versionOfClosingNode);
99
100 return zkCrd;
101 }
102
103
104
105
106
107
108
109 @Override
110 public CloseRegionDetails getDetaultDetails() {
111 ZkCloseRegionCoordination.ZkCloseRegionDetails zkCrd =
112 new ZkCloseRegionCoordination.ZkCloseRegionDetails();
113 zkCrd.setPublishStatusInZk(false);
114 zkCrd.setExpectedVersion(FAILED_VERSION);
115
116 return zkCrd;
117 }
118
119
120
121
122
123
124
125
126 private boolean setClosedState(final HRegion region,
127 ServerName sn,
128 ZkCloseRegionDetails zkCrd) {
129 final int expectedVersion = zkCrd.getExpectedVersion();
130
131 try {
132 if (ZKAssign.transitionNodeClosed(watcher, region.getRegionInfo(),
133 sn, expectedVersion) == FAILED_VERSION) {
134 LOG.warn("Completed the CLOSE of a region but when transitioning from " +
135 " CLOSING to CLOSED got a version mismatch, someone else clashed " +
136 "so now unassigning");
137 region.close();
138 return false;
139 }
140 } catch (NullPointerException e) {
141
142 LOG.warn("NPE during close -- catching and continuing...", e);
143 return false;
144 } catch (KeeperException e) {
145 LOG.error("Failed transitioning node from CLOSING to CLOSED", e);
146 return false;
147 } catch (IOException e) {
148 LOG.error("Failed to close region after failing to transition", e);
149 return false;
150 }
151 return true;
152 }
153
154
155
156
157
158 public static class ZkCloseRegionDetails implements CloseRegionCoordination.CloseRegionDetails {
159
160
161
162
163
164
165 private boolean publishStatusInZk;
166
167
168
169
170
171 private int expectedVersion = FAILED_VERSION;
172
173 public ZkCloseRegionDetails() {
174 }
175
176 public ZkCloseRegionDetails(boolean publishStatusInZk, int expectedVersion) {
177 this.publishStatusInZk = publishStatusInZk;
178 this.expectedVersion = expectedVersion;
179 }
180
181 public boolean isPublishStatusInZk() {
182 return publishStatusInZk;
183 }
184
185 public void setPublishStatusInZk(boolean publishStatusInZk) {
186 this.publishStatusInZk = publishStatusInZk;
187 }
188
189 public int getExpectedVersion() {
190 return expectedVersion;
191 }
192
193 public void setExpectedVersion(int expectedVersion) {
194 this.expectedVersion = expectedVersion;
195 }
196 }
197 }