<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>一个故事@MySQL DBA</title>
	<atom:link href="http://www.orczhou.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.orczhou.com</link>
	<description>一个故事@MySQL DBA</description>
	<lastBuildDate>Wed, 28 Jul 2010 05:05:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>越来越高的墙</title>
		<link>http://www.orczhou.com/index.php/2010/07/the-wall-between-you-and-me/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/the-wall-between-you-and-me/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 05:05:48 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[大千世界]]></category>
		<category><![CDATA[简单生活]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2339</guid>
		<description><![CDATA[<p>随着年龄的增长，随着进入社会的程度越深，随着朋友越来越远，我们越来越倾向于将自己包裹的更严，免受外面的纷杂世事的侵扰。和人来往时，会首先假设对方是有所图的、有恶意，简单的说就是假设对方是“坏人”。如果双方这样的戒心都很深，又没有一方愿意先“示好”，那壁垒就将长存。	言语和表情（统称为“行为表现”）都[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/07/the-wall-between-you-and-me/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>随着年龄的增长，随着进入社会的程度越深，随着朋友越来越远，我们越来越倾向于将自己包裹的更严，免受外面的纷杂世事的侵扰。和人来往时，会首先假设对方是有所图的、有恶意，简单的说就是假设对方是“坏人”。如果双方这样的戒心都很深，又没有一方愿意先“示好”，那壁垒就将长存。	言语和表情（统称为“行为表现”）都是心理活动的表现，当壁垒已经建立，当戒心已经存在，那么都将体现在“行为表现”上。如果一方已经有这样的行为表现，对方也就很难示好了。恶性循环就产生了，墙也就越来越高了。</p>
<p>一般的过程：</p>
<p>	双方戒心 => 建立壁垒 => 更高的戒心 => 更高的壁垒 &#8230;</p>
<p>	双方戒心 => 建立壁垒 => 更高的戒心 => 一方“示好” => 降低戒心 => 一方“示好” => 推开壁垒</p>
<p>	双方戒心 => 一方“示好” => 推开壁垒</p>
<p>这里想说一下我的一个好朋友，也是我研究生阶段的室友李聪。本科时，虽然有一起上的课程，但和李聪基本不认识。有一次需要用移动硬盘，有人告诉我李聪那儿有，后来还是因为李聪人看起来很不友好，所以没有去找他借。是的，当时感觉他看起来很不友好，很多人看起来都很不友好。</p>
<p>后来，研究生在一个方向，住在一个间学生宿舍，一起上讨论班，虽然生活中也还是有很多摩擦，但是有一点是很明确的，他是一个友好的人，对熟悉的朋友如此，对一般认识的人也是如此。不友好只是看起来而已。</p>
<p>两人初识时，壁垒往往是一句言语，一次小事儿，甚至是一个眼神、一个动作导致的。而且这种壁垒一旦建立，想要推开则需要一件大事、一次深入合作、一段很长时间的接触才行。</p>
<p>有时候这种壁垒的建立是无意义的，有时候也确实需要保护自我。如果壁垒已然建立，那么时机合适我愿意首先做“示好”的一方，愿意逐步、更快速的推开壁垒。</p>
<p>如果能有一颗宽容的心，则最好不让壁垒建立，不让戒心滋生。当然这是比较难的，也有一定的风险。</p>
<p>另外，上面说的是人和人之间的交往，如果是和有关部门的话，那完全是另一回事儿了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/the-wall-between-you-and-me/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MySQL/InnoDB源代码：线程并发访问控制(再续)</title>
		<link>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-3/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-3/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 11:19:00 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[代码细节]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2308</guid>
		<description><![CDATA[<p>这是该系列的第三篇文章（<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-1/">1</a>，<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">2</a>）了。之所以选择并发线程控制着手研究InnoDB的代码有两个原因：第一，这段代码相对独立，不要了解太多的相关代码就可以理解；第二，稍微多看一些代码你会发现，到处都是线程并发控制相关的代码出现，所以这也是一个基础。</p>
<p>在<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-1/">第一篇</a>中，介绍了InnoDB内部排他锁的实现，<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">第二篇</a>则介绍InnoDB<strong>内部</strong>读写锁的<strong>实现原理</strong>（这里说的“内部”是为了区别于数据库层面的读写锁）。本篇则将延续<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">第二篇</a>，介绍读写锁相关的代码实现。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-3/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>这是该系列的第三篇文章（<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-1/">1</a>，<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">2</a>）了。之所以选择并发线程控制着手研究InnoDB的代码有两个原因：第一，这段代码相对独立，不要了解太多的相关代码就可以理解；第二，稍微多看一些代码你会发现，到处都是线程并发控制相关的代码出现，所以这也是一个基础。</p>
<p>在<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-1/">第一篇</a>中，介绍了InnoDB内部排他锁的实现，<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">第二篇</a>则介绍InnoDB<strong>内部</strong>读写锁的<strong>实现原理</strong>（这里说的“内部”是为了区别于数据库层面的读写锁）。本篇则将延续<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">第二篇</a>，介绍读写锁相关的代码实现。<span id="more-2308"></span></p>
<div class="myt1">1. 基本数据结构rw_lock_struct</div>
<p>InnoDB读写锁核心的数据结构是rw_lock_struct，下面列出了主要的成员：</p>
<pre>
<div class="mycode">struct rw_lock_struct {
	volatile lint	lock_word;  //标记该读写锁的状态（参考）
	volatile ulint	waiters; //当前是否有等待获取锁的线程
	volatile ibool	recursive; //标记该锁是否被递归获取
	volatile os_thread_id_t	writer_thread; //如果有被以写锁方式获取，则记录该进程ID（为了递归获取）
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
	mutex_t	mutex;		//用来保护lock_word和该结构的
#endif
	......</div>
</pre>
<p>如果理解了前面介绍的读写锁的原理再来看rw_lock_struct的结构，还是比较简单的。相关的初始化和释放函数分别为rw_lock_create_func和rw_lock_free，也都比较简单。</p>
<div class="myt1">2. 读写锁之<strong>读锁</strong></div>
<p>读锁即以共享的方式获取锁。底层实现很简单：先查看lock_word的值获取当前锁的状态，如果当前线程可以获取读锁，则调用函数rw_lock_lock_word_decr以排他方式，更改lock_word的值，读锁即将lock_word减一。rw_lock_lock_word_decr的实现在本系列的<a href="http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/">第二篇</a>中已经介绍了。如果检查lock_word发现当前进程还无法获取读锁（例如，某个线程以写锁方式获取了），则选择空循环一段（spin一段），然后再坚持lock_word。下面是一个读锁获取的示意图：</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4826507887/" title="rw_lock_s_spin by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4139/4826507887_5b657f8268_b.jpg" width="580" height="690" alt="rw_lock_s_spin" /></a></p>
<div class="myt1">3. 读写锁之<strong>写锁</strong></div>
<p>较之读锁，写锁多了一个递归获取，即当前锁是以写方式被获取时，线程需要检查当前锁持有者的线程ID，如果是自己则可以递归获取写锁。</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4827200982/" title="rw_lock_x_spin by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4116/4827200982_cec20ceabb_b.jpg" width="565" height="684" alt="rw_lock_x_spin" /></a></p>
<p>在上面的示意图中，我们可以看到写锁获取时spin时，当spin了一定回合后线程会陷入等待，当其他的线程释放锁时则会广播一次消息，当前线程会被重新唤醒，然后继续spin。</p>
<div class="myt1">4. 小结</div>
<p>这篇文章就贴了这么两张图&#8230;，发现写源代码相关的文章确实很难：如果文字太多了，那么就是介绍原理了；如果代码太多了，难免会枯燥，毕竟大段的代码拆开后就没有了顺畅的感觉，而且有堆页数之嫌（想想毕业论文吧）。这里尝试了一下“流程图+部分代码”的办法，试试。</p>
<p>两张示意图都是放在<a href="http://www.flickr.com/">Flickr</a>上的，功夫网对她很不友好，所以看到原图可能需要翻墙。另外，本网站也存了一份额外的拷贝：<a href="http://www.orczhou.com/wp-content/uploads/2010/07/rw_lock_s_spin.png">图1</a>，<a href="http://www.orczhou.com/wp-content/uploads/2010/07/rw_lock_s_spin.png">图2</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>赤脚游普陀</title>
		<link>http://www.orczhou.com/index.php/2010/07/barefoot-mind-putuo/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/barefoot-mind-putuo/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 07:34:45 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[简单生活]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2295</guid>
		<description><![CDATA[<p>一个人 背包 走</p>
<p>骑车到黄龙，买了到沈家门的车票</p>
<p>收到了很多关于杭州的旅游传单，发现很多地方都还值得再去</p>
<p>想订青旅，早没房间了。去了住哪儿？</p>
<p>上了汽车，思绪乱飞，很多心底的念想都出来了</p>
<p>耳边又想起了《晓之车》</p>
<p>路上很多车，路边有广告牌</p>
<p>田间，两个人骑着车，太阳很大</p>
<p>玩玩《传颂之物》的游戏吧</p>
<p>太阳很大，云很白、很浓，很清晰</p>
<p>想起了工作，MySQL Q3 Q4 我们要做成怎样</p>
<p>一座小山，像是断了一半，露出石头，山另一侧是全是绿树</p>
<p>水塔、烟囱、白云、乱跑的思绪</p>
<p>烈日下，天边的白云如高贵的展览品</p>
<p>绿树很多，到处是。都在享受着烈日炎炎</p>
<p>白云，还是白云，让我想起了古希腊诸神的雕塑</p>
<p>11:58</p>
<p>路边抛锚的汽车、余姚榨菜、“面朝大<strong>湖</strong>，春暖花开”&#8230;</p>
<p>天边的云，越来越近</p>
<p>“为什么你听不见&#8230;” &#8211; - -郑智化</p>
<p><embed src="http://www.xiami.com/widget/318706_79180/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed></p>
<p>五夫大桥</p>
<p>湖 重叠连绵的山 白云  [......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/07/barefoot-mind-putuo/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>一个人 背包 走</p>
<p>骑车到黄龙，买了到沈家门的车票</p>
<p>收到了很多关于杭州的旅游传单，发现很多地方都还值得再去</p>
<p>想订青旅，早没房间了。去了住哪儿？</p>
<p>上了汽车，思绪乱飞，很多心底的念想都出来了</p>
<p>耳边又想起了《晓之车》</p>
<p>路上很多车，路边有广告牌</p>
<p>田间，两个人骑着车，太阳很大</p>
<p>玩玩《传颂之物》的游戏吧</p>
<p>太阳很大，云很白、很浓，很清晰</p>
<p>想起了工作，MySQL Q3 Q4 我们要做成怎样</p>
<p>一座小山，像是断了一半，露出石头，山另一侧是全是绿树</p>
<p>水塔、烟囱、白云、乱跑的思绪</p>
<p>烈日下，天边的白云如高贵的展览品</p>
<p>绿树很多，到处是。都在享受着烈日炎炎</p>
<p>白云，还是白云，让我想起了古希腊诸神的雕塑</p>
<p>11:58</p>
<p>路边抛锚的汽车、余姚榨菜、“面朝大<strong>湖</strong>，春暖花开”&#8230;</p>
<p>天边的云，越来越近</p>
<p>“为什么你听不见&#8230;” &#8211; - -郑智化</p>
<p><embed src="http://www.xiami.com/widget/318706_79180/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed></p>
<p>五夫大桥</p>
<p>湖 重叠连绵的山 白云  <span id="more-2295"></span></p>
<p>买了两块钱的酥饼，就这早上的水。MP3没点了&#8230;</p>
<p>两只鸟飞过，无痕</p>
<p>烟囱 黑烟 白云 水泥</p>
<p>跨海大桥 水是黄的</p>
<p>广告牌：“手把人生方向 脚踏悲欢离合”</p>
<p>城市 道路 哪都一般</p>
<p>下了车，完全不知道这是哪儿</p>
<p>真是哪儿都一样，六个男城管，一个老妪小贩，最后城管拖走了水果车，老妪先是骂骂咧咧，而后，一脸茫然</p>
<p>想买地图，没买到</p>
<p>问路，坐公交到码头，买到了地图，半生洞码头</p>
<p>上了船，据说这里是：“观音过此不肯去”</p>
<p>到了一个农家旅店，100元/天，出去走走</p>
<p>荡秋千也会头晕&#8230;对面有个小海滩，人很少，面朝大海，想到童年</p>
<p>耳边又海浪声，脚下有沙滩，手上有凉鞋</p>
<p>看着海浪打到脚上</p>
<p>有个亭子叫：“自在”</p>
<p>有一位朋友的帽子被风吹掉了</p>
<p>路上遇到很多僧人</p>
<p>脚在沙滩上踩过一串足迹 海浪又很快将它冲掉</p>
<p>“海天万里”</p>
<p>从海边到普济禅寺 途经一井 又遇一僧</p>
<p>普济禅寺 大圆通殿 文殊 伽蓝 普贤 地藏王 大雄 积善堂</p>
<p>三洲感应 般若波罗蜜多心经 观自在菩萨</p>
<p>太阳落下 月亮升起</p>
<p>秋千 海 月亮 这里让我想家</p>
<p>=+=+=+=+=</p>
<p>喝碗粥 继续走</p>
<p>“度一切苦厄”</p>
<p>艳阳下的海，远处一艘船，偶尔看到一两个礁石</p>
<p>“南海观音” “观音跳”</p>
<p>观音像很高，离白云很近</p>
<p>周围的导游有点口干&#8230;</p>
<p>看到一个牌子上写着“禁止喇嘛”，再仔细一看是“禁止鸣喇叭”</p>
<p>很多人在烧香，而且很多年轻人，他们应该先求己</p>
<p>很多人在向炉子里投硬币，他们是来旅游的</p>
<p>看见有的石狮下写着：“谁谁谁敬制、供养”，想起了一句话：有心为善 虽善不赏 无心为恶 虽恶不罚</p>
<p>今天所有的人都穿了鞋，除了我</p>
<p>玄奘西行：破格剃度 表请西行 高昌留阻 为法忘躯 参谒名师 周游天竺 破邪显正 名震五印 无遮大会 返还祖国 大宗召见 译经伟业 见性成佛</p>
<p>“樂助一萬元以上五萬元以下功德芳名”</p>
<p>鑒真東渡：精研律學 名貫江淮 &#8230;</p>
<p>大理石板上，不怎么烫</p>
<p>观音像：面色平和</p>
<p>有一个老者，每步一拜</p>
<p>南海观音道场</p>
<p>这里供了很多花，引来了蜜蜂</p>
<p>入清凉地 勿自暴 勿自弃 圣与贤 可驯致</p>
<p>恩欲报怨欲忘 报怨短报恩长</p>
<p>凡出言 信为先 诈与妄 奚可焉</p>
<p>茅屋两三间 草草蔽风雨 客来不入门 坐爱千年树 （又一首好寺被“坐爱”毁了）</p>
<p>西方净苑</p>
<p>普陀礼观音 上海看世博（这句话把观音身份降到了什么程度&#8230;）</p>
<p>路遇一小孩，问爸爸：“那个人为什么不穿鞋”。我喜欢小孩，因为他们也是想到什么就说什么</p>
<p>到码头了，又得穿鞋了</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/barefoot-mind-putuo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>何时背起行囊</title>
		<link>http://www.orczhou.com/index.php/2010/07/it-is-the-time-for-a-relax-1/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/it-is-the-time-for-a-relax-1/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 15:54:52 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[简单生活]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2273</guid>
		<description><![CDATA[<p>晚上<a href="http://blog.sina.com.cn/intootherain">博宇</a>聊了一会儿天，又勾起了旅行的欲望：</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4787091046/" title="小镇 by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4078/4787091046_b14f43a928.jpg" width="500" height="375" alt="小镇"></a></p>]]></description>
			<content:encoded><![CDATA[<p>晚上<a href="http://blog.sina.com.cn/intootherain">博宇</a>聊了一会儿天，又勾起了旅行的欲望：</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4787091046/" title="小镇 by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4078/4787091046_b14f43a928.jpg" width="500" height="375" alt="小镇"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/it-is-the-time-for-a-relax-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manage MySQL With Open Source</title>
		<link>http://www.orczhou.com/index.php/2010/07/manage-mysql-with-open-source/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/manage-mysql-with-open-source/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 19:14:13 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2204</guid>
		<description><![CDATA[<p>上次在一个“<a href="http://www.taobaodba.com/html/459_db_conference_pic_info.html">数据库技术论坛</a>”上分享MySQL管理方面的一些经验，这里把PPT分享一下：</p>
<div style="width:425px" id="__ss_4556719"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/orczhou/manage-mysql-with-open-source" title="Manage MySQL with open source">Manage MySQL with open source</a></strong><object id="__sse4556719" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=managemysqlwithopensource-100620074016-phpapp01&#038;rel=0&#038;stripped_title=manage-mysql-with-open-source" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4556719" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=managemysqlwithopensource-100620074016-phpapp01&#038;rel=0&#038;stripped_title=manage-mysql-with-open-source" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>- -EOF- -</p>]]></description>
			<content:encoded><![CDATA[<p>上次在一个“<a href="http://www.taobaodba.com/html/459_db_conference_pic_info.html">数据库技术论坛</a>”上分享MySQL管理方面的一些经验，这里把PPT分享一下：</p>
<div style="width:425px" id="__ss_4556719"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/orczhou/manage-mysql-with-open-source" title="Manage MySQL with open source">Manage MySQL with open source</a></strong><object id="__sse4556719" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=managemysqlwithopensource-100620074016-phpapp01&#038;rel=0&#038;stripped_title=manage-mysql-with-open-source" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4556719" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=managemysqlwithopensource-100620074016-phpapp01&#038;rel=0&#038;stripped_title=manage-mysql-with-open-source" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>- -EOF- -</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/manage-mysql-with-open-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL/InnoDB源代码：线程并发访问控制(续)</title>
		<link>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/</link>
		<comments>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 14:45:55 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[代码细节]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Source Code]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2215</guid>
		<description><![CDATA[<p><a href="http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/">前面</a>做了一个开始，沿着路慢慢走下去。</p>
<div class="myt1">0. 起源</div>
<p>开始之前，这里可以说说这次准备开始研究源代码的一个很大诱因了。前一段时间在生产环境遇到了一个InnoDB报错，这个错误甚至会导致InnoDB Crash：</p>
<div class="mycode">InnoDB: Warning: a long semaphore wait:<br />
&#8211;Thread 1222654272 has waited at ./include/btr0btr.ic line 53 for 241.00 seconds the semaphore:<br />
S-lock on RW-latch at 0x2aaab510b818 created in file buf/buf0buf.c line 680</div>
<p>沿着这里的线索 buf/buf0buf.c line 680  找到了：</p>
<div class="mycode">678	mutex_create(&#038;block->mutex, SYNC_BUF_BLOCK);<br />
679<br />
680	rw_lock_create(&#038;block->lock, SYNC_LEVEL_VARYING);<br />
681	ut_ad(rw_lock_validate(&#038;(block->lock)));</div>
<p>继续，就开始看rw_lock_create的实现，然后感觉需要看更多基础的一点的内容，这样就有了前面一片文章，继续研究，就有了现在的这篇文章。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/">前面</a>做了一个开始，沿着路慢慢走下去。</p>
<div class="myt1">0. 起源</div>
<p>开始之前，这里可以说说这次准备开始研究源代码的一个很大诱因了。前一段时间在生产环境遇到了一个InnoDB报错，这个错误甚至会导致InnoDB Crash：</p>
<div class="mycode">InnoDB: Warning: a long semaphore wait:<br />
&#8211;Thread 1222654272 has waited at ./include/btr0btr.ic line 53 for 241.00 seconds the semaphore:<br />
S-lock on RW-latch at 0x2aaab510b818 created in file buf/buf0buf.c line 680</div>
<p>沿着这里的线索 buf/buf0buf.c line 680  找到了：</p>
<div class="mycode">678	mutex_create(&#038;block->mutex, SYNC_BUF_BLOCK);<br />
679<br />
680	rw_lock_create(&#038;block->lock, SYNC_LEVEL_VARYING);<br />
681	ut_ad(rw_lock_validate(&#038;(block->lock)));</div>
<p>继续，就开始看rw_lock_create的实现，然后感觉需要看更多基础的一点的内容，这样就有了前面一片文章，继续研究，就有了现在的这篇文章。<span id="more-2215"></span></p>
<div class="myt1">1. 读写锁</div>
<p>前文介绍了，InnoDB中如何使用mutex_struct结构来保护内存（变量）。我们可以看到，如果使用mutex_struct时，其实实现的是一个排他锁。如果每个变量可以被允许并发共享（只读）访问，写的时候才需要“排他”访问的话，再用mutex_struct的话就不合适了。所以，InnoDB在mutex_struct的基础上，又实现了一个<strong>读写锁</strong>。</p>
<p>本文中&#8221;共享锁&#8221;即&#8221;读锁&#8221;，&#8221;排他锁&#8221;即&#8221;写锁&#8221;。关于读写锁的基本知识这里就不再介绍了。先说说InnoDB的实现原理，再来看细节。InnoDB使用了一个整数来标记当前锁的状态。</p>
<div class="myt1">2. 读写锁 InnoDB实现机制</div>
<p>InnoDB用了一个很简单的读写锁实现机制，使用一个整型变量lock_word标志当前锁的状态：</p>
<div class="mycode">struct rw_lock_struct {<br />
	volatile lint	<strong>lock_word</strong>; 	/*!< Holds the state of the lock. */</div>
<p>初始化时，lock_word的值为1048576（0&#215;00100000），当每一个线程获得一次读锁时，lock_word值减一。每次获取写锁时，lock_word的值则减少1048576。这样，每次根据lock_word当前值，就可以获取当前锁的状态了。下面是关于lock_word规则的详细说明：</p>
<div class="myt2">1） lock_word初始值为X_LOCK_DECR（#define X_LOCK_DECR	 0×00100000 //1,048,575）</div>
<div class="myt2">2） 每一线程以读（共享）的方式获取该锁，则lock_word减1</div>
<div class="myt2">3） 每次线程以写（排他）的方式获取锁，则lock_word减X_LOCK_DECR</div>
<div class="myt2">4） 如果某线程以写（排他）方式获得锁，该线程仍可以以递归的方式获得该写锁</div>
<div class="myt2">5） 如果线程在等待获取写锁，lock_word减X_LOCK_DECR，<strong>且这样可以阻止线程再获得读锁</strong></div>
<div class="myt2">6） 写锁虽然可以递归获取，但是读锁不能递归获取</div>
<p>根据上面的规律，我们就可以推导出，lock_word取不同区间的值时，当前锁的状态。例如当0&lt;lock_word&lt;X_LOCK_DECR时，当前锁以读的方式被获取，下面是lock_word不同区间值锁的状态表：</p>
<div class="myt2">1） lock_word == X_LOCK_DECR   则锁处于初始状态，即没有任何线程获得该锁</div>
<div class="myt2">2） 0 < lock_word < X_LOCK_DECR  则锁处于读锁状态，读锁持有者个数为X_LOCK_DECR-lock_word；且并没有任何写锁处于等待状态</div>
<div class="myt2">3） lock_word == 0  则锁处于写锁状态</div>
<div class="myt2">4） -X_LOCK_DECR < lock_word < 0  则锁处于读锁状态，且有一个线程在等待写锁。-lock_word就是读锁的个数</div>
<div class="myt2">5） lock_word <= -X_LOCK_DECR  则当前锁处于“递归写锁”（同一个线程多次获得该写锁）状态，写锁的个数是((-lock_word) / X_LOCK_DECR) + 1</div>
<p>这里看到，当线程需要获取该锁（读、写）的时候，根据lock_word值即可以判断当前锁的状态，也就可以知道自己是否可以获得锁。</p>
<div class="myt1">3. 关于递归写锁</div>
<p>lock_word基本上包含了锁的全部状态，但是如果细心的话，你会发现有一个例外：当一个线程A需要获得写锁的时候，lock_word的如果是写锁状态时，线程A还必须知道当前持有该锁的线程ID，如果持有锁的线程就是自己，则线程A可以获得写锁。所以，rw_lock_struct结构中还有另一个成员变量：</p>
<div class="mycode">volatile os_thread_id_t	writer_thread;</div>
<p>当锁以排他方式被持有的时候，该变量记录持有者的线程ID。</p>
<p>如果细心，你还可能发现，这里虽然提到了“递归写锁”，却没有提到“递归读锁”。在InnoDB的读写锁实现时，并不考虑读锁的递归，如果锁被排他方式获取，即使是同一个线程，仍然无法获取读锁。</p>
<div class="myt1">4 .lock_word的一致性</div>
<p>在读写锁的实现中，lock_word的可以“举足轻重”。这就要求每次对lock_word的修改都要做到“一致”。否则，这把锁就坏了。</p>
<div class="myt2">4.1 什么是一致性</div>
<p>如果是单线程，获取读锁我们可能写出下面的代码：</p>
<div class="mycode">if(local_lock_word > 0){<br />
    local_lock_word = local_lock_word -1;<br />
}
</div>
<p>上面的代码，在多线多处理环境是不安全的，会导致lock_word的不一致。线程A需要获取读锁，则CPU在执行上面代码的时候，首先获取local_lock_word的值将其载入寄存器，然后运算，然后返回到内存。如果在“载入寄存器之后运算之前”，lock_word的值发生了改变（例如另一个线程B成功获取了读锁），而这时当前线程A却不知道，线程A仍然把自己的值回写到内存，则会覆盖线程B对lock_word的修改。lock_word的值就不一致了，等锁全部释放后，lock_word的值就可能不是X_LOCK_DECR。</p>
<p>上面这段话可能有点绕，简单的说：多线程并发时，上面简单的赋值操作是不可靠的。回想一下多线程，就不难理解上面这段话了。</p>
<div class="myt2">4.2 InnoDB如何保证lock_wrod的一致性</div>
<p>介绍完了前面那么多原理，这里总算可以看看源代码的一些东西了。InnoDB封装了函数rw_lock_lock_word_decr来实现对lock_wrod的一致操作。InnoDB会根据不同的编译环境，决定使用不同的策略。简单地，InnoDB使用了前面介绍的mutex_t（排他锁）来实现lock_word的一致操作，即在操作之前获取排他锁；另外，InnoDB根据不同的CPU平台还可以使用<a href="http://en.wikipedia.org/wiki/Compare-and-swap">Compare-And-Swap</a>来实现，下面来看看源码：</p>
<p>这里是核心代码，详细参考sync0rw.ic文件</p>
<pre>
<div class="mycode">ibool rw_lock_lock_word_decr(rw_lock_t*	lock, ulint amount)
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
	while (local_lock_word > 0) {
		if (<font color="blue">os_compare_and_swap_lint</font>(&#038;lock->lock_word,local_lock_word,local_lock_word - amount)) {
			return(TRUE);
		}
		local_lock_word = lock->lock_word;
	}
	return(FALSE);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
	ibool success = FALSE;
	<strong><font color="blue">mutex_enter(&#038;(lock->mutex));</font></strong>
	if (lock->lock_word > 0) {
		lock->lock_word -= amount;
		success = TRUE;
	}
	<strong><font color="blue">mutex_exit(&#038;(lock->mutex));</font></strong>
	return(success);
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}</div>
</pre>
<p>有了<a href="http://en.wikipedia.org/wiki/Compare-and-swap">Compare-And-Swap</a>或者排他锁(<a href="http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/">前文</a>的mutex_t)的保证，InnoDB就可以一致的更改锁的状态（lock_word）了。</p>
<div class="myt1">5. 再休息一下</div>
<p>这篇文章算是介绍了一下InnoDB读写锁的实现机制，本来想把具体实现也写了，发现作为一篇博<del datetime="2010-07-06T09:04:48+00:00">客</del>文是有点长了，而且已经非常的晦涩难懂了。所以暂时休息一下，欲知后事如何，且听下回分解。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/07/mysql-innodb-source-code-sync-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MySQL/InnoDB源代码：线程并发访问控制</title>
		<link>http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/</link>
		<comments>http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 03:51:24 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[代码细节]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Source Code]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2173</guid>
		<description><![CDATA[<p>作为DBA关心的更多的可能是原理、机制，对于源码一般大家也不是特别关心，也不太用得上。而且对于对于源代码级别的细节也很难用文字表达自己的理解，最终理解必须还是需要自己去看看每一行代码到底是怎样的。也读过《Understanding.MySQL.Internals》的大部分章节，作者也是偏重于从代码的实现目的（原理、机制）来介绍的，国内的《MySQL核心内幕》（个人对于“核心内幕”这个词有莫名的反感）算是更多的从源码开始介绍MySQL了，可是这本书也许是授予篇幅的限制，介绍的东西也并不多。</p>
<p>开始写这篇文章，不能期待自己能写多少，也不能期待自己能研究多少，不过至少走出了自己探索的第一步。文章的宗旨不在于能够多么细致的分析MySQL的源代码，而是希望能给自己，能给他人打开走向源代码的第一道门。</p>
<p>我是BNU数学系毕业的，对C语言知道甚少，C语言的经历大概就是“计算方法”课程中实现的求解各种方程的撇脚程序了。所以虽然我会极力避免错误，但是相信还是会犯一堆错误，希望各位看官能够宽容点，有错误指出来，慢慢改正。</p>
<div class="myt1">0. 开始</div>
<p>InnoDB的代码通过宏定义考虑很多平台的兼容问题，这里分析的主要是类Unix/Linux平台（POSIX标准）的代码段，所以下面的很多代码段也是删除相关兼容性代码的。本文InnoDB源码是Plugin1.0.6版本。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>作为DBA关心的更多的可能是原理、机制，对于源码一般大家也不是特别关心，也不太用得上。而且对于对于源代码级别的细节也很难用文字表达自己的理解，最终理解必须还是需要自己去看看每一行代码到底是怎样的。也读过《Understanding.MySQL.Internals》的大部分章节，作者也是偏重于从代码的实现目的（原理、机制）来介绍的，国内的《MySQL核心内幕》（个人对于“核心内幕”这个词有莫名的反感）算是更多的从源码开始介绍MySQL了，可是这本书也许是授予篇幅的限制，介绍的东西也并不多。</p>
<p>开始写这篇文章，不能期待自己能写多少，也不能期待自己能研究多少，不过至少走出了自己探索的第一步。文章的宗旨不在于能够多么细致的分析MySQL的源代码，而是希望能给自己，能给他人打开走向源代码的第一道门。</p>
<p>我是BNU数学系毕业的，对C语言知道甚少，C语言的经历大概就是“计算方法”课程中实现的求解各种方程的撇脚程序了。所以虽然我会极力避免错误，但是相信还是会犯一堆错误，希望各位看官能够宽容点，有错误指出来，慢慢改正。</p>
<div class="myt1">0. 开始</div>
<p>InnoDB的代码通过宏定义考虑很多平台的兼容问题，这里分析的主要是类Unix/Linux平台（POSIX标准）的代码段，所以下面的很多代码段也是删除相关兼容性代码的。本文InnoDB源码是Plugin1.0.6版本。<span id="more-2173"></span></p>
<div class="myt1">1. InnoDB多线程并发访问</div>
<p>MySQL是一个多线程的实现的<a href="http://en.wikipedia.org/wiki/Database_management_system">DBMS</a>，多线程编程需要解决的一个重要问题就是线程间并发访问的控制。一般某个线程更改需要更改某个内存块（变量）时，首先要先将数据从内存读取到寄存器，然后计算更改之，最后回写到内存块。如果有<strong>多个线程同时</strong>在修改内存块，而且读取同时（“同时”表示在两个线程修改该值之前读取）发生，那么两个线程将有一个会丢失修改。</p>
<p>所以，希望保持内存数据（变量）“一致”、“准确”时，线程在操作这些变量时，需要先获取对应的锁。利用各个变量对应的“锁机制”来保证数据访问的并发控制。</p>
<div class="myt1">2. 基本原理：Posix thread</div>
<p>多线程并发访问控制中，InnoDB使用标准<a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html">POSIX线程模型</a>中的mutex（condition variable）实现基本的排他访问。在对mutex（condition variable）的封装的基础上，又实现了相应的读写锁。</p>
<div class="myt2">2.1 os_fast_mutex_t VS pthread_mutex_t</div>
<p>pthread_mutex_t封装在os_fast_mutex_t中，condition variable则封装在了os_event_struct中。</p>
<div class="mycode">typedef pthread_mutex_t	os_fast_mutex_t;</div>
<p>对应的mutex操作分别封装在了os_fast_mutex_init / os_fast_mutex_lock / os_fast_mutex_unlock / os_fast_mutex_free中，这里我们看看os_fast_mutex_trylock的封装函数实现：</p>
<pre>
<div class="mycode">ulint os_fast_mutex_trylock(
	os_fast_mutex_t*	fast_mutex)
{
#ifdef __WIN__
	EnterCriticalSection(fast_mutex);
	return(0);
#else
	return((ulint) pthread_mutex_trylock(fast_mutex));
#endif
}</div>
</pre>
<div class="myt2">2.2 os_event_struct VS condition variable</div>
<p>Condition variable较之pthread_mutex_t要复杂一点，对应的封装也更复杂。os_event_struct封装了condition variable全部操作，主要包括初始化，陷入等待，广播唤醒：os_event_create（初始化）/os_event_wait_low（等待）/os_event_set（广播唤醒）。下面是基本数据结构struct os_event_struct：</p>
<pre>
<div class="mycode">struct os_event_struct {
	os_fast_mutex_t	os_mutex;
	ibool		is_set;
	ib_longlong	signal_count;
	pthread_cond_t	cond_var;	/* condition variable is used in
					waiting for the event */
        ......
};</div>
</pre>
<p>这里抽取一个广播唤醒开函数os_event_set看看：</p>
<pre>
<div class="mycode">void os_event_set(
	os_event_t	event)	/*!< in: event to set */
{
	os_fast_mutex_lock(&#038;(event->os_mutex));
	if (event->is_set) {
		/* Do nothing */
	} else {
		event->is_set = TRUE;
		event->signal_count += 1;
		ut_a(0 == <strong>pthread_cond_broadcast</strong>(&#038;(event->cond_var)));
	}
	os_fast_mutex_unlock(&#038;(event->os_mutex));
}</div>
</pre>
<p>可以看到上面函数，没有什么神秘的地方，就是判断了一下是否需要广播，然后调用了pthread_cond_broadcast函数广播。</p>
<p>数据结构os_fast_mutex_t和os_event_t看到，InnoDB并不是那么复杂，但是需要对Linux（或者说POSIX）有一定的理解。</p>
<p>另外，算是最底层的数据结构，事实上，这个封装还没结束，InnoDB其他模块中用的较多的是mutex_struct和rw_lock结构，mutex_t是对os_event_t封装，rw_lock是对mutex_t的封装。</p>
<div class="myt1">3. 前奏：mutex_struct</div>
<div class="myt2">3.1 mutex_struct的一般说明</div>
<pre>
<div class="mycode">struct mutex_struct {
	os_event_t	event;	/* Used by sync0arr.c for the wait queue */
	ulint	lock_word;	/* This ulint is the target of the atomic
				test-and-set instruction in Win32 */
	ulint	waiters;	//如果有线程在等待，设置为1
	UT_LIST_NODE_T(mutex_t)	list;
	const char*	cfile_name;/* File name where mutex created */
	ulint		cline;	/* Line where created */
#ifndef UNIV_HOTBACKUP
	ulong		count_os_wait; /* count of os_wait */
#endif /* !UNIV_HOTBACKUP */
};</div>
</pre>
<p>mutex_struct相关的函数有很多，一般需要使用的有：mutex_create、mutex_enter、mutex_exit；还有一些其他的函数：mutex_spin_wait、mutex_free、mutex_signal_object。</p>
<div class="myt2">3.2 mutex_struct的典型用法</div>
<p>InnoDB中一个典型的mutex_struct使用如下：</p>
<pre>
<div class="mycode">mutex_create(&#038;rw_lock_list_mutex);
mutex_enter(&#038;rw_lock_list_mutex);
...
//这里，对rw_lock_list_mutex所保护的对象，这里可以进行一致的、排他操作
...
mutex_exit(&#038;rw_lock_list_mutex);</div>
</pre>
<p>mutex_create函数相对简单，做了一些初始化的工作。我们继续沿着线索来看看mutex_enter的实现。这个函数实现：</p>
<pre>
<div class="mycode">typedef struct mutex_struct		mutex_t;
void mutex_enter_func(
	mutex_t* mutex, const char*  file_name, ulint  line)
{
	ut_d(mutex->count_using++);
	if (!mutex_test_and_set(mutex)) {
		ut_d(mutex->thread_id = os_thread_get_curr_id());
		return;	/* Succeeded! */
	}
	mutex_spin_wait(mutex, file_name, line);
}</div>
</pre>
<p>代码说明：首先，尝试使用mutex_test_and_set（这是对os_fast_mutex_trylock的封装）获得锁，成功则返回。失败，则调用mutex_spin_wait陷入“spin lock的方式”获取锁。spin lock的方式是指，自己不释放cpu资源，而是自己空循环一段时间后，在重新尝试获取锁。</p>
<div class="myt2">3.3 继续深入：mutex_spin_wait</div>
<p>线索到了mutex_spin_wait了，该函数是InnoDB里面实现了spin lock的主要部分。这里简单介绍一下原理：首先线程检查lock_word，如果被设置0（表示当前并没有变量并没有被锁住），则直接调用mutex_test_and_set（其实是os_fast_mutex_trylock）来尝试获取锁。如果lock_word=1那么，则表示当前的锁已经被某个线程获取，则线程进入空循环，延迟一段时间（spin lock），等待lock_word被设置为0后，立刻调用mutex_test_and_set尝试获取锁。如果lock_word一直1（锁一直在被占用），那么线程将在延迟SYNC_SPIN_ROUNDS个单位时间后，线程将尝试调用mutex_test_and_set一次（碰运气），如果仍失败，这时线程将陷入等待（这时Condition variables开始登上舞台），如果其他线程释放该锁，则会将lock_word被设置为0，并进行一次广播，那么前面陷入等待的线程将会被唤醒，并重新调用mutex_test_and_set尝试获取锁。</p>
<p>下面是mutex_spin_wait的一个简单流程图：</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4748692857/" title="mutex_spin_wait_v3 by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4121/4748692857_19d8c453be.jpg" width="500" height="449" alt="mutex_spin_wait_v3"></a></p>
<div class="myt2">3.4 小结mutex_struct</div>
<p>再回头看看mutex_struct的一般使用方法，先是mutex_create，然后是mutex_enter，最后是mutex_exit，该函数会调用os_event_set进行一次广播（广播函数本身是会释放pthread_mutex_t的）。</p>
<div class="myt1">4. 休息一会儿</div>
<p>至此，我们看到，InnoDB一般通过数据结构mutex_struct来实现对内存块（变量）的完全排他访问。如果只是排他访问，可能会导致效率较低，因为很多时候，不需要排他，只需要共享方式访问就可以了。InnoDB在mutex_struct基础上，再做了一次封装，对应的数据结构为rw_lock_struct。</p>
<p>好了，这篇文章已经够长了&#8230;.欲知后事如何，且听下回分解。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/06/mysql-innodb-source-code-sync-1/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Move On</title>
		<link>http://www.orczhou.com/index.php/2010/06/worldcup-england-vs-germany/</link>
		<comments>http://www.orczhou.com/index.php/2010/06/worldcup-england-vs-germany/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 16:41:56 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[简单生活]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2162</guid>
		<description><![CDATA[<p>球场上充满了戏剧性。“德国队 VS 英格兰”，这是第三场16进8的淘汰赛，也是目前为止世界杯最精彩的比赛，尤其是上半场。</p>
<p>在德国进两球领先的情况下，英格兰于37分钟打入一球，扳为二比一。戏剧性的事情发生在了39分钟，兰帕德一脚远射，足球先打在了德国队上门柱内侧，足球完全弹入球门（足球全部越过球门线）[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/06/worldcup-england-vs-germany/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>球场上充满了戏剧性。“德国队 VS 英格兰”，这是第三场16进8的淘汰赛，也是目前为止世界杯最精彩的比赛，尤其是上半场。</p>
<p>在德国进两球领先的情况下，英格兰于37分钟打入一球，扳为二比一。戏剧性的事情发生在了39分钟，兰帕德一脚远射，足球先打在了德国队上门柱内侧，足球完全弹入球门（足球全部越过球门线），足球弹在地上后又弹向球门外，守门员立刻拿住球，并发出。主裁判和边裁都没有看清楚足球是否入网，裁判并没有判这个进球有效。</p>
<p>比分从一比零，到二比零，到二比一，再到这个误判。由于这个误判，英格兰失去了扳平比分的机会。在电视机前的我，也为裁判的判罚“捶胸顿足”，同时也为英格兰惋惜。&#8221;英格兰这个球真冤。。。&#8221;，“倒霉的英格兰，进球被裁判看错了”，“这个球裁判漏洞太过了……助理裁判是罪人啊”，“如果今晚德国是 2:1 取胜，或者谁最终一球取胜，英格兰球迷得疯掉”，很多人都在为英格兰喊冤。当时，愤愤不平的我大喝了一口果汁，接着继续骂骂咧咧，抱怨着这个不公平的世界。</p>
<p>比赛还在继续，二比一进入下半场。这个比分对英格兰来说，也并没有那么糟，事实上，英格兰队下半场发挥都还是正常的：鲁尼还在游走，杰拉德有两脚远射（有点唐突），后防线状态还是那么“放松”。</p>
<p>在67分钟、70分钟德国队穆勒打入两粒精彩而毫无争议的进球，把比分扩大为四比一，比分也延续到了终场。</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4738545579/" title="Germany VS England by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4135/4738545579_621a055609.jpg" width="500" height="47" alt="Germany VS England"></a></p>
<p>人生亦如此。</p>
<p>引用Twitter上的一段话，结束本文：</p>
<p><a href="http://twitter.com/orczhou">@orczhou</a>: 想起了《Lost》中一句经典台词Let it go and move on RT <a href="http://twitter.com/buzhoushan">@buzhoushan</a>: 这是她们的借口RT <a href="http://twitter.com/ryangato">@ryangato</a> 对英国佬来说还是比较重要的 RT <a href="http://twitter.com/orczhou">@orczhou</a>: 上半场的那个误判已经不那么重要了</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/06/worldcup-england-vs-germany/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于紧张</title>
		<link>http://www.orczhou.com/index.php/2010/06/about-nervous/</link>
		<comments>http://www.orczhou.com/index.php/2010/06/about-nervous/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 13:03:56 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[简单生活]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2141</guid>
		<description><![CDATA[<p>昨天，在一个<a href="http://www.taobaodba.com/html/448_dba_fourm.html">数据库技术论坛</a>上做了一个小的<a href="http://www.slideshare.net/orczhou/manage-mysql-with-open-source">分享</a>，在台上大概“扯”了大约40分钟吧，效果还不错，不过印象最深的是上台分享前的紧张心理。</p>
<p>技术论坛中来了很多数据库方面的大牛，还有很多每天一起工作的同事，我的分享是在下午4点半左右。上午的时候，还没有任何的紧张心理，到下午了便开始紧张了，越是接近我上场时越是紧张。外表虽然仍很冷静，不过自己清晰地感觉到逐渐加快的心率。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/06/about-nervous/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>昨天，在一个<a href="http://www.taobaodba.com/html/448_dba_fourm.html">数据库技术论坛</a>上做了一个小的<a href="http://www.slideshare.net/orczhou/manage-mysql-with-open-source">分享</a>，在台上大概“扯”了大约40分钟吧，效果还不错，不过印象最深的是上台分享前的紧张心理。</p>
<p>技术论坛中来了很多数据库方面的大牛，还有很多每天一起工作的同事，我的分享是在下午4点半左右。上午的时候，还没有任何的紧张心理，到下午了便开始紧张了，越是接近我上场时越是紧张。外表虽然仍很冷静，不过自己清晰地感觉到逐渐加快的心率。<span id="more-2141"></span></p>
<p>心理紧张，思绪就如野马，四处乱跑，各种关于紧张的回忆都冒了出来。想起小学时老师让我做校广播员时的情景，当时就跟老师说，我会紧张，我做不了，老师用尽了平时本领，苦劝：“没什么紧张的，你又不用直接面对谁&#8230;Bla Bla&#8230;”。事情最后因为我的担小、紧张而不了了之，而那段时间学校周四的广播也断了一段时间。高中时，原本准备去竞选学生会的职位，自己事前做了很多准备，竞选词练习了很多次，不过也一样，发现自己越接近竞选的日子越紧张。后来，因为自己当天临时有事，还是错过了参加竞选，现在也已经忘了是什么事情了，回忆起来，大概是故意躲避的吧。大学时也有类似的记忆，《图形学》课程上的学生自主教学，《概率论和通信》讨论班的分享等等。只要是需要上台单独面对很多人的时候，紧张心理都如约而至，虽然紧张程度各有不同。</p>
<p>从小到大，经历的紧张次数太多，后来总结出来了自己的几个特点：</p>
<p>1. 在需要一个人面对的时候，紧张总会如期而至，对于我，这大概是无法克服的</p>
<p>2. 事前如果有充分，紧张虽然还是会有，但是一般不会影响正常发挥。随着演讲（分享、讨论、面试等）的进行，紧张会逐渐消失</p>
<p>3. 紧张程度和自己对事情的重视程度有关</p>
<p>有时候，紧张大概是正常的，可能是你对事情很重视，也可能是你对事情期望很高，以后我还是会紧张，甚至会很紧张，不过自己把事情做好，把准备做充分。紧张一点又何妨？</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/06/about-nervous/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>I forgive you &#8212; Benjamin Linus of Lost</title>
		<link>http://www.orczhou.com/index.php/2010/06/benjamin-linus/</link>
		<comments>http://www.orczhou.com/index.php/2010/06/benjamin-linus/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 01:45:25 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[简单生活]]></category>
		<category><![CDATA[Lost]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2110</guid>
		<description><![CDATA[<p>Lost中，另有一个很大的悬疑是是当Martin Keamy杀死Ben的女儿（其实是养女）Alex后，Ben进入了一个小密室，然后召唤出了<a href="http://www.orczhou.com/index.php/2010/06/jacobe-and-esau/">黑烟</a>，消灭了Keamy的部队。Why？为什么Ben能够召唤黑烟呢？</p>
<p>一起来再来认识一下Benjamin Linus吧。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/06/benjamin-linus/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>Lost中，另有一个很大的悬疑是是当Martin Keamy杀死Ben的女儿（其实是养女）Alex后，Ben进入了一个小密室，然后召唤出了<a href="http://www.orczhou.com/index.php/2010/06/jacobe-and-esau/">黑烟</a>，消灭了Keamy的部队。Why？为什么Ben能够召唤黑烟呢？</p>
<p>一起来再来认识一下Benjamin Linus吧。<span id="more-2110"></span></p>
<p><font color="red">Ben的身份</font></p>
<p>Ben很早就在Lost剧集中出现了，开始是混在Oceanic 815幸存者中，被发现后抓走了部分幸存者并回到自己营地。大家都应该还记得刚看到S03EP01时Ben在海滩边衣冠整齐的和Kate享受早餐时的那份迷惑和抓狂吧。</p>
<p>Ben的身份到第三季才开始慢慢明朗。Ben的母亲在他出生的时候死去，他的父亲也因此而讨厌甚至有些恨Ben。Ben从没有享受过父爱、母爱，这给Ben的童年留下阴影，让Ben的心中充满了怨恨。</p>
<p>整个剧集中，Ben被很多人打过，满脸伤疤。其实Ben心中伤疤才是罪恶的根源。</p>
<p><font color="red">我们认识的Ben</font></p>
<p>Ben脸上和心中的伤疤随着Ben的成长而被放大，最终，心中的怨恨让他杀死了整个Dharma。他杀死了Dharma组织的全部人，杀死了自己的父亲，对815er的人毫不手软（最后他杀死了Lock）。这一切，我们看到Ben在不顾一切、疯狂、不择手段地保护着小岛。是的，Ben一直用“保护小岛”的想法，当作自己的行为的理由。Ben相信自己是“接班人”，Richard也相信。</p>
<p>Richard一直是个比较中立，或者说忠心的人。他遵从他的诺言，保护、听从每一个可能的“接班人”（candidate），当他觉得Ben可能是“接班人”时，也是全力的在辅佐这Ben，在Ben杀死全部Dharma的时候也是这样。直到John的出现，这大概是Ben后来杀死了John的原因。</p>
<p>无论是在后来灯塔上的大转盘上，还是石壁上，其实并没有Ben的名字，而且Ben后来自己也承认了自己从来没有见过Jacobe，所以Ben不是“接班人”，<a href="http://lostpedia.wikia.com/wiki/Candidates#Known_candidates">从来就不是</a>。</p>
<p><font color="red">Ben的背后</font></p>
<p>Richard相信Ben是“接班人”，不仅是因为Ben的果断、谎言、诡辩，和观众一样，Richard也发现Ben背后隐隐有着一股里在帮助着他。</p>
<p>后来证明这股力量并不是来自Jacobe，而是在自Esau。</p>
<p>Esau利用了Ben的怨恨、利用了Ben的欲望，Ben和Esau之间已经达成某种“契约”，所以Ben能够召唤黑烟。直到最后，Ben终于意识到了自己不是“接班人”，也意识到并不是自己在召唤黑烟，而是黑烟召唤了他。</p>
<p>“It‘s where i was told i could summon the monster. That&#8217;s before I realized that it was the one summoning me”(<a href="http://tv.sohu.com/20100519/n272222230.shtml">S06EP16</a> 9分15秒)</p>
<p>在第五季最后一集（S05EP17），也是整个Lost的一个小高潮。Ben一直希望自己能够成为“接班人”，一直不择手段地保护着小岛，他的心智已经被怨恨、欲望、嫉妒所侵蚀。当Locke出现，他发现自己什么都不是的时候，在嫉妒和愤怒中，他被Esau利用，最终，在Esau的教唆下Ben又杀死了Jacobe。</p>
<p><font color="red">我看Ben</font></p>
<p>从剧集的角度，Ben是不可或缺的，想想没有了Ben的演绎，剧情多枯燥。</p>
<p>Ben是一个悲剧人物，如果怨恨、欲望、嫉妒都是恶魔的话，那么他就是这些恶魔的化身。他巧舌如簧，不择手段，他心中没有一丝怜悯和宽容。</p>
<p>在大结局中，John Locke准备走进教堂的时，Ben说出了一句：“I am very sorry for what i did to you&#8230;”。John坐在轮椅上回答：</p>
<p>“I forgive you”。</p>
<p>&ndash; &ndash; EOF &ndash; &ndash;</p>
<p>参考：</p>
<p>1. <a href="http://ncjl.wordpress.com/2009/03/11/good-vs-evil-ben-linus/">good vs. evil – ben linus</a></p>
<p>2. <a href="http://en.wikipedia.org/wiki/Benjamin_Linus">Benjamin_Linus of lostpedia</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/06/benjamin-linus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
