2011-03-24 22 views
8

Tenemos una aplicación django bastante típica ejecutándose en postgresql 9.0. Recientemente descubrimos algunas consultas de DNS que se han ejecutado durante más de 4 horas, debido a búsquedas ineficientes en la interfaz de administración. Si bien planeamos solucionar estas consultas, como medida de seguridad nos gustaría restringir artificialmente el tiempo de consulta de la base de datos a 15 segundos, pero solo en el contexto de una solicitud web; los trabajos por lotes y las tareas de apio no deben estar limitados por esta restricción.¿Cómo puedo limitar el tiempo de consulta de la base de datos durante las solicitudes web?

¿Cómo podemos hacer eso? ¿O es una idea terrible?

Respuesta

20

La mejor manera de hacer esto sería la creación de un papel/usuario que sólo se utiliza para ejecutar las peticiones web, a continuación, la statement_timeout ese rol .

ALTER ROLE role_name SET statement_timeout = 15000 

Todas las demás funciones utilizarán la configuración global de statement_timeout (que está deshabilitada en una instalación común).

+0

+ 1 Buena opción. Solo recuerde que el usuario puede restablecer esto para su sesión emitiendo el mismo comando con un tiempo de espera mayor. Con una llamada web, supongo que esto no sería un problema, ya que el usuario no tendrá una interfaz para configurarlo. – Kuberchaun

+0

Matthew Wood: Vaya, qué gran sugerencia. Gracias. StarShip3000: esta respuesta resuelve el problema técnico, que es todo lo que me importa. El problema que plantea no es un problema tecnológico, es un problema de recursos humanos. Esos son fáciles de resolver. –

+0

¡Gran solución! Gracias por eso. También puede emitir 'set session statement_timeout = 15000;' si solo quiere limitar una sesión específica, o incluso 'set local statement_timeout = 15000;'. Más información: http://www.postgresql.org/docs/9.5/static/runtime-config-client.html#GUC-STATEMENT-TIMEOUT –

-4

Por lo que el tiempo se va, usted podría pasar todas sus consultas a través de una clase que, en la creación de instancias, genera dos hilos: uno para la consulta, y uno para un temporizador. Si el temporizador llega a 15 segundos, entonces mata el hilo con la consulta.

En cuanto a averiguar si la consulta se crea una instancia de una solicitud web, no sé lo suficiente sobre Django para poder ayudarte. De manera simplista, diría que en su clase que maneja sus llamadas a la base de datos, un parámetro opcional para el constructor podría ser algo como context, que podría ser http en el caso de una solicitud web y "" para cualquier otra cosa.

+0

Esta es una solución muy sobre-diseñada para el problema con toneladas de peligros potenciales, y haciendo un trabajo que el sistema de base de datos maneja de forma nativa. – Fleep

0

Tendrá que manejar esto manualmente. Eso es verificar la regla de 15 segundos y eliminar las consultas que la violan.

Consulta pg_stat_activity y encuentra a los infractores y llama a pg_terminate_backend (procpid) para matar a los infractores.

Algo como esto en un bucle:

SELECT pg_terminate_backend(pg_stat_activity.procpid) 
FROM pg_stat_activity 
WHERE pg_stat_activity.datname = 'TARGET_DB' 
    AND usename = 'WEBUSERNAME' 
    AND (now()-query_start) > '00:00:15'; 
+0

Por supuesto, supone que conoce los nombres de las cuentas que utiliza la interfaz web. Sin embargo, si tiene una lista de direcciones IP de su servidor web, puede usarlas también. Consulte la tabla pg_stat_activity. – Kuberchaun

Cuestiones relacionadas