维基百科转储表pagelinks的问题

时间:2017-05-13 15:06:19

标签: mysql performance size wikipedia dump

我从enwiki-latest-pagelinks.sql.gz下载了dumps.wikimedia.org/enwiki/latest/转储。

我解压缩了文件,其未压缩的大小为37G。

表结构如下:

SHOW CREATE TABLE wp_dump.pagelinks;

CREATE TABLE `pagelinks` (
  `pl_from` int(8) unsigned NOT NULL DEFAULT '0',
  `pl_namespace` int(11) NOT NULL DEFAULT '0',
  `pl_title` varbinary(255) NOT NULL DEFAULT '',
  `pl_from_namespace` int(11) NOT NULL DEFAULT '0',
  UNIQUE KEY `pl_from` (`pl_from`,`pl_namespace`,`pl_title`),
  KEY `pl_namespace` (`pl_namespace`,`pl_title`,`pl_from`),
  KEY `pl_backlinks_namespace` (`pl_from_namespace`,`pl_namespace`,`pl_title`,`pl_from`)
) ENGINE=InnoDB DEFAULT CHARSET=binary

我将表导入了一个新的空数据库:

mysql -D wp_dump -u root -p < enwiki-latest-pagelinks.sql

我正在运行任务的计算机有16G的RAM,而mysql数据库位于SSD上,所以我假设尽管表的大小,导入也不会花太长时间。

但是,该任务已运行一天以上且仍在运行。没有其他进程访问mysql,并且计算机上没有工作负载。

数据库文件本身现在是79G大。

ls -lh

-rw-r----- 1 mysql mysql   65 May 11 17:40 db.opt
-rw-r----- 1 mysql mysql 8,6K May 12 07:06 pagelinks.frm
-rw-r----- 1 mysql mysql  79G May 13 16:59 pagelinks.ibd

该表现在有超过5亿行。

SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'wp_dump';

+------------+------------+
| table_name | table_rows |
+------------+------------+
| pagelinks  |  520919860 |
+------------+------------+

我想知道:

enwiki-latest-pagelinks.sql真的超过79G吗?

pagelinks真的包含超过5亿行吗?

导入pagelinks表确实需要很长时间吗?

您能提供预期的表格大小和行数量的指标吗?

更新:2017年5月14日:

insert仍然在运行; pagelinks.ibd文件现在130G;行数现在几乎是7亿

更新:2017年5月16日:

insert仍然在运行; pagelinks.ibd文件现在204G;行数现在超过12亿

我计算了过去两天每秒插入的行数:

rows / sek = 3236

并且:在sql脚本中每个insert语句有几千个插入(head -41 enwiki-latest-pagelinks.sql | tail -1 | grep -o "(" | wc -l是30471)

所以,我的后续/修改过的问题:

给定sql文件大小为37G和表结构(如上所列),是否需要行数和idb文件大小?

rows / sek = 3236是一个好的值(意味着插入表需要几天时间)?

可能限制速度因素/如何加快导入速度?

  • 禁用索引(并在插入后计算它们?)
  • 优化交易(提交(在脚本中没有设置)/ autocommit(现在开启))?
  • 优化变量设置(例如innodb_buffer_pool_size,现在是134217728)?

3 个答案:

答案 0 :(得分:3)

@Sim Betren:我当前正在导入同一个表,我可以获得大约7700行/秒。这意味着每天约600,000,000行。可能最重要的是在InnoDB上获得正确的设置:

https://dba.stackexchange.com/questions/83125/mysql-any-way-to-import-a-huge-32-gb-sql-dump-faster

innodb_buffer_pool_size = 4G
innodb_log_buffer_size = 256M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0

这些设置效果很好。根据我的阅读和尝试,InnoDB喜欢高内存设置。理想情况下,人们会使用16Gb甚至32Gb的机器,然后更多地增加这些设置。但是我在适度的设置上获得了7700行/秒,这已经快10年了:

  • Intel Q6700 quad
  • 8 Gb DDR2内存

我将这款具有10年历史的硬件与2017款500Gb SSD相结合,该型号专用于工作并处理读取和写入。使用旧硬件的原因是SSD是设置中最重要的部分(因为IOPS)。再加上使用旧硬件我节省了一些钱。但是,硬件仅限于8Gb的DDR2。我认为一台具有32Gb或64Gb内存的新型专用机器确实可以飞行。

