~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 signal
16
import sys
17
import time
18
14612.2.6 by William Grant
utilities
19
import psycopg2
20
7771.5.3 by Stuart Bishop
Script to kill transactions that have been active for too long
21
22
def main():
23
    parser = OptionParser()
24
    parser.add_option(
25
        '-c', '--connection', type='string', dest='connect_string',
26
        default='', help="Psycopg connection string",
27
        )
28
    parser.add_option(
29
        '-s', '--max-seconds', type='int',
30
        dest='max_seconds', default=60*60,
31
        help='Maximum seconds time connections are allowed to remain active.',
32
        )
33
    parser.add_option(
34
        '-q', '--quiet', action='store_true', dest="quiet",
35
        default=False, help='Silence output',
36
        )
37
    parser.add_option(
38
        '-n', '--dry-run', action='store_true', default=False,
39
        dest='dry_run', help="Dry run - don't kill anything",
40
        )
41
    parser.add_option(
42
        '-u', '--user', action='append', dest='users',
43
        help='Kill connection of users matching REGEXP', metavar='REGEXP')
44
    options, args = parser.parse_args()
45
    if len(args) > 0:
46
        parser.error('Too many arguments')
47
    if not options.users:
48
        parser.error('--user is required')
49
50
    user_match_sql = 'AND (%s)' % ' OR '.join(
51
        ['usename ~* %s'] * len(options.users))
52
53
    con = psycopg2.connect(options.connect_string)
54
    cur = con.cursor()
55
    cur.execute("""
56
        SELECT usename, procpid, backend_start, xact_start
57
        FROM pg_stat_activity
58
        WHERE xact_start < CURRENT_TIMESTAMP - '%d seconds'::interval %s
59
        ORDER BY procpid
60
        """ % (options.max_seconds, user_match_sql), options.users)
61
62
    rows = list(cur.fetchall())
63
64
    if len(rows) == 0:
65
        if not options.quiet:
66
            print 'No transactions to kill'
67
            return 0
68
69
    for usename, procpid, backend_start, transaction_start in rows:
70
        print 'Killing %s (%d), %s, %s' % (
71
            usename, procpid, backend_start, transaction_start,
72
            )
73
        if not options.dry_run:
74
            os.kill(procpid, signal.SIGTERM)
75
    return 0
76
77
78
if __name__ == '__main__':
79
    sys.exit(main())