forked from pinterest/mysql_utils
-
Notifications
You must be signed in to change notification settings - Fork 2
/
find_shard_mismatches.py
executable file
·92 lines (73 loc) · 3.29 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
#!/usr/bin/env python
import argparse
from lib import host_utils
from lib import mysql_lib
def main():
description = ("MySQL orpahned shard detector\n\n"
"This utility will attempt to find orphaned databases "
"across sharddb and modsharddb")
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 orphan in orphaned:
print 'Orphan dbs {host} {dbs}'.format(host=orphan,
dbs=','.join(orphaned[orphan]))
for orphan in orphaned_but_used:
print 'Orphan but still used dbs {host} {dbs}'.format(host=orphan,
dbs=','.join(orphaned_but_used[orphan]))
for orphan in missing:
print 'Missing dbs {host} {dbs}'.format(host=orphan,
dbs=','.join(missing[orphan]))
if not orphaned and not orphaned_but_used and not missing:
print "No problems found"
def find_shard_mismatches(instance=False):
""" Find shards that are missing or unexpected in modhsarddb and sharddb
Args:
instance - If supplied, only check this instance.
Returns:
orphaned - A dict of unexpected and (according to table statistics)
unused shards. Key is master instance, value is a set.
orphaned_but_used - A dict of unexpected and but used shards.
Data strucutre is the same as orphaned.
missing - A dict of expected but missing shards.
Data strucutre is the same as orphaned.
"""
orphaned = dict()
orphaned_but_used = dict()
missing_shards = dict()
zk = host_utils.MysqlZookeeper()
host_shard_map = zk.get_host_shard_map()
if instance:
new_host_shard_map = dict()
new_host_shard_map[instance.__str__()] = host_shard_map[instance.__str__()]
host_shard_map = new_host_shard_map
for master in host_shard_map:
expected_shards = host_shard_map[master]
instance = host_utils.HostAddr(master)
activity = mysql_lib.get_dbs_activity(instance)
actual_shards = mysql_lib.get_dbs(instance)
unexpected_shards = actual_shards.difference(expected_shards)
missing = expected_shards.difference(actual_shards)
if missing:
missing_shards[master] = expected_shards.difference(actual_shards)
for db in unexpected_shards:
if activity[db]['ROWS_CHANGED'] != 0:
if master not in orphaned_but_used:
orphaned_but_used[master] = set()
orphaned_but_used[master].add(db)
else:
if master not in orphaned:
orphaned[master] = set()
orphaned[master].add(db)
return orphaned, orphaned_but_used, missing_shards
if __name__ == "__main__":
main()