MySQL 5.7 可以完成每秒 50 万查询

本文详细介绍了MySQL 5.7版本在每秒查询性能上的显著提升,特别是针对读写混合负载的场景。通过对InnoDB引擎的优化,实现了高达50万次每秒查询的性能。

本文提供 MySql5.7实现每秒50W查询 一文的细节以及基准测试结果,解释了我早期在Mysql Connect 发表的谈话。

回顾 MySQL / InnoDB 的改善历史。你能很容易发现。在MySQL 5.6稳定版本中从来没有在read-only 这么快的提速,它很容易搞懂,以及在read-only(RO)有着良好的扩张性。也很期待它在read+write(RW)上达到一个较高水平。(特别是在读取数据是数据库主要工作的时候)


然而。我们对于RO在 MySQL 5.6的表现也十分的高兴,在5.7这个版本中,主要工作集中在 read+write (RW)上, 因为在大数据的处理上还没能达到我们的期望。但是RW依赖RO下。能够再次提高速度。 InnoDB 团队通过不断的改进,强烈的推进优化着5.7这个版本的每秒的性能。 

下面就按顺序为大家讲解

事实上,在MySQL中只读工作量控制内部链接的方式有以下两种:

  • 用单个表:MDL,trx_sys和lock_sys(InnoDB)
  • 多表:trx_sys和lock_sys(主要是InnoDB)

任何很快的单表范围测试的工作量主要由于MDL链接导致锁住。而多表将会由于InnoDB内部构件限制(不同的表将由不同的MDL锁保护,所以这种情况下MDL中的链接瓶颈将会降低)。但是同样,也要看工作量的大小–一个比一般多的只读工作测量将会在MySQL5.6中表现的会更好(如Sysbench OLTP_RO),同时在工作量少而快的查询(如Sysbench Point-Selects(用外键去取一个记录))将会使所有链接变得困难,而且只能在16核-HT中测量,而在32核中表现很差..但是任何如Point-Select测试的工作量将在所有MySQL内部构件一起工作是会让你看到可能达到最大的性能(开始用SQL解析器,终止与取行值)..在你给定的MySQL版本和给定的HW配置下,这也可能达到最大SQL 查询/每秒(QPS)率。

在Mysql5.6上我们获得的最佳结果是25万个查询每秒,这也是那段时间Mysql/InnoDb上使用SQL语句查询得到的最好的结果了。

当然,只有在使用‘只读事务’功能才能达到这么高速度(Mysql5.6上的新功能);另外,需要使用AUTOCOMMIT=1,否则CPU就会被轻易地浪费在启动事务、提交事务上,你会实际上损失系统的整体性能。

因此,在Mysql5.7上介绍的第一个改进是‘只读事务的自动发现’(实际上每个InnoDb事务都被认为是只读的直到有一个DML声明在此之外)功能—,这很大程度上简化了只读事务功能,节省了用户和开发者的时间,他们不用再去管理是否采用只读事务功能。但是,使用这个功能你仍然不能达到Mysql潜在的最佳每秒查询率,因为CPU时间还是浪费在事务的开启、结束状态处理过程当中。

同时,Percona用不同的的方案来解决“事务列表”管理(TRX-列表)及在InnoDB中trx_sys互斥链接慢的问题。Percona的解决方案在用事务处理Point-Selects高负载时能表现良好,但MySQL5.7表现一般(但我不会公布5.7的结果,因为它的代码不公开)…所以,至少我现在可以做一些比较:

MySQL 5.7 可以完成每秒 50 万查询 - 第1张  | IT江湖

观察结果:

  • 在MySQL5.6,Percona 5.5和MySQL5.7中的8个表中用同样的Roint-Select-TRX只读测试(用事务)(2013.5月的结果)
  • 同时你也可以看到,在同样的16核-HT配置下我们离峰值25万/s的结果还很远。
  • MySQL5.6在trx_sys互斥访问中延长了链接时间,而且自从64个用户后每秒的请求数将减少。
  • Percona5.5能维持很长的时间的负载,每秒请求在512个用户时才开始减少
  • 当MySQL5.7已经保持一段时间时,每秒请求依然没有减少(对于更多用户并发的情况你在这幅图里是看不到的)…

然而,很明显,如果用MySQL想要得到最大的潜在每秒查询速率,事务应当避免。

让我们来看一看这是2013年5月我们的每秒最大查询速率。

在同一点八张表进行测试,但是没有使用MySQL5.6的事物:

