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.handler;
20
21 import java.io.IOException;
22 import java.io.InterruptedIOException;
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.conf.Configuration;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
35 import org.apache.hadoop.hbase.Server;
36 import org.apache.hadoop.hbase.TableExistsException;
37 import org.apache.hadoop.hbase.catalog.CatalogTracker;
38 import org.apache.hadoop.hbase.catalog.MetaEditor;
39 import org.apache.hadoop.hbase.catalog.MetaReader;
40 import org.apache.hadoop.hbase.executor.EventHandler;
41 import org.apache.hadoop.hbase.executor.EventType;
42 import org.apache.hadoop.hbase.master.AssignmentManager;
43 import org.apache.hadoop.hbase.master.HMaster;
44 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
45 import org.apache.hadoop.hbase.master.MasterFileSystem;
46 import org.apache.hadoop.hbase.master.MasterServices;
47 import org.apache.hadoop.hbase.master.TableLockManager;
48 import org.apache.hadoop.hbase.master.TableLockManager.TableLock;
49 import org.apache.hadoop.hbase.util.FSTableDescriptors;
50 import org.apache.hadoop.hbase.util.FSUtils;
51 import org.apache.hadoop.hbase.util.ModifyRegionUtils;
52 import org.apache.zookeeper.KeeperException;
53
54
55
56
57 @InterfaceAudience.Private
58 public class CreateTableHandler extends EventHandler {
59 private static final Log LOG = LogFactory.getLog(CreateTableHandler.class);
60 protected final MasterFileSystem fileSystemManager;
61 protected final HTableDescriptor hTableDescriptor;
62 protected final Configuration conf;
63 private final AssignmentManager assignmentManager;
64 private final CatalogTracker catalogTracker;
65 private final TableLockManager tableLockManager;
66 private final HRegionInfo [] newRegions;
67 private final TableLock tableLock;
68
69 public CreateTableHandler(Server server, MasterFileSystem fileSystemManager,
70 HTableDescriptor hTableDescriptor, Configuration conf, HRegionInfo [] newRegions,
71 MasterServices masterServices) {
72 super(server, EventType.C_M_CREATE_TABLE);
73
74 this.fileSystemManager = fileSystemManager;
75 this.hTableDescriptor = hTableDescriptor;
76 this.conf = conf;
77 this.newRegions = newRegions;
78 this.catalogTracker = masterServices.getCatalogTracker();
79 this.assignmentManager = masterServices.getAssignmentManager();
80 this.tableLockManager = masterServices.getTableLockManager();
81
82 this.tableLock = this.tableLockManager.writeLock(this.hTableDescriptor.getTableName()
83 , EventType.C_M_CREATE_TABLE.toString());
84 }
85
86 public CreateTableHandler prepare()
87 throws NotAllMetaRegionsOnlineException, TableExistsException, IOException {
88 int timeout = conf.getInt("hbase.client.catalog.timeout", 10000);
89
90 try {
91 if(catalogTracker.waitForMeta(timeout) == null) {
92 throw new NotAllMetaRegionsOnlineException();
93 }
94 } catch (InterruptedException e) {
95 LOG.warn("Interrupted waiting for meta availability", e);
96 InterruptedIOException ie = new InterruptedIOException(e.getMessage());
97 ie.initCause(e);
98 throw ie;
99 }
100
101
102 this.tableLock.acquire();
103 boolean success = false;
104 try {
105 TableName tableName = this.hTableDescriptor.getTableName();
106 if (MetaReader.tableExists(catalogTracker, tableName)) {
107 throw new TableExistsException(tableName);
108 }
109
110
111
112
113
114
115
116
117
118 try {
119 if (!this.assignmentManager.getZKTable().checkAndSetEnablingTable(tableName)) {
120 throw new TableExistsException(tableName);
121 }
122 } catch (KeeperException e) {
123 throw new IOException("Unable to ensure that the table will be" +
124 " enabling because of a ZooKeeper issue", e);
125 }
126 success = true;
127 } finally {
128 if (!success) {
129 releaseTableLock();
130 }
131 }
132 return this;
133 }
134
135 @Override
136 public String toString() {
137 String name = "UnknownServerName";
138 if(server != null && server.getServerName() != null) {
139 name = server.getServerName().toString();
140 }
141 return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" +
142 this.hTableDescriptor.getTableName();
143 }
144
145 @Override
146 public void process() {
147 TableName tableName = this.hTableDescriptor.getTableName();
148 LOG.info("Create table " + tableName);
149
150 try {
151 MasterCoprocessorHost cpHost = ((HMaster) this.server).getCoprocessorHost();
152 if (cpHost != null) {
153 cpHost.preCreateTableHandler(this.hTableDescriptor, this.newRegions);
154 }
155 handleCreateTable(tableName);
156 completed(null);
157 if (cpHost != null) {
158 cpHost.postCreateTableHandler(this.hTableDescriptor, this.newRegions);
159 }
160 } catch (Throwable e) {
161 LOG.error("Error trying to create the table " + tableName, e);
162 completed(e);
163 }
164 }
165
166
167
168
169
170 protected void completed(final Throwable exception) {
171 releaseTableLock();
172 String msg = exception == null ? null : exception.getMessage();
173 LOG.info("Table, " + this.hTableDescriptor.getTableName() + ", creation " +
174 msg == null ? "successful" : "failed. " + msg);
175 if (exception != null) {
176
177
178
179
180 try {
181 this.assignmentManager.getZKTable().removeEnablingTable(
182 this.hTableDescriptor.getTableName(), false);
183 } catch (KeeperException e) {
184
185 LOG.error("Got a keeper exception while removing the ENABLING table znode "
186 + this.hTableDescriptor.getTableName(), e);
187 }
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 private void handleCreateTable(TableName tableName)
206 throws IOException, KeeperException {
207 Path tempdir = fileSystemManager.getTempDir();
208 FileSystem fs = fileSystemManager.getFileSystem();
209
210
211 Path tempTableDir = FSUtils.getTableDir(tempdir, tableName);
212 new FSTableDescriptors(this.conf).createTableDescriptorForTableDirectory(
213 tempTableDir, this.hTableDescriptor, false);
214 Path tableDir = FSUtils.getTableDir(fileSystemManager.getRootDir(), tableName);
215
216
217 List<HRegionInfo> regionInfos = handleCreateHdfsRegions(tempdir, tableName);
218
219 if (!fs.rename(tempTableDir, tableDir)) {
220 throw new IOException("Unable to move table from temp=" + tempTableDir +
221 " to hbase root=" + tableDir);
222 }
223
224 if (regionInfos != null && regionInfos.size() > 0) {
225
226 addRegionsToMeta(this.catalogTracker, regionInfos);
227
228
229 try {
230 assignmentManager.getRegionStates().createRegionStates(regionInfos);
231 assignmentManager.assign(regionInfos);
232 } catch (InterruptedException e) {
233 LOG.error("Caught " + e + " during round-robin assignment");
234 InterruptedIOException ie = new InterruptedIOException(e.getMessage());
235 ie.initCause(e);
236 throw ie;
237 }
238 }
239
240
241 try {
242 assignmentManager.getZKTable().setEnabledTable(tableName);
243 } catch (KeeperException e) {
244 throw new IOException("Unable to ensure that " + tableName + " will be" +
245 " enabled because of a ZooKeeper issue", e);
246 }
247 }
248
249 private void releaseTableLock() {
250 if (this.tableLock != null) {
251 try {
252 this.tableLock.release();
253 } catch (IOException ex) {
254 LOG.warn("Could not release the table lock", ex);
255 }
256 }
257 }
258
259
260
261
262
263
264
265 protected List<HRegionInfo> handleCreateHdfsRegions(final Path tableRootDir,
266 final TableName tableName)
267 throws IOException {
268 return ModifyRegionUtils.createRegions(conf, tableRootDir,
269 hTableDescriptor, newRegions, null);
270 }
271
272
273
274
275 protected void addRegionsToMeta(final CatalogTracker ct, final List<HRegionInfo> regionInfos)
276 throws IOException {
277 MetaEditor.addRegionsToMeta(this.catalogTracker, regionInfos);
278 }
279 }