Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 22

What is Extensible Storage Engine

The Extensible Storage Engine (ESE) is an advanced indexed and sequential


access method (ISAM) storage technology. ESE enables applications to store and
retrieve data from tables using indexed or sequential cursor navigation. It
supports denormalized schemas including wide tables with numerous sparse
columns, multi-valued columns, and sparse and rich indexes. It enables
applications to enjoy a consistent data state using transacted data update and
retrieval. A crash recovery mechanism is provided so that data consistency is
maintained even in the event of a system crash. It provides ACID (Atomic
Consistent Isolated Durable) transactions over data and schema by way of a
write-ahead log and a snapshot isolation model. Transactions in ESE are highly
concurrent, making ESE useful for server applications. It caches data to maximize
high performance access to data. In addition, it is lightweight, making it useful
for applications that serve in auxiliary roles.

ESE is for use in applications that require fast and/or light structured data
storage, where raw file access or the registry does not support the application's
indexing or data size requirements.

It is used by applications that never store more than 1 megabyte of data, and has
been used in applications with databases in extreme cases in excess of 1 terabyte,
and commonly over 50 gigabytes.

This documentation is intended for developers who are familiar with C and C++,
and basic database concepts such as tables, columns, indexes, recovery, and
transactions. The only access method for ESE is the C API that is described in this
documentation.

The Extensible Storage Engine is a Windows component that was introduced in


Windows 2000. Not all features or APIs are available in all versions of the
Windows operating systems.

ESE provides a user-mode storage engine that manages data inside of flat, binary
files that are accessible through the Windows APIs. ESE is accessed through a
DLL that is loaded directly into the application's process; no remote access
methods are required of or provided by the database engine itself. Though ESE
has no remote or inter-process access method, the data files it uses can be
provided remotely by using server message block (SMB) through the Windows
APIs, but this is not recommended.

Note Windows XP 64-Bit Edition is the same as Windows Server 2003 for the
purpose of determining the ESE feature set that is supported.

Notes

ESE was formerly known as Joint Engine Technology (JET) Blue, and so
frequently the term "JET Blue" or "JET" is used interchangeably with the term
ESE outside this documentation. However, there are in fact two completely
separate implementations of the JET API, called JET Blue and JET Red. The term
"JET" is frequently also used to refer to JET Red, which is the database engine
that is used with Microsoft Office Access. The two JET implementations are
completely different, are separately maintained, have a vastly different feature
set, and are not interchangeable. Within the ESE documentation, "JET" refers to
the ESE or the JET API as ESE implements it. Any references to the JET Red will
always explicitly be labeled "JET Red".

About Extensible Storage Engine


The extensible storage engine (ESE) is a database engine that stores information
in a logical sequence. Information can be retrieved either sequentially or by
accessing defined indices. Updates to the database are implemented with a
transaction in order to ensure secure operations. ESE enables simultaneous
access to multiple databases, including transaction-log file databases that can be
used for system recovery. ESE is scalable to large or small applications. The
following features are available with the ESE application programming interface
(API):

 Backup and restore: An application can make consistent copies of the data
state while it is on-line and actively modifying data state.
 Cursor Navigation: The application can navigate with the cursor to access
data either sequentially or by using indices.
 Database: A collection of tables that are backed up and restored as a single
unit.
 Logging and crash recovery: The ESE API ensures that application-
defined data consistency is honored even in the event of a system crash.
 Tables: The fundamental structure of the ESE database that is used to store
data.
 Transaction: The ESE database engine provides Atomic Consistent
Isolated Durable (ACID) transactions that allow applications to retrieve
data only from reliable data states and maintains data consistency in the
event of an unexpected process termination or system shutdown.
 Scalable: The application can create databases as large as 100 GB or as
small as 1MB.

Database Overview
The ESE database is an indexed sequential access method (ISAM) for storing and
retrieving data. An ESE database is stored in a single file and consists of one or
more user-defined tables. Data is organized in records in the table with one or
more user-defined columns. Indexes that are created provide different
organization for the entire set or a subset of records in the table. Using the ESE
API, applications can create cursors that navigate records in the database in
different sequential orders. The elements of the table are defined below:

 Column: The column is a field in the table that stores a specific type of
