记录我工作学习生活中的点点滴滴......

THINKPHP SQL解析缓存bug的研究及修复
发布于 开发框架
2012-04-02 02:44:03
4571
0

BUG形式:
我缓存默认方式为memcache ,然后开启了sql解析缓存。
这样日志一直报连接错误。错误如下

[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Undefined index: persistent CacheMemcache.class.php 第 43 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Undefined index: timeout CacheMemcache.class.php 第 45 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Undefined index: host CacheMemcache.class.php 第 47 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Undefined index: port CacheMemcache.class.php 第 47 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Undefined index: timeout CacheMemcache.class.php 第 47 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [8] Memcache::connect() [memcache.connect]: Server (tcp 0) failed with: Failed to parse address "" (0) CacheMemcache.class.php 第 47 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [2] Memcache::connect() [memcache.connect]: Can't connect to :0, Failed to parse address "" (0) CacheMemcache.class.php 第 47 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [2] Memcache::set() [memcache.set]: No servers added to memcache connection CacheMemcache.class.php 第 97 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [2] Memcache::set() [memcache.set]: No servers added to memcache connection CacheMemcache.class.php 第 97 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [2] Memcache::set() [memcache.set]: No servers added to memcache connection CacheMemcache.class.php 第 97 行. 
[ 2012-04-02T09:24:37+08:00 ] /index.php | NOTIC: [2] Memcache::set() [memcache.set]: No servers added to memcache connection CacheMemcache.class.php 第 97 行.


而不开启sql解析缓存则无错。

BUG研究
通过研究发现
手册中12.7

所以如果佝癿应用有大量癿SQL查诟需求,那举可以开启SQL览枂缓存以减少SQL览枂提高性能。
要开启SQL览枂缓存,叧需要讴置: 
'DB_SQL_BUILD_CACHE' =>true; 
即可开启数据库查诟癿SQL创建缓存,默认缓存方式为文件方式,迓可以支持xcache和apc方式
缓存,叧需要讴置: 
'DB_SQL_BUILD_QUEUE' => 'xcache' 
我们知道,一个项目癿查诟SQL癿量可能会非常巨大,所以有必要讴置下缓存癿队列长度,例如,
我们希望SQL览枂缓存丌超过20条记录,可以讴置: 
'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存癿队列长度


DB_SQL_BUILD_QUEUE 按照正常理解命名是队列缓存的形式,queue翻译过来是队列,怎么按照这个手册的理解成了sql解析缓存的形式呢?
如果找到相关代码db.class.php 第918-920行

  1. if(isset($key)) { // 写入SQL创建缓存
  2.             S($key,$sql,0,'',array('length'=>C('DB_SQL_BUILD_LENGTH'),'queue'=>C('DB_SQL_BUILD_QUEUE')));
  3.         }
复制代码

发现sql解析缓存并没有像手册上那样说的
第四个参数为空 即调用DATA_CACHE_TYPE设置的方式 并不是手册上说的File
DB_SQL_BUILD_QUEUE也证实了我的猜想,是队列缓存形式,而非sql解析缓存形式

这样出现了当启用了memcache缓存形式的时候同时启用了sql解析缓存
在sql解析用memcache进行缓存,但是传入参数缺少memcache相关的参数,导致最开始那样的错误

解决办法
在配置文件中定义DB_SQL_BUILD_TYPE然后修改db.class.php 第918-920行为

  1. if(isset($key)) { // 写入SQL创建缓存
  2.             S($key,$sql,0,C('DB_SQL_BUILD_TYPE'),array('length'=>C('DB_SQL_BUILD_LENGTH'),'queue'=>C('DB_SQL_BUILD_QUEUE')));
  3.         }
复制代码

这样就解决了这个问题

 



分享本文到:
除非特殊注明,本文版权归原作者所有,欢迎转载!转载请注明版权以及本文地址,谢谢。
转载保留版权:Pakey's BLog >>开发框架 >>THINKPHP SQL解析缓存bug的研究及修复
本文地址:http://www.pakey.net/blog/think-buildsqlcache-bug.html