Existem muitos artigos exagerando (IMHO, é claro) a necessidade innodb_file_per_table
. Eu entendo que com innodb_file_per_table
, deve haver um melhor controle sobre as tabelas individuais; como fazer backup de cada tabela separadamente. No entanto, a reivindicação de melhor desempenho é questionável.
No meu teste, não há diferença no desempenho de innodb_file_per_table
e ibdata1
para um banco de dados de 60 GB. Obviamente, foi um teste simples com consultas normais e a situação pode ser diferente para consultas complicadas na vida real (esse é o motivo pelo qual eu fiz essa pergunta). O Linux de 64 bits ext4
pode lidar efetivamente com arquivos grandes.
Com innodb_file_per_table
, são necessárias mais operações de E / S de disco; e isso é significativo em se complicado JOIN
e FOREIGN KEY
restrições.
O espaço de tabela é compartilhado em um único ibdata
; como os espaços de tabela dedicados para tabelas separadas podem economizar espaço em disco? Obviamente, é mais fácil liberar espaço para cada tabela ALTER
, mas ainda é um processo caro (com bloqueio de tabela).
PERGUNTA: Isso innodb_file_per_table
afeta um melhor desempenho do mysql? Se sim, por que?
fonte
Respostas:
Não acho que seja uma questão de desempenho, mas de gerenciamento.
Com um arquivo separado por tabela, você pode armazenar diferentes bancos de dados em diferentes dispositivos de armazenamento, por exemplo.
Você pode lidar com o caso de bancos de dados muito grandes em sistemas de arquivos que não podem manipular arquivos grandes (pelo menos adie o problema até que uma tabela atinja o limite de tamanho do arquivo).
Você não tem crescimento descontrolado de espaço de tabela. Se você tiver algumas tabelas grandes descartadas, o
ibdata
arquivo permanecerá pequeno.Um aspecto que pode ter algum efeito no desempenho é a fragmentação dos dados e índices da tabela, que serão limitados por tabela. Mas isso precisa ser testado para ser confirmado.
fonte
innodb_file_per_table
.Porque é mais fácil gerenciar indivíduos, pois isso pode ser feito no nível do arquivo. Isso significa que, mesmo que o servidor esteja inoperante, você ainda pode copiar os dados copiando os arquivos da tabela, enquanto usar um espaço de tabela compartilhado significa copiar tudo o que pode ser desnecessariamente grande ou encontrar uma maneira de fazer o servidor executar a extração de dados ( você realmente não deseja extrair manualmente os dados com um editor hexadecimal).
Alguém avisou que você não pode simplesmente copiar e colar
.ibd
arquivos de um servidor para outro. Isso pode ser verdade, mas não deve se aplicar a backups no mesmo servidor (estou usando o termo backup aqui no sentido tradicional de fazer uma cópia; ou seja, não alterando drasticamente a coisa toda). Além disso,ibdata1
é recriado automaticamente na inicialização (como visto na etapa de exclusãoibdata1
da maioria dos guias de “conversão em arquivo por tabela”). Como tal, você não precisa copiaribdata1
além dos seus.ibd
arquivos (e seus.frm
arquivos correspondentes etc.).Se estiver tentando recuperar uma tabela perdida, deve ser suficiente copiar o arquivo
.ibd
e.frm
, além deinformation_schema
(que é muito menor queibdata1
). Dessa forma, você pode colocá-los em um servidor fictício e extrair sua tabela sem ter que copiar toda a coisa enorme.Não é de surpreender que o desempenho dependa inteiramente dos bancos de dados específicos em uso. Uma pessoa terá (até muito) resultados diferentes de outra.
É verdade que haverá mais operações de E / S de disco com arquivo por tabela, mas apenas um pouco mais. Pense em como o sistema funciona.
Para um banco de dados monolítico:
ibdata1
está abertoibdata1
Para um banco de dados por tabela:
ibdata1
está aberto.ibd
arquivo individual é aberto.ibd
arquivo.ibd
arquivo já abertoVocê notará que, quando o servidor está em execução, não é possível mover os arquivos de dados porque o servidor possui identificadores abertos. Isso ocorre porque, ao iniciar, ele os abre e os deixa abertos. Não os abre e fecha para cada consulta individual.
Como tal, há apenas mais algumas operações de E / S no início, quando o servidor é inicializado; não enquanto estiver em execução. Além disso, embora cada
.ibd
arquivo individual tenha sua própria sobrecarga separada (assinaturas, estruturas etc.), eles são armazenados em cache na memória e não são lidos novamente para cada consulta. Além disso, as mesmas estruturas são lidas mesmo com um espaço de tabela compartilhado, portanto, quase não há (se é que existe) mais memória necessária.Na verdade, se houver, o desempenho pode ser de fato pior .
Ao usar um espaço de tabela compartilhado, as operações de leitura e gravação podem às vezes / frequentemente ser combinadas para que o servidor leia uma amostra de dados de várias tabelas de uma só vez
ibdata
.No entanto, se os dados estiverem espalhados entre vários arquivos, ele deverá executar uma operação de E / S separada para cada um individualmente.
É claro que isso novamente depende inteiramente do banco de dados em questão; o impacto no desempenho do mundo real dependeria do tamanho, da frequência da consulta e da fragmentação interna do espaço de tabela compartilhado. Algumas pessoas podem notar uma grande diferença, enquanto outras podem não ter nenhum impacto.
Isso não. Se alguma coisa, aumenta o uso do disco.
Não tenho um banco de dados de 60 GB para testar, mas meu "insignificante" banco de dados pessoal, que contém minha instalação do WordPress e algumas tabelas pequenas para uso pessoal e testes de desenvolvimento, pesavam ~ 30 MB ao usar um espaço de tabela compartilhado. Depois de convertê-lo em arquivo por tabela, ele aumentou para ~ 85 MB. Mesmo eliminando tudo e reimportando, ele ainda tinha mais de 60 MB.
Esse aumento é devido a dois fatores:
O tamanho mínimo absoluto para
ibdata1
é - por algum motivo - 10 MB, mesmo que você não tenha nada além deinformation_schema
armazenado.Com um espaço de tabela compartilhado, só
ibdata1
há sobrecarga, como assinaturas de arquivos, metadados, etc., mas com cada tabela, cada.ibd
arquivo individual tem tudo isso. Isso significa que o total (mesmo com um hipotético <10MBibdata1
) seria um pouco maior em pelo menos:Obviamente, esses não serão grandes aumentos (a menos que você esteja usando um host que limite o tamanho do banco de dados ou os armazene em uma unidade flash etc.), mas eles aumentam mesmo assim e ao alternar ( todas ) as tabelas para arquivos Por tabela, você pode reduzir
ibdata1
para 10 MB, o total geral será invariavelmente mais do que era.fonte
Esta é a minha razão para SEMPRE usar innodb_file_per_table:
Sem arquivo por tabela, o arquivo ibdata nunca comprime, encolhe ou diminui o espaço. Não quando você exclui uma linha, descarta uma tabela ou um banco de dados. 2 GB de dados podem se tornar um arquivo de 20 GB rapidamente, se você tiver um sistema de filas ativo.
Digamos que você queira fazer um backup da sua tabela atual de 1 GB antes de uma alteração e soltá-la depois. Você está preso com um GB de espaço agora não utilizado no seu ibdata. Vadio.
Provavelmente existem infinitos exemplos de casos em que medidas temporárias aumentam o arquivo de dados único, mas basta dizer que, na minha opinião, nunca há uma razão para NÃO usar innodb_file_per_table
Além disso, aqui está um bom post para ler: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table
fonte
Minha razão pela qual não usar innodb_file_per_table é desempenho.
Fiz alguns testes para nosso banco de dados com 450 tabelas no mysql 5.5.45 Linux CentOS versão 6.7
Para testes de unidade que inserem dispositivos elétricos no banco de dados antes de cada teste (não usando todas as tabelas todas as vezes) e também os testes em si funcionam muito com o banco de dados (inserções, atualizações, exclusões, seleções ), o desempenho era 3-5 vezes melhor quando as tabelas de banco de dados não eram separados em mais arquivos.
Eu recomendo testar seu banco de dados com as consultas que você deseja usar e compará-lo antes de decidir usar innodb_file_per_table
Talvez você descubra que, para o servidor de produção, você pode usar innodb_file_per_table, mas para o ambiente de IC (continua a integração) que inicia testes de unidade (usa muito o banco de dados) e também é melhor desenvolvedores que iniciam muito os testes de unidade por causa do desempenho.
fonte
Isso torna os dados mais gerenciáveis, porque você pode recuperar o espaço não utilizado, o que é bom.
Acho que se seu banco de dados for usado principalmente para consultas selecionadas, isso não afetará muito o desempenho. Ele ainda precisa ler sobre a mesma quantidade de dados. Acho que não importa muito de quais arquivos está lendo os dados.
No entanto, isso pode piorar o desempenho em um banco de dados que faz muitas inserções e atualizações. Isso ocorre porque o mysql chama fsync () no arquivo de armazenamento após você confirmar uma transação. Se houver um único arquivo, ele faz uma chamada e aguarda a conclusão da chamada. Se houver muitos arquivos, ele precisará fazer a chamada várias vezes e aguardar o retorno de todas essas chamadas antes que o comando commit possa retornar.
Aqui está uma postagem de alguém que teve esse problema: http://umangg.blogspot.com/2010/02/innodbfilepertable.html
fonte
Conforme o artigo abaixo, o desempenho não é sobre gerenciamento de dados (operações brutas), mas sobre criação e descarte de objetos.
innodb_file_per_table torna a criação massiva e a eliminação de objetos mais lentas que o armazenamento ibdata e a produção não é aplicável, mas o teste contínuo deve ser relevante.
https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/
fonte
IMHO, é melhor usar innodb_file_per_table, é mais seguro. Se você não usá-lo, poderá haver um problema nos sistemas FAT32, onde apenas arquivos de 4 GB são permitidos. Eu escrevi um artigo sobre isso no idioma eslovaco ( https://www.itsoft.sk/preco-sa-neuvolni-miesto-na-disku-po-zmazani-mysql-tabulky/ ).
fonte