登录 |

江西电信光猫配置

2014年06月26日 下午 22:33 | 作者:

设备型号: I-120E-Q
设备标识号: A8AD3D-48300A8AD3D893D24
硬件版本: I120EQV1B1
软件版本: 3FE54920111146
WAN信息: 默认网关 117.40.70.1
子网掩码 255.255.255.255
首选DNS服务器 202.101.224.69
备用DNS服务器 202.101.226.69
WAN连接: 接口 连接名称 启用状态 协议 连接类型 NAT VLAN 连接状态 IP 地址 掩码 默认网关 DNS服务器
pon_46_0_1 1_TR069_R_VID_46 启用 DHCP TR069 禁用 46 已连接 10.3.7.158 255.255.240.0 10.3.0.1 192.168.0.30
ppp121 2_INTERNET_R_VID_41 启用 PPPoE INTERNET 启用 41 已连接 117.40.70.15 255.255.255.255 117.40.70.1 202.101.224.69
202.101.226.69
pon_45_0_0 3_OTHER_B_VID_45 启用 Bridge OTHER 禁用 45 已连接  255.255.255.255 
GPON链路信息

连接状态: 注册成功
LOID注册状态: 注册成功
FEC能力: 支持
FEC状态: 禁用

GPON收发包情况

接收字节: 4626000 发送字节: 4256000
接收帧: 4626 发送帧: 4256
接收组播帧: 0 发送组播帧: 0
接收广播帧: 0 发送广播帧: 0
接收OMCI: 164 发送OMCI: 164
FEC错误帧: 0 HEC错误帧: 0
丢失帧: 0

告警信息

光信号状态: 正常

光模块信息

下行光功率: -20.41dbm
发送光功率: 1.88dbm

WAN信息:

默认网关 117.40.70.1
子网掩码 255.255.255.255
首选DNS服务器 202.101.224.69
备用DNS服务器 202.101.226.69

WAN连接:

接口 连接名称 启用状态 协议 连接类型 NAT VLAN 连接状态 IP 地址 掩码 默认网关 DNS服务器
pon_46_0_1 1_TR069_R_VID_46 启用 DHCP TR069 禁用 46 已连接 10.3.7.158 255.255.240.0 10.3.0.1 192.168.0.30
ppp121 2_INTERNET_R_VID_41 启用 PPPoE INTERNET 启用 41 已连接 117.40.70.15 255.255.255.255 117.40.70.1 202.101.224.69
202.101.226.69
pon_45_0_0 3_OTHER_B_VID_45 启用 Bridge OTHER 禁用 45 已连接   255.255.255.255    

比特币和比特币银行?

2014年02月1日 下午 46:21 | 作者:

人民币是中国人民银行的货币,
比特币就是世界比特币银行的唯一货币。

我们来看看这个比特币银行都能开展哪些业务:

  1. 开户
    比特币银行开户不需要身份证;
    任何人可以开无限个账户;没有账户管理费;没有最低存款额;
    但每个账户对应一个唯一的密码,只有密码才能控制账户。所以:
    不能改密码!
    忘记密码,不能挂失!
    没有任何人能够冻结你的账户,因为他没有密码!
    任何人无需密码都能看到一个账户有多少钱,查询转账汇款记录,但并不知道谁拥有这个账户!
  2. 存款
    1. 没钱怎么存款?
      到交易所购买比特币;
      挖矿获得比特币;
    2. 转账到您的比特币私人账户
  3. 转账汇款
    只需要输入收款人账户和汇款金额;
    一旦汇款成功,款项无法追回;
    10~60分钟到账;
    普通汇款无需手续费;
    快速转账需要手续费;费率不定,给得越多越能确保10分钟到账!
    支持第三方担保支付(支付宝);
  4. 贷款
    本行无法开展此项业务,因为你的账户里面的资金只属于知道密码的人,不能被银行挪用贷款。所以本银行绝不会因为挤兑破产!

PHP在命令行下和用户输入交互

2013年11月13日 下午 18:15 | 作者:


function confirm($msg, $expert='yes|y') {
	$input = propmt($msg);
	return in_array(trim($input), explode('|',$expert));
}

function propmt($msg) {
	echo $msg;
	$handle = fopen("php://stdin","r");
	return fgets($handle);
}

if ( confirm('are you sure? (yes/no)') ) {
    echo 'delete!';
}

Redis实现多机命令执行

2013年10月23日 下午 30:26 | 作者:

Agent.php

