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; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.DoNotRetryIOException; 025import org.apache.hadoop.hbase.ServerName; 026import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 027import org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher; 028import org.apache.hadoop.hbase.regionserver.SplitWALCallable; 029import org.apache.hadoop.hbase.wal.AbstractFSWALProvider; 030import org.apache.yetus.audience.InterfaceAudience; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 034import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos; 035 036/** 037 * A remote procedure which is used to send split WAL request to region server. 038 * It will return null if the task succeeded or return a DoNotRetryIOException. 039 * {@link SplitWALProcedure} will help handle the situation that encounters 040 * DoNotRetryIOException. Otherwise it will retry until success. 041 */ 042@InterfaceAudience.Private 043public class SplitWALRemoteProcedure extends ServerRemoteProcedure 044 implements ServerProcedureInterface { 045 private static final Logger LOG = LoggerFactory.getLogger(SplitWALRemoteProcedure.class); 046 private String walPath; 047 private ServerName crashedServer; 048 049 public SplitWALRemoteProcedure() { 050 } 051 052 public SplitWALRemoteProcedure(ServerName worker, ServerName crashedServer, String wal) { 053 this.targetServer = worker; 054 this.crashedServer = crashedServer; 055 this.walPath = wal; 056 } 057 058 @Override 059 protected void rollback(MasterProcedureEnv env) throws IOException, InterruptedException { 060 throw new UnsupportedOperationException(); 061 } 062 063 @Override 064 protected boolean abort(MasterProcedureEnv env) { 065 return false; 066 } 067 068 @Override 069 protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { 070 MasterProcedureProtos.SplitWALRemoteData.Builder builder = 071 MasterProcedureProtos.SplitWALRemoteData.newBuilder(); 072 builder.setWalPath(walPath).setWorker(ProtobufUtil.toServerName(targetServer)) 073 .setCrashedServer(ProtobufUtil.toServerName(crashedServer)); 074 serializer.serialize(builder.build()); 075 } 076 077 @Override 078 protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException { 079 MasterProcedureProtos.SplitWALRemoteData data = 080 serializer.deserialize(MasterProcedureProtos.SplitWALRemoteData.class); 081 walPath = data.getWalPath(); 082 targetServer = ProtobufUtil.toServerName(data.getWorker()); 083 crashedServer = ProtobufUtil.toServerName(data.getCrashedServer()); 084 } 085 086 @Override 087 public Optional<RemoteProcedureDispatcher.RemoteOperation> remoteCallBuild(MasterProcedureEnv env, 088 ServerName serverName) { 089 return Optional 090 .of(new RSProcedureDispatcher.ServerOperation(this, getProcId(), SplitWALCallable.class, 091 MasterProcedureProtos.SplitWALParameter.newBuilder().setWalPath(walPath).build() 092 .toByteArray())); 093 } 094 095 @Override 096 protected void complete(MasterProcedureEnv env, Throwable error) { 097 if (error == null) { 098 try { 099 env.getMasterServices().getSplitWALManager().deleteSplitWAL(walPath); 100 } catch (IOException e) { 101 LOG.warn("Failed split of {}; ignore...", walPath, e); 102 } 103 succ = true; 104 } else { 105 if (error instanceof DoNotRetryIOException) { 106 LOG.warn("Sent {} to wrong server {}, try another", walPath, targetServer, error); 107 succ = true; 108 } else { 109 LOG.warn("Failed split of {}, retry...", walPath, error); 110 succ = false; 111 } 112 } 113 } 114 115 public String getWAL() { 116 return this.walPath; 117 } 118 119 @Override 120 public ServerName getServerName() { 121 // return the crashed server is to use the queue of root ServerCrashProcedure 122 return this.crashedServer; 123 } 124 125 @Override 126 public boolean hasMetaTableRegion() { 127 return AbstractFSWALProvider.isMetaFile(new Path(walPath)); 128 } 129 130 @Override 131 public ServerOperationType getServerOperationType() { 132 return ServerOperationType.SPLIT_WAL_REMOTE; 133 } 134 135 @Override protected void toStringClassDetails(StringBuilder builder) { 136 builder.append(getProcName()); 137 if (this.targetServer != null) { 138 builder.append(", worker="); 139 builder.append(this.targetServer); 140 } 141 } 142 143 @Override public String getProcName() { 144 return getClass().getSimpleName() + " " + SplitWALProcedure.getWALNameFromStrPath(getWAL()); 145 } 146}