8
votes

MySQL Server redémarre après l'exécution du déclencheur

J'ai un déclencheur dans MySQL qui provoque le redémarrage du serveur MySQL à chaque fois qu'il est déclenché. Cela a commencé à se produire après la mise à jour de la version 8.0.22 il y a un jour. Mon déclencheur est le suivant:

CREATE TABLE `client_invoices` (
 `id` bigint unsigned NOT NULL AUTO_INCREMENT,
 `client_invoice_id` bigint unsigned NOT NULL COMMENT 'Unique autoincrementing bigint for this client',
 `client_operating_unit_id` int unsigned NOT NULL,
 `customer_id` int unsigned NOT NULL,
 `invoice_status_id` int unsigned NOT NULL DEFAULT '1',
 `invoice_date` date NOT NULL,
 `sub_total` decimal(14,2) DEFAULT '0.00',
 `vat` decimal(14,2) DEFAULT '0.00',
 `total` decimal(14,2) DEFAULT '0.00',
 `invoiced` tinyint(1) NOT NULL COMMENT 'Invoice sent to customer',
 `paid` tinyint(1) NOT NULL COMMENT 'Invoice been paid',
 `exported` tinyint(1) NOT NULL DEFAULT '0',
 `automatic_invoice` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Invoice has been generated automatically',
 `comments` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
 `created_by` int unsigned NOT NULL DEFAULT '0',
 `updated_by` int unsigned NOT NULL DEFAULT '0',
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `invoice_id` (`client_operating_unit_id`,`client_invoice_id`),
 KEY `client_invoices_client_operating_unit_id_index` (`client_operating_unit_id`),
 KEY `client_invoices_customer_id_index` (`customer_id`),
 KEY `client_invoices_invoice_status_id_index` (`invoice_status_id`),
 KEY `client_invoices_invoice_date_index` (`invoice_date`),
 CONSTRAINT `client_invoices_client_operating_unit_id_foreign` FOREIGN KEY (`client_operating_unit_id`) REFERENCES `client_operating_units` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
 CONSTRAINT `client_invoices_customer_id_foreign` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
 CONSTRAINT `client_invoices_invoice_status_id_foreign` FOREIGN KEY (`invoice_status_id`) REFERENCES `client_invoice_status` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB AUTO_INCREMENT=60975 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

Y a-t-il quelque chose qui me manque en raison de la mise à jour récente, ou des moyens meilleurs et efficaces d'atteindre le même objectif si je ne parviens pas à trouver la cause des pannes du serveur?

J'ai également vérifié les journaux et voici ce que j'ai trouvé:

06:03:02 UTC - mysqld got signal 11 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x7f08e4921bd0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7f09c8254c70 thread_stack 0x46000
/usr/sbin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x3d) [0x2194f3d]
/usr/sbin/mysqld(handle_fatal_signal+0x313) [0xff55f3]
/lib64/libpthread.so.0(+0xf630) [0x7f09d5633630]
/usr/sbin/mysqld(Item_splocal::this_item()+0x14) [0x111fce4]
/usr/sbin/mysqld(Item_sp_variable::val_int()+0x13) [0x111fb63]
/usr/sbin/mysqld(Item_func_plus::int_op()+0x1d) [0x11aafdd]
/usr/sbin/mysqld(Item_func_numhybrid::val_int()+0x191) [0x11ad541]
/usr/sbin/mysqld(Item::save_in_field_inner(Field*, bool)+0x125) [0x11259c5]
/usr/sbin/mysqld(Item::save_in_field(Field*, bool)+0x53) [0x113ef03]
/usr/sbin/mysqld(Item_trigger_field::set_value(THD*, sp_rcontext*, Item**)+0x76) [0x113f136]
/usr/sbin/mysqld(sp_instr_set_trigger_field::exec_core(THD*, unsigned int*)+0x90) [0xe38a80]
/usr/sbin/mysqld(sp_lex_instr::reset_lex_and_exec_core(THD*, unsigned int*, bool)+0x60c) [0xe39b1c]
/usr/sbin/mysqld(sp_lex_instr::validate_lex_and_execute_core(THD*, unsigned int*, bool)+0x9a) [0xe3a55a]
/usr/sbin/mysqld(sp_head::execute(THD*, bool)+0x5d3) [0xe311c3]
/usr/sbin/mysqld(sp_head::execute_trigger(THD*, MYSQL_LEX_CSTRING const&, MYSQL_LEX_CSTRING const&, GRANT_INFO*)+0x29d) [0xe31acd]
/usr/sbin/mysqld(Trigger::execute(THD*)+0x10c) [0xfc150c]
/usr/sbin/mysqld(Trigger_chain::execute_triggers(THD*)+0x18) [0xfc28b8]
/usr/sbin/mysqld(Table_trigger_dispatcher::process_triggers(THD*, enum_trigger_event_type, enum_trigger_action_time_type, bool)+0x46) [0xfbc4a6]
/usr/sbin/mysqld(fill_record_n_invoke_before_triggers(THD*, COPY_INFO*, mem_root_deque<Item*> const&, mem_root_deque<Item*> const&, TABLE*, enum_trigger_event_type, int, bool, bool*)+0x3f9) [0xe45ac9]
/usr/sbin/mysqld(Sql_cmd_insert_values::execute_inner(THD*)+0x454) [0x1352464]
/usr/sbin/mysqld(Sql_cmd_dml::execute(THD*)+0x525) [0xf15695]
/usr/sbin/mysqld(mysql_execute_command(THD*, bool)+0x9f0) [0xeb98d0]
/usr/sbin/mysqld(Prepared_statement::execute(String*, bool)+0x8f0) [0xee8160]
/usr/sbin/mysqld(Prepared_statement::execute_loop(String*, bool)+0x117) [0xeec5f7]
/usr/sbin/mysqld(mysqld_stmt_execute(THD*, Prepared_statement*, bool, unsigned long, PS_PARAM*)+0x181) [0xeecba1]
/usr/sbin/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x1712) [0xebfbf2]
/usr/sbin/mysqld(do_command(THD*)+0x19c) [0xec101c]
/usr/sbin/mysqld() [0xfe69e0]
/usr/sbin/mysqld() [0x272fc3e]
/lib64/libpthread.so.0(+0x7ea5) [0x7f09d562bea5]
/lib64/libc.so.6(clone+0x6d) [0x7f09d3a0e8dd]



Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7f08e5343368): insert into `client_invoices` (`customer_id`, `invoice_date`, `sub_total`, `vat`, `total`, `client_operating_unit_id`, `client_invoice_id`, `invoiced`, `paid`, `created_by`, `updated_by`, `updated_at`, `created_at`) values (459, '2020-10-18 08:03:01', '24202.53', '0', '24202.53', 1, 0, 0, 0, 47, 47, '2020-10-20 08:03:02', '2020-10-20 08:03:02')
Connection ID (thread ID): 743
Status: NOT_KILLED



