MySQL数据库服务器逐渐变慢 该怎么分析与解决

MySQL数据库服务器逐渐变慢 该怎么分析与解决,第1张

我们先来看第一个阶段,MySQL慢的诊断思路,一般我们会从三个方向来做:

第一个方向是MySQL内部的观测

第二个方向是外部资源的观测

第三个方向是外部需求的改造

11 MySQL 内部观测

我们来看MySQL内部的观测,常用的观测手段是这样的,从上往下看,第一部分是Processlist,看一下哪个SQL压力不太正常,第二步是explain,解释一下它的执行计划,第三步我们要做Profilling,如果这个SQL能再执行一次的话, 就做一个Profilling,然后高级的DBA会直接动用performance_schema ,MySQL 57 以后直接动用sys_schema,sys_schema是一个视图,里面有便捷的各类信息,帮助大家来诊断性能。再高级一点,我们会动用innodb_metrics进行一个对引擎的诊断。

除了这些手段以外,大家还提出了一些乱七八糟的手段,我就不列在这了,这些是常规的一个MySQL的内部的状态观测的思路。除了这些以外,MySQL还陆陆续续提供了一些暴露自己状态的方案,但是这些方案并没有在实践中形成套路,原因是学习成本比较高。

12 外部资源观测

外部资源观测这部分,我引用了一篇文章,这篇文章的二维码我贴在上面了。这篇文章是国外的一个神写的,标题是:60秒的快速巡检,我们来看一下它在60秒之内对服务器到底做了一个什么样的巡检。一共十条命令,这是前五条,我们一条一条来看。

1uptime,uptime告诉我们这个机器活了多久,以及它的平均的负载是多少。

2dmesg -T | tail,告诉我们系统日志里边有没有什么报错。

3vmstat 1,告诉我们虚拟内存的状态,页的换进换出有没有问题,swap有没有使用。

4 mpstat -P ALL,告诉我们CPU压力在各个核上是不是均匀的。

5pidstat 1,告诉我们各个进程的对资源的占用大概是什么样子。

我们来看一下后五条:

首先是iostat-xz 1,查看IO的问题,然后是free-m内存使用率,之后两个sar,按设备网卡设备的维度,看一下网络的消耗状态,以及总体看TCP的使用率和错误率是多少。最后一条命令top,看一下大概的进程和线程的问题。

这个就是对于外部资源的诊断,这十条命令揭示了应该去诊断哪些外部资源。

13 外部需求改造

第三个诊断思路是外部的需求改造,我在这里引用了一篇文档,这篇文档是MySQL的官方文档中的一章,这一章叫Examples of Common Queries,文档中介绍了常规的SQL怎么写, 给出了一些例子。文章的链接二维码在slide上。

我们来看一下它其中提到的一个例子。

它做的事情是从一个表里边去选取,这张表有三列,article、dealer、price,选取每个作者的最贵的商品列在结果集中,这是它的最原始的SQL,非常符合业务的写法,但是它是个关联子查询。

关联子查询成本是很贵的,所以上面的文档会教你快速地把它转成一个非关联子查询,大家可以看到中间的子查询和外边的查询之间是没有关联性的。

第三步,会教大家直接把子查询拿掉,然后转成这样一个SQL,这个就叫业务改造,前后三个SQL的成本都不一样,把关联子查询拆掉的成本,拆掉以后SQL会跑得非常好,但这个SQL已经不能良好表义了,只有在诊断到SQL成本比较高的情况下才建议大家使用这种方式。

为什么它能够把一个关联子查询拆掉呢?

这背后的原理是关系代数,所有的SQL都可以被表达成等价的关系代数式,关系代数式之间有等价关系,这个等价关系通过变换可以把关联子查询拆掉。

上面的这篇文档是一个大学的教材,它从头教了关于代数和SQL之间的关系。然后一步步推导怎么去简化这句SQL。

第一,MySQL本身提供了很多命令来观察MySQL自身的各类状态,大家从上往下检一般能检到SQL的问题或者服务器的问题。

第二,从服务器的角度,我们从巡检的脚本角度入手,服务器的资源就这几种,观测手法也就那么几种,我们把服务器的资源全部都观察一圈就可以了。

第三,如果实在搞不定,需求方一定要按照数据库容易接受的方式去写SQL,这个成本会下降的非常快,这个是常规的MySQL慢的诊断思路。

