¿Cómo efectuar el backup de un millón de bases de datos por día?

En sus planes de alojamiento en internet, OVH incluye una o varias bases de datos SQL compartidas y ofrece la posibilidad de contratar bases de datos privadas de forma opcional, el SQL Privado. OVH efectúa a diario el backup de estos dos tipos de bases de datos, lo cual representa actualmente un volumen de algo más de un millón, del que se derivan problemáticas interesantes: ¿cómo distribuir el backup en el tiempo para no generar un pico de carga en la infraestructura?, ¿qué método utilizar para realizar el backup? El equipo de OVH nos explica.

¿Cuándo efectuamos el backup?

Efectuar el backup, ya sea de bases de datos o de servicios de cualquier otro tipo, produce de forma natural un aumento de carga en la infraestructura: en términos de entradas y salidas (I/O), ya que es necesario copiar los datos, y a nivel de red, ya que los datos deben transferirse de una máquina a otra.

Los administradores de sistemas conocen bien este problema. Y es por ello que el backup suele efectuarse en las horas de bajo consumo del servicio en cuestión, en general durante la noche.

OVH ha adoptado este enfoque intuitivo durante mucho tiempo. Para la inmensa mayoría de los usuarios de los alojamientos web de OVH, el período de bajo tráfico se produce entre la 1:00 y las 7:00 de la mañana, por lo que el backup de las bases de datos se realizaban en ese intervalo de tiempo.

¿Por qué entonces no procedemos de igual modo en la actualidad? Este enfoque pronto mostró sus limitaciones. Durante el intervalo de 1:00 a 7:00 AM, nuestros indicadores de sistema pasaban con frecuencia a rojo intenso: se producían cuellos de botella, los «dumps» (archivos de exportación de bases de datos SQL) tomaban más tiempo en ejecutarse y la calidad del servicio se veía amenazada ya que, en ocasiones, se depasaba el intervalo de tiempo destinado a efectuar el backup. En este sentido, la plataforma debía absorber la carga generada por el backup a medida que aumentaba la afluencia de tráfico en los sitios web alojados. En resumen, hacía falta una solución.

Entonces adoptamos otro enfoque y distribuimos la realización del backup a lo largo de todo el día para conservar el rendimiento óptimo en los alojamientos web a cualquier hora del día y de la noche.

El algoritmo de distribución

Para efectuar la distribución uniforme de copias de seguridad durante el día, necesitábamos asociar cada hora del día a una base de datos.

Pero no podíamos efectuar la distribución (o «sharding») solamente en función del nombre de la base de datos, pues en toda la infraestructura hay un número incalculable de bases de datos llamadas «wordpress», «prestashop», «test» o «demo», y el backup de todas las bases de datos «wordpress» se ejecutaría a la misma hora, lo que no habría sido muy eficaz.

Por otra parte, tampoco podíamos hacer un sharding basándonos solo en el nombre de la instancia que aloja la base de datos, aunque este fuera único, pues al tener muchas menos instancias que bases de datos, la ley de los grandes números hace que la distribución del backup a lo largo del día en función de la identidad de las instancias sea menos uniforme que la distribución en función de la identidad de las propias bases de datos. Entonces combinamos ambos datos y, actualmente, utilizamos la concatenación del nombre de la base de datos y de la instancia para efectuar el sharding.

Solo nos quedaba encontrar una fórmula que permitiera asociar esta cadena de caracteres a una hora del día, es decir, a un número comprendido entre 1 y 1440 (la cantidad de minutos en un día). Como el número 1440 es divisible por 16 (gracias a los babilonios por apostar por la muy divisible base 60 para calcular los minutos y segundos), utilizamos una simple función de hash criptográfica (digest) hexadecimal (el sha512) para generar el famoso número:

int(hashlib.sha512(instance_name + "." + db_name).hexdigest()[:90], 16) % 1440

Como muestra la siguiente gráfica, el backup se distribuye uniformemente en el tiempo.

Número de copias de seguridad programadas por intervalos de 5 minutos.

¿Cómo efectuamos el backup?

El backup de las bases de datos se puede efectuar a través de dos métodos: exportando los datos en formato SQL, o guardando una copia de las bases de datos en un formato legible por el sistema de gestión de bases de datos (DBMS, del inglés Data Base Management System), como MySQL, por ejemplo. Cada método tiene sus ventajas, sus inconvenientes, y sus casos prácticos específicos. Nosotros hemos optado por combinar ambos métodos para aprovechar la suma de beneficios.