The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
2020-10-20T06:03:04.667817Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2020-10-20T06:03:04.668382Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.22) starting as process 59229
2020-10-20T06:03:04.685040Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-10-20T06:03:07.357601Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-10-20T06:03:08.537376Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2020-10-20T06:03:08.656148Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2020-10-20T06:03:08.656724Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2020-10-20T06:03:08.733111Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.22' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server - GPL.

Quand SHOW TABLE client_invoices; , voici le résultat que j'obtiens:

CREATE TRIGGER max_client_invoice_before_insert
BEFORE INSERT
ON client_invoices FOR EACH ROW

BEGIN

DECLARE vMax int(11);

SELECT IFNULL(max(client_invoice_id),0) from client_invoices where client_operating_unit_id = NEW.client_operating_unit_id INTO vMax;

SET NEW.client_invoice_id = vMax+1;

END


29 commentaires

J'ai le même problème avec cette version de mysql (8.0.22) qui a été mise à jour hier mais dans mon cas c'est au moment de faire une mise à jour. Si vous trouvez une solution, faites le moi savoir


@ josemm1790 C'est la même version qui me donne mal à la tête. Malheureusement, je n'ai pas encore reçu de pointeurs, même du forum MySQL


C'est le même problème mais avec une autre instruction qui me fait penser qu'elle n'est pas directement liée à la requête mais peut-être à un nouveau paramètre de configuration ...


Atm j'ai recréé tous les déclencheurs (avait comme 10) et atm il semble fonctionner pendant 5 minutes. Surveillera la situation.


n'a pas marché :/


Je pense que nous devrions signaler cela comme un bogue sur bugs.mysql.com en tant que l'un des utilisateurs recommandés sur ce message: forums.mysql.com/read.php?99,690696,690696#msg-690696


bugs.mysql.com/bug.php?id=101257&thanks=4 Je l'ai déjà fait


Leo Rams: Je pense que je suis tombé sur une cause possible. Si aucune valeur par défaut n'est spécifiée pour une colonne dans laquelle vous effectuez une mise à jour / une insertion dans le déclencheur, cela peut provoquer un échec, en particulier avec les types DATE et DATETIME. Cela provoque l'échec du déclencheur sans erreur et donc peut-être un processus qui provoque le blocage et le redémarrage du démon mysql.


