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.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.concurrent.Callable;
27 import java.util.concurrent.CompletionService;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.ExecutorCompletionService;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.ThreadFactory;
32 import java.util.concurrent.ThreadPoolExecutor;
33 import java.util.concurrent.TimeUnit;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.hadoop.classification.InterfaceAudience;
38 import org.apache.hadoop.conf.Configuration;
39 import org.apache.hadoop.fs.FileSystem;
40 import org.apache.hadoop.fs.Path;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.HTableDescriptor;
43 import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
44 import org.apache.hadoop.hbase.Server;
45 import org.apache.hadoop.hbase.ServerName;
46 import org.apache.hadoop.hbase.TableExistsException;
47 import org.apache.hadoop.hbase.catalog.CatalogTracker;
48 import org.apache.hadoop.hbase.catalog.MetaEditor;
49 import org.apache.hadoop.hbase.catalog.MetaReader;
50 import org.apache.hadoop.hbase.executor.EventHandler;
51 import org.apache.hadoop.hbase.master.AssignmentManager;
52 import org.apache.hadoop.hbase.master.MasterFileSystem;
53 import org.apache.hadoop.hbase.master.ServerManager;
54 import org.apache.hadoop.hbase.regionserver.HRegion;
55 import org.apache.hadoop.hbase.util.FSTableDescriptors;
56 import org.apache.hadoop.hbase.util.ModifyRegionUtils;
57 import org.apache.hadoop.hbase.util.Threads;
58 import org.apache.zookeeper.KeeperException;
59
60
61
62
63 @InterfaceAudience.Private
64 public class CreateTableHandler extends EventHandler {
65 private static final Log LOG = LogFactory.getLog(CreateTableHandler.class);
66 protected MasterFileSystem fileSystemManager;
67 protected final HTableDescriptor hTableDescriptor;
68 protected Configuration conf;
69 protected final AssignmentManager assignmentManager;
70 protected final CatalogTracker catalogTracker;
71 protected final ServerManager serverManager;
72 private final HRegionInfo [] newRegions;
73
74 public CreateTableHandler(Server server, MasterFileSystem fileSystemManager,
75 ServerManager serverManager, HTableDescriptor hTableDescriptor,
76 Configuration conf, HRegionInfo [] newRegions,
77 CatalogTracker catalogTracker, AssignmentManager assignmentManager)
78 throws NotAllMetaRegionsOnlineException, TableExistsException,
79 IOException {
80 super(server, EventType.C_M_CREATE_TABLE);
81
82 this.fileSystemManager = fileSystemManager;
83 this.serverManager = serverManager;
84 this.hTableDescriptor = hTableDescriptor;
85 this.conf = conf;
86 this.newRegions = newRegions;
87 this.catalogTracker = catalogTracker;
88 this.assignmentManager = assignmentManager;
89
90 int timeout = conf.getInt("hbase.client.catalog.timeout", 10000);
91
92 try {
93 if(catalogTracker.waitForMeta(timeout) == null) {
94 throw new NotAllMetaRegionsOnlineException();
95 }
96 } catch (InterruptedException e) {
97 LOG.warn("Interrupted waiting for meta availability", e);
98 throw new IOException(e);
99 }
100
101 String tableName = this.hTableDescriptor.getNameAsString();
102 if (MetaReader.tableExists(catalogTracker, tableName)) {
103 throw new TableExistsException(tableName);
104 }
105
106
107
108
109
110
111
112
113 try {
114 if (!this.assignmentManager.getZKTable().checkAndSetEnablingTable(tableName))
115 throw new TableExistsException(tableName);
116 } catch (KeeperException e) {
117 throw new IOException("Unable to ensure that the table will be" +
118 " enabling because of a ZooKeeper issue", e);
119 }
120 }
121
122
123 @Override
124 public String toString() {
125 String name = "UnknownServerName";
126 if(server != null && server.getServerName() != null) {
127 name = server.getServerName().toString();
128 }
129 return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" +
130 this.hTableDescriptor.getNameAsString();
131 }
132
133 @Override
134 public void process() {
135 String tableName = this.hTableDescriptor.getNameAsString();
136 try {
137 LOG.info("Attempting to create the table " + tableName);
138 handleCreateTable(tableName);
139 completed(null);
140 } catch (Throwable e) {
141 LOG.error("Error trying to create the table " + tableName, e);
142 completed(e);
143 }
144 }
145
146
147
148
149
150 protected void completed(final Throwable exception) {
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 private void handleCreateTable(String tableName) throws IOException, KeeperException {
168 Path tempdir = fileSystemManager.getTempDir();
169 FileSystem fs = fileSystemManager.getFileSystem();
170
171
172 FSTableDescriptors.createTableDescriptor(fs, tempdir, this.hTableDescriptor);
173 Path tempTableDir = new Path(tempdir, tableName);
174 Path tableDir = new Path(fileSystemManager.getRootDir(), tableName);
175
176
177 List<HRegionInfo> regionInfos = handleCreateHdfsRegions(tempdir, tableName);
178
179
180 if (!fs.rename(tempTableDir, tableDir)) {
181 throw new IOException("Unable to move table from temp=" + tempTableDir +
182 " to hbase root=" + tableDir);
183 }
184
185 if (regionInfos != null && regionInfos.size() > 0) {
186
187 MetaEditor.addRegionsToMeta(this.catalogTracker, regionInfos);
188
189
190 List<ServerName> servers = serverManager.getOnlineServersList();
191
192 assignmentManager.removeDeadNotExpiredServers(servers);
193 try {
194 this.assignmentManager.assignUserRegions(regionInfos, servers);
195 } catch (InterruptedException e) {
196 LOG.error("Caught " + e + " during round-robin assignment");
197 InterruptedIOException ie = new InterruptedIOException(e.getMessage());
198 ie.initCause(e);
199 throw ie;
200 }
201 }
202
203
204 try {
205 assignmentManager.getZKTable().setEnabledTable(tableName);
206 } catch (KeeperException e) {
207 throw new IOException("Unable to ensure that " + tableName + " will be" +
208 " enabled because of a ZooKeeper issue", e);
209 }
210 }
211
212
213
214
215
216
217
218 protected List<HRegionInfo> handleCreateHdfsRegions(final Path tableRootDir,
219 final String tableName)
220 throws IOException {
221 return ModifyRegionUtils.createRegions(conf, tableRootDir,
222 hTableDescriptor, newRegions, null);
223 }
224 }