| #!/usr/bin/python |
| # |
| # Copyright 2011 Google Inc. All Rights Reserved. |
| |
| """Tool to shrink autotest db by deleting old data. |
| """ |
| import datetime |
| import optparse |
| import os |
| |
| settings = "autotest_lib.frontend.settings" |
| os.environ["DJANGO_SETTINGS_MODULE"] = settings |
| |
| # For db access. |
| import common |
| from django.db import connection |
| from autotest_lib.frontend.afe import models as afe_models |
| from autotest_lib.frontend.tko import models as tko_models |
| |
| |
| class DBConnection(object): |
| def __init__(self, dry_run, verbose): |
| self.dry_run = dry_run |
| self.verbose = verbose |
| if not self.dry_run: |
| self.cursor = connection.cursor() |
| |
| def execute(self, stmt): |
| if self.verbose: |
| print stmt |
| if not self.dry_run: |
| self.cursor.execute(stmt) |
| |
| def close(self): |
| if not self.dry_run: |
| self.cursor.close() |
| |
| |
| BATCH_SIZE = 1000 |
| |
| |
| def delete_job(conn, afe_job): |
| afe_host_queue_entry_ids = set([str(afe_host_queue_entry.id) |
| for afe_host_queue_entry in afe_models.HostQueueEntry.objects.filter( |
| job=afe_job)]) |
| if afe_host_queue_entry_ids: |
| conn.execute('DELETE FROM afe_aborted_host_queue_entries WHERE ' |
| 'queue_entry_id in (%s);' % ','.join(afe_host_queue_entry_ids)) |
| conn.execute('DELETE FROM afe_special_tasks WHERE ' |
| 'queue_entry_id in (%s);' % ','.join(afe_host_queue_entry_ids)) |
| |
| conn.execute('DELETE FROM afe_host_queue_entries WHERE job_id=%d;' % |
| afe_job.id) |
| conn.execute('DELETE FROM afe_ineligible_host_queues WHERE job_id=%d;' % |
| afe_job.id) |
| conn.execute('DELETE FROM afe_jobs_dependency_labels WHERE job_id=%d;' % |
| afe_job.id) |
| |
| if afe_job.parameterized_job_id: |
| conn.execute('DELETE FROM afe_parameterized_job_parameters ' |
| 'WHERE parameterized_job_id=%d;' % |
| afe_job.parameterized_job_id) |
| conn.execute('DELETE FROM afe_parameterized_jobs WHERE id=%d;' % |
| afe_job.parameterized_job_id) |
| |
| tko_test_ids = set() |
| tko_job_ids = set() |
| for tko_test_view in tko_models.TestView.objects.filter( |
| afe_job_id=afe_job.id): |
| tko_test_ids.add(str(tko_test_view.test_idx)) |
| tko_job_ids.add(str(tko_test_view.job_idx)) |
| |
| batches = len(tko_test_ids) / BATCH_SIZE + 1 |
| tko_test_ids = list(tko_test_ids) |
| for i in range(batches): |
| test_ids = tko_test_ids[i*BATCH_SIZE : (i+1)*BATCH_SIZE] |
| conn.execute('DELETE FROM tko_iteration_result WHERE test_idx in (%s);' % |
| ','.join(test_ids)) |
| conn.execute('DELETE FROM tko_iteration_attributes WHERE test_idx in (%s);' |
| % ','.join(test_ids)) |
| conn.execute('DELETE FROM tko_test_attributes WHERE test_idx in (%s);' % |
| ','.join(test_ids)) |
| |
| if tko_job_ids: |
| conn.execute('DELETE FROM tko_tests WHERE job_idx in (%s);' % |
| ','.join(tko_job_ids)) |
| conn.execute('DELETE FROM tko_job_keyvals WHERE job_id in (%s);' % |
| ','.join(tko_job_ids)) |
| |
| conn.execute('DELETE FROM tko_jobs WHERE afe_job_id=%d;' % afe_job.id) |
| conn.execute('DELETE FROM afe_jobs WHERE id=%d;' % afe_job.id) |
| |
| |
| |
| def main(): |
| parser = optparse.OptionParser() |
| parser.add_option('--days', type='int', dest='days', default=180, |
| help='How many days of data we want to keep in the db.') |
| parser.add_option('--dry_run', dest='dry_run', default=False, |
| action='store_true', |
| help='Where we like to apply the sql commands to db.') |
| parser.add_option('--verbose', dest='verbose', default=False, |
| action='store_true', |
| help='Print out all sql statement.') |
| |
| options, _ = parser.parse_args() |
| |
| conn = DBConnection(options.dry_run, options.verbose) |
| d = datetime.date.today() |
| d = d - datetime.timedelta(days=options.days) |
| for afe_job in afe_models.Job.objects.filter(created_on__lte=d): |
| print 'Delete afe job %d.' % afe_job.id |
| delete_job(conn, afe_job) |
| |
| print 'Optimize table after deletion.' |
| conn.execute('OPTIMIZE TABLE afe_aborted_host_queue_entries;') |
| conn.execute('OPTIMIZE TABLE afe_host_queue_entries;') |
| conn.execute('OPTIMIZE TABLE afe_ineligible_host_queues;') |
| conn.execute('OPTIMIZE TABLE afe_jobs_dependency_labels;') |
| conn.execute('OPTIMIZE TABLE afe_parameterized_job_parameters;') |
| conn.execute('OPTIMIZE TABLE afe_parameterized_jobs;') |
| conn.execute('OPTIMIZE TABLE tko_iteration_result;') |
| conn.execute('OPTIMIZE TABLE tko_iteration_attributes;') |
| conn.execute('OPTIMIZE TABLE tko_test_attributes;') |
| conn.execute('OPTIMIZE TABLE tko_tests;') |
| conn.execute('OPTIMIZE TABLE tko_jobs;') |
| conn.execute('OPTIMIZE TABLE afe_jobs;') |
| conn.close() |
| |
| |
| if __name__ == '__main__': |
| main() |