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