求索路上
Yang Juven's Blog
rss
email
twitter
facebook
  • Home
  • ABOUT

mysql row lock and table lock

1 Comments
Posted on 四月 18 2011

在《深入浅出mysql》一书中,“20.3.4 InnoDB行锁实现方式”一节中,有这样一句话

InnoDB行锁是通过给索引上的索引项加锁来实现的,这个特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

尽信书不如无书,这句话我一直深信不疑,除了这句话,下面还有例子为证。可是今天的一个bug引起的研究,我才发现这句话是错误的。

先从今天的bug说起的,mysqldb有一个bug,就是当mysql抛出error

Lock wait timeout exceeded; try restarting transaction.

mysqldb并不抛出异常,而是返回空的结果集。先放开mysqldb的bug,我想知道在我的代码中,什么情况下会lock timeout。看了代码,我第一个猜测就是:是不是有些表项没有加索引,导致使用了表锁,从而出项了lock timeout。接着查询资料:

  • vairable: innodb_lock_wait_timeout。When a lock wait timeout occurs, the current statement is not executed. The current transaction is not rolled back. (Until MySQL 5.0.13 InnoDB rolled back the entire transaction if a lock wait timeout happened. ) ( from InnoDB Startup Options and System Variables )
  • variable: table_lock_wait_timeout. There is no lock wait timeout in MySQL's table locks. ( from  Server System Variables and bug  )

从以上资料,可以看出,系统变量innodb_lock_wait_timeout就等待行锁释放的过期时间,但是table_lock_wait_timeout早已经弃用。因此可以确定:就算没有使用索引,加了表锁,也不会引起lock timeout。因为当加了表锁后,根本就会一直等待下去,没有过期时间。接着就开始怀疑《mysql深入浅出》中这句话的正确性了。接着再看这些资料:

  • Record locks always lock index records, even if a table is defined with no indexes. For such cases, InnoDB creates a hidden clustered index and uses this index for record locking. ( from InnoDB Record, Gap, and Next-Key Locks )

如果你想知道,innodb是如何确定和定义clustered index,请点击 这里。

现在基本明朗了:如果查询语句加锁,但是查询条件中没有索引,mysql innodb就会自动使用“隐藏的”聚集索引,当存在主键时,这个主键就是这个表的聚集索引;如果存在NOT NULL的唯一键,也可以作为聚集索引;但是以上情况都不存在,innodb就会组合各表项、递增的row ID来定义一个主键。根本就不会加所谓的表锁。


Tags: mysql 
Categories: mysql 

JavaScript原型继承

0 Comments
Posted on 四月 15 2011

以前对javascipt的原型也是很有了解的,很久以前发过一篇文章JavaScript原型继承,谈了自己对原型继承的了解。但是了解归了解,自己还没有真正写过一个子类继承一个超类,如果你认为下面的代码是继承,那就错了,那叫做“扩展”。

// Returns true if the last character is c
String.prototype.endsWith = function(c) {
    return (c == this.charAt(this.length - 1))
}

看过上段代码的同学,相信在代码附近也看到了warning:反对使用自己的方法来扩展内建类型。在《Javascript权威指南》第五版一书中,列出了一个继承需要的步骤,或许读起来不是特别理解。那就从源头开始,看看为什么继承一个父类需要什么步骤。我这里说的源头是"constructor"。看看下段话,摘自《JavaScript权威指南:

new操作符和构造函数,用来创建了一个新的对象,然后把构造函数作为这个对象的一个方法来调用。除此之外,在创建这个空对象以后,new设置这个对象的原型。这个对象的原型就是构造函数的prototype属性的值,并且这个prototype的初始化值是一个对象,只带有一个属性constructor,其值就是构造函数。
根据上面一段话,就可以将
var a = new A();
翻译成
var a = {}; 
A.call(a); 
/* If A inherit from object, A.prototype = new Object(); A.prototype.consturctor = A; */
a.prototype = A.prototype;
那如果想写一个子类B继承父类A,需要的步骤跟上面很类似:
function B() {
    A.call(this);
     /* other initialize code */
}

B.prototype = new A(); 
B.prototype.constructor = B;
 /* If need, delete some attribute you don't want to inherit */
delete B.prototype.xx;
References & Resources:
  • JavaScript权威指南

Tags: JavaScript  prototype 
Categories:

网络(非GPS)定位原理

1 Comments
Posted on 十二月 31 2010

有次在地铁上,跟朱朝卓同学聊到这样一个话题,即可装13又省钱的方法:买个可以做3G 路由的廉价手机(比如华为U8500),再买个ipod touch,用手机打电话和wifi热点,这样不到3000元就可以享受Apple产品,经济实惠!恩,的确是个很不错的途径!但是当时我有过顾虑:ipod touch使用wifi,LBS(物理定位服务)恐怕都用不成了,因为不能用GPS了嘛!但是朱朝卓告诉我是可以的,ucweb通过wifi可以定位!当时我的想法是,难道是通过ip定位?肯定很不准确吧?

