数据库备份策略与自动化工具实现

在现代的软件开发项目中,数据库扮演着至关重要的角色。无论是Web应用、数据收集系统、支付系统还是工业系统,都需要处理和存储大量的数据。最近,在多个项目中使用了SQL Server数据库。许多技术,如ASP.NET MVC、Web API、Entity Framework等,都内置了对这些数据库的支持。甚至在从模板开始一个项目时,通常会创建一个简单的SQL Server演示数据库。在Visual Studio中,创建新的或编辑现有的SQL Server数据库架构也非常简单,SQL Server还包含了内置的管理工作室IDE。

建立备份需求

在启动了几个使用SQL Server的自定义软件项目后,遇到了定期备份数据库的需求。为什么需要备份数据库?都面临着硬盘不可靠、勒索软件病毒、软件故障等问题。手头有最新的备份总是比没有更让人安心。为了自动按计划创建备份,在软件解决方案中包含了一个小型项目,其任务就是创建备份副本。

与在主应用程序中启用备份功能相比,拥有一个单独的项目的优势在于,不需要每次都将独特的备份功能插入新项目,并考虑如何使用它。

实现自动化备份

备份项目非常简单,它基于C#控制台应用程序。该应用程序设计为定期按计划启动。

考虑应用程序代码,它并不复杂:

using System; using System.Data.SqlClient; using System.IO; using System.Threading; using Ionic.Zip; namespace SimpleDBBackup { class Program { // 本地SQL Server连接字符串 static string connectionString = "Server=localhost;Integrated Security=True"; // 可选:使用凭据连接 static string connectionString = "Server=localhost;user id=user2018;password=MYDBPASSWORD;"; // 要备份的数据库名称 static string[] saDatabases = new string[] { "shop", "frontend", "accounting" }; // 备份目录。请注意:文件比DeletionDays旧将自动删除 static string backupDir = @"C:\DB_Backups"; // 删除比DeletionDays旧的备份。设置为0则永不删除备份 static int DeletionDays = 10; static Mutex mutex = new Mutex(true, "Global\\SimpleDBBackupMutex"); static void Main(string[] args) { // 只允许应用程序的单个实例 if (!mutex.WaitOne(TimeSpan.Zero, true)) { Console.WriteLine("程序已经在运行!"); return; } if (DeletionDays > 0) DeleteOldBackups(); DateTime dtNow = DateTime.Now; try { using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { sqlConnection.Open(); foreach (string dbName in saDatabases) { string backupFileNameWithoutExt = String.Format("{0}\\{1}_{2:yyyy-MM-dd_hh-mm-ss-tt}", backupDir, dbName, dtNow); string backupFileNameWithExt = String.Format("{0}.bak", backupFileNameWithoutExt); string zipFileName = String.Format("{0}.zip", backupFileNameWithoutExt); string cmdText = string.Format("BACKUP DATABASE {0}\r\nTO DISK = '{1}'", dbName, backupFileNameWithExt); using (SqlCommand sqlCommand = new SqlCommand(cmdText, sqlConnection)) { sqlCommand.CommandTimeout = 0; sqlCommand.ExecuteNonQuery(); } using (ZipFile zip = new ZipFile()) { zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; zip.AddFile(backupFileNameWithExt); zip.Save(zipFileName); } File.Delete(backupFileNameWithExt); } sqlConnection.Close(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } mutex.ReleaseMutex(); } static void DeleteOldBackups() { try { string[] files = Directory.GetFiles(backupDir); foreach (string file in files) { FileInfo fi = new FileInfo(file); if (fi.CreationTime < DateTime.Now.AddDays(-DeletionDays)) fi.Delete(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } }

应用程序由几个主要块组成:

  • 设置块
  • 创建实际备份的主函数
  • 删除旧备份的DeleteOldBackups函数

让更详细地考虑这些块:

在这里,指定数据库的连接字符串。在最简单的情况下,如果使用具有默认设置的本地服务器,第一行就足够了。如果想使用登录名和密码连接到服务器,请取消注释并修改第二行。

在主函数的开始,安装了Mutex(互斥)对象。这个对象只能以单个实例存在。在这个程序中,使用Mutex来防止程序第二次启动。使用Mutex对象,可以为进程和线程之间的交互做许多有趣和迷人的事情。

主函数中的下一个有趣的块是连接到数据库并执行备份命令:

这里一切都很简单:获取具有创建日期属性的文件列表,并删除所有创建日期早于当前日期减去指定天数的文件。

如何使用程序

在程序配置并编译为发布版本后,需要将其与库一起复制到单独的目录中,例如C:\SimpleDbBackup,同时为数据库创建一个目录(在这个例子中是C:\DB_Backups)。

现在,需要使用Windows任务计划程序创建一个定期任务,以便它每天或每天两次按计划运行,根据喜好。建议现在手动创建任务。也许将来会在主程序的代码中添加创建计划任务的功能,但目前,建议手动执行。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485