information. Columns can be fixed, or variable length, depending on the
data type stored in them. Some columns, such as tagged columns take no
space when NULL or set to the default value, and can contain multiple
values.
 Records: A record is a collection of columns values that have a unique
identity as defined by the primary key.
 Index: The index is a collection of key columns that define a stored
ordering of records in the table. The clustered, or primary, index defines
the order in which the records are stored within the table. Multiple indices
can be defined in order to specify different orderings of traversal through
records in the table. An index may also limit the set of records visible
based on simple criteria such as the presence or absence of a particular
key column value in the record.
 Cursor: The cursor indicates the current record in the table and navigates
to records in the table using the current index. The cursor also contains
information on the state of the currently prepared update.

Columns and indices may be added-to or removed-from the table at any time.
Although multiple indices may be defined, the data in the table is physically
stored and logically clustered according to the primary index definition in a B+
tree. Each secondary index is stored in a separate B+ tree that contains only
logical pointers to the actual data that is stored in the primary table. If no index is
defined, the records in the table are stored in a B+ tree in the order of insertion
and are referred to as the sequential index.

The diagram here is an example of how the data for the table is stored in a B+
tree according to the primary index. The primary index is for Name and ID, and
a secondary index is created for the employee's office number. The entries for the
secondary index are stored in a separate B+ tree that contains only pointers to the
records stored in the primary table. For example, the office number 12348 in the
secondary table is related to record 3 in the primary table. Record 3 contains the
column values for the employee in office 12348. For more information, see the
Indexing in the Table topic.
ESE Handles
ESE handles are used to create sessions and access databases. They are
maintained in a hierarchy, which means that the output from one level is used to
access resources at the next level.

The diagram here shows the hierarchy of handles and the corresponding
functions that create the handles. Also indicated along with the functions are the
handles that are used in the call to create the new handle.
As shown in the diagram, the instance is the root handle and the level at which
the database is recovered in the event of an unexpected process termination or
system shutdown. The instance handle, JET_INSTANCE, is created by
JetCreateInstance and JetCreateInstance2. The next level, the session level, is the
transaction context of the database engine and the level under which all database
operations are performed. The session handle, JET_SESID, is created in the
context of the instance in the call to JetBeginSession. The session ID is used in all
subsequent calls to access tables and databases. If the instance is being used by
more than one thread at a time then each thread must use its own session handle.
The database handle is created using the session handle and primarily used to
manage the schema of the database, but it can also be used to manage tables
inside the database. Database handles can only be used in the session under
which they are created. The handle to the database is created in the call to
JetCreateDatabase or JetOpenDatabase. Tables are associated with the database
ID under which they are created.

The JET_TABLEID data type contains a handle to a database cursor. It is used to


scan records, search records or create update and delete records. The table
handle is created in the call to JetOpenTable, or JetCreateTable.
JetOpenTempTable, JetOpenTempTable2, and JetOpenTempTable3 also create
table IDs for temporary tables, and JetCreateTableColumnIndex and
JetCreateTableColumnIndex2 return table IDs in the out structure. The columns
created within the table each have a unique column identifier or COLUMN_ID.
The columns IDs are created in the calls to JetAddColumn, or in calls to
JetOpenTempTable, JetOpenTempTable2, or JetOpenTempTable3 for
temporary tables. Column IDs may also be retrieved for a given column by name
with APIs such as JetGetTableColumnInfo.

Maintenance utilities for Microsoft Exchange sever DB.(ESEUTILS)

Defragmentation: ESEUTIL /d <DB Name>


Recovery : ESEUTIL /r <Log File Base Name>
Integrity : ESEUTIL /g <DB Name>
File Dump : ESEUTIL /m <File Name> (Mode - modifier)
Repair : ESEUTIL /p <DB Name>
Restore : ESEUTIL /c <Path Name> (Mode - modifier)
Checksum : ESEUTIL /k <File Name>
Copy file : ESEUTIL /y <source File>