Los dumps

El método del «dump» se basa en la creación de un archivo de texto de comandos SQL que, al ejecutarse, vuelven a crear la base de datos en el estado en que se encontraba en el momento de la exportación. Como ventaja, este método permite migrar datos a otras versiones del DBMS o de otros motores. También permite editar manualmente el archivo antes de reimportarlo (algo que puede ser útil en caso de que deseemos clonar un entorno de producción para hacer pruebas y que algunas tablas de gran tamaño sean inútiles).

Estas ventajas hacen que empleemos este método, y que a su vez brindemos a los clientes el acceso a los dumps, que se pueden ver y descargar directamente desde el manager. Como ya hemos visto anteriormente, los dumps se llevan a cabo todos los días a una hora fija, y se conservan durante un mes.

Para que un dump sea coherente (o sea, que refleje perfectamente el estado de la base de datos en un momento dado), podemos utilizar dos métodos:

Bloquear las tablas

Este método consiste en mantener la base de datos en su estado y poner las conexiones en espera, para que se apilen. Una vez finalizado el dump, se desbloquea y se despeja la cola de espera.

• Ventajas: Este método es compatible con todos los motores (incluyendo los principales: MyISAM e InnoDB) y el dump siempre es coherente.

• Inconveniente: Las tablas se bloquean y hay que esperar a que termine el dump para acceder a la base de datos (y, por tanto, al sitio web). En la mayoría de los casos, esto no constituye un problema, pero puede llegar a serlo si el dump se prolonga y el número de conexiones aumenta, alcanzando el máximo de conexiones simultáneas a la base de datos. Cabe destacar que el aumento de este máximo de conexiones no solucionaría el problema; solo lo aplazaría. Además, la limitación del número de conexiones protegería el servidor: una conexión requiere RAM y, con más de 200 conexiones simultáneas (el máximo autorizado para instancias de SQL Privado), la RAM asignada a las conexiones abiertas podría generar un error de tipo «out of memory» en la instancia.

Utilizar una transacción

• Ventajas: El dump es totalmente transparente y siempre coherente. No se produce ningún bloqueo.
• Inconvenientes: Solo es posible con un motor que gestione las transacciones (InnoDB), es decir, que si hay aunque sea una tabla en MyISAM, el dump sería incoherente. Además, incluso solamente con InnoDB, si se realiza un ALTER, CREATE, DROP, RENAME o TRUNCATE TABLE durante el dump, este será incoherente.

Por todo esto, hemos combinado ambos métodos: si la base de datos es 100% InnoDB, utilizamos una transacción; si no, el bloqueo de las tablas.

Es por ello que recomendamos a nuestros clientes pasar todas sus tablas a formato InnoDB, que está incluido y activado en todas las distribuciones de MySQL AB desde la versión 4 y es el motor por defecto a partir de MySQL 5.5.5.

El backup en formato DBMS

Como ya hemos visto, realizar el «dump» de una base de datos ofrece numerosas ventajas en comparación con un backup clásico. Sin embargo, este método presenta un inconveniente: la duración de la restauración, que depende del tamaño del dump.

El volumen de dumps efectuados a diario nos ha permitido establecer estadísticas muy precisas sobre la duración de las exportaciones y restauraciones. A continuación, se observa el resultado de las regresiones lineales que hemos calculado en función del tiempo de respuesta de más de 40 mil exportaciones de bases de datos 100% InnoDB (una opción que permite despreciar el tiempo de espera previo al bloqueo de la base de datos).

$ ./lr.py list
y=0.142865163057*x1+4.65205077853
R2=0.792955

Duración del dump en función del tamaño de la base de datos, en MB

R2 es el coeficiente de correlación. Un valor de 0.8 significa que la correlación es alta, o sea, que tiene sentido determinar la duración de un dump en función del tamaño de la base de datos, ya que los valores están estrechamente relacionados.

Nos preguntamos si había otros parámetros que influyeran en la determinación de la duración del dump y de la restauración, entonces repetimos el ejercicio con distintas variables: número de filas, tamaño medio de los registros... Finalmente, el único cálculo pertinente, además del tamaño de la base de datos, era el número de registros (filas):

