1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master;
19
20 import java.io.IOException;
21 import java.util.Arrays;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.Cell;
28 import org.apache.hadoop.hbase.HConstants;
29 import org.apache.hadoop.hbase.HRegionInfo;
30 import org.apache.hadoop.hbase.Server;
31 import org.apache.hadoop.hbase.ServerName;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.catalog.CatalogTracker;
34 import org.apache.hadoop.hbase.catalog.MetaEditor;
35 import org.apache.hadoop.hbase.client.HTable;
36 import org.apache.hadoop.hbase.client.Put;
37 import org.apache.hadoop.hbase.client.Result;
38 import org.apache.hadoop.hbase.master.RegionState.State;
39 import org.apache.hadoop.hbase.regionserver.HRegion;
40 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.hbase.util.ConfigUtil;
43 import org.apache.hadoop.hbase.util.MultiHConnection;
44 import org.apache.hadoop.hbase.zookeeper.MetaRegionTracker;
45 import org.apache.zookeeper.KeeperException;
46
47 import com.google.common.base.Preconditions;
48
49
50
51
52
53 @InterfaceAudience.Private
54 public class RegionStateStore {
55 private static final Log LOG = LogFactory.getLog(RegionStateStore.class);
56
57 private volatile HRegion metaRegion;
58 private volatile HRegion rootRegion;
59 private volatile boolean initialized;
60
61 private final boolean noPersistence;
62 private final CatalogTracker catalogTracker;
63 private final Server server;
64 private MultiHConnection multiHConnection;
65
66
67
68
69
70
71
72
73 static ServerName getRegionServer(final Result r) {
74 Cell cell = r.getColumnLatestCell(HConstants.CATALOG_FAMILY, HConstants.SERVERNAME_QUALIFIER);
75 if (cell == null || cell.getValueLength() == 0) return HRegionInfo.getServerName(r);
76 return ServerName.parseServerName(Bytes.toString(cell.getValueArray(),
77 cell.getValueOffset(), cell.getValueLength()));
78 }
79
80
81
82
83
84
85 static State getRegionState(final Result r) {
86 Cell cell = r.getColumnLatestCell(HConstants.CATALOG_FAMILY, HConstants.STATE_QUALIFIER);
87 if (cell == null || cell.getValueLength() == 0) return State.OPEN;
88 return State.valueOf(Bytes.toString(cell.getValueArray(),
89 cell.getValueOffset(), cell.getValueLength()));
90 }
91
92
93
94
95
96
97
98
99
100
101 private boolean shouldPersistStateChange(
102 HRegionInfo hri, RegionState state, RegionState oldState) {
103 return !hri.isMetaRegion() && !RegionStates.isOneOfStates(
104 state, State.MERGING_NEW, State.SPLITTING_NEW, State.MERGED)
105 && !(RegionStates.isOneOfStates(state, State.OFFLINE)
106 && RegionStates.isOneOfStates(oldState, State.MERGING_NEW,
107 State.SPLITTING_NEW, State.MERGED));
108 }
109
110 RegionStateStore(final Server server) {
111 Configuration conf = server.getConfiguration();
112
113 noPersistence = ConfigUtil.useZKForAssignment(conf)
114 && !conf.getBoolean("hbase.assignment.usezk.migrating", false);
115 catalogTracker = server.getCatalogTracker();
116 this.server = server;
117 initialized = false;
118 }
119
120 void start() throws IOException {
121 if (!noPersistence) {
122 if (server instanceof RegionServerServices) {
123 metaRegion = ((RegionServerServices)server).getFromOnlineRegions(
124 HRegionInfo.FIRST_META_REGIONINFO.getEncodedName());
125 }
126
127 if (metaRegion == null) {
128 Configuration conf = server.getConfiguration();
129
130
131
132
133 multiHConnection =
134 new MultiHConnection(conf, conf.getInt("hbase.regionstatestore.meta.connection", 1));
135 }
136 }
137 initialized = true;
138 }
139
140 void stop() {
141 initialized = false;
142 if (multiHConnection != null) {
143 multiHConnection.close();
144 }
145 }
146
147 void updateRegionState(long openSeqNum, RegionState newState, RegionState oldState) {
148 if (noPersistence) {
149 return;
150 }
151 try {
152 HRegionInfo hri = newState.getRegion();
153
154
155 if (hri.isMetaRegion()) {
156
157 try {
158 MetaRegionTracker.setMetaLocation(server.getZooKeeper(), newState.getServerName(),
159 newState.getState());
160 return;
161 } catch (KeeperException e) {
162 throw new IOException("Failed to update meta ZNode", e);
163 }
164 }
165
166 if (!initialized || !shouldPersistStateChange(hri, newState, oldState)) {
167 return;
168 }
169
170 ServerName oldServer = oldState != null ? oldState.getServerName() : null;
171 ServerName serverName = newState.getServerName();
172 State state = newState.getState();
173 Put put = new Put(hri.getRegionName());
174 StringBuilder info = new StringBuilder("Updating row ");
175 info.append(hri.getRegionNameAsString()).append(" with state=").append(state);
176 if (serverName != null && !serverName.equals(oldServer)) {
177 put.addImmutable(HConstants.CATALOG_FAMILY, HConstants.SERVERNAME_QUALIFIER,
178 Bytes.toBytes(serverName.getServerName()));
179 info.append("&sn=").append(serverName);
180 }
181 if (openSeqNum >= 0) {
182 Preconditions.checkArgument(state == State.OPEN
183 && serverName != null, "Open region should be on a server");
184 put.addImmutable(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER,
185 Bytes.toBytes(serverName.getHostAndPort()));
186 put.addImmutable(HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER,
187 Bytes.toBytes(serverName.getStartcode()));
188 put.addImmutable(HConstants.CATALOG_FAMILY, HConstants.SEQNUM_QUALIFIER,
189 Bytes.toBytes(openSeqNum));
190 info.append("&openSeqNum=").append(openSeqNum);
191 info.append("&server=").append(serverName);
192 }
193 put.addImmutable(HConstants.CATALOG_FAMILY, HConstants.STATE_QUALIFIER,
194 Bytes.toBytes(state.name()));
195 LOG.info(info);
196
197 if (metaRegion != null) {
198 try {
199
200
201 metaRegion.put(put);
202 return;
203 } catch (Throwable t) {
204
205
206
207
208 synchronized (this) {
209 if (metaRegion != null) {
210 LOG.info("Meta region shortcut failed", t);
211 if (multiHConnection == null) {
212 multiHConnection = new MultiHConnection(server.getConfiguration(), 1);
213 }
214 metaRegion = null;
215 }
216 }
217 }
218 }
219
220 multiHConnection.processBatchCallback(Arrays.asList(put), TableName.META_TABLE_NAME, null,
221 null);
222 } catch (IOException ioe) {
223 LOG.error("Failed to persist region state " + newState, ioe);
224 server.abort("Failed to update region location", ioe);
225 }
226 }
227
228 void splitRegion(HRegionInfo p,
229 HRegionInfo a, HRegionInfo b, ServerName sn) throws IOException {
230 MetaEditor.splitRegion(catalogTracker, p, a, b, sn);
231 }
232
233 void mergeRegions(HRegionInfo p,
234 HRegionInfo a, HRegionInfo b, ServerName sn) throws IOException {
235 MetaEditor.mergeRegions(catalogTracker, p, a, b, sn);
236 }
237
238 }