热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DebuggingMariaDBstoredprocedureswiththeSQLErrorLog_MySQL

DebuggingMariaDBstoredprocedureswiththeSQLErrorLog
MariaDB

A very old version of the MySQL site contained a nice header:Speed, Power, Ease of Use. I don’t think thatstored programs(routines, triggers, events) were supported, at that time. Now they are, and… developing them is amazingly hard.

There are many problems, for example the language is not flexible and the execution is sloooow. But the biggest problem is that there is no debug API.

In details, one of the biggest problems is that, if you have complex procedures (accessing multiple tables, having error handling, and/or calling other procedures) in practiceyou have no ideaof what warnings occur within your procedures.

MariaDB 10.0 makes things much easier by adding theSQL_ERROR_LOGplugin.Well, I don’t think that they had stored programs in mind when they developed it. But what’s important for us is that… it makes stored programs debug decent.

This article explains how. Its use in application debugging is not covered here, because it seems to me quite obvious.

Enabling SQL_ERROR_LOG

We will use theSQL_ERROR_LOGplugin. Its purpose is to log SQL errors into a text file. To enable it:

INSTALL SONAME 'sql_errlog';

Note that specifying the file extension isnot necessary; this makes the statement platform-independent. The MySQL syntax is still supported.

When the plugin is installed, the logging is always active. To stop the logging, uninstall the plugin:

UNINSTALL PLUGIN SQL_ERROR_LOG;

Unfortunately, you might see a warning like this:

Warning (Code 1620): Plugin is busy and will be uninstalled on shutdown

I don’t know any way to avoid this. But I don’t think thatSQL_ERROR_LOGis meant to be ran on a production server. However, if this is a problem for you, just ask the list or file a bug.

Errors are written in a file calledsql_errors.log, in the data directory:

MariaDB [test]> SELECT CONCAT(@@global.datadir, @@global.sql_error_log_filename) AS sql_errlog;+--------------------------------------+| sql_errlog |+--------------------------------------+| /usr/local/mysql/data/sql_errors.log |+--------------------------------------+1 row in set (0.00 sec)

To make debug and life easier, I rotate the file very often:

SET @@global.sql_error_log_rotate = 1;

The format is the following:

2014-06-301:22:30 root[root] @ localhost [] ERROR 1051: Unknown table 'test.unknown_table' : DROP TABLE `unknown_table`

Limitations

  • The session id is not written to the log. The hostname and the user account are written, but they don't help us distinguishing one session from others. I supose it is meant for being executed by application developers on their local machines.
  • In theory, only errors are logged - no warnings, no notes. But keep on reading.
  • The file format is not safely parseable. It's designed for humans.

Debug Messages

Look at the following procedure:

DROP PROCEDURE IF EXISTS do_something;DELIMITER ||CREATE PROCEDURE do_something(IN p TEXT)	READS SQL DATABEGIN	DECLARE CONTINUE HANDLER		FOR SQLSTATE '45000'	BEGIN END;		IF @debug = TRUE THEN		SET GLOBAL sql_error_log_rotate = 1;	END IF;		IF @debug = TRUE THEN		SET @error = CONCAT('p = ', IF(p IS NULL, 'NULL', QUOTE(p)));		SIGNAL SQLSTATE '45000' SET			MYSQL_ERRNO = 9999,			MESSAGE_TEXT = @error;	END IF;		-- why do something? let's do nothing!	DO NULL;END ||DELIMITER ;SET @debug = TRUE;CALL do_something('x');

Got the trick? If the@debugvariable is set toTRUE, an error is produced. The error is immediately suppressed by an emptyCONTINUE HANDLER, so the procedure's execution continues and nothing happens. Well, almost nothing: the error is logged!

So:

  1. Write yourCONTINUE HANDLERs.
  2. Set@debugto 1.
  3. CALLyour procedure.
  4. catthesql_errors.log.

Warning Logging

Look at this example:

DROP PROCEDURE IF EXISTS do_something;DELIMITER ||CREATE PROCEDURE do_something()	READS SQL DATABEGIN	DECLARE CONTINUE HANDLER		FOR SQLWARNING	BEGIN		DECLARE CONTINUE HANDLER			FOR SQLSTATE '45000'		BEGIN END;				GET DIAGNOSTICS CONDITION 1			@errno = MYSQL_ERRNO			, @error = MESSAGE_TEXT			;		IF @debug = TRUE THEN			SIGNAL SQLSTATE '45000' SET				MYSQL_ERRNO = @errno,				MESSAGE_TEXT = @error;		END IF;		RESIGNAL;	END;		IF @debug = TRUE THEN		SET GLOBAL sql_error_log_rotate = 1;	END IF;		-- here goes the 'real' procedure.	-- let's produce a warning to trigger the main HANDLER...	DO 1/0;END ||DELIMITER ;

I know: this is tricky. Writing this has been hard. But don't worry: reusing this template will be quite easy.

The mainHANDLERcatches the warnings (in this case pision by 0, if you have a goodSQL_MODE). Then we get the warning properties (GET DIAGNOSTICS) and we use them to issue an error (SIGNAL). The error is suppressed by the internal emptyHANDLER, but it is logged. Finally, the error isRESIGNAL'd, because we don't want the debug code to suppress warnings.

A final note. Do you want to log warnings only if they appear within a particular portion of your procedure? You can. Just enclose those lines in aBEGIN ... ENDconstruct, and define your handlers inside the construct.

Enjoy!

推荐阅读
  • 数据库进入全新时代,腾讯云发布五大数据库提前布局
    8月28日,腾讯云数据库在京正式启动战略升级,宣布未来将聚焦云原生、自治、超融合三大战略方向,以用户为中心,联接未来。并在现场面向全球用户同步发布五大战略级新品,包括数据库智能管家 ... [详细]
  • MFC程序连接MySQL成功实现查询功能,但无法实现修改操作——详解查询语句在MySQL中的使用过程
    selectxxx,xxx,xxxfromxxxwherexxxxxx,xxxxxx程序的日常开发中,我们经常会写到各种各样的简单的,复杂的查询sql语 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了通过mysql命令查看mysql的安装路径的方法,提供了相应的sql语句,并希望对读者有参考价值。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 本文介绍了将mysql从5.6.15升级到5.7.15的详细步骤,包括关闭访问、备份旧库、备份权限、配置文件备份、关闭旧数据库、安装二进制、替换配置文件以及启动新数据库等操作。 ... [详细]
  • MySQL45讲之备库并行复制策略-前言本文主要介绍MySQL备库的并行复制策略。为什么备库需要并行复制如果主库有大量更新操作,因为主库可以并发写入,而备库只能单线程执行的 ... [详细]
  • 【BUUCTF】[极客大挑战 2019]LoveSQL 详细题解总结笔记 Writeup
    【BUUCTF】[极客大挑战2019]LoveSQL一.SQL注入考点二.解题过程0.存在SQL注入1.万能密码adminor112.爆字段3.看回显4.爆数据库5.爆数据库的表6 ... [详细]
author-avatar
无与伦比的美丽MJ
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有