1. Defragmentation: Eseutil / <DB Name>

Defragmentation/compaction

Description: Performs off-line compaction of DB.


Syntax : Eseutil /d <DB Name>
Options : Separated by a space :
1. ‘/s <File>’ – set streaming file name
2. ‘/t <DB>’ - set temp.database name
(Default: tempdfrg*.edb).
3. ‘/f <file>’ - set temp.streaming File Name
(Default: tempdfrg.stm).
4. ‘/I ‘- do not defragment streaming files.
5. ‘/p ‘ - preserve temporary database
<ie.Don’t instate >
6. /b<DB> - Make Backup Copy Under the
specified name
7. /o – suppress logo.
NOTES: IF instating is disabled <ie. /p> the original DB is preserved
uncompacted, and the temporary DB will contain the defragmented Version of
the DB.
2. Recovery: ESEUTIL /r <Log File Base Name>.

Description: Performs recovery, bringing all DB to a Clean – Shut Down State.


Syntax : Eseutil /r <3-character log file base name>
Options : Separated by space:
1. ‘/L <Path>’ - Location of log files. (Default:
Current
Directory)
2. ‘/S<PATH>’ – Location of the System files ( eg.
Checkpoint file.

3. /I - ignore mismatched/missing db attachments.


4. /d {path} location of DB files or current directory
if path not specified.
5. /o – suppress logo
Integrity: ESEUTIL /g <DB Name>

Description: Verifies integrity of as DB


Syntax: Eseutil /g <DB name>
Parameters: <DB Name> - File name of db to verify.

Using Extensible Storage Engine


This section contains general information about how to use the following parts of
the ESE API.

 Columns
 Indexing in the Table
 Creating Databases
 Transactions
 ESE Errors
 ESE Files

Your program source files should include the esent.h header file to access
function prototypes and structure definitions for the Extensible Storage Engine
API. Developers can use the esent.lib library file to build applications that use the
Extensible Storage Engine API. At runtime, applications link to the esent.dll.

Columns
A table can be created either with an initial set of columns by calling
JetCreateTableColumnIndex or without an initial set of columns by calling
JetCreateTable. Tables in ESE can contain up to 127 fixed-length columns, 128
variable-length columns, and 64,993 tagged columns. Columns are identified by
their name and ID and can be dynamically added to the table with
JetAddColumn. Columns are created with a specific data type and an optional
set of attributes, such as whether the column is fixed-length or whether it can be
NULL or not.

The type of a column determines the data that may be stored in the column and
many of the properties of the column, including its order for indexing. ESE
supports a wide range of column types, ranging in size from 1 bit to 2 GB
(2146483647 ASCII characters or 1073741823 Unicode characters). For a complete
list of the column data types supported by ESE, see the JET_COLTYP topic. The
topics below discuss a few of the columns types supported by ESE:

 Tagged, Fixed and Variable Columns


 Version, Auto-Increment and Escrow Columns
 Long Value Columns
 Multi-Valued Sparse Columns
 User Defined Columns
 Using Columns in a Table

Indexing in the Table


An index is a set of key columns that define a persistent ordering of records in a
table. Records are index entries in the primary index. One primary index and
multiple secondary indexes can be defined to create different orders of data in
the table.

Although multiple indices can be defined, the records are physically stored in B+
trees in the order specified by the primary index. The primary index is always a
clustered index, and must also be unique. The primary index must be declared
before the first table update to preserve the index ordering. When no primary
index is defined by the application, the data is stored in the order in which
records are added to the table. This special index is referred to as a sequential
index.

Separate B+ trees are used to order records according to the secondary index.
Index entries in the secondary index contain pointers to the data stored
according to the primary index. The index entries for records in the primary
index must be unique because the secondary index points to the record using the
primary key of the record. Secondary indices may or may not have a uniqueness
constraint. For more information, see the Database Overview topic.

Creating Databases
The ESE database comprises one or more tables that organize data by columns
and rows. The ESE database is identified by name and database ID. An ESE
database looks like a single file to the Microsoft Windows operating system;
however, internally the database is stored as a collection of pages. These pages
contain metadata that describe the data in the database, the data itself, and one or
more indices that store different orders of the data. The database may contain up
to 2^31 pages, or 16 Terabytes of data for a database with 8 KB pages.

The application creates an instance of the database engine, then creates a


database and attaches it to the instance. Up to 6 databases can be simultaneously
attached to an instance with JetCreateDatabase or JetAttachDatabase. One or
more sessions should be started within the database, because all subsequent ESE
operations are performed in the context of a session. A separate session should
be opened for each thread using ESE.

This procedure will initialize ESE and create a database.

To initialize ESE and create a database

1. JetCreateInstance: Creates an instance of the database engine.


Windows XP and later: This function is available in Windows XP and later.
On Windows 2000, only one instance is supported and that instance is created
implicitly

2. JetSetSystemParameter: System parameters that the affect the physical


layout such as the JET_paramLogFilePath and JET_paramSystemPath must
be set before initializing the instance with JetInit. The parameters set at this
stage are set for all databases created in the instance. JetSetSystemParameter
is the only function that can use the instance before it is initialized with
JetInit.
3. JetInit: Initializes the instance. Instance must be initialized with JetInit
before it can be used with any other functions.
4. JetBeginSession: Creates the session for all subsequent transactions. All
database transactions take place in the context of the session (JET_SESID).
5. JetCreateDatabase: Creates the database and returns a handle to the
database ID (JET_DBID).

If the database already exists, step 5 above is replaced by the following two
steps:

a. JetAttachDatabase: Attaches the database by name to the session


b. JetOpenDatabase: Returns the database ID that is used in
subsequent database operations.

A database can be detached from one ESE instance using JetDetachDatabase and
later attached to another instance with JetAttachDatabase. When the database is
detached, it can be copied as a single file using standard Windows utilities.
However, when the database is attached to an ESE instance it cannot be copied
since ESE opens database files exclusively. Also, if the instance crashes then the
database file cannot be copied alone because it needs the transaction log files
associated with it to recover from that crash.

Transactions
ESE transactions are logical units of processing that control how an application
sees and manipulates rows in the database. Your application can use transaction
save points to determine whether to keep or discard a particular set of changes to
the database. All transactions in ESE are atomic, consistent, isolated, and durable
(ACID) as described below:

 Atomic: All the updates in the transaction either appear in the database or
they are discarded.
 Consistent: The database will always start in a legal state and will always
end in another legal state. For ESE applications, the database engine will
control some simple constraints, for example uniqueness of a unique
index, but the application itself will define almost all other aspects of what
it means for the database to be in a legal state.
 Isolation: Transactions are isolated from updates by other sessions. A
transaction will never see a partial set of changes made by another
transaction.
 Durable: After the database engine acknowledges that a transaction has
been committed, its changes are persistent in the database. The durability
of a transaction may be optionally waived for performance reasons.

Transactions are performed within the bounds of the calls to


JetBeginTransaction and JetCommitTransaction or JetRollback. When the
application enters the transaction, the database appears frozen at the instance in
time that the transaction begins. This is called snapshot isolation. If the
transaction is terminated by calling JetRollback, none of the operations
performed in the transaction are committed to the database. If the process or the
machine crashes before JetCommitTransaction is called, it is the same as calling
JetRollback.

This procedure shows how to start and commit a transaction that reads and
updates data in a database.

To start and commit a transaction


1. Call JetBeginTransaction or JetBeginTransaction2 with the session ID to
start the transaction.
2. Move the cursor to the desired record by calling JetMove with
JET_MoveFirst specified in the cRow parameter. For more information on
how to move the cursor, see the Indexing in the Table topic.
3. Call JetGetTableColumnInfo on the current record with JET_ColInfo
specified in the InfoLevel parameter to retrieve the column ID for the column.
The column ID is returned in the JET_COLUMNDEF structure.
4. Call JetSetColumn with the session ID, table ID, and column ID of the
column that is updated. The column data is contained in the pvData
parameter.
5. Call JetCommitTransaction to commit the transaction to the database.

The way in which an ESE database engine implements snapshot isolation has
some important differences from traditional relational database isolation and
locking models. When a transaction reads a row, it can always access the row
without failing or waiting for other sessions to release a lock. When a transaction
attempts to update a row, it will succeed if it is the first session to update that
row, that is the first writer wins. If the session is not the first writer then it will
immediately fail with a write conflict error. The session must then abort its
transaction, wait (usually via a random delay), for the other transaction to
commit its changes, and then retry the transaction. The database engine will not
automatically cause that session to wait until the other transaction has finished
its update. Usually, a transaction will test if it can update a row inside of the
JetUpdate call. If it cannot lock the row for update then JetUpdate will fail with
JET_errWriteConflict.

Sessions are limited to one thread from the time the transaction starts to the end
of the transaction. It is recommended that all update and retrieve operations be
performed in a transaction. ESE also supports schema modifications such as
creating tables and adding columns inside the transaction. Both update and
schema modifications can be performed in the same transaction. After the
transaction completes with JetCommitTransaction, the update is logged in the
transaction log file. These files can be used to maintain a logically consistent state
in the event of an unexpected process termination or system shutdown.

Transactions may be nested up to 7 levels with matching calls to


JetBeginTransaction and JetCommitTransaction or JetRollback nested within
each other. This allows the application to rollback a part of the transaction
without having to back out of the entire transaction. The nested call to
JetCommitTransaction signifies that this level of processing is complete;
however, the transaction is not committed to the database until the outer most
call to commit the transaction with JetCommitTransaction.

Escrow update columns can be updated concurrently by multiple sessions


without failing with Jet_errWriteConflict. The JetEscrowUpdate function may
only be called on escrow columns, columns that were created with
Jet_bitColumnEscrowUpdate

Extensible Storage Engine Errors


All possible errors returned by the Extensible Storage Engine (ESE) API are
defined by the JET_ERR data type. For a list of the error flags that are defined for
this API, see Extensible Storage Engine Error Codes.

Throughout the ESE API documentation, only the most important errors are
documented. These errors typically represent API usage errors or very important
error conditions. Be aware that any of these ESE APIs can also return other errors
that are not documented for each API. In these cases, the caller should simply
handle the error as they would any other error that is returned by the API. The
specific error value may then be used for diagnostic purposes such as tracing.

In general, a value that is greater than zero should be interpreted as a warning, a


value of zero should be interpreted as success, and a value that is less than zero
should be interpreted as an error. No other patterns in these values (for example,
ranges of values) should be relied upon by an application.

When ESE encounters some of the more serious errors, it creates an event log
entry that contains details about the errors. The level of logging can be controlled
by Event Log Parameters.
Some applications require the ability to return JET_ERRs as HRESULTs. The
following C++ example shows how to make that conversion:

Copy Code

#ifndef FACILITY_JET_ERR

#define FACILITY_JET_ERR 0xE5E

#endif

#ifndef HRESULT_FROM_JET_ERR

#define HRESULT_FROM_JET_ERR( __err )

( __err ) == JET_errSuccess ?

S_OK :

( __err ) == JET_errOutOfMemory ?

E_OUTOFMEMORY :

MAKE_HRESULT

( __err ) < 0 ?

SEVERITY_ERROR :

SEVERITY_SUCCESS

),

