Scott Zawalski | 20a9b58 | 2011-11-21 11:49:40 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # |
| 3 | # Copyright 2011 Google Inc. All Rights Reserved. |
| 4 | |
| 5 | """Tool to shrink autotest db by deleting old data. |
| 6 | """ |
| 7 | import datetime |
| 8 | import optparse |
| 9 | import os |
| 10 | |
| 11 | settings = "autotest_lib.frontend.settings" |
| 12 | os.environ["DJANGO_SETTINGS_MODULE"] = settings |
| 13 | |
| 14 | # For db access. |
| 15 | import common |
| 16 | from django.db import connection |
| 17 | from autotest_lib.frontend.afe import models as afe_models |
| 18 | from autotest_lib.frontend.tko import models as tko_models |
| 19 | |
| 20 | |
| 21 | class DBConnection(object): |
| 22 | def __init__(self, dry_run, verbose): |
| 23 | self.dry_run = dry_run |
| 24 | self.verbose = verbose |
| 25 | if not self.dry_run: |
| 26 | self.cursor = connection.cursor() |
| 27 | |
| 28 | def execute(self, stmt): |
| 29 | if self.verbose: |
| 30 | print stmt |
| 31 | if not self.dry_run: |
| 32 | self.cursor.execute(stmt) |
| 33 | |
| 34 | def close(self): |
| 35 | if not self.dry_run: |
| 36 | self.cursor.close() |
| 37 | |
| 38 | |
| 39 | BATCH_SIZE = 1000 |
| 40 | |
| 41 | |
| 42 | def delete_job(conn, afe_job): |
| 43 | afe_host_queue_entry_ids = set([str(afe_host_queue_entry.id) |
| 44 | for afe_host_queue_entry in afe_models.HostQueueEntry.objects.filter( |
| 45 | job=afe_job)]) |
| 46 | if afe_host_queue_entry_ids: |
| 47 | conn.execute('DELETE FROM afe_aborted_host_queue_entries WHERE ' |
| 48 | 'queue_entry_id in (%s);' % ','.join(afe_host_queue_entry_ids)) |
| 49 | conn.execute('DELETE FROM afe_special_tasks WHERE ' |
| 50 | 'queue_entry_id in (%s);' % ','.join(afe_host_queue_entry_ids)) |
| 51 | |
| 52 | conn.execute('DELETE FROM afe_host_queue_entries WHERE job_id=%d;' % |
| 53 | afe_job.id) |
| 54 | conn.execute('DELETE FROM afe_ineligible_host_queues WHERE job_id=%d;' % |
| 55 | afe_job.id) |
| 56 | conn.execute('DELETE FROM afe_jobs_dependency_labels WHERE job_id=%d;' % |
| 57 | afe_job.id) |
| 58 | |
| 59 | if afe_job.parameterized_job_id: |
| 60 | conn.execute('DELETE FROM afe_parameterized_job_parameters ' |
| 61 | 'WHERE parameterized_job_id=%d;' % |
| 62 | afe_job.parameterized_job_id) |
| 63 | conn.execute('DELETE FROM afe_parameterized_jobs WHERE id=%d;' % |
| 64 | afe_job.parameterized_job_id) |
| 65 | |
| 66 | tko_test_ids = set() |
| 67 | tko_job_ids = set() |
| 68 | for tko_test_view in tko_models.TestView.objects.filter( |
| 69 | afe_job_id=afe_job.id): |
| 70 | tko_test_ids.add(str(tko_test_view.test_idx)) |
| 71 | tko_job_ids.add(str(tko_test_view.job_idx)) |
| 72 | |
| 73 | batches = len(tko_test_ids) / BATCH_SIZE + 1 |
| 74 | tko_test_ids = list(tko_test_ids) |
| 75 | for i in range(batches): |
| 76 | test_ids = tko_test_ids[i*BATCH_SIZE : (i+1)*BATCH_SIZE] |
| 77 | conn.execute('DELETE FROM tko_iteration_result WHERE test_idx in (%s);' % |
| 78 | ','.join(test_ids)) |
Dennis Jeffrey | 368c54b | 2013-07-24 11:19:03 -0700 | [diff] [blame] | 79 | conn.execute('DELETE FROM tko_iteration_perf_value WHERE test_idx in ' |
| 80 | '(%s);' % ','.join(test_ids)) |
Scott Zawalski | 20a9b58 | 2011-11-21 11:49:40 -0800 | [diff] [blame] | 81 | conn.execute('DELETE FROM tko_iteration_attributes WHERE test_idx in (%s);' |
| 82 | % ','.join(test_ids)) |
| 83 | conn.execute('DELETE FROM tko_test_attributes WHERE test_idx in (%s);' % |
| 84 | ','.join(test_ids)) |
| 85 | |
| 86 | if tko_job_ids: |
| 87 | conn.execute('DELETE FROM tko_tests WHERE job_idx in (%s);' % |
| 88 | ','.join(tko_job_ids)) |
| 89 | conn.execute('DELETE FROM tko_job_keyvals WHERE job_id in (%s);' % |
| 90 | ','.join(tko_job_ids)) |
| 91 | |
| 92 | conn.execute('DELETE FROM tko_jobs WHERE afe_job_id=%d;' % afe_job.id) |
| 93 | conn.execute('DELETE FROM afe_jobs WHERE id=%d;' % afe_job.id) |
| 94 | |
| 95 | |
| 96 | |
| 97 | def main(): |
| 98 | parser = optparse.OptionParser() |
| 99 | parser.add_option('--days', type='int', dest='days', default=180, |
| 100 | help='How many days of data we want to keep in the db.') |
| 101 | parser.add_option('--dry_run', dest='dry_run', default=False, |
| 102 | action='store_true', |
| 103 | help='Where we like to apply the sql commands to db.') |
| 104 | parser.add_option('--verbose', dest='verbose', default=False, |
| 105 | action='store_true', |
| 106 | help='Print out all sql statement.') |
| 107 | |
| 108 | options, _ = parser.parse_args() |
| 109 | |
| 110 | conn = DBConnection(options.dry_run, options.verbose) |
| 111 | d = datetime.date.today() |
| 112 | d = d - datetime.timedelta(days=options.days) |
| 113 | for afe_job in afe_models.Job.objects.filter(created_on__lte=d): |
| 114 | print 'Delete afe job %d.' % afe_job.id |
| 115 | delete_job(conn, afe_job) |
| 116 | |
| 117 | print 'Optimize table after deletion.' |
| 118 | conn.execute('OPTIMIZE TABLE afe_aborted_host_queue_entries;') |
| 119 | conn.execute('OPTIMIZE TABLE afe_host_queue_entries;') |
| 120 | conn.execute('OPTIMIZE TABLE afe_ineligible_host_queues;') |
| 121 | conn.execute('OPTIMIZE TABLE afe_jobs_dependency_labels;') |
| 122 | conn.execute('OPTIMIZE TABLE afe_parameterized_job_parameters;') |
| 123 | conn.execute('OPTIMIZE TABLE afe_parameterized_jobs;') |
| 124 | conn.execute('OPTIMIZE TABLE tko_iteration_result;') |
Dennis Jeffrey | 368c54b | 2013-07-24 11:19:03 -0700 | [diff] [blame] | 125 | conn.execute('OPTIMIZE TABLE tko_iteration_perf_value;') |
Scott Zawalski | 20a9b58 | 2011-11-21 11:49:40 -0800 | [diff] [blame] | 126 | conn.execute('OPTIMIZE TABLE tko_iteration_attributes;') |
| 127 | conn.execute('OPTIMIZE TABLE tko_test_attributes;') |
| 128 | conn.execute('OPTIMIZE TABLE tko_tests;') |
| 129 | conn.execute('OPTIMIZE TABLE tko_jobs;') |
| 130 | conn.execute('OPTIMIZE TABLE afe_jobs;') |
| 131 | conn.close() |
| 132 | |
| 133 | |
| 134 | if __name__ == '__main__': |
| 135 | main() |