【问题标题】:Very slow migrations非常缓慢的迁移
【发布时间】:2017-11-17 10:50:48
【问题描述】:

我有一个(KVM)Debian 8 VM 服务器,它在本地运行 MySQL 5.5.58 和 PHP7.1 我有一台类似的机器(Vagrant VM、Debian 8、VirtualBox)。如果我将它们转储到 SQL 文件中并导入 SQL 文件,我的迁移在本地运行不到 20 秒,大约需要 2-3 秒。

但是,在 (KVM) Debian 8 虚拟机服务器迁移运行 10-20 分钟。我尝试增加 CPU 数量和 RAM 无济于事。

然而,有两件事可以极大地提高性能,但仍然不能真正使用:

  1. 将迁移文件转换为原始 SQL 并运行大约需要 20-50 秒。
  2. 设置innodb_flush_log_at_trx_commit=0 并运行迁移,这会将迁移运行时间减少到大约 4-5 分钟,但仍然无法使用。

my.cnf

[mysqld]
sync_binlog = 0
federated = 1
innodb_use_sys_malloc = 0
innodb_file_per_table = 1
innodb_stats_on_metadata = 0
innodb_buffer_pool_instances = 1
query_cache_type = 0
innodb_buffer_pool_size = 1G
innodb_log_file_size = 768M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address        = 127.0.0.1
key_buffer      = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
#max_connections        = 100
#table_cache            = 64
#thread_concurrency     = 10
query_cache_limit   = 1M
query_cache_size        = 16M

文件系统:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda         32G  6.0G   25G  20% /
udev             11M     0   11M   0% /dev
tmpfs           422M   17M  406M   4% /run
tmpfs           1.1G     0  1.1G   0% /dev/shm
tmpfs           5.3M     0  5.3M   0% /run/lock
tmpfs           1.1G     0  1.1G   0% /sys/fs/cgroup
tmpfs           211M     0  211M   0% /run/user/2031

我已测试和检查的内容:

  1. 确保我使用与本地 myqsl、php、composer 软件包相同版本的所有内容,这里没有差异。
  2. 测试了 VM 的磁盘 FIO 速度,以确保这里没有瓶颈尝试写入/读取单个大文件以及大量小文件获得全面的高速(磁盘是 SSD 并且健康)。
  3. 在迁移过程中添加了额外的内核并监控了 CPU 使用情况,它非常小。
  4. 定时执行来自Migrator 的 Laravel getUp 方法。特别定时从磁盘读取迁移文件,创建一个新类并执行查询似乎都在执行 used microtime(true)。
  5. 检查了 mysql 慢查询是否有任何慢查询,没有发现任何慢查询,迁移真的是非常基本的CREATE TABLE 语句。
  6. 尝试安装 MySQL 5.7 没有任何改进。
  7. 尝试增加 MySQL 池和日志 RAM 大小。
  8. 确保我使用的是 InnoDB。

注意:这发生在所有使用 MySQL 的方法中,我在主机上安装了 MySQL 进行测试。我安装了 docker mysql 同样的问题。我在同一个问题中安装了 vagrant instance 和 mysql 。

这个innodb_flush_log_at_trx_comit 似乎最有区别,表明我用 mysql 搞砸了一些东西,只是不知道为什么。 Migrations 每个都作为它自己的 transaction 运行,似乎有什么东西导致了这里的等待时间,不知道还有什么要检查的。

【问题讨论】:

  • 行是单独插入的吗?还是分批?差异是大约 10 的因子
  • 除非迁移产品有一些并行性,否则更多的 CPU不会有帮助。
  • 大多数 MySQL 性能问题无法通过硬件或调优来解决。让我们看看语句的示例。

标签: php mysql transactions database-migration query-performance


【解决方案1】:

您的原始 SQL 中很可能有一堆 INSERT 查询。

编辑 MySQLDump 生成的 SQL 确实有很多插入。填充测试 dbms 通常是从受版本控制的 SQL 文件完成的。 Here's some q&a about doing it in docker.

通过将START TRANSACTION; 放在开头和COMMIT; 放在最后,将每个系列的100 个左右的查询(实际数量并不重要)包装在事务中。这将摆脱自动提交带来的混乱。您将有一个如下所示的 SQL 文件:

START TRANSACTION;
INSERT ...;
... (more inserts)
INSERT ...;    
COMMIT;
START TRANSACTION;
INSERT ...;
... (more inserts)
INSERT ...;    
COMMIT;
START TRANSACTION;
INSERT ...;
... (more inserts)
INSERT ...;    
COMMIT;

避免使用 innodb 参数胡闹;默认值一般都很好,只需要在较大的动态负载下进行更改。

不要期望您的虚拟机性能与您的笔记本电脑一样好。服务器比笔记本电脑快的日子已经一去不复返了(对我们大多数人来说)。

【讨论】:

  • 但这并没有真正帮助我,因为我无法使用原始 sql 运行它违背了迁移的目的。默认参数几乎没有改进。 Vagrant 是我的本地虚拟机,运行没有任何问题。虚拟机的主机服务器比我的本地机器好得多,几乎是你可以获得的顶级规格硬件。我给了它更多的内存,没有任何区别。我不希望它以相同的方式执行,但通常为 10-20 分钟,而本地为 5-15 秒。 : /
  • 我已经按照您的建议进行了测试,并且导入时间大大增加了。
  • 更重要的是,每个INSERT 包含数十行还是数百行?
  • 没有最简单的CREATE TABLE 语句。
猜你喜欢
  • 2010-12-29
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 2014-11-07
相关资源
最近更新 更多