You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重装Ubuntu Server后Docker部署的MySQL 8.0.27性能骤降求助

排查与解决方案

一、存储层瓶颈排查

  • 检查存储介质:确认重装后是否更换了存储类型(比如从SSD换成HDD),HDD的随机写入性能远低于SSD,这是大表写入性能骤降的常见原因。用iostat -x 1查看磁盘%util指标,若持续接近100%,说明磁盘IO已饱和。
  • 检查Docker存储驱动与挂载参数:
    • 确认Docker使用的存储驱动(docker info | grep Storage Driver),优先使用overlay2,避免性能较差的devicemapper。
    • 检查数据卷挂载参数,确保添加了noatime(减少文件访问时间写入开销),挂载命令类似:docker run -v /host/path:/var/lib/mysql:rw,noatime ...
  • 检查文件系统:若使用XFS文件系统,确认是否开启了discard(TRIM支持,针对SSD),挂载时添加discard参数。

二、MySQL关键配置调整

针对1.6亿条数据的大表,重点优化InnoDB核心参数(修改my.cnf或Docker启动参数):

  • innodb_buffer_pool_size:设置为服务器物理内存的70%-80%(例如32G内存服务器设为24G),这是InnoDB性能的核心参数,用于缓存表数据和索引。
  • innodb_log_file_size:调整为1G-4G(默认可能仅48M),增大重做日志文件,减少频繁的checkpoint操作,提升写入性能。修改后需要删除旧日志文件并重启MySQL。
  • innodb_flush_log_at_trx_commit:若业务允许最终一致性,将其设为2(默认1是强一致性),降低事务日志刷盘频率。
  • innodb_write_io_threads/innodb_read_io_threads:调整为8或16,提升IO线程并发数。
  • 修正错误配置:sort_buffer_size=1G完全冗余(当前业务无排序操作),且该参数是每个连接分配,会导致内存耗尽,改回默认值(256K-1M即可);max_connections=1500若实际连接数远低于此,建议调至实际峰值的1.2倍即可。

三、表结构优化

  • 新增主键:当前表无显式主键,InnoDB会自动生成隐藏的6字节聚簇索引,严重影响大表写入性能。将唯一键address设为主键:
    ALTER TABLE addressList ADD PRIMARY KEY (address);
    
    (注意:大表执行此操作会锁表,建议在业务低峰期执行,或使用在线DDL工具)
  • 优化字段类型:
    • 将timestampReadable从varchar(32)改为datetime或timestamp,节省存储空间并提升查询/写入效率。
    • 确认showUpBlock是整数类型,当前为int足够(以太坊区块高度目前约2亿,int最大支持21亿,若后续超过可改为bigint)。
  • 清理冗余索引:若业务中未使用timestamp和firstTransactionHash的查询,可考虑删除对应的索引,减少写入时的索引维护开销。

四、写入逻辑优化

  • 批量插入替代单条插入:将程序中的循环单条INSERT改为批量插入,一次插入1000-5000条,大幅减少网络交互和事务开销,示例:
    INSERT INTO addressList (timestampReadable, timestamp, showUpBlock, firstTransactionHash, address)
    VALUES 
    ('2024-05-20 10:00:00', 1716189600, 20000000, '0x...', '0x...'),
    ('2024-05-20 10:00:01', 1716189601, 20000000, '0x...', '0x...'),
    ...;
    
    配合INSERT IGNORE或INSERT ... ON DUPLICATE KEY UPDATE address=address(忽略已存在的地址)。
  • 控制事务粒度:批量插入时手动开启事务,避免自动提交的频繁事务日志写入:
    const connection = await pool.getConnection();
    try {
      await connection.beginTransaction();
      // 执行批量插入
      await connection.query(batchInsertSql);
      await connection.commit();
    } catch (err) {
      await connection.rollback();
      throw err;
    } finally {
      connection.release();
    }
    

五、其他排查步骤

  • 更新表统计信息:重装后MySQL可能未自动更新大表的统计信息,导致执行计划异常,执行:
    ANALYZE TABLE addressList;
    
  • 检查MySQL错误日志:通过docker logs <mysql-container-name>查看是否有磁盘IO错误、内存不足等异常信息。
  • 验证程序端瓶颈:确认Web3.js获取交易的速度是否与之前一致,若交易获取变慢也会导致整体流程看似MySQL性能下降,可单独测试单条插入的耗时(排除网络或交易获取的影响)。

内容的提问来源于stack exchange,提问作者Pierogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:35:23