Index: src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (revision 1138681) +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (working copy) @@ -2477,15 +2477,38 @@ public static HRegion createHRegion(final HRegionInfo info, final Path rootDir, final Configuration conf) throws IOException { + return createHRegion(info, rootDir, conf, null); + } + + /** + * Convenience method creating new HRegions. Used by createTable. + * The {@link HLog} for the created region needs to be closed explicitly. + * Use {@link HRegion#getLog()} to get access. + * + * @param info Info for region to create. + * @param rootDir Root directory for HBase instance + * @param conf + * @param hlog shared HLog + * @return new HRegion + * + * @throws IOException + */ + public static HRegion createHRegion(final HRegionInfo info, final Path rootDir, + final Configuration conf, + final HLog hlog) + throws IOException { Path tableDir = - HTableDescriptor.getTableDir(rootDir, info.getTableDesc().getName()); + HTableDescriptor.getTableDir(rootDir, info.getTableDesc().getName()); Path regionDir = HRegion.getRegionDir(tableDir, info.getEncodedName()); FileSystem fs = FileSystem.get(conf); fs.mkdirs(regionDir); + HLog effectiveHLog = hlog; + if (hlog == null) { + effectiveHLog = new HLog(fs, new Path(regionDir, HConstants.HREGION_LOGDIR_NAME), + new Path(regionDir, HConstants.HREGION_OLDLOGDIR_NAME), conf); + } HRegion region = HRegion.newHRegion(tableDir, - new HLog(fs, new Path(regionDir, HConstants.HREGION_LOGDIR_NAME), - new Path(regionDir, HConstants.HREGION_OLDLOGDIR_NAME), conf), - fs, conf, info, null); + effectiveHLog, fs, conf, info, null); region.initialize(); return region; } Index: src/main/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision 1138681) +++ src/main/java/org/apache/hadoop/hbase/master/HMaster.java (working copy) @@ -1,5 +1,5 @@ /** - * Copyright 2010 The Apache Software Foundation + * Copyright 2011 The Apache Software Foundation * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -54,8 +54,8 @@ import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.MetaScanner; +import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor; -import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.executor.ExecutorService; import org.apache.hadoop.hbase.executor.ExecutorService.ExecutorType; import org.apache.hadoop.hbase.ipc.HBaseRPC; @@ -73,6 +73,7 @@ import org.apache.hadoop.hbase.master.handler.TableModifyFamilyHandler; import org.apache.hadoop.hbase.master.metrics.MasterMetrics; import org.apache.hadoop.hbase.regionserver.HRegion; +import org.apache.hadoop.hbase.regionserver.wal.HLog; import org.apache.hadoop.hbase.replication.regionserver.Replication; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; @@ -781,26 +782,42 @@ if(MetaReader.tableExists(catalogTracker, tableName)) { throw new TableExistsException(tableName); } - for (HRegionInfo newRegion : newRegions) { - // 1. Set table enabling flag up in zk. - try { - assignmentManager.getZKTable().setEnabledTable(tableName); - } catch (KeeperException e) { - throw new IOException("Unable to ensure that the table will be" + + // 1. Set table enabling flag up in zk. + try { + assignmentManager.getZKTable().setEnabledTable(tableName); + } catch (KeeperException e) { + throw new IOException("Unable to ensure that the table will be" + " enabled because of a ZooKeeper issue", e); - } + } + List regionInfos = new ArrayList(); + final int batchSize = this.conf.getInt("hbase.master.createtable.batchsize", 100); + HLog hlog = null; + for (int regionIdx = 0; regionIdx < newRegions.length; regionIdx++) { + HRegionInfo newRegion = newRegions[regionIdx]; + // 2. Create HRegion HRegion region = HRegion.createHRegion(newRegion, - fileSystemManager.getRootDir(), conf); + fileSystemManager.getRootDir(), conf, hlog); - // 3. Insert into META - MetaEditor.addRegionToMeta(catalogTracker, region.getRegionInfo()); + if (hlog == null) { + hlog = region.getLog(); + } + regionInfos.add(region.getRegionInfo()); + if (regionIdx % batchSize == 0) { + // 3. Insert into META + MetaEditor.addRegionsToMeta(catalogTracker, regionInfos); + regionInfos.clear(); + } + // 4. Close the new region to flush to disk. Close log file too. region.close(); - region.getLog().closeAndDelete(); } + hlog.closeAndDelete(); + if (regionInfos.size() > 0) { + MetaEditor.addRegionsToMeta(catalogTracker, regionInfos); + } // 5. Trigger immediate assignment of the regions in round-robin fashion if (newRegions.length == 1) { Index: src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java (revision 1138681) +++ src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java (working copy) @@ -19,6 +19,9 @@ */ package org.apache.hadoop.hbase.catalog; +import java.util.ArrayList; +import java.util.List; + import java.io.IOException; import java.net.ConnectException; @@ -43,6 +46,13 @@ public class MetaEditor { private static final Log LOG = LogFactory.getLog(MetaEditor.class); + private static Put makePutFromRegionInfo(HRegionInfo regionInfo) throws IOException { + Put put = new Put(regionInfo.getRegionName()); + put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(regionInfo)); + return put; + } + /** * Adds a META row for the specified new region. * @param regionInfo region information @@ -51,15 +61,31 @@ public static void addRegionToMeta(CatalogTracker catalogTracker, HRegionInfo regionInfo) throws IOException { - Put put = new Put(regionInfo.getRegionName()); - put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, - Writables.getBytes(regionInfo)); catalogTracker.waitForMetaServerConnectionDefault().put( - CatalogTracker.META_REGION, put); + CatalogTracker.META_REGION, makePutFromRegionInfo(regionInfo)); LOG.info("Added region " + regionInfo.getRegionNameAsString() + " to META"); } /** + * Adds a META row for each of the specified new regions. + * @param catalogTracker CatalogTracker + * @param regionInfos region information list + * @throws IOException if problem connecting or updating meta + */ + public static void addRegionsToMeta(CatalogTracker catalogTracker, + List regionInfos) + throws IOException { + List puts = new ArrayList(); + for (HRegionInfo regionInfo : regionInfos) { + puts.add(makePutFromRegionInfo(regionInfo)); + LOG.debug("Added region " + regionInfo.getRegionNameAsString() + " to META"); + } + catalogTracker.waitForMetaServerConnectionDefault().put( + CatalogTracker.META_REGION, puts); + LOG.info("Added " + puts.size() + " regions to META"); + } + + /** * Offline parent in meta. * Used when splitting. * @param catalogTracker