001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.master.procedure; 020 021import java.io.IOException; 022import java.util.Optional; 023 024import org.apache.hadoop.fs.Path; 025import org.apache.hadoop.hbase.DoNotRetryIOException; 026import org.apache.hadoop.hbase.ServerName; 027import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 028import org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher; 029import org.apache.hadoop.hbase.regionserver.SplitWALCallable; 030import org.apache.hadoop.hbase.wal.AbstractFSWALProvider; 031import org.apache.yetus.audience.InterfaceAudience; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 036import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos; 037/** 038 * A remote procedure which is used to send split WAL request to region server. 039 * it will return null if the task is succeed or return a DoNotRetryIOException 040 * {@link SplitWALProcedure} will help handle the situation that encounter 041 * DoNotRetryIOException. Otherwise it will retry until succeed. 042 */ 043@InterfaceAudience.Private 044public class SplitWALRemoteProcedure extends ServerRemoteProcedure 045 implements ServerProcedureInterface { 046 private static final Logger LOG = LoggerFactory.getLogger(SplitWALRemoteProcedure.class); 047 private String walPath; 048 private ServerName crashedServer; 049 050 public SplitWALRemoteProcedure() { 051 } 052 053 public SplitWALRemoteProcedure(ServerName worker, ServerName crashedServer, String wal) { 054 this.targetServer = worker; 055 this.crashedServer = crashedServer; 056 this.walPath = wal; 057 } 058 059 @Override 060 protected void rollback(MasterProcedureEnv env) throws IOException, InterruptedException { 061 throw new UnsupportedOperationException(); 062 } 063 064 @Override 065 protected boolean abort(MasterProcedureEnv env) { 066 return false; 067 } 068 069 @Override 070 protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { 071 MasterProcedureProtos.SplitWALRemoteData.Builder builder = 072 MasterProcedureProtos.SplitWALRemoteData.newBuilder(); 073 builder.setWalPath(walPath).setWorker(ProtobufUtil.toServerName(targetServer)) 074 .setCrashedServer(ProtobufUtil.toServerName(crashedServer)); 075 serializer.serialize(builder.build()); 076 } 077 078 @Override 079 protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException { 080 MasterProcedureProtos.SplitWALRemoteData data = 081 serializer.deserialize(MasterProcedureProtos.SplitWALRemoteData.class); 082 walPath = data.getWalPath(); 083 targetServer = ProtobufUtil.toServerName(data.getWorker()); 084 crashedServer = ProtobufUtil.toServerName(data.getCrashedServer()); 085 } 086 087 @Override 088 public Optional<RemoteProcedureDispatcher.RemoteOperation> remoteCallBuild(MasterProcedureEnv env, 089 ServerName serverName) { 090 return Optional 091 .of(new RSProcedureDispatcher.ServerOperation(this, getProcId(), SplitWALCallable.class, 092 MasterProcedureProtos.SplitWALParameter.newBuilder().setWalPath(walPath).build() 093 .toByteArray())); 094 } 095 096 @Override 097 protected void complete(MasterProcedureEnv env, Throwable error) { 098 if (error == null) { 099 LOG.info("split WAL {} on {} succeeded", walPath, targetServer); 100 try { 101 env.getMasterServices().getSplitWALManager().deleteSplitWAL(walPath); 102 } catch (IOException e) { 103 LOG.warn("remove WAL {} failed, ignore...", walPath, e); 104 } 105 succ = true; 106 } else { 107 if (error instanceof DoNotRetryIOException) { 108 LOG.warn("WAL split task of {} send to a wrong server {}, will retry on another server", 109 walPath, targetServer, error); 110 succ = true; 111 } else { 112 LOG.warn("split WAL {} failed, retry...", walPath, error); 113 succ = false; 114 } 115 } 116 } 117 118 public String getWAL() { 119 return this.walPath; 120 } 121 122 @Override 123 public ServerName getServerName() { 124 // return the crashed server is to use the queue of root ServerCrashProcedure 125 return this.crashedServer; 126 } 127 128 @Override 129 public boolean hasMetaTableRegion() { 130 return AbstractFSWALProvider.isMetaFile(new Path(walPath)); 131 } 132 133 @Override 134 public ServerOperationType getServerOperationType() { 135 return ServerOperationType.SPLIT_WAL_REMOTE; 136 } 137}