-->
Home | Expand Collapse | OPML | Previous | 2008-07-05 Sat | Next | Blog | Power by Lilina
 123
 123

  2008-07-05 Sat

20:01 小小魔女的早餐 (8238 Bytes) » 萨苏的BLOG
俺家闺女在幼儿园最近过得不错,老师评价写道身体健康,乐于助人,还很有正义感(某老师也有意见,说替小朋友打抱不平可以,但不该拿板凳往老师脑袋上砸。。。)

俺老爸造谣呢。其实,这阶段俺一直过着平静的田园生活,绝对奉行和平主义。


前两天去开家长会,和小小魔女同班同学的家长谈天,说到一个问题,讲他家的小孩儿早上吃饭比较困难,要么不吃,要么一边吃一边和家长发脾气。总之是比较让人头疼的事情。
http://www.cchere.net/article/1691730
当时没有多说,其实心里是比较得意的,因为我家小女早上总是吃得饱饱的,耀武扬威地出门去 – 可能就因为这个原因才有力气打老师的头。

这里面是有一点经验的,或许可以和大家分享。
http://www.cchere.net/article/1691730
其实,所有这个年龄段的小孩,可能都有同样问题。这是因为孩子贪睡,早晨被叫醒以后依然恋床,这个时候他(她)的胃口一般不会好。

那么,怎样让孩子吃好早饭呢?我的经验就是在早餐的种类上下些功夫,至少我家小女,就乖乖的吃到肚儿圆。
http://www.cchere.net/article/1691730
下面,就是萨上个星期某天早上给小家伙准备的早餐,基本是按照这种原则来配置的。

内容大家看明白了吗?

http://www.cchere.net/article/1691730这里面包括如下内容。

1.   主食:草莓果汁软面包一个 (粉色的),柔软颜色刺激食欲,味道略甜略酸。超市买来的,放在那里小家伙自己就会忍不住掰着吃。如果有牛奶,教她蘸着牛奶吃,效果也很好。
http://www.cchere.net/article/1691730
2.   粥:小米粥(船形小碗中黄色的)。我始终认为咱们老祖宗传下来的小米是最养人的。煮小米粥的时间并不需要很长,水中加小米大火煮开,在慢火煮十 几分钟就做好,工序也不复杂。好处是如果时间紧,某爹可以放弃让小小魔女自己练习吃饭,端起粥碗直接灌,小家伙地反应是大快朵颐。时间太紧时我也作玉米面 粥给她吃,就更快了。

3.   蛋:剥皮煮鸡蛋一个,略蘸一点盐。不要认为菜肴越精细小家伙越爱吃。比如,煮鸡蛋如果我给她切碎,拌上盐和香油,小家伙通常没有什么兴趣。如果是完整的鸡蛋,她会自己抓起来大吃特吃,因为她觉得这是件有意思的事情。
http://www.cchere.net/article/1691730
4.   肉:三根小泥肠,切上花刀稍稍用油一煎,样子颇吸引人。但是我每次还要加一道工序,就是给香肠插上牙签。每次小小魔女都是很有兴致地把香肠一根 一根抓来干掉。其实这个灵感是来自小时候有一次看马戏。当时马戏团有个熊猫叫伟伟,会表演吃西餐。其中有一道吃香肠就是把香肠用肉叉叉好放在那里,伟伟一 个一个叉子拿起来,吃得美不够。我想小孩子和小动物比较接近,熊猫有兴趣的吃法小小魔女或许也有兴趣。一试之下,果然。。。

5.   鱼:粉色小盘旁边,金色弯曲状的是炸小鱼。日本普遍销售类似弓鱼的小鱼,日本人拿它来做汤(我们在国内也大多如此)。一次偶然的机会,我发现这 种小鱼放一点盐炸一下,味道酥脆可口,小家伙尤其喜欢。这样,炸小鱼就成了小小魔女早餐的必备小菜。实际上,吃一些这种小鱼,对孩子的骨骼和眼睛发育都很 有好处。
http://www.cchere.net/article/1691730
6.   水果。粉色盘中放的是半个桃子,切成网格块,加上牙签。平时孩子的早餐缺少蔬菜 – 你来个蔬菜沙拉她不认阿。我总觉得营养不够平衡,后来发现补水果是个好办法。一来蔬菜含的营养成分水果也差不多,二来早餐加入水果,孩子会觉得口味有所调 剂,因此容易吃掉,可谓一举两得。通常给小小魔女吃的水果还可选苹果块或草莓,如果没有水果呢,我就给她弄一点黄瓜,切成碧绿的条,效果也不错。

