Esempio n. 1
0
def optimize_soar(request):
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('db_name')
    sql = request.POST.get('sql')
    result = {'status': 0, 'msg': 'ok', 'data': []}

    # 服务器端参数验证
    if not (instance_name and db_name and sql):
        result['status'] = 1
        result['msg'] = '页面提交参数可能为空'
        return HttpResponse(json.dumps(result), content_type='application/json')
    try:
        user_instances(request.user, type='all', db_type='mysql').get(instance_name=instance_name)
    except Exception:
        result['status'] = 1
        result['msg'] = '你所在组未关联该实例'
        return HttpResponse(json.dumps(result), content_type='application/json')

    # 检查测试实例的连接信息和soar程序路径
    soar_test_dsn = SysConfig().get('soar_test_dsn')
    soar_path = SysConfig().get('soar')
    if not (soar_path and soar_test_dsn):
        result['status'] = 1
        result['msg'] = '请配置soar_path和test_dsn!'
        return HttpResponse(json.dumps(result), content_type='application/json')

    # 目标实例的连接信息
    instance_info = Instance.objects.get(instance_name=instance_name)
    online_dsn = "{user}:{pwd}@{host}:{port}/{db}".format(user=instance_info.user,
                                                          pwd=instance_info.raw_password,
                                                          host=instance_info.host,
                                                          port=instance_info.port,
                                                          db=db_name)

    # 提交给soar获取分析报告
    soar = Soar()
    # 准备参数
    args = {"online-dsn": online_dsn,
            "test-dsn": soar_test_dsn,
            "allow-online-as-test": "false",
            "report-type": "markdown",
            "query": sql.strip().replace('"', '\\"').replace('`', '').replace('\n', ' ')
            }
    # 参数检查
    args_check_result = soar.check_args(args)
    if args_check_result['status'] == 1:
        return HttpResponse(json.dumps(args_check_result), content_type='application/json')
    # 参数转换
    cmd_args = soar.generate_args2cmd(args, shell=True)
    # 执行命令
    try:
        stdout, stderr = soar.execute_cmd(cmd_args, shell=True).communicate()
        result['data'] = stdout if stdout else stderr
    except RuntimeError as e:
        result['status'] = 1
        result['msg'] = str(e)
    return HttpResponse(json.dumps(result), content_type='application/json')
Esempio n. 2
0
def soar(request):
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('db_name')
    sql = request.POST.get('sql')
    result = {'status': 0, 'msg': 'ok', 'data': []}

    # 服务器端参数验证
    if not (instance_name and db_name and sql):
        result['status'] = 1
        result['msg'] = '页面提交参数可能为空'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')
    try:
        user_instances(request.user, 'all').get(instance_name=instance_name)
    except Exception:
        result['status'] = 1
        result['msg'] = '你所在组未关联该实例'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    sql = sql.strip().replace('"', '\\"').replace('`', '').replace('\n', ' ')
    # 目标实例的连接信息
    instance_info = Instance.objects.get(instance_name=instance_name)
    online_dsn = "{user}:{pwd}@{host}:{port}/{db}".format(
        user=instance_info.user,
        pwd=instance_info.raw_password,
        host=instance_info.host,
        port=instance_info.port,
        db=db_name)
    # 获取测试实例的连接信息和soar程序路径
    soar_cfg = Soar()
    test_dsn = soar_cfg.soar_test_dsn
    soar_path = soar_cfg.soar_path
    if not (soar_path and test_dsn):
        result['status'] = 1
        result['msg'] = '请配置soar_path和test_dsn!'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    # 提交给soar获取分析报告
    try:
        p = subprocess.Popen(
            soar_path + ' -allow-online-as-test=false -report-type=markdown' +
            ' -query "{}" -online-dsn "{}" -test-dsn "{}" '.format(
                sql.strip(), online_dsn, test_dsn),
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=True,
            universal_newlines=True)
        stdout, stderr = p.communicate()
        result['data'] = stdout
    except Exception:
        logger.error(traceback.format_exc())
        result['data'] = 'soar运行报错,请检查相关日志'
    return HttpResponse(json.dumps(result), content_type='application/json')
