2017-07-05 8 views
0

I 2 Tabellen definiert haben und eine foriegn Schlüsselbedingung zwischen ihnen wie folgt dar:Wie MySQL Fremdschlüssel debuggen, ON DELETE CASCADE auf Produktionsumgebung keine Zeilen aus Child-Tabelle zu löschen

| users | CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `account_master_id` int(11) NOT NULL, 
    `user_type_id` int(11) NOT NULL, 
    `user_group_id` int(11) NOT NULL, 
    `user_type_code` char(1) NOT NULL, 
    `membership_number` varchar(40) NOT NULL, 
    `password` varchar(60) NOT NULL, 
    `email` varchar(200) NOT NULL, 
    `isd` varchar(10) NOT NULL, 
    `mobile` varchar(20) NOT NULL, 
    `passenger_id` int(11) NOT NULL, 
    `added_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `updated_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `added_by` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`), 
    KEY `account_master_id` (`account_master_id`), 
    CONSTRAINT `acMaster_to_user` FOREIGN KEY (`account_master_id`) REFERENCES `account_master` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=189 DEFAULT CHARSET=utf8 | 


user_oauth | CREATE TABLE `user_oauth` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) NOT NULL, 
    `service` varchar(30) NOT NULL, 
    `auth_id` varchar(100) NOT NULL, 
    `email` varchar(100) NOT NULL, 
    `auto_share` tinyint(4) NOT NULL, 
    `photo` varchar(255) NOT NULL, 
    `auth_token_short` varchar(255) DEFAULT NULL, 
    `auth_details` text NOT NULL, 
    `device_type` varchar(60) NOT NULL, 
    `login_date` datetime NOT NULL, 
    `login_ip` varchar(20) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `user` (`user_id`), 
    CONSTRAINT `user_to_oauth` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=latin1 | 

auf eine Reihe von Löschen Benutzertabelle löscht entsprechende Einträge aus der Tabelle user_oauth in der lokalen und Staging-Umgebung. Aber dasselbe funktioniert nicht in der PRODUCTION-Umgebung. Ich möchte wissen, wie ich das debuggen kann.

Update:

  • beide Tabellen sind innodb
  • läuft mysql im Strict-Modus
+1

Wählen Sie @@ foreign_key_checks; '(wenn dieses Verhalten auftritt). Wenn es 0 heißt, repariere deine Daten, setze sie auf 1 und feuere dann jemanden (es sei denn, du warst es selbst, dann feg es unter den Teppich). Wenn es 1 bedeutet, müssen Sie nach anderen Ideen suchen. – Solarflare

+0

danke Kumpel, das war der Unterschied. Kannst du mir sagen, wie du das herausgefunden hast? Ich versuche nicht, nur die Antwort zu bekommen, sondern das Problem kennenzulernen und solche Dinge zu debuggen. – Gunnrryy

+0

Ich werde etwas Hintergrund über die Option als Antwort hinzufügen. WIE man es herausfinden kann, ist schwer zu sagen. Wenn Sie wissen, dass diese Option existiert, ist das keine Zauberei. Wenn du es nicht tust, ist es irgendwie. Sie können vielleicht etwas davon ableiten, dass es existiert und in der Lage ist, es im Handbuch zu finden. Für einige Informationen würde es leider auch Magie erfordern, die richtige Antwort im MySQL-Handbuch zu finden. (Nicht für alle, viele Aspekte einschließlich technischer Details sind schön gemacht). Ich denke, eine realistische Lösung ist es, dafür zu googeln oder jemanden zu fragen, der es weiß (z. B. auf stackoverflow). – Solarflare

Antwort

1

Die Gründe, warum Fremdschlüssel nicht sind funktionieren könnte:

  • sie nicht unterstützt werden (zB auf MyISAM-Tabellen)
  • sie sind disa
  • geblutet

MySQL ermöglicht es Ihnen, indem Sie die Systemvariable foreign_key_checks-0 Fremdschlüssel contraints zu deaktivieren. Auf diese Weise können Sie alle Fremdschlüsseleinschränkungen verletzen (z. B. ein Elternelement löschen oder übergeordnete untergeordnete Elemente hinzufügen). Aber es wird auch verwandte Funktionen wie Kaskaden deaktivieren, die dazu da sind, bestimmte Constraint-Verletzungen automatisch zu verhindern (zum Beispiel durch Löschen der Kinder) - was natürlich nicht mehr passieren wird, wenn die Option deaktiviert ist.

Die Idee ist, Ihnen bei einigen Verwaltungsaufgaben zu helfen, z. Importieren von Daten, wenn die referenzierten Daten noch nicht vorhanden sind, aber normalerweise nicht während des normalen Betriebs verwendet werden sollten. Wenn die Einstellung erneut angezeigt wird, sollten Sie Ihre Apps überprüfen, wenn Sie diese Option versehentlich festlegen, da sie nach jedem Serverstart standardmäßig aktiviert ist und explizit deaktiviert werden muss.

Sie können die aktuelle Einstellung z. mit

select @@foreign_key_checks; 

Sie können

SET foreign_key_checks = 1; 

verwenden, es wieder zu aktivieren, aber bewusst sein, dass es nicht Ihre aktuellen Daten überprüfen wird:

foreign_key_checks auf 1 Einstellung löst keine Scan der vorhandenen Tabellendaten. Daher werden Zeilen, die der Tabelle hinzugefügt werden, während foreign_key_checks = 0, nicht auf Konsistenz überprüft.

Also müssen Sie es selbst überprüfen und beheben. Sie können dies entweder vor oder nach der erneuten Aktivierung der Einstellung tun, obwohl dies möglicherweise zuvor einfacher war. Um eine erneute Überprüfung auszulösen, können und sollten Sie den Fremdschlüssel löschen und neu erstellen, um sicherzustellen, dass jetzt alles konsistent ist.

+0

danke für die Erklärung. Ich denke, das ist passiert, weil ich aus phpMyadmin exportiert habe, indem ich "Disable foreign key checks" gewählt habe und manuell den Code über das Terminal kopiert habe und vergessen habe, "Foreign key checks" am Ende zu aktivieren. Das war sehr hilfreich. – Gunnrryy

Verwandte Themen