Por que meus “bytes de volume usados” sempre aumentam no meu cluster Amazon Aurora?

10

Eu tenho um cluster Aurora DB da Amazon (AWS) e todos os dias [Billed] Volume Bytes Usedestá aumentando.

Métrica VolumeBytesUsada do CloudWatch ao longo do tempo

Eu verifiquei o tamanho de todas as minhas tabelas (em todos os meus bancos de dados nesse cluster) usando a INFORMATION_SCHEMA.TABLEStabela:

SELECT ROUND(SUM(data_length)/1024/1024/1024) AS data_in_gb, ROUND(SUM(index_length)/1024/1024/1024) AS index_in_gb, ROUND(SUM(data_free)/1024/1024/1024) AS free_in_gb FROM INFORMATION_SCHEMA.TABLES;
+------------+-------------+------------+
| data_in_gb | index_in_gb | free_in_gb |
+------------+-------------+------------+
| 30         | 4           | 19         |
+------------+-------------+------------+

Total: 53GB

Então, por que eu estou sendo cobrado quase 75 GB no momento?

Entendo que o espaço provisionado nunca pode ser liberado, da mesma maneira que os arquivos ibdata em um servidor MySQL normal nunca podem diminuir; Eu estou bem com isso. Isso está documentado e aceitável.

Meu problema é que, todos os dias, o espaço cobrado aumenta. E tenho certeza de que NÃO estou usando 75 GB de espaço temporariamente. Se eu fizesse algo assim, eu entenderia. É como se o espaço de armazenamento que eu estou liberando, excluindo linhas das minhas tabelas, ou eliminando tabelas, ou mesmo eliminando bancos de dados, nunca fosse reutilizado.

Entrei em contato com o suporte da AWS (premium) várias vezes e nunca consegui obter uma boa explicação sobre o motivo.
Recebi sugestões para executar OPTIMIZE TABLEnas tabelas em que há muito free_space(por INFORMATION_SCHEMA.TABLEStabela) ou para verificar o comprimento do histórico do InnoDB, para garantir que os dados excluídos ainda não sejam mantidos no segmento de reversão (ref: MVCC ) e reinicie as instâncias para garantir que o segmento de reversão esteja vazio.
Nenhum deles ajudou.

Guillaume Boudreau
fonte

Respostas:

17

Há várias coisas em jogo aqui ...

  1. Cada tabela é armazenada em seu próprio espaço de tabela

    Por padrão, o grupo de parâmetros para os clusters Aurora (nomeado default.aurora5.6) define innodb_file_per_table = ON. Isso significa que cada tabela é armazenada em um arquivo separado, no cluster de armazenamento Aurora. Você pode ver qual espaço de tabela é usado para cada uma das suas tabelas usando esta consulta:

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    Nota: Não tentei mudar innodb_file_per_tablepara OFF. Talvez isso ajude ..?

  2. O espaço de armazenamento liberado pela exclusão de espaços de tabela NÃO é reutilizado

    Citando o suporte premium da AWS:

    Devido ao design exclusivo do mecanismo de armazenamento Aurora, para aumentar seu desempenho e tolerância a falhas, o Aurora não possui uma funcionalidade para desfragmentar os espaços de tabela arquivo por tabela da mesma maneira que o MySQL padrão.

    Atualmente, o Aurora infelizmente não tem como reduzir os espaços de tabela como o MySQL padrão e todo o espaço fragmentado é cobrado porque está incluído no VolumeBytesUsed.
    O motivo pelo qual o Aurora não pode recuperar o espaço de uma tabela descartada da mesma maneira que o MySQL padrão é que os dados da tabela são armazenados de maneira completamente diferente de um banco de dados MySQL padrão com um único volume de armazenamento.

    Se você soltar uma tabela ou linha no Aurora, o espaço não será recuperado no volume do cluster do Auroras devido a esse design complicado.
    Essa incapacidade de recuperar pequenas quantidades de espaço de armazenamento é um sacrifício feito para obter ganhos adicionais de desempenho do volume de armazenamento em cluster Auroras e a tolerância a falhas bastante aprimorada do Aurora.

    Mas há uma maneira obscura de reutilizar parte desse espaço desperdiçado ...
    Novamente, cite o suporte premium da AWS:

    Depois que o conjunto total de dados exceder um determinado tamanho (aproximadamente 160 GB), você poderá começar a recuperar espaço em blocos de 160 GB para reutilização, por exemplo, se você tiver 400 GB no volume do cluster Aurora e DROP 160 GB ou mais das tabelas, o Aurora poderá reutilize automaticamente 160 GB de dados. No entanto, pode demorar para recuperar esse espaço.
    A razão pela qual a grande quantidade de dados necessária para ser liberada de uma só vez se deve ao design exclusivo do Auroras como um mecanismo de banco de dados em escala corporativa, diferentemente do MySQL padrão, que não pode ser usado nessa escala.

  3. OPTIMIZE TABLE é mau!

    Como o Aurora é baseado no MySQL 5.6, OPTIMIZE TABLEé mapeado para ALTER TABLE ... FORCE, que reconstrói a tabela para atualizar estatísticas do índice e liberar espaço não utilizado no índice clusterizado. Efetivamente, junto com innodb_file_per_table = ONisso, significa executar um OPTIMIZE TABLEcria um novo arquivo de espaço de tabela e exclui o antigo. Como a exclusão de um arquivo de espaço de tabela não libera o armazenamento que estava usando, isso significa OPTIMIZE TABLEque sempre resultará em mais armazenamento sendo provisionado. Ai!

    Ref: https://dev.mysql.com/doc/refman/5.6/en/optimize-table.html#optimize-table-innodb-details

  4. Usando tabelas temporárias

    Por padrão, o grupo de parâmetros para as instâncias do Aurora (nomeadas default.aurora5.6) define default_tmp_storage_engine = InnoDB. Isso significa que toda vez que estou criando uma TEMPORARYtabela, ela é armazenada, juntamente com todas as minhas tabelas regulares , no cluster de armazenamento Aurora. Isso significa que novo espaço é provisionado para armazenar essas tabelas, aumentando assim o VolumeBytesUsed total.
    A solução para isso é bastante simples: altere o default_tmp_storage_enginevalor do parâmetro para MyISAM. Isso forçará o Aurora a criar as TEMPORARYtabelas no armazenamento local da instância.
    Nota: o armazenamento local das instâncias é limitado; veja a Free Local Storagemétrica no CloudWatch para ver quanto armazenamento suas instâncias têm. Instâncias maiores (mais caras) têm mais armazenamento local.

    Ref: nenhum ainda; a documentação atual do Amazon Aurora não menciona isso. Pedi à equipe de suporte da AWS para atualizar a documentação e atualizará minha resposta se / uma vez.

Guillaume Boudreau
fonte
1
Esta é uma ótima resposta e , uau , essas são algumas advertências importantes. Ainda bem que vi isso.
ceejayoz
Idem. Percebeu que um servidor de banco de dados tinha até 300 GB, para um banco de dados com tamanho relatado pelo MySQL de 54 GB ... se o espaço nunca for recuperado, esse é um bom exemplo do que acontece quando você tem muitas tabelas gravadas frequentemente ( por exemplo, tabelas de log, tabelas de índice, etc.).
geerlingguy