Esempio n. 3
0
def optimize_sqladvisor(request):
    sql_content = request.POST.get('sql_content')
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('db_name')
    verbose = request.POST.get('verbose', 1)
    result = {'status': 0, 'msg': 'ok', 'data': []}

    # 服务器端参数验证
    if sql_content is None or instance_name is None:
        result['status'] = 1
        result['msg'] = '页面提交参数可能为空'
        return HttpResponse(json.dumps(result), content_type='application/json')

    try:
        user_instances(request.user, type='all', db_type='mysql').get(instance_name=instance_name)
    except Exception:
        result['status'] = 1
        result['msg'] = '你所在组未关联该实例!'
        return HttpResponse(json.dumps(result), content_type='application/json')

    # 检查sqladvisor程序路径
    sqladvisor_path = SysConfig().get('sqladvisor')
    if sqladvisor_path is None:
        result['status'] = 1
        result['msg'] = '请配置SQLAdvisor路径!'
        return HttpResponse(json.dumps(result), content_type='application/json')

    # 取出实例的连接信息
    instance_info = Instance.objects.get(instance_name=instance_name)

    # 提交给sqladvisor获取分析报告
    sqladvisor = SQLAdvisor()
    # 准备参数
    args = {"h": instance_info.host,
            "P": instance_info.port,
            "u": instance_info.user,
            "p": instance_info.raw_password,
            "d": db_name,
            "v": verbose,
            "q": sql_content.strip().replace('"', '\\"').replace('`', '').replace('\n', ' ')
            }

    # 参数检查
    args_check_result = sqladvisor.check_args(args)
    if args_check_result['status'] == 1:
        return HttpResponse(json.dumps(args_check_result), content_type='application/json')
    # 参数转换
    cmd_args = sqladvisor.generate_args2cmd(args, shell=True)
    # 执行命令
    try:
        stdout, stderr = sqladvisor.execute_cmd(cmd_args, shell=True).communicate()
        result['data'] = f'{stdout}{stderr}'
    except RuntimeError as e:
        result['status'] = 1
        result['msg'] = str(e)
    return HttpResponse(json.dumps(result), content_type='application/json')
Esempio n. 4
0
def sqladvisor(request):
    sql_content = request.POST.get('sql_content')
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('db_name')
    verbose = request.POST.get('verbose')
    result = {'status': 0, 'msg': 'ok', 'data': []}

    # 服务器端参数验证
    if sql_content is None or instance_name is None:
        result['status'] = 1
        result['msg'] = '页面提交参数可能为空'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    sql_content = sql_content.strip()

    try:
        user_instances(request.user, 'all').get(instance_name=instance_name)
    except Exception:
        result['status'] = 1
        result['msg'] = '你所在组未关联该实例!'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    if verbose is None or verbose == '':
        verbose = 1

    # 取出实例的连接信息
    instance_info = Instance.objects.get(instance_name=instance_name)

    # 提交给sqladvisor获取审核结果
    sqladvisor_path = SysConfig().sys_config.get('sqladvisor')
    sql_content = sql_content.strip().replace('"',
                                              '\\"').replace('`', '').replace(
                                                  '\n', ' ')
    try:
        p = subprocess.Popen(
            sqladvisor_path +
            ' -h "%s" -P "%s" -u "%s" -p "%s\" -d "%s" -v %s -q "%s"' %
            (str(instance_info.host), str(
                instance_info.port), str(instance_info.user),
             str(Prpcrypt().decrypt(instance_info.password), ), str(db_name),
             verbose, sql_content),
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=True,
            universal_newlines=True)
        stdout, stderr = p.communicate()
        result['data'] = stdout
    except Exception:
        logger.error(traceback.format_exc())
        result['data'] = 'sqladvisor运行报错,请检查日志'
    return HttpResponse(json.dumps(result), content_type='application/json')
