Pergunta

Essa pergunta já tem resposta aqui:

Como faço backups no MySQL?

Espero que haja algo melhor do que apenas executar o mysqldump a cada "x" horas.

Existe algo parecido com o SQL Server, onde você pode fazer um backup completo todos os dias e, em seguida, incrementais a cada hora, para que, se o seu banco de dados morrer, você possa restaurar o backup mais recente?

Algo como o log do banco de dados, onde, desde que o log não morra, você pode restaurar até o ponto exato onde o banco de dados morreu?

Além disso, como essas coisas afetam o bloqueio?Eu esperaria que as transações on-line ficassem bloqueadas por um tempo se eu fizesse um mysqldump.

Foi útil?

Solução

Você pode querer dar uma olhada backups incrementais.

Outras dicas

mysqldump é uma abordagem razoável, mas tenha em mente que, para alguns mecanismos, isso bloqueará suas tabelas durante o dump - e isso traz problemas de disponibilidade para grandes conjuntos de dados de produção.

Uma alternativa óbvia para isso é mk-parallel-dump do Maatkit (http://www.maatkit.org/) que você realmente deveria verificar se for um administrador mysql.Isso faz dump de múltiplas tabelas ou bancos de dados em paralelo usando mysqldump, diminuindo assim o tempo total que seu dump leva.

Se você estiver executando em uma configuração replicada (e se estiver usando MySQL para dados importantes em produção, você não tem desculpas para não fazer isso), fazer dumps de um escravo de replicação dedicado a esse propósito evitará quaisquer problemas de bloqueio de causando problemas.

A próxima alternativa óbvia - pelo menos no Linux - é usar instantâneos LVM.Você pode bloquear suas tabelas, capturar instantâneos do sistema de arquivos e desbloquear as tabelas novamente;em seguida, inicie um MySQL adicional usando uma montagem desse instantâneo, despejando a partir daí.Esta abordagem é descrita aqui: http://www.mysqlperformanceblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/

agora estou começando a parecer um profissional de marketing deste produto.eu respondi uma pergunta com isso aqui, então eu respondi outro com isso novamente aqui.

em poucas palavras, tente sqlyog (empresa no seu caso) de webyog para todos os seus requisitos de mysql.não só agenda backups, mas também sincronização de horários para que você possa realmente replicar seu banco de dados para um servidor remoto.

tem uma edição comunitária gratuita e também uma edição empresarial.eu recomendo o último para você, mas também recomendo que você comece com a edição comm e primeiro Veja como você gosta.

Eu uso mysqlhotcopy, um utilitário rápido de backup on-line para bancos de dados e tabelas MySQL locais.Estou muito feliz com isso.

o pessoal da Percona criou uma alternativa de código aberto para o innobackup ...

Xtrabackup

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

Leia este artigo sobre o XtraDBhttp://www.linux-mag.com/cache/7356/1.html

Você pode querer complementar seu esquema de backup offline atual com Replicação MySQL.

Então, se você tiver uma falha de hardware, poderá simplesmente trocar de máquina.Se você detectar a falha rapidamente, seus usuários nem notarão nenhum tempo de inatividade ou perda de dados.

Eu uso um script simples que despeja o banco de dados mysql em um arquivo tar.gz, criptografa-o usando gpg e envia-o para uma conta de e-mail (Google Mail, mas isso é realmente irrelevante)

O script é um script Python, que basicamente executa o seguinte comando e envia por e-mail o arquivo de saída.

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

Este é o backup completo.Ele também possui a parte de backup da web, que apenas tar/gzipa/criptografa os arquivos.É um site bastante pequeno, então os backups da web têm muito menos de 20 MB, portanto podem ser enviados para a conta do GMail sem problemas (os dumps do MySQL são pequenos, cerca de 300 KB compactados).É extremamente básico e não será muito bem dimensionado.Eu executo uma vez por semana usando o cron.

Não tenho certeza de como devemos colocar scripts longos nas respostas, então vou colocá-los como um bloco 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()

Você pode fazer dumps completos de bancos de dados/tabelas InnoDB sem bloqueio (tempo de inatividade) via mysqldump com as opções "--single-transaction --skip-lock-tables".Funciona bem para fazer snapshots semanais + diários/de hora em hora incrementos de log binário (#Usando o log binário para ativar backups incrementais).

@Jake,

Obrigado pela informação.Agora, parece que apenas a versão comercial possui recursos de backup.

Não existe NADA embutido no MySQL para fazer backups decentes?

A página oficial do MySQL até recomenda coisas como "bem, você pode copiar os arquivos, ENQUANTO ELES NÃO ESTÃO SENDO ATUALIZADOS"...

O problema com um backup direto da pasta do banco de dados mysql é que o backup não será necessariamente consistente, a menos que você faça um bloqueio de gravação durante o backup.

Eu executo um script que percorre todos os bancos de dados, fazendo um mysqldump e gzip em cada um para uma pasta de backup e, em seguida, faço backup dessa pasta em fita.

Isto, no entanto, significa que não existe tal coisa como incremental backups, já que o dump noturno é um dump completo.Mas eu diria que isso poderia ser uma coisa boa, já que uma restauração de um backup completo será um processo significativamente mais rápido do que a restauração incremental - e se você estiver fazendo backup em fita, isso provavelmente significará reunir várias fitas antes de poder fazer uma restauração completa.

De qualquer forma, seja qual for o plano de backup escolhido, certifique-se de fazer uma restauração de teste para garantir que funciona e tenha uma ideia de quanto tempo pode levar e exatamente quais etapas você precisa seguir.

a maneira correta de executar backups incrementais ou contínuos de um servidor mysql é com logs binários.

para começar, bloqueie todas as tabelas ou desative o servidor.use mysql dump para fazer um backup ou apenas copie o diretório de dados.você só precisa fazer isso uma vez ou sempre que desejar um backup COMPLETO.

antes de reativar o servidor, certifique-se de que o log binário esteja ativado.

para fazer um backup incremental, faça login no servidor e emita um comando FLUSH LOGS.em seguida, faça backup do arquivo de log binário fechado mais recentemente.

se você tiver todas as tabelas innodb, é mais simples usar inno hot backup (não gratuito) ou mysqldump com a opção --single-transaction (é melhor você ter muita memória para lidar com as transações).

Os logs binários são provavelmente a maneira correta de fazer backups incrementais, mas se você não confia em formatos de arquivos binários para armazenamento permanente, aqui está uma maneira ASCII de fazer backups incrementais.

mysqldump não é um formato ruim, o principal problema é que ele gera uma tabela como uma grande linha.O seguinte sed trivial dividirá sua saída ao longo das bordas do registro:

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

O arquivo resultante é bastante amigável e eu os tenho mantido em um repositório SVN padrão com bastante sucesso.Isso também permite que você mantenha um histórico de backups, caso você descubra que a última versão foi interrompida e você precisa da versão da semana passada.

Esta é uma solução bastante sólida para shell Linux.Eu uso há anos:

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

  • Os backups contínuos:diariamente, mensalmente, anualmente
  • Muitas opções

@Daniel,

caso você ainda esteja interessado, há uma solução mais recente (nova para mim) compartilhada por Paulo Galbraith, uma ferramenta que permite backup online de tabelas innodb chamada ibbackup do oráculo que cita Paulo,

quando usado em conjunto com innobackup, funcionou muito bem na criação de um backup noturno, sem tempo de inatividade durante o backup

mais detalhes podem ser encontrados em blog de Paulo

Parece que você está falando sobre reversão de transação.

Então, em termos do que você precisa, se você tiver os logs contendo todas as consultas históricas, esse já não é o backup?Por que você precisa de um backup incremental que é basicamente uma cópia redundante de todas as informações nos logs do banco de dados?

Se sim, por que você não usa o mysqldump e faz o backup de vez em quando?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top