En general prefiero realizar los backups desde scripts, pero muchas veces esta tarea se debe realizar desde la misma aplicación. Algo a tomar muy en cuenta si opta por este camino, es que los backups -- en lo posible -- deben ser generados con las herramientas que el motor de base de datos trae para este fin.
En los ejemplos se muestra el uso de mysqldump
y la clase Process, que según MSDN proporciona acceso a procesos locales y remotos, y permite iniciar y detener procesos del sistema local
:
csharp:
public void Backup
(string args
)
{
ProcessStartInfo psi =
new ProcessStartInfo
(ConfigurationManager.
AppSettings["MysqlDump"], args
);
string filename = Path.
Combine(workingDir, DateTime.
Now.
ToString(@"yyyy-MM-dd.\sql"));
using (StreamWriter writer =
new StreamWriter
(filename,
false, Encoding.
UTF8))
{
using(Process process =
new Process
())
{
psi.
CreateNoWindow =
true;
// Evita que el proceso se inicie en una nueva ventana.
psi.
UseShellExecute =
false;
// Evita que se use el shell del sistema operativo para iniciar el proceso.
psi.
RedirectStandardOutput =
true;
// Escribir la salida en Process.StandarOuput
psi.
StandardOutputEncoding = Encoding.
UTF8;
// Codificación de los datos de salida
process.
StartInfo = psi;
process.
OutputDataReceived +=
delegate(object sender, DataReceivedEventArgs e
)
{
writer.
WriteLine(e.
Data);
};
process.
Start();
process.
BeginOutputReadLine();
// Lectura asincrónica del stream de salida
process.
WaitForExit();
// Esperar a que el proceso termine.
}
}
}
Aunque en el código mostrado es más sencillo realizar algún proceso sobre los datos generados, hay que tener muy en cuenta la codificación de los datos en los backups, puesto que por un descuido se puede generar fácilmente basura.
Si se quiere evitar estos problemas de codificación, se podría usar algo como:
csharp:
public void Backup
(string args
)
{
string filename = Path.
Combine(workingDir, DateTime.
Now.
ToString(@"yyyy-MM-dd.\sql"));
ProcessStartInfo psi =
new ProcessStartInfo
("cmd.exe",
string.
Format("/c \"\"{0}\" {1} > \"{2}\"\"",
ConfigurationManager.
AppSettings["MysqlDump"], args,
filename
));
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
using (Process process = new Process())
{
process.StartInfo = psi;
process.Start();
process.WaitForExit();
}
}
En fin, usar uno u otro método va a depender de los requerimientos de la aplicación.