今天中午,和双木成林同学聊天得知:用wifi定位,很准确,我还是觉得应该公司ip比较固定的缘故!但是双木成林接着说,在他家里定位也很准确!这就奇怪了,难道Google跟中国运营商有合作?这样需要满足以下条件才能定位:

  1. 当用户连接网络时,运营商给用户分配地址的同时,同事记录了你的连接账号和分配ip的映射关系,通过用户的账号自然知道用户的地理位置,因为用户申请账号的时候都填写家庭或者公司地址
  2. Google可以随时根据ip去访问运行商的接口获知详细地理位置。既然google都可以,那相关部门肯定也可以啊!

如果真是这样,那就危险了?自己在任何地方,都没有隐私可言?被跨省也易如反掌啊!接着认真查看了Google Geolocaion API,发现并不是这样!

Many devices do not have native access to GPS or other location data. Additionally, GPS can take a long time to get an accurate location fix, drains battery, and does not work indoors. Because of these problems, the location API also has the ability to send various signals that the devices has access to (nearby cell sites, wifi nodes, etc) to a third-party location service provider, who can resolve the signals into a location estimate.

大概的过程是这样的:Google是很大型的公司,每天都会分配很多工作人员到各城市满大街乱跑,去收集无线热点信息(包括cell sites和wifi nodes),将那些固定、持久的无线热点以及地理信息保存到Google地理信息库中。当有浏览器或者应用程序请求地理信息时,会收集电脑或者手机附近的无线热点,发送给Google解析,从而获取详细的地址信息。

因此可以说,如果你的电脑或者手机没有无线设备或者禁用了无线设备,单凭ip是获取不到详细地理信息的!

测试:使用支持html5的浏览器(Firefox 或者 chrome)访问http://html5demos.com/geo,点击“允许”浏览器跟踪您的地理信息,如果你当前打开了无线网卡,看看定位是否准确?我的电脑是台式机,不能定位,我让我女朋友测试,不知情的她说:我是特工。

References & Resoucres:

  • Google Geolocaion API
  • HTML5中的位置定位

Tags: Geolocation  GPS 
Categories: web 

Thinking in yield

1 Comments
Posted on 十二月 20 2010

yield作为python的一个关键字,如果在函数体使用,那么这个调用这个函数返回一个“生成迭代器”(generator iterator),当然在平时都称呼为“生成器”。xrange函数就是我们常见的调用后返回生成器(当然这个是已经经过包装的生成器),xrange与range的区别是什么?常见的回答当然是:xrange省内存,在遍历的时候需要的时候才会生成所需要的时,而不像range,首先把所有的值都生成好保存在一个list中。恩,这的确是他们的最表面的区别。

为了更深入的了解生成器,还是先介绍下生成器有的特性和特点吧:

  • 可以迭代(恩,这个特性是废话,从名字都可以看出来,但是这的确是生成器最基本的一个特性)
  • 通过调用next函数或者send函数(其实next() = send(None) ),会执行到yield语句,就会被冻结,冻结后就返回它的caller;直至调用下次send函数从上次冻结点接着执行
  • 当生成器对象引用计数为0被回收时,如果发现生成器对象仍然被冻结,就会调用close函数,close函数的作用就是抛出一个GeneratorExit的异常
  • 生成器只能被迭代一次(有点惊讶?我看源码的时候,发现这个的时候也有点)

那generator是如何实现的呢?看了源码其实很简单,在初始化一个生成器对象,都需要一个参数: PyFrameObject * f。这个f就是生成器函数的栈帧,当函数被冻结时,记录这个栈帧的栈点stacktop 以及虚拟机字节码位置f_lasti。下次执行的时候直接从这个字节码位置和栈点执行。一切很简单吧!

一切谜底都要从python源码Python/ceval.c中的PyEval_EvalFrameEx开始,初始化代码:

 

    /* An explanation is in order for the next line.

       f->f_lasti now refers to the index of the last instruction
       executed.  You might think this was obvious from the name, but
       this wasn't always true before 2.3!  PyFrame_New now sets
       f->f_lasti to -1 (i.e. the index *before* the first instruction)
       and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
       does work.  Promise. */
    next_instr = first_instr + f->f_lasti + 1; 
    stack_pointer = f->f_stacktop;
    assert(stack_pointer != NULL);
    f->f_stacktop = NULL;   /* remains NULL unless yield suspends frame */

 

