¿MySQL foreign_key_checks afecta a toda la base de datos?

201

Cuando ejecuto este comando en MySQL:

SET FOREIGN_KEY_CHECKS=0;

¿Afecta todo el motor o es solo mi transacción actual?

Sean Nguyen
fuente
15
prueba: inicie sesión en mysql: muestre variables como '% FOREIGN%'; SET FOREIGN_KEY_CHECKS = 0; Después de eso, inicie sesión en mysql usando una consola diferente. Puedo ver que mostrar variables como '%% EXTRANJERO' está ACTIVADO en lugar de DESACTIVADO.
Sean Nguyen

Respuestas:

98

En realidad, hay dos foreign_key_checksvariables: una variable global y una variable local (por sesión). Tras la conexión, la variable de sesión se inicializa con el valor de la variable global.
El comando SET foreign_key_checksmodifica la variable de sesión.
Para modificar la variable global, use SET GLOBAL foreign_key_checkso SET @@global.foreign_key_checks.

Consulte las siguientes secciones del manual:
http://dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
http://dev.mysql.com/doc/refman/5.7/en/server -system-variables.html

Ron Inbar
fuente
1
¿Es costoso configurar el Foreign_key_checks en cada solicitud? Tengo un script para actualizar la base de datos y no quisiera que nadie más pueda anular las comprobaciones de clave externa de forma predeterminada durante esa actualización. Entonces, ¿haría millones de consultas y me preguntaba si un SET sería significativo o no?
Aki el
@Aki Si está actualizando la base de datos, diría que es mejor bloquear el acceso para todos los demás. Al menos para escribir. De lo contrario, puede esperar todo tipo de problemas de acceso concurrente.
tishma
1
Gran respuesta y distinción. Es importante darse cuenta de las consecuencias de cómo funciona. Significa que no puede configurar el GLOBAL foreign_key_checksy en esa misma sesión esperar que ignore las restricciones de claves foráneas. Necesita establecer la variable no global.
Tyler Collier
12

Como explicó Ron, hay dos variables, local y global. La variable local siempre se usa, y es la misma que global al conectarse.

SET FOREIGN_KEY_CHECKS=0;
SET GLOBAL FOREIGN_KEY_CHECKS=0;

SHOW Variables WHERE Variable_name='foreign_key_checks'; # always shows local variable

Al configurar la variable GLOBAL, la local no se cambia para ninguna conexión existente. También debe volver a conectar o establecer la variable local.

Quizás no sea intuitivo, MYSQL no aplica claves foráneas cuando FOREIGN_KEY_CHECKS se vuelven a habilitar. Esto hace posible crear una base de datos inconsistente aunque las claves externas y las comprobaciones estén activadas.

Si desea que sus claves externas sean completamente consistentes, debe agregar las claves mientras la verificación está activada.

Bouke Versteegh
fuente
1
¿Puede dar más detalles ...? "Si desea que sus claves foráneas sean completamente consistentes, debe agregar las claves mientras la verificación está activada".
user2782001
44
Supongamos que tiene una tabla con referencias de id, pero faltan algunos registros referenciados. Si agrega la clave externa (FK) mientras FOREIGN_KEY_CHECKS están activados, Mysql generará un error y se negará a agregar el FK, debido a la referencia rota. Cuando agrega la clave foránea mientras FOREIGN_KEY_CHECKS están desactivados, mysql continúa sin errores. Incluso cuando habilite las comprobaciones después, no habrá ningún error. Ahora tiene una tabla con datos inconsistentes, aunque haya un FK. Como tal, la existencia de un FK no garantiza la coherencia de la base de datos, a menos que se haya agregado mientras las comprobaciones de FK estaban activadas.
Bouke Versteegh el
10
# will get you the current local (session based) state.
SHOW Variables WHERE Variable_name='foreign_key_checks';

Si no configuró GLOBAL, solo su sesión se vio afectada.

Mike Karras
fuente
1

Tuve el mismo error cuando intenté migrar la base de datos de Drupal a un nuevo servidor apache local (estoy usando XAMPP en una máquina con Windows). En realidad, no sé el significado de este error, pero después de intentar los pasos a continuación, importé la base de datos sin errores. Espero que esto pueda ayudar:

Cambiar php.ini en C: \ xampp \ php \ php.ini

max_execution_time = 600
max_input_time = 600
memory_limit = 1024M
post_max_size = 1024M

Cambiar my.ini en C: \ xampp \ mysql \ bin \ my.ini

max_allowed_packet = 1024M
Saeed cr7
fuente
-2

En caso de utilizar el navegador de consultas Mysql, SET FOREIGN_KEY_CHECKS=0;no tiene ningún impacto en la versión 1.1.20. Sin embargo, funciona bien en MySql query browser 1.2.17

usuario2682955
fuente