MySQL 5.7 可以完成每秒 50 万查询 - 第2张  | IT江湖

观察:

  • 上面的测试是保持MySQL5.6始终执行在16核上,然后是16芯-HT,32核,32芯-HT.
  • 正如你所看到的,最大的每秒查询速率比预期的还要大 -—— 在MySQL上是每秒27.5万
  • 最大的结果已经达到16芯-HT.
  • 然而在32核上的结果并没有16芯-HT上的好(由于竞争中断,在相同内核中,具有2CPU线程的配置能够更好的管理线程竞争——所以真正的并发性仍保存在16线程,而不是32核上)

而在MySQL5.7上做同样的测试却看起来大有不同,因为在5.7中lock_sys互斥链接的时间段已经很低了,同时trx_sys互斥相关代码也得到第一次变化的情形:

MySQL 5.7 可以完成每秒 50 万查询 - 第3张  | IT江湖

观察结果:

  • 首先你可以看到5.7在同样的16核-HT配置下的性能已经比5.6的要好
  • 之后,在32核配置下没有明显的增强!
  • 在32核-HT配置下达到了35万/秒的最大请求!
  • 从上面特殊(具有攻击性)只读负载测试的情况下可以容易看出我们在32核中得到的结果要比16的好,同时我们还没有启动超线程(在32核-HT)…牛吧!;-)

从另一方面来讲,仍然有改进的空间这点还是很清晰的。有关trx_sys的争用仍然在持续。我们没有充分的使用CPU的能力来做有用的工作(仍然有许多CPU周期用在锁的轮转)…不过现在的结果比以前好多了,并且比5.6好很多,因此没有理由继续挖掘来提高这方面的性能,我们主要集中在我们曾经花费了巨大的空间的读写负载的性能提高上。

到了5月底,也就是我们的性能会议期间,Sunny给try_sys互斥争用增加了几个新的更改,从那以后最大的每秒可进行的查询(QPS)可达到375K!这是不是对5.7进行了足够的性能提高,对吗?;-)

同时,我们继续与建议用其他方式管理TRX列表的Percona团队交换了意见,他们的方案看起来非常有趣,不过在5.5上,这样的代码却不能展示出更高的每秒可进行的查询数(QPS),而且在5.6上的这样代码(曾经测试过Percona Server 5.6)最大的每秒可进行的查询数(QPS)也不会比在MySQL 5.6上大。然而,讨论涉及到一个有趣的观点:如果同时有一些读写负载在运行的话,它对只读性能有什么影响呢?…而且,即使在同样的测试条件下MySQL 5.7代码仍然运行的要好一些,效果是非常明显的(你可以在这儿查看我的分析,然而,再次说明一下,这段时间内我不能展示5.7上的结果,因为它的代码还没有对大众公布-也许会在以后的一篇文章中给出)..

由于这儿同时对任何纯粹的读写负载也有影响,因此有足够的动机以Sunnys很长时间所期待的那样重新写整个TRX列表相关的代码,然而,这种经历简直让人痴迷! 

;-)) 日复一日,我们很高兴的看到我们的每秒可进行的查询图逐渐变高,直到在同一个32核的超线程服务器上达到了每秒可进行的查询440K!

5.7开发里程碑发布2上进行的Select 8个表所得到的结果数:

MySQL 5.7 可以完成每秒 50 万查询 - 第4张  | IT江湖

不需要说明..;-))

然而,有一个小小的令人奇怪的地方-我们试图与Sunny通过不同的工具分析所有瓶颈和代码更改所带来的影响。而且在某些测试里,令我吃惊的是Sunny观察到比我更高的每秒可进行的查询数..这个“奇异之处”与下面因素相关:

  • 在高负载下,现在的5.7代码都运行在接近硬件极限(主要是CPU)的位置,因此每条指令都非常重要!
  • 如果使用的Unix套接字或者IP端口,那么区分就会非常明显!
  • Sysbench自身使用了30%的CPU时间,不过同样的测试负载使用的是(具有更短的代码路径的)老版本的Sysbench的话,它将只使用20%CPU,剩余的10%用在MySQL服务器上。
  • 因此,同样测试负载的情况下,使用Unix套接字而不是IP 端口,并且使用Sysbench-0.4.8替代Sysbench-0.4.13的话,我们将得到每秒可进行的查询数超过500K!-很容易,不是吗?;-))

让我们来比较“之前”和“之后”的差异

