Skip to content

Commit

Permalink
chore(database): use root user for db processlist and kill process
Browse files Browse the repository at this point in the history
  • Loading branch information
tanmoysrt committed Dec 20, 2024
1 parent b54a098 commit ea7abae
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
16 changes: 15 additions & 1 deletion agent/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def fetch_process_list(self):
return []
return [
{
"id": record["Id"],
"id": str(record["Id"]),
"command": record["Command"],
"query": record["Info"],
"state": record["State"],
Expand All @@ -394,10 +394,24 @@ def fetch_process_list(self):
"db_user_host": record["Host"].split(":")[0],
}
for record in result[0]["output"]
if record["db"] == self.database_name
]

def kill_process(self, pid: str):
with contextlib.suppress(Exception):
processes = self.fetch_process_list()
"""
It's important to validate whether the pid belongs to the current database
As we are running it as `root` user, it can be possible to kill processes from other databases
by forging the request
"""
isFound = False
for process in processes:
if process.get("id") == pid:
isFound = True
break
if not isFound:
return
"""
The query can fail if the process is already killed.
Anyway we need to reload the process list after killing to verify if the process is killed.
Expand Down
13 changes: 4 additions & 9 deletions agent/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,11 +887,6 @@ def run_sql_query(self, query: str, commit: bool = False, as_dict: bool = False)
response["failed_query"] = db.last_executed_query
return response

@job("Analyze Slow Queries")
def analyze_slow_queries_job(self, queries: list[dict], database_root_password: str):
return self.analyze_slow_queries(queries, database_root_password)

@step("Analyze Slow Queries")
def analyze_slow_queries(self, queries: list[dict], database_root_password: str) -> list[dict]:
"""
Args:
Expand All @@ -918,11 +913,11 @@ def fetch_summarized_database_performance_report(self, mariadb_root_password: st
database = self.db_instance(username="root", password=mariadb_root_password)
return database.fetch_summarized_performance_report()

def fetch_database_process_list(self):
return self.db_instance().fetch_process_list()
def fetch_database_process_list(self, mariadb_root_password: str):
return self.db_instance(username="root", password=mariadb_root_password).fetch_process_list()

def kill_database_process(self, pid: str):
return self.db_instance().kill_process(pid)
def kill_database_process(self, pid: str, mariadb_root_password: str):
return self.db_instance(username="root", password=mariadb_root_password).kill_process(pid)

def db_instance(self, username: str | None = None, password: str | None = None) -> Database:
if not username:
Expand Down
19 changes: 14 additions & 5 deletions agent/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,15 +591,20 @@ def run_sql(bench, site):


@application.route(
"/benches/<string:bench>/sites/<string:site>/database/analyze-slow-queries", methods=["GET"]
"/benches/<string:bench>/sites/<string:site>/database/analyze-slow-queries", methods=["POST"]
)
@validate_bench_and_site
def analyze_slow_queries(bench: str, site: str):
queries = request.json["queries"]
mariadb_root_password = request.json["mariadb_root_password"]

job = Server().benches[bench].sites[site].analyze_slow_queries_job(queries, mariadb_root_password)
return {"job": job}
return Response(
json.dumps(
Server().benches[bench].sites[site].analyze_slow_queries(queries, mariadb_root_password),
cls=JSONEncoderForSQLQueryResult,
),
mimetype="application/json",
)


@application.route(
Expand All @@ -618,14 +623,18 @@ def database_performance_report(bench, site):

@application.route("/benches/<string:bench>/sites/<string:site>/database/processes", methods=["GET", "POST"])
def database_process_list(bench, site):
return jsonify(Server().benches[bench].sites[site].fetch_database_process_list())
data = request.json
return jsonify(
Server().benches[bench].sites[site].fetch_database_process_list(data["mariadb_root_password"])
)


@application.route(
"/benches/<string:bench>/sites/<string:site>/database/kill-process/<string:pid>", methods=["GET", "POST"]
)
def database_kill_process(bench, site, pid):
Server().benches[bench].sites[site].kill_database_process(pid)
data = request.json
Server().benches[bench].sites[site].kill_database_process(pid, data["mariadb_root_password"])
return "killed"


Expand Down

0 comments on commit ea7abae

Please sign in to comment.