0

"Vulcan.edb"使用中のアプリケーションからコピーした ESE データベース ( ) があります。当然、これはデータベースが「ダーティ シャットダウン」状態にあることを意味します。幸いなことに、私はデータベースのログ ファイル ( "V01.log")を持っています。私が見つけることができるすべての 同様の 質問によると、データベースを接続してエンジンに復元させることができるはずです。マネージ ESE API を使用して、データベースを接続するために使用しているコードを次に示します (アンマネージ C++ ポートは簡単なはずです)。

public void ReadFromDatabase(string fileName, string logFileBaseName)
{
    string databaseDirectory = Path.GetDirectoryName(fileName);

    int pageSize;
    Api.JetGetDatabaseFileInfo(fileName, out pageSize, JET_DbInfo.PageSize);
    Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.DatabasePageSize, pageSize, null);

    Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.Recovery, 0, "Off");

    JET_INSTANCE jetInstance;
    string jetInstanceName = Guid.NewGuid().ToString("N");
    Api.JetCreateInstance(out jetInstance, jetInstanceName);

    Api.JetSetSystemParameter(jetInstance, JET_SESID.Nil, JET_param.BaseName, 0, logFileBaseName);
    Api.JetSetSystemParameter(jetInstance, JET_SESID.Nil, JET_param.LogFilePath, 0, databaseDirectory);
    Api.JetSetSystemParameter(jetInstance, JET_SESID.Nil, JET_param.TempPath, 0, databaseDirectory);
    Api.JetSetSystemParameter(jetInstance, JET_SESID.Nil, JET_param.SystemPath, 0, databaseDirectory);
    Api.JetSetSystemParameter(jetInstance, JET_SESID.Nil, Microsoft.Isam.Esent.Interop.Server2003.Server2003Param.AlternateDatabaseRecoveryPath, 0, databaseDirectory);
    try
    {
        Api.JetInit(ref jetInstance);

        JET_SESID sessionId;
        Api.JetBeginSession(jetInstance, out sessionId, "admin", "");

        try
        {
            Api.JetAttachDatabase(sessionId, fileName, AttachDatabaseGrbit.ReadOnly);

            JET_DBID databaseId;
            Api.JetOpenDatabase(sessionId, fileName, "", out databaseId, OpenDatabaseGrbit.ReadOnly);

            // Do other stuff here...

            Api.JetCloseDatabase(sessionId, databaseId, CloseDatabaseGrbit.None);
        }
        finally
        {
            Api.JetEndSession(sessionId, EndSessionGrbit.None);
        }
    }
    finally
    {
        Api.JetTerm(jetInstance);
    }
}

実際、データベース ファイルとログ ファイルの両方を にコピーし<directory of database>て実行する edbntutl.exe /r V01 /l <directory of database> /s <directory of database> /d <directory of database>と、データベースが使用可能になり、コード内でアタッチ可能になります。ただし、データベースを手動で回復する手順を実行しないと、コードの呼び出しに失敗JetAttachDatabaseし、エラーが発生しますJET_errDatabaseDirtyShutdown

では、私のコードがデータベースを自動的に回復しないのはなぜでしょうか? 文書化されていないことを行っているかedbntutl、エンジンがデータベースを回復できるようにするためにセッションの構成に何かが欠けています。前者は問題外ではありませんが、そうであれば非常に残念であり、代わりに何かが欠けているだけだと私は信じがちです.

注: 「コードを実行する前に esentutil を実行する」に相当する回答は、ユーティリティがパブリック API で利用できないことを行っているという証拠がなければ、正しいとは見なされません。

4

1 に答える 1