写点什么

MySQL 触发器 Trigger 加载以及目前局限

作者:GreatSQL
  • 2023-05-17
    福建
  • 本文字数:1133 字

    阅读完需:约 4 分钟

  • GreatSQL 社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。

  • GreatSQL 是 MySQL 的国产分支版本,使用上与 MySQL 一致。

  • 作者: 亮

  • 文章来源:GreatSQL 社区原创



概念介绍

首先需要知道 MySQL 中触发器特点,以及表 table 相关触发器加载方式


  1. MySQL 中单个 trigger 仅支持单事件触发即单个触发器不支持类似 insert or update 等多事件语法操作,如果需要多事件都能被同一个表触发,只能分别建立多个对应 trigger。

  2. 触发器加载首先需要加载触发器分组列表 Trigger_chain,后续再将具体触发器添加到 Trigger_chain 内。

  3. 表 table 属性内可包含多个触发器分组列表 Trigger_chain,Trigger_chain 用于加载不同类别的触发器,主要类别有 insert、update 或 delete 类型。

  4. 触发器分组列表 Trigger_chain 内 m_triggers 又可加载多个具体属于该分组的具体触发器。

触发器分组列表 Trigger_chain 加载过程

1.当打开表 table 时通过如下函数过程加载触发器分组列表 Trigger_chain

函数open_tables->open_and_process_table->handle_table->add_tables_and_routines_for_triggers
复制代码

2.跟踪 add_tables_and_routines_for_triggers 函数内参数定义

查看 TRG_EVENT_MAX 定义

enum enum_trigger_event_type {
TRG_EVENT_INSERT = 0,
TRG_EVENT_UPDATE = 1,
TRG_EVENT_DELETE = 2,
TRG_EVENT_MAX
};
复制代码

查看 TRG_ACTION_MAX 定义

enum enum_trigger_action_time_type {
TRG_ACTION_BEFORE = 0,
TRG_ACTION_AFTER = 1,
TRG_ACTION_MAX
};
复制代码

查看函数 get_triggers 内可知触发器加载存储方式是二维数组 m_trigger_map 内

/// Triggers grouped by event, action_time.
Trigger_chain *m_trigger_map[TRG_EVENT_MAX] [TRG_ACTION_MAX];
复制代码


  • 综合 TRG_EVENT_MAX 和 TRG_ACTION_MAX 以及 m_trigger_map 可以看出目前 MySQL 触发器加载设计方式存在一定的弊端,即 TRG_EVENT 分组只能按 insert、update、delete 区分,单次触发事件只能触发执行对应分组内的触发器,对于需要扩展单触发器同时支持多事件的方式如:insert or update 、update or delete 等方式将需要较大的改造。

触发器分组列表 Trigger_chain 添加具体触发器 trigger 过程

1.打开过的 table 其触发器通过如下函数过程加载

  • 函数 open_tables->open_table_entry_fini->check_n_load

2.具体加载过程

  • 通过函数 check_n_load 内调用 load_triggers 函数从磁盘加载已经建好的触发器 t。

  • 然后调用 create_trigger_chain 函数获取到前期已经加载的触发器分组列表 Trigger_chain。

  • 最后触发器分组列表 Trigger_chain 调用 add_trigger 添加具体触发器 t 至分组列表内。


当目标表 table 有 insert、update 或 delete 操作时,即会触发执行对应分组列表 Trigger_chain 内相应分组的触发器。


说明:MySQL 在新增和删除触发器的操作时都会关闭当前已经打开的 table 句柄,在下次打开 table 时会重新 load 相应的 trigger。

发布于: 刚刚阅读数: 5
用户头像

GreatSQL

关注

GreatSQL社区 2023-01-31 加入

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。 社区:https://greatsql.cn/ Gitee: https://gitee.com/GreatSQL/GreatSQL

评论

发布
暂无评论
MySQL触发器Trigger加载以及目前局限_MySQL_GreatSQL_InfoQ写作社区