• 押宝的人生

    有一个关于时间的“祖父悖论”,同理,谁也无法判断未来:反证法,如果你能够判断未来,那你去干扰,导致未来没有按照你的判断发生,那你的判断就是错误的。这大概也是人生另一个有趣的地方吧,你永远也不知道未来会怎样。你不知道你的未来会怎样,你不知道你工作的未来会怎样,你不知道你十年之后会怎样,你也不知道你所公司的未来会怎样…… 对于未来,我们甚至没有一点是可以确定的。

    很有意思的是,我们在做很多决定的时候,却都是基于我们对于未来的判断(例如,天气预报)。事实上,很多时候这是不靠谱的。当然,预测对的时候也有。所以我一直觉得,当我们每次基于此去预测未来的时候,我们都在押宝而已,有时候押的准,有时候会运气不好。

    我们不必因为之前对于未来判断失败而责备自己。人的一生是短暂和孤单的,未来是不可以预测的,勇敢的追求内心的理想吧。

    The Persistence of Memory

    The Persistence of Memory

  • 当管理的MySQL主机越来越多的时候,遇到Bug的可能性也就越来越大了。基本上,每隔一段时间,我们都会遇到一个Bug或者版本兼容问题。有些Bug已经修复(Bug #44571),有些Bug无法重现或者修复(Bug #39168)。即使Bug能够重现,我们也不能期待MySQL/Innobase能够多快的给出Patch,他们没有这个义务,我们也没有权利要求。

    如何处理Bug?

    尝试到找Bug重现的场景,确定他是一个Bug,而不是一个Mistake。一般遇到Bug,都能在MySQL Bug找到线索,如果能够确定是Bug,可以看看新的版本是不是已经修复,如果修复则可以考虑升级小版本号。对于更高的小版本号,我们有如下假设(或者认为)

    • 更高的小版本号解决了更多Bug;
    • 如果更高的小版本有新特性,那么意味着新特性可能带来更多的Bug;
    • 更高的小版本,仍然会有和老版本不兼容的地方;
    • 更高的小版本,有很cool的新特性;
    • 一般,小版本的升级不会影响应用。

    所以,一般遇到Bug,新的小版本如果有修复,我们将优先考虑升级小版本号。

    另外,找到Bug重现的场景,还可以考虑绕过Bug(workaround),让自己的应用或者DDL尽量避免Bug出现。有时候,新版本新特性会带来一些Bug,不得以我们还可以考虑降级版本,虽然这是不推荐的做法,因为这样的可能陷入死循环。

    Bug?Debug!

    纵然,Innobase/MySQL AB已经被Oracle收购,MySQL的源代码仍然受到GPL的保护,所以我们仍然能够获得源代码,这就意味着我们自己Debug也成为可能。很多做开源方案的团队、公司已经发布了很多Patch,一般是做性能提升或者功能增强,他们也在MySQL Bug上提交了很多Patch建议。

    这里的另一个问题是,自己的团队是否可能去Debug、打补丁?一般地,如果能够找到源代码的Bug,将其提交到MySQL Bug上,等待更加理解整个架构的人去将代码Merge到源码树中,一般是比较靠谱的办法。这大概也是为什么,目前开源社区、团队产生的一般是性能提升或者功能增强补丁,而很少Debug补丁。

  • 起因

    昨天,在给一个数据表DDL操作时,InnoDB报了如下错误:

    100602 13:48:39 [ERROR] Index uk_usplugin_plugid of test/test_user_plugin_0002 has 2 columns unique inside InnoDB, but MySQL is asking statistics for 3 columns. Have you mixed up .frm files from different installations? See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html

    MySQL版本:MySQL5.1.45+InnoDB Plugin1.0.6

    当时的DDL:

    alter table test_user_plugin_0002 drop index USER_ID,add unique index uk_pluser_userid(USER_ID,PLUGIN_ID);

    追踪

    MySQL Bug System中看到,问题类似于Bug #44571中的Case2(Bug #47622)。问题的大概原因是,InnoDB的system table中的表信息和MySQL字典中的表信息不同步导致的。尝试了几次,无法重现错误。

    如何避开(workaround)

    可以通过下面的SQL来重建InnoDB的索引:

    alter table test_user_plugin_0002 engine=innodb

    Bug #47622看到5.1.46中貌似已经解决了这个问题,还可以尝试升级到5.1.46。

    另外,应该还可以尝试在DDL时打开old_alter_table来避免:(未验证)

    SET [GLOBAL] old_alter_table=ON
  • 较之MyISAM的一个很大的优势是,InnoDB会缓存数据块。如果系统中的数据量并不大,或者或者活跃数据量并不大时,InnoDB会将这些数据块全部缓存到Buffer Pool(内存)中,这样可以最大限度的提高提供的响应速度,特别是读取。当用户请求需要查询数据块时,InnoDB会首先在Buffer Pool中查找数据,如果Buffer Pool中没有该数据块时,InnoDB会从磁盘上Load对应的数据块,并通过LRU算法替代当前Buffer Pool的缓存块。

    1. Buffer Pool中LRU缺点、细节

    这样LRU算法的一个缺点是,如果有某一个查询做了一次全表扫描(例如备份,临时DDL等),都可能会导致整个Buffer Pool中LRU链表中的数据块都被替换了,甚至很多热点数据也会被替换,而这些新进的数据块可能在这一次查询之后就再也不会被读到了。我们也称这种情况为“Buffer Pool被污染”了。

    在InnoDB则引入了一些新的机制来避免这种情况。算法仍然是LRU算法,但是加上了中点策略(类似于MyISAM的key buffer中的midpoint strategy)。同时引入了参数innodb_old_blocks_time来控制Buffer Pool不被污染。

    LRU链表中的数据分为两部分:Sublist of new和Sublist of old。后者包含访问最近没有访问的数据块(链表越后面的数据块,最近越没有被访问)。默认情况,前者占63%(5/8),后者37%(3/8)。

    BufferPoolLRU (more…)

  • 很早之前就遇到一次这个故障,当时是一台主机故障,这次是上百台主机故障。当时是使用mysqldump向NFS备份时,写数据时大概是NFS出现故障,使得mysqldump进程进入uninterruptible sleep(man ps)状态:

    $ps axu|grep mysqldump
    mysql 2718 0.0 0.0 51088 672 pts/0 S+ 13:30 0:00 grep mysqldump
    mysql 14916 1.4 0.0 0 0 ? D 02:03 10:03 [mysqldump]

    进入该状态的进程,会一直等待NFS,不接受任何信号,当然也就无法被杀死(kill/fuser -k)。因为进程一直在运行队列(running queue)中,所以还会导致主机的Load上升(虽然主机并不繁忙)。如果由于这个原因被卡住的进程很多的话,主机的Load可能会看起来非常高。 (more…)

  • 关于CAP

    后知后觉仍然比不知不觉好一点,虽然我们努力最求的是先知先觉。

    在阅读了Eric A. Brewer的keynote at the PODC和Gilbert and Lynch的Brewer’s Conjecture and the Feasibility of Consistent,Available,Partition-Tolerant Web Service后,对CAP有了些初步的认识,也尝试弄清楚一些基本的问题。

    1. 为什么我们需要知道CAP

    记得当初学习数学科学(例如微分方程)的时候,如果求解一个问题,首先我们需要证明这个解的存在性。(没学过微分方程也可以回忆一下哥尼斯堡七桥问题

    现实生活中,我们往往面临的是非常具体(甚至琐碎)的问题,我们也在不断付出巨大的努力的尝试解决它们。如果问题棘手,发现一时无法走出的困境后,往往会寻求新的设计方案来解决问题。每一个方案(系统)设计之初,参与设计者往往对未来这个方案充满了憧憬,事实上,新方案也一般能解决现有系统的瓶颈。但是新方案运行一段时间后,我们又会重新发现,我们绕过了一些问题,面对的是一些新的困境。

    为了避免这种情况,在设计新方案的时候,我们需要尝试弄清楚我们现在系统解决了哪些问题,没有解决哪些问题,无法解决哪些问题;设计新系统,我们能够解决哪些,无法解决哪些。

    CAP理论(也许不能说是严格理论,因为我们往往在C、A、P之前寻求平衡)便是基于这样的思考,产生的理论。 (more…)