$ ./lr.py list
y=2.62412392084*x1+0.130888461045*x2+4.60953501036
R2=0.800904

Duración del dump en función del número de registros (en millones) y del tamaño de la base de datos (en MB)

A partir de los análisis realizados, hemos adaptado nuestra estrategia para minimizar el tiempo de restauración de las bases de datos en caso de incidencia en nuestros sistemas, pues sabemos que una base de datos no disponible significa que el sitio web correspondiente tampoco está disponible, y la situación para el usuario es crítica. De esta forma, cuando el tamaño de una instancia que aloja bases de datos es superior a 4 GB (lo que corresponde a una duración media de restauración de 10 minutos), duplicamos sistemáticamente los dumps de backup en formato DBMS. Esto tiene la ventaja de que la restauración es más rápida ante algún problema en un cluster de almacenamiento. Estas copias, que se realizan para todas las instancias compartidas que alojan bases de datos, así como para las instancias de SQL Privado de más de 4 GB, no están a disposición de los usuarios; solo sirven en caso de que haya un problema en un cluster de almacenamiento. Por su parte, el usuario solo tiene acceso a sus dumps.

Para realizar este backup en formato DBMS, utilizamos, para MySQL y MariaDB, la herramienta XtraBackup en modo full-backup (y no en modo incremental), con el fin de facilitar la restauración. XtraBackup es una herramienta open source de Percona que permite realizar backups coherentes y sin bloqueo de las tablas, independientemente del motor utilizado (MyISAM, InnoDB...). Es importante tener en cuenta que las copias de seguridad con XtraBackup se hacen a escala de una instancia completa y no de una simple base de datos. Para PostgreSQL, empleamos pg_basebackup.

Verificación de las tablas y necesidades de RAM

Antes de realizar un dump (ya sea diario o puntual), comprobamos el estado de las tablas y las reparamos si es necesario. En instancias MySQL y MariaDB, utilizamos el comando mysqlcheck. Este problema tiende a desaparecer, ya que las últimas versiones de MySQL y MariaDB gestionan cada vez mejor la escritura de operaciones interrumpidas por crashes, y el problema no existe en absoluto con PostgreSQL.

La comprobación de una tabla, y sobre todo su reparación, puede requerir mucha más RAM que la que tiene la instancia. Por ese motivo, mientras se realiza el mysqlcheck y el dump, aumentamos temporalmente la RAM de la instancia añadiéndole 4 GB. Si las bases de datos son lo suficientemente grandes, usted podrá constatar el aumento de la RAM en el manager:

En caso de que los dumps tomen menos de un minuto, esta adición de RAM puede pasar desapercibida entre dos mediciones, de modo que no sería visible en las gráficas del manager.

Es importante señalar que este pico de memoria disponible va a distorsionar la gráfica, haciendo que la curva de uso de memoria sea casi ilegible, de modo que no dude en hacer clic en «Límite máximo de RAM», debajo de la gráfica, para mostrar solamente la curva de uso de memoria.

¿Dónde almacenamos las copias de seguridad?

Un backup solo tiene sentido si está almacenado en una plataforma distinta. Es por ello que conservamos los dumps en la plataforma Public Cloud Storage, totalmente independiente de las plataformas de gestión de bases de datos del servicio de alojamiento en internet. Así las copias de seguridad se distribuyen en tres réplicas síncronas, situadas en tres dominios de incidencias distintos: uno en Gravelines, otro en Roubaix y un tercero en Estrasburgo. Las copias en cuestión se conservarán durante un mes.

Por su parte, las copias de seguridad XtraBackup y pg_basebackup de los SQL Privado de la plataforma de París (planes de alojamiento creados antes de julio de 2016), se almacenan en un cluster Ceph diferente del utilizado para almacenar los datos de producción. Por último, las copias de seguridad de la plataforma de Gravelines (planes de hosting creados a partir de julio de 2016) se conservan en los discos duros locales (y los datos de producción, en un cluster Ceph).

Mi cuenta de clienteContact SalesWebmail OVHcloud Blog

¡Bienvenido/a a OVHcloud!

Identifíquese para contratar una solución, gestionar sus productos y servicios, y consultar sus pedidos

Conectar