草庐IT

mysql - 限制 ALTER TABLE 磁盘利用率

coder 2023-06-12 原文

我将从 MySQL Online DDL Limitations 中的一些内容开始。页面:

There is no mechanism to pause an online DDL operation or to throttle I/O or CPU usage for an online DDL operation.

但是,我仍然对可能错过的解决方案感兴趣。

情况:索引越来越大,而且它们变得越来越大,以至于没有足够的内存来处理所使用的查询,导致磁盘 I/O 猛增,一切都陷入困惑.已创建较小的新复合索引,但问题是运行 ALTER TABLE 而不破坏任何内容。

事实如下:

  1. 这是一个 InnoDB 表。
  2. 该表没有主键或唯一索引。
  3. 任何列组合都不适合用作主键或唯一索引。
  4. 该表没有外键。
  5. 该表每月分区(当前为 50 个)。
  6. 该表必须始终接受写入。
  7. 最新的 3-6 个分区必须接受读取。
  8. 有一个 id 列,但这不是唯一的。
  9. 该表包含大约 20 亿行。
  10. 当月的分区是唯一接收写入的分区。
  11. 提前 1 个月进行分区;总是有一个空分区。

SHOW CREATE TABLE(我没有包括所有分区):

CREATE TABLE `my_wonky_table` (
  `id` bigint(20) unsigned NOT NULL,
  `login` varchar(127) DEFAULT NULL,
  `timestamp` int(10) unsigned NOT NULL,
  `ip` varchar(32) CHARACTER SET ascii DEFAULT NULL,
  `val_1` int(10) unsigned DEFAULT NULL,
  `val_2` varchar(127) DEFAULT NULL,
  `val_3` varchar(255) DEFAULT NULL,
  `val_4` varchar(127) DEFAULT NULL,
  `val_5` int(10) unsigned DEFAULT NULL,
  KEY `my_wonky_table_id_idx` (`id`),
  KEY `my_wonky_table_timestamp_idx` (`timestamp`),
  KEY `my_wonky_table_val_1_idx` (`val_1`,`id`),
  KEY `my_wonky_table_val_2_idx` (`val_2`,`id`),
  KEY `my_wonky_table_val_4_idx` (`val_4`,`id`),
  KEY `my_wonky_table_val_5_idx` (`val_5`,`id`),
  KEY `my_wonky_table_ip_idx` (`ip`,`id`),
  KEY `my_wonky_table_login_idx` (`login`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`id`)
(PARTITION pdefault VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */

关于查询:它始终是 id 上的 SELECT,其他所有内容都用于过滤。

我想避免的:

  • 关闭数据库实例。
  • 100% 的磁盘 I/O

我曾想过使用pt-online-schema-change工具来节流,但遇到了无主键墙。一个不同的解决方案是在代码中执行此操作,有效地将触发器移动到代码库,并使用有些奇怪的 block (例如,使用时间戳列的一个小时的数据 block )缓慢复制数据,因为没有唯一索引。

是否有其他可用的解决方案和/或工具?

最佳答案

  1. 创建一个类似于真实 表的 表,但具有修改后的索引。包含一个 PRIMARY KEY 这样您就不会再被困住。 -- 这是 ALTER,但还不是“填充”。
  2. 在新表中,对旧数据使用季度或年度分区;当前和(以后) future 的分区每月一次。 -- 这是为了减少分区总数。我的经验法则是“不超过 50 个分区”。 (如果您对此计划有疑问,请告诉我。)
  3. 编写脚本慢慢地将所有数据从 分区复制到 表中。我对chunking的建议在这里可能会有用。
  4. 就在你被 catch 之前,创建一个新分区。但是不要从中复制。在前一个分区的末尾停止“复制”脚本。
  5. 当 catch 除了这个新分区时,停止写入。
  6. 复制最后一个分区。 -- 这是第 4 步得到返回的地方。
  7. 原子交换:RENAME TABLE real TO old,new TO real;。并再次打开书写。

强烈建议编写所有脚本并在另一台机器上练习。实践可以只占总数的一小部分,但至少需要有几个分区。

关于mysql - 限制 ALTER TABLE 磁盘利用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43256401/

有关mysql - 限制 ALTER TABLE 磁盘利用率的更多相关文章

  1. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  2. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  3. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  4. ruby-on-rails - 限制 will_paginate 中的页数 - 2

    因此,在使用Sphinx时,搜索限制为1000个结果。但是,如果will_paginate生成的结果分页链接超过1000个,请不要考虑这一点,并提供指向超过1000/per_page的页面的链接。设置最大页数或类似内容的明显方法是什么?干杯。 最佳答案 我认为最好将参数:total_entries提交给方法paginate:@posts=Post.paginate(:page=>params[:page],:per_page=>30,:total_entries=>1000)will_paginate将仅为显示1000个结果所需的页

  5. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  6. ruby-on-rails - 当我通过 rvm 使用 rails3 时,如何在 ubuntu 上安装 mysql2 gem? - 2

    我正在尝试绕过rails配置这个极其复杂的迷宫。到目前为止,我设法在ubuntu上设置了rvm(出于某种原因,ruby在ubuntu存储库中已经过时了)。我设法建立了一个Rails项目。我希望我的测试项目使用mysql而不是mysqlite。当我尝试“rakedb:migrate”时,出现错误:“!!!缺少mysql2gem。将其添加到您的Gemfile:gem'mysql2'”当我尝试“geminstallmysql”时,出现错误,告诉我需要为安装命令提供参数。但是,参数列表很大,我不知道该选择哪些。如何通过在ubuntu上运行的rvm和mysql获取rails3?谢谢。

  7. ruby - 评论限制 - 2

    在ruby​​1.9中,放宽了行结束位置的条件,因此我们现在可以用句号开始一行来显示方法调用。当我们混淆了链式和非链式方法,并希望显示下一个非链式方法的开始位置时,这很方便。如果没有这个新功能,我们能做的最好的可能就是使用缩进:method1(args1).method2(args2).method3(args3)method4(args4).method5(args5).method6(args6)或插入一个空行。但这很不方便,因为我们必须注意缩进,同时,不要忘记在每个方法调用之后加上链中最后一个方法调用之后的句点。正因为如此,我制造了很多错误,要么有一个额外的周期,要么有一个缺失的

  8. ruby - 如何在特定队列中推送作业并使用 sidekiq 限制工作人员数量? - 2

    我知道我们可以做到:sidekiq_optionsqueue:"Foo"但在这种情况下,Worker只分配给一个队列:“Foo”。我需要在特定队列中分配作业(而不是worker)。使用Resque很容易:Resque.enqueue_to(queue_name,my_job)另外,为了并发问题,我需要限制每个队列的Worker数量为1。我该怎么做? 最佳答案 您可能会使用https://github.com/brainopia/sidekiq-limit_fetch然后:Sidekiq::Client.push({'class'=>

  9. ruby-on-rails - 如何限制模型每天创建一条记录? - 2

    业务逻辑:用户每天只能为日记创建一个条目。在创建条目之前,它必须查询记录以确定是否已经为今天创建了条目。我正在寻找解决此问题的最佳方法的建议。我对如何在客户端实现它有一些想法,但我真的很想在模型层进行验证。任何帮助将不胜感激。 最佳答案 在日志表上创建唯一索引:add_index:journal_entries,[:user_id,:created_on],unique:true然后只能创建一条具有给定user_id和日期的记录,如果违反,数据库将引发异常。请注意,created_on必须是date列,而不是datetime。这是唯

  10. ruby-on-rails - 使用 PostgreSQL 适配器限制 ActiveRecord 迁移 5.0 中的文本列 - 2

    我的迁移看起来像这样classCreateQuestionings现在,当我运行$rakedb:migrate:reset时,在我的db/schema.rb中看不到限制:create_table"questionings",force::cascadedo|t|t.text"body",null:falseend我做错了吗还是这是一个错误?顺便说一下,我使用的是rails5.0.0.beta3和ruby​​2.3.0p0。 最佳答案 t.text在PostgreSQL和textdoesn'tallowforsizelimits中生成

随机推荐