• 猿创征文|授权用户查询不到表?



    CSDN

    前言

    📫 作者简介:六月暴雪飞梨花,专注于研究Java,就职于科技型公司后端中级工程师,擅长后端架构设计

    🔥 三连支持:如果此文还不错的话,还请 ❤️关注、👍点赞、👉收藏三连,支持一下博主~

    1 背景概述

    1.1 授权用户查询不到表?

    是这样子,前几日我的一位同事需要创建一个用户并且授权几张业务表提供给伙伴小组同事使用。脚本创建,提供授权。给伙伴使用时,伙伴小组给予的回复是查询不到表,整整给摆了一道乌龙。由于是半道儿上临时受命接的项目,也不知道前任捣鼓了啥,经过排查日志发现,是设置了MySQL的审计。好,那今日就浅浅的聊一下吧,作为一个成长。

    1.2 什么是MySQL审计?遵循什么规范?

    MySQL Enterprise Edition 包括 MySQL Enterprise Audit,使用服务器插件实现。MySQL Enterprise Audit 使用开放的 MySQL Audit API 来启用标准的、基于策略的监控和记录在特定 MySQL 服务器上执行的连接和查询活动。MySQL Enterprise Audit 旨在满足 Oracle 审计规范,为受内部和外部监管准则约束的应用程序提供了一个开箱即用、易于使用的审计和合规性解决方案。安装后,审计插件使 MySQL 服务器能够生成包含服务器活动审计记录的日志文件。日志内容包括客户端连接和断开连接的时间,以及它们在连接时执行的操作,例如它们访问的数据库和表。

    关于Oracle审计的规范,可以参考下官方提供的白皮文档。

    审计概述:https://docs.oracle.com/cd/E26926_01/html/E25889/auditov-1.html#scrolltoc

    审计白皮书https://www.oracle.com/cn/a/tech/docs/technical-resources/bwp-security-audit-vault.pdf

    1.3 MySQL审计解决什么问题?

    // to do

    2 本地实验环境

    MySQL专业版(MySQL Enterprise Edition)审计请参考官方提供的解决方案和操作执行步骤:MySQL Enterprise Edition审计 ,下面来说说MySQL Community (GPL) 社区版本自建测试环境审计是如何设置的。本文是在 GNU/Linux(CentOS 7 x86_64)环境下实验,后续我又在Mac上面实验了下,都是一致的结果。

    MySQL审计这里提供几种方式来讲一下,根据自己实验操作的步骤一一列出来,提供给大家借鉴,欢迎大家提出意见,不胜感激。也希望在MySQL进阶技能树的进阶可以有这个实践。

    MySQL审计的三种方式:

    • General Query Log
    • BinLog + init_connect
    • 审计插件

    下面先讲一下这个 general_log。

    2.1 general_log(不推荐)

    默认情况下,MySQL不开启General Query Log;开启General Query Log后,MySQL将所有到达MySQL Server的SQL语句记录下来。
    关于MySQL的日志,官方给予了明确的解释和说明,从字面的意思理解下,通常有以下几种日志:

    日志类型名称]日志信息
    Error log错误日志启动、运行或停止 mysqld时遇到的问题
    General query log一般查询日志已建立的客户端连接和从客户端收到的语句
    Binary log二进制日志更改数据的语句(也用于复制)
    Relay log中继日志从复制源服务器接收的数据更改
    Slow query log慢查询日志执行时间超过 long_query_time几秒钟的查询
    DDL log (metadata log)DDL 日志(元数据日志)DDL 语句执行的元数据操作

    2.2.1 查看general_log设置

    执行SQL命令可以看到默认general_logOFF的,SQL关键字语句和属性值是不区分大小写(这个可以设置)。

    mysql> show variables like 'general_log';
    
    • 1

    在这里插入图片描述

    2.2.2 查看日志文件

    General Query Log打开后,所有SQL的访问都会记录在general_log_file指向的日志文件。关于全局变量general_log_file值,日志文件位置,可以执行下面命令获取到。

    mysql> show variables like 'general_log_file';
    
    • 1

    在这里插入图片描述
    默认情况下,日志文件会放在你的MySQL文件下,命名规则为机器名称.log,例如我的mysql日志放在了/usr/local/mysql-8.0.18-macos10.14-x86_64/data/(通常情况下,我们称/usr/local/mysql-8.0.18-macos10.14-x86_64/MySQ_HOME)目录,机器名称为Macbook,那么这里的日志文件则是Macbook.log

    首先,我们可以看一下这个文件存放了什么内容。

    Aion.Liu $ tail -200f /usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log
    tail: /usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log: No such file or directory
    
    • 1
    • 2

    No such file or directory这提示我们没有这个文件或目录?事实上,这个也验证了我们第1步骤的准确性,默认是关闭的。

    2.2.3 手工打开General Query Log

    当执行mysql> set global general_log = on; 后,我们设置了全局变量general_log为打开状态,再次查看general_log是打开的,为ON状态。
    在这里插入图片描述
    当我们打开之后,我们再次按照2.2.2的步骤查看下日志文件的内容,惊喜来了,里面有文本内容了(下面我截取了部分)。

    Aion.Liu $ tail -200f /usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log
    										alert_notification.is_default,
    										alert_notification.disable_resolve_message,
    										alert_notification.send_reminder,
    										alert_notification.frequency
    										FROM alert_notification
    	  							 WHERE alert_notification.org_id = 1 AND ((alert_notification.is_default = '1'))
    2022-08-30T14:19:49.933094Z	 3678 Prepare	SELECT
    										alert_notification.id,
    										alert_notification.uid,
    										alert_notification.uid
    										FROM alert_notification
    	  							 WHERE alert_notification.org_id = 1 AND alert_notification.id = 1
    2022-08-30T14:20:35.933719Z	 3608 Close stmt
    2022-08-30T14:20:35.933977Z	 3678 Prepare	SELECT `id`, `org_id`, `version`, `name`, `type`, `access`, `url`, `password`, `user`, `database`, `basic_auth`, `basic_auth_user`, `basic_auth_password`, `with_credentials`, `is_default`, `json_data`, `secure_json_data`, `read_only`, `uid`, `created`, `updated` FROM `data_source` WHERE `id`=? AND `org_id`=? LIMIT 1
    2022-08-30T14:20:35.934139Z	 3678 Execute	SELECT `id`, `org_id`, `version`, `name`, `type`, `access`, `url`, `password`, `user`, `database`, `basic_auth`, `basic_auth_user`, `basic_auth_password`, `with_credentials`, `is_default`, `json_data`, `secure_json_data`, `read_only`, `uid`, `created`, `updated` FROM `data_source` WHERE `id`=4 AND `org_id`=1 LIMIT 1
    2022-08-30T14:20:35.934361Z	 3678 Close stmt
    2022-08-30T14:20:35.935332Z	 3608 Prepare	SELECT
    										alert_notification.id,
    										alert_notification.uid,
    										alert_notification.org_id,
    										alert_notification.name,
    										alert_notification.type,
    										alert_notification.created,
    										alert_notification.updated,
    										alert_notification.settings,
    										alert_notification.secure_settings,
    										alert_notification.is_default,
    										alert_notification.disable_resolve_message,
    										alert_notification.send_reminder,
    										alert_notification.frequency
    										FROM alert_notification
    	  							 WHERE alert_notification.org_id = ? AND ((alert_notification.is_default = ?))
    2022-08-30T14:20:35.935422Z	 3608 Execute	SELECT
    										alert_notification.id,
    										alert_notification.uid,
    										alert_notification.org_id,
    										alert_notification.name,
    										alert_notification.type,
    										alert_notification.created,
    										alert_notification.updated,
    										alert_notification.settings,
    										alert_notification.secure_settings,
    										alert_notification.is_default,
    										alert_notification.disable_resolve_message,
    										alert_notification.send_reminder,
    										alert_notification.frequency										
    										……
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    查看下当前日志文件的大小324K,这里我们打开日志后,日志就会实时写入到日志文件中。

    Aion.Liu $ du -h /usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log
    324K	/usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log
    
    • 1
    • 2

    2.2.4 实验

    1)我们在命令行工具窗口任意执行一些语句,我这里就查询下table1的表记录数有多少。
    在这里插入图片描述
    2)这个时候,我们看下日志文件的内容是如何记录的
    在这里插入图片描述
    很好理解了吧,查询类型以及执行语句的内容已经被记录到了日志中。

    3)使用客户端工具执行SQL命令,在我本地实验数据库study中,查询abc这张表的两个列数据。
    在这里插入图片描述
    4)这个时候,我们在过去日志文件查询下。
    在这里插入图片描述
    是不是很好理解了,这个时候在服务器执行的操作会被记录到设置的日志文件Macbook.log中。

    5)我们关闭全局日志设置试试
    执行命令如下命令

    mysql> set global general_log = off;
    Query OK, 0 rows affected (0.00 sec)
    
    • 1
    • 2

    查看日志文件内容

    tail -200f /usr/local/mysql-8.0.18-macos10.14-x86_64/data/Macbook.log
    
    • 1

    在这里插入图片描述
    由于我这里开启了调度事件和一些触发器,导致一直在执行SQL语句,所以会打印出来很多日志信息。当我们再次关闭时,日志将不在打印,并且在最后一行告知我们已经关闭了日志。那是不是所有的操作都会被记录到日志中呢,你如果有兴趣可以在本地试试。写到这里,前面遗留的一个 // to do 就无需我再多言了。

    3 总结

    开启General Query Log只要用户执行了操作,无论对错,MySQL就会记录日志,这样的话日志量会非常庞大,对数据库效率有影响。所以我们一般不建议开启开功能,个别情况下可能会临时的开一段时间以供排查故障等使用。

  • 相关阅读:
    Python在不同场景下的并发编程方案选择
    turtle模块练习
    Django JWT验证
    LeetCode --- 1920. Build Array from Permutation 解题报告
    我终于会写 Java 的定时任务了!
    代码随想录算法训练营第五十七天| 392.判断子序列、115.不同的子序列
    今日财富杂志今日财富杂志社今日财富编辑部2022年第21期目录
    SpringCloud Gateway 漏洞分析 (CVE-2022-22947)
    Redis网络模型
    python读取txt格式的点云文件,可视化显示,保存ply格式
  • 原文地址:https://blog.csdn.net/L_Lycos/article/details/126614374