1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
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  
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  }