1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.procedure;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.NavigableMap;
26 import java.util.TreeMap;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HRegionLocation;
32 import org.apache.hadoop.hbase.MetaTableAccessor;
33 import org.apache.hadoop.hbase.ServerName;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.TableNotDisabledException;
36 import org.apache.hadoop.hbase.TableNotFoundException;
37 import org.apache.hadoop.hbase.classification.InterfaceAudience;
38 import org.apache.hadoop.hbase.client.Connection;
39 import org.apache.hadoop.hbase.client.RegionLocator;
40 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
41 import org.apache.hadoop.hbase.master.AssignmentManager;
42 import org.apache.hadoop.hbase.master.BulkReOpen;
43 import org.apache.hadoop.hbase.master.MasterFileSystem;
44 import org.apache.hadoop.hbase.util.Bytes;
45
46 import com.google.common.collect.Lists;
47 import com.google.common.collect.Maps;
48
49
50
51
52 @InterfaceAudience.Private
53 public final class MasterDDLOperationHelper {
54 private static final Log LOG = LogFactory.getLog(MasterDDLOperationHelper.class);
55
56 private MasterDDLOperationHelper() {}
57
58
59
60
61 public static boolean isOnlineSchemaChangeAllowed(final MasterProcedureEnv env) {
62 return env.getMasterServices().getConfiguration()
63 .getBoolean("hbase.online.schema.update.enable", false);
64 }
65
66
67
68
69
70
71
72 public static void checkTableModifiable(final MasterProcedureEnv env, final TableName tableName)
73 throws IOException {
74
75 if (!MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) {
76 throw new TableNotFoundException(tableName);
77 }
78
79
80 if (!env.getMasterServices().getAssignmentManager().getTableStateManager()
81 .isTableState(tableName, ZooKeeperProtos.Table.State.DISABLED)
82 && !MasterDDLOperationHelper.isOnlineSchemaChangeAllowed(env)) {
83 throw new TableNotDisabledException(tableName);
84 }
85 }
86
87
88
89
90 public static void deleteColumnFamilyFromFileSystem(
91 final MasterProcedureEnv env,
92 final TableName tableName,
93 List<HRegionInfo> regionInfoList,
94 final byte[] familyName) throws IOException {
95 final MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();
96 if (LOG.isDebugEnabled()) {
97 LOG.debug("Removing family=" + Bytes.toString(familyName) + " from table=" + tableName);
98 }
99 if (regionInfoList == null) {
100 regionInfoList = ProcedureSyncWait.getRegionsFromMeta(env, tableName);
101 }
102 for (HRegionInfo hri : regionInfoList) {
103
104 mfs.deleteFamilyFromFS(hri, familyName);
105 }
106 }
107
108
109
110
111 public static boolean reOpenAllRegions(
112 final MasterProcedureEnv env,
113 final TableName tableName,
114 final List<HRegionInfo> regionInfoList) throws IOException {
115 boolean done = false;
116 LOG.info("Bucketing regions by region server...");
117 List<HRegionLocation> regionLocations = null;
118 Connection connection = env.getMasterServices().getConnection();
119 try (RegionLocator locator = connection.getRegionLocator(tableName)) {
120 regionLocations = locator.getAllRegionLocations();
121 }
122
123 NavigableMap<HRegionInfo, ServerName> hri2Sn = new TreeMap<HRegionInfo, ServerName>();
124 for (HRegionLocation location : regionLocations) {
125 hri2Sn.put(location.getRegionInfo(), location.getServerName());
126 }
127 TreeMap<ServerName, List<HRegionInfo>> serverToRegions = Maps.newTreeMap();
128 List<HRegionInfo> reRegions = new ArrayList<HRegionInfo>();
129 for (HRegionInfo hri : regionInfoList) {
130 ServerName sn = hri2Sn.get(hri);
131
132
133 if (null == sn) {
134 LOG.info("Skip " + hri);
135 continue;
136 }
137 if (!serverToRegions.containsKey(sn)) {
138 LinkedList<HRegionInfo> hriList = Lists.newLinkedList();
139 serverToRegions.put(sn, hriList);
140 }
141 reRegions.add(hri);
142 serverToRegions.get(sn).add(hri);
143 }
144
145 LOG.info("Reopening " + reRegions.size() + " regions on " + serverToRegions.size()
146 + " region servers.");
147 AssignmentManager am = env.getMasterServices().getAssignmentManager();
148 am.setRegionsToReopen(reRegions);
149 BulkReOpen bulkReopen = new BulkReOpen(env.getMasterServices(), serverToRegions, am);
150 while (true) {
151 try {
152 if (bulkReopen.bulkReOpen()) {
153 done = true;
154 break;
155 } else {
156 LOG.warn("Timeout before reopening all regions");
157 }
158 } catch (InterruptedException e) {
159 LOG.warn("Reopen was interrupted");
160
161 Thread.currentThread().interrupt();
162 break;
163 }
164 }
165 return done;
166 }
167 }