那yield或者说生成器都有哪些应用呢:

  • 生成迭代器(靠,又是废话)
  • 与with_statement结合使用
  • 著名的"Trampoline in python"
  • 轻量级任务
  • 其他……

Resouces & References:

  • The yield statement
  • Coroutines via Enhanced Generators
  • The with statement
  • Tramoplining in python(这个地方请看评论,我觉得评论比文章更为精彩)

Tags:  
Categories: python 

Git与SVN的不同

0 Comments
Posted on 十二月 14 2010

以前写过一个blog:Git初学习,现在读来觉得当初对于git的理解真的很肤浅,现在就来说说git与svn的不同:

  • 分布式。这是git最明显的一个特征,分布式SCM。分布式也就要求,分布式中的每台机都保存了整个代码仓库所需要的所有代码和资源,而不仅仅是当前最新版本。分布式也带来很多好处:可以在离线的情况下版本控制;另外与集中式SCM不同,即使服务器挂掉也无妨,可以采用任何一台机进行恢复。
  • 版本。svn的版本有着revision的概念,版本号是递增的。版本号能够递增,也是因为svn是集中式SCM的缘故。当多个用户同时提交时,svn服务器会将用户之间的提交操作串行。git是分布式SCM,没有递增的版本号,git采用的做法是:在保存到git之前,git将所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引,作为版本号。
  • 储存方式。svn每个版本提交时,保存的是当前版本与上个版本之间的diff。而git提交时,则是快照。比如git commit了文件A和B,则提交完成后,至少创建了5个对象,新的文件BLOB对象A和B;一个记录着目录树内容及其各个文件对应BLOB对象索引的tree对象;一个包含指向tree对象(根目录)的索引和其他提交信息元数据的commit对象。如果当前代码仓库还有文件C,由于文件C并没有修改,所以tree对象中保存的便是上个版本文件C的BLOB对象的索引。但是一旦文件被修改,比如A和B,就会创建一个新的BLOB文件对象,而不是仅仅的快照。git这种做法虽然牺牲了存储空间(现在存储空间很廉价的吧),但是当比较两个版本或者合并分支的时候,速度上会有明显的提升。
  • 真正的分支和tag。使用过svn都知道,svn中的分支和tag都是我们认为赋予的概念,都是通过svn copy复制到另外一个目录,通过目录或者人为命名标记为分支或者tag,并且人为的规定:tag是只读的,不能修改,而实际上可以修改的。而git则实现了真正的创建一个分支很简单,仅仅是创建一个branche对象,其中branche对象包含有指定commit对象的校验和(即版本号),当随着开发的进行,提交新版本时,branche对象直接修改版本号即可。创建tag也是如此,新建一个tag对象,包含指定commit对象的校验和和其他数据信息。这也就是为什么在git下,创建分支和标签为什么这么快的根本原因。

Tags: git 
Categories: linux 
« Older Entries


About Me

Feeds

  • Entries (RSS)
  • Comments (RSS)
  • 订阅到 Google Reader
  • 订阅到 抓虾
  • 订阅到 鲜果
  • 订阅到 QQ

Popular Posts

  • 又遇乱码(837)
  • Alias与WSGIScriptAlias(408)
  • mysql row lock and table lock(339)
  • TCP连接被重置的探究(310)
  • 网络(非GPS)定位原理(271)
  • python-memcached连接维护(251)
  • memcached与iptables(251)
  • GRANT与UPDATE mysql.user(251)

Recent Posts

  • mysql row lock and table lock
  • JavaScript原型继承
  • 网络(非GPS)定位原理
  • Thinking in yield
  • Git与SVN的不同
  • openvpn随机启动并自动连接
  • MapReduce初探
  • Alias与WSGIScriptAlias

Recent Comments

  • Wholesale New Era Ca:v class="hft-li...
  • Cheap NBA Hats:How often should I c...
  • NFL Jerseys:v class="hft-li...
  • jianpx:可能还需要关心sorted内部是用什么排...
  • jianpx:真幸福~...

Categories

  • 感悟(2)
  • python(8)
  • linux(3)
  • mysql(2)
  • NoSQL(1)
  • web(8)
  • 心情(3)
  • android(1)
  • C(1)
  • Distributed(2)

Archives

  • April 2011(2)
  • December 2010(4)
  • November 2010(4)
  • October 2010(3)
  • July 2010(7)
  • June 2010(6)
  • May 2010(4)
  • April 2010(2)

Blog roll

  • 徐明的博客
  • Steven Wang's Blog
  • StephenChan's Tech Space
  • Vonbo's Blog
  • 夏凯的个人博客

  • Home
  • ABOUT
  • Login
Powered by Google App Engine  |   Designed by WebTreats  |   由 xuming 提供 Micolog程序