0

所以,我正在使用 Wordpress、MySQL (8.0.16)、InnoDB。该wp_options表通常为 13 MB。问题是,它突然(至少在几天内)变成 27 GB,然后停止增长,因为没有更多可用空间。这 27 GB 被视为数据,而不是索引。

转储和导入表格会为您提供正常大小的表格。条目数约为 4k,自增索引为 200k+。对表进行碎片整理ALTER TABLE wp_options ENGINE = InnoDB;将磁盘上的表大小更改为正常,但即使在服务器重新启动后,mysql 也认为不同。

+------------+------------+
| Table      | Size in MB |
+------------+------------+
| wp_options |   26992.56 |
+------------+------------+
1 row in set (0.00 sec)

MySQL日志不多说:

2019-08-05T17:02:41.939945Z 1110933 [ERROR] [MY-012144] [InnoDB] posix_fallocate(): Failed to preallocate data for file ./XXX/wp_options.ibd, desired size 4194304 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/8.0/en/operating-system-error-codes.html
2019-08-05T17:02:41.941604Z 1110933 [Warning] [MY-012637] [InnoDB] 1048576 bytes should have been written. Only 774144 bytes written. Retrying for the remaining bytes.
2019-08-05T17:02:41.941639Z 1110933 [Warning] [MY-012638] [InnoDB] Retry attempts for writing partial data failed.
2019-08-05T17:02:41.941655Z 1110933 [ERROR] [MY-012639] [InnoDB] Write to file ./XXX/wp_options.ibd failed at offset 28917628928, 1048576 bytes should have been written, only 774144 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
2019-08-05T17:02:41.941673Z 1110933 [ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'

我的猜测是某些东西开始添加选项(可能是与瞬态相关的东西?)并且永远不会停止。

问题是,如何调试它?任何帮助/提示将不胜感激。

每小时进行一次 Cron 碎片整理看起来是一个非常糟糕的解决方案。

升级版:

1 天过去了,可用磁盘空间减少了 7 GB。当前的自动增量索引是 206975(昨天有 27 GB 空闲时是 202517)。所以 4.5K 条目 = 7 GB,我猜?

mysql> SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM information_schema.TABLES WHERE table_schema = 'XXX' AND table_name = 'wp_options';
+------------+------------+
| Table      | Size in MB |
+------------+------------+
| wp_options |    7085.52 |
+------------+------------+
1 row in set (0.00 sec)


mysql> select ENGINE, TABLE_NAME,Round( DATA_LENGTH/1024/1024) as data_length , round(INDEX_LENGTH/1024/1024) as index_length, round(DATA_FREE/ 1024/1024) as data_free from information_schema.tables  where  DATA_FREE > 0 and TABLE_NAME = "wp_options" limit 0, 10;
+--------+------------+-------------+--------------+-----------+
| ENGINE | TABLE_NAME | data_length | index_length | data_free |
+--------+------------+-------------+--------------+-----------+
| InnoDB | wp_options |        7085 |            0 |         5 |
+--------+------------+-------------+--------------+-----------+

我将监控可用空间如何减少的动态,也许这会对问题有更多的了解。

UPD(最终)

我有一种感觉,这很愚蠢,我是对的。里面有一个flush_rewrite_rules();不圣洁的东西functions.php。检查一般日志很有帮助。

4

5 回答 5

2

一种可能是您看到的有关表大小的统计信息不正确。

MySQL 8.0 尝试缓存有关表的统计信息,但在实现中似乎存在一些错误。有时它将表统计信息显示为 NULL,有时它显示值,但在您修改表数据时无法更新它们。

例如,请参阅https://bugs.mysql.com/bug.php?id=83957,这是一个讨论此缓存行为问题的错误。

您可以禁用缓存。它可能会导致对 INFORMATION_SCHEMA 或 SHOW TABLE STATUS 的查询稍微慢一些,但我想这并不比 MySQL 8.0 之前的版本差。

SET GLOBAL information_schema_stats_expiry = 0;

整数值是 MySQL 保持统计信息缓存的秒数。如果您查询表统计信息,您可能会看到缓存中的旧值,直到它们过期并且 MySQL 通过从存储引擎中读取来刷新它们。

缓存到期的默认值为 86400 或 24 小时。这似乎太过分了。

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_information_schema_stats_expiry

如果您认为 Wordpress 正在写入表格,那么它可能是。您可以启用二进制日志或查询日志来查找。或者只是观察SHOW PROCESSLIST几分钟。

您可能有一个经常更新或插入表格的 wordpress 插件。您可以查找最新的update_time:

SELECT * FROM INFORMATION_SCHEMA.TABLES
ORDER BY UPDATE_TIME DESC LIMIT 3;

观看此内容以了解最近写入的表。

此 UPDATE_TIME 统计信息有一些注意事项。它并不总是与更新表的查询同步,因为对表空间文件的写入是异步的。在这里阅读:https ://dev.mysql.com/doc/refman/8.0/en/tables-table.html

于 2019-08-06T21:00:58.570 回答
1

您是否有一个临时站点,并且问题是否在那里复制?如果是这样,请关闭暂存站点上的所有插件(只要关闭插件不会破坏您的站点)以查看问题是否停止。如果是这样,则一次再次打开它们以找出导致问题的插件。

如果您没有临时站点,那么您可以尝试在现场进行此操作,但请记住,您将弄乱您的现场功能(通常不推荐)。在这种情况下,只需删除您绝对不需要的插件,希望其中一个是罪魁祸首。如果可行,请一次添加一个,直到找到导致问题的插件。


我上面的建议假设插件导致了这个问题。开箱即用的 WordPress 不这样做(不是我听说过的)。可能有自定义编程执行此操作,但您需要让我们知道有关任何最近脚本的更多详细信息。

此时最大的问题是你不知道问题是什么。在你这样做之前,很难采取纠正措施。

于 2019-08-08T16:29:16.657 回答
1

一些插件无法自行清理。追查您添加的有关问题开始时间的插件。查看行中options是否有进一步暗示特定插件的线索。

不,没有什么是 MySQL 的统计数据等可以解释计算中出现 27GB 的“错误”。没有任何数量的OPTIMIZE TABLE, etc 将解决超过一小部分的问题。您需要删除大部分行。向我们展示一些最近的行(高AUTO_INCREMENTID)。

于 2019-08-08T21:49:57.700 回答
1

你试过慢日志吗?这可能会给您一些提示,所有查询的来源。

于 2019-08-13T11:02:29.363 回答
0

如果表有频繁的删除/更新/插入,可以运行 OPTIMIZE TABLE yourTable;

它需要在维护窗口中运行。

它将释放空间以供重用,但不会减少磁盘空间。

于 2019-08-08T19:09:34.427 回答