我有一个奇怪的问题。我有一个数据库,名为restorelogs
。从SQL Server恢复差异备份
自动备份脚本执行完整备份,之后每隔3小时进行一次差异备份。 第二天再做一次,然后再次比较,依此类推。
不,我想写一个脚本,什么是恢复这个文件int restorelogs数据库。
从PHP我通过SQLSRV使用这些SQL查询:
USE master;
ALTER DATABASE restorelogs SET MULTI_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307151435.bak' WITH REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307151745diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307152045diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307152345diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307160245diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307160545diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307160845diff.bak' WITH FILE= 1, REPLACE, NORECOVERY;
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307161145diff.bak' WITH FILE= 1, REPLACE, RECOVERY;
现在会自带游戏的有趣的部分。
如果我将这些查询复制到SQL Server Management Studio中并运行它,它可以正常工作。有表格,没有错误信息,一切都很好。
但是。当我尝试从php中完成时,数据库以恢复模式离开。
当我通读很多页面时,我明白了,最后一个查询需要包含RECOVERY
选项来恢复数据库(我也尝试在第一次查询时不使用REPLACE)。
它怎么会发生?
请帮帮我,我错了什么。
更新:基于亚当评论:我完全试图做到这一点。我收集备份文件,并使用第一个(全部),NORECOVERY,REPLACE和最后一个WITH RECOVERY。
这是我尝试: 功能pushToDatabase($文件){
$dbh = new Database();
$dbh->query("USE master");
pre($dbh->errorInfo(), 0);
$cnt = count($files);
$i = 0;
foreach ($files as $file) {
$withFile = '';
$option = '';
$moves = '';
if ($i == 0) {
//restoreFromDisk($file);
//truncateDatabase();
$option = " NORECOVERY, REPLACE";
} else {
$option = " RECOVERY";
}
if ($i > 0) {
$withFile = " FILE=1, ";
}
if ($i == 0 || $i == count($files) - 1) {
$sql = "RESTORE DATABASE " . DB_NAME . " FROM DISK = '" . $file . "' WITH " . $withFile . $option . ";";
echo $sql . "<br />";
$dbh->exec($sql);
pre($dbh->errorInfo(), 0);
}
$i++;
}
$sql = "RESTORE DATABASE " . DB_NAME . " WITH RECOVERY;";
$dbh->exec($sql);
pre($dbh->errorInfo(), 0);
echo $sql . "<br />";
die("NOW WE ARE DONE!");
}
第一个语句运行没有任何问题:
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307151435.bak' WITH NORECOVERY, REPLACE;
但在此之后,当我想挽回最后一个diff文件:
RESTORE DATABASE restorelogs FROM DISK = 'D:/Apache/htdocs/logreader/extracts/SRO_VT_LOG201307161145diff.bak' WITH FILE=1, RECOVERY;
我找回了一条错误消息:
[Microsoft][SQL Server Native Client 10.0][SQL Server]A previous restore operation was interrupted and did not complete processing on file 'Log_DB_Data'. Either restore the backup set that was interrupted or restart the restore sequence.'
并且数据库状态保持还原模式。
我也尝试玩RESTORE FILELISTONLY,并将文件移动到正确的位置。我可以这样做,但之后我无法恢复差异备份。
function restoreFromDisk($file) {
$sql = "RESTORE FILELISTONLY FROM DISK = '" . $file . "'";
$res = dbQuery($sql);
$option = ' ,REPLACE, RECOVERY';
while ($row = dbFetchAssoc($res)) {
if ($row["LogicalName"] == "Log_DB_Data") {
$move[] = " MOVE '" . $row["LogicalName"] . "' TO '" . MSSQL_DATA_PATH . "resetlogs.mdf'";
} else {
$move[] = " MOVE '" . $row["LogicalName"] . "' TO '" . MSSQL_DATA_PATH . "resetlogs.ldf'";
}
}
$moves = join(",", $move);
$sql = "RESTORE DATABASE " . DB_NAME . " FROM DISK = '" . $file . "' WITH " . $moves . $option . ";";
dbQuery($sql);
echo $sql . "<br />";
$sql = "RESTORE DATABASE " . DB_NAME . " WITH RECOVERY;";
dbQuery($sql);
echo $sql . "<br />";
}
好的,我想出了导致问题的原因。 当我将它复制到mssql管理器中时,它按照我的预期运行。因为,查询正在彼此等待。 我做你伤心,我只是我们最后的差异文件。 但是从php,我无法调用mysql_query(“GO”); 因此,当我尝试启动第二次恢复时,差分文件,我得到了这个回: 以前的恢复操作中断,并没有完成处理文件'Log_DB_Data'。恢复被中断的备份集或重新启动恢复序列。 – vaso123
我会将恢复命令添加到数组,并自行处理每个命令。例如,第一次迭代将恢复完整备份,然后下一次迭代将执行差异恢复。 –
我最后的尝试是创建一个存储过程,然后传递2个文件,也许mssql可以做到这一点。 – vaso123