首先应该确定是谁慢的,往往是程序处理方面的问题而不是数据库的问题。

程序方面应该尽可能的减少数据查询返回的内容,减少IO压力,磁盘IO和网络IO是非常非常慢的。比如可以查询返回ID,然后再根据ID一条一条的查询具体内容,看似慢了,在数据量大的时候快很多

对于数据可以参照下面几点

1、优化SQL语句,SQL语句对查询速度影响最大的

2、对于经常查询的字段作索引。但是这样会增加修改时的压力

4、优化SQLServer,比如给其分配固定的内存,预先分配查询内存,调整CPU使用率等。SQL Server 可以占用几乎所有Windows的内存,但是申请内存开销很大。因此可以设定其使用固定大小内存,比如启动就分配1G以上内存。

5、优化硬件资源,比如使用更高的服务器或者硬盘,独立安排数据库的数据文件和索引文件,将数据文件分布于不同的物理硬盘上等等

6、考虑使用分布数据库或者对大表进行拆分

1、晚上是高峰期:晚上是很多网站、应用的高峰期,用户访问量比较大,服务器负载也就更大,容易造成数据库访问变慢。

2、系统资源不足:晚上可能有其他任务在占用服务器的资源,包括CPU、内存、硬盘等,对数据库性能产生影响。

3、数据库优化不充分:数据库的性能优化是一个长期的过程,如果没有做好索引优化、SQL语句优化等方面的工作,晚上时访问量增大时,自然会感觉到慢。

因为开机自启动程序过多、安全软件后台进行检测或升级数据库、病毒感染、硬盘碎片过多,长时间运行多个大型软件导致运行内存不足、使用迅雷全速下载等等都会导致速度慢。

解决方法:

1、检查应用软件或者驱动程序

有些程序在电脑系统启动会时使系统变慢。如果要是否是这方面的原因,我们可以从“安全模式”启动。因为这是原始启动,“安全模式”运行的要比正常运行时要慢。但是,如果你用“安全模式”启动发现电脑启动速度比正常启动时速度要快,那可能某个程序是导致系统启动速度变慢的原因。

2、桌面图标太多会惹祸

桌面上有太多图标也会降低系统启动速度。Windows每次启动并显示桌面时,都需要逐个查找桌面快捷方式的图标并加载它们,图标越多,所花费的时间当然就越多。建议大家将不常用的桌面图标放到一个专门的文件夹中或者干脆删除!

3、删除随机启动程序

可以使用金山毒霸的开机优化功能,一键提高开机速度。如果你的计算机感染了病毒,那么系统的运行速度会大幅度变慢。建议使用金山毒霸的快速查杀功能,一键查杀电脑病毒,提高电脑运行速度!

cpu高估计还是sql语句有问题,我也是新手,转帖一个给你参考参考

1-- 检查系统

sar -u 5 5

2-- 看谁在用CPU

topas

ps -ef |grep ora #检查第四列,C的大小(unit,100 per cpu)

3-- 检查CPU数量

/usr/sbin/bindprocessor -q

lsattr El proc0

4-- 2种可能:

1) A Background (instance) process

2) An oracle (user) process #此种可能最大。

5-- 如果是用户进程:那么高CPU的主要原因有:

Large Queries, Procedure compilation or execution, Space management and Sorting

51-- 查看每个Session的CPU利用情况:

select sssid,secommand,ssvalue CPU ,seusername,seprogram from v$sesstat ss, v$session se where ssstatistic# in (select statistic# from v$statname where name = 'CPU used by this session') and sesid=sssid and sssid>6 order by sssid;

52-- 比较上述Session,看那个session的CPU使用时间最多,然后查看该Session的具体情况:

select ssid, wevent, wwait_time, wseq#, qsql_text from v$session_wait w, v$session s, v$process p, v$sqlarea q where spaddr=paddr and ssid=&p and ssql_address=qaddress;

53-- 得到上述信息后,查看相应 *** 作是否有hash joins 和 full table scans。如果有hash joins 和 full table scans那么必须创建相应的Index或者检查Index是否有效。

另外必须检查是否有并行的查询存在和同一时刻有多个用户在执行相同的SQL语句,如果有必须关闭并行的查询和任何类型的并行提示(hints);如果查询使用intermedia数据,那么为了减少总的Index大小,必须限制使用Intermedia的Worldlist。(try restricting the wordlist that intermedia uses to help reduce the total indexsize)。

