记一次php数据类型隐式转换导致的MySQL宕机

今天上午忙着开发QQ公众号粉丝信息获取的需求,在本地环境下测试OK的情况下上线部署,可是代码并没有正确执行,经过一番调试,发现问题卡在DB查询上,可是这个DB查询是走唯一索引并且limit 1的,为什么会卡在这里呢,刚准备继续深挖,运维同学那边报DB压力,由一条SQL语句导致的,我过去瞄了一眼,非常不幸居然是我这条走唯一索引的语句导致的,我看了一眼,立刻明白问题所在,先来看着条SQL

1
select * from users where app_id=2497444480 and openid='38BA79AD704DDC5A4F1CA8' limit 1

这条SQL采用的是pdo绑定的方式生成的,原本应该生成如下样子

1
select * from users where app_id='2497444480' and openid='38BA79AD704DDC5A4F1CA8' limit 1

差别就是app_id的类型,可是为什么PDO会认为app_id是整型呢,这不合理啊,因为app_id也是从数据库获取出来的,数据库里面是varchar类型,php获取查询出来的数组应该也是string类型才对,经过一番查找发现有一段代码事先对数据做过二次处理,简化如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$user_info = [
[
'id' => '2492',
'app_id' => '2497444708',
'openid' => '38BA79ADEC5A4F1CA8',
'subscribe' => '1',
'nickname' => '大羊驼。',
]
];

$tmp = [];
foreach ($user_info as $k => $v) {
$tmp[$v['app_id']] = $v;
}

foreach ($tmp as $app_id => $v) {

$data = [
'app_id' => $app_id,
];

var_dump($data);
exit;
}

输出的结果是

1
2
3
4
array(1) {
["app_id"]=>
int(2497805708)
}

阅读更多

nwjs下编译sqlite3

由于网上查找的资料基本不对,特别是最后还需要手动修改build的文件夹名称,这个也是想当然的解决方法,如果使用原生node命令调试会始终报Error: Module version mismatch.

OK,具体步骤如下

1、npm install nw-gyp -g
2、git clone https://github.com/mapbox/node-sqlite3.git 到node_module/sqlite3目录下,你也可以不clone直接npm install sqlite3,但是我测试失败,所以只好先下载
3、cd node_module/sqlite3
4、npm install –build-from-source –runtime=node-webkit –target_arch=x64 –target=0.12.3 最后的–target是你的nwjs的版本
build成功之后会生成node_module/sqlite3/lib/binding/node-webkit-v0.12.3-darwin-x64/node_sqlite3.node文件,其实这个时候就已经成功了

阅读更多

Can't create test file /home/mysql/dev01.lower-test

由于迁移mysql数据库目录到磁盘的/home分区,完成之后重启mysql提示这个错误(141107 16:43:38 [Warning] Can’t create test file /home/mysql/dev01.lower-test),权限都是mysql肯定不会有错,在网上找到一篇文章,解决了这个问题
编辑 /etc/apparmor.d/usr.sbin.mysqld 文件,可以看到

阅读更多

Vagrant中nginx服务器JS/CSS文件输出乱码

刚开是在mac下用Vagrant的centos开发时遇到过一个问题,JS和CSS文件里面会出现奇特的乱码字符,从而导致JS错误,当时查了很多资料,走了很多弯路,最后在GitHub找到一个正确答案,今天突然想起来,顺便记录一下
在nginx配置文件中加上

阅读更多

go对URL参数的处理类似PHP(http_build_query)

开始用GO写一些小代码,还是无法摆脱PHP的固定思维,在请求接口的时候php很容易就想到了http_build_query,到了GO里面就不知道改怎么处理了,特别是GO的强类型,处理起来异常痛苦,今天看到文章发现我自己实现的方式太山寨了,贴一下标准做法和山寨做法,如果你有什么更好的方式,欢迎交流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func HttpBuildQuery(params map[string]string) (param_str string) {

params_arr := make([]string, 0, len(params))

for k, v := range params {
params_arr = append(params_arr, fmt.Sprintf("%s=%s", k, v))
}

//fmt.Println(params_arr)

param_str = strings.Join(params_arr, "&")
return param_str
}