FACILITY_JET_ERR,

( __err ) < 0 ?
-( __err ) :

( __err )

& 0xFFFF

#endif

For information about configuring system parameters for error handling, see
Error Handling Parameters.

See Also
Error Handling Parameters
Extensible Storage Engine Error Codes
JET_ERR

Extensible Storage Engine Files


The Extensible Storage Engine uses the following types of files:

 Transaction Log Files


 Temporary Transaction Log Files
 Reserved Transaction Log Files
 Checkpoint Files
 Database Files
 Temporary Databases

This table contains an overview of the data file names that are managed by ESE. For
Windows Vista and later, the JET_paramLegacyNames setting impacts the file names
that are used.
Windows
Server 2003 Windows Vista Windows Vista and
and earlier and later later
JET_paramLegacyNa JET_bitESE98FileNa
mes setting N/A None mes
Current Log <inst>.log <inst>.jtx <inst>.log
Pre-Init Log <inst>tmp.log <inst>tmp.jtx <inst>tmp.log
Rotated Logs <inst>XXXXX. <inst>XXXXX.jtx <inst>XXXXX.log
log after FFFFF after FFFFF switch to
switch to <inst>XXXXXXXX.lo
<inst>XXXXXXX g.
X.jtx
Checkpoint File <inst>.chk <inst>.jcp <inst>.jcp
Temporary Database <temp db file <temp db file <temp db file name>
name> name> Default: Default: tmp.edb
Default: tmp.edb
tmp.edb
Reserved Transaction res1.log & <inst>RESXXXXX <inst>RESXXXXX.jrs
Log File res2.log .jrs
Database File <db file <db file name> <db file name>
name>

