View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.catalog;
21  
22  import java.io.IOException;
23  import java.net.ConnectException;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.HConstants;
28  import org.apache.hadoop.hbase.HRegionInfo;
29  import org.apache.hadoop.hbase.HServerInfo;
30  import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
31  import org.apache.hadoop.hbase.client.Delete;
32  import org.apache.hadoop.hbase.client.Put;
33  import org.apache.hadoop.hbase.ipc.HRegionInterface;
34  import org.apache.hadoop.hbase.util.Bytes;
35  import org.apache.hadoop.hbase.util.Writables;
36  
37  /**
38   * Writes region and assignment information to <code>.META.</code>.
39   * <p>
40   * Uses the {@link CatalogTracker} to obtain locations and connections to
41   * catalogs.
42   */
43  public class MetaEditor {
44    private static final Log LOG = LogFactory.getLog(MetaEditor.class);
45  
46    /**
47     * Adds a META row for the specified new region.
48     * @param regionInfo region information
49     * @throws IOException if problem connecting or updating meta
50     */
51    public static void addRegionToMeta(CatalogTracker catalogTracker,
52        HRegionInfo regionInfo)
53    throws IOException {
54      Put put = new Put(regionInfo.getRegionName());
55      put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
56          Writables.getBytes(regionInfo));
57      catalogTracker.waitForMetaServerConnectionDefault().put(
58          CatalogTracker.META_REGION, put);
59      LOG.info("Added region " + regionInfo.getRegionNameAsString() + " to META");
60    }
61  
62    /**
63     * Offline parent in meta.
64     * Used when splitting.
65     * @param catalogTracker
66     * @param parent
67     * @param a Split daughter region A
68     * @param b Split daughter region B
69     * @throws NotAllMetaRegionsOnlineException
70     * @throws IOException
71     */
72    public static void offlineParentInMeta(CatalogTracker catalogTracker,
73        HRegionInfo parent, final HRegionInfo a, final HRegionInfo b)
74    throws NotAllMetaRegionsOnlineException, IOException {
75      HRegionInfo copyOfParent = new HRegionInfo(parent);
76      copyOfParent.setOffline(true);
77      copyOfParent.setSplit(true);
78      Put put = new Put(copyOfParent.getRegionName());
79      addRegionInfo(put, copyOfParent);
80      put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER,
81        Writables.getBytes(a));
82      put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER,
83        Writables.getBytes(b));
84      catalogTracker.waitForMetaServerConnectionDefault().put(CatalogTracker.META_REGION, put);
85      LOG.info("Offlined parent region " + parent.getRegionNameAsString() +
86        " in META");
87    }
88  
89    public static void addDaughter(final CatalogTracker catalogTracker,
90        final HRegionInfo regionInfo, final HServerInfo serverInfo)
91    throws NotAllMetaRegionsOnlineException, IOException {
92      HRegionInterface server = catalogTracker.waitForMetaServerConnectionDefault();
93      byte [] catalogRegionName = CatalogTracker.META_REGION;
94      Put put = new Put(regionInfo.getRegionName());
95      addRegionInfo(put, regionInfo);
96      if (serverInfo != null) addLocation(put, serverInfo);
97      server.put(catalogRegionName, put);
98      LOG.info("Added daughter " + regionInfo.getRegionNameAsString() +
99        " in region " + Bytes.toString(catalogRegionName) +
100       (serverInfo == null?
101         ", serverInfo=null": ", serverInfo=" + serverInfo.getServerName()));
102   }
103 
104   /**
105    * Updates the location of the specified META region in ROOT to be the
106    * specified server hostname and startcode.
107    * <p>
108    * Uses passed catalog tracker to get a connection to the server hosting
109    * ROOT and makes edits to that region.
110    *
111    * @param catalogTracker catalog tracker
112    * @param regionInfo region to update location of
113    * @param serverInfo server the region is located on
114    * @throws IOException
115    * @throws ConnectException Usually because the regionserver carrying .META.
116    * is down.
117    * @throws NullPointerException Because no -ROOT- server connection
118    */
119   public static void updateMetaLocation(CatalogTracker catalogTracker,
120       HRegionInfo regionInfo, HServerInfo serverInfo)
121   throws IOException, ConnectException {
122     HRegionInterface server = catalogTracker.waitForRootServerConnectionDefault();
123     if (server == null) throw new IOException("No server for -ROOT-");
124     updateLocation(server, CatalogTracker.ROOT_REGION, regionInfo, serverInfo);
125   }
126 
127   /**
128    * Updates the location of the specified region in META to be the specified
129    * server hostname and startcode.
130    * <p>
131    * Uses passed catalog tracker to get a connection to the server hosting
132    * META and makes edits to that region.
133    *
134    * @param catalogTracker catalog tracker
135    * @param regionInfo region to update location of
136    * @param serverInfo server the region is located on
137    * @throws IOException
138    */
139   public static void updateRegionLocation(CatalogTracker catalogTracker,
140       HRegionInfo regionInfo, HServerInfo serverInfo)
141   throws IOException {
142     updateLocation(catalogTracker.waitForMetaServerConnectionDefault(),
143         CatalogTracker.META_REGION, regionInfo, serverInfo);
144   }
145 
146   /**
147    * Updates the location of the specified region to be the specified server.
148    * <p>
149    * Connects to the specified server which should be hosting the specified
150    * catalog region name to perform the edit.
151    *
152    * @param server connection to server hosting catalog region
153    * @param catalogRegionName name of catalog region being updated
154    * @param regionInfo region to update location of
155    * @param serverInfo server the region is located on
156    * @throws IOException In particular could throw {@link java.net.ConnectException}
157    * if the server is down on other end.
158    */
159   private static void updateLocation(HRegionInterface server,
160       byte [] catalogRegionName, HRegionInfo regionInfo, HServerInfo serverInfo)
161   throws IOException {
162     Put put = new Put(regionInfo.getRegionName());
163     addLocation(put, serverInfo);
164     server.put(catalogRegionName, put);
165     LOG.info("Updated row " + regionInfo.getRegionNameAsString() +
166       " in region " + Bytes.toStringBinary(catalogRegionName) + " with " +
167       "server=" + serverInfo.getHostnamePort() + ", " +
168       "startcode=" + serverInfo.getStartCode());
169   }
170 
171   /**
172    * Deletes the specified region from META.
173    * @param catalogTracker
174    * @param regionInfo region to be deleted from META
175    * @throws IOException
176    */
177   public static void deleteRegion(CatalogTracker catalogTracker,
178       HRegionInfo regionInfo)
179   throws IOException {
180     Delete delete = new Delete(regionInfo.getRegionName());
181     catalogTracker.waitForMetaServerConnectionDefault().
182       delete(CatalogTracker.META_REGION, delete);
183     LOG.info("Deleted region " + regionInfo.getRegionNameAsString() + " from META");
184   }
185 
186   /**
187    * Deletes daughter reference in offlined split parent.
188    * @param catalogTracker
189    * @param parent Parent row we're to remove daughter reference from
190    * @param qualifier SplitA or SplitB daughter to remove
191    * @param daughter
192    * @throws NotAllMetaRegionsOnlineException
193    * @throws IOException
194    */
195   public static void deleteDaughterReferenceInParent(CatalogTracker catalogTracker,
196       final HRegionInfo parent, final byte [] qualifier,
197       final HRegionInfo daughter)
198   throws NotAllMetaRegionsOnlineException, IOException {
199     Delete delete = new Delete(parent.getRegionName());
200     delete.deleteColumns(HConstants.CATALOG_FAMILY, qualifier);
201     catalogTracker.waitForMetaServerConnectionDefault().
202       delete(CatalogTracker.META_REGION, delete);
203     LOG.info("Deleted daughter reference " + daughter.getRegionNameAsString() +
204       ", qualifier=" + Bytes.toStringBinary(qualifier) + ", from parent " +
205       parent.getRegionNameAsString());
206   }
207 
208   /**
209    * Updates the region information for the specified region in META.
210    * @param catalogTracker
211    * @param regionInfo region to be updated in META
212    * @throws IOException
213    */
214   public static void updateRegionInfo(CatalogTracker catalogTracker,
215       HRegionInfo regionInfo)
216   throws IOException {
217     Put put = new Put(regionInfo.getRegionName());
218     addRegionInfo(put, regionInfo);
219     catalogTracker.waitForMetaServerConnectionDefault().put(
220         CatalogTracker.META_REGION, put);
221     LOG.info("Updated region " + regionInfo.getRegionNameAsString() + " in META");
222   }
223 
224   private static Put addRegionInfo(final Put p, final HRegionInfo hri)
225   throws IOException {
226     p.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
227         Writables.getBytes(hri));
228     return p;
229   }
230 
231   private static Put addLocation(final Put p, final HServerInfo hsi) {
232     p.add(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER,
233       Bytes.toBytes(hsi.getHostnamePort()));
234     p.add(HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER,
235       Bytes.toBytes(hsi.getStartCode()));
236     return p;
237   }
238 }