`
iwindyforest
  • 浏览: 230723 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
InnoDB引擎的锁特性 mysql 骑虎的康盛,两难的站长,关于Discuz发展的讨论
说到底,这根就在这MySQL上了。大家都知道mysql傻快,但往往不知道为啥快。简而言之就是因为“简单”,程序代码简单,功能也简单——处理个简单SQL查询很快,一旦是多表连接多条件查询,立马现原形,要做结果差集操作?没门,这正是mysql不能被严格成为“关系型数据库”(RDBMS)的原因。
在discuz X系列以前,站长论坛累计的数据量不大,一般就百万条帖子吧。虽然dz代码有缺陷,mysql不给力但还是能跑跑的(忽然想起《活着》中那句‘急了也能跑’,哈哈)。到X推出后现今数据量超千万的站也不会少了,虽然康盛对新版程序构架优化、数据库优化分库上做了不少改进,但这些改进带来的一点提升却被暴增的新功能所吞噬尽,反而因为更加复杂的SQL或者因为服务器分表的多次查询延迟而更加恶化——代码级的优化已经无法环节系统的缓慢。mysql只能接受简单的查询,对于新增的关系复杂的功能多带来的复杂查询条件力不从心。

数据库此时就是整个系统的瓶颈。

即便采用了内存缓存技术(memcache),可总是有数据要写入数据库的,比如session,pv,在线时间等等。myisam一写表就锁表,遇上高流量即便没有发帖系统照样扛不住。你说换支持行锁的innodb引擎吧,可mysql不能再说自己飞快了,一个 SELECT count(*)就能让系统龟速。最坑爹的是才知道innodb的所谓行锁是锁索引,使用也是有条件的:

    InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
    在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。下面通过一些实际例子来加以说明。
    (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁。
    (2)由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是 使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。
    (3)当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索 引或普通索引,InnoDB都会使用行锁来对数据加锁。
    (4)即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决 定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突 时,别忘了检查SQL的执行计划,以确认是否真正使用了索引

    当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的 索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁 (Next-Key锁)。






这真难办啊,myisam是快,可是大并发下锁表阻塞严重,还时不时抽风坏表;innodb支持事务(先不谈支持的程度)不坏表吧可速度就慢多了(尤其是对于论坛这种经常要做select count(*)操作的)。这mysql众多引擎,各有特色,可就没一顺手放心的,还是那句话,就一坑爹的要你命3000(不知道的去看周星星的《大内密探零零七》)。
可康盛已经被mysql所捆绑了,构架优化都是针对MySQL的,比如分表到服务器,查询SQL切分连表操作为多个单表查询。要换数据库?还不如重写DZ呢。
现有新增功能已经因为历史数据而产生多多的问题,也让数据库更加疲惫,所以对于站长对新功能的呼声,官方只能忽视了。
Global site tag (gtag.js) - Google Analytics