Esempio n. 5
0
def edit(request):
    """编辑/录入数据库"""
    instance_id = request.POST.get('instance_id', 0)
    db_name = request.POST.get('db_name')
    owner = request.POST.get('owner', '')
    remark = request.POST.get('remark', '')

    if not all([db_name]):
        return JsonResponse({'status': 1, 'msg': '参数不完整,请确认后提交', 'data': []})

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    try:
        owner_display = Users.objects.get(username=owner).display
    except Users.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '负责人不存在', 'data': []})

    # 更新或者录入信息
    InstanceDatabase.objects.update_or_create(
        instance=instance,
        db_name=db_name,
        defaults={"owner": owner, "owner_display": owner_display, "remark": remark})
    return JsonResponse({'status': 0, 'msg': '', 'data': []})
Esempio n. 6
0
def kill_session(request):
    instance_name = request.POST.get('instance_name')
    thread_ids = request.POST.get('ThreadIDs')
    result = {'status': 0, 'msg': 'ok', 'data': []}

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(instance_name=instance_name)
    except Instance.DoesNotExist:
        result = {'status': 1, 'msg': '你所在组未关联该实例', 'data': []}
        return HttpResponse(json.dumps(result), content_type='application/json')

    # 判断是RDS还是其他实例
    if AliyunRdsConfig.objects.filter(instance=instance, is_enable=True).exists():
        result = aliyun_kill_session(request)
    else:
        thread_ids = thread_ids.replace('[', '').replace(']', '')
        engine = get_engine(instance=instance)
        sql = "select concat('kill ', id, ';') from information_schema.processlist where id in ({});".format(thread_ids)
        all_kill_sql = engine.query('information_schema', sql)
        kill_sql = ''
        for row in all_kill_sql.rows:
            kill_sql = kill_sql + row[0]
        engine.execute('information_schema', kill_sql)

    # 返回查询结果
    return HttpResponse(json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True),
                        content_type='application/json')
Esempio n. 7
0
def create(request):
    """创建数据库"""
    instance_id = request.POST.get('instance_id', 0)
    db_name = request.POST.get('db_name')
    owner = request.POST.get('owner', '')
    remark = request.POST.get('remark', '')

    if not all([db_name]):
        return JsonResponse({'status': 1, 'msg': '参数不完整,请确认后提交', 'data': []})

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    try:
        owner_display = Users.objects.get(username=owner).display
    except Users.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '负责人不存在', 'data': []})

    engine = get_engine(instance=instance)
    exec_result = engine.execute(db_name='information_schema', sql=f"create database {db_name};")
    if exec_result.error:
        return JsonResponse({'status': 1, 'msg': exec_result.error})
    # 保存到数据库
    else:
        InstanceDatabase.objects.create(
            instance=instance, db_name=db_name, owner=owner, owner_display=owner_display, remark=remark)
    return JsonResponse({'status': 0, 'msg': '', 'data': []})
Esempio n. 8
0
def lock(request):
    """锁定/解锁账号"""
    instance_id = request.POST.get('instance_id', 0)
    user_host = request.POST.get('user_host')
    is_locked = request.POST.get('is_locked')
    lock_sql = ''

    if not all([user_host]):
        return JsonResponse({'status': 1, 'msg': '参数不完整,请确认后提交', 'data': []})

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    # escape
    user_host = MySQLdb.escape_string(user_host).decode('utf-8')

    if is_locked == 'N':
        lock_sql = f"ALTER USER {user_host} ACCOUNT LOCK;"
    elif is_locked == 'Y':
        lock_sql = f"ALTER USER {user_host} ACCOUNT UNLOCK;"

    engine = get_engine(instance=instance)
    exec_result = engine.execute(db_name='mysql', sql=lock_sql)
    if exec_result.error:
        return JsonResponse({'status': 1, 'msg': exec_result.error})
    return JsonResponse({'status': 0, 'msg': '', 'data': []})
