Restore produces an out of memory error
Posted: Wed 19 May 2010 21:38
Can someone help me please. I am carrying out what I thought would be a simple task. That is to create a backup and restore program for my databases. My test database produces a backup.dump file of 220Mb.
For completeness, at the end of the message I show both the backup and restore functions using the Devart library. This also shows how it is being Backed up. But it is the Restore that I am having an issue with
I have messed around with the code for 5 days with various technique permutations and still have not found a working configuration.
Thank you for your help.
The goal is to produce a backup which is zipped up in a secure file. I am using the free DotNetZip mechanism compress and password protect the backup. (I can recommend this mechanism to others). I have got to the point where this is not causing me any issues. I am backing up the data and the schema independently of each other. My working backup function is as follows:
public bool DoDumpNetZip()
{
bool result = false;
try
{
//I put the connection in a class called from my form
Connect myConnection = new Connect(userName, Pass, port, hostName, dbName);
if (myConnection.Login()) //my own method of the class to login
{
Devart.Data.PostgreSql.PgSqlDump DataBackup = new Devart.Data.PostgreSql.PgSqlDump();
//get connection is a method returning the connection
DataBackup.Connection = myConnection.getConnection();
DataBackup.IncludeBlob = true;
DataBackup.CreateConstraints = false;
DataBackup.GenerateHeader = true;
DataBackup.Mode = Devart.Data.PostgreSql.DumpMode.Data;
//The biggest backup stream tested so far is around 300Mb
//and it worked – well it has produced a file
MemoryStream myStream = new MemoryStream();
DataBackup.Backup(myStream);
//This is my class to create a password protected zip file
CSLZip myZip = new CSLZip();
result = myZip.ZipFromStream(myStream, destination + backupName + ".zip");
myStream.Close();
//now backup the schema and add it the created zip file
DataBackup.Mode = Devart.Data.PostgreSql.DumpMode.Schema;
myStream = new MemoryStream();
DataBackup.Backup(myStream);
result = myZip.ZipFromStreamAdd(myStream, destination + backupName + ".zip","schema.backup");
myConnection.Logout();
}
}
catch (Exception executeCommand) { MessageBox.Show(executeCommand.Message); };
return result;
}
//The above code works fine. As far as I can see and the files appear to be correctly created.
Now to the Restore.
The goal is NOT to have to restore to a blank new database as this requires postgresql rights the the program user will not have, but to restore data to the existing structure.
Issues:
Restore will not restore data from the dump into tables with existing data without errosrs.
If the data rows are deleted the Restore gives errors regarding the constraints.
The version below
a. truncates all the data in the tables
b. disable triggers so the constraints are not an issue
Now I get the OutOfMemory error and or a total OS dump of the system.
Using the Task Monitor on my Vista Ultimate 3Gb RAM laptop which has a local copy of postgresql 8.4 with the latest Devart (build 4.90.124). At the point of the Restore method is called it shows Memory in use is 1.25Gb out of 3. The dump file is 220Mb in size.
All I see in the Task Manager is the Memory grow and grow till I get an Out of Memory error. The restore function is:
//Calls to unzip the backup.dump (data backup) is done before calling this
public bool DoRestoreFromFile(string myFile)
{
bool result = false;
Devart.Data.PostgreSql.PgSqlCommand command1 = null;
Devart.Data.PostgreSql.PgSqlCommand command2 = null;
try
{
CSLConnect myConnection = new CSLConnect(userName, Pass, port, hostName, dbName);
DataTable tables = null;
if (myConnection.Login())
{
tables = myConnection.getConnection().GetSchema("Tables", new string[] { "public" });
myConnection.Logout();
};
//Clear down the datatables except TblAdmin
if (myConnection.Login())
{
foreach (DataRow row in tables.Rows)
{
string tname = row["name"].ToString();
if (tname.ToUpper() != "TBLADMIN")
{
//If I don’t disable the triggers then the restore data fails
//because of constraints. I use TRUNCATE as it VACUUM’s as part
//of its process
//I would prefer NOT to use raw SQL call but feel I have
//no choice
command2 = new Devart.Data.PostgreSql.PgSqlCommand
("ALTER TABLE \"" + tname + "\" DISABLE TRIGGER ALL", myConnection.getConnection());
command1 = new Devart.Data.PostgreSql.PgSqlCommand
("TRUNCATE TABLE \"" + tname + "\" RESTART IDENTITY CASCADE", myConnection.getConnection());
try
{
command1.ExecuteNonQuery();
command2.ExecuteNonQuery();
}
catch (Exception ex) { MessageBox.Show(ex.Message); };
}
}
myConnection.getConnection().Commit();
myConnection.Logout();
};
if (myConnection.Login())
{
Devart.Data.PostgreSql.PgSqlDump DataRestore = new Devart.Data.PostgreSql.PgSqlDump();
DataRestore.Connection = myConnection.getConnection();
//It is during the next call that I get Out of Memory
DataRestore.Restore(myFile);
//Never get to this section of code so I don’t know
//if it makes sense yet
DataRestore.Connection.Commit();
myConnection.Logout();
}
if (myConnection.Login())
{
foreach (DataRow row in tables.Rows)
{
string tname = row["name"].ToString();
command1 = new Devart.Data.PostgreSql.PgSqlCommand
("ALTER TABLE \"" + tname + "\" ENABLE TRIGGER ALL", myConnection.getConnection());
try
{
command1.ExecuteNonQuery();
}
catch { };
};
myConnection.Logout();
};
result = true;
}
catch (Exception executeCommand) { MessageBox.Show(executeCommand.Message); };
return result;
}
For completeness, at the end of the message I show both the backup and restore functions using the Devart library. This also shows how it is being Backed up. But it is the Restore that I am having an issue with
I have messed around with the code for 5 days with various technique permutations and still have not found a working configuration.
Thank you for your help.
The goal is to produce a backup which is zipped up in a secure file. I am using the free DotNetZip mechanism compress and password protect the backup. (I can recommend this mechanism to others). I have got to the point where this is not causing me any issues. I am backing up the data and the schema independently of each other. My working backup function is as follows:
public bool DoDumpNetZip()
{
bool result = false;
try
{
//I put the connection in a class called from my form
Connect myConnection = new Connect(userName, Pass, port, hostName, dbName);
if (myConnection.Login()) //my own method of the class to login
{
Devart.Data.PostgreSql.PgSqlDump DataBackup = new Devart.Data.PostgreSql.PgSqlDump();
//get connection is a method returning the connection
DataBackup.Connection = myConnection.getConnection();
DataBackup.IncludeBlob = true;
DataBackup.CreateConstraints = false;
DataBackup.GenerateHeader = true;
DataBackup.Mode = Devart.Data.PostgreSql.DumpMode.Data;
//The biggest backup stream tested so far is around 300Mb
//and it worked – well it has produced a file
MemoryStream myStream = new MemoryStream();
DataBackup.Backup(myStream);
//This is my class to create a password protected zip file
CSLZip myZip = new CSLZip();
result = myZip.ZipFromStream(myStream, destination + backupName + ".zip");
myStream.Close();
//now backup the schema and add it the created zip file
DataBackup.Mode = Devart.Data.PostgreSql.DumpMode.Schema;
myStream = new MemoryStream();
DataBackup.Backup(myStream);
result = myZip.ZipFromStreamAdd(myStream, destination + backupName + ".zip","schema.backup");
myConnection.Logout();
}
}
catch (Exception executeCommand) { MessageBox.Show(executeCommand.Message); };
return result;
}
//The above code works fine. As far as I can see and the files appear to be correctly created.
Now to the Restore.
The goal is NOT to have to restore to a blank new database as this requires postgresql rights the the program user will not have, but to restore data to the existing structure.
Issues:
Restore will not restore data from the dump into tables with existing data without errosrs.
If the data rows are deleted the Restore gives errors regarding the constraints.
The version below
a. truncates all the data in the tables
b. disable triggers so the constraints are not an issue
Now I get the OutOfMemory error and or a total OS dump of the system.
Using the Task Monitor on my Vista Ultimate 3Gb RAM laptop which has a local copy of postgresql 8.4 with the latest Devart (build 4.90.124). At the point of the Restore method is called it shows Memory in use is 1.25Gb out of 3. The dump file is 220Mb in size.
All I see in the Task Manager is the Memory grow and grow till I get an Out of Memory error. The restore function is:
//Calls to unzip the backup.dump (data backup) is done before calling this
public bool DoRestoreFromFile(string myFile)
{
bool result = false;
Devart.Data.PostgreSql.PgSqlCommand command1 = null;
Devart.Data.PostgreSql.PgSqlCommand command2 = null;
try
{
CSLConnect myConnection = new CSLConnect(userName, Pass, port, hostName, dbName);
DataTable tables = null;
if (myConnection.Login())
{
tables = myConnection.getConnection().GetSchema("Tables", new string[] { "public" });
myConnection.Logout();
};
//Clear down the datatables except TblAdmin
if (myConnection.Login())
{
foreach (DataRow row in tables.Rows)
{
string tname = row["name"].ToString();
if (tname.ToUpper() != "TBLADMIN")
{
//If I don’t disable the triggers then the restore data fails
//because of constraints. I use TRUNCATE as it VACUUM’s as part
//of its process
//I would prefer NOT to use raw SQL call but feel I have
//no choice
command2 = new Devart.Data.PostgreSql.PgSqlCommand
("ALTER TABLE \"" + tname + "\" DISABLE TRIGGER ALL", myConnection.getConnection());
command1 = new Devart.Data.PostgreSql.PgSqlCommand
("TRUNCATE TABLE \"" + tname + "\" RESTART IDENTITY CASCADE", myConnection.getConnection());
try
{
command1.ExecuteNonQuery();
command2.ExecuteNonQuery();
}
catch (Exception ex) { MessageBox.Show(ex.Message); };
}
}
myConnection.getConnection().Commit();
myConnection.Logout();
};
if (myConnection.Login())
{
Devart.Data.PostgreSql.PgSqlDump DataRestore = new Devart.Data.PostgreSql.PgSqlDump();
DataRestore.Connection = myConnection.getConnection();
//It is during the next call that I get Out of Memory
DataRestore.Restore(myFile);
//Never get to this section of code so I don’t know
//if it makes sense yet
DataRestore.Connection.Commit();
myConnection.Logout();
}
if (myConnection.Login())
{
foreach (DataRow row in tables.Rows)
{
string tname = row["name"].ToString();
command1 = new Devart.Data.PostgreSql.PgSqlCommand
("ALTER TABLE \"" + tname + "\" ENABLE TRIGGER ALL", myConnection.getConnection());
try
{
command1.ExecuteNonQuery();
}
catch { };
};
myConnection.Logout();
};
result = true;
}
catch (Exception executeCommand) { MessageBox.Show(executeCommand.Message); };
return result;
}