MySQL Backup/Restore als 3rd-party-apps

Status
Für weitere Antworten geschlossen.

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Die 3rd-party-apps für den MySQL Backup/Restore ist nicht ganz ungefährlich. Daher macht bitte von eurer MySQL-Datenbank vorher ein Komplett-Backup (also inklusive der mysql-Meta-Informationen), so wie ihr es bislang immer schon gemacht habt. Beim Restore werden nämlich die gesamten Datenbank-Dateien ersetzt und das kann, wenn irgendwas beim Test nicht stimmt, ganz schön in die Hose gehen. Im schlimmsten Fall muss man die MySQL-Datenbank wieder komplett neu aufsetzen.

(1) Wie immer müssen die Voraussetzungen für die Installation einer 3rd-party-apps erfüllt sein. Dazu gibt es an anderer Stelle einen Thread.

(2) Die Datei /usr/syno/synoman/webman/3rdparty/MySQLbackup/application.cfg enthält den Inhalt:
Rich (BBCode):
text = MySQLbackup
description = MySQLbackup
type = embedded
path = /phpsrc/MySQLbackup/MySQLbackup.php

(3) Anlegen eines Verzeichnisses /usr/syno/synoman/phpsrc/MySQLbackup. Dort hinein die Datei MySQLbackup.php anlegen mit dem Inhalt:
PHP:
<?php
ob_implicit_flush(); 
if (!isset($_REQUEST['action'])) $_REQUEST['action']='';
if (!isset($_REQUEST['path'])) $_REQUEST['path']='/volume1/database_backup';
?>
<html><head><title>MySQLbackup</title>
<style>pre{font-size:11px}body,input{font:11px Verdana}fieldset{border:1px solid #bbb}</style>
</head><body>
<form id="f" name="f" method="get" action="MySQLbackup.php">
<input type="hidden" name="action" id="action" value="" />
Please stop all your MySQL-database-activities before you backup. 
If you want to backup to a share, be sure that you have already created one.<br/><br/>
<input type="text" name="path" size="50" value="<?php print $_REQUEST['path'] ?>" />
<input type="button" value="Backup" onclick="document.getElementById('action').value='backup';submit()" />
<input type="button" value="Restore" onclick="document.getElementById('action').value='restore';submit()" />
</form>
<fieldset><legend>Protocol</legend>
<pre>
<?php
if ($_REQUEST['action'] == 'backup' && $_REQUEST['path'] != '') {
  print "/usr/syno/etc/rc.d/S21mysql.sh stop<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh stop"); sleep(5);
  if (!is_dir($_REQUEST['path'])) exec("mkdir -p ".$_REQUEST['path']); 
  print "cp -R /volume1/@database/* ".$_REQUEST['path']."<br/><br/>";
  exec( "cp -R /volume1/@database/* ".$_REQUEST['path']);
  passthru("du /volume1/@database");print "<br/>";
  passthru("du ".$_REQUEST['path']);print "<br/>";
  print "/usr/syno/etc/rc.d/S21mysql.sh start<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh start"); sleep(2); 
  print "== finished ==";
}
elseif ($_REQUEST['action'] == 'restore' && is_dir($_REQUEST['path']) && $_REQUEST['path'] != '@bak.database') {
  if (is_dir("/volume1/@bak.database")) 
     die ("please remove the directory @bak.database - it contains a copy of your last database");
  print "/usr/syno/etc/rc.d/S21mysql.sh stop<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh stop"); sleep(5);
  print "mv /volume1/@database /volume1/@bak.database<br/>";  
  exec( "mv /volume1/@database /volume1/@bak.database");
  print "mkdir /volume1/@database<br/>";
  exec( "mkdir /volume1/@database");    
  print "cp -R ".$_REQUEST['path']."/* /volume1/@database<br/><br/>";
  exec( "cp -R ".$_REQUEST['path']."/* /volume1/@database");
  passthru("du ".$_REQUEST['path']);print "<br/>";  
  passthru("du /volume1/@database");print "<br/>";  
  print "/usr/syno/etc/rc.d/S21mysql.sh start<br/>";   
  exec( "/usr/syno/etc/rc.d/S21mysql.sh start"); sleep(2);  
  print "== finished ==";  
}
$_REQUEST['action']='';
?>
</pre></fieldset></body></html>

Funktionsweise:
Bei Backup bzw. Restore wird die Datenbank vorher heruntergefahren, daher geht es nicht im laufenden Betrieb. Dann wird eine physische Kopie der Datenbankdateien kopiert bzw. zurückkopiert. Vor dem Zurückkopieren wird eine Umbenennung des aktuellen Datenbank-Verzeichnisses gemacht (/volume1/@bak.database) und damit gesichert. Dieses Verzeichnis muss man nach einem Restore manuell löschen. (Ich bau später mal ein, dass das auch automatisch geht. Dient der Sicherheit, dass man sich beim Testen nicht alles automatisch weghaut.) Nach dem Backup bzw. Restore wird die Datenbank wieder gestartet. Ein Protokoll zeigt alle Kommandos an, die ausgeführt werden. Mittels du (disk usage) wird die Blockanzahl der Quelle bzw. Kopie angezeigt.
Wenn das auf diese Weise gesicherte Datenbank-Verzeichnis als Share vorliegt, dann kann man es einfach per lokaler Datensicherung auch auf ein anderes Medium sichern.