Esempio n. 9
0
def instance_param(request):
    # 获取用户关联实例列表
    instances = user_instances(request.user,
                               type='all',
                               db_type=['mysql', 'inception', 'goinception'])
    context = {'tab': 'param_tab', 'instances': instances}
    return render(request, 'param.html', context)
def edit(request):
    """修改、录入数据库账号"""
    instance_id = request.POST.get('instance_id', 0)
    user = request.POST.get('user')
    host = request.POST.get('host')
    password = request.POST.get('password')
    remark = request.POST.get('remark', '')

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    if not all([user, host]):
        return JsonResponse({'status': 1, 'msg': '参数不完整,请确认后提交', 'data': []})

    # 保存到数据库
    if password:
        InstanceAccount.objects.update_or_create(
            instance=instance, user=user, host=host,
            defaults={
                "password": password,
                "remark": remark
            }
        )
    else:
        InstanceAccount.objects.update_or_create(
            instance=instance, user=user, host=host,
            defaults={
                "remark": remark
            }
        )
    return JsonResponse({'status': 0, 'msg': '', 'data': []})
Esempio n. 11
0
def binlog2sql(request):
    # 获取实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]
    return render(request, 'binlog2sql.html', {'instances': instances})
Esempio n. 12
0
def schemasync(request):
    # 获取实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]
    return render(request, 'schemasync.html', {'instances': instances})
def delete(request):
    """删除账号"""
    instance_id = request.POST.get('instance_id', 0)
    user_host = request.POST.get('user_host')
    user = request.POST.get('user')
    host = request.POST.get('host')

    if not all([user_host]):
        return JsonResponse({'status': 1, 'msg': '参数不完整,请确认后提交', 'data': []})

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    # escape
    user_host = MySQLdb.escape_string(user_host).decode('utf-8')

    engine = get_engine(instance=instance)
    exec_result = engine.execute(db_name='information_schema', sql=f"DROP USER {user_host};")
    if exec_result.error:
        return JsonResponse({'status': 1, 'msg': exec_result.error})
    # 删除数据库对应记录
    else:
        InstanceAccount.objects.filter(instance=instance, user=user, host=host).delete()
    return JsonResponse({'status': 0, 'msg': '', 'data': []})
Esempio n. 14
0
def process(request):
    instance_name = request.POST.get('instance_name')
    command_type = request.POST.get('command_type')

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(instance_name=instance_name)
    except Instance.DoesNotExist:
        result = {'status': 1, 'msg': '你所在组未关联该实例', 'data': []}
        return HttpResponse(json.dumps(result), content_type='application/json')

    base_sql = "select id, user, host, db, command, time, state, ifnull(info,'') as info from information_schema.processlist"
    # 判断是RDS还是其他实例
    if AliyunRdsConfig.objects.filter(instance=instance, is_enable=True).exists():
        result = aliyun_process_status(request)
    else:
        if command_type == 'All':
            sql = base_sql + ";"
        elif command_type == 'Not Sleep':
            sql = "{} where command<>'Sleep';".format(base_sql)
        else:
            sql = "{} where command= '{}';".format(base_sql, command_type)
        query_engine = get_engine(instance=instance)
        query_result = query_engine.query('information_schema', sql)
        if not query_result.error:
            processlist = query_result.to_dict()
            result = {'status': 0, 'msg': 'ok', 'rows': processlist}
        else:
            result = {'status': 1, 'msg': query_result.error}
    # 返回查询结果
    return HttpResponse(json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True),
                        content_type='application/json')