Transaction Log Files


Transaction log files contain operations on database files. They contain enough
information to bring a database to a logically consistent state after an unexpected
process termination or system shutdown.

The names of the log files are dependent on a three-letter base name, which can
be set with JET_paramBaseName. The examples below use a base name of "edb",
because that is the default base name. The extension for the transaction log files
will be either .log or .jtx depending upon whether the JET_bitESE98FileNames is
set in the JET_paramLegacyFileNames parameter. For more information, see
Extensible Storage Engine System Parameters.

Transaction log files are named <base><generation-number>.log, beginning with


1. The log generation number is in hexadecimal format. For example,
edb00001.log is the first log, and edb000ff.log is the 255th log. The log files have
five hexadecimal digits in the log file name, until the 1048576th log file, at which
point the log files start being named in an 11.3 format (for example,
edb00100000.log). <base>.log is always the log file that is currently being used. If
the database engine is not active, the generation of edb.log can be identified
using the following command: esentutl.exe -ml edb.log.

Although transaction log files have the .LOG extension commonly associated
with text files, transaction log files are in a binary format and should never be
edited by a user.

Database operations are written to the log first. The data can be written to the
database file later; possibly immediately, potentially much later. In the event of
unexpected process or system termination, the operations are still present in the
log files, and incomplete transactions can be rolled back. The act of replaying
transaction log files is called soft recovery, and it is done automatically when
JetInit or JetInit2 is called. Soft recovery can also be performed manually with
the "-r" option of the Esentutl.exe program. The act of replaying transaction log
files on a database that is restored from a backup is called hard recovery.

