Monthly Archives: August 2012

通过MySql日志恢复丢失的数据

最郁闷的情况是没有备份数据库,但是因为自己的疏忽不小心把数据给删除了,特别是删除了积累很久的数据,那真是想死的心都会有。

不过如果你没有关闭MySql的日志功能,那么还是有补救的方法。前两天就遇到这样一件事,一朋友由于误操作导致公司网站数据几乎全丢,并且之前没有任何备份;我上服务器查看后发现,还好MySql日志全部在(mysql下的var目录下可以看到mysql-bin.0000XX这样的文件,这个就是MySql的日至,这个里面记录了所有之前运行过的SQL语句;没有查询语句)。

既然日志还在,那就算有得救,先将二进制的日志文件转成SQL语句,MySql提供了这样的方法“mysqlbinlog”;方法还提供了–start-date和–stop-date这两个选项来确定开始和结束时间,如果不带这两个参数将恢复日至文件中的所有SQL语句,当然-u,-p,-h,-P这样的基础参数一定会有;因为是误操作导致数据丢失,所以要将结束时间定义在误操作前,不然恢复出来的数据还是和现在一样。以下命令是从bin.000001这个日志中生成2012年1月1日0点到2012年8月1日0点之间的SQL语句,并且存入1.sql中,如果有多个日志文件那就要进行多次这个动作。

cd /usr/local/mysql/bin
mysqlbinlog -uroot -p --start-date="2012-01-01 0:00:00" --stop-date="2012-08-01 0:00:00" /usr/local/mysql/bin.000001 > 1.sql

通过这个命令导出的文件估计大家都能看懂了,就是一些带了注释的SQL语句;有了这个那直接将SQL导入到MySql中即可;这里注意下,因为日至中有那个时间段所有的建库,建表,添加,删除,修改语句,所以最好将数据库恢复到导出时设定的那个开始时间点,这样不会出现语句冲突的问题;当然如果是在已经忘记时间或者有很多数据库,那么就要自己去处理下所有的SQL语句,要么将需要恢复的有关SQL整理好或者解决导入过程中所有的冲突。

这里着重提醒,恢复前一定要对现在的MySql做全面备份,以免产生更大损失

具体的导入数据方法应该就不用过多说了,只要将你导出的所有sql文件全部运行一遍即可。

mysql -uroot -p < 1.sql

PHP基于openCV实现人脸识别

最近公司在做一个面部识别的项目,突然想起来OpenCV也有相关功能,并且还有PHP的扩展;因为OpenCV是开源的,就想到配置起来玩玩。

