Apêndice A. Problemas e Erros Comuns

Índice

A.1. Como Determinar o Que Está Causando Problemas
A.2. Erros Comuns Usando o MySQL
A.2.1. Erro: Access Denied
A.2.2. Erro: MySQL server has gone away
A.2.3. Erro: Can't connect to [local] MySQL server
A.2.4. Erro: Client does not support authentication protocol
A.2.5. Erro: Host '...' is blocked
A.2.6. Erro: Too many connections
A.2.7. Erro: Some non-transactional changed tables couldn't be rolled back
A.2.8. Erro: Out of memory
A.2.9. Erro: Packet too large
A.2.10. Erros de Comunicação / Comunicação Abortada
A.2.11. Erro: The table is full
A.2.12. Erro: Can't create/write to file
A.2.13. Erro no Cliente: Commands out of sync
A.2.14. Erro: Ignoring user
A.2.15. Erro: Table 'xxx' doesn't exist
A.2.16. Erro: Can't initialize character set xxx
A.2.17. Arquivo Não Encontrado
A.3. Assuntos Relacionados a Instalação
A.3.1. Problemas de Ligação com a Biblioteca do Cliente MySQL
A.3.2. Como Executar o MySQL Como Um Usuário Normal
A.3.3. Problemas com Permissões de Arquivos
A.4. Assuntos Relacionados a Administração
A.4.1. O Que Fazer Se o MySQL Continua Falhando
A.4.2. Como Recuperar uma Senha de Root Esquecida
A.4.3. Como o MySQL Trata de Discos Sem Espaço
A.4.4. Onde o MySQL Armazena Arquivos Temporários
A.4.5. Como Proteger ou AlterarHow to Protect or Change the MySQL Socket File /tmp/mysql.sock
A.4.6. Problemas Com Fuso Horário
A.5. Assuntos Relacionados a Consultas
A.5.1. Caso-Sensitivito em Pesquisas
A.5.2. Problemas Usando Colunas DATE
A.5.3. Problemas com Valores NULL
A.5.4. Problemas com alias
A.5.5. Deletando Linhas de Tabelas Relacionadas
A.5.6. Resolvendo Problemas Com Registros Não Encontrados
A.5.7. Problemas com Comparação de Ponto Flutuante
A.6. Assuntos Relacionados ao Otimizador
A.6.1. Camo evitar o varredura da tabela,,,
A.7. Assuntos Relacionados a Definições de Tabelas
A.7.1. Problemas com ALTER TABLE.
A.7.2. Como Alterar a Ordem das Colunas em Uma Tabela
A.7.3. Problemas com TEMPORARY TABLE

Este capítulo lista alguns problemas e mensagens de erro comuns que os usuários encontram. Você aprenderá como entender o problema e o que fazer para resolvê-lo. Você também encontrará soluções apropriadas para alguns prblemas comuns.

A.1. Como Determinar o Que Está Causando Problemas

Quando você encontrar problemas, a primeira coisa que você deve fazer é descobrir qual o programa / parte do equipamento está causando problema:

  • Se você tiver um dos seguintes sintomas, então é provavel que haja um problema de hardware (como memória, placa mãe, CPU ou disco rígido) ou kernel:

    • O teclado não funciona. Isto normalmente pode ser verificado pressionando CAPS LOCK. Se a luz do CAPS LOCK não alterar, você deverá trocar o seu teclado. (Antes de fazer isto, você deve tentar reiniciar o seu computador e verificar todos os cabos do teclado.)

    • O ponteiro do mouse não move.

    • A máquina não responde ao ping de uma máquina remota.

    • Diferente, programas não relacionados não comportam corretamente.

    • Se o seu sistema reiniciar inesperadamente (um programa de nível do usuário nunca deve finalizar o seu sistema).

    Neste caso você deve inciar verificando todos os seus cabos e executando alguma ferramenta de diagnóstico para verificar o seu hardware. Você também deve verificar se existem patches, atualizações ou service packs para o seu sistema operacional que poderiam resolver o seu problema. Verifique também que todas as suas bibliotecas (como glibc) estão atualizadas.

    Sempre é bom usar uma máquina com memória ECC para descobrir problemas de memória antecipadamente.

  • Se o seu teclado está travado, você deve estar apto a consertá-lo logando em sua máquina a partir de outra máquina e executando kbd_mode -a nela.

  • Por favor, examine o seu arquivo de log do sistema (/var/log/messages ou similar) procurando pela razão de seus problemas. Se você acha que o problema está no MySQL então você deve examinar o arquivo de log do MySQL. See Secção 4.10.4, “O Log Binário”.

  • Se você acha que você não tem problema de hardware, você deve tentar encontrar qual o programa que está causando problemas.

    Tente usar top, ps, taskmanager, ou algum programa parecido, para verificar qual programa está utilizando toda a CPU oui travando a máquina.

  • Verifique com top, df, ou um programa similar se você excedeu a quantidade de memória, espaço em disco, arquivos abertos ou algum outro recurso crítico.

  • Se o problema é algum processo em execução, você sempre pode tentar matá-lo. Se ele não quiser morrer, provavelmente há um bug em seu sistema operacional.

Se depois de você examinar todas as outras possibilidades e você tiver concluído que é o cliente MySQL ou o servidor MySQL que está causando problemas, é hora de fazer um relatório de erro para a nossa lista de emails ou nossa equipe de suporte. No relatório de erro, tente dar uma descrição bem detalhada de como o sistema se comporta e o que você acha que está acontecendo. Você também deve dizer porque você acha que é o MySQL que esta causando problemas. Lev em consideração todas as situações neste capítulo. Indique qualquer problema exatamente como ele aparece quando você examina o seu sistema. Use o método 'cortar e colar' para qualquer saída e/ou mensagem de erro do programa e/ou arquivos de log!

Tente descrever em detalhes qual programa não está funcionando e todos os sintomas que você vê! Nós recebemos muitos relatórios de erros que apenas indicavam "o sistema não funciona". Isto não nos fornece qualquer informação sobre o que poderia ser o problema.

Se um programa falhar, sempre é útil saber:

  • O programa em questão realizou um operação de segmentation fault (core dumped)?

  • O program aesta consumindo toda a CPU? Verifique com top. Deixe o programa rodar por um tempo. Ele pode estar avaliando algo pesado.

  • Se é o servidor mysqld que está causando problemas, você pode fazer um mysqladmin -u root ping ou mysqladmin -u root processlist?

  • O que o progrma cliente diz (tente com mysql, por exemplo) quando você tenta conectar ao servidor MySQL? O cliente travou? Você obteve qualquer saída do programa?

Quando enviar um relatório de erro, você deve seguir o que é descrito neste manual. See Secção 1.7.1.2, “Fazendo perguntas ou relatando erros”.

A.2. Erros Comuns Usando o MySQL

Esta seção lista alguns erros que os usuários obtém frequqntemente. Você encontrará descrições de erros e como resolvê-los aqui.

A.2.2. Erro: MySQL server has gone away

Esta seção também cobre o erro relacionado sobre perda de conexão com o servidor durante uma consulta.

A razão mais comum para o erro MySQL server has gone away é que o servidor esgotou o tempo limite e fechou a conexão. Por padrão, o servidor fecha uma conexão depois de 8 horas se nada aconctecer. Você pode alterar o tempo limite configurando a variável wait_timeout quando você iniciar o mysqld.

Outra razão comum para receber o erro MySQL server has gone away é porque você executou um ``fechar'' em sua conexão MySQL a então tentou executar uma consulta na conexão fechada.

Se você tiver um script, você só tem que executar a consulta novamente para o cliente reconectar autometicamente.

Você normalmente pode obter os seguintes códigos de erros neste caso (qual você obterá dependerá do SO):

Código de erroDescrição
CR_SERVER_GONE_ERRORO cliente não pode enviar um pedido ao servidor.
CR_SERVER_LOSTO cliente não obteve um erro ao escrever no servidor, mas não obteve uma resposta completa (ou nenhuma resposta) a seu pedido.

Você também irá obter este erro se alguém tiver matado a thread em execução com kill #threadid#.

Você pode verificar que o MySQL não morreu executando mysqladmin version e examinando o tempo em execução. Se o problema é que o mysqld falhou você deve descobrir a razão da falha. Você deve neste caso iniciar verificando se executar a consulta novamente irá finalizar o MySQL novamente. See Secção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”.

Você também pode obter estes erros se você enviar uma consulta incorreta ou muito grande ao servidor. Se mysqld recebe um pacote muito grande ou fora de ordem. ele assume que alguma coisa saiu errado com o cliente e fecha a conexão. Se você precisa de grandes consultas (por exemplo, se você está trabalhando com grandes colunas BLOB), você pode aumentar o limite da consulta iniciando o mysqld com a opção -O max_allowed_packet=# (padrão 1M). A memória extra é alocada sobre demanda, assim o mysqld alocará mais memória apenas quando você executar uma grande consulta ou quando o mysqld deve retornar um grande registro de resultado!

Você também obterá uma conexão perdida se você estiver enviando um pacote >= 16M e se seu cliente for mais antigo que a versão 4.0.8 e a versão do seu servidor é 4.0.8 e acima ou vice versa.

Se você quiser fazer um relatório de erros descreendo este prolema, esteja certo de ter incluído as seguintes informações:

See Secção 1.7.1.2, “Fazendo perguntas ou relatando erros”.

