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 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Set;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.Abortable;
34 import org.apache.hadoop.hbase.classification.InterfaceAudience;
35 import org.apache.hadoop.hbase.client.HConnection;
36 import org.apache.hadoop.hbase.replication.ReplicationException;
37 import org.apache.hadoop.hbase.replication.ReplicationFactory;
38 import org.apache.hadoop.hbase.replication.ReplicationPeers;
39 import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;
40 import org.apache.hadoop.hbase.replication.ReplicationQueuesClient;
41 import org.apache.hadoop.hbase.replication.ReplicationStateZKBase;
42 import org.apache.hadoop.hbase.util.HBaseFsck;
43 import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter;
44 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
45 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
46 import org.apache.zookeeper.KeeperException;
47
48
49
50
51 @InterfaceAudience.Private
52 public class ReplicationChecker {
53 private static final Log LOG = LogFactory.getLog(ReplicationChecker.class);
54 private ErrorReporter errorReporter;
55 private ReplicationQueuesClient queuesClient;
56 private ReplicationPeers replicationPeers;
57 private ReplicationQueueDeletor queueDeletor;
58
59 private Map<String, List<String>> undeletedQueueIds = new HashMap<String, List<String>>();
60
61 public ReplicationChecker(Configuration conf, ZooKeeperWatcher zkw, HConnection connection,
62 ErrorReporter errorReporter) throws IOException {
63 try {
64 this.errorReporter = errorReporter;
65 this.queuesClient = ReplicationFactory.getReplicationQueuesClient(zkw, conf, connection);
66 this.queuesClient.init();
67 this.replicationPeers = ReplicationFactory.getReplicationPeers(zkw, conf, this.queuesClient,
68 connection);
69 this.replicationPeers.init();
70 this.queueDeletor = new ReplicationQueueDeletor(zkw, conf, connection);
71 } catch (ReplicationException e) {
72 throw new IOException("failed to construct ReplicationChecker", e);
73 }
74 }
75
76 public boolean hasUnDeletedQueues() {
77 return errorReporter.getErrorList()
78 .contains(HBaseFsck.ErrorReporter.ERROR_CODE.UNDELETED_REPLICATION_QUEUE);
79 }
80
81 public void checkUnDeletedQueues() throws IOException {
82 Set<String> peerIds = new HashSet<String>(this.replicationPeers.getAllPeerIds());
83 try {
84 List<String> replicators = this.queuesClient.getListOfReplicators();
85 for (String replicator : replicators) {
86 List<String> queueIds = this.queuesClient.getAllQueues(replicator);
87 for (String queueId : queueIds) {
88 ReplicationQueueInfo queueInfo = new ReplicationQueueInfo(queueId);
89 if (!peerIds.contains(queueInfo.getPeerId())) {
90 if (!undeletedQueueIds.containsKey(replicator)) {
91 undeletedQueueIds.put(replicator, new ArrayList<String>());
92 }
93 undeletedQueueIds.get(replicator).add(queueId);
94
95 String msg = "Undeleted replication queue for removed peer found: "
96 + String.format("[removedPeerId=%s, replicator=%s, queueId=%s]",
97 queueInfo.getPeerId(), replicator, queueId);
98 errorReporter.reportError(
99 HBaseFsck.ErrorReporter.ERROR_CODE.UNDELETED_REPLICATION_QUEUE, msg);
100 }
101 }
102 }
103 } catch (KeeperException ke) {
104 throw new IOException(ke);
105 }
106 }
107
108 private static class ReplicationQueueDeletor extends ReplicationStateZKBase {
109 public ReplicationQueueDeletor(ZooKeeperWatcher zk, Configuration conf, Abortable abortable) {
110 super(zk, conf, abortable);
111 }
112
113 public void removeQueue(String replicator, String queueId) throws IOException {
114 String queueZnodePath = ZKUtil.joinZNode(ZKUtil.joinZNode(this.queuesZNode, replicator),
115 queueId);
116 try {
117 ZKUtil.deleteNodeRecursively(this.zookeeper, queueZnodePath);
118 LOG.info("remove replication queue, replicator: " + replicator + ", queueId: " + queueId);
119 } catch (KeeperException e) {
120 throw new IOException("failed to delete queue, replicator: " + replicator + ", queueId: "
121 + queueId);
122 }
123 }
124 }
125
126 public void fixUnDeletedQueues() throws IOException {
127 for (Entry<String, List<String>> replicatorAndQueueIds : undeletedQueueIds.entrySet()) {
128 String replicator = replicatorAndQueueIds.getKey();
129 for (String queueId : replicatorAndQueueIds.getValue()) {
130 queueDeletor.removeQueue(replicator, queueId);
131 }
132 }
133 }
134 }