每天给她的早点,大体都是这样,当然有些内容会经常换换花样。我发现她对餐具也很注意的,要是换一个盘子,就会吃得少些,可能是喜欢这个盘子的图案。
http://www.cchere.net/article/1691730
这一天早上小小魔女的战绩是除了四分之一个面包和一点蛋青外,统统消灭光。

小魔女一度担任小小魔女的厨师,两个星期以后决定放弃,她觉得让小家伙多吃,还是我这个当爸爸的有些办法。
http://www.cchere.net/article/1691730
其实经验也是可以总结的,为小家伙准备早餐,我觉得有四个要注意的地方。

第一,   颜色要柔和鲜艳,有吸引力。如果小家伙看了就觉得难以接受,那要他(她)吞到肚子里就如同登天。
http://www.cchere.net/article/1691730
第二,   味道不要太刺激,略带甜味咸味较好,食品不要太硬。因为小家伙刚刚起来,整个身体还在慢慢进入工作状态,太刺激的食物类似冷毛巾擦脸,也不会受欢迎。

第三,   吃法要带有游戏性质,让她觉得有新鲜感,也容易吸引孩子的注意力。
http://www.cchere.net/article/1691730
第四,种类要多,每一种的量要少,从而达到营养平衡的目的。

照这种办法来,一般小东西都会乖乖地亮出小肚皮来,不管它是魔是妖。有兴趣的朋友可以试试。
http://www.cchere.net/article/1691730
[完]

我老爸讲完了,该俺啦。大家可能最近看俺出来得少了,其实这并非本意,每天我爸打电脑我都去给他捣乱,这是因为我是很想念大家的。
http://www.cchere.net/article/1691730
但是,俺老爸说了,俺已经慢慢长大,要三从四德,不适宜抛头露面了,所以,俺也只好低调些。。。

谁叫他管着俺的肚皮呢?县官不如现管阿!那啥杨大哥咋说? -- 人生不如意者,常十九也。。。

http://www.cchere.net/article/1691730
07:01 寻找小强 -- 数据传输故障调查实例 三 (13218 Bytes) » 萨苏的BLOG
看着这排锯齿,老萨一声冷笑,这东西看着眼熟阿。

锯齿的含义就是数据传输不能稳定保持在某个速率,忽快忽慢。这种问题的起因往往是数据传输中丢包造成的线路不稳定。

对啊,想想如果运军火的列车一路上老丢东西,货运单永远对不上号,那整个运输计划能不乱么?这就是铁道游击队厉害的地方。
http://www.talkcc.net/article/1690910
前面处理这个问题的工程师表示他也有同样的看法,但是日本到对端的国际线路上,数据包的传送丢失率很低。

巴嘎,你的,军人的不是,战术的不懂,土八路不在铁路上下手,难道他不会在车站里头截么?
http://www.talkcc.net/article/1690910
一句话惊醒梦中人。这网络上呢,讲究的是铁路警察各管一段 – 比如这位工程师所属的部门,只管国际之间的线路 – WAN,这相当于铁道线;另有部门负责公司内部的网络连接 – LAN,这相当于车站;还有部门专门负责服务器,这相当于军火仓库。这样的分工协作,可以各自发挥专长,但也容易造成缺乏换位思考的现象,

点看全图
接头女:听说鬼子已经盯上车站这块儿。。。  王连举:你是说走私臭豆腐那事儿咱先不干了?
http://www.talkcc.net/article/1690910
虽然数据传递实际上既要跨越国际线路也要通过内部网,任何一段都可能出现丢包,但一般来说,国与国之间的线路出问题,大家想的多半还是国际线路上有没有故 障,因为那毕竟好几千里地呢,从距离上看,公司楼里头的网络基本可以忽略不计。可是如果吃过几次苦头,就会考虑问题是否可能出在公司内部网上。因为虽然国 际线路很漫长,但光缆埋在地底下很少有人会去动它,而公司内部,经常有些多动症的家伙冲着各种设备一直在改,造成种种事端。

点看全图http://www.talkcc.net/article/1690910
李奶奶:小伙子,这影射新浪博克的话儿可不能乱说~~~阿!

甚至,我都能猜测出问题可能出在什么地方。
http://www.talkcc.net/article/1690910
于是萨一个电话把负责内部网的同事也从被窝里拎出来,让他测试相邻设备之间的连结有无问题。这是个大连来的小伙子,刚毕业,处理故障经验不太多,但挺肯干的,几分钟就把结果拿出来了。

