我的编程空间,编程开发者的网络收藏夹
学习永远不晚

记一次由mysql触发器引发的故障

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

记一次由mysql触发器引发的故障

上周六到公司上班,刚坐下没多久,公司业务传过消息说,用户borrow表信息无法更新。查看网站报错如下:
记一次由mysql触发器引发的故障
报错信息表示是由于mysql的函数和触发器引起的,问了下公司开发,他们表示函数功能已经测试上线好久了,没有问题,而触发器是这周刚上的。于是,赶紧进入生产的DB服务器进行查看:

mysql> use wendi;
Database changed
mysql> SHOW TRIGGERS\G;
...
*************************** 2. row ***************************
             Trigger: cl_borrow_before_insert_tigger
               Event: INSERT
               Table: cl_borrow
           Statement: begin
  set @channel_id = (select channel_id from cl_user where user_id = new.user_id);
  -- if @channel_id is not null and new.channel_id is null THEN
  --   update cl_borrow set channel_id=@channel_id where borrow_id = new.borrow_id;
  -- end if;
  insert into cl_borrow_status_log (user_id,borrow_id,status_old,status_new,audit_user_id,audit_remark,create_time,channel_id) values (new.user_id,new.borrow_id,null,new.status,new.audit_user_id,new.audit_remark,UNIX_TIMESTAMP(now()),@channel_id);
end
              Timing: BEFORE
             Created: NULL
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
*************************** 3. row ***************************
             Trigger: cl_borrow_after_insert_trigger
               Event: INSERT
               Table: cl_borrow
           Statement: begin
  set @channel_id = (select channel_id from cl_user where user_id = new.user_id);
  -- if @channel_id is not null and new.channel_id is null THEN
  --   update cl_borrow set channel_id=@channel_id where borrow_id = new.borrow_id;
  -- end if;
  insert into cl_borrow_status_log (user_id,borrow_id,status_old,status_new,audit_user_id,audit_remark,create_time,channel_id) values (new.user_id,new.borrow_id,null,new.status,new.audit_user_id,new.audit_remark,UNIX_TIMESTAMP(now()),@channel_id);
end
              Timing: AFTER
             Created: NULL
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
*************************** 4. row ***************************
             Trigger: cl_borrow_after_update_trigger
               Event: UPDATE
               Table: cl_borrow
           Statement: begin
  if old.status != new.status then 
    set @channel_id = (select channel_id from cl_user where user_id = new.user_id); 
    insert into cl_borrow_status_log (user_id,borrow_id,status_old,status_new,audit_user_id,audit_remark,create_time,channel_id) values (new.user_id,new.borrow_id,old.status,new.status,new.audit_user_id,new.audit_remark,UNIX_TIMESTAMP(now()),@channel_id);
  end if;
end
              Timing: AFTER
             Created: NULL
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
*************************** 5. row ***************************
             Trigger: cl_borrow_status_log
               Event: INSERT
               Table: cl_borrow_status_log
           Statement: BEGIN
  update cl_borrow set double_audit_user_id = new.audit_user_id,double_audit_time=new.create_time where borrow_id=new.borrow_id ;
end
              Timing: AFTER
             Created: NULL
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
    ...
    11 rows in set (0.00 sec)

如上,总共有11条触发器。为了不影响业务,我决定先将触发器备份,然后将其删除。

1,备份mysql触发器:
mysqldump --triggers -R -ndt -uroot -p cashloan> wenditrigger.sql

这里复习下mysqldump命令:

--triggers: Dump triggers for each dumped table. (Defaults to on; use --skip-triggers to disable.)

这个是默认值,mysqldump默认会导出触发器。(如果不想备份触发器使用--skip-triggers即可)

-R, --routines: Dump stored routines (functions and procedures).

导出存储过程以及函数。

-n, --no-create-db Suppress the CREATE DATABASE ... IF EXISTS statement that normally is output for each dumped database if --all-databases or --databases is given.

不创建建库语句,只对数据进行导出。

-d, --no-data No row information.

不导出数据,只导出表结构。

-t, --no-create-info Don't write table creation info.

不导出建表语句,只导出数据。

2,查看备份内容:
[root@DB ~]$ less wenditrigger.sql
-- MySQL dump 10.13  Distrib 5.6.20, for linux-glibc2.5 (x86_64)
...
DELIMITER ;;
  ;;
...
  ;;
DELIMITER ;

可以看到触发器已经备份好了。

3,删除触发器:

因为当时情况紧急,首要任务是将业务恢复,所以就把触发器全部删除了。
删除暂时没找到批量的方法,还好数据只有11条,一条一条删吧。