Esempio n. 15
0
def databases(request):
    """获取实例数据库列表"""
    instance_id = request.POST.get('instance_id')
    saved = True if request.POST.get('saved') == 'true' else False  # 平台是否保存

    if not instance_id:
        return JsonResponse({'status': 0, 'msg': '', 'data': []})

    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    # 获取已录入数据库
    cnf_dbs = dict()
    for db in InstanceDatabase.objects.filter(
            instance=instance).values('id', 'db_name', 'owner', 'owner_display', 'remark'):
        db['saved'] = True
        cnf_dbs[f"{db['db_name']}"] = db

    # 获取所有数据库
    sql_get_db = """SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME 
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql', 'test', 'sys');"""
    query_engine = get_engine(instance=instance)
    query_result = query_engine.query('information_schema', sql_get_db, close_conn=False)
    if not query_result.error:
        dbs = query_result.rows
        # 获取数据库关联用户信息
        rows = []
        for db in dbs:
            db_name = db[0]
            sql_get_bind_users = f"""select group_concat(distinct(GRANTEE)),TABLE_SCHEMA
from information_schema.SCHEMA_PRIVILEGES
where TABLE_SCHEMA='{db_name}'
group by TABLE_SCHEMA;"""
            bind_users = query_engine.query('information_schema', sql_get_bind_users, close_conn=False).rows
            row = {
                'db_name': db_name,
                'charset': db[1],
                'collation': db[2],
                'grantees': bind_users[0][0].split(',') if bind_users else [],
                'saved': False
            }
            # 合并数据
            if db_name in cnf_dbs.keys():
                row = dict(row, **cnf_dbs[db_name])
            rows.append(row)
        # 过滤参数
        if saved:
            rows = [row for row in rows if row['saved']]

        result = {'status': 0, 'msg': 'ok', 'rows': rows}
    else:
        result = {'status': 1, 'msg': query_result.error}

    # 关闭连接
    query_engine.close()
    return HttpResponse(json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True),
                        content_type='application/json')
Esempio n. 16
0
def optimize_sqltuning(request):
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('db_name')
    sqltext = request.POST.get('sql_content')
    option = request.POST.getlist('option[]')
    sqltext = sqlparse.format(sqltext, strip_comments=True)
    sqltext = sqlparse.split(sqltext)[0]
    if re.match(r"^select|^show|^explain", sqltext, re.I) is None:
        result = {'status': 1, 'msg': '只支持查询SQL!', 'data': []}
        return HttpResponse(json.dumps(result),
                            content_type='application/json')
    try:
        user_instances(request.user).get(instance_name=instance_name)
    except Instance.DoesNotExist:
        result = {'status': 1, 'msg': '你所在组未关联该实例!', 'data': []}
        return HttpResponse(json.dumps(result),
                            content_type='application/json')
    # escape
    db_name = MySQLdb.escape_string(db_name).decode('utf-8')

    sql_tunning = SqlTuning(instance_name=instance_name,
                            db_name=db_name,
                            sqltext=sqltext)
    result = {'status': 0, 'msg': 'ok', 'data': {}}
    if 'sys_parm' in option:
        basic_information = sql_tunning.basic_information()
        sys_parameter = sql_tunning.sys_parameter()
        optimizer_switch = sql_tunning.optimizer_switch()
        result['data']['basic_information'] = basic_information
        result['data']['sys_parameter'] = sys_parameter
        result['data']['optimizer_switch'] = optimizer_switch
    if 'sql_plan' in option:
        plan, optimizer_rewrite_sql = sql_tunning.sqlplan()
        result['data']['optimizer_rewrite_sql'] = optimizer_rewrite_sql
        result['data']['plan'] = plan
    if 'obj_stat' in option:
        result['data']['object_statistics'] = sql_tunning.object_statistics()
    if 'sql_profile' in option:
        session_status = sql_tunning.exec_sql()
        result['data']['session_status'] = session_status
    # 关闭连接
    sql_tunning.engine.close()
    result['data']['sqltext'] = sqltext
    return HttpResponse(json.dumps(result,
                                   cls=ExtendJSONEncoder,
                                   bigint_as_string=True),
                        content_type='application/json')
