Advertisement
planzelle

Killing long running idle postgres pids

Aug 28th, 2015
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.53 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5.     Utility to check for idle running queries over a long time
  6.     Will kill the pid and send an email to error-account with
  7.     some infos concerning the killed pids/queries
  8.  
  9.     Place it on db server. Best used with crontab.
  10.    
  11.     For test purposes debug can be set to 1
  12.     In debug-mode the queries are only displayed - no killing occurs/ no mail (for manual call)
  13.  
  14. """
  15.  
  16. import os
  17. import signal
  18. import psycopg2
  19. from email.mime.text import MIMEText
  20. import smtplib
  21. import sys
  22. import socket
  23.  
  24.  
  25. debug = 0
  26. maxMinutes = 240 # 4h
  27. reportMail = 'error@myserver.com'
  28.  
  29. # no config beyond this point needed
  30.  
  31. host = socket.gethostbyaddr(socket.gethostname())[0]
  32. sender = 'longrunner@'+ host
  33. smtpserver = 'smtp.myserver.com'
  34. usetls = True
  35. smtpusername = ''
  36. smtppassword = ''
  37.  
  38.  
  39. def sendmail(recipient, subject, content):
  40.     msg = MIMEText(content)
  41.     msg['From'] = sender
  42.     msg['To'] = recipient
  43.     msg['Subject'] = subject
  44.     server = smtplib.SMTP(smtpserver)
  45.     if usetls:
  46.         server.starttls()
  47.     if smtpusername and smtppassword:
  48.         server.login(smtpusername, smtppassword)
  49.     server.sendmail(sender, recipient, msg.as_string())
  50.     server.quit()
  51.  
  52.  
  53.  
  54. def main():
  55.     try:
  56.         conn = psycopg2.connect("dbname='postgres' host='127.0.0.1' user='postgres' password=''")
  57.     except:
  58.         print "Could not connect to local database [127.0.0.1]"
  59.  
  60.     cur = conn.cursor()
  61.     sql = """SELECT
  62.         /* 00 */ pid,
  63.         /* 01 */ datname,
  64.         /* 02 */ client_addr,
  65.         /* 03 */ substring(query,0,160),
  66.         /* 04 */ state,
  67.         /* 05 */ waiting,
  68.         /* 06 */ (now()-query_start) AS elapsed,
  69.         /* 07 */ (extract(EPOCH FROM (now()-query_start))/60)::INTEGER AS minutes
  70.         FROM pg_stat_activity
  71.         WHERE query!='<IDLE>' AND query!='DISCARD ALL'
  72.         ORDER BY elapsed ASC;"""
  73.  
  74.     try:
  75.         cur.execute(sql)
  76.     except:
  77.         print "Querying db failed"
  78.  
  79.     try:
  80.         rows = cur.fetchall()
  81.     except:
  82.         print "Could not fetch resultset"
  83.  
  84.     counter = 0
  85.     mailbody = ""
  86.     for row in rows:
  87.         if row[7] <= maxMinutes:
  88.             continue
  89.  
  90.         line = """pid=%s minutes=%s state=%s db=%s ip=%s\n\tquery=%s\n\n""" % (row[0], row[7], row[4], row[1], row[2], row[3])
  91.         mailbody += line
  92.         if debug==1:
  93.             print line
  94.  
  95.         if debug==0:
  96.             os.kill(row[0], signal.SIGQUIT) #if not working try: SIGKILL
  97.             counter += 1
  98.  
  99.     if counter > 0:
  100.         mailheader = """The following %s pids have been killed [limit= %s minutes]:\n\n""" % (counter, maxMinutes)
  101.         mailbody = mailheader + mailbody
  102.         sendmail(reportMail, 'LongRunner: '+ host, mailbody)
  103.     sys.exit(0)
  104.  
  105. if __name__ == '__main__':
  106.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement