Problemas e Erros Comuns - MariaDB - Databases - Software - Computers

Problemas e Erros Comuns

Índice

Como Determinar o Que Está Causando Problemas
Erros Comuns Usando o MySQL
Erro: Access Denied
Erro: MySQL server has gone away
Erro: Can't connect to [local] MariaDB server
Erro: Client does not support authentication protocol
Erro: Host '...' is blocked
Erro: Too many connections
Erro: Some non-transactional changed tables couldn't be rolled back
Erro: Out of memory
Erro: Packet too large
Erros de Comunicação / Comunicação Abortada
Erro: The table is full
Erro: Can't create/write to file
Erro no Cliente: Commands out of sync
Erro: Ignoring user
Erro: Table 'xxx' doesn't exist
Erro: Can't initialize character set xxx
Arquivo Não Encontrado
Assuntos Relacionados a Instalação
Problemas de Ligação com a Biblioteca do Cliente MySQL
Como Executar o MariaDB Como Um Usuário Normal
Problemas com Permissões de Arquivos
Assuntos Relacionados a Administração
O Que Fazer Se o MariaDB Continua Falhando
Como Recuperar uma Senha de Root Esquecida
Como o MariaDB Trata de Discos Sem Espaço
Onde o MariaDB Armazena Arquivos Temporários
Como Proteger ou AlterarHow to Protect or Change the MariaDB Socket File /tmp/mysql.sock
Problemas Com Fuso Horário
Assuntos Relacionados a Consultas
Caso-Sensitivito em Pesquisas
Problemas Usando Colunas DATE
Problemas com Valores NULL
Problemas com alias
Deletando Linhas de Tabelas Relacionadas
Resolvendo Problemas Com Registros Não Encontrados
Problemas com Comparação de Ponto Flutuante
Assuntos Relacionados ao Otimizador
Camo evitar o varredura da tabela,,,
Assuntos Relacionados a Definições de Tabelas
Problemas com ALTER TABLE.
Como Alterar a Ordem das Colunas em Uma Tabela
Problemas com TEMPORARY TABLE

Este 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.

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 depois de você examinar todas as outras possibilidades e você tiver concluído que é o cliente MariaDB ou o servidor MariaDB 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 MariaDB que esta causando problemas. Lev em consideração todas as situações neste 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:

Quando enviar um relatório de erro, você deve seguir o que é descrito neste manual. Leia 'Fazendo perguntas ou relatando erros'.

Erros Comuns Usando o MariaDB

Erro: Access Denied
Erro: MySQL server has gone away
Erro: Can't connect to [local] MariaDB server
Erro: Client does not support authentication protocol
Erro: Host '...' is blocked
Erro: Too many connections
Erro: Some non-transactional changed tables couldn't be rolled back
Erro: Out of memory
Erro: Packet too large
Erros de Comunicação / Comunicação Abortada
Erro: The table is full
Erro: Can't create/write to file
Erro no Cliente: Commands out of sync
Erro: Ignoring user
Erro: Table 'xxx' doesn't exist
Erro: Can't initialize character set xxx
Arquivo Não Encontrado

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

Erro: Access Denied

See 'Causas dos Erros de Accesso Negado'. Leia 'Como o Sistema de Privilégios Funciona'.

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 MariaDB 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 MariaDB 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 MariaDB novamente. Leia Seção A.4.1, 'O Que Fazer Se o MariaDB 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 'Fazendo perguntas ou relatando erros'.

Erro: Can't connect to [local] MariaDB server

Um cliente MariaDB 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 MariaDB 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 MariaDB 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. Leia '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 MariaDB server pode ocorrer:

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

Erro: Client does not support authentication protocol

O MariaDB 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> MariaDB
Client does not support authentication protocol requested by server; consider upgrading MariaDB client

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

Para mais informações sobre hash de senha e autenticação, veja 'Hashing de Senhas no MariaDB 4.1'.

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!

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. Leia 'SHOW PROCESSLIST'.

O número máximo de conexões MariaDB 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.

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'. Leia 'SHOW TABLE STATUS'.

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

show variables like 'have_%'. Leia 'SHOW VARIABLES'.

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: MariaDB client ran out of memory

note que o erro se refere ao cliente MariaDB MariaDB. 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).

Erro: Packet too large

Quando um cliente MariaDB 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 MariaDB 3.23 o maior pacote possível é 16M (devido a limites do protocolo cliente/servidor). No MariaDB 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 MariaDB ou um única linha enviada para o cliente.

Quando um cliente MariaDB 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 MariaDB 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 MariaDB, 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 MariaDB 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.

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 '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:

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.

