21

在 MySQL 方面需要帮助,因为它不是我的强项。所以任何帮助表示赞赏。

我的网站上存在缺失值UPDATEINSERT缺失值的问题。这在网站上的其他功能上引起了一些问题,但我无法找到在任何课程中完成UPDATE或完成的位置。INSERT

有没有什么办法,也许是一个 MySQL 触发器,我可以添加到这些表中,允许我存储 or 的原始或完整UPDATE查询INSERT。我尝试过日志记录,但这适用于整个数据库,并且占用了太多磁盘空间。

提前感谢您的任何回复。

PS:目前PHP类有点乱,因为我们还处于开发阶段,所以在更新或插入函数中添加异常会花费太多时间。所以请重点回答问题。再次感谢。

4

8 回答 8

41

您可以使用以下语句将当前 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列中。

于 2012-05-20T06:54:14.363 回答
4

我认为您需要检查数据库服务器的常规查询日志

The server ... ... logs each SQL statement received from clients. ... ... Since MySQL 5.1.6 log can be a file or a table.

于 2012-05-17T01:20:08.713 回答
1

如果您不希望数据库中缺少某些值,您可以使用约束来强制执行吗?

于 2012-05-26T07:05:48.327 回答
1

您不必将其记录到数据库中。

file_put_contents 与 FILE_APPEND 一起使用,并使用制表符分隔符或 csv 将其存储在文本文件中。这样,您可以在需要时轻松导入数据库,或者在需要时在 Excel 或 Numbers(在 Mac 中)中查看文件。

您可以按日期记录文本文件,即 sql_queries_2012-05-24,然后将其存储在文件夹中。文本文件不应占用比将其存储在数据库中更多的空间。一个简单的 'if else' 语句,带有 php 日期函数,应该得到按日期排序的日志记录。

使用文本文件在资源方面肯定比将它们存储在数据库中更具成本效益。此外,使用php fgetcsv对文本文件进行索引和 INSERT 比使用 mysql UPDATE 快得多。

于 2012-05-24T03:17:53.323 回答
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;
}
于 2012-05-26T06:38:16.773 回答
0

如果您既不能修改应用程序以记录您发送到 MySQL 的内容(通常是解决方案 #1),也不能启用通用查询日志(解决方案 #2,但是是的,不适用于生产) - 您可能想要使用 MySQL 代理. 看到这个:https ://github.com/mysql/mysql-proxy

MySQL Proxy 是轻量级程序,您可以将其放在客户端(PHP 脚本)和 MySQL 服务器之间。您可以在运行 MySQL 服务器本身的同一台服务器上运行 MySQL 代理,并使您的客户端直接连接到代理端口而不是 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 Proxy 增加了一些开销,但通常它非常轻量级。如果你也保持 Lua 脚本轻量级 - 它应该可以正常工作。

编辑:

该存储库最后一次更新是在 2014 年,目前,版本档案是这样说的:

MySQL Proxy 不是 GA,不推荐用于生产。

我们建议将 MySQL 路由器用于生产用途。下载 MySQL 路由器 »

遗憾的是,MySQL Router 看起来不像 MySQL Proxy 那样允许相同的功能。

于 2012-05-25T19:27:59.430 回答
-1

如果您的服务器安装了 PHP 5.3.0 或更高版本,那么这可能会有所帮助 http://www.php.net/manual/en/mysqlnd.plugin.php

于 2012-05-19T08:23:51.157 回答
-2

您可能希望打开二进制日志记录,以便查看每个更新(注意:不是每个查询)。您只需要添加--log-bin选项,然后使用 . 查看生成的日志mysqlbinlog。如有必要,您可以从备份启动数据库副本,在备份位置的日志中启动(使用类似--master-data选项 to保存在备份中mysqldump),然后一次运行一个更新,直到获得坏行。然后,您知道哪个更新是罪魁祸首。您可以编写最后一部分的脚本和/或对日志长度使用二进制搜索以使其运行得更快。

于 2012-05-19T08:51:35.517 回答