作者:xuty
处理方式:
--视图定义CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`%` SQL SECURITY DEFINER VIEW v_test--函数定义CREATE DEFINER=`root`@`%` FUNCTION `f_test()` RETURNS varchar(100) SQL SECURITY DEFINER--存储过程定义CREATE DEFINER=`root`@`%` PROCEDURE `p_test`() SQL SECURITY DEFINER--触发器定义CREATE DEFINER=`root`@`%` trigger t_test--事件定义CREATE DEFINER=`root`@`%` EVENT `e_test`
DEFINER:对象定义者,在创建对象时可以手动指定用户,不指定的话默认为当前连接用户; SQL SECURITY:指明以谁的权限来执行该对象,有两个选项,一个为 DEFINER,一个为 INVOKER,默认情况下系统指定为 DEFINER; DEFINER:表示按定义者的权限来执行; INVOKER:表示按调用者的权限来执行。





因为要在会话窗口下模拟 verbose 一样输出备份信息,所以就照搬了原生的 verbose_msg() 函数,新建了个 print_dump_msg() 函数用于备份信息输出。

6.2 行数显示
dump_table 函数中增加备份行数输出,本身源码就是一行一行循环读取的,所以非常方便打印输出。

6.3 DEFINER 摘除
trigger 与 event 的 DEFINER 是在 dump_trigger |dump_events_for_db->cover_definer_clause 函数中通过 my_case_str 方法摘走的。

routines 的 DEFINER 是在 dump_routines_for_db 函数中通过 fprint 方法重新拼接定义摘走的。

views 的 DEFINER 是在 get_view_structure 函数中通过 my_case_str 方法摘走的。

七、改写效果
1. 备份过程中打印具体信息

2. SQL 备份中摘除了 DEFINER 属性

八、性能测试
通过 sysbench 造测试数据后,分别使用改写后的 mysqldump 与原生的 mysqldump 进行多次远程备份,查看平均耗时。
这里选择远程备份测试是因为很多实际使用场景也是远程备份,而且远程备份更能体现出频繁打印信息对备份性能的影响。
实际压测发现,如果每一行都打印一次,会严重影响性能,所以改成 1W 行打印一次,影响会比较小。
另外踩了个坑,一开始测试的时候是使用开启 debug 编译的 mysqldump,所以会执行很多多余的 debug 代码,备份速度非常慢,关闭 debug 重新编译后,速度就比较正常了。

通过测试,如果是 1W 行打印一次,对于备份的性能损耗是比较低的,在可接受范围之内。
九、小结
本次通过直接修改 mysqldump 源码的方式,比较好的解决了 DEFINER 问题,另外将改写后的 mysqldump 源码拿到 Windows 环境下编译后是可以直接使用的,亲测有效,不过 Windows 编译环境搭建繁琐多了。
故障分析 | MySQL 优化案例 - select count(*)
社区近期动态

点一下“阅读原文”了解更多资讯文章转载自爱可生开源社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