A.2.3. Erro: Can't connect to [local] MySQL server

Um cliente MySQL em Unix pode conectar ao servidor mysqld de dois modos diferentes: sockets Unix, que conectam através de um arquivo no sistema de arquivos (padrão /tmp/mysqld.sock) ou TCP/IP, que conecta através um número de porta. Sockets Unix são mais rápidos que TCP/IP mas só podem ser usados quando conectados ao servidor no mesmo computador. Sockets Unix são usados se você não especificar um nome de máquina ou se você especificar o nome de máquina especial localhost.

No Windows, se o servidor mysqld está rodando no 9x/Me, você só pode conectar via TCP/IP. Se o servidor estiver rodando no NT/2000/XP e o mysqld é iniciado com --enable-named-pipe, você também pode conectar com named pipes. O nome do named pipes é MySQL. Se você não der um nome de máquina quando conectar ao mysqld, um cliente MySQL tentará conectar primeiro ao named pipe, e se isto não funcionar ele irá conectar a porta TCP/IP. Você pode forçar o uso de named pipes no Windows usando . como nome de máquina.

O erro (2002) Can't connect to ... normalmente significa que não há um servidor MySQL rodando no sistema ou que você está usando um arquivo socket ou porta TCP/IP errado ao tentar conectar so servidor mysqld.

Inicie verificando (usando ps ou gerenciador de tarefas do Windows) que há um processo chamado mysqld executando em seu sistema! Se não houver nenhum processo mysqld, você deve iniciar um. See Secção 2.4.2, “Problemas Inicializando o Servidor MySQL”.

Se um processo mysqld estiver em execução, você pode verificar o servidor tentando estas diferentes conexões (o número da porta e o caminho do socket devem ser diferente em sua consiguração, é claro):

shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip for your host' version
shell> mysqladmin --protocol=socket --socket=/tmp/mysql.sock version

Note o uso de aspas para traz em vez de aspas para frente com o comando hostname; isto provoca a saída de hostname (que é, o nome de máquina atual) para ser substituído no comando mysqladmin.