6-- 上述方案只能根据已经运行完成的 *** 作,对于正在执行的长时间 *** 作只能等 *** 作完成后才能检测得到。因此我们可以通过另外一个很好的工具来检测正在运行的长时间 *** 作语句。v$session_longops,这个视图显示那些 *** 作正在被运行,或者已经完成。每个process完成后会刷新本视图的信息。

7-- 怎样寻找集中使用CPU的Process:

很多时候会发现有N个Process在平均分享着CPU的利用率,这种情况唯一的可能性就是这些Process在执行着相同的Package或者Query

这种情况:建议通过statspack,在CPU高利用率额时候运行几个快照,然后根据这些快照检查Statspack报告,检查报告中最TOP的 Query。然后使用 sql_trace and tkprof 工具去跟踪一下。同时检查buffer cache 的命中率是否大雨95%。

同时在报告中还需要检查一下table scans (long tables),看是否在报告生成期间有存在全表扫描。

8-- 另外还有一些不是特别重要的,但是也必须关心检查的参数可能消耗CPU。

数据千万级别之多,占用的存储空间也比较大,可想而知它不会存储在一块连续的物理空间上,而是链式存储在多个碎片的物理空间上。可能对于长字符串的比较,就用更多的时间查找与比较,这就导致用更多的时间。

可以做表拆分,减少单表字段数量,优化表结构。

在保证主键有效的情况下,检查主键索引的字段顺序,使得查询语句中条件的字段顺序和主键索引的字段顺序保持一致。

主要两种拆分 垂直拆分,水平拆分。

垂直分表

也就是“大表拆小表”,基于列字段进行的。一般是表中的字段较多,将不常用的, 数据较大,长度较长(比如text类型字段)的拆分到“扩展表“。 一般是针对 那种 几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。

垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Product一个库,订单Order一个库。 切分后,要放在多个服务器上,而不是一个服务器上。为什么? 我们想象一下,一个购物网站对外提供服务,会有用户,商品,订单等的CRUD。没拆分之前, 全部都是落到单一的库上的,这会让数据库的单库处理能力成为瓶颈。按垂直分库后,如果还是放在一个数据库服务器上, 随着用户量增大,这会让单个数据库的处理能力成为瓶颈,还有单个服务器的磁盘空间,内存,tps等非常吃紧。 所以我们要拆分到多个服务器上,这样上面的问题都解决了,以后也不会面对单机资源问题。

数据库业务层面的拆分,和服务的“治理”,“降级”机制类似,也能对不同业务的数据分别的进行管理,维护,监控,扩展等。 数据库往往最容易成为应用系统的瓶颈,而数据库本身属于“有状态”的,相对于Web和应用服务器来讲,是比较难实现“横向扩展”的。 数据库的连接资源比较宝贵且单机处理能力也有限,在高并发场景下,垂直分库一定程度上能够突破IO、连接数及单机硬件资源的瓶颈。

水平分表

针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库 *** 作还是有IO瓶颈。不建议采用。

水平分库分表

将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。

水平分库分表切分规则

1 RANGE

从0到10000一个表,10001到20000一个表;

2 HASH取模

一个商场系统,一般都是将用户,订单作为主表,然后将和它们相关的作为附表,这样不会造成跨库事务之类的问题。 取用户id,然后hash取模,分配到不同的数据库上。

3 地理区域

比如按照华东,华南,华北这样来区分业务,七牛云应该就是如此。

4 时间

按照时间切分,就是将6个月前,甚至一年前的数据切出去放到另外的一张表,因为随着时间流逝,这些表的数据 被查询的概率变小,所以没必要和“热数据”放在一起,这个也是“冷热数据分离”。

分库分表后面临的问题

事务支持

分库分表后,就成了分布式事务了。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价; 如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

跨库join

只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。

跨节点的count,order by,group by以及聚合函数问题

这些是一类问题,因为它们都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作。解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

数据迁移,容量规划,扩容等问题

来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度。

ID问题

一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由

一些常见的主键生成策略

UUID

使用UUID作主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题。

Twitter的分布式自增ID算法Snowflake

在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位 机器ID 10位 毫秒内序列12位。

跨分片的排序分页

一般来讲,分页时需要按照指定字段进行排序。当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片,而当排序字段非分片字段的时候,情况就会变得比较复杂了。为了最终结果的准确性,我们需要在不同的分片节点中将数据进行排序并返回,并将不同分片返回的结果集进行汇总和再次排序,最后再返回给用户。

