排查数据库插入慢的问题

2024年 3月 14日 72.4k 0

项目背景

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

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

问题

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

排查思路

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

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

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

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

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

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

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

    iperf3 下载地址

    CentOS 下载地址

    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

    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 中,你可以使用多种方法来查看表是否被锁定。以下是一些常用的方法:

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

    如果某个表的 In_use 值大于 0,那么它可能正在被锁定。但是,这并不能确切地告诉你表被哪种锁锁定(例如,读锁或写锁)。
    2. 使用 ****SHOW ENGINE INNODB STATUS ****命令:
    对于使用 InnoDB 存储引擎的表,你可以使用这个命令来获取详细的锁定信息。这个命令的输出包含了很多信息,其中 TRANSACTIONS 部分会显示当前活动的事务和它们持有的锁。

    SHOW ENGINE INNODB STATUSG
    

    在输出中,查找 TRANSACTIONS 部分,并查看 LOCK WAIT 或 holding lock 等相关的行。
    3. 使用 ****information_schema ****数据库:
    information_schema 数据库包含了关于 MySQL 服务器元数据的表。你可以查询这些表来获取关于锁的信息。

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

    SELECT * FROM information_schema.INNODB_LOCKS;  
    SELECT * FROM information_schema.INNODB_LOCK_WAITS;
    
  • 使用性能模式:
    如果你的 MySQL 服务器启用了性能模式(Performance Schema),你可以查询 performance_schema 数据库中的表来获取关于锁的信息。
  • 例如,events_statements_history 和 events_waits_history_long 等表可能包含与锁定相关的信息。
    5. 第三方工具:
    除了上述的 SQL 命令外,还有一些第三方工具和图形界面(如 Percona Toolkit、MySQL Workbench 等)可以帮助你更直观地查看和管理 MySQL 的锁。
    6. 检查错误日志:
    如果表被锁定并导致超时或其他错误,这些信息可能会记录在 MySQL 的错误日志中。检查这些日志可能会提供有关锁定问题的线索。

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

    检查数据库性能

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

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

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

    可事实就是贼慢。

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

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

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

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

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

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

    相关文章

    Oracle如何使用授予和撤销权限的语法和示例
    Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
    下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
    社区版oceanbase安装
    Oracle 导出CSV工具-sqluldr2
    ETL数据集成丨快速将MySQL数据迁移至Doris数据库

    发布评论