Aqui estão algumas razões pela quais o erro Can't connect to local MySQL server pode ocorrer:

  • mysqld não está rodando.

  • Você está rodando em um sistema que usa MIT-pthreads. Se você estiver executando em um sistema que não possui threads nativas, o mysqld usa o pacote MIT-pthreads. See Secção 2.2.3, “Sistemas Operacionais suportados pelo MySQL”. No entanto, nem todas as versões de MIT-pthreads suportam sockets Unix. Em um sistema sem suporte a sockets você sempre deve especificar o nome de máquina explicitamente ao conectar ao servidor. Tente usar este comando para verificar a conexão com o servidor:

    shell> mysqladmin -h `hostname` version
    

  • Alguém removeu o socket Unix que o mysqld utiliza (por padrão /tmp/mysqld.sock). Você deve ter um trabalho cron que remove o socket MySQL (por exemplo, um trbalhoque remove arquivos antigos do diretório /tmp). Você sempre pode executar mysqladmin version e verificar que o socket que o mysqladmin está tentando usar realmente existe. A correção neste caso é alterar o trabalho cron para não remover mysqld.sock ou para colocar o socket em outro local. See Secção A.4.5, “Como Proteger ou AlterarHow to Protect or Change the MySQL Socket File /tmp/mysql.sock.

  • Você iniciou o servidor mysqld com a opção --socket=/path/to/socket. Se você alterar o caminho do socket para o servidor, você também deve notificar o cliente MySQL sobre o novo caminho. Você pode fazer isto fornecendo o caminho do socket como um argumento para o cliente. See Secção A.4.5, “Como Proteger ou AlterarHow to Protect or Change the MySQL Socket File /tmp/mysql.sock.

  • Você está usando Linux e uma thread finalizou (core dumped). Neste caso você deve matar as outras threads mysqld (por exemplo, com o script mysql_zap antes de você poder iniciar um novo servidor MySQL. See Secção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”.

  • Você pode não ter privilégios de leitura e escrita tanto no diretório que guarda o arquivo de socket quanto no próprio arquivo de socket. Neste caso você deve mudar o privilégio do diretório/arquivo ou reiniciar mysqld para que ele use um diretorio que você possa utilizar.

Se você obter a mensagem de erro Can't connect to MySQL server on alguma_maquina, você pode tentar o seguinte para descobrir qual é o problema:

  • Verifique se o servidor está funcionando fazendo telnet seu-servidor num-porta-tcp-ip e pressione Enter algumas vezes. Se houver um servidor MySQL em execução nesta porta você deve obter uma resposta que inclui o número da versão do servidor MySQL em execução. Se você obter um erro como telnet: Unable to connect to remote host: Connection refused, então não há nenhum servidor rodando na porta dada.

  • Tente conectar ao daemon mysqld na máquina local e verifique a porta TCP/IP que o mysqld está configurado para usar (variável port) com mysqladmin variables.

  • Verifique se o seu servidor mysqld não foi iniciado com a opção --skip-networking.

A.2.4. Erro: Client does not support authentication protocol

O MySQL 4.1 usa um protocolo de autenticação baseado em um algorítmo de hashing de senha que é incompatível com aquele usado por outros clientes. Se você atualizar o servidor para a versão 4.1, tentar se conectar a ele com um cliente mais antigo pode falhar com a seguinte mensagem:

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

Para resolver este problema você deve fazer um dos seguintes:

  • Atualizar todos os progrmas clientes para usar a biblioteca cliente 4.1.1 ou mais nova.

  • Use uma conta com uma senha antiga ao conectar em clientes anteriores ao 4.1.

  • Reset o usuário que precisa de um cliente anterior ao 4.1 para usar a senha antiga:

    mysql> UPDATE user SET Password = OLD_PASSWORD('mypass')
        -> WHERE Host = 'some_host' AND User = 'some_user';
    mysql> FLUSH PRIVILEGES;
    

  • Diga ao servidor para usar o algoritmo de hashing de senha antigo:

    1. Inicie o mysqld com --old-passwords.

    2. Defina a senha para todos os usuários que tenham senha longa. Você pode encontrar estes usuários com:

      SELECT * FROM mysql.user WHERE LEN(password) > 16;
      

Para mais informações sobre hash de senha e autenticação, veja Secção 4.3.11, “Hashing de Senhas no MySQL 4.1”.

A.2.5. Erro: Host '...' is blocked

Se você obter um erro como este:

Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

significa que o mysqld obteve diversos (max_connect_errors) pedidos de conexão da máquina 'hostname' e que foram interrompidos no eio. Depois de max_connect_errors pedidos com falhas o mysqld assume que algo está errado (como um attack de um cracker), e bloqueia o site para tais conexões até alguém executar o comando mysqladmin flush-hosts.

Por padrão, o mysqld bloqueia um host depois de 10 erros de conexão. Você pode facilmente ajustar isto iniciando o servidor assim:

shell> mysqld_safe -O max_connect_errors=10000 &

Note que se você obter esta mensagem de erro para uma dada máquina, você deve primeiramente verificar se não há nada errado com a conexão TCP/IP desta máquina. Se sua conexão TCP/IP não estiver funcionando, não será nada bom aumentar o valor da variável max_connect_errors!

A.2.6. Erro: Too many connections

Se você obter o erro Too many connections quando vacê tentar se conectar ao MySQL, isto significa que já existe max_connections clientes conectados ao servidor mysqld.

Se você precisar de mais conexões do que o padrão (100), então você deve reiniciar o mysqld com um valor maior para a variável max_connections.

Note que atualmente o mysqld permite que (max_connections+1) clientes se conectem. A última conexão é reservada para um usuário com o privilégio SUPER. Ao não dar este privilégio a usuários normais (eles não precisam dele), um administrador com este privilégio pode logar e utilizar SHOW PROCESSLIST para descobrir o que pode estar errado. See Secção 4.6.8.6, “SHOW PROCESSLIST.

O número máximo de conexões MySQL depende de quão boa é a biblioteca de threads na dada plataforma. Linux ou Solaris devem estar aptos a suportar 500-1000 conexões simultâneas, dependendo de quanta RAM você tem e do que o cliente está fazendo.

A.2.7. Erro: Some non-transactional changed tables couldn't be rolled back

Se você obter o erro/aviso: Warning: Some non-transactional changed tables couldn't be rolled back ao tentar fazer um ROLLBACK, isto significa que algumas das tabelas que você utiliza na transação não suportam transações. Estas tabelas não transacionaisn não serão afetadas pela instrução ROLLBACK.

O caso mais comum em que isto acontece é quando você tenta criar uma tabela de um tipo que não é suportado por seu binário mysqld. Se o mysqld não suporta um tipo de tabela (ou se o tipo de tabela está disabilitado por uma opção de inicialização), ele criará a tabela com o tipo mais comumente usado em suas outras tabelas, que é provavelmente o MyISAM.

Você pode verificar o tipo de uma tabela fazendo:

SHOW TABLE STATUS LIKE 'nome_tabela'. See Secção 4.6.8.2, “SHOW TABLE STATUS.

Você pode verificar as extensão que seu binário mysqld suporta com:

show variables like 'have_%'. See Secção 4.6.8.4, “SHOW VARIABLES.

A.2.8. Erro: Out of memory

Se você executar uma consulta e obter algo como o seguinte erro:

mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory

note que o erro se refere ao cliente MySQL mysql. A razão para este erro é simplesmente que o cliente não possui memória suficente para armazenar todo o resultado.

Para solucionar o problema, primeiro verifique que sua consulta está correta. É razoável que você deva retornar tantos registros? Se for, você pode utilizar mysql --quick, que usa mysql_use_result() para retornar o resultado. Isto coloca menos carga no cliente (mas mais carga nop servidor).

A.2.9. Erro: Packet too large

Quando um cliente MySQL ou o servidor mysqld recebe um pacote maior que max_allowed_packet bytes, ele envia o erro Packet too large e fecha a conexão.

No MySQL 3.23 o maior pacote possível é 16M (devido a limites do protocolo cliente/servidor). No MySQL 4.0.1 e acima el só é limitado pela quantidade de memória que você tem no seu servidor (até um máximo teórico de 2GB).

Um pacote de conexão é uma única instrução SQL enviada ao servidor MySQL ou um única linha enviada para o cliente.

Quando um cliente MySQL ou o servidor mysqld obtem um pacote maior que max_allowed_packet bytes, ele envia o erro Packet too large e fecha a conexão. Com alguns clientes você também pode obter o erro Lost connection to MySQL server during query se o pacote de comunicação for muito grande.

Note que tanto o cliente quanto o servidor tem a sua própria variável max_allowed_packet. Se você quiser tratar os pacotes grandes, você tem que aumentar esta variável tanto no cliente quanto no servidor.

É seguro aumentar esta variável já que a memória só é alocada quando necessário; esta variável é mais uma precaução para pegar pacotes errados entre o cliente/servidor e também para assegurar que você use pacotes grandes acidentalemente e assim fique sem memória.

Se você estiver usando o cliente mysql, você pode especificar um buffer maior iniciando o cliente com mysql --set-variable=max_allowed_packet=8M. Outros clientes tem métodos diferentes de configurar esta variável. Por favor, note que --set-variable está obsoleta desde o MySQL 4.0, em seu lugar utilize --max-allowed-packet=8M.

Você pode utilizar o arquivo de opção para definir max_allowed_packet com um tamanho maior no mysqld. Por exemplo, se você está esperando armazenar o tamanho total de um MEDIUMBLOB em uma tabela, você precisará iniciar o servidor com a opção set-variable=max_allowed_packet=16M.

Você também pode obter problemas estranhos com pacotes grandes se você estiver usando blobs grandes, mas você não deu para mysqld accesso a memória suficiente para tratar a consulta. Se você suspeita que este é o caso, tente adicionar ulimit -d 256000 no inicio do script mysqld_safe e reinicie o mysqld.

A.2.10. Erros de Comunicação / Comunicação Abortada

A partir do MySQL 3.23.40 você só recebe o erro de Conexão abortada se você iniciar o mysqld com --warnings.

Se você encontar erros como o seguinte em seu log de erro.

010301 14:38:23  Aborted connection 854 to db: 'users' user: 'josh'

See Secção 4.10.1, “O Log de Erros”.

Isto significa que algum dos seguintes problemas ocorreu:

Quando o descrito acima ocorrer, a variável Aborted_clients do servidor é incrementeda.

A variável Aborted_connects do servidor é incrementeda quando:

  • Quando um pacote de conexão não contém a informação correta.

  • Quando o usuário não tiver privilégios para conectar ao banco de dados.

  • Quando o usuário usar uma senha errada.

  • Quando levar mais de connect_timeout segundos para obter um pacote de conexão. See Secção 4.6.8.4, “SHOW VARIABLES.

Note que o descrito acima podia indicar que alguém está tentando derrubar o seu banco de dados.

Outras razões para problemas com Clientes abortados / Conexões abortadas.

  • O uso de protocolo Ethernet com Linux, tanto half quanto full duplex. Muitos drivers de Ethernet do Linux possui este bug. Você deve testá-lo transferindo um arquivo enorme via ftp entre estas duas máquinas. Se uma transferência entra no modo de estouro-pausa-esoturo-pausa... então você está experimentando uma síndorme de duplex no Linux A única solução é trocar o modo duplex, tanto da placa de rede quanto do Hub/Switch entre full duplex e half duplex e testar os resultados para decidir qual é a melhor configuração.

  • Alguns problemas com a biblioteca de threads interrompe uma leitura.

  • TCP/IP mal configurado.

  • Defeitos na rede, hub, switch, cabos, ... Isto pode ser diagnosticado de forma apropriada aomente através de reposição de hardware.

  • max_allowed_packet é muito pequeno ou a consulta exige memória livre que você alocou para mysqld. See Secção A.2.9, “Erro: Packet too large.

A.2.11. Erro: The table is full

exitem alguns casos diferentes nos quais você pode obter este erro:

  • Você está usando um versão mais antiga do MySQL (antes da 3.23.0) quando uma tabela temporária em memória se torna maior que tmp_table_size bytes. Para evitar este problema, você pode utilizar a opção -O tmp_table_size=# para fazer o mysqld aumentar o tamanho da tabela temporária ou usar a opção SQL SQL_BIG_TABLES antes de disparar a consulta problematica. See Secção 5.5.6, “Sintaxe de SET.

    Você também pode iniciar mysqld com a opção --big-tables. Isto é extamente o mesmo que usar SQL_BIG_TABLES para toadas as consultas.

    No MySQL Versão 3.23, se uma tabelas temporárias em memória se torna maior que tmp_table_size, o servido automaticamente a converte para tabelas em disco MyISAM.

  • Você está usando tabelas InnoDB e fica sem espaço no tablespace do InnoDB. Neste cado a solução é extender o tablespace do InnoDB.

  • Você está usando tabelas ISAM ou MyISAM em um SO que só suporta arquivos de 2G e você alcançou este limite para os arquivos de dado ou índice.

  • Você está usando tabelas MyISAM e o dado necessário ou tamanho do índice é maior que alqueles para os quais o MySQL alocou ponteiros. (Se você não especificar MAX_ROWS para CREATE TABLE o MySQL só alocará ponteriros para guardar 4G de dados).

    Você pode verificar o tamanho máximo do dados/índice fazendo

    SHOW TABLE STATUS FROM database LIKE 'nome_tabela';
    

    ou usando myisamchk -dv database/nome_tabela.

    Se este é o problema, você pode corrigí-lo fazendo algo como:

    ALTER TABLE nome_tabela MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
    

    Você só precisa especificar AVG_ROW_LENGTH para tabelas com campos BLOB/TEXT já que neste caso o MySQL não pode otimizar o espaço necessário baseado apenas no número de linhas.

A.2.12. Erro: Can't create/write to file

Se você obter um erro do tipo abaixo em suas consultas:

Can't create/write to file '\\sqla3fe_0.ism'.

significa que o MySQL não pode criar um arquivo temporário para o resultado no diretório temporário dado. (O erro acima é um mensagem de erro típica no Windows; a mensagem de erro do Unix é parecida.) A correção é iniciar o mysqld com --tmpdir=path ou adicionar ao seu arquivo de opção:

[mysqld]
tmpdir=C:/temp

assumindo que o diretórioe c:\\temp existe. See Secção 4.1.2, “Arquivo de Opções my.cnf.

Verifique também o código de erro que você obteve com perror. Outra razão pode ser um erro de disco cheio;

shell> perror 28
Error code  28:  No space left on device

A.2.13. Erro no Cliente: Commands out of sync

Se você obter Commands out of sync; you can't run this command now no código de seu cliente, você está chamando funções do cliente na ordem errada.

Isto pode acontecer, por exemplo, se você está utilizando mysql_use_result() e tenta executar uma nova consulta antes de chamar mysql_free_result(). Isto também pode acontecer se você tentar executar duas consultas que retornam dados sem um mysql_use_result() ou mysql_store_result() entre elas.

A.2.14. Erro: Ignoring user

Se você obter o seguinte erro:

Found wrong password for user: 'some_user@some_host'; ignoring user

significa que quando o mysqld foi iniciado ou quando recarregiou a tabela de permissões, ele encontrou uma entrada na tabela user com uma senha inválida. Como resultado, a entrada é simplesmente ignorada pelo sistema de permissões.

As possíveis causas e correções para este problema:

  • Você pode executar uma nova versão do mysqld com uma tabela user antiga. Você pode verificar isto executando mysqlshow mysql user para ver se o campo da senha é menor que 16 caracteres. Se for, você pode corrigir esta condição executando o script scripts/add_long_password.

  • O usuário tem um senha antiga (8 caracteres) e você não iniciou o mysqld com a opção --old-protocol. Atualize o usuário na tabela user com uma nova senha ou reinicie o mysqld com --old-protocol.

  • Você especificou uma senha na tabela de usuário user sem sar a função PASSWORD(). Use mysql para atualizar o usuário na tabela user com uma nova senha. Utilize a função PASSWORD():

    mysql> UPDATE user SET password=PASSWORD('your password')
        ->             WHERE user='XXX';
    

A.2.15. Erro: Table 'xxx' doesn't exist

Se você obter o erro Table 'xxx' doesn't exist ou Can't find file: 'xxx' (errno: 2), significa que não existem tabelas no banco de dados atual com o nome xxx.

Note que como o MySQL utiliza diretórios e arquivos para armazenar banco de dados e tabelas, o nome de banco de dados e tabelas são caso-sensitive! (No Windows o nome de banco de dados e tabelas não são caso-sensitivo mas todas as referências a uma dada tabela dentro de uma consulta devem utilizar o mesmo caso!)

Você pode verificar quais tabelas existem no banco de dados atual com SHOW TABLES. See Secção 4.6.8, “Sintaxe de SHOW.

A.2.16. Erro: Can't initialize character set xxx

Se você obtr um erro do tipo:

MySQL Connection Failed: Can't initialize character set xxx

significa que é um dos seguintes problemas:

  • O conjunto de caracter é multi-byte e você não tem suporte para o conjunto de caracteres no cliente.

    Neste caso você precisa recompilar o cliente com --with-charset=xxx ou com --with-extra-charsets=xxx. See Secção 2.3.3, “Opções típicas do configure.

    Todos os bionários MySQL padrões são compilados com --with-extra-character-sets=complex que habilita o suporte para todos os conjuntos de caracteres multi-byte. See Secção 4.7.1, “O Conjunto de Caracteres Utilizado para Dados e Ordenação”.

  • O conjunto de caracteres é simples e não foi compilado no mysqld e os arquivos de definição do conjunto de caracteres não estão localizados onde o cliente esperava encontrá-los.

    Neste caso você precisa:

    • Recompilar o cliente com suporte ao conjunto de caracteres. See Secção 2.3.3, “Opções típicas do configure.

    • Especificar para o cliente onde o arquivo de definição do conjuntos de caracteres está. Para muitos clientes você pode fazê-lo com a opção --character-sets-dir=path-to-charset-dir.

    • Copie o arquivo de definição de caracteres no caminho onde o cliente espera que eles estejam.

A.2.17. Arquivo Não Encontrado

Se você obter ERROR '...' not found (errno: 23), Can't open file: ... (errno: 24), ou qualquer outro erro com errno 23 ou errno 24 no MySQL, significa que você não alocou descritores de arquivo suficiente para o MySQL. Você pode usar o utilitário perror para obter uma descrição sobre o que o número de erro significa:

shell> perror 23
File table overflow
shell> perror 24
Too many open files
shell> perror 11
Resource temporarily unavailable

O problema aqui é que mysqld está tentando manter aberto muitos arquivos simultanemanete. Você pode também dizer para o mysqld não abrir muitos arquivos de uma vez ou aumentar o número de descritores de arquivos disponíveis para o mysqld.

Para dizer para o mysqld manter aberto poucos arquivos por vez, você pode tornar a cache de tabela menor usando a opção -O table_cache=32 para mysqld_safe (o valor padrão é 64). Reduzindo o valor de max_connections também reduzirá o número de arquivos abertos (o valor padrão é 90).

Para alterar o número de descritores de arquivos disponíveis para mysqld, você pode usar a opção --open-files-limit=# para mysqld_safe ou -O open-files-limit=# para mysqld. See Secção 4.6.8.4, “SHOW VARIABLES. O modo mais fácil de fazer isto é adicioar a opção ao seu arquivo de opção. See Secção 4.1.2, “Arquivo de Opções my.cnf. Se você tiver um versão antiga do mysqld que não suporte isto, você pode editar o script mysqld_safe. Existe uma linha ulimit -n 256 comentada no script. Você pode remover o caracter '#' para ``descomentar'' esta linha, e altere o número 256 para afetar o número de descritores de arquivos disponíveis para mysqld.

ulimit (e open-files-limit) podem aumentar o número de descritorese de arquivo, mas apenas até o limite imposto pelo sistema operacional. Também há um limite 'maior' que só pode ser sobrescrito se você iniciar o mysqld_safe ou mysqld como root (apenas se lembre que você também precisa usar a opção --user=... neste caso). Se você precisa aumentar o limite do SO no número dos descritores de arquivo disponíveis para cada processo, cosulte a documentacão para ser sistema operacional.

Note que se você rodar o shell tcsh, ulimit não funcioará! tcsh também relatará o valor incorreto quando você pergunta pelo limite atual! Neste caso você deve iniciar mysqld_safe com sh!

A.3. Assuntos Relacionados a Instalação

A.3.1. Problemas de Ligação com a Biblioteca do Cliente MySQL

Se você estiver ligando o seu programa e obter o erro de símbolos sem referência que iniciam com mysql_, como os seguintes:

/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'

você deve estar apto a resolvê-los adicionando -Lpath-to-the-mysql-library -lmysqlclient no final da sua linha de ligação.

Se você obter erros de undefined reference (referência indefinida) para as funções descompactadas ou compactadas, adicione -lz no final sa sua linha de ligação e tente novamente!

Se você obter erros de undefined reference (referência indefinida) para funções que devem existir em seu sistema, como connect, verifique a página do man sobre a função em questão para saber quais bibiotecas você deve adicionar a sua linha de ligação!

Se você obter erros de undefined reference (referência indefinida) para funções que não existem em seu sistema, como o seguinte

mf_format.o(.text+0x201): undefined reference to `__lxstat'

normalmente significa que sua biblioteca é compilada em um sistema que não é 100% compatível com o seu. Neste caso você de fazer o download da última distribuição fonte do MySQL e compilá-la você mesmo. See Secção 2.3, “Instalando uma distribuição com fontes do MySQL”.

Se você estiver tentando executar um programa e então obter erros de símbolos sem referência que começam com mysql_ ou que a biblioteca do mysqlclient não pode encontrar, significa que seu sistema não pode encontrar a biblioteca compartilhada libmysqlclient.so.

A correção deste problema é dizer ao seu sistema para buscar onde a biblioteca esta lacolizada usando um dos seguintes métodos:

  • Adicione o caminho ao diretório onde está o libmysqlclient.so à variável de ambiente LD_LIBRARY_PATH.

  • Adicione o caminho ao diretório onde está o libmysqlclient.so à variável de ambiente LD_LIBRARY.

  • Copie libmysqlclient.so a algum local que é pesquisado pelo seu sistema, como /lib, e atualize a informação da biblioteca compartilhada executando ldconfig.

OUtro modo de resolver este problema é ligar o seu programa estaticamente, com -static, ou removendo as bibliotecas dinâmicas do MySQL antes de ligar o seu código. Na próxima vez você deve estar certo que nenhum outro programa esta usando bibliotecas dinâmicas!

A.3.2. Como Executar o MySQL Como Um Usuário Normal

O servidor mysqld pode ser iniciado por qualquer usuário. Para fazer com que o mysqld execute como um usuário nome_usuário do Unix, você deve fazer o seguinte:

  1. Pare o servidor se ele estiver em execução (use mysqladmin shutdown).

  2. Altere o diretório de banco de dados e arquivos para que nome_usuário tenha privilégios de leitura e escrita do arquivo (você pode precisar estar como o usuário root do Unix):

    shell> chown -R nome_usuario /caminho/para/dir_dados/mysql
    

    Se o diretório ou arquivos dentro do diretório de dados do MySQL são links simbolicos, você também precisará seguir estes links e alterar os diretórios e arquivos para os quais ele aponta. chown -R pode não seguir o link simbólico para você.

  3. Inicie o servidor como o usuário nome_usuário, ou, se você está usando o MySQL Versão 3.22 ou mais antiga, inicie o mysqld como o usuário root do Unix e use a opção --user=nome_usuario. mysqld trocará para executar como o usuário nome_usuário do Unix antes de aceitar qualquer conexão.

  4. Para iniciar o servidor automaticamente com o nome de usuário dado na inicialização do sistema, adicione um linha user que especifica o nome do usuário ao grupo [mysqld] do arquivo de opções /etc/my.cnf ou o arquivo de opções my.cnf no diretório de dados do servidor. Por exemplo:

    [mysqld]
    user=nome_usuario
    

Neste ponto, seu processo mysqld deve estar executando bem e redondo como usuário nome_usuario do Unix. No entanto algo não altera: o conteúdo da tabela de permissões. Por padrão (logo depois de executar o script de instalação das tabelas de permissões mysql_install_db), o usuário MySQL root é o único com permissão para acessar o banco de dados mysql ou para criar ou apagar banco de dados. A menos que você tenha alterado estas permissões, elas ainda valem. Isto não deve impedí-lo de de acessar o MySQL como usuário root do MySQL quando você está logado como outro usuário Unix deiferente de root; apenas especifique a opção -u root ao programa cliente.

Note que acessar o MySQL como root, fornecendo -u root na linha de comando é diferente de de executar o MySQL como o usuário root do Unix,or como outro Usuário Unix. A permissão de acesso e nome de usuários do MySQL estão completamente separados dos nomes de usuário do Unix. A única conexão com os nomes de usuário do Unix é que se você não utilizar a opção -u quando chamr o seu programa cliene, o cliente tentará conectar usando seu nome de login do Unix como o seu nome de usuário do MySQL

Se a sua conta Unix não esta segura, você deve pelo menos colocar uma senha no usuário root do MySQL na tabela de acesso. Senão qualquer usuário com uma conta nesta máquina poderá executar mysql -u root nome_bd e fazer o que quiser.

A.3.3. Problemas com Permissões de Arquivos

Se você tiver problemas com permissões de arquivo, por exemplo, se o mysql enviar a seguinte mensagem de erro quando você criar uma tabela:

ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)

então a variável de ambiente UMASK pode estar configurada incorretamente quando o mysqld inicia. O valor umask padrão é 0660. Você pode alterar este comportamento iniciando o mysqld_safe como a seguir:

shell> UMASK=384  # = 600 em octal
shell> export UMASK
shell> /path/to/mysqld_safe &

Por padrão o MySQL criará o banco de dados e diretórios RAID com permissão tipo 0700. Você pode modificar este comportamento configurando a variável UMASK_DIR. Se você definir isto, novos diretórios são criados com a combinação de UMASK e UMASK_DIR. Por exemplo, se você quiser ao grupo a todos os novos diretórios, você pode fazer:

shell> UMASK_DIR=504  # = 770 em octal
shell> export UMASK_DIR
shell> /path/to/mysqld_safe &

No MySQL Versão 3.23.25 e acima, o MySQL assume que o valor para UMASK e UMASK_DIR está em octal se ele iniciar com um zero.

See Apêndice F, Variáveis de Ambientes do MySQL.

A.4. Assuntos Relacionados a Administração

A.4.1. O Que Fazer Se o MySQL Continua Falhando

Todas as versões do MySQL são testadas em muitas plataformas antes de serem distribuídas. Isto não significa que não existe nenhum erro no MySQL, mas significa que se houver erros, eles são poucos e podem ser difíceis de encontrar. Se você tiver u problema, sempre ajudará se você tentar encontrar exatamente o que falhou em seu sistema e assim você terá uma chance muito maior de tê-lo corrigido rapidamente.

Primeiro, você deve tentar descobrir o problema é que o daemon do mysqld morre ou se o seu problema é relativo ao seu cliente. Você pode verificar o quanto tempo o seu servidor mysqld está em execução utilizando o mysqladmin version. Se o mysqld morrer, você pode encontrar a causa disto no arquivo mysql-data-directory/`nome_maquina`.err. See Secção 4.10.1, “O Log de Erros”.

Em alguns sistemas você pode encontrar neste arquivo um stack trace de onde o mysqld finalizou e assim você pode resolver com resolve_back_stack. See Secção E.1.4, “Usando Stack Trace”. Note qte os valores da variável escrita no arquivo .err não podem sempre estar 100% corretas.

Muitas falhas do MySQL são causadas por arquivos de índices/dados corrompidos. O MySQL atualizará os dados em disco, com a chamada de sistema write(), depois de todas as intruções SQL e antes do ser notificado sobre o resultado. (Isto não é verdade se você estiver executando com delay_key_write, caso no qual apenas o dado é escrito.) Insto significa que o dado é salvo mesmo se o mysqld falhar, já que o SO se certificará de que o dado não descarregado esta escrito em disco. Você pode forçar o MySQL a sincronizar tudo para o disco depois de todo comando SQL inicando o mysqld com --flush.

O exposto acimo significa que normalmente você não deve ter tabelas corrompidas a menos que:

  • Alguém/algo finalize o mysqld ou a máquina no meio de uma atualização.

  • Você encontrou um bug no mysqld que faça com que ele finalize no meio de uma atualização.

  • Alguém está manipulando os arquivos de dados/índices de fora do mysqld sem o bloqueio de tabela apropriado.

  • Se você estiver executando muitos servidores mysqld no mesmo dado em um sistema que não suporta bons bloqueios de sistema de arquivos (normalmente tartando o daemon lockd) ou se você está executando multiplos servidores com --skip-external-locking

  • Você tem um arquivo de dados/índices que contem muitos dados errados que deixam o mysqld confuso.

  • Você encontrou um bug no código de armazenamento do dado. Isto não é desejável mas é possível. Neste caso você ode tentar alterar o tipo de arquivo para outro mecanismo de armazenamento usando ALTER TABLE em uma cópia corrigida da tabela!

Por ser muito difícil saber o motivo das falhas, tente primeiro verificar se o que está funcionando para outros está falhando com você. Por favor, tente o seguinte:

Finalize o daemon mysqld com mysqladmin shutdown, execute myisamchk --silent --force */*.MYI em todas as tabelas e reinicie o daemon mysqld. Isto irá assegurar que você está executando de um estado ``limpo''. See Capítulo 4, Administração do Bancos de Dados MySQL.

  • Use mysqld --log e tente determinar a partir da informação no log se alguma consulta específica finalizou o servidor. Aproximadamente 95% de todos os erros são relacionados com um consulta em particular! Normalmente ela é uma das últimas consultas no arquivo de log antes do MySQL reiniciar See Secção 4.10.2, “O Log de Consultas”. Se você puder finalizar o MySQL repetidamente com uma das consultas, mesmo quando você tiver verificado todas as tabelas logo antes de realizá-la, então você estará apto a localizar o bug e deve fazer um relatório de bug para isto! See Secção 1.7.1.3, “Como relatar erros ou problemas”.

  • Tente fazer um caso de teste que possamos utilizar para reproduzir o problema. See Secção E.1.6, “Fazendo um Caso de Teste Se Ocorre um Corrompimento de Tabela”.

  • Tente executar o teste incluso mysql-test e o benchmark do MySQL. See Secção 14.1.2, “Pacotes de Teste do MySQL”. Eles devem testar o MySQL bem. Você também pode adicionar ao benchmark um código que simule a sua aplicação! O benchmark pode ser encontrado no diretório bench na distribuição fonte ou, em uma distribuição binária, no diretório sql-bench sob o diretório de instalação do seu MySQL.

  • Experimente fork_test.pl e fork2_test.pl.

  • Se você configurar o MySQL para depuração, será muito mais fácil para obter informações sobre possíveis erros se alguma coisa der errado. Reconfigure o MySQL com a opção --with-debug ou --with-debug=full no configure e então recompile-o. See Secção E.1, “Depurando um Servidor MySQL”.

  • Configurar o MySQL para depuração faz com que um alocador de memória seja incluído para que se possa encontrar alguns erros. Ele também fornece muita informação sobre o que está acontecendo.

  • Você aplicou todas as últimas correções para o seu sistema operacional?

  • Use a opção --skip-external-locking com o mysqld. Em alguns sistemas, o gerenciador de bloqueios lockd não funciona de forma apropriada; a opção --skip-external-locking faz com que mysqld não utilize bloqueio externo. (Isto significa que você não pode executar 2 servidores mysqld sobre o memo dado e que você deve ser cuidadoso ao utilizar myisamchk, mas pode ser instrutivo tentar a opção como teste).

  • Você tentou mysqladmin -u root processlist quando o mysqld parecia estar rodando mas não respondia? Algumas vezes o mysqld não está <<comatose>> mesmo quando você acha que não. O problema pode ser que todas as conexões estão em uso, o pode haver algum problema interno de bloqueio. mysqladmin processlist normalmente estará apto a fazer uma conexão mesmo nestes casos e pode fornecer informação útil sobre o número conexões atuais e os seus estados.

  • Execute o comando mysqladmin -i 5 status ou mysqladmin -i 5 -r status ou em uma janela separada para produzir estatísticas enquanto você executa outras consultas.

  • Experimente o seguinte:

    1. Inicie o mysqld a partir do gdb (ou em outro depurador). See Secção E.1.3, “Depurando o mysqld no gdb”.

    2. Execute o seu script de testes.

    3. Imprima o <<backtrace>> e as varáveis locais nos 3 níveis mais baixos. No gdb você pode fazê-lo com o seguinte comando quando o mysqld falhar dentro do gdb:

      backtrace
      info local
      up
      info local
      up
      info local
      

      Com gdb você também pode examinar quais threads existem com info threads e troca para uma thread específica com thread #, onde # é a ID da thread.

  • Tente simular a sua aplicação com um script Perl para forçar o MySQL a falhar o mudar o seu comportamento.

  • Envie um relatório de bug normal. See Secção 1.7.1.3, “Como relatar erros ou problemas”. Seja mais detalhista que o normal. Como o MySQL funciona para muitas pessoas, pode ser que as falhas resultem de algo que exista apenas em seu computador (por exemplo, um erro que é relacionado a suas bibliotecas de sistemas em particular).

  • Se você tiver um problema em tabelas com registros do tamanho dinâmico e você não está usando colunas BLOB/TEXT (mas apenas colunas VARCHAR, você pode tentar alterar todas as colunas VARCHAR para CHAR com ALTER TABLE. Isto forçara o MySQL a usar linhas de tamanho fixo. Linhas de tamanho fixo utilizam um pouco mais de espaço extra, mas são muito mais tolerante a corrompimento.

    O código de registro dinâmico atual foi usado pela MySQL AB por pelo menos 3 anos em qualquer problema, mas por natureza os registro de tamanho dinâmico são mais propensos a erros, assim pode ser uma boa idéia tentar o exposto acima para ver se ajuda.

A.4.2. Como Recuperar uma Senha de Root Esquecida

Se você nunca definiu um senha de root para o MySQL, então o servidor não irá exigir uma senha para a conexão como root. É recomendado que sempre seja definida uma senha para cada usuário. See Secção 4.3.2, “Como Tornar o MySQL Seguro contra Crackers”.

Se você tiver definido um senha de root, mas a esqueceu, você pode definir uma nova senha com o seguinte procedimento:

  1. Finalize o daemon mysqld enviando um kill (não kill -9) para o servidor mysqld. O pid é armazenado em um arquivo .pid, que normalmente está no diretório de banco de dados do MySQL:

    shell> kill `cat /mysql-data-directory/hostname.pid`
    

    Você deve ser o usuário root do Unix ou o mesmo usuário com o qual o mysqld está executando para fazer isto.

  2. Reinicie o mysqld com a opção --skip-grant-tables.

  3. Defina uma nova senha com o comando mysqladmin password:

    shell> mysqladmin -u root password 'mynewpassword'
    

  4. Agora você também pode parar o mysqld e reiniciá-lo normalmente, ou apenas carregue a tabela de privilégios com:

    shell> mysqladmin -h hostname flush-privileges
    

  5. Depois disto, você deve estar apto para conectar usando a nova senha.

De forma alternativa, você pode definir a nova senha usando o cliente mysql:

  1. Finalize e reinicie o mysqld com a opção --skip-grant-tables com descrito acima.

  2. Conecte ao servidor mysqld com:

    shell> mysql -u root mysql
    

  3. Dispare os seguintes comandos no cliente mysql:

    mysql> UPDATE user SET Password=PASSWORD('minhanovasenha')
        ->             WHERE User='root';
    mysql> FLUSH PRIVILEGES;
    

  4. Depois disto, você deve estar apto a conectar usando a nova senha.

  5. Você agora pode parar o mysqld e reiniciá-lo normalmente.

A.4.3. Como o MySQL Trata de Discos Sem Espaço

Quando o ocorre uma condição de disco sem espaço, o MySQL faz seguinte:

  • Ele verifica a cada minuto para ver se existe espaço suficiente para escrever a linha atual. Se houver espaço suficiente, ele continua como se nada tivesse aconteciso.

  • A cada 6 minutos ele grava uma entrada no log de arquivo avisando sobre a condição de disco cheio.

Para aliviar o problema, você pode realizar as seguintes ações:

  • Para continuar, você só tem que liberar espaço suficiente em disco para inserir todos os registros.

  • Para abortar a thread, você deve enviar um mysqladmin kill para a thread. A thread será abortada a próxima vez que ele verificar o disco (em 1 minuto).

  • Note que outra thread pode estar esperando pelas tabelas que provocaram a condição de disco cheio. Se você tiver diversas theads ``bloqueadas'', matar a que está esperando pela condição de disco cheio irá permitir as outras threads de continuar.

A exceção ao comportamento acima é quando você usa REPAIR ou OPTIMIZE ou quando os índices são criados em um grupo antes de um LOAD DATA INFILE ou depois de uma instrução ALTER TABLE.

Todos os comandos acima podem usar arquivos temporários grandes que por si próprios poderiam causar grandes problemas para o resto do sistema. Se o MySQL ficar sem espaço em disco enquanto faz qualquer uma das operações acima, ele removerá o arquivo temporário grande e indicara que houve falha na tabela (exceto para ALTER TABLE, no qual a tabela antiga ficará inalterada).

A.4.4. Onde o MySQL Armazena Arquivos Temporários

O MySQL usa o valor da variável de ambiente TMPDIR como caminho para o diretória que aramzena os arquivos temporários. Se você não tiver definido TMPDIR, o MySQL usa o padrão do sistema, que normalmente é /tmp ou /usr/tmp. Se o sistema de arquivo contendo o seu diretório de arquivo temporário é muito pequeno, você deve editar o mysqld_safe para configurar TMPDIR para apontar para um diretório onde você tenha espaço suficiente! Você também pode definir o diretório temporário usando a opção --tmpdir com mysqld.

O MySQL cria todos os arquivos temporários como arquivos ocultos. Isto assegura que os arquivos temporários serão removidos se o mysqld for terminado. A desvantagem de usar arquivos ocultos é que você não verá um arquivo temporário grande que enche o sistema de arquivos no qual o diretório de arquivos temporários está localizado.

Ao ordenar (ORDER BY ou GROUP BY), o MySQL normalmente usa um ou dois arquivos temporários. O espaço em disco máximo que você precisa é:

(tamanho do que é ordenado + sizeof(apontador do banco de dados))
* números de linhas encontradas
* 2

sizeof(apontados do banco de dados) normalmene é 4, mas pode crescer no futuro para tabelas realmente grandes.

Para algumas consultas SELECT, o MySQL também cria tabelas SQL temporárias. Elas não são ocultas e têm nomes da forma SQL_*.

ALTER TABLE cria uam tabela temporária no mesmo diretório da tabela original.

Se você está usando o MySQL 4.1 ou posterior você pode espalhar a carga entre vários discos físicos definindo --tmpdir com uma lista de caminhos separados por dois pontos : (ponto e vírgula ; no Windows). Eles serão feitos através de escalonamento round-robin. Nota: Estes caminhos devem ser de diferentes discos físicos, e não partições diferentes do mesmo disco.

A.4.5. Como Proteger ou AlterarHow to Protect or Change the MySQL Socket File /tmp/mysql.sock

Se você tiver problemas com o fato que de que qualquer um pode deletar o socket de comunicação /tmp/mysql.sock do MySQL, você pode, na maioria das versões Unix, protejer o seu sistema de arquivos /tmp definindo o bit sticky. Conecte como root e faça o seguinte:

shell> chmod +t /tmp

Isto protejerá o seu sistema de arquivos /tmp para que os arquivos só possam ser deletados pelo seus donos ou pelo superusuário (root).

Você pode verificar se o bit sticky está setado executando ls -ld /tmp. Se o último bit de permissão é t, o bit está configurado

Você pode alterar o local onde o MySQL usa/coloca o arquivo de socket da seguinte maneira:

  • Especifique o caminho em uma arquivo de opção local ou global. Por exemplo, coloque em /etc/my.cnf:

    [client]
    socket=path-for-socket-file
    
    [mysqld]
    socket=path-for-socket-file
    

    See Secção 4.1.2, “Arquivo de Opções my.cnf.

  • Especificando isto na linha de comando para o mysqld_safe e na maioria dos clientes com a opção --socket=path-for-socket-file.

  • Especifique o caminho para o socket na variável de ambiente MYSQL_UNIX_PORT.

  • Definindo o caminho com a opção --with-unix-socket-path=path-for-socket-file do configure. See Secção 2.3.3, “Opções típicas do configure.

Você pode testar se o socket funciona com o seguinte comando:

shell> mysqladmin --socket=/path/to/socket version

A.4.6. Problemas Com Fuso Horário

Se você tiver problema com SELECT NOW() retornando valores em GMT e não em sua hora local, você terá que definir a variável de ambinte TZ com a seu fuso horário atual. Isto deve ser feito no ambiente no qual o servidor é executado, por exemplo, em mysqld_safe ou mysql.server. See Apêndice F, Variáveis de Ambientes do MySQL.

A.5. Assuntos Relacionados a Consultas

A.5.1. Caso-Sensitivito em Pesquisas

Por padrão, as pesquisas no MySQL são caso-insensitivo (a menos que haja algum conjunto de caracter que nunca seja caso-insensitivo, com czech). Isto significa que se você buscar com nome_coluna LIKE 'a%', você obterá todos os valores de colunas que iniciam com A ou a. Se você quiser fazer esta busca caso-sensitivo, use algo como INSTR(nome_coluna, "A")=1 para verificar o prefixo. Ou use STRCMP(nome_coluna, "A") = 0 se o valor da coluna deve se exatamente "A".

Operações de comparações simples (>=, >, = , < , <=, ordenando e agrupando) são basedos em cada ``valor de ordenação'' do caracter. Caracteres com o mesmo valor de ordenação (como 'E', 'e' e 'é') são tratados como o mesmo caracter!

Em versões antigas do MySQL, comparações com LIKE eram feitas com o valor de letra maiúscula de cada caracter (E == e mas E <> é). Nas versões mais novas, LIKE funciona assim como os outros operadores de comparação.

Se você quiser que uma coluna sempre seja tratada de modo caso-sensitivo, declare a como BINARY. See Secção 6.5.3, “Sintaxe CREATE TABLE.

Se você está usando caracteres Chineses na codificação big5, você pode tornar todas as colunas de caracteres BINARY. Isto funciona porque a ordenação de caracteres de codificação big5 é baseada na ordem do código ASCII.

A.5.2. Problemas Usando Colunas DATE

O formato de um valor DATE é 'YYYY-MM-DD'. De acordo com o padrão SQL, nenhum outro formato é permitido. Você deve usar este formato em expressões UPDATE e na cláusula WHERE de insrtruções SELECT. Por exemplo:

mysql> SELECT * FROM nome_tabela WHERE date >= '1997-05-05';

Por conveniência, o MySQL converte automaticamente uma data em um número se a data é usada em um contexto numérico (e vice versa). Ele também é esperto o bastante para permitir uma forma de string ``relaxada'' em uma atualização e em uma cláusula WHERE que compara uma data a uma coluna TIMESTAMP, DATE, ou DATETIME. (Forma relaxada significa que qualquer caracter de pontuação pode seu usado como separador entre as partes. Por exemplo, '1998-08-15' e '1998#08#15' são equivalentes). O MySQL também pode converter uma string sem separadores (como '19980815'), desde que ela faça sentido como uma data.

A data especial '0000-00-00' pode ser armazenada e recuperada como '0000-00-00'. Ao usar uma data '0000-00-00' com o MyODBC, ele a converterá automaticamente em NULL em sua versão 2.50.12 e acima, porqie o ODBC não pode tratar este tipo de data.

Como o MySQL realiza a conversão descrita acima, a seguinte instrução funcionará:

mysql> INSERT INTO nome_tabela (idate) VALUES (19970505);
mysql> INSERT INTO nome_tabela (idate) VALUES ('19970505');
mysql> INSERT INTO nome_tabela (idate) VALUES ('97-05-05');
mysql> INSERT INTO nome_tabela (idate) VALUES ('1997.05.05');
mysql> INSERT INTO nome_tabela (idate) VALUES ('1997 05 05');
mysql> INSERT INTO nome_tabela (idate) VALUES ('0000-00-00');

mysql> SELECT idate FROM nome_tabela WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM nome_tabela WHERE idate >= 19970505;
mysql> SELECT MOD(idate,100) FROM nome_tabela WHERE idate >= 19970505;
mysql> SELECT idate FROM nome_tabela WHERE idate >= '19970505';

No entatnto o seguinte não funcionará:

mysql> SELECT idate FROM nome_tabela WHERE STRCMP(idate,'19970505')=0;

STRCMP() é uma função string, assim ela converte idate em uma string e realiza um comparação de string. Ela não converte '19970505' em uma datae e realiza uma comparaçãas de data.

Note que o MySQL faz uma verificação muito limitada da validade da data. Se você aramazenar uma data incorreto, tal como '1998-2-31', a data invalida será armazenada.

Como o MySQL empacota a data para armazenamento, ele não pode armazenar qualquer data dada como já que ela não caberia dentro do buffer de resultado. As regras de aceitação das datas são:

  • Se o MySQL pode armazenar e recuperar um data dada, a data errada é acieta para colunas DATE e DATETIME.

  • Todos os valores de dia entre 0-31 são aceitos para qualquer data. Isto torna muito conveniente para plicações web nas quais você pede ano, mês e dia em 3 campos diferentes.

  • O campo do dia ou mês pode ser zero. Isto é conveniente se você quiser armazenar uma data de aniversário em uma coluna DATE e você não sabea parte da data.

Se a data não pode ser convertida para qualquer valor razoável, um 0 é armazenado no campo DATE, o qual será recuperado como 0000-00-00. Isto é uma questão tanto de velocidade quanto de conveniência já que acreditamos que a responsabilidade do banco de dados é recuperar a mesma data que você armazenou (mesmo se a data não era logicamente correta em todos os casos). Nós pensamos que é papel da aplicação verificar as datas, e não do servidor.

A.5.3. Problemas com Valores NULL

O conceito do valor NULL é uma fonte comum de confusão para os iniciantes em SQL, que frequentemente pensa que NULL é a mesma coisa que uma string vazia "". Este não é o caso! Por exemplo, as seguintes intruções são completamente diferentes:

mysql> INSERT INTO minha_tabela (telefone) VALUES (NULL);
mysql> INSERT INTO minha_tabela (telefone) VALUES ("");

Ambas as intruções inserem um valor na coluna telefone, mas a primeira insere um valor NULL e a segunda insere uma string vazia. O significado do primeiro pode ser considerado como ``telefone não é conhecido'' e o significado da segunda pode ser considerado como ``ela não tem telefone''.

Em SQL, o valor NULL é sempre falso em coparação a qualquer outro valor, mesmo NULL. Uma expressão que contém NULL sempre produz um valor NULL a menos que seja indicado na documentação para os operadores e funções involvidos na expressão. Todas as colunas no seguinte exemplo retornam NULL:

mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);

Se você quiser procurar por uma coluna cujo valor é NULL, você nãp pode usar o teste =NULL. A seguinte instrução não retorna nenhuma linha, pois expr = NULL é FALSO, para qualquer expressão:

mysql> SELECT * FROM minha_tabala WHERE phone = NULL;

Para procurar por valores NULL, você deve usar o teste IS NULL. A seguir mostramos como encontrar o némuro de telefone NULL e o número de telefone vazio:

mysql> SELECT * FROM minha_tabela WHERE telefone IS NULL;
mysql> SELECT * FROM minha_tabela WHERE telefone = "";

Note que você pode adicionar um índice a uma coluna que tenha valores NULL apenas se você estiver usando o MySQL versão 3.23.2 ou mais novo e estiver usando tipos de tabelas NyISAM, InnoDB ou BDB. Em versões anteriores e com outros tipos de tabelas, você deve declara tais colunas como NOT NULL. Isto também significa que você então não poderá inserir NULL em uma coluna indexada.

Ao ler dados com LOAD DATA INFILE, colunas vazias são atualizadas com ''. Se você quiser um valor NULL em uma coluna, você deve usar \N no arquivo texto. A palavra literal 'NULL' também pode ser usada em algumas circunstâncias. See Secção 6.4.8, “Sintaxe LOAD DATA INFILE.

Ao usar ORDER BY, valores NULL são apresentados primeiro, ou por último se você especificar DESC para armazenar em ordem decrescente. Exceção: Nos MySQL 4.0.2 até 4.0.10, se você armazenar em ordem decrescente usando DESC, valores NULL são apresentados por último.

Ao usar GROUP BY, todos os valores NULL são considerados iguais.

Funções de agrupamento (resumo) como COUNT(), MIN() e SUM() ignoram valores NULL. A exceção a isto é COUNT(*), que conta linhas e não colunas individuais. Por exemplo, a seguinte instrução deve produzir duas contagens. A primeira é a contagem do número de linhas na tabela e a segunda é a contagem do número de valores diferentes de NULL na coluna age:

mysql> SELECT COUNT(*), COUNT(age) FROM person;

Para ajudar com o tratamento de NULL, você pode usar os operadores IS NULL e IS NOT NULL e a função IFNULL().

Para alguns tipos de colunas, valores NULL são tratados de forma especial, Se você inserir NULL na primeira coluna TIMESTAMP de uma tabela, a data e hora atual serão inseridos. Se você isere NULL em uma coluna AUTO_INCREMENT, o próximo número na sequência é inserida.

A.5.4. Problemas com alias

Você pode usar um alias para referir a uma coluna no GROUP BY, ORDER BY, ou na parte HAVING. Aliases podem ser usados para dar as colunas nomes melhores:

SELECT SQRT(a*b) as rt FROM nome_tabela GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM nome_tabela GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM nome_tabela;

Note que o padrão SQL não permite que você se refira a uma alias na cláusula WHERE. Isto é porque quando o código WHERE é executado o valor da coluna ainda não pode ser determinado. Por exemplo, a seguinte consulta é ilegal:

SELECT id,COUNT(*) AS cnt FROM nome_tabela WHERE cnt > 0 GROUP BY id;

A instrução WHERE é executada para determinar quais linhas devem ser incluídas na parte GROUP BY enquanto HAVING é usado para decidir quais linhas o conjunto de resultados deve usar.

A.5.5. Deletando Linhas de Tabelas Relacionadas

Como o MySQL não suporta subconsultas (antes da versão 4.1), enm o uso de mais de uma tabela na instruçao DELETE (antes da versão 4.0), você deve usar a seguinte abordagem para deletar linhas de 2 tabelas relacionadas:

  1. SELECT as linhas baseado em alguma condição WHERE na tabela principal.

  2. DELETE as linhas da tabela princiapl basada nas mesmas condições.

  3. DELETE FROM tabela_relacionada WHERE coluna_relacionada IN (linhas_selecionadas).

Se o número total de caracteres na consulta com colunas_relacionadas é maior que 1,048,576 (o valor padrão de max_allowed_packet, você deve separá-lo em duas partes menores e executar múltiplas instruções DELETE. Você provavelmente obterá o DELETE mais rápido apenas delatando 100-1000 ids de colunas_relacionadas por consulta se colunas_relacionadas é um índice. Se colunas_relacionadas não é um índice, a velocidadi é independente do número de argumentos na cláusula IN.

A.5.6. Resolvendo Problemas Com Registros Não Encontrados

If you have a complicated query that has many tables and that doesn't return any rows, you should use the following procedure to find out what is wrong with your query:

  1. Teste a consulta com EXPLAIN e verifique se você pode encontrar alguma coisa que está errada. See Secção 5.2.1, “Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)”.

  2. Selcione apenas aqueles campos que são usados na cláusula WHERE.

  3. Remova uma tabela por vez da consulta até que ela retorne alguns registros. Se as tabelas são grandes, é uma boa idéia usar LIMIT 10 com a consulta.

  4. Faça um SELECT da coluna encontrou um registro com a tabela que foi removido por última da consulta.

  5. Se você estiver comparando colunas FLOAT ou DOUBLE com números que tenham decimais, você não pode usar '='. Este problema é comum na maioria das linguagens de computadores porque valores de ponto-flutuante não são valores exatos. Na maioria dos casos, alterar o FLOAT por DOUBLE corrigirá isto. See Secção A.5.7, “Problemas com Comparação de Ponto Flutuante”.

  6. Se você ainda não pode imaginar o que está errado, crie um teste mínimo que possa ser executado com mysql test < query.sql e possa mostrar seus problemas. Você pode criar um arquivo de teste com mysqldump --quick banco_de_dados tabela > query.sql. Abra o arquivo em um editor, remova algumas linhas inseridas (se houver muitas) e adicione sua instrução select no fim do arquivo.

    Teste se você ainda está tendo problemas fazendo:

    shell> mysqladmin create test2
    shell> mysql test2 < query.sql
    

    Envie o arquivo de teste usando mysqlbug para lista de email gerais do MySQL. See Secção 1.7.1.1, “As Listas de Discussão do MySQL”.

A.5.7. Problemas com Comparação de Ponto Flutuante

Números de ponto flutuante geram confusões algumas vezes, pois estes números não são armazenados como valores exatos dentro da arquitetura dos computadores. O que pode ser ver na tela não é o valor exato do número.

Tipos de campos FLOAT, DOUBLE e DECIMAL são assim.

CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
(2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
(4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
(5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
(6, 0.00, 0.00), (6, -51.40, 0.00);

mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i    | a      | b     |
+------+--------+-------+
|    1 |  21.40 | 21.40 |
|    2 |  76.80 | 76.80 |
|    3 |   7.40 |  7.40 |
|    4 |  15.40 | 15.40 |
|    5 |   7.20 |  7.20 |
|    6 | -51.40 |  0.00 |
+------+--------+-------+

O resultado está correto. Embora pareça que os primeiros cinco registros não devessem passar no teste de comparação, eles deviam porque a diferença entre o número mostrado está na décima casa decimal ou depende da arquitetura do computador.

O problema não pode ser resolvido usando ROUND() (ou função similar), porque o resultado ainda é um número de ponto flutuante. Exemplo:

mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i    | a      | b     |
+------+--------+-------+
|    1 |  21.40 | 21.40 |
|    2 |  76.80 | 76.80 |
|    3 |   7.40 |  7.40 |
|    4 |  15.40 | 15.40 |
|    5 |   7.20 |  7.20 |
|    6 | -51.40 |  0.00 |
+------+--------+-------+

É assim que o número da coluna 'a' se parece:

mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a,
    -> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b;
+------+----------------------+-------+
| i    | a                    | b     |
+------+----------------------+-------+
|    1 |  21.3999999999999986 | 21.40 |
|    2 |  76.7999999999999972 | 76.80 |
|    3 |   7.4000000000000004 |  7.40 |
|    4 |  15.4000000000000004 | 15.40 |
|    5 |   7.2000000000000002 |  7.20 |
|    6 | -51.3999999999999986 |  0.00 |
+------+----------------------+-------+

Dependendo da arquitetura do computador você pode ou não ver resultados similares. Cada CPU pode avaliar um númere de ponto flutuante de forma diferente. Por exemplo, em alguma máquinas você pode obter resultados 'corretos' multiplicando ambos argumentos por 1, como no exemplo a seguir.

AVISO: NUNCA CONFIE NESTE MÉTODO EM SUAS APLICAÇÕES, ESTE É UM EXEMPLO DE UM MÉTODO ERRADO!!!

mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+------+
| i    | a      | b    |
+------+--------+------+
|    6 | -51.40 | 0.00 |
+------+--------+------+

A razão pela qual o método acima parece funcionar é que na máquina onde o teste foi realizado, a CPU de aritimética de ponto flutuante é realizada arredondando números para serem iguais, mas não há nenhuma regra que qualquer CPU deva fazer assim, então isto não é confiável.

O modo correto de fazermos comparações de ponto flutuante é primeiro decidir qual é a tolerância desejada entre os números e então fazer a comparação com o número tolerado. Por exemplo, se nós concordarmos que números de ponto flutuante devem ser considerados o mesmo, se eles forem o mesmo com precisão de quatro casas deciamis (0.0001), a comparação deve ser feita assim:

mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
    -> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+--------+------+
| i    | a      | b    |
+------+--------+------+
|    6 | -51.40 | 0.00 |
+------+--------+------+
1 row in set (0.00 sec)

E vice-versa, se nós quisermos obter registros onde os números são o mesmo, o teste seria:

mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
    -> GROUP BY i HAVING ABS(a - b) < 0.0001;
+------+-------+-------+
| i    | a     | b     |
+------+-------+-------+
|    1 | 21.40 | 21.40 |
|    2 | 76.80 | 76.80 |
|    3 |  7.40 |  7.40 |
|    4 | 15.40 | 15.40 |
|    5 |  7.20 |  7.20 |
+------+-------+-------+

A.6. Assuntos Relacionados ao Otimizador

O MySQL usa um otimizador baseado no custo para descobrir o melhor modo de resolver uma consulta. Em muitos casos o MySQL pode calcular a melhor consulta possível mas em alguns casos o MySQL não tem informação suficiente sobre os dados e precisa fazer alguns palpites sobre os dados.

Esta seção do manual é direcionada para os casos nos quais o MySQL não faz isto corretamente.

A ferramenta que se tem disponível para ajudar o MySQL a fazer as coisas 'certas' são:

A.6.1. Camo evitar o varredura da tabela,,,

EXPLAIN mostrará ALL na coluna type quando o MySQL usa uma busca na tabela para resolver uma consulta. Isto acontece normalmente quando:

  • A tabela é tão pequena que é mais rápido fazer uma varredura na tabela que uma busca nas chaves. Isto é um caso comum para tabelas com menos de 10 linhas e um tamanho de linha pequeno.

  • Não há nenhum restrição utilizável na cláusula ON ou WHERE para colunas indexadas.

  • Você está comparando colunas indexadas com constantes e o MySQL calculou (baseado na árvore de índices) que a constante cobre uma parte muito grande da tabela e uma busca na tabela seria mais rápido.. See Secção 5.2.4, “Como o MySQL Otimiza Cláusulas WHERE.

  • Você está usando uma chave com baixa cardinalidade (= muitos registros coincidentes) através de outra coluna. O MySQL assumirá neste caso que usar a chave fará muitas pesquisas de chave e neste caso a varredura da tabela seria mais rápido.

O que você pode fazer para evita uma busca 'errada' em tabelas grandes é:

  • Use ANALYZE TABLE para a tabela em quastão atualizar a distribuição das chaves.. See Secção 4.6.2, “Sintaxe de ANALYZE TABLE.

  • Use FORCE INDEX para a tabela em questão para dizer ao MySQL que uma busca na tabela é muito cara comparado com usar um dos índices dados. See Secção 6.4.1, “Sintaxe SELECT.

    SELECT * FROM t1,t2 force index(index_for_column) WHERE t1.column=t2.column;
    
  • Inicie o mysqld com --max-seeks-for-key=1000 ou faça SET MAX_SEEKS_FOR_KEY=1000 para dizer ao otimizador que nenhuma busca de chave fará mais que 1000 pesquisas nas chaves.

A.7. Assuntos Relacionados a Definições de Tabelas

A.7.1. Problemas com ALTER TABLE.

ALTER TABLE altera uma tablea para o conjunto de caracteres atual. Se você obter um erro de chave duplicada durante ALTER TABLE, então a causa é que o novo conjunto de caracteres mapeia duas chaves para o mesmo valor ou que a tabela está corrompida, caso no qual você deve fazer um REPAIR TABLE na tabela.

Se ALTER TABLE finalizar com um erro com este:

Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)

o problema pode ser que o MySQL falhou em um ALTER TABLE anterior e existe uma tabela antiga chamada A-algumacoisa ou B-algumacoisa. Neste caso, vá até o diretório de dados do MySQL e delete todos os campos que tenham nomes iniciando com A- ou B-. (Você pode quere movê-los para algum lugar em vez de deletá-los.)

ALTER TABLE funciona do seguinte modo:

  • Cria uma nova tabela chamada A-xxx com as alterações pedidas.

  • Todos os registros da tabela antiga são copiadas para A-xxx.

  • A tabela antiga é renomeada com B-xxx.

  • A-xxx é renomeada com o nome da sua tabela antiga.

  • B-xxx é deletada.

Se algo der errado com a operação de renomeação, o MySQL tenta desfazer a mudança. Se algo der seriamente errado (isto não deve acontecer, é claro), o MySQL pode deixar a tabela antiga como B-xxx, mas uma simples renomeação no nível do sistema deve trazer o seus dados de volta.

A.7.2. Como Alterar a Ordem das Colunas em Uma Tabela

O ponto principal do MySQL é abstrair a aplicação do formato de armazenamento dos dados. Você sempre deve especificar a ordem na qual você deseja recuperar os dados. Por exemplo:

SELECT nome_coluna1, nome_coluna2, nome_coluna3 FROM nome_tabela;

retornará na ordem nome_coluna1, nome_coluna2, nome_coluna3, enquanto:

SELECT nome_coluna1, nome_coluna3, nome_coluna2 FROM nome_tabela;

retornará colunas na ordem nome_coluna1, nome_coluna3, nome_coluna2.

Se você quiser alterar a ordem das colunas, você pode fazer o seguinte:

  1. Crie uma nova abela com as colunas na ordem correta.

  2. Execute INSERT INTO tabela_nova SELECT campos-na-ordem-de-tabela_nova FROM tabela_antiga.

  3. Delete ou renomeie tabela_antiga.

  4. ALTER TABLE tabela_nova RENAME tabela_antiga.

Em uma aplicação, você nunca deve usar SELECT * e recuperar as colunas baseado em suas posições, pois a ordem e a posição nas quais as colunas são retornadas não permanecerá a mesma se você adicionar/mover/deletar colunas. Uma simples alteração na estrutura de seu banco de dados causaria uma falha em sua aplicação. É claro que SELECT * é muito mais cabível em testes de cosultas.

A.7.3. Problemas com TEMPORARY TABLE

Segue uma lista de limitações com TEMPORARY TABLES.

  • Uma tabela temporária só pode ser do tipo HEAP, ISAM, MyISAM, MERGE, ou InnoDB.

  • Você não pode usar tabelas temporárias mais que uma vez na mesma consulta. Por exemplo, o seguinte não funciona.

    mysql> SELECT * FROM tabela_temporária, tabela_temporária AS t2;
    
  • Você não pode usar RENAME em uma tabela temporária (TEMPORARY). Note que ALTER TABLE nome_orig RENAME nome_novo funciona!


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.