这种测试的方法很简单,上一部分说过,公司内部的连结是服务器 –〉Switch -> 防火墙-〉Switch ->路由器。这个测试就是要求他从每个设备对邻居作Ping,来看结果。
http://www.talkcc.net/article/1690910
在路有器和Switch之间的Ping结果有些值得注意的地方,有兴趣的朋友可以看看 – 不是这一行的看不懂也不要紧,注意最后一段就可以了。(我把真正的地址用xxx代替了)

>ping
http://www.talkcc.net/article/1690910
Protocol [ip]:

Target IP address: xxx.xxx.xxx.xxx
http://www.talkcc.net/article/1690910
Repeat count [5]: 123

Datagram size [100]:
http://www.talkcc.net/article/1690910
Timeout in seconds [2]:

Extended commands [n]:
http://www.talkcc.net/article/1690910
Sweep range of sizes [n]:

Type escape sequence to abort.
http://www.talkcc.net/article/1690910
Sending 123, 100-byte ICMP Echos to xxx.xxx.xxx.xxx, timeout is 2 seconds:

!!!.!!!!!.!!!!!!.!!!!!.!!!!!.!!!!!.!!!!!!!!.!!!!!!.!!!!!.!!!!!.!!!!!!!
http://www.talkcc.net/article/1690910
!.!!!!!!!!!!!!.!!!!!.!!!!!!!!.!!!!!!.!!!!!.!!!!!.!!!!

Success rate is 86 percent (106/123), round-trip min/avg/max = 1/3/31 ms

http://www.talkcc.net/article/1690910
问题,就出在加重的部分。网络Ping测试结果中,“!”表示通,“.”表示不通,这个结果说明了什么呢?可以看到123个测试包中只有86%(106个)回应,其他的都被丢弃!据此我判断路由器与Switch之间通信存在问题。

如果是这样,那这条线路上的故障就迎刃而解了 – 远端的数据跋涉千里到达本地的时候并无问题,但通过路由器传递向服务器的时候,在通过Swtich数据交换机时丢包,所以降低了传输质量,引起速度锐减。
http://www.talkcc.net/article/1690910
点看全图
说,皇军饭盒里的臭豆腐,是不是你放的?!

这个结果在我意料之中。路由器和Switch数据交换机都有高速以太网端口,是用网线直接连结的。这种构造的连结上,经常会出现一种错误,结果正是造成丢包。(stam69兄弟提到了这种可能,行家阿)http://www.talkcc.net/article/1690910

什么问题呢?这就是Cisco两台设备之间连结时,端口Duplex参数的设定不匹配错误。

Duplex参数是干什么的呢?它是用来决定网络端口怎样工作的,可以设成三种 – Full(全双工), Half(半双工)和Auto(自动设定)。http://www.talkcc.net/article/1690910

Full全双工的意思是这个口收数据的时候同时也能发数据,是复线铁路,进出互不影响。Half半双工的意思是这个口收数据的时候只能收,发数据的时候只能发,是个单线铁路,效率低一点。

点看全图http://www.talkcc.net/article/1690910
网络端口的全双工和半双工工作方式说明示意图,上面是半双工,下面是全双工


今天大多数网络端口都是全双工的,也有少数只能半双工工作。
http://www.talkcc.net/article/1690910
两个端口相连的时候,双方的工作方式必须一致,你是Full,我也得是Full,你是Half,我也得是Half。

否则双方之间的数据通讯就会大量出现丢包。
http://www.talkcc.net/article/1690910
做IT的里头,象老萨这种棒槌不是很多,大多数干这行的家伙都属于浑身是消息儿,一按就会动,眼睛毛都是空的。假如端口的配置只有Full和Half两种,多半不会有人弄错。那是,跟男浴池女浴池一样,那也能走错么?

问题是Cisco公司比老萨还棒槌,它规定,Duplex的设定呢,除了Full,Half以外,还有一种叫做 – Auto。
http://www.talkcc.net/article/1690910
按照Cisco公司的说法,这Auto(自动设定)可是个好功能。比如你不熟悉端口的技术,弄不清该设Full还是Half的时候,两边就设成Auto,两端的机器会自动将双方之间数据传递的工作方式调整成都是Full或都是Half,于是,双方就可以流畅通信了。

好功能吧?
http://www.talkcc.net/article/1690910
嘿嘿,问题就出在这个“好功能”上。

