这个问题在这里已经有答案了:

如何在 MySQL 中进行备份?

我希望有比每“x”小时运行 mysqldump 更好的东西。

有没有像 SQL Server 那样的东西,您可以每天进行完整备份,然后每小时进行增量备份,这样如果您的数据库损坏了,您可以恢复到最新的备份?

像DB日志这样的东西,只要日志不死,就可以恢复到DB死的确切点?

另外,这些东西如何影响锁定?如果我执行 mysqldump,我预计在线事务会被锁定一段时间。

有帮助吗?

解决方案

您可能想看看 增量备份.

其他提示

mysqldump 是一种合理的方法,但请记住,对于某些引擎,这将在转储期间锁定您的表 - 这对于大型生产数据集存在可用性问题。

一个明显的替代方案是来自 Maatkit 的 mk-parallel-dump (http://www.maatkit.org/)如果你是 mysql 管理员,你真的应该检查一下。这会使用 mysqldump 并行转储多个表或数据库,从而减少转储所需的总时间。

如果您在复制设置中运行(并且如果您在生产中使用 MySQL 来存储重要数据,那么您没有理由不这样做),从专用于该目的的复制从属设备中获取转储将防止任何锁定问题制造麻烦。

下一个明显的替代方案(至少在 Linux 上)是使用 LVM 快照。您可以锁定表、对文件系统进行快照并再次解锁表;然后使用该快照的安装启动另一个 MySQL,并从那里转储。这种方法的描述如下: http://www.mysqlperformanceblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/

现在我开始听起来像这个产品的营销人员了。我用它回答了一个问题 这里, ,然后我又回答了另一个 这里.

简而言之,尝试 sqlyog (您的案例中的企业) 网约格 满足您所有的 mysql 需求。它不仅 安排备份, , 但是也 日程同步 因此您实际上可以将数据库复制到远程服务器。

它有免费的社区版和企业版。我向您推荐后者,但我也建议您从通讯版开始,然后首先 看看你喜欢它.

我使用 mysqlhotcopy,一个 本地 MySQL 数据库和表的快速在线热备份实用程序. 。我对此很满意。

Percona 的人制作了 innobackup 的开源替代品......

超备份

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

阅读这篇关于 XtraDB 的文章http://www.linux-mag.com/cache/7356/1.html

您可能想补充当前的离线备份方案 MySQL复制.

然后,如果出现硬件故障,您只需更换机器即可。如果您很快发现故障,您的用户甚至不会注意到任何停机或数据丢失。

我使用一个简单的脚本,将 mysql 数据库转储到 tar.gz 文件中,使用 gpg 对其进行加密并将其发送到邮件帐户(Google Mail,但这实际上无关紧要)

该脚本是一个 Python 脚本,它基本上运行以下命令,并通过电子邮件发送输出文件。

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

这是整个备份。它还具有网络备份部分,仅 tar/gzips/加密文件。这是一个相当小的站点,因此 Web 备份远小于 20MB,因此可以毫无问题地发送到 GMail 帐户(MySQL 转储很小,压缩后约为 300KB)。它非常基础,并且无法很好地扩展。我使用 cron 每周运行一次。

我不太确定我们应该如何在答案中放入较长的脚本,所以我只是把它作为代码块。

#!/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()

您可以通过 mysqldump 使用“--single-transaction --skip-lock-tables”选项对 InnoDB 数据库/表进行完全转储,而无需锁定(停机)。非常适合制作每周快照+每日/每小时快照 二进制日志增量 (#使用二进制日志启用增量备份)。

@杰克,

谢谢(你的)信息。现在,似乎只有商业版本具有备份功能。

MySQL 中没有内置任何东西来进行像样的备份吗?

MySQL 官方页面甚至推荐诸如“好吧,你可以复制这些文件,只要它们没有被更新”......

直接备份mysql数据库文件夹的问题是备份不一定一致,除非在备份时做了写锁。

我运行一个脚本来遍历所有数据库,对每个数据库执行 mysqldump 和 gzip 到备份文件夹,然后将该文件夹备份到磁带。

然而,这意味着不存在这样的事情 增加的 备份,因为夜间转储是完整转储。但我认为这可能是一件好事,因为从 完整备份 这将是一个比从增量恢复快得多的过程 - 如果您要备份到磁带,则可能意味着在进行完整恢复之前需要收集大量磁带。

无论如何,无论您采用哪种备份计划,请务必进行试用恢复以确保其有效,并了解可能需要多长时间以及您需要执行哪些步骤。

运行 mysql 服务器增量或连续备份的正确方法是使用二进制日志。

首先,锁定所有表或关闭服务器。使用 mysql dump 进行备份,或者只是复制数据目录。您只需执行一次此操作,或者在任何需要完整备份的时候执行此操作。

在恢复服务器之前,请确保启用二进制日志记录。

要进行增量备份,请登录到服务器并发出 FLUSH LOGS 命令。然后备份最近关闭的二进制日志文件。

如果你有所有innodb表,那么使用inno热备份(不是免费的)或带有--single-transaction选项的mysqldump会更简单(你最好有大量内存来处理事务)。

二进制日志可能是执行增量备份的正确方法,但如果您不信任用于永久存储的二进制文件格式,这里有一种执行增量备份的 ASCII 方法。

mysqldump 不是一种糟糕的格式,主要问题是它将表中的内容输出为一大行。以下简单的 sed 将沿着记录边界分割其输出:

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

生成的文件非常适合差异化,并且我已经相当成功地将它们保存在标准 SVN 存储库中。如果您发现上一个版本已失效并且您需要上周的版本,这还允许您保留备份历史记录。

这是一个非常可靠的 Linux shell 解决方案。我已经使用它很多年了:

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

  • 是否滚动备份:每日、每月、每年
  • 很多选择

@丹尼尔,

如果您仍然感兴趣,有一个新的(对我来说是新的)解决方案由 保罗·加尔布雷斯, ,一个允许在线备份 innodb 表的工具,称为 备份 引用保罗的神谕,

当与一起使用时 创新备份, ,在创建夜间备份方面做得很好,在备份期间没有停机时间

可以在以下位置找到更多详细信息: 保罗的博客

听起来你在谈论事务回滚。

因此,就您所需要的而言,如果您拥有包含所有历史查询的日志,那不是已经备份了吗?为什么需要增量备份,它基本上是数据库日志中所有信息的冗余副本?

如果是这样,为什么不使用 mysqldump 并每隔一段时间进行备份呢?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top