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.procedure; 019 020import java.io.IOException; 021import java.util.Arrays; 022import java.util.concurrent.CountDownLatch; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.fs.FileSystem; 025import org.apache.hadoop.fs.Path; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.client.RegionInfoBuilder; 028import org.apache.hadoop.hbase.client.TableDescriptor; 029import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure; 030import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 031import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException; 032import org.apache.hadoop.hbase.procedure2.ProcedureUtil; 033import org.apache.hadoop.hbase.procedure2.ProcedureYieldException; 034import org.apache.hadoop.hbase.regionserver.HRegion; 035import org.apache.hadoop.hbase.util.CommonFSUtils; 036import org.apache.hadoop.hbase.util.FSTableDescriptors; 037import org.apache.hadoop.hbase.util.RetryCounter; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.InitMetaState; 043import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.InitMetaStateData; 044import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; 045 046/** 047 * This procedure is used to initialize meta table for a new hbase deploy. It will just schedule an 048 * {@link TransitRegionStateProcedure} to assign meta. 049 */ 050@InterfaceAudience.Private 051public class InitMetaProcedure extends AbstractStateMachineTableProcedure<InitMetaState> { 052 053 private static final Logger LOG = LoggerFactory.getLogger(InitMetaProcedure.class); 054 055 private CountDownLatch latch = new CountDownLatch(1); 056 057 private RetryCounter retryCounter; 058 059 @Override 060 public TableName getTableName() { 061 return TableName.META_TABLE_NAME; 062 } 063 064 @Override 065 public TableOperationType getTableOperationType() { 066 return TableOperationType.CREATE; 067 } 068 069 private static TableDescriptor writeFsLayout(Path rootDir, Configuration conf) throws IOException { 070 LOG.info("BOOTSTRAP: creating hbase:meta region"); 071 FileSystem fs = rootDir.getFileSystem(conf); 072 Path tableDir = CommonFSUtils.getTableDir(rootDir, TableName.META_TABLE_NAME); 073 if (fs.exists(tableDir) && !fs.delete(tableDir, true)) { 074 LOG.warn("Can not delete partial created meta table, continue..."); 075 } 076 // Bootstrapping, make sure blockcache is off. Else, one will be 077 // created here in bootstrap and it'll need to be cleaned up. Better to 078 // not make it in first place. Turn off block caching for bootstrap. 079 // Enable after. 080 TableDescriptor metaDescriptor = 081 FSTableDescriptors.tryUpdateAndGetMetaTableDescriptor(conf, fs, rootDir); 082 HRegion 083 .createHRegion(RegionInfoBuilder.FIRST_META_REGIONINFO, rootDir, conf, metaDescriptor, null) 084 .close(); 085 return metaDescriptor; 086 } 087 088 @Override 089 protected Flow executeFromState(MasterProcedureEnv env, InitMetaState state) 090 throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { 091 LOG.debug("Execute {}", this); 092 try { 093 switch (state) { 094 case INIT_META_WRITE_FS_LAYOUT: 095 Configuration conf = env.getMasterConfiguration(); 096 Path rootDir = CommonFSUtils.getRootDir(conf); 097 TableDescriptor td = writeFsLayout(rootDir, conf); 098 env.getMasterServices().getTableDescriptors().update(td, true); 099 setNextState(InitMetaState.INIT_META_ASSIGN_META); 100 return Flow.HAS_MORE_STATE; 101 case INIT_META_ASSIGN_META: 102 LOG.info("Going to assign meta"); 103 addChildProcedure(env.getAssignmentManager() 104 .createAssignProcedures(Arrays.asList(RegionInfoBuilder.FIRST_META_REGIONINFO))); 105 return Flow.NO_MORE_STATE; 106 default: 107 throw new UnsupportedOperationException("unhandled state=" + state); 108 } 109 } catch (IOException e) { 110 if (retryCounter == null) { 111 retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration()); 112 } 113 long backoff = retryCounter.getBackoffTimeAndIncrementAttempts(); 114 LOG.warn("Failed to init meta, suspend {}secs", backoff, e); 115 setTimeout(Math.toIntExact(backoff)); 116 setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT); 117 skipPersistence(); 118 throw new ProcedureSuspendedException(); 119 } 120 } 121 122 @Override 123 protected boolean waitInitialized(MasterProcedureEnv env) { 124 // we do not need to wait for master initialized, we are part of the initialization. 125 return false; 126 } 127 128 @Override 129 protected void rollbackState(MasterProcedureEnv env, InitMetaState state) 130 throws IOException, InterruptedException { 131 throw new UnsupportedOperationException(); 132 } 133 134 @Override 135 protected InitMetaState getState(int stateId) { 136 return InitMetaState.forNumber(stateId); 137 } 138 139 @Override 140 protected int getStateId(InitMetaState state) { 141 return state.getNumber(); 142 } 143 144 @Override 145 protected InitMetaState getInitialState() { 146 return InitMetaState.INIT_META_WRITE_FS_LAYOUT; 147 } 148 149 @Override 150 protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { 151 super.serializeStateData(serializer); 152 serializer.serialize(InitMetaStateData.getDefaultInstance()); 153 } 154 155 @Override 156 protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException { 157 super.deserializeStateData(serializer); 158 serializer.deserialize(InitMetaStateData.class); 159 } 160 161 @Override 162 protected void completionCleanup(MasterProcedureEnv env) { 163 latch.countDown(); 164 } 165 166 public void await() throws InterruptedException { 167 latch.await(); 168 } 169}