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