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