Tabla de contenidos
Access deniedCan't connect to [local] MySQL serverClient does not support authentication protocolLa máquina 'host_name' está bloqueadaDemasiadas conexionesOut of memoryMySQL se ha apagadoPacket too largeThe table is fullCan't create/write to fileCommands out of syncIgnoring userTable 'nombre_de_tabla' doesn't existCan't initialize character set/tmp/mysql.sockDATENULLEste apéndice enumera algunos problemas comunes y mensajes de error que usted podría encontrarse. Explica como determinar los motivos de los problemas y qué hacer para resolverlos.
Cuando se encuentre un problema, la primera cosa que debe hacer es determinar qué programa o pieza de hardware lo está causando:
Si tiene uno de los siguientes síntomas, entonces es probable que sea un problema de hardware (como memória, placa madre, CPU, o disco duro), o un problema del núcleo del sistema operativo:
El teclado no funciona. Esta anomalía puede comprobarse normalmente pulsando la tecla Bloq Mayus (Caps Lock). Si la luz de bloqueo de mayúsculas no se enciende, debería cambiar su teclado. (Antes de hacer esto, debería intentar reiniciar la máquina y comprobar todo el cableado del teclado).
El puntero del ratón no se mueve.
La máquina no responde a pings de máquinas remotas.
Otros programas que no están relacionados con MySQL no se comportan correctamente.
El sistema se reinició inesperadamente. (Un programa de nivel de usuario defectuoso nunca debería ser capaz de hacer caer el sistema.)
En este caso, debería comenzar por comprobar todos los cables y ejecutar
alguna herramienta de diagnóstico para comprobar el hardware. Debería también
comprobar si hay algún parche, actualización, o paquetes de servicio
para su sistema operativo que podría resolver su problema. Compruebe también
que todas las librerías (tales como glibc) están actualizadas.
Siempre es bueno utilizar una máquina con memoria ECC para descubrir los problemas de memoria lo antes posible.
Si el teclado está bloqueado, debería ser capaz de recuperarlo
conectándose a su máquina desde otra y ejecutando kbd_mode -a.
Por favor, examine su archivo de registro del sistema
(/var/log/messages o similar) para encontrar
motivos de su problema. Si piensa que el problema está en MySQL, también
debería revisar los archivos de registro de MySQL. Consulte
Sección 5.10, “Los ficheros de registro (log) de MySQL”.
Si no cree que tenga problemas de hardware, debería intentar encontrar el programa que le está casuando problemas. Intente utilizar los programas top, ps, el Administrador de Tareas, o algún programa similar, para comprobar cual de los procesos que se están ejecutando está monopolizando la CPU o bloqueando la máquina.
Utilice top, df, o un programa similar para comprobar si se está quedando sin memoria, espacio en disco, descriptores de archivo, o algún otro recurso crítico.
Si el problema es algún proceso desbocado, siempre puede intentar matarlo. Si no quiere morir, probablemente exista algún error en el sistema operativo.
Si tras haber examinado el resto de posibilidades y llega a la conclusión de que el servidor o el cliente MySQL puedan estar causando el problema, es el momento de crear un informe de fallos para nuestra lista de correos o equipo de soporte. En el informe, intente dar una descripción muy detallada de como el sistema se está comportando y qué es lo que usted cree que está sucediendo. También debería explicar por qué cree que MySQL está causando el problema. Tenga en cuenta todas los puntos de este capítulo. Explique cualqiuer problema de la maenra exacta como aparecen cuando usted examina su sistema. Utilice el método de “copiar y pegar” para enviar cualquier salida o mensaje de error de los programas o archivos de registro.
Intente explicar con detalle qué programa no está funcionando y los síntomas que usted ve. En el pasado, hemos recibido muchos informes de error que únicamente decían “el sistema no funciona.” Esto no nos da mucha información sobre cual pueda ser el problema.
Si un programa falla, siempre es útil saber lo siguiente:
¿Ha hecho el programa en cuestión un fallo de segmentación?
¿El programa está ocupando todo el tiempo disponible de CPU? Compruébelo con top. Deje el programa ejecutarse durante unos instantes, podría ser simplemente que está haciendo algunos cálculos intensivos.
Si el servidor mysqld está causando problemas, ¿puede usted obtener algún tipo de respuesta de él con mysqladmin -u root ping o mysqladmin -u root processlist?
¿Qué dicen los programas cliente cuando intenta conectarse al servidor MySQL? (Inténtelo con mysql, por ejemplo.) ¿Funciona el cliente? ¿Consigue algún tipo de respuesta desde el cliente?
Al enviar un informe de fallo, usted debe seguir el borrador descrito en Sección 1.6.1.2, “Hacer preguntas y reportar bugs”.
Access deniedCan't connect to [local] MySQL serverClient does not support authentication protocolLa máquina 'host_name' está bloqueadaDemasiadas conexionesOut of memoryMySQL se ha apagadoPacket too largeThe table is fullCan't create/write to fileCommands out of syncIgnoring userTable 'nombre_de_tabla' doesn't existCan't initialize character setEsta sección enumera algunos errores que los usuarios encuentran de manera frecuente cuando ejecutan programas MySQL. Aunque los problemas se muestran cuando intenta ejecutar programas cliente, las soluciones a muchos de los problems pasan por cambios en la configuración del servidor MySQL.
Un error de Acceso denegado puede tener muchas causas.
Frecuentemente el problema está relacionado con las cuentas MySQL a las
que el servidor deja que se conecten los programas cliente. Consulte
Sección 5.6.8, “Causas de errores Access denied”. Consulte Sección 5.6.2, “Cómo funciona el sistema de privilegios”.
Un cliente MySQL en Unix puede conectarse al servidor
mysqld de dos maneras diferentes: Utilizando un archivo
socket de Unix para conectarse a través de un archivo en el sistema de
ficheros (por defecto /tmp/mysql.sock), o utilizando
TCP/IP, que se conecta a través de un número de puerto. Una conexión
a través de archivo socket de Unix es más rápida que a través de TCP/IP,
pero solo puede ser utilizada cuando se conecta a un servidor en la misma
máquina. Se utiliza un archivo de socket Unix siempre que no se especifique
un nombre de servidor o si se especifica el nombre de servidor especial
localhost.
Si el servidor MySQL está ejecutándose en Windows 9x o Me, puede
conectarse únicamente a través de TCP/IP. Si el servidor se está ejecutando
sobre Windows NT, 2000, XP, o 2003 y ha sido iniciado con la opción
--enable-named-pipe, puede también conectarse a través
de named pipes si el cliente se está ejecutando en la misma máquina que
el servidor. El nombre de la named pipe es por defecto
MySQL. Si no se especifica un nombre de servidor
al conectar a mysqld, un cliente MySQL intenta primero
conectarse a la named pipe. Si esto no funciona, se conecta al puerto
TCP/IP. Usted puede forzar la utilizaciónde named pipes en windows utilizando
. como el nombre de servidor.
hostname.
El error (2002) Can't connect to ... normalmente
significa que no hay un servidor MySQL ejecutándose en el sistema o
que usted está especificando un archivo de socket Unix o número de puerto TCP/IP
al intentar conectarse al servidor.
Comience por comprobar si hay un proceso llamado mysqld ejecutándose en el servidor. (Utilice ps xa | grep mysqld en Unix o el Administrador de tareas en Windows). Si no existe ese proceso, debería iniciar el servidor. Consulte Sección 2.9.2.3, “Arrancar y resolver problemas del servidor MySQL”.
Si hay un proceso mysqld ejecutándose, puede comprobarlo
ejecutando los siguientes comandos. El número de puerto o nombre del archivo
socket de Unix pueden ser diferentes en su configuración.
host_ip representa el número de IP de la máquina
donde se está ejecutando el servidor.represents the IP number of the
machine where the server is running.
shell> mysqladmin version shell> mysqladmin variables shell> mysqladmin -h `hostname` version variables shell> mysqladmin -h `hostname` --port=3306 version shell> mysqladmin -h host_ip version shell> mysqladmin --protocol=socket --socket=/tmp/mysql.sock version
Tenga en cuenta la utilización de acentos abiertos en vez de comillas en
el comando hostname; esto provoca que la salida
de hostname (es decir, el nombre de máquina actual)
sea sustituida en el comando mysqladmin. Si no tiene
ningún comando hostname o está ejecutando sobre
Windows, puede escribir manualmente el nombre de su máquina (sin acentos
abiertos) tra la opción -h. También puede intentarlo
con -h 127.0.0.1 para conectarse con TCP/IP a la máquina
local.
Aquí hay algunas razones por las que el error
Can't connect to local MySQL server podría ocurrir:
mysqld no se está ejecutando. Compruebe la lista de procesos de sus sistema operativo para asegurarse de que el proceso mysqld está presente.
Usted está ejecutando un sistema que utiliza hilos tipo MIT-pthreads. Si está ejecutando un sistema que no tiene hilos antivos, mysqld utiliza el paquete de MIT-pthreads package. Consulte Sección 2.1.1, “Sistemas operativos que MySQL soporta”. Aún así, no todas las versiones de MIT-pthreads soportan los archivos socket de Unix. En un sistema sin soporte para archivos socket, siempre debe especificar el nombre de máquina explícitamente cuando se conecte al servidor. Intente utilizar este comando para comprobar la conexión con el servidor:
shell> mysqladmin -h `hostname` version
Alguien ha borrado el archivo socket de Unix que
mysqld utiliza
(/tmp/mysql.sock por defecto). Por ejemplo,
usted podría tener un trabajo de cron que elimine
los archivos antiguos del directorio /tmp. Siempre
puede ejecutar mysqladmin version para comprobar
si el archivo socket de Unix que to check whether the Unix socket file that
mysqladmin está intentando utilizar existe realmente.
La solución en este caso es cambiar el trabajo de
cron para que no elimine
mysql.sock o colocar el archivo socket en algún
otro lugar. Consulte Sección A.4.5, “Cómo proteger o cambiar el fichero socket de MySQL /tmp/mysql.sock”.
Usted ha iniciado el servidor mysqld con la opción
--socket=/path/to/socket, pero ha olvidado decirle
al programa cliente el nuevo nombre del archivo socket. Si cambia
la ruta del socket en el servidor, también tiene que notificárselo a los
programas cliente. Puede hacer esto proporcionándole al cliente la
misma opción --socket al ejecutarlo. También debe
asegurarse de que los programas cliente tienen permiso para acceder
al archivo mysql.sock. Para averiguar donde está
almacenado el archivo, puede hacer:
shell> netstat -ln | grep mysql
Consulte Sección A.4.5, “Cómo proteger o cambiar el fichero socket de MySQL /tmp/mysql.sock”.
Usted está ejecutando Linux y un hilo del servidor ha muerto (volcado
de memoria). En este caso, usted debe matar el resto de hilos de
mysqld (por ejemplo, con kill
o con el script mysql_zap) antes de que pueda
reiniciar el servidor MySQL. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”.
El servidor o el programa cliente podrían no tener los privilegios
de acceso adecuados para el directorio que almacena el archivo socket
de Unix, o para el archivo mismo. En este caso, usted debe cambiar
los privilegios del directorio o los del archivo mismo para que el servidor
y los clientes puedan acceder a ellos, o reiniciar mysqld
con una opción --socket que especifique un nombre
de archivo de socket en un directorio donde el servidor pueda crearlo
y los programas cliente puedan acceder a él.
Si usted obtiene el mensaje de error Can't connect to MySQL
server on some_host, puede intentar los siguientes procedimientos
para averiguar cual es el problema:
Compruebe si el servidor se está ejecutando en esa máquina mediante
la ejecución de telnet some_host 3306 y presionando
la tecla Enter unas cuantas veces. (3306 es el puerto por defecto de MySQL.
Cambie el valor si su servidor está escuchando en un puerto diferente.)
Si hay un servidor MySQL ejecutándose y escuchando al puerto, debería
obtener una respuesta que incluyera el número de versión del servidor.
Si obtiene un error como telnet: Unable to connect to
remote host: Connection refused, entonces no hay ningún
servidor ejecutándose en el puerto dado.
Si el servidor está ejecutándose en la máquina local, intente utilizar
mysqladmin -h localhost variables para conectar
utilizando el archivo socket de Unix. Colmpruebe el número de puerto
TCP/IP al que el servidor está configurado para escuchar (es el valor
de la variable port.)
Asegúrese de que su servidor mysqld no fue iniciado
utilizando la opción --skip-networking. Si lo fue
no puede conectarse a él utilizando TCP/IP.
Compruebe que no hay un cortafuegos bloqueando el acceso a MySQL. Aplicaciones como ZoneAlarm o el cortafuegos personal de Windows XP podría necesitar ser configurados para permitir el acceso externo a un servidor MySQL.
Las versiones de MySQL número 4.1 y superiores utilizan un protocolo de autentificación basado en un algoritmo de hash de la clave que es incompatible con el que se utiliza en los clientes anteriores. Si actualiza su servidor a 4.1, los intentos de conectarse a él desde un cliente más viejo pueden fallar con el siguiente mensaje:
shell> mysql Client does not support authentication protocol requested by server; consider upgrading MySQL client
Para resolver este problema, debería utilizar alguno de los siguientes métodos:
Actualizar todos los programas clientes para que utilicen la librería de cliente 4.1.1 o posterior.
Cuando se conecte al servidor con un programa cliente anterior al 4.1, utilice una cuenta que todavía mantenga una clave al estilo pre-4.1.
Reestablezca la clave al estilo pre-4.1 para cada usuario que necesite
utilizar un programa cliente anterior a la versión 4.1. Esto puede hacerse
utilizando la sentencia SET PASSWORD y la función
OLD_PASSWORD():
mysql> SET PASSWORD FOR
-> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');
Una alternativa es utilizar UPDATE y
FLUSH PRIVILEGES:
mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd')
-> WHERE Host = 'some_host' AND User = 'some_user';
mysql> FLUSH PRIVILEGES;
Sustituya la clave que quiera utilizar por
“newpwd” en los ejemplos precedentes.
MySQL no puede retornar la clave original, así que es necesario introducir
una clave nueva.
Indique al servidor que utilice el algoritmo de hashing de claves antiguo:
Inicie mysqld con la opción
--old-passwords.
Asigne una clave con formato antiguo a cada cuenta que tenga su clave actualizada al formato más largo de la versión 4.1. Puede identificar estas cuentas con la siguiente consulta:
mysql> SELECT Host, User, Password FROM mysql.user
-> WHERE LENGTH(Password) > 16;
Para cada registro de cuentas que se muestre en la consulta, utilice
los valores de Host y User
y asigne una clave utilizando la función OLD_PASSWORD()
y SET PASSWORD o
UPDATE, tal como se ha explicado previamente.
Nota: En PHP, la extensión
mysql no soporta el nuevo protocolo de autentificación
en MySQL 4.1.1 y superior. Esto es así independientemente de la versión de PHP
utilizada. Si desea poder utilizar la extensión mysql
con MySQL 4.1 seguir alguna de las indicaciones explicadas arriba para
configurar MySQL con clientes antiguos. La extensión mysqli
(que significa "MySQL mejorado" - "MySQL Improved"; nueva en PHP 5)
es compatible con el nuevo algoritmo de hashing mejorado
empleado en MySQL 4.1 y superiores, y sin ninguna configuración especial
necesaria que deba hacerse para utilizar esta nueva librería cliente de MySQL
para PHP. Para más información sobre la extensión mysqli
consulte http://php.net/mysqli.
For additional background on password hashing and authentication, Consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1”.
Los programas cliente de MySQL piden una contraseña cuando son invocados
con la opción --password o -p sin especificar
ningún valor para la contraseña:
shell> mysql -u user_name -p
Enter password:
En algunos sistemas, puede ocurrir que su contraseña funcione cuando es especificada en un archivo de opciones o en la línea de comandos, pero no cuando sea introducida interactivamente en la línea de comandos. Esto ocurre cuando la librería proveida por el sistema para leer contraseñas limite los valores de éstas a un número pequeño de caracteres (normalmente ocho). Eso es un problema con la librería del sistema, no con MySQL. Para poder solucionarlo, cambie su contraseña de MySQL a un valor que sea de ocho o menos caracteres de longitud, o ponga su constraseña en un archivo de opciones.
Si obtiene el siguiente error, significa que mysqld
ha recibido demasiados intentos de conexión desde la máquina
'
que han sido interrumpidos:
host_name'
Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
El número de intentos de conexión interrumpidos se puede determinar con
el valor de la variable de sistema max_connect_errors.
Tras max_connect_errors intentos fallidos,
mysqld asume que hay algo que va mal (por ejemplo, que
alguien está intentando romper la seguridad del sistema), y bloquea la máquina
para que no pueda intentar volver a conectarse hasta que usted ejecute el comando
mysqladmin flush-hosts o introduzca la sentencia
FLUSH HOSTS. Consulte Sección 5.3.3, “Variables de sistema del servidor”.
Por defecto, mysqld bloquea una máquina tras 10 errores de conexión. Puede ajustar el valor iniciando el servidor así:
shell> mysqld_safe --max_connect_errors=10000 &
Si usted obtiene este mensaje de error para una máquina concreta, debería
primero averiguar que no hay ningún problema con las conexiones TCP/IP desde esa
máquina. Si está teniendo problemas de red, no hace ningún bien el incrementar
el valor de la variable max_connect_errors.
Si obtiene un error Too many connections cuando intenta conectarse
al servidor mysqld, significa que todas las conexiones
disponibles están siendo utilizadas por otros clientes.
El número de conexiones permitidas está controlado por la variable de sistema
max_connections. Su valor por defecto es 100. Si necesita soportar
más conexiones, debería reiniciar mysqld con un valor más grande
de esta variable.
mysqld realmente permite conectarse a
max_connections+1 clientes. La conexión extra esta reservada
para ser utilizada por cuentas que tienen el privilegio SUPER.
Otorgando el privilegio SUPER a los administradores y no a usuarios
normales (que no deberían necesitarlo), un administrador puede conectarse al servidor y
utilizar SHOW PROCESSLIST para diagnosticar problemas aún cuando
el máximo número de clientes sin privilegios estén conectados.
Consulte Sección 13.5.4.16, “Sintaxis de SHOW PROCESSLIST”.
El número máximo de conexiones que MySQL puede soportar depende de la calidad de la librería de hilos de una plataforma dada. Linux o Solaris deberían ser capaces de soportar 500-1000 conexiones simultáneas, dependiendo de cuanta RAM tenga y que estén haciendo los clientes. Los binarios estáticos de Linux proveidos por MySQL AB pueden soportar hasta 4000 conexiones.
Si usted ejecuta una consulta utilizando el programa cliente mysql y recibe un error como el siguiente, significa que mysql no tiene suficiente memoria para almacenar el resultado completo de la consulta:
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
Para remediarlo, primero compruebe si su consulta es correcta. ¿Es razonable que
devuelva tantas filas? Si no, corríjala y inténtelo de nuevo. Si no es así, puede
invocar mysql con la opción --quick. Esto provoca
que utilice la función mysql_use_result() de la API C para obtener
el resultado, lo que hace que haya menos carga en el cliente (pero más en el servidor).
Esta sección también explica el error relacionado
Lost connection to server during query.
La razón más común para el error MySQL server has gone
away es que el servidor ha agotado el tiempo de espera
y ha cerrado la conexión. En este caso, normalmente obtendrá uno de los
siguientes códigos de error (dependiendo del sistema operativo):
| Código de error | Descripción |
CR_SERVER_GONE_ERROR | El cliente no pudo enviar una consulta al servidor. |
CR_SERVER_LOST | El cliente no obtuvo ningún error al escribir al servidor pero tampoco obtuvo una respuesta completa (o ninguna respuesta) a la pregunta. |
Por defecto, el servidor cierra la conexión tras ocho horas si no
pasa nada. Puede cambiar el límite de tiempo estableciendo la variable
wait_timeout cuadno inicie mysqld
Consulte Sección 5.3.3, “Variables de sistema del servidor”.
Si usted tiene un script, tiene que ejecutar la consulta de nuevo
para que el cliente haga una reconexión automática. Esto da por hecho
que tiene la reconexión automática activada en el cliente (que es la opción por
defecto en el cliente de línea de comandos mysql).
Otras razones comunes por las que puede aparecer el error MySQL server has gone
away son:
Usted (o el administrador de la base de datos) ha matado el hilo que se estaba
ejecutando con una sentencia KILL o el comando
mysqladmin kill.
Usted ha intentado ejecutar una sentencia tras cerrar la conexión con el servidor. Esto es síntoma de un error lógico en la aplicación que debería ser corregido.
Se ha agotado el tiempo de espera de una conexión TCP/IP desde el lado cliente. Esto puede
ocurrir si usted ha estado utilizando los comandos:
mysql_options(...,
MYSQL_OPT_READ_TIMEOUT,...) o
mysql_options(...,
MYSQL_OPT_WRITE_TIMEOUT,...). En este caso, aumentar el tiempo de espera
puede ayudar a resolver el problema.
Se ha agotado el tiempo de espera en el lado del servidor, y el cliente no tiene
activada la opción de reconexión automática (la opción reconnect en la
estructura MYSQL es igual a 0).
Usted está utilizando un cliente windows y el servidor ha cortado la conexión (probablemente
porque wait_timeout ha expirado) antes de que el comando fuese ejecutado.
El problema en windows es que en algunos casos MySQL no obtiene un error desde el SO cuando escribe a la conexión TCP/IP desde el servidor, sino que obtiene el error cuando intenta leer la respuesta desde la conexión.
En este caso, aunque el flag reconnect en la estructura
MYSQL sea igual a 1, MySQL no reconecta y vuelve a ejecutar
la sentencia, ya que no sabe si el servidor recibió la sentencia original o no.
La solución a esto es o hacer un mysql_ping en la conexión si ha pasado
mucho tiempo desde la última sentencia (esto es lo que MyODBC hace) o
establecer un wait_timeout en el servidor mysqld
tan alto que en la práctica, nunca llegue a sobrepasarse.
También puede obtener estos errores si envía una consulta al servidor que sea incorrecta
o demasiado grande. Si mysqld recibe un paquete que es demasiado
grande o fuera de lugar, asume que ha habido algún error con el cliente y cierra la
conexión. Si necesita realizar grances consultas (por ejemplo, si está trabajando con
columnas BLOB muy grandes), debería incrementar el límite de las consultas
estableciendo la variable de servidor max_allowed_packet, que tiene un valor
por defecto de 1MB. También podría necesitar incrementar el tamaño máximo de paquete en el
lado cliente. Puede encontrar más información para establecer el tamaño de paquete en
Sección A.2.9, “Packet too large”.
También puede perder la conexión si envía un paquete de más de 16MB y su cliente es anterior a la versión 4.0.8 y su servidor posterior a 4.0.8, o viceversa.
También puede ver el error MySQL server has gone
away si MySQL se inicia con la opción --skip-networking.
Ha encontrado un error por el que el servidor cayó mientas ejecutaba una sentencia.
Puede comprobar si el servidor MySQL cayó y se reinició ejecutando mysqladmin version y examinando el tiempo de ejecución del servidor (uptime). Si la conexión del cliente se cortó debido a que mysqld falló y se reninicó, debería intentar encontrar la razón del fallo. Comience por comprobar si ejecutando la misma sentencia el servidor cae de nuevo. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”.
Puede obtener más información sobre las conexiones perdidas iniciando mysqld con la
opción --log-warnings=2. Esto registra algunos de los errores de
desconexión en el archivo hostname.err. Consulte Sección 5.10.1, “El registro de errroes (Error Log)”.
Si quiere crear un informe de error en relación a este problema, asegúrese de incluir la siguiente información:
Indique si el servidor MySQL murió. Puede enecontrar esta información en el registro de errores del servidor. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”.
Si una consulta específica mata a mysqld y las tablas implicadas habían sido
comprobadas con CHECK TABLE antes de ejecutar la consulta, ¿puede proporcionar
una prueba que permita reproducir el caso? Consulte Sección D.1.6, “Crear un caso de prueba tras haber encontrado una tabla corrupta”.
¿Cual es el valor de la variable de sistema wait_timeout en el
servidor MySQL? (mysqladmin variables le da el valor de esta variable.)
Ha intentado ejecutar mysqld con la opción --log
para determinar si la consulta problemática aparece en el registro?
Consulte también Sección A.2.10, “Errores de comunicación y conexiones abortadas”.
Consulte Sección 1.6.1.2, “Hacer preguntas y reportar bugs”.
Un paquete de comunicación es una única sentencia SQL enviada al servidor MySQL o una única fila que es enviada al cliente.
En MySQL 3.23, el páquete más grande posible es de 16MB, debido a los límites del protocolo cliente/servidor. En MySQL 4.0.1 y superiores, el límite es de 1GB.
Cuando un cliente MySQL o el servidor mysqld recibe un paquete más grande
de max_allowed_packet bytes, este devuelve un error
Packet too large y cierra la conexión. Con algunos clientes, también
podría obtener un error Lost connection to MySQL server during query si el
paquete de comunicación es demasiado grande.
Tanto el cliente como el servidor tienen su propia variable max_allowed_packet
así que si quiere gestionar paquetes grandes, debe aumentar esta variable tanto en el cliente como
en el servidor.
Si está utilizando el programa cliente mysql, el valor por defecto de la
variable max_allowed_packet es de 16MB. Este es también el máximo valor permitido
anteriormente a la versión MySQL 4.0. Para establecer un valor mayor desde 4.0 en adelante, inicie
mysql de la siguiente manera:
mysql> mysql --max_allowed_packet=32M
Esto establece el tamaño del paquete en 32MB.
El valor por defecto de la variable max_allowed_packet en el servidor es de 1MB.
Pue incrementar esto si el servidor necesita gestionar consultas grandes (por ejemplo, si está trabajando
con columnas BLOB grandes). Por ejemplo, para establecer la variable a 16MB, inicie el
servidor así:
mysql> mysqld --max_allowed_packet=16M
Para versiones previas a MySQL 4.0, utilice esta sintaxis:
mysql> mysqld --set-variable=max_allowed_packet=16M
También puede utilizar un archivo de opciones para establecer max_allowed_packet.
Por ejemplo, para establecer el valor para el servidor en 16MB, añada las siguientes líneas en su
archivo de opciones:
[mysqld] max_allowed_packet=16M
Para versiones previas a MySQL 4.0, utilice esta sintaxis:
[mysqld] set-variable = max_allowed_packet=16M
Es seguro incrementar el valor de esta variable porque la memoria extra tan solo es utilizada cuando se necesite. Por ejemplo, mysqld solo ocupa más memoria cuando usted ejecuta una consulta grande o cuando mysqld debe retornar una fila de resultados grande. El valor por defecto pequeño en la variable, es una precaución para atrapar paquetes incorrectos entre el cliente y el servidor, y también para asegurarse de que usted no se queda sin memoria al utilizar paquetes grandes de manera accidental.
También puede sufrir problemas extraños con paquetes grandes si está utilizando valores
BLOB grandes pero no ha dado a mysqld acceso a suficiente memoria
para gestionar la consulta. Si sospecha que este es el caso, intente añadir
ulimit -d 256000 al principio del script mysqld_safe
y reinicie mysqld.
El registro de errores del servidor puede ser una fuente de información útil
sobre problemas de conexión. Consulte Sección 5.10.1, “El registro de errroes (Error Log)”. A partir de MySQl 3.23.40,
si quiere iniciar el servidor con la opción --warnings (o
--log-warnings desde MySQl 4.0.3 en adelante), usted podría encontrar
mensajes como este en su registro de errores:
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
Si un mensaje Aborted connections aparece en el registro de errores, la causa
puede ser alguna de las siguientes:
El programa cliente no llamó a mysql_close() antes de salir.
El cliente ha estado inactivo más de wait_timeout o
interactive_timeout segundos, sin enviar ninguna petición al servidor. Consulte
Sección 5.3.3, “Variables de sistema del servidor”.
El programa cliente abortó de manera abrupta en mitad de una transferencia de datos.
Cuando alguna de estas cosas pasa, el servidor incrementa la variable de estado Aborted_clients.
El servidor incrementa la variable de estado Aborted_connects
cuando una de las siguientes cosas ocurren:
Un cliente no tiene privilegios para conectar a una base de datos.
Un cliente utiliza una contraseña incorrecta.
Un paquete de conexión no contiene la información correcta.
Se tarda más de connect_timeout en obtener un paqueta de conexión. Consulte
Sección 5.3.3, “Variables de sistema del servidor”.
Si este tipo de cosas pasan, ¡podría ser indicativo de que alguien está intentando entrar en su servidor!
Otros motivos para los problemas con clientes que abortan o conexiones interrumpidas:
Utilización del protocolo Ethernet con Linux, tanto en half como en full duplex. Muchos drivers de Ethernet en Linux tienen este error. Debería comprobar si su driver contiene este error transfiriendo un archivo enorme via FTP entre el cliente y el servidor. Si la transferencia entra en un modo de ejecución-pausa-ejecución-pausa, usted está experimentando el síndrome duplex de Linux. La única solución es cambiar el modo duplex tanto de su tarjeta de red como de su concentrador o switch tanto a full como a half duplex, y comprobar los resultados para determinar la mejor configuración.
Algunos problemas con la librería de hilos de ejecución que causa interrupciones en las lecturas.
TCP/IP mal configurado.
Redes, concentradores, switches o cables defectuosos. Esto solo puede ser diagnosticado mediante el reemplazo de hardware.
El valor de la variable max_allowed_packet es demasiado pequeño o las consultas requieren
más memoria de la que tiene disponible para mysqld. Consulte Sección A.2.9, “Packet too large”.
Consulte también Sección A.2.8, “MySQL se ha apagado”.
Hay varias maneras en que puede producirse un error de tabla llena:
Cuando utiliza un servidor MySQL anterior a la versión 3.23 y una tabla temporal en memoria
se hace más grande de tmp_table_size bytes. Para evitar este problema puede utilizar
la opción -O tmp_table_size=# para hacer que mysqld
incremente el valor temporal del tamaño de tablas, o utilizar la opción SQL_BIG_TABLES
antes de ejecutar la consulta problemática. Consulte
Sección 13.5.3, “Sintaxis de SET”.
También puede iniciar mysqld con la opción --big-tables. Esto es
exactamente lo mismo que utilizar la opción SQL_BIG_TABLES para todas las consultas.
A partir de MySQL 3.23, este problema no debería ocurrir. Si una tabla
en memoria se hace más grande que tmp_table_size, el servidor automáticamente
la convierte en una tabla de disco MyISAM.
Está utilizando tablas InnoDB y se quedó sin espacio en el espacio de tablas
InnoDB. En este caso, la solución es aumentar el espacio de tablas InnoDB.
Consulte Sección 15.7, “Añadir y suprimir registros y ficheros de datos InnoDB”.
Está utilizando tablas ISAM o MyISAM en un sistema operativo que
tan solo soporta hasta 2GB de tamaño de archivo, habiendo superado ya este límite para el archivo de datos o de índices.
Está utilizando una tabla MyISAM, y el espacio requerido por la tabla excede a lo que permite
el tamaño de puntero interno. Si no especifica la opción de tabla MAX_ROWS cuando cree una tabla,
MySQL utiliza la variable de sistema myisam_data_pointer_size. Desde MySQL 5.0.6 en adelante,
el valor por defecto es de 6 bytes, que es suficiente para permitir 65536 TB de datos. Antes de MySQL 5.0.6, el valor
por defecto es de 4 bytes, que solo es suficiente para permitir 4 GB de datos. Consulte Sección 5.3.3, “Variables de sistema del servidor”.
Puede comprobar los tamaños máximos de datos e índices mediante esta consulta:
SHOW TABLE STATUS FROM database LIKE 'nombre_tabla';
También puede utilizar myisamchk -dv /ruta/a/archivo-indice-de-tabla.
Si el tamaño del puntero es demasiado pequeño, puede corregir el problema utilizando ALTER TABLE:
ALTER TABLEnombre_tablaMAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
Tiene que especificar AVG_ROW_LENGTH solo para tablas con columnas
BLOB o TEXT; en este caso, MySQL no puede optimizar el espacio
requerido basándose únicamente en el número de filas.
Si obtiene un error del siguiente tipo en algunas consultas, significa que MySQL no puede crear un archivo temporal para el conjunto de resultados en el directorio temporal:
Can't create/write to file '\\sqla3fe_0.ism'.
El error anterior es un mensaje típico para Windows; el mensaje de Unix es similar.
Una solución es iniciar mysqld con la opción --tmpdir
o añadir la opción a la sección [mysqld] de su archivo de opciones. Por ejemplo, para especificar
el directorio C:\temp, utilice estas líneas:
[mysqld] tmpdir=C:/temp
El directorio C:\temp debe existir y tener suficiente espacio para que el
servidor MySQL escriba en él. Consulte Sección 4.3.2, “Usar ficheros de opciones”.
Otra causa de este error pueden ser temas de permisos. Asegúrese de que el servidor MySQL puede
escribir en el directorio tmpdir.
Compruebe también el código de error que obtiene con perror. Una razón por la que el servidor puede no escribir en una tabla es que el sistema de archivos esté lleno:
shell> perror 28 Error code 28: No space left on device
Si botiene un error Commands out of sync; you can't run this
command now en su código de cliente, está llamando a las funciones cliente en orden erróneo.
Esto puede pasar, por ejemplo, si está utilizando mysql_use_result()
e intenta ejecutar una nueva consulta antes de llamar a mysql_free_result().
También puede pasar si intenta ejecutar dos consultas que retornan datos sin llamar a
mysql_use_result() o mysql_store_result() entre ellas.
Si obtiene el siguiente error, significa que cuando se inició mysqld
o cuando recargó las tablas de privilegios, encontró una cuenta en la tabla user
que tenía una contraseña no válida.
Found wrong password for user
'
un_usuario'@'un_host';
ignoring user
Como resultado, la cuenta es sencillamente ignorada por el sistema de privilegios.
La siguiente lista indica posibles causas de este problema, y algunas soluciones:
Quizá está ejecutando una versión nueva de mysqld con una tabla user vieja.
Puede comprobar esto ejecutando el comando mysqlshow mysql user para ver si la columna
Password es más corta de 16 caracteres. Si es así, puede corregir esta condición ejecutando el script
scripts/add_long_password.
La cuenta tiene una contraseña antigua (de ocho caracteres de longitud) y no inició el servidor
mysqld con la opción --old-protocol.
Actualice la cuenta en la tabla user para que tenga una nueva contraseña, o reinicie
mysqld con la opción --old-protocol.
Ha especificado una contraseña en la tabla user sin utilizar la función PASSWORD().
Utilice mysql para actualizar la cuenta en la tabla user con una nueva contraseña
asegurándose de utilizar la función PASSWORD():
mysql> UPDATE user SET Password=PASSWORD('nuevopwd')
-> WHERE User='usuario' AND Host='maquina';
If you get either of the following errors, it usually means that no table exists in the current database with the given name:
Table 'nombre_de_tabla' doesn't exist Can't find file: 'nombre_de_tabla' (errno: 2)
En algunos casos, puede ser que la tabla no exista porque usted se esté refiriendo a ella incorrectamente:
Debido a que MySQL utiliza directorios y archivos para almacenar bases de datos y tablas, los nombres de bases de datos y tablas son sensibles a las letras mayúsculas si se encuentran en un sistema de archivos que lo sea.
Aún en los sistemas de archivo que no son sensibles a la diferencia entre minúscula y mayúscula, como en Windows, todas las referencias a una tabla dada deben utilizar el mismo tipo de letra.
Puede comprobar las tablas que hay en la base de datos actual con
SHOW TABLES. Consulte Sección 13.5.4, “Sintaxis de SHOW”.
Si tiene problemas con los juegos de caracteres, puede obtener un error como este:
MySQL Connection Failed: Can't initialize character set charset_name
Este error puede tener una de las siguientes causas:
El juego de caracteres es un juego multi-byte, y no tiene soporte para ese juego de caracteres en el cliente.
En este caso, necesita recompilar el cliente ejecutando
configure con la opción --with-charset=
o charset_name--with-extra-charsets=. Consulte Sección 2.8.2, “Opciones típicas de configure”.
charset_name
Todos los binarios estándard MySQL se compilan con --with-extra-character-sets=complex, que
activa el soporte para los juegos de carácter multi-byte. Consulte
Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.
El juego de caracteres es un juego simple que no está compilado en mysqld, y el archivo de definición de juegos de caracteres no está en el lugar que el cliente espera encontrarlo.
En este caso, necesita utilizar uno de los siguientes métodos para resolver el problema:
Recompile el cliente con soporte para el juego de caracteres. Consulte Sección 2.8.2, “Opciones típicas de configure”.
Especifique al cliente el directorio donde la definición del juego de caraceres tiene sus archivos. En muchos clientes
puede hacerlo con la opción --character-sets-dir.
Copie los archivos de definición de caracteres a la ruta donde el cliente espera que estén.
Si obtiene ERROR '...' not found (errno: 23),
Can't open file: ... (errno: 24), o cualquier otro error con errno 23 o errno
24 de MySQL, significa que no tiene reservados suficientes descriptores de archivo para el servidor MySQL.
Puede utilizar la utilidad perror para obtener una descripción de lo que el número de error significa:
shell> perror 23 Error code 23: File table overflow shell> perror 24 Error code 24: Too many open files shell> perror 11 Error code 11: Resource temporarily unavailable
El problema aquí es que mysqld está intentando mantener abiertos demasiados archivos de manera simultánea. Puede decirle a mysqld que no abra tantos archivos a la vez, o incrementar el número de descriptores disponibles para mysqld.
Para decirle a mysqld que mantenga abiertos menos archivos de manera
simultánea, puede hacer la cache de la tabla mas pequeña reduciendo el valor de la variable
de sistema table_cache (el valor por defecto es 64). Reducir
el valor de max_connections también reduce el número de archivos
abiertos (el valor por defecto es 100).
Para cambiar el número de descriptores de archivo disponibles para
mysqld, puede utilizar la opción --open-files-limit
para mysqld_safe o (desde MySQL 3.23.30) establecer la variable de
sistema open_files_limit. Consulte
Sección 5.3.3, “Variables de sistema del servidor”. La manera más fácil de establecer estos valores
es añadir una opción a su archivo de opciones. Consulte Sección 4.3.2, “Usar ficheros de opciones”.
Si usted dispone de una versión antigua de mysqld que no soporta
el establecimiento del límite de archivos abiertos, puede editar el script
mysqld_safe. Hay una línea comentada en el script,
ulimit -n 256. Puede eliminar el carácter '#'
para descomentar esta línea, y cambiar el número 256 para establecer
el número de descriptores de archivos que serán puestos a disposición de
mysqld.
--open-files-limit y ulimit
pueden incrementar el número de descriptores de archivo, pero sólo hasta el límite
impuesto por el sistema operativo. Hay también un límite impuesto que puede ser
sobreseido sólo si inicia mysqld_safe o
mysqld como root (simplemente recuerde que
necesita iniciar el servidor con la opción --user en este caso
para que no continue ejecutándose como root tras el inicio).
Si usted necesita incrementar el límite del sistema operativo sobre el número de
descriptores de archivo disponibles para cada proceso, consulte la documentación de su
sistema operativo.
Nota: ¡Si usted ejecuta el shell tcsh, ulimit no funciona! tcsh también informa de valores incorrectos cuando le interroga por los límites actuales. En este caso, debería iniciar mysqld_safe utilizando sh.
Cuando usted enlaza un programa para utilizar la librería cliente de MySQL, usted podría
obtener errores de referencias no definidas para los símbolos que comiencen con
mysql_, tal como los que se muestran aquí:
/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'
Debería ser capaz de resolver este problema añadiento
-Ldir_path -lmysqlclient al final de su comando de enlace, donde
dir_path representa la ruta de el directorio donde la librería cliente
está situada. Para determinar el directorio correcto, utilice este comando:
shell> mysql_config --libs
La salida de mysql_config podría indicar otras librerías que deberían ser especificadas en el comando de enlace también.
Si obtiene errores de undefined reference en las funciones
uncompress o compress, intente añadir
-lz al final de su comando de enlace e intente de nuevo.
Si usted obtiene errores undefined reference para una función
que no deberían ocurrir en su sistema, tal como connect,
compruebe la página de la función en el manual y determine qué librerías debería
añadir para el comando de enlace.
Podría obtener errores undefined reference como el siguiente por las
funciones que no existen en su sistema:
mf_format.o(.text+0x201): undefined reference to `__lxstat'
Esto normalmente significa que su librería cliente MySQL fue compilada en un sistema que no es compatible al 100% con el suyo. En este caso, debería descargar la última distribución de código fuente de MySQL y compilar usted mismo MySQL. Consulte Sección 2.8, “Instalación de MySQL usando una distribución de código fuente”.
Podría obtener errores de referencia en tiempo de ejecución cuando intenta ejecutar
un programa MySQL. Si estos errores especifican símbolos que comienzan con
mysql_ o indican que la librería cliente
mysqlclient no puede encontrarse, significa que su sistema no
puede encontrar la librería compartida libmysqlclient.so.
La corrección para esto es decirle a su sistema que busque las librerías compartidas
donde estén situadas. Utilice aquel de los siguientes métodos que sea apropiedo para
su sistema:
Añada la ruta al direcotorio donde se encuentre libmysqlclient.so
a la variable de entorno LD_LIBRARY_PATH.
Añada la ruta al directorio donde libmysqlclient.so
se encuentra a la variable de entorno LD_LIBRARY.
Copie el archivo libmysqlclient.so a algún directorio de los
que su sistema busca, como por ejemplo /lib, y actualice
la información de la librería compartido ejecutando ldconfig.
Otra manera de resolver este problema es enlazando su programa de manera estática con la
opción -static, o eleminando las librería dinámicas MySQL antes de
enlazar su código. Antes de intentar el segundo método, usted debería asegurarse
de que ningún otro programa está utilizando las librerías dinámicas.
En Windows, usted puede ejecutar el servidor como un servicio de Windows utilizando cuentas de usuario normales a partir de MySQL 4.0.17 and 4.1.2. (Versiones más antiguas de MySQL requieren que usted tenga derechos de administrador. Eso fue un error introducido en MySQL 3.23.54.)
En Unix, el servidor MySQL mysqld puede iniciarse y ser ejecutado
por cualquier usuario. Aún así, usted debería evitar ejecutar el servidor como el usuario
Unix root, por razones de seguridad. Para ejecutar
mysqld como un usuario normal Unix sin privilegios
user_name, debe hacer lo siguiente:
Pare el servidor si se está ejecutando (utilice el comando mysqladmin shutdown).
Cambie los directorios de la base de datos y archivos, de manera que el usuario
user_name tenga privilegios para leer y escribir
archivos en ellos (podría necesitar hacerlo como usuario root
en Unix):
shell> chown -Ruser_name/path/to/mysql/datadir
Si no hace esto, el servidor no es capaz de acceder a bases de datos o tablas cuando se
ejecuta como user_name.
Si los directorios o archivos en el directorio de datos de MySQL son enlaces simbólicos,
necesitará también seguir estos enlaces y cambiar los directorios y archivos a los
que apuntan. Podría ser que chown -R no siguiera los enlaces por
usted.
Inicie el servidor como el usuario user_name. Si usted
está utilizando MySQL 3.22 o posterior, otra alternativa es iniciar
mysqld como usuario root de Unix
y utilizar la opción --user=.
mysqld se inicia, y entonces cambia la ejecución al usuario Unix user_nameuser_name antes de aceptar ninguna conexión.
Para iniciar al servidor como el usuario dado automáticamente al inicio del sistema,
especifique el nombre de usuario añadiendo una opción
user a el grupo [mysqld] del archivo de opciones
/etc/my.cnf o el archivo de opciones my.cnf
en el directorio de datos del servidor. Por ejemplo:
[mysqld]
user=user_name
Si su máquina Unix no es segura, debería asignar contraseñas a las cuentas
root de MySQL en las tablas de privilegios. De otra manera
cualquier usuario con una cuenta de entrada a su máquina podría ejecutar el cliente
mysql con una opción --user=root y realizar
cualquier operación.
(Es una buena idea asignar contraseñas a las cuentas MySQL en cualquier caso, pero
especialmente si existen otras cuentas de entrada en la máquina del servidor.)
Consulte Sección 2.9, “Puesta en marcha y comprobación después de la instalación”.
Si usted tiene problemas con los permisos de archivos, la variable de entorno
UMASK puede estar especificada de manera incorrecta al inicio de
mysqld. Por ejemplo, MySQL puede devolver el siguiente mensaje de error
al crear una tabla:
ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
El valor por defecto de UMASK es
0660. Ustee puede cambiar este comportamiento iniciando
mysqld_safe de la siguiente manera:
shell> UMASK=384 # = 600 en octal shell> export UMASK shell> mysqld_safe &
Por defecto, MySQL crea las bases de datos y directorios
RAID con un valor de permiso de acceso de 0700.
Usted puede modificar este comportamiento estableciendo la variable
UMASK_DIR. Si usted establece su valor, los nuevos directorios serán
creados con los valores combinados de UMASK y
UMASK_DIR. Por ejemplo, si usted quiere dar acceso de grupo a todos los
directorios nuevos, puede hacer eso:
shell> UMASK_DIR=504 # = 770 en octal shell> export UMASK_DIR shell> mysqld_safe &
En MySQL 3.23.25 y superiores, MySQL asume que el valor de UMASK y UMASK_DIR está en octal si comienza por cero.
Consulte Apéndice E, Variables de entorno.
/tmp/mysql.sock
Si nunca ha establecido una contraseña para el usuario root de MySQL,
el servidor no requiere ninguna contraseña para conectar como root. De
todas formas, se recomienda establecer una contraseña para cada cuenta. Consulte
Sección 5.5.1, “Guía de seguridad general”.
Si usted había establecido previamente una contraseña para el usuario root, pero ha olvidado cual era, puede establecer una nueva contraseña.
El siguiente procedimiento es para sistemas Windows. El procedimiento para sistemas Unix está descrito más adelante en esta sección.
El proceso bajo Windows: The procedure under Windows:
Entre en su sistema como Administrador.
Pare el servidor MySQL si se está ejecutando. Para servidores que se estén ejecutando como servicio de Windows, vaya al Gestor de Servicios:
Menú Inicio -> Panel de Control -> Herramientas administrativas -> Servicios
Después encuentre en la lista el servicio MySQL, y parelo.
Si su servidor no está ejecutándose como servicio, podría necesitar utilizar el Gestor de tareas para forzarlo a parar.
Cree un archivo de texto e introduzca el siguiente comando en él, en una única línea:
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MiNuevaContraseña');
Guarde el archivo con cualquier nombre. Para este ejemplo, el nombre del archivo será
C:\mysql-init.txt.
Abra una ventana de comandos para obtener una consola de comandos DOS:
Menú Inicio -> Ejecutar -> cmd
Asumiremos que usted tiene instalado MySQL en C:\mysql.
Si lo intaló en algún otro lugar, ajuste los siguientes comandos de manera adecuada.
En la línea de comandos DOS, ejecute esta orden:
C:\> C:\mysql\bin\mysqld-nt --init-file=C:\mysql-init.txt
Los contenidos del archivo nombrado por la opción --init-file
son ejecutados en el inicio del servidor, cambiando la contraseña de
root. Cuando el servidor se haya iniciado correctamente, debería
borrar el archivo C:\mysql-init.txt.
Los usuarios de MySQL 4.1 y superiores que instalen MySQL utilizando el instalador
de mySQL, pueden necesitar especificar una opción --defaults-file:
C:\> C:\Archivos de Programa\MySQL\MySQL Server 5.0\bin\mysqld-nt.exe
--defaults-file="C:\Archivos de Programa\MySQL\MySQL Server 5.0\my.ini"
--init-file=C:\mysql-init.txt
La configuración apropiada de --defaults-file puede encontrarse
utilizando el Gestor de Servicios:
Menú Inicio -> Panel de Control -> Herramientas Administrativas -> Servicios
Encuentre el servicio MySQL en la lista, pulse con el botón derecho del ratón, y
escoja la opción Propiedades. El campo
Ruta al Ejecutable contiene la configuración de --defaults-file.
Pare el servidor MySQL, y reinícielo en modo normal de nuevo. Si ejecuta el servidor como servicio, inícielo desde la ventana de servicios de Windows. Si ejecuta el servidor manualmente, utilice el comando que normalmente use.
Debería poder conectar utilizando la nueva contraseña.
En un entorno Unix, el procedimiento para restablecer la contraseña
root es el siguiente:
Entre en sus sitema como usuario Unix root o bien como el mismo
usuario que ejecuta el servidor mysqld.
Localice el archivo .pid que contiene el ID de proceso del
servidor. La localización exacta y el nombre de este archivo depende de su distribución,
nombre de máquina, y configuración. Lugares comunes son /var/lib/mysql/,
/var/run/mysqld/, y
/usr/local/mysql/data/.
Generalmente, el archivo tiene una extensión .pid y comienza
con mysqld o el nombre de su máquina.
Puede parar el servidor MySQL enviando un comando kill (no kill -9) a el proceso mysqld utilizando
la ruta del archivo .pid en el siguiente comando:
shell> kill `cat /mysql-data-directory/host_name.pid`
Nótese el uso de acentos abiertos en vez de comillas simples con el comando cat; estos causan que la salida de cat sea
sustituida en el comando kill.
Cree un archivo de texto e introduzca el siguiente comando en una única línea:
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MiNuevaContraseña');
Guarde el archivo con cualquier nombre. Para este ejemplo, el archivo tendrá el nombre
~/mysql-init.
Reinicie el servidor MySQL con la opción especial
--init-file=~/mysql-init:
shell> mysqld_safe --init-file=~/mysql-init &
Los contenidos del archivo son ejecutados al inicio del servidor, cambiando la
contraseña de root. Después de que el servidor se haya iniciado con éxito, debería
borrar ~/mysql-init.
Debería poder conectar utilizando la nueva contraseña.
Una alternativa, en cualquier plataforma, es establecer la nueva contraseña desde el cliente mysql (pero esta manera es menos segura):
Pare mysqld y reinícielo con la opción
--skip-grant-tables --user=root (Los usuarios de Windows deben
omitir la parte de --user=root).
Conecte al servidor mysqld con este comando:
shell> mysql -u root
Ejecute las siguientes sentencias en el cliente mysql:
mysql> UPDATE mysql.user SET Password=PASSWORD('nuevacontraseña')
-> WHERE User='root';
mysql> FLUSH PRIVILEGES;
Reemplace “nuevacontraseña”
con la contraseña de root real que quiere utilizar.
Debería poder conectar utilizando la nueva contraseña.
Cada versión de MySQL es probada en muchas plataformas antes de ser lanzada al público. Esto no significa que no haya ningún fallo en MySQL, pero si hay alguno, deberían ser muy pocos y difíciles de encontrar. Si tiene un problema, siempre ayuda si usted intenta encontrar qué es lo que hace fallar su sistema exactamente, porque tendrá una probabilidad mucho mayor de que su problema sea solucionado rápidamente.
Primero, debería intentar averiguar si el problema es que el servidor mysqld muere o el problema tiene que ver con su cliente. Puede comprobar cuando tiempo se ha estado ejecutando ininterrumpidamente su servidor ejecutando mysqladmin version. Sí mysqld ha caido y se ha reiniciado, podría encontrar la razón mirando en el registro de errores del servidor. Consulte Sección 5.10.1, “El registro de errroes (Error Log)”.
En algunos sistemas, puede encontrar en volcado de pila en el registro de errores del
momento en que el servidor mysqld murió, y que puede analizar con el
programa resolve_stack_dump. Consulte
Sección D.1.4, “Usar stack trace”. Nótese que los valores de las variables escritos en
el registro de errores pueden no ser siempre correctos al 100%.
Muchas caidas del servidor son causadas por archivos de datos o índices corruptos.
MySQL actualiza los archivos en el disco con la llamada de sistema
write() después de cada sentencia SQL y antes de que el cliente
sea notificado del resultado. (Esto no es así si está ejecutando con
--delay-key-write, en cuyo caso los archivos de datos son escritos
pero no los de índices.) Esto significa que los contenidos de los archivos de datos están
seguros aunque mysqld caiga, porque el sistema operativo se asegura
de que los datos no volcados sean escritos al disco. Puede forzar a que MySQL escriba
todo a disco tras cada sentencia SQL iniciando mysqld con la opción
--flush.
Esto significa que normalmente usted no debería obtener tablas corruptas a menos que una de las siguientes cosas ocurra:
El servidor MySQL o la máquina han sido cerrados en medio de una actualización.
Usted ha encontrado un fallo en mysqld que ha causado que caiga en el medio de una actualización.
Algún programa externo está manipulando los archivos de datos o índices a la vez que mysqld sin bloquear la tabla apropiadamente.
Está ejecutando varios servidores mysqld utilizando el mismo
directorio de datos en un sistema que no soporta un buen mecanismo de bloqueo de
sistema de archivos (normalmente gestionado por el gestor de bloqueos lockd), o está ejecutando múltiples servidores con la opción --skip-external-locking.
Usted tiene un archivo de datos o índices erróneo que contiene datos muy corruptos que han confundido a mysqld.
Ha encontrado un fallo en el código de almacenaje de datos. Esto no es muy probable,
pero es posible. En este caso, puede intentar cambiar el tipo de la tabla a otro
motor de almacenamiento utilizando ALTER TABLE sobre una copia
reparada de la tabla.
Debido a que es muy difícil saber por qué algo está fallando, primero intente comprobar las cosas que funcionan frente a las que fallan en su caso. Por favor, intente las siguientes comprobaciones:
Pare el servidor mysqld con mysqladmin shutdown,
ejecute myisamchk --silent --force */*.MYI desde el directorio
de datos para comprobar todas las tablas MyISAM, y reinicie
mysqld. Esto le hará estar seguro de que está ejecutando el servidor desde un estado inicial limpio. Consulte Capítulo 5, Administración de bases de datos.
Inicie mysqld con la opción --log e intente
determinar a través de la información escrita en el registro si hay alguna consulta
particular que mate al servidor. Sobre el 95% de todos los fallos son relacionados
con una consulta en particular. Normalmente, esta es una de las últimas consultas
en el archivo de registro antes de que el servidor se reinicie. Consulte Sección 5.10.2, “El registro general de consultas”. Si usted puede matar repetidamente MySQL con una consulta
específica, aún cuando ha comprobado todas las tablas antes de ejecutarla, entonces
ha sido capaz de localizar el fallo, y debería enviar un informe de fallos. Consulte
Sección 1.6.1.3, “Cómo informar de bugs y problemas”.
Intente hacer un juego de pruebas que podamos utilizar para repetir el problema. Consulte Sección D.1.6, “Crear un caso de prueba tras haber encontrado una tabla corrupta”.
Intente ejecutar las pruebas en el direcotrio mysql-test
y los bancos de pruebas MySQL. Consulte Sección 27.1.2, “El paquete de pruebas MySQL Test”.
Estos deberían comprobar bastante bien MySQL. También puede añadir código a los
bancos de pruebas que simulen su aplicación. Los bancos de pruebas pueden ser
localizados en el directorio sql-bench en una distribución
de código fuente, o, en una distribución binaria, en el directorio sql-bench bajo su directorio de instalación de MySQL.
Intente el script fork_big.pl. (Está ubicado en el directorio tests de una distribución de código fuente.)
Si usted configura MySQL para depuración, es mucho más fácil recoger información
sbore los posibles errores cuando algo va mal. Configurar MySQL para depuración causa
que un gestor de memoria seguro se incluya para encontrar algunos errores. También
produce muchas más salidas informativas sobre lo que está pasando. Reconfigure
MySQL con la opción --with-debug o
--with-debug=full para ejecutar después
configure y seguidamente recompilar. Consulte
Sección D.1, “Depurar un servidor MySQL”.
Asegúrese de que usted ha aplicado los últimos parches para su sistema operativo.
Utilice la opción --skip-external-locking para
mysqld. En algunos sitemas, el gestor de bloqueos
lockd no funciona apropiadamente; la opción
--skip-external-locking le dice a mysqld
que no utilice bloqueos externos. (Esto significa que no puede ejecutar dos servidores
mysqld en el mismo directorio de datos, y que debe ser muy cuidadoso
cuando utilice myisamchk). Aún así, puede ser muy instructivo intentar la opción como prueba.)
¿Ha intentado el comando mysqladmin -u root processlist cuando mysqld parece estar ejecutándose pero no responde? A veces mysqld no está comatoso, aunque usted pueda pensar lo contrario. El problema puede ser que todas las conexiones estén en uso, o que haya algún problema de bloqueo interno. mysqladmin -u root processlist es normalmente capaz de hacer una conexión aún en esots casos, y puede proveerle de información útil sobre el número actual de conexiones y su estado.
Ejecute del comando mysqladmin -i 5 status o mysqladmin -i 5 -r status en una ventana separada para producir estadísticas mientras ejecuta sus otras consultas.
Intente lo siguiente:
Inicie mysqld desde gdb (u otro depurador). Consulte Sección D.1.3, “Depurar mysqld con gdb”.
Ejecute sus scripts de comprobación.
Imprima el trazado y las variables locales en los tres niveles más bajos. En gdb, puede hacer esto con los siuguientes comandos cuando mysqld ha caido dentro de gdb:
backtrace info local up info local up info local
Con gdb, usted puede también examinar que hilos de ejecución existen con
info threads y cambiar a un hilo específico con thread
#, donde # es el ID del hilo.
Trate de simular su aplicación con un script Perl para forzar a que MySQL falle o se comporte indebidamente.
Envíe un informe de fallos normal. Consulte Sección 1.6.1.3, “Cómo informar de bugs y problemas”. Sea aún más detallado de lo normal. Debido a que MySQL funciona para mucha gente, podría ser que los fallos fueran resultado de algo que exista tan sólo en su máquina (por ejemplo, un error relacionado con sus librerías de sistema particulares).
Si usted tiene un problema con tablas que contengan filas de longitud dinámica y está utilizando únicamente columnas
VARCHAR (no columnas BLOB ni TEXT), puede intentar cambiar
todas las columnas VARCHAR a CHAR con ALTER TABLE. Esto
fuerza a MySQL a utilizar filas de tamaño fijo. Las filas de tamaño fijo ocupan un poco más de espacio, pero son mucho
más tolerantes a la corrupción.
El código de filas dinámicas actual ha sido utilizado en MySQL AB durante muchos años con muy pocos problemas, pero las filas de longitud dinámica son, por naturaleza, más propensas a errores, así que podría ser una buena idea intentar esta estrategia y ver si ayuda.
No deje fuera el hardware de su servidor cuando esté diagnosticando problemas. El hardware defectuoso puede ser causa de corrupción de datos. Debe poner especial atención en la RAM y los discos duros cuando esté buscando problemas de hardware.
Esta sección explica como MySQL se comporta frente a errores de disco lleno (como “no space left on device”), y, a partir de MySQL 4.0.22, a errores de límite de cuota (como “write failed” o “user block limit reached”).
Esta sección es relevante para escrituras a tablas MyISAM. A paritr de MySQL 4.1.9, también se aplica
a las escrituras a archivos de registro binario y también a sus índices, excepto por las referencias a “row” y
“record” que deberían entenderse como “event.”
Cuando se llega a la situación de disco lleno, MySQL hace lo siguiente:
Comprueba una vez por minuto si hay suficiente espacio para escribir la fila actual. Si hay espacio, continua como si nada hubiese pasado.
Cada 10 minutos, escribe una entrada en el archivo de registro, avisando sobre la situación de disco lleno.
Para aliviar el problema, puede hacer lo siguiente:
Para continuar, lo único que tiene que hacer es liberar suficiente espacio en disco para insertar todos los registros.
Para abortar el hilo, debe utilizar el comando mysqladmin kill. El hilo se aborta la próxima vez que comprueba el disco (en un minuto).
Otros hilos podrían estar esperando a la tabla que causó la situación de disco lleno. Si tiene varios hilos bloqueados matar al que está esperando por la situación de disco lleno permite que los demás hilos puedan continuar.
Hay excepciones al comportamiento descrito previamente, como cuando utiliza REPAIR TABLE o
OPTIMIZE TABLE, o cuando los índices son creados en batch tras la sentencia LOAD DATA INFILE
o la sentencia ALTER TABLE. Todas estas sentencias podrían crear grandes archivos temporales que, si se
dejan a su suerte, podrían causar enormes problemas para el resto del sistema. Si el disco se llena mientras MySQL está haciendo
alguna de estas operaciones, elimina el archivo temporal grande y marca la tabla como corrupta. La excepción es que con
ALTER TABLE, la tabla antigua se deja tal como estaba, sin cambios.
MySQL utiliza el valor de la variable de entorno TMPDIR como la ruta al directorio en el que almacenar
archivos temporales. Si no tiene configurada TMPDIR, MySQL utiliza el valor por defecto del sistema, que
normalmente es /tmp, /var/tmp, o /usr/tmp.
Si el sistema de archivos que contiene su directorio de archivos temporales es demasiado pequeño, puede utilizar la opción
--tmpdir de mysqld para especificar un directorio en un sistema de archivos en el que
tenga suficiente espacio.
Desde MySQL 4.1, la opción --tmpdir puede establecerse como una lista de varias rutas que son utilizadas
de manera round-robin. Las rutas deben estar separadas por caracteres de dos puntos (':') en Unix, y de
punto y coma (';') en Windows, NetWare y OS/2.
Nota: Para repartir la carga de manea efectiva, estas rutas tienen que estar colocadas
en diferentes discos físicos, no en diferentes particiones del mismo disco.
Si el servidor MySQL actua como un esclavo de replicación, no debería hacer que
--tmpdir apunte a un drectorio en un sistema de archivos basada en memoria, o un directorio que se limpia cuando
la máquina se reinicia. Un esclavo de replicación necesita algunos de sus archivos temporales para sobrevivir a un reinicio de
la máquina de manera que pueda replicar tablas temporales u operaciones LOAD DATA
INFILE. Si se pierden archivos del directorio temporal cuando el servidor reinicia, la replicación falla.
MySQl crea todos los archivos temporales como archivos ocultos. Esto asegura que los archivos temporales se eliminan si mysqld termina. La desventaja de utilizar archivos ocultos es que usted no podrá ver el gran archivo temporal que llena su sistema de archivos.
Cuando ordena (ORDER BY o GROUP
BY), MySQL normalmente utiliza uno o dos archivos temporales. El espacio máximo de disco requerido se determina
con la siguiente expresión:
(longitud de lo que está siendo ordenado + tamañode(puntero de fila)) * número de filas concordantes * 2
El tamaño del puntero de fila es normalmente de 4 bytes, pero puede crecer en el futuro para tablas realmente grandes.
Para algunas consultas SELECT, MySQL también crea tablas SQL temporales. Estas no están ocultas y tienen
nombres del tipo SQL_*.
ALTER TABLE crea una tabla temporal en el mismo directorio que la tabla original.
El lugar por defecto del archivo de socket Unix que el servidor utiliza para comunicarse con los clientes locales es
/tmp/mysql.sock. Esto podría causar problemas, porque en agunas versiones de Unix, cualquiera puede borrar
archivos del direcotorio /tmp.
En la mayoría de versiones de Unix, usted puede proteger su directorio /tmp de manera
que los archivos solo puedan ser borrados por sus propietarios o el superusuario (root).
Para hacer esto, establezca el bit sticky en el directorio /tmp
entrando en el sitema como root y utilizando el siguiente comando:
shell> chmod +t /tmp
Puede comprobar si el bit sticky esta activado ejecutando ls -ld /tmp.
Si el último carácter de privilegios es t, el bit está activado.
Otra solución es cambiar el lugar donde el servidor crea el archivo socket de Unix. Si hace esto, debería también hacérselo saber a los programas clientes. Puede especificar el lugar del archivo de diferentes maneras:
Especifique la ruta en un archivo de opciones global o local. Por ejemplo, ponga las siguientes líneas en
/etc/my.cnf:
[mysqld] socket=/ruta/a/socket [client] socket=/ruta/a/socket
Especifique una opción --socket en la línea de comandos a mysqld_safe y cuando
ejecute programas cliente.
Establezca la variable de entorno MYSQL_UNIX_PORT apuntando a la ruta del archivo de socket Unix.
Recompile MySQL desde el código fuente para utilizar una ruta por defect diferente para el archivo socket. Defina la ruta
al arhivo con la opción --with-unix-socket-path cuando ejecute configure. Consulte
Sección 2.8.2, “Opciones típicas de configure”.
Puede comprobar si el nuevo lugar del socket funciona intentando conectar al servidor con el siguiente comando:
shell> mysqladmin --socket=/ruta//socket version
Si tiene un prooblema cn que SELECT NOW() retorno los valores en GMT y no en su hora local, tiene que decirle
al servidor cual es su zona actual. Lo mismo es aplicable para UNIX_TIMESTAMP() su retorna un valor incorrecto.
Esto debe hacerse para el entorno en que el servidor se ejecuta; por ejemplo en mysqld_safe o
mysql.server. Consulte
Apéndice E, Variables de entorno.
Puede establecer la zona horaria del servidor con la opción --timezone=timezone_name para
mysqld_safe. También puede establecerla configurando la varible de entorno
TZ antes de iniciar mysqld.
Los valores permisibles para --timezone o
TZ dependen de sus sistema. Consulte la documentación de su sistema operativo para ver qué valores son
aceptables.
DATENULL
Por defecto, las búsquedas de MySQL no tienen sensibilidad a mayúsculas (aunque algunos juegos de caracteres tienen
siempre sensibilidad a mayúsculas como el checo). Esto significa que si busca con
, obtendrá todas las columnas que comiencen con
col_name LIKE
'a%'A o a. Si quiere hacer que esta consulta sea sensible a las mayúsculas, asegúrese de que
alguno de los operandos tiene una colación binaria sensible a las mayúsculas. Por ejemplo, si está comparando una columna y una
cadena de caracteres que tienen ambos el juego de caracteres latin1, puede utilizar el operador
COLLATE para causar que cualquiera de los operandos tenga la colación
latin1_general_cs o
latin1_bin. Por ejemplo:
col_nameCOLLATE latin1_general_cs LIKE 'a%'col_nameLIKE 'a%' COLLATE latin1_general_cscol_nameCOLLATE latin1_bin LIKE 'a%'col_nameLIKE 'a%' COLLATE latin1_bin
Si quiere que una columna siemrpe sea tratada de manera sensible a mayúsculas, declárela de esa manera, con una colación que lo
sea. Consulte Sección 13.1.5, “Sintaxis de CREATE TABLE”.
Previamentea MySQL 4.1, COLLATE no está disponible. Utilice el operador
BINARY en las expresiones para tratar una cadena de caráceres como binaria:
BINARY
o
col_name LIKE 'a%'. En declaracines de columnas, utilice el atributo col_name LIKE BINARY
'a%'BINARY.
Las operaciones de comparación simples (>=, >, =, <,
<=, ordenación, y agrupación) se basan en el valor de orden del carácter. Caracteres con el mismo valor de orden
(como 'E', 'e', y 'é') se tratan como el mismo carácter.
El format de un valor DATE es 'YYYY-MM-DD'. De acuerdo al estándard SQL ningún otro
formato se permite. Debería usar este formato en las sentencias UPDATE y en la cláusula
WHERE de las sentencias SELECT. Por ejemplo:
mysql> SELECT * FROM nombre_de_tabla WHERE date >= '2003-05-05';
Por motivos de conveniencia, MySQL convierte automáticamente una fecha a un número si la fecha se utiliza en un contexto numérico
(y viceversa). Es también suficientemente inteligente para permitir diversos formatos de cadena de caracteres cuando se está
actualizando y en las cláusulas WHERE que comparan una fecha con una columna
TIMESTAMP, DATE, o
DATETIME. (Diversos formatos, significa que puede utilizarse cualquier carácter de puntuación como separador
de las partes de la fecha. Por ejemplo, '2004-08-15' y
'2004#08#15' son equivalentes.) MySQL también puede convertir una cadena de caracteres que no contenga
separadores (como '20040815'), siempre que tenga sentido como fecha.
Cuando compara una colmna DATE,
TIME, DATETIME, o
TIMESTAMP a una cadena de caracteres constante con los operadores
<, <=,
=, >=,
>, o BETWEEN, MySQL normalmente convierte la cadena de caráteres a un entero largo
interno para una comparación más rápda (y también para hacer una comparación algo más permisiva). Aún así, esta conversión
está sujeta a las siguientes restricciones:
Cuando compara dos columnas
Cuando usted compare columnas DATE,
TIME, DATETIME, o
TIMESTAMP con una expresión.
Cuando usted utilice cualquier otro método de comparación que no sean aquellos recientemente citados, como
IN o STRCMP().
Para estos casos excepcionales, la comparación se hace convirtiendo los objetos a cadenas de caracteres y realizando una comparación de cadenas de caracteres.
Para mantener todo a salvo, asuma que las fechas son comparadas como cadenas de caracteresy utilice las funciones de cadena de caracteres apropiadas para comparar un valor temporal con una cadena de caracteres.
La fecha especial '0000-00-00' puede almacenarse y recogerse como '0000-00-00'.
Cuando se utiliza una fecha '0000-00-00' a través de MyODBC, es convierte automáticamente en
NULL en MyODBC
2.50.12 y superiores, porque ODBC no puede gestionar este tipo de fechas.
Como MySQL realiza las conversiones anteriores, las siguientes sentencias funcionan:
mysql> INSERT INTOnombre_de_tabla(idate) VALUES (19970505); mysql> INSERT INTOnombre_de_tabla(idate) VALUES ('19970505'); mysql> INSERT INTOnombre_de_tabla(idate) VALUES ('97-05-05'); mysql> INSERT INTOnombre_de_tabla(idate) VALUES ('1997.05.05'); mysql> INSERT INTOnombre_de_tabla(idate) VALUES ('1997 05 05'); mysql> INSERT INTOnombre_de_tabla(idate) VALUES ('0000-00-00'); mysql> SELECT idate FROMnombre_de_tablaWHERE idate >= '1997-05-05'; mysql> SELECT idate FROMnombre_de_tablaWHERE idate >= 19970505; mysql> SELECT MOD(idate,100) FROMnombre_de_tablaWHERE idate >= 19970505; mysql> SELECT idate FROMnombre_de_tablaWHERE idate >= '19970505';
Pero lo siguente no funciona:
mysql> SELECT idate FROM nombre_de_tabla WHERE STRCMP(idate,'20030505')=0;
STRCMP() es una función de comparación de cadenas,
así que convierte idate a una cadena de caracteres en
formato 'YYYY-MM-DD' y realiza una comparación de cadenas.
Es decir, NO convierte '20030505' en la fecha '2003-05-05' para realizar una comparación de fechas.
Si está utilizando el modo SQL ALLOW_INVALID_DATES (permitir fechas no válidas), MySQL le permite almacenar las fechas que le proporciona con
una comprobación mínima: MySQL se asegura únicamente que el día esté en el rango
entre 1 y 31, y el mes en el rango entre 1 y 12.
Esto hace que MySQL sea muy convenienta para las aplicaciones web en que usted obtiene el año, mes y día en tres campos diferentes y quiere almacenar exactamente lo que el usuario insertó (sin validación de fechas).
Si no está utilizando el modo SQL NO_ZERO_IN_DATE, la parte del día
o el mes pueden ser cero. Esto es conveniente si quiere almacenar una fecha de nacimiento
en una columna DATE y solo conoce parte de esa fecha.
Si no está utlizando el modo SQL NO_ZERO_DATE, MySQL también le permite
almacenar '0000-00-00' como fecha comodín. En algunos momentos esto
puede ser más adecuado que utilizar valores NULL.
Si la fecha no puede ser convertida a ningún valor razonable, se almacena un
0 en la columna DATE, que se extrae como
'0000-00-00'. Esto es una cuestión de velocidad y conveniencia. Creemos
que la responsabilidad del servidor de bases de datos es recoger la misma fecha
que usted almacenó (aún cuando la fecha no fuese lógicamente correcta en todos los casos).
Creemos que es responsabilidad de la aplicación y no del servidor comprobar las fechas.
Si quiere que MySQL compruebe todas las fechas y acepte solo las que sean correctas
(al menos que esto sea sobreseido por IGNORE), debería establecer el modo SQL a
"NO_ZERO_IN_DATE,NO_ZERO_DATE".
La gestión de fechas en MySQL 5.0.1 y anteriores funciona como en MySQL 5.0.2 con
el modo SQL ALLOW_INVALID_DATES activado.
El concepto del valor NULL es una fuente común de confusión para
los recién llegados a SQL, que frecuentemente piensan que NULL es lo
mismo que una cadena de caracteres vacía ''. Esto no es así. Por
ejemplo, las siguientes sentencias son completamente diferentes:
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ('');
Ambas sentencias insertan un valor en la columna phone, pero la
primera inserta un valor NULL y la segunda una cadena vacía.
El significado de la primera se puede traducir por “el número de teléfono
no es conocido”, y el significado de la segunda es “se sabe que la
persona no tiene teléfono, y por tanto, no hay número de teléfono.”
Para ayudarle con la gestión de NULL, tiene disponibles
los operadores IS NULL y IS NOT NULL
y la función IFNULL().
En SQL, el valor NULL nunca da verdadero al compararlo con otro
valor, aún cuando este valor sea también NULL. Una expresión que
contiene NULL siempre produce un valor NULL a
menos que se indique lo contrario en la documentación de los operadores y funciones
implicadas en la expresión. Todas las columnas en el siguiente ejemplo retornan
NULL:
mysql> SELECT NULL, 1+NULL, CONCAT('Invisible',NULL);
Si quiere buscar valores de columna que son NULL, no puede utilizar
una comprobación expr = NULL. La siguiente sentencia no retorna
registros, porque expr = NULL nunca es verdadero para cualquier
expresión:
mysql> SELECT * FROM my_table WHERE phone = NULL;
Para buscar valores NULL debe utilizar la comprobaciónIS NULL. Las siguientes sentencias muestran como encontrar el número de teléfono
NULL y el vacío:
mysql> SELECT * FROM my_table WHERE phone IS NULL; mysql> SELECT * FROM my_table WHERE phone = '';
Puede añadir una columna índice que tenga valores NULL
si utiliza MySQL 3.23.2 o superiores, o si está utilizando los motores de almacenamiento
MyISAM, InnoDB, o BDB. A partir de
MySQL 4.0.2, el motor de almacenamiento MEMORY también tiene
soporte para valores NULL en los índices. Si no es así, todas
las columnas de índice deben ser declaradas como NOT NULL y usted
no podrá insertar un valor NULL en la columna.
Cuando lee datos con LOAD DATA INFILE, las columnas vacías o
inexistentes se rellenan con ''. Si quiere un valor NULL en una columna, usted deberá utilizar \N
en el archivo de datos. La palabra exacta “NULL” puede
ser también utilizada en algunas circunstancias. Consulte Sección 13.2.5, “Sintaxis de LOAD DATA INFILE”.
Cuando utiliza DISTINCT, GROUP
BY, o ORDER BY, todos los valores NULL
son tratados como iguales.
Cunado utilice ORDER BY, los valores NULL son
mostrados al principio, o al final si se especifica DESC para
ordenar de manera descendiente. Excepción: De MySQL 4.0.2 hasta 4.0.10, los valores
NULL se muestran primeros independientemente del orden.
Las funciones de agregación (resumen) como COUNT(),
MIN(), y SUM() ignoran los valores
NULL. La excepción a esto es COUNT(*),
que cuenta filas y no valores de columna individuales. Por ejemplo, la siguiente
sentencia produce dos conteos. El primero es un recuento del número de registros en
la tabla, y el segundo un recuento del número de valores diferentes a NULL en la columna age:
mysql> SELECT COUNT(*), COUNT(age) FROM person;
En algunos tipos de columnas, MySQL gestiona los valores
NULL de manera especial. Si inserta un valor
NULL en una columna TIMESTAMP, se insertan la fecha
y hora actual. Si inserta un valor NULL en una columna entera que
tiene el atributo AUTO_INCREMENT, se inserta el siguiente número en
la secuencia.
Puede utilizar un alias para referirse a una columna en las clausulas
GROUP
BY, ORDER BY, o
HAVING. Los alias también se puede utilizar para dar mejores
nombres a las columnas:
SELECT SQRT(a*b) AS root FROMnombre_de_tablaGROUP BY root HAVING root > 0; SELECT id, COUNT(*) AS cnt FROMnombre_de_tablaGROUP BY id HAVING cnt > 0; SELECT id AS 'Customer identity' FROMnombre_de_tabla;
El SQL estándard no permite referirse a un alias de columna en una clausula
WHERE. Esto es porque cuando se ejecuta el código de WHERE, el valor de la columna podría no estar establecido aún. Por
ejemplo, la siguiente consulta es ilegal:
SELECT id, COUNT(*) AS cnt FROM nombre_de_tabla WHERE cnt > 0 GROUP BY id;
La sentencia WHERE se ejecuta para determinar qué registros serán
incluidos en la parte de GROUP BY, así como HAVING
se utiliza para decidir qué filas del conjunto de resultados deben utilizarse.
Si usted recibe el siguiente mensjae cuando intenta realizar un
ROLLBACK, significa que una o más de las tablas que utilizó en
la transacción no tienen soporte para trasacciones:
Warning: Some non-transactional changed tables couldn't be rolled back
Estas tablas no transaccionales no se ven afectadas por la sentencia
ROLLBACK.
Si usted no estaba mezclando tablas transaccionales y no transaccionales deliberadamente
en la transacción, la razón más probable para que este mensaje aparezca es que una tabla
que usted pensaba que era transaccional no lo es realmente. Esto puede pasar si usted
intenta crear una tabla utilizando un motor de almacenamiento que no está configurado
en su servidor mysqld (o que fue desactivado con una opción inicial). Si
mysqld no tiene soporte para ese motor de almacenamiento, crea
la tabla como una tabla MyISAM, que es no transaccional.
Puede comprobar el tipo de una tabla utilizando cualquiera de las siguientes sentencias:
SHOW TABLE STATUS LIKE 'nombre_de_tabla'; SHOW CREATE TABLEnombre_de_tabla;
Consulte Sección 13.5.4.18, “Sintaxis de SHOW TABLE STATUS” y
Sección 13.5.4.5, “Sintaxis de SHOW CREATE TABLE”.
Puede consultar qué motores de almacenamiento soporta su servidor mysqld mediante la sentencia:
SHOW ENGINES;
Anteriormente a MySQL 4.1.2, la sentencia SHOW ENGINES no está
disponible. Utilice la siguiente sentencia en su lugar y compruebe el valor de la
variable que está asociada al motor de almacenamiento en el que está interesado:
SHOW VARIABLES LIKE 'have_%';
Por ejemplo, para determinar si el motor InnoDB está disponible,
compruebe el valor de la variable have_innodb.
Consulte Sección 13.5.4.8, “Sintaxis de SHOW ENGINES” y
Sección 13.5.4.21, “Sintaxis de SHOW VARIABLES”.
MySQL no soporta subconsultas en versiones previas a la 4.1, o el uso
de más de una tabla en la sentencia DELETE anteriormente
a la versión 4.0. Si su versión de MySQL no soporta subconsultas, o sentencias
DELETE multi-tabla, puede utilizar las siguientes estrategias
para borrar registros de dos tablas relacionadas:
Seleccione (SELECT) los registros basados en una condición
WHERE en la tabla principal.
Borre (DELETE) los registros de la tabla principal basándose en
la misma condición.
DELETE FROM tabla_relacionada WHERE columna_relacionada IN
(registros_seleccionados).
Si la longitud total de la sentencia DELETE para
tabla_relacionada es más de 1MB (el valor por defecto de
la variable de sistema max_allowed_packet), debería partirla
en partes más pequeñas y ejecutar múltiples sentencias DELETE.
Problablemente obtenga el borrado más rápido especificando entre 100 y 1000 valores de
columna_relacionada por sentencia si
columna_relacionada está indexada. Si
columna_relacionada no está indexada, la velocidad es independiente del número de argumentos en la clausula IN.
Si tiene una consulta complicada que utiliza muchas tablas pero que no retorna ningún registro, debería utilizar el siguiente procedimiento para encontrar qué está fallando:
Compruebe la consulta con EXPLAIN para ver si
encuentra algo que sea erróneo de una manera obvia. Consulte Sección 7.2.1, “Sintaxis de EXPLAIN (Obtener información acerca de un SELECT)”.
Seleccione únicamente aquellas columnas que están en la clausula WHERE.
Vaya quitando las tablas una a una de la consulta hasta que devuelva algunos
registros. Son las tablas son grandes, es una buena idea utilizar LIMIT 10 con la consulta.
Ejecute un SELECT sobre la columna que debería haber
extraido un registro de la tabla que fue eliminada en último lugar de la consulta.
Si está comparando columnas FLOAT o
DOUBLE con números que tengan decimales, no puede
utilizar comparaciones de igualdad (=). Este problema
es común en la mayor parte de los lenguajes informáticos debido a que no
todos los valores de coma flotante se pueden almacenar con precisión exacta.
En algunos casos, cambiar de FLOAT a DOUBLE
soluciona esto. Consulte Sección A.5.8, “Problemas con comparaciones en coma flotante”.
Si aún así no puede imaginar que es lo que funciona incorrectamente
cree un pequeña prueba que pueda ser ejecutada con mysql test <
query.sql y que muestre sus problemas. Muede crear un archivo de prueba
volcando las tablas con mysqldump
--quick db_name nombre_de_tabla_1 ...
nombre_de_tabla_n >
query.sql. Abra el archivo en un editor, elimine algunas líneas de inserción
(si hay más de las necesarias para demostrar el problema), y añada su sentencia
SELECT al final del archivo.
Verifique que el archivo de prueba demuestra el problema ejecutando los siguientes comandos:
shell> mysqladmin create test2 shell> mysql test2 < query.sql
Envíe el archivo de pruebas utilizando mysqlbug a la lista de correo general de MySQL. Consulte Sección 1.6.1.1, “Las listas de correo de MySQL”.
Tenga en cuenta que la siguiente sección es relevante principalmente para versiones
de MySQL anteriores a 5.0.3. A partir de la versión 5.0.3, MyQL realiza las operaciones
DECIMAL con una precisión de 64 dígitos decimales, lo que debería resolver los problemas de imprecisión más comunes en lo que se refiere a columnas DECIMAL. Para las columnas DOUBLE y FLOAT los problemas siguen porque la inexactitud es la naturaleza
básica de los números en coma flotante.
Los números en coma flotante a veces causan confusión porque no son almacenados
como valores exactos en la arquitectura de la computadora. Lo que puede ver en la pantalla
no es el valor exacto del número. Los tipos de columna FLOAT,
DOUBLE, y DECIMAL son de este tipo. Las
columnas DECIMAL almacenan valores con precisión exacta porque
se representan como cadenas de caracteres, pero los cálculos sobre valores
DECIMAL, en versiones previas a 5.0.3, eran realizadas utilizando operaciones de coma flotante.
El siguiente ejemplo (para versiones anteriores a 5.0.3 de MySQL)
demuestra el problema. Muestra que incluso para los tipos de columna
DECIMAL, los cálculos se realizan utilizando operaciones de coma flotante
que están sujetas al error. (En todas las versiones de MySQL, tendría problemas
similares si reemplazara las columnas DECIMAL con
FLOAT).
mysql> CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
mysql> 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 |
+------+--------+-------+
El resultado es correcto. Aunque los cinco primeros registros aparentan no poder pasar
la comparación (los valores a y b no parecen
ser diferentes), lo son porque la diferencia entre los dos números se encuentra a partir
del decimal número diez aproximadamente, dependiendo de la arquitectura de la computadora.
A partir de MySQL 5.0.3, usted obtendría únicamente el último registro en el resultado anterior.
El problema no puede ser resulto utilizando funciones como ROUND()
o similares, porque el resultado sigue siendo un número en coma flotante:
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 |
+------+--------+-------+
Esta es la apariencia que los números en la columna a tienen al mostrarse
más cifras decimales:
mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a,
-> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b;
+------+----------------------+-------+
| i | a | b |
+------+----------------------+-------+
| 1 | 21.3999999999999986 | 21.40 |
| 2 | 76.7999999999999972 | 76.80 |
| 3 | 7.4000000000000004 | 7.40 |
| 4 | 15.4000000000000004 | 15.40 |
| 5 | 7.2000000000000002 | 7.20 |
| 6 | -51.3999999999999986 | 0.00 |
+------+----------------------+-------+
Dependiendo de la arquitectura de su computadora, usted puede que vea o no resultados similares. Diferentes procesadores pueden evaluar los números en coma flotante de manera diferente. Por ejemplo, en algunas máquinas usted podría obtener los resultados “correctos” multiplicando ambos argumentos por 1, como en el siguiente ejemplo.
Aviso: Nunca utilice este método en sus aplicaciones. No es un ejemplo de procedimiento fiable.
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 |
+------+--------+------+
La razón por la que el ejemplo precedente parece funcionar es que en una máquina particular donde la prueba fue realizada, la aritmética de coma flotante del procesador redondea los números al mismo valor. No obstante, no hay ninguna regla que diga que un procesador deba hacerlo, así que este método no merece confianza.
La manera adecuada de hacer comparaciones en coma flotante es primero decidir una tolerancia aceptable para las diferencias entre los números y realizar entonces las comparaciones sobre el valor de tolerancia. Por ejemplo, si estamos de acuerdo en que los números en coma flotante deben ser considerados el mismo si están dentro de una precisión de uno sobre diez mil (0.0001), la comparación debería escribirse para encontrar diferencias mayores que el valor de tolerancia:
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)
De manera análoga, para obtener los registros en que los números son iguales, la comparación debería encontrar diferencias dentro del valor de tolerancia:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) <= 0.0001;
+------+-------+-------+
| i | a | b |
+------+-------+-------+
| 1 | 21.40 | 21.40 |
| 2 | 76.80 | 76.80 |
| 3 | 7.40 | 7.40 |
| 4 | 15.40 | 15.40 |
| 5 | 7.20 | 7.20 |
+------+-------+-------+
MySQL utiliza un optimizador basado en costos para determinar la mejor manera de resolver una consulta. En muchos casos, MySQL puede calcular el mejor plan de consulta posible, pero a veces MySQL no tiene suficiente información sobre los datos a mano y tiene que hacer suposiciones “educadas” sobre los datos.
Em ñps casps em qie MySQL no hace lo "adecuado", las herramientas que usted tiene disponible para ayudar a MySQL son:
Utilice la sentencia EXPLAIN para obtener información sobre
como MySQL procesa una consulta. Para utilizarlo, simplemente añada la palabra clave
EXPLAIN al inicio de su sentencia SELECT:
mysql> EXPLAIN SELECT * FROM t1, t2 WHERE t1.i = t2.i;
EXPLAIN está explicado con más detalle en
Sección 7.2.1, “Sintaxis de EXPLAIN (Obtener información acerca de un SELECT)”.
Utilice ANALYZE TABLE
para actualizar las definiciones
de claves de la tabla analizada. Consulte Sección 13.5.2.1, “Sintaxis de nombre_de_tablaANALYZE TABLE”.
Utilice FORCE INDEX sobre la tabla analizada para decirle a
MySQL que los escaneos de tabla son muy costosos comparado con utilizar el índice dado.
Consulte Sección 13.2.7, “Sintaxis de SELECT”.
SELECT * FROM t1, t2 FORCE INDEX (index_for_column) WHERE t1.col_name=t2.col_name;
USE INDEX y IGNORE
INDEX podrían también ser útiles.
STRAIGHT_JOIN a nivel global y de tabla. Consulte
Sección 13.2.7, “Sintaxis de SELECT”.
Puede adaptar variables globales o específicas de hilos de ejecución. Por ejemplo, inicie
mysqld con la opción --max-seeks-for-key=1000
o utilice SET max_seeks_for_key=1000 para decirle al optimizador que asuma que ninguna rastreo de claves genera más de 1000 búsquedas. Consulte Sección 5.3.3, “Variables de sistema del servidor”.
ALTER TABLE cambia una tabla a el juego de caracteres actual. Si obtiene
un error de clave duplicada durante una operación ALTER TABLE,
la causa puede ser que el nuevo juego de caracteres haga equivaler dos claves, o que la
tabla está corrompida. En este último caso, debería ejecutar REPAIR
TABLE sobre dicha tabla.
Si ALTER TABLE termina abruptamente con el siguiente error,
el problema podría ser que MySQL falló durante una operación ALTER TABLE anterior, y que hay una antigua llamadaA- o
xxxB- por el sistema:
xxx
Error on rename of './database/name.frm'
to './database/B-xxx.frm' (Errcode: 17)
En este caso, vaya al directorio de datos de MySQL y borre todos los archivos que
tengan nombres que comiencen con A- o
B-. (Quizá debería moverlos a algún otro lugar en vez de borrarlos
directamente.)
ALTER TABLE trabaja de la siguiente manera:
Crea una tabla llamada A- con
los cambios estructurales demandados.
xxx
Copia todas las filas de la tabla original en A-.
xxx
Renombra la tabla original a
B-.
xxx
Renombra A- a el nombre de tabla
original.
xxx
Borra
B-.
xxx
Si algo falla durante la operación de renombrado, MySQL intenta deshacer los cambios.
Si algo falla seriamente (aunque esto no debería pasar), MySQL podría dejar la vieja tabla
como B-. Un renombrado simple de
los archivos de tabla al nivel de sistema debería devolverle todos sus datos.
xxx
Si usted utiliza ALTER TABLE en una tabla transaccional o si está
utilizando Windows o OS/2, ALTER
TABLE desbloquea la tabla si usted ha hecho un LOCK TABLE
previo sobre ella. Esto es debido a que InnoDB y estos sistemas
operativos no puede eliminar una tabla que está en uso.
Primero, cosidere si realmente necesita cambiar el orden de columnas en una tabla. El
objetivo primordial de SQL es abstraer la aplicación del formato de almacenamiento de datos.
Debería siempre especificar el orden en el que quiere recoger sus datos. La primera de las siguiente sentencias retorna las columnas en el orden
First, consider whether you really need to change the column
order 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. The
first of the following statements returns columns in the order
col_name1,
col_name2,
col_name3, mientras que la segunda las retorna en orden
col_name1,
col_name3,
col_name2:
mysql> SELECTcol_name1,col_name2,col_name3FROMnombre_de_tabla; mysql> SELECTcol_name1,col_name3,col_name2FROMnombre_de_tabla;
Si usted decide cambiar el orden de las columnas de la tabla aún así, debe hacerlo de la siguiente manera:
Cree una tabla con las columnas en el nuevo orden.
Ejecute esta sentencia:
mysql> INSERT INTO new_table
-> SELECT columns-in-new-order FROM old_table;
Elimine o renombre old_table.
Renombre la nueva tabla al nombre original:
mysql> ALTER TABLE new_table RENAME old_table;
SELECT * es muy útil para consultas de prueba. No obstante, en una
aplicación, nunca debería utilizar SELECT
* y después recoger las columnas basándose en su posición. El orden y posición
en que las columnas son devueltas no es el mismo si usted añade, mueve, o elimina columnas.
Un cambio simple a la estructura de su tabla podría causar que su aplicación falle.
La siguiente lista indica las limitaciones en el uso de tablas temporales:
Una tabla TEMPORARY solo puede ser de tipo HEAP,
ISAM, MyISAM, MERGE, o
InnoDB.
No puede referirse a una tabla TEMPORARY más de una vez en la
misma consulta. Por ejemplo, lo siguiente no funciona:
mysql> SELECT * FROM temp_table, temp_table AS t2; ERROR 1137: Can't reopen table: 'temp_table'
La sentencia SHOW TABLES no muestra tablas
TEMPORARY.
No puede utilizar RENAME para renombrar una tabla
TEMPORARY. No obstante, puede utilicer ALTER
TABLE como alternativa:
mysql> ALTER TABLE orig_name RENAME new_name;
Esta sección es una lista de problemas conocidos en versiones recientes de MySQL.
Para información sobre temas específicos a una plataforma consulte las instrucciones de instalación y porte en Sección 2.12, “Notas específicas sobre sistemas operativos” y Apéndice D, Portar a otros sistemas.
Los siguientes problemas conocidos no han sido arreglados en MySQL 3.23 por diversos motivos, y no han sido clasificados como críticos.
Arreglado en MySQL 4.0: Evite utilizar espacios al final de los nombres de columna porque esto puede causar comportamientos inesperados. (Bug#4196)
Arreglado en MySQL 4.0.12: Puede obtener un abrazo murtal (deadlock) si utiliza
LOCK TABLE para bloquear múltiples tablas y luego en la misma
conexión utiliza DROP
TABLE para eliminar una de ellas mientras otro hilo está intentando bloquearla. (Para romper el abrazo mortal, puede utilizar KILL para matar cualquiera de los hilos implicados.)
Arreglado en MySQL 4.0.11: SELECT MAX(key_column) FROM
t1,t2,t3... donde una de las tablas está vacía no retorna
NULL sino que retorna el valor máximo de la columna.
DELETE FROM heap_table sin una clausula WHERE
no funciona en uan tabla HEAP bloqueada.
Los siguientes problemas conocidos no han sido arreglado sen MySQL 4.0 por diversos motivos, y no han sido clasificados como críticos.
Arreglado en MySQL 4.1.10: Utilizanzo HAVING, usted podría
obtener un fallo o un resultado erróneo si utiliza un alias para una función
RAND(). Esto no será corregido en la versión 4.0 porque la
corrección podría romper la compatibilidad con algunas aplicaciones.
Arreglado en MySQL 4.1.1: En una UNION, el primer
SELECT determina las propiedades de tipo,
max_length, y NULL
para las columnas del resultado.
Arreglado en MySQL 4.1: En DELETEs con muchas tablas, usted no puede referirse a tablas que serán borradas mediante un alias.
Arreglado en MySQL 4.1.2: No se puede mezclar UNION
ALL y UNION DISTINCT en la misma consulta. Si utiliza
ALL para un UNION, se utiliza para todos ellos.
FLUSH TABLES WITH READ LOCK no bloquea a los
CREATE TABLE, lo que puede causar un problema con la posición del registro
binario cuando se hace una copia de seguridad completa de las tablas y el registro binario.
Arreglado en MySQL 4.1.8: mysqldump
--single-transaction --master-data se comportaban como
mysqldump --master-data, así que el volqueado era bloqueante.
Al utilizar la función RPAD() (o cualquier función que añada espacios
a la derecha) en una consulta que tenía que ser resulta utilizando una tabla temporal,
todos los resultados se obtenían sin esos espacios (es decir RPAD()
no funcionaba).
Los siguientes problemas conocidos no han sido arreglados en MySQL 4.1 por diversos motivos, y no han sido clasificados como críticos.
Arreglado en 5.0.3:
Fixed in 5.0.3: VARCHAR y
VARBINARY no almacenaban los espacios finales.
Los siguientes problemas son conocidos y arreglarlos es de alta prioridad:
Si compara un valor NULL con una subconsulta utilizando
ALL/ANY/SOME y la subconsulta retorna un conjunto vacío, la comparación
podría devolver el resultado no estándard de NULL en vez de
TRUE o FALSE. Esto será arreglado en MySQL 5.1.
La optimización de las subconsultas para IN no es tan efectiva como para
=.
Aún cuando utilice lower_case_table_names=2 (que permite a MySQL recordar
la diferencia entre mayúsculas y minúsculas utilizada en los nombres de las bases de datos y las
tablas), MySQL no la recuerda en los nombres de bases de datos al utilizar la función
DATABASE() o en los diversos registro (en sistemas no sensibles a
mayúsculas/minúsculas).
Eliminar una restricción de FOREIGN KEY no funciona en una replicación
porque la restricción puede tener otro nombre en el esclavo.
REPLACE (y LOAD DATA
con la opción REPLACE) no dispara a ON DELETE CASCADE.
DISTINCT con ORDER BY no funciona dentro
de GROUP_CONCAT() si no utiliza todas y únicamente aquellas columnas que están
en la lista de DISTINCT.
Si un usuario tiene una transacción ejecutándose durante mucho tiempo y otro
usuario elimina una tabla que es actualizada durante la transacción, hay una pequeña
posibilidad de que el registro binario contenga el comando DROP TABLE
antes de que dicha tabla sea utilizada en la transacción. Planeamos arreglar esto haciendo
que el comando DROP TABLE espera a que la tabla no sea utilizada en ninguna
transacción.
Cuando se inserta un valor de entero grande (entre 263 y 264–1) en una columna decimal o de cadena de caracteres, se inserta con un valor negativo porque el número es evaluado en un contexto de entero con signo.
FLUSH TABLES WITH READ LOCK no bloquea los
COMMIT si el servidor se está ejecutando sin registro binario, lo que
puede causar un problema (de consistencia entre tablas) cuando se hace una copia de seguridad
completa.
ANALYZE TABLE en una tabla BDB
puede hacer que en algunos casos la tabla quede inutilizable hasta que reinicie
mysqld. Si esto ocurre, busque los errores similares a este en el archivo
de error de MySQL:
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
No ejecute ALTER TABLE en una tabla BDB
en la que usted esté ejecutando transacciones de varias sentencias hasta que todas
esas transacciones hayan sido completadas. (La transacción podría ser ignorada.)
ANALYZE TABLE, OPTIMIZE
TABLE, y REPAIR TABLE podría causar problemas en tablas para las que
usted esté utilizando INSERT DELAYED.
Realizar LOCK TABLE ... y
FLUSH TABLES ... no garantiza que no haya una transacción a medio ejecutar
en progreso en la tabla.
Las tablas BDB son relativamente lentas de abrir.
Si usted tiene muchas tablas BDB en una base de datos,
un cliente mysql podría tardar mucho en estar listo si no está
utilizando la opción -A o sí está utilizando
rehash. Esto es especialmente notable cuando tiene una cache de tablas
grande.
La replicación utiliza registro a nivel de consulta: El maestro escribe las sentencias ejecutadas al registro binario. Este es un método de registro muy rápido, compacto, y eficiente que trabaja de manera perfecta en la mayor parte de los casos.
Es posible que los datos en el maestro y el esclavo difieran si una consulta se diseña de manera que la modificación de los datos sea no-determinista (generalmente no es una práctica recomendada, incluso sin hablar de replicación).
Por ejemplo:
Las sentencias CREATE ... SELECT o INSERT
... SELECT que inserten valores cero o NULL en una columna
AUTO_INCREMENT.
DELETE, si usted está borrando registros de una tabla que tiene
claves foráneas con propiedad ON DELETE
CASCADE.
REPLACE ... SELECT, INSERT
IGNORE ... SELECT si tiene valores de clave duplicados en los datos insertados.
Si y únicamente si las sentencias precedentes no tienen una clausula
ORDER BY garantizado un orden
determinista.
Por ejemplo, en INSERT ... SELECT sin un
ORDER BY, el SELECT podría retornar registros en orden
diferente (lo que resulta en una fila que termina teniendo diferente rango, es decir,
obteniendo un número diferente en la columna AUTO_INCREMENT),
dependiendo de las elecciones hechas por los optimizadores en el maestro y el esclavo.
Una consulta está optimizada de manera diferente en el maestro y el esclavo sólo sí:
Los archivos utilizados en las dos consultas no son exactamente los mismos; por ejemplo
se ejecutó OPTIMIZE TABLE en las tablas del maestro, pero no en las
de los esclavos. (Para arreglar esto, OPTIMIZE TABLE,
ANALYZE TABLE, y REPAIR
TABLE se escriben en el registro binario a partir de MySQL 4.1.1).
La tabla está almacenada utilizando un motor de almacenamiento diferente en el maestro
que en el esclavo. (Es posible utilizar diferentes motores de almacenamiento en el maestro y el
esclavo. Por ejemplo, puede utilizar InnoDB en el maestro, pero
MyISAM en el esclavo, si el esclavo tiene menos espacio de disco disponible.)
El tamaño de buffer de MySQL (key_buffer_size, y demás) es diferente
en el maestro y el esclavo.
El maestro y el esclavo ejecutan versiones de MySQL diferentes, y el código del optimizador difiere entra esas dos versiones.
Este problema podría también afectar a la restauración de bases de datos utilizando mysqlbinlog|mysql.
La manera más fácil de evitar este problema es añadir una clausula
ORDER BY a las mencionadas consultas no-deterministas para asegurarse
de que los registros son siempre almacenados o modificados en el mismo orden.
En versiones futuras de MySQL, añadiremos automáticamente una clausula
ORDER BY allá donde sea necesaria.
Los siguientes problemas son conocidos y serán arreglados a su debido tiempo:
Los nombres de archivo de los registros se basan en el nombre del servidor (si no especifica
un nombre en la opción de inicio). Tiene que utilizar opciones como
--log-bin= si usted cambia
el nombre de su servidor. Otra opción es renombrar los antiguos archivos para reflejar el cambio
al nuevo nombre (si estos son registros binarios, debería editar el archivo de índice del registro
binario y arreglar los nombres también). Consulte Sección 5.3.1, “Opciones del comando mysqld”.
old_host_name-bin
mysqlbinlog no borra los archivos temporales tras un comando
LOAD DATA INFILE. Consulte Sección 8.5, “La utilidad mysqlbinlog para registros binarios”.
RENAME no funciona con tablas
TEMPORARY o tablas utilizadas en una tabla MERGE.
Debido a la manera en que los archivos de definición de talba son almacenados, usted no puede
utilizar el carácter 255 (CHAR(255)) en los nombres de tabla, columna, o
enumeraciones. Esto será arreglado previsiblemente en la versión 5.1, cuando implementemos
un nuevo formato de archivo de definición de tablas.
Cuando utiliza SET CHARACTER SET, usted no puede utilizar caracteres traducidos
en los nombres de base de datos, tabla y columna.
No puede utilizar '_' o '%' con ESCAPE en
LIKE ... ESCAPE.
Si usted tiene una columna DECIMAL en la que el mismo número se almacena
en diferentes formatos (por ejemplo, +01.00, 1.00,
01.00), GROUP BY puede tratar cada valor como uno diferente.
No puede instalar el servidor en otro directorio cuando utiliza MIT-pthreads. Debido a que este problema requiere cambios en los hilos MIT-pthreads, no es probable que lo arreglemos. Consulte Sección 2.8.5, “Notas sobre MIT-pthreads”.
Los valores BLOB y TEXT no puede ser utilizados
“de manera fiablemente” en GROUP
BY, ORDER BY o
DISTINCT. Solo los primeros max_sort_length se utilizan para
comparar valores BLOB en estos casos. El valor por defecto de
max_sort_length es 1024 y puede cambiarse en el momento de iniciar el servidor.
A partir de MySQL 4.0.3, también puede cambiarse en tiempo de ejecución. En versiones más antiguas,
una solución alternativa es utilizar una subcadena de caracteres. Por ejemplo:
SELECT DISTINCT LEFT(blob_col,2048) FROMnombre_de_tabla;
Los cálculos numéricos son hechos con BIGINT
o DOUBLE (ambos son normalmente de 64 bits de longitud). La precisión que
usted obtenga depende de la función. La regla general es que las funciones de bit son realizadas
con precisión de BIGINT, IF
y ELT() con precisión BIGINT
o DOUBLE, y el resto con precisión DOUBLE.
Debería evitar utilizar valores sin signo largos si son más grandes de 63 bits
(9223372036854775807) para cualquier cosa que no sean campos de tipo bit. La versión 4.0
de MySQL tiene mejor gestión de BIGINT que 3.23.
Puede tener hasta 255 columnas ENUM y
SET en una tabla.
En las funciones MIN(), MAX(), y otras funciones de
agregación, MySQL actualmente compara las columnas ENUM y
SET por su valor de cadena decaracteres en vez de la posición relativa
de la cadena en el conjunto.
mysqld_safe redirige todos los mensajes desde
mysqld al registro mysqld. Un problema
con esto es que si usted ejecuta mysqladmin refresh para cerrar
y reabrir el registro, stdout y stderr
son redirigidos todavía al registro antiguo. Si usted utiliza
--log a menudo, debería editar mysqld_safe para
que almacene sus registros en
en vez de
host_name.err de manera que pueda fácilmente
recuperar el espacio borrando el registro antiguo y ejecutando mysqladmin
refresh.
host_name.log
En una sentencia UPDATE, las columnas son actualizadas de izquierda
a drecha. Si se refiere a una columna actualizada, usted obtiene el valor actualizado en vez
del original. Por ejemplo, la siguiente sentencia incrementa KEY en
2, no 1:
mysql> UPDATE nombre_de_tabla SET KEY=KEY+1,KEY=KEY+1;
Puede referirse a múltiples tablas temporales en la misma sentencia, pero no puede referirse a ninguna de ellas más de una vez. Por ejemplo, lo siguiente no funciona:
mysql> SELECT * FROM temp_table, temp_table AS t2; ERROR 1137: Can't reopen table: 'temp_table'
El optimizador podría gestionar DISTINCT de manera diferente
cuando esté utilizando columnas ocultas en una join, y cuando no lo haga. En una join, las columnas
ocultas se contan como parte del resultado (aunque no sean mostradas), mientras que en las consultas
normales, las columnas ocultas no participan en la comparación
DISTINCT. Probalemente cambiemos esto en el futuro para que nunca se comparen
las columnas ocultas al ejecutar DISTINCT.
Un ejemplo de esto es:
SELECT DISTINCT mp3id FROM band_downloads
WHERE userid = 9 ORDER BY id DESC;
and
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;
En el segundo caso, al utilizar el servidor MySQL 3.23.x, podría obtener dos registros idénticos
en el conjunto de resultados (porque los valores en las columnas id ocultas
podrían diferir).
Tenga en cuenta que esto pasa solo en las consultas que no tienen
columnas pertenecientes al ORDER BY en el resultado.
Si ejecuta un PROCEDURE en una consulta que retorna un conjunto vacío, en
algunos casos el PROCEDURE no transforma las columnas.
La creación de una tabla de tipo MERGE no comprueba si los tablas
subyacentes son de tipos compatibles.
Si utiliza ALTER TABLE para añadir un índice
UNIQUE a una tabla utilizada en una tabla
MERGE y después añade un índice normal en la tabla
MERGE, el orden de las claves es diferente para las tablas si había una clave
no-UNIQUE antigua en la tabla. Esto es porque
ALTER TABLE pone índices UNIQUE antes
de los índices normales para poder detectar claves duplicadas tan pronto como sea posible.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.