func main(){
params := map[string]string{
"action": "getAccessToken",
"client_code": "aaaaa",
"client_secret": "ccccc",
"interface": "wxapi",
"time": strconv.FormatInt(time.Now().Unix(), 10),
}

param_str := HttpBuildQuery(params)

}

阅读更多

ngrok证书错误

最近项目里面需要用到ngrok代理本地vnc实现远程协助功能,于是要在服务器搭建一个ngrok server并且编译一个windows i386的ngrok client,但是编译后的程序连接server的时候始终提示证书错误

阅读更多

nodejs中对已加载的模块进行重载

最近开发nwjs的时候,有一个需求需要重新加载nodejs已经加载过的module,在nodejs的机制里面一个module只会加载一次,比如

阅读更多

neo4j import性能

如果使用MEAGE替代CREATE性能会差很多
但是如果预先创建索引和约束,MEAGE的性能则会提升百倍

186000个节点导入性能分析如下

类型 每秒创建节点 总耗时
无索引 20
有索引MEAGE 2000 75s
有索引CREATE 2100 70s

请注意,务必是先创建索引,在导入数据,如果已经开始导入,再追加索引,对已经执行的导入任务无效

查询性能

唯一约束索引要优于普通索引

查询

10000个朋友关系查询—Time:232.483103—Mem:32.19—PMem:39.81

绑定HOST之后单个用户关系查询基本在毫秒级别
朋友关系查询—Time:0.009949—Mem:1.57—PMem:1.68

阅读更多

改用hexo+rsync搭建博客

最早的时候使用过Wrodpress,后来觉得太重就自己写了一个博客(fifsky.com主站),但是依旧觉得太重,特别是编辑器特别不适合用来做技术类的文章编辑,经常会为了一些样式的丢失而切换到HTML状态编辑HTML,后来接触了markdown之后深深的爱上了这个标记语法,特别适合程序员的思维方式,后来就切换到Ghost博客,非常不幸的是这个博客对表格支持不好,需要修改一些源文件才能支持,这个非常不好,每次升级都需要重新修改,所以一直也没有把文章切换到Ghost博客里面,后来尝试过购买了MWeb软件,支持分类管理markdown,并且支持生成博客站点,不过生成的页面质量很差,模板可定制化不强,最后看到segmentfault的一篇文章推荐hexo,于是就试了一下,感觉还不错,命令行的方式配置和部署博客比较新颖,模板丰富质量很高,于是就决定采用这个,刚开始使用的github pages作为博客的部署环境,测试下来解析和速度实在不理想,就改用了rsync方式,官方插件的rsync不支持module,于是自己小改了一下,github地址hexo-deployer-rsync

阅读更多

NEO4J关系的属性

建立两个人的节点

1
2
3
4
5
6
7
8
// Create Sally
CREATE (sally:Person { name: 'Sally', age: 32 })

// Create John
CREATE (john:Person { name: 'John', age: 27 })

// Connect Sally and John as friends ,其中的since:就是关系的属性
CREATE (sally)-[:FRIEND_OF { since: 20151112 }]->(john)

这样就可以查询出sally和john建立关系的时间

1
2
3
MATCH (sally:Person { name: 'Sally' })
MATCH (john:Person { name: 'John' })
MATCH (sally)-[r:FRIEND_OF]-(john) RETURN r.since as friends_time

然后建立一个图书的节点

1
2
3
// Create Graph Databases book
CREATE (gdb:Book { title: 'Graph Databases',
authors: ['Ian Robinson', 'Jim Webber'] })

其中对图书的评分和评分时间在关系属性上,下同

阅读更多