Log files are of a fixed size, customizable with JET_paramLogFileSize. When the
current log file (that is, edb.log) gets filled, it gets renamed to
<base><generation-number>.log, and a new transaction log file is needed in the
transaction log stream.

Each database instance has a single log file sequence associated with it.
Windows XP introduced JetCreateInstance, allowing multiple transaction log
file sequences to be used by a single process. Multiple transaction log file
sequences cannot exist in the same directory, however.

Transaction log files should almost never be manually manipulated, renamed,


moved, or deleted because data corruption can result.

Transaction log files will be deleted by the database engine during a full backup
(see JetBackup, JetTruncateLog, JetTruncateLogInstance), or during normal
operations, if circular logging is enabled.
After a transaction log file is filled up, the database engine needs to create a new
log file. Circular logging is a means by which log files can be automatically
cleaned up by the database engine when they are no longer required for crash
recovery. This process is an alternative to removing log files as a by-product of
performing a backup. Circular logging can be controlled with the
JET_paramCircularLog system parameter. Transaction log files should not be
deleted using any other method.

Temporary Transaction Log Files


When edb.log fills up, ESE needs to create a new file. The new log transaction file
is known as a temporary transaction log file prior to its use by ESE.

While a new log file is created and its size extended, it will be called
<base>tmp.log. Creating a new file can be a potentially costly operation, so ESE
will create the next log file proactively as a background task.

Because the temporary transaction log file is created in anticipation of need for a
new transaction log file, it does not contain any useful information.

Reserved Transaction Log Files


The reserved transaction log files are created when the engine starts to allow
important operations to be logged to get a clean shutdown.

