001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master.assignment; 019 020import java.io.IOException; 021import org.apache.hadoop.hbase.TableName; 022import org.apache.hadoop.hbase.client.RegionInfo; 023import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineTableProcedure; 024import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 025import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 026import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException; 027import org.apache.hadoop.hbase.procedure2.ProcedureYieldException; 028import org.apache.yetus.audience.InterfaceAudience; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 033import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos; 034import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.GCMergedRegionsState; 035 036/** 037 * GC regions that have been Merged. Caller determines if it is GC time. This Procedure does not 038 * check. 039 * <p> 040 * This is a Table Procedure. We take a read lock on the Table. We do NOT keep a lock for the life 041 * of this procedure. The subprocedures take locks on the Regions they are purging. 042 * @deprecated 2.3.0 Use {@link GCMultipleMergedRegionsProcedure}. 043 */ 044@InterfaceAudience.Private 045@Deprecated 046public class GCMergedRegionsProcedure 047 extends AbstractStateMachineTableProcedure<GCMergedRegionsState> { 048 private static final Logger LOG = LoggerFactory.getLogger(GCMergedRegionsProcedure.class); 049 private RegionInfo father; 050 private RegionInfo mother; 051 private RegionInfo mergedChild; 052 053 public GCMergedRegionsProcedure(final MasterProcedureEnv env, final RegionInfo mergedChild, 054 final RegionInfo father, final RegionInfo mother) { 055 super(env); 056 this.father = father; 057 this.mother = mother; 058 this.mergedChild = mergedChild; 059 } 060 061 public GCMergedRegionsProcedure() { 062 // Required by the Procedure framework to create the procedure on replay 063 super(); 064 } 065 066 @Override 067 public TableOperationType getTableOperationType() { 068 return TableOperationType.MERGED_REGIONS_GC; 069 } 070 071 @Override 072 protected Flow executeFromState(MasterProcedureEnv env, GCMergedRegionsState state) 073 throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { 074 if (LOG.isTraceEnabled()) { 075 LOG.trace(this + " execute state=" + state); 076 } 077 try { 078 switch (state) { 079 case GC_MERGED_REGIONS_PREPARE: 080 // Nothing to do to prepare. 081 setNextState(GCMergedRegionsState.GC_MERGED_REGIONS_PURGE); 082 break; 083 case GC_MERGED_REGIONS_PURGE: 084 addChildProcedure(createGCRegionProcedures(env)); 085 setNextState(GCMergedRegionsState.GC_REGION_EDIT_METADATA); 086 break; 087 case GC_REGION_EDIT_METADATA: 088 env.getAssignmentManager().getRegionStateStore().deleteMergeQualifiers(mergedChild); 089 return Flow.NO_MORE_STATE; 090 default: 091 throw new UnsupportedOperationException(this + " unhandled state=" + state); 092 } 093 } catch (IOException ioe) { 094 // TODO: This is going to spew log? 095 LOG.warn("Error trying to GC merged regions " + this.father.getShortNameToLog() + " & " 096 + this.mother.getShortNameToLog() + "; retrying...", ioe); 097 } 098 return Flow.HAS_MORE_STATE; 099 } 100 101 private GCRegionProcedure[] createGCRegionProcedures(final MasterProcedureEnv env) { 102 GCRegionProcedure[] procs = new GCRegionProcedure[2]; 103 int index = 0; 104 for (RegionInfo hri : new RegionInfo[] { this.father, this.mother }) { 105 GCRegionProcedure proc = new GCRegionProcedure(env, hri); 106 proc.setOwner(env.getRequestUser().getShortName()); 107 procs[index++] = proc; 108 } 109 return procs; 110 } 111 112 @Override 113 protected void rollbackState(MasterProcedureEnv env, GCMergedRegionsState state) 114 throws IOException, InterruptedException { 115 // no-op 116 } 117 118 @Override 119 protected GCMergedRegionsState getState(int stateId) { 120 return GCMergedRegionsState.forNumber(stateId); 121 } 122 123 @Override 124 protected int getStateId(GCMergedRegionsState state) { 125 return state.getNumber(); 126 } 127 128 @Override 129 protected GCMergedRegionsState getInitialState() { 130 return GCMergedRegionsState.GC_MERGED_REGIONS_PREPARE; 131 } 132 133 @Override 134 protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { 135 super.serializeStateData(serializer); 136 final MasterProcedureProtos.GCMergedRegionsStateData.Builder msg = 137 MasterProcedureProtos.GCMergedRegionsStateData.newBuilder() 138 .setParentA(ProtobufUtil.toRegionInfo(this.father)) 139 .setParentB(ProtobufUtil.toRegionInfo(this.mother)) 140 .setMergedChild(ProtobufUtil.toRegionInfo(this.mergedChild)); 141 serializer.serialize(msg.build()); 142 } 143 144 @Override 145 protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException { 146 super.deserializeStateData(serializer); 147 final MasterProcedureProtos.GCMergedRegionsStateData msg = 148 serializer.deserialize(MasterProcedureProtos.GCMergedRegionsStateData.class); 149 this.father = ProtobufUtil.toRegionInfo(msg.getParentA()); 150 this.mother = ProtobufUtil.toRegionInfo(msg.getParentB()); 151 this.mergedChild = ProtobufUtil.toRegionInfo(msg.getMergedChild()); 152 } 153 154 @Override 155 public void toStringClassDetails(StringBuilder sb) { 156 sb.append(getClass().getSimpleName()); 157 sb.append(" child="); 158 sb.append(this.mergedChild.getShortNameToLog()); 159 sb.append(", father="); 160 sb.append(this.father.getShortNameToLog()); 161 sb.append(", mother="); 162 sb.append(this.mother.getShortNameToLog()); 163 } 164 165 @Override 166 public TableName getTableName() { 167 return this.mergedChild.getTable(); 168 } 169}