View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.master.handler;
20  
21  import java.io.InterruptedIOException;
22  import java.io.IOException;
23  import java.util.List;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.classification.InterfaceAudience;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.fs.Path;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.HRegionInfo;
32  import org.apache.hadoop.hbase.Server;
33  import org.apache.hadoop.hbase.backup.HFileArchiver;
34  import org.apache.hadoop.hbase.catalog.MetaEditor;
35  import org.apache.hadoop.hbase.executor.EventType;
36  import org.apache.hadoop.hbase.master.AssignmentManager;
37  import org.apache.hadoop.hbase.master.HMaster;
38  import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
39  import org.apache.hadoop.hbase.master.MasterFileSystem;
40  import org.apache.hadoop.hbase.master.MasterServices;
41  import org.apache.hadoop.hbase.master.RegionStates;
42  import org.apache.hadoop.hbase.master.RegionState.State;
43  import org.apache.zookeeper.KeeperException;
44  
45  @InterfaceAudience.Private
46  public class DeleteTableHandler extends TableEventHandler {
47    private static final Log LOG = LogFactory.getLog(DeleteTableHandler.class);
48  
49    public DeleteTableHandler(TableName tableName, Server server,
50        final MasterServices masterServices) {
51      super(EventType.C_M_DELETE_TABLE, tableName, server, masterServices);
52    }
53  
54    @Override
55    protected void prepareWithTableLock() throws IOException {
56      // The next call fails if no such table.
57      getTableDescriptor();
58    }
59  
60    @Override
61    protected void handleTableOperation(List<HRegionInfo> regions)
62    throws IOException, KeeperException {
63      MasterCoprocessorHost cpHost = ((HMaster) this.server)
64          .getCoprocessorHost();
65      if (cpHost != null) {
66        cpHost.preDeleteTableHandler(this.tableName);
67      }
68  
69      // 1. Wait because of region in transition
70      AssignmentManager am = this.masterServices.getAssignmentManager();
71      RegionStates states = am.getRegionStates();
72      long waitTime = server.getConfiguration().
73        getLong("hbase.master.wait.on.region", 5 * 60 * 1000);
74      for (HRegionInfo region : regions) {
75        long done = System.currentTimeMillis() + waitTime;
76        while (System.currentTimeMillis() < done) {
77          if (states.isRegionInState(region, State.FAILED_OPEN)) {
78            am.regionOffline(region);
79          }
80          if (!states.isRegionInTransition(region)) break;
81          try {
82            Thread.sleep(waitingTimeForEvents);
83          } catch (InterruptedException e) {
84            LOG.warn("Interrupted while sleeping");
85            throw (InterruptedIOException)new InterruptedIOException().initCause(e);
86          }
87          LOG.debug("Waiting on region to clear regions in transition; "
88            + am.getRegionStates().getRegionTransitionState(region));
89        }
90        if (states.isRegionInTransition(region)) {
91          throw new IOException("Waited hbase.master.wait.on.region (" +
92            waitTime + "ms) for region to leave region " +
93            region.getRegionNameAsString() + " in transitions");
94        }
95      }
96  
97      // 2. Remove regions from META
98      LOG.debug("Deleting regions from META");
99      MetaEditor.deleteRegions(this.server.getCatalogTracker(), regions);
100 
101     // 3. Move the table in /hbase/.tmp
102     MasterFileSystem mfs = this.masterServices.getMasterFileSystem();
103     Path tempTableDir = mfs.moveTableToTemp(tableName);
104 
105     try {
106       // 4. Delete regions from FS (temp directory)
107       FileSystem fs = mfs.getFileSystem();
108       for (HRegionInfo hri: regions) {
109         LOG.debug("Archiving region " + hri.getRegionNameAsString() + " from FS");
110         HFileArchiver.archiveRegion(fs, mfs.getRootDir(),
111             tempTableDir, new Path(tempTableDir, hri.getEncodedName()));
112       }
113 
114       // 5. Delete table from FS (temp directory)
115       if (!fs.delete(tempTableDir, true)) {
116         LOG.error("Couldn't delete " + tempTableDir);
117       }
118 
119       LOG.debug("Table '" + tableName + "' archived!");
120     } finally {
121       // 6. Update table descriptor cache
122       LOG.debug("Removing '" + tableName + "' descriptor.");
123       this.masterServices.getTableDescriptors().remove(tableName);
124 
125       // 7. Clean up regions of the table in RegionStates.
126       LOG.debug("Removing '" + tableName + "' from region states.");
127       states.tableDeleted(tableName);
128 
129       // 8. If entry for this table in zk, and up in AssignmentManager, remove it.
130       LOG.debug("Marking '" + tableName + "' as deleted.");
131       am.getZKTable().setDeletedTable(tableName);
132     }
133 
134     if (cpHost != null) {
135       cpHost.postDeleteTableHandler(this.tableName);
136     }
137   }
138 
139   @Override
140   protected void releaseTableLock() {
141     super.releaseTableLock();
142     try {
143       masterServices.getTableLockManager().tableDeleted(tableName);
144     } catch (IOException ex) {
145       LOG.warn("Received exception from TableLockManager.tableDeleted:", ex); //not critical
146     }
147   }
148 
149   @Override
150   public String toString() {
151     String name = "UnknownServerName";
152     if(server != null && server.getServerName() != null) {
153       name = server.getServerName().toString();
154     }
155     return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" + tableName;
156   }
157 }