• Nenhum resultado encontrado

Open Bugs / Deficiˆ encias de Projeto no MySQL

No documento 1 Informa¸c˜ oes Gerais . . . . 1 (páginas 88-94)

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.

No documento 1 Informa¸c˜ oes Gerais . . . . 1 (páginas 88-94)