Auto(自动设定)的这种功能,会让人想当然地认为,既然两端都设成Auto可以,那一端设成Auto,对端设成Full,Auto一端就应该也能把自 己的工作方式调整成Full吧,如果一端设成Auto,对端设成Half,Auto一端也应该能把自己的工作方式调整成Half吧?
http://www.talkcc.net/article/1690910
错!

也不知道Cisco公司怎么想的,按他们的设计,如果对端是Full,自己是Auto的时候,会把工作方式设成Half,如果对端是Half,自己是Auto的时候,会把工作方式设成Full,刚好弄得双方不匹配。
http://www.talkcc.net/article/1690910
怎么拧劲儿怎么来,难道这样设计的老板是吃剑麻长大的?

于是,路由器和Switch连结的时候,往往换个口就会出现大量丢包现象,因为Switch上各个口的工作方式,出厂设置都是Auto,假如路由器设的不是Auto,随便换个口双方会不匹配。
http://www.talkcc.net/article/1690910
这种事情我们排故障的时候遇到很多次了。
点看全图
好你个小强,穿上马甲就以为咱找不着你了?

http://www.talkcc.net/article/1690910看着测试结果我把自己的设想和工程师说了,大家都说太阳底下无新事,八成是这问题。

萨对此也颇为自信,让负责内部网的工程师查查设置。
http://www.talkcc.net/article/1690910
五分钟以后,人家说 – 老大,不对阿,两边设的都是Full…

80%的支持率一下子摔到了零。。。
http://www.talkcc.net/article/1690910
嗯?如果不是工作方式设错了。。。那肯定是网线有问题!

这句话也不全是为了面子,确实有网线使用不当,被重物压坏等事情发生过的,网线受损造成的丢包也会出现同样后果。
http://www.talkcc.net/article/1690910
然而,这样说着,我的眼睛扫过刚刚取下来的网络端口信息,心里往下一沉。

sh int gi0/0 | in err
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignoredhttp://www.talkcc.net/article/1690910
     107527195 packets output, 1536956913 bytes, 0 underruns
     0 output errors, 0 collisions, 0 interface resets
     0 babbles, 0 late collision, 0 deferred

http://www.talkcc.net/article/1690910
如果网线出了问题,根据我的经验,网络端口上应该出现CRC错误报警,而这里CRC错误数居然是0!

点看全图
上当了,小强不在这儿!
http://www.talkcc.net/article/1690910
这就说明网线应该是好的。

可要是都没错,怎么Ping会有那么多丢包呢?http://www.talkcc.net/article/1690910

这时候,有个工程师在说 – “要不,把网线换一根试一下?”

“不行啊,上面还有很多数据在跑,现在可不能换。。。”http://www.talkcc.net/article/1690910

听到这句话,我忽然若有所悟,拿过Switch的工作情况细看。

这一看看出了个沮丧的结论 – 嘿,从一开始我就判断错了!http://www.talkcc.net/article/1690910
点看全图
这回可栽啦!


[待续]http://www.talkcc.net/article/1690910

07:01 浪潮之巅 第九章 硅谷的另一面(四) (6666 Bytes) » Google 黑板报 -- Google 中国的博客网志


1. 成王败寇

2. 嗜血的地方

3. 机会均等

4. 硅含量不断降低

旧金山湾区之所以得名硅谷是因为早期这里的公司大多数是半导体公司或者计算机硬件公司。我们前面介绍的惠普公司虽然不能算是一家半导体公司,但它是以计算机和仪器等硬件为主的公司,可以算是硅谷早期主流公司的代表。但是,最早诞生于硅谷的真正的半导体公司是仙童半导体(Fairchild Semiconductor)。

今天知道仙童公司的人已经不多了,但它在半导体历史上占据着独一无二的地位。仙童半导体公司是从夏克利半导体(Shockley Semiconductor)“叛逃”的科技史上著名的“八叛徒”(Traitorous Eight) 创办的。其中最有名的是后来英特尔公司的创始人、摩尔定理的提出者戈登·摩尔和集成电路的发明人罗伯特·诺伊斯(Robert Noyce)。仙童半导体公司在五十年代末制造出世界第一个商用半导体集成电路。(注释:对于是谁第一个发明集成电路,现在仍有争议,德州仪器公司的专利比仙童的早,但是,仙童是世界上第一个做出了实用产品的)尽管现在仙童公司早已江河日下了,但是每一个计算机用户一定知道它的两个孩子—英特尔公司和 AMD 公司。

