Todos los productos
Search
Centro de documentos

PolarDB:Online partition maintenance

Última actualización: Sep 05, 2026

Las tablas de series temporales, como los registros, las órdenes y los datos históricos, crecen por un extremo y caducan por el otro. Por ello, requieren operaciones frecuentes de incorporación y eliminación de particiones (roll-in y roll-out). En MySQL estándar, cada operación DDL sobre una partición bloquea todo el tráfico DML hasta que finaliza o se cancela. Esta situación obliga a programar el mantenimiento fuera del horario de mayor actividad y aceptar periodos sin rendimiento.

El mantenimiento de particiones en línea resuelve este problema al sustituir los bloqueos de metadatos (MDL) a nivel de tabla por MDL a nivel de partición. Cuando una operación DDL afecta a una partición específica, PolarDB for MySQL adquiere un MDL únicamente sobre esa partición. Las demás particiones siguen disponibles para las operaciones concurrentes de lenguaje de manipulación de datos (DML). Esto elimina la ventana de bloqueo de DML y permite ejecutar el mantenimiento de particiones en cualquier momento.

A continuación se muestra cómo esta función reduce la contención de bloqueos durante las operaciones concurrentes de lenguaje de definición de datos (DDL) y DML.

Partition locking

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

Habilite el MDL a nivel de partición

Establezca partition_level_mdl_enabled en ON para habilitar el MDL a nivel de partición. Este parámetro controla la granularidad del bloqueo: en lugar de bloquear toda la tabla durante una operación DDL, PolarDB for MySQL bloquea solo la partición afectada.

Parámetro

Nivel

Descripción

partition_level_mdl_enabled

Global

Habilita el MDL a nivel de partición. Valores válidos: ON (habilitado), OFF (deshabilitado).

Nota

Reinicie el clúster después de modificar este parámetro para que el cambio surta efecto.

Operaciones compatibles

El mantenimiento de particiones en línea aplica a las siguientes operaciones DDL. La operación ADD PARTITION es compatible con tablas particionadas por RANGE y LIST. La compatibilidad con otras operaciones DDL y tipos de partición estará disponible en una versión futura.

Operación

Descripción

ADD PARTITION

Agrega una nueva partición (solo particionamiento RANGE y LIST)

DROP PARTITION

Elimina una partición existente

EXCHANGE PARTITION

Intercambia datos entre una partición y una tabla no particionada

REBUILD PARTITION

Reconstruye una partición en su lugar

REORGANIZE PARTITION

Divide o fusiona particiones existentes

Limitaciones

Si el nivel de aislamiento está configurado en REPEATABLE-READ o superior y se ejecutan operaciones DDL de forma concurrente, puede aparecer el siguiente error:

ERROR HY000: Table definition has changed, please retry transaction

Este comportamiento es normal. El error ocurre porque una instrucción DML accedió a una partición que una operación DDL concurrente acaba de crear. Vuelva a intentar la transacción para resolverlo.

Nota

El nivel de aislamiento también se puede configurar a nivel de sesión, no solo de forma global.

Ejemplo de uso

En el siguiente ejemplo se usan dos clientes concurrentes para demostrar cómo el mantenimiento de particiones en línea permite que las operaciones DML y DDL coexistan.

-- Client 1: View the current table structure
SHOW CREATE TABLE tr\G
*************************** 1. row ***************************
       Table: tr
Create Table: CREATE TABLE `tr` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `purchased` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY RANGE (year(`purchased`))
(PARTITION p0 VALUES LESS THAN (1990) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (2000) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB,
 PARTITION p4 VALUES LESS THAN (2010) ENGINE = InnoDB,
 PARTITION p5 VALUES LESS THAN (2015) ENGINE = InnoDB) */
1 row in set (0.00 sec)

-- Client 1: Start a transaction and query data
BEGIN;
Query OK, 0 rows affected (0.01 sec)

SELECT * FROM tr WHERE purchased >= '2010-01-01';
+------+----------------+------------+
| id   | name           | purchased  |
+------+----------------+------------+
|    5 | exercise bike  | 2014-05-09 |
|    7 | espresso maker | 2011-11-22 |
+------+----------------+------------+
2 rows in set (0.01 sec)

-- Client 2: While client 1's transaction is open, add a new partition and insert data
ALTER TABLE tr ADD PARTITION (PARTITION p6 VALUES LESS THAN (2020));
INSERT INTO tr VALUES (11, 'hope', '2017-11-04'), (12, 'carmen', '2018-06-08');

-- Client 1: Query again in the same transaction — the new partition's data is visible
SELECT * FROM tr WHERE purchased >= '2010-01-01';
+------+----------------+------------+
| id   | name           | purchased  |
+------+----------------+------------+
|    5 | exercise bike  | 2014-05-09 |
|    7 | espresso maker | 2011-11-22 |
|   11 | hope           | 2017-11-04 |
|   12 | carmen         | 2018-06-08 |
+------+----------------+------------+
4 rows in set (0.00 sec)

-- Client 2: Drop an old partition while client 1's transaction is still open
ALTER TABLE tr DROP PARTITION p0;

-- Client 1: Confirm the table structure reflects both changes — p6 added, p0 dropped
SHOW CREATE TABLE tr\G
*************************** 1. row ***************************
       Table: tr
Create Table: CREATE TABLE `tr` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `purchased` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY RANGE (year(`purchased`))
(PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (2000) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB,
 PARTITION p4 VALUES LESS THAN (2010) ENGINE = InnoDB,
 PARTITION p5 VALUES LESS THAN (2015) ENGINE = InnoDB,
 PARTITION p6 VALUES LESS THAN (2020) ENGINE = InnoDB) */
1 row in set (0.00 sec)

