1
+ import MySQLdb
2
+ import logging
3
+ import os
4
+ import time
5
+ import smtplib
6
+ from email .mime .text import MIMEText
7
+ #import _mysql
8
+
9
+ # date : 2016-05-11
10
+ # description: mysql slave Automatic detection slave error and Automatic repair
11
+
12
+
13
+ #发送邮件
14
+ class Servermail ():
15
+ def __init__ (self ):
16
+ self .
Server_user = "[email protected] "
17
+ self .Server_pwd = "ttt88"
18
+ self .Servers = "smtp.exmail.qq.com"
19
+
20
+ def send_user_mail (self ,title ,connect ,tomail ):
21
+ self .connect = connect
22
+ self .title = title
23
+ self .tomail = tomail
24
+
25
+ msg = MIMEText (self .connect )
26
+ msg ["Subject" ] = self .title
27
+ msg ["From" ] = self .Server_user
28
+ msg ["To" ] = ";" .join (self .tomail )
29
+ try :
30
+ with smtplib .SMTP (self .Servers , timeout = 30 ) as s :
31
+ s .login (self .Server_user , self .Server_pwd )#登陆服务器
32
+ s .sendmail (self .Server_user ,self .tomail , msg .as_string ())#发送邮件
33
+ print ("发送成功" )
34
+ except Exception as e :
35
+ print (e )
36
+ print ("发送失败" )
37
+
38
+
39
+ #连接mysql服务器,执行sql
40
+ def mysql_con (sql ):
41
+ try :
42
+ conn = MySQLdb .connect (host = '10.88.88.7' ,user = 'admin' ,port = 3307 ,passwd = 'admin)' ,unix_socket = '/tmp/mysql3.sock' )
43
+ cur = conn .cursor ()
44
+ cur .execute (sql )
45
+ data = cur .fetchone ()
46
+ cur .close ()
47
+ conn .close ()
48
+ return data
49
+ except Exception as e :
50
+ save_check_logs ('数据连接错误' ,e )
51
+
52
+
53
+
54
+ #保存日志
55
+ def save_check_logs (title ,connect ):
56
+ dspath = '/data/backup'
57
+ logname = "{0}/check_slavedb.log" .format (dspath )
58
+ logformat = ('%(asctime)s - %(levelname)s - %(filename)s - %(message)s' )
59
+ logging .basicConfig (level = logging .DEBUG ,format = logformat ,filename = logname ,filemode = 'a' )
60
+ logging .info ('数据库状态:{0} 内容: {1}' .format (title ,connect ))
61
+ s = Servermail ()
62
+
63
+ s .send_user_mail (title ,connect ,mailuser )
64
+
65
+
66
+ #检查主从是否同步
67
+ def check_slave (num = 0 ):
68
+ sql = 'show slave status'
69
+ if num >= 5 :
70
+ title = '修复错误'
71
+ connect = '超过修复最大次数,请登录服务器查看详情'
72
+ save_check_logs (title ,connect )
73
+ return False
74
+ slave_info = mysql_con (sql )
75
+ #print(slave_info)
76
+ if slave_info [10 ] == 'Yes' and slave_info [11 ] == 'Yes' :
77
+ return True
78
+ else :
79
+ #145是表损坏,1062是主键冲突。
80
+ if slave_info [18 ] == 144 or slave_info [18 ] == 145 :
81
+ r_table = slave_info [19 ].split (' ' )
82
+ repair_tables (r_table [2 ],num )
83
+ elif slave_info [18 ] == 1062 :
84
+ skip_primary_id ()
85
+ elif slave_info [18 ] == 126 :
86
+ restart_slave3 ()
87
+ else :
88
+ title = '错误'
89
+ connect = '未知的错误类型,请登录服务器手动修复'
90
+ save_check_logs (title ,connect )
91
+
92
+
93
+
94
+
95
+ #修复损坏的表
96
+ def repair_tables (tables ,num ):
97
+ if tables :
98
+ command = 'cd /data/mysql/ && /usr/local/bin/myisamchk -r -q {0}.MYI' .format (tables )
99
+ print (command )
100
+ status = os .system (command )
101
+ if status == 0 :
102
+ restart_slave3 ()
103
+ num += 1
104
+ new_status = check_slave (num )
105
+ if new_status :
106
+ title = '修复成功'
107
+ connect = '数据修复成功,表名:{0}' .format (tables )
108
+ save_check_logs (title ,connect )
109
+ else :
110
+ title = '修复失败'
111
+ connect = '数据修复失败,表名:{0}' .format (tables )
112
+ save_check_logs (title ,connect )
113
+
114
+
115
+
116
+ #跳过主键冲突的id
117
+ def skip_primary_id ():
118
+ sql = 'stop slave;SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;start slave;'
119
+ sts = mysql_con (sql )
120
+ print (sts )
121
+
122
+
123
+
124
+ #重启数据库实例
125
+ def restart_slave3 ():
126
+ os .system ('/usr/local/bin/mysqld_multi stop 3' )
127
+ time .sleep (2 )
128
+ os .system ('/usr/local/bin/mysqld_multi start 3' )
129
+ time .sleep (3 )
130
+
131
+
132
+
133
+
134
+ if __name__ == '__main__' :
135
+ check_slave ()
0 commit comments