This repository has been archived by the owner on Jun 26, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 141
/
find_shard_mismatches.py
executable file
·103 lines (79 loc) · 3.3 KB
/
find_shard_mismatches.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
import argparse
import logging
from lib import environment_specific
from lib import host_utils
from lib import mysql_lib
log = logging.getLogger(__name__)
def main():
description = ("MySQL orpahned shard detector\n\n"
"This utility will attempt to find orphaned databases "
"across sharded MySQL systems")
parser = argparse.ArgumentParser(description=description,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-i',
'--instance',
help='Check a single instance rather than all',
default=False)
args = parser.parse_args()
if args.instance:
instance = host_utils.HostAddr(args.instance)
else:
instance = False
orphaned, orphaned_but_used, missing = find_shard_mismatches(instance)
for o in orphaned:
log.info('Orphan dbs: {host} {dbs}'.format(
host=o, dbs=','.join(orphaned[o])))
for obu in orphaned_but_used:
log.info('Orphan, but still used, dbs: {host} {dbs}'.format(
host=obu, dbs=','.join(orphaned_but_used[obu])))
for m in missing:
log.info('Missing dbs:{host} {dbs}'.format(
host=m, dbs=','.join(missing[m])))
if not (orphaned or orphaned_but_used or missing):
log.info('No problems found!')
def find_shard_mismatches(instance=False):
""" Find shards that are missing or unexpected in a sharded dataset
Args:
instance - If supplied, only check this instance.
Returns:
orphaned - A dict of unexpected and (according to table statistics)
unused dbs. Key is master instance, value is a set.
orphaned_but_used - A dict of unexpected and but used dbs.
Data structure is the same as orphaned.
missing - A dict of expected but missing dbs.
Data structure is the same as orphaned.
"""
orphaned = dict()
orphaned_but_used = dict()
missing_dbs = dict()
zk = host_utils.MysqlZookeeper()
rs_dbs_map = zk.get_sharded_dbs_by_replica_set()
if instance:
rs = zk.get_replica_set_from_instance(instance)
rs_dbs_map = {rs: rs_dbs_map[rs]}
for rs in rs_dbs_map:
# non-sharded replica sets
if not len(rs_dbs_map[rs]):
continue
expected_dbs = rs_dbs_map[rs]
instance = zk.get_mysql_instance_from_replica_set(rs)
activity = mysql_lib.get_dbs_activity(instance)
actual_dbs = mysql_lib.get_dbs(instance)
unexpected_dbs = actual_dbs.difference(expected_dbs)
missing = expected_dbs.difference(actual_dbs)
if missing:
missing_dbs[instance] = expected_dbs.difference(actual_dbs)
for db in unexpected_dbs:
if activity[db]['ROWS_CHANGED'] != 0:
if instance not in orphaned_but_used:
orphaned_but_used[instance] = set()
orphaned_but_used[instance].add(db)
else:
if instance not in orphaned:
orphaned[instance] = set()
orphaned[instance].add(db)
return orphaned, orphaned_but_used, missing_dbs
if __name__ == "__main__":
environment_specific.initialize_logger()
main()