@peterC_ Dans mon cas, c'est juste une insertion directe et j'utilise le déclencheur pour calculer la valeur de la colonne en obtenant la valeur maximale de la base de données et en y ajoutant 1. Cette colonne particulière n'a pas de valeur par défaut, cela poserait-il des problèmes? Après avoir vérifié les journaux, j'ai remarqué que l'insertion se produit parfois et parfois échoue, ce qui peut également suggérer qu'il existe plusieurs facteurs qui provoquent le redémarrage du serveur, mis à part le déclencheur.


@LeoRams Cela a fonctionné dans notre cas jusqu'à présent: nous renommons la table où le problème se produisait puis nous la recréons et jusqu'à présent, cela ne s'est pas reproduit.


@ josemm1790 Hier, j'ai laissé tomber toutes les tables et les ai réimportées à nouveau (ce qui devrait être similaire à votre suggestion car cela crée les tables et les déclencheurs à partir de zéro) mais le problème persiste. Votre solution fonctionne-t-elle toujours, aucun problème maintenant?


@LeoRams Oui, de notre côté tout va bien pour le moment, on a eu le même problème sur une autre table mais on a fait la même chose et ça marche bien.


a eu le même problème avec les déclencheurs après la mise à jour vers la 8.0.22, mais dans mon cas, le déclencheur échoue de manière aléatoire


@ josemm1790 J'ai également essayé de supprimer et de recréer la table principale et la table cible du déclencheur, sans succès.


@LeoRams Veuillez publier les résultats TEXT de SHOW CREATE TABLE client_invoices; pour permettre la vérification des types de données fournis lorsque votre INSERT échoue.


@WilsonHauck J'ai mis à jour ma réponse pour inclure les résultats textuels dans la requête


@LeoRams Pourriez-vous être pris dans le tourbillon de la dernière version de GA? D'après ce que je vois, la 8.0.22 est devenue GA le 19/10/2020. Il y a environ 6 jours. À l'avenir, évitez d'installer quelque chose de moins de 3 mois pour éviter d'être à la fine pointe de la technologie en matière de rapports de bogues. Questions, A) Lorsque le déclencheur a été créé, incluait-il DELIMITER $$ en tête et DELIMITER:? B) Pour votre insertion dans client_invoices , B1) facture_date est un champ de date et n'attend pas hh: mm: ss dans la chaîne. B2) sous_total, tva, les valeurs de données totales ne nécessitent pas de guillemets simples pour les types de données décimaux.


@LeoRams B3) colonnes d'horodatage - updated_at et created_at entraîneront l'échec de l'application en raison de données hors plage lorsque les valeurs sont> 2038-01-19 03:14:07. Voir le profil, le profil réseau pour des scripts utilitaires téléchargeables gratuitement pour vous aider à optimiser les performances.


@WilsonHauck Certainement un problème soulevé par la mise à jour 8.0.22. Nous allons examiner certains des problèmes que vous avez soulevés et voir si nous pouvons y apporter des correctifs dans l'espoir que nous pourrons résoudre ce problème ...


Ayant le même problème, bien que ma colonne datetime ait une valeur par défaut alors que les colonnes varchar / char n'ont pas de valeur par défaut pour le moment (non testé en définissant une valeur par défaut)


@MrJ Cela semble définitivement être un bogue avec les routines stockées dans la version 8.0.22 et malheureusement MySQL prend son temps pour répondre à notre rapport de bogue


@LeoRams, ils viennent de me répondre en demandant un cas de test et ont dit que cela ressemblait à un double du vôtre et que les piles d'appels sont similaires, ont soumis mon rapport de bogue il y a 6 heures ... supposons qu'on vous a déjà demandé un cas de test ... aucun doute prendra un certain temps pour qu'une solution soit disponible


@MrJ Ouais, tout ce que nous pouvons faire est d'attendre qu'ils nous indiquent quel est le problème et quelles seront nos options pour une solution soit de leur côté soit du nôtre ...


@peterC_ les rapports de bogue d'Oracle sont-ils privés? a essayé d'ouvrir votre rapport de bogue mais il montre seulement que You do not have access to bug #101257.


@raphaeldavidf Les rapports de bogue ont été marqués comme privés et leur raisonnement était qu'ils provoquaient un plantage du serveur. Je ne sais pas ce que ça veut dire ni quelle est la logique derrière ça


