HBASE-21843 RegionGroupingProvider breaks the meta wal file name pattern which may...
[hbase.git] / hbase-server / src / main / java / org / apache / hadoop / hbase / master / TableNamespaceManager.java
blob21178e56c5d63bd34b6e60e82b47cfd785c06c81
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package org.apache.hadoop.hbase.master;
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25 import java.util.stream.Collectors;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.hadoop.hbase.Cell;
28 import org.apache.hadoop.hbase.CellUtil;
29 import org.apache.hadoop.hbase.DoNotRetryIOException;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.MetaTableAccessor;
32 import org.apache.hadoop.hbase.NamespaceDescriptor;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.client.BufferedMutator;
35 import org.apache.hadoop.hbase.client.Connection;
36 import org.apache.hadoop.hbase.client.Delete;
37 import org.apache.hadoop.hbase.client.Put;
38 import org.apache.hadoop.hbase.client.Result;
39 import org.apache.hadoop.hbase.client.ResultScanner;
40 import org.apache.hadoop.hbase.client.Scan;
41 import org.apache.hadoop.hbase.client.Table;
42 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
43 import org.apache.hadoop.hbase.client.TableState;
44 import org.apache.hadoop.hbase.constraint.ConstraintException;
45 import org.apache.hadoop.hbase.master.procedure.DisableTableProcedure;
46 import org.apache.hadoop.hbase.util.Bytes;
47 import org.apache.yetus.audience.InterfaceAudience;
49 import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream;
51 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
52 import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
54 /**
55 * This is a helper class used internally to manage the namespace metadata that is stored in the ns
56 * family in meta table.
58 @InterfaceAudience.Private
59 public class TableNamespaceManager {
61 public static final String KEY_MAX_REGIONS = "hbase.namespace.quota.maxregions";
62 public static final String KEY_MAX_TABLES = "hbase.namespace.quota.maxtables";
63 static final String NS_INIT_TIMEOUT = "hbase.master.namespace.init.timeout";
64 static final int DEFAULT_NS_INIT_TIMEOUT = 300000;
66 private final ConcurrentMap<String, NamespaceDescriptor> cache = new ConcurrentHashMap<>();
68 private final MasterServices masterServices;
70 TableNamespaceManager(MasterServices masterServices) {
71 this.masterServices = masterServices;
74 private void migrateNamespaceTable() throws IOException {
75 try (Table nsTable = masterServices.getConnection().getTable(TableName.NAMESPACE_TABLE_NAME);
76 ResultScanner scanner = nsTable.getScanner(
77 new Scan().addFamily(TableDescriptorBuilder.NAMESPACE_FAMILY_INFO_BYTES).readAllVersions());
78 BufferedMutator mutator =
79 masterServices.getConnection().getBufferedMutator(TableName.META_TABLE_NAME)) {
80 for (Result result;;) {
81 result = scanner.next();
82 if (result == null) {
83 break;
85 Put put = new Put(result.getRow());
86 result
87 .getColumnCells(TableDescriptorBuilder.NAMESPACE_FAMILY_INFO_BYTES,
88 TableDescriptorBuilder.NAMESPACE_COL_DESC_BYTES)
89 .forEach(c -> put.addColumn(HConstants.NAMESPACE_FAMILY,
90 HConstants.NAMESPACE_COL_DESC_QUALIFIER, c.getTimestamp(), CellUtil.cloneValue(c)));
91 mutator.mutate(put);
94 // schedule a disable procedure instead of block waiting here, as when disabling a table we will
95 // wait until master is initialized, but we are part of the initialization...
96 masterServices.getMasterProcedureExecutor().submitProcedure(
97 new DisableTableProcedure(masterServices.getMasterProcedureExecutor().getEnvironment(),
98 TableName.NAMESPACE_TABLE_NAME, false));
101 private void loadNamespaceIntoCache() throws IOException {
102 try (Table table = masterServices.getConnection().getTable(TableName.META_TABLE_NAME);
103 ResultScanner scanner = table.getScanner(HConstants.NAMESPACE_FAMILY)) {
104 for (Result result;;) {
105 result = scanner.next();
106 if (result == null) {
107 break;
109 Cell cell = result.getColumnLatestCell(HConstants.NAMESPACE_FAMILY,
110 HConstants.NAMESPACE_COL_DESC_QUALIFIER);
111 NamespaceDescriptor ns = ProtobufUtil
112 .toNamespaceDescriptor(HBaseProtos.NamespaceDescriptor.parseFrom(CodedInputStream
113 .newInstance(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength())));
114 cache.put(ns.getName(), ns);
119 public void start() throws IOException {
120 TableState nsTableState = MetaTableAccessor.getTableState(masterServices.getConnection(),
121 TableName.NAMESPACE_TABLE_NAME);
122 if (nsTableState != null && nsTableState.isEnabled()) {
123 migrateNamespaceTable();
125 loadNamespaceIntoCache();
129 * check whether a namespace has already existed.
131 public boolean doesNamespaceExist(String namespaceName) throws IOException {
132 return cache.containsKey(namespaceName);
135 public NamespaceDescriptor get(String name) throws IOException {
136 return cache.get(name);
139 public void addOrUpdateNamespace(NamespaceDescriptor ns) throws IOException {
140 insertNamespaceToMeta(masterServices.getConnection(), ns);
141 cache.put(ns.getName(), ns);
144 public static void insertNamespaceToMeta(Connection conn, NamespaceDescriptor ns)
145 throws IOException {
146 byte[] row = Bytes.toBytes(ns.getName());
147 Put put = new Put(row, true).addColumn(HConstants.NAMESPACE_FAMILY,
148 HConstants.NAMESPACE_COL_DESC_QUALIFIER,
149 ProtobufUtil.toProtoNamespaceDescriptor(ns).toByteArray());
150 try (Table table = conn.getTable(TableName.META_TABLE_NAME)) {
151 table.put(put);
155 public void deleteNamespace(String namespaceName) throws IOException {
156 Delete d = new Delete(Bytes.toBytes(namespaceName));
157 try (Table table = masterServices.getConnection().getTable(TableName.META_TABLE_NAME)) {
158 table.delete(d);
160 cache.remove(namespaceName);
163 public List<NamespaceDescriptor> list() throws IOException {
164 return cache.values().stream().collect(Collectors.toList());
167 public void validateTableAndRegionCount(NamespaceDescriptor desc) throws IOException {
168 if (getMaxRegions(desc) <= 0) {
169 throw new ConstraintException(
170 "The max region quota for " + desc.getName() + " is less than or equal to zero.");
172 if (getMaxTables(desc) <= 0) {
173 throw new ConstraintException(
174 "The max tables quota for " + desc.getName() + " is less than or equal to zero.");
178 public static long getMaxTables(NamespaceDescriptor ns) throws IOException {
179 String value = ns.getConfigurationValue(KEY_MAX_TABLES);
180 long maxTables = 0;
181 if (StringUtils.isNotEmpty(value)) {
182 try {
183 maxTables = Long.parseLong(value);
184 } catch (NumberFormatException exp) {
185 throw new DoNotRetryIOException("NumberFormatException while getting max tables.", exp);
187 } else {
188 // The property is not set, so assume its the max long value.
189 maxTables = Long.MAX_VALUE;
191 return maxTables;
194 public static long getMaxRegions(NamespaceDescriptor ns) throws IOException {
195 String value = ns.getConfigurationValue(KEY_MAX_REGIONS);
196 long maxRegions = 0;
197 if (StringUtils.isNotEmpty(value)) {
198 try {
199 maxRegions = Long.parseLong(value);
200 } catch (NumberFormatException exp) {
201 throw new DoNotRetryIOException("NumberFormatException while getting max regions.", exp);
203 } else {
204 // The property is not set, so assume its the max long value.
205 maxRegions = Long.MAX_VALUE;
207 return maxRegions;