自仙童以后,在旧金山湾区诞生了许许多多的半导体公司,包括今天世界上最大的半导体公司英特尔,旧金山湾区从此赢得了硅谷之名。直到八十年代,半导体和计算机硬件一直是硅谷的支柱产业,其中著名的半导体公司还有国家半导体和 Maxim 等公司,而中小公司就更是不计其数了。在九十年代前,硅谷著名的大公司有:惠普,英特尔,Sun,SGI,IBM (Almaden),甲骨文(Oracle),苹果,3Com, Seagate,AMD,国家半导体(National Semiconductor)。其中只有 Oracle 是以计算机软件和服务为主的公司, IBM 的 Almaden 实验室基本上是一半软件(DB2)一半硬件(存储设备),其余都是半导体公司或者计算机硬件公司。这段时间可以称得上是硅谷半导体公司的黄金时代。

但是九十年代后,虽然硅谷的半导体业还在发展,新的半导体公司还在诞生,但是,半导体在硅谷经济中的比重已经大大不如以前了。2000 年后,硅谷最大的公司是思科,谷歌,英特尔,IBM,甲骨文,苹果,惠普,雅虎,基因科技(Genentech)和 Ebay。其中谷歌,雅虎和 Ebay 是互联网公司,IBM 将存储设备部门卖给了日立公司后在 Almaden 是一个纯软件和服务的公司,而基因科技干脆就不是 IT 科技公司,而是世界上最大的生物制药公司。它们都和半导体毫无关系。即使是英特尔,也已经将其工厂迁到美国其它州以及海外,它甚至逐步将研发部门迁到费用低廉的亚利桑那和俄罗冈州。进入二十一世纪后,硅谷在世界经济和科研上的地位有增无减,半导体在全世界经济中所占的分量仍然在增加,只是硅谷的核心产业越来越远离半导体了。

造成硅谷半导体衰退的直接原因有两个,首先是反摩尔定理的效应。由于半导体的价格每十八个月降一半,当一个公司研制出来一个新的芯片以后,它不能指望像制药公司那样随着销量的上升而不断增加利润,因为用不了多少时间,这个芯片的利润就薄得必须淘汰了。整个半导体工业天天都在为利润率发愁。从这个角度讲,半导体工业很难在费用高的硅谷长期发展。我们前面提到,硅谷是一个拒绝平庸的地方,当一个行业的利润率无法维持硅谷高昂的费用时,它就必须搬出硅谷。

其次是“亚洲制造”效应,由于硅谷靠半导体和计算机硬件起飞,在七十年代它便聚集了很多半导体和计算机硬件的专家和工程师。同时,也促进了斯坦福大学和伯克利加大电机工程系的发展。这些人或者从仙童等第一代半导体公司跑出来,或者离开斯坦福和伯克利,开始了第二轮的半导体公司和计算机硬件公司的创业。其中的代表者包括开发和制造 RISC 处理器的 MIPS 公司,Sun 公司和 SGI 公司,以及 LSI 等中大等规模的公司。这些公司大部分还是由美国人为主创办。在第二代公司中有大量亚裔的工程师和主管。他们通过第二轮半导体的创业,积累了财富和经验,其中一些人后来成为世界第三轮半导体公司创业的中流砥柱。等到有大量亚裔专家出来再创办半导体和计算机公司时,他们很容易将制造甚至设计部门移到成本比美国低很多的东亚尤其是中国台湾,而只在硅谷保留科研部门。这时期最有代表性的包括当今世界上最大的显卡公司 Nvidia。其创始人黄仁勋,生于台湾,毕业于斯坦福,任职于 LSI 和 AMD,然后创办 Nvidia。这时在硅谷半导体时代创业最经典的例子。当硬件制造业移到台湾后,半导体业的整体利润就被大大地压缩了,从此改变了半导体和计算机硬件行业的游戏规则。于是以前的半导体公司为了竞争的需要都纷纷将工厂外移。到后来,大家发现一些低端的设计亦可以拿到台湾去做,硅谷的硅含量就越来越低了。

硅谷兴起于半导体工业,三十年前,硅谷就是半导体的同义词。但是现在半导体工业在硅谷的比重在不断下降。世界上很多城市因为一个产业而兴起,比如德国的鲁尔兴起于采煤和炼钢、美国的匹兹堡和底特律分别靠钢铁业和汽车业发达,但是,随着这些工业的饱和和衰落,相应的城市也渐渐衰落了。二十年前,当半导体公司开始离开硅谷时,不少人也怀疑过是否早晚有一天硅谷会步匹兹堡和底特律的后尘,二十年过去了,这种因产业变革带来的地域性衰退并没有在硅谷发生。事实上,没有了半导体,硅谷反而更加繁荣了。

