如何使用Microsoft的API还原/恢复ESE DB [英] How to restore / recover ESE DB using Microsoft's API
问题描述
我基本上想要在这里实现的是一种还原脏数据库的正确方法.
What I'm basically trying to achieve here is a proper way to restore a dirty DB.
esentutl /mh db.dat
产生以下输出
这很好,因为我在被另一个程序打开时拿了数据库的副本.
which is fine because i took a copy of the DB while being opened by another program.
是否可以使用Microsoft的JetBlue Api打开数据库,而没有正确的日志& chk文件? ( ESEDatabaseView 以某种方式做到了, nirsoft.net )
is it possible to open the DB using microsoft's JetBlue Api without the proper log & chk files? (ESEDatabaseView does it somehow, nirsoft.net)
如果Microsoft API无法实现这种情况,并且需要日志,那么恢复数据库的正确方法是什么(我已经更改了数据库的&日志位置)
If such case isn't possible with Microsoft's API, and logs are needed, what is the correct way of recovering the db(i've changed my DB's & logs location)
这是我的代码:
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
JetAttachDatabaseW
fails with -550 JET_errDatabaseDirtyShutdown
编辑,我发现没有任何检查点和日志文件的简单esenutl /p data.dat
调用也可以解决此问题.我尝试使用JetExternalRestoreW
命令,但它会不断抛出#define JET_errFileNotFound -1811 /* File not found */
Edit I have found out that a simple esenutl /p data.dat
call without any checkpoint and log files also fixes the issue. I've tried using the JetExternalRestoreW
command but it keeps throwing #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);
推荐答案
肮脏的关闭并不意味着它会丢失日志和检查文件...因此,这可能是一个单独的问题.
A dirty shutdown doesn't mean that it's missing the log and check files... So that might be a separate issue.
您上面的示例中的东西顺序错误...
You example above has things in the wrong order...
通过在JetCreateInstance之后和JetInit之前添加以下内容,可以将应用程序配置为自动尝试清除脏关机":
You can configure your application to automatically attempt to clear the "dirty shutdown" by adding the following after JetCreateInstance and before JetInit:
Api.JetSetSystemParameter(instance, JET_SESID.Nil, Server2003Param.AlternateDatabaseRecoveryPath, 0, Path.GetDirectoryName(databasePath));
(以上示例在C#中,但您明白了...)
(above sample is in C#, but you get the point...)
最后一个参数是您希望修复的数据库出现的位置,因此很可能与脏数据库文件位于同一目录.
The last parameter is the location where you'd like the repaired database to appear, so most likely that'd be the same directory as the dirty database file.
这篇关于如何使用Microsoft的API还原/恢复ESE DB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!