Erro: The table is full

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

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 MariaDB 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. Leia '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

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.

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:

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 MariaDB 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. Leia 'Sintaxe de SHOW'.

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:

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 MariaDB. 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. Leia 'SHOW VARIABLES'. O modo mais fácil de fazer isto é adicioar a opção ao seu arquivo de opção. Leia '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!

Assuntos Relacionados a Instalação

Problemas de Ligação com a Biblioteca do Cliente MySQL
Como Executar o MariaDB Como Um Usuário Normal
Problemas com Permissões de Arquivos

Problemas de Ligação com a Biblioteca do Cliente MariaDB

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 MariaDB e compilá-la você mesmo. Leia 'Instalando uma distribuição com fontes do MariaDB'.

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:

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

Como Executar o MariaDB 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 MariaDB 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 MariaDB 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 MariaDB root é o único com permissão para acessar o banco de dados MariaDB 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 MariaDB como usuário root do MariaDB 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 MariaDB como root, fornecendo -u root na linha de comando é diferente de de executar o MariaDB como o usuário root do Unix,or como outro Usuário Unix. A permissão de acesso e nome de usuários do MariaDB 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 MariaDB

Se a sua conta Unix não esta segura, você deve pelo menos colocar uma senha no usuário root do MariaDB 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.

Problemas com Permissões de Arquivos

Se você tiver problemas com permissões de arquivo, por exemplo, se o MariaDB 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 MariaDB 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 MariaDB Versão 3.23.25 e acima, o MariaDB 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 MariaDB.

Assuntos Relacionados a Administração

O Que Fazer Se o MariaDB Continua Falhando
Como Recuperar uma Senha de Root Esquecida
Como o MariaDB Trata de Discos Sem Espaço
Onde o MariaDB Armazena Arquivos Temporários
Como Proteger ou AlterarHow to Protect or Change the MariaDB Socket File /tmp/mysql.sock
Problemas Com Fuso Horário

O Que Fazer Se o MariaDB Continua Falhando

Todas as versões do MariaDB 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. Leia '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. Leia Seçã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 MariaDB são causadas por arquivos de índices/dados corrompidos. O MariaDB 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 MariaDB 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:

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. Leia Administração do Bancos de Dados MySQL.

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 'Como Tornar o MariaDB 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 MariaDB:

    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 MariaDB:

  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 MariaDB:

    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.

Como o MariaDB Trata de Discos Sem Espaço

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

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

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 MariaDB 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).

Onde o MariaDB Armazena Arquivos Temporários

O MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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.

Como Proteger ou AlterarHow to Protect or Change the MariaDB 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 MariaDB, 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 MariaDB usa/coloca o arquivo de socket da seguinte maneira:

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

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

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. Leia Apêndice F, Variáveis de Ambientes do MariaDB.

Assuntos Relacionados a Consultas

Caso-Sensitivito em Pesquisas
Problemas Usando Colunas DATE
Problemas com Valores NULL
Problemas com alias
Deletando Linhas de Tabelas Relacionadas
Resolvendo Problemas Com Registros Não Encontrados
Problemas com Comparação de Ponto Flutuante

Caso-Sensitivito em Pesquisas

Por padrão, as pesquisas no MariaDB 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 MariaDB, 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. Leia '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.

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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 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.

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 MariaDB 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. Leia '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 MariaDB 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.

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.

Deletando Linhas de Tabelas Relacionadas

Como o MariaDB 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.

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. Leia '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. Leia Seçã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 MariaDB. Leia 'As Listas de Discussão do MariaDB'.

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 |
+------+-------+-------+

Assuntos Relacionados ao Otimizador

Camo evitar o varredura da tabela,,,

O MariaDB usa um otimizador baseado no custo para descobrir o melhor modo de resolver uma consulta. Em muitos casos o MariaDB pode calcular a melhor consulta possível mas em alguns casos o MariaDB 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 MariaDB não faz isto corretamente.

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

Camo evitar o varredura da tabela,,,

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

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

Assuntos Relacionados a Definições de Tabelas

Problemas com ALTER TABLE.
Como Alterar a Ordem das Colunas em Uma Tabela
Problemas com TEMPORARY TABLE

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 MariaDB 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 MariaDB 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:

Se algo der errado com a operação de renomeação, o MariaDB tenta desfazer a mudança. Se algo der seriamente errado (isto não deve acontecer, é claro), o MariaDB 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.

Como Alterar a Ordem das Colunas em Uma Tabela

O ponto principal do MariaDB é 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.

Problemas com TEMPORARY TABLE

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



Anterior Próximo
Estendendo o MySQL Início Contribuição de Programas