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