从C#进行Postgres数据库备份/恢复
Postgres数据库备份/恢复功能的实现。
引言
本文提供了Postgres数据库备份/恢复功能。使用此应用程序,我们可以检查系统中是否安装了Postgres数据库。如果安装了Postgres数据库,则会提供Postgres数据库列表。用户可以从列表中选择所需的数据库进行备份/恢复操作。
在我的项目中,我使用了Postgres作为数据库。这里我列出了一些**Postgres的优势**。
所需的DLL
从Visual Studio访问Postgres所需的DLL是Mono.Security.dll和Npgsql.dll。我已经将这些DLL复制到应用程序的bin目录。建议仅将所需的DLL复制到bin目录。如果应用程序是Release配置,则可以删除Debug文件夹(Debug配置也适用)。
然后为应用程序添加这些引用
应用程序内部
检查Postgres安装
使用此应用程序,首先我们可以检查Postgres数据库是否已安装。单击“检查Postgres安装”按钮,它会检查系统服务列表中的Postgres服务。如果找到Postgres服务,则检查“pg_dump.exe”。如果找到该exe文件,则应用程序假定系统已安装Postgres,并且按钮背景颜色将变为绿色,数据库位置将显示在按钮旁边。
这是**检查Postgres服务**的代码。
bool bPostgresService = false;
ServiceController[] services = ServiceController.GetServices();
// try to find service name
foreach (ServiceController service in services)
{
if (service.ServiceName.Contains("postgre") == true)
{
bPostgresService = true;
break;
}
}
if (bPostgresService == true)
{
PG_DumpExePath();
objProcess.Kill();
if (sbPG_dumpPath.Length != 0)
{
MessageBox.Show("Your System is INSATALLED with Postgres");
labelLocation.Text = "Installation Location is " + strInstallLocation;
labelLocation.Visible = true;
btnCheckPostgres.BackColor = Color.Green;
panel1.Enabled = true;
}
}
else
{
objProcess.Kill();
MessageBox.Show("Your System is NOT INSATALLED with Postgres");
}
以下是搜索文件的代码。对于此函数,提供文件名作为输入参数,该函数将在所有驱动器中搜索该文件,并返回该文件的位置。performFileSearchTask
函数是一个**迭代文件搜索函数**。
private string LookForFile(string strFileName)
{
string strPG_dumpPath = string.Empty;
try
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
strPG_dumpPath = performFileSearchTask(drive.Name, strFileName);
if (strPG_dumpPath.Length != 0)
break;
}
}
catch (Exception ex)
{ }
return strPG_dumpPath;
}
private string performFileSearchTask(string dirName, string strfileName)
{
try
{
if (strPG_dumpPath.Length == 0)
{
try
{
foreach (string ddir in Directory.GetDirectories(dirName))
{
System.Security.Permissions.FileIOPermission ReadPermission =
new System.Security.Permissions.FileIOPermission(
System.Security.Permissions.FileIOPermissionAccess.Write, ddir);
if (System.Security.SecurityManager.IsGranted(ReadPermission))
{
try
{
foreach (string dfile in Directory.GetFiles(ddir, strfileName))
{
strPG_dumpPath = ddir + "\\";
if (strPG_dumpPath.Length > 0)
{
strInstallLocation = strPG_dumpPath;
break;
}
}
if (strPG_dumpPath.Length == 0)
performFileSearchTask(ddir, strfileName);
}
catch (Exception ex)
{ }
}
if (strPG_dumpPath != string.Empty)
break;
}
}
catch (Exception ex)
{ }
}
}
catch (Exception ex)
{ }
return strPG_dumpPath;
}
如果系统安装了Postgres数据库,则应用程序仅提供备份/恢复选项。下一个操作需要单击“获取所有数据库”按钮。在此按钮旁边提供端口号文本框,用于输入所需的端口号以搜索数据库(在我的情况下为5432)。
try
{
comboBox1.Items.Clear();
comboBox1.Text = string.Empty;
DataSet dsDB = new DataSet();
strPort = txtPort.Text;
strConnection = "Server=localhost;Port=" + strPort +
";Database=postgres;Userid=postgres;Password=postgres;";
dsDB = GetData("SELECT datname FROM pg_database WHERE " +
"datistemplate IS FALSE AND datallowconn IS TRUE AND datname!='postgres';");
if (dsDB != null)
{
if (dsDB.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < dsDB.Tables[0].Rows.Count; i++)
{
comboBox1.Items.Add(dsDB.Tables[0].Rows[i][0].ToString());
}
comboBox1.SelectedIndex = 0;
strDatabaseName = comboBox1.Text;
butSelectLoc.Enabled = true;
}
else
{
MessageBox.Show("No Database is existing");
}
}
}
catch (Exception ex)
{ }
此函数完成后,组合框将更新为可用的Postgres数据库。用户可以从组合框中选择要对其执行备份/恢复操作的数据库。
备份操作
首先,通过单击“选择备份文件保存位置”按钮选择要保存备份文件的位置。选择后,按钮下方的文本框将更新为备份文件的位置。备份文件格式为DbName_Backup_Date_HoursMin.Backup。
然后,用户可以单击“备份数据库”按钮。在此函数中,备份操作所需的脚本将被格式化为批处理文件,并作为进程执行。
private void butBackup_Click(object sender, EventArgs e)
{
try
{
if (textBox1.Text == "-------")
{
MessageBox.Show("Select the location to save");
return;
}
StreamWriter sw = new StreamWriter("DBBackup.bat");
// Do not change lines / spaces b/w words.
StringBuilder strSB = new StringBuilder(strPG_dumpPath);
if (strSB.Length != 0)
{
strSB.Append("pg_dump.exe --host " + strServer + " --port " + strPort +
" --username postgres --format custom --blobs --verbose --file ");
strSB.Append("\"" + textBox1.Text + "\"");
strSB.Append(" \"" + strDatabaseName + "\r\n\r\n");
sw.WriteLine(strSB);
sw.Dispose();
sw.Close();
Process processDB = Process.Start("DBBackup.bat");
do
{//dont perform anything
}
while (!processDB.HasExited);
{
MessageBox.Show(strDatabaseName + " Successfully Backed up at " + textBox1.Text);
}
}
else
{
MessageBox.Show("Please Provide the Location to take Backup!");
}
}
catch (Exception ex)
{ }
}
这是形成strPG_dumpPath
字符串所需的函数。此字符串对于备份和恢复函数都是通用的。我们提供了备份和恢复操作所需的pg_dump.exe的路径。
private void PG_DumpExePath()
{
try
{
// Do not change lines / spaces b/w words.
if (sbPG_dumpPath.Length == 0)
{
//string strPG_dumpPath = string.Empty;
if (strPG_dumpPath == string.Empty)
{
strPG_dumpPath = LookForFile("pg_dump.exe");
if (strPG_dumpPath == string.Empty)
{
MessageBox.Show("Postgres is not installed");
}
}
int a = strPG_dumpPath.IndexOf(":\\", 0);
a = a + 2;
string strSub = strPG_dumpPath.Substring(0, (a - 2));
strPG_dumpPath = strPG_dumpPath.Substring(a, (strPG_dumpPath.Length - a));
StringBuilder sbSB1 = new StringBuilder(strPG_dumpPath);
sbSB1.Replace("\\", "\r\n\r\ncd ");
StringBuilder sbSB2 = new StringBuilder("cd /D ");
sbSB2.Append(strSub);
sbSB2.Append(":\\");
sbSB1 = sbSB2.Append(sbSB1);
sbSB1 = sbSB1.Remove((sbSB1.Length - 3), 3);
sbPG_dumpPath = sbSB1;
strPG_dumpPath = sbSB1.ToString();
}
}
catch (Exception ex)
{ }
}
备份操作完成后,将为所选位置创建输出备份文件。
恢复操作
首先,通过单击“选择备份文件路径”按钮选择要从中选择备份文件的位置。选择后,按钮下方的文本框将更新为备份文件名的位置。
然后,用户可以单击“恢复数据库”按钮。在此函数中,恢复操作所需的脚本将被格式化为批处理文件,并作为进程执行。
private void butRestore_Click(object sender, EventArgs e)
{
try
{
if (txtBackupFilePath.Text == string.Empty)
{
MessageBox.Show("Select backup file");
return;
}
//check for the pre-requisites before restoring the database.*********
if (strDatabaseName != "")
{
if (txtBackupFilePath.Text != "")
{
StreamWriter sw = new StreamWriter("DBRestore.bat");
// Do not change lines / spaces b/w words.
StringBuilder strSB = new StringBuilder(strPG_dumpPath);
if (strSB.Length != 0)
{
checkDBExists(strDatabaseName);
strSB.Append("pg_restore.exe --host " + strServer +
" --port " + strPort + " --username postgres --dbname");
strSB.Append(" \"" + strDatabaseName + "\"");
strSB.Append(" --verbose ");
strSB.Append("\"" + txtBackupFilePath.Text + "\"");
sw.WriteLine(strSB);
sw.Dispose();
sw.Close();
Process processDB = Process.Start("DBRestore.bat");
do
{//dont perform anything
}
while (!processDB.HasExited);
{
MessageBox.Show("Successfully restored " +
strDatabaseName + " Database from " + txtBackupFilePath.Text);
}
}
else
{
MessageBox.Show("Please enter the save path to get the backup!");
}
}
}
else
{
MessageBox.Show("Please enter the Database name to Restore!");
}
}
catch (Exception ex)
{ }
}
结论
本文旨在演示如何获取Postgres数据库备份文件或从备份文件恢复数据库。