﻿<?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>最醉红楼--成江东@盛大在线</title>
	<atom:link href="http://www.goziwa.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.goziwa.com</link>
	<description>又一个 WordPress 博客</description>
	<lastBuildDate>Fri, 10 Sep 2010 10:07:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>[转]Tokyo Tyrant&amp;Tokyo Cabinet运维方案</title>
		<link>http://www.goziwa.com/?p=1060</link>
		<comments>http://www.goziwa.com/?p=1060#comments</comments>
		<pubDate>Fri, 10 Sep 2010 10:07:18 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[所转]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[tt]]></category>
		<category><![CDATA[成江东]]></category>
		<category><![CDATA[运维]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1060</guid>
		<description><![CDATA[from: <a href="http://www.codytan.com/2010/03/22/ttserveryunweifangan/" target="_blank">http://www.codytan.com/2010/03/22/ttserveryunweifangan/</a>
note：示例数据库目录 /data/ttserver
* 配置TTserver服务器的启动脚本
安装ttserver后默认在/usr/local/sbin目录下有ttserv[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>from: <a href="http://www.codytan.com/2010/03/22/ttserveryunweifangan/" target="_blank">http://www.codytan.com/2010/03/22/ttserveryunweifangan/</a></p>
<p>note：示例数据库目录 /data/ttserver</p>
<p>* 配置TTserver服务器的启动脚本</p>
<p>安装ttserver后默认在/usr/local/sbin目录下有ttservctl启动脚本示例，建议copy到具体ttserver数据存放的目录（一个机器可能有多个ttserver服务器，分开便于配置和管理）<br />
cp /usr/local/sbin/ttservctl /data/ttserver/</p>
<p>配置启动脚本ttservctl ,<br />
vim /data/ttserver/ttservctl<br />
如：<br />
# configuration variables<br />
basedir=&#8221;/data/ttserver&#8221; #数据库目录<br />
port=&#8221;8888&#8243; #ttserver端口<br />
ulimsiz=&#8221;256m&#8221; #对单个ulog文件限制，超过将新建一个文件<br />
sid=1 #server id不能重复<br />
mhost=&#8221;remotehost1&#8243; #master的地址<br />
mport=&#8221;8888&#8243; #master端口<br />
extfile=&#8221;$basedir/ext.lua&#8221; #lua扩展脚本文件，默认ttservctl没有这项，如果要使用lua扩展请加上，<br />
#并在启动脚本下面的逻辑代码中增加相应判断。<br />
rtsfile=&#8221;$basedir/rts&#8221; #replication的时间记录文件<br />
dbname=&#8221;$basedir/database.tch#bnum=bucket数量#xmsiz=最大使用内存&#8221;<br />
#数据库名称及优化参数（“#”后面参数，根据需求配置，bnum推荐为记录数0.5-4倍，xmsiz理论上越大性能越好，默认64M，也可以使用默认配置，去掉“#”后面参数即可）</p>
<p>启动ttserver服务器：./ttservctl start ； 关闭ttserver服务器：./ttservctl stop ;</p>
<p>note:可以放入rc.local中, ttserver启动脚本如果错误会有提示，也可以检查端口是否启用来确定ttserver的启动是否成功</p>
<p>* TTserver的监控</p>
<p>监控命令：tcrmgr inform -st -port 服务器使用的端口 监控服务地址<br />
监控程序提供数据项包括：内存使用，数据文件大小,读写次数，未命中key数量等，由cacti定时读取实现监控<br />
示例地址：http://&#8230;/cacti/graph.php?action=view&amp;rra_id=all&amp;local_graph_id=1050<br />
增加磁盘io监控，iotop （iotop要求linux内核2.6.20以上）</p>
<p>note：具体阀值可以设定iotop占总量的80%</p>
<p>* TTserver的备份</p>
<p>全量热备份</p>
<p>备份命令为：tcrmgr copy -port 1978 localhost dpath.tch.xxxxx (其中xxxxx为备份时间)<br />
根据业务需求及数据库运行状态决定备份的频度,全量热备时数据库库会写锁定，读不受影响。全量备份需记录备份时间点以提供replication恢复时所用，时间记录点精确的微妙，可记录到备份文件名中，如backup.tch.1259474040630024。</p>
<p>示例备份脚本：<br />
[ -n "$1" ] || { echo &#8220;input port number&#8221;; exit; }<br />
[ -n "$2" ] || { echo &#8220;input backup dir&#8221;; exit; }</p>
<p>backup_date=`date +%s%N`<br />
backup_date=`expr $backup_date / 1000`<br />
tcrmgr copy -port ${1} localhost ${2}/backup_${1}.tch.${backup_date}<br />
echo &#8220;back up finish! ${2}/backup_${1}.tch.${backup_date}&#8221;</p>
<p>增量备份ulog<br />
ttserver产生的ulog在&#8221;$basedir/ulog&#8221;目录，设置了ulimsiz后会按文件尺寸进行切割并按数据升序命名，可以根据备份的频度，按ulog文件最后修改时间，备份到ulog最大命名数字的前一个文件，同时也需记录备份时间，可将时间记录在打包备份的文件名中，如backup_ulog.1259474040630024.tar.gz, 和全量备份一样，精确到微秒。</p>
<p>note：全量备份速度和服务器情况有关，基本接近直接copy速度</p>
<p>* TTserver的恢复</p>
<p>使用replication恢复<br />
根据备份方案中数据库全量备份方法得到的备份库，如backup.tch.xxxxxx ,<br />
echo xxxxxx &gt; &#8220;$basedir/rts&#8221; 写入备份时间点，即恢复时间点<br />
cp backup.tch.xxxxx database_name.tch<br />
启动: ./ttservctl start<br />
恢复的库会根据时间点去master库同步数据，实现恢复</p>
<p>使用日志增量恢复</p>
<p>先使用前一个全量备份的数据库文件作为基数据库，下线要整理的ttserver。</p>
<p>清空原来的日志，然后解压，再cp 备份的ulog文件 $basedir/ulog/ ，<br />
echo xxxxxx &gt; &#8220;$basedir/rts&#8221; 写入备份时间点（压缩文件名中包含），即恢复时间点</p>
<p>单独启动ttserver ： ttserver database_name.tch<br />
从日志恢复：tcrmgr restore -port port -rcc localhost ulog<br />
ctrl+c停掉ttserver，然后使用 ./ttservctl start 启动，master结构重新建立</p>
<p>note:日志增量恢复环节应避免受其他ttserver的服务器影响，如可以使用一个不使用的端口进行恢复，这样数据也不会影响到其他服务器，恢复后再用原来的启动脚本启动，形成原来的dual master结构</p>
<p>* TTserver优化</p>
<p>定期优化，整理数据文件碎片，优化命令：<br />
tcrmgr optimize -port port host</p>
<p>note：整理时会锁库，读写都锁定</p>
<p>* 备注<br />
基于dual master的结构具有较高的可靠性，dual master其实就是实时的热备方案，所以在备份频度和广度上是否可以适当宽松一些？建议每天备份全量即可，增量的日志一直留在服务器上，但是日志的分割尺寸要根据业务和恢复的粒度来确定。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1060</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]淘宝开源Key/Value结构数据存储系统Tair技术剖析</title>
		<link>http://www.goziwa.com/?p=1054</link>
		<comments>http://www.goziwa.com/?p=1054#comments</comments>
		<pubDate>Fri, 10 Sep 2010 07:54:11 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[所转]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[key/value]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[tair]]></category>
		<category><![CDATA[taobao]]></category>
		<category><![CDATA[成江东]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1054</guid>
		<description><![CDATA[原文:<a href="http://www.infoq.com/cn/articles/taobao-tair">http://www.infoq.com/cn/articles/taobao-tair</a>
Tair是由淘宝网自主开发的Key/Value结构数据存储系统，在淘宝网有着大规模的应用。您在登录淘宝、查看商品详情页面或者在淘江湖和好友“捣浆糊”的时候，都在直接或间接地和Tair交互。
Tair于20[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>原文:<a href="http://www.infoq.com/cn/articles/taobao-tair">http://www.infoq.com/cn/articles/taobao-tair</a></p>
<p>Tair是由淘宝网自主开发的Key/Value结构数据存储系统，在淘宝网有着大规模的应用。您在登录淘宝、查看商品详情页面或者在淘江湖和好友“捣浆糊”的时候，都在直接或间接地和Tair交互。</p>
<h3>Tair于2010年6月30号在<a id="uisl" title="淘宝开源平台" href="http://code.taobao.org/">淘宝开源平台</a>上正式对外开源，本文较详细地介绍了Tair提供的功能及其实现的细节，希望对大家进一步了解Tair有所帮助。</h3>
<h2>Tair的功能</h2>
<p>Tair是一个Key/Value结构数据的解决方案，它默认支持基于内存和文件的两种存储方式，分别和我们通常所说的缓存和持久化存储对应。</p>
<p>Tair除了普通Key/Value系统提供的功能，比如get、put、delete以及批量接口外，还有一些附加的实用功能，使得其有更广的适用场景，包括：</p>
<ul>
<li>Version支持&gt;</li>
<li>原子计数器</li>
<li>Item支持</li>
</ul>
<h3>Version支持</h3>
<p>Tair中的每个数据都包含版本号，版本号在每次更新后都会递增。这个特性有助于防止由于数据的并发更新导致的问题。</p>
<p>比如，系统有一个value为“a,b,c”，A和B同时get到这个value。A执行操作，在后面添加一个d，value为“a,b,c,d”。B执行操作添加一个e，value为”a,b,c,e”。如果不加控制，无论A和B谁先更新成功，它的更新都会被后到的更新覆盖。</p>
<p>Tair无法解决这个问题，但是引入了version机制避免这样的问题。还是拿刚才的例子，A和B取到数据，假设版本号为10，A先更新，更新成功后，value为”a,b,c,d”，与此同时，版本号会变为11。当B更新时，由于其基于的版本号是10，服务器会拒绝更新，从而避免A的更新被覆盖。B可以选择get新版本的value，然后在其基础上修改，也可以选择强行更新。</p>
<h3>原子计数器</h3>
<p>Tair从服务器端支持原子的计数器操作，这使得Tair成为一个简单易用的分布式计数器。</p>
<h3>Item支持</h3>
<p>Tair还支持将value视为一个item数组，对value中的部分item进行操作。比如有个key的value为[1,2,3,4,5]，我们可以只获取前两个item，返回[1,2]，也可以删除第一个item，还支持将数据删除，并返回被删除的数据，通过这个接口可以实现一个原子的分布式FIFO的队列。</p>
<h2>Tair的内部结构</h2>
<p><a href="http://www.goziwa.com/wp-content/uploads/2010/09/tair01.jpg"><img class="aligncenter size-full wp-image-1056" title="tair01" src="http://www.goziwa.com/wp-content/uploads/2010/09/tair01.jpg" alt="" width="554" height="284" /></a><a href="http://www.goziwa.com/wp-content/uploads/2010/09/tair01.jpg"></a></p>
<p><strong>图 1</strong> Tair整体架构图</p>
<p>一个Tair集群主要包括client、configserver和dataserver 3个模块。Configserver通过和dataserver的心跳（HeartBeat）维护集群中可用的节点，并根据可用的节点，构建数据的在集群中的分布信息（见下文的对照表）。Client在初始化时，从configserver处获取数据的分布信息，根据分布信息和相应的dataserver交互完成用户的请求。Dataserver负责数据的存储，并按照configserver的指示完成数据的复制和迁移工作。</p>
<h3>数据的分布</h3>
<p>分布式系统需要解决的一个重要问题便是决定数据在集群中的分布策略，好的分布策略应该能将数据均衡地分布到所有节点上，并且还应该能适应集群节点的变化。Tair采用的对照表方式较好地满足了这两点。</p>
<p>对照表的行数是一个固定值，这个固定值应该远大于一个集群的物理机器数，由于对照表是需要和每个使用Tair的客户端同步的，所以不能太大，不然同步将带来较大的开销。我们在生产环境中的行数一般为1023 。</p>
<h4>对照表简介</h4>
<p>下面我们看对照表是怎么完成数据的分布功能的，为了方便，我们这里假设对照表的行数为6。最简单的对照表包含两列，第一列为hash值，第二列为负责该hash值对应数据的dataserver节点信息。比如我们有两个节点192.168.10.1和192.168.10.2，那么对照表类似：</p>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>0</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>1</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>2</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>3</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>4</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>5</td>
<td>192.168.10.2</td>
</tr>
</tbody>
</table>
<p>当客户端接收到请求后，将key的hash值和6取模，然后根据取模后的结果查找对照表。比如取模后的值为3，客户端将和192.168.10.2通信。</p>
<h4>对照表如何适应节点数量的变化</h4>
<p>我们假设新增了一个节点——192.168.10.3，当configserver发现新增的节点后，会重新构建对照表。构建依据以下两个原则：</p>
<ol>
<li>数据在新表中均衡地分布到所有节点上。</li>
<li>尽可能地保持现有的对照关系。</li>
</ol>
<p>更新之后的对照表如下所示：</p>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>0</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>1</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>2</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>3</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td><span style="color: #0000ff;">4</span></td>
<td><span style="color: #0000ff;">192.168.10.<span style="color: #0000ff;">3</span></span></td>
</tr>
<tr>
<td><span style="color: #0000ff;">5</span></td>
<td><span style="color: #0000ff;">192.168.10.<span style="color: #0000ff;">3</span></span></td>
</tr>
</tbody>
</table>
<p>这里将原本由192.168.10.1负责的4和192.168.10.2负责的5交由新加入的节点192.168.10.3负责。</p>
<p>如果是节点不可用，则相当于上述过程反过来，道理是一样的。</p>
<h4>多备份的支持</h4>
<p>Tair支持自定义的备份数，比如你可以设置数据备份为2，以提高数据的可靠性。对照表可以很方便地支持这个特性。我们以行数为6，两个节点为例，2个备份的对照表类似：</p>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>0</td>
<td>192.168.10.1</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>1</td>
<td>192.168.10.2</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>2</td>
<td>192.168.10.1</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>3</td>
<td>192.168.10.2</td>
<td>192.168.10.1</td>
</tr>
<tr>
<td>4</td>
<td>192.168.10.1</td>
<td>192.168.10.2</td>
</tr>
<tr>
<td>5</td>
<td>192.168.10.2</td>
<td>192.168.10.1</td>
</tr>
</tbody>
</table>
<p>第二列为主节点的信息，第三列为辅节点信息。在Tair中，客户端的读写请求都是和主节点交互，所以如果一个节点不做主节点，那么它就退化成单纯的备份节点。因此，多备份的对照表在构建时需要尽可能保证各个节点作为主节点的个数相近。</p>
<p>当有节点不可用时，如果是辅节点，那么configserver会重新为其指定一个辅节点，如果是持久化存储，还将复制数据到新的辅节点上。如果是主节点，那么configserver首先将辅节点提升为主节点，对外提供服务，并指定一个新的辅节点，确保数据的备份数。</p>
<h4>多机架和多数据中心的支持</h4>
<p>对照表在构建时，可以配置将数据的备份分散到不同机架或数据中心的节点上。Tair当前通过设置一个IP掩码来判断机器所属的机架和数据中心信息。</p>
<p>比如你配置备份数为3，集群的节点分布在两个不同的数据中心A和B，则Tair会确保每个机房至少有一份数据。假设A数据中心包含两份数据时，Tair会尽可能将这两份数据分布在不同机架的节点上。这可以减少整个数据中心或某个机架发生故障是数据丢失的风险。</p>
<h3>轻量级的configserver</h3>
<p>从Tair的整体架构图上看，configserver很类似传统分布式集群中的中心节点。整个集群服务都依赖于configserver的正常工作。</p>
<p>但Tair的configserver却是一个轻量级的中心节点，在大部分时候，configserver不可用对集群的服务是不造成影响的。</p>
<p>Tair用户和configserver的交互主要是为了获取数据分布的对照表，当client获取到对照表后，会cache这张表，然后通过查这张表决定数据存储的节点，所以请求不需要和configserver交互，这使得Tair对外的服务不依赖configserver，所以它不是传统意义上的中心节点。</p>
<p>configserver维护的对照表有一个版本号，每次新生成表，该版本号都会增加。当有数据节点状态发生变化（比如新增节点或者有节点不可用了）时，configserver会根据当前可用的节点重新生成对照表，并通过数据节点的心跳，将新表同步给数据节点。</p>
<p>当客户端请求数据节点时，数据节点每次都会将自己的对照表的版本号放入response中返回给客户端，客户端接收到response后，会将数据节点返回的版本号和自己的版本号比较，如果不相同，则主动和configserver通信，请求新的对照表。</p>
<p>所以客户端也不需要和configserver保持心跳，以便及时地更新对照表。这使得在正常的情况下，客户端不需要和configserver通信，即使configserver不可用了，也不会对整个集群的服务造成大的影响。</p>
<p>仅有当configserver不可用，此时有客户端需要初始化，那么客户端将取不到对照表信息，这将使得客户端无法正常工作。</p>
<h3>DataServer内部结构</h3>
<p>DataServer负责数据的物理存储，并根据configserver构建的对照表完成数据的复制和迁移工作。DataServer具备抽象的存储引擎层，可以很方便地添加新存储引擎。DataServer还有一个插件容器，可以动态地加载/卸载插件。</p>
<p><a href="http://www.goziwa.com/wp-content/uploads/2010/09/tair02.jpg"><img class="aligncenter size-full wp-image-1057" title="tair02" src="http://www.goziwa.com/wp-content/uploads/2010/09/tair02.jpg" alt="" width="554" height="266" /></a></p>
<p><strong>图 2</strong> DataServer的内部结构示意图</p>
<h4>抽象的存储引擎层</h4>
<p>Tair的存储引擎有一个抽象层，只要满足存储引擎需要的接口，便可以很方便地替换Tair底层的存储引擎。比如你可以很方便地将bdb、tc甚至MySQL作为Tair的存储引擎，而同时使用Tair的分布方式、同步等特性。</p>
<p>Tair默认包含两个存储引擎：mdb和fdb。</p>
<p>mdb是一个高效的缓存存储引擎，它有着和memcached类似的内存管理方式。mdb支持使用share memory，这使得我们在重启Tair数据节点的进程时不会导致数据的丢失，从而使升级对应用来说更平滑，不会导致命中率的较大波动。</p>
<p>fdb是一个简单高效的持久化存储引擎，使用树的方式根据数据key的hash值索引数据，加快查找速度。索引文件和数据文件分离，尽量保持索引文件在内存中，以便减小IO开销。使用空闲空间池管理被删除的空间。</p>
<h4>自动的复制和迁移</h4>
<p>为了增强数据的安全性，Tair支持配置数据的备份数。比如你可以配置备份数为3，则每个数据都会写在不同的3台机器上。得益于抽象的存储引擎层，无论是作为cache的mdb，还是持久化的fdb，都支持可配的备份数。</p>
<p>当数据写入一个节点（通常我们称其为主节点）后，主节点会根据对照表自动将数据写入到其他备份节点，整个过程对用户是透明的。</p>
<p>当有新节点加入或者有节点不可用时，configserver会根据当前可用的节点，重新build一张对照表。数据节点同步到新的对照表时，会自动将在新表中不由自己负责的数据迁移到新的目标节点。迁移完成后，客户端可以从configserver同步到新的对照表，完成扩容或者容灾过程。整个过程对用户是透明的，服务不中断。</p>
<h4>插件容器</h4>
<p>Tair还内置了一个插件容器，可以支持热插拔插件。</p>
<p>插件由configserver配置，configserver会将插件配置同步给各个数据节点，数据节点会负责加载/卸载相应的插件。</p>
<p>插件分为request和response两类，可以分别在request和response时执行相应的操作，比如在put前检查用户的quota信息等。</p>
<p>插件容器也让Tair在功能方便具有更好的灵活性。</p>
<h2>Tair的未来</h2>
<p>我们将Tair开源，希望有更多的用户能从我们开发的产品中受益，更希望依托社区的力量，使Tair有更广阔的发展空间。</p>
<p>Tair开源后，有很多用户关心我们是否会持续维护这个项目。我们将Tair开源后，淘宝内部已经不再有私有的Tair分支，所有的开发和应用都基于开源分支。Tair在淘宝有非常广的应用，我们内部有一个团队，专门负责Tair的开发和维护，相信我们会和社区一起，将Tair越做越好。</p>
<p>有很多用户在淘宝开源平台上申请加入Tair项目，加入项目在我们的开源平台上意味着成为项目的提交者，可以向代码库直接提交代码。所以我们暂时还没有批准外部用户加入，我们将在大家对Tair有更深入的了解后和社区一起决定是否批准加入项目的申请，在此之前，如果你有对代码的改进，欢迎使用patch的方式提交给我们，我们将在review后决定是否合并到代码库。</p>
<p>希望我们能和社区一起，将Tair做成一个真正对大家都有帮助的项目。</p>
<p><strong>关于作者</strong></p>
<p>若海，真名余刚，淘宝网核心系统研发部工程师，Tair的主要作者之一，当前的方向是大型分布式缓存和存储解决方案。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1054</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]MongoDB Indexing and Query Optimizer</title>
		<link>http://www.goziwa.com/?p=1052</link>
		<comments>http://www.goziwa.com/?p=1052#comments</comments>
		<pubDate>Thu, 09 Sep 2010 09:59:27 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[成江东]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1052</guid>
		<description><![CDATA[注：
&#8212;&#8212;&#8212;&#8212;
db.collection.find({ &#8220;field&#8221; : { $gt: value } } ); // greater than : field &#62; value
db.collection.find({[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>注：<br />
&#8212;&#8212;&#8212;&#8212;<br />
db.collection.find({ &#8220;field&#8221; : { $gt: value } } ); // greater than : field &gt; value<br />
db.collection.find({ &#8220;field&#8221; : { $lt: value } } ); // less than : field &lt; value<br />
db.collection.find({ &#8220;field&#8221; : { $gte: value } } ); // greater than or equal to : field &gt;= value<br />
db.collection.find({ &#8220;field&#8221; : { $lte: value } } ); // less than or equal to : field &lt;= value</p>
<p>$ne for &#8220;not equals&#8221;.</p>
<p>The $in operator is analogous to the SQL IN modifier, allowing you to specify an array of possible matches.<br />
db.collection.find( { &#8220;field&#8221; : { $in : array } } );</p>
<p>The $mod operator allows you to do fast modulo queries to replace a common case for where clauses. For example, the following $where query:<br />
db.things.find( &#8220;this.a % 10 == 1&#8243;)<br />
can be replaced by:<br />
db.things.find( { a : { $mod : [ 10 , 1 ] } } )</p>
<p>&#8212;&#8212;&#8212;&#8212;</p>
<p>db.createCollection(&#8220;c&#8221;);</p>
<p>db.c.insert({x:33,y:45});<br />
db.c.insert({x:31,y:27});<br />
db.c.insert({x:3,y:415});</p>
<p>db.c.find({x:{$in:[3,31]}})<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c772&#8243;), &#8220;x&#8221; : 31, &#8220;y&#8221; : 27 }<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c773&#8243;), &#8220;x&#8221; : 3, &#8220;y&#8221; : 415 }<br />
db.c.insert({x:{a:1,b:4},y:415});<br />
db.c.insert({x:{a:1},y:3});</p>
<p>db.c.find({&#8216;x.a&#8217;:1});    # using index {&#8216;x.a&#8217;:1}<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c88727a9ca71035adf0c774&#8243;), &#8220;x&#8221; : { &#8220;a&#8221; : 1, &#8220;b&#8221; : 4 }, &#8220;y&#8221; : 415 }<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c8873e49ca71035adf0c776&#8243;), &#8220;x&#8221; : { &#8220;a&#8221; : 1 }, &#8220;y&#8221; : 3 }</p>
<p>db.c.find({x:{a:1}});    # using index {x:1}      <br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c8873e49ca71035adf0c776&#8243;), &#8220;x&#8221; : { &#8220;a&#8221; : 1 }, &#8220;y&#8221; : 3 }</p>
<p>db.c.find({x:{$gte:3,$lte:5}});<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c773&#8243;), &#8220;x&#8221; : 3, &#8220;y&#8221; : 415 }<br />
db.c.insert({x:&#8217;abc&#8217;,y:415});<br />
db.c.insert({x:&#8217;bac&#8217;,y:3});</p>
<p>db.c.find({x:/^a/});    # 使用索引来判断是否是字符串或正则表达式<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c8877159ca71035adf0c777&#8243;), &#8220;x&#8221; : &#8220;abc&#8221;, &#8220;y&#8221; : 415 }</p>
<p>db.c.count({x:3})<br />
1</p>
<p>db.c.distinct({y:3})<br />
[ ]</p>
<p>db.c.update({x:3},{$set: {y:97}} ); <br />
db.c.remove({x:2});</p>
<p>db.c.find({x:null}); # 使用x索引</p>
<p>db.c.insert({y:222});<br />
db.c.find({x:null});              <br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c887b8a9ca71035adf0c779&#8243;), &#8220;y&#8221; : 222 }</p>
<p>db.c.find({x:{$exists:true}});   # 无法用索引，1.6版会修正</p>
<p>db.c.find({&#8220;x&#8221;:[1,10]});  # 空??</p>
<p>db.c.find().sort({x:1});<br />
db.c.find().sort({x:-1});</p>
<p>db.c.find({x:{$gt:4}}).sort({x:-1});<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c771&#8243;), &#8220;x&#8221; : 33, &#8220;y&#8221; : 45 }<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c772&#8243;), &#8220;x&#8221; : 31, &#8220;y&#8221; : 27 }</p>
<p>db.c.find({}).sort({&#8216;x.a&#8217;:1}) </p>
<p>db.c.find({x:3,y:97})     # 使用索引{x:1,y:1}<br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c886fa79ca71035adf0c773&#8243;), &#8220;x&#8221; : 3, &#8220;y&#8221; : 97 }</p>
<p>db.c.find().sort({x:1,y:1});</p>
<p>db.c.find({x:3}).sort({y:1});</p>
<p># 索引无效<br />
db.c.find({x:{$ne:3}});<br />
db.c.find({x:{$mod:[10,1]}}); # 索引只是用来找数字</p>
<p>db.c.find({x:{$not:/a/}});</p>
<p># 索引优化<br />
db.c.find({x:2,y:3}).hint({y:1});<br />
Thu Sep  9 15:23:41 assertion userassert:bad hint ns:test.c query:{ query: { x: 2.0, y: 3.0 }, $hint: { y: 1.0 } }<br />
error: { &#8220;$err&#8221; : &#8220;bad hint&#8221; }</p>
<p>db.c.ensureIndex({y:1});</p>
<p>db.c.find({x:2,y:3}).hint($natural:1});    # 绕过索引</p>
<p># 内存为何如此重要<br />
内存基本使用<br />
全部索引在内存<br />
部分在内存</p>
<p># 创建索引<br />
_id:1 索引自动建立</p>
<p>db.c.ensureIndex({x:1},{background:true});   # 仍然会影响性能</p>
<p>db.c.ensureIndex({x:1},{unique:true})</p>
<p># 清除索引</p>
<p>db.system.indices.find({ns:&#8217;db.c&#8217;});</p>
<p>db.c.dropIndex({x:1})<br />
db.collection.dropIndexes();<br />
db.c.reIndex()</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1052</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]schema design with mongodb</title>
		<link>http://www.goziwa.com/?p=1050</link>
		<comments>http://www.goziwa.com/?p=1050#comments</comments>
		<pubDate>Thu, 09 Sep 2010 05:22:51 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[schema]]></category>
		<category><![CDATA[成江东]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1050</guid>
		<description><![CDATA[<a href="http://www.slideshare.net/mongosf/schema-design-with-mongodb-dwight-merriman">http://www.slideshare.net/mongosf/schema-design-with-mongodb-dwight-merriman</a>
什么是面向文档
json 对象
非关系
非oodb
数据库架构!=程序架构
术语
行-&#62;json文档
表-&#62;collections
i[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.slideshare.net/mongosf/schema-design-with-mongodb-dwight-merriman">http://www.slideshare.net/mongosf/schema-design-with-mongodb-dwight-merriman</a></p>
<p>什么是面向文档<br />
json 对象<br />
非关系<br />
非oodb<br />
数据库架构!=程序架构</p>
<p>术语<br />
行-&gt;json文档<br />
表-&gt;collections<br />
indexes-&gt;index<br />
连接-&gt;嵌入和linking</p>
<p>选择架构<br />
查询更容易<br />
查询更快<br />
有利于原子性<br />
有利于分片</p>
<p>关键问题：嵌入 vs link<br />
包含相关性：嵌入<br />
嵌入=预连接<br />
Links:客户端/服务器周转<br />
On a close call,嵌入,使用丰富文档<br />
注意4MB对象限制，很专制但是使你注意设计</p>
<p>use test<br />
db.createCollection(&#8220;order&#8221;)</p>
<p>db.order.insert(<br />
{&#8216;user_id&#8217; : &#8216;6589&#8242;, &#8216;items&#8217; :<br />
[<br />
{'code':'rbk-432','name':'高性能mysql','price':49},<br />
{'code':'rbk-431','name':'高性能mssql','price':23}<br />
],<br />
&#8216;address&#8217;:{<br />
&#8217;street&#8217;:'huguang road&#8217;,<br />
&#8216;city&#8217;:&#8217;sh&#8217;,<br />
&#8217;state&#8217;:&#8217;sh&#8217;,<br />
&#8216;zip&#8217;:'200001&#8242;<br />
},<br />
total:72<br />
}<br />
)</p>
<p>db.order.insert(<br />
{&#8216;user_id&#8217; : &#8216;6519&#8242;, &#8216;items&#8217; :<br />
[<br />
{'code':'spk-432','name':'oracle调优','price':49},<br />
{'code':'rbk-432','name':'高性能mysql','price':23}<br />
],<br />
&#8216;address&#8217;:{<br />
&#8217;street&#8217;:'huguang road&#8217;,<br />
&#8216;city&#8217;:&#8217;sh&#8217;,<br />
&#8217;state&#8217;:&#8217;sh&#8217;,<br />
&#8216;zip&#8217;:'200001&#8242;<br />
},<br />
total:72<br />
}<br />
)</p>
<p>db.order.ensureIndex({&#8216;items.code&#8217;:1});</p>
<p>db.order.find({&#8216;items.code&#8217; : &#8216;rbk-432&#8242;});</p>
<p>db.order.find({created_at: {&#8216;$gt&#8217;:last_week},create_at: {&#8216;$lt&#8217;:today}}).sort({&#8216;total&#8217;:-1});</p>
<p>db.order.update({&#8216;user_id&#8217;:'6519&#8242;},{&#8216;$push&#8217;:{&#8216;items&#8217;:<br />
{&#8216;code&#8217;:&#8217;spk-432&#8242;,&#8217;name&#8217;:'真爱无敌&#8217;,'price&#8217;:100}<br />
}}<br />
);</p>
<p>db.order.update(<br />
{&#8216;user_id&#8217;:'6519&#8242;,&#8217;items.code&#8217;:'rbk-432&#8242;},<br />
{&#8216;$set&#8217;:{&#8216;items.$.quantity&#8217;:2}}<br />
);<br />
map = &#8221; function()<br />
{emit(this['address']['zip'],{total:this.total})<br />
}&#8221;</p>
<p>reduce =<br />
function(key,values) {<br />
var sum=0;<br />
values.forEach(function(doc){<br />
sum+=doc.total;<br />
}</p>
<p>return {total:sum};<br />
}&#8221;</p>
<p>db.orders.mapReduce(map,reduce,{out:&#8217;order_totals&#8217;})</p>
<p>{_id:&#8230;}<br />
应该是唯一的<br />
不变的<br />
理想状态，不重用（删除，插入）<br />
ObjectID类型适合分片</p>
<p>mongodb.org/display/docs/trees+in+mongodb</p>
<p>单表继续工作良好<br />
&gt; t.find()<br />
{ type:’irregular-shape’, area:99 }<br />
{ type:’circle’, area:3.14, radius:1 }<br />
{ type:’square’, area:4, d:2 }<br />
{ type:’rect’, area:8, x:2, y:4 }<br />
&gt; t.find( { radius : { $gt : 2.0 } } )<br />
&gt; t.ensureIndex( { radius : 1 } ) // fine<br />
一行实际完整树<br />
{<br />
comments: [<br />
{by: "mathias", text: "...",<br />
replies: []}<br />
{by: &#8220;eliot&#8221;, text: &#8220;&#8230;&#8221;,<br />
replies: [<br />
{by: "mike", text: "...", replies: []}<br />
]}<br />
]<br />
}</p>
<p>ps:mongoDB的collection相当于关系数据库里的table，document相当于table里面的row</p>
<p>优点:<br />
取一页只需一条记录<br />
整个树都在一个磁盘上的一个位置<br />
很容易看到整个结构</p>
<p>缺点:<br />
难查询<br />
难返回部分结果<br />
4M的限制</p>
<p>父链接<br />
&gt; t = db.tree1;<br />
&gt; t.find()<br />
{ &#8220;_id&#8221; : 1 }<br />
{ &#8220;_id&#8221; : 2, &#8220;parent&#8221; : 1 }<br />
{ &#8220;_id&#8221; : 3, &#8220;parent&#8221; : 1 }<br />
{ &#8220;_id&#8221; : 4, &#8220;parent&#8221; : 2 }<br />
{ &#8220;_id&#8221; : 5, &#8220;parent&#8221; : 4 }<br />
{ &#8220;_id&#8221; : 6, &#8220;parent&#8221; : 4 }<br />
&gt; // find children of node 4<br />
&gt; t.ensureIndex({parent:1})<br />
&gt; t.find( {parent : 4 } )<br />
{ &#8220;_id&#8221; : 5, &#8220;parent&#8221; : 4 }<br />
{ &#8220;_id&#8221; : 6, &#8220;parent&#8221; : 4 }<br />
// 难以得到所有层级<br />
Array of Ancestors<br />
&gt; t = db.mytree;<br />
&gt; t.find()<br />
{ &#8220;_id&#8221; : &#8220;a&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;b&#8221;, &#8220;ancestors&#8221; : [ "a" ], &#8220;parent&#8221; : &#8220;a&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;c&#8221;, &#8220;ancestors&#8221; : [ "a", "b" ], &#8220;parent&#8221; : &#8220;b&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;d&#8221;, &#8220;ancestors&#8221; : [ "a", "b" ], &#8220;parent&#8221; : &#8220;b&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;e&#8221;, &#8220;ancestors&#8221; : [ "a" ], &#8220;parent&#8221; : &#8220;a&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;f&#8221;, &#8220;ancestors&#8221; : [ "a", "e" ], &#8220;parent&#8221; : &#8220;e&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;g&#8221;, &#8220;ancestors&#8221; : [ "a", "b", "d" ], &#8220;parent&#8221; : &#8220;d&#8221; }<br />
&gt; t.ensureIndex( { ancestors : 1 } )<br />
&gt; // 找到b的所有子孙:<br />
&gt; t.find( { ancestors : &#8216;b&#8217; })<br />
{ &#8220;_id&#8221; : &#8220;c&#8221;, &#8220;ancestors&#8221; : [ "a", "b" ], &#8220;parent&#8221; : &#8220;b&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;d&#8221;, &#8220;ancestors&#8221; : [ "a", "b" ], &#8220;parent&#8221; : &#8220;b&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;g&#8221;, &#8220;ancestors&#8221; : [ "a", "b", "d" ], &#8220;parent&#8221; : &#8220;d&#8221; }<br />
&gt; // 得到f的所有祖先:<br />
&gt; anc = db.mytree.findOne({_id:&#8217;f'}).ancestors<br />
[ "a", "e" ]<br />
&gt; db.mytree.find( { _id : { $in : anc } } )<br />
{ &#8220;_id&#8221; : &#8220;a&#8221; }<br />
{ &#8220;_id&#8221; : &#8220;e&#8221;, &#8220;ancestors&#8221; : [ "a" ], &#8220;parent&#8221; : &#8220;a&#8221; }</p>
<p>原子性<br />
在行级别的原子性<br />
$operators<br />
比较和交换</p>
<p>&gt; t=db.inventory<br />
&gt; s = t.findOne( {sku:&#8217;abc&#8217;} )<br />
&gt; &#8211;s.qty;<br />
&gt; t.update({_id:s._id, qty:qty_old}, s);<br />
&gt; db.getLastError()<br />
{&#8220;err&#8221; : , &#8220;updatedExisting&#8221; : true , &#8220;n&#8221; : 1 , &#8220;ok&#8221; : 1} // it worked</p>
<p>测试：<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
db.createCollection(&#8220;inventory&#8221;)<br />
db.inventory.insert({sku:&#8217;abc&#8217;,qty:50});<br />
t=db.inventory<br />
s=t.findOne({sku:&#8217;abc&#8217;})<br />
&gt; &#8211;s.qty;<br />
49<br />
&gt; &#8211;s.qty;<br />
48</p>
<p>&gt; t.update({_id:s._id},s);           <br />
&gt; db.inventory.find();                   <br />
{ &#8220;_id&#8221; : ObjectId(&#8220;4c8849d89ca71035adf0c770&#8243;), &#8220;sku&#8221; : &#8220;abc&#8221;, &#8220;qty&#8221; : 48 }</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
&gt; t=db.inventory<br />
&gt; s = t.findOne( {sku:&#8217;abc&#8217;} )<br />
&gt; &#8211;s.qty;<br />
&gt; t.update({_id:s._id, qty:qty_old}, s);<br />
&gt; db.getLastError()<br />
{&#8220;err&#8221; : , &#8220;updatedExisting&#8221; : true , &#8220;n&#8221; : 1 , &#8220;ok&#8221; : 1} // it worked<br />
Oops?</p>
<p> t=db.inventory &#8211; Better<br />
 s = t.findOne( {sku:&#8217;abc&#8217;} )<br />
 obj_old = Object.extend({}, s);<br />
 &#8211;s.qty;<br />
 // t.update({_id:s._id, qty:qty_old}, s);<br />
 t.update( obj_old , s);<br />
 print( db.getLastError().ok ? &#8220;worked&#8221; : &#8220;try again&#8221; );<br />
Compare and Swap – versions<br />
update( { _id : myid, ver : last_ver },<br />
{ $set : { x : &#8220;abc&#8221;, y : 99 },<br />
$inc : { ver : 1 }<br />
} )</p>
<p>测试<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
t.update(<br />
{<br />
sku : &#8220;abc&#8221;,<br />
qty : {$gt:0}<br />
},<br />
{<br />
$set : { qty : 10 }<br />
}<br />
,<br />
{<br />
$inc : { qty : -1 }<br />
}<br />
)</p>
<p>t.update(<br />
{<br />
sku : &#8220;abc&#8221;,<br />
qty : {$gt:0}<br />
},<br />
{<br />
$inc : { qty : -1 }<br />
}<br />
)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Of course, don’t both doing CAS when you don’t have to<br />
&gt; t.update( { sku : &#8220;abc&#8221;,<br />
qty : {$gt:0} },<br />
{ $inc : { qty : -1 } }<br />
)</p>
<p>db.getLastError()<br />
{ &#8220;updatedExisting&#8221; : true , &#8220;n&#8221; : 1 , &#8220;ok&#8221; : 1 }<br />
{ &#8220;updatedExisting&#8221; : false , &#8220;n&#8221; : 0 , &#8220;ok&#8221; : 1 }</p>
<p>&gt; t=db.inventory<br />
&gt; s = t.findOne( {sku:&#8217;abc&#8217;} )<br />
&gt; &#8211;s.qty;<br />
&gt; t.update({_id:s._id, qty:qty_old}, s);<br />
&gt; db.getLastError()<br />
{&#8220;err&#8221; : , &#8220;updatedExisting&#8221; : true , &#8220;n&#8221; : 1 , &#8220;ok&#8221; : 1} // it worked</p>
<p>&gt; t=db.inventory<br />
&gt; s = t.findOne( {sku:&#8217;abc&#8217;} )<br />
&gt; &#8211;s.qty;<br />
&gt; t.update({_id:s._id, qty:qty_old}, s);<br />
&gt; db.getLastError()<br />
{&#8220;err&#8221; : , &#8220;updatedExisting&#8221; : true , &#8220;n&#8221; : 1 , &#8220;ok&#8221; : 1} // it worked</p>
<p>Sharding and Schemas<br />
Shard key selection<br />
Restrictions on unique indexes<br />
Consider using may collections when that is natural<br />
10 SN</p>
<p>Other Considerations<br />
Cappedcollections</p>
<p>Questions?<br />
Get involved with the MongoDB project!<br />
Coding, drivers, frameworks, documentation, translation, consulting, evangelism, suggestions, vote on jira…spread the word.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1050</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于盗梦空间的几点说明</title>
		<link>http://www.goziwa.com/?p=1044</link>
		<comments>http://www.goziwa.com/?p=1044#comments</comments>
		<pubDate>Tue, 07 Sep 2010 16:28:19 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[所看]]></category>
		<category><![CDATA[imax]]></category>
		<category><![CDATA[成江东]]></category>
		<category><![CDATA[正大星美]]></category>
		<category><![CDATA[盗梦空间]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1044</guid>
		<description><![CDATA[晚上和她一起去正大的渝乡人家吃了饭，然后八点过几分进入电影院，没有看到开头。
1，中国什么时候有正宗的科幻电影，除了霹雳贝贝和长江七号以外？
2，中国人缺少幻想力了吗？除了西游记以外？
3，想起了二十年前中国人写的七重外壳(王晋康) ，大家有兴趣可以找来看看，可见中国人其实也不缺少幻想力，算起来还比[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>晚上和她一起去正大的渝乡人家吃了饭，然后八点过几分进入电影院，没有看到开头。</p>
<p>1，中国什么时候有正宗的科幻电影，除了霹雳贝贝和长江七号以外？</p>
<p>2，中国人缺少幻想力了吗？除了西游记以外？</p>
<p>3，想起了二十年前中国人写的七重外壳(王晋康) ，大家有兴趣可以找来看看，可见中国人其实也不缺少幻想力，算起来还比电影多一层，也是因为这部小说，让我对电影的感觉打了不少折扣</p>
<p>4，中国的导演舍得用几亿拍古装片，没有勇气拍一部未来片？</p>
<p>5，以为是imax 3D的，原来只是imax屏幕，不是3D的，有点失望</p>
<p>6，音响非常好，吓到我几次</p>
<p>7，细节的确值得玩味，比如镜子的出现，比如三个图腾，色子，棋子，砣罗，以及国外有人指出的戒指</p>
<p>8，我觉得自己做过梦中梦，也是就二层的梦，但三层的肯定没有</p>
<p>9，有时候阶段性的有一段时间感觉自己活在梦里一样，随之又慢慢淡忘这种感觉</p>
<p>10，以后应该会得看，再观察一下细节</p>
<p>11，另，有一男配角是和莎莫的500天的男主角，这下想不火也难了</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1044</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>mongodb 1.6 replica set 测试</title>
		<link>http://www.goziwa.com/?p=1040</link>
		<comments>http://www.goziwa.com/?p=1040#comments</comments>
		<pubDate>Tue, 07 Sep 2010 02:16:59 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[nosql]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[replica set]]></category>
		<category><![CDATA[成江东]]></category>
		<category><![CDATA[测试]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1040</guid>
		<description><![CDATA[在192.168.0. 10.129.128.16 10.129.128.17 上分别执行
mkdir /usr/local/mongodb/repldata
/usr/local/mongodb/bin/mongod &#8211;replSet replone &#8211;dbpath /us[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>在192.168.0. 10.129.128.16 10.129.128.17 上分别执行</p>
<p>mkdir /usr/local/mongodb/repldata</p>
<p>/usr/local/mongodb/bin/mongod &#8211;replSet replone &#8211;dbpath /usr/local/mongodb/repldata &#8211;port 20001 &gt; /usr/local/mongodb/log/repl.log &amp;</p>
<p>config = {_id: &#8216;replone&#8217;, members: [<br />
                          {_id: 0, host: '192.168.0.:20001'},<br />
                          {_id: 1, host: '10.129.128.16:20001'},<br />
                          {_id: 2, host: '10.129.128.17:20001'}]<br />
           }</p>
<p>rs.initiate(config);</p>
<p>rs.status();</p>
<p>db.runCommand( { addshard : &#8220;replone/192.168.0.:20001,10.129.128.16:20001,10.129.128.17:20001&#8243; } );</p>
<p>db.isMaster();<br />
# 更新配置<br />
new_config = {_id: &#8216;replone&#8217;, members: [<br />
                          {_id: 0, host: '192.168.0.:20001'},<br />
                          {_id: 1, host: '10.129.128.16:20001'},<br />
                          {_id: 2, host: '10.129.128.17:20001'}]<br />
           }</p>
<p>use local<br />
old_config = db.system.replset.findOne();<br />
new_config.version = old_config.version + 1;</p>
<p>use admin<br />
db.runCommand({replSetReconfig: new_config});</p>
<p># 发现数据分布不太均衡<br />
db.app.stats();<br />
{<br />
        &#8220;sharded&#8221; : true,<br />
        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
        &#8220;count&#8221; : 13848261,<br />
        &#8220;size&#8221; : 1107861136,<br />
        &#8220;avgObjSize&#8221; : 80.00001848607562,<br />
        &#8220;storageSize&#8221; : 1576738304,<br />
        &#8220;nindexes&#8221; : 3,<br />
        &#8220;nchunks&#8221; : 49,<br />
        &#8220;shards&#8221; : {<br />
                &#8220;shard0000&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 2835007,<br />
                        &#8220;size&#8221; : 226800640,<br />
                        &#8220;avgObjSize&#8221; : 80.0000282186252,<br />
                        &#8220;storageSize&#8221; : 338897408,<br />
                        &#8220;numExtents&#8221; : 17,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 63943168,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 601818176,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 245023680,<br />
                                &#8220;credate_-1&#8243; : 224239680,<br />
                                &#8220;appid_1&#8243; : 132554816<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0001&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 2835188,<br />
                        &#8220;size&#8221; : 226815056,<br />
                        &#8220;avgObjSize&#8221; : 80.00000564336474,<br />
                        &#8220;storageSize&#8221; : 334808832,<br />
                        &#8220;numExtents&#8221; : 17,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 62325760,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 590111680,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 210296832,<br />
                                &#8220;credate_-1&#8243; : 242885568,<br />
                                &#8220;appid_1&#8243; : 136929280<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0002&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 3097112,<br />
                        &#8220;size&#8221; : 247769024,<br />
                        &#8220;avgObjSize&#8221; : 80.00002066441252,<br />
                        &#8220;storageSize&#8221; : 409599744,<br />
                        &#8220;numExtents&#8221; : 18,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 74790912,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 630678464,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 211451904,<br />
                                &#8220;credate_-1&#8243; : 260400064,<br />
                                &#8220;appid_1&#8243; : 158826496<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0003&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 4263251,<br />
                        &#8220;size&#8221; : 341060160,<br />
                        &#8220;avgObjSize&#8221; : 80.00001876502228,<br />
                        &#8220;storageSize&#8221; : 409599744,<br />
                        &#8220;numExtents&#8221; : 18,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 74790912,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 733636480,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 234980288,<br />
                                &#8220;credate_-1&#8243; : 301417408,<br />
                                &#8220;appid_1&#8243; : 197238784<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0004&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 817703,<br />
                        &#8220;size&#8221; : 65416256,<br />
                        &#8220;avgObjSize&#8221; : 80.0000195670066,<br />
                        &#8220;storageSize&#8221; : 83832576,<br />
                        &#8220;numExtents&#8221; : 13,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 17845760,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 137977856,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 42622976,<br />
                                &#8220;credate_-1&#8243; : 55492608,<br />
                                &#8220;appid_1&#8243; : 39862272<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                }<br />
        },<br />
        &#8220;ok&#8221; : 1<br />
}<br />
在primary上执行<br />
&gt; db.app.find({&#8220;appid&#8221;:39}).count();<br />
260748</p>
<p># 关闭</p>
<p>ps -ef|grep mongo<br />
root     10534     1  0 Sep06 ?        00:03:22 /usr/local/mongodb/bin/mongod &#8211;replSet replone &#8211;dbpath /usr/local/mongodb/repldata &#8211;port 20001<br />
root     29885 29226  0 09:38 pts/6    00:00:00 grep mongo<br />
[root@localhost bin]# kill 10534</p>
<p># 第一台日志<br />
Tue Sep  7 09:38:52 got kill or ctrl c or hup signal 15 (Terminated), will terminate after current cmd ends<br />
Tue Sep  7 09:38:52 [interruptThread] now exiting<br />
Tue Sep  7 09:38:52  dbexit:</p>
<p>Tue Sep  7 09:38:52 [interruptThread]    shutdown: going to close listening sockets&#8230;<br />
Tue Sep  7 09:38:52 [interruptThread]    going to close listening socket: 10<br />
Tue Sep  7 09:38:52 [interruptThread]    going to close listening socket: 11<br />
Tue Sep  7 09:38:52 [interruptThread]    going to close listening socket: 12<br />
Tue Sep  7 09:38:52 [interruptThread]    going to close listening socket: 13<br />
Tue Sep  7 09:38:52 [interruptThread]    shutdown: going to flush oplog&#8230;<br />
Tue Sep  7 09:38:52 [interruptThread]    shutdown: going to close sockets&#8230;<br />
Tue Sep  7 09:38:52 [interruptThread]    shutdown: waiting for fs preallocator&#8230;<br />
Tue Sep  7 09:38:52 [interruptThread]    shutdown: closing all files&#8230;<br />
Tue Sep  7 09:38:52      closeAllFiles() finished</p>
<p>Tue Sep  7 09:38:52 [interruptThread]    shutdown: removing fs lock&#8230;<br />
Tue Sep  7 09:38:52 [conn2] end connection 127.0.0.1:47350<br />
Tue Sep  7 09:38:52  dbexit: really exiting now</p>
<p>ERROR: Client::shutdown not called: slaveTracking<br />
Tue Sep  7 09:38:52 [conn68] end connection 10.129.128.17:51354<br />
Tue Sep  7 09:38:52 [conn67] end connection 10.129.128.16:46189</p>
<p># 第二台日志<br />
Tue Sep  7 09:39:05 [conn58] end connection 192.168.0.:49170<br />
Tue Sep  7 09:39:05 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server<br />
Tue Sep  7 09:39:05 [conn9] end connection 10.129.128.13:42299<br />
Tue Sep  7 09:39:05 [ReplSetHealthPollTask] replSet info 192.168.0.:20001 is now down (or slow to respond)<br />
Tue Sep  7 09:39:06 [rs Manager] replSet info electSelf 1<br />
Tue Sep  7 09:39:06 [rs Manager] replSet PRIMARY<br />
Tue Sep  7 09:39:06 [conn60] end connection 10.129.128.13:48465<br />
Tue Sep  7 09:39:07 [conn59] end connection 10.129.128.13:48458<br />
Tue Sep  7 09:39:07 [initandlisten] connection accepted from 10.129.128.13:41080 #61<br />
Tue Sep  7 09:39:08 [conn61] insert test.app 106ms<br />
Tue Sep  7 09:39:08 [conn61] insert test.app 103ms<br />
Tue Sep  7 09:39:08 [initandlisten] connection accepted from 10.129.128.13:41084 #62<br />
Tue Sep  7 09:39:09 [initandlisten] connection accepted from 10.129.128.13:41088 #63<br />
Tue Sep  7 09:39:16 [initandlisten] connection accepted from 10.129.128.17:58700 #64<br />
Tue Sep  7 09:39:29 [conn7] end connection 10.129.128.13:42295<br />
Tue Sep  7 09:39:42 [conn61] insert test.app 147ms<br />
Tue Sep  7 09:39:51 [conn61] insert test.app 152ms<br />
Tue Sep  7 09:39:59 [initandlisten] connection accepted from 10.129.128.13:41092 #65<br />
Tue Sep  7 09:40:11 [conn64] getmore local.oplog.rs cid:3504933112664086473 getMore: { ts: { $gte: new Date(5513980079480242292) } }  bytes:1652 nreturned:12 4188ms<br />
Tue Sep  7 09:40:16 [conn64] getmore local.oplog.rs cid:3504933112664086473 getMore: { ts: { $gte: new Date(5513980079480242292) } }  bytes:20 nreturned:0 4054ms<br />
Tue Sep  7 09:40:19 [conn64] getmore local.oplog.rs cid:3504933112664086473 getMore: { ts: { $gte: new Date(5513980079480242292) } }  bytes:20 nreturned:0 3238ms<br />
Tue Sep  7 09:40:23 [conn64] getmore local.oplog.rs cid:3504933112664086473 getMore: { ts: { $gte: new Date(5513980079480242292) } }  bytes:156 nreturned:1 3482ms<br />
Tue Sep  7 09:40:28 [conn64] getmore local.oplog.rs cid:3504933112664086473 getMore: { ts: { $gte: new Date(5513980079480242292) } }  bytes:20 nreturned:0 4331ms<br />
# 第三台日志<br />
Tue Sep  7 09:38:41 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server<br />
Tue Sep  7 09:38:42 [conn80] end connection 192.168.0.:55860<br />
Tue Sep  7 09:38:42 [conn11] end connection 10.129.128.13:59654<br />
Tue Sep  7 09:38:42 [ReplSetHealthPollTask] replSet info 192.168.0.:20001 is now down (or slow to respond)<br />
Tue Sep  7 09:38:42 [conn79] replSet info voting yea for 1<br />
Tue Sep  7 09:38:43 [conn83] end connection 10.129.128.13:51543<br />
Tue Sep  7 09:38:43 [rs Manager] replSet not trying to elect self as responded yea to someone else recently<br />
Tue Sep  7 09:38:43 [conn82] end connection 10.129.128.13:51536<br />
Tue Sep  7 09:38:43 [initandlisten] connection accepted from 10.129.128.13:53129 #84<br />
Tue Sep  7 09:38:45 [initandlisten] connection accepted from 10.129.128.13:53133 #85<br />
Tue Sep  7 09:38:45 [initandlisten] connection accepted from 10.129.128.13:53137 #86<br />
Tue Sep  7 09:38:52 [rs_sync] replSet SECONDARY<br />
Tue Sep  7 09:39:05 [conn9] end connection 10.129.128.13:59650<br />
Tue Sep  7 09:39:35 [initandlisten] connection accepted from 10.129.128.13:53141 #87</p>
<p># 第二台接管了<br />
# 关闭第一台之前<br />
&gt; db.app.find({&#8220;appid&#8221;:39}).count();<br />
Tue Sep  7 09:30:58 uncaught exception: count failed: { &#8220;errmsg&#8221; : &#8220;not master&#8221;, &#8220;ok&#8221; : 0 }</p>
<p># 关闭第一台之后<br />
&gt; use test<br />
switched to db test<br />
&gt; db.app.find({&#8220;appid&#8221;:39}).count();<br />
263797<br />
# 关闭第二台之后</p>
<p># 第二台日志<br />
Tue Sep  7 09:47:56 got kill or ctrl c or hup signal 15 (Terminated), will terminate after current cmd ends<br />
Tue Sep  7 09:47:56 [interruptThread] now exiting<br />
Tue Sep  7 09:47:56  dbexit:</p>
<p>Tue Sep  7 09:47:56 [interruptThread]    shutdown: going to close listening sockets&#8230;<br />
Tue Sep  7 09:47:56 [interruptThread]    going to close listening socket: 10<br />
Tue Sep  7 09:47:56 [interruptThread]    going to close listening socket: 11<br />
Tue Sep  7 09:47:56 [interruptThread]    going to close listening socket: 12<br />
Tue Sep  7 09:47:56 [interruptThread]    going to close listening socket: 13<br />
Tue Sep  7 09:47:56 [interruptThread]    shutdown: going to flush oplog&#8230;<br />
Tue Sep  7 09:47:56 [interruptThread]    shutdown: going to close sockets&#8230;<br />
Tue Sep  7 09:47:56 [interruptThread]    shutdown: waiting for fs preallocator&#8230;<br />
Tue Sep  7 09:47:56 [interruptThread]    shutdown: closing all files&#8230;<br />
Tue Sep  7 09:47:56 [conn57] got request after shutdown()<br />
Tue Sep  7 09:47:56 [conn3] end connection 127.0.0.1:39589<br />
ERROR: Client::shutdown not called: slaveTracking<br />
Tue Sep  7 09:47:57      closeAllFiles() finished</p>
<p>Tue Sep  7 09:47:57 [interruptThread]    shutdown: removing fs lock&#8230;<br />
Tue Sep  7 09:47:57  dbexit: really exiting now</p>
<p># 第三台日志<br />
Tue Sep  7 09:47:32 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server<br />
Tue Sep  7 09:47:35 [conn90] end connection 10.129.128.13:35571<br />
Tue Sep  7 09:47:37 [conn84] end connection 10.129.128.13:53129<br />
Tue Sep  7 09:47:37 [initandlisten] connection accepted from 10.129.128.13:35575 #91<br />
Tue Sep  7 09:47:38 [conn87] end connection 10.129.128.13:53141<br />
Tue Sep  7 09:47:39 [conn91] end connection 10.129.128.13:35575<br />
Tue Sep  7 09:47:39 [initandlisten] connection accepted from 10.129.128.13:35580 #92<br />
Tue Sep  7 09:47:39 [initandlisten] connection accepted from 10.129.128.13:35585 #93<br />
Tue Sep  7 09:47:41 [conn92] end connection 10.129.128.13:35580<br />
Tue Sep  7 09:47:41 [initandlisten] connection accepted from 10.129.128.13:35590 #94<br />
Tue Sep  7 09:47:42 [conn93] end connection 10.129.128.13:35585<br />
Tue Sep  7 09:47:43 [conn94] end connection 10.129.128.13:35590<br />
Tue Sep  7 09:47:43 [initandlisten] connection accepted from 10.129.128.13:35596 #95<br />
Tue Sep  7 09:47:46 [conn95] end connection 10.129.128.13:35596<br />
Tue Sep  7 09:47:46 [initandlisten] connection accepted from 10.129.128.13:35601 #96<br />
Tue Sep  7 09:47:46 [initandlisten] connection accepted from 10.129.128.13:35606 #97<br />
Tue Sep  7 09:47:47 [initandlisten] connection accepted from 10.129.128.13:35611 #98<br />
Tue Sep  7 09:47:48 [conn96] end connection 10.129.128.13:35601<br />
Tue Sep  7 09:47:48 [initandlisten] connection accepted from 10.129.128.13:35616 #99<br />
Tue Sep  7 09:47:48 [conn97] end connection 10.129.128.13:35606<br />
Tue Sep  7 09:47:49 [conn98] end connection 10.129.128.13:35611<br />
Tue Sep  7 09:47:50 [conn99] end connection 10.129.128.13:35616<br />
Tue Sep  7 09:47:50 [initandlisten] connection accepted from 10.129.128.13:35621 #100<br />
Tue Sep  7 09:47:52 [conn100] end connection 10.129.128.13:35621<br />
Tue Sep  7 09:47:52 [initandlisten] connection accepted from 10.129.128.13:35626 #101<br />
Tue Sep  7 09:47:54 [conn101] end connection 10.129.128.13:35626<br />
Tue Sep  7 09:47:54 [initandlisten] connection accepted from 10.129.128.13:35631 #102<br />
Tue Sep  7 09:47:55 [initandlisten] connection accepted from 10.129.128.13:35636 #103<br />
Tue Sep  7 09:47:56 [conn102] end connection 10.129.128.13:35631<br />
Tue Sep  7 09:47:56 [initandlisten] connection accepted from 10.129.128.13:35641 #104<br />
Tue Sep  7 09:47:57 [conn103] end connection 10.129.128.13:35636<br />
Tue Sep  7 09:47:58 [conn104] end connection 10.129.128.13:35641<br />
Tue Sep  7 09:47:58 [initandlisten] connection accepted from 10.129.128.13:35646 #105<br />
Tue Sep  7 09:48:00 [conn105] end connection 10.129.128.13:35646<br />
Tue Sep  7 09:48:00 [initandlisten] connection accepted from 10.129.128.13:35651 #106<br />
Tue Sep  7 09:48:02 [conn106] end connection 10.129.128.13:35651<br />
Tue Sep  7 09:48:02 [initandlisten] connection accepted from 10.129.128.13:35656 #107<br />
Tue Sep  7 09:48:04 [initandlisten] connection accepted from 10.129.128.13:35661 #108<br />
Tue Sep  7 09:48:04 [conn107] end connection 10.129.128.13:35656<br />
Tue Sep  7 09:48:04 [initandlisten] connection accepted from 10.129.128.13:35666 #109<br />
Tue Sep  7 09:48:06 [conn108] end connection 10.129.128.13:35661<br />
Tue Sep  7 09:48:06 [conn109] end connection 10.129.128.13:35666<br />
Tue Sep  7 09:48:06 [initandlisten] connection accepted from 10.129.128.13:35671 #110<br />
Tue Sep  7 09:48:08 [conn110] end connection 10.129.128.13:35671<br />
Tue Sep  7 09:48:08 [initandlisten] connection accepted from 10.129.128.13:35676 #111<br />
Tue Sep  7 09:48:08 [initandlisten] connection accepted from 10.129.128.13:35681 #112</p>
<p># 在mongos上执行<br />
&gt; db.app.stats();         <br />
{<br />
        &#8220;sharded&#8221; : true,<br />
        &#8220;assertion&#8221; : &#8220;dbconnectionpool: connect failed replone/192.168.0.:20001,10.129.128.16:20001,10.129.128.17:20001 : connect failed to set replone/192.168.0.:20001,10.129.128.16:20001,10.129.128.17:20001&#8243;,<br />
        &#8220;assertionCode&#8221; : 11002,<br />
        &#8220;errmsg&#8221; : &#8220;db assertion failure&#8221;,<br />
        &#8220;ok&#8221; : 0<br />
}<br />
# 查看mongos日志<br />
Tue Sep  7 09:37:22 [conn8] trying reconnect to 192.168.0.:20001<br />
Tue Sep  7 09:37:22 [conn8] reconnect 192.168.0.:20001 failed couldn&#8217;t connect to server 192.168.0.:20001}<br />
Tue Sep  7 09:37:22 [conn8] MessagingPort say send() errno:9 Bad file descriptor 192.168.0.:20001<br />
Tue Sep  7 09:37:22 [conn8] trying reconnect to 10.129.128.16:20001<br />
Tue Sep  7 09:37:22 [conn8] reconnect 10.129.128.16:20001 failed couldn&#8217;t connect to server 10.129.128.16:20001}<br />
Tue Sep  7 09:37:22 [conn8] MessagingPort say send() errno:9 Bad file descriptor 10.129.128.16:20001<br />
Tue Sep  7 09:37:23 [conn8] MessagingPort say send() errno:9 Bad file descriptor 192.168.0.:20001<br />
Tue Sep  7 09:37:23 [conn8] checkmaster: caught exception 192.168.0.:20001 socket exception<br />
Tue Sep  7 09:37:23 [conn8] MessagingPort say send() errno:9 Bad file descriptor 10.129.128.16:20001<br />
Tue Sep  7 09:37:23 [conn8] checkmaster: caught exception 10.129.128.16:20001 socket exception<br />
Tue Sep  7 09:37:24 [conn8] checkmaster: 10.129.128.17:20001 { ismaster: false, secondary: true, hosts: [ "10.129.128.17:20001", "10.129.128.16:20001", "192.168.0.:20001" ], ok: 1.0 }<br />
DBException in process: dbconnectionpool: connect failed replone/192.168.0.:20001,10.129.128.16:20001,10.129.128.17:20001 : connect failed to set replone/192.168.0.:20001,10.129.128.16:20001,10.129.128.17:20001</p>
<p># 再启动第一台<br />
Tue Sep  7 09:55:05 [initandlisten] waiting for connections on port 20001<br />
Tue Sep  7 09:55:06 [websvr] web admin interface listening on port 21001<br />
Tue Sep  7 09:55:06 [startReplSets] replSet can&#8217;t get local.system.replset config from self or any seed (yet)<br />
Tue Sep  7 09:55:06 [initandlisten] connection accepted from 10.129.128.13:43597 #1<br />
Tue Sep  7 09:55:07 [initandlisten] connection accepted from 10.129.128.13:43601 #2<br />
Tue Sep  7 09:55:07 [initandlisten] connection accepted from 10.129.128.17:50440 #3<br />
Tue Sep  7 09:55:07 [initandlisten] connection accepted from 10.129.128.13:43606 #4<br />
Tue Sep  7 09:55:08 [conn1] end connection 10.129.128.13:43597<br />
Tue Sep  7 09:55:08 [initandlisten] connection accepted from 10.129.128.13:43610 #5<br />
Tue Sep  7 09:55:09 [conn2] end connection 10.129.128.13:43601<br />
Tue Sep  7 09:55:09 [conn4] end connection 10.129.128.13:43606<br />
Tue Sep  7 09:55:10 [conn5] end connection 10.129.128.13:43610<br />
Tue Sep  7 09:55:10 [initandlisten] connection accepted from 10.129.128.13:43614 #6<br />
Tue Sep  7 09:55:11 [initandlisten] connection accepted from 10.129.128.13:43618 #7<br />
Tue Sep  7 09:55:12 [conn6] end connection 10.129.128.13:43614<br />
Tue Sep  7 09:55:12 [initandlisten] connection accepted from 10.129.128.13:43622 #8<br />
Tue Sep  7 09:55:13 [conn7] end connection 10.129.128.13:43618<br />
Tue Sep  7 09:55:14 [conn8] end connection 10.129.128.13:43622<br />
Tue Sep  7 09:55:14 [initandlisten] connection accepted from 10.129.128.13:43627 #9<br />
Tue Sep  7 09:55:16 [initandlisten] connection accepted from 127.0.0.1:52018 #10<br />
Tue Sep  7 09:55:16 [rs Manager] replSet can&#8217;t see a majority, will not try to elect self<br />
Tue Sep  7 09:55:16 [conn9] end connection 10.129.128.13:43627<br />
Tue Sep  7 09:55:16 [initandlisten] connection accepted from 10.129.128.13:43632 #11<br />
Tue Sep  7 09:55:17 [conn3] replSet info voting yea for 2<br />
Tue Sep  7 09:55:18 [ReplSetHealthPollTask] replSet info 10.129.128.17:20001 is now up<br />
Tue Sep  7 09:55:23 [initandlisten] connection accepted from 10.129.128.13:43637 #12<br />
Tue Sep  7 09:55:34 [rs_sync] replSet SECONDARY<br />
Tue Sep  7 09:55:39 [initandlisten] connection accepted from 10.129.128.13:43641 #13<br />
Tue Sep  7 09:55:39 [initandlisten] connection accepted from 10.129.128.13:43646 #14</p>
<p># mongos 日志<br />
Tue Sep  7 09:41:18 [Balancer] trying reconnect to 10.129.128.16:20001<br />
Tue Sep  7 09:41:18 [Balancer] reconnect 10.129.128.16:20001 failed couldn&#8217;t connect to server 10.129.128.16:20001}<br />
Tue Sep  7 09:41:18 [Balancer] MessagingPort say send() errno:9 Bad file descriptor 10.129.128.16:20001</p>
<p>Tue Sep  7 09:49:04 [conn8] SHARD PROBLEM** shard is too big, but can&#8217;t split: ns:test.app at: shard0000:192.168.0.:20000 lastmod: 3|1 min: { appid: 50 } max: { appid: MaxKey }<br />
Tue Sep  7 09:41:24 [conn8] ERROR: splitIfShould failed: did you call done already<br />
Tue Sep  7 09:41:25 [conn8] ERROR: splitIfShould failed: did you call done already<br />
Tue Sep  7 09:41:25 [conn8] ERROR: splitIfShould failed: did you call done already<br />
Tue Sep  7 09:41:26 [conn8] ERROR: splitIfShould failed: did you call done already<br />
Tue Sep  7 09:41:27 [conn8] ERROR: splitIfShould failed: did you call done already</p>
<p># 第三台日志<br />
Tue Sep  7 09:59:13 [ReplSetHealthPollTask] replSet info 192.168.0.:20001 is now up<br />
Tue Sep  7 09:59:13 [rs Manager] replSet info electSelf 2<br />
Tue Sep  7 09:59:13 [rs Manager] replSet PRIMARY<br />
Tue Sep  7 09:59:15 [initandlisten] connection accepted from 192.168.0.:34007 #367<br />
Tue Sep  7 09:59:30 [conn367] getmore local.oplog.rs cid:1376686932421715188 getMore: { ts: { $gte: new Date(5513985237735964768) } }  bytes:20 nreturned:0 3864ms<br />
Tue Sep  7 09:59:34 [conn367] getmore local.oplog.rs cid:1376686932421715188 getMore: { ts: { $gte: new Date(5513985237735964768) } }  bytes:20 nreturned:0 3331ms<br />
Tue Sep  7 09:59:46 [conn361] insert test.app 146ms<br />
Tue Sep  7 10:00:03 [conn367] getmore local.oplog.rs cid:1376686932421715188 getMore: { ts: { $gte: new Date(5513985237735964768) } }  bytes:17292 nreturned:127 3153ms</p>
<p># 第一台日志<br />
Tue Sep  7 09:59:17 [initandlisten] connection accepted from 10.129.128.17:52303 #16<br />
Tue Sep  7 09:59:22 [conn16] end connection 10.129.128.17:52303<br />
Tue Sep  7 09:59:23 [rs Manager] replSet info not electing self, we are not freshest<br />
Tue Sep  7 09:59:24 [initandlisten] connection accepted from 10.129.128.17:52308 #17<br />
Tue Sep  7 09:59:24 [conn17] replSet info voting yea for 2<br />
Tue Sep  7 09:59:26 [rs_sync] replSet SECONDARY<br />
# 在mongos上执行<br />
db.app.stats();<br />
{<br />
        &#8220;sharded&#8221; : true,<br />
        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
        &#8220;count&#8221; : 14283754,<br />
        &#8220;size&#8221; : 1142700592,<br />
        &#8220;avgObjSize&#8221; : 80.00001904261303,<br />
        &#8220;storageSize&#8221; : 1666487296,<br />
        &#8220;nindexes&#8221; : 3,<br />
        &#8220;nchunks&#8221; : 49,<br />
        &#8220;shards&#8221; : {<br />
                &#8220;shard0000&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 2929950,<br />
                        &#8220;size&#8221; : 234396080,<br />
                        &#8220;avgObjSize&#8221; : 80.00002730422021,<br />
                        &#8220;storageSize&#8221; : 338897408,<br />
                        &#8220;numExtents&#8221; : 17,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 63943168,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 614302784,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 250733504,<br />
                                &#8220;credate_-1&#8243; : 229105728,<br />
                                &#8220;appid_1&#8243; : 134463552<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0001&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 2931296,<br />
                        &#8220;size&#8221; : 234503696,<br />
                        &#8220;avgObjSize&#8221; : 80.00000545833652,<br />
                        &#8220;storageSize&#8221; : 334808832,<br />
                        &#8220;numExtents&#8221; : 17,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 62325760,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 602178496,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 216047616,<br />
                                &#8220;credate_-1&#8243; : 249193408,<br />
                                &#8220;appid_1&#8243; : 136937472<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0002&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 3201895,<br />
                        &#8220;size&#8221; : 256151664,<br />
                        &#8220;avgObjSize&#8221; : 80.00001998816326,<br />
                        &#8220;storageSize&#8221; : 409599744,<br />
                        &#8220;numExtents&#8221; : 18,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 74790912,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 641024960,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 217669632,<br />
                                &#8220;credate_-1&#8243; : 264397760,<br />
                                &#8220;appid_1&#8243; : 158957568<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0003&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 4368056,<br />
                        &#8220;size&#8221; : 349444576,<br />
                        &#8220;avgObjSize&#8221; : 80.00002197774022,<br />
                        &#8220;storageSize&#8221; : 499348736,<br />
                        &#8220;numExtents&#8221; : 19,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 89748992,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 753092480,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 241263552,<br />
                                &#8220;credate_-1&#8243; : 308716480,<br />
                                &#8220;appid_1&#8243; : 203112448<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                },<br />
                &#8220;shard0004&#8243; : {<br />
                        &#8220;ns&#8221; : &#8220;test.app&#8221;,<br />
                        &#8220;count&#8221; : 852557,<br />
                        &#8220;size&#8221; : 68204576,<br />
                        &#8220;avgObjSize&#8221; : 80.00001876707364,<br />
                        &#8220;storageSize&#8221; : 83832576,<br />
                        &#8220;numExtents&#8221; : 13,<br />
                        &#8220;nindexes&#8221; : 3,<br />
                        &#8220;lastExtentSize&#8221; : 17845760,<br />
                        &#8220;paddingFactor&#8221; : 1,<br />
                        &#8220;flags&#8221; : 1,<br />
                        &#8220;totalIndexSize&#8221; : 115040256,<br />
                        &#8220;indexSizes&#8221; : {<br />
                                &#8220;_id_&#8221; : 44949504,<br />
                                &#8220;credate_-1&#8243; : 44302336,<br />
                                &#8220;appid_1&#8243; : 25788416<br />
                        },<br />
                        &#8220;ok&#8221; : 1<br />
                }<br />
        },<br />
        &#8220;ok&#8221; : 1<br />
}</p>
<p>第三台的数据在增长中<br />
&gt; db.app.count();<br />
849280<br />
&gt; db.app.count();<br />
874358<br />
此时已经可以写入数据了，就是说如果只有一台的时候，会无法写入数据。</p>
<p># 启动第二台</p>
<p># 日志<br />
Tue Sep  7 10:06:00 MongoDB starting : pid=19527 port=20001 dbpath=/usr/local/mongodb/repldata 64-bit<br />
Tue Sep  7 10:06:00 db version v1.6.1, pdfile version 4.5<br />
Tue Sep  7 10:06:00 git version: c5f5f9a4f3b515dfd5272d373093fd4fd58c95d9<br />
Tue Sep  7 10:06:00 sys info: Linux domU-12-31-39-06-79-A1 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41<br />
Tue Sep  7 10:06:02 [initandlisten] waiting for connections on port 20001<br />
Tue Sep  7 10:06:02 [websvr] web admin interface listening on port 21001<br />
Tue Sep  7 10:06:03 [initandlisten] connection accepted from 127.0.0.1:59008 #1<br />
Tue Sep  7 10:06:03 [rs Manager] replSet can&#8217;t see a majority, will not try to elect self<br />
Tue Sep  7 10:06:03 [initandlisten] connection accepted from 10.129.128.17:34502 #2<br />
Tue Sep  7 10:06:04 [initandlisten] connection accepted from 192.168.0.:56396 #3<br />
Tue Sep  7 10:06:05 [ReplSetHealthPollTask] replSet info 10.129.128.17:20001 is now up<br />
Tue Sep  7 10:06:05 [ReplSetHealthPollTask] replSet info 192.168.0.:20001 is now up<br />
Tue Sep  7 10:06:06 [rs_sync] replSet SECONDARY</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1040</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]MySQL’s binary log结构简介</title>
		<link>http://www.goziwa.com/?p=1036</link>
		<comments>http://www.goziwa.com/?p=1036#comments</comments>
		<pubDate>Fri, 03 Sep 2010 03:21:07 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[binlog]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1036</guid>
		<description><![CDATA[binary log,是mysql中一个非常重要的部分,其主要作用有两个:
<ul>
<li>Replication:在master端开启binary log后,binary log记录所有数据库的改动,然后slave端获得这个binary log文件内容,就可以在slave端进行同样的操作,使master和sla[......]</li></ul><p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>binary log,是mysql中一个非常重要的部分,其主要作用有两个:</p>
<ul>
<li>Replication:在master端开启binary log后,binary log记录所有数据库的改动,然后slave端获得这个binary log文件内容,就可以在slave端进行同样的操作,使master和slave保持一致.这是binary log的一个非常重要的用途.</li>
<li>备份:在某个时间点a作了一次备份,然后利用binary log记录从这个时间点a后的所有对数据库的改动,然后下一次还原的时候,利用时间点a的备份文件和这个binary log文件,就可以将数据还原至最新时点.</li>
</ul>
<p>本文简单介绍binary log的结构.<br />
注:本文中,”binary log”是指整体,包括所有binlog文件和binlog index文件,而”binlog”,是指单独的某个二进制日志文件,”binlog index”,就是指二进制日志索引文件.</p>
<p>一.开启binary log功能<br />
在my.cnf文件中添加:</p>
<div>
<div>
<pre>log-bin=master-bin
log-bin-index=master-bin.index</pre>
</div>
</div>
<p>log-bin是指定以后生成的各个binlog文件的前缀,在这里我们设为master-bin,因此以后生成的binlog文件将会是:</p>
<div>
<div>
<pre>master-bin.000001
master-bin.000002
......</pre>
</div>
</div>
<p>而log-bin-index则是指定binlog index文件的名称,这里我们设为master-bin.index.</p>
<p>二.Binary log的结构和组织<br />
1.每个binlog记录的是一个个事件,是对数据库产生变动了的事件,例如一条update语句,而select语句一般不会写入binlog,因为它对数据库不产生变动.,在这里我们简称这些事件为”event”.注意不要和mysql的stored routines中的event混淆.<br />
2.binlog index文件只有一个,它记录的是所有binlog的文件名称,引用”MySQL High Availability”中的图来表述各个binlog文件和binlog index文件之间的关系:</p>
<p><a title="Flickr 上 tim0405 的 binlog_01" href="http://www.flickr.com/photos/51652570@N06/4919852168/"><img src="http://farm5.static.flickr.com/4096/4919852168_70ec3c44d4.jpg" alt="binlog_01" width="379" height="273" /></a></p>
<p>再实例查看一下,在某个存放了binlog文件的目录下:</p>
<div>
<div>
<pre>[zhouminjun.pt@xxxx data]$ ls -l
-rw-rw---- 1 zhouminjun.pt users      973 Aug 23 17:06 mysql-bin.000001
-rw-rw---- 1 zhouminjun.pt users      106 Aug 23 17:07 mysql-bin.000002
-rw-rw---- 1 zhouminjun.pt users      324 Aug 23 17:08 mysql-bin.000003
-rw-rw---- 1 zhouminjun.pt users      598 Aug 23 21:01 mysql-bin.000004
-rw-rw---- 1 zhouminjun.pt users      149 Aug 24 08:36 mysql-bin.000005
-rw-rw---- 1 zhouminjun.pt users     3249 Aug 24 13:25 mysql-bin.000006
-rw-rw---- 1 zhouminjun.pt users      114 Aug 24 08:36 mysql-bin.index

[zhouminjun.pt@xxxx data]$ cat mysql-bin.index
./mysql-bin.000001
./mysql-bin.000002
./mysql-bin.000003
./mysql-bin.000004
./mysql-bin.000005
./mysql-bin.000006</pre>
</div>
</div>
<p>可以看到,binlog index文件其实就是很简单的记录当前所有binlog的文件名,每行一个.当你使用”RESET MASTER”、”FLUSH LOGS”这类命令时,binlog index文件也会相应变动.</p>
<p>3.再看看binlog文件,binlog文件是二进制的,直接打开是不可阅读的.有两种方法阅读其中的内容:<br />
a.在客户端中使用”show binlog events”查看:</p>
<div>
<div>
<pre>mysql&gt; show binlog events\G;
*************************** 1. row ***************************
   Log_name: mysql-bin.000005
        Pos: 4
 Event_type: Format_desc
  Server_id: 1
End_log_pos: 106
       Info: Server ver: 5.1.49-debug-log, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000005
        Pos: 106
 Event_type: Rotate
  Server_id: 1
End_log_pos: 149
       Info: mysql-bin.000006;pos=4
2 rows in set (0.00 sec)</pre>
</div>
</div>
<p>可以看到，当前有两条event,下面解释下各个字段的意义:<br />
Log_name:这个event所在的binlog名称.这里是在mysql-bin.000005<br />
Pos:这个event在当前binlog中的位置<br />
Event_type:这个event的类型,类型是有很多,当前这个是Format_desc类型<br />
Server_id:这个event是在哪个server上发生的.注意在replication中,这个server id记录的是master端的server id.<br />
End_log_pos:下一个event的位置.因此当前这个event的长度是End_log_pos-Pos.<br />
Info:直观的可读的关于本条event的信息.</p>
<p>在刚才查看binlog的时候,里面有两条event,第一条类型是Format_desc,第二条是Rotate:</p>
<hr /><strong>Format_desc</strong>:这是每一个binlog文件的头,是每一个binlog文件必有的第一个event,在这个event中,记录了一些诸如binary log格式版本,产生这个event的mysql server版本等等.</p>
<hr /><strong>Rotate</strong>:一般来说,这是每个binlog文件的结束event.有如下情况(我在5.1.49-debug-log上已测):<br />
1.当你使用”flush logs”命令时,mysql会自动在当前正在使用的binlog文件末尾加上这个rotate事件,然后就不再使用这个binlog了,同时会创建一个新的binlog文件,然后自动在新创建的这个binlog中加上一个Format_desc event,并且更新binlog index(将这个新创建的binlog文件名添加进入).<br />
2.每次重启mysqld(通过mysqladmin关闭,再手动重启)的时候,mysql也会关闭当前binlog,并且写入一个Stop event(注意不是rotate event),然后再启动的时候会按照上面一样,创建新的binlog文件并作相关工作.<br />
3.通过kill命令直接杀死掉mysql,这个时候发生没有任何event写入.</p>
<hr />其他还有很多event类型，最常见的可能就是Query了，update、delete等操作都是Query类型.通常一个update操作在binlog文件中会产生好几个event,因为为了保证主从一致,需要确保很多外部因素的一致.<br />
在这里我们引入一个分组的概念:除了format_desc和rotate,其他的event我们往往可以对其进行分组,对于事务型数据库来说，往往认为一个事务就是一个分组，对于非事务型数据库和类似create、alter这类语句来说,一条语句本身就是一个分组.<br />
那么通常,一个分区内的语句要么全都执行,要么全都不执行,在replication中,如果slave在执行一个分组内的某条语句时,mysql突然中断了,那么mysql会重新从头开始这个分组,而非从中断点继续.这就能很好的保证了事务的原则.</p>
<p>这里有一点要说明的是,用show binlog events命令查看的永远是binlog index文件中的第一个binlog文件内容,一般来说是master-bin.000001文件,要查看其他binlog文件需要使用:</p>
<pre>show binlog events in 'mysql-bin.000003';</pre>
<p>查看mysql目前正在写哪个binlog文件可以先执行”show master status\G;”查看.</p>
<p>b.使用mysql自带的工具mysqlbinlog,比如对于一个经历了正常启动,再正常关闭(mysqladmin shutdown)的binlog来说,用mysqlbinlog查看:</p>
<pre>[zhouminjun.pt@xxxxx data]$ mysqlbinlog mysql-bin.000007
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#100825 19:19:30 server id 1  end_log_pos 106   Start: binlog v 4, server v 5.1.49-debug-log created 100825 19:19:30 at startup
ROLLBACK/*!*/;
BINLOG '
Qvx0TA8BAAAAZgAAAGoAAAAAAAQANS4xLjQ5LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABC/HRMEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#100825 19:20:12 server id 1  end_log_pos 125   Stop
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;</pre>
<p>用mysqlbinlog查看binlog可能比乱一点.但是能查看到更多的内容.<br />
每个event都是以类似下面两行开始:</p>
<div>
<div>
<pre># at 267
#100825 11:57:57 server id 1  end_log_pos 335   Query   thread_id=99    exec_time=0     error_code=0</pre>
</div>
</div>
<hr />第一行的267代表这个event的起始位的位置.</p>
<hr />第二行的100825 11:57:57代表这个event开始执行的时间(对于replication来说,无论在master的binlog中还是slave的relay-log中,值是相同的,都是指在master端开始执行的时间),100825是指10年8月25.<br />
接着是master的server id.<br />
end_log_pos指的是下一个event的起始位置,注意这个值如果是在replication中的relay-log中,那这个值是直接从master处搬过来的,因此对于relay-log来说有可能是不准的.<br />
thread_id就是执行这个event的线程id.<br />
exec_time对于master端的binlog来说是执行这个event所花费的时间,对slave端的relay-log来说,这个值是slave端执行这个event结束的时间减去master端开始执行这个event的时间,因此在一些情况下，我们还能根据这个值大概分析出slave落后于master的时间.</p>
<p>原文:<a href="http://saw-unix.com/2010/08/mysqls-binary-log_details.html">http://saw-unix.com/2010/08/mysqls-binary-log_details.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1036</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[转]浅谈数据库系统中的cache</title>
		<link>http://www.goziwa.com/?p=1033</link>
		<comments>http://www.goziwa.com/?p=1033#comments</comments>
		<pubDate>Fri, 03 Sep 2010 01:13:56 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[所转]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[buffer]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[oralce]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1033</guid>
		<description><![CDATA[Cache和Buffer是两个不同的概念，简单的说，Cache是加速“读”，而buffer是缓冲“写”，前者解决读的问题，保存从磁盘上读出的数据，后者是解决写的问题，保存即将要写入到磁盘上的数据。在很多情况下，这两个名词并没有严格区分，常常把读写混合类型称为buffer cache，本文后续的论述中[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>Cache和Buffer是两个不同的概念，简单的说，Cache是加速“读”，而buffer是缓冲“写”，前者解决读的问题，保存从磁盘上读出的数据，后者是解决写的问题，保存即将要写入到磁盘上的数据。在很多情况下，这两个名词并没有严格区分，常常把读写混合类型称为buffer cache，本文后续的论述中，统一称为cache。</p>
<p>Oracle中的log buffer是解决redo写入的问题，而data buffer cache则解决data block的读写问题。对于Oracle来说，如果IO没有在SGA中命中，都会发生物理IO，Oracle并不关心底层存储的类型，可能是一套存储系统，可能是本地磁盘，可能是RAID 10，也可能是RAID 5，可能是文件系统，也可能是裸设备，或是ASM。总之，Oracle把底层的存储系统称为存储子系统。</p>
<p>在存储系统中，cache几乎无处不在（在后面的论述中，我们统称为cache），文件系统有cache，存储有cache，RAID控制器上有cache，磁盘上也有cache。为了提高性能，Oracle的一个写操作，很有可能写在存储的cache上就返回了，如果这时存储系统发生问题，Oracle如何来保证数据一致性的问题。</p>
<p>Oracle数据库最重要的特性是：Write ahead logging，在data block在写入前，必须保证首先写入redo log，在事务commit时，同时必须保证redo log被写入。Oracle为了保证数据的一致性，对于redo log采用了<strong>direct IO</strong>，Direct IO会跳过了OS上文件系统的cache这一层。但是，OS管不了存储这一层，虽然跳过了文件系统的cache，但是依然可能写在存储的cache上。</p>
<p>一般的存储都有cache，为了提高性能，写操作在cache上完成就返回给OS了，我们称这种写操作为write back，为了保证掉电时cache中的内容不会丢失，存储都有电池保护，这些电池可以供存储在掉电后工作一定时间，保证cache中的数据被刷入磁盘，不会丢失。不同于UPS，电池能够支撑的时间很短，一般都在30分钟以内，只要保证cache中的数据被写入就可以了。存储可以关闭写cache，这时所有的写操作必须写入到磁盘才返回，我们称这种写操作为write throuogh，当存储发现某些部件不正常时，存储会自动关闭写cache，这时写性能会下降。</p>
<p>RAID卡上也有cache，一般是256M，同样是通过电池来保护的，不同于存储的是，这个电池并不保证数据可以被写入到磁盘上，而是为cache供电以保护数据不丢失，一般可以支撑几天的时间。还有些RAID卡上有flash cache，掉电后可以将cache中的内容写入到flash cache中，保证数据不丢失。如果你的数据库没有存储，而是放在普通PC机的本地硬盘之上的，一定要确认主机中的RAID卡是否有电池，很多硬件提供商默认是不配置电池的。当然，RAID卡上的cache同样可以选择关闭。</p>
<p>磁盘上的cache，一般是16M-64M，很多存储厂商都明确表示，存储中磁盘的cache是禁用的，这也是可以理解的，为了保证数据可靠性，而存储本身又提供了非常大的cache，相比较而言，磁盘上的cache就不再那么重要。SCSI指令中有一个FUA(Force Unit Access)的参数，设置这个参数时，写操作必须在磁盘上完成才可以返回，相当于禁用了磁盘的写cache。虽然没有查证到资料，但是我个人认为一旦磁盘被接入到RAID控制器中，写cache就会被禁用，这也是为了数据可靠性的考虑，我相信存储厂商应该会考虑这个问题。</p>
<p>至此，我们可以看到Oracle的一个物理IO是经历了一系列的cache之后，最终被写入到磁盘上。cache虽然可以提高性能，但是也要考虑掉电保护的问题。关于数据的一致性，是由Oracle数据库，操作系统和存储子系统共同来保证的。</p>
<p>原文:<a href="http://www.hellodba.net/2010/08/db-storage.html">http://www.hellodba.net/2010/08/db-storage.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1033</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysql 复制出错解决方法</title>
		<link>http://www.goziwa.com/?p=1029</link>
		<comments>http://www.goziwa.com/?p=1029#comments</comments>
		<pubDate>Thu, 02 Sep 2010 08:23:11 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[中断]]></category>
		<category><![CDATA[复制]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1029</guid>
		<description><![CDATA[中午正准备去吃饭,收到大量报警,10.xx.xx.xx- MySQL Replication [slave_lag] is still below threshold of 0 with -1
麻烦了,复制中断了,赶紧回办公室,连上服务器
show slave status
显示
*********[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>中午正准备去吃饭,收到大量报警,10.xx.xx.xx- MySQL Replication [slave_lag] is still below threshold of 0 with -1</p>
<p>麻烦了,复制中断了,赶紧回办公室,连上服务器</p>
<p>show slave status</p>
<p>显示</p>
<p>*************************** 1. row ***************************<br />
               Slave_IO_State: Waiting for master to send event<br />
                  Master_Host: 10.xx.xx.xx<br />
                  Master_User: repl<br />
                  Master_Port: 3306<br />
                Connect_Retry: 60<br />
              Master_Log_File: 100025.000377<br />
          Read_Master_Log_Pos: 261910<br />
               Relay_Log_File: 100026-relay-bin.001279<br />
                Relay_Log_Pos: 243970<br />
        Relay_Master_Log_File: 100025.000377<br />
             Slave_IO_Running: Yes<br />
            Slave_SQL_Running: No<br />
              Replicate_Do_DB:<br />
          Replicate_Ignore_DB:<br />
           Replicate_Do_Table:<br />
       Replicate_Ignore_Table:<br />
      Replicate_Wild_Do_Table:<br />
  Replicate_Wild_Ignore_Table:<br />
                   Last_Errno: 1062<br />
                   Last_Error: Error &#8216;Duplicate entry &#8216;31bc63deb64211dfbfb1002655d7deb0-&#8217; for key &#8216;PRIMARY&#8221; on</p>
<p>query. Default database: &#8216;test&#8217;. Query: &#8216;INSE<br />
RT INTO d_twitter.t_twitter_user (user_id,content,mood,release_time,type,tags,source_desc,ip,attachment,mood_id)</p>
<p>values (&#8221;,&#8217;添加了照片印象  \&#8221;在\&#8221; <a href="http://t">http://t</a>.<br />
sdo.com/photo/index.php?r=album/view/uid/1183155325/id/661/image/5649&#8242;,&#8217;0&#8242;,&#8217;2010-09-02</p>
<p>11:24:47&#8242;,&#8217;2&#8242;,&#8221;,&#8221;,&#8217;1034744164&#8242;,&#8217;a:3:{s:5:\&#8221;title\&#8221;;s:25:\&#8221;5649-11831<br />
55325-8_260.jpg\&#8221;;s:12:\&#8221;original_url\&#8221;;s:64:\&#8221;<a href="http://photo.staticsdo.com/a1/36/92/49/5649-1183155325">http://photo.staticsdo.com/a1/36/92/49/5649-1183155325</a>-</p>
<p>8_260.jpg\&#8221;;s:12:\&#8221;contract_url\&#8221;;s:64:\&#8221;<a href="http://photo.s">http://photo.s</a><br />
taticsdo.com/a1/36/92/49/5649-1183155325-8_260.jpg\&#8221;;}&#8217;,'31bc63deb64211dfbfb1002655d7deb0&#8242;)&#8217;<br />
                 Skip_Counter: 0<br />
          Exec_Master_Log_Pos: 243828<br />
              Relay_Log_Space: 262404<br />
              Until_Condition: None<br />
               Until_Log_File:<br />
                Until_Log_Pos: 0<br />
           Master_SSL_Allowed: No<br />
           Master_SSL_CA_File:<br />
           Master_SSL_CA_Path:<br />
              Master_SSL_Cert:<br />
            Master_SSL_Cipher:<br />
               Master_SSL_Key:<br />
        Seconds_Behind_Master: NULL<br />
Master_SSL_Verify_Server_Cert: No<br />
                Last_IO_Errno: 0<br />
                Last_IO_Error:<br />
               Last_SQL_Errno: 1062<br />
               Last_SQL_Error: Error &#8216;Duplicate entry &#8216;31bc63deb64211dfbfb1002655d7deb0-&#8217; for key &#8216;PRIMARY&#8221; on</p>
<p>query. Default database: &#8216;test&#8217;. Query: &#8216;INSE<br />
RT INTO d_twitter.t_twitter_user (user_id,content,mood,release_time,type,tags,source_desc,ip,attachment,mood_id)</p>
<p>values (&#8221;,&#8217;添加了照片印象  \&#8221;在\&#8221; <a href="http://t">http://t</a>.<br />
sdo.com/photo/index.php?r=album/view/uid/1183155325/id/661/image/5649&#8242;,&#8217;0&#8242;,&#8217;2010-09-02</p>
<p>11:24:47&#8242;,&#8217;2&#8242;,&#8221;,&#8221;,&#8217;1034744164&#8242;,&#8217;a:3:{s:5:\&#8221;title\&#8221;;s:25:\&#8221;5649-11831<br />
55325-8_260.jpg\&#8221;;s:12:\&#8221;original_url\&#8221;;s:64:\&#8221;<a href="http://photo.staticsdo.com/a1/36/92/49/5649-1183155325">http://photo.staticsdo.com/a1/36/92/49/5649-1183155325</a>-</p>
<p>8_260.jpg\&#8221;;s:12:\&#8221;contract_url\&#8221;;s:64:\&#8221;<a href="http://photo.s">http://photo.s</a><br />
taticsdo.com/a1/36/92/49/5649-1183155325-8_260.jpg\&#8221;;}&#8217;,'31bc63deb64211dfbfb1002655d7deb0&#8242;)&#8217;</p>
<p>同时收到错误日志报警</p>
<p>100902 11:28:46 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with &#8220;SLAVE START&#8221;. We stopped at log &#8216;100001.000389&#8242; position 437802</p>
<p>使用命令SHOW BINLOG EVENTS in &#8216;100001.000389&#8242; from 437802\G;</p>
<p>可以看到中断点之后的events,明显的有若干语句的 user_id为&#8221;值,说明程序有异常,和开发人员联系后,确认程序有问题,已经修正了.</p>
<p>现在就是需要跳过这些错误,恢复复制.</p>
<p>如果错误是连续的,其实可以用</p>
<p>STOP SLAVE;</p>
<p>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 15;</p>
<p>START SLAVE;</p>
<p>这样的语句,跳过所有的出错语句,但一般来说错误都是不连续的,就是中间夹杂着正确的语句,在语句比较少的情况下,可以</p>
<p>STOP SLAVE;</p>
<p>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;</p>
<p>START SLAVE;</p>
<p>一行行跳过</p>
<p>如果出错的语句比较多,最好修改my.cnf,加入</p>
<p>slave-skip-errors =1062,1032</p>
<p>或</p>
<p>slave-skip-errors =all</p>
<p>不过修改后,需要重启服务,不能动态修改,这是比较不好的地方</p>
<p>当然还有一种方法就是,如果使用了中间代理层比如amoeba,可以将原来的读写分离的两台机器,都改为读写其中一台机器,以避免复制中断造成的读写不同步.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1029</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoDB 1.6 auto sharding 测试</title>
		<link>http://www.goziwa.com/?p=1015</link>
		<comments>http://www.goziwa.com/?p=1015#comments</comments>
		<pubDate>Wed, 01 Sep 2010 09:45:10 +0000</pubDate>
		<dc:creator>学无涯</dc:creator>
				<category><![CDATA[所行]]></category>
		<category><![CDATA[auto]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[sharding]]></category>
		<category><![CDATA[测试]]></category>

		<guid isPermaLink="false">http://www.goziwa.com/?p=1015</guid>
		<description><![CDATA[1.6版终于发布了,据说sharding可以用于生产环境了,那就让我们来测试一下吧
MongoDB 1.6 is a drop-in replacement for 1.4. To upgrade, simply shutdown mongod then restart with the new b[......]<p class='read-more'><a [...]]]></description>
			<content:encoded><![CDATA[<p>1.6版终于发布了,据说sharding可以用于生产环境了,那就让我们来测试一下吧<br />
MongoDB 1.6 is a drop-in replacement for 1.4. To upgrade, simply shutdown mongod then restart with the new binaries.<br />
Sharding<br />
Sharding is now production-ready, making MongoDB horizontally scalable, with no single point of failure. A single instance of mongod can now be upgraded to a distributed cluster with zero downtime when the need arises.</p>
<p>Sharding Tutorial<br />
Sharding Documentation<br />
Upgrading a Single Server to a Cluster<br />
Replica Sets<br />
Replica sets, which provide automated failover among a cluster of n nodes, are also now available.</p>
<p>Plese note that replica pairs are now deprecated; we strongly recommend that replica pair users upgrade to replica sets.</p>
<p>Replica Set Tutorial<br />
Replica Set Documentation<br />
Upgrading Existing Setups to Replica Sets<br />
Other Improvements<br />
The w option (and wtimeout) forces writes to be propagated to n servers before returning success (this works especially well with replica sets)<br />
$or queries<br />
Improved concurrency<br />
$slice operator for returning subsets of arrays<br />
64 indexes per collection (formerly 40 indexes per collection)<br />
64-bit integers can now be represented in the shell using NumberLong<br />
The findAndModify command now supports upserts. It also allows you to specify fields to return<br />
$showDiskLoc option to see disk location of a document<br />
Support for IPv6 and UNIX domain sockets<br />
 </p>
<p>第零步：安装<br />
cd /root/upload</p>
<p>curl <a href="http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-1.6.1.tgz">http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-1.6.1.tgz</a> &gt; mongo.tgz</p>
<p>tar xzf mongo.tgz</p>
<p>mv mongodb-linux-x86_64-1.6.1 /usr/local/mongodb</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>3db:192.168.0.15 192.168.0.16 192.168.0.17<br />
1config:192.168.0.14<br />
1mongos:192.168.0.13</p>
<p>第一步：在三台db服务器分别启动mongod进程 First, start up a couple _mongod_s to be your shards.</p>
<p>mkdir /usr/local/mongodb/data<br />
mkdir /usr/local/mongodb/log</p>
<p>/usr/local/mongodb/bin/mongod &#8211;shardsvr &#8211;dbpath /usr/local/mongodb/data &#8211;port 20000 &gt; /usr/local/mongodb/log/shard.log &amp;</p>
<p>cat /usr/local/mongodb/log/shard.log<br />
第二步：在一台config服务器启动mongod进程 Now you need a configuration server and mongos:<br />
mkdir /usr/local/mongodb/config<br />
mkdir /usr/local/mongodb/log</p>
<p>/usr/local/mongodb/bin/mongod &#8211;configsvr &#8211;dbpath /usr/local/mongodb/config &#8211;port 20000 &gt; /usr/local/mongodb/log/configdb.log &amp;</p>
<p>cat /usr/local/mongodb/log/configdb.log</p>
<p>第三步：启动mongos进程，为方便测试，块大小设置为1M，不要在生产环境中这样设置<br />
mkdir /usr/local/mongodb/log</p>
<p>/usr/local/mongodb/bin/mongos &#8211;configdb 192.168.0.14:20000 &#8211;chunkSize 1 &gt; /usr/local/mongodb/log/mongos.log &amp;</p>
<p>cat /usr/local/mongodb/log/mongos.log</p>
<p>第四步：建立集群 Setting up the Cluster<br />
# We need to run a few commands on the shell to hook everything up. Start the shell, connecting to the mongos process (at localhost:27017 if you followed the</p>
<p>steps above).<br />
# To set up our cluster, we&#8217;ll add the two shards (a and b).</p>
<p>/usr/local/mongodb/bin/mongo</p>
<p>use admin</p>
<p># 添加服务器<br />
db.runCommand( { addshard : &#8220;192.168.0.15:20000&#8243; } )<br />
{ &#8220;shardadded&#8221; : &#8220;shard0000&#8243;, &#8220;ok&#8221; : 1 }</p>
<p>db.runCommand( { addshard : &#8220;192.168.0.16:20000&#8243; } )<br />
{ &#8220;shardadded&#8221; : &#8220;shard0001&#8243;, &#8220;ok&#8221; : 1 }</p>
<p>db.runCommand( { addshard : &#8220;192.168.0.17:20000&#8243; } )<br />
{ &#8220;shardadded&#8221; : &#8220;shard0001&#8243;, &#8220;ok&#8221; : 1 }</p>
<p># 设置database和collection的分区键 Now you need to tell the database that you want to spread out your data at a database and collection level. You have to</p>
<p>give the collection a key (or keys) to partition by.This is similar to creating an index on a collection.</p>
<p>db.runCommand( { enablesharding : &#8220;test&#8221; } )<br />
{&#8220;ok&#8221; : 1}</p>
<p>db.runCommand( { shardcollection : &#8220;test.app&#8221;, key : {appid : 1} } )<br />
{&#8220;ok&#8221; : 1}<br />
第五步：查看信息Administration To see what&#8217;s going on in the cluster, use the config database.</p>
<p>use config</p>
<p>show collections</p>
<p># 查看<br />
db.printShardingStatus();</p>
<p>db.runCommand({listshards:1})</p>
<p># 查看数据分布<br />
db.app.stats();</p>
<p>第六步：安装php驱动<br />
sudo pecl install mongo</p>
<p>第七步：运行php脚本<br />
vi test.php</p>
<p>&lt;?php</p>
<p>//连接localhost:27017<br />
$conn = new Mongo();</p>
<p>//选择数据库test<br />
$db = $conn-&gt;test;</p>
<p>//选择结果集<br />
$collection = $db-&gt;app;</p>
<p>for($i=1;$i&lt;10000000;$i++){</p>
<p>$data1 = mktime(0,0,0,1,1,1950);<br />
$data2 = mktime(0,0,0,1,1,2000);<br />
$rand_time = rand($data1,$data2);<br />
$credate=date(&#8220;Y-m-d H:i:s&#8221;,$rand_time);</p>
<p>$userid= rand(100000000,900000000);</p>
<p>$appid= rand(1,50);<br />
//新增<br />
$new = array(&#8216;appid&#8217; =&gt; $appid, &#8216;userid&#8217; =&gt; $userid, &#8216;credate&#8217; =&gt; $credate);<br />
$collection-&gt;insert($new);<br />
}</p>
<p>?&gt;</p>
<p>php test.php</p>
<p>发现在初期,分布不均匀,第一台DB上有100多万条,而第2,3台上各有30万条,20万条。</p>
<p>从db.printShardingStatus()也可以看出来，以下是几个时间的对比:</p>
<p><a href="http://www.goziwa.com/wp-content/uploads/2010/09/mongo01.jpg"><img class="aligncenter size-medium wp-image-1024" title="mongo01" src="http://www.goziwa.com/wp-content/uploads/2010/09/mongo01-300x237.jpg" alt="" width="300" height="237" /></a></p>
<p><a href="http://www.goziwa.com/wp-content/uploads/2010/09/mongo02.jpg"><img class="aligncenter size-medium wp-image-1025" title="mongo02" src="http://www.goziwa.com/wp-content/uploads/2010/09/mongo02-300x240.jpg" alt="" width="300" height="240" /></a></p>
<p>然后在500Ｗ数据以后，config server挂了，查看日志：</p>
<p>Wed Sep  1 17:17:43 got kill or ctrl c or hup signal 1 (Hangup), will terminate after current cmd ends<br />
Wed Sep  1 17:17:43 [interruptThread] now exiting<br />
Wed Sep  1 17:17:43  dbexit:</p>
<p>Wed Sep  1 17:17:43 [interruptThread]    shutdown: going to close listening sockets&#8230;<br />
Wed Sep  1 17:17:43 [interruptThread]    going to close listening socket: 6<br />
Wed Sep  1 17:17:43 [interruptThread]    going to close listening socket: 7<br />
Wed Sep  1 17:17:43 [interruptThread]    going to close listening socket: 8<br />
Wed Sep  1 17:17:43 [interruptThread]    going to close listening socket: 9<br />
Wed Sep  1 17:17:43 [interruptThread]    shutdown: going to flush oplog&#8230;<br />
Wed Sep  1 17:17:43  flushing op log and files</p>
<p>Wed Sep  1 17:17:43 [interruptThread]    shutdown: going to close sockets&#8230;<br />
Wed Sep  1 17:17:43 [interruptThread]    shutdown: waiting for fs preallocator&#8230;<br />
Wed Sep  1 17:17:43 [interruptThread]    shutdown: closing all files&#8230;<br />
Wed Sep  1 17:17:43      closeAllFiles() finished</p>
<p>Wed Sep  1 17:17:43 [interruptThread]    shutdown: removing fs lock&#8230;<br />
Wed Sep  1 17:17:43  dbexit: really exiting now</p>
<p>增加一台服务器测试</p>
<p>mkdir /usr/local/mongodb/data</p>
<p>/usr/local/mongodb/bin/mongod &#8211;shardsvr &#8211;dbpath /usr/local/mongodb/data &#8211;port 20001 &gt; /usr/local/mongodb/log/shard.log &amp;</p>
<p>/usr/local/mongodb/bin/mongo</p>
<p>use admin</p>
<p>db.runCommand( { addshard : &#8220;10.129.128.13:20001&#8243; } )</p>
<p>一段时间后看发现数据已经变为</p>
<p> test.app chunks:<br />
                        { &#8220;appid&#8221; : { $minKey : 1 } } &#8211;&gt;&gt; { &#8220;appid&#8221; : 1 } on : shard0003 { &#8220;t&#8221; : 34000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 1 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 3 } on : shard0003 { &#8220;t&#8221; : 31000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 3 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 4 } on : shard0003 { &#8220;t&#8221; : 33000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 4 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 5 } on : shard0003 { &#8220;t&#8221; : 36000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 5 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 6 } on : shard0003 { &#8220;t&#8221; : 39000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 6 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 7 } on : shard0003 { &#8220;t&#8221; : 37000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 7 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 8 } on : shard0003 { &#8220;t&#8221; : 40000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 8 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 9 } on : shard0002 { &#8220;t&#8221; : 6000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 9 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 10 } on : shard0002 { &#8220;t&#8221; : 7000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 10 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 11 } on : shard0003 { &#8220;t&#8221; : 42000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 11 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 12 } on : shard0002 { &#8220;t&#8221; : 9000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 12 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 13 } on : shard0001 { &#8220;t&#8221; : 10000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 13 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 14 } on : shard0002 { &#8220;t&#8221; : 11000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 14 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 15 } on : shard0001 { &#8220;t&#8221; : 12000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 15 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 16 } on : shard0002 { &#8220;t&#8221; : 13000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 16 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 17 } on : shard0001 { &#8220;t&#8221; : 14000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 17 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 18 } on : shard0002 { &#8220;t&#8221; : 15000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 18 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 19 } on : shard0001 { &#8220;t&#8221; : 16000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 19 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 20 } on : shard0002 { &#8220;t&#8221; : 17000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 20 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 21 } on : shard0001 { &#8220;t&#8221; : 18000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 21 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 22 } on : shard0002 { &#8220;t&#8221; : 19000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 22 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 23 } on : shard0001 { &#8220;t&#8221; : 20000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 23 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 25 } on : shard0002 { &#8220;t&#8221; : 21000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 25 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 26 } on : shard0001 { &#8220;t&#8221; : 22000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 26 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 27 } on : shard0002 { &#8220;t&#8221; : 23000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 27 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 28 } on : shard0001 { &#8220;t&#8221; : 24000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 28 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 29 } on : shard0002 { &#8220;t&#8221; : 25000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 29 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 30 } on : shard0001 { &#8220;t&#8221; : 26000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 30 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 31 } on : shard0002 { &#8220;t&#8221; : 27000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 31 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 32 } on : shard0001 { &#8220;t&#8221; : 30000, &#8220;i&#8221; : 2 }<br />
                        { &#8220;appid&#8221; : 32 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 33 } on : shard0001 { &#8220;t&#8221; : 42000, &#8220;i&#8221; : 1 }<br />
                        { &#8220;appid&#8221; : 33 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 34 } on : shard0001 { &#8220;t&#8221; : 29000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 34 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 35 } on : shard0002 { &#8220;t&#8221; : 40000, &#8220;i&#8221; : 1 }<br />
                        { &#8220;appid&#8221; : 35 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 36 } on : shard0003 { &#8220;t&#8221; : 32000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 36 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 37 } on : shard0003 { &#8220;t&#8221; : 35000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 37 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 38 } on : shard0003 { &#8220;t&#8221; : 38000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 38 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 39 } on : shard0003 { &#8220;t&#8221; : 41000, &#8220;i&#8221; : 0 }<br />
                        { &#8220;appid&#8221; : 39 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 40 } on : shard0000 { &#8220;t&#8221; : 3000, &#8220;i&#8221; : 181 }<br />
                        { &#8220;appid&#8221; : 40 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 41 } on : shard0000 { &#8220;t&#8221; : 3000, &#8220;i&#8221; : 182 }<br />
                        { &#8220;appid&#8221; : 41 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 42 } on : shard0000 { &#8220;t&#8221; : 5000, &#8220;i&#8221; : 12 }<br />
                        { &#8220;appid&#8221; : 42 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 43 } on : shard0000 { &#8220;t&#8221; : 6000, &#8220;i&#8221; : 1 }<br />
                        { &#8220;appid&#8221; : 43 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 44 } on : shard0000 { &#8220;t&#8221; : 3000, &#8220;i&#8221; : 184 }<br />
                        { &#8220;appid&#8221; : 44 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 45 } on : shard0000 { &#8220;t&#8221; : 6000, &#8220;i&#8221; : 2 }<br />
                        { &#8220;appid&#8221; : 45 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 46 } on : shard0000 { &#8220;t&#8221; : 41000, &#8220;i&#8221; : 1 }<br />
                        { &#8220;appid&#8221; : 46 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 47 } on : shard0000 { &#8220;t&#8221; : 4000, &#8220;i&#8221; : 108 }<br />
                        { &#8220;appid&#8221; : 47 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 48 } on : shard0000 { &#8220;t&#8221; : 4000, &#8220;i&#8221; : 109 }<br />
                        { &#8220;appid&#8221; : 48 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 49 } on : shard0000 { &#8220;t&#8221; : 4000, &#8220;i&#8221; : 110 }<br />
                        { &#8220;appid&#8221; : 49 } &#8211;&gt;&gt; { &#8220;appid&#8221; : 50 } on : shard0000 { &#8220;t&#8221; : 5000, &#8220;i&#8221; : 1 }<br />
                        { &#8220;appid&#8221; : 50 } &#8211;&gt;&gt; { &#8220;appid&#8221; : { $maxKey : 1 } } on : shard0000 { &#8220;t&#8221; : 3000, &#8220;i&#8221; : 1 }<br />
                test.people chunks:<br />
                        { &#8220;name&#8221; : { $minKey : 1 } } &#8211;&gt;&gt; { &#8220;name&#8221; : { $maxKey : 1 } } on : shard0000 { &#8220;t&#8221; : 1000, &#8220;i&#8221; : 0 }</p>
<p>数据已经进行了重新分布</p>
<p>现在的问题是,重新分布的触发条件是什么,大规模重新分布比如加入新的服务器会不会对线上业务产生影响?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goziwa.com/?feed=rss2&amp;p=1015</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