首先我们下载OpenCV源代码进行编译,首先可以去OpenCV的官方网站(http://opencv.org/)下载最新的版本,我这里下载的是2.4.2版本。

wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.2/OpenCV-2.4.2.tar.bz2
tar -jxvf OpenCV-2.4.2.tar.bz2
cd OpenCV-2.4.2
mkdir release
cd release/
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make && make install

这里我们发现使用了cmake命令,没有的可以先安装下,我是Centos系统,直接yum install cmake

接下来就是安装facedetect的PHP扩展,一样是先到官方网站(http://www.xarg.org/project/php-facedetect/)下载最新的源码包,然后编译安装。

wget https://nodeload.github.com/infusion/PHP-Facedetect/zipball/master
unzip infusion-PHP-Facedetect-4b1dfe1.zip
cd infusion-PHP-Facedetect-4b1dfe1
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install

最后就是在php.ini中加入扩展

extension=facedetect.so

保存,重启php或Apache

/etc/init.d/php-fpm restart
/etc/init.d/httpd -k restart

这个PHP的扩展只提供了两个方法,官方网站也有具体介绍

array face_detect(string picture_path, string cascade_file)
int face_count(string picture_path, string cascade_file)

face_detect方法需要带入两个参数,照片和模版文件,输出一个数组,数组中有人脸的坐标和大小
face_count方法同样需要上面两个参数,输出是照片中人脸的数量。

下面是一个简单的例子,找出人脸并切将他框出来(因为要操作图片,所以要用到GD库):

<?php
$face = "pb.jpg";
$faces = face_detect($face, "haarcascades/haarcascade_frontalface_alt.xml");

$image = imagecreatefromjpeg ($face);
$backgroundcolor = ImageColorAllocate($image, 255, 0, 0);
if (is_array($faces)){
        foreach ($faces as $v){
                imagerectangle($image, $v[x], $v[y], $v[x]+$v[w], $v[y]+$v[h], $backgroundcolor);
        }
}
header('Content-type: image/jpeg');
imagejpeg($image);
?>

DEMO地址:http://honglei.net/demo/face.php
有人会问那个模版的XML哪里来,进入前面OpenCV的解压目录,有没有看到一个haarcascades的文件夹,进入,是不是有很多XML文件,你还会发现除了上面提到的脸的模版还有鼻子,眼睛,耳朵的;这些模版都可以用,分别能找出不同的结果,至于哪个模版好,哪个模版不好那就你自己试试看,我测试的结果是haarcascade_frontalface_alt.xml相对较准。
运行上面的PHP会发现找出了所有的脸,但是有个找错了,并且消耗的时间也比较长;要真正将这个大规模应用还需要靠你自己作一定的优化,并且还要了解下找脸的思想。
其实找脸只是看着比较酷,在实际应用中其实也没有啥地方好用的,我能想到的就是辅助生成头像和做一些利用人脸的图片。

另类的用户贡献

一说到用户贡献,一般都会想到UGC(User Generated Content),觉得是用户发的文章,用户发的照片,用户发的视频这类用户原创内容。

但是大家也要关注到用户无意间的贡献(也可以所是用户无意间的反馈),比如用户听首歌,看了一个视频都会产生很多的动作,这可能有转移到另外一个领域——“数据挖掘”了,但是我更愿意叫他们是用户贡献,因为这是你所有用户默默作出的贡献。

怎样设计这类“默默的用户贡献”呢?
首先用户明确业务的目标,你的设计不能打断或影响用户使用业务的方式和流程;然后抓住要们所需要的数据重点,通过技术手段采集他们,并且将他们“偷偷”的传回服务器。

“默默用户贡献”的使用?
我们之所以设计这个环节,就是希望这些用户贡献能给我们带来一些东西,所以一定要用好他们,因为这类的用户贡献基数非常大,并且不是可以进行的贡献,存在不确定性,所以需要有很好的统计算法来分析数据。

说到这个案例我现在也还会兴奋,这个是07年在雅虎音乐的时候的一个小设计;当时困扰音乐搜索质量的有几个方面,歌曲的正确定,歌曲的连通率,是否Spam(其中分成音乐直接跳转到网页,音乐只有一段,音乐中间有广告);这些问题其实都可以通过用户来帮忙搞定。
当时我设计了一个JS的小功能,插入在IE用户(FF没有办法取得某些数据,并且IE用户基数足够大)的音乐播放页面中;这个JS的功能是读取歌曲加载后的时长信息,记录用户播放到关闭(换歌)的时间,记录用户打开页面到开始播放的时间;其实就将这么简单的三个数据设置一个阀值,超过后就将它们传回服务器。
分解下设计中的三个值:
歌曲的总时长:这个可以判断出音乐是否完整,以及是否中间加了广告;我们很意外的得到了一个非常有意思的值”5.099“,如果是跳转别的页面的歌曲,时长总是5.099
用户播放歌曲的时间:如果时间较短一般可以判断歌曲有质量问题,或则不是那首歌曲
打开页面到开始播放的时长:这个恰好反映的连通的速度,也就是连通率,并且还是以用户准的连通率,不是我们自己服务器测试出来的(服务器的网络环境和用户真的差不少)
当然,以上取得的是海量数据,一定要通过统计方法得出问题最大的那些,然后人工解决。
因为上面这个小操作,雅虎音乐搜索在那个时期的品质是超越了百度音乐和搜狗音乐的(判断依据是我们内部的测试,如果大家要喷也没有办法)。

其实这样的应用还有很多,比如google的某些数据采集(我猜测的、个人没有证实过),因为Google地图手机版本的使用量很大,所以完全通过Google地图来采集基站和热点数据;用户打开地图一般都会打开GPS功能,这时Google就可以通过程序抓去能搜索到的基站和热点信息,并且和经纬度信息一起返回给服务器,这样就能非常快速有便捷的得到那些有用数据,然后通过海量数据的分析,入库后给其他用户使用。

再比如foursquare,通过一个很小的签到游戏可以得到那个经纬度的活地图,能知道那个店在那并且是否还在。

iphone英文系统,中文通讯录排序解决方案

一般我会使用英文的操作系统,手机也不例外,但是iPhone设置成英文系统后会有一个很郁闷的结果,就是通讯录中所有中文联系人都会被归为最后“#”号那个分类中,查找非常麻烦,但是也不能全用英文名,至少我的大部分长辈就没有英文名,用拼音更就加奇怪。

不过看了下Frameworks和在网上查找一番,还确实有了解决方案:
/System/Library/Frameworks/AddressBook.Framework/下有各种语言的文件夹,每个文件夹中都有一个ABContactSections.plist文件,这个文件就是用来控制通讯录排序的;接下来就很简单了,只要把zh_CN.lprog/下的ABContactSections.plist拷贝到English.lprog/下就可以解决(为了安全,最好能备份需要替换的文件),以此类推,你当然也可以使用日文,韩文的排序文件;最后别忘记重启你的iPhone哦。

如果你觉得名在前姓在后的显示你也不爽,那么就把ABLocalizableDefaults.plist也给替换掉,这样姓名显示方式也对了。

有些同学要问,怎么替换这个文件,先越狱,然后使用iTools等工具就可以,如果没有越狱那就不用想了。

LNMP添加ImageMagick

ImageMagick 是一个免费的创建、编辑、合成图片的软件。它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线,多边形,椭圆,曲线,附加到图片伸展旋转。

但是LNMP只默认安装了GD,在此提供下LNMP下安装ImageMagick以及imagick扩展的方法。

1、安装ImageMagick
首先要下载最新的编译包,最新的包可以在下面的地址中找到http://www.imagemagick.org/download/
我们在这里选择ImageMagick-6.7.8-8.tar.gz

wget http://www.imagemagick.org/download/ImageMagick-6.7.8-8.tar.gz
tar -zxvf ImageMagick-6.7.8-8.tar.gz
cd ImageMagick-6.7.8-8/
./configure --prefix=/usr/local/imagemagick
make && make install

安装完成后可以使用以下命令验证下

convert -version

如果正常会显示版本号;也可能会出现错误“convert: error while loading shared libraries: libMagickCore.so.3: cannot open shared object file: No such file or directory”
如果不幸出现可以使用命令

ldconfig /usr/

2、安装imagick(PHP的扩展)
和上面一样,先下载编译包,最新的包可以在下面的地址中找到http://pecl.php.net/package/imagick
我们选择imagick-3.0.1.tgz,建议尽量选择正式版本

wget http://pecl.php.net/get/imagick-3.0.1.tgz
tar -zxvf imagick-3.0.1.tgz
cd imagick-3.0.1/
export PKG_CONFIG_PATH=/usr/local/imagemagick/lib/pkgconfig
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-imagick=/usr/local/imagemagick
make && make install

3、配置php.ini
需要在php.ini中添加imagick扩展

vim /usr/local/php/etc/php.ini

然后添加:

extension = "imagick.so"

保存并退出

4、重启PHP-FPM或Apache

/etc/init.d/php-fpm restart
/etc/init.d/httpd -k restart

一般情况通过上述几部就能搞定,如果遇到问题可以Google下解决掉。
LNMP.org已经提供现成的sh,可以直接用

意外断电导致KVM无法启动

昨天服务器意外断电,结果其中一个KVM虚机死活起不来,只抱错
“Error restoring domain: operation failed: failed to read qemu header”

起初是再新建一个虚机,然后将硬盘挂上,启动,正常启动,只是原来的配置没有了,这说明虚拟的磁盘没有问题;还是想着完美恢复,就去Google搜索,发现原来是原来主机关机过程中KVM的当前状态,并在下次启动时恢复,虚拟状态文件保存在/var/lib/libvirt/qemu/save,应该是意外断电导致虚拟状态文件有缺失,无法正常读取并且恢复,解决方法就是删除虚拟状态文件。

命令:
rm -Rf /var/lib/libvirt/qemu/save/(虚机名称).save

然后重启,正常;问题解决。