Windows Vista: In Windows Vista and later, the Reserved Transaction Log Files
are named <base>RESXXXXX.jrs.
Windows Server 2003: In Windows Server 2003 and earlier, The Reserved
Transaction Log Files are named res1.log and res2.log.
When the database engine runs out of disk space it cannot create a new log file.
The safest thing to do is to shut down cleanly, but some operations (such as
rollback operations) must still be logged. Most database operations will fail
during this stage.

Because the reserved transaction log files are created in anticipation of need for
transaction log files in an out-of-disk scenario, they do not contain any useful
information.
Checkpoint Files
The checkpoint file stores the checkpoint for a particular transaction log file
sequence. The checkpoint file is named <base>.chk or <base>.jcp, depending
upon whether the JET_bitESE98FileNames is set in the
JET_paramLegacyFileNames parameter, and its location is given by
JET_paramSystemPath.

Database operations are first written to the log files and then cached in memory.
At some later point, the operations get written to the database file, but for
performance reasons, the order in which operations are written to the database
file might not match the order in which they were originally logged. Operations
written to the transaction log file will be in one of two states:

 Written to the transaction log file and the database file


 Written to the transaction log file and not yet written to the database file

Many database operations can be stored in a single transaction log file. A given
log file can consist of the following items:

 All operations written to the database file


 No operations written to the database file
 A mix of operations written to the database file and operations not yet
written to the database file.

The checkpoint refers to the point in time in the transaction log stream where all
operations prior to the checkpoint have been written to the database file. There is
no guarantee about the operations that occur after the checkpoint; some might be
in memory, and some might be written to the database.
Since all the operations in the log files prior to the checkpoint are represented in
the database file, only the transaction log files after the checkpoint are needed for
soft recovery to bring a particular database into a clean state.
Database Files
The database file contains the schema for all of the tables in the database, the
records for all of the tables in the database, and the indexes over the tables. Its
location is given using JetCreateDatabase, JetCreateDatabase2,
JetAttachDatabase, or JetAttachDatabase2.

A database is cleanly shut down only after a successful call to JetTerm or


JetTerm2.

The Esentutl.exe program can detect whether a database is shut down cleanly
with the "-mh" option. For example, "esentutl.exe -mh sample.edb" will read the
database header of a database named sample.edb, and print out the state of
sample.edb. It may print out "State: Clean Shutdown" or "State: Dirty Shutdown".

A database that has not been cleanly shut down is in a dirty shutdown state.
Prior to Windows XP, this state was called inconsistent. A dirty (inconsistent)
database can be brought to a clean state with soft recovery. A corrupt database is
not the same as a dirty ("inconsistent") database.

A corrupt database refers to a physical or logical corruption, and cannot be fixed


with soft recovery. Physical corruptions can be bit flips, which will frequently be
caught by the checksums on the database pages. A failed checksum in a database
file manifests itself as a JET_errReadVerifyFailure error.

Only cleanly shut down databases can be safely moved around or renamed. If a
database was not cleanly shut down, it cannot be automatically safely moved or
renamed.

Multiple databases can be associated with a single transaction log file sequence.

Temporary Databases
The temporary database is used as a backing store for temptables and it is also
used when creating indices.

The name and location is configured with JET_paramTempPath.


Temptables are created with JetOpenTempTable, JetOpenTempTable2,
JetOpenTempTable3, JetOpenTemporaryTable. They are also created by some
API calls and used to return schema information (such as JetGetIndexInfo).

Extensible Storage Engine Callback Functions


The Extensible Storage Engine API can be extended with the following callback
functions:

 JET_CALLBACK
 JET_PFNREALLOC
 JET_PFNSTATUS

http://msdn2.microsoft.com/en-us/library/ms683060(VS.85).aspx
Extensible Storage Engine Constants
The Extensible Storage Engine Constants section contains the following sections:

 JET_CBTYP
 JET_COLTYP
 JET_OBJTYP
 JET_SNP
 JET_SNT
 Error Handling Constants
 Event Logging Constants
 Extensible Storage Engine System Parameters
 Invalid Handle Constants
 Maximum Settings Constants
 Obsolete Constants

You might also like