//----------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. // //----------------------------------------------------------------------- namespace Microsoft.Isam.Esent.Interop { using System; using System.Globalization; using System.IO; using Microsoft.Isam.Esent.Interop.Server2003; using Microsoft.Isam.Esent.Interop.Vista; using Microsoft.Isam.Esent.Interop.Windows7; /// /// This class provides properties to set and get system parameters /// on an ESENT instance. /// public partial class InstanceParameters { /// /// The instance to set parameters on. /// private readonly JET_INSTANCE instance; /// /// The session to set parameters with. /// private readonly JET_SESID sesid; /// /// Initializes a new instance of the InstanceParameters class. /// /// /// The instance to set parameters on. If this is JET_INSTANCE.Nil, /// then the settings affect the default settings of future instances. /// public InstanceParameters(JET_INSTANCE instance) { this.instance = instance; this.sesid = JET_SESID.Nil; } /// /// Gets or sets the relative or absolute file system path of the /// folder that will contain the checkpoint file for the instance. /// public string SystemDirectory { get { return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.SystemPath)); } set { this.SetStringParameter(JET_param.SystemPath, Util.AddTrailingDirectorySeparator(value)); } } /// /// Gets or sets the relative or absolute file system path of /// the folder that will contain the temporary database for the instance. /// public string TempDirectory { get { // Older versions of Esent (e.g. Windows XP) will return the // full path of the temporary database. Extract the directory name. string path = this.GetStringParameter(JET_param.TempPath); string dir = Path.GetDirectoryName(path); return Util.AddTrailingDirectorySeparator(dir); } set { this.SetStringParameter(JET_param.TempPath, Util.AddTrailingDirectorySeparator(value)); } } /// /// Gets or sets the relative or absolute file system path of the /// folder that will contain the transaction logs for the instance. /// public string LogFileDirectory { get { return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.LogFilePath)); } set { this.SetStringParameter(JET_param.LogFilePath, Util.AddTrailingDirectorySeparator(value)); } } /// /// Gets or sets the relative or absolute file system path of the /// a folder where crash recovery or a restore operation can find /// the databases referenced in the transaction log in the /// specified folder. /// /// /// This parameter is ignored on Windows XP. /// public string AlternateDatabaseRecoveryDirectory { get { if (EsentVersion.SupportsServer2003Features) { return Util.AddTrailingDirectorySeparator( this.GetStringParameter(Server2003Param.AlternateDatabaseRecoveryPath)); } return null; } set { if (EsentVersion.SupportsServer2003Features) { this.SetStringParameter( Server2003Param.AlternateDatabaseRecoveryPath, Util.AddTrailingDirectorySeparator(value)); } } } /// /// Gets or sets the three letter prefix used for many of the files used by /// the database engine. For example, the checkpoint file is called EDB.CHK by /// default because EDB is the default base name. /// public string BaseName { get { return this.GetStringParameter(JET_param.BaseName); } set { this.SetStringParameter(JET_param.BaseName, value); } } /// /// Gets or sets an application specific string that will be added to /// any event log messages that are emitted by the database engine. This allows /// easy correlation of event log messages with the source application. By default /// the host application executable name will be used. /// public string EventSource { get { return this.GetStringParameter(JET_param.EventSource); } set { this.SetStringParameter(JET_param.EventSource, value); } } /// /// Gets or sets the number of sessions resources reserved for this instance. /// A session resource directly corresponds to a JET_SESID. /// public int MaxSessions { get { return this.GetIntegerParameter(JET_param.MaxSessions); } set { this.SetIntegerParameter(JET_param.MaxSessions, value); } } /// /// Gets or sets the number of B+ Tree resources reserved for this instance. /// public int MaxOpenTables { get { return this.GetIntegerParameter(JET_param.MaxOpenTables); } set { this.SetIntegerParameter(JET_param.MaxOpenTables, value); } } /// /// Gets or sets the number of cursor resources reserved for this instance. /// A cursor resource directly corresponds to a JET_TABLEID. /// public int MaxCursors { get { return this.GetIntegerParameter(JET_param.MaxCursors); } set { this.SetIntegerParameter(JET_param.MaxCursors, value); } } /// /// Gets or sets the maximum number of version store pages reserved /// for this instance. /// public int MaxVerPages { get { return this.GetIntegerParameter(JET_param.MaxVerPages); } set { this.SetIntegerParameter(JET_param.MaxVerPages, value); } } /// /// Gets or sets the preferred number of version store pages reserved /// for this instance. If the size of the version store exceeds this /// threshold then any information that is only used for optional /// background tasks, such as reclaiming deleted space in the database, /// is instead sacrificed to preserve room for transactional information. /// public int PreferredVerPages { get { return this.GetIntegerParameter(JET_param.PreferredVerPages); } set { this.SetIntegerParameter(JET_param.PreferredVerPages, value); } } /// /// Gets or sets the the number of background cleanup work items that /// can be queued to the database engine thread pool at any one time. /// public int VersionStoreTaskQueueMax { get { return this.GetIntegerParameter(JET_param.VersionStoreTaskQueueMax); } set { this.SetIntegerParameter(JET_param.VersionStoreTaskQueueMax, value); } } /// /// Gets or sets the number of temporary table resources for use /// by an instance. This setting will affect how many temporary tables can be used at /// the same time. If this system parameter is set to zero then no temporary database /// will be created and any activity that requires use of the temporary database will /// fail. This setting can be useful to avoid the I/O required to create the temporary /// database if it is known that it will not be used. /// /// /// The use of a temporary table also requires a cursor resource. /// public int MaxTemporaryTables { get { return this.GetIntegerParameter(JET_param.MaxTemporaryTables); } set { this.SetIntegerParameter(JET_param.MaxTemporaryTables, value); } } /// /// Gets or sets the size of the transaction log files. This parameter /// should be set in units of 1024 bytes (e.g. a setting of 2048 will /// give 2MB logfiles). /// public int LogFileSize { get { return this.GetIntegerParameter(JET_param.LogFileSize); } set { this.SetIntegerParameter(JET_param.LogFileSize, value); } } /// /// Gets or sets the amount of memory used to cache log records /// before they are written to the transaction log file. The unit for this /// parameter is the sector size of the volume that holds the transaction log files. /// The sector size is almost always 512 bytes, so it is safe to assume that size /// for the unit. This parameter has an impact on performance. When the database /// engine is under heavy update load, this buffer can become full very rapidly. /// A larger cache size for the transaction log file is critical for good update /// performance under such a high load condition. The default is known to be too small /// for this case. /// Do not set this parameter to a number of buffers that is larger (in bytes) than /// half the size of a transaction log file. /// public int LogBuffers { get { return this.GetIntegerParameter(JET_param.LogBuffers); } set { this.SetIntegerParameter(JET_param.LogBuffers, value); } } /// /// Gets or sets a value indicating whether circular logging is on. /// When circular logging is off, all transaction log files that are generated /// are retained on disk until they are no longer needed because a full backup of the /// database has been performed. When circular logging is on, only transaction log files /// that are younger than the current checkpoint are retained on disk. The benefit of /// this mode is that backups are not required to retire old transaction log files. /// public bool CircularLog { get { return this.GetBoolParameter(JET_param.CircularLog); } set { this.SetBoolParameter(JET_param.CircularLog, value); } } /// /// Gets or sets a value indicating whether JetInit fails when the database /// engine is configured to start using transaction log files on disk /// that are of a different size than what is configured. Normally, /// will successfully recover the databases /// but will fail with /// to indicate that the log file size is misconfigured. However, when /// this parameter is set to true then the database engine will silently /// delete all the old log files, start a new set of transaction log files /// using the configured log file size. This parameter is useful when the /// application wishes to transparently change its transaction log file /// size yet still work transparently in upgrade and restore scenarios. /// public bool CleanupMismatchedLogFiles { get { return this.GetBoolParameter(JET_param.CleanupMismatchedLogFiles); } set { this.SetBoolParameter(JET_param.CleanupMismatchedLogFiles, value); } } /// /// Gets or sets the initial size of the temporary database. The size is in /// database pages. A size of zero indicates that the default size of an ordinary /// database should be used. It is often desirable for small applications to configure /// the temporary database to be as small as possible. Setting this parameter to /// will achieve the smallest /// temporary database possible. /// public int PageTempDBMin { get { return this.GetIntegerParameter(JET_param.PageTempDBMin); } set { this.SetIntegerParameter(JET_param.PageTempDBMin, value); } } /// /// Gets or sets the threshold in bytes for about how many transaction log /// files will need to be replayed after a crash. If circular logging is enabled using /// CircularLog then this parameter will also control the approximate amount /// of transaction log files that will be retained on disk. /// public int CheckpointDepthMax { get { return this.GetIntegerParameter(JET_param.CheckpointDepthMax); } set { this.SetIntegerParameter(JET_param.CheckpointDepthMax, value); } } /// /// Gets or sets the number of pages that are added to a database file each /// time it needs to grow to accommodate more data. /// public int DbExtensionSize { get { return this.GetIntegerParameter(JET_param.DbExtensionSize); } set { this.SetIntegerParameter(JET_param.DbExtensionSize, value); } } /// /// Gets or sets a value indicating whether crash recovery is on. /// public bool Recovery { get { return 0 == string.Compare(this.GetStringParameter(JET_param.Recovery), "on", StringComparison.OrdinalIgnoreCase); } set { if (value) { this.SetStringParameter(JET_param.Recovery, "on"); } else { this.SetStringParameter(JET_param.Recovery, "off"); } } } /// /// Gets or sets a value indicating whether online defragmentation is enabled. /// public bool EnableOnlineDefrag { get { return this.GetBoolParameter(JET_param.EnableOnlineDefrag); } set { this.SetBoolParameter(JET_param.EnableOnlineDefrag, value); } } /// /// Gets or sets a value indicating whether will check for /// indexes that were build using an older version of the NLS library in the /// operating system. /// public bool EnableIndexChecking { get { return this.GetBoolParameter(JET_param.EnableIndexChecking); } set { this.SetBoolParameter(JET_param.EnableIndexChecking, value); } } /// /// Gets or sets the name of the event log the database engine uses for its event log /// messages. By default, all event log messages will go to the Application event log. If the registry /// key name for another event log is configured then the event log messages will go there instead. /// public string EventSourceKey { get { return this.GetStringParameter(JET_param.EventSourceKey); } set { this.SetStringParameter(JET_param.EventSourceKey, value); } } /// /// Gets or sets a value indicating whether informational event /// log messages that would ordinarily be generated by the /// database engine will be suppressed. /// public bool NoInformationEvent { get { return this.GetBoolParameter(JET_param.NoInformationEvent); } set { this.SetBoolParameter(JET_param.NoInformationEvent, value); } } /// /// Gets or sets the detail level of eventlog messages that are emitted /// to the eventlog by the database engine. Higher numbers will result /// in more detailed eventlog messages. /// public EventLoggingLevels EventLoggingLevel { get { return (EventLoggingLevels)this.GetIntegerParameter(JET_param.EventLoggingLevel); } set { this.SetIntegerParameter(JET_param.EventLoggingLevel, (int)value); } } /// /// Gets or sets a value indicating whether only one database is allowed to /// be opened using JetOpenDatabase by a given session at one time. /// The temporary database is excluded from this restriction. /// public bool OneDatabasePerSession { get { return this.GetBoolParameter(JET_param.OneDatabasePerSession); } set { this.SetBoolParameter(JET_param.OneDatabasePerSession, value); } } /// /// Gets or sets a value indicating whether ESENT will silently create folders /// that are missing in its filesystem paths. /// public bool CreatePathIfNotExist { get { return this.GetBoolParameter(JET_param.CreatePathIfNotExist); } set { this.SetBoolParameter(JET_param.CreatePathIfNotExist, value); } } /// /// Gets or sets a value giving the number of B+ Tree resources cached by /// the instance after the tables they represent have been closed by /// the application. Large values for this parameter will cause the /// database engine to use more memory but will increase the speed /// with which a large number of tables can be opened randomly by /// the application. This is useful for applications that have a /// schema with a very large number of tables. /// /// Supported on Windows Vista and up. Ignored on Windows XP and /// Windows Server 2003. /// /// public int CachedClosedTables { get { if (EsentVersion.SupportsVistaFeatures) { return this.GetIntegerParameter(VistaParam.CachedClosedTables); } return 0; } set { if (EsentVersion.SupportsVistaFeatures) { this.SetIntegerParameter(VistaParam.CachedClosedTables, value); } } } /// /// Gets or sets a the number of logs that esent will defer database /// flushes for. This can be used to increase database recoverability if /// failures cause logfiles to be lost. /// /// Supported on Windows 7 and up. Ignored on Windows XP, /// Windows Server 2003, Windows Vista and Windows Server 2008. /// /// public int WaypointLatency { get { if (EsentVersion.SupportsWindows7Features) { return this.GetIntegerParameter(Windows7Param.WaypointLatency); } // older versions have no waypoint return 0; } set { if (EsentVersion.SupportsWindows7Features) { this.SetIntegerParameter(Windows7Param.WaypointLatency, value); } } } /// /// Returns a that represents the current . /// /// /// A that represents the current . /// public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "InstanceParameters (0x{0:x})", this.instance.Value); } /// /// Set a system parameter which is a string. /// /// The parameter to set. /// The value to set. private void SetStringParameter(JET_param param, string value) { Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, value); } /// /// Get a system parameter which is a string. /// /// The parameter to get. /// The value of the parameter. private string GetStringParameter(JET_param param) { int ignored = 0; string value; Api.JetGetSystemParameter(this.instance, this.sesid, param, ref ignored, out value, 1024); return value; } /// /// Set a system parameter which is an integer. /// /// The parameter to set. /// The value to set. private void SetIntegerParameter(JET_param param, int value) { Api.JetSetSystemParameter(this.instance, this.sesid, param, value, null); } /// /// Get a system parameter which is an integer. /// /// The parameter to get. /// The value of the parameter. private int GetIntegerParameter(JET_param param) { int value = 0; string ignored; Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0); return value; } /// /// Set a system parameter which is a boolean. /// /// The parameter to set. /// The value to set. private void SetBoolParameter(JET_param param, bool value) { if (value) { Api.JetSetSystemParameter(this.instance, this.sesid, param, 1, null); } else { Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, null); } } /// /// Get a system parameter which is a boolean. /// /// The parameter to get. /// The value of the parameter. private bool GetBoolParameter(JET_param param) { int value = 0; string ignored; Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0); return value != 0; } } }