This project has moved. For the latest updates, please go here.

JET_errPageSizeMismatch

Aug 29, 2010 at 4:59 AM

A part of unit testing my Esent code is to open and read the databases created by the dictionary Hello World and Stock samples. When opening the Hello World database I get the following error when attaching the database:

Microsoft.Isam.Esent.Interop.EsentErrorException : Error PageSizeMismatch (JET_errPageSizeMismatch, The database page size does not match the engine)

Is there a formal way of handling this condition? I'm trying to write general purpose code, so I'd like to be able to open any database without being stopped by errors like this. The sample code and my code were compiled and run against the same build 54436 code on the same machine. Is there a way of discovering the page size to intercept this error before it happens?

I had a look inside the PersistentDictionary code, but I can't see anything there that might affect page sizes.

Cheers,
Greg

Aug 29, 2010 at 6:05 AM

Different databases can have different page sizes. You need the JetGetDatabaseFileInfo API to get the page size. I've started implementing it but haven't finished (there are about 10 native APIs left to implement and this is one of them). It should be added to the source code shortly.

 

Aug 29, 2010 at 7:16 AM

(Appologies up front: I'm most familiar with the regular C-API, but all these will have roughly guessable ManagedEsent equivalents)

In liu of using JetGetDatabaseFileInfo() to get the page size, just run "esentutl /mh WhatEverDb.edb" and look for the line beginning with "cbDbPage:", and set the JET_paramDatabasePageSize to that manually.

Another thing I've seen quite frequently causing this error during JetInit (not your problem here, but something that you may want to watch out for) is that the page-size is also stored in the transaction log files.  So if you call JetInit() using the default JET_paramLogFilePath location (".\") or set it to another directory and there are log files there, with the page size recorded in the log file as well ... this can cause a page size conflict on JetInit().

Std Msft Disclaimer ("AS IS", confers no warranties, etc, etc)

Nov 9, 2010 at 7:00 PM

@laurionb Any news about the new release of ManagedEsent? I need to set the databaseSize to 8192 but the API call JetSetDatabaseSize is also not supported, although it is on the supported list? Or if you have

some workaround I'm all ears!

Hope to hear from you!


Regards,

JD

Nov 9, 2010 at 7:53 PM
Ah, you actually want to set JET_param.DatabasePageSize, which is supported. JetSetDatabaseSize does something quite different. You can also set SystemParameters.DatabasePageSize, which will then set the system parameter.
--Laurion
On Tue, 09 Nov 2010 12:01 -0800, "JD_Blok" <notifications@codeplex.com> wrote:

From: JD_Blok

@laurionb Any news about the new release of ManagedEsent? I need to set the databaseSize to 8192 but the API call JetSetDatabaseSize is also not supported, although it is on the supported list? Or if you have

some workaround I'm all ears!

Hope to hear from you!


Regards,

JD

Read the full discussion online.

To add a post to this discussion, reply to this email (ManagedEsent@discussions.codeplex.com)

To start a new discussion for this project, email ManagedEsent@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Nov 9, 2010 at 8:35 PM

Yes thnx, you're totally right I read to quick and its getting late! However when I set the system parameter (SystemParameters.DatabasePageSize = 8192;) before creating an instance

I still receive Error PageSizeMismatch (JET_errPageSizeMismatch, The database page size does not match the engine)

What am I doing wrong? I added my little piece of code below, which works btw on the slighty modified stockExample.edb but without the dbPageSize set.


Regards, JD

 

string DatabaseName = "contacts.edb";

SystemParameters.DatabasePageSize = 8192;

using (var instance = new Instance("mydemo"))
{
instance.Parameters.CircularLog = true;
instance.Init();
using (var session = new Session(instance))
{

Api.JetAttachDatabase(session, DatabaseName, AttachDatabaseGrbit.None);

      Api.JetOpenDatabase(session, DatabaseName, null, out dbid, OpenDatabaseGrbit.None);

       Console.WriteLine("Getting table names");
        foreach (string tablename in Api.GetTableNames(session, dbid))
        {
           Console.WriteLine(tablename);
        }
}
}
Nov 9, 2010 at 8:44 PM

JD, I think the page size parameter is only meaningful when you're creating a new database. You're simply oening an existing one -- Greg

Nov 9, 2010 at 9:36 PM
You are trying to open an existing database, so you have to set the system parameter to match the database's page size. To get that information call JetGetDatabaseFileInfo and look at the cbPageSize member of the returned JET_DBINFOMISC.
--Laurion
On Tue, 09 Nov 2010 13:35 -0800, "JD_Blok" <notifications@codeplex.com> wrote:

From: JD_Blok

Yes thnx, you're totally right I read to quick and its getting late! However when I set the system parameter (SystemParameters.DatabasePageSize = 8192;) before creating an instance

I still receive Error PageSizeMismatch (JET_errPageSizeMismatch, The database page size does not match the engine)

What am I doing wrong? I added my little piece of code below, which works btw on the slighty modified stockExample.edb but without the dbPageSize set.


Regards, JD

string DatabaseName = "contacts.edb";

SystemParameters.DatabasePageSize = 8192;

using (var instance = new Instance("mydemo"))
{
instance.Parameters.CircularLog = true;
instance.Init();
using (var session = new Session(instance))
{

Api.JetAttachDatabase(session, DatabaseName, AttachDatabaseGrbit.None);

Api.JetOpenDatabase(session, DatabaseName, null, out dbid, OpenDatabaseGrbit.None);

Console.WriteLine("Getting table names");
foreach (string tablename in Api.GetTableNames(session, dbid))
{
Console.WriteLine(tablename);
}
}
}

Read the full discussion online.

To add a post to this discussion, reply to this email (ManagedEsent@discussions.codeplex.com)

To start a new discussion for this project, email ManagedEsent@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Nov 9, 2010 at 10:34 PM
Edited Nov 9, 2010 at 10:35 PM

I know I need to set it. I used esentutl which should not make any difference, so 8192 is correct as dbPageSize.

I also verified it with some Visual Basic code from somebody else, without setting it to 8192 it will return Psize mismatch

and with the correct Psize it works. But this still leaves me clueless why it doesn't work in C#?

 

Nov 10, 2010 at 11:04 AM

Chaps, I didn't notice that JetGetDatabaseFileInfo had been introduced until you mentioned it. This function has solved the original problem of my post. Before I open an arbitrary database I call JetGetDatabaseFileInfo and get the cbPageSize, then I set SystemParameters.DatabasePageSize to that value and my open will work.

Now I can open the PersistentDictionary.edb file, which previously caused a crash.

Now I'm a bit confused about the relationship and scope (and effect) of the SystemParameters properties and JetSetSystemParameter method. I'd really appreciate a potted summary of how they relate and how and when they should be used.

Cheers, Greg

Nov 11, 2010 at 7:57 PM

With the page size mistmatch one possible problem is having logfiles left over from previous runs where the logfile has the wrong page size embedded in it. Can you make sure there aren't any extra files.

SystemParameters.DatabasePageSize is just a wrapper around JetSetSystemParameter/JetGetSystemParameter with JET_param.DatabasePageSize. All of the SystemParameters and InstanceParameters accessors work that way. I added them because it can be really tedious to manually call JetSetSystemParameter with the required arguments and some arguments (e.g. path names) have to be in specific formats so having wrapper code makes things safer.

SystemParameters is used to set global parameters and InstanceParameters is used to set instance-specific parameters (which is why the constructor takes a JET_INSTANCE). Not all parameters are exposed that way, only the most common/useful ones.

Between JetSetSystemParameter and the SystemParameters wrapper I suggest using whichever one is easiest -- they both do the same thing.

 

Nov 11, 2010 at 9:20 PM

Laurion, thanks, that makes sense and it makes more sense after I had a look at the source code.

While browsing the source I found one very illuminating comment on the jet_apram.DatabasePageSize enum that has further answered one of my questions.

It says at all instances in the same process must use the same page size. This explains why I seemed to get "random" open failures in my utility app. The failure would occur whenever I tried to open mixed page size databases and I didn't notice the pattern. The simple workaround is to trap the specific open error and warn the user that they can't open a database of page size X until they close all of the currently open ones with page size Y.

Greg

Nov 14, 2010 at 6:00 PM

Laurion, I checked for previous logfiles and they were present in my executable directory. I removed them and no more ps-mismatch errors are displayed!

Thanks!!

JD