…an application to code, test, and deploy code together. It provides Git repository management with fine grained access controls, code reviews, issue tracking, activity feeds, wikis, and continuous integration.

La anterior, es la manera en que se define Gitlab, pero palabras más palabras menos, es la mayor competencia a Github actualmente con el plus que es totalmente Open Source. Pero finalizando el mes de enero, empezó a ser noticia ya que tuvo una grave baja en el servicio y la misma compañía avisaba a su base de usuarios a través de Twitter que se encontraban realizando un mantenimiento de emergencia en la base de datos:

We are performing emergency database maintenance, GitLab.com will be taken offline

“Mantenimiento” no creo que haya sido la palabra adecuada, ya que después sería de público conocimiento lo que había ocurrido. Debido a un error humano, se presentó una pérdida de información en la base de datos de producción de Gitlab.com. Lo que sucedió después fueron una serie de eventos desafortunados y casualidades que salvaron a Gitlab, avaluada en millones de dólares, de salir del mapa tecnológico. Pero lo que me impulsa a realizar la presente entrada y es completamente digno de admirar, es la honestidad con la que ellos presentaron la información de manera transparente y en tiempo real a la comunidad llegando inclusive a realizar un directo en YouTube e indicando a través de un documento en Google Drive sobre los hallazgos encontrados en el camino de la complicada (y supongo estresante 😕) tarea de volver a tener Gitlab.com en línea.

El incidente

Pero ¿qué fue lo que sucedió? ¿Qué llevó a la caída del servicio?. En Gitlab publicaron un post donde explican cada detalle de lo ocurrido el cual considero es de lectura obligatoria si como yo haces parte de algún equipo de operaciones ya sea como SysAdmin, DevOps, Infrastructure Engineer, DBA, Site Reliability Engineer, etc (o el nombre fancy del momento para tu rol en dicha área que quieras poner). Lamentablemente, una serie de hechos desafortunados llevaron al desenlace del 31 de enero, aquí un breve resumen.

6 horas antes de lo ocurrido, un ingeniero tomó un snapshot LVM de la base de datos de producción para llevarlo al ambiente de staging, la idea era empezar a experimentar con Pgpool-II para poder tener diferentes instancias de la base de datos y balancear las cargas de trabajo.

Momentos más tarde, el equipo de operaciones se encontraba verificando un lag de aproximadamente 4 GB entre el nodo principal y el de replicación de la base de datos, causado por un aumento en la carga de trabajo en la base de datos de producción, generando que muchos usuarios no pudieran realizar comentarios en issues y realizar merge requests en la plataforma. Tratando de solucionar el problema anterior, una de las ideas que surgió era ejecutar en la instancia de replicación un rm -Rvf sobre el directorio de PostgreSQL, acción que efectivamente se realizó, pero con tan mala suerte que por error se ejecutó sobre la instancia de base de datos de producción 😯 la persona se percata uno o dos segundos después del error y cancela la operación pero ya era demasiado tarde, el daño estaba hecho, en ese momento más 300GB de información habían sido eliminadas de manera irreversible.

Aunque a primera vista la acción anterior pueda parecer la más grave de los hechos presentados, no deja de ser más que un error humano del que ninguno de nosotros estamos exentos de cometer en algún momento. Lo realmente grave desde mi punto de vista, era que los procedimientos de backups estaban completamente rotos, fallando silenciosamente, lo que se traduce a final de cuentas que no contaban con backup alguno.

Falla total de los backups

Lo que sucedió después fue la desagradable sorpresa de encontrarse que los procedimientos de backups estaban totalmente rotos. Había un cronjob que generaba cada 24 horas un backup mediante pg_dump que se debía almacenar en un bucket S3 de Amazon, pero cuando fueron a revisarlo, estaba vacío 😱 Posteriormente se dieron cuenta que una diferencia de versiones entre pg_dump (9.2) y PostgreSQL (9.6) hacía que el procedimiento fallara de manera silenciosa. Para terminar de completar, los snapshots de disco en Azure no estaban activados para las instancias de base de datos.

Tenían activados de manera automática la creación de Snapshots LVM pero por un golpe de “suerte” 6 horas antes se había realizado uno manualmente que en últimas fue el backup utilizado para volver a tener en línea Gitlab.com y minimizó un poco en tiempo los datos perdidos.

¿Enseñanza?

Al final de cuentas, el incidente de Gitlab.com es un duro recordatorio de algo que siempre hemos sabido, pero que a veces no prestamos suficiente atención: Las políticas y procedimientos de backups y restauración de éstos se deben probar de principio a fin de manera periódica. Una simple revisada del bucket S3 por parte del equipo de operaciones de Gitlab hubiera bastado para percatarse que estaba vacío y entender que dicho procedimiento no arrojaba ningún resultado. Por lo anterior creo que el peor error no fue el rm -Rvf por parte de un miembro del equipo, sino el abandono por parte de todos en el equipo de operaciones de las políticas y procedimientos de backups que no estaban funcionando. Lo único que sirvió al final del día para volver a subir Gitlab.com, fue el backup realizado de manera casual y manual 6 horas antes. A final de cuentas, tremendo golpe de suerte ¿no?.

En lo personal me gustó la transparencia de Gitlab para dar a conocer el incidente, lo que produjo de manera general respuestas positivas de toda la comunidad. Desde hoy cuentan con un seguidor y usuario más (Tiene repositorios privados ilimitados 😃 . De lectura obligatoria el post y el documento en drive explicando en mayor detalle y cronológicamente todo el incidente. No sé ustedes, pero yo me voy a testear unos cuantos backups que no he probado 😛.