Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Por que o InnoDB fornece informações de espaço livre obviamente falsas


(Isso está respondendo a algumas das perguntas enterradas nos comentários.)

Nome impróprio O espaço "livre" inclui apenas blocos inteiros, não espaço livre dentro de blocos e muitos outros detalhes.

Caso 1:Todas as tabelas estão em ibdata1 -- SHOW TABLE STATUS (ou a consulta equivalente em information_schema mostrará o mesmo Data_free valor, ou seja, quanto está livre em ibdata1 . Este espaço pode ser reutilizado por qualquer tabela. É difícil devolver o espaço ao sistema operacional.

Caso 2:Todas as tabelas são file_per_table -- Agora cada Data_free refere-se ao espaço para a mesa. E o SUM() é significativo. (ibdata1 ainda existe, mas não contém nenhuma tabela real; há muitas outras coisas que o InnoDB precisa.)

Caso 3:Mistura -- Se você ativar/desativar file_per_table várias vezes, algumas tabelas estarão em ibdata1, outras terão seus próprios tablespaces.

Caso 4:CRIAR TABLESPACE em 5.7 -- Por exemplo, você pode ter um tablespace para cada banco de dados.

Caso 5:tabelas PARTICIONADAS -- Cada partição age como uma tabela.

Caso 6:8.0 -- Ainda mais mudanças estão chegando.

Banco de dados ==Diretório Na árvore de diretórios do MySQL, cada banco de dados pode ser visto como um diretório do sistema de arquivos. Dentro desse diretório pode ser visto algum conjunto de arquivos para cada tabela. O .frm arquivo contém a definição da tabela. Se um .ibd file existe, a tabela foi criada com file_per_table. Essa pode ser a maneira mais confiável de descobrir se a tabela é file_per_table. (8.0 terá mudanças significativas aqui.)

Quanto espaço posso reutilizar ? Não há uma boa resposta. Normalmente, inserir uma linha encontrará espaço no bloco ao qual pertence e Data_free não encolherá. Mas, se houver divisão(ões) de bloco, o Data_free pode cair em algum múltiplo de 16 KB (o tamanho do bloco) ou 4 MB (o "tamanho da extensão" - ou talvez seja 8 MB?). Além disso, inserções aleatórias fazem com que os blocos BTree fiquem, em média, cerca de 69% cheios.

Alterando innodb_file_per_table não tem efeito até o próximo CREATE TABLE ou ALTER TABLE . E então só tem efeito sobre onde colocar os dados+índices recém-criados/copiados (ibdata1 ou .ibd). Não destruirá dados.

Mesas grandes geralmente têm 4 MB a 7 MB de Data_free. Ao calcular quantas linhas você pode adicionar, não planeje que Data_free caia abaixo desse intervalo.

Avg_row_size deve ser útil. Mas às vezes ela (e as linhas) são mal aproximadas. Seu produto (Data_length) está sempre correto. Então, isso pode seja uma boa estimativa de "linhas a serem percorridas antes de obter mais espaço do sistema operacional:
(Data_free - 7M) / Avg_row_size

Recomendações de espaço de tabela :Coloque tabelas 'grandes' em file_per_table. Coloque tabelas 'minúsculas' em ibdata1 ou tablespaces específicos do banco de dados (5.7). Desculpe, nenhuma recomendação simples sobre a linha divisória entre 'grande' e 'pequeno'. E é desajeitado migrar uma tabela:SET global innodb_file_per_table = ...;; sair; login (para pegar o global); ALTER TABLE tbl ENGINE=InnoDB; . E é necessariamente uma cópia completa da tabela.

(Advertência :Deixei de fora muitos detalhes.)