Tipos de Tabela do MariaDB - Databases - Software - Computers
Tipos de Tabela do MariaDB
Índice
- Tabelas
MyISAM
-
- Espaço Necessário para Chaves
- Formatos de Tabelas
MyISAM
- Problemas com Tabelas
MyISAM
- Tabelas
MERGE
-
- Problemas com Tabelas
MERGE
- Problemas com Tabelas
- Tabelas
ISAM
- Tabelas
HEAP
- Tabelas
InnoDB
-
- Visão Geral de Tabelas InnoDB
- InnoDB no MariaDB Versão 3.23
- Opções de Inicialização do InnoDB
- Criando Tablespaces no InnoDB
- Criando Tabelas InnoDB
- Adicionando e Removendo Arquivos de Dados e Log do InnoDB
- Fazendo Backup e Recuperando um Banco de Dados InnoDB
- Movendo um Banco de Dados InnoDB para Outra Máquina
- Modelo Transacional do InnoDB
- Dicas de Ajuste de Desempenho
- Implementação de Multi-versioning
- Estrutura de Tabelas e Índices
- Gerenciamento do Espaço de Arquivos e E/S de Disco
- Tratando Erros
- Restrições em Tabelas InnoDB
- Histórico de Alterações do InnoDB
- Informações de Contato do
InnoDB
- Tabelas
BDB
ouBerkeleyDB
-
- Visão Geral de Tabelas
BDB
- Instalando
BDB
- Opções de Inicialização do
BDB
- Características de Tabelas
BDB
: - Itens a serem corrigidos no
BDB
num futuro próximo: - Sistemas operacionais suportados pelo
BDB
- Restrições em Tabelas
BDB
- Erros Que Podem Ocorrer Usando Tabelas
BDB
- Visão Geral de Tabelas
No MariaDB Versão 3.23.6, você pode escolher entre 3 formatos de tabelas básicos (ISAM
, HEAP
e MyISAM
). Versões mais novas do MariaDB suportam tipos de tabelas adicionais (InnoDB
ou BDB
), dependendo de como você o compila. Um banco de dados pode conter tabelas de diferentes tipos.
Ao criar uma nova tabela, você pode dizer ao MariaDB que tipo de tabela criar. O tipo de tabela padrão é, normalmente, MyISAM
.
MySQL sempre criará um arquivo .frm
para guardar as definições de coluna e tabela. Os índices e dados da tabela serão armazenados em um ou mais arquivos, dependendo do tipo de tabela.
Se você tentar utilziar um tipo de tabela que não está ativa ou não foi compilada com o MySQL, ele irá criar uma tabela do tipo MyISAM
. Este comportamento é conveniente quando você quer copiar tabelas entre servidores MariaDB que suportam tipos de tabel;as diferentes. (Talvez o seu servidor master suporte mecanismos de armazenamento tarnsacionais para aumento de segurança, enquanto o servidor slave só utiliza mecanismos de aramazenamento não-transacionais para maior velocidade.)
Esta mudançaautomatica de tipos de tabela podem confuso para novos usuários MySQL. Planejamos arrumar isto introduzindo avisos no protocolo cliente/servidor na versão 4.1 e gerar um aviso quando uma tipo de tabela é automaticamente alterado.
Você pode converter tabelas entre tipos diferentes com a instrução ALTER TABLE
. Leia 'Sintaxe ALTER TABLE
'.
Note que o MariaDB suporta dois tipos diferentes de tabelas: tabelas seguras com transação (InnoDB
and BDB
) e tabelas não seguras com tarnsação HEAP
, ISAM
, MERGE
, e MyISAM
).
Vantagens de tabelas seguras com transação (TST):
- Mais segura. Mesmo se o MariaDB falhar ou se você tiver problemas com hardware, você pode ter os seus dados de volta, ou através de recuperação automatica ou de um backup + o log de transação.
- Você pode combinar muitas instruções e aceitar todas de uma vez com o comando
COMMIT
. - Você pode executar um
ROLLBACK
para ignorar suas mudanças (se você não estiver rodando em modo auto-commit). - Se uma atualização falhar, todas as suas mudanças serão restauradas. (Com tabelas NTST todas as mudanças que tiverem sido feitas são permanentes).
- Pode fornecer melhor concorrência se a tabela obter muitas atualizações concorrentes com leituras.
Note que para utilizar tabelas InnoDB
você tem que usar pelo menos a opção de inicialização innodb_data_file_path
. Leia 'Opções de Inicialização do InnoDB'.
Vantagens de tabelas não seguras com transação (NTST):
- Muito mais rápida e não há nenhuma sobrecarga de transação.
- Usará menos spaço em disco já que não há nenhuma sobrecarga de transação.
- Usará menos memória para as atualizações.
Você pode combinar tabelas TST e NTST na mesma instrução para obter o melhor dos dois mundos.
Tabelas MyISAM
- Espaço Necessário para Chaves
- Formatos de Tabelas
MyISAM
- Problemas com Tabelas
MyISAM
MyISAM
é o tipo de tabela padrão no MariaDB Versão 3.23. Ela é baseada no código ISAM
e possui várias extensões úteis.
O índice é armazenado em um arquivo com extensão .MYI
(MYIndex), e os dados são armazenados em um arquivo com a extensão .MYD
(MYData). Você pode verificar/reparar tabelas MyISAM
com o utilitário myisamchk
. Leia 'Uso do myisamchk
para Recuperação em Caso de Falhas'. Você pode compactar tabelas MyISAM
com myisampack
para utilizar menos espaço. Leia 'myisampack
, O Gerador de Tabelas Compactadas de Somente Leitura do MariaDB'. O itens seguintes são novos no MyISAM
:
- Existe um parâmetro no arquivo
MyISAM
que indica se a tabela foi fechada corretamente. Se omysqld
é iniciado com--myisam-recover
, tabelasMyISAM
serão automaticamente verificadas e/ou reparadas na abertura se a tabela não foi fechada apropriadamente. - Você pode
INSERIR
novas linhas em uma tabela que não tenha blocos livres no meio do arquivo de dados, na mesma hora outras threadas são lidas da tabela (inserção concorrente). Um bloco livre pode vir de uma atualização de uma linha de tamanho dinâmico com muitos dados para uma linha com menos dados ou ao deletarmos linhas. Quando todos os blocos livres são usados, todas as inserções futurs serão concorrentes de novo. - Suporte a grandes arquivos (63-bit) em sistema de arquivos/sistemas operacionais que suportam grandes arquivos.
- Todo dado é armazenado com byte mais baixo primeiro. Isto torna a máquina e SO independentes. A única exigência para a portabilidade do arquivo binário é que a a máquina utilize inteiros com sinais em complemento de dois (como toda a máquina nos últimos 20 anos tem) e formato de pontos flutuante IEEE (também totalmente dominante entre máquinas mainstream). A única área de máquinas que não podem suportar compatibilidade binária são sistemas embutidos (porque eles, algumas vezes, tem processadores peculiares).
Não há uma grande perda de velocidade em armazenar o byte mais baixo de dados primeiro; os bytes em um registro de tabela estão normalmente desalinhados e isto não dá muito poder de leitura do byte desalinhado em outra ordem além da ordem reversa. O código atual busca-valor-coluna também não é crítico em relação ao tempo comparado a outro código.
- Todas as chaves numéricas estão armazendas com o byte mais alto em primeiro para conseguir melhor compactação do índice.
- Tratamento interno de uma coluna
AUTO_INCREMENT
.MyISAM
irá atualizá-lo automaticamenteem umINSERT/UPDATE
. O valorAUTO_INCREMENT
pode ser zerado commyisamchk
. Ele fará colunasAUTO_INCREMENT
mais rápidas (pelo menos 10%) e números natigos não irão reutilizar como no antigoISAM
. Note que quando umAUTO_INCREMENT
é definido no fim de uma chave multi-parte o comportamento antigo ainda está presente. - Ao inserir ordenandamente (como quando se utiliza colunas
AUTO_INCREMENT
) a árvore chave será separada de forma que o nodo mais alto contenha apenas uma chave. Isto irá aumentar a utilização de espaço na árvore de chaves. - Colunas
BLOB
eTEXT
podem ser indexados. - Valores
NULL
são perimitidos em colunas indexadas. Isto gasta 0-1 bytes/chave. - O tamanho máximo da chave é de 500 bytes por padrão (pode ser alterado recomopilando). No caso de chaves maiores que 250 bytes, um tamanho de bloco de chave maior que o padrão de 1024 bytes é usado para esta chave.
- Número máximo de chaves/tabelas é 32 por padrão. Isto pode ser aumentado para 64 sem ser necessário recompilar
myisamchk
. myisamchk
marcará as tabelas como verificadas se alguém executá-las sem--update-state
.myisamchk --fast
só verificará aquelas tabelas que não tenham esta marca.myisamchk -a
armazena estatísticas para partes de chaves(e não apenas para toda a chave como noISAM
).- Linhas de tamanho dinâmico serão agora muito menos fragmentados quando misturar deleções com atualizações e inserções. Isto é feito combinando automaticamente blocos deletados adjacentes e extendendo blocos se o próximo bloco é deletado.
myisampack
pode empacotar colunasBLOB
eVARCHAR
.- Você pode colocar arquivos de dados e índices em diretórios diferentes para obter maior velocidade (com a opção
DATA/INDEX DIRECTORY='caminho'
paraCREATE TABLE
). Leia 'SintaxeCREATE TABLE
'.
MyISAM
também suporta os seguintes itens, os quais o MariaDB estará apto a utilizar em um futuro próximo:
- Suporte a tipos
VARCHAR
reais; uma colunaVARCHAR
inicia com um tamanho armazenado em 2 bytes. - Tabelas com
VARCHAR
podem ter um registro de tamanho fixo ou dinâmico. VARCHAR
eCHAR
podem ser maior que 64K. Todos os segmentos de chaves têm a sua própria definição de linguagem. Isto habilitará o MariaDB para ter diferentes definições de linguagens por coluna.- Um índice computado em hash pode ser usado para
UNIQUE
. Isto lhe permitirá terUNIQUE
em qualquer combinação de colunas na tabela. (Você não pode procurar em um em um índice computadoUNIQUE
, de qualquer forma.)
Note que os arquivos de índice são muito menores com MyISAM
que com ISAM
. Isto significa que MyISAM
usará normalmente menos recursos do sistema que ISAM
, mas precisará de mais tempo de CPU quando inserir dados em um índice compactado.
As seguintes opções para mysqld
podem ser usadas para alterar o comportamento de tabelas MyISAM
. Leia 'SHOW VARIABLES
'.
Opção | Descrição |
--myisam-recover=# |
Recuperação automática de tabelas com falhas. |
-O myisam_sort_buffer_size=# |
Buffer utilizado ao recuperar tabelas. |
--delay-key-write=ALL |
Não desarrega buffers de chaves entre escritas para qualquer tabela MyISAM |
-O myisam_max_extra_sort_file_size=# |
Usada paa ajudar o MariaDB a decidir quando utilzar o método lento, mas seguro, de criação de índices de cache de chaves. Note este parâmetro é dado em megabytes antes da versão 4.0.3 e em bytes a partir desta versão. |
-O myisam_max_sort_file_size=# |
Não utilzia o método rápido de ordenação de índice para criar índices se o arquivo temporário se tornasse maior que o valor dado. Note que este parâmetro é dado em megabytes antes da versão 4.0.3 e em bytes a partir desta versão. |
-O bulk_insert_buffer_size=# |
Tamanho da arvore cache utilizado na otimização de inserções em bloco. Note que este é um limite por thread! |
A recuperação automática é ativada se você iniciar o mysqld
com --myisam-recover=#
. Leia 'Opções de Linha de Comando do mysqld
'. Na abertura, é verificado se a tabela está marcada como quebrada ou se a variavel de contagem de abertura para esta tabela não é 0 e você a está executando com --skip-external-locking
. Se nenhuma das verificações acima forem verdadeiras o seguinte ocorre.
- Verifica-se se a tabela possui erros.
- Se encontrarmos um erro, tente fazer um reparação rápida (com ordenação e sem recriar o arquivo de dados) da tabela.
- Se o reparação falhar devido a um erro no arquivo de dados (por exemplo um erro de chave duplicada), é feita uma nova tentativa, mas desta vez o arquivo de dados é recriado.
- Se a reparação falhar, tente mais uma vez com o antigo método de opção de reparação (escrever linha a linha sem ordenação) o qual deve estar apto a reparar qualquer tipo de erros com pequenas exigências de disco.
Se a recuperação não estiver apta a recuperar todas as linhas de uma instrução completada previamente e você não especificou FORCE
como uma opção para myisam-recover
, então a reparação automática abortará com uma mensagem de erro no arquivo de erros:
Error: Couldn't repair table: test.g00pages
Caso você tenha utilizado a opção FORCE
, você irá obter um aviso no arquivo de erro:
Warning: Found 344 of 354 rows when repairing ./test/g00pages
Note que se você executar uma recuperação automática com a opção BACKUP
, você deve ter um script cron
que mova automaticamente arquivos com nome como tablename-datetime.BAK
do diretório de banco de dados para uma media de backup.
See 'Opções de Linha de Comando do mysqld
'.
Espaço Necessário para Chaves
O MariaDB pode suportar diversos tipos de índices, mas o tipo normal é ISAM ou MyISAM. Eles utilizam um índice de árvore-B, e você pode calcular aproximadamente o tamanho do arquivo de índice como (key_length+4)/0.67
, somado sobre todas as chaves. (Isto é para o pior caso, quando todas as chaves são inseridas ordenadamente e nós não temos nenhuma chave compactada.)
Índices string são compactados em espaços. Se a primeira parte do índice é uma string, ele também será compactado em prefixo. Compactação em espaço torna o arquivo de índice menor que o indicado acima se a coluna string tem muitos espaços no fim ou é uma coluna VARCHAR
não usada em sua totalidade. Compactação de prefixo é usado em chaves que iniciam com uma string. A Compactação de prefixo ajuda se existirem muitas strings com o prefixo idêntico.
Em tabelas MyISAM
, você também pode utilizar prefixos em números comprimidos especificando PACK_KEYS=1
quando você cria a tabela. Isto ajuda quando você tem muitas chaves inteiras que têm prefixo idêntico quando o número é armazenado com o byte mais alto primeiro.
Formatos de Tabelas MyISAM
- Características de Tabelas Estáticas (Tamanho Fixo)
- Características de Tabelas Dinâmicas
- Características de Tabelas Compactadas
MyISAM
suporta 3 tipos diferentes de tabelas. Dois deles são escolhidos automaticamente dependendo do tipo das colunas que você está usando. O terceiro, tabelas compactadas, só pode ser criado com a ferramenta myisampack
.
Quando você cria (CREATE
) ou altera (ALTER
uma tabela, você pode, para tabelas que não possuem BLOB
s, forçar o formato da tabela para DYNAMIC
ou FIXED
com a opção de tabela ROW_FORMAT=#
. No futuro você estará apto a compactar/descompactar tabelas especificando ROW_FORMAT=compressed | default
para ALTER TABLE
. Leia 'Sintaxe CREATE TABLE
'.
Características de Tabelas Estáticas (Tamanho Fixo)
Este é o formato padrão. É usado quando a tabela não contém colunas VARCHAR
, BLOB
, ou TEXT
.
Este é o formato mais e simples e seguro. É também o mais rápidos dos formatos em disco. A velocidade vem da facilidade de se encontrar dados no disco. Procurar por algo com um índice no formato estático é muito simples. Apenas multiplique o número de linhas pelo seu tamanho.
Também, ao varrermos uma tabela, é muito simples ler um número contante de registros a cada leitura de disco.
A segurança é evidenciada se o seu computador falha ao escrever em um arquivo MyISAM de tamanho fixo, caso no qual o myisamchk
pode facilemente descobrir onde cada linha começa e termina. Assim, geralmente pode se recuperar todos os registros, exceto os escritos parcialmente. Note que no MariaDB todos os índices sempre podem ser reconstruídos.
- Todas as colunas
CHAR
,NUMERIC
, eDECIMAL
tem espaços adicionados até o tamanho da coluna. - É muito rápida.
- Facil de se colocar em cache.
- Fácil de reconstruir depois de uma falha, pois os registros estão localizados em posições fixas.
- Não precisa ser reorganizada (com
myisamchk
) a menos que um grande número de registros sejam deletados e você queira retornar espaço de diaco livre ao sistema operacional. - Normalmente exige mais espaço de disco que tabelas dinâmicas.
Características de Tabelas Dinâmicas
Este formato é usado se a tabela contém colunas VARCHAR
, BLOB
ou TEXT
ou se as tabelas são criadas com ROW_FORMAT=dynamic
.
Este formato é um pouco mais complexo porque cada linha tem que ter um cabeçalho que diz o seu tamanho. Um registro também pode acabar em mais de um local quando fica maior em uma atualização.
Você pode utilizar OPTIMIZE tabela
ou myisamchk
para desfragmentar uma tabela. Se você tiver dados estáticos que você acessa/altera demias na mesma tabela, como alguma coluna VARCHAR
ou BLOB
, pode ser uma boa idéia mover as colunas dinâmicas para outra tabela apenas para evitar fragmentação.
- Todas as colunas string são dinâmicas (exceto aquelas com tamanho menor que 4).
- Cada registro é precedido por um mapa de bits indicando quais colunas estão vazias (
''
) para colunas string ou zero para colunas numéricas (Isto é diferente de colunas contendo valoresNULL
). Se uma coluna de string tem um tamanho de zero depois da remoção de espaços extras, ou uma coluna numérica tem um valor de zero, isto é marcado no mapa de bits e não é salvado em disco. Strings não vazias são salvas como um byte de tamanho mais o conteudo da string. - Geralmente utiliza muito menos espaço de disco que tabelas de tamanho fixo.
- Cada registro utiliza apenas o espeço necessário. Se um registro aumenta, ele é separado em varios pedaços, de acordo com a necessidade. Isto resulta em fragmentação do registro.
- Se você atualiza uma linha com informações que ultrapassam o seu tamanho, a linha será fragmentada. Neste caso, você pode precisar executar
myisamchk -r
de tempos em tempos para obter melhor performance. Usemyisamchk -ei nome_tabela
para algumas estatísticas. - Não é fácil de recontruí-la após uma falha, pois um registro pode ser fragmentado em muitos pedaços e um link (fragmento) pode ser perdido.
- O tamanho esperado para registros de tamanho dinâmico é:
3 + (número de colunas + 7) / 8 + (número de colunas char) + tamanho empacotado de colunas numéricas + tamanho das strings + (número de colunas NULL + 7) / 8
Existe uma penalidade de 6 bytes para cada link. Um registro dinâmico é ligado sempre que uma atualização causa um aumento do registro. Cada novo link terá pelo menos 20 bytes, assim o próximo aumento estará, provavelemente, no mesmo link. Se não, haverá outro link. Você pode checar quantos links existem com
myisamchk -ed
. Todos os links podem ser removidos commyisamchk -r
.
Características de Tabelas Compactadas
Este é um tipo somente leitura que é gerado com a ferramenta opcional myisampack
(pack_isam
para tabelas ISAM
):
- Todas as distribuições MySQL, mesmo aquelas existentes antes do MariaDB se tornar
GPL
, podem ler tabelas que forma compactadas commyisampack
. - Tabelas compactadas utilizam muito pouco espaço em disco. Isto minimiza o uso de disco, o que é muito bom quando se utiliza discos lentos (com CD-ROMs).
- Cada registro é compactado separadamente (pouca sobrecarga de acesso). O cabeçalho de um registro é fixo (1-3 bytes) dependendo do maior registro na tabela. Cada coluna é compactada diferentemente. Alguns dos tipos de compactação são:
- Existe, geralmente, uma tabela Huffman diferente para cada coluna.
- Compactação de espaço de sufixos.
- Compactação de espaço de prefixos.
- Números com valor
0
são armazenados usando 1 bit. - Se os valores em uma coluna inteira tem uma faixa pequena, a coluna é armazenada usando o menor tipo possível. Por exemplo, uma coluna
BIGINT
(8 bytes) pode ser armazenada como uma colunaTINYINT
(1 byte) se todos os valores estão na faixa de0
a255
. - Se uma coluna tem apenas um pequeno conjunto de valores possíveis, o tipo de coluna é convertido para
ENUM
. - Uma coluna pode usar uma combinação das compactações acima.
- Pode tratar registros de tamanho fixo ou dinâmico.
- Pode ser descompactada com
myisamchk
.
Problemas com Tabelas MyISAM
- Tabelas
MyISAM
Corrompidas - O Cliente está usando a tabela ou não a fechou de forma apropriada
O formato do arquivo que o MariaDB usa para armazenar dados tem sido testado extensivamente, mas sempre há circunstâncias que podem fazer com que tabelas de banco de dados sejam corrompidas.
Tabelas MyISAM
Corrompidas
Mesmo se o formato MyISAM for muito confiável (todas as alterações na tabela são escritas antes da instrução SQL retornar), você ainda pode ter tabelas corrompidas se algum dos seguintes itens ocorrer:
- O processo
mysqld
ser finalizado no meio de uma escrita. - Finalização inesperada do computador (por exemplo, se o computador é desligado).
- Um erro de hardware.
- Você estar usando um programa externo (como myisamchk) em uma tabela aberta.
- Um bug de um software no código MariaDB ou MyISAM.
Os sintomas típicos de uma tabela corrompida são:
- Você obtem o erro
Incorrect key file for table: '...'. Try to repair it
enquanto seleciona dados da tabela. - Consultas não encontram linhas em uma tabela ou retornam dados incompletos.
Você pode verificar se uma tabela está ok com o comando CHECK TABLE
. Leia 'Sintaxe de CHECK TABLE
'.
Você pode repara um tabela corrompida com REPAIR TABLE
. Leia 'Sintaxe do REPAIR TABLE
'. Você também pode repará-la, quando o mysqld
não estiver em execução com o comando myisamchk
. sintaxe myisamchk
.
Se a sua tabela estiver muito corrompida você deve tentar encontrar o razão! Leia Seção A.4.1, 'O Que Fazer Se o MariaDB Continua Falhando'.
Neste caso, a coisa mais importante de saber é se a tabela foi corrompida porque o mysqld
foi finalizado (pode se verificar isto facilmente verificando se há uma linha restarted mysqld
recente no arquivo de erro do mysql. Se este não é o caso, então você deve tentar fazer um caso de teste disto. Leia Seção E.1.6, 'Fazendo um Caso de Teste Se Ocorre um Corrompimento de Tabela'.
O Cliente está usando a tabela ou não a fechou de forma apropriada
Cada arquivo .MYI
do MyISAM
tem um contador no cabeçalho que pode ser usado para verificar se uma tabela foi fechada apropriadamente.
Se você obteve o seguinte aviso de CHECK TABLE
ou myisamchk
:
# clients is using or hasn't closed the table properly
isto significa que este contador eta fora de sincronia. Insto não significa que a tabela está corrompida, mas significa que você poderia pelo menos fazer uma verificação na tabeal para verificar se está ok.
O contador funciona da seguinte forma:
- A primeira vez que a tabela é atualizada no MySQL, um contador no cabeçalho do arquivo de índice é incrementado.
- O contador não é alterado durante outras alterações.
- Quando a última intância da tabela é fechda (devido a um
FLUSH
ou porque não há espaço na cache de tabelas) o contador é decremetado se a tabela tiver sido atualizada em qualquer ponto. - Quando você raparar a tabela ou verificá-la e ela estiver ok, o contador é zerado.
- Para evitar problemas com interações com outros processos que podem fazer uma verificação na tabela, o contador não é decrementado no fechamento se ele for 0.
Em outras palavras, o único modo dele ficar fora de sincronia é:
- As tabelas
MyISAM
são copiadas sem umLOCK
eFLUSH TABLES
. - O MariaDB ter falhado entre uma atualização e o fechamento final. (Note que a tabela pode ainda estar ok já que o MariaDB sempre faz escritas de tudo entre cada instrução.)
- Alguém ter feito um
myisamchk --recover
oumyisamchk --update-state
em uma tabela que estava em uso pormysqld
. - Muitos servidores
mysqld
estrem usando a tabela e um deles tiver feito umREPAIR
ouCHECK
da tabela enquanto ela estava em uso por outro servidor. Nesta configuração oCHECK
é seguro de se fazer (mesmo se você obter ovisos de outros servidor), masREPAIR
deve ser evitado pois ele atualmente substitui o arquivo de dados por um novo, o qual não é mostrado para os outros servidores.
Tabelas MERGE
- Problemas com Tabelas
MERGE
Tabelas MERGE
são novas no MariaDB Versão 3.23.25. O código ainda está em gamma, mas deve estar razoavelmente estável.
Uma tabela MERGE
(também conhecida como tabela MRG_MyISAM
) é uma coleção de tabelas MyISAM
idênticas que podem ser usada como uma. Você só pode fazer SELECT
, DELETE
, e UPDATE
da coleção de tabelas. Se você fizer um DROP
na tabela MERGE
, você só está apagando a especificação de MERGE
.
Note que DELETE FROM tabela_merge
usado sem um WHERE
só limpará o mapeamento a tabela, não deletando tudo nas tabeals mapeadas. (Planejamos consertar isto na versão 4.1).
Com tabelas idênticas queremos dizer que todas as tabelas são criadas com informações de colunas e chaves idênticas. Você não pode fundir tabelas nas quais as colunas são empacotadas de forma diferente, não tenham as mesmas colunas ou tenham as chaves em ordem diferente. No entanto, algumas das tabelas podem ser compactadas com myisampack
. Leia 'myisampack
, O Gerador de Tabelas Compactadas de Somente Leitura do MariaDB'.
Ao criar uma tabela MERGE
, você obterá uma arquivo de definição de tabela .frm
e um arquivo de lista de tabela .MRG
. O arquivo .MRG
contém apenas a lista de arquivos índices (arquivos .MYI
) que devem ser usados como um. Antes da versão 4.1.1, todas as tabelas usadas devem estar no mesmo banco de dados assim como a própria tabela MERGE
.
Atualmente você precisa ter os privilégios SELECT
, UPDATE
e DELETE
em tabelas mapeadas para uma tabela MERGE
.
Tabelas MERGE
podem ajudá-lo a resolver os seguintes problemas:
- Facilidade de gernciamento de um conjunto de log de tabelas. Por exemplo, você pode colocar dados de meses diferentes em arquivos separadosfrom different months into separate files, compress some of them with
myisampack
, and then create aMERGE
to use these as one. - Lhe da maior velocidade. Você pode separar uma grande tabela somente leitura baseado em algum critério e então colocar as diferentes partes da tabela em discos diferentes. Uma tabela
MERGE
desta forma pode ser muito mais rápida que se usada em uma grande tabela. (Você pode, é claro, usar também um nível RAID para obter o memo tipo de benefício.) - Faz pesquisas mais eficientes. Se você sabe exatamente o que você esta procurando, você pode buscar em apenas um dos pedaços da tabelas para algumas pesquisas e utilizar tabelas
MERGE
para outras. Você pode até ter diferentes tabelasMERGE
ativas, com possíveis arquivos sobrepostos. - Reparações mais eficientes. É facil reparar os arquivos individuais que são mapeados para um arquivo
MERGE
que tentar reparar um arquivo realmente grande. - Mapeamento instantâneo de diversos arquivos como um. Uma tabela
MERGE
usa o índice de tabelas individuais. Não é necessário manter um índice de para ela. Isto torna a coleção de tabelasMERGE
MUITO rápido de fazer ou remapear. Note que você deve especificar a definição de chave quando você cria uma tabelaMERGE
!. - Se você tem um conjunto de tabelas que você junta a uma tabela grande por demanda ou bacth, você deveria criar uma tabela
MERGE
delas por demanda. Isto é muito mais rápido é economizará bastante espaço em disco. - Contornam o limite de tamanho de arquivos do sistema operacional.
- Você pode criar um apelido/sinônimo para uma tabela usando
MERGE
sobre uma tabela. Não deve haver nenhum impacto notável na performance ao se fazer isto (apenas algumas chamadas indiretas e chamadas dememcpy()
para cada leitura).
As desvantagens de tabelas MERGE
são:
- Você só pode utilizar tabelas
MyISAM
idênticas em uma tabelaMERGE
. REPLACE
não funciona.- Tabelas
MERGE
usam mais descritores de arquivos. Se você estiver usando uma tabelaMERGE
que mapeia mais de 10 tabelas e 10 usuários a estão usando, você está usando 10*10 + 10 descritores de arquivos. (10 arquivos de dados para 10 usuários e 10 arquivos de índices compartilhados). - A leitura de chaves é lenta. Quando você faz uma leitura sobre uma chave, o mecanismo de armazenamento
MERGE
precisará fazer uma leitura em todas as tabelas para verificar qual casa melhor com a chave dada. Se você então fizer uma 'leia próximo', o mecanismo de armazenamentoMERGE
precisará procurar os buffers de leitura para encontrar a próxima chave. Apenas quando um buffer de chaves é usado, o mecanismo de armazenamento precisará ler o próximo bloco de chaves. Isto torna as chavesMERGE
mais lentas em pesquisaseq_ref
, mas não em pesquisasref
. Leia 'Sintaxe deEXPLAIN
(Obter informações sobre umaSELECT
)'. - Você não pode fazer
DROP TABLE
,ALTER TABLE
,DELETE FROM nome_tabela
sem uma cláusulaWHERE
,REPAIR TABLE
,TRUNCATE TABLE
,OPTIMIZE TABLE
, ouANALYZE TABLE
em nenhuma das tabelas que é mapeada por uma tabelaMERGE
que está 'aberta'. Se você fizer isto, a tabelaMERGE
pode ainda se referir a tabela original e você obterá resultados inexperados. O modo mais fácil de contornar esta deficiência e através do comandoFLUSH TABLES
, assegurando que nenhuma tabelaMERGE
permanecerá 'aberta'.
Quando você cria uma tabela MERGE
você deve especificar com UNION=(lista-de-tabelas)
quais tabelas você quer usar com uma. Opcionalmente você pode especificar com INSERT_METHOD
se você quer que inserções em tabelas MERGE
ocorram na primeira ou na última tabela da lista UNION
. Se você não especificar INSERT_METHOD
ou especificar NO
, entaão todos os comandos INSERT
na tabela MERGE
retornarão um erro.
O seguinte exemplo lhe mostra como utilizaqr tabelas MERGE
:
CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); CREATE TABLE t2 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1'); INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2'); CREATE TABLE total (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; SELECT * FROM total;
Note que não criamos uma chave UNIQUE
ou PRIMARY KEY
na tabela total
já que a chave não será única na tabela total
.
Note que você também pode manipular o arquivo .MRG
diretamente de fora do servidor MySQL:
shell>cd /mysql-data-directory/current-database
shell>ls -1 t1.MYI t2.MYI > total.MRG
shell>mysqladmin flush-tables
Agora você pode fazer coisas como:
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table |
| 3 | t1 |
| 1 | Testing |
| 2 | table |
| 3 | t2 |
+---+---------+
Note que a coluna a
, declarada como PRIMARY KEY
, não é unica, já que tabelas MERGE
não podem forca a unicidade sobre um conjunto de tabelas MyISAM
selecionadas.
Para remapear uma tabela MERGE
você pode fazer o seguinte:
- Fazer um
DROP
na tabela e recriá-la - Usar
ALTER TABLE nome_tabela UNION=(...)
- Alterar o arquivo
.MRG
e executar umFLUSH TABLE
na tabelaMERGE
e todas as tabelas selecionadas para forçar o mecanismo de armazenamento a ler o novo arquivo de definição.
Problemas com Tabelas MERGE
Segue abaixo os problemas conhecidos com tabelas MERGE
:
- Uma tabela
MERGE
não pode manter restriçõesUNIQUE
sobre toda tabela. Quando você faz umINSERT
, os dados vão para a primeira ou última tabela (de acordo comINSERT_METHOD=xxx
) e estas tabelasMyISAM
asseguram que os dados são únicos, mas não se sabe nada sobre outras tabelasMyISAM
. DELETE FROM tabela_merge
usado sem umWHERE
só limpará o mapeamento da tabela, não deletando tudo na tabela mapeada.RENAME TABLE
em uma tabela usada por uma tabelaMERGE
ativa pode corromper a tabela. Isto será corrigido no MariaDB 4.1.x.- Criação de uma tabela do tipo
MERGE
não verifica se o tabelas selecionadas são de tipos compatíveis ou se elas existem. O MariaDB fará uma verificação rápida de se o tamanho do registro é igual entre tabelas mapeadas quando a tabelaMERGE
é usada, mas esta não é uma verificação total.
Se você usar tabelas
MERGE
deste modo, você poderá obter problemas estranhos. - Se você usar
ALTER TABLE
para adicionar primeiro um índiceUNIQUE
em uma tabela usada em uma tabelaMERGE
e então usarALTER TABLE
para adicionar um índice normal na tabelaMERGE
, a ordem da chave será diferente para as atabelas se houvesse uma chave não única antiga na tabela. Isto ocorre porqueALTER TABLE
coloca chavesUNIQUE
antes de chaves normais para estar apto a detectar chaves duplicadas o mais rápido possível. DROP TABLE
em uma tabela que está em uso por uma tabelaMERGE
não funcionará no Windows porque o mecanismo de armazenamentoMERGE
faz o mapeamento da tabela escondido da camada mais alta do MariaDB. Como o Windows não permite que você apague arquivos que estejam abertos, você deve primeiro descarregar todas as tabelasMERGE
(comFLUSH TABLES
) ou apagar a tabelaMERGE
antes de apagar a tabela. Nós consertaremos isto assim que introduzirmosVIEW
s.
Tabelas ISAM
O tipo de tabela ISAM
, obsoleto, desaparecerá na versão 5.0. Ele está incluído no fonte do MariaDB é mas não é mais compilado. MyISAM
é uma implementação melhor deste handler de tabela e você deve converter todas as tabelas ISAM
para tabelas MySAM
o mais rápido possível.
ISAM
usa um índice B-tree
. O índice é armazenado em um arquivo com a extensão .ISM
, e os dados são armazenados em um arquivo com a extensão .ISD
. Você pode verificar/reparar tabelas ISAM
com o utilitário isamchk
. Leia 'Uso do myisamchk
para Recuperação em Caso de Falhas'.
ISAM
tem os seguintes recursos/propriedades:
- Chaves compactadas e de tamanho fixo.
- Registros de tamanho fixo e dinâmico
- chaves com 16 chaves parciais/chaves
- Tamanho máximo da chave de 256 (padrão)
- Os dados são armazenados em formato de máquina; isto é rápido mas é dependente da maquina/SO.
A maioria das coisas que são verdadeiras para tabelas MyISAM
também são verdadeiras para tabelas ISAM
. Leia 'Tabelas MyISAM
'. As maiores diferenças comparados a tabelas MyISAM
são:
- Tabelas
ISAM
não são bninários portáveis entre SO/Pataformas. - Não pode lidar com tabelas > 4G.
- Só suporta compactação de prefixo em strings.
- Limite de chaves menor.
- Tabelas dinâmicas são mais fragmentadas.
- Tableas são compactadas com
pack_isam
ao invés demyisampack
.
Se você quiser converter uma tabela ISAM
em uma tabela MyISAM
de forma a se poder utilizar utilitários tais como mysqlcheck
, use uma instrução ALTER TABLE
:
mysql> ALTER TABLE nome_tabela TYPE = MYISAM;
A versões embutidas do MariaDB não supoortam tabelas ISAM
.
Tabelas HEAP
Tabeals HEAP
usam índices hash e são armazenadas na memória. Isto as torna muito rápidas, mas se o MariaDB falhar você irá perder todos os dados armazenados nela. HEAP
é muito útil para tabelas temporárias!
As tabelas HEAP
do MariaDB utilizam hashing 100% dinâmico sem áreas em excesso. Não há espaços extras necessários para listas livres. Tabelas HEAP
também não têm problemas com deleção + inserção, o que normalmente é comum em tabelas com hash:
mysql>CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) AS down
->FROM log_table GROUP BY ip;
mysql>SELECT COUNT(ip),AVG(down) FROM test;
mysql>DROP TABLE test;
Aqui seguem algumas coisas que você deve considerar ao utilizar tabelas HEAP
:
- Você sempre deve utilizar a especificação
MAX_ROWS
na instruçãoCREATE
para assegurar que você não irá utilizar toda a memória acidentalmente. - Índices só serão utilizados com
=
e<=>
(mas é MUITO rápido). - Tabelas
HEAP
só podem usar chaves inteiras para procurar por uma linha; compare isto a tabelasMyISAM
onde qualquer prefixo de chave pode ser usada para encontrar linhas. - Tabelas
HEAP
usam um formato de registro de tamanho fixo. HEAP
não suporta colunasBLOB
/TEXT
.HEAP
não suporta colunasAUTO_INCREMENT
.- Antes do MariaDB 4.0.2,
HEAP
não suportava um índice em uma colunaNULL
. - Você pode ter chaves não únicas em uma tabela
HEAP
(isto não é comum em tabelas com hash). - Tabelas
HEAP
são compartilhadas entre todos os clientes (como qualquer outra tabela). - Você não pode pesquisar pela próxima entrada na ordem (isto é, usar o índice para fazer um
ORDER BY
). - Dados de tabelas
HEAP
são alocados em blocos menores. As tabelas são 100% dinâmicas (na inserção). Não são necessárias areas excessivas e espaço de chave extra. Linhas deletadas são colocadas em uma lista encadeada e são reutilizadas quando você insere novos dados na tabela. - Você precisa de memória extra suficiente para todas as tabelas
HEAP
que você quiser utilizar ao mesmo tempo. - Para liberar memória, você deve executar
DELETE FROM tabela_heap
,TRUNCATE tabeala_heap
ouDROP TABLE tabela_heap
. - O MariaDB não pode descobrir aproximadamente quantas linhas existem entre dois valores (isto é utilizado pela atimizador de escala para decidar qual indice usar). Isto pode afetar algumas consultas se você alterar uma tabela
MyISAM
para uma tabelaHEAP
. - Para assegurar que você não vai cometer nenhum erro acidentalmente, você não pode criar tabelas
HEAP
maiores quemax_heap_table_size
.
A memória necessária para uma linha na tabela HEAP
é:
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) + ALIGN(length_of_row+1, sizeof(char*))
sizeof(char*)
é 4 em uma máquina de 32 bits e 8 em uma máquina de 64 bits.
Tabelas InnoDB
- Visão Geral de Tabelas InnoDB
- InnoDB no MariaDB Versão 3.23
- Opções de Inicialização do InnoDB
- Criando Tablespaces no InnoDB
- Criando Tabelas InnoDB
- Adicionando e Removendo Arquivos de Dados e Log do InnoDB
- Fazendo Backup e Recuperando um Banco de Dados InnoDB
- Movendo um Banco de Dados InnoDB para Outra Máquina
- Modelo Transacional do InnoDB
- Dicas de Ajuste de Desempenho
- Implementação de Multi-versioning
- Estrutura de Tabelas e Índices
- Gerenciamento do Espaço de Arquivos e E/S de Disco
- Tratando Erros
- Restrições em Tabelas InnoDB
- Histórico de Alterações do InnoDB
- Informações de Contato do
InnoDB
Visão Geral de Tabelas InnoDB
O InnoDB
prove o MariaDB com um mecanismo de armazenamento seguro com transações (compatível com ACID
) com commit, rollback, e recuperação em caso de falhas. InnoDB faz bloqueio a nível de registro e também fornece uma leitura sem bloqueio em SELECT
em um estilo consistente com Oracle. Estes recursos aumentam a performance e a concorrência de multi usuários. Não há a necessidade de escalonamento de bloqueios em InnoDB
, pois o bloqueio a nível de registro no InnoDB cabe em um espaço muito pequeno. InnoDB
é o primeiro gerenciador de armazenamento no MariaDB que suportam restrições FOREIGN KEY
.
InnoDB
foi desenvolvido para obter o máximo de performance ao processar grande volume de dados. Sua eficiência de CPU provavelmente não é conseguido por nenhum outro mecanismo de banco de dados relacional com base em disco.
InnoDB
é usado na produção de vários sites com banco de dados grandes e que necessitam de alto desempenho. O famoso site de notícias Slashdot.org utiliza InnoDB
. Mytrix, Inc. armazena mais de 1 TB de dados em InnoDB
, em outro site trata uma carga média de 800 inserções/atualizações por segundo em InnoDB
.
Tecnicamente, InnoDB
é um banco de dados completo colocado sob o MariaDB. InnoDB
tem sua própria área de buffer para armazenar dados e índices na memória principal. InnoDB
armazena suas tabelas e índices em um espaco de tabela, o qual pode consistir de vários arquivos (ou partições de disco raw). Isto é diferente, por exemplo de tabelas MyISAM
, onde cada tabela é armazenada como um arquivo separado. Tabelas InnoDB
podem ser de qualquer tamanho, mesmo em sistemas operacionais onde o sistema de arquivo é limitado a 2 GB.
Você pode encontrar as últimas informações sobre InnoDB
em http://www.innodb.com/. A versão mais atualizada do manual do InnoDB
sempre é colocada lá.
InnoDB
é publicade sob a mesma Licença GNU GPL
, Versão 2 (de Junho de 1991) que MySQL. Se você distribuir MySQL/InnoDB, e sua aplicação não satisfaz as restrições da licença GPL, você deve comprar uma lincença comercial MySQL Pro em https://order.mysql.com/?sub=pg&pg_no=1.
InnoDB no MariaDB Versão 3.23
A partir do MariaDB versão 4.0, InnoDB
está habilitado por padrão. A seguinte informação só se aplica a série 3.23.
Tabelas InnoDB estão incluídas na distribuição fonte a partir do MariaDB 3.23.34a e está ativado no binário MariaDB -Max da série 3.23. No Windows os binários -Max estão contidos na distribuição padrão.
Se você tiver feito o download de uma versão binária do MariaDB que inclui suporte para InnoDB, simplesmente siga as instruções do manual do MariaDB para instalar um vrsão binária do MariaDB. Se você já tem o MySQL-3.23 instalado, então o modo mais simples de instalar MariaDB -Max é substituir i executável do servidor mysqld
com o executável correspondente na distribuição -Max. MariaDB e MariaDB -Max diferem apenas no executável do servidor. Leia 'Instalando uma Distribuição Binária do MariaDB'. Leia 'mysqld-max
, om servidor mysqld
extendido'.
Para compilar o MariaDB com suoprte a InnoDB, faça o download do MariaDB-3.23.34a ou posterior de https://mariadb.com/ e configure o MariaDB com a opção --with-innodb
. Veja o manual MariaDB sobre como instalar uma distribuição fonte. Leia 'Instalando uma distribuição com fontes do MariaDB'.
cd /caminho/para/fonte/mysql-3.23.37 ./configure --with-innodb
Para utiliar tabelas InnoDB no MySQL-Max-3.23 você deve especificar parâmetros de configuração na seção [mysqld]
do arquivo de configuração my.cnf
, ou no Windows opcionalmente em my.ini
.
No mínimo, na versão 3.23 você deve especificar innodb_data_file_path
onde você especificar o nome e tamanho dos arquivos de dados. Se você não mencionar innodb_data_home_dir
em my.cnf
o padrão é criar estes arquivoas no diretorio_dados
do MariaDB. Se você especificar innodb_data_home_dir
como uma string vazia, então você pode dar caminhos absolutos ao seu arquivo de dados em innodb_data_file_path
.
O modo mínimo de modificar é de adicionar a seção [mysqld]
a linha
innodb_data_file_path=ibdata:30M
mas para obter melhor desempenho é melhor que você especifique as opções como recomendado. Leia 'Opções de Inicialização do InnoDB'.
Opções de Inicialização do InnoDB
Para habilitar tabelas InnoDB
no MariaDB versão 3.23, veja 'InnoDB no MariaDB Versão 3.23'.
No MySQL-4.0 não é necessário se fazer nada específico para habilitar tabelas InnoDB
.
O comportamento padrão no MariaDB e MariaDB é criar um arquivo ibdata1
auto-extensível de 10 MB no diretório de dados do MariaDB e dois ib_logfile
s de 5MB em datadir
. (No MySQL-4.0.0 e 4.0.1 o arquivo de dados é 64 MB e não é auto-extensível.)
Note: Para obter uma boa performance você deve definir explicitamente os parâmetros listados nos seguintes exemplos.
Se você não quiser utilizar tabelas InnoDB
, você pode adicionar a opção skip-innodb
ao seu arquivo de oção do MariaDB.
A partir das versões 3.23.50 e 4.0.2 InnoDB
permite que o último arquivo de dados n linha innodb_data_file_path
seja especificado como auto-extensível. A sintaxe de innodb_data_file_path
é a seguinte:
caminhodados:tamanhoespec;caminhodados:tamanhoespec;... ... ;caminhodados:tamanhoespec[:autoextend[:max:tamanhoespec]]
Se você especificar o último arquivo de dados coma a opção autoextend, InnoDB
extenderá o último arquivo de dados se ele ficar sem espaço no tablespace. O aumento é de 8 MB a cada vez. Um exemplo:
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:100M:autoextend
instrui InnoDB
a criar apenas um único arquivo de dados com tamanho inicial de 100 MB e que é extendido em blocos de 8 MB quando o espaço acabar. Se o disco ficar cheio você pode querer adicionar outro arquivo de dados a outro disco, por exemplo. Então você tem que olhar o tamanho de ibdata1
, arredondar o tamanho para baixo até o múltiplo de 1024 * 1024 bytes (= 1 MB) mais próximo, e especificar o tamanho arredondado de ibdata1
explicitamente em innodb_data_file_path
. Depois disto você pode adicionar outros arquivos de dados:
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
Tenha cuidado com sistema de arquivos onde o tamanho máximo do arquivo é 2 GB. O InnoDB não está ciente disto. Neste sistemas de arquivos você pode querer especificar o tamanho máximo para o arquivo de dados:
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:100M:autoextend:max:2000M
Um exemplo de my.cnf
simples. Suponha que você tenha um computador com 128 MB RAM e um disco rígido. Abaixo está o exemplo dos parâmetros de configuração possíveis para my.cnf
ou my.ini
para o InnoDB. Nós consideramos que você está executando MySQL-Max-3.23.50 ou posterior, our MySQL-4.0.2 ou posterior. Este exemplo serve para a maioria dos usuários, tanto em Unix e Windows, que não querem distribuir arquivos de dados InnoDB e arquivos de log em vários discos. Isto cria um arquivo de dados ibdata1
auto-extensível e dois arquivos de log ib_logfile0
e ib_logfile1
do InnoDB no datadir
do MariaDB (normalmente /mysql/data
). O arquivo de log ib_arch_log_0000000000
do InnoDB também fica em datadir
.
[mysqld] # Você pode escrever outras opções do servidor MariaDB aqui # ... # Arquivos de dados deve estar aptos # a guardar os seus dados e índices. # Esteja certo que você tem espaço # livre suficiente em disco. innodb_data_file_path = ibdata1:10M:autoextend # Defina o tamanho da área de buffer com # 50 - 80 % da meória do seu computador set-variable = innodb_buffer_pool_size=70M set-variable = innodb_additional_mem_pool_size=10M # Defina o tamanho do seu arquivo log # para 25 % da tamanho da área de buffer set-variable = innodb_log_file_size=20M set-variable = innodb_log_buffer_size=8M # Defina ..flush_log_at_trx_commit # com 0 se você puder perder # algumas das ultimas trnsações innodb_flush_log_at_trx_commit=1
Check that the MariaDB server has the rights to create files in datadir
.
Note que os arquivo de dados devem ser < 2 GB em alguns sistemas de arquivos! O tamanho combinado do arquivos de log devem ser < 4 GB. O tamanho combinado dos arquivos de dados devem ser >= 10 MB.
Quando você criar um banco de dados pela primeira vez, é melhor que você inicie o servidor MariaDB do prompt de comando. Então InnoDB irá imprimir a informação sobre a criação do banco de dados na tela e você poderá ver o que está acontecendo. Veja abaixo na próxima seção como a saída na tela se parece. Por exemplo, no Windows você pode iniciar mysqld-max.exe
com:
your-path-to-mysqld\mysqld-max --console
Onde colocar o my.cnf
ou my.ini
no Windows? As regras para o Windows são o seguinte:
- Apenas o
my.cnf
oumy.ini
deve ser criado. - O arquivo
my.cnf
deve ser colocado no diretótio raiz do driveC:
. - O arquivo
my.ini
deve ser colocado no diretório WINDIR, e.g,C:\WINDOWS
ouC:\WINNT
. Você pode usar o comandoSET
do MS-DOS para imprimir o valor de WINDIR. - Se o seu PC utiliza um carrgador de boot onde o drive
C:
não é o drive de boot, então a sua única opçào é usar o arquivomy.ini
.
Onde especificar as opções no Unix? No Unix o mysqld
lê opções dos seguintes arquivos, se eles existirem, na seguinte ordem:
/etc/my.cnf
Opções globais.COMPILATION_DATADIR/my.cnf
Opções específicas do servidor.defaults-extra-file
O arquivo especificado com--defaults-extra-file=...
.~/.my.cnf
Opções específicas do usuário
COMPILATION_DATADIR
é o dirertório de dados do MariaDB o qual foi especificado como uma opção do ./configure
quando o mysqld
foi compilado. (normalmente /usr/local/mysql/data
para uma instalação binária ou /usr/local/var
para uma instalação fonte).
Se você não estiver certo de onde mysqld
lê o seu my.cnf
ou my.ini
, você pode dar o caminho como a primeira opção de linha de comando para o servidor: mysqld --defaults-file=your_path_to_my_cnf
.
O InnoDB forma o caminho do diretório a um arquivo de dados concatenando textualmente innodb_data_home_dir
a um nome de arquivo de dados ou caminho em innodb_data_file_path
, adicionando uma possível barra ou barra invertida entre eles se for necessário. Se a palavra-chave innodb_data_home_dir
não é mencionada em my.cnf
, o padrão para ele é o diretório 'ponto' ./
que significa o datadir
de MySQL.
Um exemplo de my.cnf
avançado. Suponha que você tenha um computador Linux com 2 GB RAM e três disco rígidos de 60 GB (no caminho de diretórios /
, /dr2
e /dr3
). Abaixo esta um exemplo de parâmetros de configuração possíveis no arquivo my.cnf
para o InnoDB.
Note que o InnoDB não cria diretórios: você mesmo deve criá-los. Use o comando mkdir
do Unix ou MS-DOS para criar o diretório base do grupo de dados e de log.
[mysqld] # Você pode escrever outras opções do servidor MariaDB aqui # ... innodb_data_home_dir = # Os arquivos de devem estar aptos a # guardar seus dados e índices innodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend # Defina o tamanho da área de buffer para # 50 - 80 % da memória do seu computador, # mas esteja certo, no Linux x86, que o # total de memória usada é < 2 GB set-variable = innodb_buffer_pool_size=1G set-variable = innodb_additional_mem_pool_size=20M innodb_log_group_home_dir = /dr3/iblogs # .._log_arch_dir deve ser o mesmo # que .._log_group_home_dir innodb_log_arch_dir = /dr3/iblogs set-variable = innodb_log_files_in_group=3 # Defina o tamanho do arquivo de log # para cerca de 15% do tamanho da # área da buffer set-variable = innodb_log_file_size=150M set-variable = innodb_log_buffer_size=8M # Defina ..flush_log_at_trx_commit com # 0 se você puder permitir a perda de # algumas das ultimas transações. innodb_flush_log_at_trx_commit=1 set-variable = innodb_lock_wait_timeout=50 #innodb_flush_method=fdatasync #set-variable = innodb_thread_concurrency=5
Note que nós colocamos os dois arquivos de dados em discos diferentes. O InnoDB preencherá o tablespace de tabela formado pelos arquivos de dados de baixo para cima. Em alguns casos ele aumentará o desempenho do banco de dados se todos os dados não forem colocados no mesmo disco físico. Colocar os arquivos de log em discos diferentes dos de dados é geralmente, benéfico para o desempenho. Você pode usar partições de discos raw (dispositivos raw) como arquivos de dados. Em alguns Unixs eles aumentam a E/S. Vejam a seção sobre gerenciamento de espaço de arquivos no InnoDB para saber como especificá-los no my.cnf
.
Aviso: no Linux x86 você deve ter cuidado par não definir um uso de memória muito alto. glibc permitirá que o área do processo cresça acima da pilha da thread, o que fará com que o seu servidor falhe. Isto é um risco se o valor de
innodb_buffer_pool_size + key_buffer + max_connections * (sort_buffer + read_buffer_size) + max_connections * 2 MB
é próximo de 2 GB ou exceda 2 GB. Cada thread usará uma pilha (geralmente 2 MB, mas no binário da MariaDB Foundation é somente 256 KB) e no pior caso usará tmabém sort_buffer + read_buffer_size
de memória adicional.
Como sintonizar outros parâmetros do servidor mysqld
? Valores comuns que servem para a maioria dos usuários são:
skip-locking set-variable = max_connections=200 set-variable = read_buffer_size=1M set-variable = sort_buffer=1M # Defina key_buffer com 5 - 50% # de sua RAM dependendo de quanto # você usa tabelas MyISAM, mas # mantenha key_buffer + tamanho da # área de buffer do InnoDB < 80% de # sua RAM set-variable = key_buffer=...
Note que alguns parâmetros são dados usando o formato do parâmetro numérico de my.cnf
: set-variable = innodb... = 123
, outros (parâmetros string e booleanos) com outro formato: innodb_... = ...
.
O significado dos parâmetros de configuração são os seguintes:
Opção | Descrição |
innodb_file_per_table |
Disponível a partir da versão 4.1.1. Esta opção faz com que o InnoDB armazene cada tabela criada em seu próprio arquivo .ibd . Veja a seção sobre multiplos tablespaces. |
innodb_data_home_dir |
A parte comum do caminho do diretório para todos arquivos de dados InnoDB. Se você não mencionar esta opção em my.cnf , o padrão é o datadir do MariaDB. Você pde especificá-lo também como uma string vazia, e neste caso você poderá utilizar caminhos de arquivos absolutos em innodb_data_file_path . |
innodb_data_file_path |
Caminho para os arquivos de dados individuais e os seus tamanhos. O caminho do diretório completo para cada arquivo de dados é obtido concatenando innodb_data_home_dir ao caminho especificado aqui. O tamanho do arquivo é especificado em megabytes, adicionando o 'M' depois da especificação do tamanho. InnoDB também entende a abreviação 'G', 1 G significa 1024 MB. A partir da versão 3.23.44 você pode definir o tamanho do arquivo maior que 4 GB em sistemas operacionais que seuportam que suportam arquivos grandes. Em alguns sistemas operacionais arquivos devem ser menor que 2 GB. Se você não especificar innodb_data_file_path , o comportamento padrão a partir do versão 4.0 é criar um arquivo de dados ibdata1 de 10 MB auto-extensível. A soma do tamanho dos arquivos devem ser menores que 10 MB. |
innodb_mirrored_log_groups |
Número de cópias idênticas de grupos de log mantidos para os banco de dados. Atualmente deve ser definido com 1. |
innodb_log_group_home_dir |
Caminho do diretório de arquivos de log do InnoDB. Se você não mencionar esta opção no my.cnf o padrão é o datadir do MariaDB. |
innodb_log_files_in_group |
Número de arquivos de log no grupo de log. O InnoDB escreve nos arquivos de modo circular. O valor recomendado aqui é 2. O valor padrão é 2. |
innodb_log_file_size |
Tamanho de cada arquivo de log em um grupo de logs em megabytes. Faixa de valores sensíveis de 1M a 1/n-th do tamanho do área de buffer especificado abaixo, onde n é o número de arquivos de log no grupo. Quanto maior é o valor, menos atividade de descarga é necessária na área de buffer, economizando E/S de disco. Mas arquivos de log maiores também significa que a recuperação será lenta no caso de falhas. O tamanho combinado do arquivo de log deve ser menor que 4GB em comutadores de 32 bits. O padrão é 5M. |
innodb_log_buffer_size |
O tamanho do buffer que o InnoDB utiliza para escrever o log em aruivos no disco. Faixa de valores sensíveis de 1M a 8M. Um buffer de log grande permite aumentar transações para executarem sem precisar de escrever o log em até se fazer um commit da transação. iAlem disso, se você tiver grande transações, fazer um buffer de log maior economiza E/S de disco. |
innodb_flush_log_at_trx_commit |
Normalmente é atribuido 1, significando que em um commit de uma transação o log é descarregado para o disco e as modificações feitas pela transação se tornam permanentes, sobrevivendo a uma falha no banco de dados. Se você estiver disposto a comprometer esta segrança e está executando transações pequenas, você pode definí-lo com 0 ou 2 para reduzir E/S de discos nos logs. O valor 0 significa que o log só é escrito no arquivo e este é descarregado pro disco aproximadamente uma vez por segundo. O valor 2 significa que o log é escrito no arquivo a cada commit, mas o arquivo de log só é descarregado em disco aproximadamente uam vez por segundo. O valor padrão é 1 a partir do MariaDB-4.0.13; antes era 0. |
innodb_log_arch_dir |
O diretório onde arquivos de log totalmente escritos seriam escritos se usarmos arquivamento de log. Atualmente o valor deste parâmetro deve ser definido igual a innodb_log_group_home_dir . |
innodb_log_archive |
Atualmente este valor deve ser definido com 0. Como a recuperação ai partir de um backup deve ser feito pelo MariaDB usando os seus próprios arquivos de log, não há nenhuma necessidade de se arquivos os arquivos de log do InnoDB. |
innodb_buffer_pool_size |
O tamanho do buffer de memória que o InnoDB usa para armazenar dados e índices de suas tabelas. Quanto maior for este valor, menor será a necessidade de E/S de disco para acessar dados na tabela. Em um servidor de banco de dados dedicado você pode definir este parâmetro até 80% do tamanho da memória física da máquina. Não atribua um valor muito alto, pois a competição da memória física pode causar paginação no sistema operacional. |
innodb_buffer_pool_awe_mem_mb |
Tamanho da área de buffer em Mb, se estiver localizado na memória AWE do Windows 32 bits. Deiponível a partir da versão 4.1.0 e relevante apenas no Windows 32 bits. Se o seu Windows suporta mais 4GB de memória, chamado Address Windowing Extensions, você pode alolcar a área de buffer do InnoDB em uma memória física AWE usando este parâmetro. O maior valor possível para isto é 64000. Se este parâmetro for especificado, então innodb_buffer_pool_size é a janela no espaço de endereço de 32 bits do mysqld onde o InnoDB mapeia aquela memória AWE. Um bom valor para innodb_buffer_pool_size é 500M. |
innodb_additional_mem_pool_size |
Tamanho do pool da memória que o InnoDB utiliza para armazenar informações de dicionário de dados e outras estruturas de dados internas. Um bom valor aqui pode ser 2M, mas quanto mais tabelas você tiver em sua aplicação, mais você precisará alocar aqui. Se o InnoDB ficar sem memória neste pool, ele l começara a alocar memória do sistema operacional e a escrever mensagens de aviso no log de erro do MariaDB. |
innodb_file_io_threads |
Número de threads de E/S de arquivos no InnoDB. Normalmente ele deve ser 4, mas no Windows E/S de disco pode se beneficiar de um número maior. |
innodb_lock_wait_timeout |
Tempo limite em segundos que uma transação InnoDB pode esperar por uma trava antes de fazer um roll back. InnodDB detecta automaticamente deadlocks de transações em sua própria tabela bloqueada e faz um roll back da transação. Se você utiliza o comando LOCK TABLES , ou outro mecanismo de armazenamento seguro com transações diferente do InnoDB na mesma transação, então um deadlock pode crescer, o que não seria notificado pelo InnoDB. Nestes casos o tempo limite é útil para resolver a situação. |
innodb_flush_method |
(Disponível a partir da versão 3.23.40.) O valor padrão para este parâmetro é fdatasync . Outra opção é O_DSYNC . |
innodb_force_recovery |
Aviso: esta opção só deve ser definida em uma situação de emergência quando você quiser um dump de suas tabelas em um banco de dados corropido! Os valores possíveis são de 1 - 6. Veja abaixo na seção 'Forçando a recuperação' sobre o significado dos valores. Como uma medida segura o InnoDB previne que um usuário modifique os dados quando esta opção é > 0. Esta opção está disponível a partir da versão 3.23.44. |
Criando Tablespaces no InnoDB
- Se Alguma Coisa Der Errado Na Criação Do Banco de Dados
Suponha que você instalou o MariaDB e editou my.cnf
para que ele contenha os parâmetros de configuração do InnoDB necessários. Antes de iniciar o MariaDB você deve verificar se os diretórios que você especificou para os arquivos de dados e de log do InnoDB existem e se você tem direito de acesso a estes diretórios. InnoDB não pode criar diretórios, apenas arquivos. Verifique também se você têm espaço suficiente em disco para or arquivos de dados e de log.
Quando iniciar o MySQL, InnoDB começara criando os seus arquivos de dados e de log. O InnoDB irá imprimir algo como o mostrado a seguir:
~/mysqlm/sql > mysqld InnoDB: The first specified datafile /home/heikki/data/ibdata1 did not exist: InnoDB: a new database to be created! InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728 InnoDB: Database physically writes the file full: wait... InnoDB: datafile /home/heikki/data/ibdata2 did not exist: new to be created InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000 InnoDB: Database physically writes the file full: wait... InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist: new to be created InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size to 5242880 InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist: new to be created InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size to 5242880 InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist: new to be created InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880 InnoDB: Started mysqld: ready for connections
Um novo banco de dados InnoDB foi criado. Você pode se conectar ao servidor MariaDB com o programa cliente MariaDB de costume como MariaDB
. Quando você finaliza o servidor MariaDB com mysqladmin shutdown
, a saída do InnoDB será como a seguinte:
010321 18:33:34 mysqld: Normal shutdown 010321 18:33:34 mysqld: Shutdown Complete InnoDB: Starting shutdown... InnoDB: Shutdown completed
Agora você pode ver os diretórios de arquivos de dados e logs e você verá os arquivos criados. O diretório de log também irá conter um pequeno arquivo chamado ib_arch_log_0000000000
. Este arquivo foi resultado da criação do banco de dados, depois do InnoDB desligar o arquivamento de log. Quando o MariaDB for iniciado novamente, a saída será a seguinte:
~/mysqlm/sql > mysqld InnoDB: Started mysqld: ready for connections
Se Alguma Coisa Der Errado Na Criação Do Banco de Dados
Se o InnoDB imprmir um erro do sistema operacional em uma operação de arquivo normalmente o problema é um dos seguintes:
- Você não criou os diretórios de dados e de logo do InnoDB.
mysqld
não tem o direito de criar arquivos neste diretório.mysqld
não le o arquivomy.cnf
oumy.ini
corretom e consequentemente não enxerga as opções que você especificou.- O disco está cheio ou a quota de disco foi excedida.
- Você criou um subdiretório cujo nome é igual ao arquivo de dados que você especificou.
- Existe um erro de sintaxe em
innodb_data_home_dir
ouinnodb_data_file_path
.
Se ocorrer algum erro na criação de banco de dados InnoDB, você deve deletar todos os arquivos criados pelo InnoDB. Isto significa todos os arquivos de dados, de log, o pequeno log arquivado e no caso de você já ter criado algumas tableas InnoDB, delete também os arquivos .frm
correspondentes a estas tabelas do diretório de banco de dados do MariaDB. Então você pode tentar criar o banco de dados InnoDB novamente.
Criando Tabelas InnoDB
- Convertendo Tabelas MyISAM para InnoDB
- Restrições
FOREIGN KEY
- Multiplos tablespaces - colocando cada tabela em seu próprio arquivo .ibd
Suponha que você tenha iniciado o cliente MariaDB com o comando mysql test
. Para criar uma tabela no formato InnoDB você deve especificar TYPE = InnoDB
no comando SQL de criação da tabela:
CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
Este comando SQL criará uma tabela e um índice na coluna A
no tablespace do InnoDB consistindo dos arquivos de dados que você especificou em my.cnf
. Adicionalmente o MariaDB criará um arquivo CUSTOMER.frm
no diretório de banco de dados test
do MariaDB. Internamente, InnoDB adicionará ao seu próprio diretório de dados uma entrada para tabela 'test/CUSTOMER'
. Assim você pode criar uma tabela de mesmo nome CUSTOMER
em outro banco de dados do MariaDB e os nomes de tabela não irão colidir dentro do InnoDB.
Você pode consultar a quantidade de espaço livre no tablespace do InnoDB utilizabdo o comando de status da tabela do MariaDB para qualquer tabela que você criou com TYPE = InnoDB
. Então a quantidade de espaço livre no tablespace aparecerá na seção de comentário da tabela na saída de SHOW
. Um exemplo:
SHOW TABLE STATUS FROM test LIKE 'CUSTOMER'
Note que a estatísticas SHOW
dada sobre tabelas InnoDB são apenas aproximadas: elas não são usadas na otimização SQL. Tamanho reservado de tabelas e índices em bytes estão acurado.
Convertendo Tabelas MyISAM para InnoDB
O InnoDB não tem uma otimização especial para criação de índices separados. Assim não há custo para exportar e importar a tabela e criar índices posteriormente. O modo mais rápido de se alterar uma tabela para InnoDB é fazer as inserções diretamente em uma tabela InnoDB, isto é, use ALTER TABLE ... TYPE=INNODB
, ou crie uma tabela InnoDB vazia com definições idênticas e insira os registro com INSERT INTO ... SELECT * FROM ...
.
Para obter um melhor controle sobre o processo de inserção, pode ser bom inserir grandes tabelas em pedaços:
INSERT INTO newtable SELECT * FROM oldtable WHERE yourkey > something AND yourkey <= somethingelse;
Depois de todos os dados serem inseridos você pode renomear as tabelas.
Durante a canversão de tabelas grandes você deve configurar á área de buffer com um tamanho grande para reduzir a E/S de disco. Não deve ser maior que 80% da memória física. Você deve configurar o arquivo de log do InnoDB grande, assim como o buffer de log.
Certifique-se de que você não irá ocupar todo o tablespace: tabelas InnoDB gasta muito mais espaço que tabelas MyISAM. Se um ALTER TABLE
ficar sem espaço, ele irá iniciar um rollback, que pode levar horas se ele estiver no limite de disco. Para inserções, o InnoDB utiliza o buffer de inserção para fundir registros de índices secundários a índices em grupos. Isto economiza muito a E/S de disco. No rollback tal mecanismo não é usado e o rollback pode demorar 30 vezes mais que a inserção.
No caso de um rollback demorado, se você não tiver dados valiosos e seu banco de dados, é melhor que você mate o processo de banco de dados, delete todos os arquivos de dados e de log do InnoDB e todos os arquivos de tabela .frm
e inicie o seu trabalho de novo, do que esperar que milhões de E/Ss de disoc de complete.
Restrições FOREIGN KEY
A partir da versão 3.23.43b, o InnoDB disponibiliza restrições de chaves estrangeiras. O InnoDB é o primeiro tipo de tabela da MySQL, que permite definir restrições de chaves estrangeiras para guardar a integridade dos seus dados.
A sintaxe da definição das restriçõess de chaves estrangeiras no InnoDB:
[CONSTRAINT [symbol]] FOREIGN KEY (index_col_name, ...) REFERENCES nome_tabela (index_nome_coluna, ...) [ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}] [ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
Ambas as tabelas devem ser do tipo InnoDB, na tabela deve existir um índice onde as colunas de chaves estrangeiras listadas como as PRIMEIRAS colunas e na tabela indicada deve haver um índice onde as colunas indicadas são listadas como as PRIMEIRAS colunas e na mesma ordem. O InnoDB não cria índices automaticamente em chaves estrangeiras para chaves referênciadas: você tem que criá-las explicitamente. Os índices são necessários para verificação de chaves estrangeiras para ser rápido e não exigir a varredura da tabela.
Colunas correspondentes nas chaves estrangeiras e a chave referenciada devem ter tipos de dados internos parecidos dentro do InnoDB para que possam ser comparados sem uma conversão de tipo. O tamanho e a sinalização de tipos inteiros devem ser o mesmo. O tamanho do tipos string não precisam ser o mesmo. Se você especificar uma ação SET NULL
, esteja certo de que você não declarou as colunas na tabela filha como NOT NULL
.
Se o MariaDB retornar o erro de número 1005 de uma instrução CREATE TABLE
, e a string de mensagem de erro se referir ao errno 150, então a criação da tabela falhou porque um restrição de chaves estrangeiras não foi formada corretamente. Similarmente, se uma ALTER TABLE
falhar e se referir ao errno 150, sgnifica que um definição de chave estrangeira foi formada incorretamente na tabela alterada. A partir da versão 4.0.13, você pode usar SHOW INNODB STATUS
para ver uma explicação detalhada do ultimo erro de chave estrangeira do InnoDB no servidor.
A partir de versão 3.23.50, InnoDB não verifica restrições de chaves estrangeiras naqueles valores de chaves estrangeiras ou chaves referênciadas que contenham uma coluna NULL.
Um desvio do padrão SQL: se na tabela pai existirem diversos registros têm o mesmo valor de chave referência, então o InnoDB atua na verificação da chave estrangeira como o outro registro pai como se o mesmo valor de chave não existisse. Por exemplo, se você tiver definido uma restrição de tipo RESTRICT
, e existir um registro filho com diversos registros pais, o InnoDB não permite a deleção de qualquer um dos registros pais.
A partir da versão 3.23.50, você também pode associar a cláusula ON DELETE CASCADE
ou ON DELETE SET NULL
com a restrição de chave estrangeira. Opções correspondentes do ON UPDATE
estão disponíveis a partir da versão 4.0.8. Se ON DELETE CASCADE
for especificado, e um registro na tabela pai for deletado, então o InnoDB automaticamente também deleta todos aqueles registros na tabela filha cujos valores de chaves estrangeiras são iguais ao valor da chave referênciada no registro pai Se ON DELETE SET NULL
for especificado, os registros filhos são automaticamente atualizados e assim as colunas na chave estrangeira são definidas com o valor NULL
do SQL.
Um desvio dos padrões SQL: se ON UPDATE CASCADE
ou ON UPDATE SET NULL
retornam para atualizar a MESMA TABELA que ja tenha sido atualizada durante o processo cascata, ele atua como RESTRICT
. Isto é para prevenirloops infinitos resultantes de atualizações em cascata. Um ON DELETE SET NULL
auto referêncial, por outro lado, funciona desde a versão 4.0.13. ON DELETE CASCADE
auto referêncial já está funcionando.
Um exemplo:
CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB; CREATE TABLE child(id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE SET NULL ) TYPE=INNODB;
Um exemplo complexo:
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id)) TYPE=INNODB; CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB; CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, product_category INT NOT NULL, product_id INT NOT NULL, customer_id INT NOT NULL, PRIMARY KEY(no), INDEX (product_category, product_id), FOREIGN KEY (product_category, product_id) REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, INDEX (customer_id), FOREIGN KEY (customer_id) REFERENCES customer(id)) TYPE=INNODB;
A partir da versão 3.23.50 o InnoDB lhe permite adicionar novas restriçoões de chaves estrangeiras a uma tabela.
ALTER TABLE seunomedetabela ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES anothertablename(...) [on_delete_and_on_update_actions]
Lembre-se de criar os índices necessários primeiro.
A partir da versão 4.0.13, o InnoDB suporta
ALTER TABLE suatabela DROP FOREIGN KEY id_chave_estrangeira_gerada_internamente
Você tem que usar SHOW CREATE TABLE
para daterminar as id's de chaves estrangeiras geradas internamente quando você apaga uma chave estrangeira.
Na versão anterior a 3.23.50 do InnoDB, ALTER TABLE
ou CREATE INDEX
não devem ser usadas em conexões com tabelas que têm restrições de chaves estrangeiras ou que são referênciadas em restrições de chaves estrangeiras: Qualquer ALTER TABLE
remove todas as restrições de chaves estrangeiras definidas na tabela. Você não deve utilizar ALTER TABLE
para tabela referenciadas também, mas utilizar DROP TABLE
e CREATE TABLE
para modifcar o esquema. Quando o MariaDB faz um ALTER TABLE
ele pode usar internamente RENAME TABLE
, e isto irá confundir a restrição de chave estrangeira que se refere a tabela. Uma instrução CREATE INDEX
é processada no MariaDB como um ALTER TABLE
, e estas restrições também se aplicam a ele.
Ao fazer a verificação de chaves estrangeiras, o InnoDB define o bloqueio a nivel de linhas compartilhadas em registros filhos e pais que ele precisa verificar. O InnoDB verifica a restrição de chaves estrangeiras imediatamente: a verificação não é aplicada no commit da transaçao.
Se você quiser ignorar as restrições de chaves estrangeiras durante, por exemplo um operação LOAD DATA
, você pode fazer SET FOREIGN_KEY_CHECKS=0
.
O InnoDB lhe permite apagar qualquer tabela mesmo que ela quebre a restrição de chaves estrangeira que referencia a tabela. Ao apagar um tabela restrição que é definida na instrução create também é apagada.
Se você recriar uma tabela que foi apagada, ela deve ter uma definição de acordo com a restrição de chaves estrangeiras que faz referência a ela. Ela deve ter os nomes e tipos de colunas corretor e deve ter os índices na chave referenciada como indicado acima. Se esta condição não for satisfeita, o MariaDB retornará o erro de número 1005 e se refere ao errno 150 na string de mensagem de erro.
A partir da versão 3.23.50 o InnoDB retorna da definição de chave estrangeira de uma tabela quando você chama
SHOW CREATE TABLE seunometabela
Assim o mysqldump
também produz as difinições de tabelas corretas no arquivo dump e não se esquece das chaves estrangeiras.
Você também pode listar as restrições de chaves estrangeiras de uma tabela T
com
SHOW TABLE STATUS FROM seubancodedados LIKE 'T'
As restrições de chaves estrangeiras são listadas no comentário da tabela impresso na saída.
Multiplos tablespaces - colocando cada tabela em seu próprio arquivo .ibd
NOTA IMPORTANTE: se você atualizar para o InnoDB-4.1.1 ou posterior, será difícil retornar a versão 4.0 ou 4.1.0! Isto ocorre porque versões anteriores do InnoDB não permitem vários tablespaces. Se você precisar retornar para a versão 4.0, você deverá fazer um dump das tabelas e recriar todo o tablespace do InnoDB. Se você não tiver criado novas tabelas InnoDB em versões posteriores a 4.1.1, e e precisar retornar a versão anterior rapidamente, você pode fazer um downgrade direto para a versão 4.0.18 do MariaDB, ou outra da série 4.0. Antes de fazer o downgrade diretamente para a versão 4.0.xx, você terá que finalizar todas as conexões a versões >= 4.1.1 e deixar o mysqld
to run purge and the insert buffer merge to completion, so that SHOW INNODB STATUS
shows the Main thread in the state waiting for server activity
. Then you can shut down mysqld
and start 4.0.18 or later in the 4.0 series. A direct downgrade is not recommended, however, because it is not extensively tested.
Starting from MySQL-4.1.1, you can now store each InnoDB table and its indexes into its own file. This feature is called multiple tablespaces, because then each table is stored into its own tablespace.
You can enable this feature by putting the line
innodb_file_per_table
in the [mysqld]
section of my.cnf
. Then InnoDB stores each table into its own file tablename.ibd
in the database directory where the table belongs. This is like MyISAM does, but MyISAM divides the table into a data file tablename.MYD
and the index file tablename.MYI
. For InnoDB, both the data and the indexes are in the .ibd
file.
If you remove the line innodb_file_per_table
from my.cnf
, then InnoDB creates tables inside the ibdata
files again. The old tables you had in the ibdata
files before an upgrade to >= 4.1.1 remain there, they are not converted into .ibd
files.
InnoDB always needs the system tablespace, .ibd
files are not enough. The system tablespace consists of the familiar ibdata
files. InnoDB puts there its internal data dictionary and undo logs.
You CANNOT FREELY MOVE .ibd files around, like you can MyISAM tables. This is because the table definition is stored in the InnoDB system tablespace, and also because InnoDB must preserve the consistency of transaction id's and log sequence numbers.
You can move an .ibd
file and the associated table from a database to another (within the same MySQL/InnoDB installation) with the familiar RENAME
command:
RENAME TABLE olddatabasename.tablename TO newdatabasename.tablename;
If you have a clean backup of an .ibd
file taken from the SAME MySQL/InnoDB installation, you can restore it to an InnoDB database with the commands:
ALTER TABLE tablename DISCARD TABLESPACE; /* CAUTION: deletes the current .ibd file! */ <put the backup .ibd file to the proper place> ALTER TABLE tablename IMPORT TABLESPACE;
Clean in this context means:
- There are no uncommitted modifications by transactions in the
.ibd
file. - There are no unmerged insert buffer entries to the
.ibd
file. - Purge has removed all delete-marked index records from the
.ibd
file. mysqld
has flushed all modified pages of the.ibd
file from the buffer pool to the file.
You can make such a clean backup .ibd
file with the following method.
- Stop all activity from the
mysqld
server and commit all transactions. - Wait that
SHOW INNODB STATUS\G
shows that there are no active transactions in the database, and the main thread of InnoDB isWaiting for server activity
. Then you can take a copy of the.ibd
file.
Another (non-free) method to make such a clean .ibd
file is to
- Use InnoDB Hot Backup to backup the InnoDB installation.
- Start a second
mysqld
server on the backup and let it clean up the.ibd
files in the backup.
It is in the TODO to allow moving clean .ibd
files also to another MySQL/InnoDB installation. That requires resetting of trx id's and log sequence numbers in the .ibd
file.
Adicionando e Removendo Arquivos de Dados e Log do InnoDB
A partir da versão 3.23.50 e 4.0.2 você pode especificar o último arquivo de dados InnoDB com autoextend
. De forma alternativa, pode se aumentar o seu tablespace especificando um arquivo de dados adicional. Para fazer isto você tem que finalizar o servidor MySQL, edite o arquivo my.cnf
adicionando um novo arquivo de dados no final
de innodb_data_file_path
, e entao iniciar o servidor MariaDB de novo.
Atualmente você não pode remover um arquivo de dados do InnoDB. Para reduzir o tamanho de seu banco de dados você tem que utilizar mysqldump
para fazer um dump de todas as suas tabelas, criar um novo banco de dados e importar suas tabelas para um novo banco de dados.
Se você quiser alterar o número ou o tamanho do seu arquivo de log InnoDB, você tem que finalizar o MariaDB e certificar que ele finalizou sem erros. Copie então o arquivo de log antigo em um local seguro apenas para o caso de algo der errado ao finalizar e você precisar recuperar o banco de dados. Delete os arquivos de log antigo do diretório de arquivos de logm edite o my.cnf
e inicie o MariaDB novamente. O InnoDB lhe dirá no inicio que ele está criando novos arquivos de log.
Fazendo Backup e Recuperando um Banco de Dados InnoDB
- Forçando a recuperação
- Ponto de Verificação
A chave para um gerenciamento seguro de banco de dados é tirar backups regularmente.
O InnoDB Hot Backup é uma ferramenta de backup online que você pode utilizar pra fazer backup dos seus banco de dados InnoDB enquanto ele está executando. O InnoDB Hot Backup não exige que você finalize o seu banco de dados e não realiza nenhum bloqueio ou cria disturbio no seu processo normal de banco de dados. O InnoDB Hot Backup é uma ferramenta adcional paga e que não está incluída na distribuição padrão do MariaDB. Veja o site do InnoDB Hot Backup http://www.innodb.com/manual.php para informações detalhadas e telas do produto.
Se você puder desativar o servidor MySQL, então, para fazer um backup de 'binario' do seu banco de dados você deve fazer o seguinte:
- Finalize o seu banco de dados MariaDB e certifique-se de que ele finalizou sem erros.
- Copie todos os seus arquivos de dados em um local seguro.
- Copie todos os seus arquivos de log do InnoDB em um local seguro.
- Copie o(s) seu(s) arquivo(s) de configuração
my.cnf
em um local seguro. - Copie todos os arquivos
.frm
da suas tabelas InnoDB em um local seguro.
Além de fazer um backup de binário descrito acima, você também deve fazer um dump da sua tabela com mysqldump
. A razão para se fazer isto é que um arquivo binário pode ser corrompido cem você perceber. Dumps de tabelas são armazenados em um arquivo texto legível e muito mais simples que arquivos binários de banco de dados. Ver tabelas corropidas através de arquivos de dump é mais fácil e, como o seu formato é simples, a chance dos dados se corromperem seriamente são bem menores.
Uma boa idéia é fazer dumps ao mesmo tempo que você faz o backup de binário do seu banco de dados. Você tem que fechar todos os bancos de dados nos clientes para ter uma cópia consistente de todas as suas tabelas em seu dump. Então você pode fazer o backup de binário e você terá uma cópia consistente de seu banco de dados em dois formatos.
Para se poder recuperar o seu banco de dados InnoDB através do backup de binário descrito acima, você tem que executar o seu banco de dados MariaDB com o sistema de log geral e o arquivamento de log do MariaDB ligado. Com sistema de log geral nós queremos dizer o mecanismo de log do servidor MariaDB que é independente dos logs do InnoDB.
Para recuperação de falhas do seu processo do servidor MySQL, a única coisa que você deve fazer é reiniciá-lo. InnoDB verificará automaticamente os logs e realizará um roll-forward do banco de dados para o situação atual. O InnoDB fará automaticamente um roll back de transações sem commit existentes no momento da falha. Durante a recuperação, InnoDB irá imprimir algo como o seguinte:
~/mysqlm/sql > mysqld InnoDB: Database was not shut down normally. InnoDB: Starting recovery from log files... InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 0 13674004 InnoDB: Doing recovery: scanned up to log sequence number 0 13739520 InnoDB: Doing recovery: scanned up to log sequence number 0 13805056 InnoDB: Doing recovery: scanned up to log sequence number 0 13870592 InnoDB: Doing recovery: scanned up to log sequence number 0 13936128 ... InnoDB: Doing recovery: scanned up to log sequence number 0 20555264 InnoDB: Doing recovery: scanned up to log sequence number 0 20620800 InnoDB: Doing recovery: scanned up to log sequence number 0 20664692 InnoDB: 1 uncommitted transaction(s) which must be rolled back InnoDB: Starting rollback of uncommitted transactions InnoDB: Rolling back trx no 16745 InnoDB: Rolling back of trx no 16745 completed InnoDB: Rollback of uncommitted transactions completed InnoDB: Starting an apply batch of log records to the database... InnoDB: Apply batch completed InnoDB: Started mysqld: ready for connections
Se o seu banco de dados for corrompido ou o seu disco falhar, você terá que fazer recuperações de um backup. no caso de dados corropidos, você deve primeiro encontrar um backup que não está corrompido. A partir de um backup, faça a recuperação a partir do arquivo de logs gerais do MariaDB de acordo com a instrução no manual do MariaDB.
Forçando a recuperação
Se ocorre o corrompimento de uma página do banco de dados, você pode desejar fazer um dump de suas tabelas no banco de dados com SELECT INTO OUTFILE
, e normalmente a maioria dos dados estará intacto e correto. Mas o corrompimento pode fazer com que SELECT * FROM table
, ou operações de background do InnoDB falhe ou apresentem avisos, ou até mesmo a recuperação roll-forward do InnoDB falhe. A partir do InnoDB 3.23.44, existe uma opção do my.cnf
com a qual você pode forçar o InnoDB a inicializar, e você também pode prevenir que operações de background sejam executadas, e assim você poderá fazer um dump de suas tabelas. Por exemplo, você pode configurar
set-variable = innodb_force_recovery = 4
no my.cnf
.
As alternativas para innodb_force_recovery
estão listadas abaixo. O banco de dados não deve ser usado com estas opções! Como medida de segurança o InnoDB previne um usuário de fazer um INSERT
, UPDATE
, ou DELETE
quando esta opção é > 0.
A partir da versão 3.23.53 e 4.0.4, você tem permissão de se fazer um DROP
ou CREATE
de uma tabela mesmo se a recuperação forçada está sendo usada. Se você sabe que determinada tabela está causando uma falha no rollback, você pode deletá-la. Você pode usar isto também para para um rollback em execução causado por uma falha importanta ou ALTER TABLE
. Você pode matar o processo mysqld e usar a opção do my.cnf
innodb_force_recovery=3
para trazer o seu banco de dados sem o rollback. Apague então a tabela que está causando o rollback.
Um número maior abaixo significa que todas as precauções de números menores estão incluídas. Se você puder fazer um dump de todas as suas tabelas com uma opção de no máximo 4, então você está relativamente seguro que apenas alguns dados em paginas individuais corrompidas são perdidos. A opção 6 é mais dramática, porque páginas de bancos de dados são deixadas e um estado obsoleto, que podem introduzir mais corrompimento em árvores-B e outras estruturas de banco de dados.
- 1 (SRV_FORCE_IGNORE_CORRUPT) deixa o servidor executar mesmo se ele detectar uma página corrompida; tenta fazer
SELECT * FROM table
saltar os índices corrompidos e páginas, o que ajuda ao fazer dump de tabelas; - 2 (SRV_FORCE_NO_BACKGROUND) evita que a thread principal seja executada: se uma falha ocorresse na remoção, isto seria evitado.
- 3 (SRV_FORCE_NO_TRX_UNDO) não executa rollback de transações depois da recuperação;
- 4 (SRV_FORCE_NO_IBUF_MERGE) também previne operações merge no buffer de inserções: se eles causassem falhar, melhor não fazê-los; não calcula as estatísticas da tabelas;
- 5 (SRV_FORCE_NO_UNDO_LOG_SCAN) não procura por undo logs quando iniciar o banco de dados: InnoDB tratará mesmo transações incompletas como comitadas;
- 6 (SRV_FORCE_NO_LOG_REDO) não faça o roll-forward no log em em conexão com recuperação.
Ponto de Verificação
O InnoDB implementa um mecanismo de ponto de verificação chamado fuzzy checkpoint. O InnoDB descarregará páginas de banco de dados modificados da áres de buffer em pequenos grupos. Não há necessidade de descarregar a área de buffer em um único grupo, o que iria, na prática, para o processamento da instrução SQL do usuário por um instante.
Na recuperação de falhas o InnoDB procura por um rotulo de ponto de verificação escrito nos arquivos de log. Ele sabe que todas as modificações no banco de dados anteriores ao rótulo já estão presentes na imagem em disco do banco de dados. O InnoDB varre os arquivos de log a partir do ponto de verificação apicando as modificações registradas no banco de dados.
O InnoDB escreve no arquivo de log de um modo circular. Todas as modificações efetivadas que tornam a pagina de banco de dados na área de buffer diferente das imagens em disco devem estar disponíveis no arquivo de log no caso do InnoDB precisar fazer uma recuperação. Isto significa que quando O InnoDB começa a reutilizar um arquivo de log no modo circular, ele deve estar certo de que imagens em disco da pagina de banco de dados já contém as modificações registradas no arquivo de log que o InnoDM irá utilizar. Em outras palavras, o InnoDB precisa criar um ponto de verificação e geralmente isto envolve descarga de páginas de banco de dados modificados para o disco.
O exposto acima explica o porque que fazer o seu arquivo de log muito maior pode economizar E/S de disco com pontos de verificação. Pode fazer sentido configurar o tamanho do arquivo de log tão grande quanto a àrea de buffer ou mesmo maior. O problema com arquivos de log grandes é que a recuperação de falhas pode ser mais demorada pois haverá mais itens a se aplicar ao banco de dados.
Movendo um Banco de Dados InnoDB para Outra Máquina
No Windows o InnoDB armazena os nomes de banco de dados e tabelas internamente sempre em letras minúsculas. Para mover bancos de dados em um formato binário do Unix para o Windows ou do Windows para o Unix você deve ter todas os nomes de tabelas e banco de dados em letras minúscula. Um modo conveniente de fazer isto é adicionar no Unix a linha
set-variable=lower_case_table_names=1
na seção [mysqld]
de seu my.cnf
antes de você iniciar a criação de sua tabela. no Windows o valor 1 é o padrão.
Arquivos de dados e log do InnoDB são binários compatíveis com todas as plataformas se o formato do número de ponto flutuante nas máquinas é o mesmo. Você pode mover um banco de dados InnoDB simplesmente copiando todos os arquivos relevantes, os quais nós já listamos na seção anterior sobre backup do banco de dados. Se o formato de ponto flutuante nas máquinas são diferentes mas você não utiliza tipos de dados FLOAT
ou DOUBLE
em suas tabelas então o procedimento é o mesmo; apenas copie os arquivos relevantes. Se os formatos são diferentes e suas tabelas contenham dados de ponto flutuante, você tem que utilizar mysqldump
e mysqlimport
para mover estas tabelas.
Uma dica de desempenho é desligar o modo auto-commit quando você importa dados em seu banco de dados, assumindo que o seu tablespace tem espaço suficiente para o grande segmento de roolback que a transação de importação ira gerar. Só faça o commit depois de importar toda a tabela ou um segmento de uma tabela.
Modelo Transacional do InnoDB
- InnoDB e
SET ... TRANSACTION ISOLATION LEVEL ...
- Leitura Consistente sem Lock
- Lock de Leitura
SELECT ... FOR UPDATE
eSELECT ... LOCK IN SHARE MODE
- Lock da Chave Seguinte: Evitando Problemas com Fantasmas
- Locks Definidos por Diferentes Instruções SQL no
InnoDB
- Detecção de Deadlock e Rollback
- Um Exemplo de Como a Leitura Consistente Funciona no
InnoDB
- Como lidar com deadlocks?
No modelo transacional do InnoDB
o objetivo é combinar as melhores propriedades de um banco de dados multi-versioning a um bloqueio de duas fases tradicional. O InnoDB
faz bloqueio a nivel de registro e execulta consultas como leitura consistente sem bloqueio, por padrao, no estilo do Oracle. A tabela travada no InnoDB é armazenada com tanta eficiência em relação ao espaço que a escala de bloqueio não é necessária: normalmente diversos usuários tem permissão para bloquear todos os registros no banco de dados, ou qualquer subconjunto aleatório de regitsros, sem que o InnoDB
fique sem memória.
No InnoDB
todas as atividades de usuários acontecem dentro de transações. Se o modo autocommit é usado no MySQL, então cada instrução SQL forma uma única transação. O MariaDB sempre inicia uma nova conexão com o modo autocommit ligado.
Se o modo autocommit é desligado com SET AUTOCOMMIT = 0
, então podemos achar que um usuário sempre tem uma transação aberta. Se for executada uma instrução SQL COMMIT
ou ROLLBACK
, a transação atual é finalizada e uma nova é iniciada. Ambas instruções liberarão todas as travas do InnoDB
que foram definidas durante a transação atual. Um COMMIT
significa que as alterações feitas na transação atual se tornam permanentes e visíveis a outros usuários. Uma instrução ROLLBACK
, por outro lado, cancela todas as modificações feitas pela transação corrente.
Se a conexão tem AUTOCOMMIT = 1
, então o usuário pode ainda relaizar uma transação multi-instrução iniciando-a com START TRANSACTION
ou BEGIN
e finalizando-a com COMMIT
ou ROLLBACK
.
InnoDB e SET ... TRANSACTION ISOLATION LEVEL ...
Em termos de níveis de isolamento transacional SQL-92, o padrão InnoDB
é REPEATABLE READ
. A partir da versão 4.0.5, InnoDB
oferece todos os níveis de isolamento transacional diferentes descritos pelo padrão SQL-92. Você pode definir o nível de isolamento padrão para todas as conexões na seção [mysqld]
do my.cnf
:
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}
Um usuário pode alterar o nível de isolamento de um única seção ou todas as próximas seções com a instrução SQL SET TRANSACTION
. Sua sintaxe é a sseguinte:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
Note que não há hífens no nome dos níveis na sintaxe SQL.
O comportamento padrão é definir o nível de isolamento para a próxima transação (não iniciada). Se você especificar a palavra chave GLOBAL
na instrução acima, ela determinará o nível de isolamento globalmente para todas as novas conexões criadas a partir deste ponto (mas não conexão exitentes). Você precisa do privilégio SUPER
para fazer isto. Usar a palavra chave SESSION
difine a transação padrão para todas as transações realizadas futuramente na conexão atual. Qualquer cliente é livre para alterar o nível de isolamento da sessão (mesmo no meio de uma transação), ou o nível de isolamento para a próxima transação.
Você pode consultar o nível de isolamento da transação global ou da sessão com:
SELECT @@global.tx_isolation; SELECT @@tx_isolation;
Nos travamentos de registro, InnoDB
usa o chamado bloqueio de chave seguinte (next-key locking). Isto significa que além dos registros de índices, o InnoDB
também pode bloquear a lacuna
antes de um registro de índice para bloquear inserções por outros usuários imediatamente antes do registro de índice. Um bloqueio de chave seguinte significa um bloqueio que trava um registro de índice e a lacuna antes dele. O bloqueio de lacuna significa um bloqueio que só trava a lacuna antes do registro de índice.
Uma descrição detalhada de cada nível de isolamento em InnoDB
:
READ UNCOMMITTED
Também é chamadadirty read
:SELECT
s sem bloqueio são realizados de forma a não procurar por uma possível versão mais nova de um registro; assim as leituras não são 'consistentes' sob este nível de isolamento; de outra forma este nível funciona comoREAD COMMITTED
.READ COMMITTED
Nível de isolamento parecido com o Oracle. Todas as instruçõesSELECT ... FOR UPDATE
eSELECT ... LOCK IN SHARE MODE
só travam o registro de índice,não
a lacuna antes dele e assim permite livre inserção de novos registros próximo ao registro travado. Mas ainda no tipo de faixaUPDATE
eDELETE
, oInnoDB
deve definir lock da chave seguinte ou da lacuna e bloquear inserções feitas por outros usuários nas lacunas cobertas pela faixa. Istó é necessário já que deve se bloquearlinhas fantasmas
para a replicação e recuperação no MariaDB funcionar. Leituras consistentes (Consistent reads) comportam como no Oracle: cada leitura consistente, mesmo dentro da mesma transação, configura e lê a sua própria cópia recente.REPEATABLE READ
Este é o nível de isolamento padrão doInnoDB
.SELECT ... FOR UPDATE
,SELECT ... LOCK IN SHARE MODE
,UPDATE
, eDELETE
que utilizam um índice único com uma condição de busca única, travam apenas o registro de índice encontrado, e não a lacuna antes dele. De outra forma estas operações empregam travamento de registro seguinte, bloqueando a faixa de índice varrida com trava de chave seguinte ou de lacuna e bloqueando novas inserções feitas por outros usuários. Em leituras consistentes (consistent reads) existe uma diferença importante do nível de isolmento anterior: neste nível todas as leituras consistentes dentro da mesma transação lêem o mesma cópia estabelacido pela primeira leitura. Esta conversão significa que se você executa diversasSELECT
s dentro da mesma transação, elas também são consistentes entre elas.SERIALIZABLE
Este nível é como o anterior, mas todos osSELECT
s são convertidos implicitamente paraSELECT ... LOCK IN SHARE MODE
.
Leitura Consistente sem Lock
Uma leitura consistente significa que o InnoDB utiliza multi-versioning para apresentar a uma consulta uma cópia do banco de dados em um dado momento. O consulta verá as mudanças feitas por aquelas transações que fizeram o commit antes daquele momento e não verá nenhuma mudança feita por transações posteriores ou que fizeram o commit. A exceção a esta regra é que a consulta verá as mudanças feitas pela transação que executar a consulta.
Se você está utilizando o nível de isolamento padrão REPEATABLE READ
, então todas as leituras consistentes dentro da mesma transação lêem a mesma cópia estabelacida pela primeira leitura naquela transação. Você pode obter uma cópia recente para sua consulta fazendo um commit da transação atual e executando uma nova consulta.
Leituras consistentes é o modo padrão no qual o InnoDB processa instruções SELECT
em níveis de isolamento READ COMMITTED
e REPEATABLE READ
. Uma leitura consistentes não configura nenhuma trava em tabelas que ela acessa e assim outros usuários estão livres para modificar estas tabelas ao mesmo tempo que uma leitura consistente esta sendo feita na tabela.
Lock de Leitura SELECT ... FOR UPDATE
e SELECT ... LOCK IN SHARE MODE
Uma leitura consistente não é conveniente em alguma circunstâncias. Suponha que você queira adicionar uma nova linha em sua tabela CHILD
, e está certo que ela já possui um pai na tabela PARENT
.
Suponha que você utilize leitura consistente para ler a tabela PARENT
e certamente veja o pai do filho na tabela. Agora você pode adiciona com segurança o registro filho na tabela CHILD
? Não, porque pode ter acontecido de outro usuário ter deletado o registro pai da tabela PARENT
, e você não estar ciente disto.
A solução é realizar o SELECT
em um modo de travamento, LOCK IN SHARE MODE
.
SELECT * FROM PARENT WHERE NAME = 'Jones' LOCK IN SHARE MODE;
Realizar uma leitura em modo compartilhado significa que lemos o dado disponível por último e configuramos travas de leitura nos registros lidos. Se o este dado pertencer a uma transação de outro usuário que ainda não fez commit, esperaremos até que o commit seja realizado. Uma trava em modo compartilhado previne que ocorra atualizações ou deleções de registros já lidos. Depois de vermos que a consulta acima retornou o pai 'Jones'
, podemos com segurança adicionar o seu filho a tabela CHILD
, e realizar o commit de nossa transação. Este exemplo mostra como implementar integridade referêncial no código de sua aplicação.
Deixe-nos mostrar outro exemplo: temos um compo de contador inteiro em uma tabela CHILD_CODES
que usamos para atribuir um identificador único para cada filho que adicionamos na tabela CHILD
. Obviamente, usar uma leitura consistente ou uma leitura em modo compartilhado para ler o valor atual do contador não é uma boa idéia, já que dois usuários do banco de dados podem ver o mesmo valor para o contador e, assim, teríamos um erro de chave duplicada ao adicionarmos os dois filhos com o mesmo identificador para a tabela.
Neste caso existem dois bons modos de se implementar a leitura e o incremento do contador: (1) atualizar o contador primeiro aumentando-o de 1 e só depois disto lê-lo, ou (2) ler o contador primeiro com um modo de bloqueio FOR UPDATE
, e incrementá-lo depois disto:
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE; UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;
Um SELECT ... FOR UPDATE
irá ler o dado disponível por último atribuindo travas exclusivas a cada linha que ele ler. Assim ele atribui uma mesma trava que um UPDATE
SQL pesquisado atribuiria nos registros.
Lock da Chave Seguinte: Evitando Problemas com Fantasmas
Em um lock de registro o InnoDB utiliza um algoritmo chamado trava de chave seguinte. O InnoDB faz o lock de registro, assim quando ele faz uma busca ou varre a tabela, ele atribui travas compartilhadas ou exclusivas nos registros que ele encontra. Assim o bloqueio de registro é mais precisamente chamado lock de registro de índice.
A trava que o InnoDB atribui em registro de índices também afetas as 'lacunas' antes daquele registro de índice. Se um usuário tem uma trava compartilhada ou exclusiva no registro R em um índice, então outro usuário não pode inserir um novo registro de índice imediatamente antes de R na ordem do índice. Este bloqueio de lacunas é feito para prevenir o chamado problema de fantasma. Suponha que eu queira ler e travar todos os filhos com identificador maior que 100 da tabela CHILD
e atualizar alguns campos nos registros selecionados.
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
Suponha que exista um índice na tabela CHILD
na coluna ID
. Nossa consulta varrerá aquele índice começando do primeiro registro onde ID
é maior que 100. Agora, se a trava atribuída no registro de índice não travasse inserções feitas nas lacunas, um novo filho poderia ser inserido na tabela. Se agora eu executasse em minha transação
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
novamente, eu veria um novo filho no resultado que a consulta retorna. Isto é contra o princípio de isolamento das transações: uma transação deve executar sem que os dados que ele estaja lendo sejam alterados durante a transação. Se considerarmos um conjunto de registros como um item de dados, então o novo filho 'fantasma' quebrará o principio do isolamento.
Quando o InnoDB varre um índice ele também pode bloquear a lacuna depois do último registro no índice. Assim como no exemplo anterior: a trava atribuida pelo InnoDB irá previnir que seja feita qualquer inserção na tabela onde ID
seja maior que 100.
Você pode utilizar trava de chave seguinte para implementar uma verificação de unicidade em sua aplicação: se você ler os seus dados em modo compartilhado e não ver um registro que duplique o que você irá inserir, então você pode inserí-lo com segurança e saber que o trava de chave seguinte atribuida ao registro sucessor ao seu durante a leitura irá previnir que alguém insira um registro que duplique o seu neste intervalo. Assim a trava de chave seguinte permite que você 'bloqueie' a não existência de algo em sua tabela.
Locks Definidos por Diferentes Instruções SQL no InnoDB
SELECT ... FROM ...
: esta é uma leitura consistente, lendo uma cópia do banco de dados e não defininfo travas.SELECT ... FROM ... LOCK IN SHARE MODE
: atribui travas de chave seguinte compratilhadas em todos os regitros de índices que a leitura encontrar.SELECT ... FROM ... FOR UPDATE
: atribui travas de chave seguinte exclusivas em todos os registros de ínidices que a leitura encontra.INSERT INTO ... VALUES (...)
: atribui uma trava exclusiva em registros inseridos; note que está rava não é uma trava de chave seguinte e não previne que outros usuários insiram nas lacunas antes do registro inserido. Se um erro de chave duplicada ocorrerm, atribua uma trava compartilhada no registro de índice duplicado.INSERT INTO T SELECT ... FROM S WHERE ...
atribui uma trava exclusiva em cada linha inserida emT
. Faz a busca emS
como uma leitura consistente, mas configura travas de chave seguinte compartilhada emS
se o log do MariaDB estiver ligado. OInnoDB
tem que atribuir travas neste último caso porque em recuperações roll-forward de um backup, toda instrução SQL tem que ser executada exatamente da mesma forma que foi feito originalmente.CREATE TABLE ... SELECT ...
realiza oSELECT
como uma leitura consistente ou com travas compartilhadas, como no item anterior.REPLACE
é feita como uma inserção se não houver colisões em uma chave única. De outra forma, uma trava de chave seguinte exclusiva é colocada na linha que deve ser atualizada.UPDATE ... SET ... WHERE ...
: atribui trava de chave seguinte exclusiva em todos os registros que a busca encontrar.DELETE FROM ... WHERE ...
:atribui trava de chave seguinte exclusiva em todos os registros que a busca encontrar.- Se uma restrição
FOREIGN KEY
é definida na tabela. qualquer inserçao, atualização ou deleção que exige verificação da condição de restrição configura travas de registros compartilhados nos registros que que ele olha na verificação da restrição. Também no caso onde a restrição falha. oInnoDB
define estes bloqueios. LOCK TABLES ...
: atribui trava a tabela. Na implementação a camada MariaDB de código atribui este bloqueio. A detecção automatica de deadlocks doInnoDB
não pode ser feita onde tais travas de tabelas estão envolvidas: veja a seção seguinte. Também, uma vez que o MariaDB sabe sobre bloqueio de registros, é impossível que você obtenha um bloqueio em uma tabela na qual outro usuário tenha bloqueio de registro. Mas isto não coloca a integridade da transação em perigo. Leia 'Restrições em Tabelas InnoDB'.
Detecção de Deadlock e Rollback
O InnoDB
detecta automaticamente o deadlock de transações e faz um roll back da(s) transação(ões) para prevenir o deadlockck. A partir da versão 4.0.5, o InnoDB
tentará escolher pequenas transações para se fazer roll back. O tamanho de uma transação é determinado pelo número de linhas que foram inseridas, atualizadas ou deletadas. Antes da versão 4.0.5, InnoDB
sempre fazia roll back da transação cujo pedido de bloqueio fosse o último a criar o deadlock, isto é, um ciclo no grafo de espera da transação.
O InnoDB
não pode detectar deadlocks onde uma trava atribuida por uma instrução MariaDB LOCK TABLES
está envolvida ou se uma trava definida em outro mecanismo de banco de dados diferente de InnoDB
está envolvida. Você tem que resolver estas situações usando innodb_lock_wait_timeout
configurado em my.cnf
.
Quando o InnoDB
realiza um rollback completo de uma transação, todos as travas da transação são liberadas. No entanto, se é feito o rollback de apenas uma única instrução SQL como um resultado de um erro, algumas das travass definidas pela instrução podem ser preservadas. Isto ocorre porque o InnoDB
armazena as travas de registro em um formato onde ele não pode saber qual trava foi definida por qual instrução SQL.
Um Exemplo de Como a Leitura Consistente Funciona no InnoDB
Suponha que você esteja utilizando o nível de isolamento padrão REPEATABLE READ
. Quando você executa uma leitura consistente, isto é, uma instrução SELECT
comum, o InnoDB
dará a sua transação um ponto no tempo de acordo com o que a sua consulta viu no banco de dados Assim, se a transação B deleta uma linha e faz um commit depois que o ponto no tempo foi atribuido, então você não verá a linha deletada. Inserções e atualização são feitos de forma parecida.
Você pode avançar o seu ponto no tempo fazendo um commit da transação e fazendo outro SELECT
.
Isto é chamado controle de concorrência multi-version.
User A User B SET AUTOCOMMIT=0; SET AUTOCOMMIT=0; time | SELECT * FROM t; | empty set | INSERT INTO t VALUES (1, 2); | v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set; COMMIT; SELECT * FROM t; --------------------- | 1 | 2 | ---------------------
Assima o usuário A vê a linha inserida por B apenas quando B fizer um commit da inserção e A tiver feito um commit de sua própria transação pois assim o ponto no tempo é avançado para depois do commit de B.
Se você deseja ver o estado mais atual do banco de dados, você deve utilizar uma trava de leitura:
SELECT * FROM t LOCK IN SHARE MODE;
Como lidar com deadlocks?
Deadlocks são um problema clássico em banco de dados transacionais, mas eles não são perigosos, a menos que eles sejam tão frequentes que você não possa executar certas transações. Normalmente você tem que escrever suas aplicações de forma que elas sempre estejam preparada a reexecutar uma transação se for feito um roll back por causa de deadlocks.
O InnoDB
utiliza bloqueio automático de registro. Você pode obter deadlocks mesmo no caso de transações que inserem ou deletam uma única linha. Isto ococrre porque estas operações não são realmente 'atômicas': elas automaticamente atribuem travas aos (possivelmente muitos) registros se índices da linha inserida/deletada.
Você pode lidar com deadlocks e reduzí-lo com os seguintes truques:
- Use
SHOW INNODB STATUS
em versões do MariaDB posteriores a 3.23.52 e 4.0.3 para determinar a causa do último deadlock. Isto pode lhe ajudar a sintonizar a sua aplicação a avitar travas. - Sempre estar preparado para reexecutar uma transação se ela falhar em um deadlock. Deadlocks não sÃo perigosos. Apenas tente de novo.
- Commit sua transações com frequência. Transações pequenas têm menos chaces de colidir.
- Se você estiver utilizando as travas de leitura
SELECT ... FOR UPDATE
ou... LOCK IN SHARE MODE
, tente usar um nível de isolamente mais baixoREAD COMMITTED
. - Accesse as suas tabelas e linha em uma ordem fixa. Assim as transações formarão filas ordenadas e não entrarão em deadlock.
- Adicione índices bem escolhidos a sua tabela. Então a suas consultas precisarão varrer menos registros de índice e consequentemente atribuirão menos locks. Use
EXPLAIN SELECT
para fazer o MariaDB selecione índices apropriados a sua consulta. - Use menos locks: se você pode utilizar um
SELECT
para retornar dados de uma copia de banco de dados antiga, não adicione a cláusulaFOR UPDATE
ouLOCK IN SHARE MODE
. Usar o nível de isolamentoREAD COMMITTED
é bom aqui, pois cada leitura consistente dentro da mesma transação lê da sua própria cópia atual. - Se nada ajudar, serialize suas transações com bloqueio de tabela:
LOCK TABLES t1 WRITE, t2 READ, ... ; [faz algo com tabelas t1 e t2 aqui]; UNLOCK TABLES
. Bloqueio de tabela faz com que suas transações se enfilerem em ordem e deadlocks serão evitados. Note queLOCK TABLES
inicia implictamente uma transação, assim como o comandoBEGIN
, eUNLOCK TABLES
finaliza implicitamente uma transação em umCOMMIT
. - Outra solução para colocar transações em série é criar uma tabela 'semáforo' auxiliar onde exista apenas uma única linha. Cada transação atualiza esta linha antes de acessar outra tabela. Deste modo todas as transações acontecem em série. Note que o algoritmo de detecção automático de deadlock do
InnoDB
também funciona pois a trava de série é uma trava de registro. Na trava de tabela do MariaDB nós temos que recorrer ao método do tempo limite para resolver um deadlock.
Dicas de Ajuste de Desempenho
SHOW INNODB STATUS
e o MonitorInnoDB
- Se o aplicativo
top
do Unix ou oGerenciado de Tarefas
do Windows mostrar que percentual de uso da CPU com sua carga de trabalho é menor que 70%, provavelmente sua carga de trabalho está no limite do disco. Talvez você esteja fazendo muitos commits de transações ou a área de buffer é muito pequena. Tornar o buffer maior pode lhe ajudar, mas não o configure com mais de 80% da memória física. - Envolva diversas modificações em uma transação. O
InnoDB
deve descarregar o log em disco a cada commit da transação se esta transação fizer modificações no banco de dados. Uma vez que o velocidade de rotação do disco é normalmente 167 revoluções/segundo, o número de commits fica limitado aos mesmos 167/segundo se o disco não enganar o sistema operacional. - Se você puder ter perda dos últimos commits feitos em transações, você pode configurar o parâmetro
innodb_flush_log_at_trx_commit
no arquivomy.cnf
com 0. OInnoDB
tenta descarregar o log uma vez por segundo de qualquer forma, embora a descarga não seja garantida. - Torne os seus arquivos de log maiores, tão grande quanto a área de buffer. Quando o
InnoDB
escrever o arquivo de log totalmente, ele terá que escrever o conteúdo modificado da área de buffer no disco em um ponto de verificação. Arquivos de log menores causarão muitos escrita desnecessárias em disco. O ponto negativo em arquivos grandes é que o tempo de recuperação será maior. - O buffer de log também deve ser grande, cerca de 8 MB.
- (Relevante para versão 3.23.39 e acima.) Em algumas versões do Linux e Unix, descarregar arquivos em disco com o comando
fdatasync
do Unix e outros métodos parecido é surpreendentemente lento. O método padrão que oInnoDB
utiliza é a funçãofdatasync
. Se você não estiver satisfeito com o desempenho da escrita do banco de dados, você pode tentar configurarinnodb_flush_method
emmy.cnf
comO_DSYNC
, emboraO_DSYNC
pareça ser mais lento em alguns sistemas. - Ao importar dados para o
InnoDB
, esteja certo de que o MariaDB não está comautocommit=1
ligado. Assim cada inserção exige uma descarga de log em disco. Coloque antes da linha de importação de arquivo do SQL
SET AUTOCOMMIT=0;
e depois dele
COMMIT;
Se você utilizar a opção
mysqldump
--opt
, você obterá arquivos dump que são mais rápidos de importar também em uma tabelaInnoDB
, mesmo sem colocá-los entreSET AUTOCOMMIT=0; ... COMMIT;
. - Tome ciência dos grandes rollbacks de inserções em massa: o
InnoDB
utiliza o buffer de inserção para economizar E/S de disco em inserções, mas em um rollback correspondente tal mecanismo não é usado. Um rollback no limite de disco pode demorar cerca de 30 vezes mais que a insserção correspondente. Matar o processa de banco de dados não irá ajudar pois o rollback irá reiniciar ao se entrar no banco de dados. O único modo de se livrar de um rollback deste tipo é aumentar a área de buffer de forma que o rollback dependa do limite de CPU e seja executado rápidamente ou deltar todo o banco de dadosInnoDB
. - Tome ciência também de outras grandeas operações com limite de disco. Use
DROP TABLE
ouTRUNCATE
(a partiir do MariaDB-4.0) para esvaziar uma tabela, nãoDELETE FROM suatabela
. - Utilize
INSERT
multi-line para reduzir a sobrecarga de comunicação entre o cliente e o servidro se você precisar inserir muitas linhas:
INSERT INTO suatabela VALUES (1, 2), (5, 5);
Esta dica é válida para inserções em qualquer tipo de tabela, não apenas no
InnoDB
.
SHOW INNODB STATUS
e o Monitor InnoDB
A partir da versão 3.23.41, o InnoDB
inclui o Monitor InnoDB que imprime informações sobre o estado interno do InnoDB
. A partir das versões 3.23.52 e 4.0.3 você pode usar o comando SQL SHOW INNODB STATUS
para trazer a saída do Monitor InnoDB
padrão para o cliente SQL. os dados são úteis para ajuste do desempenho. Se você estiver usando o cliente SQL interativo MariaDB
, a saída é mais legível se você substituir o ponto e vírgula normalmente usado no final das instruções por \G
:
SHOW INNODB STATUS\G
Outro modo de usar os Monitores InnoDB
é deixá-los gravando dados continuamente na saída padrão do servidor mysqld
(nota: o cliente MariaDB não exibirá nada). Ao ser ligado, os Monitores InnoDB exibirá dados um vez a cada 15 segundos. Se você executar mysqld
como um daemon então esta saída é normalmente direcionada para o log .err
no datadir
do MariaDB. Este dado é útil para ajuste do desempenho. No Windows você deve iniciar o mysqld-max
a partir do Prompt do MSDOS com a opção --standalone --console
para direcionar a saída para a janela do prompt do MS-DOS.
Existe um innodb_lock_monitor
separada que imprime a mesma informação que innodb_monitor
mais informações sobre travas configuradas por cada transação.
A informação impressa inclui dados sobre:
- espera de bloqueios de uma transação,
- espera de semáforo de threads,
- pedido de E/S de arquivos pendentes,
- estatísticas de área de buffer e
- atividade de fusão do buffer de inserção e remoção da thread principal do
InnoDB
.
Você pode iniciar o Monitor InnoDB com o seguinte comando SQL:
CREATE TABLE innodb_monitor(a INT) type = innodb;
e pará-lo com
DROP TABLE innodb_monitor;
A sintaxe CREATE TABLE
é só um modo de passar um comando ao mecanismo InnoDB
através do analisador SQL do MariaDB: a tabela criada não é relevante para o Monitor InnoDB
. Se você fechar o banco de dados quando o manitor estiver em execução, e você quiser iniciar o monitor novamente, você deve apagar a tabela antes de executar um novo CREATE TABLE
para iniciar o monitor. A sinstaxe pode alterar em distribuição futuras.
Uma saída padrão do Monitor InnoDB:
================================ 010809 18:45:06 INNODB MONITOR OUTPUT ================================ -------------------------- LOCKS HELD BY TRANSACTIONS -------------------------- LOCK INFO: Number of locks in the record hash table 1294 LOCKS FOR TRANSACTION ID 0 579342744 TABLE LOCK table test/mytable trx id 0 582333343 lock_mode IX RECORD LOCKS space id 0 page no 12758 n bits 104 table test/mytable index PRIMARY trx id 0 582333343 lock_mode X Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE; info bits 0 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ';; 2: len 7; hex 000002001e03ec; asc ;; 3: len 4; hex 00000001; ... ----------------------------------------------- CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS ----------------------------------------------- SYNC INFO: Sorry, cannot give mutex list info in non-debug version! Sorry, cannot give rw-lock list info in non-debug version! ----------------------------------------------------- SYNC ARRAY INFO: reservation count 6041054, signal count 2913432 4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0 Mut ex 0 sp 5530989 r 62038708 sys 2155035; rws 0 8257574 8025336; rwx 0 1121090 1848344 ----------------------------------------------------- CURRENT PENDING FILE I/O'S -------------------------- Pending normal aio reads: Reserved slot, messages 40157658 4a4a40b8 Reserved slot, messages 40157658 4a477e28 ... Reserved slot, messages 40157658 4a4424a8 Reserved slot, messages 40157658 4a39ea38 Total of 36 reserved aio slots Pending aio writes: Total of 0 reserved aio slots Pending insert buffer aio reads: Total of 0 reserved aio slots Pending log writes or reads: Reserved slot, messages 40158c98 40157f98 Total of 1 reserved aio slots Pending synchronous reads or writes: Total of 0 reserved aio slots ----------- BUFFER POOL ----------- LRU list length 8034 Free list length 0 Flush list length 999 Buffer pool size in pages 8192 Pending reads 39 Pending writes: LRU 0, flush list 0, single page 0 Pages read 31383918, created 51310, written 2985115 ---------------------------- END OF INNODB MONITOR OUTPUT ============================ 010809 18:45:22 InnoDB starts purge 010809 18:45:22 InnoDB purged 0 pages
Algumas notas sobre a saída:
- Se a seção LOCKS HELD BY TRANSACTIONS relatar espera de bloqueios, então a sua aplicação pode ter diputa de travas. A saida também ajuda a rastrear as razões de deadlocks nas transações.
- A seção SYNC INFO irá relatar semáforos reservados se você compilar o InnoDB com
UNIV_SYNC_DEBUG
definido emuniv.i
. - A seção SYNC ARRAY INFO relatas as threads que esperam por semáforos e estatísticas sobre quantas vezes a thread precisou esperar por um mutex ou por um semáforo de trava de leitura/escrita. Um número grande de espera da thread pelo semáforo pode ser um resultado de E/S de disco ou problemas de disputa dentro do InnoDB. As disoutas pode ser devido a paralelismo pesado de consultas ou problemas na programação das threads no sistema operacional.
- A seção CURRENT PENDING FILE I/O'S lista os pedidos de E/S de arquivos que estão pendente. Um número grande indica que a carga de trabalho esta no limite de disco.
- A seção BUFFER POOL lhe dá estatíticas sobre leitura e escrita das páginas. Você pode calcular a partir destes números quanto de E/S em arquivos de dados a sua consulta esta fazendo atualmente.
Implementação de Multi-versioning
Como o InnoDB é um banco de dados multi-version, ele deve mantar informações de versões antigas de seus registros na tablespace. Esta informação é armazenada na estrutura de dados que chamamos de segmento rollback como uma estrutura de dados anoga no Oracle.
Internamente o InnoDB adiciona dois campos a cada linha armazenada no banco de dados. Um campo de 6 bytes diz ao identificador da transação sobrea a última transação que inseriu ou atualizou um registro. Uma deleção também é tratada internamente como uma atualização ande um bit especial é definido para indicae a daleção. Cada linha contém também um campo de 7 bytes chamado roll pointer. O roll pointer aponta para um registro log de itens a desfazer escrito no segmento rollback. Se o registro foi atualizado, então este registro de log contém a informação necessária para reconstruir o conteúdo da linha antes de ela ter sido atualizada.
O InnoDB usa a informação no segmento rollback para realizar o operação de desfazer necessária em um rollback de uma transação. Ele também usa a informação para construir versões mais novas de um registro para uma leitura consistente.
Os logs de itens a desfazer em um segmwnto rollback são divididos en logs de inserção e atualização. Logs de inserção só são necessários em rollback das transações e podem ser discartados assim que se fizer o commit das transações. Logs de atualização também são utilizados em leituras consistentes, e eles só podem ser descartados quando não houver mais transações para as quais o InnoDB atribuiu uma cópia do banco de dados que precisasse das informações do log de atualizações em uma leitura consistente para construir uma versão mais nova do registro do banco de dados.
Você deve se lembrar de fazer commit em suas transaçãoes regularmente, inclusive aquelas transações que só fazem leituras consistentes. Senão o InnoDB não pode descartar dados do log de atualização e o segmento rollback pode crescer demias, enchendo o seu tablespace.
O tamanho físico de um registro log de itens a desfazer em um segmento rollback é normalmente menor que o registro inserido ou atualizado correspondente. Você pode usar esta informação para calcular o espaço necessário para o seu segmento rollback.
Neste esquema multi-versioning uma linha não é fisicamente removida do banco de dados imediatamente quando você a deleta com uma instrução SQL. Apenas quando o InnoDB puder descartar o registro de log de itens a desfazer da atualização ele pode, também, remover fisicamente a linha correspondente e seu registros de índices do banco de dados. Esta operação de remoção é chamada `purge' e é bem rápida, tendo, normalmente, a mesma ordem de tempo da instrução SQL que fez a deleção.
Estrutura de Tabelas e Índices
- Estrutura Física do Índice
- Buffer de Inserção
- Índices Hash Adaptativos
- Estrutura dos Registros Físicos
- Como Funciona uma Coluna
AUTO_INCREMENT
no InnoDB
O MariaDB armazena suas informações de dicionários de dados de tabelas em arquivos .frm
no diretório de banco de dados. Mas todo tabela do tipo InnoDB também tem sua própria entrada no dicionários de dados interno do InnoDB dentro da tablespace. Quando o MariaDB apaga uma tabela ou um banco de dados, ele tem que deletar o(s) arquivo(s) .frm
e a entrada correspondente dentro do dicionário de dados do InnoDB. Esta é a razão pela qual você não pode mover tabelas InnoDB entre banco de dados simplesmente movendo os arquivos .frm
e porque DROP DATABASE
não funcionava em tabelas do tipo InnoDB em versÕes do MariaDB anteriores a 3.23.43.
Toda tabela InnoDB tem um índice especial chamado de índice agrupado onde os dados dos registros são armazenados. Se você definir um chave primaria (PRIMARY KEY
) na sua tabela, então o índice da chave primária será o índice agrupado.
Se você não definir uma chave primária para a sua tabela, o InnoDB irá gerar internamente um índice agrupado qonde as linhas são ordenadas pela ID da linha que o InnoDB atribui as linhas nestas tabelas. O ID da linha é um campo de 6 bytes que cresce quando novas linhas são inseridas. Assim as linhas armazenadas pela sua ID estarão fisicamente na ordem de inserção.
Acessar uma linha pelo índice agrupado é rápido porque os dados do registro estarão na mesma página que a busca de índice nos indicar. Em muitos bancos de dados, os dados são armazenados em página diferente daquela em que se encontra os registros de índices, Se uma tabela é grande, a arquitetura do índice agrupado geralmente economiza E/S de disco se coparado a solução tradicional.
O registro em índices não agrupados (também os chamamos de índices secundários) em InnoDB contém o valor da chave primária para a linha. O InnoDB usa este valor de chave primária para buscar o registro do índice agrupado. Note que se a chave primária for grande, os índices secundários irão utilizar ainda mais espaço.
Estrutura Física do Índice
Todos os índices no InnoDB são árvores-B onde os registros de índice são armazenados na página de folhas da árvore, O tamanho padrão de uma página de índice é 16 Kb. Quando novos registros são inseridos, InnoDB tenta deixar 1 / 16 de paginas livre para futuras inserções e atualzações de registro de índices.
Se registros de índice são inseridos em ordem sequencial (ascendente ou descendente, os páginas de índices resultantes estarão cerce de 15/16 completa. Se os registros são inseridos em ordem aleatoria, então as páginas estarão de 1/2 a 15/16 completos. Se o fator de preenchimento de uma página índice ficar abaixo de 1/2, o InnoDB tentará contrair o árvore de índice para liberar a página.
Buffer de Inserção
É uma situação comum em aplicativos de banco de dados que a chave prmária seja um identificador único e os novos registros são inseridos em ordem crescente de acordo com a chave primária. Assim a inserção nos índices agrupados não exigem leituras aleatorias a disco.
Por outro lado, índices secundários são normalmente não são únicos e inserções acontecem em uma ordem relativamente aleatória nos índices secundários. Isto causaria diversos acessos de E/S aleatórios em disco sem um mecanismo especial usado em InnoDB.
Se um registro de índice deve ser inserido a um índice secundário que não é único, o InnoDB verifica se a página de índice secundário já está na área de buffer. Se este for o caso, o InnoDB fará a inserção diretamente ná página do índice. Mas, se a página de índice não for encontrada na área de buffer, O InnoDB insere o registro em uma estrutura de buffer de inserção especial. O buffer de inserção é mantido tão pequeno que ele cabe totalmente na área de buffer e inserções nele podem ser feitas muito rápido.
O buffer de inserção é unido periodicamente à árvore de índices secundários no banco de dados. Geralmente nós podemos juntar diversas inserções na mesma página na árvore índice o que economiza E/S de disco. Buffers de inserções podem aumentar a velocidade das inserções em uma tabela em cerca de 15 vezes.
Índices Hash Adaptativos
Se um banco de dados couber quase totalmente na memória principal, então o modo mais rápido de realizar consultas nela é usar índices hash. O InnoDB tem um mecanismo automatico que monitora as buscas em índices feitas nso índices definidos na tabela e, se o InnoDB notar que as consultas podiam ser beneficiadas da construçã de índices hash, tal índice é automaticamente construído.
Mas note que um índice hash é sempre construído com base em um índice de árvore-B existente na tabela. O InnoDB pode construir um índice hash em um prefixo de qualquer tamanho da chave definida pela árvore-B, dependendo de que padrão de busca o InnoDB observa em índices de árvore-B. Um índice hash pode ser parcial: não é exigido que todo o índice seja armazenado na área de buffer. O InnoDB contruirá índices hash por demanda naquelas páginas de índice que são frequentemente acessadas.
Deste forma, Através do mecanismo de índice hash adptativo o InnoDB se adapta a uma memória principal ampla, aporoximando-se da arquitetura dos bancos de dados de memória principal.
Estrutura dos Registros Físicos
- Cada registro de índice no InnoDB contém um cabeçalho de 6 bytes. O cabeçalho é usado para ligar registros consecutivos e também para bloqueio de regiostros.
- Registros em índices agrupados contém capos para todas as colunas definidas definidas pelo usuário. Adicionalmente, existe um campo de 6 bytes para a ID da transação e um campo de 7 bytes para o roll pointer.
- Se o usuário não tiver definido uma chave prmiária para uma tabela, então cada registro de índice agrupado também contém um campo ID de 6 bytes.
- Cada registro de índice secundário também contém todos os campos definidos para a chave de índice agrupado.
- Um registro também contém um ponteiro para cada campo do registro. Se o tamanho total dos campos em um registro é menor que 128 bytes, então o ponteiro é de 1 byte, senão é de 2 bytes.
Como Funciona uma Coluna AUTO_INCREMENT
no InnoDB
Depois que um banco de dados inicia, quando um usuário faz a primeira inserção em uma tabela T
onde uma coluna auto-increment foi definida, e o usuário não fornece um valor explicito para a coluna, então o InnoDB executa SELECT MAX(auto-inc-column) FROM T
, e atribui aquele valor incrementado de um a coluna e ao contador de auto incremento da tabela. Dizemos que o contador de auto incremento para a tabela T
foi inicializado.
O InnoDB segue o mesmo procedimento na inicialização do contador de auto incremento para uma tabela recem criada.
Note que se o usuário especifica em uma inserção o valor 0 a coluna auto-increment. o InnoDM trata a linha como se o valor não tivesse sido especificado.
Depois do contador de auto incremento tiver sido inicializado, se um usuário insere uma linha onde especificamos explicitamente o valor da coluna e o valor é maior que o valor atual do contador, então o contador é configurado com o valor especificado. Se o usuário não especificar um valor explicitamente, o InnoDB incrementa a contador de um e atribui o seu novo valor a coluna.
O mecanismo de auto incremento, ao atribuir valor ao contador, desvia de manipuladores de travas e transações. De outra forma você também pode obter lacuas na sequência de números se você fizer um roll back da transação que tiver obtido números do contador.
O comportamento do auto incremento não é definido se um usuário passar um valor negativo a coluna ou se o valor se tornar maior que o valor inteiro máximo que pode ser armazenado no tipo inteiro especificado.
Gerenciamento do Espaço de Arquivos e E/S de Disco
- E/S de Disco
- Gerenciamento do Espaço de Arquivo
- Desfragmentando uma Tabela
E/S de Disco
Na E/S de disco o InnoDB usa E/S assíncrona. No Windows NT ele usa a E/S assíncrona nativa fornecida pelo sistema operacional. No Unix, o InnoDB usa E/S assíncrona simulada construída dentro do InnoDB: o InnoDB cria um número de threads de E/S que cuidam das operações de E/S, tais como leitura. Em uma versão futura adcionaremos suporte para E/S simulada no Windows NT e E/S nativa nas versões de Unix que possuam este recurso.
No Windows NT o InnoDB usa E/S sem buffer. Isto significa que as páginas de disco que o InnoDB lê ou escreve não são armazenadas na cache de arquivo do sistema operacional. Isto economiza um pouco da banda de memória.
A partir da versão 3.23.41, o InnoDB usa uma técnica de descarga de arquivo da novel chamado escrita dupla (doublewrite). Ela adiciona segurança a recuperação em falhas depois de uma falha do sistema operacional ou queda de força e aumenta o desempenho na maioria dos sistemas Unix, reduzindo a necessidade de operações fsinc.
Escrita dupla significa que antes do InnoDB escrever páginas em um arquivo de dados, ele primeiro os escreve em área de tablespaces contínuos chamados de buffer de escrita dupla (doublewrite buffer). Apenas após a escrita e a descarga no buffer de escrita dupla tiver sido completada, o InnoDB escreve a página em sua posição apropriada na arquivo de dados. Se o sistema operacional falhar no meio da escrita da página, o InnoDB irá fazer a recuperação procurando uma cópia da página no buffer de escrita dupla.
A partir da versão 3.23.41 você também pode usar uma partição de disco raw como um arquivo de dados, mas insto ainda não foi testado. Quando você cria um navo arquivo de dados você tem que colocar a palavra chave newraw
imediatamente depois do tamanho do arquivo de dados em innodb_data_file_path
. A partição deve ter, pelo menos, o tamanho que você especificou. Note que 1M no InnoDB é 1024 x 1024 bytes, enquanto na especificação de disco 1 MB normalmente significa 1000 000 bytes.
innodb_data_file_path=/dev/hdd1:5Gnewraw;/dev/hdd2:2Gnewraw
Quando você reinicia o banco de dados você deve alterar a palavra chave para raw
. Senão o InnoDB escreverá sobre a sua partição!
innodb_data_file_path=/dev/hdd1:5Graw;/dev/hdd2:2Graw
Usando um disco raw você pode ter E/S sem buffer em algumas vesões de Unix.
Quando você usar partições de disco raw, certifique-se de que você tem permissões que permitem acesso de leitura e escrita na conta usada para executar o servidor MySQL.
Existem duas heurísticas read-ahead no InnoDB: read-ahead sequencial e read-ahead aleatória. Na read-ahead sequencial o InnoDB percebe que o padrão de acesso a um segmento no tablespace é sequencial. então o InnoDB enviará uma grupo de leitura das paginas do banco de dados para o sistema de E/S. No read-ahead aleatório o InnoDB percebe que algumas áreas no tablespace parecem estar no processo de serem totalmente lidas na área de buffer. O InnoDB envia as leituras remanescente para o sistema de E/S.
Gerenciamento do Espaço de Arquivo
Os arquivos de dados definido no arquivo de configuração forma o tablespace do InnoDB. Os arquivos são simplesmente concatenado para formar o tablespace, não há nenhuma listagem em uso. Atualmente você não pode definir onde suas tabelas serão alocadas no tablespace. No entanto, em um tablespace criado recentemente, o InnoDB alocará
espaço a partir do low end
O tablespace consiste de páginas de banco de dados cujo tamanho padrão é 16 KB. As páginas são agrupadas numa extendsão de 64 páginas consecutivas. Os 'arquivos' dentro de um tablespace são chamados segmentos no InnoDB. O Nome do segmento rollback é um tanto enganador porque na verdade ele contém vários segmentos no tablespace.
Para cada índice no InnoDB nós alocamos dois segmentos: um é para nós que não são folhas da árvore-B e outro é para nós de folhas. A idéia aqui é conseguir melhorar a sequencialidade
dos nós de folhas, que comtêm os dados.
Quando um segmento cresce dentro da tablespace, o InnoDB aloca as primeiras 32 páginas para ele, individualmente. Depois disto o InnoDB inicia a alocação de toda a extensão do segmento. O InnoDB pode adicionar a um grande segmento até 4 extensões de uma vez para assegurar a boa sequencilidade
dos dados.
Algumas páginas na tablespace contém bitmaps de outras páginas e dessa forma algumas poucas extensões em um tablespace do InnoDB não podem ser alocadas ao segmento como um todo, mas apenas como páginas individuais.
Quando você executa uma consulta SHOW TABLE STATUS FROM ... LIKE ...
para saber sobre o espaço livre disponível no tablespace, o InnoDB irá relatar as extensões que estejam definitivamente livres na tabelspace. O InnoDB sempre reserva algumas extensões para limpeza e outros propósitios internos; estas extensões reservadas não estao incluídas no espaço livre.
Quando você deletar dados de uma tabela, o InnoDB contrairá o índice de árvore-B correspondente. Ele depende do padrão de deleções se isto liberar páginas individuais ou extensões da tablespace, assim que o espaço liberado estiver disponível para outros usuários. Apagar a tabela ou deletar todos os registros dela garante a liberação do espaço para outros usuários, mas lembre-se que registros deletados só podem ser fisicamente removidos em uma operação de remoção (`purge'), depois que não houver mais necessidades de rollback em trasações ou leituras consistentes.
Desfragmentando uma Tabela
Se houver inserções ou deleções aleatórias nos índices de uma tabela, os índices podem se tornar fragmentados. Com frangmentação queremos dizer que a ordem física das páginas de índice no disco não está próxima a ordem alfabética dos registros nas páginas, ou que existe muitas páginas sem uso no bloco de 64 páginas no qual os índices são alocados.
Isto pode aumentar a varredura de índices de você usar mysqldump
periodicamente para se fazer uma cópiad a tabela em um arquivo texto, apagar a tabela e recarregá-la a partir do arquivo texto. Outro modo de se fazer a desfragmentação é realizar uma operação alter table 'nula' ALTER TABLE nometabela TYPE=InnoDB
. Isto faz com que o MariaDB
reconstrua a tabela.
Se as inserções a um índice são sempre crescentes e os registros só são deletados a partir do fim, então o algoritmo do gerenciamento de espaço de arquivo do InnoDB garante que a fragmentação nos índices não ocorrerão.
Tratando Erros
O tratamento de erro no InnoDB nem sempre é o mesmo que o especificado no padrão SQL. De acordo com o SQL-99, qualquer erro durante uma instrução SQL deve provocar o rollback da instrução. O InnoDB, algumas faz o rollback de apenas parte da instrução, ou de toda instrução. A seguinte lista especifica o tratamento de erro do InnoDB.
- Se você ficar sem espaço no tablespace você obterá do MariaDB o erro
'Table is full'
e o InnoDB fará o rollback da instrução. - Um deadlock de uma transação ou em caso de se esgotar o tempo de espera em uma trava o InnoDB fará um rollback de toda a transação.
- Um erro de chave duplicada faz um rollback da inserção deste registro em particular, mesmo em instruções como
INSERT INTO ... SELECT ...
. Caso você não especifique a opçãoIGNORE
em sua instrução, provavelmente isto será diferente e o InnoDB fará rollback desta instrução SQL. - Um erro de 'registro muito grande' faz um rollback da instrução SQL.
- Outros erros são geralmente detectado pela camada de código do MariaDB e fazem o rollback da instrução correspondente.
Restrições em Tabelas InnoDB
- Tabelas InnoDB não suportam índices fulltext.
- No Windows o InnoDB armazena os nomes de banco de dados e tabelas internamente sempre em letras minúsculas. Para mover bancos de dados em um formato binário do Unix para o Windows ou do Windows para o Unix você deve ter todas os nomes de tabelas e banco de dados em letras minúscula.
- Aviso: NÃO converta o sistema de tabelas MariaDB de MyISAM PARA InnoDB! Isto não é suportado; se você fizer isto o MariaDB não reiniciará até que você restaure o sistema de tabelas antigo de um backup ou os regenere com o script
mysql_install_db
. SHOW TABLE STATUS
não dá estatísticas exatas sobre tabelas InnoDB, exceto sobre o tamanho físico reservado pela tabela. O contador de linha é apenas uma estimativa rude usada na otimização SQL.- Se você tentar criar um índice único em um prefixo de coluna você obterá um erro.
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
Se você criar um índice que não seja único em um prefixo de uma coluna, o InnoDB criará um índice sobre toda a coluna.
INSERT DELAYED
não é suportado por tabelas InnoDB.- As operações
LOCK TABLES
do MariaDB não tem conhecimento dos bloqueios de resistro do InnoDBconfigurados em instruções SQL completadas: isto significa que você pode conseguir um bloqueio de tabela mesmo se já existir transações de outros usuários que tiverem bloqueios de registros na mesma tabela. Assim suas operações sobre a tabela poder ter que esperar se eles colidirem com essas travas de outros usuários. Também pode ocorrer um deadlock. No entanto isto não tarz perigo a instegridade da transação, pois o bloqueio de registro definido pelo InnoDB sempre cuidará da integridade. Um bloqueio de tabela também previne que outras transações adquiram mais bloqueios de registros (em um modo de bloqueio conflitante) na tabela. - Uma tabela não pode ter mais de 1000 colunas.
DELETE FROM TABLE
não gera a tabela novamente, mas, ao invés diato, deleta todas as linhas, uma a uma, o que não é rápido. Em versões futuras do MariaDB você poderá usarTRUNCATE
que é mais rápido.- O tamanho de página padrão utilizado no InnoDB é 16KB. Recompilando o código pode se configurá-la com 8 KB a 64 KB. O tamanho máximo de um registro é menos da metade da página de banco de dados nas versões anteriores a 3.23.40 do InnoDB. A partir da distribuição fonte da versão 3.23.41 colunas BLOB e TEXT podem ter até 4 GB e o tamanho total do registro também devem ser menores que 4GB. O InnoDB não armazena campos cjo tamanho é menor que 128 bytes em páginas separadas. Depois do InnoDB modificar o registro armazenando campos grandes em páginas separadas, o tamanho restante da linha deve ser menor que metade da página de banco de dados. O tamanho máximo da chave é de 7000 bytes.
- Em alguns sistemas operacionais os arquivos de dados devem ser menores que 2 GB. O tamanho combinado dos arquivos de log devem ser menores que 4GB.
- O tamanho máximo do tablespace é 4 bilhões de páginas de banco de dados. Este também é o tamanho máximo da tabela. O tamanho mínimo do tabelspace é de 10 MB.
- Quando você reinicia o servidor MySQL, o InnoDB pode reutilizar um valor antigo para uma coluna
AUTO_INCREMENT
. - Você não pode definir o primeiro valor de uma coluna
AUTO_INCREMENT
no InnoDB comCREATE TABLE ... AUTO_INCREMENT=...
(ouALTER TABLE ...
). Para definir este valor insira uma linha com o valor de menos e delete esta linha.
Histórico de Alterações do InnoDB
- MySQL/InnoDB-4.1.1, December 4, 2003
- MySQL/InnoDB-4.0.16, October 22, 2003
- MySQL/InnoDB-3.23.58, September 15, 2003
- MySQL/InnoDB-4.0.15, September 10, 2003
- MySQL/InnoDB-4.0.14, Junho de 2003
- MySQL/InnoDB-3.23.57, June 20, 2003
- MySQL/InnoDB-4.0.13, 20 de Maio de 2003
- MySQL/InnoDB-4.1.0, 03 de Abril de 2003
- MySQL/InnoDB-3.23.56, 17 de Março de 2003
- MySQL/InnoDB-4.0.12, 18 Março de 2003
- MySQL/InnoDB-4.0.11, 25 de Fevereiro de 2003
- MySQL/InnoDB-4.0.10, 04 de Fevereiro de 2003
- MySQL/InnoDB-3.23.55, 24 de Janeiro de 2003
- MySQL/InnoDB-4.0.9, 14 de Janeiro de 2003
- MySQL/InnoDB-4.0.8, 07 de Janeiro de 2003
- MySQL/InnoDB-4.0.7, 26 de Dezembro de 2002
- MySQL/InnoDB-4.0.6, 19 de Dezembro de 2002
- MySQL/InnoDB-3.23.54, 12 de Dezembro de 2002
- MySQL/InnoDB-4.0.5, 18 de Novembro de 2002
- MySQL/InnoDB-3.23.53, 09 de Outubro de 2002
- MySQL/InnoDB-4.0.4, 02 de Outubro de 2002
- MySQL/InnoDB-4.0.3, 28 de Agosto de 2002
- MySQL/InnoDB-3.23.52, 16 de Agosto de 2002
- MySQL/InnoDB-4.0.2, 10 de Julho de 2002
- MySQL/InnoDB-3.23.51, 12 de Junho de 2002
- MySQL/InnoDB-3.23.50, 23 de Abril de 2002
- MySQL/InnoDB-3.23.49, 17 de Fevereiro de 2002
- MySQL/InnoDB-3.23.48, 09 de Fevereiro de 2002
- MySQL/InnoDB-3.23.47, 28 de Dezembro de 2001
- MySQL/InnoDB-4.0.1, 23 de Dezembro de 2001
- MySQL/InnoDB-3.23.46, 30 de Novembro de 2001
- MySQL/InnoDB-3.23.45, 23 de Novembro de 2001
- MySQL/InnoDB-3.23.44, 02 de Novembro de 2001
- MySQL/InnoDB-3.23.43, 04 de Outubro de 2001
- MySQL/InnoDB-3.23.42, 09 de Setembro de 2001
- MySQL/InnoDB-3.23.41, 13 de Agosto de 2001
- MySQL/InnoDB-3.23.40, 16 de Julho de 2001
- MySQL/InnoDB-3.23.39, 13 de Junho de 2001
- MySQL/InnoDB-3.23.38, 12 de Maio de 2001
MySQL/InnoDB-4.1.1, December 4, 2003
- Multiple tablespaces now available for InnoDB. You can store each InnoDB type table and its indexes into a separate
.ibd
file into a MariaDB database directory, into the same directory where the.frm
file is stored. - The MariaDB query cache now works for InnoDB tables also if
AUTOCOMMIT=0
, or the statements are enclosed insideBEGIN ... COMMIT
. - Reduced InnoDB memory consumption by a few megabytes if one sets the buffer pool size < 8 MB.
- You can use raw disk partitions also in Windows.
MySQL/InnoDB-4.0.16, October 22, 2003
- Fixed a bug: in contrary to what was said in the manual, in a locking read InnoDB set two record locks if a unique exact match search condition was used on a multi-column unique key. For a single column unique key it worked right.
- Fixed a bug: if one used the rename trick
#sql... -> rsql...
to recover a temporary table, InnoDB asserted inrow_mysql_lock_data_dictionary()
. - There are several outstanding non-critical bugs reported in the MariaDB bugs database. Their fixing has been delayed, because resources are allocated to the upcoming 4.1.1 release.
MySQL/InnoDB-3.23.58, September 15, 2003
- Fixed a bug: InnoDB could make the index page directory corrupt in the first B-tree page splits after
mysqld
startup. A symptom would be an assertion failure inpage0page.c
, in functionpage_dir_find_slot()
. - Fixed a bug: InnoDB could in rare cases return an extraneous row if a rollback, purge, and a
SELECT
coincided. - Fixed a possible hang over the
btr0sea.c
latch ifSELECT
was used insideLOCK TABLES
. - Fixed a bug: if a single
DELETE
statement first managed to delete some rows and then failed in aFOREIGN KEY
error or aTable is full
error, MariaDB did not roll back the whole SQL statement as it should.
MySQL/InnoDB-4.0.15, September 10, 2003
- Fixed a bug: if you updated a row so that the 8000 byte maximum length (without
BLOB
andTEXT
) was exceeded, InnoDB simply removed the record from the clustered index. In a similar insert, InnoDB would leak reserved file space extents, which would only be freed at the next mysqld startup. - Fixed a bug: if you used big
BLOB
values, and your log files were relatively small, InnoDB could in a bigBLOB
operation temporarily write over the log produced after the latest checkpoint. If InnoDB would crash at that moment, then the crash recovery would fail, because InnoDB would not be able to scan the log even up to the latest checkpoint. Starting from this version, InnoDB tries to ensure the latest checkpoint is young enough. If that is not possible, InnoDB prints a warning to the.err
log of MariaDB and advises you to make the log files bigger. - Fixed a bug: setting
innodb_fast_shutdown=0
had no effect. - Fixed a bug introduced in 4.0.13: if a
CREATE TABLE
ended in a comment, that could cause a memory overrun. - Fixed a bug: If InnoDB printed
Operating system error number .. in a file operation
to the.err
log in Windows, the error number explanation was wrong. Workaround: look at section 13.2 of http://www.innodb.com/ibman.php about Windows error numbers. - Fixed a bug: If you created a column prefix
PRIMARY KEY
like int(a CHAR(200), PRIMARY KEY (a(10)))
on a fixed-lengthCHAR
column, InnoDB would crash even in a simpleSELECT
. CCHECK TABLE
would report the table as corrupt, also in the case where the created key was notPRIMARY
.
MySQL/InnoDB-4.0.14, Junho de 2003
- InnoDB now supports the
SAVEPOINT
andROLLBACK TO SAVEPOINT
SQL statements. See http://www.innodb.com/ibman.php#Savepoints for the syntax. - You can now create column prefix keys like in
CREATE TABLE t (a BLOB, INDEX (a(10)))
. - You can also use
O_DIRECT
as theinnodb_flush_method
on the latest versions of Linux and FreeBSD. Beware of possible bugs in those operating systems, though. - Fixed the checksum calculation of data pages. Previously most OS file system corruption went unnoticed. Note that if you downgrade from version >= 4.0.14 to an earlier version < 4.0.14 then in the first startup(s) InnoDB will print warnings:
InnoDB: Warning: an inconsistent page in the doublewrite buffer InnoDB: space id 2552202359 page number 8245, 127'th page in dblwr buf.
but that is not dangerous and can be ignored.
- Modificado o algorítmo de substituição da área de buffer para que ele tente descarregar as páginas modificados se não houver páginas a serem sustituídas nos últimos 10% da lista LRU. Isto pode produzir e/s de disco se a carga de trabalho for uma mistura de leituras e escritas.
- O algorítmo de descarga do ponto de verificação da área de buffer agora também tenta descarregar vizinhos próximos a página no fim da lista de flush. Isto pode aumentar a velocidade de desligamento do banco de dados e pode também aumentar as escritas em disco se o arquivo de log do InnoDB for muito pequeno comparado ao tamanho da área de buffer.
- Na versão 4.0.13 fazemos SHOW INNODB STATUS exibir informações detalhadas sobre o último erro de UNIQUE KEY, mas armazenar esta informação podia deixar o REPLACE bem mais lento. Não exibimos nem armazenamos mais a informação.
- Corrigido um erro: SET FOREIGN_KEY_CHECKS=0 não era replicado apropriadamente na replicação do MariaDB. A correção provavelmente não será feita na série 3.23.
- Corrigido um erro: o parâmetro innodb_max_dirty_pages_pct não levav em conta as páginas livres na área de buffer. Isto podia levar a descargas excessivas mesmo se houvesse muitas páginas livres na área de buffer. Solução: SET GLOBAL innodb_max_dirty_pages_pct = 100.
MySQL/InnoDB-3.23.57, June 20, 2003
- Changed the default value of
innodb_flush_log_at_trx_commit
from 0 to 1. If you have not specified it explicitly in yourmy.cnf
, and your application runs much slower with this new release, it is because the value 1 causes a log flush to disk at each transaction commit. - Fixed a bug: InnoDB forgot to call pthread_mutex_destroy() when a table was dropped. That could cause memory leakage on FreeBSD and other non-Linux Unixes.
- Fixed a bug: MariaDB could erroneously return 'Empty set' if InnoDB estimated an index range size to 0 records though the range was not empty; MariaDB also failed to do the next-key locking in the case of an empty index range.
- Fixed a bug:
GROUP BY
andDISTINCT
could treat NULL values inequal.
MySQL/InnoDB-4.0.13, 20 de Maio de 2003
- O
InnoDB
agora suportaALTER TABLE DROP FOREIGN KEY
. Você deve usarSHOW CREATE TABLE
para ver a ID de chaves estrangeiras geradas internamente quando quiser apagar uma chave estrangeira. SHOW INNODB STATUS
agora esxibe informações detalhadas do último erro deFOREIGN KEY
eUNIQUE KEY
detectados. Se você não entender porque oInnoDB
retorna o erro 150 de umCREATE TABLE
, você pode utilizar isto para estudar a razão.ANALYZE TABLE
agora também funciona para tabelas do tipoInnoDB
. Ela faz 10 inserções aleatórias para cada das árvores de índices e atualiza a estimativa da cardinalidade do índice adequadamente. Note que como isto é apenas uma estimativa, repetidas execuções deANALYZE TABLE
podem produzir diferentes números. O MariaDB usa a estimativa de cardinalidade do índice apenas an otimização de joins. Se alguma join não é otimizada de modo apropriado, você pode tentar usarANALYZE TABLE
.- A capacidade de commit de grupo do
InnoDB
agora também funciona quando o log binário do MariaDB está habilitado. Deve haver mais de 2 threads cliente para commit de grupo estar ativo. - Alterado o valor padrão de
innodb_flush_log_at_trx_commit
de 0 para 1. Se você não tiver especificado-o explicitamente em seumy.cnf
, e sua aplicação executar muito mais lentamente nesta nova distribuição é porque o valor 1 faz com que seja descarregado um log para disco a cada commit de transações. - Adicionado uma nova variável global configurável de sistema do MariaDB (
innodb_max_dirty_pages_pct
). Ela é um interio na faixa de 0 - 100. O padrão é 90. A thread principal noInnoDB
tenta descarregar as páginas da área de buffer já que grande parte deste percetual ainda não foi descarregado em nenhum momento. - Se
innodb_force_recovery=6
, não deixar oInnoDB
fazer reparação de páginas corrompidas baseadas no buffer de dupla escrita. - O
InnoDB
agora inica mais rápido porque ele não define a memória na área de buffer para zero. - Corrigido um erro: a definição
FOREIGN KEY
doInnoDB
era confudida com as palavras chaves 'foreign key' dentro dos comentários do MariaDB. - Corrigido um ero: se você apagasse um tablea para qual havia uma referência de chave estrangeira, e posteriormente criasse a mesma tabela com tipo de colunas não correspondentes, o
InnoDB
podia entrar em dict0load.c, na funçãodict_load_table
. - Corrigido um erro:
GROUP BY
eDISTINCT
podia tratar valoresNULL
como diferentes. O MariaDB também falahva ao fazer o lock da próxima chave no caso de uma faixa de índice vazia. - Corrigido um erro: não faz COMMIT da transação atual quando uma tabela MyISAM é atualizada; isto também faz com que
CREATE TABLE
não faça commit de uma transaçãoInnoDB
, mesmo quando o log binário estiver habilitado. - Corrigido um erro: não permite que
ON DELETE SET NULL
modifique a mesma tabela onde o delete foi feito; podemos permití-lo porqeu into não pode produzir loops infinitos em operações em cascata. - Corrigido um erro: permitir
HANDLER PREV
eNEXT
também depois de posicionar o cursor com uma busca única na chave primária - Corrigido um erro: se
MIN()
ouMAX()
resultasse em um deadlock ou em esgotamento do tempo de espera do lock, o MariaDB não retornava um erro, masNULL
como o valor da função. - Corrigido um erro: o
InnoDB
esquecia de chamarpthread_mutex_destroy()
quando uma tabela era apagada. Isto podia causar perda de memória no FreeBSD e outros Unix, exceto o Linux.
MySQL/InnoDB-4.1.0, 03 de Abril de 2003
- O
InnoDB
agora suporta até 64 GB de memória de área de buffer em um conputador Intel de 32 bits com Windows. Isto é possível porque oInnoDB
pode utilizar a extensão AWE de Windows para endereços de memória sobre o limite de 4 GB de um processador de 32 bits. Uma nova variável de inicialização innodb_buffer_pool_awe_mem_mb habilita o AWE e define o tamanho da área de buffer em megabytes. - Reduz o tamanho do cabeçalho de buffer e tabela bloqueada. O
InnoDB
utiliza 2% a menos de memória.
MySQL/InnoDB-3.23.56, 17 de Março de 2003
- Corrigido um erro grave na otimização de consultas do InnoDB: consultas do tipo SELECT ... WHERE índice_col < x and SELECT ... WHERE índice_col > x podiam provocar a varredura da tabela mesmo se a seletividade fosse muito boa.
- Corrigido um erro potencial quando MariaDB chama store_lock with TL_IGNORE no meio de uma consulta.
MySQL/InnoDB-4.0.12, 18 Março de 2003
- Nas recuperações de falhas, agora o InnoDB mostra o progresso em percentual do rollback de uma transação.
- Corrigido um erro/recurso: se seu aplicativo usa mysql_use_result(), e usa >= 2 conexões para enviar consultas SQL, ele poderia entrar em deadlock na hash S-latch adaptativa em btr0sea.c. Agora o mysqld libera a S-latch se ela passar o dado de uma SELECT para o cliente.
- Corrigido um erro: o MariaDB podia, erroneamente, retornar 'Empty set' se o InnoDB estimasse o tamanho da faixa do índice para 0 registro mesmo se o registro não estivesse vazio; o MariaDB também falhava para fazer o lock da próxima chave no caso de uma faixa de índice vazia.
MySQL/InnoDB-4.0.11, 25 de Fevereiro de 2003
- Corrigido um erro introduzido na versão 4.0.10: SELECT ... FROM ... ORDER BY ... DESC podia entrar em loop infinito.
- Um erro proeminente: SET FOREIGN_KEY_CHECKS=0 não é replicado de forma apropriada na replicação do MariaDB.
MySQL/InnoDB-4.0.10, 04 de Fevereiro de 2003
- Em INSERT INTO t1 SELECT ... FROM t2 WHERE ... anteriormente o MariaDB definia um bloqueio de tabela em t2. O bloqueio agora foi removido.
- Aumentou o tamanho máximo mostardo de SHOW INNODB STATUS para 200 KB.
- Corrigido um erro grave na otimização da consulta do InnoDB: consultas do tipo SELECT ... WHERE indice_col < x and SELECT ... WHERE indice_col > x podia provocar a varredura da tabela mesmo quand a seletividade estivess muito boa.
- Corrigido um erro: a remoção (`purge') podia causar lentidão em uma tabela BLOB cuja árvore de índice de chave primária fosse de altura 1. Sintomas: os semáforos esperam devido a um tarva X definida em btr_free_externally_stored_field().
- Corrigido um erro: usar o comando HANDLER do InnoDB em um tratamento recente de um mysqld com falha em ha_innobase::change_active_index().
- Corrigido um erro: se o MariaDB estimar uma consulta no meio de uma instrução SELECT, o InnoDB irá parar na trava de ídice hash adaptativa em btr0sea.c.
- Corrigido um erro: O InnoDB podia relatar corrompimento e declara em page_dir_find_owner_slot() se uma busca de índice hash adaptativo coincidiu com uma remoção ou uma inserção.
- Corrigido um erro: algumas ferramentas de snapshot de sistema de arquivos no Windows 2000 podia provocar uma falha na escrita em arquivo s InnoDB com erro ERROR_LOCK_VIOLATION. Agora, em escritas síncronas, o InnoDB tenta escrever novamente até 100 vezes em intervalos de 1 segundo.
- Corrigido um erro: REPLACE INTO t1 SELECT ... não funciona se t1 tiver uma coluna com auto incremento.
- Um erro proeminente: SET FOREIGN_KEY_CHECKS=0 não é replicado de forma apropriada em replicações do MariaDB.
MySQL/InnoDB-3.23.55, 24 de Janeiro de 2003
- Em INSERT INTO t1 SELECT ... FROM t2 WHERE ... anteriormente o MariaDB definia um bloqueio de tabela em t2. O bloqueio agora foi removido.
- Corrigido um erro: se o tamanho total dos arquivos de log do InnoDB fosse maior que 2GB em um comoputador de 32 bits, o InnoDB escreveria o log em uma posição errada. Isto poderia fazer com que a recuperação em caso de falhas e o InnoDB Hot Backup falhassem na varredura do log.
- Corrigido um erro: restauração do cursos de índice poderia, teoricamente, falhar.
- Consrtado um erro: uma declaração em in btr0sea.c, na função btr_search_info_update_slow podia, teoriacamente, falhar em uma
disputa
de 3 threads. - Corrigido um erro: a remoção (`purge') podia causar lentidão em uma tabela BLOB cuja árvore de índice de chave primária fosse de altura 1. Sintomas: os semáforos esperam devido a um tarva X definida em btr_free_externally_stored_field().
- Corrigido um erro: se o MariaDB estimar uma consulta no meio de uma instrução SELECT, o InnoDB irá parar na trava de ídice hash adaptativa em btr0sea.c.
- Corrigido um erro: O InnoDB podia relatar corrompimento e declara em page_dir_find_owner_slot() se uma busca de índice hash adaptativo coincidiu com uma remoção ou uma inserção.
- Corrigido um erro: algumas ferramentas de snapshot de sistema de arquivos no Windows 2000 podia provocar uma falha na escrita em arquivo s InnoDB com erro ERROR_LOCK_VIOLATION. Agora, em escritas síncronas, o InnoDB tenta escrever novamente até 100 vezes em intervalos de 1 segundo.
- Um erro proeminente: SET FOREIGN_KEY_CHECKS=0 não é replicado de forma apropriada em replicações do MariaDB. O conserto aparecerá na versão 4.0.11 e provavelmente não será passada a versão 3.23
- Corrigido um erro na função page_cur_search_with_match em pageOcur.c do InnoDB que faz com que ele fique na mesma página indefinidamente. Este erro evidentemente só está presente em tabelas com mais de uma página.
MySQL/InnoDB-4.0.9, 14 de Janeiro de 2003
- Removida a mensagem de aviso: 'InnoDB: Out of memory in additional memory pool.'
- Corrigido um erro: se o tamanho total dos arquivos de log do InnoDB fosse maior que 2GB em um comoputador de 32 bits, o InnoDB escreveria o log em uma posição errada. Isto poderia fazer com que a recuperação em caso de falhas e o InnoDB Hot Backup falhassem na varredura do log.
- Corrigido um erro: restauração do cursos de índice poderia, teoricamente, falhar.
MySQL/InnoDB-4.0.8, 07 de Janeiro de 2003
- Agora, o InnoDB também suporta FOREIGN KEY (...) REFERENCES ...(...) [ON UPDATE CASCADE | ON UPDATE SET NULL | ON UPDATE RESTRICT | ON UPDATE NO ACTION].
- Tabelas e índices agora reservam 4% a menos de espaço na tablespace. Tabelas existentes também reservam menos espaço. Atualizando para 4.0.8 vaocê verá mais espaço livre em 'InnoDB free' em SHOW TABLE STATUS.
- Corrigido um erro: atualizar a chave primária de um registro gera uma erro de chave estrangeira em todas as chaves estrangeiras que fazem referência a chaves secundárias do registro a ser atualizado. Além disso, se uma restrição de referência de chave estrangeira só se refere a primeir coluna em um índice e houver mais colunas neste índice, atualizar a coluna adicional irá gerar um erro de chave estrangeira.
- Corrigido um erro: se um índice contém algumas colunas duas vezes e esta coluna é atualizada, a tabela se tornará corrompida. Agora o InnoDB previne a criação de tais índices.
- Corrigido um erro: removido mensagens de erros supérfluos 149 e 150 do arquivo .err quando um SELECT bloquado provoca um deadlock ou um esgota o tempo limite de espera de um bloqueio.
- Consrtado um erro: uma declaração em in btr0sea.c, na função btr_search_info_update_slow podia, teoriacamente, falhar em uma
disputa
de 3 threads. - Corrigido um erro: não é possível trocar o nível de isolamento da tarnasação de volta para REPEATABLE READ depouis de definí-lo com outro valor.
MySQL/InnoDB-4.0.7, 26 de Dezembro de 2002
- O InnoDB na versão 4.0.7 é essencialmente o mesmo da in 4.0.6.
MySQL/InnoDB-4.0.6, 19 de Dezembro de 2002
- Uma vez que innodb_log_arch_dir não têm relevância sob o MySQL, não há necessidade de se especificá-lo no arquivo my.cnf.
- LOAD DATA INFILE em modo AUTOCOMMIT=1 não faz mais commits implicitos para cada 1MB de log binário escrito.
- Corrigido um erro introduzido na versão 4.0.4: LOCK TABLES ... READ LOCAL não deve definir bloqueio de registros ao lê-los. Isto provoca deadlocks e esgostamento do tempo limite de espera das travas do registro no mysqldump.
- Corrigido dois erros introduzidos na versão 4.0.4: em AUTO_INCREMENT, REPLACE pode fazer com que o contador pode ser deixado como 1. Um deadlock ou esgotamento do tempo limite de espera de travas podem causar o mesmo problema.
- Corrigido um erro: TRUNCATE em uma tabela temporária causa erro no InnoDB.
- Corrigido um erro introduzido na versão 4.0.5: se o log binário não estivessem ligado, INSERT INTO ... SELECT ... ou CREATE TABLE ... SELECT ... podiam fazer com que o InnoDB pendurasse em um semáforo criado em btr0sea.c, line128. Solução: ligar o log binário.
- Corrigido um erro: na replicação, executar SLAVE STOP no meio de uma transação multi-instrução podia fazer com que SLAVE START só realizasse parte da transação. Um erro parecido podia ocorrer se o slave finalizasse devido a um erro e fosse reiniciado.
MySQL/InnoDB-3.23.54, 12 de Dezembro de 2002
- Corrigido um erro: a estimativa de alcance do InnoDB exagerava em muito o tamanho de de uma pequna faixa de índice se o caminho ao ponto final da faixa na árvore de índice já era um ramo na raíz. Isto podia causar varreduras de tabela desnecessáriaem consultas SQL.
- Corrigido um erro: ORDER BY podia falhar se você não tiver criado um chave primária para um tabela, mas tiver definido diversos índices nos quais pelo menos um era um índice único (UNIQUE) com todos as suas colunas declaradas como NOT NULL.
- Corrigido um erro: um esgotamento do tempo de espera se um lock na conexão com ON DELETE CASCADE podia causar corrompimento em índices.
- Corrigido um erro: se um SELECT era feito com uma chave única a partir de um índice primário, e a busca correspondesse a um registro marcado para deleção, o InnoDB podia erroneamente retornar o PROXIMO registro.
- Corrigido um erro introduzido na versão 3.23: LOCK TABLE ... READ LOCAL não devia definir lock de registro na leitura das linhas. Isto causava deadlocks e esgotamento do tempo de espera do lock no mysqldump.
- Corrigido um erro: se um índice continha algumas colunas duas vezes, e aquela coluna está atualizada, a tabela fcava corrompida. De agora em diante o InnoDB previne a criação de tais índices.
MySQL/InnoDB-4.0.5, 18 de Novembro de 2002
- O InnoDb agora suporta os níveis READ COMMITTED e and READ UNCOMMITTED de isolmento de transação. O READ COMMITTED emula mais proximamente o Oracle e portar aplicações de Oracle para MariaDB se torna mais fácil.
- A resolução de deadlock agora é seletiva: tentamos pegar como vítimas transações com menos linhas modificadas ou inseridas.
- Definições FOREIGN KEY agora está ciente da configuração lower_case_nome_tabelas no arquivo my.cnf.
- SHOW CREATE TABLE não exibe o nome do banco de dados para uma definição FOREIGN KEY se a tabela referida está no mesmo banco de dados que a tabela.
- O InnoDB faz uma verificação de consistência para verificar a maioria das páginas de índices antes de escrevê-las no arquivo de dados.
- Se você definir innodb_force_recovery > 0, o InnoDB tenta saltar para os registros e páginas com índices corrompidos fazendo SELECT * FROM tabela. Isto ajuda no dump.
- O InnoDB agora usa E/S assíncrona e sem buffer no Windows 2000 e XP; e apenas E/S sem buffer assíncrono por simulação no NT, 95/98/ME.
- Corrigido um erro: a estimativa de alcance do InnoDB exagerava em muito o tamanho de de uma pequna faixa de índice se o caminho ao ponto final da faixa na árvore de índice já era um ramo na raíz. Isto podia causar varreduras de tabela desnecessáriaem consultas SQL. A correção também será feita na versão 3.23.54.
- Corrigido um erro presente nas versões 3.23.52, 4.0.3, 4.0.4: A inicialização do InnoDB podia levar muito tempo ou até mesmo falhar em alguns computadores Windows 95/98/ME.
- Corrigido um erro: o lock AUTO-INC erá guardado para o fim da transação se ele fosse concedido depois de uma espera de lock. Isto podia causar deadlocks desnecessários.
- Corrigido um erro: se SHOW INNODB STATUS, innodb_monitor, ou innodb_lock_monitor tiver exibido centenas de transações em um relatório, e a saída ficar truncada, o InnoDB travaria, imprimindo no log de erros muitas esperas por um mutex criado em srv0srv.c, line 1621.
- Corrigido um erro: SHOW INNODB STATUS no Unix sempre relata o tamanho médio dos arquivos lidos como 0 bytes.
- Corrigido um erro potencial na versão 4.0.4: o InnoDB agora faz ORDER BY ... DESC como o MyISAM.
- Corrigido um erro: DROP TABLE podia causar falhas ou um travamento se houvesse um rollback executando concorrentemente na tabela. A correção será feita na série 3.23 se este for um problema para os usuários.
- Corrigido um erro: ORDER BY podia falhar se você não tivesse criado um chave primária para uma tabela, mas tivesse definido diversos índices nos quais pelo menos um seja um índice único (UNIQUE) com todas as suas colunas declaradas como NOT NULL.
- Corrigido um erro: um espera pelo tempo limite na conexão com ON DELETE CASCADE podia causar corrompimento nos índices.
- Corrigido um erro: se um SELECT era feito com uma chave única a partir de um índice primário e a busca correspondesse a um registro marcado para deleção, o InnoDB podia retornar o próximo registro.
- Outstanding bugs: na versão 4.0.4 dois erros foram introduzidos no AUTO_INCREMENT. REPLACE pode fazer com que o contador seja decrementado. Um deadlock ou uma espera de tempo limite de lock pode causar o mesmo problema. Eles serão corrigidos na versao 4.0.6.
MySQL/InnoDB-3.23.53, 09 de Outubro de 2002
- Usamos novamente E/S de disco sem buffer para arquivos de dados no Windows. A performance de leitura do Windows XP e Windows 2000 parecem estar muito fraca com E/S normal.
- Ajustamos a estimativa de faixa para uqe varreduras de índices na faixa tenham preferência sobre a varredura completa de índices.
- Permitir a remoção e criação de tableas mesmo se o innodb_force_recovery está configurado. Pode se usar isto para remover uma tabela que causaria uma falha no rollback ou deleção, ou se uma importação de tabelas com falhas causa um rollback na recuperação.
- Corrigido um erro presente nas versões 3.23.52, 4.0.3, 4.0.4: A inicialização do InnoDB podia demorar ou mesmo travar em alguns computadores Windows 95/98/ME.
- Corrigido um ero: a finalização rápida (que é padrão), algumas vezes ficava lenta pela união do buffer de remoção e inserção.
- Corrigido um erro: fazer um grande SELECT de uma tabela onde nenhum registro estava visível em uma leitura consistente podia causar uma espera de semáforo muito longo (> 600 segundos) em btr0cur.c line 310.
- Corrigido um erro: o lock AUTO-INC era guarda para o fim da transação se fosse concedido depois de uma espera de lock. Isto podia causar um deadlock desnecessário.
- Corrigido um erro: se você criar uma tabela temporária dentro de LOCK TABLES, e usar esta tabela temporária, causará um falha de declaração em ha_innobase.cc.
- Corrigido um erro: se SHOW INNODB STATUS, innodb_monitor, ou innodb_lock_monitor tiver exibido centenas de transações em um relatório, e a saída ficar truncada, o InnoDB travaria, imprimindo no log de erros muitas esperas por um mutex criado em srv0srv.c, line 1621.
- Corrigido um erro: SHOW INNODB STATUS no Unix sempre relata o tamanho médio dos arquivos lidos como 0 bytes.
MySQL/InnoDB-4.0.4, 02 de Outubro de 2002
- Usamos novamente E/S de disco sem buffer para arquivos de dados no Windows. A performance de leitura do Windows XP e Windows 2000 parecem estar muito fraca com E/S normal.
- Aumentado o tamanho máximo da chave de tabelas InnoDB de 500 para 1024 bytes.
- Aumentado o campo de comentário da tabela em SHOW TABLE STATUS a assim até 16000 caracteres da definição de chaves estrangeiras pode ser exibidas aqui.
- O contador de auto incremento não é mais incrementado de um inserção de uma linha falhar imediatamente.
- Permitir a remoção e criação de tableas mesmo se o innodb_force_recovery está configurado. Pode se usar isto para remover uma tabela que causaria uma falha no rollback ou deleção, ou se uma importação de tabelas com falhas causa um rollback na recuperação.
- Corrigido um erro: Usar ORDER BY primarykey DESC na versão 4.0.3 causa um falha de declaração em btr0pcur.c, line 203.
- Corrigido um ero: a finalização rápida (que é padrão), algumas vezes ficava lenta pela união do buffer de remoção e inserção.
- Corrigido um erro: fazer um grande SELECT de uma tabela onde nenhum registro estava visível em uma leitura consistente podia causar uma espera de semáforo muito longo (> 600 segundos) em btr0cur.c line 310.
- Corrigido um erro: se a cache de consultas do MariaDB foi usada, ela não fica invalidada por uma modificação feita por ON DELETE CASCADE ou ...SET NULL.
- Corrigido um erro: se você criar uma tabela temporária dentro de LOCK TABLES, e usar esta tabela temporária, causará um falha de declaração em ha_innobase.cc.
- Corrigido um erro: se você definisse innodb_flush_log_at_trx_commit com 1, SHOW VARIABLES mostraria seu valor como 16 milhões.
MySQL/InnoDB-4.0.3, 28 de Agosto de 2002
- Removido um deadlock desnecessário quando a inserção precisa esperar por um lock de leitura, atualização ou deleção para liberar o lock da próxima chave.
- O comando SQL
HANDLER
do MariaDB agora também funciona para os tipos de tabelaInnoDB
. OInnoDB
faz oHANDLER
sempre ler como leitura consistente.HANDLER
é um caminho de acesso direto a leitura de índices individuais das tabelas. Em alguns casosHANDLER
pode ser usado como um substituto de cursores do lado do servidor. - Corrigido um erro na versão 4.0.2: mesmo uma única inserção podia causar um falha na versão AIX.
- Corrigido um erro: se você usar em um nome de tabela caracteres cujo código é > 127, em DROP TABLE o InnoDB podia falhar na linha 155 de pars0sym.c.
- A compilação do fonte agora fornece um versão funcional, ambas em HP-UX-11 e HP-UX-10.20. A fonte da versão 4.0.2 funciona apenas na versão 11, e a fonte do 3.23.52 apenas na 10.20.
- Corrigido um erro: se compilado em um Solaris 64-bits, o InnoDB produz um erro de bus na inicialização.
MySQL/InnoDB-3.23.52, 16 de Agosto de 2002
- O conjunto de recursos da versão 3.23 será congelada a partir desta versão. Novos recursos irão para o branch da versão 4.0, e apenas erros corrigidos serão feitos para o branch da versão 3.23.
- Muitas consultas joins no limite da CPU agora são executadas mais rápido. No Windows também muitas outras consultas no limite da CPU executar mais rápido.
- Um novo comando SQL, SHOW INNODB STATUS retorna a saída do Monitor InnoDB para o cliente. O Monitor InnoDB agora exibe informações detalhadas no último deadlock detectado.
- O InnoDB faz o otimizador de consultas SQL evitar muito mais varreduras apenas na faixa de índice e escolhe a varredura de toda a tabela. Agora isto está corrigido.
- 'BEGIN' e 'COMMIT' estão agora adicionados no log binário das transações A replicação do MariaDB agora respeita as bordas da transação: um usuário não verá mais meia transações na replicação dos slaves.
- Um slave de replicação agora exibe na recuperação de falhas o última posição do log binário do master que ele podia recuperar.
- Uma nova configuração innodb_flush_log_at_trx_commit=2 faz o InnoDB gravar o log para uma cache de arquivo do sistema operacional a cada commit. Isto é quase tão rápido quanto configurar innodb_flush_log_at_trx_commit=0, e configurar com 2 também tem o recurso no qual em uma falha onde o sistema operacional não teve problemas, nenhuma transação cujo commit foi realizado é perdida. Se osistema operacional falhar ou houver um queda de força,então a configurar com 2 não é mais segura que configurar com 0.
- Adicionado campos de checksum ao bloqueio de log.
- SET FOREIGN_KEY_CHECKS=0 ajuda na importação de tabelas numa ordem arbitrária que não respeita as regras de chaves estrangeiras.
- SET UNIQUE_CHECKS=0 aumenta a velocidade da importação das tabelas dentro do InnoDB se você tiver restrições de chave única em índices secundários.
- SHOW TABLE STATUS agora também lista possíveis ON DELETE CASCADE ou ON DELETE SET NULL no campo de comentário da tabela.
- Quando CHECK TABLE está executando em qualquer tipo de tabela InnoDB, ela agora verifica também o índice hash adaptativo para todas as tabelas.
- Se você definiu ON DELETE CASCADE ou SET NULL e atualizou o chave referenciada no registro pai, o InnoDB deletava ou atualizava o registro filho. Isto está alterado conforme o SQL-92: você recebe o erro 'Cannot delete parent row'.
- Melhorado o algoritmo de auto incremento: agora o primeiro inserte ou SHOW TABLE STATUS inicializa o contador de auto incremento para a tabela. Isto remove quase todos os deadlocks causados pelo SHOW TABLE STATUS.
- Alinhado alguns buffers usados na leitura e escrita dos arquivos de dados. Isto permite usar dispositivos raw sem buffer como arquivos de dados no Linux.
- Corrigido um erro: se você atualizasse a chave primária de uma tabela, podia ocorrer uma falha de declaração em page0page.ic line 515.
- Corrigido um erro: se você deleta ou atualiza um registro referenciado em uma restrição de chave estrangeira e a verificação de chave estrangeira esperapor um lock, então a verificação pode relatar um resultado errôneo. Isto também afeta a operação ON DELETE...
- Corrigido um erro: Um deadlock ou um erro de tempo esgotado na espera do lock no InnoDB causa um rollback de toda a transação, mas o MariaDB ainda podia gravar as instruções SQL no log binário, embora o InnoDB faça um rollback delas. Isto podia, por exemplo, fazer a replicação do banco de dados ficar fora de sincronia.
- Corrigido um erro: se o banco de dados falha no meio de um commit, então a recuperação pode perder páginas de tablespace.
- Corrigido um erro: se você especificar um conjunto de caracteres no my.cnf, então, ao contrário do que está no manual, em uma restrição de chave estrangeira uma coluna do tipo string tinha que ter o mesmo tamanho na tabela que faz a referência e na tabela referenciada.
- Corrigido um erro: DROP TABLE ou DROP DATABASE podiam falhar se houvesse um CREATE TABLE executando simultaneamente.
- Corrigido um erro: se você configurasse a área de buffer com mais de 2GB em um computador de 32 bits, o InnoDB falharia no buf0buf.ic linha 214.
- Corrigido um erro: Em cmputadores de 64 bits,atualizando registros que contenham SQL NULL em algumas colunas faziam o undo log e o ordinary log se tornavam corrupto.
- Corrigido um erro: innodb_log_monitor causava um travamento se ele suprimisse a exibição de locks para uma página.
- Corrigido um erro: na versão HP-UX-10.20, mutexes perderiam memória e causariam condições de corrida e falhariam em alguma parte do código do InnoDB.
- Corrigido um erro: se você rodou em modo AUTOCOMMIT, executou um SELECT, e imeditamente depois um RENAME TABLE, então RENAME falharia e o MariaDB reclamaria com o erro 192.
- Corrigido um erro: se compilado no Solaris 64 bits, o InnoDB produiria um erro de bus na inicialização.
MySQL/InnoDB-4.0.2, 10 de Julho de 2002
- InnoDB is essentially the same as InnoDB-3.23.51.
- If no innodb_data_file_path is specified, InnoDB at the database creation now creates a 10 MB auto-extending data file ibdata1 to the datadir of MySQL. In 4.0.1 the file was 64 MB and not auto-extending.
MySQL/InnoDB-3.23.51, 12 de Junho de 2002
- Corrigido um erro: uma join podia resultar em um segmentation faut ao copiar de uma coluna BLOB para TEXT se alguma das colunas BLOB ou TEXT na tabela continham um valor NULL do SQL.
- Corrigido um erro: se você adicionasse restrições de chaves estrangeiras auto referenciais com ON DELETE CASCADE a tabelas e uma deleção de registro fazia o InnoDB tentar deletar o mesmo registro duas vezes devido a deleção em cascata e então você obtinha um falha de declaração.
- Corrigido um erro: se você usar o 'lock de usuário' do MariaDB e fechasse uma conexão, então o InnoDB podia falhar em ha_innobase.cc, line 302.
MySQL/InnoDB-3.23.50, 23 de Abril de 2002
- O InnoDB agora suporta uma auto extensão do último arquivo de dados. Você não precisa prealocar todos os arquivos de dados na inicialização do banco de dados.
- Faz diversas alterações para facilitar o uso da ferramenta Hot Backup do InnoDB. Esta é uma ferramenta separada paga que você pode usar para tirar backus online do seu banco de dados se desligar o servidor ou configurar qualquer lock.
- Se você quiser executar a ferramenta Hot Backup do InnoDB em um arquivo de dados auto extendido você terá que atualizá-lo para a versão ibbackup-0.35.
- A fase de varredura do log na recuperação de falhas agora executará muito mais rápido.
- A partir desta versão do servidor, a ferramenta de hot backup trunca os fins dos arquivos de dados do backup do InnoDB inutilizados.
- Para permitir que a ferramenta de hot backp funcione, no Windows não usaremos mais E/S sem buffer ou E/S assíncrona nativa; usaremos a mesma assincronia simulada como no Unix.
- Agora você pode definir as cláusulas ON DELETE CASCADE ou ON DELETE SET NULL em caves estrangeiras.
- Restrições de chaves estrangeiras agora sobrevivem a ALTER TABLE e e CREATE INDEX.
- Suprimimos a verificação de FOREIGN KEY se qualquer um dos valores de coluna na chave estrangeira ou chave referenciada a ser verificada é SQL NULL. Isto écompatível com Oracle, por exemplo.
- SHOW CREATE TABLE agora também lista todas as restrições de chaves estrangeiras. O mysqdump também não esquece mais sobre sobre chaves estrangeiras na definiçãode tabelas.
- Agora você pode adicionar uma nova restrição de chave estrangeira com ALTER TABLE ... ADD CONSTRAINT FOREIGN KEY (...) REFERENCES ... (...).
- As definições de FOREIGN KEY agora permitem nomes de tabela e colunas entre aspas invertidas.
- O comando MariaDB SET TRANSACTION ISOLATION LEVEL ... agora tem o seguinte efeito em tabelas InnoDB: se uma transação é definida como SERIALIZABLE então o InnoDB conceitualmente adiciona LOCK IN SHARE MODE para todas as leituras consistentes. Se uma transação é definida com qualquer outro nível de isolação, então o InnoDB obedece sua estratégia de lock padrão que é REPEATABLE READ.
- SHOW TABLE STATUS não configuram mais um x-lock no fim de um índice auto incremento se um contador auto incremento já tiver sido inicializado. Isto remove quase todos os casos de deadlock causados por SHOW TABLE STATUS.
- Corrigido em erro: em uma instrução CREATE TABLE statement a string 'foreign' seguida por caracter que não seja de espaço confuder o analizador do FOREIGN KEY e faz a criação de tabelas falhar com número de erro 150.
MySQL/InnoDB-3.23.49, 17 de Fevereiro de 2002
- Corrigido um erro: se você chamasse DROP DATABASE para um banco de dados no qual haviam consultas executando simultaneamente, o MariaDB podia falhar ou travar. A falha foi corrigida, mas uma correção completa terá que esperar por alguas mudanças na camada de código do MariaDB.
- Corrigido um erro: no Windows deve se colocar o nome do banco de dados em minúsculo para DROP DATABASE funcionar. Corrigido na versão 3.23.49: o caso não é mais problema no Windows. No Unix o nome de banco de dadospermanece caso sensitivo.
- Corrigido um erro: se se definisse um conjunto de caracteres diferente de latin1 como o conjunto de caracteres padrão, então a definição das restrições de chaves estrangeiras podiam falhar em uma declaração em dict0crea.c, relatando um erro interno 17.
MySQL/InnoDB-3.23.48, 09 de Fevereiro de 2002
- Ajustado o otimizador SQL para favorecer busca de índices sobre a varredura de tabelas com mais frequencia.
- Corrigido um problema de performance quando diversas consultas SELECT grandes estão executando concorrentemente em um computados Linux multiprocessador. Grandes consultas SELECT no limite da CPU tambe serão executadas mais rapído em todas as plataformas de uma maneira geral.
- Se olog binário do MariaDB é usado, o InnoD agora exibe, após a recuperação de falhas, o nome do último arquivo de log binário do MariaDB e a posição neste arquivo (=byte offset) que o InnoDB pode recuperar. Isto é útil, por exemplo, quando sincronizar um banco de dados master e um slave na replicação novamente.
- Adicionado uma mensagem de erro melhor para ajudar nos problemas de instalação.
- Pode-se agora recuperar também tabelas temporárias do MariaDB que se tronaram órfão dentro do tablespace do InnoDB.
- O InnoDB agora previne que uma declaração FOREIGN KEY onde o sinal não é o mesmo nas colunas inteiras de referência e referenciada.
- Corrigido um erro: chamar SHOW CREATE TABLE ou SHOW TABLE STATUS poderia causar corrompimento de memória e fazer o mysqld falhar. O mysqldump, especialmente, corria este risco, já que ele chamava SHOW CREATE TABLE com frequencia.
- Corrigido um erro: se no Unix você fazia um ALTER TABLE em uma tabela e, simultaneamente, executava consultas nela, o mysqld podia falhar em uma declaração no row0row.c, linha 474.
- Corrigido um erro: se inserir diversas tabelas contendo uma coluna auto incremento estava envolvida dentro do LOCK TABLES, o InnoDB falhava em lock0lock.c.
- A versão 3.23.47 permitia diversos NULLS em um índice secundário UNIQUE. Mas CHECK TABLE não era relaxed: ele rporta atabela como corrompida. CHECK TABLE não reclama mais nesta situação.
- Corrigido um erro: no Sparc e outros processadores high-endian, SHOW VARIABLES exibia innodb_flush_log_at_trx_commit e outros parâmetros de inicialização booleanos sempre como OFF mesmo se eles estivessem habiliados.
- Corrigido um erro: se você executava mysqld-max-nt como um serviço no Windows NT/2000, a finalização do serviço nãoesperava o suficiente que o desligamento do InnoDb finalizasse.
MySQL/InnoDB-3.23.47, 28 de Dezembro de 2001
- A recuperação agora é mais rápida, especialmente em um sistema de carga leve, pois a verificação do background tem sido feita com mais frequencia.
- O InnoDB permite agora diversos valores de chaves parecidas em um índice secundário UNIQUE se aqueles valores contêm NULLs do SQL. Assim a convenção agora é a mesma das tabelas MyISAM.
- O InnoDB traz uma melhor estimativa de contagem de linhas de uma tabela contendo BLOBs.
- Em uma restrição FOREIGN KEY, o InnoDB agora é caso insensitivo para nomes de colunas e no Windows para nome de tabelas também.
- O InnoDB permite uma coluna FOREIGN KEY do tipo CHAR se referir a uma coluna do tipo VARCHAR e vice versa. O MariaDB silenciosamente troca os tipos de algumas colunas entre CHAR e VARCHAR e estas alterações silenciosas não seguem declarações de FOREIGN KEY mais.
- A recuperação era mais suceptível ao corrompimento de arquivos de log.
- Cálculo de estatísticas desnecessárias forma removidas das consultas que geravam um tabea temporária. Algumas consultas ORDER BY e DISTINCT executarão muito mais rápido agora.
- O MariaDB agora sabe que a varredura de uma tabela InnoDB é feita através de uma chave primária. Isto economizará uma ordenação em algumas consultas ORDER BY.
- O tamanho máximo da chave de tabelas InnoDB está restrita novamente a 500 bytes. O interpretador do MariaDB não pode tratar chaves longas.
- O valor padrão de innodb_lock_wait_timeout foi alterado de infinito para 50 segundos, e o valor padrão de innodb_file_io_threads de 9 para 4.
MySQL/InnoDB-4.0.1, 23 de Dezembro de 2001
- O InnoDB é o mesmo da versão 3.23.47.
- Na versão 4.0.0 o interpretador do MariaDB não conhece a sintaxe de LOCK IN SHARE MODE. Isto foi corrigido.
- Na versão 4.0.0 deleções multi-tabelas não funcionavam para tabelas transacinais, Isto foi corrigido.
MySQL/InnoDB-3.23.46, 30 de Novembro de 2001
- É o mesmo da versão 3.23.45.
MySQL/InnoDB-3.23.45, 23 de Novembro de 2001
- Esta é uma distribuição para correção de erros.
- Nas versões 3.23.42-.44, ao criar uma tabela no Windows você tinha que usar letras minúsculas nos nomes de bancos de dados para poder acessara tabela. Corrigido na versão 3.23.45.
- O InnoDB agora descarrega stdout e stderr a cada 10 segundos; se eles estiverem redirecionados para arquivos, o conteúdo do arquivo pode ser melhor vizualizado com um editor.
- Corrigida um falha em .44, in trx0trx.c, linha 178 quando você removia uma tabela cujo o arquivo .frm não existia dentro do InnoDB.
- Corrigido um erro no buffer de inserção. A árvore do buffer de inserção podia entrar em um estado de inconsistência, causando uma falha, e também falhara recuperação, Este erro podia aparecer, especialmente, em importação de grandes tabelas ou alterações.
- Corrigido um erro na recuperação: o InnoDB podia entrar em loop infinito constantemente exibindo uma mensagem de aviso de que ele não podia encontrar blocos livres na área de buffer.
- Corrigido um erro: quando você criava uma tabela temporária de um tipo InnoDB e então usava ALTER TABLE para ela,o servidor MariaDB podia falhar.
- Previnia a criação das tabeas do sistema do MariaDB, 'mysql.user', 'mysql.host', ou 'mysql.db', no tipo InnoDB.
- Corrigido um erro que podia causar um falha de declaração na versão 3.23.44 em srv0srv.c, linha 1728.
MySQL/InnoDB-3.23.44, 02 de Novembro de 2001
- Você pode definir restrições de chaves estrangeiras em tabelas InnoDB. Um exemplo: FOREIGN KEY (col1) REFERENCES table2(col2).
- Você pode criar arquivos de dados > 4 GB naqueles sistems de arquivos que permitem isto.
- Melhorado os monitores do InnoDB, incluindo um novo innodb_table_monitor que permite que você mostre o conteúdo do dicionário de dados interno do InnoDB.
- DROP DATABASE funcionará também com tabelas InnoDB.
- Caracteres de acento no conjunto de caracteres padrão latin1 serão ordenados de acordo com com a ordenação do MariaDB. NOTA: se você está usando o latin1 e inseriu caracteres cujo código é > 127 em uma coluna CHAR indexada, você deve executar CHECK TABLE em sua tabela quando atualizar para a versão 3.23.43, e remover e reimportar a tabela se CHECK TABLE relatar um erro. reports an error!
- O InnoDB calculará melhor a estmativa da cardinlidade da tabela.
- Alteração na resolução do deadlock: na versão 3.23.43 um deadlock fazia rolls back apenas nas instruções SQL, 3.23.44 faz o rollback de toda a transação.
- Deadlock, esgotamento do tempo de espera do lock e violação das restrições de chave estrangeiras (sem registro pais e registros filhos existentes) agora retorna códigos de erro nativos do MariaDB 1213, 1205, 1216, 1217, respectivamente.
- Um novo parâmetro do my.cnf (innodb_thread_concurrency) ajuda no ajuste de performance em ambientes de alta concorrência.
- Uma nova opção do my.cnf (innodb_force_recovery) lhe ajuda no dump de tabelas de um banco de dados corrompidos.
- Uma nova opção do my.cnf (innodb_fast_shutdown) aumentará a velocidade do desligamento. Normalmente o InnoDB faz uma união total dos buffers de inserção e remoção na finalização.
- Aumentado o tamanho máximo da chave para 7000 bytes de um tamanho anterior de 500 bytes.
- Corrigido um erro na replicação de colunas auto-incremento com inserção de multiplas linhas.
- Corrigido um erro quando o caso das letras alteram em uma atualização de uma coluna de índice secundário.
- Corrigido uma trava quando havia > 24 arquivos de dados.
- Corrigido uma falha quando MAX(col) é selecionado de uma tabela vazia, e col é uma coluna diferente da primeira em um índice multi-colunas.
- Corrigido um erro na remoção que podia causar falhas.
MySQL/InnoDB-3.23.43, 04 de Outubro de 2001
- Ele é essencialmente o mesmo que o InnoDB-3.23.42.
MySQL/InnoDB-3.23.42, 09 de Setembro de 2001
- Corrigido um erro que corrompia a tabela se a chave primária de um registro com mais de 8000-byte fosse atualizado.
- Existem 3 tipos de InnoDB Monitors: innodb_monitor, innodb_lock_monitor, and innodb_tablespace_monitor. Agora o innodb_monitor também mostra a taxa de acerto da área de buffer e o total de registros inseridos, atualizados, deletados e lidos.
- Corrigido um erro em RENAME TABLE.
- Arruamdo um erro em replicação com uma coluna auto-incremento.
MySQL/InnoDB-3.23.41, 13 de Agosto de 2001
- Suporte para < 4 GB de registros. O limite anterior era de 8000 bytes.
- Usa o método de descarga do arquivo de dupla escrita.
- Partições de disco raw suportadas como arquivos de dados.
- InnoDB Monitor.
- Diversos erros corrigidos um erro em
ORDER BY
('Sort aborted') arrumado.
MySQL/InnoDB-3.23.40, 16 de Julho de 2001
- Apenas alguns erros raros foram concertados
MySQL/InnoDB-3.23.39, 13 de Junho de 2001
- Agora
CHECK TABLE
funciona em tabelasInnoDB
. - Um novo parâmetro
innodb_unix_file_flush_method
emmy.cnf
é introduzido. Ele pode ser usado para sintonizar o desempenho da escrita em disco. - Uma coluna auto-increment agora obtem novos valores antes do mecanimo de transação. Isto economiza tempo de CPU e elimina deadlocks em transações em atribuições de novos valores.
- Diversos erros arrumados, o mais importante é o erro de rollback na 3.23.38.
MySQL/InnoDB-3.23.38, 12 de Maio de 2001
- A nova sintaxe
SELECT ... LOCK IN SHARE MODE
é introduzida. - O
InnoDB
agora chamafsync
depois de cada escrita em disco e clacula um checksum para todas as páginas do banco de dados que ele escreve ou lê, revelando defeitos e disco. - Diversos erros arrumados.
Informações de Contato do InnoDB
Informções para contato do Innobase Oy, produtor do mecanismo InnoDB
. Web site: http://www.innodb.com/. E-mail: <sales@innodb.com>
phone: 358-9-6969 3250 (office) 358-40-5617367 (mobile) Innobase Oy Inc. World Trade Center Helsinki Aleksanterinkatu 17 P.O.Box 800 00101 Helsinki Finland
Tabelas BDB
ou BerkeleyDB
- Visão Geral de Tabelas
BDB
- Instalando
BDB
- Opções de Inicialização do
BDB
- Características de Tabelas
BDB
: - Itens a serem corrigidos no
BDB
num futuro próximo: - Sistemas operacionais suportados pelo
BDB
- Restrições em Tabelas
BDB
- Erros Que Podem Ocorrer Usando Tabelas
BDB
Visão Geral de Tabelas BDB
BerkeleyDB, disponível em http://www.sleepycat.com/ tem provido o MariaDB com um mecanismo de armazenamento transacional. O suporte para este mecanismo de armazenamento está incluído na distribuição fonte do MariaDB a partir da versão 3.23.34 e está ativo no binário do MariaDB-Max. Este mecanismo de armazenamento é chamado normalmente de BDB
.
Tabelas BDB
podem ter maior chance de sobrevivência a falhas e também são capazes de realizar operações COMMIT
e ROLLBACK
em transações. A distribuição fonte do MariaDB vem com uma distribuição BDB
que possui alguns pequenos patchs para faze-lo funcionar mais suavemente com o MariaDB. Você não pode usar uma versão BDB
sem estes patchs com o MariaDB.
Na MariaDB Foundation, nós estamos trabalhando em cooperação com a Sleepycat para manter a alta qualidade da interface do MariaDB/BDB.
Quando trouxemos o suporte a tabelas BDB
, nos comprometemos a ajudar os nosso usuários a localizar o problema e criar um caso de teste reproduzível para qualquer problema envolvendo tabelas BDB
. Tais casos de teste serão enviados a Sleepycat que nos ajudará a encontrar e arrumar o problema. Como esta é uma operação de dois estágios, qualquer problema com tabelas BDB
podem levar um tempo um pouco maior para ser resolvido do que em outros mecanismos de armazenamento. De qualquer forma, como o código do BerkeleyDB tem sido usado em autras aplicações além do MariaDB, nós não vemos nenhum grande problema com isto. Leia 'Suporte Oferecido pela MariaDB Foundation'.
Instalando BDB
Se você tiver feito o download de uma versão binária do MariaDB que inclui suporte a BerkeleyDB, simplesmente siga as instruções de instalação de uma versão binária do MariaDB. Leia 'Instalando uma Distribuição Binária do MariaDB'. Leia 'mysqld-max
, om servidor mysqld
extendido'.
Para compilar o MariaDB com suporte a BerkeleyDB, faça o download do MariaDB versão 3.23.34 ou mais novo e configure MariaDB
com a opção --with-berkeley-db
. Leia 'Instalando uma distribuição com fontes do MariaDB'.
cd /path/to/source/of/mysql-3.23.34 ./configure --with-berkeley-db
Por favor, de uma olhada no manual fornecido com a distribuição BDB
para informações mais atualizadas.
Mesmo sendo o BerkeleyDB muito testado e confiável, a interface com o MariaDB ainda é considerada com qualidade gamma. Nós estamos ativamente melhorando e otimizando para torná-la estável o mais breve possível.
Opções de Inicialização do BDB
Se você estiver executando com AUTOCOMMIT=0
então as suas alterações em tabelas BDB
não serão atualizadas até que você execute um COMMIT
. No lugar de commit você pode executar um ROLLBACK
para ignorar as suas alterações. Leia 'Sintaxe de START TRANSACTION
, COMMIT
e ROLLBACK
'.
Se você estiver execuando AUTOCOMMIT=1
(padrão), será feito um commit das sua alterações imediatamente. Você pode iniciar uma transação estendida com o comando SQL BEGIN WORK
, depois do qual não será feito commit de suas alterações ae que você execute COMMIT
(ou faça ROLLBACK
das alterações.)
As seguintes opções do mysqld
podem ser usadas pa alterar o comportamento de tabelas BDB
:
Opção | Descrição |
--bdb-home=directory |
Diretório base das tabelas BDB . Ele deve ser o mesmo diretório usado para --datadir . |
--bdb-lock-detect=# |
Detecção de travas de Berkeley. Pode ser (DEFAULT , OLDEST , RANDOM , ou YOUNGEST ). |
--bdb-logdir=directory |
Diretório de arquivos log de Berkeley DB. |
--bdb-no-sync |
Não sincroniza logs descarregados. |
--bdb-no-recover |
Não inicia Berkeley DB no modo de recuperação. |
--bdb-shared-data |
Inicia Berkeley DB no modo de multi-processos (Não usa DB_PRIVATE ao inicializar Berkeley DB) |
--bdb-tmpdir=directory |
Diretorio de arquivos temporários do Berkeley DB. |
--skip-bdb |
Disabilita o uso de tabelas BDB . |
-O bdb_max_lock=1000 |
Define o número máximo de travas possíveis. Leia 'SHOW VARIABLES '. |
Se você utiliza --skip-bdb
, MariaDB não irá inicializar o biblioteca Berkeley DB e isto irá economizar muita memória. É claro que você não pode utilizar tabelas BDB
se você estiver usando esta opção. Se você tentar criar uma tabela BDB
, o MariaDB criará uma tabela MyISAM
.
Normalmente você deve iniciar mysqld
sem --bdb-no-recover
se você pretende usar tabelas BDB
. Isto pode, no entanto, lhe trazer problemas quando você tentar iniciar o mysqld
e os arquivos de log do BDB
estiverem corrompidos. Leia 'Problemas Inicializando o Servidor MySQL'.
Com bdb_max_lock
você pode especificar o número mácimo de travas (10000 por padrão) que você pode tar ativas em uma tabela BDB
. Você deve aumentá-lo se você obter um erro do tipo bdb: Lock table is out of available locks
ou Got error 12 from ...
quando você fizer transações longas ou quando mysqld
tiver que examinar muitas linhas para calcular a consulta.
Você também pode desejar alterar binlog_cache_size
e max_binlog_cache_size
se você estiver usando transações multi-linhas. Leia 'Sintaxe de START TRANSACTION
, COMMIT
e ROLLBACK
'.
Características de Tabelas BDB
:
- Para estar apto a fazer roolback da transação, o mecanismo de armazenamento
BDB
mantém arquivos de log. Para obter o máximo de desempenho você deve colocar estes arquivos em outro disco diferente do usado por seus bancos de dados usando a opção--bdb-logdir
. - O MariaDB realiza um ponto de verificação a cada vez que um novo arquivo de log do
BDB
é iniciado e remove qualquer arquivo de log que não for necessário para a transação atual. Pode se executarFLUSH LOGS
a qualquer momento para faze um ponto de verificação de tabelas Berkeley DB.
Para recuperação de desastres, deve-se usar backups de tabelas mais log binário do MariaDB. Leia 'Backups dos Bancos de Dados'.
Aviso: Se você delatar arquivos de log antigos que estão em uso, o
BDB
não estará apto a fazer a recuperação e você pode perder dados se algo der errado. - O MariaDB precisa de uma
PRIMARY KEY
em cada tabelaBDB
para poder fazer referência a linha lida anteriormente. Se você não criar um o MariaDB criará uma chave primária oculta para você. A chave oculta tem um tamanho de 5 bytes e é incrementada a cada tentaiva de inserção. - Se todas as colunas que você acessa em uma tabela
BDB
são parte do mesmo índice ou parte de uma chave primária, então o MariaDB pode executar a consulta ser ter que acessar a linha atual. Em uma tabelaMyISAM
o descrito acima é guardado apenas se as colunas são parte do mesmo índice. - A
PRIMARY KEY
será mais rápida que qualquer outra chave, já que aPRIMARY KEY
é armazenada junto com o registro do dado. Como as outras chaves são armazenads como os dados da chave + aPRIMARY KEY
, é importante manter aPRIMARY KEY
o menor possível para economizar disco e conseguir maior velocidade. LOCK TABLES
funciona em tabelasBDB
como nas outras tabelas. Se você não utilizarLOCK TABLE
, MariaDB comandará um bloqueio interno de múltipla-escrita nas tabelas para assegurar que a tabela será bloqueada apropriadamente se outra thread executar um bloqueio de tabela.- Bloqueios internos em tabelas
BDB
é feito por página. SELECT COUNT(*) FROM nome_tabela
é lento pois tabelasBDB
não mantém um contador do número de linha na tabela.- A varredura sequencial é mais lenta que com tabelas
MyISAM
já que os dados em tabelasBDB
são armazenados em árvores-B e não em um arquivo de dados separado. - A aplicação sempre deve estar preparada para tratar casos onde qualquer alteração de uma tabela
BDB
pode fazer um rollback automático e quqlquer leitura pode falhar com um erro de deadlock. - As chaves não são compactadas por prefixo ou por sufixo como em tabelas
MyISAM
. Em outras palavras, a informação da chave gastará um pouco mais de espaço em tabelasBDB
quando comparadas a tabelasMyISAM
. - Existem buracos frequentemente em tabelas
BDB
para permitir que você insira novas linhas no meio da árvore de chaves. Isto torna tabelasBDB
um pouco maiores que tabelasMyISAM
. - O otimizador precisa conhecer aproximadamente o número de linhas na tabela. O MariaDB resolve isto contando inserções e mantendo isto em um segmento separado em cada tabela
BDB
. Se você não executar várias instruçõesDELETE
ouROLLBACK
, este número deverá estar suficientemente próximo do exato para o otimizador do MariaDB, mas como o MariaDB só armazerna o número ao finalizar, ele pode estar incorreto se o MariaDB finalizar inesperadamente. Isto não deve ser fatail mesmo se este número não for 100% correto. POde se atualizar o número de linhas executandoANALYZE TABLE
ouOPTIMIZE TABLE
. Leia 'Sintaxe deANALYZE TABLE
' . Leia 'Sintaxe deOPTIMIZE TABLE
'. - Se você ficar com o seu disco cheio com uma tabela
BDB
, você obterá um erro (provavelmente erro 28) e deve ser feito um rollback da transação. Isto está em contraste com as tabelasMyISAM
eISAM
onde omysqld
irá esperar por espaço suficiente em disco pra continuar.
Itens a serem corrigidos no BDB
num futuro próximo:
- É muito lento abrir muitas tabelas
BDB
ao mesmo tempo. Se você for utilizar tabelasBDB
, você não deve ter um cache de tabela muito grande (> 256) e você deve usar--no-auto-rehash
com o clienteMariaDB
. Nós planejamos arrumar isto parcialmente na versãp 4.0. SHOW TABLE STATUS
ainda mão fornece muitas informações para tabelasBDB
- Otimizar o desempenho.
- Fazer com que não seja utilizado bloqueio de páginas quando varrermos a tabela.
Sistemas operacionais suportados pelo BDB
Atualmente sabemos que o mecanismo de armazenamento BDB
funciona com os seguintes sistemas operacionais:
- Linux 2.x Intel
- Sun Solaris (sparc e x86)
- FreeBSD 4.x/5.x (x86, sparc64)
- IBM AIX 4.3.x
- SCO OpenServer
- SCO UnixWare 7.0.1
Ele não funciona com os seguintes sistemas operacionais.
- Linux 2.x Alpha
- Linux 2.x AMD64
- Linux 2.x IA64
- Linux 2.x s390
- Max OS X
Nota: A lista acima não está completa; atualizaremos ela assim que recebermos mais informações.
Se você construir o MariaDB como suporte a tabelas BDB
e obter o seguinte erro no arquivo de log quando você iniciar o mysqld
:
bdb: architecture lacks fast mutexes: applications cannot be threaded Can't init dtabases
Isto significa que as tabelas BDB
não são suportadas por sua arquitetura. Neste caso você deve reconstruir o MariaDB sem o suporte a tabelas BDB
.
Restrições em Tabelas BDB
Aqui segue as restrições que você tem quando utiliza tabelas BDB
:
- Tabelas
BDB
armazenam no arquivo.db
o caminho para o arquivo no qual ela foi crada. (Isto foi feito para tornar possível detectar travas em um ambiente multi-usuário que suporte links simbólicos)
O efeito disto é que tabelas
BDB
não podem ser movidas entre diretórios! - Ao tirar backups de tabelas
BDB
, você pode utilizarmysqldump
ou tirar backup de todos os arquivosnome_tabela.db
e os arquivos de log doBDB
. Os arquivos de log doBDB
são os arquivos no diretório de dados base chamadolog.XXXXXXXXXX
(dez digitos); O mecanismo de armazenamentoBDB
guarda transações não terminadas em arquivos de log e exige que estes arquivos sejam apresentados quando omysqld
iniciar.
Erros Que Podem Ocorrer Usando Tabelas BDB
- Se você obter o seguinte erro no log
hostname.err
ao iniciar omysqld
:
bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
significa que a nova versão
BDB
não suporta o formato do arquivo de log antigo. Neste caso você tem que deletar todos os logsBDB
do seu diretório de banco de dados (o arquivo com nomes no formatolog.XXXXXXXXXX
) e reiniciar omysqld
. Também recomentdamos que você faça ummysqldump --opt
de sua tabelaBDB
antiga, delete as tabelas antigas e restaure o dump. - Se você não estiver executando em modo auto-commit e deltar uma tabela que é referenciada em outra transação, você pode obter a seguinte mensagem de erro em seu log de erro do MariaDB:
001119 23:43:56 bdb: Missing log fileid entry 001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid
Isto não é fatal mas não recomendamos deletar tabelas se não estiver no modo auto-commit, até que este problema seja resolvido (a solução não é trivial).
Anterior | Próximo | |
Referência de Linguagem do MariaDB | Início | Introdução ao MaxDB |