在某些数据访问层框架中,会使用show full tables from test like 'demo',来检查数据库的状态。当数据库中表的数量较少时,并没有出现严重的问题。但是当数据库中的表数量多余千个时,且并发数较高时,通过show processlist就会发现show full tables语句绝大部分处于checking permissions状态

| 2 | test | 192.168.15.128:57656 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 3 | test | 192.168.15.128:57657 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 4 | test | 192.168.15.128:57658 | NULL | Sleep | 0 | | NULL |
| 5 | test | 192.168.15.128:57659 | NULL | Query | 0 | Sending to client | show full tables from test like '%demo%' |
| 6 | test | 192.168.15.128:57662 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 7 | test | 192.168.15.128:57661 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 8 | test | 192.168.15.128:57660 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 9 | test | 192.168.15.128:57663 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 10 | test | 192.168.15.128:57664 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 11 | test | 192.168.15.128:57665 | NULL | Query | 0 | checking permissions | show full tables from test like '%demo%' |
| 12 | test | 192.168.15.128:57666 | test | Query | 0 | starting | show processlist |

从给出的状态信息来看,很多人会误以为这是在该SQL需要做复杂的权限检查。google一下之后,发现也有人遇到类似的问题,并认为是mysql.user表中的条目数过多。但是我本机中,显然不是这个原因。

mysql> select count(*) from mysql.user;
+----------+
| count(*) |
+----------+
| 5           |
+----------+
1 row in set (0.00 sec)

由于show full tables from test like '%demo%'需要检查test数据库下的所有frm文件,因此表的数量越多,就越有可能出现这个问题。为了验证,我在两个实例上分别创建一个表和创建2000个表

一个表时,

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show full tables from test like 'demo';
+-----------------------+------------+
| Tables_in_test (demo) | Table_type |
+-----------------------+------------+
| demo | BASE TABLE |
+-----------------------+------------+
1 row in set (0.00 sec)

mysql> show profile;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000227 |
| checking permissions | 0.000020 |
| checking permissions | 0.000023 |
| Opening tables | 0.000452 |
| init | 0.000078 |
| System lock | 0.000051 |
| optimizing | 0.000030 |
| statistics | 0.000179 |
| preparing | 0.000134 |
| executing | 0.000069 |
| checking permissions | 0.000557 |
| Sending data | 0.000136 |
| end | 0.000036 |
| query end | 0.000032 |
| closing tables | 0.000042 |
| removing tmp table | 0.000110 |
| closing tables | 0.000060 |
| freeing items | 0.000122 |
| cleaning up | 0.000028 |
+----------------------+----------+
19 rows in set, 1 warning (0.01 sec)

2000个表时

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show full tables from test like 'demo';
+-----------------------+------------+
| Tables_in_test (demo) | Table_type |
+-----------------------+------------+
| demo | BASE TABLE |
+-----------------------+------------+
1 row in set (0.01 sec)

mysql> show profile;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000083 |
| checking permissions | 0.000004 |
| checking permissions | 0.000002 |
| Opening tables | 0.000032 |
| init | 0.000008 |
| System lock | 0.000005 |
| optimizing | 0.000003 |
| statistics | 0.000104 |
| preparing | 0.000024 |
| executing | 0.000004 |
| checking permissions | 0.002991 |
| Sending data | 0.000014 |
| end | 0.000003 |
| query end | 0.000005 |
| closing tables | 0.000002 |
| removing tmp table | 0.000003 |
| closing tables | 0.000002 |
| freeing items | 0.000047 |
| cleaning up | 0.000013 |
+----------------------+----------+
19 rows in set, 1 warning (0.01 sec)

0.002991/0.000557=5.36,其所消耗时间增长了5倍以上,在高并发下,其现象更明显。

那么标注为红色的checking permission是否真正表示在做权限检查了,答案是否定的。

通过检查MySQL5.6源码,可以发现,在执行show full tables from test like '%demo%'时,checking permission期间其实做了两部分工作,

1、检查权限

