【问题标题】:In what efficient way does MyISAM/InnoDB deletes specific text from a file?MyISAM/InnoDB 以什么有效的方式从文件中删除特定文本?
【发布时间】:2017-09-25 17:50:07
【问题描述】:

在将其标记为重复之前,请阅读整个问题。

我知道我们只有一种方法可以从 C 中的文件中删除特定文本,即重写整个文件,除了我们要删除的文本。但是如果我们有一个文件数千或数百万行文本。现在,由于 MyISAM 是一个必须提高效率的存储引擎,因为它要用于数百万条记录并且它是用 C 语言制作的,那么它如何在不重新重写整个文件的情况下实现这一点?即我在问 MyISAM 的开发人员使用何种技术从文件中删除特定文本而不重新重写它。

【问题讨论】:

  • 不标记为重复,而是将 vtc 标记为“太宽泛”。我们不能解释数据库:(
  • @MartinJames 能否请您简要解释一下。我只是要求开发人员使用的解决方案来克服重写文件的问题。
  • 同意@MartinJames。简短的回答是不可能的。 MySQL 引擎是多年和许多开发人员的成果(边缘:年数乘以人-用“开发人员英语”怎么说?-我不是母语英语)
  • BD 文件不是简单的文本文件、字符流,并且在更新/删除期间不会重写。这种理解是没有帮助的——它完全不同。一个人用几行 C 代码在短时间内“手动”“手动”修补 db 文件是不可能的(我在职业生涯中做过这么几次)。在 SQL 中使用最大可能的高级访问权限,对服务器进行良好的调整(默认值不太好),使用缓存,禁用刷新
  • @JacekCz - 我的回答是否“不可能”?

标签: c database file innodb myisam


【解决方案1】:

就像在DOS中一样,东西不是“删除”,而是“标记为已删除”,这样对于所有后续操作,被删除的东西似乎都消失了。

MyISAM:

  • 标记记录的第一个字节以表明它已“删除”。
  • 从每个索引中删除相应的条目。

InnoDB:

  • 转到包含要删除的行的块(在数据BTree中,由PRIMARY KEY索引);将其标记为已删除。
  • 向重做/撤消日志添加内容——以防后续ROLLBACK 恢复该行。
  • 向更改缓冲区添加一个条目,以便索引查找不会找到该行。
  • 最终将更改缓冲区条目刷新到实际索引。
  • 最终将数据记录清除出块。

在任一引擎中,只有少数 IOP(BTree 向下钻取、读取、写入、日志记录)来删除行。实际的 IOP 数量取决于缓存——由于将此删除与表上的其他操作相结合。

MyISAM 的数据是一个流文件;代码将“寻找”+读取或写入一条记录。

MyISAM 的索引是 BTree 并缓存在“key_buffer”(1KB 块)中; InnoDB 的数据和索引是 BTrees 并缓存在“buffer_pool”(16KB 块)中。所有操作都是seek+一个block的读/写。

我认为,InnoDB 重做/撤消日志是流式传输的。

InnoDB 的“双写”缓冲区是一个被冗余写入的块。这是针对“撕裂页面”的 ACID 保护,其中在断电期间块被写入一半。大多数磁盘的操作单位是一个 512 字节的“扇区”; MyISAM/InnoDB 的单元有几个这样的。

从长远来看

那么,如果一条记录仅被标记为已删除,那么 磁盘 空间是否曾经恢复?我强调磁盘空间而不是“内存”RAM,因为 RAM 只是用作缓存。

嗯,这取决于。如果您正在“搅动”数据——删除和插入——那么DELETE 释放的空间将可用于INSERT。但是,由于记录的布局方式,INSERT 可能会或可能不会重用最近由DELETE 释放的空间。但是,从长远来看,插入将填补删除留下的“漏洞”。但是……

BTree 本身就有一个小问题。每个节点都是一个固定大小的块。做了几次删除后,固定大小并没有缩小。在进行过多插入后,该块被“拆分”成两个块(具有相同的、固定的大小)。尽管如此,随着时间的推移,BTree 将被吸引到大约 69% 的满载。也就是说,最初的 69 个完整块将(经过大量流失后)达到大约 100 个块的稳定状态,同时仍包含相同数量的记录。

所以,一张表会增长,但永远不会缩小。但增长仅限于实际数据大小的某些倍数。缩小呢?...

在 MyISAM 和 InnoDB 中,都有自动“碎片整理”的方法,并将浪费的空间还给操作系统。但是,有一个 SQL 语句可以做到这一点。但不要使用它;这是不值得的。它创建一个新表,复制所有数据,重建索引并将表重命名为您拥有的表。很多努力;几乎没有什么好处。

另一件事...如果两个“相邻”的 BTree 块小于一半,则这些块将被合并。 (这会释放一个块以便在给定表中重用,但不会将其返回给操作系统。)

“大公司”是做什么的?回答:“没什么。”我曾经为这样的公司工作,所以我可以根据经验说话。在 100 个系统上的 10,000 个表中,我确定了 2 个值得进行碎片整理的案例。而且只有每月一次。还有 MyISAM,而不是 InnoDB。你今天不应该使用 MyISAM。

【讨论】:

  • 所以这意味着数据实际上并没有被删除,而是被标记为已删除并跳过阅读。在这种情况下,内存不会被释放,这将是这些存储引擎的缺点之一,从长远来看,将需要重写文件以释放内存。我是对的吗?这(长时间重写一次)真的发生在像谷歌和脸书这样的大公司吗?
  • @ChaitanyaVaishampayan - 为您的评论添加了长答案
猜你喜欢
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 2011-08-13
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多