pcntl_signal(SIGCHLD, SIG_IGN);

require 'iRedis.php';

$hostname = trim(`hostname`);
$redis = new iRedis('127.0.0.1');
$redis->conn || die;

$redis2 = new iRedis('127.0.0.1');
$redis2->conn || die;

$client_list = $redis->client('setname', $hostname);
$redis->subscribe('cmd');
while ( !feof($redis->conn) ) {
        $argv = $redis->read_reply($redis->conn);
        if ( $argv === null ) {
                echo "timeout\n";
                if ( $redis->ping() ) {
                        continue;
                } else {
                        exit;
                }
        } else {
                $pid = pcntl_fork();
                if ($pid == -1) {
                        die('could not fork');
                } else if ($pid) {
                } else {
                        echo "exec\n";
                        $handle = popen($argv[2], "r");
                        while ( !feof($handle) ) {
                                if ( $response = fread($handle, 8192) ) {
                                        $redis2->publish("resp:$hostname", $response);
                                }
                        }
                        exit;
                }
        }
}

Console.php

require 'iRedis.php';
$redis = new iRedis('127.0.0.1');
$redis2 = new iRedis('127.0.0.1');

if ( empty($argv[1]) ) die("no command!\n");

$cmd = $argv[1];
if ( isset($argv[2]) ) parse_str($argv[2], $opt);

if ( !isset($opt['line']) ) $opt['line'] = "\n";

$redis->psubscribe('resp*');
$redis2->publish('cmd', $cmd." 2>&1");

$last_host = $host = '';
$hosts = array();
while ( !feof($redis->conn) ) {
        $argv = $redis->read_reply($redis->conn);
        $host = substr($argv[2],5);
        if( !array_key_exists($host, $hosts) ) $hosts[$host] = count($hosts)+1;
        if ( $argv !== null ) {
                if ( $last_host !== $host ) echo "\n\33[1;41m",str_pad($hosts[$host],3,'0',STR_PAD_LEFT)," ",$host,"\33[0m",$opt['line'];
                echo trim($argv[3]);
        }
        $last_host = $host;
}

iRedis.php

class iRedis {
        var $host;
        var $pass;
        var $port;
        var $flags;
        var $conn;

        function __construct($host=null, $port=6379) {
                if ( !empty($host) ) {
                        $this->connect($host, $port);
                }
        }

