文章
网络安全

谈谈thphd的《对养猫君对葱爆的分析的分析》一文的错误之处

对养猫君对葱爆的分析的分析

我最近翻站里的旧文章,发现这篇一年以前的文章里充斥着大量的IT常识错误,作者的语气还颇为自信,气势很能唬住一些外行读者。这样一篇充满低级错误的文章以贵站(前)站长的身份发在站里,实属拉低了贵站技术的上限。不知那些专业的IT人士看到这样一篇文章,会对2047的技术水平作何感想?因此,我认为有必要写一篇文章,指出《葱爆的分析的分析》的错误之处。

thphd在这篇文章中的技术分析有很多错误。我不清楚是他自己一知半解就信口开河,还是自己清楚但故意误导读者。比如,技术分析部分的第二段就是如此:

MySQL遇到磁盘已满的情况,并不会返回DISK_FULL错误并拒绝服务,而会直接当场卡死,除非非常了解mysql工作原理,否则只能强行重启:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

我很疑惑thphd是否真的看过这个链接里的内容,这个链接里讲的是MySQL如何处理磁盘写满的情况。根据MySQL文档的说明,在磁盘写满时,MySQL并不会“卡死”,而只是每隔一分钟检查一下是否有足够的空间写入,如果有空间就写入,没有空间就不写入,就好像什么都没发生一样(it continues as if nothing had happened)。

就算不去读MySQL的文档,凭常识也可以推断出,MySQL作为一款全世界最流行的数据库系统,背后又有Oracle这样的公司支持,必然会考虑到磁盘写满这样的常见情况。所谓MySQL“卡死”纯属缺乏计算机常识的臆测。

这篇文章里更有一些极度缺乏常识的观点,例如:

因为开机过程也是需要写入磁盘的,磁盘空间不足可能导致开机卡死。而云服务器无法开机就连不上,也就无法进行远程操作

我不知道thphd是否有操作Linux系统的经验。Linux系统非常可靠,这和我们日常使用windows电脑的经验不同,即使硬盘写满,内存占满,CPU使用率100%,也不会影响正常使用,当然也不影响远程连接。事实上在商业环境中,操作系统满负荷重载运行是很正常的事情(包括偶尔写满硬盘),否则公司投资了昂贵的IT基础设施又不能跑满,岂不是严重的浪费。

下面的分析更是看似有理,实则是满篇的胡说八道:

所以另一种情况是,品葱站长强行重启了服务器,开启了数据库,数据库尝试从上一次强行重启的地方开始恢复。由于几乎所有数据库都依赖某种b+tree,而b+tree最流行的实现是leveldb(myrocks),leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

常见的数据库管理系统由存储引擎和外部的“wrapper”构成。存储引擎是数据库的核心,其本质是一棵查找树(B树、B+树、LSM树),通过查找树可以高效地完成数据读写等数据库基本功能。外部的“wrapper”负责解析命令、查询规划、用户认证等功能。

要查看mysql的存储引擎,可以在MySQL控制台输入show engines。下图所示列出了MySQL使用的存储引擎,可见其中并没有thphd提到的“leveldb/myrocks”

事实上,MySQL最常用的存储引擎的是InnoDB和MyISAM。InnoDB是芬兰公司Innobase在2005年开发的一款存储引擎,MyISAM是MySQL团队基于IBM ISAM开发的存储引擎。而LevelDB是谷歌公司在2011年发布的一款嵌入式数据库,和MySQL风马牛不相及。

再进一步,thphd对LevelDB存储特性的分析,也是完全错误的:

leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

从技术角度说,leveldb并不依赖底层磁盘的写入特性。确实,LevelDB对底层存储设备做了“顺序写入速度大于随机写入速度”的假设,这是为了优化写入性能。这种实现叫做LSM树(Log Structured Merge Tree,日志结构合并树),而不是thphd所说的B+树。好了,这里thphd又犯了一个知识性错误。

LSM树会把对数据的修改变化缓存在内存中,达到一定的大小限制后,将这些变化批量写入磁盘。确实,在LSM树把数据写入磁盘之前,断电会导致数据丢失,然而LevelDB中数据缓存-写入的间隔非常短,仅为几百毫秒。换句话说,如果你在1秒的时间内,向LevelDB写入数据然后断电,那么这1秒内写入的数据确实会丢失,但是只要超过1秒,数据就会永久写入磁盘,不管怎么断电都不会影响数据,除非磁盘本身损坏。

再退一步说,LevelDB的作者是谷歌首席程序员Jeffrey Dean,并且在开发过程中得到了谷歌的大力支持。就算你对我或thphd说的一切表示怀疑,你应该可以相信谷歌顶级程序员的实力——LevelDB经过了无数苛刻环境的考验,重启电脑并不会丢失大半年的数据,否则谷歌首席程序员就不要混了。

至于看了《对养猫君对葱爆的分析的分析》信以为真的网友,这不是大家的错,毕竟术业有专攻,不能要求每个人都是IT专家。但是贵站的前站长thphd暗示自己是“IT从业人士”,却发表这样一篇错误百出的文章,我想只有两种可能:要么是 1) 拉大旗扯虎皮,用专业名词忽悠外行,证明自己对“葱爆”的原因推测正确,进而达到污蔑其它网站的目的。要么就是 2) 没有基本的网络常识,被抓迟早的事。

相关资料:

[1] MySQL存储引擎:https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html

[2] MySQL磁盘满的行为:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

[3] LevelDB:https://github.com/google/leveldb

[4] LSM-tree: https://en.wikipedia.org/wiki/Log-structured_merge-tree

菜单
  1. linda   rico y libre

    好文章,当然thphd失踪倒不是因为没有基本的网络常识...

  2. kebi123456  

    顶一个,我看来一下那篇文章,对mysql的描述简直就是在胡说八道

  3. kebi123456  

    mysql完全就跟leveldb没关系,leveldb是lsm树跟b+树也完全没有关系,不知道那篇文章是怎么胡扯扯到一起的