Todos os produtos
Search
Central de documentação

PolarDB:Instruções DDL sem bloqueio

Última atualização: Jun 28, 2026

A instrução ALTER TABLE em uma tabela grande pode bloquear todas as novas transações por minutos ou horas. Quando uma instrução DDL de bloqueio mantém a fila de solicitações de bloqueio MDL-X aberta, cada transação que acessa essa tabela fica presa atrás dela — e se a fila crescer o suficiente, o esgotamento de conexões pode derrubar toda a sua aplicação. O DDL sem bloqueio elimina esse risco: a instrução DDL tenta adquirir o bloqueio em intervalos curtos, liberando sua posição na fila entre as tentativas para que as novas transações continuem em execução.

Como funciona

O sistema de bloqueio de metadados (MDL) do MySQL protege as tabelas durante as alterações de esquema. Uma instrução DDL de bloqueio solicita um bloqueio exclusivo MDL-X e mantém a fila de solicitações bloqueada até adquirir o bloqueio. Como o MDL-X tem a maior prioridade, cada nova transação que acessa a tabela fica presa atrás da instrução DDL — mesmo que o próprio DDL ainda esteja aguardando a conclusão de uma transação mais antiga.

O DDL sem bloqueio altera esse comportamento:

  1. A instrução DDL tenta adquirir o bloqueio MDL-X dentro de um tempo limite curto (loose_polar_nonblock_ddl_lock_wait_timeout, padrão: 1 segundo).

  2. Se o bloqueio não estiver disponível, a instrução DDL libera completamente sua posição na fila. Como a fila não está mais bloqueada, as transações pendentes e as novas podem adquirir seus próprios bloqueios e prosseguir normalmente.

  3. Após um intervalo configurável (loose_polar_nonblock_ddl_retry_interval, padrão: 6 segundos), a instrução DDL tenta novamente.

  4. Os passos 2–3 se repetem até loose_polar_nonblock_ddl_retry_times tentativas.

Durante os intervalos de nova tentativa, a tabela permanece totalmente acessível. As transações por segundo (TPS) podem cair brevemente quando o DDL adquire o bloqueio, mas nunca chegam a zero.

Nota

O DDL sem bloqueio tem prioridade inferior ao DDL de bloqueio e maior chance de falhar ao adquirir o bloqueio MDL-X. Use-o quando a continuidade do negócio for mais importante do que a velocidade da alteração de esquema.

Versões compatíveis

O DDL sem bloqueio requer um dos seguintes:

  • PolarDB for MySQL 8.0.1 na versão de revisão 8.0.1.1.29 ou posterior

  • PolarDB for MySQL 8.0.2 na versão de revisão 8.0.2.2.12 ou posterior

Para verificar a versão de revisão do seu cluster, consulte Versões do mecanismo 5.6, 5.7 e 8.0.

Instruções DDL compatíveis

As instruções que suportam o DDL sem bloqueio dependem da sua versão de revisão.

Versão de revisãoInstruções compatíveisObservações
8.0.1.1.29 ou posterior, ou 8.0.2.2.12ALTER TABLE apenasPara desfragmentar uma tabela InnoDB, use ALTER TABLE table_name ENGINE=InnoDB em vez de OPTIMIZE TABLE table_name
8.0.2.2.13 ou posteriorALTER TABLE, OPTIMIZE TABLE, TRUNCATE TABLE

Ativar o DDL sem bloqueio

Todos os quatro parâmetros são de nível de sessão. Defina-os na mesma sessão antes de executar a instrução DDL.

Passo 1: Ativar o modo DDL sem bloqueio

SET SESSION loose_polar_nonblock_ddl_mode = ON;

O parâmetro loose_polar_nonblock_ddl_mode está desativado (OFF) por padrão.

Passo 2: Configurar o comportamento de nova tentativa

SET SESSION loose_polar_nonblock_ddl_retry_times = 4194304;
SET SESSION loose_polar_nonblock_ddl_retry_interval = 6;
SET SESSION loose_polar_nonblock_ddl_lock_wait_timeout = 1;
ParâmetroPadrãoValores válidosUnidadeQuando alterar
loose_polar_nonblock_ddl_retry_times0 (derivado de lock_wait_timeout)0–31536000Defina como 4194304 para alterações de esquema de longa duração em tabelas grandes
loose_polar_nonblock_ddl_retry_interval61–31536000SegundosAumente para reduzir a contenção de bloqueio; diminua para concluir o DDL mais rapidamente
loose_polar_nonblock_ddl_lock_wait_timeout11–31536000SegundosAumente se o bloqueio não for adquirido com frequência suficiente sob uma carga pesada de escrita

