Índice
MyISAM
MERGE
ISAM
HEAP
InnoDB
InnoDB
BDB
ou BerkeleyDB
BDB
BDB
BDB
BDB
:BDB
num futuro próximo:BDB
BDB
BDB
No MySQL Versão 3.23.6, você pode escolher entre 3 formatos de
tabelas básicos (ISAM
, HEAP
e
MyISAM
). Versões mais novas do MySQL 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 MySQL 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 MySQL 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
. See
Secção 6.5.4, “Sintaxe ALTER TABLE
”.
Note que o MySQL 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 MySQL 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
. See
Secção 7.5.3, “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.
MyISAM
é o tipo de tabela padrão no MySQL
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
. See
Secção 4.5.6.7, “Uso do myisamchk
para Recuperação em Caso de Falhas”. Você pode compactar tabelas
MyISAM
com myisampack
para
utilizar menos espaço. See Secção 4.8.4, “myisampack
, O Gerador de Tabelas Compactadas de Somente Leitura do MySQL”. O itens
seguintes são novos no MyISAM
:
Existe um parâmetro no arquivo MyISAM
que
indica se a tabela foi fechada corretamente. Se o
mysqld
é iniciado com
--myisam-recover
, tabelas
MyISAM
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 um
INSERT/UPDATE
. O valor
AUTO_INCREMENT
pode ser zerado com
myisamchk
. Ele fará colunas
AUTO_INCREMENT
mais rápidas (pelo menos
10%) e números natigos não irão reutilizar como no antigo
ISAM
. Note que quando um
AUTO_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
e TEXT
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 no
ISAM
).
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 colunas
BLOB
e VARCHAR
.
Você pode colocar arquivos de dados e índices em diretórios
diferentes para obter maior velocidade (com a opção
DATA/INDEX DIRECTORY="caminho"
para
CREATE TABLE
). See
Secção 6.5.3, “Sintaxe CREATE TABLE
”.
MyISAM
também suporta os seguintes itens, os
quais o MySQL estará apto a utilizar em um futuro próximo:
Suporte a tipos VARCHAR
reais; uma coluna
VARCHAR
inicia com um tamanho armazenado em
2 bytes.
Tabelas com VARCHAR
podem ter um registro
de tamanho fixo ou dinâmico.
VARCHAR
e CHAR
podem ser
maior que 64K. Todos os segmentos de chaves têm a sua
própria definição de linguagem. Isto habilitará o MySQL
para ter diferentes definições de linguagens por coluna.
Um índice computado em hash pode ser usado para
UNIQUE
. Isto lhe permitirá ter
UNIQUE
em qualquer combinação de colunas
na tabela. (Você não pode procurar em um em um índice
computado UNIQUE
, 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
. See Secção 4.6.8.4, “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 MySQL 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=#
.
See Secção 4.1.1, “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 Secção 4.1.1, “Opções de Linha de Comando do mysqld
”.
O MySQL 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.
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
. See
Secção 6.5.3, “Sintaxe CREATE TABLE
”.
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 MySQL todos os índices sempre podem ser
reconstruídos.
Todas as colunas CHAR
,
NUMERIC
, e DECIMAL
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.
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 valores
NULL
). 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. Use myisamchk -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 com myisamchk -r
.
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 MySQL se tornar GPL
, podem ler
tabelas que forma compactadas com
myisampack
.
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 coluna TINYINT
(1 byte) se todos os valores estão na faixa de
0
a 255
.
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
.
O formato do arquivo que o MySQL 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.
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 MySQL 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
. See
Secção 4.5.4, “Sintaxe de CHECK TABLE
”.
Você pode repara um tabela corrompida com REPAIR
TABLE
. See Secção 4.5.5, “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! See Secção A.4.1, “O Que Fazer Se o MySQL 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. See
Secção E.1.6, “Fazendo um Caso de Teste Se Ocorre um Corrompimento de Tabela”.
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 um
LOCK
e FLUSH TABLES
.
O MySQL ter falhado entre uma atualização e o fechamento final. (Note que a tabela pode ainda estar ok já que o MySQL sempre faz escritas de tudo entre cada instrução.)
Alguém ter feito um myisamchk
--recover
ou myisamchk
--update-state
em uma tabela que estava em uso
por mysqld
.
Muitos servidores mysqld
estrem usando
a tabela e um deles tiver feito um
REPAIR
ou CHECK
da
tabela enquanto ela estava em uso por outro servidor.
Nesta configuração o CHECK
é seguro
de se fazer (mesmo se você obter ovisos de outros
servidor), mas REPAIR
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
são novas no MySQL 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
. See
Secção 4.8.4, “myisampack
, O Gerador de Tabelas Compactadas de Somente Leitura do MySQL”.
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 a MERGE
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 tabelas MERGE
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 tabelas
MERGE
MUITO rápido de fazer ou remapear.
Note que você deve especificar a definição de chave quando
você cria uma tabela MERGE
!.
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 de
memcpy()
para cada leitura).
As desvantagens de tabelas MERGE
são:
Você só pode utilizar tabelas MyISAM
idênticas em uma tabela MERGE
.
REPLACE
não funciona.
Tabelas MERGE
usam mais descritores de
arquivos. Se você estiver usando uma tabela
MERGE
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
armazenamento MERGE
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 chaves MERGE
mais lentas em
pesquisas eq_ref
, mas não em pesquisas
ref
. See Secção 5.2.1, “Sintaxe de EXPLAIN
(Obter informações sobre uma SELECT
)”.
Você não pode fazer DROP TABLE
,
ALTER TABLE
, DELETE FROM
nome_tabela
sem uma cláusula
WHERE
, REPAIR TABLE
,
TRUNCATE TABLE
, OPTIMIZE
TABLE
, ou ANALYZE TABLE
em
nenhuma das tabelas que é mapeada por uma tabela
MERGE
que está "aberta". Se você fizer
isto, a tabela MERGE
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
comando FLUSH TABLES
, assegurando que
nenhuma tabela MERGE
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 um
FLUSH TABLE
na tabela
MERGE
e todas as tabelas selecionadas para
forçar o mecanismo de armazenamento a ler o novo arquivo de
definição.
Segue abaixo os problemas conhecidos com tabelas
MERGE
:
Uma tabela MERGE
não pode manter
restrições UNIQUE
sobre toda tabela.
Quando você faz um INSERT
, os dados vão
para a primeira ou última tabela (de acordo com
INSERT_METHOD=xxx
) e estas tabelas
MyISAM
asseguram que os dados são
únicos, mas não se sabe nada sobre outras tabelas
MyISAM
.
DELETE FROM tabela_merge
usado sem um
WHERE
só limpará o mapeamento da
tabela, não deletando tudo na tabela mapeada.
RENAME TABLE
em uma tabela usada por uma
tabela MERGE
ativa pode corromper a
tabela. Isto será corrigido no MySQL 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 MySQL fará uma
verificação rápida de se o tamanho do registro é igual
entre tabelas mapeadas quando a tabela
MERGE
é 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 índice UNIQUE
em uma tabela
usada em uma tabela MERGE
e então usar
ALTER TABLE
para adicionar um índice
normal na tabela MERGE
, a ordem da chave
será diferente para as atabelas se houvesse uma chave não
única antiga na tabela. Isto ocorre porque ALTER
TABLE
coloca chaves UNIQUE
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 tabela MERGE
não funcionará no
Windows porque o mecanismo de armazenamento
MERGE
faz o mapeamento da tabela
escondido da camada mais alta do MySQL. Como o Windows não
permite que você apague arquivos que estejam abertos, você
deve primeiro descarregar todas as tabelas
MERGE
(com FLUSH
TABLES
) ou apagar a tabela
MERGE
antes de apagar a tabela. Nós
consertaremos isto assim que introduzirmos
VIEW
s.
O tipo de tabela ISAM
, obsoleto, desaparecerá
na versão 5.0. Ele está incluído no fonte do MySQL 4.1 é 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
. See
Secção 4.5.6.7, “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
16 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
. See Secção 7.1, “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 de myisampack
.
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 MySQL não supoortam tabelas
ISAM
.
Tabeals HEAP
usam índices hash e são
armazenadas na memória. Isto as torna muito rápidas, mas se o
MySQL falhar você irá perder todos os dados armazenados nela.
HEAP
é muito útil para tabelas temporárias!
As tabelas HEAP
do MySQL 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ção
CREATE
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 tabelas
MyISAM
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 colunas
BLOB
/TEXT
.
HEAP
não suporta colunas
AUTO_INCREMENT
.
Antes do MySQL 4.0.2, HEAP
não suportava
um índice em uma coluna NULL
.
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
ou DROP TABLE
tabela_heap
.
O MySQL 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 tabela
HEAP
.
Para assegurar que você não vai cometer nenhum erro
acidentalmente, você não pode criar tabelas
HEAP
maiores que
max_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.
InnoDB
O InnoDB
prove o MySQL 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 MySQL 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 MySQL. 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.
A partir do MySQL 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 MySQL 3.23.34a e está ativado no binário MySQL -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 MySQL
que inclui suporte para InnoDB, simplesmente siga as
instruções do manual do MySQL para instalar um vrsão binária
do MySQL. Se você já tem o MySQL-3.23 instalado, então o modo
mais simples de instalar MySQL -Max é substituir i executável
do servidor mysqld
com o executável
correspondente na distribuição -Max. MySQL e MySQL -Max
diferem apenas no executável do servidor. See
Secção 2.2.9, “Instalando uma Distribuição Binária do MySQL”. See
Secção 4.8.5, “mysqld-max
, om servidor mysqld
extendido”.
Para compilar o MySQL com suoprte a InnoDB, faça o download do
MySQL-3.23.34a ou posterior de
http://www.mysql.com/
e configure o MySQL com a opção
--with-innodb
. Veja o manual MySQL sobre como
instalar uma distribuição fonte. See
Secção 2.3, “Instalando uma distribuição com fontes do MySQL”.
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 MySQL. 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. See Secção 7.5.3, “Opções de Inicialização do InnoDB”.
Para habilitar tabelas InnoDB
no MySQL
versão 3.23, veja Secção 7.5.2, “InnoDB no MySQL 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 MySQL 4.0 e MySQL 4.1 é criar um
arquivo ibdata1
auto-extensível de 10 MB
no diretório de dados do MySQL 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 MySQL.
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 MySQL (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 MySQL 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 MySQL 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 MySQL 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
ou
my.ini
deve ser criado.
O arquivo my.cnf
deve ser colocado no
diretótio raiz do drive C:
.
O arquivo my.ini
deve ser colocado no
diretório WINDIR, e.g, C:\WINDOWS
ou
C:\WINNT
. Você pode usar o comando
SET
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 arquivo
my.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 MySQL 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 MySQL 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 MySQL AB é 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 MySQL. 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 MySQL. |
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 MySQL-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 MySQL 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 MySQL. |
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. |
Suponha que você instalou o MySQL e editou
my.cnf
para que ele contenha os parâmetros
de configuração do InnoDB necessários. Antes de iniciar o
MySQL 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 MySQL com o programa cliente MySQL de costume como
mysql
. Quando você finaliza o servidor MySQL
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 MySQL for iniciado
novamente, a saída será a seguinte:
~/mysqlm/sql > mysqld InnoDB: Started mysqld: ready for connections
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 arquivo
my.cnf
ou my.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
ou
innodb_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 MySQL. Então você pode tentar criar o banco de
dados InnoDB novamente.
Suponha que você tenha iniciado o cliente MySQL 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 MySQL criará um
arquivo CUSTOMER.frm
no diretório de banco
de dados test
do MySQL. 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 MySQL 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 MySQL 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.
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.
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 MySQL 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 MySQL 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 MySQL 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 MySQL 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.
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 MySQL, 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 is Waiting 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.
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 MySQL 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 MySQL 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 MySQL novamente. O InnoDB
lhe dirá no inicio que ele está criando novos arquivos de log.
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 MySQL. 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 MySQL 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 MySQL com o sistema de log geral e o arquivamento de log do MySQL ligado. Com sistema de log geral nós queremos dizer o mecanismo de log do servidor MySQL 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 MySQL de acordo com a instrução no manual do MySQL.
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.
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.
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.
SET ... TRANSACTION ISOLATION LEVEL ...
SELECT ... FOR UPDATE
e SELECT ... LOCK IN SHARE MODE
InnoDB
InnoDB
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 MySQL 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
.
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 é chamada
``dirty 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 como READ
COMMITTED
.
READ COMMITTED
Nível de isolamento
parecido com o Oracle. Todas as instruções
SELECT ... FOR UPDATE
e SELECT
... 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 faixa
UPDATE
e DELETE
, o
InnoDB
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 bloquear ``linhas fantasmas''
para a replicação e recuperação no MySQL 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 do InnoDB
.
SELECT ... FOR UPDATE
, SELECT
... LOCK IN SHARE MODE
,
UPDATE
, e DELETE
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 diversas SELECT
s dentro da
mesma transação, elas também são consistentes entre
elas.
SERIALIZABLE
Este nível é como o
anterior, mas todos os SELECT
s são
convertidos implicitamente para SELECT ... LOCK
IN SHARE MODE
.
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.
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.
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.
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 em T
. Faz a busca em
S
como uma leitura consistente, mas
configura travas de chave seguinte compartilhada em
S
se o log do MySQL estiver ligado. O
InnoDB
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 o
SELECT
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. o
InnoDB
define estes bloqueios.
LOCK TABLES ...
: atribui trava a
tabela. Na implementação a camada MySQL de código
atribui este bloqueio. A detecção automatica de
deadlocks do InnoDB
não pode ser feita
onde tais travas de tabelas estão envolvidas: veja a
seção seguinte. Também, uma vez que o MySQL 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. See
Secção 7.5.15, “Restrições em Tabelas InnoDB”.
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 MySQL 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.
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;
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
MySQL 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 baixo READ 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 MySQL
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áusula
FOR UPDATE
ou LOCK IN SHARE
MODE
. Usar o nível de isolamento READ
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 que LOCK TABLES
inicia
implictamente uma transação, assim como o comando
BEGIN
, e UNLOCK
TABLES
finaliza implicitamente uma transação
em um COMMIT
.
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
MySQL nós temos que recorrer ao método do tempo limite
para resolver um deadlock.
Se o aplicativo top
do Unix ou o
Gerenciado 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 arquivo
my.cnf
com 0. O
InnoDB
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 o InnoDB
utiliza é a
função fdatasync
. Se você não estiver
satisfeito com o desempenho da escrita do banco de dados,
você pode tentar configurar
innodb_flush_method
em
my.cnf
com O_DSYNC
,
embora O_DSYNC
pareça ser mais lento em
alguns sistemas.
Ao importar dados para o InnoDB
, esteja
certo de que o MySQL não está com
autocommit=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 tabela
InnoDB
, mesmo sem colocá-los entre
SET 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 dados
InnoDB
.
Tome ciência também de outras grandeas operações com
limite de disco. Use DROP TABLE
ou
TRUNCATE
(a partiir do MySQL-4.0) para
esvaziar uma tabela, não DELETE 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
.
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
mysql
, 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 MySQL
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
MySQL. 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 MySQL: 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 em
univ.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.
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.
O MySQL 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 MySQL 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 MySQL 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.
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.
É 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.
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.
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.
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.
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.
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.
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
MySQL
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.
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
MySQL 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ção IGNORE
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 MySQL e fazem o rollback da instrução correspondente.
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 MySQL de MyISAM PARA InnoDB! Isto não é suportado;
se você fizer isto o MySQL 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 MySQL 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 MySQL
você poderá usar TRUNCATE
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 com
CREATE TABLE ... AUTO_INCREMENT=...
(ou
ALTER TABLE ...
). Para definir este valor
insira uma linha com o valor de menos e delete esta linha.
Multiple tablespaces now available for InnoDB. You can
store each InnoDB type table and its indexes into a
separate .ibd
file into a MySQL
database directory, into the same directory where the
.frm
file is stored.
The MySQL query cache now works for InnoDB tables also if
AUTOCOMMIT=0
, or the statements are
enclosed inside BEGIN ... 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.
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 in
row_mysql_lock_data_dictionary()
.
There are several outstanding non-critical bugs reported in the MySQL bugs database. Their fixing has been delayed, because resources are allocated to the upcoming 4.1.1 release.
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 in page0page.c
, in
function page_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 if
SELECT
was used inside LOCK
TABLES
.
Fixed a bug: if a single DELETE
statement first managed to delete some rows and then
failed in a FOREIGN KEY
error or a
Table is full
error, MySQL did not roll
back the whole SQL statement as it should.
Fixed a bug: if you updated a row so that the 8000 byte
maximum length (without BLOB
and
TEXT
) 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 big BLOB
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 MySQL 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 in t(a
CHAR(200), PRIMARY KEY (a(10)))
on a
fixed-length CHAR
column, InnoDB would
crash even in a simple SELECT
.
CCHECK TABLE
would report the table as
corrupt, also in the case where the created key was not
PRIMARY
.
InnoDB now supports the SAVEPOINT
and
ROLLBACK 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 the
innodb_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 MySQL. 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.
Changed the default value of
innodb_flush_log_at_trx_commit
from 0
to 1. If you have not specified it explicitly in your
my.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: MySQL could erroneously return 'Empty set' if InnoDB estimated an index range size to 0 records though the range was not empty; MySQL also failed to do the next-key locking in the case of an empty index range.
Fixed a bug: GROUP BY
and
DISTINCT
could treat NULL values
inequal.
O InnoDB
agora suporta ALTER
TABLE DROP FOREIGN KEY
. Você deve usar
SHOW 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 de
FOREIGN KEY
e UNIQUE
KEY
detectados. Se você não entender porque o
InnoDB
retorna o erro 150 de um
CREATE TABLE
, você pode utilizar isto
para estudar a razão.
ANALYZE TABLE
agora também funciona
para tabelas do tipo InnoDB
. 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 de ANALYZE
TABLE
podem produzir diferentes números. O
MySQL 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 usar
ANALYZE TABLE
.
A capacidade de commit de grupo do
InnoDB
agora também funciona quando o
log binário do MySQL 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 seu my.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 MySQL
(innodb_max_dirty_pages_pct
). Ela é um
interio na faixa de 0 - 100. O padrão é 90. A thread
principal no InnoDB
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
o InnoDB
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
do InnoDB
era confudida
com as palavras chaves 'foreign key' dentro dos
comentários do MySQL.
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ção
dict_load_table
.
Corrigido um erro: GROUP BY
e
DISTINCT
podia tratar valores
NULL
como diferentes. O MySQL 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ção InnoDB
, 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
e NEXT
também depois de
posicionar o cursor com uma busca única na chave
primária
Corrigido um erro: se MIN()
ou
MAX()
resultasse em um deadlock ou em
esgotamento do tempo de espera do lock, o MySQL não
retornava um erro, mas NULL
como o
valor da função.
Corrigido um erro: o InnoDB
esquecia de
chamar pthread_mutex_destroy()
quando
uma tabela era apagada. Isto podia causar perda de
memória no FreeBSD e outros Unix, exceto o Linux.
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 o
InnoDB
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.
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 MySQL chama store_lock with TL_IGNORE no meio de uma consulta.
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 MySQL 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 MySQL também falhava para fazer o lock da próxima chave no caso de uma faixa de índice vazia.
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 MySQL.
Em INSERT INTO t1 SELECT ... FROM t2 WHERE ... anteriormente o MySQL 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 MySQL 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 MySQL.
Em INSERT INTO t1 SELECT ... FROM t2 WHERE ... anteriormente o MySQL 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 MySQL 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 MySQL. 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.
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.
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.
O InnoDB na versão 4.0.7 é essencialmente o mesmo da in 4.0.6.
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.
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.
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 MySQL 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.
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.
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 MySQL 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.
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 MySQL agora
também funciona para os tipos de tabela
InnoDB
. O InnoDB
faz
o HANDLER
sempre ler como leitura
consistente. HANDLER
é um caminho de
acesso direto a leitura de índices individuais das
tabelas. Em alguns casos HANDLER
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.
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 MySQL 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 MySQL 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 MySQL reclamaria com o erro 192.
Corrigido um erro: se compilado no Solaris 64 bits, o InnoDB produiria um erro de bus na inicialização.
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.
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 MySQL e fechasse uma conexão, então o InnoDB podia falhar em ha_innobase.cc, line 302.
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 MySQL 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.
Corrigido um erro: se você chamasse DROP DATABASE para um banco de dados no qual haviam consultas executando simultaneamente, o MySQL 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 MySQL.
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.
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 MySQL é usado, o InnoD agora exibe, após a recuperação de falhas, o nome do último arquivo de log binário do MySQL 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 MySQL 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.
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 MySQL 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 MySQL 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 MySQL 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.
O InnoDB é o mesmo da versão 3.23.47.
Na versão 4.0.0 o interpretador do MySQL 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.
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 MySQL podia falhar.
Previnia a criação das tabeas do sistema do MySQL, '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.
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 MySQL. 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 MySQL 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.
Ele é essencialmente o mesmo que o InnoDB-3.23.42.
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.
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.
Agora CHECK TABLE
funciona em tabelas
InnoDB
.
Um novo parâmetro
innodb_unix_file_flush_method
em
my.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.
A nova sintaxe SELECT ... LOCK IN SHARE
MODE
é introduzida.
O InnoDB
agora chama
fsync
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.
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
BDB
BDB
BDB
BDB
:BDB
num futuro próximo:BDB
BDB
BDB
BerkeleyDB, disponível em
http://www.sleepycat.com/
tem provido o MySQL com um mecanismo de armazenamento
transacional. O suporte para este mecanismo de armazenamento
está incluído na distribuição fonte do MySQL a partir da
versão 3.23.34 e está ativo no binário do MySQL-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 MySQL vem com uma distribuição BDB
que possui alguns pequenos patchs para faze-lo funcionar mais
suavemente com o MySQL. Você não pode usar uma versão
BDB
sem estes patchs com o MySQL.
Na MySQL AB, nós estamos trabalhando em cooperação com a Sleepycat para manter a alta qualidade da interface do MySQL/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 MySQL, nós não vemos nenhum grande problema com isto.
See Secção 1.4.1, “Suporte Oferecido pela MySQL AB”.
Se você tiver feito o download de uma versão binária do MySQL
que inclui suporte a BerkeleyDB, simplesmente siga as
instruções de instalação de uma versão binária do MySQL.
See Secção 2.2.9, “Instalando uma Distribuição Binária do MySQL”. See
Secção 4.8.5, “mysqld-max
, om servidor mysqld
extendido”.
Para compilar o MySQL com suporte a BerkeleyDB, faça o download
do MySQL versão 3.23.34 ou mais novo e configure
MySQL
com a opção
--with-berkeley-db
. See
Secção 2.3, “Instalando uma distribuição com fontes do MySQL”.
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 MySQL ainda é considerada com qualidade gamma. Nós estamos ativamente melhorando e otimizando para torná-la estável o mais breve possível.
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. See Secção 6.7.1, “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. See
Secção 4.6.8.4, “SHOW VARIABLES ”. |
Se você utiliza --skip-bdb
, MySQL 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 MySQL
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. See
Secção 2.4.2, “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. See Secção 6.7.1, “Sintaxe de START TRANSACTION
, COMMIT
e ROLLBACK
”.
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 MySQL 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 executar FLUSH
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 MySQL. See Secção 4.5.1, “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 MySQL precisa de uma PRIMARY KEY
em
cada tabela BDB
para poder fazer
referência a linha lida anteriormente. Se você não criar
um o MySQL 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 MySQL pode executar a
consulta ser ter que acessar a linha atual. Em uma tabela
MyISAM
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 a PRIMARY
KEY
é armazenada junto com o registro do dado.
Como as outras chaves são armazenads como os dados da chave
+ a PRIMARY KEY
, é importante manter a
PRIMARY KEY
o menor possível para
economizar disco e conseguir maior velocidade.
LOCK TABLES
funciona em tabelas
BDB
como nas outras tabelas. Se você
não utilizar LOCK TABLE
, MySQL
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 tabelas BDB
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 tabelas
BDB
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 tabelas BDB
quando comparadas
a tabelas MyISAM
.
Existem buracos frequentemente em tabelas
BDB
para permitir que você insira novas
linhas no meio da árvore de chaves. Isto torna tabelas
BDB
um pouco maiores que tabelas
MyISAM
.
O otimizador precisa conhecer aproximadamente o número de
linhas na tabela. O MySQL resolve isto contando inserções
e mantendo isto em um segmento separado em cada tabela
BDB
. Se você não executar várias
instruções DELETE
ou
ROLLBACK
, este número deverá estar
suficientemente próximo do exato para o otimizador do
MySQL, mas como o MySQL só armazerna o número ao
finalizar, ele pode estar incorreto se o MySQL 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 executando ANALYZE TABLE
ou
OPTIMIZE TABLE
. See
Secção 4.6.2, “Sintaxe de ANALYZE TABLE
” . See
Secção 4.6.1, “Sintaxe de OPTIMIZE 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 tabelas MyISAM
e ISAM
onde o mysqld
irá esperar por espaço suficiente em disco pra continuar.
É muito lento abrir muitas tabelas BDB
ao mesmo tempo. Se você for utilizar tabelas
BDB
, você não deve ter um cache de
tabela muito grande (> 256) e você deve usar
--no-auto-rehash
com o cliente
mysql
. Nós planejamos arrumar isto
parcialmente na versãp 4.0.
SHOW TABLE STATUS
ainda mão fornece
muitas informações para tabelas BDB
Otimizar o desempenho.
Fazer com que não seja utilizado bloqueio de páginas quando varrermos a tabela.
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 MySQL 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 MySQL sem o suporte a 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 utilizar mysqldump
ou tirar backup
de todos os arquivos nome_tabela.db
e os
arquivos de log do BDB
. Os arquivos de
log do BDB
são os arquivos no diretório
de dados base chamado log.XXXXXXXXXX
(dez
digitos); O mecanismo de armazenamento
BDB
guarda transações não terminadas
em arquivos de log e exige que estes arquivos sejam
apresentados quando o mysqld
iniciar.
Se você obter o seguinte erro no log
hostname.err
ao iniciar o
mysqld
:
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 logs BDB
do seu
diretório de banco de dados (o arquivo com nomes no formato
log.XXXXXXXXXX
) e reiniciar o
mysqld
. Também recomentdamos que você
faça um mysqldump --opt
de sua tabela
BDB
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 MySQL:
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).
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.