Esempio n. 17
0
def sqlquery(request):
    # 获取实例支持查询的标签id
    tag_id = InstanceTag.objects.get(tag_code='can_read').id
    # 获取用户关联实例列表
    instances = [slave for slave in user_instances(request.user, type='all', db_type='all', tags=[tag_id])]

    context = {'instances': instances}
    return render(request, 'sqlquery.html', context)
Esempio n. 18
0
def sqlquery(request):
    # 获取用户关联实例列表
    instances = [
        slave.instance_name for slave in user_instances(request.user, 'slave')
    ]

    context = {'instances': instances}
    return render(request, 'sqlquery.html', context)
Esempio n. 19
0
def sqlanalyze(request):
    """SQL分析页面"""
    # 获取实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]
    return render(request, 'sqlanalyze.html', {'instances': instances})
Esempio n. 20
0
def sqlquery(request):
    # 获取用户关联实例列表
    instances = [
        slave
        for slave in user_instances(request.user, type='slave', db_type='all')
    ]

    context = {'instances': instances}
    return render(request, 'sqlquery.html', context)
Esempio n. 21
0
def sqlanalyze(request):
    """
    SQL分析页面
    :param request:
    :return:
    """
    # 获取实例列表
    instances = [instance.instance_name for instance in user_instances(request.user, 'all')]
    return render(request, 'sqlanalyze.html', {'instances': instances})
Esempio n. 22
0
def users(request):
    """获取实例用户列表"""
    instance_id = request.POST.get('instance_id')
    saved = True if request.POST.get('saved') == 'true' else False  # 平台是否保存

    if not instance_id:
        return JsonResponse({'status': 0, 'msg': '', 'data': []})
    try:
        instance = user_instances(request.user, db_type=['mysql']).get(id=instance_id)
    except Instance.DoesNotExist:
        return JsonResponse({'status': 1, 'msg': '你所在组未关联该实例', 'data': []})

    # 获取已录入用户
    cnf_users = dict()
    for user in InstanceAccount.objects.filter(instance=instance).values('id', 'user', 'host', 'remark'):
        user['saved'] = True
        cnf_users[f"`{user['user']}`@`{user['host']}`"] = user
    # 获取所有用户
    query_engine = get_engine(instance=instance)
    server_version = query_engine.server_version
    # MySQL 5.7.6版本起支持ACCOUNT LOCK
    if server_version >= (5, 7, 6):
        sql_get_user = "******"
    else:
        sql_get_user = "******"
    query_result = query_engine.query('mysql', sql_get_user)
    if not query_result.error:
        db_users = query_result.rows
        # 获取用户权限信息
        rows = []
        for db_user in db_users:
            user_host = db_user[0]
            user_priv = query_engine.query('mysql', 'show grants for {};'.format(user_host), close_conn=False).rows
            row = {
                'user_host': user_host,
                'user': db_user[1],
                'host': db_user[2],
                'privileges': user_priv,
                'saved': False,
                'is_locked': db_user[3] if server_version >= (5, 7, 6) else None
            }
            # 合并数据
            if user_host in cnf_users.keys():
                row = dict(row, **cnf_users[user_host])
            rows.append(row)
        # 过滤参数
        if saved:
            rows = [row for row in rows if row['saved']]

        result = {'status': 0, 'msg': 'ok', 'rows': rows}
    else:
        result = {'status': 1, 'msg': query_result.error}

    # 关闭连接
    query_engine.close()
    return HttpResponse(json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True),
                        content_type='application/json')
Esempio n. 23
0
def archive(request):
    """归档列表页面"""
    # 获取资源组
    group_list = user_groups(request.user)
    ins_list = user_instances(request.user, db_type=['mysql'])
    return render(request, 'archive.html', {
        'group_list': group_list,
        'ins_list': ins_list
    })