一,硬盘IO的延时

对于SQL Server数据库系统,限制查询响应的主要因素是硬盘的延时,根据硬盘的物理构造(磁道和扇区),延时可以分为寻道延时和旋转延时:

寻道延时:硬盘的物理刺头移动并定位到所需数据的时间,

旋转延时:硬盘旋转到所需数据的时间,通常用MB/S,或IO吞吐量来衡量

在OLTP系统中,数据更新 *** 作较多,每次读取的数据量少,目标数据的位置相对随机(随机读写),因此,对于寻道延时要求更高,硬盘需要花费更多的寻道时间。

在DSS/DW系统中,事务的运行时间更长,数据相对静态,不常更新,读 *** 作比写 *** 作的要求更高,顺序读 *** 作占比很高,因此,IO吞吐量更重要,可以通过硬盘的盘面来增加顺序访问的IO吞吐量。

二,根据WaitType侦测IO性能

SQL Server引擎把IO作为一个资源来看待,在多任务的现代数据库系统中,同一时刻会接收到很多查询请求,每一个查询请求都需要申请系统资源(CPU、内存和IO),才能继续执行下去,然而系统的资源是有限的,当查询争用资源时,有些查询请求资源得到满足,顺利执行下去,有些查询请求的资源得不到满足,该查询就被阻塞,处于等待资源分配的状态。当出现IO性能问题时,查询语句会被硬盘IO阻塞,这使得执行计划被迫挂起(或阻塞)来等待资源,SQL Server通过DMV来显示系统运行的状态,用等待类型来表示不同的阻塞信息。

1,数据文件的IO

如果SQL Server 出现 IO 性能问题,那么在SQL Server 内部通过DMV sysdm_exec_requests的wait_type,来反馈 IO 问题。如果查询请求的wait_type长时间处于PageIOLatch_XX,那么说明系统不能很快把数据读取到内存中。

PAGEIOLATCH_xx :用于描述数据页的IO争用,说明系统正在从硬盘加载数据到内存的Buffer Pool中

当SQL Server 要去读或写一个Page的时候,首先会在Buffer Pool里寻找,如果在Buffer Pool中找到了,那么读写 *** 作会继续进行,没有任何等待。如果没有找到,那么SQL Server 就会设置Wait_Type为PageIOLatch_EX(写)或PageIOLatch_SH(读),然后发起一个异步IO *** 作,将页面读入Buffer Pool中,在IO没有完成之前,Request将会保持在PageIOLatch_EX(写)或PageIOLatch_SH(读)的等待状态。IO消耗的时间越长,等待的时间越长。

2,日志文件的写入

日志文件以写为主,工作量由修改命令激发的事务数量决定。当SQL Server要写事务到日志文件时,如果Disk 不能及时完成IO请求,那么事务就无法提交,SQL Server 不得不进入WriteLog 等待状态,直到事务被成功记录到日志文件中,才会提交当前的事务。

如果request经常出现WriteLog的Wait type,说明事务日志的写请求不能被Disk及时完成,这种情况,对SQL Server 整体性能影响较大。

WRITELOG:在数据被修改时,在Log Cache和Buffer Cache中都会有记录,如果在Log Cache中的数据在checkpoint时写入硬盘,就会发生这种等待。

LOGBUFFER等待:很少出现,当一个任务正在等待存储日志到Log Buffer中时,就会出现LOGBUFFER等待,出现这种等待,说明日志所在的硬盘无法响应请求。如果把日志文件放在一个非常慢的硬盘上,而数据文件放在一个非常快的硬盘上,就会出现这种等待。

3,AYSNC_IO_COMPLIETION和IO_COMPLIETION也是IO瓶颈的潜在指标

AYSNC_IO_COMPLIETION:标识任务正在等待IO请求来完成 *** 作,当一个应用程序连接SQL Server,在处理数据时变得非常慢,很可能就会出现这种类型的等待。

IO_COMPLIETION:发生在一个任务正在等待用于非数据页IO的IO *** 作上,非数据页,一般是指日志文件,通常发生在修改大量修改,或者内存中存在大量的脏数据时。

三,影响读写性能的因素

数据库系统对IO的性能依赖较高,那么影响数据库系统读写性能的因素有哪些呢?

1,物理硬盘的IO能力

