Saltar al contenido

El espacio en disco

De la base de datos al bloque: tablespaces, segmentos, extensiones y su correspondencia con los ficheros físicos; cómo se crea un tablespace; qué ficheros usa cada producto; qué es un motor de almacenamiento; y cuándo hay que particionar una tabla.

De la base de datos al bloque

Entre la base de datos y el disco hay una escalera de unidades lógicas que el administrador maneja a diario. La idea de fondo es que el gestor no quiere depender de dónde caiga cada byte: reserva espacio en piezas grandes y luego lo reparte por dentro. Esta es la escalera, de mayor a menor, con la nomenclatura de Oracle, que es la que se pregunta.

Nivel lógicoQué agrupa
Base de datosTodo el conjunto. Se apoya en uno o varios tablespaces.
TablespaceAgrupa objetos. Es la unidad con la que el administrador asigna espacio, y puede repartirse entre uno o varios ficheros de datos.
SegmentoUn objeto concreto que ocupa espacio: una tabla, un índice, el área de deshacer, un objeto grande de tipo LOB.
ExtensiónUn trozo de espacio contiguo dentro del fichero. Los segmentos crecen añadiendo extensiones, igual que un volumen lógico crece añadiendo extensiones en LVM.
BloqueLa unidad mínima de lectura y escritura del gestor. Cada extensión contiene uno o varios bloques lógicos.

Enfrente de esa escalera lógica está la física, que es mucho más corta: ficheros de datos y bloques del sistema operativo. La correspondencia entre las dos no es de uno a uno, y ahí está lo que se pregunta. Un tablespace puede guardarse en un fichero o repartirse entre varios; una misma tabla puede acabar con sus datos en varios ficheros; y cada bloque lógico del gestor se traduce a uno o varios bloques del sistema de ficheros según cómo esté configurado el tamaño de bloque. Esa indirección es justamente lo que permite mover, ampliar o reubicar el almacenamiento sin tocar las aplicaciones.

El aprovechamiento práctico es doble. Por un lado se puede decidir dónde vive cada objeto: al crear una tabla se indica a qué tablespace pertenece, y así se separan en discos distintos los datos, los índices y las áreas temporales. Por otro lado se puede crecer sin parar el servicio, añadiendo un fichero más al tablespace que se ha quedado corto.

Base de datos, tablespace, segmento, extensión y bloque, en ese orden. El tablespace es lógico; el fichero de datos es físico; y la relación entre ambos no tiene por qué ser de uno a uno.

De la base de datos al bloque

Base de datos

  • El conjunto completo de datos y metadatos

Tablespace

  • Unidad lógica de almacenamiento, apoyada en uno o varios ficheros de datos

Segmento

  • Todo el espacio de un objeto: una tabla, un índice

Extensión

  • Conjunto contiguo de bloques que se reserva de una vez

Bloque

  • La unidad mínima de lectura y escritura en disco

Para el examen

  • De arriba abajo: base de datos, tablespace, segmento, extensión y bloque

  • El bloque: la unidad mínima de entrada y salida

Crear un tablespace y dejarlo crecer

Crear un tablespace consiste en decirle al gestor qué fichero o ficheros va a usar, de qué tamaño arranca y qué hacer cuando se llene. Las tres decisiones son de administración pura y ninguna se puede tomar sin saber cómo va a crecer el dato.

sql
CREATE TABLESPACE ts_intentos
  DATAFILE '/u01/oradata/ts_intentos_01.dbf'
  SIZE 500M
  AUTOEXTEND ON NEXT 100M MAXSIZE 20G;
  • DATAFILE indica el fichero físico donde se guarda. Se puede repetir la cláusula, o añadir más ficheros después, para repartir el tablespace entre varios discos.
  • SIZE es el espacio que se reserva de entrada, aunque todavía esté vacío.
  • AUTOEXTEND ON deja que el fichero crezca solo cuando se agote, en incrementos de NEXT, hasta el tope de MAXSIZE. Sin autoextensión, el día que se llena la aplicación empieza a dar errores de escritura.
  • MAXSIZE existe para evitar el efecto contrario: que una carga descontrolada llene el sistema de ficheros entero y tire abajo la máquina, no solo la base.

