El Motor de Almacenamiento Extensible ( ESE ), también conocido como JET Blue , es una tecnología de almacenamiento de datos ISAM (método de acceso secuencial indexado) de Microsoft . ESE es el núcleo de Microsoft Exchange Server , Active Directory y la Búsqueda de Windows . También lo utilizan varios componentes de Windows, como el cliente de Windows Update y el Centro de Ayuda y Soporte Técnico . Su propósito es permitir que las aplicaciones almacenen y recuperen datos mediante acceso secuencial indexado.
ESE permite la actualización y recuperación de datos transaccionales . Incorpora un mecanismo de recuperación ante fallos que garantiza la coherencia de los datos incluso en caso de caída del sistema. Las transacciones en ESE son altamente concurrentes, lo que lo hace idóneo para aplicaciones de servidor. ESE almacena los datos en caché de forma inteligente para asegurar un acceso de alto rendimiento. Además, ESE es ligero, lo que lo hace adecuado para aplicaciones auxiliares.
El entorno de ejecución ESE (ESENT.DLL) se ha incluido en todas las versiones de Windows desde Windows 2000 , con una versión nativa x64 incluida en las versiones x64 de Windows XP y Windows Server 2003. Microsoft Exchange , hasta Exchange 2003, solo incluía la edición de 32 bits, ya que era la única plataforma compatible. Con Exchange 2007 , se incluye la edición de 64 bits.
Bases de datos
Una base de datos es una agrupación tanto física como lógica de datos. Una base de datos ESE se presenta como un único archivo para Windows. Internamente, la base de datos es una colección de páginas de 2, 4, 8, 16 o 32 KB (las opciones de páginas de 16 y 32 KB solo están disponibles en Windows 7 y Exchange 2010), [ 1 ] organizadas en una estructura de árbol B balanceada . [ 2 ] Estas páginas contienen metadatos para describir los datos contenidos en la base de datos, los datos en sí, índices para conservar órdenes de interés de los datos y otra información. Esta información se encuentra intercalada dentro del archivo de la base de datos, pero se realizan esfuerzos para mantener agrupados los datos utilizados conjuntamente dentro de la base de datos. Una base de datos ESE puede contener hasta 2 × 32 páginas, o 16 terabytes de datos, [ 3 ] para páginas de 8 kilobytes .
Las bases de datos ESE se organizan en grupos denominados instancias. La mayoría de las aplicaciones utilizan una única instancia, pero también pueden utilizar varias. La importancia de la instancia radica en que asocia una única serie de registros de recuperación con una o más bases de datos. Actualmente, se pueden conectar hasta 6 bases de datos de usuario a una instancia ESE simultáneamente. Cada proceso independiente que utiliza ESE puede tener hasta 1024 instancias ESE.
Una base de datos es portátil, ya que puede separarse de una instancia de ESE en ejecución y luego conectarse a la misma instancia o a otra diferente. Mientras está separada, se puede copiar mediante las utilidades estándar de Windows. No se puede copiar mientras se está utilizando activamente, puesto que ESE abre exclusivamente archivos de base de datos. Una base de datos puede residir físicamente en cualquier dispositivo compatible con operaciones de E/S directamente direccionables por Windows.
Tablas
Una tabla es una colección homogénea de registros, donde cada registro tiene el mismo conjunto de columnas. Cada tabla se identifica mediante un nombre, cuyo alcance es local a la base de datos que la contiene. La cantidad de espacio en disco asignado a una tabla dentro de una base de datos viene determinada por un parámetro que se especifica al crear la tabla con la operación CreateTable. Las tablas crecen automáticamente en respuesta a la creación de datos.
Las tablas tienen uno o más índices. Debe haber al menos un índice agrupado para los datos de los registros. Cuando la aplicación no define un índice agrupado, se utiliza un índice artificial que ordena y agrupa los registros según el orden cronológico de inserción. Los índices se definen para conservar el orden de los datos y permiten tanto el acceso secuencial a los registros en el orden del índice como el acceso directo a los registros mediante los valores de las columnas del índice. Los índices agrupados en ESE también deben ser primarios, lo que significa que la clave del índice debe ser única.
Los índices agrupados y no agrupados se representan mediante árboles B+ . Si una operación de inserción o actualización provoca un desbordamiento de página, esta se divide: se asigna una nueva página que se encadena lógicamente entre las dos páginas previamente adyacentes. Dado que esta nueva página no es físicamente adyacente a sus vecinas lógicas, el acceso a ella no es tan eficiente. ESE cuenta con una función de compactación en línea que recompacta los datos. Si se prevé que una tabla se actualice con frecuencia, se puede reservar espacio para futuras inserciones especificando una densidad de página adecuada al crear una tabla o un índice. Esto permite evitar o posponer las operaciones de división.
Registros y columnas
Un registro es un conjunto asociado de valores de columna. Los registros se insertan y actualizan mediante operaciones de actualización y se pueden eliminar mediante operaciones de eliminación. Las columnas se establecen y recuperan mediante operaciones de establecimiento y recuperación de columnas, respectivamente. El tamaño máximo de un registro es de 8110 bytes para páginas de 8 kilobytes, con la excepción de las columnas de valores largos. Los tipos de columna LongText y LongBinary no contribuyen significativamente a esta limitación de tamaño, y los registros pueden contener datos mucho mayores que el tamaño de una página de base de datos cuando los datos se almacenan en columnas de valores largos. Cuando se almacena una referencia de valor largo en un registro, solo se requieren 9 bytes de datos dentro del registro. Estos valores largos pueden tener un tamaño de hasta 2 gigabytes (GB).
Los registros suelen ser uniformes, ya que cada uno contiene un conjunto de valores para el mismo conjunto de columnas. En ESE, también es posible definir muchas columnas para una tabla y, aun así, que cada registro contenga solo un pequeño número de valores de columna no nulos. En este sentido, una tabla también puede ser una colección de registros heterogéneos.
ESE admite una amplia gama de valores de columna, con tamaños que van desde 1 bit hasta 2 GB. Elegir el tipo de columna correcto es importante, ya que este determina muchas de sus propiedades, incluido su orden para los índices. ESE admite los siguientes tipos de datos:
Tipos de columna
Columnas fijas, variables y etiquetadas
Cada tabla ESE puede definir hasta 127 columnas de longitud fija, 128 columnas de longitud variable y 64.993 columnas etiquetadas.
- Las columnas fijas son, esencialmente, columnas que ocupan la misma cantidad de espacio en cada registro, independientemente de su valor. Las columnas fijas utilizan un bit para representar si el valor de la columna es nulo y una cantidad fija de espacio en cada registro en el que se establece dicha columna, o una columna fija definida posteriormente.
- Las columnas variables son, esencialmente, columnas que ocupan una cantidad variable de espacio en cada registro en el que se establecen, dependiendo del tamaño del valor de la columna en cuestión. Las columnas variables ocupan 2 bytes para determinar si un valor es nulo y su tamaño, y una cantidad variable de espacio en cada registro en el que se establece dicha columna.
- Las columnas etiquetadas son columnas que no ocupan espacio si no se establecen en un registro. Pueden tener un solo valor o múltiples valores. Una misma columna etiquetada puede tener varios valores en un mismo registro. Cuando se establecen columnas etiquetadas en un registro, cada instancia de una columna etiquetada ocupa aproximadamente 4 bytes, además del tamaño de la instancia del valor de la columna etiquetada. Cuando el número de instancias de una misma columna etiquetada es elevado, la sobrecarga por instancia de columna etiquetada es de aproximadamente 2 bytes. Las columnas etiquetadas son ideales para columnas dispersas, ya que no ocupan espacio si no se establecen. Si una columna etiquetada con múltiples valores está indexada, el índice contendrá una entrada para el registro por cada valor de la columna etiquetada.
En una tabla dada, las columnas se dividen en dos categorías: aquellas que aparecen exactamente una vez en cada registro, con la posibilidad de contener algunos valores nulos; y aquellas que aparecen con poca frecuencia o que pueden tener múltiples apariciones en un mismo registro. Las columnas fijas y variables pertenecen a la primera categoría, mientras que las columnas etiquetadas pertenecen a la segunda. La representación interna de ambas categorías de columnas es diferente, y es importante comprender las ventajas y desventajas de cada una. Las columnas fijas y variables suelen estar presentes en todos los registros, incluso cuando la aparición contiene un valor nulo. Estas columnas se pueden identificar rápidamente mediante una tabla de desplazamiento. Las apariciones de columnas etiquetadas van precedidas de un identificador de columna, y la columna se localiza mediante una búsqueda binaria en el conjunto de columnas etiquetadas.
Valores largos
Los tipos de columna Texto largo y Binario largo son objetos binarios de gran tamaño. Se almacenan en un árbol B+ independiente del índice agrupado, indexado por ID de valor largo y desplazamiento de bytes. ESE admite la adición, la sobrescritura de rangos de bytes y el ajuste de tamaño para estas columnas. Además, ESE cuenta con una función de almacenamiento de instancia única que permite que varios registros hagan referencia al mismo objeto binario de gran tamaño, como si cada registro tuviera su propia copia de la información, es decir, sin conflictos de bloqueo entre registros. El tamaño máximo de un valor de columna Texto largo o Binario largo es de 2 GB.
Columnas de versión, autoincremento y depósito en garantía
Las columnas de versión se incrementan automáticamente en ESE cada vez que se modifica un registro que contiene esta columna mediante una operación de actualización. Esta columna no puede ser modificada por la aplicación, solo leída. Entre las aplicaciones de las columnas de versión se incluye determinar si es necesario actualizar una copia en memoria de un registro. Si el valor en un registro de la tabla es mayor que el valor en una copia en caché, se considera que la copia en caché está desactualizada. Las columnas de versión deben ser de tipo Long.
Las columnas de autoincremento se configuran automáticamente mediante ESE, de modo que el valor que contienen es único para cada registro de la tabla. Estas columnas, al igual que las de versión, no pueden ser configuradas por la aplicación. Las columnas de autoincremento son de solo lectura y se configuran automáticamente cuando se inserta un nuevo registro en una tabla mediante una operación de actualización. El valor de la columna permanece constante durante la vida útil del registro, y solo se permite una columna de autoincremento por tabla. Las columnas de autoincremento pueden ser de tipo Long o Currency.
Las columnas de depósito en garantía se pueden modificar mediante una operación EscrowUpdate. Las actualizaciones de depósito en garantía son operaciones delta numéricas. Las columnas de depósito en garantía deben ser de tipo Long. Ejemplos de operaciones delta numéricas incluyen sumar 2 a un valor o restar 1 a un valor. ESE rastrea el cambio en un valor en lugar del valor final de una actualización. Varias sesiones pueden tener cambios pendientes realizados mediante EscrowUpdate en el mismo valor porque ESE puede determinar el valor final real independientemente de qué transacciones se confirmen y cuáles se reviertan. Esto permite que varios usuarios actualicen simultáneamente una columna realizando cambios delta numéricos. Opcionalmente, el motor de base de datos puede borrar registros con un valor cero en la columna. Un uso común para dicha columna de depósito en garantía es el contador de referencias: varios subprocesos incrementan/decrementan el valor sin bloqueos, y cuando el contador llega a cero, el registro se elimina automáticamente.
Índices
Un índice es una ordenación persistente de registros en una tabla. Los índices se utilizan tanto para el acceso secuencial a las filas en el orden definido como para la navegación directa de registros basada en los valores de las columnas indexadas. El orden definido por un índice se describe mediante una matriz de columnas, en orden de precedencia. Esta matriz de columnas también se denomina clave de índice. Cada columna se denomina segmento de índice. Cada segmento de índice puede ser ascendente o descendente, en función de su contribución a la ordenación. Se puede definir cualquier número de índices para una tabla. ESE proporciona un amplio conjunto de funciones de indexación.
Índices agrupados
Un índice puede especificarse como índice agrupado o primario. En ESE, el índice agrupado debe ser único y se denomina índice primario. Otros índices se describen como índices no agrupados o secundarios. Los índices primarios se diferencian de los secundarios en que la entrada del índice es el registro en sí, y no un puntero lógico al registro. Los índices secundarios tienen claves primarias en sus hojas para vincularse lógicamente con el registro en el índice primario. En otras palabras, la tabla está agrupada físicamente según el orden del índice primario. La recuperación de datos de registros no indexados en el orden del índice primario suele ser mucho más rápida que en el orden del índice secundario. Esto se debe a que un único acceso al disco puede cargar en memoria varios registros que se accederán en un corto intervalo de tiempo. El mismo acceso al disco satisface las operaciones de acceso a múltiples registros. Sin embargo, la inserción de un registro en medio de un índice, según lo determine el orden del índice primario, puede ser mucho más lenta que agregarlo al final del índice. La frecuencia de actualización debe considerarse cuidadosamente en función de los patrones de recuperación al diseñar la tabla. Si no se define un índice primario para una tabla, se crea un índice primario implícito, denominado índice de clave de base de datos (DBK). El DBK es simplemente un número único ascendente que se incrementa cada vez que se inserta un registro. Como resultado, el orden físico de los registros en un índice DBK es el orden cronológico de inserción, y los nuevos registros siempre se añaden al final de la tabla. Si una aplicación desea agrupar datos en un índice no único, puede hacerlo añadiendo una columna de autoincremento al final de la definición del índice no único.
Indexación sobre columnas multivaloradas
Los índices se pueden definir sobre columnas multivalor. Pueden existir varias entradas en estos índices para registros con múltiples valores en la columna indexada. Las columnas multivalor se pueden indexar junto con columnas de valor único. Cuando se indexan dos o más columnas multivalor juntas, la propiedad de multivalor solo se aplica a la primera columna multivalor del índice. Las columnas de menor precedencia se tratan como si fueran de valor único.
Índices dispersos
Los índices también pueden definirse como dispersos. Los índices dispersos no contienen al menos una entrada por cada registro de la tabla. Existen varias opciones para definir un índice disperso. Se pueden excluir registros de los índices cuando una clave de índice completa es NULL, cuando cualquier segmento de clave es NULL o cuando solo el primer segmento de clave es NULL. Los índices también pueden tener columnas condicionales. Estas columnas nunca aparecen en un índice, pero pueden impedir que un registro se indexe cuando la columna condicional es NULL o no NULL.
Índices de tuplas
También se pueden definir índices para incluir una entrada por cada subcadena de una columna de texto o texto largo. Estos índices se denominan índices de tupla. Se utilizan para acelerar las consultas con predicados de coincidencia de subcadenas. Los índices de tupla solo se pueden definir para columnas de texto. Por ejemplo, si el valor de una columna de texto es "Me encanta JET Blue" y el índice está configurado para tener un tamaño mínimo de tupla de 4 caracteres y una longitud máxima de tupla de 10 caracteres, entonces se indexarán las siguientes subcadenas:
Aunque los índices de tuplas pueden ser muy grandes, pueden acelerar significativamente las consultas del tipo: encontrar todos los registros que contengan “JET Blue” . Se pueden usar para subcadenas más largas que la longitud máxima de la tupla dividiendo la subcadena de búsqueda en cadenas de búsqueda de longitud máxima de tupla e intersectando los resultados. Se pueden usar para coincidencias exactas para cadenas tan largas como la longitud máxima de la tupla o tan cortas como la longitud mínima de la tupla, sin intersección de índices. Para obtener más información sobre cómo realizar la intersección de índices en ESE, consulte Intersección de índices . Los índices de tuplas no pueden acelerar las consultas donde la cadena de búsqueda es más corta que la longitud mínima de la tupla.
Actas
Una transacción es una unidad lógica de procesamiento delimitada por las operaciones BeginTransaction y CommitTransaction, o Rollback. Todas las actualizaciones realizadas durante una transacción son atómicas; o bien aparecen todas en la base de datos al mismo tiempo, o bien no aparece ninguna. Las actualizaciones posteriores realizadas por otras transacciones son invisibles para la transacción. Sin embargo, una transacción solo puede actualizar datos que no hayan cambiado mientras tanto; de lo contrario, la operación falla inmediatamente sin esperar. Las transacciones de solo lectura nunca necesitan esperar, y las transacciones de actualización solo pueden interferir entre sí. Las transacciones que se terminan mediante Rollback o por un fallo del sistema no dejan rastro en la base de datos. En general, el estado de los datos se restaura en Rollback al estado anterior a BeginTransaction.
Las transacciones pueden anidarse hasta en 7 niveles, con un nivel adicional reservado para uso interno de ESE. Esto significa que una parte de una transacción puede revertirse sin necesidad de revertir la transacción completa; una confirmación de transacción (CommitTransaction) de una transacción anidada simplemente indica el éxito de una fase del procesamiento, y la transacción externa aún puede fallar. Los cambios se confirman en la base de datos solo cuando se confirma la transacción más externa. Esto se conoce como confirmación al nivel de transacción 0. Cuando la transacción se confirma al nivel de transacción 0, los datos que la describen se vacían sincrónicamente en el registro para garantizar que la transacción se complete incluso en caso de una caída posterior del sistema. El vaciado sincrónico del registro hace que las transacciones de ESE sean duraderas. Sin embargo, en algunos casos, las aplicaciones desean ordenar sus actualizaciones, pero no garantizar de inmediato que los cambios se realicen. En este caso, las aplicaciones pueden confirmar los cambios con JET_bitIndexLazyFlush.
ESE admite un mecanismo de control de concurrencia llamado multiversión. En la multiversión, cada transacción consulta una vista consistente de toda la base de datos tal como estaba en el momento en que se inició la transacción. Las únicas actualizaciones que encuentra son las que ella misma ha realizado. De esta forma, cada transacción opera como si fuera la única transacción activa en ejecución en el sistema, excepto en caso de conflictos de escritura. Dado que una transacción puede realizar cambios basándose en datos leídos que ya han sido actualizados en otra transacción, la multiversión por sí sola no garantiza transacciones serializables . Sin embargo, la serialización se puede lograr cuando se desee simplemente utilizando bloqueos de lectura de registros explícitos para bloquear los datos leídos en los que se basan las actualizaciones. Tanto los bloqueos de lectura como los de escritura se pueden solicitar explícitamente con la operación GetLock.
Además, ESE admite una función avanzada de control de concurrencia conocida como bloqueo de depósito en garantía. El bloqueo de depósito en garantía es una actualización extremadamente concurrente en la que se modifica un valor numérico de forma relativa, es decir, sumando o restando otro valor numérico. Las actualizaciones de depósito en garantía no generan conflictos, incluso con otras actualizaciones concurrentes del mismo dato. Esto es posible porque las operaciones admitidas son conmutables y pueden confirmarse o revertirse de forma independiente. Como resultado, no interfieren con las transacciones de actualización concurrentes. Esta función se utiliza frecuentemente para agregaciones mantenidas.
ESE también extiende la semántica de transacciones, desde operaciones de manipulación de datos hasta operaciones de definición de datos. Es posible agregar un índice a una tabla y que transacciones simultáneas actualicen la misma tabla sin ningún tipo de conflicto de bloqueo. Posteriormente, una vez finalizadas estas transacciones, el índice recién creado está disponible para todas ellas y contiene entradas para las actualizaciones de registros realizadas por otras transacciones que no pudieron percibir la presencia del índice en el momento de las actualizaciones. Las operaciones de definición de datos pueden ejecutarse con todas las funcionalidades propias del mecanismo de transacciones para la actualización de registros. Entre las operaciones de definición de datos compatibles se incluyen AddColumn, DeleteColumn, CreateIndex, DeleteIndex, CreateTable y DeleteTable.
Navegación del cursor y el búfer de copia
Un cursor es un puntero lógico dentro de un índice de tabla. Puede ubicarse sobre un registro, antes del primero, después del último o incluso entre registros. Si se encuentra antes o después de un registro, no hay ningún registro activo. Es posible tener varios cursores en el mismo índice de tabla. Muchas operaciones con registros y columnas se basan en la posición del cursor. Esta posición puede modificarse secuencialmente mediante operaciones de movimiento o directamente utilizando las claves del índice con operaciones de búsqueda. También es posible mover el cursor a una posición fraccionaria dentro del índice, lo que permite desplazarlo rápidamente a la posición de la barra de desplazamiento. Esta operación se realiza con la misma velocidad que una búsqueda y no requiere acceder a datos intermedios.
Cada cursor dispone de un búfer de copia para crear un nuevo registro o modificar uno existente, columna por columna. Este es un búfer interno cuyo contenido se puede cambiar con operaciones SetColumns. Las modificaciones del búfer de copia no alteran automáticamente los datos almacenados. El contenido del registro actual se puede copiar en el búfer de copia mediante la operación PrepareUpdate, y las operaciones Update almacenan el contenido del búfer de copia como un registro. El búfer de copia se borra implícitamente al confirmar o revertir una transacción, así como durante las operaciones de navegación. RetrieveColumns se puede utilizar para recuperar datos de columna, ya sea del registro o del búfer de copia, si existe.
Procesamiento de consultas
Las aplicaciones ESE invariablemente consultan sus datos. Esta sección del documento describe las características y técnicas que utilizan las aplicaciones para escribir la lógica de procesamiento de consultas en ESE.
Tablas de clasificación y temporales
ESE proporciona una función de ordenación mediante tablas temporales. La aplicación inserta los registros de datos en el proceso de ordenación de uno en uno y luego los recupera también de uno en uno en orden. La ordenación se realiza entre la inserción del último registro y la recuperación del primero. Las tablas temporales también pueden utilizarse para conjuntos de resultados parciales y completos. Estas tablas ofrecen las mismas funcionalidades que las tablas base, incluyendo la posibilidad de navegar secuencialmente o directamente a las filas mediante claves de índice que coinciden con la definición de ordenación. Las tablas temporales también pueden actualizarse para el cálculo de agregaciones complejas. Las agregaciones simples pueden calcularse automáticamente con una función similar a la de ordenación, donde la agregación deseada es un resultado natural del proceso de ordenación.
Índices de cobertura
La recuperación de datos de columna directamente desde índices secundarios es una optimización de rendimiento importante. Las columnas se pueden recuperar directamente desde índices secundarios, sin acceder a los registros de datos, mediante el indicador RetrieveFromIndex en la operación RetrieveColumns. Es mucho más eficiente recuperar columnas desde un índice secundario que desde el registro, al navegar por el índice. Si los datos de la columna se recuperaran del registro, sería necesaria una navegación adicional para localizarlo mediante la clave primaria. Esto podría generar accesos adicionales al disco. Cuando un índice proporciona todas las columnas necesarias, se denomina índice de cobertura. Cabe destacar que las columnas definidas en el índice primario de la tabla también se encuentran en los índices secundarios y se pueden recuperar de forma similar mediante JET_bitRetrieveFromPrimaryBookmark.
Las claves de índice se almacenan en formato normalizado, que en muchos casos puede desnormalizarse para obtener el valor original de la columna. La normalización no siempre es reversible. Por ejemplo, los tipos de columna Texto y Texto largo no se pueden desnormalizar. Además, las claves de índice pueden truncarse cuando los datos de la columna son muy extensos. En los casos en que las columnas no se pueden recuperar directamente de los índices secundarios, siempre se puede acceder al registro para recuperar los datos necesarios.
Intersección de índices
Las consultas suelen implicar una combinación de restricciones de datos. Una forma eficiente de procesar una restricción es utilizar un índice disponible. Sin embargo, si una consulta incluye múltiples restricciones, las aplicaciones suelen procesarlas recorriendo todo el rango del índice que satisface el predicado más restrictivo. El predicado restante, denominado predicado residual, se procesa aplicándolo al registro en sí. Este método es sencillo, pero tiene la desventaja de requerir potencialmente numerosos accesos al disco para cargar los registros en memoria y aplicar el predicado residual.
La intersección de índices es un mecanismo de consulta importante que utiliza varios índices para procesar de forma más eficiente una restricción compleja. En lugar de usar un solo índice, se combinan rangos de índices en varios índices para obtener un número mucho menor de registros a los que se puede aplicar cualquier predicado residual. ESE facilita este proceso mediante la operación IntersectIndexes. Esta operación acepta una serie de rangos de índices en índices de la misma tabla y devuelve una tabla temporal de claves primarias que permite navegar a los registros de la tabla base que satisfacen todos los predicados de índice.
Tablas preunidas
Una operación de unión (join) es común en tablas normalizadas, donde se combinan datos lógicamente relacionados para su uso en una aplicación. Las uniones pueden ser costosas debido a la gran cantidad de accesos a datos necesarios para cargar la información relacionada en memoria. Este proceso se puede optimizar definiendo una tabla base que contenga datos para dos o más tablas lógicas. El conjunto de columnas de la tabla base es la unión de los conjuntos de columnas de estas tablas lógicas. Las columnas etiquetadas permiten esto gracias a su buen manejo de datos multivalorados y dispersos. Dado que los datos relacionados se almacenan juntos en el mismo registro, se accede a ellos de forma conjunta, minimizando así el número de accesos a disco necesarios para realizar la unión. Este proceso se puede extender a un gran número de tablas lógicas, ya que ESE admite hasta 64 993 columnas etiquetadas. Dado que se pueden definir índices sobre columnas multivaloradas, también es posible indexar tablas internas. Sin embargo, existen algunas limitaciones y las aplicaciones deben considerar cuidadosamente la pre-unión antes de emplear esta técnica.
Registro de eventos y recuperación tras fallos
La función de registro y recuperación de ESE garantiza la integridad y la coherencia de los datos en caso de fallo del sistema. El registro consiste en documentar de forma redundante las operaciones de actualización de la base de datos en un archivo de registro. La estructura de este archivo es muy robusta ante fallos del sistema. La recuperación consiste en utilizar este registro para restaurar las bases de datos a un estado coherente tras un fallo del sistema.
Las operaciones de transacción se registran y el registro se vacía en disco durante cada confirmación al nivel de transacción 0. Esto permite que el proceso de recuperación rehaga las actualizaciones realizadas por las transacciones que se confirman al nivel de transacción 0 y deshaga los cambios realizados por las transacciones que no se confirmaron al nivel de transacción 0. Este tipo de esquema de recuperación se conoce a menudo como un esquema de recuperación de "avance/retroceso". Los registros pueden conservarse hasta que los datos se copien de forma segura mediante un proceso de copia de seguridad descrito a continuación, o bien pueden reutilizarse de forma circular tan pronto como ya no sean necesarios para la recuperación tras un fallo del sistema. El registro circular minimiza la cantidad de espacio en disco necesario para el registro, pero tiene implicaciones en la capacidad de recrear un estado de datos en caso de fallo del medio.
Copia de seguridad y restauración
El registro y la recuperación también desempeñan un papel fundamental en la protección de datos ante fallos en el medio de almacenamiento. ESE admite copias de seguridad en línea, donde se copian una o más bases de datos, junto con los archivos de registro, sin afectar a las operaciones de la base de datos. Las bases de datos pueden seguir consultándose y actualizándose mientras se realiza la copia de seguridad. Esta copia de seguridad se denomina «copia de seguridad difusa» porque el proceso de recuperación debe ejecutarse como parte de la restauración para recuperar un conjunto coherente de bases de datos. Se admiten tanto la copia de seguridad por streaming como la copia instantánea.
La copia de seguridad en tiempo real es un método que copia todos los archivos de base de datos deseados y los archivos de registro necesarios durante el proceso. Las copias de archivos se pueden guardar directamente en cinta o en cualquier otro dispositivo de almacenamiento. No se requiere ninguna interrupción de la actividad con las copias de seguridad en tiempo real. Tanto la base de datos como los archivos de registro se someten a una suma de comprobación para garantizar que no existan errores de datos durante el proceso. Las copias de seguridad en tiempo real también pueden ser incrementales. En las copias de seguridad incrementales, solo se copian los archivos de registro, que se pueden restaurar junto con una copia de seguridad completa anterior para que todas las bases de datos recuperen su estado actual.
Las copias de seguridad instantáneas son un nuevo método de copia de seguridad de alta velocidad. Son mucho más rápidas porque la copia se crea virtualmente tras un breve periodo de inactividad de la aplicación. A medida que se actualizan los datos, la copia virtual se materializa. En algunos casos, la compatibilidad del hardware con las copias de seguridad instantáneas hace innecesario guardar las copias virtuales. Las copias de seguridad instantáneas siempre son copias de seguridad completas.
La función de restauración permite aplicar una copia de seguridad individual o una combinación de una copia de seguridad completa con una o más copias de seguridad incrementales. Además, se pueden reproducir los archivos de registro existentes para recrear un conjunto de datos completo hasta la última transacción registrada como confirmada en el nivel de transacción 0. La restauración de una copia de seguridad se puede realizar en cualquier sistema compatible con la aplicación original. No es necesario que sea la misma máquina ni que tenga la misma configuración. La ubicación de los archivos se puede modificar durante el proceso de restauración.
Copia de seguridad y restauración en hardware diferente
Cuando se crea una base de datos ESENT, el tamaño del sector del disco físico se almacena junto con la base de datos. Se espera que el tamaño del sector físico se mantenga constante entre sesiones; de lo contrario, se notifica un error. Cuando se clona una unidad física o se restaura desde una imagen de unidad a una unidad que utiliza un tamaño de sector físico diferente ( unidades de formato avanzado ), ESENT notificará errores. [ 4 ]
Este es un problema conocido y Microsoft tiene parches disponibles. Para Windows Vista o Windows Server 2008, consulte KB2470478. [ 5 ] Para Windows 7 o Windows Server 2008 R2, consulte KB982018. [ 6 ]
Historia
JET Blue fue desarrollado originalmente por Microsoft como una posible actualización del motor de base de datos JET Red en Microsoft Access , pero nunca se utilizó para este propósito. En cambio, pasó a ser utilizado por Exchange Server, Active Directory, el Servicio de replicación de archivos (FRS), el Editor de configuración de seguridad, los Servicios de certificados, el Servicio de nombres de Internet de Windows (WINS) y una gran cantidad de otros servicios, aplicaciones y componentes de Windows de Microsoft. [ 7 ] Durante años, fue una API privada utilizada solo por Microsoft, pero desde entonces se ha convertido en una API pública que cualquiera puede usar.
El desarrollo del Motor de Acceso a Datos (DAE) comenzó en marzo de 1989, cuando Allen Reiter se unió a Microsoft. Durante el año siguiente, un equipo de cuatro desarrolladores trabajó para Allen, completando en gran medida el ISAM. Microsoft ya contaba con el ISAM BC7 (JET Red), pero inició el proyecto del Motor de Acceso a Datos (DAE) para crear un motor de base de datos más robusto, como una incursión en la entonces nueva arquitectura cliente-servidor. En la primavera de 1990, los equipos de BC7 ISAM y DAE se unieron para formar el proyecto Joint Engine Technology (JET), responsable de producir dos motores: una versión 1 ( JET Red ) y una versión 2 (JET Blue), que cumplirían con la misma especificación de API (JET API). El DAE pasó a llamarse JET Blue por el color de la bandera de Israel, mientras que el BC7 ISAM pasó a llamarse JET Red por el color de la bandera de Rusia. Si bien JET Blue y JET Red se desarrollaron según la misma especificación de API, no compartían ningún código ISAM. Ambos admitían un procesador de consultas común, QJET, que posteriormente, junto con el BC7 ISAM, se convirtió en sinónimo de JET Red.
JET Blue se lanzó por primera vez en 1994 como ISAM para WINS, DHCP y los servicios RPL ( ahora desaparecidos ) en Windows NT 3.5. En 1996, se lanzó nuevamente como motor de almacenamiento para Microsoft Exchange. Otros servicios de Windows eligieron JET Blue como su tecnología de almacenamiento y, para el año 2000, todas las versiones de Windows comenzaron a incluirlo. Active Directory utilizó JET Blue, que pasó a formar parte de un conjunto especial de código de Windows llamado Trusted Computing Base (TCB). El número de aplicaciones de Microsoft que utilizan JET Blue sigue creciendo, y la API de JET Blue se publicó en 2005 para facilitar su uso por parte de un número cada vez mayor de aplicaciones y servicios, tanto dentro como fuera de Windows.
Una entrada del blog web de Microsoft Exchange [ 8 ] afirmó que entre los desarrolladores que han contribuido a JET Blue se encuentran Cheen Liao, Stephen Hecht, Matthew Bellew, Ian Jose, Edward "Eddie" Gilbert, Kenneth Kin Lum, Balasubramanian Sriram, Jonathan Liem, Andrew Goodsell, Laurion Burchall, Andrei Marinescu, Adam Foxman, Ivan Trindev, Spencer Low y Brett Shirley.
En enero de 2021, Microsoft liberó el código fuente de ESE. [ 9 ] Se publicó en GitHub con la permisiva licencia MIT .
Comparación con JET Red
Si bien comparten un linaje común, existen grandes diferencias entre JET Red y ESE.
- JET Red es una tecnología para compartir archivos, mientras que ESE está diseñada para integrarse en una aplicación de servidor y no comparte archivos.
- JET Red realiza la recuperación de archivos en el mejor esfuerzo posible, mientras que ESE cuenta con registro de escritura anticipada y aislamiento de instantáneas para una recuperación garantizada tras un fallo.
- JET Red, en versiones anteriores a la 4.0, solo admite el bloqueo a nivel de página, mientras que ESE y JET Red versión 4.0 admiten el bloqueo a nivel de registro.
- JET Red admite una amplia variedad de interfaces de consulta, incluidas ODBC y OLE DB . ESE no incluye un motor de consultas, sino que depende de que las aplicaciones escriban sus propias consultas como código C ISAM.
- JET Red tiene un tamaño máximo de archivo de base de datos de 2 GiB , mientras que ESE tiene un tamaño máximo de archivo de base de datos de 8 TiB con páginas de 4 KiB , y de 16 TiB con páginas de 8 KiB.
Referencias
- ↑ En este contexto, 1 KB = 1024 B
- ↑ "Arquitectura de motor de almacenamiento extensible" . TechNet . Consultado el 18 de junio de 2007 .
- ↑ En este contexto, 1 TB = 1024 4 B
- ↑ " Productos de Acronis: Las aplicaciones basadas en ESENT que se ejecutan en Windows Vista, Windows Server 2008 y Windows 7 pueden no funcionar correctamente después de restaurar o clonar en una unidad con sectores físicos diferentes | Base de conocimientos" . kb.acronis.com
- ↑ "Las aplicaciones creadas con ESENT que se ejecutan en un equipo con Windows Vista o Windows Server 2008 podrían no funcionar correctamente después de que cambie el tamaño del sector físico del dispositivo de almacenamiento" . Archivado del original el 28 de febrero de 2015. Consultado el 19 de noviembre de 2014 .
- ↑ "Hay disponible una actualización que mejora la compatibilidad de Windows 7 y Windows Server 2008 R2 con discos de formato avanzado " . support.microsoft.com
- ↑ "Motor de almacenamiento extensible" . Microsoft .
- ↑ "Motor de almacenamiento extensible" . Consultado el 19 de diciembre de 2008 .
- ↑ "Microsoft publica como código abierto ESE, el motor de almacenamiento extensible" . 3 de febrero de 2021. Consultado el 5 de febrero de 2021 .
- "Terminología de intercambio" . Archivado del original el 9 de noviembre de 2008. Consultado el 20 de agosto de 2015 .
- "Conceptos básicos para comprender el almacenamiento de información" . Archivado del original el 9 de junio de 2007. Consultado el 18 de junio de 2007 .
Enlaces externos
- Sitio web oficial
- Motor de almacenamiento extensible en GitHub
- Motor de almacenamiento extensible - CodeProject
- Motores de bases de datos
- Software anteriormente propietario
- Interfaces de programación de aplicaciones de Microsoft
- Software de base de datos de Microsoft
- Software gratuito de Microsoft
- Software que utiliza la licencia MIT.