Esempio n. 24
0
def dbdiagnostic(request):
    # 获取用户关联实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]

    context = {'tab': 'process', 'instances': instances}
    return render(request, 'dbdiagnostic.html', context)
Esempio n. 25
0
def sqladvisor(request):
    # 获取用户关联实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]

    context = {'instances': instances}
    return render(request, 'sqladvisor.html', context)
Esempio n. 26
0
def slowquery(request):
    # 获取用户关联实例列表
    instances = [
        instance.instance_name
        for instance in user_instances(request.user, 'all')
    ]

    context = {'tab': 'slowquery', 'instances': instances}
    return render(request, 'slowquery.html', context)
Esempio n. 27
0
def optimize_sqltuningadvisor(request):
    """
    sqltuningadvisor工具获取优化报告
    :param request:
    :return:
    """
    sql_content = request.POST.get('sql_content')
    instance_name = request.POST.get('instance_name')
    db_name = request.POST.get('schema_name')
    result = {'status': 0, 'msg': 'ok', 'data': []}

    # 服务器端参数验证
    if sql_content is None or instance_name is None:
        result['status'] = 1
        result['msg'] = '页面提交参数可能为空'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    try:
        instance = user_instances(
            request.user).get(instance_name=instance_name)
    except Instance.DoesNotExist:
        result = {'status': 1, 'msg': '实例不存在', 'data': []}
        return HttpResponse(json.dumps(result),
                            content_type='application/json')

    # 不删除注释语句,已获取加hints的SQL优化建议,进行语法判断,执行第一条有效sql
    sql_content = sqlparse.format(sql_content.strip(), strip_comments=False)
    # 对单引号加转义符,支持plsql语法
    sql_content = sql_content.replace("'", "''")
    try:
        sql_content = sqlparse.split(sql_content)[0]
    except IndexError:
        result['status'] = 1
        result['msg'] = '没有有效的SQL语句'
        return HttpResponse(json.dumps(result),
                            content_type='application/json')
    else:
        # 过滤非Oracle语句
        if not instance.db_type == 'oracle':
            result['status'] = 1
            result['msg'] = 'SQLTuningAdvisor仅支持oracle数据库的检查'
            return HttpResponse(json.dumps(result),
                                content_type='application/json')

    # 执行获取优化报告
    query_engine = get_engine(instance=instance)
    sql_result = query_engine.sqltuningadvisor(str(db_name),
                                               sql_content).to_sep_dict()
    result['data'] = sql_result

    # 返回查询结果
    return HttpResponse(json.dumps(result,
                                   cls=ExtendJSONEncoder,
                                   bigint_as_string=True),
                        content_type='application/json')
Esempio n. 28
0
def user_all_instances(request):
    """获取用户所有实例列表(通过资源组间接关联)"""
    user = request.user
    type = request.GET.get('type')
    db_type = request.GET.getlist('db_type[]')
    tag_codes = request.GET.getlist('tag_codes[]')
    instances = user_instances(user, type, db_type, tag_codes).values('id', 'type', 'db_type', 'instance_name')
    rows = [row for row in instances]
    result = {'status': 0, 'msg': 'ok', "data": rows}
    return HttpResponse(json.dumps(result), content_type='application/json')
Esempio n. 29
0
def slowquery(request):
    """SQL慢日志页面"""
    # 获取用户关联实例列表
    instances = [
        instance.instance_name for instance in user_instances(
            request.user, type='all', db_type='mysql')
    ]

    context = {'tab': 'slowquery', 'instances': instances}
    return render(request, 'slowquery.html', context)
Esempio n. 30
0
def archive(request):
    """归档列表页面"""
    # 获取资源组
    group_list = user_groups(request.user)
    ins_list = user_instances(request.user, db_type=['mysql']).order_by(
        Convert('instance_name', 'gbk').asc())
    return render(request, 'archive.html', {
        'group_list': group_list,
        'ins_list': ins_list
    })