如何使用 Microsoft API 还原/恢复 ESE 数据库
How to restore / recover ESE DB using Microsoft's API
我在这里基本上想要实现的是恢复脏数据库的正确方法。
esentutl /mh db.dat
产生以下输出
这很好,因为我在被另一个程序打开时获取了数据库的副本。
是否可以在没有正确日志和 chk 文件的情况下使用 Microsoft 的 JetBlue Api 打开数据库? (ESEDatabaseView 以某种方式做到了,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);
脏关机并不意味着它丢失了日志和检查文件...所以这可能是一个单独的问题。
你上面的例子顺序错了...
您可以将应用程序配置为自动尝试清除 "dirty shutdown",方法是在 JetCreateInstance 之后和 JetInit 之前添加以下内容:
Api.JetSetSystemParameter(instance, JET_SESID.Nil, Server2003Param.AlternateDatabaseRecoveryPath, 0, Path.GetDirectoryName(databasePath));
(上面的示例是在 C# 中,但你明白了...)
最后一个参数是您希望修复的数据库出现的位置,因此很可能是与脏数据库文件相同的目录。
我在这里基本上想要实现的是恢复脏数据库的正确方法。
esentutl /mh db.dat
产生以下输出
这很好,因为我在被另一个程序打开时获取了数据库的副本。
是否可以在没有正确日志和 chk 文件的情况下使用 Microsoft 的 JetBlue Api 打开数据库? (ESEDatabaseView 以某种方式做到了,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);
脏关机并不意味着它丢失了日志和检查文件...所以这可能是一个单独的问题。
你上面的例子顺序错了...
您可以将应用程序配置为自动尝试清除 "dirty shutdown",方法是在 JetCreateInstance 之后和 JetInit 之前添加以下内容:
Api.JetSetSystemParameter(instance, JET_SESID.Nil, Server2003Param.AlternateDatabaseRecoveryPath, 0, Path.GetDirectoryName(databasePath));
(上面的示例是在 C# 中,但你明白了...)
最后一个参数是您希望修复的数据库出现的位置,因此很可能是与脏数据库文件相同的目录。