需要MySQL的帮助,因为它不是我的强项。所以任何帮助都表示赞赏。
我的网站上存在UPDATE
或INSERT
缺少值的问题。这导致了网站上其他功能的一些问题,但我无法找到UPDATE
或INSERT
在任何类中完成的位置。
有没有办法,也许是MySQL触发器,我可以添加到这些表格中,这样我就可以存储UPDATE
或INSERT
的原始或完整查询。我已经尝试过记录,但这适用于整个数据库,并且它占用了太多的磁盘空间。
提前感谢您的回复。
PS:目前,由于我们还处于开发阶段,PHP类有点乱,因此在更新或插入函数中添加例外将花费太多时间。所以请把重点放在问题的答案上。再次感谢。答案 0 :(得分:33)
您可以使用以下语句将当前SQL查询作为字符串获取:
SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID()
所以你要做的就是创建一个TRIGGER
,它运行在你的表上的插入和/或更新操作上,应该(i)获取当前的sql语句和(ii)将其插入另一个表中,如下所示:
DELIMITER |
CREATE TRIGGER log_queries_insert BEFORE INSERT ON `your_table`
FOR EACH ROW
BEGIN
DECLARE original_query VARCHAR(1024);
SET original_query = (SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID());
INSERT INTO `app_sql_debug_log`(`query`) VALUES (original_query);
END;
|
DELIMITER ;
您必须创建两个触发器 - 一个用于更新,另一个用于插入。触发器将新查询作为字符串插入 app_sql_debug_log
列的 query
表中。
答案 1 :(得分:4)
我认为您需要检查数据库服务器的General Query Log。
The server ... ... logs each SQL statement received from clients. ... ... Since MySQL 5.1.6 log can be a file or a table.
答案 2 :(得分:1)
您不必将其记录到数据库中。
使用file_put_contents with FILE_APPEND并使用制表符分隔符或csv将其存储在文本文件中。这样,您可以在需要时轻松导入数据库或在需要时在Excel或Numbers(在Mac中)查看文件。
您可以按日期记录文本文件,即sql_queries_2012-05-24,并将其存储在一个文件夹中。文本文件不应占用比将其存储在数据库中更多的空间。使用php日期函数的简单'if else'语句应该按日期排序日志。
使用文本文件在资源方面比将它们存储在数据库中更具成本效益。 此外,使用php fgetcsv从文本文件中索引和INSERT比使用mysql UPDATE快得多。
答案 3 :(得分:0)
如果您既不能修改应用程序来记录发送给MySQL的内容(通常是解决方案#1),也不能启用常规查询日志(解决方案#2,但是,不是生产) - 您可能想要使用MySQL代理。请参阅:https://github.com/mysql/mysql-proxy
MySQL Proxy是一个轻量级程序,可以放在客户端(PHP脚本)和MySQL服务器之间。您可以在运行MySQL服务器本身的同一服务器上运行MySQL Proxy,并使您的客户端直接连接到代理端口而不是MySQL服务器(如果您无法修改客户端,您可以将MySQL服务器移动到另一个端口,并设置MySQL代理到以前由MySQL服务器使用的端口)。
然后,可以使用自定义脚本扩展MySQL代理,其中您的自定义脚本可以捕获各种类型的事件:新连接,发送到服务器的查询等。对于查询,您可以灵活地记录它们或阻止它们,或者无论如何,修改查询,或添加除实际发送的查询之外的新查询。
坏消息 - 自定义脚本在Lua (http://dev.mysql.com/doc/refman/5.5/en/mysql-proxy-scripting.html)中实现。好消息 - 您可以找到许多用于MySQL代理的示例Lua脚本。例如: http://forge.mysql.com/wiki/Lua_Scripts_For_MySQL_Proxy_Examples 。特别是您可能需要检查“阻止不需要的查询”示例并根据您的需要进行修改(您实际上不会阻止任何内容,但会将某些查询打印到日志中)。
MySQL代理增加了一些开销,但通常它非常轻量级。如果你保持你的Lua脚本也很轻松 - 它应该可以正常工作。
修改强>
存储库最后一次更新于2014年,目前,version archives说明了这一点:
MySQL代理不是GA,不建议用于生产。
我们建议使用MySQL路由器进行生产。 Download MySQL Router »
MySQL路由器看起来不像它允许与MySQL代理相同的功能。
答案 4 :(得分:0)
简单的基于PHP的解决方案
在PHP中使用override_function
使用您自己的函数覆盖mysql_query
,您可以使用该函数来分析和/或记录任何相关查询。
rename_function('mysql_query', 'mysql_query_orig');
override_function('mysql_query', '$query', 'return override_mysql_query($query);');
function override_mysql_query($query)
{
$result = mysql_query_orig($query);
if (stripos($query, "mytablename") !== FALSE) {
// log, echo, etc.
}
return $result;
}
答案 5 :(得分:0)
如果您不希望数据库中缺少某些值,可以使用约束来强制执行该操作吗?
答案 6 :(得分:-1)
如果您的服务器安装了PHP 5.3.0或更高版本,那么这可能会有所帮助 http://www.php.net/manual/en/mysqlnd.plugin.php
答案 7 :(得分:-1)
您可能希望启用binary logging,以便查看每次更新(请注意:并非每个查询)。您只需添加--log-bin
选项,然后使用mysqlbinlog
查看生成的日志。如有必要,您可以从备份启动数据库的副本,从备份位置的日志开始(使用--master-data
选项保存在备份中mysqldump
),然后运行一次更新一次,直到你得到一个坏行。然后你知道哪个更新是罪魁祸首。您可以编写最后一部分的脚本和/或在日志长度上使用二进制搜索,以使其更快。