        function pconnect($host, $port=6379) {
                return $this->connect($host, $port, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
        }

        function connect($host, $port=6379, $flags=STREAM_CLIENT_CONNECT) {
                $this->host  = $host;
                $this->port  = $port;
                $this->flags = $flags;

                $this->conn  = stream_socket_client("tcp://$host:$port", $errno, $errstr, 10, $flags);
                if (!$this->conn) {
                        echo "$errstr ($errno)
\n"; return false; } if ( !empty($this->pass) ) { $this->auth($pass); } return $this->conn; } function auth($pass) { $this->pass = $pass; return $this->__call('auth', array($pass)); } function reconnect() { if ( $this->connect($this->host, $this->port, $this->flags) ) { if ( !empty($this->pass) ) { return $this->auth($this->pass); } return true; } return false; } function close() { fclose($this->conn); } function do_cmd($cmd) { if ( fwrite($this->conn, $cmd) === false ) { if ( !$this->reconnect() ) { return false; } return $this->do_cmd($cmd); } return $this->read_reply($this->conn); } function __call($name, $args) { array_unshift($args, $name); $argc = count($args); $cmd = '*'.$argc."\r\n"; foreach ( $args as $arg ) { $cmd .= '$'.strlen($arg)."\r\n".$arg."\r\n"; } return $this->do_cmd($cmd); } function read_reply($fd) { $argc = 1; $argv = array(); while ( $line = fgets($fd) ) { $val = substr($line,1,-2); switch ($line{0}) { case '+': case '-': case ':': $argv[] = $val; break; case '*': $argc = $val; continue 2; case '$': $len = $val; if ( $len > 0 ) { $buffer = ''; while ( $len > 0 && $chunk = fread($fd, $len) ) { $buffer .= $chunk; $len -= strlen($chunk); } $argv[] = $buffer; fread($fd,2); // -- ignore CRLF } else { $argv[] = null; } break; } if ( count($argv) == $argc ) { return $argc > 1 ? $argv : $argv[0]; } } } }

僵尸进程

2013年10月23日 下午 12:40 | 作者:

原则:

一个子进程死了,先变成僵尸,等待父进程收尸

父进程必须是子进程的亲爹,爷爷就不行了

如果亲爹死的早:

  1. 自动过继给init当儿子,由init收尸

如果亲爹还活着:

  1. 声明放弃抚养权,由init收尸
    pcntl_signal(SIGCHLD, SIG_IGN);
    一旦声明放弃,就无法获取子进程退出状态码:
    pcntl_waitpid(返回错误码-1)
    proc_open:proc_get_status/proc_close (返回错误码-1)
    但还有后悔药 pcntl_signal(SIGCHLD, SIG_DFL) 恢复接收信号
  2. 一个负责任的好爹,亲自收尸
    pcntl_waitpid 

    1. 阻塞等待所有子进程
      while( $pid_exited = pcntl_waitpid(-1, $status) ) {
      }
    2. 注册信号处理句柄
      pcntl_signal(SIGCHLD, function($signo){
      $pid_exited = pcntl_waitpid(-1, $status);
      });
  3. 一个不负责任的爹,活着却不管不问
    儿子死了就变成了僵尸,想当僵尸还是很难的:)

 

PHP性能checklist

2013年10月14日 上午 08:22 | 作者:

  1. 运行环境
    1. 使用最新的PHP版本 + 20%
      5.5 > 5.4 > 5.3
    2. 使用更快的OPCache缓存 + 20%
      ZendOpcache > APC
    3. 使用Nginx+PHP-FPM 而不是 Apache+mod_php
      1. Nginx
        1. workers进程数等于CPU核数
          worker_processes =  [CPU cores];
        2. 设置cpu亲密性,每个worker对于一个cpu
          worker_cpu_affinity 01 10; #双核
        3. 使用 limit_zone阻止恶意访问
          limit_req_zone  $binary_remote_addr  zone=qps1:1m   rate=3r/s;
          location /delay {
              limit_req   zone=qps1  burst=5;
          }
        4. 静态文件缓存
          location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
              expires 24h;
              log_not_found off;
          }
      2. PHP-FPM
        1. 打开error_log+slow_log,帮助你监控,迅速定位错误
          slowlog = /var/log/php-fpm.$pool.slow
          request_slowlog_timeout = 1
          php_admin_value[error_log] = /var/log/php-fpm.$pool.error
        2. 使用进程池
          PHP支持使用进程池,比如将网站前端和管理后台分别设置两个进程池:
          [fontend]
          # 前端:并发请求多,限制内存占用,限制单请求执行时长
          max_children=100;memory_limit=16M;request_terminate_timeout=15
          [backend]
          # 后端:并发请求少,占用内存大,不限制执行时间
          max_children=10;memory_limit=128M;request_terminate_timeout=0
        3. 设置合理的进程数
          取决于你的PHP程序是IO密集型还是CPU密集型,可使用htop观察;
          IO密集型:100/%MEM
          * 限制内存 php_admin_value[memory_limit] = 32M
          CPU密集型:100/%CPU
          pm = dynamic
          pm.max_children = ?
        4. 设置PHP最长执行时间
          PHP-FPM一个请求独占一个进程,如果不设置超时时间,慢请求会迅速占满所有fpm进程
          request_terminate_timeout = 15
    4. PHP的mysql扩展使用Mysqlnd驱动,而不是libmysql
      ./configure –with-mysql=mysqlnd –with-mysqli=mysqlnd –with-pdo-mysql=mysqlnd
    5. MySQL
      1. 打开慢日志
        log_slow_queries = /var/log/mysql/mysql-slow.log
        long_query_time = 1
      2. Innodb 设置
        innodb_buffer_pool_size = 1G
        innodb_log_file_size = 256M
        innodb_log_buffer_size = 4M
        innodb_flush_log_at_trx_commit = 2
        innodb_thread_concurrency = 8
        innodb_flush_method = O_DIRECT
  2. PHP
    1. 优化原则
      抓大放小(总执行时长=执行时长*执行次数)
      * 安装xhprof+XHGui;进入Hardest Hit ,按Total Wall Time(总执行时长)排序
    2. CPU
      * 监测代码执行前后的,脚本使用内存变化 

      1. 大加载
        1. 使用大数组作为配置文件
          使用hidef 一次性载入
        2. 载入不需要的类/库文件
          lazyload,按需加载库文件
      2. 反序列化
        1. 使用更快的序列化/反序列化方法
          explode > msgpack > igbinary > json> serialize
        2. 避免反序列化大对象(同大加载)
          保持小对象的序列化/反序列化,不要缓存大数据,检测方法同上
      3. 使用简单的数据/对象结构
        例如:避免对大数据集使用Active Record
    3. IOwait
      1. 架构设计上,避免单点,可水平扩展
        异步解决不了可扩展性问题,总执行时长还是一样多
      2. 设置请求timeout
        避免一个服务延迟,拖累整个页面请求
      3. 合并请求  curl/sql/redis/memcache
        * PHPIO: 循环执行IO函数,记录代码路径重复次数,例如:
        foreach ($users as $uid) {
        mysql_query(‘SELECT * FROM usr WHERE uid = $uid’)
        }
        =>
        mysql_query(‘SELECT * FROM usr WHERE uid IN (‘.implode(‘,’,$users).’)’);

垃圾评论导致WordPress登录后台奇慢无比!

2013年10月9日 下午 31:26 | 作者:

自从换了美国主机后,Wordpress后台打开就奇慢无比,调试过程:

  1. xhprof
    访问http://www.hemono.com/wp-admin/?_profile=1,结果啥也没记录下来:(
    通常的profile工具是注册一个shutdown函数,最后一次性的将结果写入磁盘;遇到这样的超时程序,需要能够实时的写入profile到存储设备,todo:让phpio支持实时记录
  2. Strace
    php-fpm进程比较多,如果使用strace-f 跟踪父进程id的话,输出的内容太杂乱,还是新建一个单独pid的测试环境:

    1. php-fpm
      新建一个debug-pool:/etc/php5/fpm/pool.d/debug.conf
      [debug]
      listen = 127.0.0.1:9001
      pm = static
      pm.max_children = 1
    2. nginx
      新建一个debug站点:
      listen:8080;
      fastcgi_pass 127.0.0.1:9001;
    3. 在htop里面找到pool-debug的进程id
      strace -s 1024 -p [debug-pool-pid]
    4. 然后在浏览器中访问http://localhost:8080,终端里面应该可以看到php-fpm的系统调用
      看了半天,发现程序在不断的执行SQL,但是strace无法定位到出错的PHP代码段,到是可以把strace显示的SQL拿到源代码目录去grep一下;
      在htop看到mysqld的cpu占用老高,把慢日志打开再说。
  3. 打开慢日志
    1. php-fpm 慢日志 /etc/php5/fpm/pool.d/debug.conf
      slowlog = /var/log/php-fpm.slow.$pool.log
      request_slowlog_timeout = 1 

      [09-Oct-2013 10:51:36]  [pool debug] pid 12263
      script_filename = /var/www/hemono.com/wp-admin/index.php
      [0x00007fc9e145ee28] mysql_query() /var/www/hemono.com/wp-includes/wp-db.php:1098
      [0x00007fc9e145ecc8] query() /var/www/hemono.com/wp-includes/wp-db.php:1379
      [0x00007fc9e145eb48] get_results() /var/www/hemono.com/wp-admin/includes/dashboard.php:612
      [0x00007fffc11dc080] wp_dashboard_recent_comments() unknown:0
      [0x00007fc9e145e8f0] call_user_func() /var/www/hemono.com/wp-admin/includes/template.php:963
      [0x00007fc9e145e7a0] do_meta_boxes() /var/www/hemono.com/wp-admin/includes/dashboard.php:206
      [0x00007fc9e145e688] wp_dashboard() /var/www/hemono.com/wp-admin/index.php:63
    2. mysql慢日志 /etc/mysql/my.cnf
      log_slow_queries        = /var/log/mysql/mysql-slow.log
      long_query_time = 1 

      # Query_time: 1.010872  Lock_time: 0.000149 Rows_sent: 50  Rows_examined: 78376
      SELECT * FROM wp_comments c LEFT JOIN wp_posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT 0, 50;
      SELECT * FROM wp_comments c LEFT JOIN wp_posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT 50, 50;
      SELECT * FROM wp_comments c LEFT JOIN wp_posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT 100, 50;
      ……
    3. 最后还是靠慢日志定位到问题:
      /wp-admin/includes/dashboard.php

      function wp_dashboard_recent_comments() {
              global $wpdb;
      
              if ( current_user_can('edit_posts') )
                      $allowed_states = array('0', '1');
              else
                      $allowed_states = array('1');
      
              // Select all comment types and filter out spam later for better query performance.
              $comments = array();
              $start = 0;
      
              $widgets = get_option( 'dashboard_widget_options' );
              $total_items = isset( $widgets['dashboard_recent_comments'] ) && isset( $widgets['dashboard_recent_comments']['items'] )
                      ? absint( $widgets['dashboard_recent_comments']['items'] ) : 5;
              // 由于垃圾评论35000多条,导致迟迟不能获得5条有效的评论,只需加个条件 c.`comment_approved` != 'spam' 过滤掉spam评论
      +        while ( count( $comments ) < 5 && $possible = $wpdb->get_results( "SELECT * FROM $wpdb->comments c LEFT JOIN $wpdb->posts p ON c.comment_post_ID = p.ID WHERE c.`comment_approved` != 'spam' AND p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT $start, 50" ) ) {
      -        while ( count( $comments ) < 5 && $possible = $wpdb->get_results( "SELECT * FROM $wpdb->comments c LEFT JOIN $wpdb->posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT $start, 50" ) ) {
      
                      foreach ( $possible as $comment ) {
                              if ( count( $comments ) >= $total_items )
                                      break;
                              if ( in_array( $comment->comment_approved, $allowed_states ) && current_user_can( 'read_post', $comment->comment_post_ID ) )
                                      $comments[] = $comment;
                      }
                      break;
                      $start = $start + 50;
              }

emlog优化(一)——罪恶的缓存

2013年09月28日 下午 56:01 | 作者:

引言

emlog使用文件缓存,将数据序列化后存放到 content/cache/,如果你的blog只有几百篇日志,那么这个缓存还是有效果的,如果用emlog运营商业化应用,添加个上千篇日志,这个缓存设计就反倒成为拖累系统的累赘。

问题原因

来看看 include/lib/cache.php 是怎么读取缓存的:

function readCache($cacheName) {
	if ( $this->{$cacheName.'_cache'} == null ) {
		$cachefile = EMLOG_ROOT . '/content/cache/' . $cacheName . '.php';
		// 如果缓存文件不存在则自动生成缓存文件
		if (!is_file($cachefile) || filesize($cachefile) <= 0) {
				if (method_exists($this, 'mc_' . $cacheName)) {
						call_user_func(array($this, 'mc_' . $cacheName));
				}
		}
		if ($fp = fopen($cachefile, 'r')) {
				$data = fread($fp, filesize($cachefile));
				fclose($fp);
				$this->{$cacheName.'_cache'} = unserialize(str_replace("{$cacheName.'_cache'};
}

fopen文件,str_replace替换保护前缀,然后unserialize数据;
来看看一个8000条日志的blog,产生多少缓存数据:

ls -lhS content/cache/
total 17M
-rw-r--r-- 1 www-data www-data 3.9M Sep 28 23:21 logtags.php
-rw-r--r-- 1 www-data www-data 3.1M Sep 28 23:21 tags.php
-rw-r--r-- 1 www-data www-data 693K Sep 28 23:21 logsort.php
-rw-r--r-- 1 www-data www-data 434K Sep 28 23:21 logalias.php
-rw-r--r-- 1 www-data www-data 7.3K Sep 28 23:21 options.php
-rw-r--r-- 1 www-data www-data 2.7K Sep 28 23:21 record.php
-rw-r--r-- 1 www-data www-data 1.4K Sep 28 23:21 newtw.php
-rw-r--r-- 1 www-data www-data 1.1K Sep 28 23:21 comment.php
-rw-r--r-- 1 www-data www-data  971 Sep 28 23:21 sort.php
-rw-r--r-- 1 www-data www-data  935 Sep 28 23:21 logatts.php
-rw-r--r-- 1 www-data www-data  829 Sep 28 23:21 link.php
-rw-r--r-- 1 www-data www-data  691 Sep 28 23:21 newlog.php
-rw-r--r-- 1 www-data www-data  679 Sep 28 23:21 user.php
-rw-r--r-- 1 www-data www-data  673 Sep 28 23:21 sta.php
-rw-r--r-- 1 www-data www-data  592 Sep 28 23:21 navi.php

缓存文件最大达到了3.9M,反序列化时间长达300~500ms,所以说嘛,不会设计缓存,还不如老老实实用数据库SELECT;

优化

优化的方向?

  1. 更快的反序列化方法,比如json、igbinary、msgpack
  2. 对象持久化:hidef

我选用hidef持久化的方法,在php-fpm启动时一次性载入大数组,每次进程请求直接引用数据对象,无需反序列化。

  1. 安装hidef
    pecl install hidef
  2. 配置hidef
    extension=hidef.so
    [hidef]
    hidef.data_path=/var/www/emlog/content/cache
  3. 修改  include/lib/cache.php
            /**
             * 写入缓存
             */
            function cacheWrite ($cacheData, $cacheName) {
                    // 为hidef写入cache,文件后缀名必须为.data
                    @file_put_contents(EMLOG_ROOT . '/content/cache/' . $cacheName . '.data', $cacheData);
                   // 原写入缓存代码 从略 ……
            }
    
            /**
             * 读取缓存文件
             */
            function readCache($cacheName) {
                    if ( $this->{$cacheName.'_cache'} == null ) {
                            if ( strpos($_SERVER['REQUEST_URI'], 'admin') === false && // 管理后台不使用hidef加速
                                    $cacheVal = hidef_fetch($cacheName) ) { // hidef_fetch 获取缓存目录下对应 ***.data 的数据
                                    if ( in_array($cacheName, array('options')) ) {
                                            $cacheVal = $cacheVal->thaw();
                                    }
                                    $this->{$cacheName.'_cache'} = $cacheVal;
                            } else {
                                    // 原读取缓存代码 从略 ……
                            }
                    }
    
                    return $this->{$cacheName.'_cache'};
            }
  4. Crontab 监控缓存目录更新,自动重载php5-fpm
    * * * * * /usr/local/bin/php5-fpm-reload 

    #!/bin/sh
    # php5-fpm-reload
    md5_new="`ls -l /var/www/emlog/content/cache | md5sum | cut -d ' ' -f1`"
    md5_old="`cat /tmp/cache.md5`"
    
    if [ "$md5_new" != "$md5_old" ]; then
            service php5-fpm reload
            echo $md5_new > /tmp/cache.md5
    fi
  5. 由于hidef将数组作为FrozenArray引用对象保存,这个对象ReadOnly,支持key读取,foreach迭代,不能赋值,unset,不能使用数组函数array_XXX 操作,可以使用thaw()导出为标准Array; emlog大量用到array_search, 写个自定义函数替换掉:
    function _array_search( $needle, $haystack, $strict=false) {
            if ( is_array($haystack) ) return array_search($needle, $haystack, $strict);
            foreach ( $haystack as $_key => $_val ) {
                    $find = $strict ? ($_val === $needle) : ($_val == $needle);
                    if ($find) return $_key;
            }
    }

优化结果

优化前 优化后 Diff Diff%
Incl. Wall Time(microsec)
执行时间(毫秒)
376,113
376 毫秒
8,921
8毫秒
-367,192 -97.6%
Incl.
PeakMemUse(bytes)
峰值内存占用
67,770,496
64Mb
522,056
0.5Mb
-67,248,440 -99.2%

关键路径优化前/后的时间差

mysql挂载data到zfs分区

2013年09月12日 上午 43:34 | 作者:

zpool create tank /dev/sdb1

rm -rf /var/lib/mysql

zfs create -o mountpoint=/var/lib/mysql tank/mysql

mysql_install_db

chcon -R -t mysqld_db_t /var/lib/mysql

/etc/my.conf
innodb_use_native_aio=false

mysql start

 

Oracle Solaris 管理:ZFS 文件系统

http://docs.oracle.com/cd/E26926_01/html/E25826/

ZFS in 30 minutes

SElinux 安全策略 引发的mysql数据库无法启动 http://blog.sina.com.cn/s/blog_53b13d950100w4yt.html
chcon -R -t mysqld_db_t /var/lib/mysql

使用tmpfs文件系统做MySQL tmpdir潜在的问题 http://www.linuxidc.com/Linux/2013-03/80696.htm
/etc/my.conf
innodb_use_native_aio=false

编译PHP5.4内存不够

2013年08月14日 下午 26:22 | 作者:

VPS编译PHP5.4报错,make:*** [ext/fileinfo/libmagic/apprentice.lo] Error 1,编译这个fileinfo扩展至少要700M内存。

https://bugs.php.net/bug.php?id=48809

解决方案:

  1. 禁用fileinfo扩展
    –disable-fileinfo
  2. 添加swap分区
  1. 进入一个目录
    cd /var/
  2. 获取256M的文件块
    dd if=/dev/zero of=swapfile bs=1024 count=262144
  3. 创建swap文件
    mkswap swapfile
  4. 激活swap文件
    swapon swapfile
  5. 查看一下swap是否正确
    swapon -s
  6. 加到fstab文件中让系统引导时自动启动
    vi /etc/fstab
    /var/swapfile swap swap defaults 0 0