硅谷没有了硅,那么留下了什么呢?

  2008-07-04 Fri

17:20 July 2 Haskell Weekly News Available (456 Bytes) » PLNews: Programming Language News

The July 2, 2008 edition of the Haskell Weekly News is now available. It summarises recent developments and discussion within the Haskell community.



From: July 2 Haskell Weekly News Available

17:18 July 2 Tcl-URL! Now Available (376 Bytes) » PLNews: Programming Language News

The July 2, 2008 edition of the Tcl-URL! is now available. It summarises recent developments within the Tcl community.



From: July 2 Tcl-URL! Now Available

17:16 Frink 2008-07-03 Released (485 Bytes) » PLNews: Programming Language News

Frink 2008-07-03 has been released. Frink is a language which allows for units of measurement to be tracked throughout calculations to help ensure correct answers.

This release includes bug fixes.



From: Frink 2008-07-03 Released

17:15 Kite 1.0b3 Released (524 Bytes) » PLNews: Programming Language News

Kite 1.0b3 has been released. Kite is a small, object-oriented language.

This release includes: support for regular expressions, support for anonymous recursive functions, improved debugging support, more reliable exception handling, and other changes.



From: Kite 1.0b3 Released

17:13 Sleep 2.1 Update 1 Released (535 Bytes) » PLNews: Programming Language News

Sleep 2.1 Update 1 has been released. Sleep is an embeddable scripting language implemented in Java, and inspired by Perl and Objective-C.

This release includes: performance improvements, bug fixes, improved compile-time error checking, and other changes.



From: Sleep 2.1 Update 1 Released

17:11 eTcl 1.0-rc29 Released (651 Bytes) » PLNews: Programming Language News

eTcl 1.0-rc29 has been released. eTcl is a standalone, single-executable distribution of Tcl, supporting a number of platforms and including several popular extensions.

This release includes: the use of Tcl/Tk 8.5.3, new commands in the wce package, support for anti-aliased lines in Pixane, applets to wrap sources into a standalone executable, and other changes.



From: eTcl 1.0-rc29 Released

16:27 Recovering Innodb table Corruption (35438 Bytes) » MySQL Performance Blog

Assume you're running MySQL with Innodb tables and you've got crappy hardware, driver bug, kernel bug, unlucky power failure or some rare MySQL bug and some pages in Innodb tablespace got corrupted. In such cases Innodb will typically print something like this:

InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 7.
InnoDB: You may have to recover from a backup.
080703 23:46:16 InnoDB: Page dump in ascii and hex (16384 bytes):
... A LOT OF HEX AND BINARY DATA...
080703 23:46:16 InnoDB: Page checksum 587461377, prior-to-4.0.14-form checksum 772331632
InnoDB: stored checksum 2287785129, prior-to-4.0.14-form stored checksum 772331632
InnoDB: Page lsn 24 1487506025, low 4 bytes of lsn at page end 1487506025
InnoDB: Page number (if stored to page already) 7,
InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 6353
InnoDB: Page may be an index page where index id is 0 25556
InnoDB: (index "PRIMARY" of table "test"."test")
InnoDB: Database page corruption on disk or a failed

and crash with assertion failure.
So what can you do to recover such a table ?

There are multiple things which can get corrupted and I will be looking in details on the simple one in this article - when page in clustered key index is corrupted. It is worse compared to having data corrupted in secondary indexes, in which case simple OPTIMIZE TABLE could be enough to rebuild it, but it is much better compared to table dictionary corruption when it may be much harder to recover the table.

In this example I actually went ahead and manually edited test.ibd file replacing few bytes so corruption is mild.

First I should note CHECK TABLE in INNODB is pretty useless. For my manually corrupted table I am getting:

SQL:
  1. mysql> CHECK TABLE test;
  2. ERROR 2013 (HY000): Lost connection TO MySQL server during query
  3.  
  4. mysql> CHECK TABLE test;
  5. +-----------+-------+----------+----------+
  6. | TABLE     | Op    | Msg_type | Msg_text |
  7. +-----------+-------+----------+----------+
  8. | test.test | CHECK | STATUS   | OK       |
  9. +-----------+-------+----------+----------+
  10. 1 row IN SET (0.69 sec)

