Índice
Access Denied
MySQL server has gone away
Can't connect to [local] MySQL server
Client does not support authentication protocol
Host '...' is blocked
Too many connections
Some non-transactional changed tables couldn't be rolled back
Out of memory
Packet too large
The table is full
Can't create/write to file
Commands out of sync
Ignoring user
Table 'xxx' doesn't exist
Can't initialize character set xxx
/tmp/mysql.sock
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.
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”.
Access Denied
MySQL server has gone away
Can't connect to [local] MySQL server
Client does not support authentication protocol
Host '...' is blocked
Too many connections
Some non-transactional changed tables couldn't be rolled back
Out of memory
Packet too large
The table is full
Can't create/write to file
Commands out of sync
Ignoring user
Table 'xxx' doesn't exist
Can't initialize character set xxx
Esta seção lista alguns erros que os usuários obtém frequqntemente. Você encontrará descrições de erros e como resolvê-los aqui.
See Secção 4.3.12, “Causas dos Erros de Accesso Negado
”. See
Secção 4.3.6, “Como o Sistema de Privilégios Funciona”.
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 erro | Descrição |
CR_SERVER_GONE_ERROR | O cliente não pode enviar um pedido ao servidor. |
CR_SERVER_LOST | O 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:
Informe se o MySQL morreu ou não. (Você pode encontrar
into no arquivo hostname.err
). See
Secção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”.
Se uma cosulta específica matar o mysqld
e as tabelas envolvidas foram verificadas com CHECK
TABLE
antes que você fizesse a consulta, você
pode fazer um caso de teste para isto? See
Secção E.1.6, “Fazendo um Caso de Teste Se Ocorre um Corrompimento de Tabela”.
Qual é o valor da variável wait_timeout
no servidor MySQL? mysqladmin variables
lhe dá o valor destas variáveis.
Você tentou executar mysqld
com
--log
e verificou se a consulta executada
apareceu no log?
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
.
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:
Inicie o mysqld com --old-passwords
.
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”.
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
!
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.
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
”.
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).
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 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:
O programa cliente não chamou
mysql_close()
antes de sair.
O cliente tem esperado mais que
wait_timeout
ou
interactive_timeout
sem fazer nenhuma
requisição. See Secção 4.6.8.4, “SHOW VARIABLES
”. See
Secção 4.6.8.4, “SHOW VARIABLES
”.
O programa cliente finalizou abuptamente no meio de uma transferência.
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
”.
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.
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
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.
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';
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
”.
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.
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
!
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!
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:
Pare o servidor se ele estiver em execução (use
mysqladmin shutdown
).
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ê.
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.
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.
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.
/tmp/mysql.sock
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:
Inicie o mysqld
a partir do
gdb
(ou em outro depurador). See
Secção E.1.3, “Depurando o mysqld no gdb”.
Execute o seu script de testes.
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.
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:
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.
Reinicie o mysqld
com a opção
--skip-grant-tables
.
Defina uma nova senha com o comando mysqladmin
password
:
shell> mysqladmin -u root password 'mynewpassword'
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
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
:
Finalize e reinicie o mysqld
com a
opção --skip-grant-tables
com descrito
acima.
Conecte ao servidor mysqld
com:
shell> mysql -u root mysql
Dispare os seguintes comandos no cliente
mysql
:
mysql>UPDATE user SET Password=PASSWORD('minhanovasenha')
->WHERE User='root';
mysql>FLUSH PRIVILEGES;
Depois disto, você deve estar apto a conectar usando a nova senha.
Você agora pode parar o mysqld
e
reiniciá-lo normalmente.
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).
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.
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
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
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.
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.
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.
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.
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.
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:
SELECT
as linhas baseado em alguma
condição WHERE
na tabela principal.
DELETE
as linhas da tabela princiapl
basada nas mesmas condições.
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
.
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:
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
)”.
Selcione apenas aqueles campos que são usados na cláusula
WHERE
.
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.
Faça um SELECT
da coluna encontrou um
registro com a tabela que foi removido por última da
consulta.
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”.
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”.
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 | +------+-------+-------+
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:
EXPLAIN
. See Secção 5.2.1, “Sintaxe de EXPLAIN
(Obter informações sobre uma SELECT
)”.
ANALYZE TABLE
. See
Secção 4.6.2, “Sintaxe de ANALYZE TABLE
”.
USE INDEX
, FORCE INDEX
and IGNORE INDEX
. See
Secção 6.4.1, “Sintaxe SELECT
”.
STRAIGHT JOIN
a nível de tabela e global.
See Secção 6.4.1, “Sintaxe SELECT
”.
Configurar variáveis específicas de threads. See
Secção 4.6.8.4, “SHOW VARIABLES
”.
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.
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.
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:
Crie uma nova abela com as colunas na ordem correta.
Execute INSERT INTO tabela_nova SELECT
campos-na-ordem-de-tabela_nova FROM tabela_antiga
.
Delete ou renomeie tabela_antiga
.
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.
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.