SafeDispatch/SafeMobileLIB_DLL/Failover/DBInteraction.cs

424 lines
16 KiB
C#
Raw Normal View History

2024-02-22 16:43:59 +00:00
using System;
using System.Diagnostics;
using System.IO;
namespace SafeMobileLib
{
public static class DBInteraction
{
public static string safemobilePath = Utils.GetRegValue("Path", "SafeMobile");
public static string SafeMobilePath
{
get { return safemobilePath; }
set { safemobilePath = value; }
}
/// <summary>
///
/// </summary>
/// <param name="connStr">”host = 10.120.1.130 port = 5432 user = postgres dbname = safedispatchdb”</param>
public static bool RewindCommand(string connStr)
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
string dbPath = safemobilePath + "\\postgresql\\SafeDB";
sw.WriteLine("pushd " + appPath);
sw.WriteLine($"pg_rewind.exe -target-pgdata= {dbPath} -source-server= {connStr}");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
if (output.Contains("Done!"))
{
Utils.WriteLine("RewindCommand: " + output, ConsoleColor.Magenta);
return true;
}
return false;
}
}
public static void ReceiveXlogCommand(string archive_folder, string slot_name, string connStr)
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine($"pg_receivexlog.exe -D {archive_folder} -v --slot= {slot_name} -d= {connStr} ");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
Utils.WriteLine("ReceiveXlogCommand: " + output, ConsoleColor.Magenta);
}
}
public static void BaseBackup(string masterIP)
{
try
{
string extractPath = $"{safemobilePath}\\postgresql\\pgsql\\bin\\SafeDBMaster";
string SafeDbFolder = $"{safemobilePath}\\postgresql\\SafeDB";
if (Directory.Exists(extractPath))
Directory.Delete(extractPath, true);
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine($"pg_basebackup.exe -X stream -P -h {masterIP} -U postgres -D SafeDBMaster");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
Utils.WriteLine("BaseBackup completed: " + output, ConsoleColor.Magenta);
}
// Get our files (recursive and any of them, based on the 2nd param of the Directory.GetFiles() method
string[] originalFiles = Directory.GetFiles(extractPath, "*", SearchOption.AllDirectories);
// Dealing with a string array, so let's use the actionable Array.ForEach() with a anonymous method
Array.ForEach(originalFiles, (originalFileLocation) =>
{
// Get the FileInfo for both of our files
FileInfo originalFile = new FileInfo(originalFileLocation);
FileInfo destFile = new FileInfo(originalFileLocation.Replace(extractPath, SafeDbFolder));
// ^^ We can fill the FileInfo() constructor with files that don't exist...
// ... because we check it here
if (destFile.Exists)
{
originalFile.CopyTo(destFile.FullName, true);
}
else // ... otherwise create any missing directories and copy the folder over
{
Directory.CreateDirectory(destFile.DirectoryName); // Does nothing on directories that already exist
originalFile.CopyTo(destFile.FullName, true); // Copy but don't over-write
}
});
Utils.WriteLine("SafeDB folder was successfully updated!!! " + SafeDbFolder, ConsoleColor.DarkGreen);
}
catch (Exception ex)
{
Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red);
}
}
/// <summary>
/// Creates a replication Slot in the database
/// </summary>
public static void CreateReplicationSlot()
{
try
{
Utils.WriteLine("Creating Replication Slot");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine("psql.exe -U postgres");
sw.WriteLine("SELECT * FROM pg_create_physical_replication_slot('replication_slot_node');");
sw.WriteLine("SELECT * FROM pg_replication_slots;");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
Utils.WriteLine("Replication Slot Created " + output, ConsoleColor.Magenta);
}
}
catch (Exception ex)
{
Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red);
}
}
public static void DropReplicationSlot()
{
try
{
Utils.WriteLine("Dropping Replication Slot");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine("psql.exe -U postgres");
sw.WriteLine("select pg_drop_replication_slot('replication_slot_node');");
sw.WriteLine("SELECT * FROM pg_replication_slots;");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
Utils.WriteLine("Replication Slot Deleted!!!! " + output, ConsoleColor.Magenta);
}
}
catch (Exception ex)
{
Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red);
}
}
public static bool CheckExistingReplicationSlot()
{
try
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine("psql.exe -U postgres");
sw.WriteLine("SELECT * FROM pg_replication_slots;");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
//Utils.WriteLine("Replication Slot Created " + output, ConsoleColor.Magenta);
if (output.Contains("replication_slot_node") == false)
{
return false;
}
else
{
return true;
}
}
}
catch (Exception ex)
{
Utils.WriteLine("Existing Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red);
return false;
}
}
public static bool CheckReplicationIsActive()
{
try
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine("psql.exe -U postgres");
sw.WriteLine("SELECT * FROM pg_replication_slots;");
}
sw.Close();
}
using (StreamReader reader = process.StandardOutput)
{
string output = reader.ReadToEnd();
process.WaitForExit();
if (output.Contains(" | t |") == false)
{
return false;
}
else
{
return true;
}
}
}
catch (Exception ex)
{
Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red);
return false;
}
}
public static void CheckDelay()
{
try
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Maximized;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
string appPath = safemobilePath + "\\postgresql\\pgsql\\bin";
sw.WriteLine("pushd " + appPath);
sw.WriteLine("psql.exe -U postgres");
sw.WriteLine("select case when pg_last_xlog_receive_location() = pg_last_xlog_replay_location() then 0 else extract (epoch from now() - pg_last_xact_replay_timestamp()) end as log_delay;");
}
sw.Close();
}
using (StreamReader file = process.StandardOutput)
{
int counter = 0;
bool writeNextLine = false;
string line;
// Read the file and display it line by line.
while ((line = file.ReadLine()) != null)
{
if (writeNextLine)
{
Utils.WriteLine(line.Trim().ToString() + " seconds delay from Master server");
}
writeNextLine = line.Contains("-----------");
counter++;
}
file.Close();
}
}
catch (Exception ex)
{
Utils.WriteLine("Check Delay ERROR: " + ex.ToString(), ConsoleColor.Red);
}
}
}
}