First run is check table in normal operation mode - in which case Innodb simply crashes if there is checksum error (even if we're running CHECK operation). In second case I'm running with innodb_force_recovery=1 and as you can see even though I get the message in the log file about checksum failing CHECK TABLE says table is OK. This means You Can't Trust CHECK TABLE in Innodb to be sure your tables are good.

In this simple corruption was only in the data portion of pages so once you started Innodb with innodb_force_recovery=1 you can do the following:

SQL:
  1. mysql> CREATE TABLE `test2` (
  2.     ->   `c` char(255) DEFAULT NULL,
  3.     ->   `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4.     ->   PRIMARY KEY (`id`)
  5.     -> ) ENGINE=MYISAM;
  6. Query OK, 0 rows affected (0.03 sec)
  7.  
  8. mysql> INSERT INTO test2 SELECT * FROM test;
  9. Query OK, 229376 rows affected (0.91 sec)
  10. Records: 229376  Duplicates: 0  Warnings: 0

Now you got all your data in MyISAM table so all you have to do is to drop old table and convert new table back to Innodb after restarting without innodb_force_recovery option. You can also rename the old table in case you will need to look into it more later. Another alternative is to dump table with MySQLDump and load it back. It is all pretty much the same stuff. I'm using MyISAM table for the reason you'll see later.

You may think why do not you simply rebuild table by using OPTIMIZE TABLE ? This is because Running in innodb_force_recovery mode Innodb becomes read only for data operations and so you can't insert or delete any data (though you can create or drop Innodb tables):

SQL:
  1. mysql> OPTIMIZE TABLE test;
  2. +-----------+----------+----------+----------------------------------+
  3. | TABLE     | Op       | Msg_type | Msg_text                         |
  4. +-----------+----------+----------+----------------------------------+
  5. | test.test | OPTIMIZE | error    | Got error -1 FROM storage engine |
  6. | test.test | OPTIMIZE | STATUS   | Operation failed                 |
  7. +-----------+----------+----------+----------------------------------+
  8. 2 rows IN SET, 2 warnings (0.09 sec)

That was easy, right ?

I also thought so, so I went ahead and edited test.ibd a little more wiping one of the page headers completely. Now CHECK TABLE would crash even with innodb_force_recovery=1

080704 0:22:53 InnoDB: Assertion failure in thread 1158060352 in file btr/btr0btr.c line 3235
InnoDB: Failing assertion: page_get_n_recs(page) > 0 || (level == 0 && page_get_page_no(page) == dict_index_get_page(index))
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even

If you get such assertion failures most likely higher innodb_force_recovery values would not help you - they are helpful in case there is corruption in various system areas but they can't really change anything in a way Innodb processes page data.

The next comes trial and error approach:

SQL:
  1. mysql> INSERT INTO test2 SELECT * FROM test;
  2. ERROR 2013 (HY000): Lost connection TO MySQL server during query

You may think will will scan the table until first corrupted row and get result in MyISAM table ? Unfortunately test2 ended up to be empty after the run. At the same time I saw some data could be selected. The problem is there is some buffering taking place and as MySQL crashes it does not store all data it could recover to MyISAM table.

Using series of queries with LIMIT can be handly if you recover manually:

SQL:
  1. mysql> INSERT IGNORE INTO test2 SELECT * FROM test LIMIT 10;
  2. Query OK, 10 rows affected (0.00 sec)
  3. Records: 10  Duplicates: 0  Warnings: 0
  4.  
  5. mysql> INSERT IGNORE INTO test2 SELECT * FROM test LIMIT 20;
  6. Query OK, 10 rows affected (0.00 sec)
  7. Records: 20  Duplicates: 10  Warnings: 0
  8.  
  9. mysql> INSERT IGNORE INTO test2 SELECT * FROM test LIMIT 100;
  10. Query OK, 80 rows affected (0.00 sec)
  11. Records: 100  Duplicates: 20  Warnings: 0
  12.  
  13. mysql> INSERT IGNORE INTO test2 SELECT * FROM test LIMIT 200;
  14. Query OK, 100 rows affected (1.47 sec)
  15. Records: 200  Duplicates: 100  Warnings: 0
  16.  
  17. mysql> INSERT IGNORE INTO test2 SELECT * FROM test LIMIT 300;
  18. ERROR 2013 (HY000): Lost connection TO MySQL server during query

As you can see I can get rows from the table in the new one until we finally touch the row which crashes MySQL. In this case we can expect this is the row between 200 and 300 and we can do bunch of similar statements to find exact number doing "binary search"

Note even if you do not use MyISAM table but fetch data to the script instead make sure to use LIMIT or PK Rangers when MySQL crashes you will not get all data in the network packet you potentially could get due to buffering.

So now we found there is corrupted data in the table and we need to somehow skip over it. To do it we would need to find max PK which could be recovered and try some higher values

SQL:
  1. mysql> SELECT max(id) FROM test2;
  2. +---------+
  3. | max(id) |
  4. +---------+
  5. |     220 |
  6. +---------+
  7. 1 row IN SET (0.00 sec)
  8.  
  9. mysql> INSERT IGNORE INTO test2 SELECT * FROM test WHERE id>250;
  10. ERROR 2013 (HY000): Lost connection TO MySQL server during query
  11.  
  12. mysql> INSERT IGNORE INTO test2 SELECT * FROM test WHERE id>300;
  13. Query OK, 573140 rows affected (7.79 sec)
  14. Records: 573140  Duplicates: 0  Warnings: 0

So we tried to skip 30 rows and it was too little while skipping 80 rows was OK. Again using binary search you can find out how many rows do you need to skip exactly to recover as much data as possible. Row size can be good help to you. In this case we have about 280 bytes per row so we get about 50 rows per page so not a big surprise 30 rows was not enough - typically if page directory is corrupted you would need to skip at least whole page. If page is corrupted at higher level in BTREE you may need to skip a lot of pages (whole subtree) to use this recovery method.

It is also well possible you will need to skip over few bad pages rather than one as in this example.

Another hint - you may want to CHECK your MyISAM table you use for recovery after MySQL crashes to make sure indexes are not corrupted.

So we looked at how to get your data back from simple Innodb Table Corruption. In more complex cases you may need to use higher innodb_force_recovery modes to block purging activity, insert buffer merge or recovery from transactional logs all together. Though the lower recovery mode you can run your recovery process with better data you're likely to get.

In some cases such as if data dictionary or "root page" for clustered index is corrupted this method will not work well - in this case you may wish to use Innodb Recovery Toolkit which is also helpful in cases you've want to recover deleted rows or dropped table.

I should also mention at Percona we offer assistance in MySQL Recovery, including recovery from Innodb corruptions and deleted data.


Entry posted by peter | 3 comments

Add to: delicious | digg | reddit | netscape | Google Bookmarks

  2008-07-03 Thu

07:01 风邪与桔子汁 » 萨苏的BLOG
07:01 免费在线研讨会:The Google Trifecta » Google 黑板报 -- Google 中国的博客网志

  2008-07-02 Wed

17:18 newLISP 9.4.0 Released » PLNews: Programming Language News
17:16 New Version of Allegro CL 8.1 Express Released » PLNews: Programming Language News
17:14 Smalltalk Solutions 2008 Slides Available » PLNews: Programming Language News
17:13 June 24 to July 1 Caml Weekly News Available » PLNews: Programming Language News
17:12 Tcl/Tk 8.5.3 Released » PLNews: Programming Language News
17:10 CLIS 0.9.0 Released » PLNews: Programming Language News
12:20 书: 人类尸体的有趣故事 » ★兔主席地洞★
10:41 Should we proclaim MySQL Community Edition Dead ? » MySQL Performance Blog

  2008-07-01 Tue

20:01 浪潮之巅 第九章 硅谷的另一面(三) » Google 黑板报 -- Google 中国的博客网志
07:01 与天兵打交道的人 » 萨苏的BLOG
05:08 MySQL 5.1 Stability » MySQL Performance Blog

  2008-06-30 Mon

20:01 让生活搜索走进我们的生活 » Google 黑板报 -- Google 中国的博客网志
17:20 CHICKEN 3.3.0 Released » PLNews: Programming Language News
17:17 Ctalk 0.0.59a Released » PLNews: Programming Language News
17:15 dfsch 0.2.1 Released » PLNews: Programming Language News
12:41 Resyncing table on MySQL Slave » MySQL Performance Blog
06:40 Vala 0.3.4 Released » PLNews: Programming Language News
06:38 GCC UPC 4.2.3.3 Released » PLNews: Programming Language News
06:35 amforth 2.8 Released » PLNews: Programming Language News
06:33 LispForum Announced » PLNews: Programming Language News
06:30 B-Prolog 7.1 Released » PLNews: Programming Language News

  2008-06-28 Sat

23:59 人性 » 猪猡记公园
20:01 日本记者穿越报道赤壁大战 » 萨苏的BLOG
Sources