View Javadoc

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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  
19  package org.apache.hadoop.hbase.util.hbck;
20  
21  import java.io.IOException;
22  
23  import org.apache.hadoop.hbase.InterProcessLock.MetadataHandler;
24  import org.apache.hadoop.hbase.master.TableLockManager;
25  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
26  import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
27  import org.apache.hadoop.hbase.util.Bytes;
28  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
29  import org.apache.hadoop.hbase.util.HBaseFsck;
30  import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter;
31  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
32  
33  /**
34   * Utility to check and fix table locks. Need zookeeper connection.
35   */
36  public class TableLockChecker {
37  
38    private ZooKeeperWatcher zkWatcher;
39    private ErrorReporter errorReporter;
40    long expireTimeout;
41  
42    public TableLockChecker(ZooKeeperWatcher zkWatcher, ErrorReporter errorReporter) {
43      this.zkWatcher = zkWatcher;
44      this.errorReporter = errorReporter;
45      expireTimeout = zkWatcher.getConfiguration().getLong(
46          TableLockManager.TABLE_LOCK_EXPIRE_TIMEOUT,
47          TableLockManager.DEFAULT_TABLE_LOCK_EXPIRE_TIMEOUT_MS);
48    }
49  
50    public void checkTableLocks() throws IOException {
51      TableLockManager tableLockManager
52        = TableLockManager.createTableLockManager(zkWatcher.getConfiguration(), zkWatcher, null);
53      final long expireDate = EnvironmentEdgeManager.currentTime() - expireTimeout;
54  
55      MetadataHandler handler = new MetadataHandler() {
56        @Override
57        public void handleMetadata(byte[] ownerMetadata) {
58          ZooKeeperProtos.TableLock data = TableLockManager.fromBytes(ownerMetadata);
59          String msg = "Table lock acquire attempt found:";
60          if (data != null) {
61             msg = msg +
62                String.format("[tableName=%s:%s, lockOwner=%s, threadId=%s, " +
63                "purpose=%s, isShared=%s, createTime=%s]",
64                data.getTableName().getNamespace().toStringUtf8(),
65                data.getTableName().getQualifier().toStringUtf8(),
66                ProtobufUtil.toServerName(data.getLockOwner()), data.getThreadId(),
67                data.getPurpose(), data.getIsShared(), data.getCreateTime());
68          }
69  
70          if (data != null && data.hasCreateTime() && data.getCreateTime() < expireDate) {
71            errorReporter.reportError(HBaseFsck.ErrorReporter.ERROR_CODE.EXPIRED_TABLE_LOCK, msg);
72          } else {
73            errorReporter.print(msg);
74          }
75        }
76      };
77  
78      tableLockManager.visitAllLocks(handler);
79    }
80  
81    public void fixExpiredTableLocks() throws IOException {
82      TableLockManager tableLockManager
83        = TableLockManager.createTableLockManager(zkWatcher.getConfiguration(), zkWatcher, null);
84  
85      tableLockManager.reapAllExpiredLocks();
86    }
87  
88  }