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 if (exception != null) {
173
174
175
176
177 try {
178 this.assignmentManager.getZKTable().removeEnablingTable(
179 this.hTableDescriptor.getTableName(), false);
180 } catch (KeeperException e) {
181
182 LOG.error("Got a keeper exception while removing the ENABLING table znode "
183 + this.hTableDescriptor.getTableName(), e);
184 }
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 private void handleCreateTable(TableName tableName)
203 throws IOException, KeeperException {
204 Path tempdir = fileSystemManager.getTempDir();
205 FileSystem fs = fileSystemManager.getFileSystem();
206
207
208 Path tempTableDir = FSUtils.getTableDir(tempdir, tableName);
209 new FSTableDescriptors(this.conf).createTableDescriptorForTableDirectory(
210 tempTableDir, this.hTableDescriptor, false);
211 Path tableDir = FSUtils.getTableDir(fileSystemManager.getRootDir(), tableName);
212
213
214 List<HRegionInfo> regionInfos = handleCreateHdfsRegions(tempdir, tableName);
215
216 if (!fs.rename(tempTableDir, tableDir)) {
217 throw new IOException("Unable to move table from temp=" + tempTableDir +
218 " to hbase root=" + tableDir);
219 }
220
221 if (regionInfos != null && regionInfos.size() > 0) {
222
223 addRegionsToMeta(this.catalogTracker, regionInfos);
224
225
226 try {
227 assignmentManager.getRegionStates().createRegionStates(regionInfos);
228 assignmentManager.assign(regionInfos);
229 } catch (InterruptedException e) {
230 LOG.error("Caught " + e + " during round-robin assignment");
231 InterruptedIOException ie = new InterruptedIOException(e.getMessage());
232 ie.initCause(e);
233 throw ie;
234 }
235 }
236
237
238 try {
239 assignmentManager.getZKTable().setEnabledTable(tableName);
240 } catch (KeeperException e) {
241 throw new IOException("Unable to ensure that " + tableName + " will be" +
242 " enabled because of a ZooKeeper issue", e);
243 }
244 }
245
246 private void releaseTableLock() {
247 if (this.tableLock != null) {
248 try {
249 this.tableLock.release();
250 } catch (IOException ex) {
251 LOG.warn("Could not release the table lock", ex);
252 }
253 }
254 }
255
256
257
258
259
260
261
262 protected List<HRegionInfo> handleCreateHdfsRegions(final Path tableRootDir,
263 final TableName tableName)
264 throws IOException {
265 return ModifyRegionUtils.createRegions(conf, tableRootDir,
266 hTableDescriptor, newRegions, null);
267 }
268
269
270
271
272 protected void addRegionsToMeta(final CatalogTracker ct, final List<HRegionInfo> regionInfos)
273 throws IOException {
274 MetaEditor.addRegionsToMeta(this.catalogTracker, regionInfos);
275 }
276 }