The database page size does not match the engine, trying to open Groove Music Database

Aug 21, 2016 at 10:26 AM
Edited Aug 21, 2016 at 2:29 PM
I'm currently trying to open the Groove Music Database to read from there the my playlists.

But when I try to JetAttachDatabase I get the follwoing error:

The database page size does not match the engine

The ESEDatabaseView Application can open the database, so the file is not invalid.

I tried to set the DatabasePageSize using follwoing method before the new Instance() constructor

SetIntegerParameter(Esnet.JET_INSTANCE.Nil, Esnet.JET_param.DatabasePageSize, 8192)
private void SetIntegerParameter(Esnet.JET_INSTANCE inst, Esnet.JET_param param, int value)
{
        Esnet.Api.JetSetSystemParameter(inst, Esnet.JET_SESID.Nil, param, value, null);
}

But I got the same error for 8192 16384, and 32768 always the same error, for 2048 I got a invalid parameter error.

Does someone know how to figure out the page size by the database file? Or how to debug the file?

I uploaded my GrooveDatabase with logs if someone wants to try...

https://1drv.ms/f/s!AkY5QCCnUjHghv4zzVUac979PuRcww

Thanks you for help :)

EDIT:

I used the advice in this answer
http://stackoverflow.com/questions/5031633/esent-database-engine-limited-to-specific-page-sizes

and set instance.Parameters.Recovery=false;

This way I figured out that the size seem to be 8192, since when callling it with 4096 I still get the The database page size does not match the engine. But with 8192 I get the error Database was not shutdown cleanly. Recovery must first be run to properly complete database operations for the previous shutdown.

Then I further tried the advice:
               SetIntegerParameter(Esnet.JET_INSTANCE.Nil, Esnet.JET_param.DatabasePageSize, 8192);

                var inst = new Esnet.Instance("GrooveMusicExporter");

                inst.Parameters.Recovery = true;

                // paramLogFilePath is the underlying setting. FilePath is a misleading name because it means the directory.
                inst.Parameters.LogFileDirectory = databaseDir; 
                inst.Parameters.LogFileSize = 2048;
                inst.Parameters.BaseName = "edb";
This results in the error Database was not shutdown cleanly. Recovery must first be run to properly complete database operations for the previous shutdown.

But I still don't know how to open the database, I mean Groove and ESEDatabaseView don't get the error. Do I have to use ESEUTIL?

I found this post
https://managedesent.codeplex.com/discussions/542562
Is there yet a way to recover it whith this libary and without esnetutil?
Developer
Aug 21, 2016 at 4:27 PM
You may have some leftover log files messing things up. Another person had a similar question with a different database: http://stackoverflow.com/questions/38312774/esent-always-throws-esentpagesizemismatchexception-when-trying-to-open-ie-10-11/

You will need to turn Log File Recovery back on in order to replay the log files to get a cleanly-shutdown database. That's what Groove would be doing.
By disabling recovery, you are telling the database engine to ignore any log files on disk. In other words, your LogFileDirectory and LogFileSize parameters are just being ignored at that point.
If you had Log File Recovery enabled, and started the engine with 'bad' parameters, then those log files may be getting in the way. If you are able to identify which log files were accidentally created, move them to a different location (and then later delete them).

Does that help? Or are you still experiencing difficulties?

-martin
Aug 21, 2016 at 11:08 PM
Thank you for your help,

In my Edit I turned Recovery on again, that helped me but,

It turned out that my problem was following:

To prevent my application from destroying the groove database as first step I copy all Files of the Database to a new Temp folder and only Open this copy (I only want to read data and the database is only 12 MB).
Now what I did not know is that just copying the groove database folder to another location does not work, it seems to me the edb database does not work with relative file references, but with direct ones. (correct me if I'm wrong)

This resulted that when I opened the copied edb:

The .edb in my temp still was pointing on the log files at the source location.
So since the log files and the db where at differnet localtions the Esnet Engine correctly told me my database was invalid.
Ironically Trying to open the copied edb (with Recovery=true) also resulting in corrupting the original groove database (or its logs)
Luckyly Groove is so smart to dedect a corrupted database and in this case delete the corrupted database and recover the cache again from the server (I only lost a minor local playlist)

My original Problem is solved, but what still would be nice to know how to copy a edb database correctly?
Developer
Aug 22, 2016 at 12:48 AM
It's actually the other way. :) The log files point to the full path of the .edb file. When you call JetInit, that initiates log recovery, and will look at the original location (not in your temp directory). That is what will replay the log transactions and make the .edb file in to a 'Clean' shutdown state. That's all done before JetAttachDatabase/JetOpendDatabase.

By copying to a temp location first, you'll need to specify the JET_paramAlternateDatabaseRecoveryPath prior to JetInit, or use the JET_RSTMAP functionality of JetInit3 (I may have these names slightly wrong -- it's off the top of my head :).

Does that help?

Also if you're curious, you can use esentutl -mh foo.edb to look at the header information of the database and see what paths are in there, or esentutl -ml foo.log to see which databases were attached to that transaction log stream, or esentutl -mk foo.chk to dump the checkpoint file (an optimization so that not all log files in a directory are examined every time JetInit is called).

-martin
Aug 22, 2016 at 9:58 PM
Thank you very much, that solved my problem :)

Greetings Michael