@LeoRams Des nouvelles sur le rapport de bogue?


Avoir le même problème avec 8.0.22. Le processus MySQL redémarre au hasard. Nous avons environ 11 déclencheurs et quelques-uns avaient DATETIME non par défaut. Après avoir défini la valeur par défaut, le problème persiste. N'importe quel indice comment puis-je déboguer pour accéder à la cause première et y remédier.


@raphaeldavidf rien n'a été dit ou fait sur le rapport de bogue, c'est comme s'ils ne se soucient même pas que cela se passe malheureusement ...


@AdityaMertia Je vous suggère de partager votre code de déclenchement et j'espère que quelqu'un vous orientera dans la bonne direction. Ce qui a fonctionné dans mon cas, c'était de supprimer tous les IFNULL que j'avais dans mes déclencheurs et cela a résolu le problème de redémarrage du serveur ...


5 Réponses :


1
votes

J'ai pu localiser le problème uniquement à un déclencheur de mise à jour (d'autres semblent fonctionner très bien).

La chose étrange est que ce déclencheur de mise à jour de test fonctionne très bien:

Oct 29 08:01:50 SERVER systemd[1]: mysql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Oct 29 08:01:50 SERVER systemd[1]: mysql.service: Failed with result 'exit-code'.
Oct 29 08:01:50 SERVER systemd[1]: mysql.service: Service RestartSec=100ms expired, scheduling restart.
Oct 29 08:01:50 SERVER systemd[1]: mysql.service: Scheduled restart job, restart counter is at 12.
Oct 29 08:01:50 SERVER systemd[1]: Stopped MySQL Community Server.
Oct 29 08:01:50 SERVER systemd[1]: Starting MySQL Community Server...
Oct 29 08:01:55 SERVER systemd[1]: Started MySQL Community Server.

tandis que celui-ci plante le serveur mysql au hasard:

