排查数据库插入慢的问题

项目背景

我负责的模块是这个应用的一部分(在服务器A),但数据库(在服务器B,这个应用整体功能也在服务器B上),同库。主要是不影响这个应用的其他业务,而且分库分表维护起来,比较麻烦。

简单说就是我负责的模块,需要对远程服务器上的数据库特定的几张表,进行增删改查操作。

问题

上周还正常,这周一来了,插入删除数据的效率贼慢,能插入,就是时间太长了。

排查思路

  1. 排查服务器之间的网络问题;
  2. 排查数据库是否锁表;
  3. 检查数据库性能;

排查网络问题

检查两台服务器之间的网络是否通畅

检查两台服务器之间的网络是否通畅,可以通过以下步骤进行:

  1. 检查物理连接
    • 确保两台服务器的网线正确连接到交换机或路由器的可用端口。
    • 检查连接的物理状态,包括插头是否牢固、灯光指示是否正常等。
  1. 验证IP配置
    • 在两台服务器上分别运行网络配置查看命令(如Linux中的ifconfig或ip addr,Windows中的ipconfig),确保它们的网络接口配置正确。
    • 检查IP地址、子网掩码和网关设置,确保它们在同一子网内,且没有IP地址冲突。
  1. 检查防火墙设置
    • 检查两台服务器上的防火墙设置,确保它们允许ICMP协议(用于ping命令)和其他必要的网络协议通过。
    • 如果启用了防火墙,可以尝试暂时禁用防火墙进行测试,以排除防火墙导致的网络问题。
  1. 使用ping命令测试连通性
    • 在一台服务器上使用ping命令(如ping <另一台服务器的IP地址>)来测试与另一台服务器的连通性。
    • 如果能够收到回复,说明两台服务器之间的网络连接是通畅的。
  1. 使用traceroute或tracert命令检查路由
    • 在一台服务器上使用traceroute(Linux)或tracert(Windows)命令来查看数据包从源服务器到目标服务器的路由路径。
    • 这可以帮助你发现可能存在的网络故障点或延迟较高的节点。
  1. 测试特定端口的连通性
    • 如果需要测试特定应用层服务的连通性(如数据库、Web服务等),可以使用telnet或nc(netcat)命令来测试目标端口的可达性。
    • 在一台服务器上执行类似telnet <另一台服务器的IP地址> <端口号>的命令,如果连接成功,则说明该端口在两台服务器之间是通畅的。
  1. 检查网络设备和线路
    • 检查交换机、路由器等网络设备的状态和配置,确保它们正常运行且配置正确。
    • 使用网络线缆测试仪检查网络线路是否损坏或存在其他问题。

通过以上步骤,你应该能够较为全面地检查两台服务器之间的网络连通性。如果仍然存在问题,可能需要进一步深入排查网络配置、硬件故障或外部网络问题。

检查两台服务器之间的网速

  1. 使用ping命令(测试延迟)
    • 虽然ping命令主要用于测试网络连通性,但通过观察ping命令的响应时间(即延迟),也可以间接了解网络速度。较低的延迟通常意味着较好的网络性能。
  1. 使用traceroute命令(测试传输路径)
    • traceroute命令可以显示数据包从源服务器到目标服务器所经过的路由路径。通过分析这些路径中的节点和延迟,可以了解网络连接的效率。
  1. 使用iperf3工具(测试带宽)

iperf3 使用需要关闭防火墙。

iperf3 下载地址

CentOS 下载地址

ruby 复制代码
rpm -ih ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/updates/24/x86_64/i/iperf3-3.1.3-1.fc24.x86_64.rpm

Windows10 64位下载地址

网盘提取地址

下载到电脑到,并解压后,会得到两个文件:cygwin1.dll 和 iperf3.exe,将这两个文件拷贝到 c:\windows 目录下。

最后打开 cmd,执行 iperf3 --version ,若安装成功,会打印出版本信息。

iperf3 使用方法

在客户端和服务端分别安转 iperf3软件,先启动服务端,再启动客户端。

  • 服务端:收包,使用 -s 参数指定, iperf3 -s

  • 客户端:发包,使用 -c xx.xx.xx.xx 来指定要往哪个服务端发包, iperf3 -c 172.20.20.200

css 复制代码
iperf3 -c 172.20.20.200 -i 2 -u -b 100M -f m -t 4 --get-server-output
  • 第一列 Interval:测试的时长
  • 第二列 Transfer:在 Interval 时长里,传输的数据量
  • 第三列 BandWidth:带宽
  • 第四列 Jitter:网络抖动,连续发送数据包时延差值的平均值,越小说明网络质量越好
  • 第五列 Lost/Total Datagrams:丢失的数据包与发送的总数据包

我们可以看到 传输的数据量,1s 是10M,带宽 是100M/s,网速还是可以的。

排查数据库锁表

在 MySQL 中,你可以使用多种方法来查看表是否被锁定。以下是一些常用的方法:

  1. 使用 ****SHOW OPEN TABLES ****命令 :
    这个命令会显示所有打开的表,其中 In_use 列指示了哪些表正在被使用。
sql 复制代码
SHOW OPEN TABLES WHERE In_use > 0;

如果某个表的 In_use 值大于 0,那么它可能正在被锁定。但是,这并不能确切地告诉你表被哪种锁锁定(例如,读锁或写锁)。

  1. 使用 ****SHOW ENGINE INNODB STATUS ****命令 :

