Подтвердить что ты не робот

Как сделать резервные копии в MySQL?

Как сделать резервные копии в MySQL?

Я надеюсь, что будет что-то лучше, чем просто запустить mysqldump каждые "x" часы.

Есть ли что-то вроде SQL Server, где вы можете делать полную резервную копию каждый день, а затем увеличивать каждый час, поэтому, если ваша БД умирает, вы можете восстановить до последней резервной копии?

Что-то вроде журнала БД, где до тех пор, пока журнал не умирает, вы можете восстановить точную точку, в которой сбил DB?

Также, как эти вещи влияют на блокировку? Я ожидаю, что онлайн-транзакции будут заблокированы на некоторое время, если я сделаю mysqldump.

4b9b3361

Ответ 2

mysqldump - разумный подход, но имейте в виду, что для некоторых движков это блокирует ваши таблицы на время дампа - и это имеет проблемы доступности для больших производственных наборов данных.

Очевидной альтернативой этому является mk-parallel-dump от Maatkit (http://www.maatkit.org/), который вы действительно должны проверить, re - администратор mysql. Это дублирует несколько таблиц или баз данных параллельно с использованием mysqldump, тем самым уменьшая количество общего времени, которое занимает ваш дамп.

Если вы работаете в реплицированной установке (и если вы используете MySQL для получения важных данных на производстве, у вас нет оправданий, чтобы этого не делать), взятие дампов из подчиненного репликации, предназначенное для этой цели, предотвратит любые проблемы блокировки, вызывающие проблемы.

Следующая очевидная альтернатива - в Linux, по крайней мере, - использовать снимки LVM. Вы можете заблокировать свои таблицы, снимок файловой системы и снова разблокировать таблицы; затем запустите дополнительный MySQL, используя монтировку этого моментального снимка, отбрасывая оттуда. Этот подход описан здесь: http://www.mysqlperformanceblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/

Ответ 3

теперь я начинаю казаться маркетологом для этого продукта. я ответил на вопрос здесь, затем я ответил еще раз с ним здесь.

в двух словах, попробуйте sqlyog (предприятие в вашем случае) из webyog для всех ваших требований mysql. он не только планирует резервное копирование, но также планирует синхронизацию поэтому вы можете реально реплицировать свою базу данных на удаленный сервер.

у него есть бесплатная версия сообщества, а также корпоративная версия. Я рекомендую вам позже, хотя я также рекомендую вам начать с комм-издания и сначала посмотреть, как вам нравится.

Ответ 4

Я использую mysqlhotcopy, быструю он-лайн утилиту горячего резервного копирования для локальных баз данных MySQL и таблиц. Я очень доволен этим.

Ответ 6

Возможно, вы захотите дополнить свою текущую автономную схему резервного копирования репликацией MySQL.

Тогда, если у вас есть аппаратный сбой, вы можете просто обменять компьютеры. Если вы быстро поймаете ошибку, вы не заметите даже простоя или потери данных.

Ответ 7

Я использую простой script, который сбрасывает базу данных mysql в файл tar.gz, шифрует ее с помощью gpg и отправляет ее на почтовую учетную запись (Google Mail, но это не имеет значения)

script - это Python script, который в основном запускает следующую команду и отправляет по электронной почте выходной файл.

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

Это полная резервная копия. Он также имеет часть резервного копирования в Интернете, которая просто tar/gzips/шифрует файлы. Это довольно небольшой сайт, поэтому сетевые резервные копии намного меньше 20 МБ, поэтому их можно отправить на учетную запись GMail без проблем (дампы MySQL крошечные, около 300 КБ сжаты). Он чрезвычайно прост и не очень хорошо масштабируется. Я запускаю его один раз в неделю с помощью 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=["[email protected]", "[email protected]"] # Array of email(s)
FROM_EMAIL = "[email protected]" # 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()

Ответ 8

Вы можете делать полные дампы баз/таблиц InnoDB без блокировки (простоя) через mysqldump с параметрами "--single-transaction -skip-lock-tables". Хорошо работает для создания еженедельных снимков + ежедневный/часовой бинарный шаг вхождения в журнал (# Использование двоичного журнала для включения дополнительных резервных копий).

Ответ 9

@Jake,

Спасибо за информацию. Теперь похоже, что только коммерческая версия имеет функции резервного копирования.

Разве нет НИКАКОГО встроенного в MySQL для достойного резервного копирования?

Официальная страница MySQL даже рекомендует такие вещи, как "ну, вы можете скопировать файлы, КАК ДОЛГО, КАК ОНИ НЕ ОБНОВЛЯЮТСЯ"...

Ответ 10

Проблема с прямой резервной копией базы данных базы данных mysql заключается в том, что резервная копия не обязательно будет согласованной, если только вы не выполняете блокировку записи во время резервного копирования.

Я запускаю script, который выполняет итерацию по всем базам данных, выполняя mysqldump и gzip для каждого в резервную папку, а затем создавая резервную копию этой папки на ленту.

Это, однако, означает, что нет такой вещи, как инкрементное резервное копирование, поскольку ночной дамп - полная свалка. Но я бы сказал, что это может быть хорошо, поскольку восстановление из полной резервной копии будет значительно более быстрым процессом, чем восстановление от инкрементальности - и если вы создадите резервную копию на ленту, это, скорее всего, означает сбор нескольких лент перед вами может выполнить полное восстановление.

В любом случае, в зависимости от того, какой план резервного копирования вы используете, обязательно выполните пробное восстановление, чтобы убедиться, что он работает, и получите представление о том, как долго это может потребоваться, и точно, какие шаги вам нужно пройти.

Ответ 11

правильный способ запуска инкрементного или непрерывного резервного копирования сервера mysql состоит из двоичных журналов.

для начала, заблокируйте все таблицы или снимите сервер. используйте mysql dump для создания резервной копии или просто скопируйте каталог данных. вам нужно сделать это только один раз или в любое время, когда вы хотите получить полную резервную копию.

прежде чем вы вернете сервер, убедитесь, что включено двоичное ведение журнала.

чтобы выполнить инкрементное резервное копирование, войдите на сервер и выполните команду FLUSH LOGS. затем создайте резервную копию последнего закрытого двоичного файла журнала.

если у вас есть все таблицы innodb, проще просто использовать inno hot backup (не бесплатно) или mysqldump с опцией --single-transaction (вам нужно иметь большую память для обработки транзакций).

Ответ 12

Двоичные журналы, вероятно, являются правильным способом создания инкрементных резервных копий, но если вы не доверяете форматам двоичных файлов для постоянного хранения, это способ ASCII для инкрементного резервного копирования.

mysqldump - это не плохой формат, основная проблема заключается в том, что он выводит материал как одну большую строку. Следующий тривиальный sed будет разделять его выход вдоль границ записи:

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

Полученный файл довольно дружелюбен, и я сохраняю их в стандартном репозитории SVN довольно успешно. Это также позволяет сохранять историю резервных копий, если вы обнаружите, что последняя версия была запущена, и вам нужна последняя версия на прошлой неделе.

Ответ 13

Это довольно прочное решение для оболочки Linux. Я использую его в течение многих лет:

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

  • Есть ли резервные копии: ежедневно, ежемесячно, ежегодно
  • Множество опций

Ответ 14

@Daniel,

в случае, если вас все еще интересует, есть новое (новое для меня) решение, совместно используемое Paul Galbraith, инструмент, который позволяет онлайн-резервное копирование таблиц innodb, называемое ibbackup из оракула, который цитирует Paul,

при использовании в сочетании с innobackup, отлично поработал в создание ночной резервной копии, без время простоя во время резервного копирования

более подробную информацию можно найти на Paul blog

Ответ 15

Звучит так, будто вы говорите об откате транзакций.

Итак, с точки зрения того, что вам нужно, если у вас есть журналы, содержащие все исторические запросы, разве это не резервная копия? Зачем нужна инкрементная резервная копия, которая в основном представляет собой избыточную копию всей информации в журналах БД?

Если да, почему бы вам просто не использовать mysqldump и делать резервное копирование каждый раз?