记一次数据库bug故障恢复

从一件小事说起

最近一个月不知何故,博客的VPS IP无法ping通。提交ticket要求更换ip, 毫无意外的被拒绝了。于是直接从当前VPS clone 一台间接实现了IP的更换。clone的文章参考官方指引即可。因为是克隆操作,因此所有的环境和数据都保持不变,配置成本约定于0。整个过程加上修改DNS,10分钟搞定。正准备来杯清茶休息一下的时候,发现新机器的mysql挂了:

2020-03-21T12:00:03.913175Z 0 [Note] InnoDB: Apply batch completed
2020-03-21T12:00:04.016847Z 0 [Note] InnoDB: Removed temporary tablespace data file: “ibtmp1”
2020-03-21T12:00:04.016974Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2020-03-21T12:00:04.017051Z 0 [Note] InnoDB: Setting file ‘./ibtmp1’ size to 12 MB. Physically writing the file full; Please wait …
2020-03-21T12:00:04.020703Z 0 [Note] InnoDB: Starting in background the rollback of uncommitted transactions
2020-03-21T12:00:04.020779Z 0 [Note] InnoDB: Rolling back trx with id 35499526, 1 rows to undo
12:00:04 UTC – mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.

key_buffer_size=8388608
read_buffer_size=131072
max_used_connections=0
max_threads=151
thread_count=0
connection_count=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 68195 K bytes of memory
Hope that’s ok; if not, decrease some variables in the equation.

Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong…
stack_bottom = 0 thread_stack 0x40000
/usr/sbin/mysqld(my_print_stacktrace+0x2c)[0xed2ebc]
/usr/sbin/mysqld(handle_fatal_signal+0x451)[0x7b4ea1]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)[0x7f85fd1a5340]
/usr/sbin/mysqld(_Z32page_cur_search_with_match_bytesPK11buf_block_tPK12dict_index_tPK8dtuple_t15page_cur_mode_tPmS9_S9_S9_P10page_cur_t+0x168)[0xf89528]
/usr/sbin/mysqld(_Z27btr_cur_search_to_nth_levelP12dict_index_tmPK8dtuple_t15page_cur_mode_tmP9btr_cur_tmPKcmP5mtr_t+0x1121)[0x10b2d31]
/usr/sbin/mysqld(_Z22row_search_index_entryP12dict_index_tPK8dtuple_tmP10btr_pcur_tP5mtr_t+0x11f)[0xffd4ff]
/usr/sbin/mysqld[0x11cb0d6]
/usr/sbin/mysqld(_Z12row_undo_insP11undo_node_tP9que_thr_t+0x22b)[0x11cc0bb]
/usr/sbin/mysqld(_Z13row_undo_stepP9que_thr_t+0x405)[0x1019385]
/usr/sbin/mysqld(_Z15que_run_threadsP9que_thr_t+0x871)[0xfa97c1]
/usr/sbin/mysqld(_Z31trx_rollback_or_clean_recoveredm+0xcdc)[0x106c8dc]
/usr/sbin/mysqld(trx_rollback_or_clean_all_recovered+0x4e)[0x106d7ee]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x8182)[0x7f85fd19d182]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f85fc6aa47d]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
2020-03-21T12:00:04.056733Z mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

从错误信息 mysqld got signal 11 看,应该是启动过程是尝试fix table触发了bug,因此启动失败。

如何解决 mysqld got signal 11

既然是fix corrupted table导致的问题,那么思路自然是先把mysql启动起来,备份数据,然后找到存在问题的table, 再逐步恢复数据(我的mysql server版本是:5.7.23,不同版本可能稍有差异):

  1. 如果服务器未正常停止,先停止mysql: service mysql stop
  2. 备份文件/var/lib/mysql/ib*: mkdir /tmp/fixdb && cp -rp /var/lib/mysql/ib* /tmp/fixdb
  3. 在配置文件/etc/mysql/my.cnf中添加如下内容:

[mysqld]

innodb_force_recovery = 3

  1. 启动mysql: service mysql start. 如果启动失败,尝试改大步骤3的数字,直到启动成功。
  2. 备份数据表: mysqldump -A -uUSERNAME -p > dump.sql
  3. 删除所有用户数据库:

mysql -uUSERNAME -p

