diff --git a/apps/monitor/tasks.py b/apps/monitor/tasks.py index feefdf8c..74ffcb2f 100644 --- a/apps/monitor/tasks.py +++ b/apps/monitor/tasks.py @@ -7,6 +7,7 @@ from celery import shared_task from django.utils import timezone from django.conf import settings import os +from apps.utils.sql import execute_raw_sql @shared_task(base=CustomTask) @@ -33,3 +34,44 @@ def clear_dbbackup(num: int=7): for f in files_remove_list: filepath = os.path.join(backpath, f) os.remove(filepath) + +@shared_task(base=CustomTask) +def clean_timescaledb_job_his(num: int = 30): + execute_raw_sql(f""" + DO $$ + DECLARE + batch_size INTEGER := 100000; -- 每次删除的行数 + deleted_count INTEGER := 0; + BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_class c + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE n.nspname = '_timescaledb_internal' + AND c.relname = 'bgw_job_stat_history' + ) THEN + RAISE NOTICE 'Start cleaning _timescaledb_internal.bgw_job_stat_history ...'; + + LOOP + WITH del AS ( + SELECT ctid + FROM _timescaledb_internal.bgw_job_stat_history + WHERE execution_start < NOW() - INTERVAL '{num} days' + LIMIT batch_size + ) + DELETE FROM _timescaledb_internal.bgw_job_stat_history + WHERE ctid IN (SELECT ctid FROM del); + + GET DIAGNOSTICS deleted_count = ROW_COUNT; + RAISE NOTICE 'Deleted % rows...', deleted_count; + EXIT WHEN deleted_count = 0; + + + PERFORM pg_sleep(0.1); -- 稍微休息,避免压力过大 + END LOOP; + RAISE NOTICE '✅ Data cleanup complete. Run VACUUM FULL manually.'; + ELSE + RAISE NOTICE 'Table _timescaledb_internal.bgw_job_stat_history not found.'; + END IF; + END$$; + """) \ No newline at end of file