Para mais informações sobre como aplicar esses parâmetros, consulte Configurar parâmetros de cluster e nó.

Passo 3: Executar a instrução DDL

ALTER TABLE table_name ADD INDEX index_name (column1, column2, column3);

A instrução é executada com comportamento sem bloqueio para a sessão atual. Outras sessões não são afetadas.

Teste de desempenho

Os testes a seguir comparam o DDL de bloqueio, o DDL sem bloqueio e a ferramenta de alteração de esquema online gh-ost usando o SysBench. Para mais informações sobre o SysBench, consulte Teste de desempenho OLTP.

Test environment: PolarDB for MySQL 8.0, Cluster Edition, 8 núcleos de CPU, 64 GB de memória.

Configuração

  1. Crie uma tabela com 1 milhão de linhas:

    ./oltp_read_write.lua --mysql-host="Cluster endpoint" --mysql-port="Port number" \
      --mysql-user="Username" --mysql-password="Password" \
      --mysql-db="sbtest" --tables=1 --table-size=1000000 \
      --report-interval=1 --percentile=99 --threads=8 --time=6000 prepare
  2. Simule uma carga de trabalho de leitura/gravação:

    ./oltp_read_write.lua --mysql-host="Cluster endpoint" --mysql-port="Port number" \
      --mysql-user="Username" --mysql-password="Password" \
      --mysql-db="sbtest" --tables=1 --table-size=1000000 \
      --report-interval=1 --percentile=99 --threads=8 --time=6000 run
  3. Mantenha um bloqueio MDL iniciando uma transação e deixando-a aberta:

    /* Session 1 */
    BEGIN;
    SELECT * FROM sbtest1;
  4. Em uma segunda sessão, adicione uma coluna à tabela:

    /* Session 2 */
    ALTER TABLE sbtest1 ADD COLUMN d INT;
  5. Repita a alteração de esquema usando gh-ost (requer log binário — consulte Ativar log binário):

    ./gh-ost --assume-rbr --user="Username" --password="Password" \
      --host="Cluster endpoint" --port="Port number" \
      --database="sbtest" --table="sbtest1" --alter="ADD COLUMN d INT" \
      --allow-on-master --aliyun-rds \
      --initially-drop-old-table --initially-drop-ghost-table --execute

Impacto no TPS

  • DDL de bloqueio (DDL sem bloqueio desativado) — O TPS cai a zero e permanece assim até que o DDL seja concluído. Disable nonblocking DDL statements

  • DDL sem bloqueio — O TPS cai periodicamente quando o DDL tenta novamente o bloqueio, mas nunca chega a zero. O impacto nos negócios é mínimo. Enable nonblocking DDL statements

  • gh-ost — O TPS cai a zero em picos periódicos. O gh-ost funciona criando uma tabela ghost, aplicando as alterações nela e, em seguida, renomeando atomicamente a tabela ghost no lugar (a etapa de corte). Esse corte requer um breve bloqueio de tabela, que causa as quedas periódicas de TPS. Use gh-ost to modify the table schema

Comparação de velocidade em 100 milhões de linhas

Colunas foram adicionadas a uma tabela com 100 milhões de linhas usando DDL sem bloqueio (algoritmos INSTANT, INPLACE e COPY) e gh-ost.

  • Sem carga de trabalho — O DDL sem bloqueio é concluído mais rapidamente que o gh-ost. Load-free

  • Carga de trabalho de leitura/gravação — O DDL sem bloqueio ainda é concluído mais rapidamente que o gh-ost. read_write.

O DDL sem bloqueio mantém o TPS acima de zero durante toda a alteração de esquema e é concluído mais rapidamente que o gh-ost, tanto em ambientes sem carga quanto em cargas similares às de produção.

Tópicos relacionados

Se você tiver dúvidas sobre operações DDL, entre em contato conosco.