mysql MERGE Storage Engine

mysql Merge 引擎只能用于myISAM表的合并。它能把几个相同结构的表合并成一个表来查询。而数据和索引都还在原表中储存。
假设需要记录视频每天的播放数量,但由于记录数太大,只能一天一张表来记录,如果需要查询一个月播放次数最多的10个视频。这个时候就可以创建一个merge表把一个中的30表联合成一张表,然后一条语句就能查询出来。
例子:
在mysql执行以下sql:
CREATE TABLE EXISTS `t1` (
`id` int(11) default NULL,
`value` int(11) default NULL
) ENGINE=MyISAM;

INSERT INTO `t1` (`id`, `value`) VALUES
(1, 2),
(2, 3);

CREATE TABLE `t2` (
`id` int(11) default NULL,
`value` int(11) default NULL
) ENGINE=MyISAM;

INSERT INTO `t2` (`id`, `value`) VALUES
(1, 3),
(2, 5);

CREATE TABLE IF NOT EXISTS `t` (
`id` int(11) default NULL,
`value` int(11) default NULL
) ENGINE=MRG_MyISAM UNION=(`t1`,`t2`) INSERT_METHOD=no;

然后执行
SELECT * FROM t;
SELECT id, COUNT(*) FROM t order by id;

ssh -R 反向隧道

使用ssh -R 8022:localhost:22 -N username@server.com 就能在远程服务器打开一个端口8022,发送给这个端口数据将转发给本机22端口。
默认情况下远程服务器端口绑定在lo网卡上,所以只有远程服务自己可以使用8022端口。
如果需要其他机器也能访问服务器8022端口,需要这样写:ssh -R *:8022:localhost:22 -N username@server.com, 要开启这个选项需要服务器sshd config :GatewayPorts option is enabled(我自己没有成功)
我自己的使用情况:

  • 自己家里的电脑A和公司测试服务器B 都处于内网,正常时访问不到的。
  • 国外服务器C(server.com)
  • 电脑A 执行 ssh -R 8022:localhost:22 -N username@server.com
  • 电脑B 执行 ssh -R 8023:localhost:22 -N username@server.com

这样我在任何地方都能通过服务器C去访问电脑A或者电脑B

snow leopard 修改mac地址

命令行下执行:
sudo ifconfig en0 ether xx:xx:xx:xx:xx:xx

这个命令在leopard 下是无效的。没想到在snow leopard下又重新能用了。

Tkinter 学习

最简单的例子

计算器的例子

计算器图片
计算器图片

php 原生支持memcache session

参考:http://www.ducea.com/2009/06/02/php-sessions-in-memcached/

今天突然看到有人说php session 原生支持memcache, 自己并未验证,有兴趣的同学可以试试。
具体配置:
修改php.ini文件:
; session for memcached
session.save_handler = memcache
; 127.0.0.1:11211 請自行修改成 memcached 的位置
session.save_path=”tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15″

memcache查看状态方法:
/usr/share/memcached/scripts/memcached-tool 127.0.0.1:11211 stats
/usr/share/memcached/scripts/memcached-tool 127.0.0.1:11211 display
/usr/share/memcached/scripts/memcached-tool 127.0.0.1:11211 dump

php查看memcache方法:

用python 写一个smtp 的客户端

需求

  1. 提供命令行的邮件发送模式,这样可以把php.ini的send_mail_path设置为这个脚本
  2. 命令行模式收到邮件,将邮件内容存入队列数据库即算发送完成
  3. 支持设置多个smtp帐号
  4. 该脚本需要起一个常驻进程
  5. 常驻进程主线程监听一个sock文件, sock端口用于接受外部命令,如立即检查邮件队列等
  6. 常驻进程为每个smtp帐号开启一个线程,邮件队列中有邮件时候,每个线程都能从邮件队列中读取邮件并发送,没有邮件时候,所有线程都阻塞
  7. 常驻进程需要开启一个线程没60s检查一次队列数据库是否有新邮件到达,有就加入邮件队列,同时检查是否有死掉的发送邮件的线程
  8. 命令行发送邮件前先检查常驻进程是否存在,不存在就开启一个常驻进程

下一期开发规划:

  • 支持检查远程服务是否有要发送的邮件,有就通过远程读取,并加入邮件队列

应用场景:

  • 网站如果通过自己服务sendmail发送邮件,容易被其他邮件服务当垃圾邮件过滤,所以现在只能使用google smtp帐号发送,但使用php进行smtp 邮件发送,邮件发送时间太长,而且还不能禁止大并发发送。所以想到用python来做邮件队列,能监测邮件发送的一些情况

进度:

  • 正准备开发。。。

[转载]nginx 里使用 http auth basic 认证和 ssl

转载地址:http://www.tetx.com/program/htm/tetx/blog/view/blog_id/1209961063/index.htm

nginx 安装在 /usr/local/nginx/ 目录下
1、nginx 使用 http auth basic 认证

代码可以放在 http, server, location, limit_except 段