CREATE TABLE `nobreak_status_changelog` (
  `date` datetime NOT NULL,
  `user` varchar(100) NOT NULL,
  `type` varchar(45) NOT NULL,
  `result` varchar(1000) NOT NULL,
  `attribute` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

MISE À JOUR:

Retour de SHOW CREATE TABLE cybersecurity.nobreak_status_changelog;

CREATE DEFINER=`root`@`%` TRIGGER `nobreak_status_AFTER_UPDATE` AFTER UPDATE ON `nobreak_status` FOR EACH ROW BEGIN
    DECLARE old_values VARCHAR(2000);
    
    SET old_values := '';
    
    
    IF old_values = '' THEN
        INSERT INTO cybersecurity.nobreak_status_changelog (`date`, `user`, `type`, result, attribute) VALUES (NOW(), USER(), 'UPDATE', '', '');
    END IF;
END

MISE À JOUR 2: Je viens de vérifier les journaux du serveur et ceux-ci ont commencé à apparaître au moins une fois par jour depuis la mise à jour:

CREATE DEFINER=`root`@`%` TRIGGER `nobreak_status_AFTER_UPDATE` AFTER UPDATE ON `nobreak_status` FOR EACH ROW BEGIN
    DECLARE old_values VARCHAR(2000);
    
    SET old_values := '';
    
    
    IF TRUE THEN
        INSERT INTO cybersecurity.nobreak_status_changelog (`date`, `user`, `type`, result, attribute) VALUES (NOW(), USER(), 'UPDATE', '', '');
    END IF;
END


10 commentaires

Veuillez publier les résultats TEXT de SHOW CREATE TABLE cybersecurity.nobreak_status_changelog; pour analyse.


@WilsonHauck a mis à jour le message avec le retour de SHOW CREATE TABLE


Se pourrait-il que vous ayez besoin d'un VERROU DE TABLE à ajouter à cette table sans clé PRIMAIRE?


@WilsonHauck Je ne pense pas, car le déclencheur est le seul qui écrit dans cette table, donc il n'y aurait aucune condition de course pour lire / écrire ces données


@MrJ LeoRams Obtenez-vous également ces journaux d'erreurs (mise à jour 2)?


@raphaeldavidf pas vu que là où j'ai regardé, quelle commande vous exécutez pour produire et allez jeter un oeil?


@MrJ grep -r "mysql.service" /var/log/


@raphaeldavidf ne semble pas trouver quoi que ce soit correspondant


@MrJ essayez avec grep -ri "mysql" /var/log/


@raphaeldavidf mysqld.service est ce que j'aurais dû utiliser ... votre première ligne est essentiellement la même que la mienne



0
votes

J'ai mis à jour mon déclencheur comme suit et cela a arrêté le plantage du serveur MySQL (cela fait près de 36 heures maintenant sans redémarrage):

SELECT IF(COUNT(client_invoice_id) > 0, MAX(client_invoice_id) + 1, 1)

La seule différence était de supprimer

SELECT IFNULL(max(client_invoice_id),0)

et le remplacer par

CREATE TRIGGER max_client_invoice_before_insert
                        BEFORE INSERT
                           ON client_invoices FOR EACH ROW
                        BEGIN
                           DECLARE vMax int(11);
                           SELECT IF(COUNT(client_invoice_id) > 0, MAX(client_invoice_id) + 1, 1) from client_invoices where client_operating_unit_id = NEW.client_operating_unit_id INTO vMax;
                           SET NEW.client_invoice_id = vMax;
                        END


2 commentaires

C'est bien de voir que vous avez une solution de contournement: o) Ils viennent de vérifier que ce que je leur ai fourni a causé un bogue. Malheureusement pour moi, je ne pense pas pouvoir vraiment modifier mon instruction de déclenchement: o (


@MrJ Veuillez partager votre déclencheur et j'espère que quelqu'un pourra vous fournir des conseils sur la façon de le contourner. Vous pouvez également partager un lien vers votre rapport de bogue ...



0
votes

Un de mes déclencheurs qui provoque souvent un crash

CREATE TABLE `entity_log` (
  `entity_id` int NOT NULL,
  `global_ref` varchar(30) COLLATE utf8mb4_general_ci NOT NULL,
  `entity_type` varchar(2) COLLATE utf8mb4_general_ci NOT NULL,
  `subentity_type` char(2) COLLATE utf8mb4_general_ci NOT NULL,
  `server_updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

La table

CREATE TRIGGER `items_insert`
    AFTER INSERT
        ON `items` FOR EACH ROW
    BEGIN
        DECLARE rowcount INT;
        SET rowcount = (SELECT COUNT(*) from entity_log WHERE global_ref=NEW.global_ref LIMIT 1);
        IF (rowcount=0 AND LEFT(NEW.global_ref, 2)="ZZ") THEN
            INSERT INTO entity_log (global_ref, entity_type, server_updated_at) values (NEW.global_ref, "IL", UTC_TIMESTAMP());
        END IF;
    END

Je ne sais pas comment résoudre celui-ci car il est très simple

Le rapport de bogue MySQL est référencé sur https://bugs.mysql.com/bug.php?id=101342 mais MySQL l'a rendu privé, comme les autres rapports mentionnés dans les commentaires, pour des raisons de sécurité


0 commentaires

0
votes

Même problème ici. Dans mon cas, il semble que cela se passe sur des déclencheurs pour lesquels j'ai cette sélection:

SET vTipoEvento = '';
SELECT TipoEvento
  INTO vTipoEvento
  FROM evexcl
 WHERE eclid = OLD.IdEsito;

ce qui est assez simple. Je ne sais même pas comment le réécrire ... Problèmes commencés avec mysql 8.0.22 (ubuntu 20.04.2)

J'ai beaucoup de déclencheurs et dans mon cas, il continue de redémarrer


0 commentaires

0
votes

Rejoint ce club de bogues après la mise à jour vers la 8.0.22, qui a de nombreux correctifs de sécurité et nous avons dû mettre à niveau. Dans mon cas, le déclencheur est après la suppression:

CREATE TRIGGER `TRG_n2d_delete` AFTER DELETE ON `n2d` FOR EACH ROW BEGIN
    IF ((SELECT n_state FROM nets WHERE net_id=OLD.net_id)=0) THEN
        UPDATE dicts SET hits=hits-1 WHERE d_id=OLD.d_id;
        UPDATE nets SET hits=hits-1 WHERE net_id=OLD.net_id;
    END IF;
END

En regardant le dénominateur commun, c'est comme si le problème était d'accéder aux variables locales.

Edit: réécrit le déclencheur en supprimant la variable interne et ne vois aucun crash. Mon code actuel:

CREATE TRIGGER `TRG_n2d_delete` AFTER DELETE ON `n2d` FOR EACH ROW BEGIN
    DECLARE vn_state tinyint(1);

    SELECT n_state FROM nets WHERE net_id=OLD.net_id INTO vn_state;
    IF (vn_state=0) THEN
        UPDATE dicts SET hits=hits-1 WHERE d_id=OLD.d_id;
        UPDATE nets SET hits=hits-1 WHERE net_id=OLD.net_id;
    END IF;
END


0 commentaires