...
mysql> drop trigger cl_borrow_after_insert_trigger;
mysql> drop trigger cl_borrow_after_update_trigger;
mysql> drop trigger cl_borrow_status_log;
mysql> drop trigger cl_installment_after_insert_trigger;
...

至此,业务终于恢复了。

小结:

1,MySQL触发器属于隐式调用,往往会在你不知道的情况下做出许多操作,从而增加系统的复杂程度。
2,复杂MySQL触发器会嵌套使用,这就有可能产生死锁,本例就是个印证,borrow表触发插入其他表,而插入其他表的操作又会触发borrow表更新,这就产生了死锁,导致borrow表无法被更新。

MySQL触发器简介:

触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。
触发器语法:

CREATE TRIGGER trigger_name
trigger_time
trigger_event ON table_name
FOR EACH ROW
trigger_statement

trigger_name:触发器名称
trigger_time:触发器触发时机(BEFORE/AFTER)
trigger_event: 触发事件(INSERT,UPDATE,DELETE)
table_name: 建立触发器的表名称
trigger_statement: 触发器程序体,可以为单一的SQL语句,也可以是包含BEGIN,END在内的多条语句。
FOR EACH ROW: 行级触发

参考文章:
https://www.cnblogs.com/duodushu/p/5446384.html

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

记一次由mysql触发器引发的故障

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ASM单实例由Oracle Restart引发的系列故障分析(Final Version)

ASM单实例由Oracle Restart引发的系列故障分析(Final Version) 置顶 aaron8219 2013-08-26 03:35:50   5816   收藏 分类专栏: Oracle ASM 版权 今天重新打开上次安装完的一个ASM单实
ASM单实例由Oracle Restart引发的系列故障分析(Final Version)
2016-09-18

一文带你了解MySQL中触发器的操作

目录概述介绍触发器的特性操作—创建触发器操作—new和old操作—查看触发器操作—删除触发器注意事项概述介绍触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储
2023-02-17

记一次nginx配置不当引发的499与failover机制失效问题

近期在非高峰期也存在499超过告警阈值的偶发情况,多的时候一天几次,少的时候则几天一次,持续一般也就数分钟,经过和小伙伴的共同探究,最后发现之前对于499是客户端主动断开因而和服务端关系不大的想当然认知是错误的,这里记录一下
2023-05-18

阿里云服务器发生的大故障一次深刻的技术教训

近日,阿里云服务器发生了一次大规模的故障,引发了广泛关注。本文将深入探讨这次故障的原因、影响以及阿里云对于技术故障的应对措施,以期为相关企业和技术团队提供有益的启示。正文:近日,阿里云服务器发生了一次大规模的故障,其规模之大、影响之广,都令人震惊。据了解,这次故障影响了阿里云在全球多个地区的服务器,导致大量用户的
阿里云服务器发生的大故障一次深刻的技术教训
2023-12-16

MySQL 使用触发器记录用户的操作日志问题

目录mysql 使用触发器记录用户的操作日志一、创建用户数据表(emp)和保存操作日志的表(emp_log)二、为 emp 表创建触发器1、创建触发器 trigger_after_insert_emp2、创建触发器 trigger_afte
2022-12-05

MySQL触发器在数据变更日志记录中的实现

MySQL触发器(Trigger)是一种自动执行的操作,当对某个表进行插入、更新或删除操作时,它将自动执行触发器中定义的操作数据变更日志记录(Data Change Logging)是一种记录数据库中数据变更情况的机制。在MySQL中,可
MySQL触发器在数据变更日志记录中的实现
2024-09-26

MySQL 使用触发器记录用户的操作日志问题

使用 MySQL 触发器可以记录哪些用户、什么时间对数据表进行了增、删、改操作。如果执行删除操作,则记录删除之前的数据记录;如果执行更新操作,记录更新之前的数据记录,这篇文章主要介绍了MySQL 使用触发器记录用户的操作日志,需要的朋友可以参考下
2022-12-08

MySQL触发器在数据一致性维护中的深度应用

MySQL触发器是一种在数据库中实现自动响应特定事件的机制,通过在特定数据库事件(如INSERT、UPDATE或DELETE)发生时自动执行某些动作,触发器在数据一致性维护中发挥着重要作用。以下是关于MySQL触发器在数据一致性维护中的深度
MySQL触发器在数据一致性维护中的深度应用
2024-09-26

MySQL触发器在数据同步一致性保证中的作用

MySQL触发器在数据同步一致性保证中扮演着重要角色,它们可以在数据发生变化时自动执行特定的操作,从而确保数据的一致性和完整性。以下是触发器在数据同步一致性保证中的作用:数据完整性约束触发器可以在数据被插入、更新或删除之前或之后对其进行
MySQL触发器在数据同步一致性保证中的作用
2024-09-26

编程热搜

目录