Как мне сделать резервные копии в MySQL?[дубликат]

StackOverflow https://stackoverflow.com/questions/46545

  •  09-06-2019
  •  | 
  •  

Вопрос

На этот вопрос уже есть ответ здесь:

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

Я надеюсь, что будет что-то лучше, чем просто запускать mysqldump каждые «х» часов.

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

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

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

Это было полезно?

Решение

Возможно, вы захотите посмотреть инкрементные резервные копии.

Другие советы

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

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

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

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

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

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

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

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

Ребята из Percona сделали альтернативу innobackup с открытым исходным кодом...

Экстрабэкап

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

Прочитайте эту статью о XtraDBhttp://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/gzip/шифрует файлы.Это довольно небольшой сайт, поэтому веб-резервные копии занимают гораздо меньше 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=["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()

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

@Джейк,

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

Разве в MySQL не встроено НИЧЕГО для создания достойных резервных копий?

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

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

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

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

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

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

для начала заблокируйте все таблицы или отключите сервер.используйте дамп MySQL для создания резервной копии или просто скопируйте каталог данных.вам нужно сделать это только один раз или в любое время, когда вам понадобится ПОЛНАЯ резервная копия.

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

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

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

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

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

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

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

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

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

  • Делает ли резервное копирование:ежедневно, ежемесячно, ежегодно
  • Множество вариантов

@Дэниел,

Если вам все еще интересно, есть новое (новое для меня) решение, которым поделился Пол Гэлбрейт, инструмент, позволяющий создавать онлайн-резервные копии таблиц innodb, называемый ibbackup от оракула, который цитирует Павла,

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

более подробную информацию можно найти на Блог Пола

Похоже, вы говорите об откате транзакции.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top