1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master.procedure;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InterruptedIOException;
23 import java.io.OutputStream;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.concurrent.locks.Lock;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.hbase.HConstants;
36 import org.apache.hadoop.hbase.HRegionInfo;
37 import org.apache.hadoop.hbase.ServerName;
38 import org.apache.hadoop.hbase.client.ClusterConnection;
39 import org.apache.hadoop.hbase.client.RegionReplicaUtil;
40 import org.apache.hadoop.hbase.master.AssignmentManager;
41 import org.apache.hadoop.hbase.master.MasterFileSystem;
42 import org.apache.hadoop.hbase.master.MasterServices;
43 import org.apache.hadoop.hbase.master.RegionState;
44 import org.apache.hadoop.hbase.master.RegionStates;
45 import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;
46 import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
47 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
48 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionInfo;
49 import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
50 import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.ServerCrashState;
51 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
52 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode;
53 import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
54 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
55 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
56 import org.apache.hadoop.util.StringUtils;
57 import org.apache.zookeeper.KeeperException;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class ServerCrashProcedure
76 extends StateMachineProcedure<MasterProcedureEnv, ServerCrashState>
77 implements ServerProcedureInterface {
78 private static final Log LOG = LogFactory.getLog(ServerCrashProcedure.class);
79
80
81
82
83 public static final String KEY_SHORT_WAIT_ON_META =
84 "hbase.master.servercrash.short.wait.on.meta.ms";
85
86 public static final int DEFAULT_SHORT_WAIT_ON_META = 1000;
87
88
89
90
91
92 public static final String KEY_RETRIES_ON_META =
93 "hbase.master.servercrash.meta.retries";
94
95 public static final int DEFAULT_RETRIES_ON_META = 10;
96
97
98
99
100 public static final String KEY_WAIT_ON_RIT =
101 "hbase.master.servercrash.wait.on.rit.ms";
102
103 public static final int DEFAULT_WAIT_ON_RIT = 30000;
104
105 private static final Set<HRegionInfo> META_REGION_SET = new HashSet<HRegionInfo>();
106 static {
107 META_REGION_SET.add(HRegionInfo.FIRST_META_REGIONINFO);
108 }
109
110
111
112
113 private ServerName serverName;
114
115
116
117
118 private boolean notifiedDeadServer = false;
119
120
121
122
123 private Set<HRegionInfo> regionsOnCrashedServer;
124
125
126
127
128 private List<HRegionInfo> regionsAssigned;
129
130 private boolean distributedLogReplay = false;
131 private boolean carryingMeta = false;
132 private boolean shouldSplitWal;
133
134
135
136
137 private int cycles = 0;
138
139
140
141
142
143 private int previousState;
144
145
146
147
148
149
150
151 public ServerCrashProcedure(
152 final MasterProcedureEnv env,
153 final ServerName serverName,
154 final boolean shouldSplitWal,
155 final boolean carryingMeta) {
156 this.serverName = serverName;
157 this.shouldSplitWal = shouldSplitWal;
158 this.carryingMeta = carryingMeta;
159 this.setOwner(env.getRequestUser().getShortName());
160 }
161
162
163
164
165
166 public ServerCrashProcedure() {
167 super();
168 }
169
170 private void throwProcedureYieldException(final String msg) throws ProcedureYieldException {
171 String logMsg = msg + "; cycle=" + this.cycles + ", running for " +
172 StringUtils.formatTimeDiff(System.currentTimeMillis(), getStartTime());
173
174
175 if (LOG.isDebugEnabled()) LOG.debug(logMsg);
176 throw new ProcedureYieldException(logMsg);
177 }
178
179 @Override
180 protected Flow executeFromState(MasterProcedureEnv env, ServerCrashState state)
181 throws ProcedureYieldException {
182 if (LOG.isTraceEnabled()) {
183 LOG.trace(state);
184 }
185
186 if (state.ordinal() != this.previousState) {
187 this.previousState = state.ordinal();
188 this.cycles = 0;
189 } else {
190 this.cycles++;
191 }
192 MasterServices services = env.getMasterServices();
193
194 if (!services.getAssignmentManager().isFailoverCleanupDone()) {
195 throwProcedureYieldException("Waiting on master failover to complete");
196 }
197
198
199 if (!notifiedDeadServer) {
200 services.getServerManager().getDeadServers().notifyServer(serverName);
201 notifiedDeadServer = true;
202 }
203
204 try {
205 switch (state) {
206 case SERVER_CRASH_START:
207 LOG.info("Start processing crashed " + this.serverName);
208 start(env);
209
210 if (this.carryingMeta) setNextState(ServerCrashState.SERVER_CRASH_PROCESS_META);
211 else setNextState(ServerCrashState.SERVER_CRASH_GET_REGIONS);
212 break;
213
214 case SERVER_CRASH_GET_REGIONS:
215
216 if (!isMetaAssignedQuickTest(env)) {
217
218
219 long wait =
220 env.getMasterConfiguration().getLong(KEY_SHORT_WAIT_ON_META,
221 DEFAULT_SHORT_WAIT_ON_META);
222 wait = wait / 10;
223 Thread.sleep(wait);
224 throwProcedureYieldException("Waiting on hbase:meta assignment");
225 }
226 this.regionsOnCrashedServer =
227 services.getAssignmentManager().getRegionStates().getServerRegions(this.serverName);
228
229
230 if (!this.shouldSplitWal) {
231 setNextState(ServerCrashState.SERVER_CRASH_ASSIGN);
232 } else if (this.distributedLogReplay) {
233 setNextState(ServerCrashState.SERVER_CRASH_PREPARE_LOG_REPLAY);
234 } else {
235 setNextState(ServerCrashState.SERVER_CRASH_SPLIT_LOGS);
236 }
237 break;
238
239 case SERVER_CRASH_PROCESS_META:
240
241 if (!processMeta(env)) {
242 throwProcedureYieldException("Waiting on regions-in-transition to clear");
243 }
244 setNextState(ServerCrashState.SERVER_CRASH_GET_REGIONS);
245 break;
246
247 case SERVER_CRASH_PREPARE_LOG_REPLAY:
248 prepareLogReplay(env, this.regionsOnCrashedServer);
249 setNextState(ServerCrashState.SERVER_CRASH_ASSIGN);
250 break;
251
252 case SERVER_CRASH_SPLIT_LOGS:
253 splitLogs(env);
254
255 if (this.distributedLogReplay) setNextState(ServerCrashState.SERVER_CRASH_FINISH);
256 else setNextState(ServerCrashState.SERVER_CRASH_ASSIGN);
257 break;
258
259 case SERVER_CRASH_ASSIGN:
260 List<HRegionInfo> regionsToAssign = calcRegionsToAssign(env);
261
262
263
264
265
266
267 boolean regions = regionsToAssign != null && !regionsToAssign.isEmpty();
268 if (regions) {
269 this.regionsAssigned = regionsToAssign;
270 if (!assign(env, regionsToAssign)) {
271 throwProcedureYieldException("Failed assign; will retry");
272 }
273 }
274 if (this.shouldSplitWal && distributedLogReplay) {
275
276
277
278
279 setNextState(ServerCrashState.SERVER_CRASH_WAIT_ON_ASSIGN);
280 } else {
281 setNextState(ServerCrashState.SERVER_CRASH_FINISH);
282 }
283 break;
284
285 case SERVER_CRASH_WAIT_ON_ASSIGN:
286
287
288
289
290
291
292
293 if (this.regionsAssigned != null && !this.regionsAssigned.isEmpty()) {
294 if (!waitOnAssign(env, this.regionsAssigned)) {
295 throwProcedureYieldException("Waiting on region assign");
296 }
297 }
298 setNextState(ServerCrashState.SERVER_CRASH_SPLIT_LOGS);
299 break;
300
301 case SERVER_CRASH_FINISH:
302 LOG.info("Finished processing of crashed " + serverName);
303 services.getServerManager().getDeadServers().finish(serverName);
304 return Flow.NO_MORE_STATE;
305
306 default:
307 throw new UnsupportedOperationException("unhandled state=" + state);
308 }
309 } catch (ProcedureYieldException e) {
310 LOG.warn("Failed serverName=" + this.serverName + ", state=" + state + "; retry "
311 + e.getMessage());
312 throw e;
313 } catch (IOException e) {
314 LOG.warn("Failed serverName=" + this.serverName + ", state=" + state + "; retry", e);
315 } catch (InterruptedException e) {
316
317 LOG.warn("Interrupted serverName=" + this.serverName + ", state=" + state + "; retry", e);
318 Thread.currentThread().interrupt();
319 }
320 return Flow.HAS_MORE_STATE;
321 }
322
323
324
325
326
327
328 private void start(final MasterProcedureEnv env) throws IOException {
329 MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();
330
331 mfs.setLogRecoveryMode();
332 this.distributedLogReplay = mfs.getLogRecoveryMode() == RecoveryMode.LOG_REPLAY;
333 }
334
335
336
337
338
339
340
341 private boolean processMeta(final MasterProcedureEnv env)
342 throws IOException {
343 if (LOG.isDebugEnabled()) LOG.debug("Processing hbase:meta that was on " + this.serverName);
344 MasterServices services = env.getMasterServices();
345 MasterFileSystem mfs = services.getMasterFileSystem();
346 AssignmentManager am = services.getAssignmentManager();
347 HRegionInfo metaHRI = HRegionInfo.FIRST_META_REGIONINFO;
348 if (this.shouldSplitWal) {
349 if (this.distributedLogReplay) {
350 prepareLogReplay(env, META_REGION_SET);
351 } else {
352
353 mfs.splitMetaLog(serverName);
354 am.getRegionStates().logSplit(metaHRI);
355 }
356 }
357
358
359 boolean processed = true;
360 boolean shouldAssignMeta = false;
361 AssignmentManager.ServerHostRegion rsCarryingMetaRegion = am.isCarryingMeta(serverName);
362 switch (rsCarryingMetaRegion) {
363 case HOSTING_REGION:
364 LOG.info("Server " + serverName + " was carrying META. Trying to assign.");
365 am.regionOffline(HRegionInfo.FIRST_META_REGIONINFO);
366 shouldAssignMeta = true;
367 break;
368 case UNKNOWN:
369 if (!services.getMetaTableLocator().isLocationAvailable(services.getZooKeeper())) {
370
371
372
373 shouldAssignMeta = true;
374 break;
375 }
376
377 case NOT_HOSTING_REGION:
378 LOG.info("META has been assigned to otherwhere, skip assigning.");
379 break;
380 default:
381 throw new IOException("Unsupported action in MetaServerShutdownHandler");
382 }
383 if (shouldAssignMeta) {
384
385 verifyAndAssignMetaWithRetries(env);
386 if (this.shouldSplitWal && distributedLogReplay) {
387 int timeout = env.getMasterConfiguration().getInt(KEY_WAIT_ON_RIT, DEFAULT_WAIT_ON_RIT);
388 if (!waitOnRegionToClearRegionsInTransition(am, metaHRI, timeout)) {
389 processed = false;
390 } else {
391
392 mfs.splitMetaLog(serverName);
393 }
394 }
395 }
396 return processed;
397 }
398
399
400
401
402
403 private boolean waitOnRegionToClearRegionsInTransition(AssignmentManager am,
404 final HRegionInfo hri, final int timeout)
405 throws InterruptedIOException {
406 try {
407 if (!am.waitOnRegionToClearRegionsInTransition(hri, timeout)) {
408
409
410 LOG.warn("Region " + hri.getEncodedName() + " didn't complete assignment in time");
411 return false;
412 }
413 } catch (InterruptedException ie) {
414 throw new InterruptedIOException("Caught " + ie +
415 " during waitOnRegionToClearRegionsInTransition for " + hri);
416 }
417 return true;
418 }
419
420 private void prepareLogReplay(final MasterProcedureEnv env, final Set<HRegionInfo> regions)
421 throws IOException {
422 if (LOG.isDebugEnabled()) {
423 LOG.debug("Mark " + size(this.regionsOnCrashedServer) + " regions-in-recovery from " +
424 this.serverName);
425 }
426 MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();
427 AssignmentManager am = env.getMasterServices().getAssignmentManager();
428 mfs.prepareLogReplay(this.serverName, regions);
429 am.getRegionStates().logSplit(this.serverName);
430 }
431
432 private void splitLogs(final MasterProcedureEnv env) throws IOException {
433 if (LOG.isDebugEnabled()) {
434 LOG.debug("Splitting logs from " + serverName + "; region count=" +
435 size(this.regionsOnCrashedServer));
436 }
437 MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();
438 AssignmentManager am = env.getMasterServices().getAssignmentManager();
439
440 mfs.splitLog(this.serverName);
441 if (!carryingMeta) {
442 mfs.archiveMetaLog(this.serverName);
443 }
444 am.getRegionStates().logSplit(this.serverName);
445 }
446
447 static int size(final Collection<HRegionInfo> hris) {
448 return hris == null? 0: hris.size();
449 }
450
451
452
453
454
455
456
457 private List<HRegionInfo> calcRegionsToAssign(final MasterProcedureEnv env)
458 throws IOException {
459 AssignmentManager am = env.getMasterServices().getAssignmentManager();
460 List<HRegionInfo> regionsToAssignAggregator = new ArrayList<HRegionInfo>();
461 int replicaCount = env.getMasterConfiguration().getInt(HConstants.META_REPLICAS_NUM,
462 HConstants.DEFAULT_META_REPLICA_NUM);
463 for (int i = 1; i < replicaCount; i++) {
464 HRegionInfo metaHri =
465 RegionReplicaUtil.getRegionInfoForReplica(HRegionInfo.FIRST_META_REGIONINFO, i);
466 if (am.isCarryingMetaReplica(this.serverName, metaHri) ==
467 AssignmentManager.ServerHostRegion.HOSTING_REGION) {
468 if (LOG.isDebugEnabled()) {
469 LOG.debug("Reassigning meta replica" + metaHri + " that was on " + this.serverName);
470 }
471 regionsToAssignAggregator.add(metaHri);
472 }
473 }
474
475 List<HRegionInfo> regionsInTransition = am.cleanOutCrashedServerReferences(serverName);
476 if (LOG.isDebugEnabled()) {
477 LOG.debug("Reassigning " + size(this.regionsOnCrashedServer) +
478 " region(s) that " + (serverName == null? "null": serverName) +
479 " was carrying (and " + regionsInTransition.size() +
480 " regions(s) that were opening on this server)");
481 }
482 regionsToAssignAggregator.addAll(regionsInTransition);
483
484
485 if (this.regionsOnCrashedServer != null && !this.regionsOnCrashedServer.isEmpty()) {
486 RegionStates regionStates = am.getRegionStates();
487 for (HRegionInfo hri: this.regionsOnCrashedServer) {
488 if (regionsInTransition.contains(hri)) continue;
489 String encodedName = hri.getEncodedName();
490 Lock lock = am.acquireRegionLock(encodedName);
491 try {
492 RegionState rit = regionStates.getRegionTransitionState(hri);
493 if (processDeadRegion(hri, am)) {
494 ServerName addressFromAM = regionStates.getRegionServerOfRegion(hri);
495 if (addressFromAM != null && !addressFromAM.equals(this.serverName)) {
496
497
498
499 LOG.info("Skip assigning " + hri.getRegionNameAsString()
500 + " because opened on " + addressFromAM.getServerName());
501 continue;
502 }
503 if (rit != null) {
504 if (rit.getServerName() != null && !rit.isOnServer(this.serverName)) {
505
506 LOG.info("Skip assigning region in transition on other server" + rit);
507 continue;
508 }
509 LOG.info("Reassigning region " + rit + " and clearing zknode if exists");
510 try {
511
512 ZKAssign.deleteNodeFailSilent(env.getMasterServices().getZooKeeper(), hri);
513 } catch (KeeperException e) {
514
515
516 env.getMasterServices().abort("Unexpected error deleting RIT " + hri, e);
517 throw new IOException(e);
518 }
519 regionStates.updateRegionState(hri, RegionState.State.OFFLINE);
520 } else if (regionStates.isRegionInState(
521 hri, RegionState.State.SPLITTING_NEW, RegionState.State.MERGING_NEW)) {
522 regionStates.updateRegionState(hri, RegionState.State.OFFLINE);
523 }
524 regionsToAssignAggregator.add(hri);
525
526 } else if (rit != null) {
527 if ((rit.isPendingCloseOrClosing() || rit.isOffline())
528 && am.getTableStateManager().isTableState(hri.getTable(),
529 ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING) ||
530 am.getReplicasToClose().contains(hri)) {
531
532
533
534
535
536 regionStates.updateRegionState(hri, RegionState.State.OFFLINE);
537 am.deleteClosingOrClosedNode(hri, rit.getServerName());
538 am.offlineDisabledRegion(hri);
539 } else {
540 LOG.warn("THIS SHOULD NOT HAPPEN: unexpected region in transition "
541 + rit + " not to be assigned by SSH of server " + serverName);
542 }
543 }
544 } finally {
545 lock.unlock();
546 }
547 }
548 }
549 return regionsToAssignAggregator;
550 }
551
552 private boolean assign(final MasterProcedureEnv env, final List<HRegionInfo> hris)
553 throws InterruptedIOException {
554 MasterServices masterServices = env.getMasterServices();
555 AssignmentManager am = masterServices.getAssignmentManager();
556
557 boolean retainAssignment =
558 (masterServices.getConfiguration().getBoolean("hbase.master.retain.assignment", true) &&
559 masterServices.getServerManager().isServerWithSameHostnamePortOnline(serverName)) ?
560 true : false;
561 try {
562 if (retainAssignment) {
563 Map<HRegionInfo, ServerName> hriServerMap =
564 new HashMap<HRegionInfo, ServerName>(hris.size());
565 for (HRegionInfo hri: hris) {
566 hriServerMap.put(hri, serverName);
567 }
568 LOG.info("Best effort in SSH to retain assignment of " + hris.size()
569 + " regions from the dead server " + serverName);
570 am.assign(hriServerMap);
571 } else {
572 LOG.info("Using round robin in SSH to assign " + hris.size()
573 + " regions from the dead server " + serverName);
574 am.assign(hris);
575 }
576 } catch (InterruptedException ie) {
577 LOG.error("Caught " + ie + " during " + (retainAssignment ? "retaining" : "round-robin")
578 + " assignment");
579 throw (InterruptedIOException)new InterruptedIOException().initCause(ie);
580 } catch (IOException ioe) {
581 LOG.warn("Caught " + ioe + " during region assignment, will retry");
582 return false;
583 }
584 return true;
585 }
586
587 private boolean waitOnAssign(final MasterProcedureEnv env, final List<HRegionInfo> hris)
588 throws InterruptedIOException {
589 int timeout = env.getMasterConfiguration().getInt(KEY_WAIT_ON_RIT, DEFAULT_WAIT_ON_RIT);
590 for (HRegionInfo hri: hris) {
591
592 if (!waitOnRegionToClearRegionsInTransition(env.getMasterServices().getAssignmentManager(),
593 hri, timeout)) {
594 return false;
595 }
596 }
597 return true;
598 }
599
600 @Override
601 protected void rollbackState(MasterProcedureEnv env, ServerCrashState state)
602 throws IOException {
603
604 throw new UnsupportedOperationException("unhandled state=" + state);
605 }
606
607 @Override
608 protected ServerCrashState getState(int stateId) {
609 return ServerCrashState.valueOf(stateId);
610 }
611
612 @Override
613 protected int getStateId(ServerCrashState state) {
614 return state.getNumber();
615 }
616
617 @Override
618 protected ServerCrashState getInitialState() {
619 return ServerCrashState.SERVER_CRASH_START;
620 }
621
622 @Override
623 protected boolean abort(MasterProcedureEnv env) {
624
625 return false;
626 }
627
628 @Override
629 protected boolean acquireLock(final MasterProcedureEnv env) {
630 if (env.waitServerCrashProcessingEnabled(this)) return false;
631 return env.getProcedureQueue().tryAcquireServerExclusiveLock(this, getServerName());
632 }
633
634 @Override
635 protected void releaseLock(final MasterProcedureEnv env) {
636 env.getProcedureQueue().releaseServerExclusiveLock(this, getServerName());
637 }
638
639 @Override
640 public void toStringClassDetails(StringBuilder sb) {
641 sb.append(getClass().getSimpleName());
642 sb.append(" serverName=");
643 sb.append(this.serverName);
644 sb.append(", shouldSplitWal=");
645 sb.append(shouldSplitWal);
646 sb.append(", carryingMeta=");
647 sb.append(carryingMeta);
648 }
649
650 @Override
651 public void serializeStateData(final OutputStream stream) throws IOException {
652 super.serializeStateData(stream);
653
654 MasterProcedureProtos.ServerCrashStateData.Builder state =
655 MasterProcedureProtos.ServerCrashStateData.newBuilder().
656 setServerName(ProtobufUtil.toServerName(this.serverName)).
657 setDistributedLogReplay(this.distributedLogReplay).
658 setCarryingMeta(this.carryingMeta).
659 setShouldSplitWal(this.shouldSplitWal);
660 if (this.regionsOnCrashedServer != null && !this.regionsOnCrashedServer.isEmpty()) {
661 for (HRegionInfo hri: this.regionsOnCrashedServer) {
662 state.addRegionsOnCrashedServer(HRegionInfo.convert(hri));
663 }
664 }
665 if (this.regionsAssigned != null && !this.regionsAssigned.isEmpty()) {
666 for (HRegionInfo hri: this.regionsAssigned) {
667 state.addRegionsAssigned(HRegionInfo.convert(hri));
668 }
669 }
670 state.build().writeDelimitedTo(stream);
671 }
672
673 @Override
674 public void deserializeStateData(final InputStream stream) throws IOException {
675 super.deserializeStateData(stream);
676
677 MasterProcedureProtos.ServerCrashStateData state =
678 MasterProcedureProtos.ServerCrashStateData.parseDelimitedFrom(stream);
679 this.serverName = ProtobufUtil.toServerName(state.getServerName());
680 this.distributedLogReplay = state.hasDistributedLogReplay()?
681 state.getDistributedLogReplay(): false;
682 this.carryingMeta = state.hasCarryingMeta()? state.getCarryingMeta(): false;
683
684 this.shouldSplitWal = state.getShouldSplitWal();
685 int size = state.getRegionsOnCrashedServerCount();
686 if (size > 0) {
687 this.regionsOnCrashedServer = new HashSet<HRegionInfo>(size);
688 for (RegionInfo ri: state.getRegionsOnCrashedServerList()) {
689 this.regionsOnCrashedServer.add(HRegionInfo.convert(ri));
690 }
691 }
692 size = state.getRegionsAssignedCount();
693 if (size > 0) {
694 this.regionsAssigned = new ArrayList<HRegionInfo>(size);
695 for (RegionInfo ri: state.getRegionsOnCrashedServerList()) {
696 this.regionsAssigned.add(HRegionInfo.convert(ri));
697 }
698 }
699 }
700
701
702
703
704
705
706
707
708
709 private static boolean processDeadRegion(HRegionInfo hri, AssignmentManager assignmentManager)
710 throws IOException {
711 boolean tablePresent = assignmentManager.getTableStateManager().isTablePresent(hri.getTable());
712 if (!tablePresent) {
713 LOG.info("The table " + hri.getTable() + " was deleted. Hence not proceeding.");
714 return false;
715 }
716
717 boolean disabled = assignmentManager.getTableStateManager().isTableState(hri.getTable(),
718 ZooKeeperProtos.Table.State.DISABLED);
719 if (disabled){
720 LOG.info("The table " + hri.getTable() + " was disabled. Hence not proceeding.");
721 return false;
722 }
723 if (hri.isOffline() && hri.isSplit()) {
724
725
726
727 return false;
728 }
729 boolean disabling = assignmentManager.getTableStateManager().isTableState(hri.getTable(),
730 ZooKeeperProtos.Table.State.DISABLING);
731 if (disabling) {
732 LOG.info("The table " + hri.getTable() + " is disabled. Hence not assigning region" +
733 hri.getEncodedName());
734 return false;
735 }
736 return true;
737 }
738
739
740
741
742
743 private void verifyAndAssignMetaWithRetries(final MasterProcedureEnv env) throws IOException {
744 MasterServices services = env.getMasterServices();
745 int iTimes = services.getConfiguration().getInt(KEY_RETRIES_ON_META, DEFAULT_RETRIES_ON_META);
746
747 long waitTime =
748 services.getConfiguration().getLong(KEY_SHORT_WAIT_ON_META, DEFAULT_SHORT_WAIT_ON_META);
749 int iFlag = 0;
750 while (true) {
751 try {
752 verifyAndAssignMeta(env);
753 break;
754 } catch (KeeperException e) {
755 services.abort("In server shutdown processing, assigning meta", e);
756 throw new IOException("Aborting", e);
757 } catch (Exception e) {
758 if (iFlag >= iTimes) {
759 services.abort("verifyAndAssignMeta failed after" + iTimes + " retries, aborting", e);
760 throw new IOException("Aborting", e);
761 }
762 try {
763 Thread.sleep(waitTime);
764 } catch (InterruptedException e1) {
765 LOG.warn("Interrupted when is the thread sleep", e1);
766 Thread.currentThread().interrupt();
767 throw (InterruptedIOException)new InterruptedIOException().initCause(e1);
768 }
769 iFlag++;
770 }
771 }
772 }
773
774
775
776
777
778
779
780 private void verifyAndAssignMeta(final MasterProcedureEnv env)
781 throws InterruptedException, IOException, KeeperException {
782 MasterServices services = env.getMasterServices();
783 if (!isMetaAssignedQuickTest(env)) {
784 services.getAssignmentManager().assignMeta(HRegionInfo.FIRST_META_REGIONINFO);
785 } else if (serverName.equals(services.getMetaTableLocator().
786 getMetaRegionLocation(services.getZooKeeper()))) {
787
788
789 services.getAssignmentManager().assignMeta(HRegionInfo.FIRST_META_REGIONINFO);
790 } else {
791 LOG.info("Skip assigning hbase:meta because it is online at "
792 + services.getMetaTableLocator().getMetaRegionLocation(services.getZooKeeper()));
793 }
794 }
795
796
797
798
799
800
801
802 private boolean isMetaAssignedQuickTest(final MasterProcedureEnv env)
803 throws InterruptedException, IOException {
804 ZooKeeperWatcher zkw = env.getMasterServices().getZooKeeper();
805 MetaTableLocator mtl = env.getMasterServices().getMetaTableLocator();
806 boolean metaAssigned = false;
807
808 if (mtl.isLocationAvailable(zkw)) {
809 ClusterConnection connection = env.getMasterServices().getConnection();
810
811 long timeout =
812 env.getMasterConfiguration().getLong(KEY_SHORT_WAIT_ON_META, DEFAULT_SHORT_WAIT_ON_META);
813 if (mtl.verifyMetaRegionLocation(connection, zkw, timeout)) {
814 metaAssigned = true;
815 }
816 }
817 return metaAssigned;
818 }
819
820 @Override
821 public ServerName getServerName() {
822 return this.serverName;
823 }
824
825 @Override
826 public boolean hasMetaTableRegion() {
827 return this.carryingMeta;
828 }
829
830 @Override
831 public ServerOperationType getServerOperationType() {
832 return ServerOperationType.CRASH_HANDLER;
833 }
834
835
836
837
838
839
840
841
842 @Override
843 protected boolean isYieldBeforeExecuteFromState(MasterProcedureEnv env, ServerCrashState state) {
844 return true;
845 }
846
847 @Override
848 protected boolean shouldWaitClientAck(MasterProcedureEnv env) {
849
850
851 return false;
852 }
853 }