机械硬盘的IO速度没有固态硬盘快,可以考虑把数据库系统的机械硬盘更新为固态硬盘。

2,内存对硬盘IO的影响

在SQL Server Engine 访问数据时,如果相应的data不存在于Buffer Pool,那么Buffer Manager 从Disk中的Data File(mdf 或 ndf)中将相应的data page读取到内存中。SQL Server 将data page缓存起来。理想情况下,只要SQL Server能够使用的内存充足,SQL Server 会将所有读取到内存的中Data Page缓存到Buffer Pool中。对于读取 *** 作,只要相应的数据都缓存在内存中,Select 就不会有任何硬盘IO。

当Buffer Pool空间不足时,SQL Server 激活 LazyWriter,主动将内存中一些很久没有使用的Data Cache和 Plan Cache 清除,mark为Free buffer,供其它Data Page使用。如果这些Page上的修改还没有被CheckPoint写回Disk,那么LazyWrite会将其写回。

3,碎片和压缩

如果数据页面或index 页面的碎片很多,每个页面存储的数据行较少,那么SQL Server 需要读写更多的Page。如果数据在页面里存储的非常紧凑,存储相同数据所消耗的Page越少,并且可以充分利用SQL Server 预读的优势,减少IO。

压缩技术不仅使数据占用的Disk 空间减少,而且能够减少IO。由于数据在写入Disk之间经过压缩处理,存储相同数据所消耗的Page减少,读取的Data Page会减少。压缩技术在一定程度上能够降低IO,但需要付出一定的代价:额外消耗少量的CPU和内存来解压缩。

4,利用多个物理硬盘实现Data File的并发读写

在DB中的FileGroup 创建多个File,将这些File存放到不同的Physical Disk上。File 分布到不同的Physical Disk上,IO也会分布到不同的Physical Disk上,这样能够实现数据的并发读取,提高读取性能。

对于日志文件,SQL Server会频繁的写事务日志。只要数据库发生修改,就会不断地写入日志文件。如果不能及时完成日志文件的IO,会导致事务的延迟提交,对性能的影响较大,所以,尽量将日志文件放到写入速度快的Disk上。SQL Server 顺序写事务日志,在一个时间点,SQL Server 只会写一个日志文件。在不同的Physical Disk上创建多个log file对性能基本没有帮助。

5,工作负载

日志文件以写为主,工作量由修改命令申请的事务数量决定,日志文件是顺序写的,写入速度快于随机写。如果日志记录不能及时写入,那么Request会处于WriteLog等待状态,对系统整体性能影响较大。

数据文件写入的数据量由修改量决定,SQL Server除了设置bulk logged 恢复模式之外,没有太大的调整选项。

数据文件读取的数据量,由访问的数据量和Buffer Pool中缓存的数据量共同决定。如果访问的数据量减少或者内存缓存区增加,都可以降低SQL Server 从Physical Disk读取的Data Page数量。在内存不变的情况下,可以通过优化查询语句,减少数据访问量,来提高SQL Server 数据文件的读取性能。

db2装数慢的原因:

CM包含两数据库:库服务器ICMNLSDB资源管理器RMDB,应用数据库有BBKP,其中was和RMDB数据库安装和存储在一台服务器,应用数据库BBKP和ICMNLSDB数据库在另外一台数据库上。

在测试过程中,发现只要是和CM数据库有关的网页链接访问都特别慢,在利用windows自带的perfmon性能工具查看磁盘IO时,ICMNLSDB所在的那个盘IO特别高。再利用FileMon工具查看时,发现系统访问ICMNLSDB数据库对应的表空间ICMLFQ32所在的目录很频繁,因此推测可能是这个导致磁盘IO吃紧。既然找出问题所在,接下来就是解决问题了。推测可能是表空间CIMLFQ32容量不够,但在为表空间添加容量时,系统却出现由于是系统管理的表空间,不允许更改添加表空间。而通过网上搜索,得出系统管理的表空间不受页大小的影响,和磁盘的容量有关。但本地的磁盘空间还有19G多,因此无奈只好修改表空间关联到缓冲池,通过将缓冲池设大。

以上就是关于MySQL数据库服务器逐渐变慢 该怎么分析与解决全部的内容,包括:MySQL数据库服务器逐渐变慢 该怎么分析与解决、为什么 sqlserver 慢、阿里云数据库晚上慢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9348843.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存