View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with this
6    * work for additional information regarding copyright ownership. The ASF
7    * licenses this file to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16   * License for the specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.master.handler;
20  
21  import java.io.IOException;
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.hbase.Server;
27  import org.apache.hadoop.hbase.ServerName;
28  import org.apache.hadoop.hbase.executor.EventHandler;
29  import org.apache.hadoop.hbase.executor.EventType;
30  import org.apache.hadoop.hbase.master.DeadServer;
31  import org.apache.hadoop.hbase.master.MasterServices;
32  
33  /**
34   * Handle logReplay work from SSH. Having a separate handler is not to block SSH in re-assigning
35   * regions from dead servers. Otherwise, available SSH handlers could be blocked by logReplay work
36   * (from {@link org.apache.hadoop.hbase.master.MasterFileSystem#splitLog(ServerName)}). 
37   * During logReplay, if a receiving RS(say A) fails again, regions on A won't be able to be 
38   * assigned to another live RS which causes the log replay unable to complete because WAL edits 
39   * replay depends on receiving RS to be live
40   */
41  @InterfaceAudience.Private
42  public class LogReplayHandler extends EventHandler {
43    private static final Log LOG = LogFactory.getLog(LogReplayHandler.class);
44    private final ServerName serverName;
45    protected final Server master;
46    protected final MasterServices services;
47    protected final DeadServer deadServers;
48  
49    public LogReplayHandler(final Server server, final MasterServices services,
50        final DeadServer deadServers, final ServerName serverName) {
51      super(server, EventType.M_LOG_REPLAY);
52      this.master = server;
53      this.services = services;
54      this.deadServers = deadServers;
55      this.serverName = serverName;
56      this.deadServers.add(serverName);
57    }
58  
59    @Override
60    public String toString() {
61      String name = serverName.toString();
62      return getClass().getSimpleName() + "-" + name + "-" + getSeqid();
63    }
64  
65    @Override
66    public void process() throws IOException {
67      try {
68        if (this.master != null && this.master.isStopped()) {
69          // we're exiting ...
70          return;
71        }
72        this.services.getMasterFileSystem().splitLog(serverName);
73      } catch (Exception ex) {
74        if (ex instanceof IOException) {
75          // resubmit log replay work when failed
76          this.services.getExecutorService().submit((LogReplayHandler) this);
77          this.deadServers.add(serverName);
78          throw new IOException("failed log replay for " + serverName + ", will retry", ex);
79        } else {
80          throw new IOException(ex);
81        }
82      } finally {
83        this.deadServers.finish(serverName);
84      }
85      // logReplay is the last step of SSH so log a line to indicate that
86      LOG.info("Finished processing shutdown of " + serverName);
87    }
88  }