diff --git a/sql/engines/mysql.py b/sql/engines/mysql.py index 7ab5cfe..266b609 100644 --- a/sql/engines/mysql.py +++ b/sql/engines/mysql.py @@ -872,3 +872,29 @@ def close(self): if self.conn: self.conn.close() self.conn = None + + def get_review_status_summary(self, checksum): + """sql优化详情功能,获取checksum对应的sql优化详情""" + sql_review_summary = f"""select reviewed_by,reviewed_on,comments,reviewed_status from archery.mysql_slow_query_review where checksum='{checksum}';""" + query_result = self.query("mysql", sql_review_summary) + if not query_result.error: + review_summary = query_result.rows + rows = [] + row = { + "checksum": checksum, + "reviewed_by": review_summary[0][0], + "reviewed_on": review_summary[0][1], + "comments": review_summary[0][2], + "reviewed_status": review_summary[0][3], + } + rows.append(row) + query_result.rows = rows + self.close() + return query_result + + def set_review_details(self, checksum, reviewed_by, reviewed_on, comments, reviewed_status): + """sql优化详情功能,获取checksum对应的sql优化详情""" + sql_update_review = f"""update archery.mysql_slow_query_review set reviewed_by='{reviewed_by}',reviewed_on='{reviewed_on}',comments='{comments}',reviewed_status='{reviewed_status}' where checksum='{checksum}';""" + exec_result = self.query("mysql", sql_update_review) + self.close() + return exec_result \ No newline at end of file diff --git a/sql/manual_review.py b/sql/manual_review.py new file mode 100644 index 0000000..312b12a --- /dev/null +++ b/sql/manual_review.py @@ -0,0 +1,81 @@ +# -*- coding: UTF-8 -*- +import logging +import traceback +import MySQLdb +import pymysql +import re + + + +# -*- coding: UTF-8 -*- + +import simplejson as json +from django.contrib.auth.decorators import permission_required + + +from django.http import HttpResponse, JsonResponse +from sql.utils.instance_management import ( + SUPPORTED_MANAGEMENT_DB_TYPE, +) +from common.utils.extend_json_encoder import ExtendJSONEncoder +from sql.engines import get_engine, ResultSet +from sql.utils.resource_group import user_instances +from .models import Instance, InstanceAccount + +from sql.engines.mysql import MysqlEngine + + + +@permission_required("sql.menu_slowquery", raise_exception=True) +def listreview(request): + """获取优化详情列表""" + checksum = request.POST.get("review_checksum") + + if not checksum: + return JsonResponse({"status": 0, "msg": "", "data": []}) + try: + instance = user_instances( + request.user, db_type=SUPPORTED_MANAGEMENT_DB_TYPE + ).get(instance_name="archery_internal") + except Instance.DoesNotExist: + return JsonResponse({"status": 1, "msg": "你所在组未关联该实例", "data": []}) + + #获取checksum对应的优化详情 + query_engine = MysqlEngine(instance=instance) + query_result = query_engine.get_review_status_summary(checksum) + if not query_result.error: + rows = query_result.rows + result = {"status": 0, "msg": "ok", "rows": rows} + else: + result = {"status": 1, "msg": query_result.error} + return HttpResponse( + json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True), + content_type="application/json", + ) + +@permission_required("sql.menu_slowquery", raise_exception=True) +def editreview(request): + """编辑优化详情""" + checksum = request.POST.get("checksum") + reviewed_by = request.POST.get("reviewed_by", "") + reviewed_on = request.POST.get("reviewed_on", "") + comments = request.POST.get("comments", "") + reviewed_status = request.POST.get("reviewed_status", "") + + if ( + not all([checksum, reviewed_by, reviewed_on, comments,reviewed_status]) + ): + return JsonResponse({"status": 1, "msg": "参数不完整,请确认后提交", "data": []}) + + try: + instance = user_instances( + request.user, db_type=SUPPORTED_MANAGEMENT_DB_TYPE + ).get(instance_name="archery_internal") + except Instance.DoesNotExist: + return JsonResponse({"status": 1, "msg": "你所在组未关联该实例", "data": []}) + + exec_engine = MysqlEngine(instance=instance) + exec_result = exec_engine.set_review_details( + checksum=checksum, reviewed_by=reviewed_by, reviewed_on=reviewed_on,comments=comments,reviewed_status=reviewed_status + ) + return JsonResponse({"status": 0, "msg": "", "data": []}) diff --git a/sql/models.py b/sql/models.py index 16aaef6..815d60f 100644 --- a/sql/models.py +++ b/sql/models.py @@ -921,6 +921,7 @@ class SlowQuery(models.Model): reviewed_by = models.CharField(max_length=20, blank=True, null=True) reviewed_on = models.DateTimeField(blank=True, null=True) comments = models.TextField(blank=True, null=True) + reviewed_status = models.CharField(max_length=24, blank=True, null=True) class Meta: managed = False diff --git a/sql/slowlog.py b/sql/slowlog.py index 624520b..a651b61 100644 --- a/sql/slowlog.py +++ b/sql/slowlog.py @@ -67,8 +67,8 @@ def slowquery_review(request): fingerprint__icontains=search, **filter_kwargs ) - .annotate(SQLText=F("fingerprint"), SQLId=F("checksum")) - .values("SQLText", "SQLId") + .annotate(SQLText=F("fingerprint"), SQLId=F("checksum"), ReviewedBy=F("reviewed_by"), ReviewedOn=F("reviewed_on"), Comments=F("comments"), ReviewedStatus=F("reviewed_status")) + .values("SQLText", "SQLId", "ReviewedBy", "ReviewedOn", "Comments", "ReviewedStatus") .annotate( CreateTime=Max("slowqueryhistory__ts_max"), DBName=Max("slowqueryhistory__db_max"), # 数据库 @@ -157,6 +157,7 @@ def slowquery_review_history(request): sample__icontains=search, **filter_kwargs ).annotate( + SQLChecksum=F("checksum"), # SQL语句校验和 ExecutionStartTime=F("ts_min"), # 本次统计(每5分钟一次)该类型sql语句出现的最小时间 DBName=F("db_max"), # 数据库名 HostAddress=Concat( @@ -175,6 +176,7 @@ def slowquery_review_history(request): slow_sql_record_list = slow_sql_record_obj.order_by( "-" + sortName if "desc".__eq__(sortOrder) else sortName )[offset:limit].values( + "SQLChecksum", "ExecutionStartTime", "DBName", "HostAddress", diff --git a/sql/templates/slowquery.html b/sql/templates/slowquery.html index 0219c89..3225390 100644 --- a/sql/templates/slowquery.html +++ b/sql/templates/slowquery.html @@ -4,6 +4,7 @@