对于使用 InnoDB 存储引擎的表,你可以使用这个命令来获取详细的锁定信息。这个命令的输出包含了很多信息,其中 TRANSACTIONS 部分会显示当前活动的事务和它们持有的锁。

sql 复制代码
SHOW ENGINE INNODB STATUS\G

在输出中,查找 TRANSACTIONS 部分,并查看 LOCK WAIT 或 holding lock 等相关的行。

  1. 使用 ****information_schema ****数据库 :

information_schema 数据库包含了关于 MySQL 服务器元数据的表。你可以查询这些表来获取关于锁的信息。

例如,对于 InnoDB 表,你可以查询 INNODB_LOCKS 和 INNODB_LOCK_WAITS 表来获取锁的信息。

sql 复制代码
SELECT * FROM information_schema.INNODB_LOCKS;  
SELECT * FROM information_schema.INNODB_LOCK_WAITS;
  1. 使用性能模式 :
    如果你的 MySQL 服务器启用了性能模式(Performance Schema),你可以查询 performance_schema 数据库中的表来获取关于锁的信息。

例如,events_statements_history 和 events_waits_history_long 等表可能包含与锁定相关的信息。

  1. 第三方工具 :

除了上述的 SQL 命令外,还有一些第三方工具和图形界面(如 Percona Toolkit、MySQL Workbench 等)可以帮助你更直观地查看和管理 MySQL 的锁。

  1. 检查错误日志 :

如果表被锁定并导致超时或其他错误,这些信息可能会记录在 MySQL 的错误日志中。检查这些日志可能会提供有关锁定问题的线索。

请注意,不同的锁定类型(例如,共享锁、排他锁、元数据锁等)和存储引擎(如 InnoDB、MyISAM 等)可能会影响你如何查看和管理锁定。因此,在解决锁定问题时,了解你的数据库架构和使用的存储引擎是非常重要的。

检查数据库性能

不是网络,不是锁表的问题,那大概率就是数据库性能的问题。

我检查业务逻辑,对几张核心表进行排查了一下,有一张历史表的数据量在20w 左右,随着更长时间的运行,数据量也是越来越大的,而且对关键的id 有索引。

这就是我疑问的所在,就算拿1万条数据,与20万条数据比对,在有索引的情况,性能应该是不错的。

可事实就是贼慢。

分析了下业务逻辑,与业务老师商量,插入历史表这段逻辑,可以屏蔽。性能一下子提升了不少。

MySQL表中插入和删除操作性能低下可能由多种原因引起。对于拥有20万条记录的表来说,性能问题可能并不是特别显著,但如果你感觉性能明显慢于预期,以下是一些可能的原因和相应的解决策略:

  1. 硬件性能
    • 磁盘I/O:如果磁盘性能不佳(如使用传统的机械硬盘而非SSD),那么插入和删除操作可能会受到磁盘读写速度的限制。
    • CPU和内存:低性能的CPU或不足的内存也可能导致性能问题。
  1. 索引问题
    • 过多索引:每次插入或删除记录时,相关的索引都需要更新,过多的索引会拖慢这些操作。
    • 缺失索引:对于经常用于搜索、排序或连接的字段,如果没有适当的索引,那么查询性能会受到影响,间接导致插入和删除操作看起来更慢(因为它们可能需要更多的锁定和等待)。
  1. 表类型和设计
    • MyISAM vs InnoDB:MyISAM通常具有更快的插入和读取性能,但不支持事务和外键;而InnoDB则提供了事务支持、行级锁定等,但在某些情况下可能不如MyISAM快。
    • 表结构:过多的字段或字段类型选择不当也可能影响性能。
  1. 锁定机制
    • 表锁 vs 行锁:MyISAM使用表锁,而InnoDB使用行锁。在高并发环境下,表锁可能导致性能瓶颈。
    • 死锁:多个事务相互等待对方释放资源,导致死锁,这会严重影响性能。
  1. 数据库配置
    • 缓冲区大小:如InnoDB的缓冲池大小配置不当,可能导致性能问题。
    • 日志设置:二进制日志、慢查询日志等配置不当也可能影响性能。
  1. 查询优化
    • 复杂的触发器或外键约束:每次插入或删除记录时,相关的触发器或外键约束都需要执行,如果它们很复杂,会拖慢操作。
    • 大量数据的单次操作:一次性插入或删除大量数据会比分批操作更慢。
  1. 网络延迟:如果你是在远程连接数据库,网络延迟也可能是一个因素。

解决策略

  • 优化硬件:考虑升级磁盘、CPU或内存。
  • 审查和优化索引:删除不必要的索引,为经常查询的字段添加合适的索引。
  • 选择合适的表类型:基于你的需求选择合适的存储引擎。
  • 优化查询和事务:减少复杂查询和触发器,使用合适的事务隔离级别,避免长时间持有锁。
  • 调整数据库配置:根据硬件和工作负载调整缓冲区大小、日志设置等。
  • 分批处理:对于大量数据的插入或删除操作,考虑分批处理。
  • 监控和分析:使用MySQL的性能监控工具(如SHOW PROFILE, EXPLAIN, Performance Schema等)来分析和定位性能瓶颈。

最后,建议在进行任何优化操作之前备份数据库,并在测试环境中验证优化效果。

好了,以上就是全部内容了,如果对你有帮助,麻烦多多点赞,转发,收藏,就是对我最大的鼓励!

相关推荐
追逐时光者1 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
drebander2 小时前
MySQL 查询优化案例分享
数据库·mysql
初晴~2 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581362 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳2 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾2 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭3 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
小林coding4 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者4 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu