Capítulo 5. Administración de bases de datos
Anterior |  | Siguiente

## Capítulo 5. Administración de bases de datos

Este capítulo cubre tópicos que tratan la administración de una instalación de MySQL, como configurar el servidor, administrar cuentas de usuario y realizar copias de seguridad.

## 5.1. El servidor MySQL y scripts de arranque del servidor

MySQL server, mysqld, es el programa principal que realiza la mayoría del trabajo en una instalación MySQL. El servidor está acompañado por varios scripts que realizan operaciones de inicialización cuando instala MySQL o se tratan de programas de ayuda para asistirle en la inicialización y parada del servidor.

Esta sección proporciona una visión global del servidor y de los programas relacionados, e información acerca de los scripts de inicialización del servidor. La información acerca de configurar el servidor se proporciona en Sección 5.3, “Configuración del servidor MySQL”.

### 5.1.1. Panorámica de los programas scripts y las utilidades del lado del servidor (server-side)

Todos los programas MySQL aceptan diferentes opciones. Sin embargo, cada programa MySQL proporciona una opción `--help` que puede usar para obtener una descripción de las opciones del programa. Por ejemplo, pruebe mysqld --help.

Puede cambiar las opciones por defecto en todos los programas estándard especificando opciones en la línea de comandos o en un fichero de opciones. Sección 4.3, “Especificar opciones de programa”.

La siguiente lista describe brevemente MySQL server y sus programas relacionados:

- mysqld

  El demonio SQL (esto es, el servidor MySQL). Para usar programas clientes, este programa debe estar en ejecución, ya que los programas ganan el acceso a la base de datos conectándose al servidor. Consulte Sección 5.3, “Configuración del servidor MySQL”.

- `mysqld-max`

  Una versión del servidor que incluye características adicionales. Consulte Sección 5.1.2, “El servidor extendido de MySQL mysqld-max”.

- `mysqld_safe`

  Un script de arranque del servidor. mysqld_safe intenta inicializar mysqld-max si existe, y mysqld en caso contrario. Consulte Sección 5.1.3, “El script de arranque del servidor mysqld_safe”.

- `mysql.server`

  Un script de arranque del servidor. Este script se usa en sistemas que utilizan directorios de ejecución que contienen scripts que inicializan servicios para niveles de ejecución particular. Invoque mysqld_safe para inicializar el servidor MySQL. Consulte Sección 5.1.4, “El script mysql.server para el arranque del servidor”.

- `mysqld_multi`

  Un script de arranque del servidor que puede arrancar o parar varios servidores instalados en el sistema. Consulte Sección 5.1.5, “El programa mysqld_multi para gestionar múltiples servidores MySQL”.

- `mysql_install_db`

  Este script crea las tablas de permisos de MySQL con privilegios por defecto. Normalmente se ejecuta sólo una vez, cuando se instala por primera vez MySQL en el sistema. Consulte Sección 2.9.2, “Pasos a seguir después de la instalación en Unix”.

- mysql_fix_privilege_tables

  Este script se usa tras una actualización, para actualizar las tablas de permisos con cualquier cambio que se hayan hecho en nuevas versiones de MySQL. Consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

Hay otros programas que también se ejecutan en la máquina del servidor:

- `myisamchk`

  Una utilidad para describir, testear, optimizar y reparar tablas `MyISAM`. myisamchk se describe en Sección 5.8.3, “Mantenimiento de tablas y recuperación de un fallo catastrófico (crash)”.

- `make_binary_distribution`

  Este programa crea una publicación binaria de un MySQL compilado. Puede enviarse por FTP a `/pub/mysql/upload/` a `ftp.mysql.com` para el uso de otros usuarios de MySQL.

- `mysqlbug`

  El script para reportar bugs. Puede usarse para enviar un reporte de bug a la lista de correo de MySQL. (Puede visitar http://bugs.mysql.com/ para rellenar un reporte de bug en línea. Consulte Sección 1.6.1.3, “Cómo informar de bugs y problemas”.)

### 5.1.2. El servidor extendido de MySQL mysqld-max

El servidor MySQL-Maxk es una versión del servidor MySQL mysqld compilada para añadir características adicionales.

La distribución a usar depende de la plataforma:

- Para Windows, las distribuciones binarias de MySQL incluyen ambos servidores (`mysqld.exe`) y el servidor MySQL-Max (mysqld-max.exe), por lo que no es necesario adquirir ninguna distribución especial. Símplemente use una distribución normal para Windows, disponible en http://dev.mysql.com/downloads/. Consulte Sección 2.3, “Instalar MySQL en Windows”.

- Para Linux, si instala MySQL utilizando una distribución RPM, use el RPM `MySQL-server` en primer lugar para instalar una versión estándard del servidor llamada mysqld. A continuación use el RPM `MySQL-Max` para instalar el servidor llamado mysqld-max. El RPM `MySQL-Max` presupone que el RPM con el servidor normal está instalado. Consulte Sección 2.4, “Instalar MySQL en Linux” para más información sobre los paquetes RPM para Linux.

- Todas las otras distribuciones MySQL-Max contienen un único servidor llamado mysqld pero que tiene las características adicionales incluídas.

Puede encontrar los binarios para MySQL-Max en la página Web de MySQL AB en http://dev.mysql.com/downloads/.

MySQL AB compila el servidor MySQL-Max usando las siguientes opciones de configure:

- `--with-server-suffix=-max`

  Esta opción añade un sufijo `-max` a la cadena de carácteres mysqld de la versión.

- `--with-innodb`

  Esta opción activa el soporte para el motor de almacenamiento InnoDB. Los servidores MySQL-Max siempre incluyen soporte para InnoDB . Desde MySQL 4.0 en adelante, se incluye por defecto InnoDB en todas las distribuciones binarias, por lo que no necesita un servidor MySQL-Max simplemente para obtener soporte para InnoDB.

- `--with-bdb`

  Esta opción activa el soporte para el motor de almacenamiento Berkeley DB (BDB).

- `USE_SYMDIR`

  Esta definición está activada para activar el soporte para links simbólicos en Windows. En MySQL 5.0, el soporte para links simbólicos está disponible para todos los servidores Windows, así que un servidor Max no es necesario para aprovechar esta característica.

- `--with-ndb-cluster`

  Esta opción activa el soporte para el motor de almacenamiento NDB Cluster . Actualmente (como en5.0.9-beta), el Cluster se soporta en Linux, Solaris, y Mac OS X solamente. Algunos usuarios han reportado éxitos al utilizar MySQL Cluster compilado de las fuentes en sistemas operativos basados en BSD, pero no están soportados oficialmente de momento.

Las distribuciones binarias de MySQL-Max son útiles para aquéllos que quieran instalar programas precompilados. Si compila MySQL a partir de una distribución fuente, puede construir su propio servidor de estilo Max activando las mismas características en tiempo de configuración que usan las distribuciones binarias de MySQL-Max al ser creadas.

Los servidores MySQL-Max incluyen el motor de almacenamiento BerkeleyDB (BDB) cuando es posible, pero no todas las plataformas soportan BDB.

Los servidores MySQL-Max para Solaris, Mac OS X, y Linux (en la mayoría de plataformas) incluyen soporte para el motor de almacenamiento NDB Cluster . Tenga en cuenta que el servidor debe reiniciarse con la opción `ndbcluster` para ejecutar el servidor como parte de un MySQL Cluster. (Para más detalles, consulte Sección 16.4, “Configuración de MySQL Cluster”.)

La siguiente tabla muestra en qué plataformas los binarios de MySQL-Max incluyen soporte para BDB y/o NDB Cluster:

Sistema | Soporte BDB | Soporte NDB
AIX 4.3 | N | N
HP-UX 11.0 | N | N
Linux-Alpha | N | S
Linux-IA-64 | N | N
Linux-Intel | S | S
Mac OS X | N | N
NetWare | N | N
SCO OSR5 | S | N
Solaris-SPARC | S | S
Solaris-Intel | N | S
UnixWare | S | N
Windows NT/2000/XP | S | N

Para ver los motores de almacenamiento que soporta su servidor, ejecute el siguiente comando:

    mysql> SHOW ENGINES;
    +------------+---------+----------------------------------------------------------------+
    | Engine     | Support | Comment                                                        |
    +------------+---------+----------------------------------------------------------------+
    | MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance         |
    | MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables      |
    | HEAP       | YES     | Alias for MEMORY                                               |
    | MERGE      | YES     | Collection of identical MyISAM tables                          |
    | MRG_MYISAM | YES     | Alias for MERGE                                                |
    | ISAM       | NO      | Obsolete storage engine, now replaced by MyISAM                |
    | MRG_ISAM   | NO      | Obsolete storage engine, now replaced by MERGE                 |
    | InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys     |
    | INNOBASE   | YES     | Alias for INNODB                                               |
    | BDB        | YES     | Supports transactions and page-level locking                   |
    | BERKELEYDB | YES     | Alias for BDB                                                  |
    | NDBCLUSTER | NO      | Clustered, fault-tolerant, memory-based tables                 |
    | NDB        | NO      | Alias for NDBCLUSTER                                           |
    | EXAMPLE    | NO      | Example storage engine                                         |
    | ARCHIVE    | YES     | Archive storage engine                                         |
    | CSV        | NO      | CSV storage engine                                             |
    | FEDERATED  | YES     | Federated MySQL storage engine                                 |
    | BLACKHOLE  | YES     | /dev/null storage engine (anything you write to it disappears) |
    +------------+---------+----------------------------------------------------------------+
    18 rows in set (0.00 sec)

(Consulte también Sección 13.5.4.8, “Sintaxis de `SHOW ENGINES`”.)

Antes de MySQL 4.1.2, `SHOW ENGINES` no está disponible. Use el siguiente comando en su lugar y compruebe que el valor de la variable para el motor de almacenamiento en que está interesado:

    mysql> SHOW VARIABLES LIKE 'have%';
    +-----------------------+-------+
    | Variable_name         | Value |
    +-----------------------+-------+
    | have_archive          | YES   |
    | have_bdb              | YES   |
    | have_blackhole_engine | YES   |
    | have_compress         | YES   |
    | have_crypt            | NO    |
    | have_csv              | NO    |
    | have_example_engine   | NO    |
    | have_federated_engine | YES   |
    | have_geometry         | YES   |
    | have_innodb           | YES   |
    | have_isam             | NO    |
    | have_ndbcluster       | NO    |
    | have_openssl          | YES   |
    | have_query_cache      | YES   |
    | have_raid             | NO    |
    | have_rtree_keys       | YES   |
    | have_symlink          | YES   |
    +-----------------------+-------+
    17 rows in set (0.06 sec)

La salida precisa de estos comandos `SHOW` variará en función de la versión de MySQL usada (y las características que haya activadas). Los valores en la segunda columna indican el nivel de soporte por parte del servidor para cada característica, como se muestra:

Valor | Significado
`YES` | La característica se soporta y está activa.
`NO` | La característica no se soporta.
`DISABLED` | La característica se soporta pero no está activa.

Un valor `NO` significa que el servidor está compilado sin soporte para la característica, por lo que no puede activarse en tiempo de ejecución.

Un valor `DISABLED` aparece porque el servidor se arrancó con una opción que deshabilita la característica, o porque no todas las opciones requeridas para activarla se han dado. En el último caso, el fichero de log de error ``host_name`.err` debería contener la razón indicando porqué la opción está deshabilitada.

Puede ver el mensaje `DISABLED` para los motores de almacenamiento `InnoDB`, `BDB`, o `ISAM` si el servidor está compilado para soportarlos pero se arrancó con las opciones `--skip-innodb`, `--skip-bdb`, o `--skip-isam` en tiempo de ejecución.

Todos los servidores MySQL soportan tablas `MyISAM` , ya que `MyISAM` es el motor de almacenamiento por defecto.

### 5.1.3. El script de arranque del servidor mysqld_safe

mysqld_safe es la manera recomendada de iniciar mysqld un servidor en Unix y NetWare mysqld_safe añade algunas características de seguridad como reiniciar el servidor cuando ocurre un error y guardar la información en tiempo de ejecución en un registro de errores. Los comportamientos especificos de NetWare se mencionan más adelante en esta sección.

Nota: Para preservar la compatibilidad con antiguas versiones de MySQL, las distribuciones binarias de MySQL todavía incluyen safe_mysqld como en enlace simbólico a mysqld_safe. Aún asi, no se debería confiar en esto ya que con toda certeza será eliminado en el futuro.

Por defecto, mysqld_safe intenta lanzar un ejecutable llamado mysqld-max si existe, o mysqld en otro caso. Deben tenerse en cuenta las implicaciones de este comportamiento:

- En Linux, el paquete RPM de `MySQL-Max` se basa en este comportamiento de mysqld_safe. El RPM instala un ejecutable llamado mysqld-max, que causa que mysqld_safe use automáticamente ese ejecutable a partir de ese momento.

- Si se instala una distribucion MySQL-Max que incluye un servidor llamado mysqld-max, y después se actualiza a una version no-Max de MySQL, mysqld_safe todavía intentará ejecutar el viejo servidor mysqld-max. Si se realiza una actualizacion tal, se debe eliminar manualmente el viejo servidor mysqld-max para asegurarse de que mysqld_safe ejecuta el nuevo servidor mysqld.

Para reemplazar el comportamiento por defecto y especificar explícitamente qué servidor se quiere ejecutar, se debe especificar la opción `--mysqld` o la opción `--mysqld-version` de mysqld_safe.

Muchas de las opciones de mysqld_safe son las mismas que las opciones de mysqld. Consulte Sección 5.3.1, “Opciones del comando mysqld”.

Todas las opciones específicas de mysqld_safe en la línea de comandos se pasan a mysqld. Si se desea utilizar alguna opción que es específica de mysqld_safe y que mysqld no soporta, no debe especificarse en la línea de comandos. En vez de eso, debe listarse en el grupo `[mysqld_safe]` de un archivo de opciones. Consulte Sección 4.3.2, “Usar ficheros de opciones”.

mysqld_safe lee todas las opciones de las secciones `[mysqld]`, `[server]`, y `[mysqld_safe]` de los archivos de opciones. Por compatibilidad con versiones anteriores, también lee las secciones `[safe_mysqld]`, aunque deben renombrarse dichas secciones a `[mysqld_safe]` en MySQL 5.0.

mysqld_safe soporta las siguientes opciones:

- `--help`

  Muestra un mensaje de ayuda y finaliza. (Añadido en MySQL 5.0.3)

- `--basedir=`ruta``

  La ruta al directorio de instalacion de MySQL.

- `--core-file-size=`tamaño``

  El tamaño del archivo de volcado de memoria que mysqld debería ser capaz de crear. El valor de la opción se pasa a ulimit -c.

- `--datadir=`ruta``

  La ruta al directorio de datos.

- `--defaults-extra-file=`ruta``

  El nombre de un archivo de opciones para ser leído además de los habituales.

- `--defaults-file=`ruta``

  El nombre de un archivo de opciones para ser leído en vez de los habituales.

- `--ledir=`ruta``

  La ruta a el directorio que contiene el programa mysqld. Se utiliza esta opción para indicar explícitamente la localización del servidor.

- `--log-error=`ruta``

  Escribir el registro de errores en el archivo dado. Consulte Sección 5.10.1, “El registro de errroes (Error Log)”.

- `--mysqld=`nombre_prog``

  El nombre del programa servidor (en el directorio `ledir`) que se quiere ejecutar. Esta opción es necesaria si se utiliza la distribución binaria de MySQL pero el directorio de datos está fuera de la distribución binaria.

- `--mysqld-version=`sufijo``

  Esta opción es similar a la opción `--mysqld`, pero se especifica únicamente el sufijo para el nombre del programa servidor. El nombre base se asume que es mysqld. Por ejemplo, si se usa `--mysqld-version=max`, mysqld_safe inicia el programa en el directorio `ledir`. Si el argumento de `--mysqld-version` está vacio, mysqld_safe usa mysqld en el directorio `ledir`.

- `--nice=`prioridad``

  Se utiliza el programa `nice` para establecer la prioridad del servidor a un valor dado.

- `--no-defaults`

  No leer ningún archivo de opciones.

- `--open-files-limit=`número``

  El número de ficheros que mysqld debería ser capaz de abrir. El valor de la opción se pasa a ulimit -n. Nótese que se necesita iniciar mysqld_safe como `root` para que esto funcione correctamente.

- `--pid-file=`ruta``

  La ruta al archivo de ID del proceso.

- `--port=`num_puerto``

  El número de puerto a usar cuando se esperan conexiones TCP/IP.

- `--socket=`ruta``

  El archivo de socket de unix a utilizar para conexiones locales.

- `--timezone=`zona``

  Establece la variable de ambiente de zona horaria `TZ` a el valor dado. Consúlte la documentación del sistema operativo para formatos legales de especificación de zonas horarias.

- `--user={`nombre_usuario` | `id_usuario`}`

  Ejecuta el servidor mysqld como el usuario con nombre `nombre_usuario` o el ID numérico de usuario `id_usuario`. (``Usuario'' en este contexto se refiere a una cuenta de login del sistema, no a un usuario MySQL incluído en las tablas grant.)

El script mysqld_safe está escrito de manera que normalmente puede iniciar un servidor que ha sido instalado tanto desde código fuente o desde una distribución binaria de MySQL, aún cuando típicamente estos tipos de distribuciones instalan el servidor en lugares ligeramente diferentes. (Consulte Sección 2.1.5, “Conformación de la instalación”.) mysqld_safe espera que una de las siguientes condiciones sea cierta:

- El servidor y las bases de datos pueden ser encontradas en una ruta relativa al directorio desde el que mysqld_safe es invocado. Para distribuciones binarias, mysqld_safe busca bajo su directorio de trabajo los directorios `bin` y `data`. En distribuciones de código fuente, busca los directorios `libexec` y `var`. Esta condición debe cumplirse si se ejecuta mysqld_safe desde el directorio de instalación de MySQL (por ejemplo, `/usr/local/mysql` para una distribución binaria).

- Si el servidor y las bases de datos no pueden encontrarse en una ruta relativa al directorio de trabajo, mysqld_safe intenta localizarlos mediante rutas absolutas. `/usr/local/libexec` y `/usr/local/var` son localizaciones típicas. Las localizaciones efectivas se determinan por los valores configurados en la distribución en el momento en que fue creada. Deberían ser correctos si MySQL está instalado en la localización especificada en el momento de la configuración.

Debido a que mysqld_safe trata de encontrar el servidor y las bases de datos de manera relativa a su propio directorio de trabajo, puede instalarse una distribución binaria de MySQL en cualquier lugar, siempre y cuando se ejecute mysqld_safe desde el directorio de instalación de MySQL:

    shell> cd directorio_instalacion_mysql
    shell> bin/mysqld_safe &

Si mysqld_safe falla, aún cuando ha sido invocado desde el directorio de instalación de MySQL, se pueden especificar las opciones `--ledir` y `--datadir` para indicar los directorios en los que el servidor y las bases de datos están dentro del sistema.

Normalmente, no se debería editar el script mysqld_safe. En vez de ello, ha de configurarse mysqld_safe utilizando opciones de línea de comandos u opciones en la sección `[mysqld_safe]` de un archivo de opciones `my.cnf`. En casos aislados, podría ser necesario editar mysqld_safe para que inicie el servidor apropiadamente. No obstante, si se hace esto, la versión modificada de mysqld_safe podría ser sobreescrita si se actualiza la versión de MySQL en el futuro, así que debería hacerse una copia de la versión editada que pudiera reinstalarse.

En NetWare, mysqld_safe es un NetWare Loadable Module (NLM) que ha sido portado desde el script original de Unix. Hace lo siguiente:

1. Ejecuta un número de comprobaciones del sistema y de opciones.

2. Ejecuta comprobaciones sobre tablas `MyISAM`.

3. Provee de una presencia en pantalla a el servidor MySQL.

4. Inicia mysqld, lo supervisa, y lo reinicia si termina con error.

5. Envía mensajes de error desde mysqld a el archivo ``host_name`.err` en el directorio de datos.

6. Envía la salida por pantalla de mysqld_safe hacia el archivo ``host_name`.safe` en el directorio de datos.

### 5.1.4. El script mysql.server para el arranque del servidor

Las distribuciones de MySQL en Unix incluyen un script llamado mysql.server. Puede usarse en sistemas tales como Linux y Solaris que usan directorios de ejecución estilo System V para arrancar y parar servicios del sistema. También lo usa el Startup Item de Mac OS X para MySQL.

mysql.server puede encontrarse en el directorio `support-files` bajo el directorio de instalación de MySQL o en el árbol fuente de MySQL.

Si usa el paquete de Linux RPM para el servidor (`MySQL-server-`VERSION`.rpm`), el script mysql.server se instalará en el directorio `/etc/init.d` con el nombre `mysql`. No necesita instalarlo manualmente. Consulte Sección 2.4, “Instalar MySQL en Linux” para más información acerca de los paquetes RPM para Linux.

Algunos vendedores proporcionan paquetes RPM que instalan un script de instalación bajo nombres diferentes tales como mysqld.

Si instala MySQL de una distribución fuente o usando un formato binario de distribución que no instala mysql.server automáticamente, puede instalarlo manualmente. Las instrucciones se proporcionan en Sección 2.9.2.2, “Arrancar y parar MySQL automáticamente”.

mysql.server lee opciones de las secciones `[mysql.server]` y `[mysqld]` de los ficheros de opciones. (Para compatibilidad con versiones anteriores, también lee las secciones `[mysql_server]`, aunque debe renombrar dichas secciones como `[mysql.server]` cuando use MySQL 5.0.)

### 5.1.5. El programa mysqld_multi para gestionar múltiples servidores MySQL

mysqld_multi se utiliza para administrar diversos procesos mysqld que esperan conexiones en diferentes archivos socket en Unix y puertos TCP/IP. Puede arrancar o parar servidores, o reportar su estado actual.

El programa busca grupos llamados `[mysqld#]` en `my.cnf` (o en el fichero nombrado por la opción `--config-file`). `#` puede ser cualquier entero positivo. Nos referiremos a este número como el número del grupo de opciones en la siguiente discusión, o `GNR` (N. del T.: acrónimo en ingés). Los números de grupo distinguen grupos de opciones de otros y se usan como argumentos para mysqld_multi para especificar qué servidores quiere arrancar, parar, u obtener un reporte de estatus. Las opciones listadas en esos grupos son las mismas que usaría en el grupo `[mysqld]` para arranacar mysqld. (Consulte, por ejemplo, Sección 2.9.2.2, “Arrancar y parar MySQL automáticamente”.) Sin embargo, cuando use múltiples servidores es necesario que cada uno use su propio valor para opciones tales como el fichero de socket de Unix y el número del puerto TCP/IP. Para más información sobre qué opciones deben ser únicas por servidor en un entorno de múltiples sevidores, consulte Sección 5.11, “Ejecutar más de un servidor MySQL en la misma máquina”.

Para invocar mysqld_multi, use la siguiente sintaxis:

    shell> mysqld_multi [options] {start|stop|report} [GNR[,GNR]...]

`start`, `stop`, y `report` indican qué operaciones desea realizar. Puede realizar la operación designada en un único servidor o en múltiples servidores, dependiendo de la lista `GNR` que sigue al nombre de la opción. Si no hay ninguna lista, mysqld_multi realiza la operación para todos los servidores en el fichero de opciones.

Cada valor `GNR` representa un número de grupo de opciones o rango de números de grupo. El valor debe ser un número al final de un nombre de grupo en el fichero de opciones. Por ejemplo, el `GNR` para un grupo llamado `[mysqld17]` es `17`. Para especificar un rango de números, separe el primero y último número por un guión. El valor `GNR` `10-13` reperesenta los grupos desde `[mysqld10]` hasta `[mysqld13]`. Multiples grupos o rangos de grupos pueden especificarse en la línea de comandos, separados por comas. No deben haber caráceteres de espacios en blanco (espacios o tabuladores) en la lista+ `GNR` ; cualquier cosa después de un carácter de espacio en blanco se ignora.

Este comando arranca un único servidor usando el grupo de opciones `[mysqld17]`:

    shell> mysqld_multi start 17

Este comando para diversos servidores, usando los grupos de opciones `[mysql8]` y del `[mysqld10]` hasta el `[mysqld13]`:

    shell> mysqld_multi stop 8,10-13

Para un ejemplo sobre cómo puede crear un fichero de opciones, use este comando:

    shell> mysqld_multi --example

mysqld_multi soporta las siguientes opciones:

- `--config-file=`nombre``

  Especifique el nombre de un fichero de opciones alternativo. Esto afecta a dónde mysqld_multi busca grupos de opciones `[mysqld#]` . Sin esta opción todas las opciones se leen del fichero habitual `my.cnf`. La opción no afecta a dónde mysqld_multi lee sus propias opciones, que siempre se toman del grupo `[mysqld_multi]` en el fichero habitual `my.cnf`.

- `--example`

  Muestra un fichero de opciones de ejemplo..

- `--help`

  Muestra un mensaje de ayuda y sale.

- `--log=`nombre``

  Especifica el nombre del fichero de log. Si el fichero existe, la salida de log se añade al mismo.

- `--mysqladmin=`prog_name``

  El binario mysqladmin a usar para parar los servidores.

- `--mysqld=`prog_name``

  El binario mysqld a usar. Tenga en cuenta que puede especificar mysqld_safe como el valor para esta opción. Las opciones se pasan a mysqld. Sólo asegúrese que tiene el directorio donde se encuentra mysqld en su variable de entorno `PATH` o fije mysqld_safe.

- `--no-log`

  Muestra información del log en el stdout en lugar del fichero de log. Por defecto, la salida va al fichero de log.

- `--password=`password``

  La constraseña de la cuenta MySQL a usar cuando invoque mysqladmin. Tenga en cuenta que el valor de la contraseña no es opcional para esta opción, no como en otros programas MySQL.

- `--silent`

  Desactiva los mensajes de advertencia.

- `--tcp-ip`

  Se conecta a cada servidor MySQL via puerto TCP/IP en lugar del fichero socket Unix. (Si un fichero socket no se encuentra, el servidor puede ejecutarse, pero accesible sólo via puerto TCP/IP.) Por defecto, las conexiones se hacen usando un fichero socket Unix. Esta opción afecta las operaciones `stop` y `report`.

- `--user=`user_name``

  El nombre de usuario de la cuenta MySQL a usar al invocar mysqladmin.

- `--verbose`

  Es más detallado.

- `--version`

  Muestra información sobre la versión y sale.

Apuntes acerca de mysqld_multi:

- Asegúrese que la cuenta MySQL usada para parar los servidores mysqld (con el programa mysqladmin ) tienen el mismo nombre de usuario y contraseña para cada servidor. También asegúrese que la cuenta tiene el privilegio `SHUTDOWN`. Si los servidores que quiere administrar tienen distintos nombres de usuario o contraseñas para las cuentas administrativas, puede querer crear una cuenta en cada servidor que tenga el mismo nombre de usuario y contraseña. Por ejemplo, puede inicializar una cuenta común `multi_admin` ejecutando el siguiente comando en cada servidor:

      shell> mysql -u root -S /tmp/mysql.sock -proot_password
      mysql> GRANT SHUTDOWN ON *.*
          -> TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass';

  Consulte Sección 5.6.2, “Cómo funciona el sistema de privilegios”. Tiene que hacerlo para cada servidor mysqld. Cambie los parámetros de conexión apropiadamente cuando se conecte a cada uno. Tenga en cuenta que la parte de servidor del nombre de la cuenta debe permitirle conectarse como `multi_admin` desde el servidor desde el que quiere ejecutar mysqld_multi.

- La opción `--pid-file` es muy importante si está usando mysqld_safe para arrancar mysqld (por ejemplo, `--mysqld=mysqld_safe`) Cada mysqld debe tener su propio fichero con el ID de proceso. La ventaja de usar mysqld_safe en lugar de mysqld es que mysqld_safe ``guarda'' su proceso mysqld y lo reinicia si el proceso termina debido a una señal enviada usando `kill -9` o por otras razones, tales como un segmentation fault. Por favor, tenga en cuenta que el script mysqld_safe puede requerir que lo arranque desde un lugar determinado. Esto significa que puede tener que cambiar la localización a un cierto directorio antes de ejecutar mysqld_multi. Si tiene problemas arrancando, por favor consulte el script mysqld_safe. Compruebe especialmente las líneas:

      ----------------------------------------------------------------
      MY_PWD=`pwd`
      # Check if we are starting this relative (for the binary release)
      if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
       -x ./bin/mysqld
      ----------------------------------------------------------------

  Consulte Sección 5.1.3, “El script de arranque del servidor mysqld_safe”. Los chequeos realizados por estas líneas deberían tener éxito, o podría encontrar problemas.

- El fichero socket de Unix y el puerto TCP/IP deben ser diferentes para cada mysqld.

- Puede usar la opción `--user` para mysqld, pero para hacerlo debe ejecutar el script mysqld_multi como el usuario `root` en Unix. Tener la opción en el fichero de opciones no importa; sólo obtiene una advertencia si no es el súper usuario y los procesos mysqld se inician bajo su propia cuenta Unix.

- Importante: Asegúrese que el directorio de datos es completamente accesible para todas las cuentas Unix con las que puedea iniciarse el proceso mysqld. No use la cuenta root de Unix para ello, a no ser que sepa lo que hace.

- Más importante: Antes de usar mysqld_multi aségurese de entender el significado de las opciones que se pasan a los servidores mysqld y porqué quiere tener procesos mysqld separados. Cuidado con los peligros de usar múltipes servidores mysqld con el mismo directorio de datos. Use diferentes directorios de datos, a no ser que sepa lo que hace. Iniciar múltiples servidores con el mismo directorio de datos no proporciona mejor rendimiento en un entorno threaded. Consulte Sección 5.11, “Ejecutar más de un servidor MySQL en la misma máquina”.

El siguiente ejemplo muestra como podría inicializar un fichero de opciones para usar con mysqld_multi. El primer y quinto grupo `[mysqld#]` se ha omitido intencionadamente del ejemplo para ilustrar que puede tener ``vacíos'' en el fichero de opciones. Esto proporciona una mayor flexibilidad. El order en que los programas mysqld arrancan o se paran depende del order en que aparecen en el fichero de opciones.

    # This file should probably be in your home dir (~/.my.cnf)
    # or /etc/my.cnf
    # Version 2.1 by Jani Tolonen

    [mysqld_multi]
    mysqld     = /usr/local/bin/mysqld_safe
    mysqladmin = /usr/local/bin/mysqladmin
    user       = multi_admin
    password   = multipass

    [mysqld2]
    socket     = /tmp/mysql.sock2
    port       = 3307
    pid-file   = /usr/local/mysql/var2/hostname.pid2
    datadir    = /usr/local/mysql/var2
    language   = /usr/local/share/mysql/english
    user       = john

    [mysqld3]
    socket     = /tmp/mysql.sock3
    port       = 3308
    pid-file   = /usr/local/mysql/var3/hostname.pid3
    datadir    = /usr/local/mysql/var3
    language   = /usr/local/share/mysql/swedish
    user       = monty

    [mysqld4]
    socket     = /tmp/mysql.sock4
    port       = 3309
    pid-file   = /usr/local/mysql/var4/hostname.pid4
    datadir    = /usr/local/mysql/var4
    language   = /usr/local/share/mysql/estonia
    user       = tonu

    [mysqld6]
    socket     = /tmp/mysql.sock6
    port       = 3311
    pid-file   = /usr/local/mysql/var6/hostname.pid6
    datadir    = /usr/local/mysql/var6
    language   = /usr/local/share/mysql/japanese
    user       = jani

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

## 5.2. El gestor de instancias de MySQL

Esta sección discute el uso del MySQL Instance Manager (IM). Este es el demonio que corre en el puerto TCP/IP, el cual provee monitoreo y administración de las instancias del servidor de datos MySQL. MySQL Instance Manager está disponible para sistemas operativos basados en Unix.

MySQL Instance Manager se incluye en las distribuciones de MySQL desde la versión 5.0.3, y puede usarse en lugar del script `mysqld_safe` para arrancar y parar MySQL Server, incluso desde una máquina remota. MySQL Instance Manager implementa la funcionalidad (y la mayoría de la sintaxis) del script mysqld_multi . Una descripción más detallada de MySQL Instance Manager a continuación.

### 5.2.1. Arrancar el servidor MySQL con el gestor de instancias MySQL

Normalmente, el servidor de bases de datos MySQL se arranca con el script mysql.server, que normalmente reside en el directorio `/etc/init.d/` . En MySQL 5.0.3 este script invoca mysqlmanager (el binario de MySQL Instance Manager ) para arrancar MySQL. (En versiones previas de MySQL el script mysqld_safe se usa con este propósito.) A partir de MySQL 5.0.4 el comportamiento del script de inicio ha cambiado de nuevo para incorporar ambos esquemas de inicialización. En la versión 5.0.4, el scrip de arranque usa el antiguo esquema (invocando mysqld_safe) por defecto, pero se puede cambiar la variable `use_mysqld_safe` en el script a `0` (cero) para usar el MySQL Instance Manager para arranacar un servidor.

El comportamiento del Instance Manager en este caso depende de las opciones dadas en el fichero de configuración de MySQL. Si no hay fichero de configuración, el MySQL Instance Manager crea una instancia llamada `mysqld` y trata de arrancarla con los valores por defectos (compilados). Esto significa que el IM no puede adivinar la localización de mysqld si no está instalado en la localización por defecto. Si ha instalado MySQL server en una localización no estándard, debe usar un fichero de configuración. Consulte Sección 2.1.5, “Conformación de la instalación”.

Si hay un fichero de configuración, el IM parseará el fichero de configuración en búsqueda de las secciones `[mysqld]` (P.e. `[mysqld]`, `[mysqld1]`, `[mysqld2]`, etc.) Cada una de esas secciones especifica una instancia. Al arrancar, el IM arrancará todas las instancias encontradas. El IM para todas las instancias al cerrar por defecto.

Tenga en cuenta que hay una opción especial `mysqld-path` (`mysqld-path = <path-to-mysqld-binary>`) reconocida sólo por el IM. Use esta variable para que IM conozca dónde reside el binario mysqld. También debe inicializar las opciones `basedir` y `datadir` para el servidor.

El típico ciclo de arranque/cierre para un servidor MySQL con el MySQL Instance Manager habilitado es como sigue:

- El MySQL Instance Manager se arranca con el script /etc/init.d/mysql.

- El MySQL Instance Manager arranca todas las instancias y las monitoriza.

- Si una instancia de un servidor cae, el MySQL Instance Manager la reinicia.

- Si el MySQL Instance Manager se cierra (por ejemplo con el comando /etc/init.d/mysql stop), todas las instancias se apagan con el MySQL Instance Manager.

### 5.2.2. Conexión al gestor de instancias de MySQL y creación de cuentas de usuario

La comunicación con el MySQL Instance Manager se hace usando el protocolo cliente-servidor de MySQL. Con el mismo, puede conectarse al IM usando el program cliente estándard mysql , así como con la API de C MySQL. El IM soporta la versión del protocolo cliente- servidor MySQL usada por las herramientas de cliente y bibliotecas distribuidas a partir de la versión mysql-4.1.

El IM almacena su información de usuario en un fichero de contraseñas. La localización por defecto para el fichero de contraseñas es `/etc/mysqlmanager.passwd`

Las entradas para las contraseñas se parecen a las siguiente:

    petr:*35110DC9B4D8140F5DE667E28C72DD2597B5C848

Para generar una entrada así debe invocarse IM con la opción --passwd . Entonces puede redirigir la salida a `/etc/mysqlmanager.passwd` para añadir un nuevo usuario. Un comando de ejemplo a continuación.

    ./mysqlmanager --passwd >> /etc/mysqlmanager.passwd
    Creating record for new user.
    Enter user name: mike
    Enter password: <password>
    Re-type password: <password>

La siguiente línea se añade a `/etc/mysqlmanager.passwd`:

    mike:*00A51F3F48415C7D4E8908980D443C29C69B60C9

Si no hay entradas en el fichero `/etc/mysqlmanager.passwd` no puede conectarse al IM.

### 5.2.3. Opciones de los comandos del gestor de instancias MySQL

El MySQL Instance Manager soporta varias opciones de línea de comando. Una breve lista está disponible ejecutando el comando ./mysqlmanager --help . Los siguientes comandos están disponibles:

- `-?, --help`

  Muestra la ayuda y sale..

- `--log=name`

  Ruta al fichero de log del IM. Se usa con la opción --run-as-service.

- `--pid-file=name`

  Fichero Pid a usar. Por defecto es `mysqlmanager.pid`.

- `--socket=name`

  Fichero socket a usar por las conexiones. Por defecto es `/tmp/mysqlmanager.sock`.

- `-P, --passwd`

  Prepara entrada para fichero passwd y salir.

- `--bind-address=name`

  Dirección enlazada para usar en conexiones.

- `--port=#`

  Número de puerto para usar en conexiones (número de puerto por defecto, asignado por la IANA, es el 2273).

- `--password-file=name`

  Busca los usuarios y contraseñas para el Instance Manger aquí. El fichero por defecto es `/etc/mysqlmanager.passwd`.

- `--default-mysqld-path=name`

  Dónde buscar el binario para el MySQL Server si no se proporciona un path en la sección de instancias. Ejemplo: `default-mysqld-path = /usr/sbin/mysqld`.

- `--monitoring-interval=#`

  Intervalo en segundos para monitorizar instancias. El IM tratará de conectar a cada una de las instancias monitorizadas para comprobar si están vivas / no colgadas. En caso de un fallo el IM realizará varios (de hecho muchos) intentos de reiniciar la instancia. Puede desactivar este comportamiento para instancias particulares con la opción `nonguarded` en la sección de instancia apropiada. Si no se proporciona ningún valor, se usan 20 segundos por defecto.

- `--run-as-service`

  Demoniza y arranca el proceso ángel. El proceso ángel es simple y difícil de que falle. Reinicia el IM en caso de fallo.

- `--user=name`

  Nombre de usuario para arrancar y ejecutar mysqlmanager. Se recomienda ejecutar mysqlmanager bajo la misma cuenta de usuario usada para ejectuar el servidor mysqld.

- `-V, --version`

  Muestra información de la versión y sale.

### 5.2.4. Ficheros de configuración del gestor de instancias de MySQL

El Instance Manager usa el fichero estándard `my.cnf`. Usa la sección `[manager]` para leer opciones para sí mismo y la sección `[mysqld]` para crear instancias. La sección `[manager]` contiene algunas de las opciones listadas anteriormente. Un ejemplo de la sección `[manager]` a continuación:

    # MySQL Instance Manager options section
    [manager]
    default-mysqld-path = /usr/local/mysql/libexec/mysqld
    socket=/tmp/manager.sock
    pid-file=/tmp/manager.pid
    password-file = /home/cps/.mysqlmanager.passwd
    monitoring-interval = 2
    port = 1999
    bind-address = 192.168.1.5

Las secciones de instancias especifican opciones dadas a cada instancia al arrancar. La mayoría son comunes con las opciones de MySQL Server, pero hay algunas específicas para el IM:

- `mysqld-path = <path-to-mysqld-binary>`

  La ruta al binario del servidor mysqld.

- `shutdown-delay = #`

  Número de segundos que IM debe esperar para que una instancia se cierre. Por defecto son 35 segundos. Cuando acaba el tiempo, IM asume que la instancia está colgada y trata de hacer un `kill -9` . Si usa InnoDB con tablas grandes, debe incrementar este valor.

- `nonguarded`

  Esta opcion debe activarse si se quiere desactivar la funcionalidad de monitoreo de IM para una instancia concreta.

Diversas secciones de instancias de ejemplo a continuación.

    [mysqld]
    mysqld-path=/usr/local/mysql/libexec/mysqld
    socket=/tmp/mysql.sock
    port=3307
    server_id=1
    skip-stack-trace
    core-file
    skip-bdb
    log-bin
    log-error
    log=mylog
    log-slow-queries

    [mysqld2]
    nonguarded
    port=3308
    server_id=2
    mysqld-path= /home/cps/mysql/trees/mysql-4.1/sql/mysqld
    socket     = /tmp/mysql.sock4
    pid-file   = /tmp/hostname.pid4
    datadir= /home/cps/mysql_data/data_dir1
    language=/home/cps/mysql/trees/mysql-4.1/sql/share/english
    log-bin
    log=/tmp/fordel.log

### 5.2.5. Los comandos que reconoce el gestor de instancias de MySQL

Una vez que se ha inicializado un fichero de contraseñas para el MySQL Instance Manager y que el IM está ejecutándose, puede conectarse al mismo. Puede usar la herramienta cliente mysql para conectar a través de la API MySQL estándard. A continuación se muestra la lista de comandos que el MySQL Instance Manager acepta actualmente, con ejemplos.

- `START INSTANCE <instance_name>`

  Este comando intenta arrancar una instancia:

      mysql> START INSTANCE mysqld4;
      Query OK, 0 rows affected (0,00 sec)

- `STOP INSTANCE <instance_name>`

  Esto trata de parar una instancia:

      mysql> STOP INSTANCE mysqld4;
      Query OK, 0 rows affected (0,00 sec)

- `SHOW INSTANCES`

  Muestra los nombres de todas las intancias cargadas:

      mysql> show instances;
      +---------------+---------+
      | instance_name | status  |
      +---------------+---------+
      | mysqld3       | offline |
      | mysqld4       | online  |
      | mysqld2       | offline |
      +---------------+---------+
      3 rows in set (0,04 sec)

- `SHOW INSTANCE STATUS <instance_name>`

  Muestra el estado e información de la versión de la instancia seleccionada:

      mysql> SHOW INSTANCE STATUS mysqld3;
      +---------------+--------+---------+
      | instance_name | status | version |
      +---------------+--------+---------+
      | mysqld3       | online | unknown |
      +---------------+--------+---------+
      1 row in set (0.00 sec)

- `SHOW INSTANCE OPTIONS <instance_name>`

  Muestra las opciones usadas por una instancia:

      mysql> SHOW INSTANCE OPTIONS mysqld3;
      +---------------+---------------------------------------------------+
      | option_name   | value                                             |
      +---------------+---------------------------------------------------+
      | instance_name | mysqld3                                           |
      | mysqld-path   | /home/cps/mysql/trees/mysql-4.1/sql/mysqld        |
      | port          | 3309                                              |
      | socket        | /tmp/mysql.sock3                                  |
      | pid-file      | hostname.pid3                                     |
      | datadir       | /home/cps/mysql_data/data_dir1/                   |
      | language      | /home/cps/mysql/trees/mysql-4.1/sql/share/english |
      +---------------+---------------------------------------------------+
      7 rows in set (0.01 sec)

- `SHOW <instance_name> LOG FILES`

  El comando poroporciona un listado de todos los ficheros de log usados por la instancia. El conjunto resultado contiene el path al fichero de log y al fichero de configuración (i.e. `log=/var/mysql.log`), el IM trata de adivinar su ubicación. Si IM no es capaz de localizar el fichero de logs, debe especificarlo explícitamente.

      mysql> SHOW mysqld LOG FILES;
      +-------------+------------------------------------+----------+
      | Logfile     | Path                               | Filesize |
      +-------------+------------------------------------+----------+
      | ERROR LOG   | /home/cps/var/mysql/owlet.err      | 9186     |
      | GENERAL LOG | /home/cps/var/mysql/owlet.log      | 471503   |
      | SLOW LOG    | /home/cps/var/mysql/owlet-slow.log | 4463     |
      +-------------+------------------------------------+----------+
      3 rows in set (0.01 sec)

- `SHOW <instance_name> LOG {ERROR | SLOW | GENERAL} size[,offset_from_end]`

  Este comando recibe una porción del fichero de log especificado. Ya que la mayoría de usuarios están interesados en los últimos mensajes de log, el parámetro `size` define el número de bytes que quiere recibir empezando por el final del log. Puede recibir datos del medio del fichero de log especificando el parámetro opcioneal `offset_from_end` . El siguiente ejemplo recibe 21 bytes de datos, empezando 23 bytes desde el final del fichero de log y acabando 2 bytes al final del fichero de log.:

      mysql> SHOW mysqld LOG GENERAL 21, 2;
      +---------------------+
      | Log                 |
      +---------------------+
      | using password: YES |
      +---------------------+
      1 row in set (0.00 sec)

- `SET instance_name.option_name=option_value`

  Este comando edita la configuración de la instancia especificada para cambiar/añadir opciones a la instancia. El IM asume que el fichero de configuración está localizado en `/etc/my.cnf`. Debe comprobar que el fichero existe y que tiene los permisos apropiados.

      mysql> SET mysqld2.port=3322;
      Query OK, 0 rows affected (0.00 sec)

  Los cambios hecho en el fichero de configuración no tendrán efecto hasta reiniciar el servidor MySQL. Además, estos cambios no se guardan en la cache local de configuración del Instance Manager hasta que se ejecuta un comando `FLUSH INSTANCES`.

- `UNSET instance_name.option_name`

  Este comando elimina una opción de un fichero de configuración de una instancia.

      mysql> UNSET mysqld2.port;
      Query OK, 0 rows affected (0.00 sec)

  Los cambios hecho en el fichero de configuración no tendrán efecto hasta reiniciar el servidor MySQL. Además, estos cambios no se guardan en la cache local de configuración del Instance Manager hasta que se ejecuta un comando `FLUSH INSTANCES`.

- `FLUSH INSTANCES`

  Este comando fuerza a IM a releer el fichero de configuración y a refrescar estructuras internas. Este comando debe ejectuarse tras editar el fichero de configuración. Este comando no reinicia las instancias:

      mysql> FLUSH INSTANCES;
      Query OK, 0 rows affected (0.04 sec)

## 5.3. Configuración del servidor MySQL

Esta sección discute los siguientes tópicos de MySQL Server:

- Opciones de arranque que soporta el servidor

- Cómo configurar el modo SQL del servidor

- Variables de sistema del servidor

- Variables de estado del servidor

### 5.3.1. Opciones del comando mysqld

Cuando arranca el servidor mysqld , puede especificar opciones de programa usando cualquiera de los métodos descritos en Sección 4.3, “Especificar opciones de programa”. Los métodos más comunes son proporcionar opciones en un fichero de opciones o por línea de comandos. Sin embargo, en la mayoría de los casos es deseable asegurar que el servidor usa las mismas opciones cada vez que se ejecuta. La mejor manera de asegurarlo es listarlas en un fichero de opciones. Consulte Sección 4.3.2, “Usar ficheros de opciones”.

mysqld lee opciones de los grupos `[mysqld]` y `[server]`. mysqld_safe lee opciones de los grupos `[mysqld]`, `[server]`, `[mysqld_safe]`, y `[safe_mysqld]`. mysql.server lee opciones de los grupos `[mysqld]` y `[mysql.server]` . Un servidor MySQL incrustrado normalmente lee opciones de los grupos `[server]`, `[embedded]`, y `[`xxxxx`_SERVER]` , donde `xxxxx` es el nombre de la aplicación en la que el servidor está incrustado.

mysqld acepta varias opciones de línea de comando. Para una breve lista, ejecute mysqld --help. Para ver la lista completa, use mysqld --verbose --help.

La siguiente lista muestra algunas de las opciones de servidor más comunes. Opciones adicionales se describen en los siguientes links:

- Opciones que afectan la seguridad: Consulte Sección 5.5.3, “Opciones de arranque para mysqld relacionadas con la seguridad”.

- Opciones relacionadas con SSL: Consulte Sección 5.7.7.5, “Opciones relativas a SSL”.

- Opciones de control del log binario: Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

- Opciones relacionadas con replicación: Consulte Sección 6.8, “Opciones de arranque de replicación”.

- Opciones específicas a motores de almacenamiento particulares: Consulte Sección 14.1.1, “Opciones de arranque de `MyISAM`”, Sección 14.4.3, “Opciones de arranque de `BDB`”, and Sección 15.4, “Opciones de arranque de `InnoDB`”.

También puede cambiar los valores de una variable de sistema del servidor usando el nombre de variable como opción, tal y como se describe más tarde en esta sección.

- `--help, -?`

  Muestra un mensaje de ayuda corto y sale. Use las opciones `--verbose` y `--help` simultáneamente para ver el mensaje entero.

- `--allow-suspicious-udfs`

  Este opción controla si las funciones definidas por el usuario que sólo tienen un símbolo `xxx` para la función principal pueden cargarse. Por defecto, la opción está desactivada y sólo UDFs que tengan al menos un símbolo auxiliar pueden cargarse. Esto previene intentos de cargar funciones de ficheros con objetos compartidos que no contengan UDFs legítimos. En las series de MySQL 5.0 está opción se añadió en la versión 5.0.3. Consulte Sección 27.2.3.6, “Precauciones de seguridad en funciones definidas por usuarios”.

- `--ansi`

  Usa sintaxis estándard SQL (ANSI) en lugar de sintaxis MySQL.Consulte Sección 1.7.3, “Ejecutar MySQL en modo ANSI”. Para un control más preciso sobre el modo SQL del servidor, use la opción `--sql-mode`.

- `--basedir=`path`, -b `path``

  El path al directorio de instalación de MySQL. Todas las rutas se resuelven normalmente relativas a ésta.

- `--bind-address=`IP``

  La dirección IP a ligar.

- `--console`

  Escribe los mensajes de error por `stderr` y `stdout` incluso si `--log-error` está especificado. En Windows, mysqld no cierra la pantalla de consola si se usa esta opción.

- `--character-sets-dir=`path``

  El directorio donde los conjuntos de carácteres están instalados. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--chroot=`path``

  Pone el servidor mysqld en un entorno cerrado durante el arranque usando la llamada de sistema `chroot()`. Esta es una medida de seguridad recomendada. Tenga en cuenta que el uso de esta opción limita de alguna manera `LOAD DATA INFILE` y `SELECT ... INTO OUTFILE`.

- `--character-set-server=`charset``

  Usa `charset` como el conjunto de carácteres por defecto del servidor. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--core-file`

  Escribe un fichero core si mysqld muere. Para algunos sistemas, también puede especificar la opción `--core-file-size` en mysqld_safe. Consulte Sección 5.1.3, “El script de arranque del servidor mysqld_safe”. Tenga en cuenta que en algunos sistemas como Solaris, no obtiene un fichero core si está usando la opción `--user`.

- `--collation-server=`collation``

  Usa `collation` como la colación del servidor por defecto. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--datadir=`path`, -h `path``

  La ruta al directorio de datos.

- `--debug[=`debug_options`], -# [`debug_options`]`

  Si MySQL está configurado con `--with-debug`, puede usar esta opción para obtener un fichero de traza de qué está haciendo mysqld . La cadena de carácteres `debug_options` a menudo es `'d:t:o,`file_name`'`. Consulte Sección D.1.2, “Crear ficheros de traza”.

- (DEPRECATED) `--default-character-set=`charset``

  Usa `charset` como el conjunto de carácteres por defecto. Esta opcíon está obsoleta a favor de `--character-set-server`. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--default-collation=`collation``

  Usa `collation` como colación por defecto. Esta opción está obsoleta a favor de `--collation-server`. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--default-storage-engine=`type``

  Esta opción es un sinónimo para `--default-table-type`.

- `--default-table-type=`type``

  Cambia el valor por defecto de tipo de tablas. Consulte Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.

- `--default-time-zone=`type``

  Cambia la zona horaria del servidor. Esta opción cambia la variable global de sistema `time_zone` . Si no se da esta opción, la zona horaria por defecto es la misma que la del sistema (dada por el valor de la variable de sistema `system_time_zone`.

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

  Coómo debe usarse la opción `DELAYED KEYS`. La escritura retardada de claves provoca que los buffers de claves no se vuelquen entre escrituras para tablas `MyISAM` . `OFF` desactiva escritura de claves retardada. `ON` activa escritura de claves reatardada para aquellas tablas creadas con la opción `DELAYED KEYS` . `ALL` retarda la escritura de claves para todas las tablas `MyISAM` . Consulte Sección 7.5.2, “Afinar parámetros del servidor”. Consulte Sección 14.1.1, “Opciones de arranque de `MyISAM`”.

  Nota: Si asigna a esta variable el valor `ALL`, no debe usar tablas `MyISAM` de otro programa (como de otro servidor MySQL o con myisamchk) cuando una tabla esté en uso. Hacerlo provoca corrupción de los índices.

- `--des-key-file=`file_name``

  Lee las claves por defecto usadas por `DES_ENCRYPT()` y `DES_DECRYPT()` de este fichero.

- `--enable-named-pipe`

  Activa el soporte para named pipes. Esta opción se aplica sólo en Windows NT, 2000, XP y 2004, y sólo pueden usarse con servidores mysqld-nt y mysqld-max-nt que soporten conexiones para named pipes.

- `--exit-info[=`flags`], -T [`flags`]`

  Esta es una máscara de bits de diferentes flags y que puede usar para debugar el servidor mysqld . No use esta opción a no ser que sepa exactamente lo que hace!

- `--external-locking`

  Activa bloqueo del sistema. Tenga en cuenta que si usa esta opción en un sistema en que `lockd` no funcione plenamente (comom en Linux), es fácil para mysqld caer en un deadlock. Esta opción préviamente era `--enable-locking`.

  Nota: Si usa esta opción para permitir actualizaciones en tablas `MyISAM` en cualquier proceso MySQL, debe asegurarse que las siguiente condiciones se satisfacen:

  - No debe usar la caché de consultas para consultas que usen tablas actualizadas por otros procesos.

  - No debe usar `--delay-key-write=ALL` o `DELAY_KEY_WRITE=1` en ninguna tabla compartida.

  La forma más fácil de asegurar esto es usar siempre `--external-locking` junto a `--delay-key-write=OFF --query-cache-size=0`.

  (Esto no se hace por defecto ya que en muchas configuraciones es útil tener una mezcla de las opciones anteriores.)

- `--flush`

  Escribe todos los cambios a disco después de cada comando SQL. Normalmente MySQL escribe todos los cambios en disco después de cada comando SQL y deja al sistema operativo la sincronización con el disco. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”.

- `--init-file=`file``

  Lee comandos SQL de este fichero al arrancar. Cada comando debe ser de una sola línea y no debe incluir comentarios.

- `--innodb-safe-binlog`

  Añade garantía de consistencia entre el contenido de las tablas `InnoDB` y el log binario. Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

- `--language=`lang_name`, -L `lang_name``

  Mensajes de error del cliente en el idioma dado. `lang_name` puede darse como el nombre del idioma o como la ruta al directorio donde los ficheros de idioma están instalados. Consulte Sección 5.9.2, “Escoger el idioma de los mensajes de error”.

- `--large-pages`

  Algunas arquitecturas hardware o de sistemas operativos soportan paginación de memoria mayor a la que hay por defecto (normalmente 4 KB). La implementación de este soporte depende del hardware subyacente y del SO. Aplicaciones que necesiten mucha memoria pueden obtener mejoras de rendimiento usando páginas grandes gracias a reducir los fallos en el Translation Lookaside Buffer (TLB).

  Actualmente, MySQL soporta sólo implementaciones en Linux de soporte para páginas grandes (que se llama HugeTLB en Linux). Tenemos planes de extender este soporte a FreeBSD, Solaris y posiblemente otras plataformas.

  Antes de poder usar páginas grandes en Linux, es necesario configurar el pool de memoria de HugeTLB. Como referencia, consulte el fichero `hugetlbpage.txt` en la fuente del kernel Linux.

  Esta opción está desactivada por defecto. Se añadió en MySQL 5.0.3.

- `--log[=`file`], -l [`file`]`

  Log de conexiones y consultas en este fichero. Consulte Sección 5.10.2, “El registro general de consultas”. Si no especifica un nombre de fichero, MySQL usa ``host_name`.log` como nombre de fichero.

- `--log-bin=[`file`]`

  El fichero de logs binario. Loguea todas las consultas que cambian datos en este fichero. Se usa para copias de seguridad y replicación. Consulte Sección 5.10.3, “El registro binario (Binary Log)”. Se recomienda especificar un nombre de fichero (consulte Sección A.8.4, “Cuestiones abiertas en MySQL” para la razón) en caso contrario MySQL usa ``host_name`-bin` como el nombre base para el fichero de logs.

- `--log-bin-index[=`file`]`

  El fichero índice para log binario. Consulte Sección 5.10.3, “El registro binario (Binary Log)”. Si no especifica un nombre de fichero, y si no especifica uno en `--log-bin`, MySQL usa ``host_name`-bin.index` como el nombre de fichero.

- `--log-bin-trust-routine-creators[={0|1}]`

  Sin argumento o un argumento de 1, esta opción inicializa la variable de sistema `log_bin_trust_routine_creators` a 1. Con un argumento de 0, esta opción actualiza la variable de sistema a 0.. `log_bin_trust_routine_creators` afecta cómo MySQL fuerza las restricciones en la creación de rutinas almacenadas. Consulte Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

  Esta opción se añadió en MySQL 5.0.6.

- `--log-error[=`file`]`

  Mensajes de error y de arranque en este fichero. Consulte Sección 5.10.1, “El registro de errroes (Error Log)”. Si no especifica un nombre de fichero, MySQL usa ``host_name`.err` como nombre de fichero. Si el nombre de fichero no tiene extensión, una extensión `.err` se añade al nombre.

- `--log-isam[=`file`]`

  Loguea todos los cambios `ISAM`/`MyISAM` en este fichero (usado sólo al debugar `ISAM`/`MyISAM`).

- (DEPRECATED) `--log-long-format`

  Loguea información extra a cualquiera de los logs que haya activados (log de actualización, log de consultas lentas y log binario). Por ejemplo, se añade el nombre de usuario y tiempo de la consulta para todas las consultas. Esta opción está obsoleta en MySQL 5.0, y ahora representa el comportamiento por defecto para logueo. (Consulte la descripción para `--log-short-format`.) La opción `--log-queries-not-using-indexes` está disponible para los propósitos de loguear consultas que no usan índices en el log de consultas lentas

- `--log-queries-not-using-indexes`

  Si usa esta opción con `--log-slow-queries`, las consultas que no usan índices también se loguean en el log de consultas lentas. Consulte Sección 5.10.4, “El registro de consultas lentas (Slow Query Log)”.

- `--log-short-format`

  Loguea menos información en cualquiera de los logs activados (log de actualización, log binario y log de consultas lentas). Por ejemplo, el nombre de usuario y el tiempo en que se produce la consulta no se guardan para las consultas.

- `--log-slow-admin-statements`

  Loguea comandos lentos administrativos tales como `OPTIMIZE TABLE`, `ANALYZE TABLE`, y `ALTER TABLE` en el log de consultas lentas.

- `--log-slow-queries[=`file`]`

  Loguea todas las consultas que han tardado más de `long_query_time` segundos en ejecutarse en este fichero.. See Sección 5.10.4, “El registro de consultas lentas (Slow Query Log)”. Consulte las descripciones de las opciones `--log-long-format` y `--log-short-format` para más detalles.

- `--log-warnings, -W`

  Muestra advertencias tales como `Aborted connection...` en el log de errores. Se recomienda activar esta opción, por ejemplo, si usa replicación (obtiene mayor información acerca de lo que está ocurriendo, tal como mensajes acerca de fallos de red y reconexiones). Esta opción está activada por defecto en MySQL 5.0; para desactivarla, use `--skip-log-warnings`. Las conexiones abortadas no se loguean en el log de errores a no ser que el valor sea mayor que 1. Consulte Sección A.2.10, “Errores de comunicación y conexiones abortadas”.

- `--low-priority-updates`

  Operaciones que modifiquen la tabla (`INSERT`, `REPLACE`, `DELETE`, `UPDATE`) tiene una prioridad inferior a las selecciones. También puede hacerse vía `{INSERT | REPLACE | DELETE | UPDATE} LOW_PRIORITY ...` para bajar la prioridad de sólo una consulta, o con `SET LOW_PRIORITY_UPDATES=1` para cambiar la prioridad en un thread. Consulte Sección 7.3.2, “Cuestiones relacionadas con el bloqueo (locking) de tablas”.

- `--memlock`

  Bloquea el proceso mysqld en memoria. Funciona con sistemas tales como Solaris que soportan la llamada de sistema `mlockall()` . Esto puede ser útil si tiene un problema en el que el sistema operativo cause que mysqld realice swap en el disco. Tenga en cuenta que el uso de esta operación requiere que ejecute el servidor como `root`, lo que normalmente no es una buena idea por razones de seguridad.

- `--myisam-recover [=`option`[,`option`...]]]`

  Inicializa el modo de recuperación en el motor de almacenamiento `MyISAM` . El valor para esta opción es cualquier combinación de los valores `DEFAULT`, `BACKUP`,`FORCE`, o `QUICK`. Si especifica múltiples valores, sepárelos con comas. Puede usarse como valor `""` para desactivar esta opción. Si esta opción se usa, mysqld, cuando abre una tabla `MyISAM` , comprueba si la tabla tiene marca de que haya fallado o no se haya cerrado correctamente. (La última opción sólo funciona si está ejecutando con la opción `--skip-external-locking`.) En este caso, mysqld realiza una comprobación sobre la tabla. Si la tabla está corrupta, mysqld intenta repararla.

  La siguientes opciones afectan el funcionamiento de la reparación:

  Opción | Descrición
  `DEFAULT` | Lo mismo que no dar ninguna opción `--myisam-recover`.
  `BACKUP` | Si el fichero de datos ha cambiado durante la recuperación, guarda una copia de seguridad del fichero ``tbl_name`.MYD` como ``tbl_name-datetime`.BAK`.
  `FORCE` | Ejecuta una recuperación incluso si perdemos más de un registro del fichero `.MYD`.
  `QUICK` | No comprueba los registros en la tabla si no hay ningún bloque borrado.

  Antes de reparar una tabla automáticamente, MySQL añade una nota acerca de ello en el log de errores. Si quiere poder recuperarse de la mayoría de problemas sin intervención por parte del usuario, debe usar las opciones `BACKUP,FORCE`. Esto fuerza la reparación de una tabla incluso si algunos registros se borran durante el proceso, pero guarda el antiguo fichero de datos como una copia de seguridad, de forma que posteriormente pueda examinar qué ocurrió.

- `--ndb-connectstring=`connect_string``

  Cuando use el motor de almacenamiento `NDB` , es posible determinar el servidor de administración que distribuye la configuración del cluster mediante la inicialización de la opción de la cadena de conexión. Consulte Sección 16.4.4.2, “El `connectstring` de MySQL Cluster” para la sintaxis.

- `--ndbcluster`

  Si el binario incluye soporte para el motor de almacenamiento `NDB Cluster` , la opción por defecto de desactivar el soporte para MySQL Cluster puede ignorarse usando esta opción. Consulte Capítulo 16, MySQL Cluster.

- `--old-passwords`

  Fuerza al servidor a generar un pequeño hash de contraseñas (pre-4.1) para nuevas contraseñas. Esto es útil para compatibilidad con antiguos programas cliente. Consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1”.

- `--one-thread`

  Sólo usa un thread (para debugar bajo Linux). Esta opción está disponible sólo si el servidor está compilado con la opción de debugar. Consulte Sección D.1, “Depurar un servidor MySQL”.

- `--open-files-limit=`count``

  Para cambiar el número de descriptores de fichero disponibles para mysqld. Si no se inicializa o se asigna otro valor a 0, entonces mysqld usa este valor para reservar descriptores de fichero para usar con `setrlimit()`. Si el valor es 0, entonces mysqld reserva `max_connections*5` o `max_connections + table_cache*2` (lo que sea mayor) número de ficheros. Puede tratar de incrementar este valor si mysqld le muestra el error "Too many open files."

- `--pid-file=`path``

  El path al fichero con el ID de proceso usado por mysqld_safe.

- `--port=`port_num`, -P `port_num``

  El número de puerto que se usa para escuchar conexiones TCP/IP.

- `--safe-mode`

  Omite algunas etapas de optimización.

- (DEPRECATED) `--safe-show-database`

  Consulte Sección 5.6.3, “Privilegios de los que provee MySQL”.

- `--safe-user-create`

  Si está activado, un usuario no puede crear nuevos usuarios con el comando `GRANT` , si el usuario no tiene el privilegio `INSERT` para la tabla `mysql.user` o cualquiera de sus columnas.

- `--secure-auth`

  No permite autenticación para cuentas que usan las contraseñas antiguas (pre-4.1).

- `--shared-memory`

  Activa conexiones mediante memoria compartida con clientes locales. Esta opción sólo está disponible en Windows.

- `--shared-memory-base-name=`name``

  El nombre a usar en conexiones mediante memoria compartida. Esta opción sólo está disponible en Windows.

- `--skip-bdb`

  Deshabilita el motor de almacenamiento `BDB` . Esto ahorra memoria y puede acelerar algunas operaciones. No use esta opción si necesita tablas `BDB`.

- `--skip-concurrent-insert`

  Desactiva la habilidad de seleccionar e insertar al mismo tiempo en tablas `MyISAM` . (Esto sólo debe usarse si cree que ha encontrado un bug en esta funcionalidad.)

- `--skip-external-locking`

  No usa sistema de bloqueo. Para usar myisamchk, debe apagar el servidor. (Consulte Sección 1.4.3, “Estabilidad de MySQL”.) Para evitar este requerimiento, use `CHECK TABLE` y `REPAIR TABLE` desde el MySQL Monitor para comprobar y reparar tablas `MyISAM`.

- `--skip-grant-tables`

  Esta opción hace que el servidor no use el sistema de privilegios en absoluto. Esta opción da a cualquiera que tenga acceso al servidor acceso ilimitado a todas las bases de datos. Puede hacer que un servidor en ejecución empiece a usar las tablas de privilegios de nuevo ejecutando mysqladmin flush-privileges o el comando mysqladmin reload desde una consola de sistema, o utilizando el comando MySQL `FLUSH PRIVILEGES`.

- `--skip-host-cache`

  No use la cache interna de nombres de servidor para una resolución rápida de nombre-a-IP. En lugar de ello, interrogue al servidor DNS cada vez que un cliente se conecte. Consulte Sección 7.5.6, “Cómo usa MySQL las DNS”.

- `--skip-innodb`

  Deshabilita el motor de almacenamiento `InnoDB` . Esto ahorra memoria y espacio en disco y puede acelerar algunas operaciones. No use esta opción si necesita tablas `InnoDB` .

- `--skip-name-resolve`

  No resuelva los nombres de servidor cuando compruebe las conexiones de clientes. Use sólo números IP. Si usa esta opción, todos los valores de la columna `Host` en la tabla de privilegios deben ser números IP o `localhost`. Consulte Sección 7.5.6, “Cómo usa MySQL las DNS”.

- `--skip-ndbcluster`

  Deshabilite el motor de almacenamiento `NDB Cluster` . Este es el comportamiento por defecto para los binarios compilados con el soporte para el motor de almacenamiento de `NDB Cluster` , lo que significa que el sistema reserva memoria y otros recursos para este motor de almacenamiento sólo si `--skip-ndbcluster` está subeditado explícitamente por la opción `--ndbcluster` . Consulte Sección 16.4.3, “Rápido montaje de prueba de MySQL Cluster” para un ejemplo de uso.

- `--skip-networking`

  No escucha conexiones TCP/IP en absoluto. Toda interacción con mysqld debe hacerse via named pipes o memoria compartida (en Windows) o ficheros socket en Unix. Esta opción se recomienda encarecidamente en sistemas donde sólo se permitan clientes locales. Consulte Sección 7.5.6, “Cómo usa MySQL las DNS”.

- `--standalone`

  Sólo para sistemas basados en Windows-NT; le dice al servidor MySQL que no se ejecute como servicio.

- `--symbolic-links, --skip-symbolic-links`

  Activa o desactiva el soporte para links simbólicos. Esta opción tiene diferentes efectos en Windows y Unix:

  - En Windows, habilitar links simbólicos permite establecer un link simbólico a un directorio de base de datos mediante la creación de un fichero `directory.sym` que contiene el path al directorio real. Consulte Sección 7.6.1.3, “Usar enlaces simbólicos para bases de datos en Windows”.

  - En Unix, habilitar links simbólicos significa que puede lincar un fichero de índice o de datos `MyISAM` a otro directorio con las opciones `INDEX DIRECTORY` o `DATA DIRECTORY` del comando `CREATE TABLE` . Si borra o renombra la tabla, el fichero cuyo link simbólico apunta a dicha tabla también se borra o renombra. Consulte Sección 13.1.5, “Sintaxis de `CREATE TABLE`”.

- `--skip-safemalloc`

  Si MySQL está configurado con `--with-debug=full`, todos los programs MySQL chequean para desbordamientos de memoria durante cada reserva y liberación de memoria. Este chequeo es muy lento, de forma que puede desactivarlo cuando no lo necesite mediante la opción `--skip-safemalloc` .

- `--skip-show-database`

  Con esta opción, el comando `SHOW DATABASES` sólo se permite a usuarios que tengan el privilegio `SHOW DATABASES` , y el comando muestra todos los nombres de bases de datos. Sin esta opción, `SHOW DATABASES` se permite a todos los usuarios, pero muestra cada nombre de base de datos sólo si el usuario tiene el privilegio `SHOW DATABASES` o algún privilegio sobre la base de datos.

- `--skip-stack-trace`

  No escribe la traza de la pila. Esta opción es útil cuando está ejecutando mysqld con un debugger. En algunos sistemas, puede usar esta opción para obtener un fichero core. Consulte Sección D.1, “Depurar un servidor MySQL”.

- `--skip-thread-priority`

  Desactiva el uso de prioridades de threads para un mejor tiempo de respuesta.

- `--socket=`path``

  En Unix, esta opción especifica el fichero socket de Unix para usar en conexiones locales. El valor por defecto es `/tmp/mysql.sock`. En Windows, la opción especifica el nombre de pipe a usar en conexiones locales que usen una named pipe. El valor por defecto es `MySQL`.

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

  Inicializa el modo SQL para MySQL. Consulte Sección 5.3.2, “El modo SQL del servidor”.

- `--temp-pool`

  Esta opción provoca que la mayoría de ficheros temporales creados por el servidor usen un pequeño conjunto de nombes, en lugar de un nombre único para cada fichero nuevo. Esto evita el problema del kernel de Linux de crear muchos nuevos ficheros con nombres diferentes. Con el antiguo comportamiento, parece que a Linux le ``falte'' memoria, ya que se está reservando en la entrada del cache del directorio en lugar de la cache de disco.

- `--transaction-isolation=`level``

  Especifica el nivel de aislamiento de las transacciones, que puede ser `READ-UNCOMMITTED`, `READ-COMMITTED`, `REPEATABLE-READ`, o `SERIALIZABLE`. Consulte Sección 13.4.6, “Sintaxis de `SET TRANSACTION`”.

- `--tmpdir=`path`, -t `path``

  El path del directorio a usar para crear ficheros temporales. Puede ser útil si el directorio por defecto `/tmp` reside en una partición que sea demasiado pequeña para alojar tablas temporales. En MySQL 5.0, esta opción acepta diversas rutas que se usan con una política round-robin. Las rutas deben estar separados por comas en Unix ('`:`') y puntos y comas ('`;`') en Windows, NetWare, and OS/2. Si MySQL server está actuando como un esclavo de replicación, no debe hacer que `--tmpdir` apunte a un directorio en un sistema de ficheros basado en memoria o a un directorio que se limpie al reiniciar el servidor. Un esclavo de replicación necesita que sobrevivan algunos de sus ficheros temporales tras un reinicio de la máquina de forma que pueda replicar tablas temporales u operaciones `LOAD DATA INFILE`. Si los ficheros en el directorio temporal se pierden al reiniciar el servidor, la replicación falla.

- `--user={`user_name` | `user_id`}, -u {`user_name` | `user_id`}`

  Ejecuta el servidor mysqld como si el usuario tuviese el nombre `user_name` o el ID de usuario `user_id`. (``Usuario'' en este contexto se refiere a la cuenta de login del sistema, no a un usuario MySQL listado en las tablas de permisos.)

  Esta opción es obligatoria cuando se ejecute mysqld como `root`. El servidor cambia su ID de usuario durante la secuencia de arranque, causando que se ejecute como ese usuario en particular en lugar de `root`. Consulte Sección 5.5.1, “Guía de seguridad general”.

  Para evitar un posible agujero de seguridad donde un usuario añade una opción `--user=root` a un fichero `my.cnf` (por lo tanto, causando que el servidor se ejecute como `root`), mysqld usa sólo la primera opción `--user` especificada y produce una adevertencia si hay múltiples opciones `--user` . Las opciones en `/etc/my.cnf` y `$MYSQL_HOME/my.cnf` se procesan antes que las opciones de línea de comandos, así que se recomiendo que ponga una opción `--user` en `/etc/my.cnf` y especifique un valor distinto a `root`. La opción en `/etc/my.cnf` se encuentra antes que cualquier otra opción `--user` , lo que asegura que el servidor se ejecute como un usuario distinto a `root`, y que se muestre una advertencia como resultado si cualquier otra opción `--user` se encuentra.

- `--version, -V`

  Muestra información de versión y sale.

En MySQL 5.0, puede asignar un valor a una variable de sistema del servidor usando una opción de la forma `--`nombre_variable`=`valor``. Por ejemplo, `--key_buffer_size=32M` inicializa la variable `key_buffer_size` con un valor de 32MB.

Tenga en cuenta que al asignar un valor a una variable, MySQL puede corregir automáticamente la asignación para permanecer dentro de un rango concreto, o ajustar el valor al valor permitido más próximo si sólo se permiten ciertos valores.

También puede inicializar variables usando las sintaxis `--set-variable=`nombre_variable`=`valor`` o `-O `nombre_variable`=`valor``. Sin embargo esta sintaxis está obsoleta

Puede encontrar una descripción concreta de todas las variables en Sección 5.3.3, “Variables de sistema del servidor”. La sección de ajustar los parámetros del servidor incluye información sobre cómo optimizarlos. Consulte Sección 7.5.2, “Afinar parámetros del servidor”.

Puede cambiar los valores de la mayoría de variables de sistema en un servidor en ejecución con el comando `SET`. Consulte Sección 13.5.3, “Sintaxis de `SET`”.

Si desea restringir el máximo valor que se puede asignar a una opción de arranque con `SET`, puede definirlo con la opción de línea de comandos `--maximum-`var_name``.

### 5.3.2. El modo SQL del servidor

MySQL server puede operar en distintos modos SQL, y puede aplicar estos modos de forma distinta a diferentes clientes. Esto permite que cada aplicación ajuste el modo de operación del servidor a sus propios requerimientos.

Los modos definen qué sintaxis SQL debe soportar MySQL y que clase de chequeos de validación de datos debe realizar. Esto hace más fácil de usar MySQL en distintos entornos y usar MySQL junto con otros servidores de bases de datos.

Puede especificar el modo SQL por defecto arrancando mysqld con la opción `--sql-mode="`modes`"`. El valor puede dejarse en blanco (`--sql-mode=""`) si desea resetearlo.

En MySQL 5.0, también puede cambiar el modo SQL tras el tiempo de arranque cambiando la varialbe `sql_mode` usando el comando `SET [SESSION|GLOBAL] sql_mode='`modes`'` . Asignar la variable `GLOBAL` requiere el privilegio `SUPER` y afecta las operaciones de todos los clientes que conecten a partir de entonces. Asignar la variable `SESSION` afecta sólo al cliente actual. Cualquier cliente puede cambiar el valor de `sql_mode` en su sesión en cualquier momento.

`modes` es una lista de los diferentes modos separados por comas ('`,`') . Puede consultar el modo actual mediante el comando `SELECT @@sql_mode` . El valor por defecto es vacío (sin modo seleccionado).

Los valores de los modos `sql_mode` más importantes probablemente son los siguientes:

- `ANSI`

  Cambia el comportamiento y la sintaxis para cumplir mejor el estándard SQL.

- `STRICT_TRANS_TABLES`

  Si un valor no puede insertarse tal y como se da en una tabla transaccional, se aborta el comando. Para tablas no transaccionales, aborta el comando si el valor se encuentra en un comando que implique un sólo registro o el primer registro de un comando de varios registros. Más detalles a continuación en esta sección. (Implementado en MySQL 5.0.2)

- `TRADITIONAL`

  Hace que MySQL se comporte como un sistema de bases de datos SQL ``tradicional''. Una simple descripción de este modo es `` da un error en lugar de una alerta'' cuando se inserta un valor incorrecto en la columna. Nota: `INSERT`/`UPDATE` aborta así que se detecta un error. Puede que no sea lo que quiera si está usando un motor de almacenamiento no transaccional, ya que los cambios en los datos anteriores al error no se deshacen, resultando en una actualización ``parcial'' . (Añadido en MySQL 5.0.2)

Cuando este manual se refiere al ``modo estricto,'' implica un modo donde al menos `STRICT_TRANS_TABLES` o `STRICT_ALL_TABLES` está permitido.

La siguiente lista describe todos los modos soportados:

- `ALLOW_INVALID_DATES`

  No hace un chequeo total de los datos en modo estricto. Chequea sólo que los meses se encuentran en el rango de 1 a 12 y que los días están en el rango de 1 a 31. Esto es muy conveniente para aplicaciones Web donde obtiene un año, mes y día en tres campos distintos y quiere guardar exactamente lo que inserta el usuario (sin validación de datos). Este modo se aplica a columnas `DATE` y `DATETIME` . No se aplica a columnas `TIMESTAMP` , que siempre requieren una fecha válida.

  Este modo se implementó en MySQL 5.0.2. Antes de 5.0.2, este era el modo por defecto de MySQL para tratar datos. Desde 5.0.2, el permitir el modo estricto provoca que el servidor requiera que el mes y día se evalúen como valores legales y no simplemente en los rangos de 1 a 12 y de 1 a 31, respectivamente. Por ejemplo, `'2004-04-31'` es legal con el modo estricto desactivado, pero ilegal con el modo estricto activado. Para permitir tales fechas en modo estricto, habilite `ALLOW_INVALID_DATES` también.

- `ANSI_QUOTES`

  Trata '`"`' como un identificador delimitador de carácter (como '```' ) y no como un delimitador de cadenas de carácteres. Puede usar '```' para delimitar identificadores en modo ANSI. Con `ANSI_QUOTES` activado, puede usar doble delimitadores para delimitar una cadena de carácteres literales, ya que se interpreta como un identificador.

- `ERROR_FOR_DIVISION_BY_ZERO`

  Produce un error en modo estricto (de otra forma una advertencia) cuando encuentra una división por cero (o `MOD(X,0)`) durante un `INSERT` o `UPDATE`, o en cualquier expresión (por ejemplo, en una lista de select o cláusula `WHERE` ) que implica datos de tablas y una divisón por cero. Si este modo no se da, MySQL retorna `NULL` para una división por cero. Si se usa `INSERT IGNORE` o `UPDATE IGNORE`, MySQL genera una advertencia de división por cero, pero el resultado de la operación es `NULL`. (Implmentado en MySQL 5.0.2)

- `HIGH_NOT_PRECEDENCE`

  Desde MySQL 5.0.2 , la precedencia del operador `NOT` se trata tal que expresiones como `NOT a BETWEEN b AND c` se parsean como `NOT (a BETWEEN b AND c)`. Antes de MySQL 5.0.2, la expresión se parseaba como `(NOT a) BETWEEN b AND c`. El antiguo comportamiento de mayor-precedencia puede obtenerse permitiendo el modo SQL `HIGH_NOT_PRECEDENCE` . (Añadido en MySQL 5.0.2)

      mysql> SET sql_mode = '';
      mysql> SELECT NOT 1 BETWEEN -5 AND 5;
              -> 0
      mysql> SET sql_mode = 'broken_not';
      mysql> SELECT NOT 1 BETWEEN -5 AND 5;
              -> 1

- `IGNORE_SPACE`

  Permite nombres entre el nombre de función y el carácter '`(`' . Esto fuerza que todos los nombres de función se traten como palabras reservadas. Como resultado, si quiere acceder a cualquier base de datos, tabla, o nombre de columna que sea una palabra reservada, debe delimitarla. Por ejemplo, y como hay una función `USER()` , el nombre de la tabla `user` en la base de datos `mysql` y la columna `User` en esa table se reseva, así que debe delimitarla:

      SELECT "User" FROM mysql."user";

- `NO_AUTO_CREATE_USER`

  Previene que `GRANT` cree automáticamente nuevos usuarios si de otra forma se haría, a no ser que se especifique un usuario. (Añadido en MySQL 5.0.2)

- `NO_AUTO_VALUE_ON_ZERO`

  `NO_AUTO_VALUE_ON_ZERO` afecta el tratamiento de las columnas `AUTO_INCREMENT` . Normalmente, genera el siguiente número de secuencia para la columna insertando `NULL` o `0` en ella. `NO_AUTO_VALUE_ON_ZERO` suprime este comportamiento para `0` de forma que sólo `NULL` genera el siguiente número de secuencia.

  Este modo puede ser útil si `0` se ha almacenado en una tabla con columnas `AUTO_INCREMENT` . (Esta no es una práctica recomendada, de todos modos.) Por ejemplo, si vuelca la tabla con mysqldump y posteriormente la recarga, normalmente MySQL genera un nuevo número de secuencia cuando encuentra los valores `0` , resultando en una tabla con distinto contenido que la que fue volcada. Activar `NO_AUTO_VALUE_ON_ZERO` antes de recargar el fichero con el volcado resuelve el problema. En MySQL 5.0, mysqldump incluye automáticamente en su salida un comando permitiendo `NO_AUTO_VALUE_ON_ZERO`.

- `NO_BACKSLASH_ESCAPES`

  Desactiva el uso del carácter de barra invertida ('`\`') como carácter de escape en cadenas de carácteres. Con este modo activado, la barra invertida se convierte en un carácter ordinario como cualquier otro. (Implementado en MySQL 5.0.1)

- `NO_DIR_IN_CREATE`

  Cuando crea una tabla, ignora todas las directivas `INDEX DIRECTORY` y `DATA DIRECTORY`. Este opción es útil en servidores de replicación esclavos.

- `NO_ENGINE_SUBSTITUTION`

  Evita la substitución automática de motor de almacenamiento cuando el motor deseado no está disponible o compilado.

- `NO_FIELD_OPTIONS`

  No muestra opciones específicas para columnas de MySQL en la salida de `SHOW CREATE TABLE`. Este modo se usa con mysqldump en modo de portabilidad.

- `NO_KEY_OPTIONS`

  No muestra opciones específicas para índices de MySQL en la salida de `SHOW CREATE TABLE`. Este modo se usa con mysqldump en modo de portabilidad.

- `NO_TABLE_OPTIONS`

  No muestra opciones específicas para tablas (tales como `ENGINE`) en la salida de `SHOW CREATE TABLE`. Este modo se usa con mysqldump en modo de portabilidad.

- `NO_UNSIGNED_SUBTRACTION`

  En operaciones de resta, no marca el resultado como `UNSIGNED` si uno de los operandos no tiene signo. Note que esto hace que `UNSIGNED BIGINT` no sea 100% usable en todos los contextos. Consulte Sección 12.8, “Funciones y operadores de cast”.

- `NO_ZERO_DATE`

  En modo estricto, no permite `'0000-00-00'` como fecha válida. Puede insertar fechas 0 con la opción `IGNORE` . Cuando no está en modo estricto, la fecha se acepta pero se genera una advertencia. (Añadido en MySQL 5.0.2)

- `NO_ZERO_IN_DATE`

  En modo estricto, no acepta fechas la parte del mes o día es 0. Se usa con la opción `IGNORE` , inserta una fecha `'0000-00-00'` para cualquiera de estas fechas. Cuando no está en modo estricto, la fecha se acepta pero se genera una advertencia. (Añadido en MySQL 5.0.2)

- `ONLY_FULL_GROUP_BY`

  No permite consultas que en la parte del `GROUP BY` se refieran a una columna que no se seleccione.

- `PIPES_AS_CONCAT`

  Trata `||` como un concatenador de columnas de carácteres (lo mismo que `CONCAT()`) en lugar de como sinónimo de `OR`.

- `REAL_AS_FLOAT`

  Trata `REAL` como un sinónimo de `FLOAT` en lugar de sinónimo de `DOUBLE`.

- `STRICT_ALL_TABLES`

  Activa el modo estricto para todos los motores de almacenamiento. Rechaza los datos inválidos. Detalles adicionales a continuación. (Añadido en MySQL 5.0.2)

- `STRICT_TRANS_TABLES`

  Habilita el modo estricto para motores de almacenamiento transaccionales, y cuando sea posible también para los no transaccionales. Detalles adicionales a continuación. (Implementado en MySQL 5.0.2)

El modo estricto controla cómo MySQL trata los valores de entrada invalidos o no presentes. Un valor puede ser inválido por distintas razones. Por ejemplo, puede tener un tipo de datos incorrecto para la columna, o puede estar fuera de rango. Un valor no está presente cuando el registro a insertarse no tiene un valor para una columna que no tiene la cláusua `DEFAULT` explícita en su definición.

Para tablas transaccionales, se genera un error para valores inválidos o no presentes en un comando con los modos `STRICT_ALL_TABLES` o `STRICT_TRANS_TABLES` habilitados. El comando se aborta y deshace.

Para tablas no transaccionales, el comportamiento es el mismo para cualquier modo, si un valor incorrecto se encuentra en el primer registro a insertar o actualizar. El comando se aborta y la tabla continúa igual. Si el comando inserta o modifica varios registros y el valor incorrecto aparece en el segundo o posterior registro, el resultado depende de qué modo estricto esté habilitado:

- Para `STRICT_ALL_TABLES`, MySQL devuelve un error e ignora el resto de los registros. Sin embargo, en este caso, los primeros registros se insertan o actualizan. Esto significa que puede producirse una actualización parcial, que puede no ser lo que desea. Para evitarlo, es mejor usar comandos de un único registro ya que pueden abortarse sin cambiar la tabla.

- Para `STRICT_TRANS_TABLES`, MySQL convierte los valores inválidos en el valor válido más próximo para la columna e inserta el nuevo valor. Si un valor no está presente, MySQL inserta el valor por defecto implícito para el tipo de la columna. En ese caso, MySQL genera una advertencia en lugar de un error y continúa procesando el comando. Los valores implícitos se describen en Sección 13.1.5, “Sintaxis de `CREATE TABLE`”.

El modo estricto no permite fechas inválides como `'2004-04-31'`. Esto sigue permitiendo fechas con partes con ceros, como `2004-04-00'` o fechas ``cero''. Para no permitirlas tampoco, active los modos SQL `NO_ZERO_IN_DATE` y `NO_ZERO_DATE` además del modo estricto.

Si no usa el modo estricto (esto es, ni `STRICT_TRANS_TABLES` ni `STRICT_ALL_TABLES` están activados), MySQL inserta valores ajustados para valores inválidos o no presentes y produce advertencias. En modo estricto, puede producir este comportamiento usando `INSERT IGNORE` o `UPDATE IGNORE`. Consulte Sección 13.5.4.22, “Sintaxis de `SHOW WARNINGS`”.

Los siguientes modos especiales se proporcionan como abreviaciones de combinaciones de modos de la lista precedente. Todos están disponibles en MySQL 5.0 empezando en la versión 5.0.0, excepto para `TRADITIONAL`, que se implementó en MySQL 5.0.2.

La descripción incluye todos los modos que están disponibles en la reción más reciente de MySQL. Para versiones anteriores, un modo de combinación no incluye todos los modos individuales que sólo están disponibles en las versiones más recientes.

- `ANSI`

  Equivalente a `REAL_AS_FLOAT`, `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`. Antes de MySQL 5.0.3, `ANSI` también incluye `ONLY_FULL_GROUP_BY`. Consulte Sección 1.7.3, “Ejecutar MySQL en modo ANSI”.

- `DB2`

  Equivalente a `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MAXDB`

  Equivalente a `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`, `NO_AUTO_CREATE_USER`.

- `MSSQL`

  Equivalente a `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MYSQL323`

  Equivalente a `NO_FIELD_OPTIONS`, `HIGH_NOT_PRECEDENCE`.

- `MYSQL40`

  Equivalente a `NO_FIELD_OPTIONS`, `HIGH_NOT_PRECEDENCE`.

- `ORACLE`

  Equivalente a `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`, `NO_AUTO_CREATE_USER`.

- `POSTGRESQL`

  Equivalente a `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `TRADITIONAL`

  Equivalente a `STRICT_TRANS_TABLES`, `STRICT_ALL_TABLES`, `NO_ZERO_IN_DATE`, `NO_ZERO_DATE`, `ERROR_FOR_DIVISION_BY_ZERO`, `NO_AUTO_CREATE_USER`.

### 5.3.3. Variables de sistema del servidor

El servidor mantiene varias variables de sistema que indican cómo está configurado. Todas ellas tienen valores por defecto. Pueden cambiarse al arrancar el servidor usando opciones en la línea de comandos o en ficheros de opciones. La mayoría de ellos pueden cambiarse en tiempo de ejecución usando el comando `SET`.

El servidor mysqld mantiene dos clases de variables. Las variables globales afectan las operaciones globales del servidor. Las variables de sesión afectan las operaciones para conexiones individuales de clientes.

Cuando el servidor arranca, inicializa todas las variables globales a sus valores por defecto. Estos valores pueden cambiarse con las opciones especificadas en los ficheros de opciones o en la línea de comandos. Una vez que el servidor arranca, aquellas variables globales que sean dinámicas pueden cambiarse conectando al servidor y ejectuando el comando `SET GLOBAL `var_name``. Para cambiar una variable global, debe tener el privilegio `SUPER`.

El servidor mantiene un conjunto de variables de sesión para cada cliente que se conecta. Las variables de sesión del cliente se inicializan en tiempo de conexión usando los valores actuales de las correspondientes variables globales. Para aquellas variables de sesión que son dinámicas, el cliente puede cambiarlas mediante un comando `SET SESSION `var_name`` . Cambiar una variable de sesión no necesita privilegios especiales, pero un cliente puede cambiar sólo sus variables de sesión, no las de ningún otro cliente.

Un cambio de una variable global es visible para cualquier cliente que acceda a esa variable global. Sin embargo, esto afecta a las correspondientes variables de sesión que se inicializan por la variable global sólo para clientes que se conecten después del cambio. Esto no afecta las variables de sesión para cualquier cliente que ya esté conectado (tampoco para los clientes que ejecuten el comando `SET GLOBAL`).

Cuando se cambia una variable usando las opciones de arranque, los valores de la variable pueden darse con un sufijo `K`, `M`, o `G` para indicar kilobytes, megabytes, o gigabytes, respectivamente. Por ejemplo, el siguiente comando arranca el servidor con un tamaño de key buffer de 16 megabytes:

    mysqld --key_buffer_size=16M

No importa que los sufijos se escriban en mayúscula o minúscula; `16M` y `16m` son equivalentes.

En tiempo de ejecución, use el comando `SET` para cambiar las variables de sistema. En este contexto, los sufijos no pueden usarse, pero el valor puede tomar la forma de una expresión:

    mysql> SET sort_buffer_size = 10 * 1024 * 1024;

Para espeficicar explícitamente si desea cambiar la variable global o de sesión use la opción `GLOBAL` o `SESSION`:

    mysql> SET GLOBAL sort_buffer_size = 10 * 1024 * 1024;
    mysql> SET SESSION sort_buffer_size = 10 * 1024 * 1024;

Sin dicha opción, el comando actualiza la variable de sesión.

Las variables que pueden cambiarse en tiempo de ejecución se listan en Sección 5.3.3.1, “Variables de sistema dinámicas”.

Si desea restringir el valor máximo que puede tomar una variable de sistema con el comando `SET` , puede especificarlo con `--maximum-`var_name`` en el arranque del servidor. Por ejemplo, para evitar que el valor de `query_cache_size` se incremente por encima de 32MB en tiempo de ejecución, use la opción `--maximum-query_cache_size=32M`.

Puede consultar las variables de sistema y sus valores usando el comando `SHOW VARIABLES` . Consulte Sección 9.4, “Variables de sistema” para más información.

    mysql> SHOW VARIABLES;
    +---------------------------------+---------------------------------------------------------+
    | Variable_name                   | Value                                                   |
    +---------------------------------+---------------------------------------------------------+
    | auto_increment_increment        | 1                                                       |
    | auto_increment_offset           | 1                                                       |
    | automatic_sp_privileges         | ON                                                      |
    | back_log                        | 50                                                      |
    | basedir                         | /                                                       |
    | bdb_cache_size                  | 8388600                                                 |
    | bdb_home                        | /var/lib/mysql/                                         |
    | bdb_log_buffer_size             | 32768                                                   |
    | bdb_logdir                      |                                                         |
    | bdb_max_lock                    | 10000                                                   |
    | bdb_shared_data                 | OFF                                                     |
    | bdb_tmpdir                      | /tmp/                                                   |
    | binlog_cache_size               | 32768                                                   |
    | bulk_insert_buffer_size         | 8388608                                                 |
    | character_set_client            | latin1                                                  |
    | character_set_connection        | latin1                                                  |
    | character_set_database          | latin1                                                  |
    | character_set_results           | latin1                                                  |
    | character_set_server            | latin1                                                  |
    | character_set_system            | utf8                                                    |
    | character_sets_dir              | /usr/share/mysql/charsets/                              |
    | collation_connection            | latin1_swedish_ci                                       |
    | collation_database              | latin1_swedish_ci                                       |
    | collation_server                | latin1_swedish_ci                                       |
    | completion_type                 | 0                                                       |
    | concurrent_insert               | 1                                                       |
    | connect_timeout                 | 5                                                       |
    | datadir                         | /var/lib/mysql/                                         |
    | date_format                     | %Y-%m-%d                                                |
    | datetime_format                 | %Y-%m-%d %H:%i:%s                                       |
    | div_precision_increment         | 4                                                       |
    | default_week_format             | 0                                                       |
    | delay_key_write                 | ON                                                      |
    | delayed_insert_limit            | 100                                                     |
    | delayed_insert_timeout          | 300                                                     |
    | delayed_queue_size              | 1000                                                    |
    | expire_logs_days                | 0                                                       |
    | flush                           | OFF                                                     |
    | flush_time                      | 0                                                       |
    | ft_boolean_syntax               | + -><()~*:""&|                                          |
    | ft_max_word_len                 | 84                                                      |
    | ft_min_word_len                 | 4                                                       |
    | ft_query_expansion_limit        | 20                                                      |
    | ft_stopword_file                | (built-in)                                              |
    | group_concat_max_len            | 1024                                                    |
    | have_archive                    | NO                                                      |
    | have_bdb                        | YES                                                     |
    | have_blackhole_engine           | YES                                                     |
    | have_compress                   | YES                                                     |
    | have_crypt                      | YES                                                     |
    | have_csv                        | YES                                                     |
    | have_example_engine             | YES                                                     |
    | have_federated_engine           | YES                                                     |
    | have_geometry                   | YES                                                     |
    | have_innodb                     | YES                                                     |
    | have_isam                       | NO                                                      |
    | have_ndbcluster                 | DISABLED                                                |
    | have_openssl                    | NO                                                      |
    | have_query_cache                | YES                                                     |
    | have_raid                       | NO                                                      |
    | have_rtree_keys                 | YES                                                     |
    | have_symlink                    | YES                                                     |
    | init_connect                    |                                                         |
    | init_file                       |                                                         |
    | init_slave                      |                                                         |
    | innodb_additional_mem_pool_size | 1048576                                                 |
    | innodb_autoextend_increment     | 8                                                       |
    | innodb_buffer_pool_awe_mem_mb   | 0                                                       |
    | innodb_buffer_pool_size         | 8388608                                                 |
    | innodb_checksums                | ON                                                      |
    | innodb_concurrency_tickets      | 500                                                     |
    | innodb_data_file_path           | ibdata1:10M:autoextend                                  |
    | innodb_data_home_dir            |                                                         |
    | innodb_doublewrite              | ON                                                      |
    | innodb_fast_shutdown            | 1                                                       |
    | innodb_file_io_threads          | 4                                                       |
    | innodb_file_per_table           | OFF                                                     |
    | innodb_flush_log_at_trx_commit  | 1                                                       |
    | innodb_flush_method             |                                                         |
    | innodb_force_recovery           | 0                                                       |
    | innodb_lock_wait_timeout        | 50                                                      |
    | innodb_locks_unsafe_for_binlog  | OFF                                                     |
    | innodb_log_arch_dir             |                                                         |
    | innodb_log_archive              | OFF                                                     |
    | innodb_log_buffer_size          | 1048576                                                 |
    | innodb_log_file_size            | 5242880                                                 |
    | innodb_log_files_in_group       | 2                                                       |
    | innodb_log_group_home_dir       | ./                                                      |
    | innodb_max_dirty_pages_pct      | 90                                                      |
    | innodb_max_purge_lag            | 0                                                       |
    | innodb_mirrored_log_groups      | 1                                                       |
    | innodb_open_files               | 300                                                     |
    | innodb_sync_spin_loops          | 20                                                      |
    | innodb_table_locks              | ON                                                      |
    | innodb_support_xa               | ON                                                      |
    | innodb_thread_concurrency       | 8                                                       |
    | innodb_thread_sleep_delay       | 10000                                                   |
    | interactive_timeout             | 28800                                                   |
    | join_buffer_size                | 131072                                                  |
    | key_buffer_size                 | 8388600                                                 |
    | key_cache_age_threshold         | 300                                                     |
    | key_cache_block_size            | 1024                                                    |
    | key_cache_division_limit        | 100                                                     |
    | language                        | /usr/share/mysql/english/                               |
    | large_files_support             | ON                                                      |
    | large_pages                     | OFF                                                     |
    | large_page_size                 | 0                                                       |
    | license                         | GPL                                                     |
    | local_infile                    | ON                                                      |
    | locked_in_memory                | OFF                                                     |
    | log                             | OFF                                                     |
    | log_bin                         | OFF                                                     |
    | log_bin_trust_routine_creators  | OFF                                                     |
    | log_error                       |                                                         |
    | log_slave_updates               | OFF                                                     |
    | log_slow_queries                | OFF                                                     |
    | log_warnings                    | 1                                                       |
    | long_query_time                 | 10                                                      |
    | low_priority_updates            | OFF                                                     |
    | lower_case_file_system          | OFF                                                     |
    | lower_case_table_names          | 0                                                       |
    | max_allowed_packet              | 1048576                                                 |
    | max_binlog_cache_size           | 4294967295                                              |
    | max_binlog_size                 | 1073741824                                              |
    | max_connect_errors              | 10                                                      |
    | max_connections                 | 100                                                     |
    | max_delayed_threads             | 20                                                      |
    | max_error_count                 | 64                                                      |
    | max_heap_table_size             | 16777216                                                |
    | max_insert_delayed_threads      | 20                                                      |
    | max_join_size                   | 4294967295                                              |
    | max_length_for_sort_data        | 1024                                                    |
    | max_relay_log_size              | 0                                                       |
    | max_seeks_for_key               | 4294967295                                              |
    | max_sort_length                 | 1024                                                    |
    | max_tmp_tables                  | 32                                                      |
    | max_user_connections            | 0                                                       |
    | max_write_lock_count            | 4294967295                                              |
    | multi_range_count               | 256                                                     |
    | myisam_data_pointer_size        | 6                                                       |
    | myisam_max_sort_file_size       | 2147483647                                              |
    | myisam_recover_options          | OFF                                                     |
    | myisam_repair_threads           | 1                                                       |
    | myisam_sort_buffer_size         | 8388608                                                 |
    | engine_condition_pushdown       | OFF                                                     |
    | ndb_autoincrement_prefetch_sz   | 32                                                      |
    | ndb_force_send                  | ON                                                      |
    | ndb_use_exact_count             | ON                                                      |
    | ndb_use_transactions            | ON                                                      |
    | ndb_cache_check_time            | 0                                                       |
    | net_buffer_length               | 16384                                                   |
    | net_read_timeout                | 30                                                      |
    | net_retry_count                 | 10                                                      |
    | net_write_timeout               | 60                                                      |
    | new                             | OFF                                                     |
    | old_passwords                   | OFF                                                     |
    | open_files_limit                | 1024                                                    |
    | optimizer_prune_level           | 1                                                       |
    | optimizer_search_depth          | 62                                                      |
    | pid_file                        | /var/lib/mysql/gigan.pid                                |
    | port                            | 3306                                                    |
    | preload_buffer_size             | 32768                                                   |
    | protocol_version                | 10                                                      |
    | query_alloc_block_size          | 8192                                                    |
    | query_cache_limit               | 1048576                                                 |
    | query_cache_min_res_unit        | 4096                                                    |
    | query_cache_size                | 0                                                       |
    | query_cache_type                | ON                                                      |
    | query_cache_wlock_invalidate    | OFF                                                     |
    | query_prealloc_size             | 8192                                                    |
    | range_alloc_block_size          | 2048                                                    |
    | read_buffer_size                | 131072                                                  |
    | read_only                       | OFF                                                     |
    | read_rnd_buffer_size            | 262144                                                  |
    | relay_log_purge                 | ON                                                      |
    | relay_log_space_limit           | 0                                                       |
    | rpl_recovery_rank               | 0                                                       |
    | secure_auth                     | OFF                                                     |
    | server_id                       | 0                                                       |
    | skip_external_locking           | ON                                                      |
    | skip_networking                 | OFF                                                     |
    | skip_show_database              | OFF                                                     |
    | slave_compressed_protocol       | OFF                                                     |
    | slave_load_tmpdir               | /tmp/                                                   |
    | slave_net_timeout               | 3600                                                    |
    | slave_skip_errors               | OFF                                                     |
    | slave_transaction_retries       | 10                                                      |
    | slow_launch_time                | 2                                                       |
    | socket                          | /var/lib/mysql/mysql.sock                               |
    | sort_buffer_size                | 2097144                                                 |
    | sql_mode                        |                                                         |
    | storage_engine                  | MyISAM                                                  |
    | sql_notes                       | OFF                                                     |
    | sql_warnings                    | OFF                                                     |
    | sync_binlog                     | 0                                                       |
    | sync_replication                | 0                                                       |
    | sync_replication_slave_id       | 0                                                       |
    | sync_replication_timeout        | 10                                                      |
    | sync_frm                        | ON                                                      |
    | system_time_zone                | EST                                                     |
    | table_cache                     | 64                                                      |
    | table_type                      | MyISAM                                                  |
    | thread_cache_size               | 0                                                       |
    | thread_stack                    | 196608                                                  |
    | time_format                     | %H:%i:%s                                                |
    | time_zone                       | SYSTEM                                                  |
    | timed_mutexes                   | OFF                                                     |
    | tmp_table_size                  | 33554432                                                |
    | tmpdir                          |                                                         |
    | transaction_alloc_block_size    | 8192                                                    |
    | transaction_prealloc_size       | 4096                                                    |
    | tx_isolation                    | REPEATABLE-READ                                         |
    | updatable_views_with_limit      | YES                                                     |
    | version                         | 5.0.7-beta-Max                                          |
    | version_bdb                     | Sleepycat Software: Berkeley DB 4.1.24: (June 11, 2005) |
    | version_comment                 | MySQL Community Edition - Max (GPL)                     |
    | version_compile_machine         | i686                                                    |
    | version_compile_os              | pc-linux-gnu                                            |
    | wait_timeout                    | 28800                                                   |
    +---------------------------------+---------------------------------------------------------+
    219 rows in set (0.00 sec)

La mayoría de variables de sistema se describen aquí. Las variables sin versión indican que están presentes en todas las versiones de MySQL 5.0. Para información histórica acerca de sus implementaciones, consulte Manual de referencia de MySQL 4.1. Las variables de sistema `InnoDB` están listadas en Sección 15.4, “Opciones de arranque de `InnoDB`”.

Los valores para tamaños de buffer, longitudes y tamaño de pila se dan en bytes a no ser que se especifique otra unidad.

Información sobre el ajuste de estas variables se encuentra en Sección 7.5.2, “Afinar parámetros del servidor”.

- `auto_increment_increment`

  `auto_increment_increment` y `auto_increment_offset` están pensados para usarse con replicación maestro-a-maestro, y puede usarse para controlar la operación de columnas `AUTO_INCREMENT` . Ambas variables pueden cambiarse global o localmente, y cada una de ellas puede tomar un valor entre 1 y 65.535 incluídos. Cambiar el valor de estas variables a 0 causa que su valor sea 1. Intentar cambiar el valor de cualquiera de estas variables a un entero mayor que 65,535 o menor a 0 causa que su valor sea 65,535. Intentar cambiar el valor de `auto_increment_increment` o de `auto_increment_offset` con un valor no entero da un error, y el valor de la variable no se cambie en ese caso.

  Estas dos variables afectan al comportamiento de la columnas `AUTO_INCREMENT` así:

  - `auto_increment_increment` controla el intervalo en que se incrementa el valor de columna. Por ejemplo:

          mysql> SHOW VARIABLES LIKE 'auto_inc%';
          +--------------------------+-------+
          | Variable_name            | Value |
          +--------------------------+-------+
          | auto_increment_increment | 1     |
          | auto_increment_offset    | 1     |
          +--------------------------+-------+
          2 rows in set (0.00 sec)

          mysql> CREATE TABLE autoinc1 (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
          Query OK, 0 rows affected (0.04 sec)

          mysql> SET @auto_increment_increment=10;
          Query OK, 0 rows affected (0.00 sec)

          mysql> SHOW VARIABLES LIKE 'auto_inc%';
          +--------------------------+-------+
          | Variable_name            | Value |
          +--------------------------+-------+
          | auto_increment_increment | 10    |
          | auto_increment_offset    | 1     |
          +--------------------------+-------+
          2 rows in set (0.01 sec)

          mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
          Query OK, 4 rows affected (0.00 sec)
          Records: 4  Duplicates: 0  Warnings: 0

          mysql> SELECT col FROM autoinc1;
          +-----+
          | col |
          +-----+
          |   1 |
          |  11 |
          |  21 |
          |  31 |
          +-----+
          4 rows in set (0.00 sec)

    (Note cómo se usa `SHOW VARIABLES` para obtener el valor actual de estas variables.)

  - `auto_increment_offset` determina el punto de inicio para el valor de las columnas `AUTO_INCREMENT`. Considere lo siguiente, asumiendo que estos comandos se ejecutan durante la misma sesión que el ejemplo anterior:

          mysql> SET @auto_increment_offset=5;
          Query OK, 0 rows affected (0.00 sec)

          mysql> SHOW VARIABLES LIKE 'auto_inc%';
          +--------------------------+-------+
          | Variable_name            | Value |
          +--------------------------+-------+
          | auto_increment_increment | 10    |
          | auto_increment_offset    | 5     |
          +--------------------------+-------+
          2 rows in set (0.00 sec)

          mysql> CREATE TABLE autoinc2 (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
          Query OK, 0 rows affected (0.06 sec)

          mysql> INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL);
          Query OK, 4 rows affected (0.00 sec)
          Records: 4  Duplicates: 0  Warnings: 0

          mysql> SELECT col FROM autoinc2;
          +-----+
          | col |
          +-----+
          |   5 |
          |  15 |
          |  25 |
          |  35 |
          +-----+
          4 rows in set (0.02 sec)

    Si el valor de `auto_increment_offset` es mayor que el de `auto_increment_increment`, entonces el valor `auto_increment_offset` se ignora.

  Si una o ambas variables se cambian y los nuevos registros insertados en una tabla que contengan una columna `AUTO_INCREMENT` , el resultado puede ser no intuitivo, como los valores de las series de `AUTO_INCREMENT` se calculan sin tener en cuenta los valores ya existentes en la columna, y el siguiente valor insertado es el menor valor de la serie que es mayor al máximo valor existente en la columna `AUTO_INCREMENT` . En otras palabras, la serie se calcula así:

  `auto_increment_offset + `N` * auto_increment_increment`

  donde `N` es un entero positivo en la serie [1, 2, 3, ...]. Por ejemplo:

      mysql> SHOW VARIABLES LIKE 'auto_inc%';
      +--------------------------+-------+
      | Variable_name            | Value |
      +--------------------------+-------+
      | auto_increment_increment | 10    |
      | auto_increment_offset    | 5     |
      +--------------------------+-------+
      2 rows in set (0.00 sec)

      mysql> SELECT col FROM autoinc1;
      +-----+
      | col |
      +-----+
      |   1 |
      |  11 |
      |  21 |
      |  31 |
      +-----+
      4 rows in set (0.00 sec)

      mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0

      mysql> SELECT col FROM autoinc1;
      +-----+
      | col |
      +-----+
      |   1 |
      |  11 |
      |  21 |
      |  31 |
      |  35 |
      |  45 |
      |  55 |
      |  65 |
      +-----+
      8 rows in set (0.00 sec)

  Los valores mostrados por `auto_increment_increment` y `auto_increment_offset` generan las series 5 + `N` * 10, esto es, [5, 15, 25, 35, 45, ...]. El mayor valor presente en la columna `col` antes del `INSERT` es 31, y el siguiente valor disponible en la serie `AUTO_INCREMENT` es 35, así que los valores insertados para `col` empiezan en ese punto y los resultados se muestran para la consulta `SELECT`.

  Es importante recordar que no es posible confinar los efectos de estas dos variables en una sola tabla, y por lo tanto no toman el lugar de la secuencia ofrecido por otros sistemas gestores de bases de datos; estas variables controlan el comportamiento de todas las columnas `AUTO_INCREMENT` en todas las tablas del servidor MySQL. Si una de estas variables se cambia globalmente, entonces sus efectos persisten hasta que el valor global se cambia o subyace al cambiarlo localmente, o hasta que se reinicia mysqld ; si se cambia localmente, entonces el nuevo valor afecta a las columnas `AUTO_INCREMENT` para todas las tablas en que se inserten nuevos registros por el usuario actual durante la sesión, hasta que los valores se cambien durante esa sesión.

  La variable `auto_increment_increment` se añadió en MySQL 5.0.2. Su valor por defecto es 1. Consulte Capítulo 6, Replicación en MySQL.

- `auto_increment_offset`

  Esta variable se añadió en MySQL 5.0.2. Su valor por defecto es 1. Para más detalles, consulte la descripción de `auto_increment_increment`.

- `back_log`

  El numero de peticiones de conexión que puede tener MySQL. Esto se usa cuando el thread principal de MySQL recibe muchas peticiones de conexión en un pequeño lapso de tiempo. Necesita algo de tiempo (aunque muy poco) el thread principal para comprobar la conexión y empezar un nuevo thread. El valor de `back_log` indica cuántas peticiones pueden almacenarse duarnte este corto espacio de tiempo antes que MySQL temporalmente pare de responder a nuevas peticiones. Necesita incrementarlo sólo si espera un gran número de conexiones en un pequeño lapso de tiempo.

  En otras palabras, este valor es el tamaño de la cola que escucha conexiones TCP/IP entrantes. El sistema operativo tiene su propio límite en el tamaño de la cola. La página del manual para la llamada de sistema Unix `listen()` proporcion más detalles. Consulte la documentación del SO para el máximo valor de esta variable. Intentar cambiar el valor de `back_log` por encima del límite del sistema operativo no es efectivo.

- `basedir`

  El directorio de instalación de MySQL. Esta variable puede cambiarse con la opción `--basedir` .

- `bdb_cache_size`

  El tamaño del buffer que se utiliza para cachear índices y registros para tablas `BDB` . Si no usa tablas `BDB` debe arrancar mysqld con `--skip-bdb` para no gastar memoria para esta caché.

- `bdb_home`

  El directorio base para las tablas `BDB` tables. Debe asignarse el mismo valor que para la variable `datadir`.

- `bdb_log_buffer_size`

  El tamaño del buffer que se utiliza para cachear índices y registros para tablas `BDB` . Si no usa tablas `BDB` , debe usar el valor 0 o arrancar mysqld con `--skip-bdb` para no gastar memoria con esta caché.

- `bdb_logdir`

  El directorio en que el motor de almacenamiento `BDB` escribe sus ficheros de log. Esta variable puede cambiarse con la opción `--bdb-logdir` .

- `bdb_max_lock`

  El máximo número de bloqueos que pueden tenerse activos en una tabla `BDB` (10,000 por defecto). Debe incrementarlo si errores como los siguientes ocurren cuando realiza transacciones grandes o cuando mysqld tiene que examinar muchos registros para calcular una consulta:

      bdb: Lock table is out of available locks
      Got error 12 from ...

- `bdb_shared_data`

  Está `ON` si usa `--bdb-shared-data`.

- `bdb_tmpdir`

  El valor de la opción `--bdb-tmpdir` .

- `bdb_version`

  Consulte la versión de `version_bdb`.

- `binlog_cache_size`

  El tamaño de la caché para tratar comandos SQL para el log binario durante una transacción. La cache del log binario se guarda para cada cliente si el servidor soporta diversos motores de almacenamiento transaccionales, empezando por MySQL 4.1.2, si el servidor tiene activados los logs binarios (opción `--log-bin`). Si suele usar transacciones grandes, con múltiples comandos, puede incrementar este valor para mejorar el rendimiento. Las variables de estado `Binlog_cache_use` y `Binlog_cache_disk_use` pueden ser útiles para ajustar el tamaño de estas variables. Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

- `bulk_insert_buffer_size`

  `MyISAM` usa una caché especial con forma de árbol para hacer las inserciones más rápidas para `INSERT ... SELECT`, `INSERT ... VALUES (...), (...), ...`, y `LOAD DATA INFILE`. Esta variable limita el tamaño del árbol de la caché en bytes por thread. Cambiarlo a 0 desactiva esta optimización. Nota: Esta caché se usa sólo al añadir datos en una tabla no vacía. El valor por defecto es 8MB.

- `character_set_client`

  El conjunto de carácteres para comandos que llegan del cliente.

- `character_set_connection`

  El conjunto de carácteres usado por los literales que no tienen un conjunto de carácteres introducido y para conversiones de números a cadenas de carácteres.

- `character_set_database`

  El conjunto de carácteres usado por la base de datos por defecto. El servidor actualiza esta variable cada vez que la base de datos por defecto cambia. Si no hay base de datos por defecto, la variable toma el mismo valor que `character_set_server`.

- `character_set_results`

  El conjunto de carácteres usado para retornar los resultados de las consultas al cliente.

- `character_set_server`

  El conjunto de carácteres por defecto del servidor.

- `character_set_system`

  El conjunto de carácteres usado por el servidor para almacenar identificadores. El valor es siempre `utf8`.

- `character_sets_dir`

  El directorio en el que están instalados los conjuntos de carácteres.

- `collation_connection`

  La colación del conjunto de carácteres de las conexiones.

- `collation_database`

  La colación usada por la base de datos por defecto. El servidor cambia esta variable cada vez que la base de datos por defecto cambia. Si no hay una base de datos por defecto, la variable toma el valor de `collation_server`.

- `collation_server`

  La colación por defecto del servidor.

- `concurrent_insert`

  Si `ON` (por defecto), MySQL permite comandos `INSERT` y `SELECT` que se ejecuten concurrentemente para tablas `MyISAM` que no tienen bloques libres en el medio. Puede desactivar esta opción arrancando mysqld con `--safe` or `--skip-new`.

  En MySQL 5.0.6 esta variable ha cambiado a un entero que toma 3 valores:

  Valor | Descripción
  0 | Off
  1 | (Defecto) Permite inserciones concurrentes para tablas MyISAM que no tienen agujeros
  2 | Permite inserciones concurrentes para todas las tablas MyISAM. Si la tabla tiene un agujeroy está en uso por otro thread el nuevo registro se insertará al final de la tabla. Si la tabla no está en uso, MySQL hará un bloqueo de lectura normal e insertará el registro en el agujero.

- `connect_timeout`

  El número de segundos que el servidor mysqld espera para un paquete de conexión antes de responder con `Bad handshake`.

- `datadir`

  El directorio de datos de MySQL. Esta variable puede cambiarse con la opción `--datadir`.

- `default_week_format`

  El modo a usar por la función `WEEK()`.

- `delay_key_write`

  Esta opción se aplica sólo a tablas `MyISAM` . Puede tener uno de los siguientes valores que afectan la forma de tratar la opción `DELAY_KEY_WRITE` que puede usarse en los comandos `CREATE TABLE` .

  Opción | Descrición
  `OFF` | `DELAY_KEY_WRITE` se ignora.
  `ON` | MySQL activa la opción `DELAY_KEY_WRITE` para `CREATE TABLE`. Este es el valor por defecto.
  `ALL` | Todas las nuevas tablas abiertas se tratan como si se hubieran creado con la opción `DELAY_KEY_WRITE` activada.

  Si `DELAY_KEY_WRITE` está activo, significa que el key buffer para tablas con esta opción no se vuelcan en cada actualización del índice, sino que sólo cuando se cierra una tabla. Esto acelera las escrituras de claves, pero si usa esta característica, debe añadir chequeo automático de todas las tablas `MyISAM` arrancando el servidor con la opción `--myisam-recover` (por ejemplo `--myisam-recover=BACKUP,FORCE`). Consulte Sección 5.3.1, “Opciones del comando mysqld” y Sección 14.1.1, “Opciones de arranque de `MyISAM`”.

  Tenga en cuenta que `--external-locking` no ofrece ninguna protección contra corrupción de índices para tablas que usan escrituras de claves retardadas.

- `delayed_insert_limit`

  Tras insertar `delayed_insert_limit` registros retardados, el thread que se encarga del `INSERT DELAYED` comprueba si hay algún comando `SELECT` pendiente. Si es así, les permite que se ejecuten antes de continuar insertando registros retardados.

- `delayed_insert_timeout`

  Cuánto debe esperar el thread encargado de `INSERT DELAYED` para un comando `INSERT` antes de terminar.

- `delayed_queue_size`

  Este es el límite por tabla del número de registros a encolar cuando se tratan comandos `INSERT DELAYED` . Si la cola se llena, cualquier cliente que lance un comando `INSERT DELAYED` espera hasta que haya espacio en la cola de nuevo.

- `expire_logs_days`

  El número de días para eliminar el log binario automáticamente. El valor por defecto es 0, lo que significa ``sin eliminación automática''. Las posibles eliminaciones se realizan al arranque y en la rotación del log binario.

- `flush`

  Está `ON` si ha arrancado mysqld con la opción `--flush`.

- `flush_time`

  Si se asigna un valor distinto a cero, todas las tablas se cierran cada `flush_time` segundos para liberar recursos y sincronizar datos no volcados en disco. Recomendamos que esta opción se use sólo en Windows 9x o Me, o en sistemas con recursos mínimos.

- `ft_boolean_syntax`

  La lista de operadores soportado por búsquedas full-text booleanas usando `IN BOOLEAN MODE`. Consulte Sección 12.7.1, “Búsquedas booleanas de texto completo (Full-Text)”.

  El valor por defecto de la variable es `'+ -><()~*:""&|'`. Las reglas para cambiar el valor son las siguientes:

  - La función del operador viene determinada por su posición en la cadena de carácteres.

  - El valor de reemplazo debe tener 14 carácteres.

  - Cada carácter debe ser ASCII y no alfanumérico.

  - El primer o segundo carácter debe ser un espacio.

  - No se permiten duplicados excepto los operadores delimitadores de frase en las posiciones 11 y 12. Estos dos carácteres no tienen porqué ser los mismos, pero son los dos únicos posibles.

  - Las posiciones 10, 13, y 14 (que por defecto son '`:`', '`&`', y '`|`') están reservados para extensiones futuras.

- `ft_max_word_len`

  La longitud máxima de la palabra incluída en un índice `FULLTEXT` .

  Nota: índices `FULLTEXT` deben reconstruirse al cambiar esta variable. Use `REPAIR TABLE `tbl_name` QUICK`.

- `ft_min_word_len`

  La longitud mínima de la palabra a incluirse en un índice `FULLTEXT` .

  Nota: índices `FULLTEXT` deben reconstruirse tras cambiar estas variables. Use `REPAIR TABLE `tbl_name` QUICK`.

- `ft_query_expansion_limit`

  El número de mejores coincidencias a usar en búsquedas full-text realizadas usando `WITH QUERY EXPANSION`.

- `ft_stopword_file`

  El fichero del que lee la lista de palabras de detención en búsquedas full-text. Todas las palabras del fichero se usan; los comentarios no se tienen en cuenta. Por defecto, se usa una lista de palabras de detención ( como se define en el fichero `myisam/ft_static.c` ). Actualizar esta variable con una cadena vacía (`''`) desactiva el filtrado de palabras de detención.

  Nota: índices `FULLTEXT` deben reconstruirse tras cambiar esta variable o los contenidos del fichero de palabras de detención. Use `REPAIR TABLE `tbl_name` QUICK`.

- `group_concat_max_len`

  El valor máximo permitido para la longitud del resultado de la función `GROUP_CONCAT()`.

- `have_archive`

  `YES` si mysqld soporta tablas `ARCHIVE`, `NO` si no.

- `have_bdb`

  `YES` si mysqld soporta tablas `BDB`. `DISABLED` si se usa `--skip-bdb`.

- `have_compress`

  Si está disponible la biblioteca de compresión `zlib` en el servidor. Si no lo está, las funciones `COMPRESS()` y `UNCOMPRESS()` no pueden usarse.

- `have_crypt`

  Si la llamada de sistema `crypt()` está disponible en el servidor. Si no, la función `CRYPT()` no puede usarse.

- `have_csv`

  `YES` si mysqld soporta tablas `ARCHIVE`, `NO` si no.

- `have_example_engine`

  `YES` si mysqld soporta tablas `EXAMPLE` , `NO` si no.

  `have_federated_engine`

  `YES` si mysqld soporta tablas `FEDERATED`, `NO` si no. Esta variable se añadió en MySQL 5.0.3.

- `have_geometry`

  Si el servidor soporta tipos de datos espaciales.

- `have_innodb`

  `YES` si mysqld soporta tablas `InnoDB` . `DISABLED` si se usa `--skip-innodb`.

- `have_isam`

  En MySQL 5.0, esto aparece sólo por razones de compatibilidad con versiones anteriores, y siempre es `NO`, ya que no hay soporte para tablas `ISAM`.

- `have_ndbcluster`

  `YES` si mysqld soporta tablas `NDB Cluster` . `DISABLED` si se usa `--skip-ndbcluster` .

- `have_openssl`

  `YES` si mysqld soporta SSL (encriptación) del protocolo cliente/servidor.

- `have_query_cache`

  `YES` si mysqld soporta la cache de consultas.

- `have_raid`

  `YES` si mysqld soporta la opción `RAID` .

- `have_rtree_keys`

  Si los índices `RTREE` están disponibles. (Se usan para indexación espacial en tablas `MyISAM`.)

- `have_symlink`

  Si el soporte para enlaces simbólicos está activado. Es un requesito en Unix para soporte de las opciones de tabla `DATA DIRECTORY` y `INDEX DIRECTORY` .

- `init_connect`

  Una cadena de carácteres que ejecuta el servidor para cada cliente que se conecta. La cadena consiste en uno o más comandos SQL. Para especificar varios comandos, sepárelos con un punto y coma. Por ejemplo, cada cliente arranca por defecto con modo autocommit activado. No hay ninguna variable de servidor global para especificar que autocommit esté desactivado por defecto, pero puede usar `init_connect` para conseguir el mismo efecto:

      SET GLOBAL init_connect='SET AUTOCOMMIT=0';

  Esta variable puede cambiarse en la línea de comandos o en un fichero de opciones. Para cambiar la variable tal y como se ha mostrado usando un fichero de opciones, incluya las siguientes líneas:

      [mysqld]
      init_connect='SET AUTOCOMMIT=0'

  Tenga en cuenta que el contenido de `init_connect` no se ejecuta para usuarios con el privilegio `SUPER`; esto es para el caso que el contenido se haya introducido incorrectamente (contiene una consulta incorrecta, por ejemplo con un error de sintaxis), haciendo que todas las conexiones fallen. No ejecutarlo para usuarios `SUPER` permite que éstos abran una conexión y arreglen `init_connect`.

- `init_file`

  El nombre del fichero especificado con la opción `--init-file` cuando arranca el servidor. Este fichero contiene comandos SQL que se ejecutan al arrancar el servidor. Cada comando debe estar en una única línea y no debe incluir comentarios.

- `init_slave`

  Esta variable es similar a `init_connect`, pero es una cadena de carácteres que se ejecuta por parte de un servidor esclavo cada vez que el thread SQL arranca. El formato de la cadena de carácteres es el mismo que para la variable `init_connect`.

- `innodb_`xxx``

  Las variables `InnoDB` de sistema se listan en Sección 15.4, “Opciones de arranque de `InnoDB`”.

- `interactive_timeout`

  El número de segundos que espera el servidor para actividad en una conexión interactiva antes de cerrarla. Un cliente interactivo se define como un cliente que usa la opción `CLIENT_INTERACTIVE` para `mysql_real_connect()`. Consulte también `wait_timeout`.

- `join_buffer_size`

  El tamaño del buffer que se usa para full joins (joins que no usan índices). Normalmente la mejor forma de conseguir joins rápidos es añadir índices. Incrementar el valor de `join_buffer_size` para obtener un full join más rápido cuando se añaden índices no es posible. Un buffer para joins se reserva para cada full join entre dos tablas. Para un join complejo entre varias tablas en que sus índices no se usan, buffers para joins múltiples pueden ser necesarios.

- `key_buffer_size`

  Los bloques de índices para tablas `MyISAM` y `ISAM` se guardan en buffers y se comparten para todos los threads. `key_buffer_size` es el tamaño del buffer usado para los bloques de índices. El key buffer también se conoce como la key cache.

  El tamaño máximo permitido para `key_buffer_size` es 4GB. El máximo tamaño efectivo puede ser menor, dependiendo de la memoria RAM física y los límites por proceso de RAM impuestos por el sistema operativo o la plataforma hardware.

  Incremente el valor para obtener un mejor tratamiento de índices (para todas las lecturas y escrituras múltiples) al máximo que pueda permitirse. El uso de un valor que sea el 25% del total de memoria en una máquina que principalmente ejecute MySQL es bastante común. Sin embargo, si el valor es demasiado grande (por ejemplo, más del 50% del total de la memoria) el sistema puede empezar a paginar y ser extremadamente lento. MySQL confía en el sistema operativo para tratar el cacheo del sistema de ficheros para las lecturas de datos, así que debe dejar algún espacio para cachear el sistema de ficheros.

  Para más velocidad al escribir varios registros al mismo tiempo , use `LOCK TABLES`. Consulte Sección 13.4.5, “Sintaxis de `LOCK TABLES` y `UNLOCK TABLES`”.

  Puede chequear el rendimiento del key buffer con el comando `SHOW STATUS` y examinando las variables de estado `Key_read_requests`, `Key_reads`, `Key_write_requests`, y `Key_writes` . Consulte Sección 13.5.4, “Sintaxis de `SHOW`”.

  El ratio `Key_reads/Key_read_requests` normalmente debe ser menor a 0.01. El ratio `Key_writes/Key_write_requests` normalmente está cerca de 1 si usa mayoritariamente actualizaciones y borrados, pero puede ser mucho menor si tiende a hacer actualizaciones que afecten a muchos registros al mismo tiempo o si usa la opción de tabla `DELAY_KEY_WRITE` .

  La fracción del key buffer en uso puede determinarse mediante `key_buffer_size` conjuntamente con la variable de estado `Key_blocks_unused` y el tamaño de bloque del buffer. El tamaño de bloque del buffer está disponible en la variable de servidor `key_cache_block_size` . La fracción del buffer en uso es:

      1 - ((Key_blocks_unused * key_cache_block_size) / key_buffer_size)

  Este valor es una aproximación ya que algún espacio del key buffer puede estar reservado internamente para estructuras administrativas.

  En MySQL 5.0, es posible crear múltiples key caches para tablas MyISAM. El límite de tamaño de 4GB se aplica a cada caché individualmente, no como grupo. Consulte Sección 7.4.6, “La caché de claves de `MyISAM`”.

- `key_cache_age_threshold`

  Este valor controla la demotion de buffers desde la sub-cadena caliente de una key cache a la sub-cadena templada. Los valores más pequeño provocan que la demotion ocurra más rápidamenet. El valor mínimo es 100. El valor por defecto es 300. Consulte Sección 7.4.6, “La caché de claves de `MyISAM`”.

- `key_cache_block_size`

  El tamaño en bytes de los bloques de la key cache. El valor por defecto es 1024. Consulte Sección 7.4.6, “La caché de claves de `MyISAM`”.

- `key_cache_division_limit`

  El punto de división entre las sub-cadenas calientes y tempaladas de la cadena del buffer de la key cache. El valor es el porcentaje de la cadena del buffer para usar en la sub-cadena templada. El rango de los valores permitidos es de 1 a 100. El valor por defecto es 100. Consulte Sección 7.4.6, “La caché de claves de `MyISAM`”.

- `language`

  El idioma usado para los lenguajes de error.

- `large_file_support`

  Si mysqld está compilado con la opción de soporte para grandes ficheros.

- `large_pages`

  Indica si está activado el soporte para páginas grandes. Esta variable se añadió en MySQL 5.0.3.

- `license`

  El tipo de licencia que tiene el servidor.

- `local_infile`

  Si `LOCAL` está soportado para comandos `LOAD DATA INFILE`.

- `locked_in_memory`

  Si mysqld está bloqueado en memoria con `--memlock`.

- `log`

  Si el logueo de todas las consultas en el log general de consultas está activado. Consulte Sección 5.10.2, “El registro general de consultas”.

- `log_bin`

  Si el log binario está activado. Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

- log_bin_trust_routine_creators

  Esta variable se aplica cuando el log binario está activado. Controla si los creadores de rutinas almacenadas son o no de confianza para crear rutinas almacenadas que escribirán eventos no seguros en el log binario. Si está a 0 (por defecto), los usuarios no tienen permiso para crear o cambiar rutinas almacenadas a no ser que tengan el privilegio `SUPER` además del privilegio `CREATE ROUTINE` o `ALTER ROUTINE` .

  Asignar el valor 0 fuerza la restricción que una rutina debe declararse con la característica `DETERMINISTIC` , o con las características `READS SQL DATA` o `NO SQL` . Si la variable tiene el valor 1, MySQL no fuerza esta restricción en la creación de rutinas almacenadas.

  Consulte Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

  Esta variable se añadió en MySQL 5.0.6.

- `log_error`

  La localización del log de errores.

- `log_slave_updates`

  Si las actualizaciones recibidas por un servidor esclavo de un servidor maestro deben loguearse en el log binario del servidor esclavo. El logueo binario debe estar disponible en el esclavo para que tenga efecto. Consulte Sección 6.8, “Opciones de arranque de replicación”.

- `log_slow_queries`

  Si una consulta lenta debe loguearse. ``Lenta'' está determinado por el valor de la variable `long_query_time`. Consulte Sección 5.10.4, “El registro de consultas lentas (Slow Query Log)”.

- `log_warnings`

  Si produce mensajes de advertencia adicionales. Está activado por defecto. Las conexiones abortadas no se loguean en el log de error a no ser que el valor sea mayor a 1.

- `long_query_time`

  Si una consulta dura más que este valor en segundos, la variable de estado `Slow_queries` se incrementa. Si está usando la opción `--log-slow-queries` , la consulta se loguea en el fichero de log para consultas lentas. Este valor se mide en tiempo real, no tiempo de CPU, así que una consulta que esté bajo el umbral en un sistema con poca carga puede estar por encima del umbral en un sistema con mucha carga. Consulte Sección 5.10.4, “El registro de consultas lentas (Slow Query Log)”.

- `low_priority_updates`

  Con el valor `1`, todos los comandos `INSERT`, `UPDATE`, `DELETE`, y `LOCK TABLE WRITE` esperan hasta que no hayan pendientes `SELECT` o `LOCK TABLE READ` en la tabla afectada. Esta variable se llamaba préviamente `sql_low_priority_updates`.

- `lower_case_file_system`

  Esta variable indica si el sistema de ficheros donde el directorio de datos está localizado tiene nombres de ficheros no sensibles a mayúsculas y minúsculas. `ON` significa que los nombres del fichero no son sensibles a mayúsculas y minúsculas, `OFF` significa que son sensibles a mayúsculas y minúsculas.

- `lower_case_table_names`

  Con el valor 1, los nombres de tablas se almacenan en minúsuculas en disco y las comparaciones de nombres de tablas no tienen en cuenta mayúsculas y minúsculas. Esta opción también se aplica a nombres de bases de datos y alias de tablas. Consulte Sección 9.2.2, “Sensibilidad a mayúsuclas y minúsculas de identificadores”.

  Si usa tablas `InnoDB` , debe asignar a esta variable el valor 1 en todas las plataformas para forzar que los nombres se conviertan a minúsculas.

  No debe asignar a esta variable el valor 0 si está ejecutando MySQL en un sistema que no tiene nombres de ficheros sensibles a mayúsculas y minúsculas (tales como Windows o Mac OS X). Si esta variable no tiene un valor al arrancar y el sistema de ficheros donde está localizado el directorio de datos no tiene nombres de ficheros sensibles a mayúsculas y minúsculas, MySQL automáticamente asigna a `lower_case_table_names` el valor 2.

- `max_allowed_packet`

  El tamaño máximo de un paquete o cualquier cadena de carácteres generada/intermedia.

  El buffer de paquetes de mensajes se inicializa a `net_buffer_length` bytes, pero puede crecer hasta `max_allowed_packet` bytes cuando sea necesario. Este valor por defecto es pequeño, para recibir paquetes grandes (posiblemente incorrectos).

  Debe incrementar este valor si está usando columnas grandes `BLOB` o cadenas de carácteres largas. Debe ser tan grande como el mayor `BLOB` que quiera usar. En MySQL 5.0, el límite del protocolo para `max_allowed_packet` es 1GB.

- `max_binlog_cache_size`

  Si una transacción con múltiples comandos requiere más que esta cantidad de memoria, obtiene el error `Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage`.

- `max_binlog_size`

  Si una escritura en el log binario excede el valor dado, rota el log binario. No puede cambiar este valor a más de 1GB o a menos de 4096 bytes. El valor por defecto es 1GB.

  Nota en caso que use transacciones: Una transacción se escribe en un trozo del log binario, así que nunca se trocea entre varios logs binarios. Por lo tanto, si tiene transacciones grandes, puede ver logs binarios mayores que `max_binlog_size`.

  Si `max_relay_log_size` es 0, el valor de `max_binlog_size` se aplica a relay logs también.

- `max_connect_errors`

  Si hay más que este número de conexiones interrumpidas de un equipo, este equipo se bloquea para más conexiones. Puede desbloquear equipos bloqueados con el comando `FLUSH HOSTS`.

- `max_connections`

  El número de conexiones de cliente simultáneas permitidas. Incrementar este valor incrementa el número de descriptores de fichero que requiere mysqld . Consulte Sección 7.4.8, “Cómo abre y cierra tablas MySQL” para comentarios sobre límites en los descriptores de fichero. Consulte también Sección A.2.6, “`Demasiadas conexiones`”.

- `max_delayed_threads`

  No arranque más que este número de threads para tratar comandos `INSERT DELAYED` . Si trata de insertar datos en una nueva tabla después de que todos los threads `INSERT DELAYED` estén en uso, el registro se inserta como si el atributo `DELAYED` no se hubiera especificado. Si cambia este valor a 0, MySQL nunca crea un thread para tratar registros `DELAYED` ; en efecto, esto desactiva `DELAYED` completamente.

- `max_error_count`

  El número máximo de mensajes de error, advertencia, y notas que se guardan para mostrar con `SHOW ERRORS` o `SHOW WARNINGS`.

- `max_heap_table_size`

  Esta variable cambia el máximo valor para el que las tablas `MEMORY` (`HEAP`) pueden crecer. El valor de la variable se usa para calcular el valor `MAX_ROWS` en tablas `MEMORY`. Cambiar esta variable no tiene efecto en ninguna tabla `MEMORY` existente, a no ser que la tabla se recree con un comando tal como `CREATE TABLE` o `TRUNCATE TABLE`, o cambiada con `ALTER TABLE`.

- `max_insert_delayed_threads`

  Esta variable es sinónimo de `max_delayed_threads`.

- `max_join_size`

  No permite los comandos `SELECT` que probablemente tengan que examinar más de `max_join_size` registros (para comandos en una misma tabla) o combinaciones de registros (para comandos con varias tablas) o que sea probable que hagan más de `max_join_size` búsquedas de disco. Al cambiar este valor, puede cazar los comandos `SELECT` donde las claves no se usan correctamente y que probablemente tardaran mucho tiempo. Cámbielo si sus usuarios tienden a realizar joins sin una cláusula `WHERE` , que tarden mucho tiempo, o que devuelvan millones de registros.

  Al cambiar esta variable a un valor que no sea `DEFAULT` resetea el valor de `SQL_BIG_SELECTS` a `0`. Si cambia el valor `SQL_BIG_SELECTS` de nuevo, la variable `max_join_size` se ignora.

  Si el resultado de una consulta está en la caché de consultas, no se hace el chequeo del tamaño del resultado, ya que el resultado se ha computado préviamente y no carga al servidor al enviarlo al cliente.

  Esta variable préviamente se llamaba `sql_max_join_size`.

- `max_length_for_sort_data`

  El límite en el tamaño del índice que determina qué algoritmo `filesort` se usa. Consulte Sección 7.2.10, “Cómo optimiza MySQL `ORDER BY`”.

- `max_relay_log_size`

  Si una escritura de un esclavo de replicación a su relay log excede el valor dado, rota el relay log. Esta variable le permite poner diferentes restricciones de tamaño en logs binarios y relay logs. Sin embargo, cambiar la variable a 0 hace que MySQL use `max_binlog_size` para el log binario y el relay log. Debe asignar un valor a `max_relay_log_size` entre 4096 bytes y 1GB (incluídos), o 0. El valor por defecto es 0. Consulte Sección 6.3, “Detalles de la implementación de la replicación”.

- `max_seeks_for_key`

  Limita el máximo número de búsquedas al buscar registros basados en una clave. El optimizador de MySQL asume que no se requieren más que este número de búsquedas de claves al buscar registros en una tabla al escanear una clave, a pesar de la cardinalidad real de la clave (consulte Sección 13.5.4.11, “Sintaxis de `SHOW INDEX`”). Si se pone un valor pequeño (100?), puede forzar a MySQL a que prefiera claves en lugar de escaneos de tablas.

- `max_sort_length`

  Número de bytes que se usan al ordenar valores `BLOB` o `TEXT` . Sólo los primeros `max_sort_length` bytes cada valor se usan; el resto se ignoran.

- `max_tmp_tables`

  El número máximo de tablas temporales que un cliente puede mantener abiertas al mismo tiempo. (Esta opción todavía no hace nada.)

- `max_user_connections`

  El número máximo de conexiones simultáneas permitidas para cualquier cuenta MySQL dada. Un valor 0 significa ``sin límites.''

  Antes de MySQL 5.0.3, esta variable sólo tenía visibilidad global. A partir de MySQL 5.0.3, también tiene visibilidad para sesiones de sólo lectura. La variable de sesión tiene el mismo valor que la variable global a no ser que la cuenta actual tenga un valor diferente a 0 en el límite de recursos `MAX_USER_CONNECTIONS` . En este caso, el valor de sesión refleja el límite de la cuenta.

- `max_write_lock_count`

  Después de varios bloqueos de escritura, permite que algunos bloqueos de lectura se ejecuten en medio.

- `multi_read_range`

  Especifica el máximo número de rangos a enviar a un motor de almacenamiento durante la selección de rangos. El valor por defecto es 256. Enviar múltiples rangos a un motor es una característica que puede mejorar el rendimiento de ciertas selecciones dramáticamente, particularmente para `NDBCLUSTER`. Este motor necesita enviar la petición de rangos a todos los nodos, y enviar muchas de estas peticiones a la vez reduce el coste de comunicación significativamente. Esta variable se añadió en MySQL 5.0.3.

- `myisam_data_pointer_size`

  El tamaño por defecto para punteros en bytes, para ser usado con `CREATE TABLE` para tablas `MyISAM` cuando no se especifica la opción `MAX_ROWS` . Esta variable no puede ser menor que 2 ni mayor que 7. El valor por defecto es 4. Consulte Sección A.2.11, “`The table is full`”.

- (OBSOLETO) `myisam_max_extra_sort_file_size`

  Si el fichero temporal usado para índexación rápida `MyISAM` es mayor que usando la key cache con la cantidad especificada aquí, se utiliza preferentemente el método de la key cache. Esto se usa para forzar que las claves largas de carácteres en grandes tablas usen el método de de key cache (más lento) para crear el índice. Este valor se da en bytes.

  Nota: Esta variable se eliminó en MySQL 5.0.6.

- `myisam_max_sort_file_size`

  El tamaño máximo para tablas temporales que MySQL permite para recrear un índice `MyISAM` (durante `REPAIR TABLE`, `ALTER TABLE`, o `LOAD DATA INFILE`). Si el tamaño del fichero fuese mayor que este valor, el índice se crea usando la key cache en su lugar, lo cual es más lento. El valor se da en bytes.

- `myisam_recover_options`

  El valor para la opción `--myisam-recover`.

- `myisam_repair_threads`

  Si este valor es mayor que 1, los índices de tablas `MyISAM` se crean en paralelo (cada índice en su propio thread) durante el proceso `Repair by sorting` . El valor por defecto es 1. Nota: Reparación multi-threaded repair todavía es código con calidad alpha.

- `myisam_sort_buffer_size`

  El buffer que se reserva al ordenar índices `MyISAM` durante `REPAIR TABLE` o al crear índices con `CREATE INDEX` o `ALTER TABLE`.

- `named_pipe`

  (Sólo en Windows.) Indica si el servidor soporta conexiones sobre named pipes.

- `net_buffer_length`

  El buffer de comunicación se resetea a este tamaño entre consultas. Normalmente, debe cambiarse, pero si tiene poca memoria, puede inicializarse al tamaño esperado para los comandos SQL enviados por los clientes. Si los comandos exceden este tamaño, el buffer crece automáticamente, hasta `max_allowed_packet` bytes.

- `net_read_timeout`

  El número de segundos a esperar más datos de una conexión antes de abortar la lectura. Cuando el servidor está leyendo del cliente, `net_read_timeout` es el valor que controla el tiempo máximo para abortar. Cuando el servidor está escribiendo en el cliente, `net_write_timeout` es el valor que controla el tiempo máximo para abortar. Consulte también `slave_net_timeout`.

- `net_retry_count`

  Si una lectura en un puerto de comunicaciones se interrumpe, reintenta las veces especificadas antes de abandonar. Este valor debe inicializarse a un valor alto en FreeBSD, ya que las interrupciones internas se envían a todos los threads.

- `net_write_timeout`

  Número de segundos a esperar para que se escriba un bloque en una conexión antes de abortar la escritura. Consulte también `net_read_timeout`.

- `new`

  Esta variable se usaba en MySQL 4.0 para activar algunos comportamientos de la versión 4.1 y se mantiene para compatibilidad con versiones anteriores. En MySQL 5.0, el valor siempre es `OFF`.

- `old_passwords`

  Si el servidor debe usar contraseñas estilo anterior a la versión 4.1 para cuentas de usuario de MySQL. Consulte Sección A.2.3, “`Client does not support authentication protocol`”.

- `open_files_limit`

  Número de ficheros que el sistema operativo permite abrir mysqld . Este es el valor real permitido por el sistema y puede ser distinto del valor que se da a mysqld al arrancar. El valor es 0 en sistemas donde MySQL puede cambiar el número de ficheros abiertos.

- `optimizer_prune_level`

  Controla el heurístico aplicado durante la optimización de consultas para no hacer los planes parciales menos prometedores en el espacio de búsqueda del optimizador. Un valor de 0 desactiva el heurístico de forma que el optimizador realiza una búsqueda exhaustiva. Un valor de 1 provoca que el optimizador elimine planes basados en el número de registros calculados por planes intermedios. Esta variable se añadió en MySQL 5.0.1.

- `optimizer_search_depth`

  La máxima profundidad de búsqueda realizada por el optimizador de consultas. Valores mayores que el número de relaciones en una consulta dan como resultado en mejores planes de consulta, pero lleva más tiempo generar un plan de ejecución para una consulta. Los valores menores que el número de relaciones en una consulta retornan un plan de ejecución más rápido, pero el plan resultante puede estar lejos de ser el plan óptimo. Si se usa como valor 0, el sistema automáticamente escoge un valor razonable. Si se asigna como valor el máximo número de tablas usado en una consulta más 2, el optimizador cambia al algoritmo usado en MySQL 5.0.0 ( y versiones anteriores ) para mejorar el rendimiento de las búsquedas. Esta variable se añadió en MySQL 5.0.1.

- `pid_file`

  La ruta al fichero con el ID de proceso (PID). Esta variable puede cambiarse con la opción `--pid-file`.

- `port`

  El puerto en que escucha el servidor para conexiones TCP/IP. Esta variable puede cambiarse con la opción `--port` .

- `preload_buffer_size`

  El tamaño del buffer que se reserva al pre-cargar los índices.

- `protocol_version`

  La versión del protocolo cliente/servidor usado por el servidor MySQL.

- `query_alloc_block_size`

  El tamaño de bloques de memoria reservado para objetos creados durante el parseo y ejecución de consultas. Si tiene problemas con fragmentación de memoria, puede ayudar incrementar este valor un poco.

- `query_cache_limit`

  No cachea resultados mayores que este número de bytes. El valor por defecto es 1048576 (1MB).

- `query_cache_min_res_unit`

  Tamaño mínimo (en bytes) para bloques reservados en la caché de consultas. El valor por defecto es 4096 (4KB). Para más información acerca de optimizar esta variable consulte Sección 5.12.3, “Configuración de la caché de consultas”.

- `query_cache_size`

  La cantidad de memoria reservada para cachear resultados de consultas. El valor por defecto es 0, lo que desactiva la cache de consultas. Tenga en cuenta que la cantidad de memoria se reserva incluso si `query_cache_type` tiene como valor 0. Consulte Sección 5.12.3, “Configuración de la caché de consultas” para más información.

- `query_cache_type`

  Cambia el tipo de la caché de consultas. Cambiando el valor `GLOBAL` se inicializa el tipo para todos los clientes que se conecten a partir de ese momento. Clientes individuales pueden cambiar el valor `SESSION` para afectar a su propio uso de la caché de consultas. Los posibles valores se muestran en la siguiente tabla:

  Opción | Descripción
  `0` o `OFF` | No cachea o retorna los resultados. Tenga en cuenta que esto no elimina el buffer caché para consultas. Para hacerlo, debe asignar 0 a `query_cache_size`.
  `1` o `ON` | Cachea todos los resultados de consultas excepto los que empiecen con `SELECT SQL_NO_CACHE`.
  `2` o `DEMAND` | Cachea los resultados sólo para consultas que comiencen con `SELECT SQL_CACHE`.

  En MySQL 5.0, el valor por defecto de esta variable es `ON`.

- `query_cache_wlock_invalidate`

  Normalmente, cuando un cliente adquiere un bloqueo `WRITE` en una tabla `MyISAM` , el resto de clientes no se bloquean para consultas cuyo resultado esté presente en la caché para consultas. Cambiando el valor de esta variable a 1 provoca que la adquisición de una tabla mediante un bloqueo `WRITE` invalida cualquier consulta en la caché de consultas que se refiera a la tabla. Esto fuerza a que otros clientes que traten de acceder a la tabla esperen mientras el bloqueo esté activo.

- `query_prealloc_size`

  El tamaño del buffer persistente usado para parsear y ejecutar consultas. Este buffer no se libera entre consultas. Si está ejecutando consultas complejas, un valor mayor de `query_prealloc_size` puede ser de utilidad para mejorar el rendimiento, ya que puede reducir la necesidad del servidor de realizar reserva de memoria durante las operaciones de ejecución de consultas.

- `range_alloc_block_size`

  El tamaño de los bloques que se reservan en la optimización de rango.

- `read_buffer_size`

  Cada thread que realiza un escaneo secuencial reserva un buffer de su tamaño (en bytes) para cada tabla que escanea. Si realiza muchos escaneos secuenciales, puede incrementar este valor, que por defecto es 131072.

- `read_only`

  Cuando una variable tiene el valor `ON` para un servidor esclavo de replicación, esto causa que el esclavo no permita actualizaciones excepto de threads de esclavos o de usuarios con el privilegio `SUPER`. Esto puede ser útil para asegurar que un servidor esclavo no acepte actualizaciones de los clientes.

- `relay_log_purge`

  Desactiva o activa el purgado automático de los relay logs tan pronto como no se necesitan. El valor por defecto es 1 (activado).

- `read_rnd_buffer_size`

  Cuando se leen registros ordenadamante tras una ordenación, los registros se leen a través de su buffer para evitar búsquedas en disco. Asignar a esta variable un valor mayor puede mejorar mucho el rendimiento de `ORDER BY`. Sin embargo, hay un buffer para cada cliente, así que no debe asignar un valor grande a la variable global. En lugar de ello, cambie la variable de sesión sólo en los clientes que necesiten ejecutar grandes consultas.

- `secure_auth`

  Si el servidor MySQL ha arrancado con la opción `--secure-auth` , bloquea conexiones de todas las cuentas que tengan las contraseñas almacenadas en el formato antiguo (anterior a 4.1). En ese caso, el valor de esta variable es `ON`, en el contrario es `OFF`.

  Debe activar esta opción si quiere evitar todo uso de contraseñas en el viejo formato (y por lo tanto comunicación insegura en la red).

  El arranque del servidor falla con un error si esta opción está activada y la tablas de privilegios están en formato anterior a 4.1. Consulte Sección A.2.3, “`Client does not support authentication protocol`”.

  Cuando se usa como una opción del lado del cliente, el cliente rehúsa conectar a un servidor si el servidor requiere contraseña en el viejo formato para la cuenta del cliente.

- `server_id`

  El valor de la opción `--server-id` . Se usa para servidores de replicación maestros y esclavos.

- `shared_memory`

  (Sólo en Windows.) Si el cliente permite conexiones a través de memoria compartida o no.

- `shared_memory_base_name`

  (Sólo en Windows.) Indica si el servidor permite conexiones a través de memoria compartida, e indica el identificador para memoria compartida. Esto es útil al ejecutar varias instancias de MySQL en una única máquina física.

- `skip_external_locking`

  Está `OFF` si mysqld usa bloqueo externo.

- `skip_networking`

  Está `ON` si el servidor permite sólo conexiones locales (no TCP/IP). En Unix, las conexiones locales usan un fichero socket de Unix. En Windows, las conexiones locales usan named pipes o memoria compartida. En NetWare, sólo se soportan conexiones TCP/IP, así que no asigne a esta variable el valor `ON`.

- `skip_show_database`

  Evita que se use el comando `SHOW DATABASES` sin tener el privilegio `SHOW DATABASES` . Esto puede mejorar la seguridad si le preocupa que los usuarios puedan ver las bases de datos pertenecientes a otros usuarios. En MySQL 5.0, su efecto depende del privilegio `SHOW DATABASES`: Si el valor de la variable es `ON`, el comando `SHOW DATABASES` está permitido sólo para usuarios que tengan el privilegio `SHOW DATABASES` , y el comando muestra todos los nombres de bases de datos. Si el valor es `OFF`, `SHOW DATABASES` se permite para todos los usuarios, pero sólo muestra los nombres de bases de datos que el usuario tenga el permiso `SHOW DATABASES` u otros privilegios.

- `slave_compressed_protocol`

  Si usa compresión en el protocolo maestro/servidor si ambos lo soportan.

- `slave_load_tmpdir`

  El nombre del directorio donde el esclavo crea ficheros temporales para replicar el comando `LOAD DATA INFILE`.

- `slave_net_timeout`

  Número de segundos a esperar para más datos en una conexión maestro/ servidor antes de abortar la lectura.

- `slave_skip_errors`

  Los errores de replicación que el esclavo debe dejar pasar (ignorar).

- `slow_launch_time`

  Si la creación de un thread toma más de los segundos especificados por esta variable, el sevidor incrementa la variable de estado `Slow_launch_threads` .

- `socket`

  Plataformas Unix: El fichero socket usado para conexiones clientes locales. Por defecto `/var/lib/mysql/mysql.sock`.

  Windows: El nombre del named pipe usado para conexiones cliente locales. Por defecto `mysql`.

- `sort_buffer_size`

  Cada thread que necesita una ordenación reserva un buffer de su tamaño. El incremento de este valor permite acelerar las operaciones `ORDER BY` o `GROUP BY` . Consulte Sección A.4.4, “Dónde almacena MySQL los archivos temporales”.

- `sql_mode`

  El modo del servidor SQL, que en MySQL 5.0 puede cambiarse dinámicamente. Consulte Sección 5.3.2, “El modo SQL del servidor”.

- `sql_slave_skip_counter`

  El número de eventos del maestro que el servidor esclavo debe ignorar.

- `storage_engine`

  Esta variable es un sinónimo de `table_type`. En MySQL 5.0, `storage_engine` es el nombre preferido.

- `sync_binlog`

  Si es positivo, el servidor MySQL sincroniza su log binario a disco (`fdatasync()`) después de cada escritura `sync_binlog` en su log binario. Tenga en cuenta que sólo hay una escritura en el log binario por comando si está en modo autocommit, y de otra forma una escritura por transacción. El valor por defecto es 0 lo que no sincroniza con disco. Un valor de 1 es la elección más segura, ya que en caso de error se pierden como mucho un comando/transacción del log binario; de todas formas, también es el valor más bajo (a no ser que el disco tenga una caché de batería, lo que hace la sincronización muy rápida).

- `sync_frm`

  Si esta variable se asigna a 1, cuando se crea una tabla no temporal su fichero `.frm` se sincroniza a disco (`fdatasync()`); esto es lo más lento pero más seguro en caso de un error. El valor por defecto es 1.

- `system_time_zone`

  La zona horaria del servidor. Cuando el sevidor comienza la ejecución, hereda unos valores de zona horaria de los valores por defecto de la máquina, posiblemente modificados por el entorno de la cuenta usado para ejecutar el servidor o el script de arranque. El valor se usa para asignar `system_time_zone`. Normalmente la zona horaria se especifica con la variable de entorno `TZ`. También puede especificarse usando la opción `--timezone` del script mysqld_safe .

- `table_cache`

  El número de tablas abiertas por todos los threads. Incrementar este valor incrementa el número de descriptores de ficheros que requiere mysqld . Puede chequear si necesita incrementar la caché de la tabla chequeando la variable de estado `Opened_tables` . Consulte Sección 5.3.4, “Variables de estado del servidor”. Si el valor de `Opened_tables` es grande y no quiere hacer muchos `FLUSH TABLES` (lo que fuerza a cerrar y reabrir todas las tablas), entonces debe incrementar el valor de la variable `table_cache` .

  Para más información sobre la cache de la tabla, consulte Sección 7.4.8, “Cómo abre y cierra tablas MySQL”.

- `table_type`

  El tipo de tabla por defecto (motor de almacenamiento). Para cambiar el tipo de tabla en el arranque del servidor, use la opción `--default-table-type`. Consulte Sección 5.3.1, “Opciones del comando mysqld”.

- `thread_cache_size`

  El número de threads que el servidor debe cachear para reusar. Cuando un cliente desconecta, los threads de clientes se ponen en la caché si hay menos de `thread_cache_size` threads. Peticiones de threads se sirven reusando threads tomados de la caché cuando es posible. Esta variable puede incrementarse para mejorar el rendimiento si tiene muchas nuevas conexiones. (Normalmente esto no da una mejora notable de rendimiento si tiene una buena implementación de threads.) Mediante el estudio de las diferencias entre las variables de estado `Connections` y `Threads_created` (consulte Sección 5.3.4, “Variables de estado del servidor” para más detalles) puede ver lo eficiente que es la caché de threads.

- `thread_concurrency`

  En Solaris, mysqld llama a `thr_setconcurrency()` con este valor. Esta función permite a las aplicaciones dar al sistema de threads una piesta sobre el número deseado de threads que deben ejecutarse simultáneamente.

- `thread_stack`

  El tamaño de la pila para cada thread. Muchos de los límites detectados por el test `crash-me` dependen de este valor. El valor por defecto es lo suficientemente grande para un funcionamiento normal. Consulte Sección 7.1.4, “El paquete de pruebas de rendimiento (benchmarks) de MySQL”.

- `time_zone`

  La zona horaria. El valor inical de este `'SYSTEMA'` (usa el valor de `system_time_zone`), pero puede especificarse explícitamente al arrancar el servidor con la opción `--default-time-zone` .

- `tmp_table_size`

  Si una tabla temporal en memoria excede este tamaño, MySQL la convierte automáticamente en una tabla en disco de tipo `MyISAM`. Incremente el valor de `tmp_table_size` si realiza muchas consultas avanzadas `GROUP BY` y tiene mucha memoria disponible.

- `tmpdir`

  El directorio usado para ficheros y tablas temporales. Esta variable puede tomar una lista de diferentes paths usados con una política round-robin. Estos paths pueden separarse mediante dos puntos ('`:`') en Unix y punto y coma ('`;`') en Windows, NetWare, y OS/2.

  Esta característica puede usarse para repartir la carga entre varios discos físicos. Si el servidor MySQL actúa como un esclavo de replicación, no debe asignar `tmpdir` un valor que apunte a un directorio en un sistema de ficheros en memoria o a un directorio que se borre cada vez que el servidor reinicie. Un esclavo de replicación necesita que algunos de sus ficheros temporales sobrevivan a un reinicio de servidor de forma que pueeda replicar tablas temporales u operaciones `LOAD DATA INFILE` . Si los ficheros en un directorio de ficheros temporales se pierden cuando reinicia el servidor, la replicación falla.

- `transaction_alloc_block_size`

  El tamaño reservado (en bytes) de bloques de memoria que se reservan para almacenar consultas que son partes de una transacción que debe ser guardad en el log binario al hacer un commit.

- `transaction_prealloc_size`

  Tamaño en bytes del buffer persistente para `transaction_alloc_blocks` que no se libera entre consultas. Haciéndolo lo suficientemente grande para guardar todas las consultas dentro de una única transacción, puede evitar varias llamadas `malloc()` .

- `tx_isolation`

  El nivel de aislamiento de transacción por defecto. Por defecto es `REPEATABLE-READ`.

- `updatable_views_with_limit`

  Esta variable controla si las actualizaciones pueden hacerse usando una vista que no contenga una clave primária en la tabla subyacente, si la actualización contiene una cláusula `LIMIT` . (Tales actualizaciones normalmente las generan herramientas GUI.) Una actualización es un comando `UPDATE` o `DELETE`.Clave primaria se refiere a un índice `PRIMARY KEY`, o `UNIQUE` en el que ninguna columna puede contener `NULL`.

  La variable puede tener dos valores:

  - `1` o `YES`: Muestra sólo una advertencia (no un mensaje de error). Este es el valor por defecto.

  - `0` o `NO`: Prohibe la actualización.

  Esta variable se añadió en MySQL 5.0.2.

- `version`

  El número de versión para el servidor.

- `version_bdb`

  La versión del motor de almacenamiento `BDB`.

- `version_comment`

  El script configure tiene una opción `--with-comment` que permite especificar un comentario al compilar MySQL. Esta variable contiene el valor de dicho comentario.

- `version_compile_machine`

  El tipo de máquina o arquitectura en el que se compiló MySQL.

- `version_compile_os`

  El tipo de sistema operativo en el que se compiló MySQL.

- `wait_timeout`

  Número de segundos que el servidor espera para recibir actividad en una conexión no interactiva antes de cerrarla.

  En el arranque de un thread, el valor de la variable de sesión `wait_timeout` se inicializa de la variable global `wait_timeout` o de `interactive_timeout` , dependiendo del tipo de cliente (como se define en la opción de conexión `CLIENT_INTERACTIVE` de `mysql_real_connect()`). Consulte también `interactive_timeout`.

#### 5.3.3.1. Variables de sistema dinámicas

Varias variables de sistema del servidor son dinámicas y pueden cambiarse en tiempo de ejecución mediante `SET GLOBAL` o `SET SESSION`. También puede obtener sus valores usando `SELECT`. Consulte Sección 9.4, “Variables de sistema”.

La siguiente tabla muestra la lista completa de todas las variables dinámicas de sistema. La última columna indica para cada variable si son `GLOBAL` o `SESSION` (o ambas).

Nombre de Variable | Tipo de Valor | Tipo
`autocommit` | booleana | `SESSION`
`big_tables` | booleana | `SESSION`
`binlog_cache_size` | numérica | `GLOBAL`
`bulk_insert_buffer_size` | numérica | `GLOBAL` | `SESSION`
`character_set_client` | cadena de carácteres | `GLOBAL` | `SESSION`
`character_set_connection` | cadena de carácteres | `GLOBAL` | `SESSION`
`character_set_results` | cadena de carácteres | `GLOBAL` | `SESSION`
`character_set_server` | cadena de carácteres | `GLOBAL` | `SESSION`
`collation_connection` | cadena de carácteres | `GLOBAL` | `SESSION`
`collation_server` | cadena de carácteres | `GLOBAL` | `SESSION`
`concurrent_insert` | booleana | `GLOBAL`
`connect_timeout` | numérica | `GLOBAL`
`convert_character_set` | cadena de carácteres | `GLOBAL` | `SESSION`
`default_week_format` | numérica | `GLOBAL` | `SESSION`
`delay_key_write` | `OFF` | `ON` | `ALL` | `GLOBAL`
`delayed_insert_limit` | numérica | `GLOBAL`
`delayed_insert_timeout` | numérica | `GLOBAL`
`delayed_queue_size` | numérica | `GLOBAL`
`error_count` | numérica | `SESSION`
`expire_logs_days` | numérica | `GLOBAL`
`flush` | booleana | `GLOBAL`
`flush_time` | numérica | `GLOBAL`
`foreign_key_checks` | booleana | `SESSION`
`ft_boolean_syntax` | numérica | `GLOBAL`
`group_concat_max_len` | numérica | `GLOBAL` | `SESSION`
`identity` | numérica | `SESSION`
`innodb_autoextend_increment` | numérica | `GLOBAL`
`innodb_concurrency_tickets` | numérica | `GLOBAL`
`innodb_max_dirty_pages_pct` | numérica | `GLOBAL`
`innodb_max_purge_lag` | numérica | `GLOBAL`
`innodb_sync_spin_loops` | numérica | `GLOBAL`
`innodb_table_locks` | booleana | `GLOBAL` | `SESSION`
`innodb_thread_concurrency` | numérica `GLOBAL` |
`innodb_thread_sleep_delay` | numérica `GLOBAL` |
`insert_id` | booleana | `SESSION`
`interactive_timeout` | numérica | `GLOBAL` | `SESSION`
`join_buffer_size` | numérica | `GLOBAL` | `SESSION`
`key_buffer_size` | numérica | `GLOBAL`
`last_insert_id` | numérica | `SESSION`
`local_infile` | booleana | `GLOBAL`
`log_warnings` | numérica | `GLOBAL`
`long_query_time` | numeric | `GLOBAL` | `SESSION`
`low_priority_updates` | booleana | `GLOBAL` | `SESSION`
`max_allowed_packet` | numérica | `GLOBAL` | `SESSION`
`max_binlog_cache_size` | numérica | `GLOBAL`
`max_binlog_size` | numérica | `GLOBAL`
`max_connect_errors` | numérica | `GLOBAL`
`max_connections` | numérica | `GLOBAL`
`max_delayed_threads` | numérica | `GLOBAL`
`max_error_count` | numérica | `GLOBAL` | `SESSION`
`max_heap_table_size` | numérica | `GLOBAL` | `SESSION`
`max_insert_delayed_threads` | numérica | `GLOBAL`
`max_join_size` | numérica | `GLOBAL` | `SESSION`
`max_relay_log_size` | numérica | `GLOBAL`
`max_seeks_for_key` | numérica | `GLOBAL` | `SESSION`
`max_sort_length` | numérica | `GLOBAL` | `SESSION`
`max_tmp_tables` | numérica | `GLOBAL` | `SESSION`
`max_user_connections` | numérica | `GLOBAL`
`max_write_lock_count` | numérica | `GLOBAL`
`multi_read_range` | numérica | `GLOBAL` | `SESSION`
`myisam_data_pointer_size` | numérica | `GLOBAL`
`log_bin_trust_routine_creators` | booleana | `GLOBAL`
`myisam_max_sort_file_size` | numérica | `GLOBAL` | `SESSION`
`myisam_repair_threads` | numérica | `GLOBAL` | `SESSION`
`myisam_sort_buffer_size` | numérica | `GLOBAL` | `SESSION`
`net_buffer_length` | numérica | `GLOBAL` | `SESSION`
`net_read_timeout` | numérica | `GLOBAL` | `SESSION`
`net_retry_count` | numérica | `GLOBAL` | `SESSION`
`net_write_timeout` | numérica | `GLOBAL` | `SESSION`
`old_passwords` | numérica | `GLOBAL` | `SESSION`
`optimizer_prune_level` | numérica | `GLOBAL` | `SESSION`
`optimizer_search_depth` | numérica | `GLOBAL` | `SESSION`
`preload_buffer_size` | numérica | `GLOBAL` | `SESSION`
`query_alloc_block_size` | numérica | `GLOBAL` | `SESSION`
`query_cache_limit` | numérica | `GLOBAL`
`query_cache_size` | numérica | `GLOBAL`
`query_cache_type` | enumeración | `GLOBAL` | `SESSION`
`query_cache_wlock_invalidate` | booleana | `GLOBAL` | `SESSION`
`query_prealloc_size` | numérica | `GLOBAL` | `SESSION`
`range_alloc_block_size` | numérica | `GLOBAL` | `SESSION`
`read_buffer_size` | numérica | `GLOBAL` | `SESSION`
`read_only` | numérica | `GLOBAL`
`read_rnd_buffer_size` | numérica | `GLOBAL` | `SESSION`
`rpl_recovery_rank` | numérica | `GLOBAL`
`safe_show_database` | booleana | `GLOBAL`
`secure_auth` | booleana | `GLOBAL`
`server_id` | numérica | `GLOBAL`
`slave_compressed_protocol` | booleana | `GLOBAL`
`slave_net_timeout` | numérica | `GLOBAL`
`slave_transaction_retries` | numérica | `GLOBAL`
`slow_launch_time` | numérica | `GLOBAL`
`sort_buffer_size` | numérica | `GLOBAL` | `SESSION`
`sql_auto_is_null` | booleana | `SESSION`
`sql_big_selects` | booleana | `SESSION`
`sql_big_tables` | booleana | `SESSION`
`sql_buffer_result` | booleana | `SESSION`
`sql_log_bin` | booleana | `SESSION`
`sql_log_off` | booleana | `SESSION`
`sql_log_update` | booleana | `SESSION`
`sql_low_priority_updates` | booleana | `GLOBAL` | `SESSION`
`sql_max_join_size` | numérica | `GLOBAL` | `SESSION`
`sql_mode` | enumeración | `GLOBAL` | `SESSION`
`sql_notes` | booleana | `SESSION`
`sql_quote_show_create` | booleana | `SESSION`
`sql_safe_updates` | booleana | `SESSION`
`sql_select_limit` | numérica | `SESSION`
`sql_slave_skip_counter` | numérica | `GLOBAL`
`updatable_views_with_limit` | enumeración | `GLOBAL` | `SESSION`
`sql_warnings` | booleana | `SESSION`
`sync_binlog` | numérica | `GLOBAL`
`sync_frm` | booleana | `GLOBAL`
`storage_engine` | enumeración | `GLOBAL` | `SESSION`
`table_cache` | numérica | `GLOBAL`
`table_type` | enumeración | `GLOBAL` | `SESSION`
`thread_cache_size` | numérica | `GLOBAL`
`time_zone` | cadena de carácteres | `GLOBAL` | `SESSION`
`timestamp` | booleana | `SESSION`
`tmp_table_size` | enumeración | `GLOBAL` | `SESSION`
`transaction_alloc_block_size` | numérica | `GLOBAL` | `SESSION`
`transaction_prealloc_size` | numérica | `GLOBAL` | `SESSION`
`tx_isolation` | enumeración | `GLOBAL` | `SESSION`
`unique_checks` | booleana | `SESSION`
`wait_timeout` | numérica | `GLOBAL` | `SESSION`
`warning_count` | numérica | `SESSION`

Variables marcadas como cadena de carácteres toman un valor de cadena de carácteres. Variables marcadas como numérica toman un valor numérico. Variables marcadas como boolean toman como valor 0, 1, `ON` o `OFF`. Variables marcadas como enumeración normalmente deben tomar uno de los valores disponibles para la variable, pero también pueden tomar como valor el número correspondiente al valor deseado de la enumeración. Para variables de sistema enumeradas, el primer valor de la enumeración es 0. Esto difiere de las columnas `ENUM` , en que el primer valor de la enumeración es 1.

### 5.3.4. Variables de estado del servidor

El servidor mantiene muchas variables de estado que proveen de información sobre sus operaciones. Puede ver estas variables y sus valores utilizando la sentencia `SHOW STATUS`:

    mysql> SHOW STATUS;
    +-----------------------------------+------------+
    | Variable_name                     | Value      |
    +-----------------------------------+------------+
    | Aborted_clients                   | 0          |
    | Aborted_connects                  | 0          |
    | Bytes_received                    | 155372598  |
    | Bytes_sent                        | 1176560426 |

    …

    | Connections                       | 30023      |
    | Created_tmp_disk_tables           | 0          |
    | Created_tmp_files                 | 3          |
    | Created_tmp_tables                | 2          |

    …

    | Threads_created                   | 217        |
    | Threads_running                   | 88         |
    | Uptime                            | 1389872    |
    +-----------------------------------+------------+

Muchas variables de estado son inicializadas a 0 por la sentencia `FLUSH STATUS`.

Las variables de estado tienen los siguientes significados. Las variables en las que no se indica versión están presentes en MySQL 5.0. Para información a propósito de su historial de implementación, consulte Manual de referencia de MySQL 4.1.

- `Aborted_clients`

  El número de conexiones que han sido abortadas debido a que el cliente murió sin cerrar la conexión apropiadamente. Consulte Sección A.2.10, “Errores de comunicación y conexiones abortadas”.

- `Aborted_connects`

  El número de intentos de conexión al servidor MySQL que han fallado. Consulte Sección A.2.10, “Errores de comunicación y conexiones abortadas”.

- `Binlog_cache_disk_use`

  El número de transacciones que han utilizado la cache temporal del registro binario pero han excedido el valor de `binlog_cache_size` y utilizado un archivo temporal para almacenar las sentencias de la transacción.

- `Binlog_cache_use`

  El número de transacciones que han utilizado la cache temporal del registro binario.

- `Bytes_received`

  El número de bytes recibidos desde todos los clientes.

- `Bytes_sent`

  El número de bytes enviados hacia todos los clientes.

- `Com_`xxx``

  Las variables del contador de sentencias `Com_`xxx`` indica el número de veces que cada sentencia `xxx` ha sido ejecutada. Existe una variable de estado por cada tipo de sentencia. Por ejemplo `Com_delete` y `Com_insert` cuentan sentencias `DELETE` and `INSERT`, respectivamente.

  Las variables de estado `Com_stmt_`xxx`` fueron añadidas en 5.0.8:

  - `Com_stmt_prepare`

  - `Com_stmt_execute`

  - `Com_stmt_fetch`

  - `Com_stmt_send_long_data`

  - `Com_stmt_reset`

  - `Com_stmt_close`

  Estas variables representan comandos de sentencias preparadas. Sus nombres se refieren a los comandos `COM_`xxx`` utilizados en la capa de red; en otras palabras: Sus valores son incrementados siempre que las llamadas de la API de sentencias preparadas como mysql_stmt_prepare(), mysql_stmt_execute(), etc. son ejecutadas. Asímismo,`Com_stmt_prepare`, `Com_stmt_execute` y `Com_stmt_close` se incrementan también cuando alguien ejecuta las siguientes sentencias SQL: `PREPARE`, `EXECUTE`, or `DEALLOCATE` respectivamente. `Com_stmt_fetch` representa el número total de comunicaciones de red ejecutadas al recibir datos de los cursores

  Todas las variables `Com_stmt_`xxx`` son incrementadas aunque el argumento de una sentencia preparada sea desconocido u ocurra un error durante la ejecución. Es decir, sus valores corresponden al número de peticiones recibidas, no al número de peticiones completadas con éxito.

- `Connections`

  El número de instentos de conexión (con éxito o no) al servidor MySQL.

- `Created_tmp_disk_tables`

  El número de tablas temporales en disco creadas automáticamente por el servidor mientras ejecutaba sentencias.

- `Created_tmp_files`

  Número de arhcivos temporales que mysqld ha creado.

- `Created_tmp_tables`

  El número de tablas temporales en memoria creadas automáticamente por el servidor mientras ejecuta sentencias. Si `Created_tmp_disk_tables` es grande, quizá querría aumentar el valor de `tmp_table_size` para causar que las tablas sean basadas en memoria en vez de basadas en disco.

- `Delayed_errors`

  El número de registros escritos con `INSERT DELAYED` en los que algún error ocurrió (probablemente `duplicate key`).

- `Delayed_insert_threads`

  El número de hilos gestores de `INSERT DELAYED` en uso.

- `Delayed_writes`

  El número de registros `INSERT DELAYED` escritos

- `Flush_commands`

  El número de comandos `FLUSH` ejecutados.

- `Handler_commit`

  El número de sentencias `COMMIT` internas.

- `Handler_discover`

  El servidor MySQL puede preguntar al motor de almacenamiento `NDB Cluster` si conoce una tabla con un nombre dado. Esto se llama descubrimiento (discovery). `Handler_discover` indica el número de veces que se han descubierto tablas mediante este mecanismo.

- `Handler_delete`

  El número de veces qeu se han borrado registros de tablas.

- `Handler_read_first`

  El número de veces que se lee la primera entrada de un índice. Si este valor es alto, indica que el servidor está haciendo muchos escaneos "full index"; por ejemplo, `SELECT col1 FROM foo`, suponiendo que `col1` está indexada.

- `Handler_read_key`

  El número de peticiones para leer un registro basadas en una clave. Si este número es alto, es una buena indicación de que las consultas y tablas están indexadas adecuadamente.

- `Handler_read_next`

  El número de peticiones para leer el siguiente registro en el orden de la clave. Esto se incrementa cada vez que se está consultando una columna indexada con una restricción de rango, o si se está haciendo un escaneo de índice.

- `Handler_read_prev`

  El número de peticiones para leer el registro previo en el orden de la clave. Este método de lectura es utilizado principalmente para optimizar `ORDER BY ...DESC`.

- `Handler_read_rnd`

  El número de peticiones para leer un registro basándose en una posición fija. Es alto si se están haciendo muchas consultas que requieren ordenación del resultado. Probablemente tenga muchas consultas que requieran que MySQL escanee tablas completas o tiene joins que no utilizan claves adecuadamente.

- `Handler_read_rnd_next`

  El número de peticiones para leer el siguiente registro en el archivo de datos. Éste es alto si está haciendo muchos escaneos de tablas. Generalmente esto sugiere que las tablas no están indexadas adecuadamente o que las consultas no están escritas para obetner ventaja de los índices que se tienen.

- `Handler_rollback`

  El número de sentencias `ROLLBACK` internas.

- `Handler_update`

  El número de peticiones de modificación de un registro en una tabla.

- `Handler_write`

  El número de peticiones de inserción de un registro en una tabla.

- `Innodb_buffer_pool_pages_data`

  El número de páginas que contienen datos (procesados o no). Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_dirty`

  El número de páginas sin procesar. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_flushed`

  El número de páginas del buffer sobre las que se ha hecho una petición de volcado. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_free`

  El número de páginas libres. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_latched`

  El número de páginas bloqueadas en el buffer `InnoDB`. Estas son las páginas que están siendo actualmente leidas o escritas o que no pueden ser volcadas o borradas por alguna otra razón. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_misc`

  El número de páginas ocupadas porque han sido seleccionadas para procesos administrativos, como bloqueos de registro o el índice de hash adaptativo. Este valor puede ser también calculado como `Innodb_buffer_pool_pages_total` - `Innodb_buffer_pool_pages_free` - `Innodb_buffer_pool_pages_data`. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_pages_total`

  Tamaño total del buffer, en páginas. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_read_ahead_rnd`

  El número de lecturas avanzadas ``aleatorias'' que `InnoDB` ha iniciado. Esto pasa cuando una consulta necesita escanear una gran poción de una tabla pero en orden aleatorio. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_read_ahead_seq`

  El número de lecturas avanzadas secuenciales que `InnoDB` ha iniciado. Esto pasa cuando `InnoDB` realiza un escaneo secuencial completo de una tabla. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_read_requests`

  El número de peticiones lógicas de lectura que `InnoDB` ha hecho. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_reads`

  El número de lecturas lógicas del buffer que `InnoDB` no pudo satisfacer y tuvo que hacer una lectura de una única página. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_wait_free`

  Normalmente, las escrituras al buffer de `InnoDB` se llevan acabo en segundo plano. Aún así, si es necesario leer o crear una página y no existe ninguna página vacía disponible, entonces es también necesario esperar a que las páginas sean volcadas previamente. Este contador cuenta las instancias de estas esperas. Si el tamaño del buffer ha sido establecido correctamente, este valor debería ser pequeño. Añadido en MySQL 5.0.2.

- `Innodb_buffer_pool_write_requests`

  El número de escrituras hechas al buffer de `InnoDB`. Añadido en MySQL 5.0.2.

- `Innodb_data_fsyncs`

  El número de operaciones `fsync()` total. Añadido en MySQL 5.0.2.

- `Innodb_data_pending_fsyncs`

  El número de operaciones `fsync()` pendientes. Añadido en MySQL 5.0.2.

- `Innodb_data_pending_reads`

  El número actual de lecturas pendientes. Añadido en MySQL 5.0.2.

- `Innodb_data_pending_writes`

  El número actual de escrituras pendientes. Añadido en MySQL 5.0.2.

- `Innodb_data_read`

  El total de datos leidos, en bytes. Añadido en MySQL 5.0.2.

- `Innodb_data_reads`

  El número total de lecturas de datos. Añadido en MySQL 5.0.2.

- `Innodb_data_writes`

  El número total de escrituras de datos. Añadido en MySQL 5.0.2.

- `Innodb_data_written`

  El total de datos escritos, en bytes. Añadido en MySQL 5.0.2.

- `Innodb_dblwr_writes` , `Innodb_dblwr_pages_written`

  El número de operaciones doublewrite que se han ejecutado y el número de páginas que se han escrito para ello. Añadido en MySQL 5.0.2. Consulte Sección 15.14.1, “E/S de disco (Disk I/O)”.

- `Innodb_log_waits`

  El número de esperas debidas a que el registro del buffer era demasiado pequeño y se tuvo que esperar a que fuese volcado antes de continuar. Añadido en MySQL 5.0.2.

- `Innodb_log_write_requests`

  El número de peticiones de escritura al registro. Añadido en MySQL 5.0.2.

- `Innodb_log_writes`

  El número de escrituras físicas al archivo de registro. Añadido en MySQL 5.0.2.

- `Innodb_os_log_fsyncs`

  El número de escrituras `fsync()` realizadas al archivo de registro. Añadido en MySQL 5.0.2.

- `Innodb_os_log_pending_fsyncs`

  El número de operaciones `fsync()` del archivo de registro. Añadido en MySQL 5.0.2.

- `Innodb_os_log_pending_writes`

  Escrituras del archivo de registro pendientes. Añadido en MySQL 5.0.2.

- `Innodb_os_log_written`

  El número de bytes escritos al archivo de registro. Añadido en MySQL 5.0.2.

- `Innodb_page_size`

  El tamaño de página con que se compiló `InnoDB` (16KB por defecto). Muchos valores son contados en páginas; el tamaño de página permite convertirlos fácilmente a bytes. Añadido en MySQL 5.0.2.

- `Innodb_pages_created`

  El número de páginas creadas. Añadido en MySQL 5.0.2.

- `Innodb_pages_read`

  El número de páginas leidas. Añadido en MySQL 5.0.2.

- `Innodb_pages_written`

  El número de páginas escritas. Añadido en MySQL 5.0.2.

- `Innodb_row_lock_current_waits`

  El número de bloqueos de registro por el que se está esperando. Añadido en MySQL 5.0.3.

- `Innodb_row_lock_time`

  El tiempo total gastado en adquirir bloqueos de registro, en milisegundos. Añadido en MySQL 5.0.3.

- `Innodb_row_lock_time_avg`

  El tiempo medio gastado en adquirir un bloqueo de registro, en milisegundos. Añadido en MySQL 5.0.3.

- `Innodb_row_lock_time_max`

  El tiempo máximo gastado en adquirir un bloqueo de registro, en milisegundos. Añadido en MySQL 5.0.3.

- `Innodb_row_lock_waits`

  El número de veces que se ha tenido que esperar por un bloqueo de registro. Añadido en MySQL 5.0.3.

- `Innodb_rows_deleted`

  El número de registros borrados de tablas `InnoDB`. Añadido en MySQL 5.0.2.

- `Innodb_rows_inserted`

  El número de registros insertados en tablas `InnoDB`. Añadido en MySQL 5.0.2.

- `Innodb_rows_read`

  El número de registros leidos desde tablas `InnoDB`. Añadido en MySQL 5.0.2.

- `Innodb_rows_updated`

  El número de registros actualizados en tablas `InnoDB`. Añadido en MySQL 5.0.2.

- `Key_blocks_not_flushed`

  El número de bloques de claves en la cache de claves que han cambiado pero todavía no han sido volcados a disco.

- `Key_blocks_unused`

  El número de bloques sin utilizar en la cache de claves. Puede utilizar este valor para determinar qué tamaño de la cache de claves está en uso; consulte la discusión de `key_buffer_size` en Sección 5.3.3, “Variables de sistema del servidor”.

- `Key_blocks_used`

  El número de bloques utilizados en la cache de claves. Este valor es una marca de máximo, que indica el número máximo de bloques que han sido nunca utilizados al mismo tiempo.

- `Key_read_requests`

  El número de peticiones para leer un bloque de claves de la cache.

- `Key_reads`

  El número de lecturas físicas de un bloque de claves desde disco. Si `Key_reads` es grande, entonces el valor de `key_buffer_size` es, probablemente, demasiado pequeño. La tasa de fallos de la cache puede ser calculada como `Key_reads`/`Key_read_requests`.

- `Key_write_requests`

  El número de peticiones de escritura de un bloque de claves a la cache.

- `Key_writes`

  El número de escrituras físicas de un bloque de claves a disco.

- `Last_query_cost`

  El coste total de la última consulta compilada tal como ha sido computada por el optimizador de consultas. Es útil para comparar el coste de diferentes planes de ejecución para la misma consulta. El valor por defecto de 0 significa que no se ha compilado ninguna consulta todavía. Esta variable fue añadida en MySQL 5.0.1 con un valor por defecto de -1. En MySQL 5.0.7 el valor por defecto ha cambiado a 0; también en la versión 5.0.7, el ámbito de `Last_query_cost` ha cambiado a sesión en vez de global.

- `Max_used_connections`

  El número máximo de conexiones que han sido utilizadas simultáneamente desde que el servidor ha sido iniciado.

- `Not_flushed_delayed_rows`

  El número de registros esperando a ser escritos en colas de `INSERT DELAY`.

- `Open_files`

  El número de archivos que están abiertos.

- `Open_streams`

  El número de flujos de datos (strems) que están abiertos (utilizados principalmente para el registro).

- `Open_tables`

  El número de tablas que están actualmente abiertas.

- `Opened_tables`

  El número de tablas que han sido abiertas. Si `Opened_tables` es grande, probablemente el valor de `table_cache` es demasiado pequeño.

- `Qcache_free_blocks`

  El número de bloques de memoria libres en la cache de consultas.

- `Qcache_free_memory`

  El total de memoria libre en la cache de consultas.

- `Qcache_hits`

  El número de éxitos de la cache.

- `Qcache_inserts`

  El número de consultas añadidas a la cache.

- `Qcache_lowmem_prunes`

  El número de consultas que fueron borradas de la cache de consultas debido a baja memoria.

- `Qcache_not_cached`

  El número de consultas que no han entrado en la cache (por no ser "cacheables", o debido al parámetro `query_cache_type`).

- `Qcache_queries_in_cache`

  El número de consultas registradas en la cache.

- `Qcache_total_blocks`

  El número total de bloques en la cache de consultas.

- `Questions`

  El número de consultas que han sido enviadas al servidor.

- `Rpl_status`

  El estado de la replicación a prueba de fallos (todavía no implementado).

- `Select_full_join`

  El número de joins que no utilizan índices. Si este valor no es 0, debería comprobar cuidadosamente los índices de sus tablas.

- `Select_full_range_join`

  El número de joins que han utilizado una búsqueda por rango en una tabla de referencia.

- `Select_range`

  El número de joins que han usado rangos en la primera table. Normalmente no es algo crítico aunque pueda ser bastante grande.

- `Select_range_check`

  El número de joins sin claves que comprueban la utilización de claves después de cada registro. Si esto no es cero, debería comprobar cuidadosamente los índices de sus tablas.

- `Select_scan`

  El número de joins que han hecho un escaneo total de la primera tabla.

- `Slave_open_temp_tables`

  El número de tablas temporales abiertas actualmente por el subproceso SQL esclavo.

- `Slave_running`

  Este valor es `ON` si el servidor es un esclavo que está conectado a un servidor maestro.

- `Slave_retried_transactions`

  Número total de veces desde el inicio que el subproceso SQL esclavo de replicación ha intentando alguna transacción. Para la serie de MySQL 5.0, esta variable fue añadida en la versión 5.0.4.

- `Slow_launch_threads`

  El número de subprocesos que han tardado en crearse más de `slow_launch_time` segundos.

- `Slow_queries`

  El número de consultas que han tardado más de `long_query_time` segundos. Consulte Sección 5.10.4, “El registro de consultas lentas (Slow Query Log)”.

- `Sort_merge_passes`

  El número de pasadas que el algoritmo de ordenación ha tenido que hacer. Si este valor es grande, debería considerar incrementar el valor de la variable de sistema`sort_buffer_size`

- `Sort_range`

  El número de ordenaciones que fueron realizadas utilizando rangos.

- `Sort_rows`

  El número de registros ordenados.

- `Sort_scan`

  El número de ordenaciones que fueron hechas escaneando la tabla.

- `Ssl_`xxx``

  Variables utilizadas para conexiones SSL.

- `Table_locks_immediate`

  El número de veces que un bloque de tabla ha sido adquirido inmediatamente.

- `Table_locks_waited`

  El número de veces que un bloque de tabla no se ha podido adquirir inmediatamente y se ha necesitado una espera. Si esto es alto, y tiene problemas de rendimiento, debería primero optimizar sus consultas y después, o bien utilizar replicación, o dividir sus tablas.

- `Threads_cached`

  El número de subprocesos en la cache de subprocesos.

- `Threads_connected`

  El número de conexiones abiertas actualmente.

- `Threads_created`

  El número de subprocesos creados para gestionar conexiones. Si `Threads_created` es grande, debería incrementar el valor de `thread_cache_size`. La tasa de éxitos de la cache puede ser calculada como `Threads_created`/`Connections`.

- `Threads_running`

  El número de subprocesos que no están durmiendo.

- `Uptime`

  El número de segundos que el servidor ha estado funcionando ininterrumpidamente.

## 5.4. El proceso de cierre del servidor MySQL

Los pasos del proceso de apagado del servidor son:

1. Comienza el proceso de apagado

2. El servidor crea un subproceso de apagado si es necesario

3. El servidor deja de aceptar nuevas conexiones

4. El servidor acaba con su tarea actual

5. Se apagan o cierran los motores de almacenamiento

6. El servidor se cierra

Seguidamente, una descripción más detallada del proceso:

1. Comienza el proceso de apagado.

   El apagado del servidor puede iniciarse de diferentes maneras. Por ejemplo, un usuario con el privilegio `SHUTDOWN` puede ejecutar la orden mysqladmin shutdown. mysqladmin puede ser utilizado en cualquier plataforma soportada por MySQL. También son posibles otros métodos de encendido y apagado específicos de cada sistema operativo: El servidor se apaga en Unix cuando recibe una señal `SIGTERM`. Un servidor ejecutándose como servicio en Windows se apaga cuando el administrador de servicios se lo indica.

2. El servidor crea un subproceso de apagado si es necesario.

   Dependiendo de como se ha iniciado el apagado, el servidor puede crear un subproceso para llevar a cabo el proceso de apagado. Si el apagado fue demandado por un cliente, se crea un subproceso de apagado. Si el apagado es debido a la recepción de una señal `SIGTERM`, el subproceso de la señal podría llevar a cabo el apagado él mismo, o podría crear un subproceso separado para hacerlo. Si el servidor intenta crear un subproceso de apagado y no puede hacerlo (por ejemplo, porque no hay memoria suficiente disponible), crea un mensaje de diagnóstico que aparece en el registro de errores:

       Error: Can't create thread to kill server

3. El servidor deja de aceptar nuevas conexiones.

   Para prevenir que comiencen nuevas actividades durante el apagado, el servidor deja de aceptar nuevas conexiones de clientes. Esto lo consigue cerrando las conexiones de red a las que normalmente escucha: el puerto TCP/IP, el archivo socket Unix, la "named pipe" de Windows, y la memoria compartida de Windows.

4. El servidor acaba con su tarea actual.

   En cada subproceso asociado a una conexión de un cliente, se rompe la conexión al cliente, y dicho subproceso es marcado como muerto. Los subprocesos mueren cuando se dan cuenta de que han sido marcados de esa manera. Los subprocesos de conexiones inactivas mueren rápidamente. Los que están actualmente procesando sentencias, consultan periodicamente su estado y tardan un poco más en morir. Para encontrar información adicional sobre la terminación de subprocesos, consulte Sección 13.5.5.3, “Sintaxis de `KILL`”, en particular las instrucciones sobre las operaciones `REPAIR TABLE` o `OPTIMIZE TABLE` que han sido matadas en tablas `MyISAM`.

   En los subprocesos que tienen abierta una transacción, la transacción se cancela. Nótese qeu si un subproceso está actualizando una tabla no transaccional, una operación como un `UPDATE` o `INSERT` de múltiples registros podría dejar la tabla parcialmente actualizada, porque la operación puede terminar antes de ser completada.

   Si el servidor es un servidor maestro de replicación, los subprocesos asociados a esclavos todavía conectados son tratados como subprocesos de cualquier otro cliente. Es decir, cada uno es marcado como muerto y se cierra la próxima vez que éste comprueba su estado.

   Si el servidor es un servidor esclavo de replicación, los subprocesos de Entrada/Salida y SQL se paran, si están activos, antes de que los subprocesos de cliente sean marcados como muertos. Se permite al subproceso SQL finalizar su sentencia actual (para evitar causar problemas de replicación), y entonces se para. Si el subproceso SQL estaba en medio de una transacción en ese momento, la transacción se cancela.

5. Se apagan o cierran los motores de almacenamiento.

   En este punto, la cache de tabla se escribe a disco y se cierran todas las tablas abiertas.

   Cada motor de almacenamiento realiza todas las acciones necesarias para las tablas que controla. Por ejemplo, MyISAM realiza cualquier escritura de índices pendiente de una tabla. InnoDB escribe sus buffers a disco (desde la versión 5.0.5: a menos que `innodb_fast_shutdown` valga 2), escribe el número de secuencia de registro (LSN - Log Sequence Number) en el espacio de tablas, y cierra sus propios subprocesos internos.

6. El servidor se cierra.

## 5.5. Cuestiones de seguridad general

Esta sección describe algunos temas generales de seguridad que hay que tener en cuenta, y qué se puede hacer para aumentar la seguridad de la instalación MySQL contra ataques o errores de uso. Para encontrar información específica sobre el sistema de control de accesos que MySQL utiliza para crear cuentas de usuarios y comprobar el acceso a las bases de datos, consulte Sección 5.6, “El sistema de privilegios de acceso de MySQL”.

### 5.5.1. Guía de seguridad general

Cualquiera que utilice MySQL en un ordenador conectado a Internet debería leer esta sección para evitar los errores de seguridad más comunes.

Al tratar el tema de la seguridad, hacemos hincapié en la necesidad de proteger totalmente la máquina completa (no únicamente el servidor MySQL) contra todos los tipos de ataques posibles; intercepción pasiva de paquetes, alteración, reproducción de comandos (playback), y denegación de servicio. Aquí no tratamos todos los aspectos de disponibilidad y tolerancia a fallos.

Para todas las conexiones, consultas, y otras operaciones que los usuarios pueden intentar realizar, MySQL utiliza seguridad basada en Listas de Control de Acceso (ACLs). También hay algún soporte para conexiones cifradas mediante SSL entre clientes y servidores MySQL. Muchos de los conceptos que aquí se exponen no son específicos de MySQL; las mismas ideas generales se pueden aplicar a cualquier aplicación.

Al ejecutar MySQL, siga siempre que sea posible estas recomendaciones:

- ¡No de nunca a nadie (excepto a la cuenta `root` de MySQL acceso a la tabla `user` en la base de datos `mysql`! Esto es crítico. La clave cifrada es la verdadera clave en MySQL. Cualquiera que sepa cual es la clave que hay en la tabla `user` y tenga acceso a la máquina host de la cuenta registrada puede acceder fácilmente como ese usuario.

- Estudie el sistema de privilegios de acceso de MySQL. Las sentencias `GRANT` y `REVOKE` se utilizan para controlar el acceso a MySQL. No otorgue más privilegios de los necesarios. Nunca otorgue privilegios a un mismo usuario sin tener en cuenta el equipo desde el que se conecta.

  Lista de comprobaciones:

  - Pruebe el comando `mysql -u root`. Si es capaz de conectar al servidor sin la necesidad de introducir una clave, tiene problemas. ¡Cualquiera puede conectar a su servidor MySQL como el usuario `root` de MySQL con privilegios totales! Revise las instrucciones de instalación de MySQL, prestando atención en concreto a la información sobre establecer una clave para el usuario `root`. Consulte Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”.

  - Utilice la sentencia `SHOW GRANTS` y compruebe quién tiene acceso a qué. Después utilice la sentencia `REVOKE` para denegar los privilegios que no son necesarios.

- No almacene ninguna clave sin cifrar en su base de datos. Si alguien tuviera acceso a su ordenador, el intruso podría obtener la lista completa de claves y utilizarlas. En vez de eso, utilice `MD5()`, `SHA1()`, o cualquier otra función de hashing de un sentido.

- No elija claves que puedan aparecer en un diccionario. Existen programas especiales para romperlas. Incluso claves como ``xperro98'' son muy malas. Es mucho mejor ``oweei98'', que contiene la misma palabra ``perro'' pero escrita desplazándose una tecla a la izquierda en un teclado QWERTY convencional. Otro método es usar ``Mtupc'', que ha sido tomada de las primeras letras de cada palabra de la frase ``María tuvo un pequeño corderito.'' Así es fácil de recordar y escribir, pero difícil de adivinar para cualquiera que no la conozca.

- Invierta en un firewall. Le protegerá de al menos el 50% de todos los tipos de vulnerabilidades de cualquier software. Ponga MySQL tras el firewall o en una zona desmilitarizada (DMZ).

  Lista de comprobaciones:

  - Intente escanear sus puertos desde Internet utilizando una herramienta como `nmap`. MySQL utiliza el puerto 3306 por defecto. Este puerto no debería ser accesible desde lugares no confiables. Otra manera simple de probar si el puerte MySQL está abierto o no es intentar el siguiente comando desde alguna máquina remota, donde `server_host` es la máquina en la que su servidor MySQL se está ejecutando:

        shell> telnet server_host 3306

    Si consigue conectar y algunos carácteres extraños, el puerto está abierto, y debería cerrarlo en su firewall o router, a menos que tenga una buena razón para mantenerlo abierto. Si el comando `telnet` no consigue conectar o la conexión es rechazada, entonces el puerto se encuentra bloqueado, que es como queremos que esté.

- No confíe en ningún dato enviado por los usuarios de sus aplicaciones. Pueden intentar engañar a su código introduciendo secuencias de carácteres especiales en formularios webs, URLs, o cualquier aplicación que haya desarrollado. Asegúrese de que su aplicación permance segura si un usuario introduce algo como ```; DROP DATABASE mysql;`''. Este es un ejemplo algo extremo, pero los mayores agujeros de seguridad y pérdidas de datos pueden ocurrir como resultado de hackers utilizando técnicas similares, si no se está preparado para ellas.

  Un error común es proteger únicamente valores de tipo cadena de carácteres. Recuerde comprobar los datos numéricos también. Si una aplicación genera una consulta como `SELECT * FROM table WHERE ID=234` cuando un usuario introduce el valor `234`, el usuario podría introducir el valor `234 OR 1=1` para provocar que la aplicación genere la consulta `SELECT * FROM table WHERE ID=234 OR 1=1`. Como resultado, el servidor extraerá todos los registros en la tabla. Esto, además de exponer cada registro, causa una carga excesiva en el servidor. La manera más simple de protegerse frente a este tipo de ataque es utilizar comillas simples alrededor de las constantes numéricas: `SELECT * FROM table WHERE ID='234'`. Si el usuario entrase información extra, todo sería parte de la cadena de carácteres. En un contexto numérico, MySQL automáticamente convierte esta cadena en un número, y elimina cualquier carácter no númerico del final que la cadena pueda contener.

  A veces la gente piensa que si una base de datos contiene sólo datos de dominio público, no tiene por qué ser protegida. Esto es incorrecto. Aunque sea admitible mostrar cualquier registro de la base de datos, siempre se debería proteger contra ataques de tipo denegación de servicio (por ejemplo, aquellos que se basan en la técnica del párrafo precedente, que causan que el servidor malgaste recursos). Si no, el servidor podría quedar inservible para sus usuarios legítimos.

  Lista de comprobaciones:

  - Intente introducir comillas simples y dobles ('`'`' y '`"`') en todos sus formularios web. Si obtiene cualquier clase de error MySQL, investigue el problema sin demora.

  - Intente modificar las URLs dinámicas añadiendo las cadenas `%22` ('`"`'), `%23` ('`#`'), y `%27` ('`'`').

  - Intente modificar los tipos de datos en las URLs dinámicas de tipos numéricos a alfanuméricos, usando los caracteres mostrados en los ejemplos previos. Su aplicaicón debería ser segura contra estos y otros ataques similares.

  - Intente introducir letras, espacios, y símbolos especiales en vez de números en los campos numeicos. Su aplicación debería eliminarlos antes de pasarlos a MySQL, o en todo caso generar un error. ¡Pasar valores sin comprobar a MySQL es muy peligroso!

  - Compruebe el tamaño de los datos antes de pasárselos a MySQL.

  - Haga que su aplicación se conecte a la base de datos utilizando un nombre de usuario diferente del que utiliza para tareas administrativas. No dé a sus aplicaciones ningún acceso que no necesiten.

- Muchas interfaces de programación de aplicaciones proveen alguna manera de preceder con carácteres de escape los caracteres especiales en sus datos. Usados adecuadamente, esto previene que los usuarios de las aplicaciones introduzcan valores que provoquen que la aplicación genere sentencias con efectos diferentes a los que usted pretendía:

  - API MySQL de C: Utilice la función `mysql_real_escape_string()`.

  - MySQL++: Utilice los modificadores `escape` y `quote` para streams

  - PHP: Utilice la función `mysql_escape_string()`, que está basada en la función del mismo nombre de la API MySQL de C. (Con versiones anteriores a PHP 4.0.3, utilice `addslashes()` en cambio.) En PHP 5, puede utilizar la extensión `mysqli`, que soporta los protocolo de autentificación y clave de acceso mejorados de MySQL, así como las sentencias preparadas con placeholders.

  - DBI de Perl: Utilice el método `quote()` o utilice placeholders.

  - JDBC de Java: Utilice un objeto `PreparedStatement` y placeholders.

  Otras interfaces de programación deberían tener capacidades similares.

- No transmita datos sin cifrar por Internet. Esta información es accesible para cualquiera que tenga el tiempo y la habilidad para interceptarla y utilizarla para sus propios propósitos. En vez de eso, utilice un protocolo de cifrado como SSL o SSH. MySQL soporta conexiones SSL internas desde la versión 4.0.0. El redireccionamiento de puertos de SSH se puede utilizar para crear un tunel cifrado (y comprimido) para la comunicación.

- Aprenda a utilizar las herramientas `tcpdump` y `strings`. En la mayoría de los casos, usted puede comprobar si los flujos de datos de MySQL están cifrados ejecutando un comando como el siguiente:

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

  (Esto funciona en Linux, y debería funcionar, con pequeñas modificaciones en otros sistemas.) Atención: Si no ve los datos en formato de texto, esto no siempre quiere decir que la información esté realmente cifrada. Si necesita un alto nivel de seguridad, debería consultar a un experto en la materia.

### 5.5.2. Hacer que MySQL sea seguro contra ataques

Cuando se conecta a un servidor MySQL, debería utilizar una clave. La clave no se transmite en texto llano a través de la conexión. El tratamiento de las claves durante la conexión de un cliente ha sido mejorado en MySQL 4.1.1 para ser muy seguro. Si todavía está utilizando claves del tipo anterior a 4.1.1, el algoritmo de cifrado no es tan potente como el nuevo algoritmo; con un poco de esfuerzo un atacante inteligente que pueda interceptar el tráfico entre el cliente y el servidor podría romper la clave. (Consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1” para una explicación sobre los diferentes métodos de tratamiento de claves.) Si la conexión entre el cliente y el servidor pasa a través de una red no segura, debería utilizar un tunel SSH para cifrar la comunicación.

Toda la demás información se transmite como texto, y puede ser leida por cualquiera que pueda observar la conexión. Si esto le preocupa, utilice el protocolo comprimido para hacer que el tráfico sea mucho más difícil de descifrar. Para hacer la conexión aún más segura, debería utilizar SSH para conseguir una conexión TCP/IP cifrada entre el servidor MySQL y el cliente MySQL. Puede encontrar un cliente SSH Open Source en http://www.openssh.org/, y un cliente comercial en http://www.ssh.com/.

En MySQL 5.0, puede utilizar también el soporte interno de OpenSSL. Consulte Sección 5.7.7, “Usar conexiones seguras”.

Para convertir un sistema MySQL en seguro, debería considerar seriamente las siguientes sugerencias:

- Utilice claves para todos los usuarios MySQL. Un programa cliente no conoce necesariamente la identidad de la persona utilizándolo. Es común en las aplicaciones cliente/servidor que el usuario pueda especificar cualquier nombre de usuario al programa cliente. Por ejemplo, cualquiera puede utilizar el programa mysql para conectarse como cualquier otra persona, simplemente invocándolo de la siguiente manera: `mysql -u `otro_usuario` `nombre_bd`` cuando `otro_usuario` no tiene clave. Si todos los usuarios tienen una clave, conectarse utilizando la cuenta de otro usuario se vuelve mucho más difícil.

  Para cambiar la clave de un usuario, utilice la sentencia `SET PASSWORD`. También es posible alterar la tabla `user` en la base de datos `mysql` directamente. Por ejemplo, para cambiar la clave de todas las cuentas MySQL que tienen por nombre de usuario `root`, haga lo siguiente:

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

- Nunca ejecute el servidor MySQL con el usuario `root` de Unix. Esto es extremadamente peligroso porque cualquier usuario con el privilegio `FILE` es capaz de crar ficheros como `root` (por ejemplo, `~root/.bashrc`). Para prevenir esto, mysqld rechaza ejecutarse como `root` a menos que se utilice explícitamente la opción `--user=root`.

  En vez de eso, mysqld puede (y debe) ser ejecutado mediante un usuario normal sin privilegios. Puede crear una cuenta de Unix específica llamada `mysql` para hacelo todo aún más seguro. Utilice esta cuenta tan solo para administrar MySQL. Para ejecutar mysqld mediante un usuario de Unix diferente, añada la opción `user` que especifica el nombre de usuario al grupo `[mysqld]` del fichero de opciones `/etc/my.cnf` o al fichero de opciones `my.cnf` en el directorio de datos del servidor. Por ejemplo:

      [mysqld]
      user=mysql

  Esto provoca que el servidor se inicie mediante el usuario designado, lo ejecute usted manualmente o mediante mysqld_safe o mysql.server. Para más detalles, consulte Sección A.3.2, “Cómo ejecutar MySQL como usuario normal”.

  Ejecutar mysqld como un usuario Unix diferente de `root` no significa que necesite cambiar el usuario `root` de la tabla `user`. Los usuarios de las cuentas MySQL no tienen nada que ver con los usuarios de las cuentas Unix.

- No permita el uso de enlaces simbólicos a tablas. (Esto puede desactivarse con la opción `--skip-symbolic-links`.) Esto es especialmente importante si ejecuta mysqld como `root`, porque cualquiera que tenga acceso de escritura al directorio de datos del servidor ¡podría entonces borrar cualquier fichero en el sistema!. Consulte Sección 7.6.1.2, “Utilización de enlaces simbólicos para tablas en Unix”.

- Asegúrese de que el único usuario Unix con permisos de lectura o escritura en los directorios de la base de datos es el usuario que ejecuta mysqld.

- No otorgue los privilegios `PROCESS` o `SUPER` a usuarios no-administrativos. La salida del de mysqladmin processlist muestra el texto de cualquier sentencia que se esté ejecutando, así que cualquier usuario al que se permita ejecutar ese comando puede ser capaz de ver si otro usuario ejecuta una sentencia `UPDATE user SET password=PASSWORD('not_secure')`.

  mysqld reserva una conexión extra para usuarios que tengan el privlegio `SUPER`, así que un usuario `root` puede conectarse y comprobar la actividad del servidor aún cuando todas las conexiones normales estén en uso.

  El privilegio `SUPER` puede utilizarse para cerrar conexiones de cliente, cambiar el funcionamiento del servidor modificando el valor de variables del sistema, y controlar servidores de replicación.

- No otorgue el privilegio `FILE` a usuarios no-administrativos. Cualquier usuario que posea este privilegio puede escribir un archivo en cualquier de lugar del sistema de ficheros con los privilegios del demonio mysqld. Para hacer esto un poco más seguro, los archivos generados con `SELECT ... INTO OUTFILE` no sobreescriben archivos existentes, y pueden ser escritos por cualquiera.

  El privilegio `FILE` puede también ser utilizado para leer cualquier archivos que sea legible por cualquiera o accesible para el usuario Unix que ejecuta el servidor. Con este privilegio, podría por ejemplo leer cualquier fichero e insertarlo en una tabla de la base de datos. Esto podría utilizarse, por ejemplo, utilizando `LOAD DATA` para cargar `/etc/passwd` en una tabla, que podría ser mostrada después con un `SELECT`.

- Si no confía en sus DNS, podría utilizar números IP en vez de nombres en las tablas de permisos (tablas grant). En cualquier caso, debería ser muy cuidadoso en crear registros en las tablas de permiso utilizando nombres que contengan carácteres comodín.

- Si quiere restringir el número de conexiones permitidas para una misma cuenta, puede hacerlo estableciando la variable `max_user_connections` de mysqld. La sentencia `GRANT` también soporta opciones de control de recursos para limitar la extensión de uso de servidor permitido a una cuenta. Consulte Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

### 5.5.3. Opciones de arranque para mysqld relacionadas con la seguridad

Las siguientes opciones de mysqld afectan a la seguridad:

- `--allow-suspicious-udfs`

  Esta opción cotrola si las funciones definidas por el usuario que sólo tienen un símbolo `xxx` para la función principal se pueden cargar. Por defecto, la opción está desactivada y sólo UDFs que tengan al menos un símbolo auxiliar pueden cargarse. Esto previene intentos de cargar funciones desde ficheros objeto compartidos que no contegan UDFs legítimos. Para MySQL 5.0, esta opción se añadió en MySQL 5.0.3. Consulte Sección 27.2.3.6, “Precauciones de seguridad en funciones definidas por usuarios”.

- `--local-infile[={0|1}]`

  Si arranca el servidor con `--local-infile=0`, los clientes no pueden usar `LOCAL` en comandos `LOAD DATA` . Consulte Sección 5.5.4, “Cuestiones relacionadas con la seguridad y `LOAD DATA LOCAL`”.

- `--old-passwords`

  Fuerza al servidor a generar hashes de contraseñas cortos (pre-4.1) para las nuevas contraseñas. Esto es útil para compatibilidad cuando el servidor debe soportar antiguos programas cliente. Consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1”.

- (OBSOLETO) `--safe-show-database`

  En versiones previas de MySQL, esta opción provoca que el comando `SHOW DATABASES` muestre los nombers de sólo aquellas bases de datos para las que el usuario tiene algún tipo de privilegio. En MySQL 5.0, esta opción no está disponible ya que es el comportamiento por defecto, y hay un privilegio `SHOW DATABASES` que puede usarse para controlar el acceso a los nombres de las bases de datos para cada cuenta. Consulte Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

- `--safe-user-create`

  Si está activada, un usuario no puede crear nuevos usuarios con el comando `GRANT` a no ser que el usuario tenga el privilegio `INSERT` para la tabla `mysql.user` . Si desea que un usuario tenga la habilidad de crear nuevos usuarios con los privilegios que el usuario tiene derecho a otorgar, debe otorgar al usuario el siguiente privilegio:

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

  Esto asegura que el usuario no pueda cambiar ninguna columna de privilegios directamente, pero debe usar el comando `GRANT` para dar privilegios a otros usuarios.

- `--secure-auth`

  Desactiva autenticación para cuentas que usen antiguas contraseñas (pre-4.1)

- `--skip-grant-tables`

  Esta opción hace que el servidor no use el sistema de privilegios en absoluto. Esto da a todo el mundo acceso total a todas las bases de datos! (Puede decirle a un servidor en ejecución que arranque usando las tablas de permisos de nuevo usando mysqladmin flush-privileges o el comando mysqladmin reload, o mediante el comando `FLUSH PRIVILEGES`.)

- `--skip-name-resolve`

  Los nombres de equipo no se resuelven. Todo valor en la columna `Host` en la tabla de permisos deben ser números IP o `localhost`.

- `--skip-networking`

  No permite conexiones TCP/IP a través de la red. Todas las conexiones a mysqld se realizan mediante ficheros socket de Unix.

- `--skip-show-database`

  Con esta opción, el comando `SHOW DATABASES` se permite sólo a usuarios que tengan el privilegio `SHOW DATABASES` , y el comando muestra todos los nombres de bases de datos. Sin esta opción , `SHOW DATABASES` está permitido a todos los usuarios, pero muestra cada nombre de base de datos sólo si el usuario tiene el privilegio `SHOW DATABASES` o algún privilegio para la base de datos.

### 5.5.4. Cuestiones relacionadas con la seguridad y `LOAD DATA LOCAL`

El comando `LOAD DATA` puede cargar un fichero que esté localizado en el equipo servidor, o puede cargar un fichero localizado en el equipo cliente cuando se especifica la palabra clave `LOCAL`.

Hay dos aspectos de seguridad potenciales al soportar la versión `LOCAL` de los comandos `LOAD DATA`:

- La transferencia del fichero desde el equipo cliente al equipo servidor se inicia mediante el servidor MySQL. En teoría, puede construirse un servidor modificado de forma que le diga al programa cliente que transfiera un fichero elegido por el servidor en lugar de el fichero especificado por el cliente en el comando `LOAD DATA` . Tal servidor podría acceder a cualquier fichero en el equipo cliente al que el usuario cliente tuviese acceso de lectura.

- En un entorno Web en el que los clientes se conecten mediante un servidor Web, un usuario podría usar `LOAD DATA LOCAL` para leer cualquier fichero al que el servidor Web tuviese acceso de lectura (asumiendo que el usuario puediese ejecutar cualquier comando contra el servidor SQL). En este entorno, el cliente respecto al servidor MySQL es el servidor Web, no el programa ejectuado por el usuario para conectar al servidor Web.

Para tratar estos problemas, hemos cambiado el funcionamiento de `LOAD DATA LOCAL` en MySQL 3.23.49 y MySQL 4.0.2 (4.0.13 en Windows):

- Por defecto, todos los clientes MySQL y bibliotecas en distribuciones binarias se compilan con la opción `--enable-local-infile` para ser compatible con la versión MySQL 3.23.48 y anteriores.

- Si compila MySQL de los ficheros fuentes pero no usa la opción `--enable-local-infile` para configure, `LOAD DATA LOCAL` no puede usarse por ningún cliente a no ser que se escriba explícitamente para invocar `mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0)`. Consulte Sección 24.3.3.44, “`mysql_options()`”.

- Puede desactivar todos los comandos `LOAD DATA LOCAL` desde el lado del servidor arrancando mysqld con la opción `--local-infile=0`.

- Para el cliente de línea de comando mysql, `LOAD DATA LOCAL` puede activarse especificando la opción `--local-infile[=1]` , o deshabilitarse con la opción `--local-infile=0` . De forma similar, para mysqlimport, las opciones `--local` o `-L` permite la carga de datos locales. En cualquier caso, el uso exitoso de una operación de carga local requiere que el servidor lo permita.

- Si usa `LOAD DATA LOCAL` en scripts de Perl scripts u otros programsa que lean del grupo `[client]` en los ficheros de opciones, puede añadir la opción `local-infile=1` a ese grupo. De todos modos, para evitar que esto cause problemas en programas que no entiendan `local-infile`, especifíquelo usando el prefijo `loose-` :

      [client]
      loose-local-infile=1

- Si `LOAD DATA LOCAL INFILE` está desactivado, tanto en el servidor o el cliente, un cliente que trate de ejecutar dicho comando recibe el siguiente mensaje de error:

      ERROR 1148: The used command is not allowed with this MySQL version

## 5.6. El sistema de privilegios de acceso de MySQL

MySQL tiene un sistema avanzado pero no estándard de seguridad y privilegios. Esta sección describe su funcionamiento.

### 5.6.1. Qué hace el sistema de privilegios

La función primaria del sistema de privilegios de MySQL es autenticar un usuario conectándose desde un equipo dado, y asociar dicho usuario con privilegios en una base de datos tales como `SELECT`, `INSERT`, `UPDATE`, y `DELETE`.

Funcionalidad adicional incluye la habilidad de tener usuarios anónimos y de dar privilegios para funciones específicas de MySQL tales como `LOAD DATA INFILE` y operaciones administrativas.

### 5.6.2. Cómo funciona el sistema de privilegios

El sistema de privilegios de MySQL asegura que todos los usuarios pueden ejecutar sólo la operación permitida a los mismos. Como usuario, cuando conecta a un servidor MySQL, su identidad se determina mediante el equipo desde el que se conecta y el nombre de usuario que especifique. Cuando efectúe peticiones tras conectar, el sistema le otorga privilegios acorde a su identidad y lo que quiera hacer.

MySQL considera tanto su nombre de usuario y su equipo a la hora de identificarle, ya que no hay razón para asumir que un nombre de usuario pertenece a la misma persona en cualquier sitio de Internet. Por ejemplo, el usuario `joe` que conecta desde `office.com` no tiene porqué ser la misma persona que el usuario `joe` que conecta desde `elsewhere.com`. MySQL trata esto permitiendole distinguir usuarios en diferentes equipos que tienen el mismo nombre. Puede otorgar un conjunto de privilegios para conexiones de `joe` desde `office.com`, y un conjunto distinto para conexiones de `joe` desde `elsewhere.com`.

El control de acceso de MySQL implica dos etapas:

- Etapa 1: El servidor comprueba si debe permitirle conectarse.

- Etapa 2: Asumiendo que se conecta, el servidor comprueba cada comando que ejecuta para ver si tiene suficientes permisos para hacerlo. Por ejemplo, si intenta seleccionar registros de una tabla en una base de datos o eliminar una tabla de la base de datos, el servidor verifica que tenga el permiso `SELECT` para la tabla o el permiso `DROP` para la base de datos.

Si sus permisos cambian (por usted mismo o alguien distinto) mientras está conectado, estos cambios no tienen porqué tener efecto inmediatamente para el siguiente comando que ejecute. Consulte Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios” para más detalles.

El servidor guarda información de privilegios en las tablas de permisos de la base de datos `mysql` (esto es, en la base de datos llamada `mysql`). El servidor MySQL lee el contenido de dichas tablas en memoria cuando arranca y las vuelve a leer bajo las circunstancias indicadas en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”. Las decisiones acerca de control de acceso se basan en las copias en memoria de las tablas de permisos.

Normalmente, manipula los contenidos de las tablas de permisos indirectamente usando los comandos `GRANT` y `REVOKE` para configurar cuentas y controlar los privilegios disponibles para cada una. Consulte Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”. La discusión aquí describe la estructura subyacente de las tablas de permisos y cómo el servidor usa sus contenidos cuando interactúa con clientes.

El servidor usa las tablas `user`, `db`, y `host` en la base de datos `mysql` en ambas etapas de control de acceso. Las columnas en estas tablas de permisos se muestran a continuación:

Nombre tabla | user | db | host
Alcance columnas | `Host` | `Host` | `Host`
| `User` | `Db` | `Db`
| `Password` | `User` |
Columnas privilegios | `Select_priv` | `Select_priv` | `Select_priv`
| `Insert_priv` | `Insert_priv` | `Insert_priv`
| `Update_priv` | `Update_priv` | `Update_priv`
| `Delete_priv` | `Delete_priv` | `Delete_priv`
| `Index_priv` | `Index_priv` | `Index_priv`
| `Alter_priv` | `Alter_priv` | `Alter_priv`
| `Create_priv` | `Create_priv` | `Create_priv`
| `Drop_priv` | `Drop_priv` | `Drop_priv`
| `Grant_priv` | `Grant_priv` | `Grant_priv`
| `Create_view_priv` | `Create_view_priv` | `Create_view_priv`
| `Show_view_priv` | `Show_view_priv` | `Show_view_priv`
| `Create_routine_priv` | `Create_routine_priv` |
| `Alter_routine_priv` | `Alter_routine_priv` |
| `References_priv` | `References_priv` | `References_priv`
| `Reload_priv` |  |
| `Shutdown_priv` |  |
| `Process_priv` |  |
| `File_priv` |  |
| `Show_db_priv` |  |
| `Super_priv` |  |
| `Create_tmp_table_priv` | `Create_tmp_table_priv` | `Create_tmp_table_priv`
| `Lock_tables_priv` | `Lock_tables_priv` | `Lock_tables_priv`
| `Execute_priv` |  |
| `Repl_slave_priv` |  |
| `Repl_client_priv` |  |
Columnas seguridad | `ssl_type` |  |
| `ssl_cipher` |  |
| `x509_issuer` |  |
| `x509_subject` |  |
Columnas recursos control | `max_questions` |  |
| `max_updates` |  |
| `max_connections` |  |
| `max_user_connections` |  |

`Execute_priv` se presentó en MySQL 5.0.0, pero no fue operacional hasta MySQL 5.0.3.

Las columnas `Create_view_priv` y `Show_view_priv` se añadieron en MySQL 5.0.1.

Las columnas `Create_routine_priv`, `Alter_routine_priv`, y `max_user_connections` se añadieron en MySQL 5.0.3.

Durante la segunda etapa de control de acceso, el servidor efectúa una verificación de petición para asegurar que cada cliente tiene suficientes privilegios para cada petición que recibe. Adicionalmente las tablas de permisos `user`, `db`, y `host` , el servidor puede consultar las tablas `tables_priv` y `columns_priv` para peticiones que impliquen tablas. Las tablas `tables_priv` y `columns_priv` proveen de un control de privilegios más fino a nivel de tabla y columna. Tienen las siguientes columnas:

Nombre tabla | tables_priv | columns_priv
Alcance de columnas | `Host` | `Host`
| `Db` | `Db`
| `User` | `User`
| `Table_name` | `Table_name`
|  | `Column_name`
Columnas privilegios | `Table_priv` | `Column_priv`
| `Column_priv` |
Otras columnas | `Timestamp` | `Timestamp`
| `Grantor` |

Las columnas `Timestamp` y `Grantor` actualmente no se usan y no se discuten más en esta sección.

Para verificación de peticiones que impliquen rutinas almacenadas, el servidor puede consultar la tabla `procs_priv`. Esta tabla tiene las siguientes columnas:

Nombre tabla | procs_priv
Alcance de columnas | `Host`
| `Db`
| `User`
| `Routine_name`
| `Routine_type`
Columnas privilegios | `Proc_priv`
Otras columnas | `Timestamp`
| `Grantor`

La tabla `procs_priv` existe desde MySQL 5.0.3. La columna `Routine_type` se añadió en MySQL 5.0.6. Hay una columna `ENUM` con valores de `'FUNCTION'` o `'PROCEDURE'` para indicar el tipo de rutina a que se refiere el registro. Esta columna permite que los privilegios se otorgen separadamente para una función y para un procedimiento con el mismo nombre.

Las columnas `Timestamp` y `Grantor` no se usan actualmente y no se discuten más aquí.

Cada tabla de permisos contiene columnas de alcance y columnas de privilegios:

- Las columnas de alcance determinan el alcance de cada entrada (registro) en las tablas; esto es, el contexto en que el registro se aplica. Por ejemplo, un registro de la tabla `user` con los valores `Host` y `User` de `'thomas.loc.gov'` y `'bob'` se usarían para autenticar conexiones hechas al servidor desde el equipo `thomas.loc.gov` por un cliente que especifique un nombre de usuario de `bob`. De forma similar, un registro de la tabla `db` con las columnas `Host`, `User`, y `Db` con valores `'thomas.loc.gov'`, `'bob'` y `'reports'` se usaría cuando `bob` conectase desde el equipo `thomas.loc.gov` para acceder a la base de datos `reports` . Las tablas `tables_priv` y `columns_priv` contienen columnas de alcance indicando tablas o combinaciones de tabla/columna para las que cada registro se aplica. La columna de alcance `procs_priv` indica la rutina de almacenamiento que se aplica a cada registro.

- Las columnas de privilegios indican qué privilegios se otorgan a un registro de la tabla; esto es, qué operaciones pueden ejecutarse. El servidor combina la información de diversas tablas de permisos para tener una descripción completa de los permisos de un usuario. Las reglas usadas para ello se describen en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

Las columnas de alcance contienen cadenas de carácteres. Se declaran tal y como se muestra a continuación; el valor por defecto es la cadena de carácteres vacía:

Nombre de columna | Tipo
`Host` | `CHAR(60)`
`User` | `CHAR(16)`
`Password` | `CHAR(16)`
`Db` | `CHAR(64)`
`Table_name` | `CHAR(64)`
`Column_name` | `CHAR(64)`
`Routine_name` | `CHAR(64)`

Con propósito de chequeos de acceso, las comparaciones de los valores de `Host` no tienen en cuenta mayúsculas y minúsculas. Los valores de `User`, `Password`, `Db`, y `Table_name` son sensibles a mayúsculas y minúsuclas. Los valores de `Column_name` no son sensibles a mayúsculas y minúsculas.

En las tablas `user`, `db`, y `host` , cada privilegio se lista en una columna separada que se declara como `ENUM('N','Y') DEFAULT 'N'`. En otras palabras, cada privilegio puede estar desactivado o activado, estando desactivados por defecto.

En las tablas `tables_priv`, `columns_priv`, and `procs_priv` , las columnas de privilegios se declaran como columnas de tipo `SET`. Los valores en estas columnas pueden contener cualquier combinación de los privilegios controlados por la tabla:

Nombre de tabla | Nombre de columna | Posible conjunto de elementos
`tables_priv` | `Table_priv` | `'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'`
`tables_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`columns_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`procs_priv` | `Proc_priv` | `'Execute', 'Alter Routine', 'Grant'`

Brevemente, el servidor usa las tablas de permisos como sigue:

- Las columnas de alcance de la tabla `user` determinan si se rechazan o permiten conexiones entrantes. Para conexiones permitidas, cualquier privilegio otorgado en la tabla `user` indica los privilegios globales del usuario (superusuario). Estos privilegios se aplican a todas las bases de datos en el servidor.

- Las columnas de alcance de la tabla `db` determinan qué usuarios pueden acceder a qué bases de datos desde qué equipo. La columna de privilegios determina qué operaciones se permiten. Un privilegio otorgado a nivel de base de datos se aplica a la base de datos y a todas sus tablas.

- La tabla `host` se usa en conjunción con la tabla `db` cuando desea que un registro de la tabla `db` se aplique a varios equipos. Por ejemplo, si queiere que un usuario sea capaz de usar una base de datos desde varios equipos en su red, deje el valor `Host` vacío en el registro de usuario de la tabla`db` , luego rellene la tabla `host` con un registro para cada uno de estos equipos. Este mecanismo se describe con mayor detalle en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

  Nota: La tabla `host` no se ve afectada por los comandos `GRANT` ni `REVOKE` . La mayoría de instalaciones MySQSL no necesitan usar esta tabla en absoluto.

- Las tablas `tables_priv` y `columns_priv` son similares a la tabla `db` , pero son más detalladas: se aplican a nivel de tabla y de columna en lugar de a nivel de base de datos. Un privilegio otorgado a nivel de tabla se aplica a la tabla y a todas sus columnas. Un privilegio otorgado a nivel de columna se aplica sólo a la columna especificada.

- La tabla `procs_priv` se aplica a rutinas almacenadas. Un privilegio otorgado a nivel de rutina se aplica sólo a una única rutina.

Permisos administrativos (tales como `RELOAD` o `SHUTDOWN`) se especifican sólo en la tabla `user` . Esto es debido a que las operaciones administrativas son operaciones del propio servidor y no específicas de bases de datos, así que no hay ninguna razón para listar estos privilegios en las otras tablas de permisos. De hecho, para determinar si puede realizar una operación administrativa, el servidor sólo necesita consultar la tabla `user`.

El privilegio `FILE` también se especifica sólo en la tabla `user` . No es un privilegio administrativo como tal, pero la habilidad de leer o escribir archivos en el equipo servidor es independiente de las bases de datos a las que acceda.

El servidor mysqld lee los contenidos de las tablas de permisos en memoria cuando arranca. Puede decirle que las vuelva a leer mediante el comando `FLUSH PRIVILEGES` o ejecutando los comandos mysqladmin flush-privileges o mysqladmin reload . Los cambios en las tablas de permisos tienen efecto como se indica en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”.

Cuando modifica los contenidos de las tablas de permisos, es una buena idea asegurarse que sus cambios configuran permisos tal y como desea. Para consultar los permisos de una cuenta dada, use el comando `SHOW GRANTS` . Por ejemplo, para determinar los permisos que se otorgan a una cuenta con valores `Host` y `User` de `pc84.example.com` y `bob`, use este comando:

    mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';

Una herramienta de diagnóstico útil es el script mysqlaccess , proporcionado por Yves Carlier para la distribución MySQL. Invoque mysqlaccess con la opción `--help` para ver cómo funciona. Note que mysqlaccess chequea acceso usando sólo las tablas `user`, `db`, y `host` . No chequea los privilegios de tabla, columna, o rutina especificados en las tablas `tables_priv`, `columns_priv`, o `procs_priv`.

Para ayuda adicional en problemas relacionados con el diagnóstico de permisos, consulte Sección 5.6.8, “Causas de errores `Access denied`”. Para consejos generales sobre seguridad , consulte Sección 5.5, “Cuestiones de seguridad general”.

### 5.6.3. Privilegios de los que provee MySQL

La información sobre los privilegios de las cuentas está almacenada en las tablas `user`, `db`, `host`, `tables_priv`, `columns_priv`, y `procs_priv` de la base de datos `mysql`. El servidor MySQL lee el contenido de estas tablas y lo almacena en memoria cuando se inicia, y lo relee bajo ciertas circunstancias indicadas en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”. Las decisiones de control de acceso se basan en la copia en memoria de las tablas grant.

Los nombres utilizados en las sentencias `GRANT` y `REVOKE` para referirse a privilegios se muestran en la siguiente tabla, junto al nombre de columna asociado con cada privilegio en las tablas grant y el contexto en que el privilegio se aplica. Más información sobre el significado de cada privilegio se puede encontrar en Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

Privilegio | Columna | Contexto
`CREATE` | `Create_priv` | bases de datos, tablas, o índices
`DROP` | `Drop_priv` | bases de datos o tablas
`GRANT OPTION` | `Grant_priv` | bases de datos, tablas, o procedimientos almacenados
`REFERENCES` | `References_priv` | bases de datos o tables
`ALTER` | `Alter_priv` | tablas
`DELETE` | `Delete_priv` | tablas
`INDEX` | `Index_priv` | tablas
`INSERT` | `Insert_priv` | tablas
`SELECT` | `Select_priv` | tablas
`UPDATE` | `Update_priv` | tablas
`CREATE VIEW` | `Create_view_priv` | vistas
`SHOW VIEW` | `Show_view_priv` | vistas
`ALTER ROUTINE` | `Alter_routine_priv` | procedimientos almacenados
`CREATE ROUTINE` | `Create_routine_priv` | procedimientos almacenados
`EXECUTE` | `Execute_priv` | procedimientos almacenados
`FILE` | `File_priv` | acceso a archivos en la máquina del servidor
`CREATE TEMPORARY TABLES` | `Create_tmp_table_priv` | administración del servidor
`LOCK TABLES` | `Lock_tables_priv` | administración del servidor
`CREATE USER` | `Create_user_priv` | administración del servidor
`PROCESS` | `Process_priv` | administración del servidor
`RELOAD` | `Reload_priv` | administración del servidor
`REPLICATION CLIENT` | `Repl_client_priv` | administración del servidor
`REPLICATION SLAVE` | `Repl_slave_priv` | administración del servidor
`SHOW DATABASES` | `Show_db_priv` | administración del servidor
`SHUTDOWN` | `Shutdown_priv` | administración del servidor
`SUPER` | `Super_priv` | administración del servidor

`CREATE VIEW` y `SHOW VIEW` fueron añadidos en MySQL 5.0.1. `CREATE USER`, `CREATE ROUTINE`, y `ALTER ROUTINE` fueron añaidos en MySQL 5.0.3. Aunque `EXECUTE` ya estaba presente en MySQL 5.0.0, no se activó hasta MySQL 5.0.3. Para utilizar estos privilegios cuando se actualice desde una versión más antigua de MySQL que no los tiene, debe actualizar sus tablas grant utilizando el script mysql_fix_privilege_tables proporcionado con la distribución MySQL. Consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

Para crear o modificar procedimientos almacenados cuando el registro binario está activado, debe también tener el privilegio `SUPER`, tal y como se explica en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

Los privilegios `CREATE` y `DROP` permiten crear nuevas bases de datos y tablas, o eliminar las existentes. Si otorga el privilegio `DROP` para la base de datos `mysql` a un usuario, ese usuario puede eliminar la base de datos en la que MySQL almacena los privilegios de acceso.

Los privilegios `SELECT`, `INSERT`, `UPDATE`, and `DELETE` permiten realizar operaciones en registros de tablas existentes en una base de datos.

Las sentencias `SELECT` requieren el privilegio `SELECT` sólo si realmente extraen registros de una tabla. Algunas sentencias `SELECT` no acceden a tablas, y pueden ser ejecutados por tanto sin permiso para ninguna base de datos. Por ejemplo, podría utilizar el cliente mysql como una simple calculadora para evaluar expresiones que no hacen referencia a tablas:

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

El privilegio `INDEX` permite crear o eliminar índices. `INDEX` es aplicable a tablas existentes. Si tiene el privilegio `CREATE` para una tabla, entonces puede incluir definiciones de índices en la sentencia `CREATE TABLE`.

El privilegio `ALTER` permite utilizar `ALTER TABLE` para cambiar la estructura de o renombrar tablas.

El privilegio `CREATE ROUTINE` es necesario para crear procedimientos almacenados (funciones y procedimientos). El privilegio `ALTER ROUTINE` se necesita para modificar o eliminar procedimientos almacenados, y `EXECUTE` es necesario para ejecutarlos.

El privilegio `GRANT` permite dar a otros usuarios las privilegios que uno mismo posee. Puede ser utilizado para bases de datos, tablas, y procedimientos almacenados.

El privilegio `FILE` otorga permiso para leer y escribir archivos en la máquina del servidor utilizando las sentencias `LOAD DATA INFILE` y `SELECT ... INTO OUTFILE`. Un usuario que tiene el privilegio `FILE` puede leer cualquier archivo de la máquina del servidor que sea legible por cualquiera o por el usuario que ejecuta el servidor MySQL. (Esto implica que el usuario puede leer cualquier archivo en el directorio de datos, porque el servidor puede acceder a cualquiera de estos archivos.) El privilegio `FILE` también permite al usuario crear archivos nuevos en cualquier directorio en que el servidor MySQL tiene acceso de escritura. Los archivos existentes no pueden ser sobreescritos.

Los privilegios restantes son utilizados para operaciones administrativas. Muchas de ellas puede ser realizadas utilizando el programa mysqladmin o mediante sentencias SQL. La siguiente tabla muestra qué comandos de mysqladmin permite ejecutar cada privilegio administrativo.

Privilegio | Comandos permitidos a los poseedores del privilegio Holders
`RELOAD` | `flush-hosts`, `flush-logs`, `flush-privileges`, `flush-status`, `flush-tables`, `flush-threads`, `refresh`, `reload`
`SHUTDOWN` | `shutdown`
`PROCESS` | `processlist`
`SUPER` | `kill`

El comando `reload` comunica al servidor que debe releer las tablas grant a memoria. `flush-privileges` es un sinónimo de `reload`. El comando `reload` cierra y vuelve a abrir los archivos de registro y vuelca todas las tablas. Los otros comandos `flush-`xxx`` realizan funciones similares a `refresh`, pero son más específicas y pueden ser preferibles en algunos casos. Por ejemplo, si quiere tan solo volcar los archivos de registro, `flush-logs` es mejor opción que `refresh`.

El comando `shutdown` apaga el servidor. Este comando puede ejecutarse únicamente desde mysqladmin. No hay sentencia SQL equivalente.

El comando `processlist` muestra información sobre los subprocesos que se están ejecutando en el servidor (es decir, sobre las sentencias que se están ejecutando por parte de clientes asociados con otras cuentas). El comando `kill` mata los subprocesos del servidor. Siempre puede mostrar información sobre sus propios subprocesos, o matarlos, pero necesita el privilegio `PROCESS` para ver subprocesos iniciados por otros usuarios, y el privilegio `SUPER` para matarlos. Consulte Sección 13.5.5.3, “Sintaxis de `KILL`”.

El privilegio `CREATE TEMPORARY TABLES` permite la utilización de la palabra clave `TEMPORARY` en sentencias `CREATE TABLE`.

El privilegio `LOCK TABLES` permite la utilización de sentencias `LOCK TABLES` explícitas para bloquear tablas para las que tiene el privilegio `SELECT`. Esto incluye el uso de bloqueos de escritura, que evita que cualquier otra persona lea la tabla bloqueada.

El privilegio `REPLICATION CLIENT` permite la utilización de las sentencias `SHOW MASTER STATUS` y `SHOW SLAVE STATUS`.

El privilegio `REPLICATION SLAVE` debería otorgarse a cuentas que son utilizadas por servidores esclavos para conectarse al servidor actual como su maestro. Sin este privilegio, la cuenta esclava no puede pedir actualizaciones que se hayan hecho a las bases de datos del servidor maestro.

El privilegio `SHOW DATABASES` permite a la cuenta ver los nombres de las bases de datos mediante la ejecución de la sentencia `SHOW DATABASE`. Cuentas que no tengan este privilegio solo pueden ver las bases de datos para las que tienen privilegios, y no pueden utilizar la sentencia de ninguna manera si el servidor ha sido iniciado con la opción `--skip-show-database`.

En general, es una buena idea garantizar a una cuenta solo aquellos privilegios que necesita. Se debe tener especial cuidado en seguir esta regla con los privilegios administrativos y `FILE`:

- El privilegio `FILE` puede utilizarse inadecuadamente para introducir en una tabla de la base de datos cualquier archivo que el servidor MySQL sea capaz de leer en la máquina del servidor. Esto incluye todos los archivos que sean legibles para cualquiera, además de los archivos almacenados en el directorio de datos del servidor. Esta tabla puede entonces ser accedida utilizando una sentencia `SELECT` para transferir sus contenidos a la máquina cliente.

- El privilegio `GRANT` permite a los usuarios otorgar sus mismos privilegios a otros usuarios. Dos usuarios con diferentes privilegios y con el privilegio `GRANT` pueden combinar sus privilegios.

- El privilegio `ALTER` puede ser utilizado inadecuadamente para sabotear el sistema de privilegios mediante el renombrado de tablas.

- El privilegio `SHUTDOWN` puede utilizarse inadecuadamente para denegar el servicio a otros usuarios de manera total, cerrando el servidor.

- El privilegio `PROCESS` puede utilizarse para ver el texto de las consultas que se estén ejecutando actualmente, incluyendo consultas que establecen o modifican passwords.

- El privilegio `SUPER` puede utilizarse para cerrar la conexión a otros clientes o cambiar como el servidor funciona.

- Los privilegios otorgados para la propia base de datos `mysql` pueden utilizarse para cambiar passwords y otra información de privilegios de acceso. Las passwords se almacenan cifradas, así que un usuario malicioso no puede simplemente leerlas para conocer la password. Aún así, el usuario con privlegio de escritura a la columna `Password` de la tabla `user` puede cambiar la password de una cuenta, y seguidamente conectarse al servidor MySQL utilizando esa cuenta.

Hay algunas cosas que no se pueden hacer con el sistema de privilegios de MySQL:

- No se puede especificar explícitamente que a un usuario se le deba denegar el acceso.

- No se puede especificar que un usuario tenga privilegios para crear o eliminar tablas en una base de datos, pero que no pueda crear o eliminar la propia base de datos.

### 5.6.4. Conectarse al servidor MySQL

Los programas cliente de MySQL espera por lo general que usted especifique los parámetros de conexión cuando quiere acceder a un servidor MySQL:

- El nombre de la máquina donde se está ejecutando el servidor MySQL

- Su nombre de usuario

- Su password

Por ejemplo, el cliente mysql puede ejecutarse desde un prompt de línea de comandos (indicado aquí por `shell>`) de la siguiente manera:

    shell> mysql -h nombre_host -u nombre_usuario -psu_clave

Las sintaxis alternativas de las opciones `-h`, `-u`, y `-p` son `--host=`nombre_host``, `--user=`nombre_usuario``, y `--password=`su_clave``. Nótese que no hay espacios entre `-p` o `--password=` y la clave que le sigue.

Si utiliza una opción `-p` o `--password` pero no especifica un valor para la clave, el programa cliente le pedirá que introduzca la clave. La clave no se mostrará mientras la introduce. Esto es más seguro que especificar la clave en la línea de comandos. Cualquier usuario de su sistema podría ser capaz de ver la clave especificada en la línea de comandos ejecutando un comando como ps auxww. Consulte Sección 5.7.6, “Guardar una contraseña de forma segura”.

Los programas clientes de MySQL utilizan valores por defecto para cualquier parámetro que no se especifique:

- El nombre de servidor por defecto es `localhost`.

- El nombre de usuario por defecto es `ODBC` en Windows y su nombre de usuario de Unix en Unix.

- No se aplica ninguna clave si `-p` no está especificado.

De esta manera, para un usuario de Unix con un nombre de usuario de `jose`, todos los siguientes comandos son equivalentes:

    shell> mysql -h localhost -u jose
    shell> mysql -h localhost
    shell> mysql -u jose
    shell> mysql

Otros clientes MySQL se comportan de manera similar.

Puede especificar valores diferentes para que se utilicen cuando se realiza una conexión de manera que no tenga que introducirlos en la línea de comandos cada vez que invoca un programa cliente. Esto puede llevarse a cabo de diversas maneras:

- Puede especificar los parámetros de conexión en la sección `[client]` de un archivo de opciones. La sección relevante del archivo debería tener el siguiente aspecto:

      [client]
      host=nombre_servidor
      user=nombre_usuario
      password=su_clave

  Los archivos de opciones son explicados en profundidad en Sección 4.3.2, “Usar ficheros de opciones”.

- Puede especificar algunos parámetros de conexión utilizando variables de ambiente. El nombre del servidor para mysql puede ser especificado utilizando `MYSQL_HOST`. El nombre de usuario MySQL puede especificarse mediante `USER` (esto es para Windows y Netware únicamente). La clave se puede especificar utilizando `MYSQL_PWD`, aunque esto es inseguro; consulte Sección 5.7.6, “Guardar una contraseña de forma segura”. Para ver la lista de variables, consulte Apéndice E, Variables de entorno.

### 5.6.5. Control de acceso, nivel 1: Comprobación de la conexión

Cuando intente conectar a un servidor MySQL, el servidor aceptará o rechazará la conexión basándose en su identidad y si usted puede identificar su identidad proporcionando la clave correcta. Si no es así, el servidor le denegará el acceso completamente. En caso contrario, el servidor acepta la conexión, y entra en el Estado 2, y espera peticiones.

Su identidad se basa en dos elementos de información:

- El nombre de máquina cliente (o ip) desde donde usted se conecta

- Su nombre de usuario MySQL

La comprobación de la identidad se realiza utilizando las tres columnas de la tabla `user` (`Host`, `User`, y `Password`). El servidor sólo acepta la conexión si las columnas `Host` y `User` de alguna de las tablas `user` es coincidente con el nombre de máquina y usuario del cliente, y además el cliente proporciona la clave especificada en ese registro.

Los valores de `Host` en la tabla `user` pueden ser especificados de las siguientes maneras:

- Un valor de `Host` debe ser un nombre de máquina o un número IP, o `'localhost'` para indicar la máquina local.

- Puede utilizar los carácteres comodín '`%`' y '`_`' en los valores de las columnas `Host`. Estos tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas mediante el operador `LIKE`. Por ejemplo, un valor de `Host` igual a `'%'` retorna cualquier nombre de máquina, así como un valor de `'%.mysql.com'` retorna cualquier nombre de máquina en el dominio `mysql.com`.

- Para valores de `Host` especificados como números IP, puede especificar una máscara de red indicando cuantos bits de la dirección utilizar para el número de red. Por ejemplo:

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

  Esto permite a `david` conectarse desde cualquier cliente que tenga un número IP `client_ip` para el que la siguiente condición sea cierta:

      client_ip & netmask = host_ip

  Es decir, para la sentencia `GRANT` recientemente mostrada: That is, for the `GRANT` statement just shown:

      client_ip & 255.255.255.0 = 192.58.197.0

  Los números IP que satisfagan esta condición y pueden conectar al servidor MySQL son lo que están en el rango desde `192.58.197.0` hasta `192.58.197.255`.

- Nota: La máscara de red solo puede ser utilizada para decirle al servidor que use 8, 16, 24 o 32 bits para la dirección, por ejemplo:

      192.0.0.0/255.0.0.0 (cualquier dirección de la red clase A 192)
      192.168.0.0/255.255.0.0 (cualquier dirección de la red clase B 192.168)
      192.168.1.0/255.255.255.0 (cualquier dirección de la red clase C 192.168.1)
      192.168.1.1 (solo esta IP específica)

  La siguiente máscara de red (28 bits) no funcionará:

      192.168.0.1/255.255.255.240

- Un valor vacío de `Host` en un registro de la tabla `db` significa que los privilegios de dicho registro deben ser combinados con aquellos que se encuentren en el registro de la tabla `host` que concuerde con el nombre del cliente. Los privilegios se combinan utilizando operaciones AND (intersección), no OR (union). Puede encontrar más información sobre la tabla `host` en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

  Un valor de `Host` en blanco en las otras tablas grant lo mismo que `'%'`.

Debido a que puede usar comodines en los valores IP de la columna `Host` (por ejemplo, `'144.155.166.%'` para conseguir cualquier IP en una subred), alguien podría intentar explotar esta capacidad poniéndole a su cliente el nombre `144.155.166.cualquierhost.com`. Para evitar estos intentos, MySQL no permite que los comodines sean utilizados para los nombres de cliente que empiezan con dígitos y un punto. Así que si tiene un cliente con nombre similar a `1.2.cualquierhost.com`, su nombre nunca concordará con la columna `Host` de las tablas grant. Un comodín de IP solo puede concordar con números IP, no nombres de cliente.

En la columna `User`, los carácteres comodín no están permitidos, pero puede especificar un valor en blanco, que será válido para cualquier nombre. Si el registro de la tabla `user` que concuerda con una conexión entrante tiene un valor vacio, el usuario es considerado anónimo, sin nombre de usuario, no un usuario con el nombre que el cliente especificó realmente. Esto significa que el nombre de usuario vacío es utilizado para todas las comprobaciones de acceso posteriores durante la duración de la conexión (es decir, durante el Estado 2).

La columna `Password` puede estar vacía. Esto no es un comodín que permite que cualquier clave sea permitida. Significa que el usuario debe conectarse sin especificar una clave.

Los valores que no están vacíos de `Password` en la tabla `user` representan claves cifradas. MySQL no almacena las claves en forma de texto llano para que cualquiera pueda verlo. En vez de esto, la clave suministrada por un usuario que se está intentando conetar es cifrada (utilizando la función `PASSWORD()`). La clave cifrada se utiliza entonces durante el proceso de conexión en el momento de comprobar si es correcta. (Esto se realiza sin que la clave cifrada viaje nunca sobre la conexión.) Desde el punto de vista de MySQL, la clave cifrada es la clave REAL, así que no debería darse acceso a ella a nadie. En concreto, no de acceso de lectura a las tablas de la base de datos `mysql` a usuarios no-administrativos.

MySQL 5.0 utiliza el método de autenticación más fuerte (implementado primeramente en MySQL 4.1) y que tiene una mejor protección de la clave durante el proceso de conexión que versiones previas. Es seguro aún cuando los paquetes TCP/IP fuesen interceptados o la base de datos `mysql` capturada. El cifrado de claves es comentado en mayor profundida en Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1”.

Los siguientes ejemplos nos enseñan como se aplicarían a las conexiones entrantes diferentes combinaciones de los valores de las columnas `Host` y `User` de la tabla `user`.

`Cliente` Valor | `Usuario` Valor | Conexiones que concuerdan con la entrada Entry
`'thomas.loc.gov'` | `'fred'` | `fred`, conectando desde `thomas.loc.gov`
`'thomas.loc.gov'` | `''` | Cualquier usuario, conectando desde `thomas.loc.gov`
`'%'` | `'fred'` | `fred`, conectando desde cualquier cliente
`'%'` | `''` | Cualquier usuario conectando desde cualquier cliente
`'%.loc.gov'` | `'fred'` | `fred`, conectando desde cualquier cliente en el dominio `loc.gov`
`'x.y.%'` | `'fred'` | `fred`, conectando desde `x.y.net`, `x.y.com`, `x.y.edu`, etc. (esto, probablemente, no es útil)
`'144.155.166.177'` | `'fred'` | `fred`, conectando desde el cliente con dirección IP `144.155.166.177`
`'144.155.166.%'` | `'fred'` | `fred`, conectando desde cualquier cliente en la subred de clase C `144.155.166`
`'144.155.166.0/255.255.255.0'` | `'fred'` | Idéntico al ejemplo anterior

Es posible que el nobre del cliente y del usuario de una conexión entrante concuerde con más de un registro en la tabla `user`. El conjunto de ejemplos precedentes demuestra esto: Algunas de las entradas mostradas concuerdan con una conexión de `fred` desde `thomas.loc.gov`.

Cuando hay la posibilidad de múltiples concordancias, el servidor debe determinar cual de ellas utilizar. El problema se resuelve de la siguiente manera:

- Siempre que el servidor lee la tabla `user` a memoria, ordena los registros.

- Cuando un cliente intenta conectar, el servidor mira a través de los registros en el orden establecido.

- El servidor utiliza el primer registro que concuerda con el nombre y usuario del cliente.

Para ver como esto ocurre, supongamos que la tabla `user` es como esta:

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

Cuando el servidor lee la tabla, ordena las entradas con los valores de `Host` más específicos primero. Los nombres de cliente y números de IP son los más específicos. El comodín `'%'` significa ``cualquier cliente'' y es menos específico. Registros con el mismo valor de `Host` se ordenan con el valor de `User` más específico (un valor de `User` en blanco significa ``cualquier usuario'' y es menos específico). En la tabla `user` recién mostrada, el resultado después de ordenar sería el siguiente:

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

Cuando un cliente intenta conectar, el servidor mira los registros ordenados y utiliza la primera concordancia. Para una conexión desde `localhost` por `jeffrey`, dos de las entradas de la tabla concuerdan: la primera con los valores `'localhost'` y `''` de `Host` y `User` respectivamente, y el registro con los valores `'%'` y `'jeffrey'`. El registro con valor `'localhost'` aparece primero en la tabla ordenada, así que es el que el servidor utiliza.

Aquí hay otro ejemplo. Supongamos que la tabla `user` tiene el siguiente aspecto:

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

La tabla ordenada sería:

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

Una conexión de `jeffrey` desde `thomas.loc.gov` concuerda con el primer registro, mientras que una conexión de `jeffrey` desde `whitehouse.gov` concuerda con el segundo.

Es una confusión común el pensar que, para un nombre de usuario dado, todos los registros que nombran explícitamente con a ese usuario son utilizadas primero cuando el servidor intenta encontrar una concordancia para una conexión. Esto es sencillamente falso. El ejemplo anterior ilustra esto, donde una conexión de `jeffrey` desde `thomas.loc.gov` no concuerda primero con el registro que contiene `'jeffrey'` como valor en la columna `User`, sino que ha concordado con el registro que no contiene nombre de usuario. Como resultado, `jeffrey` es tratado como un usuario anónimo aunque ha especificado un nombre de usuario al conectarse.

Si puede conectar al servidor, pero sus privilegios no son los que espera, probablemente está siendo identificado como algún otro usuario. Para averiguar qué cuenta de usuario utilizó el servidor para identificarle, use la función `CURRENT_USER()`. Devuelve un valor en formato ``user_name`@`host_name`` que indica los valores de `User` y `Host` del registro concordante en la tabla `user`. Suponga que `jeffrey` conecta y ejecuta la siguiente sentencia:

    mysql> SELECT CURRENT_USER();
    +----------------+
    | CURRENT_USER() |
    +----------------+
    | @localhost     |
    +----------------+

El resultado mostrado indica que el registro que concuerda en la tabla `user` tiene un valor vacío en la columna `User`. En otras palabras, el servidor trata a `jeffrey` como a un usuario anónimo.

Otra cosa que puede hacer para localizar problemas de autentificación es imprimir por pantalla la tabla `user` y ordenarla a mano para ver donde está la primera concordancia. Consulte Sección 12.9.3, “Funciones de información”.

### 5.6.6. Control de acceso, nivel 2: comprobación de solicitudes

Una vez establecida una conexión, el servidor entra en el estado 2 del control de acceso. Por cada petición que viene en la conexión, el servidor determina que operación realizar, y entonces comprueba si tiene suficientes privilegios para hacerlo. Aquí es donde las columnas de privilegios de las tablas grant entran en juego. Esots privilegios puede venir de cualquiera de las tablas `user`, `db`, `host`, `tables_priv`, o `columns_priv`.(Puede encontrar útil consultar Sección 5.6.2, “Cómo funciona el sistema de privilegios”, que enumera las columnas presentes en cada una de las tablas grant.)

La tabla `user` otorga privilegios que se asignan de manera global, y que se aplican sin importar sobre qué base de datos trabajamos. Por ejemplo, si la tabla `user` le otorga el privilegio `DELETE`, usted podrá borrar registros de cualquier tabla en cualquier base de datos en todo el servidor. En otras palabras, los privilegios de la tabla `user` son privilegios de superusuario. Es aconsejable otorgar privilegios en la tabla `user` sólo a superusuarios tales como administradores de base de datos. Para otros usuarios, debería dejar los privilegios de la tabla `user` con el valor `'N'` y otorgar los privilegios únicamente a niveles más específicos. Puede otorgar privilegios para bases de datos, tablas o columnas particulares.

Las tablas `db` y `host` otorgan privilegios específicos para una base de datos. Los valores en las columnas de estas tablas pueden tener los siguientes formatos:

- Los carácteres comodín '`%`' y '`_`' pueden utilizarse en las columnas `Db` de cualquiera de las tablas. Estos tienen el mismo significado que en las operaciones de reconocimiento de patrones efectuadas con el operador `LIKE`. Si quiere utilizar cualquiera de estos carácteres literales al otorgar privilegios, debe incluirlos en una secuencia de escape con una barra invertida. Por ejemplo, para incluir el carácter '`_`' como parte del nombre de una base de datos, especifíquelo como '`\_`' en la sentencia `GRANT`.

- Un valor de `'%'` en la columna `Host` de la tabla `db` significa ``cualquier host.'' Un valor vacío en la columna `Host` de la tabla `db` significa ``consulta la tabla `host` para más información'' (un proceso que se describe más adelante en esta sección).

- Un valor de `'%'` o en blanco en la columna `Host` de la tabla `host` significa ``cualquier host.''

- Un valor de `'%'` o en blanco de la columna `Db` en cualquiera de las dos tablas, significa ``cualquier base de datos.''

- Un valor en blanco de la columna `User` en cualquiera de las tablas concuerda con el usuario anónimo.

El servidor lee y ordena las tablas `db` y `host` al mismo tiempo que lee la tabla `user`. El servidor ordena la tabla `db` basándose en el rango de las columnas `Host`, `Db` y `User`, y ordena la tabla `host` basándose en el rango de las columnas `Host` y `Db`. Igual que con la tabla `user`, la ordenación coloca los valores menos específicos en última posición, y cuando el servidor busca correspondencias, utiliza la primera que encuentra.

Las tablas `tables_priv` y `columns_priv` otorgan privilegios específicos para tablas y columnas respectivamente. Los valores en las columnas de rango de estas tablas pueden tener los siguientes formatos:

- Los carácteres comodín '`%`' y '`_`' pueden ser utilizados en la columna `Host` de cualquiera de las tablas. Estos comodines tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas con el operador `LIKE`.

- Un valor de `'%'` o vacío en la columna `Host` de cualquiera de las tablas significa ``cualquier host.''

- Las columnas `Db`, `Table_name` y `Column_name` no pueden contener carácteres comodín ni estar en blanco en ninguna de las tablas.

El servidor ordena las tablas `tables_priv` y `columns_priv` basándose en las columnas `Host`, `Db`, y `User`. Esto es similar a la ordenación de la tabla `db`, pero más simple, porque únicamente la columna `Host` puede contener comodines.

El proceso de verificación de peticiones se describe aquí. (Si usted está familirizado con el código fuente de control de acceso, se dará cuenta de que la descripción aquí contenida difiere ligeramente de el algoritmo utilizado en el código. La descripción es equivalente a lo que el código hace realmente; solo difiere para hacer la explicación más simple.)

Para peticiones que requieran privilegios de administrador, como `SHUTDOWN` o `RELOAD`, el servidor comprueba únicamente el registro de la tabla `user` porque es la única tabla que especifica los privilegios administrativos. El acceso se otorga si el registro permita la operación demandada, y es denegado en caso contrario. Por ejemplo, si usted quisiera ejecutar mysqladmin shutdown, pero su registro de la tabla `user` no le otorga el privilegio `SHUTDOWN`, el servidor deniega el acceso sin ni siquiera codnsultar las tablas `db` o `host`. (No contienen ninguna columna `Shutdown_priv`, así que no hay necesidad de hacerlo.)

Para peticiones sobre bases de datos (`INSERT`, `UPDATE`, etc.), el servidor primero comprueba los privilegios globales del usuario (superuser) mirando el registro de la tabla `user`. Si el registro permite la operación demandada, se otorga el acceso. Si los privilegios globales de la tabla `user` son insuficientes, el servidor determina los privilegios específicos sobre la base de datos comprobando las tablas `db` y `host`:

1. El servidor busca en la tabla `db` una concordancia en las columnas `Host`, `Db` y `User`. Las columnas `Host` y `User` se hacen concordar con el nombre de host y de usuario MySQL. La columna `Db` se hace concordar con la base de datos a la que el usuario quiere acceder. Si no hay ningún registro para `Host` y `User`, se deniega el acceso.

2. Si hay un registro que concuerda en el registro de la tabla `db` y su columna `Host` no está vacía, ese registro define los privilegios específicos del usuario en la base de datos.

3. Si la columna `Host` del registro concordante de la tabla `db` se encuentra vacía, significa que la tabla `hosts` enumera qué hosts pueden tener acceso a la base de datos. En este caso, una comprobación más se realiza en la tabla `host` para encontrar una concordancia en las columnas `Host` y `Db`. Si ningún registro de la tabla `host` concuerda, se deniega el acceso. Si hay una concordancia, los privilegios específicios sobre la base de datos del usuario son calculados como la intersección (¡no unión!) de los privilegios en los registros de las tablas `db` y `host`; es decir, los privilegios que tienen valor `'Y'` en ambos registros. (De esta manera puede otorgar privilegios en el registro de la tabla `db` y entonces restringir selectivamente host a host utilizando los registros de la tabla `hosts`.)

Tras determinar los privilegios específicos de la base de datos otorgados por los registros de las tablas `db` y `host`, el servidor los añade a los privilegios globales otorgados por la tabla `user`. Si el resultado permite la operación demandada, se otorga el acceso. En caso contrario, el servidor comprueba sucesivamente la tabla del usuario y los privilegios de las columnas en las tablas `tables_priv` y `columns_priv`, los añade a los privilegios del usuario, y permite o deniega el acceso basándose en el resultado.

Expresado en términos booleanos, la descripción precedente de como se calculan los privilegios de un usuario, se puede resumir en:

    privilegios globales
    O (privilegios de base de datos Y privilegios de host)
    O privilegios de tabla
    O privilegios de columna

Puede no ser evidente por qué, si los privilegios globales del registro en la tabla `user` no han sido inicialmente suficientes para la operación demandada, el servidor añado estos privilegios a los de base de datos, tabla y columna más tarde. La razón es que una petición puede requerir más de un tipo de privilegio. Por ejemplo, si usted ejecuta una sentencia `INSERT INTO ... SELECT`, necesita tanto el privilegio `INSERT` como el privilegio `SELECT`. Sus privilegios podrían estar configurados de manera que la tabla `user` otorgue un privilegio, y la tabla `db` otorgue el otro. En este caso, necesita ambos privilegios para realizar la sentencia, pero el servidor no puede saberlo desde cada una de las tablas únicamente; los privilegios otorgados por los registros de ambas tablas deben ser combinados.

La tabla `host` no es afectada por sentencias `GRANT` o `REVOKE`, así que en la mayoría de las instalaciones MySQL queda sin utilizar. Si usted la modifica directamente, puede utilizarla para algunos propósitos específicos, como mantener una lista de servidores seguros. Por ejemplo, en TcX, la tabla `host` contiene una lista de todas las máquinas en la red local. Éstas tienen otorgados todos los privilegios.

También puede utilizar la tabla `host` para indicar hosts que no son seguros. Supongamos que tiene una máquina `public.su.dominio` que está situada en un lugar público que no considera seguro. Puede permitir el acceso a todos los hosts de su red excepto a esa máquina utilizando registros de la tabla `host` como este:

    +--------------------+----+-
    | Host               | Db | ...
    +--------------------+----+-
    | public.your.domain | %  | ... (all privileges set to 'N')
    | %.your.domain      | %  | ... (all privileges set to 'Y')
    +--------------------+----+-

Nauturalmente, usted debe siempre comprobar sus entradas en las tablas grant (por ejemplo, utilizando `SHOW GRANTS` o mysqlaccess) para estar seguro de que sus privilegios de acceso son realmente los que piensa que son.

### 5.6.7. Cuándo tienen efecto los camios de privilegios

Cuando mysqld se inicia, todos los contenidos de las tablas grant se leen a memoria y se hacen efectivas para el control de acceso en ese punto.

Cuando el servidor recarga las tablas grant, los privilegios para los conexiones de clientes existentes se ven afectadas de la siguiente manera:

- Los cambios en los privilegios de tabla y columna toman efecto en la siguiente petición del cliente.

- Los cambios en privilegio sde base de datos toman efecto en la siguiente sentencia `USE `db_name``.

- Los cambios a los privilegios globales y las claves de acceso toman efecto la próxima vez que el cliente se conecte.

Si usted modifica las tablas grant utilizando `GRANT`, `REVOKE`, o `SET PASSWORD`,el servidor se da cuenta de estos cambios y recarga las tablas grant en la memoria inmediatamente.

Si usted modifica las tablas grant directamente utilizando sentencias como `INSERT`, `UPDATE`, o `DELETE`, los cambios no tendrán efecto en la comprobación de privilegios hasta que se reinicie el servidor, o bien se le comunique a éste que debe recargar las tablas. Para recargar las tablas manualmente, ejecute la sentencia `FLUSH PRIVILEGES` o los comandos mysqladmin flush-privileges o mysqladmin reload.

Si usted cambia las tablas grant directamnete pero olvida recargarlas, sus cambios no tienen efecto hasta que reinicie el servidor. Esto podría confundirle intentando averiguar por qué sus cambios no parecen tener efecto.

### 5.6.8. Causas de errores `Access denied`

Si usted se encuentra problemas cuando intenta conectar al servidor MySQL, los siguientes elementos explican algunas medidas que se pueden tomar para corregir el problema.

- Asegúrese de que el servidor se está ejecutando. Si no se está ejecutando, no puede conectarse a él. Por ejemplo, si intenta conectarse a el servidor y ve un mensaje como cualquiera de los siguientes, podría ser que el servidor no se esté ejecutando:

      shell> mysql
      ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
      shell> mysql
      ERROR 2002: Can't connect to local MySQL server through socket
      '/tmp/mysql.sock' (111)

  También podría ser que el servidor se esté ejecutando, pero usted se esté intentando conectar utilizando un puerto TCP/IP, named pipe, o archivo socket de Unix diferentes de aquellos a los que el servidor atiende. Para corregir esto cuando invoca a un programa cliente, especifique la opción `--port` para indicar el puerto adecuado, o la opción `--socket` para indicar la named pipi o el archivo socket de Unix apropiados. Para averiguar dónde se encuentra el archivo socket, puede ejecutar:

      shell> netstat -ln | grep mysql

- Las tablas grant deben estar correctamente configuradas para que el servidor pueda utilizarlas en el control de acceso. Para algunos tipos de distribución (como las distribuciones binarias de Windows, o las distribuciones RPM de Linux), el proceso de instalación inicializa la base de datos `mysql` que contiene las tablas grant. Para distribuciones que no hacen esto, usted debe inicializar las tablas grant manualmente ejecutando el script mysql_install_db. Para más detalles, consulte Sección 2.9.2, “Pasos a seguir después de la instalación en Unix”.

  Una manera de determinar si debe inicializar las tablas grant es buscar un directorio `mysql` bajo el directorio de datos. (El directorio de datos normalmente se llama `data` o `var` y se encuentra bajo su directorio de instalación de MySQL.) Asegúrese de que tiene un archivo llamado `user.MYD` en el directorio `mysql` de la base de datos. Si no, ejecute el script mysql_install_db. Tras ejecutar este script e iniciar el servidor, compruebe los privilegio siniciales ejecutando este comando:

      shell> mysql -u root test

  El servidor debería dejarle conectar sin error.

- Tras una nueva instalación, usted debería conectarse al servidor y configurar sus usuarios y sus permisos de acceso:

      shell> mysql -u root mysql

  El servidor debería dejarle conectar porque el usuario MySQL `root` no tiene clave de acceso inicialmente. Esto, además, es un riesgo de seguridad, así que asignar la clave de acceso para las cuentas `root` es algo que debe hacer mientras se configuran el resto de usuarios. Puede consultar las instrucciones para asignar las claves iniciales aquí Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”.

- Si usted ha actualizado una instalación MySQL existente a una nueva versión, ¿ejecutó el script mysql_fix_privilege_tables? En caso negativo, hágalo. La estructura de las tablas grant cambia ocasionalmente cuando se añaden nuevas características, así que tras una actualización debería siempre asegurarse de que sus tablas tienen la estructura actual. Para más instrucciones, consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

- Si un programa cliente recibe el siguiente mensaje de error cuando intenta conectar, significa que el servidor está esperando las claves de acceso en un formato más nuevo del que el cliente es capaz de generar:

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

  Para más información sobre atajar este problema, consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1” y Sección A.2.3, “`Client does not support authentication protocol`”.

- Si intenta conectarse como `root` y obtiene el siguiente error, significa que usted no tiene un registro en la tabla `user` con un valor en la columna `User` de `'root'` y que mysqld no puede resolver el nombre de host para su cliente:

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

  En este caso, debería reiniciar el servidor con la opción `--skip-grant-tables` y editar su archivo `/etc/hosts` o `\windows\hosts` para añadir una entrada para su host.

- Recuerde que los programas cliente utilizan parámetros de conexión especificados en archivos de opciones o variables de entorno. Si un programa cliente parece estar enviando parámetros de conexión por defecto incorrectos cuando no los especifica en línea de comandos, compruebe su entorno y cualquier archivo de opciones implicado. Por ejemplo, si obtiene `Access denied` cuando intenta ejecutar un cliente sin ninguna opción, asegúrese de que no ha especificado una clave de acceso antigua en sus archivos de opciones.

  Puede suprimir el uso de archivos de opciones por parte de un programa cliente invocándolo con la opción `--no-default`. Por ejemplo:

      shell> mysqladmin --no-defaults -u root version

  Los archivos de opciones que los clientes utilizan están enumerados en Sección 4.3.2, “Usar ficheros de opciones”. Las variables de entorno se enumeran en Apéndice E, Variables de entorno.

- Si obtiene el siguiente error, significa que está utilizando una clave de `root` incorrecta:

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

  Si este error precedente ocurre aún cuando usted no ha especificado ninguna clave de acceso, significa que tiene una clave incorrecta en algún archivo de opciones. Intente utilizar la opción `--no-defaults` como se explica en el punto anterior.

  Para más información sobre el cambio de claves, consulte Sección 5.7.5, “Asignar contraseñas a cuentas”.

  Si usted ha perdido u olvidado la clave de `root`, puede reiniciar mysqld con `--skip-grant-tables` para cambiar la clave. Consulte Sección A.4.1, “Cómo reiniciar la contraseña de root”.

- Si usted cambia la clave utilizando `SET PASSWORD`, `INSERT`, o `UPDATE`, debe cifrar la clave utilizando la función `PASSWORD()`. Si no utiliza `PASSWORD()` para estas sentencias, la clave no funcionará. Por ejemplo, la siguiente sentencia asigna una clave, pero no la cifra, así que el usuario no es capaz de conectar tras ella:

      mysql> SET PASSWORD FOR 'abe'@'host_name' = 'eagle';

  En vez de esto, debe establecer la clave así:

      mysql> SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');

  La función `PASSWORD()` no es necesaria cuando se especifica la clave utilizando sentencias `GRANT` o (a partir de MySQL 5.0.2) `CREATE USER`, o también con el comando mysqladmin password, los cuales utilizan automáticamente `PASSWORD()` para cifrar la clave. Consulte Sección 5.7.5, “Asignar contraseñas a cuentas” y Sección 13.5.1.1, “Sintaxis de `CREATE USER`”.

- `localhost` es un sinónimo para su nombre de máquina local, y también es la máquina por defecto al que los clientes se intentan conectar si no se especifica explícitamente.

  Para evitar este problema en sistemas como ese, puede utilizar la opción `--host=127.0.0.1` para mencionar la máquina t explícitamente. Esto crea una conexión TCP/IP al servidor mysqld local. También puede utilizar TCP/IP especificando una opción `--host` que utilice el nombre real de la máquina local. En este caso, el nombre de host debe ser especificado en una fila de la tabla `user` del servidor, aun cuando el cliente esté corriendo en la misma máquina que el servidor.

- Si obtiene un error `Access denied` cuando intenta conectarse a la base de datos con `mysql- u user_name`, puede que tenga un problema con la tabla `user`. Compruebe esto ejecutando `mysql -u root mysql` e introduciendo esta sentencia SQL:

      mysql> SELECT * FROM user;

  El resultado debería incluir una fila cuyas columnas `Host` y `User` coincidan con el nombre de su máquina y su nombre de usuario MySQL.

- El mensaje de error `Access denied` indica con qué nombre de usuario se está intentando entrar al sistema, la máquina cliente desde la que se está intentando conectar, y si se está utilizando clave de acceso o no. Normalmente, debería tener una línea en la tabla `user` que concuerde exactamente con el nombre de máquina y el nombre de usuario que se ha obtenido en el mensaje de error. Por ejemplo, si obtiene un mensaje de error que contiene `using password: NO`, significa que se ha intentado entrar sin utilizar una clave de acceso.

- Si el siguiente error aparece cuando se intenta conectar desde una máquina diferente a la que está ejecutando el servidor MySQL, significa que no hay ninguna fila en la tabla `user` con un valor `Host` que concuerde con la máquina cliente:

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

  Puede corregir esto estableciendo una cuenta para la combinación de nombre de máquina y usuario que está utilizando cuando se intenta conectar.

  Si usted no conoce el número de IP o el nombre de máquina del ordenador desde el que se está conectando, debería poner una fila con un valor de `'%'` en la columna `Host` de la tabla `user`, y reiniciar mysqld en el servidor con la opción `--log`. Tras intentar conectar desde la máquina cliente, la información en el log de MySQL indica desde donde se conectó realmente. (Entonces cambie el valor `'%'` en la tabla `user` para introducir el nombre real de la máquina que se muestra en el log. De otra manera obtendría un sistema inseguro, porque permitiría conexiones desde cualquier máquina para ese usuario dado.)

  En Linux, hay otra razón por la que este error puede ocurrir, y es que esté utilizando una versión binaria de MySQL que haya sido compilada con una versión diferente de la librería `glibc` de la que usted está utilizando. En este caso, usted debería actualizar su sistema operativo o `glibc`, o descargarse una distribución MySQL en código fuente y compilarla usted mismo. Un paquete RPM de código fuente es, normalmente, trivial de compilar e instalar, así que esto no es un gran problema.

- Si especifica un nombre de máquina cuando se intenta conectar, pero obtiene un mensaje de error donde el nombre de máquina no se muestra, o es un número IP, significa que el servidor MySQL obtuvo un error al intentar resolver el número IP de el cliente a un nombre:

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

  Esto indica que existe un problema con DNS. Para arreglarlo, ejecute mysqladmin flush-hosts para reestablecer la cache interna de DNS. Consulte Sección 7.5.6, “Cómo usa MySQL las DNS”.

  Estas son algunas soluciones permanentes:

  - Intente encontrar qué le ocurre a su servidor DNS y arréglelo.

  - Especifique números IP en vez de nombres de máquina en las tablas grant de MySQL

  - Introduzca una línea para la máquina cliente en `/etc/hosts`.

  - Ejecute mysqld con la opción `--skip-name-resolve`.

  - Ejecute mysqld con la opción `--skip-host-cache`.

  - En Unix, si está ejecutando el servidor y el cliente en la misma máquina, conéctese a `localhost`. Las conexiones a `localhost` en Unix utilizan un archivo socket en vez de TCP/IP.

  - En Windows, si está ejecutando cliente y servidor en la misma máquina, y el servidor tiene activada la característica de conexión mediante named pipe, conéctese a `.` (punto). Las conexiones a `.` utilizan una named pipe en vez de TCP/IP.

- Si el comando `mysql -u root test` funciona pero `mysql -h `your_hostname` -u root test` termina con un `Access denied` (donde `your_hostname` es el nombre real de su máquina local), puede que no haya especificado correctamente el nombre de su máquina en la tabla `user`. Un problema común es que el valor de `Host` en la fila de la tabla `user` especifique un nombre de máquina incompleto, pero las rutinas de resolución de nombres de dominio de su sistema retornen un nombre de dominio completo (o viceversa). Por ejemplo, si tiene una entrada con valor `'tcx'` en `Host` de la tabla `user`, pero sus DNS dicen qeu su nombre de máquina es `'tcx.subnet.se'`, esta entrada no funcionará. Intente añadir una entrada a la tabla `user` con un valor de `Host` que contenga un comodín; por ejemplo `'tcx.%'`. ¡En cualquier caso, el uso de nombres que acaben con '`%`' es inseguro y no recomendado!

- Si `mysql -u `user_name` test` funciona pero `mysql -u `user_name` `other_db_name`` no funcionado, entonces es que no tiene concedidos los permisos para acceder a la base de datos `other_db_name` para ese usuario dado.

- Si `mysql -u `user_name`` funciona cuando se ejecuta en la máquina del servidor, pero `mysql -h `host_name` -u `user_name`` no lo hace cuando se ejecuta en una máquina cliente remota, entonces no tiene activado el acceso a el servidor para el usuario dado en la máquina remota.

- Si no es capaz de averiguar por qué obtiene el error de `Access denied`, borre de la tabla `user` todos los valores que contengan comodines (que contengan carácteres '`%`' o '`_`'). Un error muy común es insertar un nuevo registro con `Host`=`'%'` y `User`=`'`some_user`'`, pensando que esto permite especificar que `localhost` se conecte desde la misma máquina. La razón por la que esto no funciona es que los privilegios por defecto incluyen un registro con `Host`=`'localhost'` y `User`=`''`. Debido a que ese registro es más específico que `'%'`, se utiliza preferentemente frente al nuevo registro cuando conecta desde `localhost`. El procedimiento correcto es insertar una segunda entrada con `Host`=`'localhost'` y `User`=`'`some_user`'`, o borrar la entrada con `Host`=`'localhost'` y `User`=`''`. Tras borrar la entrada, recuerde ejecutar una sentencia `FLUSH PRIVILEGES` para recargar las tablas grant.

- Si obtiene el siguiente error, puede ser que tenga un problema con las tablas `db` o `host`:

      Access to database denied

  Si la entrada seleccionada de la tabla `db` contiene un valor vacio en la columna `Host`, asegúrese de que hay una o más entradas correspondientes en la tabla `host` especificando a qué máquinas se aplica la entrada de la tabla `db`.

- Si usted puede conectar al servidor MySQL, pero obtiene un mensaje `Access denied` siempre que ejecuta una sentencia `SELECT ... INTO OUTFILE` o `LOAD DATA INFILE`, su entrada en la tabla `user` no tiene el privilegio `FILE` activado.

- Si cambia las tablas grant directamente (por ejemplo, mediante sentencias `INSERT`, `UPDATE`, o `DELETE`) y sus cambios parecen que son ignorados, recuerde que debe ejecutar la sentencia `FLUSH PRIVILEGES` statement or el comando mysqladmin flush-privileges para que el servidor relea las tablas de privilegios. En otro caso, los cambios no tendrán efecto hasta la próxima vez que el servidor sea reiniciado. Recuerde que tras cambiar la clave de `root` con un comando `UPDATE`, no necesita especificar la nueva clave hasta que se haga la relectura de privilegios, porque el servidor no sabrá que la clave ha cambiado hasta ese momento.

- Si sus privilegios parecen haber cambiado en el medio de una sesión, podría ser que un administrador de MySQL los haya cambiado. La recarga de las tablas grant afecta a las nuevas conexiones de cliente, pero también a las ya existentes tal y como se indica en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”.

- Si tiene problemas de acceso con un programa Perl, PHP, Python u ODBC, intente conectar al servidor con `mysql -u `user_name` `db_name`` o `mysql -u `user_name` -p`your_pass` `db_name``. Si puede conectar utilizando el programa cliente mysql, el problema está en su programa, no en los privilegios de acceso. (No hay ningún espacio entre `-p` y la clave; también puede utilizar la sintaxis `--password=`your_pass`` para especificar la clave. Si utiliza la opción `-p` sola, MySQL le preguntará por la clave.)

- Para hacer comprobaciones, inicie el servidor mysqld con la opción `--skip-grant-tables`. Puede cambiar las tablas grant y utilizar el script mysqlaccess para comprobar que sus modificaciones tienen el efecto deseado. Cuando esté satisfecho con los cambios, ejecute mysqladmin flush-privileges para decirle al servidor mysqld que comience a utilizar las nuevas tablas grant. (Recargar las tablas sobresee la opción `--skip-grant-tables`. Esto permite decirle al servidor que comience a utilizar las tablas sin tener que reiniciarlo.)

- Si todo lo anterior falla, inicie el servidor mysqld con una opción de depuración (por ejemplo, `--debug=d,general,query`). Esto imprime la información de host y usuario sobre los intentos de conexión, así como información sobre cada comando ejecutado. Consulte Sección D.1.2, “Crear ficheros de traza”.

- Si tiene cualquier otro problema con las tablas grant de MySQL y cree que debe enviar el problema a la lista de correo, proporcione siempre un volcado de las tablas grant MySQL. Puede hacer ete volcado con el comando mysqldump mysql. Como siempre, envíe su problema utilizando el script mysqlbug. Consulte Sección 1.6.1.3, “Cómo informar de bugs y problemas”. En elgunos casos, podría necesitar reiniciar mysqld con `--skip-grant-tables` para ejecutar mysqldump.

### 5.6.9. Hashing de contraseñas en MySQL 4.1

Las cuentas de usuario de MySQL se listan en la tabla `user` de la base de datos `mysql` . Cada cuenta MySQL tiene una contraseña asiganada, aunque lo que se guarda en la columna `Password` de la tabla `user` no es una versión en texto plano de la contraseña, si no un valor hash computado a partir de la misma. Los valores hash de las contraseñas se obtienen a partir de la función `PASSWORD()` .

MySQL usa contraseñas en dos fases de la comunicación cliente/servidor:

- Cuando un cliente trata de conectar al servidor, hay un paso inicial de autenticación en el que el cliente debe presentar una contraseña cuyo valor hash coincida con el valor hash almacenado en la tabla `user` para la cuenta que el cliente quiere usar.

- Una vez que el cliente conecta, puede (si tiene los suficientes permisos) cambiar o incializar los hashes de las contraseñas para las cuentas listadas en la tabla `user` . El cliente puede hacerlo mediante la función `PASSWORD()` para generar el hash de la contraseña, o mediante los comandos `GRANT` o `SET PASSWORD`.

En otras palabras, el servidor usa los valores hash durante la autenticación cuando un cliente trata de conectar por primera vez. El servidor genera valores hash si un cliente conectado invoca la función `PASSWORD()` o usa los comandos `GRANT` o `SET PASSWORD` para inicializar o cambiar una contraseña.

El mecanismo de hash de contraseñas se actualizó en MySQL 4.1. para proporcionar una mejor seguridad y para reducir el riesgo de intercepción de contraseñas. Sin embargo, este nuevo mecanismo sólo lo entienden los servidores y clientes MySQL 4.1. (y versiones posteriores), lo cual puede acarrear algunos problemas de compatibilidad. Un cliente 4.1. o posterior puede conectar a un servidor pre-4.1, ya que el cliente entiende los mecanismos de hashing de contraseñas antiguos y nuevos. Sin embargo, un cliente pre-4.1. que trate de conectar a un servidor 4.1. o posterior puede tener problemas. Por ejemplo, un cliente 3.23 mysql que trate de conectar a un servidor 5.0 puede fallar con el siguiente mensaje de error:

    shell> mysql -h localhost -u root
    Client does not support authentication protocol requested
    by server; consider upgrading MySQL client

Otro ejemplo común es cuando se trata de usar la antigua extensión de mysql para PHP tras actualizar a MySQL 4.1 o posterior. (Consulte Sección 24.4.1, “Problemas comunes con MySQL y PHP”.)

La siguiente discusión describe las diferencias entre el antiguo y nuevo mecanismo de contraseñas, y qué debe hacer si actualiza su servidor pero necesita matener compatibilidad con clientes versión pre-4.1. Puede encontrar información adicional en Sección A.2.3, “`Client does not support authentication protocol`”. Esta información es de especial importancia para programadores de PHP que migran de versiones de bases de datos MySQL 4.0 o anteriores a versiones 4.1. o posteriores.

Nota: Esta discusión contrasta el comportamiento 4.1. con el pre-4.1, pero el comportamiento 4.1 descrito aquí realmente empieza en el 4.1.1. MySQL 4.1.0 es una versión ``particular'' ya que tiene mecanismos ligeramente distintos a los implementados en 4.1.1 y posteriormente. Las diferencias entre 4.1.0 y reciones más recientes se describen con más detalle en Manual de referencia de MySQL 4.1.

Antes de MySQL 4.1, los hashes de contraseñas computados por la función `PASSWORD()` tienen una longitud de 16 bytes. Tales hashes tienen este aspecto:

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

La columna `Password` de la tabla `user` (en la que se guardan los hashes) también tiene una longitud de 16 bytes antes de MySQL 4.1.

En MySQL 4.1, la función `PASSWORD()` se modificó para producir un valor hash más largo de 41-bytes:

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

Por consiguiene, la columna `Password` en la tabla `user` debe tener una longitud de 41 bytes para almacenar estos valores:

- Si realiza una nueva instalación de MySQL 5.0, la columna `Password` se amplía a 41 bytes automáticamente.

- Actualizar desde MySQL 4.1 (4.1.1 o posterior en la serie 4.1 ) a MySQL 5.0 no debería afectar a nada de todo esto, ya que ambas versiones usan el mismo mecanismo de hash de contraseñas. Si desea actualizar una versión antorior de MySQL a 5.0, debe actualizar primero a la versión 4.1, y luego actualizar la instalación de 4.1. a 5.0.

Una columna `Password` más amplia puede almacenar hashes de contraseñas en el antiguo y nuevo formato. El formato de cualquier valor hash de una contraseña puede determinarse de dos formas:

- La diferencia óbvia es la longitud (16 bytes contra 41 bytes).

- Una segunda diferencia es que los hashes de contraseñas en el nuevo formato simpre empieza con un carácter '`*`', mientras que una contraseña en el antiguo formato nunca lo hace.

El hash de la contraseña más larga tiene mejores propiedades criptográficas, y la autenticación de clientes basada en hashes largos es más segura que la basada en los antiguos hashes cortos.

Las diferencias entre hashes cortos y largos son relevantes para cómo el servidor usa las contraseñas durante la autenticación y por cómo genera los hashes de contraseñas para clientes conectados que realizan operaciones de cambio de contraseña.

La forma en que el servidor usa los hashes de contraseñas durante la autenticación se ve afectada por la longitud de la columna `Password` :

- Si la columna es corta, sólo se usa autenticación de hash cortos.

- Si la columna es larga, puede soportar hashes cortos o largos, y el servidor puede usar cualquier formato:

  - Clientes pre-4.1 pueden conectar, aunque sólo conocen el antiguo mecanismo de hash, pueden autenticar sólo para cuentas que tengan hashes cortos.

  - Clientes 4.1 y posterior pueden autenticar para cuentas que tengan hashes cortos o largos.

Para cuentas con hash corto, el proceso de autenticación es un poco más seguro para clientes 4.1 y posteriores que para clientes más antiguos. Respecto a seguridad, el gradienet de menos a más seguro es:

- Cliente pre-4.1 autenticando con hash de contraseña corto

- Cliente 4.1 o posterior autenticando con hash de contraseña corto.

- Cliente 4.1 o posterior autenticando con hash de contraseña largo.

La forma en que el servidor genera los hashes de contraseña para clientes conectados se ve afectado por la longitud de la columna `Password` y por la opción `--old-passwords`. Un servidor 4.1. o posterior genera hashes largos sólo si se cumplen ciertas condiciones: La columna `Password` debe ser lo suficientemente larga para guardar valores largos y no debe darse la opción `--old-passwords`. Estas condiciones se aplican como sigue:

- La columna `Password` debe ser lo suficientemente grande para guardar hashes largos (41 bytes). Si la columna no se ha actualizado y todavía tiene la longitud pre-4.1 de 16 bytes, el servidor entiende que no puede guardar hashes largos y genere sólo hashes cortos cuando un cliente realiza opraciones de cambio de contraseña mediante `PASSWORD()`, `GRANT`, o `SET PASSWORD`. Este es el comportamiento que ocurre si ha actualizado a 4.1 pero no ha ejecutado todavía el script mysql_fix_privilege_tables para ensanchar la columna `Password` .

- Si la columna `Password` es amplia, puede almacenar tanto hashes de contraseñas largos como cortos. En este caso, `PASSWORD()`, `GRANT`, y `SET PASSWORD` generan hashes largos a no ser que el servidor se haya iniciado con la opción `--old-passwords`. Este opción fuerza al servidor a generar hashes de contraseñas cortos.

El propósito de la opción `--old-passwords` es permitirle mantener compatibilidad con clientes anteriores a 4.1 bajo circunstancias donde el servidor generaría hashes de contraseñas largos. La opción no afecta la autenticación (clientes 4.1. y posteriores pueden usar cuentas que tengan hashes largos de contraseña), pero no evita la creación de hashes largos de contraseñas en la tabla `user` como resultado de una operación de cambio de contraseña. Si eso ocurre, la cuenta no puede usarse por clientes pre-4.1. Sin la opción `--old-passwords`, es posible el siguiente escenario no deseable:

- Un cliente viejo trata de conectar a una cuenta que tenga hash de contraseña corto.

- El cliente cambia su propia contraseña. Sin `--old-passwords`, esto acaba con la cuenta con un hash de contraseña largo.

- La siguiente vez que el viejo cliente trate de conectar a la cuenta, no podrá, ya que la cuenta tiene un hash de contraseña largo que requiere un nuevo mecanismo de hash durante la autenticación. (Una vez que una cuenta tiene un hash de contraseña largo en la tabla de usuario, sólo clientes 4.1. y posteriores pueden autenticar, ya que clientes pre-4.1. no entienden hashes largos.)

Este escenario ilustra que, si debe soportar clientes pre-4.1, es peligroso ejecutar un servidor 4.1 o posterior sin usar la opción `--old-passwords` . Ejecutando el servidor con `--old-passwords`, las operaciones de cambio de contraseña no generan hashes largos de contraseña y por lo tanto, no provocan que las cuentas sean inaccesibles para clientes antiguos. (Aquellos clientes no pueden bloquearse a ellos mismos mediante el cambio de su contraseña y acabando con un hash de contraseña largo.)

La desventaja de la opción `--old-passwords` es que cualquier contraseña que cree o cambie usará hashes cortos, incluso para clientes 4.1. Así, pierde la seguridad adicional proporcionada por los hashes de contraseña largos. Si quiere crear una cuenta que tiene un hash largo (por ejemplo, para usar con un cliente 4.1), debe hacerlo mientras el servidor se esté ejecutando sin `--old-passwords`.

Los siguientes escenarios son posibles al ejecutar un servidor 4.1 o posterior, incluyendo servidores MySQL 5.0:

Escenario 1:Columna `Password` corta en tabla de usuario:

- Sólo se pueden guardar hashes cortos en la columna `Password` .

- El servidor usa sólo hashes cortos durante la autenticación del cliente.

- Para clientes conectados, las operaciones de generación de hashes de contraseñas mediante `PASSWORD()`, `GRANT`, o `SET PASSWORD` usan hashes cortos exclusivamente. Cualquier cambio a una contraseña de una cuenta resulta en una cuenta teniendo un hash de contraseña corto.

- La opción `--old-passwords` puede usarse pero es supérflua ya que con una columna `Password` corta, el servidor genera sólo hashes de contraseña cortos de todas formas..

Escenario 2: Columna `Password` larga; servidor no arrancado con la opción `--old-passwords` :

- Hashes cortos o largos pueden almacenarse en la columna `Password` .

- Clientes 4.1 y posteriores (incluyendo clientes 5.0) pueden autenticar para cuentas que tengan tanto hashes cortos como largos.

- Clientes pre-4.1 pueden autenticar sólo para cuentas que tengan hashes cortos.

- Para clientes conectados, operaciones generadoras de hash como `PASSWORD()`, `GRANT`, o `SET PASSWORD` usan hashes largos exclusivamente. Un cambio en la contraseña de una cuenta resulta en dicha cuenta con un hash largo.

Como se ha indicado, un peligro en este escenario es que es posible para cuentas con hash corto quedar inaccesibles para clientes pre-4.1. Un cambio en tales contraseñas hecho via `GRANT`, `PASSWORD()`, o `SET PASSWORD` resulta en la cuenta con una contraseña larga. A partir de ahí, ningún cliente pre-4.1 puede autenticar a dicha cuenta hasta que el cliente actualice a 4.1.

Para tratar este problema, puede cambiar una contraseña de forma especial. Por ejemplo, normalmente usa `SET PASSWORD` como sigue para cambiar una contraseña de cuenta:

    mysql> SET PASSWORD FOR 'some_user'@'some_host' = PASSWORD('mypass');

Para cambiar la contraseña pero crear un hash corto, use la función `OLD_PASSWORD()` en su lugar:

    mysql> SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('mypass');

`OLD_PASSWORD()` es útil para situaciones en que explícitamente quiera generar un hash corto.

Escenario 3: Columna `Password` larga; servidor 4.1 o posterior arrancado con la opción `--old-passwords`:

- Hashes crotos o largos pueden guardarse en la columna `Password`.

- Clientes 4.1 y posteriores pueden autenticar para cuentas que tengan hashes cortos o largos ( pero tenga en cuenta que es posible crear hashes largos sólo cuando el servidor se arranca sin `--old-passwords`).

- Clientes pre-4.1 clients pueden autenticar sólo para cuentas que tengan hashes cortos.

- Para clientes conectados, operaciones de generación de hashes como `PASSWORD()`, `GRANT`, o `SET PASSWORD` usan hashes cortos exclusivamente. Cualquier cambio en la contraseña de una cuenta resulta en que dicha cuenta tenga un hash de contraseña corto.

En este escenario, no puede crear cuentas que tengan hashes de contraseña cortos, ya que la opción `--old-passwords` evita la generación de hashes largos. También, si crea una cuenta con hashes largos antes de usar la opción `--old-passwords`, cambiar la contraseña de la cuenta mientras `--old-passwords` está en efecto resulta en la cuenta teniendo una contraseña corta, causando que se pierdan los beneficios de seguridad de un hash más largo.

Las desventajas de estos escenarios pueden resumirse así:

En el escenario 1, no puede beneficiarse de hashes largos que proporcionan más seguridad de autenticación.

En el escenario 2, las cuentas con hashes cortos son inaccesibles para clientes pre-4.1 si cambia sus contraseñas sin usar explícitamente `OLD_PASSWORD()`.

En el escenario 3, `--old-passwords` evita que las cuentas con hashes cortos sean inaccesibles, pero las operaciones de cambio de contraseña causa que las cuentas con hashes largos vuelvan a ser hashes cortos, y no puede volver a hacerlos hashes largos mientras `--old-passwords` tenga efecto.

#### 5.6.9.1. Implicación del cambio en el hashing de contraseñas en aplicativos

Una actualización a MySQL 4.1 o posterior puede provocar problemas de compatibilidad para aplicaciones que usen `PASSWORD()` para generar contraseñas para sus propios propósitos. Las aplicaciones no deben hacer esto, ya que `PASSWORD()` debe usarse sólo para administrar contraseñas para cuentas MySQL. Pero algunas aplicaciones usan `PASSWORD()` para sus propios propósitos de todas formas.

Si actualiza a 4.1 o posterior desde versiones pre-4.1 de MySQL y ejecuta el servidor bajo condiciones donde genera hashes largos de contraseñas, una apliación usando `PASSWORD()` para sus propias contraseñas falla. El curso recomendado de ación en tales casos es modificar la aplicación para usar otra función, tal como `SHA1()` o `MD5()`, para producir hashes de valores. Si esto no es posible, puede usar la función `OLD_PASSWORD()` , que se proporciona para generar hashes cortos en el viejo formato. Sin embargo, debe tener en cuenta que `OLD_PASSWORD()` puede dejar de ser soportado en alguna futura versión.

Si el servidor está ejecutándose bajo circunstancias donde genera hashes cortos, `OLD_PASSWORD()` está disponible pero es equivalente a `PASSWORD()`.

Los programadores de PHP migrando sus bases de datos MySQL de la versión 4.0 o anteriores a la versión 4.1 o posterior deben consultar Old Client.

## 5.7. Gestión de la cuenta de usuario MySQL

Esta sección describe cómo preparar cuentas para clientes en su servidor MySQL. Se discuten los siguientes tópicos:

- El significado de los nombres de cuenta y contraseñas usados en MySQL y cómo se compara con los nombres y contraseñas usadas por su sistema operativo.

- Cómo preparar una nueva cuenta y borrar una existente

- Cómo camviar contraseñas

- Guías para usar contraseñas de forma segura

- Cómo usar conexiones seguras mediante SSL

### 5.7.1. Nombres de usuario y contraseñas de MySQL

Una cuenta MySQL se define en términos de un nombre de usuario y el equipo o equipos desde los que el usuario puede conectar al servidor. La cuenta también tiene una contraseña. Hay varias diferencias entre cómo se usan los nombres de usuario y contraseñas en MySQL y cómo los usa el sistema operativo:

- Los nombres de usuario, tal como los usa MySQL para autentificación, no tienen nada que ver con los nombres de usuario (nombres de logueo) tal y como los usa Windows o Unix. En Unix, la mayoría de clientes MySQL por defecto tratan de loguear usando el nombre de usuario Unix como el nombre de usuario MySQL, pero eso es sólo como conveniencia. El comportamiento por defecto puede cambiarse fácilmente, ya que el programa clienet permite especificar cualquier nombre de usuario con la opción `-u` o `--user` . Como esto significa que cualquiera puede intentar conectar al servidor usando cualquier nombre de usuario, no puede hacer una base de datos segura de ninguna forma a no ser que todas las cuentas MySQL tengan contraseña. Cualquiera que especifique un nombre de usuario para una cuenta que no tenga contraseña puede conectar al servidor.

- Nombre de usuarios en MySQL pueden tener como máximo 16 carácteres de longitudo. Este límite está hard-codeado en los servidores y clientes MySQL, y tratar de evitarlo mediante la modificación de las tablas en la base de datos `mysql` no funciona .

  Nota: Nunca debe alterar ninguna de las tablas en la base de datos `mysql` de ninguna forma excepto mediante la ejecución de los scpripts proporcionados expresamente para este propósito con la distribución MySQL. Tratar de redefinir las tablas de sistema MySQL de cualquier otra forma da como resultado un comportamiento indefinido (y no soportado).

  Nombres de usuario en el sistema operativo están completamente desligados de los nombres de usuario de MySQL y pueden tener longitud máxima diferente. Por ejemplo, los nombres de usuario Unix típicamente están limitados a 8 carácteres.

- Las contraseñas MySQL no tienen nada que ver con las contraseñas para loguear en el sistema operativo. No hay una conexión necesaria entre la contraseña que usa para entrar en una máquina Windows o Unix y la contraseña usada para acceder al servidor MySQL en esa máquina.

- MySQL encripta contraseñas usando su propio algoritmo. Esta encriptación es diferente de la usada durante el proceso de logueo de Unix. La encriptación de contraseña es la misma que la implementada en la función `PASSWORD()` . La encriptación de contraseñas Unix es la misma que la implementada por la función SQL `ENCRYPT()` . Consulte la descripción de las funciones `PASSWORD()` y `ENCRYPT()` en Sección 12.9.2, “Funciones de encriptación”. Desde la versión 4.1, MySQL usa un método más fuerte de autenticación que tiene una mejor protección de contraseña durante el proceso de conexión que en versiones anteriores. Es seguro incluso si los paquetes TCP/IP se esnifan o la base de datos `mysql` se captura. (En versiones anteriores , incluso aunque las contraseñas se guardan encriptadas en la tabla `user` , se podía usar conocimiento de la contraseña encriptada para conectar al servidor MySQL.)

Cuando instala MySQL, las tablas de permisos se inicializan con un conjunto inicial de cuentas. Estas cuentas tienen nombres y privilegios de acceso descritos en Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”, que discute cómo asignarles contraseñas. Así mismo, normalmente inicialice, modifique y borre cuentas mediante los comandos `GRANT` y `REVOKE`. Consulte Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

Cuando conecta a un servidor MySQL con un cliente de líneas de comando, puede especificar el nombre de usuario y contraseña para la cuenta que desea usar:

    shell> mysql --user=monty --password=guess db_name

Si prefiere opciones cortas, el comando es así:

    shell> mysql -u monty -pguess db_name

No deben haber espacios entre la opción `-p` y el valor de contraseña a continuación. Consulte Sección 5.6.4, “Conectarse al servidor MySQL”.

El comando precedente incluye el valor de la contraseña en la línea de comando, lo que puede ser un riesgo de seguridad. Consulte Sección 5.7.6, “Guardar una contraseña de forma segura”. Para evitarlo, especifique la opción `--password` o `-p` sin ningún valor de contraseña:

    shell> mysql --user=monty --password db_name
    shell> mysql -u monty -p db_name

A continuación, el programa cliente muestra un prompt y espera a que introduzca la contraseña. (En estos ejemplos, `db_name` no se interpreta como contraseña, ya que está separado de la precedente opción de contraseña con un espacio.)

En algunos sistemas, la llamada que MySQL usa para pedir una contraseña automáticamente limita la contraseña a ocho carácteres. Este es un problema con la librería de sistema, no con MySQL. Internamente, MySQL no tienen ningún límite para la longitud de la contraseña. Para solventar este problema, cambie su contraseña MySQL a un valor que tenga ocho o menos carácteres, o ponga su contraseña en un fichero de opciones.

### 5.7.2. Añadir nuevas cuentas de usuario a MySQL

Puede crear cuentas MySQL de dos formas:

- Usando comandos `GRANT`

- Manipulando las tablas de permisos MySQL directamente

El método preferido es usar comandos `GRANT` , ya que son más concisos y menos propenso a errores. . `GRANT` está disponible desde MySQL 3.22.11; su sintaxis se describe en Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

Otra opción para crear cuentas es usar uno de los diversos programas proporcionados por terceras partes que ofrecen capacidades para administradores de MySQL. `phpMyAdmin` es una de ellos.

Los siguientes ejemplos muestran cómo usar el programa cliente mysql para añadir nuevos usuarios. Estos ejemplos asumen que los permisos se inicializan según las pautas descritas en Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”. Esto significa que para realizar cambios, debe conectar al servidor MySQL como el usuario `root` , y la cuenta `root` debe tener el privilegio `INSERT` para la base de datos `mysql` y el permiso administrativo `RELOAD`.

En primer lugar, use el programa mysql para conectar al servidor como el usuario `root` :

    shell> mysql --user=root mysql

Si ha asignado una contraseña a la cuenta `root`, necesitará la opción `--password` o `-p` para este comando mysql y también para los mostrados a continuación en esta sección.

Tras la conexión al servidor como `root`, puede añadir nuevas cuentas. El siguiente comando usa `GRANT` para inicializar nuevas cuentas:

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

Las cuentas creadas con estos comandos `GRANT` tienen las siguientes propiedades:

- Dos de las cuentas tienen un nombre de usuario de `monty` y una contraseña de `some_pass`. Ambas cuentas son cuentas de superusuario con plenos permisos para hacer cualquier cosa. Una cuenta (`'monty'@'localhost'`) puede usarse sólo cuando se conecte desde el equipo local. La otra (`'monty'@'%'`) puede usarse para conectarse desde cualquier otro equipo. Note que es necesario tener ambas cuentas para que `monty` sea capaz de conectarse desde cualquier sitio como `monty`. Sin la cuenta `localhost`, la cuenta anónima para `localhost` creada por mysql_install_db tendría precedencia cuando `monty` conecte desde el equipo local. Como resultado, `monty` se trataría como un usuario anónimo. La razón para ello es que el usuario anónimo tiene un valor más específico en la columna `Host` que la cuenta `'monty'@'%'` y por lo tanto toma precedencia en la ordenación de la tabla `user`. (La ordenación de la tabla `user` se discute en Sección 5.6.5, “Control de acceso, nivel 1: Comprobación de la conexión”.)

- Una cuenta tiene un nombre de usuario de `admin` y no tiene contraseña. Esta cuenta puede usarse sólo desde el equipo local. Tiene los privilegios administrativos `RELOAD` y `PROCESS` . Éstos permiten al usuario `admin` ejecutar los comandos mysqladmin reload, mysqladmin refresh, y mysqladmin flush-`xxx` , así como mysqladmin processlist . No se dan permisos para acceder a ninguna base de datos. Puede añadir tal privilegio posteriormente mediante un comando `GRANT` adicional.

- Una cuenta tiene un nombre de usuario de `dummy` sin contraseña. Esta cuenta puede usarse sólo desde el equipo local. No tiene ningún privilegio. El permiso `USAGE` en el comando `GRANT` permite crear una cuenta sin darle ningún privilegio. Tiene el efecto de inicializar todos los privilegios globales a `'N'`. Se asume que se otorgarán privilegios específicos posteriormente.

Como alternativa a `GRANT`, puede crear la misma cuenta directamente mediante comandos `INSERT` y después diciendo al servidor que recargue las tablas de permisos usando `FLUSH PRIVILEGES`:

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

La razón de usar `FLUSH PRIVILEGES` al crear cuantas con `INSERT` es decir al servidor que vuelva a leer las tablas de permisos. De otro modo, los cambios no se tienen en cuenta hasta que se reinicie el servidor. Con `GRANT`, `FLUSH PRIVILEGES` no es necesario.

La razón para usar la función `PASSWORD()` con `INSERT` es encriptar las contraseñas. El comando `GRANT` encripta la contraseña, así que `PASSWORD()` no es necesario.

El valor `'Y'` activa permisos para las cuentas. Para la cuenta `admin` , puede emplear la sintaxis más clara extendida `INSERT` usando `SET`.

En el comando `INSERT` para la cuenta `dummy` account, sólo las columnas `Host`, `User`, y `Password` en el registro de la tabla `user` tienen valores asignados. Ninguna de las columnas de permisos se asignan explícitamente, así que MySQL les asigna a todas el valor por defecto de `'N'`. Esto es equivalente al funcionamiento de `GRANT USAGE`.

Para inicializar una cuenta de super usuario, sólo es necesario crear una entrada en la tabla `user` con las columnas de permisos inicializadas a `'Y'`. Los privilegios de la tabla `user` son globales, así que no se necesitan registros en ninguna de las otras tablas de permisos.

Los siguientes ejemplos crean tres cuentas y les dan acceso a bases de datos específicas. Cada una de ellas tiene un nombre de usuario `custom` y contraseña `obscure`.

Para crear las cuentas con `GRANT`, use los siguientes comandos:

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

Las tres cuentas pueden usarse de la siguiente manera:

- La primera cuenta puede acceder a la base de datos `bankaccount`, pero sólo desde el equipo local.

- La segunda cuenta puede acceder la base de datos `expenses`, pero sólo desde el equipo `whitehouse.gov`.

- La tercera cuenta puede acceder la base de datos `customer`, pero sólo desde el equipo `server.domain`.

Para inicializar las cuentas `custom` sin usar `GRANT`, use los comandos `INSERT` como se explica para modificar las tablas de permisos directamente:

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

Los primeros tres comandos `INSERT` añaden registros en la tabla `user` que permiten al usuario `custom` conectar desde los equipos con la contraseña dada, pero no otorga privilegios blobales (todos los privilegios se inicializan al valor por defecto `'N'`). Los siguientes tres comandos `INSERT` añaden registros en la tabla `db` que otorgan privilegios a `custom` para las bases de datos `bankaccount`, `expenses`, y `customer`, pero sólo cuando se accede desde los equipos apropiados. Como siempre, cuando modifique las tablas de permisos directamente, debe decirle al servidor que las recargue con `FLUSH PRIVILEGES` para que los cambios en los permisos tengan efecto.

Si quiere dar a un usuario específico acceso desde todas las máquinas dentro de un dominio dado (por ejemplo, `mydomain.com`), puede realizar un comando `GRANT` que use el carácter comodín '`%`' en la parte del equipo del nombre de cuenta:

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

Para hacer lo mismo modificando las tablas de permisos directamente, haga lo siguiente:

    mysql> INSERT INTO user (Host,User,Password,...)
        ->     VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);
    mysql> FLUSH PRIVILEGES;

### 5.7.3. Eliminar cuentas de usuario de MySQL

Para eliminar una cuenta, use el comando `DROP USER` , descrito en Sección 13.5.1.2, “Sintaxis de `DROP USER`”.

### 5.7.4. Limitar recursos de cuentas

Una forma de limitar los recursos de los servidores MySQL es asignar a la variable de sistema `max_user_connections` un valor distinto de cero. Sin embargo,este método es estrictamente global, y no está permitido para la administración de cuentas individuales. Además, limita sólo el número de conexiones simultáneas hechas usando una sóla cuenta, y no lo que un cliente puede hacer una vez conectado. Ambos tipos de control son interesantes para muchos administradores de MySQL, particularmente aquéllos que trabajan en ISPs.

En MySQL 5.0, puede limitar los siguientes recursos de servidor para cuentas individuales:

- El número de consultas que una cuenta puede realizar por hora

- El número de actualizaciones que una cuenta puede hacer por hora

- El número de veces que una cuenta puede conectar con el servidor por hora

Cualquier comando que un cliente puede realizar cuenta en el límite de consultas. Sólo los comandos que modifiquen la base de datos o las tablas cuentan en el límite de actualizaciones.

Desde MySQL 5.0.3, es posible limitar el número de conexiones simultáneas al servidor por cuenta.

Una cuenta en este contexto es un registro en la tabla `user` . Cada cuenta se identifica unívocamente por los valores de las columnas `User` y `Host`.

Como prerrequisito para usar esta característica, la tabla `user` en la base de datos `mysql` debe contener las columnas relacionadas con el recurso. Los límites de recursos se guardan en las columnas `max_questions`, `max_updates`, `max_connections`, y `max_user_connections` . Si su tabla `user` no tiene estas columnas, debe actualizarla; consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

Para cambiar el límite de recursos con un comando `GRANT` use la cláusula `WITH` que nombra cada recurso a ser limitado y un contador por hora indicando el valor límite. Por ejemplo, para crear una nueva cuenta que pueda acceder a la base de datos `customer`, pero sólo de forma limitada, utilice este comando:

    mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
        ->     IDENTIFIED BY 'frank'
        ->     WITH MAX_QUERIES_PER_HOUR 20
        ->          MAX_UPDATES_PER_HOUR 10
        ->          MAX_CONNECTIONS_PER_HOUR 5
        ->          MAX_USER_CONNECTIONS 2;

No todos los tipos de límites necesitan nombrarse en la cláusula `WITH`, pero los nombrados pueden presentarse en cualquier orden. El valor para cada límite por hora debe ser un entero representando el contador por hora. Si el comando `GRANT` no tiene cláusula `WITH`, los límites se inicializan con el valor por defecto de cero (o sea, sin límite). Para `MAX_USER_CONNECTIONS`, el límite es un entero indicando el máximo número de conexiones simultáneas que la cuenta puede hacer en cualquier momento. Si el límite asignado es el valor por defecto de cero, la variable de sistema `max_user_connections` determina el número de conexiones simultáneas para la cuenta.

Para inicializar o cambiar los límites de una cuenta existente, use un comando `GRANT USAGE` a nivel global (`ON *.*`). El siguiente comando cambia el límite de consultas para `francis` a 100:

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_QUERIES_PER_HOUR 100;

Este comando deja los permisos existentes de la cuenta inalterados y modifica sólo los valores cuyo límite se especifica.

Para eliminar un límite existente, ponga su valor a cero. Por ejemplo, para eliminar el límite de cuántas veces por hora puede conectar `francis` , use este comando:

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

El conteo del uso de recursos toma lugar cuando una cuenta tiene un límite distinto a cero para el uso de cualquier recurso.

Mientras el servidor está en ejecución, cuenta el número de veces que cada cuenta usa los recursos. Si una cuenta llega a su límite en el número de conexiones en la última hora, se rechazan cualquier intento de conexión mientras dure la hora. De forma similar, si la cuenta llega a su límite de consultas o actualizaciones, consultas o actualizaciones adicionales se rechazan mientras dure la hora. En cualquier caso, se muestra el mensaje de error apropiado

El conteo de recursos se hace por cuenta, no por cliente. Por ejemplo, si una cuenta tiene un límite de 50 consultas, no puede incrementar el límite a 100 haciendo dos conexiones simultáneas al servidor. Las consultas de ambas conexiones se cuentan juntas.

El contador actual por hora de uso de recursos puede reiniciarse globalmente para todas las cuentas, o individualmente para una cuenta dada:

- Para reiniciar los contadores actuales a cero para todas las cuentas, ejecute el comando `FLUSH USER_RESOURCES`. Los contadores también pueden reiniciarse recargando las tablas de permisos (por ejemplo,k con un comando `FLUSH PRIVILEGES` o mysqladmin reload).

- Los contadores para una cuenta individual pueden ponerse a cero cambiando cualquiera de sus límites. Para hacerlo, use `GRANT USAGE` como se ha descrito anteriormente y especifique un valor límtite igual al valor que tiene la cuenta en ese momento.

Los reinicios de contadores no afectan el límite `MAX_USER_CONNECTIONS` .

Todos los contadores empiezan a cero cuando el servidor arranca; los contadores no se guardan al reiniciar.

### 5.7.5. Asignar contraseñas a cuentas

Se pueden asignar contraseñas desde la línea de comandos usando el comando mysqladmin :

    shell> mysqladmin -u nombres_usuario -h equipo password "nuevacontr"

La cuenta para la que este comando cambia la contraseña es la que tiene un registro en la tabla `user` que coincida el `user_name` con la columna `User` y un equipo cliente desde el que se conecta en la columna `Host`.

Otra forma de asignar una contraseña en una cuenta es con el comando `SET PASSWORD` :

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

Sólo los usuarios tales como `root` con acceso de modificación para la base de datos `mysql` puede cambiar la contraseña de otro usuario. Si no está conectado como un usuario anónimo, puede cambiar su propia contraseña omitiendo la cláusula `FOR` :

    mysql> SET PASSWORD = PASSWORD('biscuit');

Puede usar el comando `GRANT USAGE` globalmente (`ON *.*`) para asignar una contraseña a una cuenta sin afectar los permisos actuales de la cuenta:

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

Aunque generalmente es peferible asignar contraseñas usando uno de los métodos precedentes, puede hacerlo modificando la tabla `user` directamente:

- Para establecer una contraseña al crear una nueva cuenta, especifique un valor para la columna `Password`:

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

- Para cambiar la contraseña en una cuenta existente, use `UPDATE` para especificar el valor de la columna `Password`:

      shell> mysql -u root mysql
      mysql> UPDATE user SET Password = PASSWORD('bagel')
          -> WHERE Host = '%' AND User = 'francis';
      mysql> FLUSH PRIVILEGES;

Cuando especifique una contraseña en una cuenta mediante `SET PASSWORD`, `INSERT`, o `UPDATE`, debe usar la función `PASSWORD()` para encriptarlo. (La única excepción es que no necesita usar `PASSWORD()` si la contraseña está vacía .) `PASSWORD()` es necesario ya que la tabla `user` guarda las contraseñas encriptadas, no en texto plano. Si olvida este hecho, es posible que guarde contraseñas así:

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

El resultado es que el valor literal `'biscuit'` se guarda como contraseña en la tabla `user`, no el valor encriptado. Cuando `jeffrey` trate de conectar al servidor usando esta contraseña, el valor se encripta y se compara con el valor guardado en la tabla `user`. Sin embargo, el valor guardado es la cadena de carácteres literal `'biscuit'`, así que la comparación falla y el servidor rechaza la conexión:

    shell> mysql -u jeffrey -pbiscuit test
    Access denied

Si inicializa la contraseña usando el comando `GRANT ... IDENTIFIED BY` o mysqladmin password , ambos encriptan la contraseña. En estos casos, el uso de la función `PASSWORD()` no es necesario.

Nota: La encriptación de `PASSWORD()` es diferente a la encriptación de contraseñas Unix. Consulte Sección 5.7.1, “Nombres de usuario y contraseñas de MySQL”.

### 5.7.6. Guardar una contraseña de forma segura

A nivel administrativo, nunca debería otorgar acceso para la tabla `mysql.user` a ninguna cuenta no administrativa.

Cuando ejecuta un programa cliente para conectarse al servidor MySQL, es desaconsejable especificar la clave de manera que sea visible o posible de averiguar para otros usuarios. Los métodos que debe utilizar para especificar su clave cuando ejecuta programas clientes son enumerados aquí, junto con una valoración de los riesgos de cada método:

- Utilice la opción `-p`your_pass`` o `--password=`your_pass`` en la línea de comandos. Por ejemplo:

      shell> mysql -u francis -pfrank db_name

  Esto es conveniente pero inseguro, porque la clave se vuelve visible para programas de consulta del estado del sistema, como ps que pueden ser invocados por otros usuarios para mostrar líneas de comando. Los clientes de MySQL normalmente sobreescriben el parámetro de la clave en la línea de comandos con ceros durante la secuencia de inicialización, pero aún así hay un breve intervalo de tiempo en que el valor es visible.

- Utilice la opción `-p` o `--password` sin especificar ningún valor para la clave. En este caso, el programa cliente solicita la clave desde el terminal:

      shell> mysql -u francis -p db_name
      Enter password: ********

  Los carácteres '`*`' indican donde se introduce la clave. La clave no se muestra mientras se está introduciendo.

  Es más seguro introducir la clave de esta manera que especificarla en la línea de comandos, porque así no es visible a otros usuarios. No obstante, este método es tan solo aplicable para programas que se ejecutan de manera interactiva. Si quiere invocar un programa cliente desde un script que no se ejecute interactivamente, no hay oportunidad de introducir la clave mediante el terminal. En algunos sistemas, incluso podría darse que la primera línea del script sea leida e interpretada (incorrectamente) como la clave.

- Almacene su clave en un archivo de opciones. Por ejemplo, en Unix puede introducir su clave en la sección `[client]` del archivo `.my.cnf` de su directorio personal.

      [client]
      password=your_pass

  Si almacena su calve en `.my.cnf`, el archivo no debería ser accesible para nadie más que usted. Para asegurarse de esto, establezca el modo de acceso del archivo a `400` o `600`. Por ejemplo:

      shell> chmod 600 .my.cnf

  Sección 4.3.2, “Usar ficheros de opciones” habla sobre los archivos de opciones con más detalle.

- Almacene su clave en la variable de entorno `MYSQL_PWD`. Este método de especificar su clave MySQL debe ser considerado extremadamente inseguro y no debería ser utilizado. Algunas versiones de ps incluyen una opción para mostrar las varialbes de entorno de los procesos en ejecución. Si establece `MYSQL_PWD`, su clave estará expuesta a cualquier otro usuario que ejecute ps. Aún en sistemas con una versión tal de ps, no es inteligente asumir que no habrá cualquier otro método mediante el cual los usuarios puedan examinar las variables de entorno. Consulte Apéndice E, Variables de entorno.

De todas maneras, la manera más segura de hacerlo es, o bien hacer que el programa cliente pregunte por la clave, o especificarla en un archivo de opciones protegido.

### 5.7.7. Usar conexiones seguras

MySQL 5.0 incluye soporte para conexiones seguras (cifradas) entre los clientes MySQL y el servidor, utilizando el protocolo SSL (Secure Sockets Layer). Esta sección explica como utilizar conexiones SSL. También explica una manera de configurar SSH en Windows.

La configuración estándard de MySQL tiene la misión de ser tan rápida como sea posible, así que no se usan las conexiones cifradas por defecto. Hacerlo, haría que el protocolo cliente/servidor fuese mucho más lento. Cifrar datos es una operación que requiere un uso intensivo de CPU, y por tanto obliga a la máquina a realizar trabajo adicional que retrasa otras tareas de MySQL. Para aplicaciones que requieran la seguridad que proveen las conexiones cifradas, el trabajo de computación extra está justificado.

MySQL permite que el cifrado sea activado para conexiones individuales. Puede escoger entre una conexión normal sin cifrar, o una segura cifrada mediante SSL dependiendo de los requerimientos de las aplicaciones individuales.

#### 5.7.7.1. Conceptos básicos de SSL

Para entender como MySQL utiliza SSL, es necesario explicar algunos conceptos básicos sobre SSL y X509. Aquellos ya familiarizados con ellos, pueden saltarse esta parte.

Por defecto, MySQL utiliza conexiones sin cifrar entre el cliente y el servidor. Esto significa que cualquiera con acceso a la red podría ver el tráfico y mirar los datos que están siendo enviados o recibidos. Incluso podría cambiar los datos mientras están aún en tránsito entre el cliente y el servidor. Para mejor la seguridad un poco, puede comprimir el tráfico entre el cliente y el servidor utilizando la opción `--compress` cuando ejecute programas cliente. No obstante, esto parará a un atacante con determinación.

Cuando necesita mover información sobre una red de una manera segura, una conexión sin cifrar es inaceptable. El cifrado es la manera de hacer que cualquier dato sea ilegible. De hecho, hoy en día la prácitca requiere muchos elementos adicionales de seguridad en los algoritmos de cifrado. Deben resistir muchos tipos de ataques conocidos.

El protocolo SSL utiliza diferentes algoritmos de cifrado para asegurarse de que los datos recibidos a través de una red pública son seguros. Tiene mecanismos para detectar cambios de datos, pérdidas, o reenvíos. SSL también incorpora algoritmos que proveen de verificación de identidad, utilizando el estándard X509.

X509 hace posible identificar a alguien en Internet. Es utilizado comúnmente en aplicaciones de comercio electrónico. En resumen, debe haber alguna compañía, llamada ``Autoridad Certificada'' (CA) que asigna certificados electrónicos a cualquiera que los necesita. Los certificados se basan en algoritmos de cifrado asimétricos que tienen dos claves de cifrado (una pública, y otra secreta). El propietario de un certificado puede enseñarselo a otra entidad como prueba de su identidad. Un certificado consiste en la clave pública de su propietario. Cualquier dato cifrado con esta clave pública puede ser solo cifrada utilizando la clave secreta correspondiente, que está en posesión del propietario del certificado.

Si necesita más información sobre SSL, X509, o cifrado, utilice su buscador de Internet favorito para buscar las palabras clave en que esté interesado.

#### 5.7.7.2. Requisitos (OpenSSL)

Para utilizar conexiones SSL entre el servidor MySQL y los programas cliente, su sistema debe tener la capacidad de ejecutar OpenSSL y su versión de MySQL debe ser la 4.0.0 o superior.

Para conseguir que las conexiones seguras funcionen con MySQL, debe hacer lo siguiente:

1. Instale la librería OpenSSL. MySQL ha sido comprobado con OpenSSL 0.9.6. Si necesita OpenSSL, visite http://www.openssl.org.

2. Cuando configure MySQL, ejecute el script configure con las opciones `--with-vio` y `--with-openssl`.

3. Asegúrese de que ha actualizado sus tablas grant para que las columnas relacionadas con SSL de la tabla `mysql.user` se hayan agregado. Esto es necesario si las tablas grant provienen de una versión de MySQL anterior a la 4.0.0. El procedimiento de actualización se explica en Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

4. Para comprobar si un servidor mysqld que se está ejecutando tiene soporte para OpenSSL, examine el valor de la variable de sistema `have_openssl`:

       mysql> SHOW VARIABLES LIKE 'have_openssl';
       +---------------+-------+
       | Variable_name | Value |
       +---------------+-------+
       | have_openssl  | YES   |
       +---------------+-------+

   Si el valor es `YES`, el servidor tiene soporte para conexiones OpenSSL.

#### 5.7.7.3. Montar certificados SSL para MySQL

Aquí tiene un ejemplo para configurar certificados SSL para MySQL:

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

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

    # Create necessary files: $database, $serial and $new_certs_dir
    # directory (optional)

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

    #
    # Generation of Certificate Authority(CA)
    #

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

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

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

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

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

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

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

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

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

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

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

    #
    # Sign client cert
    #

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

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

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

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

Para comprobar las conexiones SSL, inicie el servidor de la siguiente manera, donde `$DIR` es la ruta a el directorio donde está el archivo de opciones de ejemplo `my.cnf`:

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

Entonces ejecute un programa cliente utilizando el mismo archivo de opciones:

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

Si tiene una distribución de código fuente de MySQL, usted puede tambier comprobar su configuración modificando el archivo `my.cnf` precedente para que se refiera al certificado y los archivos de claves en el directorio `SSL` de la distribución.

#### 5.7.7.4. Opciones SSL de `GRANT`

MySQL puede comprobar los atributos de un certificado X509 además de la autentificación usual que se basa en nombre de usuario y clave. Para especificar las opciones relacionadas con SSL para una cuenta MySQL, utilice la clausula `REQUIRE` de la sentencia `GRANT`. Consulte Sección 13.5.1.3, “Sintaxis de `GRANT` y `REVOKE`”.

Hay diferentes maneras de limitar los tipos de conexión para una cuenta:

- Si una cuenta no tiene requerimientos de SSL o X509, las conexiones sin cifrar se permiten siempre que el nombre de usuario y la clave sean válidas. De cualquier manera, se pueden también utilizar conexiones cifradas, si el cliente tiene los certificados y archivos de claves apropiados.

- La opción `REQUIRE SSL` limita al servidor para que acepte únicamente conexiones cifradas SSL para la cuenta. Tenga en cuenta que esta opción puede pasarse por alto si hay algún registro ACL que permite conexiones no-SSL.

      mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
          -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;

- `REQUIRE X509` significa que el cliente debe tener un certificado pero que el certificado exacto, entidad certificadora y sujeto no importan. El único requerimiento es que debería ser posible verificar su firma con uno de los certificados CA.

      mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
          -> IDENTIFIED BY 'goodsecret' REQUIRE X509;

- `REQUIRE ISSUER 'issuer'` coloca una restricción en la conexión mediante la cual el cliente debe presentar un certificado X509 válido, emitido por la CA `'issuer'`. Si el cliente presenta un certificado que es valido pero tiene un emisor diferente, el servidor rechaza la conexión. La utilización de certificados X509 siempre implica cifrado, así que la opción `SSL` no es necesaria.

      mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
          -> IDENTIFIED BY 'goodsecret'
          -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
             O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';

  Nótese que el valor de `ISSUER` debe introducirse como una única cadena de carácteres.

- `REQUIRE SUBJECT 'subject'` establece la restricción a los intentos de conexión de que el cliente debe presentar un certificado X509 válido con sujeto `'subject'`. Si el cliente presenta un certificado que, aunque válido, tiene un sujeto diferente, el servidor rechaza la conexión.

      mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
          -> IDENTIFIED BY 'goodsecret'
          -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
             O=MySQL demo client certificate/
             CN=Tonu Samuel/Email=tonu@example.com';

  Nótese qeu el valor de `SUBJECT` debe ser introducido como una única cadena de carácteres.

- `REQUIRE CIPHER 'cipher'` es necesario para asegurar que se utilizan longitudes de cifra y claves suficientemente fuertes. El protocolo SSL por sí mismo puede ser débil si se utilizan viejos algorimots con claves de cifrado cortas. Utilizando esta opción, podemos pedir un método exacto de cifrado para permitir una conexión.

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

Las opciones `SUBJECT`, `ISSUER`, y `CIPHER` pueden combinarse en la sentencia `REQUIRE` de la siguiente manera:

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

Nótese qeu los valores de `SUBJECT` e `ISSUER` deben ser introducidos cada uno como una única cadena de carácteres.

En MySQL 5.0, la palabra clave `AND` es opcional entre las opciones de `REQUIRE`.

El orden de las opciones no importa, pero ninguna opción puede ser especificada dos veces.

#### 5.7.7.5. Opciones relativas a SSL

La siguiente lista explica las opciones que se utilizan para especificar la utilización de SSL, y archivos de certificados y calves. Se pueden introducir en línea de comandos, o mediante un archivo de opciones.

- `--ssl`

  Para el servidor, esta opción especifica que el servidor permite conexiones SSL. Para un programa cliente, permite al cliente que se conecte al servidor utilizando SSL. Esta opción no es suficiente por si sola para causar que se utilice una conexión SSL. También se deben especificar las opciones `--ssl-ca`, `--ssl-cert`, y `--ssl-key`.

  Esta opción se utiliza más frecuentemente en su forma contraria para indicar que SSL no debe utilizarse. Para hacer esto, especifique la opción como `--skip-ssl` o `--ssl=0`.

  Nótese que el uso de `--ssl` no requiere una conexión SSL. Por ejemplo, si el servidor o el cliente han sido compilados sin soporte para conexiones SSL, se utilizará una conexión normal sin cifrar.

  La manera más confiable de asegurarse de que se utiliza una conexión SSL es crear una cuenta en el servidor que incluya la clausula `REQUIRE SSL` en la sentencia `GRANT`. Then use this account to connect to the server, with both a server and client that have SSL support enabled.

- `--ssl-ca=`file_name``

  La ruta a un archivo con una lista de CAs SSL en las que se confía.

- `--ssl-capath=`directory_name``

  La ruta a un direcotrio que contiene certificados de CA confiables en formato pem.

- `--ssl-cert=`file_name``

  El nombre del archivo de certificado SSL a utilizar para establecer una conexión segura.

- `--ssl-cipher=`cipher_list``

  Una lista de cifras permisibles para usar en el cifrado SSL. `cipher_list` tiene el mismo formato que el comando `openssl ciphers`.

  Ejemplo: `--ssl-cipher=ALL:-AES:-EXP`

- `--ssl-key=`file_name``

  El nombre del archivo de clave SSL utilizado para establecer una conexión segura.

#### 5.7.7.6. Conectarse desde Windows a MySQL remotamente con SSH

Aquí hay una nota sobre como conectar para obtener una conexión segura a un servidor MySQL remoto mediante SSH (por David Carlson `<dcarlson@mplcomm.com>`):

1. Instale un cliente SSH en su máquina Windows. Como usuario, el mejor cliente no-libre que he encontrado es el `SecureCRT` de http://www.vandyke.com/. Otra opción es `f-secure` de http://www.f-secure.com/. También puede encontrar algunos libres mediante `Google` en http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/.

2. Ejecute su cliente SSH Windows. Establezca `Host_Name = URL_o_IP_suservidormysql`. Establezca `userid=su_id_usuario` para entrar al servidor. Este nombre de usuario podría no ser el mismo que el de su cuenta MySQL.

3. Establezca la redirección de puertos. Ya sea una redirección remota (Estableciendo `local_port: 3306`, `remote_host: yourmysqlservername_or_ip`, `remote_port: 3306` ) o una redirección local (Estableciendo `port: 3306`, `host: localhost`, `remote port: 3306`).

4. Guarde todo, si no es así, tendrá que rehacerlo la próxima vez.

5. Entre en su servidor con la sesión SSH que acaba de crear.

6. En su máquina Windows, ejecute alguna aplicación ODBC (como Access).

7. Cree un nuevo archivo en Windows y enlácelo a MySQL utilizando el driver ODBC de la misma manera que lo haría normalmente, excepto que debe escribir `localhost` para el nombre de servidor MySQL, no `yourmysqlservername`.

Debería tener una conexión ODBC a MySQL, cifrada utilizando SSH.

## 5.8. Prevención de desastres y recuperaciones

Esta sección explica como hacer copias de seguridad (completas e incrementales) y como realizar mantenimiento de tablas. La sintaxis de las sentencias SQL descritas aquí se detalla en Sección 13.5, “Sentencias de administración de base de datos”. La mayor parte de la información aquí contenida se aplica principalmente a tablas `MyISAM`. Los procedimientos de copia de seguridad para `InnoDB` se explican en Sección 15.8, “Hacer una copia de seguridad y recuperar una base de datos `InnoDB`”.

### 5.8.1. Copias de seguridad de bases de datos

Debido a que las tablas de MySQL se almacenan como archivos, es fácil hacer una copia de seguridad. Para hacer una copia consistente haga un `LOCK TABLES` en las tablas relevantes, seguido de un `FLUSH TABLES` para las tablas. Consulte Sección 13.4.5, “Sintaxis de `LOCK TABLES` y `UNLOCK TABLES`” y Sección 13.5.5.2, “Sintaxis de `FLUSH`”. Solo necesita obtener un bloqueo de lectura; esto permite a otros clientes continuar consultando la tabla mientras usted está haciendo una copia de los archivos del directorio de la base de datos. La sentencia `FLUSH TABLES` es necesaria para asegurarse de que todas las páginas de índice activas se escriben al disco antes de qeu comience la copia.

Si quiere hacer una copia de una tabla a un nivel SQL, puede utilizar `SELECT INTO ... OUTFILE` o `BACKUP TABLE`. Para `SELECT INTO ... OUTFILE`, el archivo de salida no debe existir previamente. Esto también es cierto para `BACKUP TABLE`, ya que permitir que archivos externos sean sobreescritos sería un riesgo de seguridad. Consulte Sección 13.2.7, “Sintaxis de `SELECT`” y Sección 13.5.2.2, “Sintaxis de `BACKUP TABLE`”.

Otra técnica para hacer copias de seguridad de una base de datos es utilizar el programa mysqldump o el script mysqlhotcopy script. Consulte See Sección 8.7, “El programa de copia de seguridad de base de datos mysqldump” y Sección 8.8, “El programa de copias de seguridad de base de datos mysqlhotcopy”.

1. Hacer una copia completa de su base de datos:

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

   O:

       shell> mysqlhotcopy db_name /path/to/some/dir

   También puede simplemente copiar todos los archivos de tablas (`*.frm`, `*.MYD`, y `*.MYI`) siempre que el servidor no esté actualizando nada. El script mysqlhotcopy utiliza este método. (Pero tenga en cuenta que estos métodos no funcionan si su base de datos contiene tablas `InnoDB`. `InnoDB` no almacena los contenidos de las tablas en directorios de base de datos, y mysqlhotcopy funciona solo para tablas `MyISAM` e `ISAM`.)

2. Pare mysqld si se está ejecutando, y después reinicielo con la opción `--log-bin[=file_name]`. Consulte Sección 5.10.3, “El registro binario (Binary Log)”. Los archivos binarios de registro le dan la información que necesita para replicar los cambios que se han producido en la base de datos tras el punto en que usted ejecutó mysqldump.

Para las tablas `InnoDB` es posible realizar una copia de seguridad en línea que no requiere bloqueos en las tablas; consulte Sección 8.7, “El programa de copia de seguridad de base de datos mysqldump”

MySQL tiene soporte para copias de seguridad incrementales: Usted necesita iniciar el servidor con la opción `--log-bin` para activar el registro binario; consulte Sección 5.10.3, “El registro binario (Binary Log)”. En el momento en que usted quiera realizar una copia de seguridad incremental (que contenga todos los cambios que han ocurrido desde la última copia de seguridad, completa o incremental), usted debe rotar el registro binario utilizando `FLUSH LOGS`. Hecho esto, necesita copiar a la localización de seguridad todos los registros binarios que daten desde el momento de la última copia de seguridad hasta el último. Estos logs binarios son la copia de seguridad incremental; cuando necesite restaurar la copia, los puede aplicar tal como se explica más adelante. La próxima vez que haga una copia de seguridad compelta, también debe rotar el registro binario haciendo `FLUSH LOGS`, `mysqldump --flush-logs`, o `mysqlhotcopy --flushlogs`. Consulte Sección 8.7, “El programa de copia de seguridad de base de datos mysqldump” y Sección 8.8, “El programa de copias de seguridad de base de datos mysqlhotcopy”.

Si su servidor MySQL es un servidor esclavo de replicación, entonces independientemente del método de copia de seguridad que elija, también debe copiar los archivos `master.info` y `relay-log.info` cuando copie los datos de su esclavo. Estos archivos son siempre necesarios para continuar la replicación después de una restauración de los datos del esclavo. Si su esclavo está replicando comandos `LOAD DATA INFILE`, debería también copiar cualquier archivo `SQL_LOAD-*` que pueda existir en el directorio especificado por la opción `--slave-load-tmpdir`. (Esta localización es por defecto el valor de la variable `tmpdir`, si no se especifica.) El esclavo necesita estos archivos para reiniciar la replicación de cualquier operación `LOAD DATA INFILE` interrumpida.

Si tiene que restaurar tablas `MyISAM`, intente recuperarlas utilizando `REPAIR TABLE` o myisamchk -r primero. Esto debería funcionar en el 99.9% de los casos. Si myisamchk falla, intente el siguiente procedimiento. Tenga en cuenta que solo funciona si tiene activado el registro binario iniciando el servidor MySQL con la opción `--log-bin`; consulte Sección 5.10.3, “El registro binario (Binary Log)”.

1. Restaure la copia de seguridad original de mysqldump, o la copia de seguridad binaria.

2. Ejecute el siguiente comando para ejecutar de nuevo las actualizaciones de los registros binarios:

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

   En algunos casos, quizá quiera reejecutar solo ciertos registros binarios, desde ciertas posiciones (lo usual es querer reejecutar todos los registros binarios desde el punto de restauración, excepto, posiblemente, algunas sentencias incorrectas). Consulte Sección 8.5, “La utilidad mysqlbinlog para registros binarios” para más información sobre la utilidad mysqlbinlog y como utilizarla.

También puede hacer copias de seguridad selectivas de archivos individuales:

- Para volcar la tabla, utilice `SELECT * INTO OUTFILE '`file_name`' FROM `tbl_name``.

- Para recargar la tabla, restaurela con `LOAD DATA INFILE 'file_name' REPLACE ...` Para evitar registros duplicados, la tabla tiene que tener un índice `PRIMARY KEY` o `UNIQUE`. La palabra clave `REPLACE` hace que los viejos registros sean reemplazados con los nuevos cuando un nuevo registro tiene la misma clave que uno antiguo.

Si tiene problema de rendimientos con su servidor mientras realiza copias de seguridad, una estrategia que puede ayudarle es crear replicación y hacer las copias de seguridad en el esclavo en vez de en el maestro. Consulte Sección 6.1, “Introducción a la replicación”.

Si está utilizando un sistema de ficheros Veritas, puede hacer una copia de seguridad así:

1. Desde un programa cliente, ejecute `FLUSH TABLES WITH READ LOCK`.

2. Desde otra línea de comandos, ejecute `mount vxfs snapshot`.

3. Desde el primer cliente, ejecute `UNLOCK TABLES`.

4. Copie los archivos de la captura (snapshot).

5. Desmonte la captura.

### 5.8.2. Ejemplo de estrategia de copias de seguridad y recuperación

Esta sección explica un procedimiento para realizar copias de seguridad que le permiten recuperar datos tras diferentes tipos de problemas:

- Fallo del sistema operativo

- Fallo de energía

- Fallo del sistema de ficheros

- Problema de hardware (disco duro, placa madre, etc)

Los comandos de ejemplo no incluyen opciones como `--user` y `--password` para los programas mysqldump y mysql. Usted debería incluir las opciones que sean necesarias para que el servidor MySQL le permita conectarse.

Asumiremos que los datos están almacenados en el motor `InnoDB` de MySQL, que tiene soporte para transacciones y recuperación automática de fallos. Siempre asumiremos que el servidor MySQL está bajo carga de trabajo en el momento del fallo. Si no fuera así, no se necesitaría ninguna recuperación.

Para casos de fallos de energía o de sistema operativo, podemos asumir que el disco de datos de MySQL está disponible tras el reinicio. Puede que entonces los archivos de datos de `InnoDB` no contengan datos consistentes debido al fallo, pero `InnoDB` lee sus registros y encuentra en ellos la lista de transacciones confirmadas y no confirmadas qeu todavía no han sido volcadas a sus archivos de datos, y los vuelca. La información sobre este proceso de recuperación de errores se le muestra al usuario a través del registro de errores de MySQL. Lo siguiente, es un extracto de ejemplo del registro:

    InnoDB: Database was not shut down normally.
    InnoDB: Starting recovery from log files...
    InnoDB: Starting log scan based on checkpoint at
    InnoDB: log sequence number 0 13674004
    InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
    InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
    InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
    InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
    ...
    InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
    InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
    InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
    InnoDB: 1 uncommitted transaction(s) which must be rolled back
    InnoDB: Starting rollback of uncommitted transactions
    InnoDB: Rolling back trx no 16745
    InnoDB: Rolling back of trx no 16745 completed
    InnoDB: Rollback of uncommitted transactions completed
    InnoDB: Starting an apply batch of log records to the database...
    InnoDB: Apply batch completed
    InnoDB: Started
    mysqld: ready for connections

En casos de fallos del sistema de fichero o de hardware, podemos asumir que el disco de datos de MySQL no está disponible tras el reinicio. Esto significa que MySQL no puede arrancar normalmente porque algunos bloques de datos del disco no son legibles. En este caso, es necesario reformatear el disco, instalar uno nuevo, o en cualquier caso, corregir el problema subyacente. Después es necesario recuperar nuestros datos de MySQL desde copias de seguridad, lo que significa que tenemos que tener copias ya realizadas. Para asegurarse de que sea así, vayamos hacia atrás en el tiempo y diseñemos una política de copias de seguridad.

#### 5.8.2.1. Política de copias de seguridad

Todos sabemos que las copias de seguridad deben programarse periodicamente. Las copias completos (una captura del estado de los datos en un momento del tiempo) puede hacerse con diferentes herramientas, en MySQL. Por ejemplo, `InnoDB Hot Backup` nos provee con una copia de seguridad en línea sin bloqueos de los archivos de datos de `InnoDB`, y con mysqldump obtenemos copias de seguridad lógicas online. En esta explicación utilizaremos mysqldump.

Supongamos que hacemos una copia de seguridad el domingo, a las 1 PM, cuando la carga es baja. El siguiente comando hace un hace una copia de seguridad completa de todas nuestras tablas `InnoDB` de todas las bases de datos:

    shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql

Esto es una copia de seguridad en línea, sin bloqueos, que no molesta a las lecturas y escrituras de las tablas. Hemos supuesto antes que nuestras tablas son `InnoDB`, así que `--single-transaction` hace una lectura consistente y garantiza que los datos vistos por mysqldump no cambian. (Los cambios hechos por otros clientes a las tablas `InnoDB` no son vistas por el proceso mysqldump.) Si también tenemos otros tipos de tablas, debemos suponer que no han sido cambiadas durante la copia de seguridad. Por ejemplo, para las tablas `MyISAM` en la base de datos `mysql`, debemos suponer que no se estaban haciendo cambios administrativos a las cuentas MySQL durante la copia de seguridad.

El archivo `.sql` resultante producido por el comando mysqldump contiene una serie de sentencias SQL `INSERT` que se pueden utilizar para recargar las tablas volcadas más tarde.

Las copias de seguridad completas son necesarias, pero no son siempre convenientes. Producen ficheros muy grandes y llevan tiempo generarse. No son óptimos en el sentido de que cada copia completa sucesiva incluye todos los datos, incluidas las partes que no han cambiado desde el último. Después de realizar una copia de seguridad completa inicial, es más eficiente hacer copias incrementales. Son más pequeñas, y llevan menos tiempo de realización. A cambio, en el momento de la recuperación, no podrá restaurarlo únicamente recargando la copia completa. También deberá procesar las copias incrementales para recuperar los cambios incrementales.

Para hacer copias de seguridad incrementales, necesitamos guardar los cambios incrementales. El servidor MySQL debería ser iniciado siempre con la opción `--log-bin` para que almacene estos cambios en un archivo mientras actualiza los datos. Esta opción activa el registro binario, así que el servidor escribe cada sentencia SQL que actualiza datos en un archivo lllamado registro binario de MySQL. Miremos al directorio de datos de un servidor MySQL que fue iniciado con la opción `--log-bin` y que se ha estado ejecutando durante algunos días. Encontramos estos archivos de registro binario:

    -rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
    -rw-rw---- 1 guilhem  guilhem         4 Nov 10 23:59 gbichot2-bin.000002
    -rw-rw---- 1 guilhem  guilhem        79 Nov 11 11:06 gbichot2-bin.000003
    -rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
    -rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
    -rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
    -rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

Cada vez que se reinicia, el servidor MySQL crea un nuevo archivo de registro binario utilizando el siguiente número en la secuencia. Mientras el servidor se está ejecutando, podemos comunicarle manualmente que cierre el archivo de registro binario actual y comience otro nuevo, ejecutando la sentencia SQL `FLUSH LOGS` o con el comando mysqladmin flush-logs. mysqldump también tiene una opción para volcar los logs. El archivo `.index` en el directorio de datos contiene la lista de todos los archivos de registro binario de MySQL en el directorio. Este archivo se utiliza para replicación.

El registro binario de MySQL es importante para la restauración, porque son copias incrementales de datos. Si se asegura de volcar los registros cuando hace su copia de seguridad completa, entonces cualquier registro binario creado tras esa copia contiene todos los cambios hechos desde entonces. Modifiquemos el comando mysqldump previo un poco para que vuelque los registros binarios de MySQL en el momento de la copia de seguridad completa, y para que el archivo de volcado contenga el nombre del registro binario actual:

    shell> mysqldump --single-transaction --flush-logs --master-data=2
               --all-databases > backup_sunday_1_PM.sql

Tras ejecutar este comando, el directorio de datos contiene un nuevo archivo de registro binario, `gbichot2-bin.000007`. El archivo `.sql` resultante contiene estas líneas:

    -- Position to start replication or point-in-time recovery from
    -- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

Como el comando mysqldump ha hecho una copia de seguridad completa, estas líneas significan dos cosas:

- El archivo `.sql` contiene todos los cambios hechos antes de cualquier cambio escrito al registro binario `gbichot2-bin.000007` o posterior.

- Todos los cambios registrados tras la copia de seguridad no están presentes en el archivo `.sql`, pero lo están en el registro binario `gbichot2-bin.000007` o posterior.

El lunes, a las 1 PM, podemos crear una copia de seguridad incremental volcando los registros para comenzar un nuevo registro binario. Por ejemplo, ejecutando un comando mysqladmin flush-logs creamos `gbichot2-bin.000008`. Todos los cambios producidos entre el domingo a la 1 PM cuando se hizo la copia completa, y el lunes a la 1 PM están en el archivo `gbichot2-bin.000007`. Esta copia incremental es importante, así que es una buena idea copiarla a un lugar seguro. (Por ejemplo, en cinta o DVD, o copiándolo a otra máquina.) El martes a la 1 PM, ejecute otro comando mysqladmin flush-logs. Todos los cambios desde el lunes a la 1 PM hasta el martes a la 1 PM están en el archivo `gbichot2-bin.000008` (que también debería ser copiado a un lugar seguro).

Los registros binarios de MySQL ocupan espacio de disco. Para ligerar espacio, púrguelos de vez en cuando. Una manera de hacerlo es borrar los registros binarios que no se necesiten, como cuando hacemos una copia de seguridad completa:

    shell> mysqldump --single-transaction --flush-logs --master-data=2
               --all-databases --delete-master-logs > backup_sunday_1_PM.sql

Tenga en cuenta que: Borrar los registros binarios de MySQL con mysqldump --delete-master-logs puede ser peligroso si su servidor es un servidor maestro de replicación, porque los servidores esclavos pueden no haber procesado completamente los contenidos del registro binario.

La descripción de la sentencia `PURGE MASTER LOGS` explica lo que debe ser verificado antes de borrar los registros binarios de MySQL. Consulte Sección 13.6.1.1, “Sintaxis de `PURGE MASTER LOGS`”.

#### 5.8.2.2. Usar copias de seguridad para una recuperación

Ahora suponga que tenemos un fallo catastrófico el miércoles a las 8 AM que requiere restauración de las copias de seguridad. Para recuperarnos, primero restauramos la última copia de seguridad completa que tenemos (la del domingo a la 1 PM). El archivo de copia completo es tan solo una serie de sentencias SQL, así qeu restaurarlo es muy fácil:

    shell> mysql < backup_sunday_1_PM.sql

En este punto, el estado de los datos ha sido restaurado al del domingo a la 1 PM. Para restaurar los datos hechos desde entonces, debemos usar las copias incrementales, es decir los archivos de registro binario `gbichot2-bin.000007` y `gbichot2-bin.000008`. Extraigalos, si es necesario, de allá donde estuviesen guardados, y luego procese sus contenidos de la siguiente manera:

    shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

Ahora hemos recuperado los datos hasta su estado del martes a la 1 PM, pero todavía hay cambios que faltan desde esa fecha hasta el momento del fallo. Para no perderlos, deberíamos haber hecho que el servidor MySQL almacenase sus registros MySQL en un lugar seguro (discos RAID, ...) diferente del lugar donde almacena sus archivos de datos, para que estos registros no estuvieran únicamente en el disco destruido. (Es decir, iniciar el servidor con la opción `--log-bin` que especifique una localización en un dispositivo físico diferente del que contiene el directorio de datos. De esta manera, los registros no se pierden aún si el dispositivo que contiene el directorio sí.) Si hubiésemos hecho esto, podríamos tener el archivo `gbichot2-bin.000009` a mano, y podríamos aplicarlo para restaurar hasta los cambios más recientes sin ninguna pérdida a como estaban en el momento del fallo.

#### 5.8.2.3. Sumario de la estrategia de copias de seguridad

En caso de un fallo de sistema operativo o energía, `InnoDB` hace todo el trabajo de restauración de datos por si mismo. Pero para asegurarse de que puede dormir bien, tenga en cuenta los siguientes puntos:

- Ejecute siempre el servidor MySQL con la opción `--log-bin`, o mejor aún `--log-bin=`log_name``, donde el archivo de registro está guardado en algún medio diferente al disco en donde está el directorio de datos. Si tiene un medio seguro tal, también puede ser bueno para hacer balanceo de carga de disco (que resulta en una mejora de rendimiento).

- Haga copias de seguridad completas periodicas, utilizando el último comando mysqldump dado previamente, que hace una copia de seguridad en línea sin bloqueo.

- Haga copias de seguridad incrementales periodicamente volcando los registros con `FLUSH LOGS` o mysqladmin flush-logs.

### 5.8.3. Mantenimiento de tablas y recuperación de un fallo catastrófico (crash)

El siguiente texto explica como utilizar myisamchk para comprobar o reparar tablas `MyISAM` (tablas con archivos `.MYI` and `.MYD`).

Puede utilizar la utilidad myisamchk para obtener información sobre las tablas de su base de datos, o para comprobar, reparar u optimizarlas. Las siguientes secciones explican como invocar myisamchk (incluyendo una descripción de sus opciones), como establecer un calendario de mantenimiento de tablas, y como utilizar myisamchk para que realice sus diferentes funciones.

Aunque la reparación de tablas con myisamchk es bastante segura, siempre es una buena idea hacer una copia de seguridad antes de hacer una reparación (o cualquier operación de mantenimiento que pueda hacer muchos cambios a una tabla)

Las operaciones de myisamchk que afectan a índices pueden causar que los índices `FULLTEXT` sean recreados con parámetros que son incompatibles con los valores utilizados por el servidor MySQL. Para evitar esto, lea las instrucciones en Sección 5.8.3.2, “Opciones generales demyisamchk”.

En muchos casos, podría encontrar más simple hacer el mantenimiento de las tablas `MyISAM` utilizando las sentencias SQL que realizan las mismas operaciones que myisamchk:

- Para comprobar o reparar tablas `MyISAM` tables, use `CHECK TABLE` o `REPAIR TABLE`.

- Para optimizar tablas `MyISAM`, use `OPTIMIZE TABLE`.

- Para analizar tablas `MyISAM`, use `ANALYZE TABLE`.

Estas sentencias pueden ser utilizadas directamente, o mediante el programa cliente mysqlcheck, que provee de una interfaz de línea de comandos.

Una de las ventajas de estas sentencias sobre myisamchk es que el servidor hace todo el trabajo. Con myisamchk, usted debe asegurare de que el servidor no utiliza las tablas al mismo tiempo. Si no es así, podría haber interacciones no deseadas entre myisamchk y el servidor.

#### 5.8.3.1. Sintaxis para invocar myisamchk

Invoque myisamchk de la siguiente manera:

    shell> myisamchk [opciones] tbl_name

Las `options` especifican lo que quiere que myisamchk haga. Se describen en las secciones posteriores. También puede obtener una lista de las opciones invocando myisamchk --help.

Sin opciones, myisamchk simplemente comprueba la tabla, como operación por defecto. Para obtener más información, o decirle a myisamchk que tome medidas correctivas, especifique las opciones tal como se explica en la siguiente guía.

`tbl_name` es el nombre de la tabla que quiere comprobar o reparar. Si ejecuta myisamchk desde otro lugar que no sea el directorio de la base de datos, debe especificar la ruta hasta este directorio, porque myisamchk no tiene la más mínima idea de en qué lugar se encuentra la base de datos. De hecho, myisamchk no se preocupa por si los archivos sobre los que trabaja se encuentran en un directorio de base de datos. Puede copiar los archivos que corresponden a la tabla en cualquier otro lugar, y hacer las operaciones de recuperación allí.

Puede invocar varios nombres de tablas en la línea de comandos de myisamchk, si lo desea. También puede especificar una tabla nombrando a su archivo de índices (el archivo con extensión `.MYI`). Esto permite que especifique todas las tablas de un directorio utilizando el patrón `*.MYI`. Por ejemplo, si se encuentra en un directorio de una base de datos, puede comprobar todas las tablas `MyISAM` de ese directorio de la siguiente manera:

    shell> myisamchk *.MYI

Si no se encuentra en el directorio de la base de datos, puede comprobar todas las tablas especificando la ruta al directorio:

    shell> myisamchk /path/to/database_dir/*.MYI

Incluso se podría comprobar todas las tablas en todas las bases de datos especificando un comodín en la ruta a el archivo de datos MySQL:

    shell> myisamchk /path/to/datadir/*/*.MYI

La manera recomendada de comprobar rápidamente todas las tablas `MyISAM` e `ISAM` es:

    shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI
    shell> isamchk --silent /path/to/datadir/*/*.ISM

Si usted quiere comprobar todas las tablas `MyISAM` e `ISAM` y repararlas si alguna está corrompida, puede utilizar los siguientes comandos:

    shell> myisamchk --silent --force --fast --update-state \
              -O key_buffer=64M -O sort_buffer=64M \
              -O read_buffer=1M -O write_buffer=1M \
              /path/to/datadir/*/*.MYI
    shell> isamchk --silent --force -O key_buffer=64M \
              -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
              /path/to/datadir/*/*.ISM

Estos comandos asumen que tiene más de 64MB libres. Para más información sobre reserva de memoria con myisamchk, consulte Sección 5.8.3.6, “Utilización de la memoria por parte de myisamchk”.

Debe asegurarse de que ningún otro programa está utilizando las tablas mientras ejecute myisamchk. Si no es así, cuando ejecute myisamchk, puede obtener el siguiente mensaje de error:

    warning: clients are using or haven't closed the table properly

Esto significa que está intentando comprobar una tabla que ha sido cambiada por otro programa (como podría ser el servidor mysqld) que no ha cerrado aún el archivo, o que ha muerto sin cerrar el archivo adecuadamente.

Si mysqld se está ejecutando, debe forzarlo a volcar cualquier modificación de tablas que todavía esté almacenada en memoria, utilizando `FLUSH TABLES`. Debería entonces asegurarse de que nadie está utilizando las tablas sobre las que se ejecuta myisamchk. La manera más fácil de evitar este problema es utilizar `CHECK TABLE` en vez de myisamchk para comprobar las tablas.

#### 5.8.3.2. Opciones generales demyisamchk

Las opciones descritas en esta sección pueden utilizarse para cualquier tipo de operación de mantenimiento de tabla realizada por myisamchk. Las secciones que siguen a la presente explican las opciones que pertenecen tan solo a operaciones específicas, como la comprobación o reparación de tablas.

- `--help, -?`

  Muestra un mensaje de ayuda y finaliza.

- `--debug=`debug_options`, -# `debug_options``

  Escribe un registro de depuración. La cadena `debug_options` suele ser frecuentemente `'d:t:o,`file_name`'`.

- `--silent, -s`

  Modo silencioso. Escribe solo cuando ocurre algún tipo de error. Puede usar `-s` dos veces (`-ss`) para hacer que myisamchk sea muy silencioso.

- `--verbose, -v`

  Modo explícito. Imprime más información. Esto puede ser utilizado en conjunción con `-d` y `-e`. Utilice `-v` múltiples veces (`-vv`, `-vvv`) para producir aún más información.

- `--version, -V`

  Muestra información sobre la versión y finaliza.

- `--wait, -w`

  En vez de terminar con un error si la tabla se encuentra bloqueada, espera a que la tabla se desbloquee antes de continuar. Tenga en cuenta que si está ejecutando mysqld con la opción `--skip-external-locking`, la tabla sólo puede haber sido bloqueada por otro comando myisamchk.

También puede establecer las variables utilizando `--`var_name`=`value`` opciones:

Variable | Valor por defecto
`decode_bits` | 9
`ft_max_word_len` | dependiente-de-versión
`ft_min_word_len` | 4
`ft_stopword_file` | lista interna
`key_buffer_size` | 523264
`myisam_block_size` | 1024
`read_buffer_size` | 262136
`sort_buffer_size` | 2097144
`sort_key_blocks` | 16
`write_buffer_size` | 262136

Las posibles variables de myisamchk y sus valores por defecto pueden ser examinadas con myisamchk --help:

`sort_buffer_size` se utiliza cuando las claves son reparadas mediante ordenación, que es el caso normal cuando se utiliza `--recover`.

`key_buffer_size` se utiliza cuando se está comprobando una tabla con `--extend-check` o cuando las claves se están reparando insertándolas registro a registro en la tabla (como cuando se hacen inserciones normales). La reparación a través del "key buffer" se utiliza en los siguientes casos:

- Ha utilizado `--safe-recover`.

- Los archivos temporales necesarios para ordenar las claves serían más del doble de grandes que cuando se crea el archivo de claves directmaente. Esto ocurre usualmente cuando hay valores grandes en la clave (tipos de columna como `CHAR`, `VARCHAR`, o `TEXT`), porque la operación de ordenamiento necesita almacenar los valores de las claves por completo mientras procede. Si tiene mucho espacio temporal y puede forzar a que myisamchk repare mediante ordenación, puede utilizar la opción `--sort-recover`.

La reparación mediante el "key buffer" necesita mucho menos espacio de disco que utilizar ordenación, pero es también mucho más lenta.

Si quiere una reparación más rápida, establezca las variables `key_buffer_size` y `sort_buffer_size` a un valor aproximadamente dle 25% de la memoria disponible. Puede subir ambas variables a un valor grande, porque solo se utiliza una de ellas a la vez.

`myisam_block_size` es el tamaño utilizado para los bloques de índices.

`ft_min_word_len` y `ft_max_word_len` indican la longitud de palabra mínima y máxima para índices `FULLTEXT`. `ft_stopword_file` indica un archivo de "palabra de parada". Esto necesita establecerse en las siguientes circunstancias.

Si utiliza myisamchk para realizar una operación que modifica los índices de las tablas (como una reparación o un análisis), los índices `FULLTEXT` son reconstruidos utilizando el archivo de palabra de parada por defecto a menos que especifique lo contrario. Esto puede resultar en el fallo de sentencias.

El problema ocurre porque estos parámetros son sólo conocidos por el servidor. No están almacenados en los archivos de índices de `MyISAM`. Para evitar el problema, si usted a modificado la longitud mínima o máxima de palabra, o el archivo de palabra de parada en el servidor, especifique los mismos valores de `ft_min_word_len`, `ft_max_word_len`, y `ft_stopword_file` para myisamchk que los que ha utilizado para mysqld. Por ejemplo, si ha establecido una longitud de palabra mínima de 3, puede reparar una tabla con myisamchk así:

    shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

Para asegurarnos de que myisamchk y el servidor utilizan los mismos valores para los parámetros de full-text, podemos ponerlos en las secciones `[mysqld]` y `[myisamchk]` de un archivo de opciones:

    [mysqld]
    ft_min_word_len=3

    [myisamchk]
    ft_min_word_len=3

Una alternativa a utilizar myisamchk es usar las sentencias `REPAIR TABLE`, `ANALYZE TABLE`, `OPTIMIZE TABLE`, o `ALTER TABLE`. Estas sentencias son ejecutadas por el servidor, que conoce los parámetros de full-text apropiados que debe utilizar.

#### 5.8.3.3. Opciones de myisamchk para comprobar tablas

myisamchk soporta las siguientes opciones para las operaciones de comprobación de tablas:

- `--check, -c`

  Comprueba si hay errores en la tabla. Esta es la operación por defecto si no se especifica ninguna opción que seleccione la operación a realizar.

- `--check-only-changed, -C`

  Comprueba sólo las tablas que han cambiado desde la última comprobación.

- `--extend-check, -e`

  Comprueba la tabla muy concienzudamente. Esto es muy lento si la tabla tiene muchos índices. Esta opción debería ser utilizada únicamente en casos extremos. Normalmente, myisamchk o myisamchk --medium-check deberían ser capaces de determinar si hay algún error en la tabla.

  Si está utilizando `--extend-check` y tiene bastante memoria, establecer un valor grande para la variable `key_buffer_size` ayuda a que la operación de reparación vaya más rápido.

- `--fast, -F`

  Comprueba solo las tablas qeu no han sido cerrados apropiadamente.

- `--force, -f`

  Realiza una operación de reparación automaticamente si myisamchk encuentra cualquier error en la tabla. El tipo de reparación es el mismo que el que se espcifica con la opción `--repair` o `-r`.

- `--information, -i`

  Imprime estadísticas informativas sobre la tabla que se comprueba.

- `--medium-check, -m`

  Realiza una comprobación que es más rápida que `--extend-check`. Esta comprobación encuentra solo el 99.99% de todos los errores, lo que debería ser suficiente en la mayor parte de los casos.

- `--read-only, -T`

  No señala la tabla como comprobada. Esto es útil si utiliza myisamchk para comprobar una tabla que está siendo utilizada por otra aplicación que no utiliza bloqueos, como mysqld cuando se ejecuta con la opción `--skip-external-locking`.

- `--update-state, -U`

  Almacena información en el archivo `.MYI` para indicar que la tabla ha sido comprobada, o si la tabla tiene fallos. Esto debería utilizarse par obtener el máximo beneficio de la opción `--check-only-changed`, pero no debería utilizarse esta opción si se está ejecutando el servidor mysqld, con la opción `--skip-external-locking`, y éste está utilizando la tabla.

#### 5.8.3.4. Opciones de myisamchk para reparar tablas

myisamchk tiene soporte para las siguientes opciones en las operaciones de reparación de tablas:

- `--backup, -B`

  Realiza una copia de seguridad del archivo `.MYD` con el formato `file_name-time.BAK`

- `--character-sets-dir=`path``

  El directorio donde los juegos de carácteres están instalados. Consulte Sección 5.9.1, “El conjunto de caracteres utilizado para datos y ordenación”.

- `--correct-checksum`

  Corrige la información de checksum de la tabla.

- `--data-file-length=`#`, -D `#``

  Longitud máxima del archivo de datos. (cuando se está reconstruyendo el archivo de datos porque está ``lleno'').

- `--extend-check, -e`

  Realiza una reparación que intenta recuperar todos los registros posibles del archivo de datos. Normalmente esto también encuentra un montón de registros basura. No utilice esta opción al menos que esté desesperado.

- `--force, -f`

  Sobreescribe los archivos temporales viejos (archivos con nombres como ``tbl_name`.TMD`) en vez de interrumpir la reparación.

- `--keys-used=`#`, -k `#``

  Para myisamchk, el valor de esta opción indica qué índices tiene que actualizar. Cada bit binario de la opción, corresponde a un índice de la tabla, donde el primer índice es el bit 0. Para isamchk, esta opción indica que sólo los primeros `#` índices de la tabla deben ser actualizados. En cualquier caso, un valor de 0 en la opción desahbilita las actualizaciones a todos los índices, lo que puede ser utilizado para obtener inserciones más rápidas. Los índices desactivados pueden ser reactivados utilizando myisamchk -r.

- `--no-symlinks, -l`

  No sigue los enlaces simbólicos. Normalmente repara una tabla que esté apuntada por un enlace simbólico. Esta opción no existe en MySQL 4.0, porque las versiones a partir de la 4.0 no eliminan los enlaces simbólicos durante las operaciones de reparación.

- `--parallel-recover, -p`

  Utiliza la misma técnica que `-r` y `-n`, pero crea todas las claves en paralelo, utilizando hilos de ejecución diferentes. Esto es código en estado alpha. Utilícelo bajo su propia responsabilidad.

- `--quick, -q`

  Consigue una reparación más rápida al no modificar el archivo de datos. Puede especificar esta opción dos veces para forzar a myisamchk a modificar el archivo original de datos en el caso de claves duplicadas.

- `--recover, -r`

  Realiza una reparación que puede resolver casi cualquier problema, excepto las claves únicas que no son únicas (que es un error extremadamente raro en tablas `MyISAM`). Si quiere recuperar una tabla, esta es la primera opción a intentar. Debería intentar con `-o` sólo si myisamchk comunica que la tabla no puede recuperarse con `-r`. (En el improbable caso de que `-r` falle, el archivo de datos permanece intacto.)

  Si tiene memoria suficiente, debería incrementar el valor de `sort_buffer_size`.

- `--safe-recover, -o`

  Hace una reparación utilizando un méto de recuperación antiguo que lee todos los registros en orden y actualiza todos los árboles de índices basándose en los registros encontrados. Esto es de un orden de magnitud más lento que `-r`, pero puede gestionar un puñado de casos muy improbables que `-r` no puede. Este método de recuperación también utiliza mucho menos espacio de disco que `-r`. Normalmente debería reparar primero con `-r`, y luego utilizar `-o` solo si `-r` falla.

  Si tiene mucha memoria, debería incrementar el valor de `key_buffer_size`.

- `--set-character-set=`name``

  Cambia el juego de carácteres utilizado por los índices de tabla. Esta opción fue reemplazada por `--set-collation` en MySQL 5.0.3.

- `--set-collation=`name``

  Cambia la colación utilizada para ordenar los índices de las tablas. El nombre del código de carácteres viene implícito en la primera parte del nombre de la colación. Esta opción fue añadida en MySQL 5.0.3.

- `--sort-recover, -n`

  Fuerza a que myisamchk utilice ordenación para establecer las claves aunque los archivos temporales puedan ser muy grandes.

- `--tmpdir=`path`, -t `path``

  La ruta a el directorio que debe utilizarse para almacenar archivos temporales. Si no está establecida, myisamchk utiliza el valor de la variable de entorno `TMPDIR`. `tmpdir` puede ser establecido como una lista de rutas de directorios que son utilizadas sucesivamente de una manera a lo "round-robin" para crear archivos temporales. El carácter de separación entre los nombres de directorio es el de dos puntos en Unix ('`:`') y el punto y coma en Windows, Netware, y OS/2 ('`;`').

- `--unpack, -u`

  Descomprime una tabla que fue comprimida con myisampack.

#### 5.8.3.5. Otras opciones de myisamchk

myisamchk tiene soporte para las siguientes opciones en cuanto a acciones que no son comprobaciones ni reparaciones de tablas:

- `--analyze, -a`

  Analiza la distribución de las claves. Esto mejora el rendimiento de las join habilitando al optimizador de join para escober mejor el orden en que unirá las tablas y qué claves debería utilizar. Para obtener información sobre la distribución, utilice el comando myisamchk --description --verbose `tbl_name` o la sentencia `SHOW KEYS FROM `tbl_name``.

- `--description, -d`

  Imprime información descriptiva sobre la tabla.

- `--set-auto-increment[=`value`], -A[`value`]`

  Fuerza que la numeración auto incremental para los nuevos registros comience en un valor dado (o superior, si existen registros con valores autoincrementales tan altos). Si `value` no está especificado, el incremente automático comienza con al valor más grande que haya actualmetne en la tabla, más uno.

- `--sort-index, -S`

  Ordena los bloques de árboles de índices de mayor a menor. Esto optimiza las búsquedas y hace que el escaneo por clave de las tablas sea más rápido.

- `--sort-records=`#`, -R `#``

  Ordena los registros de acuerdo a un índice particular. Esto hace que sus datos están mucho más localizables y puede agilizar operaciones `SELECT` y `ORDER BY` basados en rangos que utilicen este índice. (La primera vez que utilice esta opción para ordenar una tabla, puede ser muy lento.) Para determinar los números de índices de una tabla, utilice `SHOW KEYS`, que muestra los índices de una tabla en el mismo orden en que myisamchk los ve. Los ínidces están numerados comenzando por 1.

#### 5.8.3.6. Utilización de la memoria por parte de myisamchk

La reserva de memoria es importante cuando ejecute myisamchk. myisamchk no utiliza más memoria de la que se especifique con las opciones `-O`. Si usted va a utilizar myisamchk en tablas muy grandes, debería primero decidir cuanta memoria quiere utilizar. Por defecto, se utilizarán más o menos 3MB para realizar reparaciones. Utilizando valores más grandes, puede conseguir que myisamchk funcione más rápido. Por ejemplo, si tiene más de 32MB de RAM, podría utilizar estas otras opciones (además de las otras que pueda especificar):

    shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

Utilizar `-O sort=16M` probablemente sea suficiente para la mayoría de los casos.

Tenga en cuenta que myisamchk utiliza archivos temporales en `TMPDIR`. Si `TMPDIR` apunta a un sistema de ficheros en memoria, podría quedarse fácilmente sin memoria y obtener errores. Si esto ocurre, haga que `TMPDIR` apunte a algún directorio de un sistema de ficheros con más espacio y ejecute el comando myisamchk de nuevo.

Mientras está reparando, myisamchk también necesita mucho espacio de disco:

- Doble el espacio del archivo de datos (el original y una copia). Este espacio no se necesitará si hace una reparación con la opción `--quick`; en este caso solo se reconstruye el archivo de índices (la copia se crea en el mismo directorio que el original.)

- El espacio para el archivo de índices que reemplaza al viejo. El archivo de índices viejo se trunca en el inicio de la operación de reparación, así que usualmente este espacio se ignora. Este espacio debe estar en el mismo sistema de ficheros que el archivo de índices original.

- Cuando utilice `--recover` o `--sort-recover` (pero no al utilizar `--safe-recover`), necesitará espacio para un buffer de ordenación. El espacio requerido es:

      (clave_más_larga + longitud_de_puntero_a_registro) * número_de_registros * 2

  Puede comprobar la longitud de las claves y la longitud_de_puntero_a_registro con myisamchk -dv `tbl_name`. Este espacio se reserva en el directorio temporal (especificado por `TMPDIR` o `--tmpdir=`path``).

Si tiene algún problema con el espacio de disco durante una reparación, puede intentar utilizar `--safe-recover` en vez de `--recover`.

#### 5.8.3.7. Usar myisamchk para recuperación de desastres

Si ejecuta mysqld con `--skip-external-locking` (lo que es la opción por defecto en algunos sistemas, como Linux), no puede utilizar myisamchk de manera segura para comprobar una tabla si mysqld está utilizando esta misma tabla. Si puede asegurarse de que nadie está accediendo a las tablas a través de mysqld mientras ejecuta myisamchk, entonces solo tendrá que hacer mysqladmin flush-tables antes de comenzar la comprobación de las tablas. Si no puede garantizar esto, entonces debe parar mysqld mientras comprueba las tablas. Si ejecuta myisamchk mientras mysqld está actualizando las tablas, puede obtener un aviso de que una tabla está corrupta aún cuando no sea así.

Si no está utilizando `--skip-external-locking`, puede utilizar myisamchk para comprobar tablas en cualquier momento. Mientras hace esto, todos los clientes que intenten actualizar la tabla esperarán hasta que myisamchk esté listo para continuar.

Si utiliza myisamchk para reparar u optimizar tablas, debe siempre asegurarse de que el servidor mysqld no está utilizando la tabla (esto es también aplicable cuando el usted esté utilizando `--skip-external-locking`). Si no apaga mysqld, al menos debe hacer un mysqladmin flush-tables antes de ejecutar myisamchk. Sus tables podrían corromperse si el servidor y myisamchk acceden a las tablas simultáneamente.

Esta sección describe como comprobar y actuar si existe corrupción en bases de datos MySQL. Si sus tablas se corrompen frecuentemente, usted debería intentar encontrar la razón. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”.

Para una explicación de como las tablas `MyISAM` pueden corromperse, consulte Sección 14.1.4, “Problemas en tablas `MyISAM`”.

Cuando realice recuperación de fallos, es importante entender que cada tabla `MyISAM` con nombre `tbl_name` en una base de datos corresponde a tres archivos en el directorio de la base de datos:

Archivo | Propósito
``tbl_name`.frm` | Archivo de definición (formato)
``tbl_name`.MYD` | Archivo de datos
``tbl_name`.MYI` | Archivo de índices

Cada uno de estos tres tipos de archivos tiene un tipo de peligro de corrupción diferente, pero la mayoría de problemas ocurren más frecuentemente en los archivos de datos e índices.

myisamchk trabaja creando una copia de el archivo de datos `.MYD` registro a registro. Finaliza el estadio de reparación borrando el viejo archivo `.MYD` y renombrando el nuevo archivo a el nombre original. Si utiliza `--quick`, myisamchk no crea un archivo`.MYD` temporal, sino que asume que el archivo `.MYD` está correcto y solo genera un nuevo archivo de índices sin tocar el archivo `.MYD`. Esto es seguro porque myisamchk automáticamente detecta sí el archivo `.MYD` está corrompido, y para la reparación si lo está. También puede especificar la opción `--quick` dos veces. En este caso, myisamchk no aborta al encontrar algunos errores (como erroes de clave duplicada), sino que intenta resolverlo modificando el archivo `.MYD`. Normalmente, la utilización de dos opciones `--quick` es útil sólo si tiene muy poco espacio libre para realizar una reparación normal. En este caso, al menos debería hacer una copia de seguridad antes de ejecutar myisamchk.

#### 5.8.3.8. Cómo comprobar tablas `MyISAM` en busca de errores

Para comprobar una tabla `MyISAM`, utilice los siguientes comandos:

- `myisamchk `tbl_name``

  Esto encuentra el 99.99% de todos los errores. Lo que no puede encontrar es corrupción que involucre sólo al archivo de datos (lo que es muy inusual). Si quiere comprobar una tabla, normalmente debería ejecutar myisamchk sin opciones, o al menos con la opción `-s` o `--silent`.

- `myisamchk -m `tbl_name``

  Esto encuentra el 99.999% de todos los errores. Primero comprueba todos los índices, y después lee todos los registros. Calcula en checksum para todas las claves en los registros, y verifica que coincida con el de las claves en el árbol de índices.

- `myisamchk -e `tbl_name``

  Esto hace una comprobación completa y exhaustiva de todos los datos (`-e` significa ``comprobación extendida''). Hace una comprobación-lectura de la clave de cada registro para verificar que de hecho apuntan al registro correcto. Esto normalmente puede llevar mucho tiempo para una tabla grande que tenga muchos índices. Normalmente myisamchk se para tras el primer error que encuentra. Si quiere obtener más información, puede añadir la opción `--verbose` (`-v`). Esto causa que myisamchk durante un máximo de 20 errores.

- `myisamchk -e -i `tbl_name``

  Igual que el comando previo, pero la opción `-i` le dice a myisamchk que imprima también algunas estadísticas informativas.

En la mayoría de casos, un comando myisamchk sin más argumentos que el nombre de la tabla original es suficiente para comprobar la tabla.

#### 5.8.3.9. Cómo reparar tablas

La discusión en esta sección describe cómo usar myisamchk en tablas `MyISAM` (extensiones `.MYI` y `.MYD`).

También puede ( y debe, si es posible) usar los comandos `CHECK TABLE` y `REPAIR TABLE` para chequear y reparar tablas `MyISAM` . Consulte Sección 13.5.2.3, “Sintaxis de `CHECK TABLE`” y Sección 13.5.2.6, “Sintaxis de `REPAIR TABLE`”.

Los síntomas de tablas corruptas incluyen consultas que abortan inesperadamente y errores observables como los siguientes:

- ``tbl_name`.frm` is locked against change

- Can't find file ``tbl_name`.MYI` (Errcode: `###`)

- Unexpected end of file

- Record file is crashed

- Got error `###` from table handler

Para obtener ejecución acerca de los errores puede ejectuar perror `###`, donde `###` es el número de error. El siguiente ejemplo muestra cómo usar perror para encontrar el significado de la mayoría de errores comunes que indican un problema con la tabla:

    shell> perror 126 127 132 134 135 136 141 144 145
    126 = Index file is crashed / Wrong file format
    127 = Record-file is crashed
    132 = Old database file
    134 = Record was already deleted (or record file crashed)
    135 = No more room in record file
    136 = No more room in index file
    141 = Duplicate unique key or constraint on write or update
    144 = Table is crashed and last repair failed
    145 = Table was marked as crashed and should be repaired

Tenga en cuenta que el error 135 (no more room in record file) y el error 136 (no more room in index file) no son errores que puedan arreglarse con una simple reparación. En este caso, debe usar `ALTER TABLE` para incrementar los valores de las opciones de tabla `MAX_ROWS` y `AVG_ROW_LENGTH`:

    ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

Si no conoce los valores actuales de las opciones de tabla, use `SHOW CREATE TABLE` o `DESCRIBE`.

Para los otros errores, debe reparar las tablas. myisamchk normalmente detecta y arregla la mayoría de problemas que ocurren.

El proceso de reparación incluye hasta cuatro etapas, descritas aquí. Antes de empezar, debe cambiar la localización al directorio de la base de datos y comprobar los permisos de los ficheros de las tablas. En Unix, asegúrese que puede leerlos el usuario con el que corre mysqld (y con su usuario, ya que necesita acceder a los ficheros que está comprobando). En caso que necesite modificar ficheros, debe tener también permiso de escritura.

Las opciones que puede usar para el mantenimiento de tablas con myisamchk y isamchk se describen en varias de las primeras subsecciones de Sección 5.8.3, “Mantenimiento de tablas y recuperación de un fallo catastrófico (crash)”.

La siguiente sección es para los casos en los que los comandos anteriores fallen o si quiere usar las características extendidas que myisamchk y isamchk proporcionan.

Si va a reparar una tabla desde la línea de comandos, debe parar el servidor mysqld en primer lugar. Tenga en cuenta que cuando ejectua mysqladmin shutdown en un servidor remoto, el servidor mysqld todavía está activo durante un periodo de tiempo una vez que mysqladmin devuelve el control, hasta que todas las consultas están paradas y todas las claves se han volcado a disco.

Etapa 1: Comprobación de tablas

Ejecute myisamchk *.MYI o myisamchk -e *.MYI si tiene más tiempo. Use la opción `-s` (silencio) para suprimir información innecesaria.

Si el servidor mysqld está parado, debe usar la opción `--update-state` para decirle a myisamchk que marque la tabla como 'comprobada'.

Debe reparar sólo las tablas en que myisamchk anuncia un error. Para estas tables, pase a la Etapa 2.

Si obtiene errores extraños al hacer la comprobación (tales como errores `out of memory`), o si myisamchk cae, pase a la Etapa 3.

Etapa 2: Reparación sencilla

Nota: Si quiere que una operación de reparación sea mucho más rápida, debe cambiar los valores de las variables `sort_buffer_size` y `key_buffer_size` al 25% aproximado de la cantidad de memoria disponible al ejecutar myisamchk o isamchk.

En primer lugar, intente myisamchk -r -q `tbl_name` (`-r -q` significa ``modod de recuperación rápido''). Intenta reparar el fichero de indexación sin tocar el fichero de datos. Si el fichero de datos contiene todo lo que debería y los vínculos de borrado apuntan a la localización correcta dentro del fichero de datos, esto debería funcionar, y la tabla estaría reparada. Empiece a reparar la siguiente tabla. Si no es así, use el siguiente procedimiento:

1. Haga una copia de seguridad del fichero de datos antes de continuar.

2. Use myisamchk -r `tbl_name` (`-r` significa ``modo de recuperación''). Esto elimina registros incorrectos y registros borrados del fichero de datos y recunstruye el fichero de indexación.

3. Si el paso precedente falla, use myisamchk --safe-recover `tbl_name`. El modo de recuperación seguro usa un método de reucperación antiguo que soporta algunos casos que los metodos normales de recuperación no soportan (pero es más lento).

Si obtiene errores extraños al reparar (tales como errores `out of memory` ), o si myisamchk cae, pase a la Etapa 3.

Etapa 3: Reparaciones complicadas

Debe llegar a esta etapa sólo si el primer bloque de 16KB en el fichero de indexación está destruido o contiene información incorrecta, o si el fichero de indexación no se encuentra. En este caso, es necesario crear un nuevo fichero de indexación. Hágalo así:

1. Mueva el fichero de datos a una ubicación segura.

2. Use el fichero descriptor de la tabla para crear unos ficheros de datos e indexación nuevos (vacíos):

       shell> mysql db_name
       mysql> SET AUTOCOMMIT=1;
       mysql> TRUNCATE TABLE tbl_name;
       mysql> quit

   Si su versión de MySQL no soporta `TRUNCATE TABLE`, use `DELETE FROM `tbl_name`` en su lugar.

3. Copie el antiguo fichero de datos otra vez sobre el nuevo fichero de datos (recién creado). (No se limite a mover el fichero antiguo sobre el nuevo; debe guardar una copia por si algo falla.)

Vuelva a la Etapa 2. myisamchk -r -q debería funcionar. (Este no debería ser un bucle sin fin.)

Puede usar `REPAIR TABLE `tbl_name` USE_FRM`, que realiza el proceso completo automáticamente.

Etapa 4: Reparaciones muy complicadas

Debe llegar a esta etapa sólo si el fichero de descripción `.frm` ha tenido problemas. Esto no debería ocurrir nunca, ya que el fichero de descripción nunca cambia una vez que la tabla se crea:

1. Restaure el fichero de descripción desde una copia de seguridad y vuelva a la Etapa 3. También puede restaurar el fichero índice y volver a la Etapa 2. En este último caso, puede comenzar con myisamchk -r.

2. Si no tiene una copia de seguridad pero sabe exactamente cómo se creó la tabla, cree una copia de la tabla en otra base de datos. Borre el nuevo fichero de datos, luego mueva los ficheros `.frm` de descripción y `.MYI` de indexación desde la otra base de datos a la base de datos que tiene problemas. Esto le da unos nuevos ficheros de descripción e indexación, pero deja el fichero de datos `.MYD` solo. Vuelva a la Etapa 2 y trate de reconstruir el fichero de indexación.

#### 5.8.3.10. Optimización de tablas

Para eliminar registros fragmentados y eliminar espacio desperdiciado resultante del borrado o actualización de registros, ejecute myisamchk en modo recuperación:

    shell> myisamchk -r nombre_tabla

Puede optimizar una tabla de la misma forma usando el comando SQL `OPTIMIZE TABLE` . `OPTIMIZE TABLE` realiza una reparación de la tabla y un análisis de las claves, y también ordena el árbol de índices para obtener un mejor rendimiento en la búsqueda de claves. No hay posibilidad de interacción no deseada entre una utilidad y el servidor, ya que el servidor hace todo el trabajo cuando usa `OPTIMIZE TABLE`. Consulte Sección 13.5.2.5, “Sintaxis de `OPTIMIZE TABLE`”.

myisamchk tiene una serie de opciones que puede usar para mejorar el rendimiento de una tabla:

- `-S`, `--sort-index`

- `-R `index_num``, `--sort-records=`index_num``

- `-a`, `--analyze`

Para una descripción completa de estas opciones, consulte Sección 5.8.3.1, “Sintaxis para invocar myisamchk”.

### 5.8.4. Organizar un programa de mantenimiento de tablas

Es una buena práctica realizar chequeos de las tablas regularmente en lugar de esperar a que ocurran los problemas. Una forma de chequear y reparar tablas `MyISAM` es con los comandos `CHECK TABLE` y `REPAIR TABLE` . Consulte Sección 13.5.2.3, “Sintaxis de `CHECK TABLE`” y Sección 13.5.2.6, “Sintaxis de `REPAIR TABLE`”.

Otro modo de chequear tablas es usar myisamchk. Para mantenimiento, puede usar myisamchk -s. La opción `-s` (forma corta de `--silent`) hace que myisamchk se ejecute en modo silencioso, mostrando mensajes sólo cuando hay algún error.

Es una buena idea chequear las tablas al arrancar el servidor. Por ejemplo, cada vez que la máquina se reinicia durante una actualización, normalmente necesita chequear todas las tablas que hayan podido ser afectadas. (Éstas son las ``tablas que creemos que han fallado.'') Para chequear automáticamente tablas `MyISAM` , arranque el servidor con la opción `--myisam-recover` .

Un test todavía mejor sería chequear cualquier tabla cuya fecha de última modificación es más reciente que la del fichero `.pid`.

Debe chequear las tablas regularmente durante operaciones normales del sistema. En MySQL AB, utilizamos un trabajo cron para chequear todas nuestras tablas importantes una vez a la semana, usando una línea como esta en un fichero `crontab` :

    35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

Esto muestra información acerca de tablas que han fallado de forma que podemos examinarlas y repararlas cuando es necesario.

Como no hemos tenido tablas que hayan fallado inesperadamente (tablas que se corrompen por razones distintas a fallos de hardware) durante un par de años (esto es cierto), una vez a la semana es más que suficiente para nosotros.

Recomendamos que para empezar, ejecute myisamchk -s cada noche en todas la tablas que se hayan actualizado durante las últimas 24 horas, hasta que confíe en MySQL tanto como nosotros.

Normalmente, las tablas MySQL necesitan poco mantenimiento. Si cambia las tablas `MyISAM` con registros de tamaño dinámico (tablas con columnas `VARCHAR`, `BLOB`, o `TEXT` ) o tiene tablas con muchos registros borrados puede que quiera defragmentar/reaprovechar espacio de las tablas de vez en cuendo (una vez al mes?).

Puede hacerlo con `OPTIMIZE TABLE` en las tablas en cuestión. O, si puede parar el servidor mysqld por un rato, cambiando la localización al directorio de datos y usando este comando mientras el servidor está parado:

    shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI

### 5.8.5. Obtener información acerca de una tabla

Para obtener una descripción de tabla o estadísticas acerca de ella, use el comando mostrado a continuación:

- myisamchk -d `nombre_tabla`

  Ejecute myisamchk en ``modo descripción'' para producir una descripción de la tabla. Si inicia el servidor MySQL usando la opción `--skip-external-locking`, myisamchk puede reportar un error para una tabla que se actualice mientras está en ejecución. Sin embargo, ya que myisamchk no cambia la tabla en modo descripción, no hay riesgo de destruir los datos.

- myisamchk -d -v `nombre_tabla`

  Añadiendo `-v` myisamchk se ejecuta en modo información (verbose) así que produce más información acerca de lo que está haciendo.

- myisamchk -eis `nombre_tabla`

  Muestra sólo la información más importante de una tabla. Esta operación es lenta ya que debe leer la tabla entera.

- myisamchk -eiv `nombre_tabla`

  Es como `-eis`, pero dice lo que está haciendo.

A continuación hay unos ejemplos de la salida de estos comandos. Están basados en una tabla con estos tamañanos de fichero de datos e índices:

    -rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
    -rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM

Ejemplos de salida de myisamchk -d:

    MyISAM file:     company.MYI
    Record format:   Fixed length
    Data records:    1403698  Deleted blocks:         0
    Recordlength:    226

    table description:
    Key Start Len Index   Type
    1   2     8   unique  double
    2   15    10  multip. text packed stripped
    3   219   8   multip. double
    4   63    10  multip. text packed stripped
    5   167   2   multip. unsigned short
    6   177   4   multip. unsigned long
    7   155   4   multip. text
    8   138   4   multip. unsigned long
    9   177   4   multip. unsigned long
        193   1           text

Ejemplo de salida de myisamchk -d -v:

    MyISAM file:         company
    Record format:       Fixed length
    File-version:        1
    Creation time:       1999-10-30 12:12:51
    Recover time:        1999-10-31 19:13:01
    Status:              checked
    Data records:            1403698  Deleted blocks:              0
    Datafile parts:          1403698  Deleted data:                0
    Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3
    Max datafile length:  3791650815  Max keyfile length: 4294967294
    Recordlength:                226

    table description:
    Key Start Len Index   Type                  Rec/key     Root Blocksize
    1   2     8   unique  double                      1 15845376      1024
    2   15    10  multip. text packed stripped        2 25062400      1024
    3   219   8   multip. double                     73 40907776      1024
    4   63    10  multip. text packed stripped        5 48097280      1024
    5   167   2   multip. unsigned short           4840 55200768      1024
    6   177   4   multip. unsigned long            1346 65145856      1024
    7   155   4   multip. text                     4995 75090944      1024
    8   138   4   multip. unsigned long              87 85036032      1024
    9   177   4   multip. unsigned long             178 96481280      1024
        193   1           text

Ejemplo de salida de myisamchk -eis:

    Checking MyISAM file: company
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:  98%  Packed:   17%

    Records:          1403698    M.recordlength:     226
    Packed:             0%
    Recordspace used:     100%   Empty space:          0%
    Blocks/Record:   1.00
    Record blocks:    1403698    Delete blocks:        0
    Recorddata:     317235748    Deleted data:         0
    Lost space:             0    Linkdata:             0

    User time 1626.51, System time 232.36
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 639, Involuntary context switches 28966

Ejemplo de salida de myisamchk -eiv:

    Checking MyISAM file: company
    Data records: 1403698   Deleted blocks:       0
    - check file-size
    - check delete-chain
    block_size 1024:
    index  1:
    index  2:
    index  3:
    index  4:
    index  5:
    index  6:
    index  7:
    index  8:
    index  9:
    No recordlinks
    - check index reference
    - check data record references index: 1
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 2
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    - check data record references index: 3
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    - check data record references index: 5
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 6
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 7
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 8
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 9
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:   9%  Packed:   17%

    - check records and index references
    [LOTS OF ROW NUMBERS DELETED]

    Records:         1403698   M.recordlength:   226   Packed:           0%
    Recordspace used:    100%  Empty space:        0%  Blocks/Record: 1.00
    Record blocks:   1403698   Delete blocks:      0
    Recorddata:    317235748   Deleted data:       0
    Lost space:            0   Linkdata:           0

    User time 1639.63, System time 251.61
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
    Blocks in 4 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 10604, Involuntary context switches 122798

Explicación de los tipos de información que produce myisamchk se dan a continación. ``Keyfile'' se refiere al fichero índice. ``Record'' y ``row'' son sinónimos.

- `MyISAM file`(Fichero MyISAM)

  Nombre del fichero índice `MyISAM`.

- `File-version`(Versión del fichero)

  Versión del formato `MyISAM`. Actualmente siempre es 2.

- `Creation time`(Fecha de creación)

  Cuando se creó el fichero de datos.

- `Recover time`(Fecha de recuperación)

  Cuando el fichero de índices/datos se reconstruyó por última vez.

- `Data records`(Fecha de recuperación)

  Cuántos registros hay en la tabla.

- `Deleted blocks`(Bloques borrados)

  Cuántos bloques borrados todavía tienen espacio reservado. Puede optimizar la tabla para minimizar este espacio. Consulte Sección 5.8.3.10, “Optimización de tablas”.

- `Datafile parts`(Partes de ficheros de datos)

  Para el formato de registros dinámicos, indica cuántos bloques de datos hay. Para una tabla optimizada sin registros fragmentados, es lo mismo que `Registros de datos`.

- `Deleted data`(Datos borrados)

  Cuántos bytes hay de datos borrados sin reclamar. Puede optimizar la tabla para minimizar este espacio. Consulte Sección 5.8.3.10, “Optimización de tablas”.

- `Datafile pointer`(Puntero fichero de datos)

  El tamaño del puntero del fichero de datos, en bytes. Normalmente es de 2, 3, 4, o 5 bytes. La mayoría de tablas se administran con 2 bytes, pero MySQL no puede controlar esto todavía. Para tablas arregladas, esta es la dirección de un registro. Para tablas dinámicas, es la dirección de un byte.

- `Keyfile pointer`(Puntero fichero de claves)

  El tamaño del puntero del fichero índice, en bytes. Normalmente es de 1, 2, o 3 bytes. La mayoría de tablas se administran con 2 bytes, pero esto se calcula automáticamente por MySQL. Siempre es la dirección de un bloque.

- `Max datafile length`(Máximo tamaño fichero de datos)

  Cuánto puede crecer el fichero de datos, en bytes.

- `Max keyfile length`(Máximo tamaño fichero de claves)

  Cuánto puede creceer el fichero índice, en bytes.

- `Recordlength`(Tamaño registro)

  El tamaño de cada registro, en bytes.

- `Record format`(Formato de registro)

  El formato usado para almacenar registro de tablas. Los ejemplos precedentes usan `Fixed length`. Otros valores posibles son `Compressed` y `Packed`.

- `table description`(Descripción de tabla)

  Una lista de todas las claves en la tabla. Para cada clave, myisamchk muestra alguna información a bajo nivel:

  - `Key`(Clave)

    El número de esta clave.

  - `Start`(Inicio)

    Dónde en el registro comienza esta parte del índice.

  - `Len`(Longitud)

    El tamaño de esta parte del índice. Para números empaquetados, este debería ser siempre la longitud completa de la columna. Para cadenas de carácteres, podría ser menor que la longitud total de la columna indexada, ya que puede indexar un prefijo de una columna de cadenas de carácteres.

  - `Index`(Índice)

    Si un valor clave puede existir múltiples veces en el índice. Los valores son `unique` o `multip.` (múltiples).

  - `Type`(Tipo)

    Qué tipo de datos tiene esta parte del índice. Este es un tipo de datos `MyISAM` con las opciones `packed`, `stripped`, o `empty`.

  - `Root`(Raíz)

    Dirección del bloque índice raíz.

  - `Blocksize`(Tamaño de bloque)

    El tamaño de cada bloque de índices. Por defecto es de 1024, pero el valor puede cambiar en tiempo de compilación cuando MySQL se construye desde el código fuente.

  - `Rec/key`(Registros/clave)

    Este es un valor estadístico usado por el optimizador. Dice cuántos registros hay por valor para esta clave. Una clave única siempre tiene un valor de 1. Puede actualizarse tras la carga de una tabla (o muy cambiada) con myisamchk -a. Si no se actualiza en absoluto, el valor por defecto es 30.

  Para la tabla mostrada en los ejemplos, hay dos líneas para `table description` (descripción de tabla) para el noveno índice. Esto indica que es un índice de múltiples partes, en este caso con dos.

- `Keyblocks used`(Bloques de claves usados)

  Porcentaje de los bloques de clave usados. Cuando una tabla se ha reorganizad con myisamchk, como en los ejemplos, los valores son muy altos (muy cerca del máximo teórico).

- `Packed`(Empaquetado)

  MySQL intenta empaquetar las claves con un sufijo común. Sólo puede usarse para índices en columnas `CHAR`, `VARCHAR` . Para cadenas de carácteres largas que tienen partes izquierdas de la cadena similares, esto puede reducir significativamente el espacio usado. En el tercer ejemplo dado anteriomente, la cuarta clave tiene una longitud de 10 carácteres y se consigue una reducción del 60% del espacio.

- `Max levels`(Número máximo de niveles)

  La profunidad del árbol-B para esta clave. Tablas grandes con valores de clave grandes obtienen valores altos.

- `Records`Registros

  Número de registros en la tabla.

- `M.recordlength`Longitud de registro media

  La media de la longitud de los registros. Este valor es la longitud de registro para tablas con registros de longitud fija, ya que todos los registros tienen la misma longitud.

- `Packed`Empaquetado

  Espacios vacíos al final de las cadenas de carácteres en MySQL. El valor `Packed` indica el porcentaje de ahorro conseguido haciendo un empaquetado.

- `Recordspace used`Espacio de registro usado

  Porcentaje del fichero de datos usado.

- `Empty space`Espacio vacío

  Porcentaje del fichero de datos sin usar.

- `Blocks/Record`Bloques/Registro

  Número medio de bloques por registro (de cuántos enlaces se compone un registro fragmentado). Siempre es 1.0 para una tabla con formato fijo. Este valor debe estar tan cercano a 1.0 como sea posible. Si crece mucho, puede reorganizar la tabla. Consulte Sección 5.8.3.10, “Optimización de tablas”.

- `Recordblocks`Bloques de registro

  Cuántos bloques (enlaces) se usan. Para formato fijo, esto es lo mismo que el número de registros.

- `Deleteblocks`Bloques borrados

  Cuántos bloques (enlaces) están borrados.

- `Recorddata`Datos de registro

  Cuántos bytes en el fichero de datos se usan.

- `Deleted data`Datos borrados

  Cuántos bytes en el fichero de datos están borrados (no usados).

- `Lost space`Espacio perdido

  Si un registro se actualiza a una longitudo más pequeña, se pierde algo de espacio. Este valor es la suma de todas estas pérdidas, en bytes.

- `Linkdata`Datos enlazados

  Cuando se usa el formato de tabla dinámico, los fragmentos de registros se enlazan con punteros (de 4 a 7 bytes cada uno). `Linkdata` es la suma de la cantidad de almacenamiento usada por estos punteros.

Si una tabla se ha comprimido con myisampack, myisamchk -d muestra información adicional acerca de cada columna de la tabla. Consulte Sección 8.2, “myisampack, el generador de tablas comprimidas de sólo lectura de MySQL”, para un ejemplo de esta información y una descripción de lo que significa.

## 5.9. Uso internacional y localización de MySQL

Esta sección explica como configurar el servidor para utilizar diferentes juegos de carácteres. También explica como establecer la zona horaria del servidor, y activar el soporte para zonas horarias por conexión.

### 5.9.1. El conjunto de caracteres utilizado para datos y ordenación

Por defecto, MySQL utiliza el juego de carácteres ISO-8859-1 (Latin1), con ordenación de acuerdo a las reglas Suecas/Finlandesas. Estos valores por defecto son aplicables a los Estados Unidos y la mayoría de Europa occidental.

Todas las distribuciones binarias de MySQL se compilan con la opción `--with-extra-charsets=complex`. Esto añade código a todos los programas estándard que les permite manejar el juego de carácteres `latin1` y todos los juegos de carácteres multi-byte desde el binario. Otros juegos de carácteres se cargan desde un archivo de definición, cuando sea necesario.

El juego de carácteres determina qué carácteres se permiten en los nombres. También determina como las cadenas de carácteres se ordenan mediante las cláusulas `ORDER BY` y `GROUP BY` de la sentencia `SELECT`.

Puede cambiar el juego de carácteres con la opción `--default-character-set` cuando inicie el servidor. Los juegos de carácteres disponibles dependen de las opciones `--with-charset=`charset`` y `--with-extra-charsets=`list-of-charsets` | complex | all | none` del comando configure, y los archivos de configuración de juegos de carácteres enumerados en `SHAREDIR/charsets/Index`. Consulte Sección 2.8.2, “Opciones típicas de configure”.

En MySQL 5.0, también puede cambiar la colación del juego de carácteres con la opción `--default-collation` cuando inicie el servidor. La colación debe ser alguna que sea válida para el juego de carácteres por defecto. (Utilice la sentencia `SHOW COLLATION` para determinar qué colaciones están disponibles para cada juego de carácteres.) Consulte Sección 2.8.2, “Opciones típicas de configure”.

Si usted cambia el juego de carácteres cuando ejecuta MySQL, esto también podría cambiar la ordenación. En consecuencia, debe ejecutar myisamchk -r -q --set-character-set=`charset` en todas sus tablas, o sus índices podrían no estar ordenados correctamente.

Cuando un cliente se conecta a un servidor MySQL, el servidor indica al cliente cúal es el juego de carácteres por defecto del servidor. El cliente se adapta entonces para utilizar este juego de carácteres en su conexión.

Debería utilizar `mysql_real_escape_string()` cuando escape cadenas de carácteres para una sentencia SQL. `mysql_real_escape_string()` es idéntica a la antigua función `mysql_escape_string()`, excepto que toma el identificador de conexión `MYSQL` como primer parámetro para que pueda tenerse en cuenta el juego de carácteres apropiado cuando se escapan carácteres.

Si el cliente ha sido compilado con rutas diferentes a las del servidor que está instalado, y el usuario que configuró MySQL no incluyó todos los juegos de carácteres en el binario de MySQL, debe indicarle al cliente dónde puede encontrar los juegos de carácteres adicionales que necesita si el servidor ejecuta un juego de carácteres diferente.

Puede hacerlo especificando la opción `--character-sets-dir` para indicar la ruta al directorio donde se encuentra los juegos de carácteres dinámicos de MySQL. Por ejemplo, podría poner lo siguiente en un archivo de opciones:

    [client]
    character-sets-dir=/usr/local/mysql/share/mysql/charsets

Puede forzar a que el cliente utilice un juego de carácteres específico de la siguiente manera:

    [client]
    default-character-set=charset

De todas formas, normalmente, esto no es necesario.

#### 5.9.1.1. Usar el conjunto de caracteres alemán

En MySQL 5.0, el juego de carácteres y la colación se especifican separadamente. Esto significa que si quiere la ordenación alemana, debería seleccionar el juego de carácteres `latin1` y las colaciones `latin1_german1_ci` o `latin1_german2_ci`. Por ejemplo, para iniciar el servidor con la colación `latin1_german1_ci`, utilice las opciones `--character-set-server=latin1` y `--collation-server=latin1_german1_ci`.

Para obtener más información sobre las diferencias entre estas dos colaciones, consulte Sección 10.10.2, “Conjuntos de caracteres de Europa occidental”.

### 5.9.2. Escoger el idioma de los mensajes de error

Por defecto, mysqld produce mensajes de error en inglés, pero también puede producirlos en cualquiera de estos otros idiomas: alemán, checo, danés, eslovaco, español, estonio, francés, griego, holandés, húngaro, italiano, japonés, koreano, noruego, polaco, portugués, rumano, ruso o sueco.

Para iniciar mysqld con un idioma particular para los mensajes de error, utilice la opción `--language` o `-L`. El valor de la opción puede ser el nombre de un idioma o la ruta completa al archivo de mensajes de error. Por ejemplo:

    shell> mysqld --language=swedish

O:

    shell> mysqld --language=/usr/local/share/swedish

El nombre del idioma debe ser especificado en minúsculas.

Los archivos de idiomas están almacenados (por defecto) en el directorio `share/`LANGUAGE`` bajo el directorio base de MySQL.

Para cambiar el archivo de mensajes de error, debería editar el archivo `errmsg.txt`, y después ejecutar el siguiente comando para generar el archivo `errmsg.sys`:

    shell> comp_err errmsg.txt errmsg.sys

Si actualiza a una versión más nueva de MySQL, recuerde repetir los cambios con el nuevo archivo `errmsg.txt`.

### 5.9.3. Añadir un conjunto de caracteres nuevo

Esta sección explica el procedimiento para añadir nuevos juegos de carácteres a MySQL. Debe tener una distribución de código fuente de MySQL para utilizar estas instrucciones.

Para escoger el método apropiado, decida si el juego de carácteres es simple o complejo:

- Si el juego de carácteres no necesita rutinas especiales de colación para ordenar, y no necesita soporte para cáracteres multi-byte, es simple.

- Si necesita cualquiera de esas características, es complejo.

Por ejemplo, `latin1` y `danish` son juegos de carácteres simples, mientras que `big5` y `czech` son complejos.

En los siguientes procedimientos, el nombre de su juego de carácteres está representado por `MYSET`.

Para un juego de carácteres simple, haga lo siguiente:

1. Añada `MYSET` al final del archivo `sql/share/charsets/Index`. Asígnele un número único.

2. Cree el archivo `sql/share/charsets/`MYSET`.conf`. (puede utilizar una copia de `sql/share/charsets/latin1.conf` en la que basarse.)

   La sintaxis de este archivo es muy simple:

   - Los comentarios comienzan con un carácter'`#`' y continuan hasta el final de la línea.

   - Las palabras están separadas por un número de espacios arbitrario.

   - Al definir el juego de carácteres, cada palabra debe ser un número en formato hexadecimal.

   - El array `ctype` ocupa las primeras 257 palabras. Los arrays `to_lower[]`, `to_upper[]` y `sort_order[]` ocupan 256 cada uno después de eso.

   Consulte Sección 5.9.4, “Los vectores de definición de caracteres”.

3. Añada el nombre del juego de carácteres a las listas `CHARSETS_AVAILABLE` y `COMPILED_CHARSETS` en `configure.in`.

4. Reconfigurar, recompilar, y comprobar.

Para un juego de carácteres complicado, haga lo siguiente:

1. Cree el archivo `strings/ctype-`MYSET`.c` en la distribución de código fuente MySQL.

2. Añada `MYSET` al final del archivo `sql/share/charsets/Index`. Asígnele un número único.

3. Mira uno de los archivos `ctype-*.c` existentes (por ejemplo `strings/ctype-big5.c`) para ver qué necesita definir. Tenga en cuenta que los arrays del archivo deben tener nombres como `ctype_`MYSET``, `to_lower_`MYSET``, y etc. Estos corresponden a los arrays para un juego de carácteres simple. Consulte Sección 5.9.4, “Los vectores de definición de caracteres”.

4. Cerca del inicio del archivo, ponga un comentario especial como este:

       /*
        * This comment is parsed by configure to create ctype.c,
        * so don't change it unless you know what you are doing.
        *
        * .configure. number_MYSET=MYNUMBER
        * .configure. strxfrm_multiply_MYSET=N
        * .configure. mbmaxlen_MYSET=N
        */

   El programa configure utiliza este comentario para incluir el juego de carácteres en la librería MySQL automaticamente.

   Las líneas `strxfrm_multiply` y `mbmaxlen` se explican en las siguientes secciones. Necesita incluirlas sólo si necesita las funciones de colación de cadenas de carácteres o de carácteres multi-bye, respectivamente.

5. Debería crear entonces alguna de las siguientes funciones:

   - `my_strncoll_`MYSET`()`

   - `my_strcoll_`MYSET`()`

   - `my_strxfrm_`MYSET`()`

   - `my_like_range_`MYSET`()`

   Consulte Sección 5.9.5, “Soporte para colación de cadenas de caracteres”.

6. Añada el nombre del juego de carácteres a las listas `CHARSETS_AVAILABLE` y `COMPILED_CHARSETS` en `configure.in`.

7. Reconfigure, recompile, y compruebe.

El archivo `sql/share/charsets/README` incluye instrucciones adicionales.

Si quiere que el juego de carácteres sea incluido en la distribución MySQL, envíe un parche a la lista de correo `internals` de MySQL. Consulte Sección 1.6.1.1, “Las listas de correo de MySQL”.

### 5.9.4. Los vectores de definición de caracteres

`to_lower[]` y `to_upper[]` son arrays simples que contienen los carácteres en minúsucula y mayúscula correspondientes a cada miembro del juego de carácteres. Por ejemplo:

    to_lower['A'] debería contener 'a'
    to_upper['a'] debería contener 'A'

`sort_order[]` es un mapa indicando cómo deberían ser ordenados los carácteres para comparación y propósitos de ordenación. Frecuentemente (pero no en todos los juegos de carácteres) este es idéntico a `to_upper[]`, lo que significa que la ordenación es independiente de la capitalización. MySQL ordena carácteres basándose en los valores de los elementos de `sort_order[]`. Para reglas de ordenación más complicadas, consulte la explicación de colación de cadena de carácteres en Sección 5.9.5, “Soporte para colación de cadenas de caracteres”.

`ctype[]` es un array de valores binarios, con un elemento para cada carácter. (Tenga en cuenta que `to_lower[]`, `to_upper[]`, y `sort_order[]` son idexados por valor del carácter, pero `ctype[]` es indexado por el valor del carácter + 1. Esto es una convención antigua heredada para poder gestionar `EOF`.)

Puede entontrar las siguientes definiciones de máscaras de bits en `m_ctype.h`:

    #define _U      01      /* Uppercase */
    #define _L      02      /* Lowercase */
    #define _N      04      /* Numeral (digit) */
    #define _S      010     /* Spacing character */
    #define _P      020     /* Punctuation */
    #define _C      040     /* Control character */
    #define _B      0100    /* Blank */
    #define _X      0200    /* heXadecimal digit */

El valor de `ctype[]` para cada carácter debería ser la unión de los valors de máscara aplicables que describan al carácter. Por ejemplo, `'A'` es un carácter en mayúsculas (`_U`) y también es un dígito hexadecimal (`_X`), así que `ctype['A'+1]` debería tener el valor:

    _U + _X = 01 + 0200 = 0201

### 5.9.5. Soporte para colación de cadenas de caracteres

Si las reglas de ordenación para su lenguaje son demasiado complejas para ser gestionadas con la sencilla tabla `sort_order[]`, necesita utilizar las funciones de colación de cadenas de carácteres.

La mejor documentación para este propósito son los juegos de carácteres existentes. Mire los juegos de carácteres `big5`, `czech`, `gbk`, `sjis`, y `tis160` en busca de ejemplos.

Debe especificar el valor `strxfrm_multiply_`MYSET`=`N`` en el comentario especial al principio del archivo. `N` debería tener el máximo ratio en que pueda crecer las cadenas de carácteres durante `my_strxfrm_`MYSET`` (debe ser un entero positivo).

### 5.9.6. Soporte de caracteres multi-byte

Si quiere añadir soporte para un juego de carácteres nuevo que incluye carácteres multi-byte, necesita utilizar las funciones de carácter multi-byte.

La mejor documentación para este propósito son los juegos de carácteres existentes. Mire los juegos de carácteres `euc_kr`, `gb2312`, `gbk`, `sjis`, y `ujis` para encontrar ejemplos. Estos se encuentran en el archivo `ctype-`charset`.c` del directorio `strings`.

Debe especificar el valor de `mbmaxlen_`MYSET`=`N`` en el comentario especial al inicio del archivo fuente. `N` debería tener el tamaño en bytes del carácter más grande en el juego.

### 5.9.7. Problemas con conjuntos de caracteres

Si trata de utilizar un juego de carácteres que no está compilado en el binario, podría encontrarse con los siguientes problemas:

- Su programa tiene la ruta incorrecta de almacenamiento de los juegos de carácteres. (Por defecto `/usr/local/mysql/share/mysql/charsets`). Esto puede arreglarse utilizando la opción `--character-sets-dir` para ejecutar el programa en cuestión.

- El juego de carácteres es un juego multi-byte que no puede cargarse dinámicamente. En este caso, debe recompilar el programa con soporte para el juego de carácteres.

- El juego de carácteres es un juego de carácteres dinámico, pero no tiene un fichero de configuración para él. En este caso, debería instalar el archivo de configuración de una nuevo distribución MySQL.

- Si su archivo `Index` no contiene el nombre del juego de carácteres, su programa mostrará el siguiente mensaje de error:

      ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
      not found (Errcode: 2)

  En este caso, debería obtener un nuevo archivo `Index` o bien añadir el nombre manualmente de cualquier juego de carácteres que falte en el archivo actual.

Para las tablas `MyISAM`, puede comprobar el nombre del juego de carácteres y el número de una tabla con myisamchk -dvv `tbl_name`.

### 5.9.8. Soporte de zonas horarias en el servidor MySQL

En MySQL 5.0, el servidor mantiene varios ajustos de zonas horarias:

- La zona horaria del sistema. Cuando el servidor se inicia, intenta determinar la zona horaria de la máquina que lo aloja y lo utiliza para establecer la variable de sistema `system_time_zone`.

- La zona horaria del servidor. La variable global del sistema `time_zone` indica la zona horaria en que el servidor está operando actualmente. El valor inicial es `'SYSTEM'`, que indica que la zona horaria del servidor es la misma que la del sistema. El valor inicial puede ser especificado explícitamente con la opción `--default-time-zone=`timezone``. Si tiene el privilegio `SUPER`, puede establecer el valor global durante la ejecución, con esta sentencia:

      mysql> SET GLOBAL time_zone = timezone;

- Zonas horarias por conexión. Cada cliente que se conecta tiene su propio ajuste de zona horaria, otorgado por la variable de sesión `time_zone`. Inicialmente esta es la misma que la variable global `time_zone`, pero puede reestablecerse con esta sentencia:

      mysql> SET time_zone = timezone;

Los valores actuales de las zonas horarias globales y por conexión pueden consultarse así:

    mysql> SELECT @@global.time_zone, @@session.time_zone;

Los valores de `timezone` pueden darse como cadenas de carácteres indicando una variación con respecto a UTC, como por ejemplo `'+10:00'` o `'-6:00'`. Si las tablas relativas a las zonas horarias han sido creadas y rellenadas, también puede utilizar zonas horarias por su nombre, como `'Europe/Helsinki'`, `'US/Eastern'`, o `'MET'`. El valor `'SYSTEM'` indica que la zona horaria debería ser la misma que la del sistema. Los nombres de zonas horarias no distinguen capitalización (mayúsculas/minúsculas).

El procedimiento de instalación de MySQL crea las tablas de zonas horarias en la base de datos `mysql`, pero no las carga. Debe hacerlo usted manualmente. (Si está actualizando a MySQL 4.1.3 o superior desde una versión anterior, debe crear las tablas actualizando su base de datos `mysql`. Utilice las instrucciones que puede encontrar en Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.)

Si su sistema tiene su propia base de datos de información de zonas (el conjunto de archivos que describen zonas horarias), debería utilizar el programa mysql_tzinfo_to_sql para rellenar las tablas de zonas horarias. Ejemplos de esos sistemas son algunos como Linux, FreeBSD, Sun Solaris, y Mac OS X. Una localización probable para estos ficheros es el directorio `/usr/share/zoneinfo`. Si su sistema no tiene una base de datos de información de zonas, puede utilizar un paquete descargable descrito más adelante en esta sección.

El programa mysql_tzinfo_to_sql se utiliza para cargar las tablas de zonas horarias. En la línea de comandos, pase la ruta del directorio de los archivos de información de zonas a mysql_tzinfo_to_sql y envíe la salida al programa mysql. Por ejemplo:

    shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

mysql_tzinfo_to_sql lee los archivos de zona horaria de su sistema y genera sentencias SQL a partir de ellos. mysql procesa esas sentencias y las carga en las tablas de zona horaria.

mysql_tzinfo_to_sql también puede utilizarse para cargar un solo archivo de zona horaria.

Para cargar un solo archivo de zona horaria `tz_file` que corresponde a una zona horaria `tz_name`, invoque a mysql_tzinfo_to_sql de esta manera:

    shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql

Si su zona horaria necesita tener en cuenta segundos de diferencia, inicialice la información sobre segundos de diferencia de esta manera, donde `tz_file` es el nombre de su archivo de zona horaria:

    shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql

Si su sistema no tiene una base de datos de información de zonas (por ejemplo, Windows o HP-UX), puede utilizar el paquete preconfigurado de tablas de zonas horarias que está disponible en http://dev.mysql.com/downloads/timezones.html. Este paquete contiene los archivos `.frm`, `.MYD`, y `.MYI` para las tablas de zonas horarias `MyISAM`. Estas tablas deben pertenecer a la base de datos `mysql`, así que debe depositar los archivos en el subdirectorio `mysql` de su directorio de datos de MySQL. Debería apagar el servidor mientras hace esto.

¡Cuidado! Por favor, no utilice el paquete descargable si su sistema ya tiene una base de datos de información de zonas. Utilice en cambio la utilidad mysql_tzinfo_to_sql. Si no es así, podría causar una diferencia en el manejo de fechas entre MySQL y otras aplicaciones de su sistema.

Para información sobre los ajustes de zonas horarias en configuraciones de replicación consulte Sección 6.7, “Características de la replicación y problemas conocidos”.

## 5.10. Los ficheros de registro (log) de MySQL

MySQL tiene varios archivos de registro diferentes que pueden ayudarle a encontrar lo que está ocurriendo en mysqld:

Archivo de registro | Tipo de información registrado en el archivo
El registro de error | Registra problemas encontrados iniciando, ejecutando, o parando mysqld.
El registro de consultas | Registra las conexiones de clientes establecidas, y las sentencias ejecutadas.
El registro de actualizaciones The update log | Registra las sentencias que cambian datos. Este registro está ya en desuso.
El registro binario | Registra todas las sentencias que cambian datos. También utilizado para replicación.
El registro de lentitud | Registra todas las sentencias que tardarón más de `long_query_time` segundos en ejecutarse, o no utilizaron índices.

Por defecto, todos los registros son creados en el directorio de datos de mysqld. Puede forzar a mysqld a que cierre y reabra los archivos de registro (o en algunos casos, cambiar a un nuevo registro) mediante el volcado de registros. El volcado de registros ocurre cuando ejecuta la sentencia `FLUSH LOGS` o el comando mysqladmin flush-logs or mysqladmin refresh. Consulte Sección 13.5.5.2, “Sintaxis de `FLUSH`”.

Si está utilizando las capacidades de replicación de MySQL, los servidores esclavos de replicación mantienen unos registros adicionales llamados registros relay. Estos se explican en Capítulo 6, Replicación en MySQL.

### 5.10.1. El registro de errroes (Error Log)

El archivo de registro de errores contiene información que indica cuando se ha iniciado y parado mysqld y también si ha ocurrido algún error crítico mientras el servidor se estaba ejecutando.

Si mysqld termina inesperadamente y mysqld_safe necesita reiniciarlo, mysqld_safe escribe un mensaje `restarted mysqld` en el registro de errores. Si mysqld se da cuenta de que hay una tabla que necesita ser automáticamente comprobada o reparada, escribe un mensaje al registro de errores.

En algunos sistemas operativos, el registro de errores contiene un volcado de la pila si mysqld muere. El volcado puede ser utilizado para determinar cuando mysqld murió. Consulte Sección D.1.4, “Usar stack trace”.

En MySQL 5.0, puede especificar dónde quiere que mysqld almacene el registro de errores con la opción `--log-error[=`file_name`]`. Si no se proporciona ningún valor para `file_name`, mysqld utiliza el nombre ``host_name`.err` y escribe el archivo en el directorio de datos. Si ejecuta `FLUSH LOGS`, el registro de errores es renombrado con el sufijo `-old` y mysqld crea un nuevo archivo de registro.

Si no especifica `--log-error`, o (en Windows) no utiliza la opción `--console`, los errores se escriben en stderr, la salida estándar de erroes. Usualmente esto es su terminal.

En Windows, la salida de errores es siempre escrita al archivo `.err` si no se especifica la opción `--console`.

### 5.10.2. El registro general de consultas

Si quiere saber qué pasa en mysqld, debe iniciarlo con la opción `--log[=`file_name`]` o `-l [`file_name`]`. Si no se da un valor para `file_name`, el nombre por defecto es ``host_name`.log`. Esto registra todas las conexiones y sentencias a un archivo. Este registro puede ser muy útil cuando sospeche que hay un error en un cliente y quiera saber exactamente qué envió el cliente a mysqld.

mysqld escribe las sentencias al registro de consultas en el orden en que las recibe. Este orden puede ser diferente del de ejecución. Esto es aquí diferente que en el registro de actualizaciones o el registro binario, que son escritos tras la ejecución de la sentencia, pero antes de que se libere cualquier bloqueo. (El registro de consultas también contiene todas las sentencias, mientras que el registro binario no contiene sentencias que solo seleccionen datos.)

Los reinicios del servidor y volcado de registros no provocan que se genere un nuevo archivo de registro de consultas general (aunque el volcado lo cierra y lo reabre). En Unix, puede renombrar el archivo y crear uno nuevo utilizando los siguientes comandos:

    shell> mv hostname.log hostname-old.log
    shell> mysqladmin flush-logs
    shell> cp hostname-old.log to-backup-directory
    shell> rm hostname-old.log

En Windows, no puede renombrar el archivo de registro mientras el servidor lo tiene abierto. Debe parar el servidor y renombrar el registro. Después, reinicie el servidor para crear el nuevo registro.

### 5.10.3. El registro binario (Binary Log)

El registro binario contiene toda la información que está disponible en el registro de actualizaciones, en un formato más eficiente y de una manera que es segura para las transacciones.

El registro binario contiene todas las sentencias que han actualizado datos o podrían haberlo hecho (por ejemplo, un `DELETE` que no encontró filas concordantes). Las sentencias se almacenan en la forma de “eventos” que describen las modificaciones.

Atención: El registro binario ha reemplazado al antiguo registro de actualizaciones, que ya no está disponible a partir de MySQL 5.0.

El registro binario también contiene información sobre cuanto ha tardado cada sentencia que actualizó la base de datos. No contiene sentencias que no hayan modificado datos. Si quiere registrar todas las sentencias (por ejemplo, para identificar una sentencia problemática) debería utilizar el registro de consultas general. Consulte Sección 5.10.2, “El registro general de consultas”.

El propósito principal del registro binario es el de actualizar la base de datos durante una operación de recuperación tan completamente como sea posible, porque el registro binario contiene todas las actualizaciones hechas tras la copia de seguridad.

El registro binario también se utiliza en los servidores maestros de replicación como recordatorio de las sentencias que deben ser enviadas a los servidores esclavos. Consulte Capítulo 6, Replicación en MySQL.

Ejecutar el servidor con el registro binario activado hace que el rendimiento baje un 1%. Aún así, los beneficios del registro binario para las operaciones de restauración y el hecho de permitirnos poder establecer replicación generalmente son superiores a este decremento de rendimiento.

Cuando se ha iniciado con la opción `--log-bin[=`file_name`]` mysqld escribe un archivo de registro que contiene todos los comandos SQL que actualizan datos. Si no se da ningún valor para `file_name`, el valor por defecto es el nombre de la máuqina host seguido por `-bin`. Si se da el nombre del archivo, pero ninguna ruta, el archivo se escribe en el directorio de datos. Se recomienda especificar un nombre de archivo, consulte Sección A.8.4, “Cuestiones abiertas en MySQL” para ver el motivo.

Si usted proporciona una extensión en el nombre del registro (por ejemplo, `--log-bin=`file_name.extension``), la extensión se ignora y elimina sin aviso.

mysqld agraga una extensión numérica a el nombre del registro binario. Este número se incrementa cada vez que se inicia el servidor o se vuelcan los registros. También se crea un nuevo registro binario cuando el actual llega al tamaño especificado en `max_binlog_size`. Un registro binario puede llegar a ser más grande de `max_binlog_size` si está utilizando transacciones grandes: Una transacción se escribe en el registro de una sola pieza, nunca se parte entre diferentes registros.

Para poder averiguar qué archivos de registro binario diferentes han sido utilizados, mysqld también crea un archivo de índice de los registros binarios que contiene los nombres de todos los archivos de registro binario utilizados. Por defecto éste tiene el mismo nombre que el archivo de registro binario, con la extensión `'.index'`. Puede cambiar el nombre del archivo de índice con la opción `--log-bin-index[=`file_name`]`. No debería editar este archivo manualmente mientras mysqld se está ejecutando; hacerlo podría confundir a mysqld.

Puede borrar todos los archivos de registro binario con la sentencia `RESET MASTER`, o sólo algunos de ellos con `PURGE MASTER LOGS`. Consulte Sección 13.5.5.5, “Sintaxis de `RESET`” y Sección 13.6.1, “Sentencias SQL para el control de servidores maestros”.

El formato del registro binario tiene algunas limitaciones conocidas que pueden afectar a la recuperación de copias de seguridad. Consulte Sección 6.7, “Características de la replicación y problemas conocidos”.

El registro binario de procedimientos almacenados y disparadores se hace tal como se explica en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

Puede utilizar las siguientes opciones de mysqld para determinar lo que se registra en el registro binario. Vea también la explicación que sigue a esta lista de opciones.

- `--binlog-do-db=`db_name``

  Le dice al maestro que debería registrar los cambios en el registro binario si la base de datos actual (es decir, la que está seleccionada mediante `USE`) es `db_name`. Todos las otras bases de datos que no sean mencionadas explícitamente son ignoradas. Si utiliza esto, debería asegurarse de que sólo hace cambios en la base de datos actual.

  Tenga en cuenta que hay una excepción a esto en lo que respecta a las sentencias `CREATE DATABASE`, `ALTER DATABASE`, y `DROP DATABASE`, que utilizan la base de datos manipulada en vez de la actual para decidir si deberían registrar la sentencia.

  Un ejemplo de algo que no funciona como podría esperarse: Si el servidor se inició con `binlog-do-db=sales`, y usted ejecuta `USE prices; UPDATE sales.january SET amount=amount+1000;`, esta sentencia no llega a escribirse en el registro binario.

- `--binlog-ignore-db=`db_name``

  Le dice al maestro que las actualizaciones donde la base de datos actual (es decir, la que ha sido seleccionada mediante `USE`) es `db_name` no deberían ser almacenadas en el registro binario. Si utiliza esto, debería asegurarse de que solo hace actualizaciones en la base de datos actual.

  Un ejemplo de algo que no funciona como podría esperarse: Si el servidor se inició con `binlog-ignore-db=sales`, y ejecuta `USE prices; UPDATE sales.january SET amount=amount+1000;`, esta sentencia no se escribe en el registro binario.

  De la misma forma que en el caso de `--binlog-do-db`, hay una excepción para las sentencias `CREATE DATABASE`, `ALTER DATABASE`, y `DROP DATABASE`, que utilizan la base de datos manipulada para decidir si deben registrar la sentencia, en vez de la base de datos actual.

Para registrar o ignorar múltiples bases de datos, utilice múltiples opciones, especificando la opción apropiada una vez para cada base de datos.

Las reglas para registrar o ignorar actualizaciones en el registro binario son evaluadas de acuerdo a las siguientes normas. Tenga en cuenta que hay una excepción para las sentencias `CREATE DATABASE`, `ALTER DATABASE`, y `DROP DATABASE`. En esos casos, la base de datos que está siendo creada, alterada, o eliminada reemplaza a la base de datos actual en las reglas siguientes.

1. ¿Hay alguna regla `binlog-do-db` o `binlog-ignore-db`?

   - No: Escribir la sentencia al registro binario y salir.

   - Sí: Proceder al siguiente paso.

2. Hay algunas reglas (`binlog-do-db` o `binlog-ignore-db` o ambas). ¿Hay una base de datos actual (¿ha sido seleccionada alguna base de datos mediante `USE`?)?

   - No: No escribir la sentencia, y salir.

   - Sí: Proceder al siguiente paso.

3. Hay una base de datos actual. ¿Hay alguna regla `binlog-do-db`?

   - Sí: ¿Concuerda la base de datos con alguna de las reglas `binlog-do-db`?

     - Sí: Escribir la sentencia y salir.

     - No: No escribir la sentencia, y salir.

   - No: Proceder al siguiente paso.

4. Hay alguna regla `binlog-ignore-db`. ¿Concuerda la base de datos con alguna de las reglas `binlog-ignore-db`?

   - Sí: No escribir la sentencia, y salir.

   - No: Escribir la sentencia y salir.

Por ejemplo, un esclavo ejecutándose con sólo `binlog-do-db=sales` no escribe en el registro binario ninguna sentencia en la que la base de datos actual sea diferente de `sales` (es decir, a veces `binlog-do-db` puede significar ``ignora otras bases de datos'').

Si está utilizando replicación, debería no borrar los archivos de registros binarios viejos hasta que esté seguro de que ningún esclavo los necesita. Una manera de averiguarlo es hacer mysqladmin flush-logs una vez al día y borrar cualquier registro que tenga más de tres días de antigüedad. Puede borrarlos manualmente, o mejor aún mediante `PURGE MASTER LOGS` (consulte Sección 13.6.1, “Sentencias SQL para el control de servidores maestros”), que además también actualiza de manera segura el archivo de índice de registros binarios (y que puede recibir parámetros de fecha).

Un cliente con el privilegio `SUPER` puede desactivar el registro binario de sus propias sentencias utilizando una sentencia `SET SQL_LOG_BIN=0`. Consulte Sección 13.5.3, “Sintaxis de `SET`”.

Puede examinar el archivo de registro binario con la utilidad mysqlbinlog. Esto podría ser útil cuando usted quiera reprocesar sentencias almacenadas en el registro. Por ejemplo, puede actualizar un servidor MySQL desde el registro binario de la siguiente manera:

    shell> mysqlbinlog log-file | mysql -h server_name

Consulte Sección 8.5, “La utilidad mysqlbinlog para registros binarios” para obtener más información sobre la utilidad mysqlbinlog y su utilización.

Si usted está utilizando transacciones, debería utilizar el registro binario de MySQL para hacer las copias de seguridad, en vez del antiguo registro de actualizaciones.

El registro binario se hace inmediatamente después de que se completa una consulta, pero antes de que se libere cualquier bloqueo o se haga ningún commit. Esto asegura que el registro está almacenado en el orden de ejecución.

Las actualizaciones a las tablas no-transaccionales se almacenan en el registro binario inmediatamente después de su ejecución. Para las tablas transaccionales como las tablas `BDB` o `InnoDB`, todas las actualizaciones (`UPDATE`, `DELETE`, o `INSERT`) que cambian alguna tabla son almacenadas en cache hasta que se recibe una sentencia `COMMIT` en el servidor. En ese momento mysqld escribe la transacción completa al registro binario antes de que se ejecute el `COMMIT`. Cuando el flujo de ejecución que gestiona la transacción comienza, reserva un buffer de tamaño `binlog_cache_size` para almacenar consultas. Si una sentencia es más grande de esto, el flujo abre un archivo temporal para almacenar la transacción. El archivo temporal se borra cuando acaba el flujo.

La variable de estado `Binlog_cache_use` muestra el número de transacciones que han utilizado este buffer (y posiblemente un archivo temporal) para almacenar sentencias. La variable de estado `Binlog_cache_disk_use` muestra cuantas de esas transacciones llegaron realmente a utilizar un archivo temporal. Estas dos variables pueden utilizarse para establecer el valor de `binlog_cache_size` y evitar el uso de archivos temporales.

El tamaño `max_binlog_cache_size` (por defecto 4GB) se puede utilizar para restringir el tamaño total utilizado para almacenar una transacción con múltiples sentencias. Si una transacción es más grande que esto, falla y se hace un rollback.

Si usted está utilizando el registro de actualizaciones o el binario, las inserciones concurrentes se convierten a inserciones normales cuando se utiliza `CREATE ... SELECT` o `INSERT ... SELECT`. Esto se hace así para asegurarse de que se puede reconstruir una copia exacta de sus tablas aplicando los registros a una copia de seguridad.

Tenga en cuenta que el formato del registro binario es diferente en MySQL 5.0 al de versiones anteriores de MySQL, debido a mejoras en la replicación. Consulte Sección 6.5, “Compatibilidad entre versiones de MySQL con respecto a la replicación”.

Por defecto, el registro binario no se sincroniza con el disco en cada escritura. Así que si el sistema operativo o la máquina (no únicamente el servidor MySQL) falla, existe la posibilidad de que las últimas sentencias del registro binario se pierdan. Para prevenir esto, puede hacer que el registro binario se sincronice con el disco tras cada `N` escrituras, con la variable global `sync_binlog` (siendo 1 el valor más seguro, pero también el más lento). Consulte Sección 5.3.3, “Variables de sistema del servidor”. Aún con el valor de `sync_binlog` establecido en 1, existe una posibilidad de que haya una inconsistencia entre las tablas y el registro binario en el caso de fallo. Por ejemplo, si está utilizando tablas `InnoDB`, y el servidor MySQL procesa una sentencia `COMMIT`, escribe la transacción completa al registro binario, y después la envía a `InnoDB`. Si el fallo se produce entre estas dos operaciones, al reiniciar la transacción es rechazada por `InnoDB`, pero todavía existe en el registro binario. Este problema puede resolverse con la opción `--innodb-safe-binlog`, que añade consistencia entre el contenido de las tablas `InnoDB` y el registro binario.

Para que esta opción proporcione un grado mayor de seguridad, el servidor MySQL debe estar también configurado para sincronizar a disco, en cada transacción, el registro binario (`sync_binlog=1`) y (lo que es cierto por defecto) los registros `InnoDB`. El efecto de esta opción es que al reiniciar tras un fallo, o tras hacer un rollback de transacciones, el servidor MySQL elimina las transacciones `InnoDB` que han sufrido una cancelación del registro binario. Esto asegura que el registro binario refleje los datos exactos que hay en las tablas `InnoDB` y, así, el esclavo permanece sincronizado con el maestro (no recibe una sentencia que ha sido cancelada).

Tenga en cuenta que `--innodb-safe-binlog` se puede utilizar aún cuando el servidor MySQL actualice otros motores de almacenamiento que no sean `InnoDB`. Sólo las sentencia/transacciones que afecten a tablas `InnoDB` son candidatas a ser eliminadas del registro binario durante la recuperación de un fallo de `InnoDB`. Si durante la recuperación el servidor MySQL descubre que el registro binario es más corto de lo que debería ser (es decir, le falta al menos una transacción `InnoDB` realizada con éxito), lo que no debería ocurrir con `sync_binlog=1` y el disco/sistema de archivos hace una sincronización real cuando se le pide (algunos no lo hacen), muestra un mensaje de error ("The binary log <name> is shorter than its expected size"). En este caso el registro binario no es correcto, y la replicación debería reiniciarse desde una nueva imagen de los datos del maestro.

La escrituras al archivo del registro binario y al de índice de registros son gestionados de la misma manera que las escrituras a las tablas `MyISAM`. Consulte Sección A.4.3, “Cómo se comporta MySQL ante un disco lleno”.

### 5.10.4. El registro de consultas lentas (Slow Query Log)

Cuando se inicia con la opción `--log-slow-queries[=`file_name`]`, mysqld escribe un archivo de registro que contiene todos las sentencias SQL que llevaron más de `long_query_time` segundos para ejecutarse completamente. El tiempo para adquirir los bloqueos de tabla iniciales no se cuenta como tiempo de ejecución.

Si no se da ningún valor a `file_name`, el nombre por defecto es el nombre de la máquina host con el sufijo `-slow.log`. Si se da un nombre de archivo, pero no como ruta absoluta, el archivo se escribe en el directorio de datos.

Una sentencia se registra en el registro de consultas lentas después de que haya sido ejecutada y todos los bloqueos liberados. El orden de registro puede diferir del de ejecución.

El registro de consultas lentas se puede utilizar para encontrar consultas que tomen excesivo tiempo y sean por tanto candidatos a optimización. De cualquier modo, examinar un registro de consultas lentas puede convertirse en una tarea difícil. Para hacerlo más simple, puede procesar el registro de consultas lentas utilizando el comando mysqldumpslow que le ofrecerá un resumen de las sentencias que aparecen en el registro.

En el registro de consultas lentas de MySQL 5.0, las consultas lentas que no utilizan índices se registran igual que las que sí utilizan. Para prevenir que las consultas que no utilizan índices sean registradas en el registro de consultas lentas, utilice la opción `--log-short-format`. Consulte Sección 5.3.1, “Opciones del comando mysqld”.

En MySQL 5.0, la opción `--log-slow-admin-statements` del servidor le permite demandar el registro de sentencias administrativas lentas como `OPTIMIZE TABLE`, `ANALYZE TABLE`, y `ALTER TABLE` sean escritas en el registro de consultas lentas.

Las consultas gestionadas por la cache de consultas no son añadidas al registro de consultas lentas, ni tampoco las consultas que no se beneficien de la presencia de un índice porque la tabla tenga cero o una filas.

### 5.10.5. Mantenimiento de ficheros de registro (log)

El servidor MySQL puede crear un número de archivos de registro diferente que faciliten el ver que está pasando. Consulte Sección 5.10, “Los ficheros de registro (log) de MySQL”. De cualquier modo, debe limpiar estos archivos regularmente para asegurarse de que no ocupan demasiado espacio.

Cuando se utiliza MySQL con el registro activado, debería hacer copias de seguridad y eliminar los registros viejos de vez en cuando, y decirle a MySQL que comience a registrar en archivos nuevos. Consulte Sección 5.8.1, “Copias de seguridad de bases de datos”.

En una instalación Linux (Red Hat), puede utilizar el script `mysql-log-rotate` para esto. Si instaló MySQL desde una distribución RPM, el script debería haber sido instalado automáticamente. Debería tener cuidado con este script si está utilizando el registro binario para replicación; no elimine los registros binarios hasta que tenga la certeza de que sus contenidos han sido procesados por todos los esclavos.

En otros sistemas, debe instalar un script corto usted mismo desde cron o algo equivalente para gestionar los archivos de registros.

Puede forzar a MySQL para que comience a utilizar archivos de registro nuevos usando mysqladmin flush-logs o con la sentencia SQL `FLUSH LOGS`.

Una operación de volcado de registros hace lo siguiente:

- Si se está utilizando registro estándard (`--log`) o registro de consultas lentas (`--log-slow-queries`), cierra y reabre el archivo de registro (`mysql.log` y ``hostname`-slow.log` por defecto).

- Si se está utilizando registro de actualizaciones (`--log-update`) o registro binario (`--log-bin`) cierra el registro, y abre un nuevo archivo de registro con un número de secuencia superior.

Si está utilizando tan solo el registro de actualizaciones, tan solo tiene que renombrar el archivo de registro y posteriormente volcar los registros antes de hacer una copia de seguridad. Por ejemplo, puede hacer algo como esto:

    shell> cd mysql-data-directory
    shell> mv mysql.log mysql.old
    shell> mysqladmin flush-logs

Luego, haga una copia de seguridad y elimine `mysql.old`.

## 5.11. Ejecutar más de un servidor MySQL en la misma máquina

En algunos casos, podría querer ejecutar múltiples servidores mysqld en la misma máquina. Quizá quiera probar una nueva versión de MySQL dejando la configuración de producción sin cambios. O quizá quiera dar acceso para diferentes usuarios a diferentes servidores mysqld que ellos mismos puedan administrar. (Por ejemplo, podría ser un proeedor de servicios de Internet que proporcione instalaciones de MySQL independientes para cada cliente.)

Para ejecutar múltiples servidores en una única máquina, cada servidor tiene que tener valores únicos para los diferentes parámetros de operación. Estos se pueden establecer en la línea de comandos o en archivos de opciones. Consulte Sección 4.3, “Especificar opciones de programa”.

Al menos las siguientes opciones deben ser diferentes para cada servidor:

- `--port=`port_num``

  `--port` controla el número de puerto de las conexiones TCP/IP.

- `--socket=`path``

  `--socket` controla la ruta del archivo socket de Unix y el nombre de la named pipe en Windows. En Windows, es necesario especificar diferentes nombres de pipe solo para los servidores que soporten conexiones mediante named pipe.

- `--shared-memory-base-name=`name``

  Esta opción, actualmente, se utiliza sólo en Windows. Designa el nombre de memoria compartida utilizado por un servidor Windows para permitir a los clientes conectarse mediante memoria compartida.

- `--pid-file=`path``

  Esta opción se utiliza únicamente en Unix. Indica el nombre del archivo en el que el servidor escribe su ID de proceso.

Si utiliza las siguientes opciones de archivo de registro, deben ser diferentes para cada servidor:

- `--log=`path``

- `--log-bin=`path``

- `--log-update=`path``

- `--log-error=`path``

- `--bdb-logdir=`path``

Las opciones de archivo de registro se explican en Sección 5.10.5, “Mantenimiento de ficheros de registro (log)”.

Para un mejor rendimiento, puede especificar las siguientes opciones a cada servidor, de manera que se distribuya la carga entre discos físicos:

- `--tmpdir=`path``

- `--bdb-tmpdir=`path``

Tener diferentes directorios temporales también es una buena práctica, para hacer más fácil determinar qué servidor MySQL creó cualquier archivo temporal.

Generalmente, cada servidor debería utilizar un directorio de datos diferente, lo que se especifica con la opción `--datadir=path`.

Atención: Normalmente no debería tener dos servidores que actualicen los datos de la misma base de datos. Esto podría llevar a obtener sorpresas indeseadas si su sistema operativo no tiene soporte para bloqueos sin posibilidad de fallo. Si (a pesar de este aviso) ejecuta múltiples servidores que utilicen el mismo directorio de datos y tienen el registro activado, debería utilizar las opciones adecuadas para especificar nombres de archivos de registro que sean únicos para cada servidor. De otra manera, lo servidores intentan registrar en los mismos archivos. Por favor, tengan cuenta que este tipo de configuración sólo funciona con tablas `MyISAM` y `MERGE`, y no con ningún otro de los motores de almacenamiento.

Este aviso en contra de compartir un directorio de datos entre servidores también se aplica en entornos NFS. Permitir que múltiples servidores MySQL accedan a un directorio común es una muy mala idea.

- El principal problema es que NFS es un cuello de botella de velocidad. No está diseñado para un uso tal.

- Otro riesgo con NFS es que tiene que encontrar una manera de asegurarse que dos o más servidores no se interfieran unos con otros. Usualmente, el bloqueo de archivos de NFS está gestionado por el demonio `lockd`, pero de momento no hay ninguna plataforma que realice bloqueos 100% seguros en todas las situaciones.

Facilítese las cosas: Olvídese de compartir un directorio de datos entre servidores sobre NFS. Una solución mejor es tener una máquina que tenga diferentes CPUs y utilizar un sistema operativo que gestione los hilos de ejecución eficientemente.

Si tiene múltiples instalaciones de MySQL en diferentes lugares, normalmente puede especificar el directorio base de instalación para cada uno con la opción `--basedir=path`, de manera que cada servidor utilice un directorio de datos, archivo de registro, y archivo de PID diferentes. (Los valores por defecto de todos ellos son determinados en relación al directorio base). En ese caso, las únicas opciones adicionales que necesita especificar son las opciones `--socket` y `--port`. Por ejemplo, suponga que debe instalar diferentes versiones de MySQL utilizando distribuciones binarias en archivos `tar`. Se instalan en diferentes lugares, así que puede iniciar el servidor de cada instalación utilizando el comando bin/mysqld_safe bajo su correspondiente directorio base. ¡mysqld_safe determina la opción `--basedir` apropiada para pasarle a mysqld, y usted sólo necesita especificar las opciones `--socket` y `--port` a mysqld_safe.

Tal como se explica en las siguientes secciones, es posible iniciar servidores adicionales mediante el establecimiento de sus variables de entorno, o especificando opciones de línea de comandos apropiadas. Aún así, si necesita ejecutar servidores múltiples de manera permanente, es más conveniente utilizar archivos de opciones para especificar a cada servidor las opciones que deben ser únicas para él.

### 5.11.1. Ejecutar varios servidores en Windows

Puede ejecutar varios servidores en Windows iniciándolos manualmente desde la línea de comandos, cada uno con sus parámetros apropiados. En sistemas basados en Windows NT, tiene la opción de instalar varios servidores como servicios Windows y ejectuarlos de ese modo. Las instrucciones generales para ejecutar servidores MySQL desde la línea de comandos o como servicios se dan en Sección 2.3, “Instalar MySQL en Windows”.Esta sección describe cómo asegurarse que cada servidor arranca con distintos valores en las opciones de arranque que deban ser únicas para cada servidor, tales como el directorio de datos. Estas opciones se describen en Sección 5.11, “Ejecutar más de un servidor MySQL en la misma máquina”.

#### 5.11.1.1. Arrancar múltiples servidor Windows desde la raya de comando

Para arrancar manualmente múltiples servidores desde la línea de comandos, puede especificar las opciones apropiadas en la línea de comandos o en un fichero de opciones. Es más conveniente especificar las opciones en un fichero, pero es necesario asegurarse que cada servidor obtiene su propio conjunto de opciones. Para ello, cree un fichero de opciones para cada servidor y arranque el servidor con la opción `--defaults-file` cuando lo ejecute.

Suponga que desea ejectuar mysqld en el puerto 3307 con el directorio de datos en `C:\mydata1`, y mysqld-max en el puerto 3308 con un directorio de datos en `C:\mydata2`. (Para ello, asegúrese antes de copiar la base de datos `mysql` que contiene las tablas de permisos.)

A continuación cree dos ficheros de opciones. Por ejemplo, cree un fichero llamado `C:\my-opts1.cnf` que tenga este contenido:

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

Cree un segundo fichero llamado `C:\my-opts2.cnf` con este contenido:

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

A continuación, arranque cada servidor con su fichero de opciones:

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

En NT, cada servidor arranca en primer plano (no aparece un nuevo prompt hasta que acaba el servidor); necesitará ejectura estos dos comandos en una consola separada.

Para parar los servidores, debe conectarse al puerto apropiado:

    C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown
    C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown

Los servidores configurados tal y como se ha descrito permiten a los clientes la conexión mediante TPC/IP. Si su versión de Windows soporta named pipes y quiere permitir este tipo de conexiones, use los servidores mysqld-nt o mysqld-max-nt y especifique opiones que permitan la named pipe y especifique su nombre. Cada servidor que soporte conexiones mediante named pipes debe usear un nombre único. Por ejemplo, el fichero `C:\my-opts1.cnf` puede escribirse así:

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

A continuación, arranque el servidor así:

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

Modique `C:\my-opts2.cnf` similarmente para que lo use el segundo servidor.

#### 5.11.1.2. arrancar varios servidores Windows como servicios

En sistemas basados en NT, un servidor MySQL puede correr como un servicio de Windows. Los procedimientos para instalar, controlar, y eliminar un servico MySQL se describen en Sección 2.3.12, “Arrancar MySQL como un servicio de Windows”.

También puede instalar múltiples servidores MySQL como servicios. En este caso, debe asegurarse que cada servidor usa un nombre de servicio distinto además de todos los otros parámetros que deben ser únicos para cada servidor.

Para las siguientes instrucciones, se asume que desea ejectuar el servidor mysqld-nt a partir de dos versiones diferentes de MySQL que estén instaladas en `C:\mysql-4.1.8` y `C:\mysql-5.0.7`, respectivamente. (Este podría ser el caso si está ejecutando 4.1.8 como servidor de producción, pero quiere realizar tests usando 5.0.7.)

Los siguientes principios se aplican al instalar un servicio MySQL con las opciones `--install` o `--install-manual`:

- Si no especifica un nombre para el servicio, el servidor usa el nombre de servicio por defecto de `MySQL` y el servidor lee las opciones del grupo `[mysqld]` en el fichero estándard de opciones.

- Si especifica un nombre de servicio tras la opción `--install` , el servidor ignora el grupo de opciones `[mysqld]` y lee las opciones del grupo que tenga el mismo nombre que el servicio. El servidor lee opciones del fichero estándard de opciones.

- Si especifica la opción `--defaults-file` tras el nombre del servicio, el servidor ignoral el fichero estándard de opciones y lee opciones sólo del grupo `[mysqld]` del fichero especificado.

Nota: Antes de MySQL 4.0.17, sólo un servidor instalado usando el nombre de servicio por defecto (`MySQL`) o instalado explícitamente con el nombre de servicio de mysqld lee el grupo `[mysqld]` en el fichero de opciones estándard. Como en 4.0.17, todos los servidores leen el grupo `[mysqld]` si leen el fichero de opciones estándard, incluso si están instalados usando otro nombre de servicio. Esto permite usar el grupo `[mysqld]` para opciones que deben usarse por todos los servicios MySQL, y un grupo de opciones nombrado tras cada servicio para uso del servidor instalado con ese nombre de servicio.

Basándonos en la información precedente, hay varias formas de inicializar múltiples servicios. Las siguientes instrucciones describen algunos ejemplos. Antes de probar cualquiera de ellos, asegúrese que apaga y elimina cualquier servicio MySQL antes de nada.

- Aproximación 1: Espeficique las opciones para todos los servicios en uno de los ficheros de opciones estándard. Para ello, use un nombre de servicio distinto para cada servidor. Suponga que quiere ejecutar mysqld-nt 4.1.8 usando el nombre de servicio de `mysqld1` y mysqld-nt 5.0.7 usando el nombre de servicio `mysqld2`. En ese caso, puede usar el grupo `[mysqld1]` para 4.1.8 y el grupo `[mysqld2]` para 5.0.7. Por ejemplo, puede rellenar `C:\my.cnf` así:

      # options for mysqld1 service
      [mysqld1]
      basedir = C:/mysql-4.1.8
      port = 3307
      enable-named-pipe
      socket = mypipe1

      # options for mysqld2 service
      [mysqld2]
      basedir = C:/mysql-5.0.7
      port = 3308
      enable-named-pipe
      socket = mypipe2

  Instale los servicios como se describe a continuación, usando las rutas completas de los servidores para asegurarse que Windows registra el programa ejecutable correcto para cada servicio:

      C:\> C:\mysql-4.1.8\bin\mysqld-nt --install mysqld1
      C:\> C:\mysql-5.0.7\bin\mysqld-nt --install mysqld2

  Para arrancar los servicios, use el administrador de servicios, o use NET START con los nombres de servicio apropiados:

      C:\> NET START mysqld1
      C:\> NET START mysqld2

  Para parar los servicios, use el administrador de servicios, o use NET STOP con el nombre de servicio apropiado:

      C:\> NET STOP mysqld1
      C:\> NET STOP mysqld2

- Aproximación 2: Especifique opciones para cada servidor en ficheros separados y use `--defaults-file` cuando instale los servicios para decirle a cada servidor que fichero usar. En ese caso, cada fichero debe listar las opciones en el grupo `[mysqld]`.

  Con esta aproximación, para especificar opciones para mysqld-nt 4.1.8, cree un fichero `C:\my-opts1.cnf` como se muestra a continuación:

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

  Para mysqld-nt 5.0.7 , cree un fichero `C:\my-opts2.cnf` como se muestra a continuación:

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

  Instale los servicios como se muestra (introduzca cada comando en una línea distinta):

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

  Para usar la opción `--defaults-file` cuando instale un servidor MySQL como servicio, debe preceder la opción con el nombre de servicio.

  Tras instalar los servicios, arranque y párelos igual que en el ejemplo precedente.

Para eliminar múltiples servicios, use mysqld --remove para cada uno, especificando un nombre de servicio con la opción `--remove` a continuación. Si el nombre de servicio es el nombre por defecto (`MySQL`), puede omitirlo.

### 5.11.2. Ejecutar varios servidores en Unix

La forma más sencilla de ejecutar múltiples servidores en Unix es compilarlos con diferentes puertos TCP/IP y ficheros socket Unix de forma que cada uno esté escuchando en distintas interfaces de red. Además, al compilarlos en distintos directorios base para cada instalación, automáticamente se configuran distintos directorios de datos, fichero de log, y localización del fichero PID para cada uno de los servidores.

Tenga en cuenta que un servidor 4.1.8 existente está configurado para el puerto TCP/IP por defecto (3306) y fichero socket Unix (`/tmp/mysql.sock`). Para configurar un nuevo servidor 5.0.7 con parámetros distintos, use un comando configure parecido a este:

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

Aquí, `port_number` y `file_name` deben ser distintos del puerto TPC/IP por defecto y de la ruta del fichero socket Unix, y el valor `--prefix` debe especificar un fichero de instalación distinto del que hay donde MySQL se ha instalado por defecto.

Si tiene un servidor MySQL escuchando en un puerto dado, puede usar el siguiente comando para encontrar que parámetros está usando para algunas importantes variables de configuración, incluyendo el directorio base y el nombre del fichero socket Unix:

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

Con la información mostrada por este comando, puede decir los valores de las opciones que no debe usar para configurar un servidor adicional.

Tenga en cuenta que si especifica `localhost` como nombre de equipo, el comportamiento por defecto de mysqladmin es usar una conexión mediante un fichero socket Unix en lugar de TCP/IP. A partir de MySQL 4.1 , puede especificar explícitamente el protocolo de conexión a usar usando la opción `--protocol={TCP | SOCKET | PIPE | MEMORY}`.

No tiene que compilar un nuevo servidor MySQL para arrancar con un fichero socket Unix distinto o con otro puerto TCP/IP. También es posible especificar estos valores en tiempo de ejecución. Una forma de hacerlo es usando opciones por líneas de comandos:

    shell> mysqld_safe --socket=file_name --port=port_number

Para arrancar un segundo servidor, proporcione distintas opciones para `--socket` y `--port` option , e incluya la opción `--datadir=`path`` para mysqld_safe de forma que el servidor use un directorio de datos distinto.

Otra forma de conseguir un efecto similar es usar variables de entorno para inicializar el nombre de fichero socket Unix y el puerto TCP/IP:

    shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
    shell> MYSQL_TCP_PORT=3307
    shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
    shell> mysql_install_db --user=mysql
    shell> mysqld_safe --datadir=/path/to/datadir &

Hay una forma rápida de arrancar un segundo servidor para hacer pruebas. Lo bueno de este método es que los cambios en las variables de entorno se aplican a cualquier programa cliente que invoque desde la misma consola. Así, las conexiones de dichos clientes se redireccionan automáticamente al segundo servidor!

Apéndice E, Variables de entorno incluye una lista de otras variables de entorno que puede usar para afectar a mysqld.

Para ejecución automática del servidor, el script de arranque que se ejecuta al arrancar debe ejecutar el siguiente comando una vez para cada servidor con la ruta apropiada del fichero de opciones para cada comando:

    mysqld_safe --defaults-file=path

Cada fichero de opciones debe contener valores específicos para un servidor dado.

En Unix, el script mysqld_multi es otra forma de arrancar múltiples servidores. Consulte Sección 5.1.5, “El programa mysqld_multi para gestionar múltiples servidores MySQL”.

### 5.11.3. Utilización de programas cliente en un entorno de múltiples servidores

Cuando quiera conectar con un programa cliente a un servidor MySQL que está escuchando en una interfaz de red distinta de la compilada en su cliente, puede usar los siguientes métodos:

- Arranque el cliente con `--host=`host_name` --port=`port_number`` para conectar via TCP/IP a un servidor remoto, con `--host=127.0.0.1 --port=port_number` para conectar via TCP/IP a un servidor local, o con `--host=localhost --socket=`file_name`` para conectar a un servidor local via fichero socket Unix o una named pipe de Windows.

- Como en MySQL 4.1, arranque el cliente con `--protocol=tcp` para conectar via TCP/IP, `--protocol=socket` para conectar via fichero socket Unix , `--protocol=pipe` para conectar via named pipe, o `--protocol=memory` para conectar via memoria compartida. Para conexiones TCP/IP, puede necesitar especificar las opciones `--host` y `--port`. Para los otros tipos de conexión, puede necesitar especificar la opción `--socket` para especificar un fichero socket Unix o nombre de named pipe, o la opción `--shared-memory-base-name` para especificar el nombre de la memoria compartida. Las conexiones de memoria compartida se soportan sólo en Windows.

- En Unix, inicialice las variables de entorno `MYSQL_UNIX_PORT` y `MYSQL_TCP_PORT` para que apunten al fichero socket Unix y al puerto TCP/IP antes de arrancar los clientes. Si normalmente usa un fichero socket o puerto específico, puede preparar comandos para inicializar estas variables de entorno en su fichero `.login` para que se apliquen cada vez que entre. Consulte Apéndice E, Variables de entorno.

- Especifique el fichero socket Unix y el puerto TCP/IP por defecto en el grupo `[client]` de un fichero de opciones. Por ejemplo, puede usar `C:\my.cnf` en Windows, o el fichero `.my.cnf` en su directorio "home" en Unix. Consulte Sección 4.3.2, “Usar ficheros de opciones”.

- En un programa C, puede especificar los argumentos para el fichero socket o puerto en la llamada `mysql_real_connect()`. PUede tener las opciones leídas por el programa llamando a `mysql_options()`. Consulte Sección 24.3.3, “Descripción de funciones de la API C”.

- Si usa el módulo de Perl `DBD::mysql` , puede leer las opciones de los ficheros de opciones MySQL. Por ejemplo:

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

  Consulte Sección 24.5, “La API Perl de MySQL”.

  Otras interfaces de programación pueden proporcionar funcionalidad similar para leer ficheros de opciones.

## 5.12. La caché de consultas de MySQL

MySQL 5.0 Server proporciona una query cache. Cuando se usa, la query cache almacena el texto de una consulta `SELECT` junto con el resultado que se le envió al cliente. Si se recibe una consulta idéntica posteriormente, el servidor devuelve el resultado de la caché de consultas en lugar de parsear y ejecutar la consulta de nuevo.

La caché de consultas es muy útil en un entorno donde tiene tablas que no cambian frecuentemente y donde el servidor recibe muchas consultas idénticas. Esta es la típica situación de muchos servidores Web que generan muchas páginas dinámicas basadas en contenido de base de datos.

Nota: La caché de consultas no devuelve datos antiguos. Cuando las tablas se modifican, cualquier entrada relevante en la caché de consultas se eliminia.

Nota: La caché de consultas no funciona en un entorno donde tiene muchos servidores mysqld actualizando las mismas tablas `MyISAM`.

Nota: La caché de consultas no se usa para comandos preparados en la parte del servidor. Si está usando este tipo de comandos preparados, considere que no se beneficiarán de la caché de consultas. Consulte Sección 24.3.4, “Sentencias preparadas de la API C”.

A continuación algunos datos de rendimiento de la caché de consultas. Estos resultados se generaron con el MySQL benchmark suite en un Linux Alpha 2 x 500MHz con 2GB RAM y 64MB de caché de consultas.

- Si todas las consultas que está ejecutando son simples (tales como seleccionar un registro de una tabla con un registro), pero difierente de forma que las consultas no pueden cachearse, la pérdida de rendimiento por tener activa la caché de consultas es del 13%. Este puede considerarse el peor escenario posible. En el mundo real, las consultas suelen ser mucho más complicadas, así que la pérdida de rendimiento es considerablemente menor.

- Las búsquedas para un registro en una tabla de un registro són un 238% más rápidas con la caché de consultas que sin ella. Esto puede considerarse como la mínima mejora esperada para una consulta que se cachea.

Para desactivar la caché de consultas al arrancar el servidor, ponga la variable de sistema `query_cache_size` a 0. Al desactivar el código de caché de consultas, no hay una pérdida de rendimiento evidente. Las capacidades de la caché de consultas pueden quitarse totalmente del servidor usando la opción `--without-query-cache` con configure al compilar MySQL.

### 5.12.1. Cómo opera la caché de consultas

Esta sección describe cómo funciona la caché de consultas cuando está operacional. Sección 5.12.3, “Configuración de la caché de consultas” describe cómo controlar si está o no operacional.

Las consultas se comparan antes de parsearla, así que las siguientes dos consultas se consideran diferentes por la caché de consultas:

    SELECT * FROM tbl_name
    Select * from tbl_name

Las consultas deben ser exactamenten las mismas (byte a byte) para se consideradas idénticas. Además, las consultas que son idénticas pueden tratarse como diferentes por otras razones. Las consultas que usan distintas bases de datos, distintas versiones de protocolo, o distintos conjuntos de carácteres se consideran distintas consultas y se cachean por separado.

Antes que una consulta se guarde en la cache de consultas, MySQL comprueba que el usuario tenga permisos de `SELECT` para todas las bases de datos y tablas involucradas. Si no es el caso, el resultado cacheado no se usa.

Si un resultado de consulta se retorna desde la caché de consultas, el servidor incrementa la variable de estado `Qcache_hits`, no `Com_select`. Consulte Sección 5.12.4, “Estado y mantenimiento de la caché de consultas”.

Si una tabla cambia, entonces todas las consultas cacheadas que usen esa tabla pasan a ser inválidas y se eliminan de la caché.Esto incluye consultas que usen tablas `MERGE` que mapeen las tablas cambiadas. Una tabla puede cambiarse por varios tipos de comandos, tales como `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`, `ALTER TABLE`, `DROP TABLE`, o `DROP DATABASE`.

Las tablas transaccionales `InnoDB` que se han cambiado se invalidan cuando se realiza un `COMMIT`.

En MySQL 5.0, la caché de consultas también funciona dentro de transacciones cuando se usa tablas `InnoDB` ,haciendo uso del número de versión para detectar si sus contenidos han cambiado.

En MySQL 5.0, las consultas generadas por vistas se cachean. Un problema con los resultados en la caché de consultas generados por vistas que no se invalidaban apropiadamente tras algunas operaciones en dichas vistas se resolvión en MySQL 5.0.3. Consulte Sección C.1.9, “Cambios en la entrega 5.0.3 (23 Mar 2005: Beta)”.

Antes de MySQL 5.0, una consulta que empezase con un comentario podía cachearse, pero no podía obtenerse de la caché. Este problema está resuelto en MySQL 5.0.

La caché de consultas funciona para consultas del tipo `SELECT SQL_CALC_FOUND_ROWS ...` y `SELECT FOUND_ROWS()`. `FOUND_ROWS()` devuelve el valor correcto incluso si la consulta precedente se obtuvo de la cache debido a que el número de registros encontrados también se almacena en la caché.

Una consulta no puede cachearse si contiene cualquiera de las siguientes funciones:

`BENCHMARK()` | `CONNECTION_ID()` | `CURDATE()`
`CURRENT_DATE()` | `CURRENT_TIME()` | `CURRENT_TIMESTAMP()`
`CURTIME()` | `DATABASE()` | `ENCRYPT()` con un parámetro
`FOUND_ROWS()` | `GET_LOCK()` | `LAST_INSERT_ID()`
`LOAD_FILE()` | `MASTER_POS_WAIT()` | `NOW()`
`RAND()` | `RELEASE_LOCK()` | `SYSDATE()`
`UNIX_TIMESTAMP()` sin parámetros | `USER()` |

Una consulta tampoco se cachea bajo las siguientes condiciones:

- Se refiere a funciones definidas por el usuario (UDFs).

- Se refiere a variables de usuario.

- Se refiere a las tablas en la base de datos del sistema `mysql` .

- Es cualquiera de las siguientes formas:

      SELECT ... IN SHARE MODE
      SELECT ... FOR UPDATE
      SELECT ... INTO OUTFILE ...
      SELECT ... INTO DUMPFILE ...
      SELECT * FROM ... WHERE autoincrement_col IS NULL

  La última forma no se cachea ya que se usa como solución de ODBC para obtener el último ID insertado. Consulte Sección 25.1.6.1.1, “Obtaining Auto-Increment Values”.

- Se usó como comando preparado, incluso sin emplear marcadores. Por ejemplo, la consulta usada aquí:

      char *my_sql_stmt = "SELECT a, b FROM table_c";
      /* ... */
      mysql_stmt_prepare(stmt, my_sql_stmt, strlen(my_sql_stmt));

  no se cachea. Consulte Sección 24.3.4, “Sentencias preparadas de la API C”.

- Usa tablas `TEMPORARY`.

- No usa ninguna tabla.

- El usuario tiene permisos a nivel de columan para cualquiera de las tablas involucradas.

### 5.12.2. Opciones de `SELECT` para la caché de consultas

Dos opciones relacionadas con la caché de consultas pueden especificarse en los comandos `SELECT`:

- `SQL_CACHE`

  El resultado de la consulta se cachea si el valor de la variable de sistema `query_cache_type` es `ON` o `DEMAND`.

- `SQL_NO_CACHE`

  La consulta resultado no se cachea.

Ejemplos:

    SELECT SQL_CACHE id, name FROM customer;
    SELECT SQL_NO_CACHE id, name FROM customer;

### 5.12.3. Configuración de la caché de consultas

La variable de sistema `have_query_cache` indica si la caché de consultas está disponible:

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+

Cuando se usa un binario MySQL 5.0 estándard, este valor siempre es `YES`, incluso si el cacheo de consultas está desactivado.

Muchas otras variables de sistema controlan las operaciones de la caché de consultas. Estas pueden especificarse en un fichero de opciones o en la línea de comandos al arrancar mysqld. Las variables de sistema de la caché de consultas todas tienen nombres que empiezan con `query_cache_`. Se describen brevemente en Sección 5.3.3, “Variables de sistema del servidor”, con información adicional de configuracion dada aquí.

Para especificar el tamaño de la caché de consulta, inicialice la variable de sistema `query_cache_size`. Ponerla a 0 desactiva la caché de consultas. El tamaño por defecto de la caché es 0; esto es, que está desactivada.

Si el tamaño de la caché de consultas es mayor que 0, la variable `query_cache_type` influye en su funcionamiento. Esta variable puede tener los siguientes valores:

- Un valor de `0` o `OFF` evita cachear o recibir valores cacheados.

- Un valor de `1` o `ON` permite el cacheo excepto para aquellos comandos que empiecen con `SELECT SQL_NO_CACHE`.

- Un valor de `2` o `DEMAND` provoca el cacheo de sólo los comandos que empiecen con `SELECT SQL_CACHE`.

Inicializar con el valor `GLOBAL` la variable `query_cache_type` determina el comportamiento de la caché de consultas para todos los clientes que se conecten tras el cambio. Clientes individuales que controlan el comportamiento de la caché para su propia conexión meidante el valor `SESSION` de `query_cache_type`. Por ejemplo, un cliente puede desactivar el uso de la caché de consultas para sus propias consultas así:

    mysql> SET SESSION query_cache_type = OFF;

Para controlar el tamaño máximo de resultados de consultas individuales que pueden cachearse, inicialice la variable `query_cache_limit` variable. El valor por defecto es 1MB.

El resultado de una consulta (los datos enviados al cliente) se guardan en la caché de consulta durante la recepción del resultado. Por lo tanto los datos normalmente no se guardan en un gran paquete. La caché de consulta prepara bloques para guardar estos datos bajo demanda, así que cuando se llena un bloque, se prepara un nuevo bloque. Como la reserva de memoria es una operación costosa (lenta), la caché de consultas reserva bloques con un tamaño mínimo dado por la variable de sistema `query_cache_min_res_unit`. Cuando se ejecuta una consulta, el último bloque de resultados se ajusta al tamaño actual para liberar la memoria no usada. En función del tipo de consulta que ejecute el servidor, puede encontrar útil cambiar el variable de `query_cache_min_res_unit`:

- El valor por defecto de `query_cache_min_res_unit` es 4KB. Debe ser un valor adecuado para la mayoría de los casos.

- Si tiene muchas consultas con resultados pequeños, el tamaño de bloque por defecto puede llevar a fragmentación de memoria, como se indica con un alto número de bloques libres. La fragmentación puede forzar a la caché de consultas a borrar consultas de la caché debido a la falta de memoria. En este caso, debe decrementar el valor de `query_cache_min_res_unit`. El número de bloques libres y de consultas borradas debido a falta de espacio se da en las variables `Qcache_free_blocks` y `Qcache_lowmem_prunes`.

- Si la mayoría de las consultas tienen resultados grandes (compruebe las variables de estado `Qcache_total_blocks` y `Qcache_queries_in_cache` ), puede incrementar el rendimiento incrementando `query_cache_min_res_unit`. Sin embargo, tenga cuidado de no hacerlo demasiado grandes (consulte el punto anterior).

### 5.12.4. Estado y mantenimiento de la caché de consultas

Puede comprobar si la caché de consultas está presente en su servidor MySQL con el siguiente comando:

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+

Puede defragmentar la caché de consultas para mejor uso de esta memoria con el comando `FLUSH QUERY CACHE` . El comando no elimina ninguna consulta de la caché.

El comando `RESET QUERY CACHE` elimina todos los resultados de consultas de la caché de consultas. El comando `FLUSH TABLES` también lo hace.

Para monitorizar el rendimiento de la caché de consultas, use `SHOW STATUS` para ver las variables de estado de la caché:

    mysql> SHOW STATUS LIKE 'Qcache%';
    +-------------------------+--------+
    | Variable_name           | Value  |
    +-------------------------+--------+
    | Qcache_free_blocks      | 36     |
    | Qcache_free_memory      | 138488 |
    | Qcache_hits             | 79570  |
    | Qcache_inserts          | 27087  |
    | Qcache_lowmem_prunes    | 3114   |
    | Qcache_not_cached       | 22989  |
    | Qcache_queries_in_cache | 415    |
    | Qcache_total_blocks     | 912    |
    +-------------------------+--------+

Las descripicones de estas varibles se dan e Sección 5.3.4, “Variables de estado del servidor”. Algnos de sus usos se describen aquí.

El número total de consultas `SELECT` es igual a:

      Com_select
    + Qcache_hits
    + consultas con errores detectadas por el parser

El valor `Com_select` es igual a:

      Qcache_inserts
    + Qcache_not_cached
    + consultas con errores encontrados durante la comprobación de columnas/permisos

La caché de consultas usa bloques del tamaño de las variables, así `Qcache_total_blocks` y `Qcache_free_blocks` puede indicar la fragementación de memoria de la caché de consultas. Tras `FLUSH QUERY CACHE`, sólo queda un bloque de memoria libre.

Cada consulta cacheada requiere como mínimo dos bloques (uno para el texto de la consulta y otro o más para el resultado de la misma). Además, cada tabla que se usa por una consulta requiere un bloque. Sin embargo, si dos o más consultas usan la misma tabla, sólo un bloque necesita ser reservado.

La información proporcionada por la variable de estado `Qcache_lowmem_prunes` puede usarse para ayudarle a ajustar el tamaó de la caché de consutlas. Cuenta el número de consultas que se han eliminado de la caché para liberar memoria para cachear nuevas consultas. La caché de consultas usa una estrategia de último resultado usado (LRU) para decidir qué consultas eliminar de la caché. Información para ajustar las variables se da en Sección 5.12.3, “Configuración de la caché de consultas”.

É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 4. Usar los programas MySQL | Inicio | Capítulo 6. Replicación en MySQL