2、遍历test数据库下所有的frm文件,并获取相关信息。根据获得的信息,经过like条件过滤后,写入到一个临时表(memory引擎表)中

在sending data阶段,从这个临时表,把数据发送给用户

因此在某些SQL语句下,状态为checking permission时,并不一定真的在做权限检查。

所以不要频繁的向数据库发送show full tables from test like '%demo%',尤其是在表的数量很多时。

高并发下MySQL出现checking permissions的更多相关文章

  1. EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题

    下订单减库存的方式 现在,连农村的大姐都会用手机上淘宝购物了,相信电商对大家已经非常熟悉了,如果熟悉电商开发的同学,就知道在买家下单购买商品的时候,是需要扣减库存的,当然有2种扣减库存的方式, 一种是 ...

  2. 【mysql】mysql增加version字段实现乐观锁,实现高并发下的订单库存的并发控制,通过开启多线程同时处理模拟多个请求同时到达的情况 + 同一事务中使用多个乐观锁的情况处理

    mysql增加version字段实现乐观锁,实现高并发下的订单库存的并发控制,通过开启多线程同时处理模拟多个请求同时到达的情况 ==================================== ...

  3. php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  4. (高级篇)php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  5. php结合redis实现高并发下的抢购、秒杀功能 (转载)

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...

  6. php 高并发下 秒杀处理思路

    1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的后台进程以及延迟问题,不予考虑. 2.数据库乐观锁,大致的意思是先查询库存,然后立马将库存+1,然后订 ...

  7. PHP开发中多种方案实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...

  8. PHP和Redis实现在高并发下的抢购及秒杀功能示例详解

    抢购.秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等. 抢购.秒杀实现很简单,但是有些问题需要解决,主要针对两个问题: 一.高并发对数据库产生的压力二. ...

  9. 【转】php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

随机推荐

  1. git config 配置

    1. git config简介 我们知道config是配置的意思,那么git config命令就是对git进行一些配置.而配置一般都是写在配置文件里面,那么git的配置文件在哪里呢?互动一下,先问下大 ...

  2. (temp)catch ip

    String str = "192.168.1.100"; String[] ipStr = str.split("\\."); ]; ; i < ; i ...

  3. 将webservice封装成dll

    生成dll文件的步骤如下:1.发布完成后,在浏览器中打开WebService文件,如:http://localhost/WebSer/WebService1.asmx,可以看到WebService1. ...

  4. percona server 二进制安装下编译tpcc-mysql的坑

    出于习惯,percona server的部署都是通过二进制包自动化安装,结果遇到一个硕大无比的坑,编译TPCC-MySQL时出现警告 10:49:36 root@DB-Master:~/tpcc-my ...

  5. python 实现简单 http 代理

    有台 openwrt 路由器,16M flash存储 + 64M 内存 ,可以装 python .因为没有自带 url 网站访问记录,想手写一个. 原理: http 1.1 也就是 tcp 连接,有 ...

  6. Android EditText中插入话题模块的删除处理方法

    在 EditText 中添加话题 或者是 @某人 时 看起来挺简单,实际操作会有很多坑爹的问题 private String mTopic: //光标保持在话题的末尾 mInputEdit.setOn ...

  7. CSS3 笔记二(Gradients)

    CSS3 Gradients Two types of gradients: Linear Gradients (goes down/up/left/right/diagonally) Radial ...

  8. git 常用命令及解析 由浅入深

    笔者用的是windows系统,不过并没有什么影响. Git  分布式版本控制系统. 为了让初学git的人明白git是干什么的,有什么意义 笔者觉得先来介绍git作为版本控制器是怎么运作的会让大家对后边 ...

  9. proxifier 3.29 key

    Proxifier 3.29 serial key :-   [Use only One ]  (Standard Edition Keys) 5EZ8G-C3WL5-B56YG-SCXM9-6QZA ...

  10. Centos7永久修改主机名

    最近在编写centos6.x的启动脚本,考虑到以后系统会升到7.x,故想让脚本兼容7.x,还是有一些和6版本不一样的地址,修改主机名比较常用,特此记录一下 1.命令行修改: hostnamectl s ...