背景: 我有一个网站,正在从独立的 MariaDB 服务器迁移到 MariaDB galera 集群。其中一部分是我将表从大量 MyISAM 转换为 InnoDB。值得一提的是,该网站是一个大型 joomla 安装。
网站的前端运行良好。没有问题。管理部分保存任何内容的速度非常慢 - 从您点击保存到完成需要 25-30 秒。
设置 3 节点 galera 设置 - 12 核 Intel(R) Xeon(R) CPU E5-1650 v4 @ 3.60GHz 64GB w SSD 上 Raid
HA 代理用于负载平衡
/etc/my.cnf
[mysqld]
innodb_buffer_pool_siz=32Gb
innodb_log_file_size = 2Gb
innodb_flush_method=O_DIRECT
max_connections=750
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=2Mb
query_cache_size=0
skip_name_resolve
sync-binlog=0
目前,我只连接了一个开发站点,因此我可以可靠地测量正在发生的事情。以下是我在执行单个保存时注意到的等待时间:
保存之前:
MariaDB [(none)]> show global status like "%waits%";
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_log_waits | 0 |
| Innodb_mutex_os_waits | 4 |
| Innodb_mutex_spin_waits | 4 |
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_waits | 0 |
| Innodb_s_lock_os_waits | 9 |
| Innodb_s_lock_spin_waits | 11 |
| Innodb_x_lock_os_waits | 1 |
| Innodb_x_lock_spin_waits | 0 |
| Tc_log_page_waits | 0 |
+-------------------------------+-------+
10 rows in set (0.01 sec)
保存后:
MariaDB [(none)]> show global status like "%waits%";
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_log_waits | 0 |
| Innodb_mutex_os_waits | 177 |
| Innodb_mutex_spin_waits | 1580 |
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_waits | 0 |
| Innodb_s_lock_os_waits | 164 |
| Innodb_s_lock_spin_waits | 687 |
| Innodb_x_lock_os_waits | 656 |
| Innodb_x_lock_spin_waits | 905 |
| Tc_log_page_waits | 0 |
+-------------------------------+-------+
我知道 innodb 比 myisam 的开销更大,但我认为禁用 sync-binlog 并将 innodb_flush_log_at_trx_commit 设置为 2 会有所帮助,但我实际看到的是写入性能下降了约 1000%。
只是想找一些关于要检查什么、可能出错的指导。我不确定应用程序中的单个保存中 os_waits 计数是否很高,在我看来似乎是这样的,但我不太清楚是什么原因造成的,也不知道该如何修复它。
将慢查询日志设置为 2 秒后,这是它在尝试保存时捕获的唯一内容:
# Time: 180126 18:03:38
# User@Host: dev[dev] @ [192.168.10.200]
# Thread_id: 136 Schema: dev QC_hit: No
# Query_time: 6.306918 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 109438
# Rows_affected: 82677
use dev;
SET timestamp=1517007818;
UPDATE jos_assets
SET lft = lft + 2
WHERE lft > 337711;
# Time: 180126 18:03:48
# User@Host: dev[dev] @ [192.168.10.200]
# Thread_id: 136 Schema: dev QC_hit: No
# Query_time: 9.985669 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 109438
# Rows_affected: 82683
SET timestamp=1517007828;
UPDATE jos_assets
SET rgt = rgt + 2
WHERE rgt >= 337711;
提前谢谢。
答案1
这个问题原来是 Joomla 特有的,与 _assets 表的低效性有关。我想我应该早点检查慢查询日志,但正如您在原始帖子中看到的那样,在发布新文章时,有 2 个查询在一次“保存”中更新了表,导致 82677 行被更新。即使在最快的部署中,这也需要时间。
我不太清楚为什么 Joomla 每次保存帖子时都需要这样做,但一些研究表明,删除该表中的所有文章相关条目是安全的,这样总行数就减少到大约 4000 行。现在快多了。
作为参考,如果您的 Joomla 网站在转换为 Innodb 后速度很慢,这是我在资产表上找到一些信息的页面: