从毕业开始到现在一年,一直上班做重复的工作,没什么记录的也没什么时间记录。
问题描述,同一套系统部署在了两台不同服务器,一台使用金仓数据库(服务器A)一台使用mysql(服务器B)。在服务器A上,页面可正常访问,服务器B上页面却无法显示。
排查过程中大部分页面都很顺利,无非是某些表数据变动或是数据同步问题,但过程中好几个页面表现的挺奇怪的,如下图所示:
浏览器的请求并没有失败,但也没有成功(页面无数据)。并且奇怪的是,这个请求没有状态码,并且通过点击页面来观察后台日志,在日志中显示该请求被处理,之后就没有打印任何信息了,也没有任何报错。
对比两侧数据库同一张表(temp表)的数据,数据也相同。
到这里只能排查数据库日志,查看这个请求到底做了什么。
由于mysql并没有开启查询日志,因此无法得知具体的信息,但还是可以查询mysql的processlist表通过线程排查
mysql的processlist表用于查看当前mysql服务器上所有运行中的进程列表信息。该表的表结构如下图所示。
user--表示执行命令的用户名
host--表示执行命令的服务器ip及端口号
db--表示正在工作的数据库
info--表示正在执行的sql
time--表示这个sql执行了多长时间,单位为秒
上图为复现的数据,第一次查询时,这里info中的sql有四五条,并且time为2000多秒,还在不停提升。
将这个sql捞出来,使用explain分析sql查询慢的原因。
EXPLAIN :模拟Mysql优化器是如何执行SQL查询语句的,从而知道Mysql是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。
可以看到sql主要的时间都花费在了sending data上了。其实这个也是正常的,Sending data 状态表示MySQL线程开始访问数据行并把结果返回给客户端,而不仅仅是返回个客户端。由于在Sending data状态下,MySQL线程往往需要做大量的磁盘读取操作,所以经常是整个查询中耗时最长的。
但既然在这里卡这,那就继续分析,下面是我从网上找到的关于sending data的分析
简单来说就是索引问题导致数据查起来很慢。
查看不同数据库中,temp表的索引,一个4条索引,一个1条索引。并且这时得知,两台服务器的配置也是不同的。
到这里其实破案了,mysql服务器配置较低,同时缺少索引,导致数据查询缓慢。
还有一些问题
一直在执行那些sql如何结束,是否对数据库有影响?
1.我询问了相关数据库人员,被告知在这个查询sql执行完毕前,temp表无法写入数据(加锁),但因为这边没有业务,因此影响不大。
2.sql结束应该是有一个最大执行时间,之后会被自动kill,但没得到具体值,各位有知道的可以留下评论。
mysql加索引后,改问题是否能解决
1.由于流程原因,领导正在考虑数据库使用分布式数据库,另外进行sql优化。所以目前还不得知。
这两天遇到一个sql语句编写的问题
假设有一张表,表示安保人员巡查楼的时间,每15分钟巡查,每次巡查会在表中记录一条数据。现在我们想查看某个安保人员一天的巡查记录,看他是否有漏掉没有巡检的时date_time
date_time | name |
2024-06-06 12:15:00 | apf |
2024-06-06 12:30:00 | xk |
2024-06-06 12:45:00 | apf |
2024-06-06 13:00:00 | apf |
如果直接查询,查到的只是某个人员当天的巡检记录,还需要自己补全没有巡检的时间节点。
其实很简单,有一个每天的时间节点表,然后做关联查询即可。因此想办法搞一个这个表出来就是最重要的。
--请注意,以下代码为金仓数据库sql,mysql和这个sql语法大差不差,去掉15的冒号即可。
with RECURSIVE time_series as (
select timestamp '2022-11-23 00:00:00' as date_time
union all
select date_time + interval '15' minute
from time_series
where date_time + interval '15' minute <= timestamp '2022-11-23 23:59:00'
)
select date_time
into TEMPORARY table temp_time_series
from time_series;
这里用到了循环CTE(公用表表达式),以及TEMPORARY关键字
TEMPORARY关键字表示新建的表只存在于本次会话中,只要关闭查询分析器该表就会消失。
另外这里的开始于结束时间可以通过查询具体的表,配合min()于max()函数实现更加精确的范围。
得到这个time_series表之后,进行关联查询即可。不多说了。
再见我要下班了
CET的相关问题可自行查阅
公用表表达式(CTE)详解:针对 MySQL 和 SQL Server 数据库_mysql cte-优快云博客
一篇文章成为递归大神:MySQL递归查询(with recursive)-优快云博客
后言
老人先发问:“你是警察吧?”我拍拍警徽:“货真价实高考考上的,四年毕业,科科成绩优秀。”老人又问:“警察来这山旮旯里干哪样?”我说:“搜寻失踪妇女,拯救家庭于水火。”
——《孔雀菩提》