drop database xxx…

  1. 停止mysql: service mysql stop
  2. 删除ib文件:rm /var/lib/mysql/ib*
  3. 删除步骤3中添加的两行内容
  4. 启动mysql: service mysql start. 在mysql错误文件(/var/log/mysql/error.log)中应该可以看到最开始导致启动失败的corrupted table.
  5. 恢复数据:mysql -uUSERNAME -p < dump.sql. 如果恢复过程中出现 Tablespace exists错误,则尝试删除ibd文件,然后重新导入数据:

ERROR 1813 (HY000) at line 268: Tablespace ‘DBNAME.TABLENAME‘ exists.

rm /var/lib/mysql/DBNAME/*.ibd

mysql -uUSERNAME -p < dump.sql

终于大功告成。恢复过程中小紧张了一下,使用了10年的VPS终于满血复活。

参考文献

揭秘人类不再迷失之路

特殊时期,每天可以自由支配的时间一下变得非常奢侈。好在年前购入了很多新书,足不出户,至少保证灵魂在路上。

我说的是实际的路:因为去年老家面临拆迁,以租代征的基层政策以及自己对故土的小家情怀,一直没加加入这个所谓的拆迁荒唐事。趁着疫情期间,拿出手机,打开卫星地图,把自己小时候在家附近“探险”过的每个田间地头都看了个遍,勾起了自己很多难忘或喜或忧的回忆。

如今我们用手机查看地图,导航或者用卫星图片探索有趣的地点已经习以为常,但是我依然记得第一次使用谷歌地球找自家屋顶时候的欣喜和快乐。有人说,“你是谁,你从哪里来,到哪里去”是保安同志每天要叩问路人的三大哲学问题。其中两个都跟位置相关。想起了年前看书评的时候,买入的《谷歌方法》——一本关于谷歌地图,谷歌地球和街景前世今生的亲历缔造者手记。

(吐槽一下翻译的书名:谷歌方法。我呸……这根本不是一本讲什么谷歌方法的书,书的原名是 Never Lost Again: The Google Mapping Revolution That Sparked New Industries and Augmented Our Reality. 我特别喜欢原名及原版封面,它无意中揭露的谷歌地图让我们成为不再迷失一代的事实,封面LOST中的字母O使用的经典的图钉位置设计也让我们知道这本书要将的是位置这个话题。翻译成谷歌方法更多是商业上的考虑,因为它能跟之前关于谷歌的两本书形成一个系列。不过书名牛头不对马嘴的这种方式倒是能验证一些喜欢望文生义的读者有没有真正读过这本书。有没有发现这篇blog的标题也是这总风格?被中信出版社恶心透了,总得找种方式释放不是……)

南国深夜,淅沥雨声,台灯清茶,看得自己津津有味。看到其中产品故事发出笑声以及感慨声一度超过了在客厅刷好莱坞大片的妻子。

2005年的暑假,也就是老爸给我配置了一个新电脑的第二年,那时候的谷歌的一切服务在墙内都可以正常访问。瞎逛的时候,看网友推荐了一个非常有意思的软件 Google Earth. 对于很多人而言,通过这个软件,终于有了第一次从空中这个视角,准确讲是从太空中,巡查一下自家屋顶是什么样子的机会。如果你有一点点耐心,你还可以把自己经常通行的线路飞行一遍。然后发现,原来自己一直以为的最短路线其实是兜了个大圈子,原来我家附件还有一些幽深的小山丘和溪流自己还没去探索过,原来可以在家把世界上的名胜古迹免费从空中检阅一遍……

如今想来,自己算是 Google Earth 的第一批用户。同时也暗自庆幸和感谢老爸在那个时候给我配置了一台崭新的电脑(初中时候也有一台古董电脑,但是333MHz的处理器表示压力太大了),因为那个时候初中升高中,很多家长还是觉得电脑是个潘多拉魔盒,宁可扼杀死,也绝对不放过。而自己通过计算机开眼,以及后来误打误撞报考(调剂)了计算机学院细想起来应该是从这里发源的。这也是为何今年在疫情期间老爸提出想换一个笔记本电脑的时候,我居然很认真的说,老爸你别说是一台了,即使十台我也想办法明天给你搞到手。当然,老爸只是大手一挥,不屑的说,别吹牛B,赶紧的……

谷歌地图第二个里程碑当然是跟GPS有关。caoz之前一直说GPS是人类近代科技发展水平的最高代表作,芯片、通信、相对论、航天、数学不一而足,成以为然。而这个里程碑是通过第一代iPhone实现的。在iPhone出现以前,Window Mobile 系列的史前智能手机是可以通过手机基站定位,但是精度太差。而2007年推出的搭载谷歌地图的iPhone让人类解锁了在触屏智能终端上使用地图和导航的正确姿势。从科技发展的历程看,我的位置以一个蓝色图标出现在地图上,标志着人类真正步入 Never Lost Again 时代. 对此我深有体会:受限于生长的环境和科技发展水平,我在大学以前的活动范围基本限制在了县城。成都市中心是不想去的,因为找不到路,而打车对我来说太贵,自己问路又胆怯。当然,2007年,我还是没有财力解锁不再迷失。直到2010年,我购买了摩托罗拉Milestone——一个至今开起来很帅的侧滑全键盘触屏android智能手机。我依然记得我购买了这个手机以后,即使每天下午开车去接前女友(现妻子)下班也要开着谷歌地图导航,虽然距离只有几公里,虽然这条路已经走了很多遍,但是……偷老爸车出来泡妞再架个导航心里很有安全感?!

很多人可能奇怪,2009年因为总所周知的原因,它不就已经退出大陆了吗?事实上也的确如此,但是那时候的q还没有这么高,android系统也相对开发,绑定一下hosts就能访问,但是访问速度就看人品了。如今,很多人在使用地图的时候,默认指的是高德地图和百度地图,而我又一直想告诉他们其实这一切应该感谢谷歌地图却发现他们其实用这两个也挺开心的时候,只能欲言又止。可能直接开始使用高德和百度地图的用户很难理解我们这群遗老遗少对谷歌地图的那份怀念。讲一个有趣的事情。

2013年学术出差台北。离开机场坐大巴一切顺利,但是下车需要短距离步行才能到酒店。在大陆,你肯定非常从容的掏出手机,百度一下。我那时也很从容,只是百度地图打开以后一篇空白……因为它丫的就没有台北的地图,更不要提交通数据了。好在那时的微博跟台湾似乎有很多网络基础设施的合作,在街边用微博账号连上免费wifi, 顺着谷歌地图找到了酒店。你说这个事情在没有导航的时候不就是正常现象吗?也对,但关键是我们已经步入Never Lost时代,由奢入俭难呀……

高德地图和百度地图其实在产品本地化上其实做得挺有特点。比如高德相对靠谱的测绘数据,基本是国内自驾游的最佳搭档,中国的汽车销量和行驶里程有很多其实都应该感谢导航软件的成熟。比如百度地图的丰富生活周边,至于是不是骗子机构,需要自行判定。但是,从定位上看,它们与谷歌地图完全不是一个级别的东西。拉里的愿景是让一切物理世界可检索。谷歌地图就是打开物理的钥匙。从这个角度看,我倒更喜欢作者之前的公司名称——keyhole. 而让物理世界可检索有什么用吗?似乎并没有任何直接卵用。因为按照作者比尔采访了这么多人,发现一个神奇且让人无法相信的结论:

没有人能回答我提出的这个问题:在付出了这么多精力,搜集或只做了这么多的数据,花了这么多钱,开发了这么多新技术之后,谷歌地图和谷歌地球最终为谷歌赚钱了吗?谷歌地图和谷歌地球实现盈利了吗?

对此,我想最好的解释就是Google的使命:

自Google 于1998 年成立以来,我们的使命始终如一:整合全球信息,使人人都能访问并从中受益。

谷歌地图其实并不是一个简单的地图产品,我更愿意把它称为一种基于位置的基础设施,LaaS(Location as a service). 所以,虽然百度2014年开始全球化,尝试补足缺失的地图数据(并没有卫星地图数据),一直沉浸在上市喜悦好几年的高德地图从今年才开始全球化,但它们从来都不是谷歌地图的竞争者。

书末,作者轻描淡写的引入谷歌地图的缔造则,他的老板,约翰离开谷歌创办了 Niantic. 可能你跟我一样最开始甚至没有听说过这个公司,但是你大概率听过或者玩过他们的游戏 Pokémon GO。我很理解这个章节被安排在看似非正文的位置,而这也恰恰是这本书的另一个有特点的地方:真实有趣。作者作为为预算上不封顶的谷歌地图营销经理,也会负担不起加州的房价;在keyhole被谷歌收购之前,毫不夸张的说,整个公司在一分一分续命;在谷歌中,也会有地盘的争夺,也会有权利斗阵;而约翰在把谷歌地图腿上顶峰之后,只是因为既能外出同时也能玩游戏的点子可以让自己多陪伴孩子选择了创业,而且居然结果还不错。

约翰选择的路让自己思考了良久,其实很多人在大公司一直往上爬的时候是不会想自己主动离开的那一天,也不会想如果自己掉下去起不来之后该怎么办。约翰的华丽转身不是偶然,一来我在手游行业干过,他准备做游戏的那个时间点拿捏的非常好,应该说以他的资源背景和时机,取得这样的成绩其实远不及supercell。更重要的,约翰知道做的项目迟早有结束的一天,但是追求的路 never end.

一个了解疫情的小创造和几点思考

月初时候,无意中说道,一月挺长,春节长假回来还是一月。然而,后面的事,大家都知道了……

分享一个了解疫情的小工具

这个春节强制培养了十亿以上的宅男宅女,每天都会进行的一项全民活动就是刷疫情的最新新闻。现在的网络是发达了,但是大部分网民基本没有对互联网信息基本的鉴别意识,因此前几天各种谣言每天飞的“盛况”也就不足为奇了。我自己一直通过订阅一个电报群关注疫情的实时进展,消息有来源也有链接,整理和归纳也算全面及时。在第一时间分享了群的地址,但是我低估了谷歌退出中国10年这个事实对网民的影响,即使在我的朋友圈中,也有很多没法克服网络问题订阅该群。因此,索性做了一次信息的搬运工,通过微信公众号订阅获取到疫情的实时播报消息:

  • 关注微信公众号“又开车了”;

  • 点击菜单“开始订阅”,并订阅“SARI肺炎疫情播报”。当有信息更新的时候就可以收到一条“审核通知”:

几点说明:
1. 为什么要关注公众号:这是通过微信公众号的模板消息实现的,只有关注公众号,才能定向向你推送疫情消息。
2. 我很反感凭借重大事件蹭热点,大家如果觉得这个工具有用,就关注订阅,如果觉得另有用心,那您就慢走不送,多花时间陪陪家人。

几点思考

2019年是不容易的一年,年终时候一直在尝试突破的事情最终也没能打出实质性的进展。因此,在听了《黑天鹅》和《反脆弱》的书评之后,很快购入了纸质书。这里不写书评,几个感受是:

  • 黑天鹅事件发生的概率比你直觉要高。事件发生的时候,但凡牵涉其中,那就是妥妥的100%。
  • 巴菲特说过,大的机遇永远是稀缺和难以抓住的,但是你可以时刻准备好避大险。
  • 民众的侥幸心理太过普遍。有些人甚至把无知当成无谓和淡定。中国基层工作难做是真的难。如果遇到社区排查登记,请积极配合,即使她的方式有时候显得简单粗暴。
  • 覆巢之下,岂有完卵。有人说2003年的非典成就了阿里,这话不假。今年的疫情,短期也是利好线上经济。但是长期看,一个都跑不了。所以,那些趁着重大事件推销保险的,我求你们消停一下行不行,别拿你必须履行的保险合同当福利发,有种你倒是跟阿里腾讯一样捐几个亿出来呀,如果不想拿出来,那就闭嘴少恶心一点点,OK不OK?
  • 这个时代普遍不愿看书。根本谈不上爱不爱看书,而是给时间给条件,宁愿拿着手机不知所以的刷,有不愿看书。一个朋友圈的细微观察,不一定准确。
  • “幸灾乐祸”小我意识的人并不少。这个没什么好指摘的,也是很多人心里有这种火苗,但肯定是拒绝承认的。当前时代的社会连接说复杂的确复杂,说简单也的确简单。这真的不是什么躲进小楼成一体,管他春夏与秋冬。这次疫情一定会过去,我希望大家都能安全度过,但是过去的时候,你一定会发现身边的很多东西就是跟以前不一样了。