MySQL 触发器 Trigger 加载以及目前局限
GreatSQL 社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
GreatSQL 是 MySQL 的国产分支版本,使用上与 MySQL 一致。
作者: 亮
文章来源:GreatSQL 社区原创
概念介绍
首先需要知道 MySQL 中触发器特点,以及表 table 相关触发器加载方式
MySQL 中单个 trigger 仅支持单事件触发即单个触发器不支持类似 insert or update 等多事件语法操作,如果需要多事件都能被同一个表触发,只能分别建立多个对应 trigger。
触发器加载首先需要加载触发器分组列表 Trigger_chain,后续再将具体触发器添加到 Trigger_chain 内。
表 table 属性内可包含多个触发器分组列表 Trigger_chain,Trigger_chain 用于加载不同类别的触发器,主要类别有 insert、update 或 delete 类型。
触发器分组列表 Trigger_chain 内 m_triggers 又可加载多个具体属于该分组的具体触发器。
触发器分组列表 Trigger_chain 加载过程
1.当打开表 table 时通过如下函数过程加载触发器分组列表 Trigger_chain
2.跟踪 add_tables_and_routines_for_triggers 函数内参数定义
查看 TRG_EVENT_MAX 定义
查看 TRG_ACTION_MAX 定义
查看函数 get_triggers 内可知触发器加载存储方式是二维数组 m_trigger_map 内
综合 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。
版权声明: 本文为 InfoQ 作者【GreatSQL】的原创文章。
原文链接:【http://xie.infoq.cn/article/e91db59220f2feef5bcf90175】。文章转载请联系作者。
评论