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

Posted 六月暴雪飞梨花

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了猿创征文|授权用户查询不到表?相关的知识,希望对你有一定的参考价值。

文章目录


前言

📫 作者简介:六月暴雪飞梨花,专注于研究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';

2.2.2 查看日志文件

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

mysql> show variables like 'general_log_file';


默认情况下,日志文件会放在你的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

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										
										……

查看下当前日志文件的大小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

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)

查看日志文件内容

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


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

3 总结

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

猿创征文|mysql中show的常用命令-Navicat篇建议收藏

文章目录


一.mysql show 命令

示例表test_new

1.查看表信息

语法desc 表名;

例子:查看test_new表的信息。

desc test_new

结果


2.查看表信息

语法describe 表名;

例子:查看test_new表的信息。

describe test_new

结果


3.显示表中列名称

语法show columns from 表名 from 数据库名; 或:show columns from 数据库名.表名;

例子:查看testdb数据库中test_new表的列名称信息。

show columns from test_new from testdb;

结果


总结

desc/describe /show columns from 表名;

  • 查表结构中的desc就是describe,排序中的desc就是descent
  • desc 表名 (作用:显示表结构,字段类型,主键,是否为空等属性,但不显示外键)
  • show columns from 表名(此命令是实时反映当前表结构,不是说后期改了表结构了,它就不变的)

4.显示create database 语句是否能够创建指定的数据库

语法show create database 数据库名;

例子:查看testdb数据库的创建语句。

show create database testdb;

结果


5.显示create table 语句是否能够创建指定的表

语法show create table 表名;

例子:查看test_new表的创建语句。

show create table test_new

结果


Create Table 详情:

CREATE TABLE `test_new` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '数据ID',
  `content` varchar(200) NOT NULL COMMENT '内容',
  `remark` varchar(100) NOT NULL COMMENT '备注',
  `deptId` int(11) NOT NULL DEFAULT '0' COMMENT '部门ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=utf8 COMMENT='测试新表'

6.显示当前使用或者指定的database中的每个表的信息

  • 信息包括表类型和表的最新更新时间

语法show table status 或:show table status from 数据库名;

例子:查看testdb数据库的状态。

show table status from testdb;

结果



7.显示当前数据库中所有表的名称

语法show tables; 或:show tables from database_name;

例子:查看testdb数据库中所有表的名称。

show tables from testdb;

结果


8.显示mysql中所有数据库的名称

语法show databases;

例子:查看mysql中所有数据库的名称。

show databases;

结果


9.显示系统中正在运行的所有进程

  • 也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。

语法show processlist;

例子:查看mysql正在运行的所有进程。

show processlist;

结果

使用如下语句可以查看当前数据库的各IP连接数

select SUBSTRING_INDEX(host,':',1) as ip , count(*)
from information_schema.processlist group by ip

10.显示一个用户的权限,显示结果类似于grant 命令

语法show grants for 数据库用户名@localhost;

例子:查询root用户的权限。

show grants for root@localhost;

结果


11.显示表的索引

语法show index from 表名;

例子:查看test_new表的索引信息。

show index from test_new;

结果


12.显示一些系统特定资源的信息

  • 例如,正在运行的线程数量

语法show status;

例子:查看统特定资源的信息。

show status;

结果


13.显示系统变量的名称和值

语法show variables;

例子:查看系统变量的名称和值。

show variables;

结果


14.显示服务器所支持的不同权限

语法show privileges;

例子:查看服务器所支持的不同权限。

show privileges;

结果


15.显示安装以后可用的存储引擎和默认引擎

语法show engies;


16.显示innoDB存储引擎的状态

语法show innodb status;


17.显示BDB存储引擎的日志

语法show logs;


18.显示最后一个执行的语句所产生的错误、警告和通知

语法show errors; 或:show warnings;

例子:查看最后一个执行的语句所产生的错误、警告和通知。

show warnings;

结果


二.information_schema数据库部分表说明

  • SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
  • TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
  • COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
  • STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。
  • USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。
  • SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。
  • TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。
  • COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。
  • CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。
  • COLLATIONS表:提供了关于各字符集的对照信息。
  • OLLATION_CHARACTER_SET_APPLICABILITY表:指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。
  • TABLE_CONSTRAINTS表:描述了存在约束的表。以及表的约束类型。
  • KEY_COLUMN_USAGE表:描述了具有约束的键列。
  • ROUTINES表:提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。
  • VIEWS表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。
  • TRIGGERS表:提供了关于触发程序的信息。必须有super权限才能查看该表。

其他文章推荐

详谈mysql各种常用操作数据表结构的用法【建议收藏】

创作不易,感谢您的点赞与支持。

超多精彩文章,快来阅览吧!【查看更多】

以上是关于猿创征文|授权用户查询不到表?的主要内容,如果未能解决你的问题,请参考以下文章

猿创征文|mysql中show的常用命令-Navicat篇建议收藏

猿创征文|分布式国产数据库 TiDB 从入门到实战

猿创征文 | 国产数据库之openGauss的单机主备部署及快速入门

猿创征文 |万字长文搞定企业中的mysql数据库部署及使用

猿创征文 |万字长文搞定企业中的mysql数据库部署及使用

猿创征文 |万字长文搞定企业中的mysql数据库部署及使用