MySQL 5.7 可以完成每秒 50 万查询 - 第5张  | IT江湖

观察结果:

  • 通过Sysbench降低了CPU的使用率。
  • 在MySQL服务器上具有更高的CPU可用性。
  • 我们实现了50万每秒查询。

还有什么呢?

我可能只提到:kudos Sunny和整个MySQL的开发团队;

让我们看一下现在选择8张表工作负载的情况下的最大每秒查询。

  • MySQL-5.7.2 (DMR2)
  • MySQL-5.6.14
  • MySQL-5.5.33
  • Percona Server 5.6.13-rc60.5
  • Percona Server 5.5.33-rel31.1
  • MariaDB-10.0.4
  • MariaDB-5.5.32

每个引擎都在以下配置下进行测试:

  • CPU taskset: 8核-HT,16核,16核-HT,32核,32核-HT
  • 并发会话数:8,16,32 … 1024
  • InnoDB自旋等待延时:6,96

最好的结果是来自任意两个特定的组合间的比较。通过对数据库引擎的比较,我得到了下面的一个图表,这个图表我在以前的文章中已经提到过了。

MySQL 5.7 可以完成每秒 50 万查询 - 第6张  | IT江湖下面是一些评论:

  • 对Mysql5.7的巨大差距结果不需要做过多的评论,因为这是很明显的。
  • 那么,有趣的是基于MySQL5.5的代码库引擎没有任何的接近MySQL5.6的结果。
  • 这已经证实了在使用MySQL5.6的代码库引擎之后,Percona Server达到了MySQL5.6的水平,然而MariaDB-10仍然还在探索的路上。
  • 因此,毫无疑问,MySQL5.6是代码的基石!
  • MySQL5.7是在MySQL5.6基础上的再一次优化扩展。

具有什么样的扩展性呢?

MySQL 5.7 可以完成每秒 50 万查询 - 第7张  | IT江湖

答案是简单的:MySQL5.7是唯一在此基础上进行扩展的。

如果使用ip端口和一个重量级的Sysbench-0.4.13,会得到如下的结果:

MySQL 5.7 可以完成每秒 50 万查询 - 第8张  | IT江湖

QPS只是稍微的略低一点,但是总体的趋势是完全一样的。

可扩展性也是非常的相似:

MySQL 5.7 可以完成每秒 50 万查询 - 第9张  | IT江湖

更多的结果将会出来,敬请期待;

注意:对一个单表绑定过多的工作负载是不好的:

  • 减少InnoDB间的争论使得其他的争论更加的明显。
  • 当负载是绑定在一张单表上时候,MDL的争论将变得更加主导。
  • 这是预期希望的,我们在下一个DMRS上将保持不变。

还有很多挑战摆在我们面前;-)

作为参考,我上述测试的硬件配置信息如下:

  • Server : 32cores-HT (bi-thread) Intel 2300Mhz, 128GB RAM
  • OS : Oracle Linux 6.2
  • FS : 启用”noatime,nodiratime,nobarrier”挂载的EXT4


my.conf:

 

如果你需要的话,Linux Sysbench的二进制版本在这里

  • Sysbench-0.4.13-lux86
  • Sysbench-0.4.8-lux86

 

使用UNIX socket来运行Point-Selects测试的Sysbench命令如下(在parallel中启动8个进程):

 

使用IP端口来运行Point-Selects测试的Sysbench命令如下(在parallel中启动8个进程):


愿你有所收获, 