Después, al crear una tabla, se puede indicar en qué tablespace debe vivir y con qué parámetros de crecimiento arranca su segmento. Es la forma de separar en almacenamientos distintos lo que se lee mucho de lo que se escribe mucho.

sql
CREATE TABLE intento (
  id            NUMBER,
  alumno_id     NUMBER,
  tema_id       NUMBER,
  aciertos      NUMBER,
  realizado_el  TIMESTAMP
)
TABLESPACE ts_intentos
STORAGE (INITIAL 64K NEXT 128K MAXEXTENTS 200);

Una instalación de Oracle no arranca vacía de tablespaces. Los que crea de serie son SYSTEM, que guarda el diccionario de datos y es el corazón del producto; SYSAUX, auxiliar del anterior, donde van los componentes que antes se metían en SYSTEM; USERS, que es el destino por defecto de los objetos de los usuarios; TEMP, para las operaciones temporales como las ordenaciones grandes; y UNDOTBS1, para la información de deshacer que permite anular una transacción. Ojo con el nombre: es USERS, en plural.

Sin AUTOEXTEND, el tablespace lleno detiene las escrituras. Sin MAXSIZE, el fichero lleno se lleva por delante el sistema de ficheros completo.

Para el examen

  • Qué es un tablespace: una unidad lógica apoyada en uno o varios ficheros de datos físicos

  • AUTOEXTEND: hace que crezca solo

  • Recomendación: acompañarlo siempre de MAXSIZE

Qué ficheros usa cada producto

Cada gestor reparte sus datos en un juego de ficheros distinto. Reconocer las extensiones es útil en el examen y es imprescindible en la práctica, porque una copia física consiste precisamente en llevarse esos ficheros y hay que saber cuáles no se pueden olvidar.

GestorFicheros característicos
OracleFicheros de datos (.dbf) agrupados en tablespaces, ficheros de rehacer y ficheros de control.
SQL ServerFichero primario .mdf, ficheros secundarios .ndf (opcionales) y registro de transacciones .ldf.
MySQL y MariaDBCon MyISAM, .myd para los datos y .myi para los índices. El antiguo .frm guardaba la definición de la tabla.
PostgreSQLUn directorio de datos con los ficheros de cada objeto, más el registro de escritura anticipada (WAL).

Con los .frm hay que tener cuidado si la pregunta viene de un temario antiguo. Guardaban la estructura de la tabla y desaparecieron en MySQL 8.0, donde el diccionario de datos pasó a estar dentro del propio InnoDB, en tablas del sistema y no en ficheros sueltos. Los .myd y .myi siguen existiendo porque son propios de MyISAM.

En SQL Server, la separación entre .mdf y .ldf es la misma idea de reparto de papeles que ya se ha visto en Oracle: los datos por un lado y el registro de transacciones por otro. Lo importante para administrar es que el .ldf no es prescindible: es el fichero que permite deshacer, rehacer y recuperar a un instante concreto, y es también el que crece sin control si nunca se hace una copia del registro.

Para el examen

  • Ficheros de Oracle: de datos, de control y redo logs

  • Redo logs: registran los cambios

  • Para qué sirven: recuperar hasta el instante del fallo

Los motores de almacenamiento de MySQL y MariaDB

MySQL y MariaDB tienen una particularidad que ningún otro gestor grande comparte: la parte que guarda y recupera las filas del disco es reemplazable, y se elige tabla por tabla. Esa pieza se llama motor de almacenamiento, y de ella dependen cosas tan gordas como si la tabla admite transacciones o si respeta las claves ajenas. Dos tablas de la misma base pueden tener motores distintos.

