1 Informa¸c˜ oes Gerais
1.8 Qual compatibilidade aos padr˜ oes o MySQL oferece ?
1.8.6 Erros Conhecidos e Deficiˆ encias de Projetos no MySQL
1.8.6.2 Open Bugs / Deficiˆ encias de Projeto no MySQL
Os seguintes problemas s˜ao conhecidos e tem prioridade muito alta para serem corrigidos:
• FLUSH TABLES WITH READ LOCK n˜ao bloqueia CREATE TABLE ou COMMIT, que pode criar um problema com a posi¸c˜ao do log bin´ario ao se fazer um backup completo de tabelas e do log bin´ario.
• ANALYZE TABLEem uma tabela BDB pode, em alguns, casos inutilizar a tabela at´e que se reinicie o servidor mysqld. Quando isto acontecer vocˆe ir´a ver o seguinte tipo de erro no arquivo de erros do MySQL.
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
• O MySQL aceita parenteses na parteFROM, mas os ignora sem aviso. A raz˜ao pela qual n˜ao s˜ao retornados erros ´e que muitos clientes que geram consultas automaticamente adicionam parentesis na parte FROM mesmo onde eles n˜ao s˜ao necess´arios.
• Concatenar muitos RIGHT JOINS ou combinar joins LEFT e RIGHT na mesma consulta podem dar uma resposta incorreta ja que o MySQL s´o gera registrosNULLpara tabelas que precedem um join LEFT ou antes de um join RIGHT. Isto ser´a corrigido na vers˜ao 5.0 junto com o suporte a parentesis na parte FROM.
• N˜ao execute ALTER TABLE em uma tabela BDB em que vocˆe estiver executando transa¸c˜oes multi-instru¸c˜oes n˜ao completadas. (A transa¸c˜ao provavelmente ser´a ignorada).
• ANALYZE TABLE,OPTIMIZE TABLEeREPAIR TABLEpodem causar problemas em tabelas para as quais vocˆe estiver usandoINSERT DELAYED.
• Fazendo umLOCK TABLE ..eFLUSH TABLES ..n˜ao garante que n˜ao existem transa¸c˜oes n˜ao terminadas em progresso na tabela.
• Tabelas BDB s˜ao um pouco lentas para abrir. Se vocˆe tiver v´arias tabelas BDB em um banco de dados, gastar´a muito tempo para usar o cliente mysqlno banco de dados se vocˆe n˜ao estiver usando a op¸c˜ao-A ou se vocˆe estiver usandorehash. Isto ´e percebido principalmente quando vocˆe tiver um cache de tabelas grandes.
• A replica¸c˜ao utiliza o log a nivel de consulta: o master grava a consulta no log bin´ario.
Isto ´e um r´apido, compacto e eficiente m´etodo de registro o que funciona perfeitamente
na maioria dos casos. Embora nunca tenhamos ouvido sobre um caso ocorrido, h´a uma chance te´orica que o dado no master e slave sejam diferente se uma consulta ´e feita de tal modo que a modifica¸c˜ao do dado ´e n˜ao determin´istica, isto ´e, deixar ao desejo do otimizador de consultas (o que geralmente n˜ao ´e uma boa pr´atica, mesmo fora da replica¸c˜ao!). Por exemplo:
− CREATE ... SELECTouINSERT ... SELECTque preenchem com zeros ouNULLuma coluna auto_increment.
− DELETE se vocˆe estiver apagando registros de uma tabela que tem chaves es-trangeiras com a propriedade ON DELETE CASCADE.
− REPLACE ... SELECT, INSERT IGNORE ... SELECT se vocˆe tiver valores de chaves duplicados nos dados inseridos.
Se e somente se todos estas consultas N ˜AO tiverem cl´ausulasORDER BYgarantindo uma ordem determin´istica.
Na verdade, por exemplo para INSERT ... SELECT sem ORDER BY, o SELECT pode re-tornar registros em uma ordem diferente (no qual resultar´a em um registro tendo diferentes posi¸c˜oes, obtendo um n´umero diferente na colunaauto_increment), depen-dendo da escolhe feita pelo otimizador no master e slave. Uma consulta ser´a otimizada deiferentemente no master e slave apenas se:
− Os arquivos usados pelas duas consultas n˜ao s˜ao exatamente a mesma; por exemplo OPTIMIZE TABLEfoi executado nas tabelas master e n˜ao nas nas tabelas slave (para corrigir isto, desde o MySQL 4.1.1, OPTIMIZE, ANALYZE e REPAIR s˜ao escritos no log bin´ario).
− A tabela est´a armazenada em um mecanismo de armazenamento diferente no mas-ter e no slave (pode se executar diferentes mecanismos de armazenamento no metre e no slave: por exemplo, InnoDB ne master e MyISAM no slave, se o slave possuir menos espa¸co disppon´ivel em disco).
− The MySQL buffers’ sizes (key_buffer_sizeetc) are different on the master and slave.
− O master e slave executam vers˜oes diferentes do MySQL, e o c´odigo do toimizador
´e diferente entre estas vers˜oes.
Este problema tamb´em pode afetar a restaura¸c˜ao de um banco de dados usando mysqlbinlog|mysql.
O modo mais f´acil de evitar este problema em todos os casos ´e adicionar uma cl´ausula ORDER BYpara tal consulta n˜ao determin´istica assegure que os registros s˜ao sempre ar-mazenados/modificados na mesma ordem. Nas vers˜oes futuras do MySQL adicionare-mos automaticamente uma cl´ausula ORDER BYquando necess´ario.
Os seguintes problemas s˜ao conhecidos e ser˜ao corrigidos na hora certa:
• LIKE n˜ao ´e seguro com caracteres multi-byte. A compara¸c˜ao ´e feita caracter por caracter.
•
Ao usar fun¸c˜oesRPAD, ou qualquer outra fun¸c˜ao string que termina adicionando espa¸cos em branco a direita, em uma consulta que preisa usar tabelas tempor´arias para ser
rsolvida, todas as strings resultantes ser˜ao cortadas a direita (como em RTRIM). Este
´e um exemplo de uma consulta:
SELECT RPAD(t1.field1, 50, ’ ’) AS f2, RPAD(t2.field2, 50, ’ ’) AS f1 FROM table1 as t1 LEFT JOIN table2 AS t2 ON t1.record=t2.joinID ORDER BY t2.record;
O resultado final deste erro ´e que o usu´ario n˜ao conseguira espa¸cos em branco do lado direito do campo resultante.
O comportamento anterior existe em todas as vers˜oes do MySQL.
A raz˜ao disto ´e devido ao fato de tabelas HEAP, que s˜ao usadas primeiro para tabelas tempor´arias, n˜ao s˜ao capazes de tratar colunas VARCHAR.
Este comportamento ser´a corrigido em uma das distribui¸c˜oes da s´erie 4.1.
• Devido ao modo como os arquvos de defini¸c˜oes de tabelas s˜ao armazenados n˜ao se pode usar 255 caracteres (CHAR(255)) em nomes de tabelas, nomes de colunas e enum.
Isto est´a programado para ser corrigido na vers˜ao 5.1 quando temos novos arquivos de formatos de defini¸c˜ao de tabelas.
• Quando estiver usando SET CHARACTER SET, n˜ao ´e permitido usar caracteres especias no nome do banco de dados, tabelas ou campos.
• Pode-se usar _ou %com ESCAPEemLIKE ... ESCAPE.
• se vocˆe tiver uma coluna DECIMALcom um n´umero armazenado em diferentes formatos (+01.00, 1.00, 01.00),GROUP BYpode considerar cada valor como um valor diferente.
• DELETE FROM merge_table usado sem WHERE ir´a apenas apagar o mapeamento para a tabela, n˜ao apagando tudo nas tabelas mapeadas.
• Vocˆe n˜ao pode construir em outro diret´orio quando estiver utilizando MIT-pthreads.
Como isto necessitaria de altera¸c˜oes na MIT-pthreads, n´os n˜ao estamos aptos a corrig´i-la.
• BLOB valores n˜ao podem ser usados com confian¸ca em GROUP BY, ORDER BY ou DISTINCT. Somente os primeiros bytes (padr˜ao 1024) max_sort_length s˜ao usados quando estiver comparando BLOBs nestes casos. Isto pode ser alterado com a op¸c˜ao -0 max_sort_lenght para mysqld. Uma forma de contornar este problema para a maioria dos casos ´e usar a substring: SELECT DISTINCT LEFT(blob,2048) FROM nome_tabela.
• C´alculos s˜ao feitos comBIGINTouDOUBLE(normalmente, ambos tem o tamanho de 64 bits). Depende da precis˜ao utilizada na fun¸c˜ao. A regra geral ´e que fun¸c˜oes bin´arias s˜ao feitas com precis˜ao BIGINT,IF e ELT() com precis˜ao BIGINT ou DOUBLEe o resto com precis˜ao DOUBLE. Devemos evitar o uso de valores sem sinal maiores que 63 bits (9223372036854775807) para qualquer outra coisa al´em de campos bin´arios!
• Todas os campos string, exceto campos do tipo BLOB e TEXTOtem, automaticamente, todos os espa¸cos extras removidos quando recuperados. Para tipos CHAR, isto n˜ao tem problema, e pode ser considerado como um recurso de acordo com o ANSI SQL92. O problema ´e que no MySQL, campos VARCHARs˜ao tratados desta mesma forma.
• Vocˆe s´o pode ter at´e 255 colunas ENUM e SETem uma tabela.
• EmMIN(),MAX() e outras fun¸c˜oes de agrupamente, o MySQL atualmente compara as colunas ENUMe SETpelo valor de suas strings ao inv´es da posi¸c˜ao relativa da string no conjunto.
• mysqld_saferedireciona todas as mensagens demysqldpara o logmysqld. Um prob-lema com isto ´e que se vocˆe executar o mysqladmin refresh para fechar e reabrir o log, a stdoute a stderrcontinuam redirecionadas para o log antigo. Se vocˆe utiliza --log extensivamente, dever´a editar omysqld_safepara logar em ‘’hostname’.err’
em vez de ‘’hostname’.log’; assim vocˆe pode facilmente utilizar o espa¸co do log antigo apagando-o e executandomysqladmin refresh.
• Em instru¸c˜oes UPDATE, colunas s˜ao atualizadas da esquerda para a direita. Se vocˆe referenciar a uma coluna atualizada, vocˆe ir´a obter o valor atualizado em vez do valor original, por exemplo:
mysql> UPDATE nome_tabela SET KEY=KEY+1,KEY=KEY+1;
Isto atualiza KEYcom2no lugar de 1.
• Vocˆe pode se referir a m´ultiplas tabelas em uma mesma consulta, mas vocˆe n˜ao pode se referir a qualquer tabelas tempor´arias dada mais de uma vez. Por exemplo, a seguinte instru¸c˜ao n˜ao funciona.
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
• RENAMEn˜ao funciona com tabelas tempor´arias (TEMPORARY) ou tabelas usadas em uma tabelasMERGE.
• O otimizador pode lidar com oDISTINCTde forma diferente se vocˆe estiver usando col-unas ’escondidas’ em uma join ou n˜ao. Em uma join, colcol-unas escondidas s˜ao contadas como parte do resultado (mesmo se elas n˜ao s˜ao mostradas) enquanto que em queries normais colunas escondidas n˜ao participam na compara¸c˜ao DISTINCT. N´os provavel-mente iremos alterar isto no futuro para nunca comparar as colunas escondidas quando executando DISTINCT.
um exemplo disto ´e:
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;
and
SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9
AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;
No segundo caso, vocˆe pode obter duas linhas idˆenticas no MySQL 3.23.x na s´erie do resultado (porque o campo escondido ’id’ pode variar).
Perceba que isto somente acontece em consultas onde vocˆe n˜ao tem colunas ORDER BY no resultado, algo n˜ao permitido no SQL-92.
• Como o MySQL permite trabalhar com tipos de tabelas que n˜ao suportam transa¸c˜oes (e assim n˜ao pode fazer rollback em dados) algumas coisas funcionam um pouco diferentes de outros servidores SQL em MySQL (Isto serve para garantir que o MySQL nunca necessitar´a de um rollback para um comando SQL). Por´em isto pode ser um pouco estranho em casos que os valores dos campos devem ser verificados na aplica¸c˜ao, mas isto ira fornacer um ´otimo ganho de velocidade assim como permite ao MySQL fazer algumas otimiza¸c˜oes que de outro modo seriam muito dif´iceis para serem feitas.
Se vocˆe informar um valor incorreto em uma coluna, o MySQL, em vez de fazer um rollback, aramzenar´a o melhor valor poss´ivelno campo.
− Se tentar armazenar um valor fora da faixa em uma coluna num´erico, o MySQL ir´a armazenar o menor ou maior valor poss´ivel no campo.
− Se tentar armazenar uma string que n˜ao comece com um n´umero em uma coluna num´erica, o MySQL ir´a armazenar 0 na coluna.
− Se vocˆe tentar armazenar NULL em uma coluna que n˜ao aceita valores nulos, MySQL ir´a armazenar 0 ou ’’ (string vazia) na coluna. (Este comportamento pode, entretanto, ser alterado com a op¸c˜ao de compila¸c˜ao -DDONT USE DEFAULT FIELDS).
− O MySQL permite o armazenamento de alguns valores errados de data em campos do tipoDATE e DATETIME. (Como 2000-02-31 ou 2000-02-00). A id´eia ´e que n˜ao ´e servi¸co do servidor SQL validar datas. Se o MySQL pode armazenar uma data e recuperar extamente a mesma data, ent˜ao o MySQL armazenar´a a data. Se a data estiver totalmente errada, o MySQL ir´a armazenar a data 0000-00-00 no campo.
− Se vocˆe especificar um valor n˜ao suportado para um campo do tipoenum, ele ser´a alterado para o valor de erro ’empty string’, com valor num´erico 0.
− Se vocˆe definir uma colunaSETcom um valor n˜ao suportado, o valor ser´a ignorado.
• Se vocˆe executar uma PROCEDURE em uma pesquisa que retorna uma s´erie vazia, em alguns casos a instru¸c˜ao PROCEDURE n˜ao ir´a transformar as colunas.
• Cria¸c˜ao da tabela do tipo MERGE n˜ao verifiva se as tabelas envolvidas s˜ao de tipos compat´iveis.
• O MySQL ainda n˜ao pode lidar com valoresNaN,-Inf eInfem tipos double. Us´a-los causar´a problemas na exporta¸c˜ao e importa¸c˜ao de dados. Uma solu¸c˜ao intermedi´aria
´e alterarNaN paraNULL (se for poss´ivel) e -Inf e Infpara o valor doublem´inimo ou m´aximo respectivo poss´ivel.
• LIMIT em n´umeros negativos s˜ao tratados como n´umeros grandes positivos.
• Se vocˆe usarALTER TABLEpara primeiro adicionar um ´indiceUNIQUEa uma tabela usada em uma tabela MERGE e ent˜ao usar ALTER TABLE para adicionar um ´indice normal na tabela MERGE, a ordem das chaves ser´a diferente para as tabelas se existir uma chave antiga n˜ao ´unica na tabela. Isto ´e porque o ALTER TABLE coloca chaves UNIQUEantes de chaves normais para ser poss´ivel detectar chaves duplicadas o mais cedo o poss´ivel.
Os seguintes erros s˜ao conhecidos em vers˜oes mais antigas do MySQL:
• Vocˆe pode pendurar um processo se vocˆe fizer um DROP TABLE em uma tabela entre outras que esteja travada com LOCK TABLES.
• No caso seguinte vocˆe pode obter um descarrego de mem´oria para o arquivo core:
− Tratamento de inser¸c˜oes com atraso tem deixado inser¸c˜oes pendentes na tabela.
− LOCK tablecom WRITE
− FLUSH TABLES
• Antes da vers˜ao 3.23.2 do MySQL umUPDATEque atualizava uma chave com umWHERE na mesma chave podia falhar porque a chave era usada para procurar por registros e a mesma linha poderia ter encontrado v´arios itens:
UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY > 100;
Um modo de contornar este erro ´e utilizar:
mysql> UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY+0 > 100;
Isto funcionar´a porque MySQL n˜ao utilizar´a indices em express˜oes com a cl´ausula WHERE.
• Antes da vers˜ao 3.23 do MySQL, todos os tipos num´ericos tratados como campos de pontos fixos. Isto significa que vocˆe tem que especificar quantas casas decimais um campo de ponto flutuante deve ter. Todos os resultados eram retornados com o n´umero correto de casas decimais.
Para erros espec´ificos na plataforma, vejas as se¸c˜oes sobre compila¸c˜ao e portabilidade. Veja Se¸c˜ao 2.3 [Installing source], P´agina 94. Veja Apˆendice D [Porting], P´agina 1069.