0

奇妙な問題があります。というデータベースがありますrestorelogs

自動バックアップ スクリプトは完全バックアップを実行し、その後は 3 時間ごとに差分バックアップを実行します。翌日、もう一度フルを実行してから、もう一度差分を実行します。

いいえ、スクリプトを書きたいのですが、このファイルを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 を使用しないようにしています)。

どうすれば起こりますか?

私を助けてください、何が間違っていますか。

更新: Adam のコメントに基づく: 私はまさにそれをしようとしています。バックアップ ファイルを収集し、最初 (フル) を NORECOVERY、REPLACE、最後の WITH RECOVERY で使用します。

これは私が試したことです: function pushToDatabase($files) {

$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;

しかし、この後、最後の差分ファイルを復元したい場合:

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 />";
}
4

2 に答える 2

0

別のアプローチとして、SQL スクリプトを一時ファイルに書き込んでから、osql を使用してそれをスクリプトとして実行します。もちろん、これは osql がインストールされたマシンで実行していることを前提としています。

osql -E -S <server> -d master -i <sql file>
于 2013-09-27T18:26:40.533 に答える
0

ユーザーが接続される可能性がある場合 (およびユーザーのセッションを強制終了しても問題ない場合) は、データベースをシングル ユーザーに設定する必要があります。データベースを復元しているので、大丈夫だと思います。フル バックアップの復元では、置換オプションを指定する必要があります。また、最後の完全バックアップ以降のすべての変更が含まれているため、最新の差分バックアップを復元するだけで済みます (リカバリを使用)。この復元には、最​​後の差分バックアップ以降に発生したトランザクションは含まれないことにも注意してください。

3 時間ごとにログ バックアップを使用することを検討します。これにより、システムへの影響が少なくなり、ログを切り捨てることができます (完全に回復している場合)。この復元シナリオでは、フル バックアップとすべてのログ バックアップが必要で、最後のオプションで with recovery を指定します。

于 2013-07-24T20:45:49.110 に答える