Pregunta

Esta pregunta ya tiene respuesta aquí:

¿Cómo hago copias de seguridad en MySQL?

Espero que haya algo mejor que simplemente ejecutar mysqldump cada "x" horas.

¿Existe algo como SQL Server, donde pueda realizar una copia de seguridad completa cada día y luego incremental cada hora, de modo que si su base de datos muere, pueda restaurarla hasta la última copia de seguridad?

¿Algo así como el registro de la base de datos, donde mientras el registro no muera, puede restaurar hasta el punto exacto donde murió la base de datos?

Además, ¿cómo afectan estas cosas al bloqueo?Esperaría que las transacciones en línea quedaran bloqueadas por un tiempo si hago un mysqldump.

¿Fue útil?

Solución

Quizás quieras mirar copias de seguridad incrementales.

Otros consejos

mysqldump es un enfoque razonable, pero tenga en cuenta que, para algunos motores, esto bloqueará sus tablas mientras dure el volcado, y esto genera problemas de disponibilidad para grandes conjuntos de datos de producción.

Una alternativa obvia a esto es mk-parallel-dump de Maatkit (http://www.maatkit.org/) que realmente deberías consultar si eres administrador de MySQL.Esto volca múltiples tablas o bases de datos en paralelo usando mysqldump, disminuyendo así la cantidad de tiempo total que lleva el volcado.

Si está ejecutando una configuración replicada (y si está usando MySQL para datos importantes en producción, no tiene excusas para no hacerlo), realizar volcados de un esclavo de replicación dedicado para ese propósito evitará que se produzcan problemas de bloqueo. causando problemas.

La siguiente alternativa obvia, al menos en Linux, es utilizar instantáneas LVM.Puede bloquear sus tablas, tomar una instantánea del sistema de archivos y desbloquear las tablas nuevamente;luego inicie un MySQL adicional usando un montaje de esa instantánea, volcando desde allí.Este enfoque se describe aquí: http://www.mysqlrendimientoblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/

Ahora empiezo a parecer un comercializador de este producto.respondí una pregunta con eso aquí, luego respondí a otro con eso nuevamente. aquí.

En pocas palabras, pruebe sqlyog (empresa en su caso) desde webyog para todos sus requisitos de MySQL.no solo programa copias de seguridad, pero también sincronización de horarios para que pueda replicar su base de datos en un servidor remoto.

Tiene una edición comunitaria gratuita y una edición empresarial.Te recomiendo la última, aunque también te recomiendo que empieces con la edición comm y la primera. mira como te gusta.

Yo uso mysqlhotcopy, un Rápida utilidad de copia de seguridad en línea para bases de datos y tablas MySQL locales..Estoy muy contento con eso.

los chicos de Percona hicieron una alternativa de código abierto a innobackup…

Xtracopia de seguridad

https://launchpad.net/percona-xtrabackup/

Lea este artículo sobre XtraDBhttp://www.linux-mag.com/cache/7356/1.html

Es posible que desee complementar su esquema de copia de seguridad fuera de línea actual con replicación de MySQL.

Luego, si tiene una falla de hardware, puede simplemente cambiar las máquinas.Si detecta la falla rápidamente, sus usuarios ni siquiera notarán ningún tiempo de inactividad o pérdida de datos.

Utilizo un script simple que vuelca la base de datos MySQL en un archivo tar.gz, lo cifra usando gpg y lo envía a una cuenta de correo (Google Mail, pero eso es realmente irrelevante).

El script es un script de Python, que básicamente ejecuta el siguiente comando y envía por correo electrónico el archivo de salida.

mysqldump -u theuser -p mypassword thedatabase | gzip -9 - | gpg -e -r 12345 -r 23456 > 2008_01_02.tar.gz.gpg

Esta es la copia de seguridad completa.También tiene la parte de copia de seguridad web, que simplemente tar/gzips/encripta los archivos.Es un sitio bastante pequeño, por lo que las copias de seguridad web pesan mucho menos de 20 MB, por lo que se pueden enviar a la cuenta de GMail sin problemas (los volcados de MySQL son pequeños, alrededor de 300 KB comprimidos).Es extremadamente básico y no escalará muy bien.Lo ejecuto una vez por semana usando cron.

No estoy muy seguro de cómo se supone que debemos poner guiones largos en las respuestas, así que simplemente lo incluiré como un bloque de código.

#!/usr/bin/env python
#encoding:utf-8
#
# Creates a GPG encrypted web and database backups, and emails it

import os, sys, time, commands

################################################
### Config

DATE = time.strftime("%Y-%m-%d_%H-%M")

# MySQL login
SQL_USER = "mysqluser"
SQL_PASS = "mysqlpassword"
SQL_DB = "databasename"

# Email addresses
BACKUP_EMAIL=["email1@example.com", "email2@example.com"] # Array of email(s)
FROM_EMAIL = "root@myserver.com" # Only one email

# Temp backup locations
DB_BACKUP="/home/backupuser/db_backup/mysite_db-%(date)s.sql.gz.gpg" % {'date':DATE}
WEB_BACKUP="/home/backupuser/web_backup/mysite_web-%(date)s.tar.gz.gpg" % {'date':DATE}

# Email subjects
DB_EMAIL_SUBJECT="%(date)s/db/mysite" % {'date':DATE}
WEB_EMAIL_SUBJECT="%(date)s/web/mysite" % {'date':DATE}

GPG_RECP = ["MrAdmin","MrOtherAdmin"]
### end Config
################################################

################################################
### Process config
GPG_RECP = " ".join(["-r %s" % (x) for x in GPG_RECP]) # Format GPG_RECP as arg

sql_backup_command = "mysqldump -u %(SQL_USER)s -p%(SQL_PASS)s %(SQL_DB)s | gzip -9 - | gpg -e %(GPG_RECP)s > %(DB_BACKUP)s" % {
    'GPG_RECP':GPG_RECP,
    'DB_BACKUP':DB_BACKUP,
    'SQL_USER':SQL_USER,
    'SQL_PASS':SQL_PASS,
    'SQL_DB':SQL_DB
}

web_backup_command = "cd /var/www/; tar -c mysite.org/ | gzip -9 | gpg -e %(GPG_RECP)s > %(WEB_BACKUP)s" % {
    'GPG_RECP':GPG_RECP,
    'WEB_BACKUP':WEB_BACKUP,
}
# end Process config
################################################

################################################
### Main application
def main():
        """Main backup function"""
        print "Backing commencing at %s" % (DATE)

        # Run commands
        print "Creating db backup..."
        sql_status,sql_cmd_out = commands.getstatusoutput(sql_backup_command)
        if sql_status == 0:
                db_file_size = round(float( os.stat(DB_BACKUP)[6]  ) /1024/1024, 2) # Get file-size in MB
                print "..successful (%.2fMB)" % (db_file_size)
                try:
                    send_mail(
                        send_from = FROM_EMAIL,
                        send_to   = BACKUP_EMAIL,
                        subject   = DB_EMAIL_SUBJECT,
                        text      = "Database backup",
                        files     = [DB_BACKUP],
                        server    = "localhost"
                    )
                    print "Sending db backup successful"
                except Exception,errormsg:
                    print "Sending db backup FAILED. Error was:",errormsg
                #end try

                # Remove backup file
                print "Removing db backup..."
                try:
                        os.remove(DB_BACKUP)
                        print "...successful"
                except Exception, errormsg:
                        print "...FAILED. Error was: %s" % (errormsg)
                #end try
        else:
                print "Creating db backup FAILED. Output was:", sql_cmd_out
        #end if sql_status

        print "Creating web backup..."
        web_status,web_cmd_out = commands.getstatusoutput(web_backup_command)
        if web_status == 0:
                web_file_size = round(float( os.stat(WEB_BACKUP)[6]  ) /1024/1024, 2) # File size in MB
                print "..successful (%.2fMB)" % (web_file_size)
                try:
                    send_mail(
                        send_from = FROM_EMAIL,
                        send_to   = BACKUP_EMAIL,
                        subject   = WEB_EMAIL_SUBJECT,
                        text      = "Website backup",
                        files     = [WEB_BACKUP],
                        server    = "localhost"
                    )
                    print "Sending web backup successful"
                except Exception,errormsg:
                    print "Sending web backup FAIELD. Error was: %s" % (errormsg)
                #end try

                # Remove backup file
                print "Removing web backup..."
                try:
                        os.remove(WEB_BACKUP)
                        print "...successful"
                except Exception, errormsg:
                        print "...FAILED. Error was: %s" % (errormsg)
                #end try
        else:
                print "Creating web backup FAILED. Output was:", web_cmd_out
        #end if web_status
#end main
################################################

################################################
# Send email function

# needed email libs..
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

def send_mail(send_from, send_to, subject, text, files=[], server="localhost"):
        assert type(send_to)==list
        assert type(files)==list

        msg = MIMEMultipart()
        msg['From'] = send_from
        msg['To'] = COMMASPACE.join(send_to)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject

        msg.attach( MIMEText(text) )

        for f in files:
                part = MIMEBase('application', "octet-stream")
                try:
                    part.set_payload( open(f,"rb").read() )
                except Exception, errormsg:
                    raise IOError("File not found: %s"%(errormsg))
                Encoders.encode_base64(part)
                part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
                msg.attach(part)
    #end for f

        smtp = smtplib.SMTP(server)
        smtp.sendmail(send_from, send_to, msg.as_string())
        smtp.close()
#end send_mail
################################################

if __name__ == '__main__':
        main()

Puede realizar volcados completos de bases de datos/tablas InnoDB sin bloquear (tiempo de inactividad) a través de mysqldump con las opciones "--single-transaction --skip-lock-tables".Funciona bien para tomar instantáneas semanales + diarias/horarias incrementos de registro binario (#Uso del registro binario para habilitar copias de seguridad incrementales).

@Jake,

Gracias por la info.Ahora parece que sólo la versión comercial tiene funciones de copia de seguridad.

¿No hay NADA integrado en MySQL para realizar copias de seguridad decentes?

La página oficial de MySQL incluso recomienda cosas como "bueno, puedes copiar los archivos, MIENTRAS NO SE ACTUALICEN"...

El problema con una copia de seguridad directa de la carpeta de la base de datos MySQL es que la copia de seguridad no necesariamente será consistente, a menos que realice un bloqueo de escritura durante la copia de seguridad.

Ejecuto un script que recorre todas las bases de datos, haciendo un mysqldump y gzip en cada una de ellas en una carpeta de respaldo, y luego hago una copia de seguridad de esa carpeta en una cinta.

Esto, sin embargo, significa que no existe tal cosa como incremental copias de seguridad, ya que el volcado nocturno es un volcado completo.Pero yo diría que esto podría ser algo bueno, ya que una restauración desde un copia de seguridad completa será un proceso significativamente más rápido que la restauración desde archivos incrementales, y si realiza una copia de seguridad en cinta, probablemente significará reunir varias cintas antes de poder realizar una restauración completa.

En cualquier caso, sea cual sea el plan de respaldo que elija, asegúrese de realizar una restauración de prueba para asegurarse de que funcione y tener una idea de cuánto tiempo podría llevar y exactamente cuáles son los pasos que debe seguir.

La forma correcta de ejecutar copias de seguridad incrementales o continuas de un servidor MySQL es con registros binarios.

Para empezar, bloquee todas las mesas o cierre el servidor.use el volcado de mysql para hacer una copia de seguridad o simplemente copie el directorio de datos.sólo tienes que hacer esto una vez, o cada vez que quieras una copia de seguridad COMPLETA.

Antes de restablecer el servidor, asegúrese de que el registro binario esté habilitado.

para realizar una copia de seguridad incremental, inicie sesión en el servidor y emita un comando FLUSH LOGS.luego haga una copia de seguridad del archivo de registro binario cerrado más recientemente.

Si tiene todas las tablas innodb, es más sencillo usar inno hot backup (no gratuito) o mysqldump con la opción --single-transaction (será mejor que tenga mucha memoria para manejar las transacciones).

Los registros binarios son probablemente la forma correcta de realizar copias de seguridad incrementales, pero si no confía en los formatos de archivos binarios para el almacenamiento permanente, aquí tiene una forma ASCII de realizar copias de seguridad incrementales.

mysqldump no es un mal formato, el principal problema es que genera una tabla como una línea grande.El siguiente sed trivial dividirá su salida a lo largo de los límites de los registros:

mysqldump --opt -p | sed -e "s/, (/, n (/g"> database.dump

El archivo resultante es bastante compatible con las diferencias y los he mantenido en un repositorio SVN estándar con bastante éxito.Eso también le permite mantener un historial de copias de seguridad, si descubre que la última versión falló y necesita la versión de la semana pasada.

Esta es una solución bastante sólida para el shell de Linux.Lo he estado usando por años:

http://sourceforge.net/projects/automysqlbackup/

  • ¿Las copias de seguridad continuas:diario, mensual, anual
  • Muchas opciones

@Daniel,

En caso de que todavía esté interesado, hay una solución nueva (nueva para mí) compartida por Pablo Galbraith, una herramienta que permite realizar copias de seguridad en línea de tablas innodb llamada ibbackup del oráculo que cita a Pablo,

cuando se utiliza junto con innobackup, ha funcionado muy bien en la creación de una copia de seguridad nocturna, sin tiempo de inactividad durante la copia de seguridad

se pueden encontrar más detalles en el blog de pablo

Suena como si estuviera hablando de reversión de transacciones.

Entonces, en términos de lo que necesita, si tiene los registros que contienen todas las consultas históricas, ¿no es ya la copia de seguridad?¿Por qué necesita una copia de seguridad incremental que es básicamente una copia redundante de toda la información en los registros de la base de datos?

Si es así, ¿por qué no usas mysqldump y haces la copia de seguridad de vez en cuando?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top