MotorQué ofreceQué no ofrece
InnoDBTransacciones y propiedades ACID, claves ajenas, bloqueo a nivel de fila. Es el motor por defecto y el que hay que usar salvo razón muy concreta.Nada relevante para el uso general.
MyISAMLectura muy veloz, tanto por índice como en recorrido secuencial, con índices compactos.No es transaccional, no garantiza ACID y no admite claves ajenas. Sus tablas son susceptibles de corromperse y hay que repararlas a mano.
NDB ClusterReparto de los datos entre varios nodos, con transacciones distribuidas. Es el motor de MySQL Cluster.Simplicidad: exige una arquitectura de nodos de datos y nodos SQL.
MemoryVelocidad máxima, porque la tabla vive en memoria.Persistencia: al parar el servidor se pierde el contenido.

El motor se fija al crear la tabla y se puede cambiar después, lo que en la práctica implica reescribirla entera. En MariaDB aparecen además dos nombres derivados: Aria, que es su relevo de MyISAM y el motor de sus tablas internas, y XtraDB, una variante de InnoDB desarrollada por Percona que fue el motor por defecto de MariaDB solo hasta la versión 10.1; desde la 10.2 MariaDB volvió a InnoDB. Otros motores que aparecen en las listas son Spider, ColumnStore y CSV.

sql
CREATE TABLE pregunta_fallada (
  alumno_id  INT,
  pregunta_id INT,
  fallada_el DATETIME
) ENGINE = InnoDB;

ALTER TABLE pregunta_fallada ENGINE = InnoDB;

Una advertencia sobre un argumento que circula en los temarios antiguos: se decía que MyISAM era la única opción si hacía falta búsqueda de texto completo. Dejó de ser cierto en MySQL 5.6, cuando InnoDB incorporó los índices FULLTEXT. Hoy la elección de MyISAM se sostiene poco: se paga con la pérdida de transacciones, de integridad referencial y de resistencia a un apagón.

InnoDB es transaccional y respeta las claves ajenas; MyISAM no hace ninguna de las dos cosas. Si la pregunta menciona ACID o FOREIGN KEY, la respuesta es InnoDB.

Para el examen

  • InnoDB: transaccional, con claves ajenas y bloqueo por fila

  • MyISAM: sin transacciones y con bloqueo de tabla entera

  • Motor por defecto: InnoDB

Particionar una tabla que crece sin freno

Cuando una tabla se hace tan grande que cualquier operación sobre ella se vuelve inviable, la salida no es partirla en varias tablas sino particionarla: sigue siendo una sola tabla para quien la consulta, pero por dentro el gestor la guarda en trozos separados. Cada partición se puede colocar en un tablespace distinto, copiar por separado y, sobre todo, descartar entera sin recorrerla.

El criterio más frecuente es el rango, casi siempre por fecha, porque coincide con cómo se consulta y con cómo se archiva el dato histórico. En PostgreSQL se declara la tabla como particionada y después se crean las particiones como tablas hijas con su rango de valores.

sql
CREATE TABLE intento (
  id           bigint,
  alumno_id    bigint,
  realizado_el date NOT NULL
) PARTITION BY RANGE (realizado_el);

CREATE TABLE intento_2026 PARTITION OF intento
  FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');

La ganancia de administración es doble. Al consultar por fecha, el gestor descarta de golpe las particiones que no pueden contener la respuesta y solo recorre la que toca. Y al llegar el momento de purgar el histórico, se elimina la partición completa en una operación instantánea, en vez de lanzar un borrado masivo que llenaría el registro de transacciones.

PostgreSQL trae además la herencia de tablas, que permite que una tabla reciba las columnas de otra y que fue el mecanismo con el que se hacía el particionamiento antes de que existiera la sintaxis declarativa. Sigue en el producto y se usa para modelar jerarquías.

sql
CREATE TABLE alumno (...) INHERITS (persona);

Conviene no confundir particionar con fragmentar entre máquinas. Particionar reparte los datos dentro de un mismo gestor y un mismo servicio; el reparto entre nodos de un clúster, que en el mundo NoSQL se llama sharding, es otra cosa y se estudia en el tema de bases de datos no relacionales.

Para el examen

  • Criterios de partición: por rango, por lista o por hash

  • Qué se gana: consultas que descartan particiones enteras y borrados por bloque