linux中出现yum running yum-complete-transaction first 解决方法

没有评论

2012 年 06 月 15 日 at 下午 2:12分类:Linux

今天在用yum升级一台新机器时,顾客用ssh远程把server重新启动了。之后,在使用yum 时总是有提示信息:

There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.
The program yum-complete-transaction is found in the yum-utils package.

意思是,有未完成的yum事务,建议先运行yum-complete-transaction命令清除。

处理步骤:

# 安装 yum-complete-transaction

yum install yum-utils

# 运行 yum-complete-transaction

yum-complete-transaction --cleanup-only

# 清除可能存在的重复包

package-cleanup --dupes

# 清除可能存在的损坏包

package-cleanup --problems

让PHP更快的提供文件下载

没有评论

2012 年 06 月 12 日 at 下午 10:54分类:PHP

我们一般实现下载文件的流程是这样子的:
客户端从服务端下载文件的流程分析:
浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php),该网页的代码如下。
服务器接受到该请求以后,马上运行该down.php文件
运行该文件的时候,必然要把将要被下载的文件读入内存当中(这里是圣诞狂欢.jpg这张图片),这里通过fopen()函数完成该动作
注意:任何有关从服务器下载的文件操作,必然需要先在服务端将文件读入内存当中
现在文件已经在内存当中了,这是需要从内存当中读取文件,通过fread()函数完成该动作
需要注意的是,如果文件较大,文件应该是被分成多段返回给客户端的,并不是等文件在服务端全部读取完毕后,一次性返回给客户端,因为这样子会增加服务器的负荷。
所以我们需要在php代码中设置一次读取的字节数,比如我在下面的代码中通过$buffer=1024设置一次读取的字节数,每读取一次,就输出数据(即返回给浏览器)

代码:
 <?php
     header("Content-type:text/html;charset=utf-8");
 //    $file_name="cookie.jpg";
     $file_name="圣诞狂欢.jpg";
     //用以解决中文不能显示出来的问题
     $file_name=iconv("utf-8","gb2312",$file_name);
     $file_sub_path=$_SERVER['DOCUMENT_ROOT']."marcofly/phpstudy/down/down/";
     $file_path=$file_sub_path.$file_name;
     //首先要判断给定的文件存在与否
     if(!file_exists($file_path)){
         echo "没有该文件文件";
         return ;
     }
     $fp=fopen($file_path,"r");
     $file_size=filesize($file_path);
     //下载文件需要用到的头
     Header("Content-type: application/octet-stream"); 
     Header("Accept-Ranges: bytes"); 
     Header("Accept-Length:".$file_size); 
     Header("Content-Disposition: attachment; filename=".$file_name); 
     $buffer=1024;
     $file_count=0;
     //向浏览器返回数据
     while(!feof($fp) && $file_count<$file_size){
         $file_con=fread($fp,$buffer);
         $file_count+=$buffer;
         echo $file_con;
     }
 fclose($fp);
 ?>

几点注意事项:
header(“Content-type:text/html;charset=utf-8″)的作用:在服务器响应浏览器的请求时,告诉浏览器以编码格式为UTF-8的编码显示该内容
关于file_exists()函数不支持中文路径的问题:因为php函数比较早,不支持中文,所以如果被下载的文件名是中文的话,需要对其进行字符编码转换,否则file_exists()函数不能识别,可以使用iconv()函数进行编码转换
$file_sub_path() 我使用的是绝对路径,执行效率要比相对路径高
Header(“Content-type: application/octet-stream”)的作用:通过这句代码客户端浏览器就能知道服务端返回的文件形式
Header(“Accept-Ranges: bytes”)的作用:告诉客户端浏览器返回的文件大小是按照字节进行计算的
Header(“Accept-Length:”.$file_size)的作用:告诉浏览器返回的文件大小
Header(“Content-Disposition: attachment; filename=”.$file_name)的作用:告诉浏览器返回的文件的名称
以上四个Header()是必需的
fclose($fp)可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区,
那么如何让PHP更快的提供文件下载呢?
一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载.
请看下面的代码:

<?php
    $file = "/tmp/中文名.tar.gz";
 
    $filename = basename($file);
 
    header("Content-type: application/octet-stream");
 
    //处理中文文件名
    $ua = $_SERVER["HTTP_USER_AGENT"];
    $encoded_filename = urlencode($filename);
    $encoded_filename = str_replace("+", "%20", $encoded_filename);
    if (preg_match("/MSIE/", $ua)) {
     header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
    } else if (preg_match("/Firefox/", $ua)) {
     header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"');
    } else {
     header('Content-Disposition: attachment; filename="' . $filename . '"');
    }
 
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header("Content-Length: ". filesize($file));
    readfile($file);

恩, 现在看起来好多了, 不过还有一个问题, 那就是readfile, 虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.

输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO.

那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?

今天, 我看到了一个有意思的文章: How I PHP: X-SendFile.

我们可以使用Apache的module mod_xsendfile, 让Apache直接发送这个文件给用户:
如下:

<?php
    $file = "/tmp/中文名.tar.gz";
 
    $filename = basename($file);
 
    header("Content-type: application/octet-stream");
 
    //处理中文文件名
    $ua = $_SERVER["HTTP_USER_AGENT"];
    $encoded_filename = urlencode($filename);
    $encoded_filename = str_replace("+", "%20", $encoded_filename);
    if (preg_match("/MSIE/", $ua)) {
     header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
    } else if (preg_match("/Firefox/", $ua)) {
     header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"');
    } else {
     header('Content-Disposition: attachment; filename="' . $filename . '"');
    }
 
    header('Content-Disposition: attachment; filename="' . basename($file) . '"');
 
    //让Xsendfile发送文件
    header("X-Sendfile: $file");

X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.
Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看

原文出处:http://www.laruence.com/2012/05/02/2613.html

利用svn实现版本库的备份

5条评论

2012 年 06 月 01 日 at 下午 3:42分类:Linux

废话少说直接进入正题!
要想实现对svn版本库中的数据进行备份,那么最好的方法就是使用svn自带的工具svnsync来操作这个过程!网上搜一下这个东西,会出来很多资料的!这里记录下我自己的一些过程!
我现在有个版本库dkadmin,这个版本库是之前创建的,我现在想要对他进行备份!保证数据不会因为特殊原因而丢失!我们讲这个版本库称之为源版本库,
然后我们现在还需要创建一个新的版本库来存储这些备份的数据!
如下命令:

$ svnadmin create dump
$ printf '#!/bin/sh\nexit 0\n' > dump/hooks/pre-revprop-change
$ chmod a+x dump/hooks/pre-revprop-change

1、在备份机上创建一个空库:svnadmin create dump
2、更改该库的钩子脚本pre-revprop-change

3、基础的工作做好之后,那么需要对新创建的这个版本库进行初始化操作:

svnsync init file:///home/data/svndata/dump  svns://admin.duankou.com/trunk/dkadmin

语法是:svnsync init {你刚创建的库url} {源库url}
注意本地url是三个斜杠的:/// 至于为什么是三个 自己想去!
4、开始备份(同步):

   svnsync sync file:///home/data/svndata/dump --username fbbin--password binbin

当执行这一步的时候会输出很多信息的!会一个版本一个版本的进行备份!
整个的过程就这样子,我们可以把这个段代码写到源版本库的的hooks里面去,那么每次提交的时候就会自动备份了!

# vi post_commit
# svnsync sync file:///home/data/svndata/dump --username fbbin--password binbin #添加这段代码

这个命令可一解决本地备份和异地备份,如果是异地备份的话 ,我们可以把目标版本库的地址mount到本太机器上来,这样子的话就等同于本地操作了,另一种是在目标机器上面人为的驱动或者crontab去执行这个命令也是可以的,当然还有很多其他的方法!