~launchpad-pqm/launchpad/devel

10637.3.1 by Guilherme Salgado
Use the default python version instead of a hard-coded version
1
#!/usr/bin/python
8687.15.4 by Karl Fogel
Add the copyright header block to more files; tweak format in a few files.
2
#
3
# Copyright 2009 Canonical Ltd.  This software is licensed under the
4
# GNU Affero General Public License version 3 (see the file LICENSE).
7771.5.3 by Stuart Bishop
Script to kill transactions that have been active for too long
5
7771.5.4 by Stuart Bishop
Fix docstring
6
"""Kill transaction that have hung around for too long.
7771.5.3 by Stuart Bishop
Script to kill transactions that have been active for too long
7
"""
8
9
__metaclass__ = type
10
__all__ = []
11
12
13
from optparse import OptionParser
14
import os
15
import psycopg2
16
import signal
17
import sys
18
import time
19
20
21
def main():
22
    parser = OptionParser()
23
    parser.add_option(
24
        '-c', '--connection', type='string', dest='connect_string',
25
        default='', help="Psycopg connection string",
26
        )
27
    parser.add_option(
28
        '-s', '--max-seconds', type='int',
29
        dest='max_seconds', default=60*60,
30
        help='Maximum seconds time connections are allowed to remain active.',
31
        )
32
    parser.add_option(
33
        '-q', '--quiet', action='store_true', dest="quiet",
34
        default=False, help='Silence output',
35
        )
36
    parser.add_option(
37
        '-n', '--dry-run', action='store_true', default=False,
38
        dest='dry_run', help="Dry run - don't kill anything",
39
        )
40
    parser.add_option(
41
        '-u', '--user', action='append', dest='users',
42
        help='Kill connection of users matching REGEXP', metavar='REGEXP')
43
    options, args = parser.parse_args()
44
    if len(args) > 0:
45
        parser.error('Too many arguments')
46
    if not options.users:
47
        parser.error('--user is required')
48
49
    user_match_sql = 'AND (%s)' % ' OR '.join(
50
        ['usename ~* %s'] * len(options.users))
51
52
    con = psycopg2.connect(options.connect_string)
53
    cur = con.cursor()
54
    cur.execute("""
55
        SELECT usename, procpid, backend_start, xact_start
56
        FROM pg_stat_activity
57
        WHERE xact_start < CURRENT_TIMESTAMP - '%d seconds'::interval %s
58
        ORDER BY procpid
59
        """ % (options.max_seconds, user_match_sql), options.users)
60
61
    rows = list(cur.fetchall())
62
63
    if len(rows) == 0:
64
        if not options.quiet:
65
            print 'No transactions to kill'
66
            return 0
67
68
    for usename, procpid, backend_start, transaction_start in rows:
69
        print 'Killing %s (%d), %s, %s' % (
70
            usename, procpid, backend_start, transaction_start,
71
            )
72
        if not options.dry_run:
73
            os.kill(procpid, signal.SIGTERM)
74
    return 0
75
76
77
if __name__ == '__main__':
78
    sys.exit(main())