Как восстановить / восстановить базу данных ESE с помощью API Microsoft

То, чего я в основном пытаюсь достичь, это правильный способ восстановить грязную БД.

esentutl /mh db.dat дает следующий вывод

это нормально, потому что я взял копию БД, когда открывалась другой программой.

Можно ли открыть БД с помощью Microsoft JetBlue Api без надлежащих файлов log & chk? (ESEDatabaseView делает это как-то, http://www.nirsoft.net/)

Если такой случай невозможен с Microsoft API, и необходимы журналы, каков правильный способ восстановления базы данных (я изменил расположение моей базы данных и журналов)

вот мой код:

   wpath p2 = L"C:\\m.db";
        ULONG unPageSize;
        long jet_err = JetGetDatabaseFileInfoW(p2.file_string().c_str(), &unPageSize, sizeof(unPageSize), JET_DbInfoPageSize);
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetSetSystemParameter( NULL, NULL, JET_paramDatabasePageSize, unPageSize, NULL);
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetSetSystemParameter( NULL, NULL, JET_paramRecovery, 0, "Off");
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetSetSystemParameter( NULL, NULL, JET_paramLogFilePath, 0, "C:\\");
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetSetSystemParameter( NULL, NULL, JET_paramSystemPath, 0, "C:\\");
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetSetSystemParameter( NULL, NULL, JET_paramAlternateDatabaseRecoveryPath, 0, "C:\\");
        if (jet_err != JET_errSuccess) {
            return false;
        }

        JET_INSTANCE instance = { 0 };
        jet_err = JetCreateInstance(&instance, "instance");
        if (jet_err != JET_errSuccess) {
            return false;
        }

        jet_err = JetInit(&instance);
        if (jet_err != JET_errSuccess) {
            JetTerm(instance);
            return false;
        }

        JET_SESID sesid;
        jet_err = JetBeginSession(instance, &sesid, 0, 0);
        if (jet_err != JET_errSuccess) {
            JetTerm(instance);
            return false;
        }

        jet_err = JetAttachDatabaseW( sesid, pathESEDbLocation.file_string().c_str(), JET_bitDbReadOnly);
        if (jet_err != JET_errSuccess) {
            JetEndSession(sesid, 0);
            JetTerm(instance);
            return false;
        }

JetAttachDatabaseW терпит неудачу с -550 JET_errDatabaseDirtyShutdown

Изменить Я обнаружил, что простой esenutl /p data.dat Вызов без каких-либо контрольных точек и файлов журнала также устраняет проблему. Я пытался использовать JetExternalRestoreW команда, но она продолжает бросать #define JET_errFileNotFound -1811 /* File not found */

JET_RSTMAP_W p = {L"C:/Users/user/AppData/Local/Temp/db/db.dat", L"C:/Users/user/AppData/Local/Temp/db/db.dat"};
jet_err = JetExternalRestoreW(nullptr, L"C:/Users/user/AppData/Local/Temp/db/", &p, 1,L"C:/Users/igalk/AppData/Local/Temp/db/",  0, 0, nullptr);

1 ответ

Решение

Грязное завершение работы не означает, что в нем отсутствуют журнал и файлы проверки... Так что это может быть отдельной проблемой.

У вас в примере выше есть вещи в неправильном порядке...

Вы можете настроить свое приложение на автоматическую попытку очистить "грязное завершение", добавив следующее после JetCreateInstance и перед JetInit:

Api.JetSetSystemParameter(instance, JET_SESID.Nil, Server2003Param.AlternateDatabaseRecoveryPath, 0, Path.GetDirectoryName(databasePath));

(Пример выше в C#, но вы поняли...)

Последний параметр - это место, где вы хотели бы, чтобы восстановленная база данных появлялась, так что, скорее всего, это будет тот же каталог, что и грязный файл базы данных.

Другие вопросы по тегам