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; 021 022import org.apache.hadoop.hbase.MetaTableAccessor; 023import org.apache.hadoop.hbase.TableName; 024import org.apache.hadoop.hbase.client.RegionInfo; 025import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineTableProcedure; 026import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 027import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 028import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException; 029import org.apache.hadoop.hbase.procedure2.ProcedureYieldException; 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; 035import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.GCMergedRegionsState; 036 037/** 038 * GC regions that have been Merged. 039 * Caller determines if it is GC time. This Procedure does not check. 040 * <p>This is a Table Procedure. We take a read lock on the Table. 041 * We do NOT keep a lock for the life of this procedure. The subprocedures 042 * take locks on the Regions they are purging. 043 * @deprecated 2.3.0 Use {@link GCMultipleMergedRegionsProcedure}. 044 */ 045@InterfaceAudience.Private 046@Deprecated 047public class GCMergedRegionsProcedure 048extends AbstractStateMachineTableProcedure<GCMergedRegionsState> { 049 private static final Logger LOG = LoggerFactory.getLogger(GCMergedRegionsProcedure.class); 050 private RegionInfo father; 051 private RegionInfo mother; 052 private RegionInfo mergedChild; 053 054 public GCMergedRegionsProcedure(final MasterProcedureEnv env, 055 final RegionInfo mergedChild, 056 final RegionInfo father, 057 final RegionInfo mother) { 058 super(env); 059 this.father = father; 060 this.mother = mother; 061 this.mergedChild = mergedChild; 062 } 063 064 public GCMergedRegionsProcedure() { 065 // Required by the Procedure framework to create the procedure on replay 066 super(); 067 } 068 069 @Override 070 public TableOperationType getTableOperationType() { 071 return TableOperationType.MERGED_REGIONS_GC; 072 } 073 074 @Override 075 protected Flow executeFromState(MasterProcedureEnv env, GCMergedRegionsState state) 076 throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { 077 if (LOG.isTraceEnabled()) { 078 LOG.trace(this + " execute state=" + state); 079 } 080 try { 081 switch (state) { 082 case GC_MERGED_REGIONS_PREPARE: 083 // Nothing to do to prepare. 084 setNextState(GCMergedRegionsState.GC_MERGED_REGIONS_PURGE); 085 break; 086 case GC_MERGED_REGIONS_PURGE: 087 addChildProcedure(createGCRegionProcedures(env)); 088 setNextState(GCMergedRegionsState.GC_REGION_EDIT_METADATA); 089 break; 090 case GC_REGION_EDIT_METADATA: 091 MetaTableAccessor.deleteMergeQualifiers(env.getMasterServices().getConnection(), mergedChild); 092 return Flow.NO_MORE_STATE; 093 default: 094 throw new UnsupportedOperationException(this + " unhandled state=" + state); 095 } 096 } catch (IOException ioe) { 097 // TODO: This is going to spew log? 098 LOG.warn("Error trying to GC merged regions " + this.father.getShortNameToLog() + 099 " & " + this.mother.getShortNameToLog() + "; retrying...", ioe); 100 } 101 return Flow.HAS_MORE_STATE; 102 } 103 104 private GCRegionProcedure[] createGCRegionProcedures(final MasterProcedureEnv env) { 105 GCRegionProcedure [] procs = new GCRegionProcedure[2]; 106 int index = 0; 107 for (RegionInfo hri: new RegionInfo [] {this.father, this.mother}) { 108 GCRegionProcedure proc = new GCRegionProcedure(env, hri); 109 proc.setOwner(env.getRequestUser().getShortName()); 110 procs[index++] = proc; 111 } 112 return procs; 113 } 114 115 @Override 116 protected void rollbackState(MasterProcedureEnv env, GCMergedRegionsState state) 117 throws IOException, InterruptedException { 118 // no-op 119 } 120 121 @Override 122 protected GCMergedRegionsState getState(int stateId) { 123 return GCMergedRegionsState.forNumber(stateId); 124 } 125 126 @Override 127 protected int getStateId(GCMergedRegionsState state) { 128 return state.getNumber(); 129 } 130 131 @Override 132 protected GCMergedRegionsState getInitialState() { 133 return GCMergedRegionsState.GC_MERGED_REGIONS_PREPARE; 134 } 135 136 @Override 137 protected void serializeStateData(ProcedureStateSerializer serializer) 138 throws IOException { 139 super.serializeStateData(serializer); 140 final MasterProcedureProtos.GCMergedRegionsStateData.Builder msg = 141 MasterProcedureProtos.GCMergedRegionsStateData.newBuilder(). 142 setParentA(ProtobufUtil.toRegionInfo(this.father)). 143 setParentB(ProtobufUtil.toRegionInfo(this.mother)). 144 setMergedChild(ProtobufUtil.toRegionInfo(this.mergedChild)); 145 serializer.serialize(msg.build()); 146 } 147 148 @Override 149 protected void deserializeStateData(ProcedureStateSerializer serializer) 150 throws IOException { 151 super.deserializeStateData(serializer); 152 final MasterProcedureProtos.GCMergedRegionsStateData msg = 153 serializer.deserialize(MasterProcedureProtos.GCMergedRegionsStateData.class); 154 this.father = ProtobufUtil.toRegionInfo(msg.getParentA()); 155 this.mother = ProtobufUtil.toRegionInfo(msg.getParentB()); 156 this.mergedChild = ProtobufUtil.toRegionInfo(msg.getMergedChild()); 157 } 158 159 @Override 160 public void toStringClassDetails(StringBuilder sb) { 161 sb.append(getClass().getSimpleName()); 162 sb.append(" child="); 163 sb.append(this.mergedChild.getShortNameToLog()); 164 sb.append(", father="); 165 sb.append(this.father.getShortNameToLog()); 166 sb.append(", mother="); 167 sb.append(this.mother.getShortNameToLog()); 168 } 169 170 @Override 171 public TableName getTableName() { 172 return this.mergedChild.getTable(); 173 } 174}