كيف أقوم بعمل نسخ احتياطية في MySQL؟[ينسخ]

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

  •  09-06-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

كيف أقوم بعمل نسخ احتياطية في MySQL؟

آمل أن يكون هناك شيء أفضل من مجرد تشغيل mysqldump كل "x" ساعة.

هل هناك أي شيء مثل SQL Server، حيث يمكنك أخذ نسخة احتياطية كاملة كل يوم، ثم تزايدية كل ساعة، لذلك إذا ماتت قاعدة البيانات الخاصة بك، فيمكنك استعادة ما يصل إلى أحدث نسخة احتياطية؟

شيء مثل سجل قاعدة البيانات، حيث طالما لم يموت السجل، يمكنك استعادة ما يصل إلى النقطة المحددة التي ماتت فيها قاعدة البيانات؟

وأيضًا كيف تؤثر هذه الأشياء على القفل؟أتوقع أن يتم قفل المعاملات عبر الإنترنت لفترة من الوقت إذا قمت بإجراء mysqldump.

هل كانت مفيدة؟

المحلول

قد ترغب في إلقاء نظرة على النسخ الاحتياطية المتزايدة.

نصائح أخرى

يعد mysqldump أسلوبًا معقولًا، ولكن ضع في اعتبارك أنه بالنسبة لبعض المحركات، سيؤدي هذا إلى قفل الجداول الخاصة بك طوال مدة التفريغ - وهذا له مخاوف بشأن توفر مجموعات بيانات الإنتاج الكبيرة.

البديل الواضح لذلك هو mk-parallel-dump من Maatkit (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 (المؤسسة في حالتك) من com.webyog لجميع متطلبات MySQL الخاصة بك.ليس فقط جدولة النسخ الاحتياطية, ، لكن أيضا مزامنة الجداول الزمنية حتى تتمكن بالفعل من نسخ قاعدة البيانات الخاصة بك إلى خادم بعيد.

يحتوي على إصدار مجتمعي مجاني بالإضافة إلى إصدار مؤسسي.أوصيك بالإصدار الأحدث على الرغم من أنني أوصي أيضًا بالبدء بإصدار comm والأول انظر كيف تعجبك.

أستخدم mysqlhotcopy، أ أداة نسخ احتياطي سريع عبر الإنترنت لقواعد بيانات وجداول MySQL المحلية.أنا سعيد جدًا به.

قام فريق Percona بإنشاء بديل مفتوح المصدر لـ innobackup ...

Xtrabackup

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/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=["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 على كل منها إلى مجلد النسخ الاحتياطي، ثم قم بعمل نسخة احتياطية لهذا المجلد على شريط.

لكن هذا يعني أنه لا يوجد شيء اسمه تدريجي النسخ الاحتياطية، نظرًا لأن التفريغ الليلي هو تفريغ كامل.لكنني أود أن أزعم أن هذا قد يكون أمرًا جيدًا، نظرًا لأن الاستعادة من a نسخة احتياطية كاملة ستكون عملية أسرع بكثير من الاستعادة من التزايدات - وإذا كنت تقوم بالنسخ الاحتياطي على الشريط، فمن المحتمل أن يعني ذلك جمع عدد من الأشرطة قبل أن تتمكن من إجراء الاستعادة الكاملة.

على أية حال، مهما كانت خطة النسخ الاحتياطي التي تستخدمها، تأكد من إجراء استعادة تجريبية للتأكد من أنها تعمل، والحصول على فكرة عن المدة التي قد تستغرقها، والخطوات التي يتعين عليك اتباعها بالضبط.

الطريقة الصحيحة لتشغيل النسخ الاحتياطية المتزايدة أو المستمرة لخادم MySQL هي باستخدام السجلات الثنائية.

للبدء، قم بقفل كافة الجداول أو قم بإسقاط الخادم.استخدم تفريغ MySQL لعمل نسخة احتياطية، أو قم فقط بنسخ دليل البيانات.ما عليك سوى القيام بذلك مرة واحدة، أو في أي وقت تريد فيه نسخة احتياطية كاملة.

قبل إعادة الخادم احتياطيًا، تأكد من تمكين التسجيل الثنائي.

لأخذ نسخة احتياطية تزايدية، قم بتسجيل الدخول إلى الخادم وأصدر أمر FLUSH LOGS.ثم قم بعمل نسخة احتياطية لملف السجل الثنائي الذي تم إغلاقه مؤخرًا.

إذا كان لديك جميع جداول innodb، فمن الأسهل استخدام النسخ الاحتياطي السريع inno (غير مجاني) أو mysqldump مع خيار --single-transaction (من الأفضل أن يكون لديك ذاكرة كبيرة للتعامل مع المعاملات).

ربما تكون السجلات الثنائية هي الطريقة الصحيحة لإجراء نسخ احتياطية تزايدية، ولكن إذا كنت لا تثق في تنسيقات الملفات الثنائية للتخزين الدائم، فإليك طريقة ASCII لإجراء نسخ احتياطية تزايدية.

mysqldump ليس تنسيقًا سيئًا، والمشكلة الرئيسية هي أنه يُخرج جدولًا كخط واحد كبير.سوف يقوم sed التافه التالي بتقسيم إنتاجه على طول حدود التسجيل:

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

الملف الناتج صديق للفرق إلى حد كبير، وقد احتفظت به في مستودع SVN القياسي بنجاح إلى حد ما.يتيح لك ذلك أيضًا الاحتفاظ بسجل للنسخ الاحتياطية، إذا وجدت أن الإصدار الأخير قد تعطل وتحتاج إلى إصدار الأسبوع الماضي.

هذا حل قوي جدًا لـ Linux Shell.لقد تم استخدامه لسنوات:

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

  • هل النسخ الاحتياطية المتداولة:يوميا، شهريا، سنويا
  • الكثير من الخيارات

@دانيال،

في حال كنت لا تزال مهتمًا، هناك حل جديد (جديد بالنسبة لي) تمت مشاركته بواسطة بول غالبريث, ، وهي أداة تسمح بالنسخ الاحتياطي عبر الإنترنت لجداول innodb تسمى com.ibbackup من أوراكل الذي على حد تعبير بولس،

عندما تستخدم جنبا إلى جنب مع com.innobackup, ، عملت بشكل رائع في إنشاء نسخة احتياطية ليلية ، دون أي توقف أثناء النسخ الاحتياطي

يمكن العثور على مزيد من التفاصيل على مدونة بول

يبدو أنك تتحدث عن التراجع عن المعاملة.

لذا، فيما يتعلق بما تحتاجه، إذا كان لديك السجلات التي تحتوي على جميع الاستعلامات التاريخية، أليس هذا هو النسخة الاحتياطية بالفعل؟لماذا تحتاج إلى نسخة احتياطية تزايدية والتي هي في الأساس نسخة زائدة عن الحاجة لجميع المعلومات الموجودة في سجلات قاعدة البيانات؟

إذا كان الأمر كذلك، لماذا لا تستخدم mysqldump وتقوم بالنسخ الاحتياطي بين الحين والآخر؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top