XOOPS Brasil

 

Capítulo 4. Administração do Bancos de Dados MySQL

Índice

4.1. Configurando o MySQL
4.1.1. Opções de Linha de Comando do mysqld
4.1.2. Arquivo de Opções my.cnf
4.2. Executando Múltiplos MySQL Servers na Mesma Máquina
4.2.1. Executando Múltiplos Servidores no Windows
4.2.2. Executando Múltiplos Servidores no Unix
4.2.3. Usando Programas Clientes em um Ambiente Multi-Servidor
4.3. Detalhes Gerais de Segurança e o Sistema de Privilégio de Acesso do MySQL
4.3.1. Segurança Geral
4.3.2. Como Tornar o MySQL Seguro contra Crackers
4.3.3. Opções de Inicialização para o mysqld em Relação a Segurança.
4.3.4. Detalhes de Segurança com LOAD DATA LOCAL
4.3.5. O Que o Sistema de Privilégios Faz
4.3.6. Como o Sistema de Privilégios Funciona
4.3.7. Privilégios Fornecidos pelo MySQL
4.3.8. Conectando ao Servidor MySQL
4.3.9. Controle de Acesso, Estágio 1: Verificação da Conexão
4.3.10. Controle de Acesso, Estágio 2: Verificação da Requisição
4.3.11. Hashing de Senhas no MySQL 4.1
4.3.12. Causas dos Erros de Accesso Negado
4.4. Gerenciamento das Contas dos Usuários no MySQL
4.4.1. A Sintaxe de GRANT e REVOKE
4.4.2. Nomes de Usuários e Senhas do MySQL
4.4.3. Quando as Alterações nos Privilégios tem Efeito
4.4.4. Configurando os Privilégios Iniciais do MySQL
4.4.5. Adicionando Novos Usuários ao MySQL
4.4.6. Deletando Usuários do MySQL
4.4.7. Limitando os Recursos dos Usuários
4.4.8. Configurando Senhas
4.4.9. Mantendo Sua Senha Segura
4.4.10. Usando Conexões Seguras
4.5. Prevenção de Disastres e Recuperação
4.5.1. Backups dos Bancos de Dados
4.5.2. Sintaxe de BACKUP TABLE
4.5.3. Sintaxe de RESTORE TABLE
4.5.4. Sintaxe de CHECK TABLE
4.5.5. Sintaxe do REPAIR TABLE
4.5.6. Utilizando myisamchk para Manutenção de Tabelas e Recuperação em Caso de Falhas
4.5.7. Configurando um Regime de Manutenção das Tabelas
4.5.8. Obtendo Informações sobre as Tabelas
4.6. Adiministração do Banco de Dados e Referência de Linguagem
4.6.1. Sintaxe de OPTIMIZE TABLE
4.6.2. Sintaxe de ANALYZE TABLE
4.6.3. Sintaxe de CHECKSUM TABLE
4.6.4. Sintaxe de FLUSH
4.6.5. Sintaxe de RESET
4.6.6. Sintaxe de PURGE MASTER LOGS
4.6.7. Sintaxe de KILL
4.6.8. Sintaxe de SHOW
4.7. Localização do MySQL e Utilização Internacional
4.7.1. O Conjunto de Caracteres Utilizado para Dados e Ordenação
4.7.2. Mensagens de Erros em Outras Línguas
4.7.3. Adicionando um Novo Conjunto de Caracteres
4.7.4. Os Vetores de Definições de Caracteres
4.7.5. Suporte à Ordenação de Strings
4.7.6. Suporte à Caracteres Multi-byte
4.7.7. Problemas com Conjuntos de Caracteres
4.8. Utilitários e Scripts do Lado do Servidor MySQL
4.8.1. Visão Geral dos Scripts e Utilitários do Lado Servidor
4.8.2. mysqld-safe, o wrapper do mysqld
4.8.3. mysqld_multi, programa para gerenciar múltiplos servidores MySQL
4.8.4. myisampack, O Gerador de Tabelas Compactadas de Somente Leitura do MySQL
4.8.5. mysqld-max, om servidor mysqld extendido
4.9. Utilitários e Scripts do Lado do Cliente MySQL
4.9.1. Visão Geral dos Utilitários e Scripts do Lado do Cliente
4.9.2. mysql, A Ferramenta de Linha de Comando
4.9.3. mysqlcc, The MySQL Control Center
4.9.4. mysqladmin, Administrando um Servidor MySQL
4.9.5. mysqlbinlog, Executando as Consultas a Partir de um Log Binário
4.9.6. Usando mysqlcheck para Manutenção de Tabelas e Recuperação em Caso de Falhas
4.9.7. mysqldump, Descarregando a Estrutura de Tabelas e Dados
4.9.8. mysqlhotcopy, Copiando Bancos de Dados e Tabelas do MySQL
4.9.9. mysqlimport, Importando Dados de Arquivos Texto
4.9.10. mysqlshow, Exibindo Bancos de Dados, Tabelas e Colunas
4.9.11. mysql_config, Opções para compilação do cliente MySQL
4.9.12. perror, Explicando Códigos de Erros
4.9.13. Como Executar Comandos SQL a Partir de um Arquivo Texto
4.10. Os Arquivos de Log do MySQL
4.10.1. O Log de Erros
4.10.2. O Log de Consultas
4.10.3. O Log de Atualizações
4.10.4. O Log Binário
4.10.5. O Log para Consultas Lentas
4.10.6. Manutenção do Log de Arquivo
4.11. Replicação no MySQL
4.11.1. Introdução
4.11.2. Visão Geral da Implementação da Replicação
4.11.3. Detalhes de Implementação da Replicação
4.11.4. Como Configurar a Replicação
4.11.5. Recursos de Replicação e Problemas Conhecidos
4.11.6. Opções de Inicialização da Replicação
4.11.7. Instruções SQL para Controle do Servidor Master
4.11.8. Instruções SQL para Controle do Servidor Slave
4.11.9. FAQ da Replicação
4.11.10. Problemas com Replicação
4.11.11. Relatando Problemas de Replicação

4.1. Configurando o MySQL

4.1.1. Opções de Linha de Comando do mysqld

Na maioria dos casos você deve gerenciar as opções do mysqld por meio dos arquivos de opções. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

mysqld e mysqld.server lêem opções dos grupos mysqld e server. mysqld_safe lê as opções dos grupos mysqld, server, mysqld_safe e mysqld_safe. Um servidor MySQL embutido normalmente lê opções do grupos server, embedded e xxxxx_SERVER, onde xxxxx é o nome da aplicação.

mysqld aceita os seguintes opções de linha de comando. Aqui está uma lista das mais comuns. Para uma lista completa execute mysqld --help. As opções usadas para replicação estào listadas em uma seção separada, veja Seção 4.11.6, “Opções de Inicialização da Replicação”.

  • --ansi

    Utilizar a sintaxe ANSI SQL no lugar da sintaxe MySQL See Seção 1.8.2, “Executando o MySQL no modo ANSI”.

  • -b, --basedir=path

    Encaminho para o diretório de instalação. Todos os caminhos normalmente são resolvidos em relação a este.

  • --big-tables

    Permite grandes conjuntos de resultados salvando todos os conjuntos temporários em um arquivo. Ele resolve a maioria dos erros 'table full', mas também abaixa a velocidade das consultas nas quais as tabelas em memória seriam suficientes. Desde a Versão 3.23.2, o MySQL é capaz de resolver isto automaticamente usando memória para pequenas tabelas temporárias e trocando para o disco as tabelas, quando for necessário.

  • --bind-address=IP

    Endereço IP para ligar.

  • --console

    Grava a mensagem de erro no stderr/stdout mesmo se --log-error é espeficado. No Windows o mysqld não fechará a tela de console se esta opção é usada.

  • --character-sets-dir=path

    Diretório onde estão os conjuntos de caracteres. See Seção 4.7.1, “O Conjunto de Caracteres Utilizado para Dados e Ordenação”.

  • --chroot=path

    Coloca o daemon mysqld no diretorio chroot durante a inicialização. Medida de segurança recomendada desde o MySQL 4.0 (MySQL 3.23 não está apto a fornecer um chroot 100% fechado. Limita os comandos LOAD DATA INFILE e SELECT ... INTO OUTFILE.

  • --core-file

    Grava um arquivo core se o mysqld morrer. Para alguns sistemas você deve também especificar --core-file-size para mysqld_safe. See Seção 4.8.2, “mysqld-safe, o wrapper do mysqld. Note que em alguns sistemas, como Solaris, você não consiguirá um arquivo core se você também estiver usando a opção --user.

  • -h, --datadir=caminho

    Encaminha para o diretório raiz dos bancos de dados.

  • --debug[...]=

    Se o MySQL está configurado com --with-debug, você pode usar esta opção para obter um arquivo de rastreamento indicando o que o mysqld está fazendo. See Seção E.1.2, “Criando Arquivos Trace (Rastreamento)”.

  • --default-character-set=conjunto_caracter

    Configura o conjunto de caracteres padrão. See Seção 4.7.1, “O Conjunto de Caracteres Utilizado para Dados e Ordenação”.

  • --default-table-type=tipo

    Configura o tipo de tabela padrão. See Capítulo 7, Tipos de Tabela do MySQL.

  • --delay-key-write[= OFF | ON | ALL]

    Como o DELAYED KEYS do MyISAM deve ser usado. Veja mais informações sobre isto na Seção 5.5.2, “Parâmetros de Sintonia do Servidor”.

  • --delay-key-write-for-all-tables; No MySQL 4.0.3 você deve usar --delay-key-write=ALL.

    Não descarrega buffers das chaves entre escritas em nenhuma tabela MyISAM. See Seção 5.5.2, “Parâmetros de Sintonia do Servidor”.

  • --des-key-file=filename

    Read the default keys used by DES_ENCRYPT() and DES_DECRYPT() from this file.

  • --enable-external-locking (era --enable-locking)

    Habilita o bloqueio do sistema. Perceba que se usar esta opção em um sistema que não possui um lockd() completamente funcional (como no Linux) você pode fazer com que o mysqld entre em deadlock.

  • --enable-named-pipe

    Habilita suporte para named pipes (somente no NT/Win2000/XP).

  • -T, --exit-info

    Esta é uma máscara binária com diferêntes parâmetros que pode ser usada para depurar o servidor mysqld; Esta opção não deve ser usada por alguém que não a conheça muito bem!

  • --flush

    Atualiza todas as alterações no disco depois de cada comando SQL. Normalmente o MySQL só faz a escrita de todas as alterações no disco depois de cada comando SQL e deixa o sistema operacional lidar com a sincronização com o disco. Veja mais informações sobre isto na Seção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”.

  • -?, --help

    Mostra uma pequena ajuda e sai.

  • --init-file=arquivo

    Lê comandos SQL do arquivo especificado na inicialização.

  • -L, --language=...

    Mensagens de erro do cliente na língua especificada. Pode ser fornecido como um caminho completo. See Seção 4.7.2, “Mensagens de Erros em Outras Línguas”.

  • -l, --log[=arquivo]

    Log de conexões e consultas ao arquivo. See Seção 4.10.2, “O Log de Consultas”.

  • --log-bin=[arquivo]

    Registra todas as consultas que alteram dados em arquivo. Usado para backup e replicação. See Seção 4.10.4, “O Log Binário”.

  • --log-bin-index[=arquivo]

    Arquivo de índice para nomes de arquivos de log binario. Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”.

  • --log-error[=arquivo]

    Registra mensagens de erro e inicialização neste arquivo. Veja mais informações sobre isto na Seção 4.10.1, “O Log de Erros”.

  • --log-isam[=arquivo]

    Log de todas alterações ISAM/MyISAM no arquivo (usado somente quando estiver depurando bancos ISAM/MyISAM).

  • --log-long-format

    Registra algumas informações extras nos aruivos de log (log de atualizações, log binário de atualizações e log de consultas lentas, independente de qual está ativado). Por exemplo, nome do usuário e timestamp são registrados para a consulta. Se você estiver usando --log-slow-queries e --log-long-format, então consultas que não estão usando índices são registradas ao log de consultas lentas. Note que --log-long-format está obsoleto a partir do MySQL versão 4.1, quando --log-short-format foi introduzido (--log-long-format é a configuração padrão desde a versão 4.1). Note também que a partir do MySQL 4.1, a opção --log-queries-not-using-indexes está disponível para propósito de registro de consultas que não usam índices para o log de consultas lentas.

  • --log-queries-not-using-indexes

    Se você estiver usando --log-slow-queries, então consultas que não estão usando índices estão registradas no log de consultas lentas. Esta opções está disponível a partir do MySQL 4.1. See Seção 4.10.5, “O Log para Consultas Lentas”.

  • --log-short-format

    Registra menos informações extras nos aruivos de log (log de atualizações, log binário de atualizações e log de consultas lentas, independente de qual está ativado). Por exemplo, nome do usuário e timestamp são registrados para a consulta. Esta opção foi introduzida no MySQL 4.1.

  • --log-slow-queries[=arquivo]

    Log de todas as consultas que levam mais de long_query_time segundos de execução para um arquivo. Note que o padrão para a quantidade de informação registrada alterou no MySQL 4.1. Veja as opções --log-long-format e --log-long-format para mais detalhes. See Seção 4.10.5, “O Log para Consultas Lentas”.

  • --log-update[=arquivo]

    Log de atualizações para file.# onde # é um número único se não for fornecido. Veja mais informações sobre isto na Seção 4.10.3, “O Log de Atualizações”. O log de atualização estáobsoleto e será removido no MySQL 5.0; você deve usar o log binário em seu lugar (--log-bin). See Seção 4.10.4, “O Log Binário”. A partir da versão 5.0, usar --log-update apenar ligará o log binário.

  • --low-priority-updates

    Operações de alterações das tabelas (INSERT/DELETE/UPDATE) irão ter prioridade menor do que as selects. Isto também pode ser feito usando {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... para baixar a prioridade de somente uma consulta, ou SET OPTION SQL_LOW_PRIORITY_UPDATES=1 para alterar a prioridade em uma única thread. See Seção 5.3.2, “Detalhes sobre Lock de Tabelas”.

  • --memlock

    Bloqueia o processo mysqld na memória. Isto funciona somente se o seu sistema suportar a chamada de sistema mklockall() (como no Solaris). Isto pode ajudar se você tiver um problema no qual o sistema operacional faz com que o mysqld faça a troca em disco. Note que o uso desta opção exige que você execute o servidor como root, que normalmente não é uma boa idéia por razões de segurança.

  • --myisam-recover [=opção[,opção...]]] onde opção é qualquer combinação

    de DEFAULT, BACKUP, FORCE ou QUICK. Você também pode configurar isto explicitamente para "" se você deseja desabilitar esta opção. Se esta opção for usada, o mysqld irá conferir na abertura se a tabela está marcada como quebrada ou se a tabela não foi fechada corretamente. (A última opção funciona somente se você estiver executando com --skip-locking). Se este for o caso mysqld irá executar uma conferência na tabela. Se a tabela estiver corrompida, o mysqld irá tentar repará-la.

    As seguintes opções afetam no funcionamento da reparação.

    OpçãoDescrição
    DEFAULTO mesmo que não fornecer uma opção para --myisam-recover.
    BACKUPSe os dados da tabela foram alterados durante a recuperação, salve um backup do arquivo de dados nome_tabela.MYD como nome_tabela_dia_hora.BAK.
    FORCEExecute a recuperação mesmo se perdermos mais de uma linha do arquivo .MYD.
    QUICKNão confira as linhas na tabela se não existir nenhum bloco apagado.

    Antes da tabela ser reparada automaticamente, o MySQL irá adicionar uma nota no log de erros. Se você desejar que a recuperação da maioria dos problemas não tenha a intervenção de algum usuário, devem ser usadas as opções BACKUP,FORCE. Isto irá forçar um reparo de uma tabela mesmo se alguns registros forem apagados, mas ele manterá o arquivo de dados antigo como um backup para que você possa examinar posteriormente o que aconteceu.

  • --new

    A partir da versão 4.0.12, a opção --new pode ser usada para fazer o servidor se comportar como 4.1 em certos aspectos, facilitando a atualização da versão 4.0 para 4.1:

  • --pid-file=caminho

    Encaminha para o arquivo pid usado pelo mysqld_safe.

  • -P, --port=...

    Número da porta para conexões TCP/IP.

  • -o, --old-protocol

    Utilize o protocolo 3.20 para compatibilidade com alguns clientes muito antigos. See Seção 2.5.5, “Atualizando da versão 3.20 para 3.21”.

  • --one-thread

    Usa somente uma thread (para depuração sobre Linux). Esta opção está disponível apenas se o servidor está construído com a depuração habilitada. See Seção E.1, “Depurando um Servidor MySQL”.

  • --open-files-limit=

    Para alterar o número de descritores de arquivos disponíveis para o mysqld. Se isto não estiver configurado com 0, então o mysqld usará este valor para reservar descritores de arquivos para usar com setrlimit(). Se este valor é 0 então o mysqld reservará max_connections*5 ou max_connections + table_cache*2 (que é sempre é maior) número de arquivos. Você deve tentar aumentar isto se o mysqld lhe retornar o erro 'Too many open files'.

  • -O, --set-variable=name=value

    Fornece um valor para uma variável. --help lista as variáveis. Você pode encontrar uma descrição completa para todas as variáveis na seção SHOW VARIABLES deste manual. See Seção 4.6.8.4, “SHOW VARIABLES. A seção de sintonia dos parâmetros do servidor inclui informações sobre como otimizá-los. Por favor, note que --set-variable=name=value e -O name=value estão obsoletos desde o MySQL 4.0, apenas use --var=opção. See Seção 5.5.2, “Parâmetros de Sintonia do Servidor”.

    No MySQL 4.0.2 pode-se definir uma variável diretamente com --variable-name=opção e set-variable não é mais preciso no arquivo de opções.

    Se você quiser restringir o valor máximo uma opção de inicialização pode ser definida com SET, você pode definí-la usando a opção de linha de comando --maximum-variable-name. See Seção 5.5.6, “Sintaxe de SET.

    Note que quando um valor é atribuído a uma variável, o MySQL pode carrigí-lo automaticamente para permanecer dentro de uma faixa dada e também ajusta o valor um pouco para corrigir para o algoritmo usado.

  • --safe-mode

    Salta alguns estágios de otimização.

  • --safe-show-database

    Com esta opção, o comando SHOW DATABASES retorna apenas aqueles bancos de dados para os quais o usuário tem algum tipo de privilégio. Desde a versão 4.0.2 esta opção esta obsoleta e não faz nada (a opção está habilitada por padrão) já que agora temos o privilégio SHOW DATABASES. See Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

  • --safe-user-create

    Se isto estiver ativo, um usuário não pode criar novos usuários com o comando GRANT, se o usuário não ter o privilégio de INSERT na tabela mysql.user ou em alguma coluna desta tabela.

  • --skip-bdb

    Disabilita o uso de tabelas BDB. Isto economizará memória e pode aumentar a velocidade de algumas operações.

  • --skip-concurrent-insert

    Desliga a habilidade de selecionar e inserir ao mesmo tempo em tabelas MyISAM. (Isto só é usado se você achar que encontrou um erro neste recurso).

  • --skip-delay-key-write;

    No MySQL 4.0.3 você deve usar --delay-key-write=OFF. Ignore a opção DELAY_KEY_WRITE para todas as tabelas. Veja mais informações sobre isto na Seção 5.5.2, “Parâmetros de Sintonia do Servidor”.

  • --skip-grant-tables

    Esta opção faz com que o servidor não use o sistema de privilégio. Isto dá a todos acesso pleno a todos os bancos de dados! (Você pode dizer a um servidor em execução para iniciar a usar as tabelas de permissão novamente executando mysqladmin flush-privileges ou mysqladmin reload.)

  • --skip-host-cache

    Nunca utiliza cache para nomes de máquina para resoluções de nomes mais rápidos, mas pesquisa o servidor DNS em todas conexões. Veja mais informações sobre isto na Seção 5.5.5, “Como o MySQL Utiliza o DNS”.

  • --skip-innodb

    Disabilita o uso de tabelas Innodb. Isto irá economizar memória, espaço em disco e aumentar a velocidade de algumas operações.

  • --skip-external-locking (era --skip-locking)

    Não utilizar bloqueio de sistema. Para usar isamchk ou myisamchk você deve desligar o servidor. See Seção 1.2.3, “Estabilidade do MySQL”. Perceba que na Versão 3.23 do MySQL pode ser usado REPAIR e CHECK para reparar/conferir tabelas MyISAM.

  • --skip-name-resolve

    Nomes de máquinas não são resolvidos. Todos os valores da coluna Host nas tabelas de permissões devem conter números IP ou localhost. Veja mais informações sobre isto na Seção 5.5.5, “Como o MySQL Utiliza o DNS”.

  • --skip-networking

    Não escutair conexões TCP/IP. Toda interação com mysqld deve ser feito através de named pipes ou sockets Unix. Esta opção é altamente recomendada para sistemas onde requisições locais são permitidas. See Seção 5.5.5, “Como o MySQL Utiliza o DNS”.

  • --skip-new

    Não utilizar rotinas novas, possívelmente erradas.

  • --skip-symlink

    Opção obsoleta a partir da 4.0.13; use --skip-symbolic-links em seu lugar.

  • --symbolic-links, --skip-symbolic-links

    Habilita ou desabilita suporte a link simbólico. Esta opção tem efeitos diferentes no Windows e Unix.

    No Windows, habilitar links simbílicos lhe permite estabelecer um link simbólico a um diretório de banco de dadosi criando um arquivo directory.sym que contém o caminho para o diretório real. See Seção 5.6.1.3, “Usando Links Simbólicos para Bancos de Dados no Windows”.

    No Unix, habilitar links simbólicos, significa que você pode ligar uma tabela MyISAM ou um arquivo de dados em outro dirtório com as opções INDEX DIRECTORY ou DATA DIRECTORY da instrução CREATE TABLE. Se você deletar ou renomear a tabela, os arquivos para o qual o link simbólico aponta também será deletado/renomeado.

  • --skip-safemalloc

    Se o MySQL é configurado com --with-debug=full, todos os programas verificam a memória por erros para cada operação de alocação e liberação de memória. Esta consistência é muito lenta, assim para o servidor você pode evitá-la, quando você não precisar dela usando a opção --skip-safemalloc.

  • --skip-show-database

    Não permite o comando 'SHOW DATABASE', a menos que o usuário tenha privilégio SHOW DATABASES.

  • --skip-stack-trace

    Não gravar os rastreamentos de pilha. Esta opção é útil quando você estiver executando o mysqld sob um depurador. El alguns sistemas você também deve usar esta opção para conseguir um arquivo core. See Seção E.1, “Depurando um Servidor MySQL”.

  • --skip-thread-priority

    Desabilita o uso de prioridade das threads para um tempo de resposta mais rápido.

  • --socket=path

    No Unix, o arquivo socket para usar em conexões locais no lugar do padrão /tmp/mysql.sock. No Windows, o nome do pipe para usar em conexões locais que usam named pipe (padrão MySQL).

  • --sql-mode=value[,value[,value...]]

    Os valores de opção pode ser qualquer combinação de: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION, NO_AUTO_VALUE_ON_ZERO, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_KEY_OPTIONS, NO_DIR_IN_CREATE, MYSQL323, MYSQL40, DB2, MAXDB, MSSQL, ORACLE, POSTGRESQL, ou ANSI. O valor também pode ficar vazio (--sql-mode="") se você desejar limpá-la.

    NO_AUTO_VALUE_ON_ZERO afeta o tratamento de colunas AUTO_INCREMENT. Normalmente, você gera a próxima sequência de números da coluna inserindo NULL ou 0 nela. NO_AUTO_VALUE_ON_ZERO omite este comportamento para 0, assim apenas NULL gera a próxima sequência de números. Este modo pode ser útil se 0 foi armazenado em uma coluna AUTO_INCREMENT da tabela (isto não é recomendado). Por exemplo, se você fizer um dumpo de uma tabela com mysqldump e então recarregá-la, normalmente o MySQL ira gerar uma nova sequência de números quando encontrar valores 0, resultando em uma tabela com conteúdo diferente daquele do qual foi feito o dump. Habilitando NO_AUTO_VALUE_ON_ZERO antes de recarregar o arquivo de dump soluciona este problema. (A partir do MySQL 4.1.1, quando este valor se tornar disponível, o mysqldump inclui automaticamente a saída do dump para habilitar NO_AUTO_VALUE_ON_ZERO.)

    Diversos dos valores de opção são usados para compatibilidade com outros servidores. Se especificado, eles fazer o servidor omitir da saída de SHOW CREATE TABLE aquelas partes da instrução que não são entendidas pelas versões anteriores do MySQL ou outros servidores de banco de dados. Usar estes valores de opções resulta em instruções CREATE TABLE que são mais portáveis para usar com outros servidores:

    • Os valores NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_DIR_IN_CREATE, e NO_KEY_OPTIONS causam a omissão da tabela de opções, ou opções pertencentes a definição de colunas ou índices.

    • Os valroes MYSQL323 e MYSQL40 são para compatibilidade com o MySQL 3.23 e MySQL 4.0.

    • O valor usado para compatibilidade com outros servidores são DB2, MAXDB, MSSQL, ORACLE, e POSTGRESQL.

    Estas opções também afetam a saída do mysqldump, porque este programa usa SHOW CREATE TABLE para obter a instrução de criação da tabela a qual ele inclue em sua própria saída.

    Diversos valores de opções podem ter um efeito complexo porque eles são atalhos para um grupo ou conjunto de valores. Por exemplo, você pode dizer ao servidor para executar em modo ANSI usando a opção --sql-mode=ansi (ou --ansi), que é equivalente a especificar ambas das seguintes opções de linhas de comando:

    --sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY
    --transaction-isolation=SERIALIZABLE
    

    Note que especificar o modo ANSI desta forma também tem o efeito de configurar o nível de isolação da transação.

    Para mais informações sobre executar o servidor em modo ANSI, veja Seção 1.8.2, “Executando o MySQL no modo ANSI”.

    Outros valores de ``grupos'' são DB2, MAXDB, MSSQL, ORACLE, e POSTGRESQL. Esepcificar qualquer um dele ativa os valores PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, e NO_KEY_OPTIONS.

    A opção --sql-mode foi adicionada no MySQL 3.23.41. O valor NO_UNSIGNED_SUBTRACTION foi adicionado na versão 4.0.0. NO_DIR_IN_CREATE foi adicionado na versão 4.0.15. NO_AUTO_VALUE_ON_ZERO, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_KEY_OPTIONS, MYSQL323, MYSQL40, DB2, MAXDB, MSSQL, ORACLE, POSTGRESQL, e ANSI foram adicionados na versão 4.1.1.

  • --temp-pool

    Usar esta opção fará com que a maioria dos arquivos temporários criados pelo servidor para usarem um pequeno conjunto de nomes, em vez de um único nome para cada novo arquivo. Isto é para contornar um problema no kernel do Linux ao tratar com a criação de muitos arquivos novos com nomes diferentes. Com o comportamento antigo, o Linux parece ter ``perda'' de memória, já que ela é alocada na cache de entrada do diretório em vez da cache de disco.

  • --transaction-isolation={ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE }

    Configura o nível de isolação da transação padrão. See Seção 6.7.6, “Sintaxe SET TRANSACTION.

  • -t, --tmpdir=path

    Caminho do diretório usado para criar os arquivos temporários. Ele pode ser útil se o seu diretório padrão /tmp está em uma partição muito pequena para armazenar tabelas temporárias. A partir do MySQL 4.1, esta opção aceita diversos caminhos usados do modo round-robin. Os caminhos devem ser separados por dois pontos (:) (ponto e vírgula (;) no Windows). Eles serão usados de acordo com o método round-robin.

  • -u, --user=[nome_usuário | id_usuário]

    Executar o servidor mysqld como o usuário nome_usuário ou id_usário (numérica). (``User'' neste contexto se refere a conta de login do sistema, não um usuário MySQL listado na tabela de permissões.)

    Esta opção é obrigatória quando o mysqld é iniciado como usuário root. O servidor irá alterar o ID do usuário durante sua inicialização, fazendo com que ele seja executado como este usuário particular em vez de root. Veja mais informações sobre isto na Seção 4.3.2, “Como Tornar o MySQL Seguro contra Crackers”.

    A partir do MySQL 3.23.56 e 4.0.12: Para evitar um possível furo na segurança onde um usuário adiciona uma opção --user=root a algum arquivo my.cnf (fazendo o servidor executar como root, o mysqld usa apenas a primeira opção --user especificada e produz um aviso se houver múltiplas opções --user.

    As opções em /etc/my.cnf e datadir/my.cnf são processadas antes de uma opção de linha de comando, assim é recomendado que você coloque uma opção --user em /etc/my.cnf e especifique um outro valor diferente de root. A opção em /etc/my.cnf será encontrada antes de qualques outra opção --user, o que assegura que o servidor não execute como root, e que um aviso seja exibido se qualquer outra opção --user for encontrada.

  • -V, --version

    Mostra a informação da versão e sai.

  • -W, --log-warnings

    Imprime avisos como Aborted connection... no arquivo .err. É recomendável habilitar esta opção, por exemplo, se você estiver usando replicação (você obterá a mensagem sobre o que está acontecendo como falhas de rede e reconexões). See Seção A.2.10, “Erros de Comunicação / Comunicação Abortada”.

    Esta opção se chamava --warnings.

Pode se alterar a maioria dos valores de um servidor em execução com o comnado SET. Veja mais informações sobre isto na Seção 5.5.6, “Sintaxe de SET.

4.1.2. Arquivo de Opções my.cnf

O MySQL pode, desde a versão 3.22, ler as opções padrões de inicialização para o servidor e para clientes dos arquivos de opções.

No Windows, o MySQL lê opções padrões dos seguintes arquivos:

Nome do ArquivoPropósito
Windows-directory\my.iniOpções globais
C:\my.cnfOpções globais

Windows-directory é a localização do seu diretório Windows.

No Unix, o MySQL lê opções padrões dos seguintes arquivos:

Nome do arquivoPropósito
/etc/my.cnfOpções globais
DATADIR/my.cnfOpções específicas do servidor
defaults-extra-fileO arquivo especificado com --defaults-extra-file=#
~/.my.cnfOpções específicas do usuário

DATADIR é o diretório de dados do MySQL (normalmente /usr/local/mysql/data para instalações binárias ou /usr/local/var para instalações de código fonte). Perceba que este é o diretório que foi especificado na hora da configuração, não o especificado com --datadir quando o mysqld inicia! (--datadir não tem efeito sobre o local onde o servidor procura por arquivos de opções, porque ele procura pelos arquivos antes de processar qualquer argumento da linha de comando.)

Note que no Windows, você deve especificar todos os caminhos no arquivo de opção com / no lugar de \. Se for utilizado o \, será necessário digitá-lo duas vezes, pois o \ é o caractere de escape no MySQL.

O MySQL tenta ler os arquivos de opções na ordem listada acima. Se múltiplos arquivos de opções existirem, uma opção especificada em um arquivo lido depois recebe a precedência sobre a mesma opção especificada em um arquivo lido anteriormente. Opções especificadas na linha de comando recebem a precedência sobre opções especificadas em qualquer arquivo de opções. Algumas opções podem ser especificadas usando variáveis de ambiente. Opções especificadas na linha de comando ou nos arquivos de opção tem precendencia sobre valores nas variáveis de ambiente. Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL.

Os seguintes programas suportam arquivos de opções: mysql, mysqladmin, mysqld, mysqld_safe, mysql.server, mysqldump, mysqlimport, mysqlshow, mysqlcheck, myisamchk, e myisampack.

Desde a versão 4.0.2, você pode usar o prefixo loose para opções de linha de comando (ou opções no my.cnf). Se uma opção possui o prefixo loose, o programa que a ler não finalizará com um erro se uma opção for desconhecida, mas apenas enviará um aviso:

shell> mysql --loose-no-such-option

Você pode usar arquivos de opções para especificar qualquer opção extendida que o programa suporte! Execute o programa com --help para obter uma lista das opções disponíveis.

Um arquivo de opções pode conter linhas na seguinte forma:

  • #comentario

    Linhas de comentário iniciam com o caractere ‘#’ ou ‘;’. Comentários podem iniciar no meio de uma linha também. Linhas vazias são ignoradas.

  • [grupo]

    grupo é o nome do programa ou grupo para o qual você irá configurar as opções. Depois de uma linha de grupo, qualquer linha de opção ou set-variable são referentes ao grupo até o final do arquivo de opções ou outra linha de início de grupo.

  • opção

    Isto é equivalente à --opção na linha de comando.

  • opção=valor

    Isto é equivalente à --opção=valor na linha de comando. Por favor, note que você deve colocar um argumento entre aspas duplas, se o argumento de uma opção conter um caracter de comentário.

  • set-variable = nome=valor

    Isto é equivalente à --set-variable nome=valor na linha de comando.

    Por favor, notem que --set-variable está obsoleto desde o MySQL 4.0; a partir desta versão os nomes das variáveis de programa podem ser usados como nome de opções. Na linha de comando, use apenas --nome=valor. Em um arquivo de opção, use nome=valor.

O grupo [client] permite especificar opções para todos clientes MySQL (não o mysqld). Este é o grupo perfeito de se usar para espeficar a senha que você usa para conectar ao servidor. (Mas tenha certeza que o arquivo de opções só pode ser lido e gravado por você)

Se você quiser criar opções que devem ser lidas por uma versão específica do servidor mysqld você pode fazer isto com [mysqld-4.0], [mysqld-4.1] etc:

[mysqld-4.0]
new

A nova opção acima só será usada com o versões 4.0.x do servidor MySQL.

Perceba que para opções e valores, todos espaços em branco são automaticamente apagados. Você pode usar a sequencia de escape '\b', '\t', '\n', '\r', '\\' e '\s' no valor da string ('\s' == espaço).

Aqui está um típico arquivo de opções globais.

[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
port=3306
socket=/tmp/mysql.sock
set-variable = key_buffer_size=16M
set-variable = max_allowed_packet=1M

[mysqldump]
quick

Aqui está um típico arquivo de opções do usuário

[client]
# A senha seguinte será enviada para todos clientes MySQL
password="minha_senha"

[mysql]
no-auto-rehash
set-variable = connect_timeout=2

[mysqlhotcopy]
interactive-timeout

Se você tem uma distribuição fonte, você encontrará arquivos de exemplo de configuração chamados my-xxxx.cnf no diretório support-files. Se você tem uma distribuição binária olhe no diretório de instalação DIR/support-file, onde DIR é o caminho para o diretório de instalação (normalmente C:\mysql ou /usr/local/mysql). Atualmente existem arquivos de configuração para sistemas pequenos, médios, grandes e enormes. Você pode copiar my-xxxx.cnf para seu diretório home (renomeie a cópia para .my.cnf para experimentar.

Todos os programas MySQL que suportam arquivos de opções aceitam opções:

OpçãoDescrição
--no-defaultsNão lê nenhum arquivo de opções.
--print-defaultsImprima o nome do programa e todas opções.
--defaults-file=caminho-para-arquivo-padrãoUtilize somente o arquivo de configuração específicado.
--defaults-extra-file=caminho-para-arquivo-padrãoLeia este arquivo de configuração depois do arquivo de configuração global mas antes do arquivo de configuração do usuário.

Perceba que as opções acima devem vir primeiro na linha de comando para funcionar, com exceção que --print-defaults deve ser usado logo depois dos comandos --defaults-file ou --defaults-extra-file.

Notas para desenvolvedores: O tratamento de arquivos de opções é implementado simplesmente processando todos as opções coincidentes (isto é, opções no grupo apropriado) antes de qualquer argumento da linha de comando. Isto funciona bem para programas que usam a última instância de uma opção que é especificada diversas vezes. Se você tem um programa antigo que trata opções especificadas várias vezes desta forma mas não lê arquivos de opções, você só precisa adicionar duas linhas para lhe dar esta capacidade. Verifique o código fonte de qualquer um dos clientes MySQL padrão para ver como fazer isto.

Nos scripts shell você pode usar o comando my_print_defaults para analisar os arquivos de opção. O seguinte exemplo mostar a saída que my_print_defaults pode produzir quando quando pedido para mostrar as opções encontradas nos grupos [client] e [mysql]:

shell> my_print_defaults client mysql
--port=3306
--socket=/tmp/mysql.sock
--no-auto-rehash

4.2. Executando Múltiplos MySQL Servers na Mesma Máquina

Em alguns casos você pode precisar de executar múltiplos servidores mysqld executando na mesma máquina. Você pode desejar testar uma nova versão do MySQL enquanto a deixa a sua instalação da versão de produção existente sem perturbação. Ou você pode desejar dar acesso a diferentes usuários em diferentes servidores mysqld gerenciados por eles mesmos. (Por exemplo, você pode seu um provedor de serviços de internet que quer fornecer instalações independentes do MySQL para clientes diferentes).

Para executar múltiplos servidores em uma única máquina, cada servidor deve ter valores únicos para diversos parâmetros operacionais. Isto deve ser configurado na linha de comando ou em arquivos de opções. Veja Seção 4.1.1, “Opções de Linha de Comando do mysqld e Seção 4.1.2, “Arquivo de Opções my.cnf.

Pelo menos as seguintes opções devem ser diferente para cada servidor:

  • --port=port_num

  • --socket=path

  • --shared-memory-base-name (apenas Windows; novo no MySQL 4.1)

  • --pid-file=path (apenas Unix)

--port controla o número da porta para conexões TCP/IP. --socket controla o caminho do arquivo de socket no Unix e o nome do named pipe no Windows. (É necessário nomes de pipes distintos no Windows apenas para aqueles servidores que suportam conexão named pipes.)

--shared-memory-base-name designa o nome da memória compartilhada por um servidor Windows para permitir que o cliente se conecte via memória compartilhada. --pid-file indice o nome do arquivo no qual o Unix gravar a ID do seu processo.

Se você usar as seguintes opções, elas deve ser diferentes para cada servidor:

  • --log=path

  • --log-bin=path

  • --log-update=path

  • --log-error=path

  • --log-isam=path

  • --bdb-logdir=path

Se você quiser mais desempenho, você também pode especificar as seguinte opções diferentemente para cada servidor para distribuir a carga entre vários discos físicos:

  • --tmpdir=path

  • --bdb-tmpdir=path

Normalmente, cada servidor também deve usar um diretório de dados diferentes, que é especificado usando a opção --datadir=path.

AVISO: Normalmente você nunca deve ter dois servidores que atualizam dados no mesmo banco de dados! Isto pode levar a supresas inesperadas se seu o seu sistema operacionalnão suporta lock de sistema a prova de falhas, isto pode provocar surpresas indesejáveis! Se (apesar deste aviso) você executar diversos servidores usando o mesmo diretório de dados e eles tiverem com o log habilitado, você usar as opções apropriadas para especificar os nomes dos arquivos de log que são únicos em cada servidor. Senão, o servidores podem tentar gravar no mesmo arquivo de log.

Este aviso contra o compartilhamento de arquivos de dados entre servidores também se aplica em um ambeinte NFS. Permitir vários servidores MySQL acessarem um diretório de dados comum sobre NFS, é normalmente uma MÁ IDÉIA!

  • O primeiro problema é que o NFS se tornará um gargalo, tornando o sistema lento. Ele não se destina para este tipo de uso.

  • Outro risco com NFS é que você terá que conseguir um modo de se certificar que dois ou mais servidores não estão interferindo uns com os outros. Normalmente o lock de arquivo é tratado pelo daemon lockd, mas no momento não existe nenhuma plataforma que fara o locck 100% de segurança, em todas as situações.

Facilite a sua vida: esqueça sobre compartilhar um diretório de dados entre servidores sobre NFS. A solução melhor é ter um computador com um sistema operacional que manipule threads de forma eficiente threads e tenha diversas CPUs nele.

Se você tiver múltiplas instalações do MySQL em diferentes locais, normalemente você pode especificar o diretório de instalação base de cada servidor com a opção --basedir=caminho para fazer que cada servidor use diferentes diretórios de dados, arquivos de log e arquivos PID. (O padrão para todos estes valores são determinados em relação ao diretório base.) Neste caso, as únicas outras opções que você precisa especificar são as opções --socket e --port. Por exempo, suponha que você instalou a versão binária do MySQL (arquivos .tar) em diferentes locais, assim você pode iniciar o servidor usando o comando ./bin/mysqld_safe sob o diretório base correspondente de cada instalação. mysqld_safe determinará a opção --basedir apropriada para passar para mysqld, e você precisa especificar apenas as opções --socket e --port para o mysqld_safe.

Como discutido nas seções a seguir, é possível iniciar servidores adicionais configurando variáveis de ambiente ou especificando as opções de linha de comando apropriada. No entanto, se você precisa executar múltiplos servidores em uma base mais permanente, será mais coonveniente usar os arquivos de opções para especificar, para cada servidor, aquelas opções que devem ser únicas para ele. See Seção 4.1.2, “Arquivo de Opções my.cnf.

4.2.1. Executando Múltiplos Servidores no Windows

Você pode executar múltiplos servidor no Windows iniciando-os manualmente a partir da linha de comando, cada um com o parâmetro operacional apropriado. Em sistemas baseados no Windows NT, você também tem a opção de instalar vários servidores como serviços Windows e executá-los deste modo. Instruções gerais sobre a execucão de servidores MySQL a partir da linha de comando ou como serviços são dados em Seção 2.6.1, “Notas Windows”. Esta seção descreve como se certificar de que você inicioou cada servidor com valores diferentes para aquelas opções de inicialização que devem ser unicas por servidor, como o diretório de dados. (Estas opções são descritas em Seção 4.2, “Executando Múltiplos MySQL Servers na Mesma Máquina”.)

4.2.1.1. Iniciando Múltiplos Servidores na Linha de Comando

Para iniciar vários servidores manualmente na linha de comando, você pode especificar a opção apropriada na linha de comando ou no arquivo de opções. É mais conveniente colocar as opções em um arquivo de opção. Para fazer isto, crie uma arquivo de opção para cada servidor e mostre ao servidor o nome do arquivo com a opção --defaults-file quando você executá-lo.

Suponha que você queira executar o mysqld na porta 3307 com um diretório de dados de C:\mydata1, e mysqld-max na porta 3308 com um diretório de dados de C:\mydata2. Para conseguir isto, crie dois arquivos de opções. Por exemplo, crie um arquivo chamado C:\my-opts1.cnf que se pareça com isto:

[mysqld]
datadir = C:/mydata1
port = 3307

Crie um segundo arquivo chamado C:\my-opts2.cnf que se pareça com isto:

[mysqld]
datadir = C:/mydata2
port = 3308

Então inicie cada servidor com seus próprios arquivos de opção:

shell> mysqld --defaults-file=C:\my-opts1.cnf
shell> mysqld-max --defaults-file=C:\my-opts2.cnf

(No NT, o servidor iniciará em segundo plano, assim você precisará enviar estes dois comandos em janelas de console separadas.)

Para desligar o servidor, você deve conectar a porta apropriada:

shell> mysqladmin --port=3307 shutdown
shell> mysqladmin --port=3308 shutdown

Servidores configurados como descrito permitirá que clientes se conectem por TCP/IP. Se você também quiser permitir conexões named pipe, use os servidores mysqld-nt ou mysqld-max-nt e especifique as opção que habilitem o named pipe e especifique os seus nomes. (Cada servidor que suporta conexões named pipes deve ter um nome único). Por exemplo, o arquivo C:\my-opts1.cnf pode ser escrito da seguinte maneira:

[mysqld]
datadir = C:/mydata1
port = 3307
enable-named-pipe
socket = mypipe1

Estão inicie o servidor desta forma:

shell> mysqld-nt --defaults-file=C:\my-opts1.cnf

C:\my-opts2.cnf seria modificado de forma parecida para uso com o segundo servidor.

4.2.1.2. Iniciando Múltiplos Servidores Como Serviços

Em sistemas baseados no NT, um servidor MySQL pode ser executado como um serviço Windows. O procedimento para instalação, controle e remoção de um único serviço MySQL está descrito em Seção 2.1.1.7, “Iniciando o MySQL no Windows NT, 2000, ou XP”.

A partir do MySQL 4.0.2, você pode instalar vários servidores como serviços. Neste caso, você deve ter certeza de que cada servidor usa um nome de serviço diferente junto com todos os outros parâmetros que devem ser único por servidor.

Para as seguintes instruções, assuma que você queira executar o servidor mysqld-nt a partir de duas versões diferentes do MySQL que está instalado em C:\mysql-4.0.8 e C:\mysql-4.0.17, respectivamente. (Este pode ser o caso se você estiver executando a versão 4.0.8 como seu servidor de produção, mas queira testar o 4.0.17 antes de atualizá-lo.)

Os seguintes princípios são relevantes ao instalr um serviço MySQL com a opção --install:

  • Se você não especificar o nome do serviço, o servidor usa o nome padrão do serviço (MySQL) e o servidor lê as opções do grupo [mysqld] no arquivo de opções padrão.

  • Se você especificar um nome de serviço depois da opção --install, o servidor ignora o grupo de opção [mysqld] e lê as opções do grupo que tem o mesmo nome que o serviço. O servidor lê as opções do arquivo de opção padrão.

  • Se você especificar uma opção --defaults-file depois do nome do serviço, o servidor ignora o arquivo de opções padrão e lê as opções apenas do grupo [mysqld] do arquivo chamado.

Este princípios também se aplicam se você intalar um servidor usando a opção --install-manual.

Baseado na informação anterior, você tem diversos de configurar vários serviços. As seguintes instruções descrevem alguns exemplos. Antes de tentar qualquer uma delas esteja certo de que você desligou e removeu qualquer serviço MySQL existente primeiro.

  • Especifique as opções para todos os serviços em um dos arquivos de opções padrão. Para fazer isto, use um nome de serviço diferente para cada servidor. Suponha que você queira executar o mysqld-nt 4.0.8 usando o nome de serviço [mysqld1] e o mysqld-nt 4.0.17 usando o nome de serviço mysqld2. Neste caso você pode usar o grupo [mysqld1] para o 4.0.8 e o grupo [mysqld2] para o MySQL 4.0.14. Por exemplo, você pode configurar o C:\my.cnf desta forma:

    # opções para o serviço mysqld1
    [mysqld1]
    basedir = C:/mysql-4.0.8
    port = 3307
    enable-named-pipe
    socket = mypipe1
    
    # opções para o serviço mysql2
    [mysqld2]
    basedir = C:/mysql-4.0.17
    port = 3308
    enable-named-pipe
    socket = mypipe2
    

    Instale os serviços como a seguir, usando o caminho completo para o servidor para assegurar que o Windows registra o programa executável correto para cada serviço:

    shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
    shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
    

    Para iniciar os serviços, use o gerenciador de serviços, ou use NET START com o nome de serviço apropriado:

    shell> NET START mysqld1
    shell> NET START mysqld2
    

    Para parar os serviços, use o gerenciador de serviços, ou use NET STOP com o mesmo nome de serviço.

    shell> NET STOP mysqld1
    shell> NET STOP mysqld2
    

    Nota: Antes do MySQL 4.0.17, apenas um servidor instalado usando o nome de serviço padrão (MySQL) ou instalado com um nome de serviço de mysqld irá ler o grupo [mysqld] no arquivo de opções padrão. A partir da versão 4.0.17, todos os servidores lêem o grupo [mysqld] se eles lêem o arquivo de opções padrão, mesmo de esles estão instalados usando outro nome de serviço. Isto permite que você use o grupo [mysqld] para opções que devam ser usadas por todos os serviços MySQL, e um grupo de opção com o nome de cada serviço para o uso do servidor com aquele nome de serviço.

  • Especifique as opções para cada servidor em arquivos separados e use --defaults-file quando instalar os serviços para dizer para cada servidor que arquivo usar. Neste caso, cada arquivo deve listar as opções usando um grupo [mysqld].

    Com esta abordagem, para especificar as opções para o mysqld-nt 4.0.8, crie um arquivo C:\my-opts1.cnf que se pareça com:

    [mysqld]
    basedir = C:/mysql-4.0.8
    port = 3307
    enable-named-pipe
    socket = mypipe1
    

    Para o mysqld-nt 4.0.17, crie um arquivo C:\my-opts2.cnf que se pareça com:

    [mysqld]
    basedir = C:/mysql-4.0.17
    port = 3308
    enable-named-pipe
    socket = mypipe2
    

    Instale o serviço como indicado a seguir (digite cada comando em uma única linha):

    shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
               --defaults-file=C:\my-opts1.cnf
    shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
               --defaults-file=C:\my-opts2.cnf
    

    Para usar uma opção --defaults-file quando instalar um servidor MySQL como um serviço, você deve anteceder a opção com o nome do serviço.

    Depois de instalarm, inicie e para os serviços do mesmo modo que no exemplo anterior.

Para remover vários serviços, use mysqld --remove para cada um, especificando um nome de serviço depois da opção --remove se o serviço a ser removido tiver um nome difertente do padrão.

4.2.2. Executando Múltiplos Servidores no Unix

O modo mais fácil de executar diversos servidores no Unix é compilá-los com diferentes portas TCP/IP e arquivos socket, assim cada um está escutando em diferentes interfaces de rede. Também, compilando em diferentes diretórios bases para instalação, que automaticamente resulta em diferentes localizações de diretórios de dados, arquivos log e arquivos PID para cada um dos seus servidores.

Considere que um servidor existente está configurado para a porta e arquivo socket padrões. Para configurar um novo servidor para ter parâmetros operacionais diferentes, use um comando configure assim:

shell> ./configure --with-tcp-port=port_number \
             --with-unix-socket-path=nome_arquivo \
             --prefix=/usr/local/mysql-4.0.17

Aqui número_porta e nome_arquivo deve ser diferente que o número da porta e o caminho do arquivo socket padrões e o valor --prefix deve especificar um diretório de instalação diferente daquele usado pelo servidor existente.

Você pode conferir o socket usado por qualquer servidor MySQL em execução com este comando:

Se você tem um servidor MySQL escutando em uma porta dada, você pode usar o seguinte comando para descobrir quaie parâmetros operacionais ele está usando para diversas variáveis importantes configuráveis, incluíndo o diretório base e o nome do socket:

shell> mysqladmin --host=host_name --port=port_number variables

Com a informação exibida por aquele comando, você pode dizer quais valores de opção não usar ao configurar um servidor adicional.

Note que se você especificar ``localhost'' como o nome da máquina, mysqladmin irá por padrão usar uma conexão sockets Unix em vez de TCP/IP. No MySQL 4.1 você também pode especificar o protocolo a ser usado com a opção --protocol={TCP | SOCKET | PIPE | MEMORY}.

Não é necessário compilar um novo servidor MySQL apenas para iniciar com uma arquivo socket ou número de porta TCP/IP diferentes. Também é possível especificar estes valores em tempo de execução. Um modo de fazê-lo é usando as opções de linha de comando:

shell> /path/to/mysqld_safe --socket=file_name --port=port_number

Para usar outro diretório de banco de dados para o segundo servidor, passe uma opção --datadir=caminho para o mysqld_safe.

Um outro modo de conseguir este efeito é usar as variáveis de ambiente para configurar o nome do socket e o número da porta:

shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
shell> scripts/mysql_install_db
shell> bin/mysqld_safe &

Este é um modo rápido para iniciar um segundo servidor para teste. O bom deste método é que a configuração das variáveis de ambiente se aplicarão a qualquer programa cliente que você chame da shell acima. Assim, as conexões para estes clientes serão automaticamente direcionadas para o segundo servidor!

Apêndice F, Variáveis de Ambientes do MySQL inclue uma lista de outras variáveis de ambiente que você pode usar e que afetam o mysqld.

Para a execução automatica do servidor, seu script de inicialização que é executado no tempo de boot deve executar o seguinte comando uma vez para cada servidor com um caminmho apropriado do arquivo de opção para cada comando:

mysqld_safe --defaults-file=path-to-option-file

Cada arquivo de opção deve conter valores específicos para um dados servidor.

No Unix, o script mysqld_multi é outro modo de de iniciar vários servidores. Veja mais informações sobre isto na Seção 4.8.3, “mysqld_multi, programa para gerenciar múltiplos servidores MySQL”.

4.2.3. Usando Programas Clientes em um Ambiente Multi-Servidor

Quando você quiser conectar com um programa cliente a um servidor MySQL que está escutando diferentes interfaces de rede em vez daquelas compiladas em seu programa cliente, você pode conectar usando um dos seguintes métodos:

  • Inicie o cliente com --host=nome_máquina --port=número_porta para conectar com TCP/IP a uma máquina remota, ou com --host=localhost --socket=nome_arquivo para conectar a máquina local via um socket Unix ou um named pipe do Windowes.

  • No MySQL 4.1, inicie o cliente com --protocol=tcp para conectar via TCP/IP, --protocol=socket para conectar via socket Unix ou --protocol=pipe para conectar via named pipe, ou --protocol=memory para conectar via memória compartilhada. Para conexões TCP/IP, você também pode precisar especificar as opções --host e --port. Para outros tipos de conexões, você pode precisar especificar uma opção --socket para definir um nome de socket ou named pipe name, ou uma opção --shared-memory-base-name para especificar o nome da memória compartilhada.

    No Unix, configure as variáveis de ambiente MYSQL_UNIX_PORT e MYSQL_TCP_PORT para apontar para o socket Unix e porta TCP/IP antes de iniciar seus clientes. Se você normalmente utiliza uma porta ou socket específico, você pode colocar os comandos para configurar as variáveis de ambiente no arquivo .login, assim eles serão aplicados sempre quer você logar no sistema. See Apêndice F, Variáveis de Ambientes do MySQL.

  • Especifique o socket e porta TCP/IP padrões no grupo [clients] de um arquivo de opções. Por exemplo, você pode usar C:\my.cnf no WIndows ou o arquivo .my.cnf em seu diretório home no Unix. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Em um programa C, você pode especificar os argumentos de porta ou socket na chamada de mysql_real_connect(). Você também pode ter o programa lendo de um arquivo de opções chamando mysql_options(). See Seção 12.1.3, “Descrição das Funções da API C”.

  • Se você estiver usando o módulo Perl DBD::mysql você pode ler as opções dos arquivos de opções do MySQL. Por exemplo:

    $dsn = "DBI:mysql:test;mysql_read_default_group=client;"
            . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
    $dbh = DBI->connect($dsn, $user, $password);
    

    Veja mais informações sobre isto na Seção 12.5.2, “A interface DBI.

4.3. Detalhes Gerais de Segurança e o Sistema de Privilégio de Acesso do MySQL

O MySQL tem um sistema de segurança/privilégios avançado mas não padrão. A próxima seção descreve como ele funciona.

4.3.1. Segurança Geral

Qualquer um usando o MySQL em um computador conectado à internet deve ler esta seção para evitar os erros de segurança mais comuns.

Discutindo segurança, nós enfatizamos a a necessidade de proteger completamente o servidor (não simplesmente o servidor MySQL) contra todos os tipos de ataques aplicáveis: eavesdropping, altering, playback e denial of service. Não cobriremos todos os aspectos de disponibilidade e tolerância a falhas aqui.

O MySQL utiliza a segurança baseado em Listas de Controle de Acesso (ACL) para todas conexões, consultas e outras operações que um usuário pode tentar realizar. Existe também algum suporte para conexões criptografadasSSL entre clientes MySQL e servidores. Vários dos conceitos discutidos aqui não são específicos do MySQL; as mesmas idéias podem ser aplicadas para a maioria das aplicações.

Quando executando o MySQL, siga estes procedimentos sempre que possível:

  • nunca conceda a alguém (exceto ao usuário root do mysql) acesso à tabela user no banco de dados mysql!. Isto é perigoso. A senha criptografada é a senha real no MySQL. Se você conhece a senha listada na tabela user para um determinado usuário, você pode facilmente logar como este usuário se tiver acesso à máquina relacionada para aquela conta.

  • Aprenda o sistema de controle de acessos do MySQL. Os comandos GRANT e REVOKE são usados para controlar o acesso ao MySQL. Não conceda mais privilégios do que o necessário. Nunca conceda privilégios para todas as máquinas.

    Checklist:

    • Tente mysql -u root. Se você conseguir conectar com sucesso ao servidor sem a solicitação de uma senha, você tem problemas. Qualquer um pode conectar ao seu servidor MySQL como o usuário root com privilégios plenos! Revise as instruções de instalação do MySQL, prestando atenção particularmente ao item sobre configuração da senha do usuário root.

    • Utilize o comando SHOW GRANTS e confira para ver quem tem acesso a o que. Remova aqueles privilégios que não são necessários utilizando o comando REVOKE.

  • Não mantenha nenhuma senha de texto puro no seu banco de dados. Quando seu computador fica comprometido, o intruso pode obter a lista completa de senhas e utilizá-las. Utilize a função MD5(), SHA1() ou qualquer função de embaralhamento de via única.

  • Não escolha senhas de dicionários. Existem programas especiais para quebrá-las. Mesmo senhas como ``xfish98'' não sao boas. Muito melhor seria ``duag98'' que contém a mesma palavra 'fish mas digitada uma letra a esquerda em um teclado QWERTY convencional. Outro método seria usar ``Mhall'' que é obtido dos primeiros caracteres de cada palavra na frase ``Mary has a litle lamb''. Isto é fácil de lembrar e digitar, mas dificulta que alguém que não a conheça a advinhe.

  • Invista em um firewall. Ele protege você de pelo menos 50% de todos os tipos de exploits em qualquer software. Coloque o MySQL atrás do firewall ou em uma zona desmilitarizada (DMZ).

    Checklist:

    • Tente examinar suas portas da Internet utilizando alguma ferramenta como o nmap. O MySQL utiliza a porta 3306 por padrão. Esta porta não deve ser acessível para máquinas não confiáveis. Outra maneira simples para conferir se sua porta do MySQL está aberta ou não é tentar o seguinte comando de alguma máquina remota, onde nome_máquina é o nome da máquina ou o endereço IP de seu servidor MySQL:

      shell> telnet nome_máquina 3306
      

      Se você obter uma conexão e alguns caracteres, a porta está aberta e deve ser fechada no seu firewall ou roteador, a menos que você realmente tenha uma boa razão para mantê-la aberta. Se o telnet apenas parar ou a conexão for recusada, tudo está bem; a porta está bloqueada.

  • Não confie em nenhum dado incluídos pelos seus usuários. Eles podem tentar enganar seu código entrando com caracteres especiais ou sequencias de escape nos formulários Web, URLS ou qualquer aplicação que você construa. Tenha certeza que sua aplicação continua segura se um usuário entrar com algo do tipo ``; DROP DATABASE mysql;''. Este é um exemplo extremo, mas grandes falhas de segurança ou perda de dados podem ocorrer como o resultado de hackers utilizando técnicas similares, se você não estiver preparado para eles.

    Também lembre de conferir dados numéricos. Um erro comum é proteger somente as strings. Em alguns casos as pessoas pensam que se um banco de dados contém somente dados disponíveis publicamente, ele não precisa ser protegido. Isto não é verdade. No mínimo ataques do tipo denial-of-service podem ser feitos nestes bancos de dados. A maneira mais simples para proteger deste tipo de ataque é usar apóstrofos em torno das contantes numéricas: SELECT * FROM tabela WHERE ID='234' em vez de SELECT * FROM table WHERE ID=234. O MySQL automaticamente converte esta string para um número e corta todos os símbolos não-numéricos dela.

    Checklist:

    • Todas aplicações Web:

      • Tente inserir ‘'’ e ‘"’ em todos seus formulários Web. Se você obter qualquer tipo de erro do MySQL, investigue o problema imediatamente.

      • Tente modificar qualquer URL dinâmica adicionando %22 (‘"’), %23 (‘#’) e %27 (‘'’) na URL.

      • Tente modificar os tipos de dados nas URLs dinâmicas de numérico para caractere contendo caracteres dos exemplos anteriores. Sua aplicação deve ser segura contra estes ataques e similares.

      • Tente inserir caracteres, espaços e símbolos especiais no lugar de número nos campos numéricos. Sua aplicação deve removê-los antes de passá-los para o MySQL ou sua aplicação deve gerar um erro. Passar valores não verificados ao MySQL é extramente perigoso!

      • Confira o tamanho dos dados antes de passá-los ao MySQL.

      • Considere ter sua aplicação conectando ao banco de dados utilizando um usuário diferente doq ue o que é utilizado com propósitos administrativos. Não forneça às suas aplicações mais privilégios de acesso do que elas necessitam.

    • Usuários do PHP:

      • Confira a função addslashes(). No PHP 4.0.3, uma função mysql_escape_string() está disponível e é baseada na função com o mesmo nome da API C do MySQL.

    • Usuários do API C do MySQL:

      • Confira a chamada API mysql_escape_string().

    • Usuários do MySQL:

      • Confira os modificadores escape e quote para consultas streams.

    • Usuários do Perl DBI:

      • Confira o método quote() ou utilize aspas simples ou duplas.

    • Usuários do Java JDBC:

      • Utilize um objeto PreparedStatement e aspas simples ou duplas.

  • Não transmita dados sem criptografia na Internet. Estes dados são acessíveis para todos que tenham o tempo e habilidade para interceptá-lo e usá-lo para seu propósito próprio. No lugar, utilize um protocolo de criptografia como o SSL ou SSH. O MySQL suporta conexões SSL interno desde a versão 3.23.9. O repasse de portas do SSH pode ser usado para criar um tunel criptografado (e com compressão) para a comunicação.

  • Aprenda a usar os utilitários tcpdump e strings. Para a maioria dos casos você pode conferir se o fluxo de dados do MySQL está ou não criptografado utilizando um comando parecido com este:

    shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
    

    (Isto funciona sobre Linux e deve funcionar com pequenas modificações sob outros sistemas.) Alerta: Se você não ver dados não significa sempre que esteja criptografado. Se você necessita de alta segurança, você deve consultar um especialista em segurança.

4.3.2. Como Tornar o MySQL Seguro contra Crackers

Quando você conectar a um servidor MySQL, você normalmente deve usar uma senha. A senha não é transmitida em texto puro sobre a conexão, porém o algorítimo de criptografica não é muito forte e com algum esforço um atacante engenhoso pode quebrar a senha se ele conseguir capturar o tráfego entre o cliente e o servidor. Se a conexão entre o cliente e o servidor passar por uma rede não confiável, você deve usar um tunnel SSH para criptografar a comunicação.

Todas outras informações são transferidas como texto que podem ser lido por qualquer um que consiga ver a conexão. Se você se preocupa com isto, você pode usar o protocol de compressão (No MySQL versão 3.22 e superiores) para tornar o tráfico muito mais dificil de decifrar. Para deixar tudo ainda mais seguro você deve usar ssh. Você pode encontrar um cliente ssh open source em http://www.openssh.org, e um cliente ssh comercial em http://www.ssh.com. Com isto, você pode obter uma conexão TCP/IP critografada entre um servidor MySQL e um cliente MySQL.

Se você estiver usando o MySQL 4.0, você também pode usar o suporte interno OpenSSL Veja mais informações sobre isto na Seção 4.4.10, “Usando Conexões Seguras”.

Para deixar um sistema MySQL seguro, você deve considerar as seguintes sugestões:

  • Utilize senhas para todos os usuários MySQL. Lembre-se que qualquer um pode logar como qualquer outra pessoa simplesmente com mysql -u outro_usuário nome_bd se outro_usuário não tiver senha. Isto é um procedimento comum com aplicações cliente/servidor que o cliente pode especificar qualquer nome de usuário. Você pode alterar a senha de todos seus usuários editando o script mysql_install_db antes de executá-lo ou somente a senha para o usuário root do MySQL desta forma:

    shell> mysql -u root mysql
    mysql> UPDATE user SET Password=PASSWORD('nova_senha')
        ->             WHERE user='root';
    mysql> FLUSH PRIVILEGES;
    
  • Não execute o daemon do MySQL como o usuário root do Unix. Isto é muito perigoso, porque qualquer usuário com privilégios FILE estará apto a criar arquivos como o root (por exemplo, ~root/.bashrc). Para prevenir esta situação, mysqld irá recusar a execução como root a menos que ele seja especificado diretamente usando a opção --user=root.

    O mysqld pode ser executado como um usuário normal sem privilégios. Você pode também criar um novo usuário Unix mysql para tornar tudo mais seguro. Se você executar o mysqld como outro usuário Unix, você não precisará alterar o usuário root na tabela user, porque nomes de usuário do MySQL não tem nada a ver com nomes de usuários Unix. Para iniciar o mysqld como outro usuário Unix, adicione uma linha user que especifica o nome de usuário para o 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=mysql
    

    Estas opções configuram o servidor para iniciar como o usuário designado quando você o inicia manualmente ou usando mysqld_safe ou mysql.server. Para maiores detalhes, veja Seção A.3.2, “Como Executar o MySQL Como Um Usuário Normal”.

  • Não suportar links simbólicos para tabelas (Isto pode ser desabilitado com a opção --skip-symlink. Isto é muito importante caso você execute o mysqld como root, assim qualquer um que tenha acesso à escrita aos dados do diretório do mysqld podem apagar qualquer arquivo no sistema! See Seção 5.6.1.2, “Utilizando Links Simbólicos para Tabelas”.

  • Verfique se o usuário Unix que executa o mysqld é o único usuário com privilégios de leitura/escrita nos diretórios de bancos de dados.

  • Não forneça o privilégio PROCESS para todos os usuários. A saída de mysqladmin processlits mostra as consultas atualmente em execução, portanto qualquer usuário que consiga executar este comando deve ser apto a ver se outro usuário entra com uma consulta do tipo UPDATE user SET password=PASSWORD('não_seguro').

    O mysqld reserva uma conexão extra para usuários que tenham o privilégio process, portanto o usuário root do MySQL pode logar e verificar a atividade do servidor mesmo se todas as conexões normais estiverem em uso.

  • Não conceda o privilégio FILE a todos os usuários. Qualquer usuário que possua este privilégio pode gravar um arquivo em qualquer lugar no sistema de arquivos com os privilégios do daemon mysqld! Para tornar isto um pouco mais seguro, todos os arquivos gerados com SELECT ... INTO OUTFILE são lidos por todos, e não se pode sobrescrever arquivos existentes.

    O privilégio FILE pode também ser usado para ler qualquer arquivo acessível para o usuário Unix com o qual o servidor está sendo executado. Pode ocorrer abusos como, por exemplo, usar LOAD DATA para carregar o arquivo /etc/passwd em uma tabela, que pode então ser lido com SELECT.

  • Se você não confia em seu DNS, você deve utilizar números IP no lugar de nomes de máquinas nas tabelas de permissão. De qualquer forma, você deve ter muito cuidado ao criar entradas de concessão utilizando valores de nomes de máquinas que contenham metacaractes!

  • Se você deseja restrigir o número de conexões para um único usuário, você pode faze-lo configurando a variável max_user_connections no mysqld.

4.3.3. Opções de Inicialização para o mysqld em Relação a Segurança.

As seguintes opções do mysqld afetam a segurança:

  • --local-infile[=(0|1)]

    Se alguém usa --local-infile=0 então não de pode usar LOAD DATA LOCAL INFILE.

  • --safe-show-database

    Com esta opção, SHOW DATABASES retorna somente os bancos de dados nos quais o usuário tem algum tipo de privilégio. A partir da versão 4.0.2 esta opção está obsoleta e não faz nada (a opção está habilitada por padrão) já que agora temos o privilégio SHOW DATABASES. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

  • --safe-user-create

    Se for habilitado, um usuário não consegue criar novos usuários com o comando GRANT, se o usuário não tiver privilégio de INSERT na tabela mysql.user. Se você desejar fornecer a um usuário acesso para só criar novos usuários com privilégios que o usuário tenha direito a conceder, você deve dar ao usuário o seguinte privilégio:

    mysql> GRANT INSERT(user) ON mysql.user TO 'user'@'hostname';
    

    Isto irá assegurar que o usuário não poderá alterar nenhuma coluna de privilégios diretamente, mas tem que usar o comando GRANT para conceder direitos para outros usuários.

  • --skip-grant-tables

    Esta opção desabilita no servidor o uso do sistema de privilégios. Isto dá a todos os usuários acesso total a todos os bancos de dados! (Você pode dizer a um servidor em execução para para uar as tabelas de permissões executando mysqladmin flush-privileges ou mysqladmin reload.)

  • --skip-name-resolve

    Nomes de máquinas não são resolvidos. Todos os valores da coluna Host nas tabelas de permissões devem ser números IP ou localhost.

  • --skip-networking

    Não permitir conexões TCP/IP sobre a rede. Todas as conexões para mysqld devem ser feitas via Sockets Unix. Esta opção não é possível em sistemas que usam MIT-pthreads, porque o pacote MIT-pthreads não suporta sockets Unix.

  • --skip-show-database

    Não permite o comando SHOW DATABASES, a menos que o usuário tenha o privilégio SHOW DATABASES. A partie da versão 4.0.2 você não deve mais precisar desta opção, já que o aceesso pode agora ser concedido especificamente com o privilégio SHOW DATABASES.

4.3.4. Detalhes de Segurança com LOAD DATA LOCAL

No MySQL 3.23.49 e MySQL 4.0.2 (4.0.13 no Windows), adicionamos algumas novas opções para lidar com possíveis detalhes de segurança junto ao LOAD DATA LOCAL.

Exstem dois problemas possíveis com o suporte a este comando:

Como a leitura deste arquivo é iniciada por um servidor, pode-se teoricamente criar um servidor MySQL corrigido que poderia ler qualquer arquivo na máquina cliente na qual o usuário atual tenha acesso, quando o cliente envia uma consulta a tabela.

Em um ambiente web onde os clientes estão conectados a um servidor web, um usuário poderia usar LOAD DATA LOCAL para ler qualquer arquivo no qual o processo do servidor web tenha acesso de leitura (assumindo que um usuário poderia executar qualquer comando no servidor SQL).

Existem dois arquivos separados para isto:

Se você não configurar o MySQL com --enable-local-infile, então LOAD DATA LOCAL será disabilitado por todos os clientes, a menos que se chame mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0) no cliente. Veja mais informações sobre isto na Seção 12.1.3.40, “mysql_options().

Para o cliente de linha de comando mysql, LOAD DATA LOCAL pode ser habilitado especificado a opção --local-infile[=1], ou disabilitando com --local-infile=0.

Por padrão, todos os clientes e bibliotacas MySQL são compilados com --enable-local-infile, para ser compatível com o MySQL 3.23.48 e anterior.

Pode se desabilitar todos os comandos LOAD DATA LOCAL no servidor MySQL iniciando o mysqld com --local-infile=0.

No caso em que LOAD DATA LOCAL INFILE está disabilitado no servidor ou no cliente, você receberá a seguinte mensagem de erro (1148):

The used command is not allowed with this MySQL version

4.3.5. O Que o Sistema de Privilégios Faz

A função primária do sistema de privilégios do MySQL é autenticar um usuário a partir de uma determinada máquina e associar este usuário com privilégios a banco de dados como como select, insert, update e delete.

Funcionalidades adicionais incluem a habilidade de ter um usuário anônimo e conceder privilégio para funções específicas do MySQL como em LOAD DATA INFILE e operações administrativas.

4.3.6. Como o Sistema de Privilégios Funciona

O sistema de privilégios do MySQL garante que todos usuários possam fazer exatamente as operações que lhe é permitido. Quando você conecta a um servidor MySQL, sua identidade é determinada pela maquina de onde você conectou e o nome de usuário que você especificou. O sistema concede privilégios de acordo com sua identidade e com o que você deseja fazer.

O MySQL considera tanto os nomes de máquinas como os nomes de usuários porque existem poucas razões para assumir que um determinado nome de usuário pertence a mesma pessoa em todo lugar na Internet. Por exemplo, o usuário bill que conecta de whitehouse.gov não deve necessariamente ser a mesma pessoa que o usuário bill que conecta da microsoft.com O MySQL lida com isto, permitindo a distinção de usuários em diferentes máquinas que podem ter o mesmo nome: Você pode conceder a bill um conjunto de privilégios para conexões de whitehouse.gov e um conjunto diferente de privilégios para conexões de microsoft.com.

O controle de acesso do MySQL é composto de dois estágios:

  • Estágio 1: O servidor confere se você pode ter acesso ou não.

  • Estágio 2: Assumindo que você pode conectar, o servidor verifica cada requisição feita para saber se você tem ou não privilégios suficientes para realizar a operação. Por exemplo, se você tentar selecionar linha de uma tabela em um banco de dados ou apagar uma tabela do banco de dados, o servidor se certifica que você tem o privilégio select para a tabela ou o privilégio drop para o banco de dados.

Note que se os seus privilégios são alterados (tanto por você quanto por outro) enquanto você está conectado, estas alterações não irão necessariamente ter efeito com a sus próxima consulta ou consultas. Veja Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito” para maiores detalhes.

O servidor utiliza as tabelas user, db e host no banco de dados mysql em ambos estágios do controle de acesso. Os campos nestas tabelas de permissão são detalhados abaixo:

Nome da Tabelauserdbhost
Campos de EscopoHostHostHost
 UserDbDb
 PasswordUser 
Campos de PrivilégioSelect_privSelect_privSelect_priv
 Insert_privInsert_privInsert_priv
 Update_privUpdate_privUpdate_priv
 Delete_privDelete_privDelete_priv
 Index_privIndex_privIndex_priv
 Alter_privAlter_privAlter_priv
 Create_privCreate_privCreate_priv
 Drop_privDrop_privDrop_priv
 Grant_privGrant_privGrant_priv
 References_privReferences_privReferences_priv
 Reload_priv  
 Shutdown_priv  
 Process_priv  
 File_priv  
 Show_db_priv  
 Super_priv  
 Create_tmp_table_privCreate_tmp_table_privCreate_tmp_table_priv
 Lock_tables_privLock_tables_privLock_tables_priv
 Execute_priv  
 Repl_slave_priv  
 Repl_client_priv  
 ssl_type  
 ssl_cypher  
 x509_issuer  
 x509_cubject  
 max_questions  
 max_updates  
 max_connections  

No segundo estágio do controle de acesso (verificação da solicitação), o servidor pode, se a solicitação involver tabelas, consultar adicionalmente as tabelas tables_priv e columns_priv. Os campos nestas tabelas são mostrados abaixo:

Nome da tabelatables_privcolumns_priv
Campos de escopopHostHost
 DbDb
 UserUser
 Table_nameTable_name
  Column_name
Campos de privilégioTable_privColumn_priv
 Column_priv 
Outros camposTimestampTimestamp
 Grantor 

Cada tabela de permissões contêm campos de escopo e campos de privilégios.

Campos de escopo determinam o escopo de cada entrada nas tabelas, isto é, o contexto no qual a entrada se aplica. Por exemplo, uma entrada na tabela user com valores Host e User de 'thomas.loc.gov' e 'bob' devem ser usados para autenticar conexões feitas ao servidor por bob da máquina thomas.loc.gov. De maneira similar, uma entrada na tabela db com campos Host, User e Db de 'thomas.loc.gov', 'bob' e 'reports' devem ser usados quando bob conecta da máquina thomas.loc.gov para acessar o banco de dados reports. As tabelas tables_priv e columns_priv contem campos de escopo indicando as combinações de tabelas ou tabela/coluna para o qual cada entrada se aplica.

Para propósitos de verificação de acessos, comparações de valores Host são caso insensitivo, valores User, Password, Db e Table_name são caso sensitivo. Valores Column_name são caso insensitivo no MySQL versão 3.22.12 ou posterior.

Campos de privilégios indicam os privilégios concedidos por uma entrada na tabela, isto é, quais operações podem ser realizadas. O servidor combina as informações de várias tabelas de concessão para formar uma descrição completa dos privilégios de um usuário. As regras usadas para fazer isto são descritas em Seção 4.3.10, “Controle de Acesso, Estágio 2: Verificação da Requisição”.

Campos de escopo são strings, declaradas como mostrado abaixo; os valores padrão para cada é a string vazia:

Nome do CampoTipo 
HostCHAR(60) 
UserCHAR(16) 
PasswordCHAR(16) 
DbCHAR(64)(CHAR(60) para as tabelas tables_priv e columns_priv)
Table_nameCHAR(60) 
Column_nameCHAR(60) 

Nas tabelas user, db e host, todos campos de privilégios são declarados como ENUM('N','Y') --- cada um pode ter um valor de 'N' ou 'Y' e o valor padrão é 'N'.

Nas tabelas tables_ e columns_priv, os campos de privilégios são declarados como campos SET:

Nome de tabelaNome do campoPossíveis elementos do conjunto
tables_privTable_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
tables_privColumn_priv'Select', 'Insert', 'Update', 'References'
columns_privColumn_priv'Select', 'Insert', 'Update', 'References'

De maneira resumida, o servidor utiliza as tabelas de permissões desta forma:

  • Os campos de escopo da tabela user determinam quando permitir ou aceitar conexões. Para conexões permitidas, qualquer privilégio concedido em uma tabela user indica o privilégio global (superusuário) do usuário. Estes privilégios se aplicam a todos os bancos de dados no servidor.

  • As tabelas db e host são usadas juntas:

    • Os campos de escopo da tabela db determinam quais usuários podem acessar determinados bancos de dados de máquinas determinadas. Os campos de privilégios determinam quais operações são permitidas.

    • A tabela host é usada como uma extensão da tabela db quando você quer que uma certa entrada na tabela db seja aplicada a diversas máquinas. Por exemplo, se você deseja que um usuário esteja apto a usar um banco de dados a partir de diversas máquinas em sua rede, deixe o campo Host vazio no registro da tabela db, então popule a tabela Host com uma entrada para cada uma das máquinas. Este mecanismo é descrito com mais detalhes em Seção 4.3.10, “Controle de Acesso, Estágio 2: Verificação da Requisição”.

  • As tabelas tables_priv e columns_priv são similares à tabela db, porém são mais finas: Elas se aplicam ao nível de tabelas e colunas em vez do nível dos bancos de dados.

Perceba que os privilégios administrativos (RELOAD, SHUTDOWN e etc) são especificados somente na tabela user. Isto ocorre porque operações administrativas são operações no próprio servidor e não são específicas e não específicas dos bancos de dados, portanto não existe razão para listar tais privilégios nas outras tabelas de permissão. De fato, somente a tabela user necessita ser consultada para determinar se você pode ou não realizar uma operação administrativa.

O privilégio FILE também só é especificado na tabela user. Ele não é um privilégio administrativo, mas sua habilidade para ler ou escrever arquivo no servidor é independtende do banco de dados que você está acessando.

O servidor mysqld le o conteúdo das tabelas de permissões uma vez, quando é iniciado. Alterações nas tabelas de permissões tem efeito como indicado em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

Quando você modifica o conteúdo das tabelas de permissões, é uma boa idéia ter certeza que suas alterações configuraram os privilégios da forma desejada. Para ajuda no diagnostico de problemas, veja Seção 4.3.12, “Causas dos Erros de Accesso Negado. Para conselhos sobre asssuntos de segurança, Veja mais informações sobre isto na Seção 4.3.2, “Como Tornar o MySQL Seguro contra Crackers”.

Uma ferramenta de diagnóstico útil é o script mysqlaccess, que Yves Carlier fornece na distribuição MySQL. Chame mysqlaccess com a opção --help para descobrir como ele funciona. Perceba que o mysqlaccess confere o acesso usando somente as tabelas user, db e host. Ele não confere privilégios no nível de tabelas ou colunas.

4.3.7. Privilégios Fornecidos pelo MySQL

Informações sobre privilégios de usuários são armazenados nas tabelas user, db, host, tables_priv e columns_priv no banco de dados chamado mysql. O servidor MySQL lê o conteúdo destas tabelas quando ele inicia e sob as circunstâncias indicadas em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

Os nomes usados neste manual que se referem-se aos privilégios fornecidos pelo MySQL são vistos abaixo juntos com o nome da coluna associada com cada privilégio nas tabelas de permissão e o contexto em que o privilégio se aplica. Informações adicionais sobre o significado de cada privilégio pode ser encontrado em Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

PrivilégioColunaContexto
ALTERAlter_privtabelas
DELETEDelete_privtabelas
INDEXIndex_privtabelas
INSERTInsert_privtabelas
SELECTSelect_privtabelas
UPDATEUpdate_privtabelas
CREATECreate_privbanco de dados, tabelas, ou índices
DROPDrop_privbanco de dados ou tabelas
GRANTGrant_privbanco de dados ou tabelas
REFERENCESReferences_privbanco de dados ou tabelas
CREATE TEMPORARY TABLESCreate_tmp_tabela_privadministração do servidor
EXECUTEExecute_privadministração do servidor
FILEFile_privacessa a arquivos no servidor
LOCK TABLESLock_tabelas_privadministração do servidor
PROCESSProcess_privadministração do servidor
RELOADReload_privadministração do servidor
REPLICATION CLIENTRepl_client_privadministração do servidor
REPLICATION SLAVERepl_slave_privadministração do servidor
SHOW DATABASESShow_db_privadministração do servidor
SHUTDOWNShutdown_privadministração do servidor
SUPERSuper_privadministração do servidor

Os priviláegios SELECT, INSERT, UPDATE e DELETE permitem realizar operações em registros nas tabelas existentes em um banco de dados.

Instruções SELECT necessitam do privilégio select somente se ele precisar recuperar registros de uma tabela. Você pode executar certas instruções SELECT mesmo sem permissão para acessar algum dos bancos de dados no servidor. Por exemplo, você pode usar o cliente mysql como uma simples calculadora:

mysql> SELECT 1+1;
mysql> SELECT PI()*2;

O privilégio INDEX permite a criação ou remoção de índices.

O privilégio ALTER permite utilizar ALTER TABLE.

Os privilégios CREATE e DROP permitem a criação de novos bancos de dados e tabelas, ou a remoção de bancos de dados e tabelas existentes.

Perceba que se for concedido o privilégio DROP no banco de dados mysql para algum usuário, este usuário pode remover o banco de dados no qual os privilégios de acesso do MySQL estão armazenados!

O privilégio GRANT permite a você fornecer a outros usuários os privilégios que você mesmo possui.

O privilégio FILE fornece permissão para ler e escrever arquivos no servidor usando instruções LOAD DATA INFILE e SELECT ... INTO OUTFILE. Qualquer usuário que tenha este privilégio pode ler ou gravar qualquer arquivo que o servidor MySQL possa ler ou escrever. O usuário também pode ler qualquer arquivo no diretório de banco de dados atual. O usuário não pode, no entanto, alterar qualquer arquivo existente.

Os privilégios restantes são usados para operações administrativas, que são realizadas utilizando o programa mysqladmin. A tabela abaixo mostra quais comandos do mysqladmin cada privilégio administrativos permite a execução:

PrivilégioComandos permitidos
RELOADreload, refresh, flush-privileges, flush-hosts, flush-logs, and flush-tables
SHUTDOWNshutdown
PROCESSprocesslist
SUPERkill

O comando reload diz ao servidor para recarregar as tabelas de permissões. O comando refresh descarrega todas as tabelas e abre e fecha os arquivos de log. flush-privileges é um sinônimo para reload. Os outros comandos flush-* realizam funções similares ao refresh mas são mais limitados no escopo e podem ser preferíveis em alguns casos. Por exemplo, se você deseja descarregar apenas os arquivos log, flush-logs é uma melhor escolha do que refresh.

O comando shutdown desliga o servidor.

O comando processlist mostra informações sobre as threads em execução no servidor. O comando kill mata threads no servidor. Você sempre poderá mostrar ou matar suas próprias threads, mas você precisa do privilégio PROCESS para mostrar e privilégio SUPER para matar threads iniciadas por outros usuários. Veja mais informações sobre isto na Seção 4.6.7, “Sintaxe de KILL.

É uma boa idéia em geral conceder privilégios somente para aqueles usuários que necessitem deles, mas você deve ter muito cuidado ao conceder certos privilégios:

  • O privilégio grant permite aos usuários repassarem seus privilégios a outros usuários. Dois usuários com diferentes privilégios e com o privilégio grant conseguem combinar seus privilégios.

  • O privilégio alter pode ser usado para subverter o sistema de privilégios renomeando as tabelas.

  • O privilégio FILE pode ser usado com abuso para ler qualquer arquivo de leitura no servidor em uma tabela de banco de dados, o conteúdo pode ser acessando utilizando SELECT. Isto inclui o conteúdo de todos os bancos de dados hospedados pelo servidor!

  • O privilégio SHUTDOWN pode ser utilizado para negar inteiramente serviços para oturos usuários, terminando o servidor.

  • O privilégio PROCESS pode ser usado para ver o texto das consultas atualmente em execução, incluindo as consultas que configuram ou alteram senhas.

  • Privilégios no banco de dados mysql pode ser utilizado para alterar senhas e outras informações de privilégio de acesso. (Senhas são armazenadas criptografadas, portanto um usuário malicioso não pode simplesmente lê-las para saber as senhas em texto puro). Se fosse possível acessar a coluna password do banco mysql.user, seria possível logar ao servidor MySQL como outro usuário. (Com privilégios suficientes, o mesmo usuário pode trocar a senha por outra diferente.)

Existema algumas coisas que você não pode fazer com o sistem de privilégios do MySQL:

  • Você não pode especificar explicitamente que um determinado usuário deve ter acesso negado. Você não pode explicitamente comparar um usuário e depois recusar sua conexão.

  • Você não pode especificar que um usuário tenha privilégios para criar ou remover tabelas em um banco de dados, mas não possa criar ou remover o banco de dados.

4.3.8. Conectando ao Servidor MySQL

Programas clientes do MySQL geralmente necessitam de parâmetros de conexão quando você precisar acessar um servidor MySQL: a máquina na qual você deseja se conectar, seu nome de usuário e sua senha. Por exemplo, o cliente mysql pode ser iniciado desta forma (argumentos opcionais são colocandos entre ‘[’ e ‘]’):

shell> mysql [-h nome_máquina] [-u nome_usuário] [-psua_senha]

Formas alternativas das opções -h, -u e -p são --host=nome_máquina, --user=nome_usuário e --password=sua_senha. Perceba que não existe espaço entre -p ou --password= e a senha que deve vir a seguir.

NOTA: Especificar a senha na linha de comando não é seguro! Qualquer usuário no seus sistema pode saber sua senha digitando um comando do tipo: ps auxww. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

O mysql utiliza valores padrão para parâmetros de conexão que não são passados pela linha de comando:

  • O nome padrão da máquina (hostname) é localhost.

  • O nome de usuário padrão é o mesmo nome do seu usuário no Unix.

  • Nenhuma senha é fornecida se faltar o parâmetro -p.

Então, para um usuário Unix joe, os seguintes comandos são equivalentes:

shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql

Outros clientes MySQL comportam-se de forma similar.

Em sistemas Unix, você pode especificar valores padrões diferentes para serem usados quendo você faz uma conexão, assim você não precisa digitá-los na linha de comando sempre que chamar o programa cliente. Isto pode ser feito de várias maneiras:

  • Podem ser especificados parâmetros de conexão na seção [client] do arquivo de configuração .my.cnf no seu diretório home. A seção relevante do arquivo deve se parecer com isto:

    [client]
    host=nome_máquina
    user=nome_usuário
    password=senha_usuário
    

    Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Você pode especificar parâmetros de conexão utilizando variáveis de ambiente. O nome de máquina pode ser especificado para o mysql utilizando a variável MYSQL_HOST. O nome do usuário MySQL pode ser especificado utilizando USER (isto é somente para Windows). A senha pode ser especificada utilizando MYSQL_PWD (mas isto não é seguro; veja a próxima seção). See Apêndice F, Variáveis de Ambientes do MySQL.

4.3.9. Controle de Acesso, Estágio 1: Verificação da Conexão

Quando você tenta se conectar a um servidor MySQL, o servidor aceita ou rejeita a conexão baseado na sua identidade e se pode ou não verificar sua identidade fornecendo a senha correta. Senão, o servidor nega o acesso a você completamente. De outra forma, o servidor aceita a conexão, entra no estágio 2 e espera por requisiçiões.

Sua identidade é baseada em duas partes de informação:

  • A máquina de onde está conectando

  • Seu nome de usuário no MySQL

A conferência da identidade é feita utilizando os tres campos de escopo da tabela user (Host, User e Password). O servidor aceita a conexão somente se uma entrada na tabela user coincidir com a máquina, nome de usuário e a senha fornecidos.

Valores dos campos escopo na tabela user podem ser especificados como segue:

  • Um valor Host deve ser um nome de máquina ou um número IP ou 'localhost' para indicar a máquina local.

  • Você pode utilizar os metacaracteres ‘%’ e ‘_’ no campo Host.

  • Um valor Host de '%' coincide com qualquer nome de máquina.

  • Um valor Host em branco significa que o privilégio deve ser adicionado com a entrada na tabela host que coincide com o nome de máquina fornecido. Você pode encontrar mais informações sobre isto no próximo capítulo.

  • Como no MySQL Versão 3.23, para valores Host especificados como números IP, você pode especificar uma máscara de rede indicando quantos bits de endereço serão usados para o número da rede. Por exemplo:

    mysql> GRANT ALL PRIVILEGES ON db.*
        -> TO david@'192.58.197.0/255.255.255.0';
    

    Isto permitirá que todos a se conectarem a partir de determinado IP cuja condição seguinte seja verdadeira:

    IP_usuário & máscara_rede = ip_maquina.
    

    No exemplo acima todos IPs no Intervalo 192.58.197.0 - 192.58.197.255 podem se conectar ao servidor MySQL.

  • Metacaracteres não são permitidos no campo User, mas você pode especificar um valor em branco, que combina com qualquer nome. Se a entrada na tabela user que casa com uma nova conexão tem o nome do usuário em branco, o usuário é considerado como um usuário anônimo (o usuário sem nome), em vez do nome que o cliente especificou. Isto significa que um nome de usuário em branco é usado para todos as verificações de acessos durante a conexão. (Isto é, durante o estágio 2).

  • O campo Password pode ficar em branco. O que não significa que qualquer senha possa ser usada, significa que o usuário deve conectar sem especificar uma senha.

Valores de Password que não estão em branco são apresentados como senhas criptografadas. O MySQL não armazena senhas na forma de texto puro para qualquer um ver. Em vez disso, a senha fornecida por um usuário que está tentando se conectar é criptografada (utilizando a função PASSWORD()). A senha criptografada é então usada quando o cliente/servidor estiver conferindo se a senha é correta (Isto é feito sem a senha criptografada sempre trafegando sobre a conexão.) Perceba que do ponto de vista do MySQL a senha criptografada é a senha REAL, portanto você não deve passá-la para ninguém! Em particular, não forneça a usuários normais acesso de leitura para as tabelas no banco de dados mysql! A partir da versão 4.1, o MySQL emprega um mecanismo de senha e login diferente que é seguro mesmo se fizerem um sniff nos pacotes TCP/IP e/ou o banco de dados mysql é capturado.

Os exemplos abaixo mostram várias combinações de valores de Host e User nos registros da tabela user aplicando a novas conexões:

Valor em hostValor em userConexões casadas com o registro
'thomas.loc.gov'''Qualquer usuário, conectando de thomas.loc.gov
'%''fred'fred, conectando a partir de qualquer máquina
'%'''Qualquer usuário, conectando a partir de qualquer máquina
'%.loc.gov''fred'fred, conectando de qualquer máquina do domínio loc.gov
'x.y.%''fred'fred, conectando de x.y.net, x.y.com,x.y.edu, etc. (Isto provavelmente não é útil)
'144.155.166.177''fred'fred, conectando da máquina com endereço IP 144.155.166.177
'144.155.166.%''fred'fred, conectando de qualquer máquina na subrede de classe C 144.155.166
'144.155.166.0/255.255.255.0''fred'o mesmo que no exemplo anterior

Como você pode usar valores coringas de IP no campo Host (por exemplo, '144.155.166.%' combina com todas máquinas em uma subrede), existe a possibilidade que alguém possa tentar explorar esta capacidade nomeando a máquina como 144.155.166.algumlugar.com. Para evitar tais tentativas, O MySQL desabilita a combinação com nomes de máquina que iniciam com dígitos e um ponto. Portanto se você possui uma máquina nomeada como 1.2.foo.com, este nome nunca irá combinar com uma coluna Host das tabelas de permissões. Somente um número IP pode combinar com um valor coringa de IP.

Uma conexão de entrada pode coincidir com mais de uma entrada na tabela user. Por exemplo, uma conexão a partir de thomas.loc.gov pelo usuário fred pode combinar com diversas das entradas vistas na tabela anterior. Como o servidor escolhe qual entrada usar se mais de uma coincide? O servidor resolve esta questão ordenando a tabela user no tempo de inicialização, depois procura pelas entradas na ordem da classificação quando um usuário tenta se conectar. A primeira entrada que coincidir é a que será usada.

A ordenação da tabela user funciona da forma mostrada a seguir. Suponha que a tabela user se pareça com isto:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

Quando o servidor lê a tabela, ele ordena as entradas com os valores mais específicos de Host primeiro ('%' na coluna Host significa ``qualquer máquina'' e é menos específico). Entradas com o mesmo valor Host são ordenadas com os valores mais específicos de User primeiro (um valor em branco na coluna User significa ``qualquer usuário'' e é menos específico). O resultado da tabela user ordenada ficaria assim:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

Quando uma conexão é iniciada, o servidor procura entre as entradas ordenadas e utiliza a primeira entrada coincidente. Para uma conexão a partir de localhost feito por jeffrey, as entradas com 'localhost' na coluna Host coincide primeiro. Destas, a entrada com o nome do usuário em branco combina com o nome da máquina e o nome do usuário. (A entrada '%'/'jeffrey' também casaria, mas ela não é a primeira entrada coincidente na tabela.

Aqui está outro exemplo. Suponha que a tabela user fosse assim:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-

A tabela ordenada pareceria com isto:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

Uma conexão a partir de thomas.loc.gov feita por jeffrey coincide com a primeira entrada, no entanto, uma conexão de whitehouse.gov fetia por jeffrey coincidiria com a segunda entrada na tabela.

Um erro comum é pensar que para um determinado usuário, todas as entradas que citam explicitamente este usuário serão usadas primeiro quando o usuário tentar encontrar uma combinação para a conexão. Simplesmente isto não é verdade. O exemplo anterior ilustra isto, onde uma conexão de thomas.loc.gov feita por jeffrey combina primeiro não com a entrada contendo 'jeffrey' no valor do campo user, mas sim pela entrada sem o nome de usuário!

Se você tiver problemas conectando ao servidor, imprima a tabela user e ordene-a na manualmente para ver onde se deu o primeiro coincidência de valores. Se a conexão obtiver sucesso mas os seus privilégios não são os esperados, você pode usar a função CURRENT_USER() (nova na versão 4.0.6) para ver com qual combinação usuário/máquina a sua conexão coincide. Veja mais informações sobre isto na Seção 6.3.6.2, “Funções Diversas”.

4.3.10. Controle de Acesso, Estágio 2: Verificação da Requisição

Uma vez estabelecida uma conexão, o servidor entra no 2o estágio. Para cada requisição que vem na conexão, o servidor verifica se você tem privilégios suficientes para realizá-la, baseado nas operações que você deseja fazer. É aqui que os campos de concessões nas tabelas de permissões entram em ação. Estes privilégios pode vir de qualquer uma das tabelas user, db, host, tables_priv ou columns_priv. As tabelas de permissões são manipuladas com os comandos GRANT e REVOKE. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE. (Você pode achar útil fazer referencia a Seção 4.3.6, “Como o Sistema de Privilégios Funciona”, que lista os campos presentes em cada uma das tabelas de permissões.)

A tabela user concede privilégios que são especificados por você em uma base global e que se aplicam sem importar qual é o banco de dados atual. Por exemplo, se a tabela user concede a alguém o privilégio delete, este usuário pode apagar linhas de qualquer banco de dados no servidor! Em outras palavras, privilégios na tabela user são privilégios de superusuário. O correto é conceder privilégios na tabela user apenas para superusuários tais como os administradores de servidor ou de bancos de dados. Para outros usuários, você deve deixar os privilégios na tabela user configurados para 'N' e conceder privilégios somente em bancos de dados específicos, utilizando as tabelas db e host.

As tabelas db e host concedem privilégios para bancos de dados específicos. Valores nos campos de escopo podem ser especificados como a seguir:

  • Os metacaracteres ‘%’ e ‘_’ podem ser usados nos campos Host e Db de ambas tabelas. Se você deseja usar um caracter ‘_’ como parte de um nome de banco de dados, especifique-o como '\_' no comando GRANT.

  • O valor '%' em Host na tabela db significa ``qualquer máquina.'' Um valor em branco em Host na tabela db significa ``consulte a tabela host para informação adicional.''

  • O valor '%' ou em branco no campo Host na tabela host significa ``qualquer máquina.''

  • O valor '%' ou em branco no campo Db de ambas as tabelas significa ``qualquer banco de dados.''

  • O valor em branco no campo User em ambas tabelas coincide com o usuário anônimo.

As tabelas db e host são lidas e ordenadas quando o servidor inicia (ao mesmo tempo que ele lê a tabela user). A tabela db é ordenada nos campos de escopo Host, Db e User e a tabela host é ordenada nos campos de escopo Host e Db. Assim como na tabela user, a ordenação coloca os valores mais específicos no início e os menos específicos por último, e quando o servidor procura por entradas coincidentes, ele usa a primeira combinação que encontrar.

As tabelas tables_priv e columns_priv concedem privilégios específicos para tabelas e campos. Valores nos campos escopo podem ser especificados como a seguir:

  • Os meta caracteres ‘%’ e ‘_’ podem ser usados no campo Host de ambas tabelas.

  • O valor '%' ou em branco no campo Host em ambas tabelas significam ``qualquer máquina''

  • Os campos Db, Table_name e Column_name não podem conter meta caracteres ou serem brancos em ambas tabelas.

As tabelas tables_priv e columns_priv são ordenadas nos campos Host, DB e User. Isto é parecido com a ordenação da tabela db, no entanto, a ordenação é mais simples porque somente o campo Host pode conter meta caracteres.

O processo de verificação da requisição é descrito abaixo. (Se você já está familiarizado com o código de verificação de acesso, você irá perceber que a descrição aqui é um pouco diferente do algorítimo usado no código. A descrição é equivalente ao que o código realmente faz; ele só é diferente para tornar a explicação mais simples.)

Para requisições administrativas (SHUTDOWN, RELOAD, etc.), o servidor confere somente a entrada da tabela user, porque ela é a única tabela que especifica privilégios administrativos. O acesso é concedido se o registro permitir a operação requisitada ou negado caso o contrário. Por exemplo, se você deseja executar mysqladmin shutdown mas a entrada em sua tabela user não lhe concede o privilégio SHUTDOWN, o acesso é negado mesmo sem consultar as tabelas db ou host. (elas não contém o campo Shutdown_priv, portanto não existe esta necessidade.)

Para requisições relacionadas aos bancos de dados (insert, udpdate, etc.), o servidor primeiro confere os privilégios globais do usuário consultando as entradas da tabela user. Se a entrada permitir a operação requisitada, o acesso é concedido. Se os privilégios globais na tabela user são insuficientes, o servidor determina os privilégios específicos de banco de dados para o usuário consultando as tabelas db e host:

  1. O servidor consulta a tabela db por uma combinação nos campos Host, Db e User. Os campos Host e User são comparados com o nome da máquina e o nome do usuário que faz a requisição. O campo Db é comparado com o banco de dados que o usuário deseja acessar. Se não existir entradas coincidentes para o Host e User, o acesso é negado.

  2. Se existir uma combincação com a entrada da tabela db e seu campo Host não estiver em branco, aquela entrada define os privilégios especificos do banco de dados do usuario.

  3. Se o registro coincidente da tabela db tiver o campo Host em branco, significa que a tabela host enumera quais máquinas são permitidas acessar o banco de dados. Neste caso, uma consulta adicional é feita na tabela host para encontrar uma valores coincidentes nos campos Host e Db. Se nenhuma entrada na tabela host coincide, o acesso é negado. Se existir uma coincidência, os privilégios específicos de bancos de dados para o usuário são computados como a interseção (não a união!) dos privilégios nas entradas das tabelas db e host, isto é, os privilégios que são 'Y' em ambas entradas. (Desta forma você pode conceder privilégios gerais em entradas na tabela db e então restringi-los em uma base de máquina a máquina utilizando as entradas da tabela host.)

Depois de determinar os privilégios específicos do banco de dados concedido pelas entradas nas tabelas db e host, o servidor os adiciona aos privilégios globais concedidos pela tabela user. Se o resultado permitir a operação requisitada, o acesso será concedido. De outra forma, o servidor consulta os privilégios de tabelas e campos do usuario nas tabelas tables_priv e columns_priv e os adiciona aos privilégios do usuário. O acesso será permitido ou negado baseado no resultado.

Expresso em termos booleanos, a descrição precedente de como os privilégios de um usuário são calculados podem ser resumido assim:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

Ele pode não ser aparente porque, se os privilégios da entrada global de user são inicialmente insuficientes para a operação requisitada, o servidor adiciona estes privilégios mais tarde aos privilégios específicos de banco de dados, tabelas e colunas. A razão é que uma requisição pode exigir mais que um tipo de privilégio. Por exemplo, se você executar uma instrução INSERT ... SELECT, você precisa dos privilégios INSERT e SELECT. Seu privilégio pode ser tal que a entrada da tabela user concede um privilégio e a entrada da tabela db concede o outro. Neste caso, você tem os privilégios necessários para realizar a requisição, mas o servidor não pode obtê-los de ambas as tabelas por si próprio; os privilégios concedidos pelas entradas em ambas as tabelas de ser combinados.

A tabela host pode ser usada para manter uma lista dos servidores seguros.

Na Tcx, a tabela host contém uma lista de todas as máquina na rede local. A elas são concedidos todos os privilégios.

Você pode também usar a tabela host para indicar máquinas que não são seguras. Suponha que você tenha uma máquina public.your.domain que está localizada em uma área pública que você não considera segura. Você pode permitir o acesso a todas as máquinas de sua rede exceto a esta máquina usando entradas na tabela host desta forma:

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (todos os privilégios configurados para 'N')
| %.your.domain      | %  | ... (todos os privilégios configurados para 'Y')
+--------------------+----+-

Naturalmente, você deve sempre testar suas entradas nas tabelas de permissões (por exemplo, usar o mysqlaccess para ter certeza que os privilégios de acesso estão atualmente configurados da forma que você imagina.

4.3.11. Hashing de Senhas no MySQL 4.1

As contas de usuários do MySQL estão lisatadas na tabela user do banco de dados mysql. Para cada conta do MySQL é definida uma senha, no entanto o que está armazenado na coluna Password da tabela user não seja uma versão da senha em texto puro, mas um valor hash computado para ela. Valores hash de senha são calculados pela função PASSWORD().

O MySQL usa senhas em duas fases da comunicação cliente/servidor:

  • Primeiro, quando um cliente tenta se conectar ao servidor, existe uma etapa de autenticação inicial na qual o cliente deve apresentar uma senha que combina com o valor hash armazenado na tabela de usuários para a conta que aquele cliente deseja usar.

  • Em segundo lugar, depois que o cliente conecta, ele pode configurar ou alterar o hash da senha para as contas listadas na tabela de usuário (se ele tiver privilégios suficientes).O cliente pode fazer isto usando a função PASSWORD() para gerar uma hash da senha ou usando as instruções GRANT ou SET PASSWORD.

Em outra palavras, o servidor usa valores hash durante a autenticação quando um cliente tenta a primeira conexão. O servidor gera os valores hash se um cliente conectado chama a função PASSWORD() ou usa uma instrução GRANT ou SET PASSWORD para definir ou alterar uma senha.

O mecanismo de hash da senha foi atualizado no MySQL 4.1 para fornecer melhor segurança e reduzir os riscos de senhas serem roubadas. No entanto, Este novo mecanismo só é interpretado pelo servidor 4.1 e clientes 4.1, que podem resultar em alguns problemas de compatibilidade. Um cliente 4.1 pode conectar a um servidor pre-4.1, porque o cliente entende tanto o antigo quanto o novo mecanismo hash de senha. No entanto, um cliente pre-4.1 que tentar se conectar a um servidor 4.1 pode encontrar dificuldades. Por exemplo, um cliente mysql 4.0 que tentar se conectar a um servidor 4.1 pode falhar com a seguinte mensagem de erro:

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

A seguinte discussão descreve a diferença entre o antigo e o novo mecanismo de senha, e o que você deve fazer se você atualizar o seu servidor para a versão 4.1 mas precizar de manter compatibilidade com clientes pre-4.1.

Nota: Esta discussão contrasta no comportamento da versão 4.1 com o comportamento da pre-4.1, mas o da versão 4.1 descrito aqui começa relamente na versão 4.1.1. O MySQL é uma distribuição ``disferente'' porque ela tem um mecanismo um pouco diferente daquele implementado na 4.1.1 e acima. Diferenças entre a versão 4.1.0 e as versões mais recentes são descritas posteriormente.

Antes do MySQL 4.1, o hash de senha calculado pela função PASSWORD() tem tamanho de 16 bytes. Este hash se parece com:

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e   |
+--------------------+

A coluna Password da tabela user (na qual estes hashes são armazenados) também têm 16 bytes de tamanho antes do MySQL 4.1.

A partir do MySQL 4.1, a função PASSWORD() foi modificada para produzir um valor hash de 41 bytes.

mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass')                            |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+

De acordo com o mostrado, a coluna Password na tabela user também deve ter 41 bytes para armazeanar estes valores.

  • Se você realiza uma nova instalação do MySQL 4.1, a coluna Password será convertida para o tamanho de 41 bytes automaticamente.

  • Se você atualizar uma instalação mais antiga para a versão 4.1, você executar o script mysql_fix_privilege_tables para atualizar o tamanho da coluna Password de 16 para 41 bytes. (O script não altera valores de senhas existentes, que continuam com 16 bytes.)

Uma coluna Password mais larga pode armazenar hashes de senha no formato novo e no antigo. O formato de qualquer valor de hash de senha dado podeser determinado de dois modos:

  • A diferença óbvia é o tamanho (16 bytes versus 41 bytes)

  • A segunda diferença é que os hashes de senha no novo formato sempre começam com um caracter ‘*’, que as senhas no formato antigo nunca faziam.

O formato maior do hash de senha tetm melhores propriedades criptográficas, e a autenticação do cliente baseada em hashs mais longos é mais segura que aquela baseada nos antigos hashes menores.

A diferença entre os hashs de senhas menores e maiores são relevantes em como o servidor usa as senhas durante a autenticação e como ela gera hash de senhas para clientes conectados que realizam operações de alteração de senha.

O modo no qual o servidor usa o hash de senha durante a autenticação é afetada pela largura da coluna Password:

  • Se a coluna não for larga, apenas a autenticação de hash curto é usada.

  • Se a coluna é larga, ela pode guardar tanto hash curtas quanto hashs longas, e o servidor pode usar ambos os formatos:

    • Clientes pre-4.1 podem conectar, mas como els só conhecem o mecanismo hash antigo, eles só podem se conectar pelas contas com hashes curtos.

    • Clientes 4.1 podem autenticar contas com hashes longos ou curtos.

Para contas com o hash curto, o processo de autenticação é na verdade um pouco mais seguro para clientes 4.1 que para clientes mais antigos. Em termos de segurança, o gradiente do menos para o mais seguro é:

  • Clientes pre-4.1 autenticando em contas com hash de senha curto

  • Clientes 4.1 autenticando em contas com hash de senha curto

  • Clientes 4.1 autenticando em contas com hash de senha longo

O modo no qual o servidor gera hashes de senhas para clientes conectados é afetado pela largura da coluna Password e pela opção --old-passwords. Um servidor 4.1 gera hashes longos apenas se certas condicões forem encontradas: A coluna Password deve ser grande o suficiente para armazenar valores longos e a opção --old-passwords não deve ser dada. Estas condições se aplicam da seguinte forma:

  • A coluna Password deve ser grande o suficiente para armazenar hashes longos (41 bytes). Se a coluna não foi atualizada e ainda tem a largura de 16 bytes (antes da 4.1), o servidor avisa que o hash não pode caber nela e gera apenas hashes curtos quando um cliente realiza a operação de troca de senha usando PASSWORD(), GRANT, ou SET PASSWORD. (Este comportamento ocoree se você tiver atualizado para a versão 4.1 mas não executou o script mysql_fix_privilege_tables para aumentar a coluna Password.)

  • Se a coluna Password for larga, ela poderá aramazenar tanto os hashes de senha curtos quanto os longos. Neste caso, PASSWORD(), GRANT, e SET PASSWORD irão gerar hashes longos a menos que o servidor tenha sido iniciado com a opção --old-passwords. Esta opção força o servidor a gerar hashes de senha curtos.

O propósito da opção --old-passwords é permitir que você mantenha compatibilidade com clientes com versões anteriores à 4.1 sob circunstâncias nas quais os servidores gerariam hashes de senha longos. Ele não afeta a autenticação (clientes 4.1 podem ainda usar contas que possuem hash de senha longo), mas ele não previne a criaçõa de um hash de senha longo na tabela user como resultado de uma operação de troca de senha. Onde isto ocorrer, a conta não mais poderá ser usada por clientes pré-4.1. Se a opção --old-passwords, o seguinte cenário é possível:

  • Um cliente antigo conecta a uma conta que têm um hash de senha curto.

  • O cliente altera a senha das contas. Sem --old-passwords, isto resulta na conta que têm um hash de senha longo.

  • A próxima vez que o cliente antigo tentar se conectar à conta, ele não conseguirá, porque a conta agora exige o novo mecanismo de hash durante a autenticação. (Uma vez que uma conta tem um hash de senha longo na tabela de usuário, apenas os clientes 4.1 poderão ser autenticados, porque clientes de versões anteriores a 4.1 não entendem o hash longo.)

Este cenário mostra que é perigoso executar um servidor 4.1 sem usar a opção --old-passwords, operações de alteração de senha não irão gerar hashes de senha longos e assim não faz com que as contas se tornem inacessíveis para clientes mais antigos. (Estes clientes não podem bloquear eles mesmos inadivertidamente alterando suas senhas e ficando com um hash de senha longo.

A desvantagem da opção --old-passwords é que qualquer senha que você criar ou alterar usará hashes curtos, mesmo para clientes 4.1. Assim, você perde a segurança adicional fornecida pelos hashes de senha longos. Se você quiser criar uma conta qye tenha um hash longo (por exemplom parr uso pelos clientes 4.1), você deve fazê-lo enquanto executa o servidor sem a opção --old-passwords.

Os seguintes cenários são possíveis para executar um servidor 4.1:

Cenario 1) Coluna Password menor na tabela de usuários

  • Apenas hashes curtos podem ser armazenados na coluna Password.

  • O servidor usa apenas hasghes curtos durante a autenticação do cliente.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT ou SET PASSWORD usa hashes curtos exclusivamebnte. Qualquer alteração a senha de uma conta faz com que a conta tenha um hash de senha curto.

  • A opção --old-passwords pode ser usada mas é superflua porque com uma coluna Password menor, o servidor irá gerar hashes de senha curtos de qualquer forma.

Cenário 2) Colunas Password longas; servidor não iniciado com a opção --old-passwords

  • Hashes de senha longos e curtos podem ser armazenados na coluna Password.

  • Clientes 4.1 podem autenticar contas com hashes curtos ou longos.

  • Clientes anteioriores ao 4.1 só podem autenticar contas com hash curto.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT, ou SET PASSWORD usam hashes longos exclusivamente. Qualquer mudança na senha de uma conta fará com que ela possua um hash de senha longo.

  • OLD_PASSWORD() pode ser usado para gerar explicitamente um hash curto. Por exemplo, para atribuir uma senha curta a uma conta, use UPDATE da seguinte forma:

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

Como indicado anteriormente, o perigoso neste cenário é que é possível que contas com hashes de senha curtos se tornem inacessíveis para cliente anteriores ao 4.1. Qualquer alteração a senha de uma conta feita via GRANT, SET PASSWORD, ou PASSWORD() faz com que a conta tenha um hash de senha longo, e a partir deste ponto, nenhum cliente anterior ao 4.1 poderá autenticar esta conta até que ele seja atualizado para a versão 4.1.

Cenário 3) Coluna Password longa; servidor iniciado com a opção --old-passwords

  • Hashes longos e curtos podem ser armazenados na coluna Password.

  • Clientes 4.1 podem autenticar contas que tenham hashes longos ou curtos (mas note que é possível criar hashes longos apenas quando o servidor é iniciado sem --old-passwords).

  • Clientes anteriores ao 4.1 podem autentticar apenas contas com hashes curtos.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT, ou SET PASSWORD usa hashes curtos exclusivamente. Qualquer alteração em uma senha de conta faz com que a conta tenha um hash de senha curto.

Neste cenário, você não pode criar contas que tenham hashes de senha longo, porque --old-passwords previne a criação de hashes longos. Também, se você criar uma conta com um hash longo antes de usar a opção --old-passwords, alterar a senha da conta enquanto --old-passwords está funcionando faz com que seja dada a conta uma sena curta, fazendo com que ela perca os benefícios de segurança de um hash longo.

As disvantagens para este cenário pode ser resumido como a seguir:

Cenário 1) Você não pode tirar vantagem do hash longo que fornece mais autenticação segura.

Cenário 2) Contas com hashes curtos tornam clientes anteriores ao 4.1 inacessíveis se você alterar a senha deles sem usar OLD_PASSWORD() explicitamente.

Cenário 3) --old-passwords evita que as contas com hashes curtos se tornem inacessíveis, mas operações de alteração de senhas fazem com que as contas com hashes longos seja revertida para hashes curtos, e você não pode alterá-las de volta para hashes longos enquanto --old-passwords está em efeito.

Implicações de Alteração de Hashes de Senha para Aplicativos

Um atualização para o MySQL 4.1 para trazer problemas de compatibilidade para aplicações que usam PASSWORD() para gerar senha para os seus próprios propósitos. (Aplicativos não devem fazer isto, porque PASSWORD() deve ser usado paenas para gerenciar contas do MySQL. Mas algumas aplicações usam PASSWORD() para seus próprios propósitos.) Se você atualizar para o MySQL 4.1 e executar o servidor sob condições onde ele gera hashes de senha longo, uma aplicação que usa PASSWORD() para as suas próprias senhas irá falhar. O curso de ação recomendado é modificar o aplicativo para usar outras funções como SHA1() ou MD5() para produzir valores de hash. Se isto não for possível você pode utilizar a função OLD_PASSWORD(), que é fornecida para gerar hashes curtos no formato antigo. (Mas note que OLD_PASSWORD() pode vir a não ser mais suportado.)

Se o servidor está rodando sob circuntâncias onde ele gera hashes de senha curtos, OLD_PASSWORD() está disponível mas é equivalente a PASSWORD().

Hash de senhas no MySQL 4.1.0 difere do hash no 4.1.1 e acima. As diferenças da versão 4.1.0 são as seguintes:

  • Hashes de senhas de 45 bytes em vez de 41 bytes.

  • A função PASSWORD() não é repetitível. Isto é, com um dado argumento X, successivas chamadas a PASSWORD(X) geram diferentes resultados.

4.3.12. Causas dos Erros de Accesso Negado

Se você encontrar erros de Accesso Negado (Access denied) quando tentar conectar-se ao servidor MySQL, a lista abaixo indica alguns caminhos que você pode seguir para corrigir o problema:

  • Depois de instalar o MySQL, você executou o script mysql_install_db para configurar o conteúdo inicial das tabelas de permissões ? Se não, faça isto. Veja mais informações sobre isto na Seção 4.4.4, “Configurando os Privilégios Iniciais do MySQL”. Testes os privilégios iniciais executando este comando:

    shell> mysql -u root test
    

    O servidor deve deixar você conectar sem erros. Você também deve assegurar que exista o arquivo user.MYD no diretório do banco de dados do MySQL. Normalmente ele fica em CAMINHO/var/mysql/user.MYD. onde CAMINHO é o caminho para a raiz da instalação do MySQL.

  • Depois de terminar uma instalação, você deve conectar ao servidor e configurar seus usuários e suas permissões de acesso.

    shell> mysql -u root mysql
    

    O servidor deve permitir a conexão pois o usuário root MySQL vem inicialmente configurado sem senha. Isto também é um risco de segurança, portanto configurar a senha do usuário root é algo que deve ser feito enquanto você configura os outros usuários do MySQL.

    Se você tentar se conectar como root e obter este erro:

    Access denied for user: '@unknown' to database mysql
    

    isto significa que você não possui um registro na tabela user com o valor 'root' no campo User e que o mysqld não pode rsolver o nome de máquina do cliente. Neste caso, você deve reiniciar o servidor com a opção --skip-grant-tables e editar seu arquivo /etc/hosts ou o \Windows\hosts para adicionar uma entrada para sua máquina.

  • Se você obter um erro como o seguinte:

    shell> mysqladmin -u root -pxxxx ver
    Access denied for user: 'root@localhost' (Using password: YES)
    

    Significa que você está usando uma senha incorreta. See Seção 4.4.8, “Configurando Senhas”.

    Se você esqueceu a senha de root, você pode reiniciar o mysqld com a opção --skip-grant-tables para alterar a senha. Veja mais informações sobre isto na Seção A.4.2, “Como Recuperar uma Senha de Root Esquecida”.

    Se você obter o erro acima mesmo se não tiver configurado uma senha, significa que você tem algum arquivo my.ini configurado para passar alguma senha incorreta. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf. Você pode evitar o uso de arquivos de opções com a opção --no-defaults, como a seguir:

    shell> mysqladmin --no-defaults -u root ver
    
  • Se você atualizou uma instalação existente do MySQL de um versão anterior à versão 3.22.11 para a Versão 3.22.11 ou posterior, você executou o script mysql_fix_privilege_tabels ? Se não faça isto. A estrutura das tabelas de permissões alteraram com a Versão 3.22.11 do MySQL quando a instrução GRANT se tornou funcional. See Seção 2.5.6, “Atualizando a Tabela de Permissões”.

  • Se os seus privilégios parecerem alterados no meio de uma sessão, pode ser que o superusuário os alterou. A recarga das tabelas de permissões afeta novas conexões dos clientes, mas ela também afeta conexões existentes como indicado em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

  • Se você não consegue fazer a sua senha funcionar, lembre-se que você deve usar a função PASSWORD() se você configurar a senha com instruções INSERT, UPDATE ou SET PASSWORD. A função PASSWORD() é desnecessária se você especificar a senha usando a instrução GRANT ... IDENTIFIED BY ou o comando mysqladmin password. See Seção 4.4.8, “Configurando Senhas”.

  • localhost é um sinônimo para seu nome de máquina local, e é também a máquina padrão em que clientes tentam se conectar se você não especificar explicitamente o nome da máquina. Entretanto, conexões para localhost não funcionam se você estiver executando em um sistema que utilize MIT-pthreads (conexões localhost são feitas utilizando sockets Unix, que não são suportadas pelas MIT-pthreads). Para evitar este problema nestes sistemas, você deve utilizar a opção --host para nomear explicitamente o servidor. Isto fará uma conexão TCP/IP ao servidor myssqld. Neste caso, você deve ter seu nome de máquina real nos registros da tabela user no servidor. (Isto é verdadeiro mesmo se você estiver executando um programa cliente na mesma máquina que o servidor.)

  • Se você obter o erro Access denied quando tentando conectar ao banco de dados com mysql -u nome_usuário _nome_bd, você pode ter um problema com a tabela user. Verifique isto executando mysql -u root mysql e usando esta sentença SQL:

    mysql> SELECT * FROM user;
    

    O resultado deve incluir uma entrada com as colunas Host e User combinando com o nome de seu computador e seu nome de usuário no MySQL.

  • A mensagem de erro Access denied irá dizer a você com qual usuário você está tentando se logar, a máquina que está tentando conectar e se você está utilizando uma senha ou não. Normalmente, você deve ter um registro na tabela user que combine exatamente com o nome de máquina e o nome de usuário que forem fornecidos na mensagem de erro. Por exemplo, se você obter uma mensagem de erro que contenha Using password: NO, isto significa que você está tentando se conectar sem uma senha.

  • Se você obter o seguinte erro quando estiver tentando conectar de uma máquina diferente da que o servidor MySQL estiver executando, então não deve existir um registro na tabela user que combine com esta máquina:

    Host ... is not allowed to connect to this MySQL server
    

    Você pode corrigir isto utilizando a ferramenta de linha de comando mysql (no servidor!) para adicionar um registro à tabela user, db ou host para coincidir com o usuário e nome de máquina de onde você está tentando conectar, depois execute o comando mysqladmin flush-privileges. Se você não estiver executando o MySQL Versão 3.22 e você não sabe o número IP ou o nome da máquina da qual estiver conectando, você deve colocar uma entrada com o valor '%' na coluna Host da tabela user e reiniciar o mysqld com a opção --log na máquina onde é executado o servidor. Depois tente conectar a partir da máquina cliente, a informação no log do MySQL irá indicar como você está realmente conectando. (Então troque o '%' na tabela user com o nome da máquina mostrado pelo log. De outra forma você teria um sistema que seria inseguro.)

    Outra razão para este erro no Linux pode ser porque você está utilizando uma versão binária do MySQL que é compilada com uma versão diferente da glibc que você está usando. Neste caso você deve atualizar seu SO/Glibc ou fazer o download da versão fonte do MySQL e compilá-la. Um RPM fonte é, normalmente, fácil de compilar e instalar, logo, isto não é um grande problema.

  • Se você obter uma mensagem de erro onde o nome da máquina não é exibido ou, no lugar do nome da máquina existir um IP, mesmo se você tenta a conexão com um nome de máquina:

    shell> mysqladmin -u root -pxxxx -h some-hostname ver
    Access denied for user: 'root@' (Using password: YES)
    

    Isto significa que o MySQL obteve algum erro quando tentava resolver o IP para um nome de maquina. Neste caso você pode executar mysqladmin flush-hosts para zerar o cache DNS interno. Veja mais informações sobre isto na Seção 5.5.5, “Como o MySQL Utiliza o DNS”.

    Algumas soluções permanentes são:

    • Tente descobrir o que está errado com seu servidor DNS e corrija os erros.

    • Especifique números IPs no lugar de nomes nas tabelas de privilégios do MySQL.

    • Inicie o mysqld com --skip-name-resolve.

    • Inicie o mysqld com --skip-host-cache.

    • Conecte à localhost se você estiver executando o servidor e o cliente na mesma máquina.

    • Coloque os nomes das máquinas clientes em /etc/hosts.

  • Se mysql -u root test funciona mas mysql -h nome_servidor -u root test resultar em Access denied, então você pode não ter o nome correto para a sua máquina na tabela user. Um problema comum é quando o valor de Host na entrada da tabela user especifica um nome de máquina não qualificado, mas as rotinas de resolução de nomes de seu sistema retornam um nome qualificado completo do domínio (ou vice-versa). Por exemplo, se você tem uma entrada com o nome 'tcx' na tabela user, mas seu DNS diz ao MySQL que o nome da máquina é 'tcx.subnet.se', a entrada não irá funcionar. Tente adicionar um registro à tabela user que contenha o número IP de sua máquina como o valor da coluna Host. (Uma alternativa, seria adicionar um registro à tabela user com o valor de Host contendo um metacaracter, por exemplo, 'tcx.%'. Entretanto, o uso de nomes de máquinas terminando com ‘%’ é inseguro e não é recomendado!)

  • Se mysql -u nome_usuário test funciona mas mysql -u nome_usuário outro_bd não funconar, você não possui uma entrada para outro_bd listado na tabela db.

  • Se mysql -u nome_usuário nome_bd funciona quando executado no próprio servidor, mas mysql -u nome_máquina -u nome_usuário nome_bd não funciona quando executado em outra máquina cliente, você não possui o nome da máquina cliente listado na tabela user ou na tabela db.

  • Se você não estiver entendendo porque obtem Access denied, remova da tabela user todas as entradas da coluna Host que contenham meta caracteres (entradas que contenham ‘$’ ou ‘_’). Um erro muito comum é inserir uma nova entrada com Host='%' e User='algum usuário', pensando que isto irá permitir a você especificar localhost para conectar da mesma máquina. A razão disto não funcionar é que os privilégios padrões incluem uma entrada com Host='localhost' e User=''. Como esta entrada tem o valor 'localhost' em Host que é mais específica que '%', ela é usada no lugar da nova entrada quando se conectar de localhost! O procedimento correto é inserir uma segunda entrada com Host='localhost' e User='algum_usuário', ou remover a entrada com Host='localhost' e User= ''.

  • Se você obter o seguinte erro, você pode ter um problema com a tabela db ou a tabela host:

    Access to database denied
    

    Se a entrada selecionada da tabela db tiver um valor vazio na coluna Host, tenha certeza que exista uma ou mais entradas correspondentes na tabela host especificando quais máquinas aplicam-se à tabela db.

    Se você obter o erro quando estiver utilizando comandos SQL SELECT ... INTO OUTFILE ou LOAD DATA INFILE, a entrada na tabela user provavelmente não tem o privilégio file habilitado.

  • Lembre-se que programas clientes irão usar parâmetros de conexões especificados em arquivos de configuração ou variáveis ambientais. See Apêndice F, Variáveis de Ambientes do MySQL. Se parecer que algum cliente está enviando parâmetros errados para a conexão e você não os especificou na linha de comando, verifique seu ambiente e o arquivo .my.cnf no seu diretório home. Você pode também conferir os arquivos de configurações do servidor MySQL, apesar de não ser interessante gravar configurações de cliente nestes arquivos. See Seção 4.1.2, “Arquivo de Opções my.cnf. Se você obter a mensagem de acesso negado (Access denied) quando estiver executando um cliente sem opções, tenha certeza que você não especificou uma senha antiga em nenhum de seus arquivos de opções! See Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Se você fizer alterações para as tabelas de permissões diretamente (utilizando uma instrução INSERT ou UPDATE) e suas alterações parecem ser ignoradas, lembre que você deve usar uma instrução FLUSH PRIVILEGES ou executar um comando mysqladmin flush-privileges para o servidor ler novamente as tabelas com os privilégios. De outra forma, suas alterações não farão efeito até que o servidor seja reiniciado. Lembre-se que depois de configurar a senha de root com um comando UPDATE, não será necessário especificar a senha até que você atualize os privilégios, pois o servidor ainda não saberá que você alterou a senha!

  • Se você tiver problemas de acesso com Perl, PHP, Python ou um programa ODBC, tente conectar ao servidor com mysql -u nome_usuário nome_bd ou mysql -u nome_usuário -psua_senha nome_bd. Se você consegue conectar com o cliente mysql, existe algum problema com seu programa e não o acesso aos privilégios (Note que não espaço entre -p e a senha; você também pode utilizar a sintaxe --password=sua_senha para especificar a senha. Se você utilizar a opção -p sozinha, o MySQL irá lhe solicitar a senha.)

  • Para testar, iniciae o daemon mysqld com a opção --skip-grant-tables. Então você pode alterar as tabelas de permissões do MySQL e utilizar o script mysqlaccess para conferir se suas modificações fizeram o não o efeito desejado. Quando você estiver satisfeito com suas alterações, execute mysqladmin flush-privileges para dizer ao servidor mysqld para iniciar utilizando as novas tabelas com os privilégios. Nota: Recarregar as tabelas de permissões sobrescreve a opção --skip-grant-tables. Isto lhe permite dizer ao servidor para começar a utilizar as tabelas de permissões novamente sem reiniciá-lo.

  • Se tudo mais falhar, inicie o servidor mysqld com uma opção de depuração (por exemplo, --debug=d,general,query). Isto irá imprimir informações de máquinas e usuários sobre tentativas de conexões, e também informações sobre cada comando disparado. See Seção E.1.2, “Criando Arquivos Trace (Rastreamento)”.

  • Se você tiver outros problemas com as tabelas de permissões do MySQL e sente que deve enviar o problema para a lista de discussão, sempre forneça um descarga das tabelas de permissões do seu MySQL. Você pode descarregar as tabelas com o comando mysqldump mysql. Como sempre, envie seus problemas utilizando o script mysqlbug. See Seção 1.7.1.3, “Como relatar erros ou problemas”. Em alguns casos você pode precisar reiniciar o mysqld com a opção --skip-grant-tables para executar o mysqldump.

4.4. Gerenciamento das Contas dos Usuários no MySQL

4.4.1. A Sintaxe de GRANT e REVOKE

GRANT priv_type [(column_list)] [, tipo_priv [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    TO user_name [IDENTIFIED BY [PASSWORD] 'password']
        [, user_name [IDENTIFIED BY [PASSWORD] 'password'] ...]
    [REQUIRE
        NONE |
      [{SSL| X509}]
  [CIPHER cipher [AND]]
  [ISSUER issuer [AND]]
  [SUBJECT subject]]
    [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # |
                          MAX_UPDATES_PER_HOUR # |
                          MAX_CONNECTIONS_PER_HOUR #]]

REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    FROM user_name [, user_name ...]

O comando GRANT é implementado no MySQL versão 3.22.11 ou posterior. Para versões anteriores do MySQL, a instrução GRANT não faz nada.

Os comandos GRANT e REVOKE permitem aos administradores do sistema criar usuários e conceder e revogar direitos aos usuários do MySQL em quatro níveis de privilégios:

  • Nível Global

    Privilégios globais aplicam para todos os bancos de dados em um determinado servidor. Estes privilégios são armazenados na tabela mysql.user. GRANT ALL ON *.* e REVOKE ALL ON *.* concederão e revogarão apenas privilégios globais.

  • Nível dos bancos de dados

    Privilégios de bancos de dados aplicam-se a todas as tabelas em um determinado banco de dados. Estes privilégios são armazenados nas tabelas mysql.db e mysql.host. GRANT ALL ON db.* e REVOKE ALL ON db.* concederão e revogarão apenas privilégios de banco de dados.

  • Nível das tabelas

    Privilégios de tabelas aplicam-se a todas as colunas em uma determinada tabela. Estes privilégios são armazenados na tabela mysql.tables_priv. GRANT ALL ON db.table e REVOKE ALL ON db.table concederão e revogarão apenas privilégios de tabelas.

  • Nível das colunas

    Privilégios de colunas aplicam-se a uma única coluna em uma determinada tabela. Estes privilégios são armazenados na tabela mysql.columns_priv.

Para as instruções GRANT e REVOKE, tipo_priv pode ser especificado como um dos seguintes:

ALL [PRIVILEGES]Configura todos os privilégios simples exceto WITH GRANT OPTION
ALTERPermite o uso de ALTER TABLE
CREATEPermite o uso de CREATE TABLE
CREATE TEMPORARY TABLESPermite o uso de CREATE TEMPORARY TABLE
DELETEPermite o uso de DELETE
DROPPermite o uso de DROP TABLE.
EXECUTEPermite que o usuário execute stored procedures (MySQL 5.0)
FILEPermite o uso de SELECT ... INTO OUTFILE e LOAD DATA INFILE.
INDEXPermite o uso de CREATE INDEX e DROP INDEX
INSERTPermite o uso de INSERT
LOCK TABLESPermite o uso de LOCK TABLES em tabelas nas quais se tem o privilégio SELECT.
PROCESSPermite o uso de SHOW FULL PROCESSLIST
REFERENCESPara o futuro
RELOADPermite o uso de FLUSH
REPLICATION CLIENTDa o direto ao usuário de perguntar onde o slave/master está.
REPLICATION SLAVENecessário para a replicação dos slaves (para ler logs binário do master).
SELECTPermite o uso de SELECT
SHOW DATABASESSHOW DATABASES exibe todos os banco de dados.
SHUTDOWNPermite o uso de mysqladmin shutdown
SUPERPermite a conexão (uma vez) mesmo se max_connections tiverem sido alcançados e executa o comando CHANGE MASTER, KILL thread, mysqladmin debug, PURGE MASTER LOGS e SET GLOBAL
UPDATEPermite o uso de UPDATE
USAGESinônimo para ``sem privilégios.''
GRANT OPTIONSinônimo para WITH GRANT OPTION

USAGE pode ser usado quando você quer criar um usuário sem privilégios.

Os privilégios CREATE TEMPORARY TABLES, EXECUTE, LOCK TABLES, REPLICATION ..., SHOW DATABASES e SUPER são novos na versão 4.0.2. Para usar estes novos privilégios após atualizar para 4.0.2, você tem que executar o script mysql_fix_privilege_tables. Veja mais informações sobre isto na Seção 2.5.6, “Atualizando a Tabela de Permissões”.

Em versões anteriores do MySQL, o privilégio PROCESS dá o mesmo direitos que o novo privilégio SUPER.

Para anular o privilégio grant de um usuário, utilize o valor tipo_priv de GRANT OPTION:

mysql> REVOKE GRANT OPTION ON ... FROM ...;

Os únicos valores de tipo_priv que você pode especificar para uma tabela são SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, INDEX e ALTER.

Os únicos valores de tipo_priv que você pode especificar para uma coluna (isto é, quando você usar uma cláusula column_list) são SELECT, INSERT e UPDATE.

O MySQL permite que você crie privilégios a nível de banco de dados mesmo se o banco de dados não existir para tornar fácil de se preparar para o uso do banco de dados. Atualmente, no entanto, o MySQL não permite criar permissões de a nível de tabela se a tabela não existir. O MySQL não revogará automaticamente qualquer privilégio, mesmo se você apagar uma tabela ou banco de dados.

Você pode configurar privilégios globais utilizando a sintaxe ON *.*. Você pode configurar privilégios de bancos de dados utilizando a sintaxe ON nome_bd.*. Se você especificar ON * e estiver com algum banco de dados aberto, será configurado os privilégios somente para este banco de dados. (AVISO: Se você especificar ON * e você não tem possui um banco de dados aberto, irá afetar os privilégios globais!).

Note por favor Os metacaracteres ‘_’ e ‘%’ são permitidos na especificação dos nomes de bancos de dados em comandos GRANT. Isto significa que se você deseja usar um caracater ‘_’ como parte de um nome de banco de dados, você deve especificá-lo como '\_' no comando GRANT, para prevenir o usuário de poder acessar bancos de dados adicionais que correspondam ao padrão do metacaracter, ex., GRANT ... ON `foo\_bar`.* TO ....

Para acomodar concessões de direitos para usuários de máquinas arbitrárias, o MySQL suporta a especificação do valor user_name no formato usuário@máquina. Se você desejar especificar uma string user contendo caracteres especiais (como o ‘-’), ou uma string contendo caracteres especiais ou meta caracteres (como o ‘%’), você pode colocar o usuário ou o nome de máquina entre aspas (por exemplo, 'usuário-teste'@'máquina-teste').

Você pode especificar meta caracteres no nome da máquina. Por exemplo, user@"%.loc.gov" se aplica a user para qualquer máquina no domínio loc.gov, e user@"144.155.166.%" se aplica a user em qualquer máquina na subrede de classe C 144.155.166.

O formato simples user é sinônimo de user@"%".

O MySQL não suporta metacaracteres em nomes de usuários. Usuários anônimos são definidos inserindo entradas com User='' na tabela mysql.user ou criando um usuário com um nome vazio com o comando GRANT.

Nota: Se você permite o acesso de usuários anônimos ao seu servidor MySQL, você deve também concecder privilégios a todos os usuários locais como user@localhost porque, de outra forma, a entrada de usuário anônimo para a máquina local na tabela mysql.user será usada quando o usuário tentar a conexão ao servidor MySQL da máquina local!

Você pode verificar se isto se aplica a você executando a seguinte instrução:

mysql> SELECT Host,User FROM mysql.user WHERE User='';

No momento, GRANT suporta somente nomes de máquinas, tabelas bancos de dados e colunas até 60 caracteres. Um nome de usuário pode ter até 16 caracteres.

Os privilégios para uma tabela ou coluna são formados através do OU lógico dos privilégios em cada um dos quatro níveis de privilégios. Por exemplo, se a tabela mysql.user especifica que um usuário tem um privilégio global select, isto não pode ser negado por uma entrada no nível de banco de dados, tabela ou coluna.

Os privilégios para uma coluna podem ser calculados da seguinte forma:

privilégios globais
OR (privilégios de banco de dados AND privilégios de máquina)
OR privilégios de tabela
OR privilégios de coluna

Na maioria dos casos, os direitos a um usuário são atribuídos em apenas um dos níveis de privilégios, portanto a vida normalmente não é tão complicada como mostrado acima. Os detalhes do procedimento de verificação dos privilégios são apresentados em Seção 4.3, “Detalhes Gerais de Segurança e o Sistema de Privilégio de Acesso do MySQL”.

Se você concede privilégios para uma combinação de usuário e máquina que não existem na tabela mysql.user, um registro é adicionado e permanece lá até ser removido com um comando DELETE. Em outras palavras, GRANT pode criar registros na tabela user, mas REVOKE não as removerá; para removê-las você deve usar a instrução explícita DELETE.

Na Versão 3.22.12 ou posterior do MySQL, se um novo usuário é criado ou se você possui privilégios de concessão globais, a senha do usuário será especificada utilizando a cláusula IDENTIFIED BY, se uma for dada. Se o usuário já possui uma senha, ela é trocada pela nova.

Se você não quiser enviar a senha em texto puro você pode usar a opção PASSWORD seguido de uma senha embaralhada da função SQL PASSWORD() ou da função da API C make_scrambled_password(char *to, const char *password).

CUIDADO: Se você criar um novo usuário mas não especificar uma cláusula IDENTIFIED BY, o usuário não possuirá uma senha. Isto não é seguro.

Senhas podem também ser configuradas com o comando SET PASSWORD. Veja mais informações sobre isto na Seção 5.5.6, “Sintaxe de SET.

Se você conceder privilégios para um banco de dados, uma entrada na tabela mysql.db é criada se necessário. Quando todos os privilégios para o banco de dados forem removidos com REVOKE, este registro é removido.

Se um usuário não tem privilégios em uma tabela, a tabela não é mostrada quando o usuário solicita uma lista de tabelas (com a instrução SHOW TABLES por exemplo). O mesmo é verdade para SHOW DATABASES

A cláusula WITH GRANT OPTION dá ao usuário habilidade de fornecer à outros usuários quaisquer privilégios que ele tenha em um nível específico de privilégio. Você deve ter cuidado ao fornecer o privilégio grant, pois dois usuários podem se unir para unir privilégios!

MAX_QUERIES_PER_HOUR #, MAX_UPDATES_PER_HOUR # e MAX_CONNECTIONS_PER_HOUR # sãp novos no MySQL versão 4.0.2. Estas opções limitam o número de consultas/atualizações e logins que o usuários pode fazer durente uma hora. Se # é 0 (padrão), então isto significa que não há limites para aquele usuário. Veja mais informações sobre isto na Seção 4.4.7, “Limitando os Recursos dos Usuários”. Nota: para especificar qualquer destas opções para um usuário existente sem adicionar outros privilégios adicionais, use GRANT USAGE ON *.* ... WITH MAX_....

Você não pode conceder a outro usuário um privilégio que não possua; o privilégio GRANT possibilita fornecer somente os privilégios que possuir.

Esteja ciente que quando conceder a um usuário o privilégio GRANT em um nível particular de privilégios, qualquer privilégio que o usuário já possua (ou seja fornecido no futuro!) nesse nível também pode ser concedido por este usuário. Suponha que você conceda a um usuário o privilégio INSERT em um banco de dados. Se você conceder o privilégio SELECT no banco de dados e especificar WITH GRANT OPTION, o usuário além de poder repassar o privilégio SELECT poderá também repassar o insert. Se você concede o privilégio UPDATE para o usuário no banco de dados, o usuário poderá conceder os privilégios INSERT, SELECT e UPDATE.

Você não deve conceder privilégios ALTER a um usuário comum. Se você fizer isto, o usuário pode tentar enganar o sistema de privilégios renomeando tabelas!

Perceba que se você estiver utilizando privilégios de tabelas ou colunas, mesmo que para apenas um usuário, o servidor examina os privilégios de tabelas e colunas para todos os usuários e isto irá deixar o MySQL um pouco mais lento.

Quando o mysqld inicia, todos os privilégios são lidos na memória. Privilégios de bancos de dados, tabelas e colunas são iniciados um vez, e privilégios ao nível de usuário fazem efeito na próxima vez que o usuário conectar. Modificações nas tabelas de permissões que você realiza utilizando GRANT ou REVOKE são percebidas pelo servidor imediatamente. Se você modificar as tabelas de permissões manualmente (utilizando INSERT, UPDATE, etc), você deve executar uma instrução FLUSH PRIVILEGES ou executar mysqladmin flush-privileges para dizer ao servidor para recarregar as tabelas de permissões. Veja mais informações sobre isto na Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

As maiores diferenças entre o padrão SQL e versões MySQL de GRANT são:

  • No MySQL privilégios são fornecidos para uma combinação de usuário e máquina e não somente para um usuário.

  • O SQL-99 não possui privilégios no nível global ou de bancos de dados, e não suporta todos os tipos de privilégios que o MySQL suporta. O MySQL não suporta os privilégios TRIGGER, EXECUTE ou UNDER do SQL-99.

  • Os privilégios do SQL-99 são estruturadados em uma maneira hierárquica. Se você remover um usuário, todos os privilégios do usuário são removidos. No MySQL os privilégios concedidos não são removidos automaticamente, mas você deve removê-los se necessário.

  • Se no MySQL você possuir o privilégio INSERT em somente parte das colunas em uma tabela, você pode executar instruções INSERT na tabela; As colunas em que você não tem o privilégio INSERT irão receber seus valores padrões. O SQL-99 necessita que você tenha o privilégio INSERT em todas as colunas.

  • Quando você remove uma tabela no SQL-99, todos os privilégios para a tabela são removidos. Se você remover um privilégio no SQL-99, todos os privilégios que foram concedidos baseado neste privilégio são também removidos. No MySQL, privilégios só podem ser removidos com comandos REVOKE explícitos ou manipulando as tabelas de permissões do MySQL.

Para uma descrição do uso de REQUIRE, veja Seção 4.4.10, “Usando Conexões Seguras”.

4.4.2. Nomes de Usuários e Senhas do MySQL

Existem várias diferenças entre a forma que nomes de usuários e senhas são usados pelo MySQL e a forma que são usados pelo Unix ou Windows:

  • Nomes de usuários, como usado pelo MySQL para propósitos de autenticação, não tem nenhuma relação com os nomes de usuários do Unix (nomes de login) ou nomes de usuários Windows. A maioria dos clientes MySQL, por padrão, tentam se conectar utilizando o nome de usuário atual do Unix como o nome de usuário no MySQL, mas isto existe somente por conveniência. Programas clientes permite especificar um nome diferente com as opções -u ou --user. Isto significa que você não pode tornar um banco de dados seguro a menos que todos os usuários do MySQL possuam senhas. Qualquer um pode tentar se conectar ao servidor utilizando qualquer nome, e eles se conectarão com qualquer nome que não possua uma senha.

  • Nomes de usuários MySQL podem ter o tamanho de até 16 caracteres; Nomes de usuário Unix normalmente são limitados até 8 caracteres.

  • Senhas MySQL não tem nenhuma relação com senhas Unix. Não existe nenhuma associação entre a senha em que você utiliza para logar-se a uma máquina Unix e a senha que é utilizada para acessar um banco de dados na mesma máquina.

  • O MySQL criptografa senhas utilizando um algorítimo diferente que o utilizado pelo processo de login do Unix. Veja as descrições das funções PASSWORD() e ENCRYPT() em Seção 6.3.6.2, “Funções Diversas”. Perceba que mesmo que a senha é armazenada 'embaralhada', o conhecimento da sua senha 'embaralhada' é o suficiente para conseguir se conectar ao servidor MySQL!

    A partir da versão 4.1, o MySQL emprega um mecanismo de senha e login diferentes que é seguro mesmo se for feito um sniff no pacote TCP/IP e/ou o banco de dados mysql for capturado.

Usuários MySQL e seus privilégios são criados normalmente com o comando GRANT, Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

Quando você se conecta a um servidor MySQL com um cliente de linha de comando você pode especificar a senha com --password=sua-senha. Veja mais informações sobre isto na Seção 4.3.8, “Conectando ao Servidor MySQL”.

mysql --user=monty --password=guess nome_do_banco

Se você deseja que o cliente lhe solicite a senha, deve ser especificado o parâmetro --password sem nenhum argumento

mysql --user=monty --password nome_do_banco

ou no formato curto:

mysql -u monty -p nome_do_banco

Perceba que no último exemplo a senha não é 'nome_do_banco'.

Se você deseja usar a opção -p para fornecer uma senha você deve fazer assim:

mysql -u monty -pguess database_name

Em alguns sistemas, a chamada da biblioteca que é utilizada pelo MySQL para solicitar por uma senha corta automaticamente a senha para 8 caracteres. Internamente o MySQL não limita o tamanho limite da senha.

4.4.3. Quando as Alterações nos Privilégios tem Efeito

Quando o mysqld inicia, todas o conteúdo das tabelas de permissões são lidos em memória e tem efeito neste momento.

As modificações das tabelas de permissões que você realiza utilizando GRANT, REVOKE ou SET PASSWORD são imediatamente reconhecidas pelo servidor.

Se você alterar as tabelas de permissões manualmente (utilizando INSERT, UPDATE, etc), você deve executar a instrução FLUSH PRIVILEGES ou executar mysqladmin flush-privileges ou mysqladmin reload para dizer ao servidor para recarregar as tabelas de permissões. De outra forma suas alterações não terão efeito até que o servidor seja reiniciado. Se você alterar as tabelas de permissões manualmente mas se esquecer de recarregar os privilégios, suas alteração vão parecer não ter feito nenhuma diferença!

Quando o servidor reconhecer que as tabelas de permissões foram alteradas, conexões existentes são afetadas da seguinte forma:

  • Alterações nos privilégios de tabelas e colunas fazem efeito com a próxima requisição do cliente.

  • Alterações nos privilégios de bancos de dados fazem efeito no próximo comando USE nome_bd.

  • Alterações nos privilégios globais e alterações de senhas fazem efeito na próxima vez que o cliente conectar.

4.4.4. Configurando os Privilégios Iniciais do MySQL

Depois de instalar o MySQL, você configura os privilégios iniciais dos acessos executando scripts/mysql_install_db. Veja mais informações sobre isto na Seção 2.3.1, “Visão geral da instalação rápida”. O script mysql_install_db inicia o servidor mysqld, depois inicializa as tabelas de permissões com a seguinte configuração dos privilégios:

  • O usuário root do MySQL é criado como um superusuário que pode fazer qualquer coisa. Conexões devem ser feitas através da máquina local.

    NOTA: A senha inicial de root é vazia, portanto qualquer um que conectar como root sem senha terá direito a todos os privilégios.

  • Um usuário anônimo é criado e pode fazer o que desejar com bancos de dados com nome 'test' ou iniciando com 'test_'. Conexões devem ser feitas da máquina local. Isto significa que usuários locais podem se conectar sem senha e serem tratados como usuários anônimos.

  • Outros privilégios são negados. Por exemplo, usuários normais não podem executar mysqladmin ou mysqladmin processlist.

NOTA: Os privilégios padrões são diferentes no Windows. Veja mais informações sobre isto na Seção 2.1.1.8, “Executando o MySQL no Windows”.

Como sua instação inicialmente é parcialmente aberta, uma das primeiras coisas que você deve fazer é especificar uma senha para o usuário root do MySQL. Você pode fazer isto como a seguir (perceba que a senha foi especificada utilizando a função PASSWORD()):

shell> mysql -u root mysql
mysql> SET PASSWORD FOR root@localhost=PASSWORD('nova_senha');

Substitua 'nova_senha' pela senha que você deseja usar.

Se você souber o que esta fazendo, você também pode manipular diretamente a tabela privilégios:

shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('nova_senha')
    ->     WHERE user='root';
mysql> FLUSH PRIVILEGES;

Outra forma de configurar a senha é utilizando o comando mysqladmin:

shell> mysqladmin -u root password nova_senha

Somente usuários com acesso de escrita/atualização ao banco de dados mysql podem alterar a senha de outros usuários. Todos os usuários comuns (não os anônimos) podem alterar somente a própria senha com um dos comandos acima ou com SET PASSWORD=PASSWORD('nova_senha').

Perceba que se você atualizar a senha na tabela user diretamente utilizando UPDATE, você deve dizer ao servidor para reler as tabelas de permissões (com FLUSH PRIVILEGES), de outra forma a alteração não seria notificada.

Uma vez que a senha de root foi configurada, você deve informar a senha quando se conectar ao servidor MySQL como root.

Você pode desejar deixar a senha de root em branco para que você não precise especificá-la quando realizar configurações adicionais ou testes. Entretanto, tenha certeza de configurá-la antes de utilizar sua instalação para qualquer ambiente de produção.

Veja o script scripts/mysql_install_db para ver como são configurados os privilégios padrões. Você pode usar isto como uma base para ver como adicionar outros usuários.

Se você deseja que os privilégios iniciais sejam diferentes do descrito acima, é possível modificar o script mysql_install_db antes de executá-lo.

Para recriar as tabelas de permissões completamente, remova todos os arquivos .frm .MYI e .MYD no diretório contendo o banco de dados mysql. (Este é o diretório chamado mysql sob o diretório do banco de dados, que é listado quando você executa mysqld --help.) Depois execute o script mysql_install_db, possivelmente depois de editá-lo para criar os privilégios desejáveis.

NOTA: Para versões do MySQL mais antigas que a versão 3.22.10, você não deve apagar os arquivos .frm. Se você fizer isso acidentalmente, você deve voltá-los a partir de sua distribuição MySQL antes de executar mysql_install_db.

4.4.5. Adicionando Novos Usuários ao MySQL

Existem duas maneiras de adicionar usuários: utilizando instruções GRANT ou manipulando as tabelas de permissões do MySQL diretamente. O método preferido é utilizar instruções GRANT, porque elas são mais concisas e menos propensas a erros. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

Existem vários programas de colaboradores (como o phpMyAdmin) que podem ser utilizados para criar e administrar usuários. Veja mais informações sobre isto na Apêndice B, Contribuição de Programas.

Os exemplos abaixo mostram como usar o cliente mysql para configurar novos usuários. Estes exemplos assumem que privilégios são configurados de acordo com os padrões descritos na seção anterior. Isto significa que para fazer alterações, você deve se conectar na mesma máquina em que o mysqld está executando, você deve se conectar com o usuário root, e o usuário root deve ter os privilégios inster ao banco de dados mysql e o administrativo reload. Também, se você alterou a senha do usuário root, você deve especificá-la para os comandos mysql abaixo.

Primeiro, use o programa mysql para se conectar ao servidor como o usuário root do MySQL:

shell> mysql --user=root mysql

Você pode adicionar novos usuários utilizando instruções GRANT:

mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost
           IDENTIFIED BY 'alguma_senha' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@'%'
           IDENTIFIED BY 'alguma_senha' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
mysql> GRANT USAGE ON *.* TO dummy@localhost;

Estas instruções GRANT configuram três novos usuários:

  • monty

    Um superusuário completo que pode conectar ao servidor de qualquer lugar, mas deve utilizar uma senha 'alguma_senha' para fazer isto. Perceba que devemos utilizar instruções GRANT para monty@localhost e monty@"%". Se nós não adicionarmos a entrada com localhost, a entrada para o usuário anônimo para localhost que é criada por mysql_install_db toma precedência quando nos conectarmos da máquina local, porque ele contem um campo Host com um valor mais específico e também vem antes na ordenação da tabela user.

  • admin

    Um usuário que possa conectar de localhost sem uma senha e que é concedido os privilégios administrativos reload e process. Isto permite ao usuário a execução dos comandos mysqladmin reload, mysqladmin refresh e mysqladmin flush-*, bem como o mysqladmin processlist. Nenhum privilégio a nível de bancos de dados é concedido. (Depois eles podem ser adicionados utilizando instruções GRANT adicionais.)

  • dummy

    Um usuário que pode conectar sem uma senha, mas somente na máquina local. Não são concedidos nenhum privilégio---o tipo de privilégio USAGE permite a criação de um usuário sem privilégios. Ele tem o efeito de criar todos os privilégios globais com 'N'. Considera-se que você irá conceder privilégios específicos a conta posteriormente.

Também é possível adicionar a mesma informação de acesso do usuário diretamente, utilizando instruções INSERT e depois dizendo ao servidor para recarregar as tabelas de permissões:

shell> mysql --user=root mysql
mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('alguma_senha'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user VALUES('%','monty',PASSWORD('alguma_senha'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
                 Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
                        VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;

Dependendo da sua versão do MySQL, você pode precisar utilizar um número diferente de valores 'Y' acima. (Versões anteriores à versão 3.22.11 tem menos campos de privilégios, e posteriores a 4.02 têm mais). Para o usuário admin, a maior sintaxe legível de INSERT usando SET que está disponível a partir da versão 3.22.11 é a utilizada.

Note que para configurar um superusuário, você só precisar criar uma entrada na tabela user com os campos de privilégios configurados para 'Y'. Não é necessário gerar entradas nas tabelas db ou host.

Na última instrução INSERT (para o usuário dummy), apenas as colunas Host, User e Password nos registros da tabela user tem valores atribuídos. Nenhuma das colunas de privilégios são definidas explicitamente, assim o MySQL atribui a todas o valor padrão de 'N'. Isto é a mesma coisa que o GRANT USAGE faz.

O seguinte exemplo adiciona um usuário custom que pode acessar o banco de dados bankaccout apenas do localhost, o banco de dados expenses somente de whitehouse.gov e o banco de dados customer de todas de server.domain. Ele deseja utilizar a senha obscure das três máquinas.

Para configurar os privilégios deste usuário utilizando instruções GRANT, execute estes comandos:

shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON bankaccount.*
    ->     TO custom@localhost
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON expenses.*
    ->     TO custom@'whitehouse.gov'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON customer.*
    ->     TO custom@'server.domain'
    ->     IDENTIFIED BY 'obscure';

Para configurar os privilégios do usuário modificiando as tabelas de permissões diretamente, utilize estes comandos (perceba o FLUSH PRIVILEGES no final):

shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('localhost','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES
    -> ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES
    -> ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES('server.domain','customer','custom','Y','Y','Y','Y','Y','Y');

Como no exemplo anterior que usaram as instruções INSERT, você pode precisar de usar um número diferentes de valores 'Y', dependendo de sua versão do MySQL.

As primeiras três instruções INSERT adicionam entradas na tabela user que permite ao usuário custom conectar a partir de várias máquinas com a senha determinada, mas não concede permissões ao mesmo (todos os privilégios são configurados com o valor padrão de 'N'). As próximas três instruções INSERT adicionam entradas na tabela db que concedem privilégios à custom para os bancos de dados bankaccount, expenses e customer, mas só quando acessados à partir das máquinas apropriadas. Normalmente, depois de modificar as tabelas de permissões diretamente, você deve dizer ao servidor para recarregá-las (com FLUSH PRIVILEGES) para que as alterações nos privilégios tenham efeito.

Se você deseja fornecer a um usuário específico acesso de qualquer máquina em um determinado domínio (por exemplo, meudomínio.com), você pode utilizar uma instrução GRANT como a seguir:

mysql> GRANT ...
    ->     ON *.*
    ->     TO myusername@'%.mydomain.com'
    ->     IDENTIFIED BY 'mypassword';

Para realizar a mesma coisa modificando diretamente as tabelas de permissões, faça isto:

mysql> INSERT INTO user VALUES ('%.meudominio, 'meunomedeusuario'
           PASSWORD('minhasenha'),...);
mysql> FLUSH PRIVILEGES;

4.4.6. Deletando Usuários do MySQL

DROP USER nome_usuario

Este comando foi adicionado ao MySQL 4.1.1.

Ele apaga um usuário que não possua nenhum privilágio.

Para deletar um usuário do MySQL você usar o seguinte procedimento, realizando os passos na ordem mostrada.

  1. Verifique quais privilégios o usuário tem com SHOW PRIVILEGES. See Seção 4.6.8.11, “SHOW PRIVILEGES.

  2. Delete todos os privilégios do usuário com REVOKE. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

  3. Delete o usuário com DROP USER.

Se você estiver usando uma versão mais antiga do MySQL você deve primeiro revogar os privilégios e então deletar o usuário com:

DELETE FROM mysql.user WHERE user='username' and host='hostname';
FLUSH PRIVILEGES;

4.4.7. Limitando os Recursos dos Usuários

A partir do MySQL 4.0.2 pode se limitar certos recursos por usuários.

Até então, o único método disponível de limitação de uso do servidor MySQL era canfigurar a variável de inicialização max_user_connections para um valor diferente de zero. Mas este método é estritamente global e não permite o gerenciamento de usuários individuais, o que pode ser de interresse particular do Provedor de Serviços Internet.

Consequentemente, o gerenciamento de três recursos é introduzido no nível de usuário individual:

  • Número de todas as consultas por hora: Todos os comandos que podiam ser executados por um usuário.

  • Número de todas as atualizações por hora: Qualquer comando que altera qualquer tabela ou banco de dados.

  • Númeor de conexões feitas por hora: Novas conexões abertas por hora.

Um usuário no contexto mencionado acima é uma única entrada na tabela user, que é identificada unicamente por suas colunas user e host.

Todos os usuários não são limitados por padrão no uso dos recursos acima, a menos que os limites sejam garantidos a eles. Estes limites podem ser concedidos apenas através do GRANT (*.*) global, usando esta sintaxe:

GRANT ... WITH MAX_QUERIES_PER_HOUR N1
               MAX_UPDATES_PER_HOUR N2
               MAX_CONNECTIONS_PER_HOUR N3;

Pode-se especificar qualquer combinação dos recursos acima. N1, N2 e N3 são inteiros e significam contagem/hora.

Se os usuários alcançam o limite de conexões dentro de uma hora, não será aceita mais nenhuma conexão até o fim desta hora. De forma parecida se o usuário alcança o limite do número de consultas ou atualizações, consultas ou atualizações adicionais serão rejeitadas até que a hora acabe. Em todos os casos, uma mensagem de erro apropriada é enviada.

Os valores atualmente usados por um usuário em particular pode ser descarregados (zerados) enviando uma instrução GRANT com qualquer das cláusulas acima, incluíndo uma instrução GRANT com os valores atuais.

Os valores atuais para todos os usuários para todos os usuários serão descarregados se os privilégios forem recarregados (no servidor ou usando mysqladmin reload) ou se o comando FLUSH USER_RESOURCES é executado.

O resurso está habilitado assim que e concedido a um único usuário qualquer das cláusulas GRANT de limitação.

Como um prerequisito para a habilitação deste recurso, a tabela user no banco de dados mysql deve conter as colunas adicionais, como definido no script de criação de tabelas mysql_install_db e mysql_install_db.sh no subdiretório scripts.

4.4.8. Configurando Senhas

Na maioria dos casos você deve utilizar GRANT para configurar seus usuários e senhas, portanto, as informações exibidas a seguir são aplicadas somentes para usuários avançados. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

Os exemplos nas seções precedentes ilustram um princípio importante: quando você armazena uma senha não-vazia utilizando INSERT ou UPDATE você deve utilizar a função PASSWORD() para criptografá-la. Isto é porque a tabela user armazena senhas na forma criptografada, e não como texto puro. Se você esquecer deste fato, é provável que você possa tentar configurar senhas desta forma:

shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
       VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;

O resultado é que o valor 'biscuit' é armazenado como a senha na tabela user. Quando o usuário jeffrey tentar se conectar ao servidor utilizando esta senha, o cliente mysql a criptografa utilizando a função PASSWORD(), gerando um vetor de autenticação baseado em uma senha criptografada e um número randômico, obtido do servidor, e envia o resultado ao servidor. O servidor usa o valor do campo password na tabela user (que é o valor 'biscuit' não criptografado ) para realizar os mesmos cálculos e comparar os resultados. A comparação falha e o servidor rejeita a conexão:

shell> mysql -u jeffrey -pbiscuit test
Access denied

As senhas devem ser criptografadas quando elas são inseridas na tabela user, portanto a instrução INSERT deveria ter sido informada no seguinte formato:

mysql> INSERT INTO user (Host,User,Password)
       VALUES('%','jeffrey',PASSWORD('biscuit'));

Você deve também utilizar a função PASSWORD() quando utilizar instruções SET PASSWORD:

mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');

Se você configurar senhas utilizando a instrução GRANT ... IDENTIFIED BY ou o comando mysqladmin password, a função PASSWORD() é desnecessária. Ambos tomam o cuidado de criptografar a senha para você, então você deve especificar a senha 'biscuit' desta forma:

mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';

ou

shell> mysqladmin -u jeffrey password biscuit

NOTA: PASSWORD() é diferente da senha criptografada do Unix.

4.4.9. Mantendo Sua Senha Segura

Não é aconselhável especificar uma senha de uma forma que a exponha e possa ser descoberta por outros usuários. Os métodos que você pode usar para especificar sua senha quando executar programas clientes são listados abaixo, juntamente com as determinações de riscos de cada método:

  • Nunca forneça a um usuário normal acesso à tabela mysql.user. O conhecimento de uma senha criptografada possibilita a conexão como este usuário. As senhas só estão embaralhadas para que não seja possível chegar à senha real que foi usada (acontece muito a utilização de senhas similares em outras aplicações).

  • Uso da opção -psua_senha ou --password=sua_senha na linha de comando. Isto é conveniente mas inseguro, porque sua senha se torna visível para programas de informação do sistema (como no ps) que pode ser chamado por outros usuários para exibir linhas de comando. (clientes MySQL normalmente gravam zeros em cima do argumento da linha de comando durante sua sequência de inicialização, mas ainda existe um breve intervalo no qual o valor está visível.)

  • Uso das opções -p ou --pasword (sem especificar o valor sua_senha). Neste caso, o programa cliente solicita a senha do terminal:

    shell> mysql -u user_name -p
    Enter password: ********
    

    Os caracteres ‘*’ representam sua senha.

    É mais seguro digitar sua senha desta forma do que especificá-la na linha de comando porque ela não fica visível a outros usuários. Entretanto este método de digitar uma senha é válido somente para programas que você executa de forma interativa. Se você deseja chamar um cliente de um script que não execute interativamente, não existirá oportunidade de digitar a senha do terminal. Em alguns sistemas, você pode descobrir que a primeira linha do seu script é lida e interpretada (incorretamente) como sua senha!

  • Armazenar a sua senha em um arquivo de configuração. Por exemplo, você pode listar sua senha na seção [client] do arquivo .my.cnf no seu diretório home:

    [client]
    password=sua_senha
    

    Se você armazenar sua senha em um arquivo .my.cnf, o arquivo não pode ser lido por seu grupo ou pelos outros usuários. Tenha certeza que o modo de acesso do arquivo é 400 ou 600 Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Você pode armazenar sua senha na variável de ambiente MYSQL_PWD, mas este método deve ser considerado extremamente inseguro e não deve ser usado. Algumas versões de ps incluem uma opção para exibir o ambiente de processos em execução; sua senha estaria em texto puro para a leitura para todos os usuários. Mesmo em sistemas sem esta versão do ps, seria imprudência assumir que não existe outro método para observar o ambiente de processos. Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL.

Em resumo, os métodos mais seguros seriam que o programa cliente solicitasse a senha ou especificar a senha em um arquivo .my.cnf corretamente protegido.

4.4.10. Usando Conexões Seguras

4.4.10.1. Conceitos Basicos

A partir da versão 4.0.0, o MySQL tem suporte a conexões cri[ptografadas com SSL. Para entender como o MySQL usa SSL, é necessário explicar alguns conceits básicos de SSL e X509. A pessoal que já estão familiarizada com eles podem saltar esta parte.

Por padrão o MySQL não usa conexões criptografadas entre o cliente e o servidor. Isto significa que qualquer um pode observar todo o tráfico e ver os dados enviados e recebidos. Podiase até mesmo alterar os dados enquanto eles estavam em transito entre o cliente e o servidor. Algumas vezes você precisao mover informações sobre redes públicas de um modo seguro; em tais casos, usar uma conexão sem criptografia é inaceitável.

SSL é um protocolo que utiliza diferentes algorítimos de criptografia para assegurar que os dados recebidos por uma rede pública são confiáveis. Ele tem um mecanismo para detectar qualquer alteração, perda ou reenvio de dados. SSL também incorpora algoritmos para reconhecer e fornecer identidades de verificação usando o padrão X509.

Criptografia é o modo de tornar qualquer tipo de dado ilegível. De fato, as práticas de hoje precisam de muitos elementos de segurança adicionais para algoritmos de criptografia. Eles devem resistir a muitos tipos de atques conhecidos como apenas alterando a ordem da mensagem criptografada ou emviando o dado duas vezes.

X509 é um padrão que torna possível identificar alguém na Internet. Ele é mais comumente usado em aplicações e-commerce. Em termos básicos, deve haver algumas empresas (chamadas ``Autoridades de Certificação'') que atribuem certificados eletrônicos para qualquer um que precise deles. Os certificados se baseiam em algorítmos de criptografia assimétricos que possuem duas chaves de criptografia (uma chave pública e uma chave secreta). Um proprietário de certificado pode provar a sua identidade mostrnado este certificado para outra parte. Um certificado consiste das chaves públicas do proprietário. Qualquer dados criptografado com esta chave pública pode ser descriptografada apenas usando a chave secreta correspondente, que é guardada pelo dono do certificado.

O MySQL não utiliza conexões criptografadas por padrão, porque fazendo isto tornaria o protocolo cliente/servidor muito lento. Qualquer tipo de funcionalidade adiocional exige que o conputador faça um trabalho adicional e a criptografia de dados é uma operação intensiva da CPU que exige tempo e pode atrasar o MySQL nas tarefas principais. Por padrão o MySQL é ajustado para ser o mais rápido possível.

Se você precisa de mais informações sobre SSL, X509 ou criptografia, você deve usar se mecanismo de busca favorita na Internet para procurar sobre o assunto que está interessado.

4.4.10.2. Exigências

Para conseguir conexões seguras para trabalhar com o MySQL você deve fazer o seguinte:

  1. Insatale o biblioteca OpenSSL. Testamos o MySQL com OpenSSL 0.9.6. http://www.openssl.org/.

  2. Configure o MySQL com --with-vio --with-openssl.

  3. Se você estiver usando um instalação antiga do MySQL, você tem que atualizar a sua tabela mysql.user com algumas novas colunas relacionadas a SSL. Isto é necessário se suas tabelas de permissões são de uma versão anterior ao MySQL 4.0.0. O procedimento está descrito em Seção 2.5.6, “Atualizando a Tabela de Permissões”.

  4. Você pode verificar se um servidor mysqld em execução suporta OpenSSL examinando se SHOW VARIABLES LIKE 'have_openssl' retorna YES.

4.4.10.3. Configurando Certificados SSL para o MySQL

Aqui está um exemplo para configurar certificados SSL para o MySQL:

DIR=`pwd`/openssl
PRIV=$DIR/private

mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf

# Crie os aarquivos necessário: $database, $serial e o diretório
$new_certs_dir (opcional)

touch $DIR/index.txt
echo "01" > $DIR/serial

#
# Geração do Certificate Authority(CA)
#

openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf

# Saída exemplo:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:

#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

# Saída exemplo:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key (optional)
#

openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

#
# Assina o certificado do servidor
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

# Saída exemplo:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

# Saída exemplo:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

#
# Sign client cert
#

openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

# Saída exemplo:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create a my.cnf file that you can use to test the certificates
#

cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf

#
# To test MySQL

mysqld --defaults-file=$DIR/my.cnf &

mysql --defaults-file=$DIR/my.cnf

Você também pode testar sua configuração modificando o arquivo my.cnf acima para fazer referência aos certificados de demonstração no diretório mysql-dist-fonte/SSL.

4.4.10.4. Opções SSL do GRANT

O MySQL pode verificar atributos do certificado X509 em adição ao esquema normal de usuário/senha. Todas as opções comuns ainda são exigidas (usuário, senha, máscara do endereço IP, noome tabela/banco de dados).

Existem diferentes possibilidades para limitarmos as conexões:

  • Sem nenhuma opção SSL ou X509, todos os tipos de conexões criptografadas/ descriptografadas são permitidas se o usuário e senha são válidos.

  • A opção REQUIRE SSL limita o servidor para permitir apenas conexões criptografadas SSL. Note que esta opção pode ser omitida se não houver nenhum registro ACL que permita conexões não SSL.

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
    
  • REQUIRE X509 significa que o cliente deve ter um certificado válido mas não nos procupamos sobre o certificado, o emissor ou assunto exato. A única restrição é que deve ser possível verificar a sua assinatura com um dos certificados CA.

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
    
  • REQUIRE ISSUER 'emissor' coloca uma restrição na tentativa de conexão: O cliente deve apresentar um certificado X509 válido emitido pelo CA 'emissor'. Usar o certificado X509 sempre implica em criptografia, assim a opção SSL é desnecessária.

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE ISSUER 'C=FI, ST=Some-State, L=Helsinki,
        '> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com';
    
  • REQUIRE SUBJECT 'assunto' exige que o cliente tenha um certificado X509 com o assunto 'assunto'. Se o cliente apresenta um certificado que é valido mas tem um 'assunto' diferente, a conexão é disabilitada.

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE SUBJECT 'C=EE, ST=Some-State, L=Tallinn,
        '> O=MySQL demo client certificate,
        '> CN=Tonu Samuel/Email=tonu@mysql.com';
    
  • REQUIRE CIPHER 'método' é necessário para assegurar que uma criptografia forte será usada. O SSL pode ser fraco se algoritmos antigos com chaves de criptografias curtas são usados. Usando esta opção, podemos pedir por algum método de criptografia exato para permitir a conexão.

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

    As opções SUBJECT, ISSUER e CIPHER podem ser combinadas na cláusula REQUIRE desta forma:

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE SUBJECT 'C=EE, ST=Some-State, L=Tallinn,
        '> O=MySQL demo client certificate,
        '> CN=Tonu Samuel/Email=tonu@mysql.com'
        -> AND ISSUER 'C=FI, ST=Some-State, L=Helsinki,
        '> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com'
        -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

    A partir do MySQL 4.0 a palavra chave AND é opcional entre opções REQUIRE.

    A ordem das opções não importa, mas nenhuma opção pode ser especificada duas vezes.

4.4.10.5. Opções SSL de Linha de Comando

A seguinte tabela lista opções que são usadas para especificar o uso de SSL, arquivos de certificado e arquivos de chaves. Estas opções estão disponíveis a partir do MySQL 4.0. Elas podem ser dadas na linha de comando ou no arquivo de opção.

  • --ssl

    Para o servidor, especifica que o servidor permite conexões SSL. Para um programa cliente, permite que o cliente se conecte ao servidor usando SSL. Esta opção por si só não é suficiente para fazer uma conexão SSL ser usada. Você também deve especificar as opções --ssl-ca, --ssl-cert, e --ssl-key.

    Note que esta opção não exige uma conexão SSL. Por exemplo, se o servidor ou clienteestá compilado sem suporte SSL, uma conexão não criptografada normal será usada.

    O modo seguro de de se certificar que uma conexão SSL será usada é criar uma conta no servidor que inclua uma cláusula REQUIRE SSL na instrução GRANT. Então use esta conta para se conectar ao servidor, com um servidor e cliente que tenham suporte a SSL habilitado.

    Você pode usar esta opção para indicar que a conexão não deve usar SSL. Faça isto especificando a opção como --skip-ssl ou --ssl=0.

  • --ssl-ca=file_name

    O caminho para um arquivo vom uma lista de Certifcados SSL confiáveis.

  • --ssl-capath=directory_name

    O caminho para um diretório que contém certificados SSL confiáveis no formato pem.

  • --ssl-cert=file_name

    O nome do arquivo de certificado SSL usado para estabelecer uma conexão segura.

  • --ssl-cipher=cipher_list

    Uma lista de chaves permitidas, usado para criptografia SSL. cipher_list tem o mesmo formato que o comando openssl ciphers.

    Example: --ssl-cipher=ALL:-AES:-EXP

  • --ssl-key=file_name

    O nome do arquivo de chave SSL a ser usado para estabelecer uma conexão segura.

4.5. Prevenção de Disastres e Recuperação

4.5.1. Backups dos Bancos de Dados

Como as tabelas do MySQL são armazenadas como arquivos, é mais fácil realizar um backup. Para obter um backup consistente, faça um LOCK TABLES nas tabelas relevantes seguido por FLUSH TABLES para as tabelas. Veja mais informações sobre isto na Seção 6.7.5, “Sintaxe LOCK TABLES e UNLOCK TABLES. Veja mais informações sobre isto na Seção 4.6.4, “Sintaxe de FLUSH. Você só precisa de um bloqueio de leitura; isto possibilita outras threads a continuarem a pesquisar nas tabelas enquanto você copia os arquivos no diretório do banco de dados. O FLUSH TABLE é necessário para garantir que todas as páginas ativas de índices serão escritas em disco antes de iniciar o backup.

A partir das versões 3.23.56 e 4.0.12 BACKUP TABLE não permitirá que você sobrescreva arquivos exixtentes já que isso colocaria em risco a segurança.

Se você desejar realizar um backup ao nível da linguagem SQL de um tabela, você pode utilizar SELECT INTO OUTFILE ou BACKUP TABLE. Veja mais informações sobre isto na Seção 6.4.1, “Sintaxe SELECT.Veja mais informações sobre isto na Seção 4.5.2, “Sintaxe de BACKUP TABLE.

Outra maneira de efetuar um backup de um banco de dados é utilizar o programa mysqldump ou o script mysqlhotcopy. Veja mais informações sobre isto na Seção 4.9.7, “mysqldump, Descarregando a Estrutura de Tabelas e Dados”. Veja mais informações sobre isto na Seção 4.9.8, “mysqlhotcopy, Copiando Bancos de Dados e Tabelas do MySQL”.

  1. Fazer um backup completo do seu banco de dados:

    shell> mysqldump --tab=/path/to/some/dir --opt db_name
    
    ou
    
    shell> mysqlhotcopy db_name /path/to/some/dir
    

    Você também pode simplesmente copiar os arquivos das tabelas (*.frm, *.MYD) e os arquivos *.MYI) quando o servidor não estiver atualizando nada. O script mysqlhotcopy utiliza este método. (Mas nopte que estes métodos não funcionarão se seu banco de dados contém tabelas InnoDB. InnoDB não armazena o conteúdo das tabelas em diretórios de banco de dados, e o mysqlhotcopy funciona apenas para tabelas MyISAM e ISAM.)

  2. Interrompa o mysqld caso ele esteja em execução, depois inicie-o com a opção --log-bin[=nome_arquivo]. See Seção 4.10.4, “O Log Binário”. Os arquivos de log binário fornecem a informação necessária para replicar alterações ao banco de dados que forem feitas depois do ponto em que você executou mysqldump.

Se o seu servidor MySQL é um slave, seja qual for o método de backup que você escolha, quando você faz backup dos dados do slave, você deve também fazer backup dos arquivos master.info e relay-log.info que são necessários para continuar a replicação depois que você restaurar os dados do slave. Se seu slave está sujeito a replicação de comandos LOAD DATA INFILE, você também deve fazer backup dos arquivos SQL_LOAD-* que podem existir no diretório especificado pela opção slave-load-tmpdir. (A localização padrão desta opção é o valor da variável tmpdirse não especificado.) O slave precisará destes arquivos para continuar a replicação de qualquer LOAD DATA INFILE interrompido.

Se você necessita restaurar alguma coisa, tente primeiro recuperar suas tabelas utilizando REPAIR TABLE ou myisamchk -r. Isto deve funcionar em 99.9% de todos os caso, Se o myisamchk falhar, tente o seguinte procedimento: (Isto só irá funcionar se você iniciou o MySQL com --log-update, veja Seção 4.10.4, “O Log Binário”,):

  1. Restaure o backup original feito com o mysqldump ou backup binário.

  2. Execute o seguinte comando para re-executar as atualizações armazenadas no log binário:

    shell> mysqlbinlog hostname-bin.[0-9]* | mysql
    

    Em seu caso você pode querer re-executar apenas alguns log binários, a partir de certas posiçõs (normalmente você quer re-executar todos os log binários a partir da data de restauração do backup, co exceção de algumas consultas erradas). Veja Seção 4.9.5, “mysqlbinlog, Executando as Consultas a Partir de um Log Binário” fpara mais informações sobre o utilitário mysqlbinlog e como usá-lo.

    Se você estiver utilizando o log atualizado, você pode executar o conteúdo do log de atualização desta forma:

    shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
    

O comando ls é usado para obter todos os arquivos de log na ordem correta.

Você pode também fazer backups seletivos com SELECT * INTO OUTFILE 'nome_arquivo' FROM nome_tabela e restaurar com LOAD DATA INFILE 'nome_arquivo' REPLACE.... Para evitar registros duplicados, você precisará de um chave PRIMARY KEY ou uma UNIQUE na tabela. A palavra chave REPLACE substitui os antigos registros com os novos quando um novo registro duplica um antigo registro em uma chave de valores únicos.

Se você tiver problemas de performance realizando backups no seu sistema, você pode resolver isto configurando uma replicação e fazendo os backups na máquina slave no lugar da master. Veja mais informações sobre isto na Seção 4.11.1, “Introdução”.

Se você estiver utilizando um sistema de arquivos Veritas, você pode fazer:

  1. Executar em um cliente (perl ?) FLUSH TABLES WITH READ LOCK

  2. Bifurcar uma shell ou executar em outro cliente mount vfxs snapshot.

  3. Executar no primeiro cliente UNLOCK TABLES

  4. Copiar arquivos do snapshot

  5. Desmontar snapshot

4.5.2. Sintaxe de BACKUP TABLE

BACKUP TABLE nome_tabela[,nome_tabela...] TO '/caminho/para/diretório/backup'

Faz uma cópia de todos os arquivos de tabela para o diretório de backup que é o mínimo necessário para restaurá-lo. Atualmente só funciona para tabelas MyISAM. Para tabela MyISAM, copia os arquivos .frm (definições) e .MYD (dados). O arquivo de índice pode ser reconstruído a partir destes dois.

Antes de utilizar este comando, por favor veja Veja mais informações sobre isto na Seção 4.5.1, “Backups dos Bancos de Dados”.

Durante o backup, o bloqueio de leitura (read lock) será usado para cada tabela, uma de cada vez, à medida que o backup é realizado. Se você deseja fazer backup de diversas tabelas como um snapshot, você deve primeiro usar LOCK TABLES obtendo um bloqueio de leitura para cada tabela no grupo.

O comando retorna uma tabela com as seguintes colunas:

ColunaValor
TableNome da Tabela
OpSempre backup
Msg_typeUm dos seguintes: status, error, info ou warning.
Msg_textA mensagem

Note que o comando BACKUP TABLE está disponível somente no MySQL versão 3.23.25 e posterior.

4.5.3. Sintaxe de RESTORE TABLE

RESTORE TABLE nome_tabela[,nome_tabela...] FROM '/caminho/para/diretório/backup'

Restaura a tabela ou tabelas utilizando o backup feito com BACKUP TABLE. Tabelas existentes não serão reescritas - se você tentar restaurar sobre uma tabela existente, obterá um erro. A restauração demora mais tempo do que o backup pois é necessário reconstruir o índice. Quanto mais chaves tiver, mais demorado será. Como no comando BACKUP TABLE, atualmente só funciona com tabelas MyISAM.

O comando retorna uma tabela com as seguintes colunas:

ColunaValor
TableNome da Tabela
OpSempre restore
Msg_typeUm dos seguintes: status, error, info ou warning
Msg_textA mensagem

4.5.4. Sintaxe de CHECK TABLE

CHECK TABLE nome_tabela[,nome_tabela...] [opção [opção...]]

opção = QUICK | FAST | MEDIUM | EXTENDED | CHANGED

CHECK TABLE funciona somente em tabelas MyISAM. Em tabelas MyISAM é a mesma coisa que executar myisamchk --medium-check nome_tabela na tabela.

Se você não especificar nenhuma opção, MEDIUM é usado.

Verifica se existem erros na(s) tabela(s). Para as tabelas MyISAM as estatísticas das chaves são atualizadas. O comando retorna uma tabela com as seguintes colunas:

ColunaValor
TableNome da Tabela.
OpSempre check
Msg_typeUm dos seguintes: status, error, info, or warning
Msg_textA mensagem

Note que a instrução pode produzir várias linhas de informações para cada tabela conferida. A última linha irá ser do tipo Msg_type status e normalmente deve estar OK. Se você não obteve OK ou Not checked, deve ser executado, normalmente, um reparo da tabela. Veja mais informações sobre isto na Seção 4.5.6, “Utilizando myisamchk para Manutenção de Tabelas e Recuperação em Caso de Falhas”. Table is already up to date significa que o gerenciador de armazenamento para a tabela indica que não há necessidade de verificar a tabela.

Os diferentes tipos de consistências são as seguintes:

TipoSignificado
QUICKNão busca os registros verificando ligações incorretas.
FASTSó confere tabelas que não foram fechadas corretamente.
CHANGEDSó verifica as tabelas que foram alteradas desde a última conferência ou que não foram fechadas corretamente.
MEDIUMBusca os registros para verificanado que ligações removidas estão ok. Isto também calcula uma chave de conferência para os registros e verifica isto com um checksum calculado para as chaves.
EXTENDEDFaz uma busca completa nas chaves para todas as chaves em cada registro. Isto assegura que a tabela está 100% consistente, mas pode demorar muito tempo para executar!

Para tabelas MyISAM de tamanho dinâmico, uma verificação iniciada sempre fará uma verificação MEDIUM. Para registros de tamanho estático nós saltamos a busca de registros para QUICK e FAST já que os registros estão raramente corrompidos.

Você pode combinar opções de consistência como no exemplo a seguir que faz uma verificação rápida na tabela para ve se ela foi fechada corretamente:

CHECK TABLE test_table FAST QUICK;

NOTA: em alguns casos CHECK TABLE irá alterar a tabela! Isto acontece se a tabela estiver marcada como 'corrupted' (corrompida) ou 'not closed properly' (não foi fechada corretamente) mas o CHECK TABLE não encontrar não encontrar nenhum problema na tabela. Neste caso, CHECK TABLE irá marcar a tabela como ok.

Se uma tabela estiver corrompida, é preferível que seja um problema nos índices e não na parte de dados. Todos os tipos de consistência acima sempre confere os índices e deve então encontrar a maioria dos erros.

Se você só quiser conferir uma tabela que acredita estar ok, você não deve utilizar nenhuma opção para o comando check ou utilizar a opção QUICK. O último deve ser utilizado quando você estiver com pressa e o rísco do QUICK não encontrar um erro no arquivo de dados for mínimo (Na maioria dos casos o MySQL pode encontrar, sob utilização normal, qualquer erro no arquivo de dados. Se isto ocorrer, então a tabela será marcada como 'corrupted', neste caso a tabela não poderá ser utilizada até ser reparada).

FAST e CHANGED são normalmente chamados a partir de um script (um exemplo é ser executado a partir do cron) Se você desejar conferir suas tabelas de tempos em tempos. Na maioria dos casos, o FAT é uma opção melhor que CHANGED. (O único caso em que isto não acontece é quando você suspeita que encontrou um bug no código do MyISAM.).

EXTENDED deve ser utilizado somente depois de ter executado um check normalmente, mas continuar obtendo erros de uma tabela quando o MySQL tenta atualizar um registro ou encontrar um registro pela chave (isto seria muito difícil ocorrer caso uma conferência normal tenha executado com sucesso!).

Alguns problemas relatados por CHECK TABLE, não podem ser corrigidas automaticamente:

  • Found row where the auto_increment column has the value 0.

    Isto significa que você possui um registro na tabela onde o campo índice que utiliza o recurso auto_increment contem o valor 0. (É possível criar um registro onde a coluna de auto incremento seja 0 definindo explicitamente 0 em uma instrução UPDATE).

    Isto não é exatamente um erro, mas pode causar problemas se você decidir descarregar a tabela e restaurá-la ou executar um ALTER TABLE na tabela. Neste caso a coluna de auto incremento irá alterar seu valor, de acordo com as regras das colunas de auto incremento, que pode causar problemas como um erro de chave duplicada.

    Para se livrar do alerta, basta executar uma instrução UPDATE para configurar a coluna para algum outro valor diferente de 0.

4.5.5. Sintaxe do REPAIR TABLE

REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLE funciona somente em tabelas MyISAM e é a mesma coisa que executar myisamchk -r nome_tabela na tabela.

Normalmente você nunca deve executar este comando, mas se um disastre ocorrer você vai precisar recuperar seus dados de uma tabela MyISAM utilizando REPAIR TABLE. Se as suas tabelas estiverem muito corrompidas, você deve encontrar a razão, para eleiminar a necessidade de se usar REPAIR TABLE! Veja mais informações sobre isto na Seção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”. Veja mais informações sobre isto na Seção 7.1.3, “Problemas com Tabelas MyISAM.

REPAIR TABLE repara uma tabela possivelmente corrompida. O comando retorna uma tabela com as seguintes colunas:

ColunaValor
TableNome da Tabela
OpSempre repair
Msg_typeUm dos seguintes: status, error, info ou warning
Msg_textA mensagem

Note que a instrução pode produzir várias linhas de informações para cada tabela recuperada. A ultima linha será de Msg_type status e normalmente deve exibir OK. Se o retorno não for OK, você pode tentar reparar a tabela com myisamchk -o, já que REPAIR TABLE ainda não implementa todas as opções de myisamchk. Futuramente iremos torná-lo mais flexível.

Se o parâmetro QUICK for especificado, REPAIR tenta reparar somente a árvore de índices.

Se você utilizar EXTENTED, o MySQL criará o índice, registro a registro em vez de criar um índice de uma vez com ordenação; Isto pode ser melhor que a ordenação em chaves de tamanho fixo se você tiver grandes chaves do tipo char() que compactam muito bem.

No MySQL 4.0.2, existe um modo USE_FRM para REPAIR. Use-o se o arquivo .MYI estiver faltando ou o seu cabeçalho estiver corrompido. Neste modo o MySQL recriará a tabela, usando a informação do arquivo .frm. Este tipo de reparo não pode ser feito com myisamchk.

Aviso: Se o mysqld morre durante um REPAIR TABLE, é essencial que você faça imediatamente outro REPAIR na tabela antes de executar qualquer outro comando nela. (Claro que é sempre bom inciar com um backup). No pior caso você pode ter um novo arquivo de índice limpo sem informação sobre o arquivo de dados e quando você executar o próximo comando o arquivo de dados pode ser sobreescrito. Isto não é um cenário desejável, mas possível.

Antes do MySQL 4.1.1, o comando REPAIR não era gravado no log binário. Desde o MySQL 4.1.1. eles são escritos no log binário a menos que a palavra chave opcional NO_WRITE_TO_BINLOG (ou seu alias LOCAL) seja usada.

4.5.6. Utilizando myisamchk para Manutenção de Tabelas e Recuperação em Caso de Falhas

A partir do MySQL versão 3.23.13 você pode mandar verificar as tabelas MyISAM com o comando CHECK TABLE. Veja mais informações sobre isto na Seção 4.5.4, “Sintaxe de CHECK TABLE. Pode-se reparar tabelas com o comando REPAIR TABLE. Veja mais informações sobre isto na Seção 4.5.5, “Sintaxe do REPAIR TABLE.

Para verificar/reparar tabelas MyISAM (.MYI e .MYD) você deve utilizar o utilitário myisamchk. Para consistir/reparar tabelas ISAM (.ISM e .ISD) você deve usar o utilitário isamchk. Veja mais informações sobre isto na Capítulo 7, Tipos de Tabela do MySQL.

No texto a seguir iremos comentar sobre o myisamchk, mas tudo também se aplica ao antigo isamchk.

Você pode utilizar o utilitário myisamchk para obter informações sobre suas tabelas de bancos de dados, verficá-las, repará-las ou otimizá-las. As seguintes seções descrevem como executar myisamchk (incluindo uma descrição de suas opções), como montar um calendário de manutenção, e como utilizar o myisamchk para executar suas várias funções.

Você pode, na maioria dos casos, utilizar o comando OPTIMIZE TABLES para otimizar e reparar tabelas, mas não é tão rápido e confiável (no caso real de erros fatais) como o mysisamchk. Por outro lado, OPTIMIZE TABLE é mais fácil de usar e você não tem que se preocupar com a recarrega das tabelas. Veja mais informações sobre isto na Seção 4.6.1, “Sintaxe de OPTIMIZE TABLE.

Embora os reparos realizados pelo myisamchk sejam bastante seguros, porém é sempre uma boa idéia fazer um backup dos dados ANTES de realizar um reparo (ou qualquer coisa que fará grandes alterações em alguma tabela)

4.5.6.1. Sintaxe do myisamchk

myisamchk é chamado desta forma:

shell> myisamchk [opções] nome_tabela

As opções especificam o que você deseja que o myisamchk faça. Elas são descritas abaixo. (Você também pode obter a lista das opções com myisamchk --help.) Sem opções, o myisamchk simplesmente checa sua tabela. Para obter maiores informações ou dizer ao myisamchk para tomar ações corretivas, especifique as opções descritas abaixo e nas seções seguintes.

nome_tabela é o nome da tabela do banco de dados que você deseja verificar/reparar. Se você executar o myisamchk em algum lugar diferente do diretório do banco de dados, você deve especificar o caminho para o arquivo, porque myisamchk não faz idéia de onde seu banco de dados se encontra. Na verdade, myisamchk não se importa se os arquivos estão localizados em um diretório de banco de dado; você pode copiar os arquivos que correspondem a uma tabela de banco de dados em outra localização e realizar neste outro lugar as operações corretivas.

Você pode nomear várias tabelas na linha de comando do myisamchk se você desejar. Você também pode especificar um nome como um arquivo de índice (com o sufixo .MYI), que lhe permite especificar todas tabelas em um diretório utilizando o padrão *.MYI. Por exemplo, se você está em um diretório de banco de dados, você pode checar todas as tabelas no diretório desta forma:

shell> myisamchk *.MYI

Se você não estiver no diretório do banco de dados, você pode verificar todas as tabelas existentes especificando o caminho para o diretório:

shell> myisamchk /caminho/para/banco_de_dados/*.MYI

Você pode verificar todas as tabelas em todos os bancos de dados especificando um meta caracter com o caminho para o diretório de banco de dados do MySQL:

shell> myisamchk /caminho/para/diretório_dados/*/*.MYI

A maneira recomendada para conferir todas as tabelas rapidamente é:

myisamchk --silent --fast /caminho/para/diretório_dados/*/*.MYI
isamchk --silent /caminho/para/diretório_dados/*/*.ISM

Se você quiser conferir todas as tabelas e reparar todas que estiverem corrompidas, pode utilizar linha a seguir:

myisamchk --silent --force --fast --update-state -O key_buffer=64M \
          -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
          /caminho/para/diretório_dados/*/*.MYI
isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M \
        -O read_buffer=1M -O write_buffer=1M /caminho/para/diretório_dados/*/*.ISM

A linha acima assume que você tem mais de 64 MB de memória livre.

Perceba que se você obter um erro do tipo:

myisamchk: warning: 1 clients is using or hasn't closed the table properly

Isto significa que você está tentando verificar uma tabela que está sendo atualizada por outro programa (como o servidor mysqld) que ainda não fechou o arquivo ou que finalizou sem fechar o arquivo corretamente.

Se o mysqld está em execução, você deve forçar o sincronimo e fechamento de todas tabelas com FLUSH TABLES e assegurar que ninguém mais esteja utilizando as tabelas quando for executar o myisamchk. No MySQL versão 3.23 a forma mais simples de evitar este problema é utilizar CHECK TABLE no lugar de myisamchk para verificar as tabelas.

4.5.6.2. Opções Gerais do myisamchk

myisamchk suporta as seguintes opções.

  • -# ou --debug=debug_options

    Saída do log de depuração. A string debug_options geralmente é 'd:t:o,nomearquivo'.

  • -? ou --help

    Exibe uma mensagem de ajuda e sai.

  • -O nome=opção, --set-variable=nome=opção

    Configura o valor de uma variável. Por favor note que as sintaxes --set-variable=nome=valor e -O name=value estão obsoletas desde o MySQL 4.0. Use --nome=valor. As variáveis possíveis e seus valores padrões para o myisamchk podem ser examinados com myisamchk --help

    VariávelValor
    key_buffer_size523264
    read_buffer_size262136
    write_buffer_size262136
    sort_buffer_size2097144
    sort_key_blocks16
    decode_bits9

    sort_buffer_size é utilizado quando as chaves são reparadas pela ordenação das chaves, que é o caso normal quando você utiliza --recover.

    key_buffer_size é utilizando quando você estiver conferindo a tabela com --extended-check ou quando as chaves são reparadas inserindo-as registro a registro na tabela (como com inserts normais). O reparo através de buffer de chaves (key buffer) é utilizado nos seguintes casos:

    • Se você utilizar --safe-recover.

    • Se os arquivos temporários necessários para ordenar as chaves forem maior que o dobro do tamanho de quando se criasse o arquivo de chaves diretamente. Isto é o caso quando se tem chaves CHAR, VARCHAR ou TEXT tao grandes quanto necessário pela ordenação para armazenar todas as chaves durante o processo. Se você tiver muito espaço temporário e puder forçar o myisamchk a reparar por ordenação você pode utilizar a opção --sort-recover.

    Reparação através do buffer de chaves (key buffer) economiza muito mais espaço em disco do que utilizando ordenação, mas é muito mais lenta.

    Se você deseja uma reparação mais rápida, configure as variáveis acima para cerca de 1/4 da sua memória disponível. Você pode configurar as variáveis para valores altos, pois somente um dos buffers acima será utilizado a cada vez.

  • -s ou --silent

    Modo discreto ou silencioso. Escreve a saída somente quando um erro ocorre. Você pode utilizar -s duas vezes (-ss) para deixar o mysisamchk mais silencioso.

  • -v ou --verbose

    Modo prolixo. Gera mais informação de saída. Ele pode ser utilizado com -d e -e. Utilize -v múltiplas vezes -vv, -vvv) para gerar mais saída!

  • -V ou --version

    Exibe a versão do myisamchk e sai.

  • -w ou, --wait

    No lugar de gerar um erro se a tabela estiver bloqueada, espere até que a tabela fique livre antes de continuar. Perceba que se você estiver utilizando mysqld na tabela com --skip-external-locking, a tabela só pode ser trancada por outro comadno myisamchk.

4.5.6.3. Opções de Verificação do myisamchk

  • -c ou --check

    Confere por erros na tabela. Esta é a operação padrão se você não estiver utilizando opções que a anulam.

  • -e ou --extend-check

    Verifica a tabela de forma completa (que é bastante lento se você tiver vários índices). Esta opção deve ser usada somente em casos extremos. Normalmente, myisamchk ou myisamchk --medium-check deve, na maioria dos casos, estar apto a encontrar quaisquer erros na tabela.

    Se você estiver utilizando --extended-check e tiver muita memória, você deve aumentar um pouco o valor de key_buffer_size!

  • -F ou --fast

    Verifica apenas tabelas que não foram fechadas corretamente.

  • -C ou --check-only-changed

    Verifica apenas tabelas que foram alteradas desde a última verificação.

  • -f ou --force

    Reinicia o myisamchk com -r (reparos) na tabela, se myisamchk encontrar quaisquer erros na tabela.

  • -i ou --information

    Exibe informações e estatísticas sobre a tabela que estiver sendo verificada.

  • -m ou --medium-check

    Mais rápido que extended-check, mas encontra somente 99.99% de todos os erros. Deve, entretando, ser bom o bastante para a maioria dos casos.

  • -U ou --update-state

    Armazena no arquivo .MYI quando a tabela foi verificada e se a tabela falhou. Isto deve ser utilizado para obter o benefício integral da opção --check-only-changed, mas você não deve utilizar esta opção se o servidor mysqld esta usando a tabela e o mysqld esta sendo executado com --skip-external-locking.

  • -T ou --read-only

    Não marca as tabelas como verificadas. Isto é útil se você utiliza o myisamchk para verificar uma tabela que esteja em uso por alguma outra aplicação que não utiliza bloqueios (como no mysqld --skip-external-locking).

4.5.6.4. Opções de Reparos do myisamchk

As seguintes opções são usadas se você iniciar o myisamchk com -r ou -o:

  • -B or --backup

    Faz um backup dos arquivos .MYD como filename-time.BAK

  • --correct-checksum

    Correct checksum information for table.

  • -D # ou --data-file-length=#

    Tamanho máximo do arquivo de dados (ao recriar arquivos de dados quando eles estão 'cheios').

  • -e ou --extend-check

    Tenta recuperar todos registros possíveis do arquivo de dados. Normalmente isto irá encontrar também várias linhas com lixo. Não utiliza esta opção a menos que esteja em desespero total.

  • -f ou --force

    Sobrescreve antigos arquivos temporários (nome_tabela,TMD) em vez de abortar.

  • -k # ou --keys-used=#

    Se você estiver utilizando ISAM, diz ao manipulador de tabelas do ISAM para atualizar somente os primeiros # índices. Se você estiver utilizando MyISAM, informa quais chaves usar, onde cada bit seleciona uma chave (a primeira chave possui o bit 0). Isto pode ser utilizado para inserções mais rápidas! Índices desativados podem ser reativados utilizando myisamchk -r.

  • -l ou --no-symlinks

    Não segue links simbólicos. Normalmente o myisamchk repara a tabela para qual um link simbólico aponta. Esta opção não existe no MySQL 4.0 pois o MySQL 4.0 não irá remover links simbólicos durante os reparos.

  • -p or --parallel-recover

    Usa a mesma técnica que -r e -n, mas cria todas as chaves em paralelo, em threads diferentes. A opção foi adicionada no MySQL 4.0.2. Este código é alfa. Use por sua conta e risco!

  • -r ou --recover

    Pode concertar quase tudo excetos chaves únicas que não são únicas (Que é um erro extremamente indesejável com tabelas ISAM/MyISAM). Se você deseja recuperar uma tabela, esta é primeira opção a ser tentada. Somente se o myisamchk relatar que a tabela não pode ser recuperada pelo -r você deve tentar então a opção -o. (Perceba que no caso indesejável de -r falhar, o arquivo de dados continuará intacto.) Se você possui muita memória, você deve aumentar o tamanho de sort_buffer_size!

  • -o ou --safe-recover

    Utiliza um antigo método de recuperação (le através de todos registros na ordem e atualiza todas as árvores de índices baseado nos registros encontrados); esta opção é muito mais lenta que -r, mas pode tratar vários casos indesejáveis que o -r não consegue tratar. Este método de recuperação também utiliza muito menos espaço em disco que -r. Normalmente sempre se deve tentar, primeiro, um reparo com -r, e somente se ele falhar, usar -o.

    Se você possuir muita memória, você deve aumentar o tamanho de sort_buffer_size!

  • -n ou --sort-recover

    Força o uso de ordenação do myisamchk para resolver as chaves mesmo se os arquivos temporários forem muito grandes.

  • --character-sets-dir=...

    Diretório onde conjuntos de caracteres são armazenados.

  • --set-character-set=name

    Altere o conjunto de caracteres usado pelo índice

  • .t ou --tmpdir=path

    Caminho para armazenar arquivos temporários. Se isto não for configurado, myisamchk irá usar a variável de ambiente TMPDIR para isto. A partir do MySQL 4.1, tmpdir pode ser configurado com uma lista de caminhos separados por dois pontos : (ponto e virgula ; no Windows). Eles serão usado da forma robin-round.

  • -q ou --quick

    Reparo rápido sem modificar o arquivo de dados. Pode ser fornecido um segundo -q para forçar o myisamchk para modificar o arquivo de dados original no caso de chaves duplicadas.

  • -u ou --unpack

    Descompacta arquivo empacotado com o myisampack.

4.5.6.5. Outras Opções do myisamchk

Outras ações que o myisamchk pode fazer, alem de reparar e verificar tabelas:

  • -a or --analyze

    Analiza a distribuição das chaves. Isto aumenta o desempenho de join habilitando o otimizador de joins para melhor escolher em qual ordem ele deve unir as tabelas e quais chaves ele deve usar: myisamchk --describe --verbose table_name' ou usar SHOW KEYS no MySQL.

  • -d or --description

    Exibe alguma informação sobre tabela.

  • -A or --set-auto-increment[=value]

    Força que AUTO_INCREMENT com um valor maior ou igual a este. Se nenhum valor é dado, então define o próximo valor AUTO_INCREMENT com o maior valor usado para a chave automatica + 1.

  • -S or --sort-index

    Ordene o bloco da árvore índice do mais alto para o mais baixo. Isto otimizará as buscas e tornará a pesquisa em tabela através da chave mais rápida.

  • -R or --sort-records=#

    Ordena o registro de acordo com um índice. Isto faz com que seus dados estejam muito mais localizados e pode aumentar a velocidade das operações SELECT e ORDER BY neste índice. (Pode ser bem lento na primeira ordenação!) Para encontrar um número de índices da tabela, use SHOW INDEX, que exibe os índices de um tabela na mesma ordem que o myisamchk os vê. Índices são números que se iniciam com 1.

4.5.6.6. Uso de Memória do myisamchk

Alocação de memória é importante quando você executa o myisamchk. myisamchk não utiliza mais memória do que você especifica com a opção -O. Se você irá utilizar o myisamchk em grandes arquivos, você deve decidir primeiro quanta memória deseja usar. O valor padrão é utilizar somente 3MB para correções. Utilizando valores maiores, o myisamchk pode operar mais rapidamente. Por exemplo, se você tiver mais que 32M de memória RAM, você pode utilizar opções tais como esta (em adição às várias outras que podem ser especificadas):

shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

Utilizando -O sort=16M provavelmente é suficiente para a maioria dos casos.

Certiffique-se que o myisamchk utiliza arquivos temporários em TMPDIR. Se TMPDIR aponta para um sistema de arquivos em memória, você pode facilmente obter erros de memória. Se isto acontecer, configure TMPDIR para apontar para algum diretório com mais espaço e reinicie o myisamchk.

Quando reparando, o myisamchk também precisará de bastante espaço em disco:

  • Dobra-se o tamanho do arquivo de registros (o original e uma cópia). Este espaço não é necessário se for feito um reparo com --quick, já que neste caso somente o arquivo de índices será recriado. Este espaço é necessário no mesmo disco que se encontra o arquivo de registros original!

  • Espaço para o novo arquivo de índice que substitui o antigo. O arquivo de índices antigo é truncando no início, portanto, normalmente este espaço é ignorado. Este espaço é necessário no mesmo disco que o arquivo de índice original!

  • Quando utilizando --recover ou --sort-recover (mas não quando usando --safe-recover, será necessário espaço para um buffer de ordenação de: (maior_chave + tamanho_do_ponteiro_de_registro)*número_de_registros * 2. Você pode conferir o tamanho das chaves e o tamanho_do_ponteiro_de_registro com myisamchk -dv tabela. Este espaço é alocado no disco temporário (especificado por TMPDIR ou --tmpdir=#).

Se você tiver um problema com espaço em disco durante o reparo, pode-se tentar usar --safe-recover em vez de --recover.

4.5.6.7. Uso do myisamchk para Recuperação em Caso de Falhas

Se você executa o mysqld com a opção --skip-external-locking (que é o padrão em alguns sistemas, como o Linux), você não pode utilizar com segurança o myisamchk para conferir uma tabela se o mysqld estiver utilizando a mesma tabela. Se você pode ter certeza que ninguém está acessando as tabelas através do mysqld enquanto você executa o myisamchk, você só tem que executar o mysqladmin flush-tables antes de iniciar a verificação das tabelas. Se você não tem certeza, então você deve desligar o mysqld enquanto verifica as tabelas. Se você executa o myisamchk enquanto o mysqld estiver atualizando as tabelas, você pode obter um altera que a tabela está corrompida mesmo se não estiver.

Se você não estiver utilizando --skip-external-locking, pode usar o myisamchk para conferir as tabelas a qualquer hora. Enquanto você faz isto, todos os clientes que tentarem atualizar a tabela irão esperar até que o myisamchk esteja pronto, antes de continuar.

Se você utilizar o myisamchk para reparar ou otimizar tabelas, você DEVE sempre assegurar que o servidor mysqld não esteja utilizando a tabela (Isto também aplica se você utiliza --skip-external-locking). Se você não desligar o mysql, você deve, pelo menos, fazer um mysqladmin flush-tables antes de executar o myisamchk. Suas tabelas podem estar corrompidos se o servidor e o myisamchk acessarem a tabela simultaneamente.

Este capítulo descreve como checar e lidar com dados corrompidos nos bancos de dados MySQL. Se suas tabelas corromperem com frequência deve ser encontrada a razão para isto! Veja mais informações sobre isto na Seção A.4.1, “O Que Fazer Se o MySQL Continua Falhando”.

A seção de tabelas MyISAM contêm motivos do porque uma tabela pode estar corrompida. See Seção 7.1.3, “Problemas com Tabelas MyISAM.

Quando se realizar recuperação devido a falhas, é importante entender que cada tabela nome_tabela em um banco de dados corresponde a tres arquivos no diretório do banco de dados:

ArquivoPropósito
nome_tabela.frmArquivo com definições da tabela (form)
nome_tabela.MYDArquivo de dados
nome_tabela.MYIArquivo de índices

Cada um destes três tipos de arquivos está sujeito a corrupção de várias formas, mas problemas ocorrem mais frequentemente em arquivos de dados e índices.

O myisamchk trabalha criando uma cópia do arquivo de dados .MYD linha a linha. Ele termina o estágio de reparos removendo o antigo arquivo .MYD e renomeando o novo arquivo com nome original. Se for utilizada a opção --quick, myisamchk não cria um arquivo .MYD temporário, mas assume que o arquivo .MYD está correto e somente gera um novo arquivo índice sem mexer no arquivo de dados. Isto é seguro, pois o myisamchk detecta automaticamente se o arquivo .MYD está corrompido e aborda o reparo neste caso. Você pode também fornecer duas opções --quick para o myisamchk. Neste caso, o myisamchk não aborta em alguns erros (como chaves duplicadas) mas tenta resolvê-los modificando o arquivo .MYD. Normalmente o uso de duas opções --quick é útil somente se você tiver muito pouco espaço em disco para realizer um reparo normal. Neste caso você deve pelo menos fazer um backup antes de executar o myisamchk.

4.5.6.8. Como Verificar Erros em Tabelas

Para conferir uma tabela MyISAM, utilize os seguintes comandos:

  • myisamchk nome_tabela

    Encontra 99.99% de todos os erros. O que ele não pode encontrar é corrompimento que envolva SOMENTE o arquivo de dados (que não é comum). Se você desejar conferir uma tabela, você deve executar normalmente o myisamchk sem opções ou com as opções -s ou --silent.

  • myisamchk -m nome_tabela

    Encontra 99.999% de todos os erros. Ele verifica primeiramente erros em todas as entradas do índice e então le todos os registros. Ele calcula um checksum para todas as chaves nos registros e verifica se o checksum é o mesmo que o checksum das chaves na árvore de índices.

  • myisamchk -e nome_tabela

    Realiza a verificação completa de todos os dados (-e significa ``conferência extendida''). Ele faz uma conferência lendo todas as chaves de cada registro para verificar se eles realmente apontam para o registro correto. Isto pode demorar MUITO tempo em uma tabela grande com várias chaves. myisamchk normalmente irá parar depois do primeiro erro que encontrar. Se você deseja obter mais informações, pode adicionar a opção --verbose (-v). Isto faz o myisamchk continuar a percorrer a tabela até um máximo de 20 erros. Em utilização normal, um simples myisamchk (sem argumentos além do nome da tabela) é suficiente.

  • myisamchk -e -i nome_tabela

    Como o comando anterior, mas a opção -i diz ao myisamchk para exibir algumas informações estatísticas também.

4.5.6.9. Como Reparar Tabelas

Na seção seguinte nós só falaremos do uso do myiasmchk em tabelas MyISAM (extensões .MYI e .MYD). Se você estiver usando tabelas ISAM (extensões .ISM e .ISD), você deve usar a ferramenta isamchk.

A partir do MySQL versão 3.23.14, você pode reparar tabelas MyISAM com o comando REPAIR TABLE. See Seção 4.5.5, “Sintaxe do REPAIR TABLE.

Os sintomas de uma tabela corrompida incluem pesquisas que abortam inesperadamente e erros como estes:

  • nome_tabela.frm is locked against change

  • Can't find file nome_tabela.MYI (Errcode: ###)

  • Unexpected end of file

  • Record file is crashed

  • Got error ### from table handler

    Para obter mais informações sobre o erro você pode executar perror ###. Aqui estão os erros mais comuns que indicam um problema com a tabela:

    shell> perror 126 127 132 134 135 136 141 144 145
    126 = Index file is crashed / Wrong file format
    127 = Record-file is crashed
    132 = Old database file
    134 = Record was already deleted (or record file crashed)
    135 = No more room in record file
    136 = No more room in index file
    141 = Duplicate unique key or constraint on write or update
    144 = Table is crashed and last repair failed
    145 = Table was marked as crashed and should be repaired
    

    Note que o erro 135 (não mais no arquivo de registro), não é um erro que pode ser corrigido por um simples reparo. Neste caso você deve fazer:

    ALTER TABLE tabela MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
    

    Você também pode usar esta técnica para o erro 136 (não mais no arquivo de índice).

Em outros casos, você deve reparar suas tabelas. myisamchk pode normalmente detectar a maioria dos problemas que ocorrem.

O processo de reparo involve até quatro estágios, descritos abaixo. Antes de começar, você deve mudar para o diretório do banco de dados e conferir as permissões dos arquivos de tabelas. Tenha certeza que eles possam ser lidos pelo usuário do Unix com o qual mysqld é executado (e para você, porque você precisa acessar os arquivos que está conferindo). Se não estiverem, você precisa alterar os arquivos, eles também devem ter a permissão de escrita para você.

Se você estiver utilizando o MySQL versão 3.23.16 e superior, você pode (e deve) usar os comandos CHECK e REPAIR para conferir e corrigir tabelas MyISAM. See Seção 4.5.4, “Sintaxe de CHECK TABLE. See Seção 4.5.5, “Sintaxe do REPAIR TABLE.

A seção do manual sobre manutenção de tabelas inclui as opções para isamchk/myisamchk. See Seção 4.5.6, “Utilizando myisamchk para Manutenção de Tabelas e Recuperação em Caso de Falhas”.

A seguinte seção são para os casos onde o comando acima falhar ou se você desejar usar os recursos extendidos que o isamchk e myisamchk fornecem.

Se você for reparar uma tabela da linha de comandos, deve primeiro desligar o servidor mysqld. Perceba que quando você executa mysqladmin shutdown em um servidor remoto, o servidor mysqld irá continuar funcionando por um tempo depois do mysqladmin retornar, até que todas as queries parem e todas as chaves sejam descarregadas no disco.

Estágio 1: Verificando suas tabelas

Execute myisamchk *.MYI ou myisamchk -e *.MYI se você tiver tempo disponível. Utilize a opção -s (silencioso) para suprimir informações desnecessárias.

Se o servidor mysqld parar, deve ser utilizada a opção --update para dizer ao myisamchk marcar a tabela como 'checada'.

Você deve reparar somente as tabelas em que o myisamchk indicar um erro. Para tais tabelas, vá para o estágio 2.

Se você obter erros estranhos na verficação (como nos erros out of memory), ou se o myisamchk quebrar, vá para o estágio 3.

Estágio 2: Reparo simples e seguro

NOTA: Se você deseja que os reparos sejam mais rápidos, devem ser usadas as opções: -O sorf_buffer=# -O key_buffer=# (onde # seria 1/4 da memória disponível) para todos comandos isamchk/myisamchk.

Primeiro, tente usar myisamchk -r -q nome_tabela (-r -q significa ``modo de recuperação rápida''). Ele tentará reparar o arquivo de índice sem mexer no arquivo de dados. Se o arquivo de dados estiver normal e os links apagados apontam nas localizações corretas dentro do arquivo de dados, isto deve funcionar e a tabela será corrigida. Inicie o reparo da próxima tabela. Outra maneira seria utilizar os seguintes procedimentos:

  1. Faça um backup do arquivo de dados antes de continuar.

  2. Utilize myisamchk -r nome_tabela (-r significa modo de ``recuperação''). Isto removerá registros incorretos e deletados do arquivo de dados e reconstroi o arquivo de índices.

  3. Se o passo anterior falhar, utilize myisamchk --safe-recover nome_tabela. O modo de recuperação segura utiliza um metódo de recuperação antiga que trata de alguns casos que o modo de recuperação comum não consegue (porém é mais lento).

Se você obter erros estranhos no reparo (como em erros out of memory), ou se o myisamchk falhar, vá para o estágio 3.

Estágio 3: Reparo difícil

Você só deve atingir este estágio se o primeiro bloco de 16K do arquivo de índice estiver destruído ou conter informações incorretas, ou se o arquivo de índice não existir. Neste caso, é necessário criar um novo arquivo de índice. Faça como a seguir:

  1. Mova o arquivo de dados para algum lugar seguro.

  2. Use o arquivo de descrição de tabelas para criar novos arquivos (vazios) de dados e índices:

    shell> mysql nome_bd
    mysql> SET AUTOCOMMIT=1;
    mysql> TRUNCATE TABLE nome_tabela;
    mysql> quit
    

    Se sua versão do MySQL não possuir TRUNCATE TABLE, utilize DELETE FROM nome_tabela.

  3. Copie o antigo arquivo de dados de volta para o novo arquivo de dados criado. (Não só mova o antigo arquivo de volta para o novo arquivo; você deve uma cópia no caso de algo der errado.)

Volte ao estágio 2. myisamchk -r -q deve funcionar agora. (Isto não deve ser um loop eterno.)

No MySQL 4.0.2 você também pode utilizar REPAIR ... USE_FRM o qual realiza todo o procedimento automaticamente.

Estágio 4: Reparo muito difícil

Você deve atingir este estágio somente se o arquivo de descrição também falhar. Isto nunca deve acontecer, porque o arquivo de descrição não é alterado depois da tabela ser criada:

  1. Restaure o arquivo de descrição de um backup e volte ao estágio 3. Você pode também restaurar o arquivo de índice e voltar ao estágio 2. No último caso, você deve iniciar com myisamchk -r.

  2. Se você não tem um backup mas sabe exatamente como a tabela foi criada, crie uma cópia da tabela em outro banco de dados. Remova o novo arquivo de dados, e então mova a descrição e arquivos de índice do outro banco de dados para o banco de dados com problemas. Isto lhe fornece um novo arquivos índice e descrição, mas mantêm o arquivo de dados da mesma forma. Volte ao estágio 2 e tente reconstruir o arquivo de índices.

4.5.6.10. Otimização de Tabelas

Para agrupar registros fragmentados e eliminar perda de espaço resultante de remoções ou atualizações de registros, execute myisamchk no modo de recuperação:

shell> myisamchk -r nome_tabela

Você pode otimizar uma tabela da mesma forma utilizando a instrução SQL OPTIMIZE TABLE. OPTIMIZE TABLE faz o reparo de tabelas, analisa chaves e também ordena a árvore de índices para fazer pesquisas por chave mais rápidas. Também não existem possibilidade de interação não desejável entre o utilitário e o servidor, porque o servidor faz todo o trabalho quando você utiliza OPTIMIZE TABLE. Veja mais informações sobre isto na Seção 4.6.1, “Sintaxe de OPTIMIZE TABLE.

myisamchk também tem um número de outras opção que podem ser usadas para melhorar a performance de uma tabela:

  • -S, --sort-index

  • -R index_num, --sort-records=index_num

  • -a, --analyze

Para uma descrição completa da opção. See Seção 4.5.6.1, “Sintaxe do myisamchk.

4.5.7. Configurando um Regime de Manutenção das Tabelas

A partir do MySQL Versão 3.23.13, você pode conferir tabelas MyISAM com o comando CHECK TABLE. Veja mais informações sobre isto na Seção 4.5.4, “Sintaxe de CHECK TABLE. Você pode reparar tabelas com o comando REPAIR TABLE. Veja mais informações sobre isto na Seção 4.5.5, “Sintaxe do REPAIR TABLE.

É uma boa idéia verificar as tabelas regularmente em vez de esperar que ocorram problemas. Para propósitos de manutenção você pode utilizar o myisamchk -s para verificar as tabelas. A opção -s (abreviação de --silent) faz com que o myisamchk execute em modo silencioso, exibindo mensagens somente quando ocorrem erros.

É também uma boa idéia verificar as tabelas quando o servidor inicia. Por exemplo, sempre que a máquina reinicia no meio de uma atualização, você normalmente precisará conferir todas as tabelas que podem ter sido afetadas. (Isto é uma``tabela com falhas esperadas''.) Você pode adicionar um teste ao mysqld_safe que executa myisamchk para conferir todas tabelas que foram modificadas durante as últimas 24 horas se existir um arquivo .pid (process ID) antigo depois do último reboot. (O arquivo .pid é criado pelo mysqld quando ele inicia e removido quando ele termina normalmente. A presença de um arquivo .pid durante a inicialização do sistema indica que o mysqld terminou de forma anormal.)

Um teste ainda melhor seria verificar qualquer tabela cuja a data da última modificação é mais recente que a do arquivo .pid.

Você também deve verificar suas tabelas regularmente durante a operação normal do sistema. Na MySQL AB, nós executamos uma tarefa agendada cron para conferir todas nossas tabelas importantes uma vez por semana utilizando uma linha com esta no arquivo crontab:

35 0 * * 0 /diretório/do/myisamchk --fast --silent /diretório/de/dados/*/*.MYI

Isto exibe informações sobre tabelas com falhas para que possamos examiná-las e repará-las quando necessário.

Como nós não estamos tendo tabelas com falhas inesperadas (tabelas corrompidas por razões diferentes de problemas de hardware) por vários anos (isto realmente é verdade), uma vez por semana é mais que suficiente para nós.

Nós recomendamos que para iniciar, você execute myisamchk -s a cada noite em todas as tabelas que foram atualizadas durantes as últimas 24 horas, até que você confie no MySQL como nós confiamos.

Normalmente você não precisará de tanta manutenção em suas tabelas MySQL. Se você estiver alterando tabelas com registros de tamanho dinâmico (tabelas com colunas VARCHAR, BLOB ou TEXT) ou tem tabelas com vários registros apagados você pode desejar de tempos em tempos (uma vez ao mês?) desfragmentar/recuperar espaço das tabelas.

Você pode fazer isto utilizando OPTIMIZE TABLE nas tabelas em questão ou se você puder desligar o servidor mysqld por um tempo faça:

isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
myisamchk -r --silent --sort-index  -O sort_buffer_size=16M */*.MYI

4.5.8. Obtendo Informações sobre as Tabelas

Para obter uma descrição de uma tabela ou estatísticas sobre ela, utilize os comandos mostrados abaixo, nós explicaremos algumas das informações em mais detalhes posteriormente:

  • myisamchk -d nome_tabela Executa o myisamchk no ``modo descritivo'' para produzir uma descrição de sua tabela. Se você iniciar o servidor MySQL utilizando a opção --skip-locking, myisamchk pode relatar um erro para uma tabela que está sendo atualizada enquanto é executado. Entretanto, como o myisamchk não altera a tabela no modo de descrição, não existem riscos de destruição de dados.

  • myisamchk -d -v nome_tabela Para produzir mais informações sobre o que myisamchk está fazendo, adicione -v para solicitar a execução em modo verbose.

  • myisamchk -eis nome_tabela Exibe somente as informações mais importantes de uma tabela. Ele é lento porque é necessário ler a tabela inteira.

  • myisamchk -eiv nome_tabela Isto se parece com -eis, mas lhe diz o que está sendo feito.

Exemplo da saída de myisamchk -d

MyISAM file:     company.MYI
Record format:   Fixed length
Data records:    1403698  Deleted blocks:         0
Recordlength:    226

table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text

Exemplo da saída de myisamchk -d -v :

MyISAM file:         company
Record format:       Fixed length
File-version:        1
Creation time:       1999-10-30 12:12:51
Recover time:        1999-10-31 19:13:01
Status:              checked
Data records:           1403698  Deleted blocks:              0
Datafile parts:         1403698  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length: 3791650815  Max keyfile length: 4294967294
Recordlength:               226

table description:
Key Start Len Index   Type                  Rec/key     Root Blocksize
1   2     8   unique  double                      1 15845376      1024
2   15    10  multip. text packed stripped        2 25062400      1024
3   219   8   multip. double                     73 40907776      1024
4   63    10  multip. text packed stripped        5 48097280      1024
5   167   2   multip. unsigned short           4840 55200768      1024
6   177   4   multip. unsigned long            1346 65145856      1024
7   155   4   multip. text                     4995 75090944      1024
8   138   4   multip. unsigned long              87 85036032      1024
9   177   4   multip. unsigned long             178 96481280      1024
    193   1           text

Exemplo da saída de myisamchk -eis:

Checking MyISAM file: company
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%

Records:          1403698    M.recordlength:     226
Packed:             0%
Recordspace used:     100%   Empty space:          0%
Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966

Exemplo da saída de myisamchk -eiv:

Checking MyISAM file: company
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%

- check records and index references
[LOTS OF ROW NUMBERS DELETED]

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798

Aqui estão os tamanhos dos arquivos de dados e índices para a tabela utilizada nos exemplos anteriores:

-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM

Explicações para os tipos de informações que o myisamchk produz são fornecidas abaixo. O ``keyfile'' é o arquivo de índices. ``Registro'' e ``linha'' são sinônimos:

  • ISAM file Nome do arquivo (índice) ISAM.

  • Isam-version Versão do formato ISAM. Atualmente sempre 2.

  • Creation time Quando o arquivo de dados foi criado.

  • Recover time Quando foi a última vez que o arquivo de índices/dados foi reconstruído.

  • Data records Quantos registros existem na tabela.

  • Deleted blocks Quantos blocos apagados continuam alocando espaço. Você pode otimizar sua tabela para minimizar este espaço. Veja mais informações sobre isto na Seção 4.5.6.10, “Otimização de Tabelas”.

  • Datafile: Parts Para formato de registros dinâmicos, isto indica quantos blocos de dados existem. Para uma tabela otimizada sem registros fragmentados, isto é o mesmo que Data records.

  • Deleted data Quantos bytes de dados deletados não recuperados existem. Você pode otimizar sua tabela para minimizar este espaço. Veja mais informações sobre isto na Seção 4.5.6.10, “Otimização de Tabelas”.

  • Data file pointer O tamanho do ponteiro do arquivo de dados, em bytes. Ele normalmente possui 2, 3, 4 ou 5 bytes. A maioria das tabelas trabalham com 2 bytes, mas isto ainda não pode ser controlado pelo MySQL ainda. Para tabelas fixas, isto é um endereço de registro. Para tabelas dinâmicas, isto é um endereço de byte.

  • Keyfile pointer O tamanho de um ponteiro de arquivo de índices, em bytes. Ele normalmente possui 1, 2 ou 3 bytes. A maioria das tabelas trabalham com 2 bytes, mas isto é calculado automaticamente pelo MySQL. Ele é sempre um endereço de bloco.

  • Max datafile length Qual tamanho o arquivo de dados (arquivos .MYD) pode atingir, em bytes.

  • Max keyfile length Qual tamanho o arquivo de índices (.MYI pode atingir, em bytes.

  • Recordlength Quanto espaço cada registro ocupa, em bytes.

  • Record format O formato utilizado para armazenar as linhas da tabelas. Os exemplos anteriores abaixo utilizam Fixed length (tamanho fixo). Outros valores possíveis são Compressed(compactado) e Packed(empacotado).

  • table description Uma lista de todas as chaves na tabela. Para cada chave, alguma informação de baixo nível é apresentada:

    • Key

      O Número desta chave.

    • Start

      Onde, no registro, esta parte do índice inicia.

    • Len

      Qual o tamanho desta parte do índice. Para números empacotados, isto deve sempre ser o tamanho total da coluna. Para strings, deve ser mais curto que o tamanho total da coluna indexada, porque você pode indexar um prefixo de uma coluna string.

    • Index

      unique ou multip. (multiplos). Indica se um valor pode ou não exisitir várias vezes neste índice.

    • Type

      Que tipo de dados esta parte do índice tem. Isto é um tipo de dados ISAM com as opções packed, stripped ou empty.

    • Root

      Endereço do bloco de índice raiz.

    • Blocksize

      O tamanho de cada bloco de índice. O tamanho padrão é 1024, mas o valor pode ser alterado na compilação.

    • Rec/key

      Este é um valor estatístico utilizado pelo otimizador. Ele diz quantos registros existem por valor para esta chave. Uma chave única sempre tem um valor de 1. Ele pode ser atualizado depois que uma tabela é carregada (ou muito alterada) com myisamchk -a. Se isto não for completamente atualizado, um valor padrão de 30 é fornecido.

  • No primeiro exemplo acima, a nona chave é uma chave multi partes com duas partes.

  • Keyblocks used Qual o percentual de bloco de chaves são usados. Como a tabela usada nos exemplos foi reorganizada com myisamchk, os valores são muito altos (muito próximos do máximo teórico).

  • Packed O MySQL tenta empacotar chaves com um sufixo comum. Isto pode ser usado somente para chaves CHAR/VARCHAR/DECIMAL. Para strings grandes como nomes, isto pode reduzir significativamente o espaço utilizado. No terceiro exemplo acima, a quarta chave possui 10 caracteres e uma redução de 60% no espaço é obtida.

  • Max levels Qual a profundidade da árvore-B para esta chave. Grandes tabelas com chaves longas resultam em valores altos.

  • Records Quantos registros existem na tabela.

  • M.recordlength A média de tamanho do registro. Para tabelas com registros de tamanho fixo, isto é o tamanho exato do registro.

  • Packed O MySQL corta espaços do final de strings. O valor Packed indica o percentual de economia alcançado fazendo isto.

  • Recordspace used Qual percentual do arquivo de dados é usado.

  • Empty space Qual percetual do arquivo de dados não é usado.

  • Blocks/Record Número médio de blocos por registro (isto é, de quantos links um registro fragmentado é composto). Sempre será 1 para tabelas de formato fixo. Este valor deve permanecer o mais próximo possível de 1.0. Se ele aumentar, você pode reorganizar a tabela com myisamchk. See Seção 4.5.6.10, “Otimização de Tabelas”.

  • Recordblocks Quantos blocos (links) são utilizados. Para formatos fixos, este é o mesmo que o número de registros.

  • Deleteblocks Quantos blocos (links) foram excluídos.

  • Recorddata Quantos bytes no arquivo de dados são usados.

  • Deleted data Quantos bytes no arquivo de dados foram apagados (sem uso).

  • Lost space Se um registro é atualizado para um tamanho menor, algum espaço é perdido. Isto é a soma de todas estas perdas, em bytes.

  • Linkdata Quando o formato de tabela dinâmica é utilizado, fragmentos de registros são ligados com ponteiros (4 a 7 bytes cada). Linkdata é a soma do montante de armazenamento utilizado por todos estes ponteiros.

Se uma tabela foi compactada com myisampack, mysiamchk -d exibe informações adicionais sobre cada coluna da tabela. Veja Seção 4.8.4, “myisampack, O Gerador de Tabelas Compactadas de Somente Leitura do MySQL”, para um exemplo desta informação e uma descrição do que ela significa.

4.6. Adiministração do Banco de Dados e Referência de Linguagem

4.6.1. Sintaxe de OPTIMIZE TABLE

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name]...

OPTIMIZE TABLE deve ser usado se você apagou uma grande parte de uma tabela ou se você fez várias alterações à uma tabela com registros de tamanho variável (tabelas que tenham campos do tipo VARCHAR, BLOB ou TEXT). Registros apagados são mantidos em uma lista de ligações e operações INSERT subsequentes reutilizam posições de registros antigos. Você pode utilizar OPTIMIZE TABLE para reclamar o espaço inutilizado e para desfragmentar o arquivo de dados.

Na maioria da configurações você não tem que executar OPTIMIZE TABLE. Mesmo se você fizer diversas atualizações para registros de tamanhos variáveis não é desejável que você precise fazer isto mais que uma vez por mês/semana e apenas em determinadas tabelas.

No momento OPTIMIZE TABLE só funciona em tabelas MyISAM e BDB. Para tabelas BDB, OPTIMIZE TABLE é atualmente mapeado para ANALIZE TABLE. Veja mais informações sobre isto na Seção 4.6.2, “Sintaxe de ANALYZE TABLE.

Você pode ter a otimização de tabelas trabalhando em outros tipos de tabelas iniciando o mysqld com --skip-new ou --safe-mode, mas neste caso, OPTIMIZE TABLE é mapeado apenas para ALTER TABLE.

OPTIMIZE TABLE funciona da seguinte forma:

  • Se a tabela tem registros excluídos ou dividos, repara a tabela.

  • Se as páginas de índice não estão ordenas, ordene-as.

  • Se as estatísticas não estão atualizadas (e o reparo não pode ser feito ordenando o índice), atualize-as.

Perceba que a tabela estará bloqueada durante o tempo em que OPTIMIZE TABLE estiver executando.

Antes do MySQL 4.1.1, o OPTIMIZE comnado não gravava no log binário. Desde o MySQL 4.1.1 eles são escritos no log binário a menos que a palavra chave opcional NO_WRITE_TO_BINLOG (ou se alias LOCAL) seja usada.

4.6.2. Sintaxe de ANALYZE TABLE

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...]

Analisa e armazena a distribuição de chaves para a tabela. Durante a análise a tabela é bloqueada com uma trava de leitura. Isto funciona em tabelas MyISAM e BDB.

Isto seria equivalente a executar myisamchk -a na tabela.

O MySQL utiliza a distribuição de chaves armazenadas para decidir em que ordem tabelas devem ser unidas quando alguém faz um join em alguma coisa diferente de uma constante.

O comando retorna uma tabela com as seguintes colunas:

ColunaValor
TableNome da Tabela
OpSempre analyze
Msg_typeUm dos seguintes: status, error, info ou warning
Msg_textA mensagem

Você pode verificar a distribuição de chaves armazenadas com o comando SHOW INDEX. Veja mais informações sobre isto na Seção 4.6.8.1, “Recuperando Informações sobre Bancos de Dados, Tabelas, Colunas e Índices”.

Se a tabela não foi alterada deste o último comando ANALYZE TABLE, a tabela não será analisada novamente.

Antes do MySQL 4.1.1, o ANALYZE comnado não gravava no log binário. Desde o MySQL 4.1.1 eles são escritos no log binário a menos que a palavra chave opcional NO_WRITE_TO_BINLOG (ou se alias LOCAL) seja usada.

4.6.3. Sintaxe de CHECKSUM TABLE

CHECKSUM TABLE tbl_name[,tbl_name ...] [ QUICK | EXTENDED ]

Reports a table checksum. If QUICK is specified, live table checksum is reported, or NULL if the table does not support live checksum. This is very fast. In EXTENDED mode the whole table is read row by row and the checksum is calculated. This can be very slow for large tables. By default - with neither QUICK nor EXTENDED - MySQL returns live checksum if the table support it and scans the table otherwise.

Este comando está implementado no MySQL 4.1.1.

4.6.4. Sintaxe de FLUSH

FLUSH [LOCAL | NO_WRITE_TO_BINLOG] flush_option [,flush_option] ...

Você deve utilizar o comando FLUSH se desejar limpar algum dos caches internos que o MySQL usa. Para executar FLUSH, você deve ter o privilégio RELOAD.

opções podem ser qualquer uma das seguintes:

OptionDescription
HOSTSEsvazia as tabelas de cache de nomes de máquinas. Você deve descarregar as tabelas de nomes de máquinas se alguma de suas máquinas receber um número IP diferente ou se você obter a mensagem de erro Host ... is blocked. Quando mais de max_connect_erros erros occorrer em um registro para uma determinada máquina enquanto se conecta ao servidor MySQL, o MySQL assume que algo está errado e bloqueia futuras requisições desta máquina. A descarga na tabela de nomes de máquinas permite à máquina se conectar novamente. See Seção A.2.5, “Erro: Host '...' is blocked.) Você pode iniciar o mysqld com -O max_connection_errors=999999999 para evitar esta mensagem de erro.
DES_KEY_FILERecarrega a chave DES do arquivo que foi especificado com a opção --des-key-file durante inicialização do servidor.
LOGSFecha e reabre todos os arquivos de log. Se você tiver especificado o arquivo de logs de atualizações ou um arquivo de log binário sem uma extensão, o número de extensão do arquivo log será sempre incrementado de um em relação ao arquivo anterior. Se você usou uma extensão no nome do arquivo, o MySQL irá fechar e reabrir o arquivo de log de atualizações. Veja mais informações sobre isto na Seção 4.10.3, “O Log de Atualizações”. Isto é a mesma coisa que enviar o sinal SIGHUP para o servidor mysqld.
PRIVILEGESRecarrega os privilégios das tabelas de permissões no banco de dados mysql.
QUERY CACHEDefragmenta a cache de consulta par utilizar melhor a sua memória. Este comando não remove qualquer consulta da cache, ao contrário de RESET QUERY CACHE.
TABLESFecha todas as tabelas abertas e força o fechamento de todas as tabelas em uso
[TABLE | TABLES] nome_tabela [,nome_tabela...]Descarga somente das tabelas fornecidas.
TABLES WITH READ LOCKFecha todas tabelas abertas e bloqueia todas tabelas para todos os bancos de dados com leitura até que alguém execute UNLOCK TABLES. Isto é uma maneira muito conveniente para fazer backups se você possui um sistema de arquivos, como Veritas, que pode fazer uma imagem instantânea (snapshot) de um certo momento.
STATUSReinicia a maioria das variáveis de status para zero. Isto é algo que deve ser usado somente para depurar uma consulta.
USER_RESOURCESZera todos os recirsos dos usuários. Isto permitirá que usuários bloqueados façam login novamente. See Seção 4.4.7, “Limitando os Recursos dos Usuários”.

Antes do MySQL 4.1.1, o FLUSH comnado não gravava no log binário. Desde o MySQL 4.1.1 eles são escritos no log binário a menos que a palavra chave opcional NO_WRITE_TO_BINLOG (ou se alias LOCAL) seja usada, ou que o comando contenha um dos argumentos: LOGS, MASTER, SLAVE, TABLES WITH READ LOCK, pois qualquer um desses argumwentos podem causar problemas se replicados para um slave.

Você pode também acessar cada um dos comandos vistos acima com o utilitário mysqladmin, utilizando os comandos flush-hosts, flush-logs, reload ou flush-tables.

Também de uma olhada no comando RESET usado com a replicação. Veja mais informações sobre isto na Seção 4.6.5, “Sintaxe de RESET.

4.6.5. Sintaxe de RESET

RESET reset_option [,reset_option] ...

O comando RESET é usado para limpar coisas. Ele também atua como uma versão mais forte do comando FLUSH. Veja mais informações sobre isto na Seção 4.6.4, “Sintaxe de FLUSH.

Para executar RESET, você deve ter o privilégio RELOAD.

OpçãoDescrição
MASTERDeleta todos os logs binários listados no arquivo índice, esvaziando o arquivo de índice do log binário. Anteriormente chamado FLUSH MASTER. See Seção 4.11.7, “Instruções SQL para Controle do Servidor Master”.
SLAVEFaz o slave ``esquecer'' a sua posição de replicação no log binário do master. Anteriormente chamado FLUSH SLAVE. See Seção 4.11.8, “Instruções SQL para Controle do Servidor Slave”.
QUERY CACHERemove todos os resulatdos de consultas da cache de consultas.

4.6.6. Sintaxe de PURGE MASTER LOGS

PURGE {MASTER|BINARY} LOGS TO nome_binlog
PURGE {MASTER|BINARY} LOGS BEFORE data

Este comando é usado para deletar todos os logs binários estritamente anteriores ao binlog ou data especificada. Veja mais informações sobre isto na Seção 4.11.7, “Instruções SQL para Controle do Servidor Master”.

PURGE BINARY LOGS está disponível como um sinônimo para PURGE MASTER LOGS a partir do MySQL 4.1.1.

4.6.7. Sintaxe de KILL

KILL thread_id

Cada conexão ao mysqld executa em uma thread separada. Você pode ver quais threas estão em execução com o comando SHOW PROCESSLIST e matar uma thread com o comando KILL thread_id.

Se você tiver o privilégio PROCESS, você pode ver todas as threads. Se você tiver o privilégio SUPER, você pode matar todas as threads. Caso contrário, você pode ver e matar somente suas próprias threads.

Você também pode usar os comandos mysqladmin processlist e mysqladmin kill para examinar e matar threads.

Nota: Atualmente você não pode utilizar KILL com a biblioteca do servidor MySQL embutido, porque o servidor embutido apenas roda dentro das threads da aplicação, ela não cria threads de conexões por si própria.

Quando você utiliza um KILL, um sinal (flag) kill especifico é configurado para a thread.

Na maioria dos casos pode levar algum tempo para a thread morrer pois o sinal kill só é checado em intervalos específicos.

  • Nos loops SELECT, ORDER BY e GROUP BY, o sinal é checado depois de ler um bloco de registros. Se o sinal kill está habilitado a instrução é abortada.

  • Na execução de um ALTER TABLE o sinal kill é conferido antes de cada bloco de registros ser lido da tabela original. Se o sinal kill foi habilitado, o comando é abortado e a tabela temporária apagada.

  • Ao fazer um UPDATE TABLE and DELETE TABLE, o sinal de kill é conferido depois de que cada bloco é lido e depois de cada atualização ou remoção de registro. Se o sinal kill está habilitado, a instrução é abortada. Note que se você não estiver utilizando transações, as alterações não irão ser desfeitas!

  • GET_LOCK() irá aborar com NULL.

  • Uma thread INSERT DELAYED irá rapidamente descarregar todos registros que estiverem em memória e morrer.

  • Se a thread estiver no manipulador de bloqueio de tabelas (status: Locked), o bloqueio de tabela será abortado rapidamente.

  • Se a thread estiver esperando por espaço livre em disco numa chamada write, a escrita é abortada com uma mensagem de espaço em disco insuficiente.

4.6.8. Sintaxe de SHOW

   SHOW DATABASES [LIKE wild]
ou SHOW [OPEN] TABLES [FROM nome_bd] [LIKE wild]
ou SHOW [FULL] COLUMNS FROM nome_tbl [FROM nome_bd] [LIKE wild]
ou SHOW INDEX FROM nome_tbl [FROM nome_bd]
ou SHOW TABLE STATUS [FROM nome_bd] [LIKE wild]
ou SHOW STATUS [LIKE wild]
ou SHOW VARIABLES [LIKE wild]
ou SHOW [BDB] LOGS
ou SHOW [FULL] PROCESSLIST
ou SHOW GRANTS FOR user
ou SHOW CREATE TABLE nome_tbl
ou SHOW MASTER STATUS
ou SHOW MASTER LOGS
ou SHOW SLAVE STATUS
ou SHOW WARNINGS [LIMIT row_count]
ou SHOW ERRORS [LIMIT row_count]
ou SHOW TABLE TYPES

SHOW fornece informações sobre bancos de dados, tabelas, colunas ou informações do estado do servidor. Se a parte LIKE wild é usada, a string wild pode ser uma string que usa os meta caracteres ‘%’ e ‘_’ do SQL.

4.6.8.1. Recuperando Informações sobre Bancos de Dados, Tabelas, Colunas e Índices

Você pode usar nome_bd.nome_tabela como uma alternativa para a sintaxe nome_tabela FROM nome_bd. Estas duas declarações são equivalentes:

mysql> SHOW INDEX FROM minhatabela FROM meudb;
mysql> SHOW INDEX FROM meubd.minhatabela;

SHOW DATABASES lista os bancos de dados no servidor MySQL. Você também pode obter esta lista utilizando o comando mysqlshow. Na versão 4.0.2 você verá apenas aqeules banco de dados para os quais você tem algum tipo de privilégio, se você não tiver o privilégio global SHOW DATABASES.

SHOW TABLES lista as tabelas em um banco de dados específico. Esta lista também pode ser obtida utilizando o comando mysqlshow nome_db.

NOTA: Se um usuário não possui nenhum privilégio para uma tabela, a tabela não será mostrada na saída de SHOW TABLES ou mysqlshow nome_db

SHOW OPEN TABLES lista as tabelas que estão abertas no cache de tabelas. See Seção 5.4.7, “Como o MySQL Abre e Fecha as Tabelas”. O campo Comment diz quantas vezes a tabela está em cached e in_use.

SHOW COLUMNS lista as colunas em uma determinada tabela. Se você especificar a opção FULL, também irá obter os privilégios que você possui para cada coluna. Se os tipos de colunas forem diferentes do que você esperava baseando na declaração CREATE TABLE, perceba que o MySQL algumas vezes altera os tipos das colunas. See Seção 6.5.3.1, “Alteração de Especificações de Colunas”. A partir do MySQL 4.1, a palavra chave FULL também faz com que qualquer comentário por coluna seja mostrado.

A instrução DESCRIBE fornece informação similar à SHOW COLUMNS. See Seção 6.6.2, “Sintaxe DESCRIBE (Obtem Informações Sobre Colunas)”.

SHOW FIELDS é um sinônimo para SHOW COLUMNS e SHOW KEYS um sinônimo para SHOW INDEX. Você também pode listar as colunas ou índices de uma tabela com mysqlshow nome_db nome_tabela ou mysqlshow -k nome_bd nome_tabela.

SHOW INDEX retorna a informação de índice em um formato que lembra bem a chamada SQLStatistics do ODBC. As seguintes colunas são retornadas:

ColunaSignificado
TableNome da tabela.
Non_unique0 se o índice não puder conter duplicidades, 1 se puder
Key_nameNome do índice.
Seq_in_indexNúmero da sequência da coluna no índice, à partir de 1.
Column_nameNome da coluna.
CollationComo a coluna é ordenada no índice. No MySQL, pode ter valores ‘A’ (Ascendente) ou NULL (Not sorted).
CardinalityNúmero de valores únicos no índice. Isto é atualizado executando isamchk -a.
Sub_partNúmero de caracteres indexados se a coluna só é a indexada parcialmente. NULL se a chave inteira for indexada.
NullContém 'YES' se a coluna puder conter NULL.
Index_typeMétodo de índice utilizado.
CommentVários comentários. No momento, ele diz no MySQL < 4.0.2 se o índice é FULLTEXT ou não.

Perceba que como o Cardinality é contado baseado nas estatísticas armazenadas como inteiros, ele pode não ser exato para tabelas pequenas.

As colunas Null e Index_type foram adicionadas no MySQL 4.0.2.

4.6.8.2. SHOW TABLE STATUS

SHOW TABLE STATUS [FROM nome_bd] [LIKE wild]

SHOW TABLE STATUS (introduzido na versão 3.23) funciona como o SHOW STATUS, mas fornece muitas informações sobre cada tabela. Você também pode obter esta lista utilizando o comando mysqlshow --status nome_bd. As seguintes colunas são retornadas:

ColunaSignificado
NameNome da tabela.
TypeTipo da tabela. Veja mais informações sobre isto na Capítulo 7, Tipos de Tabela do MySQL.
Row_formatO formato de armazenamento do registro (Fixed (Fixo), Dynamic(dinâmico), ou Compressed (Compactado)).
RowsNúmero de registros.
Avg_row_lengthTamanho médio do registro.
Data_lengthTamanho do arquivo de dados.
Max_data_lengthTamanho máximo do arquivo de dados. Para formatos de registro fixo, este é o número maimo de registros na tabela. Para formatos de registro dinâmicos, este é o número total de bytes de dados que pode ser armazenados na tabela, dado o tamanho do ponteiro de dados utilizado.
Index_lengthTamanho do arquivo de índice.
Data_freeNúmero de bytes alocados mas não utilizados.
Auto_incrementPróximo valor do auto incremento.
Create_timeQuando a tabela foi criada.
Update_timeA última vez que arquivo de dados foi atualizado.
CollationConjunto de caracter e collation da tabela. (novo no 4.1.1)
ChecksumValor do checksum (se existir). (novo no 4.1.1)
Check_timeA última vez que a tabela foi verificada.
Create_optionsOpções extras usadas com CREATE TABLE.
CommentO Comentário utilizado quando a tabela é criada (ou alguma informação do porquê do MySQL não poder acessar a informação da tabela).

Tabelas InnoDB irão relatar o espaço livre no tablespace no comentário da tabela.

4.6.8.3. SHOW STATUS

SHOW STATUS fornece informações de status do servidor (como mysqladmin extended-status). A saída é parecida com o que está exibido abaixo, apesar dos números e formatos provavelmente serem diferentes:

+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
| Delayed_insert_threads   | 0          |
| Delayed_writes           | 0          |
| Delayed_errors           | 0          |
| Flush_commands           | 1          |
| Handler_delete           | 462604     |
| Handler_read_first       | 105881     |
| Handler_read_key         | 27820558   |
| Handler_read_next        | 390681754  |
| Handler_read_prev        | 6022500    |
| Handler_read_rnd         | 30546748   |
| Handler_read_rnd_next    | 246216530  |
| Handler_update           | 16945404   |
| Handler_write            | 60356676   |
| Key_blocks_used          | 14955      |
| Key_read_requests        | 96854827   |
| Key_reads                | 162040     |
| Key_write_requests       | 7589728    |
| Key_writes               | 3813196    |
| Max_used_connections     | 0          |
| Not_flushed_key_blocks   | 0          |
| Not_flushed_delayed_rows | 0          |
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
| Select_full_join         | 0          |
| Select_full_range_join   | 0          |
| Select_range             | 99646      |
| Select_range_check       | 0          |
| Select_scan              | 30802      |
| Slave_running            | OFF        |
| Slave_open_temp_tables   | 0          |
| Slow_launch_threads      | 0          |
| Slow_queries             | 0          |
| Sort_merge_passes        | 30         |
| Sort_range               | 500        |
| Sort_rows                | 30296250   |
| Sort_scan                | 4650       |
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+

As variáveis de estado listadas acima tem o seguinte significado:

VariávelSignficado
Aborted_clientsNúmero de conexões abortadas porque o cliente morreu sem fechar a conexão corretamente. See Seção A.2.10, “Erros de Comunicação / Comunicação Abortada”.
Aborted_connectsNúmero de tentativas que falharam ao tentar a conexão ao servidor MySQL. Veja mais informações sobre isto na Seção A.2.10, “Erros de Comunicação / Comunicação Abortada”.
Bytes_receivedNúmero de bytes recebidos por todos os clientes.
Bytes_sentNúmero de bytes enviados para todos os clientes..
Com_xxxxNúmero de vezes que os comandos xxx foram executados.
ConnectionsNúmero de tentativas de conexão ao servidor MySQL.
Created_tmp_disk_tablesNúmero de tabelas temporárias implicitas em disco criadas durante a execução de instruções.
Created_tmp_tablesNúmero de tabelas temporárias implicitas na memória criadas durante execuções de instruções.
Created_tmp_filesQuantos arquivos temporários o mysqld criou.
Delayed_insert_threadsNúmero de threads para tratamento de insertdelayed que estão em uso.
Delayed_writesNúmero de registros escritos com INSERT DELAYED.
Delayed_errorsNúmero de registros escritos com INSERT DELAYED onde algum erro ocorreu (provavelmente duplicate key).
Flush_commandsNúmero de comandos FLUSH executados.
Handler_deleteNúmero de vezes que um registro foi apagado da tabela.
Handler_read_firstNúmero de vezes que a primeira entrada foi lida de um índice. Se este valor for alto, sugere que o servidor está fazendo várias leituras de índices, por exemplo, SELECT col1 FROM foo, assumindo que col1 é indexado.
Handler_read_keyNúmero de requisições para ler um registro baseado em uma chave. Se este valor for alto, é uma boa indicação que suas pesquisas e tabelas estão indexadas corretamente.
Handler_read_nextNúmero de requisições para ler o próximo registro na ordem da chave. Este valor será aumentado se você consultar uma coluna de índice com uma faixa restrita. Ele também aumentará se forem feitas busca nos índices.
Handler_read_prevNémro de requisições ao registros anterior na ordem da chave. Ele é principalmente usado para otimizar ORDER BY ... DESC.
Handler_read_rndNúmero de requisições para ler um registro baseado em uma posição fixa. O valor será alto se você estiver executando várias pesquisas que exigem ordenação do resultado.
Handler_read_rnd_nextNúmero de requisões para ler o próximo registro no arquivo de dados. Será alto se você estiver fazendo várias buscas na tabela. Geralmente sugere que suas tabelas não estão corretamente indexadas ou que suas pesquisas não foram escritas para tirar vantagem dos índices existentes.
Handler_rollbackNúmeros de comandos ROLLBACK internos.
Handler_updateNúmero de requisições para atualizar um registro em uma tabela.
Handler_writeNúmero de requisições para inserir um registro em uma tabela.
Key_blocks_usedO número de blocos utilizados no cache das chaves.
Key_read_requestsO número de requisições para ler um bloco de chaves do cache.
Key_readsO número de leituras físicas de blocos de chaves do disco.
Key_write_requestsO número de requisições para gravar um bloco de chaves no cache.
Key_writesO número de escritas físicas de um bloco de chaves para o disco.
Max_used_connectionsO número máximo de conexões simultâneas que foram usadas.
Not_flushed_key_blocksBlocos de chaves no cache de chaves que foi alterado mas ainda não foi descarregado para o disco.
Not_flushed_delayed_rowsNúmero de registros esperando para serem escritos em filas INSERT DELAY.
Open_tablesNúmero de tabelas abertas.
Open_filesNúmero de arquivos abertos.
Open_streamsNúmero de fluxos abertos (usado principalmente para logs).
Opened_tablesNúmero de tabelas que foram abertas.
Rpl_statusStatus de replicação segura. (Ainda não está em uso).
Select_full_joinNúmero de joins sem chaves (Se for 0, você deve conferir com cuidado o índice de suas tabelas).
Select_full_range_joinNúmero de joins onde foram usadas pesquisas segmentadas na tabela de referencia.
Select_rangeNúmero de joins onde foram usadas faixas da primeira tabela. (Normalmente não é crítica mesmo se o valor estiver alto.)
Select_scanNúmero de joins onde fizemos uma busca completa na primeira tabela.
Select_range_checkNúmero de joins sem chaves onde o uso de chave foi conferido após cada registro (Se for 0, o índice de suas tabelas deve ser conferido com cuidado)
QuestionsNúmero de consultas enviadas para o servidor.
Slave_open_temp_tablesNúmero de tabelas temporárias atualmente abertas pela thread slave.
Slave_runningÉ ON se este slave está conectado a um master.
Slow_launch_threadsNúmero de threads que levaram mais tempo do que slow_lauch_time para serem criadas.
Slow_queriesNúmero de consultas que levaram mais tempo que long_query_time segundos. See Seção 4.10.5, “O Log para Consultas Lentas”.
Sort_merge_passesNúmero de ifusões feitas pelo algorítmo de ordenação. Se este valor for alto você deve considerar o aumento de sort_buffer.
Sort_rangeNúmero de ordenações que foram feitas com limites.
Sort_rowsNúmero de registros ordenados.
Sort_scanNúmero de ordenações que foram feitas lendo a tabela.
ssl_xxxVariáveis usadas por SSL; Ainda não implementado.
Table_locks_immediateNúmero de vezes que um travamento de tabela foi obtido de maneira automática.
Table_locks_waitedNúmero de vezes que um bloqueio de tabela não pôde ser obtido imediatamente e foi preciso esperar. Se o valor for alto, e você tiver problemas de performance, suas consultas devem ser otimizadas e depois dividir sua tabela ou tabelas ou usar replicação. Disponível à partir da versão 3.23.33
Threads_cachedNúmero de threads no cache de threads.
Threads_connectedNúmero de conexões atuais abertas.
Threads_createdNúmero de threads criadas para lidar com conexões.
Threads_runningNúmero de threads que não estão dormindo.
UptimeQuantos segundos o servidor está funcionando.

Alguns comentários sobre a tabela acima:

  • Se Opened_tables for grande, provavelmente sua variável table_cache está muito pequena.

  • Se key_reads for grande, provavelmente sua variável key_buffer_size provavelmente está muito pequena. O índice de acertos do cache pode ser calculaldo com key_reads/key_read_requests.

  • Se Handler_read_rnd for grande, provavelmente você possui várias consultas que exigem do MySQL fazer busca em tabelas inteiras ou você tem joins que não utilizam chaves corretamente.

  • Se Threads_created for grande você pode desejar aumentar a variável thread_cache_size. A taxa de acerto da cache pode ser calculada com Threads_created/Connections.

  • Se Created_tmp_disk_tables for grande, você pode querer aumentar a variável tmp_table_size par obter tabelas temporárias em memórias em vez de tabelas em disco.

4.6.8.4. SHOW VARIABLES

SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]

SHOW VARIABLES exibe os valores de algumas variáveis de sistema do MySQL.

As opções GLOBAL e SESSION são novas no MySQL 4.0.3. Com GLOBAL você obterá as variáveis que serão utilizadas para novas conexões ao MySQL. Com SESSION você obterá os valores que estão em efeito para a conexão atual. Se você não estiver usando nenhuma opção, SESSION será usada.

Se os valores padrões não lhe servirem, você pode configurar a maioria destas variáveis usando as opções de linha de comando na inicialização do mysqld. See Seção 4.1.1, “Opções de Linha de Comando do mysqld. Você pode alterar a maioria das variáveis com o comando SET. See Seção 5.5.6, “Sintaxe de SET.

A saída de SHOW VARIABLES se parece com o exibido abaixo, embora o formato e os números possam divergir. Você também pode conseguir esta informação usando o comando mysqladmin variables.

+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------|
| back_log                        | 50                           |
| basedir                         | /usr/local/mysql             |
| bdb_cache_size                  | 8388572                      |
| bdb_log_buffer_size             | 32768                        |
| bdb_home                        | /usr/local/mysql             |
| bdb_max_lock                    | 10000                        |
| bdb_logdir                      |                              |
| bdb_shared_data                 | OFF                          |
| bdb_tmpdir                      | /tmp/                        |
| bdb_version                     | Sleepycat Software: ...  |
| binlog_cache_size               | 32768                        |
| bulk_insert_buffer_size         | 8388608                      |
| character_set                   | latin1                       |
| character_sets                  | latin1 big5 czech euc_kr   |
| concurrent_insert               | ON                           |
| connect_timeout                 | 5                            |
| convert_character_set           |                              |
| datadir                         | /usr/local/mysql/data/       |
| delay_key_write                 | ON                           |
| delayed_insert_limit            | 100                          |
| delayed_insert_timeout          | 300                          |
| delayed_queue_size              | 1000                         |
| flush                           | OFF                          |
| flush_time                      | 0                            |
| ft_boolean_syntax               | + -><()~*:""&|               |
| ft_min_word_len                 | 4                            |
| ft_max_word_len                 | 84                           |
| ft_query_expansion_limit        | 20                           |
| ft_stopword_file                | (built-in)                   |
| have_bdb                        | YES                          |
| have_innodb                     | YES                          |
| have_isam                       | YES                          |
| have_raid                       | NO                           |
| have_symlink                    | DISABLED                     |
| have_openssl                    | YES                          |
| have_query_cache                | YES                          |
| init_file                       |                              |
| innodb_additional_mem_pool_size | 1048576                      |
| innodb_buffer_pool_size         | 8388608                      |
| innodb_data_file_path           | ibdata1:10M:autoextend       |
| innodb_data_home_dir            |                              |
| innodb_file_io_threads          | 4                            |
| innodb_force_recovery           | 0                            |
| innodb_thread_concurrency       | 8                            |
| innodb_flush_log_at_trx_commit  | 1                            |
| innodb_fast_shutdown            | ON                           |
| innodb_flush_method             |                              |
| innodb_lock_wait_timeout        | 50                           |
| innodb_log_arch_dir             |                              |
| innodb_log_archive              | OFF                          |
| innodb_log_buffer_size          | 1048576                      |
| innodb_log_file_size            | 5242880                      |
| innodb_log_files_in_group       | 2                            |
| innodb_log_group_home_dir       | ./                           |
| innodb_mirrored_log_groups      | 1                            |
| interactive_timeout             | 28800                        |
| join_buffer_size                | 131072                       |
| key_buffer_size                 | 16773120                     |
| language                        | /usr/local/mysql/share/...   |
| large_files_support             | ON                           |
| local_infile                    | ON                           |
| locked_in_memory                | OFF                          |
| log                             | OFF                          |
| log_update                      | OFF                          |
| log_bin                         | OFF                          |
| log_slave_updates               | OFF                          |
| log_slow_queries                | OFF                          |
| log_warnings                    | OFF                          |
| long_query_time                 | 10                           |
| low_priority_updates            | OFF                          |
| lower_case_table_names          | OFF                          |
| max_allowed_packet              | 1047552                      |
| max_binlog_cache_size           | 4294967295                   |
| max_binlog_size                 | 1073741824                   |
| max_connections                 | 100                          |
| max_connect_errors              | 10                           |
| max_delayed_threads             | 20                           |
| max_heap_table_size             | 16777216                     |
| max_join_size                   | 4294967295                   |
| max_relay_log_size              | 0                            |
| max_sort_length                 | 1024                         |
| max_user_connections            | 0                            |
| max_tmp_tables                  | 32                           |
| max_write_lock_count            | 4294967295                   |
| myisam_max_extra_sort_file_size | 268435456                    |
| myisam_repair_threads           | 1                            |
| myisam_max_sort_file_size       | 2147483647                   |
| myisam_recover_options          | force                        |
| myisam_sort_buffer_size         | 8388608                      |
| net_buffer_length               | 16384                        |
| net_read_timeout                | 30                           |
| net_retry_count                 | 10                           |
| net_write_timeout               | 60                           |
| open_files_limit                | 1024                         |
| pid_file                        | /usr/local/mysql/name.pid    |
| port                            | 3306                         |
| protocol_version                | 10                           |
| query_cache_limit               | 1048576                      |
| query_cache_size                | 0                            |
| query_cache_type                | ON                           |
| read_buffer_size                | 131072                       |
| read_rnd_buffer_size            | 262144                       |
| rpl_recovery_rank               | 0                            |
| safe_show_database              | OFF                          |
| server_id                       | 0                            |
| slave_net_timeout               | 3600                         |
| skip_external_locking           | ON                           |
| skip_networking                 | OFF                          |
| skip_show_database              | OFF                          |
| slow_launch_time                | 2                            |
| socket                          | /tmp/mysql.sock              |
| sort_buffer_size                | 2097116                      |
| sql_mode                        |                              |
| table_cache                     | 64                           |
| table_type                      | MYISAM                       |
| thread_cache_size               | 3                            |
| thread_stack                    | 131072                       |
| tx_isolation                    | READ-COMMITTED               |
| timezone                        | EEST                         |
| tmp_table_size                  | 33554432                     |
| tmpdir                          | /tmp/:/mnt/hd2/tmp/          |
| version                         | 4.0.4-beta                   |
| wait_timeout                    | 28800                        |
+---------------------------------+------------------------------+

Cada opção é descrita abaixo. Valores para tamanhos de buffer, comprimento e tamanho de pilha são fornecidos em bytes. Você pode especificar valores com sufixos ‘K’ ou M para indicar o valor em kilobytes ou megabytes. Por exemplo, 16M indica 16 Megabytes. Não importa se os sufixos estão em letras maiúsuculas ou minúsculas; 16M e 16m são equivalentes:

  • ansi_mode. Está ligado (ON) se o mysqld foi iniciado com --ansi. See Seção 1.8.2, “Executando o MySQL no modo ANSI”.

  • back_log O número de requisições de conexões que o MySQL pode suportar. Isto entra em cena quando a thread principal do MySQL recebe MUITAS solicitações de conexões em um espaço curto de tempo. Eles tomam algum tempo (porém muito pouco) da a thread principal para conferir a conexão e iniciar uma nova thread. O valor back_log indica quantas requisições podem ser empilhadas durante este breve tempo antes do MySQL parar de responder a novas requisições. Você isó precisa aumentá-lo se espera um número alto de conexões em um curto período de tempo

    Em outras palavras, este valor é o tamanho da fila de escuta para novas conexões TCP/IP. Seu sistema operacional tem o próprio limite para o tamanho desta fila. A página do manual Unix da chamada de sistema listen(2) deve fornecer maiores detalhes. Confira a documentação do seus SO para saber o valor máximo para esta variável. Tentativas de configurar back_log maior do que o limite de seu sistema operacional serão ineficazes.

  • basedir O valor da opção --basedir.

  • bdb_cache_size O buffer que é alocado para o cache de índice e registros de tabelas BDB. Se você não utiliza tabelas BDB, deve iniciar o mysqld com a opção --skip-bdb para evitar desperdício de memória para este cache.

  • bdb_log_buffer_size O buffer que é alocado para o cache de índice e registros de tabelas BDB. Se você não utiliza tabelas BDB, deve configurá-la com 0 ou iniciar o mysqld com a opção --skip-bdb para evitar desperdício de memória para este cache.

  • bdb_home O valor para a opção --bdb-home.

  • bdb_max_lock O número máximo de bloqueios (1000 por padrão) que podem ser feitas em uma tabela BDB. Você deve ser aumentá-la se obter erros do tipo: bdb: Lock table is out of available locks ou Got error 12 from ... quando são necessárias longas transações ou quando o mysqld precisar examinar vários registros para calcular a pesquisa.

  • bdb_logdir O valor da opção --bdb-logdir.

  • bdb_shared_data Está ligada (ON) se você estiver utilizando --bdb-shared-data.

  • bdb_tmpdir O valor da opção --bdb-tmpdir.

  • binlog_cache_size. O tamanho do cache para armazenar instruções SQL para o log binário durante uma transação. Se você geralmente utiliza transações grandes, multi-instruções, você pode aumentar este valor para obter mais performance. See Seção 6.7.1, “Sintaxe de START TRANSACTION, COMMIT e ROLLBACK.

  • bulk_insert_buffer_size (era myisam_bulk_insert_tree_size) MyISAM usa uma cache especial em árvore para fazer inserções em bloco (isto é, INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., e LOAD DATA INFILE) mais rápidos. Esta variável limita o tamanho da árvore cache em bytes por thread. Definí-la com 0 desabilitará esta otimização Nota: esta cache só é usada quando é adicionado dados a uma tabela não vazia. O valor padrão é 8 MB.

  • character_set O conjunto de caracteres padrão.

  • character_sets Os conjuntos de caracteres suportados.

  • concurrent_inserts Se ON (ligado, por padrão), o MySQL permitirá o uso de INSERT em tabelas MyISAM ao mesmo tempo em que são executadas consultas SELECT. Você pode desligar esta opção iniciando mysqld com --safe ou --skip-new.

  • connect_timeout O número de segundos que o servidor mysqld espera para um pacote de conexão antes de responder com Bad handshake.

  • datadir O valor da opção --datadir.

  • delay_key_write

    Option for MyISAM tables. Can have one of the following values:

    OFFAll CREATE TABLE ... DELAYED_KEY_WRITE são ignorados.
    ON(padrão) MySQL seguirá a opção DELAY_KEY_WRITE para CREATE TABLE.
    ALLTodas as novas tabelas abertas são tratadas como se fossem criadas com a opção DELAY_KEY_WRITE.

    Se DELAY_KEY_WRITE estiver habilitado, isto siginifica que o buffer de chaves das tabelas com esta opção não serão descarregadas a cada atualização do índice, mas somente quando a tabela é fechada. Isto irá aumentar bem a velocidade de escrita em chaves, mas você deve adicionar verificação automática de todas as tabelas com myisamchk --fast --force se você usá-lo.

  • delayed_insert_limit Depois de inserir delayed_insert_limit registros, o agente que cuida de INSERT DELAYED ira conferir se exitem instruções SELECT pendentes. Se sim, ele permite a execução destas antes de continuar.

  • delayed_insert_timeout Quanto tempo uma thread INSERT DELAYED deve esperar por instruções INSERT antes de terminar.

  • delayed_queue_size Qual tamanho deve ser alocado para a fila (em linhas) para lidar com INSERT DELAYED. Se a fila encher, algum cliente que executar INSERT DELAYED irá esperar até existir espaço na fila novamente.

  • flush É habilitado (ON) se você iniciar o MySQL com a opção --flush.

  • flush_time Se esta variável for configurada com um valor diferente de zero, então a cada flush_time segundos todas tabelas serão fechadas (para economizar recursos e sincronizar dados com o disco). Recomendamos esta opção somente em sistemas com Win95, Win98 ou outros sistemas com poucos recursos.

  • ft_boolean_syntax Lista de operadores suportados por MATCH ... AGAINST(... IN BOOLEAN MODE). Veja mais informações sobre isto na Seção 6.8, “Pesquisa Full-text no MySQL”.

  • ft_min_word_len O tamanho mínimo da palavra a ser incluída em um índice FULLTEXT. Nota: índices FULLTEXT devem ser reconstruídos depois de alterar esta variável. (Esta opção é nova para o MySQL 4.0.)

  • ft_max_word_len O tamanho máximo da palavra a ser incluída em um índice FULLTEXT. Nota: índices FULLTEXT devem ser reconstruídos depois de alterar esta variável. (Esta opção é nova para o MySQL 4.0.)

  • ft_query_expansion_limit Núnero de correspondências a usar para consulta de expansão (em MATCH ... AGAINST (... WITH QUERY EXPANSION). (Esta opção é nova no MySQL 4.1.1)

  • ft_max_word_len_for_sort O tamanho máximo da palavra a ser incluída em um índice FULLTEXT a ser usado no método rápido de recriação do índice em REPAIR, CREATE INDEX, ou ALTER TABLE. Palavras mais longas são inseridas de modo lento. A regra do dedão é a seguinte: com ft_max_word_len_for_sort aumentando, MySQL criará arquivos temporários maiores (tornando o processo lente, devido a E/S de disco), e colocará poucas chaves em um bloco ordenado (diminuindo a eficiência novamente). Quando ft_max_word_len_for_sort é muito pequeno, MySQL irá inserir várias palavras no índice de modo lento, mas pequenas palavras serão inseridas muito rapidamente.

  • ft_stopword_file O arquivo do qual se lê a lista de palavras de parada para pesquisa fulltext. Todas as palavras do arquivo serão usadas; comentários não são seguidos. Por padrão, a lista já incluída de palavras de parada é a usada (como definido em myisam/ft_static.c). Definir este parâmetro com uma string vazia ("") disabilitaa o filtro de palavras de parada. Nota: índices FULLTEXT devem ser reconstruídos depois de alterar esta variável. (Esta opção é nova para o MySQL 4.0.)

  • have_innodb YES if mysqld suporta tabelas InnoDB. DISABLED se --skip-innodb é usado.

  • have_bdb YES se o mysqld suportar tabelas Berkeley DB. DISABLED se a opção --skip-bdb for usada.

  • have_raid YES se o mysqld suportar a opção RAID.

  • have_openssl YES se o mysqld suportar SSL (criptografia) no protocolo cliente/ servidor.

  • init_file O nome do arquivo especificado com a opção --init-file quando você iniciar o servidor. Este é um arquivo das instruções SQL que você deseja que o servidor execute quando é iniciado.

  • interactive_timeout O número de segundos que o servidor espera por atividade em uma conexão antes de fechá-la. Um cliente interativo é definido como um cliente que utiliza a opção CLIENT_INTERACTIVE para mysql_real_connect(). Veja também wait_timeout.

  • join_buffer_size O tamanho do buffer que é utilizado para full joins (joins que não utilizam índices). O buffer é alocado uma vez para cada full join entre duas tabelas. Aumente este valor para obter um full join mais rápido quando a adição de índices não for possível. (Normalmente a melhor forma de obter joins rápidas é adicionar índices.)

  • key_buffer_size Blocos de índices são buferizados e compartilhados por todas as threads. key_buffer_size é o tamanho do buffer utilizado para indexar blocos.

    Aumente-o para lidar melhor com os índices (para todas as leituras e escritas múltiplas) para o máximo possível 64M em uma máquina com 256M que executa, principalmente, o MySQL é bastante comum. Entretanto, se você deixar este valor muito grande (mais que 50% da sua memória total?) seu sistema pode iniciar a paginar e se tornar MUITO lento. Lembre-se que como o MySQL não utiliza cache de leitura de dados, será necessário deixar algum espaço para o cache do sistema de arquivos para o Sistema Operacional.

    Você pode verificar a performance do buffer de chaves executando SHOW STATUS e examinar as variáveis Key_read_requests, Key_reads, Key_write_requests e Key_writes. A razão de Key_reads/Key_read_request deve normalmente ser < 0.01. O Key_write/Key_write_requests é normalmnte próximo de 1 se você estiver utilizando na maioria updates/deletes mas deve ser bem menor se você tender a fazer atualizações que afetam várias outras ao mesmo tempo ou se você estiver utilizando DELAY_KEY_WRITE. See Seção 4.6.8, “Sintaxe de SHOW.

    Para obter ainda mais velocidade quando estiver gravando vários registros ao mesmo tempo, utilize LOCK TABLES. Veja mais informações sobre isto na Seção 6.7.5, “Sintaxe LOCK TABLES e UNLOCK TABLES.

  • language A linguagem utilizada para mensagens de erro.

  • large_file_support Se o mysqld foi compilado com opções para suporte a grandes arquivos.

  • locked_in_memory Se o mysqld foi travado na memória com --memlock

  • log Se o log de todas as consultas está habilitado.

  • log_update Se o log de atualizações está habilitado.

  • log_bin Se o log binários está habilitado.

  • log_slave_updates Se as atualizações do slave devem ser logadas.

  • long_query_time Se uma consulta demorar mais que isto (em segundos), o contador Slow_queries ser incrementado. Se você estiver utilizando --log-slow-queries, a consulta será logada ao arquivo de consultas lentas. See Seção 4.10.5, “O Log para Consultas Lentas”. Este valor é medido em tempo real, não em tempo de CPU, assim uma consulta que pode estar pode estar abaixo do limiar de um sistema de carga leve pode estar acima do limiar de um sistema de carga pesada. Veja mais informações sobre isto na Seção 4.10.5, “O Log para Consultas Lentas”.

  • lower_case_nome_tabelas Se estiver configurado para 1, nomes de tabelas são armazenados em letras minúsculas no disco e nomes de tabelas serão caso-insensitivo. Na versão .0.2, esta opção também se aplica aos nomes de banco de dados. Na versão 4.1.1 esta opção também se aplcia a alias de tabelas. See Seção 6.1.3, “Caso Sensitivo nos Nomes”.

  • max_allowed_packet O valor máximo de um pacote. O buffer de mensagens é iniciado por net_buffer_length bytes, mas pode crescer até max_allowed_packet bytes quando for necessário. Este valor por padrão é pequeno, para obter pacotes maiores (possivelmente errados). Você deve incrementar este valor se você estiver usando colunas BLOB grandes. Ele deve tão grande quanto o maior BLOB que você deseja utilizar. O protocol atual limita o max_allowed_packet à 16M no MySQL 3.23 e 1G no MySQL 4.0.

  • max_binlog_cache_size Se uma transação multi-instruções necessitar de mais que este montante de memória, será obtido o erro "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage" ("Transação multi-instruções necessita mais que 'max_binlog_cache_size' bytes de armazenamento").

  • max_binlog_size Disponível a partir da 3.23.33. Se uma escrita ao log binário (replicação) exceder o valor fornecido, rotacione os logs. Você não pode configurá-lo para menos de 4096 bytes (1024 na versão do MySQL anteriores a 4.0.14), ou mais que 1 GB. O valor padrão é 1 GB. Nota se você estiver usando transações: uma transação é escrita em um bloco no arquivo de log binário, já que ele nunca é separado entre diversos logs binários. Desta forma, se você tiver grandes transações, você pode ter logs binários maioores que max_binlog_size. Se max_relay_log_size (disponível a partir do MySQL 4.0.14) é 0, então max_binlog_size se aplicará bem aos relay logs.

  • max_connections O Número de clientes simultâneos permitidos. Aumentar este valor aumenta o número de descritores de arquivos que o mysqld necessita. Veja abaixo os comentários sobre os limites de descritores de arquivos. Veja mais informações sobre isto na Seção A.2.6, “Erro: Too many connections.

  • max_connect_errors Se houver mais que este número de conexões interrompidas a partir de uma máquina está máquina terá as próximas conexões bloqueadas. Você pode desbloquar uma máquina com o comadno FLUSH HOSTS.

  • max_delayed_threads Não inicie mais do que este número de threads para lidar com instruções INSERT DELAYED. Se você tentar inserir dados em uma nova tabela depois que todas as threads INSERT DELAYED estiverem em uso, o registro será inserido como se o atributo DELAYED não fosse especificado. Se você configurá-lo com 0, o MySQL nunca criará uma thread max_delayed.

  • max_heap_table_size Esta variável define o tamanho máximo que uma tabela HEAP criada pode ter. O valor da variável é usado para calcular um valor MAX_ROWS da tabela HEAP. A definição desta variável não tem nenhum efeito sobre qualquet tabela HEAP existente, a memos que a tabela seja recriada com uma instrução como CREATE TABLE ou TRUNCATE TABLE, ou alterada com ALTER TABLE.

  • max_join_size Joins que provavelmente forem ler mais que max_join_size registros retornam um erro. Configure este valor se os seus usuários tendem a realizar joins que não possuem uma cláusula WHERE, que tomam muito tempo, e retornam milhões de registros.

  • max_relay_log_size Disponível a partir da versão 4.0.14. Se uma escrita ao relay log (um tipo de log usado por slaves de replicação, see Seção 4.11.3, “Detalhes de Implementação da Replicação”) exceder o valor dado, rotacione o relay log. Esta variável lhe permite colocar diferentes restrições de tamanho no relay logs e logs binários. No entanto, configurar a variável com 0 fará o MySQL usar max_binlog_size tanto para o log binário quanto para o relay logs. Você tem que configurar max_relay_log_size com 0 ou mais de 4096, e menos que 1 GB. O padrão é 0.

  • max_seeks_for_key Limite do número máximo de buscas ao procurar linhas com base em uma chave. O otimizador MySQL assumirá que quando pesquisar por linhas correspondentes em uma tabela através da varredura da chave, não faremos mais que este número de busca de chave independente da cardinalidade da chave. Configurando este parâmetro com um valor baixo (100 ?) você pode forçar o MySQL a preferir chaves em vez de varrer a tabela.

  • max_sort_length O número de bytes utilizados para ordenar valores BLOB ou TEXT (somente os primeiros max_sort_lenght bytes de cada valor são usados; o resto é ignorado).

  • max_user_connections O valor máximo de conexões ativas para um único usuário (0 = sem limite).

  • max_tmp_tables (Esta opção ainda não faz nada.) Número máximo de tabelas temporárias que um cliente pode manter abertas ao mesmo tempo.

  • max_write_lock_count Depois desta quantidade de bloqueios de escrita, permite que alguns bloqueios de leitura sejam executados.

  • myisam_recover_options O valor da opção --myisam-recover.

  • myisam_sort_buffer_size O buffer que é alocado ao ordenar o índice quando estiver fazendo um REPAIR ou estiver criando índices com CREATE INDEX ou ALTER TABLE.

  • myisam_max_extra_sort_file_size. Se a criação do arquivo temporário para criação rápida de índices fosse este valor maior que quando for usado o cache de chaves, de preferência ao método de cache de chaves. Isto é usado principalmente para forçar que longas chaves de caracteres em tabelas grandes usem o método de cache de chaves mais lenta para criar o índice. NOTE que este parâmetro é fornecido em megabytes!

  • myisam_repair_threads. Se este valor é maior que um, durante o processo reparo por ordenação os índices de tabels MyISAM serão criados em paralelo - cada índice em sua própria thread. Nota reparos com multi-threads está ainda sob código de qualidade alpha.

  • myisam_max_sort_file_size O tamanho máximo do arquivo temporário que é permitido ao MySQL usar enquanto recria os índices (durante REPAIR, ALTER TABLE ou LOAD DATA INFILE). Se o tamanho do arquivo for maior que isto, o índice será criado através do cache de chaves (que é mais lento). NOTE que este parâmetro é fornecido em megabytes antes da versão 4.0.3 e em bytes a partir desta versão.

  • net_buffer_length O buffer de comunicações é configurado para este tamanho entre queries. Isto não deve ser alterado normalmente, mas se você tem muito pouca memória, pode configurá-lo para o tamanho esperado de uma consulta. (Isto é, o tamanho experado das instruções SQL enviadas pelos clientes. Se as instruções excederem este valor, o buffer é aumentado automaticamente, até max_allowed_packet bytes.)

  • net_read_timeout Número de segundos para esperar por mais dados de uma conexão antes de abortar a leitura. Perceba que quando nós não esperamos dados de uma conexão, o tempo máximo de espera é definido pelo write_timeout. Veja também slave_read_timeout.

  • net_retry_count Se uma leitura na porta de comunicações for interrompida, tente novamente net_retry_count vezes antes de parar. Este valor deve ser bem alto no FreeBSD já que interrupções internas são enviadas para todas as threads.

  • net_write_timeout Número de segundos para esperar pela escrita de um bloco em uma conexão antes de abortar a escrita.

  • open_files_limit Número de arquivos que o sistema permite que o mysqld abra. Este é o valor real dado para o sistema e pode ser diferente do valor que você passa ao mysqld como parâmetro de inicialização. Ele é 0 em sistemas onde o MySQL não pode alterar o número de arquivos abertos.

  • pid_file O valor da opção --pid-file.

  • port O valor da opcao --port.

  • protocol_version A versão do protocolo usada pelo servidor MySQL.

  • range_alloc_block_size Tamanho dos blocos que são alocados ao se fazer uma otimização da faixa.

  • read_buffer_size (era record_buffer) Cada thread que faz uma leitura sequencial aloca um buffer deste tamanho para cada tabela lida. Se você fizer várias leituras sequenciais, você pode desejar aumentar este valor.

  • read_rnd_buffer_ae (era record_rnd_buffer) Ao ler registros na ordem depois de uma ordenação, os registros são lidos através deste buffer para evitar pesquisas em disco. Pode melhorar bastante o ORDER BY se configurado com um valor alto. Como esta é uma variável específica da thread, não se pode definí-la globalmente, mas apenas alterá-la ao executar alguma consulta específica grande.

  • query_alloc_block_size Tamanho dos blocos de alocação de memória que são alocados para objetos criados durante a análise e execução da consulta. Se você tiver problemas com fragmentação de memória ele pode ajudar a aumentar isto um pouco.

  • query_cache_limit Não armazena resultados que são maiores que esta variável. (Padrão 1M).

  • query_cache_size A memória alocada para armazenar resultados de consultas antigas. Se 0, a cache de consulta é desabilitada (padrãot).

  • query_cache_type Pode ser configurado com (somente numérico)

    ValorAliasComentário
    0OFFNão armazena ou recupera resultados
    1ONArmazena todos os resultados exceto consultas SELECT SQL_NO_CACHE ....
    2DEMANDArmazena apenas consultas SELECT SQL_CACHE ....
  • query_prealloc_size Buffer persistente para análise e execução da consulta. Não é liberado entre consultas. Em teoria, tornando-o ``grande o suficiente'' você pode fazer o MySQL executar consultas sem ter que fazer uma única chamada malloc.

  • safe_show_database Não exibe bancos de dados nos quais o usuário não tem nenhum privilégios. Isto pode melhorar a segurança se você se preocupa com o fato das pessoas estarem aptas a ver quais bancos de dados outros usuários possuem. Veja também skip_show_databases.

  • server_id O valor da opção --server-id.

  • skip_locking Está desligado (OFF) se o mysqld usar bloqueio externo.

  • skip_networking Está ligado (ON) se somente permitimos conexões locais (socket).

  • skip_show_databases Isto previne usuários de fazerem SHOW DATABASES se eles não possuirem o privilégio PROCESS_PRIV. Isto pode aumentar a segurança se você se preocupa com o fato das pessoas poderem ver quais bancos de dados outros usuários possuem. Veja também safe_show_databases.

  • slave_net_timeout Número de segundos para esperar por mais dados de uma conexão de master/slave antes de abortar a leitura.

  • slow_launch_time Se a criação de threads demorar mais que este valor (em segundos), o contador Slow_launch_threads será incrementado.

  • socket O socket Unix utilizado pelo servidor.

  • sort_buffer Cada thread que precisar fazer uma ordenação aloca um buffer deste tamanho. Aumente este valor para operações ORDER BY ou GROUP BY mais rápidas. Veja mais informações sobre isto na Seção A.4.4, “Onde o MySQL Armazena Arquivos Temporários”.

  • table_cache O número de tabelas abertas para todas as threads. Aumentar este valor aumenta o número de descritores de arquivos que o mysql necessita. O MySQL precisa de dois descritores de arquivos para cada tabela única aberta. Veja abaixo os comentaários sobre os limites do descritor de arquivos. Você pode conferir se necessita aumentar o cache de tabela conferindo a variável Opened_tables. See Seção 4.6.8.3, “SHOW STATUS. Se esta variável for grande e você não faz muitos FLUSH TABLES (que apenas força todas as tabelas a serem fechadas e reabertas), então você deve aumentar o valor desta variável.

    Para informações sobre como o cache de tabelas funciona, veja Seção 5.4.7, “Como o MySQL Abre e Fecha as Tabelas”.

  • table_type O tipo padrão de tabelas.

  • thread_cache_size Quantas threads devem ser mantidas em cache para reutilização. Quando um cliente desconecta, as threads dos clientes são colocadas no cache se não existir mais de thread_cache_size threads que antes. Todas novas threads serão obtidas primeiramente do cache, e só quando o cache estiver vazio uma nova thread é criada. Esta variável pode ser aumentada para melhorar a performance se você tiver várias conexões novas. (Normalmente isto não dá uma melhora de performance notável se você possuir uma boa implementação de threads.) Examinando as diferenças entre Connections e Threads_create (see Seção 4.6.8.3, “SHOW STATUS para maiores detalhes) pode ser visto o quão eficente é o cache de threads atual.

  • thread_concurrency No Solaris, mysqld irá chamar thr_setconcurrency() com este valor. thdr_setconcurrency() permite que a aplicação forneça ao sistema de threads uma dica com o número desejado de threads que devem ser executados ao mesmo tempo.

  • thread_stack O tamanho da pilha para cada thread. Vários dos limites detectados pelo teste crash-me são dependentes deste valor. O padrão é grande o suficiente para operações normais. Veja mais informações sobre isto na Seção 5.1.4, “O Pacote de Benchmark do MySQL”.

  • timezone O fuzo horário para este servidor.

  • tmp_table_size Se uma tabela temporária em memória exceder este tamanho, o MySQL irá a convertê-la automaticamente para uma tabela MyISAM em disco. Aumente o valor de tmp_table_size se você fizer várias consultas GROUP BY avançadas e você tiver muita memória.

  • tmpdir O diretório utilizado para arquivos temporários e tabelas temporárias. A partir do MySQL 4.1, ele pode ser definido com uma lista de caminhos separados por dois pontos (:) (ponto e vírgula (; no Windows). Eles serão usados de modo robin-round. Este recurso pode ser usado para dividir a craga entre diversos discos físicos.

  • transaction_alloc_block_size Tamanho dos blocos de alocação de memória que são alocados para consultas de armazenamento que são parte de uma transação que está para ser armazenada no log binário ao se fazer um commit.

  • transaction_prealloc_block_size Buffer persistente para transaction_alloc_blocks que não é liberado entre as consultas. Tornando-o ``grande o suficiente'' para caber todas as consulta em uma transação comum você pode evitar muitas chamadas malloc.

  • version O número da versão do servidor.

  • wait_timeout O número de segundos que o servidor espera pela atividade em uma conexão antes de fechá-la. Veja também interactive_timeout.

    Na inicialização da thread, SESSION.WAIT_TIMEOUT é inicializado por GLOBAL.WAIT_TIMEOUT ou GLOBAL.INTERACTIVE_TIMEOUT dependendo do tipo do cliente (como definido pela opção de conexão CLIENT_INTERACTIVE). Veja também interactive_timeout.

A seção do manual que descreve o ajuste do MySQL contém algumas informações de como sintonizar as variáveis acima. Veja mais informações sobre isto na Seção 5.5.2, “Parâmetros de Sintonia do Servidor”.

4.6.8.5. SHOW [BDB] LOGS

SHOW LOGS exibe estatísticas sobre os arquivos log existentes. Atualmente ele só exibe informações sobre arquivos de log Berkeley DB, assim um alias para ele (disponível a partir do MySQL 4.1.1) é SHOW BDB LOGS.

  • File exibe o caminho completo para o arquivo de log

  • Type exibe o tipo do arquivo log (BDB para arquivos de log Berkeley DB).

  • Status exibe o status do arquivo log (FREE se o arquivo pode ser removido, ou IN USE se o arquivo é necessário para o subsistema de transações)

4.6.8.6. SHOW PROCESSLIST

SHOW [FULL] PROCESSLIST exibe quais threads estão em execução. Esta informação também pode ser obtida com o comando mysqladmin processlist. Se você possuir o privilégio SUPER, poderá ver todas as threads. Senão só é possível ver as próprias threads. See Seção 4.6.7, “Sintaxe de KILL. Se você não utiliza a opção FULL, então somente os primeiros 100 caracteres de cada query serião exibidos.

A partir da versão 4.0.12, o MySQL informa o nome de maquina para conexões TCP/IP no formato nome_maquina:client_port para tornar mais fácil de se encontrar qual cliente está fazendo o que.

Este comando é muito útil caso você obtenha a mensagem de erro 'too many connections' e deseja saber o que está ocorrendo. O MySQL reserva uma conexão extra por cliente com o privilégio SUPER para garantir que você sempre consiga logar e conferir o sistema (assumindo que este privilégio não foi concedido para todos os usuários).

Alguns estados normalmente vistos em mysqladmin processlist

  • Checking table A thread está realizando verificação [automática] da tabela.

  • Closing tables Signiifica que a thread está descarregando os dados alterados na tabela para o disco e fechando as tabelas usadas. Isto deve ser uma operação rápida. Se não, você deve verificar se o seu disco não está cheio ou que o disco não está com sobrecarga.

  • Connect Out Slave está conectando ao master.

  • Copying to tmp table on disk O resultado temporário foi maior que tmp_table_size e a thread agora está alterando a tabela temporária na memória para o disco para economizar memória.

  • Creating tmp table A thread está criando uma tabela temporária para guardar uma parte do resultado para a consulta.

  • deleting from main table Ao executar a primeira parte de um delete multi-tabela e estamos deletando apenas da primeira tabela.

  • deleting from reference tables Ao executar a segunda parte de um delete multi-tabela e estamos deletando o registros correspondentes em outras tabelas.

  • Flushing tables A thread está executando FLUSH TABLES e está esperando que todas as threads fechem as suas tabelas.

  • Killed Alguém enviou um sinal para matar a thread e ela deve abortar a próxima vez que ele verificar o parâmetro kill. O parâmetro é verificado em cada loop maior no MySQL, mas em alguns casos ainda pode levar um tempo curto para a thread morrer. Se a thread está bloqueada par outra thread, a finalização terá efeito assim que as outras threads liberarem o bloqueio.

  • Sending data A thread está processando registros para uma instrução SELECT e também está enviando dados ao cliente.

  • Sorting for group A thread está fazendo uma ordenação para satisfazer a um GROUP BY.

  • Sorting for order A thread está fazendo uma ordenação para satisfazer a um ORDER BY.

  • Opening tables Isto simplesmente significa que a thread está tentando abrir uma tabela. Este deve ser um procedimento muito rápido, a menos que algo previna da abertura. Por exemplo um ALTER TABLE ou um LOCK TABLE pode prvenir a abertura de uma tabela até que o comando esteja finalizado.

  • Removing duplicates A consulta estava usando SELECT DISTINCT de tal modo que o MySQL não podia otimizar o distinct em um estagio anterior. Por isto o MySQL fez um estágio extra para remover todos os registros duplicados antes de enviar o resultado ao cliente.

  • Reopen table A thread obteve um lock para a tabela, mas notificou após o lock que a estrutura da tabela alterou. Ela liberou o lock, fechou a tabela e agora está tentando reabrí-la.

  • Repair by sorting O código de reparação está utilizando ordenamento para recriar os índices.

  • Repair with keycache O código de reparação está usando a criação de chaves uma a uma através da cache de chaves. Isto é muito mais lento que Repair by sorting.

  • Searching rows for update A thread esta fazendo uma primeira fase pra encontrar todos os registros coincidentes antes de atualizá-los. Isto deve ser feito se o UPDATE está alterando o índice usado para encontrar os registros envolvidos.

  • Sleeping A thread está esperando que o cliente envie um novo comando a ela.

  • System lock A thread está esperando um lock de sistema externo para a tabela. Se você não está usando múltiplos servidores mysqld que estão acessando a mesma tabela, você pode desabilitar o lock de sistema com a opção --skip-external-locking.

  • Upgrading lock O manipulador de INSERT DELAYED está tentando obter um lock para inserir registros na tabela.

  • Updating A thread está procurando por registros para atualizá-los.

  • User Lock A thread está esperando um GET_LOCK().

  • Waiting for tables A thread recebeu uma notificação que a estrutura de uma tabela foi alterada e ela precisa reabrir a tabela para receber a nova estrutura. Para poder reabrir a tabela ela deve esperar até que todas a outras threads tenham fechado a tabela em questão.

    A notificação acontece se outra thread usou FLUSH TABLES ou um dos seguintes comando na tabela em questão: FLUSH TABLES nome_tabela, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE ou OPTIMIZE TABLE.

  • waiting for handler insert O manipulador do INSERT DELAYED processou todas as inserções e está esperado por outras.

A maioria dos estados são operações muito rápidas. Se a thread permanecer em qualquer destes estados por muitos segundos, pode haver um problema que precisa ser investigado.

Existem outros estados que não são mencionados anteriormente, mas a maioia deles só são úteis para encontrar erros no mysqld.

4.6.8.7. SHOW GRANTS

SHOW GRANTS FOR usuário lista os comandos concedidos que devem ser usados para duplicar os direitos de um usuário.

mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

Para listar as permissões da sessão atual pode-se usar a função CURRENT_USER() (nova na versão 4.0.6) para descobrir com qual usuário a sessão foi autenticada. Veja mais informações sobre isto na Seção 6.3.6.2, “Funções Diversas”.

4.6.8.8. SHOW CREATE TABLE

Exibe uma instrução CREATE TABLE que irá criar a seguinte tabela:

mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE t (
  id INT(11) default NULL auto_increment,
  s char(60) default NULL,
  PRIMARY KEY (id)
) TYPE=MyISAM

SHOW CREATE TABLE cita os nomes de colunas e tabelas de acordo com o valor da opção SQL_QUOTE_SHOW_CREATE. Seção 5.5.6, “Sintaxe de SET.

4.6.8.9. SHOW WARNINGS | ERRORS

SHOW WARNINGS [LIMIT row_count]
SHOW ERRORS [LIMIT row_count]

Este comando é implementado no MySQL 4.1.0.

Ele mostra os erros,a visos e notas recebidos para o último comando. Os erros/avisos são reiniciados para cada comando que utiliza uma tabela.

O servidor MySQL envia de volta o número total de avisos e erros que você recebe para o último comando; Isto pode ser retornado chamando mysql_warning_count().

Até as mensagens max_error_count são armazenadas (variáveis global e específicas da thread).

Você pode recuperar o número de erros de @error_count e avisos de @warning_count.

SHOW WARNINGS mostra todos os erros, avisos e notas que você recebeu para o último comando enquanto SHOW ERRORS lhe mostra apenas o erro.

mysql> DROP TABLE IF EXISTS no_such_table;
mysql> SHOW WARNINGS;

+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1051 | Unknown table 'no_such_table' |
+-------+------+-------------------------------+

Note que no MySQL 4.1.0 apenas adicionamos a estrutura para avisos e poucos comandos MySQL ainda geraram avisos. A versão 4.1.1 suporta todos os tipos de avisos para LOAD DATA INFILE e instruções DML tais como os comandos INSERT, UPDATE e ALTER.

Por exemplo, aqui está um caso simple que produz avisos de conversão para instruções de inserção.

mysql> create table t1(a tinyint NOT NULL, b char(4));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(10,'mysql'),(NULL,'test'),(300,'open source');
Query OK, 3 rows affected, 4 warnings (0.15 sec)
Records: 3  Duplicates: 0  Warnings: 4

mysql> show warnings;
+---------+------+---------------------------------------------------------------+
| Level   | Code | Message                                                       |
+---------+------+---------------------------------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1                        |
| Warning | 1261 | Data truncated, NULL supplied to NOT NULL column 'a' at row 2 |
| Warning | 1262 | Data truncated, out of range for column 'a' at row 3          |
| Warning | 1263 | Data truncated for column 'b' at row 3                        |
+---------+------+---------------------------------------------------------------+
4 rows in set (0.00 sec)

O número máximo de avisos pode ser específicado usando a variável do servidor 'max_error_count', SET max_error_count=[count]; Por padrão é 64. No caso de avisos desabilitados, simplesmente zere esta variável. No caso de max_error_count ser 0, então o contador de avisos ainda representa quantos avisos ocorreram, mas nenhuma das mensagens são armazenadas.

Por exemplo, considere o seguinte instrução de tabela ALTER para o exemplo acima, o qual retorna apenas um mensagem de aviso embora o total de avisos seja 3, ao definir max_error_count=1.

mysql> show variables like 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> set max_error_count=1;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table t1 modify b char;
Query OK, 3 rows affected, 3 warnings (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 3

mysql> show warnings;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)

mysql>

4.6.8.10. SHOW TABLE TYPES

SHOW TABLE TYPES

Este comando é implementado no MySQL 4.1.0.

SHOW TABLE TYPES lhe mostra a informação de status sobre o tipo de tabela. Isto é particulamente útil para verificar se um tipo de tabela é suportado; ou para ver qual é o tipo de tabela padrão.

mysql> SHOW TABLE TYPES;

+--------+---------+-----------------------------------------------------------+
| Type   | Support | Comment                                                   |
+--------+---------+-----------------------------------------------------------+
| MyISAM | DEFAULT | Default type from 3.23 with great performance             |
| HEAP   | YES     | Hash based, stored in memory, useful for temporary tables |
| MERGE  | YES     | Collection of identical MyISAM tables                     |
| ISAM   | YES     | Obsolete table type; Is replaced by MyISAM                |
| InnoDB | YES     | Supports transactions, row-level locking and foreign keys |
| BDB    | NO      | Supports transactions and page-level locking              |
+--------+---------+-----------------------------------------------------------+
6 rows in set (0.00 sec)

A opção 'Support' DEFAULT indica se um tipo de tabela particular é é suportado, e qual é o tipo padrão. Se o servidor é iniciado com --default-table-type=InnoDB, então o campo 'Support' do InnoDB terá o valor DEFAULT.

4.6.8.11. SHOW PRIVILEGES

SHOW PRIVILEGES

Este comando é implementado no MySQL 4.1.0.

SHOW PRIVILEGES mostra a lista de privilégios de sistema o servidor MySQL suporta.

mysql> show privileges;
+------------+--------------------------+-------------------------------------------------------+
| Privilege  | Context                  | Comment                                               |
+------------+--------------------------+-------------------------------------------------------+
| Select     | Tables                   | To retrieve rows from table                           |
| Insert     | Tables                   | To insert data into tables                            |
| Update     | Tables                   | To update existing rows                               |
| Delete     | Tables                   | To delete existing rows                               |
| Index      | Tables                   | To create or drop indexes                             |
| Alter      | Tables                   | To alter the table                                    |
| Create     | Databases,Tables,Indexes | To create new databases and tables                    |
| Drop       | Databases,Tables         | To drop databases and tables                          |
| Grant      | Databases,Tables         | To give to other users those privileges you possess   |
| References | Databases,Tables         | To have references on tables                          |
| Reload     | Server Admin             | To reload or refresh tables, logs and privileges      |
| Shutdown   | Server Admin             | To shutdown the server                                |
| Process    | Server Admin             | To view the plain text of currently executing queries |
| File       | File access on server    | To read and write files on the server                 |
+------------+--------------------------+-------------------------------------------------------+
14 rows in set (0.00 sec)

4.7. Localização do MySQL e Utilização Internacional

4.7.1. O Conjunto de Caracteres Utilizado para Dados e Ordenação

Por padrão, o MySQL utiliza o conjunto de caracteres ISO-8859-1 (Latin1) com ordenação de acordo com o sueco/finlandês. Este também é o conjunto de caracteres aplicável nos EUA e oeste da Europa.

Todos os binários padrões do MySQL são compilados com --with-extra-charsets=complex. Isto adicionará código a todos os programas padrões para estarem aptos a lidar com o conjuntos de caracteres latin1 e todos os multi-byte no binário. Outros conjuntos de caracteres serão carregados de um arquivo de definições de conjuntos de caracteres quando necessários.

O conjunto de caracteres determina quais são os caracteres permitidos em nomes e qual a forma de ordenação por cláusulas ORDER BY e GROUP BY da instrução SELECT.

Você pode alterar o conjunto de caracteres com a opção --default-character-set na inicialização do servidor. Os conjuntos de caracteres disponíveis dependem dos parâmetros --with-charset=charset e --with-extra-charset= list-of-charset | complex | all | none e os arquivos de configurações de conjuntos de caracteres listados em SHAREDIR/charsets/ Index. Veja mais informações sobre isto na Seção 2.3.3, “Opções típicas do configure.

Se o conjunto de caracteres for alterado durante a execução do MySQL (que também pode alterar a ordenação), deve-se executar o 0myisamchk -r -q --set-character-set=charset em todas as tabelas. De outra forma seus índices podem não ser ordenados corretamente.

Quando um cliente conecta a um servidor MySQL, o servidor envia o conjunto de caracteres padrão em uso ao cliente. O cliente irá alternar para o uso deste conjunto de caracteres nesta conexão.

Deve ser utilizado mysql_real_escape_string() quando desejar ignorar seguências de caracteres em uma consulta SQL. mysql_real_escape_string() é identico à antiga função mysql_espace_string(), exceto pelo fato de usar a manipulador de conexão MySQL como o primeiro parâmetro.

Se o cliente for compilado com o caminho diferente daquele onde o servidor está instalado e o usuário que configurou o MySQL não incluiu todos os conjuntos de caracteres no binários do MySQL, deve ser especificado para o cliente onde ele pode encontrar os conjuntos de caracteres adcicionais que serão necessários se o servidor executar com um conjunto de caracteres diferente do cliente.

Isto pode ser especificado colocando em um arquivo de opções do MySQL:

[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets

onde o caminho aponta para onde os conjuntos de caracteres dinâmicos do MySQL são armazenados.

Pode-se forçar o cliente a usar conjuntos de caracteres específicos especificando:

[client]
default-character-set=nome-conjunto-caracteres

mas normalmente isto nunca será necessário.

4.7.1.1. German character set

Para se fazer ordenação em Alemão, você deve iniciar o mysqld com --default-character-set=latin1_de. Isto lhe dará as seguintes caracteristicas.

Ao ordenar e comparar strings, o seguinte mapeamento é feito na string antes de fazer a comparação:

ä ->  ae
ö  ->  oe
ü  ->  ue
ß  ->  ss

Todos os caracteres acentuados, são convertidos para suas contra partes sem acentos e em letras maiúsculas. Todas as letras são convertidas para maiúsculas.

Ao compara strings com LIKE o mapeamento de caracteres de um -> dois não é feito. Todas as letras são convertidas para maiúsculas. Acentos são removidos para todas as letras exceto: Ü, ü, Ö, ö, Ä e ä.

4.7.2. Mensagens de Erros em Outras Línguas

mysqld pode exibir mensagens de erros nas seguintes línguas: Tcheco, Dinamarquês, Holandês, Inglês (padrão), Estonian, Francês, Alemão, Grego, Húngaro, Italiano, Japonês, Koreano, Norueguês, Norueguês-ny, Polonês, Português, Romeno, Russo, Eslovaco, Espanhol e Sueco.

Para iniciar o mysqld com uma língua particular, use uma das opções: --language=língua ou -L língua . Por exemplo:

shell> mysqld --language=swedish

ou:

shell> mysqld --language=/usr/local/share/swedish

Perceba que todos as línguas são especificados em minúsculas.

Os arquivos de linguagens estão localizados (por padrão) em mysql_base_dir/share/LANGUAGE/.

Para atualizar o arquivo com mensagens de erros, deve-se editar o arquivo errmsg.txt e executar o seguinte comando para gerar o arquivo errmsg.sys:

shell> comp_err errmsg.txt errmsg.sys

Se você atualizar o MySQL para uma versão mais nova, lembre-se de repetir as alterações no novo arquivo errmsg.txt.

4.7.3. Adicionando um Novo Conjunto de Caracteres

Para adicionar outro conjunto de caracteres ao MySQL, utilize o seguinte procedimento.

Decida se o conjunto é simples ou complexo. Se o conjunto de caracteres não necessitar do uso de rotinas especiais de classificação de strings para ordenação e também não necessitar de suporte à caracteres multi-byte, será simples. Se ele necessitar de alguns destes recursos, será complexo.

Por exemplo, latin1 e danish são conjuntos simples de caracteres enquanto big5 ou czech são conjuntos de caracteres complexos.

Na seguinte seção, assumimos que você nomeou seu conjunto de caracteres como MYSET.

Para um conjunto de caracteres simples use o seguinte:

  1. Adicione MYSET para o final do arquivo sql/share/charsets/Index Associe um número único ao mesmo.

  2. Crie o arquivo sql/share/charsets/MYSET.conf. (O arquivo sql/share/charsets/latin1.conf pode ser utilizado como base para isto).

    A sintaxe para o arquivo é muito simples:

    • Comentários iniciam com um caractere '#' e continuam até o fim da linha.

    • Palavras são separadas por quantidades arbitrárias de espaços em brancos.

    • Ao definir o conjunto de caracteres, cada palavra deve ser um número no formato hexadecimal

    • O vetor ctype obtêm as primeiras 257 palavras. Os vetores to_lower, to_upper e sort_order obtêm, cada um, as 256 palavras seguintes.

    Veja mais informações sobre isto na Seção 4.7.4, “Os Vetores de Definições de Caracteres”.

  3. Adicione o nome do conjunto de caracteres às listas CHARSETS_AVAILABLE e COMPILED_CHARSETS no configure.in.

  4. Reconfigure, recompile e teste.

Para um conjunto de caracteres complexo faça o seguinte:

  1. Crie o arquivo strings/ctype-MYSET.c na distribuição fonte do MYSQL.

  2. Adicione MYSET ao final do arquivo sql/share/charsets/Index. Associe um número único a ele.

  3. Procure por um dos arquivos ctype-*.c existentes para ver o que precisa ser definido, por exemplo strings/ctype-big5.c. Perceba que os vetores no seu arquivo deve ter nomes como ctype_MYSET, to_lower_MYSET e etc. Isto corresponde aos arrays no conjunto simples de caracteres - Seção 4.7.4, “Os Vetores de Definições de Caracteres” - para um conjunto de caracteres complexo.

  4. Próximo ao topo do arquivo, coloque um comentário especial como este:

    /*
     * This comment is parsed by configure to create ctype.c,
     * so don't change it unless you know what you are doing.
     *
     * .configure. number_MYSET=MYNUMBER
     * .configure. strxfrm_multiply_MYSET=N
     * .configure. mbmaxlen_MYSET=N
     */
    

    O programa configure utiliza este comentário para incluir o conjunto de caracteres na biblioteca MySQL automaticamente.

    As linhas strxfrm_multiply e mbmaxlen serão explicadas nas próximas seções. Só as inclua se você precisar de funções de ordenação de strings ou das funções de conjuntos de caracteres multi-byte, respectivamente.

  5. Você deve então criar algumas das seguintes funções:

    • my_strncoll_MYSET()

    • my_strcoll_MYSET()

    • my_strxfrm_MYSET()

    • my_like_range_MYSET()

    Veja mais informações sobre isto na Seção 4.7.5, “Suporte à Ordenação de Strings”.

  6. Adicione o nome do conjunto de caracteres às listas CHARSETS_AVAILABLE e COMPILED_CHARSETS no configure.in.

  7. Reconfigure, recompile e teste.

O arquivo sql/share/charsets/README fornece algumas instruções a mais.

Se você desejar ter o seu conjunto de caracteres incluído na distribuição MySQL, envie um email com um patch para a lista de email ``internals'' do MySQL. Veja mais informações sobre isto na Seção 1.7.1.1, “As Listas de Discussão do MySQL”.

4.7.4. Os Vetores de Definições de Caracteres

to_lower[] e to_upper[] são vetores simples que definemm os caracteres minúsculos e maísculos correspondentes a cada membro do conjunto de caracteres. Por exemplo:

to_lower['A'] deve conter 'a'
to_upper['a'] deve conter 'A'

sort_order[] é um mapa indicando como os caracteres devem ser ordenados para propósitos de comparação e ordenação. Para vários conjuntos de caracteres, isto é o mesmo que to_upper[] (que significa ordenar em caso insensitivo). O MySQL ordenará caracteres baseado no valor de sort_order[caractere]. Para regras mais complicadas de ordenação, veja a discussão sobre ordenação de string abaixo. Veja mais informações sobre isto na Seção 4.7.5, “Suporte à Ordenação de Strings”.

ctype[] é um vetor com valores binários, com um elemento para cada caracter. (Note que to_lower[], to_upper[] e sort_order[] são indexados pelo valor do caracter, mas o ctype[] é indexado pelo valor do caracter + 1. Este é um antigo legado para tratamento de EOF.)

Pode-se encontrar as seguintes máscaras binárias de definições em m_ctype.h:

#define _U      01      /* Maísculo */
#define _L      02      /* Minúsculo */
#define _N      04      /* Numeral (digito) */
#define _S      010     /* Caractere de espaço */
#define _P      020     /* Pontuação */
#define _C      040     /* Caractere de controle */
#define _B      0100    /* Branco */
#define _X      0200    /* Digito heXadecimal */

A entrada ctype[] para cada caracter deve ser a união dos valores da máscara binária que descrevem o caracter. Por exemplo, 'A' é um caracter maiúsculo (_U) bem como um dígito hexadecimal (_X), portanto ctype['A'+1] deve conter o valor:

_U + _X = 01 + 0200 = 0201

4.7.5. Suporte à Ordenação de Strings

Se as regras de ordenação para a sua linguagem forem muito complexas para serem tratadas com uma simples tabela sort_order[], será necessário o uso das funções de ordenação de strings.

No momento, a melhor documentação sobre isto são os conjuntos de caracteres que já estão implementados. Confira os conjuntos de caracteres big5, czech, gbk, sjis e tis160 para exemplos.

Você deve especificar o valor strxfrm_multiply_MYSET=N no comentário especial no topo do arquivo. N deve ser configurado para a razão máxima que as strings podem crescer durante my_strxfrm_MYSET (ele deve ser um inteiro positivo).

4.7.6. Suporte à Caracteres Multi-byte

Se você deseja adicionar suporte para novos conjuntos de caracteres que incluem caracteres multi-byte, você precisa usar as funções para caracteres multi-byte.

No momento, a melhor documentação sobre isto são os conjuntos de caracteres que já estão implementados. Confira os conjuntos de caracteres euc_kr, gb2312, gbk, sjis e ujis para exemplos. Eles são implementados no arquivo ctype-'conj_caracter'.c no diretório strings

Você deve especificar o valor mbmaxlen_MYSET=N no comentário especial no topo do arquivo. N deve ser configurado como o tamanho em bytes do maior caracter no conjunto.

4.7.7. Problemas com Conjuntos de Caracteres

Se você tentar usar um conjunto de caractere que não foi compilado dentro do se binário, você pode encontrar aluguns problemas:

  • Seu programa tem um caminho errado para onde o conjunto de caracter está armazenado (Padrão /usr/local/mysql/share/mysql/charsets). Isto pode ser corrigido usando a opção --character-sets-dir para o programa em questão.

  • O conjunto sde caracteres é multi-byte e não pode ser carregado dinamicamente. Neste caso você tem que recompilar o programa com o suporte para o conjunto de caracteres.

  • O conjunto de caracteres é dinâmica, mas você não tem um arquivo de configuração para ele. Neste caso você deve instalar o arquivo configure para o conjunto de caracteres de uma nova distriibuição do MySQL.

  • Seu arquivo Index não contém o nome do conjunto de caracteres.

    ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
    (Errcode: 2)
    

    Neste caso você deve obter um novo arquivo Index ou adicionar o nome do conjunto de caracters que falta manualmente.

Para tabelas MyISAM, você pode vericifcar o nome e número do conjunto de caracteres para uma tabela com myisamchk -dvv nome_tabela.

4.8. Utilitários e Scripts do Lado do Servidor MySQL

4.8.1. Visão Geral dos Scripts e Utilitários do Lado Servidor

Todos os programas MySQL possuem várias opções diferentes, entretanto, todo programa MySQL fornece uma opção --help que pode ser usada para obter uma descrição completa das diferentes opções do programa. Por exemplo, experimente mysql --help.

Você pode sobrepor ignorar as opções padrões para todos os programas clientes com um arquivo de opções. Seção 4.1.2, “Arquivo de Opções my.cnf.

A lista abaixo descreve brevemente os programas MySQL.

  • myisamchk

    Utilitário para descrever, conferir, otimizar e reparar tabelas MySQL. Como o myisamchk tem muitas funções, eles são descritos em seu próprio capítulo. See Capítulo 4, Administração do Bancos de Dados MySQL.

  • make_binary_distribution

    Cria uma edição binária de um MySQL compilado. Isto pode ser enviado por FTP para /pub/mysql/Incoming em support.mysql.com para a conveniência de outros usuários MySQL.

  • mysqlbug

    O script para relatar erros no MySQL. Este script deve sempre ser utilizado quando for necessário preencher um relatório de erros para a lista do MySQL.

  • mysqld

    O servidor (daemon) SQL. Deve sempre estar em execução.

  • mysql_install_db

    Cria as tabelas de permissões do MySQL com os privilégios padrões. Este comando normalmente é executado somente na primeira vez quando o MySQL é instalado em um sistema.

4.8.2. mysqld-safe, o wrapper do mysqld

mysqld_safe é a maneira recomendada para iniciar um daemon mysqld no Unix. mysqld_safe adiciona alguns recursos de segurança tais como reiniciar o servidor quando um erro ocorrer e log de informações de tempo de execução a um arquivo log.

Note: Antes do MySQL 4.0, mysqld_safe é chamado safe_mysqld. Para preservar a compatibilidade com versões anteriores, a distribuição binária do MySQL para algumas vezes incluirá safe_mysqld como um link simbólico para mysqld_safe.

Se você não utilizar --mysqld=# ou --mysql-version=# o mysqld_safe irá utilizar um executável chamado mysqld-max se ele existir. Se não, mysqld_safe irá iniciar o mysqld. Isto torna muito fácil utilizar o mysql-max no lugar do mysqld; basta copiar mysqld-max no mesmo diretório do mysqld e ele será utillizado.

Normalmente o script mysqld_safe nunca deve ser editado, em vez disto, coloque as opções para o mysqld_safe na seção [mysqld_safe] no arquivo my.cnf. O mysqld_safe irá ler todas as opções das seções [mysqld], [server] e [mysqld_safe] dos arquivos de opções. (Para compatibilidade com versões anteriores, ele também lê as seções [safe_mysqld].) Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

Note que todas as opções na linha de comando para o mysqld_safe são passadas para o mysqld. Se você deseja usar algumas opções no mysqld_safe que o mysqld não suporte, você deve especificá-las no arquivo de opções.

A maioria das opções para mysqld_safe são as mesmas que as do mysqld. Veja mais informações sobre isto na Seção 4.1.1, “Opções de Linha de Comando do mysqld.

mysqld_safe suporta as seguintes opções:

  • --basedir=caminho, --core-file-size=#

    Tamanho do arquivo core que o mysqld poderá criar. Passado para ulimit -c.

  • --datadir=caminho, --defaults-extra-file=caminho, --defaults-file=caminho, --err-log=caminho, --log-error=caminho

    Gava o log de erro no caminho acima. See Seção 4.10.1, “O Log de Erros”.

  • --ledir=caminho

    Caminho para mysqld

  • --log=caminho, --mysqld=versão_do_mysqld

    Nome da versão do mysqld no diretório ledir que você deseja iniciar.

  • --mysqld-version=versão

    Similar ao --mysqld= mas aqui você só fornece o sufixo para o mysqld. Por exemplo, se você utiliza --mysqld-version=max, o mysqld_safe irá iniciar a versão ledir/mysqld-max. Se o argumento para --mysqld-version estiver vazio, ledir/mysqld será usado.

  • --nice=# (adicionado no MySQL 4.0.14), --no-defaults, --open-files-limit=#

    Número de arquivos que o mysqld poderá abrir. Passado para ulimit -n. Perceba que será necessário iniciar mysqld_safe como root para isto funcionar corretamente!

  • --pid-file=caminho, --port=#, --socket=caminho, --timezone=#

    Configura a variável de fuso horário (TZ) para o valor deste parâmetro.

  • --user=#

O script mysqld_safe é gravável, portanto ele deve estar apto para iniciar um servidor que foi instalado de uma fonte ou uma versão binária do MySQL, mesmo se o servidor estiver instalado em localizações um pouco diferentes. mysqld_safe espera uma destas condições ser verdadeira:

  • O servidor e o banco de dados pode ser encontrado relativo ao diretório de onde o mysqld_safe foi chamado. mysqld_safe procura dentro de seu diretório de trabalho pelos diretórios bin e data (para distribuições binárias) ou pelos diretórios libexec e var (para distribuições baseadas em código fonte). Esta condição deve ser satisfeita se você executar o mysqld_safe a partir do seu diretório da instalação do MySQL (por exemplo, /usr/local/mysql para uma distribuição binária).

  • Se o servidor e os bancos de dados não forem encontrados relativos ao diretório de trabalho, mysqld_safe tenta localizá-lo utilizando caminhos absolutos. Localizações típicas são /usr/local/libexec e /usr/local/var. As localizações atuais foram determinadas quando a distribuição foi construída da qual vem o mysqld_safe. Eles dever estar corretas se o MySQL foi instalado na localização padrão.

Como o mysqld_safe tentará encontrar o servidor e o banco de dados relativo a seu diretório de trabalho, você pode instalar uma distribuição binária do MySQL em qualquer lugar, desde de que o mysqld_safe seja iniciado a partir do diretório da instalação:

shell> cd diretório_instalação_mysql
shell> bin/mysqld_safe &

Se o mysqld_safe falhar, mesmo se invocado a partir do diretório de instalação do MySQL, você pode modificá-lo para usar o caminho para o mysqld e as opções de caminho que seriam corretas para seu sistema. Perceba que se você atualizar o MySQL no futuro, sua versão modificada de mysqld_safe será sobrescrita, portanto, você deve fazer uma cópia de sua versão editada para que você a possa reinstalar.

4.8.3. mysqld_multi, programa para gerenciar múltiplos servidores MySQL

mysqld_multi gerencia vários processos mysqld executando em diferentes sockets UNIX e portas TCP/IP.

O programa irá pesquisar pelos grupos chamados [mysqld#] no my.cnf (ou no arquivo fornecido no parâmetro --config-file=...), onde # pode ser qualquer número positivo a partir de 1. Este número é referenciado a seguir como número do grupo de opções ou GNR. Números de grupos distinguem grupos de opções para um outro e são usados como argumentos para mysqld_multi para especificar quais servidores você deseja iniciar, parar ou obter status. Opções listadas nestes grupos devem ser a mesma que você usaria para iniciar o mysqld. (Veja mais informações sobre isto na Seção 2.4.3, “Inicializando e parando o MySQL automaticamente.”). No entanto, para o mysqld_multi, esteja certo que cada grupo inclui opções de valores tais como a porta, socket, etc., para ser usado para cada processo mysqld individual.

Uso: mysqld_multi [OPÇÕES] {start|stop|report} [GNR,GNR,GNR...]
ou   mysqld_multi [OPÇÕES] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]

O GNR acima significa o número do grupo. Você pode iniciar, parar ou relacionar qualquer GNR ou vários deles ao mesmo tempo. (Veja --example). A lista dos GNR podem ser separadas por vírgulas, ou pelo sinal sinal de menos (-), sendo que o ultimo significa que todos os GNRS entre GNR1-GNR2 serão afetados. Sem o argumento GNR todos os grupos encontrados serão iniciados, parados ou listados. Perceba que você não deve ter nenhum espaço em branco na lista GNR. Qualquer coisa depois de um espaço em branco é ignorado.

mysqld_multi suporta as seguintes opções:

  • --config-file=...

    Arquivo de configuração alternativo. NOTA: Isto não irá afetar as próprias opções do programa (grupo [mysqld_multi]), mas somente grupos [mysqld#]. Sem esta opção tudo será procurado a partir do arquivo my.cnf.

  • --example

    Fornece um exemplo de um arquivo de configuração.

  • --help

    Exibe esta ajuda e sai.

  • --log=...

    Arquivo Log. Deve ser informado o caminho completo e o nome do arquivo log. NOTA: se o arquivo existir, tudo será anexado.

  • --mysqladmin=...

    Binário mysqladmin a ser usado para o desligamento do servidor.

  • --mysqld=...

    Binário mysqld a ser usado. Lembre-se que você também pode fornecer mysqld_safe a esta opção. As opções são passadas ao mysqld. Apenas tenha certeza que o mysqld está localizado na sua variável de ambiente PATH ou corrija o mysqld_safe.

  • --no-log

    Imprime na saída padrão em vez do arquivo log. Por padrão o arquivo log sempre fica ligado.

  • --password=...

    Senha do usuário para o mysqladmin.

  • --tcp-ip

    Conecta ao(s) servidor(es) MySQL através de porta TCP/IP no lugar de socket UNIX. Isto afeta a ação de desligar e relatar. Se um arquivo socket estiver faltando, o servidor pode ainda estar executando, mas só pode ser acessado através da porta TCP/IP. Por padrão a conexão é feita através de socket UNIX.

  • --user=...

    Usuário MySQL para o mysqladmin.

  • --version

    Exibe o número da versão e sai.

Algumas notas sobre mysqld_multi:

  • Tenha certeza que o usuário MySQL, que finalizar os serviços mysqld (e.g. utilizando o mysqladmin) tem a mesma senha e usuário para todos os diretórios de dados acessados (para o banco de dados 'mysql'). E tenha certeza que o usuário tem o privilégio 'Shutdown_priv'! Se você possui diversos diretórios de dados e vários bancos de dados 'mysql' com diferentes senhas para o usuário 'root' do MySQL, você pode desejar criar um usuário comum 'multi-admin' para cada um que utilize a mesma senha (veja abaixo). Exemplo de como fazer isto:

    shell> mysql -u root -S /tmp/mysql.sock -psenha_root -e
    "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY 'multipass'"
    Veja mais informações sobre isto na Seção 4.3.6, “Como o Sistema de Privilégios Funciona”.
    

    Você deve fazer isto para cada servidor mysqld executando em cada diretório de dados, que você tem (Apenas altere o socket, -S=...)

  • pid-file é muito importante, se você estiver utilizando mysqld_safe para iniciar o mysqld (ex. --mysqld=mysqld_safe) Todos os mysqld devem ter seus próprios pid-file. A vantagem de utilizar o mysqld_safe no lugar de executar diretamente o mysqld é que mysqld_safe guarda todos os processos e irá reiniciá-los, se um processo do mysqld falhar devido a um sinal kill -9, ou similar. (Como um falha de segmentação, que nunca pode acontecer com o MySQL.) Por favor note que pode ser necessário executar o script mysqld_safe de um lugar específico. Isto significa que você pode ter que alterar o diretório atual para um diretório específico antes de iniciar o mysqld_multi. Se você tiver problemas ao iniciar, por favor veja o script mysqld_safe. Verifique especialmente as linhas:

    --------------------------------------------------------------------------
    MY_PWD=`pwd` Check if we are starting this relative (for the binary
    release) if test -d /data/mysql -a -f ./share/mysql/english/errmsg.sys
    -a -x ./bin/mysqld
    --------------------------------------------------------------------------
    

    Veja mais informações sobre isto na Seção 4.8.2, “mysqld-safe, o wrapper do mysqld. O teste acima deve ser bem sucedido, ou você pode encontrar problemas.

  • Esteja certo do perigoso de iniciar múltiplos mysqlds no mesmo diretório de dados. Utilize diretórios de dados diferentes, a menos que você realmente SAIBA o que está fazendo!

  • O arquivo de socket e a porta TCP/IP devem ser diferentes para cada mysqld.

  • O primeiro e quinto grupo mysqld foram intencionalmente deixados de lado no exemplo. Você pode ter lacunas no arquivo de configuração. Isto lhe permite mais flexibilidade. A ordem na qual os mysqlds são iniciados ou desligados depende da ordem em que eles aparecem no arquivo de configuração.

  • Quando você desejar referenciar a um grupo específico utilizando GNR com este programa, basta utilizar o número no fim do nome do grupo ([mysqld# <==).

  • Você pode desejar utilizar a opção '--user' para o mysqld, mas para isto você precisa ser o usuário root quando iniciar o script mysqld_multi. Não importa se a opção existe no arquivo de configuração; você receberá apenas um alerta se você não for o superusuário e o mysqlds for iniciado com a SUA conta no Unix. IMPORTANTE: Tenha certeza que o pid-file e o diretório de dados é acessível para leitura e escrita (+execução para o diretório) para ESTE usuário UNIX que iniciará o processo mysqld. NÃO utilize a conta de root para isto, a menos que você SAIBA o que está fazendo!

  • MAIS IMPORTANTE: Tenha certeza que você entendeu os significados das opções que são passadas para os mysqlds e porque VOCÊ PRECISARIA ter processos mysqld separados. Iniciando múltiplos mysqlds em um diretório de dados NÃO IRÁ melhorar a performance em um sistema baseado em threads.

Veja mais informações sobre isto na Seção 4.2, “Executando Múltiplos MySQL Servers na Mesma Máquina”.

Este é um exemplo do arquivo de configuração para o funcionamento do mysqld_multi.

# Este arquivo provavelmente deve estar em seu diretório home (~/.my.cnf) ou /etc/my.cnf
# Version 2.1 by Jani Tolonen

[mysqld_multi]
mysqld     = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = multipass

[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/var2/hostname.pid2
datadir    = /usr/local/mysql/var2
language   = /usr/local/share/mysql/english
user       = john

[mysqld3]
socket     = /tmp/mysql.sock3
port       = 3308
pid-file   = /usr/local/mysql/var3/hostname.pid3
datadir    = /usr/local/mysql/var3
language   = /usr/local/share/mysql/swedish
user       = monty

[mysqld4]
socket     = /tmp/mysql.sock4
port       = 3309
pid-file   = /usr/local/mysql/var4/hostname.pid4
datadir    = /usr/local/mysql/var4
language   = /usr/local/share/mysql/estonia
user       = tonu

[mysqld6]
socket     = /tmp/mysql.sock6
port       = 3311
pid-file   = /usr/local/mysql/var6/hostname.pid6
datadir    = /usr/local/mysql/var6
language   = /usr/local/share/mysql/japanese
user       = jani

Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

4.8.4. myisampack, O Gerador de Tabelas Compactadas de Somente Leitura do MySQL

myisampack é usado para compactar tabelas MyISAM, e pack_isam é usado para compactar tabelas ISAM. Como as tabelas ISAM estão ultrapassadas, nós iremos discutir aqui somente sobre o myisampack, mas tudo dito sobre myisampack também pode ser verdadeiro para o pack_isam.

myisampack trabalha compactando cada coluna na tabela separadamente. A informação necessária para descompactar colunas é lida em memória quando a tabela é aberta. Isto resulta em uma performance muito melhor quando estiver acessando registros individuais, porque você precisará descompactar somente um registro, não um bloco muito maior do disco como faz o Stacker no MS-DOS. Normalmente, myisampack compacta o arquivo de dados 40%-70%.

O MySQL utiliza mapeamento de memória (nmap()) em tabelas compactadas e retorna ao uso normal de leitura e escrita se nmap() não funcionar.

Por favor, note o seguinte:

  • Depois de comapctada, a tabela é somente-leitura. Isto é, normalmente, pretendido (como quando acessamos tabelas compactadas em um CD). Permitir que se faça gravação em uma tabela compactada também está em nossa lista TODO, mas com baixa prioridade.

  • myisampack também pode compactar colunas BLOB ou TEXT. O antigo pack_isam (para tabelas ISAM) não pode fazer isto.

myisampack é chamado desta forma:

shell> myisampack [opções] nome_arquivo ...

Cada nome_arquivo deve ter o nome de um arquivo de índice (.MYI). Se você não se encontra em um diretório de bancos de dados, você deve especificar o caminho completo para o arquivo. Pode-se omitir a extensão .MYI.

myisampack suporta as seguintes opções:

  • -b, --backup

    Realiza um backup da tabela como nome_tabela.OLD.

  • -#, --debug=debug_options

    Log da saída de depuração. A string debug_options geralmante é 'd:t:o,nome_arquivo'.

  • -f, --force

    Força a compactação da tabela mesmo se ela se tornar maior ou se o arquivo temporário existir. myisampack cria um arquivo temporário chamado nome_tabela.TMD enquanto ele compacta a tabela. Se você matar o myisampack o arquivo .TMD não pode ser removido. Normalmente, myisampack sai com um erro se ele descobrir que nome_tabela.TMD existe. Com --force, myisampack compacta a tabela de qualquer maneira.

  • -?, --help

    Exibe uma mensagem de ajuda e sai.

  • -j nome_tabela_grande, --join=nome_tabela_grande

    Une todas as tabelas nomeadas na linha de comando em uma única tabela nome_tabela_grande. Todas tabelas que forem combinadas DEVEM ser idênticas (mesmos nomes de colunas e tipos, alguns índices, etc.).

  • -p #, --packlength=#

    Especifica o comprimento do tamanho de armazenamento, em bytes. O valor deve ser 1, 2 ou 3. (myisampack armazena todas as linhas com ponteiros de tamanhos 1, 2 ou 3 bytes. Na maioria dos casos normais, myisampack pode determinar o valor correto do tamanho antes de começar a compactar o arquivo, mas ele pode notificar durante o processo de compactação que ele pode ter usado um tamanho menor. Neste caso myisampack irá exibir uma nota dizendo que a próxima vez que você compactar o mesmo arquivo você pode utilizar um registro de tamanho menor.)

  • -s, --silent

    Modo silencioso. Escreve a saída somente quando algum erro ocorrer.

  • -t, --test

    Não compacta realmente a tabela, apenas testa a sua compactação.

  • -T dir_name, --tmp_dir=dir_name

    Utiliza o diretório especificado como a localização em que serão gravadas as tabelas temporárias.

  • -v, --verbose

    Modo verbose. Escreve informação sobre o prograsso e resultado da compactação.

  • -V, --version

    Exibe informação de versão e sai.

  • -w, --wait

    Espera e tenta novamente se a tabela estiver em uso. Se o servidor mysqld foi iniciado com a opção --skip-locking, não é uma boa idéia chamar myisampack se a tabela puder ser atualizada durante o processo de compactação.

A seqüência de comandos mostrados abaixo ilustra uma típica seção de compactação de tabelas:

shell> ls -l station.*
-rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-02-02  3:06:43
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafile pointer (bytes):     2  Keyfile pointer (bytes):     2
Max datafile length:   54657023  Max keyfile length:   33554431
Recordlength:               834
Record format: Fixed length

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long              1024       1024          1
2   32    30  multip. text                      10240       1024          1

Field Start Length Type
1     1     1
2     2     4
3     6     4
4     10    1
5     11    20
6     31    1
7     32    30
8     62    35
9     97    35
10    132   35
11    167   4
12    171   16
13    187   35
14    222   4
15    226   16
16    242   20
17    262   20
18    282   20
19    302   30
20    332   4
21    336   4
22    340   1
23    341   8
24    349   8
25    357   8
26    365   2
27    367   2
28    369   4
29    373   4
30    377   1
31    378   2
32    380   8
33    388   4
34    392   4
35    396   4
36    400   4
37    404   1
38    405   4
39    409   4
40    413   4
41    417   4
42    421   4
43    425   4
44    429   20
45    449   30
46    479   1
47    480   1
48    481   79
49    560   79
50    639   79
51    718   79
52    797   8
53    805   1
54    806   1
55    807   20
56    827   4
57    831   4

shell> myisampack station.MYI
Compressing station.MYI: (1192 records)
- Calculating statistics

normal:     20  empty-space:      16  empty-zero:        12  empty-fill:  11
pre-space:   0  end-space:        12  table-lookups:      5  zero:         7
Original trees:  57  After join: 17
- Compressing file
87.14%

shell> ls -l station.*
-rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-04-17 19:04:26
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     1
Max datafile length:   16777215  Max keyfile length:     131071
Recordlength:               834
Record format: Compressed

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long             10240       1024          1
2   32    30  multip. text                      54272       1024          1

Field Start Length Type                         Huff tree  Bits
1     1     1      constant                             1     0
2     2     4      zerofill(1)                          2     9
3     6     4      no zeros, zerofill(1)                2     9
4     10    1                                           3     9
5     11    20     table-lookup                         4     0
6     31    1                                           3     9
7     32    30     no endspace, not_always              5     9
8     62    35     no endspace, not_always, no empty    6     9
9     97    35     no empty                             7     9
10    132   35     no endspace, not_always, no empty    6     9
11    167   4      zerofill(1)                          2     9
12    171   16     no endspace, not_always, no empty    5     9
13    187   35     no endspace, not_always, no empty    6     9
14    222   4      zerofill(1)                          2     9
15    226   16     no endspace, not_always, no empty    5     9
16    242   20     no endspace, not_always              8     9
17    262   20     no endspace, no empty                8     9
18    282   20     no endspace, no empty                5     9
19    302   30     no endspace, no empty                6     9
20    332   4      always zero                          2     9
21    336   4      always zero                          2     9
22    340   1                                           3     9
23    341   8      table-lookup                         9     0
24    349   8      table-lookup                        10     0
25    357   8      always zero                          2     9
26    365   2                                           2     9
27    367   2      no zeros, zerofill(1)                2     9
28    369   4      no zeros, zerofill(1)                2     9
29    373   4      table-lookup                        11     0
30    377   1                                           3     9
31    378   2      no zeros, zerofill(1)                2     9
32    380   8      no zeros                             2     9
33    388   4      always zero                          2     9
34    392   4      table-lookup                        12     0
35    396   4      no zeros, zerofill(1)               13     9
36    400   4      no zeros, zerofill(1)                2     9
37    404   1                                           2     9
38    405   4      no zeros                             2     9
39    409   4      always zero                          2     9
40    413   4      no zeros                             2     9
41    417   4      always zero                          2     9
42    421   4      no zeros                             2     9
43    425   4      always zero                          2     9
44    429   20     no empty                             3     9
45    449   30     no empty                             3     9
46    479   1                                          14     4
47    480   1                                          14     4
48    481   79     no endspace, no empty               15     9
49    560   79     no empty                             2     9
50    639   79     no empty                             2     9
51    718   79     no endspace                         16     9
52    797   8      no empty                             2     9
53    805   1                                          17     1
54    806   1                                           3     9
55    807   20     no empty                             3     9
56    827   4      no zeros, zerofill(2)                2     9
57    831   4      no zeros, zerofill(1)                2     9

A informação exibida pelo myisampack é descrita abaixo:

  • normal

    O número de colunas para qual nenhum empacotamento extra é utilizado.

  • empty-space

    O número de colunas contendo valores que são somente espaços; estes ocuparão apenas 1 bit.

  • empty-zero

    O número de colunas contendo valores que são somente 0's binários; ocuparão 1 bit.

  • empty-fill

    O número de colunas inteiras que não ocupam a faixa completa de bytes de seu tipo; estes são alteradas para um tipo menor (por exemplo, uma coluna INTEGER pode ser alterada para MEDIUMINT).

  • pre-space

    O número de colunas decimais que são armazenadas com espaços a esquerda. Neste caso, cada valor irá conter uma contagem para o número de espaços.

  • end-space

    O número de colunas que tem muitos espaços espaços extras. Neste caso, cada valor conterá uma contagem para o número de espaços sobrando.

  • table-lookup

    A coluna tem somente um pequeno número de valores diferentes, que são convertidos para um ENUM antes da compressão Huffman.

  • zero

    O número de colunas em que todos os valores estão zerados.

  • Original trees

    O número inicial de árvores Huffman.

  • After join

    O número de árvores Huffman distintas que sobram depois de unir árvores para poupar espaço de cabeçalho.

Depois que uma tabela foi compactada, myisamchk -dvv exibe informações adicionais sobre cada campo:

  • Type

    O tipo de campo deve conter as seguites descrições:

    • constant

      Todas linhas tem o mesmo valor.

    • no endspace

      Não armazena espaços no fim.

    • no endspace, not_always

      Não armazena espaços no fim e não faz compactação de espaços finais para todos os valores.

    • no endspace, no empty

      Não armazena espaços no fim. Não armazena valores vazios.

    • table-lookup

      A coluna foi convertida para um ENUM.

    • zerofill(n)

      Os n bytes mais significativos no valor são sempre 0 e não são armazenados.

    • no zeros

      Não armazena zeros.

    • always zero

      Valores zero são armazenados em 1 bit.

  • Huff tree

    A árvore Huffman associada com o campo.

  • Bits

    O número de bits usado na árvore Huffman.

Depois de ter executado pack_isam/myisampack você deve executar o isamchk/myisamchk para recriar o índice. Neste momento você pode também ordenar os blocos de índices para criar estatísticas necessárias para o otimizador do MySQL trabalhar de maneira mais eficiente.

myisamchk -rq --analyze --sort-index nome_tabela.MYI
isamchk   -rq --analyze --sort-index nome_tabela.ISM

Depois de instalar a tabela compactada no diretório de banco de dados MySQL você deve fazer mysqladmin flush-tables para forçar o mysqld a iniciar usando a nova tabela.

Se você desejar descompactar uma tabela compactada, você pode fazer isto com a opção --unpack para o isamchk ou myisamchk.

4.8.5. mysqld-max, om servidor mysqld extendido

mysqld-max é o servidor MySQL (mysqld) configurado com as seguintes opções de configuração:

OpçãoComentário
--with-server-suffix=-maxAdiciona um sufixo à string de versão mysqld
--with-innodbSuporte a tabelas InnoDB
--with-bdbSuporte para tabelas Berkeley DB (BDB)
CFLAGS=-DUSE_SYMDIRSuporte a links simbólicos para Windows

A opção para habilitar o suporte ao InnoDB é necessário apenas no MySQL 3.23. No MySQL 4 e acima, o InnoDB já é incluído por padrão.

Você pode encontrar os binários do MySQL-max em http://www.mysql.com/downloads/mysql-max-4.0.html.

A distribuição binária Windows MySQL 3.23 inclui tanto o binário mysqld.exe padrão e o binário mysqld-max.exe. http://www.mysql.com/downloads/mysql-4.0.html. Veja mais informações sobre isto na Seção 2.1.1, “Instalando o MySQL no Windows”.

Note que como o Berkeley DB (BDB) não está disponível para todas plataformas, alguns dos binários Max podem não ter suporte para ela. Você pode conferir quais tipos de tabelas são suportadas executando a seguinte consulta:

mysql> SHOW VARIABLES LIKE "have_%";
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| have_bdb         | NO       |
| have_crypt       | YES      |
| have_innodb      | YES      |
| have_isam        | YES      |
| have_raid        | NO       |
| have_symlink     | DISABLED |
| have_openssl     | NO       |
| have_query_cache | YES      |
+------------------+----------+

O significado dos valores na segunda coluna são:

ValorSignificado.
YESA opção está ativa e é utilizada.
NOO MySQL não está compilado com suporte a esta opção.
DISABLEDA opção xxx está desabilitada porque o mysqld foi iniciado com --skip-xxxx ou porque não foi iniciado com todas as opções necessárias para habilitar esta opção. Neste caso o arquivo hostname.err deve conter uma razão indicando o porque da opção estar desabilitada.

NOTA: Para conseguir criar tabelas InnoDB você DEVE editar suas opções de inicialização para incluir ao menos a opção innodb_data_file_path. Veja mais informações sobre isto na Seção 7.5.2, “InnoDB no MySQL Versão 3.23”.

Para obter melhor performance para tabelas BDB, você deve adicionar algumas opções de configuração para elas também .Veja mais informações sobre isto na Seção 7.6.3, “Opções de Inicialização do BDB.

mysqld_safe tenta iniciar automaticamente qualquer binário mysqld com o prefixo -max. Isto faz com que seja fácil testar um outro binário mysqld em uma instalação existente. Apenas execute o configure com as opções deseejadas e, então, instale o novo binário mysqld como mysqld-max no mesmo diretório onde seu antigo binário mysqld está. Veja mais informações sobre isto na Seção 4.8.2, “mysqld-safe, o wrapper do mysqld.

No Linux, o RPM mysqld-max utiliza o recurso mysqld_safe já mencionado. (Ele apenas instala o executável mysqld-max e o mysqld_safe usará automaticamente este executável quando o mysqld_safe for reiniciado).

A tabela a seguir mostra quais tipos de tabelas nossos binários MySQL-Max incluem:

SistemaBDBInnoDB
Windows/NTSS
AIX 4.3NS
HP-UX 11.0NS
Linux-AlphaNS
Linux-IntelSS
Linux-IA-64NS
Solaris-IntelNS
Solaris-SPARCSS
SCO OSR5SS
UnixWareSS
Mac OS XNS

Note que a partir do MySQL 4, você não precisa de um servidos MySQL Max para o InnoDB porque ele é incluído por padrão.

4.9. Utilitários e Scripts do Lado do Cliente MySQL

4.9.1. Visão Geral dos Utilitários e Scripts do Lado do Cliente

Todos clientes MySQL que comunicam com o servidor utilizando a biblioteca mysqlclient utilizam as seguintes variáveis de ambiente:

NomeDescrição
MYSQL_UNIX_PORTO socket padrão, utilizado para conexões ao localhost
MYSQL_TCP_PORTA porta TCP/IP padrão
MYSQL_PWDA senha padrão
MYSQL_DEBUGOpções de depuração-ratreamento durante depuração
TMPDIRO diretório onde tabelas e arquivos temporários são criados

A utilização de MYSQL_PWD é insegura. Veja mais informações sobre isto na Seção 4.3.8, “Conectando ao Servidor MySQL”.

No Unix, o cliente mysql utiliza o arquivo nomeado na variável de ambiente MYSQL_HISTFILE para salvar o histórico da linha de comando. O valor padrão para o arquivo de histórico é $HOME/.mysql_history, onde $HOME é o valor da variável de ambiente HOME. Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL.

Se você não quiser manter um arquivo que contenh um registro de suas consultas, primeiro remova .mysql_history se ele existir, então use uma das seguintes técnicas:

  • Defina a variável MYSQL_HISTFILE para /dev/null. Para que esta configuração tenha efeito a cada vez que você logar, coloque-a em um dos arquivos de inicialização da sua shell.

  • Crie .mysql_histfile como um link simbólico para /dev/null:

    shell> ln -s /dev/null $HOME/.mysql_history
    

    Você só precisa de fazer isto uma vez.

Todos os programas MySQL podem receber várias opções diferentes. Entretanto, todo programa MySQL fornece a opção --help que você pode utilizar para obter uma descrição completa das diferentes opções do programa. Por exemplo, experimente mysql --help

Você pode sobrepor todas as opções padrões para programas cliente padrões com um arquivo de opções. Seção 4.1.2, “Arquivo de Opções my.cnf

A lista abaixo descreve resumidamente os programas MySQL:

  • msql2mysql

    Um script shell que converte programas mSQL para MySQL. Ele não lida com todos os casos, mas ele fornece um bom inicio para a conversão.

  • mysql

    A ferramenta de linha de comando para a entrada de consultas interativamente ou a execução de consultas a partir de um arquivo no modo batch. Veja mais informações sobre isto na Seção 4.9.2, “mysql, A Ferramenta de Linha de Comando”.

  • mysqlcc

    Este programa fornece uma interface gráfica para interagir com o servidor. server. Veja mais informações sobre isto na Seção 4.9.3, “mysqlcc, The MySQL Control Center”.

  • mysqlaccess

    Um script que verifica os privilégios de acesso para uma combinação de nome de máquina, usuário e banco de dados.

  • mysqladmin

    Utilitário para realizar operações administrativas, tais como criação ou remoção de bancos de dados, recarga das tabelas de permissões, descarga de tabelas em disco e reabertura dos arquivos log. mysqladmin também pode ser usado para exibir informações de versão, processos e estado do servidor. See Seção 4.9.4, “mysqladmin, Administrando um Servidor MySQL”.

  • mysqlbinlog

    Utilitário para leitura das consultas de um log binário. Pode ser usado para recuperação de falhas com um backup antigo. Veja mais informações sobre isto na Seção 4.9.5, “mysqlbinlog, Executando as Consultas a Partir de um Log Binário”.

  • mysqldump

    Descarrega um banco de dados MySQL em um arquivo como instruções SQL ou como arquivo texto separado por tabulação. Versão aprimorada do freeware escrito originalmente por Igor Romanenko. See Seção 4.9.7, “mysqldump, Descarregando a Estrutura de Tabelas e Dados”.

  • mysqlimport

    Importa arquivos texto em suas tabelas respectivas utilizando LOAD DATA INFILE. See Seção 4.9.9, “mysqlimport, Importando Dados de Arquivos Texto”.

  • mysqlshow

    Exibe informações sobre bancos de dados, tabelas, colunas e índices.

  • replace

    Um programa utilitário que é usado pelo msql2mysql, mas que também pode ser aplicável mais genericamente. replace altera conjuntos de caracteres. Utiliza uma máquina de estado finito para comparar strings maiores primeiro. Pode ser usada para trocar conjuntos de caracteres. Por exemplo, este comando troca a e b nos arquivos dados:

    shell> replace a b b a -- arquivo1 arquivo2 ...
    

4.9.2. mysql, A Ferramenta de Linha de Comando

O mysql é uma shell SQL simples (com capacidades GNU readline). Ele suporta usos interativos e não interativos. Quando usado interativamente, os resultados das consultas são apresentadas no formato de tabela ASCII. Quando não usado interativamente (como um filtro por exemplo), o resultado é apresentado em um formato separado por tabulações. (O formato de saída pode ser alterado utilizando opções da linha de comando.) Você pode executar scripts desta forma:

shell> mysql database < script.sql > saida.tab

Se você tiver problemas devido a memória insuficiente no cliente, utilize a opção --quick! Isto força o mysql a utilizar mysql_use_result() no lugar de mysql_store_result() para recuperar o conjunto de resultados.

Utilizar o mysql é muito fáci. Inicie-o como mostrado a seguir: mysql banco_de_dados ou mysql --user=nome_usuário --password=sua_senha banco_de_dados. Digite uma instrução SQL, termine-a com ‘;’, '\g', ou '\G' e pressione RETURN/ENTER.

O mysql Suporta as seguintes opções:

  • -?, --help

    Exibe esta ajuda e sai.

  • -A, --no-auto-rehash

    Sem reprocessamento automático. O 'rehash' deve ser usado se o usuário desejar que o cliente mysql complete as tabelas e campos. Esta opção é usada para acelerar a inicialização do cliente.

  • --prompt=...

    Configura o prompt do mysql com o formato especificado.

  • -b, --no-beep

    Deliga o beep nos erros.

  • -B, --batch

    Exibe resultados com o caractere de tabulação como o separador, cada registro em uma nova linha. Não utiliza o arquivo de histórico.

  • --character-sets-dir=...

    Diretório onde os conjuntos de caracteres estão localizados.

  • -C, --compress

    Utiliza compactação no protocolo cliente/servidor.

  • -#, --debug[=...]

    Log de Depuração. O padrão é 'd:t:o,/tmp/mysql.trace'.

  • -D, --database=...

    Qual banco de dados usar. Isto geralmente é util em um arquivo my.cnf.

  • --default-character-set=...

    Configura o conjunto de caracters padrão.

  • -e, --execute=...

    Executa o comando e sai. (Saída parecida com --batch)

  • -E, --vertical

    Exibe a saída de uma consulta (linhas) verticalmente. Sem esta opção você também pode forçar esta saída terminando suas instruções com \G.

  • -f, --force

    Continue mesmo se for obtido um erro SQL.

  • -g, --no-named-commands

    Comandos nomeados serão desabilitados. Utilize somente a forma \*, ou use comandos nomeados apenas no começo da linha terminada com um ponto-e-vírgula (;). Desde a versão 10.9, o cliente agora inicia com esta opção habilitada por padrão! Com a opção -g, entretando, comandos de formato longo continuarão funcionando na primeira linha.

  • -G, --enable-named-commands

    Comandos nomeados são habilitados. Comandos de formato longo são aceitos assim como os comandos reduzidos \*.

  • -i, --ignore-space

    Ignore caractere de espaço depois de nomes de funções.

  • -h, --host=...

    Conectar à máquina especificada.

  • -H, --html

    Produz saída HTML.

  • -X, --xml

    Produz saída XML.

  • -L, --skip-line-numbers

    Não escreve o número da linha para os erros. Útil quando se deseja comparar arquivos com resultados que incluem mensagens de erro.

  • --no-pager

    Desabilita paginação e impressão na saída padrão. Veja também a ajuda interativa (\h).

  • --no-tee

    Desabilita arquivo de saída. Veja também a ajuda interativa (\h).

  • -n, --unbuffered

    Descarrega e atualiza o buffer depois de cada pesquisa.

  • -N, --skip-column-names

    Não escrever nomes de colunas nos resultados.

  • -O, --set-variable nome=opção

    Fornece um valor a uma variável. --help lista as variáveis. Por favor, note que as sintaxes --set-variable=name=value e -O name=value estão obsoletas desde o MySQL 4.0, use --nome=valor.

  • -o, --one-database

    Atualiza somente o banco de dados padrão. Isto é útil para evitar atualização em outros bancos de dados no log de atualizações.

  • --pager[=...]

    Tipo de saída. O padrão é sua variável de ambiente PAGER. Paginadores válidos são: less, more, cat [>nome_arquivo], etc. Veja também a ajuda interativa (\h). Esta opção não funciona no modo batch. A opção pager funciona somente no UNIX.

  • -p[password], --password[=...]

    Senha a ser usada ao conectar ao servidor. Se uma senha não é fornecida na linha de comando, lhe será solicitado uma. Perceba que se você utilizar o formato curto -p você não pode ter um espaço entre a opção e a senha.

  • -P --port=...

    Número da porta TCP/IP para usar na conexão.

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    Especifica o protocolo de conexão usado. Novo no MySQL 4.1.

  • -q, --quick

    Não faz cache do resultado, imprime linha a linha. Isto pode deixar o servidor mais lento se a saída for suspendida. Não usa arquivo de histórico.

  • -r, --raw

    Exibe valores de colunas sem conversão de escapes. Utilizado com --batch

  • --reconnect

    Se a conexão é perdida, tentar reconectar ao servidor automaticamente (mas apenas uma vez).

  • -s, --silent

    Opção para ser mais silencioso.

  • -S --socket=...

    Arquivo socket para ser utilizado na conexão.

  • -t --table

    Saída no formato de tabela. Isto é padrão no modo não-batch.

  • -T, --debug-info

    Exibe alguma informação de depuração na saída.

  • --tee=...

    Anexa tudo no arquivo de saída. Veja também a ajuda interativa (\h). Não funciona no modo batch.

  • -u, --user=#

    Usuário para login diferente do usuário atual do sistema.

  • -U, --safe-updates[=#], --i-am-a-dummy[=#]

    Permite somente que UPDATE e DELETE utilizem chaves. Veja abaixo para maiores informações sobre esta opção. Você pode zerar esta opção se possui-la no arquivo my.cnf utilizando --safe-updates=0.

  • -v, --verbose

    Modo verbose (-v -v -v fornece o formato de saída da tabela).

  • -V, --version

    Gera saída com informação de versão e sai.

  • -w, --wait

    Espera e repete em vez de sair se a conexão estiver inacessível.

Você também pode configurar as seguntes variáveis com -O ou --set-variable. Por favor, note que as sintaxes --set-variable=nome=valor e -O name=value estão obsoletas desde o MySQL 4.0, use --var=option:

Nome VariávelPadrãoDescrição
connect_timeout0Número de seguntos antes de esgotar o tempo da conexão
local-infile0Disabilita (0) ou habilita (1) capacidade LOCAL para LOAD DATA INFILE
max_allowed_packet16777216Tamanho máximo do pacote para enviar/receber do servidor
net_buffer_length16384Tamanho do buffer para comunicação TCP/IP e socket
select_limit1000Limite automático para SELECT quando utilizar --safe-updtaes
max_join_size1000000Limite automático para registros em uma join quando utilizar --safe-updtaes.

Se o cliente mysql perder a conexào com o servidor enquanto envia uma consulta, ele tentará se reconectar imediatamente e automaticamente uma vez e enviar a consulta novamente. Note que mesmo se ele obter sucesso na reconexão, como sua primeira conexão foi finalizada, todas seus objetos da sessão anteriores foram perdidos: tabelas temporárias, e variáveis de sessão e de usuário. Desta forma, o comportamento acima pode ser perigoso para você, como neste exemplo onde o servidor foi desligado e reiniciado sem você saber:

mysql> set @a=1;
Query OK, 0 rows affected (0.05 sec)

mysql> insert into t values(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)

mysql> select * from t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

A variável de usuário @a foi perdida com a conexão e depois da reconexão ela é indefinida. Para se proteger deste risco, você pode iniciar o cliente mysql com a opção --disable-reconnect.

Se você digitar 'help' na linha de comando, mysql irá exibir os comandos que ele suporta:

mysql> help

MySQL commands:
help      (\h)    Display this text.
?         (\h)    Synonym for `help'.
clear     (\c)    Clear command.
connect   (\r)    Reconnect to the server.
                  Optional arguments are db and host.
delimiter (\d)    Set query delimiter.
edit      (\e)    Edit command with $EDITOR.
ego       (\G)    Send command to mysql server,
            display result vertically.
exit      (\q)    Exit mysql. Same as quit.
go        (\g)    Send command to mysql server.
nopager   (\n)    Disable pager, print to stdout.
notee     (\t)    Don't write into outfile.
pager     (\P)    Set PAGER [to_pager].
            Print the query results via PAGER.
print     (\p)    Print current command.
prompt    (\R)    Change your mysql prompt.
quit      (\q)    Quit mysql.
rehash    (\#)    Rebuild completion hash.
source    (\.)    Execute an SQL script file.
      Takes a file name as an argument.
status    (\s)    Get status information from the server.
system    (\!)    Execute a system shell command.
tee       (\T)    Set outfile [to_outfile].
      Append everything into given outfile.
use       (\u)    Use another database.
          Takes database name as argument.

Os comandos edit, nopager, pager, e system funcionam apenas no Unix.

O comando status lhe fornece algumas informações sobre a conexão e o servidor que está utilizando. Se você estiver executando no modo --safe-updates, status irá também imprimir os valores para as variáveis mysql que afetam suas consultas.

Uma opção útil para iniciantes (introduzido no MySQL versão 3.23.11) é o --safe-updates (ou --i-am-a-dummy para usuários que uma vez possam ter feito um DELETE FROM nome_tabela mas esqueceram da cláusula WHERE). Quando utilizar esta opção, o mysql envia o seguinte comando ao servidor MySQL quando abrir a conexão.

SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
    SQL_MAX_JOIN_SIZE=#max_join_size#"

onde #select_limit# e #max_join size# são variáveis que podem ser configuradas da linha de comando mysql. Veja mais informações sobre isto na Seção 5.5.6, “Sintaxe de SET.

O efeito da opção acima é:

  • Você não tem permissão de utilizar uma instrução UPDATE ou DELETE se você não possuir uma chave na parte WHERE. Pode-se, entretanto, forçar um UPDATE/DELETE utilizando LIMIT:

    UPDATE nome_tabela SET campo_nao_chave=# WHERE campo_nao_chave=# LIMIT 1;
    

  • Todos resultados maiores são limitados automaticamente a #select_limit# linhas.

  • SELECT's que provavelmente precisarão examinar mais que #max_join_size combinaçoes de linhas serão abortadas.

Algumas dicas úteis sobre o cliente mysql:

Alguns dados são muito mais legíveis quando exibido verticalmente, em vez da saída do tipo caixa horizontal comum. Por exemplo: Textos longos, que incluem várias linhas, são muito mais fáceis de serem lidos com saída vertical.

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 lIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@no.spam.com
  mail_to: "Thimble Smith" <tim@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:

Thimble> Hi.  I think this is a good idea.  Is anyone familiar with UTF-8
Thimble> or Unicode? Otherwise, I'll put this on my TODO list and see what
Thimble> happens.

Yes, please do that.

Regards,
Monty
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)

Para o log, você pode utilizar a opção tee. O tee pode ser iniciado com a opção --tee=..., ou pela linha de comando de maneira interativa com o comando tee. Todos os dados exibidos na tela serão anexados no arquivo fornecido. Isto também pode ser muito útil para propósitos de depuração. O tee pode ser desabilitado da linha de comando com o comando notee. Executando tee novamente o log é reiniciado. Sem um parâmetro o arquivo anterior será usado. Perceba que tee irá atualizar os resultados dentro do arquivo depois de cada comando, pouco antes da linha de comando reaparecer esperando pelo próximo comando.

Navegar ou pesquisar os resultados no modo interativo em algum programa do UNIX como o less, more ou outro similar, é agora possível com a opção --pager[=...]. Sem argumento, o cliente mysql irá procurar pela variável de ambiente PAGER e configurar pager para este valor. pager pode ser iniciado a partir da linha de comando interativa com o comando pager e desabilitado com o comando nopager. O comando recebe um argumento opcional e e o pager será configurado com ele. O comando pager pode ser chamado com um argumento, mas isto requer que a opção --pager seja usada, ou o pager será usado com a saída padrão. pager funciona somente no UNIX, uma vez que é utilizado a função popen(), que não existe no Windows. No Windows a opção tee pode ser utilizada, entretanto ela pode não ser cômoda como pager pode ser em algumas situações.

Algumas dicas sobre pager:

  • Você pode usá-lo para gravar em um arquivo:

    mysql> pager cat > /tmp/log.txt
    

    e os resultados irão somente para um arquivo. Você também pode passar qualquer opções para os programas que você deseja utilizar com pager:

    mysql> pager less -n -i -S
    

  • Note a opção -S exibida acima. Você pode achá-la muito útil quando navegar pelos resultados; experimente com a opção com saída a horizontal (finalize os comandos com \g, ou ;) e com saída vertical (final dos comandos com \G). Algumas vezes um resultado com um conjunto muito largo é difícil ser lido na tela, com a opção -S para less, você pode navegar nos resultados com o less interativo da esquerda para a direita, evitando que linhas maiores que sua tela continuem na próxima linha. Isto pode tornar o conjunto do resultado muito mais legível. você pode alterar o modo entre ligado e desligado com o less interativo com -S. Veja o 'h'(help) para mais ajuda sobre o less.

    Você pode combinar maneiras muito complexas para lidar com os resultados, por exemplo, o seguinte enviaria os resultados para dois arquivos em dois diferentes diretórios, em dois discos diferentes montados em /dr1 e /dr2, e ainda exibe o resultado na tela via less:

    mysql> pager cat | tee /dr1/tmp/res.txt | \
    tee /dr2/tmp/res2.txt | less -n -i -S
    

Você também pode combinar as duas funções acima; tenha o tee habilitado, o pager configurado para 'less' e você estará apto a navegar nos resultados no less do Unix e ainda ter tudo anexado em um arquivo ao mesmo tempo. A diferença entre UNIX tee usado com o pager e o tee embutido no cliente mysql é que o tee embutido funciona mesmo se você não tiver o comando UNIX tee disponível. O tee embutido também loga tudo que é exibido na tela, e o UNIX tee usado com pager não loga completamente. Por último o tee interativo é mais cômodo para trocar entre os modos on e off, quando você desejar logar alguma coisa em um arquivo, mas deseja estar apto para desligar o recurso quando necessário.

A partir da versão 4.0.2 é possível alterar o prompt no cliente de linha de comando mysql.

Você pode usar as seguintes opções do prompt:

OpçãoDescrição
\vversão mysqld
\dbanco de dados em uso
\hmáquina na qual está conectado
\pporta na qual está conectado
\unome do usuário
\Unome_usuário@maquina
\\\
\nnova quebra de linha
\ttab
\espaço
\_espaço
\Rhora no formato 24h (0-23)
\rhora no formato 12h (1-12)
\mminutos
\yano com dois digitos
\Yano com quatro digitos
\Dformato completo da data
\ssegundos
\wdia da semana no formato com 3 letras (Mon, Tue, ...)
\Pam/pm
\omês no formato de número
\Omês no formato com 3 letras (Jan, Feb, ...)
\ccontador que cresce a cada comando

\’ seguido por qualquer outra letra apenas retorna aquela letra.

Você pode definir o prompt nos seguintes lugares:

  • Variável de Ambiente

    Você pode configurar o prompt em qualquer arquivo de configuração do MySQL, no grupo mysql. Por exemplo:

    [mysql]
    prompt=(\u@\h) [\d]>\_
    

  • Linha de Comando

    Você pode definir a opção --prompt na linha de comando para mysql. Por exemplo:

    shell> mysql --prompt="(\u@\h) [\d]> "
    
    (usuário@maquina) [banco de dados]>
    

  • Interativamente

    Você também pode usar o comando prompt (ou \R) para alterar o seu prompt interativamente. Por exemplo:

    mysql> prompt (\u@\h) [\d]>\_
    PROMPT set to '(\u@\h) [\d]>\_'
    (usuario@maquina) [banco de dados]>
    (usuario@maquina) [banco de dados]> prompt
    Returning to default PROMPT of mysql>
    mysql>
    

4.9.3. mysqlcc, The MySQL Control Center

mysqlcc, o Centro de Controle do MySQL, é um cliente independente de plataforma que fornece um interface gráfica ao usuário (GUI) para o servidor de banco de dados MySQL. Ela suporta uso interativo, incluindo destaque de sintaxe e complementação com tab. Ele fornece gerenciamento de banco de dados e tabelas e permite a administração do servidor.

Atualmente, o mysqlcc executa em plataformas Windows e Linux.

mysqlcc não está incluído com a distribuição MySQL, mas pode ser feito o download separadamente em http://www.mysql.com/downloads/.

mysqlcc suporta as seguintes opções:

  • -?, --help

    Exibe esta ajuda e sai.

  • -b, --blocking_queries

    Usa consultas em bloco.

  • -C, --compress

    Usa o protocolo servidor/cliente compactado.

  • -c, --connection_name=name

    Este é um sinônimo para --server.

  • -d, --database=...

    Banco de dados a ser usado. Isto é útil principalmente no arquivo my.cnf.

  • -H, --history_size=#

    Tamanho do histórico para a janiela de consultas.

  • -h, --host=...

    Conecta a uma determinda máquina.

  • -p[password], --password[=...]

    Senha usada ao se conectar ao servidor. Se uma senha não for especificada na linha de comando, você deverá informá-la. Note que se você usar a forma simplificada -p não é permitido um espaço entre a opçõa e a senha.

  • -g, --plugins_path=name

    Caminho para o diretório onde os plugins do MySQL Control Center estao lacalizados.

  • -P port_num, --port=port_num

    Número da porta TCP/IP para uso na conexão.

  • -q, --query

    Abre uma janela de consulta na inicialização.

  • -r, --register

    Abre a caixa de diálogo 'Register Server' na inicialização.

  • -s, --server=name

    Nome da conexão do MySQL Control Center.

  • -S --socket=...

    Arquivo socket usado na conexão.

  • -y, --syntax

    Habilita destque da sintaxe e complementação

  • -Y, --syntax_file=name

    Arquivo de sintaxe para complementação.

  • -T, --translations_path=name

    Caminho para o diretório onde as traduções do MySQL Control Center estão localizados.

  • -u, --user=#

    Usuário para login se diferente do usuário atual.

  • -V, --version

    Exibe a versão e sai.

Você também pode configurar as seguntes variáveis com -O ou --set-variable. Por favor, note que as sintaxes --set-variable=nome=valor e -O name=value estão obsoletas desde o MySQL 4.0, use --var=option:

Variable NameDefaultDescription
connect_timeout0Number of seconds before connection timeout.
local-infile0Disable (0) or enable (1) LOCAL capability for LOAD DATA INFILE
max_allowed_packet16777216Max packet length to send to/receive from server
net_buffer_length16384Buffer for TCP/IP and socket communication
select_limit1000Automatic limit for SELECT when using --safe-updtaes
max_join_size1000000Automatic limit for rows in a join when using --safe-updates

4.9.4. mysqladmin, Administrando um Servidor MySQL

Um utilitário para realizar operações administrativas. A sintaxe é:

shell> mysqladmin [OPÇÕES] comando [opção_do_comando] comando...

Você pode obter uma lista das opção que sua versão do mysqladmin suporta executando mysqladmin --help.

O mysqladmin atual suporta os seguintes comandos:

  • create databasename

    Cria um novo banco de dados.

  • drop databasename

    Apaga um banco de dados e todas suas tabelas.

  • extended-status

    Fornece uma mensagem extendida sobre o estado do servidor.

  • flush-hosts

    Atualiza todos os nomes de máquinas que estiverem no cache.

  • flush-logs

    Atualiza todos os logs.

  • flush-tables

    Atualiza todas as tabelas.

  • flush-privileges

    Recarrega tabelas de permissões (mesmo que reload).

  • kill id,id,...

    Mata threads do MySQL.

  • password

    Configura uma nova senha. Altera a antiga senha para nova senha.

  • ping

    Checa se o mysqld está ativo.

  • processlist

    Exibe lista de threads ativas no servidor, com a instrução SHOW PROCESSLIST. Se a opção --verbose é passada, a saída é como aquela de SHOW FULL PROCESSLIST.

  • reload

    Recarrega tabelas de permissão.

  • refresh

    Atualiza todas as tabelas e fecha e abre arquivos de log.

  • shutdown

    Desliga o servidor.

  • slave-start

    Inicia thread de replicação no slave.

  • slave-stop

    Termina a thread de replicação no slave.

  • status

    Fornece uma mensagem curta sobre o estado do servidor.

  • variables

    Exibe variáveis disponíveis.

  • version

    Obtêm informação de versão do servidor.

Todos comandos podem ser reduzidos para seu prefixo único. Por exemplo:

shell> mysqladmin proc stat
+----+-------+-----------+----+-------------+------+-------+------+
| Id | User  | Host      | db | Command     | Time | State | Info |
+----+-------+-----------+----+-------------+------+-------+------+
| 6  | monty | localhost |    | Processlist | 0    |       |      |
+----+-------+-----------+----+-------------+------+-------+------+
Uptime: 10077  Threads: 1  Questions: 9  Slow queries: 0
Opens: 6 Flush tables: 1  Open tables: 2
Memory in use: 1092K  Max memory used: 1116K

O resultado do comando mysqladmin status possui as seguintes colunas:

UptimeNúmero de segundos que o servidor MySQL está funcionando.
ThreadsNúmero de threads ativas (clientes).
QuestionsNúmero de solicitações dos clientes desde que o mysqld foi iniciado.
Slow queriesConsultas que demoram mais que long_query_time segundos. Veja mais informações sobre isto na Seção 4.10.5, “O Log para Consultas Lentas”.
OpensQuantas tabelas foram abertas pelo mysqld.
Flush tablesNúmero de comandos flush..., refresh e reload.
Open tablesNúmero de tabelas abertas atualmente.
Memory in useMemória alocada diretamente pelo código do mysqld (disponível somente quando o MySQL é compilado com --with-debug=full).
Max memory usedMemória máxima alocada diretamente pelo código do mysqld (disponível somente quando o MySQL é compilado com --with-debug=full).

Se você executa um mysqladmin shutdown em um socket (em outras palavras, em um computador onde o mysqld está executando), mysqladmin irá esperar até que o arquivo-pid do MySQL seja removido para garantir que o servidor mysqld parou corretamente.

4.9.5. mysqlbinlog, Executando as Consultas a Partir de um Log Binário

Você pode examinad o arquivo de log binário (Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”) com o utilitário mysqlbinlog.

shell> mysqlbinlog hostname-bin.001

exibirá todas as consultas contidas no log binário hostname-bin.001, junto com outras informações (tempo da consulta, ID da thread que a executou, o timestamp de quando foi executada, etc).

Você pode colocar a saída do mysqlbinlog em um cliente mysql; isto é usado para recuperações de falhas quando você tem um backup antigo (Veja mais informações sobre isto na Seção 4.5.1, “Backups dos Bancos de Dados”):

shell> mysqlbinlog hostname-bin.001 | mysql

ou

shell> mysqlbinlog hostname-bin.[0-9]* | mysql

Você também pode redirecionar a saída do mysqlbinlog para um arquivo texto, então modifique este arquivo texto (para excluir as consultas que você não quer executar por alguma razão), e então execute as consultas a partir do arquivo texto dentro do mysql.

mysqlbinlog possui a opção position=# que exibirá apenas as consultas cujo offset no log binário é maior ou igual a #.

Se você tiver mais que um log binário para executar no servidor MySQL, o método seguro é fazê-lo em uma única conexão MySQL. Aqui está o que pode ser INseguro:

shell> mysqlbinlog hostname-bin.001 | mysql # DANGER!!
shell> mysqlbinlog hostname-bin.002 | mysql # DANGER!!

Isto causará problemas se o primeiro log binário conter um CREATE TEMPORARY TABLE e o segundo contém uma consulta que utiliza esta tabela temporária: quando o primeiro mysql termina, ele apara a tabela temporária, assim a o segundo mysql relatará um ``tabela desconhecida''. Isto ocorre porque você deve executar todos os log binários que você deseja em uma única conexão, especialmente se você usa tabelas temporárias. Aqui estão dois modos possíveis:

shell> mysqlbinlog hostname-bin.001 hostname-bin.002 | mysql
shell> mysqlbinlog hostname-bin.001 >  /tmp/queries.sql
shell> mysqlbinlog hostname-bin.002 >> /tmp/queries.sql
shell> mysql -e "source /tmp/queries.sql"

A partir do MySQL 4.0.14, mysqlbinlog pode preparar uma entrada para o mysql executar um LOAD DATA INFILE a partir de um log binário. Como o log binário contém os dados para carregar (isto é verdade para o MySQL 4.0; o MySQL 3.23 não grava o dado carregado em um log binário, assim o arquivo original era necessário quando se queria executar o conteúdo do log binário), mysqlbinlog copiará este data para um arquivo temporário e imprime um comando LOAD DATA INFILE para o mysql carregar este arquivo temporário. O local onde o arquivo temorário é criado é o diretório temporário por padrão; ele pode ser alterado com a opção local-load do mysqlbinlog.

Antes do MySQL 4.1, mysqlbinlog não podia preaparar saída cabíveis para mysql quando o log binário continha consultas de diferentes threads usando tabelas temporárias de mesmo nome, se estas consultas eram entrelaçadas. Isto está resolvido no MySQL 4.1.

Você também pode usar o mysqlbinlog --read-from-remote-server para ler o log binário diretamente de um servidor MySQL remoto. No entanto, isto é algo que está obsoleto já que queremos tornar fácil de se aplicar os logs binários em servidores MySQL em execução.

mysqlbinlog --help lhe dará mais informações

4.9.6. Usando mysqlcheck para Manutenção de Tabelas e Recuperação em Caso de Falhas

Desde o MySQL versão 3.23.38 você estará apto a usar a nova ferramenta de reparos e verificação de tabelas MyISAM. A diferença para o myisamchk é que o mysqlcheck deve ser usado quando o servidor mysqld estiver em funcionamento, enquanto o myisamchk deve ser usado quando ele não estiver. O benefício é que você não precisará mais desligar o servidor mysqld para verificar ou reparar suas tabelas.

O mysqlcheck utiliza os comandos do servidor MySQL CHECK, REPAIR, ANALYZE e OPTIMIZE de um modo conveniente para o usuário.

Existem três modos alternativos de chamar o mysqlcheck:

shell> mysqlcheck [OPÇÕES] database [tabelas]
shell> mysqlcheck [OPÇÕES] --databases DB1 [DB2 DB3...]
shell> mysqlcheck [OPÇÕES] --all-databases

Pode ser usado de uma maneira muito similar ao mysqldump quando o assunto for quais bancos de dados e tabelas devem ser escolhidas.

O mysqlcheck tem um recurso especial comparado comparado aos outros clientes; o comportamento padrão, verificando as tabelas (-c), pode ser alterado renomeando o binário. Se você deseja ter uma ferramenta que repare as tabelas como o procedimento padrão, você deve copiar o mysqlcheck para o disco com um outro nome, mysqlrepair, ou crie um link simbólico com o nome mysqlrepair. Se você chamar mysqlrepair agora, ele irá reparar as tabelas como seu procedimento padrão.

Os nomes que podem ser utilizados para alterar o comportamento padrão do mysqlcheck são:

mysqlrepair:   A opção padrão será -r
mysqlanalyze:  A opção padrão será -a
mysqloptimize: A opção padrão será -o

As opções disponíveis para o mysqlcheck estão listadas aqui, por favor verifique o que a sua versão suporta com o mysqlcheck --help.

  • -A, --all-databases

    Verifica todos os bancos de dados. Isto é o mesmo que --databases com todos os bancos de dados selecionados.

  • -1, --all-in-1

    Em vez de fazer uma consulta para cada tabela, execute todas as consultas separadamente para cada banco de dados. Nomes de tabelas estarão em uma lista separada por vírgula.

  • -a, --analyze

    Análise as tabelas fornecidas.

  • --auto-repair

    Se uma tabela checada está corrompida, ela é corrigida automaticamente. O reparo será feito depois que todas as tabelas tiverem sido checadas e forem detectadas tabelas corrompidas.

  • -#, --debug=...

    Log de saída de depuração. Normalmente é 'd:t:o,filename'

  • --character-sets-dir=...

    Diretório onde estão os conjuntos de caracteres.

  • -c, --check

    Verifca erros em tabelas

  • -C, --check-only-changed

    Verifica somente tabelas que foram alteradas desde a última conferência ou que não foram fechada corretamente.

  • --compress

    Utilize compressão no protocolo server/cliente.

  • -?, --help

    Exibe esta mensagem de ajuda e sai.

  • -B, --databases

    Para verificar diversos bancos de dados. Perceba a diferença no uso; Neste caso nenhuma tabela será fornecida. Todos os argumentos são tratados como nomes de bancos de dados.

  • --default-character-set=...

    Configura o conjunto de caracteres padrão.

  • -F, --fast

    Verifica somente as tabelas que não foram fechadas corretamente

  • -f, --force

    Continue mesmo se nós obtermos um erro de sql.

  • -e, --extended

    Se você estiver utilizando esta opção com CHECK TABLE, irá garantir que a tabela está 100 por cento consistente, mas leva bastante tempo.

    Se você utilizar esta opção com REPAIR TABLE, ele irá executar um comando de reparos na tabela, que não só irá demorar muito tempo para executar, mas também pode produzir muitas linhas de lixo.

  • -h, --host=...

    Conecta à máquina.

  • -m, --medium-check

    Mais rápido que verificação extendida, mas encontra somente 99.99 de todos os erros. Deve resolver a maioria dos casos.

  • -o, --optimize

    Otimizador de tabelas

  • -p, --password[=...]

    Senha para usar ao conectar ao servidor. Se a senha não for fornecida será solicitada no terminal.

  • -P, --port=...

    Número de porta para usar para conexão.

  • -q, --quick

    Se esta opção for utilizada com CHECK TABLE, evita a busca de registros verificando links errados. Esta é a conferência mais rápida.

    Se você estiver utilizando esta opção com REPAIR TABLE, ela tentará reparar somente a árvore de índices. Este é o método de reparo mais rápido para uma tabela.

  • -r, --repair

    Pode corrigir quase tudo exceto chaves únicas que não são únicas.

  • -s, --silent

    Exibe somente mensagens de erro.

  • -S, --socket=...

    Arquivo socket para usar na conexão.

  • --tables

    Sobrepõe a opção --databases (-B).

  • -u, --user=#

    Usuário para o login, se não for o usuário atual.

  • -v, --verbose

    Exibe informação sobre os vários estágios.

  • -V, --version

    Exibe informação sobre a versão e sai.

4.9.7. mysqldump, Descarregando a Estrutura de Tabelas e Dados

Utilitário para descarregar um banco de dados ou uma coleção de bancos de dados para backup ou transferencia para outro servidor SQL (Não necessariamente um servidor MySQL). A descarga irá conter instruções SQL para cria a tabela e/ou popular a tabela.

Se a idéia é backup do servidor, deve ser considerada a utilização do mysqlhotcopy. Veja mais informações sobre isto na Seção 4.9.8, “mysqlhotcopy, Copiando Bancos de Dados e Tabelas do MySQL”.

shell> mysqldump [OPÇÕES] banco_de_dados [tabelas]
OR     mysqldump [OPÇÕES] --databases [OPÇÕES] BD1 [BD2 BD3...]
OR     mysqldump [OPÇÕES] --all-databases [OPÇÕES]

Se você não fornecer nenhuma tabela ou utilizar o --databases ou --all-databases, todo(s) o(s) banco(s) de dados será(ão) descarregado(s).

Você pode obter uma lista das opções que sua versão do mysqldump suporta executando mysqldump --help.

Perceba que se você executar o mysqldump sem a opção --quick ou --opt, o mysqldump irá carregar todo o conjunto do resultado na memória antes de descarregar o resultado. Isto provavelmente será um problema se você está descarregando um banco de dados grande.

Note que se você estiver utilizando uma cópia nova do programa mysqldump e se você for fazer uma descarga que será lida em um servidor MySQL muito antigo, você não deve utilizar as opções --opt ou -e.

mysqldump suporta as seguintes opções:

  • --add-locks

    Adicione LOCK TABLES antes de UNLOCK TABLE depois de cada descarga de tabelas. (Para obter inserções mais rápidas no MySQL.)

  • --add-drop-table

    Adicione um drop table antes de cada instrução create.

  • -A, --all-databases

    Descarrega todos os bancos de dados. Isto irá ser o mesmo que --databases com todos os bancos de dados selecionados.

  • -a, --all

    Inclui todas as opções do create específicas do MySQL.

  • --allow-keywords

    Permite criação de nomes que colunas que são palavras chaves. Isto funciona utilizando o nome da tabela como prefixo em cada nome de coluna.

  • -c, --complete-insert

    Utilize instruções de insert completas (com nomes de colunas).

  • -C, --compress

    Compacta todas as informações entre o cliente e o servidor se ambos suportarem a compactação.

  • -B, --databases

    Para descarregar diversos bancos de dados. Perceba a diferença no uso. Neste caso nenhuma tabela é fornecida. Todos argumentos são estimados como nomes de bancos de dados. USE nome_bd; será incluído na saída antes de cada banco de dados novo.

  • --delayed

    Insere registros com o comando INSERT DELAYED.

  • -e, --extended-insert

    Utiliza a nova sintaxe multilinhas INSERT. (Fornece instruções de inserção mais compactas e mais rápidas.)

  • -#, --debug[=option_string]

    Rastreia a utilização do programa (para depuração).

  • --help

    Exibe uma mensagem de ajuda e sai.

  • --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=..., --lines-terminated-by=...

    Estas opções são usadas com a opção -T e tem o mesmo significado que as cláusulas correspondentes em LOAD DATA INFILE Veja mais informações sobre isto na Seção 6.4.8, “Sintaxe LOAD DATA INFILE.

  • -F, --flush-logs

    Atualiza o arquivo de log no servidor MySQL antes de iniciar a descarga.

  • -f, --force,

    Continue mesmo se obter um erro de SQL durantes uma descarga de tabela.

  • -h, --host=..

    Descarrega dados do servidor MySQL na máquina especificada. A máquina padrão é localhost.

  • -l, --lock-tables.

    Bloqueia todas as tabelas antes de iniciar a descarga. As tabelas são bloqueadas com READ LOCAL para permitir inserções concorrentes no caso de tabelas MyISAM.

    Por favor, note que ao descarregar multiplas tabelas, --lock-tables bloqueará as tabelas de cada banco de dados separadamente. Assim, usar esta opção não garantirá que suas tabelas sejam logicamente consistentes entre os banco de dados. Tabela me diferentes bancos de dados podem ser descarregadas em estados completamente diferentes.

  • -K, --disable-keys

    /*!40000 ALTER TABLE nome_tb DISABLE KEYS */; e /*!40000 ALTER TABLE nome_tb ENABLE KEYS */; será colocado na saída. Isto fará com que a carga de dados no MySQL 4.0 server seja mais rápida já que os índices são criados depois que todos os dados são inseridos.

  • -n, --no-create-db

    'CREATE DATABASE /*!32312 IF NOT EXISTS*/ nome_bd;' não será colocado na saída. A linha acima será adicionada se a opção --databases ou --all-databases for fornecida.

  • -t, --no-create-info

    Não grava informações de criação de tabelas (A instrução CREATE TABLE.)

  • -d, --no-data

    Não grava nenhuma informação de registros para a tabela. Isto é muito útil se você desejar apenas um dump da estrutura da tabela!

  • --opt

    O mesmo que --quick --add-drop-table --add-locks --extended-insert --lock-tables. Fornece a descarga mais rápida para leitura em um servidor MySQL.

  • -pyour_pass, --password[=sua_senha]

    A senha para usar quando conectando ao servidor. Se não for especificado a parte '=sua_senha', o mysqldump irá perguntar por uma senha.

  • -P port_num, --port=porta_num

    O número da porta TCP/IP usado para conectar a uma máquina. (Isto é usado para conexões a máquinas diferentes de localhost, na qual sockets Unix são utilizados.)

  • -q, --quick

    Não utiliza buffers para as consultas, descarrega diretamente para saída padrão. Utilize mysql_use_result() para fazer isto.

  • -Q, --quote-names

    Coloca os nomes de colunas e tabelas entre ‘`’.

  • -r, --result-file=...

    Direcione a saída para um determinado arquivo. Esta opção deve ser usada no MSDOS porque previne a conversão de nova linha '\n' para '\n\r' (nova linha + retorno de carro).

  • --single-transaction

    Esta opção envia um comando SQL BEGIN antes de carregar os dados do servidor. Ele é mais útil com tabelas InnoDB e nível READ_COMMITTED de isolação da transação, já que neste modo ela fará um dump do estado de consistência do banco de dados no momento que o BEGIN for enviado sem bloquear qualquer aplicação.

    Ao usar esta opção você deve manter em mente que será feito um dump no estado consistente apenas das tabelas transacionais, ex., qualquer tabela MyISAM ou HEAP na qual for feito um dump durante está p[ção pode ainda mudar de estado.

    A opção --single-transaction foi adicionada na versão 4.0.2. Esta opção é mutualmente exclusiva com a opção --lock-tables já que LOCK TABLES já faz um commit da transação anterior internamente.

  • -S /path/to/socket, --socket=/path/to/socket

    O arquivo socket que será utilizado quando conectar à localhost (que é a máquina padrão).

  • --tables

    Sobrepõe a opção --databases (-B).

  • -T, --tab=path-to-some-directory

    Cria um arquivo nome_tabela.sql, que contém os comandos SQL CREATE e um arquivo nome_tabela.txt, que contém os dados, para cada tabela dada. O formato do arquivo .txt é feito de acordo com as opções --fields-xxx e --lines--xxx. Nota: Esta opção só funciona se mysqldump está sendo executado na mesma máquina que o daemon mysqld. Você deve usar uma conta MySQL que tem o privilégio FILE, e o login de usuário/grupo com o qual o mysqld está sendo executado (normalmente usuário mysql, grupo mysql) precisa ter permissão para criar/gravar um arquivo no local especificado.

  • -u user_name, --user=user_name

    O nome do usuário do MySQL para usar ao conectar ao servidor. O valor padrão é seu nome de usuário no Unix.

  • -O nome=valor, --set-variable=nome=valor

    Confirgura o valor de uma variável. As variáveis possíveis são listadas abaixo. Note que a sintaxe --set-variable=nome=valor e -O nome=valor está obsoleto desde o MySQL 4.0. Use --nome=valor.

  • -v, --verbose

    Modo verbose. Exibe mais informações sobre o que o programa realiza.

  • -V, --version

    Exibe informações de versão e sai.

  • -w, --where='where-condition'

    Faz um dump apenas dos registros selecionados. Note que as aspas são obrigatórias:

    "--where=user='jimf'" "-wuserid>1" "-wuserid<1"
    

  • -X, --xml

    Faz um dump do banco de dados no formato XML

  • -x, --first-slave

    Faz um lock de todas as tabelas de todos os bancos de dados.

  • --master-data

    Como --first-slave, mas também exibe algum comando CHANGE MASTER TO o qual, mais tarde, fará o seu slave iniciar a partir da posição certa no log binário do master, se você tiver configurado o seu slave usando este dump SQL do master.

  • -O net_buffer_length=#, where # < 16M

    Quando estiver criando instruções de inserções em múltiplas linhas (com a opção --extended-insert ou --opt), mysqldump irá criar linhas até o tamanho de net_buffer_length. Se você aumentar esta variável, você também deve se assegurar que a variável max_allowed_packet no servidor MySQL é maior que a net_buffer_length.

O uso mais comum do mysqldump é provavelmente para fazer backups de bancos de dados inteiros. Veja mais informações sobre isto na Seção 4.5.1, “Backups dos Bancos de Dados”.

mysqldump --opt banco_dados > arquivo-backup.sql

Você pode ler de volta no MySQL com:

mysql banco_dados < arquivo-backup.sql

ou

mysql -e "source /path-to-backup/backup-file.sql" database

Entretanto, é muito útil também popular outro servidor MySQL com informações de um banco de dados:

mysqldump --opt banco_dados | mysql ---host=máquina-remota -C banco_dados

É possível descarregar vários bancos de dados com um comando:

mysqldump --databases banco_dados1 [banco_dados2 banco_dados3...] > meus_bancosdedados.sql

Se desejar descarregar todos os bancos de dados, pode-se utilizar:

mysqldump --all-databases > todos_bancos_dados.sql

4.9.8. mysqlhotcopy, Copiando Bancos de Dados e Tabelas do MySQL

O mysqlhotcopy é um script perl que utiliza LOCK TABLES, FLUSH TABLES e cp ou scp para fazer um backup rápido de um banco de dados. É a maneira mais rápida para fazer um backup do banco de dados e de algumas tabelas mas ele só pode ser executado na mesma máquina onde os diretórios dos bancos de dados estão. O mysqlhotcopy só funciona no Unix e apenas para as tabelas MyISAM e ISAM.

mysqlhotcopy nome_bd [/caminho/para/novo_diretório]

mysqlhotcopy nome_bd_2 ... nome_bd_2 /caminho/para/novo_diretório

mysqlhotcopy nome_bd./regex/

mysqlhotcopy suporta as seguintes opções:

  • -?, --help

    Exibe uma tela de ajuda e sai

  • -u, --user=#

    Usuário para fazer login no banco de dados

  • -p, --password=#

    Senha para usar ao conectar ao servidor

  • -P, --port=#

    Porta para usar ao conectar ao servidor local

  • -S, --socket=#

    Qual socket usar ao conectando a um servidor local

  • --allowold

    Não aborta se o alvo já existir (renomeie-o para _old)

  • --keepold

    Não apaga alvos anteriores (agora renomeados) quando pronto

  • --noindices

    Não inclui arquivos de índices na cópia para deixar o backup menor e mais rápido. Os índices podem ser recostruídos mais tarde com myisamchk -rq..

  • --method=#

    Metódo para copiar (cp ou scp).

  • -q, --quiet

    Seja silencioso exceto em erros

  • --debug

    Habilita depuração

  • -n, --dryrun

    Relata ações sem realizá-las

  • --regexp=#

    Copia todos bancos de dados com nomes que coincidem com a expressão regular

  • --suffix=#

    Sufixo para nomes de bancos de dados copiados

  • --checkpoint=#

    Insere entrada de ponto de controle um uma bd.tabela especificada

  • --flushlog

    Atualiza logs uma vez que todas as tabelas estiverem bloqueadas.

  • --tmpdir=#

    Diretório Temporário (em vez de /tmp).

Você pode utilizar perldoc mysqlhotcopy para obter uma documentação mais completa de mysqlhotcopy.

mysqlhotcopy lê os grupos [client] e [mysqlhotcopy] dos arquivos de opções.

Para poder executar mysqlhotcopy é necessário acesso de escrita ao diretório de backup, privilégio SELECT nas tabelas que desejar copiar e o privilégio Reload no MySQL (para poder executar FLUSH TABLES).

4.9.9. mysqlimport, Importando Dados de Arquivos Texto

mysqlimport fornece uma interface de linha de comando para a instrução SQL LOAD DATA INFILE. A maioria das opções aceitas correspondem diretamente às opções de LOAD DATA INFILE. Veja mais informações sobre isto na Seção 6.4.8, “Sintaxe LOAD DATA INFILE.

mysqlimport é chamado desta maneira:

shell> mysqlimport [opções] banco_de_dados arquivo_texto1 [arquivo_texto2....]

Para cada arquivo texto passadoo na linha de comando, mysqlimport remove qualquer extensão do nome do arquivo e utiliza o resultado para determinar para qual tabela os dados do arquivo serão importados. Por exemplo, arquivos chamados patient.txt, patient.text e patient serão importados para uma tabela chamada patient.

mysqlimport suporta as seguintes opções:

  • -c, --columns=...

    Esta opção recebe uma lista de nomes de campos separados por vírgula como um argumento. A lista de campos é utilizada para criar um comando LOAD DATA INFILE adequado que é então passado ao MySQL. Veja mais informações sobre isto na Seção 6.4.8, “Sintaxe LOAD DATA INFILE.

  • -C, --compress

    Compacta todas as informações entre o cliente e o servidor se ambos suportarem compressão.

  • -#, --debug[=option_string]

    Rastreia o programa (para depuração).

  • -d, --delete

    Esvazie a tabela antes de importar o arquivo texto.

  • --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=..., --lines-terminated-by=...

    Estas opções tem o mesmo significado que as cláusulas correspondentes para LOAD DATA INFILE. Veja mais informações sobre isto na Seção 6.4.8, “Sintaxe LOAD DATA INFILE.

  • -f, --force

    Ignorar erros. Por exemplo, se uma tabela para um arquivo texto não existir, continue processando quaisquer arquivos restantes. Sem --force, mysqlimport sai se uma tabela não existir.

  • --help

    Exibe uma mensagem de ajuda e sai.

  • -h host_name, --host=host_name

    Importa dados para o servidor MySQL na máquina referida. A máquina padrão é localhost.

  • -i, --ignore

    Veja a descrição para a opção --replace.

  • --ignore-lines=n

    Ignora as primeiras n linhas do arquivo de dados.

  • -l, --lock-tables

    Bloqueia TODAS as tabelas para escrita antes de processar qualquer arquivo texto. Isto garante que todas as tabelas são sincronizadas no servidor.

  • -L, --local

    Lê arquivos de entrada do cliente. Por padrão, é assumido que os arquivos texto estão no servidor se você conectar à localhost (máquina padrão).

  • -pyour_pass, --password[=sua_senha]

    Senha para conectar ao servidor. Se você não especificar a parte '=sua_senha', o mysqlimport irá pedir por uma senha.

  • -P port_num, --port=port_num

    O número da porta TCP/IP para usar quando conectar a uma máquina.

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    Para especificar o protocolo de conexão. Novo no MySQL 4.1.

  • -r, --replace

    As opções --replace e --ignore controlam o tratamento de registros de entrada que duplicam registros existentes em valores de chaves únicas. Se você especificar --replace, novos registros substituirão registros que tiverem o mesmo valor na chave unica. Se você especificar --ignore, registros de entrada que duplicariam um registro existente em um valor de chave única são saltados. Se você não especificar nenhuma das duas opções, um erro ocorrerá quando um valor de chave duplicado for encontrado e o resto do arquivo texto será ignorado.

  • -s, --silent

    Modo silencioso. Gera saída somente quando ocorrer algum erro.

  • -S /path/to/socket, --socket=/path/to/socket

    O arquivo socket para usar ao conectar à localhost (máquina padrão).

  • -u user_name, --user=user_name

    O nome de usuário MySQL para usar ao conectar ao servidor. O valor padrão é seu nome de usuário atual no Unix.

  • -v, --verbose

    Modo verbose. Gera mais informações na saída.

  • -V, --version

    Exibe informação sobre a versão e sai.

Abaixo um exemblo da utilização de mysqlimport:

$ mysql --version
mysql  Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686)
$ uname -a
Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
$ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
$ ed
a
100     Max Sydow
101     Count Dracula
.
w imptest.txt
32
q
$ od -c imptest.txt
0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
0000020   1  \t   C   o   u   n   t       D   r   a   c   u   l   a  \n
0000040
$ mysqlimport --local test imptest.txt
test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
$ mysql -e 'SELECT * FROM imptest' test
+------+---------------+
| id   | n             |
+------+---------------+
|  100 | Max Sydow     |
|  101 | Count Dracula |
+------+---------------+

4.9.10. mysqlshow, Exibindo Bancos de Dados, Tabelas e Colunas

mysqlshow pode ser usado para exibir rapidamente quais bancos de dados existem, suas tabelas, e o nome das colunas da tabela.

Como o programa mysql você pode obter as mesmas informações com comandos SHOW. Veja mais informações sobre isto na Seção 4.6.8, “Sintaxe de SHOW.

mysqlshow é chamado assim:

shell> mysqlshow [OPÇÕES] [banco_dados [tabela [coluna]]]
  • Se nenhum banco de dados é fornecido, todos os bancos de dados encontrados são exibidos.

  • Se nenhuma tabela é fornecida, todas as tabelas encontradas no banco de dados são exibidas.

  • Se nenhuma coluna for fornecida, todas colunas e tipos de colunas encontrados na tabela são exibidos.

Note que em versões mais novas do MySQL, você só visualiza as tabelas/bancos de dados/colunas para quais você tem algum privilégio.

Se o último argumento conter uma shell ou um meta-caracter do SQL, (*, ?, % ou _) somente o que coincidir com o meta-caracter é exibido. Se um banco de dados conter underscore (_), eles devem ser precedidos por uma barra invertida (algumas shells de Unix irão exigir duas), para se obter tabelas/colunas apropriadamente. '*' são convertidos em metacaracteres '%' do SQL e '?' em metacaracteres '_' do SQL. Isto pode causar alguma confusão quando alguém tentar exibir as colunas para uma tabela com um _, neste caso o mysqlshow exibe somente os nomes de tabelas que casarem com o padrão. Isto é facilmente corrigido adicionando um % extra na linha de comando (como um argumento separador).

4.9.11. mysql_config, Opções para compilação do cliente MySQL

mysql_config lhe fornece informação útil sobre como compilar o seu cliente MySQL e conectá-lo ao MySQL.

mysql_config suporta as seguintes opções:

  • --cflags

    Parâmetros de compilação para encontrar arquivos incluídos e parâmetros e definições de compiladores criticos usados ao compilar a biblioteca libmysqlclient.

  • --include

    Opções de compilador para encontrar arquivos de inclusão do MySQL. (Normalmente se usaria --cflags em vez disto)

  • --libs

    Bibliotecas e opções exigidas para ligar com a biblioteca cliente do MySQL.

  • --libs_r

    Bibliotecas e opções exigidas para ligar a biblioteca cliente do MySQL segura com thread.

  • --socket

    O nome socket padrão, definido ao configurar o MySQL.

  • --port

    O número da porta padrão, definida ao configurar o MySQL.

  • --version

    Número da versão da distribuição MySQL.

  • --libmysqld-libs ou --embedded

    Bibliotecas e opções exigidas para ligar com o servidor embutido MySQL.

Se você executar mysql_config sem nenhuma opção ele exibirá todas as opções suportadas mais os valores de todas elas:

shell> mysql_config
Usage: /usr/local/mysql/bin/mysql_config [OPTIONS]
Options:
        --cflags         [-I/usr/local/mysql/include/mysql -mcpu=pentiumpro]
  --include        [-I/usr/local/mysql/include/mysql]
  --libs           [-L/usr/local/mysql/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto]
  --libs_r         [-L/usr/local/mysql/lib/mysql -lmysqlclient_r -lpthread -lz -lcrypt -lnsl -lm -lpthread]
  --socket         [/tmp/mysql.sock]
  --port           [3306]
  --version        [4.0.16]
  --libmysqld-libs [-L/usr/local/mysql/lib/mysql -lmysqld -lpthread -lz -lcrypt -lnsl -lm -lpthread -lrt]

Você pode usá-lo para compilar o cliente MySQL como a seguir:

CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

4.9.12. perror, Explicando Códigos de Erros

Para a maioria dos erros de sistema o MySQL irá, em adição a uma mensagem de texto interna, imprimir também o código de erro do sistema em um dos seguintes estilos: message ... (errno: #) ou message ... (Errcode: #).

Você pode descobrir o que o código de erro significa exeminando a documentação para o seu sistema ou usar o utilitário perror.

perror exibe a descrição para um código de erro do sistema, ou um código de erro do mecanismo de armazenamento MyISAM/ISAM (handler de tabela).

perror é utilizado assim:

shell> perror [OPÇÕES] [CÓDIGO_ERRO [CÓDIGO_ERRO...]]

Exemplo:

shell> perror 13 64
Error code  13:  Permission denied
Error code  64:  Machine is not on the network

Note que a mensagem de erro sã ona maioria dependente do sistema!

4.9.13. Como Executar Comandos SQL a Partir de um Arquivo Texto

O cliente mysql normalmente é usado de maneira interativa, desta forma:

shell> mysql banco_dados

Entretanto, também é possível colocar seus comandos SQL em um arquivo e dizer ao mysql para ler a entrada a partir deste arquivo. Para fazer isto, crie um arquivo texto arquivo_texto contendo os comandos que você deseja executar. Então execute o mysql como exibido abaixo:

shell> mysql banco_dados < arquivo_texto

Você também pode iniciar seu arquivo texto com uma instrução USER nome_bd. Neste caso, não é necessário especificar o nome do banco de dados na linha de comando:

shell> mysql < arquivo_texto

Se você já está executando o mysql, você pode executar um arquivo de script SQL usando o comando source:

mysql> source filename;

Para mais informações sobre o modo batch, Seção 3.5, “Utilizando mysql em Modo Batch”.

4.10. Os Arquivos de Log do MySQL

O MySQL tem vários arquivos de log diferentes que podem ajudá-lo a descobrir o que está acontecendo dentro do mysqld:

Log fileDescription
O log de errosProblemas encontrados iniciando, executando ou parando o mysqld.
O log isamDocumenta todas alterações a tabelas ISAM. Usado somente para depuração do código isam.
O log de consultasConexões estabelecidas e consultas executadas.
O log de atualizaçõesDesatulizado: Armazena todas as instruções que alteram dados.
O log binárioArmazena todas as instruções que alteram qualquer coisa. Usada também para replicação.
O log para consultas lentasArmazena todas queries que levaram mais de long_query_time segundos para executar ou que não usaram índices.

Todos logs podem ser encontrados no diretório de dados do mysqld. Você pode forçar o mysqld a reabrir os arquivos de log (ou em alguns casos trocar para um novo log) executando FLUSH LOGS. Veja mais informações sobre isto na Seção 4.6.4, “Sintaxe de FLUSH.

4.10.1. O Log de Erros

A arquivo de log de erro contém informações indicando quando o mysqld foi iniciado e finalizado e também qualquer erro crítico encontrado na execução.

Se o mysqld finaliza inesperadamente e o mysqld_safe precisar reiniciar o mysqld, mysqld_safe gravará uma linha restarted mysqld neste arquivo. Este log também guarda um aviso se o mysqld notificar uma tabela que precisa ser automaticamente verificada ou reparada.

Em alguns sistemas operacionais, o log de erro irá conter registros de pilha de onde o mysqld finalizou. Isto pode ser usado para saber onde e como o mysqld morreu. Veja mais informações sobre isto na Seção E.1.4, “Usando Stack Trace”.

A partir do MySQL 4.0.10 você pode especificar onde o mysqld armazena o arquivo de log de erro com a opção --log-error[=filename]. Se nenhum nome de arquivo for dado, o mysqld usará mysql-data-dir/'maquina'.err no Unix e \mysql\data\mysql.err no Windows.i Se você executar flush logs o arquivo antigo terá o prefixo --old e o mysqld criará um novo arquivo de log vazio.

Em versões mais antigas do MySQL o tratamento do log de erro era feito pelo mysqld_safe o qual redirecionava o arquivo de erro para 'maquina'.err. Pode se alterar este nome de arquivo com a opção --err-log=nome_arq.

Se você não especificar --log-error ou se você utilizar a opção --console, o erro será escrito em stderr (o terminal).

No Windows a saída é sempre feita no arquivo .err se --console não for utilizado.

4.10.2. O Log de Consultas

Se você deseja saber o que acontece com mysqld, você deve iniciá-lo com a opção --log[=arquivo]. Isto irá documentar todas conexões e consultas no arquivo log (por padrão nomeado 'nome_máquina'.log). Este log pode ser muito útil quando você suspeitar de um erro em um cliente e deseja saber exatamente o que o mysqld acha que o cliente enviou.

Older versions of the mysql.server script (from MySQL 3.23.4 to 3.23.8) pass mysqld_safe a --log option (enable general query log). If you need better performance when you start using MySQL in a production environment, you can remove the --log option from mysql.server or change it to --log-bin. Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”.

Versões mais antigas do script mysql.server (MySQL 3.23.4 a 3.23.8) passam ao safe_mysql uma opção --log (habilita a log de consulta geral). Se você precisar melhorar a performance quando iniciar o uso do MySQL em um ambiente de produção, pode remover a opção --log do mysql.server ou alterá-lo para --log-bin. Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”.

As entradas neste log são escritas quando o mysqld recebe as questões. Pode estar diferente da ordem em que as instruções são executadas. Isto está em contraste com o log de atualizações e o log binário nos quais as consultas são escritas depois de serem executadas, mas que quaisquer travas sejam liberadas.

4.10.3. O Log de Atualizações

NOTA: O log de atualizações está obsoleto e foi substituído pelo log binário. Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”. O log binário pode fazer qualquer coisa que poderia ser feito com o log de atualizações, e mais. O log de atualização será removido no MySQL 5.0

Quando iniciado com a opção --log-update[=nome_arquivo], o mysqld grava um arquivo log contendo todos os comandos SQL que atualizam dados. Se nenhum arquivo for fornecido, o nome da máquina é usado. Se um nome de arquivo for fornecido, mas não possuir o caminho, o arquivo é gravado no diretório de dados. Se nome_arquivo não possuir uma extensão, o mysqld irá criar os arquivos com os nomes desta forma: nome_arquivo.###, onde ### é um número que é incrementado cada vez que mysqladmin refresh, mysqladmin flush-logs ou a instrução FLUSH LOGS forem executados ou o servidor for reiniciado.

NOTA: Para o esquema acima funcionar, você não pode criar seus próprios arquivos com o mesmo nome que os do log de atualização + algumas extensões que podem ser tratadas como números, no diretório usado pelo log de atualização!

Se forem utilizadas as opções --log ou -l, o mysqld escreve um log geral com o nome de arquivo nome_máquina.log, e o reinicio e a recarga não geram um novo arquivo de log (embora ele seja fechado e reaberto). Neste caso você pode copiá-lo (no Unix) usando:

mv nome_máquina.log nome_máquina-antigo.log
mysqladmin flush-logs
cp nome_máquina-antigo.log para-diretório-backup
rm nome_máquina-antigo.log

O log de atualização é inteligente pois registra somente instruções que realmente alteram dados. Portanto, um UPDATE ou um DELETE com uma cláusula WHERE que não encontre nenhum registro não é escrito no log. Ele salta até instruções UPDATE que atribui a uma coluna o mesmo valor que ela possuia.

O registro da atualização é feito imediatamente após uma consulta estar completa mas antes que as bloqueios sejam liberados ou que algum commit seja feito. Isto garante que o log seja escrito na ordem de execução.

Se você desejar atualizar um banco de dados a partir de arquivos de logs de atualização, você pode fazer o seguinte (assumindo que seus logs de atualização estejam nomeados na forma nome_arquivo.###):

shell> ls -1 -t -r nome_arquivo.[0-9]* | xargs cat | mysql

ls é utilizado para obter todos os arquivos de log na ordem correta.

Isto pode ser útil se você tiver que recorrer a arquivos de backup depois de uma falha e desejar refazer as atualizações que ocorreram entre a hora do backup e a falha.

4.10.4. O Log Binário

O log binário deve substituiu o log de atualizações. O log de atualizações será removido do MySQL 5.0. O log binário contém toda informação que está disponível no log de atualizações em um formato mais eficiente e de maneira transacionalmente segura.

O log binário, como o antigo log de atualização, apenas registra instruções que realmente atualizam os dados. Assim um UPDATE ou um DELETE com um WHERE que não encontra nenhum registro não é gravado no log. Ele ignora mesmo instruções UPDATE que definam a uma coluna um valor que ela já tenha.

O propósito principal do log binário é poder atualizar o banco de dados durante uma operação de restauração de forma mais completa possível, já que o log binário conteria todas as atualizações feitas depois que um backup foi realizado.

O log binário é também usado para replicar um mysqld slave a partir de um master. Veja mais informações sobre isto na Seção 4.11, “Replicação no MySQL”.

O log binário também contém informação sobre o tempo que cada consulta leva para atualizar o banco de dados. Ele não contém consultas que não modificam dados. Se você quiser registrar todas as consultas (por exemplo, para encontrar um consulta com problema) você deve usar o log geral de consultas. Veja mais informações sobre isto na Seção 4.10.2, “O Log de Consultas”.

Quando iniciado com a opção --log-bin[=nome_arquivo], o mysqld escreve um arquivo de log contendo todos comandos SQL que atualizam dados. Se nenhum arquivo for fornecido, ele aponta para o nome da máquina seguido de -bin. Se for fornecido o nome do arquivo, mas ele não tiver o caminho, o arquivo é escrito no diretório de dados.

Se você fornecer uma extensão à --log-bin=nome_arquivo.extensão, a extensão será removida sem aviso.

O mysqld irá acrescentar uma extensão ao nome de arquivo do log binário que é um número que é incrementado cada vez que mysqladmin refresh, mysqladmin flush-logs, a instrução FLUSH LOGS forem executados ou o servidor for reiniciado. Um novo log binário também será automaticamente criado quando o tamanho do log atual alcançar max_binlog_size. Nota se você estiver usando transações: uma transação é escrita em um bloco no arquivo de log binário, já que ele nunca é separado entre diversos logs binários. Desta forma, se você tiver grnades transações, você pode ter logs binários maiores que max_binlog_size.

Você pode deletar todos os arquivos de log binário com o comando RESET MASTER (Veja mais informações sobre isto na Seção 4.6.5, “Sintaxe de RESET), ou apenas alguns deles com PURGE MASTER LOGS (Veja mais informações sobre isto na Seção 4.11.7, “Instruções SQL para Controle do Servidor Master”).

Você pode utilizar as seguintes opções ao mysqld para afetar o que é documentado pelo log binário (tenha certeza de ler as notas que seguem esta tabela):

OpçãoDescrição
binlog-do-db=nome_banco_dadosDiz ao master que ele deve registrar atualizações no log binário se o banco de dado atual (ex.: aquele selecionado por USE) é 'nome_banco_dados'. Todos os outros bancos de dados que não forem explicitamente mencionados são ignorados. Note que se você utilizá-lo você deve se assegurar que você só faz atualizações no banco de dados atual. (Exemplo: binlog-do-db=algum_bancodados) Exemplo do que não funciona como você poderia esperar: se o servidor é iniciado com binlog-do-db=sales, e você fizer USE prices; UPDATE sales.january SET amount=amount+1000;, esta consulta não será gravada no log binário.
binlog-ignore-db=nome_banco_dadosDiz ao master que atualizações onde o banco de dados atual (ex.: aquele selecionado com USE) é 'nome_banco_dados' não deve ser gravado no log binário. Note que se você usar esta opção você deve ter certeza que você só faz atualizações no banco de dados atual. (Exemplo: binlog-ignore-db=algum_banco_dados) Exemplo do que não funciona como você poderia esperar: se o servidor é iniciado com binlog-do-db=sales, e você fizer USE prices; UPDATE sales.january SET amount=amount+1000;, esta consulta será gravada no log binário.

As regras estão avaliadas na seguinte ordem, para decidir se a consulta deve ser escrita no log binário ou não:

  1. Existem as regras binlog-do-db ou binlog-ignore-db?

    • Não: grave a consulta no log binário e saia.

    • Sim: Vá para o passo abaixo.

  2. Então existe algumas regras (binlog-do-db ou binlog-ignore-db ou ambos). Existe um banco de dados atual (algum banco de dados foi selecionado com USE?)?

    • Não: NÃO grave a consulta e saia.

    • Sim: vá para o passo abaixo.

  3. Existe um banco de dados. Existe alguma regra binlog-do-db?

    • Sim: O banco de dados atual se encaixa em qualquer uma das regras binlog-do-db?

      • Sim: grave a consulta e saia.

      • Não: NÃO grave a consulta e saia.

    • Não: Vá para o passo abaixo.

  4. Existem algumas regras binlog-ignore-db. O banco de dados atual se encaixa em qualquer uma das regras binlog-ignore-db?

    • Sim: não grave a consulta e saia.

    • Não: grave a consulta e saia.

Então, por exemplo, um slave em execução com apenas binlog-do-db=sales não gravará no log binário qualquer consulta em que o banco de dados atual é diferente de sales (em outras palavras, binlog-do-db pode, significar algumas vezes, ``ignore outros bancos de dados'').

Para saber quais arquivos binários foram usados, o mysqld irá criar também um arquivo de índice para o log binário que contém o nome de todos os arquivos de log binário usados. Por padrão este arquivo tem o mesmo nome que o arquivo de log binário, com a extensão '.index'. Você pode alterar o nome do arquivo de índice do log binário com a opção --log-bin-index=[nome_arquivo]. Você não deve eduitar este arquivo manualmente enquanto o mysqld estiver em execução; fazer isto confundiria o mysqld.

Se estiver sendo usado replicação, os arquivos de log binário antigos não devem ser apagados até ter certeza que nenhum slave irá mais precisar deles. Uma forma de fazer isto é o utilizar mysqladmin flush-logs uma vez por dia e então remover qualquer log com mais de 3 dias. Você pode removê-los manualmente, ou de preferência usando PURGE MASTER LOGS (Veja mais informações sobre isto na Seção 4.11.7, “Instruções SQL para Controle do Servidor Master”) o qual atualizará de forma segura o arquivo de índice do log binário para você (e que pode ter um argumento de data desde o MySQL 4.1)

Uma conexão com o privilégio SUPER pode desabilitar o registro no log binário de suas consultas usando SET SQL_LOG_BIN=0. Veja mais informações sobre isto na Seção 4.11.7, “Instruções SQL para Controle do Servidor Master”.

Você pode examinar o arquivo de log binário com o utilitário mysqlbinlog. Por exemplo, você pode atualizar um servidor MySQL a partir de um log binário como mostrado a seguir:

mysqlbinlog arquivo-log | mysql -h nome_servidor

Veja Seção 4.9.5, “mysqlbinlog, Executando as Consultas a Partir de um Log Binário” para mais informações sobre o utilitário mysqlbinlog e como utilizá-lo.

mysqlbinlog --help irá lhe fornecer mais informações de como usar este programa!

Se você estiver utilizando BEGIN [WORK] ou SET AUTOCOMMIT=0, você deve utilizar o log binário do MySQL para backups no lugar do antigo log de atualização.

O Log binário é feito imedatamente depois que uma consulta terminar mas antes que os bloqueios sejam liberados ou algum commit seja feito. Isto garante que o log seja feito na ordem de execução.

Atualizações em tabelas não transacionais são armazenadas o log binário imediatamentedepois da execução. Para tabelas tranascionais como BDB ou InnoDB, Todas atualizações (UPDATE, DELETE ou INSERT) que alteram uma tabela transacional são armazenadas no cache até um COMMIT. Quaisquer atualizações a uma tabela não transacional são armazenadas no log binário de uma vez. Todas as threads irão, no início, alocar um buffer de binlog_cache_size para registrar consultas. Se uma conaulta é maior que o registro, a thread irá criar um arquivo temporário para lidar com a mesma. O arquivo temporário será apagado quando a thread terminar.

O max_binlog_cache_size (padrão 4G) pode ser usado para restringir o tamanho total usado para armazenar uma consulta multi-transacional. Se uma transação é maior que isto ela falhará e fará um roll back.

Se você estiver utilizando o log de atualização ou o binário, inserções concorrentes não funcionarão juntas com CREATE ... INSERT e INSERT ... SELECT. Isto é para garantir que você possa recriar uma cópia exata de suas tabelas aplicando o log em um backup.

4.10.5. O Log para Consultas Lentas

Quando iniciado com a opção --log-slow-queries[=file_name] o mysqld escreve em um arquivo log contendo todos os comandos SQL que levam mais de long_query_time segundos para executar. O tempo para obter os bloqueios de tabelas iniciais não são contados como tempo de execução.

O log de consultas lentas é gerado depois que uma query é executada e depois de todas as bloqueios serem liberados. Ela pode estar em ordem diferente da que as instruções foram executadas.

Se nenhum nome de arquivo for fornecido, o padrão é o nome da máquina com o sufixo -slow.log. Se um nome de arquivo for especificado, mas não conter o caminho, o arquivo é gravado no diretório de dados.

O log para queries lentas pode ser usado para encontrar queries que levam muito tempo para executar e que devem ser candidatas a otimização. Com um log muito grande, isto pode ser uma tarefa difícil. Você pode utilizar o log de consultas lentas através do comando mysqldumpslow para obter um resumo das consultas que aparecem no log.

Se a opção --log-long-format estiver sendo usada, então as consultas que não estiverem utilizando índices serão escritas. Veja mais informações sobre isto na Seção 4.1.1, “Opções de Linha de Comando do mysqld.

4.10.6. Manutenção do Log de Arquivo

O MySQL tem vários arquivos de log que possibilitam ver o que está ocorrendo com mais facilidade. Veja mais informações sobre isto na Seção 4.10, “Os Arquivos de Log do MySQL”. Porém de tempos em tempos deve ser feita uma limpeza nos arquivos de logs do MySQL para que eles não ocupem muito do espaço do disco.

Ao utilizar o MySQL com arquivos log, você necessitará de tempos em tempos remover antigos arquivos de log e dizer ao MySQL para logar com novos arquivos. Veja mais informações sobre isto na Seção 4.5.1, “Backups dos Bancos de Dados”.

Em uma instalação Linux RedHat), você pode usar o script mysql-log-rotate para isto. Se você instalou o MySQL de uma distribuição RPM, o script deve ter sido instalado automaticamente. Perceba que você deve ter cuidado com este script se você estiver utilizando o log binário para replicação!

Em outros sistemas você deve instalar um pequeno script que será executado pelo cron para lidar com os arquivos de log.

Você pode forçar o MySQL a iniciar utilizando novos arquivos de log usando mysqladmin flush-logs ou utlizando o comando SQL FLUSH LOGS. Se você usa o MySQL Versão 3.21 deve utilizar o comando mysqladmin refresh.

O comando acima faz o seguinte:

  • Se o log padrão (--log) ou log de consultas lentas (--log-slow-queries) forem utilizados, fecha e reabre o arquivo de log. (mysql.log e `hostname`-slow.log como padrão).

  • Se o log de atualização (--log-update) é usado, fecha o log de atualização e abre um novo arquivo log com uma sequência numérica mais alta.

Se você só estiver utilizando o log de atualização, você tem apenas que atualizar os logs e então mover os arquivos de log antigos para um backup. Se você estiver utilizando o log normal, você pode fazer algo assim:

shell> cd diretório-dados-mysql
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs

e então fazer um backup e remover o mysql.old.

4.11. Replicação no MySQL

Capacidades de replicação permitidindo que os bancos de dados em um servidor MySQL seja duplicado em outro foram introduzidos no MySQL versão 3.23.15. Esta seção descreve os vários recursos da replicação no MySQL. Ele serve como uma referência para as opções disponíveis na replicação. Você será introduzido a replicação e aprenderá como implementá-la. Em direção ao final, existem algumas questões mais perguntadas (FAQ), descrições de problemas e como resolvê-los.

Sugeriemos que você visite nosso website em http://www.mysql.com/ frequentemente e leia as atualizações desta seção. A replicação esta constantemente sendo melhorada e nós atualizamos o manual frequentemente com a informação mais atual.

4.11.1. Introdução

A partir da versão 3.23.15, o MySQL suporta replicação de uma via internamente. Um servidor atua como o master, enquando o outro atua como slave. O servidor master mantêm um log binário de atualizações (see Seção 4.10.4, “O Log Binário”). É mantido também um arquivo de índices dos logs binários para manter os registro da rotatividade dos logs. Cada slave, na conexão, informa ao master onde parou desde a última atualização propagada com sucesso, realiza a atualização e então para e espera o master informar sobre novas atualizações.

Um slave também pode ser um master se você condigurar uma cadeia de servidores em replicação.

Note que se você estiver usando replicação, todas atualizações nas tabelas replicadas devem ser realizadas no servidor master. Senão, você sempre deve ter cuidados para evitar conflitos entre as atualizações que os usuários enviam ao master e aquelas que os usuários enviam ao slave.

Replicação de uma via trazem benefícios de robustez, velocidade e administração do sistema:

  • A robustez é aumentada com uma configuração master/slave. No evento de problemas com o master, você pode trocar para o slave como um backup.

  • A velocidade extra é alcançada dividindo a carga das consultas dos clientes em processamento para entre os servidores master e slave, resultando em melhor tempo de resposta. Consultas SELECT podem ser enviadas para o slave para reduzir a carga do processamento das consultas do master. Consultas que modificam dados devem ainda ser enviados para o master e slave para não ficarem fora de sincronia. Esta estratégia de balancemento de carga é efetiva se consultas que não sejam de atualização dominarem, mas este é o caso normal.

  • Outro benefício de utilizar replicação é que pode-se obter backups intantâneos do sistema fazendo backups no slave em vez de fazê-los no master. See Seção 4.5.1, “Backups dos Bancos de Dados”.

4.11.2. Visão Geral da Implementação da Replicação

A replicação no MySQL baseia-se no fato do servidor master manter o registro de todas as alterações de seus bancos de dados (atualizações, deleções, etc) no log binário. (Veja mais informações sobre isto na Seção 4.10.4, “O Log Binário”). Cada servidor slave recebe do master consultas salvas no log binário, para que assim execute as mesmas consultas nos seus dados replicados.

É muito importante entender que o log binário é simplesmente um registro iniciando a partir de um ponto fixo no tempo (o momento que você habilitou o log binário). Quaisquer slaves que você configure necessitará de cópias do banco de dados do seu master como eles existiam no momento em que o log binário foi habilitado no master. Se você iniciar os slaves com dados diferentes daqueles do master quando o log binário foi iniciado, seus slaves falharão.

A seguinte tabela indica a compatibilidade de replicação master/slave entre diferentes versões do MySQL.

  MasterMasterMasterMaster
  3.23.33 e posterior4.0.04.0.14.0.3 e posterior
Slave3.23.33 e posteriorsimnãonãonão
Slave4.0.0nãosimnãonão
Slave4.0.1simnãosimnão
Slave4.0.3 e posteriorsimnãonãosim

Como regra geral, sempre é recomendado usar versões MySQL recentes, porque as capacidades de replicação estão sendo continuamente melhoradas. Com relação a versão 4.0, recomendamos usar a mesma versão para o master e o slave, com exceção de que o 4.0.2 não é recomandado para replicação.

Note qye quando você atualiza um mestre do MySQL 3.23 para o MySQL 4.0 (ou 4.1) você não deve reiniciar a replicação usando o log binário antigo da versão 3.23, porque isto infelizmente deixa o slave 4.0 confuso. A atualização pode seguramente feita deste modo, assumindo que você tenha uma mestre 3.23 para atualizar e você tenha slaves 4.0:

  1. Bloqueie todas as atualizações no mestre (FLUSH TABLES WITH READ LOCK).

  2. Espere até que todos os slaves tenham buscados todas as alterações pelo master (use SHOW MASTER STATUS no master, e SELECT MASTER_POS_WAIT() nos slaves). Então execute STOP SLAVE nos slaves.

  3. Finalize o MySQL no master e atualize o master para o MySQL 4.0.

  4. Reinicie o MySQL no master. Grave o nome <name> do log binário mais recentemente criado do master. Você pode obter o nome dos arquivos executando SHOW MASTER STATUS no master. Então envie estes comando em cada slave:

    mysql> CHANGE MASTER TO MASTER_LOG_FILE='<name>', MASTER_LOG_POS=4;
    mysql> START SLAVE;
    

Se você também deve atualizar seus slaves da versão 3.23 para 4.0, você deve primeiro atualizar seus slaves: Desligue cada um, atualize-os e os reinicie. Então atualize o master como descrito.

A partir da versão 4.0.0, pode se usar LOAD DATA FROM MASTER para configurar um escrao. Esteja certo que LOAD DATA FROM MASTER funciona atualmente apenas se todas as tabelas no master são do tipo MyISAM. Além disso, estas instrução irão adquirir lock global de leitura, assim nenhuma escrita será possível enquanto as tabelas estão sendo transferidas do master. Quando implementarmos hot backup de tabelas sem lock (no MySQL 5.0), este lock global de leitura não será mais necessário.

Devido a estas limitações, recomendamos que você só use LOAD DATA FROM MASTER se o conjunto de dados de master for relativamente pequeno, ou se um lock de leitura prolongado no master é aceitável. Enquanto a velocidade atual do LOAD DATA FROM MASTER pode variar de sistema para sistema, uma boa regra do dedão de quanto tempo será necessário é considerar 1 segundo por 1 MB do arquivo de dados. Você ficará próximo da estimativa se tanto o master quanto o slave forem equivalentes a um Pentium 700 Mhz e estiverem conectado a uma rede de 100 MBits/s. É claro, esta é apenas uma estimativa grosseira da ordem de magnitude.

Uma vez que o slave foi configurado corretamente e está em execução, ele simplesmente conectará ao master e esperará por atualizações nos processos. Se o master for desligado ou o slave perder conectividade com seu master, ele tentará conectar periodicamente até conseguir reconectar e constinuar as atualizações. O intervalo de tentativa é controlado pela opção --master-connect-retry. O padrão é 60 segundos.

Cada slave mantêm registro de onde parou. O servidor master não tem conhecimento de quandos slaves existem ou quais estão atualizados em um determinado momento.

4.11.3. Detalhes de Implementação da Replicação

Três threads estão envolvidas na replicação: uma no master e duas no slave. Quando START SLAVE é executado, a thread de E/S é criada no slave. Ela se conecta ao master e pede pelo envio de seus logs binários. Então uma thread (chamada Binlog dump no SHOW PROCESSLIST no master) é criada no master para enviar estes logs binários. A thread de E/S lê o que o Binlog dump envia e simplesmente a copia para algum arquivo local no diretorio de dados do slave chamado relay logs. A última thread, a thread de SQL, é criada no slave; ela lê o relay logs e executa as consultas contidas nele.

Note que o master tem uma thread para cada servidor slave atualmente conectado.

Com SHOW PROCESSLIST você pode saber o que está acontecendo no master e no slave em relação a replicação.

O exemplo seguinte ilustra como as três threads aparecem em SHOW PROCESSLIST. O formato da saída é aquele usado por SHOW PROCESSLIST a partir do MySQL versão 4.0.15, quando o conteúdo da coluna State foi alterado para ser mais significativo comparado com versões alterações.

No servidor master a saída se parece com isto:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL

No servidor slave, a saída se parece com isto:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O thread to update it
   Info: NULL

Aqui a thread 2 está no master. A thread 10 é a thread de E/S no slave. A thread 11 é a thread de SQL no slave; note que o valor na coluna Time pode dizer quando o slave é comparado com o master (Veja mais informações sobre isto na Seção 4.11.9, “FAQ da Replicação”).

A lista a seguir mostra os estados mais comuns que você verá na coluna State para a thread Binlog Dump do master. Se você não ver estas threads em um servidor master, a replicação não está sendo executada.

  • Sending binlog event to slave

    Logs binários consistem de eventos, onde um evento é normamente uma consulta mais alguma informação. A thread lê um evento do log binário e ele é enviado para o slave.

  • Finished reading one binlog; switching to next binlog

    A thread finalizou a leitura de um log binário e está abrindo o seguinte a ser enviado para o slave.

  • Has sent all binlog to slave; waiting for binlog to be updated

    A thread leu todos os log binários e está inativa. Ela está esperando por conexões no master para gravar mais dados no log binário, se ele quiser.

  • Waiting to finalize termination

    Estado muito breve que ocorre quando a thread para.

Aqui estão os estados mais comuns que você verá na coluna State para a thread de E/S de um servidor slave. A partir do MySQL 4.1.1, este estado também aparece na coluna Slave_IO_State da saída de SHOW SLAVE STATUS. Isso significa que você pode ter uma boa visão do que está acontecendo apenas com SHOW STATUS SLAVE.

  • Connecting to master.

    Conectando ao master.

  • Checking master version.

    Estado muito breve que ocorre um pouco depois da conexão ser estabelecida.

  • Registering slave on master.

    Estado muito breve que ocorre um pouco depois da conexão ser estabelecida.

  • Requesting binlog dump.

    Estado muito breve que ocorre um pouco depois da conexão com o master ser estabelecida. A thread envia ao master um pedido para envio do conteúdo de seu log binário, iniciando a partir do log binário requisitado e sua posição.

  • Waiting to reconnect after a failed binlog dump request.

    Se o pedido de dump do log binário falhar (devido a desconexão), a thread fica neste estado enquanto está inativa. A thread fica inativa por master-connect-retry segundos antes de uma nova tentativa.

  • Reconnecting after a failed binlog dump request.

    Então a thread tenta se conectar com o master.

  • Waiting for master to send event.

    A thread conectou e está esperando que os eventos do log binário cheguem. Isto pode demorar se o master estiver inativo. Se a espera for maior que slave_read_timeout segundos, o tempo se esgotará. Neste ponto, a thread irá considerar a conexão quebrada e fará uma nova tentativa de conexão.

  • Queueing master event to the relay log.

    A thread leu o evento e o está copiando para o ser relay log para que a thread SQL possa processá-lo

  • Waiting to reconnect after a failed master event read.

    Um erro ocorreu durante a leitura (devido a desconexão); inativo por master-connect-retry segundos antes de tentar se reconectar.

  • Reconnecting after a failed master event read.

    Então a thread tenta se reconectar. Quando a conexão é estabelecida novamente, o estado se tornará Waiting for master to send event.

  • Waiting for the slave SQL thread to free enough relay log space

    Você está usando um valor relay_log_space_limit diferente de zero e os relay logs tem crescido tanto que o seu tamanho combinado excedem este valor. A thread E/S então espera até que a thread SQL libere espaço suficiente deletando o conteúdo dos relay logs e assim poder deletar alguns arquivos de relay logs.

  • Waiting for slave mutex on exit.

    Estado muito breve que ocorre quando a thread esta parando.

Aqui estão os estado mais comuns que você verá na coluna State para a thread de SQL de um servidor slave:

  • Reading event from the relay log

    A thread leu um evento do relay log para poder processá-lo.

  • Has read all relay log; waiting for the slave I/O thread to update it

    A thread processou todos os eventos nos arquivos de relay logs e está esperando a thread de E/S gravar novos eventos no relay log.

  • Waiting for slave mutex on exit.

    Estado muito breve que ocorre quando a thread é parada.

A coluna State para a thread de E/S também podem mostrar um string de consulta. Isto indica que a thread leu um evento do relay log, extraiu a conulta dele e está a está executando.

Antes do MySQL 4.0.2, as threads de E/S e SQL eram combinadas em uma só e nenhum relay log era usado. A vantagem do uso de duas threads é que elas separam a leitura e a execução da consulta em duas tarefas independentes, e assim o trabalho de leitura da consulta não se torna lento se a execução da consulta for lento. Por exemplo, se o servidor slave não estiver em execução por um instante, a sua thread de E/S pode rapidamente buscar todos o conteúdo dos logs binários do master quando o slave iniciar, mesmo se a thread de SQL demorar e levar horas para pegar os logs. Se o slave parar antes da thread SQL executar todas as consultas buscadas, a thread de E/S terá finalmente buscado tudo e assim um cópia segura das consultas estará armazenada localmente nos relay logs do slave para execução na próxima execução do slave. Isto permite que os log binários sejam apagados no master, já que não há mais necessidade de esperar que o slave busque o conteúdo deles.

Por padrão, relay logs são nomeados usando nome de arquivos da forma host_name-relay-bin.nnn, onde host_name é o nome da máquina servidora slave e nnn é uma sequência numérica. Arquivos de relay logs sucvessivos são criados usando uma sequência de números sucessiva, começando com 001. O slave mantém registro dos relay logs em uso atualmente em um arquivo de índice. O nome de arquivo padrão dos relay logs é host_name-relay-bin.index. Por padrão estes arquivos são criados no diretório de dados do slave. O nome de arquivo padrão pode ser sobrescrito com as opções --relay-log e --relay-log-index do servidor.

Relay logs têm o mesmo formato dos logs binários, assim ele podem ser lidos com mysqlbinlog. Um relay log é automaticamente deletado pela thread de SQL tão logo não seja mais necessária (ex.: assim que tiver sido executado todos os seus eventos). Não existem comandos para deletar relay logs já que a thread SQL cuida de fazê-lo. No entanto, a partir do MySQL 4.0.14, FLUSH LOGS rotaciona os relay logs), o que irá influenciar quando a thread de SQL deletá-los.

Um novo relay log é criado sob as seguintes condições:

  • A primeira vez que a thread de E/S inicia depois que o servidor slave inicia (No MySQL 5.0, um novo relay log será criado a cada vez que a thread de E/S inicia, não apenas pela primeira vez.)

  • Uma instrução FLUSH LOGS é executada (a partir da versão 4.0.14).

  • O tamanho do relay log atual se torna muito grande. O significado de ``muito grande'' é determinado da seguinte forma:

    • max_relay_log_size, se max_relay_log_size > 0

    • max_binlog_size, se max_relay_log_size = 0 ou o MySQL é mais velho que 4.0.14

Um servidor de replicação slave cria dois arquivos pequenos no diretório de dados. Estes arquivos são chamados master.info e relay-log.info por padrão. Eles possuem informação como aquela mostrada na saída da instrução SHOW SLAVE STATUS (Veja mais informações sobre isto na Seção 4.11.8, “Instruções SQL para Controle do Servidor Slave” para uma descrição deste comando). Como imagem de discos, eles sobrevivem ao desligamento do slave. A próxima vez que o slave é reiniciado, ele pode ler estes arquivos para saber o quanto ele processou do log binário do master e do seus próprios relay logs.

O arquivo master.info é atualizado pela thread de E/S.

A correspondência entre as linhas do arquivo e as colunas mostradas por SHOW SLAVE STATUS aparece a seguir:

LinhaDescrição
1Master_Log_File
2Read_Master_Log_Pos
3Master_Host
4Master_User
5Senha (não mostrado por SHOW SLAVE STATUS)
6Master_Port
7Connect_Retry

O arquivo relay-log.info é atualizada pela thread de SQL. A correspondência entre as linhas do arquivo e as colunas mostradas por SHOW SLAVE STATUS apaerece a seguir:

LinhaDescrição
1Relay_Log_File
2Relay_Log_Pos
3Relay_Master_Log_File
4Exec_Master_Log_Pos

Quando você faz backup dos dados de seu slave, você deve fazer backup destes 2 pequenos arquivos, junto com seus relay logs pois eles são necessários para continuar a replicação depois que você restaurar os dados do slave. Se você perder os seus relay logs mas ainda tiver o arquivo relay-log.info, você pode verifclos para determinar por quanto tempo a thread de SQL executou no log binário do master. Então você pode usar CHANGE MASTER TO com as opções MASTER_RELAY_LOG e MASTER_RELAY_POS para dizer ao slave para reler os log binários a partir deste ponto. Isto exige que o log binário ainda exista no servidor master. é claro.

Se seu slave está sujeito a replicação de instruções LOAD DATA INFILE, você também deve fazer backup dos arquivos SQL_L0AD-* que podem existir no diretório que o slave utiliza para este propósito. O slave precisará destes arquivos para continuar a replicação de qualquer instrução LOAD DATA INFILE interrompido.

A localização do diretório é especificada usando a opção --slave-load-tmpdir. Seu valor padrão, se não especificado, é o valor da variável tmpdir.

4.11.4. Como Configurar a Replicação

Aqui está uma descrição rápida de como configurar uma replicação completa em seu servidor MySQL atual. Ele assume que você deseja replicar todos os bancos de dados e nunca configurou uma replicação anteriormente. Você precisará desligar seu servidor master rapidamente para completar os passos delineados abaixo.

O procedimento é gravado para a configuração de um único slave, mas você pode usá-lo para configurar vários slaves.

Este método é o modo mais direto de se configurar um slave, mas ele não é o único. Por exemplo, se você já tem uma cópia instantânea dos dados do master, e o master já tem o seu ID do servidor definido e o log binário habilitado, você pode configurar um slaver sem desligar o master ou mesmo bloquear suas atualizações. Para maiores detalhes, veja Seção 4.11.9, “FAQ da Replicação”.

Se você deseja administrar uma configuração de replicação MySQL, sugerimos que leia todo este capítulo e experimente todos os comandos mencionados em Seção 4.11.7, “Instruções SQL para Controle do Servidor Master” e Seção 4.11.8, “Instruções SQL para Controle do Servidor Slave”. Você também deve se familiarizar com as opções de inicialização da replicação em my.cnf na Seção 4.11.6, “Opções de Inicialização da Replicação”.

Note que este procedimento e algumas das instruções SQL da replicação em seções posteriores se referrem ao privilégio SUPER. Antes do MySQL 4.0.2, use o privilégio PROCESS.

  1. Certifique-se que você possui uma versão recente do MySQL instalado no servidor master e no(s) slave(s), e que estas versões sào compatíveis de acordo com a tabela mostrada em Seção 4.11.2, “Visão Geral da Implementação da Replicação”.

    Por favor não relate os erros até que você tenha verificado que o problema está presente na última distribuição.

  2. Configure uma conta no servidor master com o com a qual o slave possa se conectar. Deve ser dada a esta conta o privilégio REPLICATION SLAVE. (Se a versão do MySQL for anterior a 4.0.2, de à conta o privilégio FILE.) Se a conta é somente para a replicação (o que é recomendável), então você não precisará fornecer nenhum privilégio adicional para ele.

    O nome de máquina no nome da conta deve ser aquele usado por cada um dos servidores slaves para conectar ao master. Por exemplo, para criar um usuário chamado repl que pode acessar seu master de qualquer máquina, você deve utilizar este comando:

    mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    Para versões do MySQL anteriores a 4.0.2, use este comando:

    mysql> GRANT FILE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    Se você planeja usar as instruções LOAD TABLE FROM MASTER ou LOAD DATA FROM MASTER a partir da máquina slave, você precisará de permissão para esta conta adicional.

    • Conceda a conta os privilégios globais SUPER e RELOAD.

    • Conceda o privilégio SELECT em todas as tabelas que você deseja carregar. Qualquer das tabelas master nas quais a conta não possa fazer um SELECT serão ignoradas por LOAD DATA FROM MASTER.

  3. Se você estiver usando tabelas MyISAM, descarregue todas as tabelas e bloqueie as consultas de escrita executando o comando FLUSH TABLES WITH READ LOCK

    mysql> FLUSH TABLES WITH READ LOCK;
    

    e faça uma cópia de todos os dados existentes em seu servidor master.

    A maneira mais fácil de fazer isto é simplesmente usar um programa (tar no Unix, PowerArchiver, WinRAR, WinZip ou qualquer outro software similar no Windows) para produzir um arquivo de banco de dados no diretório de dados do seu master. Por exemplo, para usar tar que cria um arquivo que inclui todos os bancos de dados, altere a localização no diretório de dados do servidor master, e então execute este comando:

    shell> tar -cvf /tmp/mysql-snapshot.tar .
    

    Se você quiser que o arquivo inclua apenas um banco de dados chamado estebd, utilize este comando:

    shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db
    

    Então copie o arquivo para o diretório /tmp na máquina servidora slave. Naquela máquina, altere a localização em um diretório de dados do slave e desempacote o arquivo usando este comando:

    shell> tar -xvf /tmp/mysql-snapshot.tar
    

    Você pode não desejar replicar o banco de dados mysql. Se não, você pode excluí-lo do arquivo. Você também não precisa incluir qualqer arquivo de log nos arquivos master.info ou relay-log.info.

    Enquanto o lock de leitura colocado por FLUSH TABLES WITH READ LOCK estiver em funcionando, leia o valor atual do nome do log binário e offset no master:

    mysql > SHOW MASTER STATUS;
    +---------------+----------+--------------+------------------+
    | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +---------------+----------+--------------+------------------+
    | mysql-bin.003 | 73       | test,bar     | foo,manual,mysql |
    +---------------+----------+--------------+------------------+
    1 row in set (0.06 sec)
    

    A coluna File exibe o nome do log, enquanto Position exibe o offset. No exemplo acima, o valor do log binário é mysql-bin.003 e o offset é 73. Grave os valores. Você precisará usá-los mais tarde quando estiver configurando o slave.

    Uma vez realizada a cópia e gravado o nome do log e offset, você pode reabilitar a atividade de escrita no master:

    mysql> UNLOCK TABLES;
    

    Se você estiver usando tabelas InnoDB, você deve usar a ferramente InnoDB Hot Backup que está disponível para aqueles que compraram as licenças comerciais do MySQL, suporte ou a própria ferramenta de backup. Ele faz uma cópia consistente sem fazer nenhum lock no servidor master, e grava o nome do log e o offset correspondente em um snapshot para ser usado postriormente no slave. Mais informações sobre esta ferramenta esta disponível em http://www.innodb.com/order.php.

    Sem a ferramenta Hot Backup, o modo mais rápido para tirar uma cópia das tabelas InnoDB é desligar o servidor master e copiar os arquivos e logs de dados do InnoDB e os arquivos de definição de tabela (.frm). Para gravar o nome e offset do arquivo de log atual você deve fazer o seguinte antes de desligar o servidor:

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    E então grave o nome e offset do log da saída de SHOW MASTER STATUS como mostrado anteriormente. Uma vez gravado o nome e o offset do log, desligue o servidor sem destravar as tabelas para se certificar que ele finalizará com a cópia correspondente ao arquivo de log e offset:

    shell> mysqladmin -uroot shutdown
    

    Uma alternativa para tabelas MyISAM e InnoDB é fazer um dump SQL do master em vez de uma cópia binária como acima; para isso você pode usar mysqldump --master-data em seu master e mais tarde executar o dump SQL em seu slave. No entanto, isto é mais lento que fazer a cópia binária.

    Se o master foi executado anteriormente sem o --log-bin habilitado, os valores do nome do log e da posição mostrados por SHOW MASTER STATUS ou mysqldump estarão vazios. Neste caso, grave a string vazia ('') para o nome do log e 4 para o offset.

  4. Assegure-se que a seção [mysqld] do arquivo my.cnf no master inclui a opção log-bin. Esta seção também deve conter a opção server-id=unique number, onde master_id deve ser um valor inteiro entre 1 e 2^32 - 1. Por exemplo:

    [mysqld]
    log-bin
    server-id=1
    

    Se estas opções não estão presentes, adicione-as e reinicie o servidor.

  5. Pare o servidor que será usado como slave e adicione o seguinte ao arquivo my.cnf:

    [mysqld]
    server-id=slave_id
    

    O valor slave_id, como o valor master_id, deve ser um valor inteiro de 1 to 2^32 - 1. Adicionalmente, é muito importante que o ID do slave seja diferente do ID do master. Por exemplo:

    [mysqld]
    server-id=2
    

    Se você estiver usando vários servidores, cada um deve ter um valor server-id que seja diferente daquele do master e de cada um dos slaves. Pense nos valores de server-id como algo similar ao endereço IP: Estes IDs identificam de forma única cada instância de servidor na comunidade dos parceiros de replicação.

    Se você não quiser especificar um server-id, ele será configurado com 1 se você não tiver definido master-host, senão ele será definido com 2. Note que no caso de omissão do server-id, um master irá recusar conexões de todos os slaves e um slave irá recusar se conectar a um master. Assim, omitir server-id só é bom para backups com um log binário.

  6. Se você fizer um backup biário dos dados do servidor master, copie-o para o diretório de dados do servidor slave antes de iniciá-lo. Certifique-se que os privilégios nos arquivos e diretórios estão corretos. O usuário com o qual o MySQL executa precisa estar apto a lê-los e alterá-los, assim como no master.

    Se você fizer um backup usando mysqldump, inicie o slave primeiro (veja o próximo passo).

  7. Inicie o servidor slave. Se ele tiver sido replicado previamente, inicie o servidor slave com a opção --skip-slave-start. Você também pode querer iniciar o servidor slave com a opção --log-warnings. Deste modo você irá obter mais mensagens sobre problemas (por exemplo, problemas de rede, ou conexão).

  8. Se você fez um backup dos dados do servidor master usando mysqldump, carregue o arquivo de dump no servidor slave:

    shell> mysql -u root -p < dump_file.sql
    
  9. Execute os seguintes comandos no slave, substutitua os valores dentro de <> com o os valores atuais relevantes ao ser sistema:

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='<master host name>',
        ->     MASTER_USER='<replication user name>',
        ->     MASTER_PASSWORD='<replication password>',
        ->     MASTER_LOG_FILE='<recorded log file name>',
        ->     MASTER_LOG_POS=<recorded log offset>;
    

    A tabela a seguir lista o tamanho máximo da string para as variáveis:

    MASTER_HOST60
    MASTER_USER16
    MASTER_PASSWORD32
    MASTER_LOG_FILE255
  10. Inicie a thread slave:

    mysql> START SLAVE;
    

Depois de realizado este procedimento, o slave deve se conectar ao master e pegar todas as atualizações que ocorreram desde que o backup foi restaurado.

Se você esqueceu de configurar o server-id no master, os slaves não poderão se conectar a eles:

Se você esqueceu de configurar o server-id no slave, você irá obter o seguinte erro no arquivo de log:

Warning: one should set server_id to a non-0 value if master_host is set.
The server will not act as a slave.

Você também encontrará mensagens de erro no log de erro do slave se ele não puder replicar por qualquer motivo.

Uma vez que um slave está replicando, você encontrará um arquivo chamado master.info e um chamado relay-log.info no diretório de dados. Estes dois arquivos são usados pelo slave para manter o registro de quanto foi processado do log binário do master. Não remova ou edite o arquivo, a menos que você realmente saiba o que está fazendo e entenda as implicações. Mesmo neste caso, é mais aconselhável usar o comando CHANGE MASTER TO.

NOTA: o conteúdo de master.info sobrepõe algumas opções especificadas na lina de comando ou no my.cnf veja Seção 4.11.6, “Opções de Inicialização da Replicação” para mais detalhes.

Agora que você tem uma cópia instantânea, você pode usá-la para configurar outros slaves. Para isso siga a porção referente ao slave descrita acima. Você não precisa ter outra cópia do master.

4.11.5. Recursos de Replicação e Problemas Conhecidos

Abaixo uma explicação do que é e o que não é suportado:

  • A Replicação será feita corretamente com valores AUTO_INCREMENT, LAST_INSERT_ID e TIMESTAMP.

  • As funções USER() e LOAD_FILE() são replicadas sem alterações e não funcionarão de forma confiável no slave. Isto também é verdade para CONNECTION_ID() em versões de servidor slaves mais antigas que 4.1.1. A nova função PASSWORD() no MySQL 4.1, é bem replicada desde os masters 4.1.1; o seu slave deve ser 4.1.0 ou acima para replicá-la. Se você tem slaves mais antigos e precisa replicar PASSWORD() do seu master 4.1.x, você deve iniciar o master com a opção --old-password.

  • As variávies SQL_MODE, UNIQUE_CHECKS, SQL_SELECT_LIMIT, SQL_AUTO_IS_NULL e TABLE_TYPE não são replicados ainda. FOREIGN_KEY_CHECKS é replicado desde a versão 4.0.14.

  • Você deve uilizar o mesmo conjunto de caracteres (--default-character-set) no master e slave. Senão, você pode conseguir erros de chaves duplicadas no slave, pois uma chave que é considrada como única no conjunto de caracteres no master pode não ser único no conjunto de caracteres do slave.

  • Se você estiver usando tabelas transacionais no master e não transacionais (para as mesmas tabelas) no slave, você terá prblemas se o slave for parado no meio de um bloco BEGIN/COMMIT, já que o slave irá, mais tarde, iniciar a partir do início do bloco BEGIN. Este assunto está em nosso TODO e será corrigido em um futuro próximo.

  • Consultas de atualização que usam variáveis de usuários são mal replicadas nas versões 3.23 e 4.0. Isto é corrigido no MySQL 4.1. Note que nomes de variáveis de usuários são caso insensitivo a partir da versão 5.0, assim você deve levar isto em conta quando configurar uma replicação entre um servidor com versão 5.0 e outro com uma versão anterior.

  • O slave pode se conectar ao master usando SSL, se o master e o slave forem ambos 4.1.1 ou mais novos.

  • Embora nunca tenhamos tido casos de ocorrênciar reais, é teoricamente possível de que o dado no master e no slave podem estar diferentes se uma consulta é projetada de modo que a modificação do dado seja não determinística, p.ex. deixar a vontade do otimizados de consultas (o que geralmente não é uma boa prática, mesmo fora da replicação!). Para uma explicação detalhada Seção 1.8.6.2, “Open Bugs / Deficiências de Projeto no MySQL”.

  • Antes do MySQL 4.1.1, os comandos FLUSH, ANALYZE, OPTIMIZE e REPAIR não são armazenados no log binário e por isto não são replicados para o slave. Isto normalmente não é um problema já que estes comandos não alteram nada. Isto significa, no entanto, que se você atualizar a tabela de privilégio do MySQL diretamente sem usar a instrução GRANT e replicar o banco de dados de privilégios mysql, você deve fazer um FLUSH PRIVILEGES em seu slave para que os novos privilégios tenham efeito. Também, se você utilizar FLUSH TABLES ao renomear uma tabela MyISAM envolvida em uma tabela MERGE, você terá uqe executar FLUSH TABLES manualmente no servidor. Desde o MySQL 4.1.1, estes comandos são escritos no log binário (exceto FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE, FLUSH TABLES WITH READ LOCK) a menos que você especifique NO_WRITE_TO_BINLOG (ou seu alias LOCAL). Para um exemplo da sintaxe Seção 4.6.4, “Sintaxe de FLUSH.

  • O MySQL suporta somente um master e vários slaves. Posteriormente adicionaremos um algorítimo de votação para trocar automaticamente o master se alguma coisa estiver errada com o master atual. Iremos também introduzir processos agentes para ajudar a fazer o balanceamento de carga enviando consultas SELECT para diferentes slaves.

  • Tabelas temporárias são replicadas, exceto no caso em que você desliga o servidor slave (e não apenas a thread slave), e você tem alguns tabelas temporárias replicadas e são usadas em instruções UPDATES que ainda não foram executadas no slave. (Se você desligar o slave, as tabelas temporárias necessárias por estas atualizações não estarão mais disponíveis quando o slave iniciar novamente.) Para evitar este problema, não desligue o servidor enquanto ele tiver tabelas temporárias abertas. Em vez disto, use este procedimento:

    1. Envie uma instrução STOP SLAVE.

    2. Use SHOW STATUS para verificar o valor da variável Slave_open_temp_tables.

    3. Se o valor é 0, envie um comando mysqladmin shutdown para desligar o slave.

    4. Se o valor é diferente de 0, reinicie as threads slaves com START SLAVE.

    5. Repita o procedimento anterior para ver se você terá melhor sorte na próxima vez.

    Planejamoc corrigir este problema em um futuro próximo.

  • É seguro conectar servidores em um relacionamento master/slave circular com log-slave-updates habilitado. Note, entretanto, que várias consultas não irão funcionar corretamente neste tipo de configuração a menos que o código do cliente seja escrito para tomar cuidado dos potenciais problemas que podem ocorrer em diferentes sequências em servidores diferentes.

    Isto significa que você pode fazer uma configuração parecida com o seguinte:

    A -> B -> C -> A
    

    As IDs do servidor são codificadas nos eventos do log binário. A saberá quando o evento que ele lê é foi originalmente criado por A, assim A não o executará não haverá loop infinito. Mas esta configuração circular só funcionará se você realizar atualizações não conflitantes entre as tabelas. Em outras palavras, se você insere dados em A e C, você nunca deve inserir um registro em A que pode ter uma chave confiltante com um registro em C. Você também não deve atualizar os mesmos registros em dois servidores se a ordem que a atualização é aplicada importa.

  • Se houver um erro em uma consulta no slave, a thread slave irá terminar e uma mensagem irá aparecer no log de erro do slave. Você deve então conectar a um slave manualmente, corrigir a causa do erro (por exemplo, tabela não existente), e então executar o comando sql SLAVE START.

  • Se a conexão para o master for perdida, o slave irá tentar se reconectar imediatamente. Se ele falhar, o slave irá tenatr a cada master-connect-retry segundos (padrão 60). Por causa disto, é seguro desligar o master, e então reiniciá-lo depois de um tempo. O slave também está apto para lidar com interrupções de rede. No entanto o slave notificará a a perda da rede apenas após não ter recebido dados do master por slave_net_timeout segundos. Assim se sua perda for pequena, você pode querer diminuir slave_net_timeout. See Seção 4.6.8.4, “SHOW VARIABLES.

  • Desligar o slave (corretamente) também é seguro, pois mantém sinais de onde parou. Desligamentos incorretos podem produzir problemas, especialmente se o cache de disco não foi sincronizado antes do sistema morrer. Seu sistema de tolerância a falhas será melhorado se você possuir um bom No-Break ou UPS.

  • Devido a natureza não trabnsacional das tabelas MyISAM, é possível ter uma consulta que atulizará apenas parcialmente uma taela e retornará um código de erro. Isto pode acontecer, por exemplo, em uma inserção multi-registro que tem uma violação da restrição da chave o use uma consulta de atualização é finalizada após atualizar alguns dos registros. Se isto acontecer no master, a thread slave sairá e irá esperar o DBA decidir o que fazer com isto a menos que seja autenticado e a execução da consulta resulte no mesmo código de erro. Se este comportamento da validação do código de erro não for desejável, algum (ou todos) os erros podem ser ignorados com a opção --slave-skip-errors. Ela está disponível a partir da versão 3.23.47.

  • Se você atualiza tabelas transacionais a partir de tabelas não-transacioanis dentro de um segmento BEGIN/COMMIT, a atualização no log binário pode estar fora de sincronia se algumas threads alterarem a tabela não transacional antes do commit da transação. Isto é porque a transação é escrita no log binário apenas quando é feito o commit.

  • Antes da versão 4.0.15, qualquer atualização de uma tabela não transacional é gravada no log binário imeditamente quando a atualização é feita enquanto atualizações transacionais são gravadas no COMMIT ou não gravadas se você utilizar um ROLLBACK. Você deve levar isto em conta quando atualizar tabelas transacionais e não transacionais na mesma transação e você estiver usando o log binário para backup ou replicação. Na versão 4.0.15 nós alteramos o comportamento do registro de transações que misturam atualizações de tabelas transacionais e não transacionais, que soluciona o problema (ordem das consultas boas no log binário, e todas as consultas necessárias são gravadas no log binário mesmo no caso de um ROLLBACK). O problema que permanece é quando uma segunda conexão atualiza uma tabela não transacional enquanto a primeira transação da conexão ainda não está finalizada (ordenação errada ainda pode ocorrer, porque a atualização da segunda conexão será gravada imediatamente depois de ela ter sido feita).

A seguinte tabela lista problemas na versão 3.23 que estão corrigidas na versão 4.0:

  • LOAD DATA INFILE é tratado apropriadamente desde que o arquivo ainda esteja no servidor master no momento da propagação da atualização.

  • LOAD LOCAL DATA INFILE será ignorado.

  • Na versão 3.23 RAND() em atualizações não é replicado apropriadamente. Use RAND(alguma_expr_nao_rand) se você estiver replicando atualizções com RAND(). Você pode, por exemplo, utilizar UNIX_TIMESTAMP() para o argumento de RAND(). Isto é corrigido na versão 4.0.

4.11.6. Opções de Inicialização da Replicação

Você deve utilizar a opção server-id no master e no slave para estabelecer uma ID de conexão única em cada servidor. Você deve escolher um valor único no intervalo de 1 a 2^32-1 para cada master e slave. Example: server-id=3

As opções que você pode utilizar no servidor master para controle do log binário estão todas descritas em Seção 4.10.4, “O Log Binário”.

A seguinte tabela descreve as opções que você pode utilizar nos servidores slaves. Você pode especificá-las na lina de comando ou no arquivo de opção.

NOTA: A replicação trata das seguintes opções de um modo especial:

  • --master-host

  • --master-user

  • --master-password

  • --master-port

  • --master-connect-retry

Se não existir nenhum arquivo master.info quando o servidor slave inicia, ele usa valores específicados no arquivo de opções ou na linha de comando. Isto irá ocorrer quando você iniciar o servidor como um slave de replicação pela primeira vez, ou você executar RESET SLAVE e desliga e reiniciar o servidor slave.

No entanto, se o arquivo master.info existe quando o servidor slave iniciar, ele usa o valor no arquivo e IGNORA qualquer valor especificado para aquelas opções no arquivo de opção ou na linha de comando.

Suponha que você especifique esta opção em seu arquivo my.cnf:

[mysqld]
master-host=this_host

A primeira vez que você iniciar o servidor como um slave de replicação, ele irá ler e usar a opção do arquivo my.cnf. O servidor gravará então aquele valor no arquivo master.info. A próxima vez que você iniciar o servidor, ele irá ler o valor da máquina master a partir do arquivo master.info. Se você modificar o arquivo my.cnf para especificar uma máquina master diferente, ele não terá efeito. Você deve usar CHANGE MASTER TO.

A partir do MySQL 4.1.1, as seguintes opções também é tratada de forma especial:

  • --master-ssl

  • --master-ssl-ca

  • --master-ssl-capath

  • --master-ssl-cert

  • --master-ssl-cipher

  • --master-ssl-key

O arquivo master.info inclui os valores correspondentes a essas opções. Adicionalmente, o formato do arquivo na versão 4.1.1 inclui na sua primeira linha o número de linhas no arquivo. Se você atualizar um servidor mais antigo para a versão 4.1.1, o master.info será atualizado para o novo formato automaticamente quando o novo servidor iniciar. (Se você substituir um MySQL 4.1.1 ou mais novo por uma versão mais antiga que a 4.1.1, você deve remover a primeira linha manualmente antes de iniciar o servidor mais antigo pela primeira vez.)

Como o servidor da precedência a uma arquivo master.info existente sobre as opções de inicialização acima descrito, você pode preferir usar as opções de inicialização para estes valores, e especifique-os usando a instrução CHANGE MASTER TO. Veja mais informações sobre isto na Seção 4.11.8.1, “CHANGE MASTER TO.

Este exemplo mostra um uso mais extensivo das opções de inicialização para configurar um servidor slave:

[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com

The following list describes startup options for controlling replication:

  • --log-slave-updates

    Diz ao slave para registrar as atualizações feitas pela thread da SQL do slave no log binário do slave. É desligado por padrão. É claro que ele exige que ele exige que o slave seja iniciado com o log binário habilitado (opção --log-bin). --log-slave-updates é usado quando você deseja colocar diversos servidores em cadeia. Por exemplo, você pode querer uma configuração como esta:

    A -> B -> C
    

    Isto é, A é o servidor master do slave B, e B é o servidor master do slave C. Para isto funcionar, onde B é tanto uma master quanto um slave, você deve iniciar B com a opção --log-slave-updates. A e B devem ser iniciados com o log binário habilitado.

  • --log-warnings

    Fazer slave exibir mais mensagens sobre o que está sendo feito. Por exemplo, ele avisará que ele obteve sucesso em reconectar depois de uma falha de conexão/rede, o avisrá sobre cada thread slave iniciada.

    Esta opção não está limitada apenas ao uso da replicação. Ela produz avisos através de um espectro de servidores ativos.

  • --master-host=host

    Especifica o nome de máquina ou endereço de IP do master para replicação. Se esta opção não for dada, a thread slave não será iniciada. O valor em master.info tem precedência se ele puder ser lido. Provavelmemte um nome nelhor para está opção seria algo do tipo --bootstrap-master-host, mas é muito tarde para alterá-la agora.

  • --master-user=nome_usuário

    O usuário da conta que a thread slave usará para autenticar ao conectar ao master. A conrta deve ter o privilégio REPLICATION SLAVE (Em versões anteriores a 4.0.2 ele devia ter o privilégio FILE). Se o usuário do master não for configurado, assume-se o usuário teste. O valor em master.info toma precedência se puder ser lida.

  • --master-password=password

    A senha da conta com a qual a thread slave autenticará quando conectar ao master. Se não definida, um senha vazia é considerada. O valor em master.info toma precedência se puder ser lido.

  • --master-port=portnumber

    A porta que o master está escutando. Se não definifa, a configuração de compilação do MYSQL_PORT é consierada. Se você não alterou as opções do configure, ela deve ser 3306. O valor em master.info toma precedência se ele puder ser lido.

  • --master-connect-retry=seconds

    O número de segundos que a thread slave espera antes de tentar se conectar ao master no caso do master ter caído ou a conexão for perdida. O padrão é 60. O valor em master.info toma precedência se puder ser lido.

  • --master-info-file=filename

    Especifica o nome a ser usado no arquivo que o slave grava a informação sobre o master. O nome padrão é master.info no diretório de dados.

  • --master-ssl, --master-ssl-ca=file_name, --master-ssl-capath=directory_name, --master-ssl-cert=file_name, --master-ssl-cipher=cipher_list, --master-ssl-key=filename

    Estas opções são usadas para configurar um conexão de replicação segura para o servidor master usando SSL. Os seus significados são os mesmos das opções correspondentes --ssl, --ssl-ca, --ssl-capath, --ssl-cert, --ssl-cipher, --ssl-key descritas em Seção 4.4.10.5, “Opções SSL de Linha de Comando”.

    Estas opções estão operacionais a partir do MySQL 4.1.1.

  • --max-relay-log-size=#

    Para rotacionar o relay log automaticamente. See Seção 4.6.8.4, “SHOW VARIABLES.

  • --relay-log=filename

    Para especificar a localização e nome que deve ser usado os relay logs. Você pode usá-lo para ter nomes de relay logs independentes do nome de máquina, ou se o seu relay log tend a ser grande (e você não que diminuir max_relay_log_size) e você precisa colocá-los em alguma área diferente do diretório de dados, ou se você quiser aumentar a velocidade balanceando as cargas entre os discos.

  • --relay-log-index=filename

    Para especificar a localização e nome que deve ser usado para arquivo de índice dos relay logs.

  • --relay-log-info-file=filename

    Para dar outro nome a relay-log.info e/ou colocá-lo em outro diretório, diferente do diretório de dados.

  • --relay-log-purge=0|1

    Disabilita/habilita a remoção automática dos relay logs assim que ele não são mais necessários. Esta é uma variável global que ode ser alterada dinâmicamente com SET GLOBAL RELAY_LOG_PURGE=0|1. o valor padrão é 1.

    Esta opção está disponível a partir do MySQL 4.1.1.

  • --relay-log-space-limit=#

    Para colocar um limite superior no tamanho total de todos os relay logs no slave (Um valor 0 significa ``ilimitado''). Isto é útil se você tiver um disco rígido pequeno em. sua máquina slave. Quando o limite é alcançado, a thread de E/S fica em pausa (não lê o log binário do master) até que a thread de SQL tenha buscado e deletado alguns dos relay logs não utilizados. Note que este limite não é absoluto: existem casos onde a thread SQL precisa de mais eventos para poder deletar, neste caso a thread de E/S irá superar o limite até que a deleção seja possível. Se isto não for feito ela entra em deadlock (o que acontecia antes do MySQL 4.0.13). Os usuários não devem configurar --relay-log-space-limit para menos que duas vezes o valor de --max-binlog-size (ou --max-binlog-size se --max-relay-log-size for 0) porque neste caso há a chance de que quando a thread de E/S espera por espaço livre porque --relay-log-space-limit é excedido, a thread de SQL não tem relay log para apagar e assim não pode satisfazer a thread de E/S, forçando-a a ignorar temporariamente --relay-log-space-limit.

  • --replicate-do-table=db_name.nome_tabela

    Diz para thread slave restrigir a replicação a uma tabela específica. Para especificar mais de uma tabela, use a diretiva múltiplas vezes, uma para cada tabela. Isto funcionará para atualizações através de bancos de dados, em contraste com --replicate-do-db. Por favor, leia as notas que seguem esta lista de opções

  • --replicate-ignore-table=db_name.nome_tabela

    Diz a thread slave para não replicar qualquer comando que atualiza a tabela especificada (mesmo se qualquer outra tabela puder ser atualizada pelo mesmo comando). Para especificar mais de uma tabela a ser ignorada, use a diretiva várias vezes, para cada tabela. Isto funcionará para atualizações através de bancos de dados, em contraste com --replicate-ignore-db. Por favor, leia as notas que seguem esta lista de opções

  • --replicate-wild-do-table=db_name.nome_tabela

    Diz a thread slave para restringir a replicação a consultas onde qualquer das tabelas atualizadas correspondam a padrão de meta caracteres especificado. Para especificar mais de uma tabela, use a diretiva vária vezes, uma para cada tabela, Isto funciona para atualizações através de banco de dados. Por favor, leia as notas que seguem esta lista de opções

    Exemplo: --replicate-wild-do-table=foo%.bar% replicará apenas atualizações que usam uma tabela em qualquer banco de dadis que comece com foo e cujos nomes de tabelas comecem com bar.

    Note que se você fizer --replicate-wild-do-table=foo%.% então a regra será propagada para CREATE DATABASE e DROP DATABASE, ex.: estas duas instruções serão replicadas se o nome de banco de dados corresponder ao padrão do banco de dados ('foo%' aqui) (testa mágica é possível por '%' ser o padrão da tabela).

    Caracteres curingas _ e % escapados: se você quiser replicar, por exemplo, todas as tableas do banco de dados my_own%db (este é o nome exato do banco de dados), e não replicar tabelas do banco de dados my1ownAABCdb, você deve escapar o _ e %: você deve usar algo como isto: replicate-wild-do-table=my\_own\%db. E se você estiver especificando esta opção para a linha de comando, dependendo do seu sistema, você precisará escapar o \ (por exemplo, com uma shell bash, você precisaria digitar --replicate-wild-do-table=my\\_own\\%db).

  • --replicate-wild-ignore-table=db_name.nome_tabela

    Diz a thread slave pra não replicar um consulta onde qualquer tabela corresponda ao padrão de meta caracteres dado. Para especificar mais de uma tabela, use a diretiva várias vezes, uma vez para cada tabela. Isto funcionará para atualizações através de banco de dados. Por favor, leia as notas que seguem esta lista de opções

    Exemplo: --replicate-wild-ignore-table=foo%.bar% não atualizará tabelas no banco de dados que iniciar com foo e cujo os nomes de tabela iniciem com bar.

    Note que se você fizer --replicate-wild-ignore-table=foo%.% então a regra será propagada para CREATE DATABASE e DROP DATABASE, ex. estas duas instruções não serão replciadas se o nome do banco de dados não corresponder ao padrão ('foo%' aqui) (esta mágica ocorre devido ao '%' como padrão da tabela).

    Caracteres curingas _ e % escapados: veja as anotações na descrição de replicate-wild-do-table logo acima.

  • --replicate-do-db=nome_bd

    Diz ao slave para restringir a replicação a comandos onde o banco de dados atual (p.ex., aquele selecionado por USE) é nome_bd. Para especificar mais de uym banco de dadosm use a diretiva várias vezes, uma vez por tabela. Note que isto não replicará consultas entre bancos de dados tais como UPDATE algum_bd.alguma_tabela SET foo='bar' se for selecionado outro banco de dados ou nenhum banco de dados. Se você precisa que atualizações entre bancos de dados funcionem, certifique-se de que você tem o MySQL 3.23.28 ou posterior, e use --replicate-wild-do-table=db_name.%. Por favor, leia as notas que seguem esta lista de opções

    Exemplo do que não funciona como você espera: se o slave é iniciado com --replicate-do-db=sales, e você faz USE prices; UPDATE sales.january SET amount=amount+1000;, esta consulta não será replicada.

    Se você precisar que atualizações entre bancos de dados funcionem, use --replicate-wild-do-table=db_name.%.

    A principal razão para este comportamento de apenas verificar o banco de dados atual é que é difícil para um comando sozinho saber se deve ser replicado ou não; por exemplo se você está usando comandos delete ou update multi-tabelas que continuam entre múltiplos bancos de dados. Também é muito mais rápido verificar apenas o banco de dados atual.

  • --replicate-ignore-db=nome_bd

    Diz ao slave para não replicar qualquer comando onde o banco de dados atual (p.ex. o selecionado por USE) é nome_bd. Para especificar mais bancos de daods use a diretiva diversas vezes, uma para cada banco de dados. Você não deve utilizar esta diretiva se você está usando atualização através de tabelas e você não quer que estas atualizações sejam replicadas. Por favor, leia as notas que seguem esta lista de opções

    Exemplo do que não funcionaria como esperado: se o slave é iniciado com --replicate-ignore-db=sales, e você faz USE prices; UPDATE sales.january SET amount=amount+1000;, esta consulta será replicada.

    Se você precisar de atualizações entre banco de dados funcione, use --replicate-wild-ignore-table=db_name.%.

  • --replicate-rewrite-db=de_nome->para_nome

    Diz ao slave para traduzir o banco de dados atual (p.ex. aquele selecionado por USE) para para_nome se ele era de_nome no master. Apenas instruções envolvendo a tabela podem ser afetadas (CREATE DATABASE, DROP DATABASE não poderão), e apenas se de_nome era o banco de dados atual no master. Isto não funcionará para atualizações entre banco de dados. Note que a translação é feita antes das regras de --replicate-* serem testadas.

    Exemplo: replicate-rewrite-db=master_db_name->slave_db_name

  • --report-host=host

    O Nome de máquina ou número IP do slave a ser relatado ao master durante o registro do slave. Aparecerá na saída de SHOW SLAVE HOSTS. Deixe indefinido se você não quiser que o slave se registre no master. Note que ele não é suficiente para o master simplesmente ler o número IP do slave fora dos sockets uma vez que o slave se conecte. Devido ao NAT e outros assuntos de roteamento,a quele IP pode não ser válido para se conectar ao slave a partir do master ou outras máquinas.

    Esta opção está disponível a partir do MySQL 4.0.0.

  • --report-port=portnumber

    Porta para conexão do slave relatado ao master durante o registro do slave. Defina-o apenas se o slave está escutando por uma porta diferente da padrão ou se você tiver um tunel especial do master ou outros clientes para o slave. Se não tiver certeza, deixe esta opção indefinida.

    Esta opção está disponível a partir do MySQL 4.0.0.

  • --skip-slave-start

    Diz ao servidor slave para não iniciar a thread slave na iicialização do servidor. O usuário pode iniciá-las mais tarde com START SLAVE.

  • --slave_compressed_protocol=#

    Se 1, usa compactação no protocolo cliente/servidor se tanto o slave quanto o mester suportá-la.

  • --slave-load-tmpdir=filename

    Esta opção é igual ao valor da variável tmpdir por padrão. Quando a thread SQL do slave replica um comando LOAD DATA INFILE, ele extrai os arquivos a serem carregados do relay logs em arquivos temporários, e então os carrega dentro da tabela. Se o arquivo carregado no master era enorme, os arquivos temporários no slave também serão enormes; embora você possa desejar que o slave coloque o arquivo temporário em algum disco grande diferente de tmpdir, usando esta opção. Nestes caso, você também pode usar a opção --relay-log, já que os relay logs serão grandes também. --slave-load-tmpdir deve apontar para o sistema de arquivo baseado em disco; não em um baseado em memória. Como o slave precisa de arquivos temporários usados para replicar LOAD DATA INFILE) para sobreviver a uma reinicialização da máquina.

  • --slave-net-timeout=#

    Número de segundos a esperer por mais dados do master antes de abortar a leitura, considerando o quebra de conexão e as tentativas de reconectar. A primeira vez ocorre imediatamente depois do tempo limite. O intervalo entre tentativas é controlado pela opção --master-connect-retry.

  • --slave-skip-errors= [err_code1,err_code2,... | all]

    Diz ao a thread SQL do slave para continuar a replicação quando uma consulta retornar um erro de uma lista fornecida. Normalmente, a replicação irá parar ao encontrar um erro, dando ao usuário a chance de resolver a inconsistêncian nos dados manualmente. Não use esta opção a menos que você saiba exetamente o motivo dos erros. Se não houver erros em sua configuração da replicação e programas clientes, e não houver erros no MySQL, você nunca deve ter uma replicação abortada com erro. O uso indiscriminado desta opção resultará em slaves fora de sincronia com o master e você não terá idéia de como o problema aconteceu.

    Para códigos de erros, você deve usar o número fornecido pela mensagem de erron no seu log de erros do slave e na saída de SHOW SLAVE STATUS. Uma lista completa de mensagens de erro podem ser encontradas na distribuição fonte em Docs/mysqld_error.txt. Os códigos de erros do servidor também são listados em Seção 13.1, “Erros Retornados”.

    Você também pode (mas não deve) usar um valor não recomendado de all o que irá ignorar todas as mensagens de erro e continua em frente indiferentemente. Não é preciso dizer, que se você usar isto, não podemos garantir a integridade dos seus dados. Por favor, não reclame se seus dados no slave não estiver nem próximo daqueles em seu master neste caso --- você foi avisado.

    Exemplos:

    --slave-skip-errors=1062,1053
    --slave-skip-errors=all
    

Algumas destas opções, como todas as opções --replicate-*, só podem ser definidas na inicialização do servidor slave, e não com ele ligado. Planejamos corrigir isto.

Aqui está a ordem de avaliação das regras --replicate-*, para decidir se a consulta será executada pelo slave ou ignorada por ele:

  1. Existe alguma regra --replicate-do-db ou --replicate-ignore-db?

    • Sim: teste-as como para --binlog-do-db e --binlog-ignore-db (see Seção 4.10.4, “O Log Binário”). Qual é o resultado do teste?

      • ignore a consulta: ignore-a e saia.

      • execute a consulta: não execute-a imediatamente, adie a decisão, vá para o passo abaixo.

    • Não: vá para o passo abaixo.

  2. Existe alguma regra --replicate-*-table?

    • Não: execute a consulta e saia.

    • Sim: vá para o passo abaixo. Apenas tabela que serão atualizadas serão comparadas às regras (INSERT INTO sales SELECT * from prices: apenas sales será comparada às regras). Se várias tabelas forem ser atualizadas (instruções multi-tabelas) a primeira a corresponder a regra (com ``do'' ou ``ignore'') vence (isto é, a primeira tabela é comparada a regra. se nenhuma decisão pode ser tomada a segunda tabela é compara às regras, etc).

  3. Existe alguma regra --replicate-do-table?

    • Sim: o tabela encaixa em alguma delas?

      • Sim: execute a consulta e saia.

      • Não: vá para o passo abaixo.

    • Não: vá para o passo abaixo.

  4. Existe alguma regra --replicate-ignore-table?

    • Sim: a tabela encaixa em alguma delas?

      • Sim: ignore a consulta e saia.

      • Não: vá para o passo abaixo.

    • Não: vá para o passo abaixo.

  5. Existe alguma regra --replicate-wild-do-table?

    • Sim: a tabela se encaixa em qualquer uma delas?

      • Sim: execute a consulta e saia.

      • Não: vá para o passo abaixo.

    • Não: vá para o passo abaixo.

  6. Existe alguma regra --replicate-wild-ignore-table?

    • Sim: a tabela se encaixa em qualquer uma delas?

      • Sim: ignore a consulta e saia.

      • Não: vá para o passo abaixo.

    • Não: vá para o passo abaixo.

  7. Nenhuma regra --replicate-*-table foi correspondida. Existe outra tabela para se testar com estas regras?

    • Sim: loop.

    • Não: testamos todas as tabelas a serem atualizadas, nenhuma regra foi obedecida. Existem regras --replicate-do-table ou --replicate-wild-do-table?

      • Sim: ignore a consulta e saia.

      • Não: execute a consulta e saia.

4.11.7. Instruções SQL para Controle do Servidor Master

0 replicação pode ser controlada por meio da interface SQL. Esta seção discute instruções para gerenciamento dos servidores masters de replicação. Seção 4.11.8, “Instruções SQL para Controle do Servidor Slave” discute instruções para gerenciamento dos servidores slaves.

4.11.7.1. PURGE MASTER LOGS

PURGE {MASTER|BINARY} LOGS TO 'log_name'

PURGE {MASTER|BINARY} LOGS BEFORE 'date'

Deleta todos os logs binários que estão listados no índice de log anteriores ao log ou data especificado. O log também remove da lista gravada no índice de log, e assim o log dado se torna o primeiro.

Exemplo:

PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';

A variante BEFORE está disponível no MySQL 4.1; este argumento de data pode estar no formato 'YYYY-MM-DD hh:mm:ss'. MASTER e BINARY são sinônimos, embora BINARY possa ser usado apenas a partir do MySQL 4.1.1.

Se você tiver um slave ativo que está atualmente lendo um dos logs que você stá tentando deletar, este comando não faz nada e falha com um erro. No entanto, se você tiver um slave ativo e apagar um dos logs que ele quiser ler, o slave não poderá replicar uma vez que ele esteja ativo. O comando é seguro para de se executar enquanto os sslaves estiverem replicando. Você não precisa de pará-los.

Você deve primeiro verificar todos os slaves com SHOW SLAVE STATUS para ver qual log eles estão lendo, e então você deve fazer uma lista dos logs no master com SHOW MASTER LOGS, encontrar o log mais novo entre todos os slaves (se todos os slaves estão atualizados, ele será o último log da lista), tirar backup de todos os logs que você está prestes a deletar (opcional) e deletar até o log alvo.

4.11.7.2. RESET MASTER

RESET MASTER

Deleta todos os logs binários listado no arquivo de índice, zerando o arquivo de índice do log binário.

Esta instrução rea chamada FLUSH MASTER antes do MySQL 3.23.26.

4.11.7.3. SET SQL_LOG_BIN

SET SQL_LOG_BIN = {0|1}

Disabilita ou habilita o log binário para a conexão do usuário (SQL_LOG_BIN é uma variável de sessão) se o cliente conecta usando uma conta que tem o privilégio SUPER. A instrução é ignorada se o cliente não possui este privilégio.

4.11.7.4. SHOW BINLOG EVENTS

SHOW BINLOG EVENTS [ IN 'log_name' ] [ FROM pos ] [ LIMIT [offset,] row_count ]

Mostra o evento no log binário. Se você não especificar 'log_name', o primeiro log binário será exibido.

Esta instrução está disponível a partir do MySQL 4.0.

4.11.7.5. SHOW MASTER STATUS

SHOW MASTER STATUS

Fornece a informação de status no log binário do master.

4.11.7.6. SHOW MASTER LOGS

SHOW MASTER LOGS

Lista o log binário no master. Você deve usar este comando antes de PURGE MASTER LOGS para descobrir até onde você deve ir.

4.11.7.7. SHOW SLAVE HOSTS

SHOW SLAVE HOSTS

Mostra uma lista de slaves atualmente registrados com o master. Note que slaves não iniciados com a opção --report-host=slave_name não estarão visíveis nesta lista.

4.11.8. Instruções SQL para Controle do Servidor Slave

A replicação pode ser controlada por meio da interface SQL. Esta seção discute instruções para gerenciamento dos servidores slaves de replicação. Seção 4.11.7, “Instruções SQL para Controle do Servidor Master” discute instruções para gerenciamento dos servidores master.

4.11.8.1. CHANGE MASTER TO

CHANGE MASTER TO master_def [, master_def] ...

master_def =
      MASTER_HOST = 'host_name'
    | MASTER_USER = 'user_name'
    | MASTER_PASSWORD = 'password'
    | MASTER_PORT = port_num
    | MASTER_CONNECT_RETRY = count
    | MASTER_LOG_FILE = 'master_log_name'
    | MASTER_LOG_POS = master_log_pos
    | RELAY_LOG_FILE = 'relay_log_name'
    | RELAY_LOG_POS = relay_log_pos
    | MASTER_SSL = {0|1}
    | MASTER_SSL_CA = 'ca_file_name'
    | MASTER_SSL_CAPATH = 'ca_directory_name'
    | MASTER_SSL_CERT = 'cert_file_name'
    | MASTER_SSL_KEY = 'key_file_name'
    | MASTER_SSL_CIPHER = 'cipher_list'

Altera os parâmetros que o servidor slave usa para conectar e comunicar com o servidor master. Os valores possíveis para o valor master_def estão mostrados acima.

As opções do relay log (RELAY_LOG_FILE e RELAY_LOG_POS) estão disponíveis a partir do MySQL 4.0.

As opções SSL (MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY, e MASTER_SSL_CIPHER) estão disponíveis a partir do MySQL 4.1.1. Você pode alterar estas opções mesmo nos slaves que são compilados sem suporte a SSL. Eles serão salvos no arquivo master.info mas ignorados até que você use um servidor que tenha suporte a SSL habilitado.

Por exemplo:

mysql> CHANGE MASTER TO
    ->     MASTER_HOST='master2.mycompany.com',
    ->     MASTER_USER='replication',
    ->     MASTER_PASSWORD='bigs3cret',
    ->     MASTER_PORT=3306,
    ->     MASTER_LOG_FILE='master2-bin.001',
    ->     MASTER_LOG_POS=4,
    ->     MASTER_CONNECT_RETRY=10;
mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='slave-relay-bin.006',
    ->     RELAY_LOG_POS=4025;

MASTER_USER, MASTER_PASSWORD, MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY, and MASTER_SSL_CIPHER are information for the slave to be able to connect to its master. If you don't specify some of these informations, the non-specified informations will keep their old value. For example, if the password to connect to your MySQL master has changed, you just need to issue

mysql> STOP SLAVE; -- if replication was running
mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret';
mysql> START SLAVE; -- if you want to restart replication

to tell the slave about the new password; no need to specify the information which did not change (host, port, user etc).

MASTER_HOST, MASTER_PORT are the hostname or IP adress of the master host, and its TCP port. Note that if MASTER_HOST is equal to localhost, then, like in other parts of MySQL, the port may be ignored (if Unix sockets can be used for example).

Se você especificar MASTER_HOST ou MASTER_PORT, o slave assumirá que o mestre é diferente do anterior (mesmo se você especificar um valor de nost ou porta iguais ao do valor atual.) Neste caso Assim, os valores antigos do nome e posição do log binário do mestre não são mais aplicáveis, assim se você não especificar MASTER_LOG_FILE e MASTER_LOG_POS no comando, MASTER_LOG_FILE='' e MASTER_LOG_POS=4 são silenciosamente adicionados a ele.

MASTER_LOG_FILE e MASTER_LOG_POS são as coordenadas das quais a thread de E/S do slave começara a ler do master na próxima vez em que ele for iniciado. If you specify any of them, you can't specify RELAY_LOG_FILE or RELAY_LOG_POS. If none of MASTER_LOG_FILE and MASTER_LOG_POS was specified, then the last coordinates of the slave SQL thread before CHANGE MASTER was issued, are used. This ensures that replication has no discontinuity, even if the slave SQL thread was late compared to the slave I/O thread, when you just want to change, say, the password to use. This safe behaviour was introduced starting from MySQL 4.0.17 and 4.1.1. (Before these versions, the used coordinates were the last coordinates of the slave I/O thread before CHANGE MASTER was issued, which caused the SQL thread to sometimes lose some events from the master, thus breaking replication.)

CHANGE MASTER TO deleta todos os relay logs (e inicia um novo), a menos que você especifique RELAY_LOG_FILE ou RELAY_LOG_POS (neste caso os relay logs serão mantidos; desde o MySQL 4.1.1 a variável global RELAY_LOG_PURGE será definida com zero sem aviso prévio). CHANGE MASTER TO atualiza master.info e relay-log.info.

CHANGE MASTER é util para configurar um slave quando você tem a cópia do master e gravou o registro e offset no master que corresponde a cópia tirada. Você pode executar CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master', MASTER_LOG_POS=log_offset_on_master no slave depois de restaurar a cópia.

O primeiro exemplo acima (CHANGE MASTER TO MASTER_HOST='master2.mycompany.com' etc) altera as coordenadas do master e do seu log binário. Isto é quando você deseja que o slave replique o master. O segundo exemplo, usado com menos frequência, é quando o slave possui relay logs que, por alguma razão, você deseja que o slave execute novamente; para fazer isto o master não precisa estar alcançavel, você só precisa fazer CHANGE MASTER TO e iniciar a thread de SQL (START SLAVE SQL_THREAD). Você pode usar isto mesmo fora da consiguração de replicação, em um servidor standalone, slave-de-ninguém, para recuperação depois de uma falha.

Suponha que o seu servidor tenha falhado e você tenha restaurado um backup. Você deseja reexecutar o próprio log binário do servidor (não os relay logs, mas logs binários regulares), supostamente chamado myhost-bin.*. Primeiro faça uma cópia destes logs binários em alguns lugares seguros, no caso de você não seguir exatamente o procedimento abaixo e acidentalmente apagar os logs binários de servidor. Se você estiver usando o MySQL 4.1.1 ou mais novos, defina SET GLOBAL RELAY_LOG_PURGE=0 para segurança adicional. Então inicie o servidor sem log-bin, com um novo ID do servidor (diferente do anterior), com relay-log=myhost-bin (para fazer o servidor acreditar que estes logs binários regulares são relay logs) e skip-slave-start, então execute estas instruções:

mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='myhost-bin.153',
    ->     RELAY_LOG_POS=410,
    ->     MASTER_HOST='some_dummy_string';
mysql> START SLAVE SQL_THREAD;

Então o servidor irá ler e executar seus próprios logs binários, e assim conseguindo a recuperação de falhas. Uma vez que a recuperação está finalizada, execute STOP SLAVE, desligue o servidor, delete master.info e relay-log.info, e reinicie o servidor com suas opções originais. No momento, especificar MASTER_HOST (mesmo com um valor modelo) é compulsório para fazer o servidor pensar que ele é um slave, e dar ao servidor um novo ID, diferente do anterior é compulsório senão o servidor verá os eventos com seus IDs e pensará que ele está em uma configuração de replicação circular e ignora os eventos, o que é indesejado. No futuro planejamos adicionar opções para lidar com estas pequenas restrições.

4.11.8.2. LOAD DATA FROM MASTER

LOAD DATA FROM MASTER

Tira uma cópia do master para o slave. Atualiza os valores de MASTER_LOG_FILE e MASTER_LOG_POS assim o slave será iniciado replicando da posição correta. Respeitará a regras de exclusão de tabelas e bancos de dados especificadas com as opções replicate-*.

O uso desta instrução está sujeito ao seguinte:

  • Funciona apenas com tabelas MyISAM.

  • Ele adquire um lock de leitura global no master enquanto tira um instantâneo, que evita atualizações no master durante esta operação.

No futuro está planejado fazê-lo funcionar com tabelas InnoDB e remover a necessidade de lock deleitura global usando o recurso de backup online sem bloqueio.

Se você estiver carregando tabelas grandes, você pode aumentar os valores de net_read_timeout e net_write_timeout no mestre e no slave. Veja Seção 4.6.8.4, “SHOW VARIABLES.

Note que LOAD DATA FROM MASTER NÂO copia nenhuma tabela do banco de dados mysql. Isto é para tornar facil de se ter diferentes usuários e privilégios no master e no slave.

Esta instrução exige que o usuário de replicação usado para se conectar ao master tenha privilégios RELOAD e SUPER no master, privilégios SELECT em todas as tabelas do master que você queira carregar. Todas as tabelas do master nas quais os usuários não tenham privilégio SELETC serão ignoradas pelo LOAD DATA FROM MASTER; isto ocorre porque o master irá esconde-los do usuário: LOAD DATA FROM MASTER chama SHOW DATABASES para saber qual banco de dados do master carregar, mas SHOW DATABASES retorna apenas o banco de dados nos quais o usuário tem algum privilégio. Veja Seção 4.6.8.1, “Recuperando Informações sobre Bancos de Dados, Tabelas, Colunas e Índices”. No lado do slave, o usuário que executa LOAD DATA FROM MASTER deve ter permissão para apagar e criar o banco de dados e tabelas envolvidos.

4.11.8.3. LOAD TABLE tbl_name FROM MASTER

LOAD TABLE tbl_name FROM MASTER

Faz o download de uma cópia da tabela do master para o slave. Esta instrução é implementada principalmente para depuração de LOAD DATA FROM MASTER. Exige que o usuário de replicação que é usado para conectar ao master tenha privilégios RELOAD e SUPER no master, e SELECT na tabela do master que será carregada. No lado do slave, o usuário que envia LOAD TABLE FROM MASTER deve ter permissão para apagar e criar a tabela. Leia as anotações sobre tempo limite nadescrição de LOAD DATA FROM MASTER abaixo, elas se aplicam aqui também. Por favor, leia também as limitações de LOAD DATA FROM MASTER acima, elas também se aplicam (por exemplo, LOAD TABLE FROM MASTER só funciona com tabelas MyISAM).

4.11.8.4. MASTER_POS_WAIT()

SELECT MASTER_POS_WAIT('master_log_file', master_log_pos)

Esta é uma função, não um comando. É usada para assegurar que o slave tenha alcançado (lido e executado) uma dada posição no log binário do master. Veja Seção 6.3.6.2, “Funções Diversas” para uma descrição completa.

4.11.8.5. RESET SLAVE

RESET SLAVE

Faz o slave esquecer a sua posição de replicação no log binário do master. Esta instrução é usada para uma inicialização limpa: ela deleta os arquivos master.info e relay-log.info, todos os relay logs e inicia um novo relay log. Nota: Todos os relay logs são deletados, mesmo se não forem totalmente executados pela threads SQL do slave. (Esta é uma condição que deveria existir em um slave de replicação altamente carregado, ou se você enviasse uma instrução STOP SLAVE.) As informações de conexão armazenadas no arquivo master.info são imediatamente recarregadas com os valores especificados nas opções de inicializacão, se forem especificadas. Estas informações incluem valores como máquina master, porta do master, usuário do master e senha do master. Se a thread SQL do slave estava no meio de uma replicação de tabelas temposrárias quando ela foi parada, e RESET SLAVE é excutado, estas tabelas temporárias replicadas são deletadas no slave.

Esta instrução era chamada FLUSH SLAVE antes do MySQL 3.23.26.

4.11.8.6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n

Salta os próximos n eventos do master. Útil para recuperação de paradas da replicação causada por um erro.

Esta instrução só é válida quando a thread slave não está em execução, em caso contrário, retorna um erro.

Antes do MySQL 4.0, omite a palavra chave GLOBAL da instrução.

4.11.8.7. SHOW SLAVE STATUS

SHOW SLAVE STATUS

Fornece a informação de status nos parâmetros essenciais da thread do slave. Se você utilizar esta instrução usando no cliente mysql, você pode usar o terminador \G em vez de um ponto e vírgula no fim, para conseguir um layout vertical mais legível:

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
       Slave_IO_State: Waiting for master to send event
          Master_Host: localhost
          Master_User: root
          Master_Port: 3306
        Connect_Retry: 3
      Master_Log_File: gbichot-bin.005
  Read_Master_Log_Pos: 79
       Relay_Log_File: gbichot-relay-bin.005
        Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
     Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
      Replicate_Do_DB:
  Replicate_Ignore_DB:
           Last_Errno: 0
           Last_Error:
         Skip_Counter: 0
  Exec_Master_Log_Pos: 79
      Relay_Log_Space: 552
      Until_Condition: None
       Until_Log_File:
       Until_Log_Pos: 0
   Master_SSL_Allowed: No
   Master_SSL_CA_File:
   Master_SSL_CA_Path:
      Master_SSL_Cert:
    Master_SSL_Cipher:
       Master_SSL_Key:
Seconds_Behind_Master: 8

Dependendp da sua versão do MySQL, você pode não ver todos os campos como aqui mostrado. Alguns campos estão presentes apenas a partir do MySQL 4.1.1.

Os campos mostrados por SHOW SLAVE STATUS tem o seguinte significado:

  • Slave_IO_State

    Uma cópia da coluna State da saída de SHOW PROCESSLIST para a thread de E/S do slave; lhe dirá se está thread está tentando se conectar ao master, esperando por eventos do master, reconectando ao master, etc. Os estados possíveis estão listados em Seção 4.11.2, “Visão Geral da Implementação da Replicação”. Olhar está coluna é necessário porque, por exemplo, a thread pode estar em execução mas não tem sucesso ao tentar se conectar ao master: apenas esta coluna lhe deixará ciente do problema de conexão. Por outro lado, o estado da thread SQL não é copiada, porque as coisas são mais simples para esta thread: se ela estiver em execução, não haverá problema; se não, você encontrará o erro na coluna Last_Error (descrita abaixo).

    Este campo está presente a partir do MySQL 4.1.1.

  • Master_Host

    A máquina master atual.

  • Master_User

    O usuário usado para conectar ao master.

  • Master_Port

    A porta atual do master.

  • Connect_Retry

    O valor atual de master-connect-retry.

  • Master_Log_File

    O nome do arquivo de log binário do master no qual a thread de E/S está lendo atualmente.

  • Read_Master_Log_Pos

    A posição até a qual a thread de E/S leu no log binário do master.

  • Relay_Log_File

    O nome do arquivo de relay log na qual a thread SQL está lendo e executando atualmente.

  • Relay_Log_Pos

    A posição até a qual a thread de SQL leu e executou neste relay log.

  • Relay_Master_Log_File

    O nome do arquivo de log binário do master no qual contém o último evento executado pela thread de SQL.

  • Slave_IO_Running

    Diz se a thread de E/S foi iniciada ou não.

  • Slave_SQL_Running

    Diz se a thread de SQL está iniciada ou não.

  • Replicate_Do_DB, Replicate_Ignore_DB

    A lista de banco de dados que foi especificado com as opções --replicate-do-db e --replicate-ignore-db.

  • Replicate_Do_Table, Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table

    As tabelas que foram especificadas com as opções --replicate-do-table, --replicate-ignore-table, --replicate-wild-do-table, e --replicate-wild-ignore_table.

    Estes campos estão presentes a partir do MySQL 4.1.1.

  • Last_Errno

    O número de erro retornado pela consulta executada mais recentemente. Um valor 0 significa ``sem erro''.

  • Last_Error

    A mensagem de erro retonada pela consulta executada mais recentemente. Por exemplo:

    Last_Errno: 1051
    Last_Error: error 'Unknown table 'z'' on query 'drop table z'
    

    A mensagem indica que a tabela z existia no mestre e foi apagada lá, mas ela não existe no slave, assim DROP TABLE falhou no servidor. (Isto pode ocorrer se o usuário esqueceu de copiá-la no slave ao configurá-lo).

    A string vazia significa ``sem erro''. Se o valor Last_Error não for vazio, ele também apareceria como uma mensagem no log de erro do slave. Por exemplo:

  • Skip_Counter

    O último valor usado por SQL_SLAVE_SKIP_COUNTER.

  • Exec_Master_Log_Pos

    A posição no log binário do master (Relay_Master_Log_File) do último evento executado pela thread de SQL. ((Relay_Master_Log_File,Exec_Master_Log_Pos) no log binário do master corresponde a (Relay_Log_File, Relay_Log_Pos) no relay log).

  • Relay_Log_Space

    O tamanho total de todos os relay logs existentes.

  • Until_Condition, Until_Log_File, Until_Log_pos

    O valor especificado na cláusula UNTIL da instrução START SLAVE.

    Until_Condition possui estes valores estes valorer:

    • None se nenhuma cláusula UNTIL foi especificada

    • Master se o slave estiver lendo até uma dada posição no log binário do master.

    • Relay se o slave estiver lendo até uma dada posição em seus relay logs

    Until_Log_File e Until_Log_Pos indicam o nome do arquivo de log e e posição que define o ponto no qual a thread SQL irá parar a execução.

    Estes campos estão presentes a partir do MySQL 4.1.1.

  • Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher, Master_SSL_Key

    Estes campos mostram os parâmetros SSL usado pelo slave para se conectar os master, se existirem.

    Master_SSL_Allowed possui estes valores:

    • Yes se uma conexão SSL ao master é permitida

    • No se uma conexão SSL ao master não é permitida

    • Ignored se uma conexão SSL permitida pelo servidor slave não tem suporte a SSL habilitado.

    Os valores dos outros campos correspodem ao valor das opções --master-ca, --master-capath, --master-cert, --master-cipher, e --master-key.

    Estes campos estão presentes a partir do MySQL 4.1.1.

  • Seconds_Behind_Master

    O número de segundos passados desde o último evento do master executado pela thread salve SQL. Será NULL quando nenhum evento foi executado ainda, ou depois de CHANGE MASTER e RESET SLAVE. Esta coluna pode ser usada para saber "quão atrasado está o seu slave". Funcionará mesmo se o seu master e slave não tiverem clocks idênticos.

    Estes campos estão presentes a partir do MySQL 4.1.1.

4.11.8.8. START SLAVE

START SLAVE [thread_name [, thread_name] ... ]
START SLAVE [SQL_THREAD] UNTIL
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
START SLAVE [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos

thread_name = IO_THREAD | SQL_THREAD

START SLAVE sem nenhuma opção inicia ambas as threads slaves. A thread de E/S lêem as consultas do servidor master e as armazena no relay logs. A thread de SQL le o relay log e executa a consulta. Note que se START SLAVE obter sucesso no inicialização da thread slave ela retornará sem qualquer erro. Mas mesmo neste caso pode ser que a thread slave iniciou e parou mais tarde (por que elas não conseguiram se conectar ao master ou leram o seu log binário ou qualquer outro problema). START SLAVE não lhe avisará sobre insto. Você deverá verifica seu arquivo log de erro do slave por mensagens de erro gerada pela thread slave, ou verificar que eles estão rodando bem com SHOW SLAVE STATUS.

A partir do MySQL 4.0.2, você pode adicionar as opções IO_THREAD ou SQL_THREAD à instrução a ser chamada quando a thread iniciar.

A partir do MySQL 4.1.1, uma cáusula UNTIL pode ser adicionada para especificar que o slave deve iniciar até que a thread de SQL alcance um determinado ponto no log binário dp master ou no relay log do slave. Quando a thread SQL alcança este ponto, ela para. Se a opção SQL_THREAD é especificada na instrução, ela inicia apenas a thread de SQL. Senão, ela inicia ambas as threads slaves. Se a thread SQL já estiver em execução, a claúsula UNTIL é ignorada e um aviso é enviado.

Com uma cláusula UNTIL, você deve especificar tanto uma nome de arquivo de log quanto uma posição. Não misture opções do master e do relay logs.

Qualquer condição UNTIL é restaurada por uma instrução STOP SLAVE subsequente, ou uma instrução START SLAVE que não incluir a cláusula UNTIL, ou um servidor reinicie.

A cláusula UNTIL pode ser útil para depurar a replicação, ou para fazer com que a replicação proceda até um pouco antes do ponto que você deseja evitar que o slave replique uma instrução. Por exemplo, se uma instrução DROP TABLE foi executada no master, você pode usar UNTIL para dizer ao slave para executar até aquele ponto, mas não depois. Para encontrar qual é o evento, use mysqlbinlog com o log do master ou o relay logs, ou usando uma instrução SHOW BINLOG EVENTS.

Se você estiver usando UNTIL para ter o processo slave replicando consultas nas seções, é recomendado que você inicie o slave com a opção --skip-slave-start para evitar que a thread de SQL execute quando o slave iniciar. É provavelmente melhor usar esta opção em um arquivo de opção em vez de usá-la na linha de comando, assim uma reinicialização inesperada do servidor não faz com que isso seja esquecido.

A instrução SHOW SLAVE STATUS inclui campos na saída que mostram o valor atual da condição UNTIL.

Este comando é chamado SLAVE START antes do MySQL 4.0.5. No momento, SLAVE START ainda é aceito para compatibilidade com versões anteriores, mas está obsoleto.

4.11.8.9. STOP SLAVE

STOP SLAVE [thread_name [, thread_name] ... ]

thread_name = IO_THREAD | SQL_THREAD

Para a thread slave. Como o START SLAVE, esta instrução pode ser usada com as opções IO_THREAD e SQL_THREAD para chamar a thread ou threads que irão parar.

Este comando é chamado SLAVE STOP antes do MySQL 4.0.5. No momento, SLAVE STOP ainda é aceito para compatibilidade com versões anteriores, mas está obsoleto.

4.11.9. FAQ da Replicação

P: Como eu configuro um slave se o master já estiver em execução e eu não quiser pará-lo?

R: Existem diversas opções. Se você tirou um backup do master em alguns pontos e gravou o nome e offset do log binário (da saída do SHOW MASTER STATUS) correspondente à cópia, faça o seguinte:

  1. Esteja certo de que o slave possuí um ID server único.

  2. Execute as seguintes instruções no slave, preenchendo os valores apropriados para cada parâmetro:

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='master_host-name',
        ->     MASTER_USER='master_user_name',
        ->     MASTER_PASSWORD='master_pass',
        ->     MASTER_LOG_FILE='recorded_log_name',
        ->     MASTER_LOG_POS=recorded_log_pos;
    
  3. Execute START SLAVE no slave.

Se você já não tiver um backup do master, aqui está um modo rápido de fazê-lo de forma consistente:

  1. FLUSH TABLES WITH READ LOCK

  2. gtar zcf /tmp/backup.tar.gz /var/lib/mysql ( ou uma variação disto)

  3. SHOW MASTER STATUS - esteja certo de gravar a saída - você precisará dela mais tarde

  4. UNLOCK TABLES

Uma alternativa é tirar um dump do SQL do master em vez de uma cópia binária como acima; para isto você podee usar mysqldump --master-data em seu master e posteriormente executar este dump SQL em seu slave. Isto é, no entanto, mais lento que fazer uma cópia binária.

Não importa qual dos dois métodos você usa, mais tarde siga as instruções para o caso em que você tem uma cópia e gravou o nome e offset dos logs Você pode usar a mesma cópia para configurar diversos slaves. Uma vez que os logs binários do master estão intáctos, você pode esperar por dias ou meses para configurar um slave uma vez que você possui a cópia do master. Em teoria a lacuna de espera pode ser infinita. As duas limitações práticas é o espaço em disco do master sendo preenchido com logs antigos e a quantidade de tempo que o slave gastará para buscá-los.

Você também pode usar LOAD DATA FROM MASTER. Este é um comando conveniente que tira uma cópia, a restaurá no slave e ajustar o nome e offset do log no slave, todos de uma vez. No futuro, LOAD DATA FROM MASTER será o modo recomendado de configurar um slave. Esteja avisado, no entanto, que o lock de leitura pode ser mantido por um longo tempo se você usar este comando. Ele ainda não está implementado de forma tão eficiente quanto gostariamos. Se você tiver tabelas grandes, o método preferível neste momento ainda é com uma cópia tar local depois de executar FLUSH TABLES WITH READ LOCK.

P: O slave precisa estar conectado ao master o tempo todo?

R: Não, ele não precisa. O slave pode ser desligado ou permanecer desconectado por horas ou mesmo dias, então reconecta e busca as atualizações. Por exemplo, você pode usar uma relação master/slave sobre uma conexão dial-up que está ligada esporádicamente apenas por um curto período de tempo. A implicação disto é que a uma hora dada qualquer não temos garantias de que o slave está sincronizado com o master a menos que você tire algumas medidas especiais. No futuro, teremos a opção de bloquear o master até que pelo menos um slave esteja sincronizado.

P: Como posso saber se um slave está atrasado comparado ao master? Em outra palavras, como eu sei que o dado da última consulta replicada pelo escravo?

R: Se o slave for 4.1.1 ou mais novo, leia a coluna Seconds_Behind_Master de SHOW SLAVE STATUS. Para versão mais antigas o seguinte se aplica. Isto só é possível se a thread salve de SQL existir (p.ex. se ele for exibida em SHOW PROCESSLIST, Veja mais informações sobre isto na Seção 4.11.3, “Detalhes de Implementação da Replicação”) (no MySQL 3.23: se a thread slave existir, p.ex. e mostrada em SHOW PROCESSLIST), e se ela executou pelo menos um evento do master. Realmente, quando a thread slave de SQL executa um evento lido do master, esta thread modifica seu próprio tempo do timestamp do evento (é por isto que TIMESTAMP é bem replicado). Assim é indicado na coluna Time na saída de SHOW PROCESSLIST, o número de segundos entre o timestamp do último evento replicado e o tempo real da máquina slave. Vopcê podee usar isto para determinar a data do último evento replicado. Note que se o seu slave foi desconectado do master por uma hora e então reconectado, você poderá ver uma vlaor de 3600 na coluna Time para a thread slave de SQL em SHOW PROCESSLIST... Isto ocorreria porque o slave está executando consultas de uma hora atrás.

P: Como eu forço o master a bloquear as atualizações até que o slave as busque?

R: Use o seguinte procedimento:

  1. No master, execute estes comandos:

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    Grave o nome do log e o offset da saída da instução SHOW.

  2. No slave, execute este comando, onde as coordenadas da replicação que são os argumentos da função MASTER_POS_WAIT() são os valores gravados nos passos anteriores:

    mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
    

    A instrução SELECT será bloqueada até que o slave alcance o arquivo de log e offset especificados. Neste ponto, o slave estará em sincronia com o master e a instrução irá retornar.

  3. No master, execute a seguinte instrução para permitir que o master comece a processar atualizações novamente:

    mysql> UNLOCK TABLES;
    

P: Sobre quais assuntos eu devo estar ciente ao configurar uma replicação de duas vias?

R: Atualmente a replicação do MySQL não suporta nenhum protocolo de locking entre master e slave para garantir a atomicidade de uma atualização distribuída (entre servidores). Em outras palavras, é possível para um cliente A fazer uma atualização para um co-master 1, e neste tempo, antes de propagar para o co-master 2, o cliente B pode fazer uma atualização para o co-master 2 que fará a atualização do cliente A funcionar diferentemente da que ele fez no co-master 1. Assim, quando a atualização do cliente A fizer a atualização para o co-master, ele produzirá tabelas que são diferentes daquelas que você tem no co-master 1, mesmo depois de todas as atualizações do co-master2 também terem sido propagadas. Por isso você não deve co-encadear dois servidores em uma replicação de duas vias, a menos que você possa assegurar que suas atualizações possem seguramente ocorrer em qualquer ordem, ou que de alguma forma você cuide de alguma forma a atualização fora de ordem no código do cliente.

Você também deve perceber que replicação de duas vias não melhorar em muito o desempenho, já que temos atualizações envolvidas. Ambos os servidores precisam fazer a mesma quantidade de atualizações cada, como se tivesse um servidor. A única diferença é que haverá uma pouco menos de contenção de lock, porque as atualizações originando em outro servidor serão serializadas em uma thread slave. mesmo assim, este benefício pode ser por atrasos de rede.

P: Como eu posso usar replicação para melhorar a performance do meu sistema?

R: Você devev configurar um servidor como master e direcionar todas as escritas para ele. Então configure tantos slaves quantos você pode comprar e instalar, e distribua as leituras entre o master e os slaves. Você também pode iniciar os slaves com --skip-bdb, --low-priority-updates e --delay-key-write=ALL para conseguir aumento de velocidade para o slave. Neste caso o slave usará tabelas MyISAM não transacionais em vez de tabelas BDB para conseguir mais velocidade.

Q: O que eu devo fazer para preparar o código do cliente em minhas próprias aplicações para usar replicação para melhora de performance?

A: Se a parte do seu código que for responsável pela acesso ao banco de dados tiver sido abstaído/modularizado apropriadamente, converte-lo para executar com uma configuração de replicação deve ser bem fácil. Apenas altere a implementação de seu acesso a banco de dados para enviar todas as escritas para o master e todas as leituras para o master e o slave. Se o seu código não tiver este nível de abstração, configurar um sistema de replicação lhe dará a oportunidade e motivação de limpá-lo. Você deve iniciar criando uma biblioteca ou módulo wrapper com as seguites funções:

  • safe_writer_connect()

  • safe_reader_connect()

  • safe_reader_query()

  • safe_writer_query()

safe_ no nome de cada função significa que a função cuidará do tratamento de todas as condições de erro.

Você pode, é claro, usar diferentes nomes para as funções. O importante é ter uma interface unificada para conexão para leitura, conexão para escrita, fazer uma leitura e fazer uma escrita.

Você deve então converter o código do seu cliente para usar a biblioteca wrapper. Este pode ser um processo doloroso e assustador a princípio, mas será gratificante a longo prazo. Todas as aplicações que usam a abordagem descrita poderão tirar vantagem de uma configuração master/slave, mesmo envolvendo vários slaves. O código será muito mais fácil de manter, e adicionar opções para soluções de problemas será trivial. Você só precisará modificar uma ou duas funções, por exemplo, para registrar quanto tempo uma consulta gastou ou qual consulta, entre todas elas, retornou um erro.

Se você já tiver escrito muito código, você pode querer automatizar a conversão de tarefas usando o utilitário replace, que vem com a distribuição padrão do MySQL, ou simplesmente escrever seu próprio script Perl. Provavelmente, o seu código segue algum padrão de reconhecimento. Se não, então talvez sejá melhor reescrevê-lo ou pelo menos colocá-lo dentro de um padrão.

Q: Quando e em quanto a replicação do MySQL pode aumentar a performance do meu sistema?

A: A replicação do MySQL é mais benéfica para um sistema com leituras frequentes e escritas infrequentes. Em teoria, usando uma configuração um mastre/vários slaves você pode escalar o sistema adicionando mais slaves até que você fique sem largura de banda na rede, ou a sua carga de atualizações cresça ao ponto que o master não possa tratá-la.

Para determinar quantos slaves você pode ter antes dos benefícios adicionados começarem a estabilzar e quanto você pode melhorar o desempenho do seu site, você precisa saber o padrão de suas consultas e determinar empiricamente (pelo benchmark) a ralação entre a taxa nas leituras (leituras por segundo, ou max_reads) e nas escritas (max_writes) em um master e um slave comum. O exemplo aqui lhe mostrará um calculo simplificado do que você pode obter com replicação para o nosso sistema hipotético.

Vamos dizer que o sistema de cargas consiste de 10% de escrita e 90% de leitura, e determinamos max_reads para ser 1200 - 2 * max_writes. Em outras palavras, nosso sistema pode fazer 1200 leituras por segundo sem nenhuma escrita, a escrita média é duas vezes mais lenta que a leitura média e a realação é linear. Vamos supor que o master e cada slave possuem a mesma capacidade, e temos 1 master e N slaves. Então temos para cada servidor (master ou slave):

leituras = 1200 - 2 * escritas (a partir do benchmark)

leituras = 9* escritas / (N + 1) (as leituras são separadas, mas a escrita deve ir para todos os servidores)

9*escritas/(N+1) + 2 * escritas = 1200

escritas = 1200/(2 + 9/(N+1)

Esta análise leva as seguintes conclusões:

  • Se N = 0 (que significa que não temos replicação) nosso sistema pode tratar 1200/11, cerca de 109, escritas por segundos (o que significa que teremos 9 vezes mais leituras devidos a natureza de nossa aplicação)

  • Se N = 1, podemos aumentar para 184 escritas por segundos.

  • Se N = 8, conseguimos 400.

  • Se N = 17, 480 escritas.

  • Eventualmente, a medida que N se aproxima de infinito (e seu orçamento de menos infinito), podemos chegar próximo a 600 escritas por segundo, aumentando o throughput do sistema em cerca de 5,5 vezes. No entanto, com apenas 8 servidores, já o aumentamos em quase 4 vezes.

Note que nossos calculos assumem uma largura de banda de rede infinita, e negligencia vários outros fatores que podiam se tornar significante em seu sistema. Em muitos casos, você pode não conseguir fazer um cálculo similar ao acima que irá predizer exatamente o que acontecerá em seus sistema se você adicionar N slaves de replicação. No entanto, responder as seguintes questões deve ajudá-lo a decidir quando e quanto a replicação aumentará a performance do seu sistema:

  • Qual a razão da leitura/escrita no seu sistema?

  • Quanto mais de carga de escrita um servidor pode tratar se você reduzir a leitura?

  • Para quantos slaves você tem largura de banda disponíovel em sua rede?

P: Como eu posso usar replicação para fornecer redundância/alta disponibilidade?

R: Com os recursos disponíveis atualmente, você teria que configurar um master e um slave (ou diversos slaves) e escrever um script que monitoraria o master para ver se ele está no ar e instruir as suas aplicações e os slaves do master a alterar no caso de falha. Sugestões:

  • Para dizer para um slave para alterar o master, use o comando CHANGE MASTER TO.

  • Um bom modo de manter sua aplicação informadas sobre a localização do master é tendo uma entrada DNS dinâmica para o master. Com bind você pode usar nsupdate para atualizar dinamicamente o seu DNS.

  • Você deve executar seus escravos com a opção --log-bin e sem --log-slave-updates. Deste modo o slave estará pronto para se tornar um master assim que você executar STOP SLAVE; RESET MASTER, e CHANGE MASTER TO em outros slaves.

    Por exemplo, considere que voceê tenha a seguinte configuração (``M'' representa o master, ``S'' o slave, ``WC'' o cliente que faz a leitura e escrita do banco de dados; clientes que fazem apenas a leitura do banco de dados bão são representadas já que elas não precisam trocar):

           WC
            \
             v
     WC----> M
           / | \
          /  |  \
         v   v   v
        S1   S2  S3
    

    S1 (como S2 e S3) é um slave executando com --log-bin e sem --log-slave-updates. Como as únicas escritas executada em S1 são aquelas replicadas de M, o log binário em S1 é empty (lembre-se, que S1 é executado sem --log-slave-updates). Então, por alguma razão, M se torna indisponível, e você quer que o S1 se torne o novo master (isto é, direciona todos os WC para S1 e faça S2 e S3 replicar em S1).

    Certifique-se que todos os slaves processaram aqulquer consulta em seus relay log. Em cada slave, execute STOP SLAVE IO_THREAD, então verifique a saída de SHOW PROCESSLIST até você ver Has read all relay log. Quando isto ocorrer para todos os slaves, eles podem ser reconfigurados para a nova configuração. Envie STOP SLAVE para todos os slaves, RESET MASTER no slave sendo promovido para master, e CHANGE MASTER nos outros slaves.

    Nenhum WC acessa M. Instru todos os WCs a direcionar as suas consultas para S1. De agora em diante, todas as consultas enviadas por WC para S1 são escritas no log binário de S1. O log binário de S1 contém exatamente todas as consultas de escrita enviada para S1 desde que M foi finalizado. Em S2 (e S3) faça STOP SLAVE, CHANGE MASTER TO MASTER_HOST='S1' (onde 'S1' é substituido pelo nome de máquina real de S1). Para CHANGE MASTER, adicione todas as informações sobre como conectar a S1 de S2 ou S3 (usuário, senha, porta). Em CHANGE MASTER, não é necessário especificar o nome do log binário de S1 ou a sua posição: nós sabemos que ele é o primeiro log binário, na posição 4, e estes são os padrões de CHANGE MASTER. Finalmente faça START SLAVE em S2 e S3, e agora você terá isto:

           WC
          /
          |
     WC   |  M(indisponível)
      \   |
       \  |
        v v
         S1<--S2  S3
          ^       |
          +-------+
    

    Quando M estiver ativo novamente, você só precisa enviar a ele o mesmo CHANGE MASTER enviado a S2 e S3, assim que M se tornar um slave de S1 e pegar tudo que WC gravou enquando ele estava desativado. Agora para tornarmos M como master novamente (por exemplo, porque ela é a melhor máquina), siga os procedimentos como se S1 estivesse indisponível e M fosse o novo master; então durante o procedimento não esqueça d executar RESET MASTER em M antes de tornar S1, S2, S3 como slaves de M ou eles podem buscar escritas antigas de WC, antes da indisponibilidade de M.

Atualmente estamos trabalhando na integração de um sistema de eleição de master autmotico dentro do MySQL, mas até que ele esteja pronto, você terá que criar suas próprias ferramentas de monitoramento.

4.11.10. Problemas com Replicação

Se você tiver seguido as instruções e suia configuração de replicação não está funcionando, primeiro verifique o seguinte:

  • Verifique as mensagens no log de erros. Muitos usuários perderam tempo por não fazer isto cedo o suficiente.

  • O master está logando ao log binário? Verifique com SHOW MASTER STATUS. Se estiver, Position será diferente de zero. Se não, verifique que deu a opção log-bin do master e definiu o server-id.

  • O slave está executando? Faça SHOW SLAVE STATUS e verifique se os valores Slave_IO_Running e Slave_SQL_Running são ambos Yes. Se não, verifique a opção do slave.

  • Se o slave estiver rodando, ele estabeleceu uma conexão com o master? Faça SHOW PROCESSLIST, encontre as threads de E/S e SQL (see Seção 4.11.3, “Detalhes de Implementação da Replicação” para ver como é exibido), e verifique a sua coluna State. Se ela disser Connecting to master, verifique os privilégios do usuário de replicação no master, nome de máquina do master, sua configuração de DNS, se o master está atualmente em execução e se ele está a alcance do slave.

  • Se o slave estava em execução antes mas agora parou, a razão é que normalmente algumas consultas que obtem sucesso no master falham no slave. Into nunca deve acontecer se você tiver tirado a cópia apropriada do master e nunca modificou os dados no slave fora da thread slave. Se isto ocorrer, você encontrou um erro; leia abaixo como relatá-lo.

  • Se uma consulta bem sucedida no master se recusou a executar no slave, e não parece prático fazer um nova sincronização completa do banco de dados (p.ex.: deletar o banco de dados slave e fazer uma nova cópia do master), tente o seguinte:

    • Primeiro veja se a tabela do slave estava diferente da do master. Entenda como isto aconteceu (pode ser um erro: leia o registro de alterações no manual online do MySQL como http://www.mysql.com/documentation para verificar se este é um erro conhecido e se ele já está corrigido). Então faça a tabela do slave idêntica a do master e execute START SLAVE.

    • Se o acima não funcionar ou não se aplica, tente entender se ele estaria seguro para fazer uma atualização manualmente (se necessário) e então ignorar a próxima consulta do master.

    • Se você decidiu que você pode saltar a próxima consulta, execute as seguintes instruções:

      mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
      mysql> START SLAVE;
      

      O valor de n deve ser 1 se a consulta não usa AUTO_INCREMENT ou LAST_INSERT_ID(). Senão, o valor de ser 2. A razão para usarem um valor de 2 para consultas que usam AUTO_INCREMENT ou LAST_INSERT_ID() é que elas gastam dois eventos no log binário do master.

    • Tenha certeza de que você não está tendo problemas com um erro antigo atualizando para a versão mais recente.

    • Se você tem certeza que o slave iniciou perfeitamente em sincronia com o master, e que as tabelas envolvidas não foram atualizadas fora da thread slave, relate o erro.

4.11.11. Relatando Problemas de Replicação

Quando você tiver determinado que não há erro de usuário envolvido, e a replicação ainda não funciona perfeitamente ou está instável, é hora de começar a fazer num relatório de erros. Nós precisamos do máximo de informações que você puder fornecer para conseguirmos rastrear o bug. Por favor gaste algum tempo e esforço preparando um bom relato de erro.

Se você tiver uma forma repetitível de demonstrar o problema, por favor inclua-o em nosso banco de dados de bugs http://bugs.mysql.com. Se você tem um problema de fantasma (um problema que não pode ser duplicado a sua vontade), use o seguinte procedimento:

  1. Verifique se nenhum erro de usuário está envolvido. Por exemplo, se você atualiza o slave fora da thread slave, os dados podem ficar fora de sincronia e podem ocorrer violações de chave única nas atualizações. Neste caso a thread slave irá terminar e esperar que você limpe as tabelas manualmente para entrar em sincronia. Este não é um problema de replicação; é um problema de interferência externa que faz com que a replicação falhe.

  2. Execute o slave com as opções log-slave-updates e log-bin. Elas farão com que o registre todas as atualizações que ele receber no seu próprio log binário.

  3. Salve todas as evidências antes de restaurar o estado da replicação. Se não tivermos nenhuma informação ou apenas algum esboço, será um pouco mais difícil para rastrearmos o problema. As evidências que você deve coletar são:

    • Todos os logs binários no master

    • Todos os logs binários no slave

    • A saída de SHOW MASTER STATUS no master na hora que você descobriu o problema.

    • A saída de SHOW SLAVE STATUS no master na hora que você descobriu o problema.

    • Logs de erro no master e no slave

  4. Utilize mysqlbinlog para examinar os logs binários. A informação a seguir pode ser útil para encontrar a consulta problemática, por exemplo:

    mysqlbinlog -j pos_from_slave_status /caminho/para/log_do_slave | head
    

Uma vez que você coletou as evidências do problema fantasma, tente isolá-lo em um caso de testes separados inicialmente. Então relate o problema para http://bugs.mysql.com/ com a maior quantidade possíveis de informações.


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.