mysql - 优化表后,Wordpress/MySQL (InnoDB) 表几乎瞬间碎片化?

标签 mysql database wordpress innodb

所以我最初运行 mysqltuner 并且它一直说(在全新的 Wordpress 安装上,使用 Percona InnoDB 和 Wordpress 帖子的随机虚拟数据)有碎片表。我不知道这是否是检查碎片表的正确方法:

SELECT TABLE_SCHEMA, TABLE_NAME, CONCAT(ROUND(data_length / ( 1024 * 1024 ), 2), 'MB')        DATA, CONCAT(ROUND(data_free / ( 1024 * 1024 ), 2), 'MB')FREE from information_schema.TABLES where TABLE_SCHEMA NOT IN ('information_schema','mysql') and Data_free > 0;

但那吐出:

+----------------+-------------+--------+--------+
| TABLE_SCHEMA   | TABLE_NAME  | DATA   | FREE   |
+----------------+-------------+--------+--------+
| db_wordpress   | wp_postmeta | 2.52MB | 4.00MB |
| db_wordpress   | wp_posts    | 1.52MB | 4.00MB |
+----------------+-------------+--------+--------+

所以我不确定这些表是否真的是零散的。我跑过:

ALTER TABLE wp_postmeta ENGINE='InnoDB';

哪种方法应该是“优化”InnoDB 表的正确方法?然后上面的查询显示:

+----------------+-------------+--------+--------+
| TABLE_SCHEMA   | TABLE_NAME  | DATA   | FREE   |
+----------------+-------------+--------+--------+
| db_wordpress   | wp_postmeta | 0.02MB | 4.00MB |
| db_wordpress   | wp_posts    | 1.52MB | 4.00MB |
+----------------+-------------+--------+--------+

现在,mysqltuner 仍然说那两个表是碎片化的,所以我尝试了:

OPTIMIZE TABLE wp_posts;

当运行上述查询时,然后将“数据”列放回原来的 2.52MB...

所以我不确定到底发生了什么?更不用说为什么表(特别是 wp_postswp_postmeta)会碎片化,因为我的理解是(主要是?)删除是碎片化的主要原因?如果它也是插入内容,那么在 Wordpress 中发布的几乎所有新帖子中我都会遇到碎片化问题吗?考虑到这似乎首先导致了表格碎片化?

无论哪种方式,我只是不确定上面的查询是否是检查碎片的正确查询,如果是这样,ALTER TABLE wp_postmeta ENGINE='InnoDB'OPTIMIZE TABLE wp_posts 是为优化表而运行的正确查询,如果是这样,为什么查询仍然显示为碎片?

编辑:

Percona 的配置向导给了我:

# MyISAM #
key-buffer-size                = 32M
myisam-recover                 = FORCE,BACKUP

# SAFETY #
max-allowed-packet             = 16M
max-connect-errors             = 1000000
skip-name-resolve
#sql-mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY # I disabled this due to problems with WP/Plugins
sysdate-is-now                 = 1
innodb                         = FORCE
#innodb-strict-mode             = 0 # I disabled this due to problems with WP/Plugins

# DATA STORAGE #
datadir                        = /var/lib/mysql/

# BINARY LOGGING #
log-bin                        = /var/lib/mysql/mysql-bin
expire-logs-days               = 14
sync-binlog                    = 1

# CACHES AND LIMITS #
tmp-table-size                 = 96M # I tweaked this due to mysqltuner recommendation
max-heap-table-size            = 96M # I tweaked this due to mysqltuner recommendation
query-cache-type               = 1 # I tweaked this due to mysqltuner recommendation
query-cache-size               = 96M # I tweaked this due to mysqltuner recommendation
max-connections                = 100
thread-cache-size              = 16
open-files-limit               = 65535
table-definition-cache         = 1024
table-open-cache               = 256

# INNODB #
innodb_stats_on_metadata = 0 # I added this when testing
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 2
innodb-log-file-size           = 64M
innodb-flush-log-at-trx-commit = 2
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 400

最佳答案