Anleitung zum Testen:
(1) Anlegen einer Share z. B. mit dem Namen database_backup
(2) Ausführen von MySQLbackup mit dem Pfad /volume1/database_backup und dem Klick auf "Backup" ... warten, das kann schon einige Minuten dauern
(3) Mit Telnet den Backup anschauen
(4) Mit phpmyadmin die Datenbank anschauen und irgendwas löschen/ändern
(5) Ausführen von MySQLbackup mit dem Pfad /volume1/database_backup und dem Klick auf "Restore" ... warten, das kann schon einige Minuten dauern
(6) Mit phpmyadmin anschauen, ob DB wiederhergestellt ist.
(7) Mit Telnet anschauen, ob eine Kopie der Datenbank-Datei, die den Stand vor dem Restore darstellt angelegt wurde (/volume1/@bak.database).
(8) Wenn alles ok ist, dann /volume1/@bak.database löschen.

Wie immer geht alles auf eigene Kappe. Das obligatorisch Motivations-Bildchen:
 

Anhänge

  • mysqlbackup.jpg
    mysqlbackup.jpg
    84,3 KB · Aufrufe: 143
Zuletzt bearbeitet:

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Versionserweiterung

Wie schon in dem ersten Beitrag angekündigt, jetzt die erweiterte Version. Beim Restore wird ja eine Sicherung der Datenbank angefertigt (/volume1/@bak.database), damit ein Fehler im Restore nicht komplett alles zerstören könnte.

Nach erfolgreichem Restore brauch man dieses Verzeichnis nicht mehr unbedingt und kann es löschen. Diese Funktionalität ist jetzt eingebaut.

PHP:
<?php
ob_implicit_flush(); 
if (!isset($_REQUEST['action'])) $_REQUEST['action']='';
if (!isset($_REQUEST['path'])) $_REQUEST['path']='/volume1/database_backup';
?>
<html><head><title>MySQLbackup</title>
<style>pre{font-size:11px}body,input{font:11px Verdana}fieldset{border:1px solid #bbb}</style>
</head><body>
<form id="f" name="f" method="get" action="MySQLbackup.php">
<input type="hidden" name="action" id="action" value="" />
Please stop all your MySQL-database-activities before you backup. 
If you want to backup to a share, be sure that you have already created one.<br/><br/>
<input type="text" name="path" size="50" value="<?php print $_REQUEST['path'] ?>" />
<input type="button" value="Backup" onclick="document.getElementById('action').value='backup';submit()" />
<input type="button" value="Restore" onclick="document.getElementById('action').value='restore';submit()" />
<input type="button" value="Remove @bak.database" onclick="document.getElementById('action').value='remove';submit()" />
</form>
<fieldset><legend>Protocol</legend>
<pre>
<?php
if ($_REQUEST['action'] == 'backup' && $_REQUEST['path'] != '') {
  print "/usr/syno/etc/rc.d/S21mysql.sh stop<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh stop"); sleep(5);
  if (!is_dir($_REQUEST['path'])) exec("mkdir -p ".$_REQUEST['path']); 
  print "cp -R /volume1/@database/* ".$_REQUEST['path']."<br/><br/>";
  exec( "cp -R /volume1/@database/* ".$_REQUEST['path']);
  passthru("du /volume1/@database");print "<br/>";
  passthru("du ".$_REQUEST['path']);print "<br/>";
  print "/usr/syno/etc/rc.d/S21mysql.sh start<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh start"); sleep(2); 
  print "== finished ==";
}
elseif ($_REQUEST['action'] == 'restore' && is_dir($_REQUEST['path']) && $_REQUEST['path'] != '@bak.database') {
  if (is_dir("/volume1/@bak.database")) 
     die ("please remove the directory @bak.database - it contains a copy of your last database");
  print "/usr/syno/etc/rc.d/S21mysql.sh stop<br/>"; 
  exec( "/usr/syno/etc/rc.d/S21mysql.sh stop"); sleep(5);
  print "mv /volume1/@database /volume1/@bak.database<br/>";  
  exec( "mv /volume1/@database /volume1/@bak.database");
  print "mkdir /volume1/@database<br/>";
  exec( "mkdir /volume1/@database");    
  print "cp -R ".$_REQUEST['path']."/* /volume1/@database<br/><br/>";
  exec( "cp -R ".$_REQUEST['path']."/* /volume1/@database");
  passthru("du ".$_REQUEST['path']);print "<br/>";  
  passthru("du /volume1/@database");print "<br/>";  
  print "/usr/syno/etc/rc.d/S21mysql.sh start<br/>";   
  exec( "/usr/syno/etc/rc.d/S21mysql.sh start"); sleep(2);  
  print "== finished ==";  
}
elseif ($_REQUEST['action'] == 'remove' && is_dir('/volume1/@bak.database')) {
  print "rm -r /volume1/@bak.database<br/>";
  exec( "rm -r /volume1/@bak.database");
  print "== finished =="; 
}
$_REQUEST['action']='';
?>
</pre></fieldset></body></html>
 

Anhänge

  • mysqlbackup1.jpg
    mysqlbackup1.jpg
    18,7 KB · Aufrufe: 121
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat