WBCE CMS Forum

WBCE CMS – Way Better Content Editing.

You are not logged in.

#1 04.03.2024 13:06:11

chriz
Member

Backup-Plus: Restore-Problem bei Modul NewsWithImages

Wie im Thread Modul "Backup Plus" bitte testen - Please try it: Modul "Backup Plus" (ab #122) in den letzten Tagen erwähnt, habe ich immer wieder Probleme mit dem Restore meiner WBCE-Instanz.

(Ich habe das Teil-Thema jetzt hier in einen neuen Thread ausgelagert.)

Aufgefallen war es mir, weil die wiederhergestellte Instanz unvollständig war, also noch alte Daten enthielt.

Backup-Plus 2.8.1 hatte keine Fehler gemeldet, was die Ursachensuche etwas schwierig gestaltete. In dem Rahmen habe ich Backup-Plus korrigiert, siehe oben erwähnten Thread.

Die Fehlermeldung lautet "Cannot delete or update a parent row: a foreign key constraint fails".
Sie tritt bei sehr vielen, aber nicht bei allen(!) Restore-Läufen auf, immer mit derselben SQL-Sicherungsdatei.

Durch Trial&Errror glaube ich, die Ursache nun zumindest eingekreist zu haben.

Tabelle mod_news_img_posts_img enthält zwei CONSTRAINTS

# Create table hhk_mod_news_img_posts_img
CREATE TABLE `hhk_mod_news_img_posts_img` (
  `post_id` int NOT NULL,
  `pic_id` int NOT NULL,
  `position` int NOT NULL,
  UNIQUE KEY `post_id_pic_id` (`post_id`,`pic_id`),
  KEY `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_img` (`pic_id`),
  CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_img` FOREIGN KEY (`pic_id`) REFERENCES `hhk_mod_news_img_img` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_posts` FOREIGN KEY (`post_id`) REFERENCES `hhk_mod_news_img_posts` (`post_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

die sich beim Löschen/Wiederanlegen der betroffenen Tabellen querstellen.

Ich habe es durch verschiedene Reihenfolgen der Tabellen in der SQL-Datei zu lösen versucht. Ohne Erfolg.
Als Workaround habe ich dann die drei Tabellen zusammen in einem Rahmen SET FOREIGN_KEY_CHECKS=0;    [....]  SET FOREIGN_KEY_CHECKS=1; gepackt. Das klappte dann...

Meine SQL-Kenntnisse sind leider nicht gut genug, um da eine "richtige" Ursache/Lösung zu formulieren.

Hier der gekürzte sdiff der ursprünglichen (links) und meiner veränderten SQL-Datei:

#                                                               # 
# Database Backup                                               # Database Backup
# ...                                                           # ...
# 04.03.2024, 10:18                                             # 04.03.2024, 10:18
# Backup modul version: 2.8.2                                   # Backup modul version: 2.8.2
# Database: 8.0.33                                              # Database: 8.0.33
# OS: Linux                                                     # OS: Linux
#                                                               # 

# Drop table hhk_addons if exists                               # Drop table hhk_addons if exists
DROP TABLE IF EXISTS `hhk_addons`;                              DROP TABLE IF EXISTS `hhk_addons`;

# Create table hhk_addons                                       # Create table hhk_addons

[...]


                                                              > SET FOREIGN_KEY_CHECKS=0;


                                                              > # Drop table hhk_mod_news_img_posts_img if exists
                                                              > DROP TABLE IF EXISTS `hhk_mod_news_img_posts_img`;
                                                              >
                                                              > # Create table hhk_mod_news_img_posts_img
                                                              > CREATE TABLE `hhk_mod_news_img_posts_img` (
                                                              >   `post_id` int NOT NULL,
                                                              >   `pic_id` int NOT NULL,
                                                              >   `position` int NOT NULL,
                                                              >   UNIQUE KEY `post_id_pic_id` (`post_id`,`pic_id`),
                                                              >   KEY `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_img` (`
                                                              >   CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_
                                                              >   CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_
                                                              > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
                                                              >
                                                              > # Dump data for hhk_mod_news_img_posts_img
                                                              >

# Drop table hhk_mod_news_img_img if exists                     # Drop table hhk_mod_news_img_img if exists
DROP TABLE IF EXISTS `hhk_mod_news_img_img`;                    DROP TABLE IF EXISTS `hhk_mod_news_img_img`;

# Create table hhk_mod_news_img_img                             # Create table hhk_mod_news_img_img
CREATE TABLE `hhk_mod_news_img_img` (                           CREATE TABLE `hhk_mod_news_img_img` (
  `id` int NOT NULL AUTO_INCREMENT,                               `id` int NOT NULL AUTO_INCREMENT,
  `picname` varchar(255) NOT NULL DEFAULT '',                     `picname` varchar(255) NOT NULL DEFAULT '',
  `picdesc` varchar(255) NOT NULL DEFAULT '',                     `picdesc` varchar(255) NOT NULL DEFAULT '',
  `post_id` int NOT NULL DEFAULT '0',                             `post_id` int NOT NULL DEFAULT '0',
  `position` int NOT NULL DEFAULT '0',                            `position` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)                                              PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb3;       ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb3;

# Dump data for hhk_mod_news_img_img                            # Dump data for hhk_mod_news_img_img

[...]

# Drop table hhk_mod_news_img_posts if exists                   # Drop table hhk_mod_news_img_posts if exists
DROP TABLE IF EXISTS `hhk_mod_news_img_posts`;                  DROP TABLE IF EXISTS `hhk_mod_news_img_posts`;

# Create table hhk_mod_news_img_posts                           # Create table hhk_mod_news_img_posts
CREATE TABLE `hhk_mod_news_img_posts` (                         CREATE TABLE `hhk_mod_news_img_posts` (
  `post_id` int NOT NULL AUTO_INCREMENT,                          `post_id` int NOT NULL AUTO_INCREMENT,
  `section_id` int NOT NULL DEFAULT '0',                          `section_id` int NOT NULL DEFAULT '0',
  `group_id` int NOT NULL DEFAULT '0',                            `group_id` int NOT NULL DEFAULT '0',
  `active` int NOT NULL DEFAULT '0',                              `active` int NOT NULL DEFAULT '0',
  `position` int NOT NULL DEFAULT '0',                            `position` int NOT NULL DEFAULT '0',
  `title` varchar(255) NOT NULL DEFAULT '',                       `title` varchar(255) NOT NULL DEFAULT '',
  `link` text NOT NULL,                                           `link` text NOT NULL,
  `image` varchar(256) NOT NULL DEFAULT '',                       `image` varchar(256) NOT NULL DEFAULT '',
  `content_short` text NOT NULL,                                  `content_short` text NOT NULL,
  `content_long` text NOT NULL,                                   `content_long` text NOT NULL,
  `content_block2` text NOT NULL,                                 `content_block2` text NOT NULL,
  `published_when` int NOT NULL DEFAULT '0',                      `published_when` int NOT NULL DEFAULT '0',
  `published_until` int NOT NULL DEFAULT '0',                     `published_until` int NOT NULL DEFAULT '0',
  `posted_when` int NOT NULL DEFAULT '0',                         `posted_when` int NOT NULL DEFAULT '0',
  `posted_by` int NOT NULL DEFAULT '0',                           `posted_by` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`post_id`)                                         PRIMARY KEY (`post_id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb3;      ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb3;

# Dump data for hhk_mod_news_img_posts                          # Dump data for hhk_mod_news_img_posts

[...]

                                                              | SET FOREIGN_KEY_CHECKS=1;


# Drop table hhk_mod_news_img_posts_img if exists             <
DROP TABLE IF EXISTS `hhk_mod_news_img_posts_img`;            <
                                                              <
# Create table hhk_mod_news_img_posts_img                     <
CREATE TABLE `hhk_mod_news_img_posts_img` (                   <
  `post_id` int NOT NULL,                                     <
  `pic_id` int NOT NULL,                                      <
  `position` int NOT NULL,                                    <
  UNIQUE KEY `post_id_pic_id` (`post_id`,`pic_id`),           <
  KEY `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_img` (` <
  CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_ <
  CONSTRAINT `FK_hhk_mod_news_img_posts_img_hhk_mod_news_img_ <
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;                      <
                                                              <
# Dump data for hhk_mod_news_img_posts_img                    <
                                                              <


# Drop table hhk_mod_news_img_settings if exists                # Drop table hhk_mod_news_img_settings if exists
DROP TABLE IF EXISTS `hhk_mod_news_img_settings`;               DROP TABLE IF EXISTS `hhk_mod_news_img_settings`;

[...]

Last edited by chriz (04.03.2024 16:53:23)

Offline

#2 04.03.2024 21:12:35

chriz
Member

Re: Backup-Plus: Restore-Problem bei Modul NewsWithImages

Inzwischen habe ich den Eindruck, dass es bei einem DB-Restore durchaus legitim ist, für diese Session SET FOREIGN_KEY_CHECKS=0; zu setzen.

Das wäre dann eine einzige zusätzliche Zeile am Anfang von backup.php.

Ich hatte aber den Ehrgeiz, das Abschalten der Checks auf ein Minimum zu begrenzen. Also habe ich folgendes in backup.php der ursprünglichen Tabellen-Schleife vorangestellt:

[== PHP ==]
if ($_GET['type'] !== 'page') {
        $output .= '# This prolog is a workaround to avoid constraint errors without disabling the check completely.';
        $query = "SELECT REFERENCED_TABLE_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE TABLE_NAME IN (SELECT DISTINCT TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY')";

        if ($_GET['type'] == 'wbce') {
                // ONLY for relevant wbce tables
                $prefix = str_replace('_', '\_', TABLE_PREFIX);
                $query = "SELECT REFERENCED_TABLE_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE TABLE_NAME IN (SELECT DISTINCT TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY' AND TABLE_NAME LIKE '".$prefix."%')";
        }

        $result = $database->query($query);
        if ($database->is_error()) {
                die(json_encode(array('code' => 4036, 'error' => $database->get_error())));
        }

        $output .= PHP_EOL."SET FOREIGN_KEY_CHECKS=0;";
        while ($row = $result->fetchRow()) {
                $output .= PHP_EOL."DROP TABLE IF EXISTS `$row[0]`;";
        }
        $output .= PHP_EOL."SET FOREIGN_KEY_CHECKS=1;".PHP_EOL;
}

Dies erzeugt dann in der SQL-Datei (beispielhaft):

# This prolog is a workaround to avoid constraint errors without disabling the check completely.
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `hhk_mod_news_img_img`;
DROP TABLE IF EXISTS `hhk_mod_news_img_posts`;
SET FOREIGN_KEY_CHECKS=1;

Und so läuft der Restore ohne Fehlermeldung durch.

Falls die SQL-Profis hier noch Anmerkungen oder Verbesserungsvorschläge haben, immer her damit!

Offline

#3 05.03.2024 13:23:09

webbird
Administrator

Re: Backup-Plus: Restore-Problem bei Modul NewsWithImages

Die Keychecks beim Restore temporär abzuschalten ist vollkommen legitim und im Prinzip auch die einzige Lösung. Andernfalls müßte man darauf achten, dass die Wiederherstellung der Tabellen in der korrekten Reihenfolge stattfindet, und das ist ziemlich aufwendig. Und in diesem Fall auch unnötig.


Ich habe eine Amazon-Wishlist. wink Oder spende an das Projekt.
Ich kann, wenn ich will, aber wer will, dass ich muss, kann mich mal

Offline

#4 05.03.2024 14:18:50

chriz
Member

Re: Backup-Plus: Restore-Problem bei Modul NewsWithImages

Danke für die Info/Bestätigung!

Ich habe das in backup.php nun reduziert auf:

[== PHP ==]
$output .= '# Avoid possible foreign key constraint errors during restore';
$output .= PHP_EOL."SET FOREIGN_KEY_CHECKS=0;".PHP_EOL;

Offline

#5 05.03.2024 15:51:03

webbird
Administrator

Re: Backup-Plus: Restore-Problem bei Modul NewsWithImages

Du solltest es dann am Ende aber auch wieder einschalten.


Ich habe eine Amazon-Wishlist. wink Oder spende an das Projekt.
Ich kann, wenn ich will, aber wer will, dass ich muss, kann mich mal

Offline

#6 05.03.2024 15:55:02

chriz
Member

Re: Backup-Plus: Restore-Problem bei Modul NewsWithImages

Gute Idee! big_smile
So deaktiviert gilt ja nur für die aktuelle Session. Ich hatte das auf die "Restore-Session" bezogen, ups.
Aber ja, die Session dauert noch länger...

Nachtrag: Die Reaktivierung ist nun in die generierte SQL-Datei (durch backup.php) eingebaut.

Last edited by chriz (05.03.2024 16:26:46)

Offline

Liked by:

florian

Board footer

up