前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 持续查杀符合条件的sql会话

python 持续查杀符合条件的sql会话

原创
作者头像
保持热爱奔赴山海
发布2024-07-04 15:59:06
1140
发布2024-07-04 15:59:06
举报
文章被收录于专栏:数据库相关数据库相关

生产上,某些情况下,可能会出现异常sql大量查询数据库,占用大量的cpu或者磁盘IO,这种情况下需要适当的止损。

如果有proxy的话,一般可以在proxy层面通过sql指纹进行限流或者熔断(例如proxysql就可以对指定的sql指纹进行阻断)。

如果没有proxy,则可以考虑在数据库层面添加持续kill会话的脚本,

下面就是一个持续kill符合条件的sql会话的例子:

代码语言:txt
复制
import datetime
import time as t_time

import mysql.connector


def kill_sessions(instance_host, instance_port, user, passwd, kill_condition, interval, time_range):
    try:
        mydb = mysql.connector.connect(
            host=instance_host,
            port=instance_port,
            user=user,
            passwd=passwd,
            ssl_disabled=True,
        )
    except Exception as e:
        print(f"Error initializing connection: {e}")

    start_time = t_time.time()
    while True:
        current_time = t_time.time()
        elapsed_time = current_time - start_time  # 计算已经过去的时间
        # 如果已经超过time_range指定的秒数,则退出循环
        if elapsed_time > time_range:
            print("已运行超过指定的阈值,退出循环。")
            break

        try:
            # 查询活动会话
            sql = ("SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO "
                   "FROM information_schema.processlist "
                   "WHERE 1=1 AND ID != CONNECTION_ID() and " + kill_condition)

            cursor = mydb.cursor()
            cursor.execute(sql)
            processes = cursor.fetchall()

            for process in processes:
                id, user, host, db, command, time, state, info = process
                if True:
                    print(
                        f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}, "
                        f"ID: {id},user: {user},host:{host},db: {db}, Command: {command},"
                        f"state: {state},Time: {time}s, Info: {info}")
                    try:
                        kill_query = f"KILL {id}"
                        cursor.execute(kill_query)
                    except Exception as e:
                        print(str(e))
        except mysql.connector.Error as err:
            print(f"Database error: {err}")
            
        t_time.sleep(interval)


if __name__ == "__main__":
    kill_sessions('192.168.31.181',
                  3306,
                  'dts',
                  '123456',
                  "time > 1 and info like '%select%sleep%' ",
                  0.5,
                  60)


"""
在celery里面的入参例子
对sql模糊匹配 select%t_order%desc 的,执行kill操作,每次检测间隔0.5秒,持续60秒
注意:
1、interval不能太低,information_schema.processlist表高频查询会导致性能问题
2、user需要配置成最高权限的账号(或者是慢查询对应的业务账号),否则可能出现kill失败,报错提示not thread owner

{
    "instance_host": "192.168.31.181",
    "instance_port": 3306,
    "user": "dts",
    "passwd": "dts",
    "kill_condition": "time > 1 and info like '%select%t_order%desc%' ",
    "interval": 0.5,
    "time_range": 60
}
"""

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档