Apéndice A. Problemas y errores comunes
Anterior |  | Siguiente

## Apéndice A. Problemas y errores comunes

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

## A.1. Cómo determinar a qué es debido un problema

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

## A.2. Errores comunes al usar programas MySQL

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

### A.2.1. `Access denied`

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

### A.2.2. `Can't connect to [local] MySQL server`

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

### A.2.3. `Client does not support authentication protocol`

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:

  1. Inicie mysqld con la opción `--old-passwords`.

  2. 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”.

### A.2.4. La contraseña falla cuando se introduce interactivamente

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 carácteres (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 carácteres de longitud, o ponga su constraseña en un archivo de opciones.

### A.2.5. `La máquina '`host_name`' está bloqueada`

Si obtiene el siguiente error, significa que mysqld ha recibido demasiados intentos de conexión desde la máquina `'`host_name`'` que han sido interrumpidos:

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

### A.2.6. `Demasiadas conexiones`

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.

### A.2.7. `Out of memory`

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

### A.2.8. `MySQL se ha apagado`

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

### A.2.9. `Packet too large`

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.

### A.2.10. Errores de comunicación y conexiones abortadas

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`”.

### A.2.11. `The table is full`

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 TABLE nombre_tabla MAX_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.

### A.2.12. `Can't create/write to file`

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

### A.2.13. `Commands out of sync`

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.

### A.2.14. `Ignoring user`

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 carácteres. Si es así, puede corregir esta condición ejecutando el script `scripts/add_long_password`.

- La cuenta tiene una contraseña antigua (de ocho carácteres 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`.

- A 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';

### A.2.15. `Table '`nombre_de_tabla`' doesn't exist`

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`”.

### A.2.16. `Can't initialize character set`

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=`charset_name`` o `--with-extra-charsets=`charset_name``. Consulte Sección 2.8.2, “Opciones típicas de configure”.

  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 carácteres 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 carácteres. 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.

### A.2.17. No se encontró el fichero

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.

## A.3. Problemas relacionados con la instalación

### A.3.1. Problemas al enlazar a la biblioteca de clientes MySQL

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.

### A.3.2. Cómo ejecutar MySQL como usuario normal

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:

1. Pare el servidor si se está ejecutando (utilice el comando mysqladmin shutdown).

2. 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 -R user_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.

3. 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=`user_name``. mysqld se inicia, y entonces cambia la ejecución al usuario Unix `user_name` antes de aceptar ninguna conexión.

4. 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”.

### A.3.3. Problemas con permisos de archivos

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.

## A.4. Cuestiones relacionadas con la administración

### A.4.1. Cómo reiniciar la contraseña de root

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:

1. Entre en su sistema como Administrador.

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

3. 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`.

4. Abra una ventana de comandos para obtener una consola de comandos DOS:

       Menú Inicio -> Ejecutar -> cmd

5. 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`.

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

7. Debería poder conectar utilizando la nueva contraseña.

En un entorno Unix, el procedimiento para restablecer la contraseña `root` es el siguiente:

1. Entre en sus sitema como usuario Unix `root` o bien como el mismo usuario que ejecuta el servidor mysqld.

2. 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`.

3. 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`.

4. 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`.

5. 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):

1. 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`).

2. Conecte al servidor mysqld con este comando:

       shell> mysql -u root

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

4. Debería poder conectar utilizando la nueva contraseña.

### A.4.2. Qué hacer si MySQL sigue fallando (crashing)

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:

  1. Inicie mysqld desde gdb (u otro depurador). Consulte Sección D.1.3, “Depurar mysqld con gdb”.

  2. Ejecute sus scripts de comprobación.

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

### A.4.3. Cómo se comporta MySQL ante un disco lleno

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.

### A.4.4. Dónde almacena MySQL los archivos temporales

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 carácteres 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.

### A.4.5. Cómo proteger o cambiar el fichero socket de MySQL `/tmp/mysql.sock`

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

  Consulte Sección 4.3.2, “Usar ficheros de opciones”.

- 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

### A.4.6. Problemas con las franjas horarias

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.

## A.5. Problemas relacionados con consultas

### A.5.1. Sensibilidad a mayúsculas en búsquedas

Por defecto, las búsquedas de MySQL no tienen sensibilidad a mayúsculas (aunque algunos juegos de carácteres tienen siempre sensibilidad a mayúsculas como el checo). Esto significa que si busca con ``col_name` LIKE 'a%'`, obtendrá todas las columnas que comiencen con `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 carácteres que tienen ambos el juego de carácteres `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_name COLLATE latin1_general_cs LIKE 'a%'
    col_name LIKE 'a%' COLLATE latin1_general_cs
    col_name COLLATE latin1_bin LIKE 'a%'
    col_name LIKE '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 `col_name` LIKE 'a%'` o ``col_name` LIKE BINARY 'a%'`. En declaracines de columnas, utilice el atributo `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.

### A.5.2. Problemas en el uso de columnas `DATE`

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 convenienci, 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 carácteres 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 carácteres 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 carácteres 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 carácteres y realizando una comparación de cadenas de carácteres.

Para mantener todo a salvo, asuma que las fechas son comparadas como cadenas de carácteresy utilice las funciones de cadena de carácteres apropiadas para comparar un valor temporal con una cadena de carácteres.

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 anterioes, las siguientes sentencias funcionan:

    mysql> INSERT INTO nombre_de_tabla (idate) VALUES (19970505);
    mysql> INSERT INTO nombre_de_tabla (idate) VALUES ('19970505');
    mysql> INSERT INTO nombre_de_tabla (idate) VALUES ('97-05-05');
    mysql> INSERT INTO nombre_de_tabla (idate) VALUES ('1997.05.05');
    mysql> INSERT INTO nombre_de_tabla (idate) VALUES ('1997 05 05');
    mysql> INSERT INTO nombre_de_tabla (idate) VALUES ('0000-00-00');

    mysql> SELECT idate FROM nombre_de_tabla WHERE idate >= '1997-05-05';
    mysql> SELECT idate FROM nombre_de_tabla WHERE idate >= 19970505;
    mysql> SELECT MOD(idate,100) FROM nombre_de_tabla WHERE idate >= 19970505;
    mysql> SELECT idate FROM nombre_de_tabla WHERE idate >= '19970505';

Pero lo siguente no funciona:

    mysql> SELECT idate FROM nombre_de_tabla WHERE STRCMP(idate,'20030505')=0;

`STRCMP()` is a string function, so it converts `idate` to a string in `'YYYY-MM-DD'` format and performs a string comparison. It does not convert `'20030505'` to the date `'2003-05-05'` and perform a date comparison.

If you are using the `ALLOW_INVALID_DATES` SQL mode, MySQL allows you to store dates that are given only limited checking: MySQL ensures only that the day is in the range from 1 to 31 and the month is in the range from 1 to 12.

This makes MySQL very convenient for Web applications where you obtain year, month, and day in three different fields and you want to store exactly what the user inserted (without date validation).

If you are not using the `NO_ZERO_IN_DATE` SQL mode, the day or month part can be zero. This is convenient if you want to store a birthdate in a `DATE` column and you know only part of the date.

If you are not using the `NO_ZERO_DATE` SQL mode, MySQL also allows you to store `'0000-00-00'` as a “dummy date.” This is in some cases more convenient than using `NULL` values.

If the date cannot be converted to any reasonable value, a `0` is stored in the `DATE` column, which is retrieved as `'0000-00-00'`. This is both a speed and a convenience issue. We believe that the database server's responsibility is to retrieve the same date you stored (even if the data was not logically correct in all cases). We think it is up to the application and not the server to check the dates.

If you want MySQL to check all dates and accept only legal dates (unless overriden by IGNORE), you should set `sql_mode` to `"NO_ZERO_IN_DATE,NO_ZERO_DATE"`.

Date handling in MySQL 5.0.1 and earlier works like MySQL 5.0.2 with the `ALLOW_INVALID_DATES` SQL mode enabled.

### A.5.3. Problemas con valores `NULL`

The concept of the `NULL` value is a common source of confusion for newcomers to SQL, who often think that `NULL` is the same thing as an empty string `''`. This is not the case. For example, the following statements are completely different:

    mysql> INSERT INTO my_table (phone) VALUES (NULL);
    mysql> INSERT INTO my_table (phone) VALUES ('');

Both statements insert a value into the `phone` column, but the first inserts a `NULL` value and the second inserts an empty string. The meaning of the first can be regarded as “phone number is not known” and the meaning of the second can be regarded as “the person is known to have no phone, and thus no phone number.”

To help with `NULL` handling, you can use the `IS NULL` and `IS NOT NULL` operators and the `IFNULL()` function.

In SQL, the `NULL` value is never true in comparison to any other value, even `NULL`. An expression that contains `NULL` always produces a `NULL` value unless otherwise indicated in the documentation for the operators and functions involved in the expression. All columns in the following example return `NULL`:

    mysql> SELECT NULL, 1+NULL, CONCAT('Invisible',NULL);

If you want to search for column values that are `NULL`, you cannot use an `expr NULL` test. The following statement returns no rows, because `expr = NULL` is never true for any expression:

    mysql> SELECT * FROM my_table WHERE phone = NULL;

To look for `NULL` values, you must use the `IS NULL` test. The following statements show how to find the `NULL` phone number and the empty phone number:

    mysql> SELECT * FROM my_table WHERE phone IS NULL;
    mysql> SELECT * FROM my_table WHERE phone = '';

You can add an index on a column that can have `NULL` values if you are using MySQL 3.23.2 or newer and are using the `MyISAM`, `InnoDB`, or `BDB` storage engine. As of MySQL 4.0.2, the `MEMORY` storage engine also supports `NULL` values in indexes. Otherwise, you must declare an indexed column `NOT NULL` and you cannot insert `NULL` into the column.

When reading data with `LOAD DATA INFILE`, empty or missing columns are updated with `''`. If you want a `NULL` value in a column, you should use `\N` in the data file. The literal word “`NULL`” may also be used under some circumstances. Consulte Sección 13.2.5, “Sintaxis de `LOAD DATA INFILE`”.

When using `DISTINCT`, `GROUP BY`, or `ORDER BY`, all `NULL` values are regarded as equal.

When using `ORDER BY`, `NULL` values are presented first, or last if you specify `DESC` to sort in descending order. Exception: In MySQL 4.0.2 through 4.0.10, `NULL` values sort first regardless of sort order.

Aggregate (summary) functions such as `COUNT()`, `MIN()`, and `SUM()` ignore `NULL` values. The exception to this is `COUNT(*)`, which counts rows and not individual column values. For example, the following statement produces two counts. The first is a count of the number of rows in the table, and the second is a count of the number of non-`NULL` values in the `age` column:

    mysql> SELECT COUNT(*), COUNT(age) FROM person;

For some column types, MySQL handles `NULL` values specially. If you insert `NULL` into a `TIMESTAMP` column, the current date and time is inserted. If you insert `NULL` into an integer column that has the `AUTO_INCREMENT` attribute, the next number in the sequence is inserted.

### A.5.4. Problemas con alias de columnas

You can use an alias to refer to a column in `GROUP BY`, `ORDER BY`, or `HAVING` clauses. Aliases can also be used to give columns better names:

    SELECT SQRT(a*b) AS root FROM nombre_de_tabla GROUP BY root HAVING root > 0;
    SELECT id, COUNT(*) AS cnt FROM nombre_de_tabla GROUP BY id HAVING cnt > 0;
    SELECT id AS 'Customer identity' FROM nombre_de_tabla;

Standard SQL doesn't allow you to refer to a column alias in a `WHERE` clause. This is because when the `WHERE` code is executed, the column value may not yet be determined. For example, the following query is illegal:

    SELECT id, COUNT(*) AS cnt FROM nombre_de_tabla WHERE cnt > 0 GROUP BY id;

The `WHERE` statement is executed to determine which rows should be included in the `GROUP BY` part, whereas `HAVING` is used to decide which rows from the result set should be used.

### A.5.5. Fallo en la cancelación de una transacción con tablas no transaccionales

If you receive the following message when trying to perform a `ROLLBACK`, it means that one or more of the tables you used in the transaction do not support transactions:

    Warning: Some non-transactional changed tables couldn't be rolled back

These non-transactional tables are not affected by the `ROLLBACK` statement.

If you were not deliberately mixing transactional and non-transactional tables within the transaction, the most likely cause for this message is that a table you thought was transactional actually is not. This can happen if you try to create a table using a transactional storage engine that is not supported by your mysqld server (or that was disabled with a startup option). If mysqld doesn't support a storage engine, it instead creates the table as a `MyISAM` table, which is non-transactional.

You can check the table type for a table by using either of these statements:

    SHOW TABLE STATUS LIKE 'nombre_de_tabla';
    SHOW CREATE TABLE nombre_de_tabla;

Consulte Sección 13.5.4.18, “Sintaxis de `SHOW TABLE STATUS`” and Sección 13.5.4.5, “Sintaxis de `SHOW CREATE TABLE`”.

You can check which storage engines your mysqld server supports by using this statement:

    SHOW ENGINES;

Before MySQL 4.1.2, `SHOW ENGINES` is unavailable. Use the following statement instead and check the value of the variable that is associated with the storage engine in which you are interested:

    SHOW VARIABLES LIKE 'have_%';

For example, to determine whether the `InnoDB` storage engine is available, check the value of the `have_innodb` variable.

Consulte Sección 13.5.4.8, “Sintaxis de `SHOW ENGINES`” and Sección 13.5.4.21, “Sintaxis de `SHOW VARIABLES`”.

### A.5.6. Borrar registros de tablas relacionadas

MySQL does not support subqueries prior to Version 4.1, or the use of more than one table in the `DELETE` statement prior to Version 4.0. If your version of MySQL does not support subqueries or multiple-table `DELETE` statements, you can use the following approach to delete rows from two related tables:

1. `SELECT` the rows based on some `WHERE` condition in the main table.

2. `DELETE` the rows in the main table based on the same condition.

3. `DELETE FROM related_table WHERE related_column IN (selected_rows)`.

If the total length of the `DELETE` statement for `related_table` is more than 1MB (the default value of the `max_allowed_packet` system variable), you should split it into smaller parts and execute multiple `DELETE` statements. You probably get the fastest `DELETE` by specifying only 100 to 1,000 `related_column` values per statement if the `related_column` is indexed. If the `related_column` isn't indexed, the speed is independent of the number of arguments in the `IN` clause.

### A.5.7. Resolver problemas con registros que no salen

If you have a complicated query that uses many tables but that doesn't return any rows, you should use the following procedure to find out what is wrong:

1. Test the query with `EXPLAIN` to check whether you can find something that is obviously wrong. See Sección 7.2.1, “Sintaxis de `EXPLAIN` (Obtener información acerca de un `SELECT`)”.

2. Select only those columns that are used in the `WHERE` clause.

3. Remove one table at a time from the query until it returns some rows. If the tables are large, it's a good idea to use `LIMIT 10` with the query.

4. Issue a `SELECT` for the column that should have matched a row against the table that was last removed from the query.

5. If you are comparing `FLOAT` or `DOUBLE` columns with numbers that have decimals, you can't use equality (`=`) comparisons. This problem is common in most computer languages because not all floating-point values can be stored with exact precision. In some cases, changing the `FLOAT` to a `DOUBLE` fixes this. Consulte Sección A.5.8, “Problemas con comparaciones en Floating-Point”.

6. If you still can't figure out what's wrong, create a minimal test that can be run with `mysql test < query.sql` that shows your problems. You can create a test file by dumping the tables with mysqldump --quick db_name `nombre_de_tabla_1` ... `nombre_de_tabla_n` > query.sql. Open the file in an editor, remove some insert lines (if there are more than needed to demonstrate the problem), and add your `SELECT` statement at the end of the file.

   Verify that the test file demonstrates the problem by executing these commands:

       shell> mysqladmin create test2
       shell> mysql test2 < query.sql

   Post the test file using mysqlbug to the general MySQL mailing list. See Sección 1.6.1.1, “Las listas de correo de MySQL”.

### A.5.8. Problemas con comparaciones en Floating-Point

Note that the following section is relevant primarily for versions of MySQL older than 5.0.3. As of version 5.0.3, MySQL performs `DECIMAL` operations with a precision of 64 decimal digits, which should solve most common inaccuracy problems when it comes to `DECIMAL` columns. For `DOUBLE` and `FLOAT` columns, the problems remain because inexactness is the basic nature of floating point numbers.

Floating-point numbers sometimes cause confusion because they are not stored as exact values inside computer architecture. What you can see on the screen usually is not the exact value of the number. The column types `FLOAT`, `DOUBLE`, and `DECIMAL` are such. `DECIMAL` columns store values with exact precision because they are represented as strings, but calculations on `DECIMAL` values before MySQL 5.0.3 are done using floating-point operations.

The following example (for older MySQL version than 5.0.3) demonstrate the problem. It shows that even for the `DECIMAL` column type, calculations that are done using floating-point operations are subject to floating-point error. (In all MySQL versions, you would have similar problems if you would replace the `DECIMAL` columns with `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 |
    +------+--------+-------+

The result is correct. Although the first five records look like they shouldn't pass the comparison test (the values of `a` and `b` do not appear to be different), they may do so because the difference between the numbers shows up around the tenth decimal or so, depending on computer architecture.

As of MySQL 5.0.3, you will get only the last row in the above result.

The problem cannot be solved by using `ROUND()` or similar functions, because the result is still a floating-point number:

    mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
        -> FROM t1 GROUP BY i HAVING a <> b;
    +------+--------+-------+
    | i    | a      | b     |
    +------+--------+-------+
    |    1 |  21.40 | 21.40 |
    |    2 |  76.80 | 76.80 |
    |    3 |   7.40 |  7.40 |
    |    4 |  15.40 | 15.40 |
    |    5 |   7.20 |  7.20 |
    |    6 | -51.40 |  0.00 |
    +------+--------+-------+

This is what the numbers in column `a` look like when displayed with more decimal places:

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

Depending on your computer architecture, you may or may not see similar results. Different CPUs may evaluate floating-point numbers differently. For example, on some machines you may get the “correct” results by multiplying both arguments by 1, as the following example shows.

Warning: Never use this method in your applications. It is not an example of a trustworthy method!

    mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b
        -> FROM t1 GROUP BY i HAVING a <> b;
    +------+--------+------+
    | i    | a      | b    |
    +------+--------+------+
    |    6 | -51.40 | 0.00 |
    +------+--------+------+

The reason that the preceding example seems to work is that on the particular machine where the test was done, CPU floating-point arithmetic happens to round the numbers to the same value. However, there is no rule that any CPU should do so, so this method cannot be trusted.

The correct way to do floating-point number comparison is to first decide on an acceptable tolerance for differences between the numbers and then do the comparison against the tolerance value. For example, if we agree that floating-point numbers should be regarded the same if they are same within a precision of one in ten thousand (0.0001), the comparison should be written to find differences larger than the tolerance value:

    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)

Conversely, to get rows where the numbers are the same, the test should find differences within the tolerance value:

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

## A.6. Cuestiones relacionadas con el optimizados

MySQL uses a cost-based optimizer to determine the best way to resolve a query. In many cases, MySQL can calculate the best possible query plan, but sometimes MySQL doesn't have enough information about the data at hand and has to make “educated” guesses about the data.

For the cases when MySQL does not do the "right" thing, tools that you have available to help MySQL are:

- Use the `EXPLAIN` statement to get information about how MySQL processes a query. To use it, just add the keyword `EXPLAIN` to the front of your `SELECT` statement:

      mysql> EXPLAIN SELECT * FROM t1, t2 WHERE t1.i = t2.i;

  `EXPLAIN` is discussed in more detail in Sección 7.2.1, “Sintaxis de `EXPLAIN` (Obtener información acerca de un `SELECT`)”.

- Use `ANALYZE TABLE `nombre_de_tabla`` to update the key distributions for the scanned table. See Sección 13.5.2.1, “Sintaxis de `ANALYZE TABLE`”.

- Use `FORCE INDEX` for the scanned table to tell MySQL that table scans are very expensive compared to using the given index. 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` and `IGNORE INDEX` may also be useful.

- Global and table-level `STRAIGHT_JOIN`. See Sección 13.2.7, “Sintaxis de `SELECT`”.

- You can tune global or thread-specific system variables. For example, Start mysqld with the `--max-seeks-for-key=1000` option or use `SET max_seeks_for_key=1000` to tell the optimizer to assume that no key scan causes more than 1,000 key seeks. Consulte Sección 5.3.3, “Variables de sistema del servidor”.

## A.7. Cuestiones relacionadas con definiciones de tabla

### A.7.1. Problemas con `ALTER TABLE`

`ALTER TABLE` changes a table to the current character set. If you get a duplicate-key error during `ALTER TABLE`, the cause is either that the new character sets maps two keys to the same value or that the table is corrupted. In the latter case, you should run `REPAIR TABLE` on the table.

If `ALTER TABLE` dies with the following error, the problem may be that MySQL crashed during an earlier `ALTER TABLE` operation and there is an old table named `A-`xxx`` or `B-`xxx`` lying around:

    Error on rename of './database/name.frm'
    to './database/B-xxx.frm' (Errcode: 17)

In this case, go to the MySQL data directory and delete all files that have names starting with `A-` or `B-`. (You may want to move them elsewhere instead of deleting them.)

`ALTER TABLE` works in the following way:

- Create a new table named `A-`xxx`` with the requested structural changes.

- Copy all rows from the original table to `A-`xxx``.

- Rename the original table to `B-`xxx``.

- Rename `A-`xxx`` to your original table name.

- Delete `B-`xxx``.

If something goes wrong with the renaming operation, MySQL tries to undo the changes. If something goes seriously wrong (although this shouldn't happen), MySQL may leave the old table as `B-`xxx``. A simple rename of the table files at the system level should get your data back.

If you use `ALTER TABLE` on a transactional table or if you are using Windows or OS/2, `ALTER TABLE` unlocks the table if you had done a `LOCK TABLE` on it. This is because `InnoDB` and these operating systems cannot drop a table that is in use.

### A.7.2. Cómo cambiar el orden de las columnas en una tabla

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`, whereas the second returns them in the order `col_name1`, `col_name3`, `col_name2`:

    mysql> SELECT col_name1, col_name2, col_name3 FROM nombre_de_tabla;
    mysql> SELECT col_name1, col_name3, col_name2 FROM nombre_de_tabla;

If you decide to change the order of table columns anyway, you can do so as follows:

1. Create a new table with the columns in the new order.

2. Execute this statement:

       mysql> INSERT INTO new_table
           -> SELECT columns-in-new-order FROM old_table;

3. Drop or rename `old_table`.

4. Rename the new table to the original name:

       mysql> ALTER TABLE new_table RENAME old_table;

`SELECT *` is quite suitable for testing queries. However, in an application, you should never rely on using `SELECT *` and retrieving the columns based on their position. The order and position in which columns are returned does not remain the same if you add, move, or delete columns. A simple change to your table structure could cause your application to fail.

### A.7.3. Problemas con `TEMPORARY TABLE`

The following list indicates limitations on the use of `TEMPORARY` tables:

- A `TEMPORARY` table can only be of type `HEAP`, `ISAM`, `MyISAM`, `MERGE`, or `InnoDB`.

- You cannot refer to a `TEMPORARY` table more than once in the same query. For example, the following does not work:

      mysql> SELECT * FROM temp_table, temp_table AS t2;
      ERROR 1137: Can't reopen table: 'temp_table'

- The `SHOW TABLES` statement does not list `TEMPORARY` tables.

- You cannot use `RENAME` to rename a `TEMPORARY` table. However, you can use `ALTER TABLE` instead:

      mysql> ALTER TABLE orig_name RENAME new_name;

## A.8. Problemas conocidos en MySQL

This section is a list of the known issues in recent versions of MySQL.

For information about platform-specific issues, see the installation and porting instructions in Sección 2.12, “Notas específicas sobre sistemas operativos” and Apéndice D, Portar a otros sistemas.

### A.8.1. Problemas de la versión 3.23 resueltos en una versión posterior de MySQL

The following known issues have not been fixed in MySQL 3.23 for various reasons, and are not classified as critical.

- Fixed in MySQL 4.0: Avoid using spaces at the end of column names because this can cause unexpected behavior. (Bug#4196)

- Fixed in MySQL 4.0.12: You can get a deadlock (hung thread) if you use `LOCK TABLE` to lock multiple tables and then in the same connection use `DROP TABLE` to drop one of them while another thread is trying to lock it. (To break the deadlock, you can use `KILL` to terminate any of the threads involved.)

- Fixed in MySQL 4.0.11: `SELECT MAX(key_column) FROM t1,t2,t3...` where one of the tables are empty doesn't return `NULL` but instead returns the maximum value for the column.

- `DELETE FROM heap_table` without a `WHERE` clause doesn't work on a locked `HEAP` table.

### A.8.2. Problemas de la versión 4.0 resueltos en una versión posterior de MySQL

The following known issues have not been fixed in MySQL 4.0 for various reasons, and are not classified as critical.

- Fixed in MySQL 4.1.10: Using `HAVING`, you can get a crash or wrong result if you use an alias to a `RAND()` function. This will not be fixed in 4.0 because the fix may break compatability with some applications.

- Fixed in MySQL 4.1.1: In a `UNION`, the first `SELECT` determines the type, `max_length`, and `NULL` properties for the resulting columns.

- Fixed in MySQL 4.1: In `DELETE` with many tables, you can't refer to tables to be deleted through an alias.

- Fixed in MySQL 4.1.2: You cannot mix `UNION ALL` and `UNION DISTINCT` in the same query. If you use `ALL` for one `UNION`, it is used for all of them.

- `FLUSH TABLES WITH READ LOCK` does not block `CREATE TABLE`, which may cause a problem with the binary log position when doing a full backup of tables and the binary log.

- Fixed in MySQL 4.1.8: `mysqldump --single-transaction --master-data` behaved like `mysqldump --master-data`, so the dump was a blocking one.

- When using the `RPAD()` function (or any function adding spaces to the right) in a query that had to be resolved by using a temporary table, all resulting strings had rightmost spaces removed (i.e. `RPAD()` did not work).

### A.8.3. Problemas de la versión 4.1 resueltos en una versión posterior de MySQL

The following known issues have not been fixed in MySQL 4.1 for various reasons, and are not classified as critical.

- Fixed in 5.0.3: `VARCHAR` and `VARBINARY` did not remember end space.

### A.8.4. Cuestiones abiertas en MySQL

The following problems are known and fixing them is a high priority:

- If you compare a `NULL` value to a subquery using `ALL/ANY/SOME` and the subquery returns an empty result, the comparison might evaluate to the non-standard result of `NULL` rather than to `TRUE` or `FALSE`. This will be fixed in MySQL 5.1.

- Subquery optimization for `IN` is not as effective as for `=`.

- Even if you use `lower_case_table_names=2` (which enables MySQL to remember the case used for databases and table names), MySQL does not remember the case used for database names for the function `DATABASE()` or within the various logs (on case-insensitive systems).

- Dropping a `FOREIGN KEY` constraint doesn't work in replication because the constraint may have another name on the slave.

- `REPLACE` (and `LOAD DATA` with the `REPLACE` option) does not trigger `ON DELETE CASCADE`.

- `DISTINCT` with `ORDER BY` doesn't work inside `GROUP_CONCAT()` if you don't use all and only those columns that are in the `DISTINCT` list.

- If one user has a long-running transaction and another user drops a table that is updated in the transaction, there is small chance that the binary log may contain the `DROP TABLE` command before the table is used in the transaction itself. We plan to fix this by having the `DROP TABLE` command wait until the table is not being used in any transaction.

- When inserting a big integer value (between 263 and 264–1) into a decimal or string column, it is inserted as a negative value because the number is evaluated in a signed integer context.

- `FLUSH TABLES WITH READ LOCK` does not block `COMMIT` if the server is running without binary logging, which may cause a problem (of consistency between tables) when doing a full backup.

- `ANALYZE TABLE` on a `BDB` table may in some cases make the table unusable until you restart mysqld. If this happens, look for errors of the following form in the MySQL error file:

      001207 22:07:56  bdb:  log_flush: LSN past current end-of-log

- Don't execute `ALTER TABLE` on a `BDB` table on which you are running multiple-statement transactions until all those transactions complete. (The transaction might be ignored.)

- `ANALYZE TABLE`, `OPTIMIZE TABLE`, and `REPAIR TABLE` may cause problems on tables for which you are using `INSERT DELAYED`.

- Performing `LOCK TABLE ...` and `FLUSH TABLES ...` doesn't guarantee that there isn't a half-finished transaction in progress on the table.

- `BDB` tables are relatively slow to open. If you have many `BDB` tables in a database, it takes a long time to use the mysql client on the database if you are not using the `-A` option or if you are using `rehash`. This is especially noticeable when you have a large table cache.

- Replication uses query-level logging: The master writes the executed queries to the binary log. This is a very fast, compact, and efficient logging method that works perfectly in most cases.

  It is possible for the data on the master and slave to become different if a query is designed in such a way that the data modification is non-deterministic (generally not a recommended practice, even outside of replication).

  For example:

  - `CREATE ... SELECT` or `INSERT ... SELECT` statements that insert zero or `NULL` values into an `AUTO_INCREMENT` column.

  - `DELETE` if you are deleting rows from a table that has foreign keys with `ON DELETE CASCADE` properties.

  - `REPLACE ... SELECT`, `INSERT IGNORE ... SELECT` if you have duplicate key values in the inserted data.

  If and only if the preceding queries have no `ORDER BY` clause guaranteeing a deterministic order.

  For example, for `INSERT ... SELECT` with no `ORDER BY`, the `SELECT` may return rows in a different order (which results in a row having different ranks, hence getting a different number in the `AUTO_INCREMENT` column), depending on the choices made by the optimizers on the master and slave.

  A query is optimized differently on the master and slave only if:

  - The files used by the two queries are not exactly the same; for example, `OPTIMIZE TABLE` was run on the master tables and not on the slave tables. (To fix this, `OPTIMIZE TABLE`, `ANALYZE TABLE`, and `REPAIR TABLE` are written to the binary log as of MySQL 4.1.1).

  - The table is stored using a different storage engine on the master than on the slave. (It is possible to use different storage engines on the master and slave. For example, you can use `InnoDB` on the master, but `MyISAM` on the slave if the slave has less available disk space.)

  - MySQL buffer sizes (`key_buffer_size`, and so on) are different on the master and slave.

  - The master and slave run different MySQL versions, and the optimizer code differs between these versions.

  This problem may also affect database restoration using mysqlbinlog|mysql.

  The easiest way to avoid this problem is to add an `ORDER BY` clause to the aforementioned non-deterministic queries to ensure that the rows are always stored or modified in the same order.

  In future MySQL versions, we will automatically add an `ORDER BY` clause when needed.

The following issues are known and will be fixed in due time:

- Log filenames are based on the server hostname (if you don't specify a filename with the startup option). You have to use options such as `--log-bin=`old_host_name`-bin` if you change your hostname to something else. Another option is to rename the old files to reflect your hostname change (if these are binary logs, you need to edit the binary log index file and fix the binlog names there as well). Consulte Sección 5.3.1, “Opciones del comando mysqld”.

- mysqlbinlog does not delete temporary files left after a `LOAD DATA INFILE` command. Consulte Sección 8.5, “La utilidad mysqlbinlog para registros binarios”.

- `RENAME` doesn't work with `TEMPORARY` tables or tables used in a `MERGE` table.

- Due to the way table definition files are stored, you cannot use character 255 (`CHAR(255)`) in table names, column names, or enumerations. This is scheduled to be fixed in version 5.1 when we implement new table definition format files.

- When using `SET CHARACTER SET`, you can't use translated characters in database, table, and column names.

- You can't use '`_`' or '`%`' with `ESCAPE` in `LIKE ... ESCAPE`.

- If you have a `DECIMAL` column in which the same number is stored in different formats (for example, `+01.00`, `1.00`, `01.00`), `GROUP BY` may regard each value as a different value.

- You cannot build the server in another directory when using MIT-pthreads. Because this requires changes to MIT-pthreads, we are not likely to fix this. See Sección 2.8.5, “Notas sobre MIT-pthreads”.

- `BLOB` and `TEXT` values can't “reliably” be used in `GROUP BY`, `ORDER BY` or `DISTINCT`. Only the first `max_sort_length` bytes are used when comparing `BLOB` values in these cases. The default value of `max_sort_length` value is 1024 and can be changed at server startup time. As of MySQL 4.0.3, it can be changed at runtime. For older versions, a workaround is to use a substring. For example:

      SELECT DISTINCT LEFT(blob_col,2048) FROM nombre_de_tabla;

- Numeric calculations are done with `BIGINT` or `DOUBLE` (both are normally 64 bits long). Which precision you get depends on the function. The general rule is that bit functions are performed with `BIGINT` precision, `IF` and `ELT()` with `BIGINT` or `DOUBLE` precision, and the rest with `DOUBLE` precision. You should try to avoid using unsigned long long values if they resolve to be larger than 63 bits (9223372036854775807) for anything other than bit fields. MySQL Server 4.0 has better `BIGINT` handling than 3.23.

- You can have up to 255 `ENUM` and `SET` columns in one table.

- In `MIN()`, `MAX()`, and other aggregate functions, MySQL currently compares `ENUM` and `SET` columns by their string value rather than by the string's relative position in the set.

- mysqld_safe redirects all messages from mysqld to the mysqld log. One problem with this is that if you execute mysqladmin refresh to close and reopen the log, `stdout` and `stderr` are still redirected to the old log. If you use `--log` extensively, you should edit mysqld_safe to log to ``host_name`.err` instead of ``host_name`.log` so that you can easily reclaim the space for the old log by deleting it and executing mysqladmin refresh.

- In an `UPDATE` statement, columns are updated from left to right. If you refer to an updated column, you get the updated value instead of the original value. For example, the following statement increments `KEY` by `2`, not `1`:

      mysql> UPDATE nombre_de_tabla SET KEY=KEY+1,KEY=KEY+1;

- You can refer to multiple temporary tables in the same query, but you cannot refer to any given temporary table more than once. For example, the following doesn't work:

      mysql> SELECT * FROM temp_table, temp_table AS t2;
      ERROR 1137: Can't reopen table: 'temp_table'

- The optimizer may handle `DISTINCT` differently when you are using “hidden” columns in a join than when you are not. In a join, hidden columns are counted as part of the result (even if they are not shown), whereas in normal queries, hidden columns don't participate in the `DISTINCT` comparison. We will probably change this in the future to never compare the hidden columns when executing `DISTINCT`.

  An example of this is:

      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;

  In the second case, using MySQL Server 3.23.x, you may get two identical rows in the result set (because the values in the hidden `id` column may differ).

  Note that this happens only for queries where that do not have the `ORDER BY` columns in the result.

- If you execute a `PROCEDURE` on a query that returns an empty set, in some cases the `PROCEDURE` does not transform the columns.

- Creation of a table of type `MERGE` doesn't check whether the underlying tables are compatible types.

- If you use `ALTER TABLE` to add a `UNIQUE` index to a table used in a `MERGE` table and then add a normal index on the `MERGE` table, the key order is different for the tables if there was an old, non-`UNIQUE` key in the table. This is because `ALTER TABLE` puts `UNIQUE` indexes before normal indexes to be able to detect duplicate keys as early as possible.

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

Anterior |  | Siguiente
Capítulo 27. Extender MySQL | Inicio | Apéndice B. Credits