MySQL触发器仅针对某个mysql用户

发布于 2024-08-20 15:34:42 字数 172 浏览 2 评论 0原文

我试图查明特定的 MySQL 用户是否仍在我们的系统中使用(以及它正在执行哪些查询)。

因此,我想到编写一个触发器,该触发器会在用户 X 执行查询时启动,并将该查询记录在日志表中。

我怎样才能做到这一点? 我知道如何为特定表编写查询,但不知道如何为特定用户(任何表)编写查询。

谢谢

I'm trying to find out if a specific MySQL User is still in use in our system (and what queries it is executing).

So I thought of writing a trigger that would kick in anytime user X executes a query, and it would log the query in a log table.

How can I do that?
I know how to write a query for a specific table, but not for a specific user (any table).

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半枫 2024-08-27 15:34:42

您可以在 USER()。

You could branch your trigger function on USER().

等风来 2024-08-27 15:34:42

最简单的方法是让触发器始终触发,但仅在用户是 X 时才记录。

The easiest would be to have the trigger always fire, but only logs if the user is X.

乙白 2024-08-27 15:34:42

我会考虑以下选项:

A)编写一个审核插件,它根据用户名过滤事件。

为简单起见,用户名可以硬编码在插件本身中,
或者为了优雅,可以通过插件变量进行配置,以防再次出现此问题。


http://dev.mysql.com/doc/refman /5.5/en/writing-audit-plugins.html

B) 研究 --init-connect 服务器选项。

例如,调用存储过程,检查 user() / current_user() 的值,
如果看到来自用户的连接,则将跟踪写入日志(插入表中)。


http://dev.mysql.com/doc /refman/5.5/en/server-system-variables.html#sysvar_init_connect

这可能是最接近连接触发器的东西。

C) 使用性能模式检测。

假设为 5.6。

使用表 Performance_schema.setup_instrument 仅启用语句检测。
使用表 Performance_schema.setup_actors 仅检测该用户的会话。

然后,在系统运行一段时间后,在下表中查看该用户的活动:

  • 表 Performance_schema.users 将告知是否存在某些活动
  • 表 Performance_schema.events_statements_history_long 将显示最后执行的查询
  • 表 Performance_schema.events_statements_summary_by_user将显示有关该用户执行的每种语句类型(SELECT、INSERT...)的聚合统计信息。

假设您有一个定义为“old_app”@“%”的用户,一个可能的后续问题是找出这个旧应用程序仍在从哪里(哪个主机)进行连接。

Performance_schema.accounts 将仅显示:如果看到该用户的流量,它将显示每个用户名@主机名的流量来源。
还有按帐户聚合的统计信息,查找“%_by_account%”表。


http://dev.mysql.com/doc/refman/5.6 /en/performance-schema.html

I would look at these options:

A) Write an audit plugin, which filters events based on the user name.

For simplicity, the user name can be hard coded in the plugin itself,
or for elegance, it can be configured by a plugin variable, in case this problem happens again.

See
http://dev.mysql.com/doc/refman/5.5/en/writing-audit-plugins.html

B) Investigate the --init-connect server option.

For example, call a stored procedure, check the value of user() / current_user(),
and write a trace to a log (insert into a table) if a connection from the user was seen.

See
http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_init_connect

This is probably the closest thing to a connect trigger.

C) Use the performance schema instrumentation.

This assumes 5.6.

Use table performance_schema.setup_instrument to only enable the statement instrumentation.
Use table performance_schema.setup_actors to only instrument sessions for this user.

Then, after the system has been running for a while, look at activity for this user in the following tables:

  • table performance_schema.users will tell if there was some activity at all
  • table performance_schema.events_statements_history_long will show the last queries executed
  • table performance_schema.events_statements_summary_by_user will show aggregate statistics about each statement types (SELECT, INSERT, ...) executed by this user.

Assuming you have a user defined as 'old_app'@'%', a likely follow up question will be to find out where (which host(s)) this old application is still connecting from.

performance_schema.accounts will just show that: if traffic for this user is seen, it will show each username @ hostname source of traffic.
There are statistics aggregated by account also, look for '%_by_account%' tables.

See
http://dev.mysql.com/doc/refman/5.6/en/performance-schema.html

天气好吗我好吗 2024-08-27 15:34:42

还有其他方法可以解决此问题,例如使用 MySQL 代理

在代理中,您可以做一些有趣的事情 - 从日志记录到转换查询,模式匹配(也请检查此链接以获取有关如何测试/开发脚本的详细信息)

-- set the username
local log_user = 'username'

function read_query( packet )
    if proxy.connection.client.username == log_user and string.byte(packet) == proxy.COM_QUERY then
        local log_file = '/var/log/mysql-proxy/mysql-' .. log_user .. '.log'
        local fh = io.open(log_file, "a+")
        local query = string.sub(packet, 2)
        fh:write( string.format("%s %6d -- %s \n",
            os.date('%Y-%m-%d %H:%M:%S'),
            proxy.connection.server["thread_id"],
            query))
        fh:flush()
    end
end

上面的内容已经过测试,并且它执行了预期的操作(尽管这是一个简单的变体,不记录成功或失败,并且只记录日志 proxy.COM_QUERY,查看所有 常量 查看跳过的内容并根据您的需要进行调整)

There are also other ways you could approach this problem, for example using MySQL proxy

In the proxy you could do interesting things - from logging to transforming queries, pattern matching (check this link also for details on how to test/develop the scripts)

-- set the username
local log_user = 'username'

function read_query( packet )
    if proxy.connection.client.username == log_user and string.byte(packet) == proxy.COM_QUERY then
        local log_file = '/var/log/mysql-proxy/mysql-' .. log_user .. '.log'
        local fh = io.open(log_file, "a+")
        local query = string.sub(packet, 2)
        fh:write( string.format("%s %6d -- %s \n",
            os.date('%Y-%m-%d %H:%M:%S'),
            proxy.connection.server["thread_id"],
            query))
        fh:flush()
    end
end

The above has been tested and it does what it is supposed to (although this is a simple variant, does not log success or failure and only logs proxy.COM_QUERY, see the list of all constants to see what is skipped and adjust for your needs)

浅浅淡淡 2024-08-27 15:34:42

是的,开火吧,但是只有当特定用户(用户 ID、类别)与您的凭据匹配时,才可以使用您所拥有的任何系统来查看它是什么用户(cookie、会话)来记录。

Yeah, fire away, but use whatever system you have to see what user it is (cookies, session) to log only if the specific user (userID, class) matches your credentials.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文