软件设置:

  • Linux Mint 64bit
  • 适用于Ubuntu的MySQL Server 5.7.18
  • 用于导入的MySQL Workbench

我也在Windows 10上试过这个,两者的速度差不多。所以你也可以试试Windows。

注意:我确实尝试将引擎更改为MyISAM。 MyISAM可以非常快,大约8000行/秒或更多。但由于某种原因,导入总是被破坏了。所以我会坚持使用InnoDB

更新17-06-2017:

完成导入。表&#34; pagelinks&#34;大约214Gb,有1200万行。大约112Gb是原始数据,102Gb是索引。原始的未压缩文件大约是37Gb。

导入大约需要2天6小时。平均速度= 5350行/秒。使用高端设备(大容量内存,最好是64Gb或更高)和最佳设置,可以更快地完成。但我让它在一台专用机器上全天候运行而且我并不着急,所以2天似乎没问题。

更新18-06-2017:

还导入&#34; page.sql&#34;因为它包含连接到ID的名称。未压缩的文件大约是5Gb,导入需要1小时。这似乎很快:pagelink文件大约是37Gb,大于&#34; page.sql&#34;大7倍。然而,进口需要50倍的时间。因此,有几个原因可以解释为什么&#34; pagelinks&#34;花了这么长时间:(A)可能因为它不适合内存(B)表结构,每次插入很多数据(C)设置。但最有可能是它的记忆。

结论:尝试使用具有32Gb或64Gb内存的PC。也许更多。并使用可以跟上500Gb或更高内存的SSD。 SSD比内存更重要,所以先尝试一下。

答案 1 :(得分:1)

37GB的数据 - &gt; 79GB的InnoDB表似乎合理......

  • 标题:2个引号和1个逗号 - &gt;长度为1个字节
  • Ints:几个字节,加上逗号 - &gt; INT的4个字节(无论(...)之后的INT。请参阅MEDIUMINT
  • 每行20-30字节的开销
  • BTrees的开销为20-40%。
  • UNIQUE索引变为PRIMARY KEY,群集带有数据 - &gt;很少开销。
  • 其他两个索引:每个索引的大小与数据几乎相同。这样可以增加尺寸。

将它们全部加在一起,我希望表格超过120GB。所以,可能缺少一些细节。猜测:转储是每INSERT行一行,而不是每行INSERT那么冗长的多行。

至于表现,一切都取决于SELECTs。将innodb_buffer_pool_size设置为11G左右。这个可以有效地工作以缓存79G。

更多

为了清晰起见,将UNIQUE更改为PRIMARY,因为InnoDB确实需要PK。

检查源数据。是(pl_frompl_namespacepl_title)订单?如果没有,你可以在加载前对文件进行排序吗?如果可以,那么,单独一起,应该显着提高速度。

buffer_pool的128MB也严重阻碍了进展。

答案 2 :(得分:1)

@Sim Betren:

我想开一个全新的答案,因为我发现了一个新的解决方案。拆分文件可能是最好的答案。正如在另一个答案中所讨论的,当整个模型适合内存时,InnoDB效果最佳。当需要在磁盘上交换内容时,延迟开始。 pagelinks文件是37Gb,对于大多数机器而言,它太大了,无法轻松放入内存。也许一台价值1000美元以上的具有无限内存的专用机器可以做到这一点,大多数台式机都无法做到。那你可以做什么:

  • 计划是拆分文件。首先要做的是将SQL结构与数据分开。
  • 可能有更好的方法,但我发现的一个程序是这样的: SqlDumpSplitter2

  • 转储分割器程序可能很旧但它在页面链接上工作。它只是Windows。我只是告诉它将解压缩的37Gb文件分成37块1Gb并且尽职尽责。检查数据,它似乎工作。你也可以使用74块500Mb。

  • 每个文件的导入大约每1Gb需要10到20分钟。
  • 总时间:分割37Gb文件大约需要1到2个小时。进口约6至12小时。这很容易超过我之前给出的答案
  • 导入时,请使用与上一个答案相同的大数据设置。并尝试找到一台具有16Gb或32Gb大内存的机器。

这里最重要的是:分裂它并不重要。你可以随便拆分文件。然后通过分别重新创建结构和数据来构建它。这样导入可能会从2天减少到可能只有几个小时。如果有一台大型专用机器,它可能只需要1至6个小时即可完成。