-- Client 1: Commit the transaction
COMMIT;

Comparación de rendimiento

Los dos escenarios a continuación comparan el rendimiento de DML con y sin el mantenimiento de particiones en línea.

Escenario 1: DDL bloqueado por una transacción prolongada

En MySQL estándar, cuando una operación DDL no puede avanzar porque una transacción abierta mantiene un bloqueo, dicha operación bloquea todas las operaciones DML posteriores. Esto provoca que el rendimiento caiga a cero hasta que se cancele la operación DDL o se confirme la transacción.

Con el mantenimiento de particiones en línea habilitado:

  • El rendimiento normal es idéntico al que se obtiene con la función deshabilitada, ya que habilitarla no genera sobrecarga.

  • Las transacciones prolongadas ya no bloquean las operaciones DDL sobre particiones. El tráfico DML se mantiene estable en todo momento.

Blocked DDL operations by long-running transactions

Escenario 2: Operaciones DDL que consumen mucho tiempo

Cuando una operación DDL es lenta (por ejemplo, al reconstruir una partición grande), puede causar variaciones severas en el rendimiento de DML, incluso si no hay ninguna transacción que genere bloqueos.

Con el mantenimiento de particiones en línea habilitado, las operaciones DDL que consumen mucho tiempo tienen poco impacto en el rendimiento de DML.

Time-consuming DDL operations

Consulte el estado del MDL

Mientras se ejecuta una operación DDL, consulte performance_schema.metadata_locks para ver el estado del bloqueo a nivel de partición.

El siguiente ejemplo muestra la tabla de bloqueos cuando el cliente 1 mantiene un bloqueo de lectura en la partición p5 y el cliente 2 intenta eliminarla.

-- Client 1: Start a transaction and query partition p5
BEGIN;
SELECT * FROM tr WHERE purchased >= '2010-01-01';
+------+----------------+------------+
| id   | name           | purchased  |
+------+----------------+------------+
|    5 | exercise bike  | 2014-05-09 |
|    7 | espresso maker | 2011-11-22 |
+------+----------------+------------+
2 rows in set (0.01 sec)

-- Client 1: Check the lock table
SELECT * FROM performance_schema.metadata_locks;
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+
| OBJECT_TYPE | OBJECT_SCHEMA      | OBJECT_NAME    | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE           | LOCK_DURATION | LOCK_STATUS | SOURCE            | OWNER_THREAD_ID | OWNER_EVENT_ID |
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+
| TABLE       | test               | tr             | NULL        |       140734887898944 | SHARED_READ         | TRANSACTION   | GRANTED     | sql_parse.cc:6759 |              67 |             17 |
| PARTITION   | test               | tr             | p5          |       140734887896704 | SHARED_READ         | TRANSACTION   | GRANTED     | sql_parse.cc:6502 |              67 |             17 |
| TABLE       | performance_schema | metadata_locks | NULL        |       140734879511488 | SHARED_READ         | TRANSACTION   | GRANTED     | sql_parse.cc:6759 |              68 |              4 |
| SCHEMA      | performance_schema | NULL           | NULL        |       140734879511648 | INTENTION_EXCLUSIVE | TRANSACTION   | GRANTED     | dd_schema.cc:108  |              68 |              4 |
+-------------+--------------------+----------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+
4 rows in set (0.02 sec)

La salida muestra dos bloqueos mantenidos por el hilo 67 (cliente 1): un bloqueo SHARED_READ a nivel de tabla sobre tr y un bloqueo SHARED_READ a nivel de partición sobre p5 (después de la poda de particiones). La columna OWNER_THREAD_ID identifica qué hilo mantiene el bloqueo.

-- Client 2: Attempt to drop partition p5 — this enters a waiting state
--   because client 1 still holds a SHARED_READ lock on p5
ALTER TABLE tr DROP PARTITION p5;

-- Confirm the DDL is waiting for the partition-level MDL
SHOW PROCESSLIST;
+----+-----------------+-----------+------+---------+------+-------------------------------------+----------------------------------+
| Id | User            | Host      | db   | Command | Time | State                               | Info                             |
+----+-----------------+-----------+------+---------+------+-------------------------------------+----------------------------------+
|  4 | event_scheduler | localhost | NULL | Daemon  | 1550 | Waiting on empty queue              | NULL                             |
|  8 | root            | localhost | test | Sleep   |  426 |                                     | NULL                             |
|  9 | root            | localhost | NULL | Query   |    0 | starting                            | SHOW PROCESSLIST                 |
| 10 | root            | localhost | test | Query   |   10 | Waiting for partition metadata lock | ALTER TABLE tr DROP PARTITION p5 |
+----+-----------------+-----------+------+---------+------+-------------------------------------+----------------------------------+
4 rows in set (0.00 sec)

La columna State muestra Waiting for partition metadata lock cuando una operación DDL queda en cola detrás de un bloqueo a nivel de partición. Para desbloquear la operación DDL, confirme o revierta la transacción en la sesión que genera el bloqueo. Identifique dicha sesión mediante el valor OWNER_THREAD_ID obtenido en la consulta a metadata_locks y luego confirme o revierta la transacción de esa sesión.

-- The DROP PARTITION on client 2 proceeds automatically after client 1 commits

Seguimiento de las operaciones de mantenimiento de particiones en línea

Use la variable de estado Online_altered_partition para consultar cuántas operaciones de mantenimiento de particiones en línea se han ejecutado.

SHOW STATUS LIKE 'Online_altered_partition';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| Online_altered_partition | 2565  |
+--------------------------+-------+
1 row in set (0.00 sec)

Video de la operación

Demostración: bloqueo de metadatos (MDL) a nivel de partición en PolarDB for MySQL