Manual Pt

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 868 [warning: Documents this large are best viewed by clicking the View PDF Link!]

s-ti-cas vi-zu-a-li-za-dos
Manual de Referˆencia do MySQL
Copyright c
1997-2001 MySQL AB
i
Table of Contents
Chapter 1: Informa¸oes gerais sobre o MySQL 1
1 Informa¸oes gerais sobre o MySQL
Este ´e o manual de referˆencia do MySQL para a vers˜ao 3.23.52. Como o desenvolvimento do
MySQL est´a em andamento, este manual ´e atualizado constantemente. Existe uma grande
chance desta vers˜ao n˜ao estar atualizada, a menos que vocˆe a esteja lendo online. A vers˜ao
mais recente deste manual est´a dispon´
ivel em http://www.mysql.com/documentation/ em
arios formatos diferentes. Se vocˆe est´a tendo dificuldades para encontrar as informa¸oes no
manual, tente a vers˜ao online em http://www.mysql.com/documentation/manual.php.
MySQL ´e um servidor robusto de bancos de dados SQL (Structured Query Language -
Linguagem Estruturada para Pesquisas) muito r´apido, multi-tarefa e multi-usu´ario.
MySQL ´e um software livre. Licenciado sob a GNU GENERAL PUBLIC LICENSE
http://www.gnu.org/. See hundefinedi[Licensing and Support], page hundefinedi.
Ahome page do MySQL fornece as ´ultimas informa¸oes sobre o MySQL.
A seguinte lista descreve algumas se¸oes ´uteis do manual:
Para informa¸oes sobre a empresa por tr´as do MySQL, veja hundefinedi[What is
MySQL AB], page hundefinedi.
Para discuss˜oes das capacidades do MySQL, veja hundefinedi[Features], page hunde-
finedi.
Para instru¸oes de instala¸ao, veja hundefinedi[Installing], page hundefinedi.
Para dicas sobre a portabilidade do MySQL para novas arquiteturas ou sistemas op-
eracionais, veja hundefinedi[Porting], page hundefinedi.
Para informa¸oes sobre a atualizacao da vers˜ao 3.22, veja hundefinedi[Upgrading-from-
3.22], page hundefinedi.
Para um tutorial de introdu¸ao ao MySQL, veja hundefinedi[Tutorial], page hunde-
finedi.
Para exemplos de SQL e informa¸oes sobre avalia¸oes de desempenho, veja o diret´orio
de benchmarks (‘sql-bench’ na distribui¸ao).
Para o hist´orico de novos recursos e corre¸oes de erros, veja hundefinedi[News],
page hundefinedi.
Para uma lista de erros atualmente conhecidos ou mal-funcionamento, veja hundefinedi
[Bugs], page hundefinedi.
Para projetos futuros, veja hundefinedi[TODO], page hundefinedi.
Para ver a lista de todos os colaboradores para este projeto, veja hundefinedi[Credits],
page hundefinedi.
IMPORTANTE:
Relat´orios de erros (tamb´em chamados bugs), bem como quest˜oes e comenarios, devem
ser enviados para a lista de discuss˜ao em mysql@lists.mysql.com. See hundefinedi[Bug
reports], page hundefinedi. O script mysqlbug deve ser usado para gerar comunicados de
erros.
Em distribui¸oes fonte, o script mysqlbug pode ser encontrado no diret´orio ‘scripts’. Para
distribui¸oes bin´arias, o mysqlbug pode ser encontrado no diret´orio ‘bin’. Se vocˆe encontrou
um erro de seguran¸ca no MySQL, vocˆe deve enviar um email para security@mysql.com.
2 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe tem alguma sugest˜ao relacionada a acr´escimos ou corre¸oes neste manual, por favor,
envie-a para a equiope do manual em docs@mysql.com.
Este ´e o manual de referˆencia; ele n˜ao fornece instru¸oes gerais sobre SQL ou conceitos de
bancos de dados relacionais. Se vocˆe deseja informa¸oes gerais sobre SQL, veja hundefinedi
[General-SQL], page hundefinedi. Para livros que focam mais especificamente em MySQL,
veja hundefinedi[MySQL-Books], page hundefinedi.
1.1 MySQL, MySQL AB e Open Source
1.1.1 O que ´e MySQL
MySQL, o mais popular banco de dados SQL Open Source, ´e fornecido pela MySQL AB.
MySQL AB ´e uma empresa comercial cujo neg´ocios ´e fornecer servi¸cos relacionados ao
banco de dados MySQL. See hundefinedi[What is MySQL AB], page hundefinedi.
O MySQL ´e um sistema gerenciador de bancos de dados.
Um banco de dados ´e uma cole¸ao de dados estruturados. Ele pode ser qual-
quer coisa desde uma simples lista de compras a uma galeria de imagens ou
a grande quantidade de informa¸ao da sua rede coorporativa. Para adicionar,
acessar, e processar dados armazenados em um banco de dados digital, vocˆe ne-
cessita de um sistema gerenciador de bancos de dados semelhante ao MySQL.
Como os computadores s˜ao muito bons em lidar com grandes quantidades de
dados, o gerenciamento de bancos de dados funciona como a engrenagem cen-
tral na computa¸ao, como utilit´arios independentes, ou como partes de outras
aplica¸oes.
O MySQL ´e um sistema gerenciador de bancos de dados relacional.
Um banco de dados relacional armazena dados em tabelas separadas embora
todos os dados estjam armazendos em um s´o local. Isso proporciona velocidade
e flexibilidade. As tabelas s˜ao unidas por rela¸oes definidas tornando poss´
ivel
combinar dados de diferentes tabelas nas requisi¸oes. A parte SQL do MySQL
atende pela "Linguagem estruturada de pesquisas"- a linguagem padr˜ao mais
comum usada para acessar bancos de dados.
O ´e MySQL um software Open Source.
Open Source garante para qualquer pessoa o uso ou modifica¸ao do software.
Qualquer pessoa pode fazer download do MySQL pela Internet e us´a-lo sem
ˆonus. Qualquer pessoa dedicada pode estudar o c´odigo fonte e alter´a-lo para
adequ´a-lo `as suas necessidades. O MySQL usa a GPL (Licen¸ca P´ublica Geral
GNU) http://www.gnu.org, para definir o que vocˆe pode e n˜ao pode fazer
com o software em diferentes situa¸oes. Se sentir desconforto com a GPL ou
precisair embutir o MySQL numa aplica¸ao comercial vocˆe pode adquirir a
vers˜ao comercial licenciada conosco.
Por que usar o MySQL?
O MySQL ´e extremamente r´apido, confi´avel, e f´acil de usar. Se isto ´e o que
vocˆe est´a procurando, vocˆe deveria experiment´a-lo. MySQL tamem tem um
conjunto de recursos muito pr´aticos desenvolvidos com a coopera¸ao de nossos
Chapter 1: Informa¸oes gerais sobre o MySQL 3
usu´arios. Voe pode encontrar comparativos de performance do MySQL com
outros gerenciadores de bancos de dados na nossa p´agina de benchmark See
hundefinedi[MySQL Benchmarks], page hundefinedi.
MySQL foi desenvolvido originalmente para lidar com bancos de dados muito
grandes de maneira muito mais r´apida que as solu¸oes existentes e tem sido
usado em ambientes de produ¸ao de alta demanda por diversos anos de maneira
bem sucedida. Apesar de estar em constante desenvolvimento, o MySQL hoje
oferece um rico e proveitoso conjunto de fun¸oes. A conectividade, velocidade,
e seguran¸ca fazem com que o MySQL seja altamente adapt´avel para acessar
bancos de dados na Internet.
As caracter´
isticas t´ecnicas do MySQL
Para informa¸oes t´ecnicas avan¸cadas, veja hundefinedi[Reference], page hun-
definedi. MySQL ´e um sistema cliente/servidor que consiste de um servidor
SQL multi-tarefa que suporta acessos diferentes, diversos programas clientes e
bibliotecas, ferramentas administrativas e diversas interfaces de programa¸ao.
Tamb´em concedemos o MySQL como uma biblioteca multi-tarefa que voe pode
ligar `a sua aplica¸ao para chegar a um produto mais r´apido, menor e mais
acilmente gerenci´avel.
MySQL tem muitos softwares de colaboradores dispon´
ivel.
´
E bem proavel que sua aplica¸ao ou linguagem favorita j´a suporte o MySQL.
A pron´uncia oficial do MySQL ´e “Mai Ess Que Ell” (e n˜ao MAI-SEQUEL). Mas tentamos
ao corrigir as pessoas que dizem MAI-SEQUEL.
1.1.2 O que ´e a MySQL AB
MySQL AB ´e uma empresa sueca que pertence e ´e administrada pelos fundadores do MySQL
e principais desenvolvedores. Nos dedicamos a desenvolver e disseminar nosso banco de
dados para novos usu´arios. MySQL AB ´e dona do direito autoral referente ao c´odigo
fonte do servidor MySQL e a marca comercial MySQL. Uma quantidade significativa dos
rendimentos de nossos servi¸cos ´e destinada ao desenvolvimento do MySQL. See hundefinedi
[What-is], page hundefinedi.
A MySQL AB tem obtido lucros a partir do MySQL desde o in´
icio. os n˜ao recebemos
capital externo, e todo o dinheiro foi arrecadado por n´os.
Estamos procurando parceiros que gostariam de apoiar o desenvolvimento do MySQL para
que possamos acelerar o ritmo de desenvolvimento. Se vocˆe est´a interessado, envie um
e-mail para partner@mysql.com.
Atualmente, a MySQL AB tem mais de 20 funcion´arios (http://www.mysql.com/development/team.html)
na sua folha de pagamento e est´a crescendo rapidamente.
Nossas principais fontes de recursos s˜ao:
Suporte comercial de alta qualidade para o MySQL fornecido pelos pr´oprios desen-
volvedores do MySQL. Se vocˆe tem interesse em adquirir um contrato de suporte, por
favor visite https://order.mysql.com/ para ver op¸oes de suporte ou para solicitar
suporte.
4 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Servi¸cos de Consultoria. os temos desenvolvedores e consultores em 12 paises e par-
ceiros em muitos outros pa´
ises que podem ajuda-lo com quase qualquer assunto rela-
cionado ao MySQL. Para servi¸cos de consultoria, por favor envie um email descrevendo
detalhadamente suas necessidades: info@mysql.com! Se n˜ao conseguirmos resolver seu
problema, encontraremos um parceiro ou desenvolvedor que possa ajud´a-lo.
Vendemos licen¸cas para usar o MySQL como um Banco de Dados embutido. See hunde-
finedi[Cost], page hundefinedi. Se vocˆe possui um produto comercial e deseja um banco
de dados r´apido e de alta qualidade, mas n˜ao pode tornar seu produto Open Source,
poder´a comprar o direito de uso do servidor MySQL sobre uma licen¸ca comercial nor-
mal. As licen¸cas de uso do MySQL sao vendidas em https://order.mysql.com/ ou
pelo licensing@mysql.com.
Propaganda. O http://www.mysql.com/ ´e um site de internet muito popular com mais
de 10.000.000 page views por mˆes (Janeiro 2001). Colocando um banner, vocˆe estar´a
atingindo v´arios clientes potenciais na comunidade Open Source, Linux e de Bancos de
Dados. Se tiver interesse, envie email para advertising@mysql.com.
Estamos criando um programa de parcerias que fornecer´a servi¸cos MySQL em todos
os pa´
ises. Se estiver interessado em se tornar um parceiro da MySQL AB, por favor
visite http://www.mysql.com/information/partners.html ou envie um email para
partner@mysql.com.
Fornecemos treinamento atraes de nossos parceiros. Para maiores informa¸oes, por
favor envie um email para info@mysql.com.
A marca MySQL tem, desde 1995, sido associada com velocidade e estabilidade e ´e
conhecida por ser confi´avel. Caso tenha interesse em usar a marca do MySQL no seu
neg´ocio, envie um email para info@mysql.com.
A ideologia do MySQL mostra nossa dedica¸ao ao MySQL e ao Open Source.
os desejamos que o MySQL seja:
O melhor e o mais usado banco de dados no mundo.
Acess´
ivel e dispon´
ivel para todos.
acil de usar.
Melhorado continuamente, permanecendo r´apido e seguro.
Divertido para usar e aprimorar.
Livre de erros (bugs).
A MySQL AB e sua equipe:
Promovem a filosofia Open Source e suporte `a comunidade Open Source.
Tem como objetivo serem bons cidad˜aos.
Tem preferˆencia por parceiros que compartilhem nossos valores e id´eias.
Respondem e-mails e d˜ao suporte.
ao uma empresa virtual, conectada com outras.
Trabalha contra patentes de sistemas.
Chapter 1: Informa¸oes gerais sobre o MySQL 5
1.1.3 Sobre este manual
Este manual ´e dispon´
ivel atualmente em vers˜oes Texinfo, texto, Info, HTML, PostScript
e PDF. O documento original est´a no formato Texinfo. A vers˜ao HTML ´e produzida
automaticamente usando uma vers˜ao modificada do texi2html. A vers˜ao texto e Info s˜ao
produzidas com makeinfo. A vers˜ao PostScript ´e produzida usando texi2dvi edvips. A
vers˜ao PDF ´e produzida com pdftex.
O manual original (em ingles) ´e escrito e mantido por David Axmark, Michael (Monty)
Widenius, Jeremy Cole e Paul DuBois. Para outros colaboradores, veja hundefinedi[Cred-
its], page hundefinedi.
1.1.4 Conven¸oes usadas neste manual.
Este manual usa algumas conven¸oes tipogr´aficas:
constant Fonte de largura fixa ´e usada para nomes de comandos e op¸oes; express˜oes
SQL; bancos de dados, nomes de tabelas e colunas; c´odigo C e Perl; e vari´aveis
de ambiente. Exemplo: “Para ver como o mysqladmin funciona, execute-o com
a op¸ao --help.”
filename
Fonte de largura fixa com aspas ´e usada para nomes de arquivos e caminhos.
Exemplo: “ distribui¸ao ´e instalada sobre o diret´orio ‘/usr/local’.”
c Fonte de largura constante com aspas ´e tamb´em usada para indicar sequˆencias
de caracteres. Exemplo: “Para especificar uma m´ascara, use o caractere ‘%’.”
italic Fonte It´alica ´e usada para dar ˆenfase, como aqui.
boldface Fonte em Negrito ´e usada para destacar nomes privilegiados (por exemplo,
“n˜ao permita o privil´egio a process levemente”) e ocasionalmente indicar ˆenfase
especial.
Quando um comando deve ser executado por um programa, ele ´e indicado por um prompt
antes do comando. Por exemplo, shell> ´e um prompt de comando para indicar o seu shell
atual e mysql> indica um prompt de comando do cliente mysql;
shell> digite um comando shell aqui
mysql> digite um comando mysql aqui
Comandos Shell s˜ao mostrados usando a sintaxe do Shell Bourne. Se vocˆe usa um shell do
estilo csh, pode ser necess´ario alterar algum de seus comandos. Por exemplo, a sequˆencia
para configurar uma vari´avel de ambiente e rodar um comando que se parece como abaixo
na sintaxe Bourne Shell:
shell> NOMEVAR=valor algum_comando
Para csh, execute a sequˆencia desta forma:
shell> setenv NOMEVAR valor
shell> algum_comando
Frequentemente, bancos de dados, tabelas, e nomes de colunas devem ser substitu´
idos nos
comandos. Para indicar que as substitui¸oes s˜ao necess´arias, este manual usa nome_db,
nome_tbl enome_col. Por exemplo, vocˆe pode ver uma express˜ao assim:
6 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT nome_col FROM nome_bd.nome_tbl;
Isso significa que se vocˆe estiver trabalhando numa express˜ao similar, poder´a fornecer seu
pr´oprio banco de dados, tabela e nomes de colunas, que possivelmente se parecer´a com isto:
mysql> SELECT nome_autor FROM biblio_bd.lista_autor;
Express˜oes SQL podem ser escritas em mai´usculas ou min´usculas. Quando este manual
mostra uma express˜ao SQL, ma´
isculas s˜ao usadas para as palavras-chave em quest˜ao (para
enfatiz´a-las) e min´usculas s˜ao usadas para o resto da express˜ao. Veja o exemplo na express˜ao
SELECT a seguir :
mysql> SELECT count(*) FROM nome_tbl;
Por outro lado, em uma discuss˜ao sobre a fun¸ao COUNT(), a mesma express˜ao pode ser
escrita assim:
mysql> select COUNT(*) from nome_tbl;
ao exisitindo o interesse em destacar, todas as palavras-chave s˜ao escritas uniformemente
em mai´usculas.
Em descri¸oes de sintaxe, colchetes (‘[’e‘]’) s˜ao usados para indicar palavras ou cl´ausulas
opcionais:
DROP TABLE [IF EXISTS] nome_tbl
Quando elementos da sintaxe possuem mais de uma alternativa, elas s˜ao separados por
barras verticais (‘|’). Quando um menbro de um conjuntop de op¸oes pode ser escolhido,
as alternativas s˜ao listadas em colchetes (‘[’ e ‘]’):
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
Quando um membro de um conjunto de op¸oes deve ser selecionado, as alternativas s˜ao
listadas em colchetes (‘{’ e ‘}’):
{DESCRIBE | DESC} nome_tabela {nome_campo | wild}
1.1.5 Hist´oria do MySQL
Quando come¸camos, t´
inhamos a inten¸ao de usar o mSQL para conectar `as nossas tabelas
utilizando nossas r´apidas rotinas de baixo n´
ivel (ISAM). Entretanto, depois de alguns testes,
chegamos a conclus˜ao que o mSQL ao era r´apido e nem flexivel o suficiente para nossas
necessidades. Isto resultou em uma nova interface SQL para nosso banco de dados, mas
com praticamente a mesma Interface API do mSQL. Esta API foi escolhida para facilitar a
portabilidade para c´odigos de terceiros.
A derivao do nome MySQL n˜ao ´e bem definida. Nosso diret´orio base e um grande n´umero
de nossas bibliotecas e ferramentas sempre tiveram o prefixo “my” por pelo menos 10 anos.
A filha de Monty, alguns anos mais nova que o MySQL, tamb´em ganhou o nome My. Qual
das duas originou o nome do MySQL continua sendo um mist´erio, mesmo para n´os.
1.1.6 As principais caracter´
isticas do MySQL
A seguinte lista descreve algumas das caracter´
isticas mais importantes do MySQL:
Suporte total a multi-threads usando threads diretamente no kernel. Isto significa que
se pode facilmente usar m´ultiplas CPUs, se dispon´
ivel.
Chapter 1: Informa¸oes gerais sobre o MySQL 7
C, C++, Eiffel, Java, Perl, PHP, Python e Tcl APIs. See hundefinedi[Clients], page hun-
definedi.
Funciona em diversas plataformas. See hundefinedi[Which OS], page hundefinedi.
Aceita diversos tipos de campos: inteiros de 1, 2, 3, 4 e 8 bytes com e sem sinal, FLOAT,
DOUBLE,CHAR,VARCHAR,TEXT,BLOB,DATE,TIME,DATETIME,TIMESTAMP,YEAR,SET,
and ENUM types. See hundefinedi[Column types], page hundefinedi.
Joins muito r´apidas usando uma multi-join de leitura ´unica otimizada.
Completo suporte a operadores e fun¸oes nas partes SELECT eWHERE das consultas. Por
exemplo:
mysql> SELECT CONCAT(first_name, " ", last_name) FROM nome_tabela
WHERE income/dependents > 10000 AND age > 30;
Fun¸oes SQL s˜ao implementadas atrav´es de uma biblioteca de classes altamente
otimizada e com o m´aximo de performance. Geralmente n˜ao h´a nenhuma aloca¸ao de
mem´oria depois da inicializa¸ao da pesquisa.
Suporte pleno `as cl´ausulas SQL GROUP BY eORDER BY. Suporte para fun¸oes de agru-
pamento (COUNT(),COUNT(DISTINCT ...),AVG(),STD(),SUM(),MAX() eMIN()).
Suporte para LEFT OUTER JOIN eRIGHT OUTER JOIN e sintaxes ANSI, SQL e ODBC.
Voe pode misturar tabelas de bancos de dados diferentes na mesma pesquisa (como
na vers˜ao 3.22).
Um sistema de privil´egios e senhas que ´e muito flex´
ivel, seguro e que permite verifica¸ao
baseada em esta¸oes/m´aquinas. Senhas s˜ao seguras porque todo o tr´afico de senhas ´e
criptografado quando vocˆe se conecta ao servidor.
Suporte ao ODBC (Open-DataBase-Connectivity) para Win32 (com fonte aberto). To-
das fun¸oes ODBC 2.5 e muitas outras. Por exemplo, vocˆe pode usar o MS Access para
conectar ao seu servidor MySQL. See hundefinedi[ODBC], page hundefinedi
Tabelas de disco baseadas em ´arvores-B extremamente r´apidas com compress˜ao de
´
indices.
ao permitidos at´e 32 ´
indices por tabela. Cada ´
indice pode ser composto de 1 a 16
colunas ou partes de colunas. O tamanho m´aximo do ´
indice ´e de 500 bytes (isto pode
ser alterado na compila¸ao do MySQL). Um ´
indice pode usar o prefixo de campo com
um tipo CHAR ou VARCHAR.
Registros de tamanhos fixos ou vari´aveis.
Tabelas hash em mem´oria que s˜ao usadas como tabelas tempor´arias.
Lida com bancos de dados enormes. os estamos usando MySQL com alguns bancos
de dados que cont´em 50.000.000 registros e n´os sabemos de usu´arios que usam MySQL
com 60.000 tabelas e aproximadamente 5.000.000.000 de linhas.
Todas as colunas tˆem valores padr˜ao. Vocˆe pode usar INSERT para inserir um sub-
conjunto de colunas de tabelas; aquelas colunas que n˜ao possuem valores fornecidos
explicitamente usam os seus valores padr˜oes.
Utiliza o GNU Automake, Autoconf, e Libtool para portabilidade.
Escrito em C e C++. Testado com um amplo faixa de compiladores diferentes.
Um sistema de aloca¸ao de mem´oria muito r´apido e baseado em processo(thread).
8 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ao existem furos ou problemas de mem´oria. O MySQL foi testado com o Purify, um
detector de problemas de mem´oria comercial.
Inclui o myisamchk, um utilit´ario muito r´apido para checagem, otimiza¸ao e reparo de
tabelas. Toda a funcionalidade do myisamchk est´a, tamb´em, dispon´
ivel pela interface
SQL. See hundefinedi[MySQL Database Administration], page hundefinedi.
Suporte total para v´arios conjuntos de caracteres, que incluem ISO-8859-1 (Latin1),
big5, ujis e mais. Por exemplo, os caracteres Escandinavos ‘˚a’, ‘¨a’ e ‘¨o’ s˜ao permitidos
em nomes de tabelas e colunas.
Todos os dados s˜ao armazenados no conjunto de caracteres escolhido. Todas as com-
para¸oes em colunas de sequenciascaso-insensitivo.
A ordena¸ao ´e feita de acordo com o conjunto de caracteres escolhido (o modo sueco
por padr˜ao). ´
E poss´
ivel alterar isso quando o servidor MySQL ´e iniciado. Para ver um
exemplo de v´arias ordena¸oes avan¸cadas, procure pelo c´odigo de ordena¸ao Tcheca.
O MySQL suporta diversos conjuntos de caracteres que podem ser especificados em
tempo de compila¸ao e execu¸ao.
Apelidos em tabelas e colunas s˜ao dispon´
iveis como definidos no padr˜ao SQL92.
DELETE,INSERT,REPLACE, e UPDATE retornam o n´umero de linhas que foram alteradas
(afetadas). ´
E poss´
ivel retornar o n´umero de linhas com padr˜ao coincidentes configu-
rando um parˆametro quando estiver conectando ao servidor.
Nomes de fun¸oes n˜ao comflitam com nomes de tabelas ou colunas. Por exemplo, ABS
´e um nome de campo v´alido. A ´unica restri¸ao ´e que para uma chamada de fun¸ao,
espa¸cos n˜ao s˜ao permitidos entre o nome da fun¸ao e o ‘(’ que o segue. See hundefinedi
[Reserved words], page hundefinedi.
Todos os programas MySQL podem ser chamados com as op¸oes --help ou -? para
obter ajuda online.
O servidor pode apresentar mensagem de erros aos clientes em v´arias l´
inguas. See
hundefinedi[Languages], page hundefinedi.
Os clientes podem se conectar ao servidor MySQL usando sockets(tomadas) TCP/IP,
sockets Unix, ou Named Pipes (NT).
O comando espec´
ifico do MySQL SHOW pode ser usado para devolver informa¸oes sobre
bancos de dados, tabelas e ´
indices. O comando EXPLAIN pode ser usado para determinar
como o otimizador resolve a consulta.
1.1.7 O MySQL ´e est´avel?
Esta se¸ao discute as quest˜oes “Quanto est´avel ´e o MySQL?” e “Posso depender do MySQL
neste projeto?” Tentaremos deixar claro alguns assuntos e responder algumas das quest˜oes
mais importantes que parecem interessar muitas pessoas. Esta se¸ao foi colocada juntamente
com a informa¸ao colhida da lista de discuss˜ao (que ´e muito ativa em relatar erros).
Na TcX, o MySQL vem trabalhando sem problema em nossos projetos desde o meio de 1996.
Quando o MySQL foi disponibilizado para um p´ublico maior, os fomos notificados que
existiam algumas peda¸cos de “c´odigo sem testes” que foram sendo rapidamente encontrados
pelos novos usu´arios que criavam pesquisas de uma maneira diferente das que n´os faz´
iamos.
Cada nova release teve menos problemas de portabilidade que o anterior (mesmo com os
novos recursos implementados em cada uma destas vers˜oes)
Chapter 1: Informa¸oes gerais sobre o MySQL 9
Cada release do MySQL foi sendo usado, e ocorrem problemas somente quando usu´arios
come¸cam a usar as “´areas cinzentas.” Naturalmente, usu´arios externos n˜ao sabem o que
ao as ´areas cinzentas; esta se¸ao tenta indicar aquelas que s˜ao conhecidas atualmente. As
descri¸oes lidam com a Vers˜ao 3.23 do MySQL. Todos os erros conhecidos e relatados s˜ao
reparados na ´ultima vers˜ao, com a exce¸ao dos bugs listados na se¸ao de erros, os quais s˜ao
relacionados ao desenho. See hundefinedi[Bugs], page hundefinedi
O MySQL ´e escrito em m´ultiplas camadas e diferentes m´odulos independentes. Estes
odulos est˜ao listados abaixo com indica¸oes de qu˜ao bem-testado foi cada um deles.
O handler de tabelas ISAM — Est´avel
Gerencia armazenamento e restaura¸ao de todos os dados no MySQL Vers˜ao
3.22 e anteriores. Em todas vers˜oes do MySQL, nunca foi relatado um s´o erro
neste c´odigo. A ´unica forma conhecida de corromper uma tabela ´e matar o
servidor no meio de uma atualiza¸ao. Mesmo isto n˜ao ´e suficiente para destruir
qualquer dados que n˜ao possam ser recuperados, porque todos os dados s˜ao
atualizados para o disco entre cada query. ao existe nenhum relato de erros
sobre perda de dados causados por bugs no MySQL.
O handler de tabelas MyISAM — Est´avel
Este ´e novo na vers˜ao do MySQL 3.23. ´
E amplamente baseado nos c´odigos de
tabelas ISAM mas possui diversos recursos novos e uteis.
O parser e o analisador l´exico — Est´avel
ao existem relatos de erros neste sistema h`a muito tempo.
O c´odigo C cliente — Est´avel
ao existem problemas conhecidos. Em vers˜oes mais antigas que a 3.20, ex-
istiam algumas limita¸oes no tamanho do buffer de envio/recebimento. Como
na vers˜ao 3.21, o tamanho do buffer agora ´e dinˆamico podendo chegar a um
padr˜ao de 16M.
Programas clientes padr˜oes — Est´avel
Inclui mysql,mysqladmin,mysqlshow,mysqldump, e mysqlimport.
SQL B´asico — Est´avel
O manipulador do sistema de fun¸oes, da classe string e da memoria dinamica
do SQL basico. ao existem relatos de erros neste sistema.
Otimizador de pesquisas — Est´avel
Otimizador do Range — Est´avel
Otimizador de Join — Est´avel
Locking — Gamma
Esse m´odulo ´e muito dependente do sistema. Em alguns sistemas existem certos
problemas por utilizar o locking padr˜ao do SO (fcntl(). Em alguns casos, vocˆe
pode executar o daemon do MySQL com o parˆametro --skip-locking. S˜ao
conhecidos alguns problemas ocorridos em alguns sistemas Linux e no SunOS
quando utiliza-se sistemas de arquivos montados em NFS.
Threads Linux — Est´avel
O maior problema encontrado neste m´odulo foi com a chamada fcntl(), que
´e corrigida usando a op¸ao --skip-locking com o mysqld. Algumas pessoas
10 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
relataram travamentos com a vers˜ao 0.5. Se vocˆe planeja usar mais de 1000
conex˜oes simultˆaneas, o LinuxThreads dever´a ser recompilado. Embora seja
poss´
ivel rodar todas essas conex˜oes com o LinuxThreads padr˜ao (de qualquer
forma, vocˆe nunca poder´a ir acima de 1021 conex˜oes), o espa¸co de pilha padr˜ao
de 2MB deixa a aplica¸ao inst´avel, e iremos reproduzir um coredump depois de
criar 1021 conex˜oes. See hundefinedi[Linux], page hundefinedi
Solaris 2.5+pthreads — Est´avel
Utilizamos isto para todo nosso trabalho de produ¸ao.
MIT-pthreads (Outros Sistemas) — Est´avel
ao h´a nenhum erro relatado desde da vers˜ao 3.20.15 e nenhum erro conhecido
desde a cers˜ao 3.20.16. Em alguns sistemas, h´a um "mal funcionamento"onde
algumas operacoes s˜ao muito lentas (uma parada de 1/20 segudos e feita entre
cada consulta). ´
E claro que MIT-pthreads pode deixar tudo um pouco lento,
mas as instru¸oes SELECT baseada em indice geralmente s˜ao feitas uma de cada
vez, enao elas n˜ao precis˜ao ser travadas com “mutex locking” nas threads.
Outras implementa¸oes de threads — Beta -
A portabilidade para outros sistemas ainda ´e muito nova e podem existir erros,
possivelmente no MySQL, mas a maioria na pr´opria implementa¸ao das threads.
LOAD DATA ...,INSERT ... SELECT — Est´avel
Algumas pessoas achavam que haviam encontrado bugs aqui, mas geralmente
ao mal-entendidos com rela¸ao ao funcionamento desses m´odulos. Por favor
confira o manual antes de relatar problemas!
ALTER TABLE — Est´avel
Pequenas altera¸oes na vers˜ao 3.22.12.
DBD — Est´avel
Atualmente mantido por Jochen Wiedmann (wiedmann@neckar-alb.de).
Obrigado!
mysqlaccess — Est´avel
Escrito e mantido por Yves Carlier (Yves.Carlier@rug.ac.be). Obrigado!
GRANT — Est´avel
Grandes altera¸oes feitas no MySQL Vers˜ao 3.22.12.
MyODBC (Usa ODBC SDK 2.5) — Gamma
Parece funcionar bem com muitos programas.
Replica¸ao – Beta / Gamma
Ainda estamos trabalhando na replica¸ao, portanto n˜ao espere que isso ir´a ser
olido como uma rocha ainda. Por outro lado, alguns usu´arios MySQL j´a est˜ao
usando isto com ´otimos resultados.
Tabelas BDB – Beta
O c´odigo de Bancos de dados Berkeley ´e muito est´avel, mas n´os ainda estamos
melhorando a interface entre o MySQL e as tabelas BDB, portando ele ir´a levar
algum tempo at´e ser testado como os outros tipos de tabelas foram.
Chapter 1: Informa¸oes gerais sobre o MySQL 11
Tabelas InnoDB – Beta
Esta ´e uma adi¸ao recente ao MySQL. Ela parece funcionar bem e pode ser usada
depois de alguns testes iniciais.
Recupera¸ao autom´atica de tabelas MyISAM - Beta
Isso afeta somente o novo c´odigo que confere, na inicializa¸ao do banco, se a
tabela foi fechada corretamente e executa uma conferˆencia/reparo autom´atico
da tabela em caso negativo.
MERGE de Tabelas – Beta / Gamma
O uso das chaves em MERGE de tabelas ainda n˜ao foi bem testado. A outra parte
do c´odigo MERGE foi muito bem testada.
FULLTEXT – Beta
A pesquisa textual aparenta funcionar, mas ainda n˜ao ´e amplamente usada.
MySQL AB fornece suporte por e-mail para clientes pagos, mas a lista de discuss˜ao MySQL
normalmente fornece respostas para quest˜oes comuns. Erros s˜ao normalmente corrigidos
com um patch; para erros s´erios, normalmente ´e lan¸cada uma nova release.
1.1.8 Qual o tamanho das tabelas que o MySQL pode suportar
A Vers˜ao 3.22 do MySQL tem suporte para tabelas com limite de tamanho at´e 4G. Com
o novo MyISAM no MySQL vers˜ao 3.23 o tamanho m´aximo foi extendido at´e 8 milh˜oes de
terabytes (2 ^63 bytes).
Lembre, entretando, que sistemas operacionais tem seu pr´oprio limite de tamanho para
arquivos. Seguem alguns exemplos:
Sistema Operacional Limite do tamanho do arquivo
Linux-Intel 32 bit 2G, 4G ou mais, depende da vers˜ao do
Linux
Linux-Alpha 8T (?)
Solaris 2.5.1 2G (possivelmente 4G com patch)
Solaris 2.6 4G
Solaris 2.7 Intel 4G
Solaris 2.7 ULTRA-SPARC 8T (?)
No Linux 2.2 vocˆe pode ter tabelas maiores que 2G usando o patch LFS para o sistema de
arquivos ext2. No Linux 2.4 j´a existem patches para o sistema de arquivos ReiserFS para
ter suporte a arquivos maiores.
Isto significa que o tamanho da tabela para o MySQL ´e normalmente limitado pelos sistemas
operacionais.
Por padr˜ao, tabelas do MySQL tˆem um tamanho m´aximo em torno de 4G. Vocˆe pode veri-
ficar o tamanho m´aximo da tabela com o comando SHOW TABLE STATUS ou com o myisamchk
-dv nome_tabela See hundefinedi[SHOW], page hundefinedi.
Se vocˆe precisa de tabelas maiores que 4G (e seu sistema operacional suporta isto), vocˆe
pode configurar o AVG_ROW_LENGHT e o parˆametro MAX_ROWS quando vocˆe criar sua tabela.
See hundefinedi[CREATE TABLE], page hundefinedi. Vocˆe pode tamb´em alterar isso mais
tarde com ALTER TABLE. See hundefinedi[ALTER TABLE], page hundefinedi
12 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se sua tabela grande ser´a somente leitura, vocˆe poder´a usar o myisampack para unir e
comprimir v´arias tabelas em uma. mysisampack normalmente comprime uma tabela em
pelo menos 50%, portanto voe pode obter, com isso, tabelas muito maiores. See hundefinedi
[myisampack], page hundefinedi
Uma op¸ao ´e ignorar o limite de tamanho de arquivos do sistema operacional para arquivos
de dados MyISAM usando a op¸ao RAID. See hundefinedi[CREATE TABLE], page hunde-
finedi.
Outra solu¸ao pode ser a biblioteca MERGE inclu´
ida, que lhe permite acessar uma cole¸ao
de tabelas idˆenticas como se fosse apenas uma. See hundefinedi[MERGE], page hundefinedi
1.1.9 Compatibilidade com o ano 2000 (Y2K)
O MySQL n˜ao apresenta nenhum problema com o ano 2000 (Y2K compat´
ivel)
O MySQL usa fun¸oes de tempo Unix e n˜ao tem problemas com datas at´e o ano 2069;
todos os anos de 2 d´
igitos s˜ao estimados na escala 1970 at´e 2069; o que significa que
se vocˆe armazenar 01 numa coluna year, O MySQL o tratar´a como 2001.
Todas as fun¸oes de data do MySQL est˜ao no arquivo ‘sql/time.cc’ e codificadas com
muito cuidado para ser compat´
ivel com o ano 2000.
No MySQL vers˜ao 3.22 e posterior, o novo tipo de campo YEAR pode armazenar anos
0e1901 at´e 2155 em 1 byte e mostr´a-lo usando 2 ou 4 d´
igitos.
Voe pode ter problemas com aplica¸oes que usem o MySQL de uma maneira que n˜ao
seja segura `a Y2K. Por exemplo, muitas aplica¸oes antigas armazenam ou manipulam anos
usando valores de 2 digitos (que ´e amb´
iguo) em vez de usar valores de 4 digitos. Este
problema pode ser composto por aplica¸oes que usam valores como em 00 ou 99 como
indicadores de valores “perdidos”.
Infelizmente, estes problemas podem ser dif´
iceis de resolver, porque diferentes aplica¸oes
podem ser escritas por diferentes programadores, e cada um deles pode usar um diferentes
conjunto de conven¸oes e fun¸oes manipuladoras de data.
Aqui est´a uma demonstra¸ao simples ilustrando que o MySQL n˜ao tem nenhum problema
com datas at´e o ano 2030:
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO y2k VALUES
-> ("1998-12-31","1998-12-31 23:59:59",19981231235959),
-> ("1999-01-01","1999-01-01 00:00:00",19990101000000),
-> ("1999-09-09","1999-09-09 23:59:59",19990909235959),
-> ("2000-01-01","2000-01-01 00:00:00",20000101000000),
-> ("2000-02-28","2000-02-28 00:00:00",20000228000000),
-> ("2000-02-29","2000-02-29 00:00:00",20000229000000),
-> ("2000-03-01","2000-03-01 00:00:00",20000301000000),
-> ("2000-12-31","2000-12-31 23:59:59",20001231235959),
-> ("2001-01-01","2001-01-01 00:00:00",20010101000000),
Chapter 1: Informa¸oes gerais sobre o MySQL 13
-> ("2004-12-31","2004-12-31 23:59:59",20041231235959),
-> ("2005-01-01","2005-01-01 00:00:00",20050101000000),
-> ("2030-01-01","2030-01-01 00:00:00",20300101000000),
-> ("2050-01-01","2050-01-01 00:00:00",20500101000000);
Query OK, 13 rows affected (0.01 sec)
Records: 13 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM y2k;
+------------+---------------------+----------------+
| date | date_time | time_stamp |
+------------+---------------------+----------------+
| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
| 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 |
+------------+---------------------+----------------+
13 rows in set (0.00 sec)
Isto mostra que os tipos DATE eDATETIME ao apresentar˜ao problemas com datas futuras
(eles ir˜ao conseguir trabalhar com datas at´e o ano 9999).
O tipo TIMESTAMP, que ´e usado para armazenar a hora atual, tem um alcance somente at´e
2030-01-01.TIMESTAMP tem um alcance de 1970 at´e 2030 em m´aquinas 32-bits (valor com
sinal). Em m´aquinas de 64-bits ele pode trabalhar com datas at´e 2106 (valor sem sinal).
Mesmo apesar do MySQL ser compat´
ivel com o ano 2000, ´e de sua responsabilidade forb-
necer datas que n˜ao sejam amb´
iguas. Veja hundefinedi[Y2K issues], page hundefinedipara
regras do MySQL para lidar com entrada de datas amb´
iguas (datas contendo valores de ano
com 2 d´
igitos)
1.2 Fontes de Informa¸oes Sobre MySQL
1.2.1 Livros sobre o MySQL
Para informa¸oes mais recentes sobre livros, com comenarios dos usu´arios, por favor visite
http://www.mysql.com/portal/books/html/index.html.
Enquanto este manual ainda for o lugar certo para informa¸oes t´ecnicas atualizadas, seu
objetivo principal ser´a conter tudo que ´e conhecido sobre o MySQL. Ao mesmo tempo ´e
interessante ter um livro para ler na cama ou enquanto vocˆe viaja. Segue aqui uma lista de
livros sobre MySQL e assuntos relacionados (em Inglˆes).
14 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Comprando um livro atrav´es dos hyperlinks fornecidos aqui vocˆe estar´a contribuindo para
o desenvolvimento do MySQL.
MySQL
Dispon´
ivel em Barnes and Noble
Editor New Riders
Autor Paul DuBois
Data de Publica¸ao 1st Edition December 1999
ISBN 0735709211
aginas 800
Pre¸co $49.99 US
Exemplos para Download samp_db distribution
Errata are available here
Revisado por Michael “Monty” Widenius, Moderador do MySQL.
Em MySQL, Paul DuBois introduz a vocˆe um guia completo para um dos mais populares
bancos de dados relacionais. Paul tem contribu´
ido para a documenta¸ao online para o
MySQL e ´e um membro ativo da comunidade MySQL. O principal desenvolvedor do MySQL,
Monty Widenius, e uma rede de seus companheiros desenvolvedores revisaram o manuscrito,
e forneceram a Paul o tipo de discernimento que ningu´em poderia fornecer.
Ao inv´es de simplesmente dar uma vi˜ao geral do MySQL, Paul o ensina grande parte de
seus conhecimentos. Atraes de duas tabelas exemplos utilizadas por todo o livro, ele
mostra solu¸oes para problemas que vocˆe certamente ir´a encontrar. Ele o ajuda a integrar
MySQL, eficientemente, com ferramentas de terceiros, como PHP e Perl, habilitando-o a
gerar paginas Web dinamicas atrav´es de consultas a banco de dados. Ele o ensina a escrever
programas que acessam banco de dados MySQL, e tamb´em fornece um conjunto completo
de referˆencias para tipos de campos, operadores, fun¸oes, sintaxe SQL, programando em
MySQL, API C, Perl DBI, e API PHP. MySQL simplesmente lhe dar´a informa¸oes que vocˆe
ao encontrar´a em nenhum outro lugar.
Se vocˆe usa o MySQL, este livro lhe oferece:
Uma introdu¸ao ao MySQL e SQL.
Cobertura dos tipos de dados do MySQL e como us´a-los.
Perfeito tratamento de como escrever programas clientes em C.
Um guia para usar o Perl DBI e APIs PHP para desenvolver aplica¸oes baseadas em
linha de comando e Web.
Dicas em asssuntos administrativos como contas de usu´arios, backup, recupera¸ao em
caso de quedas e seguran¸ca.
Ajuda para escolher um Provedor de Servi¸cos de Internet para acesso MySQL.
Uma referˆencia completa para tipos de dados MySQL, operadores, fun¸oes, instru¸oes
SQL e utilit´arios.
Guias de referˆencia completos para a API C do MySQL, a API do Perl DBI e fun¸oes
PHP relacionadas ao MySQL.
Chapter 1: Informa¸oes gerais sobre o MySQL 15
MySQL & mSQL
Dispon´
ivel em Barnes and Noble
Editor O’Reilly
Autores Randy Jay Yarger, George Reese & Tim King
Data de Publica¸ao 1st Edition July 1999
ISBN 1-56592-434-7, Order Number: 4347
aginas 506
Pre¸co $34.95
Este livro ensina vocˆe como usar o MySQL e mSQL, dois populares e robustos produtos de
banco de dados que suportam subsistemas de chave de SQL em ambos os sistemas Linux e
Unix. Qualquer um que conhe¸ca C b´asico, Java, Perl ou Python pode escrever um programa
para interagir com um banco de dados, podendo ser uma aplica¸ao isolada ou atrav´es de uma
agina Web. Este livro leva vocˆe atrav´es de todo o processo, da instala¸ao e configura¸ao
at´e a programa¸ao de interfaces e administra¸ao b´asica. Inclui farto material de tutorial.
Sams’ Teach Yourself MySQL in 21 Days
Dispon´
ivel em Barnes and Noble
Editor Sams
Autores Mark Maslakowski and Tony Butcher
Data de Publica¸ao Junho 2000
ISBN 0672319144
aginas 650
Pre¸co $39.99
OTeach Yourself MySQL in 21 Days da Sams ´e indicado para usu´arios Linux intermedi´arios
que desejam entrar na ´area de bancos de dados. Boa parte do publico alvo ´e formada
por desenvolvedores Web que necessitam de um banco de dados para armazenar grande
quantidade de informa¸oes para que possam ser recuperadas pela Web.
Teach Yourself MySQL in 21 Days ´e um pr´atico tutorial passo-a-passo. O leitor ir´a aprender
desenvolver e trabalhar essa tecnologia de bancos de dados open source em seu Web site
usando exemplos pr´aticos para seguir.
E-Commerce Solutions with MySQL
Dispon´
ivel em Barnes and Noble
Editor Prima Communications, Inc.
Autores ao dispon´
ivel
Data de Publica¸ao Janeiro 2000
ISBN 0761524452
aginas 500
Pre¸co $39.99
Sem descri¸ao dispon´
ivel.
MySQL and PHP from Scratch
16 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Dispon´
ivel em Barnes and Noble
Editor Que
Autores N/A
Data de Publica¸ao September 2000
ISBN 0789724405
aginas 550
Pre¸co $34.99
Este livro disponibiliza de forma conjunta informa¸oes sobre instala¸ao, configura¸ao e
corre¸ao de problemas no Apache, MySQL, PHP3 e IMP em um volume completo. Vocˆe
aprende tamb´em como cada pca ´e parte de um conjunto de aprendizagem passo-a-passo,
para criar um sistema de e-mail baseado em Web. Aprenda a executar o equivalente ao
Active Server Pages (ASP) usando PHP3, configurar um site de e-commerce usando um
banco de dados e um servidor Web Apache, e criar um sistema de entrada de dados (como
em vendas, controle de qualidade de produ¸c˜ao, preferˆencias dos clientes, etc) para instalar
no seu PC.
Professional MySQL Programming
Dispon´
ivel em Barnes and Noble
Editor Wrox Press, Inc.
Autores N/A
Data de Publica¸ao Late 2001
ISBN 1861005164
aginas 1000
Pre¸co $49.99
Sem descri¸ao dispon´
ivel.
Professional Linux Programming
Dispon´
ivel em Barnes and Noble
Editor Wrox Press, Inc.
Autores N/A
Data de Publica¸ao September 2000
ISBN 1861003013
aginas 1155
Pre¸co $47.99
Neste Best-Selling Beginning Linux Programming vocˆe aprender´a com o vivˆencia e ex-
periˆencia dos autores em desenvolvimento de software para Linux; Voe ir´a acompanhar o
desenvolvimento da aplica¸ao exemplo de uma Loja de DVD, com cap´
itulos que o levam
a diferentes aspectos de sua implementa¸ao. Capitulos individuais cobrem t´opicos im-
portantes que v˜ao al´em do tema central. Todo o foco ´e feito sobre aspectos praticos da
programa¸ao, mostrando a importˆancia de se escolher a ferramenta certa para o trabalho,
usando-a da forma correta e fazendo da forma correta na primeira vez.
PHP and MySQL Web Development
Dispon´
ivel em Barnes and Noble
Editor Sams
Chapter 1: Informa¸oes gerais sobre o MySQL 17
Autores Luke Welling, Laura Thomson
Data de Publica¸ao March 2001
ISBN 0672317842
aginas 700
Pre¸co $49.99
PHP and MySQL Web Development traz `a vocˆe as vantagens de se implementar o MySQL
e PHP. As vantagens s˜ao detalhadas atrav´es das condi¸oes estatist´
icas e de v´arios estudos de
caso. Uma aplica¸ao web pr´atica ´e desenvolvida ao longo do livro, fornecendo a vocˆe quais
ao as ferramentas necess´arias para implementar um banco de dados online e funcional.
Cada fun¸ao ´e desenvolvida separadamente, o que lhe permite escolher incorporar somente
partes que vocˆe deseja implementar. Conceitos de programa¸ao da linguagem PHP s˜ao
destacados, incluindo fun¸oes das quais amarram o suporte MySQL em um script PHP e
opicos avan¸cados cobrindo manipula¸ao de tabelas.
Livros recomendados pelos desenvolvedores do MySQL
SQL-99 Complete, Really
Dispon´
ivel em Barnes and Noble
Editor CMP Books
Autores Peter Gulutzan, Trudy Pelzer
Data de Publica¸ao April 1999
ISBN 0879305681
aginas 1104
Pre¸co $55.96
Este livro cont´em descri¸oes completas dos novos padr˜oes de sintaxe, estrutura de dados,
e processos de recupera¸ao de informa¸ao de bancos de dados SQL. Como um manual de
referˆencia baseado em exemplos, ele include todas as fun¸oes CLI, informa¸oes, tabelas de
esquemas e c´odigos de status, bem como um banco de dados funcional fornecido no disco
que acompanha o livro.
C, A reference manual
Dispon´
ivel em Barnes and Noble
Editor Prentice Hall
Autores Samuel P. Harbison, Guy L. Steele
Data de Publica¸ao September 1994
ISBN 0133262243
aginas 480
Pre¸co $35.99
Uma nova e aprimorada revis˜ao de referˆencia `a linguagem C. Este manual lhe introduz
no¸oes de "C Limpo", escrevendo c´odigo C que pode ser compilado como um programa
C++, estilo de programa¸ao C que enfatiza comportamento apropriado, portabilidade, sus-
tentabilidade, e incorpora a emenda 1 do ISO C (1994) que especifica novas facilidades para
escrever programas em C port´aveis e internacionais.
C++ for Real Programmers
Dispon´
ivel em Barnes and Noble
18 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Editor Academic Press, Incorporated
Autores Jeff Alger, Jim Keogh
Data de Publica¸ao February 1998
ISBN 0120499428
aginas 388
Pre¸co $39.95
C++ For Real Programmers preenche a lacuna entre C++ como foi descrito nos livros in-
dicados para programadores de n´
ivel iniciante e intermedi´ario e o C++ utilizado por pro-
gramadores experientes. arias t´ecnicas preciosas s˜ao descritas, organizadas em trˆes temas
simples: indire¸ao, hierarquia de classes e gerenciamento de mem´oria. Ele tamb´em cobre
detalhadamente a cria¸ao de templates, ponteiros, e t´ecnicas de otimiza¸ao. O foco do livro
´e em C++ ANSI independente de compilador.
C++ For Real Programmers ´e uma revis˜ao do Secrets of the C++ Masters e inclui um novo
apˆendice comparando C++ com Java. O livro vem com um disquete de 3.5"com c´odigo
fonte para windows.
Algorithms in C
Dispon´
ivel em Barnes and Noble
Editor Addison Wesley Longman, Inc.
Autores Robert Sedgewick
Data de Publica¸ao April 1990
ISBN 0201514257
aginas 648
Pre¸co $45.75
Algorithms in C descreve uma variedade de algoritmos em algumas ´areas de interesse, in-
cluindo: ordena¸ao, pesquisa, processamento de strings e algor´
itmos geom´etricos, graficos e
matem´aticos. O livro enfatiza t´ecnicas fundamentais, fornecendo aos leitores as ferramentas
para executar, implementar e debugar ´uteis algor´
itmos com confian¸ca.
Multithreaded Programming with Pthreads
Available Barnes and Noble
Publisher Prentice Hall
Authors Bil Lewis, Daniel J. Berg
Pub Date October 1997
ISBN 0136807291
Pages 432
Price $34.95
Baseado no best-selling Threads Primer,Multithreaded Programming with Pthreads da a
vocˆe um solido conhecimento de threads Posix: o que s˜ao, como funcionam, quando us´a-
las e como otimiz´a-las. Ele mant´em a clareze e o humor de Threads Primer, mas inclui
compara¸oes com as implementa¸oes em Win32 e OS/2. Codigos exemplos testados na
maioria das plataformas UNIX s˜ao disponibilizados com explica¸oes detalhadas de como e
porque eles usam threads.
Programming the PERL DBI: Database Programming with PERL
Chapter 1: Informa¸oes gerais sobre o MySQL 19
Available Barnes and Noble
Publisher O’Reilly & Associates, Incorporated
Authors Alligator Descartes, Tim Bunce
Pub Date February 2000
ISBN 1565926994
Pages 400
Price $27.96
Programming the Perl DBI ´e escrito em conjunto com Alligator Descartes, um dos membros
mais ativos da comunidade DBI, e como Tim Bunce, o inventor do DBI. Para os iniciantes
o livro explica a arquitetura do DBI e mostra como ecrever programas baseados em DBI.
Para os mais experientes o livro explica nuances do DBI e peculiaridades de cada DBD
individual.
Este livro inclui:
Uma introdu¸ao ao DBI e seu desemvolvimento.
Como criar consultas e casar os parˆamentros.
Trabalhando com banco de dados, drivers e manipulando instru¸oes.
Tecnicas para debugar.
Cobertura de cada DBD existente.
Uma referˆencia completa do DBI.
1.2.2 Informa¸oes gerais e tutoriais
O seguinte livro foi recomendado por v´arias pessoas na lista de discuss˜ao do MySQL:
Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
The Practical SQL Handbook: Using Structured Query Language
Second Edition
Addison-Wesley
ISBN 0-201-62623-3
http://www.awl.com
O seguinte livro recebeu algumas recomenda¸oes por usu´arios do MySQL:
Martin Gruber
Understanding SQL
ISBN 0-89588-644-8
Publisher Sybex 510 523 8233
Alameda, CA USA
Um tutorial sobre SQL est´a dispon´
ivel na rede em http://w3.one.net/~jhoffman/sqltut.htm
1.2.3 Links ´uteis relacionados ao MySQL
Al´em dos links a seguir, vocˆe pode encontrar e fazer download de v´arios programas, ferra-
mentas e APIs para MySQL do Diretorio de Colaboradores.
MySQL
20 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Tutoriais e Manuais
MySQL Myths Debunked
MySQL usado no "mundo real".
http://www.4t2.com/mysql
Informa¸oes sobre a lista de discuss˜ao alem˜a do MySQL.
http://www2.rent-a-database.de/mysql/
MySQL handbook em alem˜ao.
http://www.bitmover.com:8888//home/bk/mysql
Accesso web ao reposit´orio BitKeeper do MySQL.
http://www.analysisandsolutions.com/code/mybasic.htm
Tutorial para iniciantes no MySQL em como instalar e configurar o MySQL
numa m´aquina Windows.
http://www.devshed.com/Server_Side/MySQL/
arios tutorias sobre MySQL.
http://mysql.hitstar.com/
Manual do MySQL em chinˆes.
http://www.linuxplanet.com/linuxplanet/tutorials/1046/1/
Configurando um site web baseado em MySQL.
http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html
Tutorial Perl-MySQL.
http://www.iserver.com/support/contrib/perl5/modules.html
Instalando novos m´odulos Perl que necessitam de m´odulos localmente instala-
dos.
http://www.hotwired.com/webmonkey/databases/tutorials/tutorial4.html
Tutorial PHP/MySQL.
http://www.useractive.com/
Tutorial para MySQL.
Portando MySQL/Usando MySQL em diferentes sistemas
http://www.entropy.ch/software/macosx/mysql/
Bin´arios do MySQL para MAC OS X. Inclui informa¸oes sobre como construir
e usar MySQL no MAC OS X.
http://xclave.macnn.com/MySQL/
O Mac OS Xclave. Executando MySQL no Mac OS X.
http://www.prnet.de/RegEx/mysql.html
MySQL para Servidor Mac OS X .
http://www.latencyzero.com/macosx/mysql.html
Compilando o MySQL para o Mac OS X.
Chapter 1: Informa¸oes gerais sobre o MySQL 21
http://www.essencesw.com/Software/mysqllib.html
Novas bibliotecas cliente para o MAC OS Classic (Macintosh).
http://www.lilback.com/macsql/
Bibliotecas cliente para o MAC OS Classic (Macintosh).
http://sixk.maniasys.com/index_en.html
MySQL para a plataforma Amiga.
Links relacionados a Perl
http://dbimysql.photoflux.com/
FAQ MySQL com DBI Perl.
orum de Discuss˜ao MySQL
http://www.weberdev.com/
Exemplos de usos do MySQL; (Veja os Top 20)
http://futurerealm.com/forum/futureforum.htm
FutureForum Web Discussion Software.
Aplica¸oes comerciais que suportam o MySQL
http://www.supportwizard.com/
SupportWizard; Ajuda interativa na Web (Este produto inclui uma c´opia licen-
ciada do MySQL.)
http://www.sonork.com/
Sonork, instant messenger que n˜ao ´e orientado somente `a Internet. Ele ´e focado
em redes privadas e em pequenas e m´edias empresas. O Cliente ´e gratuito e o
servidor tamb´em ´e gratuito para at´e 5 usu´arios.
http://www.stweb.org/
StWeb - Servidor Web e de aplica¸oes Stratos - F´acil de usar, plataforma
cruzada, sistema de desenvolvimento e entrega de aplica¸oes Web para Inter-
net/Intranet. A vers˜ao padr˜ao do StWeb tem uma interface nativa para o banco
de dados MySQL.
http://www.rightnowtech.com/
Right Now Web; Automa¸ao Web para servi¸cos `a clientes.
http://www.icaap.org/Bazaar/
Bazaar; F´oruns de discuss˜ao interativas com interface Web.
http://www.phonesweep.com/
PhoneSweepT ´e o primeiro sistema de busca de telefone comercial do mundo.
Muitas invas˜oes ocorridas nos ultimos anos, n˜ao s˜ao feitas atrav´es da internet,
mas atrav´es chamadas n˜ao autorizadas atrav´es de modems. PhoneSweep per-
mite que vocˆe encontre estes modems atrav´es de repetidas chamadas locais para
todos os numeros de telefones que sua empresa controla. PhoneSweep tem um
sistema que pode reconhecer mais de 250 tipos diferentes de programas de acesso
22 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
remoto, incluindo Carbon Copy(TM), pcAnywhere(TM), e Windows NT RAS.
Todas as informa¸oes s˜ao armazenadas em um banco de dados SQL. ´
E gerado
enao um relat´orio completo detalhando quais servi¸cos forma descobertos em
cada numero de telefone em sua empresa.
Clientes SQL e Geradores de Relat´orios
urSQL Editor SQL e Utilit´ario de Consultas. Marcador de sintaxe personalizado, grade
de resultados editaveis, exporta¸ao de resultados, fun¸oes b´asicas de adminis-
tra¸ao de NySQL, Etc.. Para Windows.
MySQL Data Manager
MySQL Data Manager * ´e cliente web independente de plataforma (escrita em
perl) para servidor MySQL sobre TCP/IP.
http://ksql.sourceforge.net/
cliente MySQL para KDE.
http://www.ecker-software.de
Um cliene GUI para Windows por David Ecker.
http://www.icaap.org/software/kiosk/
Kiosk; um cliente MySQL para gerenciamento de banco de dados. Escrito em
Perl. Ser´a uma parte do Bazaar.
http://www.casestudio.com/
Ferramenta de desenvolvimento que suporta MySQL 3.23.
http://home.skif.net/~voland/zeos/eng/index.html
Zeos - Um cliente que suporta MySQL, Interbase e PostgreSQL.
http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html
Um gerador de relatorios gratuito escrito em Java
http://www.javaframework.de
MySQLExport - Exporta¸ao instru¸oes de cria¸ao do MySQL e dados em di-
versos formatos (SQL, HTML, CVS, text, ZIP, GZIP...)
http://dlabs.4t2.com
M2D, Um cliente administrativo do MySQL para windows. M2D suporta ad-
ministra¸ao de Bancos de Dados MySQL, cria¸ao de novos bancos de dados e
tabelas, edi¸ao e muito mais.
http://dlabs.4t2.com
Dexter, um pequeno servidor escrito em Perl pode ser usado como servidor
proxy para o MySQL ou como um extensor do banco de dados.
http://www.scibit.com/Products/Software/Utils/Mascon.asp
Mascon ´e um poderoso GUI Win32 para administrar MySQL bancos de dados.
http://www.rtlabs.com/
MacSQL Monitor. Gui para Bancos de dados MySQL, ODBC e JDBC para o
MAC OS.
Chapter 1: Informa¸oes gerais sobre o MySQL 23
Distribui¸oes que incluem o MySQL
http://www.suse.com/
SuSE Linux (6.1 e superior)
http://www.redhat.com/
RedHat Linux (7.0 e superior)
http://distro.conectiva.com.br
Conectiva Linux (4.0 e superior)
Ferramentas de Desenvolvimento Web que suportam MySQL
http://www.php.net/
PHP: Uma linguagem script do lado do servidor embutida em HTML.
http://www.midgard-project.org
The Midgard Application Server; um ambiente de desenvolvimento Web
poderoso baseado em MySQL e PHP.
http://www.smartworker.org
SmartWorker ´e uma plataforma para desenvolvimento de aplica¸oes Web.
http://xsp.lentus.se/
XSP: e(X)tendible (S)erver (P)ages e ´e uma linguagem embutida em tags
HTML escrito em Java (anteriormente conhecido como XTAGS.)
http://www.dbServ.de/
dbServ ´e uma extens˜ao para um servidor web para integrar a saida do banco de
dados em seu codigo HTML. Voce pode usar qualquer func¸ao HTML em sua
sa´
ida. Somente o cliente poder´a te interromper. Funciona como um servidor
isolado ou como servlet Java.
http://www.chilisoft.com/
Platforma ASP independente por Chili!Soft
http://www.voicenet.com/~zellert/tjFM
Driver JDBC para MySQL.
http://www.wernhart.priv.at/php/
Demonstra¸oes de MySQL e PHP.
http://www.dbwww.com/
ForwardSQL: Interface HTML para manipular bancos de dados MySQL.
http://www.daa.com.au/~james/www-sql/
WWW-SQL: Mostra informa¸oes de bancos de dados.
http://www.minivend.com/minivend/
Minivend: Um carrinho de compras em Web.
http://www.heitml.com/
HeiTML: uma extens˜ao HTML do lado do servidor e uma linguagem 4GL ao
mesmo tempo.
24 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
http://www.metahtml.com/
Metahtml: Um Linguagem Dinaimca de Programa¸ao para Aplica¸oes WWW.
http://www.binevolve.com/
VelocityGen para Perl e Tcl.
http://hawkeye.net/
Hawkeye Internet Server Suite.
http://www.fastflow.com/
Network Database Connection para Linux
http://www.wdbi.net/
WDBI: Navegador web como um front end universal para banco de dados que
suportam MySQL.
http://www.webgroove.com/
WebGroove Script: compilador HTML e linguagem script do lado do servidor.
http://www.ihtml.com/
Uma linguagem script do lado do servidor.
ftp://ftp.igc.apc.org/pub/myodbc/README
Como usar o MySQL com ColdFusion no Solaris.
http://calistra.com/MySQL/
Administrador ODBC MySQL Calistra.
http://www.webmerger.com
Webmerger - Esta ferramenta CGI le arquivos e gera uma saida dinamica
baseada em um conjunto de tags simple. Drivers prontos para MySQL e Post-
greSQL atrav´es do ODBC.
http://phpclub.net/
PHPclub - Dicas e truques para o PHP.
http://www.penguinservices.com/scripts
Scripts MySQL e Perl.
http://www.widgetchuck.com
The Widgetchuck; Web site com ferramentas.
http://www.adcycle.com/
AdCycle - Software gerenciador de anuncios.
http://sourceforge.net/projects/pwpage/
pwPage - fornece uma ferramenta extremamente r´apida e simples para a cria¸ao
de formulario de banco de dados. Isto ´e, se existe uma tabela de banco de
dados e uma pagina HTML foi construida usando poucas linhas pwPage pode
ser imediatamente usado para sele¸ao, inser¸ao, atualiza¸ao, dele¸ao de dados
da tabela e revis˜ao do conte´udo da tabela selecionada.
http://www.omnis-software.com/products/studio/studio.html
OMNIS Studio ´e uma ferramenta de desenvolvimento r´apido de aplica¸oes
(RAD).
Chapter 1: Informa¸oes gerais sobre o MySQL 25
http://www.webplus.com
talentsoft Web+4.6 - uma completa e poderosa linguagem de desenvolvmento
para usar na cria¸ao de aplica¸oes cliente/servidor com base na web sem escrever
programas CGI complicados, baixo-nivel e que consomem tempo.
Ferramentas de cria¸ao de bancos de dados com Suporte MySQL
http://www.mysql.com/documentation/dezign/
"DeZign for databases"´e uma ferramenta de desenvolvimento de banco de
dados que usa diagramas de relacionamento de entidades (ERD).
Servidores Web com Ferramentas MySQL
ftp://ftp.kcilink.com/pub/
mod auth mysql, Modulo de autentica¸ao para o Apache.
http://www.roxen.com/
O Servidor Web Roxen Challenger.
Extens˜oes para outros programas.
http://www.seawood.org/msql_bind/
Suporte MySQL para o BIND (O servidor de nomes da Internet).
http://www.inet-interactive.com/sendmail/
Suporte MySQL para o Sendmail e Procmail.
Utilizando o MySQL com outros programas
http://www.iserver.com/support/addonhelp/database/mysql/msaccess.html
Utilizando o MySQL com o MS Access.
http://www.iserver.com/support/contrib/perl5/modules.html
Instalando novos m´odulos Perl que exigem m´odulos instalados localmente.
Links relacionados ao ODBC
http://www.iodbc.org/
Gerenciados do driver iODBC popular (libiodbc) agora dispon´
ivel como Open
Source.
http://users.ids.net/~bjepson/freeODBC/
As p´aginas do FreeODBC.
http://genix.net/unixODBC/
Os objetivos do projeto unixODBC s˜ao desenvolver e promover o unixODBC
para ser o padr˜ao definitivo para ODBC na plataforma Linux. Isso inclui su-
portar suporte GUI para o KDE.
http://www.sw-soft.com/products/BtrieveODBC/
Um driver ODBC baseado em MySQL para o Btrieve.
26 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Links relacionados `a API
http://www.jppp.com/
Componentes para MySQL compativeis com TDataset parcialmente implemen-
tados.
http://www.riverstyx.net/qpopmysql/
qpopmysql - Um patch que permite autentica¸oes POP3 para um banco de
dados MySQL. Existe tamb´em um link para um patch de Paul Khavkine para
o Procmail para permitir a qualquer MTA a fazer a entrega a usuarios em um
banco de dados MySQL.
http://www.pbc.ottawa.on.ca
Gerador de classes Visual Basic para o Active X.
http://www.essencesw.com/Software/mysqllib.html
Novas bibliotecas clientes para o Mac OS Classic (Macintosh).
http://www.lilback.com/macsql/
Bibliotecas-cliente para o Macintosh.
http://www.essencesw.com/Plugins/mysqlplug.html
Plugin para o REALbasic (para Macintosh)
http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html
Uma biblioteca que emula sockets BSD e pthreads no Macintosh. Ela pode ser
usada se vocˆe quiser compilar a biblioteca do cliente MySQL para Mac. Ela
provavelmente pode ser usada para portar o MySQL para o Macintosh, mas
ao conhecemos ningu´em que tenha tentado isto.
http://www.dedecker.net/jessie/scmdb/
SCMDB - Um add-on para SCM que porta a biblioteca C do MySQL para
scheme (SCM). Com esta biblioteca desenvolvedores do scheme podem fazer
conec¸oes para um banco de dados MySQL e usar SQL embutido em seus
programas.
Outros Links Relacionados ao MySQL
SAT A Small Application Toolkit (SAT) ´e uma cole¸ao de utilit´arios com inten¸ao
de simplificar o desenvolvimento de aplica¸oes pequenas, multiusuarios e com
base em GUI em um ambiente (Microsoft -ou- X) Cliente Windows / Servidor
Unix.
http://www.wix.com/mysql-hosting/
Registro de provedores Web que suportam o MySQL.
http://www.softagency.co.jp/mysql/index.en.html
Links sobre usar o MySQL no Jap˜ao/´
Asia.
http://abattoir.cc.ndsu.nodak.edu/~nem/mysql/udf/
Registro UDF MySQL.
http://www.open.com.au/products.html
Sitema Web Comercial de rastreamento de defeitos
Chapter 1: Informa¸oes gerais sobre o MySQL 27
http://www.stonekeep.com/pts/
PTS: Projeto de Sistema de Rastreamento.
http://tomato.nvgc.vt.edu/~hroberts/mot
Servi¸co e software de sistema de rastreamento.
http://www.cynergi.net/exportsql/
ExportSQL: Um script para exportar dados do Access95+.
http://SAL.KachinaTech.COM/H/1/MYSQL.html
Entrada MySQL SAL - Aplica¸oes Ciˆentificas no Linux (Scientific Applications
on Linux).
http://www.infotech-nj.com/itech/index.shtml
Uma empresa de consultoria que menciona o MySQL nos direitos da companhia.
http://www.pmpcs.com/
PMP Computer Solutions. Desenvolvedores de banco de dados usando MySQL
and mSQL.
http://www.aewa.org/
Airborne Early Warning Association.
http://www.dedserius.com/y2kmatrix/
Testador Y2K.
Interfaces SQL e de Banco de Dados
http://java.sun.com/products/jdbc/
A API do JDBC para acesso a banco de dados.
http://www.gagme.com/mysql
Patch para mSQL Tcl.
http://www.amsoft.ru/easysql/
EasySQL: Um driver de gerenciamento como o ODBC.
http://www.lightlink.com/hessling/rexxsql.html
Um interface REXX para banco de dados SQL.
http://www.mytcl.cx/
Interface Tlc baseada em tcl-sql com muitos erros corrigidos.
http://www.binevolve.com/~tdarugar/tcl-sql/
Interface Tcl.
http://www.contrib.andrew.cmu.edu/~shadow/sql.html
Pagina de Referˆencia SQL com v´arios links interressantes.
Exemplos de utiliza¸oes do MySQL
http://www.little6.com/about/linux/
Little6 Inc., Um <<<...online contract and job finding site...>>> que utiliza
MySQL, PHP3, e Linux.
28 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
http://www.delec.com/is/products/prep/examples/BookShelf/index.html
DELECis - Uma Ferramenta que torna muito f´acil a cria¸ao de documenta¸ao
de tabelas gerada automaticamente. Eles tˆem usado o MySQL como exemplo.
http://www.worldrecords.com
World Records - Um mecanismo de pesquisa para informa¸oes sobre m´usica que
utiliza o MySQL e PHP.
http://www.webtechniques.com/archives/1998/01/note/
Um banco de dados de contatos usando MySQL e PHP.
http://modems.rosenet.net/mysql/
Calend´ario comunit´ario em PHP com interface Web.
http://www.odbsoft.com/cook/sources.htm
Pacote Perl para gerar p´aginas html de uma estrutura de tabelas SQL e in-
stru¸oes SQL de um formul´ario HTML.
http://www.gusnet.cx/proj/telsql/
Banco de dados b´asico de telefones usando DBI/DBD.
http://tecfa.unige.ch/guides/java/staf2x/ex/jdbc/coffee-break
Exemplos JDBC por Daniel K. Schneider.
http://www.spade.com/linux/howto/PostgreSQL-HOWTO-41.html
SQL BNF
http://www.ooc.com/
Object Oriented Concepts Inc; Aplica¸oes CORBA com exemplos em fontes.
http://www.pbc.ottawa.on.ca/
DBWiz: Fornece um exemplo de como gerenciar cursores em VB.
http://keilor.cs.umass.edu/pluribus/
Pluribus ´e um mecanismo de busca gratuito que melhora a qualidade de seus
resultados com o tempo. Pluribus funciona atrav´es da gravc˜ao de qual das
paginas um usuario selecionou entre aquelas retornadas pela consulta. Um
usuario vota na p´agina ao selecion´a-la; Pluribus utiliza ent˜ao o seu conhecimento
para melhorar a qualidade dos resultados quando outra pessoa envia a mesma
consulta (ou similar). Usa PHO e MySQL.
http://www.stopbit.com/
Stopbit -Um site de not´
icias sobre tecnologia usando MySQL e PHP.
http://www.linuxsupportline.com/~kalendar/
Gerenciador de datas para KDE - O gerenciador possui suporte monousuario
(baseado e arquivo) e multiusuario (banco de dados MySQL).
http://tim.desert.net/~tim/imger/
Exemplo de armazenamento/recupera¸ao de imagens com MySQL e CGI.
http://www.penguinservices.com/scripts
Sistema de Carrinho de Compras Online.
Chapter 1: Informa¸oes gerais sobre o MySQL 29
http://www.city-gallery.com/album/
Old Photo Album - O album ´e um projeto de historico de fotografia com co-
labora¸ao popular que gera todas a paginas atrav´es de dados armazendos em
banco de dados MySQL. As p´aginas s˜ao geradas dinamicamente atrav´es de uma
interface php3 com o conte´udo do banco de dados. Utiliza imagens e descri¸oes.
As imagens s˜ao armazenadas em um servidor web para evitar armazena-los em
um banco de dados como BLOBs. Todas as outras informa¸oes s˜ao armazenadas
no no servidor MySQL compartilhado.
Links Gerais de Banco de Dados
http://www.pcslink.com/~ej/dbweb.html
Database Jump Site
http://black.hole-in-the.net/guy/webdb/
Homepage da lista de discuss˜ao webdb-l (Web Databases).
http://www.symbolstone.org/technology/perl/DBI/index.html
agina dos m´odulos DBI/DBD do Perl.
http://www.student.uni-koeln.de/cygwin/
Ferramentas Cygwin. Unix em cima do Windows.
http://dbasecentral.com/
dbasecentral.com; Desenvolvimento e distribui¸ao de sistemas e aplicativos de
banco de dados poderosos e f´aceis de usar.
http://www.tek-tips.com/
Tek-Tips Forums s˜ao mais de 800 foruns de suporte p2p n˜ao comerciais e inden-
depentes voltado `a profissionais da Computa¸ao. Recursos incluem notifica¸ao
autom´atica para respostas, uma biblioteca de links, e prote¸ao confidenciais
para foruns particulares.
http://www.public.asu.edu/~peterjn/btree/
Arvores B: Estrutura de Dados em ´arvore balanceada.
http://www.fit.qut.edu.au/~maire/baobab/lecture/sld001.htm
Conferˆencia sobre Arvores B.
Existem tamb´em outros diversos sites Web que utilizam o MySQL. See hundefinedi[Users],
page hundefinedi. Envie sugest˜oes para esta lista no email webmaster@mysql.com. Estamos
pedindo que vocˆe disponibilize uma logomarca do MySQL em algum lugar de seu site se
vocˆe desejar ter sua p´agina citada aqui. Isto tamb´em ´e v´alido para ter sua p´agina adicionada
na pagina “ferramentas utilizadas” ou algo parecido.
1.2.4 Listas de Discuss˜ao MySQL
Esta se¸ao traz a vocˆe as listas de discuss˜ao do MySQL e da algumas dicas de como utiliz´a-
las
30 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1.2.4.1 As Listas de Discuss˜ao MySQL
Para se inscrever na principal lista de discuss˜ao sobre MySQL, envie uma mensagem para
o endere¸co de correio eletrˆonico mysql-subscribe@lists.mysql.com.
Para cancelar a sua inscri¸ao na principal lista de discuss˜ao sobre MySQL envie uma men-
sagem para o endere¸co de correio eletrˆonico mysql-unsubscribe@lists.mysql.com.
Somente o endere¸co para o qual vocˆe envia a mensagem ´e significante. O assunto e o corpo
da mensagem s˜ao ignorados.
Se o seu endere¸co de resposta n˜ao for v´alido, vocˆe pode especificar o seu endere¸co ex-
plicitamente, adicionando um h´
ifen ao comando de inscri¸ao ou cancelamento, seguido
pelo seu ender¸co com o caracter ‘@’ do seu endere¸co substituido por um ‘=’. Por exem-
plo, para inscrever seu_nome.dominio envie uma mensagem para mysql-subscribe-seu_
nome=host.dominio@lists.mysql.com
Mensagens para mysql-subscribe@lists.mysql.com ou mysql-unsubscribe@lists.mysql.com
ao processadas automaticamente pelo processador de listas de discuss˜ao exmlm. In-
forma¸oes sobre ezmlm est˜ao dispon´
iveis no Website do ezmlm.
Para enviar uma mensagem para a lista, envie para mysql@lists.mysql.com. No entanto,
ao enviem mensagens de inscri¸ao e cancelamento no mysql@lists.mysql.com por favor,
porque qualquer mensagem enviada para o endere¸co ser´a distribuida automaticamente para
milhares de outros usuarios.
Seu site local pode ter muitas inscri¸oes para mysql@lists.mysql.com. Neste caso, ele pode
ter uma lista de discuss˜ao local, assim as mensagens enviadas para lists.mysql.com para
seu site s˜ao propagadas para a lista local. Nestes casos, por favor, contate seu administrador
de sistema para adicionado ou excluido da lista local do MySQL.
Se vocˆe quiser que as mensagens da lista de discuss˜ao sejam enceminhadas para uma caixa
de correio separada no seu programa de emails, configure um filtro com base nos cabcalhos
das mensagens. Vocˆe pode tamb´em usar os cabcalhos List-ID: ou Entregar-Para: para
identificar suas mensagens.
Existe tamb´em as seguintes listas de discuss˜ao sobre MySQL atualmente:
announce-subscribe@lists.mysql.com (anuncio)
Esta ´e para anuncio de novas vers˜oes do MySQL e programas relacionados.
Esta ´e uma lista com baixo volume na qual todos usuarios do MySQL deveriam
se inscrever.
mysql-subscribe@lists.mysql.com (mysql)
A principal lista para discuss˜oes MySQL em geral. Note que alguns t´opicos s˜ao
mais bem discutidos em listas mais especializadas. Se vocˆe enviar para a lista
errada vocˆe pode n˜ao obter resposta.
mysql-digest-subscribe@lists.mysql.com (mysql-digest)
A lista mysql na forma resumida. Isto significa que voe ir´a receber todas
mensagens individuais, enviadas na forma de uma grande mensagem uma ´unica
vez ao dia.
bugs-subscribe@lists.mysql.com (bugs)
Nesta lista vocˆe somente deve postar um relato de bug completo que acontece
de maneira repetitiva usando o script mysqlbug (se vocˆe estiver executando
Chapter 1: Informa¸oes gerais sobre o MySQL 31
no Windows, vocˆe dever´a incluir uma descri¸ao do sistema operacional e a
vers˜ao do MySQL). Preferencialmente, vocˆe deve testar o problema usando a
´ultima vers˜ao est´avel ou de desenvolvimento do MySQL antes de postar um erro!
Qualquer um pode repetir o erro apenas usando mysql test < script no caso
do teste inclu´
ido. Todos os erros enviados para esta lista dever˜ao ser corrigidos
ou documentados na pr´oxima release do MySQL! Se a solu¸ao envolve apenas
a altera¸ao de pequena parte do c´odigo, ser´a enviado um patch corrigindo o
problema.
bugs-digest-subscribe@lists.mysql.com (bugs-digest)
Uma vers˜ao resumida da lista bugs.
internals-subscribe@lists.mysql.com (internals)
Uma lista para pessoas que trabalham no c´odigo do MySQL. Nesta lista pode-se
discutir desenvolvimento do MySQL e pos-patches.
internals-digest-subscribe@lists.mysql.com (internals-digest)
Uma vers˜ao resumida da lista internals.
java-subscribe@lists.mysql.com (java)
Discuss˜ao sobre MySQL e Java. Maioria sobre o driver JDBC..
java-digest-subscribe@lists.mysql.com java-digest
Uma vers˜ao resumida da lista java.
win32-subscribe@lists.mysql.com (win32)
Todas as quest˜oes relacionada ao MySQL em sistemas operacionais Microsoft,
como o Win95, Win98, NT e Win2000.
win32-digest-subscribe@lists.mysql.com (win32-digest)
Uma vers˜ao resumida da lista win32.
myodbc-subscribe@lists.mysql.com (myodbc)
Tudo sobre conectividade do MySQL com ODBC.
myodbc-digest-subscribe@lists.mysql.com (myodbc-digest)
Uma vers˜ao resumida da lista myodbc.
plusplus-subscribe@lists.mysql.com (plusplus)
Tudo relacionado `a programa¸ao da API C++ para o MySQL.
plusplus-digest-subscribe@lists.mysql.com (plusplus-digest)
Uma vers˜ao resumida da lista plusplus.
msql-mysql-modules-subscribe@lists.mysql.com (msql-mysql-modules)
Lista sobre o Suporte MySQL no Perl. msql-mysql-modules
msql-mysql-modules-digest-subscribe@lists.mysql.com
(msql-mysql-modules-digest)
Lista resumida sobre a vers˜ao do msql-mysql-modules.
Voe se inscreve ou cancela a assinatura para todas listas do mesmo jeito que foi
descrito acima. Na sua mensagem de assinatura ou cancelamento, coloque apenas o
nome da lista apropriada. Por exemplo, para assinar ou cancelar sua assinatura da
32 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
lista myodbc, envie uma mensagem para myodbc-subscribe@lists.mysql.com ou
myodbc-unsubscribe@lists.mysql.com.
Se vocˆe n˜ao obtiver uma resposta para suas quest˜oes na lista de mensagens, uma op¸ao ´e pa-
gar pelo suporte da MySQL AB, que ir´a colocar vocˆe em contato direto com desenvolvedores
MySQL. See hundefinedi[Support], page hundefinedi.
A seguinte tabela mostra algumas listas de mensagens sobre o MySQL que utilizam linguas
diferentes do Inglˆes. Perceba que elas n˜ao s˜ao operadas pela MySQL AB, portanto, n˜ao
podemos garantir a qualidade destas.
mysql-france-subscribe@yahoogroups.com Lista de mensagens na
l´
ingua francesa.
list@tinc.net Lista de mensagens coreana.
Envie subscribe mysql your@email.address para esta lista.
mysql-de-request@lists.4t2.com Lista de mensagens alem~a.
Envie subscribe mysql-de your@email.address para esta lista.
Voe pode encontrar informa¸oes sobre esta lista de mensagens em
http://www.4t2.com/mysql.
mysql-br-request@listas.linkway.com.br Lista de mensagens
em portuguˆes Envie subscribe mysql-br your@email.address para esta lista.
mysql-alta@elistas.net Lista de mensagens espanhola.
Envie subscribe mysql your@email.address para esta lista.
1.2.4.2 Fazendo perguntas ou relatando erros
Antes de enviar um relato de erro ou uma quest˜ao, por favor fa¸ca o seguinte:
Comece pesquisando o manual MySQL online em:
http://www.mysql.com/documentation/manual.php
os tentaremos manter o manual atualizado, frequentemente atualizando-o com
solu¸oes para novos problemas encontrados!
Pesquise os arquivos das listas de mensagens MySQL:
http://www.mysql.com/documentation/
Voe pode tamb´em usar a p´agina http://www.mysql.com/search.html para
pesquisar todas as p´aginas Web (incluindo o manual) que est˜ao localizados em
http://www.mysql.com/.
Se vocˆe n˜ao puder encontrar uma resposta no manual ou nos arquivos, confira com seu
expert em MySQL local. Se vocˆe continua n˜ao encontrando uma resposta para sua quest˜ao,
a em frente e leia a pr´oxima se¸ao sobre como enviar email para mysql@lists.mysql.com.
1.2.4.3 Como relatar erros ou problemas
Escrever um bom relat´orio de erro exige paciˆencia, e fazˆe-lo de forma apropriada economiza
tempo para n´os e para vocˆe. Um bom relat´orio de erros contendo um teste de caso para o
bug ir´a torn´a-lo muito mais f´acil para corrig´
i-lo no pr´oximo release. Esta se¸ao ir´a ajud´a-lo
Chapter 1: Informa¸oes gerais sobre o MySQL 33
a escrever seu relat´orio corretamente para que vocˆe n˜ao perca seu tempo fazendo coisas que
ao ir˜ao ajudar-nos muito ou nada.
os encorajamos todo mundo a usar o script mysqlbug para gerar um relato de erros
(ou um relato sobre qualquer problema), se poss´
ivel. mysqlbug pode ser encontrado no
diret´orio ‘scripts’ na distribui¸c˜ao fonte, ou, para uma distribui¸ao bin´aria, no diret´orio
bin’ no diret´orio de instala¸ao do MySQL. Se vocˆe n˜ao puder utilizar o mysqlbug, vocˆe
pode continuar incluindo todas as informa¸oes necess´arias listadas nesta se¸ao.
O script mysqlbug lhe ajudar´a a gerar um relat´orio determinando muitas das seguintes
informa¸oes automaticamente, mas se alguma coisa importante estiver faltando, por favor
forne¸ca-o junto de sua mensagem! Por favor leita esta se¸ao com cuidado e tenha certeza
que todas as informa¸oes descritas aquie est˜ao inclu´
idas no seu relat´orio.
O lugar comum para relatar erros e problemas ´e mysql@lists.mysql.com. Se vocˆe
fizer um caso com testes que demonstre o bug claramente, pode post´a-lo na lista
bugs@lists.mysql.com. Note que nesta lista vocˆe dever´a postar somente um um relat´orio
completo, usando o script mysqlbug. Se vocˆe estiver trabalhando com o MySQL para
Windows, vocˆe deve incluir uma descri¸ao do sistema operacional e a vers˜ao do MySQL.
Preferencialmente vocˆe deve testar o problema usando a ´ultima vers˜ao est´avel ou de
desenvolvimento do MySQL antes de postar ! Qualquer um deve conseguir repetir o
erro usando apenas “mysql test < script” no teste do caso incluso, ou executandoo do
shell ou utilizando scripts perl inclusos no relatorio de erro. Todos os erros postados na
lista bugs ser˜ao corrigidos ou documentados na pr´oxima release do MySQL! Se foram
necess´arias apenas pequenas altera¸oes no c´odigo para resolver este problema, n´os iremos
publicar um patch que corrige o problema.
Lembre-se que ´e poss´
ivel responder a uma mensagem contendo muita informa¸ao, mas n˜ao
a uma contendo muito pouca. Frequentemente pessoas omitem fatos porque acreditam que
conhecem a causa do problema e assumem que alguns detalhes n˜ao importam. Um bom
principio ´e: Se vocˆe est´a em d´uvida sobre declarar alguma coisa, declare-a ! ´
E milhares de
vezes mais r´apido e menos problem´atico escrever um pouco de linhas a mais no seu relat´orio
do que ser for¸cado a perguntar de novo e esperar pela resposta porque vocˆe n˜ao forneceu
informa¸ao sufiente da primeira vez.
Os erros mais comuns acontecem porque as pessoas n˜ao indicam o n´umero da vers˜ao da
distribui¸ao do MySQL que est˜ao usando, ou n˜ao indicam em qual plataforma elas tem
o MySQL instalado (Incluindo o n´umero da vers˜ao da plataforma). Essa informa¸c˜ao ´e
muito relevante, e em 99% dos casos o relato de erro ´e in´util sem ela! Frequentemente n´os
recebemos quest˜oes como, “Por que isto n˜ao funciona para mim?” enao n´os vemos que
aquele recurso requisitado n˜ao estava implementado naquela vers˜ao do MySQL, ou que o
erro descrito num relat´orio foi resolvido em uma vers˜ao do MySQL mais nova. Algumas
vezes o erro ´e dependente da plataforma; nesses casos, ´e quase imposs´
ivel corrigir alguma
coisa sem conhecimento do sistema operacional e o n´umero da vers˜ao da plataforma.
Lembre-se tamb´em de fornecer informa¸oes sobre seu compilador, se isto for relacionado
ao problema. Frequentemente pessoas encontram erros em compiladores e acreditam que o
problema ´e relacionado ao MySQL. A maioria dos compiladores est˜ao sobre desenvolvimento
todo o tempo e tornam-se melhores a cada vers˜ao. Para determinar se o seu problema
depende ou n˜ao do compilador, n´os precisamos saber qual compilador foi usado. Note que
todo problema de compila¸ao deve ser estimado como relato de erros e, consequentemente
publicado.
34 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
´
E de grande ajuda quando uma boa descri¸ao do problema ´e inclu´
ida no relato do erro. Isto
´e, um bom exemplo de todas as coisas que o levou ao problema e a correta descri¸ao do
problema. Os melhores relat´orios s˜ao aqueles que incluem um exemplo completo mostrando
como reproduzir o erro ou o problema See hundefinedi[Reproduceable test case], page hun-
definedi.
Se um programa produz uma mensagem de erro, ´e muito importante incluir essas mensagens
no seu relat´orio! Se n´os tentarmos procurar por algo dos arquivos usando programas, ´e
melhor que as mensagens de erro relatadas sejam exatamente iguais a que o programa
produziu. (At´e o caso deve ser observado!) Vocˆe nunca deve tentar lembrar qual foi a
mensagem de erro; e sim, copiar e colar a mensagem inteira no seu relat´orio!
Se vocˆe tem um problema com o MyODBC, vocˆe deve tentar gerar um arquivo para ras-
tremento de erros (trace) do MyODBC. See hundefinedi[MyODBC bug report], page hun-
definedi.
Por favor lembre-se que muitas das pessoas que ler˜ao seu relat´orio podem usar um v´
ideo de
80 colunas. Quando estiver gerando relat´orios ou exemplos usando a ferramenta de linha
de comando mysql, ent˜ao dever´a usar a op¸ao --vertical (ou a instru¸ao terminadora \G)
para sa´
ida que ir´a exceder a largura dispon´
ivel para este tipo de v´
ideo (por exemplo, com
a instru¸ao EXPLAIN SELECT; veja exemplo abaixo).
Por favor inclua a seguinte informa¸ao no seu relat´orio:
O n´umero da vers˜ao da distribui¸ao do MySQL que est´a em uso (por exemplo, MySQL
Version 3.22.22). Vocˆe poder´a saber qual vers˜ao vocˆes est´a executando, usando o
comando mysqladmin version.mysqladmin pode ser encontrado no diret´orio ‘bin
sob sua instala¸ao do MySQL.
O fabricante e o modelo da m´aquina na qual vocˆe est´a trabalhando.
O nome do sistema operacional e a vers˜ao. Para a maioria dos sistemas operacionais,
vocˆe pode obter esta informa¸ao executando o comando Unix uname -a.
Algumas vezes a quantidade de mem´oria (real e virtual) ´e relevante. Se estiver em
d´uvida, inclua esses valores.
Se vocˆe estiver usando uma distribui¸ao fonte do MySQL, ´e necess´ario o nome e n´umero
da vers˜ao do compilador usado. Se vocˆe estiver usando uma distribui¸ao bin´aria, ´e
necess´ario o nome da distribui¸ao.
Se o problema ocorre durante a compila¸ao, inclua a(s) exata(s) mensagem(s) de erro(s)
e tamb´em algumas linhas do contexto envolvendo o c´odigo no arquivo onde o erro
ocorreu.
Se o mysqld finalizou, vocˆe dever´a relatar tamb´em a consulta que travou o mysqld.
Normalmente vocˆe pode encontrar isto executando mysqld com o log habilitado. See
hundefinedi[Using log files], page hundefinedi
Se alguma tabela do banco de dados estiver relacionado ao problema, inclua a sa´
ida de
mysqldump --nodata nome_db nome_tbl1 nome_tbl2.... Isto ´e muito acil de fazer
e ´e um modo poderoso de obter informa¸oes sobre qualquer tabela em um banco de
dados que ir´a ajudar-nos a criar uma situa¸ao parecida da que vocˆe tem.
Para problemas relacionados `a velocidade ou problemas com instru¸oes SELECT, vocˆe
sempre deve incluir a sa´
ida de EXPLAIN SELECT ... e ao menos o n´umero de linhas
que a instru¸ao SELECT produz. Quanto mais informa¸ao vocˆe fornecer sobre a sua
Chapter 1: Informa¸oes gerais sobre o MySQL 35
situa¸ao, mais f´acil ser´a para algu´em ajudar-lo! A seguir um exemplo de um relat´orio
de erros muito bom (ele deve ser postado com o script mysqlbug):
Exemplo de execu¸ao usando a ferramenta de linha de comando mysql (perceba o uso
do instru¸ao terminadora \G para instru¸oes cuja largura de sa´
ida deva ultrapassar 80
colunas):
mysql> SHOW VARIABLES;
mysql> SHOW COLUMNS FROM ...\G
<saida para SHOW COLUMNS>
mysql> EXPLAIN SELECT ...\G
<saida para EXPLAIN>
mysql> FLUSH STATUS;
mysql> SELECT ...;
<Uma pequena vers~ao da sa´
ida do SELECT,
incluindo a hora em que a consulta foi executada>
mysql> SHOW STATUS;
<saida do SHOW STATUS>
Se um erro ou problema ocorrer quando estiver executando o mysqld, tente fornecer um
script de entrada que ir´a reproduzir a anomalia. Este script deve incluir qualquer ar-
quivo de fonte necess´ario. Quanto mais pr´oximo o script puder reproduzir sua situa¸ao,
melhor. Se vocˆe puder fazer uma s´erie de testes repetidos, vocˆe poder´a post´a-lo para o
bugs@lists.mysql.com para um tratamento de alta prioridade!
Se n˜ao puder fornecer o script, voe ao menos deve incluir a sa´
ida de mysqladmin
variables extended-status processlist na sua mensagem para fornecer alguma
informa¸ao da performance do seus sistema.
Se vocˆe n˜ao puder produzir um caso de teste em algumas linhas, ou se a tabela de
testes for muito grande para ser enviada por email para a lista de mensagens (mais de
10 linhas), vocˆe dever´a dar um dump de suas tabelas usando o mysqldump e criar um
arquivo ‘README’ que descreve seu problema.
Crie um arquivo comprimido de seus arquivos usando tar egzip ou zip, e use o
ftp para transferir o arquivo para ftp://support.mysql.com/pub/mysql/secret/.
E envie uma pequena descri¸ao do problema para bugs@lists.mysql.com.
Se vocˆe achar que o MySQL produziu um resultado estranho para uma consulta, n˜ao
inclua somente o resultado, mas tamb´em sua opini˜ao de como o resultado deve ser, e
uma conta descrevendo o base de sua opini˜ao.
Quando fornecer um exemplo do problema, ´e melhor usar os nomes de vari´aveis, nomes
de tabelas, etc. utilizados na sua situa¸ao atual do que enviar com novos nomes. O
problema pode ser relacionado ao nome da vari´avel ou tabela! Esses casos s˜ao raros,
mas ´e melhor prevenir do que remediar. Al´em disso, ser´a mais f´acil para vocˆe fornecer
um exemplo que use sua situa¸ao atual, que ´e o que mais importa para n´os. No caso
de ter dados que n˜ao deseja mostrar para outros, vocˆe pode usar o ftp para transferi-
lo para ftp://support.mysql.com/pub/mysql/secret/. Se os dados s˜ao realmente
confidenciais, e vocˆe n˜ao deseja mostr´a-los nem mesmo para n´os, enao v´a em frente e
providencie um exemplo usando outros nome, mas, por favor considere isso como uma
´unica chance.
36 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Inclua, se poss´
ivel, todas as op¸oes fornecidas aos programas relevantes. Por exemplo,
indique as op¸oes que vocˆe utiliza quando inicializa o daemon mysqld e aquelas que s˜ao
utilizadas para executar qualquer programa cliente MySQL. As op¸oes para programas
como o mysqld emysql, e para o script configure, ao frequentemente chaves para
respostas e s˜ao muito relevantes! Nunca ´e uma m´a id´eia inclu´
i-las de qualquer forma!
Se vocˆe usa algum m´odulo, como Perl ou PHP por favor forne¸ca o n´umero da vers˜ao
deles tamb´em.
Se sua quest˜ao ´e relacionada ao sistema de privil´egios, por favor forne¸ca a sa´
ida
de mysqlaccess, a sa´
ida de mysqladmin reload, e todas as mensagens de erro que
vocˆe obteve quando tentava conectar! Quando vocˆe testar seus privil´egios, vocˆe deve
primeiramente executar mysqlaccess. Depois, execute mysqladmin reload version e
tente conectar com o programa que gerou o problema. mysqlaccess pode ser encon-
trado no diret´orio ‘bin’ sob seu diret´orio de instala¸ao do MySQL.
Se vocˆe tiver um patch para um erro, isso ´e bom, mas n˜ao assuma que o patch ´e
tudo que precisamos, ou que iremos us´a-lo, se vocˆe n˜ao fornecer algumas informa¸oes
necess´arias, como os casos de testes mostrando o erro que seu patch corrige. os
podemos encontrar problemas com seu patch ou n´os podemos n˜ao entendˆe-lo ao todo;
se for assim, n˜ao podemos us´a-lo.
Se n´os n˜ao verificarmos exatamente o que o patch quer dizer, n´os n˜ao poderemos us´a-
lo. Casos de testes ir˜ao ajudar-nos aqui. Mostre que o patch ir´a cuidar de todas as
situa¸oes que possam ocorrer. Se n´os encontrarmos um caso (mesmo que raro) onde o
patch n˜ao funcionaria, ele pode ser in´util.
Palpites sobre o que o erro pode ser, porque ocorre, ou do que ele depende, geralmente
est˜ao errados. Mesmo o time MySQL n˜ao pode adivinhar antecipadamente tais coisas
sem usar um debugger para determinar a causa real do erro.
Indique na sua mensagem de e-mail que vocˆe conferiu o manual de referˆencia e o arquivo
de mensagens para que outros saibam que vocˆe tentou solucionar o problema.
Se vocˆe obter um parse error, por favor confira sua sintaxe com aten¸ao! Se
vocˆe n˜ao conseguiu encontrar nada errado com ela, ´e extremamente proavel
que que sua vers˜ao corrente do MySQL n˜ao suporte a consulta que vocˆe
est´a utilizando. Se vocˆe estiver usando a vers˜ao recente e o manual em
http://www.mysql.com/documentation/manual.php ao cobrir a sintaxe que
vocˆe estiver usando, o MySQL n˜ao suporta sua consulta. Neste caso, suas unicas
op¸oes s˜ao implementar vocˆe mesmo a sintaxe ou enviar uma mensagem para
mysql-licensing@mysql.com e perguntar por uma oferta para implemena-lo!
Se o manual cobrir a sintaxe que vocˆe estiver usando, mas vocˆe tiver uma vers˜ao mais
antiga do MySQL, vocˆe dever´a conferir o hist´orico de altera¸oes do MySQL para ver
quando a sintaxe foi implementada. Neste caso, vocˆe tem a op¸ao de atualizar para
uma nova vers˜ao do MySQL. See hundefinedi[News], page hundefinedi.
Se vocˆe tiver um problema do tipo que seus dados aparecem corrompidos ou voe
obtem erros quando vocˆe acessa alguma tabela em particular, vocˆe dever´a primeiro
checar depois tentar reparar suas tabelas com myisamchk ou CHECK TABLE eREPAIR
TABLE. See hundefinedi[MySQL Database Administration], page hundefinedi.
Se vocˆe frequentemente obt´em tabelas corrompidas, vocˆe deve ten-
tar encontrar quando e porque isto acontece! Neste caso, o arquivo
Chapter 1: Informa¸oes gerais sobre o MySQL 37
mysql-data-directory/’hostname’.err’ deve conter algumas informa¸oes
sobre o que aconteceu. See hundefinedi[Error log], page hundefinedi. Por favor forne¸ca
qualquer informa¸ao relevante deste arquivo no seu relat´orio de erro! Normalmente
omysqld NUNCA dever´a danificar uma tabela se nada o finalizou no meio de uma
atualiza¸ao! Se vocˆe puder encontrar a causa do fim do mysqld, se torna muito mais
acil para n´os fornecemos a vocˆe uma solu¸ao para o problema! See hundefinedi[What
is crashing], page hundefinedi.
Se poss´
ivel, fa¸ca o download e instale a vers˜ao mais recente do MySQL para saber se
ela resolve ou n˜ao o seu problema. Todas vers˜oes do MySQL s˜ao muito bem testadas
e devem funcionar sem problemas! Acreditamos em deixar tudo, o mais comp´ativel
poss´
ivel com as vers˜oes anteriores, e vocˆe conseguir´a mudar de vers˜oes MySQL em
minutos! See hundefinedi[Which version], page hundefinedi.
Se vocˆe ´e um cliente de nosso suporte, por favor envio o seu relat´orio de erros em
mysql-support@mysql.com para tratamento de alta priorit´ario, bem como para a lista de
mensagens apropriada para ver se mais algu´em teve experiˆencias com (e talvez resolveu) o
problema.
Para informa¸oes sobre relatar erros no MyODBC, veja hundefinedi[ODBC Problems],
page hundefinedi.
Para solu¸oes a alguns problemas comuns, veja See hundefinedi[Problems], page hunde-
finedi.
Quando respostas s˜ao enviadas para vocˆe individualmente e n˜ao para a lista de mensagens, ´e
considerado boa etiqueta resumir as respostas e enviar o resumo para a lista de mensagens
para que outras possam ter o benef´
icio das respostas que vocˆe recebeu que ajudaram a
resolver seu problema!
1.2.4.4 Guia para responder quest˜oes na lista de discuss˜ao
Se vocˆe considerar que sua respota possa ter um amplo interesse, vocˆe pode querer post´a-la
para a lista de mensagens em vez de responder diretamente para a pessoa que perquntou.
Tente deixar sua resposta da forma mais gen´erica poss´
ivel para que outras pessoas al´em
da que postou a pergunda possam se beneficiar dela. Quando vocˆe postar para a lista, por
favor tenha certeza que sua resposta n˜ao ´e uma r´eplica de uma resposta anterior.
Tente resumir a parte essencial da quest˜ao na sua resposta, n˜ao se sinta obrigado a citar a
mensagem original inteira.
Por favor n˜ao poste mensagens a partir de seu browser com o modo HTML ligado! Muitos
usu´arios n˜ao leem e-mail com browser!
1.3 Licenciamento e Suporte do MySQL
Esta se¸ao descreve o suporte MySQL e termos de licenciamento:
Os direitos autorais em que o MySQL ´e distribu´
ido (see hundefinedi[Copyright],
page hundefinedi)
Exemplos de situa¸oes ilustrando onde uma licen¸ca ´e necess´aria (see hundefinedi[Li-
censing examples], page hundefinedi)
38 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Custos de Suporte (see hundefinedi[Cost], page hundefinedi) e seus benef´
icios (see
hundefinedi[Support], page hundefinedi)
Custos do licenciamento comercial
1.3.1 Pol´
itica de licenciamento MySQL
Os termos formais da licen¸ca GPL podem ser encontradas em hundefinedi[GPL license],
page hundefinedi. Basicamente, nossa pol´
itica de licen¸cas e interpreta¸ao da GPL ´e desta
forma:
Perceba que vers˜oes mais antigas do MySQL ainda utilizam uma licen¸ca mais rsstrita.
Veja a documenta¸ao para aquela vers˜ao para maiores informa¸ces. Se vocˆe precisa de uma
licen¸ca MySQL comercial, porque sua aplica¸ao n˜ao se encaixa com a licen¸ca GPL, vocˆe
pode comprar uma em https://order.mysql.com
Para uso interno normal, o MySQL n˜ao custa nada. Voe n˜ao tem que nos pagar se n˜ao
quiser fazˆe-lo.
Uma licen¸ca ´e necess´aria se:
Se vocˆe unir um programa, que n˜ao ´e software livre, com c´odigo do MySQL server ou
clientes que tem o direito autoral baseado na GPL. Isto acontece por exemplo quando
vocˆe usa o MySQL como um servidor embutido nas suas aplica¸oes ou quando vocˆe
adiciona extens˜oes n˜ao livres para o servidor MySQL. Neste caso, sua aplica¸ao/c´odigo
ir´a tamb´em se tornar GPL atrav´es do esquema GPL que age como um virus. Licen-
ciando o servidor MySQL da MySQL AB sobre uma licen¸ca comercial vocˆe ir´a evitar
este problema. Veja http://www.gnu.org/copyleft/gpl-faq.html.
Voe tem uma aplica¸ao comercial que trabalha SOMENTE com o MySQL e distribui
a aplica¸ao com o servidor MySQL. Isto acontece porque vemos isto como uma uni˜ao
mesmo se ´e feito atrav´es da rede.
Voe tem uma distribui¸ao do MySQL e vocˆe n˜ao fornece o c´odigo fonte para sua c´opia
do servidor MySQL, como ´e definido na licen¸ca GPL.
N˜
AO seria necess´aria uma licen¸ca se:
ao ´e necess´ario uma licen¸ca para incluir o c´odigo cliente em programas comerciais.
A parte cliente do MySQL ´e licenciada com a LGPL GNU Library General Public
License. O programa cliente de comandos de linha mysql inclue c´odigo da biblioteca
readline que est´a na GPL.
Se a forma que vocˆe usa o MySQL n˜ao necessitar a licen¸ca, mas vocˆe gosta do MySQL
e quer promover e encorajar o desenvolvimento, vocˆe certamente ser´a bem vindo para
comprar uma licen¸ca ou suporte do MySQL.
Se vocˆe usa o MySQL num contexto comercial no qual obtem lucro com seu uso, n´os
pedimos que vocˆe ajude o desenvolvimento do MySQL, comprando algum n´
ivel de
suporte. os sentimos que se o MySQL ajuda seu neg´ocio, ´e razo´avel pedir `a vocˆe
que ajude o MySQL. (De outra forma, se vocˆe nos pergutar questˆoes de suporte, vocˆe
ao estar´a somente usando de gra¸ca uma coisa em que colocamos muito trabalho, mas,
tamb´em estar´a pedindo para n´os fornecermos suporte gratu´
ito.)
Para circunstˆancias em que uma licen¸ca MySQL ´e necess´aria, vocˆe precisa de uma licen¸ca
para cada m´aquina que executar o servidor mysqld. Entretanto, uma m´aquina com v´arios
Chapter 1: Informa¸oes gerais sobre o MySQL 39
processadores conta como uma m´aquina ´unica, e n˜ao existem restri¸c˜oes sobre o n´umero de
servidores MySQL que executam em uma m´aquina ou no n´umero de clientes conectados
simultˆaneamente a um servidor executado naquela m´aquina!
Se vocˆe tiver alguma duvida se uma licen¸ca ´e necess´aria ou n˜ao para seu uso particular do
MySQL, por favor leia isto de novo e contate-nos. See hundefinedi[Contact information],
page hundefinedi.
Se vocˆe necessita de uma licen¸ca MySQL, o modo mais f´acil para pagar por ele ´e usar o for-
mul´ario de licen¸ca no servidor securo da MySQL em https://order.mysql.com/. Outras
formas de pagamento s˜ao discutidas em hundefinedi[Payment information], page hunde-
finedi.
1.3.2 Direitos autorais usados no MySQL
Existem v´arios direitos autorais diferentes na distribui¸ao do MySQL:
1. O c´odigo fonte espec´
ifico necess´ario para construir a biblioteca mysqlclient ´e licen-
ciada sobre a LGPL e programas no diret´orio ‘client ´e GPL. Cada arquivo tem um
cabcalho que mostra qual direito autoral ´e usado para aquele arquivo.
2. A biblioteca cliente e a (GNU getopt ao cobertas pela “GNU LIBRARY GENERAL
PUBLIC LICENSE.” See hundefinedi[LGPL license], page hundefinedi.
3. Algumas partes da fonte (a biblioteca regexp ao cobertas pelos direitos autorais no
estilo de Berkeley.
4. Todas as fontes no servidor e a biblioteca (GNU readline ´e coberta pela “GNU GEN-
ERAL PUBLIC LICENSE.” See hundefinedi[GPL license], page hundefinedi. Isto
tamb´em est´a dispon´
ivel no arquivo ‘COPYING’ nas distribui¸c ˜
Oes.
Um objetivo ´e que a biblioteca cliente SQL deve ser livre o bastante que seja poss´
ivel
adicionar suporte MySQL em produtos comerciais sem uma licen¸ca. Para esta raz˜ao, n´os
escolhemos a licen¸ca LGPL para o c´odigo cliente.
Isto significa que vocˆe pode usar o MySQL gratuitamente com qualquer programa que use
qualquer tipo de licen¸ca livre. O MySQL ´e tamb´em gr´atis para a utiliza¸ao por qualquer
usu´ario final para seu uso pr´oprio ou dentro da empresa.
Entretanto, se vocˆe usa o MySQL para alguma coisa importante, poder˜a querer ajudar a
segurar seu desenvolvimento comprando licen¸cas ou contrato de suporte. See hundefinedi
[Support], page hundefinedi.
1.3.2.1 Poss´
iveis altera¸oes futuras dos direitos autorais
A vers˜ao 3.22 do MySQL continua usando uma licen¸ca mais restrita. Veja a documenta¸ao
para aquela vers˜ao para maiores informa¸oes.
1.3.3 Exemplos de situa¸oes de licenciamento
Esta se¸ao descreve algumas situa¸oes ilustrando se vocˆe deve ou n˜ao licenciar o servidor
MySQL. Geralmente estes exemplos envolvem o fornecimento do MySQL como uma parte
integral do produto.
40 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Perceba que uma licen¸ca ´unica do MySQL cobre qualquer n´umero de CPUs e servidores
mysqld em uma m´aquina! ao existe limite artificial no n´umero de clientes que conectam
ao servidor em nenhum caso.
1.3.3.1 Vendendo produtos que usam o MySQL
Para determinar se vocˆe precisa ou n˜ao de uma licen¸ca MySQL quando vender sua aplica¸ao,
vocˆe deve se perguntar se a sua aplica¸ao ´e dependente no uso do MySQL e se voe inclui
ou n˜ao o servidor MySQL com seu produto. Existem diversos casos a considerar:
Sua aplica¸ao necessita do MySQL para funcionar corretamente ?
Se seu produto necessita do MySQL, vocˆe precisa de uma licen¸ca para qualquer m´aquina
que executa o servidor mysqld. Por exemplo, se vocˆe desenvolveu sua aplica¸ao sobre o
MySQL, enao vocˆe realmente criou um produto comercial que necessita do mecanismo,
enao precisa de uma licen¸ca.
Se a sua aplica¸ao n˜ao necessita do MySQL, vocˆe n˜ao precisa obter uma licen¸ca. Por
exemplo, se o uso do MySQL apenas adiciona alguns novos recursos opcionais para seu
produto (como gerar log para um banco de dados em vez de simplesmente usar um
arquivo texto), ela deve cair no uso normal, e uma licen¸ca n˜ao ´e necess´aria.
Em outras palavras, vocˆe precisa de uma licen¸ca se vocˆe vender um produto desen-
volvido para ser usado especificamente com o MySQL ou que necessita do servidor
MySQL para funcionar completamente. Isto ´e verdadeiro se vocˆe fornecer ou n˜ao o
MySQL para seu cliente como parte da distribui¸ao de seu produto.
Ela tamb´em depende do que vocˆe ir´a fazer pelo cliente. Voe planeja fornecer a seu
cliente instru¸oes detalhadas sobre como instalar o MySQL com seu software? Ent˜ao
seu produto pode ser contingente no uso do MySQL; se sim, ser´a necess´aria a com-
pra de uma licen¸ca. Se vocˆe est´a simplesmente amarrando em um banco de dados
que vocˆe espera j´a estar instalado na ´epoca em que seu software foi comprado, ent˜ao
possivelmente n˜ao precisa de uma licen¸ca.
1.3.3.2 Servi¸cos ISP MySQL
Provedores de servi¸co de Internet (ISPs) geralmente hospedam servidores MySQL para seus
clientes. Com a licen¸ca GPL isto n˜ao necessita de uma licen¸ca.
Por outro lado, n´os encorajamos as pessoas a usar ISPs que possuem suporte MySQL, isto
dar´a a eles a confian¸ca de que se eles tiverem algum problema com a sua instala¸ao do
MySQL, seu ISP poder´a resolver o problema para eles (em alguns casos com a ajuda da
equipe de desenvolvimento MySQL).
Todos ISPs que desejam se manter atualizados devem se inscrever na nossa lista de men-
sagens announce para que eles possam ser notificados sobre assuntos que possam ser rele-
vantes para suas instala¸oes MySQL.
Perceba que se o ISP n˜ao tem uma licen¸ca para o MySQL, ele deve fornecer ao menos acesso
de leitura para a fontes da instala¸ao MySQL para que seus clientes posssam verificar se foi
corretamente corrigido.
Chapter 1: Informa¸oes gerais sobre o MySQL 41
1.3.3.3 Executando um servidor web usando o MySQL.
Se vocˆe usa o MySQL em conjunto com um servidor Web no Unix, n˜ao existe necessidade
de pagar para uma licen¸ca.
Isto ´e verdade mesmo se vocˆe executa um servidor Web Comercial que usa MySQL, porque
vocˆe n˜ao estar´a vendendo uma vers˜ao do MySQL embutida. Entretanto, neste caso n´os
gostariamos que vocˆe comprasse suporte MySQL. Porque a MySQL estar´a ajudando a sua
empresa.
1.3.4 Custos de licenciamento e suporte do MySQL
Nossa lista atual de pre¸cos para licen¸cas ´e acessada abaixo. Para fazer uma compra, por
favor visitehttps://order.mysql.com/.
Se vocˆe pagar com cart˜ao de cr´edito, a moeda ´e EURO (European Union Euro) ent˜ao os
pre¸cos podem ser um pouco diferentes.
N´umero de Licen¸cas Por c´opia
1-9 230 EURO
10-24 138 EURO
25-49 117 EURO
50-99 102 EURO
100-249 91 EURO
250-499 76 EURO
500-999 66 EURO
Para um alto volume de compras (OEM), por favor, contate: sales@mysql.com.
Para compras OEM, vocˆe deve agir como o intermedi´ario para eventuais problemas ou
requisi¸oes de seus usu´arios. os tamb´em solicitamos que os clientes OEM tenham pelo
menos uma contrato extendido de suporte. Note que as licen¸cas OEM somente s˜ao aplicadas
para produtos onde o usu´ario n˜ao tem acesso direto ao servidor MySQL (Sistema embutido).
Em outras palavras, o servidor MySQL deve ser usado com a aplica¸ao que foi fornecida
por vocˆe.
Se vocˆe possui um produto de grande vendagem e baixa margem de lucro, vocˆe pode sempre
discutir conosco sobre outros termos (por exemplo, um percentual do pre¸co de venda). Se
´e seu caso, por favor informe seu produto, pre¸co, mercado e qualquer informa¸ao que possa
ser relevante.
Uma licen¸ca paga n˜ao ´e um acordo de suporte e inclui suporte m´
inimo. Isto significa que n´os
tentamos responder qualquer quest˜ao relevante. Se a resposta existe na documenta¸ao, n´os
iremos direcion´a-lo para a se¸ao apropriada. Se vocˆe n˜ao comprou uma licen¸ca ou suporte,
provavelmente n˜ao iremos respondˆe-lo.
Se vocˆe descobrir o que consideramos de um bug real, iremos corrig´
i-lo de qualquer maneira.
Mas se vocˆe paga pelo suporte iremos notific´a-lo sobre o estado da corre¸c˜ao em vez de apenas
consert´a-lo em um release posterior.
Suporte mais completo ´e vendido separadamente. Descri¸oes do que cada n´
ivel de suporte
oferece ´e fornecido em hundefinedi[Support], page hundefinedi. Custos para os v´arios tipos
de suporte comercial s˜ao vistos abaixo. Os pre¸cos dos n´
iveis de suporte est˜ao em EURO
(European Union Euro). Um EURO equivale algo em torno de 1.06 USD.
42 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Tipo de suporte Custo por ano
Suporte b´asico por e-mail. See hundefinedi
[Basic email support], page hundefinedi.
EURO 200
Suporte extendido por e-mail See hundefinedi
[Extended email support], page hundefinedi.
EURO 1000
Suporte com Login See hundefinedi[Login
support], page hundefinedi.
EURO 2000
Suporte extendido com Login See hundefinedi
[Extended login support], page hundefinedi.
EURO 5000
Suporte telefˆonico See hundefinedi[Telephone
support], page hundefinedi.
EURO 12000
Voe pode atualizar de qualquer n´
ivel baixo de suporte para um n´
ivel mais alto pela
diferen¸ca de pre¸co entre os dois n´
iveis.
os tamb´em fornecemos suporte telefˆonico (na maioria suporte emergencial mas tamb´em
suporte 24/7). Esta op¸ao de suporte, entretanto, ao tem um pre¸co fixo e ´e negociado
para caso a caso. Se vocˆe tem interesse nesta op¸ao envie um email para sales@mysql.com
e diga-nos sobre suas necessidades.
Entenda que como nossa equipe de vendas ´e muito ocupada, ela pode tomar algum tempo
at´e que sua requisi¸ao seja atentida. Nosso pessoal de suporte entretanto sempre atender´a
prontamente `as quest˜oes de suporte!
1.3.4.1 Informa¸oes de pagamento
Atualmente podemos receber pagamento em conta, cheques ou cart˜oes de cr´edito.
Pagamentos podem ser feitos `a:
Postgirot Bank AB
105 06 STOCKHOLM, SWEDEN
MySQL AB
BOX 6434
11382 STOCKHOLM, SWEDEN
Endere¸co SWIFT : PGSI SESS
umero da conta: 96 77 06 - 3
Especifique: licen¸ca e/ou suporte, seu nome e endere¸co de e-mail.
Na Europa e Jap˜ao podem ser usados o EuroGiro (que deve ser mais barato) para a mesma
conta.
Se vocˆe deseja pagar com cheque, fa¸ca-o nominal `a “MySQL Finland AB” e envie-o para o
endere¸co abaixo:
MySQL AB
BOX 6434, Torsgatan 21
11382 STOCKHOLM, SWEDEN
Se vocˆe deseja pagar com cart˜ao de cr´edito pela Internet, pode usar Formul´ario seguro de
licen¸cas da MySQL AB.
Voe pode tamb´em imprimir uma c´opia do formul´ario de licen¸cas, preenchˆe-lo e envi´a-lo
por fax para:
Chapter 1: Informa¸oes gerais sobre o MySQL 43
+46-8-729 69 05
Se vocˆe desejar que n´os lhe cobremos, pode usar o formul´ario de licen¸cas e escrever “bill
us” no campo de comenario. Pode tamb´em enviar uma mensagem para sales@mysql.com
(ao mysql@lists.mysql.com!) com as informa¸oes de sua empresa e pedir para que n´os
envie a cobran¸ca.
1.3.4.2 Informa¸oes para Contato
Para licenciamento comercial, por favor contate a equiope de licenciamento do MySQL.
O m´etodo mais preferido ´e enviar um e-mail para licensing@mysql.com. Envios de Fax
tamb´em ´e poss´
ivel mas pode demorar mais (Fax +46-8-729 69 05).
Se vocˆe representa uma empresa que est´a interessada em ter parcerias com a MySQL, por
favor envie um e-mail para partner@mysql.com.
Por enquanto, para respostas precisas para quest˜oes t´ecnicas sobre o MySQL voe deve
comprar um de nossos contratos de suporte. O Suporte ao MySQL ´e fornecido pelos desen-
volvedores do MySQL portanto a qualidade de atendimento ´e extremamente alta.
Se vocˆe est´a interessado em colocar um banner de an´uncio em nosso site Web, envie um
e-mail para advertising@mysql.com.
Se estiver interessado em algum dos empregos listados em nossa se¸ao empregos, por favor
envie um e-mail para jobs@mysql.com.
Para discuss˜oes gerais entre nossos usu´arios, dirija sua aten¸ao para a lista de mensagens
apropriada.
Para solicita¸oes de informa¸oes gerais, envie e-mail para info@mysql.com.
Para quest˜oes ou comenarios sobre os trabalhos ou conte´udo de nosso site Web, envie e-mail
para webmaster@mysql.com.
1.3.5 Tipos de suporte comercial
Todos os detalhes a seguir fazem parte de todas op¸oes de suporte:
O suporte ´e por ano.
Corrigiremos, ou fornecemos uma forma razo´avel de contornar a situa¸ao para qualquer
bug persistente.
Iremos concentrar um esfor¸co razo´avel para encontrar e corrigir qualquer outro erro
relacionado ao MySQL.
Quanto maior o n´
ivel do contrato de suporte, maior ser´a o esfor¸co para encontrar uma
solu¸ao para seus problemas.
Os seguintes itens fazem parte de todos contratos de suporte exceto do suporte b´asico
por email:
Qualquer coisa n˜ao relacionadas a erros, como ajudar a otimizar suas queries ou seus
sitema, extendendo o MySQL com novas funcionalidades, etc., cobramos 200 EU-
ROs/hora. que ´e deduzido de seu contrato de suporte. Em outras palavras, se vocˆe
tem suporte de login (2000 EURO) pode esperar que trabalharemos por volta de 10
horas para ajudar a vocˆe com coisas deste tipo.
44 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1.3.5.1 Suporte b´asico por E-mail
Suporte b´asico por e-mail ´e uma op¸ao de suporte muito barata e deve ser entendida mais
como um meio de apoiar o desenvolvimento do MySQL do que como uma op¸ao real de
suporte. os da MySQL fornecemos v´arios suportes grat´uitos em todas as listas diferentes
do MySQL, e o dinheiro que obtemos com o suporte b´asico por e-mail ´e amplamente usado
para tornar isto poss´
ivel.
Neste n´
ivel de suporte, as listas de mensagens do MySQL s˜ao m´etodos preferidos de
comunica¸ao. Quest˜oes normalmente devem ser enviadas para a lista de mensagens
principal (mysql@lists.mysql.com) ou uma de nossas listas regulares (por exemplo,
win32@lists.mysql.com para quest˜oes relacionadas ao MySQL no windows), como outra
pessoa pode ter experimentado o mesmo e resolvido o mesmo problema que vocˆe tem. See
hundefinedi[Asking questions], page hundefinedi.
Entretando, comprando suporte b´asico por e-mail, vocˆe tamb´em tem acesso ao endere¸co
de suporte mysql-support@mysql.com, que ao ´e dispon´
ivel como parte do suporte
m´
inimo que vocˆe obtˆem comprando uma licen¸ca do MySQL. Isto significa que para
quest˜oes especialmente cr´
iticas, vocˆe tamb´em pode enviar a sua mensagem para
mysql-support@mysql.com. (Se a mensagem conter dados sens´
iveis, vocˆe deve postar
somente para mysql-support@mysql.com.)
LEMBRE-SE! de sempre incluir seu n´umero de registro e data de expira¸ao quando vocˆe
enviar uma mensagem para mysql-support@mysql.com.
Perceba que se vocˆe encontrou um bug cr´
itico e repetitivo e seguiu as regras da se¸ao do
manual de como relatar erros e envi´a-los para bugs@lists.mysql.com, prometemos tentar
corrig´
i-lo assim que poss´
ivel, sem levar em considera¸ao seu n´
ivel de suporte! See hunde-
finedi[Bug reports], page hundefinedi.
Suporte b´asico por e-mail inclui os seguintes tipos de servi¸co:
Se sua d´uvida j´a est´a solucionada no manual, iremos inform´a-lo da se¸ao correta em
que vocˆe pode achar a resposta. Se a resposta n˜ao est´a no manual, n´os iremos apontar
vocˆe na dire¸ao certa para resolver seu problema.
os garantimos uma resposta para suas mensagens de e-mail. O que n˜ao garantimos
´e que podemos resolver qualquer problema, pelo menos vocˆe receber´a uma resposta se
pudermos lhe contactar em seu e-mail.
Iremos ajudar com problemas inesperados quando vocˆe instalar o MySQL de uma
distribui¸ao bin´aria em plataformas suportadas. Este n´
ivel de suporte n˜ao cobre a
instala¸ao do MySQL de uma distribui¸ao fonte. Plataformas suportadas s˜ao aque-
las que j´a s˜ao conhecidas em que o MySQL funciona. See hundefinedi[Which OS],
page hundefinedi.
os iremos ajud´a-lo com bugs e recursos em falta. Qualquer bugs encontrados s˜ao
corrigidos no pr´oximo release do MySQL. Se o bug ´e cr´
itico para vocˆe, enviaremos um
e-mail com um patch logo que o bug for corrigido. Bugs Cr´
iticos sempre tem prioridade
alta para n´os e garantimos que ele ser´a corrigido logo que poss´
ivel.
Suas sugest˜oes para favorecer o desenvolvimento do MySQL ser˜ao levadas em con-
didera¸ao. Obtendo o suporte por email vocˆe j´a est´a ajudando o desenvolvimento do
MySQL. Se vocˆe desejar mais integra¸ao, atualize para um n´
ivel mais alto do suporte.
Chapter 1: Informa¸oes gerais sobre o MySQL 45
Se vocˆe deseja que n´os ajudemos a otimizar seu sistema, deve atualizar para um n´
ivel
mais alto de suporte.
1.3.5.2 Suporte extendido por E-mail
O suporte extendido por e-mail inclui todos os ´
itens do suporte b´asico por e-mail com estas
vantagens:
Seu e-mail ser´a atendido antes dos emails dos usu´arios do suporte b´asico e usu´arios n˜ao
registrados.
Suas sugest˜oes para o favorecimento do desenvolvimento do MySQL receber˜ao forte
considera¸ao. Extens˜oes simples que fazem parte dos objetivos b´asicos do MySQL s˜ao
implementados em poucos dias. Obtendo o suporte extendido por e-mail vocˆe estar´a
ajudando e contribuindo ao desenvolvimento do MySQL.
Situa¸oes t´
ipicas que s˜ao cobertas pelo suporte extendido por e-mail:
Iremos responder e (com raz˜ao) resolver quest˜oes relativas a poss´
iveis bugs no
MySQL. Logo que um bug for encontrado e corrido, vocˆe receber´a a corre¸ao.
Ajudaremos com problemas inesperados quando vocˆe instalar o MySQL de uma
distribui¸ao fonte ou bin´aria em plataformas suportadas.
Respoderemos quest˜oes sobre recursos n˜ao dispon´
iveis e ofereceremos dicas de
como contornar tais situa¸oes.
Forneceremos dicas de como otimizar o mysqld para sua situa¸ao.
Ser´a permitido que vocˆe influencie a prioridade de ´
itens na lista de coisas `a fazer. See
hundefinedi[TODO], page hundefinedi. Isto ir´a assegurar que os recursos que vocˆe
realmente necessita ser˜ao implementados logo que poss´
ivel.
1.3.5.3 Suporte por Login
O Suporte por Login inclui todos os detalhes citados no suporte extendido por e-mail com
estes acr´escimos:
Suas mensagens ser˜ao tratadas antes dos emails do usuarios do suporte extendido por
email.
Suas sugest˜oes para o favorecimento do desenvolvimento do MySQL receber˜ao forte
considera¸ao. Extens˜oes realistas que podem ser implementadas em poucas horas e
que ifazem parte dos objetivos b´asicos do MySQL ser˜ao implementadas assim que
poss´
ivel.
Se vocˆe possuir um problema muito espec´
ifico, podemos acessar remotamente seu sis-
tema para resolver seu problema “no local.”
Como qualquer outro fornecedor de bancos de dados, n˜ao podemos garantir que pode-
mos recuperar dados de tabelas danificadas, mas se o pior acontecer, podemos ajudar
a recuperar o que for poss´
ivel. O MySQL prova ser muito est´avel, mas qualquer coisa
´e poss´
ivel devidas as circustancias que v˜ao al´em de nosso controle (por exemplo, se seu
sistema travar ou algu´em finalizar o servidor executando um comando kill -9).
Forneceremos ajuda nas otimiza¸oes de seu sistema e queries.
46 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Voe estar´a apto a contactar um desenvolvedor MySQL (moderadamente) e discutir
seus problemas relacionados ao MySQL. Esta op¸aoi, entretanto, deve somente ser us-
ada como um ´ultimo recurso durante uma emergˆencia caso falharmos para compreender
o problema por email. Para deixar mais eficiente o uso de nosso tempo precisamos an-
tecipadamente saber de todos os fatos sobre o problema, antes de falarmos no telefone,
para trabalhar da maneira mais eficiente poss´
ivel na solu¸ao do problema.
1.3.5.4 Suporte extendido por Login
Suporte extendido por login inclui todos os ´
itens do suporte de Login com as seguintes
vantagens:
Seu e-mail tem a mais alta prioridade poss´
ivel.
Examinaremos ativamente seu sistema e vamos ajudar a otimiz´ar-lo e suas queries.
Podemos tamb´em otimizar e/ou extender o MySQL para melhor encaixar em suas
necessidades.
Voe pode tamb´em requisitar extens˜oes especiais especiais para vocˆe. Por exemplo:
mysql> select MINHA_FUNCAO(col1,col2) from tabela;
Forneceremos uma distribui¸ao bin´aria de todos releases importantes do MySQL para
seu sistema, assim que tivermos uma conta em um sistema similar. No pior caso,
podemos solicitar acesso ao seu sistem para criar uma distribui¸ao bin´aria.
Se vocˆe puder fornecer acomoda¸oes e pagar por transporte, podemos at´e mesmo enviar
um desenvolvedor MySQL para visit´a-lo e oferecer ajudar com seus problemas. Suporte
extendido por Login lhe d´a o direito de um encontro por ano. mas somos muito flex´
iveis
para com nossos clientes! Se a visita demorar 16 horas ou mais, as primeiras 8 horas
ao ser˜ao cobradas. Para as 8 horas seguintes, vocˆe ser´a cobrado com uma taxa que ´e
pelo menos 20% menor do que os valores padr˜oes.
1.3.5.5 Suporte Telefˆonico
Suporte telefˆonico fornece todos os detalhes listados no suporte extendido por login com os
seguintes complementos:
Forneceremos a vocˆe uma p´agina web dinˆamica exibindo a lista atual de desenvolvedores
MySQL que pode ajud´a-lo por telefone quando vocˆe passar por um problema cr´
itico.
Para problemas n˜ao cr´
iticos, vocˆe pode solicitar um desenvolvedor MySQL para re-
tornar a liga¸ao em at´e 48 horas para discutir quest˜oes relacionados ao MySQL.
1.3.5.6 Suporte para outros manipuladores de tabela
Para obter suporte para tabelas BDB ou tabelas InnoDB vocˆe deve pagar uma taxa adicional
de 30% no pre¸co padr˜ao do suporte para cada um dos manipuladores de tabelas que vocˆe
desejar acrescentar no suporte.
os na MySQL AB iremos ajud´a-lo a crir um relat´orio correto de bugs para o manipulador
de tabelas e submetˆe-lo aos desenvolvedores da tabela espec´
ifica. Tamb´em iremos fazer o
aximo para garantir que vocˆe ir´a obter uma resposta ou solu¸ao em tempo dos desen-
volvedores do manipulador de tabelas.
Chapter 1: Informa¸oes gerais sobre o MySQL 47
Mesmo se estivermos muito convencidos que podemos resolver a maioria dos problemas de
uma maneira precisa, n˜ao podemos garantir uma solu¸ao r´apida para quaisquer problemas
que vocˆe possa ter com os diferentes manipuladores de tabelas. Iremos entretanto fazer o
melhor poss´
ivel para ajud´a-lo a ter seu problemas resolvidos.
1.4 Qual compatibilidade aos padr˜oes o MySQL oferece ?
Esta se¸ao descreve como o MySQL relacina aos padr˜oes ANSI SQL. MySQL tem muitas
extens˜oes aos padr˜oes ANSI SQL, e aqui vocˆe descobrir´a quais s˜ao elas, e como us´a-las.
Voe ir´a tamb´em encontrar informa¸ao sobre falta de funcionalidade do MySQL, e como
trabalhar com algumas diferen¸cas.
1.4.1 Extens˜oes MySQL para o ANSI SQL92
O MySQL fornece algumas extens˜oes que vocˆe provavelmente n˜ao ir´a encontrar em alguns
bancos de dados SQL. Fique avisado que se vocˆe us´a-las, seu c´odigo pode n˜ao ser mais
port´avel para outros servidores SQL. Em alguns casos, vocˆe pode escrever c´odigo que inclui
extens˜oes MySQL, mas continua port´avel, usando comenarios da forma /*! ...*/. Neste
caso, o MySQL ir´a analisar e executar o c´odigo com o coment´ario como ir´a fazer com
qualquer outra instru¸ao MySQL, mas outros servidores SQL ir˜ao ignorar as extens˜oes.
Por exemplo:
SELECT /*! STRAIGHT_JOIN */ nome_campo FROM table1,table2 WHERE ...
Se vocˆe adicionar um n´umero de vers˜ao depois do ’!’, a sintaxe s´o ser´a executada se a
vers˜ao do MySQL ´e igual ou maior que o n´umero de vers˜ao usado:
CREATE /*!32302 TEMPORARY */ TABLE (a int);
O exemplo acima significa que se vocˆe tiver uma vers˜ao do MySQL 3.23.02 ou mais nova,
enao o MySQL ir´a usar a palavra-chave TEMPORARY
Extens˜oes MySQL s˜ao listadas abaixo:
Os tipos de campo MEDIUMINT,SET,ENUM e os diferentes tipos BLOB eTEXT.
Os atributos de campos AUTO_INCREMENT,BINARY,NULL,UNSIGNED eZEROFILL.
Todas compara¸oes de strings por padr˜ao s˜ao caso insensitivo, com classifica¸ao orde-
nada determinada pelo conjunto de caracteres corrente (ISO-8859-1 Latin1 por padr˜ao).
Se vocˆe n˜ao gosta disso vocˆe dever´a declarar suas colunas com o atributo BINARY ou
usar o operador BINARY, que fazendo com que as compara¸oes sejam feitas de acordo
com a ordem ASCII usada na m´aquina servidora do MySQL.
O MySQL mapeia cada banco de dados em um diret´orio sob o diret´orio de dados do
MySQL, e tabelas internamente num banco de dados para arquivos no diret´orio do
banco de dados.
Isto tem algumas implica¸oes:
Nomes de bancos de dados e tabelas s˜ao caso sensitivoo no MySQL em sistemas
operacionais que possuem o sistema de arquivos caso sensitivoo (como na maioria
dos sistemas Unix). See hundefinedi[Name case sensitivity], page hundefinedi.
Nomes de Bancos de dados, tabelas, ´
indices, campos ou apelidos pode come¸car
com um d´
igito (por´em n˜ao podem consistir somente de digitos).
48 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Voe pode usar comandos padr˜ao do sistemas para fazer backups, renomear, apagar
e copiar tabelas. Por exemplo, para renomear uma tabela, renomeie os arquivos
.MYD’, ‘.MYI’ e ‘.frm’. para o nome da tabela correspondente.
Em algumas instru¸oes SQL, vocˆe pode acessar tabelas de diferentes bancos de dados
com a sintaxe nome_bd.nome_tbl. Alguns servidores SQL fornecem a mesma fun-
cionalidade mas chamam isto de User space. O MySQL n˜ao suporta tablespaces como
em: create table ralph.my_table...IN minha_tablespace.
LIKE ´e permitido em campos num´ericos.
O uso de INTO OUTFILE eSTRAIGHT_JOIN em uma instru¸ao SELECT. See hundefinedi
[SELECT], page hundefinedi.
A op¸ao SQL_SMALL_RESULT em uma instru¸ao SELECT.
EXPLAIN SELECT para obter uma descri¸ao de como as tabelas s˜ao ligadas.
A utiliza¸ao de nomes de ´
indices, ´
indices em um prefixo de um campo, e uso de INDEX
ou KEY em uma instru¸ao CREATE TABLE. See hundefinedi[CREATE TABLE], page hunde-
finedi.
O uso de TEMPORARY ou IF NOT EXISTS com CREATE TABLE.
O uso de COUNT(DISTINCT lista) onde ’lista’ ´e maior que um elemento.
O uso de CHANGE nome_campo,DROP nome_campo, ou DROP INDEX,IGNORE ou RENAME
em uma instru¸ao ALTER TABLE. See hundefinedi[ALTER TABLE], page hundefinedi.
O uso de RENAME TABLE. See hundefinedi[RENAME TABLE], page hundefinedi.
Utiliza¸ao de m´ultiplas cl´ausulas ADD,ALTER,DROP, ou CHANGE em uma instru¸ao ALTER
TABLE.
O uso de DROP TABLE com as palavras-chave IF EXISTS.
Voe pode remover (drop) m´ultiplas tabelas com uma instru¸ao ´unica DROP TABLE.
A cl´ausula LIMIT da instru¸ao DELETE.
A cl´ausula DELAYED das instru¸oes INSERT eREPLACE.
A cl´ausula LOW_PRIORITY das instru¸oes INSERT,REPLACE,DELETE eUPDATE.
O uso de LOAD DATA INFILE. Em alguns casos essa sintaxe ´e compat´
ivel com o Oracle
LOAD DATA INFILE. See hundefinedi[LOAD DATA], page hundefinedi.
As intru¸oes ANALYZE TABLE,CHECK TABLE,OPTIMIZE TABLE, e REPAIR TABLE.
A instru¸ao SHOW. See hundefinedi[SHOW], page hundefinedi.
Strings podem ser fechadas pelo ‘"’ ou ‘’, n˜ao apenas pelo ‘’.
O uso do meta-caractere de escape ‘\’.
A instru¸ao SET OPTION. See hundefinedi[SET OPTION], page hundefinedi.
Voe n˜ao precisa nomear todos os campos selecionados na parte GROUP BY. Isto fornece
melhor performance para algumas consultas espec´
ificas, mas muito comuns. See hun-
definedi[Group by functions], page hundefinedi.
Pode ser especificado ASC eDESC com o GROUP BY.
Para tornar mais f´acil para usu´arios que venham de outros ambientes SQL, o MySQL
suporta apelidos (aliases) para v´arias fun¸oes. Por exemplo, todas fun¸oes de string
suportam as sintaxes ANSI SQL e ODBC.
Chapter 1: Informa¸oes gerais sobre o MySQL 49
O MySQL entende os operadores || e&& como ou(OR) e e(AND) logicos, como na
linguagem de programa¸ao C. No MySQL, || eOR ao sinˆonimos, assim como && e
AND. Devido a esta ´otima sintaxe, o MySQL n˜ao suporta o operador ANSI SQL para
concatena¸ao de strings ||; em vez disso, use o CONCAT(). Como CONCAT() aceita
arios argumentos, ´e f´acil converter o uso do operador || para MySQL.
CREATE DATABASE or DROP DATABASE. See hundefinedi[CREATE DATABASE], page hunde-
finedi.
O operador %´e um sinˆonimo para MOD(). Isto ´e, N % M ´e equivalente a MOD(N,M).%´e
suportado para programadores C e para compatibilidade com o PostgreSQL.
Os operadores =,<>,<= ,<,>=,>,<<,>>,<=>,AND,OR ou LIKE podem ser utilizados em
compara¸oes de campos a esquerda do FROM nas instru¸oes SELECT. Por exemplo:
mysql> SELECT col1=1 AND col2=2 FROM nome_tabela;
A fun¸ao LAST_INSERT_ID(). See hundefinedi[mysql_insert_id()], page hundefinedi.
Os operadores extendidos REGEXP eNOT REGEXP utilizados em express˜oes regulares.
CONCAT() ou CHAR() com um ou mais de dois argumentos. (No MySQL, estas fun¸oes
receber qualquer n´umero de argumentos.)
As fun¸oes BIT_COUNT(),CASE,ELT(),FROM_DAYS(),FORMAT(),IF(),PASSWORD(),
ENCRYPT(),md5(),ENCODE(),DECODE(),PERIOD_ADD(),PERIOD_DIFF(),TO_DAYS()
ou WEEKDAY().
Uso de TRIM() para cortar substrings. o ANSI SQL s´o suporta remo¸ao de caracteres
´unicos.
As fun¸oes do GROUP BY:STD(),BIT_OR() eBIT_AND().
Uso de REPLACE no lugar de DELETE + INSERT. See hundefinedi[REPLACE], page hunde-
finedi.
As instru¸oes FLUSH,RESET eDO.
A possibilidade de configurar vari´aveis em uma instru¸ao com :=:
SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS media FROM tabela_teste;
SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
1.4.2 Diferen¸cas do MySQL comparadas com o ANSI SQL92
os tentamos fazer com que o MySQL siguisse os padr˜oes ANSI SQL e o ODBC SQL, mas
em alguns casos, o MySQL faz algumas coisas de forma diferente:
-- ´e somente um comenario, se seguido de um espa¸co em branco. See hundefinedi
[Missing comments], page hundefinedi.
Para campos VARCHAR, expa¸cos extras s˜ao removidos quando o valor ´e armazenado.
See hundefinedi[Bugs], page hundefinedi.
Em alguns casos, campos CHAR ao alterados sem perguntas para o tipo de campo
VARCHAR. See hundefinedi[Silent column changes], page hundefinedi.
Privil´egios para uma tabela n˜ao s˜ao negadas automaticamente quando voe apaga uma
tabela. Voe deve usar explicitamente um REVOKE para negar privil´egios para uma
tabela. See hundefinedi[GRANT], page hundefinedi.
NULL AND FALSE ser˜ao interpretados como NULL e n˜ao como FALSE. Isto ´e porque ao
acreditamos que ´e uma boa coisa interpretar v´arias condi¸oes extras neste caso.
50 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1.4.3 Executando o MySQL no modo ANSI
Se vocˆe inicializa o mysqld com a op¸ao --ansi, o seguinte comportamento ´e alterado no
MySQL:
|| funciona para concatena¸ao de strings em vez de OR.
Voe pode ter qualquer n´umero de espa¸cos entre um nome de fun¸ao e o ‘(’. Isto faz
com que todos nomes de fun¸oes sejam tratadas como palavras reservadas.
"’ ser´a um caracter identificador (como o caracter aspas ‘’ do MySQL) e n˜ao um
caracter de string.
REAL ser´a um sinˆonimo para FLOAT no lugar de um sinˆonimo de DOUBLE.
O n´
ivel de isolamento padr˜ao de um transa¸ao ´e SERIALIZABLE. See hundefinedi[SET
TRANSACTION], page hundefinedi.
Isto ´e o mesmo que usar --sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT, ANSI_
QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY.
1.4.4 Funcionalidades perdidas no MySQL
As seguintes funcionalidades n˜ao est˜ao presntes na vers˜ao atual do MySQL. Para uma
lista priorizada indicando quando novas extens˜oes ser˜ao adicionadas ao MySQL vocˆe deve
consultar A lista do `a fazer online(TODO List) . Esta ´e a ´ultima vers˜ao da lista do `a fazer
neste manual. See hundefinedi[TODO], page hundefinedi.
1.4.4.1 Sub-selects
Atualmente o MySQL suporta somente sub selects da forma INSERT ... SELECT ... e
REPLACE ... SELECT .... Entretanto, vocˆe pode usar a fun¸ao IN() em outros contextos.
Em alguns casos vocˆe pode reescrever a query sem uma sub selects:
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
Isto pode ser reescrito como:
SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
As consultas:
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2 where table1.id=table2.id);
Podem ser reescritas como:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL
Para consulta aninhadas mais complexas vocˆe pode, geralmente, criar tabelas tempor´arias
para armazenar as consultas aninhadas. Em alguns casos, entretanto, essa op¸ao n˜ao ir´a
funcionar. O mais frequentemente encontrado nestes casos surgem em instru¸oes DELETE,
para o qual padr˜ao SQL n˜ao suporta joins (exceto nas sub-selects). Para esta situa¸ao exis-
tem duas op¸oes dispon´
ivel enquanto consultas aninhadas forem suportadas pelo MySQL.
A primeira op¸ao ´e usar uma linguagem de programa¸ao procedural (como Perl ou PHP)
para enviar uma query SELECT para obter as chaves prim´arias dos registros a serem dele-
tados, e depois usar estes valores para construir uma instru¸ao DELETE DELETE FROM ...
WHERE ... IN (key1,key2, ...)).
Chapter 1: Informa¸oes gerais sobre o MySQL 51
A segunda op¸ao ´e usar o interactive SQL para construir uma s´erie de instru¸oes DELETE
automaticamente, usando a extens˜ao MySQL CONCAT() (em lugar do operador padr˜ao ||.
For example:
SELECT CONCAT(’DELETE FROM tab1 WHERE pkid = ’, tab1.pkid, ’;’)
FROM tab1, tab2
WHERE tab1.col1 = tab2.col2;
Voe pode colocar esta consulta em um arquivo script e redirecionar sua sa´
ida para o
interpretador de linha de comandos mysql, canalizando sua sa´
ida de volta a uma segunda
instˆancia do interpretador:
prompt> mysql --skip-column-names mydb < myscript.sql | mysql mydb
O MySQL 4.0 suporta dele¸ao de multi-tabelas que pode ser usado para apagar registros
de forma eficiente com base em informa¸oes de uma tabela ou mesmo de v´arias tabelas ao
mesmo tempo.
1.4.4.2 SELECT INTO TABLE
O MySQL ainda n˜ao suporta a extens˜ao SQL Oracle: SELECT ... INTO TABLE .... MySQL
suporta a sintaxe ANSI SQL INSERT INTO ... SELECT ..., que ´e basicamente a mesma
coisa. See hundefinedi[INSERT SELECT], page hundefinedi.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
tblTemp1.fldOrder_ID > 100;
De maneira alternativa, vocˆe pode usar SELECT INTO OUTFILE... ou CREATE TABLE ...
SELECT para resolver seu problema.
1.4.4.3 Transa¸oes
Como o MySQL, hoje em dia, suporta transa¸oes, a seguinte discuss˜ao s´o ´e v´alida se vocˆe
estiver usando os tipos de tabelas n˜ao transacionais. See hundefinedi[COMMIT], page hun-
definedi
Essa quest˜ao ´e normalmenta feita, pelos curiosos e cr´
iticos, “Por que o MySQL n˜ao ´e um
banco de dados transacional ?” ou “Por que o MySQL n˜ao suporta transa¸oes?”.
O MySQL tem feito uma descis˜ao consciente para suportar outro paradigma para integri-
dade de dados, “opera¸oes atˆomicas.” ´
E de nosso conhecimento e experiˆencia que opera¸oes
atˆomicas oferecem integridade igual ou melhor com performance muito mais eficiente. os,
apesar de tudo, apreciamos e entendemos o paradigma de bancos de dados transacionais e
planejamos, nas pr´oximas vers˜oes, introduzir tabelas com seguran¸ca transacional nos fun-
damentos de tabelas. os iremos dar a nossos usu´arios a possibilidade de decididir se eles
precisam da velocidade das opera¸oes atˆomicas ou se eles precisam usar recursos transa-
cionais na suas aplica¸oes.
Como s˜ao utilizados recursos do MySQL para manter de forma rigorosa a integridade e
como estes recursos se comparam com o paradigma transacional?
Primeiro, no paradigma transacional, se as suas aplica¸oes s˜ao escritas de uma forma que
´e dependente na chamada de “rollback” em vez de “commit” em situa¸oes cr´
iticas, enao
transa¸oes s˜ao mais convenientes. Al´em disso, transa¸oes asseguram que atualiza¸oes in-
acabadas ou atividades corrompidas n˜ao sejam executadas no banco de dados; o servidor
52 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
oferece uma oportunidade para fazer um rollback autom´atico e seu banco de dados ´e man-
tido.
O MySQL, na maioria dos casos, permite a vocˆe resolver potenciais problemas incluindo
simples conferˆencias antes das atualiza¸oes e executando scripts simples que conferem incon-
sistˆencias no banco de dados e, automaticamente, repara ou avisa caso isto ocorra. Perceba
que apenas usando o log do MySQL ou mesmo adicionando um log extra, pode-se corrigir
tabelas perfeitamente sem nenhuma perda de integridade.
Al´em disso, atualiza¸oes transacionais fatais podem ser reescritas para serem atˆomicas. De
fato podemos dizer que todos problemas de integridade que transa¸oes resolvem podem
ser feitas com LOCK TABLES ou atualiza¸oes atˆomicas, assegurando que vocˆe nunca ir´a ter
uma finaliza¸ao autom´atica da tabela, o que ´e um problema comum em bancos de dados
transacionais.
Nem mesmo transa¸oes podem prevenir todas as falhas se o servidor cair. Nestes casos
mesmo um sistema transacional pode perder dados. A diferen¸ca entre sistemas diferentes
´e apenas em qu˜ao pequeno ´e o lapso de tempo em que eles podem perder dados. Nenhum
sistema ´e 100% seguro, somente “seguro o suficiente.” Mesmo o Oracle, com reputa¸ao de
ser o mais seguro bancos de dados transacionais, tem relatos de algumas vezes perder dados
nestas situa¸oes.
Para estar seguro com o MySQL, vocˆe apenas deve fazer backups e ter o log de atualiza¸oes
ligado. Com isto vocˆe pode se recuperar de qualquer situa¸ao poss´
ivel com bancos de dados
transacionais. ´
E sempre bom ter backups, independente de qual banco de dados vocˆe usa.
O paradigma transacional tem seus benef´
icios e suas desvantagens. Muitos usu´arios e
desenvolvedores de aplica¸oes dependem da facilidade com a qual eles podem codificar
contornando problemas onde abortar parece ser, ou ´e necess´ario, e podem ter um pouco
mais de trabalho com o MySQL por terem que pensar diferente ou escrever mais. Se
vocˆe ´e novo no paradigma de opera¸oes atˆomicas ou tem mais familiaridade ou conforto
com transa¸oes, n˜ao acabe por concluir que o MySQL n˜ao tenha se preocupado com estes
assuntos. Confian¸ca e integridade est˜ao em nossas mentes. Estimativas recentes indicam
que existem mais de 1.000.000 de servidores mysqld operando atualmente, muitos dos quais
est˜ao em ambientes de produ¸ao. ao muito, muito raros os casos nos quais nossos usu´arios
perderam seus dados, e em quase todos os casos, erros dos usu´arios est˜ao envolvidos. Isto
´e, na nossa opini˜ao, a melhor prova da estabilidade e seguran¸ca do MySQL.
Ultimamente, em situa¸oes onde integridade ´e de grande importˆancia, as atuais cara-
cter´
isticas do MySQL permitem n´
iveis transacionais ou melhor confian¸ca e integridade.
Se vocˆe bloquear tabelas com LOCK TABLES todos as atualiza¸oes ir˜ao ser adiadas at´e qual-
quer verifica¸ao de integridade ser feita. Se vocˆe s´o obter um bloqueio de leitura (oposto ao
bloqueio de escrita), ent˜ao leituras e inser¸oes poder˜ao ocorrer. Os novos registros inseridos
ao poder˜ao ser visualizados por nenhum dos clientes que tiverem um bloqueio de LEITURA
at´e eles liberarem estes bloqueios. Com INSERT DELAYED vocˆe pode enfileirar inser¸oes em
uma fila local, at´e os bloqueios serem liberados, sem que o cliente prceise esperar pela
inser¸ao completar. See hundefinedi[INSERT DELAYED], page hundefinedi
“Atomico”, no sentido em que n´os mencionamos, n˜ao ´e m´agico. Significa apenas que vocˆe
pode estar certo que enquanto cada atualiza¸ao espec´
ifica est´a sendo executada, nenhum
outro usu´ario pode interferir com ela, e nunca haver´a um rollback autom´atico (que pode
acontecer em sistemas baseados em transa¸oes se vocˆe n˜ao tiver muito cuidado). O MySQL
Chapter 1: Informa¸oes gerais sobre o MySQL 53
tamb´em assegura que nunca ocorrer´a uma leitura suja. Voe pode encontrar alguns ex-
emplos de como escrever atualiza¸oes atˆomicas na se¸ao commit-rollbak. See hundefinedi
[Commit-rollback], page hundefinedi.
Estamos pensando muito sobre integridade e performance, e n´os acreditamos que nosso
paradigma de opera¸oes atˆomicas permitem tanto confian¸ca quanto uma performance ex-
tremamente alta, na ordem de tres a cinco vezes a velocidade do mais r´apido e mais op-
timizado dos bancos de dados transacionais. os n˜ao deixamos as transa¸oes porque s˜ao
muito dif´
iceis para serem feitas. A principal raz˜ao de trabalharmos com opera¸oes atˆomicas
ao inv´es de transa¸oes ´e que fazendo isto n´os podemos aplicar muitas otimiza¸oes de veloci-
dade que de outra forma n˜ao seria poss´
ivel.
Muitos de nossos usu´arios que tem a velocidade em mentee, n˜ao est˜ao muito preocupados
com transa¸oes. Para eles transa¸oes n˜ao s˜ao importantes. Para aqueles usu´arios que est˜ao
preocupados com ou tem curiosidade sobre transa¸oes no MySQL, existe um “MySQL
Way” como n´os citamos acima. Para aqueles que d˜ao mais importˆancia a seguran¸ca do que
velocidade, recomendamos o uso das tabelas BDB ou InnoDB para todos seus dados cr´
iticos.
See hundefinedi[Table types], page hundefinedi.
Nota final: Atualmente n´os estamos trabalhando em um esquema seguro de replica¸ao o
qual acreditamos ser melhor que qualquer sistema de replica¸ao comercial que conhecemos.
Este sistema ir´a trabalhar com confian¸ca sobre o paradigma de opera¸oes atˆomicas n˜ao-
transacional. Mantenha-se informado.
1.4.4.4 Stored Procedures e Triggers
Uma Stored Procedure ´e um conjunto de comandos SQL que podem ser compilados e
armazenados no servidor. Uma fez feito isso, os clientes n˜ao necessitam reescrever toda a
consulta mas podem fazer referˆencia `a stored procedure. Isto fornece melhor performance
porque a query necessita ser analisada pelo servidor somente uma vez, e necessita menos
informa¸ao para ser enviada entre o servidor e o cliente. Voe tamb´em pode elevar o n´
ivel
conceitual tendo bibliotecas de fun¸oes no servidor.
Um trigger ´e uma stored procedure que ´e chamado quando um evento em particular ocorre.
Por exemplo, vocˆe pode instalar uma stored procedure que ´e disparada toda vez que um
registro for apagado de uma tabela de transa¸oes que automaticamente apaga o cliente
correspondente de uma tabela de clientes quando todas as transa¸oes forem removidas.
A linguagem planejada atualizada ser´a apta a armazenar stored procedures mas sem trig-
gers. Trigger normalmente deixa tudo muito mais lento, mesmo consultas que n˜ao as uti-
lizam.
Para saber quando o MySQL ter´a stored procedures, consulte hundefinedi[TODO],
page hundefinedi.
1.4.4.5 Chaves Estrangeiras (Foreign Keys)
Note que as chaves estrangeiras no SQL n˜ao s˜ao usadas para ligar tabelas, mas na maioria
das vezes s˜ao usadas para verificar a integridade referencial. Se vocˆe deseja obter resultados
de m´ultiplas tabelas de uma instru¸ao SELECT, vocˆe pode fazer isto ligando tabelas:
SELECT * from table1,table2 where table1.id = table2.id;
54 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
See hundefinedi[JOIN], page hundefinedi. See hundefinedi[example-Foreign keys], page hun-
definedi.
A sintaxe FOREIGN KEY existe no MySQL somente para compatibilidade com os comandos
CREATE TABLE de outros fabricantes, ela n˜ao faz nada. A sintaxe FOREIGN KEY sem ON
DELETE ... ´e usada na maioria dos casos para documenta¸ao. Algumas aplica¸oes ODBC
podem usar isto para produzir cl´ausulas WHERE autom´aticas, mas ´e normalmente ignorada.
FOREIGN KEY ´e algumas vezes usado para verifica¸ao, por´em, esta verifica¸ao ´e desnecess´aria
na pr´atica se os registros s˜ao inseridos nas tabelas na ordem correta. O MySQL suporta
somente estas cl´ausulas porque algumas aplica¸oes dependem delas para existir (n˜ao levando
em considera¸ao se elas funcionam ou n˜ao).
No MySQL, vocˆe pode trabalhar contornando o problema do ON DELETE... ainda n˜ao im-
plementado, adicionando as instru¸oes DELETE apropriadas a aplica¸ao quando vocˆe apagar
registros de uma tabela que possui uma chave estrangeira. Na pr´atica isto ´e t˜ao r´apido (em
alguns casos, mais r´apido) e muito mais port´avel do que o uso de chaves estrangeiras.
No futuro pr´oximo, iremos extender a implementa¸ao de CHAVES ESTRANGEIRAS para que
ao menos a informa¸ao seja armazenada no arquivo de especif´
ica¸oes da tabela e possa ser
recuperada com mysqldump e ODBC. Em um est´agio posterior, n´os implementaremos as
chaves estrangeiras para aplica¸oes que n˜ao podem ser facilmente codificadas para ignor´a-la.
1.4.4.6 Raz˜oes para n˜ao usar chaves estrangeiras
Existem v´arios problemas com as chaves estrangeiras. ´
E at´e dif´
icil sabermos por onde
come¸car:
Chaves estrangeiras tornam a vida muito complicada porque suas defini¸oes devem ser
armazenadas em um banco de dados e, implemena-las pode acabar com a “gra¸ca” de
usar arquivos que podem ser movidos, copiados e removidos.
O impacto de velocidade ´e terr´
ivel em senten¸cas INSERT eUPDATE, neste caso, quase
todas as verifica¸oes de CHAVES ESTRANGEIRAS ao desnecess´arios, pois normalmente
inserimos registros nas tabelas corretas e na ordem correta.
Existe tamb´em uma necessidade de travar registros em v´arias tabelas quando estiver
atualizando apenas uma tabela, devido ao efeito cascata em todo no banco de dados. ´
E
muito mais r´apido primeiro apagar registros de uma tabela e posteriormente apag´a-los
das outras tabelas.
Voe n˜ao pode restaurar uma tabela apagando-a totalmente e depois restaurar os reg-
istros (de uma nova fonte ou de um backup).
Se vocˆe usa chaves estrangeiras, n˜ao poder´a remover e restaurar tabelas a n˜ao ser que
fa¸ca isto com muito cuidado em uma ordem muito espec´
ifica.
´
E muito f´acil fazer defini¸oes circulares “permitidas” que impossibilitam as tabelas de
recriar cada tabela com uma simples instru¸ao de cria¸ao mesmo se a defini¸ao funciona
e est´a em uso.
´
E muito f´acil de travar regras FOREIGN KEY ... ON DELETE quando estamos codificando
uma aplica¸ao. ao ´e raro ocorrer perda de muitas informa¸oes importantes devido
apenas a uma regra ON DELETE errada ou mal utilizada.
Chapter 1: Informa¸oes gerais sobre o MySQL 55
O ´unico aspecto interessante das CHAVES ESTRANGEIRAS ´e que ela d´a ao ODBC e alguns
outros programas clientes a habilidade de ver como a tabela ´e conectada e utiliz´a-la para
mostrar diagramas de conex˜ao e ajudar na cria¸ao de aplica¸oes.
MySQL logo ir´a armazenar defini¸oes de CHAVES ESTRANGEIRAS para que o cliente possa
pedi-la e receber uma resposta sobre como a conex˜ao original foi feita. O formato atual dos
arquivos ‘.frm’ n˜ao tem lugar para elas. Em um est´agio posterior n´os iremos implementar
as chaves estrangeiras para aplica¸oes que n˜ao podem ser codificadas para evit´a-las.
1.4.4.7 Views
MySQL ainda n˜ao suporta views, mas planejamos implemena-las em torno da vers˜ao 4.1.
Views geralmente s˜ao muito ´uteis para permitir aos usu´arios acessar uma s´erie de rela¸oes
como uma tabela (em modo leitura). arios bancos de dados SQL n˜ao permitem atualizar
nenhum registro em uma view, mas vocˆe tem que fazer as atualiza¸oes em tabelas separadas.
Como o MySQL ´e normalmente usado em aplica¸oes e sistemas web onde o autor da
aplica¸ao tem total controle no uso de bancos de dados, a maioria de nossos usu´arios n˜ao
consideram view muito importante. (pelo menos nenhum teve interesse suficiente para
financiar a implementa¸ao de views).
ao ´e necess´ario o uso de views em MySQL para restringir acesso aos campos j´a que o
MySQL tem um sistema de privil´egios bem sofisticado. See hundefinedi[Privilege system],
page hundefinedi.
1.4.4.8 ‘-- como o ´
inicio de um comenario
Outros bancos de dados SQL usam ‘--’ para iniciar comenarios. O MySQL usa ‘#’ como
o caractere para in´
icio de comenario, mesmo se a ferramenta de linha de comando mysql
remover todas linhas que come¸cam com ‘--’. Voe tamb´em pode usar o coment´ario no
estilo C /*isto ´e um coment´ario*/ com o MySQL. See hundefinedi[Comments], page hun-
definedi.
O MySQL vers˜ao 3.23.3 e superior suporta o estilo de coment´ario ‘--’ somente se o co-
menario for seguido por um caractere de espa¸co. Isto ocorre porque este estilo de co-
menario causou muitos problemas com queries SQL geradas automaticamente que usavam
algo como o c´odigo seguinte, onde automaticamente er´a inserido o valor do pagamento para
!pagamento!:
UPDATE nome_tabela SET credito=credito-!pagamento!
O que vocˆe acha que ir´a acontecer quando o valor de pagamento for negativo?
Como 1--1 ´e legal no SQL, n´os achamos terr´
ivel que ‘--’ signifique in´
icio de comenario.
No MySQL Vers˜ao 3.23 vocˆe pode, entretanto, usar: 1-- Isto ´e um coment´ario
A seguinte discuss˜ao somente interessa se vocˆe estiver executando uma vers˜ao do MySQL
inferior a vers˜ao 3.23:
Se vocˆe tem um programa SQL em um arquivo texto que contˆem comenarios ‘--’ vocˆe
dever´a usar:
shell> replace " --" " #" < arquivo-texto-com-coment´ario.sql \
| mysql banco-de-dados
No lugar de:
56 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shell> mysql banco-de-dados < arquivo-texto-com-comentario.sql
Voe tamb´em pode editar o pr´oprio arquivo de comandos alterando os comenarios ‘--
para ‘#’:
shell> replace " --" " #" -- arquivo-texto-com-comentario.sql
Desfa¸ca utilizando este comando:
shell> replace " #" " --" -- arquivo-texto-com-comentario.sql
1.4.5 Quais s˜ao os padr˜oes que o MySQL segue ?
Padr˜ao SQL92. N´
iveis ODBC 0-2.
1.4.6 Como lidar sem o COMMIT-ROLLBACK
A maioria dos textos a seguir aplicam-se somente para tabelas ISAM,MyISAM eHEAP. Se vocˆe
utilizar as tabelas transacionais (tabelas BDB ou InnoDB) em uma atualiza¸c˜ao, voe poder´a
utilizar COMMIT eROLLBACK no MySQL. See hundefinedi[COMMIT], page hundefinedi.
O problema com a manipula¸ao de COMMIT-ROLLBACK eficientemente com os tipos de tabelas
citadas acima ´e que seria necess´ario um layout de tabelas completamente diferente que o
MySQL usa hoje em dia. O tipo de tabela iria necessitar tamb´em de processos extras que
fizessem a limpeza autom´atica nas tabelas, e o uso de disco seria muito maior. Isto poderia
deixar esses tipos de tabelas 2-4 vezes mais lento que s˜ao hoje.
No momento, preferimos implementar a linguagem de servidor SQL (algo parecido com
stored procedures). Com isto, voe raramente precisaria usar o COMMIT-ROLLBACK. Isto
tamb´em traria uma performance muito melhor.
Loops que necessitam de transa¸oes normalmente podem ser codificados com a ajuda de
LOCK TABLES.Se vocˆe atualiza registros previamente determinados n˜ao h´aver´a necessidade
de se usar cursores.
os na TcX temos uma maior necessidade de um banco de dados realmente r´apido do que
um banco de dados 100% gen´erico. Assim que encontrarmos uma forma de implementar
esses recursos sem perda de performance, provavelmente o faremos. No momento, existem
arias coisas mais importantes a serem feitas. Verifique o TODO para saber quais as nossas
prioridades at´e o momento. (Clientes com alto n´
ivel de suporte podem alterar isto, enao
as prioridades podem ser alteradas.)
O problema atual ´e o ROLLBACK. Sem o ROLLBACK, pode-se fazer qualquer tipo de a¸c˜ao
COMMIT com LOCK TABLES. Para suportar ROLLBAK com os tipos de tabelas acima, o MySQL
teria que ser alterado para armazenar todos registros antigos que foram atualizados e re-
verter tudo para o ponto de partida se o ROLLBACK fosse utilizado. Para casos simples, isto
ao ´e dificil para implementar (o isamlog atual pode ser usado para este prop´osito), mas
seria muito mais dif´
icil de implementar ROLLBACK para ALTER/DROP/CREATE TABLE
Para evitar o uso do ROLLBACK, vocˆe pode usar a seguinte estrat´egia:
1. Usar LOCK TABLES ... para travar todas as tabelas que vocˆe pretende acessar.
2. Testar condi¸oes.
3. Atualizar se tudo estiver bem.
4. Usar UNLOCK TABLES para liberar suas travas.
Chapter 1: Informa¸oes gerais sobre o MySQL 57
Este m´etodo ´e, normalmente, muito mais r´apido do que usar transa¸oes com poss´
iveis
ROLLBACKs, mas nem sempre. A ´unica situa¸ao em que esta solu¸ao n˜ao se aplica ´e quando
algu´em mata as threads no meio de uma atualiza¸ao. Neste caso, todos bloqueios ser˜ao
liberados mas algumas atualiza¸oes podem n˜ao ter sido executadas.
Voe tamb´em pode utilizar fun¸oes para atualizar registros em uma ´unica opera¸ao. Voe
pode ter uma aplica¸ao muito eficiente utilizando as seguintes t´ecnicas:
Modificar campos relativos aos seus valores atuais.
Atualizar somentes aqueles campos que foram realmente alterados.
Por exemplo, quando estivermos fazendo atualiza¸oes em alguma informa¸ao de clientes,
atualizamos somente os dados do cliente que foram alterados e testamos somente aqueles
que n˜ao tiveram dados alterados ou dados que dependam dos dados alterados e que tenham
sido alterados comparados ao registro original. O teste para dados alterados ´e feito com a
cl´ausula WHERE na instru¸ao UPDATE. Se o registro n˜ao for atualizado, daremos ao cliente
uma mensagem: "Alguns dos dados que vocˆe alterou foi alterado por outro usu´ario". Ent˜ao
os mostramos o registro antigo e o novo registro na tela para que o usuario possa decidir
qual vers˜ao ele pode usar.
Isto fornece algo que ´e parecido com bloqueio de colunas mas bem melhor, porque s´o
atualizamos algumas das colunas, usando valores que s˜ao relativos ao seus valores atuais.
Isto significa que instru¸oes UPDATE se parecer˜ao com isto:
UPDATE nometabela SET pay_back=pay_back+’mudan¸ca relativa’;
UPDATE customer
SET
data_corrente=’data_corrente’,
endereco=’novo endereco’,
telefone=’novo telefone’,
dinheiro_ele_nos_deve=dinheiro_ele_nos_deve+’novo_dinheiro’
WHERE
id_cliente=id AND endereco=’endereco antigo’ AND telefone=’telefone antigo’;
Como podemos ver, esta forma ´e muito eficiente e funciona mesmo se outro cliente tiver
alterado os valores nas colunas pay_back ou dinheiro_ele_nos_deve.
Em alguns casos, usu´arios tem necessitado de ROLLBACK e/ou LOCK TABLES com o prop´osito
de gerenciar identificadores ´unicos para algumas tabelas. Isto pode ser tratado de forma
muito mais eficiente usando um campo AUTO_INCREMENT e tamb´em a fun¸ao SQL LAST_
INSERT_ID() ou a fun¸ao da API C mysql_insert_id(). See hundefinedi[mysql_insert_
id()], page hundefinedi.
Na MySQL AB, n´os nunca tivemos necessidade de bloqueio no n´
ivel de registros porque
os sempre fomos capaz de programar evitando-os. Alguns casos realmente precisam de
bloqueio de registros, mas s˜ao poucos. Se vocˆe deseja bloqueio de registros, vocˆe pode usar
um campo de sinaliza¸ao na tabela e fazer como se segue:
UPDATE nome_tabela SET row_flag=1 WHERE id=ID;
O MySQL retorna 1 para o n´umero de registros atingidos se o registro for encontrado e
row_flag a n˜ao tinha 1 no registro original.
Voe pode pensar como se o MySQL tivesse alterado a consulta acima para:
UPDATE nome_tabela SET row_flag=1 WHERE id=ID and row_flag <> 1;
58 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1.4.7 Erros conhecidos e deficiˆencias de design no MySQL
Os seguintes problemas s˜ao conhecidos e tem prioridade muito alta para serem corrigidos:
ANALYZE TABLE em uma tabela BDB pode, em alguns, casos inutilizar a tabela at´e que
se reinicie o servidor mysqld. Quando isto acontecer vocˆe ir´a ver o seguinte tipo de
erro no arquivo de erros do MySQL.
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
ao execute ALTER TABLE em uma tabela BDB em que vocˆe estiver executando
transa¸oes multi-instru¸oes n˜ao completadas. (A transa¸ao provavelmente ser´a
ignorada).
ANALYZE TABLE,OPTIMIZE TABLE eREPAIR TABLE podem causar problemas em tabelas
para as quais vocˆe estiver usando INSERT DELAYED.
Fazendo um LOCK TABLE .. eFLUSH TABLES .. ao garante que n˜ao existem transa¸oes
ao terminadas em progresso na tabela.
Tabelas BDB s˜ao um pouco lentas para abrir. Se vocˆe tiver v´arias tabelas BDB em um
banco de dados, gastar´a muito tempo para usar o cliente mysql no banco de dados se
vocˆe n˜ao estiver usando a op¸ao -A ou se vocˆe estiver usando rehash. Isto ´e percebido
principalmente quando vocˆe tiver um cache de tabelas grandes.
O protocolo de replica¸ao atual n˜ao pode lidar com LOAD DATA INFILE e caracteres de
termina¸ao de linha maiores que 1 caractere.
Os seguintes problemas s˜ao conhecidos e ser˜ao corrigidos na hora certa:
No momento MATCH funciona somente com instru¸oes SELECT.
Quando estiver usando SET CHARACTER SET, n˜ao ´e permitido usar caracteres especias
no nome do banco de dados, tabelas ou campos.
DELETE FROM merge_table usado sem WHERE ir´a apenas apagar o mapeamento para a
tabela, n˜ao apagando tudo nas tabelas mapeadas.
Voe n˜ao pode construir em outro diret´orio quando estiver utilizando MIT-pthreads.
Como isto necessitaria de altera¸oes na MIT-pthreads, n´os n˜ao estamos aptos a corrig´
i-
la.
BLOB valores n˜ao podem ser usados com confian¸ca em GROUP BY,ORDER BY ou
DISTINCT. Somente os primeiros bytes (padr˜ao 1024) max_sort_length ao usados
quando estiver comparando BLOBs nestes casos. Isto pode ser alterado com a op¸ao
-0 max_sort_lenght para mysqld. Uma forma de contornar este problema para
a maioria dos casos ´e usar a substring: SELECT DISTINCT LEFT(blob,2048) FROM
nome_tabela.
alculos s˜ao feitos com BIGINT ou DOUBLE (normalmente, ambos tem o tamanho de 64
bits). Depende da precis˜ao utilizada na fun¸ao. A regra geral ´e que fun¸oes bin´arias
ao feitas com precis˜ao BIGINT,IF eELT() com precis˜ao BIGINT ou DOUBLE e o resto
com precis˜ao DOUBLE. Devemos evitar o uso de valores sem sinal maiores que 63 bits
(9223372036854775807) para qualquer outra coisa al´em de campos bin´arios!
Todas os campos string, exceto campos do tipo BLOB eTEXTO tem, automaticamente,
todos os espa¸cos extras removidos quando recuperados. Para tipos CHAR, isto n˜ao tem
problema, e pode ser considerado como um recurso de acordo com o ANSI SQL92. O
problema ´e que no MySQL, campos VARCHAR ao tratados desta mesma forma.
Chapter 1: Informa¸oes gerais sobre o MySQL 59
Voe s´o pode ter at´e 255 colunas ENUM eSET em uma tabela.
safe_mysqld redireciona todas as mensagens de mysqld para o log mysqld. Um prob-
lema com isto ´e que se vocˆe executar o mysqladmin refresh para fechar e reabrir o
log, a stdout e a stderr continuam redirecionadas para o log antigo. Se vocˆe utiliza
--log extensivamente, dever´a editar o safe_mysqld para logar em ‘’hostname’.err
em vez de ‘’hostname’.log’; assim vocˆe pode facilmente utilizar o espa¸co do log antigo
apagando-o e executando mysqladmin refresh.
Em instru¸oes UPDATE, colunas s˜ao atualizadas da esquerda para a direita. Se vocˆe
referenciar a uma coluna atualizada, vocˆe ir´a obter o valor atualizado em vez do valor
original, por exemplo:
mysql> UPDATE nome_tabela SET KEY=KEY+1,KEY=KEY+1;
Isto atualiza KEY com 2no lugar de 1.
Voe n˜ao pode usar tabelas tempor´arias mais que uma vez na mesma query. Por
exemplo, a seguinte instru¸ao n˜ao funciona.
select * from tabela_temporaria, tabela_temporaria as t2;
RENAME ao funciona com tabelas tempor´arias (TEMPORARY).
O otimizador pode lidar com o DISTINCT de forma diferente se vocˆe estiver usando col-
unas ’escondidas’ em uma join ou n˜ao. Em uma join, colunas escondidas s˜ao contadas
como parte do resultado (mesmo se elas n˜ao s˜ao mostradas) enquanto que em queries
normais colunas escondidas n˜ao participam na compara¸ao DISTINCT. os provavel-
mente iremos alterar isto no futuro para nunca comparar as colunas escondidas quando
executando DISTINCT.
um exemplo disto ´e:
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id
DESC;
e
SELECT DISTINCT band_downloads.mp3id, FROM band_downloads,band_mp3
WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id
ORDER BY band_downloads.id DESC;
No segundo caso, vocˆe pode obter duas linhas idˆenticas no MySQL 3.23.x na s´erie do
resultado (porque o campo escondido ’id’ pode variar).
Perceba que isto somente acontece em consultas onde vocˆe n˜ao tem colunas ORDER
BY no resultado, algo n˜ao permitido no ANSI SQL.
Como o MySQL permite trabalhar com tipos de tabelas que n˜ao suportam transa¸oes
(e assim n˜ao pode fazer rollback em dados) algumas coisas funcionam um pouco
diferentes de outros servidores SQL em MySQL (Isto serve para garantir que o MySQL
nunca necessitar´a de um rollback para um comando SQL). Por´em isto pode ser um
pouco estranho em casos que os valores dos campos devem ser verificados na aplica¸ao,
mas isto ira fornacer um ´otimo ganho de velocidade assim como permite ao MySQL
fazer algumas otimiza¸oes que de outro modo seriam muito dif´
iceis para serem feitas.
Se vocˆe informar um valor incorreto em uma coluna, o MySQL, em vez de fazer um
rollback, aramzenar´a o melhor valor poss´
ivel no campo.
Se tentar armazenar um valor fora da faixa em uma coluna num´erico, o MySQL
ir´a armazenar o menor ou maior valor poss´
ivel no campo.
60 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se tentar armazenar uma string que n˜ao comece com um n´umero em uma coluna
num´erica, o MySQL ir´a armazenar 0 na coluna.
Se vocˆe tentar armazenar NULL em uma coluna que n˜ao aceita valores
nulos, MySQL ir´a armazenar 0 ou ’’ (string vazia) na coluna. (Este
comportamento pode, entretanto, ser alterado com a op¸ao de compila¸ao
-DDONT USE DEFAULT FIELDS).
O MySQL permite o armazenamento de alguns valores errados de data em campos
do tipo DATE eDATETIME. (Como 2000-02-31 ou 2000-02-00). Se a data estiver
totalmente errada, o MySQL ir´a armazenar a data 0000-00-00 no campo.
Se vocˆe especificar um valor n˜ao suportado para um campo do tipo enum, ele ser´a
alterado para o valor de erro ’empty string’, com valor num´erico 0.
Se vocˆe executar uma PROCEDURE em uma pesquisa que retorna uma s´erie vazia, em
alguns casos a instru¸ao PROCEDURE ao ir´a transformar as colunas.
Cria¸ao da tabela do tipo MERGE ao verifiva se as tabelas envolvidas s˜ao de tipos
compat´
iveis.
O MySQL ainda n˜ao pode lidar com valores NaN,-Inf eInf em tipos double. Us´a-los
causar´a problemas na exporta¸ao e importa¸ao de dados. Uma solu¸ao intermedi´aria
´e alterar NaN para NULL (se for poss´
ivel) e -Inf eInf para o valor double m´
inimo ou
aximo respectivo poss´
ivel.
LIMIT em n´umeros negativos s˜ao tratados como n´umeros grandes positivos.
Se vocˆe usar ALTER TABLE para primeiro adicionar um´
indice UNIQUE a uma tabela usada
em uma tabela MERGE e enao usar ALTER TABLE para adicionar um ´
indice normal na
tabela MERGE, a ordem das chaves ser´a diferente para as tabelas se existir uma chave
antiga n˜ao ´unica na tabela. Isto ´e porque o ALTER TABLE coloca chaves UNIQUE antes
de chaves normais para ser poss´
ivel detectar chaves duplicadas o mais cedo o poss´
ivel.
Os seguintes erros s˜ao conhecidos em vers˜oes mais antigas do MySQL:
Voe pode pendurar um processo se vocˆe fizer um DROP TABLE em uma tabela entre
outras que esteja travada com LOCK TABLES.
No caso seguinte vocˆe pode obter um descarrego de mem´oria para o arquivo core:
Tratamento de inser¸oes com atraso tem deixado inser¸oes pendentes na tabela.
LOCK table com WRITE
FLUSH TABLES
Antes da vers˜ao 3.23.2 do MySQL um UPDATE que atualizava uma chave com um WHERE
na mesma chave podia falhar porque a chave era usada para procurar por registros e a
mesma linha poderia ter encontrado v´arios itens:
UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY > 100;
Um modo de contornar este erro ´e utilizar:
mysql> UPDATE nome_tabela SET KEY=KEY+1 WHERE KEY+0 > 100;
Isto funcionar´a porque MySQL n˜ao utilizar´a indices em express˜oes com a cl´ausula
WHERE.
Antes da vers˜ao 3.23 do MySQL, todos os tipos num´ericos tratados como campos
de pontos fixos. Isto significa que vocˆe tem que especificar quantas casas decimais um
Chapter 1: Informa¸oes gerais sobre o MySQL 61
campo de ponto flutuante deve ter. Todos os resultados eram retornados com o numero
correto de casas decimais.
Para erros espec´
ificos na plataforma, vejas as se¸oes sobre compila¸ao e portabilidade.
1.5 Como comparar o MySQL com outros Bancos de dados
Esta se¸ao compara o MySQL com outros bancos de dados populares.
Esta se¸ao foi escrita pelos desenvolvedores MySQL, enao deve ser lida com isto em mente.
ao ´e de nosso conhecimento a existˆencia de erros factuais nesta se¸c˜ao. Se vocˆe encontrar
algo em que acredita ser um erro, por favor nos contate em docs@mysql.com
Para uma lista de todos os limites suportados, fun¸oes e tipos veja a p´aginas Web crash-me
em http://www.mysql.com/information/crash-me.php.
1.5.1 Como comparar o MySQL com o mSQL
Performance
Para uma verdadeira compara¸ao de velocidade, consulte a suite de benchmark
do MySQL See hundefinedi[MySQL Benchmarks], page hundefinedi.
Por n˜ao existir sobrecarga de cria¸ao de threads, um pequeno parser, poucos
recursos e seguran¸ca simples, mSQL deve ser mais r´apido em:
Testes que conectam e desconectam repetidas vezes, executando queries
muito simples durante cada conex˜ao.
Opera¸oes INSERT em tabelas muito simples com poucas colunas e chaves.
CREATE TABLE eDROP TABLE.
SELECT em campos que n˜ao sejam ´
indice. (Uma varredura de tabela ´e
muito f´acil.)
Como estas opera¸oes s˜ao muito simples, ´e dif´
icil ser melhor que eles quando
vocˆe tem uma alta sobrecarga inicial. Depois da conex˜ao ser estabelecida, a
performance do MySQL deve ser bem melhor.
Por outro lado, o MySQL ´e muito mais r´apido que o mSQL (e a maioria das
outras implementa¸oes SQL) no seguinte:
Opera¸oes SELECT complexas.
Recupera¸ao de grandes resultados (MySQL tem um protocolo melhor,
mais r´apido e mais seguro)
Tabelas com strings de tamanho variavel, porque o MySQL tem um handler
mais eficiente e pode ter ´
indices em campos VARCHAR
Manipula¸ao de tabelas com v´arias colunas.
Manipula¸ao de tabelas com grande quantidade de registros.
SELECT com v´arias express˜oes.
SELECT em grande tabelas.
Tratamento de v´arias conex˜oes ao mesmo tempo. O MySQL ´e totalmente
multi-threaded. Cada conex˜ao tem sua pr´opria thread, o que significa que
nenhuma thread tem que esperar por outra (a menos que uma thread esteja
62 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
modificando uma tabela que uma outra thread deseja acessar). No mSQL,
uma vez que uma conex˜ao for estabelecida, todos outros devem esperar at´e
que a primeira tenha acabado, sem levar em considera¸ao se a conex˜ao est´a
executando uma query que ´e curta ou longa. Quando a primeira conex˜ao
termina, a pr´oxima pode ser atendida, enquanto todas as outras esperam
novamente e etc.
Joins. O mSQL pode ficar patologicamente lento se vocˆe alterar a ordem
das tabelas em uma SELECT. Na suite de benchmark, o mSQL se mostrou
15000 vezes mais lento que o MySQL. Isto ´e devido a falta de um otimizador
join para ordenar tabelas na ordem otimizada no mSQL. Entretanto, se
vocˆe colocar as tabelas na ordem exata no mSQL2 e o WHERE for simples e
usar ´
indice, o join vai ser relativamente r´apido! See hundefinedi[MySQL
Benchmarks], page hundefinedi.
ORDER BY eGROUP BY.
DISTINCT.
Usando tipos TEXT ou BLOB em campos.
Recursos SQLGROUP BY eHAVING. O mSQL ao suporta completamente o GROUP BY. O
MySQL suporta completamente o GROUP BY com HAVING e as seguintes
fun¸oes: COUNT(),AVG(),MIN(),MAX(),SUM() eSTD().COUNT(*) ´e
otimizado para retornar rapidamente se o SELECT retornar de uma tabela,
nenhum outro campo ´e devolvido e n˜ao h´a uma cl´ausula WHERE.MIN() e
MAX() podem exigir argumentos.
INSERT eUPDATE com c´alculos. O MySQL pode fazer c´alculos em uma
instru¸ao INSERT ou UPDATE. Por exemplo:
mysql> UPDATE SET x=x*10+y WHERE x<20;
Apelidos ou alias. MySQL tem suporte a apelidos para os campos.
Qualificando nomes de colunas. No MySQL, se um nome de coluna ´e ´unica
entre as tabelas usadas em uma query, vocˆe n˜ao tem que usar o qualifidador
completo.
SELECT com fun¸oes. O MySQL tem v´arias fun¸oes (muitas para serem
listadas aqui; veja hundefinedi[Functions], page hundefinedi).
Eficiˆencia no Armazenamento em Disco
Ou seja, qu˜ao pequena pode ser suas tabelas ?
Existem tipos muito precisos no MySQL, que possibilitam a cria¸ao de tabelas
que consumem muito pouco espa¸co em disco. Um exemplo de um tipo de
dados MySQL ´e o MEDIUMINT que ocupa 3 bytes. Se vocˆe tiver 100.000.000 de
registros, economizar um byte por registro pode ser m uito importante.
OmSQL2 possui uma variedade mais limitada para tipos de campos, portanto,
´e mais complicado para obter pequenas tabelas.
Estabilidade´
E dif´
icil julgar objetivamente. Para uma discuss˜ao sobre estabilidade do
MySQL, veja em hundefinedi[Stability], page hundefinedi.
Chapter 1: Informa¸oes gerais sobre o MySQL 63
os n˜ao tempos experiˆencia com a estabilidade do mSQL, portanto, n˜ao podemos
dizer nada sobre isto.
Pre¸co Outro assunto importante ´e a licen¸ca. O MySQL possui uma licen¸ca mais
flex´
ivel que o mSQL, e tamb´em ´e mais barato que o mSQL. Qualquer produto
que vocˆe escolha usar, lembre-se de considerar ao menos o pagamento de uma
licen¸ca ou suporte por e-mail. (Voe ´e obrigado a obter uma licen¸ca se incluir
o MySQL com um produto que vende.)
Interfaces Perl
O MySQL tem basicamente a mesma interface para o Perl que o mSQL com
alguns recursos adicionais.
JDBC (Java)
Atualmente, o MySQL tem v´arios drivers JDBC diferentes:
O driver mm: Um driver JDBC tipo 4 por Mark Matthews
mmatthew@ecn.purdue.edu. Este ´e distribuido sobre a LGPL.
O driver Resin. Este ´e um driver JDBC comercial open source.
http://www.caucho.com/projects/jdbc-mysql/index.xtp
O driver gwe: Uma interface JAVA fabricada pela GWE technologies (n˜ao
´e mais suportado).
O driver jms: Um driver gwe melhorado por xiaokun Kelvin ZHU
X.Zhu@brad.ac.uk (n˜ao ´e mais suportado).
O driver twz: Um driver JDBC tipo 4 por Terrence W. Zellers
zellert@voicenet.com.´
E comercial, por´em livre para uso privado e
educacional (n˜ao ´e mais suportado).
O driver recomendado ´e o driver mm. O driver Resin tamb´em pode ser bom
(pelo menos nos benchmarks parece bom), mas n´os n˜ao recebemos informa¸oes
suficientes sobre ele ainda.
os sabemos que o mSQL tem um driver JDBC, mas n´os temos muito pouca
experiˆencia com ele para comparar.
Desenvolvimento
MySQL tem uma equipe de desenvolvedores muito pequena, mas somos bem
apidos codificando em C e C++. Como threads, fun¸oes, GROUP BY e outras
recursos ainda n˜ao est˜ao implementada em mSQL, eles tˆem muitas coisas para
fazer. Para ter uma perspectiva para estas implementa¸oes vocˆe pode ar uma
olhada no arquivo de HIST´
ORICO do mSQL do ultimo ano e compar´a-lo com a
se¸ao Novidades do Manual de Referˆencia do MySQL. (see hundefinedi[News],
page hundefinedi). ´
E bem ´obvio quem tem desenvolvido mais rapidamente.
Programas utilit´arios
Ambos mSQL e MySQL tem v´arias ferramentas interessantes de terceiros. Como
´e muito f´acil portar (do mSQL para MySQL), quase todas as aplica¸oes interes-
santes que s˜ao dispon´
iveis para mSQL tamb´em est´a dispon´
ivel para MySQL.
O MySQL vem com um programa simples, msql2mysql que corrige diferen¸cas
nas sintaxes entre o mSQL e o MySQL para as fun¸c˜oes C API mais usadas.
Por exemplo, ele altera instancias de msqlConnect() para mysql_connect().
64 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Converter um programa cliente de mSQL para MySQL levam alguns poucos
minutos.
1.5.1.1 Como converter ferramentas mSQL para o MySQL
Por experiˆencia pr´opria, ´e necess´ario apenas algumas horas para converter ferramentas como
amsql-tcl emsqljava que usam a API em C do mSQL para que eles trabalhem com API
C do MySQL.
O procedimento de convers˜ao ´e:
1. Execute o script shell msql2mysql na fonte. Isto necessita o programa replace, que ´e
distribu´
ido com o MySQL.
2. Compile.
3. Corrija todos erros de compila¸ao
As diferen¸cas entre a API C do mSQL e a API C do MySQL s˜ao:
O MySQL usa uma estrutura MYSQL como um tipo de conex˜ao, (mSQL usa um int).
omysql_connect() recebe um ponteiro para uma estrutura MYSQL como um parˆametro.
´
E f´acil definir um globalmente ou usar malloc() para obter um. mysql_connect()
tamb´em recebe dois parˆametros para especificar o usu´ario e senha. Voe pode configur´a-
los para NULL, NULL para uso padr˜ao.
mysql_error() recebe uma estrutura MYSQL como um parˆametro. Apenas adicione o
parˆametro para c´odigo antigo mysql_error() se vocˆe estiver portanto o c´odigo antigo.
O MySQL retorna um n´umero de erro e uma mensagem texto de erro para todos erros.
OmSQL retorna somente a mensagem de erro.
Algumas incompatibilidades existem como o resultado do MySQL suportar mult´
iplas
conex˜oes para o servidor do mesmo processo.
1.5.1.2 Diferen¸cas entre os protocolos de comuni¸ao do mSQL e do
MySQL Cliente/servidor
Existem bastantes diferen¸cas que ´e imposs´
ivel (ou pelo menos, n˜ao ´e f´acil) suportar ambos.
O que mais caracteriza as diferen¸cas entre o protocolo do MySQL e o protocol do mSQL
est˜ao listadas abaixo:
Um buffer de mem´oria pode conter v´arias linhas de resultado.
Os buffers de mensagens crescem dinamicamente se a sua query ou o resultado for
maior que o buffer atual, chega at´e a configura¸ao do servidor e o limite do cliente.
Todos pacotes s˜ao numerados para capturar pacotes perdidos ou duplicados.
Todos valores das colunas s˜ao enviados em ASCII. Os tamanhos de colunas e linhas
ao enviados empacotados em uma codifica¸ao bin´aria (1, 2 ou 3 bytes).
O MySQL pode ler no resultado que n˜ao est´a registrado (sem necessidade de armazenar
o conjunto inteiro no cliente).
Se uma simples leitura/escrita demorar mais que 30 segundos, o servidor encerra a
conex˜ao.
Se uma conex˜ao estiver ociosa por 8 horas, o servidor encerra a conex˜ao.
Chapter 1: Informa¸oes gerais sobre o MySQL 65
1.5.1.3 Diferencas entre as sintaxes SQL do mSQL 2.0 e do MySQL
Tipos de Campos
O MySQL Tem os seguintes tipos adicionais (entre outros; see hundefinedi[CREATE TABLE],
page hundefinedi):
Tipo ENUM para um de um conjunto de strings.
Tipo SET para v´arios de um conjunto de strings.
Tipo BIGINT para inteiros com 64bits.
MySQL tamb´em suporta os seguintes atributos de tipos adicionais:
Op¸ao UNSIGNED para colunas com n´umeros inteiros.
Op¸ao ZEROFILL para colunas com n´umeros inteiros.
Op¸ao AUTO_INCREMENT para colunas com n´umeros inteiros que s˜ao CHAVE
PRIM´
ARIA. See hundefinedi[mysql_insert_id()], page hundefinedi.
Valor DEFAULT para todos os tipos de colunas.
mSQL2 tipos de campo mSQL correspondem aos tipo MySQL mostrados abaixo:
Tipo mSQL Tipo MySQL correspondenete
CHAR(tam) CHAR(tam)
TEXT(tam) TEXT(tam).tam ´e o tamanho m´aximo. E LIKE funciona.
INT INT. Com muito mais op¸oes!
REAL REAL. Ou FLOAT. Est˜ao dispon´
iveis as vers˜oes 4 e 8 bits.
UINT INT UNSIGNED
DATE DATE. Usa o tanto formato ANSI SQL quanto o formato propriet´ario do
mSQL.
TIME TIME
MONEY DECIMAL(12,2). Um n´umero de ponto fixo com dois decimais.
Cria¸ao de ´
Indices
MySQL ´
Indices podem ser especificados na hora da cria¸ao da tabela juntos a instru¸ao
CREATE TABLE.
mSQL ´
Indices podem ser criados depois da cria¸ao da tabela, com instru¸oes CREATE
INDEX separadas.
Para inserir um identificador ´unico na tabela
MySQL Usa o AUTO_INCREMENT como um especificador de tipo de coluna.
See hundefinedi[mysql_insert_id()], page hundefinedi.
mSQL
Cria um SEQUENCE em uma tabela e seleciona a coluna _seq.
Para obter um identificador ´unico para uma linha
MySQL Adicione uma chave primaria (PRIMARY) ou uma chave UNIQUE para a tabela e a
use. Novidades na Vers˜ao 3.23.11: Se as chaves primaria (PRIMARY) ou UNIQUE
consistirem de somente uma coluna e esta for do tipo inteiro, tanb´em podemos
nos referenciar a ela como _rowid.
66 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mSQL Use a coluna _rowid. Observe que _rowid pode ser alterado varias vezes,
dependendo de alguns fatores.
Obtendo a hora em que uma coluna foi alterada
MySQL Adicionando uma coluna TIMESTAMP na tabela. Este campo ´e configurado auto-
maticamente para receber os valores de data e hora atuais se vocˆe n˜ao informar
algum valor ou fornecer um valor NULL.
mSQL Usa o coluna _timestamp.
Compara¸oes de Valores NULL
MySQL O MySQL segue o ANSI SQL, portanto qualquer compara¸ao com NULL ´e sem-
pre NULL.
mSQL No mSQL,NULL = NULL ´e verdadeiro. Voe deve alterar =NULL para IS NULL
e<>NULL para IS NOT NULL quando portar c´odigos antigos do mSQL para o
MySQL.
Compara¸oes de Strings
MySQL Normalmente, compara¸oes de conjuntos de caracteres s˜ao feitas no estilo in-
dependente do caso com a forma de classifica¸ao determinada pelo conjunto
de caracteres atuais (ISO-8859-1 Latin1 por defini¸ao padr˜ao). Se vocˆe n˜ao
gosta disto, declare seus campos com o atributo BINARY, que deixa as com-
para¸oes serem realizadas de acordo com a ordena¸ao ASCII usada na m´aquina
que hospeda o servidor MySQL.
mSQL Todas as compara¸oes de conjuntos de caracteres s˜ao caso sensitivo com or-
dena¸ao na ordem ASCII.
Pesquisas Caso Insensitivo
MySQL LIKE ´e um operador caso-sensitivo ou caso-insensitivo, dependendo dos campos
envolvidos. Se poss´
ivel, o MySQL usa ´
indices se o argumento LIKE ao iniciar
com um meta caracter.
mSQL Usar CLIKE.
Manipulando Espa¸cos Excessivos
MySQL Remove todos os espa¸cos no final de colunas CHAR eVARCHAR. Utilize uma
coluna TEXT se o comportamento citado n˜ao ´e desejado.
mSQL Mant´em os espa¸cos excessivos.
Cl´ausulas WHERE
MySQL O MySQL prioriza tudo (AND ´e avaliado antes de OR). Para obter o comparta-
mento do mSQL no MySQL, use parenteses (como visto no exemplo abaixo).
mSQL Avalia tudo da esquerda para a direita. Isto significa que alguns calculos l´ogicos
com mais de tres argumentos n˜ao pode ser expressados. Tamb´em significa que
vocˆe deve alterar algumas queries quando vocˆe atualizar para o MySQL. Vocˆe
pode fazer isto facilmente adicionando parˆenteses. Suponha que vocˆe tenha a
seguinte consulta mSQL:
Chapter 1: Informa¸oes gerais sobre o MySQL 67
mysql> SELECT * FROM tabela WHERE a=1 AND b=2 OR a=3 AND b=4;
Para fazer com que o MySQL avalie a senten¸ca da maneira que o mSQL faria,
vocˆe deve adicionar parˆenteses:
mysql> SELECT * FROM tabela WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
Controle de Acesso
MySQL Tem tabelas para armazenar op¸oes de privil´egios (permiss˜oes) por usu´ario,
aquina e banco de dados. See hundefinedi[Privileges], page hundefinedi.
mSQL Tem um arquivo mSQL.acl’ em que vocˆe pode conceder privil´egios de leitura/
escrita para usu´arios.
1.5.2 Como comparar o MySQL ao PostgreSQL
Quando ler esta se¸ao, por favor perceba que ambos produtos est˜ao continuamente em
evolu¸ao. os na MySQL AB e os desenvolvedores do PostgreSQL estamos ambos trabal-
hando para fazer os nossos bancos de dados os melhores poss´
iveis, portanto, somos ambos,
uma s´eria escolha sobre qualquer banco de dados comercial.
A seguinte compara¸ao ´e feita por n´os na MySQL AB. N´os tentamos ser o mais preciso e
claro poss´
ivel, mas como n˜ao temos pleno conhecimento de todos os recursos do PostgreSQL
como temos do MySQL, podemos ter deixado alguns itens errados. Entretanto, iremos
corrigi-los que chamarem nossa aten¸ao.
Inicialmente gostariamos de notar que o PostgreSQL e o MySQL s˜ao ambos, produtos in-
tensamente usados, mas com diferentes objetivos, mesmo se ambos empenhassem na com-
patibiliza¸ao com o ANSI SQL. Isto significa que para algumas aplica¸oes o MySQL ´e mais
indicado, enquando para outras, o PostgreSQL possa ser mais. Quando for escolher qual
banco de dados usar, vocˆe deve inicialemnte conferir se o conjunto de recursos do banco de
dados satisfaz sua aplica¸ao. Se vocˆe precisa de velocidade, o MySQL ´e provavelmente sua
melhor escolha. Se vocˆe necessita e alguns recursos extras que somente o PostgreSQL pode
oferecer, vocˆe deve usar PostgreSQL.
1.5.2.1 Estrat´egias de desenvolvimento da MySQL e PostgreSQL
Quando adicionamos recursos ao MySQL, orgulhamos de criar uma solu¸ao otimizada e
definitiva. O c´odigo deve ser t˜ao bom que n´os n˜ao teremos necessidade de alter´a-lo em um
futuro pr´oximo. os tamb´em n˜ao gostamos de sacrificar velocidade em prol dos recursos,
por´em faremos o m´aximo para encontrar uma solu¸ao que ir´a fornecer o m´aximo de resulta-
dos. Isto implica que o desenvolvimento ir´a ser um pouco demorado, mas o resultado final
ir´a ter uma importˆancia maior. Este tipo de desenvolvimento s´o ´e poss´
ivel porque todo o
odigo do servidor ´e conferido por poucas (atualmente duas) pessoas antes de ser inclu´
ido
no servidor MySQL.
os na MySQL AB lan¸camos frequentemente atualiza¸oes para que possamos implementar
rapidamente novos recursos para nossos usu´arios. Por isto fazemos um pequeno lan¸camento
a aproximadamente cada 3 semanas, e uma distribui¸ao maior a cada ano. Todos
lan¸camentos s˜ao extensamente testados com nossas ferramentas de testes em v´arias
plataformas diferentes.
68 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
PostgreSQL ´e baseado em um kernel com v´arios colaboradores. Nesta configura¸ao faz
sentido priorizar a adi¸ao de v´arios recursos novos, em vez de implemena- los de forma
otimizada, porque sempre se pode otimizar itens depois se houver necessidade para isto.
Outra grande diferen¸ca entre o MySQL e o PostgreSQL ´e que quase todo o c´odigo no
servidor MySQL ´e feito por desenvolvedores que s˜ao contratados pela MySQL AB e con-
tinuam trabalhando no c´odigo do servidor. As exce¸oes s˜ao os mecanismos de transa¸oes e
a biblioteca regexp.
Este ´e o contraste com o c´odigo do PostgreSQL onde a maioria do c´odigo ´e feita por um
grande grupo de pessoas em diferentes situa¸oes e condi¸oes. o agora os desenvolvedores
do PostgreSQL anunciaram que o grupo de desenvolvimento atual finalmente teria tempo
para revisar todo o c´odigo na vers˜ao atual.
Ambos os m´etodos de desenvolvimento citados acima tem seus pr´oprios m´eritos e benef´
icios.
´
E claro que n´os na MySQL pensamos que nosso modelo ´e melhor pois ele fornece melhor
consistˆencia no c´odigo, um c´odigo reutiliz´avel e otimizado e na nossa opni˜ao, menos erros.
Pelo fato de sermos os autores do c´odigo do servidor MySQL, n´os estamos melhor adaptados
para coordenar novos recursos e lan¸camentos.
1.5.2.2 Compara¸oes de recursos entre o MySQL e PostgreSQL
Na p´agina crash-me vocˆe pode encontrar uma lista das constru¸oes e limites dos bancos de
dados que podem ser detectados autom´aticamente com um programa. Perceba entretanto
que v´arias dos limites num´ericos podem ser alterados com op¸oes de inicializa¸ao para
respectivos bancos de dados. O p´agina web acima ´e extremamente ´util quando vocˆe quer
assegurar que sua aplica¸ao funcione com v´arios bancos de dados diferentes ou quando vocˆe
desejar converter sua aplica¸ao de um banco de dados para outro.
O MySQL oferece as seguintes vantagens sobre o PostgreSQL:
OMySQL ´e normalmente muito mais r´apido que o PostgreSQL. See hundefinedi[MySQL-
PostgreSQL benchmarks], page hundefinedi.
O MySQL tem uma base de usu´arios muito maior que o PostgreSQL, portanto o c´odigo
´e mais testado e tˆem sido historicamente mais est´avel que o PostgreSQL. O MySQL ´e
muito mais usado nos ambientes de produ¸ao do que o PostgreSQL, na maioria gra¸cas
`a MySQL AB, formalmente TCX DataKonsult AB, que tem fornecido excelencia na
qualidade do do suporte comercial para o MySQL desde o dia de seu lan¸camento, onde
que at´e recentemente o PostgreSQL n˜ao era suportado.
O MySQL trabalha melhor no Windows do que o PostgreSQL. O MySQL executa como
uma aplica¸ao Windows nativa (um servi¸co no NT/Win2000/WinXP), enquanto o
PostgreSQL ´e executado sobre a emula¸ao cygwin. os temos ouvido que o PostgreSQL
ao ´e ainda est´avel no windows mas n˜ao temos capacidades para afirmar.
O MySQL tem mais APIs que outras linguagems e ´e suportado por mais programas
existentes que o PostgreSQL. See hundefinedi[Contrib], page hundefinedi.
O MySQL trabalha em sistemas pesados 24/7. Na maioria das circunstˆancias vocˆe
nunca precisar´a fazer qualquer limpeza no MySQL. O PostgreSQL n˜ao suporta ainda
sistemas 24/7 porque em determinado momento deve ser executado o VACUUM() para
recuperar espa¸co dos comandos UPDATE eDELETE e executar analizes estat´
isticas que s˜ao
cr´
iticas para obter boa performance com o PostgreSQL. VACCUM() ´e tamb´em necess´ario
Chapter 1: Informa¸oes gerais sobre o MySQL 69
depois de adicionar v´arios registros em uma tabela. Em um sistema ocupado com
arias altera¸oes, VACUUM() deve ser executado muito frequentemente, nos piores casos
mesmo muitas vezes ao dia. Durante a execu¸ao do VACUUM(), que pode durar horas se
o banco de dados for grande, o banco de dados num ponto de vista de produtividade
fica praticamente morto. A equipe PostgreSQL tem corrigido isto no seu TODO, mas
os assumimos que isto n˜ao ´e uma coisa f´acil de ser corrigida permanentemente.
O recurso de replica¸ao funciona e ´e usado por sites como:
Yahoo Finance (http://finance.yahoo.com)
Mobile.de (http://www.mobile.de/)
Slashdot (http://www.slashdot.org)
´
E inclu´
ido nas distribui¸oes MySQL dois tipos diferentes de testes: mysql-test-run
ecrash-me, bem como o de medida de velocidade. O sistema de testes ´e ativamente
atualizado com c´odigo para testar cada novo recurso e com quase todos erros repetidos
que chamaram nossa aten¸ao. os testamos o MySQL com isto em v´arias plataformas
antes de todos lan¸camentos. Estes testes s˜ao mais sofisticados que qualquer um que
vimos para o PostgreSQL, e ele assegura que o MySQL ´e mantido em um alto padr˜ao.
Existem muito mais livros impressos sobre MySQL do que sobre PostgreSQL. O’Reilly,
Sams, Que e New Rider s˜ao todas grandes editores com livros sobre MySQL. Todos re-
cursos MySQL s˜ao tamb´em documentados no manual on-line, porque, quando um novo
recurso ´e implementado ´e exigido ique os desenvolvedores do MySQL o documentem
antes de ser inclu´
ido na fonte.
O MySQL suporta mais fun¸oes b´asicas do ODBC que o PostgreSQL.
O MySQL tem um ALTER TABLE muito mais sofisticado.
O MySQL tem suporte para tabelas n˜ao transacionais para aplica¸oes que necessitam
toda velocidade que podem ter. As tabelas podem ser baseadas em mem´oria, tabelas
HEAP ou baseadas em disco MyISAM. See hundefinedi[Table types], page hundefinedi
O MySQL tem suporte para dois manipuladores de tabelas diferentes que suportam
transa¸oes, BerkeleyDB eInnoDB. Porque todo mecanismo transacional executa difer-
entemente sobre condi¸oes diferentes, isto fornece ao programador mais op¸oes para
encontrar uma solu¸ao otimizada para sua configura¸ao. See hundefinedi[Table types],
page hundefinedi
Tabelas consolidadas com MERGE lhe fornece uma maneira ´unica para criar uma vista
instananea sobre um conjunto de tabelas identicas e usa-las como uma. Isto ´e perfeito
para sistemas onde vocˆe tem arquivos log que vocˆe ordena, por exemplo por mˆes. See
hundefinedi[MERGE], page hundefinedi.
A op¸ao para comprimir tabelas somente leitura, mas ainda ter acesso direto aos reg-
istros na tabela, fornece melhor performance minimizando leituras em disco. Isto
´e muito ´util quando vocˆe estiver arquivando coisas. See hundefinedi[myisampack],
page hundefinedi.
O MySQL tem suporte interno para pesquisas textuais. See hundefinedi[Fulltext
Search], page hundefinedi.
Voe pode acessar v´arios bancos de dados da mesma conex˜ao (dependeno ´e claro de
seus privil´egios).
70 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O MySQL ´e codificado desde o ´
inicio para ser multi-thread enquando o PostgreSQL usa
processos. Troca de contexto e acesso a ´areas comuns de armazenamento ´e muito mais
apido entre threads do que entre processos separados, isto fornece ao MySQL uma
grande vantagem em velocidade em aplica¸oes multi-usu´arias e tamb´em torna muito
mais f´acil para o MySQL obter vantagem total de sistemas de multiprocessamento
sim´etrico (SMP).
O MySQL tem um sistema de privil´egios muito mais sofisticado do que o PostgreSQL.
Enquanto o PostgreSQL suporta permiss˜oes somente para INSERT,SELECT e
UPDATE/DELETE por usu´ario em um banco de dados ou uma tabela, o MySQL permite
que vocˆe defina um conjunto completo de diferentes privil´egios nos bancos de dados,
tabelas e campos. O MySQL tamb´em lhe permite especificar as combina¸oes de
privil´egios por m´aquina e usu´arios. See hundefinedi[GRANT], page hundefinedi.
O MySQL suporta um protocol cliente/servidor comprimido que aumenta a perfor-
mance em conex˜oes lentas.
O MySQL trabalha com um conceito de “table handler”, e ´e o ´unico banco de dados
relacional que conhecemos constru´
ido neste conceito. Isto permite diferentes tipos de
tabela em baixo n´
ivel serem trocadas no mecanismo SQL e cada tipo de tabela ser
otimizado para diferentes caracter´
isticas de performace.
Todos os tipos de tabelas MySQL (exceto InnoDB) s˜ao implementados como arquivos
(uma tabela por arquivo), que facilita muito o backup, mudan¸ca e dele¸ao e mesmo
conex˜oes simolicas entre bancos de dados e tabelas, mesmo se o servidor estiver desli-
gado.
Ferramentas para corrigir e otimizar tabelas MyISAM (o tipo de tabelas MySQL mais
comum). Um ferramenta de reparos s´o ´e necess´aria quando uma corrompimento fisico
do arquivo de dados acontece, normalmente por uma falha no equipamento. Elas
permitem que a maioria dos dados sejam recuperados.
Atualizar o MySQL ´e indolor. Quando vocˆe estiver atualizando o MySQL, n˜ao precisar´a
de apagar/restaurar os seus dados, como vocˆe deve fazer na maioria das atualiza¸oes
do PostgreSQL.
Desvantagens do MySQL em compara¸ao ao PostgreSQL:
O suporte a transa¸ao no MySQL n˜ao ´e t˜ao bem testado como no sistema PostgreSQL.
Como o MySQL utiliza threads, os quais ainda n˜ao est˜ao comple-
tos em v´arios Sistemas Operacionais, deve-se tamb´em usar bin´arios de
http://www.mysql.com/downloads, ou cuidadosamente seguir nossas instru¸oes em
http://www.mysql.com/doc/I/n/Installing_source.html para obter um bin´ario
otimizado que funcione em todos os casos.
Bloqueios de tabelas, usados pelas tabelas n˜ao transacionais MyISAM ´e, em muitos
casos, mais r´apidos que bloqueios de p´aginas, bloqueios de registros ou versionamento.
A desvantagem entretanto ´e que se algu´em n˜ao levar em considera¸ao como funciona
o bloqueio de tabelas, simplesmente, uma ´unica query que demora muito tempo para
executar, pode bloquear uma tabela para atualiza¸oes por um grande tempo. Isto
pode ser evitado quando for desenhar a aplica¸ao. Se n˜ao, pode-se sempre trocar a
tabela e utilizar uma das tabelas do tipo transacional. See hundefinedi[Table locking],
page hundefinedi.
Chapter 1: Informa¸oes gerais sobre o MySQL 71
Com o UDF (Fun¸oes definidas pelo usu´ario) pode-se extender o MySQL com fun¸oes
SQL normais e agregadas, mas isto ainda n˜ao ´e t˜ao f´acil e flex´
ivel como no PostgreSQL.
See hundefinedi[Adding functions], page hundefinedi.
Atualiza¸oes e remo¸oes que executam sobre mult´
iplas tabelas s˜ao mais dif´
iceis para
serem feitas no MySQL. Isto ir´a, entretanto, ser corrigido no MySQL 4.0 com DELETE
multi tabelas e UPDATE multi tabelas e no MySQL 4.1 com subselects.
O PostgreSQL atualmente oferece as seguintes vantagens sobre o MySQL:
Note que como conhecemos o mapa do MySQL, n´os inclu´
imos na seguinte tabela a vers˜ao
na qual o MySQL deve suportar o recurso. Infelizmente n´os n˜ao podemos fazer isto em na
compara¸ao anterior, porque n´os n˜ao conhecemos o mapa do PostgreSQL.
Recurso vers˜ao MySQL
Subselects 4.1
Foreign keys (Chaves Estrangeiras) 4.0 e 4.1
Views 4.2
Stored procedures 4.1
Sistemas de tipos extensivos Sem planejamento
Unions 4.0
Full join 4.0 or 4.1
Triggers 4.1
Constrainst 4.1
Cursores 4.1 or 4.2
Tipos de indices extensivos como R-trees R-trees estao planejados
para 4.2
Tabelas com heran¸ca Sem planejamento
Outras raz˜oes para usar o PostgreSQL:
O uso comum do PostgreSQL ´e mais pr´oximo ao ANSI SQL em alguns casos.
O PostgreSQL pode ficar mais r´apido codificando coisas como stored procedures.
PostgreSQL tem uma equipe de desenvolvedores maior que contribuem com o servidor.
Desvantagens do PostgreSQL comparado ao MySQL:
A cl´ausula VACUUM() dificulta o uso do PostgreSQL em um ambiente 24/7.
Somente tabelas transacionais.
INSERT,DELETE UPDATE muito mais lentos.
Para uma lista completa de desvantagens, vocˆe deve tamem examinar a primeira tabela
nesta se¸ao.
1.5.2.3 Compara¸oes de velocidade entre o MySQL e o
PostgreSQL
O ´unico benchmark open source que n´os conhecemos que pode ser usados para testar a
velocidade do MySQL e do PostgreSQL (e outros bancos) ´e o nosso pr´oprio. Ele pode ser
encontrado em http://www.mysql.com/information/benchmarks.html.
arias vezes solicitamos ajuda aos desenvolvedores e alguns usu´arios do PostgreSQL para
extender esse software de benchmark para fazer dele o teste definitivo para Bancos de Dados,
mas infelizmente n´os n˜ao estamos tendo retorno sobre isto.
72 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Por isto, n´os, os desenvolvedores do MySQL gastamos v´arias horas para obter performance
axima do PostgreSQL para os benchmarks, mas como n˜ao conhecemos PostgreSQL inti-
mamente, temos certeza que existem detalhes que podem ter sido esquecidos. os temos
na p´agina de testes em nosso site a documenta¸ao de como fizemos os testes para que seja
acil para qualquer um repetir e verificar nossos resultados.
Os testes comparativos s˜ao normalmente executados com e sem a op¸ao --fast. Quando
executado com --fast os estamos tentando usar todos os truques que o servidor pode
fazer para que o c´odigo execute o mais r´apido poss´
ivel. A id´eia ´e que a execu¸ao normal
deve mostrar como o servidor deve trabalhar numa configura¸ao padr˜ao e a execu¸ao com
--fast mostra como o servidor comportaria se o desenvolvedor da aplica¸ao usar extens˜oes
no servidor para fazer sua aplica¸ao executar mais r´apida.
Quando executando com o PostgreSQL e --fast os fazemos um VACUUM depois de quase
todos maiores UPDATE eDROP TABLE para deixar o banco de dados em forma perfeita para
as SELECTs seguintes. O tempo para VACUUM() ´e medido separadamente.
Quando executando com o PostgreSQL 7.1.1 n˜ao podemos, entretando, executar com --
fast porque durante o teste de INSERT, o postmaster (daemon do PostgreSQL) finalizou
e o banco de dados ficou t˜ao corrompido que se tornou imposs´
ivel reiniciar o postmaster.
Depois disto ter acontecido duas vezes, decidimos adiar o teste com o --fast at´e a pr´oxima
vers˜ao do PostgreSQL. Os detalhes sobre a m´aquina na qual executamos o teste pode ser
encontrado na p´agina de testes comparativos em nosso site.
Antes de irmos para os outros testes comparativos que conhecemos, gostariamos de fornecer
algumas informa¸oes sobre os testes:
´
E muito f´acil escrever um teste demonstrando que ALGUM banco de dados ´e o melhor do
mundo, restringindo o teste apenas a alguma parte em que o banco de dados seja muito
bom e n˜ao testar outras partes que podem n˜ao ser. Se algu´em publica os resultados com
uma simples figura¸ao as coisas se tornam mais f´aceis ainda.
Seria como n´os med´
issemos a velocidade do MySQL comparada ao PostgreSQL olhando
para o resumo de tempo dos testes do MySQL na nossa p´agina. Desta forma o MySQL
poderia ser 40 vezes mais r´apido que o PostgreSQL, algo que com certeza n˜ao ´e verdade.
Poder´
iamos deixar a coisa ainda pior se peg´assemos o teste onde o PostgreSQL atuou pior
e falar que o MySQL ´e mais de 2000 vezes mais r´apido que o PostgreSQL.
O caso ´e que o MySQL faz v´arias otimiza¸oes que o PostgreSQL n˜ao faz. ´
E claro que isto
tamb´em ´e verdade do outro ladoa. Um otimizador SQL ´e uma coisa muito complexa e uma
empresa pode gastar anos apenas para deixar o otimizador cada vez mais r´apido.
Se vocˆe estiver consultando os resultados dos testes procure por coisas que sua aplica¸ao
utilize e use estes resultados apenas para decidir qual banco de dados ser´a o melhor para a
sua aplica¸ao. Os resultados dos testes comparativos tamb´em mostram onde um banco de
dados em particular n˜ao ´e bom e deve lhe fornecer uma no¸ao sobre coisas que devem ser
evitadas e o que vocˆe deve fazer de outras maneiras.
Conhecemos dois testes comparativos que mostram o PostgreSQL com mais velocidade que
o MySQL. Os dois s˜ao testes multi-usu´arios, um teste que n´os da MySQL AB ainda n˜ao
tivemos tempo para desenvolver e incluir no conjunto de testes comparativos principalmente
porque ´e uma enorme tarefa fazer isto de uma maneira justa para todos os bancos de dados.
Um ´e o teste comparativo pago da Great Bridge, o qual vocˆe pode ler a respeito em:
http://www.greatbridge.com/about/press.php?content_id=4.
Chapter 1: Informa¸oes gerais sobre o MySQL 73
Este ´e provavelmente o pior software de testes que j´a vimos alguem conduzir. Ele n˜ao s´o
foi preparado para testar exatamente o que o PostgreSQL tem de melhor, mas al´em disso
foi tamb´em injusto contra todos os outros bancos de dados envolvidos no teste.
NOTA: Sabemos que nem mesmo alguns dos principais desenvolvedores do PostgreSQL
gostam da maneira que a Great Bridge conduziu os testes comparativos, ent˜ao n˜ao os
culpamos pela maneira que os testes foram realizados.
Este comparativo tem sido condenado em v´arias mensagens postadas em listas de discuss˜oes
portanto falaremos aqui apenas das coisas que estavam erradas com ele.
Os testes foram executados com uma cara ferramenta comercial, que torna imposs´
ivel
para uma empresa open source como n´os confirmar os resultados , ou mesmo conferir
como os testes realmente foram feitos. A ferramenta nem mesmo ´e uma ferramenta
de testes comparativos de verdade, mas uma ferramenta de testes de aplica¸oes e con-
figura¸ao. Dizer que ela ´e uma ferramenta “padr˜ao” de testes comparativos ´e esconder
a verdade.
A pr´opria Great Bridge admitiu que eles otimizaram os testes para o banco de dados
PostgreSQL (com VACUMM() antes dos testes) e preparou os testes, coisa que n˜ao foi feita
para nenhum dos outros bancos de dados envolvidos. Para dizer “Este processo otimiza
´
indices e libera um pouco de espa¸co em disco. Os ´
indices otimizados aumentaram a
velocidade em alguns casos.” Nossos testes claramente indicam que a diferen¸ca em
executar v´arias selects em um banco de dados com e sem VACUUM() pode facilmente
diferenciar de um fator de dez.
Os resultados dos testes tamb´em foram estranhos. A documen¸ao do teste AS3AP
menciona que o teste faz “sele¸oes, joins simples, proje¸oes, agregados, atualiza¸oes de
uma tupla e atualiza¸oes em massa (bulk updates)”.
O PostgreSQL ´e bom fazendo SELECTs e JOINs (especialmente depois de um VACUUM(),
mas n˜ao atua t˜ao bem em INSERTs ou UPDATEs. Os comparativos parecem indicar que
somente SELECTs foram feitos (ou muito poucas atualiza¸oes). Isto pode facilmente
explicar porque os resultados foram t˜ao bons para o PostgreSQL neste teste. Os maus
resultados para o MySQL obviamente rebaixa este documento.
Eles executaram o t˜ao chamado benchmark de uma m´aquina Windows acessando uma
aquina Linux sobre ODBC, uma configura¸ao que nenhum usu´ario de banco de dados
comum faria se estive executando uma aplica¸ao pesada multi-usu´aria. Isto testou mais
o driver ODBC e o protocolo Windows usado entre os clientes do que o pr´oprio banco
de dados.
Executando o banco de dados contra o Oracle e o MS-SQL (A Great Bridge indicou
indiretamente os bancos de dados que eles usaram no teste), eles usaram o ODBC
no lugar do protocolo nativo. Qualquer um que j´a tenha usado o Oracle sabe que
aplica¸oes reais devem usar a interface nativa e n˜ao ODBC. Fazer um teste atrav´es de
ODBC e reinvidicar que os resultados n˜ao teinham rela¸ao alguma com as situa¸oes de
uso na vida real n˜ao deve ser tomado como justo. Eles deveriam ter feito dois testes
com e sem ODBC para fornecer o fatos reais (depois de contratar expecialistas para
preparar os bancos de dados involvidos).
A Great Bridge faz referencias aos testes TPC-C, mas n˜ao mencionam em lugar algum
que o teste que fizeram n˜ao foi realmente um teste TPC-C e eles nem mesmo estavam
permitidos a chamare-no de teste TPC-C. Um teste TPC-C s´o pode ser conduzido
74 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
pelas regras aprovadas pelo conselho TPC (http://www.tpc.org). A Great Bridge
ao fez isto. Com isto, violaram a marca registrada TPC e descreditado seus pr´oprios
comparativos. As regras criadas pelo conselho TPC s˜ao muito estritas para garantir
que ningu´em produza falsos resultados ou relatos improaveis. Aparentemente Great
Bridge n˜ao est´a interessada em fazer isto.
Depois do primeiro teste, n´os entramos em contato com a Great Bridge e mencionamos
algumas das falhas ´obvias que cometeram com o MySQL:
Utilizaram uma vers˜ao de depura¸ao do nosso driver ODBC
Executaram em um sistema Linux que n˜ao era otimizado para threads
Utilizaram uma vers˜ao antiga do MySQL quando existia uma nova vers˜ao mais
recomendada para o uso, j´a dispon´
ivel
ao inicializaram o MySQL com as op¸oes corretas para uso em sistemas multi-
usu´arios pesados (a instala¸ao padr˜ao do MySQL ´e preparada para uso m´
inimo de
recursos).
A Great Bridge executou um novo teste, com nosso driver ODBC otimizado e com
melhores op¸oes de inicializa¸ao para o MySQL, mas recusaram usar a nossa biblioteca
glibc atualizada ou nosso bin´ario padr˜ao (usado por 80% de nossos usu´arios), que utiliza
com uma biblioteca glibc corrigida.
Segundo o que sabemos, a Great Bridge n˜ao fizeram nada para assegurar que os outros
bancos de dados foram configurados corretamente para executar bem em seu ambiente
de testes. os temos certeza, entretanto, que eles n˜ao entraram em contato com a
Oracle ou a Microsoft para pedir seu conselho nesta quest˜ao ;)
Os testes comparativos foram pagos pela Great Bridge e eles decidiram publicar so-
mente resultados parciais selecionados (em vez de publicar todo o resultado).
Tim Perdue, um f˜a ass´
iduo do PostgreSQL e relutante usu´ario MySQL publicou uma com-
para¸ao em phpbuilder.
Quando ficamos sabendo da compara¸ao, ligamos para Tim Perdue pois existiam muitas
coisas estranhas nos seus resultados. Por exemplo, ele alega que o MySQL tem um problema
com cinco usu´arios nos seus testes, enquanto sabemos que existem usu´arios com equipamen-
tos similares que usam o MySQL com cerca de 2000 conex˜oes simultˆaneas executando 400
consultas por segundo. (Neste caso o limite foi a banda de rede, n˜ao o banco de dados.)
Nos pareceu que ele estivesse usando um Kernel Linux que tinha algum problema com v´arias
threads, como nos kernels antes da vers˜ao 2.4, que possuia um problema com threads em
aquinas multi-processadas. os documentamos neste manual a forma para corrigir isto e
Tim deve estar ciente deste problema.
Outro poss´
ivel problema pode ter sido uma biblioteca glibc antiga e que Tim n˜ao tenha
usando um bin´ario MySQL de nosso site, que ´e utiliza com uma biblioteca glibc correta,
por´em compilou uma vers˜ao pr´opria. Em qualquer dos casos acima, o sintoma poderia ter
sido exatamente o que Tim mediu.
Perguntamos ao Tim se poder´
iamos ter acesso aos dados para que pud´essemos repetir a
avalia¸ao e se ele poderia conferir a vers˜ao MySQL na m´aquina para descobrir o que estava
errado e ele prometeu nos dar um retorno. Isto ainda n˜ao foi feito.
Por causa disto n˜ao podemos depositar nossa confian¸ca nestes testes :(
Chapter 1: Informa¸oes gerais sobre o MySQL 75
As coisas mudaram com o tempo e os testes acima n˜ao s˜ao mais relevantes. O MySQL
agora tem alguns diferentes manipuladores de tabela com diferente custo-benef´
icio de ve-
locidade/concorrencia. See hundefinedi[Table types], page hundefinedi. Seria interessante
ver como os testes anteriores poderiam executar com os diferentes tipos de tabelas transa-
cionais no MySQL. ´
E claro que o PostgreSQL tamb´em ganhou novos recursos desde que o
teste foi feito. Como o teste acima n˜ao foi publicamente dispon´
ivel n˜ao existe forma para
os sabermos como o banco de dados poder´a atuar nos mesmos testes hoje.
Conclus˜ao:
Os ´unicos benchmarks que existem hoje que qualquer um pode baixar e executar contra o
MySQL e o PostgreSQL s˜ao os testes MySQL. N´os, na MySQL, acreditamos que bancos de
dados com c´odigo aberto devem ser testados com ferramentas de c´odigo aberto! Este ´e o
´unico modo para assegurar que ningu´em fa¸ca testes que n˜ao possam ser reproduzidos e os
use para alegar que um banco de dados ´e melhor que o outro. Sem conhecer todos os fatos
´e imposs´
ivel responder `as alega¸oes do testador.
O que achamos estranho ´e que todos os testes que temos visto sobre o PostgreSQL, que
´e imposs´
ivel de ser reproduzido, alega que o PostgreSQL ´e melhor na maioria dos casos
enquanto em nossos testes, que qualquer um pode reproduzir, mostra claramente o contr´ario.
Com isto n´os n˜ao queremos dizer que o PostgreSQL n˜ao ´e bom em v´arias coisas (ele ´e!)
ou que ele n˜ao ´e mais r´apido que o MySQL sobre certas condi¸oes. os s´o gostariamos
de ver um teste justo que seja realmente muito bom, para que ent˜ao pudessemos ter uma
competi¸ao amig´avel!
Para maiores informa¸oes sobre nosso pacote de testes See hundefinedi[MySQL Bench-
marks], page hundefinedi.
Estamos trabalhando em um pacote de testes ainda melhor, incluindo testes multi usu´arios,
e uma melhor documenta¸ao do que os testes individuais realmente fazem e como adicionar
mais testes ao pacote.
1.6 MySQL e o futuro (o TO-DO)
Este apendice lista os recursos que planejamos implementar no MySQL.
Tudo nesta lista est´a, aproximadamente, na ordem em que ser˜ao feitas. Se vocˆe desejar
alterar a ordem de prioridades, por favor registre uma licen¸ca ou suporte e nos diga o
que vocˆe quer que seja feito mais rapidamente. See hundefinedi[Licensing and Support],
page hundefinedi.
O plano ´e que, no futuro, os suportaremos completamente o padr˜ao ANSI SQL99, mas com
arias extens˜oes ´uteis. O desafio ´e fazer isto sem sacrificar a velocidade ou comprometer o
odigo.
1.6.1 Coisas que devem constar na Vers˜ao 4.0
os planejamos fazer da vers˜ao 4.0 uma distribui¸ao “r´apida” na qual s´o adicionamos coisas
novas para que outras pessoas possam nos ajudar no desenvolvimento de novos recursos para
a vers˜ao 4.1. O MySQL vers˜ao 4.0 deve levar aproximadamente um mˆes para que possamos
torn´a-la est´avel e iniciar o desenvolvimento da vers˜ao 4.1. A vers˜ao 4.0 deve ter os seguintes
recursos:
76 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A se¸ao de novidades para a 4.0 inclui uma lista dos recursos que n´os j´a implementamos na
´arvore 4.0. See hundefinedi[News-4.0.x], page hundefinedi.
Novo formato do arquivo de defini¸ao de tabela (arquivos .frm). Isto nos permitir´a
que n˜ao tenhamos problemas de bits quando adicionarmos mais op¸oes de tabelas. O
formato antigo .frm ainda poder´a ser usado com o 4.0. Todas novas tabelas, entretanto,
usar˜ao o novo formato.
O novo formato de arquivo permitir´a adicionar novos tipos de colunas, mais op¸oes
para chaves e suporte a Chave Estrangeira.
mysqld como uma biblioteca. Isto ter´a a mesma interface como o cliente padr˜ao MySQL
(com uma fun¸ao extra para configurar apenas parˆametros de inicializa¸ao) mas ser´a
mais r´apido (sem sobrecarga do TCP/IP ou do socket), menor e mais f´acil para usar
para produtos embutidos.
Poderemos definir em tempo de liga¸ao se queremos usar o modelo cliente/servidor ou
uma aplica¸ao isolada apenas definindo com qual biblioteca deve ser ligada.
Omysqld ir´a suportar todos recursos padr˜ao do MySQL e podemos us´a-lo num cliente
que suporte threads para executar diferentes consultas em cada thread.
A replica¸ao deve trabalhar com RAND() e vari´aveis de usu´ario @var.
Backup Online com penalidade m´
inima de performance. O backup online ir´a facilitar
para adicionar um novo escravo de replica¸ao sem ter que desligar o mestre.
DELETE FROM nome_tabela ir´a retornar o n´umero de linhas apagadas. Para execu¸ao
mais r´apida use TRUNCATE nome_tabela.
Permite que DELETE em tabelas MyISAM use o cache de registros. Para fazer isto,
precisaremos atualizar os threads de cache de registros quando atualizarmos o arquivo
.MYD
Melhor replica¸ao.
Mais fun¸oes para pesquisas textuais. See hundefinedi[Fulltext Features to Appear in
MySQL 4.0], page hundefinedi.
Elenco de conjuntos de caracteres e sintaxe para manipular multiplos conjunto.
Permite usu´arios para alterar op¸oes de inicializa¸ao sem parar o servidor.
Ajuda para todos comandos no cliente.
Conex˜oes seguras (com SSL).
Extender o otimizador para otimizar algumas consultas ORDER BY key_name DESC
SHOW COLUMNS FROM nome_tabela (usado pelo cliente mysql para permitir expans˜oes
de nomes de colunas) n˜ao deve abrir a tabela, mas somente o arquivo de defini¸ao. Isto
ir´a exigir menos mem´oria e ser´a mais r´apido.
Nova chave de cache
Quando usar SET CHARACTER SET devemos traduzir a toda consulta e n˜ao somente
strings. Isto ir´a habilitar os usu´arios para usarem os caracteres traduzidos no banco de
dados, nome de colunas e tabelas.
Adicionar uma interface port´avel sobre gethostbyaddr_r() para que possamos alterar
ip_to_hostname() para n˜ao bloquear outras threads enquanto faz consultas DNS.
Adicionar o m´etodo record_in_range() para tabelas MERGE para ser poss´
ivel escolher
o´
indice correto quando existir v´arios que possam ser escolhidas. Devemos tamb´em
Chapter 1: Informa¸oes gerais sobre o MySQL 77
extender a interface de informa¸oes para obter a distribui¸ao de chaves para cada
´
indice, se analyze estiver executando em todas sub-tabelas.
SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP].
1.6.2 Coisas que devem ser feitas em um futuro bem pr´oximo
Replica¸ao livre de falhas.
Subqueries. select id from t where grp in (select grp from g where u > 100)
Tabelas derivadas.
select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a,
other_table b where a.col1=b.col1
Isto podia ser feito automaticamente criando tabelas tempor´arias para as tabelas
derivadas na dura¸ao da consulta.
Adicionar PREPARE de instru¸oes e envio de parˆametros para mysqld.
Extender o protocolo cliente/servidor para suportar avisos.
Adicionar op¸oes ao protocolo cliente/servidor para obter notas de progresso para co-
mandos de longo tempo de execu¸ao.
Adicionar bancos de dados e nomes reais de tabelas (no caso de apelidos (alias)) `a
estrutura MYSQL FIELD.
ao permitir mais que um n´umero definido de threads para executar a recupera¸ao
MyISAM ao mesmo tempo.
Alterar INSERT ... SELECT para opcionalmente usar inser¸oes concorrentes.
Implementar RENAME DATABASE. Para tornar isto seguro para todos handlers de tabelas,
ele funcionar´a assim:
Cria o novo banco de dados.
Muda o nome de todas as tabelas para o outro banco de dados, como n´os fazemos
com o comando RENAME.
Remove o banco de dados antigo.
Retornar o tipo do campo original quando fizer SELECT MIN(column) ... GROUP BY.
M´ultiplos conjuntos de resultados.
Alterar o protocol para permitir transferˆencia bin´aria de valores. Para faze-lo eficien-
temente, precisamos adicionar uma API para podermos casar as vari´aveis.
Torna poss´
ivel especificar long_query_time com precis˜ao em microsegundos.
Adicionar um prompt configur´avel para o cliente de linha de comando mysql com
op¸oes do tipo banco de dados em uso, hora e data...
Adicionar conferˆencia do alcance para tabelas MERGE.
Ligar o c´odigo myisampack no servidor.
Portar o MySQL para o BeOS.
Portar os clientes MySQL para LynxOS.
Adicionar um cache de buffer para chave tempor´aria durante INSERT/DELETE/ UPDATE
para que possamos fazer uma recupera¸c`ao f´acil se o arquivo de ´
indice encher.
78 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe executar um ALTER TABLE em uma tabela que ´e ligada simbolicamente a outro
disco, criar tabelas tempor´arias neste disco.
Implementar um tipo DATE/DATETIME para manipular fusos hor´arios corretamente para
lidarmos mais facilmente com datas em diferentes fusos hor´arios.
FreeBSD e MIT-pthreads; Deixar threads “dormindo” exigem processamento?
Conferir se threads travadas exige processamento
Corrigir o configure para que ele possa compilar todas as bibliotecas (como a MyISAM)
sem threads.
Adicionar uma op¸ao para periodicamente descarregar p´aginas chave para tabelas com
chaves atrasadas se elas n˜ao forem usadas em um certo espa¸co de tempo.
Permitir “join” em partes de chaves (quest˜ao de otimiza¸ao).
INSERT SQL_CONCURRENT emysqld --concurrent-insert para fazer inser¸oes concor-
rentes no final do arquivo se o arquivo for travado para leitura.
Armazenar defini¸oes de chaves ESTRANGEIRAS no arquivo ‘.frm’.
Cascatear o DELETE
Cursores do lado do servidor.
Conferir se o lockd trabalha com kernels Linux mais modernos; Se n˜ao n´os teremos
que corrigir o lockd! Para testar isto, inicie mysqld com --enable-locking e execute
os diferentes pacotes de testes fork*. Se eles n˜ao retornarem erros, lockd funciona.
Permite vari´aveis SQL no LIMIT, como em LIMIT @a,@b.
Permite atualiza¸ao de vari´aveis nas instru¸oes UPDATE. Por exemplo: UPDATE TABLE
foo SET @a=a+b,a=@a, b=@a+c
Alterar quando vari´aveis de usu´arios s˜ao atualizadas para ique possam ser usadas com
GROUP BY, como no exemplo seguinte : SELECT id, @a:=count(*), sum(sum_col)/@a
FROM nome_tabela GROUP BY id.
ao adicionar valores DEFAULT para as colunas. Isto retorna um erro quando se usa
um INSERT que n˜ao contenha uma coluna n˜ao tenham um DEFAULT.
Cache de pesquisas e resultados. Isto deve ser feito como um m´odulo separado que
examina cada pesquisa e se a mesma estiver no cache o resultado memorizado deve
ser retornado. Quando algu´em atualiza uma tabela deve se remover algumas queries
do cache. Isto dever´a fornecer um grande incremento de velocidade em m´aquinas com
bastante mem´oria onde pesquisas s˜ao muito repetidas (como aplica¸oes WWW). Uma
id´eia seria armazenar no cache somente pesquisas do tipo: SELECT CACHED ...
Corrigir ‘libmysql.c’ para permitir dois comandos mysql_query() em uma linha sem
ler os resultados ou fornecer uma mensagem de erro quando algu´em o fizer.
Otimizar o tipo BIT para ocupar 1 bit (hoje BIT ocupa 1 char).
Checar porque MIT-pthreads ctime() ao funciona em alguns sistemas FreeBSD.
Adicionar uma op¸ao IMAGE para LOAD DATA INFILE para n˜ao atualizar campos
TIMESTAMP eAUTO_INCREMENT.
Adicionar sintaxe LOAD DATE INFILE... UPDATE.
Para tabelas com chaves prim´arias, se os dados contˆem a chave prim´aria, entradas
que combinem com a chave prim´aria s˜ao atualizadas do resto das colunas. Entre-
tanto, colunas FALTANDO na entrada de dados n˜ao s˜ao mudadas.
Chapter 1: Informa¸oes gerais sobre o MySQL 79
Para tabelas com chaves prim´arias que falta alguma parte da chave na entrada de
dados, ou que n˜ao tenha chave prim´aria, a entrada ´e tratada como em LOAD DATA
INFILE ... REPLACE INTO.
Fazer o LOAD DATA INFILE entender sintaxes do tipo:
LOAD DATA INFILE ’file_name.txt’ INTO TABLE nome_tabela
TEXT_FIELDS (text_field1, text_field2, text_field3)
SET table_field1=concatenate(text_field1, text_field2), table_field3=23
IGNORE text_field3
Isto pode ser usado para saltar colunas extras no arquivo texto, ou
atualizar colunas baseadas em express~oes dos dados lidos...
LOAD DATA INFILE ’file_name’ INTO TABLE ’nome_tabela’ ERRORS TO err_nome_
tabela Esta forma permite que quaisquer erros e avisos sejam logados na tabela
err nome tabela. Essa tabela deve ter uma estrutura como:
line_number - N´umero da linha no arquivo de dados
error_message - A mensagem de erro/aviso
e talvez
data_line - A linha do arquivo de dados
Adicionar real suporte a VARCHAR (J´a existe suporte para isto no MyISAM).
Sa´
ida autom´atica do mysql para o netscape.
LOCK DATABASES. (com v´arias op¸oes)
Alterar ordena¸ao para alocar mem´oria em “grandes partes” para conseguir melhor
utiliza¸ao de mem´oria.
Tipos DECIMAL eNUMERIC ao podem ler n´umeros exponenciais; Field_
decimal::store(const char *from,uint len) deve ser reescrito para corrigir
isto.
Fun¸oes: ADD TO SET(valor,conjunto) e REMOVE FROM SET(valor,conjunto)
Adicionar uso de t1 JOIN t2 ON... et1 JOIN t2 USING ... Atualmente, vocˆe s´o pode
usar esta sintaxe com LEFT JOIN.
Adicionar suporte pleno para o tipo unsigned long long.
arias vari´aveis a mais para show status. Contadores para: Instru¸oes
INSERT/DELETE/UPDATE. Registros lidos e atualizados. Selects em 1 tabela e selects
com joins. N´umero real de tabelas em uma select. N´umero de consultas ORDER BY e
GROUP BY.
Se vocˆe abortar o mysql no meio de uma pesquisa, vocˆe deve abrir outra conex˜ao e
matar a pesquisa antiga. Alternativamente, deve ser feita uma tentativa para detectar
isto no servidor.
Adicionar uma interface de manioula¸ao para as informa¸oes de tabelas para que se
possa us´a-la como uma tabela de sistema. Pode se tornar um pouco lento se forem
requisitadas informa¸oes sobre todas as tabelas, mas muito flex´
ivel. SHOW INFO FROM
nome_tabela para informa¸oes b´asicas de tabelas devem tamb´em ser implementadas.
Adicionar suporte para UNICODE.
NATURAL JOIN eUNION JOIN
80 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Permitir select A from crash_me left join crash_me2 using (A); Neste caso A ´e
assumido para vir da tabela crash me.
Corrigir o ON eUSING para funcionar com o tipo de uni˜ao JOIN.
CONNECT BY PRIOR ..., como Oracle, para psquisas em estruturas hier´arquicas.
mysqladmin copy database new-database. – Nececssita do comando COPY para ser
adicionado ao mysqld
Lista de processos deve exibir n´umero de consultas/thread.
SHOW HOSTS exibir´a informa¸oes sobre o cache de nomes de m´aquinas.
Op¸oes DELETE eREPLACE para a instru¸ao UPDATE (esta op¸ao apagar´a registros quando
um erro de chave duplicada for obtido durante a atualiza¸ao.
Alterar o formato de DATETIME para armazenar fra¸oes de segundos.
Adicionar todos os tipos ANSI92 e ODBC 3.0 que ainda faltam.
Alterar nomes de tabelas de strings vazias para NULL para colunas calculadas.
ao usar ’Item copy string’ em valors num´ericos para evitar convers˜ao de n´umero-
>string->n´umero no caso de: SELECT COUNT(*)*(id+0) FROM nome_tabela GROUP BY
id
Tornar poss´
ivel o uso da nova biblioteca GNU regexp em vez da atual (A biblioteca
GNU deve ficar muito mais r´apida do que a atual).
Alterar o ALTER TABLE para que n˜ao aborte clientes que executam INSERT DELAYED.
Corrigir quando as colunas referenciadas em uma cl´ausula UPDATE cont´em os valores
antigos antes da atualiza¸ao iniciar.
myisamchk,REPAIR eOPTIMIZE TABLE devem conseguir tratar casos onde os arquivos
de dados e/ou ´
indices s˜ao links simolicos.
Adicionar simula¸ao de pread()/pwrite() no Windows para habilitar inser¸oes si-
multˆaneas.
Um analisador de arquivos log que podem analisar informa¸oes sobre quais tabelas
ao acessadas mais frequentemente, qual a frequˆencia que joins de multi-tabelas s˜ao
executadas, etc. Ele dever´a ajudar os usu´arios a identificar ´areas ou projetos de tabelas
que poder˜ao ser otimizadas para executar consultas muito mais eficientes.
Adicionar SUM(DISTINCT)
Adicionar fun¸oes de grupo ANY(),EVERY() eSOME(). Em ANSI SQL isto s´o fun-
ciona em colunas boleanas, mas n´os podemos extendˆe-las para trabalhar em qualquer
coluna/express˜ao aplicando: valor == 0 ->FALSO e valor <> 0 ->TRUE.
Corrigir o tipo para MAX(coluna) ser o mesmo que o tipo da coluna.
create table t1 (a DATE);
insert into t1 values (now());
create table t2 select max(a) from t1;
show columns from t2;
Vir com uma nova sintaxe para uma express˜ao que ir´a fazer um UPDATE no registro se
ele existir e fazer um INSERT de um novo registro se o mesmo n˜ao existir. (Como o
REPLACE trabalha com INSERT /DELETE)
Chapter 1: Informa¸oes gerais sobre o MySQL 81
1.6.3 Coisas que em algum dia devem ser feitas
Implementar fun¸ao: get_changed_tables(timeout,table1,table2,...)
Atualiza¸oes atˆomicas multi-tabelas, ex: update items,month set
items.price=month.price where items.id=month.id;;
Alterar leitura atrav´es de tabelas para usar mapeamento de mem´oria quando poss´
ivel.
Atualmente somente tabelas compactadas usam mapeamento de mem´oria.
Adicionar um novo privil´egio ’Show priv’ para comandos SHOW.
Tornar o c´odigo de timestamp autom´atico melhor. Adicionar timestamps para o log
de atualiza¸oes com SET TIMESTAMP=#;
Usar mutex de leitura/escrita em alguns lugares para obter maior velocidade.
Suporte pleno a chave estrangeira. Provavelmente implementairemos uma linguagem
procedural primeiro.
Views simples (inicialmente em uma tabela, depois em qualquer express˜ao).
Fechar algumas tabelas automaticamente se uma tabela, tabela tempor´aria ou arquivos
tempor´arios obtiverem o erro 23 (n˜ao pode abrir arquivos suficientes).
Quando algu´em encontra um campo=#, mude todas as ocorrˆencias do campo para #.
Agora isto ´e feito somente para alguns casos simples.
Alterar todas express˜oes const com express˜oes calculadas se poss´
ivel.
Chave otimizadora = express˜ao. No momento somente a chave = campo ou a chave =
constante s˜ao otimizadas.
Melhorar o c´odigo de algumas das fun¸oes de c´opia
Alterar ‘sql_yacc.yy’ para um analizador em linha para reduzir seu tamanho e obter
melhores mensagems de erro (5 dias).
Alterar o analisador para usar somente uma regra para diferentes n´umeros de argu-
mentos em uma fun¸ao.
Utilizar nomes de c´alculo completos na parte de ordena¸ao. (For ACCESS97)
UNION,MINUS,INTERSECT eFULL OUTER JOIN. (Atualmente somente o LEFT OUTER
JOIN ´e suportado)
Permitir UNIQUE em campos que podem ser NULL.
SQL_OPTION MAX_SELECT_TIME=# para colocar um limite de tempo em uma pesquisa.
Fazer o log de atualiza¸oes gravar em um banco de dados.
LIMIT negativo para recuperar dados do fim.
Alarmes em fun¸oes clientes de conex˜ao, leitura e escrita.
Por favor, perceba as altera¸oes ao safe_mysqld: de acordo com o FSSTND (que o
Debian tenta seguir) arquivos PID dever ir em ‘/var/run/<progname>.pid’ e arquivos
de log em ‘/var/log’. Seria ´otimo se vocˆe puder colocar o diret´orio de dados na
primeira declara¸ao de "pidfile"e"log", para que a coloca¸ao destes arquivos possa
ser alterada com uma simples instru¸ao.
Permitir um cliente requisitar log.
Adicionar uso de zlib() para arquivos gzip para funcionar com LOAD DATA INFILE
Corrigir ordena¸ao e agrupamento de colunas BLOB (parcialmente resolvida agora).
82 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Stored procedures. Atualmente isto n˜ao ´e tratado com muito importante j´a que as
stored procedures n˜ao est˜ao muito bem padronizadas ainda. Outro problema ´e que
verdadeiras stored procedures dificultam muito o otimizador e em v´arios casos o resul-
tado ´e mais lento que antes. os iremos, por outro lado, adicionar uma linguagem de
atualiza¸ao (atˆomica) simples que pode ser usada para escrever loops e semelhantes no
servidor MySQL.
Alterar para o uso de sem´aforos quando contar threads. Devemos primeiro implementar
uma biblioteca de sem´aforos para a MIT-pthreads.
N0˜ao atribuir novos valores AUTO_INCREMENT quando algu´em configurar uma coluna
para 0. No lugar disto usar NULL.
Adicionar suporte pleno para JOIN com parˆenteses.
Como uma alternativa para uma thread / conex˜ao gerencie uma fila de threads para
manipular as pesquisas.
Permitir obter mais de um bloqueio com GET_LOCK. Quando isto for feito, ser˜ao,
tamb´em, tratados os poss´
iveis deadlocks que essa altera¸ao ir´a acarretar.
Tempo ´e fornecido de acordo com a quantidade de trabalho, e n˜ao tempo real.
1.6.4 Algumas coisas que n˜ao temos planos para fazer
Nada; Planejamos ser totalmente compat´
iveis com o ANSI 92 / ANSI 99.
Chapter 2: Instala¸ao do MySQL 83
2 Instala¸ao do MySQL
Este cap´
itulo descreve como obter e instalar o MySQL:
Para uma lista de sites no quais vocˆe pode obter o MySQL, veja hundefinedi[Getting
MySQL], page hundefinedi.
Para saber quais s˜ao as plataformas suportadas, veja em hundefinedi[Which OS],
page hundefinedi. Por favor perceba que nem todas as plataformas suportadas s˜ao
igualmente boas para executar o MySQL. Algumas s˜ao mais robustas e eficientes que
outras - ver hundefinedi[Which OS], page hundefinedipara detalhes.
arias vers˜oes do MySQL est˜ao dispon´
iveis em distribui¸oes bin´arias e fonte. os
tamb´em fornecemos acesso p´ublico `a nossa ´arvore fonte atual para aqueles que desejam
ver nossos desenvolvimentos mais recentes e nos ajudar a testar novos c´odigos. Para
determinar que vers˜ao e tipo da distribui¸ao vocˆe deve usar, veja hundefinedi[Which
version], page hundefinedi. Se ainda restar d´uvidas, use a distribui¸ao bin´aria.
Instru¸oes de instala¸ao para distribui¸oes bin´aria e fonte s˜ao descritos em hundefinedi
[Installing binary], page hundefinediehundefinedi[Installing source], page hundefinedi.
Cada conjunto de instru¸oes inclui uma se¸ao sobre problemas espec´
ificos de sistemas
que vocˆe pode precisar.
Para procedimentos p´os-instala¸ao, veja hundefinedi[Post-installation], page hunde-
finedi. Estes procedimentos podem ser aplicados caso vocˆe use uma distribui¸ao bin´aria
ou fonte do MySQL.
2.1 Instala¸ao r´apida padr˜ao do MySQL
2.1.1 Instalando o MySQL no Linux
O caminho recomendado para instalar o MySQL no Linux ´e usando um arquivo RPM. Os
RPMs do MySQL atualmente s˜ao constru´
idos na vers˜ao 6.2 do sistema RedHat Linux mas
deve funcionar em outras vers˜oes de Linux que suportam rpm e usam glibc.
Se vocˆe tiver problemas com um arquivo RPM, por exemplo, se vocˆe receber o erro “Sorry,
the host ’xxxx’ could not be looked up”, veja hundefinedi[Binary notes-Linux],
page hundefinedi.
Os arquivos RPM que vocˆe provavelmente usar´a s˜ao:
MySQL-VERSION.i386.rpm
O servidor MySQL. Vocˆe ira precisar disto a n˜ao ser que vocˆe s´o deseje somente conectar
a um servidor MySQL executando em outra m´aquina.
MySQL-client-VERSION.i386.rpm
Os programas clientes padr˜oes do MySQL. Provavelmente vocˆe sempre instalar´a este
pacote.
MySQL-bench-VERSION.i386.rpm
Testes e comparativos de performances (benchmarks). Necessita Perl e RPMs msql-
mysql-modules.
84 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MySQL-devel-VERSION.i386.rpm
Bibliotecas e arquivos include necess´arios se vocˆe desejar compilar outros clientes
MySQL, como nos m´odulos Perl.
MySQL-VERSION.src.rpm
Este cont´em o c´odigo fonte para todos os pacotes acima. Ele tamb´em pode ser usado
para tentar construir RPMs para outras arquiteturas (por exemplo, Alpha ou SPARC).
Para ver todos os arquivo em um pacote RPM, execute:
shell> rpm -qpl MySQL-VERSION.i386.rpm
Para realizar uma instala¸ao m´
inima padr˜ao, execute:
shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm
Para instalar somente o pacote cliente, execute:
shell> rpm -i MySQL-client-VERSION.i386.rpm
O RPM coloca dados em ‘/var/lib/mysql’. O RPM tamb´em cria as entradas apropriadas
em ‘/etc/rc.d/’ para iniciar o servidor automaticamente na hora do boot. (Isto significa
que se vocˆe realizou uma instala¸ao anterior, talvez voe deseje criar uma c´opia do seu
arquivo de inicialializa¸ao instalado anteriormente se vocˆe fez alguma altera¸ao no mesmo,
para que vocˆe n˜ao perca suas altera¸oes.)
Depois de instalar o(s) arquivo(s) RPM, o daemon mysqld deve estar rodando e vocˆe j´a
deve poder iniciar o uso do MySQL. See hundefinedi[Post-installation], page hundefinedi.
Se alguma coisa der errado, vocˆe encontrar maiores informa¸oes no cap´
itulo de instala¸ao.
See hundefinedi[Installing binary], page hundefinedi.
2.1.2 Instalando o MySQL no Windows
As seguintes instru¸oes aplicam para distribui¸oes bin´arias pr´e-compiladas Se vocˆe fizer o
download de uma distribui¸ao fonte, vocˆe deve compil´a-lo e instal´a-lo por conta pr´opria.
Se vocˆe n˜ao possui uma c´opia de uma distribui¸ao MySQL, a primeira coisa a fazer ´e o
download em http://www.mysql.com/downloads/mysql-3.23.html.
Se vocˆe deseja conectar ao MySQL de algum outro programa, voe provavelmente pre-
cisar´a do driver MyODBC, que pode ser encontrado na p´agina de download MyODBC
(http://www.mysql.com/downloads/api-myodbc.html).
Para instalar alguma das distribui¸c˜oes, descompacte-a em algum diret´orio vazio e execute
o programa Setup.exe.
Por defini¸ao, o MySQL-Windows ´e configurado para ser instalado em ‘c:\mysql’. Se vocˆe
deseja instalar o MySQL em outro lugar, instale-o primeiramente em ‘c:\mysql’, enao
mova a instala¸ao para onde vocˆe preferir. Se vocˆe mover o MySQL, deve indicar onde
est´a localizado usando a op¸ao --basedir quando iniciar o servidor. Por exemplo, se vocˆe
mover a distribui¸ao MySQL para ‘d:\programs\mysql’, vocˆe deve iniciar o mysqld assim:
C:\> D:\programs\mysql\bin\mysqld --basedir D:\programs\mysql
Use mysqld --help para mostrar todas as op¸oes que o mysqld aceita!
Em todas novas vers˜oes do MySQL, vocˆe pode tamb´em criar um arquivo ‘c:\my.cnf
que guarda todas as op¸oes padr˜oes para o servidor MySQL. Copie o arquivo
\mysql\my-xxxx.cnf’ para ‘c:\my.cnf’ e edite-o para atender suas necessidades. Perceba
Chapter 2: Instala¸ao do MySQL 85
que vocˆe deve especificar todos caminhos com ‘/’ em vez de ‘\’. Se vocˆe usar ‘\’, vocˆe
precisa especific´a-lo dobrado, porque ‘\ ´e o caractere escape no MySQL. See hundefinedi
[Option files], page hundefinedi.
Iniciado com o MySQL 3.23.38, a distribui¸ao Windows inclui ambos bin´arios, normal e o
MySQL-Max. O principal benef´
icio de usar o bin´ario normal mysqld.exe ´e que ele ´e um
pouco mais r´apido e usa menos menos recursos.
Aqui est´a uma lista dos diferentes servidores MySQL que voe pode usar:
mysqld Compilado com debugger integral e conferˆencia autom´atica de
aloca¸ao de mem´oria, links simolicos, BDB e tabelas InnoDB.
mysqld-opt Bin´ario otimizado sem suporte para tabelas transacionais.
mysqld-nt Bin´ario otimizado para Nt com suporte para named pipes. vocˆe
pode executar esta vers˜ao no Win98, mas neste caso n˜ao s˜ao cri-
ados named pipes e vocˆe deve ter TCP/IP instalado.
mysqld-max Bin´ario otimizado com suporte para links simolicos, tabelas BDB
e InnoDB.
mysqld-max-nt Como o mysqld-max, por´em compilado com suporte para named
pipes.
Incluido a partir da vers˜ao 3.23.50, named pipes estar´a habilitado somente se o mysqld ´e
iniciado com a op¸ao --enable-named-pipe
Todos os bin´arios acima s˜ao otimizados para o processador Pentium Pro mas deve funcionar
em qualquer processador Intel >=i386.
Nota: Se vocˆe deseja utilizar as tabelas InnoDB, existem algumas op¸oes de inicializa¸ao que
devem ser especificadas no seu arquivo ‘my.ini’ See hundefinedi[InnoDB start], page hun-
definedi
2.2 Detalhes Gerais de Instala¸ao
2.2.1 Como obter o MySQL
Confira a home page do MySQL para informa¸oes sobre a vers˜ao atual e para instru¸oes de
download.
Nosso principal espelho de download est´a localizado em: http://download.sourceforge.net/mirrors/mysql/
Se vocˆe est´a interessado em se tornar um site espelho do MySQL, voe deve fazer sin-
cronismo anˆonimo com: rsync://download.sourceforge.net/mysql/. Envie e-mail para
webmaster@mysql.com nos notificando sobre seu espelho para ser adicionado na lista abaixo.
Se vocˆe tiver problemas com o download de nosso site principal, tente usar algum dos
espelhos listados abaixo.
Por favor relate espelhos ruins ou desatualizados ao webmaster@mysql.com.
Europa:
Austria [Univ. of Technology/Vienna] WWW FTP
Bulgaria [online.bg/Sofia] WWW FTP
Republica Tcheca [Masaryk University in Brno] WWW FTP
Republica Tcheca [www.sopik.cz] WWW
Republica Tcheca [www.gin.cz] WWW FTP
86 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Dinarca [Borsen] WWW
Dinamarca [SunSITE] WWW FTP
Estonia [OKinteractive] WWW
Fran¸ca [mtesa.net] WWW
Fran¸ca [fastorama.com, Chatenois] WWW FTP
Finlandia [tonnikala.net] WWW
Alemanha [Kernelnotes.de, Bonn] WWW FTP
Alemanha [Wolfenbuettel] WWW FTP
Grecia [NTUA, Athens] WWW FTP
Hungria [Xenia] WWW FTP
Hungria [TiszaneT] WWW FTP
Hungria [stop.hu] WWW
Islandia [GM] WWW FTP
Italia [feelinglinux.com] WWW
Italia [Teta Srl] WWW
Italia [tzone.it] WWW
Irlanda [Esat Net] WWW FTP
Latvia [linux.lv] FTP
Holanda [Silverpoint] WWW
Holanda [Widexs BV] WWW FTP
Holanda [ProServe] WWW
Polonia [Sunsite] WWW FTP
Polonia [ncservice.com/Gdansk] WWW
Portugal [Netc] WWW FTP
Romenia [roedu.net/Bucharest] FTP
Russia [DirectNet] WWW FTP
Russia [Scientific Center/Chernogolovka] FTP
Suecia [Sunet] WWW FTP
Sui¸ca [Sunsite] WWW FTP
Reino Unido [PLiG/UK] WWW FTP
Ucrania [PACO] WWW FTP
Ucrania [ISP Alkar Teleport/Dnepropetrovsk] WWW
Yugoslavia [bolex.co.yu] WWW FTP
America do Norte:
Canada [Tryc] WWW
USA [Hurricane Electric/San Jose] WWW
USA [ValueClick, Los Angeles CA] WWW FTP
EUA [Wisconsin University/Wisconsin] WWW FTP
Chapter 2: Instala¸ao do MySQL 87
EUA [LinuxWired/Scottsdale, AZ] WWW FTP
EUA [adgrafix.com/Boston, MA] WWW
EUA [netNumina/Cambridge, MA] WWW
EUA [Ahaza Systems/Seattle, WA] WWW FTP
Am´erica do Sul:
Argentina [bannerlandia.com] WWW FTP
Chile [Vision] WWW
Chile [PSINet] WWW FTP
Chile [Tecnoera] WWW
Asia:
China [linuxforum.net] WWW
China [HKLPG/Hong Kong] WWW
China [Gremlins/Hong Kong] WWW FTP
China [shellhung.org/Hong Kong] WWW FTP
Indonesia [incaf.net] WWW
Indonesia [web.id] WWW FTP
Jap˜ao [Soft Agency] WWW
Jap˜ao [u-aizu.ac.jp/Aizu] FTP
Coreia do Sul [Webiiz] WWW
Coreia do Sul [PanworldNet] WWW
Singapura [HJC] WWW FTP
Taiwan [TTN] WWW
Taiwan [nctu.edu/HsinChu] WWW
Africa:
Africa do Sul[Mweb] WWW
Africa do Sul [The Internet Solution/Johannesburg] FTP
2.2.2 Sistemas Operacionais suportados pelo MySQL
os ulitizamos o GNU Autoconf, para que seja poss´
ivel portar o MySQL para todos sis-
temas operacionais modernos com threads Posix funcionando e um compilador C++. (Para
compilar somente o c´odigo cliente, um compilador C++ ´e necess´ario mas threads n˜ao.) os
mesmos usamos e desenvolvemos o software primariamente em Sun Solaris (Vers˜oes 2.5 -
2.7) e SuSE Linux Vers˜ao 7.x.
Perceba que para alguns sistemas operacionais, o suporte nativo a thread funciona somente
nas ´ultimas vers˜oes. O MySQL compila com sucesso nas seguintes combina¸oes de sistema
operacional/pacote de thread:
AIX 4.x com threads nativas. See hundefinedi[IBM-AIX], page hundefinedi.
Amiga.
88 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
BSDI 2.x com o pacote inclu´
ido MIT-pthreads. See hundefinedi[BSDI], page hunde-
finedi.
BSDI 3.0, 3.1 e 4.x com threads nativas. See hundefinedi[BSDI], page hundefinedi.
DEC Unix 4.x com threads nativas. See hundefinedi[Alpha-DEC-UNIX], page hunde-
finedi.
FreeBSD 2.x com o pacote inclu´
ido MIT-pthreads. See hundefinedi[FreeBSD],
page hundefinedi.
FreeBSD 3.x e 4.x com threads nativas. See hundefinedi[FreeBSD], page hundefinedi.
HP-UX 10.20 com o pacote inclu´
ido MIT-pthreads. See hundefinedi[HP-UX 10.20],
page hundefinedi.
HP-UX 11.x com as threads nativas. See hundefinedi[HP-UX 11.x], page hundefinedi.
Linux 2.0+com LinuxThreads 0.7.1+ou glibc 2.0.7+. See hundefinedi[Linux],
page hundefinedi.
Mac OS X Server. See hundefinedi[Mac OS X], page hundefinedi.
NetBSD 1.3/1.4 Intel e NetBSD 1.3 Alpha (Necessita GNU make). See hundefinedi
[NetBSD], page hundefinedi.
OpenBSD >2.5 com threads nativas. OpenBSD <2.5 com o pacote inclu´
ido MIT-
pthreads . See hundefinedi[OpenBSD], page hundefinedi.
OS/2 Warp 3, FixPack 29 e OS/2 Warp 4, FixPack 4. See hundefinedi[OS/2], page hun-
definedi.
SGI Irix 6.x com threads nativas. See hundefinedi[SGI-Irix], page hundefinedi.
Solaris 2.5 e superior com threads nativas nas plataformas SPARC e x86. See hunde-
finedi[Solaris], page hundefinedi.
SunOS 4.x com o pacote inclu´
ido MIT-pthreads. See hundefinedi[Solaris], page hun-
definedi.
SCO OpenServer com o port recente do pacote FSU Pthreads. See hundefinedi[SCO],
page hundefinedi.
SCO UnixWare 7.0.1. See hundefinedi[SCO Unixware], page hundefinedi.
Tru64 Unix
Win95, Win98, NT e Win2000. See hundefinedi[Windows], page hundefinedi.
Perceba que nem todas as plataformas s˜ao apropriadas para executar o MySQL. Os seguintes
fatores determinam se uma certa plataforma ´e apropriada para uma miss˜ao cr´
itica pesada:
Estabilidade geral da biblioteca thread. Uma plataforma pode ter excelente reputa¸ao,
entretanto, se a biblioteca thread ´e inst´avel no odigo que ´e usado pelo MySQL, mesmo
se todo o resto for perfeito, o MySQL ir´a ser t˜ao est´avel quanto a biblioteca thread.
A habilidade do kernel e/ou a biblioteca thread tirar vantagem do SMP em sistemas
multi-processados. Em outras palavras, quando um proceesso cria uma thread, deve
ser poss´
ivel para aquela thread executar em uma CPU diferente que o processo original.
A habilidade do kernel e/ou a biblioteca thread executar v´arias threads que
adiquire/libera um bloqueio mutex sobre uma pequena regi˜ao cr´
itica frequentemente
sem trocas de contexto excessivos. Em outras palavras, se a implementa¸ao de
pthread_mutex_lock() requisitar a CPU muito rapidamente, isto ir´a afetar o MySQL
Chapter 2: Instala¸ao do MySQL 89
tremendamente. Se esse detalhe n˜ao estiver sendo cuidado, adicionar CPUs extras
podem deixar o MySQL mais lento.
Estabilidade e performance geral do sistema de arquivos.
Habilidade do sistema de arquivos em lidar com arquivos grandes de forma eficiente,
se suas tabelas forem grandes.
Nosso n´
ivel de experiˆencia aqui na MySQL AB com a plataforma. Se n´os conhecemos
bem uma plataforma, introduzimos otimiza¸oes/corre¸coes espec´
ificas para ela habili-
tadas na hora da compila¸ao. os tamb´em podemos fornecer conselhos sobre como
configurar seu sistema otimizadamente para o MySQL.
O volume de testes feitos internamente de configura¸oes similares.
O n´umero de usu´arios que tem executado o MySQL com sucesso naquela plataforma em
configura¸oes similares. Se esse n´umero for alto, as chances de se ter alguma surpresa
espec´
ifica da plataforma fica muito menor.
Baseado nos crit´erios acima, as melhores plataformas para a execu¸ao do MySQL at´e este
ponto s˜ao o x86 com SuSe Linux 7.1, kernel 2.4 e ReiserFS (ou qualquer distribui¸ao Linux
similar) e Sparc com Solaris 2.7 ou 2.8. FreeBSD vem em terceiro, mas realmente temos
esperan¸cas que ele ir´a se unir ao clube dos tops uma vez que a biblioteca thread est´a
melhorando. os tamb´em acreditamos que em certo ponto iremos estar aptos para incluir
todas as outras plataformas em que o MySQL compila e executa, mas n˜ao t˜ao bem e com
o mesmo n´
ivel de estabilidade e performance, na categoria superior. Isto necessitar´a de
algum esfor¸co da nossa parte em coopera¸ao com os desenvolvedores dos componentes do
Sistema Operacional/Biblioteca que o MySQL depende. Se vocˆe tiver interesse em melhorar
algum de nossos componentes, est´a em uma posi¸ao para influenciar seu desenvolvimento,
e precisa de instru¸oes mais detalhadas sobre o que o MySQL necessita para uma melhor
execu¸ao, envie um e-mail para internals@lists.mysql.com.
Por favor, perceba que a compara¸ao acima n˜ao ´e para dizer que um SO ´e melhor ou pior
que o outro em geral. os estamos falando sobre a escolha de um SO para um prop´osito
dedicado: executar o MySQL, e comparamos as plataformas levando isto em considera¸ao.
Desta forma, o resultado desta compara¸ao seria diferente se n´os inclu´
issemos mais detalhes.
E em alguns casos, a raz˜ao de um SO ser melhor que o outro pode ser simplesmente
porque colocamos mais esfor¸co nos testes e otimiza¸ao para aquela plataforma em particular.
Estamos apenas colocando nossas observoes para ajud´a-lo na decis˜ao de qual plataforma
usar o MySQL na sua configura¸ao.
2.2.3 Qual vers˜ao do MySQL deve ser usada
A primeira decis˜ao a ser feita ´e se vocˆe deve usar a ´ultima vers˜ao de desenvolvimento ou a
´ultima vers˜ao est´avel:
Normalmente, se vocˆe estiver usando o MySQL pela primeira vez ou tentando port´a-
lo para algum sistema em que n˜ao exista distribui¸ao bin´aria, recomendamos o uso
da vers˜ao est´avel (atualmente Vers˜ao 3.23.52). Repare que todos os lan¸camentos do
MySQL s˜ao conferidos com os testes comparativos de performance e um conjunto ex-
tenso de testes antes de cada lan¸camento.
Sen˜ao, caso vocˆe esteja trabalhando com um antigo sistema e quiser atualiz´a-lo, mas n˜ao
que correr o risco com uma atualiza¸ao sem corre¸oes, vocˆe deve faze-lo do mesmo ramo
90 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
que vocˆe est´a usando (onde aenas o ´ultimo n´umero da vers˜ao ´e mais novo que o seu).
os temos tentado corrigir somente erros fatais e torn´a-los menores, com altera¸oes
relativamente seguras para aquela vers˜ao.
A segunda decis˜ao a ser feita ´e se vocˆe deseja usar uma distribui¸ao fonte ou bin´aria. Na
maioria dos casos provavelmente vocˆe dever´a usar a distribui¸ao bin´aria, se alguma existir
para sua plataforma, ser´a normalmente muito mais f´acil para instalar do que a distribui¸ao
em c´odigo fonte.
Nos seguites casos vocˆe provavelmente ser´a mais bem servido com uma instala¸ao baseada
em c´odigo fonte:
Se vocˆe desejar instalar o MySQL em algum lugar expec´
ifico. (O padr˜ao das dis-
tribui¸oes bin´arias ´e estar“pronto para rodar” em qualquer lugar, mas talvez voe
deseje ainda mais flexibilidade).
Para estar apto e satisfazer diferentes requisi¸oes dos usu´arios, estaremos fornecendo
duas vers˜oes bin´arias diferentes; Uma compilada com os manipuladores de tabelas n˜ao
transacionais (um bin´ario r´apido e pequeno) e um configurado com as mais importantes
op¸oes extendidas como tabelas transacionais. Ambas vers˜oes s˜ao compiladas da mesma
distribui¸ao fonte. Todos clientes MySQL nativos pode conectar com ambas vers˜oes do
MySQL.
A distribui¸ao bin´aria extendida ´e marcada com o sufixo -max e ´e configurada com as
mesmas op¸oes de mysqld-max.mysqld-max. See hundefinedi[mysqld-max], page hun-
definedi.
Se vocˆe deseja usar o RPM MySQL-Max, primeiramente voe deve instalar o RPM MySQL
padr˜ao.
Se vocˆe deseja configurar mysqld com alguns recursos extras que N˜
AO est˜ao nas dis-
tribui¸oes bin´arias. Segue abaixo a lista das op¸oes extras mais comuns que vocˆe pode
querer usar:
--with-berkeley-db
--with-innodb
--with-raid
--with-libwrap
--with-named-z-lib (Isto ´e feito para alguns dos bin´arios)
--with-debug[=full]
A distribui¸ao bin´aria padr˜ao ´e normalmente compilada com suporte para todos con-
juntos de caracteres e deve funcionar em uma variedade de processadores para a mesma
fam´
ilia do processador.
Se vocˆe precisar de um servidor MySQL mais r´apido vocˆe pode querer recompil´a-lo com
suporte para somente o conjunto de caracteres que vocˆe precisa, usar um compilador
melhor (como pgcc) ou usar op¸oes de compiladores para usar otimiza¸oes para seu
processador.
Se vocˆe encontrar um erro e relat´a-lo para o time de desenvolvimento do MySQL voe
provavelmente receber´a um patch que ser´a necess´ario aplic´a-lo para a distribui¸ao fonte
para ter o bug corrigido.
Chapter 2: Instala¸ao do MySQL 91
Se vocˆe deseja ler (e/ou modificar) o c´odigo C e C++ que ´e o MySQL, vocˆe pode obter
uma distribui¸ao fonte. O c´odigo fonte ´e sempre o manual final. Distribui¸oes fontes
tamb´em contem mais testes e exemplos que as distribui¸oes bin´arias.
O esquema de nomes do MySQL usa n´umeros de vers˜oes que consistem de tres n´umeros e um
sufixo. Por exemplo, um nome de lan¸camento como mysql-3.21.17-beta ´e interpretado
da seguinte maneira:
O primeiro n´umero (3) descreve o formato dos arquivos. Todas releases da Vers˜ao 3
tem o mesmo formato de arquivo.
O segundo n´umero (21) ´e o n´
ivel da distribui¸ao. Normalmente existem dois para serem
escolhidos. Um ´e o ramo est´avel (atualmente 23) e o outro ´e o ramo de desenvolvimento
(atualmente 4.0). Normalmente ambos s˜ao est´aveis, mas a vers˜ao de desenvolvimento
pode acontecer coisas estranhas, faltar documenta¸ao em novos recursos, ou mesmo
ao compilar em alguns sistemas.
O terceiro n´umero (17 ´e o n´umero da vers˜ao do n´
ivel de distribui¸ao. Este ´e incremen-
tado para cada nova distribui¸ao. Normalmente voe desejar´a a ´ultima vers˜ao para o
n´
ivel de publica¸ao que tiver escolhido.
O sufixo (beta) indica o n´
ivel de estabilidade da vers˜ao. Os poss´
iveis sufixo s˜ao:
alpha indica que a vers˜ao cont´em grandes se¸oes de novos c´odigos que n˜ao foram
100% testados. Bugs conhecidos (normalmente n˜ao tem nenhum) devem estar
documentados na se¸ao News. See hundefinedi[News], page hundefinedi. Existem
tamb´em novos comandos e extens˜oes na maioria das publica¸oes alpha. Desen-
volvimento ativo que podem envolver maiores altera¸oes no c´odigo pode ocorrer
numa vers˜ao alpha, mas tudo ser´a testado antes de fazer a publica¸ao. ao podem
existir erros conhecidos em nenhuma publica¸ao do MySQL.
beta significa que todo o novo c´odigo foi testado. ao ser˜ao adicionados novos
recursos que podem causar algum tipo de corrompimento. ao deve existir bugs
conhecidos. Uma altera¸ao de vers˜ao de alpha para beta ocorre quando n˜ao existir
nenhum relato de erro fatal com uma vers˜ao alpha por pelo menos um mˆes e n˜ao
planejarmos adicionar nenhum recurso que pode deixar algum antigo comando
menos confi´avel.
gamma ´e o beta que j´a tem sido usado a algum tempo e parece funcionar bem.
Apenas pequenas corre¸oes s˜ao adicionadas. Isto ´e o que muitas empresas chamam
de release.
Se n˜ao existir um sufixo, significa que esta vers˜ao j´a est´a sendo executada h´a
algum tempo em diferentes locais sem relatos de erros al´em dos espec´
ificos de
certas plataformas. Somente corre¸oes de erros cr´
iticos s˜ao adicionados ao release.
Isto ´e o que chamamos de uma distribui¸ao est´avel.
Todas as vers˜oes do MySQL funcionam sobre nossos testes padr˜oes e comparativos para
garantir que eles s˜ao relativamente seguros para o uso. Como os testes padr˜oes s˜ao exten-
didos ao longo do tempo para conferir por todos os bugs antigos encontrados, o pacote de
testes continua melhorando.
Perceba que todas publica¸oes de vers˜oes foram testadas pelo menos com:
92 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Um pacote de testes interna
Faz parte de um sistema de produ¸ao para um cliente. Ela tem diversas tabelas
com centenas de megabytes de dados.
O pacote de comparativos da MySQL
Este executa uma s´erie de consultas comuns. ´
E tamb´em um teste para ver se
o ´ultimo conjunto de otimiza¸oes fez o c´odigo mais r´apido. See hundefinedi
[MySQL Benchmarks], page hundefinedi.
O teste crash-me
Este tenta determinar quais recursos o banco de dados suporta e quais s˜ao suas
capacidades e limita¸oes. See hundefinedi[MySQL Benchmarks], page hunde-
finedi.
Outro teste ´e que n´os usamos a vers˜ao do MySQL mais nova em nosso ambiente de produ¸ao
interna, em pelo menos uma m´aquina. os temos mais de 100 gigabytes de dados com que
trabalhar.
2.2.4 Layouts de Instala¸ao
Esta se¸ao descreve o layout padr˜ao dos diret´orios criados pela instal¸ao das distribui¸oes
bin´aria e fonte.
Uma distribui¸ao bin´aria ´e instalada descompactando-a no local de instala¸ao de sua escolha
(tipicamente ‘/usr/local/mysql’) e cria os seguintes diret´orios nesses locais:
Diret´orio Conte´udo do diret´orio
bin Programas clientes e o servidor mysqld
data Arquivos Log, bancos de dados
include Arquivos de cabcalho (headers)
lib’ Bibliotecas
scriptsmysql_install_db
share/mysql Arquivos de mensagem de erro
sql-bench Benchmarks - testes comparativos
Uma distribui¸ao baseada em c´odigo fonte ´e instalada depois de vocˆe configur´a-la e compil´a-
la. Por padr˜ao, a instala¸ao copia os arquivos em ‘/usr/local’, nos seguintes subdiret´orios:
Diret´orio Conte´udo do diret´orio
bin Programas clientes e scripts
include/mysql Arquivos de cabcalho (headers)
info Documenta¸ao no formato Info
lib/mysql’ Bibliotecas
libexec O servidor mysqld
share/mysql Arquivos com mensagens de erros
sql-bench Benchmarks e o teste crash-me
var Bancos de dados e arquivos log
Dentro de um diret´orio de instala¸ao, o layout de uma instala¸ao baseada em fontes difer-
encia de uma instala¸ao bin´aria nas seguintes formas:
O servidor mysqld ´e instalado no diret´orio ‘libexec’ no lugar de ‘bin’.
O diret´orio de dados ´e ‘var’ ao inv´es de ‘data’.
Chapter 2: Instala¸ao do MySQL 93
mysql_install_db ´e instalado no diret´orio ‘/usr/local/bin’ ao inv´es de
/usr/local/mysql/scripts’.
Os arquivos headers e diret´orios de bibliotecas est˜ao em ‘include/mysql’ e ‘lib/mysql
em vez de ‘include’ e ‘lib’.
Voe pode criar sua pr´opria instala¸ao bin´aria da compila¸c˜ao dos fontes executando o script
scripts/make_binary_distribution’.
2.2.5 Como e quando as atualiza¸oes s˜ao lan¸cadas ?
O MySQL est´a evoluindo muito rapidamente na MySQL AB e n´os queremos compartilhar
isto com outros usu´arios MySQL. Sempre que temos alguns recursos ´uteis que outros acham
necess´aio, tentamos fazer um release.
Tamb´em tentamos ajudar usu´arios que solicitam recursos que s˜ao de f´acil implementa¸ao.
Tomamos notas do que nossos usu´arios licenciados gostariam de ter,especialmente do que
nossos clientes com suporte extendido desejam e tentamos ajud´a-los.
ao existe uma real necessidade para baixar uma nova release. A se¸ao News ir´a dizer se a
nova vers˜ao tem alguma coisa que vocˆe precisa. See hundefinedi[News], page hundefinedi.
Usamos a seguinte pol´
itica quando estamos atualizando o MySQL:
Para cada pequena atualiza¸ao, o ´ultimo n´umero na vers˜ao ´e incrementado. Quando
tiver um maior n´umero de novos recursos ou menor incompatibilidade com vers˜oes
antigas, o segundo n´umero na vers˜ao ´e incrementado. Quando o formato de arquivo
altera, o primeiro n´umero ´e aumentado.
Vers˜oes est´aveis testadas aparecem na m´edia de uma a duas vezes por ano, mas se
pequenos bugs s˜ao encontrados, uma vers˜ao ser´a lan¸cada apenas com as corre¸oes dos
erros.
Releases funcionais aparecem na m´edia a cada 1-8 semanas.
Distribui¸oes bin´arias para algumas plataformas ser´a feita por n´os somente para re-
leases mais importantes. Outras pessoas podem fazer distribui¸oes bin´arias para outros
sistemas mas provavelmente com menos frequencia.
os normalmente disponibilizamos os patches logo que localizamos e corrigimos pe-
quenos bugs.
Para bugs n˜ao cr´
iticos, mas irritantes, disponibilizamos patches se eles s˜ao enviados
para n´os. De qualquer forma, iremos combinar v´arios deles em um patch maior.
Se existitr, por algum motivo, um bug fatal numa vers˜ao criaremos uma nova release
o mais cedo poss´
ivel. Gostar´
iamos que outras empresas fizessem isto tamb´em.
A vers˜ao est´avel atual ´e a 3.23; os j´a mudamos o desenvolvimento em atividade para a
vers˜ao 4.0. Bugs contiuar˜ao a ser corrigidos na vers˜ao est´avel. ao acreditamos em um
congelamento completo, pois isto abandona a corre¸oes de bugs e coisas que “devem ser
feitas.” “Alguma coisa congelada” significa que talvez possamos adicionar pequenas coisas
que “com certeza n˜ao afetar´a nada que j´a esteja funcionando.”
94 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
2.2.6 Bin´arios MySQL compilados pela MySQL AB
Como um servi¸co, n´os na MySQL AB fornecemos um conjunto de distribui¸oes bin´arias do
MySQL que s˜ao compiladas no nosso site ou em sites onde os clientes cordialmente nos d˜ao
acesso as suas m´aquinas.
Estas distribui¸oes s˜ao geradas com scripts/make_binary_distribution e s˜ao configu-
radas com os seguintes compiladores e op¸oes:
SunOS 4.1.4 2 sun4c com gcc 2.7.2.1
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" ./configure
--prefix=/usr/local/mysql --disable-shared --with-extra-
charsets=complex --enable-assembler
SunOS 5.5.1 (e superior) sun4u com egcs 1.0.3a or 2.90.27 or gcc 2.95.2 and newer
CC=gcc CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors
-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql
--with-low-memory --with-extra-charsets=complex --enable-assembler
SunOS 5.6 i86pc com gcc 2.8.1
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-low-memory --with-extra-charsets=complex
Linux 2.0.33 i386 com pgcc 2.90.29 (egcs 1.0.3a)
CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3
-mpentium -mstack-align-double -felide-constructors -fno-
exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql
--enable-assembler --with-mysqld-ldflags=-all-static --with-extra-
charsets=complex
Linux 2.2.x com x686 com gcc 2.95.2
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro
-felide-constructors -fno-exceptions -fno-rtti" ./configure
--prefix=/usr/local/mysql --enable-assembler --with-mysqld-
ldflags=-all-static --disable-shared --with-extra-charset=complex
SCO 3.2v5.0.4 i386 com gcc 2.7-95q4
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
AIX 2 4 com gcc 2.7.2.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
OSF1 V4.0 564 alpha com gcc 2.8.1
CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-low-memory --with-extra-charsets=complex
Irix 6.3 IP32 com gcc 2.8.0
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
BSDI BSD/OS 3.1 i386 com gcc 2.7.2.1
CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
Chapter 2: Instala¸ao do MySQL 95
BSDI BSD/OS 2.1 i386 com gcc 2.7.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
Qualquer que tenha mais op¸oes otimizadas para qualquer das configura¸c˜oes listadas
acima pode sempre envi´a-los para a lista de mensagens dos desenvolvedores em
internals@lists.mysql.com.
Distribui¸oes RPM que anteceda o MySQL vers˜ao 3.22 s˜ao contribui¸oes dos usu´arios. Os
RPMs gerados por n´os da MySQL AB s´o come¸caram a ser fornecidos a partir da vers˜ao
3.22 do MySQL.
Se vocˆe deseja compilar uma vers˜ao para depura¸ao do MySQL, vocˆe deve adicionar --with-
debug ou --with-debug=full para as linhas de configura¸ao acima e remover qualquer
op¸ao -fomit-frame-pointer.
2.3 Instalando uma distribui¸ao com fontes do MySQL
Antes de vocˆe continuar com as instala¸oes dos fontes, confira antes se nosso bin´ario est´a
dispon´
ivel para sua plataforma e se ela funcionar´a para voe. os colocamos muito esfor¸co
para ter certeza que nossos bin´arios s˜ao contru´
idos com as melhores op¸oes poss´
iveis.
Voe precisa das seguintes ferramentas para contruir e instalar o MySQL a partir do c´odigo
fonte:
GNU gunzip para descompactar a distribui¸ao.
Algum tar razo´avel que desempacote a distribui¸ao. Sabe-se que o GNU tar funciona.
Voe pode ter alguns problemas com o tar da Sun.
Um compilador ANSI C++ funcional. gcc >= 2.95.2, egcs >= 1.0.2 ou egcs 2.91.66,
SGI C++, e SunPro C++ ao alguns dos compiladores que sabemos que funcionam.
Alibg++ ao ´e necess´aria quando o gcc for usado. gcc 2.7.x tem um bug que
torna imposs´
ivel compilar alguns arquivos C++ perfeitamente corretos, como o
sql/sql_base.cc’. Se vocˆe possui somente o gcc 2.7.x voe deve atualiza-lo para
conseguir compilar o MySQL. gcc 2.8.1 ´e tamb´em conhecido por ter problemas em
algumas plataformas portanto ele deve ser evitado se existir um novo compilador para
a plataforma.
gcc >= 2.95.2 ´e recomendado quando compilar o MySQL Vers˜ao 3.23.x.
Um bom programa make. GNU make ´e sempre recomendado e ´e algumas vezes
necess´ario. Se vocˆe tiver problemas, recomendamos tentar o GNU make 3.75 ou mais
novo.
Se vocˆe estiver usando uma vers˜ao recente de gcc, recente o bastante para entender a op¸ao
-fno-exceptions, ´e MUITO IMPORTANTE que vocˆe a use. De outra forma, vocˆe pode
compilar um bin´ario que quebra randomicamente. os tamb´em recomendamos que vocˆe use
-felide-constructors e-fno-rtti juntas com -fno-exception. Se estiver com d´uvidas,
fa¸ca o seguinte:
CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
Na maioria dos sistemas vocˆe ir´a obter um bin´ario r´apido e est´avel com essas op¸oes.
96 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe tiver problemas, SEMPRE USE mysqlbug quando postar quest˜oes para
mysql@lists.mysql.com. Mesmo se o problema n˜ao for um bug, mysqlbug recolhe
informa¸oes do sistema que facilitar´a aos outros resolverem seu problema. Por n˜ao suar
mysqlbug, vocˆe perde a vantagem de ter seu problema resolvido! Voe ir´a encontrar
mysqlbug no diret´orio ‘scripts’ depois de desempacotar a distribui¸ao. See hundefinedi
[Bug reports], page hundefinedi.
2.3.1 Vis˜ao geral da instala¸ao r´apida
Os comandos b´asicos que vocˆe deve executar para instalar o MysQL a partir da distribui¸ao
fonte s˜ao:
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
shell> cd mysql-VERSION
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> scripts/mysql_install_db
shell> chown -R root /usr/local/mysql
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
Se vocˆe deseja ter suporte para tabelas InnoDB, vocˆe deve editar o arquivo /etc/my.cnf e
remover o caractere #antes dos parˆametros que iniciam com innodb_.... See hundefinedi
[Option files], page hundefinedi. See hundefinedi[InnoDB start], page hundefinedi.
Se vocˆe iniciar de um RPM fonte, enao fa¸ca o seguinte:
shell> rpm --rebuild MySQL-VERSION.src.rpm
Isto ir´a criar um RPM bin´ario que vocˆe pode instalar.
Voe pode adicionar novos usu´arios utilizando o script bin/mysql_setpermission se vocˆe
instalar o DBI e m´odulos Perl Msql-Mysql-modules.
Segue uma descri¸ao mais detalhada.
Para instalar uma distribui¸ao fonte, siga os passos a seguir, ent˜ao prossiga para hundefinedi
[Post-installation], page hundefinedi, para inicializa¸ao do p´os-instala¸ao e testes:
1. Escolha o diret´orio sobre o qual vocˆe deseja descompactar a distribui¸ao e v´a para ele.
2. Obtenha um arquivo de distribui¸ao de algum dos sites listados em hundefinedi[Getting
MySQL], page hundefinedi.
3. Se vocˆe esta interessado em usar tabelas Berkeley DB com MySQL, vocˆe precisar´a obter
uma vers˜ao com o patch do c´odigo fonte do Berkeley DB. Por favor leia o cap´
itulo sobre
tabelas Berkeley DB antes de continuar. See hundefinedi[BDB], page hundefinedi.
Distribui¸oes fontes do MySQL s˜ao fornecidas como arquivos tar compactados e tem
nomes como ‘mysql-VERSION.tar.gz’, onde VERSION ´e um n´umero como 3.23.52.
4. Adicione um usu´ario e grupo para o mysql executar assim:
Chapter 2: Instala¸ao do MySQL 97
shell> groupadd mysql
shell> useradd -g mysql mysql
Estes comandos adicionam o grupo mysql e o usu´ario mysql. A sintaxe para useradd e
groupadd podem mudar um pouco em diferentes vers˜oes de Unix. Elas podem tamb´em
ser chamadas adduser eaddgroup. Voe pode escolher outros nomes para o usu´ario e
grupo em vez de mysql.
5. Descompacte a distribui¸ao para o diret´orio corrente:
shell> gunzip < /path/to/mysql-VERSION.tar.gz | tar xvf -
Este comando cria um diret´orio com o nome ‘mysql-VERSION’.
6. Mude para o diret´orio da distribui¸ao descompactada:
shell> cd mysql-VERSION
Note que agora vocˆe deve configurar e construir o MySQL a partir deste diret´orio raiz
da distribui¸ao. Voe n˜ao pode constru´
i-lo em um diret´orio diferente.
7. Configure o release e compile tudo:
shell> ./configure --prefix=/usr/local/mysql
shell> make
Quando vocˆe executar configure, vocˆe pode desejar especificar algumas op¸oes. Exe-
cute ./configure --help para uma lista das op¸oes. hundefinedi[configure options],
page hundefinedi, discute algumas das op¸oes mais usadas.
Se o configure falhar, e vocˆe for enviar uma mensagem para mysql@lists.mysq.com
para pedir ajuda, por favor, inclua qualquer linhas de ‘config.log’ que vocˆe acha
que pode ajudar a resolver o problema. Tamb´em inclua as ´ultimas linhas da sa´
ida
de configure se o configure abortar. Envie o relat´orio de erros usando o script
mysqlbug. See hundefinedi[Bug reports], page hundefinedi.
Se a compila¸ao falhar, veja hundefinedi[Compilation problems], page hundefinedi,
para uma ajuda com um varios problemas comuns.
8. Instalar tudo:
shell> make install
Voe deve executar este comando como root.
9. Crie as tabelas de permiss˜oes do MySQL (necess´arias s´o se vocˆe n˜ao tiver instalado o
MySQL anteriormente):
shell> scripts/mysql_install_db
Note que as vers˜oes do MySQL anteriores `a vers˜ao 3.22.10 iniciam o servidor MySQL
quando vocˆe executa mysql_install_db. Isto n˜ao acontece mais!
10. Altere o dono dos bin´arios para root e do diret´orio dados para o usu´ario que ir´a
executar o mysqld:
shell> chown -R root /usr/local/mysql
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
O primeiro comando altera o atributo de proriedade dos arquivos para o usu´ario root,
o segundo altera o atributo de propriedade do diret´orio de dados para o usu´ario mysql,
e o terceiro altera o atributo de grupo para o grupo mysql.
98 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
11. Se vocˆe deseja instalar suporte para a interface Perl DBI/DBD, veja hundefinedi[Perl
support], page hundefinedi.
12. Se vocˆe deseja que o MySQL inicie automaticamente quando voe ligar sua m´aquina,
vocˆe pode copiar support-files/mysql.server para o local onde seu sistema tem seus
arquivos de incializa¸ao. Mais informa¸oes podem ser encontradas no pr´oprio script
support-files/mysql.server e em hundefinedi[Automatic start], page hundefinedi.
Depois de tudo ter sido instalado, vocˆe deve iniciar e testar sua distribui¸ao:
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
Se o comando falhar imediatamente com mysqld daemon ended ent˜ao vocˆe pode achar al-
guma informa¸ao no arquivo ‘diret´orio-dados-mysql/’nome_maquina’.err’. A raz˜ao
pode ser que vocˆe j´a possua outro servidor mysqld sendo executado. See hundefinedi[Mul-
tiple servers], page hundefinedi.
See hundefinedi[Post-installation], page hundefinedi.
2.3.2 Aplicando patches
Algumas vezes patches aparecem na lista de mensagens ou s˜ao colocados na ´
Area de patches
do site web do MySQL.
Para aplicar um patch da lista de mensagens, salve a mensagem em que o patch aparece em
um arquivo, mude para o diret´orio raiz da sua distribui¸ao fonte de seu MySQL e execute
estes comandos:
shell> patch -p1 < patch-file-name
shell> rm config.cache
shell> make clean
Patches do site FTP s˜ao distribu´
idos como arquivos texto ou como arquivos compactados
com gzip. Aplique um patch no formato texto como mostrado acima para patches da lista
de mensagens. Para aplicar um patch compactado, mude para o diret´orio raiz da ´arvore
fonte do MySQL e execute estes comandos:
shell> gunzip < patch-file-name.gz | patch -p1
shell> rm config.cache
shell> make clean
Depois de aplicar um patch siga as instru¸oes para uma instala¸ao normal a partir dos
fontes come¸cando com o passo ./configure. Depois de executar o passo make install,
reinicie seu servidor MySQL.
Voe pode precisar derrubar algum servidor atualmente em execu¸ao antes de executar make
install. (Use mysqladmin shutdown para fazer isto.) Alguns sistemas n˜ao lhe permitem
instalar uma nova vers˜ao do programa se ele substitui agum que estiver em execu¸ao.
2.3.3 Op¸oes t´
ipicas do configure
O script configure fornece uma grande gama de controle sobre como vocˆe configura sua
distribui¸ao MySQL. Normalmente vocˆe faz isto usando op¸oes na linha de comando do
configure. Voe tamb´em pode alterar configure usando algumas vari´aveis de ambiente.
See hundefinedi[Environment variables], page hundefinedi. Para uma lista de op¸oes su-
portadas pelo configure, execute este comando:
Chapter 2: Instala¸ao do MySQL 99
shell> ./configure --help
Algumas das op¸oes mais usadas normalmente com o configure est˜ao descritas a seguir:
Para compilar apenas as bibliotecas clientes do MySQL e programas clientes e n˜ao o
servidor, use a op¸ao --without-server:
shell> ./configure --without-server
Se vocˆe n˜ao possui um compilador C++,mysql ao ir´a compilar (ele ´e o programa
cliente que exige C++). Neste caso, vocˆe pode remover o c´odigo no configure que
testa pelo compilador C++ e executar ./configure com a op¸ao --without-server.
O passo da compia¸ao continuar´a tentaindo construir mysql, mas vocˆe pode ignorar as
advertˆencias sobre ‘mysql.cc’. (Se o make parar, tente make -k para continuar com o
resto da compila¸ao mesmo se erros ocorrerem.)
Se vocˆe n˜ao deseja que seus arquivos de logs e diret´orios de bancos de dados fiquem
localizados sobre ‘/usr/local/var’, use o comando configure; algo parecido com um
destes:
shell> ./configure --prefix=/usr/local/mysql
shell> ./configure --prefix=/usr/local \
--localstatedir=/usr/local/mysql/data
O primeiro comando altera o diret´orio instala¸ao para que tudo seja instalado sobre
/usr/local/mysql’ em vez do padr˜ao ‘/usr/local’. O segundo comando preserva o
diret´orio da instala¸ao padr˜ao, mas altera a localiza¸ao padr˜ao para diret´orios de bancos
de dados (normalmente ‘/usr/local/var’) e altera para /usr/local/mysql/data.
Se vocˆe estiver usando Unix e deseja que o arquivo socket do MySQL fique em um
diret´orio diferente do padr˜ao (normalmente no diret´orio ‘/tmp’ ou ‘/var/run’) use o
comando configure da seguinte forma:
shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
Perceba que o arquivo fornecido deve ter um caminho absoluto ! Vocˆe tamb´em pode,
mais tarde, alterar a localiza¸ao de ‘mysql.sock’ usando os arquivos de op¸oes do
MySQL. See hundefinedi[Problems with mysql.sock], page hundefinedi
Se vocˆe deseja compilar programas linkeditados estaticamente (por exemplo, para criar
uma distribui¸ao bin´aria, obter mais velocidade, ou evitar problemas com algumas
distribui¸oes Red Hat Linux), execute configure desta forma:
shell> ./configure --with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static
Se vocˆe estiver usando gcc e n˜ao tem libg++ ou libstdc++ instalados vocˆe pode dizer
ao configure para usar o gcc como seu compilador C++:
shell> CC=gcc CXX=gcc ./configure
Quando vocˆe usar como seu compilador C++, ele n˜ao ir´a ligar com o libg++ ou
libstdc++.
Segue algumas configura¸oes de vari´aveis de ambiente comuns, dependendo do compi-
lador que vocˆe estiver usando:
gcc 2.7.2.1 CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
egcs 1.0.3a CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-
exceptions -fno-rtti"
100 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
gcc 2.95.2 CFLAGS="-O3 -mpentiumpro"CXX=gcc CXXFLAGS="-O3 -
mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"
pgcc 2.90.29 ou
mais novo
CFLAGS="-O3 -mpentiumpro -mstack-align-double"CXX=gcc
CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-
constructors -fno-exceptions -fno-rtti"
Na maioria dos casos vocˆe pode obter um bin´ario MySQL razoavelmente otimizado
usando as op¸oes acima e adicionar as seguintes op¸oes para a linha de configura¸ao:
--prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
A linha completa de configura¸ao dever´a ser, em outras palavras, algo como o seguinte
para todas as vers˜oes recentes do gcc:
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
Os bin´arios que fornecemos no site Web MySQL em http://www.mysql.com ao todos
compilados com otimiza¸ao plena e deve ser perfeito para a maioria dos usu´arios. See
hundefinedi[MySQL binaries], page hundefinedi. Existem algumas coisas que vocˆe
pode alterar para criar um bin´ario ainda mais r´apido, mas isto ´e somente para usu´arios
avan¸cados. See hundefinedi[Compile and link options], page hundefinedi.
Se a constru¸ao falhar e produzir erros sobre seu compilador ou linkeditor n˜ao
estarem aptos para criarem a biblioteca compartilhada ‘libmysqlclient.so.r#
(‘r# ´e um n´umero de vers˜ao), voe pode evitar este problema fornecendo a op¸ao
--disable-share para o configure. Neste caso, configure ao construir´a uma
biblioteca libmysqlclient.so.* compartilhada.
Voe pode configurar o MySQL para n˜ao usar valores de campos DEFAULT para campos
ao-NULL (isto ´e, campos que n˜ao podem ser NULL). Com isto, senten¸cas INSERT geram
um erro a menos que vocˆe especifique explicitamente valores para todos os campos
que necessitem um valor n˜ao- NULL. Para suprimir o uso de valores default, execute o
configure desta forma:
shell> CXXFLAGS=-DDONT_USE_DEFAULT_FIELDS ./configure
Por padr˜ao, o MySQL usa o conjunto de caracteres ISO-8859-1 (Latin1). Para alterar
o conjunto padr˜ao, use a op¸ao --with-charset:
shell> ./configure --with-charset=CHARSET
CHARSET pode ser um de big5,cp1251,cp1257,czech,danish,dec8,dos,euc_kr,
gb2312,gbk,german1,hebrew,hp8,hungarian,koi8_ru,koi8_ukr,latin1,latin2,
sjis,swe7,tis620,ujis,usa7, ou win1251ukr. See hundefinedi[Character sets],
page hundefinedi.
Se vocˆe desja converter os caracteres entre o servidor e o cliente, vocˆe deve dar uma ol-
hada no comando SET OPTION CHARACTER SET. See hundefinedi[SET OPTION], page hun-
definedi.
Cuidado: Se vocˆe alterar o conjunto de caracteres depois de ter criado qualquer tabela,
vocˆe deve executar myisamchk -r -q em cada tabela. Seus ´
indices podem ser ordenados
incorretamente. (Isto pode acontecer se voe instalar o MySQL, criar algumas tabelas,
depois reconfigurar o MySQL para usar um conjunto diferente de caracteres e reinstal´a-
lo).
Com a op¸ao --with-extra-charset=LISTA vocˆe pode definir qual conjunto de car-
acteres adicionais deve ser compilado no servidor.
Chapter 2: Instala¸ao do MySQL 101
Aqui LISTA ´e uma lista de conjuntos de caracteres separados por espa¸cos, complex
para incluir todos caracteres que n˜ao podem ser carregados dinamicamente ou all
para incluir todos os conjuntos nos bin´arios.
Para configurar o MySQL com c´odigo para depura¸ao, use a op¸ao --with-debug:
shell> ./configure --with-debug
Isto inclui uma aloca¸ao segura de mem´oria que pode encontrar alguns erros e fornecer
sa´
ida sobre o que est´a acontecendo. See hundefinedi[Debugging server], page hunde-
finedi.
Se seus programas clientes usam threads, vocˆe precisar´a tamb´em compilar uma vers˜ao
thread-safe da biblioteca cliente do MySQL com as op¸oes do configure --enable-
thread-safe-client. Isto ir´a criar uma biblioteca libmysqlclient_r com o qual
vocˆe dever´a ligar suas aplica¸oes que fazem uso de threads. See hundefinedi[Threaded
clients], page hundefinedi.
Op¸oes que perten¸cam a sistemas particulares podem ser encontrados na se¸ao com de-
talhes espec´
ificos de sistemas neste manual. See hundefinedi[Operating System Specific
Notes], page hundefinedi.
2.3.4 Instalando Atrav´es da ´
Arvore Fonte de Desenvolvimento
CUIDADO: Voe deve ler esta se¸ao somente se voe estiver interessado em nos ajudar a
testar nossos novos c´odigos. Se vocˆe s´o deseja deixar o MySQL funcionando em seus sistema,
vocˆe deve usar uma distribui¸ao padr˜ao (pode ser uma distribui¸ao bin´aria ou fonte).
Para obter noss mais nova ´arvore de desenvolvimento, use estas instru¸oes:
1. Fca download do BitKeeper em http://www.bitmover.com/cgi-bin/download.cgi.
Voe precisar´a do Bitkeeper 2.0 ou posterior para acessar nosso reposit´orio.
2. Siga as instru¸oes para instal´a-lo.
3. Depois que o BitKeeper estiver instalado, use este comando se vocˆe deseja clonar o
ramo MySQL 3.23:
shell> bk clone bk://work.mysql.com:7000 mysql
Para clonar o ramo 4.0, use este comando:
shell> bk clone bk://work.mysql.com:7001 mysql-4.0
O download inicial da ´arvore fonte pode demorar um pouco, dependendo da velocidade
de sua conex˜ao; seja paciente.
4. Vocˆe precisar´a do GNU autoconf,automake,libtool em4 para executar o pr´oximo
conjunto de comandos. Caso apare¸cam alguns erros estranhos durantes este est´agio,
confira se vocˆe realmente tem a libtool instalada!
shell> cd mysql
shell> bk -r edit
shell> aclocal; autoheader; autoconf; automake;
shell> ./configure # Adicione suas op¸c~oes favoritas aqui
shell> make
Uma cole¸ao de nossos scripts de configura¸ao padr˜oes est´a localizada no subdiret´orio
BUILD/’. Se preferir, vocˆe pode usar ‘BUILD/compile-pentium-debug’. Para compilar
em uma arquitetura diferente, modifique o script removendo op¸oes que s˜ao espec´
ificas
da arquitetura Pentium.
102 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
5. Quando a constru¸ao estiver pronta, execute make install. Seja cuidadoso com isto
em uma m´aquina de produ¸ao; o comando pode sobrescrever sua vers˜ao atual insta-
lada. Se vocˆe tem outra instala¸ao do MySQL, n´os recomendamos que vocˆe execute
./configure com valores diferentes para as op¸oes prefix,tcp-port eunix-socket-
path que as usadas pelo seu servidor em produ¸ao.
6. Seja r´
igido com sua nova instala¸ao e tente fazer com que os novos recursos falhem.
Inicie executando make test. See hundefinedi[MySQL test suite], page hundefinedi.
7. Se vocˆe chegar ao est´agio make e a distribui¸ao n˜ao compilar, por favor relate-o para
bugs@lists.mysql.com. Se vocˆe instalou as ´ultimas vers˜oes das ferramentas GNU
exigidas, e elas falharam tentando processar nossos arquivos de configura¸ao, por fa-
vor informe isto tamb´em. Entretanto, se vocˆe executar aclocal e obtˆem um erro de
command not found ao o reporte.Tenha certeza que todas as ferramentas necess´arias
estejam instaladas e que sua vari´avel PATH esteja corretamente configurada para que
sua shell possa encontr´a-la.
8. Depois da opera¸ao inicial bk clone para obter a ´arvore fonte, vocˆe deve executar bk
pull periodicamente para obter as atualiza¸oes.
9. Vocˆe pode examinar o hist´orico de altera¸oes para a ´arvore com todos os diffs usando
bk sccstool. Se vocˆe ver alguns diffs estranhos ou c´odigo sobre o qual vocˆe tenha
alguma d´uvida, n˜ao hesite em enviar um e-mail para internals@lists.mysql.com.
Al´em disso, se vocˆe pensar que tem uma id´eia melhor em como fazer algo, envie um
email para o mesmo endere¸co com um patch. bk diffs ir´a produzir um patch para
vocˆe ap´os fazer as altera¸oes no c´odigo fonte. Se vocˆe n˜ao tiver tempo para codificar
sua id´eia, apenas envie uma descri¸ao.
10. BitKeeper tem um ´otimo utilit´ario de ajudar que vocˆe pode acessar via bk helptool.
2.3.5 Problemas com a compila¸ao
Todos programas MySQL compilam de forma limpa sem alertas no solaris usando gcc. Em
outros sistemas, alertas podem ocorrer devido a diferen¸cas em arquivos include dos sistemas.
Veja hundefinedi[MIT-pthreads], page hundefinedipara avisos que podem ocorrer usando
MIT-pthreads. Para outros problemas, confira a lista abaixo.
A solu¸ao para v´arios problemas envolve reconfigura¸ao. Se vocˆe precisa reconfigurar, fa¸ca
notas do seguinte:
Se configure ´e executado depois dele j´a ter sido chamado, ele pode usar informa¸ao
que foi colhida durante a chamada anterior. Esta informa¸ao ´e armazenada no ar-
quivo ‘config.cache’. Quando configure inicia, ele procura por este arquivo, lˆe seu
conte´udo, se ele existir, assumindo que aquela informa¸ao continua correta. Essa con-
jetura ´e inv´alida quando vocˆe reconfigurar.
Cada vez que vocˆe executa configure, vocˆe deve executar make de novo para re-
compilar. Entretanto, vocˆe pode desejar remover primeiro antigos arquivos objeto de
constru¸oes anteriores, porque eles foram compilados usando diferentes op¸oes de con-
figura¸ao.
Para prevenir antigas informa¸oes de configura¸oes ou arquivos objetos de serem usados,
execute estes comandos antes de re-executar configure:
Chapter 2: Instala¸ao do MySQL 103
shell> rm config.cache
shell> make clean
Uma alternativa, seria executar make distclean
A lista abaixo descreve alguns dos problemas compilando o MySQL que tem sido encontra-
dos com mais frequencia:
Se vocˆe obtˆem erros quando ‘sql_yacc.cc’ como os mostrados abaixo, vocˆe provavel-
mente tem de falta de mem´oria ou espa¸co de swap:
Internal compiler error: program cc1plus got fatal signal 11
ou
Out of virtual memory
ou
Virtual memory exhausted
O problema ´e que gcc necessita de grande quantidade de mem´oria para compilar
sql_yacc.cc’ com fun¸oes inline. Tente executando configure com a op¸ao --with-
low-memory:
shell> ./configure --with-low-memory
Esta op¸ao adiciona -fno-inline na a linha de compila¸ao se vocˆe estiver usando
gcc e-O0 se vocˆe estiver usando outro programa. Vocˆe deve tentar a op¸ao --with-
low-memory mesmo se vocˆe tiver muita mem´oria e espa¸co de swap que vocˆe ache ser
suficieente para n˜ao ocorrer erros. Este problema tem ocorrido mesmo em sistemas
com boas configura¸oes de hardware e a op¸c˜ao --with-low-memory geralmente corrige
isto.
Por padr˜ao, configure escolhe c++ como o nome do compilador e GNU c++ liga com -
lg++. Se vocˆe estiver usando gcc, este comportamento pode causar problemas durante
a compila¸ao, como o seguinte:
configure: error: installation or configuration problem:
C++ compiler cannot create executables.
Voe podem tamb´em ter problemas durante a compila¸ao relacionados `a g++,libg++
ou libstdc++.
Uma causa destes problemas ´e que vocˆe pode n˜ao ter g++ ou vocˆe pode ter g++ mas n˜ao
ter o libg++ ou o libstdc++. De uma olhada no arquivo ‘config.log’. Ele deve conter
a raz˜ao exata do porque seu compilador c++ ao funciona! Para trabalhar evitando
estes problemas, vocˆe pode usar gcc como seu compilador C++. Tente configurar a
vari´avel de ambiente CXX para "gcc -O3". Por exemplo:
shell> CXX="gcc -O3" ./configure
Isto funciona porque gcc compila c´odigo fonte C++ ao bem quanto g++ faz, mas n˜ao
ifaz a liga¸ao em libg++ ou libstdc++ por padr˜ao.
Outra forma de corrigir estes problemas, com certeza, ´e instalando g++,libg++ e
libstdc++.
Se sua compila¸ao falhar com erros, como um dos seguintes, vocˆe deve atualizar sua
vers˜ao de make para GNU make:
making all in mit-pthreads
make: Fatal error in reader: Makefile, line 18:
Badly formed macro assignment
104 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
or
make: file ‘Makefile’ line 18: Must be a separator (:
or
pthread.h: No such file or directory
O Solaris e o FreeBSD s˜ao conhecidos por terem alguns problemas com o make.
O GNU make vers˜ao 3.75 ir´a funcionar.
Se vocˆe deseja definir algumas op¸oes que devem ser usadas pelo seu compilador C ou
C++, adicione as op¸oes para as vari´aveis de ambiente CFLAGS eCXXFLAGS. Voe pode
tamb´em especificar os nomes do compilador a ser usado da mesma forma utilizando CC
eCXX. Exemplo:
shell> CC=gcc
shell> CFLAGS=-O3
shell> CXX=gcc
shell> CXXFLAGS=-O3
shell> export CC CFLAGS CXX CXXFLAGS
Olhe em hundefinedi[MySQL binaries], page hundefinedipara uma lista de defini¸ao
de op¸oes que tenham sido ´uteis em v´arios sistemas.
Se vocˆe recebeu uma mensagem de erro como esta, ´e necess´ario atualizar o compilador
gcc:
client/libmysql.c:273: parse error before ‘__attribute__’
Ogcc 2.8.1 funciona, mas recomendamos o uso do gcc 2.95.2 ou egcs 1.0.3a em seu
lugar.
Se vocˆe obtem erros como estes vistos abaixo enquanto estiver compilando o mysqld,
oconfigure ao detectou corretamente o tipo do ´ultimo argumento para accept(),
getsockname() ou getpeername():
cxx: Error: mysqld.cc, line 645: In this statement, the referenced
type of the pointer value "&length" is "unsigned long", which
is not compatible with "int".
new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
Para corrigir isto, edite o arquivo ‘config.h’ (que ´e gerado pelo configure). Procure
por estas linhas:
/* Define as the base type of the last arg to accept */
#define SOCKET_SIZE_TYPE XXX
Altere XXX para size_t ou int, dependendo de seu sistema operacional. (Perceba
que vocˆe dever´a fazer isto cada vez que vocˆe executar configure, porque configure
regenera ‘config.h’.)
O arquivo ‘sql_yacc.cc ´e gerado pelo ‘sql_yacc.yy’. Normalmente o processo de
constru¸ao n˜ao necessita criar ‘sql_yacc.cc’, porque o MySQL j´a vem com uma c´opia
pr´e-gerada. Entretanto, se vocˆe necessita recri´a-lo vocˆe pode encontrar este erro:
"sql_yacc.yy", line xxx fatal: default action causes potential...
Isto ´e um ind´
icio de que sua vers˜ao do yacc ´e deficiente. Provavelmente vocˆe precisar´a
instalar o bison (a vers˜ao GNU de yacc) e us´a-lo no lugar do yacc.
Se vocˆe necessita depurar mysqld ou um cliente MySQL, execute configure com a
op¸ao --with-debug, ent˜ao recompile e ligue seus clientes com a nova biblioteca cliente.
See hundefinedi[Debugging client], page hundefinedi.
Chapter 2: Instala¸ao do MySQL 105
2.3.6 Notas MIT-pthreads
Esta se¸ao descreve alguns dos detalhes envolvidos no uso de MIT-pthreads.
Note que no Linux vocˆe N˜
AO deve usar MIT-pthreads mas instalar LinuxThreads! See
hundefinedi[Linux], page hundefinedi.
Se seu sistema n˜ao fornece suporte nativo a thread, voe precisar´a construir o MySQL
usando o pacote MIT-pthreads. Isto inclui antigos sistemas FreeBSD, SunOS 4.X, Solaris
2.4 e anteriores entre outros. See hundefinedi[Which OS], page hundefinedi.
Na maioria dos sitemas, vocˆe pode for¸car o uso de MIT-pthreads executando o
configure com a op¸ao --with-mit-threads:
shell> ./configure --with-mit-threads
Constru¸ao em um diret´orio n˜ao fonte n˜ao ´e suportado com o uso de MIT-pthreads,
porque n´os queremos minimizar nossas altera¸oes para este c´odigo.
As verifica¸oes que determinam se MIT-pthreads ser´a usado ou n˜ao, ocorrer´a somente
durante a parte do processo de configura¸ao que trata com o c´odigo do servidor. Se vocˆe
configurou a distribui¸ao usando --without-server para construir somente o c´odigo
cliente, clientes n˜ao ir˜ao saber se o MIT-pthreads est´a sendo usado e ir´a usar conex˜oes
socket Unix por padr˜ao. Como os sockets Unix n˜ao funcionam sob MIT-pthreads, isto
significa que vocˆe precisar´a usar -h ou --host quando executar programas clientes.
Quando o MySQL ´e compilado usando MIT-pthreads, travas de sistema s˜ao desabil-
itadas por padr˜ao por raz˜oes de performance. Vocˆe pode dizer ao servidor para usar
travas de sistema com a op¸ao --use-locking.
Algumas vezes o comando pthread bind() falha ao ligar a um socket sem nenhuma
mensagem de erro (pelo menos no Solaris). O resultado ´e que todas conex˜oes ao servidor
falham. Por exemplo:
shell> mysqladmin version
mysqladmin: connect to server at ’’ failed;
error: ’Can’t connect to mysql server on localhost (146)’
A solu¸ao para isto ´e matar o servidor mysqld e reinici´a-lo. Isto s´o aconteceu conosco
quando for¸camos uma queda do servidor e fizemos uma reinicializa¸ao imediata.
Com MIT-pthreads, a chamada de sistema sleep() ao ´e interromp´
ivel com SIGINT
(break). Isto s´o ´e percebido quando vocˆe executa mysqladmin --sleep. Voe deve es-
perar pela chamada sleep() para terminar, antes da interru¸ao ser servida e o processo
parar.
Na liga¸ao, vocˆe pode receber mensagens de alerta como estes (pelo menos no Solaris);
elas podem ser ignoradas:
ld: warning: symbol ‘_iob’ has differing sizes:
(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
ld: warning: symbol ‘__iob’ has differing sizes:
(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
Alguns outros alertas tamb´em podem ser ignorados:
106 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
implicit declaration of function ‘int strtoll(...)’
ao colocamos readline para funcionar com MIT-pthreads. (Isto n˜ao ´e necess´ario,
mas pode ser interessante para alguns.)
2.4 Configura¸oes e Testes P´os-instala¸ao
Uma vez instalado o MySQL (de uma distribui¸ao bin´aria ou fonte), vocˆe deve inicializar
as tabelas de concess˜oes, iniciar o servidor e ter certeza que o servidor est´a funcionando
bem. Voe pode tamb´em desejar que o servidor inicie e pare automaticamente quando seu
sistema iniciar e desligar.
Normalmente vocˆe instala as tabelas de concess˜oes e inicia o servidor assim para instala¸oes
baseadas em uma distribui¸ao fonte:
shell> ./scripts/mysql_install_db
shell> cd diretorio_instala¸c~ao_mysql
shell> ./bin/safe_mysqld --user=mysql &
Para uma distribui¸ao bin´aria (sem ser pacotes RPM ou PKG), fa¸ca isto:
shell> cd diretorio_instala¸c~ao_mysql
shell> ./bin/mysql_install_db
shell> ./bin/safe_mysqld --user=mysql &
Isto cria o banco de dados mysql que ir´a armazenar todos privil´egios do banco de dados,
o banco de dados test que vocˆe poder´a usar para testar o MySQL e tamb´em entradas de
privil´egio para o usu´ario que usa o mysql_install_db e o usu´ario root (sem senhas). Isto
tamb´em inicia o servidor mysqld.
mysql_install_db ao ir´a sobrescrever nenhuma tabela de privil´egios antiga, ent˜ao deve
ser seguro execut´a-lo em quaisquer circunstˆancias. Se vocˆe n˜ao deseja ter o banco de dados
test vocˆe pode removˆe-lo com mysqladmin -u root drop test.
Testes s˜ao geralmente facilmente feitos de um diret´orio raiz da distribui¸ao MySQL.
Para uma distribui¸ao bin´aria, este ´e seu diret´orio de instala¸ao (normalmente algo como
/usr/local/mysql’). Para uma distrubui¸ao fonte, este ´e o diret´orio principal da sua
´arvore fonte do MySQL.
Nos comandos mostrados abaixo nesta se¸ao e nas seguintes subse¸oes, BINDIR ´e o caminho
para a localiza¸ao na qual os programas como mysqladmin esafe_mysqld est˜ao instalados.
Para uma distribui¸ao bin´aria este ´e o diret´orio ‘bin’. Para uma distribui¸ao fonte, BINDIR
´e provavelmente ‘/usr/local/bin’, a menos que vocˆe especifique um diret´orio de instala¸ao
diferente de ‘/usr/local’ quando vocˆe executa configure.EXECDIR ´e a localiza¸ao na qual
o servidor mysqld est´a instalado. Para uma distribui¸ao bin´aria, isto ´e o mesmo que BINDIR.
Para uma distribui¸ao fonte, EXECDIR ´e provavelmente ‘/usr/local/libexec’.
Testes s˜ao descritos em detalhes abaixo:
1. Se necess´ario, inicie o servidor mysqld e configure as tabelas de concess˜oes iniciais
contendo os privil´egios que determinam como os usu´arios est˜ao permitidos a conectar
ao servidor. Isto ´e feito normalmente com o script mysql_install_db:
shell> scripts/mysql_install_db
Normalmente, mysql_install_db precisa ser executado somente na primeira vez que
vocˆe instala o MySQL. Portanto, se vocˆe estiver atualizando uma instala¸ao existente,
Chapter 2: Instala¸ao do MySQL 107
vocˆe pode pular este passo. (entretanto, mysql_install_db ´e realmente seguro de usar
e n˜ao ir´a atualizar nenhuma tabela que j´a exista, ent˜ao se vocˆe n˜ao tem certeza do que
fazer, vocˆe pode sempre executar mysql_install_db.)
mysql_install_db cria seis tabelas (user,db,host,tables_priv,columns_priv e
func) no banco de dados mysql. Uma descri¸ao dos privil´egios iniciais ´e fornecido
em hundefinedi[Default privileges], page hundefinedi. De forma resumidao, estes
privil´egios permitem que o usu´ario root fa¸ca qualquer coisa no MySQL, e permitem a
qualquer um a criar ou usar bancos de dados com o nome de ’test’ ou iniciando com
’test_’ .
Se vocˆe n˜ao configurar as tabelas de concess˜oes, o seguinte erro ir´a aparecer no arquivo
log quando vocˆe n˜ao iniciar o servidor:
mysqld: Can’t find file: ’host.frm’
O erro acima pode tamb´em ocorrer com uma distribui¸ao bin´aria do MySQL se vocˆe n˜ao
iniciar o MySQL executando o ./bin/safe_mysqld! See hundefinedi[safe_mysqld],
page hundefinedi.
Voe deve precisar executar mysql_install_db como root. Entretanto, se vocˆe
preferir, pode executar o servidor MySQL como um usu´ario (n˜ao-root) sem
privil´egios, desde que o usu´ario possa ler e escrever arquivos no diret´orio de banco
de dados. Instru¸oes para executar o MySQL como um usu´ario sem privil´egios ´e
detalhado em hundefinedi[Alterando usu´arios MySQL], page hundefinedi
Se vocˆe tiver problemas com o mysql_install_db, veja hundefinedi[mysql_install_
db], page hundefinedi.
Existem algumas alternativas para executar o script mysql_install_db como ele ´e
fornecido na distribui¸ao MySQL:
Voe pode querer editar o mysql_install_db antes de execut´a-lo, para alterar os
privil´egios iniciais que s˜ao instalados nas tabelas de concess˜oes. Isto ´e ´util se vocˆe
deseja instalar o MySQL em v´arias m´aquinas com os mesmos privil´egios. Neste
caso, ´e prov´avel que voe s´o precise adicionar algumas instru¸oes INSERT extras
para as tabelas mysql.user emysql.db.
Se vocˆe deseja alterar algo na tabelas de concess˜oes depois de instal´a-las, vocˆe pode
executar mysql_install_db, ent˜ao usar mysql -u root mysql para conectar `as
tabelas de concess˜oes como o usu´ario root e usar instru¸oes SQL para modific´a-las
diretamente.
´
E poss´
ivel recriar as tabelas de permiss˜oes completamente depois delas j´a terem
sido criadas. Vocˆe pode querer fazer isto se vocˆe j´a instalou as tabelas mas deseja
recri´a-las depois das edi¸oes mysql_install_db.
Para maiores informa¸oes sobre estas alternativas, veja hundefinedi[Default privileges],
page hundefinedi.
2. Inicie o servidor MySQL assim:
shell> cd diretorio_instalacao_mysql
shell> bin/safe_mysqld &
Se vocˆe tiver problemas iniciando o servidor, veja hundefinedi[Starting server],
page hundefinedi.
108 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
3. Use mysqladmin para verificar se o servidor est´a em execu¸ao. Os seguintes coman-
dos fornecem um teste simples para conferir se o servidor est´a em funcionamento e
respondendo `as conex˜oes:
shell> BINDIR/mysqladmin version
shell> BINDIR/mysqladmin variables
A sa´
ida de mysqladmin version varia muito pouco dependendo de sua plataforma e
vers˜ao do MySQL, mas deve ser similar a esta mostrada abaixo:
shell> BINDIR/mysqladmin version
mysqladmin Ver 8.14 Distrib 3.23.32, for linux on i586
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Server version 3.23.32-debug
Protocol version 10
Connection Localhost via Unix socket
TCP port 3306
UNIX socket /tmp/mysql.sock
Uptime: 16 sec
Threads: 1 Questions: 9 Slow queries: 0 Opens: 7 Flush tables: 2 Open tables: 0 Queries per second avg: 0.000 Memory in use: 132K Max memory used: 16773K
Para ter uma id´eia do que vocˆe pode fazer com BINDIR/mysqladmin, invoque-o com a
op¸ao --help.
4. Verifique se vocˆe pode desligar o servidor:
shell> BINDIR/mysqladmin -u root shutdown
5. Verifique que vocˆe possa reiniciar o servidor. Fca isto usando safe_mysqld ou
chamado o mysqld diretamente. Por exemplo:
shell> BINDIR/safe_mysqld --log &
Se o safe_mysqld falhar, tente execut´a-lo do diret´orio de instala¸ao do MySQL (se
vocˆe j´a n˜ao estiver l´a). Se n˜ao funcionar, veja hundefinedi[Starting server], page hun-
definedi.
6. Execute alguns testes b´asicos para verificar se o servidor est´a funcionando. A sa´
ida
deve ser similar ao mostrado abaixo:
shell> BINDIR/mysqlshow
+-----------+
| Databases |
+-----------+
| mysql |
+-----------+
shell> BINDIR/mysqlshow mysql
Database: mysql
+--------------+
| Tables |
+--------------+
| columns_priv |
Chapter 2: Instala¸ao do MySQL 109
| db |
| func |
| host |
| tables_priv |
| user |
+--------------+
shell> BINDIR/mysql -e "select host,db,user from db" mysql
+------+--------+------+
| host | db | user |
+------+--------+------+
| % | test | |
| % | test_% | |
+------+--------+------+
Tamb´em existe uma suite de benchmark no diret´orio ‘sql-bench’ (sob o diret´orio de
instala¸ao do MySQL) que vocˆe pode usar para comparar como o MySQL se comporta
em diferentes plataformas. O diret´orio ‘sql-bench/Results’ cont´em os resultados de
arias execu¸oes em diferentes bancos de dados e plataformas. Para executar todos
testes, execute estes comandos:
shell> cd sql-bench
shell> run-all-tests
Se vocˆe n˜ao possui o diret´orio ‘sql-bench’, vocˆe provavelmente est´a usando uma dis-
tribui¸ao bin´aria RPM. (Distribui¸oes fontes RPMs incluem o diret´orio com os bench-
marks.) Neste caso, vocˆe deve primeiramente instalar a suite de benchmark antes
de poder us´a-lo. A partir da vers˜ao 3.22 do MySQL, come¸caram a existir arquivos
RPMs de benchmark chamados ‘mysql-bench-VERSION-i386.rpm’ que cont´em c´odigo
ie dados de benchmark.
Se vocˆe tem uma distribui¸ao fonte, vocˆe tamb´em pode executar os testes no subdi-
ret´orio ‘tests’. Por exemplo, para executar ‘auto_increment.tst’, fa¸ca isto:
shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tst
Os resultados esperados s˜ao mostrados no arquivo ‘./tests/auto_imcrement.res’.
2.4.1 Problemas Executando o mysql_install_db
O prop´osito do script mysql_install_db ´e gerar novas tabelas de privil´egios. Ele n˜ao ir´a
afeter nenhum outro dado! Ele tamb´em n˜ao far´a nada se vocˆe j´a tem a tabela de privil´egio
do MySQL instalada.
Se vocˆe deseja refazer suas tabelas de privil´egios, vocˆe deve desligar o servidor mysqld, se
ele j´a est´a executando, enao fa¸ca assim:
mv diretorio-dados-mysql/mysql diretorio-dados-mysql/mysql-old
mysql_install_db
Esta se¸ao relaciona alguns problemas que podem ser encontrados ao executar mysql_
install_db:
mysql_install_db ao instala as tabelas de permiss˜oes
Voe pode descobrir que o mysql_install_db falha ao instalar as tabelas de
permiss˜oes e termina depois de mostrar as seguintes mensagens:
110 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
starting mysqld daemon with databases from XXXXXX
mysql daemon ended
Neste caso, vocˆe deve examinar o arquivo de log com muito cuidado! O log deve
se encontrar no diret´orio ‘XXXXXX’ nomeado pela mensagem de erro, e deve
indicar porque mysqld ao inicializa. Se vocˆe n˜ao entende o que aconteceu,
inclua o log quando vocˆe postar um relato de erro usando mysqlbug! See hun-
definedi[Bug reports], page hundefinedi.
a existe um daemon mysqld sendo executado
Neste caso, provavelmente n˜ao ser´a necess´ario executar o mysql_install_db.
Voe deve executar o mysql_install_db somente uma vez, quando voe insta-
lar o MySQL da primeira vez.
Instalair um segundo daemon mysqld ao funciona quando um daemon
estiver em execu¸ao.
Isto pode acontecer quando vocˆe j´a tiver uma instala¸ao do MySQL existente,
mas deseja colocar uma nova instala¸ao em um diferente lugar (por exemplo,
para testes, ou talvez vocˆe simplesmente deseja executar duas instala¸oes ao
mesmo tempo). Geralmente o problema que ocorre quando vocˆe tenta executar
o segundo servidor ´e que ele tenta usar o mesmo socket e porta que o outro.
Neste caso vocˆe ir´a obter a mensagem de erro: Can’t start server: Bind
on TCP/IP port: Address already in use ou Can’t start server : Bind on
unix socket.... See hundefinedi[Installing many servers], page hundefinedi.
Voe n˜ao tem direito de escrita no diret´orio ‘/tmp
Se vocˆe n˜ao tem direito de escrita para criar um arquivo socket no local padr˜ao
(em ‘/tmp’) ou permiss˜ao para criar arquivos tempor´aris em ‘/tmp,’ vocˆe ir´a
obter um erro quando executar mysql_install_db ou quando iniciar ou usar
mysqld.
Voe pode especificar socket e diret´orio tempor´ario diferentes, como segue:
shell> TMPDIR=/algum_dir_tmp/
shell> MYSQL_UNIX_PORT=/algum_dir_tmp/mysqld.sock
shell> export TMPDIR MYSQL_UNIX_PORT
See hundefinedi[Problems with mysql.sock], page hundefinedi.
algum_dir_tmp’ deve ser o caminho para o mesmo diret´orio no qual voe tem
permiss˜ao de escrita. See hundefinedi[Environment variables], page hunde-
finedi.
Depois disto vocˆe deve estar apto para executar mysql_install_db e iniciar o
servidor com estes comandos:
shell> scripts/mysql_install_db
shell> BINDIR/safe_mysqld &
mysqld falha imediatamente
Se vocˆe estiver executando RedHat Vers˜ao 5.0 com uma vers˜ao de glibc an-
terior a 2.0.7-5 vocˆe deve ter certeza que vocˆe instalou todos os patches para
aglibc! Existe muita informa¸ao sobre isto nos arquivos das listas de men-
sagens do MySQL. Links para os arquivos de correio est˜ao dispon´
iveis online em
Chapter 2: Instala¸ao do MySQL 111
http://www.mysql.com/documentation/. Veja tamb´em hundefinedi[Linux],
page hundefinedi.
Voe pode tamb´em iniciar o mysqld manualmente usando a op¸ao --skip-
grant-tables e adicionar a informa¸ao de privil´egios usando o mysql:
shell> BINDIR/safe_mysqld --skip-grant-tables &
shell> BINDIR/mysql -u root mysql
Do mysql, execute manualmente os comandos SQL em mysql_install_db.
Tenha certeza de executar mysqladmin flush_privileges ou mysqladmin
reload ap´os dizer ao servidor para recarregar as tabelas de permiss˜oes.
2.4.2 Problemas inicializndo o Servidor MySQL
Se vocˆe for usar tabelas que suportem transa¸oes (BDB, InnoDB), primeiro deve-se criar
um arquivo my.cnf e configurar op¸oes de inicializa¸ao para os tipos de tabelas que vocˆe
planeja usar. See hundefinedi[Table types], page hundefinedi.
Geralmente, vocˆe inicia o servidor mysqld de uma das trˆes maneiras:
Invocando mysql.server. Este script ´e usado primariamente na inicializa¸ao e final-
iza¸ao do sistema, e ´e descrito de forma mais completa em hundefinedi[Automatic
start], page hundefinedi.
Invocando safe_mysqld, que tenta determinar as op¸oes apropriadas para mysqld e
enao execut´a-lo com estas op¸oes. See hundefinedi[safe_mysqld], page hundefinedi.
No Windows NT vocˆe deve instalar o mysqld como um servi¸co, como abaixo:
bin\mysqld-nt --install # Instala o MySQL como um servi¸co
Voe pode iniciar/parar o mysqld como abaixo:
NET START mysql
NET STOP mysql
Perceba que neste caso vocˆe n˜ao pode usar outras op¸oes para o mysqld!
Voe pode remover o servi¸co da seguinte maneira:
bin\mysqld-nt --remove # remove MySQL as a service
Invocando o mysqld diretamente.
Quando o daemon mysqld inicia, ele altera o diret´orio para o diret´orio de dados. ´
E neste
diret´orio que ele espera gravar arquivos de log e o arquivo pid (com o ID do processo) e
onde ele espera encontrar os bancos de dados.
A localiza¸ao do diret´orio de dados ´e especificada quando a distribui¸ao ´e compilada. En-
tretanto, se o mysqld espera encontrar o diret´orio de dados em lugar diferente de onde ele
realmente est´a no seu sistema, ele n˜ao funcionar´a corretamente. Se vocˆe tiver problemas
com caminhos incorretos vocˆe pode encontrar quais op¸oes o mysqld permite e quais s˜ao
as configura¸oes do caminho padr˜ao chamando o mysqld com a op¸ao --help. Vocˆe pode
sobrescrever os padr˜oes especificando os caminhos corretos como argumentos de linha de
comando ao mysqld. (Estas op¸oes tamb´em podem ser usadas com o safe_mysqld).
Normalmente vocˆe precisaria indicar ao mysqld somente o diret´orio base sob o qual o
MySQL ´e instalado. Vocˆe pode fazer isso usando a op¸ao --basedir. Voe pode tamb´em
usar --help para conferir o efeito das opc˜oes para se alterar o caminho (perceba que
--help deve ser a op¸ao final do comando mysqld. Por exemplo:
112 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shell> EXECDIR/mysqld --basedir=/usr/local --help
Uma vez que vocˆe determina as configura¸oes de caminho que vocˆe deseja, inicie o servidor
sem a op¸ao --help.
Qualquer que tenha sido o m´etodo utilizado para iniciar o servidor, se houver falha
na inicializa¸ao, confira o arquivo de log para ver se vocˆe pode entender o porquˆe.
Arquivos log est˜ao localizados no diret´orio dados (normalmente ‘/usr/local/mysql/data
para uma distribui¸ao bin´aria, /usr/local/var’ para uma distribui¸ao fonte,
\mysql\data\mysql.err’ no Windows.) Procure no diret´orio de dados por arquivos com
nomes no formato ‘nome_maquina.err’e‘nome_maquina.log’ onde nome_maquina ´e o
nome do servidor. Enao confira as ´ultimas linhas destes arquivos:
shell> tail nome_maquina.err
shell> tail nome_maquina.log
Se vocˆe encontrar algo como o seguinte no arquivo log:
000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed
000729 14:50:10 bdb: warning: ./test/t1.db: No such file or directory
000729 14:50:10 Can’t init databases
Significa que vocˆe n˜ao inicializou o mysqld com --bdb-no-recover e o Berkeley DB encon-
trou algo errado com seus arquivos log quando ele tentou recuperar seus bancos de dados.
Para poder continuar, vocˆe deve mover o antigo arquivo log Berkeley DB do diret´orio do
banco de dados para outro lugar, onde poder´a examin´a-los posteriormente. Os arquivos log
ao nomeados ‘log.0000000001’, onde o n´umero ir´a incrementar com o tempo.
Se vocˆe estiver executando o mysqld com suporte a tabelas BDB e o mysqld falhar no
in´
icio, pode ser devido a alguns problemas com o arquivo de recupera¸ao BDB. Neste caso
vocˆe pode tentar iniciar o mysqld com --bdb-no-recover. Se isto ajudar, ent˜ao vocˆe pode
remover todos os arquivos ‘log.*’ do diret´orio de dados e tentar iniciar o mysqld novamente.
Se vocˆe obter o seguinte erro, significa que algum outro programa (ou outro servidor mysqld)
a est´a usando a porta TCP/IP ou socket mysqld est´a tentando usar:
Can’t start server: Bind on TCP/IP port: Address already in use
ou
Can’t start server : Bind on unix socket...
Use ps para ter certeza que vocˆe n˜ao tem outro servidor mysqld em execu¸ao. Se vocˆe
ao consegue encontrar outro servidor, vocˆe pode tentar executar o comando telnet sua_
maquina numero_porta_tcp-ip e apertar ENTER arias vezes. Se vocˆe n˜ao obter uma
mensagem como telnet: Unable to connect to remote host: Connection refused, algo
est´a usando a mesma porta TCP/IP que o mysqld est´a tentando usar. Veja hundefinedi
[mysql install db], page hundefinediehundefinedi[Multiple servers], page hundefinedi.
Se o mysqld est´a atualmente em execu¸ao, vocˆe pode verificar as configura¸oes que ele est´a
usando executando este comando:
shell> mysqladmin variables
ou
shell> mysqladmin -h ’your-host-name’ variables
Se o safe_mysqld inicia o servidor mas vocˆe n˜ao consegue se conectar a ele, tenha certeza
que vocˆe tem uma entrada no arquivo ‘/etc/hosts’ que parece com isto:
Chapter 2: Instala¸ao do MySQL 113
127.0.0.1 localhost
Este problema s´o ocorre em sistemas que n˜ao possuem uma biblioteca thread funcional e
para o qual o MySQL deve estar configurado para usar MIT-pthreads.
Se vocˆe n˜ao consegue iniciar o mysqld vocˆe pode tentar criar um arquivo para rastreamento
de erros (trace) para encontrar o problema. See hundefinedi[Making trace files], page hun-
definedi.
Se vocˆe estiver utilizando tabelas InnoDB, procure pelas op¸oes especificas de inicializa¸ao
do InnoDB. See hundefinedi[InnoDB start], page hundefinedi.
Se vocˆe estiver usando tabelas BDB (Berkeley DB), vocˆe deve se familiarizar com as difer-
entes op¸oes especificas de inicializa¸ao do BDB. hundefinedi[BDB start], page hundefinedi.
2.4.3 Inicializando e parando o MySQL automaticamente.
Os scripts mysql.server esafe_mysqld podem ser usados para iniciar o servidor automati-
camente na inicializa¸ao do sistema. mysql.server tamb´em pode ser usado para parar o
servidor.
O script mysql.server pode ser usado para inicializar ou parar o servidor utilizando-o com
os argumentos start ou stop:
shell> mysql.server start
shell> mysql.server stop
mysql.server pode ser encontrado no diret´orio ‘share/mysql’ sob o diret´orio de instala¸ao
do MySQL ou no diret´orio ‘support-files’ da ´arvore fonte do MySQL.
Antes do mysql.server iniciar o servidor, ele vai para o diret´orio de instala¸ao do MySQL,
e enao chama o safe_mysqld. Vocˆe pode precisar editar o mysql.server se tiver uma dis-
tribui¸ao bin´aria instalada em um local n˜ao-padr˜ao. Modifique-o para chamar o diret´orio
(cd) apropriado antes de executar o safe_mysql. Se vocˆe deseja que o servidor seja ex-
ecutado com um usu´ario espec´
ifico, adicione uma linha user apropriada para o arquivo
/etc/my.cnf’, como ser´a visto posteriormente nesta se¸ao.
mysql.server stop desliga o servidor MySQL enviando um sinal para ele. Vocˆe pode
desligar o servidor manualmente executando mysqladmin shutdown.
Voe pode querer adicionar esses comandos start e stop nos lugares apropriados de seus
arquivos ‘/etc/rc.*’ quando vocˆe come¸car a usar o MySQL para aplica¸oes de produ¸ao.
Perceba que se vocˆe modifica mysql.server, e atualizar seu MySQL, sua vers˜ao modificada
ser´a sobrescrita, portanto vocˆe deve criar uma c´opia de sua vers˜ao editada.
Se o seu sistema usa ‘/etc/rc.local’ para iniciar scripts externos, vocˆe deve adicionar o
seguinte a ele:
/bin/sh -c ’cd /usr/local/mysql ; ./bin/safe_mysqld --user=mysql &’
Voe tamb´em pode adicionar op¸oes para mysql.server em um arquivo global
/etc/my.cnf’. Um t´
ipico arquivo ‘/etc/my.cnf’ pode parecer com isto:
[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql
114 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
[mysql.server]
basedir=/usr/local/mysql
O script mysql.server entende as seguintes op¸oes: datadir,basedir epid-file.
A seguinte tabela mostra quais grupos de op¸oes cada script de inicializa¸ao lˆe dos arquivos
de op¸oes:
Script Grupos de op¸oes
mysqld mysqld eserver
mysql.server mysql.server,mysqld eserver
safe_mysqld mysql.server,mysqld eserver
See hundefinedi[Option files], page hundefinedi.
2.5 Atualizando/Desatualizando o MySQL
Voe sempre pode mover os arquivos de formato e de dados do MySQL entre diferentes
vers˜oes na mesma arquitetura enquanto vocˆe tiver vers˜ao base do MySQL. A vers˜ao base
atual ´e 3. Se vocˆe alterar o conjunto de caracteres quando executar o MySQL (o que
tamb´em pode alterar a ordem de classifica¸ao), vocˆe deve executar myisamchk -r -q em
todas tabelas. De outra forma seus ´
indices podem n˜ao ser corretamente ordenados.
Se vocˆe tem receio de novas vers˜oes, vocˆe sempre pode renomear seu antigo mysqld para
algo como mysqld-’n´umero-da-vers˜ao-antiga’. Se o seu novo mysqld comportar de maneira
inesperada, vocˆe simplesmente pode desliga-lo e reiniciar com seu antigo mysqld!
Quando fizer uma atualiza¸ao, fa¸ca backup de seus bancos de dados antigos.
Se depois de uma atualiza¸ao, vocˆe tiver problemas com programas clientes recompilados
como Commands out of sync ou “core dumps” inexperados, vocˆe provavelmente usou um
arquivo de cabcalho ou de biblioteca antigo na compila¸ao de seus programas. Neste caso
vocˆe deve conferir a data de seu arquivo ‘mysql.h’ e da biblioteca ‘libmysqlclient.a
para verificar que eles s˜ao da nova distribui¸ao MySQL. Se n˜ao, por favor, recompile seus
programas!
Se vocˆe tiver problemas com a inicializa¸ao do novo servidor mysqld ou caso vocˆe n˜ao
consiga conectar sem uma senha, confira se o seu arquvo ‘my.cnf ´e o mesmo da antiga
instala¸ao! Voe pode conferir com isto: nome-programa --print-defaults. Se isto n˜ao
produzir outra sa´
ida al´em do nome do programa, vocˆe tem um arquivo my.cnf ativo que
est´a afetando o funcionamento do programa!
´
E uma boa id´eia reconstruir e reinstalar a distribui¸ao Msql-Mysql-modules sempre que
instalar uma nova vers˜ao do MySQL, particularmente se vocˆe perceber sintomas tais como
todos os scripts DBI falharem depois de atualizar o MySQL.
2.5.1 Atualizando da vers˜ao 3.22 para 3.23
A Vers˜ao 3.23 do MySQL suporta tabelas do novo tipo MyISAM e do antigo tipo ISAM. Vocˆe
ao necessita converter suas antigas tabelas para us´a-las com a vers˜ao 3.23. Por padr˜ao,
todas novas tabelas ser˜ao criadas usando o tipo MyISAM (a menos que vocˆe inicie o mysqld
com a op¸ao --default-table-type=isam). Vocˆe pode alterar uma tabela ISAM para uma
Chapter 2: Instala¸ao do MySQL 115
tabela MyISAM com ALTER TABLE nome_tabela TYPE=MyISAM ou com o script Perl mysql_
convert_table_format.
Os clientes vers˜oes 3.22 e 3.21 ir˜ao trabalhar sem quaisquer problemas com um servidor
vers˜ao 3.23.
As seguintes listas dizem o que vocˆe deve conferir quando atualizar para a vers˜ao 3.23:
Todas tabelas que usam o conjunto de caracteres tis620 devem ser corrigidos com
myisamchk -r ou REPAIR TABLE.
Se vocˆe fizer um DROP DATABASE em um banco de dados ligado simbolicamente, a liga¸ao
e o banco de dados original ser˜ao apagados. (Isto n˜ao acontece na 3.22 porque ele n˜ao
detecta a chamada de sistema readlink).
OPTIMIZE TABLE agora funciona somente para tabelas MyISAM. Para outros tipos de
tabelas, voe pode usar ALTER TABLE para otimizar a tabela. Durante o OPTIMIZE
TABLE a tabela ´e, agora, bloqueada para outras threads.
O cliente MySQL mysql ´e, agora, inicializado por padr˜ao com a op¸ao --no-named-
commands (-g). Esta op¸ao pode ser desabilitada com --enable-named-commands
(-G). Isto pode causar problemas de imcompatibilidade em alguns casos, por exemplo,
em scripts SQL que usam comandos sem ponto e v´
irgula! Comandos longos continuam
funcionando.
Se vocˆe estiver usando a ordem de classifica¸ao de caracteres alem~a, vocˆe deve reparar
todas suas tabelas com isamchk -r, porque foram feitas altera¸oes na sua ordem de
classifica¸ao!
O tipo padr˜ao de retorno de IF ir´a agora depender de ambos argumentos e n˜ao apenas
do primeiro argumento.
AUTO_INCREMENT ao ir´a funcionar com n´umeros negativos. A raz˜ao para isto ´e que
n´umeros negativos causaram problemas quando o -1 passa para 0. AUTO_INCREMENT ´e,
agora, tratado em um n´
ivel mais baixo para tabelas MyISAM e ´e muito mais r´apido
que antes. Para tabelas MyISAM n´umeros antigos tamem n˜ao s˜ao mais reusados,
mesmo se vocˆe apagar algumas linhas da tabela.
CASE,DELAYED,ELSE,END,FULLTEXT,INNER,RIGHT,THEN eWHEN agora s˜ao palavras
reservadas.
FLOAT(X) agora ´e um tipo de ponto flutuante verdadeiro e n˜ao um valor com um
n´umero fixo de decimais.
Quando estiver declarando DECIMAL(tamanho,dec o argumento tamanho n˜ao inclui
mais um lugar para o s´
imbolo do ponto decimal.
Uma string TIME agora deve estar em um dos seguintes formatos: [[[DAYS]
[H]H:]MM:]SS[.fraction] ou [[[[[H]H]H]H]MM]SS[.fraction]
LIKE agora compara strings usando as mesmas regras de compara¸ao de caracteres de
’=’. Se vocˆe precisa do antigo compartamento, vocˆe pdoe compilar o MySQL com a
op¸ao CXXFLGAS=-DLIKE_CMP_TOUPPER.
REGEXP agora ´e caso insensitivo para strings normais (n˜ao bin´arias).
Quando for necess´ario dar manuten¸ao/reparar tabelas deve ser usado CHECK TABLE ou
myisamchk para tabelas MyISAM (.MYI) e isamchk para tabelas ISAM (.ISM).
Se desejar que os arquivos mysqldump sejam compat´
iveis entre as vers˜oes 3.22 e 3.23
do MySQL, n˜ao deve ser usados as op¸oes --opt ou --full com o mysqldump.
116 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Confira todas suas chamadas `a DATE_FORMAT() para ter certeza que exista um ‘%’ antes
de cada caractere formatador. (Vers˜oes mais antigas que o MySQL 3.22 aceitaivam esta
sintaxe.)
mysql_fetch_fields_direct agora ´e uma fun¸ao (era uma macro) e ela retorna um
ponteiro para um MYSQL_FIELD no lugar de um MYSQL_FIELD.
mysql_num_fields() ao pode mais ser usada em um objeto MYSQL* (agora ´e uma
fun¸ao que obtem MYSQL_RES* como um argumento. Agora deve ser usado mysql_
field_count().
No MySQL Vers˜ao 3.22, a sa´
ida de SELECT DISTINCT ... era na maioria das vezes
ordenada. Na Vers˜ao 3.23, vocˆe deve usar GROUP BY ou ORDER BY para obter a sa´
ida
ordenada.
SUM() agora retorna NULL, em vez de 0 se n˜ao existir registros coincidentes. Isto ´e de
acordo com o ANSI SQL.
Um AND ou OR com valores NULL agora retornam NULL no lugar de 0. Isto afetar´a, em
grande parte, pesquisas que usam NOT em uma express˜ao AND/OR como NOT NULL =
NULL.LPAD() eRPAD reduzir˜ao a string resultante se ela for maior que o tamanho do
argumento.
2.5.2 Atualizando da vers˜ao 3.21 para 3.22
Nada que afetaria a compatibilidade foi alterada entre a vers˜ao 3.21 e 3.22. A ´unica difi-
culdade ´e que novas tabelas que s˜ao criadas com colunas do tipo DATE usar˜ao a nova forma
de armazenar a data. Vocˆe n˜ao pode acessar esses novos campos com uma vers˜ao antiga de
mysqld.
Depois de instalar o MySQL vers˜ao 3.22, vocˆe deve iniciar o novo servidor e depois execu-
tar o script mysql_fix_privilege_tables. Isto adicionar´a os novos privil´egios que vocˆe
precisar´a para usar o comando GRANT. Se vocˆe se esquecer disto, sera retornado o erro
Access denied quando vocˆe tentar usar ALTER TABLE,CREATE INDEX ou DROP INDEX. Se o
seu usu´ario root do MySQL necessita uma senha, vocˆe deve fornecˆela como um argumento
para o mysql_fix_privilege_tables.
A interface API C para mysql_real_connect() foi alterada. Se vocˆe tem um programa
cliente antigo que chama essa fun¸ao, vocˆe deve colocar um 0para o novo argumento db (ou
recodificar o cliente para enviar o elemento db para conex˜oes mais r´apidas). Voe tamb´em
deve chamar mysql_init() antes de chamar mysql_real_connect()! Esta altera¸ao foi
feita para permitir `a nova fun¸ao mysql_options() salvar op¸oes na estrutura do manipu-
lador do MYSQL.
A vari´avel key_buffer do mysqld mudou de nome para key_buffer_size, mas vocˆe ainda
pode usar o antigo nome nos seus arquivos de inicializa¸ao.
2.5.3 Atualizando da vers˜ao 3.20 para 3.21
Se vocˆe estiver executando uma vers˜ao mais antiga que a Vers˜ao 3.20.28 e deseja mudar
para a vers˜ao 3.21 vocˆe deve fazer o seguinte:
Inicie o servidor mysqld vers˜ao 3.21 com safe_mysqld --old-protocol para us´a-lo com
clientes de uma distribui¸ao da vers˜ao 3.20 Neste caso, a nova fun¸ao cliente mysql_errno()
Chapter 2: Instala¸ao do MySQL 117
ao ir´a retornar erro do servidor, somente CR_UNKNOWN_ERROR (mas isto funciona para erros
de clientes) e o servidor usa a forma antiga da fun¸ao password() para verifica¸ao, ao inv´es
da nova.
Se vocˆe N˜
AO estiver usando a op¸ao --old-protocol para mysqld, vocˆe precisar´a fazer as
seguir altera¸oes:
Todo o c´odigo cliente deve ser recompilado. Se vocˆe usa o ODBC, deve obter o novo
driver MyODBC 2.x.
O script scripts/add_long_password deve ser executado para converter o campo
Password na tabela mysql.user para CHAR(16).
Todas as senhas devem ser reatribuidas na tabela mysql.user (para obter 62-bits no
lugar de senhas 31-bits).
O formato das tabelas n˜ao foi alterado, enao n˜ao ´e preciso converter nenhuma tabela.
A vers˜ao do MySQL 3.20.28 e superiores podem manipular o novo formato da tabela de
usu´arios sem afetar os clientes. Se vocˆe tem uma vers˜ao do MySQL mais nova que 3.20.28,
senhas n˜ao ir˜ao mais funcionar se vocˆe converter a tabela de usuaios. Por seguran¸ca, vocˆe
primeiro deve fazer uma atualiza¸ao para a vers˜ao 3.20.28, pelo menos, e ent˜ao atualizar
para a vers˜ao 3.21.
O novo c´odigo cliente trabalha com um servidor mysqld 3.20.x, portanto se houver proble-
mas com 3.21.x vocˆe deve usar o antigo servidor 3.20.x sem a necessidade de recompilar os
clientes novamente.
Se vocˆe n˜ao est´a usando a op¸ao --old-protocol para o mysqld, antigos clientes ir˜ao emitr
a seguinte mensagem de erro:
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
A nova interface PERL DBI/DBD tamb´em suporta a antiga interface mysqlperl. A ´unica
altera¸ao que deve ser feita se vocˆe usa o mysqlperl ´e alterar os argumentos para a fun¸ao
connect(). Os novos argumentos s˜ao: host,database,user,password (os argumentos
user epassword foram alterados de lugar). See hundefinedi[Perl DBI Class], page hunde-
finedi.
As seguintes altera¸oes podem afetar consultas em antigas aplica¸oes:
HAVING deve ser especificada antes de qualquer cl´ausula ORDER BY.
Os parˆametros para LOCATE() foram trocados.
Agora existem algumas palavras reservadasi novas. As mais not´aveis s˜ao DATE TIME e
TIMESTAMP.
2.5.4 Atualizando para outra arquitetura
Se vocˆe estiver usando o MySQL Vers˜ao 3.23, vocˆe pode copiar os arquivos .frm,.MYI e
.MYD entre diferentes arquiteturas que suportem o mesmo formato de ponto flutuante. (O
MySQL cuida de cada detalhe de troca de bytes.)
Os arquivos ISAM de dados e ´
indices (‘*.ISD’ e ‘*.ISM’ respectivamente) s˜ao dependentes
da arquitetura e em alguns casos dependentees do Sistema Operacional. Se vocˆe deseja
mover suas aplica¸oes para outra m´aquina que tem uma arquitetura ou SO diferentes da
sua m´aquina atual, vocˆe n˜ao deve tentar mover um banco de dados simplesmente copiando
os arquivos para a outra m´aquina. Use o mysqldump.
118 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Por padr˜ao, o mysqldump ir´a criar um arquivo cheio de declara¸oes SQL. Vocˆe pode ent˜ao
transferir o arquivo para a outra m´aquina e alimena-la como uma entrada para o cliente
mysql.
Utilize mysqldump --help para ver quais op¸oes est˜ao dispon´
iveis. Se vocˆe est´a movendo
os dados para uma vers˜ao mais nova do MySQL, vocˆe deve usar mysqldump --opt com a
nova vers˜ao para obter uma descarga r´apida e compacta.
A mais f´acil (mas n˜ao a mais r´apida) forma para mover um banco de dados entre duas
aquinas ´e executar os seguintes comandos na m´aquina em que o banco de dados se en-
contra:
shell> mysqladmin -h ’nome da outra maquina’ create nome_bd
shell> mysqldump --opt nome_bd \
| mysql -h ’nome da outra maquina’ nome_bd
Se vocˆe deseja copiar um banco de dados de um m´aquina remota sobre uma rede lenta,
pode ser usado:
shell> mysqladmin create nome_bd
shell> mysqldump -h ’nome de outra maquina’ --opt --compress nome_bd \
| mysql nome_bd
O resultado pode tamb´em ser armazenado em um arquivo, depois transfira o arquivo para a
aquina destino e carregue o arquivo no banco de dados. Por exemplo voe pode descarregar
um banco de dados para um arquivo na m´aquina origem desta forma:
shell> mysqldump --quick nome_bd | gzip > nome_bd.contents.gz
(O arquivo criado neste exemplo est´a compactado.) Transfria o arquivo contendo o conte´udo
do banco de dados para a m´aquina destino e execute estes comandos:
shell> mysqladmin create nome_bd
shell> gunzip < nome_bd.contents.gz | mysql nome_bd
Tamb´em pode ser usado mysqldump emysqlimport para ajudar na transferˆencia do banco de
dados. Para grandes tabelas, isto ´e muito mais r´apido do que usar simplesmente mysqldump.
Nos comandos abaixo, DUMPDIR representa o caminho completo do diret´orio que vocˆe utiliza
para armazenar a sa´
ida de mysqldump.
Primeiro, crie o diret´orio para os arquivos de sa´
ida e descarregue o banco de dados:
shell> mkdir DUMPDIR
shell> mysqldump --tab=DUMPDIR nome_bd
Depois transfira os arquivo no diret´orio DUMPDIR para algum diret´orio correspondente na
aquina destino e carregue os arquivos no MySQL assim:
shell> mysqladmin create nome_bd # cria o banco de dados
shell> cat DUMPDIR/*.sql | mysql nome_bd # cria tabelas no banco de dados
shell> mysqlimport nome_bd DUMPDIR/*.txt # carrega dados nas tabelas
ao se esque¸ca de copiar o banco de dados mysql tamb´em, porque ´e nele que as tabelas
de permiss˜oes (user,db ehost) s˜ao armazenadas. Vocˆe pode ter que executar comandos
como o usu´ario root do MySQL na nova m´aquina at´e que vocˆe tenha o banco de dados
mysql no lugar.
Depois de importar o banco de dados mysql para a nova m´aquina, execute mysqladmin
flush-privileges para que o servidor recarregue as informa¸oes das tabelas de permiss˜oes.
Chapter 2: Instala¸ao do MySQL 119
2.6 Notas espec´
ificas para os Sistemas Operacionais
2.6.1 Notas Linux (Todas as vers˜oes)
As notas abaixo a respeito da glibc aplicam-se somente na situa¸ao quando o MySQL ´e
construido por vocˆe mesmo. Se voe est´a executando Linux em uma m´aquina x86, na
maioria dos casos ´e muito melhor para voe usar nosso bin´ario. os ligamos nossos bin´arios
com a melhor vers˜ao alterada da glibc, podemos escolher as melhores op¸oes do compilador,
em uma tentativa de torn´a-la funcional para um servidor muito exigido. Portanto se vocˆe
ler o texto abaixo, e est´a em d´uvida sobre o que deve fazer, tente usar o nosso bin´ario
primeiro para ver se ele preenche suas necessidades, e preocupe-se com uma constru¸ao
pr´opria apenas se vocˆe descobrir que nosso bin´ario n˜ao ´e bom o suficiente para voe. Neste
caso, ir´
iamos apreciar se fosse feito uma observao sobre isto, para que possamos fazer uma
melhor vers˜ao bin´aris da pr´oxima vez. Para um usu´ario comum, mesmo para configura¸oes
com v´arias conex˜oes concorrentes e/ou tabelas excedendo o limite de 2 GB, nosso bin´ario
´e, na maioria das vezes, a melhor escolha.
O MySQL usa LinuxThreads no Linux. Se vocˆe usa uma vers˜ao do Linux que n˜ao tenha
aglibc2, vocˆe deve instalar LinuxThreads antes de tentar compilar o MySQL. Vocˆe pode
obter o LinuxThreads em http://www.mysql.com/Downloads/Linux.
NOTA: Temos visto alguns problemas estranhos com o Linux 2.2.14 e MySQL em sistemas
SMP; Se vocˆe tem um sistema SMP, recomendamos a atualiza¸ao para o Linux 2.4! Seu
sistema ficar´a mais r´apido e mais est´avel fazendo isto!
Perceba que as vers˜oes da glibc iguais ou anteriores `a Vers˜ao 2.1.1 tem um bug fatal
no tratamento do pthread_mutex_timedwait, que ´e usado quando for feito um INSERT
DELAYED. Recomendamos n˜ao usar INSERT DELAYED antes de atualizar a glibc.
Se vocˆe planeja ter mais de 1000 conex˜oes simultˆaneas, ser´a necesario fazer algumas
altera¸oes na LinuxThreads, recompile-a e religue o MySQL ao novo ‘libpthread.a’.
Aumente PTHREAD_THREADS_MAX em ‘sysdeps/unix/sysv/linux/bits/local_lim.h
para 4096 e abaixe o STACK_SIZE no ‘linuxthreads/internals.h’ para 256KB. Os
caminhos s˜ao relativos `a raiz da glibc. Note que o MySQL n˜ao ser´a est´avel com cerca de
600-1000 conex˜oes se o valor de STACK_SIZE for o padr˜ao de 2MB.
Se vocˆe tiver um problema com o MySQL, no qual ele n˜ao consiga abrir v´arios arquivos ou
conex˜oes, pode ser que vocˆe n˜ao tenha configurado o Linux para lidar com o n´umero de
arquivos suficiente.
No Linux 2.2 e posteriores, vocˆe pode conferir o valor para a aloca¸ao dos arquivos fazendo:
cat /proc/sys/fs/file-max
cat /proc/sys/fs/dquot-max
cat /proc/sys/fs/super-max
Se vocˆe possui mais de 16M de mem´oria, deve ser adicionado o seguinte no seu script de
boot (‘/etc/rc/boot.local’ no SuSE):
echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
120 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Voe tamb´em pode executar os comandos acima da linha de comando como root, mas
neste caso, os antigos limites voltar˜ao a ser usados na pr´oxima vez que o computador for
reiniciado.
Deve tamb´em ser adicionado ao /etc/my.cnf:
[safe_mysqld]
open-files-limit=8192
Os parˆametros acima permitem o MySQL criar at´e 8192 conex˜oes +arquivos.
A constante STACK_SIZE na LinuxThreads controla o espa¸camento das pilhas threads no
espa¸co de endere¸camento. Ela necessita ser grande o bastante para que tenha espa¸co o
suficiente para a pilha de cada thread, mas pequena o bastante para manter a pilha de al-
guma thread executando dos dados globais mysqld. Infelizmente, a implementa¸ao Linux de
mmap(), como descobrimos em experiˆencias, ir´a desmapear uma regi˜ao j´a mapeada se vocˆe
solicitar o mapeamento de um endere¸co j´a em uso, zerando os dados de toda a p´agina ao
inv´es de retoernar. um erro. Portanto a seguran¸ca do mysqld ou qualquer outra aplica¸ao
baseada em threads depende do comportamento gentil do c´odigo que cria as threads. O
usu´ario deve tomar medidas para certirficar-se que o n´umero de threads em funcionamento
em qualquer hora seja suficientemente baixo para que as pilhas das threads permane¸cam
longe do monte global. Com mysqld vocˆe deve refor¸car este comportamento "gentil"con-
figurando um valor razo´avel para a vari´avel max_connections.
Se vocˆe mesmo construiu o MySQL e n˜ao deseja confus˜oes corrigindo LinuxThreads, vocˆe
deve configurar max_connections para um valor m´aximo de 500. Ele ainda deve ser menor
se vocˆe tiver uma chave grande para o buffer, grandes tabelas heap, ou outras coisas que
fazem o mysqld alocar muita mem´oria ou se vocˆe estiver executando um kernel 2.2 com o
patch de 2GB. Se vocˆe estiver usando nosso bin´ario ou RPM vers˜ao 3.23.25 ou posterior,
vocˆe pode seguramente configurar max_connections para 1500, assumindo que n˜ao h´a
uma grande chave de buffer ou tabelas heap com grande quantidade de dados. Quanto
mais vocˆe reduz STACK_SIZE em LinuxThreads mais threads vocˆe pode criar seguramente.
Recomendamos os valores entre 128K e 256K.
Se vocˆe usa v´arias conex˜oes simultˆaneas, vocˆe pode sofrer com um "recurso"do kernel
2.2 que penaliza um processo por bifurcar-se ou clonar um filho na tentativa de prevenir
um ataque de separa¸ao. Isto faz com que o MySQL n˜ao consiga fazer uma bom
escalonamento, quando o n´umero de clientes simultˆaneos cresce. Em sistemas com CPU
´unica, temos visto isto se manifestar em uma cria¸ao muito lenta das threads, tornando
a conex˜ao ao MySQL muito lenta. Em sistemas de m´ultiplas CPUs, temos observado
uma queda gradual na velocidade das consultas quando o n´umero de clientes aumenta.
No processo de tentar encontrar uma solu¸ao, recebemos um patch do kernel de um de
nossos usu´arios, que alega fazer muita diferen¸ca para seu site. O patch est´a dispon´
ivel
aqui (http://www.mysql.com/Downloads/Patches/linux-fork.patch). Atualmente
temos feito testes extensivos deste patch nos sistemas de desenvolvimento e produ¸ao.
A performance do MySQL obtem uma melhora significativa, sem causar problemas e
atualmente o recomendamos para nossos usu´arios que continuando trabalhando com
servidores muito carregados em kernels 2.2. Este detalhe foi corrigido no kernel 2.4,
portanto, se vocˆe n˜ao est´a satisfeito com a performance atual do seu sistema, melhor do
que aplicar um patch ao seu kernel 2.2, pode ser mais f´acil simplesmente atualizar para o
2.4, que lhe dar´a tamb´em uma melhora em seu sistemas SMP em adi¸ao `a corre¸ao do bug
discutido aqui.
Chapter 2: Instala¸ao do MySQL 121
Estamos testando o MySQL no kernel 2.4 em uma m´aquina com 2 processadores e desco-
brimos que o MySQL escalona muito melhor - virtualmente, ao h´a nenhuma perda de
desempenho no throughput das consultas at´e cerca de 1000 clientes, e o fator da escala do
MySQL (computado com a raz˜ao do throughput m´aximo para o thoughput de cada cliente.)
foi de 180%. Temos observado resultados similares em sistemas com 4 processadores - vir-
tualmente n˜ao h´a perda de desempenho quando o n´umero de clientes ´e incrementado at´e
1000 e o fator da escala foi de 300%. Portanto para um servidor SMP muito carregado n´os
definitivamente recomendamos o kernel 2.4. os descobrimos que ´e essencial executar o
processo mysqld com a mais alta prioridade poss´
ivel no kernel 2.4 para obter performance
axima. Isto pode ser feito adicionando o comando renice -20 $$ ao safe_mysqld. Nos
nossos testes em uma m´aquina com 4 processadores, o aumento da prioridade nos deu 60%
de aumento no throughput com 400 clientes.
Atualmente estamos tentando coletar mais informa¸oes sobre como o MySQL atua no kernel
2.4 em sistemas com 4 e 8 processadores. Se vocˆe tem acesso a um sistema deste porte e tem
feito alguns benchmarks, por favor envie um email para docs@mysql.com com os resultados
- iremos inclu´
i-los neste manual.
Existe outro detalhe que afeta muito a performance do MySQL, especialmente em sistemas
multi processados. A implementa¸ao de mutex em LinuxThreads na glibc-2.1 ´e muito ruim
para programas com v´arias threads que travam o mutex por um tempo curto. Em um
sistema SMP, ironicamente, se vocˆe liga o MySQL com LinuxThreads sem modifica¸oes,
removendo processadores da m´aquina, a performance do MySQL ´e melhorada em alguns
casos. Para corrigir este comportamento, disponibilizamos um patch para glibc 2.1.3, em
linuxthreads-2.1-patch
Com a glibc-2.2.2, o MySQL vers˜ao 3.23.36 ir´a usar o mutex adaptativo, que
´e muito melhor,mesmo que o patch na glibc-2.1.3. Avisamos, entretando, que
sobre algumas condi¸oes, o c´odigo mutex no glibc-2.2.2 overspins, que preju-
dica a performance do MySQL. A chance desta condi¸ao pode ser reduzida
mudando a prioridade do processo mysqld para a prioridade mais alta. os
tamb´em corrigimos o comportamento overspin com um patch, dispon´
ivel em
http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch.here. Ele
combina a corre¸ao do overspin, n´umero m´aximo de threads e espa¸camento das pilhas
em um ´unico patch. Voe precisar´a aplic´a-lo no diret´orio linuxthreads com patch -p0
</tmp/linuxthreads-2.2.2.patch. Acreditamos que ser´a inclu´
ido de alguma forma nos
futuros lan¸camentos da glibc-2.2. De qualquer forma, se vocˆe ligar com glibc-2.2.2,
ainda ser´a necess´ario corrigir STACK_SIZE ePTHREAD_THREADS_MAX. Temos esperan¸cas que
os padr˜oes ser˜ao corrigidos para valores mais aceit´aveis para configura¸oes pesadasa do
MySQL no futuro, enao sua constru¸ao poder´a ser reduzida a ./configure; make; make
install.
Recomendamos que vocˆe use os patches acima para construir uma vers˜ao est´atica especial
de libpthread.a e use-a somente para liga¸oes est´aticas com o MySQL. Sabemos que os
patches s˜ao seguros para o MySQL e pode melhorar significamente sua performance, mas n˜ao
podemos dizer nada sobre outras aplica¸oes. Se vocˆe ligar outras aplica¸oes coma a vers˜ao
modificada da biblioteca ou construir uma vers˜ao alterada compartilhada e instal´a-la no seu
sistema, vocˆe estar´a fazendo por sua conta e risco e tenha aten¸ao com outras aplica¸oes
que dependem de LinuxThreads.
122 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe passar por problemas estranhos durante a instala¸ao do MySQL ou com travamentos
de alguns utilit´arios comuns, ´e muito proavel que eles s˜ao relacionados a problemas de
bibliotecas ou compilador. Se for este o caso, o uso de nosso bin´ario ser´a a solu¸ao.
Um problema conhecido com a distribui¸ao bin´aria ´e que com antigos sistemas Linux que
usam libc (como o RedHat 4.x ou Slackware), vocˆe obter´a alguns problemas n˜ao fatais
com resolu¸ao de nomes. See hundefinedi[Binary notes-Linux], page hundefinedi.
Quando estiver usando LinuxThreads vocˆe ver´a um m´
inimo de trˆes processos em execu¸ao.
Estes s˜ao de fato, threads. Existir´a uma thread para o gerenciador LinuxThreads, uma
thread para lidar com conex˜oes e uma thread para tartar de alarmes e sinais.
Perceba que o kernel Linux e a biblioteca LinuxThread pode por padr˜ao ter apenas 1024
threads. Isto significa que vocˆe pode ter at´e 1021 conex˜oes ao MySQL em um sistema sem
corre¸ao. A p´agina http://www.volano.com/linuxnotes.html cont´em informa¸oes sobre
como contornar este limite.
Se vocˆe ver um processo mysqld daemon finalizado com ps, isto normalmente significa que
vocˆe encontrou um bug no MySQL ou que tenha uma tabela corrompida. See hundefinedi
[Crashing], page hundefinedi.
Para obter um descarga do core no Linux se o mysqld finalizar com um sinal SIGSEGV, vocˆe
pode iniciar o mysqld com a op¸ao --core-file. Perceba que provavelmente vocˆe tamb´em
precisar´a aumentar o core file size adicionando ulimit -c 1000000 para safe_mysqld
ou iniciar safe_mysqld com --core-file-sizes=1000000, See hundefinedi[safe_mysqld],
page hundefinedi.
Se vocˆe estiver ligando seu pr´oprio cliente MySQL e obter o erro:
ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory
Quando execut´a-los, o problema pode ser evitado com um dos seguintes m´etodos:
Ligue o cliente com a seguinte op¸ao (no lugar de -Lpath): -Wl,r/path-
libmysqlclient.so.
Copie libmysqclient.so para ‘/usr/lib’.
Adicione o caminho do diret´orio onde libmysqlclient.so est´a localizado para a
vari´avel de ambiente LD_RUN_PATH antes de executar seu cliente.
Se vocˆe estiver usando o compilador Fujitsu (fcc / FCC) vocˆe ter´a alguns problemas com-
pilando o MySQL porque os arquivos de cabcalho Linux s˜ao muito orientados ao gcc.
A seguinte linha configure deve funcionar com fcc/FCC:
CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO ’-D_EXTERN_INLINE=static __inline’" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory
2.6.1.1 Notas Linux para distribui¸oes bin´arias
O MySQL necessita pelo menos do Linux vers˜ao 2.0
A vers˜ao bin´aria ´e ligada com -static, que significa que vocˆe normalmente n˜ao precisa se
preocupar com qual vers˜ao das bibliotecas do sistema vocˆe tem. Voe n˜ao precisa insta-
lar LinuxThreads. Um programa ligado com a op¸ao -static ´e um pouco maior que um
programa ligado dinamicamente e tamb´em um pouco mais r´apido (3-5%). Um problema,
entretanto, ´e que vocˆe n˜ao pode usar fun¸oes definidas pelo usu´ario (UDF) com um pro-
grama ligado estaticamente. Se vocˆe for escrever ou usar fun¸oes UDF (isto ´e algo para
programadores C ou C++), vocˆe deve compilar o MySQL, usando liga¸oes dinamicas.
Chapter 2: Instala¸ao do MySQL 123
Se vocˆe estiver usando um sistema baseado em libc (em vez de um sistema glibc2), vocˆe,
provavelmente, ter´a alguns problemas com resolu¸ao de nomes de m´aquinas e getpwnam()
com a vers˜ao bin´aria. (Isto ´e porque o glibc infelizmente depende de algumas bibliotecas
externas para resolver nomes de m´aquinas e getpwent(), mesmo quando compilado com
-static). Neste caso, vocˆe provavelmente obter´a a seguinte mensagem de erro quando
executar mysql_install_db:
Sorry, the host ’xxxx’ could not be looked up
ou o seguinte erro quando vocˆe tentar executar mysqld com a op¸ao --user:
getpwnam: No such file or directory
Voe pode resolver este problema usando de um dos modos seguintes:
Obtenha uma distribui¸ao fonte do MySQL (uma distribui¸ao RPM ou tar.gz)ea
instale.
Execute mysql_install_db --force; Isto n˜ao executar´a o teste resolveip no mysql_
install_db. O lado ruim ´e que vocˆe n˜ao poder´a usar nomes de m´aquinas nas tabelas
de permiss˜oes; vocˆe deve usar n´umeros IP no lugar (exceto para localhost). Se vocˆe
estiver usando uma release antiga do MySQL que n˜ao suporte --force, vocˆe deve
remover o teste resolveip no mysql_install com um editor.
Inicie mysqld com su no lugar de usar --user.
As distribui¸oes bin´arias Linux-Intel e RPM do MySQL s˜ao configuradas para o m´aximo
de desempenho poss´
ivel. os sempre tentamos usar o compilador mais r´apido e est´avel
dispon´
ivel.
Suporte MySQL ao Perl exige Perl Vers˜ao 5.004 03 ou mais novo.
Em algumas vers˜oes 2.2 do kernel Linux,vocˆe pode obter o erro Resource temporarily
unavailable quando vocˆe faz v´arias novas conex˜oes para um servidor mysqld sobre
TCP/IP.
O problema ´e que o Linux tem um atraso entre o momento em que voe fecha um socket
TCP/IP at´e que ele seja realmente liberado pelo sistema. Como s´o existe espa¸co para um
n´umero finito de slots TCP/IP, vocˆe ir´a obter o erro acima se vocˆe tentar fazer muitas novas
conex˜oes TCP/IP durante um pequeno tempo, como quando vocˆe executa o benchmark do
MySQL ‘test-connect’ sobre TCP/IP.
os enviamos emails sobre este problema v´arias vezes para diferentes listas de discuss˜ao
Linux mas nunca conseguimos resolver este problema apropriadamente.
A ´unica ’corre¸c˜ao’ conhecida , para este problema ´e usar conex˜oes persistentes nos seus
clientes ou usar sockets, se vocˆe estiver executando o servidor de banco de dados e clientes
na mesma m´aquina. os experamos que o kernel Linux 2.4 corrija este problema no futuro.
2.6.1.2 Notas Linux x86
O MySQL exige a vers˜ao 5.4.12 ou mais nova da libc. Sabe-se que funciona com a libc
5.4.46. A vers˜ao 2.0.6 e posterior da glibc tamb´em deve funcionar. Existem alguns prob-
lemas com os RPMs glibc da RedHat, portanto se vocˆe tiver problemas, confira se existe
alguma atualiza¸ao! Sabemos que os RPMs glibc 2.0.7-19 e 2.0.7-29 funcionam.
Em algumas distribui¸oes Linux mais antigas, configure pode produzir um erro como este:
124 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file.
See the Installation chapter in the Reference Manual.
Fca apenas o que a mensagem de erro diz e adicione um caractere sublinhado para a macro
_P que tem somente um caractere sublinhado e enao tente novamente.
Voe pode obter alguns aviso quando estiver compilando; os mostrados abaixo podem ser
ignorados:
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function ‘void init_signals()’:
mysqld.cc:315: warning: assignment of negative value ‘-1’ to ‘long unsigned int’
mysqld.cc: In function ‘void * signal_hand(void *)’:
mysqld.cc:346: warning: assignment of negative value ‘-1’ to ‘long unsigned int’
No Debian GNU/Linux, se vocˆe deseja que o MySQL inicie automaticamente quando o
sistema iniciar, fa¸ca o seguinte:
shell> cp support-files/mysql.server /etc/init.d/mysql.server
shell> /usr/sbin/update-rc.d mysql.server defaults 99
Omysql.server pode ser encontrado no diret´orio ‘share/mysql’ sob o diret´orio de in-
stala¸ao MySQL ou no diret´orio ‘support-files’ da ´arvore fonte MySQL.
Se o mysqld sempre descarregar um core na inicializa¸ao, o problema pode ser que vocˆe
tenha um antigo ‘/lib/libc.a’. Tente renome´a-lo depois remova ‘sql/mysqld’ e fa¸ca um
novo make install e tente novamente. Este problema foi relatado em algumas instala¸oes
Slackware.
Se vocˆe obter o seguinte erro quando ligar o mysqld, significa que seu ‘libg++.a’ n˜ao est´a
instalado corretamente:
/usr/lib/libc.a(putc.o): In function ‘_IO_putc’:
putc.o(.text+0x0): multiple definition of ‘_IO_putc’
Voe pode evitar o uso de ‘libg++.a’ executando configure desta forma:
shell> CXX=gcc ./configure
2.6.1.3 Notas Linux SPARC
Em algumas implementa¸oes, readdir_r() est´a quebrada. O sintoma ´e que SHOW
DATABASES sempre retorna um conjunto vazio. Isto pode ser corrigido removendo
HAVE_READDIR_R do ‘config.h’ depois de configurar e antes de compilar.
Para alguns problemas ser´a necess´ario corrigir a sua instala¸ao Linux. O patch pode ser
encontrado em http://www.mysql.com/Downloads/patches/Linux-sparc-2.0.30.diff.
Este patch ´e para a distribui¸ao Linux ‘sparclinux-2.0.30.tar.gz’ que est´a dispon´
ivel
em vger.rutgers.edu (Uma vers˜ao de Linux que nunca foi fundido com o 2.0.30 oficial).
Voe tamb´em deve instalar LinuxThreads Vers˜ao 0.6 ou mais nova.
2.6.1.4 Notas Linux Alpha
O MySQL Vers˜ao 3.23.12 ´e a primeira vers˜ao do MySQL que ´e testada no Linux-Alpha. Se
vocˆe planeja usar o MySQL no Linux-Alpha, vocˆe deve ter certeza que possui esta vers˜ao
ou mais nova.
Chapter 2: Instala¸ao do MySQL 125
Temos testado o MySQL no Alpha com nossos pacotes de benchmarks e testes, e ele parece
funcinar muito bem. A principal coisa que ainda n˜ao tivemos tempo de testar ´e como as
coisas funcionam com muitos usu´arios simultˆaneos.
Quando n´os compilamos o bin´arios MySQL padr˜oes, os est´avamos usando SuSE 6.4, kernel
2.2.13-SMP, Compilador C Compaq (V6.2-504) e compilador C++ Compaq (V6.3-005) em
uma m´aquina Compaq DS20 com um processador Alpha EV6.
Voe pode encontrar os compiladores acima em http://www.support.compaq.com/alpha-tools).
Usando estes compiladores, em vez do gcc, obtemos 9-14 % de melhora na performance
com MySQL.
Note que a linha de configura¸ao otimiza o bin´ario para a CPU atual; isto significa que
vocˆe s´o pode utilizar nosso bin´ario se vocˆe tiver um processador Alpha EV6. os tamb´em
compilamos estaticamente para evitar problemas de bibliotecas.
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
Se vocˆe deseja usar egcs a seguinte linha de configura¸ao funcionou para n´os:
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared
Alguns problemas conhecidos quando executamos o MySQL no Linux-Alpha:
Debugar aplica¸oes baseadas em threads como o MysQL n˜ao ir´a funcionar com gdb
4.18. Voe deve fazer download e usar o gdb 5.0!
Se vocˆe tentar ligar o mysqld estaticamente quando usar o gcc, a imagem resultante ir´a
descarregar um arquivo core no in´
icio. Em outras palavras, N˜
AO use --with-mysqld-
ldflags=-all-static com gcc.
2.6.1.5 Notas Linux PowerPC
O MySQL deve funcionar no MkLinux com o mais novo pacote glibc (testado com glibc
2.0.7).
2.6.1.6 Notas Linux MIPS
Para ter o MySQL funcionando no Qube2. (Linux Mips), vocˆe precisar´a das bibliotecas
glibc mais novas (Sabemos que glibc-2.0.7.29C2 funciona). Voe tamb´em deve usar o
compilador egcs C++ (egcs-1.0.2-9,gcc 2.95.2 ou mais nova).
2.6.1.7 Notas Linux IA64
Para conseguir compilar o MySQL no Linux Ia64, usamos a seguinte linha de compila¸ao:
Usando gcc-2.96:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex
No Ia64 os bin´arios do cliente MySQL est˜ao usando bibliotecas compartilhadas. Isto
significa se vocˆe instalar nossa distribui¸ao bin´arias em algum outro lugar diferente de
/usr/local/mysql’ vocˆe precisa modificar o ‘/etc/ld.so.conf’ ou adicionar o caminho
da o diret´orio onde est´a localizado o ‘libmysqlclient.so’ na vari´avel de ambiente LD_
LIBRARY_PATH.
See hundefinedi[Link errors], page hundefinedi.
126 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
2.6.2 Notas Windows
Esta se¸ao descreve a instala¸ao e uso do MySQL no Windows. Esta informa¸ao tamb´em ´e
fornecida no arquivo ‘README’ que acompanha a distribui¸ao MySQL para Windows.
2.6.2.1 Iniciando o MySQL no Win95 / Win98
O MySQL usa TCP/IP para conectar um cliente a um servidor. (Isto permitir´a que qualquer
aquina na sua rede se conecte a seu servidor MySQL.) Por causa disto, vocˆe deve instalar
o TCP/IP na sua m´aquina antes de iniciar o MySQL. Vocˆe pode encontrar TCP/IP no seu
CD-ROM do Windows.
Perceba que se vocˆe estiver usando uma vers˜ao antiga do Win95 (por exemplo, OSR2). ´
E
prefer´
ivel que vocˆe use um pacote antigo Winsock! Para o MySQL ´e necess´ario o Winsock
2! Voe pode obter o Winsock mais novo em http://www.microsoft.com. O Win98 tem
a nova biblioteca Winsock 2, portanto o que foi dito acima n˜ao se aplica para o Win98.
Para iniciar o servidor mysqld, voe deve iniciar uma janela do Prompt do MS-DOS e
digitar:
C:\> C:\mysql\bin\mysqld
Isto ir´a iniciar o mysqld em segundo plano, sem uma janela.
Voe pode finalizar o servidor MySQL executando:
C:\> C:\mysql\bin\mysqladmin -u root shutdown
Perceba que o Win95 e o Win98 n˜ao suporta cria¸ao de named pipes. No Win95 e Win98,
vocˆe pode usar somente named pipes para se conectar a um servidor MySQL remoto,
executando em uma m´aquina Windows NT server. (´
E claro que o servidor MySQL deve
tamb´em suportar named pipes. Por exemplo, usando mysqld-opt sobre NT n˜ao ir´a permitir
conex˜oes named pipe. Voe deve usar o mysqld-nt ou mysqld-max-nt.)
Se o mysqld ao iniciar, por favor, confira o arquivo ‘\mysql\data\mysql.err’ para ver se
o servidor escreveu alguma mensagem que possa indicar a causa do problema. Vocˆe pode
tamb´em tentar iniciar o servidor com mysqld --standalone; Neste caso, vocˆe pode obter
alguma informa¸ao ´util na tela que pode ajudar a resolver o problema.
A ´ultima op¸ao ´e iniciar o mysqld com --standalone --debug. Neste caso o mysqld ir´a
escrever em um arquivo log ‘C:\mysqld.trace’ que deve conter a raz˜ao pela qual o mysqld
ao inicia. See hundefinedi[Making trace files], page hundefinedi.
2.6.2.2 Iniciando o MySQL no NT / Win2000
A se¸ao Win95/Win98 tamb´em se aplica para o MySQL no NT/Win2000 com as seguintes
diferen¸cas:
Para ter o MySQL funcionando com TCP/IP no NT, vocˆe deve instalar o service pack 3
(ou mais novo)!
Perceba que tudo a seguir que se aplique ao NT, funcionar´a tamb´em para o Win2000!
Para NT/Win2000, o nome do servidor ´e mysqld-nt. Normalmente vocˆe deve instalar o
MySQL como um servi¸co no NT/Win2000:
C:\> C:\mysql\bin\mysqld-nt --install
ou
Chapter 2: Instala¸ao do MySQL 127
C:\> C:\mysql\bin\mysqld-max-nt --install
(No Windows NT, vocˆe pode instalar qualquer dos bin´arios do servidor como um servi¸co,
mas somente os que tem nomes que terminam com -nt.exe fornecem suporte para named
pipes.)
Voe pode iniciar e parar o servi¸co MySQL com estes comandos:
C:\> NET START mysql
C:\> NET STOP mysql
Note que neste caso vocˆe n˜ao pode usar qualquer outra op¸ao para mysqld-nt!
Voe pode tamb´em executar mysqld-nt como um programa a parte no NT caso vocˆe precise
iniciar o mysqld-nt com algumas op¸oes! Se vocˆe inicia o mysqld-nt sem op¸oes no NT,
mysqld-nt tenta iniciar a ele pr´oprio como um servi¸co com as op¸oes padr˜oes do servi¸co.
Se vocˆe parou o mysqld-nt, vocˆe deve inici´a-lo com NET START mysql.
O servi¸co ´e instalado com o nome MySQL. Uma vez instalado, ele deve ser iniciado usando o
utilit´ario Services Control Manager (SCM) encontrado no Painel de Controle, ou usando o
comando NET START MySQL. Se algumas op¸oes s˜ao desejadas, elas devem ser especificadas
como “Parˆametros de inicializa¸ao” no utilit´ario SCM antes de iniciar o servi¸co MySQL.
Uma vez em execu¸ao, mysqld-nt pode ser parado usando mysqladmin, ou do utilit´ario
SCM ou usando o comando NET STOP MySQL. Se vocˆe utiliza o SCM para parar o mysqld-
nt, existe uma estranha mensagem do SCM sobre mysqld shutdown normally. Quando
vocˆe executa como um servi¸co, mysqld-nt ao tem acesso ao console e ent˜ao as mensagens
ao podem ser vistas.
No NT vocˆe pode obter as seguintes mensagens de erro do servi¸co:
Permission Denied Significa que ele n˜ao pode encontrar mysqld-nt.exe.
Cannot Register Significa que o caminho ´e incorreto.
Failed to install service. Significa que o servi¸co j´a est´a instalado ou que o Service Con-
trol Manager est´a em mau estado.
Se vocˆe tiver problemas para instalar mysqld-nt como um servi¸co, tente inici´a-lo com o
caminho completo:
C:\> C:\mysql\bin\mysqld-nt --install
Se isto n˜ao funcionar, vocˆe pode ter o mysqld-nt iniciando corretamente corrigindo o cam-
inho no registro!
Se vocˆe n˜ao deseja iniciar o mysqld-nt como um servi¸co, vocˆe pode inici´a-lo como mostrado
abaixo:
C:\> C:\mysql\bin\mysqld-nt --standalone
ou
C:\> C:\mysql\bin\mysqld --standalone --debug
Este ´ultimo exemplo fornece um arquivo para depura¸ao em ‘C:\mysqld.trace’. See hun-
definedi[Making trace files], page hundefinedi.
2.6.2.3 Executando o MySQL no Windows
O MySQL suporta TCP/IP em todas plataformas Windows e named pipes no NT. O padr˜ao
´e usar named pipes para instala¸oes locais no NT e TCP/IP para todos outros casos se o
cliente tiver TCP/IP instalado. O nome da m´aquina especifica qual protocolo ´e usado:
128 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Nome da M´aquina Protocolo
NULL (nenhum) No NT, tente o named pipes antes; se isto n˜ao funcionar, use
TCP/IP. No Win95/Win98, TCP/IP ´e usado.
. Named pipes
localhost TCP/IP para m´aquina atual
hostname TCP/IP
Voe pode for¸car um cliente MySQL a usar named pipes especificando a op¸ao --pipe ou
especificando .como o nome da m´aquina. Utilize a op¸ao --socket para especificar o nome
do pipe.
Perceba que a partir da vers˜ao 3.23.50, named pipes s´o est˜ao habilitados se o mysqld
for iniciado com a op¸ao --enable-named-pipe. Isto ´e porque alguns usu´arios tiveram
problemas desligando o servidor MySQL quando este utilizava named pipes.
Voe pode testar se o MySQL est´a funcionando ou n˜ao executando os seguintes comandos:
C:\> C:\mysql\bin\mysqlshow
C:\> C:\mysql\bin\mysqlshow -u root mysql
C:\> C:\mysql\bin\mysqladmin version status proc
C:\> C:\mysql\bin\mysql test
Se o mysqld est´a lento para responder a suas conex˜oes no Win95/Win98, provavelmente
existe um problema com seu DNS. Neste caso, inicie o mysqld com --skip-name-resolve
e use somente localhost e n´umeros IP nas tabelas de permiss˜oes do MySQL. Voe tamb´em
pode evitar o DNS quando estiver conectando em um servidor MySQL mysqld-nt execu-
tando no NT, utilizando o argumento --pipe para especificar o uso de named pipes. Isto
funcinona para a maioria de clientes MySQL.
Existem duas vers˜oes da ferramenta de linha de comando MySQL:
mysql Compilado em Windows nativo, que oferece capacidades de edi¸ao
de texto muito limitadas.
mysqlc Compilado com o compilador Cygnus GNU, que oferece edi¸ao
readline.
Se vocˆe desejar usar o mysqlc.exe, deve copiar o ‘C:\mysql\lib\cygwinb19.dll’ para o
diret´orio system do seu Windows (‘\windows\system’ ou um lugar parecido).
Os privil´egios padr˜oes no Windows d˜ao a todos usu´arios locais privil´egios totais para todos
os bancos de dados sem necessidade de especificar uma senha. Para deixar o MySQL mais
seguro, vocˆe deve configurar uma senha para todos os usu´ario e remover a linha na tabela
mysql.user que tem Host=’localhost’ eUser=’’.
Voe tamb´em deve adicionar uma senha para o usu´ario root. O exemplo seguinte inicia
removendo o usu´ario anˆonimo que pode ser usando por qualquer um para acessar o banco
de dados test, e enao configura uma senha para o usu´ario root:
C:\> C:\mysql\bin\mysql mysql
mysql> DELETE FROM user WHERE Host=’localhost’ AND User=’’;
mysql> QUIT
C:\> C:\mysql\bin\mysqladmin reload
C:\> C:\mysql\bin\mysqladmin -u root password sua_senha
Depois de configurar a senha, se vocˆe desejar desligar o servidor mysqld, vocˆe pode usar o
seguinte comando:
C:\> mysqladmin --user=root --password=isua_senha shutdown
Chapter 2: Instala¸ao do MySQL 129
Se vocˆe estiver usando a antiga vers˜ao shareware do MySQL vers˜ao 3.21 no Windows, o
comando acima ir´a falhar com um erro: parse error near ’SET OPTION password’. A
corre¸ao ´e feita atualizando a vers˜ao do MySQL, que est´a dispon´
ivel livremente.
Com as vers˜oes atuais do MySQL vocˆe pode facilmente adicionar novos usu´arios e alterar
privil´egios com os comandos GRANT eREVOKE. See hundefinedi[GRANT], page hundefinedi.
2.6.2.4 Conectando em um MySQL remoto do Windows com SSH
Aqui temos notas sobre como conectar a um servidor MySQL atrav´es de uma conex˜ao
remota e segura usando o SSH (por David Carlson dcarlson@mplcomm.com:
Instale um cliente SSH na sua m´aquina Windows. Como um usu´ario, o melhor op¸ao
paga que encontrei ´e o SecureCRT da http://www.vandyke.com/. Outra op¸ao ´e o f-
secure da http://www.f-secure.com/. Vocˆe tamb´em pode encontrar algumas vers˜oes
livres no Google em http://directory.google.com/Top/Computers/Security/Products_
and_Tools/Cryptography/SSH/Clients/Windows/.
Inicie seu cliente SSH Windows. Configure Host_Name = IP_ou_Nome_servidormysql.
Configure userid=seu_userid para logar no seu servidor (provavelmente n˜ao o mesmo
que seu usu´ario/senha do MySQL.
Configure a porta de acesso. E tamb´em fa¸ca um acesso remoto (Configure local_
port: 3306,remote_host: ip_ou_nomeservidormysql,remote_port: 3306 ) ou um
acesso local (configure port: 3306,host: localhost,remote port: 3306).
Salve tudo, sen˜ao vocˆe ter´a que refazer tudo da pr´oxima vez.
Logue ao seu servidor com a sess˜ao SSH que acabou de ser criada.
Na sua m´aquina Windows, inicie algumas aplica¸oes ODBC (como o Access).
Crie um novo arquivo no Windows e ligue ao MySQL usando o driver ODBC da mesma
forma que vocˆe normalmente faz, EXCETO pelo fato de digitar localhost para a
aquina servidora MySQL — n˜ao nomeservidormysql.
Voe agora deve ter uma conex˜ao ODBC ao MySQL, criptografada com SSH.
2.6.2.5 Dividindo dados entre diferentes discos no Win32
A partir do MySQL vers˜ao 3.23.16, o mysqld-max e servidores mysql-max-nt na distribui¸ao
MySQL s˜ao compilados com a op¸ao -DUSE_SYMDIR. Isto permite que vocˆe coloque um
banco de dados em discos diferentes adicionando um link simolico para ele (em forma
similar aos links simolicos no Unix).
No Windows, vocˆe cria um link simolico para um banco de dados criando um arquivo
que contem o caminho para o diret´orio de destino e salvando-o no diret´orio ‘mysql_data
com o arquivo ‘database.sym’. Note que o link simolico s´o ser´a usada se o diret´orio
mysql_data_dir\database’ n˜ao existir.
Por exemplo, se o diret´orio de dados do MySQL ´e ‘C:\mysql\data’ e vocˆe precisa
ter o banco de dados foo localizado em ‘D:\data\foo’, vocˆe deve criar o arquivo
C:\mysql\data\foo.sym’ que contˆem o texto D:\data\foo\. Depois disto, todas tabelas
criadas no banco de dados foo ser˜ao criadas no ‘D:\data\foo’.
Note que devido a penalidade que vocˆe tem na velocidade quando abre todas as tabelas,
os n˜ao habilitamos esta op¸ao por padr˜ao, mesmo se vocˆe compilar o MySQL com suporte
130 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
a isto. Para habilitar links simolicos vocˆe deve colocar no seu arquivo my.cnf ou my.ini
a seguinte entrada:
[mysqld]
use-symbolic-links
No MySQL 4.0 n´os habilitaremos links simolicos por padr˜ao. Ent˜ao vocˆe deve usar a op¸ao
skip-symlink se vocˆe desejar desabilit´a-las.
2.6.2.6 Compilando clientes MySQL no Windows
Em seus arquivos fontes, vocˆe deve incluir ‘windows.h’ antes de incluir ‘mysql.h’:
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
#include <mysql.h>
Voe tamb´em pode ligar seu c´odigo coma biblioteca dinˆamica ‘libmysq.lib’, que ´e apenas
um wrapper para carregar em ‘libmysql.dll’ sobre demanda, ou ligar com a biblioteca
est´atica ‘mysqlclient.lib’.
Perceba que como as bibliotecas mysqlclient s˜ao compiladas como bibliotecas threaded, vocˆe
tamb´em deve compilar seu c´odigo para ser multi-threaded!
2.6.2.7 MySQL-windows comparado com o unix MySQL
O MySQL-Windows tem provado ser muito est´avel. Esta vers˜ao do MySQL tem os mesmos
recursos que sua vers˜ao correspondente Unix com as seguintes exce¸oes:
Win95 e threads
O Win95 perde aproximadamente 200 bytes de mem´oria principal para cada
thread criada. Cada conex˜ao no MySQL cria uma nova thread, portanto vocˆe
ao deve executar o mysqld por um longo tempo no Win95 se seu servidor lida
com v´arias conex˜oes! WinNT e Win98 n˜ao sofrem deste bug.
Leituras simultˆaneas
O MySQL depende das chamadas pread() epwrite() para estar apto a
misturar INSERT eSELECT. Atualmente n´os usamos mutexes para emular
pread()/pwrite(). os iremos, a longo prazo, trocar o n´
ivel da interface
de arquivos com uma interface virtual para que n´os possamos usar a
interface readfile()/writefile() no NT para obter mais velocidade. A
implementa¸ao atual limita o n´umero de arquivos abertos que o MySQL
pode usar para 1024, o que significa que vocˆe n˜ao conseguir´a executar tantas
threads simultˆaneas no NT como no Unix.
Leitura de blocos
O MySQL usa uma leitura de blocos para cada conex˜ao. Isto significa que:
Uma conex˜ao n˜ao ir´a ser disconectada automaticamente depois de 8 horas,
como acontece com a vers˜ao Unix do MySQL.
Se uma conex˜ao trava, ´e imposs´
ivel a finaliza-la sem matar o MySQL.
mysqladmin kill ao ir´a funcionar em uma conex˜ao adormecida.
Chapter 2: Instala¸ao do MySQL 131
mysqladmin shutdown ao pode abortar enquanto existirem conex˜oes
adormecidas.
Planejamos corrigir este problema quando nossos desenvolvedores Windows
tiverem conseguido um boa solu¸ao.
Fun¸oes UDF
At´e o momento, o MySQL-Windows n˜ao suporta fun¸oes definidas pelo usu´ario.
DROP DATABASE
Voe n˜ao pode remover um banco de dados que est´a em uso por alguma thread.
Matando o MySQL do gerenciador de tarefas
Voe n˜ao pode matar o MySQL do gerenciador de tarefas ou com o utilit´ario
shutdown no Win95. Vocˆe deve deslig´a-lo com mysqladmin shutdown.
Nomes case-insensitivo
Nomes de arquivos s˜ao caso-insensitivo no Windows, portanto, nomes de ban-
cos de dados e tabelas tamb´em s˜ao caso insensitivo no MySQL para Windows.
A ´unica restri¸ao ´e que os nomes de bancos de dados e tabelas devem usar o
mesmo caso em uma senten¸ca fornecida. See hundefinedi[Name case sensitiv-
ity], page hundefinedi.
O caracter de diret´orio ‘\
Componentes de nomes de caminho no Win95 s˜ao separados pelo caracter ‘\’ o
qual tamb´em ´e o caractere de escape no MySQL. Se vocˆe estiver usando LOAD
DATA INFILE ou SELECT ... INTO OUTFILE, vocˆe deve dobrar o caractere ‘\’:
mysql> LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr;
mysql> SELECT * INTO OUTFILE ’C:\\tmp\\skr.txt’ FROM skr;
Uma alternativa ´e usar o estilo de nome de arquivos do Unix com caracteres
/’:
mysql> LOAD DATA INFILE "C:/tmp/skr.txt" INTO TABLE skr;
mysql> SELECT * INTO OUTFILE ’C:/tmp/skr.txt’ FROM skr;
erro: Can’t open named pipe
Se vocˆe utiliza uma vers˜ao 3.22 do MySQL no NT com o os clientes MySQL
mais novos, ser´a apresentado o seguinte erro:
error 2017: can’t open named pipe to host: . pipe...
Isto ocorre porque a vers˜ao do MySQL usa named pipes no NT por padr˜ao.
Voe pode evitar este erro usando a op¸ao --host=localhost para os novos
clientes MySQL ou criar um arquivo de op¸oes ‘c:\my.cnf’ que contenha a
seguinte informa¸ao:
[client]
host = localhost
A partir da vers˜ao 3.23.50, named pipes s˜ao habilitados somente se o mysqld ´e
iniciado com a op¸ao --enable-name-pipe.
Erro Access denied for user
Se vocˆe obtem o erro Access denied for user: ’some-user@unknown’ to
database ’mysql’ quando acessar um servidor MySQL na mesma aquina,
signifca que o MySQL n˜ao pode resolver seu nome de m´aquina corretamente.
132 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Para corrigir isto, vocˆe deve criar um arquivo ‘\windows\hosts’ com a seguinte
informa¸ao:
127.0.0.1 localhost
ALTER TABLE
Enquanto vocˆe estiver executando uma cl´ausula ALTER TABLE, a tabela ser´a
bloqueada para o uso por outras threads. Isto ´e relacionado com o fato de
que no Windows, vocˆe n˜ao pode apagar um arquivo que est´a sendo usado por
outras threads. (No futuro, iremos encontrar alguma forma de contornar este
problema.)
DROP TABLE em uma tabela que est´a em uso por uma tabela MERGE ao ir´a funcionar.
O manipulador MERGE faz seu mapeamento de tabelas escondido do MySQL.
Como o Windows n˜ao permite apagar arquivos que est˜ao abertos, vocˆe deve
primeiramente descarregar todas tabelas MERGE (com FLUSH TABLES) ou apagar
a tabela MERGE antes de apagar a tabela. Iremos corrigir isto quando intro-
duzirmos as VIEWs.
Aqui est˜ao alguns assuntos em aberto para qualquer um que queira nos ajudar com a vers˜ao
Windows:
Criar um servidor MYSQL.DLL mono-usu´ario. Isto deve incluir tudo de um servidor
MySQL padr˜ao, exceto cria¸c˜ao de threads. Isto deixar´a o MySQL muito mais f´acil
para ser usado em aplica¸oes que n˜ao necessitam de um verdadeiro cliente/servidor e
ao necessitam acessar o servidor de outras m´aquinas.
Adicionar alguns ´
icones agrad´aveis para o start e shutdown na instala¸ao do MySQL.
Criar uma ferramenta para gerenciar entradas de registro para as op¸oes de inicializa¸ao
do MySQL. A leitura de entradas no registro j´a est´a codificada em ‘mysqld.cc’, mas
ela deve ser refeita para ser mais orientada a parˆametros. A ferramenta tamb´em deve
estar apta para atualizar o arquivo de op¸oes ‘C:\my.cnf’ se o usu´ario preferir usa-lo
no lugar do registro.
Quando registrar o mysqld como um servi¸co com --install (no NT) seria ´otimo se
vocˆe tamb´em pudesse adicionar op¸oes padr˜oes na linha de comando. Para o momento,
a solu¸ao ´e listar os parˆametros no arquivo ‘C:\my.cnf’.
Seria muito interessante conseguir matar o mysqld do gerenciador de tarefas. Para o
momento, deve ser usado o mysqladmin shutdown.
Portar o readline para Windows para uso na ferramenta de linha de comando mysql.
Vers˜oes GUI dos clientes MySQL padr˜oes (mysql,mysqlshow,mysqladmin e
mysqldump) seria ´otimo.
Seria muito bom se as fun¸oes de leitura e escrita no socket em ‘net.c’ fosse inter-
romp´
iveis. Isto tornaria poss´
ivel matar threads abertas com mysqladmin kill no
Windows.
mysqld sempre inicia na localidade "C"e n˜ao na padr˜ao. Gostariamos de ter o mysqld
usando a localiza¸ao atual para a ordem de classifica¸ao.
Implementar fun¸oes UDF com .DLLs.
Adicionar macros para usar os m´etodos mais r´apidos de incremento/decremento de
threads seguras fornecidos pelo Windows.
Chapter 2: Instala¸ao do MySQL 133
Outros detalhes espec´
ificos do Windows s˜ao descritos no arquivo ‘README’ que acompanha
a distribui¸ao MySQL-Windows.
2.6.3 Notas Solaris
No Solaris, vocˆe deve ter problemas mesmo antes de descompactar a distribui¸ao MySQL!
Otar do Solaris n˜ao pode tratar grandes nomes de arquivos, portanto voe pode ver um
erro deste tipo quando descompactar o MySQL:
x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks
tar: directory checksum error
Neste caso, vocˆe deve usar o GNU tar (gtar) para desempacotar a distribui¸ao. Vocˆe pode
encontrar uma c´opia pr´e-compilada para Solaris em http://www.mysql.com/Downloads/.
As threads nativas da Sun funcionam somente no Solaris 2.5 e superior. Para a vers˜ao 2.4
e anteriores, o MySQL ir´a automaticamente usar MIT-pthreads. See hundefinedi[MIT-
pthreads], page hundefinedi.
Se vocˆe obter o seguinte erro de configure:
checking for restartable system calls... configure: error can not run test
programs while cross compiling
Isto significa que alguma coisa est´a errada com a instala¸ao de seu compilador! Neste caso
vocˆe deve atualizar seu compilador para uma vers˜ao mais nova. Vocˆe tamb´em pode resolver
este problema inserindo a seguinte linha no arquivo ‘config.cache’:
ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls=’no’}
Se vocˆe est´a usando Solaris em um SPARC, o compilador recomendado ´e o gcc 2.95.2. Vocˆe
pode encontr´a-lo em http://gcc.gnu.org/. Perceba que egcs 1.1.1 e gcc 2.8.1 n˜ao s˜ao
est´aveis no SPARC!
A linha do configure recomendado quando usando gcc 2.95.2 ´e:
CC=gcc CFLAGS="-O3" \
CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory --enable-assembler
Se vocˆe possui um ultra sparc, vocˆe pode obter 4% a mais de performance adicionando
"-mcpu=v8 -Wa,-xarch=v8plusa"para a CFLAGS e CXXFLAGS.
Se vocˆe possui o compilador Sun Workshop (Fortre) 5.3 (ou mais novo), vocˆe pode executar
configure da seguinte forma:
CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt" \
CXX=CC CXXFLAGS="-noex -xO4 -mt" \
./configure --prefix=/usr/local/mysql --enable-assembler
Nos benchmarks do MySQL, n´os obtemos um aumento de 6% em um Ultrasparc quando
usado o Sun Workshop 5.3 comparado ao uso do gcc com as op¸oes -mcpu.
Se vocˆe tiver um problema com fdatasync ou sched_yield, vocˆe pode corrigir isto adicio-
nando LIBS=-lrt para a linha de configura¸ao
O seguinte paragr´afo ´e relevante somente para compiladores mais antigos que o WorkShop
5.3:
Voe tamb´em pode ter que editar o script configure para alterar esta linha:
134 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
#if !defined(__STDC__) || __STDC__ != 1
para isto:
#if !defined(__STDC__)
Se vocˆe ligar __STDC__ com a op¸ao -Xc, o compilador Sun n˜ao pode compilar com o arquivo
de cabcalho ‘pthread.h’ do Solaris. Isto ´e um bug da Sun (compilador corrompido ou
arquivo include corrompido).
Se o mysqld emitir a mensagem de erro mostrada abaixo quando vocˆe execut´a-lo, vocˆe deve
tentar compilar o MySQL com o compilador Sun sem habilitar a op¸ao multi-thread (-mt):
libc internal error: _rmutex_unlock: rmutex not held
Adicione -mt aCFLAGS eCXXFLAGS e tente novamente.
Se vocˆe obter o seguinte erro quando estiver compilando o MySQL com gcc, significa que
seu gcc ao est´a configurado para sua vers˜ao de Solaris:
shell> gcc -O3 -g -O2 -DDBUG_OFF -o thr_alarm ...
./thr_alarm.c: In function ‘signal_hand’:
./thr_alarm.c:556: too many arguments to function ‘sigwait’
A coisa apropriada para fazer neste caso ´e obter a vers˜ao mais nova do gcc e compil´a-lo
com seu compilador gcc atual! Ao menos para o Solaris 2.5, a maioria das vers˜oes bin´arias
de gcc tem arquivos in´uteis e antigos que ir˜ao quebrar todos programas que usam threads
(e possivelmente outros programas)!
O Solaris n˜ao fornece vers˜oes est´aticas de todas bibliotecas de sistema (libpthreads) e
libdl), portanto voe n˜ao pode compilar o MySQL com --static. Se vocˆe tentar fazer
isto, receber´a o erro:
ld: fatal: library -ldl: not found
ou
undefined reference to ‘dlopen’
ou
cannot find -lrt
Se v´arios processos tentar conectar muito rapidamente ao mysqld, vocˆe ver´a este erro no
log do MySQL:
Error in accept: Protocol error
Voe deve tentar iniciar o servidor com a op¸ao --set-variable back_log=50 como uma
solu¸ao para esta situa¸ao. See hundefinedi[Command-line options], page hundefinedi.
Se vocˆe est´a ligando seu pr´oprio cliente MySQL, vocˆe deve obter o seguinte erro quando
tentar execut´a-lo:
ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory
O problema pode ser evitado por um dos seguintes m´etodos:
Ligue o cliente com a seguinte op¸ao (em vez de -Lpath): -Wl,r/full-path-to-
libmysqlclient.so.
Copie o arquivo ‘libmysqclient.so’ para ‘/usr/lib’.
Chapter 2: Instala¸ao do MySQL 135
Adicione o caminho do diret´orio onde ‘libmysqlclient.so’ est´a localizado `a vari´avel
de ambiente LD_RUN_PATH antes de executar seu cliente.
Quando estiver usando a op¸ao do configure --with-libwrap, vocˆe tamb´em deve incluir as
bibliotecas que o ‘libwrap.a’ necessita:
--with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket
Se vocˆe tiver problemas com o configure tentando ligar com -lz e vocˆe n˜ao tem a zlib
instalada, vocˆe ter´a duas op¸oes:
Se vocˆe deseja usar o protocol de comuni¸ao de compactado vocˆe precisar´a obter e
instalar a zlib from ftp.gnu.org.
Configure com --with-named-z-libs=no.
Se vocˆe estiver usando o gcc e tiver problemas carregando fun¸oes UDF no MySQL, tente
adicionar -lgcc para a linha de liga¸ao para a fun¸ao UDF.
Se vocˆe deseja que o MySQL inicie automaticamente, vocˆe pode copiar
support-files/mysql.server’ para ‘/etc/init.d’ e criar um link simolico
para ele, chamado ‘/etc/rc.3.d/S99mysql.server’.
2.6.3.1 Notas Solaris 2.7/2.8
Voe pode utilizar normalmente um bin´ario Solaris 2.6 no Solaris 2.7 e 2.8. A maioria dos
detalhes do Solaris 2.6 tamb´em se aplicam ao Solaris 2.7 e 2.8.
Note que o MySQL vers˜ao 3.23.4 e superiores devem estar aptos para autodetectar novas
vers˜oes do Solaris e habilitar solu¸c˜oes para os problemas seguintes!
Solaris 2.7 / 2.8 tem alguns bugs nos arquivos include. Vocˆe pode ver o seguinte erro quando
vocˆe usa o gcc:
/usr/include/widec.h:42: warning: ‘getwc’ redefined
/usr/include/wchar.h:326: warning: this is the location of the previous
definition
Se isto ocorrer, vocˆe pode fazer o seguinte para corrigir o problema:
Copie /usr/include/widec.h para .../lib/gcc-lib/os/gcc-version/include e mude
a linha 41 :
#if !defined(lint) && !defined(__lint)
para
#if !defined(lint) && !defined(__lint) && !defined(getwc)
Uma alternativa ´e editar o ‘/usr/include/widec.h’ diretamente. Desta forma, depois de
fazer a corre¸ao, vocˆe deve remover o ‘config.cache’ e executar o configure novamente !
Se vocˆe obter erros como estes quando vocˆe executar o make, ´e porque o configure
ao encontrou o arquivo ‘curses.h’ (provavelmente devido ao erro no arquivo
/usr/include/widec.h’):
In file included from mysql.cc:50:
/usr/include/term.h:1060: syntax error before ‘,’
/usr/include/term.h:1081: syntax error before ‘;’
A solu¸ao para isto ´e fazer uma das seguintes op¸oes:
136 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Configure com CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H ./configure.
Edite o ‘/usr/include/widec.h’ como indicado acima e re-execute o configure.
Remova a linha #define HAVE_TERM do arquivo ‘config.h’ e execute make novamente.
Se o seu ligador tiver problemas para encontrar o -lz quando ligar ao seu programa cliente,
provavelmente o problema ´e que seu arquivo ‘libz.so’ est´a instalado em ‘/usr/local/lib’.
Voe pode corrigir isto usando um dos seguintes m´etodos:
Adicione ‘/usr/local/lib’ ao LD_LIBRARY_PATH.
Adicione um link para ‘libz.so’ a partir de ‘/lib’.
Se vocˆe estiver usando o Solaris 8, vocˆe pode instalar a zlib opcional do CD de dis-
tribui¸ao do Solaris 8.
Configure o MySQL com a op¸ao --with-named-z-libs=no.
2.6.3.2 Notas Solaris x86
No Solaris 2.8 no x86, mysqld ir´a descarregar um core se vocˆe executar um ’strip’ no mesmo.
Se vocˆe estiver usando gcc ou egcs no Solaris X86 e vocˆe tiver problemas com descarregos
de core, vocˆe deve utilizar o seguinte comando configure:
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
./configure --prefix=/usr/local/mysql
Isto ir´a evitar problemas com a biblioteca libstdc++ e com exce¸oes C++.
Se isto n˜ao ajudar, vocˆe pode compilar uma vers˜ao com debug e execut´a-lo com um arquivo
de ratreamento (trace) ou sob gdb. See hundefinedi[Using gdb on mysqld], page hundefinedi.
2.6.4 Notas BSD
2.6.4.1 Notas FreeBSD
FreeBSD 3.x ´e recomendado para executa¸ao do MySQL uma vez ue o pacote thread ´e
muito mais integrado.
A mais f´acil e portanto a forma preferida para instal´a-lo ´e usar as portas mysql-server e
mysql-client dispon´
iveis em http://www.freebsd.org.
Usando-as vocˆe obtem:
Um MySQL funcional, com todas as otimiza¸oes conhecidas para trabalhar na sua
vers˜ao habilitada do FreeBSD.
Configura¸ao e constru¸ao autom´atica.
Scripts de inicializa¸ao instalados em /usr/local/etc/rc.d.
Habilidade para ver quais arquivos est˜ao instalados com pkg info -L. E para remover
todos com pkg delete se vocˆe n˜ao quiser mais o MySQL na m´aquina.
´
E recomendado que vocˆe utilize MIT-pthreads no FreeBSD 2.x e threads nativas nas Vers˜oes
3 e superiores. ´
E poss´
ivel executar com threads nativas em algumas vers˜oes antigas (2.2.x)
mas vocˆe pode encontrar problemas ao finalizar o mysqld.
Chapter 2: Instala¸ao do MySQL 137
O ‘Makefile’ do MySQL necessita o GNU make (gmake) para funcionar. Se vocˆe deseja
compilar o MySQL, antes vocˆe precisar´a instalar o GNU make.
Tenha certeza que sua configura¸ao de resolu¸ao de nomes esteja correta. De outra forma
vocˆe vai ter atrasos na resolu¸ao ou falhas quando conectar ao mysqld.
Tenha certeza que a entrada localhost no arquivo ‘/etc/hosts’ esteja correta (de outra
forma vocˆe ir´a ter problemas conectando ao banco de dados). O arquivo ‘/etc/hosts’ deve
iniciar com a linha:
127.0.0.1 localhost localhost.seu.dominio
Se vocˆe notar que o configure ir´a usar MIT-pthreads, vocˆe deve ler as notas sobre o
MIT-pthreads. See hundefinedi[MIT-pthreads], page hundefinedi.
Se vocˆe obter um erro do make install dizendo que ele n˜ao consegue encontrar
/usr/include/pthreads’, o configure ao percebeu que vocˆe necessita da
MIT-pthreads. Isto ´e corrigido com os seguintes comandos:
shell> rm config.cache
shell> ./configure --with-mit-threads
O FreeBSD ´e tamb´em conhecido por ter um limite muito baixo para o manipulador de
arquivos. See hundefinedi[Not enough file handles], page hundefinedi. Descomente a se¸ao
ulimit -n no safe mysqld ou aumente os limites para o usu´ario mysqld no /etc/login.conf (e
reconstrua-o com cap mkdb /etc/login.conf). Tamb´em tenha certeza que vocˆe configurou
a classe apropriada para este usu´ario no arquivo de senhas (password) se vocˆe n˜ao es-
tiver usando o padr˜ao (use: chpass nome usuario mysqld). See hundefinedi[safe_mysqld],
page hundefinedi
Se vocˆe tiver problemas com a data atual no MySQL, configurar a vari´avel TZ provavelmente
ajudar´a. See hundefinedi[Environment variables], page hundefinedi.
Para obter um sistema seguro e est´avel vocˆe deve usar somente kernels FreeBSD que estejam
marcados com -STABLE.
2.6.4.2 Notas NetBSD
Para compilar no NetBSD vocˆe precisa do GNU make. De outra forma o compilador que-
braria quando o make tentasse executar lint em arquivos C++.
2.6.4.3 Notas OpenBSD
2.6.4.4 Notas OpenBSD 2.5
No OpenBSD Vers˜ao 2.5, vocˆe pode compilar o MySQL com threads nativas com as
seguintes op¸oes:
CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no
2.6.4.5 Notas OpenBSD 2.8
Nossos usu´arios relataram que o OpenBSD 2.8 tem um bug nas threads que causa problemas
com o MySQL. Os desenvolvedores do OpenBSD j´a corrigiram o problema, mas em 25 de
Janeiro de 2001 a corre¸ao foi dispon´
ivel apenas no ramo “-current”. Os sintomas deste
bug nas threads s˜ao: resposta lenta, alta carga, alto uso de CPU e quedas do servidor.
138 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
2.6.4.6 Notas BSD/OS
2.6.4.7 Notas BSD/OS Vers˜ao 2.x
Se vocˆe obter o seguinte erro quando estiver compilando o MySQL, seu valor ulimit para
mem´oria virtual ´e muito baixo:
item_func.h: In method ‘Item_func_ge::Item_func_ge(const Item_func_ge &)’:
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1
Tente usar ulimit -v 80000 e executar o make novamente. Se isto n˜ao funcionar e vocˆe es-
tiver usando o bash, tente trocar para csh ou sh; alguns usu´arios BSDI relataram problemas
com bash eulimit.
Se vocˆe utiliza gcc, vocˆe pode tamb´em ter de usar a op¸ao --with-low-memory para o
configure estar apto a compilar o ‘sql_yacc.cc’.
Se vocˆe tiver problemas com a data atual no MySQL, configurar a vari´avel TZ provavelmente
ajudar´a. See hundefinedi[Environment variables], page hundefinedi.
2.6.4.8 Notas BSD/OS Version 3.x
Atualize para BSD/OS Vers˜ao 3.1. Se isto n˜ao for poss´
ivel, instale BSDIpatch M300-038.
Use o seguinte comando quando configurar o MySQL:
shell> env CXX=shlicc++ CC=shlicc2 \
./configure \
--prefix=/usr/local/mysql \
--localstatedir=/var/mysql \
--without-perl \
--with-unix-socket-path=/var/mysql/mysql.sock
O comeando seguinte tamb´em funciona:
shell> env CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure \
--prefix=/usr/local/mysql \
--with-unix-socket-path=/var/mysql/mysql.sock
Voe pode alterar as localiza¸oes dos diret´orios se vocˆe desejar, ou apenas usar os padr˜oes
ao especificando nenhuma localiza¸ao.
Se vocˆe tiver problemas com performance sob alta carga, tente usar a op¸ao --skip-thread-
priority para mysqld! Isto ir´a executar todas as threads com a mesma prioridade; no BSDI
vers˜ao 3.1, isto fornece melhor performance (pelo menos at´e o BSDI corrigir seu organizador
de threads).
Se vocˆe obter o erro virtual memory exhausted enquanto estiver compilando, deve tentar
usar ulimit -v 80000 e executar make novamente. Se isto n˜ao funcionar e vocˆe estiver
usando bash, tente trocar para csh ou sh; alguns usu´arios BSDI relataram problemas com
bash eulimit.
Chapter 2: Instala¸ao do MySQL 139
2.6.4.9 Notas BSD/OS Vers˜ao 4.x
O BSDI Vers˜ao 4.x tem alguns bugs relacionados `as threads. Se vocˆe deseja usar o MySQL
nesta vers˜ao, vocˆe deve instalar todas as corre¸oes relacionadas `as threads. Pelo menos a
M400-23 deve estar instalada.
Em alguns sistemas BSDI vers˜ao 4.x, vocˆe pode ter problemas com bibliotecas compartil-
hadas. O sintoma ´e que vocˆe n˜ao pode executar nenhum programa cliente, por exemplo,
mysqladmin. Neste caso voe precisa reconfigurar o MySQL, para ele n˜ao usar bibliotecas
compartilhadas, com a op¸ao --disable-shared.
Alguns clientes tiveram problemas no BSDI 4.0.1 que o bin´ario do mysqld ao conseguia
abrir tabelas depois de um tempo em funcionamento. Isto ´e porque alguns bugs relaciona-
dos a biblioteca/sistema fazem com que o mysqld altere o diret´orio atual sem nenhuma
informa¸ao!
A corre¸ao ´e atualizar para a 3.23.34 ou depois de executar configure remova a linha
$define HAVE_REALPATH de config.h antes de executar o make.
Perceba que com isso vocˆe n˜ao pode fazer um link simolico de um diret´orio de banco de
dados para outro diret´orio ou fazer um link simolico a uma tabela para outro banco de
dados no BSDI! (Criar um link simolico para outro disco funciona).
2.6.5 Notas Mac OS X
2.6.5.1 Mac OS X Public Beta
O MySQL deve funcionar sem problemas no Mac OS X Public Beta (Darwin). Vocˆe n˜ao
precisa dos patches pthread para este SO.
2.6.5.2 Mac OS X Server
Antes de tentar configurar o MySQL no MAC OS X server, primeiro vocˆe deve instalar o
pacote pthread encontrado em: http://www.prnet.de/RegEx/mysql.html.
Nosso bin´ario para o Mac OS X ´e compilado no Rhapsody 5.5 com a seguinte linha de
configura¸ao:
CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex --disable-shared
Voe deve precisar adicionar tamb´em apelidos (alias) para seu arquivo de shell para acessar
mysql emysqladmin da linha de comando:
alias mysql ’/usr/local/mysql/bin/mysql’
alias mysqladmin ’/usr/local/mysql/bin/mysqladmin’
2.6.6 Outras Notas Unix
2.6.6.1 Notas HP-UX para distribui¸oes bin´arias
Alguma das distribui¸oes bin´arias do MySQL para HP-UX ´e distribuida como um arquivo
depot da HP e como um arquivo tar. Para usar o arquivo depot vocˆe deve estar executando
pelo menos o HP-UX 10.x para ter acesso `as ferramentas de arquivos depot da HP.
140 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A vers˜ao HP do MySQL foi compilada em um servidor HP 9000/8xx sob HP-UX 10.20,
usando MIT-pthreads. Sob esta configura¸ao o MySQL funciona bem. O MySQL Vers˜ao
3.22.26 e mais novas tamb´em podem ser construidas com o pacote thread nativo da HP.
Outras configura¸oes que podem funcionar:
HP 9000/7xx executando HP-UX 10.20+
HP 9000/8xx executando HP-UX 10.30
As seguintes configura¸oes definitivamente n˜ao funcionar˜ao:
HP 9000/7xx ou 8xx executando HP-UX 10.x where x <2
HP 9000/7xx ou 8xx executando HP-UX 9.x
Para instalar a distribui¸ao, utilze um dos comandos abaixo, onde /path/to/depot ´e o
caminho completo do arquivo depot:
Para instalar tudo, incluindo o servidor, cliente e ferramentas de desenvolvimento:
shell> /usr/sbin/swinstall -s /path/to/depot mysql.full
Para instalar somente o servidor:
shell> /usr/sbin/swinstall -s /path/to/depot mysql.server
Para instalar somente o pacote cliente:
shell> /usr/sbin/swinstall -s /path/to/depot mysql.client
Para instalar somente as ferramentas de desenvolvimento:
shell> /usr/sbin/swinstall -s /path/to/depot mysql.developer
O depot copia os bin´arios e bibliotecas em ‘/opt/mysql’ e dados em ‘/var/opt/mysql’. O
depot tamb´em cria as entradas apropriadas em ‘/etc/init.d’ e ‘/etc/rc2.d’ para iniciar
o servidor automaticamente na hora do boot. Obviamente, para instalar o usu´ario deve ser
oroot.
Para instalar a distribui¸ao HP-UX tar.gz, vocˆe deve ter uma c´opia do GNU tar.
2.6.6.2 Notas HP-UX Vers˜ao 10.20
Existem alguns pequenos problemas quando compilamos o MySQL no HP-UX. N´os re-
comendamos que vocˆe use o gcc no lugar do compilador nativo do HP-UX, porque o gcc
produz um c´odigo melhor!
os recomendamos o uso do gcc 2.95 no HP-UX. N˜ao utilize op¸oes de alta otimiza¸ao
(como -O6) ja que isto pode n˜ao ser seguro no HP-UX.
Perceba que as MIT-pthreads n˜ao podem ser compiladas com o compilador HP-UX porque
ele n˜ao pode compilar arquivos .S (assembler).
A seguinte linha de configura¸ao deve funcionar:
CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs=’-ldce’ --prefix=/usr/local/mysql --disable-shared
Se vocˆe mesmo est´a compilando gcc 2.95, vocˆe n˜ao deve lig´a-lo com as bibliotecas DCE
(libdce.a ou libcma.a) se vocˆe deseja compilar o MySQL com MIT-pthreads. Se vocˆe
misturar os pacotes DCE e MIT-pthreads, vocˆe ir´a obter um mysqld com o qual n˜ao poder´a
conetar. Remova as bibliotecas DCE enquanto voe compila gcc 2.95!
Chapter 2: Instala¸ao do MySQL 141
2.6.6.3 Notas HP-UX Vers˜ao 11.x
Para HP-UX Vers˜ao 11.x n´os recomendamos o MySQL Vers˜ao 3.23.15 ou posterior.
Por causa de alguns bugs cr´
iticos nas bibliotecas padr˜ao do HP-UX, vocˆe deve instalar as
seguintes corre¸oes antes de tentar executar o MySQL no HP-UX 11.0:
PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative
Isto ir´a resolver um problema que tem como retorno EWOLDBLOCK de recv() eEBADF de
accept() em aplica¸oes threads.
Se vocˆe estiver usando gcc 2.95.1 em um sistema HP-UX 11.x sem corre¸oes, vocˆe obter´a
o erro:
In file included from /usr/include/unistd.h:11,
from ../include/global.h:125,
from mysql_priv.h:15,
from item.cc:19:
/usr/include/sys/unistd.h:184: declaration of C function ...
/usr/include/sys/pthread.h:440: previous declaration ...
In file included from item.h:306,
from mysql_priv.h:158,
from item.cc:19:
O problema ´e que o HP-UX n˜ao define consistentemente a pthreads_
atfork(). Ela tem prot´otipos coflitantes em ‘/usr/include/sys/unistd.h’:184
e ‘/usr/include/sys/pthread.h’:440 (detalhes abaixo).
Uma solu¸ao ´e copiar ‘/usr/include/sys/unistd.h’ em ‘mysql/include’ e editar
unistd.h’ alterando-o para coincidir com a defini¸ao em ‘pthread.h’. Aqui est´a o diff:
183,184c183,184
< extern int pthread_atfork(void (*prepare)(), void (*parent)(),
< void (*child)());
---
> extern int pthread_atfork(void (*prepare)(void), void (*parent)(void),
> void (*child)(void));
Depois disto, a seguinte linha configure deve funcionar:
CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" ./configure --prefix=/usr/local/mysql --disable-shared
Segue algumas inforama¸oes que um usu´ario do HP-UX Vers˜ao 11.x nos enviou sobre com-
pila¸ao do MySQL com o compilador HP-UX:
Environment:
proper compilers.
setenv CC cc
setenv CXX aCC
flags
setenv CFLAGS -D_REENTRANT
setenv CXXFLAGS -D_REENTRANT
setenv CPPFLAGS -D_REENTRANT
% aCC -V
aCC: HP ANSI C++ B3910B X.03.14.06
% cc -V /tmp/empty.c
142 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
cpp.ansi: HP92453-01 A.11.02.00 HP C Preprocessor (ANSI)
ccom: HP92453-01 A.11.01.00 HP C Compiler
cc: "/tmp/empty.c", line 1: warning 501: Empty source file.
configuration:
./configure --with-pthread \
--prefix=/source-control/mysql \
--with-named-thread-libs=-lpthread \
--with-low-memory
added ’#define _CTYPE_INCLUDED’ to include/m_ctype.h. This
symbol is the one defined in HP’s /usr/include/ctype.h:
/* Don’t include std ctype.h when this is included */
#define _CTYPE_H
#define __CTYPE_INCLUDED
#define _CTYPE_INCLUDED
#define _CTYPE_USING /* Don’t put names in global namespace. */
Eu tive que usar a op¸ao de tempo de compila¸ao -D_REENTRANT para que o compilador
reconhe¸ca o prot´otipo para localtime_r. Uma forma alternativa ´e fornecer o prot´otipo
para localtime_r. Mas eu queria pegar outros erros sem precisar execut´a-los. ao
tinha certeza onde eu precisaria dele, portanto eu o adicionei a todas as op¸oes.
As op¸oes de otimiza¸ao utilizadas pelo MySQL (-O3) n˜ao ´e reconhecida pelos compi-
ladores HP. Eu n˜ao alterei as op¸oes.
Se vocˆe obter o seguinte erro do configure
checking for cc option to accept ANSI C... no
configure: error: MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.
Confira se vocˆe n˜ao tem o caminho para o compilador K&R antes do caminho para o
compilador C e C++ do HP-UX.
2.6.6.4 Notas IBM-AIX
Detec¸ao autom´atica de xlC est´a faltando no Autoconf, portando um comando configure
deste tipo ´e necess´ario quando estiver compilando o MySQL (Este exemplo usa o compilador
IBM):
export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 "
export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192"
export CFLAGS="-I /usr/local/include"
export LDFLAGS="-L /usr/local/lib"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS
./configure --prefix=/usr/local \
--localstatedir=/var/mysql \
--sysconfdir=/etc/mysql \
--sbindir=’/usr/local/bin’ \
--libexecdir=’/usr/local/bin’ \
Chapter 2: Instala¸ao do MySQL 143
--enable-thread-safe-client \
--enable-large-files
Acima est˜ao as op¸oes usadas para compilar a distribui¸ao MySQL que pode ser encontrada
em http://www-frec.bull.com/.
Se vocˆe alterar o -O3 para -O2 na linha de configura¸ao acima, voe tamb´em deve remover
a op¸ao -qstrict (isto ´e uma limita¸ao no compilador C da IBM).
Se vocˆe estiver usando gcc ou egcs para compilar o MySQL, vocˆe DEVE usar a op¸ao -fno-
exceptions, j´a que o manipulador de exce¸oes no gcc/egcs ao ´e seguro para threads! (Isto
foi testado com egcs 1.1). Existem tamb´em alguns problemas conhecidos com o assembler
da IBM que pode gerar c´odigo errado quando usado com gcc.
os recomendamos a seguinte linha do configure com egcs egcc 2.95 no AIX:
CC="gcc -pipe -mcpu=power -Wa,-many" \
CXX="gcc -pipe -mcpu=power -Wa,-many" \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory
O-Wa,-many ´e necess´ario para o compilador ser bem sucedido. IBM est´a ciente deste
problema mas n˜ao est´a com pressa de corrig´
i-lo devido ao fato do problema poder ser
contornado. os n˜ao sabemos se o -fno-exceptions ´e necess´ario com gcc 2.9.5, mas
como o MySQL n˜ao utiliza exce¸oes e a op¸ao acima gera c´odigo mais r´apido, recomendamos
que vocˆe sempre use esta op¸ao com o egcs/gcc.
Se vocˆe tiver algum problema com c´odigo assembler tente alterar o -mcpu=xxx para o seu
processador. Normalmente power2, power ou powerpc podem ser usados, de uma maneira
alternativa vocˆe pode precisar usar 604 ou 604e. ao tenho certeza mas acredito que usar
"power"deve satisfazer a maioria dos casos, mesmo em uma m´aquina power2.
Se vocˆe n˜ao sabe qual ´e o seu processador, utilize o comando "uname -m", isto
ir´a fornecer a vocˆe uma string que parece com "000514676700", com um formato
de xxyyyyyymmss onde xx e ss s˜ao sempre 0s, yyyyyy ´e o ID ´unico do sistema e
mm ´e o ID da CPU Planar. Uma tabela destes valores podem ser encontrados em
http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm.
Isto ir´a lhe fornecer um tipo de m´aquina e um modelo de m´aquina que vocˆe pode usar
para determinar que tipo de cpu voe tem.
Se vocˆe tiver problemas com sinais (MySQL finaliza sem notifica¸ao sob alta carga) vocˆe
pode ter encontrado um bug de SO com threads e sinais. Neste caso vocˆe pode dizer ao
MySQL para n˜ao usar sinais configurando-o com:
shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \
./configure --prefix=/usr/local/mysql --with-debug --with-low-memory
Isto n˜ao afeta a performance do MySQL, mas tem o efeito colateral que vocˆe ao pode
matar clientes que est˜ao “dormindo” em uma conex˜ao com mysqladmin kill ou mysqladmin
shutdown. Neste caso, o cliente morrer´a quando ele chegar no pr´oximo comando.
Em algumas vers˜oes do AIX, ligando com libbind.a faz o getservbyname descarregar core.
Isto ´e erro no AIX e deve ser relatado para a IBM.
Para o AIX 4.2.1 e gcc vocˆe tem que fazer as seguintes altera¸oes.
Depois de configurar, edite o ‘config.h’ e ‘include/my_config.h’ e altere a linha que diz
144 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
#define HAVE_SNPRINTF 1
para
#undef HAVE_SNPRINTF
E finalmente, no ‘mysqld.cc’ vocˆe precisa adicionar um prot´otipo para initgroups.
#ifdef _AIX41
extern "C" int initgroups(const char *,int);
#endif
2.6.6.5 Notas SunOS 4
No SunOS 4, ´e necess´ario a MIT-pthreads para compilar o MySQL, o que significa que vocˆe
precisa do GNU make.
Alguns sistemas SunOS 4 tem problemas com bibliotecas dinˆamicas e libtool. Vocˆe pode
usar a seguinte linha do configure para evitar este problema:
shell> ./configure --disable-shared --with-mysqld-ldflags=-all-static
Quando compilando readline, vocˆe pode obter alguns avisos sobre defini¸oes duplicadas
que podem ser ignoradas.
Ao compilar o mysqld, v˜ao existir alguns alertas sobre implicit declaration of function
que tamb´em podem ser ignoradas.
2.6.6.6 Notas Alpha-DEC-UNIX (Tru64)
Se vocˆe est´a usando o egcs 1.1.2 no Digital Unix, vocˆe atualizar par o gcc 2.95.2, j´a que o
egcs no DEC tem v´arios erros graves !
Quando compilando programas com threads no Digital Unix, a documenta¸ao recomenda
usar a op¸ao -pthread para cc ecxx e as bibliotecas -lmach -lexc (em adi¸c˜ao para -
lpthread). Voe deve executar o configure parecido com isto:
CC="cc -pthread" CXX="cxx -pthread -O" \
./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"
Quando compilando o mysqld, vocˆe deve ver alguns avisos como estes:
mysqld.cc: In function void handle_connections()’:
mysqld.cc:626: passing long unsigned int *’ as argument 3 of
accept(int,sockadddr *, int *)’
Voe pode ignorar estes altertas com seguran¸ca. Eles ocorrem porque o configure o pode
detectar erros e n˜ao alertas.
Se vocˆe inicia o servidor diretamente da linha de comando, vocˆe pode ter problemas com
a finaliza¸ao do servidor ao sair (log out). (Quando vocˆe sai, seu processo superior recebe
um sinal SIGHUP.) Se isto acontecer, tente iniciar o servidor desta forma:
shell> nohup mysqld [options] &
nohup faz com que o comando que o segue ignore qualquer sinal SIGHUP enviado pelo
terminal. De forma alternativa, inicie o servidor executando safe_mysqld, o qual invoca o
mysqld usando nohup por vocˆe. See hundefinedi[safe_mysqld], page hundefinedi.
Se vocˆe tiver problemas quando compilar mysys/get opt.c, apenas remova a linha #define
NO PROTO do inicio do arquivo!
Chapter 2: Instala¸ao do MySQL 145
Se vocˆe estiver utilizando o compilador CC da Compac, a seguinte linha de configura¸ao
dever´a funcionar:
CC="cc -pthread"
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
CXX="cxx -pthread"
CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
export CC CFLAGS CXX CXXFLAGS
./configure \
--prefix=/usr/local/mysql \
--with-low-memory \
--enable-large-files \
--enable-shared=yes \
--with-named-thread-libs="-lpthread -lmach -lexc -lc"
gnumake
Se vocˆe tiver problemas com a libtool, ao compilar com bibliotecas compartilhadas como
no exemplo acima, quando estiver ligando ao mysqld, vocˆe deve conseguir contornar este
problema usando:
cd mysql
/bin/sh ../libtool --mode=link cxx -pthread -O3 -DDBUG_OFF \
-O4 -ansi_alias -ansi_args -fast -inline speed \
-speculate all \ -arch host -DUNDEF_HAVE_GETHOSTBYNAME_R \
-o mysql mysql.o readline.o sql_string.o completion_hash.o \
../readline/libreadline.a -lcurses \
../libmysql/.libs/libmysqlclient.so -lm
cd ..
gnumake
gnumake install
scripts/mysql_install_db
2.6.6.7 Notas Alpha-DEC-OSF1
Se vocˆe tiver problemas com compila¸ao e tem o DEC CC e o gcc instalados, tente executar
oconfigure desta forma:
CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
Se vocˆe tiver problemas com o arquivo ‘c_asm.h’, vocˆe pode criar e usar um arquivo
c_asm.h’ ’burro’ com:
touch include/c_asm.h
CC=gcc CFLAGS=-I./include \
CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
Perceba que os seguintes problemas com o programa ld pode ser corrigido
fazendo o download do ´ultimo kit de atualiza¸ao da DEC (Compaq) de
http://ftp.support.compaq.com/public/unix/.
Com o OSF1 V4.0D e o compilador "DEC C V5.6-071 no Digital Unix V4.0 (Rev. 878)"
o compilador tem alguns comportamentos estranhos (simbolos asm indefinidos). /bin/ld
tamb´em aparece estar quebrado (problemas com erros _exit undefined ocorrendo ao ligar
146 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
no mysqld). Neste sistema, temos compilado o MySQL com a seguinte linha configure,
depois de substituir /bin/ld com a vers˜ao do OSF 4.0C:
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
Com o compilador da Digital "C++ V6.1-029", o seguinte deve funcionar:
CC=cc -pthread
CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
CXX=cxx -pthread
CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host -noexceptions -nortti
export CC CFLAGS CXX CXXFLAGS
./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
Em algumas vers˜oes do OSF1, a fun¸ao alloca() est´a quebrada. Corrija isto removendo a
linha no ‘config.h’ que define ’HAVE_ALLOCA’.
A fun¸ao alloca() pode tamb´em ter um prot´otipo incorreto em /usr/include/alloca.h.
O alerta resultante deste erro pode ser ignorado.
configure ir´a usar a seguinte biblioteca thread automaticamente: --with-named-thread-
libs="-lpthread -lmach -lexc -lc".
Quando usar o gcc, vocˆe tamb´em pode tentar executar configure desta forma:
shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....
Se vocˆe tiver problemas com sinais (MySQL finalzar inesperadamente sobre alta carga),
vocˆe pode ter encontrado um erro com threads e sinais no SO. Neste caso vocˆe pode dizer
ao MySQL para n˜ao usar sinais configurando-o com:
shell> CFLAGS=-DDONT_USE_THR_ALARM \
CXXFLAGS=-DDONT_USE_THR_ALARM \
./configure ...
Isto n˜ao afeta a performance do MySQL, mas tem efeitos colaterais que n˜ao permitem
finalizar clientes que est˜ao “dormindo” em uma conex˜ao com mysqladmin kill ou
mysqladmin shutdown. Neste caso o cliente ir´a morrer quando ele receber o pr´oximo
comando.
Com gcc 2.95.2, vocˆe provavelmente encontrar´a o seguinte erro de compila¸ao:
sql_acl.cc:1456: Internal compiler error in ‘scan_region’, at except.c:2566
Please submit a full bug report.
Para corrigir isto vocˆe deve alterar para o diret´orio sql e fazer um “corta e cola” da ´ultima
linha gcc, mas altere -O3 para -O0 (ou adicione -O0 imediatamente depois de gcc se vocˆe
ao tiver algumas op¸ao -O na sua linha de compila¸ao.) Depois disto feito vocˆe deve apenas
voltar ao diret´orio superior e executar make novamente.
2.6.6.8 Notas SGI Irix
Se vocˆe estiver usando Irix Vers˜ao 6.5.3 ou mais novo, o mysqld o ir´a conseguir criar threads
se vocˆe execut´a-lo como um usu´ario com privil´egios de CAP_SCHED_MGT (como root) ou dar
ao servidor mysqld este privil´egio com o seguinte comando shell:
shell> chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
Voe pode precisar indefinir algumas coisas em ‘config.h’ depois de executar configure
e antes de compilar.
Chapter 2: Instala¸ao do MySQL 147
Em algumas implementa¸oes Irix, a fun¸ao alloca() est´a quebrada. Se o servidor mysqld
morrer em alguma instru¸ao SELECT, remova as linhas de ‘config.h’ que definem HAVE_
ALLOC eHAVE_ALLOC_H. Se mysqladmin create ao funciona, remova a linha do ‘config.h
que define HAVE_READDIR_R. Voe tamb´em deve precisar remover a linha HAVE_TERM_H.
A SGI recomenda que vocˆe instale todos os patches desta p´agina: http://support.sgi.com/surfzone/patches/patchset/6.2 indigo.rps.html
No m´
inimo, vocˆe deve instalar o ´ultimo rollup do kernel, o ´ultimo rollup rld, e o ´ultimo
rollup libc.
Definitivamente vocˆe precisar´a de todos patches POSIX nesta p´agina, para suporte
pthreads:
http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html
Se vocˆe obter o seguinte erro quando estiver compilando o ‘mysql.cc’:
"/usr/include/curses.h", line 82: error(1084): invalid combination of type
Digite o seguinte no diret´orio topo da sua ´arvore fonte do MySQL:
shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
shell> make
Existem relatos de problemas com organiza¸ao de threads. Se somente uma thread estiver
executando, o sistema fica lento. Pode se evitar isto iniciando outro cliente. Isto pode
acarretar num crescimento de 2 para 10 vezes na velocidade de execu¸ao para a outra
thread. Isto ´e um problema n˜ao compreendido com threads Irix; vocˆe deve improvisar para
encontrar solu¸oes at´e que isto seja resolvido.
Se vocˆe estiver compilando com gcc, vocˆe pode usar o seguinte comando configure:
CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql --enable-thread-safe-client --with-named-thread-libs=-lpthread
No Irix 6.5.11 com Irix C nativo e compiladores C++ ver. 7.3.1.2, o seguinte ir´a funcionar
CC=cc CXX=CC CFLAGS=’-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib’ CXXFLAGS=’-O3 -n32 -TARG:platform=IP22 \
-I/usr/local/include -L/usr/local/lib’ ./configure --prefix=/usr/local/mysql \
--with-berkeley-db --with-innodb \
--with-libwrap=/usr/local --with-named-curses-libs=/usr/local/lib/libncurses.a
2.6.6.9 Notas SCO
A vers˜ao atual foi testado somente nos sistemas “sco3.2v5.0.4” e “sco3.2v5.0.5”. A vers˜aoo
para o “sco 3.2v4.2” tamb´em tem tido muito progresso.
At´e o momento o compilador recomendado no OpenServer ´e o gcc 2.95.2. Com isto vocˆe
deve estar apto a compilar o MySQL apenas com:
CC=gcc CXX=gcc ./configure ... (op¸c~oes)
1. Para o OpenServer 5.0.X vocˆe precisa usar o GDS no SKunkware 95 (95q4c). Isto
´e necess´ario porque o GNU gcc 2.7.2 no Skunkware 97 n˜ao possui o GNU as. Vocˆe
tamb´em pode usar o egcs 1.1.2 ou mais novo http://www.egcs.com/. Se vocˆe estiver
usando egcs 1.1.2 vocˆe deve executar o seguinte comando:
shell> cp -p /usr/include/pthread/stdtypes.h /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pthread/
148 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
2. Vocˆe precisa do GCC vers˜ao 2.5.x para este produto e do sistema de desenvolvimento.
Eles s˜ao necess´arios nesta vers˜ao do SCO Unix. Vocˆe n˜ao pode usar apenas o sistema
GCC Dev.
3. Vocˆe deve obter o pacote FSU Pthreads e instal´a-lo primeiro. Pode ser obtido em
http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-threads.tar.gz. Voe
pode tamb´em obter um pacote precompilado de http://www.mysql.com/Downloads/SCO/FSU-threads-3.5c.tar.gz.
4. FSU Pthreads pode ser compilado com SCO Unix 4.2 com tcpip, ou OpenServer 3.0
ou OpenDesktop 3.0 (OS 3.0 ODT 3.0), com o Sistema de Desenvolvimento da SCO
instalado usando uma boa vers˜ao do GCC 2.5.x ODT ou OS 3.0, no qual voe necessi-
tar´a de uma boa vers˜ao do GCC 2.5.x. Existem v´arios problemas sem uma boa vers˜ao.
Esta vers˜ao do produto necessita do sistema de Desenvolvimento SCO Unix. Sem ele,
vocˆe estar´a perdendo as bibliotecas e o editor de liga¸ao necess´ario.
5. Para construir a FSU Pthreads no seu sistema, fa¸ca o seguinte:
a. Execute ./configure no diret´orio ‘threads/src’ e selecione a op¸ao SCO
OpenServer. Este comando copia ‘Makefile.SCO5’ para ‘Makefile’.
b. Execute make.
c. Para instalar no diret´orio padr˜ao ‘/usr/include’, use o usu´ario root, depois mude
para o diret´orio ‘thread/src’ e execute make install
6. Lembre de usar o GNU make quando estiver construindo o MySQL.
7. Se vocˆe n˜ao iniciou o safe_mysqld como root, vocˆe provavelmente s´o ir´a obter, por
padr˜ao, os 110 arquivos abertos por processo. O mysqld ir´a gravar uma nota sobre isto
no arquivo log.
8. Com o SCO 3.2V5.0.5, vocˆe deve usar o FSU Pthreads vers˜ao 3.5c ou mais nova. Vocˆe
deve tamb´em usar o gcc 2.95.2 ou mais novo.
O seguinte comando configure deve funcionar:
shell> ./configure --prefix=/usr/local/mysql --disable-shared
9. Com SCO 3.2V4.2, vocˆe deve usar FSU Pthreads vers˜ao 3.5c ou mais nova. O seguinte
comando configure deve funcionar:
shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
./configure \
--prefix=/usr/local/mysql \
--with-named-thread-libs="-lgthreads -lsocket -lgen -lgthreads" \
--with-named-curses-libs="-lcurses"
Voe pode ter alguns problemas com alguns arquivos de inclus˜ao. Neste
caso, vocˆe pode encontrar novos arquivos de inclus˜ao espec´
ificos do SCO em
http://www.mysql.com/Downloads/SCO/SCO-3.2v4.2-includes.tar.gz. Vocˆe deve
descompactar este arquivo no diret´orio ‘include’ da sua ´arvore fonte do MySQL.
Notas de desenvolvimento SCO:
O MySQL deve detectar automaticamente FSU Pthreads e ligar o mysqld com -
lgthreads -lsocket -lgthreads.
As bibliotecas de desenvolvimento SCO s˜ao re-entrantes nas FSU Pthreads. A SCO
diz que suas bibliotecas de fun¸oes s˜ao re-entrantes, enao elas devem ser re-entrantes
com as FSU-Pthreads. FSU Pthreads no OpenServer tentam usar o esquema SCO para
criar bibliotecas re-entrantes.
Chapter 2: Instala¸ao do MySQL 149
FSU Pthreads (ao menos a vers˜ao em http://www.mysql.com) vem ligada com GNU
malloc. Se vocˆe encontrar problemas com uso de mem´oria, tenha certeza que o
gmalloc.o’ esteja inclu´
ido em ‘libgthreads.a’ e ‘libgthreads.so’.
Na FSU Pthreads, as seguintes chamadas de sistema s˜ao compat´
iveis com pthreads:
read(),write(),getmsg(),connect(),accept(),select() ewait().
O CSSA-2001-SCO.35.2 (O patch ´e listado de costume como patch de seguran¸ca
erg711905-dscr remap ver 2.0.0) quebra FSU threads e deixa o mysqld inst´avel. Voe
deve remove-lo se vocˆe deseja executar o mysqld em uma m´aquina OpenServer 5.0.6.
Se vocˆe deseja instalar o DBI no SCO, vocˆe deve editar o ‘Makefile’ em DBI-xxx e cada
subdiret´orio.
Note que o exemplo abaixo considera o gcc 2.95.2 ou mais novo:
OLD: NEW:
CC = cc CC = gcc
CCCDLFLAGS = -KPIC -W1,-Bexport CCCDLFLAGS = -fpic
CCDLFLAGS = -wl,-Bexport CCDLFLAGS =
LD = ld LD = gcc -G -fpic
LDDLFLAGS = -G -L/usr/local/lib LDDLFLAGS = -L/usr/local/lib
LDFLAGS = -belf -L/usr/local/lib LDFLAGS = -L/usr/local/lib
LD = ld LD = gcc -G -fpic
OPTIMISE = -Od OPTIMISE = -O1
OLD:
CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include
NEW:
CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include
Isto ´e porque o carregador dinˆamico Perl n˜ao ir´a carregar os m´odulos DBI se elas foram
compiladas com icc ou cc.
Perl trabalha melhor quando compilado com cc.
2.6.6.10 Notas SCO Unixware Version 7.0
Voe deve usar uma vers˜ao de MySQL pelo menos t˜ao recente quando a Vers˜ao 3.22.13
porque esta vers˜ao corrige alguns problemas de portabilidade sob o Unixware.
os temos compilado o MySQL com o seguinte comando configure no UnixWare Vers˜ao
7.0.1:
CC=cc CXX=CC ./configure --prefix=/usr/local/mysql
Se vocˆe deseja usar o gcc, dever´a ser usado o gcc 2.95.2 ou mais novo.
2.6.7 Notas OS/2
O MySQL usa poucos arquivos aberto. Por isto, vocˆe deve adicionar uma linha parecida
com a abaixo em seu arquivo ‘CONFIG.SYS’:
150 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SET EMXOPT=-c -n -h1024
Se vocˆe n˜ao fizer isto, provavelmente vai ter o seguinte erro:
File ’xxxx’ not found (Errcode: 24)
Quando usar o MysQL com OS/2 Warp 3, o FixPack 29 ou superior ´e necess´ario. Com OS/2
Warp 4, FixPack 4 ou acima ´e necess´ario. Isto ´e uma exigˆencia da biblioteca Pthreads. O
MySQL deve estar instalado em uma parti¸ao que suporta nomes longos de arquivos como
no HPFS, FAT32, etc.
O script ‘INSTALL.CMD’ deve ser executado pelo pr´oprio ‘CMD.EXE’ do OS/2 e opde n˜ao
funcionar com shells substitutas como o ‘4OS2.EXE’.
O script ‘scripts/mysql-install-db’ foi renomeado. Agora ele ´e chamado ‘install.cmd
e ´e um script REXX, que ir´a atualizar as configura¸oes padr˜oes de seguran¸ca do MySQL e
criar os ´
icones na WorkPlace Shell para o MySQL.
Suporte a m´odulos dinˆamicos ´e compilado mas n˜ao totalmente testado. odulos dinˆamicos
devem ser compilados usando a biblioteca run-time Pthreads.
gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
-o example udf_example.cc -L../lib -lmysqlclient udf_example.def
mv example.dll example.udf
Nota: Devido a limita¸oes no OS/2, o nome do m´odulo UDF n˜ao deve esceder 8 caracteres.
odulos s˜ao armazenados no diret´orio ‘/mysql2/udf’; o script safe-mysqld.cmd ir´a colo-
car este diret´orio na vari´avel de ambiente BEGINLIBPATH. Quando usando m´odulos UDF,
extens˜oes espec´
ificas s˜ao ignoradas — consuidera-se que seja ‘.udf’. Por exemplo, no Unix,
o m´odulo compartilhado deve ser nomeado ‘example.so’ e vocˆe deve carregar uma fun¸ao
dele desta forma:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";
No OS/2, o m´odulo deve ter o nome de ‘example.udf’, mas vocˆe n˜ao deve especificar a
extens˜ao do m´odulo:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
2.6.8 Notas BeOS
Realmente temos interesse que o MySQL funcione no BeOS, mas infelizmente n˜ao temos
nimgu´em que saiba BeOS ou tenha tempo para fazer uma vers˜ao.
os estamos interessados em encontrar algu´em que fa¸ca uma vers˜ao, e iremos ajudar com
qualquer quest˜ao t´ecnica que possa ter durante o desenvolvimento.
os j´a falamos com alguns desenvolvedores BeOS que disseram que o MySQL est´a 80%
portado para o BeOS, mas n´os n˜ao sabemos qual a situa¸ao no momento.
2.6.9 Notas Novell Netware
Estamos realmente interessados em deixar o MySQL funcionando no NetWARE, mas infe-
lizmente n˜ao temos ningu´ema que saiba Netware ou tenha tempo para fazer uma vers˜ao.
os estamos interessados em encontrar algu´em que fa¸ca a vers˜ao, e iremos ajud´a-lo com
qualquer quest˜ao t´ecnica que possa ter durante o desenvolvimento.
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 151
3 Introdu¸ao ao MySQL: Um Tutorial MysQL
Este cap´
itulo fornece um tutorial de introdu¸ao ao MySQL demonstrando como usar o
programa cliente mysql para criar e usar um banco de dados simples. mysql (algumas vezes
apresentado como o “terminal monitor” ou apenas “monitor”) ´e um programa interativo que
lhe permite conectar a um servidor MySQL, executar consultas e visualizar os resultados.
mysql pode tamb´em ser executado em modo batch: voe coloca suas consultas em um
arquivo, depois diz ao mysql para executar o conte´udo do arquivo. Cobrimos aqui ambas
as formas de utilizar o mysql.
Para ver uma lista de op¸oes conhecidas pelo mysql, chame-o com a op¸ao --help:
shell> mysql --help
Este cap´
itulo presume que o mysql est´a instalado na sua m´aquina e que um servidor MySQL
est´a dispon´
ivel para quem puder conectar. Se isto n˜ao for verdade, contate seu admin-
istrador MySQL. (Se voe ´e o administrador, vocˆe precisar´a consultar outras se¸oes deste
manual.)
Este cap´
itulo descreve todo o processo de configura¸ao e uso de um banco de dados. Se
vocˆe estiver interessado em apenas acessar um banco de dados j´a existente, podera pular
as se¸oes que descrevem como criar o banco de dados e suas respectivas tabelas.
Como este cap´
itulo ´e um tutorial, arios detalhes s˜ao necessariamente deixados de fora.
Consulte as se¸oes relevantes do manual para mais informa¸oes sobre os t´opicos cobertos
aqui.
3.1 Conectando e desconectando do servidor
Para conectar ao servidor, normalmente voe precisar´a fornecer um nome de usu´ario quando
omysql for chamado e, na maioria dos casos, uma senha. Se o servidor executa em
uma m´aquina diferente de onde vocˆe esa, vocˆe tamb´em precisar´a especificar um nome
de m´aquina. Contate seu administrador para saber quais parˆametros de conex˜ao vocˆe deve
usar para conectar (isto ´e, qual m´aquina, usu´ario e senha usar). Uma vez que voe saiba
quais os parˆametros corretos, vocˆe deve estar pronto para conectar da seguinte forma:
shell> mysql -h servidor -u usuario -p
Enter password: ********
Os asteriscos (********) representam sua senha; digite-a quando o mysql mostrar o prompt
Enter password:.
Se isto funcionar, vocˆe deve ver algumas informa¸oes iniciais seguidas de um prompt mysql>
shell> mysql -h servidor -u usuario -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 459 to server version: 3.22.20a-log
Type ’help’ for help.
mysql>
O prompt lhe diz que o mysql est´a pronto para que voe digite os comandos.
152 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Algumas instala¸oes MySQL permitem aos usu´arios de se conectarem como usu´arios
anˆonimos ao servidor executando na m´aquina local. Se isto ´e o caso na sua m´aquina, vocˆe
deve conseguir conectar ao servidor chamando o mysql sem qualquer op¸ao:
shell> mysql
Depois de vocˆe conectar com sucesso, vocˆe pode disconectar a qualquer hora digitando QUIT
no prompt mysql>:
mysql> QUIT
Bye
Voe tamb´em pode desconectar pressionando Control-D.
A maioria dos exemplos nas se¸oes seguintes assumem que vocˆe j´a est´a conectado ao servidor.
Isto ´e indicado pelo prompt mysql>.
3.2 Fazendo Consultas
Tenha certeza que vocˆe est´a conectado ao servidor, como discutido na se¸ao anterior. Isto
feito, n˜ao ser´a selecionado nenhum banco de dados para trabalhar, mas n˜ao tem problemas.
Neste momento, ´e mais importante saber um pouco sobre como fazer consultas do que j´a
criar tabelas, carregar dados para elas, e recuperar dados delas. Esta se¸ao descreve os
princ´
ipios b´asicos da entrada de comandos, usando diversas consultas vocˆe pode tentar se
familiarizar com o funcionamento do mysql.
Aqui est´a um comando simples que solicita ao servidor seu n´umero de vers˜ao e a data atual.
Digite-o como visto abaixo seguindo o prompt mysql> e digite a tecla RETURN:
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| version() | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19 |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>
Esta consulta ilustra v´arias coisas sobre o mysql:
Um comando normalmente consiste de uma instru¸ao SQL seguida por um ponto e
v´
irgula. (Exsistem algumas exce¸oes onde um ponto e v´
irgula n˜ao ´e necess´ario. QUIT
mencionado anteriormente, ´e um deles. Saberemos de outros mais tarde.)
Quando vocˆe emite um comando, o mysql o envia para o servidor para execu¸ao e
mostra os resultados, depois imprime oturo mysql> para indicar que est´a pronto para
outro comando.
Omysql mostra a sa´
ida da consulta como uma tabela (linhas e colunas). A primeira
linha cont´em r´otulos para as colunas. As linhas seguintes s˜ao o resultado da consulta.
Normalmente, r´otulos de colunas s˜ao os nomes das colunas que vocˆe busca das tabelas
do banco de dados. Se vocˆe est´a recuperando o valor de uma express˜ao no lugar de
uma coluna de tabela (como no exemplo j´a visto), o mysql rotula a coluna usando a
pr´opria express˜ao.
Omysql mostra quantas linhas foram retornadas e quanto tempo a consulta levou
para executar, o que lhe d´a uma vaga id´eia da performance do servidor. Estes valores
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 153
ao impreciso porque eles representam tempo de rel´ogio (N˜ao tempo de CPU ou de
aquina), e porque eles s˜ao afetados pelos fatores como a carga do servidor e latˆencia
de rede. (Para resumir, a linha “rows in set” n˜ao ´e mostrada nos exemplos seguintes
deste cap´
itulo.)
Palavras Chave podem ser entradas em qualquer caso de letra. As seguintes consultas s˜ao
equivalentes:
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
Aqui est´a outra consulta. Ela demonstra que vocˆe pode usar o mysql como uma calculadora
simples:
mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+-------------+---------+
| 0.707107 | 25 |
+-------------+---------+
Os comandos mostrados at´e agora tˆem sido instru¸oes relativamente pequenas, de uma
linha. Voe pode tamb´em entrar com m´ultiplas instru¸oes em uma ´unica linha. Basta
finalizar cada uma com um ponto e v´
irgula:
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| version() |
+--------------+
| 3.22.20a-log |
+--------------+
+---------------------+
| NOW() |
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+
Um comando n˜ao necessita estar todo em uma ´unica linha, ent˜ao comandos extensos que
necessitam de v´arias linhas n˜ao s˜ao um problema. O mysql determina onde sua instru¸ao
termina atrav´es do ponto e v´
irgula terminador, e n˜ao pelo final da linha de entrada. (Em
outras palavras, o myqsl aceita entradas de livre formato: Ele coleta linhas de entrada mas
ao as executa at´e chegar o ponto e v´
irgula.)
Aqui est´a uma instru¸ao simples usando m´ultiplas linhas:
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+--------------------+--------------+
| USER() | CURRENT_DATE |
+--------------------+--------------+
| joesmith@localhost | 1999-03-18 |
154 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
+--------------------+--------------+
Neste exemplo, note como o prompt altera de mysql> para -> depois de vocˆe entrar a
primeira linha de uma consulta com m´ultiplas linhas. Isto ´e como o mysql indica que ainda
ao achou uma instru¸ao completa e est´a esperando pelo resto. O prompt ´e seu amigo,
porque ele fornece um retorno valioso. Se vocˆe usa este retorno, vocˆe sempre estar´a ciente
do que o mysql est´a esperando.
Se vocˆe decidir que n˜ao deseja executar um comando que est´a no meio do processo de
entrada, cancele-o digitando \c:
mysql> SELECT
-> USER()
-> \c
mysql>
Note o prompt aqui tamb´em. Ele troca para o mysql> depois de vocˆe digitar \c, fornecendo
retorno para indicar que o mysql est´a pronto para um novo comando.
A seguinte tabela mostra cada dos prompts que vocˆe pode ver e resume o que ele significa
sobre o estado em que o mysql se encontra:
Prompt Significado
mysql> Pronto para novo comando.
-> Esperando pela pr´oxima linha de comando com m´ultiplas linhas.
’> Esperando pela pr´oxima linha, coletando uma string que comece com uma aspas
simples (‘’).
"> Esperando pela pr´oxima linha, colentando uma string que comece com aspas
duplas (‘"’).
´
E muito comum instru¸oes multi-linhas ocorrem por acidente quando vocˆe pretende publicar
um comando em uma ´unica linha, mas esquece o ponto e v´
irgula terminador. Neste caso,o
mysql espera por mais entrada:
mysql> SELECT USER()
->
Se isto ocorrer com vocˆe (acha que entrou uma instru¸ao mas a ´unica resposta ´e um prompt
->), o mais proavel ´e que o mysql est´a esperando pelo ponto e v´
irgula. Se vocˆe n˜ao
perceber o que o prompt est´a lhe dizendo, vocˆe pode parar por um tempo antes de entender
o que precisa fazer. Entre com um ponto e v´
irgula para completar a instru¸ao, e o mysql
ir´a execut´a-la:
mysql> SELECT USER()
-> ;
+--------------------+
| USER() |
+--------------------+
| joesmith@localhost |
+--------------------+
O prompt ’> e"> ocorrem durante a coleta de strings. No MySQL, vocˆe pode escrever
strings utilizando os caracteres ‘’ ou ‘"’ (por exemplo, ’hello’ ou "goodbye"), e o mysql
permite a entrada de strings que consomem m´ultiplas linhas. Quando vocˆe ver um prompt
’> ou ">, significa que vocˆe digitou uma linha contendo uma string que come¸ca com um
caracter de aspas ‘’ ou ‘"’ mas ainda n˜ao entrou com a aspas que termina a string. Isto
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 155
´e bom se vocˆe realmente est´a entrando com uma string com m´ultiplas linhas, mas qual ´e
a probalidade disto acontecer ? ao muita. Geralmente, os prompts ’> e"> indicam que
vocˆe, por algum descuido, esqueceu algum caracter de aspas. Por exemplo:
mysql> SELECT * FROM minha_tabela WHERE nome = "Smith AND idade < 30;
">
Se vocˆe entrar esta senten¸ca SELECT, apertar ENTER e esperar pelo resultado, nada ir´a
acontecer. Em vez de se perguntar o porquˆe desta query demorar tanto tempo, perceba a
pista fornecida pelo prompt ">. Ele lhe diz que o mysql espera pelo resto de uma string
ao terminada. (Voe ve o erro na declara¸ao? Falta a segunda aspas na string "Smith.)
O que fazer neste ponto ? A coisa mais simples ´e cancelar o comando. Entretanto, vocˆe
ao pode simplesmente digitar \c neste caso, porque o mysql o intrerpreta como parte da
string que est´a coletando! Digite o caracter de aspas para fechar (enao o mysql sabe que
vocˆe fechou a string), enao digite \c:
mysql> SELECT * FROM minha_tabela WHERE nome = "Smith AND idade < 30;
"> "\c
mysql>
O prompt volta para mysql>, indicando que o mysql est´a pronto para um novo comando.
´
E importante saber o que os prompts ’> e o "> significam, porque se vocˆe entrar sem
querer com uma string sem termina¸ao, quaisquer linhas seguintes que forem digitadas
ser˜ao ignoradas pelo mysql — incluindo uma linha contendo QUIT! Isto pode ser um pouco
confuso, especialmente se voe n˜ao sabe que vocˆe precisa fornecer as aspas finais antes poder
cancelar o comando atual.
3.3 Cria¸ao e Utiliza¸ao de um Banco de Dados
Agora que vocˆe j´a sabe como entrar com os comandos, ´e hora de acessar um banco de dados.
Suponha que vocˆe tenha diversos animais de estima¸ao em sua casa (menagerie) e vocˆe
gostaria de ter o registro de v´arios tipos de informa¸oes sobre eles. Vocˆe pode fazer isto
criando tabelas para armazenar seus dados e carreg´a-los com a informa¸ao desejada. Depois
vocˆe pode responder diferentes tipos de quest˜oes sobre seus animais recuperando dados das
tabelas. Esta se¸ao mostrar´a como:
Criar um banco de dados
Criar uma tabela
Carregar dados na tabela
Recuperar dados de uma tabela de v´arias maneiras
Usar m´ultiplas tabelas
O banco de dados menagerie ser´a simples (deliberadamente), mas n˜ao ´e dif´
icil pensar em
situa¸oes na vida real em que um tipo similar de banco de dados pode ser usado. Por
exemplo, um banco de dados deste tipo pode ser usado por um fazendeiro para gerenciar
seu estoque de animais, ou por um veterin´ario para gerenciar registros de seus pacientes.
Uma distribui¸ao do menagerie contendo algumas das consultas e dados de exemplos usados
nas se¸oes seguintes podem ser obtidas do site Web do MySQL. Est˜ao dispon´
iveis tanto em
compressed formato tar como em formato Zip .
Utilize a instru¸ao SHOW para saber quais bancos de dados existem atualmente no servidor:
156 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
A lista de bancos de dados provavelmente ser´a diferente na sua m´aquina, mas os bancos de
dados mysql etest provavelmente estar˜ao entre eles. O banco de dados mysql ´e necess´ario
porque ele descreve privil´egios de acessos de usu´arios. O banco de dados test ´e geralamente
fornecido como um espa¸co para que os usu´arios possam fazer testes.
Se o banco de dados test existir, tente acess´a-lo:
mysql> USE test
Database changed
Perceba que o USE, como o QUIT, ao necessitam de um ponto e v´
irgula. (Vocˆe pode
terminar tais declara¸oes com uma ponto e v´
irgula se gostar; isto n˜ao importa) A instru¸ao
USE ´e especial em outra maneira, tamb´em: Ela deve ser usada em uma ´unica linha.
Voe opde usar o banco de dados test (Se vocˆe tiver acesso a ele) para os exemplos que
seguem mas qualquer coisa que vocˆe criar neste banco de dados pode ser removido por
qualquer um com acesso a ele. Por esta raz˜ao, vocˆe provavelmente deve pedir permiss˜ao
ao seu administrador MySQL para usar um banco de dados pr´oprio. Suponha que vocˆe o
chame de menagerie. O administrador precisar executar um comando como este:
mysql> GRANT ALL ON menagerie.* TO seu_usu´ario_mysql;
onde seu_usu´ario_mysql ´e o nome do usu´ario MySQL atribuido a vocˆe.
3.3.1 Criando e Selecionando um Banco de Dados
Se o administrador criar seu banco de dados quando configurar as suas permiss˜oes, vocˆe
pode come¸car a us´a-lo. Sen˜ao, vocˆe mesmo precisa cri´a-lo:
mysql> CREATE DATABASE menagerie;
No Unix, nomes de bancos de dados s˜ao caso sensitivo (ao contr´ario das palavras chave
SQL), portanto vocˆe deve sempre fazer referˆencia ao seu banco de dados como menagerie
e n˜ao Menagerie,MENAGERIE ou outra varia¸ao. Isto tamb´em ´e verdade para nomes de
tabelas. (No Windows, esta restri¸ao n˜ao se aplica, entiretanto vocˆe deve referenciar os
bancos de dados e tabelas usando o mesmo caso em toda a parte da consulta.)
Criar um bancos de dados n˜ao o seleciona para o uso; vocˆe deve fazer isso de forma expl´
icita.
Para fazer o menagerie o banco de dados atual, use o comando:
mysql> USE menagerie
Database changed
Seu banco de dados necessita ser criado somente uma ´unica vez, mas vocˆe deve selecion´a-lo
para o uso cada vez que vocˆe iniciar uma se¸ao mysql. Vocˆe pode fazer isso usando a
instru¸ao USE como visto acima. Uma forma alternativa ´e selecionar o banco de dados na
linha de comando quando vocˆe chamar o mysql. Apenas especifique seu nome depois de
qualquer parˆametro de conex˜ao que vocˆe pode precisar fornecer. Por exemplo:
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 157
shell> mysql -h servidor -u usuario -p menagerie
Enter password: ********
Perceba que menagerie ao ´e sua senha no comando mostrado. Se vocˆe precisar passar sua
senha na linha de comando depois da op¸ao -p, vocˆe deve fazˆe-lo sem usar espa¸cos (por
exemplo, -pminhasenha e n˜ao como em -p minhasenha). Entretando, colocando sua senha
na linha de comando n˜ao ´e recomendado, porque isto exp˜oe sua senha permitindo que outro
usu´ario utilize a sua m´aquina.
3.3.2 Criando uma Tabela
Criar o banco de dados ´e a parte f´acil, mas neste ponto ele est´a vazio, como o SHOW TABLES
mostrar´a:
mysql> SHOW TABLES;
Empty set (0.00 sec)
A parte mais dif´
icil ´e decidir qual a estrutura que seu banco de dados deve ter: quais tabelas
vocˆe precisar´a e que colunas estar˜ao em cada uma delas.
Voe ir´a precisar de uma tabela para guardar um registro para cada um de seus animais
de estima¸ao. Esta tabela pode ser chamada pet, e ela deve conter, pelo menos, o nome
de cada animal. Como o nome por si s´o n˜ao ´e muito interessante, a tabela dever´a conter
outras informa¸oes. Por exemplo, se mais de uma pessoa na sua fam´
ilia tamb´em tem
animais, vocˆe pode desejar listar cada dono. Voe pode tamb´em desejargravar algumas
informa¸oes descritivas b´asicas como esp´ecie e sexo.
Que tal a idade? Pode ser do interesse, mas n˜ao ´e uma boa coisa para se armazenar em um
banco de dados. A idade muda `a medida em que o tempo passa, o que significa que vocˆe
sempre ter´a de atualizar seus registros. Em vez disso, ´e melhor armazenar um valor fixo
como a data de nascimento. Ent˜ao, sempre que vocˆe precisar da idade, basta vocˆe calcul´a-la
como a diferen¸ca entre a data atual e a data de anivers´ario. O MySQL fornece fun¸oes para
fazer aritm´etica de datas, ent˜ao isto n˜ao ´e dif´
icil. Armazenando datas de anivers´ario no
lugar da idade tamb´em oferece outras vantagens:
Voe pode usar o banco de dados para tarefas como gerar lembretes para anivers´arios
que est˜ao chegando. (Se vocˆe pensa que este tipo de query ´e algo bobo, perceba que
´e a mesma quest˜ao que vocˆe perguntar no contexto de um banco de dados comercial
para identificar clientes para quais vocˆe precisar´a enviar cart˜ao de anivers´ario, para um
toque pessoal assistido pelo computador.)
Voe pode calcular a idade em rela¸ao a outras datas diferente da data atual. Por
exemplo, se vocˆe armazenar a data da morte no banco de dados, vocˆe poder´a facilmente
calcular qual a idade que o bicho tinha quando morreu.
Voe provavelmente pode pensar em outros tipos de informa¸oes que poder˜ao ser ´uteis
na tabela pet, mas as identificadas at´e o momento s˜ao suficientes por agora: nome(name),
dono(owner), esp´ecie(species), sexo(sex), data de nascimento(birth) e data da morte(death).
Utilize a sente¸ca CREATE TABLE para especificar o layout de sua tabela:
mysql> CREATE TABLE pet (nome VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
VARCHAR ´e uma boa escolha para os campos name,owner, e species porque os valores da
coluna s˜ao de tamanho vari´avel. Os tamanhos destas colunas n˜ao precisam necess´ariamente
158 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
de ser os mesmos e n˜ao precisam ser 20. Vocˆe pode escolher qualquer tamanho de 1a255,
o que vocˆe achar melhor. (Se vocˆe n˜ao fizer uma boa escolha e depois precisar de um campo
maior, o MySQL fornece o comando ALTER TABLE.)
O sexo dos animais podem ser representados em v´arias formas, por exemplo, "m" e"f" ou
mesmo "macho" e"f^emea".´
E mais simples usar os caracteres "m" e"f".
O uso do tipo de dados DATE para as colunas birth edeath ao obviamente a melhor
escolha.
Agora que vocˆe criou uma tabela, a instru¸ao SHOW TABLES deve produzir alguma sa´
ida:
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet |
+---------------------+
Para verificar se sua tabela foi criada da forma que vocˆe esperava, utilize a instru¸ao
DESCRIBE:
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
Voe pode usar DESCRIBE a qualquer hora, por exemplo, se vocˆe esquecer os nomes das
colunas na sua tabela ou de que tipos elas s˜ao.
3.3.3 Carregando dados em uma tabela
Depois de criar sua tabela, vocˆe precisar´a pova-la. As instru¸oes LOAD DATA eINSERT ao
´uteis para isto.
Suponha que seu registro de animais possa ser descrito como ´e abaixo: (Observe que o
MySQL espera datas no formato AAAA-MM-DD; isto pode ser diferente do que vocˆe est´a
acostumado.)
name owner species sex birth death
Fluffy Harold cat f 1993-02-04
Claws Gwen cat m 1994-03-17
Buffy Harold dog f 1989-05-13
Fang Benny dog m 1990-08-27
Bowser Diane dog m 1998-08-31 1995-07-29
Chirpy Gwen bird f 1998-09-11
Whistler Gwen bird 1997-12-09
Slim Benny snake m 1996-04-29
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 159
Como vocˆe est´a come¸cando com uma tabela vazia, uma forma simples de pova-la ´e criar
um arquivo texto contendo uma linha para cada um de seus animais, e depois carregar o
conte´udo do arquivo para a tabela com uma simples instru¸ao.
Voe pode criar um arquivo texto ‘pet.txt’ contendo um registro por linha, com valores
separado por tabula¸oes e na mesma ordem em que as colunas foram listadas na instru¸ao
CREATE TABLE. Para valores em falta (como sexo desconhecido ou data da morte para
animais que ainda est˜ao vivos), vocˆe pode usar valores NULL. Para represena-lo em seu
arquivo texto, use \N. Por exemplo, o registro para Whistler the bird podem parecer com
isto (onde o espa¸co em branco entre os valores ´e um simples caractere de tabula¸ao):
Whistler Gwen bird \N 1997-12-09 \N
Para carregar o arquivo texto ‘pet.txt’ na tabela pet, use este comando:
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
Voe pode especificar o valor do separador de colunas e o marcador de final de linha explici-
tamente na instru¸ao LOAD DATA se vocˆe desejar. Mas os valores omitidos s˜ao suficientes
para a instru¸ao ler o arquivo ‘pet.txt’ corretamente.
Quando vocˆe desejar adicionar novos registros um a um, a instru¸ao INSERT ´e usada. Na
sua forma mais simples, vocˆe fornece valores para cada coluna, na ordem em que as colunas
foram listadas na instru¸ao CREATE TABLE. Suponha que Diane tenha um novo hamster
chamado Puffball. Vocˆe pode adicionar um registro utilizando uma instru¸ao INSERT desta
forma:
mysql> INSERT INTO pet
-> VALUES (’Puffball’,’Diane’,’hamster’,’f’,’1999-03-30’,NULL);
Perceba que os valores de string e datas s˜ao especificados aqui como strings com aspas.
Com o INSERT vocˆe tamb´em pode inserir NULL diretamente para representar um valor em
falta. ao pode ser usado \N como vocˆe fez com LOAD DATA.
A partir deste exemplo, vocˆe dever´a perceber que existem v´arias outras formas envolvidas
para carregar seus registros inicialmente utilizando diversas instru¸oes INSERT do que uma
simples instru¸ao LOAD DATA.
3.3.4 Recuperando Informa¸oes de uma Tabela
A instru¸ao SELECT ´e usada para recuperar informa¸oes de uma tabela. A forma geral da
instru¸ao ´e:
SELECT o_que_mostrar
FROM de_qual_tabela
WHERE condi¸c~oes_para_satisfazer
o_que_mostrar indica o que vocˆe deseja ver. Isto pode ser uma lista de colunas ou *para
indicar “todas colunas.” de_qual_tabela indica a tabela de onde vocˆe deseja recuperar
os dados. A cl´ausula WHERE ´e opcional. Se estiver presente, condi¸c~oes_para_satisfazer
especificam as condi¸oes que os registros devem satisfazer para fazer parte do resultado.
3.3.4.1 Selecionando Todos os Dados
A forma mais simples do SELECT recuperar tudo de uma tabela:
160 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1998-08-31 | 1995-07-29 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+--------+---------+------+------------+------------+
Esta forma do SELECT ´e ´util se vocˆe deseja ver sua tabela inteira, como agora, depois de vocˆe
acabar de carreg´a-la com os dados iniciais. Como podemos ver, a sa´
ida mostrada revela um
erro no seu arquivo de dados: Bowser nasceu depois de morto ! Consultando seus pap´eis
originais de pedigree, descobriu que o ano correto do nascimento ´e 1989, n˜ao 1998.
Existem pelo menos duas formas de corrigir isto:
Edite o arquivo ‘pet.txt’ para corrigir o erro, depois limpe a tabela e recarregue-o
usando DELETE eLOAD DATA:
mysql> SET AUTOCOMMIT=1; # Usado para a recria¸c~ao da tabela
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
Entretanto, se vocˆe fizer isto, vocˆe tamb´em deve refazer a entrada para Puffball.
Corrigir somente o registro errado com uma instru¸ao UPDATE:
mysql> UPDATE pet SET birth = "1989-08-31" WHERE name = "Bowser";
Como foi mostrado acima, ´e f´acil recuperar uma tabela inteira. Mas normalmente voe n˜ao
vai quer fazer isto, particularmente quando a tabela ficar grande. Normalmente vocˆe estar´a
mais interessado em ter a resposta de uma quest˜ao em particular, no qual vocˆe especifica
detalhes da informa¸ao que deseja. Vamos ver algumas consultas de sele¸ao nos termos das
quest˜oes sobre seus animais.
3.3.4.2 Selecionando Registros Espec´
ificos
Voe pode selecionar apenas registros espec´
ificos da sua tabela. Por exemplo, se voe deseja
verificar a altera¸ao que fez na data de nascimento do Bowser, selecione o registro desta
forma:
mysql> SELECT * FROM pet WHERE name = "Bowser";
+--------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
A sa´
ida confirma que o ano foi gravado corretamente agora como 1989 e n˜ao 1998.
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 161
Compara¸oes de strings normalmente s˜ao caso insensitivo, ent˜ao vocˆe pode especificar o
nome como "bowser","BOWSER", etc. O resultado da pesquisa ser´a o mesmo.
Voe pode especificar condi¸oes em qualquer coluna, n˜ao apenas no name. Por exemplo,
se vocˆe deseja saber quais foram os animais que nasceram depois de 1998, teste o campo
birth:
mysql> SELECT * FROM pet WHERE birth >= "1998-1-1";
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+-------+---------+------+------------+-------+
Voe pode combinar condi¸oes, por exemplo, para encontrar cadelas (dog/f):
mysql> SELECT * FROM pet WHERE species = "dog" AND sex = "f";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
A consulta anterior utiliza o operador l´ogico AND (e). Existe tamb´em um operador OR (ou):
mysql> SELECT * FROM pet WHERE species = "snake" OR species = "bird";
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
+----------+-------+---------+------+------------+-------+
AND eOR podem ser misturados. Se vocˆe fizer isto, ´e uma ´otima id´eia usar parˆenteses para
indicar quais condi¸oes devem ser agrupadas:
mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m")
-> OR (species = "dog" AND sex = "f");
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
3.3.4.3 Selecionando Colunas Espec´
ificas
Se vocˆe n˜ao desejar ver todo o registro de sua tabela, especifique as colunas em que vocˆe
estiver interessado, separado por v´
irgulas. Por exemplo, se vocˆe deseja saber quando seus
animais nasceram, selecione as colunas name ebirth:
mysql> SELECT name, birth FROM pet;
+----------+------------+
| name | birth |
162 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
+----------+------------+
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Buffy | 1989-05-13 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
Para saber quem s˜ao os donos dos animais, use esta consulta:
mysql> SELECT owner FROM pet;
+--------+
| owner |
+--------+
| Harold |
| Gwen |
| Harold |
| Benny |
| Diane |
| Gwen |
| Gwen |
| Benny |
| Diane |
+--------+
Entretanto, perceba que a query simplesmente retornou o campo owner de cada registro, e
alguns deles apareceram mais de uma vez. Para minimizar a sa´
ida, recupere cada registro
apenas uma vez, adicionando a palavra chave DISTINCT:
mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner |
+--------+
| Benny |
| Diane |
| Gwen |
| Harold |
+--------+
Voe pode usar uma cl´ausula WHERE para combinar sele¸ao de registros com sele¸ao de
colunas. Por exemplo, para obter a data de nascimento somente dos gatos e cachorros,
utilize esta query:
mysql> SELECT name, species, birth FROM pet
-> WHERE species = "dog" OR species = "cat";
+--------+---------+------------+
| name | species | birth |
+--------+---------+------------+
| Fluffy | cat | 1993-02-04 |
| Claws | cat | 1994-03-17 |
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 163
| Buffy | dog | 1989-05-13 |
| Fang | dog | 1990-08-27 |
| Bowser | dog | 1989-08-31 |
+--------+---------+------------+
3.3.4.4 Ordenando Registros
Voe deve ter percebido nos exemplos anteriores que os registros retornados n˜ao s˜ao mostra-
dos de forma ordenada. Entretanto, normalmente ´e mais f´acil examinar a sa´
ida da consulta
quando os registros s˜ao ordenados com algum sentido. Para ordenar o resultado, utilize
uma cl´ausula ORDER BY.
Aqui est´a o dia de nascimento dos animais, ordenado por data:
mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name | birth |
+----------+------------+
| Buffy | 1989-05-13 |
| Bowser | 1989-08-31 |
| Fang | 1990-08-27 |
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Slim | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
Para ordena¸ao na ordem reversa, adicione a palavra chave DESC (descendente) ao nome da
coluna que deve ser ordenada:
mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name | birth |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Claws | 1994-03-17 |
| Fluffy | 1993-02-04 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Buffy | 1989-05-13 |
+----------+------------+
Voe pode ordenar por m´ultiplas colunas. Por exemplo, para ordenar o tipo de animal,
depois por dia de nascimento dentro do tipo de animal com os mais novos primeiro, utilize
a seguinte consulta:
mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;
+----------+---------+------------+
164 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| name | species | birth |
+----------+---------+------------+
| Chirpy | bird | 1998-09-11 |
| Whistler | bird | 1997-12-09 |
| Claws | cat | 1994-03-17 |
| Fluffy | cat | 1993-02-04 |
| Fang | dog | 1990-08-27 |
| Bowser | dog | 1989-08-31 |
| Buffy | dog | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim | snake | 1996-04-29 |
+----------+---------+------------+
Perceba que a palavra chave DESC aplica somente para o nome da coluna precedente (birth);
valores na coluna species continuam ordenados na ordem ascendente.
3.3.4.5 alculo de Datas
O MySQL fornece v´arias fun¸oes que vocˆe pode usar para realizar c´alculos em datas, por
exemplo, para calcular idades ou extrair partes de datas.
Para determinar quantos anos cada um do seus animais tem, compute a diferen¸ca do ano
da data atual e a data de nascimento (birth), depois subtraia se a o dia/mˆes da data atual
for anterior ao dia/mˆes da data de nascimento. A consulta seguinte, mostra, para cada
animal, a data de nascimento, a data atual e a idade em anos.
mysql> SELECT name, birth, CURRENT_DATE,
-> (YEAR(CURRENT_DATE)-YEAR(birth))
-> - (RIGHT(CURRENT_DATE,5)<RIGHT(birth,5))
-> AS age
-> FROM pet;
+----------+------------+--------------+------+
| name | birth | CURRENT_DATE | age |
+----------+------------+--------------+------+
| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
| Claws | 1994-03-17 | 2001-08-29 | 7 |
| Buffy | 1989-05-13 | 2001-08-29 | 12 |
| Fang | 1990-08-27 | 2001-08-29 | 11 |
| Bowser | 1989-08-31 | 2001-08-29 | 11 |
| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
| Whistler | 1997-12-09 | 2001-08-29 | 3 |
| Slim | 1996-04-29 | 2001-08-29 | 5 |
| Puffball | 1999-03-30 | 2001-08-29 | 2 |
+----------+------------+--------------+------+
Aqui, YEAR() separa a parte do ano de uma data e RIGHT() separa os cinco caracteres
mais a direita que representam a parte da data MM-DD. A parte da express˜ao que compara
os valores MM-DD resulta em 1 ou 0, o qual ajusta a diferen¸ca do ano um ano abaixo se
CURRENT_DATE ocorrer mais cedo, no ano, que birth. A express˜ao completa ´e um tanto
deselegante, enao um apelido (age) ´e usado para obter uma sa´
ida mais significativa.
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 165
A consulta funciona, mas o resultado pode ser mais compreens´
ivel se os registros forem
apresentados em alguma ordem. Isto pode ser feito adicionando uma cl´ausula ORDER BY
name para ordenar a sa´
ida pelo nome:
mysql> SELECT name, birth, CURRENT_DATE,
-> (YEAR(CURRENT_DATE)-YEAR(birth))
-> - (RIGHT(CURRENT_DATE,5)<RIGHT(birth,5))
-> AS age
-> FROM pet ORDER BY name;
+----------+------------+--------------+------+
| name | birth | CURRENT_DATE | age |
+----------+------------+--------------+------+
| Bowser | 1989-08-31 | 2001-08-29 | 11 |
| Buffy | 1989-05-13 | 2001-08-29 | 12 |
| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
| Claws | 1994-03-17 | 2001-08-29 | 7 |
| Fang | 1990-08-27 | 2001-08-29 | 11 |
| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
| Puffball | 1999-03-30 | 2001-08-29 | 2 |
| Slim | 1996-04-29 | 2001-08-29 | 5 |
| Whistler | 1997-12-09 | 2001-08-29 | 3 |
+----------+------------+--------------+------+
Para ordenar a sa´
ida por age em vez de name, ´e s´o utilizar uma cl´ausua ORDER BY diferente:
mysql> SELECT name, birth, CURRENT_DATE,
-> (YEAR(CURRENT_DATE)-YEAR(birth))
-> - (RIGHT(CURRENT_DATE,5)<RIGHT(birth,5))
-> AS age
-> FROM pet ORDER BY age;
+----------+------------+--------------+------+
| name | birth | CURRENT_DATE | age |
+----------+------------+--------------+------+
| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
| Puffball | 1999-03-30 | 2001-08-29 | 2 |
| Whistler | 1997-12-09 | 2001-08-29 | 3 |
| Slim | 1996-04-29 | 2001-08-29 | 5 |
| Claws | 1994-03-17 | 2001-08-29 | 7 |
| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
| Fang | 1990-08-27 | 2001-08-29 | 11 |
| Bowser | 1989-08-31 | 2001-08-29 | 11 |
| Buffy | 1989-05-13 | 2001-08-29 | 12 |
+----------+------------+--------------+------+
Uma consulta similar pode ser usada para determinar a idade na morte para animais que
morreram. Para determinar quais s˜ao os animais, confira se o valor de death ao ´e NULL.
Depois para estes com valores n˜ao-NULL, compute a diferen¸ca entre os valores dos campos
death ebirth:
mysql> SELECT name, birth, death,
-> (YEAR(death)-YEAR(birth)) - (RIGHT(death,5)<RIGHT(birth,5))
-> AS age
-> FROM pet WHERE death IS NOT NULL ORDER BY age;
166 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
+--------+------------+------------+------+
| name | birth | death | age |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 | 5 |
+--------+------------+------------+------+
A query usa death IS NOT NULL em vez de death != NULL porque NULL ´e um valor especial.
Isto ser´a explicado depois. See hundefinedi[Working with NULL], page hundefinedi.
E se vocˆe desejar saber quais animais fazem anivers´ario no pr´oximo mˆes? Para este tipo
de c´alculo, ano e dia s˜ao irrelevantes; vocˆe simplesmente deseja extrair a parte do mˆes da
coluna birth. O MySQL fornece diversas fun¸oes para extrair partes da data, como em
YEAR(),MONTH() eDAYOFMONTH().MONTH ´e a fun¸ao apropriada aqui. Para ver como ela
funciona, execute uma consulta simples que mostre o valor de birth eMONTH(birth):
mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name | birth | MONTH(birth) |
+----------+------------+--------------+
| Fluffy | 1993-02-04 | 2 |
| Claws | 1994-03-17 | 3 |
| Buffy | 1989-05-13 | 5 |
| Fang | 1990-08-27 | 8 |
| Bowser | 1989-08-31 | 8 |
| Chirpy | 1998-09-11 | 9 |
| Whistler | 1997-12-09 | 12 |
| Slim | 1996-04-29 | 4 |
| Puffball | 1999-03-30 | 3 |
+----------+------------+--------------+
Encontrar animais com an´
ivers´ario no pr´oximo mˆes tamb´em ´e f´acil. Suponha que o mˆes
atual ´e abril. Enao o valor do mˆes ´e 4e vocˆe procura por animais nascidos em Maio (mˆes
5) assim:
mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name | birth |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
Existe uma pequena complica¸ao se o mˆes atual ´e Dezembro, ´e claro. Vocˆe n˜ao pode apenas
adicionar um para o n´umero do mˆes (12) e procurar por animais nascidos no mˆes 13, porque
ao existe tal mˆes. O certo seria procurar por animais nascidos em Janeiro (mˆes 1).
Voe pode tamb´em escrever uma consulta para que funcione sem importar qual ´e o mˆes
atual. Assim vocˆe n˜ao tˆem quee usar um n´umero de mˆes em particular na consulta. DATE_
ADD() permite adicionar um intervalo de tempo para uma data fornecida. Se vocˆe adicionar
um mˆes para o valor de NOW(), enao extrair a parte do mˆes com MONTH(), o resultado ´e o
mˆes no qual vocˆe deseja procurar por anivers´arios:
mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 167
Uma maneira diferente para realizar a mesma tarefa ´e adicionar 1para obter o mˆes seguinte
ao atual (depois de usar a fun¸ao m´odulo (MOD) para o valor do mˆes retornar 0se ele for
12):
mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MOD(MONTH(NOW()), 12) + 1;
Perceba que MONTH retorna um n´umero entre 1 e 12. E MOD(alguma_coisa,12) retorna um
n´umero entre 0 e 11. Ent˜ao a adi¸ao tem que ser feita depois do MOD(), sen˜ao ir´
iamos de
Novembro (11) para Janeiro (1).
3.3.4.6 Trabalhando com Valores Nulos (NULL)
O valor NULL pode ser supreendente at´e vocˆe us´a-lo. Conceitualmente, NULL significa valor
em falta ou valor desconhecido e ´e tratado de uma forma diferente de outros valores. Para
testar o valor NULL, vocˆe n˜ao pode usar os operadores de compara¸oes aritm´eticas como em
=,<,ou!=. Para demonstrar para vocˆe mesmo, tente executar a seguinte consulta:
mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
|1=NULL|1!=NULL|1<NULL|1>NULL|
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
Claramente vocˆe n˜ao obter´a resultados significativos destas compara¸oes. Utilize os oper-
adores IS NULL eIS NOT NULL no lugar:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
| 0 | 1 |
+-----------+---------------+
No MySQL, 0 ou NULL significa falso e o resto ´e verdadeiro. O valor verdadeiro por o padr˜ao
em uma opera¸ao booleana ´e 1.
Este tratamento especial de NULL ´e porque, na se¸ao anterior, foi necess´ario determinar
quais animais n˜ao estavam mais vivos usando death IS NOT NULL no lugar de death !=
NULL.
3.3.4.7 Combina¸ao de padr˜oes
O MySQL fornece combina¸ao de padr˜oes do SQL bem como na forma de combina¸ao
de padr˜oes baseado nas express˜oes regulares extendidas similares `aquelas usadas pelos
utilit´arios Unix como o vi,grep esed.
A combina¸ao de padr˜oes SQL lhe permite vocˆe usar _para coincidir qualquer caractere
simples e %para coincidir um n´umero arbitr´ario de caracteres (incluindo zero caracter).
No MySQL, padr˜oes SQL s˜ao caso insensitivo por padr˜ao. Alguns exemplos s˜ao vistos
abaixo. Perceba que vocˆe n˜ao usa =ou != quando usar padr˜oes SQL; use os operadores de
compara¸ao LIKE ou NOT LIKE neste caso.
Para encontrar nomes come¸cando com ‘b’:
168 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT * FROM pet WHERE name LIKE "b%";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
Para encontrar nomes com o final ‘fy’:
mysql> SELECT * FROM pet WHERE name LIKE "%fy";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Para encontrar nomes contendo um ‘w’:
mysql> SELECT * FROM pet WHERE name LIKE "%w%";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Para encontrar nomes contendo exatamente cinco caracteres, use o caracter ‘_’:
mysql> SELECT * FROM pet WHERE name LIKE "_____";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
O outro tipo de combina¸ao de padr˜oes fornecido pelo MySQL usa express˜oes regulares
extendidas. Quando vocˆe testa por uma combina¸ao para este tipo de padr˜ao, utilize os
operadores REGEXP eNOT REGEXP (ou RLIKE eNOT RLIKE, que s˜ao sinˆonimos).
Algumas caracter´
isticas das express˜oes regulares extendidas s˜ao:
.’ combina qualquer caractere ´unico
Uma classe de caracteres ‘[...]’ combina qualquer caractere que consta dentro dos
colchetes. Por exemplo, [abc]’ combina com ‘a’, ‘b’, ou ‘c’. Para nomear uma
sequˆencia de caracteres utilize um tra¸co. [a-z]’ combina com qualquer letra min´uscula
e ‘[0-9]’ combina com qualquer d´
igito.
*’ combina nenhuma ou mais instˆancias de sua precedˆencia. Por exemplo, ‘x*’ combina
com qualquer n´umero de caracteres ‘x’, ‘[0-9]*’ combina com qualquer n´umero de
d´
igitos e ‘.*’ combina com qualquer n´umero de qualquer coisa.
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 169
Express˜oes regulares caso sensitivo, mas vocˆe pode usar uma classe de caracteres para
combinar ma´
iusculas/min´usculas se vocˆe desejar. Por exemplo, ‘[aA]’ combina o ‘a
min´usculo ou mai´usculo e ‘[a-zA-Z]’ combina qualquer letra em ambos casos.
O padr˜ao combina se ele ocorre em algum lugar no valor sendo testado. (Padr˜oes SQL
combinam somente se eles combinarem com todo o valor.)
Para fazer com que um padr˜ao deva combinar com o come¸co ou o fim de um valor
sendo testado, utilize ‘^’ no come¸co ou ‘$’ no final do padr˜ao.
Para demonstrar como express˜oes regulares extendidas funcionam, as consultas com LIKE
mostradas acima foram reescritas abaixo usando REGEXP.
Para encontrar nomes come¸cando com ‘b’, utilize ‘^’ para combinar com o come¸co do nome:
mysql> SELECT * FROM pet WHERE name REGEXP "^b";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
Antes da vers˜ao 3.23.4 do MySQL, REGEXP era caso sensitivo, e a consulta anterior n˜ao iria
retornar nenhum registro. Para combinar letras ‘b’ mai´usculas e min´usculas, utilize esta
consulta:
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
A partir do MySQL 3.23.4, para for¸car uma compara¸ao REGEXP com caso sensitivo, utilize
a palavra-chave BINARY para tornar uma das strings em uma string bin´arias. Esta consulta
ir´a combinar somente com ‘b’s min´usculos no come¸co de um nome:
mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
Para encontrar nomes finalizados com ‘fy’, utilize ‘$’ para combinar com o final do nome:
mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Para encontrar nomes contendo um ‘w’ min´usculo ou mai´usculo, utilize esta consulta:
mysql> SELECT * FROM pet WHERE name REGEXP "w";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Como uma express˜ao regular extendida encontra padr˜oes coincidentes se eles ocorrem em
qualquer lugar no valor comparado, n˜ao ´e necess´ario utiliar, na consulta anterior, nenhum
170 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
metacaracter em nenhum dos lados do padr˜ao para fazˆe-lo coincidir com todo o valor, como
seria feito se fosse utilizado o padr˜ao SQL.
Para encontrar nomes contendo exatamente cinco caracteres, utilize ‘^’ e ‘$’ para combinar
com o come¸co e fim do nome e cinco instˆancias de ‘.’ entre eles.
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Voe pode tamb´em escrever a consulta anterior utilizando o operador ‘{n}’ “repete-n-vezes”:
mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
3.3.4.8 Contando Registros
Bancos de dados normalmente s˜ao usados para responder a perguntas, “Qual a frequˆencia
que certo tipo de dados ocorre em uma tabela?” Por exemplo, vocˆe deve querer saber
quantos animais tem, ou quantos animais cada dono tem, ou vocˆe pode querer fazer v´arios
outros tipos de censos com seus animais.
Contando o n´umero total de animais que vocˆe tem ´e a mesma quest˜ao como em “Quantos
registros existem na tabela pet?” porque existe um registro por animal. A fun¸ao COUNT()
conta o n´umero de resultados n˜ao-NULL, portanto a pesquisa para contar seus animais
parecer´a com isto:
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
| 9 |
+----------+
Logo, vocˆe recuperar´a os nomes das pessoas que possuam animais. Vocˆe pode usar COUNT()
se vocˆe desejar encontrar quantos animais cada dono possui:
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny | 2 |
| Diane | 2 |
| Gwen | 3 |
| Harold | 2 |
+--------+----------+
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 171
Perceba o uso de GROUP BY para agrupar todos os registros para cada owner (dono). Sem
ele, vocˆe teria uma mensagem de erro:
mysql> SELECT owner, COUNT(owner) FROM pet;
ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause
COUNT() eGROUP BY ao ´uteis para personalizar seus dados de diversas maneiras. Os
seguintes exemplos mostram diferentes maneiras para realizar opera¸oes de censo nos ani-
mais.
N´umero de animais por esp´ecie:
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+---------+----------+
N´umero de animais por sexo:
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex | COUNT(*) |
+------+----------+
| NULL | 1 |
| f | 4 |
| m | 4 |
+------+----------+
(Nesta sa´
ida, NULL indica sexo desconhecido.)
N´umero de animais combinando esp´ecie e sexo:
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
ao ´e necess´ario selecionar uma tabela inteira quando estiver usando COUNT(). Por exemplo,
a consulta anterior, quando realizada apenas procurando por cachorros e gatos, se parece
com isto:
172 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = "dog" OR species = "cat"
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
+---------+------+----------+
Ou se vocˆe desejar saber o n´umero de animais por sexo somente de animais com sexo
conhecido:
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE sex IS NOT NULL
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
3.3.4.9 Utilizando M´ultiplas Tabelas
A tabela pet mant´em informa¸oes de quais animais vocˆe tem. Se vocˆe deseja gravar outras
informa¸oes sobre eles como eventos em suas vidas, tais como visitas ao veterin´ario ou sobre
suas crias, vocˆe necessitar´a de outra tabela. Como esta tabela deve se parecer ? Ela precisa:
Conter o nome do animal para que vocˆe saiba a qual animal pertence o evento.
Uma data para que vocˆe saiba quando ocorreu o evento.
Um campo para descrever o evento.
Um campo com o tipo de evento, se vocˆe desejar classific´a-los por categoria.
Dadas estas considera¸oes, a instru¸ao CREATE TABLE para a tabela event deve se parecer
com isto:
mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
-> type VARCHAR(15), remark VARCHAR(255));
Como na tabela pet, ´e mais f´acil carregar os registros iniciais criando um arquivo texto
delimitado por tabula¸oes contendo a informa¸ao:
Fluffy 1995-05-15 litter 4 kittens, 3 female, 1 male
Buffy 1993-06-23 litter 5 puppies, 2 female, 3 male
Buffy 1994-06-19 litter 3 puppies, 3 female
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 173
Chirpy 1999-03-21 vet needed beak straightened
Slim 1997-08-03 vet broken rib
Bowser 1991-10-12 kennel
Fang 1991-10-12 kennel
Fang 1998-08-28 birthday Gave him a new chew toy
Claws 1998-03-17 birthday Gave him a new flea collar
Whistler 1998-12-09 birthday First birthday
Carregue os registros usando:
mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;
Baseado no que vocˆe j´a aprendeu com as consultas realizadas na tabela pet, vocˆe deve estar
apto para realizar pesquisas na tabela event; os princ´
ipios s˜ao o mesmo. Mas quando a
tabela event, sozinha, ´e insuficiente para responder `as suas quest˜oes?
Suponha que vocˆe deseje saber as idades de cada animal quando eles tiveram cria. A tabela
event indica quando isto ocorre, mas para calcular a idade da m˜ae, vocˆe precisar´a da data
de nascimento dela. Como isto est´a armazenado na tabela pet, vocˆe precisar´a das duas
tabelas para a consulta:
mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
-> FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
| name | age | remark |
+--------+------+-----------------------------+
| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
| Buffy | 4.12 | 5 puppies, 2 female, 3 male |
| Buffy | 5.10 | 3 puppies, 3 female |
+--------+------+-----------------------------+
Existem v´arias coisas que devem ser percebidas sobre esta consulta:
A cl´ausula FROM lista as duas tabelas porque a consulta precisa extrair informa¸ao de
ambas.
Quando combinar (unir) informa¸oes de m´ultiplas tabelas, vocˆe precisa especificar como
registros em uma tabela podem ser coincididas com os registros na outra. Isto ´e simples
porque ambas possuem uma coluna name. A consulta utiliza a cl´ausula WHERE para
coincidir registros nas duas tabelas baseadas nos valores de name.
Como a coluna name ocorre em ambas tabelas, vocˆe deve especificar qual a tabela a que
vocˆe est´a se referindo. Isto ´e feito usando o nome da tabela antes do nome da coluna
separados por um ponto (.).
Voe n˜ao precisa ter duas tabelas diferentes para realizar uma uni˜ao. Algumas vezes ´e ´util
unir uma tabela a ela mesma, se vocˆe deseja comparar registros em uma tabela com outros
registros na mesma tabela. Por exemplo, para encontrar pares entre seus animais, vocˆe
pode unir a tabela pet com ela mesma para formar pares de machos e fˆemeas de acordo
com as esp´ecies:
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";
+--------+------+--------+------+---------+
174 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| name | sex | name | sex | species |
+--------+------+--------+------+---------+
| Fluffy | f | Claws | m | cat |
| Buffy | f | Fang | m | dog |
| Buffy | f | Bowser | m | dog |
+--------+------+--------+------+---------+
Nesta consulta, n´os especificamos apelidos para os nomes das tabelas para conseguir ref-
erenciar `as colunas e manter com qual instˆancia da tabela cada coluna de referˆencia est´a
associdada.
3.4 Obtendo Informa¸oes Sobre Bancos de Dados e Tabelas
E se vocˆe esquecer o nome de um banco de dados ou tabela, ou como ´e a estrutura de
uma certa tabela (por exemplo, como suas colunas s˜ao chamadas)? O MySQL resolve este
problema atrav´es de diversas instru¸oes que fornecem informa¸oes sobre os bancos de dados
e as tabelas que ele suporta.
Voe j´a viu SHOW DATABASES, que lista os bancos de dados gerenciados pelo servidor. Para
saber qual banco de dados est´a sendo usado atualmente, utilize a fun¸ao DATABASE():
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie |
+------------+
Se vocˆe ainda n˜ao selecionou nenhum banco de dados ainda, o resultado estar´a em branco.
Para saber quais tabelas o banco de dados atual conem (por exemplo, quando vocˆe n˜ao
tem certeza sobre o nome de uma tabela), utilize este comando:
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| event |
| pet |
+---------------------+
Se vocˆe deseja saber sobre a estrutura de uma tabela, o comando DESCRIBE ´e ´util; ele mostra
informa¸oes sobre cada uma das colunas da tabela:
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 175
+---------+-------------+------+-----+---------+-------+
A coluna Field (campo) indica o nome da coluna, Type ´e o tipo de dados para a coluna,
Null indica se a coluna pode conter valores nulos (NULL), key indica se a coluna ´e indexada
ou n˜ao e Default especifica o valor padr˜ao da coluna.
Se vocˆe tem ´
indices em uma tabela, SHOW INDEX FROM tbl_nome traz informa¸oes sobre eles.
3.5 Exemplos de Consultas Comuns
Aqui est˜ao os exemplos de como resolver problemas comuns com o MySQL.
Alguns dos exemplos usam a tabela shop para armazenar o pre¸co de cada ´
item (article)
para certas revendas (dealers). Supondo que cada revenda tenha um pre¸co fixo por artigo,
enao (article,dealer) ´e uma chave prim´aria para os registros.
Inicie a ferramenta de linha de comando mysql e selecione um banco de dados:
mysql o-nome-do-seu-banco-de-dados
(Na maioria das instala¸oes do MySQL, vocˆe pode usar o banco de dados ’test’).
Voe pode criar a tabela exemplo assim:
CREATE TABLE shop (
article INT(4) UNSIGNED ZEROFILL DEFAULT ’0000’ NOT NULL,
dealer CHAR(20) DEFAULT ’’ NOT NULL,
price DOUBLE(16,2) DEFAULT ’0.00’ NOT NULL,
PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
(1,’A’,3.45),(1,’B’,3.99),(2,’A’,10.99),(3,’B’,1.45),(3,’C’,1.69),
(3,’D’,1.25),(4,’D’,19.95);
Feito isto, os dados de exemplo s˜ao:
mysql> SELECT * FROM shop;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | A | 3.45 |
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | B | 1.45 |
| 0003 | C | 1.69 |
| 0003 | D | 1.25 |
| 0004 | D | 19.95 |
+---------+--------+-------+
3.5.1 O Valor M´aximo para uma Coluna
“Qual ´e o maior n´umero dos ´
itens?”
SELECT MAX(article) AS article FROM shop
+---------+
176 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| article |
+---------+
| 4 |
+---------+
3.5.2 O Registro que Armazena o Valor M´aximo para uma Certa
Coluna
“Encontre o n´umero, fornecedor e pre¸co do ´
item mais caro.”
No SQL ANSI isto ´e feito f´acilmente com uma sub-consulta:
SELECT article, dealer, price
FROM shop
WHERE price=(SELECT MAX(price) FROM shop)
No MySQL (que ainda n˜ao suporta sub-selects), fa¸ca isto em dois passos:
1. Obtenha o valor do pre¸co m´aximo da tabela com uma instru¸ao SELECT.
2. Usando este valor componha a pesquisa:
SELECT article, dealer, price
FROM shop
WHERE price=19.95
Outra solu¸ao ´e ordenar todos os registros por pre¸co de forma descendente e obtenha so-
mente o primeiro registro utilizando a cl´ausula espec´
ifica do MySQL LIMIT:
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1
NOTA: Se existir diversos ´
itens mais caros (por exemplo, cada um por 19,95) a solu¸ao
LIMIT mostra somente um deles !
3.5.3 aximo da Coluna por Grupo
“Qual ´e o maior pre¸co por ´
item?”
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article
+---------+-------+
| article | price |
+---------+-------+
| 0001 | 3.99 |
| 0002 | 10.99 |
| 0003 | 1.69 |
| 0004 | 19.95 |
+---------+-------+
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 177
3.5.4 As Linhas Armazenando o Group-wise M´aximo de um Certo
Campo
“Para cada ´
item, encontre o(s) fornecedor(s) com o maior pre¸co.”
No SQL ANSI, poder´
iamos fazer uma sub-consulta, desta forma:
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article);
No MySQL ´e melhor fazˆe-lo em diversos passos:
1. Obtenha a lista de (article,maxprice).
2. Para cada ´
item obtenha os registros correspondentes que tenham o maior pre¸co.
Isto pode ser feito facilmente com uma tabela tempor´aria:
CREATE TEMPORARY TABLE tmp (
article INT(4) UNSIGNED ZEROFILL DEFAULT ’0000’ NOT NULL,
price DOUBLE(16,2) DEFAULT ’0.00’ NOT NULL);
LOCK TABLES shop read;
INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;
SELECT shop.article, dealer, shop.price FROM shop, tmp
WHERE shop.article=tmp.article AND shop.price=tmp.price;
UNLOCK TABLES;
DROP TABLE tmp;
Se vocˆe n˜ao usar uma tabela TEMPOR´
ARIA, vocˆe deve bloquear tamb´em a tabela ’tmp’.
“Posso fazer isto com uma ´unica query?”
Sim, mas somente com um truque ineficiente que eu chamo de “truque MAX-CONCAT”:
SELECT article,
SUBSTRING( MAX( CONCAT(LPAD(price,6,’0’),dealer) ), 7) AS dealer,
0.00+LEFT( MAX( CONCAT(LPAD(price,6,’0’),dealer) ), 6) AS price
FROM shop
GROUP BY article;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | C | 1.69 |
| 0004 | D | 19.95 |
+---------+--------+-------+
O ´ultimo exemplo pode, ´e claro, ser feito de uma maneira mais eficiente fazendo a separa¸ao
da coluna concatenada no cliente.
178 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
3.5.5 Utilizando Vari´aveis de Usu´ario
Voe pode usar vari´aveis de usu´arios no MySQL para lembrar de resultados sem a necessi-
dade de armazen´a-las em vari´aveis no cliente. See hundefinedi[Variables], page hundefinedi.
Por exemplo, para encontrar os ´
itens com os pre¸cos mais altos e mais baixos vocˆe pode
fazer:
select @min_price:=min(price),@max_price:=max(price) from shop;
select * from shop where price=@min_price or price=@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0003 | D | 1.25 |
| 0004 | D | 19.95 |
+---------+--------+-------+
3.5.6 Utilizando Chaves Estrangeiras
Voe n˜ao precisa de chaves estrangeiras para unir 2 tabelas.
A ´unica coisa que o MySQL n˜ao faz ´e CONFERIR para ter certeza que as chaves que vocˆe
usa realmente existem na(s) tabela(s) referenciadas e ele n˜ao apaga automaticamente reg-
istros da tabela com uma defini¸ao de chave estrangeira. Se vocˆe utiliza suas chaves da
normalmente, ir´a funcionar bem:
CREATE TABLE persons (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE shirts (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM(’t-shirt’, ’polo’, ’dress’) NOT NULL,
color ENUM(’red’, ’blue’, ’orange’, ’white’, ’black’) NOT NULL,
owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
PRIMARY KEY (id)
);
INSERT INTO persons VALUES (NULL, ’Antonio Paz’);
INSERT INTO shirts VALUES
(NULL, ’polo’, ’blue’, LAST_INSERT_ID()),
(NULL, ’dress’, ’white’, LAST_INSERT_ID()),
(NULL, ’t-shirt’, ’blue’, LAST_INSERT_ID());
INSERT INTO persons VALUES (NULL, ’Lilliana Angelovska’);
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 179
INSERT INTO shirts VALUES
(NULL, ’dress’, ’orange’, LAST_INSERT_ID()),
(NULL, ’polo’, ’red’, LAST_INSERT_ID()),
(NULL, ’dress’, ’blue’, LAST_INSERT_ID()),
(NULL, ’t-shirt’, ’white’, LAST_INSERT_ID());
SELECT * FROM persons;
+----+---------------------+
| id | name |
+----+---------------------+
| 1 | Antonio Paz |
| 2 | Lilliana Angelovska |
+----+---------------------+
SELECT * FROM shirts;
+----+---------+--------+-------+
| id | style | color | owner |
+----+---------+--------+-------+
| 1 | polo | blue | 1 |
| 2 | dress | white | 1 |
| 3 | t-shirt | blue | 1 |
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
| 7 | t-shirt | white | 2 |
+----+---------+--------+-------+
SELECT s.* FROM persons p, shirts s
WHERE p.name LIKE ’Lilliana%’
AND s.owner = p.id
AND s.color <> ’white’;
+----+-------+--------+-------+
| id | style | color | owner |
+----+-------+--------+-------+
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
+----+-------+--------+-------+
3.5.7 Pesquisando em Duas Chaves
O MySQL ainda n˜ao otimiza quando voe pesquisa em duas chaves diferentes combinadas
com OR (Pesquisa em uma chave com diferentes partes OR ´e muito bem otimizadas).
SELECT field1_index, field2_index FROM test_table WHERE field1_index = ’1’
OR field2_index = ’1’
180 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A raz˜ao ´e que n´os ainda n˜ao tivemos tempos para fazer este tratamento de uma maneira
eficiente no caso geral. (A manipula¸ao do AND ´e, em compara¸ao, completamente geral e
funciona muito bem).
No momento vocˆe pode resolver isto de maneira eficiente usando uma tabela TEMPOR´
ARIA.
Este tipo de otimiza¸ao ´e tamb´em muito boa se vocˆe estiver utilizando consultas muito
complicadas no qual o servidor SQL faz as otimiza¸oes na ordem errada.
CREATE TEMPORARY TABLE tmp
SELECT field1_index, field2_index FROM test_table WHERE field1_index = ’1’;
INSERT INTO tmp
SELECT field1_index, field2_index FROM test_table WHERE field2_index = ’1’;
SELECT * from tmp;
DROP TABLE tmp;
A maneira descrita acima para resolver esta consulta ´e uma uni˜ao (UNION) de duas consultas.
3.5.8 Calculando Visitas Di´arias
A seguir demonstramos uma id´eia de como usar as fun¸oes bin´arias de agrupamento para
calcular o n´umero de dias por mˆes que um usu´ario tem visitado uma p´agina web.
CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),(2000,2,23),(2000,2,23);
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month;
que retornar´a:
+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 | 01 | 3 |
| 2000 | 02 | 2 |
+------+-------+------+
O exemplo acima calcula quantos dias diferentes foram usados para uma combina¸ao
fornecida de mˆes/ano, com remo¸ao autom´atica de entradas duplicadas.
3.6 Utilizando mysql em Modo Batch
Nas se¸oes anteriores, vocˆe usou mysql interativamente para fazer consultas e ver os re-
sultados. Voe pode tamb´em executar mysql no modo batch. Para fazer isto, coloque os
comando que vocˆe deseja executar em um arquivo, e diga ao mysqld para ler sua entrada
do arquivo:
shell> mysql < batch-file
Se vocˆe precisa especificar parˆametros de conex˜ao na linha de comando, o comando deve
parecer com isto:
shell> mysql -h host -u user -p < batch-file
Enter password: ********
Quando vocˆe utilizar o mysql desta forma, vocˆe estar´a criando um arquivo script, depois
executando o script.
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 181
Por que usar um script? Existem v´arias raz˜oes:
Se vocˆe executa uma query repetidamente (digamos, todos os dias ou todas as semanas),
transform´a-lo em um script permite que vocˆe n˜ao o redigite toda vez que o executa.
Voe pode gerar novas consultas a partir das j´a existentes copiando e editando os
arquivos de script.
O modo batch pode tamb´em ser ´util quando vocˆe estiver desenvolvendo uma consulta,
particularmente para comandos de m´ultiplas linhas ou sequˆencias de comandos com
arias instru¸oes. Se vocˆe cometer um erro, n˜ao ser´a necess´ario redigitar tudo. Apenas
edite seu arquivo script e corrija o erro, depois diga ao mysql para execut´a-lo novamente.
Se vocˆe tem uma query que produz muita sa´
ida, vocˆe pode encaminhar a sa´
ida atrav´es
de um p´aginador.
shell> mysql < batch-file | more
Voe pode capturar a sa´
ida em um arquivo para processamento posterior:
shell> mysql < batch-file > mysql.out
Voe pode distribuir seu script para outras pessoas para que elas possam executar os
comandos tamb´em.
Algumas situa¸oes n˜ao permitem uso interativo, por exemplo, quando vocˆe executa
uma consulta atrav´es de um processo autom´atico (cron job). Neste caso, vocˆe deve
usar o modo batch.
A formato padr˜ao de sa´
ida ´e diferente (mais conciso) quando vocˆe executa o mysql no modo
batch do que quando vocˆe o usa interativamente. Por exemplo, a sa´
ida de SELECT DISTINCT
species FROM pet se parece com isto quando vocˆe o executa interativamente:
+---------+
| species |
+---------+
| bird |
| cat |
| dog |
| hamster |
| snake |
+---------+
Mas fica assim quando vocˆe o executa no modo batch:
species
bird
cat
dog
hamster
snake
Se vocˆe desejar obter o formato de sa´
ida interativa no modo batch, utilize mysql -t. Para
mostrar a sa´
ida dos comandos que s˜ao executados, utilize mysql -vvv.
3.7 Consultas de Projetos Gˆemeos
Em Analytikerna e Lentus, n´os estamos fazendo os sistemas e trabalho de campo para um
grande projeto de pesquisa. Este projeto ´e uma colabora¸ao entre o Institudo de Medicina
182 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Ambiental em Karolinksa Institutet Stockholm e a Se¸ao de Pesquisa Cl´
inica em Envelhec-
imento e Psicologia na University of Southern California.
O projeto envolve uma parte de sele¸ao onde todos os gˆemeos na Su´ecia mais velhos que 65
anos s˜ao entrevistados por telefone. emeos que preenchem certos crit´erios passam para
o pr´oximo est´agio. Neste est´agio posterior, gˆemeos que desejam participar s˜ao visitados
por uma equipe de doutores/enfermeiros. Alguns dos consultas incluem exames f´
isicos e
neuropsicol´ogico, testes de laborat´orio, imagem neural, determina¸ao do estado psicol´ogico
e coletas de hist´orico familiar. Adicionalmente, dados s˜ao coletados em fatores de riscos
m´edicos e ambientais.
Mais informa¸oes sobre o estudos dos gˆemeos pode ser encontrados em:
http://www.imm.ki.se/TWIN/TWINUKW.HTM
A parte posterior do projeto ´e administrada com uma interface Web escrita utilizando a
linguagem Perl e o MySQL.
Cada noite todos dados das entrevistas s˜ao movidos para um banco de dados MySQL.
3.7.1 Encontrando Todos Gˆemeos N˜ao-distribu
´
idos
A seguinte consulta ´e usada para determinar quem vai na segunda parte do projeto:
select
concat(p1.id, p1.tvab) + 0 as tvid,
concat(p1.christian_name, " ", p1.surname) as Name,
p1.postal_code as Code,
p1.city as City,
pg.abrev as Area,
if(td.participation = "Aborted", "A", " ") as A,
p1.dead as dead1,
l.event as event1,
td.suspect as tsuspect1,
id.suspect as isuspect1,
td.severe as tsevere1,
id.severe as isevere1,
p2.dead as dead2,
l2.event as event2,
h2.nurse as nurse2,
h2.doctor as doctor2,
td2.suspect as tsuspect2,
id2.suspect as isuspect2,
td2.severe as tsevere2,
id2.severe as isevere2,
l.finish_date
from
twin_project as tp
/* For Twin 1 */
left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 183
/* For Twin 2 */
left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
person_data as p1,
person_data as p2,
postal_groups as pg
where
/* p1 gets main twin and p2 gets his/her twin. */
/* ptvab is a field inverted from tvab */
p1.id = tp.id and p1.tvab = tp.tvab and
p2.id = p1.id and p2.ptvab = p1.tvab and
/* Just the sceening survey */
tp.survey_no = 5 and
/* Skip if partner died before 65 but allow emigration (dead=9) */
(p2.dead = 0 or p2.dead = 9 or
(p2.dead = 1 and
(p2.death_date = 0 or
(((to_days(p2.death_date) - to_days(p2.birthday)) / 365)
>= 65))))
and
(
/* Twin is suspect */
(td.future_contact = ’Yes’ and td.suspect = 2) or
/* Twin is suspect - Informant is Blessed */
(td.future_contact = ’Yes’ and td.suspect = 1 and id.suspect = 1) or
/* No twin - Informant is Blessed */
(ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = ’Yes’) or
/* Twin broken off - Informant is Blessed */
(td.participation = ’Aborted’
and id.suspect = 1 and id.future_contact = ’Yes’) or
/* Twin broken off - No inform - Have partner */
(td.participation = ’Aborted’ and ISNULL(id.suspect) and p2.dead = 0))
and
l.event = ’Finished’
/* Get at area code */
and substring(p1.postal_code, 1, 2) = pg.code
/* Not already distributed */
and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
/* Has not refused or been aborted */
and not (h.status = ’Refused’ or h.status = ’Aborted’
or h.status = ’Died’ or h.status = ’Other’)
order by
tvid;
Algumas explica¸oes:
184 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
concat(p1.id, p1.tvab) + 0 as tvid
N queremos ordenar o id e o tvab concatenados na ordem num´erica. Adicio-
nando 0ao resultado faz o MySQL tratar o resultado como um n´umero.
coluna id Esta identifica um par de gˆemeos. Ela ´e uma chave em todas as tabelas.
column tvab
Esta identifica um gˆemeo em um par. Ela pode ter um valor de 1ou 2.
column ptvab
Esta ´e o inverso de tvab. Quando tvab ´e 1este campo ´e 2e vice versa. Ela
existe para poupar digita¸ao e tornar mais f´acil para o MySQL otimizar a query.
Esta consulta demonstra, entre outras coisas, como fazer buscas em uma tabela a partir da
mesma tabela com uma uniao (p1 ep2). No exemplo, isto ´e usado para conferir se um par
de um gˆemeo morreu antes de 65 anos. Se for verdade, a linha n˜ao ´e retornada.
Tudo acima existe em todas as tabelas com informa¸oes relacionada aos gˆemeos. os temos
uma chave em ambos id,tvab (todas as tabelas) e id,ptvab (person_data) para tornar
as consultas mais r´apidas.
Na nossa m´aquina de produ¸ao (Um UltraSPARC 200MHz), esta consulta retorna entre
150-200 linhas e gasta menos que um segundo.
O n´umero atual de registros nas tabelas usadas acima:
Tabela Registros
person_data 71074
lentus 5291
twin_project 5286
twin_data 2012
informant_data 663
harmony 381
postal_groups 100
3.7.2 Mostrando uma Tabela sobre a Situa¸ao dos Pares Gˆemeos
Cada entrevista termina com um c´odigo da situa¸ao chamado event. A consulta mostrada
abaixa ´e usada para mostrar uma tabela sobre todos pares gˆemeos combinados por evento.
Ela indica em quantos pares ambos gˆemeos terminaram, em quantos pares um gˆemeo ter-
minou e o outro foi recusado e assim por diante.
select
t1.event,
t2.event,
count(*)
from
lentus as t1,
lentus as t2,
twin_project as tp
where
/* We are looking at one pair at a time */
t1.id = tp.id
and t1.tvab=tp.tvab
Chapter 3: Introdu¸ao ao MySQL: Um Tutorial MysQL 185
and t1.id = t2.id
/* Just the sceening survey */
and tp.survey_no = 5
/* This makes each pair only appear once */
and t1.tvab=’1’ and t2.tvab=’2’
group by
t1.event, t2.event;
3.8 Utilizando MySQL com Apache
A se¸ao Contrib inclui programas que lhe permite autenticar seus usu´arios a partir de um
banco de dados MySQL e tamb´em permite logar seus arquivos em uma tabela MySQL. See
hundefinedi[Contrib], page hundefinedi.
Voe pode alterar o formato de log do Apache para ser facilmente lido pelo MySQL colo-
cando o seguinte no arquivo de configura¸ao do Apache:
LogFormat \
"\"%h\",%{%Y%m%d%H%M%S}t,%>s,\"%b\",\"%{Content-Type}o\", \
\"%U\",\"%{Referer}i\",\"%{User-Agent}i\""
No MySQL vocˆe pode fazer algo assim:
LOAD DATA INFILE ’/local/access_log’ INTO TABLE nome_tabela
FIELDS TERMINATED BY ’,’ OPTIONALLY ENCLOSED BY ’"’ ESCAPED BY ’\\’
186 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4 Administra¸ao de Bancos de Dados MySQL
4.1 Configurando o MySQL
4.1.1 Op¸oes da Linha de Comando do mysqld
Omysqld aceita as seguintes op¸oes de linha de comando:
--ansi Utilizar a sintaxe ANSI SQL no lugar da sintaxe MySQL See hundefinedi[ANSI
mode], page hundefinedi.
-b, --basedir=path
Encaminho para o diret´orio de instala¸ao. Todos os caminhos normalmente s˜ao
resolvidos em rela¸ao a este.
--big-tables
Permite grandes conjuntos de resultados salvando todos os conjuntos tem-
por´arios em um arquivo. Ele resolve a maioria dos erros ’table full’, mas
tamb´em abaixa a velocidade das consultas nas quais as tabelas em mem´oria
seriam suficientes. Desde a Vers˜ao 3.23.2, o MySQL ´e capaz de resolver isto au-
tomaticamente usando mem´oria para pequenas tabelas tempor´arias e trocando
para o disco as tabelas, quando for necess´ario.
--bind-address=IP
Endere¸co IP para ligar.
--character-sets-dir=path
Diret´orio onde est˜ao os conjuntos de caracteres. See hundefinedi[Conjunto de
caracteres], page hundefinedi.
--chroot=path
Muda o diret´orio raiz do daemon mysqld durante a inicializa¸ao. Medida de
seguran¸ca recomendada. Limita os comandos LOAD DATA INFILE eSELECT ...
INTO OUTFILE.
--core-file
Grava um arquivo core se o mysqld morrer. Para alguns sistemas vocˆe deve
tamb´em especificar --core-file-size para safe_mysqld. See hundefinedi
[safe_mysqld], page hundefinedi
-h, --datadir=path
Encaminha para o diret´orio raiz dos bancos de dados.
--default-character-set=charset
Configura o conjunto de caracteres padr˜ao. See hundefinedi[Conjunto de car-
acteres], page hundefinedi.
--default-table-type=type
Configura o tipo de tabela padr˜ao. See hundefinedi[Tipos de tabelas], page hun-
definedi.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 187
--debug[...]=
Se o MySQL est´a configurado com --with-debug, vocˆe pode usar esta op¸ao
para obter um arquivo de rastreamento indicando o que o mysqld est´a fazendo.
See hundefinedi[Criando arquivos de rastreamento], page hundefinedi.
--delay-key-write-for-all-tables
ao atualiza buffers das chaves entre escritas em nenhuma tabela MyISAM. See
hundefinedi[Parˆametros do servidor], page hundefinedi.
--enable-locking
Habilita o bloqueio do sistema. Perceba que se usar esta op¸ao em um sistema
que n˜ao possui um lockd() completamente funcional (como no Linux) vocˆe 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 ´e uma m´ascara bin´aria com diferˆentes parˆametros que pode ser usada para
depurar o servidor mysqld; Esta op¸ao n˜ao deve ser usada por algu´em que n˜ao
a conhe¸ca muito bem!
--flush Atualiza todas as altera¸oes no disco depois de cada comando SQL. Normal-
mente o MySQL s´o faz a escrita de todas as altera¸oes no disco depois de cada
comando SQL e deixa o sistema operacional lidar com a sincroniza¸ao com o
disco. See hundefinedi[Falhas], page hundefinedi.
-?, --help
Mostra uma pequena ajuda e sai.
--init-file=arquivo
Lˆe comandos SQL do arquivo especificado na inicializa¸ao.
-L, --language=...
Mensagens de erro do cliente na l´
ingua especificada. Pode ser fornecido como
um caminho completo. See hundefinedi[L´
inguas], page hundefinedi.
-l, --log[=arquivo]
Log de conex˜oes e consultas ao arquivo. See hundefinedi[Log de consultas],
page hundefinedi.
--log-isam[=arquivo]
Log de todas altera¸oes ISAM/MyISAM no arquivo (usado somente quando
estiver depurando bancos ISAM/MyISAM).
--log-slow-queries[=arquivo]
Log de todas as consultas que levam mais de long_query_time segundos de
execu¸ao para um arquivo. See hundefinedi[Log de consultas lentas], page hun-
definedi.
--log-update[=arquivo]
Log de atualiza¸oes para file.# onde #´e um n´umero ´unico se n˜ao for fornecido.
See hundefinedi[Log de atualiza¸ao], page hundefinedi.
188 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--log-long-format
Log de algumas informa¸oes extra ao log de atualiza¸oes. Se vocˆe estiver usando
--log-slow-queries enao consultas que n˜ao est˜ao usando ´
indices s˜ao logadas
ao log de consultas lentas.
--low-priority-updates
Opera¸oes de altera¸oes das tabelas (INSERT/DELETE/UPDATE) ir˜ao ter priori-
dade menor do que as selects. Isto tamb´em 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 al-
terar a prioridade em uma ´unica thread. See hundefinedi[Bloqueio de tabelas],
page hundefinedi.
--memlock
Bloqueia o processo mysqld na mem´oria. Isto funciona somente se o seu sistema
suportar a chamada de sistema mklockall() (como no Solaris). Isto pode
ajudar se vocˆe tiver um problema no qual o sistema operacional faz com que o
mysqld fa¸ca a troca em disco.
--myisam-recover [=op¸c~ao[,op¸c~ao...]]] onde op¸c~ao ´e qualquer combina¸c~ao
de DEFAULT,BACKUP,FORCE ou QUICK. Vocˆe tamb´em pode configurar isto ex-
plicitamente para "" se vocˆe deseja desabilitar esta op¸ao. Se esta op¸ao for
usada, o mysqld ir´a conferir na abertura se a tabela est´a marcada como que-
brada ou se a tabela n˜ao foi fechada corretamente. (A ´ultima op¸ao funciona
somente se vocˆe estiver executando com --skip-locking). Se este for o caso
mysqld ir´a executar uma conferˆencia na tabela. Se a tabela estiver corrompida,
omysqld ir´a tentar repar´a-la.
As seguintes op¸oes afetam no funcionamento da repara¸ao.
DEFAULT O mesmo que n˜ao fornecer uma op¸ao para --myisam-
recover.
BACKUP Se os dados da tabela foram alterados durante a recupera¸ao,
salve um backup do arquivo de dados ‘nome_tabela.MYD
como ‘nome_tabela_dia_hora.BAK’.
FORCE Execute a recupera¸ao mesmo se perdermos mais de uma
linha do arquivo .MYD.
QUICK ao confira as linhas na tabela se n˜ao existir nenhum bloco
apagado.
Antes da tabela ser reparada automaticamente, o MySQL ir´a adicionar uma
nota no log de erros. Se voe desejar que a recupera¸ao da maioria das
coisas n˜ao tenha a interven¸ao de algum usu´ario, devem ser usadas as op¸oes
BACKUP,FORCE. Isto ir´a for¸car um reparo de uma tabela mesmo se alguns
registros forem apagados, mas ele manter´a o arquivo de dados antigo como um
backup para que vocˆe possa examinar posteriormente o que aconteceu.
--pid-file=path
Encaminha para o arquivo pid usado pelo safe_mysqld.
-P, --port=...
N´umero da porta para conex˜oes TCP/IP.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 189
-o, --old-protocol
Utilize o protocolo 3.20 para compatibilidade com alguns clientes muito antigos.
See hundefinedi[Upgrading-from-3.20], page hundefinedi.
--one-thread
Use somente uma thread (para depura¸ao sobre Linux). See hundefinedi[De-
bugging server], page hundefinedi.
-O, --set-variable var=op¸c~ao
Fornece um valor para uma vari´avel. --help lista as vari´aveis. Voe
pode encontrar uma descri¸ao completa para todas as vari´aveis na se¸ao
SHOW VARIABLES deste manual. See hundefinedi[SHOW VARIABLES],
page hundefinedi. A se¸c˜ao de sintonia dos parˆametros do servidor inclui
informa¸oes sobre como otimiz´a-los. See hundefinedi[Server parameters],
page hundefinedi.
--safe-mode
Salta alguns est´agios de otimiza¸ao. Implica --skip-delay-key-write.
--safe-show-database
ao mostra os bancos de dados nos quais o usu´ario n˜ao tenha privil´egios.
--safe-user-create
Se isto estiver ativo, um usu´ario n˜ao pode criar novos usu´arios com o comando
GRANT, se o usu´ario n˜ao ter o privil´egio de INSERT na tabela mysql.user ou
em alguma coluna desta tabela.
--skip-concurrent-insert
Desliga a habilidade de selecionar e inserir ao mesmo tempo em tabelas MyISAM.
(Isto s´o ´e usado se vocˆe achar que encontrou um erro neste recurso).
--skip-delay-key-write
Ignore a op¸ao delay_key_write para todas as tabelas. See hundefinedi
[Parˆametros do servidor], page hundefinedi.
--skip-grant-tables
Esta op¸ao faz com que o servidor n˜ao use o sistema de privil´egio. Isto d´a a
todos acesso pleno a todos os bancos de dados! (Vocˆe pode dizer a um servidor
em execu¸ao para iniciar a usar as tabelas de permiss˜ao novamente executando
mysqladmin flush-privileges ou mysqladmin reload.)
--skip-host-cache
Nunca utiliza cache para nomes de m´aquina para resolu¸oes de nomes mais
apidos, mas pesquisa o servidor DNS em todas conex˜oes. See hundefinedi
[DNS], page hundefinedi
--skip-locking
ao utilizar bloqueio de sistema. Para usar isamchk ou myisamchk vocˆe deve
desligar o servidor. See hundefinedi[Stability], page hundefinedi. Perceba que
na Vers˜ao 3.23 do MySQL pode ser usado REPAIR eCHECK para reparar/conferir
tabelas MyISAM.
190 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--skip-name-resolve
Nomes de m´aquinas n˜ao s˜ao resolvidos. Todos os valores da coluna Host nas
tabelas de permiss˜oes devem conter n´umeros IP ou localhost. See hundefinedi
[DNS], page hundefinedi.
--skip-networking
ao escutair conex˜oes TCP/IP. Toda intera¸ao com mysqld deve ser feito
atrav´es de sockets Unix. Esta op¸ao ´e altamente recomendada para sistemas
onde requisi¸oes locais s˜ao permitidas. See hundefinedi[DNS], page hundefinedi
--skip-new
ao utilizar rotinas novas, poss´
ivelmente erradas. Implica --skip-delay-key-
write. Isto tamb´em configura o tipo de tabela padr˜ao como ISAM. See hunde-
finedi[ISAM], page hundefinedi.
--skip-symlink
ao apague ou renomeie arquivos de liga¸ao simolica para o diret´orio de dados.
--skip-safemalloc
Se o MySQL ´e configurado com --with-debug=full, todos os programas ir˜ao
verificar a mem´oria por erros para cada aloca¸ao e libera¸ao de mem´oria. Como
esta consistˆencia ´e muito lenta, vocˆe pode evit´a-la, quando vocˆe n˜ao precisar
de verificar a mem´oria, usando esta op¸ao.
--skip-show-database
ao permite o comando ’SHOW DATABASE’, a menos que o usu´ario tenha
privil´egio process.
--skip-stack-trace
ao gravar rastreamentos de pilha. Esta op¸ao ´e ´util quando vocˆe estiver exe-
cutando o mysqld sob um depurador. See hundefinedi[Depurando o servidor],
page hundefinedi.
--skip-thread-priority
Desabilita o uso de prioridade das threads para um tempo de resposta mais
apido.
--socket=path
Arquivo socket para usar em conex˜oes locais no lugar do padr˜ao
/tmp/mysql.sock.
--sql-mode=op¸c~ao[,op¸c~ao[,op¸c~ao...]]
Op¸ao pode ser qualquer combina¸ao de: REAL_AS_FLOAT,PIPES_AS_CONCAT,
ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY. Ela tamb´em
pode ficar vazia ("") se vocˆe desejar limp´a-la.
Especificar todas as op¸oes acima ´e o mesmo que usar –ansi. Com estas op¸oes,
pode se ligar somente os modos SQL necess´arios. See hundefinedi[Modo ANSI],
page hundefinedi.
transaction-isolation= { READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ
| SERIALIZABLE }
Configura o n´
ivel de isola¸ao da transa¸ao padr˜ao. See hundefinedi[SET
TRANSACTION], page hundefinedi.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 191
-t, --tmpdir=caminho
Encaminha para arquivos tempor´arios. Ele pode ser ´util se o seu diret´orio
padr˜ao /tmp est´a em uma parti¸ao muito pequena para armazenar tabelas tem-
por´arias.
-u, --user=nome_usu´ario
Executar o servidor mysqld como o usu´ario nome_usu´ario. Esta op¸ao ´e obri-
gat´oria quando o mysqld ´e iniciado como usu´ario root.
-V, --version
Gera sa´
ida com a informa¸ao da vers˜ao e sai.
-W, --warnings
Imprime avisos como Aborted connection... no arquivo .err. See hunde-
finedi[Erros de comunica¸ao], page hundefinedi.
4.1.2 Arquivo de Op¸oes my.cnf
O MySQL pode, desde a vers˜ao 3.22, ler as op¸oes padr˜oes de inicializa¸ao para o servidor
e para clientes dos arquivos de op¸oes.
O MySQL le op¸oes padr˜oes dos seguintes arquivos no Unix:
Nome do arquivo Prop´osito
/etc/my.cnf op¸oes globais
DATADIR/my.cnf op¸oes espec´
ificas do servidor
defaults-extra-file O arquivo especificado com –defaults-extra-file=#
~/.my.cnf op¸oes espec´
ificas do usu´ario
DATADIR ´e o diret´orio de dados do MySQL (normalmente ‘/usr/local/mysql/data’ para
instala¸oes bin´arias ou ‘/usr/local/var’ para instala¸oes de c´odigo fonte). Perceba que
este ´e o diret´orio que foi especificado na hora da configura¸ao, n˜ao o especificado com --
datadir quando o mysqld inicia! (--datadir ao tem efeito sobre o local onde o servidor
procura por arquivos de op¸oes, porque ele procura por eles antes de processar qualquer
argumento da linha de comando.)
O MySQL lˆe os op¸oes padr˜oes dos seguintes arquivos no windows:
Nome do Arquivo Prop´osito
windows-system-
directory\my.ini
op¸oes globais
C:\my.cnf op¸oes globais
C:\mysql\data\my.cnf op¸oes espec´
ificas do servidor
Perceba que no windows, vocˆe deve especificar todos os caminhos com /no lugar de \. Se
for utilizado o \, ser´a necess´ario digit´a-lo duas vezes, pois o \´e o caractere de escape no
MySQL.
O MySQL tenta ler os arquivos de op¸oes na ordem listada acima. Se m´ultiplos arquivos de
op¸oes existirem, uma op¸ao especificada em um arquivo lido depois recebe a precedˆencia
sobre a mesma op¸ao especificada em um arquivo lido anteriormente. Op¸oes especificadas
na linha de comando recebem a precedˆencia sobre op¸oes especificadas em qualquer arquivo
de op¸oes. Algumas op¸oes podem ser especificadas usando vari´aveis de ambiente. Op¸oes
especificadas na linha de comando ou nos arquivos de op¸ao tem precendencia sobre valores
nas vari´aveis de ambiente. See hundefinedi[Vari´aveis de ambiente], page hundefinedi.
192 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Os seguintes programas suportam arquivos de op¸oes: mysql,mysqladmin,mysqld,
mysqldump,mysqlimport,mysql.server,myisamchk emyisampack
Voe pode usar arquivos de op¸oes para especificar qualquer op¸ao extendida que o programa
suporte! Execute o programa com --help para obter uma lista das op¸oes dispon´
iveis.
Um arquivo de op¸oes pode conter linhas na seguinte forma:
#comentario
Linhas de comenario iniciam com o caractere ‘#’ ou ‘;’. Linhas vazias s˜ao
ignoradas.
[grupo] grupo ´e o nome do programa ou grupo para o qual vocˆe ir´a configurar as op¸oes.
Depois de uma linha de grupo, qualquer linha de op¸c~ao ou set-variable ao
referentes ao grupo at´e o final do arquivo de op¸oes ou outra linha de in´
icio de
grupo.
op¸c~ao Isto ´e equivalente `a --op¸c~ao na linha de comando.
op¸c~ao=valor
Isto ´e equivalente `a --op¸c~ao=valor na linha de comando.
set-variable = vari´avel=valor
Isto ´e equivalente `a --set-variable vari´avel=valor na linha de comando.
Esta sintaxe deve ser usada para configurar uma vari´avel mysqld.
O grupo client permite especificar op¸oes para todos clientes MySQL (n˜ao o mysqld).
Este ´e o grupo perfeito de se usar para espeficar a senha que vocˆe usa para conectar ao
servidor. (Mas tenha certeza que o arquivo de op¸oes s´o pode ser lido e gravado por vocˆe)
Perceba que para op¸oes e valores, todos espa¸cos em branco s˜ao automaticamente apagados.
Voe pode usar a sequencia de escape ‘\b’, ‘\t’, ‘\n’, ‘\r’, ‘\\’e‘\s’ no valor da string (‘\s
== espa¸co).
Aqui est´a um t´
ipico arquivo de op¸oes 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´a um t´
ipico arquivo de op¸oes do usu´ario
[client]
# A senha seguinte ser´a enviada para todos clientes MySQL
password=minha_senha
[mysql]
no-auto-rehash
Chapter 4: Administra¸ao de Bancos de Dados MySQL 193
set-variable = connect_timeout=2
[mysqlhotcopy]
interactive-timeout
Se vocˆe tem uma distribui¸ao fonte, vocˆe encontrar´a arquivos de exemplo de configura¸ao
chamados ‘my-xxxx.cnf’ no diret´orio ‘support-files’. Se vocˆe tem uma distribui¸ao
bin´aria olhe no diret´orio de instala¸ao ‘DIR/support-file’, onde DIR ´e o caminho para o
diret´orio de instala¸ao (normalmente ‘/usr/local/mysql’). Atualmente existem arquivos
de configura¸ao para sistemas pequenos, m´edios, grandes e enormes. Vocˆe pode copiar
my-xxxx.cnf’ para seu diret´orio home (renomeie a c´opia para ‘.my.cnf’ para experimen-
tar.
Todos os clientes MySQL que suportam arquivos de op¸oes aceitam op¸oes:
–no-defaults ao lˆe nenhum arquivo de op¸oes.
–print-defaults Imprima o nome do programa e todas op¸oes.
–defaults-file=caminho-para-
arquivo-padr˜ao
Utilize somente o arquivo de configura¸ao es-
pec´
ificado.
–defaults-extra-file=caminho-para-
arquivo-padr˜ao
Leia este arquivo de configura¸ao depois do arquivo
de configura¸ao global mas antes do arquivo de con-
figura¸ao do usu´ario.
Perceba que as op¸oes acima devem vir primeiro na linha de comando para funcionar!
--print-defaults pode, no entanto, ser usado logo depois dos comandos --defaults-
xxx-file.
Notas para desenvolvedores: O tratamento de arquivos de op¸oes ´e implementado simples-
mente processando todos as op¸oes coincidentes (isto ´e, op¸oes no grupo apropriado) antes
de qualquer argumento da linha de comando. Isto funciona bem para programas que usam
a ´ultima instˆancia de uma op¸ao que ´e especificada diversas vezes. Se vocˆe tem um pro-
grama antigo que trata op¸oes especificadas v´arias vezes desta forma mas n˜ao lˆe arquivos
de op¸oes, vocˆe s´o precisa adicionar duas linhas para lhe dar esta capacidade. Verifique o
odigo fonte de qualquer um dos clientes MySQL padr˜ao para ver como fazer isto.
Nos scripts shell vocˆe pode usar o comando ‘my_print_defaults’ para analisar os arquivos
config:
shell> my_print_defaults client mysql
--port=3306
--socket=/tmp/mysql.sock
--no-auto-rehash
A sa´
ida acima contem todas op¸oes para os grupos ’client’ e ’mysql’.
4.1.3 Instalando V´arios Servidores na Mesma M´aquina
Em alguns casos vocˆe pode precisar de v´arios daemons (servidores) mysqld diferentes ex-
ecutando na mesma m´aquina. Vocˆe pode por exemplo desejar executar uma nova vers˜ao
do MySQL para testar junto com uma vers˜ao mais antiga que est´a em produ¸ao. Outro
caso ´e quando vocˆe quiser dar acesso a diferentes usu´arios em diferentes servidores mysqld
gerenciados por eles mesmos.
194 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Uma maneira de ter um novo servidor executando ´e iniciando-o com um socket e porta
diferentes, como segue:
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/safe_mysqld &
O apˆendice das vari´aveis de ambiente incluem uma lista de outras vari´aveis de ambiente que
vocˆe pode usar e que afetam o mysqld. See hundefinedi[Vari´aveis de ambiente], page hun-
definedi.
A forma descrita acima ´e a maneira mais r´apida e suja que normalmente ´e usado para
testes. A melhor coisa ´e que com isto todas as conex˜oes que vocˆe faz na shell acima ir˜ao
automaticamente ser direcionadas para o novo servidor.
Se vocˆe precisar fazer isto permanentemente, vocˆe deve criar um arquivo de op¸oes para cada
servidor. See hundefinedi[Arquivos de op¸ao], page hundefinedi. No script de inicializa¸ao
que ´e executado no tempo de boot (mysql.server) vocˆe deve especificar ambos os servidores:
safe_mysqld --default-file=path-to-option-file
Pelo menos as seguines op¸oes devem ser diferentes por servidor:
port=#
socket=path
pid-file=path
As seguintes op¸oes devem ser diferentes, se elas forem usadas:
log=path
log-bin=path
log-update=path
log-isam=path
bdb-logdir=path
Se vocˆe precisar de mais performance, vocˆe tamb´em pode diferenciar:
tmpdir=path
bdb-tmpdir=path
See hundefinedi[Op¸oes de linha de comando], page hundefinedi.
Se vocˆe estiver instalando vers˜oes bin´arias do MySQL (arquivos .tar) e inici´a-los
com ./bin/safe_mysql enao na maioria dos casos a ´unica op¸ao que vocˆe precisa
adicionar/alterar s˜ao os argumentos socket eport do safe_mysqld.
4.1.4 Executando M´ultiplos Servidores MySQL na Mesma
aquina
Existem circunstˆancias em que vocˆe pode desejar executar v´arios servidores na mesma
aquina. Por exemplo, vocˆe pode precisar testar um novo release MySQL enquanto deixa
a configura¸ao de sua produ¸ao existente inalterada. Ou voe pode ser um provedor de
servi¸cos de Internet que deseja fornecer instala¸oes independentes de MySQL para clientes
diferentes.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 195
Se vocˆe deseja executar m´ultiplos servidores, a forma mais f´acil ´e compil´a-los com diferentes
portas TCP/IP e arquivos socket para que ambos n˜ao escutem na mesma porta TCP/IP
ou arquivo socket. See hundefinedi[mysqld_multi], page hundefinedi.
Considere que um servidor existente est´a configurado para a porta e arquivo socket padr˜oes.
Enao configure o novo servidor com o comando configure assim:
shell> ./configure --with-tcp-port=n´umero_porta \
--with-unix-socket-path=nome_arquivo \
--prefix=/usr/local/mysql-3.22.9
Aqui umero_porta enome_arquivo deve ser diferente que o n´umero da porta e o caminho
do arquivo socket padr˜oes e o valor --prefix deve especificar um diret´orio de instala¸ao
diferente daquele usado pelo servidor existente.
Voe pode conferir o socket usado por qualquer servidor MySQL em execu¸ao com este
comando:
shell> mysqladmin -h hostname --port=n´umero porta vari´aveis
Se vocˆe especificar “localhost” como o nome da m´aquina, mysqladmin ir´a por padr˜ao usar
sockets Unix no lugar de TCP/IP.
Se vocˆe tem um servidor MySQL executando na porta que vocˆe usou, vocˆe obter´a uma lista
de algumas das vari´aveis configur´aveis mais importantes no MySQL, incluindo o nome do
socket.
ao ´e necess´ario recompilar um novo servidor MySQL apenas para iniciar com uma porta
ou socket diferentes. Voe pode alterar a porta e o socket a ser usado especificando-os no
tempo de execu¸ao como op¸oes para o safe_mysqld:
shell> /path/to/safe_mysqld --socket=nome_arquivo --port=n´umero_porta
mysqld_multi pode tamb´em utilizar o safe_mysqld (ou mysqld) como um argumento e
passar as op¸oes de um arquivo de configura¸c˜ao para o safe_mysqld emysqld.
Se vocˆe executar o novo servidor no mesmo diret´orio do banco de dados que o outro servidor
com o log habilitado, vocˆe tamb´em deve especificar o nome dos arquivos log para o safe_
mysqld com --log,--log-update, ou --log-slow-queries. Se n˜ao, ambos servidores
podem tentar escrever no mesmo arquivo de log.
AVISO: Normalmente vocˆe nunca deve ter dois servidores que atualizam dados no mesmo
banco de dados! Se seu SO n˜ao suporta bloqueio de sistema a prova de falhas, isto pode
provocar surpresas indesej´aveis.
Se vocˆe deseja usar outro diret´orio de banco de dados para o segundo servidor, vocˆe pode
usar a op¸ao --datadir=caminho para o safe_mysqld.
NOTE tamb´em, que iniciando v´arios servidores MySQL (mysqlds) em diferentes m´aquinas
e deix´a-los acessar um diret´orio de dados sob NFS, ´e normalmente uma M´
A ID´
EIA! O
problema ´e que o NFS se tornar´a um gargalo, tornando o sistema lento. Ele n˜ao se destina
para este tipo de uso. E vocˆe ainda n˜ao ter´a como ter certeza que dois ou mais mysqlds
ao est˜ao interferindos uns com os outros. No momento n˜ao existe nenhuma plataforma
que faria, com 100% de seguran¸ca, o bloqueio de arquivos (daemon
Quando vocˆe for conectar a um servidor MySQL que esteja executando com uma porta
diferente daquela que foi compilada no seu cliente, vocˆe pode usar um dos seguintes m´etodos:
196 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Inicie o cliente com --host ’nome_m´aquina’ --port=n´umero_porta para conectar com
TCP/IP, ou [--host localhost] --socket=nome_arquivo para conectar atrav´es de
um socket Unix.
Em programas C ou Perl, vocˆe pode especificar os argumentos de porta ou socket
quando conectar a um servidor MySQL.
Se vocˆe estiver usando o m´odulo Perl DBD::mysql vocˆe pode ler as op¸oes dos arquivos
de op¸oes do MySQL. See hundefinedi[Option files], page hundefinedi.
$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);
Configure as vari´aveis de ambiente MYSQL_UNIX_PORT eMYSQL_TCP_PORT para apontar
para o socket Unix e porta TCP/IP antes de iniciar seus clientes. Se vocˆe normalmente
utiliza uma porta ou socket espec´
ifico, vocˆe deve colocar os comandos para configurar
as vari´aveis de ambiente no arquivo ‘.login’. See hundefinedi[Environment variables],
page hundefinedi.
Especifique o socket e porta TCP/IP padr˜oes no arquivo ‘.my.cnf’ no seu diret´orio
home. See hundefinedi[Option files], page hundefinedi.
4.2 Detalhes Gerais de Seguran¸ca e o Sistema de Acesso
O MySQL tem um sistema de seguran¸ca/privil´egios avan¸cado mas n˜ao padr˜ao. A pr´oxima
se¸ao descreve como ele funciona.
4.2.1 Seguran¸ca Geral
Qualquer um usando o MySQL em um computador conectado `a internet deve ler esta se¸ao
para evitar os erros de seguran¸ca mais comuns.
Discutindo seguran¸ca, n´os enfatizamos a a necessidade de proteger completamente o servi-
dor (n˜ao simplesmente o servidor MySQL) contra todos os tipos de ataques aplic´aveis:
eavesdropping, altering, playback e denial of service. ao cobriremos todos os aspectos de
disponibilidade e tolerˆancia a falhas aqui.
O MySQL utiliza a seguran¸ca baseado em Listas de Controle de Acesso (ACL) para todas
conex˜oes, consultas e outras opera¸oes que um usu´ario pode tentar realizar. Existe tamb´em
algum suporte para conex˜oes criptografadas SSL entre clientes MySQL e servidores. arios
dos conceitos discutidos aqui n˜ao s˜ao espec´
ificos do MySQL; as mesmas id´eias podem ser
aplicadas para a maioria das aplica¸oes.
Quando executando o MySQL, siga estes procedimentos sempre que poss´
ivel:
NUNCA CONCEDA A ALGU´
EM (EXCETO AO USU ´
ARIO ROOT DO MySQL)
ACESSO TABELA user NO BANCO DE DADOS mysql! A senha criptografada
´e a senha real no MySQL. Se vocˆe conhece a senha listada na tabela user para um
determinado usu´ario, vocˆe pode facilmente logar como este usu´ario se tiver acesso `a
aquina relacionada para aquela conta.
Aprenda o sistema de controle de acessos do MySQL. Os comandos GRANT eREVOKE
ao usados para controlar o acesso ao MySQL. N˜ao conceda mais privil´egios do que o
necess´ario. Nunca conceda privil´egios para todas as m´aquinas.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 197
Checklist:
Tente mysql -u root. Se vocˆe conseguir conectar com sucesso ao servidor sem
a solicita¸ao de uma senha, voe tem problemas. Qualquer um pode conectar
ao seu servidor MySQL como o usu´ario root com privil´egios plenos! Revise as
instru¸oes de instala¸ao do MySQL, prestando aten¸ao particularmente ao item
sobre configura¸ao da senha do usu´ario root.
Utilize o comando SHOW GRANTS e confira para ver quem tem acesso a o que. Re-
mova aqueles privil´egios que n˜ao s˜ao necess´arios utilizando o comando REVOKE.
ao 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´a-las. No lugar utilize a fun¸ao MD5() ou qualquer fun¸c˜ao de embaralhamento de
via ´unica.
ao escolha senhas de dicion´arios. Existem programas especiais para quebr´a-las.
Mesmo senhas como “xfish98” n˜ao sao boas. Muito melhor seria “duag98” que cont´em
a mesma palavra ’fish mas digitada uma letra a esquerda em um teclado QWERTY
convencional. Outro m´etodo seria usar “Mhall” que ´e obtido dos primeiros caracteres
de cada palavra na frase “Mary has a litle lamb”. Isto ´e f´acil de lembrar e digitar, mas
dificulta que algu´em que n˜ao a conhe¸ca a advinhe.
Invista em um firewall. Ele protege vocˆe de pelo menos 50% de todos os tipos de
exploits em qualquer software. Coloque o MySQL atr´as 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˜ao. Esta porta n˜ao deve ser acess´
ivel
para m´aquinas n˜ao confi´aveis. Outra maneira simples para conferir se sua porta
do MySQL est´a aberta ou n˜ao ´e tentar o seguinte comando de alguma m´aquina
remota, onde nome_m´aquina ´e o nome da m´aquina ou o endere¸co IP de seu servidor
MySQL:
shell> telnet nome_m´aquina 3306
Se vocˆe obter uma conex˜ao e alguns caracteres, a porta est´a aberta e deve ser
fechada no seu firewall ou roteador, a menos que vocˆe realmente tenha uma boa
raz˜ao para mantˆe-la aberta. Se o telnet apenas parar ou a conex˜ao for recusada,
tudo est´a bem; a porta est´a bloqueada.
ao confie em nenhum dado inclu´
idos pelos seus usu´arios. Eles podem tentar enganar
seu c´odigo entrando com caracteres especiais ou sequencias de escape nos formul´arios
Web, URLS ou qualquer aplica¸ao que vocˆe construa. Tenha certeza que sua aplica¸ao
continua segura se um usu´ario entrar com algo do tipo “; DROP DATABASE mysql;”.
Este ´e um exemplo extremo, mas grandes falhas de seguran¸ca ou perda de dados podem
ocorrer como o resultado de hackers utilizando t´ecnicas similares, se vocˆe n˜ao estiver
preparado para eles.
Tamb´em lembre de conferir dados num´ericos. Um erro comum ´e proteger somente as
strings. Em alguns casos as pessoas pensam que se um banco de dados cont´em somente
dados dispon´
iveis publicamente, ele n˜ao precisa ser protegido. Isto n˜ao ´e verdade. No
m´
inimo ataques do tipo denial-of-service podem ser feitos nestes bancos de dados. A
maneira mais simples para proteger deste tipo de ataque ´e usar ap´ostrofos em torno
198 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
das contantes num´ericas: SELECT * FROM tabela WHERE ID=’234’ em vez de SELECT *
FROM table WHERE ID=234. O MySQL automaticamente converte esta string para um
n´umero e corta todos os s´
imbolos n˜ao-num´ericos dela.
Checklist:
Todas aplica¸oes Web:
Tente inserir ‘’e‘"’ em todos seus formul´arios Web. Se vocˆe obter qualquer
tipo de erro do MySQL, investigue o problema imediatamente.
Tente modificar qualquer URL dinˆamica adicionando %22 (‘"’), %23 (‘#’) e %27
(‘’) na URL.
Tente modificar os tipos de dados nas URLs dinˆamicas de nuerico para
caractere contendo caracteres dos exemplos anteriores. Sua aplica¸ao deve ser
segura contra estes ataques e similares.
Tente inserir caracteres, espa¸cos e s´
imbolos especiais no lugar de n´umero nos
campos num´ericos. Sua aplica¸ao deve removˆe-los antes de pass´a-los para o
MySQL ou sua aplica¸ao deve gerar um erro. Passar valores n˜ao verificados
ao MySQL ´e extramente perigoso!
Confira o tamanho dos dados antes de pass´a-los ao MySQL.
Considere ter sua aplica¸ao conectando ao banco de dados utilizando um
usu´ario diferente doq ue o que ´e utilizado com prop´ositos administrativos.
ao forne¸ca `as suas aplica¸oes mais privil´egios de acesso do que elas necessi-
tam.
Usu´arios do PHP:
Confira a fun¸ao addslashes. No PHP 4.0.3, uma fun¸ao mysql_escape_
string() est´a dispon´
ivel e ´e baseada na fun¸ao com o mesmo nome da API
C do MySQL.
Usu´arios do API C do MySQL:
Confira a chamada API mysql_escape_string().
Usu´arios do MySQL:
Confira os modificadores escape equote para consultas streams.
Usu´arios do Perl DBI:
Confira o m´etodo quote() ou utilize aspas simples ou duplas.
Usu´arios do Java JDBC:
Utilize um objeto PreparedStatement e aspas simples ou duplas.
ao transmita dados sem criptografia na Internet. Estes dados s˜ao acess´
iveis para
todos que tenham o tempo e habilidade para intercept´a-lo e us´a-lo para seu prop´osito
pr´oprio. No lugar, utilize um protocolo de criptografia como o SSL ou SSH. O MySQL
suporta conex˜oes SSL interno desde a vers˜ao 3.23.9. O repasse de portas do SSH pode
ser usado para criar um tunel criptografado (e com compress˜ao) para a comunica¸ao.
Aprenda a usar os utilit´arios tcpdump estrings. Para a maioria dos casos vocˆe
pode conferir se o fluxo de dados do MySQL est´a ou n˜ao criptografado utilizando um
comando parecido com este:
shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
Chapter 4: Administra¸ao de Bancos de Dados MySQL 199
(Isto funciona sobre Linux e deve funcionar com pequenas modifica¸oes sob outros
sistemas.) Alerta: Se vocˆe n˜ao ver dados n˜ao significa sempre que esteja criptografado.
Se vocˆe necessita de alta seguran¸ca, vocˆe deve consultar um especialista em seguran¸ca.
4.2.2 Como Tornar o MySQL Seguro contra Crackers
Quando vocˆe conectar a um servidor MySQL, vocˆe normalmente deve usar uma senha. A
senha n˜ao ´e transmitida em texto puro sobre a conex˜ao, por´em o algor´
itimo de criptografica
ao ´e muito forte e com algum esfor¸co um atacante engenhoso pode quebrar a senha se ele
conseguir capturar o tr´afego entre o cliente e o servidor. Se a conex˜ao entre o cliente e o
servidor passar por uma rede n˜ao confi´avel, vocˆe deve usar um tunnel SSH para criptografar
a comunica¸ao.
Todas outras informa¸oes s˜ao transferidas como texto que podem ser lido por qualquer um
que consiga ver a conex˜ao. Se vocˆe se preocupa com isto, vocˆe pode usar o protocol de
compress˜ao (No MySQL vers˜ao 3.22 e superiores) para dificultar um pouco as coisas. Para
deixar tudo ainda mais seguro vocˆe deve usar ssh. Voe 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ˆe pode obter uma conex˜ao TCP/IP critografada entre um servidor MySQL e
um cliente MySQL.
Para deixar um sistema MySQL seguro, vocˆe deve considerar as seguintes sugest˜oes:
Utilize senhas para todos os usu´arios MySQL. Lembre-se que qualquer um pode logar
como qualquer outra pessoa simplesmente com mysql -u outro_usu´ario nome_bd se
outro_usu´ario ao tiver senha. Isto ´e um procedimento comum com aplica¸oes
cliente/servidor que o cliente pode especificar qualquer nome de usu´ario. Voe pode
alterar a senha de todos seus usu´arios editando o script mysql_install_db antes de
execut´a-lo ou somente a senha para o usu´ario root do MySQL desta forma:
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD(’nova_senha’)
WHERE user=’root’;
mysql> FLUSH PRIVILEGES;
ao execute o daemon do MySQL como o usu´ario root do Unix. Isto ´e muito perigoso,
porque qualquer usu´ario com privil´egios FILE estar´a apto a criar arquivos como o root
(por exemplo, ~root/.bashrc). Para prevenir esta situa¸ao, mysqld ir´a recusar a
execu¸ao como root a menos que ele seja especificado diretamente usando a op¸ao
--user=root.
Omysqld pode ser executado como um usu´ario normal sem privil´egios. Voe pode
tamb´em criar um novo usu´ario Unix mysql para tornar tudo mais seguro. Se vocˆe
executar o mysqld como outro usu´ario Unix, vocˆe n˜ao precisar´a alterar o usu´ario root
na tabela user, porque nomes de usu´ario do MySQL n˜ao tem nada a ver com nomes
de usu´arios Unix. Para iniciar o mysqld como outro usu´ario Unix, adicione uma linha
user que especifica o nome de usu´ario para o grupo [mysqld] do arquivo de op¸oes
/etc/my.cnf’ ou o arquivo de op¸oes ‘my.cnf’ no diret´orio de dados do servidor. Por
exemplo:
[mysqld]
user=mysql
200 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Estas op¸oes configuram o servidor para iniciar como o usu´ario designado quando vocˆe o
inicia manualmente ou usando safe_mysqld ou mysql.server. Para maiores detalhes,
veja hundefinedi[Changing MySQL user], page hundefinedi.
ao suportar links simolicos para tabelas (Isto pode ser desabilitado com a op¸ao --
skip-symlink. Isto ´e muito importante caso voe execute o mysqld como root, assim
qualquer um que tenha acesso `a escrita aos dados do diret´orio do mysqld podem apagar
qualquer arquivo no sistema! See hundefinedi[Symbolic links to tables], page hunde-
finedi.
Verfique se o usu´ario Unix que executa o mysqld ´e o ´unico usu´ario com privil´egios de
leitura/escrita nos diret´orios de bancos de dados.
ao forne¸ca o privil´egio process para todos os usu´arios. A sa´
ida de mysqladmin
processlits mostra as consultas atualmente em execu¸ao, portanto qualquer usu´ario
que consiga executar este comando deve ser apto a ver se outro usu´ario entra com uma
consulta do tipo UPDATE user SET password=PASSWORD(’n~ao_seguro’).
Omysqld reserva uma conex˜ao extra para usu´arios que tenham o privil´egio process,
portanto o usu´ario root do MySQL pode logar e verificar alguns detalhes mesmo se
todas as conex˜oes normais estiverem em uso.
ao conceda o privil´egio file a todos os usu´arios. Qualquer usu´ario que possua este
privil´egio pode gravar um arquivo em qualquer lugar no sistema de arquivos com os
privil´egios do daemon mysqld! Para tornar isto um pouco mais seguro, todos os ar-
quivos gerados com SELECT ... INTO OUTFILE ao lidos por todos, e n˜ao se pode so-
brescrever arquivos existentes.
O privil´egio file pode tamb´em ser usado para ler qualquer arquivo acess´
ivel para o
usu´ario Unix com o qual o servidor est´a sendo executado. Pode ocorrer abusos como,
por exemplo, usar LOAD DATA para carregar o arquivo ‘/etc/passwd’ em uma tabela,
que pode enao ser lido com SELECT.
Se vocˆe n˜ao confia em seu DNS, vocˆe deve utilizar n´umeros IP no lugar de nomes de
aquinas nas tabelas de permiss˜ao. De qualquer forma, vocˆe deve ter muito cuidado
ao criar entradas de concess˜ao utilizando valores de nomes de m´aquinas que contenham
metacaractes!
Se vocˆe deseja restrigir o n´umero de conex˜oes para um ´unico usu´ario, vocˆe pode faze-lo
configurando a vari´avel max_user_connections no mysqld.
4.2.3 Op¸oes de Inicializa¸ao para o mysqld em Rela¸ao a
Seguran¸ca.
As seguintes op¸oes do mysqld afetam a seguran¸ca:
--safe-show-database
Com esta op¸ao, SHOW DATABASES retorna somente os bancos de dados nos quais
o usu´ario tem algum tipo de privil´egio.
--safe-user-create
Se for habilitado, um usu´ario n˜ao consegue criar novos usu´arios com o comando
GRANT, se o usu´ario n˜ao tiver privil´egio de INSERT na tabela mysql.user. Se
vocˆe desejar fornecer a um usu´ario acesso para s´o criar novos usu´arios com
Chapter 4: Administra¸ao de Bancos de Dados MySQL 201
privil´egios que o usu´ario tenha direito a conceder, vocˆe deve dar ao usu´ario o
seguinte privil´egio:
GRANT INSERT(user) on mysql.user to ’usuarior’´
hostname’;
Isto ir´a assegurar que o usu´ario n˜ao poder´a alterar nenhuma coluna de
privil´egios diretamente, mas tem que usar o comando GRANT para conceder
direitos para outros usu´arios.
--skip-grant-tables
Esta op¸ao desabilita no servidor o uso do sistema de privil´egios. Isto d´a a
todos os usu´arios acesso total a todos os bancos de dados! (Voe pode dizer a
um servidor em execu¸ao para para uar as tabelas de permiss˜oes executando
mysqladmin flush-privileges ou mysqladmin reload.)
--skip-name-resolve
Nomes de m´aquinas n˜ao s˜ao resolvidos. Todos os valores da coluna Host nas
tabelas de permiss˜oes devem ser n´umeros IP ou localhost.
--skip-networking
ao permitir conex˜oes TCP/IP sobre a rede. Todas as conex˜oes para mysqld
devem ser feitas via Sockets Unix. Esta op¸ao n˜ao ´e poss´
ivel em sistemas que
usam MIT-pthreads, porque o pacote MIT-pthreads n˜ao suporta sockets Unix.
--skip-show-database
Com esta op¸ao a instru¸ao SHOW DATABASES ao retorna nada.
4.2.4 O Que o Sistema de Privil´egios Faz
A fun¸ao prim´aria do sistema de privil´egios do MySQL ´e autenticar um usu´ario a partir de
uma determinada m´aquina e associar este usu´ario com privil´egios a banco de dados como
como select,insert,update edelete.
Funcionalidades adicionais incluem a habilidade de ter um usu´ario anˆonimo e conceder
privil´egio para fun¸oes espec´
ificas do MySQL como em LOAD DATA INFILE e opera¸oes ad-
ministrativas.
4.2.5 Como o Sistema de Privil´egios Funciona
O Sistema de privil´egios do MySQL garante que todos usu´arios possam fazer exatamente
aquilo que ´e permitido. Quando vocˆe conecta a um servidor MySQL, sua identidade ´e
determinada pela maquina de onde voe conectou eo nome de usu´ario que vocˆe especificou.
O sistema concede privil´egios de acordo com sua identidade e com o que voe deseja fazer.
O MySQL considera tanto os nomes de m´aquinas como os nomes de usu´arios porque existem
poucas raz˜oes para assumir que um determinado nome de usu´ario pertence a mesma pessoa
em todo lugar na Internet. Por exemplo, o usu´ario bill que conecta de whitehouse.gov ao
deve necessariamente ser a mesma pessoa que o usu´ario bill que conecta da microsoft.com
O MySQL lida com isto, permitindo a distin¸ao de usu´arios em diferentes m´aquinas que
podem ter o mesmo nome: Voe pode conceder a bill um conjunto de privil´egios para
conex˜oes de whitehouse.gov e um conjunto diferente de privil´egios para conex˜oes de
microsoft.com.
O controle de acesso do MySQL ´e composto de dois est´agios:
202 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1o Est´agio: O servidor confere se vocˆe pode ter acesso ou n˜ao.
2o. Est´agio: Assumindo que vocˆe pode conectar, o servidor verifica cada requisi¸ao
feita para saber se vocˆe tem ou n˜ao privil´egios suficientes para realizar a opera¸ao.
Por exemplo, se vocˆe 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ˆe tem o privil´egio
select para a tabela ou o privil´egio drop para o banco de dados.
O servidor utiliza as tabelas user,db ehost no banco de dados mysql em ambos est´agios
do controle de acesso. Os campos nestas tabelas de permiss˜ao s˜ao detalhados abaixo:
Nome da Tabela User db host
Campos de escopo Host Host Host
User Db Db
Password User
Cmapos de
privil´egio
Select_priv Select_priv Select_priv
Insert_priv Insert_priv Insert_priv
Update_priv Update_priv Update_priv
Delete_priv Delete_priv Delete_priv
Index_priv Index_priv Index_priv
Alter_priv Alter_priv Alter_priv
Create_priv Create_priv Create_priv
Drop_priv Drop_priv Drop_priv
Grant_priv Grant_priv Grant_priv
References_priv
Reload_priv
Shutdown_priv
Process_priv
File_priv
No segundo est´agio do controle de acesso (verifica¸ao da solicita¸ao), o servidor pode, se a
solicita¸ao involver tabelas, consultar adicionalmente as tabelas tables_priv ecolumns_
priv. Os campos nestas tabelas s˜ao mostrados abaixo:
Nome da tabela tables_priv columns_priv
Campos de
escopop
Host Host
Db Db
User User
Table_name Table_name
Column_name
Campos de
privil´egio
Table_priv Column_priv
Column_priv
Outros campos Timestamp Timestamp
Grantor
Cada tabela de permiss˜oes contˆem campos de escopo e campos de privil´egios.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 203
Campos de escopo determinam o escopo de cada entrada nas tabelas, isto ´e, o contexto
no qual a entrada se aplica. Por exemplo, uma entrada na tabela user com valores Host
eUser de ’thomas.loc.gov’ e’bob’ devem ser usados para autenticar conex˜oes feitas
ao servidor por bob da m´aquina thomas.loc.gov. De maneira similar, uma entrada na
tabela db com campos Host,User eDb de ’thomas.loc.gov’,’bob’ e’reports’ devem
ser usados quando bob conecta da m´aquina thomas.loc.gov para acessar o banco de dados
reports. As tabelas tables_priv ecolumns_priv contem campos de escopo indicando as
combina¸oes de tabelas ou tabela/coluna para o qual cada entrada se aplica.
Para prop´ositos de verifica¸ao de acessos, compara¸oes de valores Host ao caso insensitivo,
valores User,Password,Db eTable_name ao caso sensitivo. Valores Column_name ao caso
insensitivo no MySQL vers˜ao 3.22.12 ou posterior.
Campos de privil´egios indicam os privil´egios concedidos por uma entrada na tabela, isto ´e,
quais opera¸oes podem ser realizadas. O servidor combina as informa¸oes de v´arias tabelas
de concess˜ao para formar uma descri¸ao completa dos privil´egios de um usu´ario. As regras
usadas para fazer isto s˜ao descritas em hundefinedi[Request access], page hundefinedi.
Campos de escopo s˜ao strings, declaradas como mostrado abaixo; os valores padr˜ao para
cada ´e a string vazia:
Nome do
Campo
Tipo
Host CHAR(60)
User CHAR(16)
Password CHAR(16)
Db CHAR(64) (CHAR(60) para as tabelas tables_priv ecolumns_priv)
Table_name CHAR(60)
Column_name CHAR(60)
Nas tabelas user,db ehost, todos campos de privil´egios s˜ao declarados como
ENUM(’N’,’Y’) --- cada um pode ter um valor de ’N’ ou ’Y’ e o valor padr˜ao ´e ’N’.
Nas tabelas tables_ ecolumns_priv, os campos de privil´egios s˜ao declarados como campos
SET:
Nome da Tabela Nome Campo Poss´
iveis elementos do conjunto
tables_priv Table_priv ’Select’, ’Insert’, ’Update’, ’Delete’,
’Create’, ’Drop’, ’Grant’, ’References’,
’Index’, ’Alter’
tables_priv Column_priv ’Select’, ’Insert’, ’Update’, ’References’
columns_priv Column_priv ’Select’, ’Insert’, ’Update’, ’References’
De maneira resumida, o servidor utiliza as tabelas de permiss˜oes desta forma:
Os campos de escopo da tabela user determinam quando permitir ou aceitar conex˜oes.
Para conex˜oes permitidas, qualquer privil´egio concedido em uma tabela user indica
o privil´egio global (superusu´ario) do usu´ario. Estes privil´egios se aplicam a todos os
bancos de dados no servidor.
As tabelas db ehost ao usadas juntas:
Os campos de escopo da tabela db determinam quais usu´arios podem acessar de-
terminados bancos de dados de m´aquinas determinadas. Os campos de privil´egios
determinam quais opera¸oes s˜ao permitidas.
204 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A tabela host ´e usada como uma extens˜ao da tabela db quando vocˆe quer que
uma certa entrada na tabela db seja aplicada a diversas m´aquinas. Por exemplo,
se vocˆe deseja que um usu´ario esteja apto a usar um banco de dados a partir de
diversas m´aquinas em sua rede, deixe o campo Host vazio no registro da tabela
db, ent˜ao popule a tabela Host com uma entrada para cada uma das m´aquinas.
Este mecanismo ´e descrito com mais detalhes em hundefinedi[Request access],
page hundefinedi.
As tabelas tables_priv ecolumns_priv ao similares `a tabela db, por´em s˜ao mais
finas: Elas se aplicam ao n´
ivel de tabelas e colunas em vez do n´
ivel dos bancos de
dados.
Perceba que os privil´egios administrativos (reload,shutdown e etc) s˜ao especificados so-
mente na tabela user. Isto ocorre porque opera¸oes administrativas s˜ao opera¸oes no
pr´oprio servidor e n˜ao s˜ao espec´
ificas e n˜ao espec´
ificas dos bancos de dados, portanto n˜ao
existe raz˜ao para listar tais privil´egios nas outras tabelas de permiss˜ao. De fato, somente
a tabela user necessita ser consultada para determinar se vocˆe pode ou n˜ao realizar uma
opera¸ao administrativa.
O privil´egio file tamb´em s´o ´e especificado na tabela user. Ele n˜ao ´e um privil´egio admin-
istrativo, mas sua habilidade para ler ou escrever arquivo no servidor ´e independtende do
banco de dados que vocˆe est´a acessando.
O servidor mysqld le o conte´udo das tabelas de permiss˜oes uma vez, quando ´e iniciado.
Altera¸oes nas tabelas de permiss˜oes tem efeito como indicado em hundefinedi[Privilege
changes], page hundefinedi.
Quando vocˆe modifica o conte´udo das tabelas de permiss˜oes, ´e uma boa id´eia ter certeza que
suas altera¸oes configuraram os privil´egios da forma desejada. Para ajuda no diagnostico
de problemas, veja hundefinedi[Access denied], page hundefinedi. Para conselhos sobre
asssuntos de seguran¸ca, See hundefinedi[Security], page hundefinedi.
Uma ferramenta de diagn´ostico ´util ´e o script mysqlaccess, que Yves Carlier fornece na
distribui¸ao MySQL. Chame mysqlaccess com a op¸ao --help para descobrir como ele
funciona. Perceba que o mysqlaccess confere o acesso usando somente as tabelas user,db
ehost. Ele n˜ao confere privil´egios no n´
ivel de tabelas ou colunas.
4.2.6 Privil´egios Fornecidos pelo MySQL
Informa¸oes sobre privil´egios de usu´arios s˜ao armazenados nas tabelas user,db,host,
tables_priv ecolumns_priv no banco de dados chamado mysql. O servidor MySQL lˆe o
conte´udo destas tabelas quando ele inicia e sob as circunstˆancias indicadas em hundefinedi
[Privilege changes], page hundefinedi.
Os nomes usados neste manual que se referem-se aos privil´egios fornecidos pelo MySQL s˜ao
vistos abaixo juntos com o nome da coluna associada com cada privil´egio nas tabelas de
permiss˜ao e o contexto em que o privil´egio aplica-se:
Privil´egio Coluna Contexto
select Select_priv tabelas
insert Insert_priv tabelas
update Update_priv tabelas
delete Delete_priv tabelas
Chapter 4: Administra¸ao de Bancos de Dados MySQL 205
index Index_priv tabelas
alter Alter_priv tabelas
create Create_priv bancos de dados, tabelas, ou ´
indices
drop Drop_priv bancos de dados ou tabelas
grant Grant_priv bancos de dados ou tabelas
references References_priv bancos de dados ou tabelas
reload Reload_priv administra¸ao do servidor
shutdown Shutdown_priv administra¸ao do servidor
process Process_priv administra¸ao do servidor
file File_priv acesso `a arquivos no servidor
Os privil´egios select,insert,update edelete permitem realizar opera¸oes em registros nas
tabelas existentes em um banco de dados.
Instru¸oes SELECT necessitam do privil´egio select somente se ele precisar recuperar registros
de uma tabela. Vocˆe pode executar certas instru¸oes SELECT mesmo sem permiss˜ao para
acessar algum dos bancos de dados no servidor. Por exemplo, vocˆe pode usar o cliente
mysql como uma simples calculadora:
mysql> SELECT 1+1;
mysql> SELECT PI()*2;
O privil´egio index permite a cria¸ao ou remo¸ao de ´
indices.
O privil´egio alter permite utilizar ALTER TABLE.
Os privil´egios create edrop permitem a cria¸ao de novos bancos de dados e tabelas, ou a
remo¸ao de bancos de dados e tabelas existentes.
Perceba que se for concedido o privil´egio drop no banco de dados mysql para algum usu´ario,
este usu´ario pode remover o banco de dados no qual os privil´egios de acesso do MySQL
est˜ao armazenados!
O privil´egio grant permite a vocˆe fornecer a outros usu´arios os privil´egios que vocˆe mesmo
possui.
O privil´egio file fornece permiss˜ao para ler e escrever arquivos no servidor usando instru¸oes
LOAD DATA INFILE eSELECT ... INTO OUTFILE. Qualquer usu´ario que tenha este privil´egio
pode ler ou gravar qualquer arquivo que o servidor MySQL possa ler ou escrever.
Os privil´egios restantes s˜ao usados para opera¸oes administrativas, que s˜ao realizadas uti-
lizando o programa mysqladmin. A tabela abaixo mostra quais comandos do mysqladmin
cada privil´egio administrativos permite a execu¸ao:
Privil´egio Comandos permitidos
reload reload,refresh,flush-privileges,flush-hosts,flush-logs eflush-
tables
shutdown shutdown
process processlist,kill
O comando reload diz ao servidor para recarregar as tabelas de permiss˜oes. O comando
refresh descarrega todas as tabelas e abre e fecha os arquivos de log. flush-privileges
´e um sinˆonimo para reload. Os outros comandos flush-* realizam fun¸oes similares ao
refresh mas s˜ao mais limitados no escopo e podem ser prefer´
iveis em alguns casos. Por
exemplo, se vocˆe deseja descarregar apenas os arquivos log, flush-logs ´e uma melhor
escolha do que refresh.
206 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O comando shutdown desliga o servidor.
O comando processlist mostra informa¸oes sobre as threads em execu¸ao no servidor.
O comando kill mata threads no servidor. Voe sempre poder´a mostrar ou matar suas
pr´oprias threads, mas vocˆe precisa do privil´egio process para mostrar ou matar threads
iniciadas por outros usu´arios. See hundefinedi[KILL], page hundefinedi
´
E uma boa id´eia em geral conceder privil´egios somente para aqueles usu´arios que necessitem
deles, mas vocˆe deve ter muito cuidado ao conceder certos privil´egios:
O privil´egio grant permite aos usu´arios repassarem seus privil´egios a outros usu´arios.
Dois usu´arios com diferentes privil´egios e com o privil´egio grant conseguem combinar
seus privil´egios.
O privil´egio alter pode ser usado para subverter o sistema de privil´egios renomeando
as tabelas.
O privil´egio file pode ser usado com abuso para ler qualquer arquivo de leitura no
servidor em uma tabela de banco de dados, o conte´udo pode ser acessando utilizando
SELECT. Isto inclui o conte´udo de todos os bancos de dados hospedados pelo servidor!
O privil´egio shutdown pode ser utilizado para negar inteiramente servi¸cos para oturos
usu´arios, terminando o servidor.
O privil´egio process pode ser usado para ver o texto das consultas atualmente em
execu¸ao, incluindo as consultas que configuram ou alteram senhas.
Privil´egios no banco de dados mysql pode ser utilizado para alterar senhas e outras
informa¸oes de privil´egio de acesso. (Senhas s˜ao armazenadas criptografadas, portanto
um usu´ario malicioso n˜ao pode simplesmente lˆe-las para saber as senhas em texto puro).
Se fosse poss´
ivel acessar a coluna password do banco mysql.user, seria poss´
ivel logar
ao servidor MySQL como outro usu´ario. (Com privil´egios suficientes, o mesmo usu´ario
pode trocar a senha por outra diferente.)
Existema algumas coisas que vocˆe n˜ao pode fazer com o sistem de privil´egios do MySQL:
Voe n˜ao pode especificar explicitamente que um determinado usu´ario deve ter acesso
negado. Voe n˜ao pode explicitamente comparar um usu´ario e depois recusar sua
conex˜ao.
Voe n˜ao pode especificar que um usu´ario tenha privil´egios para criar ou remover
tabelas em um banco de dados, mas n˜ao possa criar ou remover o banco de dados.
4.2.7 Conectando ao Servidor MySQL
Programas clientes do MySQL geralmente necessitam de parˆametros de conex˜ao quando
vocˆe precisar acessar um servidor MySQL: a m´aquina na qual vocˆe deseja se conectar, seu
nome de usu´ario e sua senha. Por exemplo, o cliente mysql pode ser iniciado desta forma
(argumentos opcionais s˜ao colocandos entre ‘[’ e ‘]’):
shell> mysql [-h nome_m´aquina] [-u nome_usu´ario] [-psua_senha]
Formas alternativas das op¸oes -h,-u e-p ao --host=nome_m´aquina,--user=nome_
usu´ario e--password=sua_senha. Perceba que n˜ao existe espco entre -p ou --password=
e a senha que deve vir a seguir.
NOTA: Especificar a senha na linha de comando n˜ao ´e seguro! Qualquer usu´ario no seus
sistema pode saber sua senha digitando um comando do tipo: ps auxww. See hundefinedi
[Option files], page hundefinedi.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 207
Omysql utiliza valores padr˜ao para parˆametros de conex˜ao que n˜ao s˜ao passados pela linha
de comando:
O nome padr˜ao da m´aquina (hostname) ´e localhost.
O nome de usu´ario padr˜ao ´e o mesmo nome do seu usu´ario no Unix.
Nenhuma senha ´e fornecida se faltar o parˆametro -p.
Enao, para um usu´ario Unix joe, os seguintes comandos s˜ao 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ˆe pode especificar valores padr˜oes diferentes para serem usados
quendo vocˆe faz uma conex˜ao, assim vocˆe n˜ao precisa digit´a-los na linha de comando sempre
que chamar o programa cliente. Isto pode ser feito de v´arias maneiras:
Podem ser especificados parˆametros de conex˜ao na se¸ao [client] do arquivo de con-
figura¸ao ‘.my.cnf’ no seu diret´orio home. A sao relevante do arquivo deve se parecer
com isto:
[client]
host=nome_m´aquina
user=nome_usu´ario
password=senha_usu´ario
See hundefinedi[Option files], page hundefinedi.
Voe pode especificar parˆametros de conex˜ao utilizando vari´aveis de ambiente. O nome
de m´aquina pode ser especificado para o mysql utilizando a vari´avel MYSQL_HOST. O
nome do usu´ario MySQL pode ser especificado utilizando USER (isto ´e somente para
Windows). A senha pode ser especificada utilizando MYSQL_PWD (mas isto n˜ao ´e seguro;
veja a pr´oxima se¸ao). See hundefinedi[Environment variables], page hundefinedi.
4.2.8 Controle de Acesso, Est´agio 1: Verifica¸ao da Conex˜ao
Quando vocˆe tenta se conectar a um servidor MySQL, o servidor aceita ou rejeita a conex˜ao
baseado na sua identidade e se pode ou n˜ao verificar sua identidade fornecendo a senha
correta. Sen˜ao, o servidor nega o acesso a vocˆe completamente. De outra forma, o servidor
aceita a conex˜ao, entra no est´agio 2 e espera por requisi¸ci˜oes.
Sua identidade ´e baseada em duas partes de informa¸ao:
A m´aquina de onde est´a conectando
Seu nome de usu´ario no MySQL
A conferˆencia da identidade ´e feita utilizando os tres campos de escopo da tabela user
(Host,User ePassword). O servidor aceita a conex˜ao somente se uma entrada na tabela
user coincidir com a m´aquina, nome de usu´ario 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´aquina ou um n´umero IP ou ’localhost’ para
indicar a m´aquina local.
208 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Voe pode utilizar os metacaracteres ‘%’ e ‘_’ no campo Host.
Um valor Host de ’%’ coincide com qualquer nome de m´aquina.
Um valor Host em branco significa que o privil´egio deve ser adicionado com a entrada
na tabela host que coincide com o nome de m´aquina fornecido. Vocˆe pode encontrar
mais informa¸oes sobre isto no pr´oximo cap´
itulo.
Como no MySQL Vers˜ao 3.23, para valores Host especificados como n´umeros IP, vocˆe
pode especificar uma m´ascara de rede indicando quantos bits de endere¸co ser˜ao usados
para o n´umero da rede. Por exemplo:
GRANT ALL PRIVILEGES on db.* to david@’192.58.197.0/255.255.255.0’;
Isto permitir´a que todos a se conectarem a partir de determinado IP cuja condi¸ao
seguinte seja verdadeira:
IP_usu´ario & m´ascara_rede = ip_maquina.
No exemplo acima todos IPs no Intervalo 192.58.197.0 - 192.58.197.255 podem se conec-
tar ao servidor MySQL.
Metacaracteres n˜ao s˜ao permitidos no campo User, mas vocˆe pode especificar um valor
em branco, que combina com qualquer nome. Se a entrada na tabela user que casa com
uma nova conex˜ao tem o nome do usu´ario em branco, o usu´ario ´e considerado como
um usu´ario anˆonimo (o usu´ario sem nome), em vez do nome que o cliente especificou.
Isto significa que um nome de usu´ario em branco ´e usado para todos as verifica¸oes de
acessos durante a conex˜ao. (Isto ´e, durante o est´agio 2).
O campo Password pode ficar em branco. O que n˜ao significa que qualquer senha possa
ser usada, significa que o usu´ario deve conectar sem especificar uma senha.
Valores de Password que n˜ao est˜ao em branco s˜ao apresentados como senhas criptografadas.
O MySQL n˜ao armazena senhas na forma de texto puro para qualquer um ver. Em vez disso,
a senha fornecida por um usu´ario que est´a tentando se conectar ´e criptografada (utilizando a
fun¸ao PASSWORD()). A senha criptografada ´e ent˜ao usada quando o cliente/servidor estiver
conferindo se a senha ´e correta (Isto ´e feito sem a senha criptografada sempre trafegando
sobre a conex˜ao.) Perceba que do ponto de vista do MySQL a senha criptografada ´e a
senha REAL, portanto vocˆe n˜ao deve pass´a-la para ningu´em! Em particular, n˜ao forne¸ca a
usu´arios normais acesso de leitura para as tabelas no banco de dados mysql!
Os exemplos abaixo mostram v´arias combina¸oes de valores de Host eUser nos registros
da tabela user aplicando a novas conex˜oes:
Valor em host Valor em user Conex˜oes casadas com o registro
’thomas.loc.gov’ ’fred’ fred, conectando de thomas.loc.gov
’thomas.loc.gov’ ’’ Qualquer usu´ario, conectando de
thomas.loc.gov
’%’ ’fred’ fred, conectando a partir de qualquer m´aquina
’%’ ’’ Qualquer usu´ario, conectando a partir de qual-
quer m´aquina
’%.loc.gov’ ’fred’ fred, conectando de qualquer m´aquina do
dom´
inio loc.gov
’x.y.%’ ’fred’ fred, conectando de x.y.net,
x.y.com,x.y.edu, etc. (Isto provavel-
mente ao ´e ´util)
Chapter 4: Administra¸ao de Bancos de Dados MySQL 209
’144.155.166.177’ ’fred’ fred, conectando da m´aquina com endere¸co IP
144.155.166.177
’144.155.166.%’ ’fred’ fred, conectando de qualquer m´aquina na sub-
rede de classe C 144.155.166
’144.155.166.0/255.255.255.0’’fred’ o mesmo que no exemplo anterior
Como vocˆe pode usar valores coringas de IP no campo Host (por exemplo, ’144.155.166.%’
combina com todas m´aquinas em uma subrede), existe a possibilidade que algu´em possa
tentar explorar esta capacidade nomeando a m´aquina como 144.155.166.algumlugar.com.
Para evitar tais tentativas, O MySQL desabilita a combina¸ao com nomes de m´aquina
que iniciam com d´
igitos e um ponto. Portanto se voe possui uma m´aquina nomeada
como 1.2.foo.com, este nome nunca ir´a combinar com uma coluna Host das tabelas de
permiss˜oes. Somente um n´umero IP pode combinar com um valor coringa de IP.
Uma conex˜ao de entrada pode coincidir com mais de uma entrada na tabela user. Por
exemplo, uma conex˜ao a partir de thomas.loc.gov pelo usu´ario fred pode combinar com
diversas das entradas vistas acima. Como o servidor escolhe qual entrada usar se mais
de uma coincide? O servidor resolve esta quest˜ao ordenando a tabela user no tempo de
inicializa¸ao, depois procura pelas entradas na ordem da classifica¸ao quando um usu´ario
tenta se conectar. A primeira entrada que coincidir ´e a que ser´a usada.
A ordena¸ao da tabela user funciona da forma mostrada a seguir. Suponha que a tabela
user se pare¸ca com isto:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
Quando o servidor lˆe a tabela, ele ordena as entradas com os valores mais espec´
ificos de Host
primeiro (’%’ na coluna Host significa “qualquer m´aquina” e ´e menos espec´
ifico). Entradas
com o mesmo valor Host ao ordenadas com os valores mais espec´
ificos de User primeiro
(um valor em branco na coluna User significa “qualquer usu´ario” e ´e menos espec´
ifico). O
resultado da tabela user ordenada ficaria assim:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
Quando uma conex˜ao ´e iniciada, o servidor procura entre as entradas ordenadas e utiliza a
primeira entrada coincidente. Para uma conex˜ao a partir de localhost feito por jeffrey,
as entradas com ’localhost’ na coluna Host coincide primeiro. Destas, a entrada com o
nome do usu´ario em branco combina com o nome da m´aquina e o nome do usu´ario. (A
entrada ’%’/’jeffrey’ tamb´em casaria, mas ela n˜ao ´e a primeira entrada coincidente na
tabela.
210 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Aqui est´a 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˜ao a partir de thomas.loc.gov feita por jeffrey coincide com a primeira en-
trada, no entanto, uma conex˜ao de whitehouse.gov fetia por jeffrey coincidiria com a
segunda entrada na tabela.
Um erro comum ´e pensar que para um determinado usu´ario, todas as entradas que citam
explicitamente este usu´ario ser˜ao usadas primeiro quando o usu´ario tentar encontrar uma
combina¸ao para a conex˜ao. Simplesmente isto n˜ao ´e verdade. O exemplo anterior ilustra
isto, onde uma conex˜ao de thomas.loc.gov feita por jeffrey combina primeiro n˜ao com
a entrada contendo ’jeffrey’ no valor do campo user, mas sim pela entrada sem o nome
de usu´ario!
Se vocˆe tiver problemas conectando ao servidor, imprima a tabela user e ordene-a na
manualmente para ver onde se deu o primeiro coincidˆencia de valores.
4.2.9 Controle de Acesso, Est´agio 2: Verifica¸ao da Requisi¸ao
Uma vez estabelecida uma conex˜ao, o servidor entra no 2o est´agio. Para cada requisi¸ao
que vem na conex˜ao, o servidor verifica se voe tem privil´egios suficientes para realiz´a-la,
baseado nas opera¸oes que vocˆe deseja fazer. ´
E aqui que os campos de concess˜oes nas
tabelas de permiss˜oes entram em a¸ao. Estes privil´egios pode vir de qualquer uma das
tabelas user,db,host,tables_priv ou columns_priv. As tabelas de permiss˜oes s˜ao
manipuladas com os comandos GRANT eREVOKE. See hundefinedi[GRANT], page hundefinedi.
(Voe pode achar ´util fazer referencia a hundefinedi[Privileges], page hundefinedi, que lista
os campos presentes em cada uma das tabelas de permiss˜oes.)
A tabela user concede privil´egios que s˜ao especificados por vocˆe em uma base global e que
se aplicam sem importar qual ´e o banco de dados atual. Por exemplo, se a tabela user
concede a algu´em o privil´egio delete, este usu´ario pode apagar linhas de qualquer banco
de dados no servidor! Em outras palavras, privil´egios na tabela user ao privil´egios de
superusu´ario. O correto ´e conceder privil´egios na tabela user apenas para superusu´arios
tais como os administradores de servidor ou de bancos de dados. Para outros usu´arios,
vocˆe deve deixar os privil´egios na tabela user configurados para ’N’ e conceder privil´egios
somente em bancos de dados espec´
ificos, utilizando as tabelas db ehost.
As tabelas db ehost concedem privil´egios para bancos de dados espec´
ificos. Valores nos
campos de escopo podem ser especificados como a seguir:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 211
Os metacaracteres ‘%’ e ‘_’ podem ser usados nos campos Host eDb de ambas tabelas.
O valor ’%’ em Host na tabela db significa “qualquer m´aquina.” Um valor em branco
em Host na tabela db significa “consulte a tabela host para informa¸ao adicional.”
O valor ’%’ ou em branco no campo Host na tabela host significa “qualquer m´aquina.”
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´ario anˆonimo.
As tabelas db ehost ao lidas e ordenadas quando o servidor inicia (ao mesmo tempo que
ele lˆe a tabela user). A tabela db ´e ordenada nos campos de escopo Host,Db eUser e a
tabela host ´e ordenada nos campos de escopo Host eDb. Assim como na tabela user, a
ordena¸ao coloca os valores mais espec´
ificos no in´
icio e os menos espec´
ificos por ´ultimo, e
quando o servidor procura por entradas coincidentes, ele usa a primeira combina¸ao que
encontrar.
As tabelas tables_priv ecolumns_priv concedem privil´egios espec´
ificos 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
aquina”
Os campos Db,Table_name eColumn_name ao podem conter meta caracteres ou serem
brancos em ambas tabelas.
As tabelas tables_priv ecolumns_priv ao ordenadas nos campos Host,DB eUser. Isto
´e parecido com a ordena¸ao da tabela db, no entanto, a ordena¸ao ´e mais simples porque
somente o campo Host pode conter meta caracteres.
O processo de verifica¸ao da requisi¸ao ´e descrito abaixo. (Se vocˆe j´a est´a familiarizado
com o c´odigo de verifica¸ao de acesso, vocˆe ir´a perceber que a descri¸ao aqui ´e um pouco
diferente do algor´
itimo usado no c´odigo. A descri¸ao ´e equivalente ao que o c´odigo realmente
faz; ele s´o ´e diferente para tornar a explica¸ao mais simples.)
Para requisi¸oes administrativas (shutdown,reload, etc.), o servidor confere somente a
entrada da tabela user, porque ela ´e a ´unica tabela que especifica privil´egios administra-
tivos. O acesso ´e concedido se o registro permitir a opera¸ao requisitada ou negado caso
o contr´ario. Por exemplo, se vocˆe deseja executar mysqladmin shutdown mas a entrada
em sua tabela user ao lhe concede o privil´egio shutdown, o acesso ´e negado mesmo sem
consultar as tabelas db ou host. (elas n˜ao cont´em o campo Shutdown_priv, portanto n˜ao
existe esta necessidade.)
Para requisi¸oes relacionadas aos bancos de dados (insert,udpdate, etc.), o servidor primeiro
confere os privil´egios globais do usu´ario consultando as entradas da tabela user. Se a
entrada permitir a opera¸ao requisitada, o acesso ´e concedido. Se os privil´egios globais na
tabela user ao insuficientes, o servidor determina os privil´egios espec´
ificos de banco de
dados para o usu´ario consultando as tabelas db ehost:
1. O servidor consulta a tabela db por uma combina¸ao nos campos Host,Db eUser. Os
campos Host eUser ao comparados com o nome da m´aquina e o nome do usu´ario que
faz a requisi¸ao. O campo Db ´e comparado com o banco de dados que o usu´ario deseja
acessar. Se n˜ao existir entradas coincidentes para o Host eUser, o acesso ´e negado.
212 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
2. Se existir uma combinca¸ao com a entrada da tabela db e seu campo Host ao estiver
em branco, aquela entrada define os privil´egios 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´aquinas s˜ao permitidas acessar o banco de dados. Neste
caso, uma consulta adicional ´e feita na tabela host para encontrar uma valores coinci-
dentes nos campos Host eDb. Se nenhuma entrada na tabela host coincide, o acesso
´e negado. Se existir uma coincidˆencia, os privil´egios espec´
ificos de bancos de dados
para o usu´ario s˜ao computados como a interse¸ao (ao a uni˜ao!) dos privil´egios nas
entradas das tabelas db ehost, isto ´e, os privil´egios que s˜ao ’Y’ em ambas entradas.
(Desta forma vocˆe pode conceder privil´egios gerais em entradas na tabela db e ent˜ao
restringi-los em uma base de m´aquina a m´aquina utilizando as entradas da tabela
host.)
Depois de determinar os privil´egios espec´
ificos do banco de dados concedido pelas entradas
nas tabelas db ehost, o servidor os adiciona aos privil´egios globais concedidos pela tabela
user. Se o resultado permitir a opera¸ao requisitada, o acesso ser´a concedido. De outra
forma, o servidor consulta os privil´egios de tabelas e campos do usuario nas tabelas tables_
priv ecolumns_priv e os adiciona aos privil´egios do usu´ario. O acesso ser´a permitido ou
negado baseado no resultado.
Expresso em termos booleanos, a descri¸ao precedente de como os privil´egios de um usu´ario
ao calculados podem ser resumido assim:
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
Ele pode n˜ao ser aparente porque, se os privil´egios da entrada global de user ao inicialmente
insuficientes para a opera¸ao requisitada, o servidor adiciona estes privil´egios mais tarde aos
privil´egios espec´
ificos de banco de dados, tabelas e colunas. A raz˜ao ´e que uma requisi¸ao
pode exigir mais que um tipo de privil´egio. Por exemplo, se voe executar uma instru¸ao
INSERT ... SELECT, vocˆe precisa dos privil´egios insert eselect. Seu privil´egio pode ser
tal que a entrada da tabela user concede um privil´egio e a entrada da tabela db concede
o outro. Neste caso, vocˆe tem os privil´egios necess´arios para realizar a requisi¸ao, mas o
servidor n˜ao pode obtˆe-los de ambas as tabelas por si pr´oprio; os privil´egios 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´em uma lista de todas as m´aquina na rede local. A elas s˜ao
concedidos todos os privil´egios.
Voe pode tamb´em usar a tabela host para indicar m´aquinas que ao ao seguras. Suponha
que vocˆe tenha uma m´aquina public.your.domain que est´a localizada em uma ´area p´ublica
que vocˆe n˜ao considera segura. Vocˆe pode permitir o acesso a todas as m´aquinas de sua
rede exceto a esta m´aquina usando entradas na tabela host desta forma:
+--------------------+----+-
| Host | Db | ...
+--------------------+----+-
| public.your.domain | % | ... (todos os privil´egios configurados para ’N’)
| %.your.domain | % | ... (todos os privil´egios configurados para ’Y’)
Chapter 4: Administra¸ao de Bancos de Dados MySQL 213
+--------------------+----+-
Naturalmente, vocˆe deve sempre testar suas entradas nas tabelas de permiss˜oes (por ex-
emplo, usar o mysqlaccess para ter certeza que os privil´egios de acesso est˜ao atualmente
configurados da forma que vocˆe imagina.
4.2.10 Causas dos Erros de Accesso Negado
Se vocˆe encontrar erros de Accesso Negado (Access denied) quando tentar conectar-se ao
servidor MySQL, a lista abaixo indica alguns caminhos que vocˆe pode seguir para corrigir
o problema:
Depois de instalar o MySQL, vocˆe executou o script mysql_install_db para configurar
o conte´udo inicial das tabelas de permiss˜oes ? Se n˜ao, fa¸ca isto. See hundefinedi[Default
privileges], page hundefinedi. Testes os privil´egios iniciais executando este comando:
shell> mysql -u root test
O servidor deve deixar vocˆe conectar sem erros. Voe tamb´em deve assegurar que
exista o arquivo ‘user.MYD’ no diret´orio do banco de dados do MySQL. Normalmente
ele fica em ‘CAMINHO/var/mysql/user.MYD’. onde CAMINHO ´e o caminho para a raiz da
instala¸ao do MySQL.
Depois de terminar uma instala¸ao, vocˆe deve conectar ao servidor e configurar seus
usu´arios e suas permiss˜oes de acesso.
shell> mysql -u root mysql
O servidor deve permitir a conex˜ao pois o usu´ario root MySQL vem inicialmente
configurado sem senha. Isto tamb´em ´e um risco de seguran¸ca, portanto configurar
a senha do usu´ario root ´e algo que deve ser feito enquanto vocˆe configura os outros
usu´arios do MySQL.
Se vocˆe tentar se conectar como root e obter este erro:
Access denied for user: ’@unknown’ to database mysql
isto significa que vocˆe n˜ao possui um registro na tabela user com o valor ’root’ no
campo User e que o mysqld ao pode rsolver o nome de m´aquina do cliente. Neste caso,
vocˆe deve reiniciar o servidor com a op¸ao --skip-grant-tables e editar seu arquivo
/etc/hosts’ouo‘\windows\hosts’ para adicionar uma entrada para sua m´aquina.
Se vocˆe obter um erro como o seguinte:
shell> mysqladmin -u root -pxxxx ver
Access denied for user: ’root@localhost’ (Using password: YES)
Significa que vocˆe est´a usando uma senha errada. See hundefinedi[Passwords],
page hundefinedi.
Se vocˆe esqueceu a senha de root, vocˆe pode reiniciar o mysqld com a op¸ao --skip-
grant-tables para alterar a senha. Vocˆe pode saber mais sobre esta op¸ao posterior-
mente nesta mesma se¸ao do manual.
Se vocˆe obter o erro acima mesmo se n˜ao tiver configurado uma senha, significa que
vocˆe tem algum arquivo my.ini configurado para passar alguma senha incorreta. See
hundefinedi[Option files], page hundefinedi. Voe pode evitar o uso de arquivos de
op¸oes com a op¸ao --no-defaults, como a seguir:
shell> mysqladmin --no-defaults -u root ver
214 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe atualizou uma instala¸ao existente do MySQL de um vers˜ao anterior
`a vers˜ao 3.22.11 para a Vers˜ao 3.22.11 ou posterior, voe executou o script
mysql_fix_privilege_tabels ? Se n˜ao fa¸ca isto. A estrutura das tabelas de
permiss˜oes alteraram com a Vers˜ao 3.22.11 do MySQL quando a instru¸ao GRANT se
tornou funcional.
Se os seus privil´egios parecerem alterados no meio de uma sess˜ao, pode ser que o
superusu´ario os alterou. A recarga das tabelas de permiss˜oes afeta novas conex˜oes
dos clientes, mas ela tamb´em afeta conex˜oes existentes como indicado em hundefinedi
[Privilege changes], page hundefinedi.
Se vocˆe n˜ao consegue fazer a sua senha funcionar, lembre-se que vocˆe deve usar a
fun¸ao PASSWORD() se vocˆe configurar a senha com instru¸oes INSERT,UPDATE ou SET
PASSWORD. A fun¸ao PASSWORD() ´e desnecess´aria se vocˆe especificar a senha usando a
instru¸ao GRANT ... IDENTIFIED BY ou o comando mysqladmin password. See hunde-
finedi[Passwords], page hundefinedi.
localhost ´e um sinˆonimo para seu nome de m´aquina local, e ´e tamb´em a m´aquina
padr˜ao em que clientes tentam se conectar se vocˆe n˜ao especificar explicitamente o
nome da m´aquina. Entretanto, conex˜oes para localhost ao funcionam se vocˆe es-
tiver executando em um sistema que utilize MIT-pthreads (conex˜oes localhost ao
feitas utilizando sockets Unix, que n˜ao s˜ao suportadas pelas MIT-pthreads). Para
evitar este problema nestes sistemas, vocˆe deve utilizar a op¸ao --host para nomear
explicitamente o servidor. Isto far´a uma conex˜ao TCP/IP ao servidor myssqld. Neste
caso, vocˆe deve ter seu nome de m´aquina real nos registros da tabela user no servidor.
(Isto ´e verdadeiro mesmo se vocˆe estiver executando um programa cliente na mesma
aquina que o servidor.)
Se vocˆe obter o erro Access denied quando tentando conectar ao banco de dados com
mysql -u nome_usu´ario _nome_bd, vocˆe pode ter um problema com a tabela user.
Verifique isto executando mysql -u root mysql e usando esta senten¸ca SQL:
mysql> SELECT * FROM user;
O resultado deve incluir uma entrada com as colunas Host eUser combinando com o
nome de seu computador e seu nome de usu´ario no MySQL.
A mensagem de erro Access denied ir´a dizer a vocˆe com qual usu´ario vocˆe est´a ten-
tando se logar, a m´aquina que est´a tentando conectar e se voe est´a utilizando uma
senha ou n˜ao. Normalmente, vocˆe deve ter um registro na tabela user que combine
exatamente com o nome de m´aquina e o nome de usu´ario que forem fornecidos na
mensagem de erro. Por exemplo, se vocˆe obter uma mensagem de erro que contenha
Using password: NO, isto significa que vocˆe est´a tentando se conectar sem uma senha.
Se vocˆe obter o seguinte erro quando estiver tentando conectar de uma m´aquina difer-
ente da que o servidor MySQL estiver executando, enao n˜ao deve existir um registro
na tabela user que combine com esta m´aquina:
Host ... is not allowed to connect to this MySQL server
Voe pode corrigir isto utilizando a ferramenta de linha de comando mysql (no servi-
dor!) para adicionar um registro `a tabela user,db ou host para coincidir com o usu´ario
e nome de m´aquina de onde vocˆe est´a tentando conectar, depois execute o comando
mysqladmin flush-privileges. Se vocˆe n˜ao estiver executando o MySQL Vers˜ao 3.22
e vocˆe n˜ao sabe o n´umero IP ou o nome da m´aquina da qual estiver conectando, vocˆe
Chapter 4: Administra¸ao de Bancos de Dados MySQL 215
deve colocar uma entrada com o valor ’%’ na coluna Host da tabela user e reiniciar
omysqld com a op¸ao --log na m´aquina onde ´e executado o servidor. Depois tente
conectar a partir da m´aquina cliente, a informa¸ao no log do MySQL ir´a indicar como
vocˆe est´a realmente conectando. (Enao troque o ’%’ na tabela user com o nome da
aquina mostrado pelo log. De outra forma vocˆe teria um sistema que seria inseguro.)
Outra raz˜ao para este erro no Linux pode ser porque vocˆe est´a utilizando uma vers˜ao
bin´aria do MySQL que ´e compilada com uma vers˜ao diferente da glibc que vocˆe est´a
usando. Neste caso vocˆe deve atualizar seu SO/Glibc ou fazer o download da vers˜ao
fonte do MySQL e compil´a-la. Um RPM fonte ´e, normalmente, f´acil de compilar e
instalar, logo, isto n˜ao ´e um grande problema.
Se vocˆe obter uma mensagem de erro onde o nome da m´aquina n˜ao ´e exibido ou, no
lugar do nome da m´aquina existir um IP, mesmo se vocˆe tenta a conex˜ao com um nome
de m´aquina:
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ˆe pode executar mysqladmin flush-hosts para zerar
o cache DNS interno. See hundefinedi[DNS], page hundefinedi.
Algumas solu¸oes permanentes s˜ao:
Tente descobrir o que est´a errado com seu servidor DNS e corrija os erros.
Especifique n´umeros IPs no lugar de nomes nas tabelas de privil´egios do MySQL.
Inicie o mysqld com --skip-name-resolve.
Inicie o mysqld com --skip-host-cache.
Conecte `a localhost se vocˆe estiver executando o servidor e o cliente na mesma
aquina.
Coloque os nomes das m´aquinas clientes em /etc/hosts.
Se mysql -u root test funciona mas mysql -h nome_servidor -u root test resultar
em Access denied, ent˜ao vocˆe pode n˜ao ter o nome correto para a sua m´aquina na
tabela user. Um problema comum ´e quando o valor de Host na entrada da tabela
user especifica um nome de m´aquina n˜ao qualificado, mas as rotinas de resolu¸ao de
nomes de seu sistema retornam um nome qualificado completo do dom´
inio (ou vice-
versa). Por exemplo, se vocˆe tem uma entrada com o nome ’tcx’ na tabela user, mas
seu DNS diz ao MySQL que o nome da m´aquina ´e ’tcx.subnet.se’, a entrada n˜ao
ir´a funcionar. Tente adicionar um registro `a tabela user que contenha o n´umero IP
de sua m´aquina como o valor da coluna Host. (Uma alternativa, seria adicionar um
registro `a tabela user com o valor de Host contendo um metacaracter, por exemplo,
’tcx.%’. Entretanto, o uso de nomes de m´aquinas terminando com ‘%’ ´e inseguro e
ao ´e recomendado!)
Se mysql -u nome_usu´ario test funciona mas mysql -u nome_usu´ario outro_bd ao
funconar, vocˆe n˜ao possui uma entrada para outro_bd listado na tabela db.
Se mysql -u nome_usu´ario nome_bd funciona quando executado no pr´oprio servidor,
mas mysql -u nome_m´aquina -u nome_usu´ario nome_bd ao funciona quando execu-
tado em outra m´aquina cliente, vocˆe n˜ao possui o nome da m´aquina cliente listado na
tabela user ou na tabela db.
216 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe n˜ao estiver entendendo porque obtem Access denied, remova da tabela user
todas as entradas da coluna Host que contenham meta caracteres (entradas que con-
tenham ‘$’ ou ‘_’). Um erro muito comum ´e inserir uma nova entrada com Host=’%’ e
User=’algum usu´ario’, pensando que isto ir´a permitir a vocˆe especificar localhost
para conectar da mesma m´aquina. A raz˜ao disto n˜ao funcionar ´e que os privil´egios
padr˜oes incluem uma entrada com Host=’localhost’ eUser=’’. Como esta entrada
tem o valor ’localhost’ em Host que ´e mais espec´
ifica que ’%’, ela ´e usada no lugar
da nova entrada quando se conectar de localhost! O procedimento correto ´e inserir
uma segunda entrada com Host=’localhost’ eUser=’algum_usu´ario’, ou remover
a entrada com Host=’localhost’ eUser=’’.
Se vocˆe obter o seguinte erro, vocˆe 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
aquinas aplicam-se `a tabela db.
Se vocˆe obter o erro quando estiver utilizando comandos SQL SELECT ... INTO
OUTFILE ou LOAD DATA INFILE, a entrada na tabela user provavelmente n˜ao tem o
privil´egio file habilitado.
Lembre-se que programas clientes ir˜ao usar parˆametros de conex˜oes especificados em
arquivos de configura¸ao ou vari´aveis ambientais. See hundefinedi[Environment vari-
ables], page hundefinedi. Se parecer que algum cliente est´a enviando parˆametros errados
para a conex˜ao e vocˆe n˜ao os especificou na linha de comando, verifique seu ambiente e
o arquivo ‘.my.cnf’ no seu diret´orio home. Vocˆe pode tamb´em conferir os arquivos de
configura¸oes do servidor MySQL, apesar de n˜ao ser interessante gravar configura¸oes
de cliente nestes arquivos. See hundefinedi[Option files], page hundefinedi. Se vocˆe
obter a mensagem de acesso negado (Access denied) quando estiver executando um
cliente sem op¸oes, tenha certeza que vocˆe n˜ao especificou uma senha antiga em nenhum
de seus arquivos de op¸oes! See hundefinedi[Option files], page hundefinedi.
Se vocˆe fizer altera¸oes para as tabelas de permiss˜oes diretamente (utilizando uma in-
stru¸ao INSERT ou UPDATE) e suas altera¸oes parecem ser ignoradas, lembre que voe
deve usar uma instru¸ao FLUSH PRIVILEGES ou executar um comando mysqladmin
flush-privileges para o servidor ler novamente as tabelas com os privil´egios. De
outra forma, suas altera¸oes n˜ao far˜ao efeito at´e que o servidor seja reiniciado. Lembre-
se que depois de configurar a senha de root com um comando UPDATE, ao ser´a
necess´ario especificar a senha at´e que vocˆe atualize os privil´egios, pois o servidor ainda
ao saber´a que vocˆe alterou a senha!
Se vocˆe tiver problemas de acesso com Perl, PHP, Python ou um programa ODBC,
tente conectar ao servidor com mysql -u nome_usu´ario nome_bd ou mysql -u nome_
usu´ario -psua_senha nome_bd. Se vocˆe consegue conectar com o cliente mysql, existe
algum problema com seu programa e n˜ao o acesso aos privil´egios (Note que n˜ao espa¸co
entre -p e a senha; vocˆe tamb´em pode utilizar a sintaxe --password=sua_senha para
especificar a senha. Se vocˆe utilizar a op¸ao -p sozinha, o MySQL ir´a lhe solicitar a
senha.)
Para testar, iniciae o daemon mysqld com a op¸ao --skip-grant-tables. Enao vocˆe
Chapter 4: Administra¸ao de Bancos de Dados MySQL 217
pode alterar as tabelas de permiss˜oes do MySQL e utilizar o script mysqlaccess para
conferir se suas modifica¸oes fizeram o n˜ao o efeito desejado. Quando vocˆe estiver
satisfeito com suas altera¸oes, execute mysqladmin flush-privileges para dizer ao
servidor mysqld para iniciar utilizando as novas tabelas com os privil´egios. Nota:
Recarregar as tabelas de permiss˜oes sobrescreve a op¸ao --skip-grant-tables. Isto
lhe permite dizer ao servidor para come¸car a utilizar as tabelas de permiss˜oes novamente
sem reinici´a-lo.
Se tudo mais falhar, inicie o servidor mysqld com uma op¸ao de depura¸ao (por exem-
plo, --debug=d,general,query). Isto ir´a imprimir informa¸oes de m´aquinas e usu´arios
sobre tentativas de conex˜oes, e tamb´em informa¸oes sobre cada comando disparado.
See hundefinedi[Making trace files], page hundefinedi.
Se vocˆe tiver outros problemas com as tabelas de permiss˜oes do MySQL e sente que
deve enviar o problema para a lista de discuss˜ao, sempre forne¸ca um descarga das
tabelas de permiss˜oes do seu MySQL. Vocˆe pode descarregar as tabelas com o comando
mysqldump mysql. Como sempre, envie seus problemas utilizando o script mysqlbug.
See hundefinedi[Bug reports], page hundefinedi. Em alguns casos vocˆe pode precisar
reiniciar o mysqld com a op¸ao --skip-grant-tables para executar o mysqldump.
4.3 Gerenciamento das Contas dos Usu´arios no MySQL
4.3.1 A Sintaxe de GRANT eREVOKE
GRANT tipo_priv [(column_list)] [, tipo_priv [(column_list)] ...]
ON {nome_tabela | * | *.* | nome_bd.*}
TO nome_usuario [IDENTIFIED BY ’password’]
[, nome_usuario [IDENTIFIED BY ’password’] ...]
[WITH GRANT OPTION]
REVOKE tipo_priv [(column_list)] [, tipo_priv [(column_list)] ...]
ON {nome_tabela | * | *.* | nome_bd.*}
FROM nome_usuario [, nome_usuario ...]
O comando GRANT ´e implementado no MySQL vers˜ao 3.22.11 ou posterior. Para vers˜oes
anteriores do MySQL, a instru¸ao GRANT ao faz nada.
Os comandos GRANT eREVOKE permitem aos administradores do sistema criar usu´arios e
conceder e revogar direitos aos usu´arios do MySQL em quatro n´
iveis de privil´egios:
N´
ivel Global
Privil´egios globais aplicam para todos os bancos de dados em um determinado
servidor. Estes privil´egios s˜ao armazenados na tabela mysql.user.
N´
ivel dos bancos de dados
Privil´egios de bancos de dados aplicam-se a todas as tabelas em um determinado
banco de dados. Estes privil´egios s˜ao armazenados nas tabelas mysql.db e
mysql.host.
N´
ivel das tabelas
Privil´egios de tabelas aplicam-se a todas as colunas em uma determinada tabela.
Estes privil´egios s˜ao armazenados na tabela mysql.tables_priv.
218 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
N´
ivel das colunas
Privil´egios de colunas aplicam-se a uma ´unica coluna em uma determinada
tabela. Estes privil´egios s˜ao armazenados na tabela mysql.columns_priv.
Se vocˆe fornecer uma permiss˜ao para usu´arios que n˜ao existem, este usu´ario ´e criado. Para
exemplos de como GRANT funciona, veja hundefinedi[Adding users], page hundefinedi.
Para as instru¸oes GRANT eREVOKE,tipo_priv pode ser especificado como um dos seguintes:
ALL PRIVILEGES FILE RELOAD
ALTER INDEX SELECT
CREATE INSERT SHUTDOWN
DELETE PROCESS UPDATE
DROP REFERENCES USAGE
ALL ´e um sinˆonimo para ALL PRIVILEGES.REFERENCES ainda n˜ao foi implementado. USAGE
´e atualmente um sinˆonimo para “sem privil´egios”. Pode ser usado quando vocˆe desejar criar
um usu´ario que n˜ao tenha privil´egios.
Para anular o privil´egio grant de um usu´ario, utilize o valor tipo_priv de GRANT OPTION:
REVOKE GRANT OPTION ON ... FROM ...;
Os ´unicos valores de tipo_priv que vocˆe pode especificar para uma tabela s˜ao SELECT,
INSERT,UPDATE,DELETE,CREATE,DROP,GRANT,INDEX eALTER.
Os ´unicos valores de tipo_priv que voe pode especificar para uma coluna (isto ´e, quando
vocˆe usar uma cl´ausula column_list) s˜ao SELECT,INSERT eUPDATE.
Voe pode configurar privil´egios globais utilizando a sintaxe ON *.*. Vocˆe pode configurar
privil´egios de bancos de dados utilizando a sintaxe ON nome_bd.*. Se vocˆe especificar ON
*e estiver com algum banco de dados aberto, ser´a configurado os privil´egios somente para
este banco de dados. (AVISO: Se vocˆe especificar ON * e vocˆe ao tem possui um banco de
dados aberto, ir´a afetar os privil´egios globais!).
Para acomodar concess˜oes de direitos para usu´arios de m´aquinas arbitr´arias, o MySQL su-
porta a especifica¸ao do valor user_name no formato usu´ario@m´aquina. Se vocˆe desejar
especificar uma string user contendo caracteres especiais (como o ‘-’), ou uma string con-
tendo caracteres especiais ou meta caracteres (como o ‘%’), vocˆe pode colocar o usu´ario ou
o nome de m´aquina entre aspas (por exemplo, ’usu´ario-teste’@’m´aquina-teste’).
Voe pode especificar meta caracteres no nome da m´aquina. Por exemplo,
user@"%.loc.gov" se aplica a user para qualquer m´aquina no dom´
inio loc.gov, e
user@"144.155.166.%" se aplica a user em qualquer m´aquina na subrede de classe C
144.155.166.
O formato simples user ´e sinˆonimo de user@"%".NOTA: Se vocˆe permite o acesso de
usu´arios anˆonimos ao seu servidor MySQL (que ´e o padr˜ao), vocˆe deve tamem adicionar
todos usu´arios locais como user@localhost porque, de outra forma, a entrada de usu´ario
anˆonimo para a m´aquina local na tabela mysql.user ir´a ser usada quando o usu´ario tentar
a conex˜ao ao servidor MySQL da m´aquina local! Usu´arios anˆonimos s˜ao definidos inserindo
entradas com User=’’ na tabela mysql.user. Voe pode verificar se isto se aplica a vocˆe
executando esta instru¸ao:
mysql> SELECT Host,User FROM mysql.user WHERE User=’’;
No momento, GRANT suporta somente nomes de m´aquinas, tabelas bancos de dados e colunas
at´e 60 caracteres. Um nome de usu´ario pode ter at´e 16 caracteres.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 219
Os privil´egios para uma tabela ou coluna s˜ao formados atrav´es do OU l´ogico dos privil´egios
em cada um dos quatro n´
iveis de privil´egios. Por exemplo, se a tabela mysql.user especifica
que um usu´ario tem um privil´egio global select, isto n˜ao pode ser negado por uma entrada
no n´
ivel de banco de dados, tabela ou coluna.
Os privil´egios para uma coluna podem ser calculados da seguinte forma:
privil´egios globais
OR (privil´egios de banco de dados AND privil´egios de m´aquina)
OR privil´egios de tabela
OR privil´egios de coluna
Na maioria dos casos, os direitos a um usu´ario s˜ao atribu´
idos em apenas um dos n´
iveis de
privil´egios, portanto a vida normalmente n˜ao ´e t˜ao complicada como mostrado acima. Os
detalhes do procedimento de verifica¸ao dos privil´egios s˜ao apresentados em hundefinedi
[Privilege system], page hundefinedi.
Se vocˆe concede privil´egios para uma combina¸ao de usu´ario e m´aquina que n˜ao existem
na tabela mysql.user, um registro ´e adicionado e permanece l´a at´e ser removido com um
comando DELETE. Em outras palavras, GRANT pode criar registros na tabela user, mas
REVOKE ao as remover´a; para removˆe-las vocˆe deve usar a instru¸ao expl´
icita DELETE.
Na Vers˜ao 3.22.12 ou posterior do MySQL, se um novo usu´ario ´e criado ou se vocˆe possui
privil´egios de concess˜ao globais, a senha do usu´ario ser´a especificada utilizando a cl´ausula
IDENTIFIED BY, se uma for dada. Se o usu´ario j´a possui uma senha, ela ´e trocada pela nova.
CUIDADO: Se vocˆe criar um novo usu´ario mas n˜ao especificar uma cl´ausula IDENTIFIED
BY, o usu´ario n˜ao possuir´a uma senha. Isto n˜ao ´e seguro.
Senhas podem tamb´em ser configuradas com o comando SET PASSWORD. See hundefinedi
[SET OPTION], page hundefinedi.
Se vocˆe conceder privil´egios para um banco de dados, uma entrada na tabela mysql.db ´e
criada se necess´ario. Quando todos os privil´egios para o banco de dados forem removidos
com REVOKE, este registro ´e removido.
Se um usu´ario n˜ao tem privil´egios em uma tabela, a tabela n˜ao ´e mostrada quando o usu´ario
solicita uma lista de tabelas (com a instru¸ao SHOW TABLES por exemplo).
A cl´ausula WITH GRANT OPTION a ao usu´ario habilidade de fornecer `a outros usu´arios quais-
quer privil´egios que ele tenha em um n´
ivel espec´
ifico de privil´egio. Vocˆe deve ter cuidado
ao fornecer o privil´egio grant, pois dois usu´arios podem se unir para unir privil´egios!
Voe n˜ao pode conceder a outro usu´ario um privil´egio que n˜ao possua; o privil´egio grant
possibilita fornecer somente os privil´egios que possuir.
Esteja ciente que quando conceder a um usu´ario o privil´egio grant em um n´
ivel particular de
privil´egios, qualquer privil´egio que o usu´ario j´a possua (ou seja fornecido no futuro!) nesse
n´
ivel tamb´em pode ser concedido por este usu´ario. Suponha que vocˆe conceda a um usu´ario
o privil´egio insert em um banco de dados. Se vocˆe conceder o privil´egio select no banco de
dados e especificar WITH GRANT OPTION, o usu´ario al´em de poder repassar o privil´egio select
poder´a tamb´em repassar o insert. Se vocˆe concede o privil´egio update para o usu´ario no
banco de dados, o usu´ario poder´a conceder os privil´egios insert,select eupdate.
Voe n˜ao deve conceder privil´egios alter a um usu´ario comum. Se vocˆe fizer isto, o usu´ario
pode tentar enganar o sistema de privil´egios renomeando tabelas!
220 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Perceba que se vocˆe estiver utilizando privil´egios de tabelas ou colunas, mesmo que para
apenas um usu´ario, o servidor examina os privil´egios de tabelas e colunas para todos os
usu´arios e isto ir´a deixar o MySQL um pouco mais lento.
Quando o mysqld inicia, todos os privil´egios s˜ao lidos na mem´oria. Privil´egios de bancos de
dados, tabelas e colunas s˜ao iniciados um vez, e privil´egios ao n´
ivel de usu´ario fazem efeito na
pr´oxima vez que o usu´ario conectar. Modifica¸oes nas tabelas de permiss˜oes que vocˆe realiza
utilizando GRANT ou REVOKE ao percebidas pelo servidor imediatamente. Se vocˆe modificar
as tabelas de permiss˜oes manualmente (utilizando INSERT,UPDATE, etc), vocˆe deve executar
uma instru¸ao FLUSH PRIVILEGES ou executar mysqladmin flush-privileges para dizer
ao servidor para recarregar as tabelas de permiss˜oes. See hundefinedi[Privilege changes],
page hundefinedi.
As maiores diferen¸cas entre o ANSI SQL e vers˜oes MySQL de GRANT ao:
No MySQL privil´egios s˜ao fornecidos para uma combina¸ao de usu´ario e m´aquina e
ao somente para um usu´ario.
O ANSI SQL n˜ao possui privil´egios no n´
ivel global ou de bancos de dados, e n˜ao
suporta todos os tipos de privil´egios que o MySQL suporta. O MySQL n˜ao suporta os
privil´egios TRIGGER,EXECUTE ou UNDER do ANSI SQL.
Os privil´egios do ANSI SQL s˜ao estruturadados em uma maneira hier´arquica. Se vocˆe
remover um usu´ario, todos os privil´egios do usu´ario s˜ao removidos. No MySQL os
privil´egios concedidos n˜ao s˜ao removidos automaticamente, mas vocˆe deve removˆe-los
se necess´ario.
Se no MySQL vocˆe possuir o privil´egio INSERT em somente parte das colunas em uma
tabela, vocˆe pode executar instru¸oes INSERT na tabela; As colunas em que vocˆe n˜ao
tem o privil´egio INSERT ir˜ao receber seus valores padr˜oes. O SQL ANSI necessita que
vocˆe tenha o privil´egio INSERT em todas as colunas.
Quando vocˆe remove uma tabela no ANSI SQL, todos os privil´egios para a tabela s˜ao
removidos. Se vocˆe remover um privil´egio no SQL ANSI, todos os privil´egios que foram
concedidos baseado neste privil´egio s˜ao tamb´em removidos. No MySQL, privil´egios s´o
podem ser removidos com comandos REVOKE expl´
icitos ou manipulando as tabelas de
permiss˜oes do MySQL.
4.3.2 Nomes de Usu´arios e Senhas do MySQL
Existem v´arias diferen¸cas entre a forma que nomes de usu´arios e senhas s˜ao usados pelo
MySQL e a forma que s˜ao usados pelo Unix ou Windows:
Nomes de usu´arios, como usado pelo MySQL para prop´ositos de autentica¸ao, n˜ao tem
nenhuma rela¸ao com os nomes de usu´arios do Unix (nomes de login) ou nomes de
usu´arios Windows. A maioria dos clientes MySQL, por padr˜ao, tentam se conectar
utilizando o nome de usu´ario atual do Unix como o nome de usu´ario no MySQL, mas
isto existe somente por conveniˆencia. Programas clientes permite especificar um nome
diferente com as op¸oes -u ou --user. Isto significa que vocˆe n˜ao pode tornar um
banco de dados seguro a menos que todos os usu´arios do MySQL possuam senhas.
Qualquer um pode tentar se conectar ao servidor utilizando qualquer nome, e eles se
conectar˜ao com qualquer nome que n˜ao possua uma senha.
Nomes de usu´arios MySQL podem ter o tamanho de at´e 16 caracteres; Nomes de
usu´ario Unix normalmente s˜ao limitados at´e 8 caracteres.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 221
Senhas MySQL n˜ao tem nenhuma rela¸ao com senhas Unix. ao existe nenhuma
associa¸ao entre a senha em que vocˆe utiliza para logar-se a uma m´aquina Unix e a
senha que ´e utilizada para acessar um banco de dados na mesma m´aquina.
O MySQL criptografa senhas utilizando um algor´
itimo diferente que o utilizado pelo
processo de login do Unix. Veja as descri¸oes das fun¸oes PASSWORD() eENCRYPT()
em hundefinedi[Miscellaneous functions], page hundefinedi. Perceba que mesmo que
a senha ´e armazenada ’embaralhada’, o conhecimento da sua senha ’embaralhada’ ´e o
suficiente para conseguir se conectar ao servidor MySQL!
Usu´arios MySQL e seus privil´egios s˜ao criados normalmente com o comando GRANT, See
hundefinedi[GRANT], page hundefinedi.
Quando vocˆe se conecta a um servidor MySQL com um cliente de linha de comando
vocˆe pode especificar a senha com --password=sua-senha. See hundefinedi[Connecting],
page hundefinedi.
mysql --user=monty --password=guess nome_do_banco
Se vocˆe deseja que o cliente lhe solicite a senha, deve ser especificado o parˆametro --
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 ´ultimo exemplo a senha ao ´e ’nome do banco’.
Se vocˆe deseja usar a op¸ao -p para fornecer uma senha vocˆe deve fazer assim:
mysql -u monty -pguess nome_do_banco
Em alguns sistemas, a chamada da biblioteca que ´e utilizada pelo MySQL para solicitar por
uma senha corta automaticamente a senha para 8 caracteres. Internamente o MySQL n˜ao
limita o tamanho limite da senha.
4.3.3 Quando as Altera¸oes nos Privil´egios tem Efeito
Quando o mysqld inicia, todas o conte´udo das tabelas de permiss˜oes s˜ao lidos em mem´oria
e tem efeito neste momento.
As modifica¸oes das tabelas de permiss˜oes que vocˆe realiza utilizando GRANT,REVOKE ou
SET PASSWORD ao imediatamente reconhecidas pelo servidor.
Se vocˆe alterar as tabelas de permiss˜oes manualmente (utilizando INSERT,UPDATE, etc), vocˆe
deve executar a instru¸ao FLUSH PRIVILEGES ou executar mysqladmin flush-privileges
ou mysqladmin reload para dizer ao servidor para recarregar as tabelas de permiss˜oes. De
outra forma suas altera¸oes ao ter˜ao efeito at´e que o servidor seja reiniciado. Se vocˆe
alterar as tabelas de permiss˜oes manualmente mas se esquecer de recarregar os privil´egios,
suas altera¸ao v˜ao parecer n˜ao ter feito nenhuma diferen¸ca!
Quando o servidor reconhecer que as tabelas de permiss˜oes foram alteradas, conex˜oes exis-
tentes s˜ao afetadas da seguinte forma:
Altera¸oes nos privil´egios de tabelas e colunas fazem efeito com a pr´oxima requisi¸ao
do cliente.
Altera¸oes nos privil´egios de bancos de dados fazem efeito no pr´oximo comando USE
nome_bd.
222 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Altera¸oes nos privil´egios globais e altera¸oes de senhas fazem efeito na pr´oxima vez que o
cliente conectar.
4.3.4 Configurando os Privil´egios Iniciais do MySQL
Depois de instalar o MySQL, vocˆe configura os privil´egios iniciais dos acessos executando
scripts/mysql_install_db. See hundefinedi[Quick install], page hundefinedi. O script
mysql_install_db inicia o servidor mysqld, depois inicializa as tabelas de permiss˜oes com
a seguinte configura¸ao dos privil´egios:
O usu´ario root do MySQL ´e criado como um superusu´ario que pode fazer qualquer
coisa. Conex˜oes devem ser feitas atrav´es da m´aquina local.
NOTA: A senha inicial de root ´e vazia, portanto qualquer um que conectar como root
sem senha ter´a direito a todos os privil´egios.
Um usu´ario anˆonimo ´e criado e pode fazer o que desejar com bancos de dados com
nome ’test’ ou iniciando com ’test_’. Conex˜oes devem ser feitas da m´aquina local.
Isto significa que usu´arios locais podem se conectar sem senha e serem tratados como
usu´arios anˆonimos.
Outros privil´egios s˜ao negados. Por exemplo, usu´arios normais n˜ao podem executar
mysqladmin ou mysqladmin processlist.
NOTA: Os privil´egios padr˜oes s˜ao diferentes no Windows. See hundefinedi[Windows run-
ning], page hundefinedi.
Como sua insta¸ao inicialmente ´e parcialmente aberta, uma das primeiras coisas que vocˆe
deve fazer ´e especificar uma senha para o usu´ario root do MySQL. Voe pode fazer isto
como a seguir (perceba que a senha foi especificada utilizando a fun¸ao PASSWORD()):
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD(’nova_senha’)
WHERE user=’root’;
mysql> FLUSH PRIVILEGES;
Voe pode, nas vers˜oes 3.22 e superiores do MySQL, utilizar a instru¸ao SET PASSWORD:
shell> mysql -u root mysql
mysql> SET PASSWORD FOR root=PASSWORD(’nova_senha’);
Outra forma de configurar a senha ´e utilizando o comando mysqladmin:
shell> mysqladmin -u root password nova_senha
Somente usu´arios com acesso de escrita/atualiza¸ao ao banco de dados mysql podem
alterar a senha de outros usu´arios. Todos os usu´arios comuns (n˜ao os anˆonimos)
podem alterar somente a pr´opria senha com um dos comandos acima ou com SET
PASSWORD=PASSWORD(’nova_senha’).
Perceba que se vocˆe atualizar a senha na tabela user diretamente utilizando o primeiro
m´etodo, vocˆe deve dizer ao servidor para reler as tabelas de permiss˜oes (com FLUSH
PRIVILEGES), de outra forma a altera¸ao n˜ao seria notificada.
Uma vez que a senha de root foi configurada, vocˆe deve informar a senha quando se conectar
ao servidor MySQL como root.
Voe pode desejar deixar a senha de root em branco para que vocˆe n˜ao precise especific´a-la
quando realizar configura¸oes adicionais ou testes. Entretanto, tenha certeza de configur´a-la
antes de utilizar sua instala¸ao para qualquer ambiente de produ¸ao.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 223
Veja o script scripts/mysql_install_db para ver como s˜ao configurados os privil´egios
padr˜oes. Voe pode usar isto como uma base para ver como adicionar outros usu´arios.
Se vocˆe deseja que os privil´egios iniciais sejam diferentes do descrito acima, ´e poss´
ivel
modificar o script mysql_install_db antes de execut´a-lo.
Para recriar as tabelas de permiss˜oes completamente, remova todos os arquivos ‘.frm’ ‘.MYI
e ‘.MYD’ no diret´orio contendo o banco de dados mysql. (Este ´e o diret´orio chamado ‘mysql
sob o diret´orio do banco de dados, que ´e listado quando vocˆe executa mysqld --help.)
Depois execute o script mysql_install_db, possivelmente depois de edit´a-lo para criar os
privil´egios desej´aveis.
NOTA: Para vers˜oes do MySQL mais antigas que a vers˜ao 3.22.10, vocˆe n˜ao deve apagar
os arquivos ‘.frm’. Se vocˆe fizer isso acidentalmente, vocˆe deve volt´a-los a partir de sua
distribui¸ao MySQL antes de executar mysql_install_db.
4.3.5 Adicionando Novos Usu´arios ao MySQL
Existem duas maneiras de adicionar usu´arios: utilizando instru¸oes GRANT ou manipulando
as tabelas de permiss˜oes do MySQL diretamente. O m´etodo preferido ´e utilizar instru¸oes
GRANT, porque elas s˜ao mais concisas e menos propensas a erros. See hundefinedi[GRANT],
page hundefinedi.
Existem v´arios programas de colaboradores como o phpmyadmin que pode ser utilizado para
criar e administrar usu´arios. See hundefinedi[Contrib], page hundefinedi.
Os exemplos abaixo mostram como usar o cliente mysql para configurar novos usu´arios.
Estes exemplos assumem que privil´egios s˜ao configurados de acordo com os padr˜oes descritos
na se¸ao anterior. Isto significa que para fazer altera¸oes, vocˆe deve se conectar na mesma
aquina em que o mysqld est´a executando, vocˆe deve se conectar com o usu´ario root, e
o usu´ario root deve ter os privil´egios inster ao banco de dados mysql e o administrativo
reload. Tamb´em, se vocˆe alterou a senha do usu´ario root, vocˆe deve especific´a-la para os
comandos mysql abaixo.
Voe pode adicionar novos usu´arios utilizando instru¸oes GRANT:
shell> mysql --user=root mysql
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¸oes GRANT configuram trˆes novos usu´arios:
monty Um superusu´ario completo que pode conectar ao servidor de qualquer lugar,
mas deve utilizar uma senha ’alguma_senha’ para fazer isto. Perceba que
devemos utilizar instru¸oes GRANT para monty@localhost emonty@"%". Se n´os
ao adicionarmos a entrada com localhost, a entrada para o usu´ario anˆonimo
para localhost que ´e criada por mysql_install_db ir´a tomar precedˆencia
quando nos conectarmos da m´aquina local, porque ele contem um campo Host
com um valor mais espec´
ifico e tamb´em vem antes na ordena¸ao da tabela user.
224 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
admin Um usu´ario que possa conectar de localhost sem uma senha e que ´e
concedido os privil´egios administrativos reload eprocess. Isto permite ao
usu´ario a execu¸ao dos comandos mysqladmin reload,mysqladmin refresh
emysqladmin flush-*, bem como o mysqladmin processlist. Nenhum
privil´egio relacionado aos bancos de dados ´e concedido. (Depois eles podem
ser adicionados utilizando instru¸oes GRANT adicionais.)
dummy Um usu´ario que pode conectar sem uma senha, mas somente na m´aquina local.
Os privil´egios globais s˜ao todos configurados para ’N’ --- o tipo de privil´egio
USAGE permite a cria¸ao de um usu´ario sem privil´egios. Considera-se que vocˆe
ir´a conceder privil´egios espec´
ificos de bancos de dados mais tarde.
Tamb´em ´e poss´
ivel adicionar a mesma informa¸ao de acesso do usu´ario diretamente, uti-
lizando instru¸oes INSERT e depois dizendo ao servidor para recarregar as tabelas de per-
miss˜oes:
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˜ao do MySQL, vocˆe pode precisar utilizar um n´umero diferente de
valores ’Y’ acima (vers˜oes anteriores `a vers˜ao 3.22.11 tem menos campos de privil´egios).
Para o usu´ario admin, a maior sintaxe leg´
ivel de INSERT que est´a dispon´
ivel a partir da
vers˜ao 3.22.11 ´e a utilizada.
Note que para configurar um superusu´ario, vocˆe s´o precisar criar uma entrada na tabela
user com os campos de privil´egios configurados para ’Y’. ao ´e necess´ario gerar entradas
nas tabelas db ou host.
Os campos de privil´egios na tabela user ao foram exibidas explicitamente na ´ultima in-
stru¸ao INSERT (para o usu´ario dummy), logo a estes campos s˜ao atribu´
idos o valor padr˜ao
’N’. Isto ´e a mesma coisa que o GRANT USAGE faz.
O seguinte exemplo adiciona um usu´ario custom que pode conectar das m´aquinas
localhost,server.domain ewhitehouse.gov, Ele deseja acessar o banco de
dados bankaccout somente de localhost, o banco de dados expenses somente de
whitehouse.gov e o banco de dados customer de todas as trˆes m´aquinas. Ele tamb´em
deseja utilizar a senha stupid das trˆes m´aquinas.
Para configurar os privil´egios deste usu´ario utilizando instru¸oes GRANT, execute estes co-
mandos:
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON bankaccount.*
TO custom@localhost
IDENTIFIED BY ’stupid’;
Chapter 4: Administra¸ao de Bancos de Dados MySQL 225
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON expenses.*
TO custom@whitehouse.gov
IDENTIFIED BY ’stupid’;
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON customer.*
TO custom@’%’
IDENTIFIED BY ’stupid’;
A raz˜ao para que n´os n˜ao concedamos privil´egios para o usu´ario ’custom’ ´e que desejamos
fornecer ao usu´ario acesso ao MySQL a partir da m´aquina local com sockets Unix e da
aquina remota ’whitehouse.gov’ com TCP/IP.
Para configurar os privil´egios do usu´ario modificiando as tabelas de permiss˜oes 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(’stupid’));
mysql> INSERT INTO user (Host,User,Password)
VALUES(’server.domain’,’custom’,PASSWORD(’stupid’));
mysql> INSERT INTO user (Host,User,Password)
VALUES(’whitehouse.gov’,’custom’,PASSWORD(’stupid’));
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(’%’,’customer’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’);
mysql> FLUSH PRIVILEGES;
As primeiras trˆes instru¸oes INSERT adicionam entradas na tabela user que permite ao
usu´ario custom conectar a partir de v´arias m´aquinas com a senha determinada, mas n˜ao
concede permiss˜oes ao mesmo (todos os privil´egios s˜ao configurados com o valor padr˜ao de
’N’). As pr´oximas trˆes instru¸oes INSERT adicionam entradas na tabela db que concedem
privil´egios `a custom para os bancos de dados bankaccount,expenses ecustomer, mas s´o
quando acessados `a partir das m´aquinas apropriadas. Normalmente, quando as tabelas de
permiss˜oes s˜ao modificadas diretamente, o servidor deve ser informado para recarreg´a-las
(com FLUSH PRIVILEGES) para que as altera¸oes nos privil´egios tenham efeito.
Se vocˆe deseja fornecer a um usu´ario espec´
ifico acesso de qualquer m´aquina em um deter-
minado dom´
inio, vocˆe pode utilizar uma instru¸ao GRANT como a seguir:
mysql> GRANT ...
ON *.*
226 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
TO meunomedeusuario@"%.meudominio.com"
IDENTIFIED BY ’minhasenha’;
Para realizar a mesma coisa modificando diretamente as tabelas de permiss˜oes, fa¸ca isto:
mysql> INSERT INTO user VALUES (’%.meudominio, ’meunomedeusuario’
PASSWORD(’minhasenha’),...);
mysql> FLUSH PRIVILEGES;
Voe pode tamb´em utilizar xmysqladmin,mysql_webadmin e mesmo xmysql para inserir,
alterar e atualizar valores nas tabelas de permiss˜oes. Vocˆe pode encontrar estes utilit´arios
em Diret´orio de Colaboradores do Website do MySQL.
4.3.6 Configurando Senhas
Na maioria dos casos vocˆe deve utilizar GRANT para configurar seus usu´arios e senhas, por-
tanto, as informa¸oes exibidas a seguir s˜ao aplicadas somentes para usu´arios avan¸cados. See
hundefinedi[GRANT], page hundefinedi.
Os exemplos nas se¸oes precedentes ilustram um princ´
ipio importante: quando vocˆe ar-
mazena uma senha n˜ao-vazia utilizando INSERT ou UPDATE vocˆe deve utilizar a fun¸ao
PASSWORD() para criptograf´a-la. Isto ´e porque a tabela user armazena senhas na forma
criptografada, e n˜ao como texto puro. Se vocˆe esquecer deste fato, ´e prov´avel que voe
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 ´e que o valor ’biscuit’ ´e armazenado como a senha na tabela user. Quando
o usu´ario jeffrey tentar se conectar ao servidor utilizando esta senha, o cliente mysql a
criptografa utilizando a fun¸ao PASSWORD(), gerando um vetor de autentica¸ao baseado em
uma senha criptografada e um n´umero randˆomico, obtido do servidor, e envia o resultado
ao servidor. O servidor usa o valor do campo password na tabela user (que ´e o valor
’biscuit’ ao criptografado ) para realizar os mesmos c´alculos e comparar os resultados.
A compara¸ao falha e o servidor rejeita a conex˜ao:
shell> mysql -u jeffrey -pbiscuit test
Access denied
As senhas devem ser criptografadas quando elas s˜ao inseridas na tabela user, portanto a
instru¸ao INSERT deveria ter sido informada no seguinte formato:
mysql> INSERT INTO user (Host,User,Password)
VALUES(’%’,’jeffrey’,PASSWORD(’biscuit’));
Voe deve tamem utilizar a fun¸ao PASSWORD() quando utilizar instru¸oes SET PASSWORD:
mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD(’biscuit’);
Se vocˆe configurar senhas utilizando a instru¸ao GRANT ... IDENTIFIED BY ou o comando
mysqladmin password, a fun¸ao PASSWORD() ´e desnecess´aria. Ambos tomam o cuidado de
criptografar a senha para vocˆe, enao vocˆe deve especificar a senha ’biscuit’ desta forma:
mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY ’biscuit’;
ou
Chapter 4: Administra¸ao de Bancos de Dados MySQL 227
shell> mysqladmin -u jeffrey password biscuit
NOTA: PASSWORD() ao realiza criptografia de senhas da mesma forma em que as senhas do
Unix s˜ao criptografadas. Voe n˜ao deve assumir que se sua senha Unix e a do MySQL s˜ao
as mesmas, o resultado de PASSWORD() ir´a resultar no mesmo valor criptografado como o
armazenado no arquivo de senhas do Unix. See hundefinedi[User names], page hundefinedi.
4.3.7 Mantendo Sua Senha Segura
ao ´e aconselh´avel especificar uma senha de uma forma que a exponha e possa ser descoberta
por outros usu´arios. Os m´etodos que vocˆe pode usar para especificar sua senha quando
executar programas clientes s˜ao listados abaixo, juntamente com as determina¸oes de riscos
de cada m´etodo:
Nunca forne¸ca a um usu´ario normal acesso `a tabela mysql.user. O conhecimento de
uma senha criptografada possibilita a conex˜ao como este usu´ario. As senhas s´o est˜ao
embaralhadas para que n˜ao seja poss´
ivel chegar `a senha real que foi usada (acontece
muito a utiliza¸ao de senhas similares em outras aplica¸oes).
Uso da op¸ao -psua_senha ou --password=sua_senha na linha de comando. Isto ´e
conveniente mas inseguro, porque sua senha se torna vis´
ivel para programas de in-
forma¸ao do sistema (como no ps) que pode ser chamado por outros usu´arios para
exibir linhas de comando. (clientes MySQL normalmente gravam zeros em cima do ar-
gumento da linha de comando durante sua sequˆencia de inicializa¸ao, mas ainda existe
um breve intervalo no qual o valor est´a vis´
ivel.)
Uso das op¸oes -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.
´
E mais seguro digitar sua senha desta forma do que especific´a-la na linha de comando
porque ela n˜ao fica vis´
ivel a outros usu´arios. Entretanto este m´etodo de digitar uma
senha ´e v´alido somente para programas que vocˆe executa de forma interativa. Se vocˆe
deseja chamar um cliente de um script que n˜ao execute interativamente, n˜ao existir´a
oportunidade de digitar a senha do terminal. Em alguns sistemas, vocˆe pode descobrir
que a primeira linha do seu script ´e lida e interpretada (incorretamente) como sua
senha!
Armazenar a sua senha em um arquivo de configura¸ao. Por exemplo, vocˆe pode listar
sua senha na se¸ao [client] do arquivo ‘.my.cnf’ no seu diret´orio home:
[client]
password=sua_senha
Se vocˆe armazenar sua senha em um arquivo ‘.my.cnf’, o arquivo n˜ao pode ser lido por
seu grupo ou pelos outros usu´arios. Tenha certeza que o modo de acesso do arquivo ´e
400 ou 600 See hundefinedi[Option files], page hundefinedi.
Voe pode armazenar sua senha na vari´avel de ambiente MYSQL_PWD, mas este m´etodo
deve ser considerado extremamente inseguro e n˜ao deve ser usado. Algumas vers˜oes
de ps incluem uma op¸ao para exibir o ambiente de processos em execu¸ao; sua senha
estaria em texto puro para a leitura para todos os usu´arios. Mesmo em sistemas sem
228 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
esta vers˜ao do ps, seria imprudˆencia assumir que n˜ao existe outro m´etodo para observar
o ambiente de processos. See hundefinedi[Environment variables], page hundefinedi.
Em resumo, os m´etodos mais seguros seriam que o programa cliente solicitasse a senha ou
especificar a senha em um arquivo ‘.my.cnf’ corretamente protegido.
4.4 Preven¸ao de Disastres e Recupera¸ao
4.4.1 Backups dos Bancos de Dados
Como as tabelas do MySQL s˜ao armazenadas como arquivos, ´e mais f´acil realizar um
backup. Para obter um backup consistente, fa¸ca um LOCK TABLES nas tabelas relevantes
seguido por FLUSH TABLES para as tabelas. See hundefinedi[LOCK TABLES], page hunde-
finedi. See hundefinedi[FLUSH], page hundefinedi. Vocˆe s´o precisa de um bloqueio de
leitura; isto possibilita outras threads a continuarem a pesquisar nas tabelas enquanto vocˆe
copia os arquivos no diret´orio do banco de dados. O FLUSH TABLE ´e necess´ario para garantir
que todas as p´aginas ativas de ´
indices ser˜ao escritas em disco antes de iniciar o backup.
Se vocˆe desejar realizar um backup ao n´
ivel da linguagem SQL de um tabela, vocˆe pode
utilizar SELECT INTO OUTFILE ou BACKUP TABLE. See hundefinedi[SELECT], page hunde-
finedi.See hundefinedi[BACKUP TABLE], page hundefinedi.
Outra maneira de efetuar um backup de um banco de dados ´e utilizar o programa mysqldump
ou o script mysqlhotcopy. See hundefinedi[mysqldump], page hundefinedi. See hunde-
finedi[mysqlhotcopy], page hundefinedi.
1. Fazer um backup completo dos bancos de dados:
shell> mysqldump --tab=/caminho/para/algum/dir --opt --full
ou
shell> mysqlhotcopy database /caminho/para/algum/dir
Voe tamb´em pode simplesmente copiar os arquivos das tabelas (‘*.frm’, ‘*.MYD’)
e os arquivos ‘*.MYI’) quando o servidor n˜ao estiver atualizando nada. O script
mysqlhotcopy utiliza este m´etodo.
2. Interrompa o mysqld caso ele esteja em execu¸ao, depois inicie-o com a op¸ao --log-
update[=nome_arquivo]. See hundefinedi[Update log], page hundefinedi. Os arquivos
de log atualizados fornecem a informa¸ao necess´aria para replicar altera¸oes ao banco
de dados que forem feitas depois do ponto em que voe executou mysqldump.
Se vocˆe 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´o ir´a funcionar se vocˆe iniciou o
MySQL com --log-update, See hundefinedi[Update log], page hundefinedi,):
1. Restaure o backup original feito com o mysqldump.
2. Execute o seguinte comando para re-executar as atualiza¸oes armazenadas no log
bin´ario:
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
Se vocˆe estiver utilizando o log atualizado, pode utilizar:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 229
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
O comando ls ´e usado para obter todos os arquivos de log na ordem correta.
Voe pode tamb´em 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ˆe precisar´a 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 ´unicos.
Se vocˆe tiver problemas de performance realizando backups no seu sistema, vocˆe pode
resolver isto configurando uma replica¸ao e fazendo os backups na m´aquina escrava no
lugar da master. See hundefinedi[Replication Intro], page hundefinedi.
Se vocˆe estiver utilizando um sistema de arquivos Veritas, vocˆe 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.4.2 Sintaxe de BACKUP TABLE
BACKUP TABLE nome_tabela[,nome_tabela...] TO ’/caminho/para/diret´orio/backup’
Faz uma c´opia de todos os arquivos de tabela para o diret´orio de backup que ´e o m´
inimo
necess´ario para restaur´a-lo. Atualmente s´o funciona para tabelas MyISAM. Para tabela
MyISAM, copia os arquivos .frm (defini¸oes) e .MYD (dados). O arquivo de ´
indice pode ser
reconstru´
ido a partir destes dois.
Antes de utilizar este comando, por favor veja See hundefinedi[Backup], page hundefinedi.
Durante o backup, o bloqueio de leitura (read lock) ser´a usado para cada tabela, uma de
cada vez, `a medida que o backup ´e realizado. Se vocˆe deseja fazer backup de diversas tabelas
como um snapshot, vocˆe deve primeiro usar LOCK TABLES obtendo um bloqueio de leitura
para cada tabela no grupo.
O comando retorna uma tabela com as seguintes colunas:
Coluna Valor
Table Nome da Tabela
Op Sempre “backup”
Msg type Um dos seguintes: status,error,info ou warning.
Msg text A mensagem.
Note que o comando BACKUP TABLE est´a dispon´
ivel somente no MySQL vers˜ao 3.23.25 e
posterior.
4.4.3 Sintaxe de RESTORE TABLE
RESTORE TABLE nome_tabela[,nome_tabela...] FROM ’/caminho/para/diret´orio/backup’
Restaura as tabelas utilizando o backup feito com BACKUP TABLE. Tabelas existentes n˜ao
ser˜ao reescritas - se vocˆe tentar restaurar sobre uma tabela existente, obter´a um erro. A
restaura¸ao demora mais tempo do que o backup pois ´e necess´ario reconstruir o ´
indice.
230 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Quanto mais chaves tiver, mais demorado ser´a. Como no comando BACKUP TABLE, atual-
mente s´o funciona com tabelas MyISAM.
O comando retorna uma tabela com as seguintes colunas:
Coluna Valor
Table Nome da Tabela
Op Sempre “restore”
Msg type Um dos seguintes: status,error,info ou warning.
Msg text A mensagem.
4.4.4 Sintaxe de CHECK TABLE
CHECK TABLE nome_tabela[,nome_tabela...] [op¸c~ao [op¸c~ao...]]
op¸c~ao = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
CHECK TABLE funciona somente em tabelas MyISAM. Em tabelas MyISAM ´e a mesma coisa
que executar myisamchk -m nome_tabela na tabela.
Se vocˆe n˜ao especificar nenhuma op¸ao, MEDIUM ´e usado.
Verifica se existem erros na(s) tabela(s). Para as tabelas MyISAM as estat´
isticas das chaves
ao atualizadas. O comando retorna uma tabela com as seguintes colunas:
Coluna Valor
Table Nome da Tabela.
Op Sempre “check”.
Msg type Um dos seguintes: status,error,info, or warning.
Msg text A mensagem.
Note que vocˆe pode obter v´arias linhas de informa¸oes para cada tabela conferida. A ´ultima
linha ir´a ser do tipo Msg_type status e normalmente deve estar OK. Se vocˆe n˜ao obteve OK
ou Not checked, deve ser executado, normalmente, um reparo da tabela. See hundefinedi
[Table maintenance], page hundefinedi.Not checked significa que a tabela de um dado
TIPO disse ao MySQL que n˜ao havia nenhuma necessidade de verific´a-la.
Os diferentes tipos de consistˆencias continuam para os seguintes:
Tipo Significado
QUICK ao busca os registros verificando liga¸oes incorretas.
FAST o confere tabelas que n˜ao foram fechadas corretamente.
CHANGED o verifica as tabelas que foram alteradas desde a ´ultima conferˆencia
ou que n˜ao foram fechadas corretamente.
MEDIUM Busca os registros para verificanado que liga¸oes removidas est˜ao ok.
Isto tamb´em calcula uma chave de conferˆencia para os registros e ver-
ifica isto com um checksum calculado para as chaves.
EXTENDED Faz uma busca completa nas chaves para todas as chaves em cada
registro. Isto assegura que a tabela est´a 100% consistente, mas pode
demorar muito tempo para executar!
Para tabelas MyISAM de tamanho dinˆamico, uma verifica¸ao iniciada sempre far´a uma veri-
fica¸ao MEDIUM. Para registros de tamanho est´atico n´os saltamos a busca de registros para
QUICK eFAST a que os registros est˜ao raramente corrompidos.
Voe pode combinar op¸oes de consistˆencia como em:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 231
CHECK TABLE test_table FAST QUICK;
O qual s´o far´a uma verifica¸ao r´apida na tabela se ela n˜ao for fechada corretamente.
NOTA: em alguns casos CHECK TABLE ir´a alterar a tabela! Isto acontece se a tabela estiver
marcada como ’corrupted’ (corrompida) ou ’not closed properly’ (n˜ao foi fechada correta-
mente) mas o CHECK TABLE ao encontrar n˜ao encontrar nenhum problema na tabela. Neste
caso, CHECK TABLE ir´a marcar a tabela como ok.
Se uma tabela estiver corrompida, ´e prefer´
ivel que seja um problema nos ´
indices e n˜ao na
parte de dados. Todos os tipos de consistˆencia acima sempre confere os ´
indices e deve enao
encontrar a maioria dos erros.
Se vocˆe s´o quiser conferir uma tabela que acredita estar ok, vocˆe n˜ao deve utilizar nenhuma
op¸ao para o comando check ou utilizar a op¸ao QUICK. O ´ultimo deve ser utilizado quando
vocˆe estiver com pressa e o r´
isco do QUICK ao encontrar um erro no arquivo de dados for
m´
inimo (Na maioria dos casos o MySQL pode encontrar, sob utiliza¸ao normal, qualquer
erro no arquivo de dados. Se isto ocorrer, ent˜ao a tabela ser´a marcada como ’corrupted’,
neste caso a tabela n˜ao poder´a ser utilizada at´e ser reparada).
FAST eCHANGED ao normalmente chamados a partir de um script (um exemplo ´e ser exe-
cutado a partir do cron) Se vocˆe desejar conferir suas tabelas de tempos em tempos. Na
maioria dos casos o FAT ´e uma op¸ao melhor que CHANGED. (O ´unico caso em que isto n˜ao
acontece ´e se houver suspeitas de bug no c´odigo 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´
icil ocorrer caso uma conferˆencia normal
tenha executado com sucesso!).
Algumas coisas relatadas pela verifica¸ao de tabelas, n˜ao podem ser corrigidas automatica-
mente:
Found row where the auto_increment column has the value 0.
Isto significa que vocˆe possui na tabela um registro onde o campo ´
indice que utiliza o
recurso auto_increment contem o valor 0. (´
E poss´
ivel criar um registro onde a coluna
de auto incremento seja 0 definindo explicitamente 0 em uma instru¸ao UPDATE)
Isto n˜ao ´e exatamente um erro, mas pode causar problemas se vocˆe decidir descarregar
a tabela e restaur´a-la ou executar um ALTER TABLE na tabela. Neste caso a coluna
de auto incremento ir´a 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¸ao UPDATE para configurar a coluna
para algum outro valor diferente de 0.
4.4.5 Sintaxe de REPAIR TABLE
REPAIR TABLE nome_tabela[,nome_tabela...] [QUICK] [EXTENDED]
REPAIR TABLE funciona somente em tabelas MyISAM e ´e a mesma coisa que executar
myisamchk -r nome_tabela na tabela.
Normalmente vocˆe nunca deve executar este comando, mas se um disastre ocorrer vocˆe vai
precisar recuperar seus dados de uma tabela MyISAM utilizando REPAIR TABLE. Se as suas
tabelas estiverem muito corrompidas, vocˆe deve encontrar a raz˜ao para isto! See hundefinedi
[Crashing], page hundefinedi. See hundefinedi[MyISAM table problems], page hundefinedi.
232 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
REPAIR TABLE repara uma tabela possivelmente corrompida. O comando retorna uma tabela
com as seguintes colunas:
Coluna Valor
Table Nome da Tabela
Op Sempre “repair”
Msg type Um dos seguintes: status,error,info ou warning.
Msg text A mensagem.
Perceba que vocˆe pode obter v´arias linhas de informa¸oes para cada tabela recuperada. A
ultima linha ser´a de Msg_type status e normalmente deve exibir OK. Se o retorno n˜ao for
OK, vocˆe pode tentar reparar a tabela com myisamchk -o, j´a que REPAIR TABLE ainda n˜ao
implementa todas as op¸oes de myisamchk. Futuramente iremos torn´a-lo mais flex´
ivel.
Se o parˆametro QUICK for especificado o MySQL tentar´a REPARAR somente a ´arvore de
´
indices.
Se vocˆe utilizar EXTENTED o MySQL criar´a o ´
indice, registro a registro em vez de criar um
´
indice de uma vez com ordena¸ao; Isto pode ser melhor que a ordena¸ao em chaves de
tamanho fixo se vocˆe tiver grandes chaves do tipo char() que compactam muito bem.
4.4.6 Utilizando myisamchk para Manuten¸ao de Tabelas e
Recupera¸ao em Caso de Falhas
A partir do MySQL vers˜ao 3.23.13 vocˆe pode mandar verificar as tabelas MyISAM com
o comando CHECK TABLE. See hundefinedi[CHECK TABLE], page hundefinedi. Pode-
se reparar tabelas com o comando REPAIR TABLE. See hundefinedi[REPAIR TABLE],
page hundefinedi.
Para verificar/reparar tabelas MyISAM (.MYI e.MYD) vocˆe deve utilizar o utilit´ario
myisamchk. Para consistir/reparar tabelas ISAM (.ISM e.ISD) vocˆe deve usar o utilit´ario
isamchk. See hundefinedi[Tipos de Tabelas], page hundefinedi.
No texto a seguir iremos comentar sobre o myisamchk, mas tudo tamb´em se aplica ao antigo
isamchk.
Voe pode utilizar o utilit´ario myisamchk para obter informa¸c˜oes sobre suas tabelas de
bancos de dados, verfic´a-las, repar´a-las ou otimiz´a-las. As seguintes se¸oes descrevem como
executar myisamchk (incluindo uma descri¸ao de suas op¸oes), como montar um calend´ario
de manuten¸ao, e como utilizar o myisamchk para executar suas v´arias fun¸oes.
Voe pode, na maioria dos casos, utilizar o comando OPTIMIZE TABLES para otimizar e
reparar tabelas, mas n˜ao ´e t˜ao r´apido e confi´avel (no caso real de erros fatais) como o
mysisamchk. Por outro lado, OPTIMIZE TABLE ´e mais f´acil de usar e vocˆe n˜ao tem que se
preocupar com a recarrega das tabelas. See hundefinedi[OPTIMIZE TABLE], page hunde-
finedi.
Mesmo os reparos realizados pelo myisamchk ao bastante seguros, por´em ´e sempre uma
boa id´eia fazer um backup dos dados ANTES de realizar um reparo (ou qualquer coisa que
far´a grandes altera¸oes em alguma tabela)
4.4.6.1 Sintaxe de chamada do myisamchk
myisamchk ´e chamado desta forma:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 233
shell> myisamchk [op¸c~oes] nome_tabela
As op¸c~oes especificam o que vocˆe deseja que o myisamchk fa¸ca. Elas s˜ao descritas abaixo.
(Voe tamb´em pode obter a lista das op¸oes com myisamchk --help.) Sem op¸oes, o
myisamchk simplesmente checa sua tabela. Para obter maiores informa¸oes ou dizer ao
myisamchk para tomar a¸oes corretivas, especifique as op¸oes descritas abaixo e nas se¸oes
seguintes.
nome_tabela ´e o nome da tabela do banco de dados que vocˆe deseja verificar/reparar.
Se vocˆe executar o myisamchk em algum lugar diferente do diret´orio do banco de dados,
vocˆe deve especificar o caminho para o arquivo, porque myisamchk ao faz id´eia de onde
seu banco de dados se encontra. Na verdade, myisamchk ao se importa se os arquivos
est˜ao localizados em um diret´orio de banco de dado; vocˆe pode copiar os arquivos que
correspondem a uma tabela de banco de dados em outra localiza¸ao e realizar neste outro
lugar as opera¸oes corretivas.
Voe pode nomear v´arias tabelas na linha de comando do myisamchk se voe desejar. Voe
tamb´em pode especificar um nome como um arquivo de ´
indice (com o sufixo ‘.MYI’), que
lhe permite especificar todas tabelas em um diret´orio utilizando o padr˜ao ‘*.MYI’. Por
exemplo, se vocˆe est´a em um diret´orio de banco de dados, vocˆe pode checar todas as
tabelas no diret´orio desta forma:
shell> myisamchk *.MYI
Se vocˆe n˜ao estiver no diret´orio do banco de dados, vocˆe pode verificar todas as tabelas
existentes especificando o caminho para o diret´orio:
shell> myisamchk /caminho/para/banco_de_dados/*.MYI
Voe pode verificar todas as tabelas em todos os bancos de dados especificando um meta
caracter com o caminho para o diret´orio de banco de dados do MySQL:
shell> myisamchk /caminho/para/diret´orio_dados/*/*.MYI
A maneira recomendada para conferir todas as tabelas rapidamente ´e:
myisamchk --silent --fast /caminho/para/diret´orio_dados/*/*.MYI
isamchk --silent /caminho/para/diret´orio_dados/*/*.ISM
Se vocˆe 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´orio_
dados/*/*.MYI
isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -
O write_buffer=1M /caminho/para/diret´orio_dados/*/*.ISM
A linha acima assume que vocˆe tem mais de 64 MB de mem´oria livre.
Perceba que se vocˆe obter um erro do tipo:
myisamchk: warning: 1 clients is using or hasn’t closed the table properly
Isto significa que vocˆe est´a tentando verificar uma tabela que est´a sendo atualizada por
outro programa (como o servidor mysqld) que ainda n˜ao fechou o arquivo ou que finalizou
sem fechar o arquivo corretamente.
Se seu mysqld est´a em execu¸ao, vocˆe deve for¸car o sincronimo e fechamento de todas tabelas
com FLUSH TABLES e assegurar que ningu´em mais esteja utilizando as tabelas quando for
executar o myisamchk. No MySQL vers˜ao 3.23 a forma mais simples de evitar este problema
´e utilizar CHECK TABLE no lugar de myisamchk para verificar as tabelas.
234 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.4.6.2 Op¸oes Gen´ericas do myisamchk
myisamchk suporta as seguintes op¸oes.
-# ou --debug=debug_options
Sa´
ida do log de depura¸ao. A string debug_options geralmente ´e
’d:t:o,nomearquivo’.
-? ou --help
Exibe uma mensagem de ajuda e sai.
-O var=op¸c~ao, --set-variable var=op¸c~ao
Configura o valor de uma vari´avel. As vari´aveis poss´
iveis e seus valores padr˜oes
para o myisamchk podem ser examinados com myisamchk --help
key buffer size 523264
read buffer size 262136
write buffer size 262136
sort buffer size 2097144
sort key blocks 16
decode bits 9
sort_buffer_size ´e utilizado quando as chaves s˜ao reparadas pela ordena¸ao
das chaves, que ´e o caso normal quando vocˆe utiliza --recover.
key_buffer_size ´e utilizando quando vocˆe estiver conferindo a tabela com -
-extended-check ou quando as chaves s˜ao reparadas inserindo-as registro a
registro na tabela (como com inserts normais). O reparo atrav´es de buffer de
chaves (key buffer) ´e utilizado nos seguintes casos:
Se vocˆe utilizar --safe-recover.
Se vocˆe estiver utilizando um ´
indice FULLTEXT.
Se os arquivos tempor´arios necess´arios para ordenar as chaves forem maior
que o dobro do tamanho de quando se criasse o arquivo de chaves dire-
tamente. Isto ´e o caso quando se tem chaves CHAR,VARCHAR ou TEXT tao
grandes quanto necess´ario pela ordena¸ao para armazenar todas as chaves
durante o processo. Se vocˆe tiver muito espa¸co tempor´ario e puder for¸car
omyisamchk a reparar por ordena¸ao vocˆe pode utilizar a op¸ao --sort-
recover.
Repara¸ao atrav´es do buffer de chaves (key buffer) economiza muito mais espa¸co
em disco do que utilizando ordena¸ao, mas ´e muito mais lenta.
Se vocˆe deseja uma repara¸ao mais r´apida, configure as vari´aveis acima para
cerca de 1/4 da sua mem´oria dispon´
ivel. Voe pode configurar as vari´aveis para
valores altos, pois somente um dos buffers acima ser´a utilizado a cada vez.
-s ou --silent
Modo discreto ou silencioso. Escreve a sa´
ida somente quando um erro ocorre.
Voe pode utilizar -s duas vezes (-ss) para deixar o mysisamchk mais silen-
cioso.
-v ou --verbose
Modo prolixo. Gera mais informa¸ao de sa´
ida. Ele pode ser utilizado com -d e
-e. Utilize -v m´ultiplas vezes -vv,-vvv) para gerar mais sa´
ida!
Chapter 4: Administra¸ao de Bancos de Dados MySQL 235
-V ou --version
Exibe a vers˜ao do myisamchk e sai.
-w ou, --wait
No lugar de gerar um erro se a tabela estiver bloqueada, espere at´e que a tabela
fique livre antes de continuar. Perceba que se voe estiver utilizando mysqld na
tabela com --skip-locking, a tabela s´o pode ser trancada por outro comadno
myisamchk.
4.4.6.3 Op¸oes de Verifica¸ao do myisamchk
-c ou --check
Confere por erros na tabela. Esta ´e a opera¸ao padr˜ao se vocˆe n˜ao estiver
utilizando op¸oes que a anulam.
-e ou --extend-check
Verifica a tabela de forma completa (que ´e bastante lento se vocˆe tiver v´arios
´
indices). Esta op¸ao 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ˆe estiver utilizando --extended-check e tiver muita mem´oria, vocˆe deve
aumentar um pouco o valor de key_buffer_size!
-F ou --fast
Verifica apenas tabelas que n˜ao foram fechadas corretamente.
-C ou --check-only-changed
Verifica apenas tabelas que foram alteradas desde a ´ultima verifica¸ao.
-f ou --force
Reinicia o myisamchk com -r (reparos) na tabela, se myisamchk encontrar quais-
quer erros na tabela.
-i ou --information
Exibe informa¸oes e estat´
isticas sobre a tabela que estiver sendo verificada.
-m ou --medium-check
Mais r´apido 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´
icio integral da op¸ao --check-only-
changed, mas vocˆe n˜ao deve utilizar esta op¸ao se o servidor mysqld esta usando
a tabela e o mysqld esta sendo executado com --skip-locking.
-T ou --read-only
ao marca as tabelas como verificadas. Isto ´e ´util se vocˆe utiliza o myisamchk
para verificar uma tabela que esteja em uso por alguma outra aplica¸ao que
ao utiliza bloqueios (como no mysqld --skip-locking).
236 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.4.6.4 Op¸oes de Reparos do myisamchk
As seguintes op¸oes s˜ao usadas se vocˆe iniciar o myisamchk com -r ou -o:
-D # ou --data-file-length=#
Tamanho m´aximo do arquivo de dados (ao recriar arquivos de dados quando
eles est˜ao ’cheios’).
-e ou --extend-check
Tenta recuperar todos registros poss´
iveis do arquivo de dados. Normalmente
isto ir´a encontrar tamb´em v´arias linhas com lixo. ao utiliza esta op¸ao a
menos que esteja em desespero total.
-f ou --force
Sobrescreve antigos arquivos tempor´arios (nome_tabela,TMD) em vez de abor-
tar.
-k # ou keys-used=#
Se vocˆe estiver utilizando ISAM, diz ao manipulador de tabelas do ISAM para
atualizar somente os primeiros #´
indices. Se vocˆe 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¸oes mais r´apidas! ´
Indices
desativados podem ser reativados utilizando myisamchk -r.
-l ou --no-symlinks
ao segue links simolicos. Normalmente o myisamchk repara a tabela para
qual um link simolico aponta. Esta op¸ao n˜ao existe no MySQL 4.0 pois o
MySQL 4.0 n˜ao ir´a remover links simolicos durante os reparos.
-r ou --recover
Pode concertar quase tudo excetos chaves ´unicas que n˜ao s˜ao ´unicas (Que ´e um
erro extremamente indesej´avel com tabelas ISAM/MyISAM). Se vocˆe deseja
recuperar uma tabela, esta ´e primeira op¸ao a ser tentada. Somente se o my-
isamchk relatar que a tabela n˜ao pode ser recuperada pelo -r vocˆe deve tentar
enao a op¸ao -o. (Perceba que no caso indesej´avel de -r falhar, o arquivo de
dados continuar´a intacto.) Se vocˆe possui muita mem´oria, vocˆe deve aumentar
o tamanho de sort_buffer_size!
-o ou --safe-recover
Utiliza um antigo m´etodo de recupera¸ao (le atrav´es de todos registros na ordem
e atualiza todas as ´arvores de ´
indices baseado nos registros encontrados); esta
op¸ao ´e muito mais lenta que -r, mas pode tratar v´arios casos indesej´aveis que
o-r ao consegue tratar. Este m´etodo de recupera¸ao tamb´em utiliza muito
menos espa¸co em disco que -r. Normalmente sempre se deve tentar, primeiro,
um reparo com -r, e somente se ele falhar, usar -o.
Se vocˆe possuir muita mem´oria, vocˆe deve aumentar o tamanho de sort_
buffer_size!
-n ou --sort-recover
For¸ca o uso de ordena¸ao do myisamchk para resolver as chaves mesmo se os
arquivos tempor´arios forem muito grandes. Isto n˜ao ter´a efeito algum se vocˆe
tiver chaves textuais na tabela.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 237
--character-sets-dir=...
Diret´orio onde conjuntos de caracteres s˜ao armazenados.
--set-character-set=name
Altere o conjunto de caracteres usado pelo ´
indice
.t ou --tmpdir=path
Caminho para armazenar arquivos tempor´arios. Se isto n˜ao for configurado,
myisamchk ir´a usar a vari´avel de ambiente TMPDIR para isto.
-q ou --quick
Reparo r´apido sem modificar o arquivo de dados. Pode ser fornecido um se-
gundo -q para for¸car o myisamchk para modificar o arquivo de dados original
no caso de chaves duplicadas.
-u ou --unpack
Descompacta arquivo empacotado com o myisampack.
4.4.6.5 Outras Op¸oes de myisamchk
Outras a¸oes que o myisamchk pode fazer, al´em de reparar e conferir tabelas:
-a ou --analyze
Analisa a distribui¸ao das chaves. Isto habilita o otimizador de joins para
a melhor escolha da ordem em deve-se unir as tabelas e quais chaves devem
ser usadas: myisamchk --describe --verbose nome_tabela’ ou utilizar SHOW
KEYS no MySQL.
-d ou --description
Exibe algumas informa¸oes sobre a tabela.
-A ou --set-auto-increment[=valor]
For¸ca o auto increment a iniciar a partir deste ponto ou de um valor mais alto.
Se nenhum valor for fornecido, ent˜ao ´e configurado o pr´oximo valor de auto
incremento at´e o valor mais alto j´a utilizado da chave +1.
-S ou --sort-index
Ordena os blocos da arvore de ´
indices na ordem: mais alto ao mais baixo. Isto
ir´a otimizar pesquisas e tornar´a a explora¸ao de tabela por chave mais r´apida.
-R ou --sort-records=#
Ordena registros de acordo com um ´
indice. Isto deixa seus dados muito mais
localizados e pode acelerar opera¸oes SELECTs e ORDER BY neste ´
indice. (Ele
pode ser muito lento para ordenar na primeira vez!) Para encontrar os n´umeros
de ´
indices de uma tabela, utilize SHOW INDEX, que exibe os ´
indices de uma tabela
na mesma ordem que o myisamchk os enxerga. ´
Indices s˜ao numerados a partir
do 1.
4.4.6.6 Uso de Mem´oria do myisamchk
Aloca¸ao de mem´oria ´e importante quando voe executa o myisamchk.myisamchk ao
utiliza mais mem´oria do que vocˆe especifica com a op¸ao -O. Se vocˆe ir´a utilizar o myisamchk
238 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
em grandes arquivos, vocˆe deve decidir primeiro quanta mem´oria deseja usar. O valor
padr˜ao ´e utilizar somente 3MB para corre¸oes. Utilizando valores maiores, o myisamchk
pode operar mais rapidamente. Por exemplo, se vocˆe tiver mais que 32M de mem´oria
RAM, vocˆe pode utilizar op¸c˜oes tais como esta (em adi¸ao `as v´arias outras que podem ser
especificadas):
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
Utilizando -O sort=16M provavelmente ´e suficiente para a maioria dos casos.
Certiffique-se que o myisamchk utiliza arquivos tempor´arios em TMPDIR. Se TMPDIR aponta
para um sistema de arquivos em mem´oria, vocˆe pode facilmente obter erros de mem´oria.
Se isto acontecer, configure TMPDIR para apontar para algum diret´orio com mais espa¸co e
reinicie o myisamchk.
Quando reparando, o myisamchk tamb´em precisar´a de bastante espa¸co em disco:
Dobra-se o tamanho do arquivo de registros (o original e uma c´opia). Este espa¸co n˜ao
´e necess´ario se for feito um reparo com --quick, j´a que neste caso somente o arquivo
de ´
indices ser´a recriado. Este espa¸co ´e necess´ario no mesmo disco que se encontra o
arquivo de registros original!
Espa¸co para o novo arquivo de ´
indice que substitui o antigo. O arquivo de´
indices antigo
´e truncando no in´
icio, portanto, normalmente este espa¸co ´e ignorado. Este espa¸co ´e
necess´ario no mesmo disco que o arquivo de ´
indice original!
Quando utilizando --recover ou --sort-recover (mas n˜ao quando usando --safe-
recover, ser´a necess´ario espa¸co para um buffer de ordena¸ao de: (maior_chave
+ tamanho_do_ponteiro_de_registro)*n´umero_de_registros * 2. Voe pode
conferir o tamanho das chaves e o tamanho do ponteiro de registro com myisamchk
-dv tabela. Este espa¸co ´e alocado no disco tempor´ario (especificado por TMPDIR ou
--tmpdir=#).
Se vocˆe tiver um problema com espa¸co em disco durante o reparo, pode-se tentar usar
--safe-recover em vez de --recover.
4.4.6.7 Uso do myisamchk para Recupera¸ao em Caso de Falhas
Se vocˆe executa o mysqld com a op¸ao --skip-locking (que ´e o padr˜ao em alguns sistemas,
como o Linux), vocˆe n˜ao pode utilizar com seguran¸ca o myisamchk para conferir uma tabela
se o mysqld estiver utilizando a mesma tabela. Se vocˆe pode ter certeza que ningu´em est´a
acessando as tabelas atrav´es do mysqld enquanto vocˆe executa o myisamchk, vocˆe s´o tem
que executar o mysqladmin flush-tables antes de iniciar a verifica¸ao das tabelas. Se vocˆe
ao tem certeza, ent˜ao vocˆe deve desligar o mysqld enquanto verifica as tabelas. Se vocˆe
executa o myisamchk enquanto o mysqld estiver atualizando as tabelas, vocˆe pode obter
um altera que a tabela est´a corrompida mesmo se n˜ao estiver.
Se vocˆe n˜ao estiver utilizando --skip-locking, pode usar o myisamchk para conferir as
tabelas a qualquer hora. Enquanto voe faz isto, todos os clientes que tentarem atualizar a
tabela ir˜ao esperar at´e que o myisamchk esteja pronto, antes de continuar.
Se vocˆe utilizar o myisamchk para reparar ou otimizar tabelas, vocˆe DEVE sempre assegurar
que o servidor mysqld ao esteja utilizando a tabela (Isto tamb´em aplica se vocˆe utiliza --
skip-locking). Se vocˆe n˜ao desligar o mysql, vocˆe deve, pelo menos, fazer um mysqladmin
flush-tables antes de executar o myisamchk.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 239
Este cap´
itulo descreve como checar e lidar com dados corrompidos nos bancos de dados
MySQL. Se suas tabelas corromperem com frequˆencia deve ser encontrada a raz˜ao para
isto! See hundefinedi[Falhas], page hundefinedi.
A se¸ao de tabelas MyISAM contˆem motivos do porque uma tabela pode estar corrompida.
See hundefinedi[MyISAM table problems], page hundefinedi.
Quando se realizar recupera¸ao devido a falhas, ´e importante entender que cada tabela
nome_tabela em um banco de dados corresponde a tres arquivos no diret´orio do banco de
dados:
Arquivo Prop´osito
nome_tabela.frm Arquivo com defini¸oes da tabela (form)
nome_tabela.MYD Arquivo de dados
nome_tabela.MYI Arquivo de ´
indices
Cada um destes trˆes tipos de arquivos est´a sujeito a corrup¸ao de v´arias formas, mas
problemas ocorrem mais frequentemente em arquivos de dados e ´
indices.
Omyisamchk trabalha criando uma c´opia do arquivo de dados ‘.MYD’ linha a linha. Ele
termina o est´agio de reparos removendo o antigo arquivo ‘.MYD’ e renomeando o novo arquivo
com nome original. Se for utilizada a op¸ao --quick,myisamchk ao cria um arquivo
.MYD’ tempor´ario, mas assume que o arquivo ‘.MYD’ est´a correto e somente gera um novo
arquivo ´
indice sem mexer no arquivo de dados. Isto ´e seguro, pois o myisamchk detecta
automaticamente se o arquivo ‘.MYD’ est´a corrompido e aborda o reparo neste caso. Voe
pode tamb´em fornecer duas op¸oes --quick para o myisamchk. Neste caso, o myisamchk
ao aborta em alguns erros (como chaves duplicadas) mas tenta resolvˆe-los modificando o
arquivo ‘.MYD’. Normalmente o uso de duas op¸oes --quick ´e ´util somente se vocˆe tiver
muito pouco espa¸co em disco para realizer um reparo normal. Neste caso vocˆe deve pelo
menos fazer um backup antes de executar o myisamchk.
4.4.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˜ao pode encontrar ´e corrompi-
mento que envolva SOMENTE o arquivo de dados (que n˜ao ´e comum). Se vocˆe
desejar conferir uma tabela, vocˆe deve executar normalmente o myisamchk sem
op¸oes ou com as op¸oes -s ou --silent.
myisamchk -m nome_tabela
Encontra 99.999% de todos os erros. Ele verifica primeiramente erros em todas
as entradas do ´
indice e enao le todos os registros. Ele calcula um checksum
para todas as chaves nos registros e verifica se o checksum ´e o mesmo que o
checksum das chaves na ´arvore de ´
indices.
myisamchk -e nome_tabela
Realiza a verifica¸ao completa de todos os dados (-e significa “conferˆencia ex-
tendida”). Ele faz uma conferˆencia lendo todas as chaves de cada registro
para verificar se eles realmente apontam para o registro correto. Isto pode de-
morar MUITO tempo em uma tabela grande com v´arias chaves. myisamchk
normalmente ir´a parar depois do primeiro erro que encontrar. Se vocˆe deseja
240 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
obter mais informa¸oes, pode adicionar a op¸ao --verbose (-v). Isto faz o
myisamchk continuar a percorrer a tabela at´e um m´aximo de 20 erros. Em
utiliza¸ao normal, um simples myisamchk (sem argumentos al´em do nome da
tabela) ´e suficiente.
myisamchk -e -i nome_tabela
Como o comando anterior, mas a op¸ao -i diz ao myisamchk para exibir algumas
informa¸oes estat´
isticas tamb´em.
4.4.6.9 Como Reparar Tabelas
Na se¸ao seguinte n´os s´o falaremos do uso do myiasmchk em tabelas MyISAM (extens˜oes
.MYI e.MYD). Se vocˆe estiver usando tabelas ISAM (extens˜oes .ISM e.ISD), vocˆe deve usar
a ferramenta isamchk.
A partir do MySQL vers˜ao 3.23.14, vocˆe pode reparar tabelas MyISAM com o comando
REPAIR TABLE. See hundefinedi[REPAIR TABLE], page hundefinedi.
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¸oes sobre o erro vocˆe pode executar perror ###. Aqui est˜ao
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
Perceba que o erro 135, n˜ao ´e um erro que pode ser corrigido por um simples reparo.
Neste caso vocˆe deve fazer:
ALTER TABLE tabela MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
Em outros casos, vocˆe deve reparar suas tabelas. myisamchk pode normalmente detectar a
maioria das coisas que estiverem erradas.
O processo de reparo involve at´e quatro est´agios, descritos abaixo. Antes de come¸car, vocˆe
deve mudar para o diret´orio do banco de dados e conferir as permiss˜oes dos arquivos de
tabelas. Tenha certeza que eles possam ser lidos pelo usu´ario do Unix com o qual mysqld
´e executado (e para vocˆe, porque vocˆe precisa acessar os arquivos que est´a conferindo).
Chapter 4: Administra¸ao de Bancos de Dados MySQL 241
Se n˜ao estiverem, vocˆe precisa alterar os arquivos, eles tamem devem ter a permiss˜ao de
escrita para vocˆe.
Se vocˆe estiver utilizando o MySQL vers˜ao 3.23.16 e superior, vocˆe pode (e deve) usar os
comandos CHECK eREPAIR para conferir e corrigir tabelas MyISAM. See hundefinedi[CHECK
TABLE], page hundefinedi. See hundefinedi[REPAIR TABLE], page hundefinedi.
A se¸ao do manual sobre manuten¸ao de tabelas inclui as op¸oes para isamchk/myisamchk.
See hundefinedi[Table maintenance], page hundefinedi.
A seguinte se¸ao s˜ao para os casos onde o comando acima falhar ou se vocˆe desejar usar os
recursos extendidos que o isamchk emyisamchk fornecem.
Se vocˆe for reparar uma tabela da linha de comandos, deve primeiro desligar o servidor
mysqld. Perceba que quando voe executa mysqladmin shutdown em um servidor remoto,
o servidor mysqld ir´a continuar funcionando por um tempo depois do mysqladmin retornar,
at´e que todas as queries parem e todas as chaves sejam descarregadas no disco.
Est´agio 1: Verificando suas tabelas
Execute myisamchk *.MYI ou myisamchk -e *.MYI se vocˆe tiver tempo dispon´
ivel. Utilize
a op¸ao -s (silencioso) para suprimir informa¸oes desnecess´arias.
Se o servidor mysqld parar, deve ser utilizada a op¸ao --update para dizer ao myisamchk
marcar a tabela como ’checada’.
Voe deve reparar somente as tabelas em que o myisamchk indicar um erro. Para tais
tabelas, v´a para o est´agio 2.
Se vocˆe obter erros estranhos na verfica¸ao (como nos erros out of memory), ou se o
myisamchk quebrar, v´a para o est´agio 3.
Est´agio 2: Reparo simples e seguro
NOTA: Se vocˆe deseja que os reparos sejam mais r´apidos, devem ser usadas as op¸oes: -O
sorf_buffer=# -O key_buffer=# (onde # seria 1/4 da mem´oria dispon´
ivel) para todos
comandos isamchk/myisamchk.
Primeiro, tente usar myisamchk -r -q nome_tabela (-r -q significa “modo de recupera¸ao
apida”). Ele tentar´a reparar o arquivo de ´
indice sem mexer no arquivo de dados. Se
o arquivo de dados estiver normal e os links apagados apontam nas localiza¸oes corretas
dentro do arquivo de dados, isto deve funcionar e a tabela ser´a corrigida. Inicie o reparo da
pr´oxima tabela. Outra maneira seria utilizar os seguintes procedimentos:
1. Fca um backup do arquivo de dados antes de continuar.
2. Utilize myisamchk -r nome_tabela (-r significa modo de “recupera¸ao”). Isto re-
mover´a registros incorretos e deletados do arquivo de dados e reconstroi o arquivo
de ´
indices.
3. Se o passo anterior falhar, utilize myisamchk --safe-recover nome_tabela. O modo
de recupera¸ao segura utiliza um met´odo de recupera¸ao antiga que trata de alguns
casos que o modo de recupera¸ao comum n˜ao consegue (por´em ´e mais lento).
Se vocˆe obter erros estranhos no reparo (como em erros out of memory), ou se o myisamchk
falhar, v´a para o est´agio 3.
Est´agio 3: Reparo dif´
icil
Voe s´o deve atingir este est´agio se o primeiro bloco de 16K do arquivo de ´
indice estiver
destru´
ido ou conter informa¸oes incorretas, ou se o arquivo de ´
indice n˜ao existir. Neste
caso, ´e necess´ario criar um novo arquivo de ´
indice. Fca como a seguir:
242 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1. Mova o arquivo de dados para algum lugar seguro.
2. Use o arquivo de descri¸ao de tabelas para criar novos arquivos (vazios) de dados e
´
indices:
shell> mysql nome_bd
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE nome_tabela;
mysql> quit
Se sua vers˜ao do MySQL n˜ao 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˜ao
o mova o antigo arquivo de volta para o novo arquivo; vocˆe deve uma c´opia no caso
de algo der errado.)
Volte ao est´agio 2. myisamchk -r -q deve funcionar agora. (Isto n˜ao deve ser um loop
eterno.)
Est´agio 4: Reparo muito dif´
icil
Voe deve atingir este est´agio somente se o arquivo de descri¸ao tamb´em falhar. Isto nunca
deve acontecer, porque o arquivo de descri¸c˜ao n˜ao ´e alterado depois da tabela ser criada:
1. Restaure o arquivo de descri¸ao de um backup e volte ao est´agio 3. Voe pode tamb´em
restaurar o arquivo de ´
indice e voltar ao est´agio 2. No ´ultimo caso, vocˆe deve iniciar
com myisamchk -r.
2. Se vocˆe ao tem um backup mas sabe exatamente como a tabela foi criada, crie uma
opia da tabela em outro banco de dados. Remova o novo arquivo de dados, e enao
mova a descri¸ao e arquivos de ´
indice do outro banco de dados para o banco de dados
com problemas. Isto lhe fornece um novo arquivos ´
indice e descri¸ao, mas mantˆem o
arquivo de dados da mesma forma. Volte ao est´agio 2 e tente reconstruir o arquivo de
´
indices.
4.4.6.10 Otimiza¸ao de Tabelas
Para agrupar registros fragmentados e eliminar perda de espa¸co resultante de remo¸oes ou
atualiza¸oes de registros, execute myisamchk no modo de recupera¸ao:
shell> myisamchk -r nome_tabela
Voe pode otimizar uma tabela da mesma forma utilizando a instru¸ao SQL OPTIMIZE
TABLE.OPTIMIZE TABLE faz o reparo de tabelas, analisa chaves e tamem ordena a ´arvore
de ´
indices para fazer pesquisas por chave mais r´apidas. Tamb´em n˜ao existem possibilidade
de intera¸ao n˜ao desej´avel entre o utilit´ario e o servidor, porque o servidor faz todo o trabalho
quando vocˆe utiliza OPTIMIZE TABLE. See hundefinedi[OPTIMIZE TABLE], page hunde-
finedi.
myisamchk tamb´em tem um n´umero de outras op¸ao que podem ser usadas para melhorar
a performance de uma tabela:
-S, --sort-index
-R num_indice, --sort-records=num_indice
-a, --analyze
Para uma descri¸ao completa da op¸ao. See hundefinedi[myisamchk syntax], page hunde-
finedi.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 243
4.4.7 Configurando um Regime de Manuten¸ao das Tabelas
A partir do MySQL Vers˜ao 3.23.13, vocˆe pode conferir tabelas MyISAM com o comando
CHECK TABLE. See hundefinedi[CHECK TABLE], page hundefinedi. Vocˆe pode reparar
tabelas com o comando REPAIR TABLE. See hundefinedi[REPAIR TABLE], page hunde-
finedi.
´
E uma boa id´eia verificar as tabelas regularmente em vez de esperar que ocorram problemas.
Para prop´ositos de manuten¸ao vocˆe pode utilizar o myisamchk -s para verificar as tabelas.
A op¸ao -s (abrevia¸ao de --silent) faz com que o myisamchk execute em modo silencioso,
exibindo mensagens somente quando ocorrem erros.
´
E tamb´em uma boa id´eia verificar as tabelas quando o servidor inicia. Por exemplo, sempre
que a m´aquina reinicia no meio de uma atualiza¸ao, vocˆe normalmente precisar´a conferir
todas as tabelas que podem ter sido afetadas. (Isto ´e uma“tabela com falhas esperadas”.)
Voe pode adicionar um teste ao safe_mysqld que executa myisamchk para conferir todas
tabelas que foram modificadas durante as ´ultimas 24 horas se existir um arquivo ‘.pid
(process ID) antigo depois do ´ultimo reboot. (O arquivo ‘.pid’ ´e criado pelo mysqld quando
ele inicia e removido quando ele termina normalmente. A presen¸ca de um arquivo ‘.pid
durante a inicializa¸ao do sistema indica que o mysqld terminou de forma anormal.)
Um teste ainda melhor seria verificar qualquer tabela cuja a data da ´ultima modifica¸ao ´e
mais recente que a do arquivo ‘.pid’.
Voe tamb´em deve verificar suas tabelas regularmente durante a opera¸ao normal do sis-
tema. Na MySQL AB, n´os 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´orio/do/myisamchk --fast --silent /diret´orio/de/dados/*/*.MYI
Isto exibe informa¸oes sobre tabelas com falhas para que possamos examin´a-las e repar´a-las
quando necess´ario.
Como n´os n˜ao estamos tendo tabelas com falhas inesperadas (tabelas corrompidas por raz˜oes
diferentes de problemas de hardware) por v´arios anos (isto realmente ´e verdade), uma vez
por semana ´e mais que suficiente para n´os.
os recomendamos que para iniciar, vocˆe execute myisamchk -s a cada noite em todas as
tabelas que foram atualizadas durantes as ´ultimas 24 horas, at´e que vocˆe confie no MySQL
como n´os confiamos.
Normalmente vocˆe n˜ao precisar´a de tanta manuten¸ao em suas tabelas MySQL. Se vocˆe
estiver alterando tabelas com registros de tamanho dinˆamico (tabelas com colunas VARCHAR,
BLOB ou TEXT) ou tem tabelas com v´arios registros apagados vocˆe pode desejar de tempos
em tempos (uma vez ao mˆes?) desfragmentar/recuperar espa¸co das tabelas.
Voe pode fazer isto utilizando OPTIMIZE TABLE nas tabelas em quest˜ao ou se vocˆe puder
desligar o servidor mysqld por um tempo fa¸ca:
isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
myisamchk -r --silent --sort-index -O sort_buffer_size=16M */*.MYI
244 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.4.8 Obtendo Informa¸oes sobre as Tabelas
Para obter uma descri¸ao de uma tabela ou estat´
isticas sobre ela, utilize os comandos
mostrados abaixo, n´os explicaremos algumas das informa¸oes em mais detalhes posterior-
mente:
myisamchk -d nome_tabela
Executa o myisamchk no “modo descritivo” para produzir uma descri¸c˜ao de sua
tabela. Se vocˆe iniciar o servidor MySQL utilizando a op¸ao --skip-locking,
myisamchk pode relatar um erro para uma tabela que est´a sendo atualizada
enquanto ´e executado. Entretanto, como o myisamchk ao altera a tabela no
modo de descri¸ao, n˜ao existem riscos de destrui¸ao de dados.
myisamchk -d -v nome_tabela
Para produzir mais informa¸oes sobre o que myisamchk est´a fazendo, adicione
-v para solicitar a execu¸ao em modo verbose.
myisamchk -eis nome_tabela
Exibe somente as informa¸oes mais importantes de uma tabela. Ele ´e lento
porque ´e necess´ario ler a tabela inteira.
myisamchk -eiv nome_tabela
Isto se parece com -eis, mas lhe diz o que est´a sendo feito.
Exemplo da sa´
ida 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´
ida 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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 245
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´
ida 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´
ida de myisamchk -eiv:
Checking MyISAM file: company
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
block_size 1024:
index 1:
246 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
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˜ao os tamanhos dos arquivos de dados e ´
indices 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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 247
Explica¸oes para os tipos de informa¸oes que o myisamchk produz s˜ao fornecidas abaixo. O
“keyfile” ´e o arquivo de ´
indices. “Registro” e “linha” s˜ao sinˆonimos:
ISAM file Nome do arquivo (´
indice) ISAM.
Isam-version
Vers˜ao do formato ISAM. Atualmente sempre 2.
Creation time
Quando o arquivo de dados foi criado.
Recover time
Quando foi a ´ultima vez que o arquivo de ´
indices/dados foi reconstru´
ido.
Data records
Quantos registros existem na tabela.
Deleted blocks
Quantos blocos apagados continuam alocando espa¸co. Vocˆe pode otimizar sua
tabela para minimizar este espa¸co. See hundefinedi[Otimiza¸ao], page hunde-
finedi.
Datafile: Parts
Para formato de registros dinˆamicos, isto indica quantos blocos de dados exis-
tem. Para uma tabela otimizada sem registros fragmentados, isto ´e o mesmo
que Data records.
Deleted data
Quantos bytes de dados deletados n˜ao recuperados existem. Voe pode otimizar
sua tabela para minimizar este espa¸co. See hundefinedi[Otimiza¸ao], page hun-
definedi.
Datafile 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˜ao pode ser controlado pelo MySQL ainda. Para tabelas fixas, isto ´e
um endere¸co de registro. Para tabelas dinˆamicas, isto ´e um endere¸co de byte.
Keyfile pointer
O tamanho de um ponteiro de arquivo de ´
indices, em bytes. Ele normalmente
possui 1, 2 ou 3 bytes. A maioria das tabelas trabalham com 2 bytes, mas isto
´e calculado automaticamente pelo MySQL. Ele ´e sempre um endere¸co 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 ´
indices (.MYI pode atingir, em bytes.
Recordlength
Quanto espa¸co cada registro ocupa, em bytes.
Record format
O formato utilizado para armazenar as linhas da tabelas. Os exemplos vistos
abaixo utilizam Fixed length (tamanho fixo). Outros valores poss´
iveis s˜ao
Compressed(compactado) e Packed(empacotado).
248 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
table description
Uma lista de todas as chaves na tabela. Para cada chave, alguma informa¸ao
de baixo n´
ivel ´e apresentada:
Key O N´umero desta chave.
Start Onde, no registro, esta parte do ´
indice inicia.
Len Qual o tamanho desta parte do ´
indice. Para n´umeros 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ˆe pode indexar um prefixo de uma coluna string.
Index unique ou multip. (multiplos). Indica se um valor pode ou n˜ao
exisitir v´arias vezes neste ´
indice.
Type Que tipo de dados esta parte do ´
indice tem. Isto ´e um tipo de
dados ISAM com as op¸oes packed,stripped ou empty.
Root Endere¸co do bloco de ´
indice raiz.
Blocksize
O tamanho de cada bloco de ´
indice. O tamanho padr˜ao ´e 1024,
mas o valor pode ser alterado na compila¸ao.
Rec/key Este ´e um valor estat´
istico utilizado pelo otimizador. Ele diz quan-
tos registros existem por valor para esta chave. Uma chave ´unica
sempre tem um valor de 1. Ele pode ser atualizado depois que
uma tabela ´e carregada (ou muito alterada) com myisamchk -a. Se
isto n˜ao for completamente atualizado, um valor padr˜ao de 30 ´e
fornecido.
No primeiro exemplo acima, a nona chave ´e uma chave multi partes com duas
partes.
Keyblocks used
Qual o percentual de bloco de chaves s˜ao usados. Como a tabela usada nos
exemplos foi reorganizada com myisamchk, os valores s˜ao muito altos (muito
pr´oximos do m´aximo te´orico).
Packed O MySQL tenta empacotar chaves com um sufixo comum. Isto pode ser us-
ado somente para chaves CHAR/VARCHAR/DECIMAL. Para strings grandes como
nomes, isto pode reduzir significativamente o espa¸co utilizado. No terceiro ex-
emplo acima, a quarta chave possui 10 caracteres e uma redu¸ao de 60% no
espa¸co ´e obtida.
Max levels
Qual a profundidade da ´arvore-B para esta chave. Grandes tabelas com chaves
longas resultam em valores altos.
Records Quantos registros existem na tabela.
M.recordlength
A m´edia de tamanho do registro. Para tabelas com registros de tamanho fixo,
isto ´e o tamanho exato do registro.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 249
Packed O MySQL corta espa¸cos do final de strings. O valor Packed indica o percentual
de economia alcan¸cado fazendo isto.
Recordspace used
Qual percentual do arquivo de dados ´e usado.
Empty space
Qual percetual do arquivo de dados n˜ao ´e usado.
Blocks/Record
N´umero m´edio de blocos por registro (isto ´e, de quantos links um registro frag-
mentado ´e composto). Sempre ser´a 1 para tabelas de formato fixo. Este valor
deve permanecer o mais pr´oximo poss´
ivel de 1.0. Se ele aumentar, vocˆe pode
reorganizar a tabela com myisamchk. See hundefinedi[Otimiza¸ao], page hun-
definedi.
Recordblocks
Quantos blocos (links) s˜ao utilizados. Para formatos fixos, este ´e o mesmo que
o n´umero de registros.
Deleteblocks
Quantos blocos (links) foram exclu´
idos.
Recorddata
Quantos bytes no arquivo de dados s˜ao usados.
Deleted data
Quantos bytes no arquivo de dados foram apagados (sem uso).
Lost space
Se um registro ´e atualizado para um tamanho menor, algum espa¸co ´e perdido.
Isto ´e a soma de todas estas perdas, em bytes.
Linkdata Quando o formato de tabela dinˆamica ´e utilizado, fragmentos de registros s˜ao
ligados com ponteiros (4 a 7 bytes cada). Linkdata ´e a soma do montante de
armazenamento utilizado por todos estes ponteiros.
Se uma tabela foi compactada com myisampack,mysiamchk -d exibe informa¸oes adicionais
sobre cada coluna da tabela. Veja hundefinedi[myisampack], page hundefinedi, para um
exemplo desta informa¸ao e uma descri¸ao do que ela significa.
4.5 Administra¸ao de Bancos de Dados e Referˆencia de
Linguagem
4.5.1 Sintaxe de OPTIMIZE TABLE
OPTIMIZE TABLE nome_tabela[,nome_tabela]...
OPTIMIZE TABLE deve ser usado se voe apagou uma grande parte de uma tabela ou se vocˆe
fez v´arias altera¸oes `a uma tabela com registros de tamanho vari´avel (tabelas que tenham
campos do tipo VARCHAR,BLOB ou TEXT). Registros apagados s˜ao mantidos em uma lista
de liga¸oes e opera¸oes INSERT subsequentes reutilizam posi¸oes de registros antigos. Voe
250 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
pode utilizar OPTIMIZE TABLE para reclamar o espa¸co inutilizado e para desfragmentar o
arquivo de dados.
No momento OPTIMIZE TABLE o funciona em tabelas MyISAM eBDB. Para tabelas BDB,
OPTIMIZE TABLE ´e atualmente mapeado para ANALIZE TABLE. See hundefinedi[ANALYZE
TABLE], page hundefinedi.
Voe pode ter a otimiza¸ao de tabelas trabalhando em outros tipos de tabelas iniciando
omysqld com --skip-new ou --safe-mode, mas neste caso, OPTIMIZE TABLE ´e mapeado
apenas para ALTER TABLE.
OPTIMIZE TABLE funciona da seguinte forma:
Se a tabela tem registros exclu´
idos ou dividos, repara a tabela.
Se as p´aginas de ´
indice n˜ao est˜ao ordenas, ordene-as.
Se as estat´
isticas n˜ao est˜ao atualizadas (e o reparo n˜ao pode ser feito ordenando o
´
indice), atualize-as.
OPTIMIZE TABLE para tabelas MyISAM ´e equivalente a executar myisamchk --quick
--check-changed-tables --sort-index --analyze na tabela.
Perceba que a tabela estar´a bloqueada durante o tempo em que OPTIMIZE TABLE estiver
executando.
4.5.2 Sintaxe de ANALYZE TABLE
ANALYZE TABLE nome_tabela[,nome_tabela...]
Analisa e armazena a distribui¸ao de chaves para a tabela. Durante a an´alise a tabela ´e
bloqueada com uma trava de leitura. Isto funciona em tabelas MyISAM eBDB.
Isto seria equivalente a executar myisamchk -a na tabela.
O MySQL utiliza a distribui¸ao de chaves armazenadas para decidir em que ordem tabelas
devem ser unidas quando algu´em faz um join em alguma coisa diferente de uma constante.
O comando retorna uma tabela com as seguintes colunas:
Coluna Valor
Table Nome da Tabela
Op Sempre “analyze”
Msg type Um dos seguintes: status,error,info ou warning.
Msg text A mensagem.
Voe pode verificar a distribui¸ao de chaves armazenadas com o comando SHOW INDEX. See
hundefinedi[SHOW DATABASE INFO], page hundefinedi.
Se a tabela n˜ao foi alterada deste o ´ultimo comando ANALYZE TABLE, a tabela n˜ao ser´a
analisada novamente.
4.5.3 Sintaxe de FLUSH
FLUSH op¸c~oes [,op¸c~oes]
Voe deve utilizar o comando FLUSH se desejar limpar algum dos caches internos que o
MySQL usa. Para executar FLUSH, vocˆe deve ter o privil´egio RELOAD.
op¸c~oes podem ser qualquer uma das seguintes:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 251
HOSTS Esvazia as tabelas de cache de nomes de m´aquinas. Voe deve descar-
regar as tabelas de nomes de m´aquinas se alguma de suas m´aquinas rece-
ber um n´umero IP diferente ou se vocˆe obter a mensagem de erro Host
... is blocked. Quando mais de max_connect_erros erros occorrer em
um registro para uma determinada m´aquina enquanto se conecta ao servi-
dor MySQL, o MySQL assume que algo est´a errado e bloqueia futuras
requisi¸oes desta m´aquina. A descarga na tabela de nomes de m´aquinas
permite `a m´aquina se conectar novamente. See hundefinedi[M´aquina
bloqueada], page hundefinedi.) Voe pode iniciar o mysqld com -O max_
connection_errors=999999999 para evitar esta mensagem de erro.
LOGS Fecha e reabre todos os arquivos de log. Se vocˆe tiver especificado o arquivo
de logs de atualiza¸oes ou um arquivo de log bin´ario sem uma extens˜ao,
o n´umeor de extens˜ao do arquivo log ser´a sempre incrementado de um em
rela¸ao ao arquivo anterior. Se vocˆe usou uma extens˜ao no nome do arquivo,
o MySQL ir´a fechar e reabrir o arquivo de log de atualiza¸oes. See hun-
definedi[Log de atualiza¸ao], page hundefinedi. Isto ´e a mesma coisa que
enviar o sinal SIGHUP para o servidor mysqld.
PRIVILEGES Recarrega os privil´egios das tabelas de permiss˜oes no banco de dados mysql.
TABLES Fecha todas as tabelas abertas e for¸ca o fechamento de todas as tabelas em
uso
[TABLE |
TABLES]
nome_tabela
[,nome_
tabela...]
Descarga somente das tabelas fornecidas.
TABLES WITH
READ LOCK
Fecha todas tabelas abertas e bloqueia todas tabelas para todos os bancos
de dados com leitura at´e que algu´em execute UNLOCK TABLES. Isto ´e uma
maneira muito conveniente para fazer backups se vocˆe possui um sistema de
arquivos, como Veritas, que pode fazer uma imagem instantˆanea (snapshot)
de um certo momento.
STATUS Reinicia a maioria das vari´aveis de status para zero. Isto ´e algo que deve
ser usado somente para depurar uma consulta.
Voe pode tamb´em acessar cada um dos comandos vistos acima com o utilit´ario mysqladmin,
utilizando os comandos flush-hosts,flush-logs,reload ou flush-tables.
Tamb´em de uma olhada no comando RESET usado com a replica¸ao. See hundefinedi
[Replica¸ao SQL], page hundefinedi.
4.5.4 Sintaxe de KILL
KILL thread_id
Cada conex˜ao ao mysqld executa em uma thread separada. Vocˆe pode ver quais threas
est˜ao em execu¸ao com o comando SHOW PROCESSLIST e matar uma thread com o comando
KILL thread_id.
252 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe tiver o privil´egio process, vocˆe pode ver e matar qualquer thread. Caso contr´ario,
vocˆe pode ver e matar somente suas pr´oprias threads.
Voe tamb´em pode usar os comandos mysqladmin processlist emysqladmin kill para
examinar e matar threads.
Quando vocˆe utiliza um KILL, um sinal (flag) kill especifico ´e configurado para a thread.
Na maioria dos casos pode levar algum tempo para a thread morrer pois o sinal kill s´o ´e
checado em intervalos espec´
ificos.
Nos loops SELECT,ORDER BY eGROUP BY, o sinal ´e checado depois de ler um bloco de
registros. Se o sinal kill est´a habilitado a instru¸ao ´e abortada.
Na execu¸ao de um ALTER TABLE o sinal kill ´e conferido antes de cada bloco de registros
ser lido da tabela original. Se o sinal kill foi habilitado, o comando ´e abortado e a tabela
tempor´aria apagada.
Ao fazer um UPDATE TABLE and DELETE TABLE, o sinal de kill ´e conferido depois de
que cada bloco ´e lido e depois de cada atualiza¸ao ou remo¸ao de registro. Se o sinal
kill est´a habilitado, a instru¸ao ´e abortada. Note que se voe n˜ao estiver utilizando
transa¸oes, as altera¸oes n˜ao ir˜ao ser desfeitas!
GET_LOCK() ir´a aborar com NULL.
Uma thread INSERT DELAYED ir´a rapidamente descarregar todos registros que estiverem
em mem´oria e morrer.
Se a thread estiver no manipulador de bloqueio de tabelas (status: Locked), o bloqueio
de tabela ser´a abortado rapidamente.
Se a thread estiver esperando por espa¸co livre em disco numa chamada write, a escrita
´e abortada com uma mensagem de espa¸co em disco insuficiente.
4.5.5 Sintaxe de SHOW
SHOW DATABASES [LIKE wild]
ou SHOW [OPEN] TABLES [FROM nome_bd] [LIKE wild]
ou SHOW [FULL] COLUMNS FROM nome_tabela [FROM nome_bd] [LIKE wild]
ou SHOW INDEX FROM nome_tabela [FROM nome_bd]
ou SHOW TABLE STATUS [FROM nome_bd] [LIKE wild]
ou SHOW STATUS [LIKE wild]
ou SHOW VARIABLES [LIKE wild]
ou SHOW LOGS
ou SHOW [FULL] PROCESSLIST
ou SHOW GRANTS FOR usuario
ou SHOW CREATE TABLE nome_tabela
ou SHOW MASTER STATUS
ou SHOW MASTER LOGS
ou SHOW SLAVE STATUS
SHOW fornece informa¸oes sobre bancos de dados, tabelas, colunas ou informa¸oes do estado
do servidor. Se a parte LIKE wild ´e usada, a string wild pode ser uma string que usa os
meta caracteres ‘%’ e ‘_’ do SQL.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 253
4.5.5.1 Recuperando Informa¸oes sobre Bancos de Dados, Tabelas,
Colunas e ´
Indices
Voe pode usar nome_bd.nome_tabela como uma alternativa para a sintaxe nome_tabela
FROM nome_bd. Estas duas declara¸oes s˜ao equivalentes:
mysql> SHOW INDEX FROM minhatabela FROM meudb;
mysql> SHOW INDEX FROM meubd.minhatabela;
SHOW DATABASES lista os bancos de dados no servidor MySQL. Voe tamb´em pode obter
esta lista utilizando o comando mysqlshow.
SHOW TABLES lista as tabelas em um banco de dados espec´
ifico. Esta lista tamb´em pode ser
obtida utilizando o comando mysqlshow nome_db.
NOTA: Se um usu´ario n˜ao possui nenhum privil´egio para uma tabela, a tabela n˜ao ser´a
mostrada na sa´
ida de SHOW TABLES ou mysqlshow nome_db
SHOW OPEN TABLES lista as tabelas que est˜ao abertas no cache de tabelas. See hundefinedi
[Cache de Tabelas], page hundefinedi. O campo Comment diz quantas vezes a tabela est´a
em cached ein_use.
SHOW COLUMNS lista as colunas em uma determinada tabela. Se vocˆe especificar a op¸ao FULL,
tamb´em ir´a obter os privil´egios que vocˆe possui para cada coluna. Se os tipos de colunas
forem diferentes do que vocˆe esperava baseando na declara¸ao CREATE TABLE, perceba que
o MySQL algumas vezes altera os tipos das colunas. See hundefinedi[Mudan¸ca de tipos de
colunas], page hundefinedi.
A declara¸ao DESCRIBE fornece informa¸ao similar `a SHOW COLUMNS. See hundefinedi
[DESCRIBE], page hundefinedi.
SHOW FIELDS ´e um sinˆonimo para SHOW COLUMNS eSHOW KEYS um sinˆonimo para SHOW INDEX.
Voe tamb´em pode listar as colunas ou ´
indices de uma tabela com mysqlshow nome_db
nome_tabela ou mysqlshow -k nome_bd nome_tabela.
SHOW INDEX retorna a informa¸ao de ´
indice em um formato que lembra bem a chamada
SQLStatistics do ODBC. As seguintes colunas s˜ao retornadas:
Coluna Significado
Table Nome da tabela.
Non_unique 0 se o ´
indice n˜ao puder conter duplicidades.
Key_name Nome do ´
indice.
Seq_in_index N´umero da sequˆencia da coluna no ´
indice, `a partir de 1.
Column_name Nome da coluna.
Collation Como a coluna ´e ordenada no ´
indice. No MySQL, pode
ter valores ‘A’ (Ascendente) ou NULL (Not sorted).
Cardinality N´umero de valores ´unicos no ´
indice. Isto ´e atualizado
executando isamchk -a.
Sub_part N´umero de caracteres indexados se a coluna s´o ´e a index-
ada parcialmente. NULL se a chave inteira for indexada.
Comment arios comenarios. No momento, ele diz se o ´
indice ´e
textual ou n˜ao.
Perceba que como o Cardinality ´e contado baseado nas estat´
isticas armazenadas como
inteiros, ele pode n˜ao ser exato para tabelas pequenas.
254 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.5.5.2 SHOW TABLE STATUS
SHOW TABLE STATUS [FROM nome_bd] [LIKE wild]
SHOW TABLE STATUS (introduzido na vers˜ao 3.23) funciona como o SHOW STATUS, mas fornece
muitas informa¸oes sobre cada tabela. Vocˆe tamb´em pode obter esta lista utilizando o
comando mysqlshow --status nome_bd. As seguintes colunas s˜ao retornadas:
Coluna Significado
Name Nome da tabela.
Type Tipo da tabela. See hundefinedi[Table types], page hunde-
finedi.
Row_format O formato de armazenamento do registro (Fixed (Fixo), Dy-
namic(dinˆamico), ou Compressed (Compactado)).
Rows N´umero de registros.
Avg_row_length Tamanho m´edio do registro.
Data_length Tamanho do arquivo de dados.
Max_data_length Tamanho m´aximo do arquivo de dados.
Index_length Tamanho do arquivo de ´
indice.
Data_free N´umero de bytes alocados mas n˜ao utilizados.
Auto_increment Pr´oximo valor do auto incremento.
Create_time Quando a tabela foi criada.
Update_time A ´ultima vez que arquivo de dados foi atualizado.
Check_time A ´ultima vez que a tabela foi verificada.
Create_options Op¸oes extras usadas com CREATE TABLE.
Comment O Comenario utilizado quando a tabela ´e criada (ou alguma
informa¸ao do porquˆe do MySQL n˜ao poder acessar a in-
forma¸ao da tabela).
Tabelas InnoDB ir˜ao relatar o espa¸co livre no tablespace no coment´ario da tabela.
4.5.5.3 SHOW STATUS
SHOW STATUS fornece informa¸oes de status do servidor (como mysqladmin extended-
status). A sa´
ida ´e parecida com o que est´a exibido abaixo, apesar dos n´umeros 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 |
Chapter 4: Administra¸ao de Bancos de Dados MySQL 255
| 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´aveis de estado listadas acima tem o seguinte significado:
Vari´avel Signficado
Aborted_clients N´umero de conex˜oes abortadas porque o cliente morreu
sem fechar a conex˜ao corretamente. See hundefinedi[Er-
ros de Comunica¸ao], page hundefinedi.
256 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Aborted_connects N´umero de tentativas que falharam ao tentar a conex˜ao
ao servidor MySQL. See hundefinedi[Erros de Comu-
nica¸ao], page hundefinedi.
Bytes_received N´umero de bytes recebidos por todos os clientes.
Bytes_sent N´umero de bytes enviados para todos os clientes..
Com_xxxx N´umero de vezes que os comandos xxx foram executados.
Connections N´umero de tentativas de conex˜ao ao servidor MySQL.
Created_tmp_disk_tables N´umero de tabelas tempor´arias implicitas em disco cri-
adas durante a execu¸ao de instru¸oes.
Created_tmp_tables N´umero de tabelas tempor´arias implicitas na mem´oria
criadas durante execu¸oes de instru¸oes.
Created_tmp_files Quantos arquivos tempor´arios o mysqld criou.
Delayed_insert_threads N´umero de threads para tratamento de insertdelayed que
est˜ao em uso.
Delayed_writes N´umero de registros escritos com INSERT DELAYED.
Delayed_errors N´umero de registros escritos com INSERT DELAYED onde
algum erro ocorreu (provavelmente duplicate key).
Flush_commands N´umero de comandos FLUSH executados.
Handler_delete N´umero de vezes que um registro foi apagado da tabela.
Handler_read_first N´umero de vezes que a primeira entrada foi lida de um
´
indice. Se este valor for alto, sugere que o servidor est´a
fazendo v´arias leituras de ´
indices, por exemplo, SELECT
col1 FROM foo, assumindo que col1 ´e indexado.
Handler_read_key N´umero de requisi¸oes para ler um registro baseado
em uma chave. Se este valor for alto, ´e uma boa in-
dica¸ao que suas pesquisas e tabelas est˜ao indexadas
corretamente.
Handler_read_next N´umero de requisi¸oes para ler o pr´oximo registro na or-
dem da chave. Este valor ser´a aumentado se vocˆe con-
sultar uma coluna de ´
indice com uma faixa restrita. Ele
tamb´em aumentar´a se forem feitas busca nos ´
indices.
Handler_read_rnd N´umero de requisi¸oes para ler um registro baseado em
uma posi¸ao fixa. O valor ser´a alto se vocˆe estiver
executando v´arias pesquisas que exigem ordena¸ao do
resultado.
Handler_read_rnd_next N´umero de requis˜oes para ler o pr´oximo registro no ar-
quivo de dados. Ser´a alto se vocˆe estiver fazendo v´arias
buscas na tabela. Geralmente sugere que suas tabelas n˜ao
est˜ao corretamente indexadas ou que suas pesquisas n˜ao
foram escritas para tirar vantagem dos ´
indices existentes.
Handler_update N´umero de requisi¸oes para atualizar um registro em uma
tabela.
Handler_write N´umero de requisi¸oes para inserir um registro em uma
tabela.
Key_blocks_used O n´umero de blocos utilizados no cache das chaves.
Key_read_requests O n´umero de requisi¸oes para ler um bloco de chaves do
cache.
Key_reads O n´umero de leituras f´
isicas de blocos de chaves do disco.
Key_write_requests O n´umero de requisi¸oes para gravar um bloco de chaves
no cache.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 257
Key_writes O n´umero de escritas f´
isicas de um bloco de chaves para
o disco.
Max_used_connections O n´umero m´aximo de conex˜oes simultˆaneas que foram
usadas.
Not_flushed_key_blocks Blocos de chaves no cache de chaves que foi alterado mas
ainda n˜ao foi descarregado para o disco.
Not_flushed_delayed_rows N´umero de registros esperando para serem escritos em
filas INSERT DELAY.
Open_tables N´umero de tabelas abertas.
Open_files N´umero de arquivos abertos.
Open_streams N´umero de fluxos abertos (usado principalmente para
logs).
Opened_tables N´umero de tabelas que foram abertas.
Select_full_join N´umero de joins sem chaves (Se for 0, vocˆe deve conferir
com cuidado o ´
indice de suas tabelas).
Select_full_range_join N´umero de joins onde foram usadas pesquisas segmen-
tadas na tabela de referencia.
Select_range N´umero de joins onde foram usadas faixas da primeira
tabela. (Normalmente ao ´e cr´
itica mesmo se o valor
estiver alto.)
Select_scan N´umero de joins onde fizemos uma busca completa na
primeira tabela.
Select_range_check N´umero de joins sem chaves onde o uso de chave foi con-
ferido ap´os cada registro (Se for 0, o ´
indice de suas tabelas
deve ser conferido com cuidado)
Questions N´umero de consultas enviadas para o servidor.
Slave_open_temp_tables N´umero de tabelas tempor´arias atualmente abertas pela
thread escrava.
Slow_launch_threads N´umero de threads que levaram mais tempo do que slow_
lauch_time para serem criadas.
Slow_queries N´umero de consultas que levaram mais tempo que long_
query_time. See hundefinedi[Log de consultas lentas],
page hundefinedi.
Sort_merge_passes N´umero de ifus˜oes feitas pelo algor´
itmo de ordena¸ao.
Se este valor for alto vocˆe deve considerar o aumento de
sort_buffer.
Sort_range N´umero de ordena¸oes que foram feitas com limites.
Sort_rows N´umero de registros ordenados.
Sort_scan N´umero de ordena¸oes que foram feitas lendo a tabela.
Table_locks_immediate N´umero de vezes que um travamento de tabela foi obtido
de maneira autom´atica.
Table_locks_waited N´umero de vezes que um bloqueio de tabela n˜ao pˆode ser
obtido imediatamente e foi preciso esperar. Se o valor for
alto, e vocˆe tiver problemas de performance, suas consul-
tas devem ser otimizadas e depois dividir sua(s) tabela(s)
ou usar replica¸ao. Dispon´
ivel `a partir da vers˜ao 3.23.33
Threads_cached N´umero de threads no cache de threads.
Threads_connected N´umero de conex˜oes atuais abertas.
Threads_created N´umero de threads criadas para lidar com conex˜oes.
Threads_running N´umero de threads que n˜ao est˜ao dormindo.
258 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Uptime Quantos segundos o servidor est´a funcionando.
Alguns comenarios sobre a tabela acima:
Se Opened_tables for grande, provavelmente sua vari´avel table_cache est´a muito
pequena.
Se key_reads for grande, provavelmente sua vari´avel key_buffer_size provavelmente
est´a muito pequena. O ´
indice de acertos do cache pode ser calculaldo com key_
reads/key_read_requests.
Se Handler_read_rnd for grande, provavelmente vocˆe possui v´arias consultas que ex-
igem do MySQL fazer busca em tabelas inteiras ou vocˆe tem joins que n˜ao utilizam
chaves corretamente.
Se Threads_created for grande vocˆe pode desejar aumentar a vari´avel thread_cache_
size.
4.5.5.4 SHOW VARIABLES
SHOW VARIABLES [LIKE wild]
SHOW VARIABLES exibe os valores de algumas vari´aveis de sistema do MySQL. Voe pode
tambˆem obter esta informa¸ao utilizando o comando mysqladmin variables. Se os valores
padr˜oes n˜ao s˜ao adequados, vocˆe pode configurar a maioria destas vari´aveis utilizando
op¸oes de linha de comando quando o mysqld iniciar. See line options-snt [Op¸oes de linha
de comando], page line options-pg.
A sa´
ida parece com o exibido abaixo, por´em o formato e os n´umeros podem divergir:
+-------------------------+---------------------------+
| Nome_vari´avel | Valor |
+-------------------------+---------------------------+
| ansi_mode | OFF |
| back_log | 50 |
| basedir | /my/monty/ |
| bdb_cache_size | 16777216 |
| bdb_log_buffer_size | 32768 |
| bdb_home | /my/monty/data/ |
| bdb_max_lock | 10000 |
| bdb_logdir | |
| bdb_shared_data | OFF |
| bdb_tmpdir | /tmp/ |
| binlog_cache_size | 32768 |
| concurrent_insert | ON |
| connect_timeout | 5 |
| datadir | /my/monty/data/ |
| delay_key_write | ON |
| delayed_insert_limit | 100 |
| delayed_insert_timeout | 300 |
| delayed_queue_size | 1000 |
| flush | OFF |
| flush_time | 0 |
| have_bdb | YES |
| have_innodb | YES |
Chapter 4: Administra¸ao de Bancos de Dados MySQL 259
| have_raid | YES |
| have_ssl | NO |
| init_file | |
| interactive_timeout | 28800 |
| join_buffer_size | 131072 |
| key_buffer_size | 16776192 |
| language | /my/monty/share/english/ |
| large_files_support | ON |
| log | OFF |
| log_update | OFF |
| log_bin | OFF |
| log_slave_updates | OFF |
| long_query_time | 10 |
| low_priority_updates | OFF |
| lower_case_table_names | 0 |
| max_allowed_packet | 1048576 |
| max_binlog_cache_size | 4294967295 |
| max_connections | 100 |
| max_connect_errors | 10 |
| max_delayed_threads | 20 |
| max_heap_table_size | 16777216 |
| max_join_size | 4294967295 |
| max_sort_length | 1024 |
| max_tmp_tables | 32 |
| max_write_lock_count | 4294967295 |
| myisam_recover_options | DEFAULT |
| myisam_sort_buffer_size | 8388608 |
| net_buffer_length | 16384 |
| net_read_timeout | 30 |
| net_retry_count | 10 |
| net_write_timeout | 60 |
| open_files_limit | 0 |
| pid_file | /my/monty/data/donna.pid |
| port | 3306 |
| protocol_version | 10 |
| record_buffer | 131072 |
| query_buffer_size | 0 |
| safe_show_database | OFF |
| server_id | 0 |
| skip_locking | ON |
| skip_networking | OFF |
| skip_show_database | OFF |
| slow_launch_time | 2 |
| socket | /tmp/mysql.sock |
| sort_buffer | 2097116 |
| table_cache | 64 |
| table_type | MYISAM |
| thread_cache_size | 4 |
| thread_stack | 65536 |
260 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| tmp_table_size | 1048576 |
| tmpdir | /tmp/ |
| version | 3.23.29a-gamma-debug |
| wait_timeout | 28800 |
+-------------------------+---------------------------+
Cada op¸ao ´e descrita abaixo. Valores para tamanhos de buffer, comprimento e tamanho
de pilha s˜ao fornecidos em bytes. Vocˆe pode especificar valores com sufixos ‘K’ ou Mpara
indicar o valor em kilobytes ou megabytes. Por exemplo, 16M indica 16 Megabytes. ao
importa se os sufixos est˜ao em letras mai´usuculas ou min´usculas; 16M e16m ao equivalentes:
ansi_mode.
Est´a ligado (ON) se o mysqld foi iniciado com --ansi. See hundefinedi[Modo
ANSI], page hundefinedi.
back_log O n´umero de requisi¸oes de conex˜oes que o MySQL pode suportar. Isto entra
em cena quando a thread principal do MySQL recebe MUITAS solicita¸oes de
conex˜oes em um espa¸co curto de tempo. Eles tomam algum tempo (por´em
muito pouco) da a thread principal para conferir a conex˜ao e iniciar uma nova
thread. O valor back_log indica quantas requisi¸oes podem ser empilhadas du-
rante este breve tempo antes do MySQL parar de responder a novas requisi¸oes.
Voe is´o precisa aumena-lo se espera um n´umero alto de conex˜oes em um curto
per´
iodo de tempo
Em outras palavras, este valor ´e o tamanho da fila de escuta para novas conex˜oes
TCP/IP. Seu sistema operacional tem o pr´oprio limite para o tamanho desta
fila. A p´agina do manual Unix da chamada de sistema listen(2) deve fornecer
maiores detalhes. Confira a documenta¸ao do seus SO para saber o valor
aximo para esta vari´avel. Tentativas de configurar back_log maior do que o
limite de seu sistema operacional ser˜ao ineficazes.
basedir O valor da op¸ao --basedir.
bdb_cache_size
O buffer que ´e alocado para o cache de ´
indice e registros de tabelas BDB. Se
vocˆe n˜ao utiliza tabelas BDB, deve iniciar o mysqld com a op¸ao --skip-bdb
para evitar desperd´
icio de mem´oria para este cache.
bdb_log_buffer_size
O buffer que ´e alocado para o cache de ´
indice e registros de tabelas BDB. Se
vocˆe n˜ao utiliza tabelas BDB, deve configur´a-la com 0 ou iniciar o mysqld com
a op¸ao --skip-bdb para evitar desperd´
icio de mem´oria para este cache.
bdb_home O valor para a op¸ao --bdb-home.
bdb_max_lock
O n´umero m´aximo de bloqueios (1000 por padr˜ao) que podem ser feitas em uma
tabela BDB. Voe deve ser aumena-la se obter erros do tipo: bdb: Lock table
is out of available locks ou Got error 12 from ... quando s˜ao necess´arias
longas transa¸oes ou quando o mysqld precisar examinar v´arios registros para
calcular a pesquisa.
bdb_logdir
O valor da op¸ao --bdb-logdir.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 261
bdb_shared_data
Est´a ligada (ON) se vocˆe estiver utilizando --bdb-shared-data.
bdb_tmpdir
O valor da op¸ao --bdb-tmpdir.
binlog_cache_size. O tamanho do cache para armazenar instru¸c~oes
SQL para o log bin´ario durante uma transa¸ao. Se vocˆe geralmente utiliza
transa¸oes grandes, multi-instru¸oes, vocˆe pode aumentar este valor para obter
mais performance. See hundefinedi[COMMIT], page hundefinedi.
character_set
O conjunto de caracteres padr˜ao.
character_sets
Os conjuntos de caracteres suportados.
concurrent_inserts
Se ON (ligado, por padr˜ao), o MySQL permitir´a o uso de INSERT em tabelas
MyISAM ao mesmo tempo em que s˜ao executadas consultas SELECT. Voe pode
desligar esta op¸ao iniciando mysqld com --safe ou --skip-new.
connect_timeout
O n´umero de segundos que o servidor mysqld espera para um pacote de conex˜ao
antes de responder com Bad handshake.
datadir O valor da op¸ao --datadir.
delay_key_write
Se habilitado (valor padr˜ao), o MySQL utilizar´a a op¸ao delay_key_write
com CREATE TABLE. Isto siginifica que o buffer de chaves das tabelas com
esta op¸ao n˜ao ser˜ao descarregadas a cada atualiza¸ao do ´
indice, mas somente
quando a tabela ´e fechada. Isto ir´a aumentar bem a velocidade de escrita em
chaves, mas voc6e deve adicionar verifica¸ao autom´atica de todas as tabelas
com myisamchk --fast --force se vocˆe us´a-lo. Note que se vocˆe iniciar o
mysqld com a op¸ao --delay-key-write-for-all-tables siginifica que to-
das as tabelas ser˜ao tratadas como se fossem criadas com a op¸ao delay_key_
write. Voe pode limpar esta configura¸ao iniciando mysqld com --skip-new
ou --safe-mode.
delayed_insert_limit
Depois de inserir delayed_insert_limit registros, o agente que cuida de
INSERT DELAYED ira conferir se exitem instru¸oes SELECT pendentes. Se sim,
ele permite a execu¸ao destas antes de continuar.
delayed_insert_timeout
Quanto tempo uma thread INSERT DELAYED deve esperar por instru¸oes 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´a
esperar at´e existir espa¸co na fila novamente.
262 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
flush ´
E habilitado (ON) se vocˆe iniciar o MySQL com a op¸ao --flush.
flush_time
Se esta vari´avel for configurada com um valor diferente de zero, ent˜ao a cada
flush_time segundos todas tabelas ser˜ao fechadas (para economizar recursos e
sincronizar dados com o disco). Recomendamos esta op¸ao somente em sistemas
com Win95, Win98 ou outros sistemas com poucos recursos.
have_bdb YES se o mysqld suportar tabelas Berkeley DB. DISABLED se a op¸ao --skip-
bdb for usada.
have_innodb
YES se o mysqld suportar tabelas InnoDB. DISABLED se a op¸ao --skip-innodb
for usada
have_raid
YES se o mysqld suportar a op¸ao RAID.
have_ssl YES se o mysqld suportar SSL (criptografia) no protocolo cliente/ servidor.
init_file
O nome do arquivo especificado com a op¸ao --init-file quando vocˆe iniciar
o servidor. Este ´e um arquivo das instru¸oes SQL que vocˆe deseja que o servidor
execute quando ´e iniciado.
interactive_timeout
O n´umero de segundos que o servidor espera por atividade em uma conex˜ao
antes de feca-la. Um cliente interativo ´e definido como um cliente que utiliza a
op¸ao CLIENT_INTERACTIVE para mysql_real_connect(). Veja tamb´em wait_
timeout.
join_buffer_size
O tamanho do buffer que ´e utilizado para full joins (joins que n˜ao utilizam
´
indices). O buffer ´e alocado uma vez para cada full join entre duas tabelas.
Aumente este valor para obter um full join mais r´apido quando a adi¸ao de
´
indices n˜ao for poss´
ivel. (Normalmente a melhor forma de obter joins r´apidas
´e adicionar ´
indices.)
key_buffer_size
Blocos de ´
indices s˜ao buferizados e compartilhados por todas as threads. key_
buffer_size ´e o tamanho do buffer utilizado para indexar blocos.
Aumente-o para lidar melhor com os ´
indices (para todas as leituras e escritas
m´ultiplas) para o m´aximo poss´
ivel 64M em uma m´aquina com 256M que exe-
cuta, principalmente, o MySQL ´e bastante comum. Entretanto, se vocˆe deixar
este valor muito grande (mais que 50% da sua mem´oria total?) seu sistema pode
iniciar a paginar e se tornar MUITO lento. Lembre-se que como o MySQL n˜ao
utiliza cache de leitura de dados, ser´a necess´ario deixar algum espa¸co para o
cache do sistema de arquivos para o Sistema Operacional.
Voe pode verificar a performance do buffer de chaves executando show status
e examinar as vari´aveis Key_read_requests,Key_reads,Key_write_requests
eKey_writes. A raz˜ao de Key_reads/Key_read_request deve normalmente
Chapter 4: Administra¸ao de Bancos de Dados MySQL 263
ser <0.01. O Key_write/Key_write_requests ´e normalmnte pr´oximo de 1 se
vocˆe estiver utilizando na maioria updates/deletes mas deve ser bem menor se
vocˆe tender a fazer atualiza¸oes que afetam v´arias outras ao mesmo tempo ou se
vocˆe estiver utilizando delay_key_write. See hundefinedi[SHOW], page hun-
definedi.
Para obter ainda mais velocidade quando estiver gravando v´arios registros ao
mesmo tempo, utilize LOCK TABLES. See hundefinedi[LOCK TABLES], page hun-
definedi.
language A linguagem utilizada para mensagens de erro.
large_file_support
Se o mysqld foi compilado com op¸oes para suporte a grandes arquivos.
locked_in_memory
Se o mysqld foi travado na mem´oria com --memlock
log Se o log de todas as consultas est´a habilitado.
log_update
Se o log de atualiza¸oes est´a habilitado.
log_bin Se o log bin´arios est´a habilitado.
log_slave_updates
Se as atualiza¸oes do escravo devem ser logadas.
long_query_time
Se uma consulta demorar mais que isto (em segundos), o contador Slow_
queries ser incrementado. Se vocˆe estiver utilizando --log-slow-queries,
a consulta ser´a logada ao arquivo de consultas lentas. See hundefinedi[Slow
query log], page hundefinedi.
lower_case_table_names
Se estiver configurado para 1, nomes de tabelas s˜ao armazenados em letras
min´usculas no disco e nomes de tabelas ser˜ao caso-insensitivo. See hundefinedi
[Name case sensitivity], page hundefinedi.
max_allowed_packet
O valor m´aximo de um pacote. O buffer de mensagens ´e iniciado por net_
buffer_length bytes, mas pode crescer at´e max_allowed_packet bytes quando
for necess´ario. Este valor por padr˜ao ´e pequeno, para obter pacotes maiores
(possivelmente errados). Voe deve incrementar este valor se vocˆe estiver us-
ando colunas BLOB grandes. Ele deve t˜ao grande quanto o maior BLOB que voe
deseja utilizar. O protocol atual limita o max_allowed_packet `a 16M.
max_binlog_cache_size
Se uma transa¸ao multi-instru¸oes necessitar de mais que este montante de
mem´oria, ser´a obtido o erro "Multi-statement transaction required more than
’max binlog cache size’ bytes of storage"("Transa¸ao multi-instru¸oes neces-
sita mais que ’max binlog cache size’ bytes de armazenamento").
264 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
max_binlog_size
Dispon´
ivel a partir da 3.23.33. Se uma escrita ao log bin´ario (replica¸ao) exceder
o valor fornecido, rotacione os logs. Voe n˜ao pode configur´a-lo para menos de
1024 bytes ou mais que 1 GB. O valor padr˜ao ´e 1 GB.
max_connections
O N´umero de clientes simultˆaneos permitidos. Aumentar este valor aumente
o n´umero de descritores de arquivos que o mysqld necessita. Veja abaixo os
comenarios sobre os limites de descritores de arquivos. See hundefinedi[Muitas
conex˜oes], page hundefinedi.
max_connect_errors
Se houver mais que este n´umero de conex˜oes interrompidas a partir de uma
aquina est´a m´aquina ter´a as pr´oximas conex˜oes bloqueadas. Voe pode des-
bloquar uma m´aquina com o comadno FLUSH HOSTS.
max_delayed_threads
ao inicie mais do que este n´umero de threads para lidar com instru¸oes INSERT
DELAYED. Se vocˆe tentar inserir dados em uma nova tabela depois que todas as
threads INSERT DELAYED estiverem em uso, o registro ser´a inserido como se o
atributo DELAYED ao fosse especificado.
max_heap_table_size
ao permita cria¸ao de tabelas heap maiores que este valor.
max_join_size
Joins que provavelmente forem ler mais que max_join_size registros retornam
um erro. Configure este valor se os seus usu´arios tendem a realizar joins que
ao possuem uma cl´ausula WHERE, que tomam muito tempo, e retornam milh˜oes
de registros.
max_sort_length
O n´umero de bytes utilizados para ordenar valores BLOB ou TEXT (somente os
primeiros max_sort_lenght bytes de cada valor s˜ao usados; o resto ´e ignorado).
max_user_connections
O valor m´aximo de conex˜oes ativas para um ´unico usu´ario (0 = sem limite).
max_tmp_tables
(Esta op¸ao ainda n˜ao faz nada.) N´umero m´aximo de tabelas tempor´arias 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¸ao --myisam-recover.
myisam_sort_buffer_size
O buffer que ´e alocado ao ordenar o ´
indice quando estiver fazendo um REPAIR
ou estiver criando ´
indices com CREATE INDEX ou ALTER TABLE.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 265
myisam_max_extra_sort_file_size.
Se a cria¸ao do arquivo tempor´ario para cria¸c˜ao r´apida de ´
indices fosse este
valor maior que quando for usado o cache de chaves, de preferˆencia ao m´etodo
de cache de chaves. Isto ´e usado principalmente para for¸car que longas chaves
de caracteres em tabelas grandes usem o m´etodo de cache de chaves mais lenta
para criar o ´
indice. NOTE que este parˆametro ´e fornecido em megabytes!
myisam_max_sort_file_size
O tamanho m´aximo do arquivo tempor´ario que ´e permitido ao MySQL usar en-
quanto recria os ´
indices (durante REPAIR,ALTER TABLE ou LOAD DATA INFILE).
Se o tamanho do arquivo for maior que isto, o ´
indice ser´a criado atrav´es do
cache de chaves (que ´e mais lento). NOTE que este parˆametro ´e fornecido em
megabytes!
net_buffer_length
O buffer de comunica¸oes ´e configurado para este tamanho entre queries. Isto
ao deve ser alterado normalmente, mas se vocˆe tem muito pouca mem´oria,
pode configur´a-lo para o tamanho esperado de uma consulta. (Isto ´e, o tamanho
experado das instru¸oes SQL enviadas pelos clientes. Se as instru¸oes excederem
este valor, o buffer ´e aumentado automaticamente, at´e max_allowed_packet
bytes.)
net_read_timeout
N´umero de segundos para esperar por mais dados de uma conex˜ao antes de abor-
tar a leitura. Perceba que quando n´os n˜ao esperamos dados de uma conex˜ao, o
tempo m´aximo de espera ´e definido pelo write_timeout. Veja tamb´em slave_
read_timeout.
net_retry_count
Se uma leitura na porta de comunica¸oes for interrompida, tente novamente
net_retry_count vezes antes de parar. Este valor deve ser bem alto no FreeBSD
a que interrup¸oes internas s˜ao enviadas para todas as threads.
net_write_timeout
N´umero de segundos para esperar pela escrita de um bloco em uma conex˜ao
antes de abortar a escrita.
open_files_limit
Se n˜ao for 0, ent˜ao o mysqld usar´a este valor para reservar descritores de ar-
quivos para usar com setrlimit(). Se este valor for 0 ent˜ao o mysqld ir´a reser-
var max_connections*5 ou max_connections + table_cache*2 (que ´e maior)
n´umero de arquivos. Voe deve tentar aumentar isto se o mysqld fornecer a
vocˆe o erro ’Too many open files’ (Muitos arquivos abertos).
pid_file O valor da op¸ao --pid-file.
port O valor da opcao --port.
protocol_version
A vers˜ao do protocolo usada pelo servidor MySQL.
266 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
record_buffer
Cada thread que faz uma leitura sequencial aloca um buffer deste tamanho para
cada tabela lida. Se vocˆe fizer v´arias leituras sequenciais, vocˆe pode desejar
aumentar este valor.
record_rnd_buffer
Ao ler registros na ordem depois de uma ordena¸ao, os registros s˜ao lidos atrav´es
deste buffer para evitar pesquisas em disco. Se n˜ao for configurado, recebe o
valor de record_buffer.
query_buffer_size
A aloca¸ao inicial do buffer de consultas. Se a maioria de suas consultas s˜ao
grandes (como quando se insere blobs), vocˆe deve aumenti´a-lo!
safe_show_databases
ao exibe bancos de dados nos quais o usu´ario n˜ao tem nenhum privil´egios. Isto
pode melhorar a seguran¸ca se vocˆe se preocupa com o fato das pessoas estarem
aptas a ver quais bancos de dados outros usu´arios possuem. Veja tamb´em
skip_show_databases.
server_id
O valor da op¸ao --server-id.
skip_locking
Est´a desligado (OFF) se o mysqld usar bloqueio externo.
skip_networking
Est´a ligado (ON) se somente permitimos conex˜oes locais (socket).
skip_show_databases
Isto previne usu´arios de fazerem SHOW DATABASES se eles n˜ao possuirem o
privil´egio PROCESS_PRIV. Isto pode aumentar a seguran¸ca se vocˆe se preocupa
com o fato das pessoas poderem ver quais bancos de dados outros usu´arios
possuem. Veja tamb´em safe_show_databases.
slave_read_timeout
N´umero de segundos para esperar por mais dados de uma conex˜ao de
mestre/escravo antes de abortar a leitura.
slow_launch_time
Se a cria¸ao de threads demorar mais que este valor (em segundos), o contador
Slow_launch_threads ser´a incrementado.
socket O socket Unix utilizado pelo servidor.
sort_buffer
Cada thread que precisar fazer uma ordena¸ao aloca um buffer deste tamanho.
Aumente este valor para opera¸oes ORDER BY ou GROUP BY mais r´apidas. See
hundefinedi[Arquivos tempor´arios], page hundefinedi.
table_cache
O n´umero de tabelas abertas para todas as threads. Aumentar este valor au-
menta o n´umero de descritores de arquivos que o mysql necessita. O MySQL
precisa de dois descritores de arquivos para cada tabela ´unica aberta. Veja
Chapter 4: Administra¸ao de Bancos de Dados MySQL 267
abaixo os comenta´arios sobre os limites do descritor de arquivos. Vocˆe pode
conferir se necessita aumentar o cache de tabela conferindo a vari´avel Opened_
tables. See hundefinedi[SHOW], page hundefinedi. Se esta vari´avel for grande
e vocˆe n˜ao faz muitos FLUSH TABLES (que apenas for¸ca todas as tabelas a serem
fechadas e reabertas), enao vocˆe deve aumentar o valor desta vari´avel.
Tenha certeza que seu sistema operacional pode lidar com o n´umero de de-
scritores de arquivos abertos configurado em table_cache. Se o table_cache
estiver configurado muito alto, o MySQL pode executar sem os descritores de ar-
quivos e recusar conex˜oes, falhar ao realizar consultas e se tornar muito inst´avel.
Para informa¸oes sobre como o cache de tabelas funciona, veja hundefinedi
[Table cache], page hundefinedi.
table_type
O tipo padr˜ao de tabelas.
thread_cache_size
Quantas threads devem ser mantidas em cache para reutiliza¸ao. Quando um
cliente desconecta, as threads dos clientes s˜ao colocadas no cache se n˜ao existir
mais de thread_cache_size threads que antes. Todas novas threads ser˜ao
obtidas primeiramente do cache, e s´o quando o cache estiver vazio uma nova
thread ´e criada. Esta vari´avel pode ser aumentada para melhorar a performance
se vocˆe tiver v´arias conex˜oes novas. (Normalmente isto n˜ao d´a uma melhora
de performance not´avel se vocˆe possuir uma boa implementa¸ao de threads.)
Examinando as diferen¸cas entre Connections eThreads_create pode ser visto
o qu˜ao eficente ´e o cache de threads atual.
thread_concurrency
No Solaris, mysqld ir´a chamar thr_setconcurrency() com este valor. thdr_
setconcurre=() permite que a aplica¸ao forne¸ca ao sistema de threads uma
dica com o n´umero desejado de threads que devem ser executados ao mesmo
tempo.
thread_stack
O tamanho da pilha para cada thread. arios dos limites detectados pelo
teste crash-me ao dependentes deste valor. O padr˜ao ´e grande o suficiente
para opera¸oes normais. See hundefinedi[Benchmarks do MySQL], page hun-
definedi.
timezone O fuzo hor´ario para este servidor.
tmp_table_size
Se uma tabela tempor´aria em mem´oria exceder este tamanho, o MySQL ir´a
a convertˆe-la automaticamente para uma tabela MyISAM em disco. Aumente o
valor de tmp_table_size se vocˆe fizer v´arias consultas GROUP BY avan¸cadas e
vocˆe tiver muita mem´oria.
tmpdir O diret´orio utilizado para arquivos tempor´arios e tabelas tempor´arias.
version O n´umero da vers˜ao do servidor.
268 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
wait_timeout
O n´umero de segundos que o servidor espera pela atividade em uma conex˜ao
antes de feca-la. Veja tamb´em interactive_timeout.
A se¸ao do manual que descreve a sintonia do MySQL cont´em algumas informa¸oes de como
sintonizar as vari´aveis acima. See hundefinedi[Parˆametros do servidor], page hundefinedi.
4.5.5.5 SHOW LOGS
SHOW LOGS exibe estat´
isticas sobre os arquivos log existentes. Atualmente ele s´o exibe in-
forma¸oes sobre arquivos de log Berkeley DB.
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 ´e necess´ario para o subsistema de transa¸oes)
4.5.5.6 SHOW PROCESSLIST
SHOW PROCESSLIST exibe quais threads est˜ao em execu¸ao. Esta informa¸ao tamb´em pode
ser obtida utilizando o comando mysqladmin processlist. Se vocˆe possuir o privil´egio
process, poder´a ver todas as threads. Sen˜ao s´o ´e poss´
ivel ver as pr´oprias threads. See
hundefinedi[KILL], page hundefinedi. Se vocˆe n˜ao utiliza a op¸ao FULL, ent˜ao somente os
primeiros 100 caracteres de cada query seri˜ao exibidos.
Este comando ´e muito ´util caso vocˆe obtenha a mensagem de erro ’too many connections’
e deseja saber o que est´a ocorrendo. O MySQL reserva uma conex˜ao extra por cliente com
o privil´egio Process_priv para garantir que vocˆe sempre consiga logar e conferir o sistema
(assumindo que este privil´egio n˜ao foi concedido para todos os usu´arios).
4.5.5.7 SHOW GRANTS
SHOW GRANTS FOR usu´ario lista os comandos concedidos que devem ser usados para duplicar
os direitos de um usu´ario.
mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO ’root’@’localhost’ WITH GRANT OPTION |
+---------------------------------------------------------------------+
4.5.5.8 SHOW CREATE TABLE
Exibe uma instru¸ao CREATE TABLE que ir´a 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,
Chapter 4: Administra¸ao de Bancos de Dados MySQL 269
PRIMARY KEY (id)
) TYPE=MyISAM
SHOW CREATE TABLE ir´a citar os nomes de colunas e tabelas de acordo com a
op¸ao SQL_QUOTE_SHOW_CREATE.hundefinedi[SET OPTION SQL_QUOTE_SHOW_CREATE],
page hundefinedi.
4.6 Localiza¸ao do MySQL e Utiliza¸ao Internacional
4.6.1 O Conjunto de Caracteres Utilizado para Dados e
Ordena¸ao
Por padr˜ao, o MySQL utiliza o conjunto de caracteres ISO-8859-1 (Latin1) com ordena¸ao
de acordo com o sueco/finlandˆes. Este tamb´em ´e o conjunto de caracteres aplic´avel nos
EUA e oeste da Europa.
Todos os bin´arios padr˜oes do MySQL s˜ao compilados com --with-extra-
charsets=complex. Isto adicionar´a c´odigo a todos os programas padr˜oes para estarem
aptos a lidar com o conjuntos de caracteres latin1 e todos os multi-byte no bin´ario.
Outros conjuntos de caracteres ser˜ao carregados de um arquivo de defini¸oes de conjuntos
de caracteres quando necess´arios.
O conjunto de caracteres determina quais s˜ao os caracteres permitidos em nomes e qual a
forma de ordena¸ao por cl´ausulas ORDER BY eGROUP BY da instru¸ao SELECT.
Voe pode alterar o conjunto de caracteres com a op¸ao --default-character-set na
inicializa¸ao do servidor. Os conjuntos de caracteres dispon´
iveis dependem dos parˆametros
--with-charset=charset e--with-extra-charset= list-of-charset | complex | all
e os arquivos de configura¸oes de conjuntos de caracteres listados em ‘SHAREDIR/charsets/
Index’. See hundefinedi[Op¸oes de configura¸oes], page hundefinedi.
Se o conjunto de caracteres for alterado durante a execu¸ao do MySQL (que tamb´em pode
alterar a ordena¸ao), deve-se executar o myisamchk -r -q em todas as tabelas. De outra
forma seus ´
indices podem n˜ao ser ordenados corretamente.
Quando um cliente conecta a um servidor MySQL, o servidor envia o conjunto de caracteres
padr˜ao em uso ao cliente. O cliente ir´a alternar para o uso deste conjunto de caracteres
nesta conex˜ao.
Deve ser utilizado mysql_real_escape_string() quando desejar ignorar seguˆencias de
caracteres em uma consulta SQL. mysql_real_escape_string() ´e identico `a antiga fun¸ao
mysql_espace_string(), exceto pelo fato de usar a manipulador de conex˜ao MySQL como
o primeiro parˆametro.
Se o cliente for compilado com o caminho diferente daquele onde o servidor est´a instalado e
o usu´ario que configurou o MySQL n˜ao incluiu todos os conjuntos de caracteres no bin´arios
do MySQL, deve ser especificado para o cliente onde ele pode encontrar os conjuntos de
caracteres adcicionais que ser˜ao necess´arios se o servidor executar com um conjunto de
caracteres diferente do cliente.
Isto pode ser especificado colocando em um arquivo de op¸oes do MySQL:
270 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
onde o caminho aponta para onde os conjuntos de caracteres dinˆamicos do MySQL s˜ao
armazenados.
Pode-se for¸car o cliente a usar conjuntos de caracteres espec´
ificos especificando:
[client]
default-character-set=nome-conjunto-caracteres
mas normalmente isto nunca ser´a necess´ario.
4.6.2 Mensagens de Erros em Outras L
´
inguas
mysqld pode exibir mensagens de erros nas seguintes l´
inguas: Tcheco, Dinamarquˆes,
Holandˆes, Inglˆes (padr˜ao), Estonian, Francˆes, Alem˜ao, Grego, H´ungaro, Italiano, Japonˆes,
Koreano, Norueguˆes, Norueguˆes-ny, Polonˆes, Portuguˆes, Romeno, Russo, Eslovaco,
Espanhol e Sueco.
Para iniciar o mysqld com uma l´
ingua particular, use uma das op¸oes: --language=l´
ingua
ou -L l´
ingua . Por exemplo:
shell> mysqld --language=swedish
ou:
shell> mysqld --language=/usr/local/share/swedish
Perceba que todos as l´
inguas s˜ao especificados em min´usculas.
Os arquivos de linguagens est˜ao localizados (por padr˜ao) em ‘mysql base dir/share/LINGUA/’.
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ˆe atualizar o MySQL para uma vers˜ao mais nova, lembre-se de repetir as altera¸oes
no novo arquivo ‘errmsg.txt’.
4.6.3 Adicionando um Novo Conjunto de Caracteres
Para adicionar outro conjunto de caracteres ao MySQL, utilize o seguinte procedimento.
Decida se o conjunto ´e simples ou complexo. Se o conjunto de caracteres n˜ao necessitar do
uso de rotinas especiais de classifica¸ao de strings para ordena¸ao e tamb´em n˜ao necessitar
de suporte `a caracteres multi-byte, ser´a simples. Se ele necessitar de alguns destes recursos,
ser´a complexo.
Por exemplo, latin1 edanish ao conjuntos simples de caracteres enquanto big5 ou czech
ao conjuntos de caracteres complexos.
Na seguinte se¸ao, assumimos que vocˆe 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´umero ´unico 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 ´e muito simples:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 271
Comenarios iniciam com um caractere ’#’ e continuam at´e o fim da linha.
Palavras s˜ao separadas por quantidades arbitr´arias de espa¸cos em brancos.
Ao definir o conjunto de caracteres, cada palavra deve ser um n´umero no formato
hexadecimal
O vetor ctype obtˆem as primeiras 257 palavras. Os vetores to_lower,to_upper
esort_order obtˆem, cada um, as 256 palavras seguintes.
See hundefinedi[Vetor de caracteres], page hundefinedi.
3. Adicione o nome do conjunto de caracteres `as listas CHARSETS_AVAILABLE eCOMPILED_
CHARSETS no configure.in.
4. Reconfigure, recompile e teste.
Para um conjunto de caracteres complexo fa¸ca o seguinte:
1. Crie o arquivo ‘strings/ctype-MYSET.c’ na distribui¸ao fonte do MYSQL.
2. Adicione MYSET ao final do arquivo ‘sql/share/charsets/Index’. Associe um
n´umero ´unico 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 - See hundefinedi[Vetor de caracteres], page hundefinedi
- para um conjunto de caracteres complexo.
4. Pr´oximo ao topo do arquivo, coloque um comenario 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 comenario para incluir o conjunto de caracteres
na biblioteca MySQL automaticamente.
As linhas strxfrm multiply e mbmaxlen ser˜ao explicadas nas pr´oximas se¸oes. o as
inclua se vocˆe precisar de fun¸oes de ordena¸ao de strings ou das fun¸oes de conjuntos
de caracteres multi-byte, respectivamente.
5. Vocˆe deve enao criar algumas das seguintes fun¸oes:
my_strncoll_MYSET()
my_strcoll_MYSET()
my_strxfrm_MYSET()
my_like_range_MYSET()
See hundefinedi[Ordena¸ao de caracteres], page hundefinedi.
6. Adicione o nome do conjunto de caracteres `as listas CHARSETS_AVAILABLE eCOMPILED_
CHARSETS no configure.in.
7. Reconfigure, recompile e teste.
272 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O arquivo ‘sql/share/charsets/README’ fornece algumas instru¸oes a mais.
Se vocˆe desejar ter o seu conjunto de caracteres inclu´
ido na distribui¸ao MySQL, envie um
email com um patch para internals@lists.mysql.com.
4.6.4 Os vetores de defini¸oes de caracteres
to_lower[] eto_upper[] ao vetores simples que definemm os caracteres min´usculos e
ma´
isculos correspondentes a cada membro do conjunto de caracteres. Por exemplo:
to_lower[’A’] deve conter ’a’
to_upper[’a’] deve conter ’A’
sort_order[] ´e um mapa indicando como os caracteres devem ser ordenados para
prop´ositos de compara¸ao e ordena¸ao. Para v´arios conjuntos de caracteres, isto ´e o
mesmo que to_upper[] (que significa ordenar em caso insensitivo). O MySQL ordenar´a
caracteres baseado no valor de sort_order[caractere]. Para regras mais complicadas de
ordena¸ao, veja a discuss˜ao sobre ordena¸ao de string abaixo. See hundefinedi[Ordena¸ao
de strings], page hundefinedi.
ctype[] ´e um vetor com valores bin´arios, com um elemento para cada caracter. (Note
que to_lower[],to_upper[] esort_order[] ao indexados pelo valor do caracter, mas o
ctype[] ´e indexado pelo valor do caracter +1. Este ´e um antigo legado para tratamento
de EOF.)
Pode-se encontrar as seguintes m´ascaras bin´arias de defini¸oes em ‘m_ctype.h’:
#define _U 01 /* Ma´
isculo */
#define _L 02 /* Min´usculo */
#define _N 04 /* Numeral (digito) */
#define _S 010 /* Caractere de espa¸co */
#define _P 020 /* Pontua¸c~ao */
#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˜ao dos valores da m´ascara bin´aria que
descrevem o caracter. Por exemplo, ’A’ ´e um caracter mai´usculo (_U) bem como um d´
igito
hexadecimal (_X), portanto ctype[’A’+1] deve conter o valor:
_U + _X = 01 + 0200 = 0201
4.6.5 Suporte `a Ordena¸ao de Strings
Se as regras de ordena¸ao para a sua linguagem forem muito complexas para serem tratadas
com uma simples tabela sort_order[], ser´a necess´ario o uso das fun¸oes de ordena¸ao de
strings.
No momento, a melhor documenta¸ao sobre isto s˜ao os conjuntos de caracteres que j´a est˜ao
implementados. Confira os conjuntos de caracteres big5, czech, gbk, sjis e tis160 para
exemplos.
Voe deve especificar o valor strxfrm_multiply_MYSET=N no coment´ario especial no topo
do arquivo. Ndeve ser configurado para a raz˜ao m´axima que as strings podem crescer
durante my_strxfrm_MYSET (ele deve ser um inteiro positivo).
Chapter 4: Administra¸ao de Bancos de Dados MySQL 273
4.6.6 Suporte `a Caracteres Multi-byte
Se vocˆe deseja adicionar suporte para novos conjuntos de caracteres que incluem caracteres
multi-byte, vocˆe precisa usar as fun¸oes para caracteres multi-byte.
No momento, a melhor documenta¸ao sobre isto s˜ao os conjuntos de caracteres que j´a
est˜ao implementados. Confira os conjuntos de caracteres euc kr, gb2312, gbk, sjis e ujis
para exemplos. Eles s˜ao implementados no arquivo ctype-’conj_caracter’.c no diret´orio
strings
Voe deve especificar o valor mbmaxlen_MYSET=N no coment´ario especial no topo do arquivo.
Ndeve ser configurado como o tamanho em bytes do maior caracter no conjunto.
4.7 Utilit´arios e Scripts do Lado Servidor MySQL
4.7.1 Vis˜ao Geral dos Scripts e Utilit´arios do Lado Servidor
Todos os clientes MySQL que comunicam com o servidor utilizando a biblioteca
mysqlclient usam as seguintes vari´aveis de ambitente:
Nome Descri¸ao
MYSQL_UNIX_PORT O socket padr˜ao; utilizado para conex˜oes `a localhost
MYSQL_TCP_PORT A porta TCP/IP padr˜ao
MYSQL_PWD A senha padr˜ao
MYSQL_DEBUG Op¸oes de depura¸ao-rastreamento ao debugar
TMPDIR O diret´orio onde tabelas e arquivos tempor´arios s˜ao criados
A utiliza¸ao de MYSQL_PWD ´e insegura. See hundefinedi[Conectando], page hundefinedi.
O cliente ‘mysql’ utiliza o arquivo nomeado na vari´avel de ambiente MYSQL_HISTFILE para
salvar o hist´orico da linha de comando. O valor padr˜ao para o arquivo de hist´orico ´e
$HOME/.mysql_history’ onde $HOME ´e o valor da vari´avel de ambiente HOME. See hunde-
finedi[Vari´aveis de ambiente], page hundefinedi.
Todos os programas MySQL possuem v´arias op¸oes diferentes, entretanto, todo programa
MySQL fornece uma op¸ao --help que pode ser usada para obter uma descri¸ao completa
das diferentes op¸oes do programa. Por exemplo, experimente mysql --help.
Voe pode sobrepor ignorar as op¸oes padr˜oes para todos os programas clientes com um
arquivo de op¸oes. hundefinedi[Arquivo de op¸oes], page hundefinedi.
A lista abaixo descreve brevemente os programas MySQL.
myisamchk
Utilit´ario para descrever, conferir, otimizar e reparar tabelas MySQL. Como o
myisamchk tem muitas fun¸oes, eles s˜ao descritos em seu pr´oprio cap´
itulo. See
hundefinedi[Administra¸ao do Banco de Dados MySQL], page hundefinedi.
make_binary_distribution
Cria uma edi¸ao bin´aria de um MySQL compilado. Isto pode ser enviado por
FTP para ‘/pub/mysql/Incoming’ em support.mysql.com para a conveniˆencia
de outros usu´arios MySQL.
274 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
msql2mysql
Um script shell que converte programas mSQL para MySQL. Ele n˜ao consegue
lidar com todos os casos, mas ´e um bom come¸co quando uma convers˜ao for
necess´aria.
mysqlaccess
Um script que confere os privil´egios de acesso para uma combina¸ao de m´aquina,
usu´ario e banco de dados.
mysqladmin
Utilit´ario para realizar opera¸c˜oes administrativas, como a cria¸ao ou remo¸ao
de bancos de dados, recarga das tabelas de permiss˜oes, descarga de tabelas ao
disco e reabertura de arquivos log. mysqladmin pode tamb´em ser utilizado para
exibir informa¸oes de vers˜ao, processos e estado do servidor. See hundefinedi
[mysqladmin], page hundefinedi.
mysqlbug O script para relatar erros no MySQL. Este script deve sempre ser utilizado
quando for necess´ario preencher um relat´orio de erros para a lista do MySQL.
mysqld O servidor (daemon) SQL. Deve sempre estar em execu¸ao.
mysqldump
Descarrega um banco de dados MySQL em um arquivo no formato de in-
stru¸oes SQL ou como arquivos texto separado por tabula¸oes. Vers˜ao melho-
rada do freeware produzido originalmente por Igor Romanenko. See hundefinedi
[mysqldump], page hundefinedi.
mysqlimport
Importa arquivos texto em suas respectivas tabelas utilizando LOAD DATA
INFILE. See hundefinedi[mysqlimport], page hundefinedi.
mysqlshow
Exibe informa¸oes sobre bancos de dados, tabelas, colunas e ´
indices.
mysql_install_db
Cria as tabelas de permiss˜oes do MySQL com os privil´egios padr˜oes. Este
comando normalmente ´e executado somente na primeira vez quando o MySQL
´e instalado em um sistema.
replace Um programa utilit´ario que ´e utilizado pelo msql2mysql, mas tamb´em pode
ser utilizado para aplica¸oes gerais. replace altera strings em arquivos ou na
entrada padr˜ao. Utiliza uma m´aquina de estado finito para coincidir primeira-
mente com strings maiores. Pode ser utilizado para trocar strings. Por exemplo,
este comando troca aebnos arquivos fornecidos:
shell> replace a b b a -- arquivo1 arquivo2 ...
4.7.2 safe mysqld, a capa do mysqld
safe_mysqld ´e a maneira recomendada para iniciar um daemon mysqld no Unix. safe_
mysqld adiciona alguns recursos de seguran¸ca tais como reiniciar o servidor quando um erro
ocorrer e log de informa¸oes de tempo de execu¸ao a um arquivo log.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 275
Se vocˆe n˜ao utilizar --mysqld=# ou --mysql-version=# osafe_mysqld ir´a utilizar um
execut´avel chamado mysqld-max se ele existir. Se n˜ao, safe_mysqld ir´a iniciar o mysqld.
Isto torna muito f´acil utilizar o mysql-max no lugar do mysqld; basta copiar mysqld-max
no mesmo diret´orio do mysqld e ele ser´a utillizado.
Normalmente o script safe_mysqld nunca deve ser editado, em vez disto, coloque as op¸oes
para o safe_mysqld na se¸ao [safe_mysqld] no arquivo my.cnf. O safe_mysqld ir´a ler
todas as op¸oes das se¸oes [mysqld],[server] e[safe_mysqld] dos arquivos de op¸oes.
See hundefinedi[Arquivo de op¸oes], page hundefinedi.
Note que todas as op¸oes na linha de comando para o safe_mysqld ao passadas para o
mysqld. Se vocˆe deseja usar algumas op¸oes no safe_mysqld que o mysqld ao suporte,
vocˆe deve especific´a-las no arquivo de op¸oes.
A maioria das op¸oes para safe_mysqld ao as mesmas que as do mysqld. See line options-
snt [Op¸oes de linha de comando], page line options-pg.
safe_mysqld suporta as seguintes op¸oes:
--basedir=caminho
--core-file-size=#
Tamanaho do arquivo core que o mysqld poder´a criar. Passado para ulimit
-c.
--datadir=caminho
--defaults-extra-file=caminho
--defaults-file=caminho
--err-log=caminho
--ledir=caminho
Caminho para mysqld
--log=caminho
--mysqld=vers~ao_do_mysqld
Nome da vers˜ao do mysqld no diret´orio ledir que vocˆe deseja iniciar.
--mysqld-version=vers~ao
Similar ao --mysqld= mas aqui vocˆe s´o fornece o sufixo para o mysqld. Por
exemplo, se vocˆe utiliza --mysqld-version=max, o safe_mysqld ir´a iniciar a
vers˜ao ledir/mysqld-max. Se o argumento para --mysqld-version estiver
vazio, ledir/mysqld ser´a usado.
--no-defaults
--open-files-limit=#
N´umero de arquivos que o mysqld poder´a abrir. Passado para ulimit -n.
Perceba que ser´a necess´ario iniciar safe_mysqld como root para isto funcionar
corretamente!
--pid-file=caminho
--port=#
--socket=caminho
--timezone=#
Configura a vari´avel de fuso hor´ario (TZ) para o valor deste parˆametro.
--user=#
276 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O script safe_mysqld ´e graavel, portanto ele deve estar apto para iniciar um servidor que
foi instalado de uma fonte ou uma vers˜ao bin´aria do MySQL, mesmo se o servidor estiver
instalado em localiza¸oes um pouco diferentes. safe_mysqld espera uma destas condi¸oes
ser verdadeira:
O servidor e o banco de dados pode ser encontrado relativo ao diret´orio de onde o
safe_mysqld foi chamado. safe_mysqld procura dentro de seu diret´orio de trabalho
pelos diret´orios ‘bin’ e ‘data’ (para distribui¸oes bin´arias) ou pelos diret´orios ‘libexec
e ‘var’ (para distribui¸oes baseadas em c´odigo fonte). Esta condi¸ao deve ser satisfeita
se vocˆe executar o safe_mysqld a partir do seu diret´orio da instala¸ao do MySQL (por
exemplo, ‘/usr/local/mysql’ para uma distribui¸ao bin´aria).
Se o servidor e os bancos de dados n˜ao forem encontrados relativos ao diret´orio de
trabalho, safe_mysqld tenta localiz´a-lo utilizando caminhos absolutos. Localiza¸oes
t´
ipicas s˜ao ‘/usr/local/libexec’ e ‘/usr/local/var’. As localiza¸oes atuais foram
determinadas quando a distribui¸ao foi constru´
ida da qual vem o safe_mysqld. Eles
dever estar corretas se o MySQL foi instalado na localiza¸ao padr˜ao.
Como o safe_mysqld tentar´a encontrar o servidor e o banco de dados relativo a seu diret´orio
de trabalho, vocˆe pode instalar uma distribui¸ao bin´aria do MySQL em qualquer lugar,
desde de que o safe_mysqld seja iniciado a partir do diret´orio da instala¸ao:
shell> cd diret´orio_instala¸c~ao_mysql
shell> bin/safe_mysqld &
Se o safe_mysqld falhar, mesmo se invocado a partir do diret´orio de instala¸ao do MySQL,
vocˆe pode modific´a-lo para usar o caminho para o mysqld e as op¸oes de caminho que
seriam corretas para seu sistema. Perceba que se vocˆe atualizar o MySQL no futuro, sua
vers˜ao modificada de safe_mysqld ser´a sobrescrita, portanto, voe deve fazer uma c´opia de
sua vers˜ao editada para que vocˆe a possa reinstalar.
4.7.3 mysqld multi, programa para gerenciar m´ultiplos servidores
MySQL
mysqld_multi gerencia v´arios processos mysqld executando em diferentes sockets UNIX e
portas TCP/IP.
O programa ir´a pesquisar pelo(s) grupo(s) chamado(s) [mysqld#] no my.cnf (ou no arquivo
fornecido no parˆametro --config-file=...), onde # pode ser qualquer n´umero positivo a partir
de 1. Estes grupos devem ser os mesmos que o grupo [mysqld] usual (ex.: op¸oes para o
mysqld, veja o manual do MySQL para informa¸oes mais detalhadas sobre este grupo), mas
com as op¸oes de portas, sockets e etc. que s˜ao necess´arias para cada processo separado do
mysqld. O n´umero no nome do grupo tem outra fun¸ao; ele pode ser utilizado para iniciar,
parar ou relatar alguns servidores mysqld espec´
ificos com este programa. Veja o uso e as
op¸oes abaixo para maiores informa¸oes.
Uso: mysqld_multi [OP~
OES] {start|stop|report} [GNR,GNR,GNR...]
ou mysqld_multi [OP~
OES] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]
O GNR acima significa o n´umero do grupo. Voe pode iniciar, parar ou relacionar qualquer
GNR ou v´arios deles ao mesmo tempo. (Veja --example). A lista dos GNR podem ser
separadas por v´
irgulas, ou pelo sinal sinal de menos (-), sendo que o ultimo significa que
todos os GNRS entre GNR1-GNR2 ser˜ao afetados. Sem o argumento GNR todos os grupos
Chapter 4: Administra¸ao de Bancos de Dados MySQL 277
encontrados ser˜ao iniciados, parados ou listados. Perceba que voe n˜ao deve ter nenhum
espa¸co em branco na lista GNR. Qualquer coisa depois de um espa¸co em branco ´e ignorado.
mysqld_multi suporta as seguintes op¸oes:
--config-file=...
Arquivo de configura¸ao alternativo. NOTA: Isto n˜ao ir´a afetar as pr´oprias
op¸oes do programa (grupo [mysqld_multi]), mas somente grupos [mysqld#].
Sem esta op¸ao tudo ser´a procurado a partir do arquivo my.cnf.
--example
Fornece um exemplo de um arquivo de configura¸ao.
--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´a anexado.
--mysqladmin=...
Bin´ario mysqladmin a ser usado para o desligamento do servidor.
--mysqld=...
Bin´ario mysqld a ser usado. Lembre-se que voe tamb´em pode fornecer safe_
mysqld a esta op¸ao. As op¸oes s˜ao passadas ao mysqld. Apenas tenha certeza
que o mysqld est´a localizado na sua vari´avel de ambiente PATH ou corrija o
safe_mysqld.
--no-log Imprime na sa´
ida padr˜ao em vez do arquivo log. Por padr˜ao o arquivo log
sempre fica ligado.
--password=...
Senha do usu´ario para o mysqladmin.
--tcp-ip Conecta ao(s) servidor(es) MySQL atrav´es de porta TCP/IP no lugar de socket
UNIX. Isto afeta a a¸ao de desligar e relatar. Se um arquivo socket estiver
faltando, o servidor pode ainda estar executando, mas s´o pode ser acessado
atrav´es da porta TCP/IP. Por padr˜ao a conex˜ao ´e feita atrav´es de socket UNIX.
--user=...
Usu´ario MySQL para o mysqladmin.
--version
Exibe o n´umero da vers˜ao e sai.
Algumas notas sobre mysqld_multi:
Tenha certeza que o usu´ario MySQL, que finalizar os servi¸cos mysqld (e.g. utilizando o
mysqladmin) tem a mesma senha e usu´ario para todos os diret´orios de dados acessados
(para o banco de dados ’mysql’). E tenha certeza que o usu´ario tem o privil´egio
’Shutdown priv’! Se vocˆe possui diversos diret´orios de dados e v´arios bancos de dados
’mysql’ com diferentes senhas para o usu´ario ’root’ do MySQL, voe pode desejar
criar um usu´ario comum ’multi-admin’ para cada um que utilize a mesma senha (veja
abaixo). Exemplo de como fazer isto:
278 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shell> mysql -u root -S /tmp/mysql.sock -psenha_root -e
"GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY ’multipass’"
See hundefinedi[Privileges], page hundefinedi.
Voe deve fazer isto para cada servidor mysqld executando em cada diret´orio de dados,
que vocˆe tem (Apenas altere o socket, -S=...)
pid-file ´e muito importante, se vocˆe estiver utilizando safe_mysqld para iniciar
omysqld (ex. --mysqld=safe mysqld) Todos os mysqld devem ter seus pr´oprios pid-
file. A vantagem de utilizar o safe_mysqld no lugar de executar diretamente o mysqld
´e que safe_mysqld guarda todos os processos e ir´a reinici´a-los, se um processo do
mysqld falhar devido a um sinal kill -9, ou similar. (Como um falha de segmenta¸ao,que
nunca pode acontecer com o MySQL.) Por favor note que pode ser necess´ario executar o
script safe_mysqld de um lugar espec´
ifico. Isto significa que vocˆe pode ter que alterar
o diret´orio atual para um diret´orio espec´
ifico antes de iniciar o mysqld_multi. Se vocˆe
tiver problemas ao iniciar, por favor veja o script safe_mysqld. 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
-------------------------------------------------------------------
-------
See hundefinedi[safe_mysqld], page hundefinedi.
O teste acima deve ser bem sucedido, ou vocˆe pode encontrar problemas.
Esteja certo do perigoso de iniciar m´ultiplos mysqlds no mesmo diret´orio de dados.
Utilize diret´orios de dados diferentes, a menos que vocˆe realmente SAIBA o que est´a
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.
Voe pode ter lacunas no arquivo de configura¸ao. Isto lhe permite mais flexibilidade.
A ordem na qual os mysqlds ao iniciados ou desligados depende da ordem em que eles
aparecem no arquivo de configura¸ao.
Quando vocˆe desejar referenciar a um grupo espec´
ifico utilizando GNR com este pro-
grama, basta utilizar o n´umero no fim do nome do grupo ([mysqld# <==).
Voe pode desejar utilizar a op¸ao ’--user’ para o mysqld, mas para isto vocˆe precisa ser
o usu´ario root quando iniciar o script mysqld_multi. ao importa se a op¸ao existe no
arquivo de configura¸ao; vocˆe receber´a apenas um alerta se vocˆe n˜ao for o superusu´ario
e o mysqlds for iniciado com a SUA conta no Unix. IMPORTANTE: Tenha certeza
que o pid-file e o diret´orio de dados ´e acess´
ivel para leitura e escrita (+execu¸ao para
o diret´orio) para ESTE usu´ario UNIX que iniciar´a o processo mysqld.N˜
AO utilize a
conta de root para isto, a menos que vocˆe SAIBA o que est´a fazendo!
MAIS IMPORTANTE: Tenha certeza que vocˆe entendeu os significados das op¸oes
que s˜ao passadas para os mysqlds e porque VOC PRECISARIA ter processos mysqld
separados. Iniciando m´ultiplos mysqlds em um diret´orio de dados N˜
AO IR ´
Amelhorar
a performance em um sistema baseado em threads.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 279
See hundefinedi[Servidores m´ultiplos], page hundefinedi.
Este ´e um exemplo do arquivo de configura¸ao para o funcionamento do mysqld_multi.
# Este arquivo provavelmente deve estar em seu diret´orio home (~/.my.cnf) ou /etc/my.cnf
# Version 2.1 by Jani Tolonen
[mysqld_multi]
mysqld = /usr/local/bin/safe_mysqld
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
See hundefinedi[Arquivo de op¸oes], page hundefinedi.
4.7.4 myisampack, O Gerador de Tabelas Compactadas Somente
Leitura
myisampack ´e usado para compactar tabelas MyISAM, e pack_isam ´e usado para compactar
tabelas ISAM. Como as tabelas ISAM est˜ao ultrapassadas, n´os iremos discutir aqui somente
280 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
sobre o myisampack, mas tudo dito sobre myisampack tamb´em pode ser verdadeiro para o
pack_isam.
myisampack trabalha compactando cada coluna na tabela separadamente. A informa¸ao
necess´aria para descompactar colunas ´e lida em mem´oria quando a tabela ´e aberta. Isto
resulta em uma performance muito melhor quando estiver acessando registros individuais,
porque vocˆe precisar´a descompactar somente um registro, n˜ao 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´oria (nmap()) em tabelas compactadas e retorna ao
uso normal de leitura e escrita se nmap() ao funcionar.
Atualmente existem duas limita¸oes com myisampack:
Depois da compacta¸ao, a tabela deve trabalhar somente para leitura.
myisampack tamb´em pode compactar colunas BLOB ou TEXT. O antigo pack_isam ao
pode fazer isto.
A corre¸ao destas limita¸oes est´a em nossa lista de pendencias (TODO), mas com baixa
prioridade.
myisampack ´e chamado desta forma:
shell> myisampack [op¸c~oes] nome_arquivo ...
Cada nome arquivo deve ter o nome de um arquivo de ´
indice (‘.MYI’). Se vocˆe n˜ao se
encontra em um diret´orio de bancos de dados, vocˆe deve especificar o caminho completo
para o arquivo. Pode-se omitir a extens˜ao ‘.MYI’.
myisampack suporta as seguintes op¸oes:
-b, --backup
Realiza um backup da tabela como nome_tabela.OLD.
-#, --debug=debug_options
Log da sa´
ida de depura¸ao. A string debug_options geralmante ´e
’d:t:o,nome_arquivo’.
-f, --force
For¸ca a compacta¸ao da tabela mesmo se ela se tornar maior ou se o arquivo
tempor´ario existir. myisampack cria um arquivo tempor´ario chamado ‘nome_
tabela.TMD’ enquanto ele compacta a tabela. Se vocˆe matar o myisampack o
arquivo ‘.TMD’ n˜ao 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 ´unica tabela nome_
tabela_grande. Todas tabelas que forem combinadas DEVEM ser idˆenticas
(mesmos nomes de colunas e tipos, alguns ´
indices, 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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 281
tamanhos 1, 2 ou 3 bytes. Na maioria dos casos normais, myisampack pode
determinar o valor correto do tamanho antes de come¸car a compactar o arquivo,
mas ele pode notificar durante o processo de compacta¸ao que ele pode ter usado
um tamanho menor. Neste caso myisampack ir´a exibir uma nota dizendo que
a pr´oxima vez que vocˆe compactar o mesmo arquivo vocˆe pode utilizar um
registro de tamanho menor.)
-s, --silent
Modo silencioso. Escreve a sa´
ida somente quando algum erro ocorrer.
-t, --test
ao compacta realmente a tabela, apenas testa a sua compacta¸ao.
-T dir_name, --tmp_dir=dir_name
Utiliza o diret´orio especificado como a localiza¸ao em que ser˜ao gravadas as
tabelas tempor´arias.
-v, --verbose
Modo verbose. Escreve informa¸ao sobre o prograsso e resultado da com-
pacta¸ao.
-V, --version
Exibe informa¸ao de vers˜ao e sai.
-w, --wait
Espera e tenta novamente se a tabela estiver em uso. Se o servidor mysqld foi
iniciado com a op¸ao --skip-locking, n˜ao ´e uma boa id´eia chamar myisampack
se a tabela puder ser atualizada durante o processo de compacta¸ao.
A seqˆencia de comandos mostrados abaixo ilustra uma t´
ipica se¸ao de compacta¸ao 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
282 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
1 2 4 unique unsigned long 1024 1024 1
2 32 30 multip. text 10240 1024 1
Field Start Length Type
111
224
364
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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 283
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
284 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 285
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¸ao exibida pelo myisampack ´e descrita abaixo:
normal O n´umero de colunas para qual nenhum empacotamento extra ´e utilizado.
empty-space
O n´umero de colunas contendo valores que s˜ao somente espa¸cos; estes ocupar˜ao
apenas 1 bit.
empty-zero
O n´umero de colunas contendo valores que s˜ao somente 0’s bin´arios; ocupar˜ao
1 bit.
empty-fill
O n´umero de colunas inteiras que n˜ao ocupam a faixa completa de bytes de
seu tipo; estes s˜ao alteradas para um tipo menor (por exemplo, uma coluna
INTEGER pode ser alterada para MEDIUMINT).
pre-space
O n´umero de colunas decimais que s˜ao armazenadas com espa¸cos a esquerda.
Neste caso, cada valor ir´a conter uma contagem para o n´umero de espa¸cos.
end-space
O n´umero de colunas que tem muitos espa¸cos espa¸cos extras. Neste caso, cada
valor conter´a uma contagem para o n´umero de espa¸cos sobrando.
table-lookup
A coluna tem somente um pequeno n´umero de valores diferentes, que s˜ao con-
vertidos para um ENUM antes da compress˜ao Huffman.
zero O n´umero de colunas em que todos os valores est˜ao zerados.
Original trees
O n´umero inicial de ´arvores Huffman.
After join
O n´umero de ´arvores Huffman distintas que sobram depois de unir ´arvores para
poupar espa¸co de cabcalho.
Depois que uma tabela foi compactada, myisamchk -dvv exibe informa¸oes adicionais sobre
cada campo:
Type O tipo de campo deve conter as seguites descri¸oes:
constant Todas linhas tem o mesmo valor.
no endspace
ao armazena espa¸cos no fim.
286 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
no endspace, not_always
ao armazena espa¸cos no fim e n˜ao faz compacta¸ao de espa¸cos
finais para todos os valores.
no endspace, no empty
ao armazena espa¸cos no fim. ao armazena valores vazios.
table-lookup
A coluna foi convertida para um ENUM.
zerofill(n)
Os nbytes mais significativos no valor s˜ao sempre 0 e n˜ao s˜ao
armazenados.
no zeros ao armazena zeros.
always zero
Valores zero s˜ao armazenados em 1 bit.
Huff tree A ´arvore Huffman associada com o campo.
Bits O n´umero de bits usado na ´arvore Huffman.
Depois de ter executado pack_isam/myisampack vocˆe deve executar o isamchk/myisamchk
para recriar o ´
indice. Neste momento voe pode tamb´em ordenar os blocos de ´
indices
para criar estat´
isticas necess´arias 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´orio de banco de dados MySQL vocˆe deve
fazer mysqladmin flush-tables para for¸car o mysqld a iniciar usando a nova tabela.
Se vocˆe desejar descompactar uma tabela compactada, vocˆe pode fazer isto com a op¸ao
--unpack para o isamchk ou myisamchk.
4.7.5 mysqld-max, Um servidor mysqld extendido
mysqld-max ´e o servidor MySQL (mysqld) configurado com as seguintes op¸oes de con-
figura¸ao:
Op¸ao Comenario
--with-server-suffix=-max Adiciona um sufixo `a string de vers˜ao mysqld
--with-bdb Suporte para tabelas Berkeley DB (BDB)
--with-innodb Suporte a tabelas InnoDB.
CFLAGS=-DUSE SYMDIR Suporte a links simolicos para Windows.
Voe pode encontrar os bin´arios do MySQL-max em http://www.mysql.com/downloads/mysql-
max-3.23.html.
A distribui¸ao bin´aria Windows MySQL 3.23 inclui tanto o bin´ario mysqld.exe padr˜ao
e o bin´ario mysqld-max.exe.http://www.mysql.com/downloads/mysql-3.23.html. See
hundefinedi[Instala¸ao no Windows], page hundefinedi.
Note que como o Berkeley DB e InnoDB n˜ao est˜ao dispon´
iveis para todas plataformas,
alguns dos bin´arios Max podem n˜ao ter suporte para os mesmos. Voe pode conferir quais
tipos de tabelas s˜ao suportadas executando a seguinte consulta:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 287
mysql> show variables like "have_%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_bdb | YES |
| have_innodb | NO |
| have_isam | YES |
| have_raid | NO |
| have_ssl | NO |
+---------------+-------+
O significado dos valores s˜ao:
Vallor Significado.
YES A op¸ao est´a ativa e ´e utilizada.
NO O MySQL n˜ao est´a compilado com suporte a esta op¸ao.
DISABLED A op¸ao xxx est´a desabilitada porque o mysqld foi iniciado
com --skip-xxxx ou porque n˜ao foi iniciado com todas as
op¸oes necess´arias para habilitar esta op¸ao. Neste caso o
arquivo hostname.err deve conter uma raz˜ao do piela qual a
op¸ao est´a desabilitada.
NOTA: Para conseguir criar tabelas InnoDB vocˆe DEVE editar suas op¸oes de inicializa¸ao
para incluir ao menos a op¸ao innodb_data_file_path. See hundefinedi[Iniciando Inn-
oDB], page hundefinedi.
Para obter melhor performance para tabelas BDB, vocˆe deve adicionar algumas op¸oes de
configura¸ao para elas tamb´em .See hundefinedi[Iniciando BDB], page hundefinedi.
safe_mysqld tentar´a iniciar automaticamente qualquer bin´ario mysqld com o prefixo -max.
Isto faz com que seja f´acil testar um outro bin´ario mysqld em uma instala¸ao existente.
Apenas execute o configure com as op¸oes deseejadas e, enao, instale o novo bin´ario
mysqld como mysqld-max no mesmo diret´orio onde seu antigo bin´ario mysqld est´a. See
hundefinedi[safe_mysqld], page hundefinedi.
O RPM mysqld-max utiliza o recurso safe_mysqld a mencionado. Ele apenas instala o
execut´avel mysqld-max e o safe_mysqld usar´a automaticamente este execut´avel quando o
safe_mysqld for reiniciado.
A tabela a seguir mostra quais tipos de tabelas nossos bin´arios padr˜oes MySQL-Max in-
cluem:
Sistema BDB InnoDB
AIX 4.3 N Y
HP-UX 11.0 N Y
Linux-Alpha N Y
Linux-Intel Y Y
Linux-Ia64 N Y
Solaris-intel N Y
Solaris-sparc Y Y
SCO OSR5 Y Y
UnixWare Y Y
Windows/NT Y Y
288 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.8 Utilit´arios e Scripts do Lado do Cliente do MySQL
4.8.1 Vis˜ao Geral dos Utilit´arios e Scripts do Lado do Cliente
Todos clientes MySQL que comunicam com o servidor utilizando a biblioteca mysqlclient
utilizam as seguintes vari´aveis de ambiente:
Nome Descri¸ao
MYSQL_UNIX_PORT O socket padr˜ao, utilizado para conex˜oes ao localhost
MYSQL_TCP_PORT A porta TCP/IP padr˜ao
MYSQL_PWD A senha padr˜ao
MYSQL_DEBUG Op¸oes de depura¸ao-ratreamento durante depura¸ao
TMPDIR O diret´orio onde tabelas e arquivos tempor´arios s˜ao criados
A utiliza¸ao de MYSQL_PWD ´e insegura. See hundefinedi[Connecting], page hundefinedi.
O cliente ‘mysql’ utiliza o arquivo nomeado na vari´avel de ambiente MYSQL_HISTFILE para
salvar o hist´orico da linha de comando. O valor padr˜ao para o arquivo de hist´orico ´e
$HOME/.mysql_history’, onde $HOME ´e o valor da vari´avel de ambiente HOME. See hunde-
finedi[Environment variables], page hundefinedi.
Todos os programas MySQL podem receber v´arias op¸c˜oes diferentes. Entretanto, todo
programa MySQL fornece a op¸ao --help que vocˆe pode utilizar para obter uma descri¸ao
completa das diferentes op¸oes do programa. Por exemplo, experimente mysql --help
Voe pode sobrepor todas as op¸oes padr˜oes para programas cliente padr˜oes com um arquivo
de op¸oes. hundefinedi[Option files], page hundefinedi
A lista abaixo descreve resumidamente os programas MySQL:
myisamchk
Utilit´ario para descrever, verificar, otimizar e reparar tabelas MySQL. Como
omyisamchk tem v´arias fun¸oes, ele ´e descrito em seu pr´oprio cap´
itulo. See
hundefinedi[Administrac˜ao de Banco de Dados MySQL], page hundefinedi.
make_binary_distribution
Gera uma distribui¸ao bin´aria do MySQL compilado. Ela pode ser enviado por
FTP para ‘/pub/mysql/Incoming’ em support.mysql.com para a conveniˆencia
de outros usu´arios MySQL.
msql2mysql
Um script shell que converte programas mSQL para MySQL. Ele n˜ao lida com
todos os casos, mas ele fornece um bom inicio para a convers˜ao.
mysqlaccess
Um script que verifica os privil´egios de acesso para uma combina¸ao de nome
de m´aquina, usu´ario e banco de dados.
mysqladmin
Utilit´ario para realizar opera¸oes administrativas, tais como cria¸ao ou remo¸ao
de bancos de dados, recarga das tabelas de permiss˜oes, descarga de tabelas em
disco e reabertura dos arquivos log. mysqladmin tamb´em pode ser usado para
exibir informa¸oes de vers˜ao, processos e estado do servidor. See hundefinedi
[mysqladmin], page hundefinedi.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 289
mysqlbug O script para relatar erros no MySQL. Este script deve ser usado sempre que
for for relatar algum bug para a lista MySQL.
mysqld O daemon SQL. Deve estar sempre em execu¸ao.
mysqldump
Descarrega um banco de dados MySQL em um arquivo como instru¸oes SQL
ou como arquivo texto separado por tabula¸ao. Vers˜ao aprimorada do free-
ware escrito originalmente por Igor Romanenko. See hundefinedi[mysqldump],
page hundefinedi.
mysqlimport
Importa arquivos texto em suas tabelas respectivas utilizando LOAD DATA
INFILE. See hundefinedi[mysqlimport], page hundefinedi.
mysqlshow
Exibe informa¸oes sobre bancos de dados, tabelas, colunas e ´
indices.
mysql_install_db
Cria as tabelas de permiss˜oes do MySQL com os privil´egios padr˜oes. Isto ´e
normalmente executado somente uma vez, quando estiver instalando o MySQL
em um sistema.
replace Um programa utilit´ario que ´e usado pelo msql2mysql, mas que tamb´em pode ser
aplic´avel mais genericamente. replace altera conjuntos de caracteres. Utiliza
uma m´aquina de estado finito para comparar strings maiores primeiro. Pode
ser usada para trocar conjuntos de caracteres. Por exemplo, este comando troca
aebnos arquivos dados:
shell> replace a b b a -- arquivo1 arquivo2 ...
4.8.2 A Ferramenta de Linha de Comando
Omysql ´e uma shell SQL simples (com capacidades GNU readline). Ele suporta usos
interativos e n˜ao interativos. Quando usado interativamente, os resultados das consultas
ao apresentadas no formato de tabela ASCII. Quando n˜ao usado interativamente (como
um filtro por exemplo), o resultado ´e apresentado em um formato separado por tabula¸oes.
(O formato de sa´
ida pode ser alterado utilizando op¸oes da linha de comando.) Vocˆe pode
executar scripts desta forma:
shell> mysql database < script.sql > saida.tab
Se vocˆe tiver problemas devido a mem´oria insuficiente no cliente, utilize a op¸ao --quick!
Isto for¸ca o mysql a utilizar mysql_use_result() no lugar de mysql_store_result() para
recuperar o conjunto de resultados.
Utilizar o mysql ´e muito f´aci. Inicie-o como mostrado a seguir: mysql banco_de_dados
ou mysql --user=nome_usu´ario --password=sua_senha banco_de_dados. Digite uma in-
stru¸ao SQL, termine-a com ‘;’, ‘\g’, ou ‘\G’ e pressione RETURN/ENTER.
Omysql Suporta as seguintes op¸oes:
-?, --help
Exibe esta ajuda e sai.
290 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
-A, --no-auto-rehash
Sem reprocessamento autom´atico. O ’rehash’ deve ser usado se o usu´ario desejar
que o cliente mysql complete as tabelas e campos. Esta op¸ao ´e usada para
acelerar a inicializa¸ao do cliente.
-B, --batch
Exibe resultados com o caractere de tabula¸ao como o separador, cada registro
em uma nova linha. ao utiliza o arquivo de hist´orico.
--character-sets-dir=...
Diret´orio onde os conjuntos de caracteres est˜ao localizados.
-C, --compress
Utiliza compacta¸ao no protocolo cliente/servidor.
-#, --debug[=...]
Log de Depura¸ao. O padr˜ao ´e ’d:t:o,/tmp/mysql.trace’.
-D, --database=...
Qual banco de dados usar. Isto geralmente ´e util em um arquivo my.cnf.
--default-character-set=...
Configura o conjunto de caracters padr˜ao.
-e, --execute=...
Executa o comando e sai. (Sa´
ida parecida com --batch)
-E, --vertical
Exibe a sa´
ida de uma consulta (linhas) verticalmente. Sem esta op¸ao vocˆe
tamb´em pode for¸car esta sa´
ida terminando suas instru¸oes com \G.
-f, --force
Continue mesmo se for obtido um erro SQL.
-g, --no-named-commands
Comandos nomeados ser˜ao desabilitados. Utilize somente a forma \*, ou use
comandos nomeados apenas no come¸co da linha terminada com um ponto-e-
v´
irgula (;). Desde a vers˜ao 10.9, o cliente agora inicia com esta op¸ao habilitada
por padr˜ao! Com a op¸ao -g, entretando, comandos de formato longo contin-
uar˜ao funcionando na primeira linha.
-G, --enable-named-commands
Comandos nomeados s˜ao habilitados. Comandos de formato longo s˜ao aceitos
assim como os comandos reduzidos \*.
-i, --ignore-space
Ignore caractere de espa¸co depois de nomes de fun¸oes.
-h, --host=...
Conectar `a m´aquina especificada.
-H, --html
Produza sa´
ida HTML.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 291
-L, --skip-line-numbers
ao escreva n´umero da linha para os erros. ´
Util quando se deseja comparar
arquivos com resultados que incluem mensagens de erro.
--no-pager
Desabilita pagina¸ao e impress˜ao na sa´
ida padr˜ao. Veja tamb´em a ajuda inter-
ativa (\h).
--no-tee Desabilita arquivo de sa´
ida. Veja tamb´em a ajuda interativa (\h).
-n, --unbuffered
Descarrega e atualiza o buffer depois de cada pesquisa.
-N, --skip-column-names
ao escrever nomes de colunas nos resultados.
-O, --set-variable var=option
Fornece um valor a uma vari´avel. --help lista as vari´aveis.
-o, --one-database
Atualiza somente o banco de dados padr˜ao. Isto ´e ´util para evitar atualiza¸ao
em outros bancos de dados no log de atualiza¸oes.
--pager[=...]
Tipo de sa´
ida. O padr˜ao ´e sua vari´avel de ambiente PAGER. Paginadores v´alidos
ao: less, more, cat [>nome arquivo], etc. Veja tamb´em a ajuda interativa (\h).
Esta op¸ao n˜ao funciona no modo batch. A op¸ao pager funciona somente no
UNIX.
-p[password], --password[=...]
Senha a ser usada ao conectar ao servidor. Se uma senha n˜ao ´e fornecida
na linha de comando, lhe ser´a solicitado uma. Perceba que se voe utilizar o
formato curto -p vocˆe n˜ao pode ter um espa¸co entre a op¸ao e a senha.
-P --port=...
N´umero da porta TCP/IP para usar na conex˜ao.
-q, --quick
ao faz cache do resultado, imprime linha a linha. Isto pode deixar o servidor
mais lento se a sa´
ida for suspendida. ao usa arquivo de hist´orico.
-r, --raw Exibe valores de colunas sem convers˜ao de escapes. Utilizado com --batch
-s, --silent
Op¸ao para ser mais silencioso.
-S --socket=...
Arquivo socket para ser utilizado na conex˜ao.
-t --table
Sa´
ida no formato de tabela. Isto ´e padr˜ao no modo n˜ao-batch.
-T, --debug-info
Exibe alguma informa¸ao de depura¸ao na sa´
ida.
292 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--tee=...
Anexa tudo no arquivo de sa´
ida. Veja tamb´em a ajuda interativa (\h). N˜ao
funciona no modo batch.
-u, --user=#
Usu´ario para login diferente do usu´ario atual do sistema.
-U, --safe-updates[=#], --i-am-a-dummy[=#]
Permite somente que UPDATE eDELETE utilizem chaves. Veja abaixo para
maiores informa¸oes sobre esta op¸ao. Voe pode zerar esta op¸ao se possui-la
no arquivo my.cnf utilizando --safe-updates=0.
-v, --verbose
Modo verbose (-v -v -v fornece o formato de sa´
ida da tabela).
-V, --version
Gera sa´
ida com informa¸ao de vers˜ao e sai.
-w, --wait
Espera e repete em vez de sair se a conex˜ao estiver inacess´
ivel.
Voe tamb´em pode configurar as seguntes vari´aveis com -O ou --set-variable:
Nome vari´avel Padr˜ao Descri¸ao
connect timeout 0 N´umero de seguntos antes de esgotar o
tempo da conex˜ao
max allowed packet 16777216 Tamanho m´aximo do pacote para en-
viar/receber do servidor
net buffer length 16384 Tamanho do buffer para comunica¸ao
TCP/IP e socket
select limit 1000 Limite autom´atico para SELECT quando
utilizar --i-am-a-dummy
max join size 1000000 Limite autom´atico para registros em uma
join quando utilizar --i-am-a-dummy.
Se vocˆe digitar ’help’ na linha de comando, mysql ir´a 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.
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.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 293
source (\.) Execute a SQL script file. Takes a file name as an argument.
status (\s) Get status information from the server.
tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
use (\u) Use another database. Takes database name as argument.
Das op¸oes acima, o pager ´e o ´unico que s´o funciona no UNIX.
O comando status lhe fornece algumas informa¸oes sobre a conex˜ao e o servidor que est´a
utilizando. Se voe estiver executando no modo --safe-updates,status ir´a tamb´em
imprimir os valores para as vari´aveis mysql que afetam suas consultas.
Uma op¸ao ´util para iniciantes (introduzido no MySQL vers˜ao 3.23.11) ´e o --safe-updates
(ou --i-am-a-dummy para usu´arios que alguma vez executaram um DELETE FROM nome_
tabela mas esqueceram da cl´ausula WHERE). Quando utilizar esta op¸ao, o mysql envia o
seguinte comando ao servidor MySQL quando abrir a conex˜ao.
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
SQL_MAX_JOIN_SIZE=#max_join_size#"
onde #select_limit# e#max_join size# ao vari´aveis que podem ser configuradas da
linha de comando mysql. See hundefinedi[SET OPTION], page hundefinedi.
O efeito da op¸ao acima ´e:
Voe n˜ao tem permiss˜ao de utilizar uma instru¸ao UPDATE ou DELETE se vocˆe n˜ao possuir
uma chave na parte WHERE. Pode-se, entretanto, for¸car um UPDATE/DELETE utilizando
LIMIT:
UPDATE nome_tabela SET campo_nao_chave=# WHERE campo_nao_chave=# LIMIT 1;
Todos resultados maiores s˜ao limitados automaticamente a #select_limit# linhas.
SELECT’s que provavelmente precisar˜ao examinar mais que #max_join_size
combina¸coes de linhas ser˜ao abortadas.
Algumas dicas ´uteis sobre o cliente mysql:
Alguns dados s˜ao muito mais leg´
iveis quando exibido verticalmente, em vez da sa´
ida do
tipo caixa horizontal comum. Por exemplo: Textos longos, que incluem v´arias linhas, s˜ao
muito mais f´aceis de serem lidos com sa´
ida 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.
294 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Regards,
Monty
file: inbox-jani-1
hash: 190402944
1 row in set (0.09 sec)
Para o log, vocˆe pode utilizar a op¸ao tee. O tee pode ser iniciado com a op¸ao --
tee=..., ou pela linha de comando de maneira interativa com o comando tee. Todos
os dados exibidos na tela ser˜ao anexados no arquivo fornecido. Isto tamem pode ser
muito ´util para prop´ositos de depura¸ao. O tee pode ser desabilitado da linha de
comando com o comando notee. Executando tee novamente o log ´e reiniciado. Sem
um parˆametro o arquivo anterior ser´a usado. Perceba que tee ir´a atualizar os resultados
dentro do arquivo depois de cada comando, pouco antes da linha de comando reaparecer
esperando pelo pr´oximo comando.
Navegar ou pesquisar os resultados no modo interativo em algum programa do UNIX
como o less, more ou outro similar, ´e agora poss´
ivel com a op¸ao --pager[=...]. Sem
argumento, o cliente mysql ir´a procurar pela vari´avel 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´a configurado com ele. O comando pager pode ser
chamado com um argumento, mas isto requer que a op¸ao --pager seja usada, ou o
pager ser´a usado com a sa´
ida padr˜ao. pager funciona somente no UNIX, uma vez
que ´e utilizado a fun¸ao popen(), que n˜ao existe no Windows. No Windows a op¸ao
tee pode ser utilizada, entretanto ela pode n˜ao ser cˆomoda como pager pode ser em
algumas situa¸oes.
Poucas dicas sobre pager: Voe pode us´a-lo para gravar em um arquivo:
mysql> pager cat > /tmp/log.txt
e os resultados ir˜ao somente para um arquivo. Voe tamb´em pode passar qualquer
op¸oes para os programas que vocˆe deseja utilizar com pager:
mysql> pager less -n -i -S
Note a op¸ao ’-S’ exibida acima. Voe pode ach´a-la muito ´util quando navegar pelos
resultados; experimente com a op¸ao com sa´
ida a horizontal (finalize os comandos com
\g’, ou ’;’) e com sa´
ida vertical (final dos comandos com ’\G’). Algumas vezes um
resultado com um conjunto muito largo ´e dif´
icil ser lido na tela, com a op¸ao -S para
less, vocˆe pode navegar nos resultados com o less interativo da esquerda para a direita,
evitando que linhas maiores que sua tela continuem na pr´oxima linha. Isto pode tornar
o conjunto do resultado muito mais leg´
ivel. vocˆe pode alterar o modo entre ligado e
desligado com o less interativo com ’-S’. Veja o ’h’(help) para mais ajuda sobre o less.
Por ´ultimo (a menos que vocˆe j´a entendeu este assunto com os exemplos acima ;) vocˆe
pode combinar maneiras muito complexas para lidar com os resultados, por exemplo,
o seguinte enviaria os resultados para dois arquivos em dois diferentes diret´orios, 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
Chapter 4: Administra¸ao de Bancos de Dados MySQL 295
Voe tamb´em pode combinar as duas fun¸oes acima; tenha o tee habilitado, o pager
configurado para ’less’ e vocˆe estar´a apto a navegar nos resultados no less do unix e
ainda ter tudo anexado em um arquivo ao mesmo tempo. A diferen¸ca entre UNIX tee
usado com o pager e o tee embutido no cliente mysql ´e que o tee embutido funciona
mesmo se vocˆe n˜ao tiver o comando UNIX tee dispon´
ivel. O tee embutido tamb´em loga
tudo que ´e exibido na tela, e o UNIX tee usado com pager ao loga completamente.
Por ´ultimo o tee interativo ´e mais cˆomodo para trocar entre os modos on e off, quando
vocˆe desejar logar alguma coisa em um arquivo, mas deseja estar apto para desligar o
recurso quando necess´ario.
4.8.3 mysqladmin, Administrando um Servidor MySQL
Um utilit´ario para realizar opera¸oes administrativas. A sintaxe ´e:
shell> mysqladmin [OP~
OES] comando [op¸c~ao_do_comando] comando...
Voe pode obter uma lista das op¸ao que sua vers˜ao do mysqladmin suporta executando
mysqladmin --help.
Omysqladmin 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´aquinas que estiverem no cache.
flush-logs
Atualiza todos os logs.
flush-tables
Atualiza todas as tabelas.
flush-privileges
Recarrega tabelas de permiss˜oes (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´a ativo.
processlist
Exibe lista de threads ativas no servidor.
reload Recarrega tabelas de permiss˜ao.
refresh Atualiza todas as tabelas e fecha e abre arquivos de log.
shutdown Desliga o servidor.
296 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
slave-start
Inicia thread de replica¸ao no slave.
slave-stop
Termina a thread de replica¸ao no slave.
status Fornece uma mensagem curta sobre o estado do servidor.
variables
Exibe vari´aveis dispon´
iveis.
version Obtˆem informa¸ao de vers˜ao do servidor.
Todos comandos podem ser reduzidos para seu prefixo ´unico. 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:
Uptime N´umero de segundos que o servidor MySQL est´a funcionando.
Threads N´umero de threads ativas (clientes).
Questions N´umero de solicita¸oes dos clientes desde que o mysqld foi
iniciado.
Slow queries Consultas que demoram mais que long_query_time segun-
dos. See hundefinedi[Log de consultas lentas], page hunde-
finedi.
Opens Quantas tabelas foram abertas pelo mysqld.
Flush tables N´umero de comandos flush...,refresh ereload.
Open tables N´umero de tabelas abertas atualmente.
Memory in use Mem´oria alocada diretamente pelo c´odigo do mysqld
(dispon´
ivel somente quando o MySQL ´e compilado com --
with-debug=full).
Max memory used Mem´oria m´axima alocada diretamente pelo c´odigo do mysqld
(dispon´
ivel somente quando o MySQL ´e compilado com --
with-debug=full).
Se vocˆe executa um mysqladmin shutdown em um socket (em outras palavras, em um
computador onde o mysqld est´a executando), mysqladmin ir´a esperar at´e que o arquivo-
pid do MySQL seja removido para garantir que o servidor mysqld parou corretamente.
4.8.4 Usando mysqlcheck para Manuten¸ao de Tabelas e
Recupera¸ao em Caso de Falhas
Desde o MySQL vers˜ao 3.23.38 vocˆe estar´a apto a usar a nova ferramenta de reparos e
verifica¸ao de tabelas MyISAM. A diferen¸ca para o myisamchk ´e que o mysqlcheck deve ser
usado quando o servidor mysqld estiver em funcionamento, enquanto o myisamchk deve ser
usado quando ele n˜ao estiver. O benef´
icio ´e que vocˆe n˜ao precisar´a mais desligar o servidor
mysqld para verificar ou reparar suas tabelas.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 297
Omysqlcheck utiliza os comandos do servidor MySQL CHECK,REPAIR,ANALYZE eOPTIMIZE
de um modo conveniente para o usu´ario.
Existem trˆes modos alternativos de chamar o mysqlcheck:
shell> mysqlcheck [OP~
OES] database [tabelas]
shell> mysqlcheck [OP~
OES] --databases DB1 [DB2 DB3...]
shell> mysqlcheck [OP~
OES] --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.
Omysqlcheck tem um recurso especial comparado comparado aos outros clientes; o com-
portamento padr˜ao, verificando as tabelas (-c), pode ser alterado renomeando o bin´ario. Se
vocˆe deseja ter uma ferramenta que repare as tabelas como o procedimento padr˜ao, vocˆe
deve copiar o mysqlcheck para o disco com um outro nome, mysqlrepair, ou crie um link
simolico com o nome mysqlrepair. Se vocˆe chamar mysqlrepair agora, ele ir´a reparar
as tabelas como seu procedimento padr˜ao.
Os nomes que podem ser utilizados para alterar o comportamento padr˜ao do mysqlcheck
ao:
mysqlrepair: A op¸c~ao padr~ao ser´a -r
mysqlanalyze: A op¸c~ao padr~ao ser´a -a
mysqloptimize: A op¸c~ao padr~ao ser´a -o
As op¸oes dispon´
iveis para o mysqlcheck est˜ao listadas aqui, por favor verifique o que a
sua vers˜ao suporta com o mysqlcheck --help.
-A, --all-databases
Verifica todos os bancos de dados. Isto ´e 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˜ao em uma
lista separada por v´
irgula.
-a, --analyze
Analise as tabelas fornecidas.
--auto-repair
Se uma tabela checada est´a corrompida, ela ´e corrigida automaticamente. O
reparo ser´a feito depois que todas as tabelas tiverem sido checadas e forem
detectadas tabelas corrompidas.
-#, --debug=...
Log de sa´
ida de depura¸ao. Normalmente ´e ’d:t:o,filename’
--character-sets-dir=...
Diret´orio onde est˜ao os conjuntos de caracteres.
-c, --check
Verifca erros em tabelas
-C, --check-only-changed
Verifica somente tabelas que foram alteradas desde a ´ultima conferˆencia ou que
ao foram fechada corretamente.
298 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--compress
Utilize compress˜ao no protocolo server/cliente.
-?, --help
Exibe esta mensagem de ajuda e sai.
-B, --databases
Para verificar diversos bancos de dados. Perceba a diferen¸ca no uso; Neste caso
nenhuma tabela ser´a fornecida. Todos os argumentos s˜ao tratados como nomes
de bancos de dados.
--default-character-set=...
Configura o conjunto de caracteres padr˜ao.
-F, --fast
Verifica somente as tabelas que n˜ao foram fechadas corretamente
-f, --force
Continue mesmo se n´os obtermos um erro de sql.
-e, --extended
Se vocˆe estiver utilizando esta op¸ao com CHECK TABLE, ir´a garantir que a
tabela est´a 100 por cento consistente, mas leva bastante tempo.
Se vocˆe utilizar esta op¸ao com REPAIR TABLE, ele ir´a executar um comando
de reparos na tabela, que n˜ao s´o ir´a demorar muito tempo para executar, mas
tamb´em pode produzir muitas linhas de lixo.
-h, --host=...
Conecta `a m´aquina.
-m, --medium-check
Mais r´apido que verifica¸ao 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˜ao for fornecida ser´a
solicitada no terminal.
-P, --port=...
N´umero de porta para usar para conex˜ao.
-q, --quick
Se esta op¸ao for utilizada com CHECK TABLE, evita a busca de registros
verificando links errados. Esta ´e a conferˆencia mais r´apida.
Se vocˆe estiver utilizando esta op¸ao com REPAIR TABLE, ela tentar´a reparar
somente a ´arvore de ´
indices. Este ´e o m´etodo de reparo mais r´apido para uma
tabela.
-r, --repair
Pode corrigir quase tudo exceto chaves ´unicas que n˜ao s˜ao ´unicas.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 299
-s, --silent
Exibe somente mensagens de erro.
-S, --socket=...
Arquivo socket para usar na conex˜ao.
--tables Sobrep˜oe a op¸ao --databases (-B).
-u, --user=#
Usu´ario para o login, se n˜ao for o usu´ario atual.
-v, --verbose
Exibe informa¸ao sobre os v´arios est´agios.
-V, --version
Exibe informa¸ao sobre a vers˜ao e sai.
4.8.5 mysqldump, Descarregando estrutura de tabelas e dados
Utilit´ario para descarregar um banco de dados ou uma cole¸ao de bancos de dados para
backup ou transferencia para outro servidor SQL (N˜ao necessariamente um servidor
MySQL). A descarga ir´a conter instru¸oes SQL para cria a tabela e/ou popular a tabela.
Se a id´eia ´e backup do servidor, deve ser considerada a utiliza¸ao do mysqlhotcopy. See
hundefinedi[mysqlhotcopy], page hundefinedi.
shell> mysqldump [OP~
OES] banco_de_dados [tabelas]
OR mysqldump [OP~
OES] --databases [OP~
OES] BD1 [BD2 BD3...]
OR mysqldump [OP~
OES] --all-databases [OP~
OES]
Se vocˆe n˜ao fornecer nenhuma tabela ou utilizar o --databases ou --all-databases,
todo(s) o(s) banco(s) de dados ser´a(˜ao) descarregado(s).
Voe pode obter uma lista das op¸oes que sua vers˜ao do mysqldump suporta executando
mysqldump --help.
Perceba que se vocˆe executar o mysqldump sem a op¸ao --quick ou --opt, o mysqldump ir´a
carregar todo o conjunto do resultado na mem´oria antes de descarregar o resultado. Isto
provavelmente ser´a um problema se vocˆe est´a descarregando um banco de dados grande.
Note que se vocˆe estiver utilizando uma c´opia nova do programa mysqldump e se vocˆe for
fazer uma descarga que ser´a lida em um servidor MySQL muito antigo, voe n˜ao deve
utilizar as op¸oes --opt ou -e.
mysqldump suporta as seguintes op¸oes:
--add-locks
Adicione LOCK TABLES antes de UNLOCK TABLE depois de cada descarga de
tabelas. (Para obter inser¸oes mais r´apidas no MySQL.)
--add-drop-table
Adicione um drop table antes de cada instru¸ao create.
-A, --all-databases
Descarrega todos os bancos de dados. Isto ir´a ser o mesmo que --databases
com todos os bancos de dados selecionados.
-a, --all Inclui todas as op¸oes do create espec´
ificas do MySQL.
300 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--allow-keywords
Permite cria¸ao de nomes que colunas que s˜ao palavras chaves. Isto funciona
utilizando o nome da tabela como prefixo em cada nome de coluna.
-c, --complete-insert
Utilize instru¸oes de insert completas (com nomes de colunas).
-C, --compress
Compacta todas as informa¸oes entre o cliente e o servidor se ambos suportarem
a compacta¸ao.
-B, --databases
Para descarregar diversos bancos de dados. Perceba a diferen¸ca no uso. Neste
caso nenhuma tabela ´e fornecida. Todos argumentos s˜ao estimados como nomes
de bancos de dados. USE nome_bd; ser´a inclu´
ido na sa´
ida 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¸oes de inser¸ao mais
compactas e mais r´apidas.)
-#, --debug[=option_string]
Rastreia a utiliza¸ao do programa (para depura¸ao).
--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¸oes s˜ao usadas com a op¸ao -T e tem o mesmo significado que as
cl´ausulas correspondentes em LOAD DATA INFILE See hundefinedi[LOAD DATA],
page hundefinedi.
-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´aquina especificada. A m´aquina
padr˜ao ´e localhost.
-l, --lock-tables.
Bloqueia todas as tabelas antes de iniciar a descarga. As tabelas s˜ao bloqueadas
com READ LOCAL para permitir inser¸oes concorrentes no caso de tabelas MyISAM.
-n, --no-create-db
’CREATE DATABASE /*!32312 IF NOT EXISTS*/ nome bd;’ n˜ao ser´a colo-
cado na sa´
ida. A linha acima ser´a adicionada se a op¸ao --databases ou --all-
databases for fornecida.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 301
-t, --no-create-info
ao grava informa¸oes de cria¸ao de tabelas (A instru¸ao CREATE TABLE.)
-d, --no-data
ao grava nenhuma informa¸ao de registros para a tabela. Isto ´e muito ´util se
vocˆe 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´apida para leitura em um servidor
MySQL.
-pyour_pass, --password[=sua_senha]
A senha para usar quando conectando ao servidor. Se n˜ao for especificado a
parte ‘=sua_senha’, o mysqldump ir´a perguntar por uma senha.
-P port_num, --port=porta_num
O n´umero da porta TCP/IP usado para conectar a uma m´aquina. (Isto ´e usado
para conex˜oes a m´aquinas diferentes de localhost, na qual sockets Unix s˜ao
utilizados.)
-q, --quick
ao utiliza buffers para as consultas, descarrega diretamente para sa´
ida padr˜ao.
Utilize mysql_use_result() para fazer isto.
-r, --result-file=...
Direcione a sa´
ida para um determinado arquivo. Esta op¸ao deve ser usada no
MSDOS porque previne a convers˜ao de nova linha ’\n’ para ’\n\r’ (nova linha
+retorno de carro).
-S /path/to/socket, --socket=/caminho/para/arquivo_socket
O arquivo socket que ser´a utilizado quando conectar `a localhost (que ´e a
aquina padr˜ao).
--tables Sobrep˜oe a op¸ao --databases (-B).
-T, --tab=path-to-some-directory
Cria um arquivo nome_tabela.sql, que cont´em os comandos SQL CREATE
e um arquivo nome_tabela.txt, que cont´em os dados, para cada tabela dada.
NOTA: Isto s´o funcionar´a se mysqldump for executado na mesma m´aquina do
daemon mysqld. O formato do arquivo .txt ´e feito de acordo com as op¸oes
--fields-xxx e--lines--xxx.
-u user_name, --user=user_name
O nome do usu´ario do MySQL para usar ao conectar ao servidor. O valor
padr˜ao ´e seu nome de usu´ario no Unix.
-O var=option, --set-variable var=option
Confirgura o valor de uma vari´avel. As vari´aveis poss´
iveis s˜ao listadas abaixo.
-v, --verbose
Modo verbose. Exibe mais informa¸oes sobre o que o programa realiza.
-V, --version
Exibe informa¸oes de vers˜ao e sai.
302 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
-w, --where=’where-condition’
Descarrega somente registros selecionados. Perceba que as aspas s˜ao obri-
gat´orias:
"--where=user=’jimf’" "-wuserid>1" "-wuserid<1"
-O net_buffer_length=#, where # < 16M
Quando estiver criando instru¸oes de inser¸oes em m´ultiplas linhas (com a op¸ao
--extended-insert ou --opt), mysqldump ir´a criar linhas at´e o tamanho de
net_buffer_length. Se vocˆe aumentar esta vari´avel, vocˆe tamb´em deve se
assegurar que a vari´avel max_allowed_packet no servidor MySQL ´e maior que
anet_buffer_length.
O uso mais comum do mysqldump ´e provavelmente para fazer backups de bancos de dados
inteiros. See hundefinedi[Backup], page hundefinedi.
mysqldump --opt banco_dados > arquivo-backup.sql
Voe pode ler de volta no MySQL com:
mysql banco_dados < arquivo-backup.sql
ou
mysql -e "source /patch-to-backup/backup-file.sql" banco_de_dados
Entretanto, ´e muito ´util tamb´em popular outro servidor MySQL com informa¸oes de um
banco de dados:
mysqldump --opt banco_dados | mysql ---host=m´aquina-remota -C banco_dados
´
E poss´
ivel descarregar v´arios 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.8.6 mysqlhotcopy, Copiando Bancos de Dados e Tabelas MySQL
Omysqlhotcopy ´e um script perl que utiliza LOCK TABLES,FLUSH TABLES ecp ou scp para
fazer um backup r´apido de um banco de dados. ´
E a maneira mais r´apida para fazer um
backup do banco de dados e de algumas tabelas mas ele s´o pode ser executado na mesma
aquina onde os diret´orios dos bancos de dados est˜ao.
mysqlhotcopy nome_bd [/caminho/para/novo_diret´orio]
mysqlhotcopy nome_bd_2 ... nome_bd_2 /caminho/para/novo_diret´orio
mysqlhotcopy nome_bd./regex/
mysqlhotcopy suporta as seguintes op¸oes:
-?, --help
Exibe uma tela de ajuda e sai
-u, --user=#
Usu´ario para fazer login no banco de dados
Chapter 4: Administra¸ao de Bancos de Dados MySQL 303
-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
ao aborta se o alvo j´a existir (renomeie-o para old)
--keepold
ao apaga alvos anteriores (agora renomeados) quando pronto
--noindices
ao inclui arquivos de ´
indices na c´opia para deixar o backup menor e mais
apido. Os ´
indices podem ser recostru´
idos mais tarde com myisamchk -rq..
--method=#
Met´odo para copiar (cp ou scp).
-q, --quiet
Seja silencioso exceto em erros
--debug Habilita depura¸ao
-n, --dryrun
Relata a¸oes sem realiz´a-las
--regexp=#
Copia todos bancos de dados com nomes que coincidem com a express˜ao 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´orio Tempor´ario (em vez de /tmp).
Voe pode utilizar perldoc mysqlhotcopy para obter uma documenta¸ao mais completa
de mysqlhotcopy.
mysqlhotcopy lˆe os grupos [client] e[mysqlhotcopy] dos arquivos de op¸oes.
Para poder executar mysqlhotcopy ´e necess´ario acesso de escrita ao diret´orio de backup,
privil´egio SELECT nas tabelas que desejar copiar e o privil´egio Reload no MySQL (para
poder executar FLUSH TABLES).
304 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.8.7 mysqlimport, Importando Dados de Arquivos Texto
mysqlimport fornece uma interface de linha de comando para a instru¸ao SQL LOAD DATA
INFILE. A maioria das op¸oes aceitas correspondem diretamente `as op¸oes de LOAD DATA
INFILE. See hundefinedi[LOAD DATA], page hundefinedi.
mysqlimport ´e chamado desta maneira:
shell> mysqlimport [op¸c~oes] banco_de_dados arquivo_texto1 [arquivo_texto2....]
Para cada arquivo texto passadoo na linha de comando, mysqlimport remove qualquer ex-
tens˜ao do nome do arquivo e utiliza o resultado para determinar para qual tabela os dados do
arquivo ser˜ao importados. Por exemplo, arquivos chamados ‘patient.txt’, ‘patient.text
e ‘patient’ ser˜ao importados para uma tabela chamada patient.
mysqlimport suporta as seguintes op¸oes:
-c, --columns=...
Esta op¸ao recebe uma lista de nomes de campos separados por v´
irgula como
um argumento. A lista de campos ´e utilizada para criar um comando LOAD
DATA INFILE adequado que ´e ent˜ao passado ao MySQL. See hundefinedi[LOAD
DATA], page hundefinedi.
-C, --compress
Compacta todas as informa¸oes entre o cliente e o servidor se ambos suportarem
compress˜ao.
-#, --debug[=option_string]
Rastreia o programa (para depura¸ao).
-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¸oes tem o mesmo significado que as cl´ausulas correspondentes para
LOAD DATA INFILE. See hundefinedi[LOAD DATA], page hundefinedi.
-f, --force
Ignorar erros. Por exemplo, se uma tabela para um arquivo texto n˜ao existir,
continue processando quaisquer arquivos restantes. Sem --force,mysqlimport
sai se uma tabela n˜ao existir.
--help Exibe uma mensagem de ajuda e sai.
-h host_name, --host=host_name
Importa dados para o servidor MySQL na m´aquina referida. A m´aquina padr˜ao
´e localhost.
-i, --ignore
Veja a descri¸ao para a op¸ao --replace.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 305
-l, --lock-tables
Bloqueia TODAS as tabelas para escrita antes de processar qualquer arquivo
texto. Isto garante que todas as tabelas s˜ao sincronizadas no servidor.
-L, --local
Lˆe arquivos de entrada do cliente. Por padr˜ao, ´e assumido que os arquivos texto
est˜ao no servidor se vocˆe conectar `a localhost (m´aquina padr˜ao).
-pyour_pass, --password[=sua_senha]
Senha para conectar ao servidor. Se vocˆe n˜ao especificar a parte ‘=sua_senha’,
omysqlimport ir´a pedir por uma senha.
-P port_num, --port=port_num
O n´umero da porta TCP/IP para usar quando conectar a uma m´aquina. (isto
´e usado para conex˜oes a m´aquinas diferentes de localhost, onde s˜ao utilizados
sockets Unix).
-r, --replace
As op¸oes --replace e--ignore controlam o tratamento de registros de en-
trada que duplicam registros existentes em valores de chaves ´unicas. Se vocˆe es-
pecificar --replace, novos registros substituir˜ao registros que tiverem o mesmo
valor na chave unica. Se vocˆe especificar --ignore, registros de entrada que
duplicariam um registro existente em um valor de chave ´unica s˜ao saltados. Se
vocˆe n˜ao especificar nenhuma das duas op¸oes, um erro ocorrer´a quando um
valor de chave duplicado for encontrado e o resto do arquivo texto ser´a ignorado.
-s, --silent
Modo silencioso. Gera sa´
ida somente quando ocorrer algum erro.
-S /path/to/socket, --socket=/path/to/socket
O arquivo socket para usar ao conectar `a localhost (m´aquina padr˜ao).
-u user_name, --user=user_name
O nome de usu´ario MySQL para usar ao conectar ao servidor. O valor padr˜ao
´e seu nome de usu´ario atual no Unix.
-v, --verbose
Modo verbose. Gera mais informa¸oes na sa´
ida.
-V, --version
Exibe informa¸ao sobre a vers˜ao e sai.
Abaixo um exemblo da utiliza¸ao 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
.
306 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
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.8.8 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ˆe pode obter as mesmas informa¸oes com comandos SHOW. See
hundefinedi[SHOW], page hundefinedi.
mysqlshow ´e chamado assim:
shell> mysqlshow [OP~
OES] [banco_dados [tabela [coluna]]]
Se nenhum banco de dados ´e fornecido, todos os bancos de dados encontrados s˜ao
exibidos.
Se nenhuma tabela ´e fornecida, todas as tabelas encontradas no banco de dados s˜ao
exibidas.
Se nenhuma coluna for fornecida, todas colunas e tipos de colunas encontrados na
tabela s˜ao exibidos.
Note que em vers˜oes mais novas do MySQL, vocˆe s´o visualiza as tabelas/bancos de da-
dos/colunas para quais vocˆe tem algum privil´egio.
Se o ´ultimo argumento conter uma shell ou um meta-caracter do SQL, (*,?,%ou _)
somente o que coincidir com o meta-caracter ´e exibido. Isto pode causar alguma confus˜ao
quando algu´em tentar exibir as colunas para uma tabela com um _, neste caso o mysqlshow
exibe somente os nomes de tabelas que casarem com o padr˜ao. Isto ´e facilmente corrigido
adicionando um %extra na linha de comando (como um argumento separador).
4.8.9 perror, Explicando C´odigos de Erros
perror pode ser usado para exibir mensagen(s) de erro. perror pode ser chamado desta
forma:
shell> perror [OP~
OES] [C´
ODIGO_ERRO [C´
ODIGO_ERRO...]]
Por exemplo:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 307
shell> perror 64 79
Error code 64: Machine is not on the network
Error code 79: Can not access a needed shared library
perror pode ser usado para exibir uma descri¸ao de um c´odigo de erro do sistema, ou um
odigo de erro do manipulador de tabelas MyISAM/ISAM. As mensagens de erro s˜ao na
maioria dependentes do sistema.
4.8.10 Como Executar Comandos SQL a Partir de um Arquivo
Texto
O cliente mysql normalmente ´e usado de maneira interativa, desta forma:
shell> mysql banco_dados
Entretanto, tamb´em ´e poss´
ivel 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ˆe deseja executar. Enao execute o mysql como
exibido abaixo:
shell> mysql banco_dados < arquivo_texto
Voe tamb´em pode iniciar seu arquivo texto com uma instru¸ao USER nome_bd. Neste caso,
ao ´e necess´ario especificar o nome do banco de dados na linha de comando:
shell> mysql < arquivo_texto
See Side Scripts-snt [Scripts do Lado do Cliente], page Side Scripts-pg.
4.9 Os Arquivos Log do MySQL
O MySQL tem v´arios arquivos de log diferentes que podem ajud´a-lo a descobrir o que est´a
acontecendo dentro do mysqld:
O log de erros Problemas encontrados iniciando, executando ou parando o
mysqld.
O log isam Documenta todas altera¸oes a tabelas ISAM. Usado somente
para depura¸ao do c´odigo isam.
O log de consultas Conex˜oes estabelecidas e consultas executadas.
O log de atualiza¸oes Desatulizado: Armazena todas as instru¸oes que alteram
dados.
O log bin´ario Armazena todas as instru¸oes que alteram qualquer coisa. Us-
ada tamb´em para replica¸ao.
O log para consultas lentas Armazena todas queries que levaram mais de long_query_
time para executar ou que n˜ao usaram ´
indices.
Todos logs podem ser encontrados no diret´orio de dados do mysqld. Vocˆe pode for¸car o
mysqld a reabrir os arquivos de log (ou em alguns casos trocar para um novo log) executando
FLUSH LOGS. See hundefinedi[FLUSH], page hundefinedi.
4.9.1 O Log de Erros
mysqld escreve todos erros para stderr, que o script safe_mysqld redireciona para um
arquivo chamado ’nome_m´aquina’.err. (No Windows, o mysqld o escreve diretamente em
\mysql\data\mysql.err’).
308 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Ele cont´em informa¸oes indicando quando o mysqld foi iniciado e parado e tamb´em os
erros cr´
iticos encontrados durante a execu¸ao. Se o mysqld finalizar inexperadamente e o
safe_mysqld precisar reiniciar o mysqld, o safe_mysqld ir´a escrever uma linha restarted
mysqld neste arquivo. Este log tamb´em armazena alertas de tabelas que necessitam ser
verificadas automaticamente ou reparadas.
Em alguns sistemas operacionais, o log de erro ir´a conter registros de pilha de onde o mysqld
finalizou. Isto pode ser usado para saber onde e como o mysqld morreu. See hundefinedi
[Utilizando registros de pilha], page hundefinedi.
4.9.2 O Log de Erros Gen´ericos
Se vocˆe deseja saber o que acontece com mysqld, vocˆe deve inici´a-lo com a op¸ao --
log[=arquivo]. Isto ir´a documentar todas conex˜oes e consultas no arquivo log (por padr˜ao
nomeado ‘’nome_m´aquina’.log’). Este log pode ser muito ´util quando vocˆe suspeitar de
um erro em um cliente e deseja saber exatamente o que o mysqld acha que o cliente enviou.
Por padr˜ao, o script mysql.server inicia o servidor MySQL com a op¸ao -l. Se vocˆe
precisar melhorar a performance quando iniciar o uso do MySQL em um ambiente de
produ¸ao, pode remover a op¸ao -l do mysql.server ou alter´a-lo para --log-bin.
As entradas neste log s˜ao escritas quando o mysqld recebe as quest˜oes. Pode estar difer-
ente da ordem em que as instru¸oes s˜ao executadas. Isto est´a em contraste com o log de
atualiza¸oes e o log bin´ario nos quais as consultas s˜ao escritas depois de serem executadas,
mas que quaisquer travas sejam liberadas.
4.9.3 O Log de Atualiza¸oes
NOTA: O log de atualiza¸oes foi substitu´
ido pelo log bin´ario. See hundefinedi[Log bin´ario],
page hundefinedi. Com ele vocˆe pode fazer qualquer coisa que poderia ser feito com o log
de atualiza¸oes.
Quando iniciado com a op¸ao --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´aquina ´e usado. Se um nome de arquivo for fornecido, mas n˜ao possuir o
caminho, o arquivo ´e gravado no diret´orio de dados. Se ‘nome_arquivo’ n˜ao possuir uma
extens˜ao, o mysqld ir´a criar os arquivos com os nomes desta forma: nome_arquivo.###’,
onde ### ´e um n´umero que ´e incrementado cada vez que mysqladmin refresh ,mysqladmin
flush-logs ou a instru¸ao FLUSH LOGS forem executados ou o servidor for reiniciado.
NOTA: Para o esquema acima funcionar, vocˆe n˜ao pode criar seus pr´oprios arquivos com
o mesmo nome que os do log de atualiza¸ao +algumas extens˜oes que podem ser tratadas
como n´umeros, no diret´orio usado pelo log de atualiza¸ao!
Se forem utilizadas as op¸oes --log ou -l, o mysqld escreve um log geral com o nome de
arquivo ‘nome_m´aquina.log’, e o reinicio e a recarga n˜ao geram um novo arquivo de log
(embora ele seja fechado e reaberto). Neste caso vocˆe pode copi´a-lo (no Unix) usando:
mv nome_m´aquina.log nome_m´aquina-antigo.log
mysqladmin flush-logs
cp nome_m´aquina-antigo.log para-diret´orio-backup
rm nome_m´aquina-antigo.log
Chapter 4: Administra¸ao de Bancos de Dados MySQL 309
O log de atualiza¸ao ´e inteligente pois registra somente instru¸oes que realmente alteram
dados. Portanto, um UPDATE ou um DELETE com uma cl´ausula WHERE que n˜ao encontre
nenhum registro n˜ao ´e escrito no log. Ele salta at´e instru¸oes UPDATE que atribui a uma
coluna o mesmo valor que ela possuia.
O registro da atualiza¸ao ´e feito imediatamente ap´os 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¸ao.
Se vocˆe desejar atualizar um banco de dados a partir de arquivos de logs de atualiza¸ao,
vocˆe pode fazer o seguinte (assumindo que seus logs de atualiza¸ao estejam nomeados na
forma ‘nome_arquivo.###’):
shell> ls -1 -t -r nome_arquivo.[0-9]* | xargs cat | mysql
ls ´e utilizado para obter todos os arquivos de log na ordem correta.
Isto pode ser ´util se vocˆe tiver que recorrer a arquivos de backup depois de uma falha e
desejar refazer as atualiza¸oes que ocorreram entre a hora do backup e a falha.
4.9.4 O Log Bin´ario de Atualiza¸oes
A inten¸ao ´e que o log bin´ario deve substituir o log de atualiza¸oes, portanto n´os recomen-
damos que vocˆe troque para este formato de log o mais r´apido poss´
ivel!
O log bin´ario cont´em toda informa¸ao que ´e dispon´
ivel no log de atualiza¸ao em um formato
mais eficiente. Ele tamb´em cont´em informa¸oes sobre quanto tempo as consultas levaram
para atualizar o banco de dados.
O log bin´ario ´e tamb´em usado para replicar um mysqld escravo a partir de um mestre. See
hundefinedi[Replica¸ao], page hundefinedi.
Quando iniciado com a op¸ao --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´aquina seguido de -bin. Se for fornecido o nome do arquivo,
mas ele n˜ao tiver o caminho, o arquivo ´e escrito no diret´orio de dados.
Se vocˆe fornecer uma extens˜ao `a --log-bin=nome_arquivo.extens~ao, a extens˜ao ser´a
removida sem aviso.
Omysqld ir´a acrescentar uma extens˜ao ao nome de arquivo do log bin´ario que ´e um n´umero
que ´e incrementado cada vez que mysqladmin refresh,mysqladmin flush-logs, a in-
stru¸ao FLUSH LOGS forem executados ou o servidor for reiniciado.
Voe pode utilizar as seguintes op¸oes ao mysqld para afetar o que ´e documentado pelo log
bin´ario:
binlog-do-db=nome_banco_dados Diz ao servidor para registrar atualiza¸oes para o
banco de dados especificado e excluir todos os out-
ros n˜ao mencionados explicitamente. (Exemplo:
binlog-do-db=algum_banco_dados)
binlog-ignore-db=nome_banco_
dados
Diz ao master que atualiza¸oes a um determi-
nado banco de dados n˜ao devem ser registradas no
log bin´ario (Exemplo: binlog-ignore-db=algum_
banco_dados)
310 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Para saber quais arquivos bin´arios foram usados, o mysqld ir´a criar tamb´em um arquivo
de ´
indice para o log bin´ario que cont´em o nome de todos os arquivos de log bin´ario usados.
Por padr˜ao este arquivo tem o mesmo nome que o arquivo de log bin´ario, com a extens˜ao
’.index’. Voe pode alterar o nome do arquivo de ´
indice do log bin´ario com a op¸ao
--log-bin-index=[nome_arquivo].
Se estiver sendo usado replica¸ao, os arquivos de log bin´ario antigos n˜ao devem ser apagados
at´e ter certeza que nenhum escravo ir´a mais precisar deles. Uma forma de fazer isto ´e o
utilizar mysqladmin flush-logs uma vez por dia e ent˜ao remover qualquer log com mais
de 3 dias.
Voe pode examinar o arquivo de log bin´ario com o comando mysqlbinlog. Por exemplo,
vocˆe pode atualizar um servidor MySQL a partir de um log bin´ario como mostrado a seguir:
mysqlbinlog arquivo-log | mysql -h nome_servidor
Voe tamb´em pode utilizar o programa mysqlbinlog para ler o log bin´ario diretamente de
um servidor MySQL remoto !
mysqlbinlog --help ir´a lhe fornecer mais informa¸oes de como usar este programa!
Se vocˆe estiver utilizando BEGIN [WORK] ou SET AUTOCOMMIT=0, vocˆe deve utilizar o log
bin´ario do MySQL para backups no lugar do antigo log de atualiza¸ao.
O Log bin´ario ´e 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¸ao.
Todas atualiza¸oes (UPDATE,DELETE ou INSERT) que alteram uma tabela transacional (como
tabelas BDB) s˜ao armazenadas no cache at´e um COMMIT. Quaisquer atualiza¸oes a uma
tabela n˜ao transacional s˜ao armazenadas no log bin´ario de uma vez. Todas as threads
ir˜ao, no in´
icio, alocar um buffer de binlog_cache_size para registrar consultas. Se uma
conaulta ´e maior que o registro, a thread ir´a criar um arquivo tempor´ario para lidar com a
mesma. O arquivo tempor´ario ser´a apagado quando a thread terminar.
Omax_binlog_cache_size pode ser usado para restringir o tamanho total usado para
armazenar uma consulta multi-transacional.
Se vocˆe estiver utilizando o log de atualiza¸ao ou o bin´ario, inser¸oes concorrentes n˜ao
funcionar˜ao juntas com CREATE ... INSERT eINSERT ... SELECT. Isto ´e para garantir que
vocˆe possa recriar uma c´opia exata de suas tabelas aplicando o log em um backup.
4.9.5 O Log para Consultas Lentas
Quando iniciado com a op¸ao --log-slow-queries[=file_name] omysqld escreve em um
arquivo log contendo todos os comandos SQL que levam mais de long_query_time para
executar. O tempo para obter os bloqueios de tabelas iniciais n˜ao s˜ao contados como tempo
de execu¸ao.
O log de consultas lentas ´e gerado depois que uma query ´e executada e depois de todas as
bloqueios serem liberados. Ela pode estar em ordem diferente da que as instru¸oes foram
executadas.
Se nenhum nome de arquivo for fornecido, o padr˜ao ´e o nome da m´aquina com o sufixo
-slow.log. Se um nome de arquivo for especificado, mas n˜ao conter o caminho, o arquivo
´e gravado no diret´orio de dados.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 311
O log para queries lentas pode ser usado para encontrar queries que levam muito tempo
para executar e que devem ser candidatas a otimiza¸ao. Com um log muito grande, isto
pode ser uma tarefa dif´
icil. Voe pode utilizar o log de consultas lentas atraes do comando
mysqldumpslow para obter um resumo das consultas que aparecem no log.
Se a op¸ao --log-long-format estiver sendo usada, enao as consultas que n˜ao estiverem
utilizando ´
indices ser˜ao escritas. See line options-snt [Op¸oes de linha de comando], page
line options-pg.
4.9.6 O Log de Manuten¸ao de Arquivo
O MySQL tem v´arios arquivos de log que possibilitam ver o que est´a ocorrendo com mais
facilidade. See hundefinedi[Arquivos de Log], page hundefinedi. Por´em de tempos em
tempos deve ser feita uma limpeza nos arquivos de logs do MySQL para que eles n˜ao ocupem
muito do espa¸co do disco.
Ao utilizar o MySQL com arquivos log, vocˆe necessitar´a de tempos em tempos remover
antigos arquivos de log e dizer ao MySQL para logar com novos arquivos. See hundefinedi
[Backup], page hundefinedi.
Em uma instala¸ao Linux RedHat), vocˆe pode usar o script mysql-log-rotate para isto.
Se vocˆe instalou o MySQL de uma distribui¸ao RPM, o script deve ter sido instalado
automaticamente. Perceba que vocˆe deve ter cuidado com isto se vocˆe estiver utilizando o
log para replica¸ao!
Em outros sistemas vocˆe deve instalar um pequeno script que ser´a executado pelo cron
para lidar com os arquivos de log.
Voe pode for¸car o MySQL a iniciar utilizando novos arquivos de log usando mysqladmin
flush-logs ou utlizando o comando SQL FLUSH LOGS. Se vocˆe usa o MySQL Vers˜ao 3.21
deve utilizar o comando mysqladmin refresh.
O comando acima faz o seguinte:
Se o o log padr˜ao (--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˜ao).
Se o log de atualiza¸ao (--log-update) ´e usado, fecha o log de atualiza¸ao e abre um
novo arquivo log com uma sequˆencia num´erica mais alta.
Se vocˆe s´o estiver utilizando o log de atualiza¸ao, vocˆe tem apenas que atualizar os logs e
enao mover os arquivos de log antigos para um backup. Se vocˆe estiver utilizando o log
normal, vocˆe pode fazer algo assim:
shell> cd diret´orio-dados-mysql
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs
e enao fazer um backup e remover o ‘mysql.old’.
4.10 Replica¸ao no MySQL
Este cap´
itulo descreve os v´arios recursos da replica¸ao no MySQL. Ele serve como uma
referˆencia para as op¸oes dispon´
iveis na replica¸ao. Voe ser´a introduzido a replica¸ao
e aprender´a como implemena-la. Em dire¸ao ao final, existem algumas quest˜oes mais
perguntadas (FAQ) e descri¸oes de problemas e como resolvˆe-los.
312 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
4.10.1 Introdu¸ao
Um motivo de se usar replica¸ao ´e para ganhar robustez e velocidade. No caso de robustez
vocˆe pode ter dois sistemas e pode fazer um troca para o backup se tiver problemas com o
mestre. A velocidade extra ´e alcan¸cada enviando uma parte de consultas que n˜ao sejam de
atualiza¸ao para o servidor de replica¸ao. ´
E claro que isto funciona somente se consultas
que n˜ao fazem atualiza¸oes forem em maior n´umero, o que ´e o caso normal.
A partir da vers˜ao 3.23.15, o MySQL suporta replica¸ao de uma via internamente. Um
servidor atua como o mestre, enquando o outro atua como escravo. Note que um servidor
pode exercer a fun¸ao do mestre em um momento e de escravo em outro. O servidor mestre
mantˆem um log bin´ario de atualiza¸oes (See hundefinedi[Log bin´ario], page hundefinedi.)
e um arquivo ´
indice para logs bin´arios para manter os registro da rotatividade dos logs. O
escravo, na conex˜ao, informa ao mestre onde parou desde a ´ultima atualiza¸ao propagada
com sucesso, realiza a atualiza¸ao e ent˜ao para e espera o mestre informar sobre novas
atualiza¸oes.
Note que se vocˆe estiver replicando um banco de dados, todas atualiza¸oes neste banco de
dados deve ser feito atrav´es do mestre !
Outro benef´
icio de utilizar replica¸ao ´e que pode-se obter backups intantˆaneos do sis-
tema fazendo backups no escravo em vez de fazˆe-los no mestre. See hundefinedi[Backup],
page hundefinedi.
4.10.2 Vis˜ao Geral da Implementa¸ao da Replica¸ao
A replica¸ao no MySQL ´e baseia-se no fato do servidor manter o registro de todas as
altera¸oes de seus bancos de dados (atualiza¸oes, dele¸oes, etc) no log bin´ario. (See hunde-
finedi[Log bin´ario], page hundefinedi.) e do(s) servidor(es) escravo(s) ler(em) as consultas
salvas no log bin´ario do servidor mestre para que assim execute as mesmas consultas nos
seus dados replicados.
´
Emuito importante entender que o log bin´ario ´e simplesmente um registro iniciando a
partir de um ponto fixo no tempo (o momento que voe habilitou o log bin´ario). Quaisquer
escravos que vocˆe configure necessitar´a de c´opias de todos os dados do seu mestre como
eles existiam no momento em que o log bin´ario foi habilitado no mestre. Se vocˆe iniciar
os escravos com dados que n˜ao estejam de acordo com o que est´a no mestre quando o log
bin´ario foi iniciado, seus escravos falhar˜ao.
Em uma pr´oxima vers˜ao (4.0), ao existir´a a necessidade de manter uma c´opia dos da-
dos para novos escravos que vocˆe deseje configurar atrav´es da funcionalidade do backup
instananeo sem ter a necessidade de bloqueios. Entretanto, neste momento, ´e necess´ario
travar todas escritas atrav´es de uma trava de leitura global ou desligar o master enquando
faz c´opia.
Uma vez que o escravo foi configurado corretamente e est´a em execu¸ao, ele simplesmente
conectar´a ao mestre e esperar´a por atualiza¸oes nos processos. Se o mestre for desligado
ou o escravo perder conectividade com seu mestre, ele tentar´a conectar a cada master-
connect-retry segundos at´e conseguir reconectar e resumir as atualiza¸oes.
Cada escravo mantˆem registro de onde parou. O servidor mestre n˜ao tem conhecimento de
quandos escravos existem ou quais est˜ao atualizados em um determinado momento.
A pr´oxima se¸ao explica o processo de configura¸ao mestre/escravo com mais detalhes.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 313
4.10.3 Como Configurar a Replica¸ao
Abaixo est´a uma descri¸ao r´apida de como configurar uma replica¸ao completa em seu
servidor MySQL atual. Ele assume que vocˆe deseja replicar todos os bancos de dados e
nunca configurou uma replica¸ao anteriormente. Voe precisar´a desligar seu servidor mestre
rapidamente para completar os passos delineados abaixo.
1. Certifique-se que vocˆe possui uma vers˜ao recente do MySQL instalado no servidor
mestre e no(s) escravo(s).
Utilize a vers˜ao 3.23.29 ou superior. Releases anteriores utilizavam um formato de log
bin´ario diferente e possuia erros que foram corrigidos em vers˜oes atuais. Por favor,
ao relate erros at´e que vocˆe tenha verificado que o problema esteja presnte na ´ultima
vers˜ao.
2. Configure um usu´ario especial para a replica¸ao na m´aquina master com o privil´egio
FILE e permiss˜ao para conectar a partir de todos os escravos. Se a fun¸ao deste usu´ario
´e somente para a replica¸ao, enao vocˆe n˜ao precisar´a fornecer nenhum privil´egio adi-
cional para ele.
Por exemplo, para criar um usu´ario chamado repl que pode acessar seu mestre de
qualquer m´aquina, vocˆe deve utilizar este comando:
GRANT FILE ON *.* TO repl@"%" IDENTIFIED BY ’<senha>’;
3. Desligue o MySQL no mestre.
mysqladmin -u root -p<senha> shutdown
4. Fca uma c´opia de todos os dados existentes em seu servidor mestre.
A maneira mais f´acil de fazer isto (no Unix) ´e simplesmente usar o comando tar para
produzir um arquivo die todo o seu diret´orio de dados. A localiza¸ao exata do diret´orio
de dados depende de sua instala¸c˜ao.
tar -cvf /tmp/mysql-snapshot.tar /caminho/para/diret´orio-dados
Usu´arios windows podem usar o Winzip ou algum software similiar para criar um
arquivo do diret´orio de dados.
5. No arquivo my.cnf no mestre adicione log-bin eserver-id=n´umero_´unico na se¸ao
[mysqld] e reinicie o servi¸co. ´
E muito importante que o que a identifica¸ao do servidor
na m´aquina escrava seja diferente da identifica¸ao no mestre. Pense em server-id
como alguma coisa similiar a endere¸cos IP - ele identifica unicamente a instˆancia do
servidor na comunidade de parceiros de replica¸ao.
[mysqld]
log-bin
server-id=1
6. Reinicie o MySQL na m´aquina mestre.
7. Adicione o seguinte no my.cnf no(s) escravo(s):
master-host=<nome do mestre>
master-user=<nome do usu´ario de replica¸c~ao>
master-password=<senha do usu´ario de replica¸c~ao>
master-port=<porta TCP/IP para o mestre>
server-id=<algum n´umero ´unico entre 2 e 2^32-1>
trocando os valores entre <> com o que for relacionado ao seu sistema.
314 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
server-id deve ser diferente para cada servidor participante da replica¸ao. Se vocˆe
ao especificar um server-id, ele ser´a configurado para 1 se vocˆe n˜ao definiu master-
host, sen˜ao ele ser´a configurado para 2. Perceba que no caso da omiss˜ao de server-id
o mestre ir´a recusar conex˜oes de todos os escravos, e o escravo recusar´a a conex˜ao a
um mestre. Assim, omitindo server-id ´e bom somente para um backup com um log
bin´ario.
8. Coloque os dados copiados anteriormente no seu diret´orio de dados no(s) escravo(s).
Tenha certeza que os privil´egios nos arquivos e diret´orios est˜ao corretos. O usu´ario que
executa o MySQL deve estar apto para ler e escrever nos bancos de dados, da mesma
forma que no mestre.
9. Restart the slave(s).
Depois de completados os procedimentos acima, o(s) escravo(s) devem se conectar ao mestre
e pegar todas as atualiza¸oes que ocorreram desde que o backup foi restaurado.
Se vocˆe esqueceu de configurar o server-id no escravo vocˆe ir´a 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.
Se vocˆe esqueceu fazer isto no mestre, os escravos n˜ao v˜ao conseguir se conectar ao mestre.
Se um escravo n˜ao est´a apto para replicar por alguma raz˜ao, vocˆe encontrar´a a mensagem
de erro no arquivo de log de erros no escravo.
Uma vez que um escravo est´a replicando, vocˆe encontrar´a um arquivo chamado master.info
no mesmo diret´orio do seu log de erros. O arquivo master.info ´e usado pelo escravo para
manter o registro de quanto foi processado do log bin´ario do mestre. ao remova ou edite
o arquivo, a menos que vocˆe realmente saiba o que est´a fazendo. Mesmo neste caso, ´e mais
aconselh´avel usar o comando CHANGE MASTER TO.
4.10.4 Recursos de Replica¸ao e Problemas Conhecidos
Abaixo uma explica¸ao do que ´e e o que n˜ao ´e suportado:
A Replica¸ao ser´a feita corretamente com valores AUTO_INCREMENT,LAST_INSERT_ID
eTIMESTAMP.
RAND() nas atualiza¸oes n˜ao replica corretamente. Utilize RAND(alguma_expr_n~ao_
rand^omica) se estiver replicando atualiza¸oes com RAND(). Vocˆe pode, por exemplo,
usar UNIX_TIMESTAMP() para o argumento para RAND().
Devem ser usados os mesmos conjuntos de caracteres (--default-character-set) no
mestre e no escravo. Se n˜ao, vocˆe pode obter erros de chaves duplicadas no escravo,
pois uma chave que ´e tratada como ´unica no mestre pode n˜ao ser a mesma no outro
conjunto de caracteres.
LOAD DATA INFILE ser´a tratato corretamente enquanto o arquivo ainda continuar no
servidor mestre no momento da propaga¸ao da atualiza¸ao. LOAD LOCAL DATA INFILE
ser´a ignorado na replica¸ao.
Consultas de atualiza¸ao que usam vari´aveis de usu´arios (ainda) n˜ao s˜ao seguras para
replicar.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 315
Comandos FLUSH ao s˜ao armazenados no log bin´ario e por isso, ao s˜ao replicadas para
os escravos. Normalmente isto n˜ao ´e um problema j´a que FLUSH ao altera nada. Entre-
tanto, isto significa que se vocˆe atualizar as tabelas de privil´egios do MySQL diretamente
sem usar a instru¸ao GRANT e replicar o banco de dados de privil´egios do MySQL, vocˆe
deve fazer um FLUSH PRIVILEGES nos escravos para fazer com que os novos privil´egios
tenham efeito.
A partir da vers˜ao 3.23.29 tabelas tempor´arias s˜ao replicadas corretamente com a ex-
cess˜ao do caso no qual o servidor escravo ´e desligado (n˜ao apenas a thread escrava da
replica¸ao), e algumas tabelas tempor´arias est˜ao abertas e s˜ao usadas nas atualiza¸oes
subsequentes. Para lidar com este problema, iantes de desligar o escravo, execute SLAVE
STOP e enao verifique a vari´avel Slave_open_temp_tables para ver se ela ´e 0, ent˜ao
execute mysqladmin shutdown. Se o n´umero n˜ao for 0, reinicie a thred escrava com
SLAVE START e veja se vocˆe tea mais sorte na pr´oxima vez. Existir´a uma solu¸ao
melhor, mas teremos que esper´a-la at´e a vers˜ao 4.0. Em vers˜oes anteriores, tabelas
tempor´arias n˜ao eram replicadas corretamente - n´os recomendamos que voe atualize
sua vers˜ao ou execute SET SQL_LOG_BIN=0 nos seus clientes antes de todas as consultas
com tabelas tempor´arias.
O MySQL suporta somente um mestre e v´arios escravos. Na vers˜ao 4.x adicionaremos
um algor´
itimo de vota¸ao para trocar automaticamente o mestre se alguma coisa estiver
errada com o mestre atual. Iremos tamb´em introduzir processos agentes para ajudar
a fazer o balanceamento de carga enviando consultas com SELECTS para diferentes
escravos.
A partir da vers˜ao 3.23.26 ´e seguro conectar servidores em um relacionamento circular
com log-slave-updates habilitado. Perceba, entretanto, que v´arias queries n˜ao ir˜ao
funcionar corretamente neste tipo de configura¸ao a menos que o c´odigo do cliente seja
escrito para tomar cuidado dos potenciais problemas que podem ocorrer em diferentes
sequˆencias em servidores diferentes.
Isto significa que vocˆe pode fazer uma configura¸ao parecida com o seguinte:
A->B->C->A
Esta configura¸ao funcionar´a se vocˆe fizer somente atualiza¸oes n˜ao conflitantes entre
as tabelas. Em outras palavras, se vocˆe inserir dados em A e C, vocˆe nunca poder´a
inserir uma linha em A que pode ter uma chave conflitante com uma linha inserida em
C. Voe tamb´em n˜ao deve atualizar as mesmas linhas em dois servidores se a ordem
em que as atualiza¸oes s˜ao aplicadas importar.
Note que o formato de log foi alterado na Vers˜ao 3.23.26 portanto escravos anteriores
a vers˜ao 3.23.26 n˜ao conseguir˜ao ler estes logs.
Se houver um erro em uma consulta no escravo, a thread escrava ir´a terminar e uma
mensagem ir´a aparecer no arquivo .err. Vocˆe deve enao conectar a um escravo man-
ualmente, corrigir a causa do erro (por exemplo, tabela n˜ao existente), e enao executar
o comando sql SLAVE START (dispon´
ivel a partir da vers˜ao 3.23.16). Na vers˜ao 3.23.15,
ser´a necess´ario reiniciar o servidor.
Se a conex˜ao para o mestre for perdida, o escravo ir´a tentar conectar de novo imedi-
atamente e no caso de falhas, a cada master-connect-retry (padr˜ao 60) segundos.
Por causa disto, ´e seguro desligar o mestre, e enao reinici´a-lo depois de um tempo. O
escravo tamb´em est´a apto para lidar com interrup¸oes de rede.
316 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Desligar o escravo (corretamente) tamb´em ´e seguro, pois mant´em sinais de onde parou.
Desligamentos incorretos podem produzir problemas, especialmente se o cache de disco
ao foi sincronizado antes do sistema morrer. Seu sistema de tolerˆancia a falhas ser´a
melhorado se vocˆe possuir um bom No-Break ou UPS.
Se o mestre est´a escutando em uma porta n˜ao padr˜ao, vocˆe tamb´em deve especific´a-la
com o parˆametro master-port no my.cnf.
Na vers˜ao 3.23.15, todas as tabelas e bancos de dados ser˜ao replicados. A partir da
vers˜ao 3.23.16, vocˆe pode restringir a replica¸ao para um conjunto de bancos de dados
com diretivas replicate-do-db no my.cnf ou apenas excluir um conjunto de bancos
de dados com replicate-ignore-db. At´e a vers˜ao 3.23.23, existia um bug que n˜ao
lidava corretamente com LOAD DATA INFILE se voe fizesse isto em um banco de dados
que foi excluido da replica¸ao.
A partir da Vers˜ao 3.23.16, SET SQL_LOG_BIN = 0 ir´a desligar a replica¸ao (bin´arias)
no mestre e SET SQL_LOG_BIN=1 ir´a lig´a-la novamente - vocˆe deve possuir o privil´egio
process para fazer isto.
A partir da vers˜ao 3.23.19, vocˆe pode limpar vest´
igios de replica¸oes anteriores quando
algo estiver errada acontecer e vocˆe deseja iniciar corretamnete com os comandos FLUSH
MASTER eFLUSH SLAVE. Na vers˜ao 3.23.26 n´os os renomeamos respectiviamente para
RESET MASTER eRESET SLAVE para deixar claro o que eles fazem. As variantes antigas
FLUSH ainda funcionam, para manter compatibilidade.
A partir da vers˜ao 3.23.21, vocˆe pode utilizar LOAD TABLE FROM MASTER para backup
de rede e configurar inicialmente a replica¸ao. Recentemente, recebemos v´arios relatos
de bugs relacionados e estamos investigando, portanto n´os recomendamos que vocˆe o
utilize somente para testes at´e que se torne mais est´avel.
A partir da vers˜ao 3.23.23, vocˆe pode alterar os mestres e ajustar a posi¸ao do log com
CHANGE MASTER TO.
A partir da vers˜ao 3.23.23, vocˆe pode dizer ao mestre que atualiza¸oes em determinados
bancos de dados n˜ao devem ser registradas no log bin´ario com binlog-ignore-db.
A partir da vers˜ao 3.23.26, vocˆe pode utilizar replicate-rewrite-db para dizer ao
escravo para fazer atualiza¸oes de um banco de dados no mestre para outro com um
nome diferente no escravo.
A partir da vers˜ao 3.23.28, vocˆe pode utilizar PURGE MASTER LOGS TO ’log-name’ para
se livrar de logs antigos enquanto o escravo estiver funcionando.
4.10.5 Op¸oes da Replica¸ao no my.cnf
Se vocˆe estiver utilizando replica¸ao, recomentados o uso da vers˜ao 3.23.30 do MySQL
ou superior. Vers˜oes antigas funcionam, mas elas possuem algums bugs e faltam alguns
recursos.
Voe deve utilizar a op¸ao server-id no mestre e no escravo. Isto configura um ´unico id de
replica¸ao. Deve ser escolhido um valor ´unico no intervalo de 1 a 2^32-1 para cada mestre
e escravo. Example: server-id=3
A tabela a seguir tem as op¸oes que podem ser utilizadas no MESTRE:
Chapter 4: Administra¸ao de Bancos de Dados MySQL 317
Op¸ao Descri¸ao
log-bin=nome_arquivo Grava em um log bin´ario de atualiza¸oes em uma lo-
caliza¸ao espec´
ifica. Perceba que se vocˆe fornecer
um parˆametro com uma extens˜ao (por exemplo, log-
bin=/mysql/logs/replication.log ) as vers˜oes at´e 3.23.24
ao ir˜ao funcionar direito durante a replica¸ao se vocˆe fizer
FLUSH LOGS. O problema ´e corrigido na vers˜ao 3.23.25. Se
vocˆe estiver utilizando este tipo de nome de log, FLUSH LOGS
ser´a ignorado no log bin´ario. Para limpar o log, execute FLUSH
MASTER, e n˜ao se esque¸ca de executar FLUSH SLAVE em todos
os escravos. Na vers˜ao 3.23.26 e em vers˜oes posteriores vocˆe
deve utilizar RESET MASTER eRESET SLAVE
log-bin-index=filename Como o usu´ario pode disparar o comando FLUSH LOGS, pre-
cisamos saber qual log est´a ativo no momento e quais foram
foram rotacionados e em qual sequˆencia. Esta informa¸ao ´e
armazenada no arquivo de ´
indice do log bin´ario. O padr˜ao ´e
‘nome aquina‘.index. Vocˆe pode utilizar esta op¸ao se de-
seja se rebelar.
Exemplo: log-bin-index=db.index.
sql-bin-update-same Se configurado, atribuir um valor a SQL_LOG_BIN ir´a atribuir
automaticamente ao parˆametro SQL_LOG_UPDATE o mesmo va-
lor e vice versa.
binlog-do-db=nome_bd Diz ao mestre que ele deve logar as atualiza¸oes para o log
bin´ario se o banco de dados atual for ’nome bd’. Todos os
outros bancos de dados s˜ao ignorados. Note que se voe uti-
lizar esta op¸ao vocˆe deve se assegurar que s´o poder´a ser feito
atualiza¸oes no banco de dados atual.
Exemplo: binlog-do-db=nome_bd.
binlog-ignore-db=nome_
bd
Diz ao mestre que atualiza¸oes onde o banco de dados at-
ual ´e ’nome bd’ n˜ao devem ser armazenadas no log bin´ario.
Perceba que se vocˆe usar esta op¸ao vocˆe deve ter certeza que
vocˆe somente atualizar´a o banco de dados atual.
Exemplo: binlog-ignore-db=nome_bd
A tabela seguinte cont´em as op¸oes que vocˆe opde utilizar para SLAVE:
Op¸ao Descri¸ao
master-host=m´aquina Nome da m´aquina mestre ou endere¸co IP para replica¸ao. Se
ao for configurada a thread do escravo n˜ao ser´a iniciada.
Exemplo: master-host=db-master.mycompany.com.
318 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
master-user=nome_
usu´ario
O usu´ario que a thread escrava usar´a para autenticar ao
conectando ao mestre. O usu´ario deve ter o privil´egio FILE.
Se master-user n˜ao for configurado, assume-se o usu´ario
teste.
Exemplo: master-user=scott.
master-password=senha A senha que a thread escrava usar´a para autenticar ao
conectando ao mestre. Se n˜ao for configurada, uma senha
vazia ´e enviada.
Exemplo: master-password=tiger.
master-port=n´umero_
porta
A porta que o mestre escutar´a. Se n˜ao for configurado, a
configura¸ao padr˜ao de compila¸ao MYSQL_PORT ´e assumida.
Se vocˆe n˜ao tiver alterado op¸c˜oes do configure, este valor
deve ser 3306.
Exemplo: master-port=3306.
master-connect-
retry=segundos
O n´umero de segundos que a thread escrava dormir´a antes de
tentar novamente a conex˜ao ao mestre no caso do mestre cair
ou perder a conex˜ao. o tempo padr˜ao ´e 60.
Exemplo: master-connect-retry=60.
master-info-file=nome_
arquivo
A localiza¸ao do arquivo que mostra em qual parte do mestre
est´avamos durante o processo de replica¸ao. O padr˜ao ´e mas-
ter.info no diret´orio de dados. Sasha: A ´unica raz˜ao que vejo
para alterar o padr˜ao ´e o dsejo de se rebelar.
Exemplo: master-info-file=master.info.
replicate-do-
table=nome_bd.nome_
tabela
Diz `a thread escrava para restringir a replica¸ao a uma tabela
espec´
ifica. Para especificar mais de uma tabela, utilize a di-
retiva v´arias vezes, uma para cada tabela. Isto ir´a funcionar
para atualiza¸oes cruzadas em bancos de dados, em contraste
com replicate-do-db.
Exemplo: replicate-do-table=nome_bd.nome_tabela.
replicate-ignore-
table=nome_bd.nome_
tabela
Diz `a thread escrava n˜ao replicar uma tabela espec´
ifica. Para
especificar mais de uma tabela a ser ignorada, utilize a diretiva
m´ultiplas vezes, uma vez para cada tabela. Isto ir´a funcionar
para atualiza¸oes cruzadas em bancos de dados, em contraste
com replicate-ignore-db.
Exemplo: replicate-ignore-table=nome_bd.nome_
tabela.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 319
replicate-wild-do-
table=nome_bd.nome_
tabela
Diz `a thread escrava para restringir a replica¸ao `as tabelas
que combinarem com a mascara especificado. Para especificar
mais de uma tabela, utilize a diretiva diversas vezes, uma vez
para cada tabela. Isto funcionar´a para atualiza¸oes cruzadas
em bancos de dados.
Exemplo: replicate-wild-do-table=foo%.bar% ir´a
replicar atualiza¸oes em tabelas que iniciem em todos os
bancos de dados cujos nomes iniciem com foo e nas tabelas
cujos nomes iniciam com bar.
replicate-wild-ignore-
table=nome_bd.nome_
tabela
Diz `a thread escrava para n˜ao replicar as tabelas que com-
binarem com a m´ascara especificada. Para especificar mais
de uma tabela, utilize a diretiva diversas vezes, uma vez para
cada tabela. Isto funcionar´a para atualiza¸oes cruzadas em
bancos de dados.
Exemplo: replicate-wild-ignore-table=foo%.bar% ao
ir´a atualizar as tabelas nos bancos de dados cujos nomes ini-
ciam com foo e nas tabelas que iniciam com bar.
replicate-ignore-
db=nome_banco_dados
Diz `a thread escrava n˜ao replicar um banco de dados es-
pec´
ifico. Para especificar mais que um banco de dados para
ignorar, utilize a diretiva v´arias vezes, uma para cada banco
de dados. Esta op¸ao n˜ao ir´a funcionar se vocˆe utilizar at-
ualiza¸oes cruzadas em bancos de dados. Se vocˆe necessi-
tar de atualiza¸oes cruzadas, tenha certeza que vocˆe possui
o MySQL 3.23.28 ou superior, e utilize replicate-wild-
ignore-table=db_name.%
Exemplo: replicate-ignore-db=algum_bd.
replicate-do-db=nome_
banco_dados
Diz `a thread escrava restringir a replica¸ao para um banco
de dados especificado. Para especificar mais de um banco
de dados, utilize a mesma diretiva diversas vezes, uma para
cada banco de dados. Perceba que isto funcionar´a somente
se vocˆe n˜ao utilizar consultas com bancos de dados cruza-
dos como UPDATE algum_bd.alguma_tabela SET foo=’bar’
enquanto tiver selecionado um banco de dados diferentei ou
nenhum banco de dados. Se voe necessita ter atualiza¸oes
de bancos de dados cruzados funcionando, tenha certeza que
sua vers˜ao do MySQL ´e a 3.23.28 ou posterior e utilize
replicate-wild-do-table=nome_bd.%
Example: replicate-do-db=algum_bd.
log-slave-updates Diz ao escravo para registrar as atualiza¸oes da thread escrava
no log bin´ario. Desligado por padr˜ao. Deve ser ligado se vocˆe
planeja ter escravos daisy-chain.
320 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
replicate-rewrite-
db=do_nome->para_nome
Atualiza em um banco de dados com um nome diferente do
original
Exemplo: replicate-rewrite-db=nome_bd_mestre-
>nome_bd_escravo.
slave-skip-errors=c´od_
erro_1,c´od_erro_2,..
Dispon´
ivel somente na vers˜ao 3.23.47 e posterior. Diz `a thread
escrava para continuar a replica¸ao quando uma consulta re-
tornar um erro fornecido na lista. Normalmente, replica¸ao
ir´a para quando um erro for encontrado, dando ao usu´ario
uma chance para resolver a inconsistˆencia nos dados man-
ualmente. ao utilize esta op¸ao a menos que vocˆe en-
tenda bem a raz˜ao dos erros. Se n˜ao existirem bugs na con-
figura¸ao de sua replica¸ao e programas clientes e at´e mesmo
no pr´oprio MySQL, vocˆe nunca deve ter um aborto com erro.
O uso indiscrimiado desta op¸ao ir˜ao resultar em escravos n˜ao
confi´aveis e sempre fora de sincronia com o mestre e vocˆe n˜ao
ter id´eia de como o problema ocorreu.
Para c´odigos de erros, vocˆe deve utilizar os n´umeros forneci-
dos pela mensagem de erro no log de erros do escravo e na
sa´
ida do comando SHOW SLAVE STATUS. A lista completa das
mensagens de erros podem ser encontradas na distribui¸ao
fonte em Docs/mysqld_error.txt
Voe tamb´em pode ( mas n˜ao deve ) usar um valor n˜ao
recomendado de all que ir´a ignorar todas as mensagens de
erros e manter a comunica¸ao sem maiores crit´erios. ao ´e
necess´ario falar, que se vocˆe us´a-lo, ao poder´a ser assegurada
a integridade de seus dados. Por favor n˜ao reclame se os dados
em sua m´aquina escrava n˜ao estiverem nem perto dos que
est˜ao no mestre no seu caso - vocˆe foi avisado.
Exemplo:
slave-skip-errors=1062,1053 ou slave-skip-
errors=all
skip-slave-start Diz ao servidor escravo para n˜ao iniciar o escravo na inicial-
iza¸ao. O usu´ario deve cham´a-lo posteriormente com SLAVE
START.
slave_read_timeout=# N´umero de segundos a esperar por mais dados do mestre antes
de abortar a leitura.
4.10.6 Comandos SQL Relacionados `a Replica¸ao
A replica¸ao pode ser controlada atrav´es da interface SQL. Abaixo segue o resumo dos
comandos:
Comando Descri¸ao
SLAVE START Inicia a thread escrava. (Escravo)
SLAVE STOP Termina a thread escrava. (Escravo)
Chapter 4: Administra¸ao de Bancos de Dados MySQL 321
SET SQL_LOG_BIN=0 Desativa o registro de atualiza¸oes se o usu´ario possui o
privil´egio process. De outra forma, ´e ignorado. (Mestre)
SET SQL_LOG_BIN=1 Reabilita o registro de atualiza¸oes se o usu´ario possui o
privil´egio process. De outra maneira, ´e ignorado. (Mestre)
SET SQL_SLAVE_SKIP_
COUNTER=n
Salta o(s) pr´oximo(s) neventos do mestre. alido somente
quando a thread escrava n˜ao estiver em execu¸ao, de outra
forma, retorna um erro. ´
Util para recupera¸ao de pequenos
erros da replica¸ao.
RESET MASTER Apaga todos os logs bin´arios listados no arquivo de ´
indice,
zerando o arquivo de ´
indice. Nas vers˜oes pre-3.23.26, FLUSH
MASTER (Mestre)
RESET SLAVE Faz o escravo esquecer da sua posi¸ao da replica¸ao nos logs
do mestre. Em vers˜oes anteriores `a 3.23.26 o comando era
chamado FLUSH SLAVE (Escravo)
LOAD TABLE nome_tabela
FROM MASTER
Descarrega uma c´opia da tabela do mestre para o escravo.
(Escravo)
322 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
CHANGE MASTER TO
lista_def_mestre
Altera os parˆametros do mestre para os valores especificados
em lista_def_mestre e reinicia a thread escrava. lista_
def_mestre ´e uma lista separada por v´
irgulas de master_def
onde master_def ´e um dos seguintes: MASTER_HOST,MASTER_
USER,MASTER_PASSWORD,MASTER_PORT,MASTER_CONNECT_
RETRY,MASTER_LOG_FILE,MASTER_LOG_POST. Exemplo:
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;
Voe s´o precisa especificar os valores que devem ser alter-
ados. Os valores omitidos permanecer˜ao os mesmos com
a exce¸ao de quando vocˆe altera a m´aquina ou a porta.
Neste caso, o escravo ir´a assumir que desde que vocˆe esteja
conectando a uma m´aquina diferente ou uma porta diferente,
o mestre ´e diferente. Assim, os valores antigos do log e sua
posi¸ao n˜ao s˜ao mais aplic´aveis, e ser˜ao zerados automatica-
mente para uma string vazia e 0, respectivamente (os valores
iniciais). Perceba que se voe reiniciar o escravo, ele lembrar´a
do seu ´ultimo mestre. Se isto n˜ao for desej´avel, vocˆe deve apa-
gar o arquivo ‘master.info’ antes de reiniciar, e o escravo ir´a
ler o seu mestre do arquivo my.cnf ou da linha de comando.
(Escravo)
SHOW MASTER STATUS Fornece informa¸oes de estado no log bin´ario do mestre.
(Mestre)
SHOW SLAVE STATUS Fornece informa¸oes de estado nos parˆametros essenciais da
thread escrava. (Escravo)
SHOW MASTER LOGS Dispon´
ivel somente a partir da vers˜ao 3.23.28. Lista os logs
bin´arios no mestre. Voe deve usar este comando antes de
PURGE MASTER LOGS TO para saber at´e aonde deve ir.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 323
PURGE MASTER LOGS TO
’nome_log
Dispon´
ivel a partir da vers˜ao 3.23.28. Apaga todos os logs da
replica¸ao que estiverem listados no ´
indice de log anteriores ao
log especificado e tamb´em os remove do´
indice de log, portanto
o log fornecido agora vem em primeiro. Exemplo:
PURGE MASTER LOGS TO ’mysql-bin.010’
Este comando n˜ao far´a nada e ir´a falhar retornando um erro
caso vocˆe tenha um escravo ativo que esteja lendo um dos logs
que vocˆe estiver tentando apagar. Entretanto, se vocˆe possui
um escravo inativo e limpar um dos logs que ele desejar ler,
o escravo n˜ao conseguir´a replicar no momento que iniciar. O
comando ´e seguro para ser executado enquanto os escravos
estiverem replicando - vocˆe n˜ao precisa par´a-los.
Primeiro, vocˆe deve conferir todos os escravos com SHOW
SLAVE STATUS para ver qual log est˜ao sendo usados, ent˜ao
fa¸ca uma listagem dos logs no mestre com SHOW MASTER LOGS,
encontre o log mais novo entre todos os escravos (se todos os
escravos estiver atualizados, ele ser´a o ´ultimo log na lista),
fa¸ca um backup de todos os logs que vocˆe deseja deletar (op-
cional) e limpe at´e o log alvo.
4.10.7 FAQ da Replica¸ao
Q: Por quˆe as vezes eu vejo mais que uma thread Binlog_Dump no mestre depois que eu
reinicio o escravo ?
R:Binlog_Dump ´e um processo cont´
inuo que ´e tratado pelo servidor da seguinte maneira:
Pegue as atualiza¸oes.
Uma vez que n˜ao existem mais atualiza¸oes, v´a para pthread_cond_wait(), de onde
podemos despertar de uma atualiza¸ao ou um kill.
Quando acordado, confira a raz˜ao. Se n˜ao seremos filnalizados, continue o loop Binlog_
dump.
Se existir algum erro fatal, tais como detectar um cliente finalizado, termine o loop.
Portanto, se a thread escrava parar no servidor escravo, a thread Binlog_Dump correspon-
dente no mestre n˜ao ir´a notific´a-lo at´e ocorrer pelo menos uma atualiza¸ao no mestre (ou
um kill), que ´e necess´ario para despert´a-lo de pthread_cond_wait(). Neste intervalo, o
escravo pode ter aberto outra conex˜ao, que resulta em outra thread Binlog_Dump.
O problema acima n˜ao deve estar presente na vers˜ao 3.23.26 ou posterior. Na vers˜ao 3.23.26
os adicionamos server-id para cada servidor da replica¸c˜ao, ie agora todas as antigas
threads zumbis s˜ao finalizadas no mestre quando uma nova thread de replica¸ao conectar
do mesmo escravo.
Q: Como rotaciono os logs de replica¸ao?
R: Na vers˜ao 3.23.28 vocˆe deve usar o comando PURGE MASTER LOGS TO depois de determinar
quais logs podem ser apagados e opcionalmente fazer backups dos mesmos anteriormente.
Em vers˜oes anteriores o processo era muito mais doloroso e n˜ao pode ser feita com seguran¸ca
sem parar todos os escravos caso vocˆe planeje reutilizar os logs. Vocˆe precisar´a parar as
threads escravas, editar o arquivo de ´
indice do log bin´ario, apagar as linhas de logs antigos,
reiniciar o mestre, iniciar as threads escravas e enao remover os arquivos de log antigos.
324 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Q: Como eu fa¸co uma atualiza¸ao a sem parar uma replica¸ao ?
R: Se vocˆe estiver atualizando vers˜oes anteriores a 3.23.26, deve apenas travar as tabelas
do mestre, deixar os escravos se atualizarem, e ent˜ao executar FLUSH MASTER no mester e
FLUSH SLAVE no escravo para zerar os logs, e ent˜ao reiniciar novas vers˜oes do mestre e do
escravo. Perceba que o escravo pode continuar derrubado por algum tempo - desde que o
mestre estiver registrando todas as atualiza¸oes, o escravo ir´a estar apto a capt´a-las uma
vez que esteja ligado e possa conectar.
Depois da vers˜ao 3.23.26, n˜ao mais modificamos o protocolo de replica¸c˜ao, assim vocˆe pode
atualizar mestres e escravos sem parar a replica¸ao para uma vers˜ao 3.23 mais nova e vocˆe
pode ter diverentes vers˜oes do MySQL executando no escravo e no mestre, desde que ambos
sejam mais novos que 3.23.26.
Q: Do que devo estar ciente quando for configurar uma replica¸ao de duas vias?
R: A replica¸ao do MySQL atualmente n˜ao suporta nenhum protocolo de bloqueio entre
o mestre e o escravo para garantir a atomicidade de uma atualiza¸ao distribuida (cross-
server). Em outras palavras, ´e poss´
ivel para um cliente A fazer uma atualiza¸ao para um
co-master 1, e no intervalo, antes dele propagar para o co-master 2, o cliente B pode fazer
uma atualiza¸ao para o co-master 2 que ir´a tornar a atualiza¸ao do cliente A diferente que
foi solicitado em co-master 1. Assim, quando o cliente A atualizar no co-master 2, ela ir´a
produzier tabelas que ser˜ao diferentes das que vocˆe possui no co-master 1, mesmo depois
de todas as atualiza¸oes do co-master 2 terem sido propagadas. Portanto, vocˆe n˜ao deve
fazer uma a¸ao em cadeia de dois servidores em uma rela¸ao de replica¸ao de duas vias,
a menos que vocˆe tenha certeza que suas atualiza¸oes podem seguramente acontecer em
alguma ordem, ou a menos que vocˆe tome cuidado com as atualiza¸oes fora de ordem no
odigo cliente.
Voe tamb´em pode perceber que a replica¸ao de duas vias n˜ao proporciona um grande
aumento de performance, se considerarmos as atualiza¸aoes. Ambos servidores precisam
fazer a mesma quantidade de atualiza¸oes cada um, como se existisse apenas um servidor. A
unica diferen¸ca ´e que haver´a um pouco menos de bloqueios, a que as atualiza¸oes originadas
em outro servidor ser˜ao colocadas em s´erie em uma thread escrava. Este benef´
icio, no
entanto, pode acarretar atraso na rede.
Q: Como eu posso utilizar a replica¸ao para melhorar a performance em meu sistema?
R: Voe deve configurar um servidor como o mestre, e direcionar todas as escritas para
ele, e configurar quantos escravos seu dinheiro e seu espa¸co permitir, distribuir as leituras
entre o mestre e os escravos. Vocˆe pode tamb´em iniciar os escravos com --skip-bdb,-
-low-priority-updates e--delay-key-write-for-all-tables para obter melhora na
velocidade do escravo. Neste caso o escravo ir´a usar tabelas MyISAM ao transacionais em
vez de tabelas BDB para obter mais velocidade.
Q: O que eu devo fazer para preparar o meu c´odigo cliente para obter melhor performance
na replica¸ao ?
R: Se a parte do seu c´odigo que ´e respons´avel para acesso no banco de dados foi corretamente
abstraido/modularizado, convertˆe-lo para executar com a configura¸ao replicada deve ser
muito suave e f´acil - apenas altera a implementa¸ao do acesso ao banco de dados para
ler de algum escravo ou do mestre e para sempre gravar no mestre. Se o seu c´odigo n˜ao
possui este tipo de abstra¸ao, configurar um sistema replicado lhe dar´a uma oportunidade
Chapter 4: Administra¸ao de Bancos de Dados MySQL 325
e motivao para ajust´a-lo. Voe deve iniciar criando uma camada de biblioteca/modulo
com as seguintes fun¸oes:
safe_writer_connect()
safe_reader_connect()
safe_reader_query()
safe_writer_query()
safe_ significa que a fun¸ao ir´a tomar cuidado com o tratamento de todas as condi¸oes de
erro.
Enao vocˆe deve converter seu c´odigo cliente para usar a camada de biblioteca. Esse processo
pode ser doloroso e assustador a princ´
ipio, mas ele valer´a a pena a longo prazo. Todas as
aplica¸oes que seguirem o padr˜ao acima receber˜ao poder˜ao tirar vantagem de uma solu¸ao
de um mestre/v´arios escravos. O c´odigo ser´a um pouco mais f´acil de manter, e adicionar
op¸oes para localiza¸ao de defeitos ser´a trivial. Vocˆe s´o precisar´a modificar uma ou duas
fun¸oes, por exemplo, para registrar quanto tempo cada consulta demora para ser executada,
ou qual consulta, entre milhares, est´a errada. Se voe j´a escreveu muito c´odigo, pode
precisar automatizar a tarefa de convers˜ao utilizando o utilit´ario replace desenvolvido pelo
Monty, que acompanha a distribui¸ao padr˜ao do MySQL, ou escreva seu pr´oprio script Perl.
Esperan¸cosamente, seu c´odigo segue algum padr˜ao reconhecido. Se n˜ao, provavelmente ser´a
melhor reescrever tudo novamente, ou pelo menos tente come¸car a seguir algum padr˜ao.
Perceba que, ´e claro, vocˆe pode utilizar nomes diferentes para as fun¸c˜oes. O que ´e importante
´e ter uma interface unificada para conex˜oes de leitura e conex˜oes de escrita.
Q: Quando e quanto a replica¸ao do MySQL pode melhorar a performance de meu sistema?
A: A replica¸ao do MySQL ´e mais eficas para um sistema com leituras frequentes e que n˜ao
tenha muitas escritas. Em teoria, utilizando uma conrfigura¸ao de um mestre para v´arios
escravos vocˆe pode escalar adicionando mais escravos at´e n˜ao ter mais banda de rede, ou
at´e que sua carga de atualiza¸oes cres¸ca ao ponto que o mestre n˜ao consiga lidar.
Para determinar quantos escravos vocˆe pode utilizar antes dos benef´
icios adicionados
come¸carem a funcionar e o quanto vocˆe pode melhorar a performance de seu site, voe
precisar´a saber seus estilos de query e de maneira emp´
irica (por benchmarking) determinar
a rela¸ao entre o r´
itmo de transferˆencia nas leituras (por segundo ou max_reads) e nas
escritas max_writes) em um mestre e escravo comuns. O exemplo abaixo mostra um
alculo especialmente simplificado de quanto vocˆe pode obter com replica¸ao para seu
sistema imagin´ario.
Digamos que a carga de seu sistema consista em 10% de escrita e 90% de leitura, e n´os
determinamos que max_reads = 1200 - 2 * max_writes, ou em outras palavras, nosso
sistema pode fazer 1200 leituras por segundo com nenhuma escrita, nossa escrita m´edia
´e duas vezes mais lenta que a leitura m´edia e a rela¸ao ´e linear. Vamos supor que nosso
mestre e escravo n˜ao tenham a mesma capacidade, e possuimos N escravos e 1 mestre.
Enao teremos para cada servidor (mestre ou escravo):
leituras = 1200 - 2 * escritas (dos benchmarks)
leituras = 9* escritas / (N + 1) (a leitura ´e dividida, mas a escrita ´e enviada a todos
os servidores)
9*escritas/(N+1) + 2 * escritas = 1200
326 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
escritas = 1200/(2 + 9/(N+1)
Portanto se N = 0, que significa que n˜ao possuimos replica¸ao, nosso sistema pode lidar
com 1200/11, cerca de 109 escritas por segundo (que significa que teremos 9 vezes o n´umero
de leituras devido `a natureza de nossa aplica¸ao).
Se N = 1, teremos um ganho de 184 escritas por segundo.
Se N = 8, ganharemos 400.
Se N = 17, 480 escritas.
Eventualmente como N aproxima do infinito (e nosso or¸camento vai infinitamente par o
negativo), podemos chegar perto de 600 escritas por segundo, aumentando o rendimento do
sistema em cerca de 5.5 vezes. Entretanto com somente 8 servidores j´a seria quase 4 vezes
mais r´apido.
Perceba que nossos c´alculos assumem uma banda de rede infinita e ignora diversos outros
fatores que podem se tornar muito significante em nosso sistema. Em v´arios casos, vocˆe
pode n˜ao conseguir fazer uma c´alculo similar ao acima predizendo de forma acurada o que
acontecer´a com seus sistema se vocˆe adicionar N escravos de replica¸ao. Entretanto, respon-
der as seguintes quest˜oes deve ajudar a sua decis˜ao, se com tudo, a replica¸c˜ao melhorar´a a
performance de seu sistema:
Qual a raz˜ao de leitura/escrita em seu sistema?
Quanta carga de escritas a mais o servidor pode tratar se vocˆe reduzir as leituras?
Quantos servidores sua banda de rede pode suportar?
P: Como eu posso utilizar a replica¸ao para fornecer redundˆancia e alta disponibilidade?
R: Com os recursos atualmente dispon´
iveis, vocˆe teria que configurar um mestre e um
escravo (ou v´arios escravos) e escrever um script que ir´a monitorar o mestre para ver se ele
est´a funcionando, e instruir suas aplica¸oes e os escravos da mudan¸ca de mestre em caso de
falha. Algumas sugest˜oes:
Para dizer a um escravo para trocar de mestre utilize o comando CHANGE MASTER TO.
Uma boa forma de manter suas aplica¸oes informadas aonde est´a o mestre ´e utilizar
uma entrada de DNS dinˆamica para o mestre. Com bind vocˆe pode utilizar nsupdate
para atualizar dinamicamente seu DNS.
Voe deve executar seus escravos com a op¸ao log-bin e sem log-slave-updates.
Dessa forma o escravo estar´a pronto para virar um mestre logo que vocˆe executar o
comando STOP SLAVE;RESET MASTER eCHANGE MASTER TO nos outros escravos. Isto
tamb´em pode ajudar a encontrar falsas atualiza¸oes que podem acontecer por motivos
de configura¸oes erradas do escravo (idealmente, vocˆe deve configurar direitos de acesso
para que nenhum cliente possa atualizar o escravo, exceto para a thread escrava) com-
binado com poss´
iveis bugs em seus programas clientes (eles nunca devem atualizar o
escravo diretamente).
Atualmente estamos trabalhando em integrar um sistema de elei¸ao autom´atica de mestres
no MySQL, mas at´e que esteja pronto, vocˆe dever´a criar suas pr´oprias ferramentas de
monitoramento.
Chapter 4: Administra¸ao de Bancos de Dados MySQL 327
4.10.8 Corrigindo Problemas de Replica¸ao
Se vocˆe tiver seguido as intru¸oes e sua configura¸ao de replica¸ao n˜ao estiver funcionando,
primeiro elimine o fator erros de usu´arios verificando o seguinte:
O mestre est´a gravando no log bin´ario? Confira com SHOW MASTER STATUS. Se estiver,
Position ser´a um valor diferente de zero. Se n˜ao verifique se vocˆe forneceu ao mestre
a op¸ao log-bin e configurou server-id.
O escravo est´a funcionando? Confira com SHOW SLAVE STATUS. A resposta ´e encon-
trada na coluna Slave_running. Se n˜ao, verifique as op¸oes do escravo e verifique as
mensagens no log de erros por mensagens.
Se o escravo estiver funcionando, ele estabeleceu comunica¸ao com o mestre? Execute
oSHOW PROCESSLIST, encontre a thread com o valor system user na coluna User e
none na coluna Host e confira a coluna State. Se ela conter connecting to master,
verifique os privil´egios para o usu´ario de replica¸ao no mestre, o nome da m´aquina
mestre, sua configura¸ao DNS, se o mestre est´a funcionando, se ele ´e alcan¸cado pelo
escravo e se tudo parece ok, leia os logs de erros.
Se o escravo estava funcionando, mas foi parado, procure na sa´
ida de SHOW SLAVE
STATUS e confira os logs de erros. Isto normalmente acontece quando alguma consulta
conclu´
ida com sucesso no mestre falha no escravo. Isto nunca deve acontecer se vocˆe
fizer uma copia dos dados do mester correto e nunca modificar os dados no escravo fora
da thread escrava. Se acontecer, isto ´e um bug, leia abaixo como report´a-lo.
Se uma consulta que foi conclu´
ida no mestre recusar a executar no escravo e um resin-
cronismo completo do banco de dados ( o mais adequado a se fazer ) n˜ao parece resolver,
experimente o seguinte:
Veja primeiro se existe algum registro est´atico no caminho. Compreenda como isto
ocorreu, entao apague-o e execute SLAVE START
Se o dito acima n˜ao funcionar ou n˜ao for aplic´avel ao seu caso, tente descobrir se
seria seguro fazer a atualiza¸ao manualmente (se for necess´ario) e enao ignore a
pr´oxima consulta do mestre.
Se vocˆe decidiu que deve ignorar a pr´oxima consulta, fa¸ca SET SQL_SLAVE_
SKIP_COUNTER=1; SLAVE START; para saltar uma consulta que n˜ao utilize
auto increment ou last insert id ou de outra forma, SET SQL_SLAVE_SKIP_
COUNTER=2; SLAVE START;. A raz˜ao das consultas auto increment/last insert id
serem diferentes ´e que elas s˜ao utilizam eventos do log bin´ario do mestre.
Se vocˆe tem certeza que o escravo iniciou perfeitamente em sincronia com o mestre,
e que as tabelas envolvidas nao foram atualizadas fora da thread escrava, relate o
erro, para que vocˆe n˜ao precise repetir os truques acima novamente.
Tenha certeza de que vocˆe n˜ao est´a tendo problemas com um erro antigo atualizando
para a vers˜ao mais recente.
Se tudo o mais falhar, leia os logs de erro. Se eles estiverem muito grandes, execute grep
-i slave /caminho/para/seu/log.err no escravo. ao existe um modelo gen´erico
para pesquisar no mestre, j´a que os ´unicos erros que ele registra s˜ao erros gerais de
sistema - se ele puder, ele enviar´a os erros para o escravo quando alguma coisa estiver
errada.
328 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Quando vocˆe tiver determinado que n˜ao h´a erro de usu´ario envolvido, e a replica¸ao ainda
ao funciona perfeitamente ou est´a inst´avel, ´e hora de come¸car a fazer num relat´orio de
erros. os precisamos do m´aximo de informa¸oes que vocˆe puder fornecer para conseguirmos
rastrear o bug. Por favor gaste algum tempo e esfor¸co preparando um bom relato de erro. O
ideal seria nos enviar um realt´orio no formato encontrato no diret´orio mysql-test/t/rpl*
da ´arvore fonte. Se vocˆe submeter um relat´orio como este, vocˆe pode esperar um patch em
um dia ou dois na maioria dos casos, embora, ´e claro, o tempo pode variar dependendo de
um n´umero de fatores.
Outra op¸ao ´e criar um programa com parˆametros de configura¸ao f´aceis para o mestre e o
escravo que ir˜ao demonstrar o problema em nossos sistemas. Voe pode escreve-lo em Perl
ou em C, dependendo da linguagem que vocˆe tenha mais dom´
inio.
Se vocˆe pode demonstrar o problema com alguma das formas descritas acima, utilize
mysqlbug para preparar um relat´orio de erros e envie-o para bugs@lists.mysql.com. Se
vocˆe tem um fantasma - um problema que s´o pode ser simulado em seu sistema:
Verifique se n˜ao existem erros de usu´ario envolvidos. Por exemplo, se vocˆe atualiza o
escravo fora da thread escrava, os dados podem ficar fora de sincronia e podem ocorrer
viola¸oes de chave ´unica nas atualiza¸oes, neste caso a thread escrava ir´a terminar e
esperar que vocˆe limpe as tabelas manualmente para entrar em sincronia.
Execute o escravo com log-slave-updates elog-bin - isto ir´a registrar todas as
atualiza¸oes no escravo.
Salve todas as evidˆencias antes de restaurar a replica¸ao. Se n˜ao tivermos nenhuma
informa¸ao ou apenas algum esbco, ser´a um pouco mais dif´
icil para rastrearmos o
problema. As evidˆencias que vocˆe deve coletar s˜ao:
Todos os logs bin´arios no mestre
Todos os logs bin´arios no escravo
A sa´
ida de SHOW MASTER STATUS no mestre na hora que vocˆe descobriu o problema.
A sa´
ida de SHOW SLAVE STATUS no mestre na hora que voe descobriu o problema.
Logs de erro no mestre e no escravo
Utilize mysqlbinlog para examinar os logs bin´arios. A informa¸ao a seguir pode ser
´util para encontrar a consulta problem´atica, por exemplo:
mysqlbinlog -j pos_from_slave_status /caminho/para/log_do_escravo | head
Uma vez que vocˆe coletou as evidˆencias do problema fantasma, tente isol´a-lo em um caso
de testes separados inicialmente. Enao relate o problema para bugs@lists.mysql.com
com a maior quantidade poss´
iveis de informa¸oes.
Chapter 5: Otimiza¸ao do MySQL 329
5 Otimiza¸ao do MySQL
Otimiza¸ao ´e uma tarefa complicada porque necessita um entendimento do sistema como
um todo. Enquanto for poss´
ivel fazer algumas otimiza¸oes com pequeno conhecimento de
seu sistema ou aplica¸ao, quanto mais otimizado voe desejar que o seu sistema esteja, mais
ter´a que saber sobre ele.
Este cap´
itulo tentar´a explicar e fornecer alguns exemplos de diferentes formas de otimizar
o MySQL. Lembre-se, no entanto, que sempre existir˜ao (cada vez mais dif´
iceis) formas
adicionais de deixar seu sistema mais r´apido.
5.1 Vis˜ao Geral da Otimiza¸ao
A parte mais importante para obter um sistema r´apido ´e com certeza o projeto b´asico. Vocˆe
tamb´em precisa saber quais tipos de coisas seus sistema estar´a fazendo, e quais s˜ao gargalos
existentes.
Os gargalos mais comuns s˜ao:
Pesquisa em disco ´
E necess´ario tempo para o disco encontrar uma quantidade de dados.
Com discos modernos em 1999, o tempo m´edio para isto era normalmente menor que
10ms, portanto em teoria poder´
iamos fazer 1000 buscas por segundo. Este tempo
melhora moderadamente com discos novos e isso ´e muito dif´
icil otimizar para uma
´unica tabela. A maneira de otimizar isto ´e colocando os dados em mais de um disco.
Leitura de disco/Escrita (I/O) Quando o disco estiver na posi¸ao correta precisaremos
que os dados sejam lidos. Com discos mais modernos em 1999, um disco retorna algo
em torno de 10-20Mb/s. Isto ´e mais f´acil de otimizar que as buscas porque vocˆe pode
ler v´arios discos em paralelo.
Ciclos de CPU. Quando tivermos os dados na mem´oria principal (ou se eles j´a estiverem
a) precisaremos process´a-los para conseguir nosso resultado. O fator de limita¸ao mais
comum ´e ter ppequenas tabelas, comparadas com a mem´oria. Mas, com pequenas
tabelas, normalmente n˜ao teremos problemas com velocidade.
Largura de banda da mem´oria. Quando a CPU precisa de mais dados que podem caber
no cache da CPU a largura da banda da mem´oria principal se torna um gargalo. Isto
´e um gargalo muito incomum para a maioria dos sistema, mas ´e bom estarmos ciente
dele.
5.1.1 Limita¸oes do projeto MySQL/Trocas
Como o MySQL utiliza um bloqueio de tabelas extremamente r´apido (multiplas leituras /
´unica escritas) o maior problema restante ´e um conjunto de um fluxo constante de inser¸oes
e selects lentas na mesma tabela.
os acreditamos que para um grante n´umero de sistemas, a performance extremamente
apida em outros casos faz desta uma escolha vencedora. Isto ´e normalmente poss´
ivel de
ser feito tendo v´arias c´opias da tabela, mas necessita de mais esfor¸co e hardware.
Tamb´em estamos trabalhando em algumas extens˜oes para resolver este problema para al-
guns nichos comuns de aplica¸oes.
330 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
5.1.2 Portabilidade
Como todos os servidores SQL implementam partes diferentes da linguagem SQL, ´e trabal-
hoso escrever aplica¸oes SQL port´aveis. Para inserts e selects muito simples ´e f´acil, mas
quanto mais recurso vocˆe precisa, mais dif´
icil se torna a implementa¸ao. Se vocˆe deseja
uma aplica¸ao que seja r´apida com v´arios bancos de dados a tarefa se tornar´a mais dif´
icil
ainda!
Para fazer uma aplica¸ao complexa port´avel vocˆe precisar´a eleger um n´umero fechado de
servidores SQL para funcionar com seu sistema.
Voe pode utilizar o MySQL programa/web-page crash-me - http://www.mysql.com/information/crash-
me.php - para encontrar fun¸oes, tipos e limites que vocˆe pode utilizar com uma sele¸ao de
servidores de bancos de dados. O Crash-me agora testa quase tudo poss´
ivel, mas continua
compreens´
ivel com aproximadamente 450 itens testados.
Por exemplo, vocˆe n˜ao deve ter nomes de colunas maior do que 18 caracteres se desejar
utilizar o Informix ou DB2.
Os programas de benchmarks e crash-me do MySQL s˜ao bastante independentes do bancos
de dados. Dando uma olhada em como n´os os tratamos, vocˆe pode sentir o que ´e necess´ario
para escrever sua aplica¸ao independente do banco de dados. Os benchmarks podem ser
encontrados no diret´orio ‘sql-bench’ na distribui¸ao fonte do MySQL. Eles s˜ao escritos em
Perl com a interface de banco de dados DBI (que resolve a parte do problema de acesso).
Veja http://www.mysql.com/information/benchmarks.html para os resultados deste
benchmark.
Como pode ser visto nestes resultados, todos os bancos de dados tem alguns pontos fra-
cos. Isto ´e, eles possuem diferentes compromissos de projeto que levam a comportamentos
diferentes.
Se vocˆe procura por independencia de banco de dados, precisar´a ter uma boa id´eia dos
gargalos de cada servidor SQL. O MySQL ´e muito r´apido para recupera¸ao e atualiza¸ao
de dados, mas ter´a problemas em misturar leituras/escritas lentas na mesma tabela. O
Oracle, por outro lado, possui um grande problema quando vocˆe tentar acessar registros
que foram recentemente atualizados (at´e eles serem atualizados no disco). Bancos de dados
transacionais geralmente n˜ao s˜ao muito bons gerando tabelas de resumo das tabelas log,
nestes casos o travamento de registros ´e praticamente in´util.
Para fazer sua aplica¸ao realmente independente de banco de dados, voe precisar´a definir
uma interface que pode ser estendida atrav´es da qual vocˆe far´a a manipula¸ao dos dados.
Como o C++ est´a dispon´
ivel na maioria dos sistemas, faz sentido utilizar classes C++ para
fazer a interface ao banco de dados.
Se vocˆe utilizar algum recurso espec´
ifico para algum banco de dados (como o comando
REPLACE no MySQL), vocˆe deve codificar um m´etodo para os outros serviodores SQL para
implementar o mesmo recurso (mas mais lento). Com o MySQL vocˆe pode utilizar a sintaxe
/*! */ para adicionar palavras chave espec´
ificas do MySQL para uma query. O c´odigo
dentro de /**/ ser´a tratado como um comenario (ignorado) pela maioria dos servidores
SQL.
Se alta performance REAL ´e mais importante que exatid˜ao, como em algumas aplica¸oes
WEB, uma possibilidade ´e criar uma camada de aplica¸ao que armazena todos os resultados
para lhe fornecer uma performance ainda mais alta. Deixando resultados antigos ’expirar’
Chapter 5: Otimiza¸ao do MySQL 331
depois de um tempo, vocˆe pode manter o cache razoavelmente atual. Isto ´e muito bom
no caso de uma carga extremamente pesada, pois neste caso vocˆe pode aumentar o cache
dinamicamente e configurar o tempo de expira¸ao maior at´e que as coisas voltem ao normal.
Neste caso a informa¸ao de cria¸ao de tabelas devem conter informa¸oes do tamanho inicial
do cache e com qual frequˆencia a tabela, normalmente, deve ser renovada.
5.1.3 Para que Utilizamos o MySQL ?
Durante o desenvolvimento inicial do MySQL, os recursos do MySQL foram desenvolvidos
para atender nosso maior cliente. Eles lidam com data warehousing para alguns dos maiores
varejistas na Su´ecia.
De todas as lojas, obtemos resumos semanais de todas as transa¸oes de cart˜oes de bonus e
esperamos fornecer informa¸oes ´uteis para ajudar os donos das lojas a descobrir como suas
campanhas publicit´arias est˜ao afetando seus clientes.
Os dados s˜ao bem grandes (cerca de 7 milh˜oes de transa¸oes por mˆes), e armazenamos dados
por cerca de 4-10 anos que precisamos apresentar para os usu´arios. Recebemos requisi¸oes
semanais dos clientes que desejam ter acesso ’instananeo’ aos novos relat´orios contendo
estes dados.
Resolvemos este problema armazenando todas informa¸oes mensalmente em tabelas com
transa¸oes compactadas. Temos um conjunto de macros (script) que geram tabelas resum-
idas agrupadas por diferentes crit´erios (grupo de produto, id do cliente, loja...) das tabelas
com transa¸oes. Os relat´orios s˜ao p´aginas Web que s˜ao geradas dinamicamente por um
pequeno shell script que analisa uma p´agina Web, executa as instru¸oes SQL na mesma e
insere os resultados. os usariamos PHP ou mod perl mas eles n˜ao estavam dispon´
iveis na
´epoca.
Para dados graficos escrevemos um ferramenta simples em Cque pode produzir GIFs basea-
dos no resultado de uma consulta SQL (com alguns processamentos do resultado). Isto
tamb´em ´e executado dinamicamente a partir do script Perl que analisa os arquivos HTML.
Na maioria dos casos um novo relat´orio pode simplesmente ser feito copiando um script
existente e modificando a consulta SQL no mesmo. Em alguns casos, precisamos adicionar
mais campos a uma tabela de resumo existente ou gerar uma nova, mas isto tamb´em ´e bem
simples, pois mantemos todas as tabelas com as transa¸os no disco. (Atualmente possuimos
pelo menos 50G de tabelas com transa¸oes e 200G de outos dados do cliente.)
os tamb´em deixamos nossos clientes acessarem as tabelas sum´arias diretamente com
ODBC para que os usu´arios avan¸cados possam tamb´em fazer experimentar com os dados.
os n˜ao tivemos nenhum problema lidando com isso em um servidor Sun Ultra SPARC-
station (2x200 Mhz) bem modesto. Atualmente atualizamos um de nossos servidores para
um UltraSPARC com 2 CPUs de 400 Mhz, e planejamos lidar com transa¸oes no n´
ivel
de produto, o que pode significar um aumento de pelo menos dez vezes nosso volume de
dados. Acreditamos que podemos lidar com isto apenas adicionando mais disco aos nossos
sistemas.
Tamb´em estamos experimentando com Intel-Linux para obter mais poder de CPU por um
melhor pre¸co. Agora que possuimos o formato bin´arios do bancos de dados port´aveis (a
partir da vers˜ao 3.23), come¸caremos a utiliz´a-lo para partes da aplica¸ao.
332 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Nossa sensa¸ao inicial ´e que o Linux ir´a atuar muito melhor em cargas baixas a m´edias e o
Solaris ir´a atuar melhor quando vocˆe come¸car a ter uma carga alta pelo uso extremo de IO
de disco, mas ainda n˜ao temos nada conclusivo sobre isto. Depois de algumas discuss˜oes com
um desenvolvedor do Kernel do Linux, conclu´
imos que isto pode ser um efeito colateral do
Linux; fornecer tantos recursos para uma tarefa batch que a performance interativa se torna
muito baixa. Isto deixa a m´aquina muito lenta e sem resposta enquanto grandes batches
estiverem em execu¸ao. Esperamos que isto tenha um tratamento melhor em futuras vers˜oes
do kernel Linux.
5.1.4 O Pacote de Benchmark do MySQL
Esta se¸ao deve conter uma descri¸ao t´ecnica do pacote de benchmarks do MySQL (e
crash-me), mas a descri¸c˜ao ainda n˜ao est´a pronta. Atualmente, vocˆe pode ter uma boa
id´eia do benchmark verificando os c´odigos e resultados no diret´orio ‘sql-bench’ em qualquer
distribui¸ao fonte do MySQL.
Este conjunto de benchmark pretende ser um benchmark que ir´a dizer a qualquer usu´ario
se uma determinada implementa¸ao SQL ir´a atuar bem ou mal.
Notea que este benchmark utiliza uma ´unica thead, portanto ele mede o tempo m´
inimo para
as opera¸oes. Planejamos no futuro adicionar v´arios testes multi-threaded no conjunto de
benchmark.
Por exemplo, (executado na mesma m´aquina NT 4.0):
Lendo 2000000 linhas por ´
indice Segundos Segundos
mysql 367 249
mysql odbc 464
db2 odbc 1206
informix odbc 121126
ms-sql odbc 1634
oracle odbc 20800
solid odbc 877
sybase odbc 17614
Inserindo (350768) linhas Segundos Segundos
mysql 381 206
mysql odbc 619
db2 odbc 3460
informix odbc 2692
ms-sql odbc 4012
oracle odbc 11291
solid odbc 1801
sybase odbc 4802
No teste acima o MySQL foi executado com um cache de ´
indices de 8M.
Temos concentrado alguns resultados de benchmarks em http://www.mysql.com/information/benchmarks.html.
Perceba que a Oracle n˜ao est´a inclu´
ida porque eles solicitaram a remo¸ao. Todos bench-
marks Oracle devem ser aprovados pela Oracle! Acreditamos que os benchmarks da Oracle
ao MUITO tendecioso pois os benchmarks acima devem ser executados supostamente para
uma instala¸ao padr˜ao para um ´unico cliente.
Chapter 5: Otimiza¸ao do MySQL 333
Para executar a suite de benchmarks, vocˆe deve fazer download de uma distribui¸ao fonte
do MySQL, instalar o driver DBI do perl, e o driver DBD do perl para o banco de dados
que desejar testar e depois fazer:
cd sql-bench
perl run-all-tests --server=#
onde # ´e um dos servidores suportados. Voe pode obter uma lista de todos parˆametros e
servidores suportados executando run-all-tests --help.
crash-me tenta determinar quais recursos um banco de dados suporta e quais suas capaci-
dades e limita¸oes atuais para a execu¸ao de consultas. Por exemplo, ele determina:
Quais tipos de colunas s˜ao suportados
Quantos ´
indices s˜ao suportados
Quais fun¸oes s˜ao suportadas
Qual o tamanho m´aximo de uma query
Qual o tamanho m´aximo de um registro do tipo VARCHAR
Podemos encontrar o resultado do crash-me para diversos bancos de dados em
http://www.mysql.com/information/crash-me.php.
5.1.5 Utilizando seus Pr´oprios Benchmarks
Definitivamente vocˆe deve fazer benchmarks de sua aplica¸ao e banco de dados para saber
quais s˜ao os gargalos. Corrigindo (ou substituindo o gargalho com um ’m´odulo burro’) vocˆe
pode facilmente identificar o pr´oximo gargalo (e continuar). Mesmo se a performance geral
para sua aplica¸ao ´e suficiente, vocˆe deve pelo menos criar um plano para cada gargalo e
decidir como resolvˆe-lo se algum dia vocˆe precisar de performance extra.
Para um exemplo de programas de benchmarks port´aveis, consulte o conjunto de bench-
marks do MySQL. See hundefinedi[Benchmarks do MySQL], page hundefinedi. Vocˆe pode
pegar qualquer programa deste conjunto e modific´a-lo para suas necessidades. Fazendo isto
vocˆe pode tentar solu¸oes diferentes para seu problema e testar qual solu¸ao ´e a mais r´apida
para vocˆe.
´
E muito comum que alguns problemas somente ocorram quando o sistema estiver muito
carregado. os tivemos alguns clientes que nos contactaram quando eles testaram um
sistema em produ¸ao e encontraram problemas de carga. Em cada um dos casos, existiam
problemas com projeto b´asico (busca em tabelas n˜ao eram bons com alta carga) ou detalhes
de SO/biblioteca. A maioria destes seriam MUITO mais f´aceis de resolver se os sistemas
a n˜ao estivessem em uso.
Para evitar problemas deste tipo, vocˆe deve colocar algum esfor¸co em testar a performance
de toda sua aplica¸ao sobre a pior carga poss´
ivel! Vocˆe pode utilizar o Super Smack para
isto, e ele est´a dispon´
ivel em: http://www.mysql.com/Downloads/super-smack/super-
smack-1.0.tar.gz. Como o nome sugere, ele pode derrubar seu sistema se vocˆe solicitar,
portanto, utilize-o somente em sistemas de desenvolvimento.
334 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
5.2 Otimizando SELECTs e Outras Consultas
Primeiramente, uma coisa que afeta todas as consultas: Quanto mais complexo seu sistema
de permiss˜oes, maior a sobrecarga.
Se vocˆe n˜ao tiver nenhuma instru¸ao GRANT realizada, MySQL otmizar´a a verifica¸ao de
permiss˜oes de alguma forma. Dessa forma, se vocˆe possui um volume muito alto, o tempo
pode piorar tentando permitir o acesso. Por outro lado, maior verifica¸ao de permiss˜oes
resulta em uma sobrecarga maior.
Se o seu problema ´e com alguma fun¸ao expl´
icita do MySQL, vocˆe pode sempre consultar
o tempo da mesma com o cliente MySQL:
mysql> select benchmark(1000000,1+1);
+------------------------+
| benchmark(1000000,1+1) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.32 sec)
O exemplo acima demonstra que o MySQL pode excutar 1.000.000 express˜oes +em 0.32
segundos em um PentiumII 400MHz.
Todas fun¸oes MySQL devem ser bem otimizadas, mas existem algumas excess˜oes e o
benchmark(loop_count,expression) ´e uma ´otima ferramenta para saber se existe um
problema com sua query.
5.2.1 Sintaxe de EXPLAIN (Obter informa¸oes sobre uma SELECT)
EXPLAIN nome_tabela
ou EXPLAIN SELECT op¸c~oes_select
EXPLAIN nome_tabela ´e um sinˆonimo para DESCRIBE nome_tabela ou SHOW COLUMNS FROM
nome_tabela.
Quando uma instru¸ao SELECT for precedida da palavra chave EXPLAIN, o MySQL explicar´a
como ele deve processar a SELECT, fornecendo informa¸ao sobre como as tabelas est˜ao sendo
unidas e em qual ordem.
Com a ajuda de EXPLAIN, vocˆe pode ver quando devem ser adicionados ´
indices `a tabelas
para obter uma SELECT mais r´apida que utiliza ´
indices para encontrar os registros. Voe
tamb´em pode ver se o otimizador une as tabelas em uma melhor ordem. Para for¸car o
otimizador a utilizar uma ordem espec´
ifica de join para uma instru¸ao SELECT, adicione
uma cl´ausula STRAIGHT_JOIN.
Para liga¸oes mais complexas, EXPLAIN retorna uma linha de informa¸ao para cada tabela
utilizada na instru¸ao SELECT. As tabelas s˜ao listadas na ordem que seriam lidas. O MySQL
soluciona todas as joins utilizando um m´etodo multi-join de varedura simples. Isto significa
que o MySQL lˆe uma linha da primeira tabela, depois encontra uma linha que combina na
segunda tabela, depois na terceira tabela e continua. Quando todas tabelas s˜ao processadas,
ele exibe as colunas selecionadas e recua atrav´es da lista de tabelas at´e uma tabela na qual
existem registros coincidentes for encontrada. O pr´oximo registro ´e lido desta tabela e o
processo continua com a pr´oxima tabela.
A sa´
ida de EXPLAIN inclui as seguintes colunas:
Chapter 5: Otimiza¸ao do MySQL 335
table A tabela para a qual a linha de sa´
ida se refere.
type O tipo de join. Informa¸oes sobre os v´arios tipos s˜ao fornecidas abaixo.
possible_keys
A coluna possible_keys indica quais ´
indices o MySQL pode utilizar para en-
contrar os registros nesta tabela. Note que esta coluna ´e totalmente indepen-
dente da ordem das tabelas. Isto significa que algumas das chaves em possi-
ble keys podem n˜ao ser usadas na pr´atica com a ordem de tabela gerada.
Se esta coluna estiver vazia, n˜ao existem ´
indices relevantes. Neste caso, vocˆe
poder´a melhora a performance de sua query examinando a cl´ausula WHERE para
ver se ela refere a alguma coluna ou colunas que podem ser indexadas. Se for
verdade, crie um ´
indice apropriado e confira a consulta com EXPLAIN novamente.
See hundefinedi[ALTER TABLE], page hundefinedi.
Para ver os ´
indices existentes em uma tabela, utilize SHOW INDEX FROM nome_
tabela.
key A coluna key indica a chave que o MySQL decidiu usar. A chave ser´a NULL
se nenhum ´
indice for escolhido. Se o MySQL escolher o ´
indice errado, vocˆe
provavelmente deve for¸car o MySQL a usar outro ´
indice utilizando myisamchk
--analyze, ou See hundefinedi[myisamchk syntax], page hundefinediou USE
INDEX/IGNORE INDEX. See hundefinedi[JOIN], page hundefinedi.
key_len A coluna key_len indica o tamanho da chave que o MySQL decidiu utilizar.
O tamanho ser´a NULL se key for NULL. Note que isto nos diz quantas partes de
uma chave multi-partes o MySQL realmente est´a utilizando.
ref A coluna ref exibe quais colunas ou contantes s˜ao usadas com a key para
selecionar registros da tabela.
rows A coluna rows informa o n´umero de linhas que o MySQL deve examinar para
executar a consulta.
Extra Esta coluna contem informa¸oes adicionais de como o MySQL ir´a resolver a
consulta. A seguir uma explica¸ao das diferentes strings de texto que podem
ser encontradas nesta coluna:
Distinct O MySQL n˜ao continuar´a a procurar por mais registros para a
combina¸ao de registro atual depois de ter encontrado o primeiro
registro coincidente.
Not exists
O MySQL estava apto a fazer uma otimiza¸ao LEFT JOIN na con-
sulta e n˜ao examinar´a mais registros nesta tabela para a com-
bina¸ao do registro anterior depois que encontrar um registro que
satisfa¸ca o crit´erio do LEFT JOIN.
Exemplo:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
Assume que t2.id ´e definido com NOT NULL. Neste caso o MySQL
ir´a percorrer t1 e procurar pelos registros em t2 atrav´es de t1.id.
Se o MySQL encontrar um registro combinando em t2, ele sabe que
336 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
t2.id nunca poder´a ser NULL e n˜ao ir percorrer at´e o resto dos reg-
istros em t2 que possuirem o mesmo id. Em outras palavras, para
cada registro em t1 o MySQL s´o precisa fazer uma ´unica pesquisa
em t2, independente de quantos registros coincidentes existirem em
t2.
range checked for each record (index map: #)
O MySQL n˜ao encontrou um bom ´
indice para usar. No lugar, ele
ir´a fazer uma verifica¸ao sobre qual ´
indice usar (se existir) para
cada combina¸ao das tabelas precedentes, e usar´a este ´
indice para
recuperar os registros da tabela. Isto n˜ao ´e muito r´apido mas ´e
mais r´apido que fazer um join sem um ´
indice.
Using filesort
O MySQL precisar´a fazer uma passada extra para descobrir como
recuperar os registros na ordem de classifica¸ao. A classifica¸ao ´e
feita indo atrav´es de todos os registros de acordo com join type
e armazenar a chave de ordena¸ao mais o ponteiro para o registro
para todos os registros que combinarem com o WHERE. Enao as
chaves s˜ao classificadas. Finalmente os registros s˜ao recuperados
na ordem de classifica¸ao.
Using index
A informa¸ao da coluna ´e recuperada da tabela utilizando somente
informa¸oes na ´arvore de ´
indices sem ter que fazer uma pesquisa
adicional para ler o registro atual. Isto pode ser feito quando todas
as colunas usadas para a tabela fizerem parte do mesmo ´
indice.
Using temporary
Para resolver a consulta, o MySQL precisar´a criar uma tabela tem-
por´aria para armazenar o resultado. Isto acontece normalmente se
vocˆe fizer um ORDER BY em um conjunto de colunas diferentes das
quais vocˆe fez um GROUP BY.
Where used
Uma cl´ausula WHERE ser´a utilizada para restringir quais registros
ser˜ao combinados com a pr´oxima tabela ou enviar para o cliente.
se vocˆe n˜ao possui esta informa¸ao e a tabela ´e do tipo ALL ou
index, pode existir alguma coisa errada na sua query (Se vocˆe n˜ao
pretender examinar todos os registros da tabela).
Se vocˆe desejar deixar suas consultas o mais r´apido poss´
ivel, vocˆe deve dar uma
olhada em Using filesort eUsing temporary.
Os diferentes tipos de joins est˜ao listados abaixo, ordenados do melhor para o pior tipo:
system A tabela tem somente um registro (= tabela de sistema). Este ´e um caso
especial do join do tipo const.
const A tabela possui pelo menos um registro coincidente, que ser´a lido no in´
icio da
consulta. Como s´o h´a um registro, valores da coluna neste registro podem ser
tratados como contantes pelo otimizador at´e o final. Tabelas const ao muito
apidas como elas s˜ao lidas somente uma vez!
Chapter 5: Otimiza¸ao do MySQL 337
eq_ref Um registro ser´a lido desta tabela para cada combina¸ao de registros das tabelas
anteriores. Este ´e o melhor tipo poss´
ivel de join, depois dos tipos const. Ele ´e
utilizado quando todas as partes de um ´
indice s˜ao usados pelo join e o ´
indice
for UNIQUE ou um PRIMARY KEY.
ref Todos os registros com valores de ´
indices combinando ser˜ao lidos desta tabela
para cada combina¸ao de registros das tabelas anteriores. ref ´e utilizado se
o join usar somente o prefixo mais a esquerda da chave, ou se a chave n˜ao
for UNIQUE ou uma PRIMARY KEY (em outras palavras, se a liga¸ao n˜ao pode
selecionar um ´unico registro baseado no valor da chave). Se a chave usada
coincidir apenas com poucos registros este tipo de join ´e de boa qualidade.
range Ser˜ao recuperados somentes os registros que estiverem dentro de uma faixa
dada, utilizando um ´
indice para selecionar os registros. A coluna key indica
qual ´
indice ´e usado. O key_len contem a parte mais longa da chave foi usada.
A coluna ref ser´a NULL para este tipo.
index Isto ´e o mesmo que ALL, exceto que somente a ´arvore de ´
indice ´e lida. Isto
normalmente ´e mais r´apido que ALL a que o arquivo de ´
indice ´e normalmente
menor que o arquivo de dados.
ALL Uma pesquisa completa ser´a feita na tabela para cada combina¸ao de registros
das tabelas anteriores. Isto normalmente n˜ao ´e bom se a tabela ´e a primeira
ao marcada com const, e normalmente muito ruim em todos os outros casos.
Normalmente vocˆe pode evitar ALL adicionando mais ´
indices, assim o registro
pode ser recuperado baseado em valores contantes ou valores de colunas de
tabelas anteriores.
Voe pode ter uma boa indica¸ao de qu˜ao boa ´e sua join multiplicando todos os valores
na coluna rows na sa´
ida de EXPLAIN. Isto deve dizer a grosso modo quantos registros o
MySQL deve examinar para executar a consulta. Este n´umero ´e tamb´em usado quando
vocˆe restringe consultas com a vari´avel max_join_size. See hundefinedi[Parˆametros de
servidor], page hundefinedi.
O exemplo a seguir mostra como um JOIN pode ser otimizado progressivamente utilizando
a informa¸ao fornecida por EXPLAIN.
Suponha que vocˆe tem a instru¸ao SELECT exibida abaixo, que vocˆe est´a examinando uti-
lizando EXPLAIN:
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
tt.ProjectReference, tt.EstimatedShipDate,
tt.ActualShipDate, tt.ClientID,
tt.ServiceCodes, tt.RepetitiveID,
tt.CurrentProcess, tt.CurrentDPPerson,
tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
et_1.COUNTRY, do.CUSTNAME
FROM tt, et, et AS et_1, do
WHERE tt.SubmitTime IS NULL
AND tt.ActualPC = et.EMPLOYID
AND tt.AssignedPC = et_1.EMPLOYID
AND tt.ClientID = do.CUSTNMBR;
Para este exemplo, assuma que:
338 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
As colunas comparadas foram declaradas como a seguir:
Tabela Coluna Tipo da coluna
tt ActualPC CHAR(10)
tt AssignedPC CHAR(10)
tt ClientID CHAR(10)
et EMPLOYID CHAR(15)
do CUSTNMBR CHAR(15)
As tabelas possuem os ´
indices mostrados abaixo:
Tabela ´
Indice
tt ActualPC
tt AssignedPC
tt ClientID
et EMPLOYID (chave prim´aria)
do CUSTNMBR (chave prim´aria)
Os valores tt.ActualPC ao foram distribu´
idos de maneira uniforme.
Inicialmente, antes de ser feita qualquer otimiza¸ao, a instru¸ao EXPLAIN produzia a seguinte
informa¸ao.
table type possible_keys key key_len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
do ALL PRIMARY NULL NULL NULL 2135
et_1 ALL PRIMARY NULL NULL NULL 74
tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872
range checked for each record (key map: 35)
Como o tipo ´e ALL em todas tabelas, esta sa´
ida indica que o MySQL est´a fazendo uma
liga¸ao completa em todas as tabelas! Isto levar´a muito tempo para ser executado, pois o
produto do n´umero de registros em cada tabela deve ser examinado ! Neste caso, existem
74 * 2135 * 74 * 3872 registros. Se as tabelas forem maiores, imagine quanto tempo este
tipo de consulta pode demorar.
Um dos problemas aqui ´e que o MySQL n˜ao pode (ainda) utilizar ´
indices em colunas de
maneira eficiente se elas foram declaras ide forma diferente. Neste contexto, VARCHAR e
CHAR ao o mesmo a menos que tenham sido declarados com tamanhos diferentes. Como
tt.ActualPC ´e declarado como CHAR(10) eet.EMPLOYID ´e declarado como CHAR(15), existe
aqui uma diferen¸ca de tamanho.
Para corrigir esta diferen¸ca entre tamanhos de registros, utilize ALTER TABLE para alterar o
tamanho de ActualPC de 10 para 15 caracteres:
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
Agora ambos campos tt.ActualPC eet.EMPLOYID ao VARCHAR(15). Executando a in-
stru¸ao EXPLAIN novamente produzir´a este resultado:
table type possible_keys key key_len ref rows Extra
tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used
do ALL PRIMARY NULL NULL NULL 2135
range checked for each record (key map: 1)
et_1 ALL PRIMARY NULL NULL NULL 74
range checked for each record (key map: 1)
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
Chapter 5: Otimiza¸ao do MySQL 339
Isto n˜ao est´a perfeito, mas est´a bem melhor ( o produto dos valores de rows agora menor
por um fator de 74 ). Esta vers˜ao ´e executada em v´arios segundos.
Uma segunda altera¸ao pode ser feita para eliminar as diferen¸cas de tamanho das colunas
para as compara¸oes tt.AssignedPC = et_1.EMPLOYID ett.ClientID = do.CUSTNMBR :
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
MODIFY ClientID VARCHAR(15);
Agora EXPLAIN produz a sa´
ida mostrada abaixo:
table type possible_keys key key_len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
tt ref AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
Este resultado ´e quase o melhor que se pode obter.
O problema restante ´e que, por padr˜ao, o MySQL assume que valores na coluna
tt.ActualPC est˜ao distribu´
idos igualmente, e este n˜ao ´e o caso para a tabela tt.
Felizmente, ´e f´acil informar ao MySQL sobre isto:
shell> myisamchk --analyze caminho_para_banco_dados_MySQL/tt
shell> mysqladmin refresh
Agora a join est´a perfeita, e EXPLAIN produz esta sa´
ida:
table type possible_keys key key_len ref rows Extra
tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
Perceba que a coluna rows na sa´
ida de EXPLAIN ´e uma boa ajuda para otimizador de joins
do MySQL. Para otimizar uma consulta, vocˆe deve conferir se os n´umeros est˜ao perto da
realidade. Se n˜ao, vocˆe pode obter melhor desempenho utilizando STRAIGHT_JOIN em sua
instru¸ao SELECT e tentar listar as tabelas em uma ordem diferente na cl´ausula FROM.
5.2.2 Estimando o Desempenho de uma Consulta
Na maioria dos casos vocˆe pode estimar a performance contando buscas em disco. Para
tabelas pequenas, normalmente vocˆe pode encontrar o registro com 1 pesquisa em disco
(uma vez que o ´
indice provavelmente est´a no cache). Par tabelas maiores, vocˆe pode esti-
mar (usando ind´
ices de arvores B++) que vocˆe precisar´a de: log(row_count) / log(index_
block_length / 3 * 2 / (index_length + data_pointer_length)) + 1 buscas em disco
para encontrar um registro.
No MySQL um bloco de ´
indice tem geralmente 1024 bytes e o ponteiro de dados 4 bytes.
Uma tabela de 500.000 registros com um ´
indice com tamanho de 3 (inteiro m´edio) lhe d´a:
log(500,000)/log(1024/3*2/(3+4)) + 1 = 4 pesquisas.
Como o ´
indice acima necessita cerca de 500,000 * 7 * 3/2 = 5.2M, (assumindo que os buffers
de ´
indices s˜ao carregados at´e 2/3, que ´e o normal) vocˆe provavelmente ter´a grande parte
dos ´
indices em mem´oria e provavelmente precisar´a somente de 1 ou 2 chamadas para ler
dados do SO para encontrar o registro.
340 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Entretanto, para escritas, vocˆe precisar´a utilizar 4 requisi¸oes para encontrar onde posi-
cionar o novo ´
indice e normalmente 2 buscas para atualizar o ´
indice e escrever o registro.
Perceba que o que foi dito acima n˜ao significa que sua aplica¸ao perder´a performance por N
log N! Como tudo ´e armazenado no cache de seu SO ou do servidor SQL as coisas come¸car˜ao
a ficar um pouco mais lentas quando as tabelas come¸carem a crescer. Quando os dados se
tornam muito grandes para o cache, as coisas come¸car˜ao a ficar bem mais lentas at´e que suas
aplica¸oes estejam limitadas a buscas em disco (o que aumenta em N log N). Para evitar
isto, aumente o cache de ´
indice quando os dados crescerem. See hundefinedi[Parˆametros
do servidor], page hundefinedi.
5.2.3 Velocidade das Consultas que Utilizam SELECT
Em geral, quando vocˆe desejar tornar uma consulta lenta SELECT ... WHERE mais r´apida, a
primeira coisa que deve ser conferida ´e se vocˆe pode ou n˜ao adicionar um ´
indice. See hun-
definedi[´
indices MySQL], page hundefinedi. Todas as referˆencias entre diferentes tabelas
devem ser feitas normalmente com ´
indices. Voe pode utilizar o comando EXPLAIN para
determinas quais ´
indices s˜ao usados para uma SELECT. See hundefinedi[EXPLAIN], page hun-
definedi.
Algumas dicas gerais:
Para ajudar o MySQL a otimizar melhor as consultas, execute myisamchk --analyze
em uma tabela depois dela ter sido carregada com dados relevantes. Isto atualiza um
valor para cada parte do ´
indice que indica o n´umero m´edio de registros que tem o
mesmo valor. (Para ´
indices ´unicos, isto ´e sempre 1, ´e claro). O MySQL usar´a isto
para decidir qual ´
indice escolher quando vocˆe conectar duas tabelas utilizando uma
’express˜ao n˜ao constante’. Os resultados de analyze podem ser conferidos utilizando
SHOW INDEX FROM nome_tabela e examindo a coluna Cardinality.
Para ordenar um ´
indice e dados de acordo com um ´
indice, utilize myisamchk --sort-
index --sort-records=1 (se vocˆe deseja ordenar pelo ´
indice 1). Se vocˆe possui um
´
indice unico no qual deseja ler todos registros na ordem do ´
indice, esta ´e uma boa forma
para torn´a-lo mais r´apido. Perceba entretanto, que esta ordena¸ao n˜ao foi escrita de
maneira otimizada e levar´a muito tempo em tabelas grandes!
5.2.4 Como o MySQL Otimiza Cl´ausulas WHERE
As otimiza¸oes WHERE ao colocadas aqui na parte da SELECT porque normalmente elas
ao usadas com SELECT, mas as mesmas otimiza¸oes aplicam-se para WHERE em instru¸oes
DELETE eUPDATE.
Note tamb´em que esta se¸ao est´a incompleta. O MySQL faz v´arias otimiza¸oes e ainda n˜ao
tivemos tempo para documentarmos todas elas.
Algumas das otimiza¸oes feitas pelo MySQL s˜ao s˜ao listadas abaixo:
Remo¸ao de parˆenteses desnecess´arios:
((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
Enla¸cos de constantes:
(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
Chapter 5: Otimiza¸ao do MySQL 341
Remo¸ao de condi¸oes contantes (necess´ario por causa dos enla¸cos de contantes):
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
Express˜oes constantes utilizadas por ´
indices s˜ao avaliadas somente uma vez.
COUNT(*) em uma ´unica tabela sem um WHERE ´e recuperado diretamente da informa¸ao
da tabela. Isto tamb´em ´e feito para qualquer express˜ao NOT NULL quando usada somente
com uma tabela.
Pr´e detec¸ao de express˜oes contantes inalidas. O MySQL detecta rapidamente que
algumas instru¸oes SELECT ao imposs´
iveis e n˜ao retornar´a registros.
HAVING ´e fundido com WHERE se n˜ao for utilizado GROUP BY ou fun¸oes de agrupamento
(COUNT(),MIN()...).
Para cada sub-join, um WHERE mais simples ´e constru´
ido para obter uma avalia¸ao mais
apida de WHERE para cada sub-join e tamb´em para saltar registros da maneira mais
apida poss´
ivel.
Todas tabelas constantes s˜ao lidas primeiro, antes de qualquer tabelas na consulta.
Uma tabela constante ´e:
Uma tabela vazia ou uma tabela com 1 registro.
Uma tabela que ´e usada com uma cl´ausula WHERE em um ´
indice UNIQUE, ou uma
PRIMARY KEY, onde todas as partes do ´
indice s˜ao usadas com express˜oes constantes
e as partes do ´
indice s˜ao definidas como NOT NULL.
Todas as tabelas seguintes s˜ao usadas como tabelas constantes:
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
A melhor combina¸ao de join para unir as tabelas ´e encontrada tentando todas as
possibilidades. Se todas colunas em ORDER BY e em GROUP BY vierem da mesma tabela,
enao esta tabela ser´a preferencialmente a primeira na uni˜ao.
Se existerem uma cl´ausula ORDER BY e uma GROUP BY diferente, ou se a ORDER BY ou
GROUP BY conterem colunas de tabelas diferentes da primeira tabela na fila de join, uma
tabela tempor´aria ser´a criada.
Se vocˆe utilizar SQL_SMALL_RESULT, o MySQL usar´a a tabela tempor´aria em mem´oria.
Cada ´
indice de tabela ´e consultado e o melhor ´
indice que cobrir menos de 30% dos
registros ´e usado. Se nenhum ´
indice for encontrado, uma varredura r´apida ´e feita pela
tabela.
Em alguns casos, o MySQL pode ler registros do ´
indice mesmo sem consultar o arquivo
de dados. Se todas colunas usadas do ´
indice s˜ao num´ericas, enao somente a ´arvore de
´
indice ´e usada para resolver a consulta.
Antes de dar sa´
ida em cada registro, aqueles que n˜ao combinam com a cl´ausula HAVING
ao ignorados.
Alguns exemplos de consultas muito r´apidas:
mysql> SELECT COUNT(*) FROM nome_tabela;
mysql> SELECT MIN(key_part1),MAX(key_part1) FROM nome_tabela;
mysql> SELECT MAX(key_part2) FROM nome_tabela
342 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
WHERE key_part_1=constant;
mysql> SELECT ... FROM nome_tabela
ORDER BY key_part1,key_part2,... LIMIT 10;
mysql> SELECT ... FROM nome_tabela
ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
As seguintes consultas s˜ao resolvidas utilizando somente a ´arvore de ´
indices (assumindo que
as colunas indexadas s˜ao num´ericas):
mysql> SELECT key_part1,key_part2 FROM nome_tabela WHERE key_part1=val;
mysql> SELECT COUNT(*) FROM nome_tabela
WHERE key_part1=val1 AND key_part2=val2;
mysql> SELECT key_part2 FROM nome_tabela GROUP BY key_part1;
As consultas a seguir utilizam indexa¸ao para recuperar os registros na ordem de classi-
fica¸ao sem um passo de ordena¸ao separado:
mysql> SELECT ... FROM nome_tabela ORDER BY key_part1,key_part2,... ;
mysql> SELECT ... FROM nome_tabela ORDER BY key_part1 DESC,key_part2 DESC,... ;
5.2.5 Como o MySQL Otimiza Cl´ausulas DISTINCT
DISTINCT ´e convertido em GROUP BY em todas as colunas. DISTINCT combinado com ORDER
BY tamb´em ir´a em v´arios casos criar uma tabela tempor´aria.
Quando combinando LIMIT # com DISTINCT, o MySQL ir´a parar logo que encontrar #
registros ´unicos.
Se vocˆe n˜ao utiliza colunas de todas tabelas usadas, o MySQL ir´a parar a varredura das
tabelas n˜ao usadas logo que encontrar a primeira coincidˆencia.
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
Neste caso, assumindo que t1 ´e usando antes de t2 (confira com EXPLAIN), MySQL ir´a parar
de ler de t2 (para aquele registro particular em t1) quando o primeiro registro em t2 for
encontrado.
5.2.6 How MySQL Optimizes LEFT JOIN and RIGHT JOIN
A LEFT JOIN B no MySQL ´e implementando como a seguir:
A tabela B´e configurada para ser dependente da tabela Ae de todas as tabelas das
quais Adepende.
A tabela A´e configurada para ser dependente de todas as tabelas (exceto B) que s˜ao
usadas na condi¸ao LEFT JOIN.
Todas as condi¸oes LEFT JOIN ao movidas para a cl´ausula WHERE.
Todas as otimiza¸oes padr˜oes de join s˜ao feitas, com a excess˜ao que uma tabela ´e sempre
lida depois de todas as tabelas das quais ´e dependente. Se existir uma dependˆencia
circular o MySQL ir´a emitir um erro.
Todas as otimiza¸oes padr˜oes de WHERE ao realizadas.
Se existir um registro em Aque coincida com a cl´ausula WHERE, mas n˜ao existir nenhum
registro em Bque comincida com a condi¸ao LEFT JOIN ent˜ao um registro extra em B
´e gerado com todas as colunas com valor NULL.
Chapter 5: Otimiza¸ao do MySQL 343
Se vocˆe utiliza LEFT JOIN para encontrar registros que n˜ao existem em alguma tabela e
est´a usando o seguinte teste: nome_coluna IS NULL na parte WHERE, onde nome colun
´e um campo que ´e declarado como NOT NULL, ent˜ao o MySQL para de pesquisar por
mais registros (para uma combina¸ao particular de chaves) depois de ter encontrado
um registro que combinar com a condi¸ao LEFT JOIN.
RIGHT JOIN ´e implementado de forma an´aloga `a LEFT JOIN.
A ordem de leitura das tabelas for¸cada por LEFT JOIN eSTRAIGHT JOIN ir´a ajudar o
otimizador de joins (que calcula em qual ordem as tabelas devem ser unidas) a fazer seu
trabalho mais rapidamente, j´a que haver˜ao poucas permuta¸oes de tabelas a serem conferi-
das.
Perceba que o texto acima significa que se vocˆe fizer uma consulta do tipo:
SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
O MySQL ir´a fazer uma pesquisa completa em ba que o LEFT JOIN ir´a for¸ca-lo a ser lido
antes de d.
A corre¸ao neste caso ´e alterar a consulta para:
SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
5.2.7 Como o MySQL Otimiza Cl´ausulas LIMIT
Em alguns casos o MySQL ir´a tratar a consulta de maneira diferente quando vocˆe estiver
utilizando LIMIT # e n˜ao estiver utilizando HAVING:
Se vocˆe estiver selecionando apenas alguns registros com LIMIT, o MySQL usar´a ´
indices
em alguns casos quando ele normalmente preferiria fazer uma varredura completa na
tabela.
Se vocˆe utilizar LIMIT # com ORDER BY, O MySQL ir´a terminar a ordena¸ao logo que
ele encontrar os primeiros #registros em vez de ordenar a tabela inteira.
Ao combinar LIMIT # com DISTINCT, o MySQL ir´a parar logo que ele encontrar #
registros ´unicos.
Em alguns casos um GROUP BY pode ser resolvido lendo a chave em ordem (ou fazer
uma classifica¸ao na chave) e enao calcular resumos at´e o valor da chave alterar. Neste
caso, LIMIT # ao ir´a calcular nenhum GROUP BY desnecess´ario.
Logo que o MySQL enviar os primeiros #registros para o cliente, ele ir´a abortar a
consulta.
LIMIT 0 ir´a sempre retornar rapidamente um conjunto vazio. Isto ´e util para conferir
a consulta e obter os tipos de campos do resultado.
O tamanho das tabelas tempor´arias usa LIMIT # para calcular quanto de espa¸co ´e
necess´ario para resolver a consulta.
5.2.8 Performance das Consultas que Utilizam INSERT
O tempo para inserir um registro consiste aproximadamente de:
Conex˜ao: (3)
Enviar a consulta para o servidor: (2)
344 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Analisar a consulta (2)
Inserir o registro: (1 x size of record)
Inserir os ´
indices: (1 x number of indexes)
Fechar: (1)
onde os n´umeros s˜ao de certa forma proporcionais ao tempo total. Isto n˜ao leva em con-
siderac˜ao o sobrecarga inicial para abrir tabelas (que ´e feita uma vez para cada consulta
concorrente em execu¸ao).
O tamanho da tabela diminuem a velocidade da inser¸ao de ´
indices em N log N (Arvores
B).
Algumas maneiras de acelerar as inser¸oes:
Se vocˆe estiver inserindo v´arios registros do mesmo cliente ao mesmo tempo, utilize
instru¸oes INSERT com listas de m´ultiplos valores. Isto ´e muito mais r´apido (muitas
vezes em alguns casos) do que utilizar instru¸oes INSERT separadas.
Se vocˆe inserir v´arios registros de diferentes clientes, vocˆe pode obter velocidades mais
altas utilizando a instru¸ao INSERT DELAYED. See hundefinedi[INSERT], page hunde-
finedi.
Perceba que com MyISAM vocˆe pode inserir registros ao mesmo tempo que SELECTs
estejam executando se n˜ao existirem registros apagados nas tabelas.
Ao carregar uma tabela de um arquivo texto, utilize LOAD DATA INFILE. Isto ´e normal-
mente 20 vezes mais r´apido do que utilizar v´arias instru¸c˜oes INSERT See hundefinedi
[LOAD DATA], page hundefinedi.
´
E poss´
ivel com algum trabalho extra fazer o LOAD DATA INFILE executar ainda mais
apido quando a tabela tiver v´arios ´
indices. Utilize o seguinte procedimento:
1. Opcionalmente crie a tabela com CREATE TABLE. Por exemplo, utilizando mysql
ou Perl-DBI.
2. Execute a instru¸ao FLUSH TABLES ou o comando shell mysqladmin flush-tables.
3. Utilize myisamchk --keys-used=0 -rq /path/to/db/nome_tabela. Isto
remover´a o uso de todos os ´
indices da tabela.
4. Insira dados na tabela com LOAD DATA INFILE. Isto n˜ao atualizar´a ´
indices e ser´a
muito mais r´apido.
5. Se no futuro vocˆe precisar da tabela somente para leitura, execute myisampack na
mesma para torn´a-la menor. See hundefinedi[Formato compactado], page hunde-
finedi.
6. Recrie os ´
indices com myisamchk -r -q /caminho/para/bd/nome_tabela. Isto
criar´a a ´arvore de ´
indices em mem´oria antes de escrevˆe-la para o disco, que ´e
muito mais r´apido porque evita que seja feita muita busca disco. A ´arvore de
´
indices resultante ´e tamb´em balanceada perfeitamente.
7. Execute uma instru¸ao FLUSH TABLES ou o comando shell mysqladmin flush-
tables.
Este procedimento ir´a ser construido dentro de LOAD DATA INFILE em alguma vers˜ao
futura do MySQL.
Voe pode acelar inser¸oes bloqueando suas tabelas:
Chapter 5: Otimiza¸ao do MySQL 345
mysql> LOCK TABLES a WRITE;
mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
mysql> INSERT INTO a VALUES (8,26),(6,29);
mysql> UNLOCK TABLES;
A principal diferen¸ca na velocidade ´e que o buffer de ´
indices ´e descarregado no disco
somente uma vez, depois de todas instru¸oes INSERT term sido completadas. Normal-
mente existiria tantas descargas do buffer de ´
indices quanto instru¸oes INSERT difer-
entes. O bloqueio n˜ao ´e necess´ario se vocˆe pode inserir todos registros com uma simples
instru¸ao.
O bloqueio ir´a tamb´em diminuir o tempo total de testes de multi-conex˜oes, mas o
tempo m´aximo de espera para algumas threads ir´a aumentar (porque eles esperam
pelos bloqueios). Por exemplo:
thread 1 faz 1000 inser¸c~oes
thread 2, 3 e 4 faz 1 inser¸c~ao
thread 5 faz 1000 inser¸c~oes
Se vocˆe n˜ao estiver usando travas, 2, 3 e 4 ir˜ao terminar antes de 1 e 5, Se estiver
utilizando travas, 2, 3 e 4 provavelmente n˜ao ir˜ao terminar antes de 1 ou 5, mas o
tempo total deve ser cerca de 40% mais r´apido.
Como as opera¸oes INSERT,UPDATE eDELETE ao muito r´apidas no MySQL, vocˆe obter´a
melhor perfomance geral adicionando travas em tudo que fizer mais que cerca de 5
inser¸oes ou atualiza¸oes em um registro. Se vocˆe fizer v´arias inser¸oes em um registro,
vocˆe pode utilizar LOCK TABLES seguido de um UNLOCK TABLES de vez em quando (em
torno de 1000 registro) para permitr que outras threads acessem a tabela. Isto tamb´em
continua mostrando um bom ganho de performance.
Com certeza, LOAD DATA INFILE ´e muito mais r´apido para carregar dados.
Para obter mais velocidade para LOAD DATA INFILE eINSERT, aumente o tamanho do buffer
de chaves. See hundefinedi[Parˆametros de servidor], page hundefinedi.
5.2.9 Performance das Consultas que Utilizam UPDATE
Consultas de atualiza¸ao s˜ao otimizadas como uma consulta que usa SELECT com a sobre-
carga adicional de escrita. A velocida da escrita depende do tamanho dos dados e do n´umero
de ´
indices que ser˜ao atualizados. ´
Indices que n˜ao forem alterados n˜ao ser˜ao atualizados.
Outra forma para obter atualiza¸oes r´apidas ´e atrasar as atualiza¸oes e ent˜ao fazer v´arias
atualiza¸oes em um registro posteriormente. Fazer v´arias atualiza¸oes em um registro ´e
muito mais r´apido do que fazer uma por vez se vocˆe travar a tabela.
Perceba que, com formato de registros dinˆamicos, atualizar um registro para um valor maior
que o tamanho total pode dividir o registro. Portanto, se vocˆe faz isso frequentemente,
´e muito importante usar OPTIMZE TABLE de vez em quando. See hundefinedi[OPTIMIZE
TABLE], page hundefinedi.
5.2.10 Performance das Consultas que Utilizam DELETE
Se vocˆe deseja apagar todos os registros em uma tabela, deve usar TRUNCATE TABLE nome_
tabela. See hundefinedi[TRUNCATE], page hundefinedi.
346 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O tempo para apagar um registro ´e exatamente proporcional ao n´umero de ´
indices. Para
apagar registros mais rapidamente, vocˆe pode aumentar o tamanho do cache de ´
indices.
See hundefinedi[Parˆametros do servidor], page hundefinedi.
5.2.11 Mais Dicas sobre Otimiza¸oes.
Dicas n˜ao ordenadas para sistemas r´apidos:
Utilize conex˜oes persistentes aos banco de dados para evitar a sobrecarga da conex˜ao.
Se vocˆe n˜ao poder utilizar conex˜oes persistentes e for fazer v´arias novas conex˜oes para
o banco de dados, vocˆe pode desejar alterar o valor da vari´avel thread_cache_size.
See hundefinedi[Parˆametros do servidor], page hundefinedi.
Sempre verifique se todas as suas consultas realmente utilizam os ´
indices que foram
criados nas tabelas. No MySQL vocˆe pode fazer isto com o comando EXPLAIN. See
hundefinedi[Explain], page hundefinedi.
Tente evitar consultas SELECT complexas em tabelas que s˜ao muito atualizadas. Isto
evita problemas com travamento de tabelas.
As novas tabelas MyISAM permitem inserir registros em uma tabela sem registros apa-
gados ao mesmo tempo que outra tabela a estiver lendo. Se este recurso ´e importante
para vocˆe, deve considerar m´etodos onde vocˆe n˜ao tem que apagar registrou ou executar
OPTIMIZE TABLE depois de ter apagado v´arios registros.
Utilize ALTER TABLE ... ORDER BY expr1,expr2... se vocˆe na maioria das vezes re-
cupera registros na ordem expr1,expr2... Utilizando esta op¸ao depois de grandes
altera¸oes para a tabela, pode lhe dar um ganho de performance.
Em alguns casos pode fazer sentido introduzir uma coluna ’hash’ baseada nas
informa¸oes das outras colunas. Se esta coluna for curta e razoavelmente ´unica
pode ser muito mais r´apido do que ter um grande ´
indice em v´arias colunas. No
MySQL ´e muito f´acil usar esta coluna extra: SELECT * FROM nome_tabela WHERE
hash=MD5(concat(col1,col2)) AND col_1=’constante’ AND col_2=’constante’
Para tabelas que alteram muito vocˆe deve tentar evitar todas colunas VARCHAR ou BLOB.
Voe ter´a tamanho de registro dinˆamico assim que usar um simples campo VARCHAR ou
BLOB. See hundefinedi[Tipos de tabelas], page hundefinedi.
Normalmente n˜ao ´e muito ´util cortar uma tabela em diferentes tabelas apenas porque
os registros est˜ao ’grandes’. Para acessar um registro, o maior problema para a per-
formance ´e a busca em disco para encontra o primeiro byte do registro. Depois de
encontrar os dados a maioria dos novos discos podem ler o registro inteiro r´apido o
bastante para a maioria das aplica¸oes. Os ´unicos caos onde realmente faz sentido
dividir uma tabela ´e se ela ´e uma tabela de registros com tamanho dinˆamico (veja
acima) que vocˆe pode alterar para um tamanho fixo, ou se vocˆe frequentemente precisa
examinar a tabela e n˜ao precisa da maioria das colunas. See hundefinedi[Tipos de
tabela], page hundefinedi.
Se frequentemente vocˆe precisar calcular alguma coisa baseada em informa¸ao de v´arios
registros (ex: contagem de registros), provavlmente ´e melhor introduzir uma nova
tabela e atualizar o contador em tempo real. Uma atualiza¸ao do tipo UPDATE table
set count=count+1 where index_column=constante ´e muito rapida!
Chapter 5: Otimiza¸ao do MySQL 347
Isto ´e realmente importante quando voe usa bancos de dados como o MySQL que s´o
tem travamento de tabelas (multiplos leituras/escrita ´unica). Isto tamb´em dar´a melhor
performance com a maioria dos banco de dados, j´a que o gerenciador de bloqueio de
registro ter´a menos a fazer neste caso.
Se vocˆe precisar colterar estatisicas de tabelas maiores, utilize tabelas resumo em vez
de buscar em toda a tabela. Manter os resumos deve ser mais r´apido que tentar criar
estatit´
iscas instantaneamente. ´
E muito mais r´apido criar novas tabelas atrav´es dos logs
quando as coisas mudam (dependendo das descis˜oes de neg´ocio) que ter que alterar a
aplica¸ao em execu¸ao.
Se poss´
ivel, deve-se classificar relat´orios como ’instantˆaneo’ ou ’estat´
isticos’ onde os
dados necess´arios para relat´orios estai´
isticos s˜ao gerados apenas com base nas tabelas
resumo que s˜ao geradas a partir dos dados atuais.
Tire vantagem do fato de que a coluna tem valores padr˜oes. Insira valores explicita-
mente apenas quando os valores a serem inseridos diferem do padr˜ao. Isto reduz a
analise que o MySQL precisa fazer e aumenta a velocidade de inser¸ao.
Em alguns casos ´e conveniente empacotar e armazenar os dados em um campo
blob. Neste caso vocˆe deve adicionar algum c´odigo em sua aplica¸ao para
empacotar/desempacotar as coisas no campo blob, mas isto pode poupar v´arios
acessos a algum est´agio. Isto ´e pr´atico quando vocˆe possui dados que n˜ao conformam
com uma estrutura est´atica de tabela.
Normalmente, vocˆe deve tentar manter todos dados n˜ao-redundantes (o que ´e chamado
de 3a forma normal na teoria de bancos de dados), mas vocˆe n˜ao deve ter medo de
duplicar alguns itens ou criar tabelas de resumo se vocˆe precisar delas para ganhar
mais velocidade.
Stored Procedures ou UDF (fun¸oes definidas pelo usu´arios) pode ser uma boa forma
para obter mais performance. Neste caso vocˆe deve, entretanto, sempre ter uma
maneira de fazer isso de outra maneira (mais lenta) se vocˆe utilizar algum banco de
dados que n˜ao suporta isto.
Voe pode sempre ganhar velocidade fazendo cache de perguntas/respostas na sua
aplica¸ao e tentando fazer v´arias inser¸oes/atualiza¸oes ao mesmo tempo. Se seu banco
de dados suporta travamento de tabelas (como o MySQL e Oracle), isto deve ajudar
a garantir que o cache de ´
indices ´e descarregado somente uma vez depois de todas
atualiza¸oes.
Use INSERT /*! DELAYED */ quando n˜ao precisar saber quando os dados s˜ao gravados.
Isto melhora a velocidade porque v´arios registros podem ser gravados com uma simples
escrita em disco.
Use INSERT /*! LOW_PRIORITY */ quando vocˆe desejar que suas consultas sejam mais
importantes.
Use SELECT /*! HIGH_PRIORITY */ para obter consultas que ignoram a fila. Isto ´e, a
consulta ´e feita mesmo se alguem estiver esperando para fazer uma escrita.
Use a instru¸ao INSERT multi-linhas para armazenar v´arios registros com um comando
SQL (v´arios servidores SQL suportam isto).
Use LOAD DATA INFILE para carregar volumes maiores de dados. Isto ´e mais r´apido que
as inser¸oes normais e mais r´apido at´e quando o myisamchk for integrado no mysqld.
348 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Use colunas AUTO_INCREMENT para garantir valores ´unicos.
Use OPTIMIZE TABLE de vez em quando para evitar fragmenta¸ao quando estiver usando
formatos de tabela dinˆamica. See hundefinedi[OPTIMIZE TABLE], page hundefinedi.
Use tabelas HEAP para obter mais velocidade sempre que poss´
ivel. See hundefinedi
[Tipos de tabelas], page hundefinedi.
Quando estiver usando uma configura¸ao de servidor Web normal, imagens devem ser
armazenadas como arquivos. Isto ´e, armazene apenas uma referˆencia para o arquivo
no banco de dados. A principal raz˜ao para isto ´e que um servidor Web normal ´e muito
melhor trabalhando com cache de arquivos do que com conte´udo de banco de dados.
Portanto ser´a muito mais f´acil obter um sistema r´apido se vocˆe utilizar arquivos.
Use tabelas em mem´oria para dados n˜ao-cr´
iticos que s˜ao acessados frequentemente
(como informa¸oes sobre o ´ultimo banner visto para usu´arios que n˜ao possuem cookies).
Colunas com informa¸oes identicas em diferentes tabelas devem ser declaradas idˆenticas
e ter nomes idˆenticos. No entanto, antes da vers˜ao 3.23, vocˆe pode obter liga¸oes mais
lentas.
Tente manter os nomes mais simples (use nome em vez de nome_cliente na tabela
cliente). Para deixar seus nomes port´aveis para outros servidores SQL vocˆe deve mantˆe-
los menores que 18 caracteres.
Se vocˆe realmente precisa de alta velocidade, vocˆe deve verificar as interfaces de baixo
n´
ivel para armazenagem de dados que os diferentes servidores SQL suportam! Por ex-
emplo, para acessar tabelas MySQL MyISAM diretamente, vocˆe pode obter um aumento
de velocidade de 2-5 vezes comparado ao uso da interface SQL. Para conseguir essa
fa¸canha, os dados devem estar no mesmo servidor que sua aplica¸ao, e normalmente
devem ser acessados por apenas um processo (porque travamento de arquivos externo
ao muito lentos). Os problemas acima podem ser eliminados introduzindo comandos
MyISAM de baixo n´
ivel no servidor MySQL (isto pode ser a maneira mais f´acil para au-
mentar a performance). Tenha cuidado em projetar a interface com o banco de dados,
ela deve ser bem facil para suportar estes tipos de otimiza¸oes.
Em v´arios casos ´e mais r´apido acessar dados de um banco de dados (utilizando uma
conex˜ao ativa) do que acessar um arquivo texto, apenas pelo fato do banco de dados
ser mais compacto do que o arquivo texto (se vocˆe estiver utilizando dados num´ericos),
e isto ir´a envolver menos acessos `a disco. Voe tamb´em ir´a poupar c´odigo porque
ao ser´a necess´ario analisar seus arquivos texto para encontrar limites de registros e
campos.
Voe pode tamb´em usar replica¸ao para conseguir ainda mais performance nas suas
aplica¸oes. See hundefinedi[Replica¸ao], page hundefinedi.
Declarando uma tabela com DELAY_KEY_WRITE=1 ir´a tornar a atualiza¸ao de ´
indices
mais r´apida, pois as mesmas n˜ao ser˜ao escritas em disco at´e o arquivo ser fechado.
O lado ruim ´e que vocˆe deve executar myisamchk nestas tabelas antes de iniciar o
mysqld para garantir que os dados est˜ao corretos se o mysqld for finalizado no meio
da execu¸ao. Como a informa¸ao de chave pode sempre ser gerada a partir dos dados,
vocˆe n˜ao deve perder nada usando DELAY_KEY_WRITE.
5.3 Detalhes sobre Bloqueios
Chapter 5: Otimiza¸ao do MySQL 349
5.3.1 Como o MySQL Bloqueia as Tabelas
Voe pode encontrar uma discuss˜ao sobre diferentes m´etodos de bloqueios no apˆendice. See
hundefinedi[M´etodos de bloqueio], page hundefinedi.
Todos os bloqueios no MySQL s˜ao livres de deadlock. Isto ´e gerenciado requisitando todos
os bloqueios necess´arios de uma vez no come¸co de uma consulta e sempre bloqueando as
tabelas na mesma ordem.
O m´etodo de bloqueio que o MySQL utiliza para ESCRITA funciona da seguinte forma:
Se n˜ao existirem travas na tabela, coloque uma bloqueio de escrita na mesma.
Caso contr´ario, coloca a requisi¸ao de trava na fila de bloqueios para escrita.
O m´etodo de bloqueio que o MySQL utilizado para LEITURA funciona da seguinte maneira:
Se n˜ao existirem tarvas na tabela, coloca um bloqueio de leitura na mesma.
Caso contr´ario, coloca a requisi¸ao de trava na fila de bloqueios para leitura.
Quando um bloqueio ´e liberado, a trava fica dispon´
ivel para as threads na fila de bloqueios
de escrita, e enao para as threads na fila de bloqueios de leitura.
Isto significa que se vocˆe possui v´arias atualiza¸oes em uma tabela, instru¸oes SELECT ir˜ao
esperar at´e que n˜ao existam mais atualiza¸c˜oes.
Para contornar este problema no caso onde vocˆe precisa fazer v´arias opera¸oes de INSERT
eSELECT em uma tabela, vocˆe pode inserir registros em uma tabela tempor´aria e atualizar
a tabela real com os registros da tabela tempor´aria de uma s´o vez.
Isto pode ser feito usando o c´odigo a seguir:
mysql> LOCK TABLES tabela_real WRITE, tabela_insercao WRITE;
mysql> insert into tabela real select * from tabela_insercao;
mysql> TRUNCATE TABLE tabela_insercao;
mysql> UNLOCK TABLES;
Voe pode utilizar as op¸oes LOW_PRIORITY com INSERT,UPDATE ou DELETE ou HIGH_
PRIORITY com SELECT se vocˆe desejar priorizar a recupera¸ao em alguns casos espec´
ificos.
Tamb´em podei-se iniciar o mysqld com --low-priority-updates para obter o mesmo
comportamento.
Utilizar SQL_BUFFER_RESULT pode tamb´em tornar a cria¸ao de locks de tabelas mais cur-
tos.See hundefinedi[SELECT], page hundefinedi.
Voe tamb´em pode alterar o c´odigo de bloqueioss no ‘mysys/thr_lock.c’ para usar uma
fila simples. Neste caso, bloqueios de escrita e leitura devem ter a mesma prioridade, o que
pode ajudar em algumas aplica¸oes.
5.3.2 Detalhes de Bloqueios de Tabelas
O c´odigo de bloqueio de tabelas no MySQL ´e livre de deadlock.
O MySQL utiliza bloqueio de tabelas (no lugar de bloqueio de registros ou colnas) em todos
os tipos de tabelas, exceto tabelas BDB, para obter uma alta velocidade nos bloqueios. Para
grandes tabelas, bloqueio de tabelas ´e MUITO melhor que bloqueio de registros para a
maioria das aplica¸oes, mas existem, ´e claro, algumas desvantagens.
Para tabelas BDB eInnoDB, O MySQL s´o utiliza bloqueio de tabelas se vocˆe bloquear
explicitamente a tabela com LOCK TABLES ou executar um comando quer ir´a modificar todos
350 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
os registros na tabela, como ALTER TABLE. Para estes tipos de tabelas n´os recomendamos a
vocˆe n˜ao utilizar LOCK TABLES.
No MySQL vers˜ao 3.23.7 ou superior , vocˆe pode inserir registros em tabelas MyISAM ao
mesmo tempo que outras threads est˜ao lendo da mesma tabela. Perceba que atualmente
isto funciona somente se n˜ao existirem buracos depois de registros apagados na tabela no
momento que a inser¸ao ´e feita. Quando todos os buracos forem preenchidos com novos
dados, inser¸oes concorrentes ir˜ao automaticamente ser habilitadas novamente.
O bloqueio de tabelas habilita v´arias threads para lerem de uma tabela ao mesmo tempo,
mas se uma thread desejar escrever a uma tabela, ela primeiramente deve obter acesso
exclusivo. Durante a atualiza¸ao, todas outras threads que desejarem acessar esta tabela
em particular ir˜ao esperar at´e que a atualiza¸ao acabe.
Como atualiza¸oes em tabelas normalmente s˜ao consideradas mais importantes que SELECT,
todas as instru¸oes que atualizam uma tabela tem maior prioridade que instru¸oes que
simplesmente recuperam informa¸oes. Isto deve garantir que atualiza¸oes n˜ao fiquem na
fila por terem sido passadas v´arias consultas pesadas em uma tabela espec´
ifica. (Voe
pode alterar isto utilizando LOW PRIORITY com a instru¸ao que faz a atualiza¸ao ou
HIGH_PRIORITY com a instru¸ao SELECT.)
A partir do MySQL vers˜ao 3.23.7 pode-se utilizadar a vari´avel max_write_lock_count para
for¸car o MySQL a fornecer temporariamente a todas as instru¸oes SELECT, que esperam por
uma tabela, uma prioridade mais alta depois de um n´umero espec´
ifico de inser¸oes em uma
tabela.
O bloqueio de tabela n˜ao ´e, no entanto, muito bom sobre os seguintes cen´arios:
Um cliente emite uma SELECT que exige muito tempo para ser executada.
Outro cliente enao executa um UPDATE na tabela usada. Este cliente ter´a que esperar
at´e que a SELECT seja terminada.
Outro cliente executa outra instru¸ao SELECT na mesma tabela. Como UPDATE tem
maior prioridade que SELECT, esta SELECT ir´a esperar pelo t´ermino da UPDATE. Ela
tamb´em ir´a esperar pelo t´ermino da primeira SELECT!
Uma thread est´a esperando por algo do tipo disco cheio, caso em que todas as threads
que desejam acessar a tabela com problema ir˜ao ser colocadas em estado de espera at´e
que mais espa¸co em disco seja dispon´
ivel.
Algumas solu¸oes poss´
iveis para este problema s˜ao:
Tente deixar suas instru¸oes SELECT sempre r´apidas. Voe pode ter que criar algumas
tabelas de resumo para fazer isto.
Inicie o mysqld com --low-priority-updates. Isto ir´a fornecer a todas instru¸oes
que atualizam (modificam) uma tabela prioridade menor que uma instru¸ao SELECT.
Neste caso a ´ultima instru¸ao SELECT no cen´ario anterior deveria executar antes da
instru¸ao INSERT.
Voe pode fornecer a uma instru¸ao INSERT,UPDATE ou DELETE espec´
ifica menor pri-
oridade com o atributo LOW_PRIORITY.
Inicie o mysqld com um valor baixo para max write lock count para fornecer bloqueios
de LEITURA depois de um certo n´umero de bloqueios de ESCRITA.
Chapter 5: Otimiza¸ao do MySQL 351
Voe pode especificar que todas as atualiza¸oes de uma thread espec´
ifica deve ser feita
utilizando prioridade baixa com o comando SQL: SET SQL_LOW_PRIORITY_UPDATES=1.
See hundefinedi[SET OPTION], page hundefinedi.
Voe pode especificar que uma SELECT espec´
ifica ´e muito importante com o atributo
HIGH_PRIORITY. See hundefinedi[SELECT], page hundefinedi.
Se vocˆe tiver problemas com INSERT combinado com SELECT, utilize as novas tabelas
MyISAM, pois elas suportam SELECTs e INSERTs concorrentes.
Se vocˆe utiliza principalmente instru¸oes INSERT eSELECT misturadas, o atributo
DELAYED no INSERT provavelmente ir´a resolver seus problemas. See hundefinedi
[INSERT], page hundefinedi.
Se vocˆe tiver problemas com SELECT eDELETE, a op¸ao LIMIT para DELETE pode ajudar.
See hundefinedi[DELETE], page hundefinedi.
5.4 Otimizando a Estrutura do Banco de Dados
5.4.1 Op¸oes do Projeto
O MySQL mantem dados de registros e ´
indices em arquivos separados. arios (quase todos)
bancos de dados misturam dados de registros e ´
indice no mesmo arquivo. os acreditamos
que a escolha do MySQL ´e melhor para uma ampla escala de sistemas modernos.
Outra forma de armazenar os dados de registros ´e manter a informa¸ao para cada coluna
em uma ´area separada (exemplos s˜ao o SDBM e o Focus). Isto ir´a causar um ponto de
performance para toda consulta que acessar mais de uma coluna. Como isto degrada rapi-
damente quando mais de uma coluna ´e acessada, acreditamos que este modelo n˜ao ´e bom
para prop´ositos gerais de bancos de dados.
O caso mais comum ´e aquele em que o ´
indice e dados s˜ao armazenados juntos (como no
Oracle/Sybase). Neste caso vocˆe ir´a encontrar a informa¸ao do registro na folha da p´agina
de ´
indice. A coisa boa com este layout ´e que ele, em v´arios casos, dependendo de como
o´
indice ´e armazenado no cache, salva uma leitura de disco. As desvantagens deste layout
ao:
A varredura da tabela ´e muito mais lenta porque vocˆe tem que ler os ´
indices para
encontrar os dados.
ao podem ser usados apenas a tabela de ´
indices para recuperar dados para uma
consulta.
Voe perde muito espa¸co de armazenagem, j´a que que os ´
indices devem ser duplicados
nos n´os (pois os registros n˜ao podem ser armazenados nos n´os).
Dele¸oes ir˜ao degenerar a tabela depois de um tempo (j´a que os ´
indices nos n´os nor-
malmente n˜ao s˜ao atualizados na dele¸ao).
´
E mais dif´
icil fazer o cache somente dos dados de ´
indices.
5.4.2 Deixando os Dados com o Menor Tamanho Poss´
ivel
Uma das otimiza¸oes mais b´asicas ´e tentar manter seus dados (e ´
indices) utilizando o menor
espa¸co poss´
ivel no disco (e em mem´oria). Isto pode fornecer grandes melhorias porque a
352 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
leitura de disco ´e mais r´apida e normalmente menos mem´oria principal ser´a usada. A
indexa¸ao tamb´em exige menos recursos se for feita em colunas menores.
O MySQL suporta v´arios diferentes tipos de tabelas e formatos de registros. Voe pode
ter um ´otimo ganho de performance escolhendo o formato certo de tabela a ser usada. See
hundefinedi[Tipos de tabelas], page hundefinedi.
Pode-se obter melhor performance em uma tabela e minimizar espa¸co de armazenagem
utilizando as t´ecnicas listadas abaixo:
Utilize os tipos mais eficientes (menores) sempre que poss´
ivel. O MySQL tem v´arios
tipos especializados que economizam espa¸co em disco e mem´oria.
Utilize tipos inteiros menores se poss´
ivel para obter tabelas menores. Por exemplo,
MEDIUMINT normalmente ´e melhor que INT.
Declare colunas para serem NOT NULL se poss´
ivel. Isto deixa tudo mais r´apido e vocˆe
economiza um bit por coluna. Perceba que se vocˆe realmente precisa de NULL nas suas
aplica¸oes, podem ser usados. Tente simplesmente n˜ao us´a-la em todas as colunas por
padr˜ao.
Se vocˆe n˜ao possui nenhuma coluna de tamanho vari´avel (VARCHAR,TEXT ou BLOB),
um formato de registro de tamanho fixo para ´e utilizado. Isto ´e mais r´apido mas
infelizmente pode ocupar mais espa¸co. See hundefinedi[Formatos de tabelas MyISAM],
page hundefinedi.
O´
indice prim´ario de uma tabela deve ser o mais curto poss´
ivel. Isto torna a identi-
fica¸ao de um registro f´acil e eficiente.
Para cada tabela, vocˆe deve decidir qual met´odo de armazenamento/´
indice utilizar.
See hundefinedi[Tipos de tabelas], page hundefinedi.
Crie somente os ´
indices necess´arios. ´
Indices s˜ao bons para recupera¸ao mas ruins
quando vocˆe precisa armazenar os dados rapidamente. Se na maioria das vezes vocˆe
acessa uma tabela pesquisando em uma combina¸ao de colunas, crie um ´
indice para
elas. A primeira parte do ´
indice deve ser a coluna mais utilizada. Se vocˆe SEMPRE
utiliza v´arias colunas, deve usar a coluna com mais duplica¸oes em primeiro lugar para
obter melhor compacta¸ao do ´
indice.
Se for melhor que uma coluna tenha um prefixo ´unico nos primeiros caracteres, ´e
melhor indexar somente este prefixo. O MySQL suporta um ´
indice em uma parte
de uma coluna de caracteres. ´
Indices menores s˜ao mais r´apidos n˜ao somente porque
eles exigem menos espa¸co em disco mas tamb´em porque eles ir˜ao fornecer a vocˆe mais
acerto no cache de ´
indice e isto diminui acessos a disco. See hundefinedi[Parˆametros
de servidor], page hundefinedi.
Em algumas circunstˆancias pode ser ben´efico dividir uma tabela que ´e varrida fre-
quentemente em duas. Isto ´e verdade especificamente se a tabela tiver um formato
dinˆamico e for poss´
ivel utilizar um formato de tabela est´atico que possa ser usada para
encontrar os registros relevantes quando se fizer uma varredura da tabela.
5.4.3 Como o MySQL Utiliza ´
indices
Os ´
indices s˜ao utilizados para encontrar registros com um valor espec´
ifico de uma coluna
rapidamente. Sem um ´
indice o MySQL tem de iniciar com o primeiro registro e depois ler
atrav´es de toda a tabela at´e que ele encontre os registros relevantes. Quanto maior a tabela,
Chapter 5: Otimiza¸ao do MySQL 353
maior ser´a o custo. Se a tabela possui um ´
indice para as colunas em quest˜ao, o MySQL
pode rapidamente obter uma posi¸c˜ao para procurar no meio do arquivo de dados sem ter
que varrer todos os registros. Se uma tabela possui 1000 registros, isto ´e pelo menos 100
vezes mais r´apido do que ler todos os registros sequencialmente. Note que se vocˆe precisar
acessar quase todos os 1000 registros, seria mais r´apido acess´a-los sequencialmente porque
evitaria acessos ao disco.
Todos os ´
indices do MySQL (PRIMARY,UNIQUE eINDEX) s˜ao armazenados em ´arvores B.
Strings s˜ao automaticamente compactadas nos espa¸cos finais e prefixados. See hundefinedi
[CREATE INDEX], page hundefinedi.
´
Indices s˜ao utilizados para:
Encontrar rapidamente os registros que coincidam com uma cl´ausula WHERE.
Recuperar registros de outras tabelas ao realizar joins.
Encontrar o valor MAX() ou MIN() para uma coluna indexada espeifica. Isto ´e otimizado
por um preprocessador que confere se vocˆe esa utilizando WHERE key part #=constante
em todas as partes da chave <N. Neste caso o MySQL ir´a fazer uma simples procura
na chave e trocar a express˜ao MIN() com uma constante. Se todas as express˜oes forem
trocadas por constantes, a consulta retornar´a imediatamente:
SELECT MIN(key_part2),MAX(key_part2) FROM nome_tabela where key_part1=10
Ordenar ou agrupar uma tabela se a ordena¸ao ou agrupamento for feito em um prefixo
mais `a esquerda de uma chave util (por exemplo, ORDER BY key_part_1, key_part_2
). A chave ´e lida na ordem invertida se todas as partes da chave forem seguidas por
DESC.
O´
indice tamb´em pode ser utilizado mesmo se ORDER BY ao coincidir exatamente com o
´
indice, j´a que todas as partes n˜ao utilizadas do ´
indice e todos os extras que s˜ao colunas
ORDER BY ao constantes na cl´ausula WHERE A consulta seguinte utilizar´a o ´
indice para
resolver a parte ORDER BY:
SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3;
SELECT * FROM foo WHERE coluna=constante ORDER BY coluna, key_part1;
SELECT * FROM foo WHERE key_part1=const GROUP BY key_part2;
Em alguns casos uma consulta pode ser otimizada para recuperar valores sem consultar
o arquivo de dados. Se todas colunas utilizadas para alguma tabela s˜ao num´ericas e for-
mam um prefixo mais `a esquerda para alguma chave, os valores podem ser recuperados
da ´arvore de ´
indices para aumentar a velocidade:
SELECT key_part3 FROM nome_tabela WHERE key_part1=1
Suponha que vocˆe utilize a seguinte instru¸ao SELECT:
mysql> SELECT * FROM nome_tabela WHERE col1=val1 AND col2=val2;
Se um ´
indice de colunas m´ultiplas existir em col1 ecol2, os registros apropriados podem
ser recuperados diretamente. Se ´
indices separados de ´unicas colunas existirem em col1
ecol2, o otimizador tentar´a encontrar o ´
indice mais restritivo decidindo qual ´
indice ir´a
encontrar menos registros e usar´a este ´
indice para recuperar os registros.
Se a tabela possuir um ´
indice de m´ultiplas colunas, qualquer prefixo mais `a esquerda do
´
indice pode ser usado pelo otimizador para encontrar registros. Por exemplo, se vocˆe possui
um ´
indice de trˆes colunas em (col1,col2,col3), vocˆe tem capacidades de busca indexada
em (col1),(col1,col2) e(col1,col2,col3).
354 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O MySQL n˜ao pode utilizar um ´
indice parcial se as colunas n˜ao formarem um prefixo mais
`a esquerda do ´
indice. Suponha que vocˆe tenha as instru¸oes SELECT mostradas abaixo:
mysql> SELECT * FROM nome_tabela WHERE col1=val1;
mysql> SELECT * FROM nome_tabela WHERE col2=val2;
mysql> SELECT * FROM nome_tabela WHERE col2=val2 AND col3=val3;
Se um ´
indice existir em (col1,col2,col3), somente a primeira consulta exibida acima
utiliza o ´
indice. A segunda e terceira consultas involvem colunas indexadas, mas (col2) e
(col2,col3) ao s˜ao os prefixos mais `a esquerda de (col1,col2,col3).
O MySQL tamb´em utiliza ´
indices para compara¸oes do tipo LIKE se o argumento para LIKE
for uma string constante que n˜ao inicie com um meta caracter Por exemplo as seguintes
instru¸oes SELECT utilizam ´
indices:
mysql> select * from nome_tabela where key_col LIKE "Patrick%";
mysql> select * from nome_tabela where key_col LIKE "Pat%_ck%";
Na primeira instru¸ao, somente os registros com "Patrick" <= key_col < "Patricl" ao
considerados. Na segunda instru¸ao, somente registros com "Pat" <= key_col < "Pau" ao
considerados.
As seguintes instru¸oes SELECT ao usar˜ao ´
indices:
mysql> select * from nome_tabela where key_col LIKE "%Patrick%";
mysql> select * from nome_tabela where key_col LIKE other_col;
Na primeira instru¸ao, o valor LIKE inicia com um meta caracter. Na segunda instru¸ao, o
valor LIKE ao ´e uma constante.
Pesquisas com nome_coluna IS NULL usar˜ao ´
indices se nome coluna for um ´
indice.
O MySQL normalmente utiliza o ´
indice que encontra o menor n´umero de registros. Um
´
indice ´e usado para colunas que vocˆe compara com os seguintes operadores: =,>,>=,<,<=,
BETWEEN e um LIKE com um prefixo sem meta caracteres como ’algo%’.
Qualquer ´
indice que n˜ao cobrem todos os n´
iveis de AND na cl´ausula WHERE ao ´e utilizado
para otimizar a consulta. Em outras palavras: Para poder usar um ´
indice, um prefixo do
´
indice deve ser utilizado em todo agrupamento AND.
A seguinte cl´ausula WHERE utilizar´a ´
indices:
... WHERE index_part1=1 AND index_part2=2 AND other_column=3
... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */
... WHERE index_part1=’hello’ AND index_part_3=5
/* otimizado como "index_part1=’hello’" */
... WHERE index1=1 and index2=2 or index1=3 and index3=3;
/* pode utilizar ´
indice em index1 mas n~ao em index2 ou index 3 */
Estas cl´ausulas WHERE N˜
AO utilizam ´
indices:
... WHERE index_part2=1 AND index_part3=2 /* index_part_1 n~ao ´e usado */
... WHERE index=1 OR A=10 /* O ´
indice n~ao ´e usado em ambas as partes AND*/
... WHERE index_part1=1 OR index_part2=10 /* Nenhum indice cobre os registros */
Perceba que em alguns casos o MySQL n˜ao utilizar´a um ´
indice, mesmo se algum estiver
dispon´
ivel. Alguns dos casos onde isto acontece:
Se o uso do ´
indice necessita que o MySQL acesse mais de 30% dos registros na tabela.
(Neste caso uma varredura da tabela ´e provavelmente mais r´apido, j´a que isto necessite
Chapter 5: Otimiza¸ao do MySQL 355
de menos pesquisas em discos). Perceba que se uma consulta utiliza LIMIT para recu-
perar somente parte dos registros, o MySQL ir´a utilizar um ´
indice de qualquer forma,
pois assim pode encontrar os poucos registros mais rapidamente e retornar o resultado.
5.4.4 ´
Indices de Colunas
Todos os tipos de colunas do MySQL podem ser indexadas. O uso de ´
indices nas colunas
relevantes ´e a melhor forma de melhorar a performance de opera¸oes SELECT.
O n´umero m´aximo de chaves e o tamanho m´aximo de um ´
indice ´e definido pelo manipulador
de tabelas. See hundefinedi[Tipos de tabelas], page hundefinedi. Voe pode com todos os
manipuladores de tabelas ter pelo menos 16 chaves e um ´
indice de tamanho total de pelo
menos 256 bytes.
Para colunas CHAR eVARCHAR vocˆe pode indexar um prefixo da coluna. Isto ´e muito mais
apido e necessita de menos espa¸co em disco do que indexar a coluna inteira. A sintaxe
para utilizar na instru¸ao CREATE TABLE para indexar um prefixo de uma coluna se parece
com o exemplo a seguir:
KEY nome_indice (nome_campo(tamanho))
O exemplo abaixo cria um ´
indice para os primeiros 10 caracteres da coluna nome:
mysql> CREATE TABLE teste (
nome CHAR(200) NOT NULL,
KEY nome_indice (nome(10)));
Para colunas BLOB eTEXT, vocˆe deve indexar um prefixo da coluna. Vocˆe n˜ao pode indexar
a coluna inteira.
No MySQL Vers˜ao 3.23.23 ou posterior, vocˆe pode tamb´em criar ´
indices FULLTEXT espe-
ciais. Eles s˜ao utilizados para pesquisas textuais. Somente o tipo de tabela MyISAM suporta
´
indices FULLTEXT. Eles podem ser criados somente de colunas VARCHAR eTEXT. Indexa¸ao
sempre acontece sobre toda a coluna e indexa¸ao parcial n˜ao ´e suportada. Veja hundefinedi
[Fulltext Search], page hundefinedipara detalhes.
5.4.5 ´
Indices de M´ultiplas Colunas
O MySQL pode criar ´
indices em m´ultiplas colunas. Um ´
indice pode consistir de at´e 15
colunas. (Em colunas CHAR eVARCHAR vocˆe tamb´em pode utilizar um prefixo da coluna
como parte de um ´
indice).
Um ´
indice de m´ultiplas colunas pode ser considerado um array ordenado contendo valores
que s˜ao criados concatenando valores de colunas indexadas.
O MySQL utiliza ´
indices de m´ultiplas colunas de forma que consultas s˜ao r´apidas quando
vocˆe especifica uma quantidade conhecida para a primeira coluna do ´
indice em uma cl´ausula
WHERE, mesmo se vocˆe n˜ao especificar valores para as outras colunas.
Suponha que uma tabela ´e criada com as seguintes especifica¸oes:
mysql> CREATE TABLE teste (
id INT NOT NULL,
ultimo_nome CHAR(30) NOT NULL,
primeiro_nome CHAR(30) NOT NULL,
PRIMARY KEY (id),
356 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
INDEX nome (ultimo_nome,primeiro_nome));
Enao o ´
indice nome ´e um ´
indice com ultimo_nome eprimeiro_nome. O ´
indice ser´a usado
para consultas que especificarem valores em um limite conhecido para ultimo_nome, ou
para ambos ultimo_nome eprimeiro_nome. Desta forma, o ´
indice nome ser´a usado nas
seguintes consultas:
mysql> SELECT * FROM teste WHERE ultimo_nome="Widenius";
mysql> SELECT * FROM teste WHERE ultimo_nome="Widenius"
AND primeiro_nome="Michael";
mysql> SELECT * FROM teste WHERE ultimo_nome="Widenius"
AND (primeiro_nome="Michael" OR primeiro_nome="Monty");
mysql> SELECT * FROM teste WHERE ultimo_nome="Widenius"
AND primeiro_nome >="M" AND primeiro_nome < "N";
Entretanto, o ´
indice nome ao ser´a usado nas seguintes consultas:
mysql> SELECT * FROM teste WHERE primeiro_nome="Michael";
mysql> SELECT * FROM teste WHERE ultimo_nome="Widenius"
OR primeiro_nome="Michael";
Para maiores informa¸oes sobre a maneira que o MySQL utiliza ´
indices para melhorar o
desempenho das consultas, veja hundefinedi[´
indices do MySQL], page hundefinedi.
5.4.6 Como o MySQL abre e fecha tabelas
table_cache,max_connections emax_tmp_tables afetam o n´umero m´aximo de arquivos
que o servidor mantˆem abertos. Se vocˆe aumentar um ou ambos destes valores, vocˆe pode
ir contra um limite imposto pelo seu sistema operacional no n´umero de arquivos abertos
por processo. Entretanto, o limite em v´arios sistemas pode ser aumentado. Consulte a
documenta¸ao de seu Sistema Operacional para saber como fazˆe-lo, porque o m´etodo para
alterar o limite varia muito de um sistema para outro.
table_cache ´e relacionado a max_connections. Por exemplo, para 200 conex˜oes concor-
rentes em execu¸ao, vocˆe deve ter um chace de tabela de pelo menos 200 * n, onde n´e o
n´umero m´aximo de tabelas em um join. Voe tamb´em precisa reservar alguns descritores
de arquivos para tabelas e arquivos tempor´arios.
O cache de tabelas abertas pode crescer at´e um m´aximo de table_cache (o padr˜ao ´e 64;
isto pode ser alterado com a op¸ao do mysqld -O table_cache=#. Uma tabela nunca ´e
fechada, exceto quando o cache est´a cheio e outra thread tentar abrir uma tabela ou se vocˆe
utilizar mysqladmin refresh ou mysqladmin flush-tables.
Quando o cache de tabela encher, o servidor usa o seguinte procedimento para encontrar
uma entrada de cache para usar:
Tabelas que n˜ao estiverem em uso s˜ao liberadas, na ordem LRU (least-recently-used),
ou seja, a tabela que foi usada menos rcentemente.
Se o cache estiver cheio e nenhuma tabelas pode ser liberada, mas uma nova tabela
precisar ser aberta, o cache ´e extendido temporariamente quando necess´ario.
Chapter 5: Otimiza¸ao do MySQL 357
Se o cache estiver no estado temporariamente extendido e uma tabela vai do estado
em-uso para o fora-de-uso, a tabela ´e fechada e liberada do cache.
Uma tabela ´e aberta para cada acesso simultˆaneo. Isto significa que se voe tem duas
threads acessando a mesma tabela ou acessando a tabela duas vezes na mesma query (com
AS) a tabelas precisa ser aberta duas vezes. A primeira abertura de qualquer tabela exige
dois descritores de arquivos; cada uso adicional da tabela exige somente um descritor.
O descritor extra para a primeira abertura ´e para o arquivo de ´
indice: este descritor ´e
compartilhado entre todas as threads.
Voe pode conferir se o seu cache de tabela est´a muito pequeno conferindo a vari´avel do
mysqld opened_tables. Se este valor for muito grande, mesmo se vocˆe n˜ao fez v´arios FLUSH
TABLES, vocˆe deve aumentar seu cache de tabelas. See hundefinedi[SHOW STATUS],
page hundefinedi.
5.4.7 Desvantagem em Criar um N´umero Grande de Tabelas no
Mesmo Banco de Dados
Se vocˆe possui muitos arquivos em um diret´orio, opera¸oes de abrir, fechar e cria¸ao ficar˜ao
lentos. Se voe executar instru¸oes SELECT em diversas tabelas, existir´a uma pequena
sobrecarga quando o cache de tabela estiver cheio, porque para toda tabela que teve que
ser aberta, outra deve ser fechada. Voe pode reduzir esta sobrecarga tornando o cache de
tabelas maior.
5.4.8 Por Quˆe Tantas Tabelas Abertas ?
Ao executar o comando mysqladmin status, vocˆe ver´a algo deste tipo:
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
Isto pode ser bastante estranho se vocˆe s´o possui 6 tabelas.
O MySQL ´e multithreaded, portanto ele pode ter v´arias consultas abertas na mesma tabela
simultaneamente. Para minimizar o problema com duas threads tendo diferentes estados
no mesmo arquivo, a tabela ´e aberta independentemente por cada thread concorrente. Isto
exige mais mem´oria e um descritor extra de arquivo para o arquivo de dados. O descritor
de arquivo de ´
indice ´e compartilhado entre todas as threads.
5.5 Otimizando o servidor MySQL
5.5.1 Sintonia dos Parˆametros em Tempo de Sistema/Compila¸ao
e na Inicializa¸ao
os iniciamos com o n´
ivel do sistema pois algumas destas decis˜oes devem ser feitas bem
cedo. Em outros casos uma r´apida olhada para esta parte pode satisfazer porque ela n˜ao ´e
ao importante para os grandes ganhos. Entretanto, ´e sempre bom ter ter no¸oes de como
vocˆe pode obter melhorias alterando coisas neste n´
ivel.
Qual sistema operacional a usar ´e realmente importante! Para obter o melhor uso de
aquinas com m´ultiplas CPUs vocˆe deve utilizar Solaris (porque as threads funcionam
muito bem) ou Linux (porque o kernel 2.2 tem suporte SMP muito bom). Em m´aquinas
358 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Linux 32-bits temos o limite de tamanho de arquivo de 2G por padr˜ao. Esperamos que
isto seja corrigido logo quando novos sistemas de arquivos forem liberados (XFS/Reiserfs).
Se vocˆe precisa desesperadamente de trabalhar com arquivos maiores que 2G em m´aquinas
intel Linux, vocˆe deve obter o patch LFS para o sistema de arquivos ext2.
Como ainda n˜ao temos o MySQL em produ¸ao em muitas outras plataformas, n´os aconsel-
hamos que vocˆe teste a plataforma pretendida antes de escolhe-la, se poss´
ivel.
Outras dicas:
Se vocˆe possui RAM suficiente, vocˆe pode remover todos os dispositivos de troca.
Alguns sistemas operacionais ir˜ao utilizar um disposotico de troca em alguns contextos,
mesmo se vocˆe possuir mem´oria livre.
Utilize a op¸ao do MySQL --skip-locking para evitar bloqueios externos. Perceba
que isto n˜ao ir´a afetar a funcionalidade do MySQL se voe estiver executando um ´unico
servidor. Apenas lembre-se de desligar o servidor (ou travar as partes relevantes) antes
de executar myisamchk. Em alguns sistemas esta troca ´e obrigat´orio porque o bloqueio
externo n˜ao funciona em nenhum caso.
A op¸ao --skip-locking est´a ligada por padr˜ao quando compilando com
MIT-pthreads, porque flock() ao ´e totalmente suportado pelas MIT-pthreads em
todas plataformas. ´
E tamb´em o padr˜ao para Linux pois o bloqueio de arquivos no
Linux n˜ao ´e muito seguro.
O ´unico caso que vocˆe n˜ao pode utilizar --skip-locking ´e se vocˆe precisa de v´arios
servidores MySQL (n˜ao clientes) acessando os mesmos dados, ou executar myisamchk
na tabela sem primeiramente descarregar e travar as tabelas no servidor mysqld.
Voe pode continuar usando LOCK TABLES/UNLOCK TABLES mesmo se vocˆe estiver uti-
lizando --skip-locking.
5.5.2 Parˆametros de Sintonia do Servidor
Voe pode obter o tamanho padr˜ao do buffer usados pelo servidor mysqld com este comando:
shell> mysqld --help
Este comando produz uma lista de todas as op¸oes do mysqld e vari´aveis configur´aveis. A
sa´
ida inclui os valores padr˜ao e se parece com isto:
Possible variables for option --set-variable (-O) are:
back_log current value: 5
bdb_cache_size current value: 1048540
binlog_cache_size current_value: 32768
connect_timeout current value: 5
delayed_insert_timeout current value: 300
delayed_insert_limit current value: 100
delayed_queue_size current value: 1000
flush_time current value: 0
interactive_timeout current value: 28800
join_buffer_size current value: 131072
key_buffer_size current value: 1048540
lower_case_table_names current value: 0
long_query_time current value: 10
max_allowed_packet current value: 1048576
Chapter 5: Otimiza¸ao do MySQL 359
max_binlog_cache_size current_value: 4294967295
max_connections current value: 100
max_connect_errors current value: 10
max_delayed_threads current value: 20
max_heap_table_size current value: 16777216
max_join_size current value: 4294967295
max_sort_length current value: 1024
max_tmp_tables current value: 32
max_write_lock_count current value: 4294967295
myisam_sort_buffer_size current value: 8388608
net_buffer_length current value: 16384
net_retry_count current value: 10
net_read_timeout current value: 30
net_write_timeout current value: 60
query_buffer_size current value: 0
record_buffer current value: 131072
record_rnd_buffer current value: 131072
slow_launch_time current value: 2
sort_buffer current value: 2097116
table_cache current value: 64
thread_concurrency current value: 10
tmp_table_size current value: 1048576
thread_stack current value: 131072
wait_timeout current value: 28800
Se existir um servidor mysqld em execu¸ao, vocˆe pode ver quais valores ele est´a usando
atualmente para as vari´aveis executando este comando:
shell> mysqladmin variables
Para encontrar uma descri¸ao completa de todas as vari´aveis na se¸ao SHOW VARIABLES
neste manual. See hundefinedi[SHOW VARIABLES], page hundefinedi.
O comando SHOW STATUS exibe estat´
istiscas de um servidor em funcionamento. See hunde-
finedi[SHOW STATUS], page hundefinedi.
O MySQL utiliza algor´
itmos que s˜ao muito escal´aveis, portanto, normalmente vocˆe pode
trabalhar com pouca mem´oria. Entretanto, se vocˆe fornecer ao MySQL mais mem´oria,
obter´a um desempenho melhor.
Quando estiver ajustando um servidor MySQL, as duas vari´aveis mais importantes que
devem ser usadas s˜ao key_buffer_size etable_cache. Vocˆe deve se sentir confiante que
as duas estejam corretas antes de tentar alterar qualquer outra vari´avel.
Se vocˆe possui miuita mem´oria (>=256M) e v´arias tabelas e deseja obter o melhor desem-
penho com um n´umero moderado de clientes, deve utilizar algo como:
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
-O sort_buffer=4M -O record_buffer=1M &
Se possui apenas 128M e possuir algumas poucas tabelas, mas ainda deseja realizar v´arias
ordena¸oes, vocˆe pode utilizar:
shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M
Se vocˆe possuir pouca mem´oria e tiver muitas conex˜oes, utilize algo como:
360 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
-O record_buffer=100k &
ou mesmo:
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
-O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
Se vocˆe estiver executando um GROUP BY ou ORDER BY em arquivos que s˜ao muito maiores que
sua mem´oria dispon´
ivel vocˆe deve aumentar o valor de record_rnd_buffer para acelerar
a leitura de registros depois que a ordena¸ao ´e feita.
Quando vocˆe tiver instalado o MySQL, o diret´orio ‘support-files’ ir´a conter alguns
arquivos exemplos do my.cnf, ‘my-huge.cnf’, ‘my-large.cnf’, ‘my-medium.cnf’e‘my-
small.cnf’, vocˆe pode us´a-los como base para otimizar seu sistema.
Se vocˆe possui v´arias conex˜oes, “problemas de trocas” pode ocorrer a menos que o mysqld
tenha sido configurado para usar muito pouca mem´oria para cada conex˜ao. O mysqld tem
melhor performance se vocˆe tiver mem´oria suficiente para todas as conex˜oes, ´e claro.
Perceba que se vocˆe alterar uma op¸ao para mysqld, ele permanece em efeito somente para
aquela instˆancia do servidor.
Para ver os efeitos de uma altera¸ao de parˆametro, fa¸ca algo como:
shell> mysqld -O key_buffer=32m --help
Tenha certeza que a op¸ao --help seja a ´ultima do comando; de outra forma o efeito de
qualquer op¸oes listadas depois na linha de comando n˜ao ser˜ao refletidas na sa´
ida.
5.5.3 Como a Compila¸ao e a Liga¸ao Afeta a Velocidade do
MySQL
A maioria dos testes seguintes s˜ao feitos no Linux com os benchmarks do MySQL, mas eles
devem fornecer alguma indica¸ao para outros sistemas operacionais e workloads.
Voe obtˆem um execut´avel mais veloz quando ligado com -static.
No Linux, vocˆe ir´a obter o c´odigo mais r´apido quando compilando com pgcc e-03. Para
compilar ‘sql_yacc.cc’ com estas op¸oes, vocˆe precisa de cerca de 200M de mem´oria porque
ogcc/pgcc precisa de muita mem´oria para criar todas as fun¸oes em linha. Tamb´em deve
ser configurado o parˆametro CXX=gcc para evitar que a biblioteca libstdc++ seja incluida
(n˜ao ´e necess´aria). Perceba que com algumas vers˜oes do pgcc, o c´odigo resultante ir´a
executar somente em verdadeiros processadores Pentium, mesmo que vocˆe utilize a op¸ao do
compilador para o c´odigo resultante que vocˆe quer, funcionando em todos os processadores
do tipo x586 (como AMD).
o pelo fato de utilizar um melhor compilador e/ou melhores op¸oes do compilador vocˆe
pode obter um aumento de desempenho de 10-30% na sua aplica¸c˜ao. Isto ´e particularmente
importante se vocˆe mesmo compila o servidor SQL!
os testamos ambos os compiladores Cygnus Codefusion e o Fujitsu, mas quando os testa-
mos, nenhum dos dois era suficientemente livre de erros para que o MySQL compilasse com
as otimiza¸oes.
Quando vocˆe compila o MySQL deve incluir suporte somente para os conjuntos de carac-
teres que deseja usar. (Op¸ao --with-charset=xxx). As distribui¸oes bin´arias padr˜ao do
MySQL s˜ao compiladas com suporte para todos os conjuntos de caracteres.
Segue uma lista de algumas medidas que temos feito:
Chapter 5: Otimiza¸ao do MySQL 361
Se vocˆe utiliza o pgcc e compila tudo com -O6, o servidor mysqld ´e 1% mais r´apido do
que com o gcc 2.95.2.
Se vocˆe liga dinamicamente (sem -static), o resultado ´e 13% mais lento no Linux.
Note que vocˆe ainda pode utilizar uma biblioteca do MySQL dinamicamente ligada. ´
E
o o servidor que ´e cr´
itico para performance.
Se vocˆe corta seu bin´ario mysqld com strip libexec/mysqld, o bin´ario gerado pode
ficar at´e 4% mais r´apido.
Se vocˆe conecta utilizando TCP/IP em vez de utilizar sockets Unix, o resultado ´e 7.5%
mais lento no mesmo computador. (Se vocˆe fizer conex˜ao `a localhost, o MySQL ir´a,
por padr˜ao, utilizar sockets).
Se vocˆe conectar utilizando TCP/IP de outro computador sobre uma rede Ethernet de
100M as coisas ficar˜ao de 8-11% mais lentas.
Se vocˆe compilar com --with-debug=full, estar´a perdendo cerca de 20% para a maio-
ria das consultas, mas algumas consultas podem demorar muito mais tempo (os bench-
marks do MySQL demonstram 35% de perda). Se utilizar --with-debug, ent˜ao ir´a
perder 15%. Ao iniciar uma vers˜ao do mysqld compilada com --with-debug=full
com --skip-safemalloc o resultado final deve ser perto de quando compilado com
--with-debug.
Em uma Sun SPARCstation 20, SunPro C++ 4.2 ´e 5 % mais r´apido que gcc 2.95.2.
Compilando com gcc 2.95.2 para o ultrasparc com a op¸ao -mcpu=v8 -Wa,-
xarch=v8plusa melhora a performance em 4%.
No Solaris 2.5.1, a MIT-pthreads ´e 8-12% mais lenta do que as threads nativas do
Solaris em um ´unico processador. Com mais carga/CPUs a diferen¸ca deve aumentar.
Executando com --log-bin deixa o MySQL 1 % mais lento.
Compilando no Linux-x86 com gcc sem frame pointers -fomit-frame-pointer ou -
fomit-frame-pointer -ffixed-ebp deixa o mysqld 1-4% mais r´apido.
A distribui¸ao MySQL-Linux fornecida pela MySQL AB ´e normalmente compilada com
pgcc, mas vamos retornar a usar o gcc pelo fato de um bug no pgcc que gera o c´odigo
que n˜ao executa no AMD. Continuaremos a usar o gcc at´e que o bug seja resolvido. Neste
meio tempo, se vocˆe possui uma m´aquina que n˜ao seja AMD, vocˆe pode ter um bin´ario
mais r´apido compilando com o pgcc. O bin´ario padr˜ao do MySQL para Linux ´e ligado
estaticamente para conseguir mais desempenho e ser mais port´avel.
5.5.4 Como o MySQL Utiliza a Mem´oria
A lista abaixo indica algumas das maneiras inas quais o servidor mysqld utiliza a mem´oria.
Onde aplic´avel, o nome da vari´avel do servidor relevante ao uso de mem´oria ´e fornecido:
O buffer de chave (vari´avel key_buffer_size) ´e compartilhado por todas as threads;
Outros buffers usados pelo servido s˜ao alocados quando necess´arios. See hundefinedi
[Parˆametros de servidor], page hundefinedi.
Cada conex˜ao utiliza algum espa¸co espec´
ifico da thread: Uma de pilha (padr˜ao de 64K,
vari´avel thread_stack), um buffer de conex˜ao (vari´avel net_buffer_lenght), e um
buffer de resultados (vari´avel net_buffer_lenght). Os buffers de conex˜oes e resultados
ao aumentados dinamicamente para max_allowed_packet quando necess´ario. Quando
362 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
uma consulta est´a sendo executada, uma c´opia da string da consulta atual ´e tamb´em
alocada.
Todas as threads compartilhas a mesma mem´oria base.
Somente as tabelas ISAM / MyISAM compactadas s˜ao mapeadas em mem´oria. Isto ´e
porque o espa¸co de mem´oria de 32-bits de 4GB n˜ao ´e grande o bastante para a maioria
das grandes tabelas. Quando sistemas com endere¸camento de 64-bits se tornarem
comuns poderemos adicionar um suporte gieral para o mapeamento de mem´oria.
Cada requisi¸ao fazendo uma varredura sequencial em uma tabela aloca um buffer de
leitura (vari´avel record_buffer).
Ao ler registros na ordem ’randˆomica’ (por exemplo, depois de uma ordena¸ao) um
buffer de leitura randˆomico ´e alocado para evitar pesquisas em disco. (vari´avel record_
rnd_buffer).
Todas as joins s˜ao feitas em um ´unico passo, e a maioria delas podem ser feitas mesmo
sem usar uma tabela tempor´aria. A maioria das tabelas tempor´arias s˜ao tabelas
baseadas em mem´oria (HEAP). Tabelas tempor´arias com uma grande extens˜ao de
registros (calculada como a soma do tamanho de todas as colunas) ou que contenham
colunas BLOB ao armazenadas em disco.
Um problema nas vers˜oes do MySQL anteriores a vers˜ao 3.23.2 ´e que se uma tabela
HEAP excede o tamanho de tmp_table_size, vocˆe recebe o erro The table nome_
tabela is full. Em vers˜oes mais novas isto ´e tratado alterando automaticamente a
tabela em mem´oria (HEAP) para uma tabela baseada em disco (MyISAM) quando
necess´ario. Para contornar este problema, vocˆe pode aumentar o tamanho da tabela
tempor´aria configurando a op¸c˜ao tmp_table_size do mysqld, ou configurando a op¸ao
do SQL SQL_BIG_TABLES no progrma cliente. See hundefinedi[SET OPTION], page hun-
definedi. Na vers˜ao 3.20 do MySQL, o n´umero m´aximo da tabela tempor´aria era
record_buffer*16, assim, se vocˆe estiver utilizando esta vers˜ao, vocˆe ter´a que au-
mentar o valor record_buffer. Voe tamb´em pode iniciar o mysqld com a op¸ao
--big-tables para sempre armazenar as tabelas tempor´arias em disco. Entretanto
isto afetar´a a velocidade de v´arias consultas complicadas.
A maioria das requisi¸oes da ordena¸ao alocam um bufer de ordena¸ao e 0-2 arquivos
tempor´arios dependendo do tamanho do resultado. See hundefinedi[Arquivos tem-
por´ario], page hundefinedi.
Quase todas as an´alises e c´alculos s˜ao feitos em um armazenamento de mem´oria local.
Nenhuma sobrecarga de mem´oria ´e necess´ario para ´
itens pequenos e a aloca¸ao e lib-
era¸ao normal de mem´oria lenta ´e evitada. A mem´oria ´e alocada somente para grandes
strings inesperadas (isto ´e feito com malloc() efree()).
Cada arquivo de ´
indice ´e aberto uma vez e o arquivo de dados ´e aberto uma vez para
cada thread concorrente. Uma estrutura de tabela, estrutura de coluna para cada
coluna e um buffer de tamanho 3 * n ´e alocado para cada thread concorrente. (onde
n´e o maior tamanho do registro, sem levar em considera¸ao colunas BLOB. Um BLOB
utiliza de 5 a 8 bytes mais o tamanho dos dados contidos na mesma. O manipulador
de tabelas ISAM/MyISAM ir˜ao usar um registro extra no buffer para uso interno.
Para cada tabela com colunas BLOB, um buffer ´e aumentado dinamicamente para ler
grandes valores BLOB. Se vocˆe ler uma tabela, um buffer do tamanho do maior registro
BLOB ´e alocado.
Chapter 5: Otimiza¸ao do MySQL 363
Manipuladores de tabelas para todas tabelas em uso s˜ao salvos em um cache e geren-
ciado como FIFO. Normalmente o cache possui 64 entradas. Se uma tabela foi usada
por duas threads ao mesmo tempo, o cache ter´a duas entredas para a tabela. See
hundefinedi[Cache de tabela], page hundefinedi.
Um comando mysqladmin flush-tables fecha todas tabelas que n˜ao est˜ao em uso
e marca todas tabelas em uso para serem fechadas quando a thread atualmente em
execu¸ao terminar. Isto ir´a liberar efetivamente a maioria da mem´oria em uso.
ps e outros programas de informa¸oes do sistema podem relatar que o mysqld usa muita
mem´oria. Isto pode ser causado pelas pilhas de threads em diferentes endere¸cos de mem´oria.
Por exemplo, a vers˜ao do ps do Solaris conta a mem´oria n˜ao usada entre as pilhas como
mem´oria usada. Voe pode verificar isto conferindo a mem´oria dispon´
ivel com swap -s.
Temos testado o mysqld com detectores comerciais de perda de mem´oria, portanto tais
perdas n˜ao devem existir.
5.5.5 Como o MySQL Utiliza o DNS
Quando uma nova thread conecta ao mysqld, o mysqld ir´a extender uma nova thread para
lidar com o pedido. Esta thread primeiro confere se o nome da m´aquina est´a no cache de
nomes de m´aquinas. Se n˜ao, a thread ir´a chamar gethostbyaddr_r() egethostbyname_
r() para resolver o nome.
Se o sistema operacional n˜ao suporta as chamadas acima em threads seguras, a thread ir´a
travar um mutex e chamar gethostbyaddr() egethostbyname(). Perceba que neste caso
nenhuma outra thread pode resolver outros nomes de m´aquinas que n˜ao existam no cache
de nomes de m´aquina at´e que a primeira thread esteja pronta.
Voe pode desabilitar a procura de nomes de m´aquinas no DNS iniciando o mysqld com
a op¸ao --skip-name-resolve. Neste caso vocˆe s´o pode usar n´umeros IP nas tabelas de
privil´egio do MySQL.
Se vocˆe possuir um DNS muito lento e v´arias m´aquinas, pode obter mais desempenho
desligando a procura de nomes de m´aquinas usando a op¸ao --skip-name-resolve ou
aumentando HOST_CACHE_SIZE (default: 128) e recompilar mysqld.
Voe pode desabilitar o cache de nomes de m´aquinas com --skip-host-cache. Este cache
pode ser limpado com os comandos FLUSH HOSTS ou mysqladmin flush-hosts.
Se vocˆe n˜ao deseja permitir conex˜oes TCP/IP, pode iniciar o mysqld com --skip-
networking.
5.5.6 SET Syntax
SET [OPTION] SQL_VALUE_OPTION= valor, ...
SET OPTION configura v´arias op¸oes que afetam a opera¸ao do servidor ou seu cliente. Qual-
quer op¸ao que for configurada continua em efeito at´e que a se¸ao atual termine ou at´e que
a op¸ao seja configurada para um valor diferente.
CHARACTER SET nome_conjunto_caracteres | DEFAULT
Mapeia todas as strings do e para o cliente com o mapa especificado. Atual-
mente a ´unica op¸ao para character_set_name ´e cp1251_koi8, mas vocˆe pode
adicionar novos mapas editando o arquivo ‘sql/convert.cc’ na distribui¸ao
364 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
fonte do MySQL. O mapeamento padr˜ao pode ser restaurado utilizando o valor
DEFAULT para character_set_name.
Perceba que a sintaxe para configurar a op¸ao CHARACTER SET ´e diferente da
sintaxe para configurar as outras op¸oes.
PASSWORD = PASSWORD(’alguma senha’)
Configura a senha para o usu´ario atual. Qualquer usu´ario que n˜ao seja anˆonimo
pode alterar sua pr´opria senha!
PASSWORD FOR user = PASSWORD(’alguma senha’)
Configura a senha para um usu´ario espec´
ifico no servidor atual. Somente
um usu´ario com acesso ao banco de dados mysql pode fazer isto. O usu´ario
deve ser fornecido no formato usu´ario@home_maquina, onde usu´ario enome_
aquina ao exatamente o que est˜ao listados nas colunas User eHost da tabela
mysql.user. Por exemplo, se vocˆe possui uma entrada com os campos User e
Host com ’bob’ e’%.loc.gov’, vocˆe escreveria:
mysql> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("nova_senha");
or
mysql> UPDATE mysql.user SET password=PASSWORD("nova_senha") where user="bob’ and host="%.loc.gov";
SQL_AUTO_IS_NULL = 0 | 1
Se configurado com 1(padr˜ao) o ´ultimo registro inserido em uma tabela com um
regitro auto incremnto pode ser encontrado com a seguinte constru¸ao: WHERE
auto_increment_column IS NULL. Isto ´e usado por alguns programas ODBC
como o Access.
AUTOCOMMIT= 0 | 1
Se configurado com 1todas altera¸oes em uma tabela ser´a feita de uma vez.
Para iniciar uma transa¸ao de v´arios comandos, deve ser usada a instru¸ao
BEGIN. See hundefinedi[COMMIT], page hundefinedi. Se configurado com 0
deve ser usado COMMIT/ROLLBACK para aceitar/recusar aquela transa¸ao. See
hundefinedi[COMMIT], page hundefinedi. Note que quando vocˆe altera do
modo n˜ao-AUTOCOMMIT para AUTOCOMMIT, o MySQL ir´a fazer um COMMIT au-
tom´atico em quaisquer transa¸oes abertas.
SQL_BIG_TABLES = 0 | 1
Se configurado com 1, todas tabelas tempor´arias s˜ao armazenadas em disco em
vez da mem´oria. Isto ser´a um pouco mais lento, mas vocˆe n˜ao ter´a o erro The
table nome_tabela is full para grandes opera¸oes SELECT que necessitam de
uma tabela tempor´aria grande. O valor padr˜ao para uma nova conex˜ao ´e 0(isto
´e, utiliza tabelas tempor´arias em mem´oria).
SQL_BIG_SELECTS = 0 | 1
Se configurado com 0, o MySQL ir´a abortar se uma tentaviva de se fazer um
SELECT for, provavelmente, levar muito tempo. Isto ´e ´util quando uma instru¸ao
WHERE ao aconselhada for utilizado. Uma grande consulta ´e definida como
uma SELECT que provavelmente ter´a que examinar mais que max_join_size
registros. O valor padr˜ao para uma nova conex˜ao ´e 1(que permitir´a qualquer
instru¸ao SELECT).
Chapter 5: Otimiza¸ao do MySQL 365
SQL_BUFFER_RESULT = 0 | 1
SQL_BUFFER_RESULT ir´a for¸car que o resultado de SELECT’s seja colocado em
tabelas tempor´arias. Isto ir´a ajudar o MySQL a liberar mais cedos bloqueios
de tabela e ajudar˜ao em casos onde elas ocupam muito tempo para enviar o
conjunto de resultados para o cliente.
SQL_LOW_PRIORITY_UPDATES = 0 | 1
Se configurado com 1, todas instru¸oes INSERT,UPDATE,DELETE eLOCK TABLE
WRITE ir˜ao esperar at´e que n˜ao existam SELECT ou LOCK TABLE READ pendentes
na tabela afetada.
SQL_MAX_JOIN_SIZE = valor | DEFAULT
ao permita que SELECTs que provavelmente necessitem examinar mais que
valor combina¸oes de registros. Configurando este valor, vocˆe pode obter
SELECTs onde chaves n˜ao s˜ao usadas corretamente e que provavelmente gas-
tar˜ao um bom tempo. Configurando-o para um valor diferente do DEFAULT
ir´a definir o atributo SQL_BIG_SELECTS com o padr˜ao. Se vocˆe configurar o
atributo SQL_BIG_SELECTS novamente, a vari´avel SQL_MAX_JOIN_SIZE ser´a ig-
norada. Voe pode configurar um valor padr˜ao para esta vari´avel iniciando o
mysqld com -O max_join_size=#.
SQL_SAFE_UPDATES = 0 | 1
Se configurado com 1, o MySQL ir´a aborar se tentarmos fazer um UPDATE
ou DELETE sem utilizar uma chave ou LIMIT na cl´ausula WHERE. Desta forma
´e poss´
ivel capturar atualiza¸oes erradas ao criarmos comandos SQL manual-
mente.
SQL_SELECT_LIMIT = valor | DEFAULT
O n´umero m´aximo de registros para retornar de instru¸oes SELECT. Se uma
SELECT tem uma cl´ausula LIMIT, o LIMIT tem precedˆeencia sobre o valor de
SQL_SELECT_LIMIT. O valor padr˜ao para uma nova conex˜ao ´e “unlimited” (ilim-
itado). Se vocˆe alterou o limite, o valor padr˜ao pode ser restaurado atribuindo
o valor DEFAULT aSQL_SELECT_LIMIT.
SQL_LOG_OFF = 0 | 1
Se configurado com 1, nenhum registro ser´a feito no log padr˜ao para este cliente,
se o cliente tiver o privil´egio process. Isto n˜ao afeta o log de atualiza¸oes!
SQL_LOG_UPDATE = 0 | 1
Se configurado com 0, nenhum registro ser´a feito no log de atualiza¸oes para o
cliente, se o cliente tiver o privil´egio process. Isto n˜ao afeta o log padr˜ao!
SQL_QUOTE_SHOW_CREATE = 0 | 1
Se configurado com 1,SHOW CREATE TABLE ir´a colocar os nomes de tabela e
colunas entre aspas. Est´a ligado por padr˜ao, para que replica¸ao de tabelas
com nomes de colunas estranhos funcione. hundefinedi[SHOW CREATE TABLE],
page hundefinedi.
TIMESTAMP = valor_timestamp | DEFAULT
Configura a hora/data para este cliente. ´
E usado para obter a hora e data
original se vocˆe utiliza o log de atualiza¸oes para restaurar registros. valor_
timestamp deve ser um timestamp UNIX Epoch, n˜ao um timestamp MySQL.
366 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
LAST_INSERT_ID = #
Configura o valor a ser retornado de LAST_INSERT_ID(). Ele ´e armazenado
no log de atualiza¸oes quando vocˆe utiliza LAST_INSERT_ID() em um comando
que atualiza uma tabela.
INSERT_ID = #
Configura o valor que ser´a usado pelo comando INSERT ou ALTER TABLE seguinte
ao inserir um valor AUTO_INCREMENT. Isto ´e usado principalmente com o log de
atualiza¸oes.
5.6 Detalhes de Disco
Como mencionado acima, pesquisas em disco s˜ao o maior gargalo de desempenho. Estes
problemas ficam cada vez mais aparentes quando os dados come¸cam a crescer tanto que
efetivo armazenamento em cache se torna imposs´
ivel. Para grandes bancos de dados,
onde vocˆe acessa dados mais ou menos aleatoriamente, vocˆe pode ter certeza de que
precisar´a de pelo menos uma busca em disco para ler e v´arias para gravar os dados.
Para minimizar este problema, utilize discos com menor tempo de pesquisa.
Aumente o n´umero de eixo de discos dispon´
iveis (e enao reduza a sobrecarga da
pesquisa) ligando arquivos simbolicamente em diferentes discos ou utilizando striping
de discos.
Usando links simolicos
Significa que vocˆe liga simbolicamente o ´
indice e/ou arquivos de dados ao
diret´orio de dados normal em outro disco (que pode tamb´em ser striped).
Isto torna os tempos de pesquisa e leitura melhor (Se os discos n˜ao s˜ao
usados para outras coisas). See hundefinedi[Links simb´olicos], page hun-
definedi.
Striping Striping significa que vocˆe possui v´arios discos e coloca o primeiro bloco
no primeiro disco, o segundo bloco no segundo disco, e o N-simo no (N
odulo n´umero de discos) disco, e assim por diante. Isto significa que
se o seu tamanho de dados normais ´e menos que o tamanho do bloco
(ou perfeitamente alinhado) vocˆe ir´a obter um desempenho muito melhor.
Perceba que striping ´e muito dependente do SO e do tamanho do bloco.
Portanto me¸ca a performance de sua aplica¸ao com diferentes tamanhos
de blocos. See hundefinedi[Benchamrks], page hundefinedi.
Perceba que a diferen¸ca de velocidade para striping ´e muito dependente
dos parˆametros. Dependendo de como vocˆe configura os parˆametros do
striping e do n´umero de discos vocˆe pode obter uma diferen¸ca de v´arias
ordens de grandeza. Note que vocˆe deve escolher a otimiza¸ao randˆomica
ou pelo acesso sequencial.
Para confiabilidade vocˆe pode desejar utilizar RAID 0+1 (striping +espelhamento)
mas neste caso vocˆe ir´a precisar de 2*N discos para armazenar N discos de dados.
Isto ´e provavelmente a melhor op¸ao se vocˆe possuir dinheiro! Vocˆe pode tamb´em,
entretanto, ter que investir em algum software gerenciador de volumes para lidar com
isto eficientemente.
Chapter 5: Otimiza¸ao do MySQL 367
Uma boa op¸ao ´e ter ter dados de m´edia importˆancia (aqueles que podem ser regen-
erados) em um armazenamento RAID 0 enquanto os dados realemtente importantes
(como informa¸oes de m´aquinas e logs) em um sistema RAID 0+1 ou RAID de N dis-
cos. RAID N pode ser um problema se vocˆe tem v´arias escritas devido ao tempo para
atualizar os bits de paridade.
Voe pode tamb´em configurar os parˆametros para o sistema de arquivos que o banco
de dados usa. Uma altera¸ao simples ´e montar o sistema de arquivos com a op¸ao
noatime. Isto faz com que ele evite a atualiza¸ao do ´ultimo tempo de acesso no inode
e com isto tamb´em evita algumas buscas em disco.
No Linux, vocˆe pode obter um desempenho muito melhor (cerca de 100% sobre carga
pode ser comum) utilizando hdparm para configurar sua interface de disco! O exemplo
a seguir deve ser muito ´util para o MySQL (e provavelmente v´arias outras aplica¸oes):
hdparm -m 16 -d 1
Perceba que o desempenho/confian¸ca ao utilizar o exemplo acima depende de seu hard-
ware, portanto n´os sugerimos que vocˆe teste bem seu sistema depois de utilizar hdparm!
Por favor consulte a p´agina do manual (man) do hdparm para maiores informa¸oes! Se
ohdparm ao for usado corretamente, poder´a resultar em corrup¸ao do sistema de
arquivos. Realize backups de tudo antes de experimentar!
Em v´arios sistemas operacionais os discos podem ser montados com a op¸ao ’async’
para configurar o sistema de arquivos a ser atualizado de modo ass´
incrono. Se o seu
computador ´e razoavelmente est´avel, isto deve fornecer mais desempenho sem sacrificar
a seguran¸ca. (Esta op¸ao ´e ligada por padr˜ao no Linux.)
Se vocˆe n˜ao precisar saber a ´ultima vez que um arquivo foi acessado (o que realmente
ao ´e muito ´util em um servidor de banco de dados), vocˆe pode montar seus sistema
de arquivos com a op¸ao noatime.
5.6.1 Utilizando Links Simb´olicos
Voe pode mover tabelas e bancos de dados do diret´orio de banco de dados para outras
localiza¸oes e troa-los por links simolicas para os novos locais. Voe pode fazer isto, por
exemplo, para mover um banco de dados para um sistema de arquivos com mais espa¸co livre
ou aumentar a velocidade de seu sistema esipalhando suas tabelas para discos diferentes.
A maneira recomendada de se fazer isto ´e ligar simbolicamente bancos de dados a discos
diferentes e s´o ligar tabelas como ´ultimo recurso.
5.6.1.1 Utilizando Links Simb´olicos para Bancos de Dados
A maneira de ligar simbolicamente um banco de dados ´e, primeiramente, criar um diret´orio
em algum disco onde vocˆe possui espa¸co livre e enao criar uma liga¸ao simolica para ele
a partir do diret´orio do banco de dados do MySQL.
shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test mysqld-datadir
O MySQL n˜ao suporta que vocˆe ligue um diret´orio a v´arios bancos de dados. Trocando um
diret´orio de banco de dados com uma liga¸ao simolica ir´a funcionar bem desde que n˜ao
sejam feitos links simolicos entre os bancos de dados. Suponha que vocˆe tenha um banco
368 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
de dados db1 sob o diret´orio de dados do MySQL, e enao criar uma liga¸ao simb´olica db2
que aponte para db1.
shell> cd /caminho/para/diretorio/dados
shell> ln -s db1 db2
Agora, para qualquer tabela tbl_a em db1, tamb´em aparecer´a uma tabela tbl_a em db2.
Se uma thread atualizar db1.tbl_a e outra atualizar db2.tbl_a, ocorrer˜ao porblemas.
Se vocˆe realmente precisar disto, vocˆe deve alterar o c´odigo seguinte em ‘mysys/mf_
format.c’:
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
para
if (1)
No Windows vocˆe pode utilizar links simolicos para diret´orios compilando o MySQL com
-DUSE_SYMDIR. Isto lhe permite colocar diferentes bancos de dados em discos diferentes.
See hundefinedi[Links simolicos no Windows], page hundefinedi.
5.6.1.2 Utilizando Links Simb´olicos para Tabelas
Antes do MySQL 4.0 vocˆe n˜ao deve utilizar tabelas com liga¸oes simolicas, se vocˆe n˜ao tiver
muito cuidado com as mesmas. O problema ´e que se vocˆe executar ALTER TABLE,REPAIR
TABLE ou OPTIMIZE TABLE em uma tabela ligada simbolicamente, os links simolicos ser˜ao
removidas e substituidos pelos arquivos originiais. Isto acontece porque o comando acima
funcinoa criando um arquivo tempor´ario no diret´orio de banco de dados e quando o comando
´e completo, substitui o arquivo original pelo arquivo tempor´ario.
Voe n˜ao deve ligar simbolicamente tabelas em um sistema que n˜ao possui uma chamada
realpath() completa. (Pelo menos Linux e Solaris suportam realpath()
No MySQL 4.0 links simolicos s´o s˜ao suportados completamente por tabelas MyISAM. Para
outros tipos de tabelas vocˆe provavelmente obter´a problemas estranhos ao fazer qualquer
um dos comandos mencionados acima.
O tratamento de links simolicos no MySQL 4.0 funciona da seguinte maneira (isto ´e mais
relevante somente para tabelas MyISAM.
No diret´orio de dados vocˆe sempre ter´a o arquivo de defini¸oes das tabelas e os arquivos
de ´
indice/dados.
Voe pode ligar simbolicamente o arquivo ´
indice e o arquivo de dados para diret´orios
diferentes, independente do outro arquivo.
A liga¸ao pode ser feita partir do sistema operacional (se o mysqld ao estiver em
execu¸ao) ou com o comando INDEX/DATA DIRECTORY="caminho-para- diretorio"
em CREATE TABLE. See hundefinedi[CREATE TABLE], page hundefinedi.
myisamchk ao ir´a substituir um link simolico pelo ´
indice/arquivo mas funciona dire-
tamente nos arquivos apontados pelos links simolicos. Qualquer arquivo tempor´ario
ser´a criado no mesmo diret´orio que o arquivo de dados/´
indice est´a.
Quando vocˆe remove uma tabela que est´a usando links simolicos, o link e o arquivo
para o qual ela aponta s˜ao apagados. Esta ´e uma boa raz˜ao pela qual vocˆe N ˜
AO deve
executar mysqld como root e n˜ao deve permitir que pessoas tenham acesso de escrita
ao diret´orios de bancos de dados do MySQL.
Chapter 5: Otimiza¸ao do MySQL 369
Se vocˆe renomear uma tabela com ALTER TABLE RENAME e n˜ao deseja alterar o banco de
dados, o link simb´olico para o diret´orio de banco de dados ser´a renomeada corretamente.
Se vocˆe utiliza ALTER TABLE RENAME para mover uma tabela para outro banco de dados,
enao a tabela ser´a movida para outro diret´orio de banco de dados e os links simb´olicos
antigos e os arquivos para os quais eles apontam ser˜ao removidos.
Se vocˆe n˜ao utiliza links simolicos, vocˆe deve usar a op¸ao --skip-symlink do mysqld
para garantir que ningu´em pode apagar ou renomear um arquivo fora do diret´orio de
dados do mysqld.
O que ainda n˜ao ´e suportado:
ALTER TABLE ignora todas as op¸oes INDEX/DATA DIRECTORY="caminho".
CREATE TABLE ao relata se a tabela possui links simolicos.
Omysqldump ao inclui a informa¸ao de links simolicos na sa´
ida.
BACKUP TABLE eRESTORE TABLE ao respeitam links simolicos.
370 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
6 Referˆencia de Linguagem do MySQL
O MySQL possui uma interface SQL muito complexa mas intuitiva e f´acil de aprender. Este
cap´
itulo descreve os v´arios comandos, tipos e fun¸oes que vocˆe precisa conhecer para usar o
MySQL de maneira eficiente e efetiva. Este cap´
itulo tamb´em serve como referˆencia para to-
das as funcionalidades inclu´
idas no MySQL. Para poder utilizar este cap´
itulo eficientemente,
vocˆe deve achar ´util fazer referˆencia aos v´arios ´
indices.
6.1 Estrutura da Linguagem
6.1.1 Literais: Como Gravar Strings e Numerais
Esta se¸ao descreve as diversas maneiras para gravar strings e n´umeros no MySQL. Ela
tamb´em cobre as v´arias nuances e “pegadinhas” pelas quais vocˆe pode passar ao lidar com
estes tipos b´asicos no MySQL.
6.1.1.1 Strings
Uma string ´e uma sequˆencia de caracteres, cercada por caracteres de aspas simples (‘’)
ou duplas (‘"’) (Se vocˆe utiliza o modo ANSI deve utilizar somente as aspas simples).
Exemplos:
’uma string’
"outra string"
Em uma string, certas sequˆencias tem um significado especial. Cada uma destas sequˆencias
come¸cam com uma barra invertida (‘\’), conhecida como caracter de escape. O MySQL
reconhece a seguinte sequˆencia de escape:
\0 Um caracter ASCII 0 (NUL).
\’ Um caracter de aspas simples (‘’).
\" Um caracter de aspas duplas (‘"’).
\b Um caracter de backspace.
\n Um caracter de nova linha.
\r Um caracter de retorno de carro.
\t Um caracter de tabula¸ao.
\z ASCII(26) (Control-Z). Este caracter pode ser codificado para permitir que vocˆe
contorne o problema que o ASCII(26) possui comoEND-OF-FILE ou EOF (Fim
do arquivo) no Windows. (ASCII(26) ir´a causar problemas se vocˆe tentar usar
mysql banco_dados < nome_arquivo).
\\ O caracter de barra invertida (‘\’) character.
\% Um caracter ‘%’. Ele pode ser usado para pesquisar por instˆancias literais de ‘%
em contextos onde ‘%’ deve, de outra maneira, ser interpretado como um meta
caracter. See hundefinedi[Fun¸oes de compara¸oes de string], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 371
\_ Um caracter ‘_’. Ele ´e usado para pesquisar por instˆancias literais de ‘_’ em
contextos onde ‘_’ deve, de outra maneira, ser intrerpretado como um meta
caracter. See hundefinedi[Fun¸oes de compara¸oes de string], page hundefinedi.
Note que se vocˆe utilizar ‘\%’ ou ‘\_’ em alguns contextos de strings, eles retornar˜ao as
strings ‘\%’ e ‘\_’ e n˜ao ‘%’ e ‘_’.
Estas s˜ao as v´arias maneiras de incluir aspas com uma string:
Um ‘’ dentro de uma string com ‘’ pode ser escrita como ‘’’’.
Um ‘"’ dentro de uma string com ‘"’ pode ser escrita como ‘""’.
Voe pode preceder o caracter de aspas com um caracter de escape (‘\’).
Um ‘’ dentro de uma string com ‘"’ n˜ao precisa de tratamento especial e n˜ao precisa
ser duplicada ou utilizada com caracter de escape. Da mesma maneira, ‘"’ dentro de
uma string com ‘’ n˜ao necessita de tratamento especial.
As instru¸oes SELECT exibidas abaixo demonstram como cita¸oes e escapes funcionam:
mysql> SELECT ’hello’, ’"hello"’, ’""hello""’, ’hel’’lo’, ’\’hello’;
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel’lo | ’hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT "hello", "’hello’", "’’hello’’", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | ’hello’ | ’’hello’’ | hel"lo | "hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT "Isto\ns~ao\nQuatro\nlinhas";
+--------------------+
| Isto
s~ao
Quatro
linhas |
+--------------------+
Se vocˆe deseja inserir dados bin´arios em uma coluna BLOB, os caracteres a seguir devem ser
representados por sequˆencias de espace:
NUL ASCII 0. Vocˆe deve represena-lo como ‘\0’ (uma barra invertida e um caractere
0’).
\ASCII 92, barra invertida. Representado como ‘\\’.
ASCII 39, aspas simples. Representado como ‘\’’.
"ASCII 34, aspas duplas. Representado como ‘\"’.
Se vocˆe escreve c´odigo C, vocˆe pode utilizar a fun¸ao da API C mysql_escape_string()
para caracteres de escape para a instru¸ao INSERT. See hundefinedi[Vis˜ao geral da fun¸ao
API C], page hundefinedi. No Perl, pode ser utilizado o m´etodo quote do pacote DBI para
converter caracteres especiais para as sequˆencias de escape corretas. See hundefinedi[Classe
DBI do Perl], page hundefinedi.
Deve ser utilizada uma fun¸ao de escape em qualquer string que contˆem qualquer um dos
caracteres especiais listados acima!
372 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
6.1.1.2 N´umeros
Inteiros s˜ao representados como uma sequˆencia de d´
igitos. N´umeros de ponto flutuante
utilizam ‘.’ como um separador decimal. Ambos os tipos devem ser precedidos por ‘-’ para
indicar um valor negativo.
Exemplos de inteiros v´alidos:
1221
0
-32
Exemplo de n´umeros de ponto flutuante v´alidos:
294.42
-32032.6809e+10
148.00
Um inteiro pode ser usado em um contexto de ponto flutuante; ele ´e interpretado como o
de ponto flutuante equivalente.
6.1.1.3 Valores Hexadecimais
O MySQL suporta valores hexadecimais. No contexto num´erico estes atuam como um
inteiro (precis˜ao de 64-bits). No contexto de strings, atuam como uma string bin´aria onde
cada par de d´
igitos hexadecimais ´e convertido para um caracter:
mysql> SELECT 0xa+0;
-> 10
mysql> select 0x5061756c;
-> Paul
Strings hexadecimais s˜ao frequentemente usadas pelo ODBC para fornecer valores `as colunas
BLOB.
6.1.1.4 Valores NULL
O valor NULL significa “sem dados” e ´e diferente de valores como 0para tipos num´ericos ou
strings vazias para tipos string. See hundefinedi[Problemas com NULL], page hundefinedi.
NULL pode ser representado por \N ao usar o formato de arquivo texto para importa¸ao ou
exporta¸ao (LOAD DATA INFILE,SELECT ... INTO OUTFILE). See hundefinedi[LOAD DATA],
page hundefinedi.
6.1.2 Nomes de Banco de dados, Tabela, ´
Indice, Coluna e
Apelidos
Nomes de banco de dados, tabela, ´
indice, coluna e apelidos seguem todos as mesmas regras
no MySQL.
Note que as regras foram alteradas a partir do MySQL vers˜ao 3.23.6, quando introduzimos
aspas em identificadores (nomes banco de dados, tabela e coluna) com ‘’. ‘"’ funcionar´a
tamb´em para citar identificadores se vocˆe executar no modo ANSI. See hundefinedi[Modo
ANSI], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 373
Identificador Tamanho
aximo
Caracteres permitidos
Banco de
dados
64 Qualquer caractere que ´e permitido em um nome de diret´orio
exceto ‘/’ ou ‘.’.
Tabela 64 Qualquer caractere permitido em um nome de arquivo, exceto
/’ ou ‘.’.
Coluna 64 Todos os caracteres.
Alias 255 Todos os caracteres.
Note que em adi¸ao ao mostrado acima, vocˆe n˜ao pode ter ASCII(0) ou ASCII(255) ou o
caracter de cita¸ao (aspas) em um identificador.
Perceba que se o identificador ´e uma palavra restrita ou conem caracteres especiais vocˆe
deve sempre coloa-lo entre ao us´a-lo:
SELECT * from ‘select‘ where ‘select‘.id > 100;
Em vers˜oes anteriores do MySQL, as regras se nomes eram as seguintes:
Um nome pode consistir de caracteres alfanum´ericos do conjunto atual de caractres e
tamb´em ‘_’e‘$’. O conjunto de caracteres padr˜ao ´e o ISO-8859-1 Latin1; e pode ser al-
terado com a op¸ao --default-character-set no mysqld. See hundefinedi[Conjunto
de caracteres], page hundefinedi.
Um nome pode iniciar com qualquer caractere que ´e legal no nome. Em particular,
pode iniciar com um n´umero (isto difere de v´arios outros sistemas de bancos de dados!).
Entretanto um nome n˜ao pode consistir somente de n´umeros.
O caractere ‘.’ n˜ao pode ser utilizado em nomes porque ele ´e usado para extender o
formato pelo qual vocˆe pode fazer referˆencias a colunas (veja abaixo).
´
E recomendado que vocˆe n˜ao utilize nomes como 1e, porque uma express˜ao como 1e+1 ´e
amb´
igua. Ela pode ser interpretada como a express˜ao 1e + 1 ou como o n´umero 1e+1.
No MySQL vocˆe pode se referir a uma coluna utilizando uma das formas seguintes:
Coluna de referˆencia Significado
nome_campo Coluna nome_campo de qualquer tabela usada na consulta
contendo uma coluna com aquele nome.
nome_tabela.nome_campo Coluna nome_campo da tabela nome_tabela do banco de
dados atual.
nome_bd.nome_tabela.nome_
campo
Coluna nome_campo da tabela nome_tabela do banco
de dados nome_bd. Esta forma ´e dispon´
ivel no MySQL
Vers˜ao 3.22 ou posterior.
‘nome_coluna‘ Uma coluna que ´e uma palavra chave ou contem carac-
teres especiais.
Voe n˜ao precisa especificar um prefixo de nome_tabela ou nome_bd.nome_tabela para
uma referˆencia de coluna em uma instru¸ao, a menos que a referˆencia seja amb´
igua. Por
exemplo, suponha que cada tabela t1 et2 contenham uma coluna c, e vocˆe deve recuperar
cem uma instru¸ao SELECT que utiliza ambas tabelas t1 et2. Neste caso, c´e amb´
iguo
porque ele n˜ao ´e ´unico entre as tabelas usadas na instru¸ao, portanto deve ser indicado qual
´e a tabela que se deseja escrever, t1.c ou t2.c. De mesma forma, se vocˆe for recuperar de
uma tabela tem um banco de dados db1 e uma tabela tem um banco de dados db2, vocˆe
deve se refererir `as colunas nestas tabelas como db1.t.nome_campo edb2.t.nome_campo.
374 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A sintaxe .nome_tabela indica a tabela nome_tabela no banco de dados atual. Esta
sintaxe ´e aceitada para compatibilidade ODBC, porque alguns programas ODBC prefixam
os nomes das tabelas com um caracter ‘.’.
6.1.3 Caso Sensitivo nos Nomes
No MySQL, bancos de dados e tabelas correspondem a diret´orios e arquivos em seus di-
ret´orios. Consequentemente, o caso sensitivo no sistema operacional ir´a determinar o caso
sensitivo nos nomes de bancos de dados e tabelas. Isto significa que nomes de bancos de
dados e tabelas s˜ao caso sensitivo no Unix e caso insensitivo no Windows. See hundefinedi
[Extens˜oes ao ANSI], page hundefinedi.
NOTA: Apesar de nomes de bancos e tabelas serem caso insensitivo no Windows, vocˆe n˜ao
deve fazer referˆencia a um certo banco de dados ou tabela utilizando casos diferentes na
mesma consulta. A consulta a seguir n˜ao deve funcionar porque ela chama uma tabela
como minha_tabela e outra como MINHA_TABELA.
mysql> SELECT * FROM minha_tabela WHERE MINHA_TABELA.col=1;
Nomes de colunas n˜ao s˜ao caso sensitivo em todas as circunstˆancias.
Aliases nas tabelas s˜ao caso sensitivo. A consulta seguinte n˜ao deve funcionar porque ela
faz referˆencia ao alias como ae como A.
mysql> SELECT nome_campo FROM nome_tabela AS a
WHERE a.nome_campo = 1 OR A.nome_campo = 2;
Apelidos (alias) em colunas n˜ao caso insensitivo.
Se vocˆe tem um problema para lembrar o caso usado para os nomes de tabelas, adote uma
conven¸ao consistente, como sempre criar bancos de dados e tabelas utilizando nomes em
min´usculas.
Uma maneira para evitar este problema ´e iniciar o mysqld com -O lower_case_table_
names=1. Por padr˜ao esta op¸ao ´e 1 no Windows e 0 no Unix.
Se lower_case_table_names for 1, o MySQL ir´a converte todos os nomes de tabelas para
min´usculo no armazenamento e pesquisa. Perceba que se vocˆe alterar esta op¸ao, ser´a
necess´ario converter primeiramente seus nomes de tabelas antigos para min´usculo antes de
iniciar o mysqld.
6.1.4 Vari´aveis de Usu´ario
O MySQL suporta vari´aveis espec´
ificas de thread com a sintaxe @nomevari´avel. Um nome
de vari´avel consiste de caracteres alfanum´ericos do conjunto atual de caracteres e tamb´em
_’, ‘$’e‘.’. O conjunto de caracteres padr˜ao ´e ISO-8859-1 Latin1; ele pode ser alterado com
a op¸ao --default-character-set do mysqld. See hundefinedi[Conjunto de caracteres],
page hundefinedi.
As vari´aveis n˜ao precisam ser inicializadas. Elas cont´em NULL por padr˜ao e podem ar-
mazenar um valor inteiro, real ou uma string. Todas as vari´aveis de uma thread s˜ao auto-
maticamente liberadas quando uma thread termina.
Voe pode configurar uma variavel com a syntaxe SET.
SET @vari´avel= { expressao inteira | expressiao real | expressao string }
[,@vari´avel= ...].
Chapter 6: Referˆencia de Linguagem do MySQL 375
Voce tambm pode configurar uma vari´avel em uma express˜ao com a sintaxe
@variable:=expr
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |
+----------------------+------+------+------+
| 5 | 5 | 1 | 4 |
+----------------------+------+------+------+
(Devemos utilizar a syntax := aqui porque =esta reservado para compara¸oes).
Vari´aveis de usu´arios devem ser utilizadas em express˜oes onde s˜ao permitidas. Isto n˜ao
inclui utiliza-las em contextos onde um n´umero ´e explicitamente necess´ario, assim como
na cl´ausula LIMIT de uma instru¸ao SELECT ou a clausula IGNORE number LINE de uma
instru¸ao LOAD DATA.
NOTE: Em uma instru¸ao SELECT , cada express˜ao s´o ´e avaliada quando enviada ao cliente.
Isto significa que nas cl´ausula HAVING,GROUP BY, ou ORDER BY, vocˆe n˜ao pode fazer referˆencia
a uma exprees˜ao que envolve vari´aveis que s˜ao configuradas na instru¸ao SELECT. Por
examplo, a seguinte instru¸ao N ˜
AO funcionar´a como o esperado:
SELECT (@aa:=id) AS a, (@aa+3) AS b FROM nome_tabela HAVING b=5;
A raz˜ao ´e que o @aa ao ir´a conter o valor da linha atual. , mas o valor da id da linha
previamente aceita.
6.1.5 Sintaxe de Comenarios
O servidor MySQL suporta os estilos de comenario # no fim da linha,-- no fim da linha
e/* na linha ou em multiplas linhas */
mysql> select 1+1; # Este coment´ario continua at´e o fim da linha
mysql> select 1+1; -- Este comnet´ario continua at´e o fim da linha
mysql> select 1 /* Este ´e um coment´ario de linha */ + 1;
mysql> select 1+
/*
Este ´e um coment´ario
de m´ultiplas linhas
*/
1;
Note que o estilo de comenario -- requer que pelo menos um espa¸co ap´os o c´odigo {--!
Embora o servidor entenda as sintaxes de comenarios aqui descritas, existem algumas
limit¸oes no modo que o cliente mysql analisa o comenario /* ... */:
Caracteres de aspas simples e aspas duplas s˜ao utilizados para indicar o in´
icio de uma
string com aspas, mesmo dentro de um comenario. Se as aspas n˜ao coincidirem com
uma segunda aspas dentro do comenario, o analisador n˜ao percebe que o comenario
tem um fim. Se vocˆe estiver executando o mysql interativamente, vocˆe pode perceber
a confus˜ao ocorrida por causa da mudan¸ca do prompt de mysql> para ’> ou ">.
Um ponto e v´
irgula ´e utilizado para indicar o fim de uma instru¸ao SQL e qualquer
coisa que venha ap´os ele indica o in´
icio da pr´oxima instru¸ao.
376 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Estas limita¸oes se aplicam tanto a quando se executa mysql interativamente quanto quando
se coloca oos comandos em um arquivo e pede para que mysql leia as entradas deste arquivo
com o comando mysql < some-file.
MySQL n˜ao suporta o estilo de comenario ANSI SQL ‘--’. See hundefinedi[Missing
comments], page hundefinedi.
6.1.6 MySQL ´e Exigente com Palavra Reservadas?
Um problema comum ocorre quando tentamos criar tabelas com nome de campo que usam
nomes de tipos de dados ou fun¸oes criadas no MySQL, com TIMESTAMP ou GROUP, Vocˆe
poder´a fazer isso (por exemplo, ABS ´e um nome de campo permitido), mas espa¸cos n˜ao
ao permitidos entre o nome da fun¸ao e o ‘(’ quando estiver usando este nome de fun¸ao
tamb´em como o nome de uma campo.
As seguintes palavras s˜ao explicitamente reservadas em MySQL. Muitas delas s˜ao proibidas
pelo ANSI SQL92 como nomes de campos e/ou tabelas. (por examplo, group). Algu-
mas poucas s˜ao reservadasporque o MySQL precisa delas e est´a usando (atualmente) um
analisador yacc:
action add aggregate all
alter after and as
asc avg avg_row_length auto_increment
between bigint bit binary
blob bool both by
cascade case char character
change check checksum column
columns comment constraint create
cross current_date current_time current_
timestamp
data database databases date
datetime day day_hour day_minute
day_second dayofmonth dayofweek dayofyear
dec decimal default delayed
delay_key_write delete desc describe
distinct distinctrow double drop
end else escape escaped
enclosed enum explain exists
fields file first float
float4 float8 flush foreign
from for full function
global grant grants group
having heap high_priority hour
hour_minute hour_second hosts identified
ignore in index infile
inner insert insert_id int
integer interval int1 int2
int3 int4 int8 into
if is isam join
key keys kill last_insert_id
Chapter 6: Referˆencia de Linguagem do MySQL 377
leading left length like
lines limit load local
lock logs long longblob
longtext low_priority max max_rows
match mediumblob mediumtext mediumint
middleint min_rows minute minute_second
modify month monthname myisam
natural numeric no not
null on optimize option
optionally or order outer
outfile pack_keys partial password
precision primary procedure process
processlist privileges read real
references reload regexp rename
replace restrict returns revoke
rlike row rows second
select set show shutdown
smallint soname sql_big_tables sql_big_selects
sql_low_priority_
updates
sql_log_off sql_log_update sql_select_limit
sql_small_result sql_big_result sql_warnings straight_join
starting status string table
tables temporary terminated text
then time timestamp tinyblob
tinytext tinyint trailing to
type use using unique
unlock unsigned update usage
values varchar variables varying
varbinary with write when
where year year_month zerofill
Os simbolos seguintes (da tabela acima) n˜ao s˜ao permitidos pela ANSI SQL mas permitidos
pelo MySQL como nome de campos/tabelas. Isto ocorre porque alguns destes nomes s˜ao
muito naturais e v´arios pessoas j´a o utilizaram.
ACTION
BIT
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP
6.2 Tipos de Campos
MySQL suporta um certo n´umeors de tipos de campos que podem ser agrupaos em trˆes cate-
gorias: tipos num´ericos, tipos de data e hora, e tipos string (caracteres). Esta se¸ao primeiro
378 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
lhe d´a uma vis˜ao geral dos tipos dispon´
iveis e resume as exigencias de armazenamento em
cada tipo de coluna, tamb´em fornece uma descri¸ao mais detalhada da propriedade dos
tipos em cada categoria. A vis˜ao dada ´e propositalmente breve. As descri¸oes mais detal-
hdas devem ser consultadas para informa¸oes adicionais sobre tipos de campo particulares
como os formatos permitidos nos quais vocˆe pode especificar valores.
Os tipos de campos suportados pelo MySQL est˜ao listados abaixo: As seguintes letras s˜ao
usadas como c´odigo nas descri¸oes:
MIndica o tamanho m´aximo do display. O tamanho m´aximo oficial do display ´e
255.
DAplica aos tipos de ponto flutuante e indica o n´umero de digitos ap´os o ponto
decimal. O maior valor poss´
ivel ´e 30, mas n˜ao pode ser maior que M-2.
Colchetes (‘[’ and ‘]’) indicam partes de tipos espec´
ificos que s˜ao opicionais
Note que se vocˆe especificar ZEROFILL para um campo MySQL automaticamente ir´a adi-
cionar o atributo UNSIGNED ao campo.
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro muito pequeno. A faixa deste inteiro com sinal ´e de -128 at´e 127.
A faixa sem sinal ´e de 0at´e 255.
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro pequeno. A faixa do inteiro com sinal ´e de -32768 at´e 32767. A
faixa sem sinal ´e de 0a65535.
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro de tamanho m´edio. A faica com sinal ´e de -8388608 a8388607. A
faixa sem sinal ´e de 0to 16777215.
INT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro de tamanho normal. A faixa com sinal ´e de -2147483648 a
2147483647. A faixa sem sinal ´e de 0a4294967295.
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
Este ´e um sinˆonimo para INT.
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
Um inteiro grande. A faixa com sinal ´e de -9223372036854775808 a
9223372036854775807. A faixa sem sinal ´e de 0a18446744073709551615.
Existem algumas coisas sobre campos BIGINT sobre as quias vocˆe deve estar
ciente:
Como todas as opera¸oes aritim´eticas s˜ao feitas usando valores BIGINT ou
DOUBLE com sinal, ao devemos util¸cizar inteiros sem sinal maiores que
9223372036854775807 (63 bits) exceto com fun¸oes ded bit! Se vocˆe fizer
isto, alguns dos ´ultimos digitos no resultado podem estar errados por causa
de erros de arredondamento na convers˜ao de BIGINT para DOUBLE.
Voe pode armazenar valores inteiro exatos em um campo BIGINT
aramzenando-os como string, como ocorre nestes casos n˜ao haver´a
nenhuma representa¸ao intermediaria dupla.
Chapter 6: Referˆencia de Linguagem do MySQL 379
-’, ‘+’, e ‘*’ ser˜ao utilizados em c´alculos aritim´eticos BIGINT quando ambos
os argumentos forem valores do tipo INTEGER! Isto significa que se vocˆe
multilicar dois inteiros grandes (ou obter resultados de fun¸oes que retor-
nam inteiros) vocˆe pode obter resultados inesperados quando o resultado
for maior que 9223372036854775807.
FLOAT(precis~ao) [ZEROFILL]
Um n´umero de ponto flutuante. ao pode ser sem sinal. precis~ao pode ser
<=24 para um n´umero de ponto flutuante de precis˜ao simples e entre 25 e 53
para um n´umero de ponto flutuante de dupla-precis˜ao. Estes tipos s˜ao como os
tipos FLOAT eDOUBLE descritos logo abaixo. FLOAT(X) tem o mesma faixa que
os tipos correspondentes FLOAT eDOUBLE, mas o tamanho do display e n´umero
de casas decimais ´e indefinido.
Na vers˜ao 3.23 do MySQL, este ´e um verdadeiro valor de ponto flutuante. Em
vers˜oes anteriores , FLOAT(precis~ao) sempre tem 2 casas decimais.
Note que o uso de FLOAT pode trazer alguns problemas inesperados como nos
alculos j´a que em MySQL todos s˜ao feitos com dupla-precis˜ao. See hundefinedi
[No matching rows], page hundefinedi.
Esta sintaxe ´e fornecida para comptibilidade com ODBC.
FLOAT[(M,D)] [ZEROFILL]
Um numero de ponto flutuante pequeno (precis˜ao simples). ao pode ser sem
sinal. Os valores permitidos s˜ao de -3.402823466E+38 a-1.175494351E-38,0
e de 1.175494351E-38 a3.402823466E+38. O M ´e a largura do display e o D ´e
o n´umero de casas decimais. FLOAT sem um argumento ou com um argumento
<=24 tende a um numero de ponto flutuante de precis˜ao simples.
DOUBLE[(M,D)] [ZEROFILL]
Um n´umero de ponto flutuante de tamanho normal (dupla-precis˜ao). ao
pode ser sem sinal. Valores permitidos entre -1.7976931348623157E+308
e-2.2250738585072014E-308,0e entre 2.2250738585072014E-308 e
1.7976931348623157E+308. O M ´e a largura do display e o D ´e n´umero de
casa decimais. DOUBLE sem argumento ou FLOAT(X) onde 25 <= X <= 53 s˜ao
n´umeros de ponto flutuante de dupla-precis˜ao.
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
Estes s˜ao sinˆonimos para DOUBLE.
DECIMAL[(M[,D])] [ZEROFILL]
Um n´umero de ponto flutuante n˜ao empacotado. ao pode ser sem sinal. Se
comporta como um campo CHAR: “n˜ao empacotado” significa que o n´umero ´e
armazenado como uma string, usando um caracter para cada digito do valor.
O ponto decimal e, para n´umeros negativos, o sinal de menos (‘-’), ao s˜ao
contados em M (mas ´e reservado espa¸co para isto). Se Dfor 0, os valores n˜ao
ter˜ao ponto decimal ou parte fracion´aria. A faixa m´axima do valor DECIMAL ´e
a mesma do DOUBLE, mas a faixa atual para um campo DECIMAL dado pode ser
limitado pela escolha de MeD.
380 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se Dao for definido ser´a considerado como 0. Se Mao for definido ´e consid-
erado como 10.
Note que na vers˜ao 3.22 do MySQL o argumento Mtem que incluir o espa¸co
necess´ario para o sinal ´e o ponto decimal.
NUMERIC(M,D) [ZEROFILL]
Este ´e um sinˆonimo para DECIMAL.
DATE
Uma data. A faixa suportada ´e entre ’1000-01-01’ e’9999-12-31’. MySQL
mostra valores DATE no formato ’AAAA-MM-DD’, mas permite a vocˆe a atribuir
valores a campos DATE utilizando tanto strings quanto n´umeros. See hundefinedi
[DATETIME], page hundefinedi.
DATETIME
Um combina¸ao de hora e data. A faixa suportada ´e entre ’1000-01-01
00:00:00’ e’9999-12-31 23:59:59’. MySQL mostra valores DATETIME no
formato ’AAAA-MM-DD HH:MM:SS’, mas permite a vocˆe que atribuir valores a
campos DATETIME utilizado strings ou n´umeros. See hundefinedi[DATETIME],
page hundefinedi.
TIMESTAMP[(M)]
Uma estampa de tempo. A faixa ´e entre ’1970-01-01 00:00:00’ e algum
momento no ano 2037. MySQL mostra valores TIMESTAMP nos formatos
YYYYMMDDHHMMSS,YYMMDDHHMMSS,YYYYMMDD, ou YYMMDD, dependendo se M´e
14 (ou n˜ao definido), 12,8, ou 6, mas permite a vocˆe atribuir valores ao
campo TIMESTAMP usando strings ou n´umeros. Um cmapo TIMESTAMP ´e util
para gravar a data e a hora em uma opera¸ao de INSERT or UPDATE porque ´e
automaticamente definido a data e a hora da opera¸ao mais recente se vocˆe
pr´oprio n˜ao especificar um valor. Vocˆe tamb´em pode definir a data e a hora
atual atribuindo ao campo um valor NULL. See hundefinedi[Date and time
types], page hundefinedi.
Um TIMESTAMP sempre ´e armazenado em 4 bytes. O argumento Mo afeta como
a coluna TIMESTAMP ´e mostrada.
Note que colunas do tipo TIMESTAMP(X) columns onde X ´e 8 ou 14 s˜ao apre-
sentadas como n´umeros enquanto as outras colunas TIMESTAMP(X) ao strings.
Isto ´e apenas para assegurar que podemos eliminar e restaurar com seguran¸ca
tabelas com estes tipos! See hundefinedi[DATETIME], page hundefinedi.
TIME
Uma hora. A faixa ´e entre ’-838:59:59’ e’838:59:59’. MySQL mostra
valores TIME no formato ’HH:MM:SS’, mas permite a vocˆe atribuir valores para
as colunas TIME usando strings ou n´umeros. See hundefinedi[TIME], page hun-
definedi.
YEAR[(2|4)]
Um ano no formato de 2 ou 4 digitos (padr˜ao s˜ao 4 digitos). Os valores per-
mitidos est˜ao entre 1901 e2155,0000 no formato de 4 digitos, e 1970-2069
se vocˆe estiver usando o formato de 2 digitos (70-69). MySQL mostra valores
Chapter 6: Referˆencia de Linguagem do MySQL 381
YEAR no formato YYYY, mas permie atribuir valores aos campos do tipo YEAR
usando strings ou n´umeros. (O tipo YEAR ´e novo na vers˜ao 3.22 do MySL). See
hundefinedi[YEAR], page hundefinedi.
[NATIONAL] CHAR(M) [BINARY]
Uma string de tamanho fixo que ´e sempre preenchida a direita com espa¸cos at´e o
tamanho especificado quando armazenado. A faixa de M´e de 1 a 255 caracteres.
Espa¸cos extras s˜ao removidos quando o valor ´e recuperado. Valores CHAR ao
ordenados e comparados no modo caso insensitivo de acordo com o conjunto de
caracteres padr˜ao, a menos que a palavra chave BINARY seja utilizada.
NATIONAL CHAR (forma reduzida NCHAR) ´e o modo ANSI SQL de definir que um
campo CHAR deve usar o conjunto de caracteres padr˜ao. Isto ´e padr˜ao no
MySQL.
CHAR ´e uma simplifica¸c`ao para CHARACTER.
MySQL lhe permite criar um campo do tipo CHAR(0).Isto ´e muito ´util quando
vocˆe precisa de comptibilidade com aplicativos antigos que dependem da ex-
istˆencia de uma coluna, mas que, na verdade, n˜ao utiliza um valor. Isto tamb´em
´e muito bom quando vocˆe precisa de uma coluna que s´o pode receber 2 valores.
Um CHAR(0), que n˜ao ´e definido como um NOT NULL, o ir´a ocupar um bit e
pode assumir 2 valores: NULL or "". See hundefinedi[CHAR], page hundefinedi.
BIT
BOOL
CHAR Estes trˆes s˜ao sinˆonimos para CHAR(1).
[NATIONAL] VARCHAR(M) [BINARY]
Uma string de tamanho vari´avel. NOTA: Espa¸cos extras s˜ao removidos quando
o caracter ´e armazenado (o que difere da especifica¸ao ANSI SQL). A faixa de
M´e de 1 a 255 characters. Valores VARCHAR ao ordenados e comparados no
modo caso insensitivo a menos que a palavra chave BINARY seja utilizada. See
hundefinedi[Silent column changes], page hundefinedi.
VARCHAR ´e uma simplifica¸ao para CHARACTER VARYING. See hundefinedi
[CHAR], page hundefinedi.
TINYBLOB
TINYTEXT
Um campo BLOB ou TEXT com tamanho m´aximo de 255 (2^8 - 1) caracteres. See
hundefinedi[Silent column changes], page hundefinedi. See hundefinedi[BLOB],
page hundefinedi.
BLOB
TEXT
Um campo BLOB ou TEXT com tamanho m´aximo de 65535 (2^16 - 1) caracteres.
See hundefinedi[Silent column changes], page hundefinedi. See hundefinedi
[BLOB], page hundefinedi.
382 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MEDIUMBLOB
MEDIUMTEXT
Um campo BLOB ou TEXT com tamanho m´aximo de 16777215 (2^24 - 1) carac-
teres. See hundefinedi[Silent column changes], page hundefinedi. See hunde-
finedi[BLOB], page hundefinedi.
LONGBLOB
LONGTEXT
Um campo BLOB ou TEXT com tamanho m´aximo de 4294967295 (2^32 - 1)
caracteres. See hundefinedi[Silent column changes], page hundefinedi. See hun-
definedi[BLOB], page hundefinedi. Note que como o protocolo cliente/servidor
e tabelas MyISAM tem, atualmente, um limite de 16M por pacote de trans-
miss˜ao/registro de tabela, vocˆe ainda n˜ao pode utilizar toda a faixa de valores
deste tipo. See hundefinedi[BLOB], page hundefinedi.
ENUM(’valor1’,’valor2’,...)
Uma enumera¸ao. Um objeto string que s´o pode ter um valor, selecionado da
lista de valores ’valor1’,’valor2’,...,NULL ou valor especial de erro "".
Um ENUM pode ter um m´aximo de 65535 valores diferentes. See hundefinedi
[ENUM], page hundefinedi.
SET(’valor1’,’valor2’,...)
Um conjunto. Um objeto string que pode ter zero ou mais valores, cada um
deve ser selecionado da lista de valores ’valor1’,’valor2’,.... Um SET pode
ter at´e 64 membros. See hundefinedi[SET], page hundefinedi.
6.2.1 Tipos Num´ericos
MySQL suporta todos os tipos num´ericos da ANSI/ISO SQL92. Estes tipos incluem o tipos
de dados num´ericos exatos (NUMERIC,DECIMAL,INTEGER, e SMALLINT), assim como o tipos
de dados num´ericos aproximados (FLOAT,REAL, e DOUBLE PRECISION). A palavra-chave INT
´e um sinˆonimo para INTEGER, e a palavra-chave DEC ´e um sinˆonimo para DECIMAL.
Os tipos NUMERIC eDECIMAL ao implementados como o mesmo tipo pelo MySQL, como
permitido pelo padr˜ao SQL92. Eles s˜ao usados por valores para os quais ´e importante
preservar a exatid˜ao como, por exemplo, dados monet´arios. Quando ´e declarado um campo
de algum desses tipos a precis˜ao e a escala podem ser (e normalmente ´e) especificadas; por
exemplo:
salario DECIMAL(9,2)
Neste exemplo, 9(precis~ao) representa o n´umero de digitos decimais significantes que ser˜ao
armazenados no valor, e 2(escala) representa o n´umero de d´
igitos que ser˜ao armazenados
ap´os o ponto decimal. Neste caso, no entanto, a faixa de valores que podem ser armazendos
na coluna salario ´e de -9999999.99 a9999999.99. (MySQL pode, na verdade, armazenar
numeros acima de 9999999.99 neste campo porque ele n˜ao precisa armazenar o sinal para
n´umeros positivos).
Em ANSI/ISO SQL92, a sintaxe DECIMAL(p) ´e equivalente a DECIMAL(p,0). Da mesma
forma, a sintaxe DECIMAL ´e equivalente a DECIMAL(p,0), onde a implementa¸ao permite
decidir o valor de p. MySQL ainda n˜ao suporta nenhuma dessas duas formas variantes
dos tipos de dados DECIMAL/NUMERIC. Este, geralmente, n˜ao ´e um problema s´erio, a que
Chapter 6: Referˆencia de Linguagem do MySQL 383
os principais benef´
icios destes tipos derivam da habilidade de controlar precis˜ao e escala
explicitamente.
Valores DECIMAL eNUMERIC ao armazenados como strings, ao inv´es de um numero de ponto-
flutuante bin´ario, para preservar o precis˜ao decimal destes valores. Um caracter ´e usado
para cada digito, para o ponto decimal (se escala > 0), e para o sinal ‘-’ (para n´umeros
negativos). Se escala ´e 0, valores DECIMAL eNUMERIC ao cont´em ponto decimal ou parte
fracion´aria.
A faixa m´axima dos valores DECIMAL eNUMERIC ´e o mesmo do DOUBLE, mas a faixa real para
um campo DECIMAL or NUMERIC pode ser limitado pela precis~ao ou pela escala para uma
dada coluna. Quando ´e atribu´
ido a uma coluna um valor com mais digitos ap´os o ponto
decimal do que o permitido especificado na escala, o valor ´e arredondado para aquela
escala. Quando ´e atribuido um valor a uma coluna DECIMAL ou NUMERIC o qual excede a
faixa determinada pelas precis~ao eescala especificada (ou padr˜ao), MySQL armazena o
valor correspondente ao final daquela faixa.
Como uma extens˜ao do padr˜ao ANSI/ISO SQL92, MySQL tamb´em suporta os tipos in-
tegrais TINYINT,MEDIUMINT, e BIGINT como listado nas tabelas abaixo. Outra extens˜ao
suportada pelo MySQL ´e especificar, opcionalmente, o tamanho do display de um valor
inteiro entre parenteses seguindo o nome do tipo (por exemplo, INT(4)). Esta especifica¸ao
opcional do tamanho ´e usada para preenchimento a esquerda do display de valores cujo
tamanho ´e menor que o especificado para a coluna, mas n˜ao limita a faixa de valores que
podem ser armazendos na coluna, nem o n´umero de d´
igitos que ser˜ao mostrados para va-
lores que excederem o tamanho especificado na coluna. Quando usados em conjunto com o
atributo opcional de extens˜ao ZEROFILL, o padr˜ao do preenchimento de espa¸cos ´e a substi-
tui¸ao por zeros. Por exemplo, para uma coluna declarada com INT(5) ZEROFILL, o valor
4´e retornado como 00004. Note que se vocˆe armazenar valores maiores que a largura do
display em um coluna do tipo inteiro, vocˆe pode ter problemas quando o MySQL gerar
tabelas tempor´arias para algum join complicado, j´a que nestes casos o MySQL acredita que
os dados cabem na largura original da coluna.
Todos os tipos inteiros podem ter um atributo opcional (n˜ao-padr˜ao) UNSIGNED. Valores
sem sinal podem ser usados quando vocˆe permite apenas n´umeros positivos em uma coluna
e vocˆe precisa de uma faixa de valores um pouco maior para a coluna.
O tipo FLOAT ´e usado para representar tipos de dados num´ericos aproximados. O padr˜ao
ANSO/ISO SQL92 permite especifica¸ao opcional da precis˜ao (mas ao da faixa do ex-
poente) em bits, ap´os a a palavra FLOAT e entre parenteses. A implementa¸ao MySQL
tamb´em suporta esta especifica¸ao opcional de precis˜ao. Quando FLOAT ´e usada para uma
tipo de coluna sem especifica¸ao de precis˜ao, MySQL utiliza quatro bytes para armazenar
os valores. Uma sintaxe variante tamb´em ´e suportada, com dois numeros entre parenteses
ap´os a palavra FLOAT. Com esta op¸ao, o primeiro n´umero continua a representar a quan-
tidade de bytes necess´aria para armazenar o valor, e o segundo n´umero especifica o n´umero
de d´
igitos a serem armazenados e mostrados ap´os o ponto decimal (como com DECIMAL e
NUMERIC). Quando ´e pedido ao MySQL para armazenar um n´umero em uma coluna com
mais digitos decimais ap´os o ponto decimal que o especificado para esta coluna, o valor ´e
arredondado eliminando os digitos extras quando armazenado.
Os tipos REAL eDOUBLE PRECISION ao aceitam especifica¸oes de precis˜ao. Como uma ex-
tens˜ao do padr˜ao ANSI/ISO SQL92, MySQL reconhece DOUBLE como um sinˆonimo para o
384 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
tipo DOUBLE PRECISION. Em constraste com a exigencia do padr˜ao de que a precis˜ao do
tipo REAL seja menor que aquele usado pelo DOUBLE PRECISION, MySQL implementa ambos
como valores de ponto flutuante de 8 bits de dupla precis˜ao (quando n˜ao estiver executando
em “modo ANSI”). Para uma portabilidade m´axima, c´odigos que requerem armazenamento
de valores de dados num´ericos aproximados usam FLOAT ou DOUBLE PRECISION sem especi-
fica¸ao de precis˜ao ou de numeros decimais.
Quando solicitado a armazenar um valor em uma coluna num´erica que est´a fora da faixa
permitida pelo tipo da coluna, o MySQL ajusta o valor ao limite da faixa permitida mais
apropriado e armazena este valor.
Por exemplo, a faixa de uma coluna INT ´e de -2147483648 a2147483647. Se vocˆe tentar
inserir -9999999999 em uma coluna INT, o valor ´e ajustado para o limite mais baixo da
faixa de valores e -2147483648 ´e armazenado. Da mesma forma, se vocˆe tentar inserir
9999999999,2147483647 ser´a armazenado.
Se o campo INT ´e UNSIGNED, o tamanho da faixa do campo ´e o mesmo mas o limite passa
a ser de 0a4294967295. Se vocˆe tentar armazenar -9999999999 e9999999999, os valores
armazenados na coluna ser˜ao 0e4294967296.
Convers˜oes que ocorrem devido a ajustes s˜ao relatados como “avisos” para ALTER TABLE,
LOAD DATA INFILE,UPDATE, e instru¸oes INSERT multi-registros.
6.2.2 Tipos de Data e Hora
Os tipos de data e hora s˜ao DATETIME,DATE,TIMESTAMP,TIME, e YEAR. Cada um desses
tipos tem uma faixa de valores legais, assim com um valor “zero” que ´e usado quando
vocˆe especifica um valor ilegal. Note que o MySQL permite que vocˆe armazene certos
valores de datas inexistentes, como 1999-11-31. A raz˜ao para isto ´e que pensamos que ´e
responsabilidade do aplicativo tratar das verifica¸oes de data, n˜ao do servidor SQL. Para
fazer uma verifica¸ao ’r´apida’ de data, MySQL s´o checa se o mˆes est´a na faixa de 0-12
e o dia est´a na faixa de 0-31. As faixas acima s˜ao definidas desta forma porque MySQL
lhe permite armazenar, em um campo DATE ou DATETIME, datas onde o dia ou o dia/mˆes
ao zero. Isto ´e extremamente ´util para aplicativos que precisam armazenar uma data de
nascimento na qual vocˆe n˜ao sabe a data exata. Nestes casos vocˆe simplesmente armazena
a data como 1999-00-00 ou 1999-01-00. (Voe n˜ao pode esperar obter um valor correto
para fun¸oes como DATE_SUB() ou DATE_ADD para datas como estas.)
Aqui est˜ao algumas considera¸oes para ter em mente quando estiver trabalhando com tipos
de data e hora.
MySQL recupera valores para um tipo de data ou hora dado em um formato padr˜ao,
mas ele tenta interpretar uma variedade de formatos para os valores fornecidos (por
exemplo, quando vocˆe especifica um valor a ser atribuido ou comparado a um tipo de
data ou hora). No entanto, s´o os formatos descritos na se¸ao seguinte s˜ao suportados. ´
E
esperado que vocˆe forne¸ca valores permitidos. Resultados imprevisiveis podem ocorrer
se vocˆe usar outros formatos.
Embora o MySQL tente interpretar valores em diversos formatos, ele sempre espera
que a parte da data referente ao ano esteja mais a esquerda do valor. Datas devem ser
dadas na ordem ano-mˆes-dia (por exemplo, ’98-09-04’), ao inv´es das ordens mais
usadas mˆes-dia-ano ou dia-mˆes-ano (por exemplo: ’09-04-98’,’04-09-98’).
Chapter 6: Referˆencia de Linguagem do MySQL 385
MySQL converte automaticamente um tipo de data ou hora em um n´umero se o valor
´e usado em um contexto num´erico, e vice-versa.
Quando o MySQL encontra um valor para um tipo de data ou hora que est´a fora da
faixa permitida ou ´e ilegal neste tipo (veja o in´
icio desta se¸ao), ele converte o valor
para “zero”. (A exce¸ao ocorre no campo TIME, onde o valor fora da faixa ´e ajustado
para o valor limite apropriado na faixa de valores deste tipo.) A tabela abaixo mostra
o formato do valor “zero” para cada tipo:
Tipo de Coluna Valor “Zero”
DATETIME ’0000-00-00 00:00:00’
DATE ’0000-00-00’
TIMESTAMP 00000000000000 (tamanho depende do tamanho do display)
TIME ’00:00:00’
YEAR 0000
Os valores “zero” s˜ao especiais, mas vocˆe pode armazenar ou fazer referˆencia a eles
explicitamente usando os valores mostrados na tabela. Vocˆe tamb´em pode fazer into
usando ’0’ ou 0, o que ´e mais f´acil de escrever.
Valores “zero” para data ou hora usados em MyODBC ao convertidos automatica-
mente para NULL na vers˜ao 2.50.12 MyODBC e acima, porque ODBC n˜ao pode tratar
tais valores.
6.2.2.1 Assuntos referentes ao ano 2000 (Y2K) e Tipos de Data
O MySQL tem sua pr´opria seguran¸ca para o ano 2000 (see hundefinedi[compatibilidade com
o ano 2000], page hundefinedi), mas os dados entrados no MySQL podem ao ter. Qualquer
entrada contendo valores de ano de 2 digitos ´e amb´
iguo, porque o s´eculo ´e desconhecido.
Tais valores devem ser interpretados na forma de 4 digitos j´a que o MySQL armazena anos
internamente utilizando 4 digitos.
Para tipos DATETIME,DATE,TIMESTAMP eYEAR, MySQL interpreta datas com valores
amb´
iguos para o ano usando as seguintes regras:
Valores de ano na faixa 00-69 ao convertidos para 2000-2069.
Valores de anos na faixa 70-99 ao convertidos para 1970-1999.
Lembre-se de que essas regras fornecem apenas palpites razo´aveis sobre o que a sua data
significa. Se a heur´
istica usada pelo MySQL n˜ao produz o valor vocˆe deve fornecer entre
sem ambiguidade contendo valores de ano de 4 digitos.
ORDER BY ir´a ordenar tipos YEAR/DATE/DATETIME de 2 digitos apropriadamente.
Note temb´em que algumas fun¸oes com MIN() eMAX() ir˜ao converter TIMESTAMP/DATE
para um n´umero. Isto significa que um timestamp com ano de 2 digitos n˜ao ir´a funcionar
corretamente com estas fun¸oes. A solu¸ao neste caso ´e converter o TIMESTAMP/DATE para
um formato de ano de 4 digitos ou usar algo como MIN(DATE_ADD(timestamp,INTERVAL 0
DAYS)).
6.2.2.2 Os Tipos DATETIME,DATE eTIMESTAMP
Os tipos DATETIME,DATE, e TIMESTAMP ao relacionados. Esta se¸ao descreve suas cara-
cter´
isticas, como eles se assemelham ou como se diferem.
386 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O tipo DATETIME ´e usado quando vocˆe precisa de valores que cont´em informa¸oes sobre
data e a a hora. MySQL recupera e mostra valores DATETIME no formato ’YYYY-MM-DD
HH:MM:SS’. A faixa suportada ´e de ’1000-01-01 00:00:00’ at´e ’9999-12-31 23:59:59’.
(“Suportada” significa que embora valores anteriores possam funcionar, ao h´a nenhura
garantia de disto.)
O tipo DATA ´e usado quando se necessita apenas do valor da data, sem a parte da hora.
MySQL recupera e mostra valores do tipo DATA no formato ’YYYY-MM-DD’. A faixa supor-
tada ´e de ’1000-01-01’ at´e ’9999-12-31’.
O tipo de campo TIMESTAMP fornece um tipo que pode ser usado para, automaticamente,
marcar opera¸oes INSERT or UPDATE com a data e hora atual. Se vocˆe tiver multiplas colunas
TIMESTAMP, s´o a primeira ´e atualizada automaticamente.
Atualiza¸oes automaticas da primeira coluna TIMESTAMP ocorrem sob qualquer uma das
seguintes condi¸oes:
A coluna n˜ao ´e explicitamente especificada em uma instru¸ao INSERT ou LOAD DATA
INFILE.
A coluna n˜ao ´e explicitamente especificada em uma instru¸c˜ao UPDATE e e alguma outra
coluna muda o valor. (Note que um UPDATE que coloca em uma coluna o mesmo
valor que ele j´a possui n˜ao ir´a causar a atualiza¸ao da coluna TIMESTAMP, porque se
vocˆe atribui a uma coluna o seu valor atual, MySQL ignora a atualiza¸ao para maior
eficiˆencia).
Voe define explicitamente a uma coluna TIMESTAMP o valor NULL.
Outras colunas TIMESTAMP, al´em da primeira podem ser definidas com a data e hora atuais.
Basta defini-las com NULL ou NOW()
Voe pode definir colunas TIMESTAMP com um valor diferente da data e hora atuais colocando
explicitamente o valor desejado. Isto ´e verdade mesmo para a primeira coluna TIMESTAMP.
Voe pode usar esta propriedade se, por exemplo, vocˆe quiser que um TIMESTAMP tenha seu
valor definido como a data e hora atuais na cria¸ao de registros, mas n˜ao quer alter´a-los
quando o registro for atualizado mais tarde:
Deixe o MySQL definir a coluna quando o registro ´e criado. Isto ir´a inicializa-la com
a data e hora atuais.
Quando vocˆe realizar subsequentes atualiza¸oes em outras colunas do registro, defina
explicitamente a coluna TIMESTAMP com o valor atual.
Por outro lado, vocˆe pode achar que ´e mais f´acil usar uma coluan DATETIME que vocˆe inicial-
iza com NOW() quando o registro for criado e deixa como est´a em atualiza¸oes subsequentes.
Valores TIMESTAMP podem ter valores do incio de 1970 at´e algum momento do ano 2037,
com a resolu¸ao de um segundo. Valores s˜ao mostrados como n´umeros
O formato no qual o MySQL recupera e mostra valores TIMESTAMP depende do tamanho
do display, como ilustrado pela tabela que se segue: O formato ‘cheio’ TIMESTAMP ´e de 14
digitos, mas colunas TIMESTAMP podem ser criadas com tamanho de display menores:
Tipo da Coluna Formato do Display
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
Chapter 6: Referˆencia de Linguagem do MySQL 387
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY
Todas as colunas TIMESTAMP tem o mesmo tamanho de armazenamento, independente do
tamanho de display. Os tamanhos de display mais comuns s˜ao 6, 8, 12, e 14. Voe pode
especificar um tamanho de display arbitrario na hora da cria¸ao da tabela, mas valores de
0 ou maiores que 14 s˜ao mudados para 14. Valores ´
impares de tamanho na faixa de 1 a 13
ao mudados para o maior n´umero par mais pr´oximo.
Nota: Na vers˜ao 4.1, TIMESTAMP ´e retornado com uma string com o formato ’YYYY-MM-DD
HH:MM:DD’, e timestamp de diferentes tamamnhos n˜ao s˜ao mais suportados.
Voe pode especificar calores DATETIME,DATE eTIMESTAMP usando qualquer conjunto de
formatos comum:
Como uma string nos formatos ’YYYY-MM-DD HH:MM:SS’ ou ’YY-MM-DD HH:MM:SS’.
Uma sintaxe “relaxada” ´e permitida---nenhum caracter de pontua¸ao pode ser usado
como um delimitador entre parte de data ou hora. Por exemplo, ’98-12-31 11:30:45’,
’98.12.31 11+30+45’,’98/12/31 11*30*45’, e ’98@12@31 11^30^45’ ao equiva-
lentes.
Como uma string nos formatos ’YYYY-MM-DD’ ou ’YY-MM-DD’. Uma sintaxe “relaxada”
´e permitida aqui tamb´em. Por exemplo, ’98-12-31’,’98.12.31’,’98/12/31’, e
’98@12@31’ ao equivalentes.
Como uma string sem delimitadores nos formatos ’YYYYMMDDHHMMSS’ ou
’YYMMDDHHMMSS’, desde que a string fa¸ca sentido como data. Por example,
’19970523091528’ e’970523091528’ ao interpretadas com ’1997-05-23
09:15:28’, mas ’971122129015’ ´e ilegal (tem uma parte de minutos sem sentido) e
se torna ’0000-00-00 00:00:00’.
Como uma string sem delimitadores nos formatos ’YYYYMMDD’ ou ’YYMMDD’, desde
que a string tenha sentido com data. Por exemplo, ’19970523’ e’970523’ ao in-
terpretedas como ’1997-05-23’, mas ’971332’ ´e ilegal (tem uma parte de mˆes sem
sentido) e se torna ’0000-00-00’.
Como um n´umero nos formatos YYYYMMDDHHMMSS ou YYMMDDHHMMSS, desde que o
n´umero fa¸ca sentido como uma data. Por exemplo, 19830905132800 e830905132800
ao interpretedos como ’1983-09-05 13:28:00’.
Como um n´umero nos formatos YYYYMMDD ou YYMMDD, desde que o n´umero fa¸ca sentido
como data. Por exemplo, 19830905 e830905 ao interpretedos como ’1983-09-05’.
Como o resultado de uma fun¸ao que retorne uma valor aceitavel em um contexto
DATETIME,DATE ou TIMESTAMP, tal como NOW() ou CURRENT_DATE.
Valores DATETIME,DATE, ou TIMESTAMP ilegais s˜ao convertidos para o valor “zero” do tipo
apropriado (’0000-00-00 00:00:00’,’0000-00-00’,ou00000000000000).
Para valores especificados com strings que incluem delimitadores de data, n˜ao ´e necess´ario
especificar dois digitos para valores de mˆes ou dia qua s˜ao menores que 10.’1979-6-9’
´e o mesmo que ’1979-06-09’. Similarmente, para valores especificados como strings que
incluem delimitadores de hora, ao ´e necess´ario especificar dois digitos para valores de
388 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
hora, minutos ou segundo que s˜ao menores que 10.’1979-10-30 1:2:3’ e o mesmo que
’1979-10-30 01:02:03’.
Valores especificados como n´umeros devem ter 6, 8, 12, ou 14 digitos. Se o n´umero ´e de
8 ou 14 digitos, ele assume estar no formato YYYYMMDD ou YYYYMMDDHHMMSS e que o ano
´e dado pelos 4 primeiros d´
igitos. Se o ´e de 6 ou 12 d´
igitos, ele assume estar no formato
YYMMDD or YYMMDDHHMMSS e que o ano ´e dado pelos 2 primeiros digitos. umeros que n˜ao
possua estes tamanho s˜ao interpretados como calores preenchidos com zero at´e o tamanho
mais pr´oximo.
Valores especificados como strings n˜ao delimitadas s˜ao interpretados usando o seu tamanho
como dado. Se a string possui 8 ou 14 caracteres, o ano ´e assumido como os 4 primeiros
caracteres. De outra forma o assume-se que o ano s˜ao os 2 primeiros caracteres. A string
´e interpretadada esquerda para direita para encontrar os valores do ano, mˆes, dia, hora,
minute e segundo, para as partes da string. Isto significa que vocˆe n˜ao deve utilizar strings
com menos de 6 caracteres. Por exemplo, se vocˆe especificar ’9903’, pensando em repre-
sentar Mar¸co de 1999, vocˆe perceber´a que o MySQL insere uma data “zero” em sua tabela.
Isto ocorre porque os valores do ano e mˆes s˜ao 99 e03, mas a parte contendo o dia n˜ao
existe (zero), enao o valor n˜ao ´e uma data legal.
Colunas TIMESTAMP armazena valores legais utilizando precis˜ao total com a qual os valores
foram especificados, independente do tamanho do display. Isto tem diversas implica¸oes:
Sempre especifique o ano, mˆes e dia, mesmo se seus tipos de coluna s˜ao TIMESTAMP(4)
ou TIMESTAMP(2). De outra forma, os valores n˜ao ser˜ao datas legais date e um 0ser´a
armazenado.
Se vocˆe usa ALTER TABLE para aumentar uma coluna TIMESTAMP, informa¸oes ser˜ao
mostradas como se antes estivessem “escondidas”.
De forma similar, reduzindo o tamanho de uma coluna TIMESTAMP ao causa perda de
informa¸ao, exceto no sentido de que menos informa¸ao aparece quando os valores s˜ao
mostrados.
Embora os valores TIMESTAMP sejam armazenados com precis˜ao total, a ´unica fun¸ao
que opera diretamente com o valor armazenado ´e UNIX_TIMESTAMP(). OUtras fun¸oes
operam com o formato do valor recuperado Isto significa que n˜ao se pode usar fun¸oes
como HOUR() or SECOND() a menos que a parte relevante do valor TIMESTAMP esteja
inclu´
ido no valor formatado. POr exemplo, a parte HH de uma coluna TIMESTAMP ao
´e mostrada a menos que o tamanho do display seja de pelo menos 10, logo tentar usar
HOUR() em um valor TIMESTAMP menor produz um resultado sem significado.
Voe pode, algumas vezes, atribuir valores de um tipo de data para um objeto de um
diferente tipo de data. No entanto pode haver algumas altera¸oes de valores ou perda de
informa¸ao
Se vocˆe atribuir um valor de DATE value a um objeto DATETIME ou TIMESTAMP, a parte
da hora do valor resultante ´e definido como ’00:00:00’, porque o vlaor DATE ao
cont´em informa¸oes de hora.
Se vocˆe atribuir um valor DATETIME ou TIMESTAMP para um objeto DATE, a parte da
hora do valor resultante ´e deletado, pois o tipo DATE ao armazena informa¸oes de
hora.
Lembre-se de que embora todos os valores DATETIME,DATE, e TIMESTAMP possam ser
especificados usando o mesmo conjunto de formatos, os tipos n˜ao tem a mesa faixa de
Chapter 6: Referˆencia de Linguagem do MySQL 389
valores. Por exemplo, valores TIMESTAMP ao podem ser anteriores a 1970 ou posteriores
a2037. Isto significia que datas como ’1968-01-01’, s˜ao permitidas como valores
DATETIME ou DATE, mas n˜ao s˜ao v´alidas para valores TIMESTAMP e ser˜ao covertidas para
0se atribuidas para tais objetos.
Esteja ciente de certas dificuldades quando especificar valores de data:
A forma “relaxada” permitida em valores especificados com strings podem causar certas
confus˜oes. Por exemplo, um valor como ’10:11:12’ pode parecer com um valor de
hora devido ao limitador ‘:’, mas se usado em um contexto de data ser´a interpretado
como o ano ’2010-11-12’. O valor ’10:45:15’ ser´a convertido para ’0000-00-00’
pois ’45’ ao ´e um valor de mˆes permitido.
O servidor MySQL funciona basicamente checando a validade da data: dias entre 00-
31, mˆes entre 00-12, anos entre 1000-9999. Qualquer data que n˜ao esteja nesta faixa
ser´a revetida para 0000-00-00. Por favor, note que isto ainda lhe permite armazenar
datas invalidas tais como 2002-04-31. Isto permite a aplica¸oes web armazenar dados
de um formul´ario sem verifica¸oes adicionais. Para assegurar que a data ´e valida, fa¸ca
a checagem em sua aplica¸ao.
Valores de anos especificados com 2 digitos s˜ao amb´
iguos, pois o s´eculo n˜ao ´e conhecido.
MySQL interpreta valores de anos com dois digitos usando as seguintes regras:
Valores de ano na faixa de 00-69 ao convertidos para 2000-2069.
Valores de ano na faixa de 70-99 ao convertidos para 1970-1999.
6.2.2.3 O tipo TIME
O MySQL recupera e mostra valores TIME no formato ’HH:MM:SS’ (ou no formato
’HHH:MM:SS’ para valores grandes). Volares TIME podem estar na faixa de ’-838:59:59’
at´e ’838:59:59’. A raz˜ao para a parte da hora ser t˜ao grande ´e que o tipo TIME pode ser
usado n˜ao apenas para representar a hora do dia (que deve ser menor que 24 horas), mas
tamb´em para tempo restante ou intervalos de tempo entre dois eventos(que podem ser
maior que 24 horas ou mesmo negativo).
Voe pode especificar valores TIME de variadas formas:
Como uma string no formato ’D HH:MM:SS.fra¸c~ao’ . (Note que o MySQL n˜ao ar-
mazena ainda fra¸oes para a coluna time.) Pode-se tamb´em utilizar uma das seguintes
sintaxes “relaxadas”:
HH:MM:SS.fra¸c~ao,HH:MM:SS,HH:MM,D HH:MM:SS,D HH:MM,D HH ou SS. Aqui D´e um
dia entre 0-33.
Como uma string sem delimitadores no formato ’HHMMSS’, desde que ela tenha sentido
como uma hora. Por exemplo, ’101112’ ´e esntendido como ’10:11:12’, mas ’109712’
´e ilegal (a parte dos minutos n˜ao tem nenhum sentido) e se torna ’00:00:00’.
Como um n´umero no formato HHMMSS , desde que tenha sentido como uma hora. Por
exemplo, 101112 ´e entendido com ’10:11:12’. Os formatos alternativos seguintes
tamb´em s˜ao entendidos: SS,MMSS,HHMMSS eHHMMSS.fra¸c~ao. Note que o MySQL
ainda n˜ao armazena fra¸oes.
Como o resultado de uma fun¸ao que retorne um valor que ´e aceit´avel em um contexto
do tipo TIME, tal como CURRENT_TIME.
390 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Para valores TIME especificados como uma string que incluem delimitadores de hora, n˜ao
´e necess´ario especificar dois d´
igitos para valores de hora, minutos ou segundos que sejam
menores que 10.’8:3:2’ ´e o mesmo que ’08:03:02’.
Seja cuidadoso ao atribuir valores TIME “pequenos” para uma coluna TIME. Sem dois pontos,
o MySQL interprete valores assumindo que os digitos mais a direita representam segundos.
(MySQL interpreta valores TIME como tempo decorrido ao inv´es de hora do dia.) Por
exemplo, vocˆe poderia pensar em ’1112’ e1112 significam ’11:12:00’ (11 horas e 12
minutos), mas o MySQL o intepreta como ’00:11:12’ (onze minutos e 12 segundos). De
forma similar, ’12’ e12 ao interpretados como ’00:00:12’. Valores TIME com dois pontos,
em contrapartida, s˜ao tratados como hora do dia. Isto ´e, ’11:12’ significar´a ’11:12:00’,
ao ’00:11:12’.
Valores que s˜ao legais mas que est˜ao fora da faixa permitidas s˜ao ajustados para o valor
limita da faixa mais apropriado. Por exemplo, ’-850:00:00’ e’850:00:00’ ao conver-
tidos para ’-838:59:59’ e’838:59:59’, respectivmente.
Valores TIME ilegais s˜ao convertidos para ’00:00:00’. Note que como ’00:00:00’ ´e um
valor TIME, n˜ao temos com dizer, a partir de um valor ’00:00:00’ armazenado na tabela,
se o valor original armazenado foi especificado como ’00:00:00’ ou se foi ilegal.
6.2.2.4 The YEAR Type
O tipo YEAR ´e um tipo de 1 byte usado para representar anos.
O MySQL recupera e mostra valores YEAR no formato YYYY. A faixa de valores ´e de 1901
at´e 2155.
Voe pode especificar valores YEAR em uma variedade de formatos:
Como uma string de 4 digitos na faixa de ’1901’ at´e ’2155’.
Como um n´umero de 4 d´
igitos na faixa de 1901 at´e 2155.
Como uma string de dis d´
igitos na faixa ’00’ at´e ’99’. Valores na faixa de ’00’ at´e
’69’ e’70’ at´e ’99’ ao convetidas para valores YEAR na faixa de 2000 at´e 2069 e
1970 at´e 1999.
Como um n´umero de 2 digitos na faixa de 1at´e 99. Valores na faixa de 1at´e 69 e70
at´e 99 ao convertidos para valores YEAR na faixa de 2001 at´e 2069 e1970 at´e 1999.
Note que a faixa para n´umeros de dois d´
igitos ´e um pouco diferente da faixa de strings
de dois d´
igitos, pois n˜ao se pode especificar zero diretamente como um n´umero e tˆe-lo
interpretado com 2000. Voe deve especific´a-lo como uma string ’0’ ou ’00’ ou ele
ser´a interpretado com 0000.
Como o resultado de uma fun¸ao que retorna um valor que ´e aceit´avel em um contexto
do tipo YEAR, tal como NOW().
Valores YEAR ilegais s˜ao convertidos para 0000.
6.2.3 Tipos String
Os tipos strings s˜ao CHAR,VARCHAR,BLOB,TEXT,ENUM, e SET. Esta se¸ao descreve como
este tipos funcionam, suas exigˆencias de armazenamento e como us´a-los em suas consultas.
Tipo Tam.max´
imo Bytes
Chapter 6: Referˆencia de Linguagem do MySQL 391
TINYTEXT ou TINYBLOB 2^8-1 255
TEXT ou BLOB 2^16-1 (64K-1) 65535
MEDIUMTEXT ou MEDIUMBLOB 2^24-1 (16M-1) 16777215
LONGBLOB 2^32-1 (4G-1) 4294967295
6.2.3.1 Os tipos CHAR eVARCHAR
Os tipos CHAR eVARCHAR ao parecidos, mas diferem no modo como s˜ao armazenados e
recuperados.
O tamanho de um campo CHAR ´e fixado pelo tamanho declarado na cria¸ao da tabela. O
tamanho pode ser qualquer valor entre 1 e 255 (Como na vers˜ao 3.23 do MySQL, o tamanho
pode ser de 0 a 255). Quando valores CHAR ao armazenados, eles s˜ao preenchidos a direita
com espa¸cos at´e o tamanho especificado. Quando valores CHAR ao recuperados, espa¸cos
extras s˜ao removidos.
Valores no campo VARCHAR ao strings de tamanho vari´avel. Vocˆe pode declarar um campo
VARCHAR para ter qualquer tamanho entre 1 e 255, assim como para campo CHAR. No entanto,
diferente de CHAR, valores VARCHAR ao armazendos usando apenas quantos caracteres forem
necess´arios, mais 1 byte para gravar o tamanho. Valores n˜ao s˜ao preenchidos; ao contr´ario,
espa¸cos extras s˜ao removidos quando valores s˜ao armazenados. (Esta remo¸ao de espa¸cos
difere das especifica¸oes do SQL-99).
Se vocˆe atribuir um valor para uma coluna CHAR ou VARCHAR que exceda o tamanho m´aximo
da coluna, o valor ´e truncado para este tamanho.
A seguinte tabela ilustra as diferen¸cas entre os dois tipos de colunas, mostrando o resultado
de se armazenar v´arios valores de strings em campos CHAR(4) eVARCHAR(4):
Valor CHAR(4) Exigˆencia p/
armazenamento
VARCHAR(4) Exigˆencia p/
armazenamento
’’ ’ ’ 4 bytes ’’ 1 byte
’ab’ ’ab ’ 4 bytes ’ab’ 3 bytes
’abcd’ ’abcd’ 4 bytes ’abcd’ 5 bytes
’abcdefgh’ ’abcd’ 4 bytes ’abcd’ 5 bytes
Os valores recuperados para as colunas CHAR(4) eVARCHAR(4) ser˜ao os mesmos em cada
caso, j´a que espa¸cos ectras s˜ao removidos das colunas CHAR quando recuperados.
Valores nas colunas CHAR eVARCHAR ao ordenados e comparadaos no modo caso-insensitivo,
a menos que o atributo BINARY seja especificado quando a tabela for criada. O atributo
BINARY significa que os valores das colunas s˜ao ordenados e comparados no modo caso-
sensitivo de acordo com a ordem ASCII da maquina onde o servidor MySQL est´a sesndo
executado. BINARY ao afeta como as colunas s˜ao armazenadas e recuperadas.
O atributo BINARY ´e pegajoso. Isto significa que se uma coluna definida com BINARY ´e
usada na express˜ao, toda a express˜ao ´e comparada como um valor BINARY.
MySQL pode alterar sem aviso o tipo de uma coluna CHAR ou VARCHAR na hora de criar a
tabela. See hundefinedi[Silent column changes], page hundefinedi.
6.2.3.2 Os Tipos BLOB eTEXT
Um BLOB ´e um objeto binario grande que pode guardar um montante variado de da-
dos. Os quatro tipos BLOB:TINYBLOB,BLOB,MEDIUMBLOB, e LONGBLOB diferem apenas
392 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
no tamanho maximo dos valores que eles podem guradar. See hundefinedi[Storage require-
ments], page hundefinedi.
Os quatro tipos TEXT:TINYTEXT,TEXT,MEDIUMTEXT, e LONGTEXT correspondem aos quatro
tipos BLOB e tˆem o mesmo tamanho m´aximo e necessidade de tamanho para armazenamento.
A ´unica diferen¸ca entre os tipos BLOB eTEXT ´e que ordena¸ao e compara¸ao s˜ao realizadas
no modo caso-sensitivo para valores BLOB e no modo caso-insensitivo para valores TEXT. Em
outras palavras, um TEXT ´e um BLOB no modo caso-insensitivo.
Se vocˆe atribuir um valor a uma coluna BLOB ou TEXT que exceda o tamanho m´aximo do
tipo da coluna, o valor ´e truncado para servir ao campo.
Em muitos casos, podemos considerar um campo TEXT como um campo VARCHAR que pode
ser t˜ao grande quando desejamos. Da mesma forma podemos considerar um campo BLOB
como um campo VARCHAR BINARY. As diferen¸cas s˜ao:
Voe pode ter indices em um campo BLOB eTEXT no MySQL Vers˜ao 3.23.2 e mais
novas. Vers˜oes antigas do MySQL n˜ao suportam isto.
ao h´a remo¸ao de espa¸cos extras para campos BLOB eTEXT quando os valores s˜ao
armazenados, como h´a em campos VARCHAR.
Colunas BLOB eTEXT ao podem ter valores padr˜oes.
MyODBC define valores BLOB como LONGVARBINARY e valores TEXT como LONGVARCHAR.
Como valores BLOB eTEXT podem ser extremamentes longos, vocˆe pode deparar com alguns
problemas quando utiliz´a-los:
Se vocˆe quiser utilizar GROUP BY ou ORDER BY em um campo BLOB ou TEXT, vocˆe deve
converte-los em objetos de tamanho fixo. O modo padr˜ao de se fazer isto ´e com a
fun¸ao SUBSTRING. Por exemplo:
mysql> SELECT comentario FROM nome_tabela,SUBSTRING(comentario,20) AS substr
-> ORDER BY substr;
Se vocˆe n˜ao fizer isto, s´o os primeiros max_sort_length bytes de uma coluna ser˜ao
utilizados na ordena¸ao. O valor padr˜ao de max_sort_length ´e 1024; este calor pode
ser alterado utilizando-se a op¸ao -O quando o servidor ´e inicializado. Vocˆe pode
agrupar uma express˜ao envolvendo valores BLOB ou TEXT especificando a posi¸ao da
coluna ou utilizando apelidos (alias):
mysql> SELECT id,SUBSTRING(col_blob,1,100) FROM nome_tabela GROUP BY 2;
mysql> SELECT id,SUBSTRING(col_blob,1,100) AS b FROM nome_tabela GROUP BY b;
O tamanho m´aximo de uma objeto BLOB ou TEXT´e determinado pelo seu tipo, mas o
maior valor que vocˆe pode, atualmente, transmitir entre o cliente e o servidor ´e determi-
nado pela quantidade de mem´oria dispon´
ivel e o tamanho dos buffers de comunica¸ao.
Voe pode mudar o tamanho do buffer de mensagem, mas vocˆe deve faze-lo no servidor
e no cliente. See hundefinedi[Server parameters], page hundefinedi.
Note que cada valor BLOB ou TEXT ´e representado internamente por um objeto alocado
searadamente. Est´a ´e uma diferen¸ca com todos os outros tipos de colunas, para o qual o
armazenamento ´e alocado um por coluna quando a tabela ´e aberta.
Chapter 6: Referˆencia de Linguagem do MySQL 393
6.2.3.3 O Tipo ENUM
Um ENUM ´e um objeto string cujo valor normalmente ´e escolhido de uma lista de valores
permitidos que s˜ao enumerados explicitamente na especifica¸ao da coluna na cria¸ao da
tabela.
O valor pode ser a string vazia ("") ou NULL sob certas circunstˆancias:
Se vocˆe inserir um valor inalido em um ENUM (isto ´e, uma string que n˜ao est´a presente
na lista de valores permitidos), a string vazia ´e inserida no lugar como um valor especial
de erro. Esta string pode se diferenciar de um string vazia ’norma’ pelo fato de que
esta string tem uo valor num´erico 0. Veremos mais sobre este assunto mais tarde.
Se um ENUM ´e declarado NULL,NULL ´e tamb´em um valor permitido para a coluna, e o
valor padrao ´e NULL. Se um ENUM ´e decalarado NOT NULL, o valor padr˜ao ´e o primeiro
elemento da lista de valores permitidos.
Cada enumera¸ao tem um ´
indice:
Valores da lista de elementos permitidos na especifica¸ao da coluna s˜ao n´umeros
come¸cados com 1.
O valor de ´
indice de uma string vazia que indique erro ´e 0. Isto significa que vocˆe pode
usar a seguinte instru¸ao SELECT para encontrar linhas nas quais valores ENUM inalidos
forma atribuidos:
mysql> SELECT * FROM nome_tabela WHERE col_enum=0;
O´
indice de um valor NULL ´e NULL.
Por exemplo, uma coluna especificada como ENUM("um", "dois", "tr^es") pode ter quql-
quer um dos valores mostrados aqui. O ´
indice de cada valor tamb´em ´e mostrado:
Valor Indice
NULL NULL
"" 0
"um" 1
"dois" 2
"tr^es" 3
Uma enumera¸ao pode ter um m´aximo de 65535 elementos.
A partir da vers˜ao 3.23.51 espa¸cos extras s˜ao automaticamente deletados dos valores ENUM
quando a tabela ´e criada.
O caso da letra ´e irrelevante quando vocˆe atribui valores a um coluna ENUM. No entanto,
valores recuperados posteriormente da coluna ter´a o caso de letras de acordo com os valores
que foram usados para especificar os valores permitidos na cria¸ao da tabela.
Se vocˆe recupera um ENUM em um contexto num´erico, o indice do valor da coluna ´e retornado.
Por exemplo, vocˆe pode recuperar valores num´ericos de uma coluna ENUM desta forma:
mysql> SELECT col_enum+0 FROM nome_tabela;
Se vocˆe armazena um n´umero em um ENUM, o n´umero ´e tratado como um ´
indice, e o valor
armazenado ´e o membro da enumera¸ao com este ´
indice. (No entanto, este n˜ao ir´a funcionar
com LOAD DATA, o qual trata todas as entradas como strings.) ao ´e aconselh´avel armazenar
n´umeros em uma string ENUM pois pode tornar as coisas um pouco confusas.
394 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Valores ENUM ao armazenados de acordo com a ordem na qual os membros da enumera¸ao
foram listados na especifica¸ao da coluna. (Em outras palavras, valores ENUM ao ordena-
dos de acordo com o seus n´umeros de ´
indice.) Por exemplo, "a" vem antes de "b" para
ENUM("a", "b"), mas "b" vem antes de "a" para ENUM("b", "a"). A string vazia vem
antes de strings n˜ao-vazias, e valores NULL vem antes de todos os outros valores de enu-
mera¸ao. Para evitar resultados inesperados, especifique a lista ENUM em ordem alfab´etica.
Voe tamb´em pode usar GROUP BY CONCAT(col) para ter certeza de que as colunas est˜ao
ordenadas alfabeticamente e n˜ao pelo ´
indice num´erico.
Se vocˆe quiser obter todos os valores poss´
iveis para uma coluna ENUM, vocˆe deve usar:
SHOW COLUMNS FROM nome_tabela LIKE nome_coluna_enum e analizar a defini¸ao de ENUM
na segunda coluna.
6.2.3.4 O Tipo SET
Um SET ´e um objeto string que pode ter zero ou mais valores, cada um deve ser escolhido de
uma lista de valores permitidos especificados quando a tabela ´e criada. Valores de colunas
SET que consistem de m´ultiplos membros s˜ao espeficados separados por virgula (‘,’). Uma
consqu6encia distop ´e que valores dos membros de SET ao podem, eles mesmos, conter
v´
irgula.
Por exemplo, uma coluna especificada como SET("um", "dois") NOT NULL pode ter qual-
quer um destes valores:
""
"um"
"dois"
"um, dois"
Um SET pode ter no m´aximo 64 membros diferentes.
A partir da vers˜ao 3.23.51, espa¸cos extras s˜ao automaticamente removidos dos valores de
SET quando a tabela ´e criada.
MySQL armazena valores SET numericamente, com o bit de baixa-ordem do valor ar-
mazenado correspondendo ao primeiro membro do conjunto. Se vocˆe recupera um valor
SET em um contexto num´erico, o valor recuperado tem o conjunto de bits correspondente
aos membros que aparecem no valor da coluna. Por exemplo, vocˆe pode recuperar valores
num´ericos de uma coluna SET assim:
mysql> SELECT col_set+0 FROM nome_tabela;
Se um n´umero ´e armazenado em uma coluna SET, os bits que est˜ao habilitados (com 1)
na representa¸ao bin´aria do n´umero determinam o qual o membro no valor da coluna.
Suponha uma coluna especificada como SET("a","b","c","d"). Enao os membros ter˜ao
os seguintes valores bin´arios:
SET membro Valor decimal Valor bin´ario
a 1 0001
b 2 0010
c 4 0100
d 8 1000
Se vocˆe atribuir um valor 9a esta coluna, que ´e 1001 em bin´ario, o primeiro e o quarto
valores membros do SET "a" e"d" ao selecionados e o valor resultante ´e "a,d".
Chapter 6: Referˆencia de Linguagem do MySQL 395
Para um valor contendo mais que um elemento de SET, ao importa em qual ordem os
elementos s˜ao listados quando foram inseridos seus valores. Tamb´em n˜ao importa quan-
tas vezes um dado elemento e listado no valor. Quando o valor ´e recuperado posterior-
mente, cada elemento aparecer´a uma vez, listados de acordo com a ordem em que eles
foram especificados na cri¸ao da tabela. Por exemplo, se uma coluna ´e especificada como
SET("a","b","c","d"), ent˜ao "a,d","d,a" e"d,a,a,d,d" ir˜ao todos aparecer como
"a,d" quando recuperados.
Se vocˆe define um valor que n˜ao ´e suportado pela coluna SET, o valor ser´a ignorado.
Valores SET ao ordenados num´ericamente. Valores NULL em antes de valores SET ao
NULL.
Normalmente, vocˆe realiza um SELECT em uma coluna SET usando o operador LIKE ou a
fun¸ao FIND_IN_SET():
mysql> SELECT * FROM nome_tabela WHERE col_set LIKE ’%valor%’;
mysql> SELECT * FROM nome_tabela WHERE FIND_IN_SET(’valor’,col_set)>0;
Mas o seguinte tamb´em funciona:
mysql> SELECT * FROM nome_tabela 2 WHERE col_set = ’val1,val2’;
mysql> SELECT * FROM nome_tabela 3 WHERE col_set & 1;
A primeira desta instru¸oes procura por uma correpondencia exata. A segunda por valores
contendo o primeiro membro.
Se vocˆe quer obter todos os valores poss´
iveis para uma coluna SET, vocˆe deve usar: SHOW
COLUMNS FROM nome_tabela LIKE nome_coluna_set e analizar a defini¸ao do SET na se-
gunda coluna.
6.2.4 Escolhendo o Tipo Certo para um Campo
Para um uso mais eficiente do armzenamento, tente usar o tipo mais adequado em todos os
casos. Por exemplo, se um campo de inteiro for usado para valores em uma faixa entre 1e
99999,MEDIUMINT UNSIGNED ´e o melhor tipo.
Represta¸ao precisa de valores monet´arios ´e um priblema comum. No MySQL vocˆe deve
usar o tipo DECIMAL. Ele armazena uma string, ent˜ao nenhuma perda de precis˜ao deve
ocorrer. Se a precis˜ao n˜ao ´e t˜ao importante, o tipo DOUBLE pode ser satisfat´orio.
Para uma alta precis˜ao vocˆe sempre pode converter para um tipo de ponto fixo armazenado
em um BIGINT. Isto perite fazer todos os c´alculos com inteiros e converter o resultado para
um ponto flutuante somente quando necess´ario.
6.2.5 Usando Tipos de Campos de Outros Mecanisnmos de Banco
de Dados
Para facilitar o uso de code para implementa¸oes SQL de outras empresas, MySQL mapeia
os tipos de campos como mostrado na tabela seguinte. Este mapeamento torna f´acil mudar
defini¸oes de tabelas de outros mecanismos de banco de dados para o MySQL:
Tipo de outras
empresas
Tipo MySQL
BINARY(NUM) CHAR(NUM) BINARY
CHAR VARYING(NUM) VARCHAR(NUM)
396 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
FLOAT4 FLOAT
FLOAT8 DOUBLE
INT1 TINYINT
INT2 SMALLINT
INT3 MEDIUMINT
INT4 INT
INT8 BIGINT
LONG VARBINARY MEDIUMBLOB
LONG VARCHAR MEDIUMTEXT
MIDDLEINT MEDIUMINT
VARBINARY(NUM) VARCHAR(NUM) BINARY
O mapeamento do tipo de campo ocorre na cria¸ao da tabela. Se vocˆe cria uma tabela com
tipos usador por outras empresas e enao executa uma instru¸ao DESCRIBE nome_tabela,
MySQL relaciona a estrutura de tabela utilizando os tipos equivalentes do MySQL.
6.2.6 Exigˆencias de Armazenamento dos Tipos de Coluna
As exigˆencias de armazenamento para cada um dos tipos de colunas suportados pelo MySQL
est˜ao listados por categoria.
Exigˆencias de armazenamento para tipos num´ericos
Tipo da coluna Tamanho exigido
TINYINT 1 byte
SMALLINT 2 bytes
MEDIUMINT 3 bytes
INT 4 bytes
INTEGER 4 bytes
BIGINT 8 bytes
FLOAT(X) 4 se X <= 24 ou 8 se 25 <= X <= 53
FLOAT 4 bytes
DOUBLE 8 bytes
DOUBLE PRECISION 8 bytes
REAL 8 bytes
DECIMAL(M,D) M+2 bytes se D >0, M+1 bytes se D = 0 (D+2, se M < D)
NUMERIC(M,D) M+2 bytes se D >0, M+1 bytes se D = 0 (D+2, se M < D)
Exigˆencia de armazenamento para tipos data e hora
Tipo de coluna Tamanho exigido
DATE 3 bytes
DATETIME 8 bytes
TIMESTAMP 4 bytes
TIME 3 bytes
YEAR 1 byte
Chapter 6: Referˆencia de Linguagem do MySQL 397
Exigˆencia de armazenamento para tipos string
Tipo de coluna Tamanho exigido
CHAR(M) M bytes, 1 <= M <= 255
VARCHAR(M) L+1 bytes, onde L <= M e1 <= M <= 255
TINYBLOB,TINYTEXT L+1 bytes, onde L < 2^8
BLOB,TEXT L+2 bytes, onde L < 2^16
MEDIUMBLOB,MEDIUMTEXT L+3 bytes, onde L < 2^24
LONGBLOB,LONGTEXT L+4 bytes, onde L < 2^32
ENUM(’valor1’,’valor2’,...) 1 ou 2 bytes, dependendo do n´umero de valores enumer-
ados (65535 valores no m´aximo)
SET(’valor1’,’valor2’,...) 1, 2, 3, 4 or 8 bytes, dependendo do n´umero de membros
do conjunto (64 membros no m´aximo)
Tipos VARCHAR,BLOB eTEXT ao de tamanho vari´aveis, tendo o tamanho exigido para
armazenamento dependendo do tamanho atual dos valores da coluna (representado por Lna
tabela anterior), e n˜ao do tamanho m´aximo do tipo. Por exemplo, uma coluna VARCHAR(10)
pode guardar uma string com um tamanho m´aximo de 10 caracteres. O tamanho exigido
para armazenamento atual ´e o tamanho da string (L), mais 1 byte para para gravar o
tamanho da string. Por exemplo, para a string ’abcd’,L´e 4 e o tamanho exigido para
armazenamento ´e 5 bytes.
Os tipos BLOB eTEXT exigem 1, 2, 3 ou 4 bytes para gravar o tamanho do valor da coluna,
dependendo do tamanho m´aximo poss´
ivel do tipo. See hundefinedi[BLOB], page hunde-
finedi.
Se uma tabela inclui qualquer tipo de coluna de tamanho vari´avel, o formato do registro
tamb´em ser´a de tamanho vari´avel. Note que quando uma tabela ´e criada, MySQL pode,
sob certas condi¸oes, mudar uma coluna de um tipo de tamanho vari´avel para um tipo de
tamanho fixo, ou vice-versa. See hundefinedi[Silent column changes], page hundefinedi.
O tamanho de um objeto ENUM ´e determinado por um n´umero de diferntes valores enumer-
ados. Um byte ´e usado para enumera¸oes at´e 255 valores poss´
iveis. Dois bytes s˜ao usados
para enumera¸oes at´e 65535 valores. See hundefinedi[ENUM], page hundefinedi.
O tamanho de uma objeto ´e determinado pelo n´umero de diferentes membros do conjunto.
Se o tamanho do conjunto ´e N, o objeto ocupa (N+7)/8 bytes, arredondados acima para
1, 2, 3, 4, ou 8 bytes. Um SET pode ter no m´aximo 64 membros. See hundefinedi[SET],
page hundefinedi.
O tamanho m´aximo de um registro em uma tabela MyISAM ´e 65534 bytes. Cada coluna
BLOB eTEXT ocupa apenas 5-9 bytes deste tamanho.
6.3 Fun¸oes para Uso em Cl´ausulas SELECT eWHERE
Um select_expression ou where_definition em uma instru¸ao SQL pode consistir de
qualquer express˜ao utilizando as fun¸oes descritas abaixo.
Uma express˜ao que cont´em NULL sempre produz um valor NULL a menos que esteja indicado
na dodumenta¸ao para os operandos e fun¸oes envolvidos na express˜ao.
Nota: ao deve haver nenhum espa¸co em branco entre um nome de fun¸ao e os parentesis
que a seguem. Isto ajuda o analizador MySQL a distinguir entre chamadas de fun¸oes e
398 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
referˆencias a tabelas ou colunas que possuem o mesmo nome de uma fun¸ao. Espa¸cos entre
argumentos s˜ao permitidos.
Voe pode for¸car o MySQL a aceitar espa¸cos depois do nome de fun¸oes iniciando o mysqld
com a op¸ao --ansi ou usando o CLIENT_IGNORE_SPACE no mysql_connect(), mas neste
caso nome de fun¸oes se tornar˜ao palavras reservadas. See hundefinedi[ANSI mode],
page hundefinedi.
Para sermos breve, exemplos mostram a saida do programa mysql na forma abreviada.
Enao isto:
mysql> SELECT MOD(29,9);
1 rows in set (0.00 sec)
+-----------+
| mod(29,9) |
+-----------+
| 2 |
+-----------+
´e mostrado desta forma:
mysql> SELECT MOD(29,9);
-> 2
6.3.1 Operadores e Fun¸oes de Tipos n˜ao Especificados
6.3.1.1 Parenteses
( ... )
Use parenteses para for¸car a ordem em que as express˜oes ser˜ao avaliadas. Por exemplo:
mysql> SELECT 1+2*3;
-> 7
mysql> SELECT (1+2)*3;
-> 9
6.3.1.2 Operadores de Compara¸ao
Opera¸oes de compara¸ao resultam em um valor 1(VERDADEIRO), 0(FALSO), ou NULL.
Estas fun¸oes funcionam tanto para tipos num´ericos quanto para tipos strings. Strings
ao convertidas automaticamente para n´umeros e n´umeros para strings quando necess´ario
(como em Perl).
MySQL realiza compara¸oes de acordo com as seguintes regras:
Se um ou ambos os argumentos s˜ao NULL, o resultado da compara¸ao ´e NULL, exceto
para o operador <=>.
Se ambos os argumentos em uma compara¸ao s˜ao strings, eles s˜ao comparados como
strings.
Se ambos os argumentos s˜ao inteiros, eles s˜ao comparados como inteiros.
Valores hexadecimais s˜ao tratados como strings bin´arias se n˜ao comparadas a um
n´umero.
Chapter 6: Referˆencia de Linguagem do MySQL 399
Se uma dos argumentos ´e uma coluna TIMESTAMP ou DATETIME e o outro argumento ´e
uma constante, a constante ´e convertida para um timestamp antes da compara¸ao ser
realizada. Isto ocorre para ser mais amig´avel ao ODBC.
Em todos os outros casos, os argumentos s˜ao coparados como n´umeroos de ponto
flutuante (real).
Por padr˜ao, compara¸oes de string s˜ao feita de modo independente do caso, usando o
conjunto de caracteres atual (ISO-8859-1 Latin1 por padr˜ao, o qual tamb´em funciona de
forma excelente para o Inglˆes).
Os seguintes exemplos ilustram a convers˜ao de strings para n´umeros para opera¸oes de
compara¸ao:
mysql> SELECT 1 > ’6x’;
-> 0
mysql> SELECT 7 > ’6x’;
-> 1
mysql> SELECT 0 > ’x6’;
-> 0
mysql> SELECT 0 = ’x6’;
-> 1
=Igual:
mysql> SELECT 1 = 0;
-> 0
mysql> SELECT ’0’ = 0;
-> 1
mysql> SELECT ’0.0’ = 0;
-> 1
mysql> SELECT ’0.01’ = 0;
-> 0
mysql> SELECT ’.01’ = 0.01;
-> 1
<>
!= Diferente:
mysql> SELECT ’.01’ <> ’0.01’;
-> 1
mysql> SELECT .01 <> ’0.01’;
-> 0
mysql> SELECT ’zapp’ <> ’zappp’;
-> 1
<= Menor que ou igual:
mysql> SELECT 0.1 <= 2;
-> 1
<Menor que:
mysql> SELECT 2 < 2;
-> 0
>= Maior que ou igual:
400 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT 2 >= 2;
-> 1
>Maior que:
mysql> SELECT 2 > 2;
-> 0
<=> Igual para NULL:
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
->110
IS NULL
IS NOT NULL
Teste para saber se um valor ´e ou n˜ao NULL:
mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
->001
mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
->110
Para estar apto a funcionar bem com outros programas, MySQL suporta os
seguintes recursos extras quando utiliza-se IS NULL:
Voe pode encontrar o ´ultimo registro inserido com:
SELECT * FROM nome_tabela WHERE auto_col IS NULL
Isto pode ser desabilitado configurando SQL_AUTO_IS_NULL=0. See hunde-
finedi[SET OPTION], page hundefinedi.
Para colunas DATE eDATETIME NOT NULL vocˆe pode encontrar a data espe-
cial 0000-00-00 utilizando:
SELECT * FROM nome_tabela WHERE coluna_data IS NULL
Isto ´e necess´ario para que algums aplica¸oes ODBC funcionem (j´a que
ODBC n˜ao tem suporte a data 0000-00-00)
expr BETWEEN min AND max
Se expr ´e maior que ou igual a min eexpr ´e menor que ou igual a max,BETWEEN
retorna 1, sen˜ao ´e retornado 0. Isto ´e equivalente a express˜ao (min <= expr AND
expr <= max) se todos os argumentos s˜ao do mesmo tipo. Sen˜ao os tipos s˜ao
convertidos, conforme as regras acima, e aplicadas a todos os trˆes argumentos.
Note que antes da vers˜ao 4.0.5 argumentos eram convertidos para o tipo da
expr.
mysql> SELECT 1 BETWEEN 2 AND 3;
-> 0
mysql> SELECT ’b’ BETWEEN ’a’ AND ’c’;
-> 1
mysql> SELECT 2 BETWEEN 2 AND ’3’;
-> 1
mysql> SELECT 2 BETWEEN 2 AND ’x-3’;
-> 0
expr NOT BETWEEN min AND max
O mesmo que NOT (expr BETWEEN min AND max).
Chapter 6: Referˆencia de Linguagem do MySQL 401
expr IN (valor,...)
Retorna 1se expr ´e qualquer dos valores na lista IN, sen˜ao retorna 0. Se todos
os valores s˜ao constantes, ent˜ao os valores s˜ao avaliados de acordo com o tipo da
expr e ordenado. A busca do item ´e ent˜ao feita usando pesquisa bin´aria. Isto
significa que IN ´e muito r´apido se os valores da lista IN forem todos contantes.
Se expr ´e uma express˜ao strig em caso-sensitivo, a compara¸ao ´e realizadas no
modo caso-sensitvo:
mysql> SELECT 2 IN (0,3,5,’wefwf’);
-> 0
mysql> SELECT ’wefwf’ IN (0,3,5,’wefwf’);
-> 1
O n´umero de valores na lista IN ´e limitada apenas pelo valor max_allowed_
packet.
Na vers˜ao 4.1 (para se adequar ao padr˜ao SQL-99), IN returna NULL ao apeans
se a express˜ao a sua esquerda ´e NULL, mas tamb´em se nenhuma correspondˆencia
´e encontrada na lista e uma de suas express˜oes ´e NULL.
expr NOT IN (valor,...)
O mesmo que NOT (expr IN (valor,...)).
ISNULL(expr)
Se expr ´e NULL,ISNULL() retorna 1, sen˜ao retorna 0:
mysql> SELECT ISNULL(1+1);
-> 0
mysql> SELECT ISNULL(1/0);
-> 1
Note que a compra¸ao de valores NULL usando =sempre ser´a falso!
COALESCE(lista)
Retorna o primeiro elemento n˜ao NULL na lista:
mysql> SELECT COALESCE(NULL,1);
-> 1
mysql> SELECT COALESCE(NULL,NULL,NULL);
-> NULL
INTERVAL(N,N1,N2,N3,...)
Retorna 0se N < N1,1se N < N2 e assim por diante. Todos os argumentos s˜ao
tratados como inteiros. Isto exige que N1 < N2 < N3 < ... < Nn para que esta
fun¸ao funcione corretamente. Isto ocorre devido a utiliza¸ao pesquisa bin´aria
(muito r´apida):
mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
-> 3
mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
-> 2
mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
-> 0
Se vocˆe est´a comparando strings em caso-insensitivo com qualquer um dos operadores
padr˜oes (=,<>..., mas n˜ao LIKE) espa¸cos em branco extras (espa¸cos, tabula¸oes e novas
linhas) ser˜ao ignorados.
402 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT "a" ="A \n";
-> 1
6.3.1.3 Operadores Logicos
Em SQL, todos os operadores logicos avaliam TRUE (VERDADEIRO), FALSE (FALSO)
ou NULL (DESCONHECIDO). No MySQL, esta implementa¸ao ´e como 1(TRUE), 0
(FALSE), e NULL. A maioria deles ´e comum entre diferentes bancos de dados SQL. no
entanto alguns podem retonar qualquer valor diferente de zero para TRUE.
NOT
!NOT logico. Avalia como 1se o operador ´e 0, como 0se o operador ´e diferente
de zero, e NOT NULL retorna NULL.
mysql> SELECT NOT 10;
-> 0
mysql> SELECT NOT 0;
-> 1
mysql> SELECT NOT NULL;
-> NULL
mysql> SELECT ! (1+1);
-> 0
mysql> SELECT ! 1+1;
-> 1
O ´ultimo exemplo produz 1pois a a express˜ao ´e avaliada como (!1)+1.
AND
&& AND l´ogico. Avalia como 1se todos os operandos s˜ao diferentes de zero e n˜ao
´e NULL, como 0se um ou mais operandos s˜ao 0, sen˜ao retorna NULL.
mysql> SELECT 1 && 1;
-> 1
mysql> SELECT 1 && 0;
-> 0
mysql> SELECT 1 && NULL;
-> NULL
mysql> SELECT 0 && NULL;
-> 0
mysql> SELECT NULL && 0;
-> 0
Por favor note que as vers˜oes do MySQL anteriores a vers˜ao 4.0.5 param a
avalia¸ao quando um valor NULL ´e encontrado, e n˜ao continua o processo bus-
cando por poss´
iveis 0s. Isto significa que nessa vers˜ao, SELECT (NULL AND 0)
retorna NULL ao inv´es de 0. Na vers˜ao 4.0.5 o c´odigo tem sido re-elaborado
para que o resultado sempre seja como prescrito pelo padr˜ao SQL utilizando a
otimiza¸ao sempre que poss´
ivel.
OR
|| OR l´ogico. Avalia como 1se algum operando ´e diferente de zero e como NULL
se algum operando for NULL, sen˜ao 0´e retornado.
Chapter 6: Referˆencia de Linguagem do MySQL 403
mysql> SELECT 1 || 1;
-> 1
mysql> SELECT 1 || 0;
-> 1
mysql> SELECT 0 || 0;
-> 0
mysql> SELECT 0 || NULL;
-> NULL
mysql> SELECT 1 || NULL;
-> 1
XOR XOR l´ogico. Retorna NULL se o operando tamb´em ´e NULL. Para operandos
ao NULL, avalia como 1se um n´umero ´
impar de operandos ´e diferente de zero,
sen˜ao 0´e retornado.
mysql> SELECT 1 XOR 1;
-> 0
mysql> SELECT 1 XOR 0;
-> 1
mysql> SELECT 1 XOR NULL;
-> NULL
mysql> SELECT 1 XOR 1 XOR 1;
-> 1
a XOR b ´e matematicamente igual a (a AND (NOT b)) OR ((NOT a) and b).
XOR foi adicionado na vers˜ao 4.0.2.
6.3.1.4 Fun¸oes de Fluxo de Controle
IFNULL(expr1,expr2)
Se expr1 ao ´e NULL,IFNULL() retorna expr1, sen˜ao retorna expr2.IFNULL()
retorna um valor num´erico ou string, dependendo do contexto no qual ´e usado:
mysql> SELECT IFNULL(1,0);
-> 1
mysql> SELECT IFNULL(NULL,10);
-> 10
mysql> SELECT IFNULL(1/0,10);
-> 10
mysql> SELECT IFNULL(1/0,’yes’);
-> ’yes’
Na vers˜ao 4.0.6 e acima o valor resultante padr˜ao de IFNULL(expr1,expr2) ´e o
mais geral das duas express˜oes, na seguinte ordem: STRING,REAL ou INTEGER.
A diferen¸ca das vers˜oes anteriores ´e mais not´avel quando se cria uma tabela
baseada em uma express˜ao ou o MySQL tem que armazenar internamente um
valor de IFNULL() em uma tabela tempor´aria.
CREATE TABLE foo SELECT IFNULL(1,"teste") as teste;
Na vers˜ao 4.0.6 do MySQL o tipo da coluna ’teste’ ´e CHAR(4) enquanto nas
vers˜oes anteriores ela seria do tipo BIGINT.
404 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
NULLIF(expr1,expr2)
Se expr1 = expr2 for verdadeiro, ´e retornado NULL sen˜ao ´e retornado expr1.
Isto ´e o mesmo que CASE WHEN x = y THEN NULL ELSE x END:
mysql> SELECT NULLIF(1,1);
-> NULL
mysql> SELECT NULLIF(1,2);
-> 1
Note que expr1 ´e avaliada duas vezes no MySQL se os argumentos n˜ao s˜ao
iguais.
IF(expr1,expr2,expr3)
Se expr1 ´e VERDADEIRA (expr1 <> 0 eexpr1 <> NULL) ent˜ao IF() retorna
expr2, sen˜ao ela retorna expr3.IF() returna um valor num´erico ou string,
dependendo do contexto no qual ´e usado.
mysql> SELECT IF(1>2,2,3);
-> 3
mysql> SELECT IF(1<2,’sim’,’n~ao’);
-> ’sim’
mysql> SELECT IF(STRCMP(’teste’,’teste1’),’n~ao’,’sim’);
-> ’n~ao’
Se expr2 ou expr3 ´e explicitamente NULL enao o tipo resultante da fun¸ao
IF() ´e o tipo da coluna n˜ao NULL. (Este comportamento ´e novo na vers˜ao 4.0.3
do MySQL).
expr1 ´e avaliada como um valor inteiro, o qual significa que se vocˆe est´a testando
valores de ponto flutuante ou strings, vocˆe de fazˆe-lo usando um operando de
compara¸ao:
mysql> SELECT IF(0.1,1,0);
-> 0
mysql> SELECT IF(0.1<>0,1,0);
-> 1
No primeiro caso acima, IF(0.1) retorna 0porque 0.1 ´e convertido para um
valor inteiro, resultando um um teste IF(0). Isto pode n˜ao ser o que vocˆe
esperava. No segundo caso, a compara¸ao testa se o valor de ponto flutuante
ao ´e zero. O resultado da compara¸ao converte o termo em um interiro.
O tipo de retorno padr˜ao de IF() (o que pode importar quando ele ´e ar-
mazenado em uma tabela tempor´aria) ´e calculado na vers˜ao 3.23 do MySQL
de seguinte forma:
Express˜ao Valor de
retorno
expr2 ou expr3 retorna string string
expr2 ou expr3 retorna um valor de ponto
flutuante
ponto flutuante
expr2 ou expr3 retorna um inteiro inteiro
Se expr2 e expr3 s˜ao strings, ent˜ao o resultado ´e caso-insensitivo se ambas
strings s˜ao caso insensitivo. (A patir da vers˜ao 3.23.51)
Chapter 6: Referˆencia de Linguagem do MySQL 405
CASE valor WHEN [valor comparado] THEN resultado [WHEN [valor comparado] THEN
resultado ...] [ELSE resultado] END
CASE WHEN [condi¸c~ao] THEN result [WHEN [condi¸c~ao] THEN resultado ...] [ELSE
resultado] END
A primeira express˜ao retorna o resultado onde valor=valor comparado. A
segunda express˜ao retorna o o resultado da primeira condi¸ao, a qual ´e ver-
dadeira. Se n˜ao existe nenhum resultado correspondente, ent˜ao o resultado
depois do ELSE ´e retornado. Se n˜ao existe parte ELSE enao ´e retornado NULL
is returned:
mysql> SELECT CASE 1 WHEN 1 THEN "um"
WHEN 2 THEN "dois" ELSE "mais" END;
-> "one"
mysql> SELECT CASE WHEN 1>0 THEN "verdadeiro" ELSE "falso" END;
-> "true"
mysql> SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2 END;
-> NULL
O tipo do valor de retorno (INTEGER,DOUBLE ou STRING) ´e do mesmo tipo do primeiro valor
retornado (a express˜ao depois do primeiro THEN).
6.3.2 Fun¸oes String
Fun¸oes string retornam NULL se o tamanho do resultado for maior que o parˆametro do
servidor max_allowed_packet. See hundefinedi[Server parameters], page hundefinedi.
Para fun¸oes que operam com as posi¸oes de uma string, a primeira posi¸ao ´e numerada
como 1.
ASCII(str)
Retorna o valor do c´odigo ASCII do caracter mais a esquerda da string str.
Retorna 0se str ´e uma string vazia. Retorna NULL se str ´e NULL:
mysql> SELECT ASCII(’2’);
-> 50
mysql> SELECT ASCII(2);
-> 50
mysql> SELECT ASCII(’dx’);
-> 100
Veja tamb´em a fun¸ao ORD().
ORD(str) Se o caracter mais a esquerda da string str ´e um caracter multi-byte,
´e retornado o c´odigo para este caracter, calculado a partir dos valores
do c´odigo ASCII dos seus caracteres contituintes utizando-se a seguinte
ormula: ((primeiro byte do c´odigo ASCII)*256+(segundo byte do c´odigo
ASCII))[*256+terceiro byte do c´odigo ASCII...]. Se o caracter mais a
esquerda n˜ao ´e multi-byte, ´e retornado o mesmo valor que a fun¸ao ASCII()
retorna:
mysql> SELECT ORD(’2’);
-> 50
406 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
CONV(N,da_base,para_base)
Converte n´umeros entre diferentes bases. Retorna uma representa¸ao string do
n´umero N, convertido da base da_base para base para_base. Retorna NULL se
qualquer argumento ´e NULL. O argumento N´e interpretado como um inteiro,
mas pode ser especificado como um inteiro ou uma string. A base m´
inima ´e 2
e a m´axima ´e 36. Se para_base ´e um n´umero negativo, N´e considerado como
um n´umero com sinal. Caso contr´ario, N´e tratado como um n´umero sem sinal.
CONV funciona com precis˜ao de 64-bit:
mysql> SELECT CONV("a",16,2);
-> ’1010’
mysql> SELECT CONV("6E",18,8);
-> ’172’
mysql> SELECT CONV(-17,10,-18);
-> ’-H’
mysql> SELECT CONV(10+"10"+’10’+0xa,10,10);
-> ’40’
BIN(N) Retorna um representa¸ao string do valor bin´ario de N, onde N´e um n´umero
muito grande (BIGINT). Isto ´e equivalente a CONV(N,10,2). Retorna NULL se N
´e NULL:
mysql> SELECT BIN(12);
-> ’1100’
OCT(N)
Retorna uma representa¸ao string do valor octal de N, onde N´e um n´umero
muito grande. Isto ´e equivalente a CONV(N,10,8). Retorna NULL se N´e NULL:
mysql> SELECT OCT(12);
-> ’14’
HEX(N_ou_S)
Se N OU S ´e um n´umero, ´e retornado um representa¸ao string do valor hex-
adecimal de N, onde N´e um n´umero muito grande (BIGINT). Isto ´e equivalente
aCONV(N,10,16).
Se N OU S ´e uma string, ´e retornado uma string hexadecimal de N OU S onde
cada caracter de N OU S ´e convertido para 2 d´
igitos hexadecimais. Isto ´e o
inverso da string 0xff.
mysql> SELECT HEX(255);
-> ’FF’
mysql> SELECT HEX("abc");
-> 616263
mysql> SELECT 0x616263;
-> "abc"
CHAR(N,...)
CHAR() interpretia os argumentos como inteiros e retorna uma string com car-
acteres dados pelo valor do c´odigo ASCII referentes a estes inteiros. Valores
NULL ao desconsiderados:
mysql> SELECT CHAR(77,121,83,81,’76’);
-> ’MySQL’
Chapter 6: Referˆencia de Linguagem do MySQL 407
mysql> SELECT CHAR(77,77.3,’77.3’);
-> ’MMM’
CONCAT(str1,str2,...)
Retorna a string resultante da concatena¸ao dos argumentos. Retorna NULL
se qualquer dos argumentos for NULL. Pode ter mais de 2 argumentos. Um
argumento num´erico ´e convertido para sua forma string equivalente:
mysql> SELECT CONCAT(’My’, ’S’, ’QL’);
-> ’MySQL’
mysql> SELECT CONCAT(’My’, NULL, ’QL’);
-> NULL
mysql> SELECT CONCAT(14.3);
-> ’14.3’
CONCAT_WS(separador, str1, str2,...)
CONCAT_WS() significa CONCAT With Separator (CONCAT com separador)
e ´e uma forma especial do CONCAT(). O primeiro argumento ´e o separador
para os outros argumentos. O separador pode ser uma string assim como os
outros argumentos. Se o separador ´e NULL, o resultado ser´a NULL. A fun¸ao ir´a
desconsiderar qualquer NULL e strings vazias, depois do argumento do separador.
O separador ser´a adicionado entre as strings concatenadas:
mysql> SELECT CONCAT_WS(",","First name","Second name","Last Name");
-> ’First name,Second name,Last Name’
mysql> SELECT CONCAT_WS(",","First name",NULL,"Last Name");
-> ’First name,Last Name’
LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
Retorna o tamanho da string str:
mysql> SELECT LENGTH(’text’);
-> 4
mysql> SELECT OCTET_LENGTH(’text’);
-> 4
Note que para CHAR_LENGTH() eCHARACTER_LENGTH(), caracteres multi-byte
ao contados apenas uma vez.
BIT_LENGTH(str)
Retorna o tamanho da string str em bits:
mysql> SELECT BIT_LENGTH(’text’);
-> 32
LOCATE(substr,str)
POSITION(substr IN str)
Retorna a posi¸ao da primeira ocorrˆencia da substring substr na string str.
Retorna 0se substr ao est´a na str:
mysql> SELECT LOCATE(’bar’, ’foobarbar’);
-> 4
408 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT LOCATE(’xbar’, ’foobar’);
-> 0
Esta fun¸ao ´e multi-byte. Na vers˜ao 3.23 do MySQL esta fun¸ao ´e caso sensitivo,
enquanto na vers˜ao 4.0 ela s´o ´e caso-sensitivo se os argumentos s˜ao uma string
bin´aria.
LOCATE(substr,str,pos)
Retorna a posi¸ao da primeira ocorrˆencia da substring substr na string str,
iniciando na posi¸ao pos. Retorna 0se substr ao est´a em str:
mysql> SELECT LOCATE(’bar’, ’foobarbar’,5);
-> 7
Esta fun¸ao ´e multi-byte. Na vers˜ao 3.23 do MySQL esta fun¸ao ´e caso sensitivo,
enquanto na vers˜ao 4.0 ela s´o ´e caso-sensitivo se os argumentos s˜ao uma string
bin´aria.
INSTR(str,substr)
Retorna a posi¸ao da primeira ocorrˆencia da substring substr na string str.
´
E o mesmo que as o LOCATE() com dois argumentos, exceto pelo fato de que os
argumentos est˜ao tracados:
mysql> SELECT INSTR(’foobarbar’, ’bar’);
-> 4
mysql> SELECT INSTR(’xbar’, ’foobar’);
-> 0
Esta fun¸ao ´e multi-byte. Na vers˜ao 3.23 do MySQL esta fun¸ao ´e caso sensitivo,
enquanto na vers˜ao 4.0 ela s´o ´e caso-sensitivo se os argumentos s˜ao uma string
bin´aria.
LPAD(str,tam,strpreench)
Retorna a string str, preenchida a esquerda com a string strpreench at´e que
str possua tam caracteres. Se str ´e maior que tam ent˜ao ela ser´a reduzida para
tam caracteres.
mysql> SELECT LPAD(’hi’,4,’??’);
-> ’??hi’
RPAD(str,tam,strpreech)
Retorna a string str, preenchida a direita com a string strpreench at´e que
str possua tam caracteres. Se str ´e maior que tam ent˜ao ela ser´a reduzida para
tam caracteres.
mysql> SELECT RPAD(’hi’,5,’?’);
-> ’hi???’
LEFT(str,tam)
Retorna os tam caracteres mais a esquerda da string str:
mysql> SELECT LEFT(’foobarbar’, 5);
-> ’fooba’
Esta fun¸ao ´e multi-byte.
RIGHT(str,tem)
Retorna os tam caracteres mais a esquerda da string str:
Chapter 6: Referˆencia de Linguagem do MySQL 409
mysql> SELECT RIGHT(’foobarbar’, 4);
-> ’rbar’
Esta fun¸ao ´e multi-byte.
SUBSTRING(str,pos,tam)
SUBSTRING(str FROM pos FOR tam)
MID(str,pos,tam)
Retorna a substring com tam caracteres da string str, iniciando da posi¸ao pos.
A forma variante que utiliza FROM ´e a sintaxe SQL-92:
mysql> SELECT SUBSTRING(’Quadratically’,5,6);
-> ’ratica’
Esta fun¸ao ´e multi-byte.
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
Retorna uma substring da string str iniciando na posi¸c˜ao pos:
mysql> SELECT SUBSTRING(’Quadratically’,5);
-> ’ratically’
mysql> SELECT SUBSTRING(’foobarbar’ FROM 4);
-> ’barbar’
Esta fun¸ao ´e multi-byte.
SUBSTRING_INDEX(str,delim,cont)
Retorna a substring da string str antes de cont ocorrencias do delimitador
delim. Se cont ´e positivo, tudo a esquerda do delimitador final (contando a
partir da esquerda) ´e retornado. Se cont ´e negativo, tudo a direita do delimi-
tador final (contando a partir da direita) ´e retornado.
mysql> SELECT SUBSTRING_INDEX(’www.mysql.com’, ’.’, 2);
-> ’www.mysql’
mysql> SELECT SUBSTRING_INDEX(’www.mysql.com’, ’.’, -2);
-> ’mysql.com’
Esta fun¸ao ´e multi-byte.
LTRIM(str)
Retorna a string str com caracteres de espa¸cos extras iniciais removidos:
mysql> SELECT LTRIM(’ barbar’);
-> ’barbar’
RTRIM(str)
Retourna a string str com caracteres de espa¸cos extras finais removidos:
mysql> SELECT RTRIM(’barbar ’);
-> ’barbar’
Esta fun¸ao ´e multi-byte.
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
Retorna a string str com todos prefixos e/ou sufixos remstr removidos. Se nen-
hum dos especificadores BOTH,LEADING ou TRAILING ao dados, ´e considerado
BOTH. Se remstr ao ´e especificada, espa¸cos s˜ao removidos:
410 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT TRIM(’ bar ’);
-> ’bar’
mysql> SELECT TRIM(LEADING ’x’ FROM ’xxxbarxxx’);
-> ’barxxx’
mysql> SELECT TRIM(BOTH ’x’ FROM ’xxxbarxxx’);
-> ’bar’
mysql> SELECT TRIM(TRAILING ’xyz’ FROM ’barxxyz’);
-> ’barx’
Esta fun¸ao ´e multi-byte.
SOUNDEX(str)
Retorna uma string ’soundex’ de str. Duas strings que soam de forma pare-
cida devem ter strings ’soundex’ iguais. Uma string soundex padr˜ao possui 4
caracteres, mas a fun¸ao SOUNDEX() retorna uma string de tamanho arbitr´ario.
Voe posde usar SUBSTRING() no resultado para obter uma string ’soundex’
padr˜ao. Todos os caracteres n˜ao alfanum´ericos s˜ao ignorados na string dada.
Todas caracteres internacionais fora da faixa A-Z s˜ao tratados como vogais:
mysql> SELECT SOUNDEX(’Hello’);
-> ’H400’
mysql> SELECT SOUNDEX(’Quadratically’);
-> ’Q36324’
SPACE(N) Retorna uma string contendo Ncaracteres de espa¸co:
mysql> SELECT SPACE(6);
-> ’
REPLACE(str,da_str,para_str)
Retorna a string str com todas ocorrˆencias da string da_str substituida pela
string para_str:
mysql> SELECT REPLACE(’www.mysql.com’, ’w’, ’Ww’);
-> ’WwWwWw.mysql.com’
Esta fun¸ao ´e multi-byte.
REPEAT(str,cont)
Retorna uma string consistindo da string str repetida cont vezes. Se cont <=
0, ´e retornado uma string vazia. ´
E retornado NULL se str ou cont ao NULL:
mysql> SELECT REPEAT(’MySQL’, 3);
-> ’MySQLMySQLMySQL’
REVERSE(str)
Returns the string str with the order of the characters reversed:
mysql> SELECT REVERSE(’abc’);
-> ’cba’
Esta fun¸ao ´e multi-byte.
INSERT(str,pos,tam,novastr)
Retorna a string str, com a a substring come¸cando na posi¸ao pos e contendo
tam caracteres substituida pela string novastr:
mysql> SELECT INSERT(’Quadraticio’, 3, 4, ’Onde’);
Chapter 6: Referˆencia de Linguagem do MySQL 411
-> ’QuOndetico’
Esta fun¸ao ´e multi-byte.
ELT(N,str1,str2,str3,...)
Retorna str1 se N=1,str2 se N=2, e assim por diante. Retorna NULL se N
´e menor que 1ou maior que o n´umero de argumentos. ELT() ´e o complemento
de FIELD():
mysql> SELECT ELT(1, ’ej’, ’Heja’, ’hej’, ’foo’);
-> ’ej’
mysql> SELECT ELT(4, ’ej’, ’Heja’, ’hej’, ’foo’);
-> ’foo’
FIELD(str,str1,str2,str3,...)
Retorna o ´
indice de str na lista str1,str2,str3,.... Retorns 0se str ao
for encontrada. FIELD() ´e o complemento de ELT():
mysql> SELECT FIELD(’ej’, ’Hej’, ’ej’, ’Heja’, ’hej’, ’foo’);
-> 2
mysql> SELECT FIELD(’fo’, ’Hej’, ’ej’, ’Heja’, ’hej’, ’foo’);
-> 0
FIND_IN_SET(str,strlista)
Retorna um valor 1para Nse a string str est´a na lista strlist contendo N
substrings. A lista de string ´e composta de substrings separadas pelo caracter
,’. Se o primeiro argumento ´e uma string constante e o segundo ´e uma col-
una do tipo SET, a fun¸ao FIND_IN_SET() ´e otimizada para usar aritm´etica
bin´aria! Retorna 0se str ao est´a na strlista ou se strlista ´e uma string
vazia. Retorna NULL se os argumentos s˜ao NULL. Esta fun¸ao n˜ao ir´a funcionar
adequadamente se o primeiro argumento cont´em uma ‘,’:
mysql> SELECT FIND_IN_SET(’b’,’a,b,c,d’);
-> 2
MAKE_SET(bits,str1,str2,...)
Retorna um conjunto (uma string contendo substrings separadas por ‘,’) con-
tendo as strings que tem o bit correspondente em bits definido . str1 corre-
sponde ao bit 1, str2 ao bit 2, etc. Strings NULL em str1,str2,... ao s˜ao
adicionadas ao resultado:
mysql> SELECT MAKE_SET(1,’a’,’b’,’c’);
-> ’a’
mysql> SELECT MAKE_SET(1 | 4,’Oi’,’meu’,’mundo’);
-> ’Oi,mundo’
mysql> SELECT MAKE_SET(0,’a’,’b’,’c’);
-> ’’
EXPORT_SET(bits,on,off,[separador,[numero_de_bits]])
Retorna uma string onde para todo bit 1 em ’bit’, voe obt´em uma string ’on’
e para cada bit 0 vocˆe obtem uma string ’off’, Cada string ´e separada com
’separador’ (padr˜ao,’,’) e s´o ’n´umero de bits’ (padr˜ao 64) de ’bits’ ´e usado:
mysql> SELECT EXPORT_SET(5,’S’,’N’,’,’,4)
-> S,N,S,N
412 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
LCASE(str)
LOWER(str)
Retorna a string str com todos caracteres alterados para letra min´usculas de
acordo com o conjunto de caracteres atual (o padr˜ao ´e ISO-8859-1 Latin1):
mysql> SELECT LCASE(’MYSQL’);
-> ’mysql’
Esta ´e uma fun¸ao multi-byte.
UCASE(str)
UPPER(str)
Retorna a string str com todos caracteres alterados para letra mai´usculas de
acordo com o conjunto de caracteres atual (o padr˜ao ´e ISO-8859-1 Latin1):
mysql> SELECT UCASE(’Hej’);
-> ’HEJ’
Esta ´e uma fun¸ao multi-byte.
LOAD_FILE(nome_arquivo)
Lˆeb o arquivo e retona o conteudo do arquivo como uma string. O arquivo beve
estar no servidor, vocˆe deve especificar o caminho completo para o arquivo, e
vocˆe deve ter o privil´egio FILE. O arquivo deve ser leg´
ivel para todos e ser
menor que o especificado em max_allowed_packet.
Se o arquivo n˜ao existe ou n˜ao pode ser lido devido a alguma das raz˜oes acima,
a fun¸ao retornar´a NULL:
mysql> UPDATE nome_tabela
SET coluna_blob=LOAD_FILE("/tmp/picture")
WHERE id=1;
Se vocˆe n˜ao est´a usando a vers˜ao 3.23 MySQL, vocˆe tem que fazer a leitura
do arquivo dentro do seu aplicativo e criar uma instru¸ao INSERT para atu-
alizar o banco de dados com a informa¸ao do arquivo. Um modo de se fazer
isto, se vocˆe estiver usando a biblioteca MySQL++, pode ser encontrada em
http://www.mysql.com/documentation/mysql++/mysql++-examples.html.
QUOTE(str)
Coloca uma string entre aspas para produzir um resultado que possa ser usada
em uma intru¸ao SQL como um valor de dados com o caracter de escape correto.
A string ´e retornada entre aspas simples e cada instˆaqncia de aspas simples
(‘’), barra invertida (‘\’), ASCII NUL, e Control-Z ´e precedida por uma barra
invertida. Se o argumento ´e NULL, o valor retornado ´e a palavra “NULL” sem
aspas simples.
A fun¸ao QUOTE foi adicionada na vers˜ao 4.0.3 do MySQL.
mysql> SELECT QUOTE("Don’t");
-> ’Don\’t!’
mysql> SELECT QUOTE(NULL);
-> NULL
6.3.2.1 Fun¸oes de Compara¸ao de Strings
MySQL automaticamente converte n´umeros para quando necess´ario, e vice-versa:
Chapter 6: Referˆencia de Linguagem do MySQL 413
mysql> SELECT 1+"1";
-> 2
mysql> SELECT CONCAT(2,’ test’);
-> ’2 test’
Se vocˆe quiser converter um n´umero em uma string de forma explicita, passe-o como um
argumento de CONCAT().
Se uma fun¸ao de string tem uma string bin´aria como argumento, a string resultante ´e
tamb´em um string bin´aria. Um n´umero convertido para uma string ´e tratado como um
string bin´aria. Isto afeta apenas a compara¸ao.
Normalmente, se qualquer express˜ao em uma string ´e caso-sensitivo, a compara¸ao ´e real-
izada no modo caso sensitivo.
expr LIKE pad [ESCAPE ’car-escape’]
Correspondˆencia de padr˜oes usando uma simples express˜ao de compara¸oes
SQL. Retorna 1(VERDADEIRO) ou 0(FALSO). Com LIKE vocˆe pode usar os
seguintes meta-caracteres no padrao:
Car Descri¸ao
%Corresponde a qualquer n´umero de caracteres, at´e
zero caracteres
_Corresponde a exatamente um caracter
mysql> SELECT ’David!’ LIKE ’David_’;
-> 1
mysql> SELECT ’David!’ LIKE ’%D%v%’;
-> 1
Para testar instˆancias literais de um meta caracter, preceda o caracter com o
carcter de escape. Se vocˆe n˜ao especificar o caracter de ESCAPE, assume-se ‘\’:
String Description
\% Correponde a um caracter %
\_ Correponde a um caracter _
mysql> SELECT ’David!’ LIKE ’David\_’;
-> 0
mysql> SELECT ’David_’ LIKE ’David\_’;
-> 1
Para especificar um caracter de escape diferebte, use a cl´ausula ESCAPE:
mysql> SELECT ’David_’ LIKE ’David|_’ ESCAPE ’|’;
-> 1
As seguintes instru¸oes mostram que a compara¸ao de strings s˜ao
caso-insensitivo, a menos que um dos operandos seja uma string bin´aria:
mysql> SELECT ’abc’ LIKE ’ABC’;
-> 1
mysql> SELECT ’abc’ LIKE BINARY ’ABC’;
-> 0
LIKE ´e permitido em uma express˜ao num´erica! (Esta ´e uma extens˜ao MySQL
para o LIKE do SQL-99.)
mysql> SELECT 10 LIKE ’1%’;
414 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
-> 1
Nota: Como MySQL usa sintaxe de escape do C em strings (por exemplo,
\n’), vocˆe deve dobrar qualquer ‘\’ que voe usar em sua string LIKE. Por
exemplo, para pesquisar por ‘\n’, especifique-o como ‘\\n’. Para buscar por
\’, especifique-o como ‘\\\\’ (as barras invertidas s˜ao eliminadas uma vez pelo
analizador e outra vez quando a correspondˆencia de padr˜oes ´e feita, deixando
uma ´unicas barra invertida para ser verificada).
Note: OLIKE atual ao ´e um caracter multi-byte. Compara¸aoes s˜ao feitas
caracter por caracter.
expr NOT LIKE pad [ESCAPE ’car-escape’]
O mesmo que NOT (expr LIKE pad [ESCAPE ’car-escape’]).
expr SOUNDS LIKE expr
O mesmo que SOUNDEX(expr)=SOUNDEX(expr) (dispon´
ivel apenas na vers˜ao 4.1
ou posterior).
expr REGEXP pad
expr RLIKE pad
Realiza a busca de padr˜oes em uma express˜a string com base no padr˜ao pad.
O padr˜ao pode ser uma express˜ao regular extendida. See hundefinedi[Regexp],
page hundefinedi. Retorna 1se expr conincide com pad, sen˜ao retorna 0.RLIKE
´e um sinˆonimo para REGEXP, fornecido para compatibilidade com mSQL. Nota:
Como MySQL usa a sintaxe de escape do C em strings (por exemplo, ‘\n’),
vocˆe deve dobrar qualquer ‘\’ que vocˆe use em sua string REGEXP. Como na
vers˜ao 3.23.4 do MySQL, REGEXP ´e caso- insensitivo para strings normais (n˜ao
bin´arias).
mysql> SELECT ’Monty!’ REGEXP ’m%y%%’;
-> 0
mysql> SELECT ’Monty!’ REGEXP ’.*’;
-> 1
mysql> SELECT ’new*\n*line’ REGEXP ’new\\*.\\*line’;
-> 1
mysql> SELECT "a" REGEXP "A", "a" REGEXP BINARY "A";
-> 1 0
mysql> SELECT "a" REGEXP "^[a-d]";
-> 1
REGEXP eRLIKE usam o conjunto de caracteres atual (ISO-8859-1 Latin1 por
padr˜ao) para decidir o tipo de caracter.
expr NOT REGEXP pad
expr NOT RLIKE pad
O mesmo que NOT (expr REGEXP pad).
STRCMP(expr1,expr2)
STRCMP() retorna 0se as string s˜ao a mesma, -1 se o primeiro argumento ´e
menor que o segundo de acordo com a ordena¸ao atual e 1em caso contario:
mysql> SELECT STRCMP(’texto’, ’texto2’);
-> -1
Chapter 6: Referˆencia de Linguagem do MySQL 415
mysql> SELECT STRCMP(’texto2’, ’texto’);
-> 1
mysql> SELECT STRCMP(’texto’, ’texto’);
-> 0
MATCH (col1,col2,...) AGAINST (expr)
MATCH (col1,col2,...) AGAINST (expr IN BOOLEAN MODE)
MATCH ... AGAINST() ´e usado para busca de textos completos e retorna a
relvˆancia - similaridade medidad entre o texto nas colunas (col1,col2,...)
e a consulta expr. Relevˆancia ´e um n´umero de ponto flutuante. Relevˆancia
zero significa que n˜ao houve nenhuma similaridade. MATCH ... AGAINST() est´a
dispon´
ivel na vers˜ao 3.23.23 ou posterior do MySQL. A extens˜ao IN BOOLEAN
MODE foi adicionada na vers˜ao 4.0.1. Para detalhes e exemplos de uso, veja
hundefinedi[Fulltext Search], page hundefinedi.
6.3.2.2 Caso-Sensitivo
BINARY O operador BINARY transforma uma string em uma string bin´aria. Este ´e um
modo f´acil de for¸car a compara¸ao para se caso-sensitivo mesmo se a coluna
ao seja definida como BINARY ou BLOB:
mysql> SELECT "a" = "A";
-> 1
mysql> SELECT BINARY "a" = "A";
-> 0
BINARY string ´e um atalho para CAST(string AS BINARY). See hundefinedi
[Cast Functions], page hundefinedi.BINARY foi introduzida na vers˜ao 3.23.0 do
MySQL.
Note que em alguns contextos MySQL n˜ao estar´a apto a usar o ´
indice de forma
eficiente quando se transformar uma coluna ´
indice em BINARY.
Se vocˆe quiser compara um blob caso-insensitivo vocˆe pode sempre convertˆe-lo para letras
mai´usculas antes de faer a compara¸ao:
SELECT ’A’ LIKE UPPER(col_blobl) FROM nome_tabela;
ao planejamos introduzir em breve coer¸c˜ao (casting) entre diferentes conjuntos de carac-
teres para tornar compar¸oes de strings mais flex´
ivel.
6.3.3 Fun¸oes Num´ericas
6.3.3.1 Opera¸oes Aritim´eticas
Os operadores aritim´eticos usuais est˜ao dispon´
iveis. ‘-’, ‘+’, e ‘*’, o resultado ´e calculado
com precis˜ao de BIGINT (64-bit) se ambos os argumentos s˜ao inteiros! Se um dos argumentos
for um inteiro sem sinal, e o outro argumento ´e um inteiro tamem, o resultado ser´a um
inteiro sem sinal. See hundefinedi[Cast Functions], page hundefinedi.
+Adi¸ao:
mysql> SELECT 3+5;
-> 8
416 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
-Subtra¸ao:
mysql> SELECT 3-5;
-> -2
*Multiplica¸ao:
mysql> SELECT 3*5;
-> 15
mysql> SELECT 18014398509481984*18014398509481984.0;
-> 324518553658426726783156020576256.0
mysql> SELECT 18014398509481984*18014398509481984;
-> 0
O resultado da ´ultima express˜ao ´e incorreta porque o resultado da multiplica¸ao
de inteiros excede a faixa de 64-bits dos c´alculos BIGINT.
/Divis˜ao:
mysql> SELECT 3/5;
-> 0.60
Divis˜oes por zero produz um resultado NULL:
mysql> SELECT 102/(1-1);
-> NULL
Uma divis˜ao ser´a calculada com aritim´etica BIGINT somente se executada em
um contexto no qual o resultado ´e convertido para um interiro!
6.3.3.2 Fun¸oes Matematicas
Todas as fun¸oes matematicas retornam NULL no caso de um erro.
-Menos unario. Muda o sinal do argumento:
mysql> SELECT - 2;
-> -2
Note que se este operador ´e utilizando com um BIGINT, o valor retornado ´e um
BIGINT! Isto significa que vocˆe deve evitar usar -em inteiros que pode ter o
valor de -2^63!
ABS(X) Retorna o valor absoluto de X:
mysql> SELECT ABS(2);
-> 2
mysql> SELECT ABS(-32);
-> 32
O uso desta fun¸ao ´e seguro com valores BIGINT.
SIGN(X) Retorna o sinal do argumento como -1,0, ou 1, dependendo de quando X´e
negativo, zero, ou positivo:
mysql> SELECT SIGN(-32);
-> -1
mysql> SELECT SIGN(0);
-> 0
mysql> SELECT SIGN(234);
-> 1
Chapter 6: Referˆencia de Linguagem do MySQL 417
MOD(N,M)
%Modulo (como o operador %em C). Retorna o resto de Ndividido por M:
mysql> SELECT MOD(234, 10);
-> 4
mysql> SELECT 253 % 7;
-> 1
mysql> SELECT MOD(29,9);
-> 2
mysql> SELECT 29 MOD 9;
-> 2
O uso desta fun¸ao ´e seguro com valores BIGINT. O ´ultimo exemplo s´o funciona
no MySQL 4.1
FLOOR(X) Retorna o maior valor inteiro n˜ao maior que X:
mysql> SELECT FLOOR(1.23);
-> 1
mysql> SELECT FLOOR(-1.23);
-> -2
Note que o valor retornado ´e convertido para um BIGINT!
CEILING(X)
Retorna o menor valor inteiro n˜ao menor que X:
mysql> SELECT CEILING(1.23);
-> 2
mysql> SELECT CEILING(-1.23);
-> -1
Note que o valor retornado ´e convertido para um BIGINT!
ROUND(X)
ROUND(X,D)
Retorna o argumeto X, arredondado para o inteiro mais poximo. Com dois
argumentos o arredandamento ´e feito para um n´umero com Ddecimais.
mysql> SELECT ROUND(-1.23);
-> -1
mysql> SELECT ROUND(-1.58);
-> -2
mysql> SELECT ROUND(1.58);
-> 2
mysql> SELECT ROUND(1.298, 1);
-> 1.3
mysql> SELECT ROUND(1.298, 0);
-> 1
Note que o comportamento de ROUND() quando o argumento est´a no meio do
caminho entre dois inteiros depende da implementa¸ao da biblioteca C. Alguns
arredondamentos para o n´umero mais pr´oximo, ao sempre para baixo, para
cima ou s˜ao zero. Se vocˆe precisa de um tipo de arredondamento, vocˆe deve
usar uma fun¸ao bem definida como TRUNCATE() ou FLOOR().
DIV Divis˜ao de inteiros. Similar ao FLOOR() mas seguro com valores BIGINT.
418 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT 5 DIV 2
-> 2
DIV ´e novo no MySQL 4.1.0.
EXP(X) Retorna o valor de e(the base of natural logarithms) raised to the power of X:
mysql> SELECT EXP(2);
-> 7.389056
mysql> SELECT EXP(-2);
-> 0.135335
LN(X) Retorna o logaritmo natural de X:
mysql> SELECT LN(2);
-> 0.693147
mysql> SELECT LN(-2);
-> NULL
Esta fun¸ao foi adicionada na vers˜ao 4.0.3 do MySQL. ´
E sinˆonimo de LOG(X)
no MySQL.
LOG(X)
LOG(B,X) Se chamado com um parˆametro, esta fun¸ao retorna o logar´
itmo natural de X:
mysql> SELECT LOG(2);
-> 0.693147
mysql> SELECT LOG(-2);
-> NULL
Se chamado com dois parˆametros, esta fun¸ao retorna o logar´
itmo natural de X
para uma base arbitraria B:
mysql> SELECT LOG(2,65536);
-> 16.000000
mysql> SELECT LOG(1,100);
-> NULL
A op¸ao de base arbitr´aria foi adicionada na vers˜ao 4.0.3 do MySQL. LOG(B,X)
´e equivalente a LOG(X)/LOG(B).
LOG2(X) Returna o logar´
itmo na base 2 de X:
mysql> SELECT LOG2(65536);
-> 16.000000
mysql> SELECT LOG2(-100);
-> NULL
LOG2() ´e ´util para descobrir quantos bits um n´umero necessitaria para ser
armazenado. Esta fun¸ao foi adicionada na vers˜ao 4.0.3 do MySQL. Em vers˜oes
anteriores, vocˆe pode usar LOG(X)/LOG(2).
LOG10(X) Returna o logar´
itmo na base 10 de X:
mysql> SELECT LOG10(2);
-> 0.301030
mysql> SELECT LOG10(100);
-> 2.000000
mysql> SELECT LOG10(-100);
-> NULL
Chapter 6: Referˆencia de Linguagem do MySQL 419
POW(X,Y)
POWER(X,Y)
Retorna o valor de Xelevado a potˆencia de Y:
mysql> SELECT POW(2,2);
-> 4.000000
mysql> SELECT POW(2,-2);
-> 0.250000
SQRT(X) Retorna o a raiz quadrada n˜ao negativa de X:
mysql> SELECT SQRT(4);
-> 2.000000
mysql> SELECT SQRT(20);
-> 4.472136
PI() Retorna o valor de PI. A quantidade de n´umeros decimais padr˜ao ´e 5, mas o
MySQL usa internamente a precis˜ao dupla completa para PI.
mysql> SELECT PI();
-> 3.141593
mysql> SELECT PI()+0.000000000000000000;
-> 3.141592653589793116
COS(X) Retorna o cosseno de X, onde X´e dado em radianos:
mysql> SELECT COS(PI());
-> -1.000000
SIN(X) Retorna o seno de X, onde X´e dado em radianos:
mysql> SELECT SIN(PI());
-> 0.000000
TAN(X) Retorna a tangente de X, onde X´e dado em radianos:
mysql> SELECT TAN(PI()+1);
-> 1.557408
ACOS(X) Retorna o arco cosseno X, isto ´e, o valor cujo cosseno ´e X. Retorna NULL se X
ao est´a na faixa de -1 a1:
mysql> SELECT ACOS(1);
-> 0.000000
mysql> SELECT ACOS(1.0001);
-> NULL
mysql> SELECT ACOS(0);
-> 1.570796
ASIN(X) Retorna o arco seno X, isto ´e, o valor cujo seno ´e X. Retorna NULL se Xao est´a
na faixa de -1 a1:
mysql> SELECT ASIN(0.2);
-> 0.201358
mysql> SELECT ASIN(’foo’);
-> 0.000000
ATAN(X) Retorna o arco tangente X, isto ´e, o valor cuja tangente ´e X.X:
420 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT ATAN(2);
-> 1.107149
mysql> SELECT ATAN(-2);
-> -1.107149
ATAN(Y,X)
ATAN2(Y,X)
Retorna o arco tangente de duas variaveis XeY.´
E similar ao caclculo do arco
tengente de Y / X, exceto que os sinais de ambos argumentos s˜ao usados para
determinas o quadrante do resultado:
mysql> SELECT ATAN(-2,2);
-> -0.785398
mysql> SELECT ATAN2(PI(),0);
-> 1.570796
COT(X) Returns a cotangente de X:
mysql> SELECT COT(12);
-> -1.57267341
mysql> SELECT COT(0);
-> NULL
RAND()
RAND(N) Retorna um valor de ponto flutuante aleat´orio na faixa de 0a1.0. Se um
argumento inteiro N´e especificado, ele ´e usado como uma semente (produzindo
uma sequˆencia repetitiva):
mysql> SELECT RAND();
-> 0.9233482386203
mysql> SELECT RAND(20);
-> 0.15888261251047
mysql> SELECT RAND(20);
-> 0.15888261251047
mysql> SELECT RAND();
-> 0.63553050033332
mysql> SELECT RAND();
-> 0.70100469486881
Voe n˜ao pode usar uma coluna com valores RAND() em uma cl´ausula ORDER
BY, pois ORDER BY avaliaria a coluna m´ultiplas vezes. Na vers˜ao 3.23 vocˆe pode
fazer: SELECT * FROM nome_tabela ORDER BY RAND()
Isto ´e ´util para obter um amostra aleat´oria de um conjunto SELECT * FROM
tabela1,tabela2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000.
Note que um RAND() em uma cl´ausula WHERE ser´a reavliado toda vez que WHERE
´e executado.
RAND() ao ´e um gerador de n´umeros aletat´orios perfeito, mas ´e um modo
apido de se gerar n´umeros aleat´orios ad hoc que ser˜ao port´aveis entre platafor-
mas para a mesma vers˜ao do MySQL.
LEAST(X,Y,...)
Com dois ou mais argumentos, retorna o menor (valor-m´
inimo) argumento. Os
argumentos s˜ao comparados usando as seguintes regras:
Chapter 6: Referˆencia de Linguagem do MySQL 421
Se o valor de retorno ´e usado em um contexto INTEGER, ou todos argumen-
tos s˜ao valores inteiro, eles s˜ao comparados como inteiros.
Se o valor de retorno ´e usado em um contexto REAL, ou todos argumentos
ao valores reais, eles s˜ao comparados como inteiros.
Se qualquer um dos argumento for uma string caso-sensitivo, os argumentos
ao comparados como strings caso-sensitivo.
Nos outros casos, os argumentos s˜ao comparados como strings
caso-insensitivo:
mysql> SELECT LEAST(2,0);
-> 0
mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
-> 3.0
mysql> SELECT LEAST("B","A","C");
-> "A"
Em vers˜oes do MySQl anteriores a vers˜ao 3.22.5, vocˆe pode usar MIN() no lugar
de LEAST.
GREATEST(X,Y,...)
Retorna o maior (valor m´aximo) argumento. Os argumentos s˜ao comparados
usando as mesmas regras do LEAST:
mysql> SELECT GREATEST(2,0);
-> 2
mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
-> 767.0
mysql> SELECT GREATEST("B","A","C");
-> "C"
Em vers˜oes do MySQl anteriores a vers˜ao 3.22.5, vocˆe pode usar MAX() no lugar
de GRATEST.
DEGREES(X)
Retorna o argumento X, convertido de radianos para graus:
mysql> SELECT DEGREES(PI());
-> 180.000000
RADIANS(X)
Retorna o argumento X, convertido de graus para radianos:
mysql> SELECT RADIANS(90);
-> 1.570796
TRUNCATE(X,D)
Retiorna o n´umero X, truncado para Dcasas decimais. Se D´e 0, o resultado n˜ao
ter´a ponto deciaml ou prate fracion´aria:
mysql> SELECT TRUNCATE(1.223,1);
-> 1.2
mysql> SELECT TRUNCATE(1.999,1);
-> 1.9
mysql> SELECT TRUNCATE(1.999,0);
-> 1
422 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT TRUNCATE(-1.999,1);
-> -1.9
A partir do MySQL 3.23.51 todos o n´umeros s˜ao arredondados para zero.
Se D´e negativo, enao D numeros da parte inteira s˜ao zerados:
mysql> SELECT TRUNCATE(122,-2);
-> 100
Note que como os n´umeros decimais n˜ao s˜ao normalmente armazenados como
n´umeros exatos, mas como valores double, vocˆe pode obter o seguinte resultado:
mysql> SELECT TRUNCATE(10.28*100,0);
-> 1027
O resultado acima acontece porque 10.28 ´e, na verdade, armazenado como
10.2799999999999999.
6.3.4 Fun¸oes de Data e Hora
Veja hundefinedi[Tipos de data e hora], page hundefinedipara um descri¸ao da faixa de
valores que cada tipo tem e os formatos v´alidos nos quais valores de de data e hora podes
ser especificados.
Aqui est´a um exemplo que usa fun¸oes de data. A consulta seguinte seleciona todos os
registros com um valores em uma coluna col_data dentro dos ´ultimos 30 dias:
mysql> SELECT algo FROM nome_tabela
WHERE TO_DAYS(NOW()) - TO_DAYS(col_data) <= 30;
DAYOFWEEK(data)
Retorna o ´
indice do dia da semana para data (1= Domingo, 2= Segunda, ...
7= S´abado). Estes valores de ´
indices correspondem ao padr˜ao ODBC.
mysql> SELECT DAYOFWEEK(’1998-02-03’);
-> 3
WEEKDAY(data)
Retorna o ´
indice do dia das semana para data (0= Segunda, 1= Ter¸ca, ... 6
= Domingo):
mysql> SELECT WEEKDAY(’1998-02-03 22:23:00’);
-> 1
mysql> SELECT WEEKDAY(’1997-11-05’);
-> 2
DAYOFMONTH(data)
Retorna o dia do mˆes para data, na faixa de 1at´e 31:
mysql> SELECT DAYOFMONTH(’1998-02-03’);
-> 3
DAYOFYEAR(data)
Retorna o dia do ano para data, na faixa de 1at´e 366:
mysql> SELECT DAYOFYEAR(’1998-02-03’);
-> 34
Chapter 6: Referˆencia de Linguagem do MySQL 423
MONTH(data)
Retorna o mˆes para data, na faixa de 1at´e 12:
mysql> SELECT MONTH(’1998-02-03’);
-> 2
DAYNAME(data)
Retorna o nome do dia da semana para data:
mysql> SELECT DAYNAME("1998-02-05");
-> ’Thurday’
MONTHNAME(data)
Retorna o nome do mˆes para data:
mysql> SELECT MONTHNAME("1998-02-05");
-> ’February’
QUARTER(data)
Retorna o trimestre para data, na faixa de 1at´e 4:
mysql> SELECT QUARTER(’98-04-01’);
-> 2
WEEK(data)
WEEK(data,primeiro)
Com um ´unico argumento, retorna a semana para date, na faixa de 0a53 (sim,
pode ter o inicio de uma semana 53), para locais onde Domingo ´e o primeiro
dia da semana. A forma de WEEK com dois argumentos permite especificar se a
semana come¸ca no Domingo ou na Segunda e se o valor de retorno de estar na
faixa 0-53 ou 1-52.
Aqui est´a uma tabela para como o segundo argumento funciona:
Value Meaning
0 Semana come¸ca no Domingo e retorna
valor na faixa 0-53
1 Semana come¸ca na Segunda e retorna
valor na faixa 0-53
2 Semana come¸ca no Domingo e retorna
valor na faixa 1-53
3 Semana come¸ca na Segunda e retorna
valor na faixa 1-53 (ISO 8601)
mysql> SELECT WEEK(’1998-02-20’);
-> 7
mysql> SELECT WEEK(’1998-02-20’,0);
-> 7
mysql> SELECT WEEK(’1998-02-20’,1);
-> 8
mysql> SELECT WEEK(’1998-12-31’,1);
-> 53
Voe pode definir o valor padr˜ao do segundo argumento atrav´es de uma vari´avel
default week format. A sintaxe de default week format ´e:
SET [SESSION |GLOBAL] default week format = [0|1|2|3];
Nota: Na vers˜ao 4.0, WEEK(#,0) foi alterado para corresponder ao calend´ario
americano.
424 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note que se a semana for a ´ultima semana do ano anterior, MySQL retornar´a
0 se vocˆe n˜ao usar 2 ou 3 como argumento opcional:
mysql> SELECT YEAR(’2000-01-01’), WEEK(’2000-01-01’,0);
-> 2000, 0
mysql> SELECT WEEK(’2000-01-01’,2);
-> 52
Alg´uem pode dizer que o MySQL deveria retornar 52 para a fun¸ao WEEK() ja
que a data dada ´e, na verdade, a 52 semana de 1999. os decidimos retornar
0 j´a que queremos que fun¸ao retorne ’o n´umero da semana do ano dado’. Isto
faz com que o uso da fun¸ao WEEK() seja seguro quando combinado com outras
fun¸oes que extraiam um parte de uma data.
Se vocˆe prefere saber a semana correta do ano, enao vocˆe deve usar o 2 ou 3
como argumento opcional ou usar a fun¸ao YEARWEEK():
mysql> SELECT YEARWEEK(’2000-01-01’);
-> 199952
mysql> SELECT MID(YEARWEEK(’2000-01-01’),5,2);
-> 52
YEAR(data)
Retorna o ano para data na faixa de 1000 a9999:
mysql> SELECT YEAR(’98-02-03’);
-> 1998
YEARWEEK(data)
YEARWEEK(data,primeiro)
Retorna o ano e a semana para a data. O segundo argumento funciona exata-
mente como o segundo argumento de WEEK(). Note que o ano pode ser diferente
do ano no argumento data para a primeira e a ´ultima semana do ano:
mysql> SELECT YEARWEEK(’1987-01-01’);
-> 198653
Note que o n´umero da semana ´e diferente do que seria retornado pela fun¸ao
WEEK() (0) para os argumentos opcionais 0 ou 1, j´a que WEEK() retorna a semana
no centexto de um ano dado.
HOUR(hora)
Retorna a hora para hora, na faixa de 0a23:
mysql> SELECT HOUR(’10:05:03’);
-> 10
MINUTE(hora)
Retorna o minuto para hora, na faixa de 0a59:
mysql> SELECT MINUTE(’98-02-03 10:05:03’);
-> 5
SECOND(hora)
Retorna o segundo para hora, na faixa de 0a59:
mysql> SELECT SECOND(’10:05:03’);
-> 3
Chapter 6: Referˆencia de Linguagem do MySQL 425
PERIOD_ADD(P,N)
Adiciona Nmeses ao per´
iodo P(no formato AAMM ou AAAAMM). Retorna um valor
no formato AAAAMM.
Note que o argumento de per´
iodo Pao ´e um valor de data:
mysql> SELECT PERIOD_ADD(9801,2);
-> 199803
PERIOD_DIFF(P1,P2)
Retorna o n´umero de meses entre os per´
iodos P1 eP2.P1 eP2 devem estar no
formato AAMM ou AAAAMM.
Note que os argumentos de per´
iodo P1 eP2 ao ao valores de data:
mysql> SELECT PERIOD_DIFF(9802,199703);
-> 11
DATE_ADD(data,INTERVAL tipo expr)
DATE_SUB(data,INTERVAL tipo expr)
ADDDATE(data,INTERVAL tipo expr)
SUBDATE(data,INTERVAL tipo expr)
Estas fun¸oes realizam opera¸oes aritm´eticas em datas. ADDDATE() eSUBDATE()
ao sinˆonimos para DATE_ADD() eDATE_SUB().
Na vers˜ao 3.23 do MySQL, vocˆe pode usar +e-ao inv´es de DATE_ADD() e
DATE_SUB() se a express˜ao do lado direito ´e um coluna date ou datetime. (Veja
exemplo abaixo.)
data ´e um valor DATETIME ou DATE especificando a data de in´
icio. expr is
an express˜ao especificando o intervala a ser adicionado ou subtraido da data de
in´
icio. expr ´e uma string; ela pode iniciar com um ‘-’ para intervalos negativos.
type ´e uma palavra chave indicando como a express˜ao deve ser interpretada.
A seguinte tabela mostra como os argumentos tipo eexpr se relacionam:
tipo do valor Formarto esperado da expr
SECOND SEGUNDOS
MINUTE MINUTOS
HOUR HORAS
DAY DIAS
MONTH MESES
YEAR ANOS
MINUTE_SECOND "MINUTOS:SEGUNDOS"
HOUR_MINUTE "HORAS:MINUTOS"
DAY_HOUR "DIAS HORAS"
YEAR_MONTH "ANOS-MESES"
HOUR_SECOND "HORAS:MINUTOS:SEGUNDOS"
DAY_MINUTE "DIAS HORAS:MINUTOS"
DAY_SECOND "DIAS HORAS:MINUTOS:SEGUNDOS"
O MySQL permite qualquer delimitador de pontua¸c˜ao no formato de expr. Os
delimitadores mostrados na tabela s˜ao apenas sugeridos. Se o argumento date
´e um valor de DATA e seus c´alculos envolvem apenas as partes ANO,MS, e DIA
(into ´e, nenhuma parte de hora), o resultado ´e um valor do tipo DATE. Sen˜ao,
o resultado ´e um valor do tipo DATETIME:
426 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
-> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
-> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
-> INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
-> INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
-> INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
-> INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
-> INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
Se vocˆe especificado um intervalo muito curto (n˜ao inclue todas as partes que
seriam esperadas pelo intervalo para aquele tipo), MySQL assume que vocˆe
ao especificou a parte mais a esquerda do valor do intervalo. Por exemplo, se
vocˆe especifica um tipo DAY_SECOND, o valor esperado de expr dever´a ter as
partes de dias, horas, minutos e segundos. Se vocˆe especifica um valor como
"1:10", MySQL assume que as partes do dia e da hora foram esquecidas e o
valor representa minutos e segundos. Em outras palavras, "1:10" DAY_SECOND
´e interpretado de forma equivalente a "1:10" MINUTE_SECOND. Isto ´e an´alogo a
forma que o MySQL interpreta valores TIME representado tempo decorrido no
lugar de hora do dia.
Note que se vocˆe adicionar ou subtrair um valor contendo data com um outro
contendo uma parte de hora, o valor data ser´a automaticamente convertido
para um valor datetime:
mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 DAY);
-> 1999-01-02
mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 HOUR);
-> 1999-01-01 01:00:00
Se vocˆe utilizar datas incorretas, o valor retornado NULL. Sˆe vocˆe adicionar
MONTH,YEAR_MONTH, ou YEAR e a data resultante tiver um dia maior que o dia
aximo para aquele mˆes, o dia ´e ajustado para o dia m´aximo no mˆes.
mysql> SELECT DATE_ADD(’1998-01-30’, INTERVAL 1 MONTH);
-> 1998-02-28
Note pelo exemplo anterior que a palavra INTERVAL e a palavra chave type ao
ao caso sensitivo.
Chapter 6: Referˆencia de Linguagem do MySQL 427
EXTRACT(tipo FROM data)
A fun¸ao EXTRACT() usa o mesmo tipo de intervalo especificado como DATE_
ADD() ou DATE_SUB(), mas extrai partes da da data em vez de realizar ar-
itim´etica de data.
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102
TO_DAYS(data)
Dada uma data data, retorna o n´umero do dia (o n´umero de dias desde o ano
0);
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS(’1997-10-07’);
-> 729669
TO_DAYS() ao pode ser usado com valores que orecedem o advento do calen-
dario Gregoriano (1582), porque ele n˜ao leva em conta os dias perdidos quando
o calend´ario foi mudado.
FROM_DAYS(N)
Dado um n´umero de dia N, retorna um valor DATE:
mysql> SELECT FROM_DAYS(729669);
-> ’1997-10-07’
FROM_DAYS() ao pode ser usado com valores que orecedem o advento do calen-
dario Gregoriano (1582), porque ele n˜ao leva em conta os dias perdidos quando
o calend´ario foi mudado.
DATE_FORMAT(data,formato)
Formata o valor de data de acordo com a string formato string. Os seguintes
identificadores podem ser utilizados na string formato:
Specifier Description
%M Nome do mˆes (January..December)
%W Nome da semana (Sunday..Saturday)
%D Dia do mˆes com sufixo Inglˆes (0th,1st,2nd,3rd, etc.)
%Y Ano, numerico, 4 digitos
%y Ano, numerico, 2 digitos
%X Ano para a semana onde o Domingo ´e o primeiro dia da
semana, numerico, 4 digitos, usado com ’%V’
%x Ano para a semana onde a segunda ´e o primeiro dia da
semana, numerico, 4 digitos, usado com ’%v’
%a Nome da semana abreviado (Sun..Sat)
%d Dia do mˆes, numerico (00..31)
%e Dia do mˆes, numerico (0..31)
%m Mˆes, numerico (00..12)
%c Mˆes, numerico (0..12)
428 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
%b Nome do mˆes abreviado (Jan..Dec)
%j Dia do ano (001..366)
%H Hora (00..23)
%k Hora (0..23)
%h Hora (01..12)
%I Hora (01..12)
%l Hora (1..12)
%i Minutos, numerico (00..59)
%r Tempo, 12-horas (hh:mm:ss [AP]M)
%T Tempo, 24-horas (hh:mm:ss)
%S Segundos (00..59)
%s Segundos (00..59)
%p AM ou PM
%w Dia da semana (0=Domingo..6=Sabado)
%U Semana(00..53), onde o Domingo ´e o primeiro dia da
semana.
%u Semana(00..53), onde a Segunda ´e o primeiro dia da
semana.
%V Semana(01..53), onde o Domingo ´e o primeiro dia da se-
mana. Usado com ’%X’
%v Semana(01..53), onde a Segunda ´e o primeiro dia da se-
mana. Usado com ’%x’
%% Um literal ‘%’.
Todos os outros caracteres s˜ao apenas copiados para o resultado, sem inter-
preta¸ao:
mysql> SELECT DATE_FORMAT(’1997-10-04 22:23:00’, ’%W %M %Y’);
-> ’Saturday October 1997’
mysql> SELECT DATE_FORMAT(’1997-10-04 22:23:00’, ’%H:%i:%s’);
-> ’22:23:00’
mysql> SELECT DATE_FORMAT(’1997-10-04 22:23:00’,
’%D %y %a %d %m %b %j’);
-> ’4th 97 Sat 04 10 Oct 277’
mysql> SELECT DATE_FORMAT(’1997-10-04 22:23:00’,
’%H %k %I %r %T %S %w’);
-> ’22 22 10 10:23:00 PM 22:23:00 00 6’
mysql> SELECT DATE_FORMAT(’1999-01-01’, ’%X %V’);
-> ’1998 52’
Como na vers˜ao 3.23 do MySQL, o caracter ‘% ´e exigido antes dos caracteres
de especifica¸ao de formato. Em vers˜oes anteriores do MySQL ‘%’ era opcional.
A raz˜ao para a faixa de valores do mˆes e do dia come¸carem com zero ´e
que o MySQL permite datas incompletas tais como ’2004-00-00’ serem
armazenadas no MySQL 3.23.
TIME_FORMAT(hora,formato)
´
E usado como a fun¸ao DATE_FORMAT() acima, mas a string de formato pode
conter apenas os especificadores de formato que tratam de horas, minutos e
segundos. Outros especificadores produzem um valor NULL ou 0.
Chapter 6: Referˆencia de Linguagem do MySQL 429
CURDATE()
CURRENT_DATE
Retorna a data de hoje como um valor no formato ’YYYY-MM-DD’ ou YYYYMMDD,
dependendo se a fun¸ao ´e usada num contexto num´erico ou de string.
mysql> SELECT CURDATE();
-> ’1997-12-15’
mysql> SELECT CURDATE() + 0;
-> 19971215
CURTIME()
CURRENT_TIME
Retorna a hora atual como um valor no formato ’HH:MM:SS’ ou HHMMSS,
mysql> SELECT CURTIME();
-> ’23:50:26’
mysql> SELECT CURTIME() + 0;
-> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
Retorna a data e hora atual como um valor no formato ’YYYY-MM-DD HH:MM:SS’
ou YYYYMMDDHHMMSS, dependendo se a fun¸ao ´e utilizada num contexto num´erico
ou de string.
mysql> SELECT NOW();
-> ’1997-12-15 23:50:26’
mysql> SELECT NOW() + 0;
-> 19971215235026
Note que NOW() o ´e avaliado uma vez por consulta, definido no inicio da ex-
ecu¸ao. Isto significa que m´ultiplas referˆencias a NOW() em uma ´unica consulta
ir´a sempre retornar o mesmo valor.
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(data)
Se chamado sem argumento, retorna um tipo timestamp do Unix (segundos
desde ’1970-01-01 00:00:00’ GMT) como um inteiro sem sinal. Se UNIX_
TIMESTAMP() ´e chamada com um argumento data, ´e retornado o valor do argu-
mento como segundo desde ’1970-01-01 00:00:00’ GMT. data pode ser um
string DATE, uma string DATETIME, um TIMESTAMP, ou um n´umero no formato
YYMMDD ou YYYYMMDD na hora local:
mysql> SELECT UNIX_TIMESTAMP();
-> 882226357
mysql> SELECT UNIX_TIMESTAMP(’1997-10-04 22:23:00’);
-> 875996580
Qaundo UNIX_TIMESTAMP ´e usado em uma coluna TIMESTAMP, a fun¸ao re-
tornar´a o valor timestamp interno diretamente, sem nenhuma convers˜ao “string-
para-unix-timestamp” implicita. Se vocˆe passar uma data fora da faixa para
UNIX_TIMESTAMP(), a fun¸ao ir´a retornar 0, mas por favor note que s´o veri-
fica¸oes b´asicas s˜ao realizadas. (ano 1970-2037, mˆes 01-12, dia 01-31).
430 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vocˆe subtrair colunas UNIX_TIMESTAMP(), vocˆe pode querer mudar o resul-
tado para inteiro com sinal. See hundefinedi[Fun¸oes de tipagem], page hunde-
finedi.
FROM_UNIXTIME(unix_timestamp [,formato])
Retorna a representa¸ao do argumento unix_timestamp como um valor no for-
mato ’YYYY-MM-DD HH:MM:SS’ ou YYYYMMDDHHMMSS, dependendo de do contexto
em que a fun¸o ´e utilizada:
Se o formato ´e dado o resultado ´e formatado de acordo com a string formato.
formato pode conter os especificadores listados acima para a fun¸ao DATE_
FORMAT()
mysql> SELECT FROM_UNIXTIME(875996580);
-> ’1997-10-04 22:23:00’
mysql> SELECT FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
’%Y %D %M %h:%i:%s %x’);
-> ’1997 23rd December 03:43:30 1997’
SEC_TO_TIME(seconds)
Retorna o argumento segundos, convertido em horas, minutos e segundos como
um valor no formato ’HH:MM:SS’ ou HHMMSS, dependendo do contexto em que
a fun¸ao ´e utilizada:
mysql> SELECT SEC_TO_TIME(2378);
-> ’00:39:38’
mysql> SELECT SEC_TO_TIME(2378) + 0;
-> 3938
TIME_TO_SEC(time)
Retorna o argumento time, convertido em segundos:
mysql> SELECT TIME_TO_SEC(’22:23:00’);
-> 80580
mysql> SELECT TIME_TO_SEC(’00:39:38’);
-> 2378
6.3.5 Fun¸oes de Convers˜ao
A sintaxe da fun¸ao CAST ´e:
CAST(express~ao AS tipo)
ou
CONVERT(express~ao,tipo)
Onde tipo ´e um dos:
BINARY
CHAR (Novo na vers˜ao 4.0.6)
DATE
DATETIME
Chapter 6: Referˆencia de Linguagem do MySQL 431
SIGNED {INTEGER}
TIME
UNSIGNED {INTEGER}
CAST() ´e da sintaxe SQL-99 syntax e CONVERT() ´e da sintaxe ODBC.
A fun¸ao de convers˜ao ´e principalmente ´util quando vocˆe deseja criar uma coluna com um
tipo espec´
ifico em uma CREATE ... SELECT:
CREATE TABLE nova_tabela SELECT CAST(’2000-01-01’ AS DATE);
CAST(string AS BINARY ´e a mesma coisa que BINARY string.CAST(expr AS CHAR trata a
express˜ao como sendo uma string com o conjunto de caracteres padr˜ao.
Para converter uma string para um valor num´erico, normalmente n˜ao ´e necess´ario se fazer
nada; apenas use a string como se fosse um n´umero:
mysql> SELECT 1+’1’;
-> 2
Se vocˆe usar um n´umero em um contexto string, o n´umero ser´a convertido automaticamente
para uma string BINARY.
mysql> SELECT CONCAT("hello you ",2);
-> "hello you 2"
O MySQL suporta aritim´etico com valores de 64 bits com sinal e sem sinal. Se vocˆe est´a
usando um opera¸ao num´erica (como +) e um dos operandos ´e unsigned integer (inteiro
sem sinal), o resultado tamb´em ser´a sem sinal (unsigned). Vocˆe pode for¸car o tipo usando
os operadores de convers˜ao SIGNED eUNSIGNED, os quais ir˜ao converter a opera¸ao para um
inteiro de 65 bits com sinal e sem sinal, respectivamente.
mysql> SELECT CAST(1-2 AS UNSIGNED)
-> 18446744073709551615
mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
-> -1
Note que se um dos operdores for um valor de ponto flutuante (neste contexto DECIMAL()
´e considerado um valor de ponto flutuante) o resultado ser´a um valor de ponto flutuante e
ao ´e afetado pela regra acima.
mysql> SELECT CAST(1 AS UNSIGNED) -2.0
-> -1.0
Se vocˆe estiver utilizando uma string em uma opera¸c˜ao aritim´etica, ela ´e convertida para
um n´umero de ponto flutuante.
As fun¸oes CAST() eCONVERT() foram adicionadas no MySQL 4.0.2.
O tratamento de valores sem sinais foi mudado no MySQL 4.0 para suportar valores BIGINT
apropriadamente. Se vocˆe tiver algum c´odigo que deseja executar no MySQL 4.0 e 3.23
(casos em que vocˆe provavelmente n˜ao poder´a usar a fun¸ao CAST), vocˆe pode utilizar o
seguinte truque para conseguir um resultado com sinal quando subtraindo duas colunas do
tipo unsigned integer (inteiro sem sinal):
SELECT (coluna_sem_sinal_1+0.0)-(coluna_sem_sinal_2+0.0);
A id´eia ´e que as colunas sejam convertidas para ponto flutuante antes de se fazer a subtra¸ao.
Se vocˆe tiver algum problema com colunas UNSIGNED no seu aplica¸ao MySQL antiga ao
portar para o MySQL 4.0, vocˆe pode usar a op¸ao --sql-mode=NO_UNSIGNED_SUBTRACTION
432 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ao iniciar mysqld. Note, no entanto, que enquanto voe utilizar esta op¸ao, ao ser´a poss´
ivel
conseguir um uso efetivo do tipo de coluna UNSIGNED BIGINT.
6.3.6 Outras Fun¸oes
6.3.6.1 Fun¸oes Bin´arias
O MySQL utiliza aritim´etica BIGINT (64bits) para opera¸oes bin´arias, assim estes oper-
adores possuem uma faixa m´axima de 64 bits.
|Operador bin´ario OR
mysql> SELECT 29 | 15;
-> 31
O resultado ´e um inteiro sem sinal de 64 bits.
&Operado bin´ario AND
mysql> SELECT 29 & 15;
-> 13
O resultado ´e um inteiro sem sinal de 64 bits.
^Operado bin´ario XOR
mysql> SELECT 1 ^ 1;
-> 0
mysql> SELECT 1 ^ 0;
-> 1
mysql> SELECT 11 ^ 3;
-> 8
O resultado ´e um inteiro sem sinal de 64 bits.
XOR foi adicionado na vers˜ao 4.0.2.
<<
Desloca um numero BIGINT (muito grande) a esquerda:
mysql> SELECT 1 << 2;
-> 4
O resultado ´e um inteiro sem sinal de 64 bits.
>> Desloca um numero BIGINT (muito grande) a direita:
mysql> SELECT 4 >> 2;
-> 1
O resultado ´e um inteiro sem sinal de 64 bits.
~Inverte todos os bits:
mysql> SELECT 5 & ~1;
-> 4
O resultado ´e um inteiro sem sinal de 64 bits.
BIT_COUNT(N)
Retorna o n´umero de bits que s˜ao passados no argumento N:
mysql> SELECT BIT_COUNT(29);
-> 4
Chapter 6: Referˆencia de Linguagem do MySQL 433
6.3.6.2 Fun¸oes Diversas
DATABASE()
Retorna o nome do banco de dados atual:
mysql> SELECT DATABASE();
-> ’test’
Se nenhum banco de dados estiver selecionado, DATABASE() retorna uma string
vazia.
USER()
SYSTEM_USER()
SESSION_USER()
retorna o nome do usu´ario MySQL atual:
mysql> SELECT USER();
-> ’davida@localhost’
Na vers˜ao 3.22.11 do MySQL ou posterior, s˜ao incluidos o nome de m´aquina
do cliente e o nome do usu´ario. Voe pode extrair apenas a parte do nome da
seguinte forma (o qual funciona tamb´em com a parte do nome de m´aquna):
mysql> SELECT SUBSTRING_INDEX(USER(),"@",1);
-> ’davida’
CURRENT_USER()
Retorna o nome do usu´ario, como foi autenticado na sess˜ao atual
mysql> SELECT USER();
-> ’davida@localhost’
mysql> SELECT * FROM mysql.user;
-> ERROR 1044: Access denied for user: ’@localhost’ to database ’mysql’
mysql> SELECT CURRENT_USER();
-> ’@localhost’
PASSWORD(str)
OLD_PASSWORD(str)
Calcula a senha a partir de senha str em texto puro. Est´a ´e a fun¸ao que ´e
utilizada para criptografar a senha do MySQL para armazenamento na coluna
Password da tabela de permiss˜oes user
mysql> SELECT PASSWORD(’badpwd’);
-> ’7f84554057dd964b’
A criptografia de PASSWORD() ao e revers´
ivel.
PASSWORD() ao realiza a criptografia da senha da mesa maneira que as senhas
Unix s˜ao criptografadas. Veja ENCRYPT().
Note: A fun¸ao PASSWORD() ´e usada pelo sistema de autentifica¸ao no servi-
dor MySQL, vocˆe N~
AO deve uitliz´a-las em suas pr´oprias aplica¸oes. Para este
prop´osito utilize MD5() ou SHA1(). Veja tamb´em RFC-2195 para maiores in-
forma¸oes sobre o tratamento de senha e autentica¸ao segura em suas aplica¸oes.
ENCRYPT(str[,salt])
Criptografa str utilizando a chamada de sistema crypt() do Unix. O argu-
mento salt deve ser uma string com dois caracteres. (Na vers˜ao 3.22.16 do
MySQL, salt deve ser maior que dois caracteres.):
434 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT ENCRYPT("hello");
-> ’VxuFAJXVARROc’
Se crypt() ao estiver dispon´
ivel no seu sistema, ENCRYPT() sempre retorna
NULL.
ENCRYPT() ignora tudo depois dos primeiros 8 caracteres de str, pelo menos
em alguns sistemas. Isto ´e determinado pelo comportamento da chamada de
sistema crypt().
ENCODE(str,senha_str)
Criptografa str usando senha_str como a senha. Para descriptografar o re-
sultado, utilize DECODE().
O resultado ´e uma string bin´aria do mesmo tamanho de str. Se vocˆe deseja
salv´a-la em uma coluna, use uma coluna do tipo BLOB.
DECODE(cript_str,senha_str)
Descriptografa o string criptografada cript_str usando senha_str como a
senha. cript_str deve ser uma string retornada de ENCODE().
MD5(string)
Calcula um checksum MD5 de 128 bits para a string. O valor ´e retornado como
um n´umero hexadecimal de 32 digitos que pode, por exemplo, ser usado como
uma chave hash:
mysql> SELECT MD5("testing");
-> ’ae2b1fca515949e5d54fb22b8ed95575’
Este ´e o "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
SHA1(string)
SHA(string)
Calcula um checksum SHA1 de 160 bit para a string, como descrito no RFC
3174 (Algoritmo Hash de Seguran¸ca). O valor ´e retornado como um n´umero
hexadecial de 40 digitos, or NULL no caso do argumento ser NULL . Uma das
possibilidades para o uso desta fun¸ao ´e a chave hash. Voe tamb´em pode us´a-lo
como uma fun¸ao segura de criptografia para armazenar senhas.
mysql> SELECT SHA1("abc");
-> ’a9993e364706816aba3e25717850c26c9cd0d89d’
SHA1() foi adicionado na vers˜ao 4.0.2, e pode ser considerada um equivalente
ao MD5() com criptografia mais segura. SHA() ´e um sinˆonimo para SHA1().
AES_ENCRYPT(string,string_chave)
AES_DECRYPT(string,string_chave)
Estas fun¸oes permitem criptografia/descriptografia de dados usando o algo-
ritmo oficial AES (Padr˜ao Avan¸cado de Criptografia), antes conhecido como
Rijndael. Criptgrafia com uma chave de 128 bits podem ser usadas, mas vocˆe
pode extendˆe-la para 256 bits atrav´es da fonte. os escolhemos 128 bits porque
´e muito mais r´apido e ´e bastante seguro.
Os argumentos de entrada podem ser de qualquer tamanho. Se ambos argu-
mentos s˜ao NULL, o resultado desta fun¸ao tam b´em ser´a NULL.
Chapter 6: Referˆencia de Linguagem do MySQL 435
Como o AES ´e um algor´
itimo de n´
ivel de bloco, padding ´e usado para codificar
strings de tamanho ´
impares e enao a string resultante pode ser calculada como
16*(trunc(tamanho string/16)+1).
Se AES_DECRYPT() detectar dados inalidos ou padding incorreto, ela retornar´a
NULL. No entanto, ´e poss´
ivel para o AES_DECRYPT() retornar um valor n˜ao-NULL
(possivelmente lixo) se os dados de entrada ou a chave forem inalidos
Voe pode usar as fun¸oes AES para armazenar dados de forma criptografada
modificando as suas consultas:
INSERT INTO t VALUES (1,AES_ENCRYPT("texto","senha"));
Voe pode obter mais seguran¸ca evitando tranferir a chave em suas conex˜oes a
cada consulta, o que pode ser conseguido armazenando-o em var´aveis do lado
do servidor na hora das conex˜ao.
SELECT @senha:="minha senha";
INSERT INTO t VALUES (1,AES_ENCRYPT("texto",@senha));
AES_ENCRYPT() eAES_DECRYPT() foram adicionados na vers˜ao 4.0.2, e podem
ser considerados a fun¸ao de criptografia mais segura atualmente dispon´
ivel no
MySQL.
DES_ENCRYPT(string_para_ciptografar [, (numero_chave | chave_string) ] )
Criptografa a string com a chave dada utilizando o algortimo Triplo-DES.
Note que esta fun¸ao s´o funciona se vocˆe tiver configurado o MySQL com su-
porte a SSl. See hundefinedi[Conex˜oes seguras], page hundefinedi.
A chave de criptografia utilizada ´e escolhida da seguinte forma:
Argumento Descri¸ao
Somente um
argumento
A primeira chave de des-key-file ´e utilizada.
N´umero da chave A chave dada (0-9) de des-key-file ´e utilizada.
string A chave_string dada ser´a utilizada para criptografar
string_para_criptografar.
O string retornada ser´a uma string bin´aria onde o primeiro caracter ser´a
CHAR(128 | n´umero_chave).
O 128 ´e adicionado para facilitar o reconhecimento da chave de criptografia. Se
vocˆe usar uma chave string, num´ero_chave ser´a 127.
Havendo erro, esta fun¸ao retorna NULL.
O tamanho da string para o resultado ser´a novo_tamanho= tamanho_orig +
(8-(tamanho_orig % 8))+1.
Odes-key-file ter´a o seguinte formato:
numero_chave chave_string_des
numero_chave chave_string_des
Cada numero_chave deve ser um n´uero na faixa de 0 a 9. As linhas do arquivo
podem estar em qualquer ordem. chave_string_des ´e a string que ser´a usada
para criptografar a mensagem. Entre o n´umero e a chave deve haver pelo menos
um espa¸co. A primeira chave ´e a chave padr˜ao que ser´a utilizada se n˜ao for
especificada nenhuma chave como argumento para DES_ENCRYPT()
436 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Voe pode dizer ao MySQL para ler novos valores de arquivos de chave com o
comando FLUSH DES_KEY_FILE. Isto exige o privil´egio Reload_priv.
Um benef´
icio de ter um conjunto de chaves padr˜oes ´e que ele d´a a aplica¸ao um
modo de verificar a existˆencia de valores criptografados em colunas, sem dar ao
usu´ario final o direito de descriptografar estes valores.
mysql> SELECT endereco_clientes FROM tabela_clientes WHERE
cartao_credito_criptografado = DES_ENCRYPT("numero_cartao_
credito");
DES_DECRYPT(string_para_descriptografar [, chave_string])
Derscritogra uma string criptografada com DES_ENCRYPT().
Note que esta fun¸ao s´e funciona se vocˆe tiver configurado o MySQL com su-
porte SSL. See hundefinedi[Conex˜oes seguras], page hundefinedi.
Se nenhum argumento chave_string for dado, DES_DECRYPT() examina o
primeiro byte da string criptografada para determinar o n´umero de chave DES
que foi usado para criptografar a string original, e enao lˆe a chave de des-key-
file para descriptografar a mensagem. Para isto funcionar o usu´ario deve ter
o privil´egio SUPER.
Se vocˆe passar para esta fun¸ao um argumento chave_string, aquela string ´e
usada como a chave para descriptografar a mensagem.
Se a string_para_descriptografar ao se paracer com uma string crip-
tografada, o MySQL retornar´a a string_para_descriptografar dada.
Havendo erro, esta fun¸ao retorna NULL.
LAST_INSERT_ID([expr])
Retorna o ´ultimo valor gerado automaticamente que tenha sido inserido em um
coluna AUTO_INCREMENT. See hundefinedi[mysql_insert_id()], page hunde-
finedi.
mysql> SELECT LAST_INSERT_ID();
-> 195
O ´ultimo ID que foi gerado e mantido no servidor em uma base por conex˜ao.
Ele n˜ao ser´a alterado por outro cliente. Ele nem mesmo ser´a atualizado se vocˆe
atuializar outra coluna AUTO_INCREMENT com um valor n˜ao-m´agico (Isto ´e, um
valro que n˜ao seja NULL e nem 0).
Se vocˆe inserir muitos registros ao mesmo tempo com uma instru¸ao insert,
LAST_INSERT_ID() retorna o valor da primeira linha inserida. A raz˜ao para
isto ´e tornar poss´
ivel reproduzir facilmente a mesma intru¸ao INSERT em algum
outro servidor.
Se expr ´e dado com um argumento para LAST_INSERT_ID(), enao o valor
do argumento ´e retornado pela fun¸ao e ´e configurado como o pr´oximo valor
para ser retornado pela LAST_INSERT_ID(). Isto pode ser ´util para simular
sequˆencias:
Primeiro crie a tabela:
mysql> CREATE TABLE sequencia (id INT NOT NULL);
mysql> INSERT INTO sequencia VALUES (0);
Enao a tabela pode ser usada para gerar sequˆencia de n´umeros como estes:
Chapter 6: Referˆencia de Linguagem do MySQL 437
mysql> UPDATE sequencia SET id=LAST_INSERT_ID(id+1);
Voe pode gerar sequˆencias sem chamar LAST_INSERT_ID(), mas a utilidade
de se usar a fun¸ao deste modo ´e que o valor ID ´e mantido no servidor como o
´ultimo valor gerado automaticamente (seguro para multi-usur´ario). Vocˆe pode
recuperar a nova ID como vocˆe leria qualquer valor AUTO_INCREMENT normal
no MySQL. Por exemplo, LAST_INSERT_ID() (sem um argmento) retornar´a a
nova ID. A fun¸ao mysql_insert_id() da API C tamb´em pode ser usada para
obter o valor.
Note que como mysql_insert_id() o ´e atualizado depois de instru¸oes INSERT
eUPDATE, vocˆe n˜ao pode utilizar a fun¸ao da API C para recuperar o valor para
LAST_INSERT_ID(expr) depois de executar outra instru¸ao SQL como SELECT
ou SET.
FORMAT(X,D)
Formata o n´umero Xcom um format como ’#,###,###.##’, arredondado para
Dcasas decimais. Se D´e 0, o resultado n˜ao ter´a nehum ponto decimal ou parte
fracion´aria:
mysql> SELECT FORMAT(12332.123456, 4);
-> ’12,332.1235’
mysql> SELECT FORMAT(12332.1,4);
-> ’12,332.1000’
mysql> SELECT FORMAT(12332.2,0);
-> ’12,332’
VERSION()
Retorna uma string indicando a vers˜ao do servidro MySQL:
mysql> SELECT VERSION();
-> ’3.23.13-log’
Note que se seu vers˜ao finalizar com -log, significa que o log est´a habilitado.
CONNECTION_ID()
Retorna a identifica¸ao (thread_id) desta conex˜ao. Cada conex˜ao tem seu
pr´oprio id ´unico:
mysql> SELECT CONNECTION_ID();
-> 1
GET_LOCK(str,temo_limite)
Tenta conseguir uma trava com o nome dado pela string str, com um tempo
limite de timeout segundos. Retorna 1se o bloqueio foi obtido com sucesso, 0
se o tempo esgotou ou NULL se uma erro ocorreu (tal como estouro de mem´oria
ou a threado tiver sido finalizada com mysqladmin kill). Uma trava ´e lib-
erada quando vocˆe executa RELEASE_LOCK(), executa uma nova GET_LOCK(),
ou a thread termina. Esta fun¸ao pode ser usada para implementar bloqueio
de aplica¸ao ou para simular registros travados. Ela bloqueia pedido de out-
ros clientes para travas com o mesmo nome; clientes que concordam com um
dado nome da trava podem usar a string para realizar travamento de consultas
cooperativos:
mysql> SELECT GET_LOCK("lock1",10);
438 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
-> 1
mysql> SELECT IS_FREE_LOCK("lock2");
-> 1
mysql> SELECT GET_LOCK("lock2",10);
-> 1
mysql> SELECT RELEASE_LOCK("lock2");
-> 1
mysql> SELECT RELEASE_LOCK("lock1");
-> NULL
Note que a segunda chamada de RELEASE_LOCK() retorna NULL porque a trava
"lock1" foi liberada automaticamente pela segunda. GET_LOCK() call.
RELEASE_LOCK(str)
Libera a trava nomeada pela string str que foi obtida com GET_LOCK(). Re-
torna 1se a trava foi liberada, 0se a trava n˜ao foi bloquada pela thread (caso
onde a trava n˜ao ´e liberada), e NULL se o nome da trava n˜ao existe. A trava
nunca exitir´a se ela nunca for obtida pela chamada de GET_LOCK() ou se ela ja
tiver sido liberada.
A instru¸ao DO ´e conveniente para ser utilizada com RELEASE_LOCK(). See
hundefinedi[DO], page hundefinedi.
IS_FREE_LOCK(str)
Verifica se a trava chamada str est´a livre para ser utilizada (ex. ao est´a
bloqueada). Retorna 1se a trava est´a liver (ningu´em a esta usando), 0se a
trava est´a em uso, e NULL caso ocorra erro (como argumentos incorretos).
BENCHMARK(cont,expr)
A fun¸ao BENCHMARK() executa a express˜ao expr repetidamente cont vezes. Ela
pode ser usada para medir a velocidade em que o MySQL processa a express˜ao.
O valor resultante ´e sempre 0. A inten¸ao ´e us´a-la no clientei mysql, relatando
o tempo de execu¸ao da consulta:
mysql> SELECT BENCHMARK(1000000,ENCODE("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE("hello","goodbye")) |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
1 row in set (4.74 sec)
O tempo relatado ´e o tempo decorrido no cliente, n˜ao o tempo de CPU no servi-
dor. Pode ser aconselh´avel executar BENCHMARK() diversas vezes e interpretar
o resultado cosiderado o peso da carga da maquina servidora.
INET_NTOA(expr)
Dado um endere¸co num´erico de rede (4 ou 8 bytes), retorna a representac˜ao no
formato com pontos do endere¸co como uma string:
mysql> SELECT INET_NTOA(3520061480);
-> "209.207.224.40"
Chapter 6: Referˆencia de Linguagem do MySQL 439
INET_ATON(expr)
Dada a represena¸ao com pontos de um endere¸co de rede como uma string,
retorna um inteiro que representa o valor num´erico deste endere¸co. Endere¸cos
podem ter 4 ou 8 bytes de endere¸camento:
mysql> SELECT INET_ATON("209.207.224.40");
-> 3520061480
O n´umero gerado ´e sempre na ordem de bytes da rede; por exemplo o n´umero
acima ´e calculado como 209*256^3 + 207*256^2 + 224*256 +40.
MASTER_POS_WAIT(nome_log, log_pos [, tempo_limite])
Envia blocos o escravo alcan¸car (ex.: ter lido e aplicado todas as atualiza¸oes) a
posi¸ao espec´
ifica no log mestre. Se a informa¸ao mestre n˜ao est´a inicializada,
ou se os argumentos est˜ao incorretos, retorna NULL. Se o escravo n˜ao est´a
em execu¸ao, enviar´a blocos e ir´a esperar at´e que ele seja iniciado e v´a para
(ou passe por) a posi¸ao especificada. Se o escravo j´a passou pela posi¸ao
especificada, retorna imediatamente.
Se tempo_limite (novo na vers˜ao 4.0.10) ´e especificado, ir´a esperar at´e que
tempo_limite segundos tenham se passado. tempo_limite deve ser maior que
0; zero ou um tempo_limite negativo significa sem tempo limite. O valor de
retorno ´e o n´umero de eventos de log que ele tem que esperar para obter a
posi¸ao especificada, NULL no caso de erro, ou -1 se o tempo limite tiver sido
excedido.
O comando ´e ´util para controle de sincroniza¸ao mo mestre-escravo.
FOUND_ROWS()
Retorna o n´umero de linhas qeu o comando SELECT SQL_CALC_FOUND_ROWS ...
anterior teria retornado, se ele n˜ao tiver sido restrigido com LIMIT.
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM nome_tabela
WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
O segundo SELECT ir´a retornar um n´umero indicando quantas linhas o primeiro
SELECT teria retornado se ele fosse escrito sem a cl´ausula LIMIT.
Note que se vocˆe estiver usando SELECT SQL_CALC_FOUND_ROWS ..., o MySQL
tem que calcular todos os registros no conjunto de resultados. No entanto, isto
´e mais r´apido que se vocˆe n˜ao utilizar LIMIT, j´a que o resultado precisa ser
enviado ao cliente.
O valor de FOUND_ROWS() o ´e relevante logo ap´os um comando SELECT SQL_
CALC_FOUND_ROWS.
SQL_CALC_FOUND_ROWS est´a dispon´
ivel a partir da vers˜ao 4.0.0 do MySQL.
6.3.7 Fun¸oes para Usar com Cl´ausulas GROUP BY
Se vocˆe utiliza um fun¸ao de agrupamento em uma instru¸ao que n˜ao contenha um cl´ausula
GROUP BY, equivale a fazer um agrupamento com todos os registros.
COUNT(expr)
Retorna a quantidade de valores n˜ao-NULL nos registros recuperados por uma
instrucao SELECT:
440 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT estudante.nome_estudente,COUNT(*)
-> FROM estudante,curso
-> WHERE estudante.id_estudante=curso.id_estudante
-> GROUP BY nome_estudante;
COUNT(*) ´e um pouco diferente de retornar o n´umero de registros recupera-
dos,quando eles possu´
irem valores NULL.
COUNT(*) ´e otimizado para retornar muito r´apido se SELECT recuoperar registros
de uma tabela, nenhuma outra coluna for retornada, e n˜ao houver nenhuma
cl´ausula WHERE. Por exemplo:
mysql> SELECT COUNT(*) FROM estudente;
COUNT(DISTINCT expr,[expr...])
Retorna a quantidade de regiastros com valores n˜ao-NULL diferentes:
mysql> SELECT COUNT(DISTINCT resultados) FROM estudente;
No MySQl vocˆe pode obter o n´umero de combina¸ao de express˜oes distintas
que n˜ao cont´em NULL fornecendo uma lista de express˜oes. No SQL-99 voe
teria que concatenar todas as express˜ao utilizando COUNT(DISTINCT ...).
AVG(expr)
Retorna o valor m´edio de expr:
mysql> SELECT nome_estudante, AVG(nota_teste)
-> FROM estudante
-> GROUP BY nome_estudante;
MIN(expr)
MAX(expr)
Retorna o valor m´
inimo o u m´aximo de expr.MIN() eMAX() poder usar uma
string como argumento; nestes casos eles retornam o a string de valor m´
inimo
ou m´aximo. See hundefinedi[´
Indices do MySQL], page hundefinedi.
mysql> SELECT nome_estudante, MIN(nota_teste), MAX(nota_teste)
-> FROM estudante
-> GROUP BY nome_estudante;
Em MIN(),MAX() e outras fun¸oes de agrupamento o MySQL, atualmente,
compara colunas ENUM eSET pelo seu valor string em vez de fazˆe-lo pela sua
posi¸ao relativa de string no conjunto. Isto ser´a retificado.
SUM(expr)
Retorna a soma de expr. Note que se o conjunto de retorno n˜ao possuir regitros
ele retornar´a NULL!
GROUP_CONCAT(expr)
Sintaxe completa:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC] [,col ...]]
[SEPARATOR valor_str])
Esta fun¸ao foi adicionada na vers˜ao 4.1 do MySQL. Ele retorna a string resul-
tante contendo valores de um grupo:
Chapter 6: Referˆencia de Linguagem do MySQL 441
mysql> SELECT nome_estudante,
-> GROUP_CONCAT(note_teste)
-> FROM estudante
-> GROUP BY nome_estudante;
ou
mysql> SELECT nome_estudante,
-> GROUP_CONCAT(DISTINCT nota_teste
-> ORDER BY nota_teste DESC SEPARATOR " ")
-> FROM estudante
-> GROUP BY nome_estudante;
No MySQL vocˆe pode obter valores de combina¸oes de express˜oes concatena-
dos. Voe pode eliminar valores duplicados utilizando DISTINCT. Se vocˆe quiser
ordenar valores no resultado vocˆe deve utilizar a cl´ausula ORDER BY. Para or-
denar inversamente, adicione a palavra chave DESC (descendente) ao nome da
coluna que vocˆe est´a ordenando na cl´ausula ORDER BY. O padr˜ao ´e a ordem cres-
cente; pode-se tamb´em especific´ala explicitamente usando a palavra chave ASC.
SEPARATOR ´e o valor string que deve ser inserido entre os valores no resultado.
O padr˜ao ´e um virgula (‘","’). Voe pode remover o separador especificando
SEPARATOR "".
Voe pode definir um tamanho m´aximo permitido com a vari´avel group_
concat_max_len em sua configura¸ao. A sintaxe para se fazer isto em tempo
de execu¸ao ´e:
SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
Se um tamanho m´aximo tiver sido atribuido, o resultado ´e truncado no seu
tamanho m´aximo.
A fun¸ao GROUP_CONCAT() ´e uma implementa¸ao aprimorada da fun¸ao b´asica
LIST() suportada pelo Sybase SQL Anywhere. GROUP_CONCAT() ´e compat´
ivel
com a funcionalidade extrwemamente limitada de de LIST(), se utilizada em
apenas uma coluna e nenhuma outra op¸ao ´e especificada. LIST() ao tem
uma ordem de classifica¸ao padr˜ao.
VARIANCE(expr)
Retorna a variˆancia padr˜ao de expr. Esta ´e uma extens˜ap do SQL-99
(dispon´
ivel somente a partir da vers˜ao 4.1).
STD(expr)
STDDEV(expr)
Retorna o desvio padr˜ao de expr. Esta ´e uma extens˜ao do SQL-99. O formato
STDDEV() desta fun¸ao ´e fornecida para compatibilidade com Oracle.
BIT_OR(expr)
Retorna o resultado da opera¸ao bin´aria OR de todos os bits em expr. O cal-
cululo ´e relizado com precis˜ao de 64 bits (BIGINT).
A fun¸ao retortna 0 se n˜ao houver registros coincidentes.
BIT_AND(expr)
Retorna o resultado da opera¸ao bin´aria AND de todos os bits em expr. O
calcululo ´e relizado com precis˜ao de 64 bits (BIGINT).
A fun¸ao retortna 1 se n˜ao houver registros coincidentes.
442 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
O MySQL tem extendido o uso de GROUP BY. Voe pode utilizar colunas ou c´alculos na
express˜ao SELECT que n˜ao aparecem na parte GROUP BY. Ele espera por qalquer valor poss´
ivel
para este grupo. Voe pode utilizar isto para conseguir um melhor desempenho evitando
ordena¸ao e agrupamento em itens desnecess´arios. Por exemplo, vocˆe n˜ao precisa fazer um
agrupamento em cliente.nome na consulta seguinte:
mysql> SELECT pedido.idcliente,cliente.nome,MAX(pagamento)
-> FROM pedido, cliente
-> WHERE pedido.idcliente = cliente.idcliente
-> GROUP BY pedido.idcliente;
No padr˜ao SQL, vocˆe teria que adicionar cliente.nome a cl´ausula GROUP BY. No MySQL,
o nomˆe ´e redundante se vocˆe n˜ao o executa em modo ANSI.
ao utilize este recurso se as colunas omitidas na parte GROUP BY ao s˜ao ´unicas no grupo!
Voe obter´a resultados inexperados.
Em alguns casos, vocˆe pode utilizar MIN eMAX para obter o valor de uma coluna espec´
ifica,
mesmo que ele n˜ao seja ´unico. O exemplo seguinte fornece o valor de coluna do registro
contendo o menor valor na coluna ordem:
SUBSTR(MIN(CONCAT(RPAD(ordem,6,’ ’),coluna)),7)
See Maximum-column-group-row-snt [example-Maximum-column-group-row],
page Maximum-column-group-row-pg.
NOte que se vocˆe estiver usando a vers˜ao 3.22 do MySQL (ou anterior) ou se estiver tentando
seguir o SQL-99, vocˆe n˜ao pode utilizar express˜oes nas cl´ausulas GROUP BY or ORDER BY. Vocˆe
pode contornar esta limita¸ao utilizando um alias para a express˜ao:
mysql> SELECT id,FLOOR(value/100) AS val FROM nome_tabela
-> GROUP BY id,val ORDER BY val;
Na vers˜ao 3.23 do MySQL vocˆe pode fazer:
mysql> SELECT id,FLOOR(value/100) FROM nome_tabela ORDER BY RAND();
6.4 Manipula¸ao de Dados: SELECT,INSERT,UPDATE,DELETE
6.4.1 Sintaxe SELECT
SELECT [STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
express~ao_select,...
[INTO {OUTFILE | DUMPFILE} ’nome_arquivo’ op¸c~oes_exporta¸c~ao]
[FROM tabelas_ref
[WHERE defini¸c~ao_where]
[GROUP BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC], ...]
[HAVING where_definition]
[ORDER BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC], ...]
[LIMIT [offset,] linhas | linhas OFFSET offset]
[PROCEDURE nome_procedimento(lista_argumentos)]
[FOR UPDATE | LOCK IN SHARE MODE]]
Chapter 6: Referˆencia de Linguagem do MySQL 443
SELECT ´e utilizado para retornar registros selecionados de uma ou mais tabelas. express~ao_
select indica as colunas que vocˆe deseja recuperar. SELECT tanb´em pode ser utilizado para
retornar registros calculados sem referˆencia a nenhuma tabela. Por exemplo:
mysql> SELECT 1 + 1;
-> 2
Todas as palavras chaves devem ser fornecidas exatamente na ordem mostrada acima. Por
exemplo, uma cl´ausula HAVING deve vir depois de qualquer cl´ausula GROUP BY e antes de
qualquer cl´ausula ORDER BY.
Uma express˜ao SELECT pode utilizar um alias usando AS. O alias ´e usaado como o
nome da coluna da express˜ao e pode ser usado com cl´ausulas ORDER BY ou HAVING. Por
exemplo:
mysql> SELECT CONCAT(primeiro_nome,’ ’,ultimo_nome) AS nome_completo
FROM minha_tabela ORDER BY nome_completo;
ao ´e permitido utilizar um alias de coluna em uma cl´ausula WHERE, pois o valor da
coluna pode ainda n˜ao ter sido determinado quando a cl´ausula WHERE for executada.
See hundefinedi[Problemas com alias], page hundefinedi.
A cl´ausula FROM table_references indica a tabela de onde os registros ser˜ao retor-
nados. Se vocˆe indicar mais de uma tabela, vocˆe estar´a realizando uma join. Para
informa¸oes sobre a sintaxe de join, veja hundefinedi[JOIN], page hundefinedi. Para
cada tabela especificada, vocˆe pode, opcionalmente, especificar um alias.
nome_tabela [[AS] alias] [[USE INDEX (lista_indice)] | [IGNORE INDEX (lista_
indice)] | FORCE INDEX (lista_indice)]]
Como na vers˜ao 3.23.12 do MySQL, vocˆe pode dar sugest˜oes sobre qual ´
indice o MySQL
deve usar ao recuperar informa¸oes de uma tabela. Isto ´e ´util se EXPLAIN mostrar que o
MySQL esta utilizando o ´
indice errado da lista de ´
indices poss´
iveis. Especificando USE
INDEX (lista_indice) vocˆe pode dizer ao MySQL para usar somente um dos ´
indices
poss´
iveis para encontrar registros em uma tabela. A sintaxe alternativa IGNORE INDEX
(lista_indice) pode ser usada para dizer ao MySQL para n˜ao utilizar alguns ´
indices
particulares.
Na vers˜ao 4.0.9 do MySQL vocˆe tamb´em pode usar FORCE INDEX. Ele funciona como
USE INDEX (lista_indice) mas ele assume que uma varredura em uma tabelas ´e
MUITO cara. Em outras palavras, uma varredura s´o ser´a usada se n˜ao houver nenhum
modo de utilizar um dos ´
indices dados para encontrar registros nas tabelas.
USE/IGNORE/FORCE KEY ´e sinˆonimo de USE/IGNORE/FORCE INDEX.
Voe pode se referir a uma tabela como nome_tabela (dentro do banco de dados
atual) ou como nomebd.nome_tabela para especificar um banco de dados. Voe
pode se referir a um coluna como nome_coluna,nome_tabela.nome_coluna ou
nomebd.nome_tabela.nome_coluna. Voe n˜ao precisa especificar um prefixo
nome_tabla ou nomebd.nome_tabela para referˆencia a uma coluna em uma
instru¸ao SELECT a menos a referˆencia seja amb´
igua. Veja hundefinedi[Legal names],
page hundefinedi, para exemplos de ambiguidade que exigem a forma mais explicita
de referˆencia a coluna.
Pode se definir um alias fazendo referˆencia a uma tabela utilizando nome_tabela [AS]
nome_alias:
444 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT t1.nome, t2.salario FROM funcionarios AS t1, info AS t2
-> WHERE t1.nome = t2.nome;
mysql> SELECT t1.nome, t2.salario FROM funcionarios t1, info t2
-> WHERE t1.nome = t2.nome;
Colunas selecionadas para sa´
ida podem ser referidas em cl´ausulas ORCER BY eGROUP
BY usando nomes de colunas, alias de colunas ou posi¸oes de colunas. As posi¸oes de
colunas come¸cam com 1:
mysql> SELECT college, region, seed FROM tournament
-> ORDER BY region, seed;
mysql> SELECT college, region AS r, seed AS s FROM tournament
-> ORDER BY r, s;
mysql> SELECT college, region, seed FROM tournament
-> ORDER BY 2, 3;
Para ordenar inversamente, adicione a palavra-chave DESC (descendente) ao nome da
coluna na cl´ausula ORDER BY na qual vocˆe est´a ordenando. A ordem padr˜ao ´e ascedente;
ela pode ser especificada explicitamente usando a palavra-chave ASC.
Voe pode usar qualquer uma das fun¸oes suportadas pelo MySQL na cl´ausula WHERE.
See hundefinedi[Fun¸oes], page hundefinedi.
A cl´ausula HAVING pode se referir a qualquer coluna ou alias definido na express~ao_
select. Ele ´e aplicado por ultimo, pouco antes dos itens serem enviados ao cliente,
sem otimiza¸ao. ao utilie HAVING para itens que devem estar na cl´ausula WHERE. Por
exemplo, n˜ao escreva isto:
mysql> SELECT nome_col FROM nome_tabela HAVING nome_col > 0;
Escreva assim:
mysql> SELECT nome_col FROM nome_tabela WHERE nome_col > 0;
Na vers˜ao 3.22.5 ou posterior, vocˆe tamb´em pode escrever consultar desta forma:
mysql> SELECT usuario,MAX(salario) FROM usuarios
-> GROUP BY usuario HAVING MAX(salario)>10;
Em vers˜oes mais antigas, vocˆe pode escrever desta forma:
mysql> SELECT usuario,MAX(salario) AS soma FROM usuarios
-> group by usuario HAVING soma>10;
As op¸oes DISTINCT,DISTINCTROW eALL especificam quando registros duplicados de-
vem ser retornados. O padr˜ao ´e (ALL), todos os registros coincidentes s˜ao retornaodos.
DISTINCT eDISTINCTROW ao sinˆonimos e espcificam que registros duplicados no con-
junto de resultados devem ser remopvidos.
Todas as op¸oes iniciando com SQL_,STRAIGHT_JOIN, e HIGH_PRIORITY ao extens˜oes
do MySQL para SQL-99.
HIGH_PRIORITY dar´a uma prioridade maior ao SELECT do que para uma instru¸ao que
atualizam uma tabela. Vocˆe s´o deve isto para consultas que sejam r´apidas e devam ser
feitas imediatamente. Uma consulta SELECT HIGH_PRIORITY retornar´a se a tabela est´a
bloqueada para leitura memsmo se houver uma instru¸ao de atualiza¸ao que estiver
esperando a libera¸ao da tabela.
SQL_BIG_RESULT pode ser usado com GROUP BY ou DISTINCT para dizer ao otimizador
que o conjunto de resultados ter´a muitas linhas. Neste caso, o MySQL usar´a direta-
mente tabelas temporarias em disco se necess´ario. O MySQL tamb´em ir´a, neste caso,
Chapter 6: Referˆencia de Linguagem do MySQL 445
preferir ordenar fazendo uma tabela tempor´aria com um cahve nos elementos GROUP
BY.
SQL_BUFFER_RESULT for¸car´a que o resultado seja colocado em uma tabela tempor´aria.
Isto ajudar´a o MySQL a liberar as travas de tabelas mais cedo e ajudar´a nos casos
onde ele lev´a muito tempo para enviar o conjunto de resultado ao cliente.
SQL_SMALL_RESULT, uma op¸ao especifica do MySQL, pode ser usada com GROUP BY ou
DISTINCT para dizer ao otimizador que o conjunto de resultados ser´a pequeno. Neste
caso, o MySQL usar´a tabelas tempor´arias r´apidas para armazenar a tabela resultante
em vez de usar ordena¸ao. Na vers˜ao 3.23 do MySQL isto n˜ao ´e necess´ario normalmente.
SQL_CALC_FOUND_ROWS (vers˜ao 4.0.0 e acima) diz ao MySQL para calcular quantas
linhas haveriam nop conjunto de resultados, desconsiderando qualquer cl´ausula LIMIT.
O n´umero de linhas pode ser recuperado com SELECT FOUND_ROWS(). See hundefinedi
[Fun¸oes diversas], page hundefinedi.
Por favor, note que em nvers˜oes anteriores a 4.1.0 isto n˜ao funciona com LIMIT 0,
o qual ´e otimizado para retornar instantaneamente (resultando em 0 registros). See
hundefinedi[Otimiza¸ao LIMIT], page hundefinedi.
SQL_CACHE diz ao MySQL para armazenar o resultado da consulta em um cache de
consultas se vocˆe estiver utilizando QUERY_CACHE_TYPE=2 (DEMAND). See hundefinedi
[Cache de consultas], page hundefinedi.
SQL_NO_CACHE diz ao MySQL para n˜ao permitir que o resulado da consulta deja asr-
mazenado nesta cahe de consultas. See hundefinedi[Cache de consultas], page hunde-
finedi.
Se vocˆe utiliza GROUP BY, os registros de sa´
ida ser˜ao ordenados de acordo com o GROUP
BY como se vocˆe tivesse tido um ORDER BY sobre todos os campos no GROUP BY. O
MySQL tem estendido o GROUP BY para que vocˆe tamb´em possa especificar ASC eDESC
ao GROUP BY:
SELECT a,COUNT(b) FROM tabela_teste GROUP BY a DESC
O MySQL tem extendido o uso do GROUP BY para lhe permitir selecionar campos que n˜ao
est˜ao mencionados na cl´ausula GROUP BY. Se vocˆe n˜ao est´a conseguindo os resultados
esperados ara a sua consulta, leia a descri¸ao de GROUP BY. See hundefinedi[Fun¸oes
Group By], page hundefinedi.
STRAIGHT_JOIN for¸ca o otimizador a unir as tabelas en ordem em que elas s˜ao listads
na cl´ausula FROM. Vocˆe pode us´a-lo para aumentar a velocidade de uma consultase o
otimizador de unir as tabelas em uma ordem n˜ao otimizada. See hundefinedi[EXPLAIN],
page hundefinedi.
A cl´ausula LIMIT pode ser usada para restringir o n´umero de linhas retornadas pela
instru¸ao SELECT.LIMIT utiliza um ou dois agumebntos num´ericos. Os argumentos
devem ser constants inteiras.
Se forem fornecidos dois argumentos, o primeiro especifica a posi¸ao do primeiro registro
a ser retornado e o segundo especifica o n´umero m´aximo de linhas a retornar. A posi¸ao
do registro inicial ´e 0 (n˜ao 1):
Para ser compat´
ivel com o PostgreeSQL, o MySQL suporta a sintaxe: LIMIT # OFFSET
#.
mysql> SELECT * FROM tabela LIMIT 5,10; # Recupera linhas 6-15
446 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
To retrieve all rows from a certain offset up to the end of the result set, you can use -1
for the second parameter:
mysql> SELECT * FROM tabela LIMIT 95,-1; # Recupera linhas 96-ultima.
Se um dos argumentos ´e dado, ele indica o n´umero m´aximo de linhas a retornar:
mysql> SELECT * FROM tabela LIMIT 5; # Recupera as primeiras 5 linhas
Em outras palavras, LIMIT n ´e equivalente a LIMIT 0,n.
iA forma SELECT ... INTO OUTFILE ’nome_arquivo’ do SELECT grava os registros se-
lecionados em um arquivo. O arquivo ´e criado na m´aquina servidora e n˜ao pode j´a
existir (entre outras coisas, isto previne tabelas de banco de dados e arquivos tais
como ‘/etc/passwd’ de serem destru´
idos). Vocˆe deve ter o privil´egio FILE na m´aquina
servidora para utilizar esta forma de SELECT.
SELECT ... INTO OUTFILE tem como inten¸ao principal deixar que vocˆe descarregue
rapidamente um tabela de uma m´aquina servidora. Se vocˆe quiser criar o arquivo
resultante em outra m´aquina, diferente do servidor, vocˆe n˜ao deve usar SELECT ...
INTO OUTFILE. Neste caso vocˆe deve usar algum programa cliente como mysqldump
--tab ou mysql -e "SELECT..." > outfile para gerar o arquivo.
SELECT ... INTO OUTFILE ´e o complemento de LOAD DATA INFILE; a sintaxe para a
parte op¸c~oes_exporta¸c~ao de uma instru¸ao consiste das mesmas cl´ausulas CAMPOS
eLINHAS que s˜ao usadas com a instru¸ao LOAD DATA INFILE. See hundefinedi[LOAD
DATA], page hundefinedi.
No arquivo texto resultante, somente os seguintes coracteres s˜ao escritos com o caracter
ESCAPE BY:
O caracter ESCAPE BY
O primeiro caracter em FIELDS TERMINATED BY
O primeiro caracter em LINES TERMINATED BY
Adicionalmente, ASCII 0 ´e convertido para ESCAPE BY seguido por 0 (ASCII 48).
A raz˜ao para o mostrado acima ´e que vocˆe deve escapar qualquer caracter FIELDS
TERMINATED BY,ESCAPE BY, or LINES TERMINATED BY para termos a seguran¸ca que o
arquivo poder´a ser lido de volta. ´
E feito escape de ASCII 0 para facilitar a visuzliza¸ao
com alguns paginadores.
Como o arquivo resultante n˜ao tem que estar em conformidade com a sintaxe SQL,
nada mais precisa ser seguido de caraceres de escape.
Aqui segue um exemplo de como se obter um arquivo no formato usado por muitos
programas antigos.
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text"
FIELDS TERMINATED BY ’,’ OPTIONALLY ENCLOSED BY ’"’
LINES TERMINATED BY "\n"
FROM tabela_teste;
Se vocˆe utilizar INTO DUMPFILE em vez de INTO OUTFILE, o MySQL s´o ir´a escrever um
linha no arquivo, sem nenhum terminador de linha ou colunas e sem nenhum escape.
Ele ´e ´util se vocˆe quiser armazenar um blob em um arquivo.
Note que qualuqer arquivo criado por INTO OUTFILE eINTO DUMPFILE poder˜ao ser
escritos por todos os usu´arios! A raz˜ao ´e que o servidor MySQL n˜ao pode criar um
Chapter 6: Referˆencia de Linguagem do MySQL 447
arquivo que pertence a qualquer um al´em do usu´ario que o est´a executando (vocˆe nunca
deve executar mysqld como root) o arquivo tem que ser graavel para todos para que
vocˆe possa manipul´a-lo.
Se vocˆe estiver utilizando FOR UPDATE em um mecanismo de armazenamento com trava-
mento de p´aginas/registros, as linas examinadas ser˜ao travadas para escrita.
6.4.1.1 Sintaxe JOIN
O MySQL suporta as seguintes sintaxes JOIN para uso em instru¸oes SELECT:
tabela_ref, tabela_ref
tabela_ref [CROSS] JOIN tabela_ref
tabela_ref INNER JOIN tabela_ref condi¸c~ao_join
tabela_ref STRAIGHT_JOIN tabela_ref
tabela_ref LEFT [OUTER] JOIN tabela_ref condi¸c~ao_join
tabela_ref LEFT [OUTER] JOIN tabela_ref
tabela_ref NATURAL [LEFT [OUTER]] JOIN tabela_ref
{ OJ tabela_ref LEFT OUTER JOIN tabela_ref ON expr_condicional }
tabela_ref RIGHT [OUTER] JOIN tabela_ref condi¸c~ao_join
tabela_ref RIGHT [OUTER] JOIN tabela_ref
tabela_ref NATURAL [RIGHT [OUTER]] JOIN tabela_ref
Onde tabela_ref ´e definido como:
nome_tabela [[AS] alias] [[USE INDEX (lista_indice)] | [IGNORE INDEX (lista_
indice)] | [FORCE INDEX (lista_indice)]]
acondi¸c~ao_join ´e definido como:
ON expr_condicional |
USING (lista_colunas)
Geralamente vocˆe n˜ao dever´a ter nenhuma condi¸ao na parte ON que ´e usada para restringir
quais registros vocˆe ter´a no seu resultado (existem excess˜oes a esta regra). Se quiser re-
stringir quais registros devem estar no resultado, vocˆe ter´a que fazˆe-lo na cl´ausula WHERE.
Note que em vers˜oes anteriores a 3.23.17, o INNER JOIN ao utilizava uma condi¸c~ao_join!
A ´ultima sintaxe LEFT OUTER JOIN mostrada acima s´o existe para compatibilidade com
ODBC:
Pode se usar um alias para referˆencia a tabelas com nome_tabela AS nome_alias ou
nome_tabela nome_alias:
mysql> SELECT t1.nome, t2.salario FROM funcionarios AS t1, info AS t2
-> WHERE t1.nome = t2.nome;
A condicional ON ´e qualquer condi¸ao da forma que pode ser usada em uma cl´ausula
WHERE.
Se n˜ao houver registros coincidentes para a tabela a direita da parte ON ou USING em
um LEFT JOIN, uma linha com NULL atribu´
ido a todas as colunas ´e usada para a tabela
a direita. Vocˆe pode usar este fato para encontrar registro em uma tabela que n˜ao
houver contrapartes em outra tabela
mysql> SELECT tabela1.* FROM tabela1
-> LEFT JOIN tabela2 ON tabela1.id=tabela2.id
-> WHERE tabela2.id IS NULL;
448 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Este exemplo encontra todas as linhas em tabela1 com um valor id que n˜ao est´a
presente em tabela2 (isto ´e, toda as linhas em tabela1 sem linha correspondente
em tabela2). Assume-se que tabela2.id ´e declarada NOT NULL. See hundefinedi
[Otimiza¸ao LEFT JOIN], page hundefinedi.
A cl´ausula USING (lista_colunas) nomeia uma lista de colunas que devem existir en
ambas as tabelas. Uma cl´ausula USING como:
A LEFT JOIN B USING (C1,C2,C3,...)
´e definida para ser semanticamente identica a uma exprss˜ao ON como esta:
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
Um NATURAL [LEFT] JOIN de duas tabelas ´e definido para ser semanticamente equiva-
lente a um INNER JOIN ou um LEFT JOIN com uma cl´ausula USING que nomeia todas
as colunas que exitem em ambas as tabelas.
INNER JOIN e,(v´
irgula) s˜ao semanticamente equivalentes. Ambos fazem um join
completo entre as tabelas usadas. Normalmente voe especifica como as tabelas devem
ser ligadas em uma condi¸ao WHERE.
RIGHT JOIN funciona de forma an´aloga a um LEFT JOIN. Para manter o c´odigo port´avel
entre banco de dados, ´e recomendado usar LEFT JOIN em vez de RIGHT JOIN.
STRAIGHT_JOIN ´e identico a JOIN, exceto pelo fato de que a tabela de esquerda sempre
´e lida antes da tabela da direita. Ele pode ser usado para aqueles casos (poucos) onde
o otimizador join coloca as tabelas na ordem errada.
Como na vers˜ao 3.23.12, vocˆe pode dar sugest˜oes sobre qual ´
indice o MySQL deve
us quando retornar informa¸oes de uma tabela. Isto ´e ´util se EXPLAIN mostar que
o MySQL est´a utilizando o ´
indice errado da lista de ´
indices poss´
iveis. Especificando
USE INDEX (lista_indice), vocˆe pode dizer ao MySQL para usar somente um dos
´
indices poss´
iveis para encontrar registros em uma tabela. A sintaxe alternativa IGNORE
INDEX (lista_indice) pode ser usado para dizer ao MySQL para n˜ao utilizar ´
indices
particulares.
Na vers˜ao 4.0.9 do MySQL vocˆe tamb´em pode utilizar FORCE INDEX. Ele funciona
como USE INDEX (key_list) mas com assume que uma varredura na tabela ´e MUITO
cara. Em outras palavras, uma varredura na tabela s´o sea feita se n˜ao houver modo
de uitlizar um dos ´
indices fornecidos para se enecontrar registros no tabela.
USE/IGNORE KEY ao sinˆonimos de USE/IGNORE INDEX.
Alguns exemplos:
mysql> SELECT * FROM tabela1,tabela2 WHERE tabela1.id=tabela2.id;
mysql> SELECT * FROM tabela1 LEFT JOIN tabela2 ON tabela1.id=tabela2.id;
mysql> SELECT * FROM tabela1 LEFT JOIN tabela2 USING (id);
mysql> SELECT * FROM tabela1 LEFT JOIN tabela2 ON tabela1.id=tabela2.id
-> LEFT JOIN tabela3 ON tabela2.id=tabela3.id;
mysql> SELECT * FROM tabela1 USE INDEX (chave1,chave2)
-> WHERE chave1=1 AND chave2=2 AND chave3=3;
mysql> SELECT * FROM tabela1 IGNORE INDEX (chave3)
-> WHERE chave1=1 AND chave2=2 AND chave3=3;
See hundefinedi[Otimiza¸ao LEFT JOIN], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 449
6.4.1.2 Sintaxe UNION
SELECT ...
UNION [ALL]
SELECT ...
[UNION
SELECT ...]
UNION foi implementado no MySQL 4.0.0.
UNION ´e usado para combinar o resultado de muitas instru¸oes SELECT em um ´unico conjunto
de resultados.
As colunas listadas na por¸ao express˜ao select de SELECT devem ter o mesmo tipo. Os nomes
das colunas usadas na primeira consulta SELECT ser˜ao usadas como nomes de colunas para
o resultado retornado.
Os comandos SELECT ao comandos selects normais, mas com a seguinte restri¸ao:
Somente o ´ultimo comando SELECT pode ter INTO OUTFILE.
Se vocˆe n˜ao utilzar a palavra-chave ALL para o UNION, todas as linhas retornadas ser˜ao
´unicas, como se vocˆe tivesse utilizado um DISTINCT para o resultado final. Se vocˆe especificar
ALL, vocˆe obter´a todos os regitros encontrados em todas as instru¸oes SELECT.
Se vocˆe quiser usar um ORDER BY para o resultado UNION final, vocˆe deve utilizar parenteses:
(SELECT a FROM nome_tabela WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM nome_tabela WHERE a=11 AND B=2 ORDER BY a LIMIT 10)
ORDER BY a;
6.4.2 Sintaxe HANDLER
HANDLER nome_tabela OPEN [ AS alias ]
HANDLER nome_tabela READ nome_indice { = | >= | <= | < } (valor1,valor2,...)
[ WHERE ... ] [LIMIT ... ]
HANDLER nome_tabela READ nome_indice { FIRST | NEXT | PREV | LAST }
[ WHERE ... ] [LIMIT ... ]
HANDLER nome_tabela READ { FIRST | NEXT }
[ WHERE ... ] [LIMIT ... ]
HANDLER nome_tabela CLOSE
A instru¸ao HANDLER fornece acesso direto a interface do mecanismo de armazenamento de
tabelas MyISAM.
A primeira forma da instru¸ao HANDLER abre uma tabela, tornando a acess´
ivel atrav´es de
subsequentes instru¸oes HANDLER ... READ. Este objeto de tabela n˜ao ´e copartilhada com
outras threads e n˜ao ser˜ao fechadas at´e que as chamadas de thread HANDLER nome_tabela
CLOSE ou a thread termine.
A segunda forma busca um registro (ou mais, especificado pela cl´ausula LIMIT) onde o
´
indice especificado ´e utilizado na condi¸ao e a condi¸ao WHERE ´e encontrada. Se o ´
indice
consiste de v´arias partes (se divide em v´aria colunas) os valores s˜ao especificados em uma
lista separadas por v´
irgulas, fornecendo valores somente para algumas poucas primeiras
colunas poss´
iveis.
450 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A terceira forma busca uma linha (ou mais, especificado pela cl´ausula LIMIT) da tabela na
ordem do ´
indice, correspondendo a condi¸ao WHERE.
A quarta forma (sem especifica¸ao de ´
indice) busca um registro (ou mais, especificado pela
cl´ausula LIMIT) da tabela na ordem natural da linhas (como armazenado no arquivo de
dados) de acordo com a condi¸ao WHERE ´e mais r´apido que HANDLER nome_tabela READ
nome_indice quando ´e necess´aria uma varredura completa da tabela.
HANDLER ... CLOSE fecha uma tabela que foi aberta com HANDLER ... OPEN.
Nota: Se vocˆe estiver utilizando a interface HANDLER para PRIMARY KEY vocˆe deve se lembrar
de colocar o nome entre aspas: HANDLER tbl READ ‘PRIMARY‘ > (...)
HANDLER ´e uma instru¸ao de baixo n´
ivel. Por exemplo, ela n˜ao fornece consitˆencia. Isto ´e,
HANDLER ... OPEN N˜
AO pega uma imagem instˆantanea da tabela, e N˜
AO trava a tabela.
Isto significa que depois que um HANDLER ... OPEN ´e feito, os dados da tabela podem
ser modificados (por esta ou outra thread) e estas modifica¸oes podem aparecer apenas
parcialmente nas buscas HANDLER ... NEXT ou HANDLER ... PREV.
As raz˜oes para se utilizar esta interface em vez do SQL normal s˜ao:
Ela ´e mais r´apida que SELECT porque:
Um mecanismo de armazenamento designado ´e alocado pela thread em HANDLER
OPEN.
Existe menos an´alise envolvida.
N`ao existe sobrecaga de otimiza¸ao e verifica¸ao de consultas.
A tabela utilizada n˜ao precisa estar travada em pedidos de dois handlers.
A interface handler n˜ao precisa fornecer uma aprˆencia consistente dos dados (por
exemplo, dirty-reads s˜ao permitidas), assim o mecanismo de armazenamento pode
fazer otimiza¸oes que o SQL normalmente n˜ao permite.
´
E muito mais f´acil portar aplica¸oes que usam interface como ISAM para o MySQL.
Ele permite se fazer uma travessia em um banco de dados de uma maneira que n˜ao ´e
facil (em alguns casos imposs´
ivel) de fazer com SQL. A interface handler ´e um modo
mais natural de mostrar dados ao trabalhar com aplica¸oes que fornecem uma interface
interativa com o usu´ario para o banco de dados.
6.4.3 Sintaxe INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] nome_tabela [(nome_coluna,...)]
VALUES ((express~ao | DEFAULT),...),(...),...
[ ON DUPLICATE KEY UPDATE nome_coluna=express~ao, ... ]
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] nome_tabela [(nome_coluna,...)]
SELECT ...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] nome_tabela
SET nome_coluna=(express~ao | DEFAULT), ...
[ ON DUPLICATE KEY UPDATE nome_coluna=express~ao, ... ]
Chapter 6: Referˆencia de Linguagem do MySQL 451
INSERT insere novos registros em uma tabela existente. A forma INSERT ... VALUES da
instru¸ao insere registros baseado em valores especificados explicitamente. A forma INSERT
... SELECT insere linhas selecionadas de outra(s) tabela(s). A forma INSERT ... VALUES
com listas de m´ultiplos valores ´e suportado a partir da vers˜ao 3.22.5. A sintaxe nome_
coluna=express~ao ´e suportada a partir da ver˜ao 3.22.10 do MySQL.
nome_tabela ´e a tabela na qual as linhas ser˜ao inseridas. A lista de nome das colunas ou
a cl´ausula SET indica para quais colunas a instru¸ao especifica valor:
Se vocˆe n˜ao especificar a lista de colunas para INSERT ... VALUES ou INSERT ...
SELECT, dever˜ao ser fornecidos valores para todas as colunas na lista VALUES() ou pelo
SELECT. Se vocˆe n˜ao souber a ordem das colunas nas tabelas, use DESCRIBE nome_
tabela para descobrir.
Qualquer coluna que n˜ao tiver o valor fornecido explicitamente assumir´a o seu valor
padr˜ao. Por exemplo, se vocˆe especificar uma lista de colunas que n˜ao definem todas
as coolunas na tabela, `as colunas n˜ao definidas ser˜ao atribu´
idos o seu valor padr˜ao.
Atribui¸ao de valor padr˜ao ´e definido em hundefinedi[CREATE TABLE], page hundefinedi.
Voe tamb´em pode utilizar a palavra-chave DEFAULT para atribuir o valor padr˜ao a uma
coluna (Novo na vers˜ao 4.0.3. do MySQL). Fica mais f´acil de se escrever instru¸oes
INSERT que atribuem valor a apenas algumas colunas porque ele permite que vocˆe evite
escrever uma lista VALUES() incompleta (uma lista que n˜ao inclu um valor para cada
coluna da tabela). De outa forma, vocˆe teria que escrever a lista de nomes de colunas
correspondentes a cada valor na lista VALUES().
MySQL sempre tem uma valor padr˜ao para todos os campos. Isto ´e algo imposto pelo
MySQL para estar apto a funcionar com tabelas transacionais e n˜ao transcaionais.
Nossa vis˜ao ´e que a verifica¸ao do conte´udo dos campos deve ser feita pela application
and not in the database server.
Uma express~ao pode se referir a qualquer coluna que tenha sida definaida anterior-
mente na lista de valores. Por exemplo, voe pode dizer:
mysql> INSERT INTO nome_tabela (col1,col2) VALUES(15,col1*2);
Mas n˜ao:
mysql> INSERT INTO nome_tabela (col1,col2) VALUES(col2*2,15);
Se vocˆe especificar a palavra-chave LOW_PRIORITY, a execu¸ao do INSERT ´e atrasada at´e
que nenhum outro cliente esteja lendo a tabela. Neste caso o cliente tem que esperar
at´e que a instru¸ao insert esteja completa, a qual pode levar bastante tempo se a tabela
estiver em uso constante. ´
E diferente de INSERT DELAYED, que deixa o cliente continuar
de uma vez. See hundefinedi[INSERT DELAYED], page hundefinedi. Note que LOW_
PRIORITY ao deve normalmente ser usado com tabelas MyISAM ja que elas disabilitam
inser¸oes concorrentes. See hundefinedi[MyISAM], page hundefinedi.
If you specify the keyword IGNORE in an INSERT with many value rows, any rows
that duplicate an existing PRIMARY or UNIQUE key in the table are ignored and are
not inserted. If you do not specify IGNORE, the insert is aborted if there is any row
that duplicates an existing key value. You can determine with the C API function
mysql_info() how many rows were inserted into the table.
If you specify ON DUPLICATE KEY UPDATE clause (new in MySQL 4.1.0), and a row is
inserted that would cause a duplicate value in a PRIMARY or UNIQUE key, an UPDATE of
the old row is performed. For example, the command:
452 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
--> ON DUPLICATE KEY UPDATE c=c+1;
in case of column ais declared as UNIQUE and already holds 1once, would be identical
to the
mysql> UPDATE table SET c=c+1 WHERE a=1;
Note: that if column bis unique too, the UPDATE command would be written as
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
and if a=1 OR b=2 matches several rows, only one row will be updated! In general,
one should try to avoid using ON DUPLICATE KEY clause on tables with multiple UNIQUE
keys.
Since MySQL 4.1.1 one can use function VALUES(nome_coluna) to refer to the col-
umn value in the INSERT part of the INSERT ... UPDATE command - that is the value
that would be inserted if there would be no duplicate key conflict. This function espe-
cially useful in multiple-row inserts. Naturally VALUES() function is only meaningful
in INSERT ... UPDATE command and returns NULL otherwise.
Example:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
--> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
The command above is identical to
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
--> ON DUPLICATE KEY UPDATE c=3;
mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)
--> ON DUPLICATE KEY UPDATE c=9;
When one uses ON DUPLICATE KEY UPDATE, the DELAYED option is ignored.
If MySQL was configured using the DONT_USE_DEFAULT_FIELDS option, INSERT state-
ments generate an error unless you explicitly specify values for all columns that require
a non-NULL value. See hundefinedi[configure options], page hundefinedi.
You can find the value used for an AUTO_INCREMENT column with the mysql_insert_id
function. See hundefinedi[mysql_insert_id()], page hundefinedi.
If you use INSERT ... SELECT or an INSERT ... VALUES statement with multiple value lists,
you can use the C API function mysql_info() to get information about the query. The
format of the information string is shown here:
Records: 100 Duplicates: 0 Warnings: 0
Duplicates indicates the number of rows that couldn’t be inserted because they would
duplicate some existing unique index value. Warnings indicates the number of attempts to
insert column values that were problematic in some way. Warnings can occur under any of
the following conditions:
Inserting NULL into a column that has been declared NOT NULL. The column is set to
its default value.
Setting a numeric column to a value that lies outside the column’s range. The value is
clipped to the appropriate endpoint of the range.
Setting a numeric column to a value such as ’10.34 a’. The trailing garbage is stripped
and the remaining numeric part is inserted. If the value doesn’t make sense as a number
at all, the column is set to 0.
Chapter 6: Referˆencia de Linguagem do MySQL 453
Inserting a string into a CHAR,VARCHAR,TEXT, or BLOB column that exceeds the column’s
maximum length. The value is truncated to the column’s maximum length.
Inserting a value into a date or time column that is illegal for the column type. The
column is set to the appropriate zero value for the type.
6.4.3.1 INSERT ... SELECT Syntax
INSERT [LOW_PRIORITY] [IGNORE] [INTO] nome_tabela [(column list)] SELECT ...
With INSERT ... SELECT statement you can quickly insert many rows into a table from one
or many tables.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
tblTemp1.fldOrder_ID > 100;
The following conditions hold for an INSERT ... SELECT statement:
The target table of the INSERT statement cannot appear in the FROM clause of the
SELECT part of the query because it’s forbidden in standard SQL to SELECT from
the same table into which you are inserting. (The problem is that the SELECT possibly
would find records that were inserted earlier during the same run. When using subquery
clauses, the situation could easily be very confusing!)
AUTO_INCREMENT columns work as usual.
You can use the C API function mysql_info() to get information about the query.
See hundefinedi[INSERT], page hundefinedi.
To ensure that the binary log can be used to re-create the original tables, MySQL will
not allow concurrent inserts during INSERT ... SELECT.
You can of course also use REPLACE instead of INSERT to overwrite old rows.
6.4.4 INSERT DELAYED Syntax
INSERT DELAYED ...
The DELAYED option for the INSERT statement is a MySQL-specific option that is very
useful if you have clients that can’t wait for the INSERT to complete. This is a common
problem when you use MySQL for logging and you also periodically run SELECT and UPDATE
statements that take a long time to complete. DELAYED was introduced in MySQL Version
3.22.15. It is a MySQL extension to SQL-92.
INSERT DELAYED only works with ISAM and MyISAM tables. Note that as MyISAM tables sup-
ports concurrent SELECT and INSERT, if there is no free blocks in the middle of the datafile,
you very seldom need to use INSERT DELAYED with MyISAM. See hundefinedi[MyISAM],
page hundefinedi.
When you use INSERT DELAYED, the client will get an OK at once and the row will be
inserted when the table is not in use by any other thread.
Another major benefit of using INSERT DELAYED is that inserts from many clients are bun-
dled together and written in one block. This is much faster than doing many separate
inserts.
Note that currently the queued rows are only stored in memory until they are inserted into
the table. This means that if you kill mysqld the hard way (kill -9) or if mysqld dies
unexpectedly, any queued rows that weren’t written to disk are lost!
454 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
The following describes in detail what happens when you use the DELAYED option to INSERT
or REPLACE. In this description, the “thread” is the thread that received an INSERT DELAYED
command and “handler” is the thread that handles all INSERT DELAYED statements for a
particular table.
When a thread executes a DELAYED statement for a table, a handler thread is created
to process all DELAYED statements for the table, if no such handler already exists.
The thread checks whether the handler has acquired a DELAYED lock already; if not,
it tells the handler thread to do so. The DELAYED lock can be obtained even if other
threads have a READ or WRITE lock on the table. However, the handler will wait for all
ALTER TABLE locks or FLUSH TABLES to ensure that the table structure is up to date.
The thread executes the INSERT statement, but instead of writing the row to the table,
it puts a copy of the final row into a queue that is managed by the handler thread.
Any syntax errors are noticed by the thread and reported to the client program.
The client can’t report the number of duplicates or the AUTO_INCREMENT value for the
resulting row; it can’t obtain them from the server, because the INSERT returns before
the insert operation has been completed. If you use the C API, the mysql_info()
function doesn’t return anything meaningful, for the same reason.
The binary log is updated by the handler thread when the row is inserted into the
table. In case of multiple-row inserts, the binary log is updated when the first row is
inserted.
After every delayed_insert_limit rows are written, the handler checks whether any
SELECT statements are still pending. If so, it allows these to execute before continuing.
When the handler has no more rows in its queue, the table is unlocked. If no new INSERT
DELAYED commands are received within delayed_insert_timeout seconds, the handler
terminates.
If more than delayed_queue_size rows are pending already in a specific handler queue,
the thread requesting INSERT DELAYED waits until there is room in the queue. This is
done to ensure that the mysqld server doesn’t use all memory for the delayed memory
queue.
The handler thread will show up in the MySQL process list with delayed_insert in
the Command column. It will be killed if you execute a FLUSH TABLES command or kill it
with KILL thread_id. However, it will first store all queued rows into the table before
exiting. During this time it will not accept any new INSERT commands from another
thread. If you execute an INSERT DELAYED command after this, a new handler thread
will be created.
Note that the above means that INSERT DELAYED commands have higher priority than
normal INSERT commands if there is an INSERT DELAYED handler already running!
Other update commands will have to wait until the INSERT DELAYED queue is empty,
someone kills the handler thread (with KILL thread_id), or someone executes FLUSH
TABLES.
The following status variables provide information about INSERT DELAYED commands:
Variable Meaning
Delayed_insert_threads Number of handler threads
Delayed_writes Number of rows written with INSERT DELAYED
Chapter 6: Referˆencia de Linguagem do MySQL 455
Not_flushed_delayed_
rows
Number of rows waiting to be written
You can view these variables by issuing a SHOW STATUS statement or by executing a
mysqladmin extended-status command.
Note that INSERT DELAYED is slower than a normal INSERT if the table is not in use. There
is also the additional overhead for the server to handle a separate thread for each table on
which you use INSERT DELAYED. This means that you should only use INSERT DELAYED
when you are really sure you need it!
6.4.5 UPDATE Syntax
UPDATE [LOW_PRIORITY] [IGNORE] nome_tabela
SET nome_coluna1=expr1 [, nome_coluna2=expr2 ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT rows]
or
UPDATE [LOW_PRIORITY] [IGNORE] nome_tabela [, nome_tabela ...]
SET nome_coluna1=expr1 [, nome_coluna2=expr2 ...]
[WHERE where_definition]
UPDATE updates columns in existing table rows with new values. The SET clause indicates
which columns to modify and the values they should be given. The WHERE clause, if given,
specifies which rows should be updated. Otherwise, all rows are updated. If the ORDER BY
clause is specified, the rows will be updated in the order that is specified.
If you specify the keyword LOW_PRIORITY, execution of the UPDATE is delayed until no other
clients are reading from the table.
If you specify the keyword IGNORE, the update statement will not abort even if we get
duplicate key errors during the update. Rows that would cause conflicts will not be updated.
If you access a column from nome_tabela in an expression, UPDATE uses the current value
of the column. For example, the following statement sets the age column to one more than
its current value:
mysql> UPDATE persondata SET age=age+1;
UPDATE assignments are evaluated from left to right. For example, the following statement
doubles the age column, then increments it:
mysql> UPDATE persondata SET age=age*2, age=age+1;
If you set a column to the value it currently has, MySQL notices this and doesn’t update
it.
UPDATE returns the number of rows that were actually changed. In MySQL Version 3.22
or later, the C API function mysql_info() returns the number of rows that were matched
and updated and the number of warnings that occurred during the UPDATE.
Starting from MySQL version 3.23, you can use LIMIT # to ensure that only a given number
of rows are changed. MySQL will stop the update as soon as it has found LIMIT rows that
satisfies the WHERE clause, independent of the rows changed content or not.
456 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
If an ORDER BY clause is used (available from MySQL 4.0.0), the rows will be updated in
that order. This is really only useful in conjunction with LIMIT.
Starting with MySQL Version 4.0.4, you can also perform UPDATE operations that cover
multiple tables:
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
Note: you can not use ORDER BY or LIMIT with multi-table UPDATE.
6.4.6 DELETE Syntax
DELETE [LOW_PRIORITY] [QUICK] FROM table_name
[WHERE where_definition]
[ORDER BY ...]
[LIMIT rows]
or
DELETE [LOW_PRIORITY] [QUICK] table_name[.*] [, table_name[.*] ...]
FROM table-references
[WHERE where_definition]
or
DELETE [LOW_PRIORITY] [QUICK]
FROM table_name[.*] [, table_name[.*] ...]
USING table-references
[WHERE where_definition]
DELETE deletes rows from table_name that satisfy the condition given by where_
definition, and returns the number of records deleted.
If you issue a DELETE with no WHERE clause, all rows are deleted. If you do this in AUTOCOMMIT
mode, this works as TRUNCATE. See hundefinedi[TRUNCATE], page hundefinedi. In MySQL
3.23, DELETE without a WHERE clause will return zero as the number of affected records.
If you really want to know how many records are deleted when you are deleting all rows,
and are willing to suffer a speed penalty, you can use a DELETE statement of this form:
mysql> DELETE FROM table_name WHERE 1>0;
Note that this is much slower than DELETE FROM table_name with no WHERE clause, because
it deletes rows one at a time.
If you specify the keyword LOW_PRIORITY, execution of the DELETE is delayed until no other
clients are reading from the table.
If you specify the word QUICK then the storage engine will not merge index leaves during
delete, which may speed up certain kind of deletes.
In MyISAM tables, deleted records are maintained in a linked list and subsequent INSERT
operations reuse old record positions. To reclaim unused space and reduce file-sizes, use the
OPTIMIZE TABLE statement or the myisamchk utility to reorganise tables. OPTIMIZE TABLE
is easier, but myisamchk is faster. See hundefinedi[OPTIMIZE TABLE], page hundefinediand
hundefinedi[Optimisation], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 457
The first multi-table delete format is supported starting from MySQL 4.0.0. The second
multi-table delete format is supported starting from MySQL 4.0.2.
The idea is that only matching rows from the tables listed before the FROM or before the
USING clause are deleted. The effect is that you can delete rows from many tables at the
same time and also have additional tables that are used for searching.
The .* after the table names is there just to be compatible with Access:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
or
DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
In the above case we delete matching rows just from tables t1 and t2.
If an ORDER BY clause is used (available from MySQL 4.0.0), the rows will be deleted in that
order. This is really only useful in conjunction with LIMIT. For example:
DELETE FROM somelog
WHERE user = ’jcole’
ORDER BY timestamp
LIMIT 1
This will delete the oldest entry (by timestamp) where the row matches the WHERE clause.
The MySQL-specific LIMIT rows option to DELETE tells the server the maximum number of
rows to be deleted before control is returned to the client. This can be used to ensure that
a specific DELETE command doesn’t take too much time. You can simply repeat the DELETE
command until the number of affected rows is less than the LIMIT value.
From MySQL 4.0, you can specify multiple tables in the DELETE statement to delete rows
from one table depending on a particular condition in multiple tables. However, you can
not use ORDER BY or LIMIT in a multi-table DELETE.
6.4.7 TRUNCATE Syntax
TRUNCATE TABLE table_name
In 3.23 TRUNCATE TABLE is mapped to COMMIT ; DELETE FROM table_name. See hundefinedi
[DELETE], page hundefinedi.
TRUNCATE TABLE differs from DELETE FROM ... in the following ways:
Truncate operations drop and re-create the table, which is much faster than deleting
rows one by one.
Not transaction-safe; you will get an error if you have an active transaction or an active
table lock.
Doesn’t return the number of deleted rows.
As long as the table definition file ‘table_name.frm’ is valid, the table can be re-created
this way, even if the data or index files have become corrupted.
TRUNCATE is an Oracle SQL extension.
458 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
6.4.8 REPLACE Syntax
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] nome_tabela [(nome_coluna,...)]
VALUES (expression,...),(...),...
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] nome_tabela [(nome_coluna,...)]
SELECT ...
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] nome_tabela
SET nome_coluna=expression, nome_coluna=expression,...
REPLACE works exactly like INSERT, except that if an old record in the table has the same
value as a new record on a UNIQUE index or PRIMARY KEY, the old record is deleted before
the new record is inserted. See hundefinedi[INSERT], page hundefinedi.
In other words, you can’t access the values of the old row from a REPLACE statement. In
some old MySQL versions it appeared that you could do this, but that was a bug that has
been corrected.
To be able to use REPLACE you must have INSERT and DELETE privileges for the table.
When you use a REPLACE command, mysql_affected_rows() will return 2 if the new row
replaced an old row. This is because one row was inserted after the duplicate was deleted.
This fact makes it easy to determine whether REPLACE added or replaced a row: check
whether the affected-rows value is 1 (added) or 2 (replaced).
Note that unless you use a UNIQUE index or PRIMARY KEY, using a REPLACE command makes
no sense, since it would just do an INSERT.
6.4.9 LOAD DATA INFILE Syntax
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE ’file_name.txt’
[REPLACE | IGNORE]
INTO TABLE nome_tabela
[FIELDS
[TERMINATED BY ’\t’]
[[OPTIONALLY] ENCLOSED BY ’’]
[ESCAPED BY ’\\’ ]
]
[LINES TERMINATED BY ’\n’]
[IGNORE number LINES]
[(nome_coluna,...)]
The LOAD DATA INFILE statement reads rows from a text file into a table at a very high
speed. If the LOCAL keyword is specified, the file is read from the client host. If LOCAL is
not specified, the file must be located on the server. (LOCAL is available in MySQL Version
3.22.6 or later.)
For security reasons, when reading text files located on the server, the files must either
reside in the database directory or be readable by all. Also, to use LOAD DATA INFILE on
server files, you must have the FILE privilege on the server host. See hundefinedi[Privileges
provided], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 459
In MySQL 3.23.49 and MySQL 4.0.2 LOCAL will only work if you have not started mysqld
with --local-infile=0 or if you have not enabled your client to support LOCAL. See
hundefinedi[LOAD DATA LOCAL], page hundefinedi.
If you specify the keyword LOW_PRIORITY, execution of the LOAD DATA statement is delayed
until no other clients are reading from the table.
If you specify the keyword CONCURRENT with a MyISAM table, then other threads can retrieve
data from the table while LOAD DATA is executing. Using this option will of course affect the
performance of LOAD DATA a bit even if no other thread is using the table at the same time.
Using LOCAL will be a bit slower than letting the server access the files directly, because the
contents of the file must travel from the client host to the server host. On the other hand,
you do not need the FILE privilege to load local files.
If you are using MySQL before Version 3.23.24 you can’t read from a FIFO with LOAD DATA
INFILE. If you need to read from a FIFO (for example the output from gunzip), use LOAD
DATA LOCAL INFILE instead.
You can also load datafiles by using the mysqlimport utility; it operates by sending a
LOAD DATA INFILE command to the server. The --local option causes mysqlimport to
read datafiles from the client host. You can specify the --compress option to get better
performance over slow networks if the client and server support the compressed protocol.
When locating files on the server host, the server uses the following rules:
If an absolute pathname is given, the server uses the pathname as is.
If a relative pathname with one or more leading components is given, the server searches
for the file relative to the server’s data directory.
If a filename with no leading components is given, the server looks for the file in the
database directory of the current database.
Note that these rules mean a file given as ‘./myfile.txt’ is read from the server’s data
directory, whereas a file given as ‘myfile.txt’ is read from the database directory of the
current database. For example, the following LOAD DATA statement reads the file ‘data.txt
from the database directory for db1 because db1 is the current database, even though the
statement explicitly loads the file into a table in the db2 database:
mysql> USE db1;
mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
The REPLACE and IGNORE keywords control handling of input records that duplicate existing
records on unique key values. If you specify REPLACE, new rows replace existing rows that
have the same unique key value. If you specify IGNORE, input rows that duplicate an existing
row on a unique key value are skipped. If you don’t specify either option, an error occurs
when a duplicate key value is found, and the rest of the text file is ignored.
If you load data from a local file using the LOCAL keyword, the server has no way to stop
transmission of the file in the middle of the operation, so the default behaviour is the same
as if IGNORE is specified.
If you use LOAD DATA INFILE on an empty MyISAM table, all non-unique indexes are created
in a separate batch (like in REPAIR). This normally makes LOAD DATA INFILE much faster
when you have many indexes.
LOAD DATA INFILE is the complement of SELECT ... INTO OUTFILE. See hundefinedi
[SELECT], page hundefinedi. To write data from a database to a file, use SELECT ... INTO
460 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
OUTFILE. To read the file back into the database, use LOAD DATA INFILE. The syntax of
the FIELDS and LINES clauses is the same for both commands. Both clauses are optional,
but FIELDS must precede LINES if both are specified.
If you specify a FIELDS clause, each of its subclauses (TERMINATED BY,[OPTIONALLY]
ENCLOSED BY, and ESCAPED BY) is also optional, except that you must specify at least one
of them.
If you don’t specify a FIELDS clause, the defaults are the same as if you had written this:
FIELDS TERMINATED BY ’\t’ ENCLOSED BY ’’ ESCAPED BY ’\\’
If you don’t specify a LINES clause, the default is the same as if you had written this:
LINES TERMINATED BY ’\n’
In other words, the defaults cause LOAD DATA INFILE to act as follows when reading input:
Look for line boundaries at newlines.
Break lines into fields at tabs.
Do not expect fields to be enclosed within any quoting characters.
Interpret occurrences of tab, newline, or ‘\’ preceded by ‘\’ as literal characters that
are part of field values.
Conversely, the defaults cause SELECT ... INTO OUTFILE to act as follows when writing
output:
Write tabs between fields.
Do not enclose fields within any quoting characters.
Use ‘\’ to escape instances of tab, newline or ‘\’ that occur within field values.
Write newlines at the ends of lines.
Note that to write FIELDS ESCAPED BY ’\\’, you must specify two backslashes for the value
to be read as a single backslash.
The IGNORE number LINES option can be used to ignore a header of column names at the
start of the file:
mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
When you use SELECT ... INTO OUTFILE in tandem with LOAD DATA INFILE to write data
from a database into a file and then read the file back into the database later, the field and
line handling options for both commands must match. Otherwise, LOAD DATA INFILE will
not interpret the contents of the file properly. Suppose you use SELECT ... INTO OUTFILE
to write a file with fields delimited by commas:
mysql> SELECT * INTO OUTFILE ’data.txt’
-> FIELDS TERMINATED BY ’,’
-> FROM ...;
To read the comma-delimited file back in, the correct statement would be:
mysql> LOAD DATA INFILE ’data.txt’ INTO TABLE table2
-> FIELDS TERMINATED BY ’,’;
If instead you tried to read in the file with the statement shown here, it wouldn’t work
because it instructs LOAD DATA INFILE to look for tabs between fields:
Chapter 6: Referˆencia de Linguagem do MySQL 461
mysql> LOAD DATA INFILE ’data.txt’ INTO TABLE table2
-> FIELDS TERMINATED BY ’\t’;
The likely result is that each input line would be interpreted as a single field.
LOAD DATA INFILE can be used to read files obtained from external sources, too. For exam-
ple, a file in dBASE format will have fields separated by commas and enclosed in double
quotes. If lines in the file are terminated by newlines, the command shown here illustrates
the field and line handling options you would use to load the file:
mysql> LOAD DATA INFILE ’data.txt’ INTO TABLE nome_tabela
-> FIELDS TERMINATED BY ’,’ ENCLOSED BY ’"’
-> LINES TERMINATED BY ’\n’;
Any of the field or line handling options may specify an empty string (’’). If not empty,
the FIELDS [OPTIONALLY] ENCLOSED BY and FIELDS ESCAPED BY values must be a single
character. The FIELDS TERMINATED BY and LINES TERMINATED BY values may be more than
one character. For example, to write lines that are terminated by carriage return-linefeed
pairs, or to read a file containing such lines, specify a LINES TERMINATED BY ’\r\n’ clause.
For example, to read a file of jokes, that are separated with a line of %%, into a SQL table
you can do:
CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT
NOT NULL);
LOAD DATA INFILE "/tmp/jokes.txt" INTO TABLE jokes FIELDS TERMINATED BY ""
LINES TERMINATED BY "\n%%\n" (joke);
FIELDS [OPTIONALLY] ENCLOSED BY controls quoting of fields. For output (SELECT ...
INTO OUTFILE), if you omit the word OPTIONALLY, all fields are enclosed by the ENCLOSED
BY character. An example of such output (using a comma as the field delimiter) is shown
here:
"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"
If you specify OPTIONALLY, the ENCLOSED BY character is used only to enclose CHAR and
VARCHAR fields:
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20
Note that occurrences of the ENCLOSED BY character within a field value are escaped by
prefixing them with the ESCAPED BY character. Also note that if you specify an empty
ESCAPED BY value, it is possible to generate output that cannot be read properly by LOAD
DATA INFILE. For example, the output just shown above would appear as shown here if
the escape character is empty. Observe that the second field in the fourth line contains a
comma following the quote, which (erroneously) appears to terminate the field:
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20
462 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
For input, the ENCLOSED BY character, if present, is stripped from the ends of field values.
(This is true whether OPTIONALLY is specified; OPTIONALLY has no effect on input interpre-
tation.) Occurrences of the ENCLOSED BY character preceded by the ESCAPED BY character
are interpreted as part of the current field value. In addition, duplicated ENCLOSED BY char-
acters occurring within fields are interpreted as single ENCLOSED BY characters if the field
itself starts with that character. For example, if ENCLOSED BY ’"’ is specified, quotes are
handled as shown here:
"The ""BIG"" boss" -> The "BIG" boss
The "BIG" boss -> The "BIG" boss
The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY controls how to write or read special characters. If the FIELDS ESCAPED
BY character is not empty, it is used to prefix the following characters on output:
The FIELDS ESCAPED BY character
The FIELDS [OPTIONALLY] ENCLOSED BY character
The first character of the FIELDS TERMINATED BY and LINES TERMINATED BY values
ASCII 0(what is actually written following the escape character is ASCII ’0’, not a
zero-valued byte)
If the FIELDS ESCAPED BY character is empty, no characters are escaped. It is probably not
a good idea to specify an empty escape character, particularly if field values in your data
contain any of the characters in the list just given.
For input, if the FIELDS ESCAPED BY character is not empty, occurrences of that character
are stripped and the following character is taken literally as part of a field value. The
exceptions are an escaped ‘0’ or ‘N’ (for example, \0 or \N if the escape character is ‘\’).
These sequences are interpreted as ASCII 0(a zero-valued byte) and NULL. See below for
the rules on NULL handling.
For more information about ‘\’-escape syntax, see hundefinedi[Literals], page hundefinedi.
In certain cases, field and line handling options interact:
If LINES TERMINATED BY is an empty string and FIELDS TERMINATED BY is non-empty,
lines are also terminated with FIELDS TERMINATED BY.
If the FIELDS TERMINATED BY and FIELDS ENCLOSED BY values are both empty (’’), a
fixed-row (non-delimited) format is used. With fixed-row format, no delimiters are used
between fields. Instead, column values are written and read using the “display” widths
of the columns. For example, if a column is declared as INT(7), values for the column
are written using 7-character fields. On input, values for the column are obtained by
reading 7 characters. Fixed-row format also affects handling of NULL values; see below.
Note that fixed-size format will not work if you are using a multi-byte character set.
Handling of NULL values varies, depending on the FIELDS and LINES options you use:
For the default FIELDS and LINES values, NULL is written as \N for output and \N is
read as NULL for input (assuming the ESCAPED BY character is ‘\’).
If FIELDS ENCLOSED BY is not empty, a field containing the literal word NULL as its
value is read as a NULL value (this differs from the word NULL enclosed within FIELDS
ENCLOSED BY characters, which is read as the string ’NULL’).
If FIELDS ESCAPED BY is empty, NULL is written as the word NULL.
Chapter 6: Referˆencia de Linguagem do MySQL 463
With fixed-row format (which happens when FIELDS TERMINATED BY and FIELDS
ENCLOSED BY are both empty), NULL is written as an empty string. Note that this
causes both NULL values and empty strings in the table to be indistinguishable when
written to the file because they are both written as empty strings. If you need to be
able to tell the two apart when reading the file back in, you should not use fixed-row
format.
Some cases are not supported by LOAD DATA INFILE:
Fixed-size rows (FIELDS TERMINATED BY and FIELDS ENCLOSED BY both empty) and
BLOB or TEXT columns.
If you specify one separator that is the same as or a prefix of another, LOAD DATA INFILE
won’t be able to interpret the input properly. For example, the following FIELDS clause
would cause problems:
FIELDS TERMINATED BY ’"’ ENCLOSED BY ’"’
If FIELDS ESCAPED BY is empty, a field value that contains an occurrence of FIELDS
ENCLOSED BY or LINES TERMINATED BY followed by the FIELDS TERMINATED BY value
will cause LOAD DATA INFILE to stop reading a field or line too early. This happens
because LOAD DATA INFILE cannot properly determine where the field or line value
ends.
The following example loads all columns of the persondata table:
mysql> LOAD DATA INFILE ’persondata.txt’ INTO TABLE persondata;
No field list is specified, so LOAD DATA INFILE expects input rows to contain a field for each
table column. The default FIELDS and LINES values are used.
If you wish to load only some of a table’s columns, specify a field list:
mysql> LOAD DATA INFILE ’persondata.txt’
-> INTO TABLE persondata (col1,col2,...);
You must also specify a field list if the order of the fields in the input file differs from the
order of the columns in the table. Otherwise, MySQL cannot tell how to match up input
fields with table columns.
If a row has too few fields, the columns for which no input field is present are set to default
values. Default value assignment is described in hundefinedi[CREATE TABLE], page hunde-
finedi.
An empty field value is interpreted differently than if the field value is missing:
For string types, the column is set to the empty string.
For numeric types, the column is set to 0.
For date and time types, the column is set to the appropriate “zero” value for the type.
See hundefinedi[Date and time types], page hundefinedi.
Note that these are the same values that result if you assign an empty string explicitly to
a string, numeric, or date or time type explicitly in an INSERT or UPDATE statement.
TIMESTAMP columns are only set to the current date and time if there is a NULL value for
the column, or (for the first TIMESTAMP column only) if the TIMESTAMP column is left out
from the field list when a field list is specified.
If an input row has too many fields, the extra fields are ignored and the number of warnings
is incremented.
464 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
LOAD DATA INFILE regards all input as strings, so you can’t use numeric values for ENUM or
SET columns the way you can with INSERT statements. All ENUM and SET values must be
specified as strings!
If you are using the C API, you can get information about the query by calling the API
function mysql_info() when the LOAD DATA INFILE query finishes. The format of the
information string is shown here:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Warnings occur under the same circumstances as when values are inserted via the INSERT
statement (see hundefinedi[INSERT], page hundefinedi), except that LOAD DATA INFILE also
generates warnings when there are too few or too many fields in the input row. The warnings
are not stored anywhere; the number of warnings can only be used as an indication if
everything went well. If you get warnings and want to know exactly why you got them,
one way to do this is to use SELECT ... INTO OUTFILE into another file and compare this
to your original input file.
If you need LOAD DATA to read from a pipe, you can use the following trick:
mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
mysql -e "LOAD DATA INFILE ’x’ INTO TABLE x" x
If you are using a version of MySQL older than 3.23.25 you can only do the above with
LOAD DATA LOCAL INFILE.
For more information about the efficiency of INSERT versus LOAD DATA INFILE and speeding
up LOAD DATA INFILE, See hundefinedi[Insert speed], page hundefinedi.
6.4.10 DO Syntax
DO expression, [expression, ...]
Execute the expression but don’t return any results. This is a shorthand of SELECT
expression, expression, but has the advantage that it’s slightly faster when you don’t
care about the result.
This is mainly useful with functions that has side effects, like RELEASE_LOCK.
6.5 Data Definition: CREATE,DROP,ALTER
6.5.1 CREATE DATABASE Syntax
CREATE DATABASE [IF NOT EXISTS] db_name
CREATE DATABASE creates a database with the given name. Rules for allowable database
names are given in hundefinedi[Legal names], page hundefinedi. An error occurs if the
database already exists and you didn’t specify IF NOT EXISTS.
Databases in MySQL are implemented as directories containing files that correspond to
tables in the database. Because there are no tables in a database when it is initially
created, the CREATE DATABASE statement only creates a directory under the MySQL data
directory.
You can also create databases with mysqladmin. See Side Scripts-snt [Client-Side Scripts],
page Side Scripts-pg.
Chapter 6: Referˆencia de Linguagem do MySQL 465
6.5.2 DROP DATABASE Syntax
DROP DATABASE [IF EXISTS] db_name
DROP DATABASE drops all tables in the database and deletes the database. If you do a DROP
DATABASE on a symbolic linked database, both the link and the original database is deleted.
Be VERY careful with this command!
DROP DATABASE returns the number of files that were removed from the database directory.
Normally, this is three times the number of tables, because normally each table corresponds
to a ‘.MYD’ file, a ‘.MYI’ file, and a ‘.frm’ file.
The DROP DATABASE command removes from the given database directory all files with the
following extensions:
Ext Ext Ext Ext
.BAK .DAT .HSH .ISD
.ISM .ISM .MRG .MYD
.MYI .db .frm
All subdirectories that consists of 2 digits (RAID directories) are also removed.
In MySQL Version 3.22 or later, you can use the keywords IF EXISTS to prevent an error
from occurring if the database doesn’t exist.
You can also drop databases with mysqladmin. See Side Scripts-snt [Client-Side Scripts],
page Side Scripts-pg.
6.5.3 CREATE TABLE Syntax
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nome_tabela [(create_definition,...)]
[table_options] [select_statement]
or
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nome_tabela LIKE old_table_name;
create_definition:
nome_coluna type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
or PRIMARY KEY (index_nome_coluna,...)
or KEY [index_name] (index_nome_coluna,...)
or INDEX [index_name] (index_nome_coluna,...)
or UNIQUE [INDEX] [index_name] (index_nome_coluna,...)
or FULLTEXT [INDEX] [index_name] (index_nome_coluna,...)
or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_nome_coluna,...)
[reference_definition]
or CHECK (expr)
type:
TINYINT[(length)] [UNSIGNED] [ZEROFILL]
or SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
or MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
or INT[(length)] [UNSIGNED] [ZEROFILL]
or INTEGER[(length)] [UNSIGNED] [ZEROFILL]
466 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
or BIGINT[(length)] [UNSIGNED] [ZEROFILL]
or REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
or DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
or FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
or DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
or NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
or CHAR(length) [BINARY]
or VARCHAR(length) [BINARY]
or DATE
or TIME
or TIMESTAMP
or DATETIME
or TINYBLOB
or BLOB
or MEDIUMBLOB
or LONGBLOB
or TINYTEXT
or TEXT
or MEDIUMTEXT
or LONGTEXT
or ENUM(value1,value2,value3,...)
or SET(value1,value2,value3,...)
index_nome_coluna:
nome_coluna [(length)]
reference_definition:
REFERENCES nome_tabela [(index_nome_coluna,...)]
[MATCH FULL | MATCH PARTIAL]
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM }
or AUTO_INCREMENT = #
or AVG_ROW_LENGTH = #
or CHECKSUM = {0 | 1}
or COMMENT = "string"
or MAX_ROWS = #
or MIN_ROWS = #
or PACK_KEYS = {0 | 1 | DEFAULT}
or PASSWORD = "string"
or DELAY_KEY_WRITE = {0 | 1}
or ROW_FORMAT= { default | dynamic | fixed | compressed }
or RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=# RAID_CHUNKSIZE=#
or UNION = (table_name,[table_name...])
Chapter 6: Referˆencia de Linguagem do MySQL 467
or INSERT_METHOD= {NO | FIRST | LAST }
or DATA DIRECTORY="absolute path to directory"
or INDEX DIRECTORY="absolute path to directory"
select_statement:
[IGNORE | REPLACE] SELECT ... (Some legal select statement)
CREATE TABLE creates a table with the given name in the current database. Rules for
allowable table names are given in hundefinedi[Legal names], page hundefinedi. An error
occurs if there is no current database or if the table already exists.
In MySQL Version 3.22 or later, the table name can be specified as db_name.nome_tabela.
This works regardless of whether there is a current database.
From MySQL Version 3.23, you can use the TEMPORARY keyword when you create a table.
The name is restricted to the current connection, and the temporary table will automatically
be deleted when the connection is closed. This means that two different connections can
both use the same temporary table name without conflicting with each other or with an
existing table of the same name. (The existing table is hidden until the temporary table is
deleted.). From MySQL 4.0.2 one must have the CREATE TEMPORARY TABLES privilege to be
able to create temporary tables.
In MySQL Version 3.23 or later, you can use the keywords IF NOT EXISTS so that an error
does not occur if the table already exists. Note that there is no verification that the table
structures are identical.
In MySQL 4.1 you can use LIKE to create a table based on a table definition in another
table. In MySQL 4.1 you can also specify the type for a generated column:
CREATE TABLE foo (a tinyint not null) SELECT b+1 AS ’a’ FROM bar;
Each table nome_tabela is represented by some files in the database directory. In the case
of MyISAM-type tables you will get:
File Purpose
nome_tabela.frm Table definition (form)
file
nome_tabela.MYD Datafile
nome_tabela.MYI Index file
For more information on the properties of the various column types, see hundefinedi[Column
types], page hundefinedi:
If neither NULL nor NOT NULL is specified, the column is treated as though NULL had
been specified.
An integer column may have the additional attribute AUTO_INCREMENT. When you
insert a value of NULL (recommended) or 0into an AUTO_INCREMENT column, the column
is set to value+1, where value is the largest value for the column currently in the
table. AUTO_INCREMENT sequences begin with 1. See hundefinedi[mysql_insert_id()],
page hundefinedi.
If you delete the row containing the maximum value for an AUTO_INCREMENT column,
the value will be reused with an ISAM, or BDB table but not with a MyISAM or InnoDB
table. If you delete all rows in the table with DELETE FROM table_name (without a
WHERE) in AUTOCOMMIT mode, the sequence starts over for all table types.
468 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note: there can be only one AUTO_INCREMENT column per table, and it must be indexed.
MySQL Version 3.23 will also only work properly if the AUTO_INCREMENT column only
has positive values. Inserting a negative number is regarded as inserting a very large
positive number. This is done to avoid precision problems when numbers ’wrap’ over
from positive to negative and also to ensure that one doesn’t accidentally get an AUTO_
INCREMENT column that contains 0.
In MyISAM and BDB tables you can specify AUTO_INCREMENT secondary column in
a multi-column key. See AUTO˙INCREMENT-snt [example-AUTO INCREMENT],
page AUTO˙INCREMENT-pg.
To make MySQL compatible with some ODBC applications, you can find the last
inserted row with the following query:
SELECT * FROM nome_tabela WHERE auto_col IS NULL
CREATE TABLE automatically commits the current InnoDB transaction if MySQL binary
logging is used.
NULL values are handled differently for TIMESTAMP columns than for other column types.
You cannot store a literal NULL in a TIMESTAMP column; setting the column to NULL
sets it to the current date and time. Because TIMESTAMP columns behave this way, the
NULL and NOT NULL attributes do not apply in the normal way and are ignored if you
specify them.
On the other hand, to make it easier for MySQL clients to use TIMESTAMP columns,
the server reports that such columns may be assigned NULL values (which is true), even
though TIMESTAMP never actually will contain a NULL value. You can see this when you
use DESCRIBE nome_tabela to get a description of your table.
Note that setting a TIMESTAMP column to 0is not the same as setting it to NULL,
because 0is a valid TIMESTAMP value.
ADEFAULT value has to be a constant, it cannot be a function or an expression.
If no DEFAULT value is specified for a column, MySQL automatically assigns one, as
follows.
If the column may take NULL as a value, the default value is NULL.
If the column is declared as NOT NULL, the default value depends on the column type:
For numeric types other than those declared with the AUTO_INCREMENT attribute,
the default is 0. For an AUTO_INCREMENT column, the default value is the next
value in the sequence.
For date and time types other than TIMESTAMP, the default is the appropriate zero
value for the type. For the first TIMESTAMP column in a table, the default value
is the current date and time. See hundefinedi[Date and time types], page hunde-
finedi.
For string types other than ENUM, the default value is the empty string. For ENUM,
the default is the first enumeration value.
Default values must be constants. This means, for example, that you cannot set the
default for a date column to be the value of a function such as NOW() or CURRENT_DATE.
KEY is a synonym for INDEX.
In MySQL, a UNIQUE key can have only distinct values. An error occurs if you try to
add a new row with a key that matches an existing row.
Chapter 6: Referˆencia de Linguagem do MySQL 469
APRIMARY KEY is a unique KEY with the extra constraint that all key columns must
be defined as NOT NULL. In MySQL the key is named PRIMARY. A table can have only
one PRIMARY KEY. If you don’t have a PRIMARY KEY and some applications ask for the
PRIMARY KEY in your tables, MySQL will return the first UNIQUE key, which doesn’t
have any NULL columns, as the PRIMARY KEY.
APRIMARY KEY can be a multiple-column index. However, you cannot create a multiple-
column index using the PRIMARY KEY key attibute in a column specification. Doing so
will mark only that single column as primary. You must use the PRIMARY KEY(index_
nome_coluna, ...) syntax.
If the PRIMARY or UNIQUE key consists of only one column and this is of type integer,
you can also refer to it as _rowid (new in Version 3.23.11).
If you don’t assign a name to an index, the index will be assigned the same name as the
first index_nome_coluna, with an optional suffix (_2,_3,...) to make it unique. You
can see index names for a table using SHOW INDEX FROM nome_tabela. See hundefinedi
[SHOW DATABASE INFO], page hundefinedi.
Only the MyISAM,InnoDB, and BDB table types support indexes on columns that can
have NULL values. In other cases you must declare such columns NOT NULL or an error
results.
With nome_coluna(length) syntax, you can specify an index that uses only a part of
aCHAR or VARCHAR column. This can make the index file much smaller. See hundefinedi
[Indexes], page hundefinedi.
Only the MyISAM table type supports indexing on BLOB and TEXT columns. When
putting an index on a BLOB or TEXT column you MUST always specify the length of
the index:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
When you use ORDER BY or GROUP BY with a TEXT or BLOB column, only the first max_
sort_length bytes are used. See hundefinedi[BLOB], page hundefinedi.
In MySQL Version 3.23.23 or later, you can also create special FULLTEXT indexes. They
are used for full-text search. Only the MyISAM table type supports FULLTEXT indexes.
They can be created only from CHAR,VARCHAR, and TEXT columns. Indexing always
happens over the entire column; partial indexing is not supported. See hundefinedi
[Fulltext Search], page hundefinedifor details of operation.
In MySQL Version 3.23.44 or later, InnoDB tables support checking of foreign key
constraints. See hundefinedi[InnoDB], page hundefinedi. Note that the FOREIGN KEY
syntax in InnoDB is more restricted than the syntax presented above. InnoDB does
not allow index_name to be specified, and the columns of the referenced table always
have to be explicitly named. Starting from 4.0.8 InnoDB supports both ON DELETE
and ON UPDATE actions on foreign keys. See the InnoDB manual section for the precise
syntax. See hundefinedi[InnoDB], page hundefinedi. For other table types, MySQL
Server does parse the FOREIGN KEY,CHECK, and REFERENCES syntax in CREATE TABLE
commands, but without further action being taken. See hundefinedi[ANSI diff Foreign
Keys], page hundefinedi.
Each NULL column takes one bit extra, rounded up to the nearest byte.
The maximum record length in bytes can be calculated as follows:
470 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
row length = 1
+ (sum of column lengths)
+ (number of NULL columns + 7)/8
+ (number of variable-length columns)
The table_options and SELECT options are only implemented in MySQL Version 3.23
and above.
The different table types are:
Table type Description
BDB or BerkeleyDB Transaction-safe tables with page locking. See hundefinedi
[BDB], page hundefinedi.
HEAP The data for this table is only stored in memory. See hunde-
finedi[HEAP], page hundefinedi.
ISAM The original storage engine. See hundefinedi[ISAM],
page hundefinedi.
InnoDB Transaction-safe tables with row locking. See hundefinedi
[InnoDB], page hundefinedi.
MERGE A collection of MyISAM tables used as one table. See hunde-
finedi[MERGE], page hundefinedi.
MRG MyISAM An alias for MERGE tables
MyISAM The new binary portable storage engine that is replacing
ISAM. See hundefinedi[MyISAM], page hundefinedi.
See hundefinedi[Table types], page hundefinedi.
If a table type is specified, and that particular type is not available, MySQL will choose
the closest table type to the one that you have specified. For example, if TYPE=BDB is
specified, and that distribution of MySQL does not support BDB tables, the table will
be created as MyISAM instead.
The other table options are used to optimise the behaviour of the table. In most cases,
you don’t have to specify any of them. The options work for all table types, if not
otherwise indicated:
Option Description
AUTO_INCREMENT The next AUTO_INCREMENT value you want to set for your table
(MyISAM).
AVG_ROW_LENGTH An approximation of the average row length for your table.
You only need to set this for large tables with variable size
records.
CHECKSUM Set this to 1 if you want MySQL to maintain a checksum for
all rows (makes the table a little slower to update but makes
it easier to find corrupted tables) (MyISAM).
COMMENT A 60-character comment for your table.
MAX_ROWS Max number of rows you plan to store in the table.
MIN_ROWS Minimum number of rows you plan to store in the table.
PACK_KEYS Set this to 1 if you want to have a smaller index. This usu-
ally makes updates slower and reads faster (MyISAM, ISAM).
Setting this to 0 will disable all packing of keys. Setting this
to DEFAULT (MySQL 4.0) will tell the storage engine to only
pack long CHAR/VARCHAR columns.
Chapter 6: Referˆencia de Linguagem do MySQL 471
PASSWORD Encrypt the ‘.frm’ file with a password. This option doesn’t
do anything in the standard MySQL version.
DELAY_KEY_WRITE Set this to 1 if want to delay key table updates until the table
is closed (MyISAM).
ROW_FORMAT Defines how the rows should be stored. Currently this option
only works with MyISAM tables, which supports the DYNAMIC
and FIXED row formats. See hundefinedi[MyISAM table for-
mats], page hundefinedi.
When you use a MyISAM table, MySQL uses the product of max_rows * avg_row_
length to decide how big the resulting table will be. If you don’t specify any of
the above options, the maximum size for a table will be 4G (or 2G if your operating
systems only supports 2G tables). The reason for this is just to keep down the pointer
sizes to make the index smaller and faster if you don’t really need big files.
If you don’t use PACK_KEYS, the default is to only pack strings, not numbers. If you
use PACK_KEYS=1, numbers will be packed as well.
When packing binary number keys, MySQL will use prefix compression. This means
that you will only get a big benefit of this if you have many numbers that are the same.
Prefix compression means that every key needs one extra byte to indicate how many
bytes of the previous key are the same for the next key (note that the pointer to the
row is stored in high-byte-first-order directly after the key, to improve compression).
This means that if you have many equal keys on two rows in a row, all following ’same’
keys will usually only take 2 bytes (including the pointer to the row). Compare this to
the ordinary case where the following keys will take storage size for key +pointer size
(usually 4). On the other hand, if all keys are totally different, you will lose 1 byte
per key, if the key isn’t a key that can have NULL values. (In this case the packed key
length will be stored in the same byte that is used to mark if a key is NULL.)
If you specify a SELECT after the CREATE statement, MySQL will create new fields for
all elements in the SELECT. For example:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> TYPE=MyISAM SELECT b,c FROM test2;
This will create a MyISAM table with three columns, a, b, and c. Notice that the columns
from the SELECT statement are appended to the right side of the table, not overlapped
onto it. Take the following example:
mysql> SELECT * FROM foo;
+---+
|n|
+---+
|1|
+---+
mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM bar;
+------+---+
472 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
|m |n|
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)
For each row in table foo, a row is inserted in bar with the values from foo and default
values for the new columns.
CREATE TABLE ... SELECT will not automatically create any indexes for you. This is
done intentionally to make the command as flexible as possible. If you want to have
indexes in the created table, you should specify these before the SELECT statement:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
If any errors occur while copying the data to the table, it will automatically be deleted.
To ensure that the update log/binary log can be used to re-create the original tables,
MySQL will not allow concurrent inserts during CREATE TABLE ... SELECT.
The RAID_TYPE option will help you to break the 2G/4G limit for the MyISAM datafile
(not the index file) on operating systems that don’t support big files. Note that this
option is not recommended for filesystem that supports big files!
You can get more speed from the I/O bottleneck by putting RAID directories on different
physical disks. RAID_TYPE will work on any OS, as long as you have configured MySQL
with --with-raid. For now the only allowed RAID_TYPE is STRIPED (1and RAID0 are
aliases for this).
If you specify RAID_TYPE=STRIPED for a MyISAM table, MyISAM will create RAID_CHUNKS
subdirectories named 00, 01, 02 in the database directory. In each of these directories
MyISAM will create a table_name.MYD. When writing data to the datafile, the RAID
handler will map the first RAID_CHUNKSIZE *1024 bytes to the first file, the next RAID_
CHUNKSIZE *1024 bytes to the next file and so on.
UNION is used when you want to use a collection of identical tables as one. This only
works with MERGE tables. See hundefinedi[MERGE], page hundefinedi.
For the moment you need to have SELECT,UPDATE, and DELETE privileges on the tables
you map to a MERGE table. All mapped tables must be in the same database as the
MERGE table.
If you want to insert data in a MERGE table, you have to specify with INSERT_METHOD into
with table the row should be inserted. See hundefinedi[MERGE], page hundefinedi.
This option was introduced in MySQL 4.0.0.
In the created table the PRIMARY key will be placed first, followed by all UNIQUE keys
and then the normal keys. This helps the MySQL optimiser to prioritise which key to
use and also more quickly detect duplicated UNIQUE keys.
By using DATA DIRECTORY="directory" or INDEX DIRECTORY="directory" you can
specify where the storage engine should put it’s table and index files. Note that the
directory should be a full path to the directory (not relative path).
This only works for MyISAM tables in MySQL 4.0, when you are not using the --skip-
symlink option. See hundefinedi[Symbolic links to tables], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 473
6.5.3.1 Silent Column Specification Changes
In some cases, MySQL silently changes a column specification from that given in a CREATE
TABLE statement. (This may also occur with ALTER TABLE.):
VARCHAR columns with a length less than four are changed to CHAR.
If any column in a table has a variable length, the entire row is variable-length as a
result. Therefore, if a table contains any variable-length columns (VARCHAR,TEXT, or
BLOB), all CHAR columns longer than three characters are changed to VARCHAR columns.
This doesn’t affect how you use the columns in any way; in MySQL, VARCHAR is just
a different way to store characters. MySQL performs this conversion because it saves
space and makes table operations faster. See hundefinedi[Table types], page hunde-
finedi.
TIMESTAMP display sizes must be even and in the range from 2 to 14. If you specify a
display size of 0 or greater than 14, the size is coerced to 14. Odd-valued sizes in the
range from 1 to 13 are coerced to the next higher even number.
You cannot store a literal NULL in a TIMESTAMP column; setting it to NULL sets it to the
current date and time. Because TIMESTAMP columns behave this way, the NULL and NOT
NULL attributes do not apply in the normal way and are ignored if you specify them.
DESCRIBE nome_tabela always reports that a TIMESTAMP column may be assigned NULL
values.
MySQL maps certain column types used by other SQL database vendors to MySQL
types. See vendor column types-snt [Other-vendor column types], page vendor column
types-pg.
If you want to see whether MySQL used a column type other than the one you specified,
issue a DESCRIBE nome_tabela statement after creating or altering your table.
Certain other column type changes may occur if you compress a table using myisampack.
See hundefinedi[Compressed format], page hundefinedi.
6.5.4 ALTER TABLE Syntax
ALTER [IGNORE] TABLE nome_tabela alter_spec [, alter_spec ...]
alter_specification:
ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
or ADD [COLUMN] (create_definition, create_definition,...)
or ADD INDEX [index_name] (index_nome_coluna,...)
or ADD PRIMARY KEY (index_nome_coluna,...)
or ADD UNIQUE [index_name] (index_nome_coluna,...)
or ADD FULLTEXT [index_name] (index_nome_coluna,...)
or ADD [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_nome_coluna,...)
[reference_definition]
or ALTER [COLUMN] nome_coluna {SET DEFAULT literal | DROP DEFAULT}
or CHANGE [COLUMN] old_nome_coluna create_definition
[FIRST | AFTER column_name]
or MODIFY [COLUMN] create_definition [FIRST | AFTER column_name]
or DROP [COLUMN] nome_coluna
or DROP PRIMARY KEY
474 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
or DROP INDEX index_name
or DISABLE KEYS
or ENABLE KEYS
or RENAME [TO] new_nome_tabela
or ORDER BY col
or table_options
ALTER TABLE allows you to change the structure of an existing table. For example, you can
add or delete columns, create or destroy indexes, change the type of existing columns, or
rename columns or the table itself. You can also change the comment for the table and
type of the table. See hundefinedi[CREATE TABLE], page hundefinedi.
If you use ALTER TABLE to change a column specification but DESCRIBE nome_tabela indi-
cates that your column was not changed, it is possible that MySQL ignored your modifi-
cation for one of the reasons described in hundefinedi[Silent column changes], page hunde-
finedi. For example, if you try to change a VARCHAR column to CHAR, MySQL will still use
VARCHAR if the table contains other variable-length columns.
ALTER TABLE works by making a temporary copy of the original table. The alteration is
performed on the copy, then the original table is deleted and the new one is renamed. This
is done in such a way that all updates are automatically redirected to the new table without
any failed updates. While ALTER TABLE is executing, the original table is readable by other
clients. Updates and writes to the table are stalled until the new table is ready.
Note that if you use any other option to ALTER TABLE than RENAME, MySQL will always
create a temporary table, even if the data wouldn’t strictly need to be copied (like when you
change the name of a column). We plan to fix this in the future, but as one doesn’t normally
do ALTER TABLE that often this isn’t that high on our TODO. For MyISAM tables, you can
speed up the index recreation part (which is the slowest part of the recreation process) by
setting the myisam_sort_buffer_size variable to a high value.
To use ALTER TABLE, you need ALTER,INSERT, and CREATE privileges on the table.
IGNORE is a MySQL extension to SQL-92. It controls how ALTER TABLE works if there
are duplicates on unique keys in the new table. If IGNORE isn’t specified, the copy is
aborted and rolled back. If IGNORE is specified, then for rows with duplicates on a
unique key, only the first row is used; the others are deleted.
You can issue multiple ADD,ALTER,DROP, and CHANGE clauses in a single ALTER TABLE
statement. This is a MySQL extension to SQL-92, which allows only one of each clause
per ALTER TABLE statement.
CHANGE nome_coluna,DROP nome_coluna, and DROP INDEX are MySQL extensions to
SQL-92.
MODIFY is an Oracle extension to ALTER TABLE.
The optional word COLUMN is a pure noise word and can be omitted.
If you use ALTER TABLE nome_tabela RENAME TO new_name without any other options,
MySQL simply renames the files that correspond to the table nome_tabela. There is no
need to create the temporary table. See hundefinedi[RENAME TABLE], page hundefinedi.
create_definition clauses use the same syntax for ADD and CHANGE as for CREATE
TABLE. Note that this syntax includes the column name, not just the column type. See
hundefinedi[CREATE TABLE], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 475
You can rename a column using a CHANGE old_nome_coluna create_definition
clause. To do so, specify the old and new column names and the type that the column
currently has. For example, to rename an INTEGER column from ato b, you can do
this:
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
If you want to change a column’s type but not the name, CHANGE syntax still requires
two column names even if they are the same. For example:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
However, as of MySQL Version 3.22.16a, you can also use MODIFY to change a column’s
type without renaming it:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
If you use CHANGE or MODIFY to shorten a column for which an index exists on part of
the column (for instance, if you have an index on the first 10 characters of a VARCHAR
column), you cannot make the column shorter than the number of characters that are
indexed.
When you change a column type using CHANGE or MODIFY, MySQL tries to convert data
to the new type as well as possible.
In MySQL Version 3.22 or later, you can use FIRST or ADD ... AFTER nome_coluna to
add a column at a specific position within a table row. The default is to add the column
last. From MySQL Version 4.0.1, you can also use the FIRST and AFTER keywords in
CHANGE or MODIFY.
ALTER COLUMN specifies a new default value for a column or removes the old default
value. If the old default is removed and the column can be NULL, the new default is
NULL. If the column cannot be NULL, MySQL assigns a default value, as described in
hundefinedi[CREATE TABLE], page hundefinedi.
DROP INDEX removes an index. This is a MySQL extension to SQL-92. See hundefinedi
[DROP INDEX], page hundefinedi.
If columns are dropped from a table, the columns are also removed from any index of
which they are a part. If all columns that make up an index are dropped, the index is
dropped as well.
If a table contains only one column, the column cannot be dropped. If what you intend
is to remove the table, use DROP TABLE instead.
DROP PRIMARY KEY drops the primary index. If no such index exists, it drops the first
UNIQUE index in the table. (MySQL marks the first UNIQUE key as the PRIMARY KEY if
no PRIMARY KEY was specified explicitly.)
If you add a UNIQUE INDEX or PRIMARY KEY to a table, this is stored before any not
UNIQUE index so that MySQL can detect duplicate keys as early as possible.
ORDER BY allows you to create the new table with the rows in a specific order. Note
that the table will not remain in this order after inserts and deletes. In some cases, it
may make sorting easier for MySQL if the table is in order by the column that you wish
to order it by later. This option is mainly useful when you know that you are mostly
going to query the rows in a certain order; by using this option after big changes to
the table, you may be able to get higher performance.
476 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
If you use ALTER TABLE on a MyISAM table, all non-unique indexes are created in a
separate batch (like in REPAIR). This should make ALTER TABLE much faster when you
have many indexes.
Since MySQL 4.0 the above feature can be activated explicitly. ALTER TABLE ...
DISABLE KEYS makes MySQL to stop updating non-unique indexes for MyISAM table.
ALTER TABLE ... ENABLE KEYS then should be used to recreate missing indexes. As
MySQL does it with special algorithm which is much faster then inserting keys one by
one, disabling keys could give a considerable speedup on bulk inserts.
With the C API function mysql_info(), you can find out how many records were
copied, and (when IGNORE is used) how many records were deleted due to duplication
of unique key values.
The FOREIGN KEY,CHECK, and REFERENCES clauses don’t actually do anything,
except for InnoDB type tables which support ADD CONSTRAINT FOREIGN KEY (...)
REFERENCES ... (...). Note that InnoDB does not allow an index_name to be
specified. See hundefinedi[InnoDB], page hundefinedi. The syntax for other table
types is provided only for compatibility, to make it easier to port code from other SQL
servers and to run applications that create tables with references. See hundefinedi
[Differences from ANSI], page hundefinedi.
Here is an example that shows some of the uses of ALTER TABLE. We begin with a table t1
that is created as shown here:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
To rename the table from t1 to t2:
mysql> ALTER TABLE t1 RENAME t2;
To change column afrom INTEGER to TINYINT NOT NULL (leaving the name the same), and
to change column bfrom CHAR(10) to CHAR(20) as well as renaming it from bto c:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
To add a new TIMESTAMP column named d:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
To add an index on column d, and make column athe primary key:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
To remove column c:
mysql> ALTER TABLE t2 DROP COLUMN c;
To add a new AUTO_INCREMENT integer column named c:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (c);
Note that we indexed c, because AUTO_INCREMENT columns must be indexed, and also that
we declare cas NOT NULL, because indexed columns cannot be NULL.
When you add an AUTO_INCREMENT column, column values are filled in with sequence num-
bers for you automatically. You can set the first sequence number by executing SET INSERT_
ID=# before ALTER TABLE or using the AUTO_INCREMENT = # table option. See hundefinedi
[SET OPTION], page hundefinedi.
Chapter 6: Referˆencia de Linguagem do MySQL 477
With MyISAM tables, if you don’t change the AUTO_INCREMENT column, the sequence num-
ber will not be affected. If you drop an AUTO_INCREMENT column and then add another
AUTO_INCREMENT column, the numbers will start from 1 again.
See hundefinedi[ALTER TABLE problems], page hundefinedi.
6.5.5 RENAME TABLE Syntax
RENAME TABLE nome_tabela TO new_nome_tabela[, nome_tabela2 TO new_tbl_name2,...]
The rename is done atomically, which means that no other thread can access any of the
tables while the rename is running. This makes it possible to replace a table with an empty
one:
CREATE TABLE new_table (...);
RENAME TABLE old_table TO backup_table, new_table TO old_table;
The rename is done from left to right, which means that if you want to swap two tables
names, you have to:
RENAME TABLE old_table TO backup_table,
new_table TO old_table,
backup_table TO new_table;
As long as two databases are on the same disk you can also rename from one database to
another:
RENAME TABLE current_db.nome_tabela TO other_db.nome_tabela;
When you execute RENAME, you can’t have any locked tables or active transactions. You
must also have the ALTER and DROP privileges on the original table, and the CREATE and
INSERT privileges on the new table.
If MySQL encounters any errors in a multiple-table rename, it will do a reverse rename for
all renamed tables to get everything back to the original state.
RENAME TABLE was added in MySQL 3.23.23.
6.5.6 DROP TABLE Syntax
DROP [TEMPORARY] TABLE [IF EXISTS] nome_tabela [, nome_tabela,...] [RESTRICT | CASCADE]
DROP TABLE removes one or more tables. All table data and the table definition are removed,
so be careful with this command!
In MySQL Version 3.22 or later, you can use the keywords IF EXISTS to prevent an error
from occurring for tables that don’t exist. In 4.1 one gets a NOTE for all not existing tables
when using IF EXISTS. See hundefinedi[SHOW WARNINGS], page hundefinedi.
RESTRICT and CASCADE are allowed to make porting easier. For the moment they don’t do
anything.
Note:DROP TABLE will automatically commit current active transaction (except if you are
using 4.1 and the TEMPORARY key word.
Option TEMPORARY is ignored in 4.0. In 4.1 this option works as follows:
Only drops temporary tables.
It doesn’t end a running transactions.
No access rights is checked.
Using TEMPORARY is a good way to ensure that you don’t accidently drop a real table.
478 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
6.5.7 CREATE INDEX Syntax
CREATE [UNIQUE|FULLTEXT] INDEX index_name
ON nome_tabela (nome_coluna[(length)],... )
The CREATE INDEX statement doesn’t do anything in MySQL prior to Version 3.22. In
Version 3.22 or later, CREATE INDEX is mapped to an ALTER TABLE statement to create
indexes. See hundefinedi[ALTER TABLE], page hundefinedi.
Normally, you create all indexes on a table at the time the table itself is created with CREATE
TABLE. See hundefinedi[CREATE TABLE], page hundefinedi.CREATE INDEX allows you to add
indexes to existing tables.
A column list of the form (col1,col2,...) creates a multiple-column index. Index values
are formed by concatenating the values of the given columns.
For CHAR and VARCHAR columns, indexes can be created that use only part of a column,
using nome_coluna(length) syntax. (On BLOB and TEXT columns the length is required.)
The statement shown here creates an index using the first 10 characters of the name column:
mysql> CREATE INDEX part_of_name ON customer (name(10));
Because most names usually differ in the first 10 characters, this index should not be much
slower than an index created from the entire name column. Also, using partial columns
for indexes can make the index file much smaller, which could save a lot of disk space and
might also speed up INSERT operations!
Note that you can only add an index on a column that can have NULL values or on a
BLOB/TEXT column if you are using MySQL Version 3.23.2 or newer and are using the
MyISAM table type.
For more information about how MySQL uses indexes, see hundefinedi[MySQL indexes],
page hundefinedi.
FULLTEXT indexes can index only VARCHAR and TEXT columns, and only in MyISAM tables.
FULLTEXT indexes are available in MySQL Version 3.23.23 and later. hundefinedi[Fulltext
Search], page hundefinedi.
6.5.8 DROP INDEX Syntax
DROP INDEX index_name ON nome_tabela
DROP INDEX drops the index named index_name from the table nome_tabela.DROP INDEX
doesn’t do anything in MySQL prior to Version 3.22. In Version 3.22 or later, DROP INDEX
is mapped to an ALTER TABLE statement to drop the index. See hundefinedi[ALTER TABLE],
page hundefinedi.
6.6 Basic MySQL User Utility Commands
6.6.1 USE Syntax
USE db_name
The USE db_name statement tells MySQL to use the db_name database as the default
database for subsequent queries. The database remains current until the end of the session
or until another USE statement is issued:
Chapter 6: Referˆencia de Linguagem do MySQL 479
mysql> USE db1;
mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable
mysql> USE db2;
mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
Making a particular database current by means of the USE statement does not preclude you
from accessing tables in other databases. The following example accesses the author table
from the db1 database and the editor table from the db2 database:
mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
-> WHERE author.editor_id = db2.editor.editor_id;
The USE statement is provided for Sybase compatibility.
6.6.2 DESCRIBE Syntax (Get Information About Columns)
{DESCRIBE | DESC} nome_tabela [nome_coluna | wild]
DESCRIBE is a shortcut for SHOW COLUMNS FROM. See hundefinedi[SHOW DATABASE
INFO], page hundefinedi.
DESCRIBE provides information about a table’s columns. nome_coluna may be a column
name or a string containing the SQL ‘%’ and ‘_’ wildcard characters. There is no need to
enclose the string in quotes.
If the column types are different from what you expect them to be based on a CREATE
TABLE statement, note that MySQL sometimes changes column types. See hundefinedi
[Silent column changes], page hundefinedi.
This statement is provided for Oracle compatibility.
The SHOW statement provides similar information. See hundefinedi[SHOW], page hundefinedi.
6.7 MySQL Transactional and Locking Commands
6.7.1 BEGIN/COMMIT/ROLLBACK Syntax
By default, MySQL runs in autocommit mode. This means that as soon as you execute an
update, MySQL will store the update on disk.
If you are using transactions safe tables (like InnoDB,BDB, you can put MySQL into non-
autocommit mode with the following command:
SET AUTOCOMMIT=0
After this you must use COMMIT to store your changes to disk or ROLLBACK if you want to
ignore the changes you have made since the beginning of your transaction.
If you want to switch from AUTOCOMMIT mode for one series of statements, you can use the
START TRANSACTION or BEGIN or BEGIN WORK statement:
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summmary=@A WHERE type=1;
COMMIT;
START TRANSACTION was added to MySQL 4.0.11; This is the recommended way to start an
ad-hoc transaction as this is SQL-99 syntax,
480 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note that if you are using non-transaction-safe tables, the changes will be stored at once,
independent of the status of the autocommit mode.
If you do a ROLLBACK when you have updated a non-transactional table you will get an
error (ER_WARNING_NOT_COMPLETE_ROLLBACK) as a warning. All transaction-safe tables will
be restored but any non-transaction-safe table will not change.
If you are using START TRANSACTION or SET AUTOCOMMIT=0, you should use the MySQL
binary log for backups instead of the older update log. Transactions are stored in the
binary log in one chunk, upon COMMIT, to ensure that transactions which are rolled back
are not stored. See hundefinedi[Binary log], page hundefinedi.
The following commands automatically end a transaction (as if you had done a COMMIT
before executing the command):
Command Command Command
ALTER TABLE BEGIN CREATE INDEX
DROP DATABASE DROP TABLE RENAME TABLE
TRUNCATE
You can change the isolation level for transactions with SET TRANSACTION ISOLATION LEVEL
.... See hundefinedi[SET TRANSACTION], page hundefinedi.
6.7.2 LOCK TABLES/UNLOCK TABLES Syntax
LOCK TABLES nome_tabela [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, nome_tabela [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES
LOCK TABLES locks tables for the current thread. UNLOCK TABLES releases any locks held
by the current thread. All tables that are locked by the current thread are automatically
unlocked when the thread issues another LOCK TABLES, or when the connection to the server
is closed.
To use LOCK TABLES in MySQL 4.0.2 you need the global LOCK TABLES privilege and a
SELECT privilege on the involved tables. In MySQL 3.23 you need to have SELECT,insert,
DELETE and UPDATE privileges for the tables.
The main reasons to use LOCK TABLES are for emulating transactions or getting more speed
when updating tables. This is explained in more detail later.
If a thread obtains a READ lock on a table, that thread (and all other threads) can only read
from the table. If a thread obtains a WRITE lock on a table, then only the thread holding
the lock can read from or write to the table. Other threads are blocked.
The difference between READ LOCAL and READ is that READ LOCAL allows non-conflicting
INSERT statements to execute while the lock is held. This can’t however be used if you are
going to manipulate the database files outside MySQL while you hold the lock.
When you use LOCK TABLES, you must lock all tables that you are going to use and you
must use the same alias that you are going to use in your queries! If you are using a table
multiple times in a query (with aliases), you must get a lock for each alias!
WRITE locks normally have higher priority than READ locks, to ensure that updates are
processed as soon as possible. This means that if one thread obtains a READ lock and then
another thread requests a WRITE lock, subsequent READ lock requests will wait until the
Chapter 6: Referˆencia de Linguagem do MySQL 481
WRITE thread has gotten the lock and released it. You can use LOW_PRIORITY WRITE locks
to allow other threads to obtain READ locks while the thread is waiting for the WRITE lock.
You should only use LOW_PRIORITY WRITE locks if you are sure that there will eventually
be a time when no threads will have a READ lock.
LOCK TABLES works as follows:
1. Sort all tables to be locked in a internally defined order (from the user standpoint the
order is undefined).
2. If a table is locked with a read and a write lock, put the write lock before the read lock.
3. Lock one table at a time until the thread gets all locks.
This policy ensures that table locking is deadlock free. There is however other things one
needs to be aware of with this schema:
If you are using a LOW_PRIORITY WRITE lock for a table, this means only that MySQL will
wait for this particlar lock until there is no threads that wants a READ lock. When the
thread has got the WRITE lock and is waiting to get the lock for the next table in the lock
table list, all other threads will wait for the WRITE lock to be released. If this becomes a
serious problem with your application, you should consider converting some of your tables
to transactions safe tables.
You can safely kill a thread that is waiting for a table lock with KILL. See hundefinedi
[KILL], page hundefinedi.
Note that you should not lock any tables that you are using with INSERT DELAYED. This is
because that in this case the INSERT is done by a separate thread.
Normally, you don’t have to lock tables, as all single UPDATE statements are atomic; no
other thread can interfere with any other currently executing SQL statement. There are a
few cases when you would like to lock tables anyway:
If you are going to run many operations on a bunch of tables, it’s much faster to lock
the tables you are going to use. The downside is, of course, that no other thread can
update a READ-locked table and no other thread can read a WRITE-locked table.
The reason some things are faster under LOCK TABLES is that MySQL will not flush the
key cache for the locked tables until UNLOCK TABLES is called (normally the key cache
is flushed after each SQL statement). This speeds up inserting/updateing/deletes on
MyISAM tables.
If you are using a storage engine in MySQL that doesn’t support transactions, you
must use LOCK TABLES if you want to ensure that no other thread comes between a
SELECT and an UPDATE. The example shown here requires LOCK TABLES in order to
execute safely:
mysql> LOCK TABLES trans READ, customer WRITE;
mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;
mysql> UPDATE customer SET total_value=sum_from_previous_statement
-> WHERE customer_id=some_id;
mysql> UNLOCK TABLES;
Without LOCK TABLES, there is a chance that another thread might insert a new row
in the trans table between execution of the SELECT and UPDATE statements.
By using incremental updates (UPDATE customer SET value=value+new_value) or the
LAST_INSERT_ID() function, you can avoid using LOCK TABLES in many cases.
482 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
You can also solve some cases by using the user-level lock functions GET_LOCK() and
RELEASE_LOCK(). These locks are saved in a hash table in the server and implemented
with pthread_mutex_lock() and pthread_mutex_unlock() for high speed. See hunde-
finedi[Miscellaneous functions], page hundefinedi.
See hundefinedi[Internal locking], page hundefinedi, for more information on locking policy.
You can lock all tables in all databases with read locks with the FLUSH TABLES WITH READ
LOCK command. See hundefinedi[FLUSH], page hundefinedi. This is very convenient way
to get backups if you have a filesystem, like Veritas, that can take snapshots in time.
NOTE:LOCK TABLES is not transaction-safe and will automatically commit any active trans-
actions before attempting to lock the tables.
6.7.3 SET TRANSACTION Syntax
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Sets the transaction isolation level for the global, whole session or the next transaction.
The default behaviour is to set the isolation level for the next (not started) transaction. If
you use the GLOBAL keyword, the statement sets the default transaction level globally for all
new connections created from that point on. You will need the SUPER privilege to do this.
Using the SESSION keyword sets the default transaction level for all future transactions
performed on the current connection.
You can set the default global isolation level for mysqld with --transaction-
isolation=.... See line options-snt [Command-line options], page line options-pg.
6.8 MySQL Full-text Search
As of Version 3.23.23, MySQL has support for full-text indexing and searching. Full-text
indexes in MySQL are an index of type FULLTEXT.FULLTEXT indexes are used with MyISAM
tables and can be created from CHAR,VARCHAR, or TEXT columns at CREATE TABLE time or
added later with ALTER TABLE or CREATE INDEX. For large datasets, it will be much faster
to load your data into a table that has no FULLTEXT index, then create the index with ALTER
TABLE (or CREATE INDEX). Loading data into a table that already has a FULLTEXT index
will be slower.
Full-text searching is performed with the MATCH() function.
mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO articles VALUES
-> (NULL,’MySQL Tutorial’, ’DBMS stands for DataBase ...’),
-> (NULL,’How To Use MySQL Efficiently’, ’After you went through a ...’),
-> (NULL,’Optimising MySQL’,’In this tutorial we will show ...’),
Chapter 6: Referˆencia de Linguagem do MySQL 483
-> (NULL,’1001 MySQL Tricks’,’1. Never run mysqld as root. 2. ...’),
-> (NULL,’MySQL vs. YourSQL’, ’In the following database comparison ...’),
-> (NULL,’MySQL Security’, ’When configured properly, MySQL ...’);
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM articles
-> WHERE MATCH (title,body) AGAINST (’database’);
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
The MATCH() function performs a natural language search for a string against a text col-
lection (a set of one or more columns included in a FULLTEXT index). The search string is
given as the argument to AGAINST(). The search is performed in case-insensitive fashion.
For every row in the table, MATCH() returns a relevance value, that is, a similarity measure
between the search string and the text in that row in the columns named in the MATCH()
list.
When MATCH() is used in a WHERE clause (see example above) the rows returned are automat-
ically sorted with highest relevance first. Relevance values are non-negative floating-point
numbers. Zero relevance means no similarity. Relevance is computed based on the number
of words in the row, the number of unique words in that row, the total number of words in
the collection, and the number of documents (rows) that contain a particular word.
It is also possible to perform a boolean mode search. This is explained later in the section.
The preceding example is a basic illustration showing how to use the MATCH() function.
Rows are returned in order of decreasing relevance.
The next example shows how to retrieve the relevance values explicitly. As neither WHERE
nor ORDER BY clauses are present, returned rows are not ordered.
mysql> SELECT id,MATCH (title,body) AGAINST (’Tutorial’) FROM articles;
+----+-----------------------------------------+
| id | MATCH (title,body) AGAINST (’Tutorial’) |
+----+-----------------------------------------+
| 1 | 0.64840710366884 |
| 2 | 0 |
| 3 | 0.66266459031789 |
| 4 | 0 |
| 5 | 0 |
| 6 | 0 |
+----+-----------------------------------------+
6 rows in set (0.00 sec)
The following example is more complex. The query returns the relevance and still sorts the
rows in order of decreasing relevance. To achieve this result, you should specify MATCH()
twice. This will cause no additional overhead, because the MySQL optimiser will notice
that the two MATCH() calls are identical and invoke the full-text search code only once.
484 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT id, body, MATCH (title,body) AGAINST
-> (’Security implications of running MySQL as root’) AS score
-> FROM articles WHERE MATCH (title,body) AGAINST
-> (’Security implications of running MySQL as root’);
+----+-------------------------------------+-----------------+
| id | body | score |
+----+-------------------------------------+-----------------+
| 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 |
| 6 | When configured properly, MySQL ... | 1.31140957288 |
+----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)
MySQL uses a very simple parser to split text into words. A “word” is any sequence
of characters consisting of letters, digits, ’, and ‘_’. Any “word” that is present in the
stopword list or is just too short (3 characters or less) is ignored.
Every correct word in the collection and in the query is weighted according to its significance
in the query or collection. This way, a word that is present in many documents will have
lower weight (and may even have a zero weight), because it has lower semantic value in this
particular collection. Otherwise, if the word is rare, it will receive a higher weight. The
weights of the words are then combined to compute the relevance of the row.
Such a technique works best with large collections (in fact, it was carefully tuned this way).
For very small tables, word distribution does not reflect adequately their semantic value,
and this model may sometimes produce bizarre results.
mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST (’MySQL’);
Empty set (0.00 sec)
The search for the word MySQL produces no results in the above example, because that word
is present in more than half the rows. As such, it is effectively treated as a stopword (that
is, a word with zero semantic value). This is the most desirable behaviour -- a natural
language query should not return every second row from a 1 GB table.
A word that matches half of rows in a table is less likely to locate relevant documents.
In fact, it will most likely find plenty of irrelevant documents. We all know this happens
far too often when we are trying to find something on the Internet with a search engine.
It is with this reasoning that such rows have been assigned a low semantic value in this
particular dataset.
As of Version 4.0.1, MySQL can also perform boolean full-text searches using the IN
BOOLEAN MODE modifier.
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST (’+MySQL -YourSQL’ IN BOOLEAN MODE);
+----+------------------------------+----------------------------------
---+
| id | title | body |
+----+------------------------------+----------------------------------
---+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 2 | How To Use MySQL Efficiently | After you went through a ... |
| 3 | Optimising MySQL | In this tutorial we will show ... |
| 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... |
Chapter 6: Referˆencia de Linguagem do MySQL 485
| 6 | MySQL Security | When configured properly, MySQL ... |
+----+------------------------------+----------------------------------
---+
This query retrieved all the rows that contain the word MySQL (note: the 50% threshold is
not used), but that do not contain the word YourSQL. Note that a boolean mode search does
not automatically sort rows in order of decreasing relevance. You can see this from result
of the preceding query, where the row with the highest relevance (the one that contains
MySQL twice) is listed last, not first. A boolean full-text search can also work even without
aFULLTEXT index, although it would be slow.
The boolean full-text search capability supports the following operators:
+A leading plus sign indicates that this word must be present in every row
returned.
-A leading minus sign indicates that this word must not be present in any row
returned.
By default (when neither plus nor minus is specified) the word is optional, but
the rows that contain it will be rated higher. This mimicks the behaviour of
MATCH() ... AGAINST() without the IN BOOLEAN MODE modifier.
< > These two operators are used to change a word’s contribution to the relevance
value that is assigned to a row. The <operator decreases the contribution and
the >operator increases it. See the example below.
( ) Parentheses are used to group words into subexpressions.
~A leading tilde acts as a negation operator, causing the word’s contribution
to the row relevance to be negative. It’s useful for marking noise words. A
row that contains such a word will be rated lower than others, but will not be
excluded altogether, as it would be with the -operator.
*An asterisk is the truncation operator. Unlike the other operators, it should be
appended to the word, not prepended.
"The phrase, that is enclosed in double quotes ", matches only rows that contain
this phrase literally, as it was typed.
And here are some examples:
apple banana
find rows that contain at least one of these words.
+apple +juice
... both words.
+apple macintosh
... word “apple”, but rank it higher if it also contain “macintosh”.
+apple -macintosh
... word “apple” but not “macintosh”.
+apple +(>pie <strudel)
... “apple” and “pie”, or “apple” and “strudel” (in any order), but rank “apple
pie” higher than “apple strudel”.
486 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
apple* ... “apple”, “apples”, “applesauce”, and “applet”.
"some words"
... “some words of wisdom”, but not “some noise words”.
6.8.1 Full-text Restrictions
All parameters to the MATCH() function must be columns from the same table that is
part of the same FULLTEXT index, unless the MATCH() is IN BOOLEAN MODE.
The MATCH() column list must exactly match the column list in some FULLTEXT index
definition for the table, unless this MATCH() is IN BOOLEAN MODE.
The argument to AGAINST() must be a constant string.
6.8.2 Fine-tuning MySQL Full-text Search
Unfortunately, full-text search has few user-tunable parameters yet, although adding some
is very high on the TODO. If you have a MySQL source distribution (see hundefinedi
[Installing source], page hundefinedi), you can exert more control over full-text searching
behaviour.
Note that full-text search was carefully tuned for the best searching effectiveness. Modifying
the default behaviour will, in most cases, only make the search results worse. Do not alter
the MySQL sources unless you know what you are doing!
The minimum length of words to be indexed is defined by the MySQL variable ft_
min_word_len. See hundefinedi[ft_min_word_len], page hundefinedi. Change it to
the value you prefer, and rebuild your FULLTEXT indexes. (This variable is only available
from MySQL version 4.0.)
The stopword list can be loaded from file specified by ft_stopword_file variable. See
hundefinedi[ft_stopword_file], page hundefinedi. Rebuild your FULLTEXT indexes
after modifying the stopword list. (This variable is only available from MySQL version
4.0.10 and onwards)
The 50% threshold is determined by the particular weighting scheme chosen. To disable
it, change the following line in ‘myisam/ftdefs.h’:
#define GWS_IN_USE GWS_PROB
To:
#define GWS_IN_USE GWS_FREQ
Then recompile MySQL. There is no need to rebuild the indexes in this case. Note: by
doing this you severely decrease MySQL’s ability to provide adequate relevance values
for the MATCH() function. If you really need to search for such common words, it would
be better to search using IN BOOLEAN MODE instead, which does not observe the 50%
threshold.
Sometimes the search engine maintainer would like to change the operators used for
boolean full-text searches. These are defined by the ft_boolean_syntax variable. See
hundefinedi[ft_boolean_syntax], page hundefinedi. Still, this variable is read-only,
its value is set in ‘myisam/ft_static.c’.
For those changes that require you to rebuild your FULLTEXT indexes, the easiest way to do
so for a MyISAM table is to use the following statement, which rebuilds the index file:
Chapter 6: Referˆencia de Linguagem do MySQL 487
mysql> REPAIR TABLE nome_tabela QUICK;
6.8.3 Full-text Search TODO
Make all operations with FULLTEXT index faster.
Proximity operators
Support for "always-index words". They could be any strings the user wants to treat
as words, examples are "C++","AS/400","TCP/IP", etc.
Support for full-text search in MERGE tables.
Support for multi-byte charsets.
Make stopword list to depend of the language of the data.
Stemming (dependent of the language of the data, of course).
Generic user-suppliable UDF preparser.
Make the model more flexible (by adding some adjustable parameters to FULLTEXT in
CREATE/ALTER TABLE).
6.9 MySQL Query Cache
From version 4.0.1, MySQL server features a Query Cache. When in use, the query cache
stores the text of a SELECT query together with the corresponding result that was sent to
the client. If an identical query is later received, the server will retrieve the results from
the query cache rather than parsing and executing the same query again.
NOTE: The query cache does not return stale data. When data is modified, any relevant
entries in the query cache are flushed.
The query cache is extremely useful in an environment where (some) tables don’t change
very often and you have a lot of identical queries. This is a typical situation for many web
servers that use a lot of dynamic content.
Below is some performance data for the query cache. (These results were generated by
running the MySQL benchmark suite on a Linux Alpha 2 x 500 MHz with 2 GB RAM and
a 64 MB query cache):
If all of the queries you’re performing are simple (such as selecting a row from a table
with one row); but still differ so that the queries can not be cached, the overhead for
having the query cache active is 13%. This could be regarded as the worst case scenario.
However, in real life, queries are much more complicated than our simple example so
the overhead is normally significantly lower.
Searches after one row in a one row table is 238% faster. This can be regarded as close
to the minimum speedup to be expected for a query that is cached.
If you want to disable the query cache code set query_cache_size=0. By disabling
the query cache code there is no noticeable overhead. (query cache can be excluded
from code with help of configure option --without-query-cache)
6.9.1 How The Query Cache Operates
Queries are compared before parsing, thus
488 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SELECT * FROM nome_tabela
and
Select * from nome_tabela
are regarded as different queries for query cache, so queries need to be exactly the same
(byte for byte) to be seen as identical. In addition, a query may be seen as different if for
instance one client is using a new communication protocol format or another character set
than another client.
Queries that uses different databases, uses different protocol versions or the uses different
default character sets are considered different queries and cached separately.
The cache does work for SELECT CALC_ROWS ... and SELECT FOUND_ROWS() ... type
queries because the number of found rows is also stored in the cache.
If query result was returned from query cache then status variable Com_select will not
be increased, but Qcache_hits will be. See hundefinedi[Query Cache Status and Mainte-
nance], page hundefinedi.
If a table changes (INSERT,UPDATE,DELETE,TRUNCATE,ALTER or DROP TABLE|DATABASE),
then all cached queries that used this table (possibly through a MRG_MyISAM table!) become
invalid and are removed from the cache.
Transactional InnoDB tables that have been changed will be invalidated when a COMMIT is
performed.
A query cannot be cached if it contains one of the functions:
Function Function Function
User-Defined Functions CONNECTION_ID FOUND_ROWS
GET_LOCK RELEASE_LOCK LOAD_FILE
MASTER_POS_WAIT NOW SYSDATE
CURRENT_TIMESTAMP CURDATE CURRENT_DATE
CURTIME CURRENT_TIME DATABASE
ENCRYPT (with one parameter) LAST_INSERT_ID RAND
UNIX_TIMESTAMP (without
parameters)
USER BENCHMARK
Nor can a query be cached if it contains user variables, references the mysql system database,
is of the form SELECT ... IN SHARE MODE,SELECT ... INTO OUTFILE ...,SELECT ... INTO
DUMPFILE ... or of the form SELECT * FROM AUTOINCREMENT_FIELD IS NULL (to retrieve
last insert id - ODBC work around).
However, FOUND ROWS() will return the correct value, even if the preceding query was fetched
from the cache.
In case a query does not use any tables, or uses temporary tables, or if the user has a column
privilege for any of the involved tables, that query will not be cached.
Before a query is fetched from the query cache, MySQL will check that the user has SELECT
privilege to all the involved databases and tables. If this is not the case, the cached result
will not be used.
6.9.2 Query Cache Configuration
The query cache adds a few MySQL system variables for mysqld which may be set in a
configuration file, on the command-line when starting mysqld.
Chapter 6: Referˆencia de Linguagem do MySQL 489
query_cache_limit Don’t cache results that are bigger than this. (Default 1M).
query_cache_min_res_unit
This variable is present from version 4.1.
The result of a query (the data that is also sent to the client) is stored in the query
cache during result retrieval. Therefore the data is usually not handled in one big
chunk. The query cache allocates blocks for storing this data on demand, so when
one block is filled, a new block is allocated. Because memory allocation operation is
costly (time wise), the query cache allocates blocks with a minimum size of query_
cache_min_res_unit. When a query is executed, the last result block is trimmed to
the actual data size, so that unused memory is freed.
The default value of query_cache_min_res_unit is 4 KB which should be ade-
quate for most cases.
If you have a lot of queries with small results, the default block size may lead
to memory fragmentation (indicated by a large number of free blocks (Qcache_
free_blocks), which can cause the query cache to have to delete queries from the
cache due to lack of memory (Qcache_lowmem_prunes)). In this case you should
decrease query_cache_min_res_unit.
If you mostly have queres with big results (see Qcache_total_blocks and Qcache_
queries_in_cache), you can increase performance by increasing query_cache_
min_res_unit. However, be careful to not make it to large (see the previous
point).
query_cache_size The amount of memory (specified in bytes) allocated to store results
from old queries. If this is 0, the query cache is disabled (default).
query_cache_type This may be set (only numeric) to
Option Description
0 (OFF, don’t cache or retrieve results)
1 (ON, cache all results except SELECT SQL_NO_CACHE ... queries)
2 (DEMAND, cache only SELECT SQL_CACHE ... queries)
Inside a thread (connection), the behaviour of the query cache can be changed from the
default. The syntax is as follows:
QUERY_CACHE_TYPE = OFF | ON | DEMAND QUERY_CACHE_TYPE = 0 | 1 | 2
Option Description
0 or OFF Don’t cache or retrieve results.
1 or ON Cache all results except SELECT SQL_NO_CACHE ... queries.
2 or DEMAND Cache only SELECT SQL_CACHE ... queries.
6.9.3 Query Cache Options in SELECT
There are two possible query cache related parameters that may be specified in a SELECT
query:
Option Description
SQL_CACHE If QUERY_CACHE_TYPE is DEMAND, allow the query to be cached. If
QUERY_CACHE_TYPE is ON, this is the default. If QUERY_CACHE_TYPE
is OFF, do nothing.
490 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SQL_NO_CACHE Make this query non-cachable, don’t allow this query to be stored in
the cache.
6.9.4 Query Cache Status and Maintenance
With the FLUSH QUERY CACHE command you can defragment the query cache to better utilise
its memory. This command will not remove any queries from the cache. FLUSH TABLES also
flushes the query cache.
The RESET QUERY CACHE command removes all query results from the query cache.
You can check whether the query cache is present in your MySQL version:
mysql> SHOW VARIABLES LIKE ’have_query_cache’;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
1 row in set (0.00 sec)
You can monitor query cache performance in SHOW STATUS:
Variable Description
Qcache_queries_in_
cache
Number of queries registered in the cache.
Qcache_inserts Number of queries added to the cache.
Qcache_hits Number of cache hits.
Qcache_lowmem_prunes Number of queries that were deleted from
cache because of low memory.
Qcache_not_cached Number of non-cached queries (not
cachable, or due to QUERY_CACHE_TYPE).
Qcache_free_memory Amount of free memory for query cache.
Qcache_free_blocks Number of free memory blocks in query
cache.
Qcache_total_blocks Total number of blocks in query cache.
Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached.
The query cache uses variable length blocks, so Qcache_total_blocks and Qcache_free_
blocks may indicate query cache memory fragmentation. After FLUSH QUERY CACHE only a
single (big) free block remains.
Note: Every query needs a minimum of two blocks (one for the query text and one or more
for the query results). Also, every table that is used by a query needs one block, but if two
or more queries use same table only one block needs to be allocated.
You can use the Qcache_lowmem_prunes status variable to tune the query cache size. It
counts the number of queries that have been removed from the cache to free up memory
for caching new queries. The query cache uses a least recently used (LRU) strategy to
decide which queries to remove from the cache.
Chapter 7: MySQL Table Types 491
7 MySQL Table Types
As of MySQL Version 3.23.6, you can choose between three basic table formats (ISAM,HEAP
and MyISAM). Newer versions of MySQL support additional table types (InnoDB, or BDB),
depending on how you compile it.
When you create a new table, you can tell MySQL what type of table to create. The default
table type is usually MyISAM.
MySQL will always create a ‘.frm’ file to hold the table and column definitions. The table’s
index and data will be stored in one or more other files, depending on the table type.
If you try to use a table type that is not compiled-in or activated, MySQL will instead
create a table of type MyISAM. This behaviour is convenient when you want to copy tables
between MySQL servers that support different table types. (Perhaps your master server
supports transactional storage engines for increased safety, while the slave servers use only
non-transactional storage engines for greater speed.)
This automatic change of table types can be confusing for new MySQL users. We plan to fix
this by introducing warnings in the new client-server protocol in version 4.1 and generating
a warning when a table type is automatically changed.
You can convert tables between different types with the ALTER TABLE statement. See hun-
definedi[ALTER TABLE], page hundefinedi.
Note that MySQL supports two different kinds of tables: transaction-safe tables (InnoDB
and BDB) and not transaction-safe tables (HEAP,ISAM,MERGE, and MyISAM).
Advantages of transaction-safe tables (TST):
Safer. Even if MySQL crashes or you get hardware problems, you can get your data
back, either by automatic recovery or from a backup +the transaction log.
You can combine many statements and accept these all in one go with the COMMIT
command.
You can execute ROLLBACK to ignore your changes (if you are not running in auto-
commit mode).
If an update fails, all your changes will be restored. (With NTST tables all changes
that have taken place are permanent)
Can provide better concurrency if the table gets many updates concurrently with reads.
Note that to use InnoDB tables you have to use at least the innodb_data_file_path startup
option. See hundefinedi[InnoDB start], page hundefinedi.
Advantages of not transaction-safe tables (NTST):
Much faster as there is no transaction overhead.
Will use less disk space as there is no overhead of transactions.
Will use less memory to do updates.
You can combine TST and NTST tables in the same statements to get the best of both
worlds.
492 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
7.1 MyISAM Tables
MyISAM is the default table type in MySQL Version 3.23. It’s based on the ISAM code and
has a lot of useful extensions.
The index is stored in a file with the ‘.MYI’ (MYIndex) extension, and the data is stored
in a file with the ‘.MYD’ (MYData) extension. You can check/repair MyISAM tables with the
myisamchk utility. See hundefinedi[Crash recovery], page hundefinedi. You can compress
MyISAM tables with myisampack to take up much less space. See hundefinedi[myisampack],
page hundefinedi.
The following is new in MyISAM:
There is a flag in the MyISAM file that indicates whether the table was closed correctly. If
mysqld is started with --myisam-recover,MyISAM tables will automatically be checked
and/or repaired on open if the table wasn’t closed properly.
You can INSERT new rows in a table that doesn’t have free blocks in the middle of the
datafile, at the same time other threads are reading from the table (concurrent insert).
An free block can come from an update of a dynamic length row with much data to a
row with less data or when deleting rows. When all free blocks are used up, all future
inserts will be concurrent again.
Support for big files (63-bit) on filesystems/operating systems that support big files.
All data is stored with the low byte first. This makes the data machine and OS
independent. The only requirement is that the machine uses two’s-complement signed
integers (as every machine for the last 20 years has) and IEEE floating-point format
(also totally dominant among mainstream machines). The only area of machines that
may not support binary compatibility are embedded systems (because they sometimes
have peculiar processors).
There is no big speed penalty in storing data low byte first; the bytes in a table row
is normally unaligned and it doesn’t take that much more power to read an unaligned
byte in order than in reverse order. The actual fetch-column-value code is also not
time critical compared to other code.
All number keys are stored with high byte first to give better index compression.
Internal handling of one AUTO_INCREMENT column. MyISAM will automatically update
this on INSERT/UPDATE. The AUTO_INCREMENT value can be reset with myisamchk.
This will make AUTO_INCREMENT columns faster (at least 10%) and old numbers will
not be reused as with the old ISAM. Note that when an AUTO_INCREMENT is defined on
the end of a multi-part-key the old behaviour is still present.
When inserted in sorted order (as when you are using an AUTO_INCREMENT column) the
key tree will be split so that the high node only contains one key. This will improve
the space utilisation in the key tree.
BLOB and TEXT columns can be indexed.
NULL values are allowed in indexed columns. This takes 0-1 bytes/key.
Maximum key length is 500 bytes by default (can be changed by recompiling). In cases
of keys longer than 250 bytes, a bigger key block size than the default of 1024 bytes is
used for this key.
Maximum number of keys/table is 32 as default. This can be enlarged to 64 without
having to recompile myisamchk.
Chapter 7: MySQL Table Types 493
myisamchk will mark tables as checked if one runs it with --update-state.myisamchk
--fast will only check those tables that don’t have this mark.
myisamchk -a stores statistics for key parts (and not only for whole keys as in ISAM).
Dynamic size rows will now be much less fragmented when mixing deletes with updates
and inserts. This is done by automatically combining adjacent deleted blocks and by
extending blocks if the next block is deleted.
myisampack can pack BLOB and VARCHAR columns.
You can use put the datafile and index file on different directories to get more speed
(with the DATA/INDEX DIRECTORY="path" option to CREATE TABLE). See hundefinedi
[CREATE TABLE], page hundefinedi.
MyISAM also supports the following things, which MySQL will be able to use in the near
future:
Support for a true VARCHAR type; a VARCHAR column starts with a length stored in 2
bytes.
Tables with VARCHAR may have fixed or dynamic record length.
VARCHAR and CHAR may be up to 64K. All key segments have their own language
definition. This will enable MySQL to have different language definitions per column.
A hashed computed index can be used for UNIQUE. This will allow you to have UNIQUE
on any combination of columns in a table. (You can’t search on a UNIQUE computed
index, however.)
Note that index files are usually much smaller with MyISAM than with ISAM. This means
that MyISAM will normally use less system resources than ISAM, but will need more CPU
time when inserting data into a compressed index.
The following options to mysqld can be used to change the behaviour of MyISAM tables. See
hundefinedi[SHOW VARIABLES], page hundefinedi.
Option Description
--myisam-recover=# Automatic recovery of crashed tables.
-O myisam_sort_buffer_size=# Buffer used when recovering tables.
--delay-key-write=ALL Don’t flush key buffers between writes for any My-
ISAM table
-O myisam_max_extra_sort_file_
size=#
Used to help MySQL to decide when to use the slow
but safe key cache index create method. Note that
this parameter is given in megabytes before 4.0.3 and
in bytes beginning with this version.
-O myisam_max_sort_file_size=# Don’t use the fast sort index method to created in-
dex if the temporary file would get bigger than this.
Note that this parameter is given in megabytes be-
fore 4.0.3 and in bytes beginning with this version.
-O bulk_insert_buffer_size=# Size of tree cache used in bulk insert optimisation.
Note that this is a limit per thread!
The automatic recovery is activated if you start mysqld with --myisam-recover=#. See line
options-snt [Command-line options], page line options-pg. On open, the table is checked if
it’s marked as crashed or if the open count variable for the table is not 0 and you are running
with --skip-external-locking. If either of the above is true the following happens.
494 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
The table is checked for errors.
If we found an error, try to do a fast repair (with sorting and without re-creating the
datafile) of the table.
If the repair fails because of an error in the datafile (for example a duplicate key error),
we try again, but this time we re-create the datafile.
If the repair fails, retry once more with the old repair option method (write row by
row without sorting) which should be able to repair any type of error with little disk
requirements..
If the recover wouldn’t be able to recover all rows from a previous completed statement and
you didn’t specify FORCE as an option to myisam-recover, then the automatic repair will
abort with an error message in the error file:
Error: Couldn’t repair table: test.g00pages
If you in this case had used the FORCE option you would instead have got a warning in the
error file:
Warning: Found 344 of 354 rows when repairing ./test/g00pages
Note that if you run automatic recover with the BACKUP option, you should have a cron
script that automatically moves file with names like ‘tablename-datetime.BAK’ from the
database directories to a backup media.
See line options-snt [Command-line options], page line options-pg.
7.1.1 Space Needed for Keys
MySQL can support different index types, but the normal type is ISAM or MyISAM.
These use a B-tree index, and you can roughly calculate the size for the index file as (key_
length+4)/0.67, summed over all keys. (This is for the worst case when all keys are
inserted in sorted order and we don’t have any compressed keys.)
String indexes are space compressed. If the first index part is a string, it will also be prefix
compressed. Space compression makes the index file smaller than the above figures if the
string column has a lot of trailing space or is a VARCHAR column that is not always used
to the full length. Prefix compression is used on keys that start with a string. Prefix
compression helps if there are many strings with an identical prefix.
In MyISAM tables, you can also prefix compress numbers by specifying PACK_KEYS=1 when
you create the table. This helps when you have many integer keys that have an identical
prefix when the numbers are stored high-byte first.
7.1.2 MyISAM Table Formats
MyISAM supports 3 different table types. Two of them are chosen automatically depending
on the type of columns you are using. The third, compressed tables, can only be created
with the myisampack tool.
When you CREATE or ALTER a table you can for tables that doesn’t have BLOBs force the table
format to DYNAMIC or FIXED with the ROW_FORMAT=# table option. In the future you will
be able to compress/decompress tables by specifying ROW_FORMAT=compressed | default
to ALTER TABLE. See hundefinedi[CREATE TABLE], page hundefinedi.
Chapter 7: MySQL Table Types 495
7.1.2.1 Static (Fixed-length) Table Characteristics
This is the default format. It’s used when the table contains no VARCHAR,BLOB, or TEXT
columns.
This format is the simplest and most secure format. It is also the fastest of the on-disk
formats. The speed comes from the easy way data can be found on disk. When looking up
something with an index and static format it is very simple. Just multiply the row number
by the row length.
Also, when scanning a table it is very easy to read a constant number of records with each
disk read.
The security is evidenced if your computer crashes when writing to a fixed-size MyISAM
file, in which case myisamchk can easily figure out where each row starts and ends. So it
can usually reclaim all records except the partially written one. Note that in MySQL all
indexes can always be reconstructed:
All CHAR,NUMERIC, and DECIMAL columns are space-padded to the column width.
Very quick.
Easy to cache.
Easy to reconstruct after a crash, because records are located in fixed positions.
Doesn’t have to be reorganised (with myisamchk) unless a huge number of records are
deleted and you want to return free disk space to the operating system.
Usually requires more disk space than dynamic tables.
7.1.2.2 Dynamic Table Characteristics
This format is used if the table contains any VARCHAR,BLOB, or TEXT columns or if the table
was created with ROW_FORMAT=dynamic.
This format is a little more complex because each row has to have a header that says how
long it is. One record can also end up at more than one location when it is made longer at
an update.
You can use OPTIMIZE table or myisamchk to defragment a table. If you have static data
that you access/change a lot in the same table as some VARCHAR or BLOB columns, it might
be a good idea to move the dynamic columns to other tables just to avoid fragmentation:
All string columns are dynamic (except those with a length less than 4).
Each record is preceded by a bitmap indicating which columns are empty (’’) for string
columns, or zero for numeric columns. (This isn’t the same as columns containing NULL
values.) If a string column has a length of zero after removal of trailing spaces, or a
numeric column has a value of zero, it is marked in the bit map and not saved to disk.
Non-empty strings are saved as a length byte plus the string contents.
Usually takes much less disk space than fixed-length tables.
Each record uses only as much space as is required. If a record becomes larger, it is
split into as many pieces as are required. This results in record fragmentation.
If you update a row with information that extends the row length, the row will be
fragmented. In this case, you may have to run myisamchk -r from time to time to get
better performance. Use myisamchk -ei nome_tabela for some statistics.
496 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Not as easy to reconstruct after a crash, because a record may be fragmented into many
pieces and a link (fragment) may be missing.
The expected row length for dynamic sized records is:
3
+ (number of columns + 7) / 8
+ (number of char columns)
+ packed size of numeric columns
+ length of strings
+ (number of NULL columns + 7) / 8
There is a penalty of 6 bytes for each link. A dynamic record is linked whenever an
update causes an enlargement of the record. Each new link will be at least 20 bytes, so
the next enlargement will probably go in the same link. If not, there will be another
link. You may check how many links there are with myisamchk -ed. All links may be
removed with myisamchk -r.
7.1.2.3 Compressed Table Characteristics
This is a read-only type that is generated with the optional myisampack tool (pack_isam
for ISAM tables):
All MySQL distributions, even those that existed before MySQL went GPL, can read
tables that were compressed with myisampack.
Compressed tables take very little disk space. This minimises disk usage, which is very
nice when using slow disks (like CD-ROMs).
Each record is compressed separately (very little access overhead). The header for a
record is fixed (1-3 bytes) depending on the biggest record in the table. Each column
is compressed differently. Some of the compression types are:
There is usually a different Huffman table for each column.
Suffix space compression.
Prefix space compression.
Numbers with value 0are stored using 1 bit.
If values in an integer column have a small range, the column is stored using the
smallest possible type. For example, a BIGINT column (8 bytes) may be stored as
aTINYINT column (1 byte) if all values are in the range 0to 255.
If a column has only a small set of possible values, the column type is converted
to ENUM.
A column may use a combination of the above compressions.
Can handle fixed- or dynamic-length records.
Can be uncompressed with myisamchk.
7.1.3 MyISAM Table Problems
The file format that MySQL uses to store data has been extensively tested, but there are
always circumstances that may cause database tables to become corrupted.
Chapter 7: MySQL Table Types 497
7.1.3.1 Corrupted MyISAM Tables
Even if the MyISAM table format is very reliable (all changes to a table is written before
the SQL statements returns) , you can still get corrupted tables if some of the following
things happens:
The mysqld process being killed in the middle of a write.
Unexpected shutdown of the computer (for example, if the computer is turned off).
A hardware error.
You are using an external program (like myisamchk) on a live table.
A software bug in the MySQL or MyISAM code.
Typial typical symptoms for a corrupt table is:
You get the error Incorrect key file for table: ’...’. Try to repair it while se-
lecting data from the table.
Queries doesn’t find rows in the table or returns incomplete data.
You can check if a table is ok with the command CHECK TABLE. See hundefinedi[CHECK
TABLE], page hundefinedi.
You can repair a corrupted table with REPAIR TABLE. See hundefinedi[REPAIR TABLE],
page hundefinedi. You can also repair a table, when mysqld is not running with the
myisamchk command. myisamchk syntax.
If your tables get corrupted a lot you should try to find the reason for this! See hundefinedi
[Crashing], page hundefinedi.
In this case the most important thing to know is if the table got corrupted if the mysqld
died (one can easily verify this by checking if there is a recent row restarted mysqld in
the mysqld error file). If this isn’t the case, then you should try to make a test case of this.
See hundefinedi[Reproduceable test case], page hundefinedi.
7.1.3.2 Clients is using or hasn’t closed the table properly
Each MyISAM .MYI’ file has in the header a counter that can be used to check if a table has
been closed properly.
If you get the following warning from CHECK TABLE or myisamchk:
# clients is using or hasn’t closed the table properly
this means that this counter has come out of sync. This doesn’t mean that the table is
corrupted, but means that you should at least do a check on the table to verify that it’s
okay.
The counter works as follows:
The first time a table is updated in MySQL, a counter in the header of the index files
is incremented.
The counter is not changed during further updates.
When the last instance of a table is closed (because of a FLUSH or because there isn’t
room in the table cache) the counter is decremented if the table has been updated at
any point.
When you repair the table or check the table and it was okay, the counter is reset to 0.
498 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
To avoid problems with interaction with other processes that may do a check on the
table, the counter is not decremented on close if it was 0.
In other words, the only ways this can go out of sync are:
The MyISAM tables are copied without a LOCK and FLUSH TABLES.
MySQL has crashed between an update and the final close. (Note that the table may
still be okay, as MySQL always issues writes for everything between each statement.)
Someone has done a myisamchk --recover or myisamchk --update-stateon a table
that was in use by mysqld.
Many mysqld servers are using the table and one has done a REPAIR or CHECK of the
table while it was in use by another server. In this setup the CHECK is safe to do
(even if you will get the warning from other servers), but REPAIR should be avoided
as it currently replaces the datafile with a new one, which is not signaled to the other
servers.
7.2 MERGE Tables
MERGE tables are new in MySQL Version 3.23.25. The code is still in gamma, but should be
reasonable stable.
AMERGE table (also known as a MRG_MyISAM table) is a collection of identical MyISAM tables
that can be used as one. You can only SELECT,DELETE, and UPDATE from the collection of
tables. If you DROP the MERGE table, you are only dropping the MERGE specification.
Note that DELETE FROM merge_table used without a WHERE will only clear the mapping for
the table, not delete everything in the mapped tables. (We plan to fix this in 4.1).
With identical tables we mean that all tables are created with identical column and key
information. You can’t merge tables in which the columns are packed differently, doesn’t
have exactly the same columns, or have the keys in different order. However, some of the
tables can be compressed with myisampack. See hundefinedi[myisampack], page hunde-
finedi.
When you create a MERGE table, you will get a ‘.frm’ table definition file and a ‘.MRG’ table
list file. The ‘.MRG’ just contains a list of the index files (‘.MYI’ files) that should be used
as one. All used tables must be in the same database as the MERGE table itself.
For the moment, you need to have SELECT,UPDATE, and DELETE privileges on the tables you
map to a MERGE table.
MERGE tables can help you solve the following problems:
Easily manage a set of log tables. For example, you can put data from different months
into separate files, compress some of them with myisampack, and then create a MERGE
to use these as one.
Give you more speed. You can split a big read-only table based on some criteria and
then put the different table part on different disks. A MERGE table on this could be
much faster than using the big table. (You can, of course, also use a RAID to get the
same kind of benefits.)
Do more efficient searches. If you know exactly what you are looking after, you can
search in just one of the split tables for some queries and use a MERGE table for others.
You can even have many different MERGE tables active, with possible overlapping files.
Chapter 7: MySQL Table Types 499
More efficient repairs. It’s easier to repair the individual files that are mapped to a
MERGE file than trying to repair a really big file.
Instant mapping of many files as one. A MERGE table uses the index of the individual
tables. It doesn’t need to maintain an index of its one. This makes MERGE table
collections VERY fast to make or remap. Note that you must specify the key definitions
when you create a MERGE table!.
If you have a set of tables that you join to a big table on demand or batch, you should
instead create a MERGE table on them on demand. This is much faster and will save a
lot of disk space.
Go around the file-size limit for the operating system.
You can create an alias/synonym for a table by just using MERGE over one table. There
shouldn’t be any really notable performance impacts of doing this (only a couple of
indirect calls and memcpy() calls for each read).
The disadvantages with MERGE tables are:
You can only use identical MyISAM tables for a MERGE table.
REPLACE doesn’t work.
MERGE tables uses more file descriptors. If you are using a MERGE table that maps over
10 tables and 10 users are using this, you are using 10*10 +10 file descriptors. (10
datafiles for 10 users and 10 shared index files.)
Key reads are slower. When you do a read on a key, the MERGE storage engine will
need to issue a read on all underlying tables to check which one most closely matches
the given key. If you then do a "read-next"then the MERGE storage engine will need
to search the read buffers to find the next key. Only when one key buffer is used
up, the storage engine will need to read the next key block. This makes MERGE keys
much slower on eq_ref searches, but not much slower on ref searches. See hundefinedi
[EXPLAIN], page hundefinedi.
You can’t do DROP TABLE,ALTER TABLE,DELETE FROM table_name without a WHERE
clause, REPAIR TABLE,TRUNCATE TABLE,OPTIMIZE TABLE, or ANALYZE TABLE on any of
the table that is mapped by a MERGE table that is "open". If you do this, the MERGE table
may still refer to the original table and you will get unexpected results. The easiest
way to get around this deficiency is to issue the FLUSH TABLES command, ensuring no
MERGE tables remain "open".
When you create a MERGE table you have to specify with UNION(list-of-tables) which
tables you want to use as one. Optionally you can specify with INSERT_METHOD if you want
insert for the MERGE table to happen in the first or last table in the UNION list. If you don’t
specify INSERT_METHOD or specify NO, then all INSERT commands on the MERGE table will
return an error.
The following example shows you how to use MERGE tables:
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2");
CREATE TABLE total (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20))
TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
500 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note that you can also manipulate the ‘.MRG’ file directly from the outside of the MySQL
server:
shell> cd /mysql-data-directory/current-database
shell> ls -1 t1.MYI t2.MYI > total.MRG
shell> mysqladmin flush-tables
Now you can do things like:
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table |
| 3 | t1 |
| 1 | Testing |
| 2 | table |
| 3 | t2 |
+---+---------+
Note that the acolumn, though declared as PRIMARY KEY, is not really unique, as MERGE
table cannot enforce uniqueness over a set of underlying MyISAM tables.
To remap a MERGE table you can do one of the following:
DROP the table and re-create it
Use ALTER TABLE table_name UNION(...)
Change the ‘.MRG’ file and issue a FLUSH TABLE on the MERGE table and all underlying
tables to force the storage engine to read the new definition file.
7.2.1 MERGE Table Problems
The following are the known problems with MERGE tables:
AMERGE table cannot maintain UNIQUE constraints over the whole table. When you do
INSERT, the data goes into the first or last table (according to INSERT_METHOD=xxx)
and this MyISAM table ensures that the data are unique, but it knows nothing about
others MyISAM tables.
DELETE FROM merge_table used without a WHERE will only clear the mapping for the
table, not delete everything in the mapped tables.
RENAME TABLE on a table used in an active MERGE table may corrupt the table. This
will be fixed in MySQL 4.0.x.
Creation of a table of type MERGE doesn’t check if the underlying tables are of compatible
types. If you use MERGE tables in this fashion, you are very likely to run into strange
problems.
If you use ALTER TABLE to first add an UNIQUE index to a table used in a MERGE table and
then use ALTER TABLE to add a normal index on the MERGE table, the key order will be
different for the tables if there was an old non-unique key in the table. This is because
ALTER TABLE puts UNIQUE keys before normal keys to be able to detect duplicate keys
as early as possible.
Chapter 7: MySQL Table Types 501
The range optimiser can’t yet use MERGE table efficiently and may sometimes produce
non-optimal joins. This will be fixed in MySQL 4.0.x.
DROP TABLE on a table that is in use by a MERGE table will not work on Windows
because the MERGE storage engine does the table mapping hidden from the upper layer of
MySQL. Because Windows doesn’t allow you to drop files that are open, you first must
flush all MERGE tables (with FLUSH TABLES) or drop the MERGE table before dropping
the table. We will fix this at the same time we introduce VIEWs.
7.3 ISAM Tables
The deprecated ISAM table type will disappear in MySQL version 5.0. MyISAM is a better
implementation of the same thing.
ISAM uses a B-tree index. The index is stored in a file with the ‘.ISM’ extension, and the
data is stored in a file with the ‘.ISD’ extension. You can check/repair ISAM tables with
the isamchk utility. See hundefinedi[Crash recovery], page hundefinedi.
ISAM has the following features/properties:
Compressed and fixed-length keys
Fixed and dynamic record length
16 keys with 16 key parts/key
Max key length 256 (default)
Data is stored in machine format; this is fast, but is machine/OS dependent.
Most of the things true for MyISAM tables are also true for ISAM tables. See hundefinedi
[MyISAM tables], page hundefinedi. The major differences compared to MyISAM tables are:
ISAM tables are not binary portable across OS/Platforms.
Can’t handle tables >4G.
Only support prefix compression on strings.
Smaller key limits.
Dynamic tables get more fragmented.
Tables are compressed with pack_isam rather than with myisampack.
If you want to convert an ISAM table to a MyISAM table so that you can use utilities such as
mysqlcheck, use an ALTER TABLE statement:
mysql> ALTER TABLE nome_tabela TYPE = MYISAM;
The embedded MySQL versions doesn’t support ISAM tables.
7.4 HEAP Tables
HEAP tables use hashed indexes and are stored in memory. This makes them very fast, but
if MySQL crashes you will lose all data stored in them. HEAP is very useful for temporary
tables!
The MySQL internal HEAP tables use 100% dynamic hashing without overflow areas. There
is no extra space needed for free lists. HEAP tables also don’t have problems with delete +
inserts, which normally is common with hashed tables:
502 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) AS down
-> FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;
Here are some things you should consider when you use HEAP tables:
You should always use specify MAX_ROWS in the CREATE statement to ensure that you
accidentally do not use all memory.
Indexes will only be used with =and <=> (but are VERY fast).
HEAP tables can only use whole keys to search for a row; compare this to MyISAM tables
where any prefix of the key can be used to find rows.
HEAP tables use a fixed record length format.
HEAP doesn’t support BLOB/TEXT columns.
HEAP doesn’t support AUTO_INCREMENT columns.
Prior to MySQL 4.0.2, HEAP doesn’t support an index on a NULL column.
You can have non-unique keys in a HEAP table (this isn’t common for hashed tables).
HEAP tables are shared between all clients (just like any other table).
You can’t search for the next entry in order (that is, to use the index to do an ORDER
BY).
Data for HEAP tables are allocated in small blocks. The tables are 100% dynamic (on
inserting). No overflow areas and no extra key space are needed. Deleted rows are put
in a linked list and are reused when you insert new data into the table.
You need enough extra memory for all HEAP tables that you want to use at the same
time.
To free memory, you should execute DELETE FROM heap_table,TRUNCATE heap_table
or DROP TABLE heap_table.
MySQL cannot find out approximately how many rows there are between two values
(this is used by the range optimiser to decide which index to use). This may affect
some queries if you change a MyISAM table to a HEAP table.
To ensure that you accidentally don’t do anything foolish, you can’t create HEAP tables
bigger than max_heap_table_size.
The memory needed for one row in a HEAP table is:
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
sizeof(char*) is 4 on 32-bit machines and 8 on 64-bit machines.
7.5 InnoDB Tables
7.5.1 InnoDB Tables Overview
InnoDB provides MySQL with a transaction-safe (ACID compliant) storage engine with
commit, rollback, and crash recovery capabilities. InnoDB does locking on row level and
also provides an Oracle-style consistent non-locking read in SELECTs. These features increase
Chapter 7: MySQL Table Types 503
multiuser concurrency and performance. There is no need for lock escalation in InnoDB,
because row level locks in InnoDB fit in very small space. InnoDB tables support FOREIGN
KEY constraints as the first table type in MySQL.
InnoDB has been designed for maximum performance when processing large data volumes.
Its CPU efficiency is probably not matched by any other disk-based relational database
engine.
InnoDB is used in production at n´umerous large database sites requiring high performance.
The famous Internet news site Slashdot.org runs on InnoDB. Mytrix, Inc. stores over 1 TB
of data in InnoDB, and another site handles an average load of 800 inserts/updates per
second in InnoDB.
Technically, InnoDB is a complete database backend placed under MySQL. InnoDB has its
own buffer pool for caching data and indexes in main memory. InnoDB stores its tables
and indexes in a tablespace, which may consist of several files (or raw disk partitions). This
is different from, for example, MyISAM tables where each table is stored as a separate file.
InnoDB tables can be of any size also on those operating systems where file-size is limited
to 2 GB.
You can find the latest information about InnoDB at http://www.innodb.com/. The most
up-to-date version of the InnoDB manual is always placed there, and you can also order
commercial licenses and support for InnoDB.
In the source distribution of MySQL, InnoDB appears as a subdirectory. InnoDB is dis-
tributed under the GNU GPL License Version 2 (of June 1991).
7.5.2 InnoDB in MySQL Version 3.23
From MySQL version 4.0, InnoDB is enabled by default. The following information only
applies to the 3.23 series.
InnoDB tables are included in the MySQL source distribution starting from 3.23.34a and
are activated in the MySQL -Max binary of the 3.23 series. For Windows the -Max binaries
are contained in the standard distribution.
If you have downloaded a binary version of MySQL that includes support for InnoDB, simply
follow the instructions of the MySQL manual for installing a binary version of MySQL. If
you already have MySQL-3.23 installed, then the simplest way to install MySQL -Max is
to replace the server executable ‘mysqld’ with the corresponding executable in the -Max
distribution. MySQL and MySQL -Max differ only in the server executable. See hundefinedi
[Installing binary], page hundefinedi. See max-snt [mysqld-max], page max-pg.
To compile MySQL with InnoDB support, download MySQL-3.23.34a or newer version from
http://www.mysql.com/ and configure MySQL with the --with-innodb option. See the
MySQL manual about installing a MySQL source distribution. See hundefinedi[Installing
source], page hundefinedi.
cd /path/to/source/of/mysql-3.23.37
./configure --with-innodb
To use InnoDB tables in MySQL-Max-3.23 you must specify configuration parameters in the
[mysqld] section of the configuration file ‘my.cnf’, or on Windows optionally in ‘my.ini’.
At the minimum, in 3.23 you must specify innodb_data_file_path where you specify the
names and the sizes of datafiles. If you do not mention innodb_data_home_dir in ‘my.cnf
504 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
the default is to create these files to the datadir of MySQL. If you specify innodb_data_
home_dir as an empty string, then you can give absolute paths to your data files in innodb_
data_file_path.
The minimal way to modify it is to add to the [mysqld] section the line
innodb_data_file_path=ibdata:30M
but to get good performance it is best that you specify options as recommended. See
hundefinedi[InnoDB start], page hundefinedi.
7.5.3 InnoDB Startup Options
To enable InnoDB tables in MySQL version 3.23, see hundefinedi[InnoDB in MySQL 3.23],
page hundefinedi.
In MySQL-4.0 you do are not required to do anything specific to enable InnoDB tables.
The default behaviour is to create an auto-extending 10 MB file ‘ibdata1’ in the datadir
of MySQL. (In MySQL-4.0.0 and 4.0.1 the datafile is 64 MB and not auto-extending.)
Note: To get good performance you should explicitly set the InnoDB parameters listed in
the following examples.
If you don’t want to use InnoDB tables, you can add the skip-innodb option to your MySQL
option file.
Starting from versions 3.23.50 and 4.0.2 InnoDB allows the last datafile on the innodb_
data_file_path line to be specified as auto-extending. The syntax for innodb_data_
file_path is then the following:
pathtodatafile:sizespecification;pathtodatafile:sizespecification;...
... ;pathtodatafile:sizespecification[:autoextend[:max:sizespecification]]
If you specify the last datafile with the autoextend option, InnoDB will extend the last
datafile if it runs out of free space in the tablespace. The increment is 8 MB at a time. An
example:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:100M:autoextend
instructs InnoDB to create just a single datafile whose initial size is 100 MB and which
is extended in 8 MB blocks when space runs out. If the disk becomes full you may want
to add another data file to another disk, for example. Then you have to look the size of
ibdata1’, round the size downward to the closest multiple of 1024 * 1024 bytes (= 1 MB),
and specify the rounded size of ‘ibdata1’ explicitly in innodb_data_file_path. After that
you can add another datafile:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
Be cautious on filesystems where the maximum file-size is 2 GB. InnoDB is not aware of
the OS maximum file-size. On those filesystems you might want to specify the max size for
the datafile:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:100M:autoextend:max:2000M
A simple ‘my.cnf’ example. Suppose you have a computer with 128 MB RAM and one hard
disk. Below is an example of possible configuration parameters in ‘my.cnf’ or ‘my.ini’ for
Chapter 7: MySQL Table Types 505
InnoDB. We assume you are running MySQL-Max-3.23.50 or later, or MySQL-4.0.2 or later.
This example suits most users, both on Unix and Windows, who do not want to distribute
InnoDB datafiles and log files on several disks. This creates an auto-extending data file
ibdata1’ and two InnoDB log files ‘ib_logfile0’ and ‘ib_logfile1’ to the datadir of
MySQL (typically ‘/mysql/data’). Also the small archived InnoDB log file ‘ib_arch_log_
0000000000’ ends up in the datadir.
[mysqld]
# You can write your other MySQL server options here
# ...
# Data file(s) must be able to
# hold your data and indexes.
# Make sure you have enough
# free disk space.
innodb_data_file_path = ibdata1:10M:autoextend
# Set buffer pool size to
# 50 - 80 % of your computer’s
# memory
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
# Set the log file size to about
# 25 % of the buffer pool size
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
# Set ..flush_log_at_trx_commit
# to 0 if you can afford losing
# some last transactions
innodb_flush_log_at_trx_commit=1
Check that the MySQL server has the rights to create files in datadir.
Note that datafiles must be <2 GB in some file systems! The combined size of the log files
must be <4 GB. The combined size of datafiles must be >= 10 MB.
When you for the first time create an InnoDB database, it is best that you start the
MySQL server from the command prompt. Then InnoDB will print the information about
the database creation to the screen, and you see what is happening. See below next section
what the printout should look like. For example, in Windows you can start ‘mysqld-
max.exe’ with:
your-path-to-mysqld>mysqld-max --console
Where to put ‘my.cnf’ or ‘my.ini’ in Windows? The rules for Windows are the following:
Only one of ‘my.cnf’ or ‘my.ini’ should be created.
The ‘my.cnf’ file should be placed in the root directory of the drive ‘C:’.
The ‘my.ini’ file should be placed in the WINDIR directory, e.g, C:\WINDOWS’ or
C:\WINNT’. You can use the SET command of MS-DOS to print the value of WINDIR.
If your PC uses a boot loader where the ‘C:’ drive is not the boot drive, then your only
option is to use the ‘my.ini’ file.
Where to specify options in Unix? On Unix ‘mysqld’ reads options from the following files,
if they exist, in the following order:
506 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
/etc/my.cnf’ Global options.
COMPILATION_DATADIR/my.cnf’ Server-specific options.
defaults-extra-file’ The file specified with --defaults-extra-file=....
~/.my.cnf’ User-specific options.
COMPILATION_DATADIR’ is the MySQL data directory which was specified as a ./configure
option when ‘mysqld’ was compiled (typically ‘/usr/local/mysql/data’ for a binary in-
stallation or ‘/usr/local/var’ for a source installation).
If you are not sure from where ‘mysqld’ reads its ‘my.cnf’ or ‘my.ini’, you can give the path
as the first command-line option to the server: mysqld --defaults-file=your_path_to_
my_cnf.
InnoDB forms the directory path to a datafile by textually catenating innodb_data_home_
dir to a datafile name or path in innodb_data_file_path, adding a possible slash or
backslash in between if needed. If the keyword innodb_data_home_dir is not mentioned
in ‘my.cnf’ at all, the default for it is the ’dot’ directory ‘./’ which means the datadir of
MySQL.
An advanced ‘my.cnf’ example. Suppose you have a Linux computer with 2 GB RAM and
three 60 GB hard disks (at directory paths ‘/’, ‘/dr2’ and ‘/dr3’). Below is an example of
possible configuration parameters in ‘my.cnf’ for InnoDB.
Note that InnoDB does not create directories: you have to create them yourself. Use the
Unix or MS-DOS mkdir command to create the data and log group home directories.
[mysqld]
# You can write your other MySQL server options here
# ...
innodb_data_home_dir =
# Data files must be able to
# hold your data and indexes
innodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend
# Set buffer pool size to
# 50 - 80 % of your computer’s
# memory, but make sure on Linux
# x86 total memory usage is
# < 2 GB
set-variable = innodb_buffer_pool_size=1G
set-variable = innodb_additional_mem_pool_size=20M
innodb_log_group_home_dir = /dr3/iblogs
# .._log_arch_dir must be the same
# as .._log_group_home_dir
innodb_log_arch_dir = /dr3/iblogs
set-variable = innodb_log_files_in_group=3
# Set the log file size to about
# 15 % of the buffer pool size
set-variable = innodb_log_file_size=150M
set-variable = innodb_log_buffer_size=8M
# Set ..flush_log_at_trx_commit to
# 0 if you can afford losing
# some last transactions
Chapter 7: MySQL Table Types 507
innodb_flush_log_at_trx_commit=1
set-variable = innodb_lock_wait_timeout=50
#innodb_flush_method=fdatasync
#set-variable = innodb_thread_concurrency=5
Note that we have placed the two datafiles on different disks. InnoDB will fill the tablespace
formed by the datafiles from bottom up. In some cases it will improve the performance of
the database if all data is not placed on the same physical disk. Putting log files on a
different disk from data is very often beneficial for performance. You can also use raw disk
partitions (raw devices) as datafiles. In some Unixes they speed up I/O. See the manual
section on InnoDB file space management about how to specify them in ‘my.cnf’.
Warning: on Linux x86 you must be careful you do not set memory usage too high. glibc
will allow the process heap to grow over thread stacks, which will crash your server. It is a
risk if the value of
innodb_buffer_pool_size + key_buffer +
max_connections * (sort_buffer + read_buffer_size) + max_connections * 2 MB
is close to 2 GB or exceeds 2 GB. Each thread will use a stack (often 2 MB, but in MySQL
AB binaries only 256 KB) and in the worst case also sort_buffer + read_buffer_size
additional memory.
How to tune other ‘mysqld’ server parameters? Typical values which suit most users are:
skip-locking
set-variable = max_connections=200
set-variable = read_buffer_size=1M
set-variable = sort_buffer=1M
# Set key_buffer to 5 - 50%
# of your RAM depending on how
# much you use MyISAM tables, but
# keep key_buffer + InnoDB
# buffer pool size < 80% of
# your RAM
set-variable = key_buffer=...
Note that some parameters are given using the numeric ‘my.cnf’ parameter format: set-
variable = innodb... = 123, others (string and boolean parameters) with another format:
innodb_... = ... .
The meanings of the configuration parameters are the following:
Option Description
innodb_data_home_dir The common part of the directory path for all InnoDB
datafiles. If you do not mentioned this option in ‘my.cnf
the default is the datadir of MySQL. You can specify
this also as an empty string, in which case you can use
absolute file paths in innodb_data_file_path.
508 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
innodb_data_file_path Paths to individual datafiles and their sizes. The full di-
rectory path to each datafile is acquired by concatenating
innodb data home dir to the paths specified here. The
file sizes are specified in megabytes, hence the ’M’ after
the size specification above. InnoDB also understands
the abbreviation ’G’, 1 G meaning 1024 MB. Starting
from 3.23.44 you can set the file-size bigger than 4 GB
on those operating systems which support big files. On
some operating systems files must be <2 GB. The sum
of the sizes of the files must be at least 10 MB.
innodb_mirrored_log_groups Number of identical copies of log groups we keep for the
database. Currently this should be set to 1.
innodb_log_group_home_dir Directory path to InnoDB log files.
innodb_log_files_in_group Number of log files in the log group. InnoDB writes to
the files in a circular fashion. Value 3 is recommended
here.
innodb_log_file_size Size of each log file in a log group in megabytes. Sensible
values range from 1M to 1/nth of the size of the buffer
pool specified below, where n is the number of log files in
the group. The bigger the value, the less checkpoint flush
activity is needed in the buffer pool, saving disk I/O. But
bigger log files also mean that recovery will be slower in
case of a crash. The combined size of log files must be <
4 GB on 32-bit computers.
innodb_log_buffer_size The size of the buffer which InnoDB uses to write log to
the log files on disk. Sensible values range from 1M to 8M.
A big log buffer allows large transactions to run without a
need to write the log to disk until the transaction commit.
Thus, if you have big transactions, making the log buffer
big will save disk I/O.
innodb_flush_log_at_trx_
commit
Normally you set this to 1, meaning that at a transaction
commit the log is flushed to disk, and the modifications
made by the transaction become permanent, and survive
a database crash. If you are willing to compromise this
safety, and you are running small transactions, you may
set this to 0 or 2 to reduce disk I/O to the logs. Value 0
means that the log is only written to the log file and the
log file flushed to disk approximately once per second.
Value 2 means the log is written to the log file at each
commit, but the log file is only flushed to disk approxi-
mately once per second. The default value is 1 starting
from MySQL-4.0.13, previously it was 0.
innodb_log_arch_dir The directory where fully written log files would be
archived if we used log archiving. The value of this pa-
rameter should currently be set the same as innodb_log_
group_home_dir.
Chapter 7: MySQL Table Types 509
innodb_log_archive This value should currently be set to 0. As recovery from
a backup is done by MySQL using its own log files, there
is currently no need to archive InnoDB log files.
innodb_buffer_pool_size The size of the memory buffer InnoDB uses to cache data
and indexes of its tables. The bigger you set this the
less disk I/O is needed to access data in tables. On a
dedicated database server you may set this parameter up
to 80% of the machine physical memory size. Do not set
it too large, though, because competition of the physical
memory may cause paging in the operating system.
innodb_additional_mem_
pool_size
Size of a memory pool InnoDB uses to store data dic-
tionary information and other internal data structures.
A sensible value for this might be 2M, but the more ta-
bles you have in your application the more you will need
to allocate here. If InnoDB runs out of memory in this
pool, it will start to allocate memory from the operating
system, and write warning messages to the MySQL error
log.
innodb_file_io_threads Number of file I/O threads in InnoDB. Normally, this
should be 4, but on Windows disk I/O may benefit from
a larger number.
innodb_lock_wait_timeout Timeout in seconds an InnoDB transaction may wait for a
lock before being rolled back. InnoDB automatically de-
tects transaction deadlocks in its own lock table and rolls
back the transaction. If you use LOCK TABLES command,
or other transaction-safe storage engines than InnoDB in
the same transaction, then a deadlock may arise which
InnoDB cannot notice. In cases like this the timeout is
useful to resolve the situation.
innodb_flush_method (Available from 3.23.40 up.) The default value for this is
fdatasync. Another option is O_DSYNC.
7.5.4 Creating InnoDB Tablespace
Suppose you have installed MySQL and have edited ‘my.cnf’ so that it contains the nec-
essary InnoDB configuration parameters. Before starting MySQL you should check that
the directories you have specified for InnoDB datafiles and log files exist and that you have
access rights to those directories. InnoDB cannot create directories, only files. Check also
you have enough disk space for the data and log files.
When you now start MySQL, InnoDB will start creating your datafiles and log files. InnoDB
will print something like the following:
~/mysqlm/sql > mysqld
InnoDB: The first specified datafile /home/heikki/data/ibdata1
did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728
InnoDB: Database physically writes the file full: wait...
InnoDB: datafile /home/heikki/data/ibdata2 did not exist:
510 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
new to be created
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880
InnoDB: Started
mysqld: ready for connections
A new InnoDB database has now been created. You can connect to the MySQL server with
the usual MySQL client programs like mysql. When you shut down the MySQL server with
mysqladmin shutdown’, InnoDB output will be like the following:
010321 18:33:34 mysqld: Normal shutdown
010321 18:33:34 mysqld: Shutdown Complete
InnoDB: Starting shutdown...
InnoDB: Shutdown completed
You can now look at the datafiles and logs directories and you will see the files created.
The log directory will also contain a small file named ‘ib_arch_log_0000000000’. That file
resulted from the database creation, after which InnoDB switched off log archiving. When
MySQL is again started, the output will be like the following:
~/mysqlm/sql > mysqld
InnoDB: Started
mysqld: ready for connections
7.5.4.1 If Something Goes Wrong in Database Creation
If InnoDB prints an operating system error in a file operation, usually the problem is one
of the following:
You did not create InnoDB data or log directories.
mysqld’ does not have the rights to create files in those directories.
mysqld’ does not read the right ‘my.cnf’ or ‘my.ini’ file, and consequently does not
see the options you specified.
The disk is full or a disk quota is exceeded.
You have created a subdirectory whose name is equal to a datafile you specified.
There is a syntax error in innodb_data_home_dir or innodb_data_file_path.
If something goes wrong in an InnoDB database creation, you should delete all files created
by InnoDB. This means all datafiles, all log files, the small archived log file, and in the case
you already did create some InnoDB tables, delete also the corresponding ‘.frm’ files for
these tables from the MySQL database directories. Then you can try the InnoDB database
creation again.
Chapter 7: MySQL Table Types 511
7.5.5 Creating InnoDB Tables
Suppose you have started the MySQL client with the command mysql test. To create
a table in the InnoDB format you must specify TYPE = InnoDB in the table creation SQL
command:
CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
This SQL command will create a table and an index on column Ainto the InnoDB tablespace
consisting of the datafiles you specified in ‘my.cnf’. In addition MySQL will create a file
CUSTOMER.frm’ to the MySQL database directory ‘test’. Internally, InnoDB will add to
its own data dictionary an entry for table ’test/CUSTOMER’. Thus you can create a table
of the same name CUSTOMER in another database of MySQL, and the table names will not
collide inside InnoDB.
You can query the amount of free space in the InnoDB tablespace by issuing the table status
command of MySQL for any table you have created with TYPE = InnoDB. Then the amount
of free space in the tablespace appears in the table comment section in the output of SHOW.
An example:
SHOW TABLE STATUS FROM test LIKE ’CUSTOMER’
Note that the statistics SHOW gives about InnoDB tables are only approximate: they are
used in SQL optimisation. Table and index reserved sizes in bytes are accurate, though.
7.5.5.1 Converting MyISAM Tables to InnoDB
InnoDB does not have a special optimisation for separate index creation. Therefore it does
not pay to export and import the table and create indexes afterwards. The fastest way to
alter a table to InnoDB is to do the inserts directly to an InnoDB table, that is, use ALTER
TABLE ... TYPE=INNODB, or create an empty InnoDB table with identical definitions and
insert the rows with INSERT INTO ... SELECT * FROM ....
To get better control over the insertion process, it may be good to insert big tables in pieces:
INSERT INTO newtable SELECT * FROM oldtable
WHERE yourkey > something AND yourkey <= somethingelse;
After all data has been inserted you can rename the tables.
During the conversion of big tables you should set the InnoDB buffer pool size big to reduce
disk I/O. Not bigger than 80% of the physical memory, though. You should set InnoDB log
files big, and also the log buffer large.
Make sure you do not run out of tablespace: InnoDB tables take a lot more space than
MyISAM tables. If an ALTER TABLE runs out of space, it will start a rollback, and that can
take hours if it is disk-bound. In inserts InnoDB uses the insert buffer to merge secondary
index records to indexes in batches. That saves a lot of disk I/O. In rollback no such
mechanism is used, and the rollback can take 30 times longer than the insertion.
In the case of a runaway rollback, if you do not have valuable data in your database, it is
better that you kill the database process and delete all InnoDB data and log files and all
InnoDB table ‘.frm’ files, and start your job again, rather than wait for millions of disk
I/Os to complete.
512 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
7.5.5.2 Foreign Key Constraints
Starting from version 3.23.43b InnoDB features foreign key constraints. InnoDB is the first
MySQL table type which allows you to define foreign key constraints to guard the integrity
of your data.
The syntax of a foreign key constraint definition in InnoDB:
[CONSTRAINT symbol] FOREIGN KEY (index_nome_coluna, ...)
REFERENCES table_name (index_nome_coluna, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
Both tables have to be InnoDB type and there must be an index where the foreign key and
the referenced key are listed as the FIRST columns. InnoDB does not auto-create indexes
on foreign keys or referenced keys: you have to create them explicitly.
Corresponding columns in the foreign key and the referenced key must have similar internal
data types inside InnoDB so that they can be compared without a type conversion. The
size and the signedness of integer types has to be the same. The length of string types
need not be the same. If you specify a SET NULL action, make sure you have not declared
the columns in the child table NOT NULL.
If MySQL gives the error number 1005 from a CREATE TABLE statement, and the error
message string refers to errno 150, then the table creation failed because a foreign key
constraint was not correctly formed. Similarly, if an ALTER TABLE fails and it refers to errno
150, that means a foreign key definition would be incorrectly formed for the altered table.
Starting from version 3.23.50 you can also associate the ON DELETE CASCADE or ON DELETE
SET NULL clause with the foreign key constraint. Starting from version 4.0.8 you can use
also similar ON UPDATE actions.
If ON DELETE CASCADE is specified, and a row in the parent table is deleted, then InnoDB
automatically deletes also all those rows in the child table whose foreign key values are
equal to the referenced key value in the parent row. If ON DELETE SET NULL is specified, the
child rows are automatically updated so that the columns in the foreign key are set to the
SQL NULL value.
Starting from version 3.23.50, InnoDB does not check foreign key constraints on those
foreign key or referenced key values which contain a NULL column.
Starting from version 3.23.50 the InnoDB parser allows you to use backquotes (‘) around
table and column names in the FOREIGN KEY ... REFERENCES ... clause but the InnoDB
parser is not yet aware of the option lower_case_table_names you can specify in ‘my.cnf’.
An example:
CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT, INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE SET NULL
) TYPE=INNODB;
Starting from version 3.23.50 InnoDB allows you to add a new foreign key constraint to a
table through
Chapter 7: MySQL Table Types 513
ALTER TABLE yourtablename
ADD [CONSTRAINT symbol] FOREIGN KEY (...) REFERENCES anothertablename(...)
[on_delete_and_on_update_actions]
Remember to create the required indexes first, though.
In InnoDB versions <3.23.50 ALTER TABLE or CREATE INDEX should not be used in connec-
tion with tables which have foreign key constraints or which are referenced in foreign key
constraints: Any ALTER TABLE removes all foreign key constrainst defined for the table. You
should not use ALTER TABLE to the referenced table either, but use DROP TABLE and CREATE
TABLE to modify the schema. When MySQL does an ALTER TABLE it may internally use
RENAME TABLE, and that will confuse the foreign key costraints which refer to the table. A
CREATE INDEX statement is in MySQL processed as an ALTER TABLE, and these restrictions
apply also to it.
When doing foreign key checks InnoDB sets shared row level locks on child or parent records
it has to look at. InnoDB checks foreign key constraints immediately: the check is not
deferred to transaction commit.
InnoDB allows you to drop any table even though that would break the foreign key con-
straints which reference the table. When you drop a table the constraints which were defined
in its create statement are also dropped.
If you re-create a table which was dropped, it has to have a definition which conforms to
the foreign key constraints referencing it. It must have the right column names and types,
and it must have indexes on the referenced keys, as stated above. If these are not satisfied,
MySQL returns error number 1005 and refers to errno 150 in the error message string.
Starting from version 3.23.50 InnoDB returns the foreign key definitions of a table when
you call
SHOW CREATE TABLE yourtablename
Then also ‘mysqldump’ produces correct definitions of tables to the dump file, and does not
forget about the foreign keys.
You can also list the foreign key constraints for a table Twith
SHOW TABLE STATUS FROM yourdatabasename LIKE ’T’
The foreign key constraints are listed in the table comment of the output.
7.5.6 Adding and Removing InnoDB Data and Log Files
From version 3.23.50 and 4.0.2 you can specify the last InnoDB datafile to autoextend.
Alternatively, you can increase to your tablespace by specifying an additional datafile. To
do this you have to shut down the MySQL server, edit the ‘my.cnf’ file adding a new datafile
to innodb_data_file_path, and then start the MySQL server again.
Currently you cannot remove a datafile from InnoDB. To decrease the size of your database
you have to use ‘mysqldump’ to dump all your tables, create a new database, and import
your tables to the new database.
If you want to change the number or the size of your InnoDB log files, you have to shut
down MySQL and make sure that it shuts down without errors. Then copy the old log
files into a safe place just in case something went wrong in the shutdown and you will need
them to recover the database. Delete then the old log files from the log file directory, edit
514 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
my.cnf’, and start MySQL again. InnoDB will tell you at the startup that it is creating
new log files.
7.5.7 Backing up and Recovering an InnoDB Database
The key to safe database management is taking regular backups.
InnoDB Hot Backup is an online backup tool you can use to backup your InnoDB database
while it is running. InnoDB Hot Backup does not require you to shut down your database
and it does not set any locks or disturb your normal database processing. InnoDB Hot
Backup is a non-free additional tool which is not included in the standard MySQL distri-
bution. See the InnoDB Hot Backup homepage http://www.innodb.com/hotbackup.html
for detailed information and screenshots.
If you are able to shut down your MySQL server, then to take a ’binary’ backup of your
database you have to do the following:
Shut down your MySQL database and make sure it shuts down without errors.
Copy all your datafiles into a safe place.
Copy all your InnoDB log files to a safe place.
Copy your ‘my.cnf’ configuration file(s) to a safe place.
Copy all the ‘.frm’ files for your InnoDB tables into a safe place.
In addition to taking the binary backups described above, you should also regularly take
dumps of your tables with ‘mysqldump’. The reason to this is that a binary file may be
corrupted without you noticing it. Dumped tables are stored into text files which are human-
readable and much simpler than database binary files. Seeing table corruption from dumped
files is easier, and since their format is simpler, the chance for serious data corruption in
them is smaller.
A good idea is to take the dumps at the same time you take a binary backup of your
database. You have to shut out all clients from your database to get a consistent snapshot
of all your tables into your dumps. Then you can take the binary backup, and you will then
have a consistent snapshot of your database in two formats.
To be able to recover your InnoDB database to the present from the binary backup described
above, you have to run your MySQL database with the general logging and log archiving of
MySQL switched on. Here by the general logging we mean the logging mechanism of the
MySQL server which is independent of InnoDB logs.
To recover from a crash of your MySQL server process, the only thing you have to do
is to restart it. InnoDB will automatically check the logs and perform a roll-forward of
the database to the present. InnoDB will automatically roll back uncommitted transac-
tions which were present at the time of the crash. During recovery, InnoDB will print out
something like the following:
~/mysqlm/sql > mysqld
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
Chapter 7: MySQL Table Types 515
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections
If your database gets corrupted or your disk fails, you have to do the recovery from a backup.
In the case of corruption, you should first find a backup which is not corrupted. From a
backup do the recovery from the general log files of MySQL according to instructions in the
MySQL manual.
7.5.7.1 Checkpoints
InnoDB implements a checkpoint mechanism called a fuzzy checkpoint. InnoDB will flush
modified database pages from the buffer pool in small batches, there is no need to flush
the buffer pool in one single batch, which would in practice stop processing of user SQL
statements for a while.
In crash recovery InnoDB looks for a checkpoint label written to the log files. It knows that
all modifications to the database before the label are already present on the disk image of
the database. Then InnoDB scans the log files forward from the place of the checkpoint
applying the logged modifications to the database.
InnoDB writes to the log files in a circular fashion. All committed modifications which make
the database pages in the buffer pool different from the images on disk must be available
in the log files in case InnoDB has to do a recovery. This means that when InnoDB starts
to reuse a log file in the circular fashion, it has to make sure that the database page images
on disk already contain the modifications logged in the log file InnoDB is going to reuse. In
other words, InnoDB has to make a checkpoint and often this involves flushing of modified
database pages to disk.
The above explains why making your log files very big may save disk I/O in checkpointing.
It can make sense to set the total size of the log files as big as the buffer pool or even bigger.
The drawback in big log files is that crash recovery can last longer because there will be
more log to apply to the database.
7.5.8 Moving an InnoDB Database to Another Machine
InnoDB data and log files are binary-compatible on all platforms if the floating-point num-
ber format on the machines is the same. You can move an InnoDB database simply by
516 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
copying all the relevant files, which we already listed in the previous section on backing up
a database. If the floating-point formats on the machines are different but you have not
used FLOAT or DOUBLE data types in your tables then the procedure is the same: just copy
the relevant files. If the formats are different and your tables contain floating-point data,
you have to use ‘mysqldump’ and ‘mysqlimport’ to move those tables.
A performance tip is to switch off auto-commit mode when you import data into your
database, assuming your tablespace has enough space for the big rollback segment the big
import transaction will generate. Do the commit only after importing a whole table or a
segment of a table.
7.5.9 InnoDB Transaction Model
In the InnoDB transaction model the goal has been to combine the best properties of a
multi-versioning database to traditional two-phase locking. InnoDB does locking on row
level and runs queries by default as non-locking consistent reads, in the style of Oracle.
The lock table in InnoDB is stored so space-efficiently that lock escalation is not needed:
typically several users are allowed to lock every row in the database, or any random subset
of the rows, without InnoDB running out of memory.
In InnoDB all user activity happens inside transactions. If the autocommit mode is used
in MySQL, then each SQL statement will form a single transaction. MySQL always starts
a new connection with the autocommit mode switched on.
If the autocommit mode is switched off with SET AUTOCOMMIT = 0, then we can think that
a user always has a transaction open. If he issues the SQL COMMIT or ROLLBACK statement,
it ends the current transaction, and a new starts. Both statements will release all InnoDB
locks that were set during the current transaction. A COMMIT means that the changes
made in the current transaction are made permanent and become visible to other users. A
ROLLBACK, on the other hand, cancels all modifications made by the current transaction.
If the connection has AUTOCOMMIT = 1, then the user can still perform a multi-statement
transaction by starting it with BEGIN and ending it with COMMIT or ROLLBACK.
In terms of the SQL-92 transaction isolation levels, the InnoDB default is REPEATABLE
READ. Starting from version 4.0.5, InnoDB offers all 4 different transaction isolation levels
described by the SQL-92 standard. You can set the default isolation level for all connections
in the [mysqld] section of ‘my.cnf’:
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED
| REPEATABLE-READ | SERIALIZABLE}
A user can change the isolation level of a single session or all new incoming connections
with the
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED
| REPEATABLE READ | SERIALIZABLE}
SQL statement. Note that there are no hyphens in level names in the SQL syntax. If you
specify the keyword GLOBAL in the above statement, it will determine the initial isolation
level of new incoming connections, but will not change the isolation level of old connections.
Chapter 7: MySQL Table Types 517
Any user is free to change the isolation level of his session, even in the middle of a transac-
tion. In versions <3.23.50 SET TRANSACTION had no effect on InnoDB tables. In versions <
4.0.5 only REPEATABLE READ and SERIALIZABLE were available.
You can query the global and session transaction isolation levels with:
SELECT @@global.tx_isolation;
SELECT @@tx_isolation;
In row level locking InnoDB uses so-called next-key locking. That means that besides index
records, InnoDB can also lock the ’gap’ before an index record to block insertions by other
users immediately before the index record. A next-key lock means a lock which locks an
index record and the gap before it. A gap lock means a lock which only locks a gap before
some index record.
A detailed description of each isolation level in InnoDB:
READ UNCOMMITTED This is also called ’dirty read’: non-locking SELECTs are performed
so that we do not look at a possible earlier version of a record; thus they are not ’con-
sistent’ reads under this isolation level; otherwise this level works like READ COMMITTED.
READ COMMITTED Somewhat Oracle-like isolation level. All SELECT ... FOR UPDATE and
SELECT ... LOCK IN SHARE MODE statements only lock the index records, NOT the gaps
before them, and thus allow free inserting of new records next to locked records. UPDATE
and DELETE which use a unique index with a unique search condition, only lock the
index record found, not the gap before it. But still in range type UPDATE and DELETE
InnoDB must set next-key or gap locks and block insertions by other users to the
gaps covered by the range. This is necessary since ’phantom rows’ have to be blocked
for MySQL replication and recovery to work. Consistent reads behave like in Oracle:
each consistent read, even within the same transaction, sets and reads its own fresh
snapshot.
REPEATABLE READ This is the default isolation level of InnoDB. SELECT ... FOR UPDATE,
SELECT ... LOCK IN SHARE MODE,UPDATE, and DELETE which use a unique index with
a unique search condition, only lock the index record found, not the gap before it.
Otherwise these operations employ next-key locking, locking the index range scanned
with next-key or gap locks, and block new insertions by other users. In consistent
reads there is an important difference from the previous isolation level: in this level
all consistent reads within the same transaction read the same snapshot established by
the first read. This convention means that if you issue several plain SELECTs within
the same transaction, these SELECTs are consistent also with respect to each other.
SERIALIZABLE This level is like the previous one, but all plain SELECTs are implicitly
converted to SELECT ... LOCK IN SHARE MODE.
7.5.9.1 Consistent Read
A consistent read means that InnoDB uses its multi-versioning to present to a query a
snapshot of the database at a point in time. The query will see the changes made by
exactly those transactions that committed before that point of time, and no changes made
by later or uncommitted transactions. The exception to this rule is that the query will see
the changes made by the transaction itself which issues the query.
If you are running with the default REPEATABLE READ isolation level, then all consistent
reads within the same transaction read the snapshot established by the first such read in
518 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
that transaction. You can get a fresher snapshot for your queries by committing the current
transaction and after that issuing new queries.
Consistent read is the default mode in which InnoDB processes SELECT statements in READ
COMMITTED and REPEATABLE READ isolation levels. A consistent read does not set any locks
on the tables it accesses, and therefore other users are free to modify those tables at the
same time a consistent read is being performed on the table.
7.5.9.2 Locking Reads
A consistent read is not convenient in some circumstances. Suppose you want to add a
new row into your table CHILD, and make sure that the child already has a parent in table
PARENT.
Suppose you use a consistent read to read the table PARENT and indeed see the parent of
the child in the table. Can you now safely add the child row to table CHILD? No, because
it may happen that meanwhile some other user has deleted the parent row from the table
PARENT, and you are not aware of that.
The solution is to perform the SELECT in a locking mode, LOCK IN SHARE MODE.
SELECT * FROM PARENT WHERE NAME = ’Jones’ LOCK IN SHARE MODE;
Performing a read in share mode means that we read the latest available data, and set a
shared mode lock on the rows we read. If the latest data belongs to a yet uncommitted
transaction of another user, we will wait until that transaction commits. A shared mode
lock prevents others from updating or deleting the row we have read. After we see that the
above query returns the parent ’Jones’, we can safely add his child to table CHILD, and
commit our transaction. This example shows how to implement referential integrity in your
application code.
Let us look at another example: we have an integer counter field in a table CHILD_CODES
which we use to assign a unique identifier to each child we add to table CHILD. Obviously,
using a consistent read or a shared mode read to read the present value of the counter is not
a good idea, since then two users of the database may see the same value for the counter,
and we will get a duplicate key error when we add the two children with the same identifier
to the table.
In this case there are two good ways to implement the reading and incrementing of the
counter: (1) update the counter first by incrementing it by 1 and only after that read it, or
(2) read the counter first with a lock mode FOR UPDATE, and increment after that:
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE;
UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;
ASELECT ... FOR UPDATE will read the latest available data setting exclusive locks on each
row it reads. Thus it sets the same locks a searched SQL UPDATE would set on the rows.
7.5.9.3 Next-key Locking: Avoiding the Phantom Problem
In row level locking InnoDB uses an algorithm called next-key locking. InnoDB does the row
level locking so that when it searches or scans an index of a table, it sets shared or exclusive
locks on the index records in encounters. Thus the row level locks are more precisely called
index record locks.
Chapter 7: MySQL Table Types 519
The locks InnoDB sets on index records also affect the ’gap’ before that index record. If a
user has a shared or exclusive lock on record R in an index, then another user cannot insert
a new index record immediately before R in the index order. This locking of gaps is done to
prevent the so-called phantom problem. Suppose I want to read and lock all children with
identifier bigger than 100 from table CHILD, and update some field in the selected rows.
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
Suppose there is an index on table CHILD on column ID. Our query will scan that index
starting from the first record where ID is bigger than 100. Now, if the locks set on the
index records would not lock out inserts made in the gaps, a new child might meanwhile be
inserted to the table. If now I in my transaction execute
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
again, I will see a new child in the result set the query returns. This is against the isolation
principle of transactions: a transaction should be able to run so that the data it has read
does not change during the transaction. If we regard a set of rows as a data item, then the
new ’phantom’ child would break this isolation principle.
When InnoDB scans an index it can also lock the gap after the last record in the index.
Just that happens in the previous example: the locks set by InnoDB will prevent any insert
to the table where ID would be bigger than 100.
You can use next-key locking to implement a uniqueness check in your application: if you
read your data in share mode and do not see a duplicate for a row you are going to insert,
then you can safely insert your row and know that the next-key lock set on the successor
of your row during the read will prevent anyone meanwhile inserting a duplicate for your
row. Thus the next-key locking allows you to ’lock’ the non-existence of something in your
table.
7.5.9.4 Locks Set by Different SQL Statements in InnoDB
SELECT ... FROM ... : this is a consistent read, reading a snapshot of the database
and setting no locks.
SELECT ... FROM ... LOCK IN SHARE MODE : sets shared next-key locks on all index
records the read encounters.
SELECT ... FROM ... FOR UPDATE : sets exclusive next-key locks on all index records
the read encounters.
INSERT INTO ... VALUES (...) : sets an exclusive lock on the inserted row; note that
this lock is not a next-key lock and does not prevent other users from inserting to the
gap before the inserted row. If a duplicate key error occurs, sets a shared lock on the
duplicate index record.
INSERT INTO T SELECT ... FROM S WHERE ... sets an exclusive (non-next-key) lock on
each row inserted into T. Does the search on Sas a consistent read, but sets shared
next-key locks on Sif the MySQL logging is on. InnoDB has to set locks in the latter
case because in roll-forward recovery from a backup every SQL statement has to be
executed in exactly the same way as it was done originally.
CREATE TABLE ... SELECT ... performs the SELECT as a consistent read or with shared
locks, like in the previous item.
520 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
REPLACE is done like an insert if there is no collision on a unique key. Otherwise, an
exclusive next-key lock is placed on the row which has to be updated.
UPDATE ... SET ... WHERE ... : sets an exclusive next-key lock on every record the
search encounters.
DELETE FROM ... WHERE ... : sets an exclusive next-key lock on every record the search
encounters.
If a FOREIGN KEY constraint is defined on a table, any insert, update, or delete which
requires checking of the constraint condition sets shared record level locks on the records
it looks at to check the constraint. Also in the case where the constraint fails, InnoDB
sets these locks.
LOCK TABLES ... : sets table locks. In the implementation the MySQL layer of code
sets these locks. The automatic deadlock detection of InnoDB cannot detect deadlocks
where such table locks are involved: see the following section. Also, since MySQL does
know about row level locks, it is possible that you get a table lock on a table where
another user currently has row level locks. But that does not put transaction integerity
into danger. See hundefinedi[InnoDB restrictions], page hundefinedi.
7.5.9.5 Deadlock Detection and Rollback
InnoDB automatically detects a deadlock of transactions and rolls back a transaction or
transactions to prevent the deadlock. Starting from version 4.0.5, InnoDB will try to pick
small transactions to roll back. The size of a transaction is determined by the number of
rows it has inserted, updated, or deleted. Previous to 4.0.5, InnoDB always rolled back the
transaction whose lock request was the last one to build a deadlock, that is, a cycle in the
waits-for graph of transactions.
InnoDB cannot detect deadlocks where a lock set by a MySQL LOCK TABLES statement is
involved, or if a lock set in another storage engine than InnoDB is involved. You have to
resolve these situations using innodb_lock_wait_timeout set in ‘my.cnf’.
When InnoDB performs a complete rollback of a transaction, all the locks of the transaction
are released. However, if just a single SQL statement is rolled back as a result of an error,
some of the locks set by the SQL statement may be preserved. This is because InnoDB
stores row locks in a format where it cannot afterwards know which was set by which SQL
statement.
7.5.9.6 An Example of How the Consistent Read Works in
InnoDB
Suppose you are running on the default REPEATABLE READ isolation level. When you issue a
consistent read, that is, an ordinary SELECT statement, InnoDB will give your transaction a
timepoint according to which your query sees the database. Thus, if transaction B deletes a
row and commits after your timepoint was assigned, then you will not see the row deleted.
Similarly with inserts and updates.
You can advance your timepoint by committing your transaction and then doing another
SELECT.
This is called multi-versioned concurrency control.
Chapter 7: MySQL Table Types 521
User A User B
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| empty set
| INSERT INTO t VALUES (1, 2);
|
v SELECT * FROM t;
empty set
COMMIT;
SELECT * FROM t;
empty set;
COMMIT;
SELECT * FROM t;
---------------------
|1|2|
---------------------
Thus user A sees the row inserted by B only when B has committed the insert, and A has
committed his own transaction so that the timepoint is advanced past the commit of B.
If you want to see the “freshest” state of the database, you should use a locking read:
SELECT * FROM t LOCK IN SHARE MODE;
7.5.9.7 How to cope with deadlocks?
Deadlocks are a classic problem in transactional databases, but they are not dangerous,
unless they are so frequent that you cannot run certain transactions at all. Normally you
have to write your applications so that they are always prepared to re-issue a transaction
if it gets rolled back because of a deadlock.
InnoDB uses automatic row level locking. You can get deadlocks even in the case of trans-
actions which just insert or delete a single row. That is because these operations are not
really ’atomic’: they automatically set locks on the (possibly several) index records of the
row inserted/deleted.
You can cope with deadlocks and reduce the number of them with the following tricks:
Use SHOW INNODB STATUS in MySQL versions >= 3.23.52 and >= 4.0.3 to determine
the cause of the latest deadlock. That can help you to tune your application to avoid
deadlocks.
Always be prepared to re-issue a transaction if it fails in a deadlock. Deadlocks are not
dangerous. Just try again.
Commit your transactions often. Small transactions are less prone to collide.
If you are using locking reads SELECT ... FOR UPDATE or ... LOCK IN SHARE MODE, try
using a lower isolation level READ COMMITTED.
522 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Access your tables and rows in a fixed order. Then transactions will form nice queues,
and do not deadlock.
Add good indexes to your tables. Then your queries need to scan less index records
and consequently set less locks. Use EXPLAIN SELECT to determine that MySQL picks
appropriate indexes for your queries.
Use less locking: if you can afford a SELECT to return data from an old snapshot, do
not add the clause FOR UPDATE or LOCK IN SHARE MODE to it. Using READ COMMITTED
isolation level is good here, because each consistent read within the same transaction
reads from its own fresh snapshot.
If nothing helps, serialize your transactions with table level locks: LOCK TABLES
t1 WRITE, t2 READ, ... ; [do something with tables t1 and t2 here]; UNLOCK
TABLES. Table level locks make you transactions to queue nicely, and deadlocks are
avoided. Note that LOCK TABLES implicitly starts a transaction, just like the command
BEGIN, and UNLOCK TABLES implicitly ends the transaction in a COMMIT.
Another solution to serialize transactions is to create an auxiliary ’semaphore’ table
where there is just a single row. Each transaction updates that row before accessing
other tables. In that way all transactions happen in a serial fashion. Note that then
also the InnoDB instant deadlock detection algorithm works, because the serializing
lock is a row level lock. In MySQL table level locks we have to resort to the timeout
method to resolve a deadlock.
7.5.9.8 Performance Tuning Tips
1. If the Unix ‘top’ or the Windows ‘Task Manager’ shows that the CPU usage percentage
with your workload is less than 70%, your workload is probably disk-bound. Maybe you are
making too many transaction commits, or the buffer pool is too small. Making the buffer
pool bigger can help, but do not set it bigger than 80% of physical memory.
2. Wrap several modifications into one transaction. InnoDB must flush the log to disk at
each transaction commit, if that transaction made modifications to the database. Since the
rotation speed of a disk is typically at most 167 revolutions/second, that constrains the
number of commits to the same 167/second if the disk does not fool the operating system.
3. If you can afford the loss of some latest committed transactions, you can set the ‘my.cnf
parameter innodb_flush_log_at_trx_commit to 0. InnoDB tries to flush the log once per
second anyway, though the flush is not guaranteed.
4. Make your log files big, even as big as the buffer pool. When InnoDB has written the
log files full, it has to write the modified contents of the buffer pool to disk in a checkpoint.
Small log files will cause many unnecessary disk writes. The drawback in big log files is
that recovery time will be longer.
5. Also the log buffer should be quite big, say 8 MB.
6. (Relevant from 3.23.39 up.) In some versions of Linux and Unix, flushing files to disk with
the Unix fdatasync and other similar methods is surprisingly slow. The default method
InnoDB uses is the fdatasync function. If you are not satisfied with the database write
performance, you may try setting innodb_flush_method in ‘my.cnf’ to O_DSYNC, though
O DSYNC seems to be slower on most systems.
Chapter 7: MySQL Table Types 523
7. In importing data to InnoDB, make sure that MySQL does not have autocommit=1 on.
Then every insert requires a log flush to disk. Put before your plain SQL import file line
SET AUTOCOMMIT=0;
and after it
COMMIT;
If you use the ‘mysqldump’ option --opt, you will get dump files which are fast to import
also to an InnoDB table, even without wrapping them to the above SET AUTOCOMMIT=0;
... COMMIT; wrappers.
8. Beware of big rollbacks of mass inserts: InnoDB uses the insert buffer to save disk I/O in
inserts, but in a corresponding rollback no such mechanism is used. A disk-bound rollback
can take 30 times the time of the corresponding insert. Killing the database process will
not help because the rollback will start again at the database startup. The only way to
get rid of a runaway rollback is to increase the buffer pool so that the rollback becomes
CPU-bound and runs fast, or delete the whole InnoDB database.
9. Beware also of other big disk-bound operations. Use DROP TABLE or TRUNCATE (from
MySQL-4.0 up) to empty a table, not DELETE FROM yourtable.
10. Use the multi-line INSERT to reduce communication overhead between the client and
the server if you need to insert many rows:
INSERT INTO yourtable VALUES (1, 2), (5, 5);
This tip is of course valid for inserts into any table type, not just InnoDB.
7.5.9.9 The InnoDB Monitor
Starting from version 3.23.41 InnoDB includes the InnoDB Monitor which prints informa-
tion on the InnoDB internal state. When switched on, InnoDB Monitor will make the
MySQL server ‘mysqld’ to print data (note: the MySQL client will not print anything) to
the standard output about once every 15 seconds. This data is useful in performance tuning.
On Windows you must start mysqld-max from a MS-DOS prompt with the --standalone
--console options to direct the output to the MS-DOS prompt window.
There is a separate innodb_lock_monitor which prints the same information as innodb_
monitor plus information on locks set by each transaction.
The printed information includes data on:
lock waits of a transactions,
semaphore waits of threads,
pending file I/O requests,
buffer pool statistics, and
purge and insert buffer merge activity of the main thread of InnoDB.
You can start InnoDB Monitor through the following SQL command:
CREATE TABLE innodb_monitor(a INT) type = innodb;
and stop it by
DROP TABLE innodb_monitor;
The CREATE TABLE syntax is just a way to pass a command to the InnoDB engine through
the MySQL SQL parser: the created table is not relevant at all for InnoDB Monitor. If you
524 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shut down the database when the monitor is running, and you want to start the monitor
again, you have to drop the table before you can issue a new CREATE TABLE to start the
monitor. This syntax may change in a future release.
A sample output of the InnoDB Monitor:
================================
010809 18:45:06 INNODB MONITOR OUTPUT
================================
--------------------------
LOCKS HELD BY TRANSACTIONS
--------------------------
LOCK INFO:
Number of locks in the record hash table 1294
LOCKS FOR TRANSACTION ID 0 579342744
TABLE LOCK table test/mytable trx id 0 582333343 lock_mode IX
RECORD LOCKS space id 0 page no 12758 n bits 104 table test/mytable index
PRIMARY trx id 0 582333343 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE;
info bits 0
0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";;
2: len 7; hex 000002001e03ec; asc ;; 3: len 4; hex 00000001;
...
-----------------------------------------------
CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS
-----------------------------------------------
SYNC INFO:
Sorry, cannot give mutex list info in non-debug version!
Sorry, cannot give rw-lock list info in non-debug version!
-----------------------------------------------------
SYNC ARRAY INFO: reservation count 6041054, signal count 2913432
4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0
Mut ex 0 sp 5530989 r 62038708 sys 2155035;
rws 0 8257574 8025336; rwx 0 1121090 1848344
-----------------------------------------------------
CURRENT PENDING FILE I/O’S
--------------------------
Pending normal aio reads:
Reserved slot, messages 40157658 4a4a40b8
Reserved slot, messages 40157658 4a477e28
...
Reserved slot, messages 40157658 4a4424a8
Reserved slot, messages 40157658 4a39ea38
Total of 36 reserved aio slots
Pending aio writes:
Total of 0 reserved aio slots
Pending insert buffer aio reads:
Total of 0 reserved aio slots
Pending log writes or reads:
Reserved slot, messages 40158c98 40157f98
Chapter 7: MySQL Table Types 525
Total of 1 reserved aio slots
Pending synchronous reads or writes:
Total of 0 reserved aio slots
-----------
BUFFER POOL
-----------
LRU list length 8034
Free list length 0
Flush list length 999
Buffer pool size in pages 8192
Pending reads 39
Pending writes: LRU 0, flush list 0, single page 0
Pages read 31383918, created 51310, written 2985115
----------------------------
END OF INNODB MONITOR OUTPUT
============================
010809 18:45:22 InnoDB starts purge
010809 18:45:22 InnoDB purged 0 pages
Some notes on the output:
If the section LOCKS HELD BY TRANSACTIONS reports lock waits, then your
application may have lock contention. The output can also help to trace reasons for
transaction deadlocks.
Section SYNC INFO will report reserved semaphores if you compile InnoDB with
UNIV_SYNC_DEBUG defined in ‘univ.i’.
Section SYNC ARRAY INFO reports threads waiting for a semaphore and statistics
on how many times threads have needed a spin or a wait on a mutex or a rw-lock
semaphore. A big number of threads waiting for semaphores may be a result of disk
I/O, or contention problems inside InnoDB. Contention can be due to heavy parallelism
of queries, or problems in operating system thread scheduling.
Section CURRENT PENDING FILE I/O’S lists pending file I/O requests. A large
number of these indicates that the workload is disk I/O-bound.
Section BUFFER POOL gives you statistics on pages read and written. You can
calculate from these numbers how many datafile I/Os your queries are currently doing.
7.5.10 Implementation of Multi-versioning
Since InnoDB is a multi-versioned database, it must keep information of old versions of
rows in the tablespace. This information is stored in a data structure we call a rollback
segment after an analogous data structure in Oracle.
InnoDB internally adds two fields to each row stored in the database. A 6-byte field tells
the transaction identifier for the last transaction which inserted or updated the row. Also
a deletion is internally treated as an update where a special bit in the row is set to mark
it as deleted. Each row also contains a 7-byte field called the roll pointer. The roll pointer
points to an undo log record written to the rollback segment. If the row was updated, then
the undo log record contains the information necessary to rebuild the content of the row
before it was updated.
526 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
InnoDB uses the information in the rollback segment to perform the undo operations needed
in a transaction rollback. It also uses the information to build earlier versions of a row for
a consistent read.
Undo logs in the rollback segment are divided into insert and update undo logs. Insert undo
logs are only needed in transaction rollback and can be discarded as soon as the transaction
commits. Update undo logs are used also in consistent reads, and they can be discarded
only after there is no transaction present for which InnoDB has assigned a snapshot that
in a consistent read could need the information in the update undo log to build an earlier
version of a database row.
You must remember to commit your transactions regularly, also those transactions which
only issue consistent reads. Otherwise InnoDB cannot discard data from the update undo
logs, and the rollback segment may grow too big, filling up your tablespace.
The physical size of an undo log record in the rollback segment is typically smaller than
the corresponding inserted or updated row. You can use this information to calculate the
space need for your rollback segment.
In our multi-versioning scheme a row is not physically removed from the database immedi-
ately when you delete it with an SQL statement. Only when InnoDB can discard the update
undo log record written for the deletion, it can also physically remove the corresponding
row and its index records from the database. This removal operation is called a purge, and
it is quite fast, usually taking the same order of time as the SQL statement which did the
deletion.
7.5.11 Table and Index Structures
MySQL stores its data dictionary information of tables in ‘.frm’ files in database directories.
But every InnoDB type table also has its own entry in InnoDB internal data dictionaries
inside the tablespace. When MySQL drops a table or a database, it has to delete both a
.frm’ file or files, and the corresponding entries inside the InnoDB data dictionary. This
is the reason why you cannot move InnoDB tables between databases simply by moving
the ‘.frm’ files, and why DROP DATABASE did not work for InnoDB type tables in MySQL
versions <= 3.23.43.
Every InnoDB table has a special index called the clustered index where the data of the
rows is stored. If you define a PRIMARY KEY on your table, then the index of the primary
key will be the clustered index.
If you do not define a primary key for your table, InnoDB will internally generate a clustered
index where the rows are ordered by the row id InnoDB assigns to the rows in such a table.
The row id is a 6-byte field which monotonically increases as new rows are inserted. Thus
the rows ordered by the row id will be physically in the insertion order.
Accessing a row through the clustered index is fast, because the row data will be on the
same page where the index search leads us. In many databases the data is traditionally
stored on a different page from the index record. If a table is large, the clustered index
architecture often saves a disk I/O when compared to the traditional solution.
The records in non-clustered indexes (we also call them secondary indexes), in InnoDB
contain the primary key value for the row. InnoDB uses this primary key value to search
for the row from the clustered index. Note that if the primary key is long, the secondary
indexes will use more space.
Chapter 7: MySQL Table Types 527
7.5.11.1 Physical Structure of an Index
All indexes in InnoDB are B-trees where the index records are stored in the leaf pages of the
tree. The default size of an index page is 16 KB. When new records are inserted, InnoDB
tries to leave 1 / 16 of the page free for future insertions and updates of the index records.
If index records are inserted in a sequential (ascending or descending) order, the resulting
index pages will be about 15/16 full. If records are inserted in a random order, then the
pages will be 1/2 - 15/16 full. If the fillfactor of an index page drops below 1/2, InnoDB
will try to contract the index tree to free the page.
7.5.11.2 Insert Buffering
It is a common situation in a database application that the primary key is a unique identifier
and new rows are inserted in the ascending order of the primary key. Thus the insertions
to the clustered index do not require random reads from a disk.
On the other hand, secondary indexes are usually non-unique and insertions happen in a
relatively random order into secondary indexes. This would cause a lot of random disk I/Os
without a special mechanism used in InnoDB.
If an index record should be inserted to a non-unique secondary index, InnoDB checks if
the secondary index page is already in the buffer pool. If that is the case, InnoDB will do
the insertion directly to the index page. But, if the index page is not found from the buffer
pool, InnoDB inserts the record to a special insert buffer structure. The insert buffer is
kept so small that it entirely fits in the buffer pool, and insertions can be made to it very
fast.
The insert buffer is periodically merged to the secondary index trees in the database. Often
we can merge several insertions on the same page in of the index tree, and hence save disk
I/Os. It has been measured that the insert buffer can speed up insertions to a table up to
15 times.
7.5.11.3 Adaptive Hash Indexes
If a database fits almost entirely in main memory, then the fastest way to perform queries
on it is to use hash indexes. InnoDB has an automatic mechanism which monitors index
searches made to the indexes defined for a table, and if InnoDB notices that queries could
benefit from building of a hash index, such an index is automatically built.
But note that the hash index is always built based on an existing B-tree index on the table.
InnoDB can build a hash index on a prefix of any length of the key defined for the B-tree,
depending on what search pattern InnoDB observes on the B-tree index. A hash index
can be partial: it is not required that the whole B-tree index is cached in the buffer pool.
InnoDB will build hash indexes on demand to those pages of the index which are often
accessed.
In a sense, through the adaptive hash index mechanism InnoDB adapts itself to ample main
memory, coming closer to the architecture of main memory databases.
528 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
7.5.11.4 Physical Record Structure
Each index record in InnoDB contains a header of 6 bytes. The header is used to link
consecutive records together, and also in the row level locking.
Records in the clustered index contain fields for all user-defined columns. In addition,
there is a 6-byte field for the transaction id and a 7-byte field for the roll pointer.
If the user has not defined a primary key for a table, then each clustered index record
contains also a 6-byte row id field.
Each secondary index record contains also all the fields defined for the clustered index
key.
A record contains also a pointer to each field of the record. If the total length of the
fields in a record is <128 bytes, then the pointer is 1 byte, else 2 bytes.
7.5.11.5 How an Auto-increment Column Works in InnoDB
After a database startup, when a user first does an insert to a table Twhere an auto-
increment column has been defined, and the user does not provide an explicit value for the
column, then InnoDB executes SELECT MAX(auto-inc-column) FROM T, and assigns that
value incremented by one to the column and the auto-increment counter of the table. We
say that the auto-increment counter for table Thas been initialised.
InnoDB follows the same procedure in initializing the auto-increment counter for a freshly
created table.
Note that if the user specifies in an insert the value 0 to the auto-increment column, then
InnoDB treats the row like the value would not have been specified.
After the auto-increment counter has been initialised, if a user inserts a row where he
explicitly specifies the column value, and the value is bigger than the current counter value,
then the counter is set to the specified column value. If the user does not explicitly specify a
value, then InnoDB increments the counter by one and assigns its new value to the column.
The auto-increment mechanism, when assigning values from the counter, bypasses locking
and transaction handling. Therefore you may also get gaps in the number sequence if you
roll back transactions which have got numbers from the counter.
The behaviour of auto-increment is not defined if a user gives a negative value to the column
or if the value becomes bigger than the maximum integer that can be stored in the specified
integer type.
7.5.12 File Space Management and Disk I/O
7.5.12.1 Disk I/O
In disk I/O InnoDB uses asynchronous I/O. On Windows NT it uses the native asynchronous
I/O provided by the operating system. On Unix, InnoDB uses simulated asynchronous I/O
built into InnoDB: InnoDB creates a number of I/O threads to take care of I/O operations,
such as read-ahead. In a future version we will add support for simulated aio on Windows
NT and native aio on those versions of Unix which have one.
Chapter 7: MySQL Table Types 529
On Windows NT InnoDB uses non-buffered I/O. That means that the disk pages InnoDB
reads or writes are not buffered in the operating system file cache. This saves some memory
bandwidth.
Starting from 3.23.41 InnoDB uses a novel file flush technique called doublewrite. It adds
safety to crash recovery after an operating system crash or a power outage, and improves
performance on most Unix flavors by reducing the need for fsync operations.
Doublewrite means that InnoDB before writing pages to a datafile first writes them to a
contiguous tablespace area called the doublewrite buffer. Only after the write and the flush
to the doublewrite buffer has completed, InnoDB writes the pages to their proper positions
in the datafile. If the operating system crashes in the middle of a page write, InnoDB will
in recovery find a good copy of the page from the doublewrite buffer.
Starting from 3.23.41 you can also use a raw disk partition as a datafile, though this has
not been tested yet. When you create a new datafile you have to put the keyword newraw
immediately after the data file-size in innodb_data_file_path. The partition must be >=
than you specify as the size. Note that 1M in InnoDB is 1024 x 1024 bytes, while in disk
specifications 1 MB usually means 1000 000 bytes.
innodb_data_file_path=hdd1:5Gnewraw;hdd2:2Gnewraw
When you start the database again you must change the keyword to raw. Otherwise,
InnoDB will write over your partition!
innodb_data_file_path=hdd1:5Graw;hdd2:2Graw
By using a raw disk you can on some Unixes perform unbuffered I/O.
There are two read-ahead heuristics in InnoDB: sequential read-ahead and random read-
ahead. In sequential read-ahead InnoDB notices that the access pattern to a segment in the
tablespace is sequential. Then InnoDB will post in advance a batch of reads of database
pages to the I/O system. In random read-ahead InnoDB notices that some area in a
tablespace seems to be in the process of being fully read into the buffer pool. Then InnoDB
posts the remaining reads to the I/O system.
7.5.12.2 File Space Management
The datafiles you define in the configuration file form the tablespace of InnoDB. The files
are simply catenated to form the tablespace, there is no striping in use. Currently you
cannot directly instruct where the space is allocated for your tables, except by using the
following fact: from a newly created tablespace InnoDB will allocate space starting from
the low end.
The tablespace consists of database pages whose default size is 16 KB. The pages are
grouped into extents of 64 consecutive pages. The ’files’ inside a tablespace are called
segments in InnoDB. The name of the rollback segment is somewhat misleading because it
actually contains many segments in the tablespace.
For each index in InnoDB we allocate two segments: one is for non-leaf nodes of the B-tree,
the other is for the leaf nodes. The idea here is to achieve better sequentiality for the leaf
nodes, which contain the data.
When a segment grows inside the tablespace, InnoDB allocates the first 32 pages to it
individually. After that InnoDB starts to allocate whole extents to the segment. InnoDB
can add to a large segment up to 4 extents at a time to ensure good sequentiality of data.
530 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Some pages in the tablespace contain bitmaps of other pages, and therefore a few extents in
an InnoDB tablespace cannot be allocated to segments as a whole, but only as individual
pages.
When you issue a query SHOW TABLE STATUS FROM ... LIKE ... to ask for available free
space in the tablespace, InnoDB will report the extents which are definitely free in the
tablespace. InnoDB always reserves some extents for clean-up and other internal purposes;
these reserved extents are not included in the free space.
When you delete data from a table, InnoDB will contract the corresponding B-tree indexes.
It depends on the pattern of deletes if that frees individual pages or extents to the tablespace,
so that the freed space is available for other users. Dropping a table or deleting all rows
from it is guaranteed to release the space to other users, but remember that deleted rows
can be physically removed only in a purge operation after they are no longer needed in
transaction rollback or consistent read.
7.5.12.3 Defragmenting a Table
If there are random insertions or deletions in the indexes of a table, the indexes may become
fragmented. By fragmentation we mean that the physical ordering of the index pages on
the disk is not close to the alphabetical ordering of the records on the pages, or that there
are many unused pages in the 64-page blocks which were allocated to the index.
It can speed up index scans if you periodically use mysqldump to dump the table to a text
file, drop the table, and reload it from the dump. Another way to do the defragmenting is
to ALTER the table type to MyISAM and back to InnoDB again. Note that a MyISAM table
must fit in a single file on your operating system.
If the insertions to and index are always ascending and records are deleted only from the
end, then the file space management algorithm of InnoDB guarantees that fragmentation
in the index will not occur.
7.5.13 Error Handling
The error handling in InnoDB is not always the same as specified in the SQL standard.
According to SQL-99, any error during an SQL statement should cause the rollback of
that statement. InnoDB sometimes rolls back only part of the statement, or the whole
transaction. The following list specifies the error handling of InnoDB.
If you run out of file space in the tablespace, you will get the MySQL ’Table is full’
error and InnoDB rolls back the SQL statement.
A transaction deadlock or a timeout in a lock wait make InnoDB to roll back the whole
transaction.
A duplicate key error only rolls back the insert of that particular row, even in a state-
ment like INSERT INTO ... SELECT .... This will probably change so that the SQL
statement will be rolled back if you have not specified the IGNORE option in your state-
ment.
A ’row too long’ error rolls back the SQL statement.
Other errors are mostly detected by the MySQL layer of code, and they roll back the
corresponding SQL statement.
Chapter 7: MySQL Table Types 531
7.5.14 Restrictions on InnoDB Tables
Warning: do NOT convert MySQL system tables from MyISAM TO InnoDB tables!
This is not supported; if you do this MySQL will not restart until you restore the old
system tables from a backup or re-generate them with the mysql_install_db script.
SHOW TABLE STATUS does not give accurate statistics on InnoDB tables, except for the
physical size reserved by the table. The row count is only a rough estimate used in
SQL optimisation.
If you try to create a unique index on a prefix of a column you will get an error:
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
If you create a non-unique index on a prefix of a column, InnoDB will create an index
over the whole column.
INSERT DELAYED is not supported for InnoDB tables.
The MySQL LOCK TABLES operation does not know of InnoDB row level locks set in
already completed SQL statements: this means that you can get a table lock on a table
even if there still exist transactions of other users which have row level locks on the
same table. Thus your operations on the table may have to wait if they collide with
these locks of other users. Also a deadlock is possible. However, this does not endanger
transaction integrity, because the row level locks set by InnoDB will always take care
of the integrity. Also, a table lock prevents other transactions from acquiring more row
level locks (in a conflicting lock mode) on the table.
You cannot have a key on a BLOB or TEXT column.
A table cannot contain more than 1000 columns.
DELETE FROM TABLE does not regenerate the table but instead deletes all rows, one by
one, which is not that fast. In future versions of MySQL you can use TRUNCATE which
is fast.
The default database page size in InnoDB is 16 KB. By recompiling the code one can
set it from 8 KB to 64 KB. The maximun row length is slightly less than half of a
database page in versions <= 3.23.40 of InnoDB. Starting from source release 3.23.41
BLOB and TEXT columns are allowed to be <4 GB, the total row length must also be <
4 GB. InnoDB does not store fields whose size is <= 128 bytes on separate pages. After
InnoDB has modified the row by storing long fields on separate pages, the remaining
length of the row must be less than half a database page. The maximun key length is
7000 bytes.
On some operating systems datafiles must be <2 GB. The combined size of log files
must be <4 GB.
The maximum tablespace size is 4 billion database pages. This is also the maximum
size for a table. The minimum tablespace size is 10 MB.
When you restart the MySQL server, InnoDB may reuse an old value for an AUTO_
INCREMENT column.
7.5.15 InnoDB Change History
532 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
7.5.15.1 MySQL/InnoDB-4.1.0, April, 2003
InnoDB now supports up to 64 GB of buffer pool memory in a Windows 32-bit Intel
computer. This is possible because InnoDB can use the AWE extension of Windows
to address memory over the 4 GB limit of a 32-bit process. A new startup variable
innodb buffer pool awe mem mb enables AWE and sets the size of the buffer pool in
megabytes.
Reduced the size of buffer headers and the lock table. InnoDB uses 2 % less memory.
7.5.15.2 MySQL/InnoDB-3.23.56, March, 2003
Fixed a major bug in InnoDB query optimisation: queries of type SELECT ... WHERE
indexcolumn <x and SELECT ... WHERE indexcolumn >x could cause a table scan
even if the selectivity would have been very good.
7.5.15.3 MySQL/InnoDB-4.0.12, March, 2003
In crash recovery InnoDB now prints the progress in percents of a transaction rollback.
7.5.15.4 MySQL/InnoDB-4.0.11, February 25, 2003
Fixed a bug introduced in 4.0.10: SELECT ... FROM ... ORDER BY ... DESC could
hang in an infinite loop.
An outstanding bug: SET FOREIGN KEY CHECKS=0 is not replicated properly in
the MySQL replication.
7.5.15.5 MySQL/InnoDB-4.0.10, February 4, 2003
In INSERT INTO t1 SELECT ... FROM t2 WHERE ... MySQL previously set a table
level read lock on t2. This lock is now removed.
Increased SHOW INNODB STATUS max printed length to 200 KB.
Fixed a major bug in InnoDB query optimisation: queries of type SELECT ... WHERE
indexcolumn <x and SELECT ... WHERE indexcolumn >x could cause a table scan
even if the selectivity would have been very good.
Fixed a bug: purge could cause a hang in a BLOB table where the primary key in-
dex tree was of height 1. Symptom: semaphore waits caused by an X-latch set in
btr free externally stored field().
Fixed a bug: using InnoDB HANDLER commands on a fresh handle crashed mysqld
in ha innobase::change active index().
Fixed a bug: if MySQL estimated a query in the middle of a SELECT statement,
InnoDB could hang on the adaptive hash index latch in btr0sea.c.
Fixed a bug: InnoDB could report table corruption and assert in
page dir find owner slot() if an adaptive hash index search coincided with
purge or an insert.
Fixed a bug: some file system snapshot tool in Windows 2000 could cause an InnoDB
file write to fail with error 33 ERROR LOCK VIOLATION. In synchronous writes
InnoDB now retries the write 100 times at 1 second intervals.
Chapter 7: MySQL Table Types 533
Fixed a bug: REPLACE INTO t1 SELECT ... did not work if t1 has an auto-inc
column.
An outstanding bug: SET FOREIGN KEY CHECKS=0 is not replicated properly in
the MySQL replication.
7.5.15.6 MySQL/InnoDB-3.23.55, January 24, 2003
In INSERT INTO t1 SELECT ... FROM t2 WHERE ... MySQL previously set a table
level read lock on t2. This lock is now removed.
Fixed a bug: if the combined size of InnoDB log files was >= 2 GB in a 32-bit computer,
InnoDB would write log in a wrong position. That could make crash recovery and
InnoDB Hot Backup to fail in log scan.
Fixed a bug: index cursor restoration could theoretically fail.
Fixed a bug: an assertion in btr0sea.c, in function btr search info update slow could
theoretically fail in a race of 3 threads.
Fixed a bug: purge could cause a hang in a BLOB table where the primary key in-
dex tree was of height 1. Symptom: semaphore waits caused by an X-latch set in
btr free externally stored field().
Fixed a bug: if MySQL estimated a query in the middle of a SELECT statement,
InnoDB could hang on the adaptive hash index latch in btr0sea.c.
Fixed a bug: InnoDB could report table corruption and assert in
page dir find owner slot() if an adaptive hash index search coincided with
purge or an insert.
Fixed a bug: some file system snapshot tool in Windows 2000 could cause an InnoDB
file write to fail with error 33 ERROR LOCK VIOLATION. In synchronous writes
InnoDB now retries the write 100 times at 1 second intervals.
An outstanding bug: SET FOREIGN KEY CHECKS=0 is not replicated properly
in the MySQL replication. The fix will appear in 4.0.11 and will probably not be
backported to 3.23.
Fixed bug in InnoDB page0cur.c in function page cur search with match which caused
InnoDB to remain on the same page forever. This bug is evident only in tables with
more than one page.
7.5.15.7 MySQL/InnoDB-4.0.9, January 14, 2003
Removed the warning message: ’InnoDB: Out of memory in additional memory pool.’
Fixed a bug: if the combined size of InnoDB log files was >= 2 GB in a 32-bit computer,
InnoDB would write log in a wrong position. That could make crash recovery and
InnoDB Hot Backup to fail.
Fixed a bug: index cursor restoration could theoretically fail.
7.5.15.8 MySQL/InnoDB-4.0.8, January 7, 2003
InnoDB now supports also FOREIGN KEY (...) REFERENCES ...(...) [ON UPDATE
CASCADE |ON UPDATE SET NULL |ON UPDATE RESTRICT |ON UPDATE
NO ACTION].
534 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Tables and indexes now reserve 4 % less space in the tablespace. Also existing tables
reserve less space. By upgrading to 4.0.8 you will see more free space in "InnoDB free"
in SHOW TABLE STATUS.
Fixed bugs: updating the PRIMARY KEY of a row would generate a foreign key error
on all FOREIGN KEYs which referenced secondary keys of the row to be updated.
Also, if a referencing FOREIGN KEY constraint only referenced the first columns in
an index, and there were more columns in that index, updating the additional columns
generated a foreign key error.
Fixed a bug: if an index contains some column twice, and that column is updated, the
table will become corrupt. From now on InnoDB prevents creation of such indexes.
Fixed a bug: removed superfluous error 149 and 150 printouts from the .err log when
a locking SELECT caused a deadlock or a lock wait timeout.
Fixed a bug: an assertion in btr0sea.c, in function btr search info update slow could
theoretically fail in a race of 3 threads.
Fixed a bug: one could not switch a session transaction isolation level back to RE-
PEATABLE READ after setting it to something else.
7.5.15.9 MySQL/InnoDB-4.0.7, December 26, 2002
InnoDB in 4.0.7 is essentially the same as in 4.0.6.
7.5.15.10 MySQL/InnoDB-4.0.6, December 19, 2002
Since innodb log arch dir has no relevance under MySQL, there is no need to specify
it any more in my.cnf.
LOAD DATA INFILE in AUTOCOMMIT=1 mode no longer does implicit commits
for each 1 MB of written binlog.
Fixed a bug introduced in 4.0.4: LOCK TABLES ... READ LOCAL should not set row
locks on the rows read. This caused deadlocks and lock wait timeouts in mysqldump.
Fixed two bugs introduced in 4.0.4: in AUTO INCREMENT, REPLACE could cause
the counter to be left 1 too low. A deadlock or a lock wait timeout could cause the
same problem.
Fixed a bug: TRUNCATE on a TEMPORARY table crashed InnoDB.
Fixed a bug introduced in 4.0.5: if binlogging was not switched on, INSERT INTO ...
SELECT ... or CREATE TABLE ... SELECT ... could cause InnoDB to hang on a
semaphore created in btr0sea.c, line 128. Workaround: switch binlogging on.
Fixed a bug: in replication issuing SLAVE STOP in the middle of a multi-statement
transaction could cause that SLAVE START would only perform a part of the trans-
action. A similar error could occur if the slave crashed and was restarted.
7.5.15.11 MySQL/InnoDB-3.23.54, December 12, 2002
Fixed a bug: the InnoDB range estimator greatly exaggerated the size of a short index
range if the paths to the endpoints of the range in the index tree happened to branch
already in the root. This could cause unnecessary table scans in SQL queries.
Chapter 7: MySQL Table Types 535
Fixed a bug: ORDER BY could fail if you had not created a primary key to a table,
but had defined several indexes of which at least one was a UNIQUE index with all its
columns declared as NOT NULL.
Fixed a bug: a lock wait timeout in connection with ON DELETE CASCADE could
cause corruption in indexes.
Fixed a bug: if a SELECT was done with a unique key from a primary index, and
the search matched to a delete-marked record, InnoDB could erroneously return the
NEXT record.
Fixed a bug introduced in 3.23.53: LOCK TABLES ... READ LOCAL should not
set row locks on the rows read. This caused deadlocks and lock wait timeouts in
mysqldump.
Fixed a bug: if an index contains some column twice, and that column is updated, the
table will become corrupt. From now on InnoDB prevents creation of such indexes.
7.5.15.12 MySQL/InnoDB-4.0.5, November 18, 2002
InnoDB now supports also transaction isolation levels READ COMMITTED and
READ UNCOMMITTED. READ COMMITTED more closely emulates Oracle and
makes porting of applications from Oracle to MySQL easier.
Deadlock resolution is now selective: we try to pick as victims transactions with less
modified or inserted rows.
FOREIGN KEY definitions are now aware of the lower case table names setting in
my.cnf.
SHOW CREATE TABLE does not output the database name to a FOREIGN KEY
definition if the referred table is in the same database as the table.
InnoDB does a consistency check to most index pages before writing them to a data
file.
If you set innodb force recovery >0, InnoDB tries to jump over corrupt index records
and pages when doing SELECT * FROM table. This helps in dumping.
InnoDB now again uses asynchronous unbuffered i/o in Windows 2000 and XP; only
unbuffered simulated async i/o in NT, 95/98/ME.
Fixed a bug: the InnoDB range estimator greatly exaggerated the size of a short index
range if the paths to the endpoints of the range in the index tree happened to branch
already in the root. This could cause unnecessary table scans in SQL queries. The fix
will also be backported to 3.23.54.
Fixed a bug present in 3.23.52, 4.0.3, 4.0.4: InnoDB startup could take very long or
even crash on some Win 95/98/ME computers.
Fixed a bug: the AUTO-INC lock was held to the end of the transaction if it was
granted after a lock wait. This could cause unnecessary deadlocks.
Fixed a bug: if SHOW INNODB STATUS, innodb monitor, or innodb lock monitor
had to print several hundred transactions in one report, and the output became trun-
cated, InnoDB would hang, printing to the error log many waits for a mutex created
at srv0srv.c, line 1621.
Fixed a bug: SHOW INNODB STATUS on Unix always reported average file read size
as 0 bytes.
536 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed a potential bug in 4.0.4: InnoDB now does ORDER BY ... DESC like MyISAM.
Fixed a bug: DROP TABLE could cause crash or a hang if there was a rollback
concurrently running on the table. The fix will only be backported to 3.23 if this
appears a real problem for users.
Fixed a bug: ORDER BY could fail if you had not created a primary key to a table,
but had defined several indexes of which at least one was a UNIQUE index with all its
columns declared as NOT NULL.
Fixed a bug: a lock wait timeout in connection with ON DELETE CASCADE could
cause corruption in indexes.
Fixed a bug: if a SELECT was done with a unique key from a primary index, and the
search matched to a delete-marked record, InnoDB could return the NEXT record.
Outstanding bugs: in 4.0.4 two bugs were introduced to AUTO INCREMENT. RE-
PLACE can cause the counter to be left 1 too low. A deadlock or a lock wait timeout
can cause the same problem. These will be fixed in 4.0.6.
7.5.15.13 MySQL/InnoDB-3.23.53, October 9, 2002
We again use unbuffered disk i/o to data files in Windows. Win XP and Win 2000
read performance seems to be very poor with normal i/o.
Tuned range estimator so that index range scans are preferred over full index scans.
Allow dropping and creating a table even if innodb force recovery is set. One can use
this to drop a table which would cause a crash in rollback or purge, or if a failed table
import causes a runaway rollback in recovery.
Fixed a bug present in 3.23.52, 4.0.3, 4.0.4: InnoDB startup could take very long or
even crash on some Win 95/98/ME computers.
Fixed a bug: fast shutdown (which is the default) sometimes was slowed down by purge
and insert buffer merge.
Fixed a bug: doing a big SELECT from a table where no rows were visible in a
consistent read could cause a very long (>600 seconds) semaphore wait in btr0cur.c
line 310.
Fixed a bug: the AUTO-INC lock was held to the end of the transaction if it was
granted after a lock wait. This could cause unnecessary deadlocks.
Fixed a bug: if you created a temporary table inside LOCK TABLES, and used that
temporary table, that caused an assertion failure in ha innobase.cc.
Fixed a bug: if SHOW INNODB STATUS, innodb monitor, or innodb lock monitor
had to print several hundred transactions in one report, and the output became trun-
cated, InnoDB would hang, printing to the error log many waits for a mutex created
at srv0srv.c, line 1621.
Fixed a bug: SHOW INNODB STATUS on Unix always reported average file read size
as 0 bytes.
7.5.15.14 MySQL/InnoDB-4.0.4, October 2, 2002
We again use unbuffered disk i/o in Windows. Win XP and Win 2000 read performance
seems to be very poor with normal i/o.
Chapter 7: MySQL Table Types 537
Increased the max key length of InnoDB tables from 500 to 1024 bytes.
Increased the table comment field in SHOW TABLE STATUS so that up to 16000
characters of foreign key definitions can be printed there.
The auto-increment counter is no longer incremented if an insert of a row immediately
fails in an error.
Allow dropping and creating a table even if innodb force recovery is set. One can use
this to drop a table which would cause a crash in rollback or purge, or if a failed table
import causes a runaway rollback in recovery.
Fixed a bug: Using ORDER BY primarykey DESC in 4.0.3 causes an assertion failure
in btr0pcur.c, line 203.
Fixed a bug: fast shutdown (which is the default) sometimes was slowed down by purge
and insert buffer merge.
Fixed a bug: doing a big SELECT from a table where no rows were visible in a
consistent read could cause a very long (>600 seconds) semaphore wait in btr0cur.c
line 310.
Fixed a bug: if the MySQL query cache was used, it did not get invalidated by a
modification done by ON DELETE CASCADE or ...SET NULL.
Fixed a bug: if you created a temporary table inside LOCK TABLES, and used that
temporary table, that caused an assertion failure in ha innodb.cc.
Fixed a bug: if you set innodb flush log at trx commit to 1, SHOW VARIABLES
would show its value as 16 million.
7.5.15.15 MySQL/InnoDB-4.0.3, August 28, 2002
Removed unnecessary deadlocks when inserts have to wait for a locking read, update,
or delete to release its next-key lock.
The MySQL HANDLER SQL commands now work also for InnoDB type tables. InnoDB
does the HANDLER reads always as consistent reads. HANDLER is a direct access path to
read individual indexes of tables. In some cases HANDLER can be used as a substitute
of server-side cursors.
Fixed a bug in 4.0.2: even a simple insert could crash the AIX version.
Fixed a bug: if you used in a table name characters whose code is >127, in DROP
TABLE InnoDB could assert on line 155 of pars0sym.c.
Compilation from source now provides a working version both on HP-UX-11 and HP-
UX-10.20. The source of 4.0.2 worked only on 11, and the source of 3.23.52 only on
10.20.
Fixed a bug: if compiled on 64-bit Solaris, InnoDB produced a bus error at startup.
7.5.15.16 MySQL/InnoDB-3.23.52, August 16, 2002
The feature set of 3.23 will be frozen from this version on. New features will go the 4.0
branch, and only bug fixes will be made to the 3.23 branch.
Many CPU-bound join queries now run faster. On Windows also many other CPU-
bound queries run faster.
538 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A new SQL command SHOW INNODB STATUS returns the output of the InnoDB
Monitor to the client. The InnoDB Monitor now prints detailed info on the latest
detected deadlock.
InnoDB made the SQL query optimiser to avoid too much index-only range scans and
choose full table scans instead. This is now fixed.
"BEGIN"and "COMMIT"are now added in the binlog around transactions. The
MySQL replication now respects transaction borders: a user will no longer see half
transactions in replication slaves.
A replication slave now prints in crash recovery the last master binlog position it was
able to recover to.
A new setting innodb flush log at trx commit=2 makes InnoDB to write the log to
the operating system file cache at each commit. This is almost as fast as the setting
innodb flush log at trx commit=0, and the setting 2 also has the nice feature that in a
crash where the operating system does not crash, no committed transaction is lost. If
the operating system crashes or there is a power outage, then the setting 2 is no safer
than the setting 0.
Added checksum fields to log blocks.
SET FOREIGN KEY CHECKS=0 helps in importing tables in an arbitrary order
which does not respect the foreign key rules.
SET UNIQUE CHECKS=0 speeds up table imports into InnoDB if you have UNIQUE
constraints on secondary indexes.
SHOW TABLE STATUS now lists also possible ON DELETE CASCADE or ON
DELETE SET NULL in the comment field of the table.
When CHECK TABLE is run on any InnoDB type table, it now checks also the adaptive
hash index for all tables.
If you defined ON DELETE CASCADE or SET NULL and updated the referenced key
in the parent row, InnoDB deleted or updated the child row. This is now changed to
conform to SQL-92: you get the error ’Cannot delete parent row’.
Improved the auto-increment algorithm: now the first insert or SHOW TABLE STA-
TUS initializes the auto-inc counter for the table. This removes almost all surprising
deadlocks caused by SHOW TABLE STATUS.
Aligned some buffers used in reading and writing to data files. This allows using
unbuffered raw devices as data files in Linux.
Fixed a bug: If you updated the primary key of a table so that only the case of
characters changed, that could cause assertion failures, mostly in page0page.ic line
515.
Fixed a bug: If you delete or update a row referenced in a foreign key constraint and
the foreign key check has to wait for a lock, then the check may report an erroneous
result. This affects also the ON DELETE... operation.
Fixed a bug: A deadlock or a lock wait timeout error in InnoDB causes InnoDB to roll
back the whole transaction, but MySQL could still write the earlier SQL statements
to the binlog, even though InnoDB rolled them back. This could, for example, cause
replicated databases to get out-of-sync.
Chapter 7: MySQL Table Types 539
Fixed a bug: If the database happened to crash in the middle of a commit, then the
recovery might leak tablespace pages.
Fixed a bug: If you specified a non-latin1 character set in my.cnf, then, in contrary to
what is stated in the manual, in a foreign key constraint a string type column had to
have the same length specification in the referencing table and the referenced table.
Fixed a bug: DROP TABLE or DROP DATABASE could fail if there simultaneously
was a CREATE TABLE running.
Fixed a bug: If you configured the buffer pool bigger than 2 GB in a 32-bit computer,
InnoDB would assert in buf0buf.ic line 214.
Fixed a bug: on 64-bit computers updating rows which contained the SQL NULL in
some column could cause the undo log and the ordinary log to become corrupt.
Fixed a bug: innodb log monitor caused a hang if it suppressed lock prints for a page.
Fixed a bug: in the HP-UX-10.20 version mutexes would leak and cause race conditions
and crashes in any part of InnoDB code.
Fixed a bug: if you ran in the AUTOCOMMIT mode, executed a SELECT, and
immediately after that a RENAME TABLE, then RENAME would fail and MySQL
would complain about error 1192.
Fixed a bug: if compiled on 64-bit Solaris, InnoDB produced a bus error at startup.
7.5.15.17 MySQL/InnoDB-4.0.2, July 10, 2002
InnoDB is essentially the same as InnoDB-3.23.51.
If no innodb data file path is specified, InnoDB at the database creation now creates a
10 MB auto-extending data file ibdata1 to the datadir of MySQL. In 4.0.1 the file was
64 MB and not auto-extending.
7.5.15.18 MySQL/InnoDB-3.23.51, June 12, 2002
Fixed a bug: a join could result in a seg fault in copying of a BLOB or TEXT column
if some of the BLOB or TEXT columns in the table contained SQL NULL values.
Fixed a bug: if you added self-referential foreign key constraints with ON DELETE
CASCADE to tables and a row deletion caused InnoDB to attempt the deletion of the
same row twice because of a cascading delete, then you got an assertion failure.
Fixed a bug: if you use MySQL ’user level locks’ and close a connection, then InnoDB
may assert in ha innobase.cc, line 302.
7.5.15.19 MySQL/InnoDB-3.23.50, April 23, 2002
InnoDB now supports an auto-extending last data file. You do not need to preallocate
the whole data file at the database startup.
Made several changes to facilitate the use of the InnoDB Hot Backup tool. It is a
separate non-free tool you can use to take online backups of your database without
shutting down the server or setting any locks.
If you want to run the InnoDB Hot Backup tool on an auto-extending data file you
have to upgrade it to version ibbackup-0.35.
540 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
The log scan phase in crash recovery will now run much faster.
Starting from this server version, the hot backup tool truncates unused ends in the
backup InnoDB data files.
To allow the hot backup tool to work, on Windows we no longer use unbuffered i/o or
native async i/o; instead we use the same simulated async i/o as on Unix.
You can now define the ON DELETE CASCADE or ON DELETE SET NULL clause
on foreign keys.
FOREIGN KEY constraints now survive ALTER TABLE and CREATE INDEX.
We suppress the FOREIGN KEY check if any of the column values in the foreign key
or referenced key to be checked is the SQL NULL. This is compatible with Oracle, for
example.
SHOW CREATE TABLE now lists also foreign key constraints. Also mysqldump no
longer forgets about foreign keys in table definitions.
You can now add a new foreign key constraint with ALTER TABLE ... ADD CON-
STRAINT FOREIGN KEY (...) REFERENCES ... (...).
FOREIGN KEY definitions now allow backquotes around table and column names.
MySQL command SET TRANSACTION ISOLATION LEVEL ... has now the fol-
lowing effect on InnoDB tables: if a transaction is defined as SERIALIZABLE then
InnoDB conceptually adds LOCK IN SHARE MODE to all consistent reads. If a
transaction is defined to have any other isolation level, then InnoDB obeys its default
locking strategy which is REPEATABLE READ.
SHOW TABLE STATUS no longer sets an x-lock at the end of an auto-increment index
if the auto-increment counter has already been initialized. This removes in almost all
cases the surprising deadlocks caused by SHOW TABLE STATUS.
Fixed a bug: in a CREATE TABLE statement the string ’foreign’ followed by a non-
space character confused the FOREIGN KEY parser and caused table creation to fail
with errno 150.
7.5.15.20 MySQL/InnoDB-3.23.49, February 17, 2002
Fixed a bug: if you called DROP DATABASE for a database on which there simulta-
neously were running queries, the MySQL server could crash or hang. Crashes fixed,
but a full fix has to wait some changes in the MySQL layer of code.
Fixed a bug: on Windows one had to put the database name in lower case for DROP
DATABASE to work. Fixed in 3.23.49: case no longer matters on Windows. On Unix
the database name remains case-sensitive.
Fixed a bug: if one defined a non-latin1 character set as the default character set, then
definition of foreign key constraints could fail in an assertion failure in dict0crea.c,
reporting an internal error 17.
7.5.15.21 MySQL/InnoDB-3.23.48, February 9, 2002
Tuned the SQL optimiser to favor more often index searches over table scans.
Fixed a performance problem when several large SELECT queries are run concurrently
on a multiprocessor Linux computer. Large CPU-bound SELECT queries will now also
generally run faster on all platforms.
Chapter 7: MySQL Table Types 541
If MySQL binlogging is used, InnoDB now prints after crash recovery the latest MySQL
binlog file name and the position in that file (= byte offset) InnoDB was able to recover
to. This is useful, for example, when resynchronizing a master and a slave database in
replication.
Added better error messages to help in installation problems.
One can now recover also MySQL temporary tables which have become orphaned inside
the InnoDB tablespace.
InnoDB now prevents a FOREIGN KEY declaration where the signedness is not the
same in the referencing and referenced integer columns.
Fixed a bug: calling SHOW CREATE TABLE or SHOW TABLE STATUS could cause
memory corruption and make mysqld to crash. Especially at risk was mysqldump,
because it calls frequently SHOW CREATE TABLE.
Fixed a bug: if on Unix you did an ALTER TABLE to an InnoDB table and simul-
taneously did queries to it, mysqld could crash with an assertion failure in row0row.c,
line 474.
Fixed a bug: if inserts to several tables containing an auto-inc column were wrapped
inside one LOCK TABLES, InnoDB asserted in lock0lock.c.
In 3.23.47 we allowed several NULLS in a UNIQUE secondary index. But CHECK
TABLE was not relaxed: it reports the table as corrupt. CHECK TABLE no longer
complains in this situation.
Fixed a bug: on Sparc and other high-endian processors SHOW VARIABLES showed
innodb flush log at trx commit and other boolean-valued startup parameters always
OFF even if they were switched on.
Fixed a bug: if you ran mysqld-max-nt as a service on Windows NT/2000, the service
shutdown did not always wait long enough for the InnoDB shutdown to finish.
7.5.15.22 MySQL/InnoDB-3.23.47, December 28, 2001
Recovery happens now faster, especially in a lightly loaded system, because background
checkpointing has been made more frequent.
InnoDB allows now several similar key values in a UNIQUE secondary index if those
values contain SQL NULLs. Thus the convention is now the same as in MyISAM
tables.
InnoDB gives a better row count estimate for a table which contains BLOBs.
In a FOREIGN KEY constraint InnoDB is now case-insensitive to column names, and
in Windows also to table names.
InnoDB allows a FOREIGN KEY column of CHAR type to refer to a column of VAR-
CHAR type, and vice versa. MySQL silently changes the type of some columns between
CHAR and VARCHAR, and these silent changes do not hinder FOREIGN KEY dec-
laration any more.
Recovery has been made more resilient to corruption of log files.
Unnecessary statistics calculation has been removed from queries which generate a
temporary table. Some ORDER BY and DISTINCT queries will now run much faster.
542 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MySQL now knows that the table scan of an InnoDB table is done through the primary
key. This will save a sort in some ORDER BY queries.
The maximum key length of InnoDB tables is again restricted to 500 bytes. The
MySQL interpreter is not able to handle longer keys.
The default value of innodb lock wait timeout was changed from infinite to 50 seconds,
the default value of innodb file io threads from 9 to 4.
7.5.15.23 MySQL/InnoDB-4.0.1, December 23, 2001
InnoDB is the same as in 3.23.47.
In 4.0.0 the MySQL interpreter did not know the syntax LOCK IN SHARE MODE.
This has been fixed.
In 4.0.0 multi-table delete did not work for transactional tables. This has been fixed.
7.5.15.24 MySQL/InnoDB-3.23.46, November 30, 2001
This is the same as 3.23.45.
7.5.15.25 MySQL/InnoDB-3.23.45, November 23, 2001
This is a bugfix release.
In versions 3.23.42-.44 when creating a table on Windows you have to use lower case
letters in the database name to be able to access the table. Fixed in 3.23.45.
InnoDB now flushes stdout and stderr every 10 seconds: if these are redirected to files,
the file contents can be better viewed with an editor.
Fixed an assertion failure in .44, in trx0trx.c, line 178 when you drop a table which has
the .frm file but does not exist inside InnoDB.
Fixed a bug in the insert buffer. The insert buffer tree could get into an inconsistent
state, causing a crash, and also crashing the recovery. This bug could appear especially
in large table imports or alterations.
Fixed a bug in recovery: InnoDB could go into an infinite loop constantly printing a
warning message that it cannot find free blocks from the buffer pool.
Fixed a bug: when you created a temporary table of the InnoDB type, and then used
ALTER TABLE to it, the MySQL server could crash.
Prevented creation of MySQL system tables ’mysql.user’, ’mysql.host’, or ’mysql.db’,
in the InnoDB type.
Fixed a bug which can cause an assertion failure in 3.23.44 in srv0srv.c, line 1728.
7.5.15.26 MySQL/InnoDB-3.23.44, November 2, 2001
You can define foreign key constraints on InnoDB tables. An example: FOREIGN
KEY (col1) REFERENCES table2(col2).
You can create >4 GB data files in those file systems that allow it.
Improved InnoDB monitors, including a new innodb table monitor which allows you
to print the contents of the InnoDB internal data dictionary.
Chapter 7: MySQL Table Types 543
DROP DATABASE will now work also for InnoDB tables.
Accent characters in the default character set latin1 will be ordered according to the
MySQL ordering.<br>NOTE: if you are using latin1 and have inserted characters
whose code is >127 to an indexed CHAR column, you should run CHECK TABLE on
your table when you upgrade to 3.23.43, and drop and reimport the table if CHECK
TABLE reports an error!
InnoDB will calculate better table cardinality estimates.
Change in deadlock resolution: in .43 a deadlock rolls back only the SQL statement,
in .44 it will roll back the whole transaction.
Deadlock, lock wait timeout, and foreign key constraint violations (no parent row, child
rows exist) now return native MySQL error codes 1213, 1205, 1216, 1217, respectively.
A new my.cnf parameter innodb thread concurrency helps in performance tuning in
high concurrency environments.
A new my.cnf option innodb force recovery will help you in dumping tables from a
corrupted database.
A new my.cnf option innodb fast shutdown will speed up shutdown. Normally InnoDB
does a full purge and an insert buffer merge at shutdown.
Raised maximum key length to 7000 bytes from a previous limit of 500 bytes.
Fixed a bug in replication of auto-inc columns with multiline inserts.
Fixed a bug when the case of letters changes in an update of an indexed secondary
column.
Fixed a hang when there are >24 data files.
Fixed a crash when MAX(col) is selected from an empty table, and col is a not the
first column in a multi-column index.
Fixed a bug in purge which could cause crashes.
7.5.15.27 MySQL/InnoDB-3.23.43, October 4, 2001
This is essentially the same as InnoDB-3.23.42.
7.5.15.28 MySQL/InnoDB-3.23.42, September 9, 2001
Fixed a bug which corrupted the table if the primary key of a >8000-byte row was
updated.
There are now 3 types of InnoDB Monitors: innodb monitor, innodb lock monitor, and
innodb tablespace monitor. innodb monitor now prints also buffer pool hit rate and
the total number of rows inserted, updated, deleted, read.
Fixed a bug in RENAME TABLE.
Fixed a bug in replication with an auto-increment column.
7.5.15.29 MySQL/InnoDB-3.23.41, August 13, 2001
Support for <4 GB rows. The previous limit was 8000 bytes.
Use the doublewrite file flush method.
544 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Raw disk partitions supported as data files.
InnoDB Monitor.
Several hang bugs fixed and an ORDER BY bug (’Sort aborted’) fixed.
7.5.15.30 MySQL/InnoDB-3.23.40, July 16, 2001
Only a few rare bugs fixed.
7.5.15.31 MySQL/InnoDB-3.23.39, June 13, 2001
CHECK TABLE now works for InnoDB tables.
A new my.cnf parameter innodb unix file flush method introduced. It can be used to
tune disk write performance.
An auto-increment column now gets new values past the transaction mechanism. This
saves CPU time and eliminates transaction deadlocks in new value assignment.
Several bug fixes, most notably the rollback bug in 3.23.38.
7.5.15.32 MySQL/InnoDB-3.23.38, May 12, 2001
The new syntax SELECT ... LOCK IN SHARE MODE is introduced.
InnoDB now calls fsync after every disk write and calculates a checksum for every
database page it writes or reads, which will reveal disk defects.
Several bug fixes.
7.5.16 InnoDB Contact Information
Contact information of Innobase Oy, producer of the InnoDB engine. Web site:
http://www.innodb.com/. E-mail: Heikki.Tuuri@innodb.com
phone: 358-9-6969 3250 (office) 358-40-5617367 (mobile)
Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O.Box 800
00101 Helsinki
Finland
7.6 BDB or BerkeleyDB Tables
7.6.1 Overview of BDB Tables
BerkeleyDB, available at http://www.sleepycat.com/ has provided MySQL with a trans-
actional storage engine. Support for this storage engine is included in the MySQL source
distribution starting from version 3.23.34 and is activated in the MySQL-Max binary. This
storage engine is typically called BDB for short.
BDB tables may have a greater chance of surviving crashes and are also capable of COMMIT
and ROLLBACK operations on transactions. The MySQL source distribution comes with a
Chapter 7: MySQL Table Types 545
BDB distribution that has a couple of small patches to make it work more smoothly with
MySQL. You can’t use a non-patched BDB version with MySQL.
We at MySQL AB are working in close cooperation with Sleepycat to keep the quality of
the MySQL/BDB interface high.
When it comes to supporting BDB tables, we are committed to help our users to locate the
problem and help creating a reproducible test case for any problems involving BDB tables.
Any such test case will be forwarded to Sleepycat who in turn will help us find and fix the
problem. As this is a two-stage operation, any problems with BDB tables may take a little
longer for us to fix than for other storage engines. However, as the BerkeleyDB code itself
has been used by many other applications than MySQL, we don’t envision any big problems
with this. See hundefinedi[Support], page hundefinedi.
7.6.2 Installing BDB
If you have downloaded a binary version of MySQL that includes support for BerkeleyDB,
simply follow the instructions for installing a binary version of MySQL. See hundefinedi
[Installing binary], page hundefinedi. See max-snt [mysqld-max], page max-pg.
To compile MySQL with Berkeley DB support, download MySQL Version 3.23.34 or newer
and configure MySQL with the --with-berkeley-db option. See hundefinedi[Installing
source], page hundefinedi.
cd /path/to/source/of/mysql-3.23.34
./configure --with-berkeley-db
Please refer to the manual provided with the BDB distribution for more updated information.
Even though Berkeley DB is in itself very tested and reliable, the MySQL interface is still
considered gamma quality. We are actively improving and optimising it to get it stable very
soon.
7.6.3 BDB startup options
If you are running with AUTOCOMMIT=0 then your changes in BDB tables will not be updated
until you execute COMMIT. Instead of commit you can execute ROLLBACK to forget your
changes. See hundefinedi[COMMIT], page hundefinedi.
If you are running with AUTOCOMMIT=1 (the default), your changes will be committed imme-
diately. You can start an extended transaction with the BEGIN WORK SQL command, after
which your changes will not be committed until you execute COMMIT (or decide to ROLLBACK
the changes).
The following options to mysqld can be used to change the behaviour of BDB tables:
Option Description
--bdb-
home=directory
Base directory for BDB tables. This should be
the same directory you use for --datadir.
--bdb-lock-
detect=#
Berkeley lock detect. One of (DEFAULT,OLDEST,
RANDOM, or YOUNGEST).
--bdb-
logdir=directory
Berkeley DB log file directory.
--bdb-no-sync Don’t synchronously flush logs.
--bdb-no-recover Don’t start Berkeley DB in recover mode.
546 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
--bdb-shared-data Start Berkeley DB in multi-process mode (Don’t
use DB_PRIVATE when initialising Berkeley DB)
--bdb-
tmpdir=directory
Berkeley DB temporary file directory.
--skip-bdb Disable usage of BDB tables.
-O bdb_max_
lock=1000
Set the maximum number of locks possible. See
hundefinedi[bdb_max_lock], page hundefinedi.
If you use --skip-bdb, MySQL will not initialise the Berkeley DB library and this will save
a lot of memory. Of course, you cannot use BDB tables if you are using this option. If you
try to create a BDB table, MySQL will instead create a MyISAM table.
Normally you should start mysqld without --bdb-no-recover if you intend to use BDB
tables. This may, however, give you problems when you try to start mysqld if the BDB log
files are corrupted. See hundefinedi[Starting server], page hundefinedi.
With bdb_max_lock you can specify the maximum number of locks (10000 by default) you
can have active on a BDB table. You should increase this if you get errors of type bdb:
Lock table is out of available locks or Got error 12 from ... when you have do long
transactions or when mysqld has to examine a lot of rows to calculate the query.
You may also want to change binlog_cache_size and max_binlog_cache_size if you are
using big multi-line transactions. See hundefinedi[COMMIT], page hundefinedi.
7.6.4 Characteristics of BDB tables:
To be able to rollback transactions, the BDB storage engine maintains log files. For
maximum performance you should place these on another disk than your databases by
using the --bdb-logdir option.
MySQL performs a checkpoint each time a new BDB log file is started, and removes any
log files that are not needed for current transactions. One can also run FLUSH LOGS at
any time to checkpoint the Berkeley DB tables.
For disaster recovery, one should use table backups plus MySQL’s binary log. See
hundefinedi[Backup], page hundefinedi.
Warning: If you delete old log files that are in use, BDB will not be able to do recovery
at all and you may lose data if something goes wrong.
MySQL requires a PRIMARY KEY in each BDB table to be able to refer to previously read
rows. If you don’t create one, MySQL will create an maintain a hidden PRIMARY KEY
for you. The hidden key has a length of 5 bytes and is incremented for each insert
attempt.
If all columns you access in a BDB table are part of the same index or part of the primary
key, then MySQL can execute the query without having to access the actual row. In a
MyISAM table the above holds only if the columns are part of the same index.
The PRIMARY KEY will be faster than any other key, as the PRIMARY KEY is stored to-
gether with the row data. As the other keys are stored as the key data +the PRIMARY
KEY, it’s important to keep the PRIMARY KEY as short as possible to save disk and get
better speed.
LOCK TABLES works on BDB tables as with other tables. If you don’t use LOCK TABLE,
MySQL will issue an internal multiple-write lock on the table to ensure that the table
will be properly locked if another thread issues a table lock.
Chapter 7: MySQL Table Types 547
Internal locking in BDB tables is done on page level.
SELECT COUNT(*) FROM table_name is slow as BDB tables doesn’t maintain a count of
the number of rows in the table.
Sequential scanning is slower than with MyISAM tables as the data in BDB tables stored
in B-trees and not in a separate datafile.
The application must always be prepared to handle cases where any change of a BDB
table may make an automatic rollback and any read may fail with a deadlock error.
Keys are not prefix or suffix-compressed like keys in MyISAM tables. In other words, the
key information will take a little more space in BDB tables compared to MyISAM tables.
There are often holes in the BDB table to allow you to insert new rows in the middle of
the key tree. This makes BDB tables somewhat larger than MyISAM tables.
The optimiser needs to know an approximation of the number of rows in the table.
MySQL solves this by counting inserts and maintaining this in a separate segment in
each BDB table. If you don’t issue a lot of DELETE or ROLLBACK statements, this number
should be accurate enough for the MySQL optimiser, but as MySQL only stores the
number on close, it may be incorrect if MySQL dies unexpectedly. It should not be
fatal even if this number is not 100% correct. One can update the number of rows by
executing ANALYZE TABLE or OPTIMIZE TABLE. See hundefinedi[ANALYZE TABLE],
page hundefinedi. See hundefinedi[OPTIMIZE TABLE], page hundefinedi.
If you get full disk with a BDB table, you will get an error (probably error 28) and the
transaction should roll back. This is in contrast with MyISAM and ISAM tables where
mysqld will wait for enough free disk before continuing.
7.6.5 Things we need to fix for BDB in the near future:
It’s very slow to open many BDB tables at the same time. If you are going to use
BDB tables, you should not have a very big table cache (like >256) and you should use
--no-auto-rehash with the mysql client. We plan to partly fix this in 4.0.
SHOW TABLE STATUS doesn’t yet provide that much information for BDB tables.
Optimise performance.
Change to not use page locks at all when we are scanning tables.
7.6.6 Operating systems supported by BDB
Currently we know that the BDB storage engine works with the following operating systems:
Linux 2.x Intel
Solaris SPARC
Caldera (SCO) OpenServer
Caldera (SCO) UnixWare 7.0.1
It doesn’t work with the following operating systems:
Linux 2.x Alpha
Max OS X
548 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note: The above list is not complete; we will update it as we receive more information.
If you build MySQL with support for BDB tables and get the following error in the log file
when you start mysqld:
bdb: architecture lacks fast mutexes: applications cannot be threaded
Can’t init dtabases
This means that BDB tables are not supported for your architecture. In this case you must
rebuild MySQL without BDB table support.
7.6.7 Restrictions on BDB Tables
Here follows the restrictions you have when using BDB tables:
BDB tables store in the ‘.db’ file the path to the file as it was created. (This was done
to be able to detect locks in a multi-user environment that supports symlinks).
The effect of this is that BDB tables are not movable between directories!
When taking backups of BDB tables, you have to either use mysqldump or take a backup
of all table_name.db files and the BDB log files. The BDB log files are the files in
the base data directory named log.XXXXXXXXXX (ten digits); The BDB storage engine
stores unfinished transactions in the log files and requires these logs to be present when
mysqld starts.
7.6.8 Errors That May Occur When Using BDB Tables
If you get the following error in the hostname.err log when starting mysqld:
bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
it means that the new BDB version doesn’t support the old log file format. In this case
you have to delete all BDB logs from your database directory (the files with names that
have the format log.XXXXXXXXXX) and restart mysqld. We would also recommend you
to do a mysqldump --opt of your old BDB tables, delete the old tables, and restore the
dump.
If you are not running in auto-commit mode and delete a table that is referenced in
another transaction, you may get the following error messages in your MySQL error
log:
001119 23:43:56 bdb: Missing log fileid entry
001119 23:43:56 bdb: txn_abort: Log undo failed for LSN:
1 3644744: Invalid
This is not fatal but we don’t recommend that you delete tables if you are not in
auto-commit mode, until this problem is fixed (the fix is not trivial).
Chapter 8: MySQL APIs 549
8 MySQL APIs
Este cap´
itulo descreve as APIs dispon´
iveis para o MySQL, onde consegui-las e como utiliz´a-
las. A API C ´e a coberta mais estensamente, j´a que ela foi desenvolvida pela equipe do
MySQL e ´e a base para a maioria das outras APIs.
8.1 API C do MySQL
O c´odigo da API C ´e distribu´
ido com o MySQL. Ele est´a inclu´
ido na biblioteca mysqlclient
e permite programas em C a fazer acesso em banco de dados.
Muitos dos clientes na distribui¸ao fonte do MySQL est´a escrito em C. Se vocˆe estiver
procurando por exemplos que demonstrem como utilizar a API C, dˆe uma olhada neste
clientes. Voe pode encontr´a-los no diret´orio clients na distribui¸ao fonte do MySQL.
A maioria das outras clientes API (todos exceto Connector/J) usam a biblioteca
mysqlclient para se comunicar com o servidor MySQL. Isto significa que, por exemplo,
vocˆe pode tirar vantagem das mesmas vari´aveis de ambientes que s˜ao utilizados por
outros programas clientes, pois eles referˆenciados pela biblioteca. Veja Side Scripts-snt
[Client-Side Scripts], page Side Scripts-pg, para uma lista destas vari´aveis.
O cliente tem um tamanho m´aximo de buffer de comunica¸ao. O tamanho do buffer que ´e
alocado inicialmente (16K bytes) ´e automaticamente aumentado para o tamanho m´aximo
(o m´aximo ´e 16M). Como o tamanho do buffer ´e aumentado somente como autoriza¸ao de
demanda, o simples aumento do limite m´aximo padr˜ao n˜ao faz, por si s´o, que mais recursos
sejam usado. Esta verifica¸ao de tamanho ´e na maioria verifica¸oes por consultas erradas e
pacotes de comunica¸oes.
O buffer de comunica¸ao deve ser grande o suficiente para conter uma ´unica instru¸ao
SQL (para tr´afego cliente-servidor) e uma linha de dado retornado (para trafico servidor-
cliente). Cada buffer de comunica¸ao de thread ´e dinamicamente aumentado para manipular
qualquer consulta ou linha at´e o limite m´aximo. Por exemplo, se vocˆe tiver valores BLOB
que contenham at´e 16M de dados, vocˆe deve ter um limite de buffer de comunica¸ao de pelo
menos 16M (no servidor e no cliente). A m´aximo padr˜ao do cliente ’16M. mas o m´aximo
padr˜ao no servidor ´e 1M. Voe pode aumentar iso alterando o valor do parˆametro max_
allowed_packet quando o servidor ´e iniciado. See hundefinedi[Par6ametros de servidor],
page hundefinedi.
O servidor MySQL encolhe cada buffer de comunica¸ao para net_buffer_length bytes
depois de cada consulta. Para clientes, o tamanho do buffer associado com um conex˜ao
ao ´e reduzido at´e que a conex˜ao seja fechada, quando a mem´oria de tempo do cliente ´e
recuperada.
Para programa¸ao com threads, veja hundefinedi[Threaded clients], page hundefinedi. Para
criar uma aplica¸ao stand-alone que inclua o "servidor"e o "cliente"no mesmo programa (e
que n˜ao comunica com um servidor MySQL externo), veja hundefinedi[libmysqld], page hun-
definedi.
8.1.1 Tipos de Dados da API C
MYSQL Esta estrutura representa um manpulador para uma conex˜ao ao banco de dados.
´
E usada para quase todas as fun¸oes MySQL.
550 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MYSQL_RES
Esta estrutura representa o resultado de uma consulta que retorna linhas
(SELECT,SHOW,DESCRIBE,EXPLAIN). A informa¸ao retornada de uma consulta
´e chamada conjunto de resultado no resto desta se¸ao.
MYSQL_ROW
Esta ´e uma representa¸ao segura de tipo de uma linha de dados. Ela ´e imple-
mentada atualmente como um vetor de strings de tamanho fixo (Voe n˜ao pode
trat´a-los como strings terminadas com null se os valores do campo podem conter
dados bin´arios, porque tais valores podem conter um byte null internamente.).
Linhas s˜ao obtidas pela chamada de mysql_fetch_row().
MYSQL_FIELD
Esta estrutura cont´em informa¸ao sobre um campo, tais como nome, tipo e
tamanho do campo. Seus membros s˜ao descritos em mais detalhes aqui. Voe
pode obter a estrutura MYSQL_FIELD para cada campo chamando mysql_fetch_
field() repetidamente. Valores de campos n˜ao s˜ao parte desta estrutura; eles
est˜ao contidos na estrutura MYSQL_ROW.
MYSQL_FIELD_OFFSET
Esta ´e uma representa¸ao segura de um offset em uma lista de campos MySQL.
(Usado por mysql_field_seek().) Offsets s˜ao n´umeros de campos em um
registro, come¸cando com zero.
my_ulonglong
O tipo usado pelo n´umero de linhas e para mysql_affected_rows(),
mysql_num_rows(), e mysql_insert_id(). Este tipo fornece uma faixa de 0
a1.84e19.
Em alguns sistemas, tentar imprimir um valor do tipo my_ulonglong ao fun-
cionar´a. Para imprimir tais valores, converta-os para unsigned long e use o
formato de impress˜ao %lu. Exemplo:
printf ("N´umero de linhas: %lu\n", (unsigned long) mysql_num_
rows(resultado));
A estrutura MYSQL_FIELD contem os membros listados aqui:
char * name
O nome do campo, como um string terminada com null.
char * table
O nome da tabela contendo este campo, se n˜ao for um campo calculado. Para
campos calculador, o valor table ´e uma string vazia.
char * def
O valor padr˜ao para este campo, como um string terminada em null. Ele ´e
atribuido apenas se vocˆe utilizar mysql_list_fields().
enum enum_field_types tipo
O tipo do campo. O valor tipo pode ser um dos seguintes:
Valou tipo Descri¸ao do tipo
FIELD_TYPE_TINY campo TINYINT
Chapter 8: MySQL APIs 551
FIELD_TYPE_SHORT campo SMALLINT
FIELD_TYPE_LONG campo INTEGER
FIELD_TYPE_INT24 campo MEDIUMINT
FIELD_TYPE_LONGLONG campo BIGINT
FIELD_TYPE_DECIMAL campo DECIMAL ou NUMERIC
FIELD_TYPE_FLOAT campo FLOAT
FIELD_TYPE_DOUBLE campo DOUBLE ou REAL
FIELD_TYPE_TIMESTAMP campo TIMESTAMP
FIELD_TYPE_DATE campo DATE
FIELD_TYPE_TIME campo TIME
FIELD_TYPE_DATETIME campo DATETIME
FIELD_TYPE_YEAR campo YEAR
FIELD_TYPE_STRING campo String (CHAR ou VARCHAR)
FIELD_TYPE_BLOB campo BLOB ou TEXT (usa max_length para de-
terminar o tamanho m´aximo)
FIELD_TYPE_SET campo SET
FIELD_TYPE_ENUM campo ENUM
FIELD_TYPE_NULL campo tipo-NULL
FIELD_TYPE_CHAR Deprecado; use FIELD_TYPE_TINY
Voe pode utilizar a macro IS_NUM() para testar se uma campo tem um tipo
num´erico. Passe o valor tipo para IS_NUM() e ele ir´a avaliar como VER-
DADEIRO (TRUE) se o campo for num´erico:
if (IS_NUM(campo->tipo))
printf("Campo ´e num´erico\n");
unsigned int length
A largura de um campo, como especificado nas defini¸oes da tabela.
unsigned int max_length
A largura m´axima do campo no conjunto de resultados (O tamanho do maior
valor do campo para os registro no resultado atual). Se vocˆe utilizar mysql_
store_result() ou mysql_list_fields(), ele contem o tamanho m´aximo
para o campo. Se vocˆe utiliza mysql_use_result(), o valor desta vari´avel
´e zero.
unsigned int param
Diferentes parˆametros bin´arios para o campo. O valor de param pode ter zero
ou mais dos seguintes conjunto de bits:
Valor param Descri¸ao param
NOT_NULL_FLAG Campo n˜ao pode ser NULL
PRI_KEY_FLAG Campo ´e parte de uma chave prim´aria
UNIQUE_KEY_FLAG Campo ´e parte de uma chave ´unica
MULTIPLE_KEY_FLAG Campo ´e parte de uma chave n˜ao ´unica
UNSIGNED_FLAG Campo tem o atributo UNSIGNED
ZEROFILL_FLAG Campo tem o atributo ZEROFILL
BINARY_FLAG Campo tem o atributo BINARY
AUTO_INCREMENT_FLAG Campo tem o atributo AUTO_INCREMENT
ENUM_FLAG Campo ´e um ENUM (obsoleto)
552 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SET_FLAG Campo ´e um SET (obsoleto)
BLOB_FLAG Campo ´e um BLOB ou TEXT (obsoleto)
TIMESTAMP_FLAG Campo ´e um TIMESTAMP (obsoleto)
Uso dos parˆametros BLOB_FLAG,ENUM_FLAG,SET_FLAG, e TIMESTAMP_FLAG
foram obsoletos porque eles indicavam o tipo de um campo e n˜ao um
atributo do tipo. ´
E prefer´
ivel testar campo->tipo para FIELD_TYPE_BLOB,
FIELD_TYPE_ENUM,FIELD_TYPE_SET,ouFIELD_TYPE_TIMESTAMP.
O seguinte exemplo ilustra o uso t´
ipico do valor param:
if (campo->param & NOT_NULL_FLAG)
printf("Campo n~ao pode ser nulo\n");
Voe pode usar as seguintes macros para determinar o status dos valores param:
Status param Descri¸ao
IS_NOT_NULL(param) Verdadeiro se se este campo ´e definido como NOT
NULL
IS_PRI_KEY(param) Verdadeiro de este campo ´e uma chave prim´aria
IS_BLOB(param) Verdadeiro se este campo ´e um BLOB ou TEXT
(obsoleto; teste campo->tipo)
unsigned int decimals
O n´umero de decimais para um campo num´erico.
8.1.2 Vis˜ao Geral das Fun¸ao da API C
As fun¸oes dispon´
iveis na API C s˜ao listadas aqui e descritas em maiores detalhes em uma
se¸ao posterior. See hundefinedi[Fun¸oes API C], page hundefinedi.
Fun¸ao Descri¸ao
mysql affected rows() Retorna o n´umero de linhas alteradas/deletadas/insweridas
pela ´ultima consulta \ UPDATE,DELETE,ouINSERT.
mysql change user() Muda o usuario em um banco de dados em uma conex˜ao
aberta.
mysql character set name() Retorna o nome do conjunto de carcters padr˜ao para a
conex˜ao.
mysql close() Fecha ua conex˜ao com o servidor
mysql connect() Se conecta ao servidro MySQL. Esta fun¸ao est´a deprecad;
utilize mysql_real_connect().
mysql create db() Cria um banco de dados. Esta fun¸ao est´a obsoleta; utiliza
o comando SQL CREATE DATABASE.
mysql data seek() Busca por uma linha arbitr´aria em um conjunto de resulta-
dos de uma consulta.
mysql debug() Faz um DBUG_PUSH com a string dada.
Chapter 8: MySQL APIs 553
mysql drop db() Apaga um banco de dados; Esta fun¸ao esta obsoleta; utiliza
o comando SQL DROP DATABASE.
mysql dump debug info() Faz o servidor escrever informa¸c˜oes de depoura¸ao no log.
mysql eof() Determina quando a ulitma linha de um conjunto de re-
sultados foi lida. Esta fun¸ao foi obsoleta; Utilize mysql_
errno() ou mysql_error()
mysql errno() Retorna o n´umero de erro para a fun¸ao MySQL chamada
mais recentemente.
mysql error() Retorna a mensagem de erro para fun¸ao MySQL chamada
mais recentemente.
mysql escape string() Escapa caracteres especiais em uma string para ser usada
em uma instru¸ao SQL.
mysql fetch field() Retorna o tipo do pr´oximo campo na tabela.
mysql fetch field direct() Retorna o tipo de um campo da tabela, dado um n´umero
do campo.
mysql fetch fields() Retorna um vetor de todas as estruturas do campo.
mysql fetch lengths() Retorna o tamanho de todas as colunas na linha atual.
mysql fetch row() Busca o pr´oximo registro no conjunto de resultados.
mysql field seek() Coloca o cursor da coluna em uma coluna espec´
ifica.
mysql field count() Retorna o n´umero de colunas resultantes da consulta mais
recente.
mysql field tell() Retorna a posi¸ao do cursos de campos usado pelo ´ultimo
mysql_fetch_field().
mysql free result() Libera a mem´oria usada por um conjunto de resultados.
mysql get client info() Retorna a vers˜ao do cliente.
mysql get host info() Retorna uma string descrevendo a conex˜ao.
mysql get server version() Retorna o n´umero da vers˜ao do servidor como um inteiro
(Novo na vers˜ao 4.1)
mysql get proto info() Retorna a vers˜ao do protovolo usado para a conex˜ao.
mysql get server info() Retorna o n´umero da vers˜ao do servidor.
mysql info() Retorna informa¸ao sobre a consulta executada mais recen-
temente.
mysql init() Obtem ou inicializa uma estrutura MYSQL.
554 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql insert id() Retorna o ID gerado para uma coluna AUTO_INCREMENT pela
consulta anterior.
mysql kill() Mata uma thread dada.
mysql list dbs() Retorna o nome do banco de dados correspondente a uma
express˜ao regular.
mysql list fields() retorna nome de campos coincidindo com uma express˜ao
regular.
mysql list processes() Retorna uma lista das threads atuais do servidor.
mysql list tables() Retorna os nomes de tabelas correspondente a uma ex-
press˜ao regular.
mysql num fields() Retorna o n´umero de coluans em um conjunto de resultados.
mysql num rows() Retorna o n´umero de linhas em um conjunto de resultados.
mysql options() Define op¸oes de conex˜ao para mysql_connect().
mysql ping() Verifica se a conex˜ao ao servidor est´a funcionando, re-
conectando se necess´ario.
mysql query() Executa uma consulta SQL especificada com uma string ter-
minada com null.
mysql real connect() Conecta ao servidor MySQL.
mysql real escape string() Escapa caracteres especiais em uma string para ser utilizada
em uma instru¸ao SQL, olhando na conta o conjunto de
caracteres atual da conex˜ao
mysql real query() Executa uma consulta SQL especificada como uma string
fixa.
mysql reload() Diz ao servidor pra recarregar a tabela de permiss˜oes
mysql row seek() Busca por uma linha no resultado, usando o valor retornado
de mysql_row_tell().
mysql row tell() Retorna a posi¸ao dio cursor de linhas.
mysql select db() Seleciona um banco de dados.
mysql shutdown() Desliga o servidor de banco de dados.
mysql stat() Retorna o status do servidor como uma string.
mysql store result() Recupera um resultado completo para o cliente.
mysql thread id() Retorna a identifica¸ao da thread atual.
mysql thread safe() Retorna 1 se o cliente foi compilado como thread-safe.
Chapter 8: MySQL APIs 555
mysql use result() Inicia uma resultado recuperado registro por registro.
mysql commit() Faz um commits na transa¸ao (novo na vers˜ao 4.1).
mysql rollback() Faz um roll back na transa¸ao (novo na vers˜ao 4.1).
mysql autocommit() Muda o modo autocommit em ligado/desligado (novo na
vers˜ao 4.1).
mysql more results() Verifica se n˜ao existem mais resultados (novo na vers˜ao 4.1).
mysql next result() Retorna/Inicia o pr´oximo resultado em execu¸oes consultas
m´ultiplas (inovo na vers˜ao 4.1).
Para se conectar ao servidor, chame mysql_init() para iniciar um manipulador de conex˜ao,
enao chame mysql_real_connect() com este manipulador (com informa¸oes de nome
de m´aquina, usu´arios e senha). Conectado, mysql_real_connect() define o parˆametro
reconnect (parte da estrutura MYSQL) para um valor de 1. Este parˆametro indica, no
evento que uma consulta n˜ao pode ser realizada por perda de conex˜ao, para tentar reconectar
ao servidor ao antes de desistir. Quando n˜ao precisar mais da conex˜ao, chame mysql_
close() para termin´a-la.
Enquanto a conex˜ao estiver ativa, o cliente pode enviar consultas SQL para o servidor
usando mysql_query() ou mysql_real_query(). A diferen¸ca entre os dois ´e que mysql_
query() espera que a consulta seja especificada como uma string terminada em null, en-
quanto mysql_real_query() espera um string de tamanho fixa. Se a string conter dados
bin´arios (a qual pode incluir bytes null), vocˆedeve usar mysql_real_query().
Para cada consulta n˜ao-SELECT (por exemplo, INSERT,UPDATE,DELETE), vocˆe pode desco-
brir quantas linhas foram alteradas (afetadas) chamando mysql_affected_rows().
Para consultas SELECT, vocˆe retorna os registros selecionados como um resultado. (Note que
algumas intru¸oes s˜ao como a SELECT ao retornar registros. Elas incluem SHOW,DESCRIBE
eEXPLAIN. elas devem ser tratadas da mesma maneira que instru¸oes SELECT.)
Existem dois modos para um cliente processae o resultado. Um mode ´e recuperar todo o
resultado de uma vez chamando mysql_store_result(). Esta fun¸ao busca no servidor
todas as linhas retornadas pela consulta e as armazena no cliente. O segundo modo ´e o
cliente iniciar um retorno do resultado registro por registro chamando mysql_use_result().
Esta fun¸ao inicia o retorno, mas n˜ao busca realmente nenhuma linha do servidor.
Em ambos os casos, acesse registros chamando mysql_fetch_row(). Com mysql_store_
result(),mysql_fetch_row() acessa registros que j´a tenham sido buscado do servidor.
Com mysql_use_result(),mysql_fetch_row() recupera, na verdade, o registro do servi-
dor. Informa¸oes sobre o tamanho dos dados em cada registro ´e dispon´
ivel pela chamada
mysql_fetch_lengths().
Depois de finalizar o uso do resultado, chame mysql_free_result() para liberar a mem´oria
usada por ele.
Os dois mecanismos de recupera¸ao s˜ao complementares. Programas clientes devem escolher
a abordagem mais apropriada para suas necessidades. Na pr´atica, clientes tendem a utilizar
mysql_store_result().
Uma vantagem de mysql_store_result() ´e que pelo fato de todos os registros serem
trazidos para o cliente, vocˆe n˜ao s´o pode acessar registros sequencialmente, mas tamb´em
556 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
pode mover para tarz e para frente no resultado utilizando mysql_data_seek() ou mysql_
row_seek() para altera a posi¸ao atual do registro no resultado. Vocˆe tamb´em pode saber
quantas linhas existem chamando mysql_num_rows(). Por outro lado, a necessidade de
mem´oria para mysql_store_result() pode ser muito alta para resultados grandes e vocˆe
encontrar´a como mais facilidade condi¸oes de estouro de mem´oria.
Uma vantagem de mysql_use_result() ´e que o clientes exige menos mem´oria para o re-
sultado porque ele mantem apenas um registro por vez (por haver menor sobrecarga de
aloca¸ao, mysql_use_result() pode ser mais r´apido). As desvantagens s˜ao que vocˆe deve
processar cada registro rapidamente para evitar prender o servidor, vocˆe n˜ao tem acesso
aleat´orio aos registros no resultado (vocˆe s´o pode acess´a-los sequencialmente) e voe n˜ao
sabe quantos registros existem no resultado at´e que vocˆe recupere todos eles. Al´em disso,
vocˆe deve recuperar todos os registros mesmo que vocˆe j´a tenham encontrado a informa¸c˜ao
que procura antes do finalizar o conjunto de resultados.
A API torna poss´
ivel para os clientes responder apropriadamente as consultas (recuperando
somente os regiostros necess´arios) sem saber se a consulta ´e uma instru¸ao SELECT ou n˜ao.
Voe pode fazer isto chamando mysql_store_result() depois de cada mysql_query() (ou
mysql_real_query()). Se o resultado for obtido com sucesso, a consulta foi um SELECT e
vocˆe pode ler os registros. Se a obten¸ao do resultado falhar, chame mysql_field_count()
para determinar se o resultado era o esperado. Se mysql_field_count() retornar zero, a
consulta n˜ao retornou nenhum dado (indicando que ela era um INSERT,UPDATE,DELETE,
etc.), e n˜ao era esperado que retornasse registros. Se mysql_field_count() ´e diferente de
zero, a consulta deveria retornar registros, mas n˜ao o fez. Isto indica que a consulta foi um
SELECT que falhou. Veja a descri¸ao de mysql_field_count() para um exemplo de como
deve ser feito.
mysql_store_result() emysql_use_result() permitem que vocˆe obtenha informa¸ao
sobre os campos que montam o resultado (o n´umero de campos, os seus nome e tipos, etc.)
Voe pode acessar informa¸oes de campo sequencialmente dentro dos registros chamando
mysql_fetch_field() repetidamente, ou pelo n´umero do campo dentro do registro
chamando mysql_fetch_field_direct(). A posi¸ao atual do cursor de campos pode ser
alterada cahamando mysql_field_seek(). Definir o cursor de campo afeta chamadas
subsequentes de mysql_fetch_field(). Vocˆe tamb´em pode conseguir informa¸oes de
todos os campos de uma s´o vez chamando mysql_fetch_fields().
Para detectar e relatar problemas, o MySQL fornace acesso a informa¸oes de erro atrav´es das
fun¸oes mysql_errno() emysql_error(). Elas retornam o c´odigo de erro ou a mensagem
de erro para a fun¸ao chamada mais recentemente que tenha tido sucesso ou que tenha
falhado, permitindo a vocˆe determinar quando um erro ocorreu e qual foi ele.
8.1.3 Descri¸ao das Fun¸oes da API C
Nas descri¸oes a seguir, um parˆametro ou valor retornado NULL significa NULL no sentido da
linguagem de programa¸ao C, n˜ao um valor NULL do MySQL.
Fun¸oes que retornam um valor geralmente retornam um ponteiro ou um inteiro. A menos
que seja especificado, func˜oes que retornam um ponteiro, retornam um valor diferente de
NULL para indicar sucesso ou um valor NULL para indicar um erro, e fun¸oes que retornam
um inteiro, retoprnam zero para indicar sucesso ou um valor diferente de zero para indicar
Chapter 8: MySQL APIs 557
um erro. A menos que a descri¸ao da fun¸ao diga algo diferente, n˜ao fa¸ca teste com outro
valor al´em do zero.
if (result) /* correct */
... error ...
if (result < 0) /* incorrect */
... error ...
if (result == -1) /* incorrect */
... error ...
Quando uma fun¸ao retornar um erro, a subsecao Erros de descri¸ao de fun¸oes lista os
poss´
iveis tipos de erro. Voe pode descobrir quais deles ocorreu chamando mysql_errno().
Uma representa¸ao string do erro pode ser obtida chamando mysql_error().
8.1.3.1 mysql_affected_rows()
my_ulonglong mysql_affected_rows(MYSQL *mysql)
Descri¸ao
Retorna o n´umero de registros alterados pelo ´ultimo UPDATE, deletados elo ´ultimo DELETE ou
inseridos pelo ´ultimo INSERT. Pode ser chamado imediatamente ap´os mysql_query() para
instru¸oes UPDATE,DELETE, ou INSERT. Para instru¸oes SELECT,mysql_affected_rows()
funciona como mysql_num_rows().
Valor Retornado
Um inteiro maior que zero indica o n´umero de registros afetados ou recuperados. Zero indica
que nenhum registro foi atualizado por uma instru¸ao UPDATE, nenhuma linha foi encontrada
pela cl´ausula WHERE na consulta ou a consulta ainda n˜ao foi executada. -1 indica que a
consulta retornou um erro ou que, para uma consulta SELECT,mysql_affected_rows() foi
chamado antes da chamada mysql_store_result().
Erros
Nenhum.
Exemplo
mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
printf("%ld products updated",(long) mysql_affected_rows(&mysql));
Se se for especificado o parˆametro CLIENT_FOUND_ROWS ao conectar no mysqld,mysql_
affected_rows() retornar´a o n´umero de linhas encontardos pela cl´ausula WHERE para a
instru¸ao UPDATE.
Note que quando for utilizado um comando REPLACE,mysql_affected_rows() retornar´a
2 se o novo registro substituir um mais antigo. Isto ´e porque neste caso um registro foi
inserido e depois os registros duplicados foram deletados.
558 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.3.2 mysql_change_user()
my_bool mysql_change_user(MYSQL *mysql, const char *user, const char
*password, const char *db)
Descri¸ao
Altera o usu´ario ´e faz com que o banco de dados especificado por db se torne o banco de
dados padr˜ao (atual) na conex˜ao especificada por mysql. Em consultas subsequentes este
banco de dados ´e o padr˜ao para referˆencias a tabelas que n˜ao especificam o banco de dados
explicitamente.
Esta fun¸ao foi introduzida na vers˜ao do MySQL.
mysql_change_user() falha a menos que o usu´ario conectado possa ser autenticado ou se
ele n˜ao tiver permiss˜ao para utilizar o banco de dodos. Neste caso o usu´ario e o banco de
dados n˜ao s˜ao alterados.
O parˆametro db pode ser definido como NULL se vocˆe n˜ao dseseja ter um banco de dados
padr˜ao.
A partir da vers˜ao 4.0.6 do MySQL este comando sempre far´a ROLLBACK de qualquer
transa¸ao ativa, fecha todas as tabelas tempor´arias, destrava todas as tabelas bloqueadas e
volta a um estado como se tivesse feito uma inova conex˜ao. Isto ir´a acontecer mesmo se o
usu´ario n˜ao foi alterado.
Valor Retornado
Zero se obteve successo. Diferente de zero se ocorreu um erro.
Erros
O mesmo que pode ser obtido com mysql_real_connect().
CR_COMMANDS_OUT_OF_SYNC
Comandos forma executados em ordem inapropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL finalizou.
CR_SERVER_LOST
A conex˜ao ao servidor foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
ER_UNKNOWN_COM_ERROR
O servidor MySQL n˜ao possui este comando (provavelmente um vers˜ao mais
antiga)
ER_ACCESS_DENIED_ERROR
O usu´ario ou a senha estavam errados.
ER_BAD_DB_ERROR
O banco de dados n˜ao existe.
Chapter 8: MySQL APIs 559
ER_DBACCESS_DENIED_ERROR
O usu´ario n˜ao tem direitos de acessoa este banco de dados.
ER_WRONG_DB_NAME
O nome de banco de dados ´e muito grande.
Exemplo
if (mysql_change_user(&mysql, "user", "password", "new_database"))
{
fprintf(stderr, "Failed to change user. Error: %s\n",
mysql_error(&mysql));
}
8.1.3.3 mysql_character_set_name()
const char *mysql_character_set_name(MYSQL *mysql)
Descri¸ao
Retorna o conjunto de caracteres padr˜ao para a conex˜ao atual.
Valor Retornado
O conjunto de carcteres padr˜ao
Erros
Nenhum.
8.1.3.4 mysql_close()
void mysql_close(MYSQL *mysql)
Descri¸ao
feca uma conex˜ao aberta anteriormente. mysql_close() tamb´em desaloca o ponteiro do
manipulador da conex˜ao para o mysql se ele tiver sido alocado automaticamente por mysql_
init() ou mysql_connect().
Valor Retornado
Nenhum.
Erros
Nenhum.
8.1.3.5 mysql_connect()
MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const
char *passwd)
560 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Descri¸ao
A fun¸ao est´a obsoleta. ´
E melhor utilizar mysql_real_connect().
mysql_connect() tenta estabelecer uma conex˜ao a um banco de dados MySQL executando
em host.mysql_connect() deve completar com suceso antes que vocˆe podssa executar
qualquer uma das fun¸ao da API, com a exce¸ao de mysql_get_client_info().
O significado dos parˆametros s˜ao os mesmos que os parˆametros correspondentes para mysql_
real_connect() com a diferen¸ca que o parˆametro de conex˜ao pode ser NULL. Neste caso a
API C aloca mem´oria para a estrutura de conex˜ao automaticamente e a libera quando vocˆe
chamar mysql_close(). A disvantagem desta abordagem ´e que vocˆe n˜ao pode retornar uma
mensagem de erro se a conex˜ao falhar. (Para obter informa¸oes de erro de mysql_errno()
ou mysql_error(), vocˆe deve fornecer um ponteiro MYSQL alido.)
Valor Retornado
O mesmo de mysql_real_connect().
Erros
O mesmo de mysql_real_connect().
8.1.3.6 mysql_create_db()
int mysql_create_db(MYSQL *mysql, const char *db)
Descri¸ao
Cria o banco de dados nomeado pelo parˆametro db.
Esta fun¸ao est´a obsoleta. ´
E melhor utilizar mysql_query() para comandar uma instru¸ao
SQL CREATE DATABASE.
Valor Retornado
Zero se o banco de dados foi criado com successo. Diferente de zero se ocorreu um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Chapter 8: MySQL APIs 561
Exemplo
if(mysql_create_db(&mysql, "my_database"))
{
fprintf(stderr, "Failed to create new database. Error: %s\n",
mysql_error(&mysql));
}
8.1.3.7 mysql_data_seek()
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)
Descri¸ao
Busca um registro arbitr´ario em um resultado de uma consulta. Ela exige que a estrutura
do resultado contenha todo o resultado da consulta, assim mysql_data_seek() o pode ser
usado em conjunto com mysql_store_result(), n˜ao com mysql_use_result().
O offset deve der um valor na faixa de 0 a mysql_num_rows(result)-1.
Valor Retornado
Nenhum.
Erros
Nenhum.
8.1.3.8 mysql_debug()
void mysql_debug(const char *debug)
Descri¸ao
Faz um DBUG_PUSH com a string dada. mysql_debug() usa a biblioteca de depura¸ao
Fred Fish. Para utilizar esta fun¸ao vocˆe deve compilar a biblioteca cliente para suportar
depura¸ao. See hundefinedi[Depurando o servidor], page hundefinedi. See hundefinedi
[Depurando o cliente], page hundefinedi.
Valor Retornado
Nenhum.
Erros
Nenhum.
Exemplo
A chamada mostrada aqui faz com que a biblioteca cliente gere um arquivo de rastreamento
/tmp/client.trace’ na m´aquina cliente:
mysql_debug("d:t:O,/tmp/client.trace");
562 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.3.9 mysql_drop_db()
int mysql_drop_db(MYSQL *mysql, const char *db)
Descri¸ao
Apaga o banco de dados nomeado pelo parˆametro db.
Esta fun¸ao est´a obsoleta. ´
E melhor utilizar mysql_query() para realizar uma instru¸ao
SQL DROP DATABASE.
Valor Retornado
Zero se o banco de dados foi apagdo com sucesso. Diferente de zero ocorreu um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Exemplo
if(mysql_drop_db(&mysql, "my_database"))
fprintf(stderr, "Failed to drop the database: Error: %s\n",
mysql_error(&mysql));
8.1.3.10 mysql_dump_debug_info()
int mysql_dump_debug_info(MYSQL *mysql)
Descri¸ao
Instrui o servidor a gravar algumas informa¸oes de depura¸ao no log. Para funcionar, o
usu´ario conectado deve ter pivil´egio SUPER.
Valor Retornado
Zero se o comando obteve sucesso. Diferete de zero se ocorreu um erro.
Chapter 8: MySQL APIs 563
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.11 mysql_eof()
my_bool mysql_eof(MYSQL_RES *result)
Descri¸ao
Esta fun¸ao est´a obsoleta. mysql_errno() ou mysql_error() podem ser usados em seu
lugar.
mysql_eof() determina se o ´ultimo registro de um resultado foi lido.
Se vocˆe buscar um resultado com um chamada mysql_store_result() bem sucedida, o
cliente recebe todo o resultado em uma opera¸ao. Neste caso, ´e um valor NULL retornado de
mysql_fetch_row() sempre significa que o fim do resultado foi atingido e n˜ao ´e necess´ario
chamar mysql_eof(). Quando usado com mysql_store_result(),mysql_eof() sempre
retornar´a verdadeiro.
Por outro lado, se vocˆe utilizar mysql_use_result() para iniciar um resultado recuperado,
as linhas do conjunto s˜ao obtido do servidor uma a uma, chamando mysql_fetch_row()
repetidamente. Como pode ocorrer um erro na conex˜ao durante este processo, um valor NULL
retornado de mysql_fetch_row() ao significa, necess´ariaemente, que o fim do resultado
fo atingido normalmente. Neste caso, vocˆe pode utilizar mysql_eof() para determinar o
que aconteceu. mysql_eof() retorna um valor diferente de zero se o fim do resultaod foi
atingido e zero se ocorreu um erro.
Historicamente, mysql_eof() ´e preterido pelas fun¸oes de erro padr˜ao do MySQL mysql_
errno() emysql_error(). Como estas fun¸oes de erro fornecem a mesma informa¸ao,
o uso das duas ´ultimas ´e preferido sobre mysql_eof(), a qual est´a obsoleta. (De fato,
elas fornecem mais informa¸oes, porque mysql_eof() retorna apenas um valor booleano
enquanto as fun¸oes de erro indicam uma raz˜ao para a ocorrˆencia do erro quando ele ocorre).
Valor Retornado
Zero se nenhum erro ocorreu. Diferente de zero o fim do resultado foi atingido.
Erros
Nenhum.
564 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Exemplo
Os exemplos seguintes mostram como vocˆe deve usar mysql_eof():
mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
{
// faz algo com os dados
}
if(!mysql_eof(result)) // mysql_fetch_row() falha devido a um erro
{
fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}
No entanto, vocˆe pode conseguir o mesmo efeito com as fun¸oes de erro padr˜oes do MySQL:
mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
{
// faz algo com os dados
}
if(mysql_errno(&mysql)) // mysql_fetch_row() falha devido a um erro
{
fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}
8.1.3.12 mysql_errno()
unsigned int mysql_errno(MYSQL *mysql)
Descri¸ao
Para a conex˜ao especificada pelo mysql,mysql_errno() retorna o c´odigo de erro para a
fun¸ao API chamada mais recentemente que tenha obtido sucesso ou falhado. Um valor
de retorno de zero significa que um erro ocorreu. N´umeroos de mensagens de erro de
clientes s˜ao listados no arquivo de cabcalho ‘errmsg.h’ do MySQL. N´umeros de mensagem
de erros do servidor s˜ao listados no arquivo ‘mysqld_error.h’. Na distribui¸ao fonte do
MySQL vocˆe pode encontrar uma lista completa de n´ueros de mensagens de erro no arquivo
Docs/mysqld_error.txt’.
Valor Retornado
Um valor com c´odigo de erro. Zero se nenhum erro ocorrer.
Erros
Nenhum.
8.1.3.13 mysql_error()
char *mysql_error(MYSQL *mysql)
Chapter 8: MySQL APIs 565
Descri¸ao
Para a conex˜ao especificada por mysql,mysql_error() retorna a mensagem de erro para
a fun¸ao de API chamda mais recentemented API que tenha falhado ou n˜ao. Uma string
vazia ("") ´e retornada se nenhum erro ocorrer. OIsto significa que os dois testes seguintes
ao equivalentes:
if(mysql_errno(&mysql))
{
// ocorreu um erro
}
if(mysql_error(&mysql)[0] != ’\0’)
{
// ocorreu um erro
}
A l´
ingua da mensagem de erro do cliente pode ser alterada recompilando a biblioteca do
cliente MySQL. Atualmente vocˆe pode escolher mensagens de erro em v´arias l´
inguas difer-
entes. See hundefinedi[Languages], page hundefinedi.
Valor Retornado
Uma string que descreve um erro. Uma string vazia se nenhum erro ocorrer.
Erros
Nenhum.
8.1.3.14 mysql_escape_string()
Voe deve usar mysql_real_escape_string() em seu lugar!
Esta fun¸ao ´e identica a mysql_real_escape_string() exceto que mysql_real_escape_
string() pega um manipulador de cnex˜ao como seu primeiro argumento e escapa a string
de acordo com a conjunto de caracteres padr˜ao. mysql_escape_string() ao utiliza um
argumento de conex˜ao e n˜ao respeita o conjunto de caracteres atual.
8.1.3.15 mysql_fetch_field()
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)
Descri¸ao
Retorna a defini¸ao de uma coluna de um resultado como uma estrutura MYSQL_FIELD.
Chame esta fun¸ao repetidamente para retornar informa¸oes sobre todas as colunas no
resultado. mysql_fetch_field() retorna NULL quando n˜ao existirem mais campos.
mysql_fetch_field() ´e definido para retornar a informa¸ao do primeiro campo cada vez
que vocˆe executar uma nova consulta SELECT. O campo retornado por mysql_fetch_
field() tamb´em ´e afetado pela chamadas mysql_field_seek().
566 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Se vovˆe tiver chamado mysql_query() para realizar um SELECT em uma tabela mas n˜ao
tiver chamado mysql_store_result(), MySQL retorna o tamanho padr˜ao do blob (8K
bytes) quando chamar mysql_fetch_field() para saber o tamanho de um campo BLOB.
(O tamanho de 8 k ´e escolhido porque o MySQL n˜ao sabe o tamanho m´aximo do BLOB. Ele
pode ser configurado algumas vezes.) Uma vez retornado o resultado, campo->tamanho_max
cont´em o tamanho da maior valor para esta coluna em uma consulta espec´
ifica.
Valor Retornado
A estrutura MYSQL_FIELD para a coluna atual. NULL ao houver mais colunas.
Erros
Nenhum.
Exemplo
MYSQL_FIELD *field;
while((field = mysql_fetch_field(result)))
{
printf("field name %s\n", field->name);
}
8.1.3.16 mysql_fetch_fields()
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)
Descri¸ao
Retorna um vetor de todas as estruturas MYSQL_FIELD no resultado. Cada estrutura fornece
a defini¸ao do campo para uma coluna do resultado.
Valor Retornado
Um vetor da estrutura MYSQL_FIELD para todas as colunas no resultado.
Erros
Nenhum.
Exemplo
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;
num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for(i = 0; i < num_fields; i++)
Chapter 8: MySQL APIs 567
{
printf("Field %u is %s\n", i, fields[i].name);
}
8.1.3.17 mysql_fetch_field_direct()
MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int
fieldnr)
Descri¸ao
Dado um n´umero de campo fieldnr para uma colua em resultado, retorna a informa¸ao
de campo daquela coluna como uma estrutura MYSQL_FIELD Vocˆe pode utilizar esta fun¸ao
para retornar a defini¸ao para uma coluna arbitr´aria. O valor de fieldnr deve estar na
faixa de 0 a mysql_num_fields(result)-1.
Valor Retornado
A estrutura MYSQL_FIELD para uma coluna espec´
ifica.
Erros
Nenhum.
Exemplo
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;
num_fields = mysql_num_fields(result);
for(i = 0; i < num_fields; i++)
{
field = mysql_fetch_field_direct(result, i);
printf("Field %u is %s\n", i, field->name);
}
8.1.3.18 mysql_fetch_lengths()
unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
Descri¸ao
Retorna o tamanho da coluna do registro atual em um resultado. Se vocˆe planeja copiar
calores dos compos, esta informa¸ao de tamanho ´e ´util tamem para a otimiza¸ao,
porque vocˆe pode evitar a chamada strlen(). Se o resultado cont´em dados bi´arios, vocˆe
deveutilizar esta fun¸ao para determinar o tamanho dos dados, pois strlen() retorna um
valor incorreto para quaquer campo contendo caracteres nulos.
O tamanho para colunas vazias e para colunas contendo valores NULL ´e zero. Para ver como
distnguir este dois casos, veja a descri¸ao de mysql_fetch_row().
568 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Valor Retornado
Um vetor de unsigned long integers (inteiros longos sem sinal) representando o tamanho de
cada coluna (n˜ao incluindo nenhuma caracter nulo). NULL se ocorrer um erro.
Erros
mysql_fetch_lengths() o ´e v´alido para o registro atual no resultado. Ele retorna NULL
se vocˆe cham´a-lo antes de mysql_fetch_row() ou depois de retornar todos os registros em
um resultado.
Exemplo
MYSQL_ROW row;
unsigned long *lengths;
unsigned int num_fields;
unsigned int i;
row = mysql_fetch_row(result);
if (row)
{
num_fields = mysql_num_fields(result);
lengths = mysql_fetch_lengths(result);
for(i = 0; i < num_fields; i++)
{
printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
}
}
8.1.3.19 mysql_fetch_row()
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
Descri¸ao
Recuera o pr´oximo registro do resultado. Quando usado depois de mysql_store_result(),
mysql_fetch_row() retorna NULL quando n˜ao houver mais registros para retornar. Quando
usado depois de mysql_use_result(),mysql_fetch_row() retorna NULL quando n˜ao hou-
ver mais registros para retornar ou ocorrer um erro.
O n´umero de valores no registro ´e dado por mysql_num_fields(result). Se row guarda
o valor retornado de uma chamada mysql_fetch_row(), apontadores para os valores s˜ao
acessados como row[0] arow[mysql_num_fields(result)-1]. Valores NULL no registro
ao indicados por apontadores NULL.
Os tamanhos dos valores do campo no registro poden ser obtidos chamando mysql_fetch_
lengths(). Campos vazios e campos contendo NULL tem tamanho 0; vocˆe pode distingui-los
verificando o apontador para o valor do campo. Se o apontador ´e NULL, o campo ´e NULL;
sen˜ao o campo est´a vazio.
Chapter 8: MySQL APIs 569
Valor Retornado
Uma estrutura MYSQL_ROW para o pr´oximo registro. NULL se n˜ao houver mais linhas para
retornar ou ocorrer um erro.
Erros
CR_SERVER_LOST
A conex˜ao com o servidor foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Exemplo
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;
num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
{
unsigned long *lengths;
lengths = mysql_fetch_lengths(result);
for(i = 0; i < num_fields; i++)
{
printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
}
printf("\n");
}
8.1.3.20 mysql_field_count()
unsigned int mysql_field_count(MYSQL *mysql)
Se vocˆe estiver utilizando uma vers˜ao anterior a vers˜ao 3.22.24 do MySQL, vocˆe deve utilizar
unsigned int mysql_num_fields(MYSQL *mysql).
Descri¸ao
Retorna o n´umero de colunas para a consulta mais recente na conex˜ao.
Normalmente esta fun¸ao ´e utilizada quando mysql_store_result() retorna NULL (enao
vocˆe n˜ao possui um apontador para o resultado). Neste caso, vocˆe pode chamar mysql_
field_count() para determinar se mysql_store_result() ao produziu um resultado
vazio. Isto permite que o programa cliente tome a a¸ao aprpriada sem saber se a consulta
foi uma instru¸ao SELECT (ou do mesmo tipo). O exemplo mostrado aqui ilustra como isto
pode ser feito.
See hundefinedi[NULL mysql_store_result()], page hundefinedi.
570 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Valor Retornado
Um unsigned integer (inteiro sem sinal) representando o n´umero de campo em um resultado.
Erros
Nenhum.
Exemplo
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;
if (mysql_query(&mysql,query_string))
{
// error
}
else // query succeeded, process any data returned by it
{
result = mysql_store_result(&mysql);
if (result) // there are rows
{
num_fields = mysql_num_fields(result);
// retrieve rows, then call mysql_free_result(result)
}
else // mysql_store_result() returned nothing; should it have?
{
if(mysql_field_count(&mysql) == 0)
{
// query does not return data
// (it was not a SELECT)
num_rows = mysql_affected_rows(&mysql);
}
else // mysql_store_result() should have returned data
{
fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}
}
}
Uma alternativa ´e substituir a chamada mysql_field_count(&mysql) com
mysql_errno(&mysql). Neste caso, vocˆe est´a verificando diretamente um erro de
mysql_store_result() em vez de conferir o valor de mysql_field_count() se a instru¸ao
foi uma SELECT.
8.1.3.21 mysql_field_seek()
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET
offset)
Chapter 8: MySQL APIs 571
Descri¸ao
Define o cursor campo com o offset dado. A pr´oxima chamada para mysql_fetch_field()
ir´a recuperar a defini¸ao de campo da coluna associada com o offset.
Para buscar o inicio de um registro, passe zero como valor do offset.
Valor Retornado
O valor anterior do cursor de campo.
Erros
Nenhum.
8.1.3.22 mysql_field_tell()
MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)
Descri¸ao
Retorna a posi¸ao do cursos do campo usado pelo ´ultimo mysql_fetch_field(). Este valor
pode ser usado como um argumento para mysql_field_seek().
Valor Retornado
O offset atual do cursor de campo.
Erros
Nenhum.
8.1.3.23 mysql_free_result()
void mysql_free_result(MYSQL_RES *result)
Descri¸ao
Libera a mem´oria alocada para o resultado por mysql_store_result(),mysql_use_
result(),mysql_list_dbs(), etc. Quando vocˆe finalizar o uso do resultado, vocˆe deve
liberar a mem´oria utilizada chamando mysql_free_result().
Valor Retornado
Nenhum.
Erros
Nenhum.
572 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.3.24 mysql_get_client_info()
char *mysql_get_client_info(void)
Descri¸ao
Retorna uam string que representa a vers˜ao da biblioteca cliente.
Valor Retornado
Uma string representando a vers˜ao da biblioteca cliente do MySQL.
Erros
Nenhum.
8.1.3.25 mysql_get_server_version()
unsigned long mysql_get_server_version(MYSQL *mysql)
Descri¸ao
Retorna o n´umero de vers˜ao do servidor como um inteiro (novo na vers˜ao 4.1)
Valor Retornado
Um n´umero que representa a vers˜ao do servidor MySQL no formato:
vers˜ao principal*10000 +vers˜ao menor*100 +sub vers˜ao
Por exemplo, 4.1.0 ´e retornado como 40100.
Ela ´e ´util para determinar a vers˜ao do servidor rapidamente em um programa cliente para
saber se algumas capacidades existem.
Erros
Nenhum.
8.1.3.26 mysql_get_host_info()
char *mysql_get_host_info(MYSQL *mysql)
Descri¸ao
Retorna uma string descrevendo o tipo da conex˜ao em uso, incluindo o nome da maquina
servidora.
Valor Retornado
Uma string respresntando o nome da m´aquina servidora e o tipo de conex˜ao.
Chapter 8: MySQL APIs 573
Erros
Nenhum.
8.1.3.27 mysql_get_proto_info()
unsigned int mysql_get_proto_info(MYSQL *mysql)
Descri¸ao
Retorna a vers˜ao do protocolo usado pela conex˜ao atual.
Valor Retornado
Um unsigned integer (inteiro sem sinal) representando a vers˜ao do protocolo usado pela
conex˜ao atual.
Erros
Nenhum.
8.1.3.28 mysql_get_server_info()
char *mysql_get_server_info(MYSQL *mysql)
Descri¸ao
Retorna um string que representa o n´umero da vers˜ao do servidor.
Valor Retornado
Um string representando o n´umero da vers˜ao do servidor.
Erros
Nenhum.
8.1.3.29 mysql_info()
char *mysql_info(MYSQL *mysql)
Descri¸ao
Retorna um string fornecendo informa¸ao sobre a consulta executada mais recentemente,
mas apenas para as instru¸oes listadas aqui. Para outras inastru¸oes, mysql_info() retorna
NULL. O formato da string varia dependendo do tipo de consulta, como descrito aqui. Os
n´umeros s˜ao apenas ilustrativos; a string ir´a conter valores apropriados para a consulta.
INSERT INTO ... SELECT ...
Formato da string: Records: 100 Duplicates: 0 Warnings: 0
574 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
INSERT INTO ... VALUES (...),(...),(...)...
Formato da string: Records: 3 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ...
Formato da string: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE
Formato da string: Records: 3 Duplicates: 0 Warnings: 0
UPDATE Formato da string: Rows matched: 40 Changed: 40 Warnings: 0
Note que mysql_info() retorna um valor n˜ao-NULL para a instru¸ao INSERT ... VALUES
somente se um lista de m´
iltiplos valores ´e especificada na instru¸ao.
Valor Retornado
Uma string represntando informa¸ao adicional sobre a consulta executada mais recente-
mente. NULL se n˜ao houver nenhuma informa¸ao dispon´
ivel para a consulta.
Erros
Nenhum.
8.1.3.30 mysql_init()
MYSQL *mysql_init(MYSQL *mysql)
Descri¸ao
Aloca ou inicializa um objeto MYSQL apropriado para mysql_real_connect(). Se mysql ´e
um ponteiro NULL, a fun¸ao aloca, inicializa e retorna um novo objeto. Sen˜ao o objeto ´e
inicializado e o endere¸co do objeto ´e retornado. Se mysql_init() aloca um novo objeto,
ele ser´a liberado quando mysql_close() for chamado para fechar a conex˜ao.
Valor Retornado
Um handle MYSQL* inicializado. NULL se n˜ao houver mem´oria suficiente para alocar o novo
objeto.
Erros
Em caso de mem´oria insuficiente, NULL ´e retornado.
8.1.3.31 mysql_insert_id()
my_ulonglong mysql_insert_id(MYSQL *mysql)
Chapter 8: MySQL APIs 575
Descri¸ao
Retorna o ID gerado para uma coluna AUTO_INCREMENT pela consulta anterior. Use esta
fun¸ao depois de ter realizado um consulta INSERT em uma tabela que contenha um campo
AUTO_INCREMENT.
Note que mysql_insert_id() retorna 0se a consulta anterior n˜ao gerar um valor AUTO_
INCREMENT. Se vocˆe desejar salvar o valor para uso posterior, chame mysql_insert_id()
imediatamente depois da consulta que gerou o valor.
mysql_insert_id() ´e atualizado depois de instru¸oes INSERT eUPDATE que geram um
valor AUTO_INCREMENT ou que definem um valor de coluna com LAST_INSERT_ID(expr).
See hundefinedi[Fun¸oes diversas], page hundefinedi.
Note tamb´em que o valor da fun¸ao SQL LAST_INSERT_ID() sempre cont´em o o valor AUTO_
INCREMENT gerado mais recentemente e n˜ao ´e zerado entre as consultas porque o valor desta
fun¸ao ´e mantido no servidor.
Valor Retornado
O valor do campo AUTO_INCREMENT que foi atualizado pela consulta anterior. Retorna
zero se n˜ao houve consultas anteriores na conex˜ao ou se a consulta n˜ao atualizou o valor
AUTO_INCREMENT.
Erros
Nenhum.
8.1.3.32 mysql_kill()
int mysql_kill(MYSQL *mysql, unsigned long pid)
Descri¸ao
Diz para o servidor matar um thread especificada pelo pid.
Valor Retornado
Zero em caso de sucesso. Diferente de zero se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
576 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.3.33 mysql_list_dbs()
MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)
Descri¸ao
Retorna um resultado com nome de banco de dados no servidor que correspondem a uma
express˜ao regular especificada pelo parˆametro wild.wild pode conter o meta caracteres ‘%
ou ‘_’, ou pode ser um ponteiro NULL para coreesponder a todos os banco de dados. Chamar
mysql_list_dbs() ´e o mesmo que executar a consulta SHOW databases [LIKE wild].
Voe deve liberar o resultado com mysql_free_result().
Valor Retornado
Um conjunto de resultados MYSQL_RES no caso de sucesso. NULL se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.34 mysql_list_fields()
MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char
*wild)
Descri¸ao
Retorna um resultado contendo nomes de campos de uma tabela dada que correspondam a
express˜ao regular especificada pelo parˆametro wild.wild pode conter os metacaracteres ‘%
ou ‘_’, ou pode ser um ponteiro NULL para corresponder a todos os campos. Chamar mysql_
list_fields() ´e o mesmo que executar a consulta SHOW COLUMNS FROM nome_tabela [LIKE
wild].
Note que ´e recomendado que vocˆe use SHOW COLUMNS FROM nome_tabela em vez de mysql_
list_fields().
Voe deve liberar o resultado com mysql_free_result().
Valor Retornado
Um conjunto de resultados MYSQL_RES em caso de sucesso. NULL se ocorrer um erro.
Chapter 8: MySQL APIs 577
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.35 mysql_list_processes()
MYSQL_RES *mysql_list_processes(MYSQL *mysql)
Descri¸ao
Retorna um resultado descrevendo a thread atual do servidor. ´
E o mesmo tipo de informa¸ao
relatado por mysqladmin processlist ou uma consulta SHOW PROCESSLIST.
Voe deve liberar o resultado com mysql_free_result().
Valor Retornado
Um conjunto de resultados MYSQL_RES em caso de sucesso. NULL se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.36 mysql_list_tables()
MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)
Descri¸ao
Retorna um resultado contendo nomes de tabelas no banco de dados atual que correspondam
a express˜ao regular especificada pelo parˆametro wild.wild pode conter os mets caracteres
%’ or ‘_’, ou pode ser uma ponteiro NULL para corresponde a todas as tabelas. Chamar
mysql_list_tables() ´e o mesmo que executar a consulta SHOW tables [LIKE wild].
Voe deve liberar o resultado com mysql_free_result().
578 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Valor Retornado
Um conjunto de resultados MYSQL_RES em caso de sucesso. NULL se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.37 mysql_num_fields()
unsigned int mysql_num_fields(MYSQL_RES *result)
ou
unsigned int mysql_num_fields(MYSQL *mysql)
A segunda forma n˜ao funciona na vers˜ao 3.22.24 ou mais novas do MySQL. Para passar um
argumento MYSQL* vocˆe de utilizar unsigned int mysql_field_count(MYSQL *mysql) em
seu lugar.
Descri¸ao
Retorna o n´umero de colunas em um resultado.
Note que vocˆe pode obter o n´umero de colunas com um ponteiro para o conjunto de resul-
tados ou para um manipulador (handle) de conex˜ao. Voe usaria o manipular de conex˜ao
se mysql_store_result() ou mysql_use_result() retorna NULL (enao vocˆe n˜ao tem um
ponteiro para o resultado). Neste caso, vocˆe pode chamar mysql_field_count() para de-
terminar se mysql_store_result() ao produziu um resultado vazio. Isto permite que o
programa cliente tome a a¸ao apropriada sem saber se a consulta foi uma instru¸ao SELECT
(ou do tipo SELECT). O exemplo mostrado abaixo ilustra como isto pode ser feito.
See hundefinedi[NULL mysql_store_result()], page hundefinedi.
Valor Retornado
Um unsigned integer (inteiro sem sinal) representando o n´umero de campos no conjunto de
resultasdos.
Erros
Nenhum.
Chapter 8: MySQL APIs 579
Exemplo
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;
if (mysql_query(&mysql,query_string))
{
// erro
}
else // query succeeded, process any data returned by it
{
result = mysql_store_result(&mysql);
if (result) // existem resgitros
{
num_fields = mysql_num_fields(result);
// retorna registros e chama mysql_free_result(result)
}
else // mysql_store_result() retorna vazio; era esperado?
{
if (mysql_errno(&mysql))
{
fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}
else if (mysql_field_count(&mysql) == 0)
{
// consulta n~ao retora dados
// (ela n~ao era um SELECT)
num_rows = mysql_affected_rows(&mysql);
}
}
}
Uma alternativa (se vocˆe souber qyue a sua consulta retornou um resultado) ´e substituir
a chamada mysql_errno(&mysql) pela verifica¸ao de se mysql_field_count(&mysql) ´e =
0. Isto s´o acontece se alguma coisa der errado.
8.1.3.38 mysql_num_rows()
my_ulonglong mysql_num_rows(MYSQL_RES *result)
Descri¸ao
Retorna o n´umero de linhas em um resultado.
O uso de mysql_num_rows() depende de se vocˆe utiliza mysql_store_result() ou mysql_
use_result() para retornar o resultado. Se vocˆe usa mysql_store_result(),mysql_num_
rows() pode ser chamado imediatamente. Se vocˆe usa mysql_use_result(),mysql_num_
rows() ao retornar´a o valor correto at´e que todas as linhas no resultado tenham sido
recuperadas.
580 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Valor Retornado
O numero de linhas no resultado.
Erros
Nenhum.
8.1.3.39 mysql_options()
int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)
Descri¸ao
Pode ser usado para definir op¸oes extras de conex˜ao e afetar o comportamento de uma
conex˜ao. Esta fun¸ao pode ser chamada v´arias vezes para definir diversas op¸oes.
mysql_options() deve ser chamado depois de mysql_init() e antes de mysql_connect()
ou mysql_real_connect().
O argumento option ´e a op¸ao que vocˆe que definir; o argumento arg ´e o valor para a
op¸ao. Se a op¸ao ´e um inteiro, enao arg deve apontar para o valor do inteiro.
Valores poss´
iveis para as op¸oes:
Op¸ao Tipo de
argumento
Fun¸ao
MYSQL_OPT_CONNECT_TIMEOUT unsigned int
*
Tempo limite de conex˜ao em
segundos.
MYSQL_OPT_COMPRESS ao usado Usa o protocolo cliente/servidor
compactado.
MYSQL_OPT_LOCAL_INFILE ponteiro para
unsigned
integer
opcional
Se nenhum ponteiro for dado ou
se apontar para um unsigned
int != 0 o comando LOAD LOCAL
INFILE est´a habilitado.
MYSQL_OPT_NAMED_PIPE ao usado Usa named pipes para conectar
ao servidor MySQL no NT.
MYSQL_INIT_COMMAND char * Comando para executar ao
conectar ao servidor MySQL.
Ser´a automaticamente execu-
tado ao se reconectar.
MYSQL_READ_DEFAULT_FILE char * Lˆe op¸oes do arquivo de op¸oes
definido no lugar de ‘my.cnf’.
MYSQL_READ_DEFAULT_GROUP char * Lˆe op¸oes do grupo indicado no
arquivo ‘my.cnf’ ou no arquivo
especificado com MYSQL_READ_
DEFAULT_FILE.
Note que o grupo client ´e sempre lido se vocˆe utiliza MYSQL_READ_DEFAULT_FILE ou MYSQL_
READ_DEFAULT_GROUP.
O grupo especificado no arquivo de op¸os pode conter as seguintes op¸oes:
Op¸ao Descri¸ao
Chapter 8: MySQL APIs 581
connect-timeout Tempo limite de conex˜ao em segundos. No Linux
este tempo limite tamb´em ´e utilizado para esperar
pela primeira resposta do servidor
compress Utiliza o protocolo cliente/servidor compactado.
database Conecta a este banco de dados se nenhum banco de
dados for especificado no comando de conex˜ao.
debug Op¸oes de depura¸ao.
disable-local-
infile
Disabilita o uso de LOAD DATA LOCAL.
host Nome de m´aquina padr˜ao.
init-command Comando para executar ao conectar ao servi-
dor MySQL. Ser´a executado automaticamente ao
reconectar.
interactive-
timeout
O mesmo que o especificado em CLIENT_
INTERACTIVE para mysql_real_connect(). See
hundefinedi[mysql real connect], page hundefinedi.
local-
infile[=(0|1)]
Se n˜ao houver argumento ou o argumento for difer-
ente de 0 habilita o uso de LOAD DATA LOCAL.
max_allowed_packet Tamanho m´aximo dos pacotes que o cliente pode ler
do servidor.
password Senha padr˜ao.
pipe Usa named pipes para conectar ao servidor MySQL
no NT.
protocol=(TCP |
SOCKET | PIPE |
MEMORY)
Qual protocolo usar ao conectar no servidor (Novo
na vers˜ao 4.1)
port N´umero padr˜ao da porta.
return-found-rows Diz ao mysql_info() para retornar registros en-
contrados no lugar de registros atualizados ao usar
UPDATE.
shared-memory-
base-name=name
Nome da mem´oria comprtilhada utilizada para
conectar ao servidor (o padr˜ao ´e "MySQL"). Novo
na vers˜ao 4.1.
socket N´umero padr˜ao do socket.
user Usu´ario padr˜ao.
Note que timeout foi substituido por connect-timeout, mas timeout ainda funcionar´a
por enquanto.
Para maiores informa¸oes sobre arquivos de op¸oes, veja hundefinedi[Arquivo de op¸oes],
page hundefinedi.
Valor Retornado
Zero em caso de sucesso. Diferente de zero se vocˆe utilizar uma op¸ao desconhecida.
Exemplo
MYSQL mysql;
mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
582 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
{
fprintf(stderr, "Failed to connect to database: Error: %s\n",
mysql_error(&mysql));
}
O exemplo acima diz ao cliente para usar o protocolo cliente/servidor compactado e ler a
op¸ao adicional da se¸ao odbc no arquivo de op¸oes ‘my.cnf’.
8.1.3.40 mysql_ping()
int mysql_ping(MYSQL *mysql)
Descri¸ao
Verifica se a conex˜ao ao servidor est´a funcionando. Se ela tiver ca´
ido ´e feita uma tentativa
de conex˜ao automaticamente.
Esta fun¸ao pode ser usada pelos clientes que se ficam inativo por um longo tempo para
verificar se o servidor fechou a conex˜ao e reconectar se necess´ario.
Valor Retornado
Zero se o servidor estiver funcionando. Diferente de zero se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.41 mysql_query()
int mysql_query(MYSQL *mysql, const char *query)
Descri¸ao
Executa uma consulta SQL apontada pela string terminada em null query. A consulta deve
deve consistir de uma ´unica instru¸ao SQL. Voe n˜ao deve adicionar ponto e v´
irgula (‘;’)
ou \g ao fim da instru¸ao.
mysql_query() ao pode ser usadas por consultas que contenham dados bin´arios; vocˆe deve
utilizar mysql_real_query() em seu lugar. (Dados bin´arios podem conter o caracter ‘\0’,
que mysql_query() interpreta como o fim a string de consulta.)
Se vocˆe quiser saber se a consulta deve retornar um resultado ou n˜ao, vocˆe pode uti-
lizar mysql_field_count() para verificar isto. See hundefinedi[mysql_field_count()],
page hundefinedi.
Chapter 8: MySQL APIs 583
Valor Retornado
Zero se a consulta obteve sucesso. Diferente de zero se ocorreu um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.42 mysql_real_connect()
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
const char *passwd, const char *db, unsigned int port, const char *unix_socket,
unsigned int client_flag)
Descri¸ao
mysql_real_connect() tenta estabelecer uma conex˜ao mecanismo MySQL de banco de
dados executando em host.mysql_real_connect() deve completar com suceeso antes que
vocˆe possa executar qualquer um das outars fun¸aoes da API, com a excess˜ao de mysql_
get_client_info().
Os parˆametros s˜ao especificados da seguinte forma:
O primeiro parˆametro deve ser o endere¸co de uma estrutura MYSQL existente. Antes
de chamar mysql_real_connect() vocˆe deve chamar mysql_init() para inicializar a
estrutura MYSQL. Voe pode alterar v´aria op¸oes de conex˜ao com a chamada mysql_
options(). See hundefinedi[mysql options], page hundefinedi.
O valor de host pode ser tanto um nome de m´aquivo quanto um endere¸co IP. Se host
´e NULL ou a string "localhost", a conex˜ao ´e feita na m´aquina local. Se o SO suporta
sockets (Unix) ou named pipes (Windows), eles s˜ao utilizados em vez de TCP/IP para
a conex˜ao ao servidor.
O parˆametro user cont´em a indetifica¸ao do usu´ario MySQL. Se user ´e NULL, considera-
se o usu´ario padr˜ao. Sob Unix, ele ´e o login atual. Sob ODBC no Windows, o usu´ario
atual deve ser especificado explicitamente. See hundefinedi[Administrador ODBC],
page hundefinedi.
O parˆametro passwd cont´em a senha para user. Se passwd ´e NULL, somente entradas
na tabela user para usu´arios que tenham campo de senha em branco (vazia) ser˜ao
verificados ipor um padr˜ao coincidenete. Isto permite que o admistrador do banco
de dados configure o sistema de privil´egios do MySQL de tal maneira que usu´arios
os usu´arios conseguir˜ao privileios diferentes, dependendo se ele espcificou ou n˜ao uma
senha.
584 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Nota: ao tente criptografar a senha antes de chamar mysql_real_connect(); senhas
criptografadas s˜ao tratadas automaticamente pela API cliente.
db ´e o nome de banco de dados. Se db ao ´e NULL, a conex˜ao definir´a o banco de dados
padr˜ao com este valor.
Se port ao ´e 0, o valor ser´a usado como o n´umero da porta para as conex˜oes TCP/IP.
Note que o parˆametro host determina o tipo da conex˜ao.
Se unix_socket ao ´e NULL, a string especifica o socket ou named pipe que deve ser
usado. Note que o parˆametro host determina o tipo de conex˜ao.
O valor de client_flag ´e normalmente 0, mas pode ser definido como uma combina¸ao
dos parˆametro seguintes em circunstˆancias especiais:
Nome do parˆametro Descri¸ao do parˆametro
CLIENT_COMPRESS Usa protocolo compactado.
CLIENT_FOUND_ROWS Retorna o n´umero de linhas encontradas (correspon-
dentes a um padr˜ao), n˜ao o n´umero de linha efetivo.
CLIENT_IGNORE_SPACE Permite espa¸co depois do nome de fun¸oes. torna todos
os nomes de fun¸oes palavras reservadas.
CLIENT_INTERACTIVE Permite interactive_timeout segundos (no lugar de
wait_timeout segundos) de inatividade antes de fechar
a conex˜ao.
CLIENT_NO_SCHEMA ao permite a sintaxe db_name.nome_tabela.nome_
coluna. Isto ´e para o ODBC. Ele faz com que o anal-
izador gere um erro se vocˆe utilizar aquela sintaxe. ´
E ´util
para achar erros em alguns programas ODBC.
CLIENT_ODBC O cliente ´e um cliente ODBC. Torna o mysqld mais
amig´avel ao ODBC.
CLIENT_SSL Usa SSL (protocolo criptografado).
Valor Retornado
Um handle de conex˜ao MYSQL* se a conex˜ao foi obtida com sucesso, NULL se a conex˜ao
falhou. Para um conex˜ao estabelecida o valor de retorn ´e o mesmo que o valor do primeiro
parˆametro.
Erros
CR_CONN_HOST_ERROR
Falhou ao conectar ao servidor MySQL.
CR_CONNECTION_ERROR
Falhou ao conectar ao servidor MySQL local.
CR_IPSOCK_ERROR
Falhou au criar um socket IP.
CR_OUT_OF_MEMORY
Sem mem´oria.
CR_SOCKET_CREATE_ERROR
Falhou ao criar um socket Unix.
Chapter 8: MySQL APIs 585
CR_UNKNOWN_HOST
Falhou ao procurar o endere¸co IP para o nome de maquina.
CR_VERSION_ERROR
Um erro de protocolo resultou da tentativa de conexao a um servidor com
uma biblioteca cliente que utiliza uma vers˜ao de protocolo diferente. Isto pode
acontecer se vocˆe utiliza uma biblioteca cliente muito antiga para se conectar a
um novo servidor qua n˜ao foi iniciado com a op¸ao --old-protocol.
CR_NAMEDPIPEOPEN_ERROR
Falhou ao criar um named pipe no Windows.
CR_NAMEDPIPEWAIT_ERROR
Falhou ao esperar por um named pipe no Windows.
CR_NAMEDPIPESETSTATE_ERROR
Falhou ao conseguir mainpulador do pipe no Windows.
CR_SERVER_LOST
Se connect_timeout > 0 e leva mais que connect_timeout segundos para
conectar ao servidor ou se o servidro foi finalizado ao executar o init-command.
Exemplo
MYSQL mysql;
mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"seu_programa");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
{
fprintf(stderr, "Failed to connect to database: Error: %s\n",
mysql_error(&mysql));
}
Usando mysql_options() a biblioteca MySQL ir´a ler as se¸oes [client] e[seu_programa]
no arquivo ‘my.cnf’ o qual ir´a assegurar que seu programa ir´a funcionar, mesmo se alguem
tiver configurado o MySQL de um modo fora do padr˜ao.
Note que sob a conex˜ao, mysql_real_connect() define o parˆametro reconnect (parte da
estrutura MYSQL) para um valor de 1. Este parˆametro indica, no evento em que uma consulta
ao pode ser realizada devido a perda de conex˜ao, para tentar se reconectar ao servidor
antes de esgotar as tentativas.
8.1.3.43 mysql_real_escape_string()
unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char
*from, unsigned long length)
Descri¸ao
A fun¸ao ´e usada para criar um string SQL v´alida que vocˆe pode usar em uma instru¸ao
SQL. See hundefinedi[Sintaxe de string], page hundefinedi.
586 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A string em from ´e codificada para uma string SQL com escape, levando em conta o conjunto
de caracteres atual da conex˜aon. O resultado ´e colocada em to e uma byte nulo de termin¸ao
´e adcionado. Caracteres codificados s˜ao NUL (ASCII 0), ‘\n’, ‘\r’, ‘\’, ‘’, ‘"’, e Control-
Z (See hundefinedi[Literais], page hundefinedi). (O MySQL precisa que apenas a barra
invertida e as aspas utilizadas para citar a consulta sejam escapadas. Esta fun¸ao coloca os
outros caracteres entre aspas para torn´a-lo mais f´acil de ser lido em arquivos log.)
A string apontada por from deve ter o tamanho de length bytes. Voe deve alocar o buffer
to para o tamanho de pelo menos length*2+1 bytes. (No pior caso, cada caracter pode
precisar de ser codificado como se utilizasse dois bytes, e vocˆe preciria de espa¸co para o
byte null de termina¸ao.) Quando mysql_real_escape_string() retornar, o conte´udo de
to ser´a uma string terminada em null. O valor ´e o tamanho da string codificada. ao
incluindo o caracter nulo usado para terminar a string.
Exemplo
char query[1000],*end;
end = strmov(query,"INSERT INTO test_table values(");
*end++ = ’\’’;
end += mysql_real_escape_string(&mysql, end,"What’s this",11);
*end++ = ’\’’;
*end++ = ’,’;
*end++ = ’\’’;
end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
*end++ = ’\’’;
*end++ = ’)’;
if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
{
fprintf(stderr, "Failed to insert row, Error: %s\n",
mysql_error(&mysql));
}
A fun¸ao strmov() usada no exemplo est´a inclu´
ida na biblioteca mysqlclient e funciona
como strcpy() mas retorna um ponteiro para null de termina¸ao do primeiro parˆametro.
Valor Retornado
O tamanho do valor colocado em to, n˜ao incluindo o caracter null de termina¸ao.
Erros
Nenhum.
8.1.3.44 mysql_real_query()
int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)
Chapter 8: MySQL APIs 587
Descri¸ao
Executa a consulta SQL apontada por query, que deve ser uma string de length bytes. A
consulta deve consistir de uma instru¸ao SQL simples. Voe n˜ao deve adicionar um ponto
e virgula (‘;’) ou \g no fim da instru¸ao.
Voe deve utilizar mysql_real_query() em lugar de mysql_query() para consultas que
contenham dados bin´arios, pois eles podem conter o caracter ‘\0’. Al´em disso, mysql_real_
query() ´e mais r´apido que mysql_query() pois ele n˜ao faz chamadas strlen() na string
de consulta.
Se vocˆe quiser saber se a consulta retornou um resultado ou n˜ao, vocˆe pode usar mysql_
field_count(). See hundefinedi[mysql field count], page hundefinedi.
Valor Retornado
Zero se a consulta obteve sucesso. Deiferente de zero se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.45 mysql_reload()
int mysql_reload(MYSQL *mysql)
Descri¸ao
Diz ao servidor MySQL para recarregar a tabela de ables. The connected user must have
the RELOAD privilege.
This function is deprecated. It is preferable to use mysql_query() to issue a SQL FLUSH
PRIVILEGES statement instead.
Valor Retornado
Zero for success. Non-zero if an error occurred.
588 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.46 mysql_row_seek()
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)
Descri¸ao
Atribui ao cursor de linha um registro arbitr´ario em resultado de uma consulta. Isto exige
que a estrutura do resultado contenha todo o resultado da consulta, assim mysql_row_
seek() pode ser um usado em conjunto apenas com mysql_store_result(), e n˜ao com
mysql_use_result().
O offset deve ser um valor retornado de uma chamada a mysql_row_tell() ou a mysql_
row_seek(). Este valor n˜ao simplesmente um n´umero de linha; se vocˆe quiser buscasr um
registro em um resultado usando o n´umero de linha utilize mysql_data_seek().
Valor Retornado
O valor anterior do cursor de linha. Este valor pode ser passado a uma chamada subsequente
mysql_row_seek().
Erros
Nenhum.
8.1.3.47 mysql_row_tell()
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)
Descri¸ao
Retorna a posi¸ao atual do cursor de linha para a ´ultima mysql_fetch_row(). Este valor
pode ser utilizado como argumento para mysql_row_seek().
Voe deve utilizar mysql_row_tell() somente depois de mysql_store_result(), e n˜ao
depois de mysql_use_result().
Valor Retornado
O offset atual do cursos de linha.
Chapter 8: MySQL APIs 589
Erros
Nenhum.
8.1.3.48 mysql_select_db()
int mysql_select_db(MYSQL *mysql, const char *db)
Descri¸ao
Faz com que o banco de dados espexcificado por db se torne o padr˜ao (atual) na conex˜ao
especificada por mysql. Nas consultas seguintes este banco de dados ´e o padr˜ao para tabelas
que n˜ao incluem uma especifica¸ao explicita para o banco de dados.
mysql_select_db() falha a menos que o usu´ario conectado possa ser autenticado com
permiss˜ao para utilizar o banco de dados.
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.49 mysql_shutdown()
int mysql_shutdown(MYSQL *mysql)
Descri¸ao
Diz ao servidor de banco de dados para finalizar. O usu´ario conectado deve ter privil´egio
SHUTDOWN.
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
590 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.50 mysql_stat()
char *mysql_stat(MYSQL *mysql)
Descri¸ao
Retorna uma string contendo informa¸oes sinmilares a aquelas fornecidas pelo comando
mysqladmin status. Isto inclui o tempo de conex˜ao em segundos e o n´umero de threads
em execu¸ao, recargas e tabelas abertas.
Valor Retornado
Uma string descrevendo o status do servidor. NULL se um erro ocorrer.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.51 mysql_store_result()
MYSQL_RES *mysql_store_result(MYSQL *mysql)
Descri¸ao
Voe deve chamar mysql_store_result() ou mysql_use_result() para cada consulta que
retorne dados com sucesso (SELECT,SHOW,DESCRIBE,EXPLAIN).
Voe n˜ao precisa chamar mysql_store_result() ou mysql_use_result() para outras con-
sultas, mas ele n˜ao causar´a nenhum dano ou nenhuma queda notel de desempenho se vocˆe
Chapter 8: MySQL APIs 591
chamar mysql_store_result() em todos os casos. Vocˆe pode detectar se a consulta n˜ao
obteve resultado verificando se mysql_store_result() retornou 0.
Se vocˆe quiser saber se a consulta devia retornar algum resultado, vocˆe pode utilizar mysql_
field_count() para fazer a verifica¸ao. See hundefinedi[mysql field count], page hunde-
finedi.
mysql_store_result() lˆe todo o resultado de uma consulta para um cliente, aloca uma
estrutura MYSQL_RES e coloca o resultado nesta estrutura.
mysql_store_result() retorna um ponteiro para null se a consulta n˜ao retornar um re-
sultado (se a consulta foi, por exemplo, uma instru¸ao INSERT).
mysql_store_result() tamb´em retorna um ponterio para null se a leitura do resultado
falhar. Voe pode verficar se vocˆe obteve um erro verificando se mysql_error() ao re-
tornou um ponterio para null, se mysql_errno() retorna <> 0, ou se mysql_field_count()
retorna <> 0.
Um resultado vazio ´e retornado se n˜ao houver registros a retornar. (Um resultado vazio ´e
diferente de um ponteiro para null em um valor de retorno).
Uma vez que vocˆe tenha chamado mysql_store_result() e tenha retornado um resultado
que n˜ao ´e uma apontador para null, vocˆe pode chamar mysql_num_rows() para descobrir
quantas linhas existem no resultado.
Voe pode chamar mysql_fetch_row() para buscar registros no resultado ou mysql_row_
seek() emysql_row_tell() para obter ou definir a poi¸ao atual do registro dentro do
resultado.
Voe deve chamar mysql_free_result() quando tiver terminado com o resultado.
See hundefinedi[NULL mysql_store_result()], page hundefinedi.
Valor Retornado
Uma estrutura de resultado MYSQL_RES com o resultado. NULL se um erro ocorreu.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Sem memoria.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.52 mysql_thread_id()
unsigned long mysql_thread_id(MYSQL *mysql)
592 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Descri¸ao
Retorna a ID da thread da conex˜ao atual. Este valor pode ser usado como um argumento
para mysql_kill() para finalizar a thread.
Se a conex˜ao for perdida e vocˆe reconectar com mysql_ping(), a ID da thread ir´a alterar.
Isto significa que vocˆe deve obter a ID da thread e guard´a-la para uso posterior. Voe deve
obtˆe-la quando precisar dela.
Valor Retornado
A ID da thread da conex˜ao atual.
Erros
Nenhum.
8.1.3.53 mysql_use_result()
MYSQL_RES *mysql_use_result(MYSQL *mysql)
Descri¸ao
Voe deve chamar mysql_store_result() ou mysql_use_result() para cada consulta que
retornar data com sucesso (SELECT,SHOW,DESCRIBE,EXPLAIN).
mysql_use_result() inicicia a recupera¸ao de um resultado mas n˜ao lˆe realmente o re-
sultado no cliente como mysql_store_result() faz. Cada regiostro deve ser recuperado
individualmente fazendo chamadas a mysql_fetch_row(). Ele lˆe o resultado de uma con-
sulta diretamente do servidor sem armazenar em uma tabela tempor´aria ou em um buffer
local, o o que ´e mais r´apido e utiliza menos mem´oria que mysql_store_result(). O cliente
s´
io ir´a alocar mem´oria para o registro atual para o buffer de comunica¸ao que pode crescer
para max_allowed_packet bytes.
Por outro lado , vocˆe n˜ao deve utilizar mysql_use_result() se vocˆe estiver fazendo v´arios
processamentos para cada registros no lado do cliente, ou se a sa´
ida ´e enviada para a tela,
na qual o usu´ario de digitar um ^S (parada de tela). Isto ir´a prender o servidor e impedir
outras threads de atualizar qualquer tabela na qual o dados esteja sendo buascado.
Ao usar mysql_use_result(), vocˆe deve executar mysql_fetch_row() at´e um valor NULL
ser retornado, sen˜ao, os registros n˜ao buscados retornar˜ao como part do resultado de sua
pr´oxima consulta. A API C fornecer´a o erro Commands out of sync; you can’t run this
command now se vocˆe esquecer de fazˆe-lo.
Voe n˜ao pode utilizar mysql_data_seek(),mysql_row_seek(),mysql_row_tell(),
mysql_num_rows(), ou mysql_affected_rows() com m resultado retornado de
mysql_use_result(), nem pode executar outras consultas at´e que mysql_use_result()
tenha finalizado. (No entanto, depois de buscar todos os regitros, mysql_num_rows()
retornar´a corretamente o n´umero de regiostros buscados).
Voe deve chamar mysql_free_result() ap´os terminar de utilizar o resultado.
Chapter 8: MySQL APIs 593
Valor Retornado
Uma estrutura de resultado MYSQL_RES.NULL se ocorrer um erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Sem mem´oria.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.3.54 mysql_commit()
my_bool mysql_commit(MYSQL *mysql)
Descri¸ao
Faz um commits na transa¸ao atual. Dispon´
ivel no MySQL 4.1
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
Erros
Nenhum.
8.1.3.55 mysql_rollback()
my_bool mysql_rollback(MYSQL *mysql)
Descri¸ao
Faz um rollback na transa¸ao atual. Dispon´
ivel no MySQL 4.1
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
Erros
Nenhum.
594 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.3.56 mysql_autocommit()
my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)
Descri¸ao
Define o modo autocommit como ligado/desligado. Se o mode for 1, defien o modo auto-
commit como ligado; Se for 0, como desligado. Dispon´
ivel no MySQL 4.1
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
Erros
Nenhum.
8.1.3.57 mysql_more_results()
my_bool mysql_more_results(MYSQL *mysql)
Descri¸ao
Retorna verdade se mais resultados da consulta atualmente em execu¸ao existem, e a
aplica¸ao deve chamar mysql_next_result() para buscar os resultados. Dispon´
ivel no
MySQL 4.1
Valor Retornado
TRUE se existem mais resultados. FALSE se n˜ao existem mais resultados.
Erros
Nenhum.
8.1.3.58 mysql_next_result()
int mysql_next_result(MYSQL *mysql)
Descri¸ao
Se existem mais resultados da consulta, mysql_next_result() e o pr´oximo resultado da
consulta e retorna o status a aplica¸ao. Dispon´
ivel no MySQL 4.1
Valor Retornado
Zero em caso de sucesso. Deiferente de zero se ocorrer um erro.
Erros
Nenhum.
Chapter 8: MySQL APIs 595
8.1.4 Intru¸oes Preparadas da API C
A partir da vers˜ao 4.1 do MySQL, vocˆe tamb´em pode fazer uso de instru¸oes preparadas
utilizando o manipulador de instru¸oes MYSQL_STMT, que suporta a execu¸ao de m´ultiplas
consultas e liga¸ao de sa´
idas.
Execu¸ao preparada ´e um modo eficiente de executar uma instru¸ao mais de uma vez. A
instru¸ao ´e primeiramente analizada (preparada). Ent˜ao ´e executada uma ou mais vezes
posteriormente, utilizando o manipulador de instru¸oes retornado pela fun¸c˜ao preparada.
Outra vantagem de instru¸oes preparadas ´e que ela utiliza um protocolo bin´ario, o qual faz
a transferˆencia de dados entre clinete e servidor de forma mais eficiente.
Execu¸ao preparada ´e mais r´apida que a execu¸ao direta para instru¸oes executadas mais
que uma vez, pois a consulta ´e analizada apenas uma vez; No caso de execu¸ao direta ,
a consulta ´e analisada todas as vezes. Execu¸ao preparada tamb´em pode fornecer uma
redu¸ao de tr´afico de rede pois durante a execu¸ao da chamada, s´o s˜ao enviados os dados
para os parˆametros.
8.1.5 Tipo de Dados de Instru¸oes Prepaadas da API C
Instru¸ao preparadas utilizam principalmente as duas estruturas MYSQL_STMT eMYSQL_BIND
seguintes:
MYSQL_STMT
Esta estrutura representa um manipuladaor de instru¸ao para instru¸c˜aoes
preparadas. Ele ´e usada por todas as fun¸oes relacionadas a instru¸oes.
A instru¸ao ´e inicializada quando a consulta ´e preparada utilizando mysql_
prepare().
Uma conex˜ao pode ter ’n’ maniouladores de instru¸oes, e o limite depende dos
recursos do sistema.
MYSQL_BIND
Esta estrutura ´e utilizada para ligar buffer de parˆametros (mysql_bind_
param()) utlizando os dados dos parˆametros para chamar mysql_execute();
assim como ligar buffer de registros (mysql_bind_result()) para buscar o
resultado com os dados utilizando mysql_fetch().
A estrutura MYSQL_BIND cont´em os membros listados aqui:
enum enum_field_types buffer_type [input]
O tipo do buffer. O valor type deve ser um dos seguintes:
MYSQL_TYPE_TINY
MYSQL_TYPE_SHORT
MYSQL_TYPE_LONG
MYSQL_TYPE_LONGLONG
MYSQL_TYPE_FLOAT
MYSQL_TYPE_DOUBLE
MYSQL_TYPE_TIME
MYSQL_TYPE_DATE
596 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MYSQL_TYPE_DATETIME
MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_STRING
MYSQL_TYPE_VAR_STRING
MYSQL_TYPE_TINY_BLOB
MYSQL_TYPE_MEDIUM_BLOB
MYSQL_TYPE_LONG_BLOB
MYSQL_TYPE_BLOB
void *buffer [input/output]
Um ponteiro para um buffer de dados de parˆametros no caso dele
ser utilizado para fornecer dados de parˆametros ou ponteiro para
um buffer no qual se deve retornar os dados quando a estrutura
para liga¸ao do resultado.
unsigned long buffer_length [input]
Tamanho do *buffer em bytes. Para caracteres e dados C bin´arios,
buffer length especifica o tamanho do *buffer a ser utilizado como
um dado de parˆametro no caso dele ser usado com mysql_bind_
param() ou para retornar v´arios bytes ao buscar o resultado quando
ele ´e usado com mysql_bind_result().
long *length [input/output]
Ponteiro para o buffer para o tamanho do parˆametro. Quando
a estrutura ´e usada como uma entrada para a liga¸ao dos da-
dos dos parˆametros, este argumento aponta para um buffer que,
quando mysql_execute() ´e chamado, contem o tamanho do valor
do parˆametro aramzenado em *buffer. Isto ´e ignorado exceto para
caracteres ou dados C bin´arios.
Se o tamanho ´e um ponteiro nulo, o protocolo assume que todos os
caracteres e dados bin´arios s˜ao terminaodos com null.
When this structure is used in output binding, then mysql_fetch()
return the the length of the data that is returned.
bool *is_null [input/output]
Indica se o dado do parˆametro ´e NULL ou o dado buscado ´e NULL.
MYSQL_TIME
Esta estrutura ´e utilizada para enviar e receber dados DATE, TIME e TIMES-
TAMP diretamente de/para o servidor.
A estrutura MYSQL_TIME cont´em os membros listados abaixo:
Membro Tipo Descri¸ao
year unsigned int Ano.
month unsigned int es.
day unsigned int Dia do mˆes.
hour unsigned int Hora do dia(TIME).
minute unsigned int Minutos.
Chapter 8: MySQL APIs 597
second unsigned int Segundos.
neg my bool Um parˆametro booleano para indicar se o tempo ´e negativo
second_part unsigned long Parte fracionada do segundo(ainda n˜ao usado)
8.1.6 Vis˜ao Geral das Fun¸oes de Instru¸oes Preparadas da API C
The functions available in the prepared statements are listed here and are described in
greater detail in the later section. See hundefinedi[C API Prepared statement functions],
page hundefinedi.
Fun¸ao Descri¸ao
mysql prepare() Prepara uma string SQL para execu¸ao.
mysql param count() Retorna o n´umero de parˆametros em uma instru¸ao SQL
preparada.
mysql prepare result() Retorna meta informa¸ao de instru¸oes preparadas em
forma de um conjunto de resultados.
mysql bind param() Liga um buffer para marcador de parˆametro em um in-
stru¸ao SQL preparada.
mysql execute() Executa a instru¸ao preparada.
mysql stmt affected rows() Retorna o n´umero de registros alter-
ados/deletados/inseridos pelo ´ultima consulta
UPDATE, DELETE, ou INSERT.
mysql bind result() Liga o buffers de dados da aplica¸ao em colunas no resultado
da consulta.
mysql stmt store result() Retorna o resultado completo para o cliente.
mysql stmt data seek() Busca um registro arbitr´ario no resultado de uma consulta.
mysql stmt row seek() Busca por um registro no resultado de uma busca, utilizando
o valor reotornado de mysql_stmt_row_tell().
mysql stmt row tell() Retorna a posi¸ao do cursor de registro.
mysql stmt num rows() Retorna o total de registros do resultado de uma instru¸ao
armazenada.
mysql fetch() Busca o pr´oximo conjunto de dados do resultado e retorna
os dados para todas as colunas limites.
mysql stmt close() Libera a mem´oria usada pela instru¸ao preparada.
mysql stmt errno() Retorna o n´umero de erro para a ´ultima instru¸ao execu-
tada.
mysql stmt error() Retorna a mensagem de erro para a ´ultima instru¸ao exe-
cutada.
598 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql send long data() Envia dados longos em blocos para o servidor.
Chama mysql_prepare() para preparar e iniciar o manipulador de instru¸oes, chama
mysql_bind_param() para fornecer os dados do parˆametro e chama mysql_execute() para
executar a consulta. Vocˆe pode repetir o mysql_execute() alterando o valor do parˆametro
do buffer respectivo fornecido por mysql_bind_param().
No caso do consulta ser uma instru¸ao SELECT ou qualquer outra consulta que retorne um
resultado, mysql prepare() tamb´em retornar´a a informa¸ao dos meta dados do resultado na
forma de um resultado MYSQL_RES atrav´es de mysql_prepare_result().
Voe pode forncer o buffer de resultado usando mysql_bind_result(), assim mysql_
fetch() retornar´a automaticamente os dados para este buffer. Esta busca ´e feita registro
a registro.
Voe tamb´em pode enviar o texto ou dado bin´ario em blocos para o servidor
utilizando mysql_send_long_data(), especficando a op¸ao is long data=1 ou
length=MYSQL LONG DATA ou -2 na estrutura MYSQL BIND fornecida com
mysql_bind_param().
Assim que a instru¸ao executada acabar, ela deve ser liberada usando mysql_stmt_close
para liberar todos os recursos alocados para o manipulador de instru¸ao.
Execution Steps:
Para prepara e executar uma instru¸ao, a aplica¸ao:
Chama mysql prepare() e passa uma string contendo uma instru¸ao SQL. Em um
preparo com sucesso, mysql prepare retorna o manipulador de instru¸c˜ao v´alido para a
aplica¸ao.
Se a consulta retorna um resultado, mysql prepare result retorna a informa¸ao de meta
dados do resultado.
Define o valor de qualquer parˆametro usando mysql bind param. Todos os parˆametros
devem ser definidos. Sen˜ao ser´a retornado um erro ou produzido um resultado inesper-
ado.
Chama mysql execute() para executar a instru¸ao.
Repete os passos 2 e 3 se necess´ario, alterando o valor do parˆametro e re-executando a
instru¸ao.
Liga o buffer de dados pata retornar o valor do registro, se for um resultado de uma
consulta; usando mysql bind result().
Busca os dados para o buffer registro a registro chamando mysql fetch() repetidas vezes
at´e n˜ao haver mais registros.
Quando mysql prepare() ´e chamado, no protocolo cliente/servidor do MySQL:
O servidor analiza a consulta e envia o status de ok de volta para o cliente
atribuindo uma identifica¸ao a instru¸ao. Ele tamb´em envia um n´umero total
de parˆametros, contagem de colunas e sua meta informa¸ao se for um resultado
orientado a consulta. Toda a sintaxe e semˆantica da consulta ´e verificada esta
chamada pelo servidor.
O clinte utiliza esta identifica¸ao da instru¸ao para as demais execu¸oes, assim o
servidor identifica a instru¸ao dentre outras existentes. Agora o cliente aloca um
manipulador de instru¸oes com esta identifica¸ao e a retorna para a aplica¸ao.
Chapter 8: MySQL APIs 599
Quando o mysql execute() ´e chamado, no protocolo cliente/servidor do MySQL:
O cliente utiliza o manipulador de instru¸c˜oes e envia o dado do parˆametro para o
servidor.
O servidor identifica a instru¸ao usando a identifica¸ao fornecida pelo cliente, e
substitui o marcador do parˆametro com o dado fornecido mais recente e executa
a consulta. Se ´e retornado um resultado, envia o dado de volta para o cliente,
sen˜ao envia o status de OK como n´umero total de registros alterados/deletados/
inseridos.
Quando mysql fetch() ´e chamado, no protocolo cliente/servidor do MySQL:
O cliente lˆe os dados do pacote registro por registro e o coloca no buffer de dados
da aplica¸ao fazendo as convers˜oes necess´arias. Se o o tipo do buffer de aplica¸ao
´e o mesmo do tipo do campo, as convers˜oes seguem em frente.
Voe pode obter o c´odigo e mensagem de erro da instru¸ao utilizando mysql_stmt_errno()
emysql_stmt_error() respectivamente.
8.1.7 Descri¸ao das Fun¸oes de Instru¸ao Preparada da API C
Voe precisa das seguintes fun¸oes quando quiser preparar e executar as consultas.
8.1.7.1 mysql_prepare()
MYSQL_STMT * mysql_prepare(MYSQL *mysql, const char *query, unsigned long
length)
Descri¸ao
Prepara a consulta SQL apontada pela string com termina¸ao em nulo ’query’. A consul-
tadeve consistir de uma ´unica instru¸ao SQL. Voe n˜ao deve adicionar ponto e virgula (‘;‘)
ou \g a instru¸ao.
A aplica¸ao pode incluir um ou mais marcadores de parˆametro na instru¸ao SQL. Para
incluir um marcador de parˆametro, a aplica¸ao embute uma exclama¸ao (?) na string SQL
na posi¸ao aprpriada.
Os marcadores s´o s˜ao v´alidos em certos lugares na instru¸ao SQL. Por exemplo, eles n˜ao
ao permitidos em lista select (a lista de colunas retornadas por uma instru¸c˜ao SELECT),
nem s˜ao permitidas como ambos operadores de oper¸ao bin´aria assim como o sinal de igual
(=), porque seria imposs´
ivel determinar o tipo do parˆametro. Em geral, parˆametros s˜ao
alidos somente em instru¸ao de Linguagem de Manipula¸ao de Dados (Data Manipula-
tion Languange-DML), e n˜ao em instru¸oes de Linguagem de Defini¸ao de Dados (Data
Defination Language-DDL).
Os marcadores de parˆametro limitam vari´aveis de aplica¸oes utilizando mysql_bind_
param().
Valor Retornado
MYSQL_STMT se o preparo obteve sucesso. NULL se ocorreu um erro.
600 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Falta de mem´oria
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Se o preparo n˜ao obteve sucesso, ex. quando mysql_prepare() retorna uma instru¸ao
NULL, os erros podem ser obtidos chamando mysql_error().
Exemplo
Para o uso de mysql_prepare() consulte o exemplo de hundefinedi[mysql execute],
page hundefinedi.
8.1.7.2 mysql_param_count()
unsigned int mysql_param_count(MYSQL_STMT *stmt)
Descri¸ao
Retorna o n´umero de marcadores de parˆametros presentes na consulta preparada.
Valor Retornado
Um unsigned integer (inteiro sem sinal) representando o n´umero de parˆametros em uma
instru¸ao.
Erros
Nenhum.
Exemplo
Para utilizar mysql_param_count() consulte o exemplo de hundefinedi[mysql execute],
page hundefinedi.
8.1.7.3 mysql_prepare_result()
MYSQL_RES *mysql_prepare_result(MYSQL_STMT *stmt)
Chapter 8: MySQL APIs 601
Descri¸ao
Se mysql_prepare() retornou um resultado de uma consulta, mysql_prepare_result() re-
torna o resultado dos meta dados na forma de uma estrutura MYSQL_RES; que tamb´em pode
ser usada para processar a meta informa¸ao como o n´umero total de campos e informa¸ao
de campos indiv´
iduais. O resultado retornado pode ser passado como um argumento para
qualquer um dos campos com base na API para processar informa¸ao do resultado dos meta
dados com:
mysql num fields()
mysql fetch field()
mysql fetch field direct()
mysql fetch fields()
mysql field count()
mysql field seek()
mysql field tell() and
mysql free result()
Valor Retornado
Uma estrutura de resultado MYSQL_RES. NULL se nenhuma meta informa¸ao existe na
consulta preparada.
Erros
CR_OUT_OF_MEMORY
Falta de mem´oria
CR_UNKNOWN_ERROR
Ocorreu um erro desconhecido
Exemplo
Para utilizar mysql_prepare_result() consulte o exemplo de hundefinedi[mysql fetch],
page hundefinedi
8.1.7.4 mysql_bind_param()
int mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)
Descri¸ao
mysql_bind_param ´e utilizado para ligar dados para os marcadores de parˆametros na in-
stru¸ao SQL com mysql_prepare. Ele utiliza a estrutura MYSQL BIND para fornecer os
dados.
Os tipos de buffers suportados s˜ao:
MYSQL TYPE TINY
602 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MYSQL TYPE SHORT
MYSQL TYPE LONG
MYSQL TYPE LONGLONG
MYSQL TYPE FLOAT
MYSQL TYPE DOUBLE
MYSQL TYPE TIME
MYSQL TYPE DATE
MYSQL TYPE DATETIME
MYSQL TYPE TIMESTAMP
MYSQL TYPE STRING
MYSQL TYPE VAR STRING
MYSQL TYPE TINY BLOB
MYSQL TYPE MEDIUM BLOB
MYSQL TYPE LONG BLOB
Valor Retornado
Zeros se a liga¸ao foi obtida com sucesso. Diferente de zero se ocorrer um erro.
Erros
CR_NO_PREPARE_STMT
ao existem instru¸oes preparadas
CR_NO_PARAMETERS_EXISTS
ao existem parˆametros para ligar
CR_INVALID_BUFFER_USE
Indica se a liga¸ao forncer´a dados longos em bolcos e se o tipo de buffer ´e bin´ario
ou n˜ao ´e uma string.
CR_UNSUPPORTED_PARAM_TYPE
A convers˜ao n˜ao ´e suportada, possivelmente o buffer type ´e inv´alido ou n˜ao ´e
um dos tipos suportados listados acima.
CR_OUT_OF_MEMOR
Falta de mem´oria
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Exemplo
Para utilizar mysql_bind_param() consulte o exemplo de hundefinedi[mysql execute],
page hundefinedi.
8.1.7.5 mysql_execute()
int mysql_execute(MYSQL_STMT *stmt.
Chapter 8: MySQL APIs 603
Descri¸ao
mysql_execute() executa a consulta preparada associada ao manipulador de instru¸oes.
O valor do marcador de parˆametros ser´a enviado para o servidor durante esta chamada,
assimque o servidor substituir marcadores com os novos dados fornecidos.
Se a instru¸ao ´e um UPDATE,DELETE,ou INSERT, o n´umero total de changed/
deletd/inserted pode ser encontrado chamando mysql_stmt_affected_rows. Se este ´e um
resultado de uma consulta, deve se chamar mysql_fetch() para buscar dados previamente
para fazer qualquer outra chamada que resulte em um processamento de consulta. Para
mais informa¸oes sobre como buscar dados ibin´arios, consulte hundefinedi[mysql fetch],
page hundefinedi.
Valor Retornado
mysql_execute() retorna os seguintes valores:
Valor de Retorno Descri¸ao
0 Sucesso
1 Erro ocorrido. odigo e mensagem de erro podem ser
obtidos chamando mysql_stmt_errno() emysql_stmt_
error().
Erros
CR_NO_PREPARE_QUERY
Nenhuma consulta preprada previamente para execu¸ao
CR_ALL_PARAMS_NOT_BOUND
ao forma fornecidos todos os dados de parˆametros.
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Falta de mem´oria
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Exemplo
O seguinte exemplo explica o uso de mysql_prepare,mysql_param_count,mysql_bind_
param,mysql_execute emysql_stmt_affected_rows().
MYSQL_BIND bind[3];
MYSQL_STMT *stmt;
604 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ulonglong affected_rows;
long length;
unsigned int param_count;
int int_data;
short small_data;
char str_data[50], query[255];
my_bool is_null;
/* Define o modo autocommit como true (verdadeiro) */
mysql_autocommit(mysql, 1);
if (mysql_query(mysql,"DROP TABLE IF EXISTS test_table"))
{
fprintf(stderr, "\n drop table failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
if (mysql_query(mysql,"CREATE TABLE test_table(col1 INT, col2 varchar(50), \
col3 smallint,\
col4 timestamp(14))"))
{
fprintf(stderr, "\n create table failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
/* Prepara uma consulta insert com 3 par^ametros */
strmov(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)");
if(!(stmt = mysql_prepare(mysql, query, strlen(query))))
{
fprintf(stderr, "\n prepare, insert failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
fprintf(stdout, "\n prepare, insert successful");
/* Obt´em a contagem de par^amwetros para a instru¸c~ao */
param_count= mysql_param_count(stmt);
fprintf(stdout, "\n total parameters in insert: %d", param_count);
if (param_count != 3) /* valida a contagem de par^ametros */
{
fprintf(stderr, "\n invalid parameter count returned by MySQL");
exit(0);
}
/* Liga os dados aos par^ametros */
/* PARTE INTEGER */
Chapter 8: MySQL APIs 605
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= 0;
bind[0].length= 0;
/* PARTE STRING */
bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= sizeof(str_data);
bind[1].is_null= 0;
bind[1].length= 0;
/* PARTE SMALLINT */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;
bind[2].is_null= &is_null;
bind[2].length= 0;
is_null= 0;
/* Liga os buffers */
if (mysql_bind_param(stmt, bind))
{
fprintf(stderr, "\n param bind failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Especifica os dados */
int_data= 10; /* integer */
strcpy(str_data,"MySQL"); /* string */
/* INSERE dados SMALLINT como NULL */
is_null= 1;
/* Executa a instru¸c~ao insert - 1*/
if (mysql_execute(stmt))
{
fprintf(stderr, "\n execute 1 failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
fprintf(stderr, "\n send a bug report to bugs@lists.mysql.com, by asking why this is not working ?");
exit(0);
}
/* Obtem o n´umeros total de registros afetados */
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, "\n total affected rows: %lld", affected_rows);
if (affected_rows != 1) /* valida linha afetadas */
606 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
{
fprintf(stderr, "\n invalid affected rows by MySQL");
exit(0);
}
/* Re-executa o insert, alterando os valores */
int_data= 1000;
strcpy(str_data,"The most popular open source database");
small_data= 1000; /* smallint */
is_null= 0; /* reset NULL */
/* Executa a instru¸c~ao insert - 2*/
if (mysql_execute(stmt))
{
fprintf(stderr, "\n execute 2 failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Obtem o n´umeros total de registros afetados */
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, "\n total affected rows: %lld", affected_rows);
if (affected_rows != 1) /* validate affected rows */
{
fprintf(stderr, "\n invalid affected rows by MySQL");
exit(0);
}
/* Fecha a instru¸c~ao */
if (mysql_stmt_close(stmt))
{
fprintf(stderr, "\n failed while closing the statement");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* APAGA A TABELA */
if (mysql_query(mysql,"DROP TABLE test_table"))
{
fprintf(stderr, "\n drop table failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
fprintf(stdout, "Success, MySQL prepared statements are working!!!");
8.1.7.6 mysql_stmt_affected_rows()
ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)
Chapter 8: MySQL APIs 607
Descri¸ao
Retorna o n´umero total de registros alterados pela ´ultima instru¸aoexecutada. Pode
ser chamada imediatamente depois de mysql execute() para UPDATE,DELETE,ou
instru¸oes INSERT. Para instru¸oes SELECT, mysql stmt affected rows funciona como
mysql num rows().
Valor Retornado
Um integer (inteiro) maior que zero indica o n´umero de registros afetados ou retornados.
Zero indica que nenhum registro foi atualizado em uma instru¸ao UPDATE, nenhum re-
gitro coincidiu com a cl´ausula WHERE na consulta ou que nenhuma consulta foi exeutada
ainda. -1 indica que a consulta retornou um erro ou que, para uma consulta SELECT,
mysql stmt affected rows() foi chamado antes de chamra mysql fetch().
Erros
Nenhum.
Exemplo
Para utilizar mysql_stmt_affected_rows() consulte o exemplo de hundefinedi
[mysql execute], page hundefinedi.
8.1.7.7 mysql_bind_result()
my_bool mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
Descri¸ao
mysql_bind_result() ´e usado para associar, ou ligar, colunas no resultados ao buffer de
dados e buffer de tamanho. Quando mysql_fetch() ´e chamado para buscar dados, o
protocolo clinete MySQL retorna os para as colunas limitiadas no buffer especificado.
Note que todas as colunas devem ser limitadas antes de chamar mysql_fetch() no caso
de buscar os dados para o buffers; sen˜ao mysql_fetch() simplesmente ignorado os dados
trazidos; os buffers devem se suficientes para guardar os dados j´a que o protocolo n˜ao retorna
dados em blocos.
Uma coluna pode ser limitada a qualquer hora, mesmo depois do dados ter sido buscado
do resultado. A nova liga¸ao tem efeito ba pr´oxima vez em que mysql_fetch() ´e chamado.
Por exemplo, suponha que uma aplica¸ao liga a coluna em um resultado e chama mysql_
fetch(). O protocolo MySQL retorna dados em buffers limitados. Agora suponha que a
aplica¸ao ligue a coluna a um diferente cojunto de buffers, enao o protocolo n˜ao coloca os
dados do registro recem buscados em um novo buffer limitado. Ele o faz que o pr´oximo
mysql_fetch() for chamado.
Para ligar uma coluna, uma aplica¸ao chama mysql_bind_result() e passa o tipo, o en-
dere¸co e o endere¸co do buffer do tamanho.
Os tipos de buffers suportados s˜ao:
608 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MYSQL TYPE TINY
MYSQL TYPE SHORT
MYSQL TYPE LONG
MYSQL TYPE LONGLONG
MYSQL TYPE FLOAT
MYSQL TYPE DOUBLE
MYSQL TYPE TIME
MYSQL TYPE DATE
MYSQL TYPE DATETIME
MYSQL TYPE TIMESTAMP
MYSQL TYPE STRING
MYSQL TYPE VAR STRING
MYSQL TYPE BLOB
MYSQL TYPE TINY BLOB
MYSQL TYPE MEDIUM BLOB
MYSQL TYPE LONG BLOB
Valor Retornado
Zero se a liga¸ao obteve sucesso. Diferente de zero se ocorreu um erro.
Erros
CR_NO_PREPARE_STMT
ao existe instru¸oes preparadas
CR_UNSUPPORTED_PARAM_TYPE
A convers˜ao n˜ao ´e suportada, possivelmente o buffer type ´e inv´alido ou n˜ao
nanlista dos tipos de buffers suportados
CR_OUT_OF_MEMOR
Falta de mem´oria
CR_UNKNOWN_ERROR
Ocorreu um erro desconhecido
Exemplo
Para utilizar mysql_bind_result() consulta o exemplo de hundefinedi[mysql fetch],
page hundefinedi
8.1.7.8 mysql_stmt_store_result()
int mysql_stmt_store_result(MYSQL_STMT *stmt)
Chapter 8: MySQL APIs 609
Descri¸ao
Voe deve chamar mysql_stmt_store_result() para cada query que retornar dados com
sucesso(SELECT,SHOW,DESCRIBE,EXPLAIN), e s´o se vocˆe quiser armazenar todo o resultado
no buffer no cliente, assim que a chamada mysql_fetch() subsequente retornar os dados
em buffers.
Voe n˜ao precisa chamar mysql_stmt_store_result() para outras consultas, mas n˜ao
causar´a nenhum dano ou queda de performance em todo caso. Voe pode detectar se a
consulta n˜ao gera um resultado verificado se mysql_prepare_result() retorna 0. Para
mais informa¸oes consulte hundefinedi[mysql prepare result], page hundefinedi.
Valor Retornado
Zero se o resultado foi armazenado em buffer com sucesso ou Diferente de zero em caso
de erro.
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Falta de memoria.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
8.1.7.9 mysql_stmt_data_seek()
void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset)
Descri¸ao
Busca um registro arbitr´ario no resultado de uma instru¸ao. Isto exige que a estrutura
do resultado da instru¸ao contenha todo o resultado da ´ultima consulta executada, assim
mysql_stmt_data_seek() pode ser usada em conjunto apenas com mysql_stmt_store_
result().
O offset deve ser um valor na faixa de 0 a mysql_stmt_num_rows(stmt)-1.
Valor Retornado
Nenhum.
610 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Erros
Nenhum.
8.1.7.10 mysql_stmt_row_seek()
MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET
offset)
Descri¸ao
Define o cursor de linha com um registro arbitr´ario em um resultado de instru¸ao. Isto
exige que a estrutura do resultado contenha todo o resultado da consulta, assim mysql_
stmt_row_seek() pode ser usado em conjunto apenas com mysql_stmt_store_result().
O offset deve ser um valor retornado de uma chamada a mysql_stmt_row_tell() ou a
mysql_stmt_row_seek(). Este valor n˜ao ´e simplesmente um n´umerod de linha; se vocˆe
quiser buscar um registro em um resultado usando um n´umero de linha utilize mysql_
stmt_data_seek().
Valor Retornado
O valor anterior do cursor de linha. Este valor pode ser passado a uma chamada subsequente
de mysql_stmt_row_seek().
Erros
Nenhum.
8.1.7.11 mysql_stmt_row_tell()
MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt)
Descri¸ao
Retorna a posi¸ao corrente do cursor de linha para o ´ultimo mysql_fetch(). Este valor
pode ser usado como um argumento para mysql_stmt_row_seek().
Voe deve usar mysql_stmt_row_tell() somente depois de mysql_stmt_store_result().
Valor Retornado
O offset atual do cursor de linha.
Erros
Nenhum.
8.1.7.12 mysql_stmt_num_rows()
my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt)
Chapter 8: MySQL APIs 611
Descri¸ao
Rertorna o n´umero de registros no resultado.
O uso de mysql_stmt_num_rows() depende de se vocˆe utilizou mysql_stmt_store_
result() para armazenar todo o resultado no manipulador de instru¸oes ou
ao.
Se vocˆe utilizou mysql_stmt_store_result(),mysql_stmt_num_rows() pode ser chamado
imediatamente.
Valor Retornado
O n´umero de linhas no resultado.
Erros
Nenhum.
8.1.7.13 mysql_fetch()
int mysql_fetch(MYSQL_STMT *stmt)
Descri¸ao
mysql_fetch() retorna o pr´oximo conjunto de registros no resultado. Ele pode ser chamado
apenas enquanto existir o conjunto de resultados. Per exemplo, depois de uma chamada de
mysql_execute() que cria o resultado ou depois de mysql_stmt_store_result(), que ´e
chamado depois de mysql_execute() para armazenar todo o resultado.
Se buffers de linhas s˜ao limitados usando mysql_bind_result(), ele retorna os dados neste
buffer para todas as colunas no registro atual e os tamanhos s˜ao retornados para o apontador
do tamanho.
Note que, todas as colunas devem ser limitadas pela aplica¸ao.
Se o dado buscado ´e um dado NULL, enao o valor is_null de MYSQL_BIND cont´em TRUE
(VERDASDEIRO), 1, sen˜ao o dado e seu tamanho ´e retornado para as vari´aveis *buffer
e*length baseada no tipo de buffer especificado pela aplica¸ao, Todos os tipos num´ericos,
float e double tem o tamanho fixo (em bytes) como mostrado abaixo:
Tipo Tamanho
MYSQL TYPE TINY 1
MYSQL TYPE SHORT 2
MYSQL TYPE LONG 4
MYSQL TYPE FLOAT 4
MYSQL TYPE LONGLONG 8
MYSQL TYPE DOUBLE 8
MYSQL TYPE TIME sizeof(MYSQL TIME)
MYSQL TYPE DATE sizeof(MYSQL TIME)
MYSQL TYPE DATETIME sizeof(MYSQL TIME)
MYSQL TYPE TIMESTAMP sizeof(MYSQL TIME)
MYSQL TYPE STRING tam dados
612 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MYSQL TYPE VAR STRING tam dados
MYSQL TYPE BLOB tam dados
MYSQL TYPE TINY BLOB tam dados
MYSQL TYPE MEDIUM BLOB tam dados
MYSQL TYPE LONG BLOB tam dados
onde *tam_dados ao ´e nada mais que ’Tamanho atual do dado’.
Valor Retornado
Valor retornado Descri¸ao
0 Sucesso, o dado foi buscado para o buffers de dados da
aplica¸ao.
1 Ocorreu um erro. O c´odigo e a mensagem de erro podem
ser obtidos chamando mysql_stmt_errno() emysql_
stmt_error().
100, MYSQL NO DATA ao existem mais registros/dados
Erros
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Falta de memoria.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_SERVER_LOST
A conex˜ao ao servidor MySQL foi perdida durante a consulta.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
CR_UNSUPPORTED_PARAM_TYPE
Se o tipo de buffer ´e MYSQL TYPE DATE,DATETIME,TIME,ou TIMES-
TAMP; e se o tipo de dado n˜ao ´e DATE, TIME, DATETIME ou TIMESTAMP.
Todos os outros erros de convers˜ao n˜ao suportada s˜ao retornados de mysql_
bind_result().
Exemplo
O seguinte exemplo explica o uso de mysql_prepare_result,mysql_bind_result(), e
mysql_fetch()
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
MYSQL_RES *result;
int int_data;
Chapter 8: MySQL APIs 613
long int_length, str_length;
char str_data[50];
my_bool is_null[2];
query= "SELECT col1, col2 FROM test_table WHERE col1= 10)");
if (!(stmt= mysql_prepare(mysql, query, strlen(query)))
{
fprintf(stderr, "\n prepare failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
/* Obt´em meta informa¸c~ao dos campos */
if (!(result= mysql_prepare_result(stmt)))
{
fprintf(stderr, "\n prepare_result failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
fprintf(stdout, "Total fields: %ld", mysql_num_fields(result));
if (mysql_num_fields(result) != 2)
{
fprintf(stderr, "\n prepare returned invalid field count");
exit(0);
}
/* Executa a consulta SELECT */
if (mysql_execute(stmt))
{
fprintf(stderr, "\n execute failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Liga o buffer de dados do resultado */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= &is_null[0];
bind[0].length= &int_length;
bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
bind[1].buffer= (void *)str_data;
bind[1].buffer_length= 20;
bind[1].is_null= &is_null[1];
bind[1].length= &str_length;
if (mysql_bind_result(stmt, bind))
614 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
{
fprintf(stderr, "\n bind_result failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Agora busca os dados para o buffer*/
if (mysql_fetch(stmt))
{
fprintf(stderr, "\n fetch failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
if (is_null[0])
fprintf(stdout, "\n Col1 data is NULL");
else
fprintf(stdout, "\n Col1: %d, length: %ld", int_data, int_length);
if (is_null[1])
fprintf(stdout, "\n Col2 data is NULL");
else
fprintf(stdout, "\n Col2: %s, length: %ld", str_data, str_length);
/* chama mysql_fetch de novo */
if (mysql_fetch(stmt) |= MYSQL_NO_DATA)
{
fprintf(stderr, "\n fetch return more than one row);
exit(0);
}
/* Libera a meta informa¸c~ao do resultado preparado */
mysql_free_result(result);
/* Libera o manipulador de instru¸c~ao */
if (mysql_stmt_free(stmt))
{
fprintf(stderr, "\n failed to free the statement handle);
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
8.1.7.14 mysql_send_long_data()
int mysql_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number,
const char *data, ulong length)
Chapter 8: MySQL APIs 615
Descri¸ao
Permite que um aplica¸ao envie os dados em blocos para o servidor. Esta fun¸ao pode ser
usada para enviar valores de dados bin´arios e caracteres em partes para uma coluna (deve
ser text ou blob) com um tipo de dado bin´ario ou de caracter.
data ´e um ponterio para o buffer contendo os dados atauis para o parˆametro represntado
por parameter_number.length indica a quantidade de dados a ser enviado em bytes.
Valor Retornado
Zero se os dados s˜ao enviados com sucesso para o servidir. Diferente de zero se ocorrer um
erro.
Erros
CR_INVALID_PARAMETER_NO
N´umero de parˆametro inalido
CR_COMMANDS_OUT_OF_SYNC
Os comando foram executados em uma ordem inpropriada.
CR_OUT_OF_MEMORY
Falta de memoria.
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_UNKNOWN_ERROR
Um erro desconhecido ocorreu.
Example
O exemplo seguinte explica como enviar os dados em blocos para um coluna do tipo text:
MYSQL_BIND bind[1];
long length;
query= "INSERT INTO test_long_data(text_column) VALUES(?)");
if (!mysql_prepare(mysql, query, strlen(query))
{
fprintf(stderr, "\n prepare failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
}
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].length= &length;
bind[0].is_null= 0;
/* Liga os buffers */
616 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
if (mysql_bind_param(stmt, bind))
{
fprintf(stderr, "\n param bind failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Envia os dados em blocos para o servidor */
if (!mysql_send_long_data(stmt,1,"MySQL",5))
{
fprintf(stderr, "\n send_long_data failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Envia o pr´oximo peda¸co de dados */
if (mysql_send_long_data(stmt,1," - The most popular open source database",40))
{
fprintf(stderr, "\n send_long_data failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
/* Agora executa a consulta */
if (mysql_execute(stmt))
{
fprintf(stderr, "\n mysql_execute failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
}
This inserts the data, "MySQL - The most popular open source database"
to the field ’text_column’.
8.1.7.15 mysql_stmt_close()
my_bool mysql_stmt_close(MYSQL_STMT *)
Descri¸ao
Fecha a instru¸ao preparada. mysql_stmt_close() tamb´em desaloca o manipulador de
instru¸oes apontado por stmt.
Se os resultados do consulta atual est˜ao pendentes ou n˜ao foram lidos; o resultado da
consulta ´e cancelado para que a pr´oxima chamada possa ser executada.
Valor Retornado
Zero se a instru¸ao for libera com sucesso. Diferente de zero se ocorrer um erro.
Chapter 8: MySQL APIs 617
Erros
CR_SERVER_GONE_ERROR
O servidor MySQL foi finalizado.
CR_UNKNOWN_ERROR
Ocorreu um erro desconhecido.
Exemplo
Para utilizar mysql_stmt_close() consulte o exemplo de hundefinedi[mysql execute],
page hundefinedi.
8.1.7.16 mysql_stmt_errno()
unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)
Descri¸ao
Para a instru¸ao especificada por stmt,mysql_stmt_errno() retorna o c´odigo de erro para
a fun¸ao de instru¸oes da API chamada mais recentemente. Um valor de retorno de zero
significa que n˜ao ocorreu nenhum erro. N´umeros de mensagens de erro do cliente est˜ao
listadas no arquivo cabclho errmsg.h do MySQL. lient error message numbers are listed in
the MySQL errmsg.h header file. N´umeros de mensagens de erro do servidor est˜ao listado
no arquivo mysqld error.h. Na distribui¸c˜ao fonte do MySQL vocˆe pode encontra uma lista
completa com mensagem de erros e n´umeros de erros no arquivo Docs/mysqld error.txt
Valor Retornado
Um valor de c´odigo de erro. Zero se n˜ao ocorreu erro.
Erros
Nenhum
8.1.7.17 mysql_stmt_error()
char *mysql_stmt_error(MYSQL_STMT *stmt)
Descri¸ao
Para a instru¸ao especificada por stmt,mysql_stmt_error() retorna a mensagem de erro
para a fun¸ao de instru¸ao da API chamada mais recentemente. Um string vazia ("")
´e retornado se n˜ao ocorreu nenhum erro. Isto significa que os seguintes comandos s˜ao
equivalentes:
if (mysql_stmt_errno(stmt))
{
// an error occured
618 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
}
if (mysql_stmt_error(stmt))
{
// an error occured
}
A linguagem da mensagem de erro do cliente pode ser alterada recompilando a biblioteca
cliente do MySQL. Atualmente vocˆe pode escolher mensagem de erros em diversas lingua-
gens.
Valor Retornado
Um string contendo a descri¸ao do erro. Uma string vazia se n˜ao ocorrer erros.
Erros
Nenhum
8.1.8 Manipulando a execu¸ao de m´ultiplas consultas na API C
A partir da vers˜ao 4.1, o MySQL suporta a execu¸ao de multi consultas em um ´unico
comando. Para utiliz´a-lo, vocˆe deve definir o parˆametro do cliente CLIENT_MULTI_QUERIES
ao abrir a conex˜ao.
Por padr˜ao mysql_query() ou mysql_real_query() retornam apenas o status da primeira
consulta e o status das consultas subsequentes podem ser processados usadno mysql_more_
results() emysql_next_result().
/* Conecta ao servidor com a op¸c~ao CLIENT_MULTI_QUERIES */
mysql_real_query(..., CLIENT_MULTI_QUERIES);
/* Executa m´ultiplas consultas */
mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
CREATE TABLE test_table(id INT);\
INSERT INTO test_table VALUES(10);\
UPDATE test_table SET id=20 WHERE id=10;\
SELECT * FROM test_table;\
DROP TABLE test_table";
while (mysql_more_results(mysql))
{
/* Processa todos os resultados */
mysql_next_result(mysql);
...
printf("total affected rows: %lld", mysql_affected_rows(mysql));
...
if ((result= mysql_store_result(mysql))
{
/* Returna um resultado e o porcessa */
}
Chapter 8: MySQL APIs 619
}
8.1.9 Manipulando DATE, TIME e TIMESTAMP na API C
Utilizando o novo protocolo bin´ario do MySQL 4.1 e acima, pode se enviar e receber dados
DATE, TIME e TIMESTAMP utilizando a estrutura MYSQL_TIME.
A estrutura MYSQL_TIME consite dos seguintes membros:
year
month
day
hour
minute
second
second part
Para enviar dados, deve se usar as instru¸oes preparadas com mysql_prepare() emysql_
execute(); e deve se ligar os parˆametros usando tipos como MYSQL_TYPE_DATE para proces-
sar valores de data (date), MYSQL_TYPE_TIME para hora (time) e MYSQL_TYPE_DATETIME ou
MYSQL_TYPE_TIMESTAMP para datetime/timestamp usando mysql_bind_param() ao enviar
emysql_bind_results() enquanto recebe os dados.
Aqui est´a um exemplo simples; que insere dados DATE, TIME e TIMESTAMP.
MYSQL_TIME ts;
MYSQL_BIND bind[3];
MYSQL_STMT *stmt;
strmov(query, "INSERT INTO test_table(date_field, time_field,
timestamp_field) VALUES(?,?,?");
stmt= mysql_prepare(mysql, query, strlen(query)));
/* define a entrada do buffer com 3 par^ametros */
bind[0].buffer_type= MYSQL_TYPE_DATE;
bind[0].buffer= (char *)&ts;
bind[0].is_null= 0;
bind[0].length= 0;
..
bind[1]= bind[2]= bind[0];
..
mysql_bind_param(stmt, bind);
/* fornece os dados a serme enviados na estrutura ts */
ts.year= 2002;
ts.month= 02;
ts.day= 03;
620 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ts.hour= 10;
ts.minute= 45;
ts.second= 20;
mysql_execute(stmt);
..
8.1.10 Descri¸ao das Fun¸oes de Threaded da API C
Voe precisa utilizar as seguintes fun¸oes quando quiser criar um cliente em uma thread.
See hundefinedi[Clientes em threads], page hundefinedi.
8.1.10.1 my_init()
void my_init(void)
Descri¸ao
Esta fun¸ao precisa ser chamada uma vez pelo programa antes de se chamar qualquer
fun¸ao do MySQL. Ela inicializa algumas var´aveis globais que o MySQL precisa. se vocˆe
est´a usando uma biblioteca cliente de thread segura, tamb´em ser´a feita uma chamada a
mysql_thread_init() para esta thread.
Ela ´e chamada automaticamente por mysql_init(),mysql_server_init() e
mysql_connect().
Valor Retornado
Nenhum
8.1.10.2 mysql_thread_init()
my_bool mysql_thread_init(void)
Descri¸ao
Esta fun¸ao preisa aser chamada para cada thread criada para inicializar vari´aveis espec´
ificas
de threads.
Ela ´e automaticamente chamada por my_init() emysql_connect().
Valor Retornado
Nenhum.
8.1.10.3 mysql_thread_end()
void mysql_thread_end(void)
Chapter 8: MySQL APIs 621
Descri¸ao
Esta fun¸ao precisa ser chamada antes da chamada de pthread_exit() para liberar a
mem´oria alocada por mysql_thread_init().
Note que a fun¸ao ao ´e chamada automaticamente pela biblioteca cliente. Deve ser
chamada explicitamente para evitar perda de mem´oria.
Valor Retornado
Nenhum.
8.1.10.4 mysql_thread_safe()
unsigned int mysql_thread_safe(void)
Descri¸ao
Esta fun¸ao indica se o cliente ´e compilado como uma thread segura.
Valor Retornado
1 se o cliente possui thread segura, 0 em outro caso.
8.1.11 Descri¸ao de Fun¸oes do Servidor Embutido da API C
Voe deve utilizar as seguints fun¸oes se vocˆe quiser permitir que a sua aplica¸ao seja ligada
a biblicoteca de servidor MySQL embutido. See hundefinedi[libmysqld], page hundefinedi.
Se o programa ´e ligado com -lmysqlclient em vez de -lmysqld, estas fun¸oes n˜ao far˜ao
nada. Isto torna poss´
ivel escolher entre usar o servidor MySQL embutido e um servidor
stand-alone sem modificar nenhum c´odigo.
8.1.11.1 mysql_server_init()
int mysql_server_init(int argc, char **argv, char **groups)
Descri¸ao
Esta fun¸ao deve ser chamada uma vez no program usando o servidor embutido aantes
de se chamar qualquer iutra fun¸ao do MySQL. Ela inicia o servidor e inicializa qualquer
subsistema (mysys, InnoDB, etc.) que o servidor utilize. Se esta fun¸ao n˜ao for chamada, o
programa ir´a falhar. Se vocˆe estiver usando o pacote DBUG que vem com o MySQL, vocˆe
deve chamar esta fun¸ao depois de ter chamado MY_INIT().
Os argumentos argc eargv ao an´alogos ao argumentos para o main(). O primeiro elemento
de argv ´e ignorado (ele cont´em normalmente, o nome do programa). por conveniˆencia, argc
pode ser 0(zero) se n˜ao houver argumentos de linha de comando para o servidor. mysql_
server_init() faz uma copia dos argumentos, assim ´e seguro destruir argv ou groups
depois da chamada.
A lista de strings terminadas em NULL em groups seleciona qual grupo no arquivo de op¸oes
ser´a ativado. See hundefinedi[Arquivos de op¸oes], page hundefinedi. Por conveniˆencia,
groups deve ser NULL, caso no qual os grupos [server] d[emedded] estar˜ao ativos.
622 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Exemplo
#include <mysql.h>
#include <stdlib.h>
static char *server_args[] = {
"this_program", /* this string is not used */
"--datadir=.",
"--key_buffer_size=32M"
};
static char *server_groups[] = {
"embedded",
"server",
"this_program_SERVER",
(char *)NULL
};
int main(void) {
mysql_server_init(sizeof(server_args) / sizeof(char *),
server_args, server_groups);
/* Use any MySQL API functions here */
mysql_server_end();
return EXIT_SUCCESS;
}
Valor Retornado
0 se okay, 1 se ocorrer um erro.
8.1.11.2 mysql_server_end()
void mysql_server_end(void)
Descri¸ao
Esta fun¸ao deve ser chamada no programa depois de todas outra fun¸oes MySQL. Ela
finaliza o srvidor embutido.
Valor Retornado
Nenhum.
8.1.12 Quest˜oes e problemas comuns ao utilzar a API C
Chapter 8: MySQL APIs 623
8.1.12.1 Porque Algumas Vezes mysql_store_result() Retorna
NULL Ap´os mysql_query() Returnar com Sucesso?
´
E poss´
ivel para mysql_store_result() retornar NULL seguida de uma chamda com sucesso
ao mysql_query(). Quando isto acontece, significa que uma da seguintes condi¸oes ocorreu:
Existe um falha no malloc() (por exemplo, se o resultado for muito grande).
Os dados n˜ao podem ser lidos (ocorreu um erro na conex˜ao).
A consulta n˜ao retornou dados (por exemplo, ela era um INSERT,UPDATE, ou DELETE).
Voe sempre pode verificar se a instru¸ao devia produzir um resultado n˜ao vazio chamando
mysql_field_count(). Se mysql_field_count() retornar zero, o resultado est´a vazio e a
´ultima consulta era uma instru¸ao que n˜ao devia retorbar valor (por exemplo, um INSERT ou
um DELETE). Se mysql_field_count() retorna um valor diferente se zero, a instru¸ao devia
ter produzido um resultado n˜ao vazio. Veja a descri¸ao da fun¸ao mysql_field_count()
para um exemplo.
Voe pode testar um erro chamando mysql_error() ou mysql_errno().
8.1.12.2 Que Resusltados Posso Onbetr de uma Consulta?
Sobre o resultado restornado de uma consulta, vocˆe pode obter as seguintes informa¸aoes:
mysql_affected_rows() retorna o n´umero de registros afetados pela ´ultima consulta
ao se fazer uma INSERT,UPDATE, ou DELETE. Uma exce¸ao ´e que se for utilizado DELETE
sem uma cl´ausula WHERE, a tabela ´e recriada vazia, o que ´e mais r´apido! Neste caso,
mysql_affected_rows() retorna zero para o n´umero de registros afetados.
mysql_num_rows() retorna o n´umero de registros em um resultado. Com
mysql_store_result(),mysql_num_rows() pode ser chamado assim que mysql_
store_result() retornar. Com mysql_use_result(),mysql_num_rows() o pode
ser chamado depois de ter buscado todos os registros com mysql_fetch_row().
mysql_insert_id() retorna o ID gerado pela ´ultima consulta que inseriu um registro
em uma tabela com ´
indice AUTO_INCREMENT. See hundefinedi[mysql_insert_id()],
page hundefinedi.
Algumas consultas (LOAD DATA INFILE ...,INSERT INTO ... SELECT ...,UPDATE) re-
tornam informa¸oes adcionais. O resultado ´e retornado por mysql_info(). Veja a
descri¸ao de mysql_info() para o formato da string que ela returnou. mysql_info()
retorna um ponteiro NULL se n˜ao houver informa¸oes adicionais.
8.1.12.3 Como Posso Obter a ID ´
Unica para a ´
Ultima Linha
Inserida?
Se vocˆe inserir um registro em uma tabela contendo uma coluna que tiver o atributo AUTO_
INCREMENT, vocˆe pode obter o ID gerado mais recentemente chamando a fun¸ao mysql_
insert_id().
Voe tamb´em pode recuperar o ID utilizando a fun¸ao LAST_INSERT_ID() em uma string
de consulta que foi passada a mysql_query().
Voe pode verificar se um ´
indice AUTO_INCREMENT ´e usado executando o seguinte c´odigo.
Ele tamb´em verifica se a consulta era um INSERT com um ´
indice AUTO_INCREMENT:
624 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
if (mysql_error(&mysql)[0] == 0 &&
mysql_num_fields(result) == 0 &&
mysql_insert_id(&mysql) != 0)
{
used_id = mysql_insert_id(&mysql);
}
O ID gerado mais recentemente ´e mantido no servidor em uma base por conex˜ao. Ele n˜ao
ser´a alterado por outro cliente. Ele n˜ao ser´a alterado mesmo se vocˆe atualizar outra coluna
AUTO_INCREMENT com um valor n˜ao m´agico (isto ´e, um valor que n˜ao ´e NULL e nem 0).
Se vocˆe quiser utilizar o ID que foi gerado por uma tabela e inserido em uma segunda tabela,
vocˆe ode utilizar instru¸c˜oes SQL como esta:
INSERT INTO foo (auto,text)
VALUES(NULL,’text’); # gera ID inserindo NULL
INSERT INTO foo2 (id,text)
VALUES(LAST_INSERT_ID(),’text’); # usa ID na segunda tabela
8.1.12.4 Problemas com Liga¸ao na API C
Ar ligar com a API C, os segintes error podem ocorrem em alguns sistemas:
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -
lnsl
Undefined first referenced
symbol in file
floor /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client
Se isto acontecer em seu sistema, vocˆe deve incluir a biblioteca math adiconando -lm ao
fim da linha de compila¸ao/liga¸ao.
8.1.13 Construindo Programas Clientes
Se vocˆe compilar clientes MySQL escritos por vocˆe mesmo ou obtido de terceiros, else
devem ser ligados utilizando a op¸ao -lmysqlclient -lz no comando de liga¸ao. Voe
tamb´em pode prcisar de especificar uma op¸ao -L para dizer ao ligado onde encntrar a
biblioteca. Por exemplo, se a biblioteca ´e instalada em ‘/usr/local/mysql/lib’, use -
L/usr/local/mysql/lib -lmysqlclient -lz no comando de liga¸ao.
Para clientes que utilizam arquivos de cabcalho do MySQL, pode ser necess´ario especificar a
op¸ao -I ao compil´a-los, (por exemplo, -I/usr/local/mysql/include), assim o compilador
pode encontrar o arquivo de cabe¸calho.
Para o mostrado acima de forma simples no Unix, fornecemos o script mysql_config para
vocˆe. See hundefinedi[mysql config], page hundefinedi.
Voe pode utiliz´a-lo para compila o cliente MySQL como a seguir:
CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname ‘$CFG --cflags‘ progname.c ‘$CFG --libs‘"
sh -c ´e necess´ario para fazer com que a sheel n˜ao trate a sa´
ida de mysql_config como uma
palavra.
Chapter 8: MySQL APIs 625
8.1.14 Como Fazer um Cliente em Threads
A biblioteca cliente ´e quase segura com threads. O maior problema ´e que a subrotinas em
net.c’ que leem dos sockets n˜ao s˜ao seguras a interrup¸oes. Isto foi feito pesando que vocˆe
pudesse desejar ter o seu pr´oprio alarme que possa quebrar uma longa leitura no servidor.
Se vocˆe instalar manipuladores de interrup¸ao para a interrup¸c˜ao SIGPIPE, o manipulador
socket deve ser segura com threads.
Nos bin´arios antigos que distribu´
imos em nosso web site (http://www.mysql.com/), as
bibliotecas clientes n˜ao est˜ao normalmente compiladas com a op¸ao de seguran¸ca com thread
(os bin´arios s˜ao complados com seguran¸ca com thread por padr˜ao). Distribui¸oes bin´arias
mais novas devem ter uma biblioteca normal e uma segura com threads.
Para termos um cliente em threads onde vocˆe pode interromper o cliente a partir de out-
ras threads a definir tempo limites ao falar com o servidor MySQL, vocˆe deve utilizar as
bibliotecas -lmysys,-lmystrings, e -ldbug e o c´odigo net_serv.o que o servidor utiliza.
Se vocˆe n˜ao precisar de insterrup¸oes ou de tempos limites, vocˆe pode apenas compilar um
biblioteca cliente (mysqlclient_r) segura com threads e utiliz´a-las. See hundefinedi[API
C MySQL], page hundefinedi. Neste caso vocˆe n˜ao precisa se preocupar com o arquivo
objeto net_serv.o ou outras bibliotecas MySQL.
Quando usar um cliente em thread e vocˆe quiser utilizar tempos limite e interrup¸oes, vocˆe
pode ter um grande uso das rotinas no arquivo ‘thr_alarm.c’. Se vocˆe estiver utilizando
rotinas da biblioteca mysys, a ´unica coisa que voe deve lembrar ´e de chamar primeiro
my_init()! See hundefinedi[Fun¸oes Threads do C], page hundefinedi.
Todas as fun¸oes com excess˜ao de mysql_real_connect() ao seguras com thread por
padr˜ao. As anota¸oes seguintes descrevem como compilar uma biblioteca cliente segura com
thread e utiliz´a-la de maneira segura. (As anota¸oes abaixo para mysql_real_connect() na
verdade se aplicam tamb´em a mysql_connect(), mas como mysql_connect() est´a obsoleto,
vocˆe deve utilizar mysql_real_connect().)
Para tornar mysql_real_connect() seguro com thread, vocˆe deve recompilar a biblioteca
cliente com este comando:
shell> ./configure --enable-thread-safe-client
Isto ir´a criar uma biblioteca cliente libmysqlclient_r. (Assumindo que o seu SO tenha a
fun¸ao gethostbyname_r() segura com thread). Esta biblioteca ´e segura com thread por
conex˜ao. Voe pode deixar duas threads compartilharem a mesma conex˜ao com os seguintes
cuidados:
Duas threads n˜ao podem enviar uma consaulta ao servidor MySQl ao mesmo tempo
na mesma conex˜ao. Em particular, vocˆe deve assegurar que entre um mysql_query()
emysql_store_result() nenhuma outra thread est´a usadno a mesma conex˜ao.
arias threads podem acess´ar resultados diferentes que s˜ao recuperados com mysql_
store_result().
Se vocˆe utilizar mysql_use_result, vocˆe ter´a que assegurar que nenhuma outra thread
est´a usando a mesma conex˜ao at´e que o resultado seja fechado. No entanto, ´e melhor
para clientes em threads que compartilham a mesma conex˜ao utilizar mysql_store_
result().
Se vocˆe quiser utilizar m´ultiplas threads na mesma conex˜ao, vocˆe deve ter uma trava
mutex na combina¸ao das chamadas mysql_query() emysql_store_result(). Uma
626 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
vez que mysql_store_result() esteja pronto, a trva pode ser liberada e outras threads
podem utilizar a mesma conex˜ao.
Se vocˆe programa com threads POSIX, vocˆe pode utilizar pthread_mutex_lock() e
pthread_mutex_unlock() para estabelecer e liberar uma trava mutex.
Voe precisa saber o seguinte se vocˆe tiver uma thread que estiver chamando fun¸oes MySQL
que n˜ao criaram a conex˜ao ao banco de dados MySQL:
Quando vocˆe chamar mysql_init() ou mysql_connect(), MySQL ir´a criar um vari´avel
especica da thread para a thread que ´e utilizada pela bibklioteca de depura¸ao (entre outra
coisas).
Se vocˆe chamar uma fun¸ao MySQL, antes da thread chamar mysql_init() ou mysql_
connect(), a thread n˜ao ter´a as vari´aveis espec´
ificas de thread necess´arias alocadas e vocˆe
acabar´a finalizando com uma descarga de mem´oria mais cedo ou mais tarde.
Para fazer que as coisas funcionem suavemente vocˆe tem que fazer o seguinte:
1. Chama my_init() no in´
icio do seu programa se for chamar qualquer outra fun¸ao
MySQL antes de chamar mysql_real_connect().
2. Chame mysql_thread_init() no manipulador de thread antes de chamar qualquer
outra fun¸ao MySQL.
3. Na thread, chame mysql_thread_end() antes de chamar pthread_exit(). Isto ir´a
liberar a mem´oria usada pelas vari´aveis espec´
ificas da thread do MySQL.
Voe pode obter alguns erros devido a s´
imbolos indefinidos ao ligar seu cliente com
libmysqlclient_r. Na maioria dos casos isto ocorre por n˜ao estar inclu´
ida a biblioteca
de threads na linha de liga¸ao/compila¸ao.
8.1.15 libmysqld, a Biblioteca do Servidor Embutido MySQL
8.1.15.1 Vis˜ao Geral da Biblioteca do Servidor MySQL Embutido
A biblioteca do servidor MySQL embutido torna poss´
ivel executar um servidor MySQL
com todos os recursos destro da aplica¸ao cliente. Os principais benef´
icios s˜ao o aumento
de velocidade e o gerenciamento mais simples de aplica¸oes embutidas.
A API ´e idˆentica para a vers˜ao embutida do MySQL e a vers˜ao cliente/servidor. Para alterar
uma aplica¸ao em thread antiga para utilizar a biblioteca embutida, vocˆe normalmente s´o
precisa adicionar chamadas as seguintes fun¸oes:
Fun¸ao Quando chamar
mysql_server_
init()
Deve ser chamada antes de qualquer outra fun¸ao MySQL, de
preferˆencia no inicio da fun¸ao main().
mysql_server_end() Deve ser chamada antes da sa´
ida do programa.
mysql_thread_
init()
Deve ser chamada em cada thread que vocˆe criar que acessar´a
o MySQL.
mysql_thread_end() Deve ser chamada antes de se chamar pthread_exit()
Voe deve ligar seu c´odigo com ‘libmysqld.a’ em vez de ‘libmysqlclient.a’.
As fun¸oes acima mysql_server_xxx tamb´em est˜ao inclu´
idas em ‘libmysqlclient.a’ para
permitir a troca entre a vers˜ao embutida e a clienete/servidor apenas ligando sua aplica¸ao
na biblioteca certa. See hundefinedi[mysql server init], page hundefinedi.
Chapter 8: MySQL APIs 627
8.1.15.2 Compilando Programas com libmysqld
Para obter uma biblioteca libmysqld vocˆe deve configurar o MySQL com a op¸ao --with-
embedded-server.
Quando voc6e liga o seu programa com libmysqld, vocˆe tamb´em deve incluir a biblioteca
espec´
ifica do sistema pthread e algumas bibliotecas que o servidor MySQL utiliza. Voe
pode conseguir a lista completa de bibliotecas executando mysql_config --libmysqld-
libs.
Os parˆametros corretos para compilar e ligar um programa em thread devem ser usados,
mesmo se vocˆe n˜ao chamar nenhuma fun¸ao thread diretamente em seu c´odigo.
8.1.15.3 Restri¸oes usando um Servidor MySQL Embutido
O servidor embutido tem as seguintes limita¸oes:
ao tem suporte a tabelas ISAM. (Isto ´e feito para tornar a biblioteca menor)
No possui fun¸cs UDF.
ao ratreia pilha em caso de descarga de mem´oria.
Sem suporte a RAID interno. (Normalmente n˜ao ´e necess´ario j´a que a maioria dos SO
possui suporte a arquivos grandes).
Voe pode configur´a-lo como servidor ou master (sem replica¸ao).
Voe n˜ao pode conectar ao servidor embutido de um processo externo com sockets ou
TCP/IP.
Algumas desta limita¸oes podem ser alteradas editando o arquivo ‘mysql_embed.h’ e re-
compilando o MySQL.
8.1.15.4 Usando Arquivo de Op¸oes com o Servidor Embutido
O descrito abaixo ´e o modo recomendado de utilizar arquivos de op¸oes para facilitar a troca
entre uma aplica¸ao cliente/servidor ´e uma onde o MySQL est´a embutido. See hundefinedi
[Arquivos de op¸ao], page hundefinedi.
Coloque as se¸oes comuns na se¸ao [server]. Ela ser´a lida por ambas as vers˜oes do
MySQL.
Coloque a opoes espec´
ificas do cliente/servidor na se¸ao [mysqld].
Coloque as op¸oes espec´
ificas do MySQL embutido na se¸ao [embedded].
Coloque as op¸oes espec´
ificas da aplica¸ao na se¸ao [ApplicationName_SERVER].
8.1.15.5 Itens a Fazer no Servidor Embutido (TODO)
Estamos fornecendo op¸oes para deixar de fora algumas partes do MySQL para tornar
a biblioteca menor.
Ainda h´a muita otimiza¸ao de velocidade a se fazer.
O erros s˜ao escritos no stderr. Adicionaremos uma op¸ao para especificar um nome de
arquivo para eles.
Temos que alterar o InnoDB para n˜ao ser t˜ao descritivo quando usado em um servidor
embutido.
628 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.1.15.6 Um Exemplo Simples de Seridor Embutido
Este programa e makefile exemplo devem funcionar sem nenhuma altera¸ao em um sistema
Linux ou FreeBSD. Para outros sistemas operacionais, pequenas mudan¸cas ser˜ao necess´arias.
Este exemplo ´e feito para dar detalhes suficientes para enteder o problema, sem a desordem
que ´e uma parte necess´aria de uma aplica¸ao real.
Para experimentar o exemplo, crie um diret´orio ‘test_libmysqld’ no mesmo n´
ivel que
o diret´orio fonte do mysql-4.0. Salve o fonte ‘test_libmysqld.c’ e o ‘GNUmakefile’ no
diret´orio e execute GNU ‘make’ de dentro do diret´orio ‘test_libmysqld’.
test_libmysqld.c
/*
* A simple example client, using the embedded MySQL server library
*/
#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);
const char *server_groups[] = {
"test_libmysqld_SERVER", "embedded", "server", NULL
};
int
main(int argc, char **argv)
{
MYSQL *one, *two;
/* mysql_server_init() devve ser chamado antes de qualquer
* fun¸c~ao mysql.
*
* Voc^e pode usar mysql_server_init(0, NULL, NULL), e iniciar
* o servidor usando os grupos = {
* "server", "embedded", NULL
* }.
*
* Em seu arquivo $HOME/.my.cnf file, voc^e provavelmente deseja colocar:
[test_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english
*´
E claro que voc^e poderia modifcar argc e argv antes de pass´a-los
* a esta fun¸c~ao. Ou poder´a criar novos do modo que preferir. Mas
* todos os argumentos em argv (exceto argv[0], que ´e o nome do
Chapter 8: MySQL APIs 629
* programa) devem ser op¸c~oes v´alidas para o servidor MySQL.
*
* Se voc^e ligar este cliente em um biblioteca mysqlclient
* normal, esta fun¸c~ao n~ao far´a nada.
*/
mysql_server_init(argc, argv, (char **)server_groups);
one = db_connect("test");
two = db_connect(NULL);
db_do_query(one, "SHOW TABLE STATUS");
db_do_query(two, "SHOW DATABASES");
mysql_close(two);
mysql_close(one);
/* Isto deve ser chamado depois de todas outras fun¸c~oes mysql*/
mysql_server_end();
exit(EXIT_SUCCESS);
}
static void
die(MYSQL *db, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
(void)putc(’\n’, stderr);
if (db)
db_disconnect(db);
exit(EXIT_FAILURE);
}
MYSQL *
db_connect(const char *dbname)
{
MYSQL *db = mysql_init(NULL);
if (!db)
die(db, "mysql_init failed: no memory");
/*
* Certifique-se que o cliente e o servidor utilizam grupos diferentes.
* Isto ´e critico pois o servidor n~ao aceitar´a as op¸c~oes do
* cliente e vice versa.
*/
mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test_libmysqld_CLIENT");
if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
die(db, "mysql_real_connect failed: %s", mysql_error(db));
630 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
return db;
}
void
db_disconnect(MYSQL *db)
{
mysql_close(db);
}
void
db_do_query(MYSQL *db, const char *query)
{
if (mysql_query(db, query) != 0)
goto err;
if (mysql_field_count(db) > 0)
{
MYSQL_RES *res;
MYSQL_ROW row, end_row;
int num_fields;
if (!(res = mysql_store_result(db)))
goto err;
num_fields = mysql_num_fields(res);
while ((row = mysql_fetch_row(res)))
{
(void)fputs(">> ", stdout);
for (end_row = row + num_fields; row < end_row; ++row)
(void)printf("%s\t", row ? (char*)*row : "NULL");
(void)fputc(’\n’, stdout);
}
(void)fputc(’\n’, stdout);
}
else
(void)printf("Affected rows: %lld\n", mysql_affected_rows(db));
mysql_free_result(res);
return;
err:
die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
}
GNUmakefile
# This assumes the MySQL software is installed in /usr/local/mysql
inc := /usr/local/mysql/include/mysql
lib := /usr/local/mysql/lib
Chapter 8: MySQL APIs 631
# If you have not installed the MySQL software yet, try this instead
#inc := $(HOME)/mysql-4.0/include
#lib := $(HOME)/mysql-4.0/libmysqld
CC := gcc
CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
CFLAGS := -g -W -Wall
LDFLAGS := -static
# You can change -lmysqld to -lmysqlclient to use the
# client/server library
LDLIBS = -L$(lib) -lmysqld -lz -lm -lcrypt
ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pthread
else
# Assume Linux
LDLIBS += -lpthread
endif
# This works for simple one-file test programs
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))
all: $(targets)
clean:
rm -f $(targets) $(objects) *.core
8.1.15.7 Licensiando o Servidor Embutido
O c´odigo fonte do MySQL ´e coberto pela licen¸ao GNU GPL (see hundefinedi[Licen¸ca GPL],
page hundefinedi). Um resultado disto ´e que qualquer programa que incluam, na liga¸ao
com libmysqld, o c´odigo fonte do MySQL deve ser distribu´
ido como software livre. (sob
uma licen¸ca compat´
ivel com a GPL).
os encorajamos a todos a promover o software livre distribuindo o c´odigo sob a GPL ou
uma licen¸ca compat´
ivel. Para aqueles que n˜ao puderem fazˆe-lo, outra op¸ao ´e comprar um
licen¸ca comercial para o c´odigo MySQL da MySQL AB. Para maiores detalhes, consulte
hundefinedi[MySQL licenses], page hundefinedi.
8.2 Suporte ODBC ao MySQL
O MySQL fornece suporte para ODBC atrav´es do programa MyODBC. Este cap´
itulo lhe
ensinar´a como instalar o MyODBC, e como us´a-lo. Aqui, vocˆe tamb´em encontrar´a uma lista
de programas comuns que s˜ao conhecidos por funcionar com MyODBC.
632 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.2.1 Como Instalar o MyODBC
MyODBC 2.50 ´e um driver de n´
ivel 0 (com recursos de n´
ivel 1 e 2) e especifica¸ao de ODBC
2.50 de 32 bits para conectar um programa ODBC ao MySQL. MyODBC funciona nos Win-
dows 9x/Me/NT/2000/XP e na maioria da plataformas Unix. MyODBC 3.51 ´e uma vers˜ao
melhorada com n´
ivel 1 (core API completo +recursos de n´
ivel 2) e especifica¸ao de ODBC
3.5x.
MyODBC ´e Open Source, e vocˆe pode encontrar a vers˜ao mais nova em
http://www.mysql.com/downloads/api-myodbc.html. Note que a vers˜ao 2.50.x
utiliza a licen¸ca LGPL, enquanto a vers˜ao 3.51.x utiliza a licen¸ca GPL.
Se vcˆe tiver problemas com o MyODBC e seu programa tamb´em funciona com OLEDB, vocˆe
deve experimentar o driver OLEDB.
Normalmente vocˆe s´o precisa instalar o MyODBC em m´asquinas Windows. Vocˆe s´o precisar´a
de MyODBC para Unix se tiver um programa como ColdFusion que roda em m´aquinas Unix
e utilizam ODBC para conectar ao banco de dados.
Se vocˆe quiser instalar MyODBC em um Unix, vocˆe precisar´a de um gerenciador ODBC.MyODBC
funciona com a maioria dos gerenciadores ODBC para Unix.
Para instalar MyODBC no Windows, vocˆe deve baixar o arquivo MyODBC .zip’ apropriado,
descompact´a-lo com WinZIP ou algum programa parecido e executar o arquivo ‘SETUP.EXE’.
No Windows/NT/XP vocˆe pode obter o seguinte erro ao tentar instalar o MyODBC:
An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart
Windows and try installing again (before running any applications which
use ODBC)
O problema neste caso ´e que algum outro progrma est´a utilizando ODBC e pela forma que
como o Windows ´e feito, vocˆe pode, neste caso, ao estar apto a instalar um novo driver
ODBC com programa de insta¸ao do ODBC da Microsoft. Neste caso vocˆe pode continuar
selecionando Ignore para copiar o resto dos aerquivos ODBC e a instala¸ao final deve
funcionar. Se n˜ao funcionar, a solu¸ao ´e reinicializar seu computador em “modo seguro”
(Escolhendo-o ao pressionar F8 assim que seu computador iniciar o Windows durante a
reinicializa¸ao), instalar MyODBC, e reiniciar em modo normal.
Para conectar a uma m´aquina Unix de uma m´aquina Windows, com uma aplica¸ao
ODBC (uma que n˜ao tenha suporte nativo as MySQL), vocˆe deve primeiro instalar
MyODBC em uma m´aquina Windows.
O usu´ario ´e m´aquina Windows devem ter privil´egios para acessar o servidor MySQL
na m´aquina Unix. Isto pode ser feito om o comando GRANT. See hundefinedi[GRANT],
page hundefinedi.
Voe deve criar uma entrada ODBC DSN como a seguir:
Abra o painel de controle na m´aquina Windows.
Dˆe um duplo clique no ´
icone Fonte de Dados ODBC 32-bit.
Clique na se¸ao Usu´ario DSN.
Clique no bot˜ao Adicionar.
Selecione MySQL na tela Criar Nova Fonte de Dados e clique no bot˜ao Finalizar.
A tela de configura¸ao padr˜ao do Driver MySQL ´e mostrada. See hundefinedi
[Administrador ODBC], page hundefinedi.
Chapter 8: MySQL APIs 633
Agora inicie a sua aplica¸ao e selcione o driver ODBC com o DSN que voc6e especificou
no adminitrador ODBC.
Verifique se h´a outra op¸ao de configura¸ao na tela do MySQL (trace, n˜ao pergunta ao
conectar, etc) que vocˆe possa tentar se ocorrerem problemas.
8.2.2 Como Preencher os V´arios Campos no Programa de
Administra¸ao do ODBC
Existem trˆes maneiras poss´
iveis de especificar o nome de servidor no Windows95:
Use o endere¸co IP no servidor.
Adicione um arquivo ‘\windows\lmhosts’ com a seguinte informa¸ao:
ip nome_maquina
Por exemplo:
194.216.84.21 meu_nome_maquina
Configure o PC para utilizar DNS.
Exemplo de como preencher a configura¸c~ao do ODBC.
Windows DSN name: test
Description: This is my test database
MySql Database: test
Server: 194.216.84.21
User: monty
Password: my_password
Port:
O valor para o campo Windows DSN name ´e qualquer nome que seja ´unico em sua configura¸ao
ODBC Windows.
You don’t have to specify values for the Server,User,Password, or Port fields in the
ODBC setup screen. However, if you do, the values will be used as the defaults later when
you attempt to make a connection. You have the option of changing the values at that
time.
If the port number is not given, the default port (3306) is used.
If you specify the option Read options from C:\my.cnf, the groups client and odbc will
be read from the ‘C:\my.cnf’ file. You can use all options that are usable by mysql_
options(). See hundefinedi[mysql_options()], page hundefinedi.
8.2.3 Connect parameters for MyODBC
One can specify the following parameters for MyODBC on the [Servername] section of an
ODBC.INI’ file or through the InConnectionString argument in the SQLDriverConnect()
call.
Parameter Default value Comment
user ODBC (on
Windows)
The username used to connect to MySQL.
server localhost The hostname of the MySQL server.
database The default database.
634 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
option 0 A integer by which you can specify how MyODBC should
work. See below.
port 3306 The TCP/IP port to use if server is not localhost.
stmt A statement that will be executed when connecting to
MySQL.
password The password for the server user combination.
socket The socket or Windows pipe to connect to.
The option argument is used to tell MyODBC that the client isn’t 100% ODBC compliant.
On Windows, one normally sets the option flag by toggling the different options on the
connection screen but one can also set this in the option argument. The following options
are listed in the same order as they appear in the MyODBC connect screen:
Bit Description
1 The client can’t handle that MyODBC returns the real width of a column.
2 The client can’t handle that MySQL returns the true value of affected rows.
If this flag is set then MySQL returns ’found rows’ instead. One must have
MySQL 3.21.14 or newer to get this to work.
4 Make a debug log in c:\myodbc.log. This is the same as putting MYSQL_
DEBUG=d:t:O,c::\myodbc.log in ‘AUTOEXEC.BAT
8 Don’t set any packet limit for results and parameters.
16 Don’t prompt for questions even if driver would like to prompt
32 Simulate a ODBC 1.0 driver in some context.
64 Ignore use of database name in ’database.table.column’.
128 Force use of ODBC manager cursors (experimental).
256 Disable the use of extended fetch (experimental).
512 Pad CHAR fields to full column length.
1024 SQLDescribeCol() will return fully qualified column names
2048 Use the compressed server/client protocol
4096 Tell server to ignore space after function name and before ’(’ (needed by Power-
Builder). This will make all function names keywords!
8192 Connect with named pipes to a mysqld server running on NT.
16384 Change LONGLONG columns to INT columns (some applications can’t handle
LONGLONG).
32768 Return ’user’ as Table qualifier and Table owner from SQLTables (experimental)
65536 Read parameters from the client and odbc groups from ‘my.cnf
131072 Add some extra safety checks (should not bee needed but...)
If you want to have many options, you should add the above flags! For example setting
option to 12 (4+8) gives you debugging without package limits!
The default ‘MYODBC.DLL’ is compiled for optimal performance. If you want to debug MyODBC
(for example to enable tracing), you should instead use ‘MYODBCD.DLL’. To install this file,
copy ‘MYODBCD.DLL’ over the installed ‘MYODBC.DLL’ file.
8.2.4 How to Report Problems with MyODBC
MyODBC has been tested with Access, Admndemo.exe, C++-Builder, Borland Builder 4, Cen-
tura Team Developer (formerly Gupta SQL/Windows), ColdFusion (on Solaris and NT with
svc pack 5), Crystal Reports, DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro,
Chapter 8: MySQL APIs 635
FoxPro, Notes 4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32
bit, VC++, and Visual Basic.
If you know of any other applications that work with MyODBC, please send mail to
myodbc@lists.mysql.com about this!
With some programs you may get an error like: Another user has modifies the record
that you have modified. In most cases this can be solved by doing one of the following
things:
Add a primary key for the table if there isn’t one already.
Add a timestamp column if there isn’t one already.
Only use double float fields. Some programs may fail when they compare single floats.
If the above doesn’t help, you should do a MyODBC trace file and try to figure out why things
go wrong.
8.2.5 Programs Known to Work with MyODBC
Most programs should work with MyODBC, but for each of those listed here, we have tested
it ourselves or received confirmation from some user that it works:
Program Comment
Access To make Access work:
If you are using Access 2000, you should get and install the newest (ver-
sion 2.6 or above) Microsoft MDAC (Microsoft Data Access Components)
from http://www.microsoft.com/data/. This will fix the following bug
in Access: when you export data to MySQL, the table and column names
aren’t specified. Another way to around this bug is to upgrade to MyO-
DBC Version 2.50.33 and MySQL Version 3.23.x, which together provide
a workaround for this bug!
You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5)
which can be found here http://support.microsoft.com/support/kb/articles/Q
239/1/14.ASP. This will fix some cases where columns are marked as
#deleted# in Access.
Note that if you are using MySQL Version 3.22, you must to apply the
MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around
this problem.
For all Access versions, you should enable the MyODBC option flag Return
matching rows. For Access 2.0, you should additionally enable Simulate
ODBC 1.0.
You should have a timestamp in all tables you want to be able to up-
date. For maximum portability TIMESTAMP(14) or simple TIMESTAMP is
recommended instead of other TIMESTAMP(X) variations.
You should have a primary key in the table. If not, new or updated rows
may show up as #DELETED#.
Only use DOUBLE float fields. Access fails when comparing with single
floats. The symptom usually is that new or updated rows may show up as
#DELETED# or that you can’t find or update rows.
636 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
If you are linking a table through MyODBC, which has BIGINT as one
of the column, then the results will be displayed as #DELETED. The work
around solution is:
Have one more dummy column with TIMESTAMP as the data type,
preferably TIMESTAMP(14).
Check the ’Change BIGINT columns to INT’ in connection options di-
alog in ODBC DSN Administrator
Delete the table link from access and re-create it.
It still displays the previous records as #DELETED#, but newly
added/updated records will be displayed properly.
If you still get the error Another user has changed your data after adding
aTIMESTAMP column, the following trick may help you:
Don’t use table data sheet view. Create instead a form with the fields you
want, and use that form data sheet view. You should set the DefaultValue
property for the TIMESTAMP column to NOW(). It may be a good idea to
hide the TIMESTAMP column from view so your users are not confused.
In some cases, Access may generate illegal SQL queries that MySQL can’t
understand. You can fix this by selecting "Query|SQLSpecific|Pass-
Through" from the Access menu.
Access on NT will report BLOB columns as OLE OBJECTS. If you want to
have MEMO columns instead, you should change the column to TEXT with
ALTER TABLE.
Access can’t always handle DATE columns properly. If you have a problem
with these, change the columns to DATETIME.
If you have in Access a column defined as BYTE, Access will try to export
this as TINYINT instead of TINYINT UNSIGNED. This will give you problems
if you have values >127 in the column!
ADO When you are coding with the ADO API and MyODBC you need to put attention
in some default properties that aren’t supported by the MySQL server. For
example, using the CursorLocation Property as adUseServer will return for
the RecordCount Property a result of -1. To have the right value, you need to
set this property to adUseClient, like is showing in the VB code here:
Dim myconn As New ADODB.Connection
Dim myrs As New Recordset
Dim mySQL As String
Dim myrows As Long
myconn.Open "DSN=MyODBCsample"
mySQL = "SELECT * from user"
myrs.Source = mySQL
Set myrs.ActiveConnection = myconn
myrs.CursorLocation = adUseClient
myrs.Open
myrows = myrs.RecordCount
Chapter 8: MySQL APIs 637
myrs.Close
myconn.Close
Another workaround is to use a SELECT COUNT(*) statement for a similar query
to get the correct row count.
Active server pages (ASP)
You should use the option flag Return matching rows.
BDE applications
To get these to work, you should set the option flags Don’t optimize column
widths and Return matching rows.
Borland Builder 4
When you start a query you can use the property Active or use the method
Open. Note that Active will start by automatically issuing a SELECT * FROM
... query that may not be a good thing if your tables are big!
ColdFusion (On Unix)
The following information is taken from the ColdFusion documentation:
Use the following information to configure ColdFusion Server for Linux to use
the unixODBC driver with MyODBC for MySQL data sources. Allaire has verified
that MyODBC Version 2.50.26 works with MySQL Version 3.22.27 and ColdFusion
for Linux. (Any newer version should also work.) You can download MyODBC at
http://www.mysql.com/downloads/api-myodbc.html
ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator to
add the MySQL data source. However, the driver is not included with Cold-
Fusion Version 4.5.1. Before the MySQL driver will appear in the ODBC
datasources drop-down list, you must build and copy the MyODBC driver to
/opt/coldfusion/lib/libmyodbc.so’.
The Contrib directory contains the program ‘mydsn-xxx.zip’ which allows you
to build and remove the DSN registry file for the MyODBC driver on Coldfusion
applications.
DataJunction
You have to change it to output VARCHAR rather than ENUM, as it exports the
latter in a manner that causes MySQL grief.
Excel Works. A few tips:
If you have problems with dates, try to select them as strings using the
CONCAT() function. For example:
select CONCAT(rise_time), CONCAT(set_time)
from sunrise_sunset;
Values retrieved as strings this way should be correctly recognised as time
values by Excel97.
The purpose of CONCAT() in this example is to fool ODBC into thinking
the column is of “string type”. Without the CONCAT(), ODBC knows the
column is of time type, and Excel does not understand that.
638 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Note that this is a bug in Excel, because it automatically converts a string
to a time. This would be great if the source was a text file, but is plain
stupid when the source is an ODBC connection that reports exact types
for each column.
Word
To retrieve data from MySQL to Word/Excel documents, you need to use the
MyODBC driver and the Add-in Microsoft Query help.
For example, create a db with a table containing 2 columns of text:
Insert rows using the mysql client command-line tool.
Create a DSN file using the ODBC manager, for example, ‘my’ for the db
above.
Open the Word application.
Create a blank new documentation.
Using the tool bar called Database, press the button insert database.
Press the button Get Data.
At the right hand of the screen Get Data, press the button Ms Query.
In the Ms Query create a New Data Source using the DSN file my.
Select the new query.
Select the columns that you want.
Make a filter if you want.
Make a Sort if you want.
Select Return Data to Microsoft Word.
Click Finish.
Click Insert data and select the records.
Click OK and you see the rows in your Word document.
odbcadmin
Test program for ODBC.
Delphi You must use BDE Version 3.2 or newer. Set the Don’t optimize column
width option field when connecting to MySQL.
Also, here is some potentially useful Delphi code that sets up both an ODBC
entry and a BDE entry for MyODBC (the BDE entry requires a BDE Alias Editor
that is free at a Delphi Super Page near you. (Thanks to Bryan Brunton
bryan@flesherfab.com for this):
fReg:= TRegistry.Create;
fReg.OpenKey(’\Software\ODBC\ODBC.INI\DocumentsFab’, True);
fReg.WriteString(’Database’, ’Documents’);
fReg.WriteString(’Description’, ’ ’);
fReg.WriteString(’Driver’, ’C:\WINNT\System32\myodbc.dll’);
fReg.WriteString(’Flag’, ’1’);
fReg.WriteString(’Password’, ’’);
fReg.WriteString(’Port’, ’ ’);
Chapter 8: MySQL APIs 639
fReg.WriteString(’Server’, ’xmark’);
fReg.WriteString(’User’, ’winuser’);
fReg.OpenKey(’\Software\ODBC\ODBC.INI\ODBC Data Sources’, True);
fReg.WriteString(’DocumentsFab’, ’MySQL’);
fReg.CloseKey;
fReg.Free;
Memo1.Lines.Add(’DATABASE NAME=’);
Memo1.Lines.Add(’USER NAME=’);
Memo1.Lines.Add(’ODBC DSN=DocumentsFab’);
Memo1.Lines.Add(’OPEN MODE=READ/WRITE’);
Memo1.Lines.Add(’BATCH COUNT=200’);
Memo1.Lines.Add(’LANGDRIVER=’);
Memo1.Lines.Add(’MAX ROWS=-1’);
Memo1.Lines.Add(’SCHEMA CACHE DIR=’);
Memo1.Lines.Add(’SCHEMA CACHE SIZE=8’);
Memo1.Lines.Add(’SCHEMA CACHE TIME=-1’);
Memo1.Lines.Add(’SQLPASSTHRU MODE=SHARED AUTOCOMMIT’);
Memo1.Lines.Add(’SQLQRYMODE=’);
Memo1.Lines.Add(’ENABLE SCHEMA CACHE=FALSE’);
Memo1.Lines.Add(’ENABLE BCD=FALSE’);
Memo1.Lines.Add(’ROWSET SIZE=20’);
Memo1.Lines.Add(’BLOBS TO CACHE=64’);
Memo1.Lines.Add(’BLOB SIZE=32’);
AliasEditor.Add(’DocumentsFab’,’MySQL’,Memo1.Lines);
C++ Builder
Tested with BDE Version 3.0. The only known problem is that when the table
schema changes, query fields are not updated. BDE, however, does not seem to
recognise primary keys, only the index PRIMARY, though this has not been a
problem.
Vision You should use the option flag Return matching rows.
Visual Basic
To be able to update a table, you must define a primary key for the table.
Visual Basic with ADO can’t handle big integers. This means that some
queries like SHOW PROCESSLIST will not work properly. The fix is to set the
option OPTION=16384 in the ODBC connect string or to set the Change BIGINT
columns to INT option in the MyODBC connect screen. You may also want to
set the Return matching rows option.
VisualInterDev
If you get the error [Microsoft][ODBC Driver Manager] Driver does not
support this parameter the reason may be that you have a BIGINT in
your result. Try setting the Change BIGINT columns to INT option in the
MyODBC connect screen.
Visual Objects
You should use the option flag Don’t optimize column widths.
640 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.2.6 How to Get the Value of an AUTO_INCREMENT Column in
ODBC
A common problem is how to get the value of an automatically generated ID from an INSERT.
With ODBC, you can do something like this (assuming that auto is an AUTO_INCREMENT
field):
INSERT INTO foo (auto,text) VALUES(NULL,’text’);
SELECT LAST_INSERT_ID();
Or, if you are just going to insert the ID into another table, you can do this:
INSERT INTO foo (auto,text) VALUES(NULL,’text’);
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),’text’);
See hundefinedi[Getting unique ID], page hundefinedi.
For the benefit of some ODBC applications (at least Delphi and Access), the following query
can be used to find a newly inserted row:
SELECT * FROM nome_tabela WHERE auto IS NULL;
8.2.7 Reporting Problems with MyODBC
If you encounter difficulties with MyODBC, you should start by making a log file from the
ODBC manager (the log you get when requesting logs from ODBCADMIN) and a MyODBC
log.
To get a MyODBC log, you need to do the following:
1. Ensure that you are using ‘myodbcd.dll’ and not ‘myodbc.dll’. The easiest
way to do this is to get ‘myodbcd.dll’ from the MyODBC distribution and copy
it over the ‘myodbc.dll’, which is probably in your ‘C:\windows\system32’ or
C:\winnt\system32’ directory.
Note that you probably want to restore the old myodbc.dll file when you have finished
testing, as this is a lot faster than ‘myodbcd.dll’.
2. Tag the ‘Trace MyODBC’ option flag in the MyODBC connect/configure screen. The log
will be written to file ‘C:\myodbc.log’.
If the trace option is not remembered when you are going back to the above screen, it
means that you are not using the myodbcd.dll driver (see the item above).
3. Start your application and try to get it to fail.
Check the MyODBC trace file, to find out what could be wrong. You should be able to find
out the issued queries by searching after the string >mysql_real_query in the ‘myodbc.log
file.
You should also try duplicating the queries in the mysql monitor or admndemo to find out
if the error is MyODBC or MySQL.
If you find out something is wrong, please only send the relevant rows (max 40 rows) to
myodbc@lists.mysql.com. Please never send the whole MyODBC or ODBC log file!
If you are unable to find out what’s wrong, the last option is to make an archive (tar or zip)
that contains a MyODBC trace file, the ODBC log file, and a README file that explains
the problem. You can send this to ftp://support.mysql.com/pub/mysql/secret/. Only
we at MySQL AB will have access to the files you upload, and we will be very discrete with
the data!
Chapter 8: MySQL APIs 641
If you can create a program that also shows this problem, please upload this too!
If the program works with some other SQL server, you should make an ODBC log file where
you do exactly the same thing in the other SQL server.
Remember that the more information you can supply to us, the more likely it is that we
can fix the problem!
8.3 MySQL Java Connectivity (JDBC)
There are 2 supported JDBC drivers for MySQL:
MySQL Connector/J from MySQL AB, implemented in 100% native Java. This product
was formerly known as the mm.mysql driver. You can download MySQL Connector/J
from http://www.mysql.com/products/connector-j/.
The Resin JDBC driver, which can be found at http://www.caucho.com/projects/jdbc-
mysql/index.xtp.
For documentation, consult any JDBC documentation, plus each driver’s own documenta-
tion for MySQL-specific features.
8.4 MySQL PHP API
PHP is a server-side, HTML-embedded scripting language that may be used to create
dynamic web pages. It contains support for accessing several databases, including MySQL.
PHP may be run as a separate program or compiled as a module for use with the Apache
web server.
The distribution and documentation are available at the PHP web site
(http://www.php.net/).
8.4.1 Common Problems with MySQL and PHP
Error: "Maximum Execution Time Exceeded"This is a PHP limit; go into the
php3.ini’ file and set the maximum execution time up from 30 seconds to something
higher, as needed. It is also not a bad idea to double the ram allowed per script to 16
MB instead of 8 MB.
Error: "Fatal error: Call to unsupported or undefined function mysql connect() in
.."This means that your PHP version isn’t compiled with MySQL support. You can
either compile a dynamic MySQL module and load it into PHP or recompile PHP with
built-in MySQL support. This is described in detail in the PHP manual.
Error: "undefined reference to ‘uncompress’"This means that the client library is
compiled with support for a compressed client/server protocol. The fix is to add -lz
last when linking with -lmysqlclient.
8.5 MySQL Perl API
This section documents the Perl DBI interface. The former interface was called mysqlperl.
DBI/DBD now is the recommended Perl interface, so mysqlperl is obsolete and is not docu-
mented here.
642 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.5.1 DBI with DBD::mysql
DBI is a generic interface for many databases. That means that you can write a script that
works with many different database engines without change. You need a DataBase Driver
(DBD) defined for each database type. For MySQL, this driver is called DBD::mysql.
For more information on the Perl5 DBI, please visit the DBI web page and read the docu-
mentation:
http://dbi.perl.org/
For more information on Object Oriented Programming (OOP) as defined in Perl5, see the
Perl OOP page:
http://language.perl.com/info/documentation.html
Note that if you want to use transactions with Perl, you need to have DBD-mysql version
1.2216 or newer. Version 2.1022 or newer is recommended.
Installation instructions for MySQL Perl support are given in hundefinedi[Perl support],
page hundefinedi.
If you have the MySQL module installed, you can find information about specific MySQL
functionality with one of the following command
shell> perldoc DBD/mysql
shell> perldoc mysql
8.5.2 The DBI Interface
Portable DBI Methods
Method Description
connect Establishes a connection to a database server.
disconnect Disconnects from the database server.
prepare Prepares a SQL statement for execution.
execute Executes prepared statements.
do Prepares and executes a SQL statement.
quote Quotes string or BLOB values to be inserted.
fetchrow_array Fetches the next row as an array of fields.
fetchrow_arrayref Fetches next row as a reference array of fields.
fetchrow_hashref Fetches next row as a reference to a hashtable.
fetchall_arrayref Fetches all data as an array of arrays.
finish Finishes a statement and lets the system free
resources.
rows Returns the number of rows affected.
data_sources Returns an array of databases available on localhost.
ChopBlanks Controls whether fetchrow_* methods trim spaces.
NUM_OF_PARAMS The number of placeholders in the prepared
statement.
NULLABLE Which columns can be NULL.
trace Perform tracing for debugging.
MySQL-specific Methods
Method Description
insertid The latest AUTO_INCREMENT value.
Chapter 8: MySQL APIs 643
is_blob Which columns are BLOB values.
is_key Which columns are keys.
is_num Which columns are numeric.
is_pri_key Which columns are primary keys.
is_not_null Which columns CANNOT be NULL. See NULLABLE.
length Maximum possible column sizes.
max_length Maximum column sizes actually present in result.
NAME Column names.
NUM_OF_FIELDS Number of fields returned.
table Table names in returned set.
type All column types.
The Perl methods are described in more detail in the following sections. Variables used for
method return values have these meanings:
$dbh Database handle
$sth Statement handle
$rc Return code (often a status)
$rv Return value (often a row count)
Portable DBI Methods
connect($data_source, $username, $password)
Use the connect method to make a database connection to the data source.
The $data_source value should begin with DBI:driver_name:. Example uses
of connect with the DBD::mysql driver:
$dbh = DBI->connect("DBI:mysql:$database", $user, $password);
$dbh = DBI->connect("DBI:mysql:$database:$hostname",
$user, $password);
$dbh = DBI->connect("DBI:mysql:$database:$hostname:$port",
$user, $password);
If the user name and/or password are undefined, DBI uses the values of the DBI_
USER and DBI_PASS environment variables, respectively. If you don’t specify a
hostname, it defaults to ’localhost’. If you don’t specify a port number, it
defaults to the default MySQL port (3306).
As of Msql-Mysql-modules Version 1.2009, the $data_source value allows cer-
tain modifiers:
mysql_read_default_file=file_name
Read ‘file_name’ as an option file. For information on option files,
see hundefinedi[Option files], page hundefinedi.
mysql_read_default_group=group_name
The default group when reading an option file is normally the
[client] group. By specifying the mysql_read_default_group
option, the default group becomes the [group_name] group.
mysql_compression=1
Use compressed communication between the client and server
(MySQL Version 3.22.3 or later).
644 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql_socket=/path/to/socket
Specify the pathname of the Unix socket that is used to connect to
the server (MySQL Version 3.21.15 or later).
Multiple modifiers may be given; each must be preceded by a semicolon.
For example, if you want to avoid hardcoding the user name and password into
aDBI script, you can take them from the user’s ‘~/.my.cnf’ option file instead
by writing your connect call like this:
$dbh = DBI->connect("DBI:mysql:$database"
. ";mysql_read_default_file=$ENV{HOME}/.my.cnf",
$user, $password);
This call will read options defined for the [client] group in the option file. If
you wanted to do the same thing but use options specified for the [perl] group
as well, you could use this:
$dbh = DBI->connect("DBI:mysql:$database"
. ";mysql_read_default_file=$ENV{HOME}/.my.cnf"
. ";mysql_read_default_group=perl",
$user, $password);
disconnect
The disconnect method disconnects the database handle from the database.
This is typically called right before you exit from the program. Example:
$rc = $dbh->disconnect;
prepare($statement)
Prepares a SQL statement for execution by the database engine and returns a
statement handle ($sth), which you can use to invoke the execute method.
Typically you handle SELECT statements (and SELECT-like statements such as
SHOW,DESCRIBE, and EXPLAIN) by means of prepare and execute. Example:
$sth = $dbh->prepare($statement)
or die "Can’t prepare $statement: $dbh->errstr\n";
If you want to read big results to your client you can tell Perl to use mysql_
use_result() with:
my $sth = $dbh->prepare($statement { "mysql_use_result" => 1});
execute The execute method executes a prepared statement. For non-SELECT state-
ments, execute returns the number of rows affected. If no rows are affected,
execute returns "0E0", which Perl treats as zero but regards as true. If an error
occurs, execute returns undef. For SELECT statements, execute only starts
the SQL query in the database; you need to use one of the fetch_* methods
described here to retrieve the data. Example:
$rv = $sth->execute
or die "can’t execute the query: $sth->errstr;
do($statement)
The do method prepares and executes a SQL statement and returns the number
of rows affected. If no rows are affected, do returns "0E0", which Perl treats as
Chapter 8: MySQL APIs 645
zero but regards as true. This method is generally used for non-SELECT state-
ments that cannot be prepared in advance (due to driver limitations) or that
do not need to be executed more than once (inserts, deletes, etc.). Example:
$rv = $dbh->do($statement)
or die "Can’t execute $statement: $dbh- >errstr\n";
Generally the ’do’ statement is much faster (and is preferable) than
prepare/execute for statements that don’t contain parameters.
quote($string)
The quote method is used to "escape"any special characters contained in the
string and to add the required outer quotation marks. Example:
$sql = $dbh->quote($string)
fetchrow_array
This method fetches the next row of data and returns it as an array of field
values. Example:
while(@row = $sth->fetchrow_array) {
print qw($row[0]\t$row[1]\t$row[2]\n);
}
fetchrow_arrayref
This method fetches the next row of data and returns it as a reference to an
array of field values. Example:
while($row_ref = $sth->fetchrow_arrayref) {
print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
}
fetchrow_hashref
This method fetches a row of data and returns a reference to a hash table
containing field name/value pairs. This method is not nearly as efficient as
using array references as demonstrated above. Example:
while($hash_ref = $sth->fetchrow_hashref) {
print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\
$hash_ref->{title}\n);
}
fetchall_arrayref
This method is used to get all the data (rows) to be returned from the SQL
statement. It returns a reference to an array of references to arrays for each
row. You access or print the data by using a nested loop. Example:
my $table = $sth->fetchall_arrayref
or die "$sth->errstr\n";
my($i, $j);
for $i ( 0 .. $#{$table} ) {
for $j ( 0 .. $#{$table->[$i]} ) {
print "$table->[$i][$j]\t";
}
print "\n";
}
646 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
finish Indicates that no more data will be fetched from this statement handle. You
call this method to free up the statement handle and any system resources
associated with it. Example:
$rc = $sth->finish;
rows Returns the number of rows changed (updated, deleted, etc.) by the last com-
mand. This is usually used after a non-SELECT execute statement. Example:
$rv = $sth->rows;
NULLABLE Returns a reference to an array of values that indicate whether columns may
contain NULL values. The possible values for each array element are 0 or the
empty string if the column cannot be NULL, 1 if it can, and 2 if the column’s
NULL status is unknown. Example:
$null_possible = $sth->{NULLABLE};
NUM_OF_FIELDS
This attribute indicates the number of fields returned by a SELECT or SHOW
FIELDS statement. You may use this for checking whether a statement returned
a result: A zero value indicates a non-SELECT statement like INSERT,DELETE,
or UPDATE. Example:
$nr_of_fields = $sth->{NUM_OF_FIELDS};
data_sources($driver_name)
This method returns an array containing names of databases available to the
MySQL server on the host ’localhost’. Example:
@dbs = DBI->data_sources("mysql");
ChopBlanks
This attribute determines whether the fetchrow_* methods will chop leading
and trailing blanks from the returned values. Example:
$sth->{’ChopBlanks’} =1;
trace($trace_level)
trace($trace_level, $trace_filename)
The trace method enables or disables tracing. When invoked as a DBI class
method, it affects tracing for all handles. When invoked as a database or
statement handle method, it affects tracing for the given handle (and any future
children of the handle). Setting $trace_level to 2 provides detailed trace
information. Setting $trace_level to 0 disables tracing. Trace output goes to
the standard error output by default. If $trace_filename is specified, the file
is opened in append mode and output for all traced handles is written to that
file. Example:
DBI->trace(2); # trace everything
DBI->trace(2,"/tmp/dbi.out"); # trace everything to
# /tmp/dbi.out
$dth->trace(2); # trace this database handle
$sth->trace(2); # trace this statement handle
You can also enable DBI tracing by setting the DBI_TRACE environment variable.
Setting it to a numeric value is equivalent to calling DBI->(value). Setting it
to a pathname is equivalent to calling DBI->(2,value).
Chapter 8: MySQL APIs 647
MySQL-specific Methods
The methods shown here are MySQL-specific and not part of the DBI standard. Several of
them are now deprecated: is_blob,is_key,is_num,is_pri_key,is_not_null,length,
max_length, and table. Where DBI-standard alternatives exist, they are noted here:
insertid If you use the AUTO_INCREMENT feature of MySQL, the new auto-incremented
values will be stored here. Example:
$new_id = $sth->{insertid};
As an alternative, you can use $dbh->{’mysql_insertid’}.
is_blob Returns a reference to an array of boolean values; for each element of the array,
a value of TRUE indicates that the respective column is a BLOB. Example:
$keys = $sth->{is_blob};
is_key Returns a reference to an array of boolean values; for each element of the array,
a value of TRUE indicates that the respective column is a key. Example:
$keys = $sth->{is_key};
is_num Returns a reference to an array of boolean values; for each element of the array,
a value of TRUE indicates that the respective column contains numeric values.
Example:
$nums = $sth->{is_num};
is_pri_key
Returns a reference to an array of boolean values; for each element of the array, a
value of TRUE indicates that the respective column is a primary key. Example:
$pri_keys = $sth->{is_pri_key};
is_not_null
Returns a reference to an array of boolean values; for each element of the array,
a value of FALSE indicates that this column may contain NULL values. Example:
$not_nulls = $sth->{is_not_null};
is_not_null is deprecated; it is preferable to use the NULLABLE attribute (de-
scribed above), because that is a DBI standard.
length
max_length
Each of these methods returns a reference to an array of column sizes. The
length array indicates the maximum possible sizes that each column may be
(as declared in the table description). The max_length array indicates the
maximum sizes actually present in the result table. Example:
$lengths = $sth->{length};
$max_lengths = $sth->{max_length};
NAME Returns a reference to an array of column names. Example:
$names = $sth->{NAME};
table Returns a reference to an array of table names. Example:
$tables = $sth->{table};
type Returns a reference to an array of column types. Example:
$types = $sth->{type};
648 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
8.5.3 More DBI/DBD Information
You can use the perldoc command to get more information about DBI.
perldoc DBI
perldoc DBI::FAQ
perldoc DBD::mysql
You can also use the pod2man,pod2html, etc., tools to translate to other formats.
You can find the latest DBI information at the DBI web page: http://dbi.perl.org/.
8.6 MySQL C++ API
MySQL Connector/C++ (or MySQL++) is the official MySQL API for C++. More information
can be found at http://www.mysql.com/products/mysql++/.
8.6.1 Borland C++
You can compile the MySQL Windows source with Borland C++ 5.02. (The Windows source
includes only projects for Microsoft VC++, for Borland C++ you have to do the project files
yourself.)
One known problem with Borland C++ is that it uses a different structure alignment
than VC++. This means that you will run into problems if you try to use the default
libmysql.dll libraries (that was compiled with VC++) with Borland C++. You can do one
of the following to avoid this problem.
You can use the static MySQL libraries for Borland C++ that you can find on
http://www.mysql.com/downloads/os-win32.html.
Only call mysql_init() with NULL as an argument, not a pre-allocated MYSQL struct.
8.7 MySQL Python API
MySQLdb provides MySQL support for Python, compliant with the Python DB API version
2.0. It can be found at http://sourceforge.net/projects/mysql-python/.
8.8 MySQL Tcl API
MySQLtcl is a simple API for accessing a MySQL database server from the Tcl programming
language. It can be found at http://www.xdobry.de/mysqltcl/.
8.9 MySQL Eiffel wrapper
Eiffel MySQL is an interface to the MySQL database server using the Eif-
fel programming language, written by Michael Ravits. It can be found at
http://efsa.sourceforge.net/archive/ravits/mysql.htm.
Chapter 9: Spatial Extensions in MySQL 649
9 Spatial Extensions in MySQL
9.1 Introduction
In release 4.1 MySQL introduces spatial extensions, which allow generating, storing and
analysing of geographic features.
9.1.1 Geographic Features
Ageographic feature is anything in the world that has a location.
A feature can be:
An entity. For example, a mountain, a pond, a city.
A space. For example, a postcode area, the tropics.
A definable location. For example, a crossroad, as a particular place where two streets
intersect.
You can also find documents which use term geospatial feature to refer to geographic
features.
Geometry is another word that denotes a geographic feature. The original meaning of
the word geometry denotes a branch of mathematics. Another meaning that comes from
cartography, referring to the geometric features that cartographers use to map the world.
We will mean the same thing using all these terms, a geographic feature, or a geospatial
feature, or a feature, or a geometry, with geometry as the most used in this documen-
tation.
Let’s define a geometry as a point or an aggregate of points representing anything in the
world that has a location.
9.1.2 Approach
MySQL implements spatial extensions following OpenGIS specifications.
The OpenGIS Consortium (OGC), is an international consortium of more than 250 compa-
nies, agencies, universities participating in the development of publicly available conceptual
solutions that can be useful with all kinds of applications that manage spatial data. See
http://www.opengis.org/.
In 1997, the OpenGIS Consortium published the OpenGIS (r) Simple Features
Specifications For SQL, which proposes several conceptual ways for extending an SQL
RDBMS to support spatial data. MySQL implements a subset of the SQL with Geometry
Types environment proposed by OGC. This term refers to an SQL environment that
has been extended with a set of geometry types. A geometry-valued SQL column is
implemented as a column of a geometry type. The specifications describe a set of SQL
geometry types, as well as functions on those types to create and analyse geometry values.
650 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.2 OpenGIS Geometry Model
The set of geometry types, proposed by OGC’s SQL with Geometry Types environment, is
based of OpenGIS Geometry Model. In this model, each geometric object:
is associated with a Spatial Reference System, which describes the coordinate space in
which the object is defined.
belongs to some geometry class.
9.2.1 Geometry Class Hierarchy
Geometry
Point
Curve
LineString
Line
LinearRing
Surface
Polygon
GeometryCollection
MultiPoint
MultiCurve
MultiLineString
MultiSurface
MultiPolygon
Geometry is the base class. It’s an abstract (non-instantiable) class. The instantiable
subclasses of Geometry are restricted to zero, one, and two-dimensional geometric objects
that exist in two-dimensional coordinate space. All instantiable geometry classes are defined
so that valid instances of a geometry class are topologically closed (i.e. all defined geometries
include their boundary).
The base Geometry class has subclasses for Point,Curve,Surface and
GeometryCollection.
Curve stands for 1-dimensional objects, and has subclass LineString, with sub-subclasses
Line and LinearRing.
Surface is designed for two-dimensional objects and has subclass Polygon.
GeometryCollection has specialised 0, 1 and two-dimensional collection classes named
MultiPoint,MultiLineString and MultiPolygon for modelling geometries correspond-
ing to collections of Points,LineStrings and Polygons respectively. MultiCurve and
MultiSurface are introduced as abstract superclasses that generalise the collection inter-
faces to handle Curves and Surfaces.
Geometry,Curve,Surface,MultiCurve and MultiSurface are defined as non-instantiable
classes, it is not possible to create an object of these classes. They define a common set of
methods for its subclasses and included for the reason of extensibility.
Point, LineString, Polygon, GeometryCollection, MultiPoint, MultiLineString, MultiPoly-
gon are instantiable classes (marked bold in the hierarchy tree).
Chapter 9: Spatial Extensions in MySQL 651
9.2.2 Class Geometry
Geometry is the root class of the hierarchy. Each geometry is described by a number of
its properties. Particular subclasses of the root class Geometry have their own specific
properties. Properties, which are common for all geometry subclasses, are described in the
list below. Geometry is a non-instantiable class.
9.2.3 Geometry properties
The type that a geometry belongs to. Each geometry belongs to one of instantiable
classes in the hierarchy.
Its SRID, the identifier of a geometry’s associated Spatial Reference System which
describes the coordinate space in which the geometry object is defined.
Geometry’s coordinates in its Spatial Reference System, represented as double pre-
cision (8 byte) numbers. All non-empty geometries include at least one pair of (X,Y)
coordinates. Empty geometries contain no coordinates.
Its interior, boundary and exterior. All geometries occupy some position in space.
The exterior of a geometry is all space not occupied by the geometry. The interior is
the space occupied by the geometry. The boundary is the interface between geometry’s
interior and exterior.
Its MBR, or Envelope, the geometry’s Minimum Bounding Rectangle. This is the bound-
ing geometry, formed by the minimum and maximum (X,Y) coordinates:
((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
The quality of being simple or non-simple. Geometry values of some types
(LineString, MultyPoint, MultiLineString) are either simple of non-simple. Each type
determines its own assertions for being simple or non-simple.
The quality of being closed or not closed. Geometry values of some types
(LineString, MultiString) are either closed or not closed. Each type determines its
own assertions for being closed or not closed.
The quality of being empty or not empty A geometry is empty if it does not have any
points. Exterior, interior and boundary of an empty geometry are not defined, i.e.,
they are represented by a NULL value. An empty geometry is defined to be always
simple. An empty geometry has an area of 0.
Its dimension A geometry can have a dimension of -1, 0, 1 or 2.
-1 stands for empty geometries.
0 stands for geometries with no length and no area.
1 stands for geometries with non-zero length and zero area.
2 stands for geometries with non-zero area.
Points have a dimension of zero. LineStrings have a dimension of 1. Polygons have a
dimension of 2. Dimensions of MultiPoints, MultiLineStrings and MultiPolygons are
the same as the dimensions of the elements they consist of.
For example, in different coordinate systems, a distance between two objects may differ
even when objects have the same coordinates, because the distance on the planar
coordinate system and the distance on the geocentric system (coordinates on the
Earth’s surface) are different things.
652 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.2.4 Class Point
APoint is a geometry that represents a single location in coordinate space.
Point examples
Imagine a large-scale map of the world with a lot of cities. A point could represent
each city.
On a city map, a Point could represent a bus stop.
Point properties
X-coordinate value.
Y-coordinate value.
The Boundary of a Point is an empty set.
A Point is defined as zero-dimensional geometry.
9.2.5 Class Curve
ACurve is a one-dimensional geometry, usually represented by a sequence of points. Par-
ticular subclasses of Curve specify the form of the interpolation between points. Curve is a
non-instantiable class.
Curve properties
Coordinates of its points.
Curve is defined as one-dimensional geometry.
A Curve is simple if it does not pass through the same point twice.
A Curve is closed if its start point is equal to its end point.
The boundary of a closed Curve is empty.
The boundary of a non-closed Curve consists of its two end points.
A Curve that is simple and closed is Ring.
9.2.6 Class LineString
A LineString is a Curve with linear interpolation between points.
LineString examples
On a world map a LineStrings could represent rivers.
In a city map a LineStrings could represent streets.
LineString properties
Coordinates of LineString segments, defined by each consecutive pair of points.
A LineString is a Line, if it consists of exactly two points.
A LineString is a LinearRing, of it’s both closed and simple.
Chapter 9: Spatial Extensions in MySQL 653
9.2.7 Class Surface
ASurface is a two-dimensional geometric object.
Surface properties
A Surface is defined as a two-dimensional geometry.
The OpenGIS specification defines a simple Surface as consisting of a single ’patch’
that is associated with one ’exterior boundary’ and zero or more ’interior’ boundaries.
The boundary of a simple Surface is the set of closed curves corresponding to its exterior
and interior boundaries.
The only instantiable subclass of Surface defined in OpenGIS specification, is Polygon.
9.2.8 Class Polygon
A Polygon is a planar Surface representing a multisided geometry, defined by one exterior
boundary and zero or more interior boundaries. Each interior boundary defines a hole in
the Polygon.
Polygon examples
On a region map: forests, districts, etc.
The assertions for polygons (the rules that define valid polygons) are:
1. The boundary of a Polygon consists of a set of LinearRings (i.e. LineStrings that are
both simple and closed) that make up its exterior and interior boundaries.
2. No two rings in the boundary cross, the rings in the boundary of a Polygon may
intersect at a Point but only as a tangent.
3. A Polygon may not have cut lines, spikes or punctures.
4. The Interior of every Polygon is a connected point set.
5. The Exterior of a Polygon with one or more holes is not connected. Each hole defines
a connected component of the Exterior.
In the above assertions, polygons are simple geometries.
9.2.9 Class GeometryCollection
AGeometryCollection is a geometry that is a collection of one or more geometries of any
class.
All the elements in a GeometryCollection must be in the same Spatial Reference (i.e. in the
same coordinate system). GeometryCollection places no other constraints on its elements.
Subclasses of GeometryCollection described below may restrict membership based on:
Element types
Dimension.
Other constraints on the degree of spatial overlap between elements.
654 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.2.10 Class MultiPoint
AMultiPoint is a collection whose elements are restricted to Points. The points are not
connected or ordered in any way.
MultiPoint examples
One a world map, a Multipoint could represent a chain of small islands.
MultiPoint properties
MultiPoint is defined as a zero-dimensional geometry.
A MultiPoint is simple if no two Points in the MultiPoint are equal (have identical
coordinate values).
The boundary of a MultiPoint is empty set.
9.2.11 Class MultiCurve
A MultiCurve is a geometry collection whose elements are Curves. MultiCurve is a non-
instantiable class.
MultiCurve properties
A MultiCurve is simple if and only if all of its elements are simple, the only intersections
between any two elements occur at points that are on the boundaries of both elements.
The boundary of a MultiCurve is obtained by applying the "mod 2 union rule": A
point is in the boundary of a MultiCurve if it is in the boundaries of an odd number
of elements of the MultiCurve.
A MultiCurve is defined as a one-dimensional geometry.
A MultiCurve is closed if all of its elements are closed.
The boundary of a closed MultiCurve is always empty.
9.2.12 Class MultiLineString
AMultiLineString is a MultiCurve whose elements are LineStrings.
MultiLineString examples
On a region map, a MultiLineString could represent a river system or a highway system.
9.2.13 Class MultiSurface
A MultiSurface is a geometric collection whose elements are surfaces. MultiSurface is a
non-instantiable class.
Chapter 9: Spatial Extensions in MySQL 655
MultiSurface assertions
1. The interiors of any two surfaces in a MultiSurface may not intersect.
2. The boundaries of any two elements in a MultiSurface may intersect at most at a finite
number of points.
The only instantiable subclass of MultiSurface is MultiPolygon.
9.2.14 Class MultiPolygon
A MultiPolygon is a MultiSurface whose elements are Polygons.
MultiPolygon examples
On a region map, a MultiPolygon could represent a system of lakes.
The assertions for MultiPolygons are:
1. The interiors of two Polygons that are elements of a MultiPolygon may not intersect.
2. The Boundaries of any two Polygons that are elements of a MultiPolygon may not
cross and may touch at only a finite number of points. (Note that crossing is already
forbidden by the first assertion.)
3. A MultiPolygon may not have cut lines, spikes or punctures; a MultiPolygon is a
Regular, Closed point set.
4. The interior of a MultiPolygon with more than one Polygon is not connected, the
number of connected components of the interior of a MultiPolygon is equal to the
number of Polygons in the MultiPolygon.
MultiPolygon properties
MultiPolygon is defined as two-dimensional geometry.
The boundary of a MultiPolygon is a set of closed curves (LineStrings) corresponding
to the boundaries of its element Polygons.
Each Curve in the boundary of the MultiPolygon is in the boundary of exactly one
element Polygon, and every Curve in the boundary of an element Polygon is in the
boundary of the MultiPolygon.
9.3 Supported Spatial Data Formats
This section describes the standard spatial data formats that are used to store geometry
objects.
They are:
Well-Known Text (WKT) representation.
Well-Known Binary (WKB) representation.
9.3.1 Well-Known Text (WKT) Representation
The Well-Known Text (WKT) representation of Geometry is designed to exchange geometry
data in ASCII form.
656 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.3.1.1 WKT Examples
Examples of WKT representations of geometry objects are:
POINT(10 10)
A Point.
LINESTRING(10 10, 20 20, 30 40)
A LineString with three points.
POLYGON((10 10, 10 20, 20 20, 20 15, 10 10))
A Polygon with one exterior ring and zero interior rings.
MULTIPOINT(10 10, 20 20)
A MultiPoint with two Points.
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
A MultiLineString with two LineStrings.
MULTIPOLYGON(((10 10, 10 20, 20 20, 20 15, 10 10)), ((60 60, 70 7, 80 60, 60 60
)))
A MultiPolygon with two Polygons.
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
A GeometryCollection consisting of two Points and one LineString.
9.3.1.2 Bachus-Naur Forms of WKT
The text representation of the implemented instantiable geometric types conforms to this
grammar:
The notation {}* denotes zero or more repetitions of the tokens within the braces;
The braces do not appear in the output token list.
<Geometry Tagged Text> :=
<Point Tagged Text>
| <LineString Tagged Text>
| <Polygon Tagged Text>
| <MultiPoint Tagged Text>
| <MultiLineString Tagged Text>
| <MultiPolygon Tagged Text>
| <GeometryCollection Tagged Text>
<Point Tagged Text> := POINT <Point Text>
<LineString Tagged Text> := LINESTRING <LineString Text>
<Polygon Tagged Text> := POLYGON <Polygon Text>
<MultiPoint Tagged Text> := MULTIPOINT <Multipoint Text>
<MultiLineString Tagged Text> := MULTILINESTRING <MultiLineString Text>
<MultiPolygon Tagged Text> := MULTIPOLYGON <MultiPolygon Text>
<GeometryCollection Tagged Text> := GEOMETRYCOLLECTION <GeometryCollection Text>
<Point Text> := EMPTY | ( <Point> )
<Point> := <x> <y>
<x> := double precision literal
<y> := double precision literal
<LineString Text> := EMPTY | ( <Point > {, <Point > }* )
Chapter 9: Spatial Extensions in MySQL 657
<Polygon Text> := EMPTY | ( <LineString Text > {, < LineString Text > }*)
<Multipoint Text> := EMPTY | ( <Point Text > {, <Point Text > }* )
<MultiLineString Text> := EMPTY | ( <LineString Text > {, < LineString Text > }* )
<MultiPolygon Text> := EMPTY | ( < Polygon Text > {, < Polygon Text > }* )
<GeometryCollection Text> := EMPTY | ( <Geometry Tagged Text> {, <Geometry Tagged Text> }* )
9.3.2 Well-Known Binary (WKB) Representation
Well-Known Binary (WKB) representation is defined by the OpenGIS specifications. It’s
also defined in the ISO "SQL/MM Part 3: Spatial"standard.
WKB is used to exchange geometry data as binary streams represented by BLOB values
containing geometic information, according to the structures described below.
WKB uses the following basic type definitions:
9.3.2.1 WKB Basic Types
// byte : 8-bit unsigned integer (1 byte)
// uint32 : 32-bit unsigned integer (4 bytes)
// double : double precision number (8 bytes)
enum wkbGeometryType
{
wkbPoint = 1,
wkbLineString = 2,
wkbPolygon = 3,
wkbMultiPoint = 4,
wkbMultiLineString = 5,
wkbMultiPolygon = 6,
wkbGeometryCollection = 7
}
enum wkbByteOrder
{
wkbXDR = 0, // Big Endian
wkbNDR = 1 // Little Endian
}
9.3.2.2 WKB Building Blocks
// Building Blocks : Point, LinearRing
Point
{
double x;
double y;
}
LinearRing
{
uint32 numPoints;
Point points[numPoints];
}
658 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.3.2.3 WKB Representation of Geometry Values
WKBPoint
{
byte byteOrder;
uint32 wkbType; // 1
Point point;
}
WKBLineString
{
byte byteOrder;
uint32 wkbType; // 2
uint32 numPoints;
Point points[numPoints];
}
WKBPolygon
{
byte byteOrder;
uint32 wkbType; // 3
uint32 numRings;
LinearRing rings[numRings];
}
WKBMultiPoint
{
byte byteOrder;
uint32 wkbType; // 4
uint32 num_wkbPoints;
WKBPoint WKBPoints[num_wkbPoints];
}
WKBMultiLineString
{
byte byteOrder;
uint32 wkbType; // 5
uint32 num_wkbLineStrings;
WKBLineString WKBLineStrings[num_wkbLineStrings];
}
wkbMultiPolygon
{
byte byteOrder;
uint32 wkbType; // 6
uint32 num_wkbPolygons;
WKBPolygon wkbPolygons[num_wkbPolygons];
}
WKBGeometry
{
union
{
WKBPoint point;
WKBLineString linestring;
WKBPolygon polygon;
Chapter 9: Spatial Extensions in MySQL 659
WKBGeometryCollection collection;
WKBMultiPoint mpoint;
WKBMultiLineString mlinestring;
WKBMultiPolygon mpolygon;
}
}
WKBGeometryCollection
{
byte byte_order;
uint32 wkbType; // 7
uint32 num_wkbGeometries;
WKBGeometry wkbGeometries[num_wkbGeometries];
}
9.3.2.4 WKB Examples
A WKB which corresponds to POINT(1,1) looks like this sequence of 21 bytes:
0101000000000000000000F03F000000000000F03F
Where, consequently,
Byte order : 01
WKB type : 01000000
X : 000000000000F03F
Y : 000000000000F03F
9.4 Creating a Spatially Enabled MySQL Database
9.4.1 MySQL Spatial Data Types
MySQL provides a hierarchy of datatypes, corresponding to the OpenGIS Geometry Model.
GEOMETRY
POINT
LINESTRING
POLYGON
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
The GEOMETRY type can store geometries of any type, other types restrict their values to
a partilcular geometry type. GEOMETRYCOLLECTION can store a collection of objects of any
type, other collection types restrict the type of collection members to a particular geometry
type.
9.4.2 Creating Spatial Values
660 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.4.2.1 Creating a Geometry Using Its WKT
MySQL provides a number of function which take a Well-Known Text representation and,
optionally, a spatial reference system identifier as input parameters, and return the corre-
sponding geometry.
GeomFromText() accepts a WKT of any geometry type as its first argument.
For construction of geometry values restricted to a particular type, an implementation also
provides a type-specific construction function for each geometry type.
9.4.2.2 Functions To Create a Geometry Using Its WKT
GeomFromText(wkt,srid)
GeometryFromText(wkt,srid)
Constructs a geometry of any type using its WKT representation and SRID.
PointFromText(wkt,srid)
Constructs a POINT using its WKT representation and SRID.
LineFromText(wkt,srid)
LineStringFromText(wkt,srid)
Constructs a LINESTRING using its WKT representation and SRID.
PolyFromText(wkt,srid)
PolygonFromText(wkt,srid)
Constructs a POLYGON using its WKT representation and SRID.
MPointFromText(wkt,srid)
MultiPointFromText(wkt,srid)
Constructs a MULTIPOINT using its WKT representation and SRID.
MLineFromText(wkt,srid)
MultiLineStringFromText(wkt,srid)
Constructs a MULTILINESTRING using its WKT representation and SRID.
MPolyFromText(wkt,srid)
MultiPolygonFromText(wkt,srid)
Constructs a MULTIPOLYGON using its WKT representation and SRID.
GeomCollFromText(wkt,srid)
Constructs a GEOMETRYCOLLECTION using its WKT representation and
SRID.
As an optional feature, an implementation may also support building of Polygon or
MultiPolygon values, given an arbitrary collection of possibly intersecting rings or closed
LineString values. Implementations that support this feature should include the following
functions (Note: MySQL does not yet implement these):
BdPolyFromText(multiLineStringTaggedText String, SRID Integer):Polygon
Constructs a Polygon given an arbitrary collection of closed linestrings as a
MultiLineString text representation.
BdMPolyFromText(multiLineStringTaggedText String, SRID Integer):MultiPolygon
Constructs a MultiPolygon given an arbitrary collection of closed Linestrings
as a MultiLineString text representation.
Chapter 9: Spatial Extensions in MySQL 661
9.4.2.3 Creating a Geometry Using Its WKB
MySQL provides a set of functions which take a BLOB containing Well-Known Binary
representation and, optionally, a spatial reference system identifier (SRID) as their input
parameters, and return the corresponding geometry.
GeomFromWKB can accept a WKB of any geometry type as its first argument. For construc-
tion of geometry values restricted to a particular type, an implementation also provides a
specific construction function for each type of geometry as described in the list above.
9.4.2.4 Functions To Create a Geometry Using Its WKB
GeomFromWKB(wkt,srid)
GeometryFromWKB(wkt,srid)
Constructs a geometry of any type using its WKB representation and SRID.
PointFromWKB(wkt,srid)
Constructs a POINT using its WKB representation and SRID.
LineFromWKB(wkt,srid)
LineStringFromWKB(wkt,srid)
Constructs a LINESTRING using its WKB representation and SRID.
PolyFromWKB(wkt,srid)
PolygonFromWKB(wkt,srid)
Constructs a POLYGON using its WKB representation and SRID.
MPointFromWKB(wkt,srid)
MultiPointFromWKB(wkt,srid)
Constructs a MULTIPOINT using its WKB representation and SRID.
MLineFromWKB(wkt,srid)
MultiLineStringFromWKB(wkt,srid)
Constructs a MULTILINESTRING using its WKB representation and SRID.
MPolyFromWKB(wkt,srid)
MultiPolygonFromWKB(wkt,srid)
Constructs a MULTIPOLYGON using its WKB representation and SRID.
GeomCollFromWKB(wkt,srid)
Constructs a GEOMETRYCOLLECTION using its WKB representation and
SRID.
As an optional feature, an implementation may also support the Θuilding’ of Polygon or
MultiPolygon values given an arbitrary collection of possibly intersecting rings or closed
LineString values. Implementations that support this feature should include the following
functions (Note: MySQL does not yet implement these):
BdPolyFromWKB(WKBMultiLineString Binary,SRID Integer): Polygon
Constructs a Polygon given an arbitrary collection of closed linestrings as a
MultiLineString binary representation.
BdMPolyFromWKB(WKBMultiLineString Binary, SRID Integer):MultiPolygon
Constructs a MultiPolygon given an arbitrary collection of closed linestrings as
a MultiLineString binary representation.
662 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.4.2.5 Creating a Geometry Value Using MySQL-Specific
Functions
Note: the functions listed in this section are not yet implemented in the current version.
MySQL provides a set of useful functions for creating geometry WKB representations. The
functions described in this section are MySQL extensions to the OpenGIS specifications.
The results of these functions are BLOBs containing geometry WKB representations. The
results of these functions can be substituted as first argument for GeomFromWKB() function
family.
Point(x,y)
Constructs a WKBPoint using its coordinates.
MultiPoint(WKBPoint,WKBPoint,...,WKBPoint)
Constructs a WKBMultiPoint using WKBPoints. When any argument is not
WKBPoint, the return value is NULL.
LineString(WKBPoint,WKBPoint,...,WKBPoint)
Constructs a WKBLineString from a number of WKBPoints. When any ar-
gument is not WKBPoint, the return value is NULL. When the number of
WKBPoints is less than two the return value is NULL.
MultiLineString(WKBLineString,WKBLineString,...,WKBLineString)
Constructs a WKBMultiLineString using using WKBLineStrings. When any
argument is not WKBLineString, the return value is NULL.
Polygon(WKBLineString,WKBLineString,...,WKBLineString)
Constructs a Polygon from a number of WKBLineStrings. When any argument
is not representing WKB of a LinearRing (i.e. not closed and simple LineString)
the return value is NULL.
MultiPolygon(WKBPolygon,WKBPolygon,...,WKBPolygon)
Constructs a WKBMultiPolygon from a set of WKBPolygons. When any ar-
gument is not a WKBPolygon, the rerurn value is NULL.
GeometryCollection(WKBGeometry,WKBGeometry,..,WKBGeometry)
Constucts a GeometryCollection. When any argument is not a well-formed
WKB representation of a geometry, the return value is NULL.
9.4.3 Creating Spatial Columns
MySQL provides a standard way of creating spatial columns for geometry types.
CREATE TABLE
Use the CREATE TABLE statement to create a table with a spatial column:
mysql> CREATE TABLE g1 (p1 GEOMETRY);
Query OK, 0 rows affected (0.02 sec)
mysql>
ALTER TABLE
Use the ALTER TABLE statement to add a spatial column to an existing table:
mysql> ALTER TABLE g1 ADD p2 POINT;
Query OK, 0 rows affected (0.00 sec)
Chapter 9: Spatial Extensions in MySQL 663
Records: 0 Duplicates: 0 Warnings: 0
mysql>
9.4.4 Populating Spatial Columns
After you have created spatial columns, you can populate them with your spatial data.
To populate spatially enabled columns, MySQL supports two spatial formats (described
previously), Well Known Text (WKT) and Well-Known Binary (WKB) representation.
9.4.4.1 Examples Of Using WKT Functions
INSERT INTO geom VALUES (GeomFromText(’POINT(1 1)’))
INSERT INTO geom VALUES (GeomFromText(’LINESTRING(0 0,1 1,2 2)’))
INSERT INTO geom VALUES (GeomFromText(’POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))’))
INSERT INTO geom VALUES (GeomFromText(’GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))’))
INSERT INTO geom VALUES (PointFromText(’POINT(1 1)’))
INSERT INTO geom VALUES (LineStringFromText(’LINESTRING(0 0,1 1,2 2)’))
INSERT INTO geom VALUES (PolygomFromText(’POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))’))
INSERT INTO geom VALUES (GeomCollFromText(’GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))’))
Note, a client application program which wants to use WKB representation of geometry
values, is responsible for sending correctly formed WKB in queries to server.
Inserting a Point(1,1) with binary literal syntax:
INSERT INTO geom VALUES (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
An ODBC applications can send a WKB representation, binding it as an argument of
BLOB type: INSERT INTO geom VALUES (GeomFromWKB(?));
Inserting Point(1,1) using the result of mysql_escape_string() in libmysqlclient
applications. INSERT INTO geom VALUES (GeomFromWKB(’\0\0\0\0\0\0\0\0\0?\0\0\0\0\0\0?’));
9.4.5 Fetching Spatial Data
Geometry values, previously stored in a table, can be fetched in either WKT or WKB
representation.
9.4.5.1 Fetching Spatial Data Using WKT Representation
The AsText() function provides textual access to geometry values by converting them into
a WKT string.
mysql> SELECT AsText(p1) FROM g1;
+-------------------------+
| AsText(p1) |
+-------------------------+
| POINT(1 1) |
| LINESTRING(0 0,1 1,2 2) |
+-------------------------+
2 rows in set (0.00 sec)
664 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.4.5.2 Fetching Spatial Data Using WKB Representation
The AsBinary() function provides binary access to geometry values by converting them
into a BLOB containing WKB.
SELECT AsBinary(g) FROM geom;
AsBinary() returns a BLOB with a geometry in its WKB representation.
9.5 Analysing Spatial Information
After populating spatial columns with values, you are ready to query and analyse them.
Spatial analysis can be performed using spatial functions in:
Any interactive SQL program, like mysql or MySQLCC.
Application programs in any languages supporting a MySQL client API.
MySQL provides a set of functions to perform various operations on spatial data. These
functions can be labeled into four major groups according to the type of operation they
perform:
Functions that convert geometries between various formats.
Functions that describe qualitative or quantitative properties of a geometry.
Functions that describe relations between two geometries.
Functions that create new geometries from existing ones.
9.5.1 Functions To Convert Geometries Between Different
Formats
As discussed (see hundefinedi[GIS MySQL spatial data types], page hundefinedi, see hun-
definedi[GIS populating spatial columns], page hundefinedi), MySQL understands Well-
Known Text (WKT) and Well-Known Binary (WKB) geometry representations through
support of these functions:
GeomFromWKT(string wkt [,integer srid]): geometry
Converts WKT representation into internal geometry format. A number of
type-specific functions are also supported.
GeomFromWKB(binary wkb [,integer srid]): geometry
Converts WKB representation into internal geometry format A number of type-
specific functions are also supported.
AsWKT(geometry g): string
Converts internal geometry format into WKT representation.
AsWKB(geometry g): binary
Converts internal geometry format into WKB representation.
mysql> SELECT AsText(GeomFromText(’LineString(1 1,2 2,3 3)’));
+-------------------------------------------------+
| AsText(GeomFromText(’LineString(1 1,2 2,3 3)’)) |
+-------------------------------------------------+
| LINESTRING(1 1,2 2,3 3) |
+-------------------------------------------------+
Chapter 9: Spatial Extensions in MySQL 665
9.5.2 Functions To Analyse Geometry Properties
Functions that belong to this group take a geometry value as their argument and return some
quantitive or qualitive property of this geometry. Some functions restrict their argument
type.
9.5.2.1 Basic Functions To Analyse Geometry Properties
These functions don’t restrict their argument and accept a geometry of any type.
GeometryType(geometry g):string
Returns as string the name of the geometry subtype of which this geometry
instance is a member.
mysql> SELECT GeometryType(GeomFromText(’POINT(1 1)’));
+------------------------------------------+
| GeometryType(GeomFromText(’POINT(1 1)’)) |
+------------------------------------------+
| POINT |
+------------------------------------------+
Dimension(geometry g):integer
The inherent dimension of this Geometry object, which can be -1, 0, 1 or 2.
mysql> SELECT Dimension(GeomFromText(’LineString(1 1,2 2)’));
+------------------------------------------------+
| Dimension(GeomFromText(’LineString(1 1,2 2)’)) |
+------------------------------------------------+
| 1 |
+------------------------------------------------+
SRID(geometry g):integer
Returns the Spatial Reference System ID for this geometry.
mysql> SELECT SRID(GeomFromText(’LineString(1 1,2 2)’,101));
+-----------------------------------------------+
| SRID(GeomFromText(’LineString(1 1,2 2)’,101)) |
+-----------------------------------------------+
| 101 |
+-----------------------------------------------+
Envelope(geometry g):geometry
The Minimum Bounding Rectangle (MBR) for this geometry, returned as a
polygon. The polygon is defined by the corner points of the bounding box:
POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
mysql> SELECT AsText(Envelope(GeomFromText(’LineString(1 1,2 2)’,101)));
+-----------------------------------------------------------+
| AsText(Envelope(GeomFromText(’LineString(1 1,2 2)’,101))) |
+-----------------------------------------------------------+
| POLYGON((1 1,2 1,2 2,1 2,1 1)) |
+-----------------------------------------------------------+
Note: MySQL does not yet implement the following functions:
666 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Boundary(g:Geometry):Geometry
Returns the closure of the combinatorial boundary of this Geometry.
IsEmpty(geometry g):Integer
Returns 1 (TRUE) if this Geometry is the empty geometry. If true, then this
Geometry represents the empty point set.
IsSimple(geometry g):Integer
Returns 1 (TRUE) if this Geometry has no anomalous geometric points, such as
self intersection or self tangency. The description of each instantiable geometric
class includes the specific conditions that cause an instance of that class to be
classified as not simple.
9.5.2.2 Functions To Analyse Point Properties
X(point p):Double
The x-coordinate value for this point.
mysql> SELECT X(GeomFromText(’Point(56.7 53.34)’,101));
+------------------------------------------+
| X(GeomFromText(’Point(56.7 53.34)’,101)) |
+------------------------------------------+
| 56.7 |
+------------------------------------------+
Y(point p):Double
The y-coordinate value for this point
mysql> SELECT Y(GeomFromText(’Point(56.7 53.34)’,101));
+------------------------------------------+
| Y(GeomFromText(’Point(56.7 53.34)’,101)) |
+------------------------------------------+
| 53.34 |
+------------------------------------------+
9.5.2.3 Functions To Analyse LineString Properties
StartPoint(LineString l):Point
The start point of this LineString.
mysql> SELECT AsText(StartPoint(GeomFromText(’LineString(1 1,2 2,3 3)’)));
+------------------------------------------------------------
-+
| AsText(StartPoint(GeomFromText(’LineString(1 1,2 2,3 3)’))) |
+------------------------------------------------------------
-+
| POINT(1 1) |
+------------------------------------------------------------
-+
EndPoint(LineString l):Point
The end point of this LineString.
Chapter 9: Spatial Extensions in MySQL 667
mysql> SELECT AsText(EndPoint(GeomFromText(’LineString(1 1,2 2,3 3)’)));
+------------------------------------------------------------
+
| AsText(EndPoint(GeomFromText(’LineString(1 1,2 2,3 3)’))) |
+------------------------------------------------------------
+
| POINT(3 3) |
+------------------------------------------------------------
+
PointN(LineString l,integer n):Point
Returns the specified point N in this Linestring.
mysql> SELECT AsText(PointN(GeomFromText(’LineString(1 1,2 2,3 3)’),2));
+-----------------------------------------------------------+
| AsText(PointN(GeomFromText(’LineString(1 1,2 2,3 3)’),2)) |
+-----------------------------------------------------------+
| POINT(2 2) |
+-----------------------------------------------------------+
GLength(LineString l):Double
The length of this LineString in its associated spatial reference.
mysql> SELECT GLength(GeomFromText(’LineString(1 1,2 2,3 3)’));
+--------------------------------------------------+
| GLength(GeomFromText(’LineString(1 1,2 2,3 3)’)) |
+--------------------------------------------------+
| 2.8284271247462 |
+--------------------------------------------------+
NumPoints(LineString l):Integer
The number of points in this LineString.
mysql> SELECT NumPoints(GeomFromText(’LineString(1 1,2 2,3 3)’));
+----------------------------------------------------+
| NumPoints(GeomFromText(’LineString(1 1,2 2,3 3)’)) |
+----------------------------------------------------+
| 3 |
+----------------------------------------------------+
Note: MySQL does not yet implement the following functions:
IsRing(LineString l):Integer
Returns 1 (TRUE) if this LineString is closed (StartPoint ( ) = EndPoint ( ))
and this LineString is simple (does not pass through the same point more than
once).
IsClosed(LineString l):Integer
Returns 1 (TRUE) if this LineString is closed (StartPoint() == EndPoint()).
mysql> SELECT IsClosed(GeomFromText(’LineString(1 1,2 2,3 3)’));
+---------------------------------------------------+
| IsClosed(GeomFromText(’LineString(1 1,2 2,3 3)’)) |
+---------------------------------------------------+
| 0 |
+---------------------------------------------------+
668 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.5.2.4 Functions To Analyse MultiLineString Properties
GLength(MultiLineString m):Double
The Length of this MultiLineString which is equal to the sum of the lengths of
the elements.
mysql> SELECT GLength(GeomFromText(’MultiLineString((1 1,2 2,3 3),(4 4,5 5))’));
+------------------------------------------------------------
-------+
| GLength(GeomFromText(’MultiLineString((1 1,2 2,3 3),(4 4,5 5))’)) |
+------------------------------------------------------------
-------+
| 4.2426406871193 |
+------------------------------------------------------------
-------+
IsClosed(MultiLineString m):Integer
Returns 1 (TRUE) if this MultiLineString is closed (StartPoint() = EndPoint()
for each LineString in this MultiLineString).
mysql> SELECT IsClosed(GeomFromText(’MultiLineString((1 1,2 2,3 3),(4 4,5 5))’));
+------------------------------------------------------------
--------+
| IsClosed(GeomFromText(’MultiLineString((1 1,2 2,3 3),(4 4,5 5))’)) |
+------------------------------------------------------------
--------+
| 0 |
+------------------------------------------------------------
--------+
9.5.2.5 Functions To Analyse Polygon Properties
Area(Polygon p):Double
The area of this Polygon, as measured in the spatial reference system of this
Polygon.
mysql> SELECT Area(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’));
+------------------------------------------------------------
----------------+
| Area(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’)) |
+------------------------------------------------------------
----------------+
| 8 |
+------------------------------------------------------------
----------------+
NumInteriorRings(Polygon p):Integer
Returns the number of interior rings in this Polygon.
mysql> SELECT NumInteriorRings(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’));
+------------------------------------------------------------
----------------------------+
| NumInteriorRings(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’)) |
Chapter 9: Spatial Extensions in MySQL 669
+------------------------------------------------------------
----------------------------+
| 1 |
+------------------------------------------------------------
----------------------------+
1 row in set (0.00 sec)
ExteriorRing(Polygon p):LineString
Returns the exterior ring of this Polygon as a LineString.
mysql> SELECT AsText(ExteriorRing(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’)));
+------------------------------------------------------------
--------------------------------+
| AsText(ExteriorRing(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’))) |
+------------------------------------------------------------
--------------------------------+
| LINESTRING(0 0,0 3,3 3,3 0,0 0) |
+------------------------------------------------------------
--------------------------------+
InteriorRingN(Polygon p, Integer N):LineString
Returns the N-th interior ring for this Polygon as a LineString.
mysql> SELECT AsText(InteriorRingN(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’),1));
+------------------------------------------------------------
-----------------------------------+
| AsText(InteriorRingN(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))’),1)) |
+------------------------------------------------------------
-----------------------------------+
| LINESTRING(1 1,1 2,2 2,2 1,1 1) |
+------------------------------------------------------------
-----------------------------------+
Note: MySQL does not yet implement the following functions:
Centroid(Polygon p):Point
The mathematical centroid for this Polygon as a Point. The result is not guar-
anteed to be on this Polygon.
PointOnSurface(p:Polygon):Point
A point guaranteed to be on this Polygon.
9.5.2.6 Functions To Analyse MultiPolygon Properties
Area(MultiPolygon m):Double
The area of this MultiPolygon, as measured in the spatial reference system of
this MultiPolygon.
mysql> SELECT Area(GeomFromText(’MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))’));
+------------------------------------------------------------
-----------------------+
| Area(GeomFromText(’MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))’)) |
+------------------------------------------------------------
-----------------------+
670 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| 8 |
+------------------------------------------------------------
-----------------------+
Note: MySQL does not yet implement the following functions:
Centroid(MultyPolygon p):Point
The mathematical centroid for this MultiPolygon as a Point. The result is not
guaranteed to be on this MultiPolygon.
PointOnSurface(MultiPolygon m):Point
A Point guaranteed to be on this MultiPolygon.
9.5.2.7 Functions To Analyse GeometryCollection Properties
NumGeometries(GeometryCollection g):Integer
Returns the number of geometries in this GeometryCollection.
mysql> SELECT NumGeometries(GeomFromText(’GeometryCollection(Point(1 1),LineString(2 2, 3 3))’));
+------------------------------------------------------------
------------------------+
| NumGeometries(GeomFromText(’GeometryCollection(Point(1 1),LineString(2 2, 3 3))’)) |
+------------------------------------------------------------
------------------------+
| 2 |
+------------------------------------------------------------
------------------------+
GeometryN(GeometryCollection g,integer N):Geometry
Returns the N-th geometry in this GeometryCollection.
mysql> SELECT AsText(GeometryN(GeomFromText(’GeometryCollection(Point(1 1),LineString(2 2, 3 3))’),1));
+------------------------------------------------------------
------------------------------+
| AsText(GeometryN(GeomFromText(’GeometryCollection(Point(1 1),LineString(2 2, 3 3))’),1)) |
+------------------------------------------------------------
------------------------------+
| POINT(1 1) |
+------------------------------------------------------------
------------------------------+
Note: Functions for specific geometry type return NULL if the passed geometry is of wrong
geometry type. For example Area() returns NULL if object type is neither Polygon nor
MultiPolygon.
9.5.3 Functions That Create New Geometries From Existing Ones
9.5.3.1 Geometry Properties That Produce New Geometries
In the section (see hundefinedi[GIS functions to analyse geometry properties], page hunde-
finedi), we’ve already discussed some functions that can construct new geometries from the
exising ones:
Chapter 9: Spatial Extensions in MySQL 671
Envelope(geometry g):geometry
StartPoint(LineString l):Point
EndPoint(LineString l):Point
PointN(LineString l,integer n):Point
ExteriorRing(Polygon p):LineString
InteriorRingN(Polygon p, Integer N):LineString
GeometryN(GeometryCollection g,integer N):Geometry
9.5.3.2 Spatial Operators
OpenGIS proposes a number of other functions that can produce geometries. They are
designed to implement Spatial Operators.
Note: These functions are not yet implemented. They should appear in the future releases.
Intersection(Geometry g1,g2):Geometry
A geometry that represents the point set intersection of g1 with g2.
Union(Geometry g1,g2):Geometry
A geometry that represents the point set union of g1 with g2.
Difference(Geometry g1,g2):Geometry
A geometry that represents the point set difference of g1 with g2.
SymDifference(Geometry g1,g2):Geometry
A geometry that represents the point set symmetric difference of g1 with g2.
Buffer(Geometry g, double d):Geometry
A geometry that represents all points whose distance from gis less than or
equal to distance of d.
ConvexHull(Geometry g):Geometry
A geometry that represents the convex hull of g.
9.5.4 Functions For Testing Spatial Relations Between Geometric
Objects
The functions described in this sections take two geometries as input parameters and return
a qualitive or quantitive relation between them.
9.5.5 Relations On Geometry Minimal Bounding Rectangles
(MBR)
The current release provides some functions that can test relations between mininal bound-
ing rectangles of two geometries. They include:
MBRContains(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangle of geom1 contains the Minimum
Bounding Rectangle of geom2. Otherwise, 0 is returned.
672 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql> SELECT MBRContains(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0))’),GeomFromText(’Point(1 1)’));
+------------------------------------------------------------
----------------------------+
| MBRContains(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0))’),GeomFromText(’Point(1 1)’)) |
+------------------------------------------------------------
----------------------------+
| 1 |
+------------------------------------------------------------
----------------------------+
MBRWithin(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangle of geom1 is within the Minimum
Bounding Rectangle of geom2. Otherwise, 0 is returned.
mysql> SELECT MBRWithin(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0))’),GeomFromText(’Polygon((0 0,0 5,5 5,5 0,0 0))’));
+------------------------------------------------------------
----------------------------------------------+
| MBRWithin(GeomFromText(’Polygon((0 0,0 3,3 3,3 0,0 0))’),GeomFromText(’Polygon((0 0,0 5,5 5,5 0,0 0))’)) |
+------------------------------------------------------------
----------------------------------------------+
| 1 |
+------------------------------------------------------------
----------------------------------------------+
MBRDisjoint(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangles of the two geometries do not
intersect. Otherwise, 0 is returned.
MBREqual(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangles of the two geometries are the
same. Otherwise, 0 is returned.
MBRIntersects(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangles of the two geometries intersect.
Otherwise, 0 is returned.
MBROverlaps(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangles of the two geometries overlaps.
Otherwise, 0 is returned.
MBRTouches(geom1,geom2)
Returns 1 if the Minimum Bounding Rectangles of the two geometries overlaps.
Otherwise, 0 is returned.
9.5.6 Functions That Test Spatial Relationships Between
Geometries
Note: The functions given in the list below are not yet implemented. These functions will
provide full (not MBR-based only) support for spatial analysis.
Contains(geom1,geom2)
Returns 1 if geom1 completely contains geom2, otherwise 0 is returned.
Chapter 9: Spatial Extensions in MySQL 673
Crosses(geom1,geom2)
Returns 1 if geom1 spatially crosses geom2. If geom1 is a polygon or a multipoly-
gon, NULL is returned. If geom2 is a point or a multipoint, NULL is returned.
Otherwise 0 is returned.
The term spatially crosses denotes a spatial relation when two given geome-
tries intersect, and their intersection results in a geometry that has a dimension
that is one less than the maximum dimension of the two given geometries, and
the intersection is not equal to any of the two given geometries.
Disjoint(geom1,geom2)
Returns 1 if geom1 is spatially disjoint from geom2, i.e. if given geometries do
not intersect. Otherwise, 0 is returned.
Equal(geom1,geom2)
Returns 1 if geom1 is spatially equal to geom2, otherwise 0 is returned.
Intersects(geom1,geom2)
Returns 1 if geom1 spatially intersects geom2, otherwise 0 is returned.
Overlaps(geom1,geom2)
Returns 1 if geom1 spatially overlaps geom2, otherwise, 0 is returned. Term
spatially overlaps is used if two geometries intersect and their intersection
results in a geometry of the same dimension but not equal to either of the given
geometries.
Touches(geom1,geom2)
Returns 1 if geom1 spatially touches geom2, otherwise, 0 is returned. Two
geometries spatially touch if the interior of both geometries do not intersect,
but the boundary of one of the geometries intersects either the boundary or the
interioir of the geometries.
Within(geom1,geom2)
Returns 1 if geom1 is spatially within geom2, otherwise, 0 is returned.
Distance(geom1:Geometry,geom2:Geometry):Double
The shortest distance between any two points in the two geometries.
9.6 Optimising Spatial Analysis
It is known that search operations in usual databases can be optimised using indexes. This
is still true for spatial databases. With help of great variery of multi-dimensional indexing
methods which have already been designed in the world, it’s possible to optimise spatial
searches, the most typical of which are:
A point query. Searching for all objects that contain a given point.
A region query. Searching for all objects that overlap a given region.
MySQL utilises R-Trees with quadratic splitting to index spatial columns. A spatial
index is built using the MBR of a geometry. For most geometries, the MBR is a minimum
rectangle that surrounds the geometries. For a horizontal or a vertical linestring as well as for
a point, the MBR is a degenerated rectangle, into the linestring and the point respectively.
674 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
9.6.1 Creating Spatial Indexes
MySQL can create spatial indexes in the same way it can create regular indexes. The
normal syntax for creating indexes is extended with the SPATIAL keyword:
With CREATE TABLE:
CREATE TABLE g (g GEOMETRY NOT NULL, SPATIAL INDEX(g));
With CREATE INDEX:
CREATE SPATIAL INDEX sp_index ON g (g);
With ALTER TABLE:
ALTER TABLE g (ADD SPATIAL KEY(g));
Let’s say we have a database with more than 32000 geometries. Geometries are stored in
the field gof type GEOMETRY. The table also has a field fid, storing object IDs, with the
AUTO INCREMENT attribute.
mysql> SHOW FIELDS FROM g;
+-------+----------+-----------+------+-----+---------+----------------
+
| Field | Type | Collation | Null | Key | Default | Extra |
+-------+----------+-----------+------+-----+---------+----------------
+
| fid | int(11) | binary | | PRI | NULL | auto_increment |
| g | geometry | binary | | | | |
+-------+----------+-----------+------+-----+---------+----------------
+
2 rows in set (0.00 sec)
mysql> SELECT COUNT(*) FROM g;
+----------+
| count(*) |
+----------+
| 32376 |
+----------+
1 row in set (0.00 sec)
Let’s add a spatial index:
mysql> ALTER TABLE g ADD SPATIAL KEY(g);
Query OK, 32376 rows affected (4.05 sec)
Records: 32376 Duplicates: 0 Warnings: 0
9.6.2 Using a Spatial Index
The optimiser investigates if available spatial indexes can be involved in the search whenever
a query with a function like MBRContains() or MBRWithin() in the WHERE clause is
executed.
For example, let’s say we want to find all objects that are in the given rectangle:
mysql> SELECT fid,AsText(g) FROM g WHERE
mysql> MBRContains(GeomFromText(’Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))’),g);
+-----+----------------------------------------------------------------
-------------+
Chapter 9: Spatial Extensions in MySQL 675
| fid | AsText(g) |
+-----+----------------------------------------------------------------
-------------+
| 21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8) |
| 22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4) |
| 23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2) |
| 24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823) |
| 25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
| 26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2) |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
| 1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2) |
| 2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121) |
| 3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113) |
| 4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6) |
| 5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2) |
| 6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077) |
| 7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4) |
| 10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019) |
| 11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8) |
| 13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8) |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134) |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4) |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001) |
+-----+----------------------------------------------------------------
-------------+
20 rows in set (0.00 sec)
Now let’s check the way this query is executed, using EXPLAIN:
mysql> EXPLAIN SELECT fid,AsText(g) FROM g WHERE
mysql> MBRContains(GeomFromText(’Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))’),g);
+----+-------------+-------+-------+---------------+------+---------+--
----+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+--
----+------+-------------+
| 1 | SIMPLE | g | range | g | g | 32 | NULL | 50 | Using where |
+----+-------------+-------+-------+---------------+------+---------+--
----+------+-------------+
1 row in set (0.00 sec)
Now let’s check what would happen if we didn’t have a spatial index:
mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText(’Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))’),g);
+----+-------------+-------+------+---------------+------+---------+---
---+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+---
---+-------+-------------+
| 1 | SIMPLE | g | ALL | NULL | NULL | NULL | NULL | 32376 | Using where |
676 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
+----+-------------+-------+------+---------------+------+---------+---
---+-------+-------------+
1 row in set (0.00 sec)
Lets execute the above query, ignoring the spatial key we have:
mysql> SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText(’Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))’),g);
+-----+----------------------------------------------------------------
-------------+
| fid | AsText(g) |
+-----+----------------------------------------------------------------
-------------+
| 1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2) |
| 2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121) |
| 3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113) |
| 4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6) |
| 5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2) |
| 6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077) |
| 7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4) |
| 10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019) |
| 11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8) |
| 13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8) |
| 21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8) |
| 22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4) |
| 23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2) |
| 24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823) |
| 25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
| 26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2) |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134) |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4) |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001) |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
+-----+----------------------------------------------------------------
-------------+
20 rows in set (0.46 sec)
The execution time for this query rises from 0.00 seconds to 0.46 seconds, when the index
is not used.
In the future releases, spatial indexes will also be used for optimising other functions. See
hundefinedi[GIS functions for testing spatial relations between geometric objects], page hun-
definedi.
9.7 MySQL Conformance And Compatibility
Chapter 9: Spatial Extensions in MySQL 677
9.7.1 GIS Features That Are Not Yet Implemented
Additional Metadata Views
OpenGIS specifications propose several additional metadata views. For exam-
ple, a system view named GEOMETRY COLUMNS contains a description of
geometry columns, one row for each geometry column in the database.
Functions to add/drop spatial columns
OpenGIS assumes that columns can be added/dropped using
AddGeometryColumn() and DropGeometryColumn() functions corre-
spondently. In MySQL this is to be done using the regular ALTER TABLE
command instead.
Spatial Reference Systems and their IDs (SRIDs) related things:
Functions like Length() and Area() assume planar coordinate system.
All objects are currently considered to be in the same planar coordinate
system.
Function Length() on LineString and MultiLineString currently should be called as
GLength().
The problem is that it conflicts with a usual function Length() and sometimes
it’s not possible to distinguish if the function was called in the textual or spatial
context. We need either to solve this somehow, or decide on another function
name.
678 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
10 Extending MySQL
10.1 MySQL Internals
This chapter describes a lot of things that you need to know when working on the MySQL
code. If you plan to contribute to MySQL development, want to have access to the bleeding-
edge in-between versions code, or just want to keep track of development, follow the in-
structions in hundefinedi[Installing source tree], page hundefinedi. If you are interested
in MySQL internals, you should also subscribe to our internals mailing list. This list is
relatively low traffic. For details on how to subscribe, please see list-snt [Mailing-list], page
list-pg. All developers at MySQL AB are on the internals list and we help other people
who are working on the MySQL code. Feel free to use this list both to ask questions about
the code and to send patches that you would like to contribute to the MySQL project!
10.1.1 MySQL Threads
The MySQL server creates the following threads:
The TCP/IP connection thread handles all connection requests and creates a new
dedicated thread to handle the authentication and SQL query processing for each con-
nection.
On Windows NT there is a named pipe handler thread that does the same work as the
TCP/IP connection thread on named pipe connect requests.
The signal thread handles all signals. This thread also normally handles alarms and
calls process_alarm() to force timeouts on connections that have been idle too long.
If mysqld is compiled with -DUSE_ALARM_THREAD, a dedicated thread that handles
alarms is created. This is only used on some systems where there are problems with
sigwait() or if one wants to use the thr_alarm() code in ones application without a
dedicated signal handling thread.
If one uses the --flush_time=# option, a dedicated thread is created to flush all tables
at the given interval.
Every connection has its own thread.
Every different table on which one uses INSERT DELAYED gets its own thread.
If you use --master-host, a slave replication thread will be started to read and apply
updates from the master.
mysqladmin processlist only shows the connection, INSERT DELAYED, and replication
threads.
10.1.2 MySQL Test Suite
Until recently, our main full-coverage test suite was based on proprietary customer data
and for that reason has not been publicly available. The only publicly available part of
our testing process consisted of the crash-me test, a Perl DBI/DBD benchmark found
in the sql-bench directory, and miscellaneous tests located in tests directory. The lack
of a standardised publicly available test suite has made it difficult for our users, as well
Chapter 10: Extending MySQL 679
developers, to do regression tests on the MySQL code. To address this problem, we have
created a new test system that is included in the source and binary distributions starting
in Version 3.23.29.
The current set of test cases doesn’t test everything in MySQL, but it should catch most
obvious bugs in the SQL processing code, OS/library issues, and is quite thorough in testing
replication. Our eventual goal is to have the tests cover 100% of the code. We welcome
contributions to our test suite. You may especially want to contribute tests that examine
the functionality critical to your system, as this will ensure that all future MySQL releases
will work well with your applications.
10.1.2.1 Running the MySQL Test Suite
The test system consist of a test language interpreter (mysqltest), a shell script to run
all tests(mysql-test-run), the actual test cases written in a special test language, and
their expected results. To run the test suite on your system after a build, type make
test or mysql-test/mysql-test-run from the source root. If you have installed a binary
distribution, cd to the install root (eg. /usr/local/mysql), and do scripts/mysql-test-
run. All tests should succeed. If not, you should try to find out why and report the problem
if this is a bug in MySQL. See hundefinedi[Reporting mysqltest bugs], page hundefinedi.
If you have a copy of mysqld running on the machine where you want to run the test suite
you do not have to stop it, as long as it is not using ports 9306 and 9307. If one of those
ports is taken, you should edit mysql-test-run and change the values of the master and/or
slave port to one that is available.
You can run one individual test case with mysql-test/mysql-test-run test_name.
If one test fails, you should test running mysql-test-run with the --force option to check
if any other tests fails.
10.1.2.2 Extending the MySQL Test Suite
You can use the mysqltest language to write your own test cases. Unfortunately, we have
not yet written full documentation for it. You can, however, look at our current test cases
and use them as an example. The following points should help you get started:
The tests are located in mysql-test/t/*.test
A test case consists of ;terminated statements and is similar to the input of mysql
command-line client. A statement by default is a query to be sent to MySQL server,
unless it is recognised as internal command (eg. sleep).
All queries that produce resultse.g., SELECT,SHOW,EXPLAIN, etc., must be preceded
with @/path/to/result/file. The file must contain the expected results. An easy
way to generate the result file is to run mysqltest -r < t/test-case-name.test from
mysql-test directory, and then edit the generated result files, if needed, to adjust them
to the expected output. In that case, be very careful about not adding or deleting any
invisible characters - make sure to only change the text and/or delete lines. If you
have to insert a line, make sure the fields are separated with a hard tab, and there is
a hard tab at the end. You may want to use od -c to make sure your text editor has
not messed anything up during edit. We, of course, hope that you will never have to
edit the output of mysqltest -r as you only have to do it when you find a bug.
680 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
To be consistent with our setup, you should put your result files in mysql-test/r
directory and name them test_name.result. If the test produces more than one
result, you should use test_name.a.result,test_name.b.result, etc.
If a statement returns an error, you should on the line before the statement specify with
the --error error-number. The error number can be a list of possible error numbers
separated with ’,’.
If you are writing a replication test case, you should on the first line of the test file,
put source include/master-slave.inc;. To switch between master and slave, use
connection master; and connection slave;. If you need to do something on an al-
ternate connection, you can do connection master1; for the master, and connection
slave1; for the slave.
If you need to do something in a loop, you can use something like this:
let $1=1000;
while ($1)
{
# do your queries here
dec $1;
}
To sleep between queries, use the sleep command. It supports fractions of a second,
so you can do sleep 1.3;, for example, to sleep 1.3 seconds.
To run the slave with additional options for your test case, put them in the command-
line format in mysql-test/t/test_name-slave.opt. For the master, put them in
mysql-test/t/test_name-master.opt.
If you have a question about the test suite, or have a test case to contribute, e-mail
to internals@lists.mysql.com. As the list does not accept attachments, you should
ftp all the relevant files to: ftp://support.mysql.com/pub/mysql/Incoming/
10.1.2.3 Reporting Bugs in the MySQL Test Suite
If your MySQL version doesn’t pass the test suite you should do the following:
Don’t send a bug report before you have found out as much as possible of what when
wrong! When you do it, please use the mysqlbug script so that we can get information
about your system and MySQL version. See hundefinedi[Bug reports], page hundefinedi.
Make sure to include the output of mysql-test-run, as well as contents of all .reject
files in mysql-test/r directory.
If a test in the test suite fails, check if the test fails also when run by its own:
cd mysql-test
mysql-test-run --local test-name
If this fails, then you should configure MySQL with --with-debug and run
mysql-test-run with the --debug option. If this also fails send the trace file
var/tmp/master.trace’ to ftp://support.mysql.com/pub/mysql/secret so that we
can examine it. Please remember to also include a full description of your system, the
version of the mysqld binary and how you compiled it.
Try also to run mysql-test-run with the --force option to see if there is any other
test that fails.
Chapter 10: Extending MySQL 681
If you have compiled MySQL yourself, check our manual for how to compile MySQL
on your platform or, preferable, use one of the binaries we have compiled for you at
http://www.mysql.com/downloads/. All our standard binaries should pass the test
suite !
If you get an error, like Result length mismatch or Result content mismatch it
means that the output of the test didn’t match exactly the expected output. This
could be a bug in MySQL or that your mysqld version produces slight different results
under some circumstances.
Failed test results are put in a file with the same base name as the result file with the
.reject extension. If your test case is failing, you should do a diff on the two files. If
you cannot see how they are different, examine both with od -c and also check their
lengths.
If a test fails totally, you should check the logs file in the mysql-test/var/log directory
for hints of what went wrong.
If you have compiled MySQL with debugging you can try to debug this by running
mysql-test-run with the --gdb and/or --debug options. See hundefinedi[Making
trace files], page hundefinedi.
If you have not compiled MySQL for debugging you should probably do that. Just
specify the --with-debug options to configure! See hundefinedi[Installing source],
page hundefinedi.
10.2 Adding New Functions to MySQL
There are two ways to add new functions to MySQL:
You can add the function through the user-definable function (UDF) interface. User-
definable functions are added and removed dynamically using the CREATE FUNCTION
and DROP FUNCTION statements. See hundefinedi[CREATE FUNCTION], page hundefinedi.
You can add the function as a native (built in) MySQL function. Native functions are
compiled into the mysqld server and become available on a permanent basis.
Each method has advantages and disadvantages:
If you write a user-definable function, you must install the object file in addition to the
server itself. If you compile your function into the server, you don’t need to do that.
You can add UDFs to a binary MySQL distribution. Native functions require you to
modify a source distribution.
If you upgrade your MySQL distribution, you can continue to use your previously
installed UDFs. For native functions, you must repeat your modifications each time
you upgrade.
Whichever method you use to add new functions, they may be used just like native functions
such as ABS() or SOUNDEX().
10.2.1 CREATE FUNCTION/DROP FUNCTION Syntax
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER}
SONAME shared_library_name
682 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
DROP FUNCTION function_name
A user-definable function (UDF) is a way to extend MySQL with a new function that works
like native (built in) MySQL functions such as ABS() and CONCAT().
AGGREGATE is a new option for MySQL Version 3.23. An AGGREGATE function works exactly
like a native MySQL GROUP function like SUM or COUNT().
CREATE FUNCTION saves the function’s name, type, and shared library name in the
mysql.func system table. You must have the INSERT and DELETE privileges for the mysql
database to create and drop functions.
All active functions are reloaded each time the server starts, unless you start mysqld with
the --skip-grant-tables option. In this case, UDF initialisation is skipped and UDFs are
unavailable. (An active function is one that has been loaded with CREATE FUNCTION and
not removed with DROP FUNCTION.)
For instructions on writing user-definable functions, see hundefinedi[Adding functions],
page hundefinedi. For the UDF mechanism to work, functions must be written in C or C++,
your operating system must support dynamic loading and you must have compiled mysqld
dynamically (not statically).
Note that to make AGGREGATE work, you must have a mysql.func table that contains the
column type. If this is not the case, you should run the script mysql_fix_privilege_
tables to get this fixed.
10.2.2 Adding a New User-definable Function
For the UDF mechanism to work, functions must be written in C or C++ and your operating
system must support dynamic loading. The MySQL source distribution includes a file
sql/udf_example.cc’ that defines 5 new functions. Consult this file to see how UDF
calling conventions work.
For mysqld to be able to use UDF functions, you should configure MySQL with --with-
mysqld-ldflags=-rdynamic The reason is that to on many platforms (including Linux)
you can load a dynamic library (with dlopen()) from a static linked program, which
you would get if you are using --with-mysqld-ldflags=-all-static If you want to
use an UDF that needs to access symbols from mysqld (like the methaphone example in
sql/udf_example.cc’ that uses default_charset_info), you must link the program with
-rdynamic (see man dlopen).
For each function that you want to use in SQL statements, you should define corresponding
C (or C++) functions. In the discussion below, the name “xxx” is used for an example
function name. To distinguish between SQL and C/C++ usage, XXX() (uppercase) indicates
a SQL function call, and xxx() (lowercase) indicates a C/C++ function call.
The C/C++ functions that you write to implement the interface for XXX() are:
xxx() (required)
The main function. This is where the function result is computed. The corre-
spondence between the SQL type and return type of your C/C++ function is
shown here:
SQL type C/C++
type
Chapter 10: Extending MySQL 683
STRING char *
INTEGER long long
REAL double
xxx_init() (optional)
The initialisation function for xxx(). It can be used to:
Check the number of arguments to XXX().
Check that the arguments are of a required type or, alternatively, tell
MySQL to coerce arguments to the types you want when the main function
is called.
Allocate any memory required by the main function.
Specify the maximum length of the result.
Specify (for REAL functions) the maximum number of decimals.
Specify whether the result can be NULL.
xxx_deinit() (optional)
The deinitialisation function for xxx(). It should deallocate any memory allo-
cated by the initialisation function.
When a SQL statement invokes XXX(), MySQL calls the initialisation function xxx_init()
to let it perform any required setup, such as argument checking or memory allocation. If
xxx_init() returns an error, the SQL statement is aborted with an error message and the
main and deinitialisation functions are not called. Otherwise, the main function xxx() is
called once for each row. After all rows have been processed, the deinitialisation function
xxx_deinit() is called so it can perform any required cleanup.
For aggregate functions (like SUM()), you must also provide the following functions:
xxx_reset() (required)
Reset sum and insert the argument as the initial value for a new group.
xxx_add() (required)
Add the argument to the old sum.
When using aggregate UDF functions MySQL works the following way:
1. Call xxx_init() to let the aggregate function allocate the memory it will need to store
results.
2. Sort the table according to the GROUP BY expression.
3. For the first row in a new group, call the xxx_reset() function.
4. For each new row that belongs in the same group, call the xxx_add() function.
5. When the group changes or after the last row has been processed, call xxx() to get the
result for the aggregate.
6. Repeat 3-5 until all rows has been processed
7. Call xxx_deinit() to let the UDF free any memory it has allocated.
All functions must be thread-safe (not just the main function, but the initialisation and
deinitialisation functions as well). This means that you are not allowed to allocate any
global or static variables that change! If you need memory, you should allocate it in xxx_
init() and free it in xxx_deinit().
684 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
10.2.2.1 UDF Calling Sequences for simple functions
The main function should be declared as shown here. Note that the return type and
parameters differ, depending on whether you will declare the SQL function XXX() to return
STRING,INTEGER, or REAL in the CREATE FUNCTION statement:
For STRING functions:
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error);
For INTEGER functions:
long long xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
For REAL functions:
double xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
The initialisation and deinitialisation functions are declared like this:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void xxx_deinit(UDF_INIT *initid);
The initid parameter is passed to all three functions. It points to a UDF_INIT structure that
is used to communicate information between functions. The UDF_INIT structure members
are listed below. The initialisation function should fill in any members that it wishes to
change. (To use the default for a member, leave it unchanged.):
my_bool maybe_null
xxx_init() should set maybe_null to 1if xxx() can return NULL. The default
value is 1if any of the arguments are declared maybe_null.
unsigned int decimals
Number of decimals. The default value is the maximum number of decimals
in the arguments passed to the main function. (For example, if the function
is passed 1.34,1.345, and 1.3, the default would be 3, because 1.345 has 3
decimals.
unsigned int max_length
The maximum length of the string result. The default value differs depending
on the result type of the function. For string functions, the default is the length
of the longest argument. For integer functions, the default is 21 digits. For real
functions, the default is 13 plus the number of decimals indicated by initid-
>decimals. (For numeric functions, the length includes any sign or decimal
point characters.)
If you want to return a blob, you can set this to 65K or 16M; this memory is
not allocated but used to decide which column type to use if there is a need to
temporary store the data.
char *ptr A pointer that the function can use for its own purposes. For example, functions
can use initid->ptr to communicate allocated memory between functions. In
xxx_init(), allocate the memory and assign it to this pointer:
Chapter 10: Extending MySQL 685
initid->ptr = allocated_memory;
In xxx() and xxx_deinit(), refer to initid->ptr to use or deallocate the
memory.
10.2.2.2 UDF Calling Sequences for aggregate functions
Here follows a description of the different functions you need to define when you want to
create an aggregate UDF function.
char *xxx_reset(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
This function is called when MySQL finds the first row in a new group. In the function you
should reset any internal summary variables and then set the given argument as the first
argument in the group.
In many cases this is implemented internally by reseting all variables and then calling xxx_
add().
char *xxx_add(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
This function is called for all rows that belongs to the same group, except for the first row.
In this you should add the value in UDF ARGS to your internal summary variable.
The xxx() function should be declared identical as when you define a simple UDF function.
See hundefinedi[UDF calling], page hundefinedi.
This function is called when all rows in the group has been processed. You should normally
never access the args variable here but return your value based on your internal summary
variables.
All argument processing in xxx_reset() and xxx_add() should be done identically as for
normal UDF functions. See hundefinedi[UDF arguments], page hundefinedi.
The return value handling in xxx() should be done identically as for a normal UDF. See
hundefinedi[UDF return values], page hundefinedi.
The pointer argument to is_null and error is the same for all calls to xxx_reset(),
xxx_add() and xxx(). You can use this to remember that you got an error or if the xxx()
function should return NULL. Note that you should not store a string into *error! This is
just a 1 byte flag!
is_null is reset for each group (before calling xxx_reset().error is never reset.
If isnull or error are set after xxx() then MySQL will return NULL as the result for the
group function.
10.2.2.3 Argument Processing
The args parameter points to a UDF_ARGS structure that has the members listed here:
unsigned int arg_count
The number of arguments. Check this value in the initialisation function if you
want your function to be called with a particular number of arguments. For
example:
686 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
if (args->arg_count != 2)
{
strcpy(message,"XXX() requires two arguments");
return 1;
}
enum Item_result *arg_type
The types for each argument. The possible type values are STRING_RESULT,
INT_RESULT, and REAL_RESULT.
To make sure that arguments are of a given type and return an error if they
are not, check the arg_type array in the initialisation function. For example:
if (args->arg_type[0] != STRING_RESULT ||
args->arg_type[1] != INT_RESULT)
{
strcpy(message,"XXX() requires a string and an integer");
return 1;
}
As an alternative to requiring your function’s arguments to be of particular
types, you can use the initialisation function to set the arg_type elements to
the types you want. This causes MySQL to coerce arguments to those types for
each call to xxx(). For example, to specify coercion of the first two arguments
to string and integer, do this in xxx_init():
args->arg_type[0] = STRING_RESULT;
args->arg_type[1] = INT_RESULT;
char **args
args->args communicates information to the initialisation function about the
general nature of the arguments your function was called with. For a constant
argument i,args->args[i] points to the argument value. (See below for
instructions on how to access the value properly.) For a non-constant argument,
args->args[i] is 0. A constant argument is an expression that uses only
constants, such as 3or 4*7-2 or SIN(3.14). A non-constant argument is an
expression that refers to values that may change from row to row, such as
column names or functions that are called with non-constant arguments.
For each invocation of the main function, args->args contains the actual ar-
guments that are passed for the row currently being processed.
Functions can refer to an argument ias follows:
An argument of type STRING_RESULT is given as a string pointer plus
a length, to allow handling of binary data or data of arbitrary length.
The string contents are available as args->args[i] and the string
length is args->lengths[i]. You should not assume that strings are
null-terminated.
For an argument of type INT_RESULT, you must cast args->args[i] to a
long long value:
long long int_val;
int_val = *((long long*) args->args[i]);
Chapter 10: Extending MySQL 687
For an argument of type REAL_RESULT, you must cast args->args[i] to
adouble value:
double real_val;
real_val = *((double*) args->args[i]);
unsigned long *lengths
For the initialisation function, the lengths array indicates the maximum string
length for each argument. You should not change these. For each invocation of
the main function, lengths contains the actual lengths of any string arguments
that are passed for the row currently being processed. For arguments of types
INT_RESULT or REAL_RESULT,lengths still contains the maximum length of
the argument (as for the initialisation function).
10.2.2.4 Return Values and Error Handling
The initialisation function should return 0if no error occurred and 1otherwise. If an error
occurs, xxx_init() should store a null-terminated error message in the message parameter.
The message will be returned to the client. The message buffer is MYSQL_ERRMSG_SIZE
characters long, but you should try to keep the message to less than 80 characters so that
it fits the width of a standard terminal screen.
The return value of the main function xxx() is the function value, for long long and double
functions. A string functions should return a pointer to the result and store the length of
the string in the length arguments.
Set these to the contents and length of the return value. For example:
memcpy(result, "result string", 13);
*length = 13;
The result buffer that is passed to the calc function is 255 byte big. If your result fits in
this, you don’t have to worry about memory allocation for results.
If your string function needs to return a string longer than 255 bytes, you must allocate
the space for it with malloc() in your xxx_init() function or your xxx() function and
free it in your xxx_deinit() function. You can store the allocated memory in the ptr slot
in the UDF_INIT structure for reuse by future xxx() calls. See hundefinedi[UDF calling],
page hundefinedi.
To indicate a return value of NULL in the main function, set is_null to 1:
*is_null = 1;
To indicate an error return in the main function, set the error parameter to 1:
*error = 1;
If xxx() sets *error to 1for any row, the function value is NULL for the current row and
for any subsequent rows processed by the statement in which XXX() was invoked. (xxx()
will not even be called for subsequent rows.) Note: in MySQL versions prior to 3.22.10,
you should set both *error and *is_null:
*error = 1;
*is_null = 1;
688 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
10.2.2.5 Compiling and Installing User-definable Functions
Files implementing UDFs must be compiled and installed on the host where the server runs.
This process is described below for the example UDF file ‘udf_example.cc’ that is included
in the MySQL source distribution. This file contains the following functions:
metaphon() returns a metaphon string of the string argument. This is something like
a soundex string, but it’s more tuned for English.
myfunc_double() returns the sum of the ASCII values of the characters in its argu-
ments, divided by the sum of the length of its arguments.
myfunc_int() returns the sum of the length of its arguments.
sequence([const int]) returns an sequence starting from the given number or 1 if
no number has been given.
lookup() returns the IP number for a hostname.
reverse_lookup() returns the hostname for an IP number. The function may be
called with a string "xxx.xxx.xxx.xxx" or four numbers.
A dynamically loadable file should be compiled as a sharable object file, using a command
something like this:
shell> gcc -shared -o udf_example.so myfunc.cc
You can easily find out the correct compiler options for your system by running this com-
mand in the ‘sql’ directory of your MySQL source tree:
shell> make udf_example.o
You should run a compile command similar to the one that make displays, except that you
should remove the -c option near the end of the line and add -o udf_example.so to the
end of the line. (On some systems, you may need to leave the -c on the command.)
Once you compile a shared object containing UDFs, you must install it and tell MySQL
about it. Compiling a shared object from ‘udf_example.cc’ produces a file named some-
thing like ‘udf_example.so’ (the exact name may vary from platform to platform). Copy
this file to some directory searched by ld, such as ‘/usr/lib’. On many systems, you can set
the LD_LIBRARY or LD_LIBRARY_PATH environment variable to point at the directory where
you have your UDF function files. The dlopen manual page tells you which variable you
should use on your system. You should set this in mysql.server or safe_mysqld startup
scripts and restart mysqld.
After the library is installed, notify mysqld about the new functions with these commands:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION reverse_lookup
-> RETURNS STRING SONAME "udf_example.so";
mysql> CREATE AGGREGATE FUNCTION avgcost
-> RETURNS REAL SONAME "udf_example.so";
Functions can be deleted using DROP FUNCTION:
mysql> DROP FUNCTION metaphon;
mysql> DROP FUNCTION myfunc_double;
Chapter 10: Extending MySQL 689
mysql> DROP FUNCTION myfunc_int;
mysql> DROP FUNCTION lookup;
mysql> DROP FUNCTION reverse_lookup;
mysql> DROP FUNCTION avgcost;
The CREATE FUNCTION and DROP FUNCTION statements update the system table func in the
mysql database. The function’s name, type and shared library name are saved in the table.
You must have the INSERT and DELETE privileges for the mysql database to create and drop
functions.
You should not use CREATE FUNCTION to add a function that has already been created. If
you need to reinstall a function, you should remove it with DROP FUNCTION and then reinstall
it with CREATE FUNCTION. You would need to do this, for example, if you recompile a new
version of your function, so that mysqld gets the new version. Otherwise, the server will
continue to use the old version.
Active functions are reloaded each time the server starts, unless you start mysqld with the
--skip-grant-tables option. In this case, UDF initialisation is skipped and UDFs are
unavailable. (An active function is one that has been loaded with CREATE FUNCTION and
not removed with DROP FUNCTION.)
10.2.3 Adding a New Native Function
The procedure for adding a new native function is described here. Note that you cannot add
native functions to a binary distribution because the procedure involves modifying MySQL
source code. You must compile MySQL yourself from a source distribution. Also note that
if you migrate to another version of MySQL (for example, when a new version is released),
you will need to repeat the procedure with the new version.
To add a new native MySQL function, follow these steps:
1. Add one line to ‘lex.h’ that defines the function name in the sql_functions[] array.
2. If the function prototype is simple (just takes zero, one, two or three arguments), you
should in lex.h specify SYM(FUNC ARG#) (where # is the number of arguments) as
the second argument in the sql_functions[] array and add a function that creates a
function object in ‘item_create.cc’. Take a look at "ABS" and create_funcs_abs()
for an example of this.
If the function prototype is complicated (for example takes a variable number of ar-
guments), you should add two lines to ‘sql_yacc.yy’. One indicates the preprocessor
symbol that yacc should define (this should be added at the beginning of the file).
Then define the function parameters and add an “item” with these parameters to the
simple_expr parsing rule. For an example, check all occurrences of ATAN in ‘sql_
yacc.yy’ to see how this is done.
3. In ‘item_func.h’, declare a class inheriting from Item_num_func or Item_str_func,
depending on whether your function returns a number or a string.
4. In ‘item_func.cc’, add one of the following declarations, depending on whether you
are defining a numeric or string function:
double Item_func_newname::val()
longlong Item_func_newname::val_int()
String *Item_func_newname::Str(String *str)
690 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
If you inherit your object from any of the standard items (like Item_num_func), you
probably only have to define one of the above functions and let the parent object take
care of the other functions. For example, the Item_str_func class defines a val()
function that executes atof() on the value returned by ::str().
5. You should probably also define the following object function:
void Item_func_newname::fix_length_and_dec()
This function should at least calculate max_length based on the given arguments. max_
length is the maximum number of characters the function may return. This function
should also set maybe_null = 0 if the main function can’t return a NULL value. The
function can check if any of the function arguments can return NULL by checking the
arguments maybe_null variable. You can take a look at Item_func_mod::fix_length_
and_dec for a typical example of how to do this.
All functions must be thread-safe (in other words, don’t use any global or static variables
in the functions without protecting them with mutexes).
If you want to return NULL, from ::val(),::val_int() or ::str() you should set null_
value to 1 and return 0.
For ::str() object functions, there are some additional considerations to be aware of:
The String *str argument provides a string buffer that may be used to hold the result.
(For more information about the String type, take a look at the ‘sql_string.h’ file.)
The ::str() function should return the string that holds the result or (char*) 0 if
the result is NULL.
All current string functions try to avoid allocating any memory unless absolutely nec-
essary!
10.3 Adding New Procedures to MySQL
In MySQL, you can define a procedure in C++ that can access and modify the data in a
query before it is sent to the client. The modification can be done on row-by-row or GROUP
BY level.
We have created an example procedure in MySQL Version 3.23 to show you what can be
done.
Additionally we recommend you to take a look at mylua. With this you can use the LUA
language to load a procedure at runtime into mysqld.
10.3.1 Procedure Analyse
analyse([max elements,[max memory]])
This procedure is defined in the ‘sql/sql_analyse.cc’. This examines the result from your
query and returns an analysis of the results:
max elements (default 256) is the maximum number of distinct values analyse will
notice per column. This is used by analyse to check if the optimal column type should
be of type ENUM.
max memory (default 8192) is the maximum memory analyse should allocate per col-
umn while trying to find all distinct values.
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
Chapter 10: Extending MySQL 691
10.3.2 Writing a Procedure
For the moment, the only documentation for this is the source.
You can find all information about procedures by examining the following files:
sql/sql_analyse.cc
sql/procedure.h
sql/procedure.cc
sql/sql_select.cc
692 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Appendix A Problems and Common Errors
This chapter lists some common problems and error messages that users have run into. You
will learn how to figure out what the problem is, and what to do to solve it. You will also
find proper solutions to some common problems.
A.1 How to Determine What Is Causing Problems
When you run into problems, the first thing you should do is to find out which program /
piece of equipment is causing problems:
If you have one of the following symptoms, then it is probably a hardware (like memory,
motherboard, CPU, or hard disk) or kernel problem:
The keyboard doesn’t work. This can normally be checked by pressing Caps Lock.
If the Caps Lock light doesn’t change you have to replace your keyboard. (Before
doing this, you should try to reboot your computer and check all cables to the
keyboard.)
The mouse pointer doesn’t move.
The machine doesn’t answer to a remote machine’s pings.
Different, unrelated programs don’t behave correctly.
If your system rebooted unexpectedly (a faulty user level program should never
be able to take down your system).
In this case you should start by checking all your cables and run some diagnostic tool
to check your hardware! You should also check if there are any patches, updates, or
service packs for your operating system that could likely solve your problems. Check
also that all your libraries (like glibc) are up to date.
It’s always good to use a machine with ECC memory to discover memory problems
early!
If your keyboard is locked up, you may be able to fix this by logging into your machine
from another machine and execute kbd_mode -a on it.
Please examine your system log file (/var/log/messages or similar) for reasons for your
problems. If you think the problem is in MySQL then you should also examine MySQL’s
log files. See hundefinedi[Binary log], page hundefinedi.
If you don’t think you have hardware problems, you should try to find out which
program is causing problems.
Try using top,ps,taskmanager, or some similar program, to check which program is
taking all CPU or is locking the machine.
Check with top,df, or a similar program if you are out of memory, disk space, open
files, or some other critical resource.
If the problem is some runaway process, you can always try to kill it. If it doesn’t want
to die, there is probably a bug in the operating system.
If after you have examined all other possibilities and you have concluded that it’s the
MySQL server or a MySQL client that is causing the problem, it’s time to do a bug report
for our mailing list or our support team. In the bug report, try to give a very detailed
Appendix A: Problems and Common Errors 693
description of how the system is behaving and what you think is happening. You should
also state why you think it’s MySQL that is causing the problems. Take into consideration
all the situations in this chapter. State any problems exactly how they appear when you
examine your system. Use the ’cut and paste’ method for any output and/or error messages
from programs and/or log files!
Try to describe in detail which program is not working and all symptoms you see! We have
in the past received many bug reports that just state "the system doesn’t work". This
doesn’t provide us with any information about what could be the problem.
If a program fails, it’s always useful to know:
Has the program in question made a segmentation fault (core dumped)?
Is the program taking up the whole CPU? Check with top. Let the program run for a
while, it may be evaluating something heavy.
If it’s the mysqld server that is causing problems, can you do mysqladmin -u root
ping or mysqladmin -u root processlist?
What does a client program say (try with mysql, for example) when you try to connect
to the MySQL server? Does the client jam? Do you get any output from the program?
When sending a bug report, you should of follow the outlines described in this manual. See
hundefinedi[Asking questions], page hundefinedi.
A.2 Common Errors When Using MySQL
This section lists some errors that users frequently get. You will find descriptions of the
errors, and how to solve the problem here.
A.2.1 Access denied Error
See hundefinedi[Access denied], page hundefinedi. See hundefinedi[Privileges], page hun-
definedi.
A.2.2 MySQL server has gone away Error
This section also covers the related Lost connection to server during query error.
The most common reason for the MySQL server has gone away error is that the server
timed out and closed the connection. By default, the server closes the connection after 8
hours if nothing has happened. You can change the time limit by setting the wait_timeout
variable when you start mysqld.
Another common reason to receive the MySQL server has gone away error is because you
have issued a “close” on your MySQL connection and then tried to run a query on the
closed connection.
If you have a script, you just have to issue the query again for the client to do an automatic
reconnection.
You normally can get the following error codes in this case (which one you get is OS-
dependent):
Error code Description
694 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
CR_SERVER_GONE_ERROR The client couldn’t send a question to the server.
CR_SERVER_LOST The client didn’t get an error when writing to the server,
but it didn’t get a full answer (or any answer) to the
question.
You will also get this error if someone has kills the running thread with kill #threadid#.
You can check that the MySQL hasn’t died by executing mysqladmin version and exam-
ining the uptime. If the problem is that mysqld crashed you should concentrate one finding
the reason for the crash. You should in this case start by checking if issuing the query again
will kill MySQL again. See hundefinedi[Crashing], page hundefinedi.
You can also get these errors if you send a query to the server that is incorrect or too large.
If mysqld gets a packet that is too large or out of order, it assumes that something has gone
wrong with the client and closes the connection. If you need big queries (for example, if you
are working with big BLOB columns), you can increase the query limit by starting mysqld
with the -O max_allowed_packet=# option (default 1M). The extra memory is allocated
on demand, so mysqld will allocate more memory only when you issue a big query or when
mysqld must return a big result row!
You will also get a lost connection if you are sending a packet >= 16M if your client is older
than 4.0.8 and your server is 4.0.8 and above, or the other way around.
If you want to make a bug report regarding this problem, be sure that you include the
following information:
Include information if MySQL died or not. (You can find this in the hostname.err
file. See hundefinedi[Crashing], page hundefinedi.
If a specific query kills mysqld and the involved tables where checked with CHECK
TABLE before you did the query, can you do a test case for this? See hundefinedi
[Reproduceable test case], page hundefinedi.
What is the value of the wait_timeout variable in the MySQL server ? mysqladmin
variables gives you the value of this
Have you tried to run mysqld with --log and check if the issued query appears in the
log ?
See hundefinedi[Asking questions], page hundefinedi.
A.2.3 Can’t connect to [local] MySQL server Error
A MySQL client on Unix can connect to the mysqld server in two different ways: Unix
sockets, which connect through a file in the file system (default ‘/tmp/mysqld.sock’) or
TCP/IP, which connects through a port number. Unix sockets are faster than TCP/IP but
can only be used when connecting to a server on the same computer. Unix sockets are used
if you don’t specify a hostname or if you specify the special hostname localhost.
On Windows, if the mysqld server is running on 9x/Me, you can connect only via TCP/IP.
If the server is running on NT/2000/XP and mysqld is started with --enable-named-pipe,
you can also connect with named pipes. The name of the named pipe is MySQL. If you
don’t give a hostname when connecting to mysqld, a MySQL client will first try to connect
to the named pipe, and if this doesn’t work it will connect to the TCP/IP port. You can
force the use of named pipes on Windows by using .as the hostname.
Appendix A: Problems and Common Errors 695
The error (2002) Can’t connect to ... normally means that there isn’t a MySQL server
running on the system or that you are using a wrong socket file or TCP/IP port when
trying to connect to the mysqld server.
Start by checking (using ps or the task manager on Windows) that there is a process running
named mysqld on your server! If there isn’t any mysqld process, you should start one. See
hundefinedi[Starting server], page hundefinedi.
If a mysqld process is running, you can check the server by trying these different connections
(the port number and socket pathname might be different in your setup, of course):
shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h ‘hostname‘ version variables
shell> mysqladmin -h ‘hostname‘ --port=3306 version
shell> mysqladmin -h ’ip for your host’ version
shell> mysqladmin --protocol=socket --socket=/tmp/mysql.sock version
Note the use of backquotes rather than forward quotes with the hostname command; these
cause the output of hostname (that is, the current hostname) to be substituted into the
mysqladmin command.
Here are some reasons the Can’t connect to local MySQL server error might occur:
mysqld is not running.
You are running on a system that uses MIT-pthreads. If you are running on a system
that doesn’t have native threads, mysqld uses the MIT-pthreads package. See hunde-
finedi[Which OS], page hundefinedi. However, not all MIT-pthreads versions support
Unix sockets. On a system without sockets support you must always specify the host-
name explicitly when connecting to the server. Try using this command to check the
connection to the server:
shell> mysqladmin -h ‘hostname‘ version
Someone has removed the Unix socket that mysqld uses (default ‘/tmp/mysqld.sock’).
You might have a cron job that removes the MySQL socket (for example, a job that
removes old files from the ‘/tmp’ directory). You can always run mysqladmin version
and check that the socket mysqladmin is trying to use really exists. The fix in this
case is to change the cron job to not remove ‘mysqld.sock’ or to place the socket
somewhere else. See hundefinedi[Problems with mysql.sock], page hundefinedi.
You have started the mysqld server with the --socket=/path/to/socket option. If
you change the socket pathname for the server, you must also notify the MySQL clients
about the new path. You can do this by providing the socket path as an argument to
the client. See hundefinedi[Problems with mysql.sock], page hundefinedi.
You are using Linux and one thread has died (core dumped). In this case you must
kill the other mysqld threads (for example, with the mysql_zap script before you can
start a new MySQL server. See hundefinedi[Crashing], page hundefinedi.
You may not have read and write privilege to either the directory that holds the socket
file or privilege to the socket file itself. In this case you have to either change the
privilege for the directory / file or restart mysqld so that it uses a directory that you
can access.
If you get the error message Can’t connect to MySQL server on some_hostname, you can
try the following things to find out what the problem is :
696 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Check if the server is up by doing telnet your-host-name tcp-ip-port-number and
press Enter a couple of times. If there is a MySQL server running on this port you
should get a responses that includes the version number of the running MySQL server.
If you get an error like telnet: Unable to connect to remote host: Connection
refused, then there is no server running on the given port.
Try connecting to the mysqld daemon on the local machine and check the TCP/IP
port that mysqld it’s configured to use (variable port) with mysqladmin variables.
Check that your mysqld server is not started with the --skip-networking option.
A.2.4 Host ’...’ is blocked Error
If you get an error like this:
Host ’hostname’ is blocked because of many connection errors.
Unblock with ’mysqladmin flush-hosts’
this means that mysqld has gotten a lot (max_connect_errors) of connect requests from
the host ’hostname’ that have been interrupted in the middle. After max_connect_errors
failed requests, mysqld assumes that something is wrong (like an attack from a cracker), and
blocks the site from further connections until someone executes the command mysqladmin
flush-hosts.
By default, mysqld blocks a host after 10 connection errors. You can easily adjust this by
starting the server like this:
shell> safe_mysqld -O max_connect_errors=10000 &
Note that if you get this error message for a given host, you should first check that there
isn’t anything wrong with TCP/IP connections from that host. If your TCP/IP connections
aren’t working, it won’t do you any good to increase the value of the max_connect_errors
variable!
A.2.5 Too many connections Error
If you get the error Too many connections when you try to connect to MySQL, this means
that there is already max_connections clients connected to the mysqld server.
If you need more connections than the default (100), then you should restart mysqld with
a bigger value for the max_connections variable.
Note that mysqld actually allows (max_connections+1) clients to connect. The last con-
nection is reserved for a user with the SUPER privilege. By not giving this privilege to normal
users (they shouldn’t need this), an administrator with this privilege can log in and use SHOW
PROCESSLIST to find out what could be wrong. See hundefinedi[SHOW PROCESSLIST],
page hundefinedi.
The maximum number of connects MySQL is depending on how good the thread library
is on a given platform. Linux or Solaris should be able to support 500-1000 simultaneous
connections, depending on how much RAM you have and what your clients are doing.
A.2.6 Some non-transactional changed tables couldn’t be rolled
back Error
If you get the error/warning: Warning: Some non-transactional changed tables
couldn’t be rolled back when trying to do a ROLLBACK, this means that some of the
Appendix A: Problems and Common Errors 697
tables you used in the transaction didn’t support transactions. These non-transactional
tables will not be affected by the ROLLBACK statement.
The most typical case when this happens is when you have tried to create a table of a type
that is not supported by your mysqld binary. If mysqld doesn’t support a table type (or if
the table type is disabled by a startup option) , it will instead create the table type with
the table type that is most resembles to the one you requested, probably MyISAM.
You can check the table type for a table by doing:
SHOW TABLE STATUS LIKE ’table_name’. See hundefinedi[SHOW TABLE STATUS],
page hundefinedi.
You can check the extensions your mysqld binary supports by doing:
show variables like ’have_%’. See hundefinedi[SHOW VARIABLES], page hundefinedi.
A.2.7 Out of memory Error
If you issue a query and get something like the following error:
mysql: Out of memory at line 42, ’malloc.c’
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
note that the error refers to the MySQL client mysql. The reason for this error is simply
that the client does not have enough memory to store the whole result.
To remedy the problem, first check that your query is correct. Is it reasonable that it should
return so many rows? If so, you can use mysql --quick, which uses mysql_use_result()
to retrieve the result set. This places less of a load on the client (but more on the server).
A.2.8 Packet too large Error
When a MySQL client or the mysqld server gets a packet bigger than max_allowed_packet
bytes, it issues a Packet too large error and closes the connection.
In MySQL 3.23 the biggest possible packet is 16M (due to limits in the client/server proto-
col). In MySQL 4.0.1 and up, this is only limited by the amount on memory you have on
your server (up to a theoretical maximum of 2G).
A communication packet is a single SQL statement sent to the MySQL server or a single
row that is sent to the client.
When a MySQL client or the mysqld server gets a packet bigger than max_allowed_packet
bytes, it issues a Packet too large error and closes the connection. With some clients, you
may also get Lost connection to MySQL server during query error if the communication
packet is too big.
Note that both the client and the server has it’s own max_allowed_packet variable. If you
want to handle big packets, you have to increase this variable both in the client and in the
server.
It’s safe to increase this variable as memory is only allocated when needed; this variable is
more a precaution to catch wrong packets between the client/server and also to ensure that
you don’t accidentally use big packets so that you run out of memory.
If you are using the mysql client, you may specify a bigger buffer by starting the client with
mysql --set-variable=max_allowed_packet=8M. Other clients have different methods to
698 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
set this variable. Please note that --set-variable is deprecated since MySQL 4.0, just
use --max-allowed-packet=8M instead.
You can use the option file to set max_allowed_packet to a larger size in mysqld. For
example, if you are expecting to store the full length of a MEDIUMBLOB into a table, you’ll
need to start the server with the set-variable=max_allowed_packet=16M option.
You can also get strange problems with large packets if you are using big blobs, but you
haven’t given mysqld access to enough memory to handle the query. If you suspect this
is the case, try adding ulimit -d 256000 to the beginning of the safe_mysqld script and
restart mysqld.
A.2.9 Communication Errors / Aborted Connection
Starting with MySQL 3.23.40 you only get the Aborted connection error of you start
mysqld with --warnings.
If you find errors like the following in your error log.
010301 14:38:23 Aborted connection 854 to db: ’users’ user: ’josh’
See hundefinedi[Error log], page hundefinedi.
This means that something of the following has happened:
The client program did not call mysql_close() before exit.
The client had been sleeping more than wait_timeout or interactive_timeout with-
out doing any requests. See hundefinedi[wait_timeout], page hundefinedi. See hunde-
finedi[interactive_timeout], page hundefinedi.
The client program ended abruptly in the middle of the transfer.
When the above happens, the server variable Aborted_clients is incremented.
The server variable Aborted_connects is incremented when:
When a connection packet doesn’t contain the right information.
When the user didn’t have privileges to connect to a database.
When a user uses a wrong password.
When it takes more than connect_timeout seconds to get a connect package. See
hundefinedi[connect_timeout], page hundefinedi.
Note that the above could indicate that someone is trying to break into your database!
Other reasons for problems with Aborted clients / Aborted connections.
Usage of Ethernet protocol with Linux, both half and full duplex. Many Linux Ethernet
drivers have this bug. You should test for this bug by transferring a huge file via ftp
between these two machines. If a transfer goes in burst-pause-burst-pause ... mode
then you are experiencing a Linux duplex syndrome. The only solution is switching
duplex mode for both your network card and Hub/Switch to either full duplex or to
half duplex and testing the results to decide on the best setting.
Some problem with the thread library that causes interrupts on reads.
Badly configured TCP/IP.
Faulty Ethernets or hubs or switches, cables ... This can be diagnosed properly only
by replacing hardware.
Appendix A: Problems and Common Errors 699
max_allowed_packet is too small or queries require more memory than you have allo-
cated for mysqld. See hundefinedi[Packet too large], page hundefinedi.
A.2.10 The table is full Error
There is a couple of different cases when you can get this error:
You are using an older MySQL version (before 3.23.0) when an in-memory temporary
table becomes larger than tmp_table_size bytes. To avoid this problem, you can
use the -O tmp_table_size=# option to make mysqld increase the temporary table
size or use the SQL option BIG_TABLES before you issue the problematic query. See
hundefinedi[SET], page hundefinedi.
You can also start mysqld with the --big-tables option. This is exactly the same as
using BIG_TABLES for all queries.
In MySQL Version 3.23, in-memory temporary tables will automatically be converted
to a disk-based MyISAM table after the table size gets bigger than tmp_table_size.
You are using InnoDB tables and run out of room in the InnoDB tablespace. In this
case the solution is to extend the InnoDB tablespace.
You are using ISAM or MyISAM tables on an OS that only supports files of 2G in size
and you have hit this limit for the data or index file.
You are using MyISAM tables and the needed data or index size is bigger than what
MySQL has allocated pointers for. (If you don’t specify MAX_ROWS to CREATE TABLE
MySQL will only allocate pointers to hold 4G of data).
You can check the maximum data/index sizes by doing
SHOW TABLE STATUS FROM database LIKE ’table_name’;
or using myisamchk -dv database/table_name.
If this is the problem, you can fix it by doing something like:
ALTER TABLE table_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
You only have to specify AVG_ROW_LENGTH for tables with BLOB/TEXT fields as in
this case MySQL can’t optimise the space required based only on the number of rows.
A.2.11 Can’t create/write to file Error
If you get an error for some queries of type:
Can’t create/write to file ’\\sqla3fe_0.ism’.
this means that MySQL can’t create a temporary file for the result set in the given temporary
directory. (The above error is a typical error message on Windows, and the Unix error
message is similar.) The fix is to start mysqld with --tmpdir=path or to add to your
option file:
[mysqld]
tmpdir=C:/temp
assuming that the ‘c:\\temp’ directory exists. See hundefinedi[Option files], page hunde-
finedi.
Check also the error code that you get with perror. One reason may also be a disk full
error;
700 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
shell> perror 28
Error code 28: No space left on device
A.2.12 Commands out of sync Error in Client
If you get Commands out of sync; you can’t run this command now in your client code,
you are calling client functions in the wrong order!
This can happen, for example, if you are using mysql_use_result() and try to execute
a new query before you have called mysql_free_result(). It can also happen if you try
to execute two queries that return data without a mysql_use_result() or mysql_store_
result() in between.
A.2.13 Ignoring user Error
If you get the following error:
Found wrong password for user: ’some_user@some_host’; ignoring user
this means that when mysqld was started or when it reloaded the permissions tables, it
found an entry in the user table with an invalid password. As a result, the entry is simply
ignored by the permission system.
Possible causes of and fixes for this problem:
You may be running a new version of mysqld with an old user table. You can check
this by executing mysqlshow mysql user to see if the password field is shorter than 16
characters. If so, you can correct this condition by running the scripts/add_long_
password script.
The user has an old password (8 characters long) and you didn’t start mysqld with the
--old-protocol option. Update the user in the user table with a new password or
restart mysqld with --old-protocol.
You have specified a password in the user table without using the PASSWORD() function.
Use mysql to update the user in the user table with a new password. Make sure to
use the PASSWORD() function:
mysql> UPDATE user SET password=PASSWORD(’your password’)
-> WHERE user=’XXX’;
A.2.14 Table ’xxx’ doesn’t exist Error
If you get the error Table ’xxx’ doesn’t exist or Can’t find file: ’xxx’ (errno: 2),
this means that no table exists in the current database with the name xxx.
Note that as MySQL uses directories and files to store databases and tables, the database
and table names are case-sensitive! (On Windows the databases and tables names are not
case-sensitive, but all references to a given table within a query must use the same case!)
You can check which tables you have in the current database with SHOW TABLES. See hun-
definedi[SHOW], page hundefinedi.
Appendix A: Problems and Common Errors 701
A.2.15 Can’t initialize character set xxx error
If you get an error like:
MySQL Connection Failed: Can’t initialize character set xxx
This means one of the following things:
The character set is a multi-byte character set and you have no support for the character
set in the client.
In this case you need to recompile the client with --with-charset=xxx or with --
with-extra-charsets=xxx. See hundefinedi[configure options], page hundefinedi.
All standard MySQL binaries are compiled with --with-extra-character-
sets=complex which will enable support for all multi-byte character sets. See
hundefinedi[Character sets], page hundefinedi.
The character set is a simple character set which is not compiled into mysqld and the
character set definition files are not in the place where the client expects to find them.
In this case you need to:
Recompile the client with support for the character set. See hundefinedi[configure
options], page hundefinedi.
Specify to the client where the character set definition files are. For many clients
you can do this with the --character-sets-dir=path-to-charset-dir option.
Copy the character definition files to the path where the client expects them to
be.
A.2.16 File Not Found
If you get ERROR ’...’ not found (errno: 23),Can’t open file: ... (errno: 24), or
any other error with errno 23 or errno 24 from MySQL, it means that you haven’t allocated
enough file descriptors for MySQL. You can use the perror utility to get a description of
what the error number means:
shell> perror 23
File table overflow
shell> perror 24
Too many open files
shell> perror 11
Resource temporarily unavailable
The problem here is that mysqld is trying to keep open too many files simultaneously. You
can either tell mysqld not to open so many files at once or increase the number of file
descriptors available to mysqld.
To tell mysqld to keep open fewer files at a time, you can make the table cache smaller by
using the -O table_cache=32 option to safe_mysqld (the default value is 64). Reducing
the value of max_connections will also reduce the number of open files (the default value
is 90).
To change the number of file descriptors available to mysqld, you can use the option --
open-files-limit=# to safe_mysqld or -O open-files-limit=# to mysqld. See hunde-
finedi[open_files_limit], page hundefinedi. The easiest way to do that is to add the
option to your option file. See hundefinedi[Option files], page hundefinedi. If you have an
702 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
old mysqld version that doesn’t support this, you can edit the safe_mysqld script. There
is a commented-out line ulimit -n 256 in the script. You can remove the ’#’ character to
uncomment this line, and change the number 256 to affect the number of file descriptors
available to mysqld.
ulimit (and open-files-limit) can increase the number of file descriptors, but only up
to the limit imposed by the operating system. There is also a ’hard’ limit that can only
be overridden if you start safe_mysqld or mysqld as root (just remember that you need
to also use the --user=... option in this case). If you need to increase the OS limit on
the number of file descriptors available to each process, consult the documentation for your
operating system.
Note that if you run the tcsh shell, ulimit will not work! tcsh will also report incorrect
values when you ask for the current limits! In this case you should start safe_mysqld with
sh!
A.3 Installation Related Issues
A.3.1 Problems When Linking with the MySQL Client Library
If you are linking your program and you get errors for unreferenced symbols that start with
mysql_, like the following:
/tmp/ccFKsdPa.o: In function ‘main’:
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to ‘mysql_init’
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to ‘mysql_real_connect’
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to ‘mysql_real_connect’
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to ‘mysql_error’
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to ‘mysql_close’
you should be able to solve this by adding -Lpath-to-the-mysql-library -lmysqlclient
last on your link line.
If you get undefined reference errors for the uncompress or compress function, add -lz
last on your link line and try again!
If you get undefined reference errors for functions that should exist on your system, like
connect, check the man page for the function in question, for which libraries you should
add to the link line!
If you get undefined reference errors for functions that don’t exist on your system, like
the following:
mf_format.o(.text+0x201): undefined reference to ‘__lxstat’
it usually means that your library is compiled on a system that is not 100% compatible
with yours. In this case you should download the latest MySQL source distribution and
compile this yourself. See hundefinedi[Installing source], page hundefinedi.
If you are trying to run a program and you then get errors for unreferenced symbols that
start with mysql_ or that the mysqlclient library can’t be found, this means that your
system can’t find the share ‘libmysqlclient.so’ library.
The fix for this is to tell your system to search after shared libraries where the library is
located by one of the following methods:
Appendix A: Problems and Common Errors 703
Add the path to the directory where you have ‘libmysqlclient.so’ the LD_LIBRARY_
PATH environment variable.
Add the path to the directory where you have ‘libmysqlclient.so’ the LD_LIBRARY
environment variable.
Copy ‘libmysqlclient.so’ to some place that is searched by your system, like ‘/lib’,
and update the shared library information by executing ldconfig.
Another way to solve this problem is to link your program statically, with -static, or by
removing the dynamic MySQL libraries before linking your code. In the second case you
should be sure that no other programs are using the dynamic libraries!
A.3.2 How to Run MySQL As a Normal User
The MySQL server mysqld can be started and run by any user. In order to change mysqld
to run as a Unix user user_name, you must do the following:
1. Stop the server if it’s running (use mysqladmin shutdown).
2. Change the database directories and files so that user_name has privileges to read and
write files in them (you may need to do this as the Unix root user):
shell> chown -R user_name /path/to/mysql/datadir
If directories or files within the MySQL data directory are symlinks, you’ll also need
to follow those links and change the directories and files they point to. chown -R may
not follow symlinks for you.
3. Start the server as user user_name, or, if you are using MySQL Version 3.22 or later,
start mysqld as the Unix root user and use the --user=user_name option. mysqld
will switch to run as the Unix user user_name before accepting any connections.
4. To start the server as the given user name automatically at system startup time, add
auser line that specifies the user name to the [mysqld] group of the ‘/etc/my.cnf
option file or the ‘my.cnf’ option file in the server’s data directory. For example:
[mysqld]
user=user_name
At this point, your mysqld process should be running fine and dandy as the Unix user user_
name. One thing hasn’t changed, though: the contents of the permissions tables. By default
(right after running the permissions table install script mysql_install_db), the MySQL
user root is the only user with permission to access the mysql database or to create or drop
databases. Unless you have changed those permissions, they still hold. This shouldn’t stop
you from accessing MySQL as the MySQL root user when you’re logged in as a Unix user
other than root; just specify the -u root option to the client program.
Note that accessing MySQL as root, by supplying -u root on the command-line, has
nothing to do with MySQL running as the Unix root user, or, indeed, as another Unix
user. The access permissions and user names of MySQL are completely separate from Unix
user names. The only connection with Unix user names is that if you don’t provide a -u
option when you invoke a client program, the client will try to connect using your Unix
login name as your MySQL user name.
If your Unix box itself isn’t secured, you should probably at least put a password on the
MySQL root users in the access tables. Otherwise, any user with an account on that
machine can run mysql -u root db_name and do whatever he likes.
704 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A.3.3 Problems with File Permissions
If you have problems with file permissions, for example, if mysql issues the following error
message when you create a table:
ERROR: Can’t find file: ’path/with/filename.frm’ (Errcode: 13)
then the environment variable UMASK might be set incorrectly when mysqld starts up. The
default umask value is 0660. You can change this behaviour by starting safe_mysqld as
follows:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &
By default MySQL will create database and RAID directories with permission type 0700.
You can modify this behaviour by setting the UMASK_DIR variable. If you set this, new
directories are created with the combined UMASK and UMASK_DIR. For example, if you want
to give group access to all new directories, you can do:
shell> UMASK_DIR=504 # = 770 in octal
shell> export UMASK_DIR
shell> /path/to/safe_mysqld &
In MySQL Version 3.23.25 and above, MySQL assumes that the value for UMASK and UMASK_
DIR is in octal if it starts with a zero.
See hundefinedi[Environment variables], page hundefinedi.
A.4 Administration Related Issues
A.4.1 What To Do If MySQL Keeps Crashing
All MySQL versions are tested on many platforms before they are released. This doesn’t
mean that there aren’t any bugs in MySQL, but it means if there are bugs, they are very
few and can be hard to find. If you have a problem, it will always help if you try to find
out exactly what crashes your system, as you will have a much better chance of getting this
fixed quickly.
First, you should try to find out whether the problem is that the mysqld daemon dies or
whether your problem has to do with your client. You can check how long your mysqld
server has been up by executing mysqladmin version. If mysqld has died, you may find
the reason for this in the file ‘mysql-data-directory/‘hostname‘.err’. See hundefinedi
[Error log], page hundefinedi.
Many crashes of MySQL are caused by corrupted index / data files. MySQL will update
the data on disk, with the write() system call, after every SQL statement and before the
client is notified about the result. (This is not true if you are running with delay_key_
write, in which case only the data is written.) This means that the data is safe even if
mysqld crashes, as the OS will ensure that the not flushed data is written to disk. You can
force MySQL to sync everything to disk after every SQL command by starting mysqld with
--flush.
The above means that normally you shouldn’t get corrupted tables unless:
Appendix A: Problems and Common Errors 705
Someone/something killed mysqld or the machine in the middle of an update.
You have found a bug in mysqld that caused it to die in the middle of an update.
Someone is manipulating the data/index files outside of mysqld without locking the
table properly.
If you are running many mysqld servers on the same data on a system that doesn’t
support good filesystem locks (normally handled by the lockd daemon ) or if you are
running multiple servers with --skip-external-locking
You have a crashed index/datafile that contains very wrong data that got mysqld
confused.
You have found a bug in the data storage code. This isn’t that likely, but it’s at least
possible. In this case you can try to change the file type to another storage engine by
using ALTER TABLE on a repaired copy of the table!
Because it is very difficult to know why something is crashing, first try to check whether
things that work for others crash for you. Please try the following things:
Take down the mysqld daemon with mysqladmin shutdown, run myisamchk --silent
--force */*.MYI on all tables, and restart the mysqld daemon. This will ensure that
you are running from a clean state. See hundefinedi[MySQL Database Administration],
page hundefinedi.
Use mysqld --log and try to determine from the information in the log whether some
specific query kills the server. About 95% of all bugs are related to a particular query!
Normally this is one of the last queries in the log file just before MySQL restarted.
See hundefinedi[Query log], page hundefinedi. If you can repeatedly kill MySQL with
one of the queries, even when you have checked all tables just before doing the query,
then you have been able to locate the bug and should do a bug report for this! See
hundefinedi[Bug reports], page hundefinedi.
Try to make a test case that we can use to reproduce the problem. See hundefinedi
[Reproduceable test case], page hundefinedi.
Try running the included mysql-test test and the MySQL benchmarks. See hundefinedi
[MySQL test suite], page hundefinedi. They should test MySQL rather well. You can
also add code to the benchmarks that simulates your application! The benchmarks can
be found in the ‘bench’ directory in the source distribution or, for a binary distribution,
in the ‘sql-bench’ directory under your MySQL installation directory.
Try fork_test.pl and fork2_test.pl.
If you configure MySQL for debugging, it will be much easier to gather information
about possible errors if something goes wrong. Reconfigure MySQL with the --with-
debug option or --with-debug=full to configure and then recompile. See hunde-
finedi[Debugging server], page hundefinedi.
Configuring MySQL for debugging causes a safe memory allocator to be included that
can find some errors. It also provides a lot of output about what is happening.
Have you applied the latest patches for your operating system?
Use the --skip-external-locking option to mysqld. On some systems, the lockd
lock manager does not work properly; the --skip-external-locking option tells
mysqld not to use external locking. (This means that you cannot run 2 mysqld servers
706 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
on the same data and that you must be careful if you use myisamchk, but it may be
instructive to try the option as a test.)
Have you tried mysqladmin -u root processlist when mysqld appears to be running
but not responding? Sometimes mysqld is not comatose even though you might think
so. The problem may be that all connections are in use, or there may be some internal
lock problem. mysqladmin processlist will usually be able to make a connection
even in these cases, and can provide useful information about the current number of
connections and their status.
Run the command mysqladmin -i 5 status or mysqladmin -i 5 -r status or in a
separate window to produce statistics while you run your other queries.
Try the following:
1. Start mysqld from gdb (or in another debugger). See hundefinedi[Using gdb on
mysqld], page hundefinedi.
2. Run your test scripts.
3. Print the backtrace and the local variables at the 3 lowest levels. In gdb you can
do this with the following commands when mysqld has crashed inside gdb:
backtrace
info local
up
info local
up
info local
With gdb you can also examine which threads exist with info threads and switch
to a specific thread with thread #, where #is the thread id.
Try to simulate your application with a Perl script to force MySQL to crash or misbe-
have.
Send a normal bug report. See hundefinedi[Bug reports], page hundefinedi. Be even
more detailed than usual. Because MySQL works for many people, it may be that the
crash results from something that exists only on your computer (for example, an error
that is related to your particular system libraries).
If you have a problem with tables with dynamic-length rows and you are not using
BLOB/TEXT columns (but only VARCHAR columns), you can try to change all VARCHAR
to CHAR with ALTER TABLE. This will force MySQL to use fixed-size rows. Fixed-size
rows take a little extra space, but are much more tolerant to corruption!
The current dynamic row code has been in use at MySQL AB for at least 3 years
without any problems, but by nature dynamic-length rows are more prone to errors,
so it may be a good idea to try the above to see if it helps!
A.4.2 How to Reset a Forgotten Root Password
If you never set a root password for MySQL, then the server will not require a password at
all for connecting as root. It is recommended to always set a password for each user. See
hundefinedi[Security], page hundefinedi.
If you have set a root password, but forgot what it was, you can set a new password with
the following procedure:
Appendix A: Problems and Common Errors 707
1. Take down the mysqld server by sending a kill (not kill -9) to the mysqld server.
The pid is stored in a ‘.pid’ file, which is normally in the MySQL database directory:
shell> kill ‘cat /mysql-data-directory/hostname.pid‘
You must be either the Unix root user or the same user mysqld runs as to do this.
2. Restart mysqld with the --skip-grant-tables option.
3. Set a new password with the mysqladmin password command:
shell> mysqladmin -u root password ’mynewpassword’
4. Now you can either stop mysqld and restart it normally, or just load the privilege tables
with:
shell> mysqladmin -h hostname flush-privileges
5. After this, you should be able to connect using the new password.
Alternatively, you can set the new password using the mysql client:
1. Take down and restart mysqld with the --skip-grant-tables option as described
above.
2. Connect to the mysqld server with:
shell> mysql -u root mysql
3. Issue the following commands in the mysql client:
mysql> UPDATE user SET Password=PASSWORD(’mynewpassword’)
-> WHERE User=’root’;
mysql> FLUSH PRIVILEGES;
4. After this, you should be able to connect using the new password.
5. You can now stop mysqld and restart it normally.
A.4.3 How MySQL Handles a Full Disk
When a disk-full condition occurs, MySQL does the following:
It checks once every minute to see whether there is enough space to write the current
row. If there is enough space, it continues as if nothing had happened.
Every 6 minutes it writes an entry to the log file warning about the disk full condition.
To alleviate the problem, you can take the following actions:
To continue, you only have to free enough disk space to insert all records.
To abort the thread, you must send a mysqladmin kill to the thread. The thread will
be aborted the next time it checks the disk (in 1 minute).
Note that other threads may be waiting for the table that caused the disk full condition.
If you have several “locked” threads, killing the one thread that is waiting on the disk-
full condition will allow the other threads to continue.
Exceptions to the above behaveour is when you use REPAIR or OPTIMIZE or when the indexes
are created in a batch after an LOAD DATA INFILE or after an ALTER TABLE statement.
All of the above commands may use big temporary files that left to themself would cause big
problems for the rest of the system. If MySQL gets disk full while doing any of the above
operations, it will remove the big temporary files and mark the table as crashed (except for
ALTER TABLE, in which the old table will be left unchanged).
708 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A.4.4 Where MySQL Stores Temporary Files
MySQL uses the value of the TMPDIR environment variable as the pathname of the directory
in which to store temporary files. If you don’t have TMPDIR set, MySQL uses the system
default, which is normally ‘/tmp’ or ‘/usr/tmp’. If the filesystem containing your temporary
file directory is too small, you should edit safe_mysqld to set TMPDIR to point to a directory
in a filesystem where you have enough space! You can also set the temporary directory using
the --tmpdir option to mysqld.
MySQL creates all temporary files as hidden files. This ensures that the temporary files will
be removed if mysqld is terminated. The disadvantage of using hidden files is that you will
not see a big temporary file that fills up the filesystem in which the temporary file directory
is located.
When sorting (ORDER BY or GROUP BY), MySQL normally uses one or two temporary files.
The maximum disk-space needed is:
(length of what is sorted + sizeof(database pointer))
* number of matched rows
* 2
sizeof(database pointer) is usually 4, but may grow in the future for really big tables.
For some SELECT queries, MySQL also creates temporary SQL tables. These are not hidden
and have names of the form ‘SQL_*’.
ALTER TABLE creates a temporary table in the same directory as the original table.
If you use MySQL 4.1 or later you can spread load between several physical disks by setting
--tmpdir to a list of paths separated by colon :(semicolon ;on Windows). They will be
used in round-robin fashion. Note: These paths should end up on different physical disks,
not different partitions of the same disk.
A.4.5 How to Protect or Change the MySQL Socket File
/tmp/mysql.sock
If you have problems with the fact that anyone can delete the MySQL communication socket
/tmp/mysql.sock’, you can, on most versions of Unix, protect your ‘/tmp’ filesystem by
setting the sticky bit on it. Log in as root and do the following:
shell> chmod +t /tmp
This will protect your ‘/tmp’ filesystem so that files can be deleted only by their owners or
the superuser (root).
You can check if the sticky bit is set by executing ls -ld /tmp. If the last permission bit
is t, the bit is set.
You can change the place where MySQL uses / puts the socket file the following ways:
Specify the path in a global or local option file. For example, put in /etc/my.cnf:
[client]
socket=path-for-socket-file
[mysqld]
socket=path-for-socket-file
See hundefinedi[Option files], page hundefinedi.
Appendix A: Problems and Common Errors 709
Specifying this on the command-line to safe_mysqld and most clients with the --
socket=path-for-socket-file option.
Specify the path to the socket in the MYSQL_UNIX_PORT environment variable.
Defining the path with the configure option --with-unix-socket-path=path-for-
socket-file. See hundefinedi[configure options], page hundefinedi.
You can test that the socket works with this command:
shell> mysqladmin --socket=/path/to/socket version
A.4.6 Time Zone Problems
If you have a problem with SELECT NOW() returning values in GMT and not your local
time, you have to set the TZ environment variable to your current time zone. This should
be done for the environment in which the server runs, for example, in safe_mysqld or
mysql.server. See hundefinedi[Environment variables], page hundefinedi.
A.5 Query Related Issues
A.5.1 Case-Sensitivity in Searches
By default, MySQL searches are case-insensitive (although there are some character sets
that are never case-insensitive, such as czech). That means that if you search with nome_
coluna LIKE ’a%’, you will get all column values that start with Aor a. If you want to
make this search case-sensitive, use something like INSTR(nome_coluna, "A")=1 to check
a prefix. Or use STRCMP(nome_coluna, "A") = 0 if the column value must be exactly "A".
Simple comparison operations (>=, >, = , < , <=, sorting and grouping) are based on each
character’s “sort value”. Characters with the same sort value (like E, e and ´e) are treated
as the same character!
In older MySQL versions LIKE comparisons were done on the uppercase value of each
character (E == e but E <> ´e). In newer MySQL versions LIKE works just like the other
comparison operators.
If you want a column always to be treated in case-sensitive fashion, declare it as BINARY.
See hundefinedi[CREATE TABLE], page hundefinedi.
If you are using Chinese data in the so-called big5 encoding, you want to make all character
columns BINARY. This works because the sorting order of big5 encoding characters is based
on the order of ASCII codes.
A.5.2 Problems Using DATE Columns
The format of a DATE value is ’YYYY-MM-DD’. According to standard SQL, no other format
is allowed. You should use this format in UPDATE expressions and in the WHERE clause of
SELECT statements. For example:
mysql> SELECT * FROM nome_tabela WHERE date >= ’1997-05-05’;
As a convenience, MySQL automatically converts a date to a number if the date is used
in a numeric context (and vice versa). It is also smart enough to allow a “relaxed” string
710 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
form when updating and in a WHERE clause that compares a date to a TIMESTAMP,DATE, or a
DATETIME column. (Relaxed form means that any punctuation character may be used as the
separator between parts. For example, ’1998-08-15’ and ’1998#08#15’ are equivalent.)
MySQL can also convert a string containing no separators (such as ’19980815’), provided
it makes sense as a date.
The special date ’0000-00-00’ can be stored and retrieved as ’0000-00-00’. When using
a’0000-00-00’ date through MyODBC, it will automatically be converted to NULL in MyODBC
Version 2.50.12 and above, because ODBC can’t handle this kind of date.
Because MySQL performs the conversions described above, the following statements work:
mysql> INSERT INTO nome_tabela (idate) VALUES (19970505);
mysql> INSERT INTO nome_tabela (idate) VALUES (’19970505’);
mysql> INSERT INTO nome_tabela (idate) VALUES (’97-05-05’);
mysql> INSERT INTO nome_tabela (idate) VALUES (’1997.05.05’);
mysql> INSERT INTO nome_tabela (idate) VALUES (’1997 05 05’);
mysql> INSERT INTO nome_tabela (idate) VALUES (’0000-00-00’);
mysql> SELECT idate FROM nome_tabela WHERE idate >= ’1997-05-05’;
mysql> SELECT idate FROM nome_tabela WHERE idate >= 19970505;
mysql> SELECT MOD(idate,100) FROM nome_tabela WHERE idate >= 19970505;
mysql> SELECT idate FROM nome_tabela WHERE idate >= ’19970505’;
However, the following will not work:
mysql> SELECT idate FROM nome_tabela WHERE STRCMP(idate,’19970505’)=0;
STRCMP() is a string function, so it converts idate to a string and performs a string com-
parison. It does not convert ’19970505’ to a date and perform a date comparison.
Note that MySQL does very limited checking whether the date is correct. If you store an
incorrect date, such as ’1998-2-31’, the wrong date will be stored.
Because MySQL packs dates for storage, it can’t store any given date as it would not fit
onto the result buffer. The rules for accepting a date are:
If MySQL can store and retrieve a given date, the wrong date is accepted for DATE and
DATETIME columns.
All days values between 0-31 are accepted for any date. This makes it very convenient
for web applications where you ask year, month and day in 3 different fields.
The day or month field may be zero. This is convenient if you want to store a birthdate
inaDATE column and you only know part of the date.
If the date cannot be converted to any reasonable value, a 0is stored in the DATE field,
which will be retrieved as 0000-00-00. This is both a speed and convenience issue as we
believe that the database’s responsibility is to retrieve the same date you stored (even if
the data was not logically correct in all cases). We think it is up to the application to check
the dates, and not the server.
A.5.3 Problems with NULL Values
The concept of the NULL value is a common source of confusion for newcomers to SQL, who
often think that NULL is the same thing as an empty string "". This is not the case! For
example, the following statements are completely different:
Appendix A: Problems and Common Errors 711
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ("");
Both statements insert a value into the phone column, but the first inserts a NULL value
and the second inserts an empty string. The meaning of the first can be regarded as “phone
number is not known” and the meaning of the second can be regarded as “she has no
phone”.
In SQL, the NULL value is always false in comparison to any other value, even NULL. An
expression that contains NULL always produces a NULL value unless otherwise indicated in
the documentation for the operators and functions involved in the expression. All columns
in the following example return NULL:
mysql> SELECT NULL,1+NULL,CONCAT(’Invisible’,NULL);
If you want to search for column values that are NULL, you cannot use the =NULL test. The
following statement returns no rows, because expr = NULL is FALSE, for any expression:
mysql> SELECT * FROM my_table WHERE phone = NULL;
To look for NULL values, you must use the IS NULL test. The following shows how to find
the NULL phone number and the empty phone number:
mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";
Note that you can only add an index on a column that can have NULL values if you are
using MySQL Version 3.23.2 or newer and are using the MyISAM or InnoDB table type. In
earlier versions and with other table types, you must declare such columns NOT NULL. This
also means you cannot then insert NULL into an indexed column.
When reading data with LOAD DATA INFILE, empty columns are updated with ’’. If you
want a NULL value in a column, you should use \N in the text file. The literal word ’NULL’
may also be used under some circumstances. See hundefinedi[LOAD DATA], page hundefinedi.
When using ORDER BY,NULL values are presented first. In versions prior to 4.0.2, if you sort
in descending order using DESC,NULL values are presented last. When using GROUP BY, all
NULL values are regarded as equal.
To help with NULL handling, you can use the IS NULL and IS NOT NULL operators and the
IFNULL() function.
For some column types, NULL values are handled specially. If you insert NULL into the first
TIMESTAMP column of a table, the current date and time is inserted. If you insert NULL into
an AUTO_INCREMENT column, the next number in the sequence is inserted.
A.5.4 Problems with alias
You can use an alias to refer to a column in the GROUP BY,ORDER BY, or in the HAVING part.
Aliases can also be used to give columns better names:
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM table_name;
Note that standard SQL doesn’t allow you to refer to an alias in a WHERE clause. This is
because when the WHERE code is executed the column value may not yet be determined. For
example, the following query is illegal:
712 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
The WHERE statement is executed to determine which rows should be included in the GROUP
BY part while HAVING is used to decide which rows from the result set should be used.
A.5.5 Deleting Rows from Related Tables
As MySQL doesn’t support subqueries (prior to Version 4.1), nor the use of more than one
table in the DELETE statement (prior to Version 4.0), you should use the following approach
to delete rows from 2 related tables:
1. SELECT the rows based on some WHERE condition in the main table.
2. DELETE the rows in the main table based on the same condition.
3. DELETE FROM related_table WHERE related_column IN (selected_rows).
If the total number of characters in the query with related_column is more than 1,048,576
(the default value of max_allowed_packet, you should split it into smaller parts and execute
multiple DELETE statements. You will probably get the fastest DELETE by only deleting 100-
1000 related_column ids per query if the related_column is an index. If the related_
column isn’t an index, the speed is independent of the number of arguments in the IN
clause.
A.5.6 Solving Problems with No Matching Rows
If you have a complicated query that has many tables and that doesn’t return any rows,
you should use the following procedure to find out what is wrong with your query:
1. Test the query with EXPLAIN and check if you can find something that is obviously
wrong. See hundefinedi[EXPLAIN], page hundefinedi.
2. Select only those fields that are used in the WHERE clause.
3. Remove one table at a time from the query until it returns some rows. If the tables
are big, it’s a good idea to use LIMIT 10 with the query.
4. Do a SELECT for the column that should have matched a row against the table that
was last removed from the query.
5. If you are comparing FLOAT or DOUBLE columns with numbers that have decimals, you
can’t use ’=’. This problem is common in most computer languages because floating-
point values are not exact values. In most cases, changing the FLOAT to a DOUBLE will
fix this. See hundefinedi[Problems with float], page hundefinedi.
6. If you still can’t figure out what’s wrong, create a minimal test that can be run with
mysql test < query.sql that shows your problems. You can create a test file with
mysqldump --quick database tables > query.sql. Open the file in an editor, remove
some insert lines (if there are too many of these), and add your select statement at the
end of the file.
Test that you still have your problem by doing:
shell> mysqladmin create test2
shell> mysql test2 < query.sql
Post the test file using mysqlbug to mysql@lists.mysql.com.
Appendix A: Problems and Common Errors 713
A.5.7 Problems with Floating-Point Comparison
floating-point numbers cause confusion sometimes, because these numbers are not stored as
exact values inside computer architecture. What one can see on the screen usually is not
the exact value of the number.
Field types FLOAT,DOUBLE and DECIMAL are such.
CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
(2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
(4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
(5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
(6, 0.00, 0.00), (6, -51.40, 0.00);
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i | a | b |
+------+--------+-------+
| 1 | 21.40 | 21.40 |
| 2 | 76.80 | 76.80 |
| 3 | 7.40 | 7.40 |
| 4 | 15.40 | 15.40 |
| 5 | 7.20 | 7.20 |
| 6 | -51.40 | 0.00 |
+------+--------+-------+
The result is correct. Although the first five records look like they shouldn’t pass the
comparison test, they may do so because the difference between the numbers show up
around tenth decimal, or so depending on computer architecture.
The problem cannot be solved by using ROUND() (or similar function), because the result
is still a floating-point number. Example:
mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i | a | b |
+------+--------+-------+
| 1 | 21.40 | 21.40 |
| 2 | 76.80 | 76.80 |
| 3 | 7.40 | 7.40 |
| 4 | 15.40 | 15.40 |
| 5 | 7.20 | 7.20 |
| 6 | -51.40 | 0.00 |
+------+--------+-------+
This is what the numbers in column ’a’ look like:
mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a,
-> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b;
+------+----------------------+-------+
714 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
| i | a | b |
+------+----------------------+-------+
| 1 | 21.3999999999999986 | 21.40 |
| 2 | 76.7999999999999972 | 76.80 |
| 3 | 7.4000000000000004 | 7.40 |
| 4 | 15.4000000000000004 | 15.40 |
| 5 | 7.2000000000000002 | 7.20 |
| 6 | -51.3999999999999986 | 0.00 |
+------+----------------------+-------+
Depending on the computer architecture you may or may not see similar results. Each CPU
may evaluate floating-point numbers differently. For example in some machines you may
get ’right’ results by multiplaying both arguments with 1, an example follows.
WARNING: NEVER TRUST THIS METHOD IN YOUR APPLICATION, THIS IS AN
EXAMPLE OF A WRONG METHOD!!!
mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+------+
| i | a | b |
+------+--------+------+
| 6 | -51.40 | 0.00 |
+------+--------+------+
The reason why the above example seems to be working is that on the particular machine
where the test was done, the CPU floating-point arithmetics happens to round the numbers
to same, but there is no rule that any CPU should do so, so it cannot be trusted.
The correct way to do floating-point number comparison is to first decide on what is the
wanted tolerance between the numbers and then do the comparison against the tolerance
number. For example, if we agree on that floating-point numbers should be regarded the
same, if they are same with precision of one of ten thousand (0.0001), the comparison should
be done like this:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+--------+------+
| i | a | b |
+------+--------+------+
| 6 | -51.40 | 0.00 |
+------+--------+------+
1 row in set (0.00 sec)
And vice versa, if we wanted to get rows where the numbers are the same, the test would
be:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) < 0.0001;
+------+-------+-------+
| i | a | b |
+------+-------+-------+
| 1 | 21.40 | 21.40 |
| 2 | 76.80 | 76.80 |
| 3 | 7.40 | 7.40 |
Appendix A: Problems and Common Errors 715
| 4 | 15.40 | 15.40 |
| 5 | 7.20 | 7.20 |
+------+-------+-------+
A.6 Table Definition Related Issues
A.6.1 Problems with ALTER TABLE.
ALTER TABLE changes a table to the current character set. If you get a duplicate key error
during ALTER TABLE, then the cause is either that the new character sets maps two keys to
the same value or that the table is corrupted, in which case you should run REPAIR TABLE
on the table.
If ALTER TABLE dies with an error like this:
Error on rename of ’./database/name.frm’ to ’./database/B-a.frm’ (Errcode: 17)
the problem may be that MySQL has crashed in a previous ALTER TABLE and there is an old
table named ‘A-something’ or ‘B-something’ lying around. In this case, go to the MySQL
data directory and delete all files that have names starting with A- or B-. (You may want
to move them elsewhere instead of deleting them.)
ALTER TABLE works the following way:
Create a new table named ‘A-xxx’ with the requested changes.
All rows from the old table are copied to ‘A-xxx’.
The old table is renamed ‘B-xxx’.
A-xxx’ is renamed to your old table name.
B-xxx’ is deleted.
If something goes wrong with the renaming operation, MySQL tries to undo the changes.
If something goes seriously wrong (this shouldn’t happen, of course), MySQL may leave the
old table as ‘B-xxx’, but a simple rename on the system level should get your data back.
A.6.2 How To Change the Order of Columns in a Table
The whole point of SQL is to abstract the application from the data storage format. You
should always specify the order in which you wish to retrieve your data. For example:
SELECT nome_coluna1, nome_coluna2, nome_coluna3 FROM nome_tabela;
will return columns in the order nome_coluna1,nome_coluna2,nome_coluna3, whereas:
SELECT nome_coluna1, nome_coluna3, nome_coluna2 FROM nome_tabela;
will return columns in the order nome_coluna1,nome_coluna3,nome_coluna2.
If you want to change the order of columns anyway, you can do it as follows:
1. Create a new table with the columns in the right order.
2. Execute INSERT INTO new_table SELECT fields-in-new_table-order FROM
old_table.
3. Drop or rename old_table.
4. ALTER TABLE new_table RENAME old_table.
716 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
You should never, in an application, use SELECT * and retrieve the columns based on their
position, because the order and position in which columns are returned cannot may not
remain the same (if you add/move/delete columns). A simple change to your database
structure would then cause your application to fail. Of course SELECT * is quite suitable
for testing queries.
A.6.3 TEMPORARY TABLE problems
The following are a list of the limitations with TEMPORARY TABLES.
A temporary table can only be of type HEAP,ISAM,MyISAM,MERGE, or InnoDB.
You can’t use temporary tables more than once in the same query. For example, the
following doesn’t work.
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
You can’t use RENAME on a TEMPORARY table. Note that ALTER TABLE org_name RENAME
new_name works!
Appendix B: Contributed Programs 717
Appendix B Contributed Programs
Many users of MySQL have contributed very useful support tools and add-ons.
A list of some software available from the MySQL website (or any mirror) is shown here.
You can also visit our online listing of MySQL-related software at http://www.mysql.com/portal/software/.
The community facilities there also allow for your input!
If you want to build MySQL support for the Perl DBI/DBD interface, you should fetch the
Data-Dumper,DBI, and DBD-mysql files and install them. See hundefinedi[Perl support],
page hundefinedi.
Note: The programs listed here can be freely downloaded and used. They are copyrighted
by their respective owners. Please see individual product documentation for more details on
licensing and terms. MySQL AB assumes no liability for the correctness of the information
in this chapter or for the proper operation of the programs listed herein.
B.1 APIs
Perl Modules
http://www.mysql.com/Downloads/Contrib/KAMXbase1.2.tar.gz Convert
between ‘.dbf’ files and MySQL tables. Perl module written by Pratap
Pereira pereira@ee.eng.ohio-state.edu, extended by Kevin A. McGrail
kmcgrail@digital1.peregrinehw.com. This converter can handle MEMO fields.
http://www.mysql.com/Downloads/Contrib/HandySQL-1.1.tar.gz HandySQL
is a MySQL access module. It offers a C interface embedded in Perl and is ap-
proximately 20% faster than regular DBI.
OLEDB
http://www.mysql.com/Downloads/Win32/MyOLEDB3.exe MyOLEDB 3.0 instal-
lation package from SWSoft.
http://www.mysql.com/Downloads/Win32/mysql-oledb-3.0.0.zip Source for
MyOLEDB 3.0.
http://www.mysql.com/Downloads/Win32/MySamples.zip Examples and docu-
mentation for MyOLEDB.
http://www.mysql.com/Downloads/Win32/MyOLEDB.chm Help files for
MyOLEDB.
http://www.mysql.com/Downloads/Win32/libmyodbc.zip Static MyODBC li-
brary used for build MyOLEDB. Based on MyODBC code.
C++
http://www.mysql.com/Downloads/Contrib/mysql-c++-0.02.tar.gz MySQL
C++ wrapper library. By Roland Haenel, rh@ginster.net.
http://www.mysql.com/Downloads/Contrib/MyDAO.tar.gz MySQL C++ API.
By Satish spitfire@pn3.vsnl.net.in. Inspired by Roland Haenel’s C++ API
and Ed Carp’s MyC library.
718 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
http://www.mysql.com/products/mysql++/ MySQL C++ API (more than just a
wrapper library). Originally by kevina@clark.net. Now maintained by Sinisa at
MySQL AB.
http://nelsonjr.homepage.com/NJrAPI/ A C++ database independent library
that supports MySQL.
Delphi
http://www.mysql.com/Downloads/Contrib/DelphiMySQL2.zip Delphi
interface to libmysql.dll,bybsilva@umesd.k12.or.us.
http://www.mysql.com/Downloads/Contrib/Udmysql.pas A wrapper for
libmysql.dll for usage in Delphi. By Reiner Sombrowsky.
http://www.fichtner.net/delphi/mysql.delphi.phtml A Delphi Interface to
MySQL, with source code. By Matthias Fichtner.
http://www.productivity.org/projects/tmysql/ TmySQL, a library to use
MySQL with Delphi.
https://sourceforge.net/projects/zeoslib/ Zeos Library is a set of delphi
native datasets and database components for MySql, PostgreSQL, Interbase, MS
SQL, Oracle, DB/2. Also it includes development tools such as Database Explorer
and Database Designer.
http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe
Delphi 5 Shareware MySQL Dataset Components.
http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz MySQL
Ruby module. By TOMITA Masahiro tommy@tmtm.org Ruby is an Object-Oriented
Interpreter Language (http://www.netlab.co.jp/ruby/).
http://www.mysql.com/Downloads/Contrib/JdmMysqlDriver-0.1.0.tar.gz A Vi-
sualWorks 3.0 Smalltalk driver for MySQL. By joshmiller@earthlink.net.
http://www.mysql.com/Downloads/Contrib/Db.py Python module with caching. By
gandalf@rosmail.com.
http://www.mysql.com/Downloads/Contrib/MySQLmodule-1.4.tar.gz Python
interface for MySQL. By Joseph Skinner joe@earthlight.co.nz. Modified by Joerg
Senekowitsch senekow@ibm.net.
http://www.mysql.com/Downloads/Contrib/MySQL-python-0.3.0.tar.gz
MySQLdb Python is an DB-API v2.0-compliant interface to MySQL. Transactions
are supported if the server and tables support them. It is thread-safe, and
contains a compatibility module for older code written for the no-longer-maintained
MySQLmodule interface.
http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz An in-
terface program for the Matlab program by MathWorks. The interface
is done by Kimmo Uutela and John Fisher (not by Mathworks). Check
http://boojum.hut.fi/~kuutela/mysqlmex.html for more information.
http://www.mysql.com/Downloads/Contrib/mysqltcl-1.53.tar.gz Tcl interface
for MySQL. Based on ‘msqltcl-1.50.tar.gz’. For version 2.0 and more info, see
http://www.xdobry.de/mysqltcl/.
http://www.mysql.com/Downloads/Contrib/MyC-0.1.tar.gz A Visual Basic-like
API, by Ed Carp.
Appendix B: Contributed Programs 719
http://www.mysql.com/Downloads/Contrib/Vdb-dflts-2.1.tar.gz This is a new
version of a set of library utilities intended to provide a generic interface to SQL
database engines such that your application becomes a 3-tiered application. The ad-
vantage is that you can easily switch between and move to other database engines
by implementing one file for the new backend without making any changes to your
applications. By damian@cablenet.net.
http://www.mysql.com/Downloads/Contrib/DbFramework-1.10.tar.gz DbFrame-
work is a collection of classes for manipulating MySQL databases. The classes
are loosely based on the CDIF Data Model Subject Area. By Paul Sharpe
paul@miraclefish.com.
http://www.mysql.com/Downloads/Contrib/pike-mysql-1.4.tar.gz MySQL mod-
ule for pike. For use with the Roxen web server.
http://www.mysql.com/Downloads/Contrib/squile.tar.gz Module for guile that
allows guile to interact with SQL databases. By Hal Roberts.
http://www.mysql.com/Downloads/Contrib/stk-mysql.tar.gz Interface for Stk.
Stk is the Tk widgets with Scheme underneath instead of Tcl. By Terry Jones.
http://www.mysql.com/Downloads/Contrib/eiffel-wrapper-1.0.tar.gz Eiffel
wrapper by Michael Ravits.
http://www.mysql.com/Downloads/Contrib/SQLmy0.06.tgz FlagShip Replaceable
Database Driver (RDD) for MySQL. By Alejandro Fernandez Herrero. The Flagship
RDD homepage is at http://www.fship.com/rdds.html.
http://www.mysql.com/Downloads/Contrib/mydsn-1.0.zip Binary and source for
mydsn.dll. mydsn should be used to build and remove the DSN registry file for the
MyODBC driver in Coldfusion applications. By Miguel Angel Sol´orzano.
http://www.mysql.com/Downloads/Contrib/MySQL-ADA95_API.zip An ADA95 in-
terface to the MySQL API. By Francois Fabien.
http://www.mysql.com/Downloads/Contrib/MyTool-DLL_for_VB_and_MySQL.zip
A DLL with MySQL C API for Visual Basic. By Ken Menzel kenm@icarz.com.
http://www.mysql.com/Downloads/Contrib/MYSQLX.EXE MySQL ActiveX Object
for directly accessing your MySQL servers from IIS/ASP, VB, VC++ skipping the
slower ODBC methods. Fully updatable, multi-threaded with full support for all
MySQL fieldtypes (version 2001.1.1). By SciBit http://www.scibit.com/.
http://www.fastflow.it/mylua/ MyLUA home page; how to use the LUA language
to write MySQL PROCEDURE that can be loaded runtime.
http://www.mysql.com/Downloads/Contrib/lua-4.0.tar.gz LUA 4.0
http://www.mysql.com/Downloads/Contrib/mylua-3.23.32.1.tar.gz Patch
for MySQL 3.23.32 to use LUA 4.0. By Cristian Giussani.
http://www.mysql.com/Downloads/Contrib/patched_myodbc.zip Patch
(for Omniform 4.0 support) to the MyODBC driver. By Thomas Thaele
tthaele@papenmeier.de
B.2 Converters
http://www.mysql.com/Downloads/Contrib/mssql2mysql.txt Converter from
720 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
MS-SQL to MySQL. By Michael Kofler. The mssql2mysql home page is at
http://www.kofler.cc/mysql/mssql2mysql.html.
http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.14.tar.gz Con-
vert between ‘.dbf’ files and MySQL tables. By Maarten Boekhold
(boekhold@cindy.et.tudelft.nl), William Volkman, and Michael Wide-
nius. This converter includes rudimentary read-only support for MEMO
fields.
http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.13.tgz Con-
vert between ‘.dbf’ files and MySQL tables. By Maarten Boekhold,
boekhold@cindy.et.tudelft.nl, and Michael Widenius. This converter can’t handle
MEMO fields.
http://www.mysql.com/Downloads/Contrib/dbf2mysql.zip Convert between Fox-
Pro ‘.dbf’ files and MySQL tables on Windows. By Alexander Eltsyn, ae@nica.ru or
ae@usa.net.
http://www.mysql.com/Downloads/Contrib/dbf2sql.zip Short and simple prg that
can help you transport your data from foxpro table into MySQL table. By Danko Josic.
http://www.mysql.com/Downloads/Contrib/dump2h-1.20.gz Convert
from mysqldump output to a C header file. By Harry Brueckner,
brueckner@mail.respublica.de.
http://www.mysql.com/Downloads/Contrib/exportsql.txt A script that is similar
to access_to_mysql.txt, except that this one is fully configurable, has better type
conversion (including detection of TIMESTAMP fields), provides warnings and sugges-
tions while converting, quotes all special characters in text and binary data, and
so on. It will also convert to mSQL v1 and v2, and is free of charge for anyone.
See http://www.cynergi.net/exportsql/ for the latest version. By Pedro Freire,
support@cynergi.net. Note: Doesn’t work with Access2!
http://www.mysql.com/Downloads/Contrib/access_to_mysql.txt Paste this func-
tion into an Access module of a database that has the tables you want to export. See
also exportsql. By Brian Andrews. Note: Doesn’t work with Access2!
http://www.mysql.com/Downloads/Contrib/importsql.txt A script that does
the exact reverse of exportsql.txt. That is, it imports data from MySQL
into an Access database via ODBC. This is very handy when combined with
exportsql, because it lets you use Access for all DB design and administration,
and synchronise with your actual MySQL server either way. Free of charge. See
http://www.netdive.com/freebies/importsql/ for any updates. Created by
Laurent Bossavit of NetDIVE. Note: doesn’t work with Access2!
http://www.mysql.com/Downloads/Contrib/mdb2sql.bas Converter from Access97
to MySQL by Moshe Gurvich.
http://www.mysql.com/Downloads/Contrib/msql2mysqlWrapper-1.0.tgz A C
wrapper from mSQL to MySQL. By alfred@sb.net
http://www.mysql.com/Downloads/Contrib/sqlconv.pl A simple script that can be
used to copy fields from one MySQL table to another in bulk. Basically, you can run
mysqldump and pipe it to the sqlconv.pl script. The script will parse through the
mysqldump output and will rearrange the fields so they can be inserted into a new table.
An example is when you want to create a new table for a different site you are working
Appendix B: Contributed Programs 721
on, but the table is just a bit different (that is - fields in different order, etc.). By Steve
Shreeve.
http://www.mysql.com/Downloads/Contrib/oracledump Perl program to convert
Oracle databases to MySQL. Has same output format as mysqldump. By Johan
Andersson.
http://www.mysql.com/Downloads/Contrib/excel2mysql Perl program
to import Excel spreadsheets into a MySQL database. By Stephen Hurd
shurd@sk.sympatico.ca
http://www.mysql.com/Downloads/Contrib/T2S_100.ZIP. Windows program to
convert text files to MySQL databases. By Asaf Azulay.
B.3 Utilities
http://worldcommunity.com/opensource/utilities/mysql_backup.html MySQL
Backup is a backup script for MySQL. By Peter F. Brown.
http://www.mysql.com/Downloads/Contrib/mysql_watchdog.pl Monitor the
MySQL daemon for possible lockups. By Yermo Lamers, yml@yml.com.
http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tar.gz
http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tgz Prints
the structure of every table in a database. By Thomas Wana.
http://www.mysql.com/Downloads/Contrib/mysqlsync. A Perl script to keep re-
mote copies of a MySQL database in sync with a central master copy. By Mark
Jeftovic. markjr@easydns.com.
http://www.mysql.com/Downloads/Contrib/MySQLTutor-0.2.tar.gz. MySQL-
Tutor. A MySQL tutorial for beginners.
http://www.mysql.com/Downloads/Contrib/MySQLDB.zip
http://www.mysql.com/Downloads/Contrib/MySQLDB-readme.html. A COM
library for MySQL by Alok Singh.
http://www.mysql.com/Downloads/Contrib/mysql_replicate.pl Perl program
that handles replication. By elble@icculus.nsg.nwu.edu
http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz Perl
script that uses reverse indexing to handle text searching. By Daniel Koch.
http://www.mysql.com/Downloads/Contrib/dbcheck Perl script that takes a backup
of tables before running isamchk on them. By Elizabeth.
http://www.mysql.com/Downloads/Contrib/mybackup.
http://www.mswanson.com/mybackup (mybackup home page) Wrapper for
mysqldump to backup all databases. By Marc Swanson.
http://www.mysql.com/Downloads/Contrib/mdu.pl.gz Prints the storage usage of
a MySQL database.
722 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Appendix C Credits
This appendix lists the developers, contributors, and supporters that have helped to make
MySQL what it is today.
C.1 Developers at MySQL AB
These are the developers that are or have been employed by MySQL AB to work on the
MySQL database software, roughly in the order they started to work with us. Following
each developer is a small list of the tasks that the developer is responsible for, or the
accomplishments they have made. All developers are involved in support.
Michael (Monty) Widenius
Lead developer and main author of the MySQL server (mysqld).
New functions for the string library.
Most of the mysys library.
The ISAM and MyISAM libraries (B-tree index file handlers with index com-
pression and different record formats).
The HEAP library. A memory table system with our superior full dynamic
hashing. In use since 1981 and published around 1984.
The replace program (take a look at it, it’s COOL!).
MyODBC, the ODBC driver for Windows95.
Fixing bugs in MIT-pthreads to get it to work for MySQL Server. And
also Unireg, a curses-based application tool with many utilities.
Porting of mSQL tools like msqlperl,DBD/DBI, and DB2mysql.
Most of crash-me and the foundation for the MySQL benchmarks.
David Axmark
Initial main writer of the Reference Manual, including enhancements to
texi2html.
Automatic web site updating from the manual.
Initial Autoconf, Automake, and Libtool support.
Licensing.
Parts of all the text files. (Nowadays only the ‘README’ is left. The rest
ended up in the manual.)
Lots of testing of new features.
Our in-house Free Software legal expert.
Mailing list maintainer (who never has the time to do it right...).
Our original portability code (more than 10 years old now). Nowadays
only some parts of mysys are left.
Someone for Monty to call in the middle of the night when he just got that
new feature to work.
Chief "Open Sourcerer"(MySQL community relations).
Appendix C: Credits 723
Jani Tolonen mysqlimport
A lot of extensions to the command-line clients.
PROCEDURE ANALYSE()
Sinisa Milivojevic
Compression (with zlib) in the client/server protocol.
Perfect hashing for the lexical analyser phase.
Multi-row INSERT
mysqldump -e option
LOAD DATA LOCAL INFILE
SQL_CALC_FOUND_ROWS SELECT option
--max-user-connections=... option
net_read and net_write_timeout
GRANT/REVOKE and SHOW GRANTS FOR
New client-server protocol for 4.0
UNION in 4.0
Multi-table DELETE/UPDATE
Derived tables in 4.1
User resources management
Initial developer of the MySQL++ C++ API and the MySQLGUI client.
Tonu Samuel (past developer)
VIO interface (the foundation for the encrypted client/server protocol).
MySQL Filesystem (a way to use MySQL databases as files and directo-
ries).
The CASE expression.
The MD5() and COALESCE() functions.
RAID support for MyISAM tables.
Sasha Pachev Initial implementation of replication (up to version 4.0).
SHOW CREATE TABLE.
mysql-bench
Matt Wagner MySQL test suite.
Webmaster (until 2002).
Coordinator of development.
Miguel Solorzano
Win32 development and release builds.
Windows NT server code.
WinMySQLAdmin
Timothy Smith (past developer)
Dynamic character sets support.
724 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
configure, RPMs and other parts of the build system.
Initial developer of libmysqld, the embedded server.
Sergei Golubchik
Full-text search.
Added keys to the MERGE library.
Jeremy Cole Proofreading and editing this fine manual.
ALTER TABLE ... ORDER BY ....
UPDATE ... ORDER BY ....
DELETE ... ORDER BY ....
Indrek Siitan Designing/programming of our web interface.
Author of our newsletter management system.
Jorge del Conde
MySQLCC (MySQL Control Center)
Win32 development
Initial implementation of the website portals.
Venu Anuganti
Connector/ODBC (MyODBC) 3.51
New client/server protocol for 4.1 (for prepared statements).
Arjen Lentz Maintainer of the MySQL Reference Manual.
Preparing the O’Reilly printed edition of the manual.
Alexander (Bar) Barkov, Alexey (Holyfoot) Botchkov, and Ramil Kalimullin
Spatial data (GIS) and R-Trees implementation for 4.1
Unicode and character sets for 4.1
Oleksandr (Sanja) Byelkin
Query cache in 4.0
Implementation of subqueries (4.1).
Aleksey (Walrus) Kishkin and Alexey (Ranger) Stroganov
Benchmarks design and analysis.
Maintenance of the MySQL test suite.
Zak Greant Open Source advocate, MySQL community relations.
Carsten Pedersen
The MySQL Certification program.
Lenz Grimmer
Production (build and release) engineering.
Peter Zaitsev SHA1(),AES_ENCRYPT() and AES_DECRYPT() functions.
Appendix C: Credits 725
Debugging, cleaning up various features.
Alexander (Salle) Keremidarski
Support.
Debugging.
Per-Erik Martin
Lead developer for stored procedures (5.0) and triggers.
Jim WinsteadLead web developer.
Mark Matthews
Connector/J driver (Java).
Peter Gulutzan
SQL-99, SQL:2003 standards compliance.
Documentation of existing MySQL code/algorithms.
C.2 Contributors to MySQL
While MySQL AB owns all copyrights in the MySQL server and the MySQL manual, we wish
to recognise those who have made contributions of one kind or another to the MySQL
distribution. Contributors are listed here, in somewhat random order:
Paul DuBois
Ongoing help with making this manual correct and understandable. That in-
cludes rewriting Monty’s and David’s attempts at English into English as other
people know it.
Gianmassimo Vigazzola qwerg@mbox.vol.it or qwerg@tin.it
The initial port to Win32/NT.
Kim Aldale
Helped to rewrite Monty’s and David’s early attempts at English into English.
Per Eric Olsson
For more or less constructive criticism and real testing of the dynamic record
format.
Irena Pancirov irena@mail.yacc.it
Win32 port with Borland compiler. mysqlshutdown.exe and mysqlwatch.exe
David J. Hughes
For the effort to make a shareware SQL database. At TcX, the predeces-
sor of MySQL AB, we started with mSQL, but found that it couldn’t satisfy
our purposes so instead we wrote a SQL interface to our application builder
Unireg. mysqladmin and mysql client are programs that were largely influ-
enced by their mSQL counterparts. We have put a lot of effort into making
the MySQL syntax a superset of mSQL. Many of the API’s ideas are borrowed
from mSQL to make it easy to port free mSQL programs to the MySQL API. The
MySQL software doesn’t contain any code from mSQL. Two files in the dis-
tribution (‘client/insert_test.c’ and ‘client/select_test.c’) are based
726 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
on the corresponding (non-copyrighted) files in the mSQL distribution, but are
modified as examples showing the changes necessary to convert code from mSQL
to MySQL Server. (mSQL is copyrighted David J. Hughes.)
Fred Fish For his excellent C debugging and trace library. Monty has made a number of
smaller improvements to the library (speed and additional options).
Richard A. O’Keefe
For his public domain string library.
Henry Spencer
For his regex library, used in WHERE column REGEXP regexp.
Free Software Foundation
From whom we got an excellent compiler (gcc), the libc library (from which we
have borrowed ‘strto.c’ to get some code working in Linux), and the readline
library (for the mysql client).
Free Software Foundation & The XEmacs development team
For a really great editor/environment used by almost everybody at MySQL
AB/TcX/detron.
Patrick Lynch
For helping us acquire http://www.mysql.com/.
Fred Lindberg
For setting up qmail to handle the MySQL mailing list and for the incredible
help we got in managing the MySQL mailing lists.
Igor Romanenko igor@frog.kiev.ua
mysqldump (previously msqldump, but ported and enhanced by Monty).
Yuri Dario
For keeping up and extending the MySQL OS/2 port.
Tim Bunce, Alligator Descartes
For the DBD (Perl) interface.
Tim Bunce
Author of mysqlhotcopy.
Andreas Koenig a.koenig@mind.de
For the Perl interface for MySQL Server.
Eugene Chan eugene@acenet.com.sg
For porting PHP for MySQL Server.
Michael J. Miller Jr. mke@terrapin.turbolift.com
For the first MySQL manual. And a lot of spelling/language fixes for the FAQ
(that turned into the MySQL manual a long time ago).
Yan Cailin
First translator of the MySQL Reference Manual into simplified Chinese in
early 2000 on which the Big5 and HK coded (http://mysql.hitstar.com/)
versions were based. Personal home page at linuxdb.yeah.net.
Appendix C: Credits 727
Giovanni Maruzzelli maruzz@matrice.it
For porting iODBC (Unix ODBC).
Chris Provenzano
Portable user level pthreads. From the copyright: This product includes soft-
ware developed by Chris Provenzano, the University of California, Berkeley,
and contributors. We are currently using version 1 60 beta6 patched by Monty
(see ‘mit-pthreads/Changes-mysql’).
Xavier Leroy Xavier.Leroy@inria.fr
The author of LinuxThreads (used by the MySQL Server on Linux).
Zarko Mocnik zarko.mocnik@dem.si
Sorting for Slovenian language and the ‘cset.tar.gz’ module that makes it
easier to add other character sets.
"TAMITO"tommy@valley.ne.jp
The _MB character set macros and the ujis and sjis character sets.
Joshua Chamas joshua@chamas.com
Base for concurrent insert, extended date syntax, debugging on NT, and an-
swering on the MySQL mailing list.
Yves Carlier Yves.Carlier@rug.ac.be
mysqlaccess, a program to show the access rights for a user.
Rhys Jones rhys@wales.com (And GWE Technologies Limited)
For JDBC, a module to extract data from a MySQL Database with a Java
client.
Dr Xiaokun Kelvin ZHU X.Zhu@brad.ac.uk
Further development of the JDBC driver and other MySQL-related Java tools.
James Cooper pixel@organic.com
For setting up a searchable mailing list archive at his site.
Rick Mehalick Rick_Mehalick@i-o.com
For xmysql, a graphical X client for MySQL Server.
Doug Sisk sisk@wix.com
For providing RPM packages of MySQL for Red Hat Linux.
Diemand Alexander V. axeld@vial.ethz.ch
For providing RPM packages of MySQL for Red Hat Linux-Alpha.
Antoni Pamies Olive toni@readysoft.es
For providing RPM versions of a lot of MySQL clients for Intel and SPARC.
Jay Bloodworth jay@pathways.sde.state.sc.us
For providing RPM versions for MySQL Version 3.21.
Jochen Wiedmann wiedmann@neckar-alb.de
For maintaining the Perl DBD::mysql module.
Therrien Gilbert gilbert@ican.net, Jean-Marc Pouyot jmp@scalaire.fr
French error messages.
728 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Petr Snajdr, snajdr@pvt.net
Czech error messages.
Jaroslaw Lewandowski jotel@itnet.com.pl
Polish error messages.
Miguel Angel Fernandez Roiz
Spanish error messages.
Roy-Magne Mo rmo@www.hivolda.no
Norwegian error messages and testing of Version 3.21.#.
Timur I. Bakeyev root@timur.tatarstan.ru
Russian error messages.
brenno@dewinter.com & Filippo Grassilli phil@hyppo.com
Italian error messages.
Dirk Munzinger dirk@trinity.saar.de
German error messages.
Billik Stefan billik@sun.uniag.sk
Slovak error messages.
Stefan Saroiu tzoompy@cs.washington.edu
Romanian error messages.
Peter Feher
Hungarian error messages.
Roberto M. Serqueira
Portuguese error messages.
Carsten H. Pedersen
Danish error messages.
Arjen G. Lentz
Dutch error messages, completing earlier partial translation (also work on con-
sistency and spelling).
David Sacerdote davids@secnet.com
Ideas for secure checking of DNS hostnames.
Wei-Jou Chen jou@nematic.ieo.nctu.edu.tw
Some support for Chinese(BIG5) characters.
Wei He hewei@mail.ied.ac.cn
A lot of functionality for the Chinese(GBK) character set.
Zeev Suraski bourbon@netvision.net.il
FROM_UNIXTIME() time formatting, ENCRYPT() functions, and bison advisor.
Active mailing list member.
Luuk de Boer luuk@wxs.nl
Ported (and extended) the benchmark suite to DBI/DBD. Have been of great
help with crash-me and running benchmarks. Some new date functions. The
mysql_setpermissions script.
Appendix C: Credits 729
Jay Flaherty fty@mediapulse.com
Big parts of the Perl DBI/DBD section in the manual.
Paul Southworth pauls@etext.org, Ray Loyzaga yar@cs.su.oz.au
Proof-reading of the Reference Manual.
Alexis Mikhailov root@medinf.chuvashia.su
User-definable functions (UDFs); CREATE FUNCTION and DROP FUNCTION.
Andreas F. Bobak bobak@relog.ch
The AGGREGATE extension to UDF functions.
Ross Wakelin R.Wakelin@march.co.uk
Help to set up InstallShield for MySQL-Win32.
Jethro Wright III jetman@li.net
The ‘libmysql.dll’ library.
James Pereria jpereira@iafrica.com
Mysqlmanager, a Win32 GUI tool for administrating MySQL Server.
Curt Sampson cjs@portal.ca
Porting of MIT-pthreads to NetBSD/Alpha and NetBSD 1.3/i386.
Antony T. Curtis antony.curtis@olcs.net
Porting of the MySQL Database software to OS/2.
Martin Ramsch m.ramsch@computer.org
Examples in the MySQL Tutorial.
Steve Harvey
For making mysqlaccess more secure.
Konark IA-64 Centre of Persistent Systems Private Limited
http://www.pspl.co.in/konark/. Help with the Win64 port of the MySQL
server.
Albert Chin-A-Young.
Configure updates for Tru64, large file support and better TCP wrappers sup-
port.
John Birrell
Emulation of pthread_mutex() for OS/2.
Benjamin Pflugmann
Extended MERGE tables to handle INSERTS. Active member on the MySQL
mailing lists.
Guilhem Bichot
Fixed handling of exponents for DECIMAL. Author of mysql_tableinfo.
Jocelyn Fournier
Excellent spotting and reporting innumerable bugs (especially in the MySQL
4.1 subquery code).
Georg Richter
MySQL 4.1 testing and bug hunting. New PHP 5.0 mysqli extension (API) for
use with MySQL 4.1 and up.
730 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Marc Liyanage
Maintaining the Mac OS X packages and providing invaluable feedback on how
to create Mac OS X PKGs.
Other contributors, bugfinders, and testers: James H. Thompson, Maurizio Menghini, Wo-
jciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar Haneke, jehamby@lightside,
psmith@BayNetworks.com,duane@connect.com.au, Ted Deppner ted@psyber.com, Mike
Simons, Jaakko Hyvatti.
And lots of bug report/patches from the folks on the mailing list.
A big tribute goes to those that help us answer questions on the mysql@lists.mysql.com
mailing list:
Daniel Koch dkoch@amcity.com
Irix setup.
Luuk de Boer luuk@wxs.nl
Benchmark questions.
Tim Sailer tps@users.buoy.com
DBD-mysql questions.
Boyd Lynn Gerber gerberb@zenez.com
SCO-related questions.
Richard Mehalick RM186061@shellus.com
xmysql-related questions and basic installation questions.
Zeev Suraski bourbon@netvision.net.il
Apache module configuration questions (log & auth), PHP-related questions,
SQL syntax-related questions and other general questions.
Francesc Guasch frankie@citel.upc.es
General questions.
Jonathan J Smith jsmith@wtp.net
Questions pertaining to OS-specifics with Linux, SQL syntax, and other things
that might need some work.
David Sklar sklar@student.net
Using MySQL from PHP and Perl.
Alistair MacDonald A.MacDonald@uel.ac.uk
Not yet specified, but is flexible and can handle Linux and maybe HP-UX. Will
try to get user to use mysqlbug.
John Lyon jlyon@imag.net
Questions about installing MySQL on Linux systems, using either ‘.rpm’ files
or compiling from source.
Lorvid Ltd. lorvid@WOLFENET.com
Simple billing/license/support/copyright issues.
Patrick Sherrill patrick@coconet.com
ODBC and VisualC++ interface questions.
Appendix C: Credits 731
Randy Harmon rjharmon@uptimecomputers.com
DBD, Linux, some SQL syntax questions.
C.3 Supporters to MySQL
While MySQL AB owns all copyrights in the MySQL server and the MySQL manual, we wish to
recognise the following companies, which helped us finance the development of the MySQL
server, such as by paying us for developing a new feature or giving us hardware for devel-
opment of the MySQL server.
VA Linux / Andover.net
Funded replication.
NuSphere Editing of the MySQL manual.
Stork Design studio
The MySQL web site in use between 1998-2000.
Intel Contributed to development on Windows and Linux platforms.
Compaq Contributed to Development on Linux/Alpha.
SWSoft Development on the embedded mysqld version.
FutureQuest
--skip-show-database
732 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Appendix D MySQL Change History
This appendix lists the changes from version to version in the MySQL source code.
We are now working actively on MySQL 4.1 & 5.0 and will only provide critical bug fixes
for MySQL 4.0 and MySQL 3.23. We update this section as we add new features, so that
everybody can follow the development.
Our TODO section contains what further plans we have for 4.1 & 5.0. See hundefinedi
[TODO], page hundefinedi.
Note that we tend to update the manual at the same time we make changes to MySQL.
If you find a version listed here that you can’t find on the MySQL download page
(http://www.mysql.com/downloads/), this means that the version has not yet been
released!
D.1 Changes in release 5.0.0 (Development)
For the time being, version 5.0 is only available in source code. See hundefinedi[Installing
source tree], page hundefinedi.
The following changelog shows what has already been done in the 5.0 tree:
Basic support for stored procedures (SQL-99 style).
Added SELECT INTO list_of_vars, which can be of mixed, i.e., global and local type.
Deprecated the update log (no longer supported). It is fully replaced by the binary log.
D.2 Changes in release 4.1.x (Alpha)
Version 4.1 of the MySQL server includes many enhancements and new features. Binaries
for this version are available for download at http://www.mysql.com/downloads/mysql-
4.1.html.
Subqueries:
SELECT * FROM t1 WHERE t1.a=(SELECT t2.b FROM t2);
SELECT * FROM t1 WHERE (1,2,3) IN (SELECT a,b,c FROM t2);
Derived tables:
SELECT t1.a FROM t1, (SELECT * FROM t2) t3 WHERE t1.a=t3.a;
INSERT ... ON DUPLICATE KEY UPDATE ... syntax. This allows you to UPDATE an ex-
isting row if the insert would cause a duplicate value in a PRIMARY or UNIQUE key.
(REPLACE allows you to overwrite an existing row, which is something entirely differ-
ent.) See hundefinedi[INSERT], page hundefinedi.
A newly designed GROUP_CONCAT() aggregate function. See hundefinedi[Group by
functions], page hundefinedi.
Extensive Unicode (UTF8) support.
Character sets can be defined per column, table and database.
BTREE index on HEAP tables.
Appendix D: MySQL Change History 733
Support for OpenGIS (Geographical data). See hundefinedi[GIS spatial extensions in
MySQL], page hundefinedi.
SHOW WARNINGS shows warnings for the last command. See hundefinedi[SHOW WARN-
INGS], page hundefinedi.
Faster binary protocol with prepared statements and parameter binding. See hunde-
finedi[C API Prepared statements], page hundefinedi.
Multi-line queries: You can now issue several queries at once and then read the results
in one go. See hundefinedi[C API multiple queries], page hundefinedi.
Create Table: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table LIKE table.
Server based HELP command that can be used in the mysql command line client (and
other clients) to get help for SQL commands.
For a full list of changes, please refer to the changelog sections for each individual 4.1.x
release.
D.2.1 Changes in release 4.1.1 (not released yet)
Functionality added or changed:
New global variable RELAY_LOG_PURGE to enable/disable automatic relay log purging.
LOAD DATA now produces warnings that can be fetched with SHOW WARNINGS
Bugs fixed:
Fixed a rare replication bug when a transaction spanned on two or more relay logs, and
the slave was stopped while he was executing the part of the transaction which was in
the second or further relay log. Then replication would resume at the beginning of the
second or further relay log, which was wrong (it should resume at BEGIN, in the first
relay log). Bug #53.
Fixed double freed memory
Fixed crashing bug with temp. tables in UNION’s
Fixed a crashing bug in DERIVED TABLES when EXPLAIN is used on a DERIVED TABLES
with a join
Fixed a crashing bug in DELETE with ORDER BY and LIMIT caused by non initiated array
of reference pointers.
Fixed a bug in USER() function caused by the error in the size of the allocated string
Fixed a crashing bug when attempting to create a table with GEOMETRY column type
with a storage engine that does not support it.
Fixed a crashing bug in UNION caused by the empty select list and a non-existent field
being used in some of the sub-selects.
Fixed a replication bug when the master is 3.23 and the slave 4.0: the slave lost the
replicated temporary tables if FLUSH LOGS was issued on the master (bug #254).
D.2.2 Changes in release 4.1.0 (03 Apr 2003: Alpha)
Functionality added or changed:
734 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
On Windows, we are now using shared memory to communicate between server
and client when they are running on the same machine and you are connecting to
localhost.
REPAIR of MyISAM tables now uses less temporary disk space when sorting char
columns.
DATE/DATETIME checking is now a bit stricter to support the ability to automatically
distinguish between date, datetime, and time with microseconds. For example, dates
of type YYYYMMDD HHMMDD are no longer supported; one must either have separators
between each DATE/TIME part or not at all.
Server side help for all MySQL functions. One can now type help week in the mysql
client and get help for the week() function.
Added new client function: mysql_get_server_version().
Fixed bug in libmysqlclient that fetched field defaults
Fixed bug in ‘mysql.cc’ client when skipping comments
Added record_in_range() method to MERGE tables to be able to choose the right
index when there are many to choose from.
Replication now works with RAND() and user variables @var.
Allow one to change mode for ANSI_QUOTES on the fly.
EXPLAIN SELECT now can be killed. See hundefinedi[KILL], page hundefinedi.
REPAIR TABLE now can be killed. See hundefinedi[KILL], page hundefinedi.
Allow one to specify empty key lists for USE|IGNORE|FORCE INDEX.
DROP TEMPORARY TABLE now only drops temporary tables and doesn’t end transactions.
Added a support for UNION in derived tables.
TIMESTAMP is now returned as string of type ’YYYY-MM-DD HH:MM:DD’ and different
timestamp lengths are not supported.
This change was necessary for SQL standards compliance. In a future version, a further
change will be made (backward compatible with this change), allowing the timestamp
length to indicate the desired number of digits of fractions of a second.
New faster client/server protocol which supports prepared statements, bound parame-
ters, and bound result columns, binary transfer of data, warnings.
Added database and real table name (in case of alias) to the MYSQL_FIELD structure.
Multi-line queries: You can now issue several queries at once and then read the results
in one go.
In CREATE TABLE foo (a INT not null primary key) the PRIMARY word is now op-
tional.
In CREATE TABLE the attribute SERIAL is now an alias for BIGINT NOT NULL AUTO_
INCREMENT UNIQUE.
SELECT ... FROM DUAL is an alias for SELECT .... (To be compatible with some other
databases).
If one creates a too long CHAR/VARCHAR it’s now automatically changed to TEXT or BLOB;
One will get a warning in this case.
Appendix D: MySQL Change History 735
One can specify the different BLOB/TEXT types with the syntax BLOB(length) and
TEXT(length). MySQL will automatically change it to one of the internal BLOB/TEXT
types.
CHAR BYTE is an alias for CHAR BINARY.
VARCHARACTER is an alias for VARCHAR.
New operators integer MOD integer and integer DIV integer.
SERIAL DEFAULT VALUE added as an alias for AUTO_INCREMENT.
TRUE and FALSE added as alias for 1 and 0, respectively.
Aliases are now forced in derived tables, as per SQL-99.
Fixed SELECT .. LIMIT 0 to return proper row count for SQL_CALC_FOUND_ROWS.
One can specify many temporary directories to be used in a round-robin fashion with:
--tmpdir=dirname1:dirname2:dirname3.
Subqueries: SELECT * from t1 where t1.a=(SELECT t2.b FROM t2).
Derived tables:
SELECT a.col1, b.col2
FROM (SELECT MAX(col1) AS col1 FROM root_table) a,
other_table b
WHERE a.col1=b.col1;
Character sets to be defined per column, table and database.
Unicode (UTF8) support.
BTREE index on HEAP tables.
Faster embedded server (new internal communication protocol).
One can add a comment per column in CREATE TABLE.
SHOW FULL COLUMNS FROM table_name shows column comments.
ALTER DATABASE.
Support for GIS (Geometrical data). See hundefinedi[GIS spatial extensions in
MySQL], page hundefinedi.
SHOW [COUNT(*)] WARNINGS shows warnings from the last command.
One can specify a column type for a colum in CREATE TABLE ... SELECT by defining
the column in the CREATE part.
CREATE TABLE foo (a tinyint not null) SELECT b+1 AS ’a’ FROM bar;
expr SOUNDS LIKE expr same as SOUNDEX(expr)=SOUNDEX(expr).
VARIANCE(expr) returns the variance of expr
One can create a table from the existing table using CREATE [TEMPORARY] TABLE [IF
NOT EXISTS] table (LIKE table). The table can be either normal or temporary.
New options --reconnect and disable-reconnect for the mysql client, to reconnect
automatically or not if the connection is lost.
START SLAVE (STOP SLAVE) no longer returns an error if the slave is already started
(stopped); it returns a warning instead.
SLAVE START and SLAVE STOP are no longer accepted by the query parser; use START
SLAVE and STOP SLAVE instead.
736 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.3 Changes in release 4.0.x (Production)
Version 4.0 of the MySQL server includes many enhancements and new features:
The InnoDB table type is now included in the standard binaries, adding transactions,
row-level locking, and foreign keys. See hundefinedi[InnoDB], page hundefinedi.
A query cache, offering vastly increased performance for many applications. By caching
complete result sets, later identical queries can return instantly. See hundefinedi[Query
Cache], page hundefinedi.
Improved full-text indexing with boolean mode, truncation, and phrase searching. See
hundefinedi[Fulltext Search], page hundefinedi.
Enhanced MERGE tables, now supporting INSERTs and AUTO_INCREMENT. See hunde-
finedi[MERGE], page hundefinedi.
UNION syntax in SELECT. See hundefinedi[UNION], page hundefinedi.
Multi-table DELETE statements. See hundefinedi[DELETE], page hundefinedi.
libmysqld, the embedded server library. See hundefinedi[libmysqld], page hundefinedi.
Additional GRANT privilege options for even tighter control and security. See hundefinedi
[GRANT], page hundefinedi.
Management of user resources in the GRANT system, particularly useful for ISPs and
other hosting providers. See hundefinedi[User resources], page hundefinedi.
Dynamic server variables, allowing configuration changes without having to take down
the server. See hundefinedi[SET OPTION], page hundefinedi.
Improved replication code and features. See hundefinedi[Replication], page hunde-
finedi.
Numerous new functions and options.
Changes to existing code for enhanced performance and reliability.
For a full list of changes, please refer to the changelog sections for each individual 4.0.x
release.
D.3.1 Changes in release 4.0.14 (not released yet)
Functionality added or changed:
Added multi-threaded MyISAM repair optimisation and myisam_repair_threads vari-
able to enable it. See hundefinedi[myisam_repair_threads], page hundefinedi.
Added innodb_max_dirty_pages_pct variable which controls amount of dirty pages
allowed in Innodb buffer pool.
Bugs fixed:
LOAD DATA INFILE will now read 000000 as a zero date instead as "2000-00-00".
Fixed bug that caused DELETE FROM table WHERE const_expression always to delete
the whole table (even if expression result was false). (bug #355)
Appendix D: MySQL Change History 737
D.3.2 Changes in release 4.0.13 (to be released soon)
Functionality added or changed:
Disabled MyISAM RAID in the Max binary packages - several users reported assertion
failures even when not using RAID (bug #346). Some of its functionality can be
achieved by using MERGE tables instead. See hundefinedi[MERGE tables], page hunde-
finedi.
CURRENT_USER() and "access denied"error messages now report hostname exactly as
it was specified in the GRANT command.
Removed Benchmark results from the source and binary distributions. They are still
available in the BK source tree, though.
InnoDB tables now support ANALYZE TABLE.
MySQL now issues a warning when it opens a table that was created with MySQL 4.1.
mysql’ command line client no longer looks for \* commands inside backtick-quoted
strings.
Option --new now changes binary items (0xFFDF) to be treated as binary strings in-
stead of numbers by default. This fixes some problems with character sets where it’s
convenient to input the string as a binary item. After this change you have to convert
the binary string to INTEGER with a CAST if you want to compare two binary items
with each other and know which one is bigger than the other. SELECT CAST(0xfeff AS
UNSIGNED) < CAST(0xff AS UNSIGNED). This will be the default behaviour in MySQL
4.1. (Bug #152)
Fixed bug with NATURAL LEFT JOIN,NATURAL RIGHT JOIN and RIGHT JOIN when using
many joined tables. The problem was that the JOIN method was not always associated
with the tables surrounding the JOIN method. If you have a query that uses many
RIGHT JOIN or NATURAL ... JOINS you should check that they work as you expected
after upgrading MySQL to this version. (Bug #291)
Enabled delayed_insert_timeout on Linux (most modern glibc libraries have a fixed
pthread_cond_timedwait). (Bug #211)
Don’t create more insert delayed threads than given by max_insert_delayed_threads.
(Bug #211)
Fixed that SET SQL_BIG_SELECTS=1 works as documented (New bug in 4.0)
Changed UPDATE ... LIMIT to also count accepted, but not changed rows.
Tuned optimizer to favour clustered index over table scan.
BIT_AND() and BIT_OR() now return an unsigned 64 bit value.
Added warnings to error log of why a secure connection failed (when running with
--log-warnings).
Deprecated options --skip-symlink and --use-symbolic-links and replaced these
with --symbolic-links.
The default option for innodb_flush_log_at_trx_commit was changed from 0 to 1
to make InnoDB tables ACID by default. See hundefinedi[InnoDB start], page hunde-
finedi.
Added a feature to SHOW KEYS to display keys that are disabled by ALTER TABLE
DISABLE KEYS command.
738 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
When using a non-existing table type with CREATE TABLE, first try if the default table
type exists before falling back to MyISAM.
Added MEMORY as an alias for HEAP.
Renamed function rnd to my_rnd as the name was too generic and is an exported
symbol in libmysqlclient (thanks to Dennis Haney for the initial patch).
Portability fix: renamed ‘include/dbug.h’ to ‘include/my_debug.h’.
mysqldump no longer silently deletes the binlogs when called with --master-data or
--first-slave; while this behaviour was convenient for some users, others may suffer
from it. Now one has to explicitely ask for this deletion with the new --delete-
master-logs option.
If the slave is configured (using for example replicate-wild-ignore-
table=mysql.%) to exclude mysql.user,mysql.host,mysql.db,mysql.tables_priv
and mysql.columns_priv from replication, then GRANT and REVOKE will not be
replicated.
Bugs fixed:
Fixed wrong result from truncation operator (*) in MATCH ... AGAINST() in some com-
plex joins.
Fixed a crash in REPAIR ... USE_FRM command, when used on read-only or nonexisting
table.
Fixed a crashing bug in mysql monitor program. It occured if program was started
with --no-defaults, with a prompt that contained hostname and connection to non-
existing db was requested
Fixed problem when comparing a key for a multi-byte-character set. (Bug #152)
Fixed bug in LEFT,RIGHT and MID when used with multi-byte character sets and some
GROUP BY queries. (Bug #314)
Fix problem with ORDER BY being discarded for some DISTINCT queries. (Bug #275)
Fixed some serious bugs in UPDATE ... ORDER BY. (Bug #241)
Fixed unlikely problem in optimising WHERE clause with constant expression like in
WHERE 1 AND (a=1 AND b=1).
Fixed that SET SQL_BIG_SELECTS=1 works again.
Introduced proper backtick quoting for db.table in SHOW GRANTS
Bug #283 (FULLTEXT index stops working after ALTER TABLE that converts TEXT field
to CHAR) fixed.
Mark a MyISAM table as "analyzed"only when all the keys are indeed analyzed.
Only ignore world-writeable ‘my.cnf’ files that are regular files (and not e.g. named
pipes or character devices).
Fixed few smaller issues with SET PASSWORD.
Fixed error message which contained deprecated text.
Fixed a bug with two NATURAL JOINs in the query.
SUM() didn’t return NULL when there was no rows in result or when all values was NULL.
On Unix symbolic links handling was not enabled by default and there was no way to
turn this on.
Appendix D: MySQL Change History 739
Added missing dashes to parameter --open-files-limit in ‘mysqld_safe’ (bug
#264).
Fixed wrong hostname for TCP/IP connections displayed in SHOW PROCESSLIST.
Fixed a bug with NAN in FORMAT(...) function ...
Fixed a bug with improperly cached database privileges.
Fixed a bug in ALTER TABLE ENABLE / DISABLE KEYS which failed to force a refresh of
table data in the cache.
Fixed bugs in replication of LOAD DATA INFILE for custom parameters (ENCLOSED,
TERMINATED and so on) and temporary tables (Bugs #183 and #222).
Fixed a replication bug when the master is 3.23 and the slave 4.0: the slave lost the
replicated temporary tables if FLUSH LOGS was issued on the master (bug #254).
Fixed bug in multi-table updates which occurred whenever a temporary table, con-
taining update data, had to be converted from HEAP to MyISAM.
Fixed a bug when doing LOAD DATA INFILE IGNORE : when reading the binary log,
mysqlbinlog and the replication code read REPLACE instead of IGNORE. This could
make the slave’s table become different from the master’s table. Bug #218.
Fixed a deadlock when relay_log_space_limit was set to a too small value. Bug
#79.
Fixed a bug in HAVING clause when an alias is used from the select list.
Fixed a bug in MyISAM when a row is inserted into a table with a large number of
NULL columns. Bug was caused by wrong calculation of the record length, as the space
required for storage of NULL bits was not added to the total record length.
Fixed a bug when SELECT @nonexistent variable caused the error in client - server
protocol due to net printf() being sent to the client twice.
Fixed a bug in setting SQL_BIG_SELECTS option.
Fixed a bug in SHOW PROCESSLIST which only displayed a localhost in the "Host"
column. This was caused by a glitch that only used current thread info instead info
from the linked list of threads.
Removed unnecessary Mac OS X helper files from server RPM (bug #144).
Allow optimisation of multi-table-update for InnoDB tables as well.
Fixed a bug in multi-table-updates that caused some rows to be updated several
times.
Fixed a bug in mysqldump when it was called with --master-data: the CHANGE MASTER
TO commands appended to the SQL dump had wrong coordinates (bug #159).
Fixed a bug when an updating query using USER() was replicated on the slave ; this
caused segfault on the slave (bug #178). USER() is still badly replicated on the slave
(it is replicated to "").
D.3.3 Changes in release 4.0.12 (15 Mar 2003: Production)
Functionality added or changed:
mysqld’ no longer reads options from world-writeable config files.
740 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Integer values between 9223372036854775807 and 9999999999999999999 are now re-
garded as unsigned longlongs, not as floats. This makes these values work similar to
values between 10000000000000000000 and 18446744073709551615.
SHOW PROCESSLIST will now include the client TCP port after the hostname to make
it easier to know from which client the request originated.
Bugs fixed:
Fixed ‘mysqld’ crash on extremely small values of sort_buffer variable.
INSERT INTO u SELECT ... FROM t was written too late to the binary log if t was very
frequently updated during the execution of this query. This could cause a problem
with mysqlbinlog or replication. The master must be upgraded, not the slave. (bug
#136).
Fixed checking of random part of WHERE clause (bug #142).
Fixed a bug with multi-table updates with InnoDB tables. This bug occurred as, in
many cases, InnoDB tables can not be updated "on the fly", but offsets to the records
have to be stored in a temporary table.
Added missing file ‘mysql_secure_installation’ to the server RPM subpackage
(bug #141).
Fixed MySQL (and ‘myisamchk’) crash on artificially corrupted .MYI files.
Don’t allow BACKUP TABLE to overwrite existing files.
Fixed a bug with multi-table UPDATEs when user had all privileges on the database
where tables are located and there were any entries in tables_priv table, i.e. grant_
option was true.
Fixed a bug that allowed a user with table or column grants on some table, TRUNCATE
any table in the same database.
Fixed deadlock when doing LOCK TABLE followed by DROP TABLE in the same thread. In
this case one could still kill the thread with KILL.
LOAD DATA LOCAL INFILE was not properly written to the binary log (hence not properly
replicated). (bug #82).
RAND() entries were not read correctly by mysqlbinlog from the binary log which
caused problems when restoring a table that was inserted with RAND().INSERT INTO
t1 VALUES(RAND()). In replication this worked ok.
SET SQL_LOG_BIN=0 was ignored for INSERT DELAYED queries. (bug #104).
SHOW SLAVE STATUS reported too old positions (columns Relay_Master_Log_File and
Exec_master_log_pos) for the last executed statement from the master, if this state-
ment was the COMMIT of a transaction. The master must be upgraded for that, not the
slave. (bug #52).
LOAD DATA INFILE was not replicated by the slave if replicate_*_table was set on
the slave. (bug #86).
After RESET SLAVE, the coordinates displayed by SHOW SLAVE STATUS looked un-reset
(though they were, but only internally). (bug #70).
Fixed query cache invalidation on LOAD DATA.
Fixed memory leak on ANALYZE procedure with error.
Appendix D: MySQL Change History 741
Fixed a bug in handling CHAR(0) columns that could cause wrong results from the
query.
Fixed rare bug with wrong initialization of AUTO_INCREMENT column, as a secondary
column in a multi-column key (see AUTO˙INCREMENT-snt [AUTO_INCREMENT on sec-
ondary column in a multi-column key], page AUTO˙INCREMENT-pg), when data was
inserted with INSERT ... SELECT or LOAD DATA into an empty table.
On windows, STOP SLAVE didn’t stop the slave until the slave got one new command
from the master (this bug has been fixed for MySQL 4.0.11 by releasing updated 4.0.11a
windows packages, which include this individual fix on top of the 4.0.11 sources). (bug
#69).
Fixed a crash when no database was selected and LOAD DATA command was issued with
full table name specified, including database prefix.
Fixed a crash when shutting down replication on some platforms (e.g. Mac OS X).
Fixed a portability bug with pthread_attr_getstacksize on HP-UX 10.20 (Patch
was also included in 4.0.11a sources).
Fixed the bigint test to not fail on some platforms (e.g. HP-UX and Tru64) due to
different return values of the atof() function.
Fixed the rpl_rotate_logs test to not fail on certain platforms (e.g. Mac OS X) due
to a too long file name (changed slave-master-info.opt to .slave-mi).
D.3.4 Changes in release 4.0.11 (20 Feb 2003)
Functionality added or changed:
NULL is now sorted LAST if you use ORDER BY ... DESC (as it was before before MySQL
4.0.2). This change was required to comply with the SQL-99 standard. (The original
change was made because we thought that SQL-99 required NULL to be always sorted
at the same position, but this was wrong).
Added START TRANSACTION (SQL-99 syntax) as alias for BEGIN. This is recommended
to use instead of BEGIN to start a transaction.
Added OLD_PASSWORD() as a synonym for PASSWORD().
Allow keyword ALL in group functions.
Added support for some new INNER JOIN and JOIN syntaxes. For example, SELECT *
FROM t1 INNER JOIN t2 didn’t work before.
Novell NetWare 6.0 porting effort completed, Novell patches merged into the main
source tree.
Bugs fixed:
Fixed problem with multi-table-delete and InnoDB tables.
Fixed a problem with BLOB NOT NULL columns used with IS NULL.
Re-added missing pre- and post(un)install scripts to the Linux RPM packages (they
were missing after the renaming of the server subpackage).
Fixed that table locks are not released with multi-table updates and deletes with Inn-
oDB storage engine.
Fixed bug in updating BLOB columns with long strings.
742 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed integer-wraparound when giving big integer (>= 10 digits) to function that re-
quires an unsigned argument, like CREATE TABLE (...) AUTO_INCREMENT=#.
MIN(key_column) could in some cases return NULL on a column with NULL and other
values.
MIN(key_column) and MAX(key_column) could in some cases return wrong values when
used in OUTER JOIN.
MIN(key_column) and MAX(key_column) could return wrong values if one of the tables
was empty.
Fixed rare crash in compressed MyISAM tables with blobs.
Fixed bug in using aggregate functions as argument for INTERVAL,CASE,FIELD,
CONCAT_WS,ELT and MAKE_SET functions.
When running with --lower-case-table-names (default on windows) and you had ta-
bles or databases with mixed case on disk, then executing SHOW TABLE STATUS followed
with DROP DATABASE or DROP TABLE could fail with Errcode 13.
D.3.5 Changes in release 4.0.10 (29 Jan 2003)
Functionality added or changed:
Added option --log-error[=file_name] to mysqld_safe and mysqld. This option
will force all error messages to be put in a log file if the option --console is not given.
On Windows --log-error is enabled as default, with a default name of host_name.err
if the name is not specified.
Changed some things from Warning: to Note: in the log files.
The mysqld server should now compile on Netware.
Added optimisation that if one does GROUP BY ... ORDER BY NULL then result is not
sorted.
New command-line option for ‘mysqld’ to replace/disable built-in stopword list, that
is used in fulltext search. See hundefinedi[ft_stopword_file], page hundefinedi.
Changed default stack size from 64K to 192K; This fixes a core dump problem on Red
Hat 8.0 and other systems with a glibc that requires >128K stack for gethostbyaddr()
to resolve a hostname. You can fix this for earlier MySQL versions by starting mysqld
with --thread-stack=192K.
Added mysql_waitpid to the binary distribution and the MySQL-client RPM sub-
package (required for mysql-test-run).
Renamed the main MySQL RPM package to MySQL-server. When updating from an
older version, MySQL-server.rpm will simply replace MySQL.rpm.
If a slave is configured with replicate_wild_do_table=db.% or replicate_wild_
ignore_table=db.%, these rules will be applied to CREATE/DROP DATABASE too.
Added timeout value for MASTER_POS_WAIT().
Bugs fixed:
Fixed initialization of the random seed for newly created threads to give a better rand()
distribution from the first call.
Appendix D: MySQL Change History 743
Fixed a bug that caused mysqld to hang when a table was opened with the HANDLER
command and then dropped without being closed.
Fixed bug in logging to binary log (which affects replication) a query that inserts a
NULL in an auto_increment field and also uses LAST_INSERT_ID().
Fixed an unlikely bug that could cause a memory overrun when using ORDER BY
constant_expression.
Fixed a table corruption in ‘myisamchk’’s parallel repair mode.
Fixed bug in query cache invalidation on simple table renaming.
Fixed bug in mysqladmin --relative.
On some 64 bit systems, show status reported a strange number for Open_files and
Open_streams.
Fixed wrong number of columns in EXPLAIN on empty table.
Fixed bug in LEFT JOIN that caused zero rows to be returned in the case the WHERE
condition was evaluated as FALSE after reading const tables. (Unlikely condition).
FLUSH PRIVILEGES didn’t correctly flush table/column privileges when mysql.tables_
priv is empty.
Fixed bug in replication when using LOAD DATA INFILE one a file that updated and
auto increment field with NULL or 0. This bug only affected MySQL 4.0 masters (not
slaves or MySQL 3.23 masters). NOTE: If you have a slave that has replicated a file
with generated auto increment fields then the slave data is corrupted and you should
reinitialise the affected tables from the master.
Fixed possible memory overrun when sending a blob >16M to the client.
Fixed wrong error message when setting a NOT NULL field to an expression that returned
NULL.
Fixed core dump bug in str LIKE "%other_str%" where str or other_str contained
characters >= 128.
Fixed bug: When executing on master LOAD DATA and InnoDB failed with table full
error the binary log was corrupted.
D.3.6 Changes in release 4.0.9 (09 Jan 2003)
Functionality added or changed:
OPTIMIZE TABLE will for MyISAM tables treat all NULL values as different when calcu-
lating cardinality. This helps in optimising joins between tables where one of the tables
has a lot of NULL values in a indexed column:
SELECT * from t1,t2 where t1.a=t2.key_with_a_lot_of_null;
Added join operator FORCE INDEX (key_list). This acts likes USE INDEX (key_list)
but with the addition that a table scan is assumed to be VERY expensive. One bad
thing with this is that it makes FORCE a reserved word.
Reset internal row buffer in MyISAM after each query. This will reduce memory in the
case you have a lot of big blobs in a table.
Bugs fixed:
744 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
A security patch in 4.0.8 causes the mysqld server to die if the remote hostname can’t
be resolved. This is now fixed.
Fixed crash when replication big LOAD DATA INFILE statement that caused log rotation.
D.3.7 Changes in release 4.0.8 (07 Jan 2003)
Functionality added or changed:
Default max_packet_length for libmysqld.c is now 1024*1024*1024.
One can now specify max_allowed_packet in a file ready by mysql_options(MYSQL_
READ_DEFAULT_FILE). for clients.
When sending a too big packet to the server with the not compressed protocol, the
client now gets an error message instead of a lost connection.
We now send big queries/result rows in bigger hunks, which should give a small speed
improvement.
Fixed some bugs with the compressed protocol for rows >16M.
InnoDB tables now also supports ON UPDATE CASCADE in FOREIGN KEY constraints. See
the InnoDB section in the manual for the InnoDB changelog.
Bugs fixed:
Fixed bug in ALTER TABLE with BDB tables.
Fixed core dump bug in QUOTE() function.
Fixed a bug in handling communication packets bigger than 16M. Unfortunately this
required a protocol change; If you upgrade the server to 4.0.8 and above and have
clients that uses packets >= 255*255*255 bytes (=16581375) you must also upgrade
your clients to at least 4.0.8. If you don’t upgrade, the clients will hang when sending
a big packet.
Fixed bug when sending blobs longer than 16M to client.
Fixed bug in GROUP BY when used on BLOB column with NULL values.
Fixed a bug in handling NULLs in CASE ... WHEN ...
D.3.8 Changes in release 4.0.7 (20 Dec 2002)
Functionality added or changed:
mysqlbug now also reports the compiler version used for building the binaries (if the
compiler supports the option --version).
Bugs fixed:
Fixed compilation problems on OpenUnix and HPUX 10.20.
Fixed some optimisation problems when compiling MySQL with -DBIG_TABLES on a
32 bit system.
mysql_drop_db() didn’t check permissions properly so anyone could drop another users
database. DROP DATABASE is checked properly.
Appendix D: MySQL Change History 745
D.3.9 Changes in release 4.0.6 (14 Dec 2002: Gamma)
Functionality added or changed:
Added syntax support for CHARACTER SET xxx and CHARSET=xxx table options (to be
able to read table dumps from 4.1).
Fixed replication bug that caused the slave to loose its position in some cases when the
replication log was rotated.
Fixed that a slave will restart from the start of a transaction if it’s killed in the middle
of one.
Moved the manual pages from ‘man’ to ‘man/man1’ in the binary distributions.
The default type returned by IFNULL(A,B) is now set to be the more ’general’ of the
types of Aand B. (The order is STRING,REAL or INTEGER).
Moved the ‘mysql.server’ startup script in the RPM packages from
/etc/rc.d/init.d/mysql’ to ‘/etc/init.d/mysql’ (which almost all cur-
rent Linux distributions support for LSB compliance).
Added Qcache_lowmem_prunes status variable (number of queries that were deleted
from cache because of low memory).
Fixed mysqlcheck so it can deal with table names containing dashes.
Bulk insert optimisation (see hundefinedi[bulk_insert_buffer_size], page hunde-
finedi) is no longer used when inserting small (less than 100) number of rows.
Optimisation added for queries like SELECT ... FROM merge_table WHERE indexed_
column=constant_expr.
Added functions LOCALTIME and LOCALTIMESTAMP as synonyms for NOW().
CEIL is now an alias for CEILING.
The CURRENT_USER() function can be used to get a user@host value as it was matched
in the GRANT system. See hundefinedi[CURRENT_USER()], page hundefinedi.
Fixed CHECK constraints to be compatible with SQL-99. This made CHECK a reserved
word. (Checking of CHECK constraints is still not implemented).
Added CAST(... as CHAR).
Added PostgreSQL compatible LIMIT syntax: SELECT ... LIMIT # OFFSET #
mysql_change_user() will now reset the connection to the state of a fresh connect
(Ie, ROLLBACK any active transaction, close all temporary tables, reset all user variables
etc..)
Bugs fixed:
Fixed number of found rows returned in multi table updates
Make --lower-case-table-names default on Mac OS X as the file system is case
sensitive.
Transactions in AUTOCOMMIT=0 mode didn’t rotate binary log.
A fix for the bug in a SELECT with joined tables with ORDER BY and LIMIT clause when
filesort had to be used. In that case LIMIT was applied to filesort of one of the tables,
although it could not be. This fix solved problems with LEFT JOIN too.
746 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql_server_init() now makes a copy of all arguments. This fixes a problem when
using the embedded server in C# program.
Fixed buffer overrun in libmysqlclient library that allowed a malicious MySQL server
to crash the client application.
Fixed security-related bug in mysql_change_user() handling. All users are strongly
recommended to upgrade to version 4.0.6.
Fixed bug that prevented --chroot command-line option of mysqld from working.
Fixed bug in phrase operator "..." in boolean full-text search.
Fixed bug that caused OPTIMIZE TABLE to corrupt the table under some rare circum-
stances.
Part rewrite of multi-table-update to optimise it, make it safer and more bug free.
LOCK TABLES now works together with multi-table-update and multi-table-delete.
--replicate-do=xxx didn’t work for UPDATE commands. (Bug introduced in 4.0.0)
Fixed shutdown problem on Mac OS X.
Major InnoDB bugs in REPLACE, AUTO_INCREMENT, INSERT INTO ... SELECT ...
were fixed. See the InnoDB changelog in the InnoDB section of the manual.
D.3.10 Changes in release 4.0.5 (13 Nov 2002)
Functionality added or changed:
Port number was added to host name (if it is known) in SHOW PROCESSLIST command
Changed handling of last argument in WEEK() so that one can get week number ac-
cording to the ISO 8601 specification. (Old code should still work).
Fixed that INSERT DELAYED threads doesn’t hang on Waiting for INSERT when one
sends a SIGHUP to mysqld.
Change that AND works according to SQL-99 when it comes to NULL handling. In
practice, this only affects queries where you do something like WHERE ... NOT (NULL
AND 0).
mysqld will now resolve basedir to its full path (with realpath()). This enables one
to use relative symlinks to the MySQL installation directory. This will however cause
show variables to report different directories on systems where there is a symbolic
link in the path.
Fixed that MySQL will not use index scan on index disabled with IGNORE INDEX or
USE INDEX. to be ignored.
Added --use-frm option to mysqlcheck. When used with REPAIR, it gets the table
structure from the .frm file, so the table can be repaired even if the .MYI header is
corrupted.
Fixed bug in MAX() optimisation when used with JOIN and ON expressions.
Added support for reading of MySQL 4.1 table definition files.
BETWEEN behaviour changed (see hundefinedi[Comparison Operators], page hunde-
finedi). Now datetime_col BETWEEN timestamp AND timestamp should work as ex-
pected.
One can create TEMPORARY MERGE tables now.
Appendix D: MySQL Change History 747
DELETE FROM myisam_table now shrinks not only the ‘.MYD’ file but also the ‘.MYI
file.
When one uses the --open-files-limit=# option to mysqld_safe it’s now passed on
to mysqld.
Changed output from EXPLAIN from ’where used’ to ’Using where’ to make it more
in line with other output.
Removed variable safe_show_database as it was no longer used.
Updated source tree to be built using automake 1.5 and libtool 1.4.
Fixed an inadvertently changed option (--ignore-space) back to the original --
ignore-spaces in mysqlclient. (Both syntaxes will work).
Don’t require UPDATE privilege when using REPLACE.
Added support for DROP TEMPORARY TABLE ..., to be used to make replication safer.
When transactions are enabled, all commands that update temporary tables inside a
BEGIN/COMMIT are now stored in the binary log on COMMIT and not stored if one does
ROLLBACK. This fixes some problems with non-transactional temporary tables used
inside transactions.
Allow braces in joins in all positions. Formerly, things like SELECT * FROM (t2 LEFT
JOIN t3 USING (a)), t1 worked, but not SELECT * FROM t1, (t2 LEFT JOIN t3 USING
(a)). Note that braces are simply removed, they do not change the way the join is
executed.
InnoDB now supports also isolation levels READ UNCOMMITTED and READ COMMITTED.
For a detailed InnoDB changelog, see hundefinedi[InnoDB change history], page hun-
definediin this manual.
Bugs fixed:
Fixed bug in MAX() optimisation when used with JOIN and ON expressions.
Fixed that INSERT DELAY threads don’t hang on Waiting for INSERT when one sends
aSIGHUP to mysqld.
Fixed that MySQL will not use an index scan on an index that has been disabled with
IGNORE INDEX or USE INDEX.
Corrected test for root user in mysqld_safe.
Fixed error message issued when storage engine cannot do CHECK or REPAIR.
Fixed rare core dump problem in complicated GROUP BY queries that didn’t return any
result.
Fixed mysqlshow to work properly with wildcarded database names and with database
names that contain underscores.
Portability fixes to get MySQL to compile cleanly with Sun Forte 5.0.
Fixed MyISAM crash when using dynamic-row tables with huge numbers of packed fields.
Fixed query cache behaviour with BDB transactions.
Fixed possible floating point exception in MATCH relevance calculations.
Fixed bug in full-text search IN BOOLEAN MODE that made MATCH to return incorrect
relevance value in some complex joins.
748 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed a bug that limited MyISAM key length to a value slightly less that 500. It is
exactly 500 now.
Fixed that GROUP BY on columns that may have a NULL value doesn’t always use disk
based temporary tables.
The filename argument for the --des-key-file argument to mysqld is interpreted
relative to the data directory if given as a relative pathname.
Removed a condition that temp table with index on column that can be NULL has to
be MyISAM. This was okay for 3.23, but not needed in 4.*. This resulted in slowdown
in many queries since 4.0.2.
Small code improvement in multi-table updates.
Fixed a newly introduced bug that caused ORDER BY ... LIMIT # to not return all rows.
Fixed a bug in multi-table deletes when outer join is used on an empty table, which
gets first to be deleted.
Fixed a bug in multi-table updates when a single table is updated.
Fixed bug that caused REPAIR TABLE and myisamchk to corrupt FULLTEXT indexes.
Fixed bug with caching the mysql grant table database. Now queries in this database
are not cached in the query cache.
Small fix in mysqld_safe for some shells.
Give error if a MyISAM MERGE table has more than 2 ^32 rows and MySQL was not
compiled with -DBIG_TABLES.
Fixed some ORDER BY ... DESC problems with InnoDB tables.
D.3.11 Changes in release 4.0.4 (29 Sep 2002)
Fixed bug where GRANT/REVOKE failed if hostname was given in non-matching case.
Don’t give warning in LOAD DATA INFILE when setting a timestamp to a string value
of ’0’.
Fixed bug in myisamchk -R mode.
Fixed bug that caused mysqld to crash on REVOKE.
Fixed bug in ORDER BY when there is a constant in the SELECT statement.
One didn’t get an error message if mysqld couldn’t open the privilege tables.
SET PASSWORD FOR ... closed the connection in case of errors (bug from 4.0.3).
Increased max possible max_allowed_packet in mysqld to 1 GB.
Fixed bug when doing a multi-line INSERT on a table with an AUTO_INCREMENT key
which was not in the first part of the key.
Changed LOAD DATA INFILE to not recreate index if the table had rows from before.
Fixed overrun bug when calling AES_DECRYPT() with incorrect arguments.
--skip-ssl can now be used to disable SSL in the MySQL clients, even if one is using
other SSL options in an option file or previously on the command line.
Fixed bug in MATCH ... AGAINST( ... IN BOOLEAN MODE) used with ORDER BY.
Added LOCK TABLES and CREATE TEMPORARY TABLES privilege on the database level.
One must run the mysql_fix_privilege_tables script on old installations to activate
these.
Appendix D: MySQL Change History 749
In SHOW TABLE ... STATUS, compressed tables sometimes showed up as dynamic.
SELECT @@[global|session].var_name didn’t report global | session in the result
column name.
Fixed problem in replication that FLUSH LOGS in a circular replication setup created an
infinite number of binary log files. Now a rotate-binary-log command in the binary
log will not cause slaves to rotate logs.
Removed STOP EVENT from binary log when doing FLUSH LOGS.
Disable the use of SHOW NEW MASTER FOR SLAVE as this needs to be completely changed
in 4.1.
Fixed a bug with constant expression (e.g. field of a one-row table, or field from a
table, referenced by a UNIQUE key) appeared in ORDER BY part of SELECT DISTINCT.
--log-binary=a.b.c now properly strips off .b.c.
FLUSH LOGS removed numerical extension for all future update logs.
GRANT ... REQUIRE didn’t store the SSL information in the mysql.user table if SSL
was not enabled in the server.
GRANT ... REQUIRE NONE can now be used to remove SSL information.
AND is now optional between REQUIRE options.
REQUIRE option was not properly saved, which could cause strange output in SHOW
GRANTS.
Fixed that mysqld --help reports correct values for --datadir and --bind-address.
Fixed that one can drop UDFs that didn’t exist when mysqld was started.
Fixed core dump problem with SHOW VARIABLES on some 64 bit systems (like Solaris
sparc).
Fixed a bug in my getopt; --set-variable syntax didn’t work for those options that
didn’t have a valid variable in my option struct. This affected at least default-table-
type option.
Fixed a bug from 4.0.2 that caused REPAIR TABLE and myisamchk --recover to fail on
tables with duplicates in a unique key.
Fixed a bug from 4.0.3 in calculating the default data type for some functions. This
affected queries of type CREATE TABLE table_name SELECT expression(),...
Fixed bug in queries of type SELECT * FROM table-list GROUP BY ... and SELECT
DISTINCT * FROM ....
Fixed bug with the --slow-log when logging an administrator command (like FLUSH
TABLES).
Fixed a bug that OPTIMIZE of locked and modified table, reported table corruption.
Fixed a bug in my getopt in handling of special prefixes (--skip-,--enable-). -
-skip-external-locking didn’t work and the bug may have affected other similar
options.
Fixed bug in checking for output file name of the tee option.
Added some more optimisation to use index for SELECT ... FROM many_tables ..
ORDER BY key limit #
Fixed problem in SHOW OPEN TABLES when a user didn’t have access permissions to one
of the opened tables.
750 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.3.12 Changes in release 4.0.3 (26 Aug 2002: Beta)
Fixed problem with configure ... --localstatedir=....
Cleaned up mysql.server script.
Fixed a bug in mysqladmin shutdown when pid file was modified while mysqladmin
was still waiting for the previous one to disappear. This could happen during a very
quick restart and caused mysqladmin to hang until shutdown_timeout seconds had
passed.
Don’t increment warnings when setting AUTO_INCREMENT columns to NULL in LOAD DATA
INFILE.
Fixed all boolean type variables/options to work with the old syntax, e.g. all of
these work: --lower-case-table-names, --lower-case-table-names=1, -O lower-case-table-
names=1, --set-variable=lower-case-table-names=1
Fixed shutdown problem (SIGTERM signal handling) on Solaris. (Bug from 4.0.2).
SHOW MASTER STATUS now returns an empty set if binary log is not enabled.
SHOW SLAVE STATUS now returns an empty set if slave is not initialised.
Don’t update MyISAM index file on update if not strictly necessary.
Fixed bug in SELECT DISTINCT ... FROM many_tables ORDER BY not-used-column.
Fixed a bug with BIGINTs and quoted strings.
Added QUOTE() function that performs SQL quoting to produce values that can be
used as data values in queries.
Changed variable DELAY_KEY_WRITE to an enum to allow one set DELAY_KEY_WRITE for
all tables without taking down the server.
Changed behaviour of IF(condition,column,NULL) so that it returns the value of the
column type.
Made safe_mysqld a symlink to mysqld_safe in binary distribution.
Fixed security bug when having an empty database name in the user.db table.
Fixed some problems with CREATE TABLE ... SELECT function().
mysqld now has the option --temp-pool enabled by default as this gives better per-
formance with some operating systems.
Fixed problem with too many allocated alarms on slave when connecting to master
many times (normally not a very critical error).
Fixed hang in CHANGE MASTER TO if the slave thread died very quickly.
Big cleanup in replication code (less logging, better error messages, etc..)
If the --code-file option is specified, the server calls setrlimit() to set the maxi-
mum allowed core file size to unlimited, so core files can be generated.
Fixed bug in query cache after temporary table creation.
Added --count=N (-c) option to mysqladmin, to make the program do only Niterations.
To be used with --sleep (-i). Useful in scripts.
Fixed bug in multi-table UPDATE: when updating a table, do_select() became con-
fused about reading records from a cache.
Fixed bug in multi-table UPDATE when several fields were referenced from a single table
Appendix D: MySQL Change History 751
Fixed bug in truncating nonexisting table.
Fixed bug in REVOKE that caused user resources to be randomly set.
Fixed bug in GRANT for the new CREATE TEMPORARY TABLE privilege.
Fixed bug in multi-table DELETE when tables are re-ordered in the table initialisation
method and ref lengths are of different sizes.
Fixed two bugs in SELECT DISTINCT with large tables.
Fixed bug in query cache initialisation with very small query cache size.
Allow DEFAULT with INSERT statement.
The startup parameters myisam_max_sort_file_size and myisam_max_extra_sort_
file_size are now given in bytes, not megabytes.
External system locking of MyISAM/ISAM files is now turned off by default. One can
turn this on with --external-locking. (For most users this is never needed).
Fixed core dump bug with INSERT ... SET db_name.table_name.colname=’’.
Fixed client hangup bug when using some SQL commands with wrong syntax.
Fixed a timing bug in DROP DATABASE
New SET [GLOBAL | SESSION] syntax to change thread-specific and global server vari-
ables at runtime.
Added variable slave_compressed_protocol.
Renamed variable query_cache_startup_type to query_cache_type,myisam_bulk_
insert_tree_size to bulk_insert_buffer_size,record_buffer to read_buffer_
size and record_rnd_buffer to record_rnd_buffer_size.
Renamed some SQL variables, but old names will still work until 5.0. See from-3.23-snt
[Upgrading-from-3.23], page from-3.23-pg.
Renamed --skip-locking to --skip-external-locking.
Removed unused variable query_buffer_size.
Fixed a bug that made the pager option in the mysql client non-functional.
Added full AUTO_INCREMENT support to MERGE tables.
Extended LOG() function to accept an optional arbitrary base parameter. See hunde-
finedi[Mathematical functions], page hundefinedi.
Added LOG2() function (useful for finding out how many bits a number would require
for storage).
Added LN() natural logarithm function for compatibility with other databases. It is
synonymous with LOG(X).
D.3.13 Changes in release 4.0.2 (01 Jul 2002)
Cleaned up NULL handling for default values in DESCRIBE table_name.
Fixed truncate() to round up negative values to the nearest integer.
Changed --chroot=path option to execute chroot() immediately after all options
have been parsed.
Don’t allow database names that contain ‘\’.
lower_case_table_names now also affects database names.
752 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added XOR operator (logical and bitwise XOR) with ^as a synonym for bitwise XOR.
Added function IS_FREE_LOCK("lock_name"). Based on code contributed by Hartmut
Holzgraefe hartmut@six.de.
Removed mysql_ssl_clear() from C API, as it was not needed.
DECIMAL and NUMERIC types can now read exponential numbers.
Added SHA1() function to calculate 160 bit hash value as described in RFC 3174
(Secure Hash Algorithm). This function can be considered a cryptographically more
secure equivalent of MD5(). See hundefinedi[Miscellaneous functions], page hundefinedi.
Added AES_ENCRYPT() and AES_DECRYPT() functions to perform encryption according
to AES standard (Rijndael). See hundefinedi[Miscellaneous functions], page hunde-
finedi.
Added --single-transaction option to mysqldump, allowing a consistent dump of
InnoDB tables. See hundefinedi[mysqldump], page hundefinedi.
Fixed bug in innodb_log_group_home_dir in SHOW VARIABLES.
Fixed a bug in optimiser with merge tables when non-unique values are used in summing
up (causing crashes).
Fixed a bug in optimiser when a range specified makes index grouping impossible
(causing crashes).
Fixed a rare bug when FULLTEXT index is present and no tables are used.
Added privileges CREATE TEMPORARY TABLES,EXECUTE,LOCK TABLES,REPLICATION
CLIENT,REPLICATION SLAVE,SHOW DATABASES and SUPER. To use these, you must
have run the mysql_fix_privilege_tables script after upgrading.
Fixed query cache align data bug.
Fixed mutex bug in replication when reading from master fails.
Added missing mutex in TRUNCATE TABLE; This fixes some core dump/hangup problems
when using TRUNCATE TABLE.
Fixed bug in multi-table DELETE when optimiser uses only indices.
Fixed that ALTER TABLE table_name RENAME new_table_name is as fast as RENAME
TABLE.
Fixed bug in GROUP BY with two or more fields, where at least one field can contain
NULL values.
Use Turbo Boyer-Moore algorithm to speed up LIKE "%keyword%" searches.
Fixed bug in DROP DATABASE with symlink.
Fixed crash in REPAIR ... USE_FRM.
Fixed bug in EXPLAIN with LIMIT offset != 0.
Fixed bug in phrase operator "..." in boolean full-text search.
Fixed bug that caused duplicated rows when using truncation operator *in boolean
full-text search.
Fixed bug in truncation operator of boolean full-text search (wrong results when there
are only +word*s in the query).
Fixed bug in boolean full-text search that caused a crash when an identical MATCH
expression that did not use an index appeared twice.
Appendix D: MySQL Change History 753
Query cache is now automatically disabled in mysqldump.
Fixed problem on Windows 98 that made sending of results very slow.
Boolean full-text search weighting scheme changed to something more reasonable.
Fixed bug in boolean full-text search that caused MySQL to ignore queries of ft_min_
word_len characters.
Boolean full-text search now supports “phrase searches”.
New configure option --without-query-cache.
Memory allocation strategy for “root memory” changed. Block size now grows with
number of allocated blocks.
INET_NTOA() now returns NULL if you give it an argument that is too large (greater
than the value corresponding to 255.255.255.255).
Fix SQL_CALC_FOUND_ROWS to work with UNIONs. It will work only if the first SELECT
has this option and if there is global LIMIT for the entire statement. For the moment,
this requires using parentheses for individual SELECT queries within the statement.
Fixed bug in SQL_CALC_FOUND_ROWS and LIMIT.
Don’t give an error for CREATE TABLE ...(... VARCHAR(0)).
Fixed SIGINT and SIGQUIT problems in ‘mysql.cc’ on Linux with some glibc versions.
Fixed bug in ‘convert.cc’, which is caused by having an incorrect net_store_
length() linked in the CONVERT::store() method.
DOUBLE and FLOAT columns now honor the UNSIGNED flag on storage.
InnoDB now retains foreign key constraints through ALTER TABLE and CREATE/DROP
INDEX.
InnoDB now allows foreign key constraints to be added through the ALTER TABLE syntax.
InnoDB tables can now be set to automatically grow in size (autoextend).
Added --ignore-lines=n option to mysqlimport. This has the same effect as the
IGNORE n LINES clause for LOAD DATA.
Fixed bug in UNION with last offset being transposed to total result set.
REPAIR ... USE_FRM added.
Fixed that DEFAULT_SELECT_LIMIT is always imposed on UNION result set.
Fixed that some SELECT options can appear only in the first SELECT.
Fixed bug with LIMIT with UNION, where last select is in the braces.
Fixed that full-text works fine with UNION operations.
Fixed bug with indexless boolean full-text search.
Fixed bug that sometimes appeared when full-text search was used with “const” tables.
Fixed incorrect error value when doing a SELECT with an empty HEAP table.
Use ORDER BY column DESC now sorts NULL values first. (In other words, NULL values
sort first in all cases, whether or not DESC is specified.). This is changed back in 4.0.10.
Fixed bug in WHERE key_name=’constant’ ORDER BY key_name DESC.
Fixed bug in SELECT DISTINCT ... ORDER BY DESC optimisation.
Fixed bug in ... HAVING ’GROUP_FUNCTION’(xxx) IS [NOT] NULL.
754 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed bug in truncation operator for boolean full-text search.
Allow value of --user=# option for mysqld to be specified as a numeric user ID.
Fixed a bug where SQL_CALC_ROWS returned an incorrect value when used with one
table and ORDER BY and with InnoDB tables.
Fixed that SELECT 0 LIMIT 0 doesn’t hang thread.
Fixed some problems with USE/IGNORE INDEX when using many keys with the same
start column.
Don’t use table scan with BerkeleyDB and InnoDB tables when we can use an index
that covers the whole row.
Optimised InnoDB sort-buffer handling to take less memory.
Fixed bug in multi-table DELETE and InnoDB tables.
Fixed problem with TRUNCATE and InnoDB tables that produced the error Can’t
execute the given command because you have active locked tables or an active
transaction.
Added NO_UNSIGNED_SUBTRACTION to the set of flags that may be specified with the
--sql-mode option for mysqld. It disables unsigned arithmetic rules when it comes to
subtraction. (This will make MySQL 4.0 behave more closely to 3.23 with UNSIGNED
columns).
The result returned for all bit functions (|,<<, ...) is now of type unsigned integer.
Added detection of nan values in MyISAM to make it possible to repair tables with nan
in float or double columns.
Fixed new bug in myisamchk where it didn’t correctly update number of “parts” in the
MyISAM index file.
Changed to use autoconf 2.52 (from autoconf 2.13).
Fixed optimisation problem where the MySQL Server was in “preparing” state for a
long time when selecting from an empty table which had contained a lot of rows.
Fixed bug in complicated join with const tables. This fix also improves performance
a bit when referring to another table from a const table.
First pre-version of multi-table UPDATE statement.
Fixed bug in multi-table DELETE.
Fixed bug in SELECT CONCAT(argument_list) ... GROUP BY 1.
INSERT ... SELECT did a full rollback in case of an error. Fixed so that we only roll
back the last statement in the current transaction.
Fixed bug with empty expression for boolean full-text search.
Fixed core dump bug in updating full-text key from/to NULL.
ODBC compatibility: Added BIT_LENGTH() function.
Fixed core dump bug in GROUP BY BINARY column.
Added support for NULL keys in HEAP tables.
Use index for ORDER BY in queries of type: SELECT * FROM t WHERE key_part1=1 ORDER
BY key_part1 DESC,key_part2 DESC
Fixed bug in FLUSH QUERY CACHE.
Appendix D: MySQL Change History 755
Added CAST() and CONVERT() functions. The CAST and CONVERT functions are nearly
identical and mainly useful when you want to create a column with a specific type
in a CREATE ... SELECT statement. For more information, read hundefinedi[Cast
Functions], page hundefinedi.
CREATE ... SELECT on DATE and TIME functions now create columns of the expected
type.
Changed order in which keys are created in tables.
Added new columns Null and Index_type to SHOW INDEX output.
Added --no-beep and --prompt options to mysql command-line client.
New feature: management of user resources.
GRANT ... WITH MAX_QUERIES_PER_HOUR N1
MAX_UPDATES_PER_HOUR N2
MAX_CONNECTIONS_PER_HOUR N3;
See hundefinedi[User resources], page hundefinedi.
Added mysql_secure_installation to the ‘scripts/’ directory.
D.3.14 Changes in release 4.0.1 (23 Dec 2001)
Added system command to mysql.
Fixed bug when HANDLER was used with some unsupported table type.
mysqldump now puts ALTER TABLE nome_tabela DISABLE KEYS and ALTER TABLE
nome_tabela ENABLE KEYS in the sql dump.
Added mysql_fix_extensions script.
Fixed stack overrun problem with LOAD DATA FROM MASTER on OSF/1.
Fixed shutdown problem on HP-UX.
Added DES_ENCRYPT() and DES_DECRYPT() functions.
Added FLUSH DES_KEY_FILE statement.
Added --des-key-file option to mysqld.
HEX(string) now returns the characters in string converted to hexadecimal.
Fixed problem with GRANT when using lower_case_table_names=1.
Changed SELECT ... IN SHARE MODE to SELECT ... LOCK IN SHARE MODE (as in
MySQL 3.23).
A new query cache to cache results from identical SELECT queries.
Fixed core dump bug on 64-bit machines when it got an incorrect communication
packet.
MATCH ... AGAINST(... IN BOOLEAN MODE) can now work without FULLTEXT index.
Fixed slave to replicate from 3.23 master.
Miscellaneous replication fixes/cleanup.
Got shutdown to work on Mac OS X.
Added ‘myisam/ft_dump’ utility for low-level inspection of FULLTEXT indexes.
Fixed bug in DELETE ... WHERE ... MATCH ....
756 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added support for MATCH ... AGAINST(... IN BOOLEAN MODE).Note: you must re-
build your tables with ALTER TABLE tablename TYPE=MyISAM to be able to use boolean
full-text search.
LOCATE() and INSTR() are now case-sensitive if either argument is a binary string.
Changed RAND() initialisation so that RAND(N) and RAND(N+1) are more distinct.
Fixed core dump bug in UPDATE ... ORDER BY.
Changed INSERT INTO ... SELECT to stop on errors by default.
Ignore DATA DIRECTORY and INDEX DIRECTORY directives on Windows.
Added boolean full-text search code. It should be considered early alpha.
Extended MODIFY and CHANGE in ALTER TABLE to accept the FIRST and AFTER keywords.
Indexes are now used with ORDER BY on a whole InnoDB table.
D.3.15 Changes in release 4.0.0 (Oct 2001: Alpha)
Added --xml option to mysql for producing XML output.
Added full-text variables ft_min_word_len,ft_max_word_len, and ft_max_word_
len_for_sort.
Added documentation for libmysqld, the embedded MySQL server library. Also added
example programs (a mysql client and mysqltest test program) which use libmysqld.
Removed all Gemini hooks from MySQL server.
Removed my_thread_init() and my_thread_end() from ‘mysql_com.h’, and added
mysql_thread_init() and mysql_thread_end() to ‘mysql.h’.
Support for communication packets >16M. In 4.0.1 we will extend MyISAM to be able
to handle these.
Secure connections (with SSL).
Unsigned BIGINT constants now work. MIN() and MAX() now handle signed and un-
signed BIGINT numbers correctly.
New character set latin1_de which provides correct German sorting.
STRCMP() now uses the current character set when doing comparisons, which means
that the default comparison behaviour now is case-insensitive.
TRUNCATE TABLE and DELETE FROM nome_tabela are now separate functions. One
bonus is that DELETE FROM nome_tabela now returns the number of deleted rows,
rather than zero.
DROP DATABASE now executes a DROP TABLE on all tables in the database, which fixes a
problem with InnoDB tables.
Added support for UNION.
Added support for multi-table DELETE operations.
A new HANDLER interface to MyISAM tables.
Added support for INSERT on MERGE tables. Patch from Benjamin Pflugmann.
Changed WEEK(#,0) to match the calendar in the USA.
COUNT(DISTINCT) is about 30% faster.
Speed up all internal list handling.
Appendix D: MySQL Change History 757
Speed up IS NULL,ISNULL() and some other internal primitives.
Full-text index creation now is much faster.
Tree-like cache to speed up bulk inserts and myisam_bulk_insert_tree_size variable.
Searching on packed (CHAR/VARCHAR) keys is now much faster.
Optimised queries of type: SELECT DISTINCT * from nome_tabela ORDER by
key_part1 LIMIT #.
SHOW CREATE TABLE now shows all table attributes.
ORDER BY ... DESC can now use keys.
LOAD DATA FROM MASTER “automatically” sets up a slave.
Renamed safe_mysqld to mysqld_safe to make this name more in line with other
MySQL scripts/commands.
Added support for symbolic links to MyISAM tables. Symlink handling is now enabled
by default for Windows.
Added SQL_CALC_FOUND_ROWS and FOUND_ROWS(). This makes it possible to know how
many rows a query would have returned without a LIMIT clause.
Changed output format of SHOW OPEN TABLES.
Allow SELECT expression LIMIT ....
Added IDENTITY as a synonym for AUTO_INCREMENT (like Sybase).
Added ORDER BY syntax to UPDATE and DELETE.
SHOW INDEXES is now a synonym for SHOW INDEX.
Added ALTER TABLE nome_tabela DISABLE KEYS and ALTER TABLE nome_tabela
ENABLE KEYS commands.
Allow use of IN as a synonym for FROM in SHOW commands.
Implemented “repair by sort” for FULLTEXT indexes. REPAIR TABLE,ALTER TABLE, and
OPTIMIZE TABLE for tables with FULLTEXT indexes are now up to 100 times faster.
Allow SQL-99 syntax X’hexadecimal-number’.
Cleaned up global lock handling for FLUSH TABLES WITH READ LOCK.
Fixed problem with DATETIME = constant in WHERE optimisation.
Added --master-data and --no-autocommit options to mysqldump. (Thanks to Brian
Aker for this.)
Added script mysql_explain_log.sh to distribution. (Thanks to mobile.de).
D.4 Changes in release 3.23.x (Recent; still supported)
Please note that since release 4.0 is now production level, only critical fixes are done in
the 3.23 release series. You are recommended to upgrade when possible, to take advantage
of all speed and feature improvements in 4.0. See from-3.23-snt [Upgrading-from-3.23],
page from-3.23-pg.
The 3.23 release has several major features that are not present in previous versions. We
have added three new table types:
MyISAM A new ISAM library which is tuned for SQL and supports large files.
758 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
InnoDB A transaction-safe storage engine that supports row level locking, and many
Oracle-like features.
BerkeleyDB or BDB
Uses the Berkeley DB library from Sleepycat Software to implement
transaction-safe tables.
Note that only MyISAM is available in the standard binary distribution.
The 3.23 release also includes support for database replication between a master and many
slaves, full-text indexing, and much more.
All new features are being developed in the 4.x version. Only bug fixes and minor enhance-
ments to existing features will be added to 3.23.
The replication code and BerkeleyDB code is still not as tested and as the rest of the code,
so we will probably need to do a couple of future releases of 3.23 with small fixes for this
part of the code. As long as you don’t use these features, you should be quite safe with
MySQL 3.23!
Note that the above doesn’t mean that replication or Berkeley DB don’t work. We have
done a lot of testing of all code, including replication and BDB without finding any problems.
It only means that not as many users use this code as the rest of the code and because of
this we are not yet 100% confident in this code.
D.4.1 Changes in release 3.23.57 (not released yet)
Fixed a security problem with SELECT and wildcarded select list, when user only had
partial column SELECT privileges on the table.
Fixed unlikely problem in optimising WHERE clause with constant expression like in
WHERE 1 AND (a=1 AND b=1).
Fixed problem on IA64 with timestamps which caused mysqlbinlog to fail.
The default option for innodb_flush_log_at_trx_commit was changed from 0 to 1
to make InnoDB tables ACID by default. See hundefinedi[InnoDB start], page hunde-
finedi.
Fixed problem with too many allocated alarms on slave when connecting to master
many times (normally not a very critical error).
Fixed a bug in replication of temporary tables (bug #183).
Fixed 64 bit bug that affected at least AMD hammer systems.
Fixed a bug when doing LOAD DATA INFILE IGNORE : when reading the binary log,
mysqlbinlog and the replication code read REPLACE instead of IGNORE. This could
make the slave’s table become different from the master’s table (bug #218).
Fixed a bug in MyISAM when a row is inserted into a table with a large number of
NULL columns. Bug was caused by wrong calculation of the record length, as the space
required for storage of NULL bits was not added to the total record length.
Binary log was not locked during a TRUNCATE table_name or DELETE FROM table_name
which could cause an INSERT to table_name to be written to the binary log before the
TRUNCATE/DELETE command.
Fixed rare bug in UPDATE of InnoDB tables where one row could be updated multiple
times.
Appendix D: MySQL Change History 759
Give an error for empty table and column names.
Changed PROCEDURE ANALYSE() to report DATE instead of NEWDATE.
Changed PROCEDURE ANALYSE(#) to restrict number of values in enum to #also for
string values.
mysqldump no longer silently deletes the binlogs when called with --master-data or
--first-slave; while this behaviour was convenient for some users, others may suffer
from it. Now one has to explicitely ask for this deletion with the new --delete-
master-logs option.
Fixed a bug in mysqldump when it was called with --master-data: the CHANGE MASTER
TO commands appended to the SQL dump had wrong coordinates (bug #159).
D.4.2 Changes in release 3.23.56 (13 Mar 2003)
Fixed ‘mysqld’ crash on extremely small values of sort_buffer variable.
Fixed a bug in privilege system for GRANT UPDATE on column level.
Fixed a rare bug when using a date in HAVING with GROUP BY.
Fixed checking of random part of WHERE clause (Bug #142).
Fixed MySQL (and ‘myisamchk’) crash on artificially corrupted .MYI files.
Security enhancement: mysqld’ no longer reads options from world-writeable config
files.
Security enhancement: mysqld’ and ‘safe_mysqld’ now only use the first --user
option specified on the command line. (Normally this comes from ‘/etc/my.cnf’)
Security enhancement: Don’t allow BACKUP TABLE to overwrite existing files.
Fixed unlikely deadlock bug when one thread did a LOCK TABLE and another thread
did a DROP TABLE. In this case one could do a KILL on one of the threads to resolve
the deadlock.
LOAD DATA INFILE was not replicated by slave if replicate_*_table was set on the
slave.
Fixed a bug in handling CHAR(0) columns that could cause wrong results from the
query.
Fixed a bug in SHOW VARIABLES on 64-bit platforms. The bug was caused by wrong
declaration of variable server_id.
The Comment column in SHOW TABLE STATUS now reports that it can contain NULL
values (which is the case for a crashed ‘.frm’ file).
Fixed the rpl_rotate_logs test to not fail on certain platforms (e.g. Mac OS X) due
to a too long file name (changed slave-master-info.opt to .slave-mi).
Fixed a problem with BLOB NOT NULL columns used with IS NULL.
Fixed bug in MAX() optimisation in MERGE tables.
Better RAND() initialization for new connections.
Fixed bug with connect timeout. This bug was manifested on OS’s with poll() system
call, which resulted in timeout the value specified as it was executed in both select()
and poll().
Fixed bug in SELECT * FROM table WHERE datetime1 IS NULL OR datetime2 IS NULL.
760 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed bug in using aggregate functions as argument for INTERVAL,CASE,FIELD,
CONCAT_WS,ELT and MAKE_SET functions.
When running with --lower-case-table-names (default on windows) and you had ta-
bles or databases with mixed case on disk, then executing SHOW TABLE STATUS followed
with DROP DATABASE or DROP TABLE could fail with Errcode 13.
Fixed bug in logging to binary log (which affects replication) a query that inserts a
NULL in an auto_increment field and also uses LAST_INSERT_ID().
Fixed bug in mysqladmin --relative.
On some 64 bit systems, show status reported a strange number for Open_files and
Open_streams.
D.4.3 Changes in release 3.23.55 (23 Jan 2003)
Fixed double free’d pointer bug in mysql_change_user() handling, that enabled a
specially hacked version of MySQL client to crash mysqld.Note, that one needs to
login to the server by using a valid user account to be able to exploit this bug.
Fixed bug with the --slow-log when logging an administrator command (like FLUSH
TABLES).
Fixed bug in GROUP BY when used on BLOB column with NULL values.
Fixed a bug in handling NULLs in CASE ... WHEN ....
Bugfix for --chroot (see 3.23.54-snt [News-3.23.54], page 3.23.54-pg) is reverted.
Unfortunately, there is no way to make it to work, without introducing backward-
incompatible changes in ‘my.cnf’. Those who need --chroot functionality,
should upgrade to MySQL 4.0. (The fix in the 4.0 branch did not break
backward-compatibility).
Make --lower-case-table-names default on Mac OS X as the file system is case
insensitive.
Fixed a bug in ‘scripts/mysqld_safe.sh’ in NOHUP_NICENESS testing.
Transactions in AUTOCOMMIT=0 mode didn’t rotate binary log.
Fixed a bug in scripts/make_binary_distribution that resulted in a remaining
@HOSTNAME@ variable instead of replacing it with the correct path to the hostname
binary.
Fixed a very unlikely bug that could cause SHOW PROCESSLIST to core dump in
pthread mutex unlock() if a new thread was connecting.
Forbid SLAVE STOP if the thread executing the query has locked tables. This removes
a possible deadlock situation.
D.4.4 Changes in release 3.23.54 (05 Dec 2002)
Fixed a bug, that allowed to crash mysqld with a specially crafted packet.
Fixed a rare crash (double free’d pointer) when altering a temporary table.
Fixed buffer overrun in libmysqlclient library that allowed malicious MySQL server
to crash the client application.
Fixed security-related bug in mysql_change_user() handling. All users are strongly
recommended to upgrade to the version 3.23.54.
Appendix D: MySQL Change History 761
Fixed bug that prevented --chroot command-line option of mysqld from working.
Fixed bug that made OPTIMIZE TABLE to corrupt the table under some rare circum-
stances.
Fixed mysqlcheck so it can deal with table names containing dashes.
Fixed shutdown problem on Mac OS X.
Fixed bug with comparing an indexed NULL field with <=> NULL.
Fixed bug that caused IGNORE INDEX and USE INDEX sometimes to be ignored.
Fixed rare core dump problem in complicated GROUP BY queries that didn’t return any
result.
Fixed a bug where MATCH ... AGAINST () >=0 was treated as if it was >.
Fixed core dump in SHOW PROCESSLIST when running with an active slave (unlikely
timing bug).
Allow one to start multiple MySQL servers on windows (code backported from 4.0.2).
One can create TEMPORARY MERGE tables now.
Fixed that --core-file works on Linux (at least on kernel 2.4.18).
Fixed a problem with BDB and ALTER TABLE.
Fixed reference to freed memory when doing complicated GROUP BY ... ORDER BY
queries. Symptom was that mysqld died in function send_fields.
Allocate heap rows in smaller blocks to get better memory usage.
Fixed memory allocation bug when storing BLOB values in internal temporary tables
used for some (unlikely) GROUP BY queries.
Fixed a bug in key optimising handling where the expression WHERE column_name =
key_column_name was calculated as true for NULL values.
Fixed core dump bug when doing LEFT JOIN ... WHERE key_column=NULL.
Fixed MyISAM crash when using dynamic-row tables with huge numbers of packed fields.
Updated source tree to be built using automake 1.5 and libtool 1.4.
D.4.5 Changes in release 3.23.53 (09 Oct 2002)
Fixed crash when SHOW INNODB STATUS was used and skip-innodb was defined.
Fixed possible memory corruption bug in binary log file handling when slave rotated
the logs (only affected 3.23, not 4.0).
Fixed problem in LOCK TABLES on windows when one connects to a database that
contains upper case letters.
Fixed that --skip-show-databases doesn’t reset the --port option.
Small fix in safe_mysqld for some shells.
Fixed that FLUSH STATUS doesn’t reset delayed_insert_threads.
Fixed core dump bug when using the BINARY cast on a NULL value.
Fixed race condition when someone did a GRANT at the same time a new user logged in
or did a USE DATABASE.
Fixed bug in ALTER TABLE and RENAME TABLE when running with -O lower_case_
table_names=1 (typically on windows) when giving the table name in uppercase.
762 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed that -O lower_case_table_names=1 also converts database names to lower case.
Fixed unlikely core dump with SELECT ... ORDER BY ... LIMIT.
Changed AND/OR to report that they can return NULL. This fixes a bug in GROUP BY
on AND/OR expressions that return NULL.
Fixed a bug that OPTIMIZE of locked and modified MyISAM table, reported table
corruption.
Fixed a BDB-related ALTER TABLE bug with dropping a column and shutting down im-
mediately thereafter.
Fixed problem with configure ... --localstatedir=....
Fixed problem with UNSIGNED BIGINT on AIX (again).
Fixed bug in pthread mutex trylock() on HPUX 11.0.
Multithreaded stress tests for InnoDB.
D.4.6 Changes in release 3.23.52 (14 Aug 2002)
Wrap BEGIN/COMMIT around transaction in the binary log. This makes replication
honour transactions.
Fixed security bug when having an empty database name in the user.db table.
Changed initialisation of RND() to make it less predicatable.
Fixed problem with GROUP BY on result with expression that created a BLOB field.
Fixed problem with GROUP BY on columns that have NULL values. To solve this we now
create an MyISAM temporary table when doing a GROUP BY on a possible NULL item.
From MySQL 4.0.5 we can use in memory HEAP tables for this case.
Fixed problem with privilege tables when downgrading from 4.0.2 to 3.23.
Fixed thread bug in SLAVE START,SLAVE STOP and automatic repair of MyISAM tables
that could cause table cache to be corrupted.
Fixed possible thread related key-cache-corruption problem with OPTIMIZE TABLE and
REPAIR TABLE.
Added name of ’administrator command’ logs.
Fixed bug with creating an auto-increment value on second part of a UNIQUE() key
where first part could contain NULL values.
Don’t write slave-timeout reconnects to the error log.
Fixed bug with slave net read timeouting
Fixed a core-dump bug with MERGE tables and MAX() function.
Fixed bug in ALTER TABLE with BDB tables.
Fixed bug when logging LOAD DATA INFILE to binary log with no active database.
Fixed a bug in range optimiser (causing crashes).
Fixed possible problem in replication when doing DROP DATABASE on a database with
InnoDB tables.
Fixed that mysql_info() returns 0 for ’Duplicates’ when using INSERT DELAYED
IGNORE.
Added -DHAVE_BROKEN_REALPATH to the Mac OS X (darwin) compile options in
configure.in’ to fix a failure under high load.
Appendix D: MySQL Change History 763
D.4.7 Changes in release 3.23.51 (31 May 2002)
Fix bug with closing tags missing slash for mysqldump XML output.
Remove end space from ENUM values. (This fixed a problem with SHOW CREATE TABLE.)
Fixed bug in CONCAT_WS() that cut the result.
Changed name of server variables Com_show_master_stat to Com_show_master_
status and Com_show_slave_stat to Com_show_slave_status.
Changed handling of gethostbyname() to make the client library thread-safe even if
gethostbyname_r doesn’t exist.
Fixed core-dump problem when giving a wrong password string to GRANT.
Fixed bug in DROP DATABASE with symlinked directory.
Fixed optimisation problem with DATETIME and value outside DATETIME range.
Removed Sleepycat’s BDB doc files from the source tree, as they’re not needed (MySQL
covers BDB in its own documentation).
Fixed MIT-pthreads to compile with glibc 2.2 (needed for make dist).
Fixed the FLOAT(X+1,X) is not converted to FLOAT(X+2,X). (This also affected
DECIMAL,DOUBLE and REAL types)
Fixed the result from IF() is case in-sensitive if the second and third arguments are
case sensitive.
Fixed core dump problem on OSF/1 in gethostbyname_r.
Fixed that underflowed decimal fields are not zero filled.
If we get an overflow when inserting ’+11111’ for DECIMAL(5,0) UNSIGNED columns,
we will just drop the sign.
Fixed optimisation bug with ISNULL(expression_which_cannot_be_null) and
ISNULL(constant_expression).
Fixed host lookup bug in the glibc library that we used with the 3.23.50 Linux-x86
binaries.
D.4.8 Changes in release 3.23.50 (21 Apr 2002)
Fixed buffer overflow problem if someone specified a too long datadir parameter to
mysqld
Add missing <row> tags for mysqldump XML output.
Fixed problem with crash-me and gcc 3.0.4.
Fixed that @@unknown_variable doesn’t hang server.
Added @@VERSION as a synonym for VERSION().
SHOW VARIABLES LIKE ’xxx’ is now case-insensitive.
Fixed timeout for GET_LOCK() on HP-UX with DCE threads.
Fixed memory allocation bug in the glibc library used to build Linux binaries, which
caused mysqld to die in ’free()’.
Fixed SIGINT and SIGQUIT problems in mysql.
Fixed bug in character table converts when used with big ( >64K) strings.
764 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
InnoDB now retains foreign key constraints through ALTER TABLE and CREATE/DROP
INDEX.
InnoDB now allows foreign key constraints to be added through the ALTER TABLE syntax.
InnoDB tables can now be set to automatically grow in size (autoextend).
Our Linux RPMS and binaries are now compiled with gcc 3.0.4, which should make
them a bit faster.
Fixed some buffer overflow problems when reading startup parameters.
Because of problems on shutdown we have now disabled named pipes on windows by
default. One can enable named pipes by starting mysqld with --enable-named-pipe.
Fixed bug when using WHERE key_column = ’J’ or key_column=’j’.
Fixed core-dump bug when using --log-bin with LOAD DATA INFILE without an active
database.
Fixed bug in RENAME TABLE when used with lower_case_table_names=1 (default on
Windows).
Fixed unlikely core-dump bug when using DROP TABLE on a table that was in use by a
thread that also used queries on only temporary tables.
Fixed problem with SHOW CREATE TABLE and PRIMARY KEY when using 32 indexes.
Fixed that one can use SET PASSWORD for the anonymous user.
Fixed core dump bug when reading client groups from option files using
mysql_options().
Memory leak (16 bytes per every corrupted table) closed.
Fixed binary builds to use --enable-local-infile.
Update source to work with new version of bison.
Updated shell scripts to now agree with new POSIX standard.
Fixed bug where DATE_FORMAT() returned empty string when used with GROUP BY.
D.4.9 Changes in release 3.23.49
Don’t give warning for a statement that is only a comment; this is needed for mysqldump
--disable-keys to work.
Fixed unlikely caching bug when doing a join without keys. In this case the last used
field for a table always returned NULL.
Added options to make LOAD DATA LOCAL INFILE more secure.
MySQL binary release 3.23.48 for Linux contained a new glibc library, which has
serious problems under high load and Red Hat 7.2. The 3.23.49 binary release doesn’t
have this problem.
Fixed shutdown problem on NT.
D.4.10 Changes in release 3.23.48 (07 Feb 2002)
Added --xml option to mysqldump for producing XML output.
Changed to use autoconf 2.52 (from autoconf 2.13)
Fixed bug in complicated join with const tables.
Appendix D: MySQL Change History 765
Added internal safety checks for InnoDB.
Some InnoDB variables were always shown in SHOW VARIABLES as OFF on high-byte-first
systems (like SPARC).
Fixed problem with one thread using an InnoDB table and another thread doing an
ALTER TABLE on the same table. Before that, mysqld could crash with an assertion
failure in ‘row0row.c’, line 474.
Tuned the InnoDB SQL optimiser to favor index searches more often over table scans.
Fixed a performance problem with InnoDB tables when several large SELECT queries
are run concurrently on a multiprocessor Linux computer. Large CPU-bound SELECT
queries will now also generally run faster on all platforms.
If MySQL binlogging is used, InnoDB now prints after crash recovery the latest MySQL
binlog name and the offset InnoDB was able to recover to. This is useful, for example,
when resynchronising a master and a slave database in replication.
Added better error messages to help in installation problems of InnoDB tables.
It is now possible to recover MySQL temporary tables that have become orphaned
inside the InnoDB tablespace.
InnoDB now prevents a FOREIGN KEY declaration where the signedness is not the same
in the referencing and referenced integer columns.
Calling SHOW CREATE TABLE or SHOW TABLE STATUS could cause memory corruption and
make mysqld crash. Especially at risk was mysqldump, because it frequently calls SHOW
CREATE TABLE.
If inserts to several tables containing an AUTO_INCREMENT column were wrapped inside
one LOCK TABLES,InnoDB asserted in ‘lock0lock.c’.
In 3.23.47 we allowed several NULL values in a UNIQUE secondary index for an InnoDB
table. But CHECK TABLE was not relaxed: it reports the table as corrupt. CHECK TABLE
no longer complains in this situation.
SHOW GRANTS now shows REFERENCES instead of REFERENCE.
D.4.11 Changes in release 3.23.47 (27 Dec 2001)
Fixed bug when using the following construct: SELECT ... WHERE key=@var_name OR
key=@var_name2
Restrict InnoDB keys to 500 bytes.
InnoDB now supports NULL in keys.
Fixed shutdown problem on HP-UX. (Introduced in 3.23.46)
Fixed core dump bug in replication when using SELECT RELEASE_LOCK().
Added new command: DO expression,[expression]
Added slave-skip-errors option.
Added statistics variables for all MySQL commands. (SHOW STATUS is now much
longer.)
Fixed default values for InnoDB tables.
Fixed that GROUP BY expr DESC works.
Fixed bug when using t1 LEFT JOIN t2 ON t2.key=constant.
766 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql_config now also works with binary (relocated) distributions.
D.4.12 Changes in release 3.23.46 (29 Nov 2001)
Fixed problem with aliased temporary table replication.
InnoDB and BDB tables will now use index when doing an ORDER BY on the whole table.
Fixed bug where one got an empty set instead of a DEADLOCK error when using BDB
tables.
One can now kill ANALYZE,REPAIR, and OPTIMIZE TABLE when the thread is waiting
to get a lock on the table.
Fixed race condition in ANALYZE TABLE.
Fixed bug when joining with caching (unlikely to happen).
Fixed race condition when using the binary log and INSERT DELAYED which could cause
the binary log to have rows that were not yet written to MyISAM tables.
Changed caching of binary log to make replication slightly faster.
Fixed bug in replication on Mac OS X.
D.4.13 Changes in release 3.23.45 (22 Nov 2001)
(UPDATE|DELETE) ...WHERE MATCH bugfix.
shutdown should now work on Darwin (Mac OS X).
Fixed core dump when repairing corrupted packed MyISAM files.
--core-file now works on Solaris.
Fix a bug which could cause InnoDB to complain if it cannot find free blocks from the
buffer cache during recovery.
Fixed bug in InnoDB insert buffer B-tree handling that could cause crashes.
Fixed bug in InnoDB lock timeout handling.
Fixed core dump bug in ALTER TABLE on a TEMPORARY InnoDB table.
Fixed bug in OPTIMIZE TABLE that reset index cardinality if it was up to date.
Fixed problem with t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL when
date column was declared as NOT NULL.
Fixed bug with BDB tables and keys on BLOB columns.
Fixed bug in MERGE tables on OS with 32-bit file pointers.
Fixed bug in TIME_TO_SEC() when using negative values.
D.4.14 Changes in release 3.23.44 (31 Oct 2001)
Fixed Rows_examined count in slow query log.
Fixed bug when using a reference to an AVG() column in HAVING.
Fixed that date functions that require correct dates, like DAYOFYEAR(column), will
return NULL for 0000-00-00 dates.
Fixed bug in const-propagation when comparing columns of different types. (SELECT
* FROM date_col="2001-01-01" and date_col=time_col)
Appendix D: MySQL Change History 767
Fixed bug that caused error message Can’t write, because of unique constraint
with some GROUP BY queries.
Fixed problem with sjis character strings used within quoted table names.
Fixed core dump when using CREATE ... FULLTEXT keys with other storage engines
than MyISAM.
Don’t use signal() on Windows because this appears to not be 100% reliable.
Fixed bug when doing WHERE nome_coluna=NULL on an indexed column that had NULL
values.
Fixed bug when doing LEFT JOIN ... ON (nome_coluna = constant) WHERE
nome_coluna = constant.
When using replications, aborted queries that contained %could cause a core dump.
TCP_NODELAY was not used on some systems. (Speed problem.)
Applied portability fixes for OS/2. (Patch by Yuri Dario.)
The following changes are for InnoDB tables:
Add missing InnoDB variables to SHOW VARIABLES.
Foreign keys checking is now done for InnoDB tables.
DROP DATABASE now works also for InnoDB tables.
InnoDB now supports datafiles and raw disk partitions bigger than 4 GB on those
operating systems that have big files.
InnoDB calculates better table cardinality estimates for the MySQL optimiser.
Accent characters in the default character set latin1 are ordered according to the
MySQL ordering.
Note: if you are using latin1 and have inserted characters whose code is greater than
127 into an indexed CHAR column, you should run CHECK TABLE on your table when you
upgrade to 3.23.44, and drop and reimport the table if CHECK TABLE reports an error!
A new ‘my.cnf’ parameter, innodb_thread_concurrency, helps in performance tuning
in heavily concurrent environments.
A new ‘my.cnf’ parameter, innodb_fast_shutdown, speeds up server shutdown.
A new ‘my.cnf’ parameter, innodb_force_recovery, helps to save your data in case
the disk image of the database becomes corrupt.
innodb_monitor has been improved and a new innodb_table_monitor added.
Increased maximum key length from 500 to 7000 bytes.
Fixed a bug in replication of AUTO_INCREMENT columns with multiple-line inserts.
Fixed a bug when the case of letters changes in an update of an indexed secondary
column.
Fixed a hang when there are >24 datafiles.
Fixed a crash when MAX(col) is selected from an empty table, and col is not the first
column in a multi-column index.
Fixed a bug in purge which could cause crashes.
768 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.4.15 Changes in release 3.23.43 (04 Oct 2001)
Fixed a bug in INSERT DELAYED and FLUSH TABLES introduced in 3.23.42.
Fixed unlikely bug, which returned non-matching rows, in SELECT with many tables
and multi-column indexes and ’range’ type.
Fixed an unlikely core dump bug when doing EXPLAIN SELECT when using many tables
and ORDER BY.
Fixed bug in LOAD DATA FROM MASTER when using table with CHECKSUM=1.
Added unique error message when one gets a DEADLOCK during a transaction with
BDB tables.
Fixed problem with BDB tables and UNIQUE columns defined as NULL.
Fixed problem with myisampack when using pre-space filled CHAR columns.
Applied patch from Yuri Dario for OS/2.
Fixed bug in --safe-user-create.
D.4.16 Changes in release 3.23.42 (08 Sep 2001)
Fixed problem when using LOCK TABLES and BDB tables.
Fixed problem with REPAIR TABLE on MyISAM tables with row lengths in the range from
65517 to 65520 bytes.
Fixed rare hang when doing mysqladmin shutdown when there was a lot of activity in
other threads.
Fixed problem with INSERT DELAYED where delay thread could be hanging on
upgrading locks with no apparent reason.
Fixed problem with myisampack and BLOB.
Fixed problem when one edited ‘.MRG’ tables by hand. (Patch from Benjamin Pflug-
mann).
Enforce that all tables in a MERGE table come from the same database.
Fixed bug with LOAD DATA INFILE and transactional tables.
Fix bug when using INSERT DELAYED with wrong column definition.
Fixed core dump during REPAIR of some particularly broken tables.
Fixed bug in InnoDB and AUTO_INCREMENT columns.
Fixed bug in InnoDB and RENAME TABLE columns.
Fixed critical bug in InnoDB and BLOB columns. If you have used BLOB columns larger
than 8000 bytes in an InnoDB table, it is necessary to dump the table with mysqldump,
drop it and restore it from the dump.
Applied large patch for OS/2 from Yuri Dario.
Fixed problem with InnoDB when one could get the error Can’t execute the given
command... even when no transaction was active.
Applied some minor fixes that concern Gemini.
Use real arithmetic operations even in integer context if not all arguments are integers.
(Fixes uncommon bug in some integer contexts).
Appendix D: MySQL Change History 769
Don’t force everything to lowercase on Windows. (To fix problem with Windows and
ALTER TABLE). Now --lower_case_names also works on Unix.
Fixed that automatic rollback is done when thread end doesn’t lock other threads.
D.4.17 Changes in release 3.23.41 (11 Aug 2001)
Added --sql-mode=option[,option[,option]] option to mysqld. See line options-
snt [Command-line options], page line options-pg.
Fixed possible problem with shutdown on Solaris where the ‘.pid’ file wasn’t deleted.
InnoDB now supports <4 GB rows. The former limit was 8000 bytes.
The doublewrite file flush method is used in InnoDB. It reduces the need for Unix
fsync() calls to a fraction and improves performance on most Unix flavors.
You can now use the InnoDB Monitor to print a lot of InnoDB state information, in-
cluding locks, to the standard output. This is useful in performance tuning.
Several bugs which could cause hangs in InnoDB have been fixed.
Split record_buffer to record_buffer and record_rnd_buffer. To make things
compatible to previous MySQL versions, if record_rnd_buffer is not set, then it
takes the value of record_buffer.
Fixed optimising bug in ORDER BY where some ORDER BY parts where wrongly removed.
Fixed overflow bug with ALTER TABLE and MERGE tables.
Added prototypes for my_thread_init() and my_thread_end() to ‘mysql_com.h
Added --safe-user-create option to mysqld.
Fixed bug in SELECT DISTINCT ... HAVING that caused error message Can’t find
record in #...
D.4.18 Changes in release 3.23.40
Fixed problem with --low-priority-updates and INSERT statements.
Fixed bug in slave thread when under some rare circumstances it could get 22 bytes
ahead on the offset in the master.
Added slave_net_timeout for replication.
Fixed problem with UPDATE and BDB tables.
Fixed hard bug in BDB tables when using key parts.
Fixed problem when using GRANT FILE ON database.* ...; previously we added the
DROP privilege for the database.
Fixed DELETE FROM nome_tabela ... LIMIT 0 and UPDATE FROM nome_tabela ...
LIMIT 0, which acted as though the LIMIT clause was not present (they deleted or
updated all selected rows).
CHECK TABLE now checks if an AUTO_INCREMENT column contains the value 0.
Sending a SIGHUP to mysqld will now only flush the logs, not reset the replication.
Fixed parser to allow floats of type 1.0e1 (no sign after e).
Option --force to myisamchk now also updates states.
770 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added option --warnings to mysqld. Now mysqld prints the error Aborted
connection only if this option is used.
Fixed problem with SHOW CREATE TABLE when you didn’t have a PRIMARY KEY.
Properly fixed the rename of innodb_unix_file_flush_method variable to innodb_
flush_method.
Fixed bug when converting BIGINT UNSIGNED to DOUBLE. This caused a problem when
doing comparisons with BIGINT values outside of the signed range.
Fixed bug in BDB tables when querying empty tables.
Fixed a bug when using COUNT(DISTINCT) with LEFT JOIN and there weren’t any
matching rows.
Removed all documentation referring to the GEMINI table type. GEMINI is not released
under an Open Source license.
D.4.19 Changes in release 3.23.39 (12 Jun 2001)
The AUTO_INCREMENT sequence wasn’t reset when dropping and adding an
AUTO_INCREMENT column.
CREATE ... SELECT now creates non-unique indexes delayed.
Fixed problem where LOCK TABLES nome_tabela READ followed by FLUSH TABLES put
an exclusive lock on the table.
REAL @variable values were represented with only 2 digits when converted to strings.
Fixed problem that client “hung” when LOAD TABLE FROM MASTER failed.
myisamchk --fast --force will no longer repair tables that only had the open count
wrong.
Added functions to handle symbolic links to make life easier in 4.0.
We are now using the -lcma thread library on HP-UX 10.20 so that MySQL will be
more stable on HP-UX.
Fixed problem with IF() and number of decimals in the result.
Fixed date-part extraction functions to work with dates where day and/or month is 0.
Extended argument length in option files from 256 to 512 chars.
Fixed problem with shutdown when INSERT DELAYED was waiting for a LOCK TABLE.
Fixed core dump bug in InnoDB when tablespace was full.
Fixed problem with MERGE tables and big tables (>4G) when using ORDER BY.
D.4.20 Changes in release 3.23.38 (09 May 2001)
Fixed a bug when SELECT from MERGE table sometimes results in incorrectly ordered
rows.
Fixed a bug in REPLACE() when using the ujis character set.
Applied Sleepycat BDB patches 3.2.9.1 and 3.2.9.2.
Added --skip-stack-trace option to mysqld.
CREATE TEMPORARY now works with InnoDB tables.
InnoDB now promotes sub keys to whole keys.
Appendix D: MySQL Change History 771
Added option CONCURRENT to LOAD DATA.
Better error message when slave max_allowed_packet is too low to read a very long
log event from the master.
Fixed bug when too many rows where removed when using SELECT DISTINCT ...
HAVING.
SHOW CREATE TABLE now returns TEMPORARY for temporary tables.
Added Rows_examined to slow query log.
Fixed problems with function returning empty string when used together with a group
function and a WHERE that didn’t match any rows.
New program mysqlcheck.
Added database name to output for administrative commands like CHECK,REPAIR,
OPTIMIZE.
Lots of portability fixes for InnoDB.
Changed optimiser so that queries like SELECT * FROM nome_tabela,nome_tabela2
... ORDER BY key_part1 LIMIT # will use index on key_part1 instead of filesort.
Fixed bug when doing LOCK TABLE to_table WRITE,...; INSERT INTO to_table...
SELECT ... when to_table was empty.
Fixed bug with LOCK TABLE and BDB tables.
D.4.21 Changes in release 3.23.37 (17 Apr 2001)
Fixed a bug when using MATCH() in HAVING clause.
Fixed a bug when using HEAP tables with LIKE.
Added --mysql-version option to safe_mysqld
Changed INNOBASE to InnoDB (because the INNOBASE name was already used). All
configure options and mysqld start options now use innodb instead of innobase.
This means that before upgrading to this version, you have to change any configuration
files where you have used innobase options!
Fixed bug when using indexes on CHAR(255) NULL columns.
Slave thread will now be started even if master-host is not set, as long as server-id
is set and valid ‘master.info’ is present.
Partial updates (terminated with kill) are now logged with a special error code to the
binary log. Slave will refuse to execute them if the error code indicates the update
was terminated abnormally, and will have to be recovered with SET SQL_SLAVE_SKIP_
COUNTER=1; SLAVE START after a manual sanity check/correction of data integrity.
Fixed bug that erroneously logged a drop of internal temporary table on thread termi-
nation to the binary log -- this bug affected replication.
Fixed a bug in REGEXP on 64-bit machines.
UPDATE and DELETE with WHERE unique_key_part IS NULL didn’t update/delete all
rows.
Disabled INSERT DELAYED for tables that support transactions.
Fixed bug when using date functions on TEXT/BLOB column with wrong date format.
772 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
UDFs now also work on Windows. (Patch by Ralph Mason.)
Fixed bug in ALTER TABLE and LOAD DATA INFILE that disabled key-sorting. These
commands should now be faster in most cases.
Fixed performance bug where reopened tables (tables that had been waiting for FLUSH
or REPAIR) would not use indexes for the next query.
Fixed problem with ALTER TABLE to InnoDB tables on FreeBSD.
Added mysqld variables myisam_max_sort_file_size and myisam_max_extra_sort_
file_size.
Initialise signals early to avoid problem with signals in InnoDB.
Applied patch for the tis620 character set to make comparisons case-independent and
to fix a bug in LIKE for this character set. Note: All tables that uses the tis620
character set must be fixed with myisamchk -r or REPAIR TABLE !
Added --skip-safemalloc option to mysqld.
D.4.22 Changes in release 3.23.36 (27 Mar 2001)
Fixed a bug that allowed use of database names containing a ‘.’ character. This fixes
a serious security issue when mysqld is run as root.
Fixed bug when thread creation failed (could happen when doing a lot of connections
in a short time).
Fixed some problems with FLUSH TABLES and TEMPORARY tables. (Problem with freeing
the key cache and error Can’t reopen table....)
Fixed a problem in InnoDB with other character sets than latin1 and another problem
when using many columns.
Fixed bug that caused a core dump when using a very complex query involving
DISTINCT and summary functions.
Added SET TRANSACTION ISOLATION LEVEL ...
Added SELECT ... FOR UPDATE.
Fixed bug where the number of affected rows was not returned when MySQL was
compiled without transaction support.
Fixed a bug in UPDATE where keys weren’t always used to find the rows to be updated.
Fixed a bug in CONCAT_WS() where it returned incorrect results.
Changed CREATE ... SELECT and INSERT ... SELECT to not allow concurrent inserts
as this could make the binary log hard to repeat. (Concurrent inserts are enabled if
you are not using the binary or update log.)
Changed some macros to be able to use fast mutex with glibc 2.2.
D.4.23 Changes in release 3.23.35 (15 Mar 2001)
Fixed newly introduced bug in ORDER BY.
Fixed wrong define CLIENT_TRANSACTIONS.
Fixed bug in SHOW VARIABLES when using INNOBASE tables.
Setting and using user variables in SELECT DISTINCT didn’t work.
Appendix D: MySQL Change History 773
Tuned SHOW ANALYZE for small tables.
Fixed handling of arguments in the benchmark script run-all-tests.
D.4.24 Changes in release 3.23.34a
Added extra files to the distribution to allow INNOBASE support to be compiled.
D.4.25 Changes in release 3.23.34 (10 Mar 2001)
Added the INNOBASE storage engine and the BDB storage engine to the MySQL source
distribution.
Updated the documentation about GEMINI tables.
Fixed a bug in INSERT DELAYED that caused threads to hang when inserting NULL into
an AUTO_INCREMENT column.
Fixed a bug in CHECK TABLE /REPAIR TABLE that could cause a thread to hang.
REPLACE will not replace a row that conflicts with an AUTO_INCREMENT generated key.
mysqld now only sets CLIENT_TRANSACTIONS in mysql->server_capabilities if the
server supports a transaction-safe storage engine.
Fixed LOAD DATA INFILE to allow numeric values to be read into ENUM and SET columns.
Improved error diagnostic for slave thread exit.
Fixed bug in ALTER TABLE ... ORDER BY.
Added max_user_connections variable to mysqld.
Limit query length for replication by max_allowed_packet, not the arbitrary limit of
4 MB.
Allow space around =in argument to --set-variable.
Fixed problem in automatic repair that could leave some threads in state Waiting for
table.
SHOW CREATE TABLE now displays the UNION() for MERGE tables.
ALTER TABLE now remembers the old UNION() definition.
Fixed bug when replicating timestamps.
Fixed bug in bidirectional replication.
Fixed bug in the BDB storage engine that occurred when using an index on multi-part
key where a key part may be NULL.
Fixed MAX() optimisation on sub-key for BDB tables.
Fixed problem where garbage results were returned when using BDB tables and BLOB
or TEXT fields when joining many tables.
Fixed a problem with BDB tables and TEXT columns.
Fixed bug when using a BLOB key where a const row wasn’t found.
Fixed that mysqlbinlog writes the timestamp value for each query. This ensures that
one gets same values for date functions like NOW() when using mysqlbinlog to pipe
the queries to another server.
Allow --skip-gemini,--skip-bdb, and --skip-innodb options to be specified when
invoking mysqld, even if these storage engines are not compiled in to mysqld.
774 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
One can now do GROUP BY ... DESC.
Fixed a deadlock in the SET code, when one ran SET @foo=bar, where bar is a column
reference, an error was not properly generated.
D.4.26 Changes in release 3.23.33 (09 Feb 2001)
Fixed DNS lookups not to use the same mutex as the hostname cache. This will enable
known hosts to be quickly resolved even if a DNS lookup takes a long time.
Added --character-sets-dir option to myisampack.
Removed warnings when running REPAIR TABLE ... EXTENDED.
Fixed a bug that caused a core dump when using GROUP BY on an alias, where the alias
was the same as an existing column name.
Added SEQUENCE() as an example UDF function.
Changed mysql_install_db to use BINARY for CHAR columns in the privilege tables.
Changed TRUNCATE nome_tabela to TRUNCATE TABLE nome_tabela to use the same
syntax as Oracle. Until 4.0 we will also allow TRUNCATE nome_tabela to not crash old
code.
Fixed “no found rows” bug in MyISAM tables when a BLOB was first part of a multi-part
key.
Fixed bug where CASE didn’t work with GROUP BY.
Added --sort-recover option to myisamchk.
myisamchk -S and OPTIMIZE TABLE now work on Windows.
Fixed bug when using DISTINCT on results from functions that referred to a group
function, like:
SELECT a, DISTINCT SEC_TO_TIME(SUM(a))
FROM nome_tabela GROUP BY a, b;
Fixed buffer overrun in libmysqlclient library. Fixed bug in handling STOP event
after ROTATE event in replication.
Fixed another buffer overrun in DROP DATABASE.
Added Table_locks_immediate and Table_locks_waited status variables.
Fixed bug in replication that broke slave server start with existing ‘master.info’. This
fixes a bug introduced in 3.23.32.
Added SET SQL_SLAVE_SKIP_COUNTER=n command to recover from replication glitches
without a full database copy.
Added max_binlog_size variable; the binary log will be rotated automatically when
the size crosses the limit.
Added Last_error,Last_errno, and Slave_skip_counter variables to SHOW SLAVE
STATUS.
Fixed bug in MASTER_POS_WAIT() function.
Execute core dump handler on SIGILL, and SIGBUS in addition to SIGSEGV.
On x86 Linux, print the current query and thread (connection) id, if available, in the
core dump handler.
Appendix D: MySQL Change History 775
Fixed several timing bugs in the test suite.
Extended mysqltest to take care of the timing issues in the test suite.
ALTER TABLE can now be used to change the definition for a MERGE table.
Fixed creation of MERGE tables on Windows.
Portability fixes for OpenBSD and OS/2.
Added --temp-pool option to mysqld. Using this option will cause most temporary
files created to use a small set of names, rather than a unique name for each new file.
This is to work around a problem in the Linux kernel dealing with creating a bunch of
new files with different names. With the old behaviour, Linux seems to "leak"memory,
as it’s being allocated to the directory entry cache instead of the disk cache.
D.4.27 Changes in release 3.23.32 (22 Jan 2001: Production)
Changed code to get around compiler bug in Compaq C++ on OSF/1, that broke
BACKUP,RESTORE,CHECK,REPAIR, and ANALYZE TABLE.
Added option FULL to SHOW COLUMNS. Now we show the privilege list for the columns
only if this option is given.
Fixed bug in SHOW LOGS when there weren’t any BDB logs.
Fixed a timing problem in replication that could delay sending an update to the client
until a new update was done.
Don’t convert field names when using mysql_list_fields(). This is to keep this code
compatible with SHOW FIELDS.
MERGE tables didn’t work on Windows.
Fixed problem with SET PASSWORD=... on Windows.
Added missing ‘my_config.h’ to RPM distribution.
TRIM("foo" from "foo") didn’t return an empty string.
Added --with-version-suffix option to configure.
Fixed core dump when client aborted connection without mysql_close().
Fixed a bug in RESTORE TABLE when trying to restore from a non-existent directory.
Fixed a bug which caused a core dump on the slave when replicating SET PASSWORD.
Added MASTER_POS_WAIT().
D.4.28 Changes in release 3.23.31 (17 Jan 2001)
The test suite now tests all reachable BDB interface code. During testing we found and
fixed many errors in the interface code.
Using HAVING on an empty table could produce one result row when it shouldn’t.
Fixed the MySQL RPM so it no longer depends on Perl5.
Fixed some problems with HEAP tables on Windows.
SHOW TABLE STATUS didn’t show correct average row length for tables larger than 4G.
CHECK TABLE ... EXTENDED didn’t check row links for fixed size tables.
Added option MEDIUM to CHECK TABLE.
776 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed problem when using DECIMAL() keys on negative numbers.
HOUR() (and some other TIME functions) on a CHAR column always returned NULL.
Fixed security bug in something (please upgrade if you are using an earlier MySQL
3.23 version).
Fixed buffer overflow bug when writing a certain error message.
Added usage of setrlimit() on Linux to get -O --open-files-limit=# to work on
Linux.
Added bdb_version variable to mysqld.
Fixed bug when using expression of type:
SELECT ... FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=t2.a
In this case the test in the WHERE clause was wrongly optimised away.
Fixed bug in MyISAM when deleting keys with possible NULL values, but the first key-
column was not a prefix-compressed text column.
Fixed mysql.server to read the [mysql.server] option file group rather than the
[mysql_server] group.
Fixed safe_mysqld and mysql.server to also read the server option section.
Added Threads_created status variable to mysqld.
D.4.29 Changes in release 3.23.30 (04 Jan 2001)
Added SHOW OPEN TABLES command.
Fixed that myisamdump works against old mysqld servers.
Fixed myisamchk -k# so that it works again.
Fixed a problem with replication when the binary log file went over 2G on 32-bit
systems.
LOCK TABLES will now automatically start a new transaction.
Changed BDB tables to not use internal subtransactions and reuse open files to get more
speed.
Added --mysqld=# option to safe_mysqld.
Allow hex constants in the --fields-*-by and --lines-terminated-by options to
mysqldump and mysqlimport. By Paul DuBois.
Added --safe-show-database option to mysqld.
Added have_bdb,have_gemini,have_innobase,have_raid and have_openssl to
SHOW VARIABLES to make it easy to test for supported extensions.
Added --open-files-limit option to mysqld.
Changed --open-files option to --open-files-limit in safe_mysqld.
Fixed a bug where some rows were not found with HEAP tables that had many keys.
Fixed that --bdb-no-sync works.
Changed --bdb-recover to --bdb-no-recover as recover should be on by default.
Changed the default number of BDB locks to 10000.
Fixed a bug from 3.23.29 when allocating the shared structure needed for BDB tables.
Appendix D: MySQL Change History 777
Changed mysqld_multi.sh to use configure variables. Patch by Christopher McCrory.
Added fixing of include files for Solaris 2.8.
Fixed bug with --skip-networking on Debian Linux.
Fixed problem that some temporary files where reported as having the name UNOPENED
in error messages.
Fixed bug when running two simultaneous SHOW LOGS queries.
D.4.30 Changes in release 3.23.29 (16 Dec 2000)
Configure updates for Tru64, large file support, and better TCP wrapper support. By
Albert Chin-A-Young.
Fixed bug in <=> operator.
Fixed bug in REPLACE with BDB tables.
LPAD() and RPAD() will shorten the result string if it’s longer than the length argument.
Added SHOW LOGS command.
Remove unused BDB logs on shutdown.
When creating a table, put PRIMARY keys first, followed by UNIQUE keys.
Fixed a bug in UPDATE involving multi-part keys where one specified all key parts both
in the update and the WHERE part. In this case MySQL could try to update a record
that didn’t match the whole WHERE part.
Changed drop table to first drop the tables and then the ‘.frm’ file.
Fixed a bug in the hostname cache which caused mysqld to report the hostname as ’’
in some error messages.
Fixed a bug with HEAP type tables; the variable max_heap_table_size wasn’t used.
Now either MAX_ROWS or max_heap_table_size can be used to limit the size of a HEAP
type table.
Changed the default server-id to 1 for masters and 2 for slaves to make it easier to use
the binary log.
Renamed bdb_lock_max variable to bdb_max_lock.
Added support for AUTO_INCREMENT on sub-fields for BDB tables.
Added ANALYZE of BDB tables.
In BDB tables, we now store the number of rows; this helps to optimise queries when
we need an approximation of the number of rows.
If we get an error in a multi-row statement, we now only roll back the last statement,
not the entire transaction.
If you do a ROLLBACK when you have updated a non-transactional table you will get an
error as a warning.
Added --bdb-shared-data option to mysqld.
Added Slave_open_temp_tables status variable to mysqld
Added binlog_cache_size and max_binlog_cache_size variables to mysqld.
DROP TABLE,RENAME TABLE,CREATE INDEX and DROP INDEX are now transaction end-
points.
778 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
If you do a DROP DATABASE on a symbolically linked database, both the link and the
original database is deleted.
Fixed DROP DATABASE to work on OS/2.
Fixed bug when doing a SELECT DISTINCT ... table1 LEFT JOIN table2 ... when
table2 was empty.
Added --abort-slave-event-count and --disconnect-slave-event-count options
to mysqld for debugging and testing of replication.
Fixed replication of temporary tables. Handles everything except slave server restart.
SHOW KEYS now shows whether key is FULLTEXT.
New script mysqld_multi. See hundefinedi[mysqld_multi], page hundefinedi.
Added new script, mysql-multi.server.sh. Thanks to Tim Bunce
Tim.Bunce@ig.co.uk for modifying mysql.server to easily handle hosts
running many mysqld processes.
safe_mysqld,mysql.server, and mysql_install_db have been modified to use
mysql_print_defaults instead of various hacks to read the ‘my.cnf’ files. In
addition, the handling of various paths has been made more consistent with how
mysqld handles them by default.
Automatically remove Berkeley DB transaction logs that no longer are in use.
Fixed bug with several FULLTEXT indexes in one table.
Added a warning if number of rows changes on REPAIR/OPTIMIZE.
Applied patches for OS/2 by Yuri Dario.
FLUSH TABLES nome_tabela didn’t always flush the index tree to disk properly.
--bootstrap is now run in a separate thread. This fixes a problem that caused mysql_
install_db to core dump on some Linux machines.
Changed mi_create() to use less stack space.
Fixed bug with optimiser trying to over-optimise MATCH() when used with UNIQUE key.
Changed crash-me and the MySQL benchmarks to also work with FrontBase.
Allow RESTRICT and CASCADE after DROP TABLE to make porting easier.
Reset status variable which could cause problem if one used --slow-log.
Added connect_timeout variable to mysql and mysqladmin.
Added connect-timeout as an alias for timeout for option files read by mysql_
options().
D.4.31 Changes in release 3.23.28 (22 Nov 2000: Gamma)
Added new options --pager[=...],--no-pager,--tee=... and --no-tee to the
mysql client. The new corresponding interactive commands are pager,nopager,tee
and notee. See hundefinedi[mysql], page hundefinedi,mysql --help and the interac-
tive help for more information.
Fixed crash when automatic repair of MyISAM table failed.
Fixed a major performance bug in the table locking code when one constantly had a
lot of SELECT,UPDATE and INSERT statements running. The symptom was that the
Appendix D: MySQL Change History 779
UPDATE and INSERT queries were locked for a long time while new SELECT statements
were executed before the updates.
When reading options_files with mysql_options() the return-found-rows option
was ignored.
One can now specify interactive-timeout in the option file that is read by mysql_
options(). This makes it possible to force programs that run for a long time (like
mysqlhotcopy) to use the interactive_timeout time instead of the wait_timeout
time.
Added to the slow query log the time and the user name for each logged query. If you
are using --log-long-format then also queries that do not use an index are logged,
even if the query takes less than long_query_time seconds.
Fixed a problem in LEFT JOIN which caused all columns in a reference table to be NULL.
Fixed a problem when using NATURAL JOIN without keys.
Fixed a bug when using a multi-part keys where the first part was of type TEXT or
BLOB.
DROP of temporary tables wasn’t stored in the update/binary log.
Fixed a bug where SELECT DISTINCT * ... LIMIT # only returned one row.
Fixed a bug in the assembler code in strstr() for SPARC and cleaned up the
global.h’ header file to avoid a problem with bad aliasing with the compiler
submitted with Red Hat 7.0. (Reported by Trond Eivind Glomsrd)
The --skip-networking option now works properly on NT.
Fixed a long outstanding bug in the ISAM tables when a row with a length of more
than 65K was shortened by a single byte.
Fixed a bug in MyISAM when running multiple updating processes on the same table.
Allow one to use FLUSH TABLE nome_tabela.
Added --replicate-ignore-table,--replicate-do-table,--replicate-wild-
ignore-table, and --replicate-wild-do-table options to mysqld.
Changed all log files to use our own IO_CACHE mechanism instead of FILE to avoid OS
problems when there are many files open.
Added --open-files and --timezone options to safe_mysqld.
Fixed a fatal bug in CREATE TEMPORARY TABLE ... SELECT ....
Fixed a problem with CREATE TABLE ... SELECT NULL.
Added variables large_file_support,net_read_timeout,net_write_timeout and
query_buffer_size to SHOW VARIABLES.
Added status variables created_tmp_files and sort_merge_passes to SHOW STATUS.
Fixed a bug where we didn’t allow an index name after the FOREIGN KEY definition.
Added TRUNCATE table_name as a synonym for DELETE FROM table_name.
Fixed a bug in a BDB key compare function when comparing part keys.
Added bdb_lock_max variable to mysqld.
Added more tests to the benchmark suite.
Fixed an overflow bug in the client code when using overly long database names.
780 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql_connect() now aborts on Linux if the server doesn’t answer in timeout seconds.
SLAVE START did not work if you started with --skip-slave-start and had not ex-
plicitly run CHANGE MASTER TO.
Fixed the output of SHOW MASTER STATUS to be consistent with SHOW SLAVE STATUS. (It
now has no directory in the log name.)
Added PURGE MASTER LOGS TO.
Added SHOW MASTER LOGS.
Added --safemalloc-mem-limit option to mysqld to simulate memory shortage when
compiled with the --with-debug=full option.
Fixed several core dumps in out-of-memory conditions.
SHOW SLAVE STATUS was using an uninitialised mutex if the slave had not been started
yet.
Fixed bug in ELT() and MAKE_SET() when the query used a temporary table.
CHANGE MASTER TO without specifying MASTER_LOG_POS would set it to 0 instead of 4
and hit the magic number in the master binlog.
ALTER TABLE ... ORDER BY ... syntax added. This will create the new table with the
rows in a specific order.
D.4.32 Changes in release 3.23.27 (24 Oct 2000)
Fixed a bug where the automatic repair of MyISAM tables sometimes failed when the
datafile was corrupt.
Fixed a bug in SHOW CREATE when using AUTO_INCREMENT columns.
Changed BDB tables to use new compare function in Berkeley DB 3.2.3.
You can now use Unix sockets with MIT-pthreads.
Added the latin5 (turkish) character set.
Small portability fixes.
D.4.33 Changes in release 3.23.26 (18 Oct 2000)
Renamed FLUSH MASTER and FLUSH SLAVE to RESET MASTER and RESET SLAVE.
Fixed <> to work properly with NULL.
Fixed a problem with SUBSTRING_INDEX() and REPLACE(). (Patch by Alexander Igo-
nitchev)
Fix CREATE TEMPORARY TABLE IF NOT EXISTS not to produce an error if the table exists.
If you don’t create a PRIMARY KEY in a BDB table, a hidden PRIMARY KEY will be created.
Added read-only-key optimisation to BDB tables.
LEFT JOIN in some cases preferred a full table scan when there was no WHERE clause.
When using --log-slow-queries, don’t count the time waiting for a lock.
Fixed bug in lock code on Windows which could cause the key cache to report that the
key file was crashed even if it was okay.
Automatic repair of MyISAM tables if you start mysqld with --myisam-recover.
Appendix D: MySQL Change History 781
Removed the TYPE= keyword from CHECK and REPAIR. Allow CHECK options to be
combined. (You can still use TYPE=, but this usage is deprecated.)
Fixed mutex bug in the binary replication log -- long update queries could be read only
in part by the slave if it did it at the wrong time, which was not fatal, but resulted in
a performance-degrading reconnect and a scary message in the error log.
Changed the format of the binary log -- added magic number, server version, binlog
version. Added server id and query error code for each query event.
Replication thread from the slave now will kill all the stale threads from the same
server.
Long replication user names were not being handled properly.
Added --replicate-rewrite-db option to mysqld.
Added --skip-slave-start option to mysqld.
Updates that generated an error code (such as INSERT INTO foo(some_key) values
(1),(1)) erroneously terminated the slave thread.
Added optimisation of queries where DISTINCT is only used on columns from some of
the tables.
Allow floating-point numbers where there is no sign after the exponent (like 1e1).
SHOW GRANTS didn’t always show all column grants.
Added --default-extra-file=# option to all MySQL clients.
Columns referenced in INSERT statements now are initialised properly.
UPDATE didn’t always work when used with a range on a timestamp that was part of
the key that was used to find rows.
Fixed a bug in FULLTEXT index when inserting a NULL column.
Changed to use mkstemp() instead of tempnam(). Based on a patch from John Jones.
D.4.34 Changes in release 3.23.25 (29 Sep 2000)
Fixed that databasename works as second argument to mysqlhotcopy.
The values for the UMASK and UMASK_DIR environment variables now can be specified
in octal by beginning the value with a zero.
Added RIGHT JOIN. This makes RIGHT a reserved word.
Added @@IDENTITY as a synonym for LAST_INSERT_ID(). (This is for MSSQL com-
patibility.)
Fixed a bug in myisamchk and REPAIR when using FULLTEXT index.
LOAD DATA INFILE now works with FIFOs. (Patch by Toni L. Harbaugh-Blackford.)
FLUSH LOGS broke replication if you specified a log name with an explicit extension as
the value of the log-bin option.
Fixed a bug in MyISAM with packed multi-part keys.
Fixed crash when using CHECK TABLE on Windows.
Fixed a bug where FULLTEXT index always used the koi8_ukr character set.
Fixed privilege checking for CHECK TABLE.
The MyISAM repair/reindex code didn’t use the --tmpdir option for its temporary files.
782 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added BACKUP TABLE and RESTORE TABLE.
Fixed core dump on CHANGE MASTER TO when the slave did not have the master to start
with.
Fixed incorrect Time in the processlist for Connect of the slave thread.
The slave now logs when it connects to the master.
Fixed a core dump bug when doing FLUSH MASTER if you didn’t specify a filename
argument to --log-bin.
Added missing ‘ha_berkeley.x’ files to the MySQL Windows distribution.
Fixed some mutex bugs in the log code that could cause thread blocks if new log files
couldn’t be created.
Added lock time and number of selected processed rows to slow query log.
Added --memlock option to mysqld to lock mysqld in memory on systems with the
mlockall() call (like in Solaris).
HEAP tables didn’t use keys properly. (Bug from 3.23.23.)
Added better support for MERGE tables (keys, mapping, creation, documentation...).
See hundefinedi[MERGE], page hundefinedi.
Fixed bug in mysqldump from 3.23 which caused some CHAR columns not to be quoted.
Merged analyze,check,optimize and repair code.
OPTIMIZE TABLE is now mapped to REPAIR with statistics and sorting of the index tree.
This means that for the moment it only works on MyISAM tables.
Added a pre-alloced block to root malloc to get fewer mallocs.
Added a lot of new statistics variables.
Fixed ORDER BY bug with BDB tables.
Removed warning that mysqld couldn’t remove the ‘.pid’ file under Windows.
Changed --log-isam to log MyISAM tables instead of isam tables.
Fixed CHECK TABLE to work on Windows.
Added file mutexes to make pwrite() safe on Windows.
D.4.35 Changes in release 3.23.24 (08 Sep 2000)
Added created_tmp_disk_tables variable to mysqld.
To make it possible to reliably dump and restore tables with TIMESTAMP(X) columns,
MySQL now reports columns with Xother than 14 or 8 to be strings.
Changed sort order for latin1 as it was before MySQL Version 3.23.23. Any table
that was created or modified with 3.23.22 must be repaired if it has CHAR columns that
may contain characters with ASCII values greater than 128!
Fixed small memory leak introduced from 3.23.22 when creating a temporary table.
Fixed problem with BDB tables and reading on a unique (not primary) key.
Restored the win1251 character set (it’s now only marked deprecated).
Appendix D: MySQL Change History 783
D.4.36 Changes in release 3.23.23 (01 Sep 2000)
Changed sort order for ’German’; all tables created with ’German’ sortorder must be
repaired with REPAIR TABLE or myisamchk before use!
Added --core-file option to mysqld to get a core file on Linux if mysqld dies on the
SIGSEGV signal.
MySQL client mysql now starts with option --no-named-commands (-g) by default.
This option can be disabled with --enable-named-commands (-G). This may cause
incompatibility problems in some cases, for example, in SQL scripts that use named
commands without a semicolon, etc. ! Long format commands still work from the first
line.
Fixed a problem when using many pending DROP TABLE statements at the same time.
Optimiser didn’t use keys properly when using LEFT JOIN on an empty table.
Added shorter help text when invoking mysqld with incorrect options.
Fixed non-fatal free() bug in mysqlimport.
Fixed bug in MyISAM index handling of DECIMAL/NUMERIC keys.
Fixed a bug in concurrent insert in MyISAM tables. In some contexts, usage of MIN(key_
part) or MAX(key_part) returned an empty set.
Updated mysqlhotcopy to use the new FLUSH TABLES table_list syntax. Only tables
which are being backed up are flushed now.
Changed behaviour of --enable-thread-safe-client so that both non-threaded (-
lmysqlclient) and threaded (-lmysqlclient_r) libraries are built. Users who linked
against a threaded -lmysqlclient will need to link against -lmysqlclient_r now.
Added atomic RENAME TABLE command.
Don’t count NULL values in COUNT(DISTINCT ...).
Changed ALTER TABLE,LOAD DATA INFILE on empty tables and INSERT ... SELECT
... on empty tables to create non-unique indexes in a separate batch with sorting.
This will make the above calls much faster when you have many indexes.
ALTER TABLE now logs the first used insert id correctly.
Fixed crash when adding a default value to a BLOB column.
Fixed a bug with DATE_ADD/DATE_SUB where it returned a datetime instead of a date.
Fixed a problem with the thread cache which made some threads show up as
***DEAD*** in SHOW PROCESSLIST.
Fixed a lock in our thr rwlock code, which could make selects that run at the same time
as concurrent inserts crash. This only affects systems that don’t have the pthread_
rwlock_rdlock code.
When deleting rows with a non-unique key in a HEAP table, all rows weren’t always
deleted.
Fixed bug in range optimiser for HEAP tables for searches on a part index.
Fixed SELECT on part keys to work with BDB tables.
Fixed INSERT INTO bdb_table ... SELECT to work with BDB tables.
CHECK TABLE now updates key statistics for the table.
784 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ANALYZE TABLE will now only update tables that have been changed since the last
ANALYZE. Note that this is a new feature and tables will not be marked to be analysed
until they are updated in any way with 3.23.23 or newer. For older tables, you have to
do CHECK TABLE to update the key distribution.
Fixed some minor privilege problems with CHECK,ANALYZE,REPAIR and SHOW CREATE
commands.
Added CHANGE MASTER TO statement.
Added FAST,QUICK EXTENDED check types to CHECK TABLES.
Changed myisamchk so that --fast and --check-only-changed are also honored with
--sort-index and --analyze.
Fixed fatal bug in LOAD TABLE FROM MASTER that did not lock the table during index
re-build.
LOAD DATA INFILE broke replication if the database was excluded from replication.
More variables in SHOW SLAVE STATUS and SHOW MASTER STATUS.
SLAVE STOP now will not return until the slave thread actually exits.
Full-text search via the MATCH() function and FULLTEXT index type (for MyISAM files).
This makes FULLTEXT a reserved word.
D.4.37 Changes in release 3.23.22 (31 Jul 2000)
Fixed that lex_hash.h is created properly for each MySQL distribution.
Fixed that MASTER and COLLECTION are not reserved words.
The log generated by --slow-query-log didn’t contain the whole queries.
Fixed that open transactions in BDB tables are rolled back if the connection is closed
unexpectedly.
Added workaround for a bug in gcc 2.96 (intel) and gcc 2.9 (IA64) in gen_lex_hash.c.
Fixed memory leak in the client library when using host= in the ‘my.cnf’ file.
Optimised functions that manipulate the hours/minutes/seconds.
Fixed bug when comparing the result of DATE_ADD()/DATE_SUB() against a number.
Changed the meaning of -F, --fast for myisamchk. Added -C, --check-only-
changed option to myisamchk.
Added ANALYZE nome_tabela to update key statistics for tables.
Changed binary items 0x... to be regarded as integers by default.
Fix for SCO and SHOW PROCESSLIST.
Added auto-rehash on reconnect for the mysql client.
Fixed a newly introduced bug in MyISAM, where the index file couldn’t get bigger than
64M.
Added SHOW MASTER STATUS and SHOW SLAVE STATUS.
D.4.38 Changes in release 3.23.21
Added mysql_character_set_name() function to the MySQL C API.
Made the update log ASCII 0 safe.
Appendix D: MySQL Change History 785
Added the mysql_config script.
Fixed problem when using <or >with a char column that was only partly indexed.
One would get a core dump if the log file was not readable by the MySQL user.
Changed mysqladmin to use CREATE DATABASE and DROP DATABASE statements instead
of the old deprecated API calls.
Fixed chown warning in safe_mysqld.
Fixed a bug in ORDER BY that was introduced in 3.23.19.
Only optimise the DELETE FROM nome_tabela to do a drop+create of the table if we are
in AUTOCOMMIT mode (needed for BDB tables).
Added extra checks to avoid index corruption when the ISAM/MyISAM index files get
full during an INSERT/UPDATE.
myisamchk didn’t correctly update row checksum when used with -ro (this only gave
a warning in subsequent runs).
Fixed bug in REPAIR TABLE so that it works with tables without indexes.
Fixed buffer overrun in DROP DATABASE.
LOAD TABLE FROM MASTER is sufficiently bug-free to announce it as a feature.
MATCH and AGAINST are now reserved words.
D.4.39 Changes in release 3.23.20
Fixed bug in 3.23.19; DELETE FROM nome_tabela removed the ‘.frm’ file.
Added SHOW CREATE TABLE.
D.4.40 Changes in release 3.23.19
Changed copyright for all files to GPL for the server code and utilities and to LGPL for
the client libraries.
Fixed bug where all rows matching weren’t updated on a MyISAM table when doing
update based on key on a table with many keys and some key changed values.
The Linux MySQL RPMs and binaries are now statically linked with a linuxthread
version that has faster mutex handling when used with MySQL.
ORDER BY can now use REF keys to find subsets of the rows that need to be sorted.
Changed name of print_defaults program to my_print_defaults to avoid name
confusion.
Fixed NULLIF() to work as required by SQL-99.
Added net_read_timeout and net_write_timeout as startup parameters to mysqld.
Fixed bug that destroyed index when doing myisamchk --sort-records on a table
with prefix compressed index.
Added pack_isam and myisampack to the standard MySQL distribution.
Added the syntax BEGIN WORK (the same as BEGIN).
Fixed core dump bug when using ORDER BY on a CONV() expression.
Added LOAD TABLE FROM MASTER.
Added FLUSH MASTER and FLUSH SLAVE.
Fixed big/little endian problem in the replication.
786 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.4.41 Changes in release 3.23.18
Fixed a problem from 3.23.17 when choosing character set on the client side.
Added FLUSH TABLES WITH READ LOCK to make a global lock suitable for making a copy
of MySQL datafiles.
CREATE TABLE ... SELECT ... PROCEDURE now works.
Internal temporary tables will now use compressed index when using GROUP BY on
VARCHAR/CHAR columns.
Fixed a problem when locking the same table with both a READ and a WRITE lock.
Fixed problem with myisamchk and RAID tables.
D.4.42 Changes in release 3.23.17
Fixed a bug in FIND_IN_SET() when the first argument was NULL.
Added table locks to Berkeley DB.
Fixed a bug with LEFT JOIN and ORDER BY where the first table had only one matching
row.
Added 4 sample ‘my.cnf’ example files in the ‘support-files’ directory.
Fixed duplicated key problem when doing big GROUP BY operations. (This bug was
probably introduced in 3.23.15.)
Changed syntax for INNER JOIN to match SQL-99.
Added NATURAL JOIN syntax.
A lot of fixes in the BDB interface.
Added handling of --no-defaults and --defaults-file to safe_mysqld.sh and
mysql_install_db.sh.
Fixed bug in reading compressed tables with many threads.
Fixed that USE INDEX works with PRIMARY keys.
Added BEGIN statement to start a transaction in AUTOCOMMIT mode.
Added support for symbolic links for Windows.
Changed protocol to let client know if the server is in AUTOCOMMIT mode and if there
is a pending transaction. If there is a pending transaction, the client library will give
an error before reconnecting to the server to let the client know that the server did a
rollback. The protocol is still backward-compatible with old clients.
KILL now works on a thread that is locked on a ’write’ to a dead client.
Fixed memory leak in the replication slave thread.
Added new log-slave-updates option to mysqld, to allow daisy-chaining the slaves.
Fixed compile error on FreeBSD and other systems where pthread_t is not the same
as int.
Fixed master shutdown aborting the slave thread.
Fixed a race condition in INSERT DELAYED code when doing ALTER TABLE.
Added deadlock detection sanity checks to INSERT DELAYED.
Appendix D: MySQL Change History 787
D.4.43 Changes in release 3.23.16
Added SLAVE START and SLAVE STOP statements.
Added TYPE=QUICK option to CHECK and to REPAIR.
Fixed bug in REPAIR TABLE when the table was in use by other threads.
Added a thread cache to make it possible to debug MySQL with gdb when one does
a lot of reconnects. This will also improve systems where you can’t use persistent
connections.
Lots of fixes in the Berkeley DB interface.
UPDATE IGNORE will not abort if an update results in a DUPLICATE_KEY error.
Put CREATE TEMPORARY TABLE commands in the update log.
Fixed bug in handling of masked IP numbers in the privilege tables.
Fixed bug with delay_key_write tables and CHECK TABLE.
Added replicate-do-db and replicate-ignore-db options to mysqld, to restrict
which databases get replicated.
Added SQL_LOG_BIN option.
D.4.44 Changes in release 3.23.15 (May 2000: Beta)
To start mysqld as root, you must now use the --user=root option.
Added interface to Berkeley DB. (This is not yet functional; play with it at your own
risk!)
Replication between master and slaves.
Fixed bug that other threads could steal a lock when a thread had a lock on a table
and did a FLUSH TABLES command.
Added the slow_launch_time variable and the Slow_launch_threads status vari-
able to mysqld. These can be examined with mysqladmin variables and mysqladmin
extended-status.
Added functions INET_NTOA() and INET_ATON().
The default type of IF() now depends on the second and third arguments and not only
on the second argument.
Fixed case when myisamchk could go into a loop when trying to repair a crashed table.
Don’t write INSERT DELAYED to update log if SQL_LOG_UPDATE=0.
Fixed problem with REPLACE on HEAP tables.
Added possible character sets and time zone to SHOW VARIABLES output.
Fixed bug in locking code that could result in locking problems with concurrent inserts
under high load.
Fixed a problem with DELETE of many rows on a table with compressed keys where
MySQL scanned the index to find the rows.
Fixed problem with CHECK on table with deleted keyblocks.
Fixed a bug in reconnect (at the client side) where it didn’t free memory properly in
some contexts.
788 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed problems in update log when using LAST_INSERT_ID() to update a table with
an AUTO_INCREMENT key.
Added NULLIF() function.
Fixed bug when using LOAD DATA INFILE on a table with BLOB/TEXT columns.
Optimised MyISAM to be faster when inserting keys in sorted order.
EXPLAIN SELECT ... now also prints out whether MySQL needs to create a temporary
table or use file sorting when resolving the SELECT.
Added optimisation to skip ORDER BY parts where the part is a constant expression in
the WHERE part. Indexes can now be used even if the ORDER BY doesn’t match the index
exactly, as long as all the unused index parts and all the extra ORDER BY columns are
constants in the WHERE clause. See hundefinedi[MySQL indexes], page hundefinedi.
UPDATE and DELETE on a whole unique key in the WHERE part are now faster than before.
Changed RAID_CHUNKSIZE to be in 1024-byte increments.
Fixed core dump in LOAD_FILE(NULL).
D.4.45 Changes in release 3.23.14
Added mysql_real_escape_string() function to the MySQL C API.
Fixed a bug in CONCAT() where one of the arguments was a function that returned a
modified argument.
Fixed a critical bug in myisamchk, where it updated the header in the index file when
one only checked the table. This confused the mysqld daemon if it updated the same
table at the same time. Now the status in the index file is only updated if one uses
--update-state. With older myisamchk versions you should use --read-only when
only checking tables, if there is the slightest chance that the mysqld server is working
on the table at the same time!
Fixed that DROP TABLE is logged in the update log.
Fixed problem when searching on DECIMAL() key field where the column data contained
leading zeros.
Fix bug in myisamchk when the AUTO_INCREMENT column isn’t the first key.
Allow DATETIME in ISO8601 format: 2000-03-12T12:00:00
Dynamic character sets. A mysqld binary can now handle many different character
sets (you can choose which when starting mysqld).
Added command REPAIR TABLE.
Added mysql_thread_safe() function to the MySQL C API.
Added the UMASK_DIR environment variable.
Added CONNECTION_ID() function to return the client connection thread ID.
When using =on BLOB or VARCHAR BINARY keys, where only a part of the column was
indexed, the whole column of the result row wasn’t compared.
Fix for sjis character set and ORDER BY.
When running in ANSI mode, don’t allow columns to be used that aren’t in the GROUP
BY part.
Appendix D: MySQL Change History 789
D.4.46 Changes in release 3.23.13
Fixed problem when doing locks on the same table more than 2 times in the same LOCK
TABLE command; this fixed the problem one got when running the test-ATIS test with
--fast or --check-only-changed.
Added SQL_BUFFER_RESULT option to SELECT.
Removed end space from double/float numbers in results from temporary tables.
Added CHECK TABLE command.
Added changes for MyISAM in 3.23.12 that didn’t get into the source distribution because
of CVS problems.
Fixed bug so that mysqladmin shutdown will wait for the local server to close down.
Fixed a possible endless loop when calculating timestamp.
Added print_defaults program to the ‘.rpm’ files. Removed mysqlbug from the client
.rpm’ file.
D.4.47 Changes in release 3.23.12 (07 Mar 2000)
Fixed bug in MyISAM involving REPLACE ... SELECT ... which could give a corrupted
table.
Fixed bug in myisamchk where it incorrectly reset the AUTO_INCREMENT value.
LOTS of patches for Linux Alpha. MySQL now appears to be relatively stable on
Alpha.
Changed DISTINCT on HEAP temporary tables to use hashed keys to quickly find dupli-
cated rows. This mostly concerns queries of type SELECT DISTINCT ... GROUP BY ....
This fixes a problem where not all duplicates were removed in queries of the above
type. In addition, the new code is MUCH faster.
Added patches to make MySQL compile on Mac OS X.
Added IF NOT EXISTS clause to CREATE DATABASE.
Added --all-databases and --databases options to mysqldump to allow dumping of
many databases at the same time.
Fixed bug in compressed DECIMAL() index in MyISAM tables.
Fixed bug when storing 0 into a timestamp.
When doing mysqladmin shutdown on a local connection, mysqladmin now waits until
the PID file is gone before terminating.
Fixed core dump with some COUNT(DISTINCT ...) queries.
Fixed that myisamchk works properly with RAID tables.
Fixed problem with LEFT JOIN and key_field IS NULL.
Fixed bug in net_clear() which could give the error Aborted connection in the
MySQL clients.
Added options USE INDEX (key_list) and IGNORE INDEX (key_list) as parameters
in SELECT.
DELETE and RENAME should now work on RAID tables.
790 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.4.48 Changes in release 3.23.11
Allow the ALTER TABLE nome_tabela ADD (field_list) syntax.
Fixed problem with optimiser that could sometimes use incorrect keys.
Fixed that GRANT/REVOKE ALL PRIVILEGES doesn’t affect GRANT OPTION.
Removed extra ‘)’ from the output of SHOW GRANTS.
Fixed problem when storing numbers in timestamps.
Fix problem with timezones that have half hour offsets.
Allow the syntax UNIQUE INDEX in CREATE statements.
mysqlhotcopy - fast online hot-backup utility for local MySQL databases. By Tim
Bunce.
New more secure mysqlaccess. Thanks to Steve Harvey for this.
Added --i-am-a-dummy and --safe-updates options to mysql.
Added select_limit and max_join_size variables to mysql.
Added SQL_MAX_JOIN_SIZE and SQL_SAFE_UPDATES options.
Added READ LOCAL lock that doesn’t lock the table for concurrent inserts. (This is used
by mysqldump.)
Changed that LOCK TABLES ... READ doesn’t anymore allow concurrent inserts.
Added --skip-delay-key-write option to mysqld.
Fixed security problem in the protocol regarding password checking.
_rowid can now be used as an alias for an integer type unique indexed column.
Added back blocking of SIGPIPE when compiling with --thread-safe-clients to
make things safe for old clients.
D.4.49 Changes in release 3.23.10
Fixed bug in 3.23.9 where memory wasn’t properly freed when using LOCK TABLES.
D.4.50 Changes in release 3.23.9
Fixed problem that affected queries that did arithmetic on group functions.
Fixed problem with timestamps and INSERT DELAYED.
Fixed that date_col BETWEEN const_date AND const_date works.
Fixed problem when only changing a 0 to NULL in a table with BLOB/TEXT columns.
Fixed bug in range optimiser when using many key parts and or on the middle key
parts: WHERE K1=1 and K3=2 and (K2=2 and K4=4 or K2=3 and K4=5)
Added source command to mysql to allow reading of batch files inside the mysql client.
Original patch by Matthew Vanecek.
Fixed critical problem with the WITH GRANT OPTION option.
Don’t give an unnecessary GRANT error when using tables from many databases in the
same query.
Added VIO wrapper (needed for SSL support; by Andrei Errapart and T˜onu Samuel).
Appendix D: MySQL Change History 791
Fixed optimiser problem on SELECT when using many overlapping indexes. MySQL
should now be able to choose keys even better when there are many keys to choose
from.
Changed optimiser to prefer a range key instead of a ref key when the range key can
uses more columns than the ref key (which only can use columns with =). For example,
the following type of queries should now be faster: SELECT * from key_part_1=const
and key_part_2 > const2
Fixed bug that a change of all VARCHAR columns to CHAR columns didn’t change row
type from dynamic to fixed.
Disabled floating-point exceptions for FreeBSD to fix core dump when doing SELECT
FLOOR(POW(2,63)).
Renamed mysqld startup option from --delay-key-write to --delay-key-write-
for-all-tables.
Added read-next-on-key to HEAP tables. This should fix all problems with HEAP tables
when using non-UNIQUE keys.
Added option to print default arguments to all clients.
Added --log-slow-queries option to mysqld to log all queries that take a long time
to a separate log file with a time indicating how long the query took.
Fixed core dump when doing WHERE key_col=RAND(...).
Fixed optimisation bug in SELECT ... LEFT JOIN ... key_col IS NULL, when key_col
could contain NULL values.
Fixed problem with 8-bit characters as separators in LOAD DATA INFILE.
D.4.51 Changes in release 3.23.8 (02 Jan 2000)
Fixed problem when handling indexfiles larger than 8G.
Added latest patches to MIT-pthreads for NetBSD.
Fixed problem with timezones that are <GMT - 11.
Fixed a bug when deleting packed keys in NISAM.
Fixed problem with ISAM when doing some ORDER BY ... DESC queries.
Fixed bug when doing a join on a text key which didn’t cover the whole key.
Option --delay-key-write didn’t enable delayed key writing.
Fixed update of TEXT column which involved only case changes.
Fixed that INSERT DELAYED doesn’t update timestamps that are given.
Added function YEARWEEK() and options x,X,vand Vto DATE_FORMAT().
Fixed problem with MAX(indexed_column) and HEAP tables.
Fixed problem with BLOB NULL keys and LIKE "prefix%".
Fixed problem with MyISAM and fixed-length rows <5 bytes.
Fixed problem that could cause MySQL to touch freed memory when doing very com-
plicated GROUP BY queries.
Fixed core dump if you got a crashed table where an ENUM field value was too big.
792 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.4.52 Changes in release 3.23.7 (10 Dec 1999)
Fixed workaround under Linux to avoid problems with pthread_mutex_timedwait,
which is used with INSERT DELAYED. See hundefinedi[Linux], page hundefinedi.
Fixed that one will get a ’disk full’ error message if one gets disk full when doing sorting
(instead of waiting until we got more disk space).
Fixed a bug in MyISAM with keys >250 characters.
In MyISAM one can now do an INSERT at the same time as other threads are reading
from the table.
Added max_write_lock_count variable to mysqld to force a READ lock after a certain
number of WRITE locks.
Inverted flag delay_key_write on show variables.
Renamed concurrency variable to thread_concurrency.
The following functions are now multi-byte-safe: LOCATE(substr,str),
POSITION(substr IN str),LOCATE(substr,str,pos),INSTR(str,substr),
LEFT(str,len),RIGHT(str,len),SUBSTRING(str,pos,len),SUBSTRING(str
FROM pos FOR len),MID(str,pos,len),SUBSTRING(str,pos),SUBSTRING(str
FROM pos),SUBSTRING_INDEX(str,delim,count),RTRIM(str),TRIM([[BOTH |
TRAILING] [remstr] FROM] str),REPLACE(str,from_str,to_str),REVERSE(str),
INSERT(str,pos,len,newstr),LCASE(str),LOWER(str),UCASE(str) and
UPPER(str); patch by Wei He.
Fix core dump when releasing a lock from a non-existent table.
Remove locks on tables before starting to remove duplicates.
Added option FULL to SHOW PROCESSLIST.
Added option --verbose to mysqladmin.
Fixed problem when automatically converting HEAP to MyISAM.
Fixed bug in HEAP tables when doing insert +delete +insert +scan the table.
Fixed bugs on Alpha with REPLACE() and LOAD DATA INFILE.
Added interactive_timeout variable to mysqld.
Changed the argument to mysql_data_seek() from ulong to ulonglong.
D.4.53 Changes in release 3.23.6
Added -O lower_case_table_names={0|1} option to mysqld to allow users to force
table names to lowercase.
Added SELECT ... INTO DUMPFILE.
Added --ansi option to mysqld to make some functions SQL-99 compatible.
Temporary table names now start with #sql.
Added quoting of identifiers with ("in --ansi mode).
Changed to use snprintf() when printing floats to avoid some buffer overflows on
FreeBSD.
Made FLOOR() overflow safe on FreeBSD.
Added --quote-names option to mysqldump.
Appendix D: MySQL Change History 793
Fixed bug that one could make a part of a PRIMARY KEY NOT NULL.
Fixed encrypt() to be thread-safe and not reuse buffer.
Added mysql_odbc_escape_string() function to support big5 characters in MyO-
DBC.
Rewrote the storage engine to use classes. This introduces a lot of new code, but will
make table handling faster and better.
Added patch by Sasha for user-defined variables.
Changed that FLOAT and DOUBLE (without any length modifiers) no longer are fixed
decimal point numbers.
Changed the meaning of FLOAT(X): Now this is the same as FLOAT if X <= 24 and a
DOUBLE if 24 < X <= 53.
DECIMAL(X) is now an alias for DECIMAL(X,0) and DECIMAL is now an alias for
DECIMAL(10,0). The same goes for NUMERIC.
Added option ROW_FORMAT={default | dynamic | fixed | compressed} to CREATE_
TABLE.
DELETE FROM table_name didn’t work on temporary tables.
Changed function CHAR_LENGTH() to be multi-byte character safe.
Added function ORD(string).
D.4.54 Changes in release 3.23.5 (20 Oct 1999)
Fixed some Y2K problems in the new date handling in 3.23.
Fixed problem with SELECT DISTINCT ... ORDER BY RAND().
Added patches by Sergei A. Golubchik for text searching on the MyISAM level.
Fixed cache overflow problem when using full joins without keys.
Fixed some configure issues.
Some small changes to make parsing faster.
Adding a column after the last field with ALTER TABLE didn’t work.
Fixed problem when using an AUTO_INCREMENT column in two keys
With MyISAM, you now can have an AUTO_INCREMENT column as a key sub part: CREATE
TABLE foo (a INT NOT NULL AUTO_INCREMENT, b CHAR(5), PRIMARY KEY (b,a))
Fixed bug in MyISAM with packed char keys that could be NULL.
AS on field name with CREATE TABLE table_name SELECT ... didn’t work.
Allow use of NATIONAL and NCHAR when defining character columns. This is the same
as not using BINARY.
Don’t allow NULL columns in a PRIMARY KEY (only in UNIQUE keys).
Clear LAST_INSERT_ID() if one uses this in ODBC: WHERE auto_increment_column
IS NULL. This seems to fix some problems with Access.
SET SQL_AUTO_IS_NULL=0|1 now turns on/off the handling of searching after the last
inserted row with WHERE auto_increment_column IS NULL.
Added new variable concurrency to mysqld for Solaris.
794 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added --relative option to mysqladmin to make extended-status more useful to
monitor changes.
Fixed bug when using COUNT(DISTINCT ...) on an empty table.
Added support for the Chinese character set GBK.
Fixed problem with LOAD DATA INFILE and BLOB columns.
Added bit operator ~(negation).
Fixed problem with UDF functions.
D.4.55 Changes in release 3.23.4 (28 Sep 1999)
Inserting a DATETIME into a TIME column no longer will try to store ’days’ in it.
Fixed problem with storage of float/double on little endian machines. (This affected
SUM().)
Added connect timeout on TCP/IP connections.
Fixed problem with LIKE "%" on an index that may have NULL values.
REVOKE ALL PRIVILEGES didn’t revoke all privileges.
Allow creation of temporary tables with same name as the original table.
When granting a user a GRANT option for a database, he couldn’t grant privileges to
other users.
New command: SHOW GRANTS FOR user (by Sinisa).
New date_add syntax: date/datetime + INTERVAL # interval_type. By Joshua
Chamas.
Fixed privilege check for LOAD DATA REPLACE.
Automatic fixing of broken include files on Solaris 2.7
Some configure issues to fix problems with big filesystem detection.
REGEXP is now case-insensitive if you use non-binary strings.
D.4.56 Changes in release 3.23.3
Added patches for MIT-pthreads on NetBSD.
Fixed range bug in MyISAM.
ASC is now the default again for ORDER BY.
Added LIMIT to UPDATE.
Added mysql_change_user() function to the MySQL C API.
Added character set to SHOW VARIABLES.
Added support of --[whitespace] comments.
Allow INSERT into nome_tabela VALUES (), that is, you may now specify an empty
value list to insert a row in which each column is set to its default value.
Changed SUBSTRING(text FROM pos) to conform to SQL-99. (Before this construct
returned the rightmost pos characters.)
SUM() with GROUP BY returned 0 on some systems.
Changed output for SHOW TABLE STATUS.
Appendix D: MySQL Change History 795
Added DELAY_KEY_WRITE option to CREATE TABLE.
Allow AUTO_INCREMENT on any key part.
Fixed problem with YEAR(NOW()) and YEAR(CURDATE()).
Added CASE construct.
New function COALESCE().
D.4.57 Changes in release 3.23.2 (09 Aug 1999)
Fixed range optimiser bug: SELECT * FROM table_name WHERE key_part1 >= const
AND (key_part2 = const OR key_part2 = const). The bug was that some rows could
be duplicated in the result.
Running myisamchk without -a updated the index distribution incorrectly.
SET SQL_LOW_PRIORITY_UPDATES=1 was causing a parse error.
You can now update index columns that are used in the WHERE clause. UPDATE nome_
tabela SET KEY=KEY+1 WHERE KEY > 100
Date handling should now be a bit faster.
Added handling of fuzzy dates (dates where day or month is 0), such as ’1999-01-00’.
Fixed optimisation of SELECT ... WHERE key_part1=const1 AND key_part_2=const2
AND key_part1=const4 AND key_part2=const4; indextype should be range instead of
ref.
Fixed egcs 1.1.2 optimiser bug (when using BLOBs) on Linux Alpha.
Fixed problem with LOCK TABLES combined with DELETE FROM table.
MyISAM tables now allow keys on NULL and BLOB/TEXT columns.
The following join is now much faster: SELECT ... FROM t1 LEFT JOIN t2 ON ...
WHERE t2.not_null_column IS NULL.
ORDER BY and GROUP BY can be done on functions.
Changed handling of ’const item’ to allow handling of ORDER BY RAND().
Indexes are now used for WHERE key_column = function.
Indexes are now used for WHERE key_column = nome_coluna even if the columns are
not identically packed.
Indexes are now used for WHERE nome_coluna IS NULL.
Changed heap tables to be stored in low byte first order (to make it easy to convert to
MyISAM tables)
Automatic change of HEAP temporary tables to MyISAM tables in case of ’table is full’
errors.
Added --init-file=file_name option to mysqld.
Added COUNT(DISTINCT value, [value, ...]).
CREATE TEMPORARY TABLE now creates a temporary table, in its own namespace, that
is automatically deleted if connection is dropped.
New reserved words (required for CASE): CASE, THEN, WHEN, ELSE and END.
New functions EXPORT_SET() and MD5().
Support for the GB2312 Chinese character set.
796 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.4.58 Changes in release 3.23.1
Fixed some compilation problems.
D.4.59 Changes in release 3.23.0 (05 Aug 1999: Alpha)
A new storage engine library (MyISAM) with a lot of new features. See hundefinedi
[MyISAM], page hundefinedi.
You can create in-memory HEAP tables which are extremely fast for lookups.
Support for big files (63-bit) on OSs that support big files.
New function LOAD_FILE(filename) to get the contents of a file as a string value.
New operator <=> which will act as =but will return TRUE if both arguments are
NULL. This is useful for comparing changes between tables.
Added the ODBC 3.0 EXTRACT(interval FROM datetime) function.
Columns defined as FLOAT(X) are not rounded on storage and may be in scientific
notation (1.0 E+10) when retrieved.
REPLACE is now faster than before.
Changed LIKE character comparison to behave as =; This means that ’e’ LIKE ’´e’ is
now true. (If the line doesn’t display correctly, the latter ’e’ is a French ’e’ with a dot
above.)
SHOW TABLE STATUS returns a lot of information about the tables.
Added LIKE to the SHOW STATUS command.
Added Privileges column to SHOW COLUMNS.
Added Packed and Comment columns to SHOW INDEX.
Added comments to tables (with CREATE TABLE ... COMMENT "xxx").
Added UNIQUE, as in CREATE TABLE table_name (col INT not null UNIQUE)
New create syntax: CREATE TABLE table_name SELECT ...
New create syntax: CREATE TABLE IF NOT EXISTS ...
Allow creation of CHAR(0) columns.
DATE_FORMAT() now requires ‘%’ before any format character.
DELAYED is now a reserved word (sorry about that :( ).
An example procedure is added: analyse, file: sql_analyse.c’. This will describe
the data in your query. Try the following:
SELECT ... FROM ...
WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
This procedure is extremely useful when you want to check the data in your table!
BINARY cast to force a string to be compared in case-sensitive fashion.
Added --skip-show-database option to mysqld.
Check whether a row has changed in an UPDATE now also works with BLOB/TEXT
columns.
Added the INNER join syntax. NOTE: This made INNER a reserved word!
Appendix D: MySQL Change History 797
Added support for netmasks to the hostname in the MySQL grant tables. You can
specify a netmask using the IP/NETMASK syntax.
If you compare a NOT NULL DATE/DATETIME column with IS NULL, this is changed to a
compare against 0to satisfy some ODBC applications. (By shreeve@uci.edu.)
NULL IN (...) now returns NULL instead of 0. This will ensure that null_column NOT
IN (...) doesn’t match NULL values.
Fix storage of floating-point values in TIME columns.
Changed parsing of TIME strings to be more strict. Now the fractional second part is
detected (and currently skipped). The following formats are supported:
[[DAYS] [H]H:]MM:]SS[.fraction]
[[[[[H]H]H]H]MM]SS[.fraction]
Detect (and ignore) fractional second part from DATETIME.
Added the LOW_PRIORITY attribute to LOAD DATA INFILE.
The default index name now uses the same case as the column name on which the
index name is based.
Changed default number of connections to 100.
Use bigger buffers when using LOAD DATA INFILE.
DECIMAL(x,y) now works according to SQL-99.
Added aggregate UDF functions. Thanks to Andreas F. Bobak (bobak@relog.ch) for
this!
LAST_INSERT_ID() is now updated for INSERT INTO ... SELECT.
Some small changes to the join table optimiser to make some joins faster.
SELECT DISTINCT is much faster; it uses the new UNIQUE functionality in MyISAM. One
difference compared to MySQL Version 3.22 is that the output of DISTINCT is no longer
sorted.
All C client API macros are now functions to make shared libraries more reliable.
Because of this, you can no longer call mysql_num_fields() on a MYSQL object, you
must use mysql_field_count() instead.
Added use of LIBWRAP; patch by Henning P. Schmiedehausen.
Don’t allow AUTO_INCREMENT for other than numerical columns.
Using AUTO_INCREMENT will now automatically make the column NOT NULL.
Show NULL as the default value for AUTO_INCREMENT columns.
Added SQL_BIG_RESULT;SQL_SMALL_RESULT is now default.
Added a shared library RPM. This enhancement was contributed by David Fox
(dsfox@cogsci.ucsd.edu).
Added --enable-large-files and --disable-large-files switches to configure.
See ‘configure.in’ for some systems where this is automatically turned off because of
broken implementations.
Upgraded readline to 4.0.
New CREATE TABLE options: PACK_KEYS and CHECKSUM.
Added --default-table-type option to mysqld.
798 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.5 Changes in release 3.22.x (Old; discontinued)
The 3.22 version has faster and safer connect code than version 3.21, as well as a lot of new
nice enhancements. As there aren’t really any major changes, upgrading from 3.21 to 3.22
should be very easy and painless. See from-3.21-snt [Upgrading-from-3.21], page from-3.21-
pg.
D.5.1 Changes in release 3.22.35
Fixed problem with STD().
Merged changes from the newest ISAM library from 3.23.
Fixed problem with INSERT DELAYED.
Fixed a bug core dump when using a LEFT JOIN/STRAIGHT_JOIN on a table with only
one row.
D.5.2 Changes in release 3.22.34
Fixed problem with GROUP BY on TINYBLOB columns; this caused bugzilla to not show
rows in some queries.
Had to do total recompile of the Windows binary version as VC++ didn’t compile all
relevant files for 3.22.33 :(
D.5.3 Changes in release 3.22.33
Fixed problems in Windows when locking tables with LOCK TABLE.
Quicker kill of SELECT DISTINCT queries.
D.5.4 Changes in release 3.22.32 (14 Feb 2000)
Fixed problem when storing numbers in timestamps.
Fix problem with timezones that have half hour offsets.
Added mysqlhotcopy, a fast online hot-backup utility for local MySQL databases. By
Tim Bunce.
New more secure mysqlaccess. Thanks to Steve Harvey for this.
Fixed security problem in the protocol regarding password checking.
Fixed problem that affected queries that did arithmetic on GROUP functions.
Fixed a bug in the ISAM code when deleting rows on tables with packed indexes.
D.5.5 Changes in release 3.22.31
A few small fixes for the Windows version.
D.5.6 Changes in release 3.22.30
Fixed optimiser problem on SELECT when using many overlapping indexes.
Disabled floating-point exceptions for FreeBSD to fix core dump when doing SELECT
FLOOR(POW(2,63)).
Appendix D: MySQL Change History 799
Added print of default arguments options to all clients.
Fixed critical problem with the WITH GRANT OPTION option.
Fixed non-critical Y2K problem when writing short date to log files.
D.5.7 Changes in release 3.22.29 (02 Jan 2000)
Upgraded the configure and include files to match the latest 3.23 version. This should
increase portability and make it easier to build shared libraries.
Added latest patches to MIT-pthreads for NetBSD.
Fixed problem with timezones that are <GMT -11.
Fixed a bug when deleting packed keys in NISAM.
Fixed problem that could cause MySQL to touch freed memory when doing very com-
plicated GROUP BY queries.
Fixed core dump if you got a crashed table where an ENUM field value was too big.
Added mysqlshutdown.exe and mysqlwatch.exe to the Windows distribution.
Fixed problem when doing ORDER BY on a reference key.
Fixed that INSERT DELAYED doesn’t update timestamps that are given.
D.5.8 Changes in release 3.22.28 (20 Oct 1999)
Fixed problem with LEFT JOIN and COUNT() on a column which was declared NULL +
and it had a DEFAULT value.
Fixed core dump problem when using CONCAT() inaWHERE clause.
Fixed problem with AVG() and STD() with NULL values.
D.5.9 Changes in release 3.22.27
Fixed prototype in ‘my_ctype.h’ when using other character sets.
Some configure issues to fix problems with big filesystem detection.
Fixed problem when sorting on big BLOB columns.
ROUND() will now work on Windows.
D.5.10 Changes in release 3.22.26 (16 Sep 1999)
Fixed core dump with empty BLOB/TEXT column argument to REVERSE().
Extended /*! */ with version numbers.
Changed SUBSTRING(text FROM pos) to conform to SQL-99. (Before this construct
returned the rightmost ’pos’ characters.)
Fixed problem with LOCK TABLES combined with DELETE FROM table
Fixed problem that INSERT ... SELECT didn’t use BIG_TABLES.
SET SQL_LOW_PRIORITY_UPDATES=# didn’t work.
Password wasn’t updated correctly if privileges didn’t change on: GRANT ...
IDENTIFIED BY
800 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed range optimiser bug in SELECT * FROM table_name WHERE key_part1 >= const
AND (key_part2 = const OR key_part2 = const).
Fixed bug in compression key handling in ISAM.
D.5.11 Changes in release 3.22.25
Fixed some small problems with the installation.
D.5.12 Changes in release 3.22.24 (05 Jul 1999)
DATA is no longer a reserved word.
Fixed optimiser bug with tables with only one row.
Fixed bug when using LOCK TABLES table_name READ; FLUSH TABLES;
Applied some patches for HP-UX.
isamchk should now work on Windows.
Changed ‘configure’ to not use big file handling on Linux as this crashes some Red
Hat 6.0 systems
D.5.13 Changes in release 3.22.23 (08 Jun 1999)
Upgraded to use Autoconf 2.13, Automake 1.4 and libtool 1.3.2.
Better support for SCO in configure.
Added option --defaults-file=### to option file handling to force use of only one
specific option file.
Extended CREATE syntax to ignore MySQL Version 3.23 keywords.
Fixed deadlock problem when using INSERT DELAYED on a table locked with LOCK
TABLES.
Fixed deadlock problem when using DROP TABLE on a table that was locked by another
thread.
Add logging of GRANT/REVOKE commands in the update log.
Fixed isamchk to detect a new error condition.
Fixed bug in NATURAL LEFT JOIN.
D.5.14 Changes in release 3.22.22 (30 Apr 1999)
Fixed problem in the C API when you called mysql_close() directly after mysql_
init().
Better client error message when you can’t open socket.
Fixed delayed_insert_thread counting when you couldn’t create a new delayed insert
thread.
Fixed bug in CONCAT() with many arguments.
Added patches for DEC 3.2 and SCO.
Fixed path-bug when installing MySQL as a service on NT.
The MySQL-Windows version is now compiled with VC++ 6.0 instead of with VC++
5.0.
New installation setup for MySQL-Windows.
Appendix D: MySQL Change History 801
D.5.15 Changes in release 3.22.21
Fixed problem with DELETE FROM TABLE when table was locked by another thread.
Fixed bug in LEFT JOIN involving empty tables.
Changed the mysql.db column from CHAR(32) to CHAR(60).
MODIFY and DELAYED are no longer reserved words.
Fixed a bug when storing days in a TIME column.
Fixed a problem with Host ’...’ is not allowed to connect to this MySQL server
after one had inserted a new MySQL user with a GRANT command.
Changed to use TCP_NODELAY also on Linux (should give faster TCP/IP connections).
D.5.16 Changes in release 3.22.20 (18 Mar 1999)
Fixed STD() for big tables when result should be 0.
The update log didn’t have newlines on some operating systems.
INSERT DELAYED had some garbage at end in the update log.
D.5.17 Changes in release 3.22.19 (Mar 1999: Production)
Fixed bug in mysql_install_db (from 3.22.17).
Changed default key cache size to 8M.
Fixed problem with queries that needed temporary tables with BLOB columns.
D.5.18 Changes in release 3.22.18
Fixes a fatal problem in 3.22.17 on Linux; after shutdown not all threads died properly.
Added option -O flush_time=# to mysqld. This is mostly useful on Windows and tells
how often MySQL should close all unused tables and flush all updated tables to disk.
Fixed problem that a VARCHAR column compared with CHAR column didn’t use keys
efficiently.
D.5.19 Changes in release 3.22.17
Fixed a core dump problem when using --log-update and connecting without a default
database.
Fixed some configure and portability problems.
Using LEFT JOIN on tables that had circular dependencies caused mysqld to hang for-
ever.
D.5.20 Changes in release 3.22.16 (Feb 1999: Gamma)
mysqladmin processlist could kill the server if a new user logged in.
DELETE FROM nome_tabela WHERE key_column=nome_coluna didn’t find any matching
rows. Fixed.
DATE_ADD(column, ...) didn’t work.
INSERT DELAYED could deadlock with status ’upgrading lock’
802 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Extended ENCRYPT() to take longer salt strings than 2 characters.
longlong2str is now much faster than before. For Intel x86 platforms, this function
is written in optimised assembler.
Added the MODIFY keyword to ALTER TABLE.
D.5.21 Changes in release 3.22.15
GRANT used with IDENTIFIED BY didn’t take effect until privileges were flushed.
Name change of some variables in SHOW STATUS.
Fixed problem with ORDER BY with ’only index’ optimisation when there were multiple
key definitions for a used column.
DATE and DATETIME columns are now up to 5 times faster than before.
INSERT DELAYED can be used to let the client do other things while the server inserts
rows into a table.
LEFT JOIN USING (col1,col2) didn’t work if one used it with tables from 2 different
databases.
LOAD DATA LOCAL INFILE didn’t work in the Unix version because of a missing file.
Fixed problems with VARCHAR/BLOB on very short rows (<4 bytes); error 127 could
occur when deleting rows.
Updating BLOB/TEXT through formulas didn’t work for short (<256 char) strings.
When you did a GRANT on a new host, mysqld could die on the first connect from this
host.
Fixed bug when one used ORDER BY on column name that was the same name as an
alias.
Added BENCHMARK(loop_count,expression) function to time expressions.
D.5.22 Changes in release 3.22.14
Allow empty arguments to mysqld to make it easier to start from shell scripts.
Setting a TIMESTAMP column to NULL didn’t record the timestamp value in the update
log.
Fixed lock handler bug when one did INSERT INTO TABLE ... SELECT ... GROUP BY.
Added a patch for localtime_r() on Windows so that it will no lonher crash if your
date is >2039, but instead will return a time of all zero.
Names for user-defined functions are no longer case-sensitive.
Added escape of ^Z (ASCII 26) to \Z as ^Z doesn’t work with pipes on Windows.
mysql_fix_privileges adds a new column to the mysql.func to support aggregate
UDF functions in future MySQL releases.
D.5.23 Changes in release 3.22.13
Saving NOW(),CURDATE() or CURTIME() directly in a column didn’t work.
SELECT COUNT(*) ... LEFT JOIN ... didn’t work with no WHERE part.
Updated ‘config.guess’ to allow MySQL to configure on UnixWare 7.0.x.
Appendix D: MySQL Change History 803
Changed the implementation of pthread_cond() on the Windows version. get_lock()
now correctly times out on Windows!
D.5.24 Changes in release 3.22.12
Fixed problem when using DATE_ADD() and DATE_SUB() inaWHERE clause.
You can now set the password for a user with the GRANT ... TO user IDENTIFIED BY
’password’ syntax.
Fixed bug in GRANT checking with SELECT on many tables.
Added missing file mysql_fix_privilege_tables to the RPM distribution. This is
not run by default because it relies on the client package.
Added option SQL_SMALL_RESULT to SELECT to force use of fast temporary tables when
you know that the result set will be small.
Allow use of negative real numbers without a decimal point.
Day number is now adjusted to maximum days in month if the resulting month after
DATE_ADD/DATE_SUB() doesn’t have enough days.
Fix that GRANT compares columns in case-insensitive fashion.
Fixed a bug in ‘sql_list.h’ that made ALTER TABLE dump core in some contexts.
The hostname in user@hostname can now include ‘.’ and ‘-’ without quotes in the
context of the GRANT,REVOKE and SET PASSWORD FOR ... statements.
Fix for isamchk for tables which need big temporary files.
D.5.25 Changes in release 3.22.11
Important: You must run the mysql_fix_privilege_tables script when you upgrade
to this version! This is needed because of the new GRANT system. If you don’t do this,
you will get Access denied when you try to use ALTER TABLE,CREATE INDEX, or DROP
INDEX.
GRANT to allow/deny users table and column access.
Changed USER() to return a value in user@host format. Formerly it returned only
user.
Changed the syntax for how to set PASSWORD for another user.
New command FLUSH STATUS that resets most status variables to zero.
New status variables: aborted_threads,aborted_connects.
New option variable: connection_timeout.
Added support for Thai sorting (by Pruet Boonma pruet@ds90.intanon.nectec.or.th).
Slovak and Japanese error messages.
Configuration and portability fixes.
Added option SET SQL_WARNINGS=1 to get a warning count also for simple inserts.
MySQL now uses SIGTERM instead of SIGQUIT with shutdown to work better on
FreeBSD.
Added option \G (print vertically) to mysql.
SELECT HIGH_PRIORITY ... killed mysqld.
804 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
IS NULL on a AUTO_INCREMENT column in a LEFT JOIN didn’t work as expected.
New function MAKE_SET().
D.5.26 Changes in release 3.22.10
mysql_install_db no longer starts the MySQL server! You should start mysqld with
safe_mysqld after installing it! The MySQL RPM will, however, start the server as
before.
Added --bootstrap option to mysqld and recoded mysql_install_db to use it. This
will make it easier to install MySQL with RPMs.
Changed +,-(sign and minus), *,/,%,ABS() and MOD() to be BIGINT aware (64-bit
safe).
Fixed a bug in ALTER TABLE that caused mysqld to crash.
MySQL now always reports the conflicting key values when a duplicate key entry occurs.
(Before this was only reported for INSERT.)
New syntax: INSERT INTO nome_tabela SET nome_coluna=value, nome_
coluna=value, ...
Most errors in the ‘.err’ log are now prefixed with a time stamp.
Added option MYSQL_INIT_COMMAND to mysql_options() to make a query on connect
or reconnect.
Added option MYSQL_READ_DEFAULT_FILE and MYSQL_READ_DEFAULT_GROUP to
mysql_options() to read the following parameters from the MySQL option files:
port,socket,compress,password,pipe,timeout,user,init-command,host and
database.
Added maybe_null to the UDF structure.
Added option IGNORE to INSERT statements with many rows.
Fixed some problems with sorting of the koi8 character sets; users of koi8 must run
isamchk -rq on each table that has an index on a CHAR or VARCHAR column.
New script mysql_setpermission, by Luuk de Boer. It allows easy creation of new
users with permissions for specific databases.
Allow use of hexadecimal strings (0x...) when specifying a constant string (like in the
column separators with LOAD DATA INFILE).
Ported to OS/2 (thanks to Antony T. Curtis antony.curtis@olcs.net).
Added more variables to SHOW STATUS and changed format of output to be like SHOW
VARIABLES.
Added extended-status command to mysqladmin which will show the new status
variables.
D.5.27 Changes in release 3.22.9
SET SQL_LOG_UPDATE=0 caused a lockup of the server.
New SQL command: FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]
New SQL command: KILL thread_id.
Appendix D: MySQL Change History 805
Added casts and changed include files to make MySQL easier to compile on AIX and
DEC OSF/1 4.x
Fixed conversion problem when using ALTER TABLE from a INT to a short CHAR() col-
umn.
Added SELECT HIGH_PRIORITY; this will get a lock for the SELECT even if there is a
thread waiting for another SELECT to get a WRITE LOCK.
Moved wild_compare() to string class to be able to use LIKE on BLOB/TEXT columns
with \0.
Added ESCAPE option to LIKE.
Added a lot more output to mysqladmin debug.
You can now start mysqld on Windows with the --flush option. This will flush
all tables to disk after each update. This makes things much safer on the Windows
platforms but also much slower.
D.5.28 Changes in release 3.22.8
Czech character sets should now work much better. You must also install
http://www.mysql.com/Downloads/Patches/czech-3.22.8-patch. This patch
should also be installed if you are using a character set which uses my_strcoll()!
The patch should always be safe to install (for any system), but as this patch changes
ISAM internals it’s not yet in the default distribution.
DATE_ADD() and DATE_SUB() didn’t work with group functions.
mysql will now also try to reconnect on USE DATABASE commands.
Fix problem with ORDER BY and LEFT JOIN and const tables.
Fixed problem with ORDER BY if the first ORDER BY column was a key and the rest of
the ORDER BY columns wasn’t part of the key.
Fixed a big problem with OPTIMIZE TABLE.
MySQL clients on NT will now by default first try to connect with named pipes and
after this with TCP/IP.
Fixed a problem with DROP TABLE and mysqladmin shutdown on Windows (a fatal bug
from 3.22.6).
Fixed problems with TIME columns and negative strings.
Added an extra thread signal loop on shutdown to avoid some error messages from the
client.
MySQL now uses the next available number as extension for the update log file.
Added patches for UNIXWARE 7.
D.5.29 Changes in release 3.22.7 (Sep 1998: Beta)
Added LIMIT clause for the DELETE statement.
You can now use the /*! ... */ syntax to hide MySQL-specific keywords when you
write portable code. MySQL will parse the code inside the comments as if the sur-
rounding /*! and */ comment characters didn’t exist.
806 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
OPTIMIZE TABLE nome_tabela can now be used to reclaim disk space after many
deletes. Currently, this uses ALTER TABLE to regenerate the table, but in the future it
will use an integrated isamchk for more speed.
Upgraded libtool to get the configure more portable.
Fixed slow UPDATE and DELETE operations when using DATETIME or DATE keys.
Changed optimiser to make it better at deciding when to do a full join and when using
keys.
You can now use mysqladmin proc to display information about your own threads.
Only users with the PROCESS privilege can get information about all threads. (In 4.0.2
one needs the SUPER privilege for this.)
Added handling of formats YYMMDD,YYYYMMDD,YYMMDDHHMMSS for numbers when using
DATETIME and TIMESTAMP types. (Formerly these formats only worked with strings.)
Added connect option CLIENT_IGNORE_SPACE to allow use of spaces after function
names and before ‘(’ (Powerbuilder requires this). This will make all function names
reserved words.
Added the --log-long-format option to mysqld to enable timestamps and
INSERT IDs in the update log.
Added --where option to mysqldump (patch by Jim Faucette).
The lexical analyser now uses “perfect hashing” for faster parsing of SQL statements.
D.5.30 Changes in release 3.22.6
Faster mysqldump.
For the LOAD DATA INFILE statement, you can now use the new LOCAL keyword to read
the file from the client. mysqlimport will automatically use LOCAL when importing
with the TCP/IP protocol.
Fixed small optimise problem when updating keys.
Changed makefiles to support shared libraries.
MySQL-NT can now use named pipes, which means that you can now use MySQL-NT
without having to install TCP/IP.
D.5.31 Changes in release 3.22.5
All table lock handing is changed to avoid some very subtle deadlocks when using DROP
TABLE,ALTER TABLE,DELETE FROM TABLE and mysqladmin flush-tables under heavy
usage. Changed locking code to get better handling of locks of different types.
Updated DBI to 1.00 and DBD to 1.2.0.
Added a check that the error message file contains error messages suitable for the
current version of mysqld. (To avoid errors if you accidentally try to use an old error
message file.)
All count structures in the client (affected_rows(),insert_id(), ...) are now of type
BIGINT to allow 64-bit values to be used. This required a minor change in the MySQL
protocol which should affect only old clients when using tables with AUTO_INCREMENT
values >16M.
Appendix D: MySQL Change History 807
The return type of mysql_fetch_lengths() has changed from uint * to ulong *. This
may give a warning for old clients but should work on most machines.
Change mysys and dbug libraries to allocate all thread variables in one struct. This
makes it easier to make a threaded ‘libmysql.dll’ library.
Use the result from gethostname() (instead of uname()) when constructing ‘.pid’ file
names.
New better compressed server/client protocol.
COUNT(),STD() and AVG() are extended to handle more than 4G rows.
You can now store values in the range -838:59:59 <= x <=838:59:59 in a TIME
column.
Warning: incompatible change!! If you set a TIME column to too short a value, MySQL
now assumes the value is given as: [[[D ]HH:]MM:]SS instead of HH[:MM[:SS]].
TIME_TO_SEC() and SEC_TO_TIME() can now handle negative times and hours up to
32767.
Added new option SET SQL_LOG_UPDATE={0|1} to allow users with the PROCESS
privilege to bypass the update log. (Modified patch from Sergey A Mukhin
violet@rosnet.net.)
Fixed fatal bug in LPAD().
Initialise line buffer in ‘mysql.cc’ to make BLOB reading from pipes safer.
Added -O max_connect_errors=# option to mysqld. Connect errors are now reset for
each correct connection.
Increased the default value of max_allowed_packet to 1M in mysqld.
Added --low-priority-updates option to mysqld, to give table-modifying opera-
tions (INSERT,REPLACE,UPDATE,DELETE) lower priority than retrievals. You can now
use {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... You can also use SET
SQL_LOW_PRIORITY_UPDATES={0|1} to change the priority for one thread. One side
effect is that LOW_PRIORITY is now a reserved word. :(
Add support for INSERT INTO table ... VALUES(...),(...),(...), to allow insert-
ing multiple rows with a single statement.
INSERT INTO nome_tabela is now also cached when used with LOCK TABLES. (Previ-
ously only INSERT ... SELECT and LOAD DATA INFILE were cached.)
Allow GROUP BY functions with HAVING:
mysql> SELECT col FROM table GROUP BY col HAVING COUNT(*)>0;
mysqld will now ignore trailing ‘;’ characters in queries. This is to make it easier to
migrate from some other SQL servers that require the trailing ‘;’.
Fix for corrupted fixed-format output generated by SELECT INTO OUTFILE.
Warning: incompatible change! Added Oracle GREATEST() and LEAST() functions.
You must now use these instead of the MAX() and MIN() functions to get the
largest/smallest value from a list of values. These can now handle REAL,BIGINT and
string (CHAR or VARCHAR) values.
Warning: incompatible change! DAYOFWEEK() had offset 0 for Sunday. Changed the
offset to 1.
808 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Give an error for queries that mix GROUP BY columns and fields when there is no GROUP
BY specification.
Added --vertical option to mysql, for printing results in vertical mode.
Index-only optimisation; some queries are now resolved using only indexes. Until
MySQL 4.0, this works only for numeric columns. See hundefinedi[MySQL indexes],
page hundefinedi.
Lots of new benchmarks.
A new C API chapter and lots of other improvements in the manual.
D.5.32 Changes in release 3.22.4
Added --tmpdir option to mysqld, for specifying the location of the temporary file
directory.
MySQL now automatically changes a query from an ODBC client:
SELECT ... FROM table WHERE auto_increment_column IS NULL
to:
SELECT ... FROM table WHERE auto_increment_column == LAST_INSERT_ID()
This allows some ODBC programs (Delphi, Access) to retrieve the newly inserted row
to fetch the AUTO_INCREMENT id.
DROP TABLE now waits for all users to free a table before deleting it.
Fixed small memory leak in the new connect protocol.
New functions BIN(),OCT(),HEX() and CONV() for converting between different num-
ber bases.
Added function SUBSTRING() with 2 arguments.
If you created a table with a record length smaller than 5, you couldn’t delete rows
from the table.
Added optimisation to remove const reference tables from ORDER BY and GROUP BY.
mysqld now automatically disables system locking on Linux and Windows, and for
systems that use MIT-pthreads. You can force the use of locking with the --enable-
external-locking option.
Added --console option to mysqld, to force a console window (for error messages)
when using Windows.
Fixed table locks for Windows.
Allow ‘$’ in identifiers.
Changed name of user-specific configuration file from ‘my.cnf’ to ‘.my.cnf’ (Unix only).
Added DATE_ADD() and DATE_SUB() functions.
D.5.33 Changes in release 3.22.3
Fixed a lock problem (bug in MySQL Version 3.22.1) when closing temporary tables.
Added missing mysql_ping() to the client library.
Added --compress option to all MySQL clients.
Changed byte to char in ‘mysql.h’ and ‘mysql_com.h’.
Appendix D: MySQL Change History 809
D.5.34 Changes in release 3.22.2
Searching on multiple constant keys that matched more than 30% of the rows didn’t
always use the best possible key.
New functions <<,>>,RPAD() and LPAD().
You can now save default options (like passwords) in a configuration file (‘my.cnf’).
Lots of small changes to get ORDER BY to work when no records are found when using
fields that are not in GROUP BY (MySQL extension).
Added --chroot option to mysqld, to start mysqld in a chroot environment (by Nikki
Chumakov nikkic@cityline.ru).
Trailing spaces are now ignored when comparing case-sensitive strings; this should fix
some problems with ODBC and flag 512!
Fixed a core dump bug in the range optimiser.
Added --one-thread option to mysqld, for debugging with LinuxThreads (or glibc).
(This replaces the -T32 flag)
Added DROP TABLE IF EXISTS to prevent an error from occurring if the table doesn’t
exist.
IF and EXISTS are now reserved words (they would have to be sooner or later).
Added lots of new options to mysqldump.
Server error messages are now in ‘mysqld_error.h’.
The server/client protocol now supports compression.
All bug fixes from MySQL Version 3.21.32.
D.5.35 Changes in release 3.22.1 (Jun 1998: Alpha)
Added new C API function mysql_ping().
Added new API functions mysql_init() and mysql_options(). You now MUST call
mysql_init() before you call mysql_real_connect(). You don’t have to call mysql_
init() if you only use mysql_connect().
Added mysql_options(...,MYSQL_OPT_CONNECT_TIMEOUT,...) so you can set a time-
out for connecting to a server.
Added --timeout option to mysqladmin, as a test of mysql_options().
Added AFTER column and FIRST options to ALTER TABLE ... ADD columns. This makes
it possible to add a new column at some specific location within a row in an existing
table.
WEEK() now takes an optional argument to allow handling of weeks when the week
starts on Monday (some European countries). By default, WEEK() assumes the week
starts on Sunday.
TIME columns weren’t stored properly (bug in MySQL Version 3.22.0).
UPDATE now returns information about how many rows were matched and updated,
and how many “warnings” occurred when doing the update.
Fixed incorrect result from FORMAT(-100,2).
ENUM and SET columns were compared in binary (case-sensitive) fashion; changed to be
case-insensitive.
810 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.5.36 Changes in release 3.22.0
New (backward-compatible) connect protocol that allows you to specify the database
to use when connecting, to get much faster connections to a specific database.
The mysql_real_connect() call is changed to:
mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
const char *passwd, const char *db, uint port,
const char *unix_socket, uint client_flag)
Each connection is handled by its own thread, rather than by the master accept()
thread. This fixes permanently the telnet bug that was a topic on the mail list some
time ago.
All TCP/IP connections are now checked with backward-resolution of the hostname
to get better security. mysqld now has a local hostname resolver cache so connections
should actually be faster than before, even with this feature.
A site automatically will be blocked from future connections if someone repeatedly
connects with an “improper header” (like when one uses telnet).
You can now refer to tables in different databases with references of the form nome_
tabela@db_name or db_name.nome_tabela. This makes it possible to give a user read
access to some tables and write access to others simply by keeping them in different
databases!
Added --user option to mysqld, to allow it to run as another Unix user (if it is started
as the Unix root user).
Added caching of users and access rights (for faster access rights checking)
Normal users (not anonymous ones) can change their password with mysqladmin
password ’new_password’. This uses encrypted passwords that are not logged in the
normal MySQL log!
All important string functions are now coded in assembler for x86 Linux machines.
This gives a speedup of 10% in many cases.
For tables that have many columns, the column names are now hashed for much faster
column name lookup (this will speed up some benchmark tests a lot!)
Some benchmarks are changed to get better individual timing. (Some loops were so
short that a specific test took <2 seconds. The loops have been changed to take about
20 seconds to make it easier to compare different databases. A test that took 1-2
seconds before now takes 11-24 seconds, which is much better)
Re-arranged SELECT code to handle some very specific queries involving group functions
(like COUNT(*)) without a GROUP BY but with HAVING. The following now works:
mysql> SELECT COUNT(*) as C FROM table HAVING C > 1;
Changed the protocol for field functions to be faster and avoid some calls to malloc().
Added -T32 option to mysqld, for running all queries under the main thread. This
makes it possible to debug mysqld under Linux with gdb!
Added optimisation of not_null_column IS NULL (needed for some Access queries).
Allow STRAIGHT_JOIN to be used between two tables to force the optimiser to join them
in a specific order.
Appendix D: MySQL Change History 811
String functions now return VARCHAR rather than CHAR and the column type is now
VARCHAR for fields saved as VARCHAR. This should make the MyODBC driver better, but
may break some old MySQL clients that don’t handle FIELD_TYPE_VARCHAR the same
way as FIELD_TYPE_CHAR.
CREATE INDEX and DROP INDEX are now implemented through ALTER TABLE.CREATE
TABLE is still the recommended (fast) way to create indexes.
Added --set-variable option wait_timeout to mysqld.
Added time column to mysqladmin processlist to show how long a query has taken
or how long a thread has slept.
Added lots of new variables to show variables and some new to show status.
Added new type YEAR.YEAR is stored in 1 byte with allowable values of 0, and 1901 to
2155.
Added new DATE type that is stored in 3 bytes rather than 4 bytes. All new tables are
created with the new date type if you don’t use the --old-protocol option to mysqld.
Fixed bug in record caches; for some queries, you could get Error from table
handler: # on some operating systems.
Added --enable-assembler option to configure, for x86 machines (tested on Linux
+ gcc). This will enable assembler functions for the most important string functions
for more speed!
D.6 Changes in release 3.21.x
Version 3.21 is quite old now, and should be avoided if possible. This information is kept
here for historical purposes only.
D.6.1 Changes in release 3.21.33
Fixed problem when sending SIGHUP to mysqld;mysqld core dumped when starting
from boot on some systems.
Fixed problem with losing a little memory for some connections.
DELETE FROM nome_tabela without a WHERE condition is now done the long way when
you use LOCK TABLES or if the table is in use, to avoid race conditions.
INSERT INTO TABLE (timestamp_column) VALUES (NULL); didn’t set timestamp.
D.6.2 Changes in release 3.21.32
Fixed some possible race conditions when doing many reopen/close on the same tables
under heavy load! This can happen if you execute mysqladmin refresh often. This
could in some very rare cases corrupt the header of the index file and cause error 126
or 138.
Fixed fatal bug in refresh() when running with the --skip-external-locking op-
tion. There was a “very small” time gap after a mysqladmin refresh when a table
could be corrupted if one thread updated a table while another thread did mysqladmin
refresh and another thread started a new update ont the same table before the first
thread had finished. A refresh (or --flush-tables) will now not return until all used
tables are closed!
812 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
SELECT DISTINCT with a WHERE clause that didn’t match any rows returned a row in
some contexts (bug only in 3.21.31).
GROUP BY + ORDER BY returned one empty row when no rows where found.
Fixed a bug in the range optimiser that wrote Use_count: Wrong count for ... in
the error log file.
D.6.3 Changes in release 3.21.31
Fixed a sign extension problem for the TINYINT type on Irix.
Fixed problem with LEFT("constant_string",function).
Fixed problem with FIND_IN_SET().
LEFT JOIN core dumped if the second table is used with a constant WHERE/ON expression
that uniquely identifies one record.
Fixed problems with DATE_FORMAT() and incorrect dates. DATE_FORMAT() now ignores
’%’ to make it possible to extend it more easily in the future.
D.6.4 Changes in release 3.21.30
mysql now returns an exit code >0 if the query returned an error.
Saving of command-line history to file in mysql client. By Tommy Larsen
tommy@mix.hive.no.
Fixed problem with empty lines that were ignored in ‘mysql.cc’.
Save the pid of the signal handler thread in the pid file instead of the pid of the main
thread.
Added patch by tommy@valley.ne.jp to support Japanese characters SJIS and UJIS.
Changed safe_mysqld to redirect startup messages to ’hostname’.err instead of
’hostname’.log to reclaim file space on mysqladmin refresh.
ENUM always had the first entry as default value.
ALTER TABLE wrote two entries to the update log.
sql_acc() now closes the mysql grant tables after a reload to save table space and
memory.
Changed LOAD DATA to use less memory with tables and BLOB columns.
Sorting on a function which made a division / 0 produced a wrong set in some cases.
Fixed SELECT problem with LEFT() when using the czech character set.
Fixed problem in isamchk; it couldn’t repair a packed table in a very unusual case.
SELECT statements with &or |(bit functions) failed on columns with NULL values.
When comparing a field = field, where one of the fields was a part key, only the length
of the part key was compared.
D.6.5 Changes in release 3.21.29
LOCK TABLES + DELETE from nome_tabela never removed locks properly.
Fixed problem when grouping on an OR function.
Appendix D: MySQL Change History 813
Fixed permission problem with umask() and creating new databases.
Fixed permission problem on result file with SELECT ... INTO OUTFILE ...
Fixed problem in range optimiser (core dump) for a very complex query.
Fixed problem when using MIN(integer) or MAX(integer) in GROUP BY.
Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha.)
Fixed bug in WEEK("XXXX-xx-01").
D.6.6 Changes in release 3.21.28
Fixed socket permission (clients couldn’t connect to Unix socket on Linux).
Fixed bug in record caches; for some queries, you could get Error from table
handler: # on some operating systems.
D.6.7 Changes in release 3.21.27
Added user level lock functions GET_LOCK(string,timeout),RELEASE_LOCK(string).
Added Opened_tables to show status.
Changed connect timeout to 3 seconds to make it somewhat harder for crackers to kill
mysqld through telnet +TCP/IP.
Fixed bug in range optimiser when using WHERE key_part_1 >= something AND key_
part_2 <= something_else.
Changed configure for detection of FreeBSD 3.0 9803xx and above
WHERE with string_col_key = constant_string didn’t always find all rows if the
column had many values differing only with characters of the same sort value (like e
and ´e).
Strings keys looked up with ’ref’ were not compared in case-sensitive fashion.
Added umask() to make log files non-readable for normal users.
Ignore users with old (8-byte) password on startup if not using --old-protocol option
to mysqld.
SELECT which matched all key fields returned the values in the case of the matched
values, not of the found values. (Minor problem.)
D.6.8 Changes in release 3.21.26
FROM_DAYS(0) now returns "0000-00-00".
In DATE_FORMAT(), PM and AM were swapped for hours 00 and 12.
Extended the default maximum key size to 256.
Fixed bug when using BLOB/TEXT in GROUP BY with many tables.
An ENUM field that is not declared NOT NULL has NULL as the default value. (Previously,
the default value was the first enumeration value.)
Fixed bug in the join optimiser code when using many part keys on the same key:
INDEX (Organisation,Surname(35),Initials(35)).
Added some tests to the table order optimiser to get some cases with SELECT ... FROM
many_tables much faster.
814 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Added a retry loop around accept() to possibly fix some problems on some Linux
machines.
D.6.9 Changes in release 3.21.25
Changed typedef ’string’ to typedef ’my_string’ for better portability.
You can now kill threads that are waiting on a disk-full condition.
Fixed some problems with UDF functions.
Added long options to isamchk. Try isamchk --help.
Fixed a bug when using 8 bytes long (alpha); filesort() didn’t work. Affects
DISTINCT,ORDER BY and GROUP BY on 64-bit processors.
D.6.10 Changes in release 3.21.24
Dynamic loadable functions. Based on source from Alexis Mikhailov.
You couldn’t delete from a table if no one had done a SELECT on the table.
Fixed problem with range optimiser with many OR operators on key parts inside each
other.
Recoded MIN() and MAX() to work properly with strings and HAVING.
Changed default umask value for new files from 0664 to 0660.
Fixed problem with LEFT JOIN and constant expressions in the ON part.
Added Italian error messages from brenno@dewinter.com.
configure now works better on OSF/1 (tested on 4.0D).
Added hooks to allow LIKE optimisation with international character support.
Upgraded DBI to 0.93.
D.6.11 Changes in release 3.21.23
The following symbols are now reserved words: TIME,DATE,TIMESTAMP,TEXT,BIT,
ENUM,NO,ACTION,CHECK,YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,STATUS,VARIABLES.
Setting a TIMESTAMP to NULL in LOAD DATA INFILE ... didn’t set the current time for
the TIMESTAMP.
Fix BETWEEN to recognise binary strings. Now BETWEEN is case-sensitive.
Added --skip-thread-priority option to mysqld, for systems where mysqld’s thread
scheduling doesn’t work properly (BSDI 3.1).
Added ODBC functions DAYNAME() and MONTHNAME().
Added function TIME_FORMAT(). This works like DATE_FORMAT(), but takes a time
string (’HH:MM:DD’) as argument.
Fixed unlikely(?) key optimiser bug when using ORs of key parts inside ANDs.
Added variables command to mysqladmin.
A lot of small changes to the binary releases.
Fixed a bug in the new protocol from MySQL Version 3.21.20.
Changed ALTER TABLE to work with Windows (Windows can’t rename open files). Also
fixed a couple of small bugs in the Windows version.
Appendix D: MySQL Change History 815
All standard MySQL clients are now ported to MySQL-Windows.
MySQL can now be started as a service on NT.
D.6.12 Changes in release 3.21.22
Starting with this version, all MySQL distributions will be configured, compiled and
tested with crash-me and the benchmarks on the following platforms: SunOS 5.6
sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c, SunOS 5.6 i86pc, Irix 6.3 mips5k, HP-
UX 10.20 hppa, AIX 4.2.1 ppc, OSF/1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1
i386.
Fix COUNT(*) problems when the WHERE clause didn’t match any records. (Bug from
3.21.17.)
Removed that NULL = NULL is true. Now you must use IS NULL or IS NOT NULL to test
whether a value is NULL. (This is according to SQL-99 but may break old applications
that are ported from mSQL.) You can get the old behaviour by compiling with -DmSQL_
COMPLIANT.
Fixed bug that core dumped when using many LEFT OUTER JOIN clauses.
Fixed bug in ORDER BY on string formula with possible NULL values.
Fixed problem in range optimiser when using <= on sub index.
Added functions DAYOFYEAR(),DAYOFMONTH(),MONTH(),YEAR(),WEEK(),QUARTER(),
HOUR(),MINUTE(),SECOND() and FIND_IN_SET().
Added SHOW VARIABLES command.
Added support of “long constant strings” from SQL-99:
mysql> SELECT ’first ’ ’second’; -> ’first second’
Upgraded Msql-Mysql-modules to 1.1825.
Upgraded mysqlaccess to 2.02.
Fixed problem with Russian character set and LIKE.
Ported to OpenBSD 2.1.
New Dutch error messages.
D.6.13 Changes in release 3.21.21a
Configure changes for some operating systems.
D.6.14 Changes in release 3.21.21
Fixed optimiser bug when using WHERE data_field = date_field2 AND date_field2
= constant.
Added SHOW STATUS command.
Removed ‘manual.ps’ from the source distribution to make it smaller.
D.6.15 Changes in release 3.21.20
Changed the maximum table name and column name lengths from 32 to 64.
Aliases can now be of “any” length.
816 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Fixed mysqladmin stat to return the right number of queries.
Changed protocol (downward compatible) to mark if a column has the AUTO_INCREMENT
attribute or is a TIMESTAMP. This is needed for the new Java driver.
Added Hebrew sorting order by Zeev Suraski.
Solaris 2.6: Fixed configure bugs and increased maximum table size from 2G to 4G.
D.6.16 Changes in release 3.21.19
Upgraded DBD to 1.1823. This version implements mysql_use_result in DBD-Mysql.
Benchmarks updated for empress (by Luuk).
Fixed a case of slow range searching.
Configure fixes (‘Docs’ directory).
Added function REVERSE() (by Zeev Suraski).
D.6.17 Changes in release 3.21.18
Issue error message if client C functions are called in wrong order.
Added automatic reconnect to the ‘libmysql.c’ library. If a write command fails, an
automatic reconnect is done.
Small sort sets no longer use temporary files.
Upgraded DBI to 0.91.
Fixed a couple of problems with LEFT OUTER JOIN.
Added CROSS JOIN syntax. CROSS is now a reserved word.
Recoded yacc/bison stack allocation to be even safer and to allow MySQL to handle
even bigger expressions.
Fixed a couple of problems with the update log.
ORDER BY was slow when used with key ranges.
D.6.18 Changes in release 3.21.17
Changed documentation string of --with-unix-socket-path to avoid confusion.
Added ODBC and SQL-99 style LEFT OUTER JOIN.
The following are new reserved words: LEFT,NATURAL,USING.
The client library now uses the value of the environment variable MYSQL_HOST as the
default host if it’s defined.
SELECT nome_coluna, SUM(expr) now returns NULL for nome_coluna when there are
matching rows.
Fixed problem with comparing binary strings and BLOBs with ASCII characters over
127.
Fixed lock problem: when freeing a read lock on a table with multiple read locks, a
thread waiting for a write lock would have been given the lock. This shouldn’t affect
data integrity, but could possibly make mysqld restart if one thread was reading data
that another thread modified.
Appendix D: MySQL Change History 817
LIMIT offset,count didn’t work in INSERT ... SELECT.
Optimised key block caching. This will be quicker than the old algorithm when using
bigger key caches.
D.6.19 Changes in release 3.21.16
Added ODBC 2.0 & 3.0 functions POWER(),SPACE(),COT(),DEGREES(),RADIANS(),
ROUND(2 arg) and TRUNCATE().
Warning: Incompatible change! LOCATE() parameters were swapped according to
ODBC standard. Fixed.
Added function TIME_TO_SEC().
In some cases, default values were not used for NOT NULL fields.
Timestamp wasn’t always updated properly in UPDATE SET ... statements.
Allow empty strings as default values for BLOB and TEXT, to be compatible with
mysqldump.
D.6.20 Changes in release 3.21.15
Warning: Incompatible change! mysqlperl is now from Msql-Mysql-modules. This
means that connect() now takes host,database,user,password arguments! The
old version took host,database,password,user.
Allow DATE ’1997-01-01’,TIME ’12:10:10’ and TIMESTAMP ’1997-01-01 12:10:10’
formats required by SQL-99. Warning: Incompatible change! This has the unfortunate
side-effect that you no longer can have columns named DATE,TIME or TIMESTAMP. :(
Old columns can still be accessed through tablename.columnname!)
Changed Makefiles to hopefully work better with BSD systems. Also, ‘manual.dvi
is now included in the distribution to avoid having stupid make programs trying to
rebuild it.
readline library upgraded to version 2.1.
A new sortorder german-1. That is a normal ISO-Latin1 with a german sort order.
Perl DBI/DBD is now included in the distribution. DBI is now the recommended way to
connect to MySQL from Perl.
New portable benchmark suite with DBD, with test results from mSQL 2.0.3, MySQL,
PostgreSQL 6.2.1 and Solid server 2.2.
crash-me is now included with the benchmarks; this is a Perl program designed to find
as many limits as possible in a SQL server. Tested with mSQL, PostgreSQL, Solid and
MySQL.
Fixed bug in range-optimiser that crashed MySQL on some queries.
Table and column name completion for mysql command-line tool, by Zeev Suraski and
Andi Gutmans.
Added new command REPLACE that works like INSERT but replaces conflicting records
with the new record. REPLACE INTO TABLE ... SELECT ... works also.
Added new commands CREATE DATABASE db_name and DROP DATABASE db_name.
Added RENAME option to ALTER TABLE:ALTER TABLE name RENAME TO new_name.
818 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
make_binary_distribution now includes ‘libgcc.a’ in ‘libmysqlclient.a’. This
should make linking work for people who don’t have gcc.
Changed net_write() to my_net_write() because of a name conflict with Sybase.
New function DAYOFWEEK() compatible with ODBC.
Stack checking and bison memory overrun checking to make MySQL safer with weird
queries.
D.6.21 Changes in release 3.21.14b
Fixed a couple of small configure problems on some platforms.
D.6.22 Changes in release 3.21.14a
Ported to SCO Openserver 5.0.4 with FSU Pthreads.
HP-UX 10.20 should work.
Added new function DATE_FORMAT().
Added NOT IN.
Added automatic removal of ’ODBC function conversions’: {fn now() }
Handle ODBC 2.50.3 option flags.
Fixed comparison of DATE and TIME values with NULL.
Changed language name from germany to german to be consistent with the other
language names.
Fixed sorting problem on functions returning a FLOAT. Previously, the values were
converted to INTs before sorting.
Fixed slow sorting when sorting on key field when using key_column=constant.
Sorting on calculated DOUBLE values sorted on integer results instead.
mysql no longer requires a database argument.
Changed the place where HAVING should be. According to the SQL standards, it should
be after GROUP BY but before ORDER BY. MySQL Version 3.20 incorrectly had it last.
Added Sybase command USE DATABASE to start using another database.
Added automatic adjusting of number of connections and table cache size if the maxi-
mum number of files that can be opened is less than needed. This should fix that mysqld
doesn’t crash even if you haven’t done a ulimit -n 256 before starting mysqld.
Added lots of limit checks to make it safer when running with too little memory or
when doing weird queries.
D.6.23 Changes in release 3.21.13
Added retry of interrupted reads and clearing of errno. This makes Linux systems
much safer!
Fixed locking bug when using many aliases on the same table in the same SELECT.
Fixed bug with LIKE on number key.
New error message so you can check whether the connection was lost while the command
was running or whether the connection was down from the start.
Appendix D: MySQL Change History 819
Added --table option to mysql to print in table format. Moved time and row infor-
mation after query result. Added automatic reconnect of lost connections.
Added != as a synonym for <>.
Added function VERSION() to make easier logs.
New multi-user test ‘tests/fork_test.pl’ to put some strain on the thread library.
D.6.24 Changes in release 3.21.12
Fixed ftruncate() call in MIT-pthreads. This made isamchk destroy the ‘.ISM’ files
on (Free)BSD 2.x systems.
Fixed broken __P_ patch in MIT-pthreads.
Many memory overrun checks. All string functions now return NULL if the returned
string should be longer than max_allowed_packet bytes.
Changed the name of the INTERVAL type to ENUM, because INTERVAL is used in SQL-99.
In some cases, doing a JOIN + GROUP + INTO OUTFILE, the result wasn’t grouped.
LIKE with ’_’ as last character didn’t work. Fixed.
Added extended SQL-99 TRIM() function.
Added CURTIME().
Added ENCRYPT() function by Zeev Suraski.
Fixed better FOREIGN KEY syntax skipping. New reserved words: MATCH,FULL,
PARTIAL.
mysqld now allows IP number and hostname for the --bind-address option.
Added SET CHARACTER SET cp1251_koi8 to enable conversions of data to and from the
cp1251_koi8 character set.
Lots of changes for Windows 95 port. In theory, this version should now be easily
portable to Windows 95.
Changed the CREATE COLUMN syntax of NOT NULL columns to be after the DEFAULT value,
as specified in the SQL-99 standard. This will make mysqldump with NOT NULL and
default values incompatible with MySQL Version 3.20.
Added many function name aliases so the functions can be used with ODBC or SQL-92
syntax.
Fixed syntax of ALTER TABLE nome_tabela ALTER COLUMN nome_coluna SET DEFAULT
NULL.
Added CHAR and BIT as synonyms for CHAR(1).
Fixed core dump when updating as a user who has only SELECT privilege.
INSERT ... SELECT ... GROUP BY didn’t work in some cases. An Invalid use of
group function error occurred.
When using LIMIT,SELECT now always uses keys instead of record scan. This will give
better performance on SELECT and a WHERE that matches many rows.
Added Russian error messages.
820 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.6.25 Changes in release 3.21.11
Configure changes.
MySQL now works with the new thread library on BSD/OS 3.0.
Added new group functions BIT_OR() and BIT_AND().
Added compatibility functions CHECK and REFERENCES.CHECK is now a reserved word.
Added ALL option to GRANT for better compatibility. (GRANT is still a dummy function.)
Added partly-translated Dutch error messages.
Fixed bug in ORDER BY and GROUP BY with NULL columns.
Added function LAST_INSERT_ID() SQL function to retrieve last AUTO_INCREMENT
value. This is intended for clients to ODBC that can’t use the mysql_insert_id()
API function, but can be used by any client.
Added --flush-logs option to mysqladmin.
Added command STATUS to mysql.
Fixed problem with ORDER BY/GROUP BY because of bug in gcc.
Fixed problem with INSERT ... SELECT ... GROUP BY.
D.6.26 Changes in release 3.21.10
New mysqlaccess.
CREATE now supports all ODBC types and the mSQL TEXT type. All ODBC 2.5 functions
are also supported (added REPEAT). This provides better portability.
Added text types TINYTEXT,TEXT,MEDIUMTEXT and LONGTEXT. These are actually
BLOBtypes, but all searching is done in case-insensitive fashion.
All old BLOB fields are now TEXT fields. This only changes that all searching on strings
is done in case-sensitive fashion. You must do an ALTER TABLE and change the data
type to BLOB if you want to have tests done in case-sensitive fashion.
Fixed some configure issues.
Made the locking code a bit safer. Fixed very unlikely deadlock situation.
Fixed a couple of bugs in the range optimiser. Now the new range benchmark test-
select works.
D.6.27 Changes in release 3.21.9
Added --enable-unix-socket=pathname option to configure.
Fixed a couple of portability problems with include files.
Fixed bug in range calculation that could return empty set when searching on multiple
key with only one entry (very rare).
Most things ported to FSU Pthreads, which should allow MySQL to run on Caldera
(SCO). See hundefinedi[Caldera], page hundefinedi.
D.6.28 Changes in release 3.21.8
Works now in Solaris 2.6.
Appendix D: MySQL Change History 821
Added handling of calculation of SUM() functions. For example, you can now use
SUM(column)/COUNT(column).
Added handling of trigometric functions: PI(),ACOS(),ASIN(),ATAN(),COS(),SIN()
and TAN().
New languages: Norwegian, Norwegian-ny and Portuguese.
Fixed parameter bug in net_print() in ‘procedure.cc’.
Fixed a couple of memory leaks.
Now allow also the old SELECT ... INTO OUTFILE syntax.
Fixed bug with GROUP BY and SELECT on key with many values.
mysql_fetch_lengths() sometimes returned incorrect lengths when you used mysql_
use_result(). This affected at least some cases of mysqldump --quick.
Fixed bug in optimisation of WHERE const op field.
Fixed problem when sorting on NULL fields.
Fixed a couple of 64-bit (Alpha) problems.
Added --pid-file=# option to mysqld.
Added date formatting to FROM_UNIXTIME(), originally by Zeev Suraski.
Fixed bug in BETWEEN in range optimiser (did only test = of the first argument).
Added machine-dependent files for MIT-pthreads i386-SCO. There is probably more
to do to get this to work on SCO 3.5.
D.6.29 Changes in release 3.21.7
Changed ‘Makefile.am’ to take advantage of Automake 1.2.
Added the beginnings of a benchmark suite.
Added more secure password handling.
Added new client function mysql_errno(), to get the error number of the error mes-
sage. This makes error checking in the client much easier. This makes the new server
incompatible with the 3.20.x server when running without --old-protocol. The client
code is backward-compatible. More information can be found in the ‘README’ file!
Fixed some problems when using very long, illegal names.
D.6.30 Changes in release 3.21.6
Fixed more portability issues (incorrect sigwait and sigset defines).
configure should now be able to detect the last argument to accept().
D.6.31 Changes in release 3.21.5
Should now work with FreeBSD 3.0 if used with ‘FreeBSD-3.0-libc_r-1.0.diff’,
which can be found at http://www.mysql.com/downloads/patches.html.
Added new -O tmp_table_size=# option to mysqld.
New function FROM_UNIXTIME(timestamp) which returns a date string in ’YYYY-MM-DD
HH:MM:DD’ format.
New function SEC_TO_TIME(seconds) which returns a string in ’HH:MM:SS’ format.
New function SUBSTRING_INDEX(), originally by Zeev Suraski.
822 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.6.32 Changes in release 3.21.4
Should now configure and compile on OSF/1 4.0 with the DEC compiler.
Configuration and compilation on BSD/OS 3.0 works, but due to some bugs in BSD/OS
3.0, mysqld doesn’t work on it yet.
Configuration and compilation on FreeBSD 3.0 works, but I couldn’t get pthread_
create to work.
D.6.33 Changes in release 3.21.3
Added reverse check lookup of hostnames to get better security.
Fixed some possible buffer overflows if filenames that are too long are used.
mysqld doesn’t accept hostnames that start with digits followed by a ’.’, because the
hostname may look like an IP number.
Added --skip-networking option to mysqld, to allow only socket connections. (This
will not work with MIT-pthreads!)
Added check of too long table names for alias.
Added check if database name is okay.
Added check if too long table names.
Removed incorrect free() that killed the server on CREATE DATABASE or DROP
DATABASE.
Changed some mysqld -O options to better names.
Added -O join_cache_size=# option to mysqld.
Added -O max_join_size=# option to mysqld, to be able to set a limit how big queries
(in this case big = slow) one should be able to handle without specifying SET SQL_BIG_
SELECTS=1. A # = is about 10 examined records. The default is “unlimited”.
When comparing a TIME,DATE,DATETIME or TIMESTAMP column to a constant, the
constant is converted to a time value before performing the comparison. This will
make it easier to get ODBC (particularly Access97) to work with the above types. It
should also make dates easier to use and the comparisons should be quicker than before.
Applied patch from Jochen Wiedmann that allows query() in mysqlperl to take a
query with \0 in it.
Storing a timestamp with a 2-digit year (YYMMDD) didn’t work.
Fix that timestamp wasn’t automatically updated if set in an UPDATE clause.
Now the automatic timestamp field is the FIRST timestamp field.
SELECT * INTO OUTFILE, which didn’t correctly if the outfile already existed.
mysql now shows the thread ID when starting or doing a reconnect.
Changed the default sort buffer size from 2M to 1M.
D.6.34 Changes in release 3.21.2
The range optimiser is coded, but only 85% tested. It can be enabled with --new, but
it crashes core a lot yet...
Appendix D: MySQL Change History 823
More portable. Should compile on AIX and alpha-digital. At least the isam library
should be relatively 64-bit clean.
New isamchk which can detect and fix more problems.
New options for isamlog.
Using new version of Automake.
Many small portability changes (from the AIX and alpha-digital port) Better checking
of pthread(s) library.
czech error messages by snajdr@pvt.net.
Decreased size of some buffers to get fewer problems on systems with little memory.
Also added more checks to handle “out of memory” problems.
mysqladmin: you can now do mysqladmin kill 5,6,7,8 to kill multiple threads.
When the maximum connection limit is reached, one extra connection by a user with
the process acl privilege is granted.
Added -O backlog=# option to mysqld.
Increased maximum packet size from 512K to 1024K for client.
Almost all of the function code is now tested in the internal test suite.
ALTER TABLE now returns warnings from field conversions.
Port changed to 3306 (got it reserved from ISI).
Added a fix for Visual FoxBase so that any schema name from a table specification is
automatically removed.
New function ASCII().
Removed function BETWEEN(a,b,c). Use the standard SQL syntax instead: expr
BETWEEN expr AND expr.
MySQL no longer has to use an extra temporary table when sorting on functions or
SUM() functions.
Fixed bug that you couldn’t use nome_tabela.field_name in UPDATE.
Fixed SELECT DISTINCT when using ’hidden group’. For example:
mysql> SELECT DISTINCT MOD(some_field,10) FROM test
-> GROUP BY some_field;
Note: some_field is normally in the SELECT part. Standard SQL should require it.
D.6.35 Changes in release 3.21.0
New reserved words used: INTERVAL,EXPLAIN,READ,WRITE,BINARY.
Added ODBC function CHAR(num,...).
New operator IN. This uses a binary search to find a match.
New command LOCK TABLES nome_tabela [AS alias] {READ|WRITE} ...
Added --log-update option to mysqld, to get a log suitable for incremental updates.
New command EXPLAIN SELECT ... to get information about how the optimiser will
do the join.
824 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
For easier client code, the client should no longer use FIELD_TYPE_TINY_BLOB,FIELD_
TYPE_MEDIUM_BLOB,FIELD_TYPE_LONG_BLOB or FIELD_TYPE_VAR_STRING (as previ-
ously returned by mysql_list_fields). You should instead only use FIELD_TYPE_
BLOB or FIELD_TYPE_STRING. If you want exact types, you should use the command
SHOW FIELDS.
Added varbinary syntax: 0x###### which can be used as a string (default) or a number.
FIELD_TYPE_CHAR is renamed to FIELD_TYPE_TINY.
Changed all fields to C++ classes.
Removed FORM struct.
Fields with DEFAULT values no longer need to be NOT NULL.
New field types:
ENUM A string which can take only a couple of defined values. The value is stored
as a 1-3 byte number that is mapped automatically to a string. This is
sorted according to string positions!
SET A string which may have one or many string values separated with ’,’. The
string is stored as a 1-, 2-, 3-, 4- or 8-byte number where each bit stands
for a specific set member. This is sorted according to the unsigned value
of the stored packed number.
Now all function calculation is done with double or long long. This will provide
the full 64-bit range with bit functions and fix some conversions that previously could
result in precision losses. One should avoid using unsigned long long columns with
full 64-bit range (numbers bigger than 9223372036854775807) because calculations are
done with signed long long.
ORDER BY will now put NULL field values first. GROUP BY will also work with NULL values.
Full WHERE with expressions.
New range optimiser that can resolve ranges when some keypart prefix is constant.
Example:
mysql> SELECT * FROM nome_tabela
-> WHERE key_part_1="customer"
-> AND key_part_2>=10 AND key_part_2<=10;
D.7 Changes in release 3.20.x
Version 3.20 is quite old now, and should be avoided if possible. This information is kept
here for historical purposes only.
Changes from 3.20.18 to 3.20.32b are not documented here because the 3.21 release branched
here. And the relevant changes are also documented as changes to the 3.21 version.
D.7.1 Changes in release 3.20.18
Added -p# (remove #directories from path) to isamlog. All files are written with a
relative path from the database directory Now mysqld shouldn’t crash on shutdown
when using the --log-isam option.
New mysqlperl version. It is now compatible with msqlperl-0.63.
Appendix D: MySQL Change History 825
New DBD module available.
Added group function STD() (standard deviation).
The mysqld server is now compiled by default without debugging information. This
will make the daemon smaller and faster.
Now one usually only has to specify the --basedir option to mysqld. All other paths
are relative in a normal installation.
BLOB columns sometimes contained garbage when used with a SELECT on more than
one table and ORDER BY.
Fixed that calculations that are not in GROUP BY work as expected (SQL-99 extension).
Example:
mysql> SELECT id,id+1 FROM table GROUP BY id;
The test of using MYSQL_PWD was reversed. Now MYSQL_PWD is enabled as default in the
default release.
Fixed conversion bug which caused mysqld to core dump with Arithmetic error on
SPARC-386.
Added --unbuffered option to mysql, for new mysqlaccess.
When using overlapping (unnecessary) keys and join over many tables, the optimiser
could get confused and return 0 records.
D.7.2 Changes in release 3.20.17
You can now use BLOB columns and the functions IS NULL and IS NOT NULL in the
WHERE clause.
All communication packets and row buffers are now allocated dynamically on demand.
The default value of max_allowed_packet is now 64K for the server and 512K for the
client. This is mainly used to catch incorrect packets that could trash all memory. The
server limit may be changed when it is started.
Changed stack usage to use less memory.
Changed safe_mysqld to check for running daemon.
The ELT() function is renamed to FIELD(). The new ELT() function returns a value
based on an index: FIELD() is the inverse of ELT() Example: ELT(2,"A","B","C")
returns "B".FIELD("B","A","B","C") returns 2.
COUNT(field), where field could have a NULL value, now works.
A couple of bugs fixed in SELECT ... GROUP BY.
Fixed memory overrun bug in WHERE with many unoptimisable brace levels.
Fixed some small bugs in the grant code.
If hostname isn’t found by get_hostname, only the IP is checked. Previously, you got
Access denied.
Inserts of timestamps with values didn’t always work.
INSERT INTO ... SELECT ... WHERE could give the error Duplicated field.
Added some tests to safe_mysqld to make it “safer”.
LIKE was case-sensitive in some places and case-insensitive in others. Now LIKE is
always case-insensitive.
826 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
mysql.cc’: Allow ’#’ anywhere on the line.
New command SET SQL_SELECT_LIMIT=#. See the FAQ for more details.
New version of the mysqlaccess script.
Change FROM_DAYS() and WEEKDAY() to also take a full TIMESTAMP or DATETIME as
argument. Before they only took a number of type YYYYMMDD or YYMMDD.
Added new function UNIX_TIMESTAMP(timestamp_column).
D.7.3 Changes in release 3.20.16
More changes in MIT-pthreads to get them safer. Fixed also some link bugs at least
in SunOS.
Changed mysqld to work around a bug in MIT-pthreads. This makes multiple small
SELECT operations 20 times faster. Now lock_test.pl should work.
Added mysql_FetchHash(handle) to mysqlperl.
The mysqlbug script is now distributed built to allow for reporting bugs that appear
during the build with it.
Changed ‘libmysql.c’ to prefer getpwuid() instead of cuserid().
Fixed bug in SELECT optimiser when using many tables with the same column used as
key to different tables.
Added new latin2 and Russian KOI8 character tables.
Added support for a dummy GRANT command to satisfy Powerbuilder.
D.7.4 Changes in release 3.20.15
Fixed fatal bug packets out of order when using MIT-pthreads.
Removed possible loop when a thread waits for command from client and fcntl() fails.
Thanks to Mike Bretz for finding this bug.
Changed alarm loop in ‘mysqld.cc’ because shutdown didn’t always succeed in Linux.
Removed use of termbits from ‘mysql.cc’. This conflicted with glibc 2.0.
Fixed some syntax errors for at least BSD and Linux.
Fixed bug when doing a SELECT as superuser without a database.
Fixed bug when doing SELECT with group calculation to outfile.
D.7.5 Changes in release 3.20.14
If one gives -p or --password option to mysql without an argument, the user is solicited
for the password from the tty.
Added default password from MYSQL_PWD (by Elmar Haneke).
Added command kill to mysqladmin to kill a specific MySQL thread.
Sometimes when doing a reconnect on a down connection this succeeded first on second
try.
Fixed adding an AUTO_INCREMENT key with ALTER_TABLE.
AVG() gave too small value on some SELECTs with GROUP BY and ORDER BY.
Appendix D: MySQL Change History 827
Added new DATETIME type (by Giovanni Maruzzelli maruzz@matrice.it).
Fixed that defining DONT_USE_DEFAULT_FIELDS works.
Changed to use a thread to handle alarms instead of signals on Solaris to avoid race
conditions.
Fixed default length of signed numbers. (George Harvey georgeh@pinacl.co.uk.)
Allow anything for CREATE INDEX.
Add prezeros when packing numbers to DATE,TIME and TIMESTAMP.
Fixed a bug in OR of multiple tables (gave empty set).
Added many patches to MIT-pthreads. This fixes at least one lookup bug.
D.7.6 Changes in release 3.20.13
Added standard SQL-92 DATE and TIME types.
Fixed bug in SELECT with AND-OR levels.
Added support for Slovenian characters. The ‘Contrib’ directory contains source and
instructions for adding other character sets.
Fixed bug with LIMIT and ORDER BY.
Allow ORDER BY and GROUP BY on items that aren’t in the SELECT list. (Thanks to Wim
Bonis bonis@kiss.de, for pointing this out.)
Allow setting of timestamp values in INSERT.
Fixed bug with SELECT ... WHERE ... = NULL.
Added changes for glibc 2.0. To get glibc to work, you should add the ‘gibc-2.0-
sigwait-patch’ before compiling glibc.
Fixed bug in ALTER TABLE when changing a NOT NULL field to allow NULL values.
Added some SQL-92 synonyms as field types to CREATE TABLE.CREATE TABLE now
allows FLOAT(4) and FLOAT(8) to mean FLOAT and DOUBLE.
New utility program mysqlaccess by Yves.Carlier@rug.ac.be. This program shows
the access rights for a specific user and the grant rows that determine this grant.
Added WHERE const op field (by bonis@kiss.de).
D.7.7 Changes in release 3.20.11
When using SELECT ... INTO OUTFILE, all temporary tables are ISAM instead of
HEAP to allow big dumps.
Changed date functions to be string functions. This fixed some “funny” side effects
when sorting on dates.
Extended ALTER TABLE for SQL-92 compliance.
Some minor compatibility changes.
Added --port and --socket options to all utility programs and mysqld.
Fixed MIT-pthreads readdir_r(). Now mysqladmin create database and
mysqladmin drop database should work.
Changed MIT-pthreads to use our tempnam(). This should fix the “sort aborted” bug.
Added sync of records count in sql_update. This fixed slow updates on first connection.
(Thanks to Vaclav Bittner for the test.)
828 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.7.8 Changes in release 3.20.10
New insert type: INSERT INTO ... SELECT ...
MEDIUMBLOB fixed.
Fixed bug in ALTER TABLE and BLOBs.
SELECT ... INTO OUTFILE now creates the file in the current database directory.
DROP TABLE now can take a list of tables.
Oracle synonym DESCRIBE (DESC).
Changes to make_binary_distribution.
Added some comments to installation instructions about configure’s C++ link test.
Added --without-perl option to configure.
Lots of small portability changes.
D.7.9 Changes in release 3.20.9
ALTER TABLE didn’t copy null bit. As a result, fields that were allowed to have NULL
values were always NULL.
CREATE didn’t take numbers as DEFAULT.
Some compatibility changes for SunOS.
Removed ‘config.cache’ from old distribution.
D.7.10 Changes in release 3.20.8
Fixed bug with ALTER TABLE and multi-part keys.
D.7.11 Changes in release 3.20.7
New commands: ALTER TABLE,SELECT ... INTO OUTFILE and LOAD DATA INFILE.
New function: NOW().
Added new field File_priv to mysql/user table.
New script add_file_priv which adds the new field File_priv to the user table.
This script must be executed if you want to use the new SELECT ... INTO and LOAD
DATA INFILE ... commands with a version of MySQL earlier than 3.20.7.
Fixed bug in locking code, which made lock_test.pl test fail.
New files ‘NEW’ and ‘BUGS’.
Changed ‘select_test.c’ and ‘insert_test.c’ to include ‘config.h’.
Added status command to mysqladmin for short logging.
Increased maximum number of keys to 16 and maximum number of key parts to 15.
Use of sub keys. A key may now be a prefix of a string field.
Added -k option to mysqlshow, to get key information for a table.
Added long options to mysqldump.
Appendix D: MySQL Change History 829
D.7.12 Changes in release 3.20.6
Portable to more systems because of MIT-pthreads, which will be used automatically
if configure cannot find a -lpthreads library.
Added GNU-style long options to almost all programs. Test with program --help.
Some shared library support for Linux.
The FAQ is now in ‘.texi’ format and is available in ‘.html’, ‘.txt’ and ‘.ps’ formats.
Added new SQL function RAND([init]).
Changed sql_lex to handle \0 unquoted, but the client can’t send the query through
the C API, because it takes a str pointer. You must use mysql_real_query() to send
the query.
Added API function mysql_get_client_info().
mysqld now uses the N_MAX_KEY_LENGTH from ‘nisam.h’ as the maximum allowable
key length.
The following now works:
mysql> SELECT filter_nr,filter_nr FROM filter ORDER BY filter_nr;
Previously, this resulted in the error: Column: ’filter_nr’ in order clause is
ambiguous.
mysql now outputs ’\0’,’\t’,’\n’ and ’\\’ when encountering ASCII 0, tab, new-
line or ’\’ while writing tab-separated output. This is to allow printing of binary data
in a portable format. To get the old behaviour, use -r (or --raw).
Added german error messages (60 of 80 error messages translated).
Added new API function mysql_fetch_lengths(MYSQL_RES *), which returns an ar-
ray of column lengths (of type uint).
Fixed bug with IS NULL in WHERE clause.
Changed the optimiser a little to get better results when searching on a key part.
Added SELECT option STRAIGHT_JOIN to tell the optimiser that it should join tables in
the given order.
Added support for comments starting with ’--’ in ‘mysql.cc’ (Postgres syntax).
You can have SELECT expressions and table columns in a SELECT which are not used
in the group part. This makes it efficient to implement lookups. The column that is
used should be a constant for each group because the value is calculated only once for
the first row that is found for a group.
mysql> SELECT id,lookup.text,SUM(*) FROM test,lookup
-> WHERE test.id=lookup.id GROUP BY id;
Fixed bug in SUM(function) (could cause a core dump).
Changed AUTO_INCREMENT placement in the SQL query:
INSERT INTO table (auto_field) VALUES (0);
inserted 0, but it should insert an AUTO_INCREMENT value.
mysqlshow.c’: Added number of records in table. Had to change the client code a
little to fix this.
mysql now allows doubled ’’ or "" within strings for embedded or ".
New math functions: EXP(),LOG(),SQRT(),ROUND(),CEILING().
830 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.7.13 Changes in release 3.20.3
The configure source now compiles a thread-free client library -lmysqlclient. This
is the only library that needs to be linked with client applications. When using the
binary releases, you must link with -lmysql -lmysys -ldbug -lmystrings as before.
New readline library from bash-2.0.
LOTS of small changes to configure and makefiles (and related source).
It should now be possible to compile in another directory using VPATH. Tested with
GNU Make 3.75.
safe_mysqld and mysql.server changed to be more compatible between the source
and the binary releases.
LIMIT now takes one or two numeric arguments. If one argument is given, it indicates
the maximum number of rows in a result. If two arguments are given, the first argument
indicates the offset of the first row to return, the second is the maximum number of rows.
With this it’s easy to do a poor man’s next page/previous page WWW application.
Changed name of SQL function FIELDS() to ELT(). Changed SQL function
INTERVALL() to INTERVAL().
Made SHOW COLUMNS a synonym for SHOW FIELDS. Added compatibility syntax FRIEND
KEY to CREATE TABLE. In MySQL, this creates a non-unique key on the given columns.
Added CREATE INDEX and DROP INDEX as compatibility functions. In MySQL, CREATE
INDEX only checks if the index exists and issues an error if it doesn’t exist. DROP INDEX
always succeeds.
mysqladmin.c’: added client version to version information.
Fixed core dump bug in sql_acl (core on new connection).
Removed host,user and db tables from database test in the distribution.
FIELD_TYPE_CHAR can now be signed (-128 to 127) or unsigned (0 to 255) Previously,
it was always unsigned.
Bug fixes in CONCAT() and WEEKDAY().
Changed a lot of source to get mysqld to be compiled with SunPro compiler.
SQL functions must now have a ’(’ immediately after the function name (no interven-
ing space). For example, ’USER(’ is regarded as beginning a function call, and ’USER
(’ is regarded as an identifier USER followed by a ’(’, not as a function call.
D.7.14 Changes in release 3.20.0
The source distribution is done with configure and Automake. It will make porting
much easier. The readline library is included in the distribution.
Separate client compilation: the client code should be very easy to compile on systems
which don’t have threads.
The old Perl interface code is automatically compiled and installed. Automatic com-
piling of DBD will follow when the new DBD code is ported.
Dynamic language support: mysqld can now be started with Swedish or English (de-
fault) error messages.
New functions: INSERT(),RTRIM(),LTRIM() and FORMAT().
Appendix D: MySQL Change History 831
mysqldump now works correctly for all field types (even AUTO_INCREMENT). The format
for SHOW FIELDS FROM nome_tabela is changed so the Type column contains informa-
tion suitable for CREATE TABLE. In previous releases, some CREATE TABLE information
had to be patched when re-creating tables.
Some parser bugs from 3.19.5 (BLOB and TIMESTAMP) are corrected. TIMESTAMP now
returns different date information depending on its create length.
Changed parser to allow a database, table or field name to start with a number or ’_’.
All old C code from Unireg changed to C++ and cleaned up. This makes the daemon
a little smaller and easier to understand.
A lot of small bug fixes done.
New ‘INSTALL’ files (not final version) and some information regarding porting.
D.8 Changes in release 3.19.x
Version 3.19 is quite old now, and should be avoided if possible. This information is kept
here for historical purposes only.
D.8.1 Changes in release 3.19.5
Some new functions, some more optimisation on joins.
Should now compile clean on Linux (2.0.x).
Added functions DATABASE(),USER(),POW(),LOG10() (needed for ODBC).
In a WHERE with an ORDER BY on fields from only one table, the table is now preferred
as first table in a multi-join.
HAVING and IS NULL or IS NOT NULL now works.
A group on one column and a sort on a group function (SUM(),AVG()...) didn’t work
together. Fixed.
mysqldump: Didn’t send password to server.
D.8.2 Changes in release 3.19.4
Fixed horrible locking bug when inserting in one thread and reading in another thread.
Fixed one-off decimal bug. 1.00 was output as 1.0.
Added attribute ’Locked’ to process list as info if a query is locked by another query.
Fixed full magic timestamp. Timestamp length may now be 14, 12, 10, 8, 6, 4 or 2
bytes.
Sort on some numeric functions could sort incorrectly on last number.
IF(arg,syntax_error,syntax_error) crashed.
Added functions CEILING(),ROUND(),EXP(),LOG() and SQRT().
Enhanced BETWEEN to handle strings.
832 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
D.8.3 Changes in release 3.19.3
Fixed SELECT with grouping on BLOB columns not to return incorrect BLOB info. Group-
ing, sorting and distinct on BLOB columns will not yet work as expected (probably it
will group/sort by the first 7 characters in the BLOB). Grouping on formulas with a
fixed string size (use MID() on a BLOB) should work.
When doing a full join (no direct keys) on multiple tables with BLOB fields, the BLOB
was garbage on output.
Fixed DISTINCT with calculated columns.
Appendix E: Porting to Other Systems 833
Appendix E Porting to Other Systems
This appendix will help you port MySQL to other operating systems. Do check the list of
currently supported operating systems first. See hundefinedi[Which OS], page hundefinedi.
If you have created a new port of MySQL, please let us know so that we can list it here and
on our web site (http://www.mysql.com/), recommending it to other users.
Note: If you create a new port of MySQL, you are free to copy and distribute it under the
GPL license, but it does not make you a copyright holder of MySQL.
A working Posix thread library is needed for the server. On Solaris 2.5 we use Sun PThreads
(the native thread support in 2.4 and earlier versions is not good enough), on Linux we use
LinuxThreads by Xavier Leroy, Xavier.Leroy@inria.fr.
The hard part of porting to a new Unix variant without good native thread support is
probably to port MIT-pthreads. See ‘mit-pthreads/README’ and Programming POSIX
Threads (http://www.humanfactor.com/pthreads/).
Up to MySQL 4.0.2, the MySQL distribution included a patched version of
Chris Provenzano’s Pthreads from MIT (see the MIT Pthreads web page at
http://www.mit.edu/afs/sipb/project/pthreads/ and a programming introduction at
http://www.mit.edu:8001/people/proven/IAP_2000/). These can be used for some
operating systems that do not have POSIX threads. See pthreads-snt [MIT-pthreads],
page pthreads-pg.
It is also possible to use another user level thread package named FSU Pthreads (see
http://moss.csc.ncsu.edu/~mueller/pthreads/). This implementation is being used
for the SCO port.
See the ‘thr_lock.c’ and ‘thr_alarm.c’ programs in the ‘mysys’ directory for some
tests/examples of these problems.
Both the server and the client need a working C++ compiler. We use gcc on many platforms.
Other compilers that are known to work are SPARCworks, Sun Forte, Irix cc, HP-UX aCC,
IBM AIX xlC_r), Intel ecc and Compaq cxx).
To compile only the client use ./configure --without-server.
There is currently no support for only compiling the server, nor is it likly to be added unless
someone has a good reason for it.
If you want/need to change any ‘Makefile’ or the configure script you will also need GNU
Automake and Autoconf. See hundefinedi[Installing source tree], page hundefinedi.
All steps needed to remake everything from the most basic files.
/bin/rm */.deps/*.P
/bin/rm -f config.cache
aclocal
autoheader
aclocal
automake
autoconf
./configure --with-debug=full --prefix=’your installation directory’
# The makefiles generated above need GNU make 3.75 or newer.
# (called gmake below)
834 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
gmake clean all install init-db
If you run into problems with a new port, you may have to do some debugging of MySQL!
See hundefinedi[Debugging server], page hundefinedi.
Note: before you start debugging mysqld, first get the test programs mysys/thr_alarm and
mysys/thr_lock to work. This will ensure that your thread installation has even a remote
chance to work!
E.1 Debugging a MySQL server
If you are using some functionality that is very new in MySQL, you can try to run mysqld
with the --skip-new (which will disable all new, potentially unsafe functionality) or with
--safe-mode which disables a lot of optimisation that may cause problems. See hundefinedi
[Crashing], page hundefinedi.
If mysqld doesn’t want to start, you should check that you don’t have any ‘my.cnf’ files
that interfere with your setup! You can check your ‘my.cnf’ arguments with mysqld --
print-defaults and avoid using them by starting with mysqld --no-defaults ....
If mysqld starts to eat up CPU or memory or if it “hangs”, you can use mysqladmin
processlist status to find out if someone is executing a query that takes a long time. It
may be a good idea to run mysqladmin -i10 processlist status in some window if you
are experiencing performance problems or problems when new clients can’t connect.
The command mysqladmin debug will dump some information about locks in use, used
memory and query usage to the mysql log file. This may help solve some problems. This
command also provides some useful information even if you haven’t compiled MySQL for
debugging!
If the problem is that some tables are getting slower and slower you should try to opti-
mise the table with OPTIMIZE TABLE or myisamchk. See hundefinedi[MySQL Database
Administration], page hundefinedi. You should also check the slow queries with EXPLAIN.
You should also read the OS-specific section in this manual for problems that may be unique
to your environment. See hundefinedi[Operating System Specific Notes], page hundefinedi.
E.1.1 Compiling MYSQL for Debugging
If you have some very specific problem, you can always try to debug MySQL. To do this
you must configure MySQL with the --with-debug or the --with-debug=full option. You
can check whether MySQL was compiled with debugging by doing: mysqld --help. If the
--debug flag is listed with the options then you have debugging enabled. mysqladmin ver
also lists the mysqld version as mysql ... --debug in this case.
If you are using gcc or egcs, the recommended configure line is:
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors \
-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \
--with-debug --with-extra-charsets=complex
This will avoid problems with the libstdc++ library and with C++ exceptions (many com-
pilers have problems with C++ exceptions in threaded code) and compile a MySQL version
with support for all character sets.
Appendix E: Porting to Other Systems 835
If you suspect a memory overrun error, you can configure MySQL with --with-debug=full,
which will install a memory allocation (SAFEMALLOC) checker. Running with SAFEMALLOC is
however quite slow, so if you get performance problems you should start mysqld with the
--skip-safemalloc option. This will disable the memory overrun checks for each call to
malloc and free.
If mysqld stops crashing when you compile it with --with-debug, you have probably found
a compiler bug or a timing bug within MySQL. In this case you can try to add -g to the
CFLAGS and CXXFLAGS variables above and not use --with-debug. If mysqld now dies, you
can at least attach to it with gdb or use gdb on the core file to find out what happened.
When you configure MySQL for debugging you automatically enable a lot of extra safety
check functions that monitor the health of mysqld. If they find something “unexpected,”
an entry will be written to stderr, which safe_mysqld directs to the error log! This also
means that if you are having some unexpected problems with MySQL and are using a
source distribution, the first thing you should do is to configure MySQL for debugging!
(The second thing, of course, is to send mail to mysql@lists.mysql.com and ask for help.
Please use the mysqlbug script for all bug reports or questions regarding the MySQL version
you are using!
In the Windows MySQL distribution, mysqld.exe is by default compiled with support for
trace files.
E.1.2 Creating Trace Files
If the mysqld server doesn’t start or if you can cause the mysqld server to crash quickly,
you can try to create a trace file to find the problem.
To do this you have to have a mysqld that is compiled for debugging. You can check this by
executing mysqld -V. If the version number ends with -debug, it’s compiled with support
for trace files.
Start the mysqld server with a trace log in ‘/tmp/mysqld.trace’ (or ‘C:\mysqld.trace
on Windows):
mysqld --debug
On Windows you should also use the --standalone flag to not start mysqld as a service:
In a DOS window do:
mysqld --debug --standalone
After this you can use the mysql.exe command-line tool in a second DOS window to
reproduce the problem. You can take down the above mysqld server with mysqladmin
shutdown.
Note that the trace file will get very big! If you want to have a smaller trace file, you can
use something like:
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
which only prints information with the most interesting tags in ‘/tmp/mysqld.trace’.
If you make a bug report about this, please only send the lines from the trace file
to the appropriate mailing list where something seems to go wrong! If you can’t
locate the wrong place, you can ftp the trace file, together with a full bug report, to
836 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
ftp://support.mysql.com/pub/mysql/secret/ so that a MySQL developer can take a
look a this.
The trace file is made with the DBUG package by Fred Fish. See hundefinedi[The DBUG
package], page hundefinedi.
E.1.3 Debugging mysqld under gdb
On most systems you can also start mysqld from gdb to get more information if mysqld
crashes.
With some older gdb versions on Linux you must use run --one-thread if you want to be
able to debug mysqld threads. In this case you can only have one thread active at a time.
We recommend you to upgrade to gdb 5.1 ASAP as thread debugging works much better
with this version!
When running mysqld under gdb, you should disable the stack trace with --skip-stack-
trace to be able to catch segfaults within gdb.
It’s very hard to debug MySQL under gdb if you do a lot of new connections the whole time
as gdb doesn’t free the memory for old threads. You can avoid this problem by starting
mysqld with -O thread_cache_size= ’max_connections +1’. In most cases just using -O
thread_cache_size=5’ will help a lot!
If you want to get a core dump on Linux if mysqld dies with a SIGSEGV signal, you can
start mysqld with the --core-file option. This core file can be used to make a backtrace
that may help you find out why mysqld died:
shell> gdb mysqld core
gdb> backtrace full
gdb> exit
See hundefinedi[Crashing], page hundefinedi.
If you are using gdb 4.17.x or above on Linux, you should install a ‘.gdb’ file, with the
following information, in your current directory:
set print sevenbit off
handle SIGUSR1 nostop noprint
handle SIGUSR2 nostop noprint
handle SIGWAITING nostop noprint
handle SIGLWP nostop noprint
handle SIGPIPE nostop
handle SIGALRM nostop
handle SIGHUP nostop
handle SIGTERM nostop noprint
If you have problems debugging threads with gdb, you should download gdb 5.x and try
this instead. The new gdb version has very improved thread handling!
Here is an example how to debug mysqld:
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Do this when mysqld crashes
Appendix E: Porting to Other Systems 837
Include the above output in a mail generated with mysqlbug and mail this to
mysql@lists.mysql.com.
If mysqld hangs you can try to use some system tools like strace or /usr/proc/bin/pstack
to examine where mysqld has hung.
strace /tmp/log libexec/mysqld
If you are using the Perl DBI interface, you can turn on debugging information by using
the trace method or by setting the DBI_TRACE environment variable. See hundefinedi[Perl
DBI Class], page hundefinedi.
E.1.4 Using a Stack Trace
On some operating systems, the error log will contain a stack trace if mysqld dies unex-
pectedly. You can use this to find out where (and maybe why) mysqld died. See hunde-
finedi[Error log], page hundefinedi. To get a stack trace, you must not compile mysqld
with the -fomit-frame-pointer option to gcc. See hundefinedi[Compiling for debugging],
page hundefinedi.
If the error file contains something like the following:
mysqld got signal 11;
The manual section ’Debugging a MySQL server’ tells you how to use a
stack trace and/or the core file to produce a readable backtrace that may
help in finding out why mysqld died
Attemping backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong
stack range sanity check, ok, backtrace follows
0x40077552
0x81281a0
0x8128f47
0x8127be0
0x8127995
0x8104947
0x80ff28f
0x810131b
0x80ee4bc
0x80c3c91
0x80c6b43
0x80c1fd9
0x80c1686
you can find where mysqld died by doing the following:
1. Copy the above numbers to a file, for example ‘mysqld.stack’.
2. Make a symbol file for the mysqld server:
nm -n libexec/mysqld > /tmp/mysqld.sym
Note that most MySQL binary distributions (except for the "debug"packages, where
this information is included inside of the binaries themselves) already ship with the
above file, named mysqld.sym.gz. In this case you can simply unpack it by doing:
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
838 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
3. Execute resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack.
This will print out where mysqld died. If this doesn’t help you find out why mysqld
died, you should make a bug report and include the output from the above command
with the bug report.
Note however that in most cases it will not help us to just have a stack trace to find the
reason for the problem. To be able to locate the bug or provide a workaround, we would
in most cases need to know the query that killed mysqld and preferable a test case so
that we can repeat the problem! See hundefinedi[Bug reports], page hundefinedi.
E.1.5 Using Log Files to Find Cause of Errors in mysqld
Note that before starting mysqld with --log you should check all your tables with
myisamchk. See hundefinedi[MySQL Database Administration], page hundefinedi.
If mysqld dies or hangs, you should start mysqld with --log. When mysqld dies again,
you can examine the end of the log file for the query that killed mysqld.
If you are using --log without a file name, the log is stored in the database directory as
’hostname’.log In most cases it’s the last query in the log file that killed mysqld, but if
possible you should verify this by restarting mysqld and executing the found query from
the mysql command-line tools. If this works, you should also test all complicated queries
that didn’t complete.
You can also try the command EXPLAIN on all SELECT statements that takes a long time to
ensure that mysqld is using indexes properly. See hundefinedi[EXPLAIN], page hundefinedi.
You can find the queries that take a long time to execute by starting mysqld with --log-
slow-queries. See hundefinedi[Slow query log], page hundefinedi.
If you find the text mysqld restarted in the error log file (normally named ‘hostname.err’)
you have probably found a query that causes mysqld to fail. If this happens you should
check all your tables with myisamchk (see hundefinedi[MySQL Database Administra-
tion], page hundefinedi), and test the queries in the MySQL log files to see if one doesn’t
work. If you find such a query, try first upgrading to the newest MySQL version. If
this doesn’t help and you can’t find anything in the mysql mail archive, you should re-
port the bug to mysql@lists.mysql.com. Links to mail archives are available online at
http://lists.mysql.com/.
If you have started mysqld with myisam-recover, MySQL will automatically check and
try to repair MyISAM tables if they are marked as ’not closed properly’ or ’crashed’. If this
happens, MySQL will write an entry in the hostname.err file ’Warning: Checking table
...’ which is followed by Warning: Repairing table if the table needs to be repaired. If
you get a lot of these errors, without mysqld having died unexpectedly just before, then
something is wrong and needs to be investigated further. See line options-snt [Command-
line options], page line options-pg.
It’s of course not a good sign if mysqld did died unexpectedly, but in this case one shouldn’t
investigate the Checking table... messages but instead try to find out why mysqld died.
E.1.6 Making a Test Case If You Experience Table Corruption
If you get corrupted tables or if mysqld always fails after some update commands, you can
test if this bug is reproducible by doing the following:
Appendix E: Porting to Other Systems 839
Take down the MySQL daemon (with mysqladmin shutdown).
Make a backup of the tables (to guard against the very unlikely case that the repair
will do something bad).
Check all tables with myisamchk -s database/*.MYI. Repair any wrong tables with
myisamchk -r database/table.MYI.
Make a second backup of the tables.
Remove (or move away) any old log files from the MySQL data directory if you need
more space.
Start mysqld with --log-bin. See hundefinedi[Binary log], page hundefinedi. If you
want to find a query that crashes mysqld, you should use --log --log-bin.
When you have gotten a crashed table, stop the mysqld server.
Restore the backup.
Restart the mysqld server without --log-bin
Re-execute the commands with mysqlbinlog update-log-file | mysql. The update
log is saved in the MySQL database directory with the name hostname-bin.#.
If the tables are corrupted again or you can get mysqld to die with the above command,
you have found reproducible bug that should be easy to fix! FTP the tables and the
binary log to ftp://support.mysql.com/pub/mysql/secret/ and enter it into our
bugs system at http://bugs.mysql.com/. If you are a support customer), you can
also support@mysql.com to alert the MySQL team about the problem and have it fixed
as soon as possible.
You can also use the script mysql_find_rows to just execute some of the update statements
if you want to narrow down the problem.
E.2 Debugging a MySQL client
To be able to debug a MySQL client with the integrated debug package, you should configure
MySQL with --with-debug or --with-debug=full. See hundefinedi[configure options],
page hundefinedi.
Before running a client, you should set the MYSQL_DEBUG environment variable:
shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace
shell> export MYSQL_DEBUG
This causes clients to generate a trace file in ‘/tmp/client.trace’.
If you have problems with your own client code, you should attempt to connect to the
server and run your query using a client that is known to work. Do this by running mysql
in debugging mode (assuming you have compiled MySQL with debugging on):
shell> mysql --debug=d:t:O,/tmp/client.trace
This will provide useful information in case you mail a bug report. See hundefinedi[Bug
reports], page hundefinedi.
If your client crashes at some ’legal’ looking code, you should check that your ‘mysql.h
include file matches your mysql library file. A very common mistake is to use an old
mysql.h’ file from an old MySQL installation with new MySQL library.
840 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
E.3 The DBUG Package
The MySQL server and most MySQL clients are compiled with the DBUG package originally
made by Fred Fish. When one has configured MySQL for debugging, this package makes
it possible to get a trace file of what the program is debugging. See hundefinedi[Making
trace files], page hundefinedi.
One uses the debug package by invoking the program with the --debug="..." or the -#...
option.
Most MySQL programs has a default debug string that will be used if you don’t specify an
option to --debug. The default trace file is usually /tmp/programname.trace on Unix and
\programname.trace on Windows.
The debug control string is a sequence of colon separated fields as follows:
<field_1>:<field_2>:...:<field_N>
Each field consists of a mandatory flag character followed by an optional ","and comma-
separated list of modifiers:
flag[,modifier,modifier,...,modifier]
The currently recognised flag characters are:
Flag Description
d Enable output from DBUG <N>macros for the current state. May be followed by a
list of keywords which selects output only for the DBUG macros with that keyword.
An empty list of keywords implies output for all macros.
D Delay after each debugger output line. The argument is the number of tenths of
seconds to delay, subject to machine capabilities. That is, -#D,20 is delay two
seconds.
f Limit debugging and/or tracing, and profiling to the list of named functions. Note
that a null list will disable all functions. The appropriate "d"or "t"flags must still
be given, this flag only limits their actions if they are enabled.
F Identify the source file name for each line of debug or trace output.
i Identify the process with the pid or thread id for each line of debug or trace output.
g Enable profiling. Create a file called ’dbugmon.out’ containing information that can
be used to profile the program. May be followed by a list of keywords that select
profiling only for the functions in that list. A null list implies that all functions are
considered.
L Identify the source file line number for each line of debug or trace output.
n Print the current function nesting depth for each line of debug or trace output.
N Number each line of dbug output.
o Redirect the debugger output stream to the specified file. The default output is
stderr.
O As obut the file is really flushed between each write. When needed the file is closed
and reopened between each write.
p Limit debugger actions to specified processes. A process must be identified with the
DBUG PROCESS macro and match one in the list for debugger actions to occur.
P Print the current process name for each line of debug or trace output.
r When pushing a new state, do not inherit the previous state’s function nesting level.
Useful when the output is to start at the left margin.
S Do function sanity( file , line ) at each debugged function until sanity() returns
something that differs from 0. (Mostly used with safemalloc to find memory leaks)
Appendix E: Porting to Other Systems 841
t Enable function call/exit trace lines. May be followed by a list (containing only one
modifier) giving a numeric maximum trace level, beyond which no output will occur
for either debugging or tracing macros. The default is a compile time option.
Some examples of debug control strings which might appear on a shell command-line (the
"-#"is typically used to introduce a control string to an application program) are:
-#d:t
-#d:f,main,subr1:F:L:t,20
-#d,input,output,files:n
-#d:t:i:O,\\mysqld.trace
In MySQL, common tags to print (with the doption) are: enter,exit,error,warning,info
and loop.
E.4 Locking methods
Currently MySQL only supports table locking for ISAM/MyISAM and HEAP tables, page-level
locking for BDB tables and row-level locking for InnoDB tables. See hundefinedi[Internal
locking], page hundefinedi. With MyISAM tables one can freely mix INSERT and SELECT
without locks, if the INSERTs are non-conflicting (i.e. whenever they append to the end of
the table file rather than filling freespace from deleted rows/data).
Starting in version 3.23.33, you can analyse the table lock contention on your system by
checking Table_locks_waited and Table_locks_immediate environment variables.
To decide if you want to use a table type with row-level locking, you will want to look at
what the application does and what the select/update pattern of the data is.
Pros for row locking:
Fewer lock conflicts when accessing different rows in many threads.
Fewer changes for rollbacks.
Makes it possible to lock a single row a long time.
Cons:
Takes more memory than page level or table locks.
Is slower than page level or table locks when used on a big part of the table, because
one has to do many more locks.
Is definitely much worse than other locks if you do often do GROUP BY on a large part
of the data or if one has to often scan the whole table.
With higher level locks one can also more easily support locks of different types to tune
the application as the lock overhead is less notable as for row level locks.
Table locks are superior to page level / row level locks in the following cases:
Mostly reads
Read and updates on strict keys; this is where one updates or deletes a row that can
be fetched with one key read:
UPDATE table_name SET column=value WHERE unique_key#
DELETE FROM table_name WHERE unique_key=#
SELECT combined with INSERT (and very few UPDATEs and DELETEs).
842 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Many scans / GROUP BY on the whole table without any writers.
Other options than row / page level locking:
Versioning (like we use in MySQL for concurrent inserts) where you can have one writer
at the same time as many readers. This means that the database/table supports different
views for the data depending on when one started to access it. Other names for this are
time travel, copy on write or copy on demand.
Copy on demand is in many case much better than page or row level locking; the worst case
does, however, use much more memory than when using normal locks.
Instead of using row level locks one can use application level locks (like get lock/release lock
in MySQL). This works of course only in well-behaved applications.
In many cases one can do an educated guess which locking type is best for the application,
but generally it’s very hard to say that a given lock type is better than another; everything
depends on the application and different part of the application may require different lock
types.
Here are some tips about locking in MySQL:
Most web applications do lots of selects, very few deletes, updates mainly on keys, and
inserts in some specific tables. The base MySQL setup is very well tuned for this.
Concurrent users are not a problem if one doesn’t mix updates with selects that need to
examine many rows in the same table.
If one mixes inserts and deletes on the same table then INSERT DELAYED may be of great
help.
One can also use LOCK TABLES to speed up things (many updates within a single lock is
much faster than updates without locks). Splitting thing to different tables will also help.
If you get speed problems with the table locks in MySQL, you may be able to solve these
by converting some of your tables to InnoDB or BDB tables. See hundefinedi[InnoDB],
page hundefinedi. See hundefinedi[BDB], page hundefinedi.
The optimisation section in the manual covers a lot of different aspects of how to tune
applications. See hundefinedi[Tips], page hundefinedi.
E.5 Comments about RTS threads
I have tried to use the RTS thread packages with MySQL but stumbled on the following
problems:
They use an old version of a lot of POSIX calls and it is very tedious to make wrappers for
all functions. I am inclined to think that it would be easier to change the thread libraries
to the newest POSIX specification.
Some wrappers are already written. See ‘mysys/my_pthread.c’ for more info.
At least the following should be changed:
pthread_get_specific should use one argument. sigwait should take two arguments.
A lot of functions (at least pthread_cond_wait,pthread_cond_timedwait) should return
the error code on error. Now they return -1 and set errno.
Appendix E: Porting to Other Systems 843
Another problem is that user-level threads use the ALRM signal and this aborts a lot of
functions (read,write,open...). MySQL should do a retry on interrupt on all of these but
it is not that easy to verify it.
The biggest unsolved problem is the following:
To get thread-level alarms I changed ‘mysys/thr_alarm.c’ to wait between alarms with
pthread_cond_timedwait(), but this aborts with error EINTR. I tried to debug the thread
library as to why this happens, but couldn’t find any easy solution.
If someone wants to try MySQL with RTS threads I suggest the following:
Change functions MySQL uses from the thread library to POSIX. This shouldn’t take
that long.
Compile all libraries with the -DHAVE_rts_threads.
Compile thr_alarm.
If there are some small differences in the implementation, they may be fixed by changing
my_pthread.h’ and ‘my_pthread.c’.
Run thr_alarm. If it runs without any “warning”, “error” or aborted messages, you
are on the right track. Here is a successful run on Solaris:
Main thread: 1
Thread 0 (5) started
Thread: 5 Waiting
process_alarm
Thread 1 (6) started
Thread: 6 Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6 Slept for 1 (1) sec
Thread: 6 Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6 Slept for 2 (2) sec
Thread: 6 Simulation of no alarm needed
Thread: 6 Slept for 0 (3) sec
Thread: 6 Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6 Slept for 4 (4) sec
Thread: 6 Waiting
process_alarm
thread_alarm
Thread: 5 Slept for 10 (10) sec
Thread: 5 Waiting
process_alarm
process_alarm
thread_alarm
844 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Thread: 6 Slept for 5 (5) sec
Thread: 6 Waiting
process_alarm
process_alarm
...
thread_alarm
Thread: 5 Slept for 0 (1) sec
end
E.6 Differences between different thread packages
MySQL is very dependent on the thread package used. So when choosing a good platform
for MySQL, the thread package is very important.
There are at least three types of thread packages:
User threads in a single process. Thread switching is managed with alarms and the
threads library manages all non-thread-safe functions with locks. Read, write and
select operations are usually managed with a thread-specific select that switches to
another thread if the running threads have to wait for data. If the user thread packages
are integrated in the standard libs (FreeBSD and BSDI threads) the thread package
requires less overhead than thread packages that have to map all unsafe calls (MIT-
pthreads, FSU Pthreads and RTS threads). In some environments (for example, SCO),
all system calls are thread-safe so the mapping can be done very easily (FSU Pthreads
on SCO). Downside: All mapped calls take a little time and it’s quite tricky to be able
to handle all situations. There are usually also some system calls that are not handled
by the thread package (like MIT-pthreads and sockets). Thread scheduling isn’t always
optimal.
User threads in separate processes. Thread switching is done by the kernel and all data
are shared between threads. The thread package manages the standard thread calls to
allow sharing data between threads. LinuxThreads is using this method. Downside:
Lots of processes. Thread creating is slow. If one thread dies the rest are usually left
hanging and you must kill them all before restarting. Thread switching is somewhat
expensive.
Kernel threads. Thread switching is handled by the thread library or the kernel and is
very fast. Everything is done in one process, but on some systems, ps may show the
different threads. If one thread aborts, the whole process aborts. Most system calls are
thread-safe and should require very little overhead. Solaris, HP-UX, AIX and OSF/1
have kernel threads.
In some systems kernel threads are managed by integrating user level threads in the system
libraries. In such cases, the thread switching can only be done by the thread library and
the kernel isn’t really “thread aware”.
Appendix F: Environment Variables 845
Appendix F Environment Variables
Here is a list of all the environment variables that are used directly or indirectly by MySQL.
Most of these can also be found in other places in this manual.
Note that any options on the command-line will take precedence over values specified in con-
figuration files and environment variables, and values in configuration files take precedence
over values in environment variables.
In many cases it’s preferable to use a configure file instead of environment variables to
modify the behaviour of MySQL. See hundefinedi[Option files], page hundefinedi.
Variable Description
CCX Set this to your C++ compiler when running configure.
CC Set this to your C compiler when running configure.
CFLAGS Flags for your C compiler when running configure.
CXXFLAGS Flags for your C++ compiler when running configure.
DBI_USER The default user name for Perl DBI.
DBI_TRACE Used when tracing Perl DBI.
HOME The default path for the mysql history file is ‘$HOME/.mysql_
history’.
LD_RUN_PATH Used to specify where your ‘libmysqlclient.so’ is.
MYSQL_DEBUG Debug-trace options when debugging.
MYSQL_HISTFILE The path to the mysql history file.
MYSQL_HOST Default host name used by the mysql command-line client.
MYSQL_PS1 Command prompt to use in the mysql command-line client.
See hundefinedi[mysql], page hundefinedi.
MYSQL_PWD The default password when connecting to mysqld. Note that
use of this is insecure!
MYSQL_TCP_PORT The default TCP/IP port.
MYSQL_UNIX_PORT The default socket; used for connections to localhost.
PATH Used by the shell to finds the MySQL programs.
TMPDIR The directory where temporary tables/files are created.
TZ This should be set to your local time zone. See hundefinedi
[Timezone problems], page hundefinedi.
UMASK_DIR The user-directory creation mask when creating directories.
Note that this is ANDed with UMASK!
UMASK The user-file creation mask when creating files.
USER The default user on Windows to use when connecting to
mysqld.
846 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Appendix G MySQL Regular Expressions
A regular expression (regex) is a powerful way of specifying a complex search.
MySQL uses Henry Spencer’s implementation of regular expressions, which is aimed at
conformance with POSIX 1003.2. MySQL uses the extended version.
This is a simplistic reference that skips the details. To get more exact information, see
Henry Spencer’s regex(7) manual page that is included in the source distribution. See
hundefinedi[Credits], page hundefinedi.
A regular expression describes a set of strings. The simplest regexp is one that has no
special characters in it. For example, the regexp hello matches hello and nothing else.
Non-trivial regular expressions use certain special constructs so that they can match more
than one string. For example, the regexp hello|word matches either the string hello or
the string word.
As a more complex example, the regexp B[an]*s matches any of the strings Bananas,
Baaaaas,Bs, and any other string starting with a B, ending with an s, and containing any
number of aor ncharacters in between.
A regular expression may use any of the following special characters/constructs:
^Match the beginning of a string.
mysql> SELECT "fo\nfo" REGEXP "^fo$"; -> 0
mysql> SELECT "fofo" REGEXP "^fo"; -> 1
$Match the end of a string.
mysql> SELECT "fo\no" REGEXP "^fo\no$"; -> 1
mysql> SELECT "fo\no" REGEXP "^fo$"; -> 0
.Match any character (including newline).
mysql> SELECT "fofo" REGEXP "^f.*"; -> 1
mysql> SELECT "fo\nfo" REGEXP "^f.*"; -> 1
a* Match any sequence of zero or more acharacters.
mysql> SELECT "Ban" REGEXP "^Ba*n"; -> 1
mysql> SELECT "Baaan" REGEXP "^Ba*n"; -> 1
mysql> SELECT "Bn" REGEXP "^Ba*n"; -> 1
a+ Match any sequence of one or more acharacters.
mysql> SELECT "Ban" REGEXP "^Ba+n"; -> 1
mysql> SELECT "Bn" REGEXP "^Ba+n"; -> 0
a? Match either zero or one acharacter.
mysql> SELECT "Bn" REGEXP "^Ba?n"; -> 1
mysql> SELECT "Ban" REGEXP "^Ba?n"; -> 1
mysql> SELECT "Baan" REGEXP "^Ba?n"; -> 0
de|abc Match either of the sequences de or abc.
mysql> SELECT "pi" REGEXP "pi|apa"; -> 1
mysql> SELECT "axe" REGEXP "pi|apa"; -> 0
mysql> SELECT "apa" REGEXP "pi|apa"; -> 1
mysql> SELECT "apa" REGEXP "^(pi|apa)$"; -> 1
Appendix G: MySQL Regular Expressions 847
mysql> SELECT "pi" REGEXP "^(pi|apa)$"; -> 1
mysql> SELECT "pix" REGEXP "^(pi|apa)$"; -> 0
(abc)* Match zero or more instances of the sequence abc.
mysql> SELECT "pi" REGEXP "^(pi)*$"; -> 1
mysql> SELECT "pip" REGEXP "^(pi)*$"; -> 0
mysql> SELECT "pipi" REGEXP "^(pi)*$"; -> 1
{1}
{2,3} The is a more general way of writing regexps that match many occurrences of
the previous atom.
a* Can be written as a{0,}.
a+ Can be written as a{1,}.
a? Can be written as a{0,1}.
To be more precise, an atom followed by a bound containing one integer iand
no comma matches a sequence of exactly imatches of the atom. An atom
followed by a bound containing one integer iand a comma matches a sequence
of ior more matches of the atom. An atom followed by a bound containing
two integers iand jmatches a sequence of ithrough j(inclusive) matches of
the atom.
Both arguments must be in the range from 0to RE_DUP_MAX (default 255),
inclusive. If there are two arguments, the second must be greater than or equal
to the first.
[a-dX]
[^a-dX] Matches any character which is (or is not, if ^is used) either a,b,c,dor X.
To include a literal ]character, it must immediately follow the opening bracket
[. To include a literal -character, it must be written first or last. So [0-9]
matches any decimal digit. Any character that does not have a defined meaning
inside a [] pair has no special meaning and matches only itself.
mysql> SELECT "aXbc" REGEXP "[a-dXYZ]"; -> 1
mysql> SELECT "aXbc" REGEXP "^[a-dXYZ]$"; -> 0
mysql> SELECT "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1
mysql> SELECT "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0
mysql> SELECT "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1
mysql> SELECT "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
[[.characters.]]
The sequence of characters of that collating element. The sequence is a single
element of the bracket expression’s list. A bracket expression containing a
multi-character collating element can thus match more than one character, for
example, if the collating sequence includes a ch collating element, then the
regular expression [[.ch.]]*c matches the first five characters of chchcc.
[=character_class=]
An equivalence class, standing for the sequences of characters of all collating
elements equivalent to that one, including itself.
848 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
For example, if oand (+) are the members of an equivalence class, then
[[=o=]],[[=(+)=]], and [o(+)] are all synonymous. An equivalence class
may not be an endpoint of a range.
[:character_class:]
Within a bracket expression, the name of a character class enclosed in [: and :]
stands for the list of all characters belonging to that class. Standard character
class names are:
Name Name Name
alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit
These stand for the character classes defined in the ctype(3) manual page. A
locale may provide others. A character class may not be used as an endpoint
of a range.
mysql> SELECT "justalnums" REGEXP "[[:alnum:]]+"; -> 1
mysql> SELECT "!!" REGEXP "[[:alnum:]]+"; -> 0
[[:<:]]
[[:>:]] These match the null string at the beginning and end of a word respectively.
A word is defined as a sequence of word characters which is neither preceded
nor followed by word characters. A word character is an alnum character (as
defined by ctype(3)) or an underscore (_).
mysql> SELECT "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1
mysql> SELECT "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
mysql> SELECT "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
Appendix H: GNU General Public License 849
Appendix H GNU General Public License
Version 2, June 1991
Copyright c
1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share and change
it. By contrast, the GNU General Public License is intended to guarantee your freedom
to share and change free software---to make sure the software is free for all its users. This
General Public License applies to most of the Free Software Foundation’s software and to
any other program whose authors commit to using it. (Some other Free Software Foundation
software is covered by the GNU Library General Public License instead.) You can apply it
to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public
Licenses are designed to make sure that you have the freedom to distribute copies of free
software (and charge for this service if you wish), that you receive source code or can get
it if you want it, that you can change the software or use pieces of it in new free programs;
and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these
rights or to ask you to surrender the rights. These restrictions translate to certain respon-
sibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you
must give the recipients all the rights that you have. You must make sure that they, too,
receive or can get the source code. And you must show them these terms so they know
their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this
license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author’s protection and ours, we want to make certain that everyone un-
derstands that there is no warranty for this free software. If the software is modified by
someone else and passed on, we want its recipients to know that what they have is not the
original, so that any problems introduced by others will not reflect on the original authors’
reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid
the danger that redistributors of a free program will individually obtain patent licenses, in
effect making the program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone’s free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
850 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
TERMS AND CONDITIONS FOR COPYING,
DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed
by the copyright holder saying it may be distributed under the terms of this General
Public License. The “Program”, below, refers to any such program or work, and a
“work based on the Program” means either the Program or any derivative work under
copyright law: that is to say, a work containing the Program or a portion of it, either
verbatim or with modifications and/or translated into another language. (Hereinafter,
translation is included without limitation in the term “modification”.) Each licensee is
addressed as “you”.
Activities other than copying, distribution and modification are not covered by this
License; they are outside its scope. The act of running the Program is not restricted,
and the output from the Program is covered only if its contents constitute a work based
on the Program (independent of having been made by running the Program). Whether
that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program’s source code as you
receive it, in any medium, provided that you conspicuously and appropriately publish
on each copy an appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any warranty; and give
any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your
option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a
work based on the Program, and copy and distribute such modifications or work under
the terms of Section 1 above, provided that you also meet all of these conditions:
a. You must cause the modified files to carry prominent notices stating that you
changed the files and the date of any change.
b. You must cause any work that you distribute or publish, that in whole or in part
contains or is derived from the Program or any part thereof, to be licensed as a
whole at no charge to all third parties under the terms of this License.
c. If the modified program normally reads commands interactively when run, you
must cause it, when started running for such interactive use in the most ordinary
way, to print or display an announcement including an appropriate copyright notice
and a notice that there is no warranty (or else, saying that you provide a warranty)
and that users may redistribute the program under these conditions, and telling
the user how to view a copy of this License. (Exception: if the Program itself is
interactive but does not normally print such an announcement, your work based
on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections
of that work are not derived from the Program, and can be reasonably considered
independent and separate works in themselves, then this License, and its terms, do not
apply to those sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based on the Program,
the distribution of the whole must be on the terms of this License, whose permissions
for other licensees extend to the entire whole, and thus to each and every part regardless
of who wrote it.
Appendix H: GNU General Public License 851
Thus, it is not the intent of this section to claim rights or contest your rights to
work written entirely by you; rather, the intent is to exercise the right to control the
distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the
Program (or with a work based on the Program) on a volume of a storage or distribution
medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2)
in object code or executable form under the terms of Sections 1 and 2 above provided
that you also do one of the following:
a. Accompany it with the complete corresponding machine-readable source code,
which must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
b. Accompany it with a written offer, valid for at least three years, to give any third-
party, for a charge no more than your cost of physically performing source distri-
bution, a complete machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium customarily
used for software interchange; or,
c. Accompany it with the information you received as to the offer to distribute cor-
responding source code. (This alternative is allowed only for noncommercial dis-
tribution and only if you received the program in object code or executable form
with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifi-
cations to it. For an executable work, complete source code means all the source code
for all modules it contains, plus any associated interface definition files, plus the scripts
used to control compilation and installation of the executable. However, as a spe-
cial exception, the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major components (compiler,
kernel, and so on) of the operating system on which the executable runs, unless that
component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from
a designated place, then offering equivalent access to copy the source code from the
same place counts as distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly
provided under this License. Any attempt otherwise to copy, modify, sublicense or
distribute the Program is void, and will automatically terminate your rights under this
License. However, parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such parties remain in full
compliance.
5. You are not required to accept this License, since you have not signed it. However,
nothing else grants you permission to modify or distribute the Program or its derivative
works. These actions are prohibited by law if you do not accept this License. Therefore,
by modifying or distributing the Program (or any work based on the Program), you
indicate your acceptance of this License to do so, and all its terms and conditions for
copying, distributing or modifying the Program or works based on it.
852 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
6. Each time you redistribute the Program (or any work based on the Program), the
recipient automatically receives a license from the original licensor to copy, distribute
or modify the Program subject to these terms and conditions. You may not impose
any further restrictions on the recipients’ exercise of the rights granted herein. You are
not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any
other reason (not limited to patent issues), conditions are imposed on you (whether by
court order, agreement or otherwise) that contradict the conditions of this License, they
do not excuse you from the conditions of this License. If you cannot distribute so as
to satisfy simultaneously your obligations under this License and any other pertinent
obligations, then as a consequence you may not distribute the Program at all. For
example, if a patent license would not permit royalty-free redistribution of the Program
by all those who receive copies directly or indirectly through you, then the only way
you could satisfy both it and this License would be to refrain entirely from distribution
of the Program.
If any portion of this section is held invalid or unenforceable under any particular
circumstance, the balance of the section is intended to apply and the section as a
whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other
property right claims or to contest validity of any such claims; this section has the
sole purpose of protecting the integrity of the free software distribution system, which
is implemented by public license practices. Many people have made generous contri-
butions to the wide range of software distributed through that system in reliance on
consistent application of that system; it is up to the author/donor to decide if he or
she is willing to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence
of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either
by patents or by copyrighted interfaces, the original copyright holder who places the
Program under this License may add an explicit geographical distribution limitation
excluding those countries, so that distribution is permitted only in or among countries
not thus excluded. In such case, this License incorporates the limitation as if written
in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of the General
Public License from time to time. Such new versions will be similar in spirit to the
present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a
version number of this License which applies to it and “any later version”, you have
the option of following the terms and conditions either of that version or of any later
version published by the Free Software Foundation. If the Program does not specify a
version number of this License, you may choose any version ever published by the Free
Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distri-
bution conditions are different, write to the author to ask for permission. For software
Appendix H: GNU General Public License 853
which is copyrighted by the Free Software Foundation, write to the Free Software Foun-
dation; we sometimes make exceptions for this. Our decision will be guided by the two
goals of preserving the free status of all derivatives of our free software and of promoting
the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLI-
CABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPY-
RIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS
IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST
OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT
LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
END OF TERMS AND CONDITIONS
854 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public,
the best way to achieve this is to make it free software which everyone can redistribute and
change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the
start of each source file to most effectively convey the exclusion of warranty; and each file
should have at least the “copyright” line and a pointer to where the full notice is found.
one line to give the program’s name and a brief idea of what it does.
Copyright (C) yyyy name of author
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an
interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
This is free software, and you are welcome to redistribute it
under certain conditions; type ‘show c’ for details.
The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the
General Public License. Of course, the commands you use may be called something other
than ‘show w’ and ‘show c’; they could even be mouse-clicks or menu items---whatever suits
your program.
You should also get your employer (if you work as a programmer) or your school, if any,
to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the
names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
‘Gnomovision’ (which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary
programs. If your program is a subroutine library, you may consider it more useful to permit
linking proprietary applications with the library. If this is what you want to do, use the
GNU Library General Public License instead of this License.
Appendix I: GNU Lesser General Public License 855
Appendix I GNU Lesser General Public License
Version 2.1, February 1999
Copyright c
1991, 1999 Free Software Foundation, Inc.
59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence the
version number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to share and change
it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom
to share and change free software---to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated
software---typically libraries---of the Free Software Foundation and other authors who
decide to use it. You can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better strategy to use in any
particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not price. Our General
Public Licenses are designed to make sure that you have the freedom to distribute copies
of free software (and charge for this service if you wish); that you receive source code or
can get it if you want it; that you can change the software and use pieces of it in new free
programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you
these rights or to ask you to surrender these rights. These restrictions translate to certain
responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must
give the recipients all the rights that we gave you. You must make sure that they, too,
receive or can get the source code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them with the library after
making changes to the library and recompiling it. And you must show them these terms so
they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we
offer you this license, which gives you legal permission to copy, distribute and/or modify
the library.
To protect each distributor, we want to make it very clear that there is no warranty for the
free library. Also, if the library is modified by someone else and passed on, the recipients
should know that what they have is not the original version, so that the original author’s
reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We
wish to make sure that a company cannot effectively restrict the users of a free program by
856 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
obtaining a restrictive license from a patent holder. Therefore, we insist that any patent
license obtained for a version of the library must be consistent with the full freedom of use
specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General
Public License. This license, the GNU Lesser General Public License, applies to certain
designated libraries, and is quite different from the ordinary General Public License. We
use this license for certain libraries in order to permit linking those libraries into non-free
programs.
When a program is linked with a library, whether statically or using a shared library, the
combination of the two is legally speaking a combined work, a derivative of the original
library. The ordinary General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General Public License permits
more lax criteria for linking other code with the library.
We call this license the Lesser General Public License because it does Less to protect the
user’s freedom than the ordinary General Public License. It also provides other free software
developers Less of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many libraries. However, the
Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible
use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free
programs must be allowed to use the library. A more frequent case is that a free library
does the same job as widely used non-free libraries. In this case, there is little to gain by
limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater
number of people to use a large body of free software. For example, permission to use the
GNU C Library in non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users’ freedom, it does
ensure that the user of a program that is linked with the Library has the freedom and the
wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay
close attention to the difference between a “work based on the library” and a “work that
uses the library”. The former contains code derived from the library, whereas the latter
must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING,
DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other program which contains
a notice placed by the copyright holder or other authorized party saying it may be
distributed under the terms of this Lesser General Public License (also called “this
License”). Each licensee is addressed as “you”.
A “library” means a collection of software functions and/or data prepared so as to be
conveniently linked with application programs (which use some of those functions and
data) to form executables.
Appendix I: GNU Lesser General Public License 857
The “Library”, below, refers to any such software library or work which has been
distributed under these terms. A “work based on the Library” means either the Library
or any derivative work under copyright law: that is to say, a work containing the
Library or a portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is included without
limitation in the term “modification”.)
“Source code” for a work means the preferred form of the work for making modifications
to it. For a library, complete source code means all the source code for all modules it
contains, plus any associated interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not covered by this
License; they are outside its scope. The act of running a program using the Library is
not restricted, and output from such a program is covered only if its contents constitute
a work based on the Library (independent of the use of the Library in a tool for writing
it). Whether that is true depends on what the Library does and what the program
that uses the Library does.
1. You may copy and distribute verbatim copies of the Library’s complete source code
as you receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty; keep
intact all the notices that refer to this License and to the absence of any warranty; and
distribute a copy of this License along with the Library.
You may charge a fee for the physical act of transferring a copy, and you may at your
option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it, thus forming a
work based on the Library, and copy and distribute such modifications or work under
the terms of Section 1 above, provided that you also meet all of these conditions:
a. The modified work must itself be a software library.
b. You must cause the files modified to carry prominent notices stating that you
changed the files and the date of any change.
c. You must cause the whole of the work to be licensed at no charge to all third
parties under the terms of this License.
d. If a facility in the modified Library refers to a function or a table of data to
be supplied by an application program that uses the facility, other than as an
argument passed when the facility is invoked, then you must make a good faith
effort to ensure that, in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of its purpose remains
meaningful.
(For example, a function in a library to compute square roots has a purpose that
is entirely well-defined independent of the application. Therefore, Subsection 2d
requires that any application-supplied function or table used by this function must
be optional: if the application does not supply it, the square root function must
still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable sections of
that work are not derived from the Library, and can be reasonably considered indepen-
dent and separate works in themselves, then this License, and its terms, do not apply
858 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
to those sections when you distribute them as separate works. But when you distribute
the same sections as part of a whole which is a work based on the Library, the distri-
bution of the whole must be on the terms of this License, whose permissions for other
licensees extend to the entire whole, and thus to each and every part regardless of who
wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to
work written entirely by you; rather, the intent is to exercise the right to control the
distribution of derivative or collective works based on the Library.
In addition, mere aggregation of another work not based on the Library with the
Library (or with a work based on the Library) on a volume of a storage or distribution
medium does not bring the other work under the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public License instead
of this License to a given copy of the Library. To do this, you must alter all the notices
that refer to this License, so that they refer to the ordinary GNU General Public
License, version 2, instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify that version
instead if you wish.) Do not make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy, so the ordinary
GNU General Public License applies to all subsequent copies and derivative works made
from that copy.
This option is useful when you wish to copy part of the code of the Library into a
program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of it, under Section
2) in object code or executable form under the terms of Sections 1 and 2 above provided
that you accompany it with the complete corresponding machine-readable source code,
which must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated place,
then offering equivalent access to copy the source code from the same place satisfies the
requirement to distribute the source code, even though third parties are not compelled
to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but is designed
to work with the Library by being compiled or linked with it, is called a “work that
uses the Library”. Such a work, in isolation, is not a derivative work of the Library,
and therefore falls outside the scope of this License.
However, linking a “work that uses the Library” with the Library creates an executable
that is a derivative of the Library (because it contains portions of the Library), rather
than a “work that uses the library”. The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a “work that uses the Library” uses material from a header file that is part of
the Library, the object code for the work may be a derivative work of the Library even
though the source code is not. Whether this is true is especially significant if the work
can be linked without the Library, or if the work is itself a library. The threshold for
this to be true is not precisely defined by law.
Appendix I: GNU Lesser General Public License 859
If such an object file uses only numerical parameters, data structure layouts and ac-
cessors, and small macros and small inline functions (ten lines or less in length), then
the use of the object file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the Library will still
fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute the object code
for the work under the terms of Section 6. Any executables containing that work also
fall under Section 6, whether they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a “work that
uses the Library” with the Library to produce a work containing portions of the Li-
brary, and distribute that work under terms of your choice, provided that the terms
permit modification of the work for the customer’s own use and reverse engineering for
debugging such modifications.
You must give prominent notice with each copy of the work that the Library is used
in it and that the Library and its use are covered by this License. You must supply
a copy of this License. If the work during execution displays copyright notices, you
must include the copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one of these things:
a. Accompany the work with the complete corresponding machine-readable source
code for the Library including whatever changes were used in the work (which must
be distributed under Sections 1 and 2 above); and, if the work is an executable
linked with the Library, with the complete machine-readable “work that uses the
Library”, as object code and/or source code, so that the user can modify the
Library and then relink to produce a modified executable containing the modified
Library. (It is understood that the user who changes the contents of definitions
files in the Library will not necessarily be able to recompile the application to use
the modified definitions.)
b. Use a suitable shared library mechanism for linking with the Library. A suitable
mechanism is one that (1) uses at runtime a copy of the library already present
on the user’s computer system, rather than copying library functions into the
executable, and (2) will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is interface-compatible with
the version that the work was made with.
c. Accompany the work with a written offer, valid for at least three years, to give the
same user the materials specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d. If distribution of the work is made by offering access to copy from a designated
place, offer equivalent access to copy the above specified materials from the same
place.
e. Verify that the user has already received a copy of these materials or that you have
already sent this user a copy.
For an executable, the required form of the “work that uses the Library” must include
any data and utility programs needed for reproducing the executable from it. However,
as a special exception, the materials to be distributed need not include anything that
is normally distributed (in either source or binary form) with the major components
860 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
(compiler, kernel, and so on) of the operating system on which the executable runs,
unless that component itself accompanies the executable.
It may happen that this requirement contradicts the license restrictions of other pro-
prietary libraries that do not normally accompany the operating system. Such a con-
tradiction means you cannot use both them and the Library together in an executable
that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side in
a single library together with other library facilities not covered by this License, and
distribute such a combined library, provided that the separate distribution of the work
based on the Library and of the other library facilities is otherwise permitted, and
provided that you do these two things:
a. Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities. This must be distributed
under the terms of the Sections above.
b. Give prominent notice with the combined library of the fact that part of it is a work
based on the Library, and explaining where to find the accompanying uncombined
form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library except
as expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense, link with, or distribute the Library is void, and will automatically terminate
your rights under this License. However, parties who have received copies, or rights,
from you under this License will not have their licenses terminated so long as such
parties remain in full compliance.
9. You are not required to accept this License, since you have not signed it. However,
nothing else grants you permission to modify or distribute the Library or its derivative
works. These actions are prohibited by law if you do not accept this License. Therefore,
by modifying or distributing the Library (or any work based on the Library), you
indicate your acceptance of this License to do so, and all its terms and conditions for
copying, distributing or modifying the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library), the recipient
automatically receives a license from the original licensor to copy, distribute, link with
or modify the Library subject to these terms and conditions. You may not impose any
further restrictions on the recipients’ exercise of the rights granted herein. You are not
responsible for enforcing compliance by third parties with this License.
11. If, as a consequence of a court judgment or allegation of patent infringement or for any
other reason (not limited to patent issues), conditions are imposed on you (whether by
court order, agreement or otherwise) that contradict the conditions of this License, they
do not excuse you from the conditions of this License. If you cannot distribute so as
to satisfy simultaneously your obligations under this License and any other pertinent
obligations, then as a consequence you may not distribute the Library at all. For
example, if a patent license would not permit royalty-free redistribution of the Library
by all those who receive copies directly or indirectly through you, then the only way
you could satisfy both it and this License would be to refrain entirely from distribution
of the Library.
Appendix I: GNU Lesser General Public License 861
If any portion of this section is held invalid or unenforceable under any particular
circumstance, the balance of the section is intended to apply, and the section as a
whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other
property right claims or to contest validity of any such claims; this section has the
sole purpose of protecting the integrity of the free software distribution system which
is implemented by public license practices. Many people have made generous contri-
butions to the wide range of software distributed through that system in reliance on
consistent application of that system; it is up to the author/donor to decide if he or
she is willing to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence
of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain countries either
by patents or by copyrighted interfaces, the original copyright holder who places the
Library under this License may add an explicit geographical distribution limitation
excluding those countries, so that distribution is permitted only in or among countries
not thus excluded. In such case, this License incorporates the limitation as if written
in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of the Lesser
General Public License from time to time. Such new versions will be similar in spirit
to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies a version
number of this License which applies to it and “any later version”, you have the option of
following the terms and conditions either of that version or of any later version published
by the Free Software Foundation. If the Library does not specify a license version
number, you may choose any version ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs whose distribu-
tion conditions are incompatible with these, write to the author to ask for permission.
For software which is copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our decision will be
guided by the two goals of preserving the free status of all derivatives of our free soft-
ware and of promoting the sharing and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLI-
CABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPY-
RIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS”
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST
OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
862 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED
ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT
LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix I: GNU Lesser General Public License 863
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible use to the public,
we recommend making it free software that everyone can redistribute and change. You can
do so by permitting redistribution under these terms (or, alternatively, under the terms of
the ordinary General Public License).
To apply these terms, attach the following notices to the library. It is safest to attach them
to the start of each source file to most effectively convey the exclusion of warranty; and
each file should have at least the “copyright” line and a pointer to where the full notice is
found.
one line to give the library’s name and an idea of what it does.
Copyright (C) year name of author
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to
sign a “copyright disclaimer” for the library, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the library
‘Frob’ (a library for tweaking knobs) written by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That’s all there is to it!
864 Referˆencia t´ecnica para o MySQL vers˜ao 3.23.52
Ind´
ices dos comandos, tipos e fun¸oes SQL
(Index is nonexistent)
Concept Index 865
Concept Index
(Index is nonexistent)

Navigation menu