Supongamos que su equipo escribe un sistema de software que (¡sorprendentemente!) Funciona bien.
Un día, uno de los ingenieros ejecuta por error algunas consultas SQL que cambian algunos de los datos de la base de datos y luego se olvida de ello.
Después de un tiempo descubres los datos corruptos / erróneos y todos se rascan la cabeza sobre qué parte del código causó esto y por qué, sin éxito. Mientras tanto, el gerente del proyecto insiste en que encontremos la parte del código que lo causó.
Como tratas con esto?
project-management
Nik Kyriakides
fuente
fuente
Respuestas:
Es obvio que ningún gerente de proyecto invertirá una cantidad infinita de tiempo en tal problema. Quieren evitar que la misma situación ocurra nuevamente.
Para lograr este objetivo, incluso si uno no puede encontrar la causa raíz de tal falla, a menudo es posible tomar algunas medidas para
Por ejemplo, un registro más detallado, un manejo de errores más detallado o una señalización de error inmediata podrían ayudar a evitar que se repita el mismo error o encontrar la causa raíz. Si su sistema permite agregar disparadores de base de datos, tal vez sea posible agregar un disparador que prohíba la inconsistencia que se introduce en primer lugar.
Piense cuál podría ser el tipo de acción apropiado en su situación y sugiérale esto al equipo; Estoy seguro de que su gerente de proyecto estará encantado.
Como lo mencionaron otros, también es una buena idea prohibir dicho procedimiento (si tiene influencia sobre cómo se opera el sistema). Nadie debe poder ejecutar consultas ad-hoc no documentadas que cambien el contenido de la base de datos. Si es necesario realizar dicha consulta, asegúrese de que exista una política para almacenar la consulta junto con su fecha de ejecución, el nombre de la persona que la ejecutó y la razón por la que se utilizó, en un lugar documentado.
fuente
Esto no es un error
Al menos no en tu código. Es un error en tu proceso . Su gerente de proyecto debería estar mucho más preocupado por su proceso que su código.
En pocas palabras, al no permitir que los ingenieros cambien las bases de datos de producción o desarrollo compartido .
Suponiendo que se trata de una base de datos de desarrollo compartida:
Idealmente, si es posible, evite tener una base de datos compartida en primer lugar . En cambio, tenga bases de datos por desarrollador que sean de corta duración. Esto debería automatizarse con scripts, de lo contrario el costo de la prueba se vuelve demasiado grande, y hay un incentivo para no probar las cosas. Puede tener estas bases de datos en la estación de trabajo del desarrollador o en un servidor central.
Si, por alguna razón, DEBE tener una base de datos compartida, debe usar accesorios , esencialmente, algo que establece la base de datos en un estado bueno conocido cada vez que necesita usarla. Esto evita que los desarrolladores sean mordidos por los cambios de otras personas.
Si necesita aplicar cambios permanentes a la base de datos, debe confirmarlos en su control de origen . Configure su base de datos de modo que los desarrolladores no tengan permiso para escribir directamente en ella, y tengan un programa que extraiga los cambios del control de origen y los aplique.
Finalmente, a partir de su descripción de cómo está depurando cosas, parece que no está usando CI . Use CI . Es un poco difícil de configurar, pero ahorrará MUCHO tiempo a largo plazo, sin mencionar que evitará que se preocupe por los errores de base de datos no reproducibles. ¡ Ahora solo tendrás que preocuparte por los heisenbugs !
Asumiendo que esta es una base de datos de producción:
Si sus desarrolladores están cambiando las bases de datos de producción, muchas cosas han salido terriblemente mal, incluso si los cambios son absolutamente correctos.
Los desarrolladores nunca deberían acceder a las bases de datos de producción . No hay absolutamente ninguna razón para hacerlo, y tantas cosas que pueden salir muy, muy mal.
Si necesita arreglar algo en una base de datos de producción, primero haga una copia de seguridad, restaure esa copia de seguridad en una instancia (de desarrollo) diferente y luego juegue alrededor de esa base de datos de desarrollo. Una vez que cree que tiene una solución lista (¡en el control de origen!), Vuelve a hacer la restauración, aplica la solución y ve el resultado. Luego, después de hacer una copia de seguridad de las cosas nuevamente (e idealmente evitar las actualizaciones simultáneas), arregla la instancia de producción, idealmente a través de un parche de software.
Si necesita probar algo en una base de datos de producción ... no, no lo necesita . Cualquier prueba que necesite hacer, debe hacerlo en una instancia de desarrollo. Si necesita algunos datos para hacer las pruebas, obtendrá esos datos allí.
fuente
Una base de datos de producción debe tener un registro de acceso completo y controles de acceso basados en roles. Por lo tanto, debe tener pruebas contundentes de que la OMS hizo QUÉ CUÁNDO en la base de datos y, por lo tanto, desvió la atención del código a una seguridad operativa deficiente.
fuente
En este caso, finalmente descubriste la causa, pero tomando tu hipótesis de que no ...
Primero, analiza lo que cambió. Si el sistema funcionaba bien antes, una mirada cuidadosa a todo lo que se ha hecho recientemente podría revelar el cambio que causó el error. Revise sistemáticamente su control de versiones, los sistemas de CI / implementación y el control de configuración para ver si algo cambió. Ejecute git bisect o un mecanismo equivalente para realizar una búsqueda binaria. Revise los registros. Busca registros que no sabías que tenías. Hable con todos los que tengan acceso al sistema para ver si han hecho algo recientemente. Para su problema, si es lo suficientemente exhaustivo en este proceso, es de esperar que esto revele las consultas SQL olvidadas.
En segundo lugar, la instrumentación. Si no puede encontrar directamente la causa de un error, agregue instrumentación a su alrededor para recopilar datos sobre el problema. Pregúntese "si pudiera reproducir este error en el comando, qué me gustaría ver en el depurador", y luego registre eso. Repita según sea necesario hasta que comprenda mejor el problema. Como sugiere Doc Brown, agregue el registro de estados relevantes para el error. Agregue aserciones que detecten datos corruptos. Por ejemplo, si su error es un bloqueo de la aplicación, agregue un mecanismo de registro de bloqueo. Si ya tiene uno, excelente, agregue anotaciones a los registros de fallas para registrar el estado potencialmente relevante para la falla. Considere si los problemas de concurrencia pueden estar involucrados y pruebe para ejercer seguridad de subprocesos .
Tercero, la resiliencia. Los errores son inevitables, así que pregúntese cómo puede mejorar sus sistemas para que sean más resistentes para que la recuperación del error sea más fácil. ¿Podrían sus respaldos ser mejorados (o existentes)? ¿Mejor monitoreo, conmutación por error y alertas? ¿Más redundancia? ¿Mejor manejo de errores? ¿Desacoplar los servicios dependientes entre sí? ¿Puede mejorar sus procesos de acceso a la base de datos y consultas manuales? En el mejor de los casos, estas cosas harán que las consecuencias de su error sean menos graves, y en el peor de los casos, probablemente sean buenas cosas para hacer de todos modos.
fuente
También puede considerar si debe agregar procesos adicionales para reducir la probabilidad de que el acceso manual a la base de datos cause este tipo de problema en el futuro.
fuente
Estaba trabajando en el equipo de desarrollo para un producto de base de datos de mainframe cuando un cliente informó que tenía una base de datos corrupta. Una corrupción en el sentido de que el estado interno de los bits en el disco significaba que la base de datos no era legible a través del software de la base de datos. En el mundo mainframe, los clientes le pagan $ millones y usted debe tomar esto en serio. Esto es lo que hicimos:
Paso 0: ayude al cliente a ponerse en funcionamiento nuevamente reparando la base de datos.
Paso 1: al examinar el archivo en el disco a nivel hexadecimal, determinamos que la corrupción era sistemática: hubo muchos casos de la misma corrupción. Entonces, definitivamente fue causado a nivel del software de base de datos. De hecho, fue lo suficientemente sistemático como para sentir que podíamos descartar problemas de subprocesos múltiples.
Después de eliminar muchas otras teorías, nos centramos en una utilidad que podría usarse para la reorganización física de la base de datos. Parecía ser el único código que tenía acceso a los datos en el nivel correcto. Luego descubrimos una forma de ejecutar esta utilidad, con opciones cuidadosamente seleccionadas, que reproducían el problema. El cliente no pudo confirmar o negar que esto era lo que había hecho, pero como era la única explicación que podíamos encontrar, decidimos que era la causa probable y no tenían más remedio que aceptar nuestro diagnóstico. .
Paso 2: Luego hicimos dos cambios en el software: (a) dificultó causar este efecto accidentalmente a través de una interfaz de usuario "sí, sé lo que estoy haciendo", y (b) introdujo un nuevo archivo de registro para que si Si alguna vez sucedió de nuevo, tendríamos un registro de las acciones del usuario.
Entonces, básicamente (a) repara el daño y restaura la ejecución en vivo, (b) encuentra la causa raíz, (c) haz lo que sea necesario para evitar que vuelva a ocurrir o para facilitar el diagnóstico si vuelve a ocurrir.
fuente
Desde mi experiencia, lo que su jefe quiere es cierta garantía de nivel de que esto no volverá a ocurrir. Si es el caso de que la causa no fue el código, porque eso está asegurado por la prueba de unidad, por lo que suponiendo que ya tenga cobertura de prueba en su base de código, la solución debería agregar "prueba" a su base de datos. Citaré a Don Gilman, porque él clavó allí:
Pero también, debe tener un Procedimiento operativo estándar para cambiar los datos en producción. Por ejemplo, ningún DBA debe cambiar los datos, ningún desarrollador debe ejecutar el cambio por sí mismo y, como se define en el SOP, deben exigirse mutuamente formalmente el cambio por correo o boleto.
Debe haber una cita como esta en alguna parte, si no, puede citarme:
fuente
Hay varias cosas que se deben hacer con errores no reproducibles.
Cree un boleto y registre todo lo que pueda pensar en el boleto. Compruebe también si este "error" se ha registrado antes y vincule los tickets. Eventualmente, puede obtener suficientes tickets para establecer un patrón sobre cómo reproducir el error. Esto incluye soluciones alternativas utilizadas para tratar de evitarlo. Incluso si esta es la única instancia, si hay una primera vez, eventualmente habrá una segunda vez. Cuando encuentre la causa, cierre el ticket con una explicación de cuál fue la causa para tener una idea clara de lo que sucedió si vuelve a ocurrir (solución perdida en una fusión incorrecta)
Mire el sistema, qué falló y cómo falló. Intente encontrar áreas del código que puedan actualizarse para que la falla sea menos probable. Algunos ejemplos...
execute(<query>)
conexecuteMyStoredProcedure(<params>)
Es posible que esto no solucione el error, pero incluso si no lo hace, el sistema ahora es más estable / seguro, por lo que aún vale la pena.
Parte de 2, pero sucedió algo y debes saber cuándo sucede de nuevo. Debe crear algunos scripts / programas de comprobación de estado para supervisar el sistema, de modo que los administradores puedan recibir alertas dentro de las 24 horas posteriores a la aparición del error (cuanto menos demora, mejor, dentro de lo razonable). Esto hará que la limpieza sea mucho más fácil. (Tenga en cuenta que, además de los registros de las bases de datos, el sistema operativo también debe registrar quién inicia sesión en él y cualquier acción no leída que realicen. Al menos, debe haber registros de tráfico de red a esa máquina)
fuente
Su problema no fue causado por una falla en su software, sino por alguien que estaba jugando con la base de datos. Si llama a las cosas que van mal un "error", entonces su error es fácilmente reproducible: las cosas siempre saldrán mal cuando alguien hace cosas estúpidas en la base de datos. Y hay formas de evitar este "error", al no permitir que la base de datos se modifique manualmente o mediante el uso de software no probado, y al controlar estrictamente quién puede modificar la base de datos.
Si solo llama "error" a las fallas de su base de datos, entonces no tiene un error irreproducible, no tiene ningún error. Es posible que tenga un informe de error, pero también tiene evidencia de que el problema no fue causado por un error. Por lo tanto, puede cerrar el informe de error, no como "irreproducible", sino como "base de datos dañada". No es raro tener informes de errores donde la investigación muestra que no hay errores, pero un usuario usó mal el software, las expectativas del usuario eran incorrectas, etc.
En ese caso, todavía sabe que hubo un problema que no desea que se repita, por lo que debe realizar la misma acción que en el primer caso.
fuente