<think>好的,用户现在问的是MySQL5.7如何查询锁的情况。我需要详细回答这个问题,包括相关的SQL语句和解释,还要给出代码示例。之前用户已经问过关于InnoDB行锁的问题,现在可能是在实际使用中遇到了锁的问题,需要排查。首先,我需要回忆一下MySQL5.7中查看锁的方法。记得在5.7版本中,常用的系统表是information_schema下的INNODB_TRX、INNODB_LOCKS和INNODB_LOCK_WAITS,不过可能在8.0之后这些表被performance_schema替代了,但用户问的是5.7,所以应该用这些表。另外,还可以使用SHOW ENGINEINNODBSTATUS命令来查看锁信息。 接下来,我需要分步骤说明如何查询锁的情况。可能需要包括查询当前事务、锁的详细信息、锁等待情况,以及如何分析死锁。同时,用户可能需要具体的SQL示例,所以需要写出具体的查询语句,并解释每个字段的含义。 此外,用户可能想知道如何监控锁等待和死锁,所以需要包括如何设置innodb_print_all_deadlocks参数,以及如何分析死锁日志。还要注意权限问题,因为某些系统表可能需要管理员权限才能访问。还要考虑用户的实际应用场景,比如他们可能在生产环境中遇到锁等待或死锁,需要快速定位问题。因此,提供的查询需要简洁有效,并且解释清楚每个步骤的作用。需要确保提供的代码示例正确,并且针对MySQL5.7版本。例如,在5.7中,INNODB_LOCKS和INNODB_LOCK_WAITS表是存在的,而在8.0中这些表被移除了,所以必须确认这一点。可能需要查阅文档确认,但根据记忆,5.7确实有这些表。 另外,用户可能想知道如何解读结果,所以需要解释每个查询返回的字段,比如lock_id、lock_mode、lock_type等,以及如何根据这些信息判断锁的类型和持有者。最后,要提出相关问题,比如如何解决死锁、不同锁模式的区别,如何监控锁等待时间等,这些相关问题需要和当前问题紧密相关,帮助用户深入理解。</think>在MySQL 5.7中查看锁状态主要通过以下系统表和执行引擎状态命令实现,以下是完整的查询方案: --- ### 一、核心查询方法 #### 1. 查询当前所有事务状态 ```sql SELECT * FROM information_schema.INNODB_TRX; ``` **关键字段说明**: - `trx_id`:事务ID - `trx_state`:事务状态(RUNNING/LOCK WAIT) - `trx_started`:事务开始时间 - `trx_query`:正在执行的SQL语句 - `trx_lock_structs`:持有的锁数量 #### 2. 查看详细锁信息 ```sql SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, l.lock_table, l.lock_index, l.lock_mode, l.lock_type FROM information_schema.INNODB_LOCK_WAITS w INNER JOIN information_schema.INNODB_LOCKS l ON w.requesting_lock_id = l.lock_id INNER JOIN information_schema.INNODB_TRX r ON w.requesting_trx_id = r.trx_id INNER JOIN information_schema.INNODB_TRX b ON w.blocking_trx_id = b.trx_id; ``` #### 3. 查看锁等待关系 ```sql SELECT waiting_pid, blocking_pid, waiting_query, blocking_query FROM sys.innodb_lock_waits; -- 需要先安装sys库 ``` #### 4. 引擎状态查看(包含最新死锁信息) ```sql SHOW ENGINE INNODB STATUS\G ``` 在输出结果的 `LATEST DETECTED DEADLOCK` 部分查看死锁详情 --- ### 二、锁分析案例 #### 场景:分析锁等待问题 ```sql -- 步骤1:找到被阻塞的线程 SELECT * FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT'; -- 步骤2:查看具体的锁争用关系 SELECT r.trx_id waiting_trx, b.trx_id blocking_trx, l.lock_table, l.lock_index, l.lock_mode FROM information_schema.INNODB_LOCK_WAITS w JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id JOIN information_schema.INNODB_LOCKS l ON w.requesting_lock_id = l.lock_id; -- 步骤3:终止阻塞线程 -- 根据步骤2查到的blocking_trx_id,找到对应的线程ID KILL [thread_id]; ``` --- ### 三、死锁日志分析示例 ```log LATEST DETECTED DEADLOCK ------------------------ 2024-01-01 12:00:00 0x7f8e3c0d6700 *** (1) TRANSACTION: TRANSACTION 12345, ACTIVE 10 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s) MySQL thread id 1001, OS thread handle 123456, query id 67890 localhost root UPDATE table1 SET col1=1 WHERE id=5 *** (1) HOLDS THE LOCK(S): RECORD LOCKS space id 1234 page no 5 n bits 72 index PRIMARY of table `test`.`table1` trx id 12345 lock_mode X locks rec but not gap *** (2) TRANSACTION: TRANSACTION 67890, ACTIVE 8 sec starting index read mysql tables in use 1, locked 1 3 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 1002, OS thread handle 654321, query id 12345 localhost root UPDATE table1 SET col1=2 WHERE id=6 *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 1234 page no 5 n bits 72 index PRIMARY of table `test`.`table1` trx id 67890 lock_mode X locks rec but not gap ``` --- ### 四、监控配置建议 1. 开启死锁日志记录 ```ini [mysqld] innodb_print_all_deadlocks = 1 -- 将所有死锁信息写入错误日志 ``` 2. 定期检查锁等待 ```sql -- 查看超过30秒的长事务 SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 30; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值