GCP Cloud SQL – Recuperando una base de datos eliminada accidentalmente

Introducción

Todo comenzó con un simple mensaje: «Hola Geko, estamos recibiendo un timeout de conexión con la DB«. Nos llevó menos de 2 minutos descubrir qué estaba pasando: La base de datos se había borrado. Después de llevarnos las manos a la cabeza varias veces, la tarea principal era recuperar los datos (y el servicio). Afortunadamente, Google aplica políticas de copias de seguridad que guardan una copia cada día. En Geko todos estamos de acuerdo con esta política. La cosa es que fuimos a buscar las copias de seguridad, y la pesadilla comenzó. ¡No había copias de seguridad! ¡No había nada! Y entonces descubrimos que las copias de seguridad están estrechamente ligadas al propio recurso de la base de datos, de modo que si ésta se elimina las copias de seguridad también lo harán. Google lo deja bien claro en su documentación de Cloud SQL.

Warning: All data on an instance, including backups, is permanently lost when that instance is deleted. To preserve your data, export it to Cloud Storage before you delete it. The Cloud SQL Admin role includes the permission to delete the instance. To prevent accidental deletion, grant this role only as needed.

No vamos a profundizar más en el tema de cómo se borró la base de datos. Simplemente decir que fue un proceso automatizado que detectó un cambio en el tamaño de disco y, cuando trataba de reemplazar el valor con el anterior (que era un valor menor) se requirió un reemplazo completo de la base de datos. No hubo oportunidad para aceptarlo ni para pararlo, por lo que la situación era la que era:

  • No hay base de datos == No hay datos
  • No hay copias de seguridad

Qué hicimos para resolver la situación

Incluso cuando Google nos estaba diciendo que las copias de seguridad se borran cuando lo hace la base de datos, y que todos los hechos apuntaban a esta hipótesis, fuimos obstinados a pesar de todo ello. La interfaz web de GCP no nos ofreció forma alguna de recuperar nada, por lo que decidimos continuar investigando por línea de comandos (CLI gcloud). ¡Y ésta fue la clave de nuestro éxito!

Teníamos la teoría de que las copias de seguridad deberían estar todavía en alguna parte (aún cuando la documentación dice lo contrario), así que comprobamos diferentes tipos de lugares de almacenamiento hasta probar la sección de copias de seguridad de SQL. Resulta que fuimos lo suficientemente rápidos al comprobar esta sección, y también sabíamos el nombre de la base de datos borrada, por lo que fuimos capaces de ejecutar el siguiente comando.

$ gcloud sql backups list --instance=deleted-db-name --project our-project
ID             WINDOW_START_TIME              ERROR  STATUS
1614876500000  2021-03-04T04:00:00.000+00:00  -      SUCCESSFUL
1614765400000  2021-03-03T04:00:00.000+00:00  -      SUCCESSFUL
1614654300000  2021-03-02T04:00:00.000+00:00  -      SUCCESSFUL
1614543200000  2021-03-01T04:00:00.000+00:00  -      SUCCESSFUL
1614432100000  2021-02-28T04:00:00.000+00:00  -      SUCCESSFUL
1614321000000  2021-02-27T04:00:00.000+00:00  -      SUCCESSFUL
1614210000000  2021-02-26T04:00:00.000+00:00  -      SUCCESSFUL

Y ahí estaban! Después de recuperar el aliento y las sonrisas, el proceso de recuperación daba comienzo. Todavía no confiábamos plenamente en que esto fuese a funcionar, ya que quizás la lista de copias estaba ahí mientras que los datos ya no. Nos movimos rápido porque sabíamos que el tiempo jugaba en nuestra contra, así que inmediatamente creamos una nueva base de datos desde cero y, justo después, iniciamos el proceso de restauración.

$ gcloud sql backups restore 1614876500000 --restore-instance=new-db-from-scratch-name --project our-project --backup-instance=deleted-db-name
All current data on the instance will be lost when the backup is 
restored.

Do you want to continue (Y/n)?  

Restoring Cloud SQL instance...done.                                                                                                                                                                                                        
Restored [https://sqladmin.googleapis.com/sql/v1beta4/projects/our-project/instances/new-db-from-scratch-name]

Finalmente, incluso teniendo retroalimentación positiva por parte de GCP, todavía no nos creíamos que hubiera funcionado. Teníamos que verificar que los datos efectivamente estaba ahí, y así lo hicimos. Afortunadamente todo se había recuperado, por lo que nuestro siguiente y último paso fue realizar una extracción SQL de los datos, de modo que pudiéramos asegurar que teníamos una copia reciente en otra localización diferente.

Conclusión

Incluso después de buscar en Google con ahínco y no encontrar ningún resultado que sirviera de ayuda  — ya que todos dicen que no hay nada que hacer — nuestro conocimiento y pasión nos hizo continuar investigando acerca del tema hasta que encontramos la manera. Sabemos que fuimos afortunados al encontrar las copias de seguridad todavía ahí, pero también sabemos que fuimos rápidos, metódicos y obstinados al buscar y detectar una solución. Por otra parte, hemos aprendido que no nos podemos fiar de las copias de seguridad realizadas por el proveedor, por lo que estamos trabajando actualmente en procedimientos para tener copias en más sitios. Tenemos muy claro que esta es la primera y última vez que nos sucede esto.

Además, y al contrario que AWS, como mencionamos anteriormente, GCP relaciona fuertemente el recurso de la base de datos con sus copias de seguridad. Esto se ha demostrado que puede llegar a ser un gran problema cuando hay que gestionar un borrado accidental. Y a eso hay que sumarle que no es posible copiar o mover las copias de seguridad a otros tipos de almacenamiento. A pesar de lo anterior, hay soluciones personalizadas como extraer los datos SQL regularmente y almacenarlos en un bucket, pero no es algo oficial.

Por otra parte, recomendamos encarecidamente ser cautos cuando haya procesos automatizados alrededor. Hasta donde hemos visto, la única forma de proteger contra eliminación una base de datos en GCP, es limitar los permisos. Por ello, la forma de proceder es eliminar el permiso DELETE de las cuentas (de servicio) que estos procesos automatizados usen.

Joke about GCP. Geko as a strong dog says: I accidentally deleted my DB. I need a backup! ― GCP as a weak dog answers: I deleted your backups when removing the DB. It was not was you was looking for? ― And finally Geko dog replies: Ok... let me find them for you and fix all this mess!

Afortunadamente siempre puedes contar con el equipo de Geko (un equipo de ingenieros altamente cualificados), quienes profundizarán en el tema hasta conseguir hacerlo sencillo o solucionarlo para ti. ¡No olvides volver por el blog de Geko para comprobar qué hay nuevo por aquí! El equipo de Geko siempre estará más que contento de verte por aquí, y por supuesto

¡Ponte en contacto con nosotros para más información!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *