【问题标题】:Creating a large MySQL index (1B rows) fails with "Lost connection to MySQL server during query"创建大型 MySQL 索引(1B 行)失败并显示“在查询期间丢失与 MySQL 服务器的连接”
【发布时间】:2014-02-17 16:58:24
【问题描述】:

我正在尝试在一个相当大的 MySQL 表(超过 10 亿行,144GB)上创建一个复合索引。

ALTER TABLE table_name ADD INDEX id_date ( id, `date` );

我让它在一夜之间运行了几次,但它一直失败并显示以下消息(错误日志中没有其他内容。)我无法确定查询运行了多长时间,但可能持续了大约八小时。

ERROR 2013 (HY000) at line 3: Lost connection to MySQL server during query

我用SET expand_fast_index_creation=ON; 尝试过,但这似乎只是让它更快地失败(也许一个小时。)

服务器在 Hetzner 的专用 Ubuntu 机器上运行,具有 32G RAM、4GB 交换空间和 8 个内核。大量可用磁盘空间(1TB 磁盘。)

Server version: 5.6.13-rc61.0-log Percona Server (GPL), Release 61.0

这是 my.cnf 文件,主要是反复试验的结果:

[mysqld]
# General
binlog_cache_size = 8M
binlog_format = row
character-set-server = utf8
connect_timeout = 10
datadir = /var/lib/mysql/data
delay_key_write = OFF
expire_logs_days = 10
join_buffer_size = 8M
log-bin=/var/lib/mysql/logs/mysql-bin
log_warnings = 2
max_allowed_packet = 100M
max_binlog_size = 1024M
max_connect_errors = 20
max_connections = 512
max_heap_table_size = 64M
net_read_timeout = 600
net_write_timeout = 600
query_cache_limit = 8M
query_cache_size = 128M
server-id = 1
skip_name_resolve
slave_net_timeout = 60
thread_cache_size = 8
thread_concurrency = 24
tmpdir = /var/tmp
tmp_table_size = 64M
transaction_isolation = READ-COMMITTED
wait_timeout = 57600
net_buffer_length = 1M

# MyISAM
bulk_insert_buffer_size = 64M
key_buffer_size = 384M
myisam_recover_options = BACKUP,FORCE
myisam_sort_buffer_size = 128M

# InnoDB
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 25G
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
#innodb_lazy_drop_table = 1
innodb_log_buffer_size = 16M
innodb_log_files_in_group = 3
innodb_log_file_size = 1024M
innodb_max_dirty_pages_pct = 90
innodb_locks_unsafe_for_binlog = 1

[client]
default-character-set = utf8

[mysqldump]
max_allowed_packet = 16M

任何线索将不胜感激!

【问题讨论】:

  • 如何减少行数...大声笑,MySQL 中有 10 亿行?
  • 可能需要进行重组,但到目前为止 MySQL 表现良好。查询始终失败,这让我相信配置更改可能能够解决手头的问题。我将研究分区。
  • 您认为 16 小时后它可能会失败吗?您的 wait_timeout 设置为 16 小时(57600 秒)。
  • @BrentBaisley 实际上我在发现默认值为 8 小时后添加了该值。从那以后,我没有在没有“expand_fast_index_creation”的情况下尝试过(大约一个小时后失败。)我目前正在将数据迁移到带有新索引的分区表中,该索引似乎进展顺利。希望这能为我解决这个问题。

标签: mysql database


【解决方案1】:

作为一种解决方法,我建议创建一个像旧表一样的新表,添加索引,插入旧表中的数据(可能是合理的分块),然后切换到新表。在你的情况下,检查你想为你的数据使用哪个存储引擎听起来是个好主意——如果你有想要处理的原始数据,也许“ARCHIVE”可能是你的选择。或者,如果您的数据中保存有任何类型的结构/“关系”信息,请尝试规范化您的数据模型并缩小相关表的大小。

【讨论】:

  • 我还没有对“INSERT..SELECT”有太多的运气,我正在再次尝试将“innodb_lock_wait_timeout”设置为更高的值。数据是关系型的,但重要的查询只在一张表上运行。你对如何处理分块有什么建议吗?
  • 块成功了,我的配置的上限似乎是一次大约 100MM 行。每个查询大约需要 2 个小时。 "INSERT INTO new_table SELECT * FROM old_table LIMIT 0, 99999999;"
猜你喜欢
  • 1970-01-01
  • 2012-11-15
  • 2020-07-11
  • 2015-09-22
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
相关资源
最近更新 更多