#准备:
cd /usr/local/nginx/conf
mkdir auth
cd auth/
htpasswd -c -d .htpasswd 用户名 #回车并输入密码再回车,-c 是创建新的文件,如果已经存在就不要使用 -c 了,-d 是密码的加密方式(Use crypt() encryption for passwords.)
#编辑host配置,在 server 段加:
auth_basic “Restricted”;
auth_basic_user_file auth/.htpasswd; #可以使用相对路径,相对于 nginx.conf 位置
#检查语法:
sudo /usr/local/nginx/sbin/nginx -t
#重新启用配置:
kill -HUP `cat /usr/local/nginx/logs/nginx.pid`

注意:Since version 0.6.7 the filename path is relative to directory of nginx configuration file nginx.conf, but not to nginx prefix directory.

参考:http://wiki.nginx.org/NginxHttpAuthBasicModule
2、nginx 使用 ssl

#准备
cd /usr/local/nginx/conf
mkdir ssl
cd ssl/
sudo openssl req -new -x509 -nodes -out tetx.pem -keyout tetx.key #生成密钥对
#配置一个 server:
server {
listen 443;
server_name localhost;

ssl on;
ssl_certificate ssl/tetx.pem;
ssl_certificate_key ssl/tetx.key;

ssl_session_timeout 5m;

ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;

location / {
root html;
index index.html index.htm;
}
}

网站发送邮件被当垃圾邮件问题

网站邮件一开始使用系统的sendmail函数来发送,发现很多邮件系统都会把邮件当作垃圾邮件,用户基本上就没机会看到邮件。
而使用gmail等公共邮件服务器,每次发送邮件时间太长(平均7s左右),而且每天邮件有上限(每天500封)。为了不被当垃圾邮件,只能使用公共邮件服务了。注册一个google的企业邮局,开通50个帐号,然后根据用户id把每个用户的id平均打散到50个帐号上发送。这样网站每天能发送的邮件是 500*50=2.5万封。邮件发送时候并不即时发送,而是排到队列服务中。队列服务每次同时只发送4封邮件,一直到邮件发送完为止。将50帐号的收到的邮件都转发到一个公共邮箱,这样就可以监测每天的系统退信了。

  • 思维导图
    邮件发送思维导图
  • 队列服务代码

macOS 命令行下执行sudo 不输入密码的方式

1. 打开sudo配置文件
命令行下执行:
visudo
2. 将配置文件中
%wheel ALL=(ALL) NOPASSWD: ALL
的注释去掉
3. 将本机用户加入到wheel组
命令行下执行:
dscl . -append /Groups/wheel GroupMembership zhangwenjin
4. 注销后配置就生效了。

memcached 实现合并数据库更新的方法

方案1 memcached 中数据被替换时候,将被替换数据抛出,并同步到数据库

memcached1.4.1 修改方法:

items.c 文件

#include <arpa/inet.h>

static pthread_mutex_t notify_lock = PTHREAD_MUTEX_INITIALIZER;

static void notify_out_of_memory(char *msg)

{

   static int sockfd = -1;

   static struct sockaddr_in servaddr;

   static socklen_t len;

   static int fflags;

   /*if (strlen(msg) > 1024)

   return;*/

   pthread_mutex_lock(&notify_lock);

   do {

   if (sockfd == -1) {

   if (settings.verbose > 1) {

   fprintf(stderr, “— debug create notify socket\n”);

   }

   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {

   if (settings.verbose > 0) {

   perror(“socket error: “);

   break;

   }

   }

   /* non-block mode */

   fflags = fcntl(sockfd, F_GETFL);

   fflags |= O_NONBLOCK;

   fcntl(sockfd, F_SETFL, fflags);

  

   bzero(&servaddr, sizeof(servaddr));

   servaddr.sin_family = AF_INET;

   servaddr.sin_port = htons(12345);

   inet_aton(“127.0.0.1″, &servaddr.sin_addr);

   len = sizeof(servaddr);

   }

   sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&servaddr, len);

   if (settings.verbose > 1) {

   fprintf(stderr, “— nofity %s\n”, msg);

   }

   } while (0);

   pthread_mutex_unlock(&notify_lock);

}

修改do_item_alloc函数后7行加入

if (it->nkey > 0) {

char tmp[1024*5];

strcpy(tmp, “SET\n”);

strncpy(tmp+4, ITEM_key(it),it->nkey);

tmp[it->nkey+4] = ‘\n’;

//fprintf(stderr, “— key: %s data=’”, tmp);

strncpy(tmp+it->nkey+5, ITEM_data(it), it->nbytes);

tmp[it->nkey + 5 + it->nbytes] = ‘\0′;

notify_out_of_memory(tmp);

fprintf(stderr, “%s’\n”, tmp);

}

方案2: memcached 设置为永不过期数据不能被替换,如果数据改动时候,把数据设置完永不过期。当后50条数据都为不过期数据时候,把后50条数据同步到数据库,并主动清除。