Todos os produtos
Search
Central de documentação

PolarDB:Manutenção de partições online

Última atualização: Jun 28, 2026

Tabelas de séries temporais — como logs, pedidos e registros históricos — crescem em uma extremidade e têm dados antigos removidos na outra. Esse ciclo exige operações frequentes de adição e remoção de partições. No MySQL padrão, qualquer operação DDL em partições bloqueia todo o tráfego DML até a conclusão ou o cancelamento do DDL. Isso obriga você a agendar manutenções fora do horário de pico e a aceitar períodos com throughput zero.

A manutenção de partições online resolve esse problema substituindo os bloqueios de metadados (MDLs) no nível da tabela por MDLs no nível da partição. Quando uma operação DDL tem como alvo uma partição específica, o PolarDB for MySQL adquire um MDL apenas nessa partição. As demais partições continuam acessíveis para operações simultâneas de linguagem de manipulação de dados (DML). Essa abordagem elimina a janela de indisponibilidade para DML e permite executar a manutenção de partições a qualquer momento.

A figura a seguir ilustra como o recurso reduz a contenção de bloqueios durante operações simultâneas de linguagem de definição de dados (DDL) e DML.

Partition locking

Pré-requisitos

Antes de começar, verifique se você possui:

Ativar MDL no nível de partição

Defina partition_level_mdl_enabled como ON para ativar o MDL no nível de partição. Esse parâmetro controla a granularidade do bloqueio: em vez de bloquear toda a tabela durante uma operação DDL, o PolarDB for MySQL bloqueia apenas a partição afetada.

Parâmetro

Nível

Descrição

partition_level_mdl_enabled

Global

Ativa o MDL no nível de partição. Valores válidos: ON (ativado), OFF (desativado).

Nota

Reinicie o cluster após alterar este parâmetro para que a mudança tenha efeito.

Operações suportadas

A manutenção de partições online aplica-se às seguintes operações DDL. A operação ADD PARTITION é compatível com tabelas particionadas por RANGE e LIST. O suporte a operações DDL adicionais e outros tipos de particionamento estará disponível em uma versão futura.

Operação

Descrição

ADD PARTITION

Adiciona uma nova partição (apenas particionamento RANGE e LIST)

DROP PARTITION

Remove uma partição existente

EXCHANGE PARTITION

Troca dados entre uma partição e uma tabela não particionada

REBUILD PARTITION

Reconstrói uma partição localmente

REORGANIZE PARTITION

Divide ou mescla partições existentes

Limitações

Se o nível de isolamento estiver definido como REPEATABLE-READ ou superior e houver operações DDL simultâneas, o seguinte erro poderá ocorrer:

ERROR HY000: Table definition has changed, please retry transaction

Esse comportamento é esperado. O erro ocorre porque uma instrução DML acessou uma partição recém-criada por uma operação DDL simultânea. Tente novamente a transação para resolver o problema.

Nota

O nível de isolamento também pode ser definido no nível da sessão, não apenas globalmente.

Exemplo de uso

O exemplo a seguir utiliza dois clientes simultâneos para demonstrar como a manutenção de partições online permite a coexistência de operações DML e DDL.

-- 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;

Comparação de desempenho

Os dois cenários a seguir comparam o throughput de DML com e sem a manutenção de partições online.

Cenário 1: DDL bloqueado por uma transação longa

No MySQL padrão, quando uma operação DDL não consegue prosseguir porque uma transação aberta detém um bloqueio, essa operação DDL bloqueia todas as operações DML subsequentes. Como resultado, o throughput cai para zero até o cancelamento do DDL ou a confirmação da transação.

Com a manutenção de partições online ativada:

  • O throughput normal permanece idêntico ao observado quando o recurso está desativado — sua ativação não gera sobrecarga.

  • Transações longas deixam de bloquear operações DDL em partições. O tráfego DML mantém-se estável durante todo o processo.

Blocked DDL operations by long-running transactions

Cenário 2: Operações DDL demoradas

Quando uma operação DDL é lenta (por exemplo, ao reconstruir uma partição grande), ela pode causar oscilações severas no throughput de DML, mesmo sem nenhuma transação bloqueante envolvida.

Com a manutenção de partições online ativada, operações DDL demoradas têm pouco impacto no throughput de DML.

Time-consuming DDL operations

Visualize status do MDL

Durante a execução de uma operação DDL, consulte performance_schema.metadata_locks para verificar o estado dos bloqueios no nível de partição.

O exemplo a seguir mostra a tabela de bloqueios quando o cliente 1 detém um bloqueio de leitura na partição p5 e o cliente 2 tenta remover essa partição.

-- 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)

A saída exibe dois bloqueios mantidos pela thread 67 (cliente 1): um bloqueio SHARED_READ no nível da tabela em tr e um bloqueio SHARED_READ no nível da partição em p5 (após a eliminação de partições). A coluna OWNER_THREAD_ID identifica qual thread detém o bloqueio.

-- 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)

A coluna State exibe Waiting for partition metadata lock quando um DDL fica enfileirado atrás de um bloqueio no nível de partição. Para desbloquear o DDL, confirme ou reverta a transação na sessão bloqueante. Identifique a sessão bloqueante usando o OWNER_THREAD_ID obtido na consulta a metadata_locks e, em seguida, confirme ou reverta a transação dessa sessão.

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

Acompanhar operações de manutenção de partições online

Utilize a variável de status Online_altered_partition para verificar quantas operações de manutenção de partições online foram executadas.

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

Vídeo da operação

Demonstração — Bloqueio de metadados (MDL) no nível de partição do PolarDB for MySQL