Archery系统调用my2sql读取binlog的功能优化
Archery系统集成了my2sql工具,可以通过此功能分析MysQL的binlog,方便SQL回滚,还可以协助异常分析,定位问题。
优化点
解析后没有SQL语句返回,可能的原因是解析过程中遇到了错误,而系统没有捕获错误,更没有将错误异常返回给操作者。
此处的优化,就是解决这一信息黑洞,排除因解析遇错而导致没有SQL语句。换句话说,优化后,当解析过程中遇到Error或fatal时,定会抛出错误。
代码位置
优化代码文件:..../sql/binlog.py
方法---def my2sql(request):
step 1 定义捕获异常的正则表达式
在以下代码的后面
# 参数转换 cmd_args = my2sql.generate_args2cmd(args)
添加正则表达式
###### 添加个正则表达式,去判断是不是结果中有fatal 或者 error ######例如[2019/01/12 16:37:51] [fatal] context.go:401 start postion(-start-file -start-pos) must less than stop position(-end-file -end-pos) fatal_pattern = r'^(\[)\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}\]\W+\[fatal\]' ######例如[2019/01/12 16:37:51] [error] binlogstreamer.go:77 close sync with err: ERROR 1236 (HY000): A slave with the same server_uuid/server_id as this slave has connected to the master; error_pattern = r'^(\[)\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}\]\W+\[error\]' errmsgs = [] ###2024011201
step 2 通过正则刷选返回的数据
改造前的代码
if n <= num and isinstance(line, str): if line[0:6].upper() in ("INSERT", "DELETE", "UPDATE"): n = n + 1 row_info = {} try: row_info["sql"] = line + ";" except IndexError: row_info["sql"] = line + ";" rows.append(row_info) else: break
改造后的代码
if n <= num and isinstance(line, str): if line[0:6].upper() in ("INSERT", "DELETE", "UPDATE"): n = n + 1 row_info = {} try: row_info["sql"] = line + ";" except IndexError: row_info["sql"] = line + ";" rows.append(row_info) ### start add 利用正则判断,筛选有结果中错误的行数 elif re.search(fatal_pattern,line) or rs.search(error_pattern,line): n = n + 1 errmsgs.append(line + ';') #err_info = {} ###注释掉的这段代码是把错误信息当初SQL信息,打印到前端SQL显示端 #try: # err_info['sql'] = line + ';' #except IndexError: # err_info['sql'] = line + ';' #errmsgs.append(err_info) ##### end else: break
3.异常捕获后,返回
修改前
if rows.__len__() == 0: # 判断是否有异常 stderr = p.stderr.read() if stderr and isinstance(stderr, str): result["status"] = 1 result["msg"] = stderr return HttpResponse(json.dumps(result), content_type="application/json") # 终止子进程
修改后
if rows.__len__() == 0: # 判断是否有异常 stderr = p.stderr.read() if stderr and isinstance(stderr, str): result["status"] = 1 result["msg"] = stderr return HttpResponse(json.dumps(result), content_type="application/json") ###start add 将结果中错误信息返回给前端 if errmsgs.__len__() != 0: result['status'] = 1 result['msg'] = errmsgs return HttpResponse(json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True), content_type='application/json') ### end # 终止子进程