我猜您将所有表存储在中央表空间 ibdata1 中,因为当你这样做时,data_free对于所有 表,报告为整个ibdata1 中未使用的空间量。文件。

换句话说,比较data_lengthdata_free除非您使用 innodb_file_per_table=1,否则这不是一种非常有用的衡量碎片的方法.

ALTER TABLE wp_postmeta ENGIN=InnoDB确实会进行表重组并重建二级索引。页面填充得更好是有道理的,因此您的 2.52MB 被重写为 0.02MB(这可能是一个或两个 16KB 数据页面)。

在您使用的规模下,我根本不会担心碎片化。即使以碎片形式存储数据也只占用了 2.5 MB,因此您的缓冲池仍然只填充了一小部分。注意碎片的原因是当您试图扩展缓冲池以容纳更多数据时。对于您的情况,无论如何它都会适合。


关于您的评论和其他信息:

innodb-buffer-pool-size        = 400

这不是一个好的设置值。此变量的单位是字节,因此您请求了一个非常小的缓冲池。事实上,InnoDB 将忽略您的配置,而是使用 5MB 的最小值。如果您检查 MySQL 错误日志,您可能会看到:

[Note] InnoDB: Initializing buffer pool, size = 5.0M

这对于任何典型的生产网站来说都太小了。如果您想获得良好的性能,缓冲池的大小是一个至关重要的调整参数。缓冲池应该足够大以容纳您的工作集,即您的应用程序最常使用的数据页面。参见 MySQL Performance Blog's post "10 MySQL settings to tune after installation" .

也就是说,您的数据库可能非常小,目前 5.0MB 就足够了。但请记住,MySQL 5.6 中缓冲池的默认大小为 128MB。

你已经为你的键缓冲区分配了 32MB,它只用于 MyISAM 索引。 I recommend against using MyISAM在大多数情况下对于任何表。如果您没有 MyISAM 表,那么内存最好分配给您的 InnoDB 缓冲池。

您还为查询缓存分配了 96MB。查询缓存有一些缺点——取决于您网站的流量,它实际上弊大于利。除非你从中得到很多好处,否则我会禁用它(query_cache_type=0 query_cache_size=0),并将该 RAM 用于缓冲池。参见 MySQL Performance Blog's post "MySQL Query Cache"有关这方面的更多信息。


关于您的第二条评论:

不,innodb_buffer_pool_size 不是以 MB 为单位,而是以字节为单位。只有在数字后加上“M”后缀才能使其成为 MB。

The MySQL 5.6 manual on innodb_buffer_pool_size 说:

The size in bytes of the buffer pool, the memory area where InnoDB caches table and index data. The default value is 128MB.

我刚刚用 MySQL 5.5.36 测试了它——不是 Percona Server,只是普通的 MySQL 社区版。我确认当我设置 innodb_buffer_pool_size=400 ,我得到的是 5.0MB,这是记录的最小大小。

我还测试了 MySQL 5.1.70,当我将缓冲池大小设置为 400 时,我在错误日志中看到了这一点:

140203  9:46:20 [Warning] option 'innodb-buffer-pool-size': signed value 400 adjusted to 1048576
140203  9:46:20  InnoDB: Initializing buffer pool, size = 1.0M

MySQL 5.1 的最小缓冲池大小记录为 1.0MB。

关于mysql - 优化表后,Wordpress/MySQL (InnoDB) 表几乎瞬间碎片化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21516994/

相关文章:

mysql - 对许多传入文件建立索引

安卓 Realm .io : Row/Object is no longer valid

php - 按标题和分类术语检查帖子是否存在?

javascript - jQuery .click() 不会在特定元素上触发

mysql - 从代码中检索表名和列名

javascript - 更新到 WP 4.5 后,Wordpress 中的 Visual Composer 错误

mysql - SQL 计算 5 天的行数并添加到 count_concat

PHP 从数据库中以逗号分隔的字符串形式导出值

mysql - 语句检查日期时间是否在列中的两个日期时间之内

ruby-on-rails - rails 字段验证是否