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

排查MariaDB Galera Cluster与Apache Fetch语句的延迟问题

MariaDB Galera集群实时查询延迟随时间升高问题排查

近期将MariaDB Galera集群接入实时系统后,出现网站打开时间越久,数据库Fetch调用延迟越高的问题。具体表现为:查询初始延迟约20ms,20分钟后延迟升至200ms;由于用户可能连续数小时打开网站,且每秒执行一次Fetch请求,当延迟超过1秒时会引发内存泄漏。

补充背景:

  • 该查询返回约50列数据,网站加载时会清空表,表数据量不大
  • 此前使用单节点数据库无此问题,已确认所有程序连接同一集群节点
  • 集群与网站工作站在同一网络,未经过流量管理器,节点间通过10GB交换机连接,同步速度快
  • 开发PC上单节点MariaDB+Apache无延迟升高情况,测试时仅打开一个标签页,数据库未遭遇大量连接/重连请求(计划用Memcache优化)

代码示例

PHP查询语句

<?php       
//echo 'before'.utime(true); 
$dbquery= "SELECT * FROM `MyTable` WHERE Column = '$value' ORDER BY Id DESC LIMIT 1";
$result = $db->prepare($dbquery);
$result->execute();
$myResults = $result->fetchAll();
//echo 'after:'.utime(true);

echo json_encode($myResults);
?>

JavaScript定时调用代码

//javascript
this.ahaTimeout = setTimeout(() => {
   this.ahaInterval = setInterval(tmpFunction => {
    fetch("myDBcall.php", {
          method: 'post',
          headers: {
            "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
          }
        }).then(response => response.json()).then(data => {
    //do stuff

   }, 1000)
}, 1000 - new Date().getMilliseconds());

集群配置文件

my.cnf

[client-server]
 !includedir /etc/my.cnf.d
[mysqld]
query_cache_type=0
query_cache_size=0
max_allowed_packet=768M

server.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
bind-address=<nodeIPaddress>
user=mysql

innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=128M

log-error=/var/log/mysqld/log
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so

wsrep_node_name='mynode'
wsrep_node_incoming_address='<nodeIPaddress>'
wsrep_node_address='<10GBnetworkIPaddress>'

wsrep_cluster_name='myCluster'
wsrep_cluster_address="gcommm://<10GBnode1IP>:4567,<10GBnode2IP>:4567,<10GBnode3IP>:4567"

wsrep_provider_options='gcache.size=300M;gcache.page_size=300M;gcs.max_packet_size=1024000'
wsrep_slave_threads=4
wsrep_sst_method=rsync

排查思路与解决方案

数据库层面排查

  • 调整InnoDB缓冲池:当前innodb_buffer_pool_size=128M过小,频繁查询易导致缓存命中率下降、磁盘IO升高。建议根据服务器内存调整(如8核16G服务器可设为12G)。
  • 监控Galera集群状态:执行SHOW STATUS LIKE 'wsrep_%';,重点关注wsrep_flow_control_paused(是否触发流控)、wsrep_local_recv_queue_avg(接收队列平均长度),排查节点同步延迟是否拖慢查询。
  • 开启慢查询日志:在my.cnf中添加配置:
    slow_query_log=1
    slow_query_log_file=/var/log/mysql/slow.log
    long_query_time=0.05
    
    记录慢查询,确认是否存在执行计划随时间变化的情况。
  • 检查连接与锁状态:执行SHOW PROCESSLIST;,查看是否有未释放的连接或锁等待,排查Galera下隐式事务未提交的可能。

应用层面优化

  • 修复SQL注入与执行计划缓存:当前PHP代码直接拼接$value存在注入风险,且未正确使用参数绑定,改为:
    $dbquery= "SELECT * FROM `MyTable` WHERE Column = ? ORDER BY Id DESC LIMIT 1";
    $result = $db->prepare($dbquery);
    $result->execute([$value]);
    
    参数绑定可让数据库缓存执行计划,避免重复解析SQL。
  • 优化查询与索引:避免SELECT *,只查询需要的列;创建联合索引CREATE INDEX idx_column_id ON MyTable(Column, Id DESC);,提升查询效率。
  • 启用持久化连接:PHP使用PDO时添加PDO::ATTR_PERSISTENT => true配置,复用数据库连接,减少连接建立开销。
  • 调整前端轮询策略:每秒一次Fetch过于频繁,可根据业务需求延长间隔,或改用WebSocket推送替代轮询,降低服务器与数据库压力。

系统层面排查

  • 监控磁盘IO:用iostat或iotop查看磁盘读写情况,确认是否因磁盘性能瓶颈导致延迟升高。
  • 检查内存与Swap:执行free -m,确认是否存在内存不足触发Swap的情况,Swap会严重拖慢数据库性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:52:04