1 |
仅供参考,我还没仔细看呢<br /><br />DATETIME 日期和时间的组合。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,但允许使用字符串或数字为DATETIME列分配值。 TIMESTAMP[(M)] 时间戳。范围是'1970-01-01 00:00:00'到2037年。 TIMESTAMP列用于INSERT或UPDATE操作时记录日期和时间。如果你不分配一个值,表中的第一个TIMESTAMP列自动设置为最近操作的日期和时间。也可以通过分配一个NULL值,将TIMESTAMP列设置为当前的日期和时间。 TIMESTAMP值返回后显示为'YYYY-MM-DD HH:MM:SS'格式的字符串,显示宽度固定为19个字符。如果想要获得数字值,应在TIMESTAMP 列添加+0。 注释:MySQL 4.1以前使用的TIMESTAMP格式在MySQL 5.1中不支持;关于旧格式的信息参见MySQL 4.1 参考手册。 |
MMAP 与 SHR
一直不太清楚Linux top命令中的SHR字段究竟都包含了些什么,前些天了解了一下MMAP,今天猜想MMAP申请的内存应该会算到SHR头上的吧,下面写了一个脚本测试了一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int ac, char **av) { int fd = open(av[1], O_RDONLY, 00777); char *fp =(char *) mmap(NULL, 1024 * 1024 * 100,PROT_READ, MAP_SHARED,fd,0); char c; int i = 0; while(i++< 1024*1024*10) { c = *fp++; } sleep(20000000); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 |
/** * 测试结果 * 1. mmap 并不立即开辟内存 * 2. 如果访问的指针到了mmap的内存的外面,会出现总线错误,当然,超过一点点或许是可以的,但一定不要超过一个页的大小 * 3. mmap的内存被当做是SHR的,这个是一定的,和mmap时的MAP_SHARED没有关系,例如: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4996 junjie2 18 0 103m 10m 10m T 0.0 0.0 0:00.04 a.out * * * */ |
代码写的比较差,不过只是为了说明问题而已,没有太多时间来写这些东西,这里仅仅记录一下,有时间再整理。
匿名的mmap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int ac, char **av) { char *fp =(char *) mmap(NULL, 1024 * 1024 * 200,PROT_READ, MAP_SHARED|MAP_ANONYMOUS, -1, 0); char c; int i = 0; if (fp == MAP_FAILED) { printf("error\n") ;exit(1); } while(i++< 1024*1024*100) { c = *(fp+i); } sleep(20000000); return 0; } |
区别于上面的代码的部分:
1. 不需要再打开一个fd
2. mmap调用时使用 MAP_ANONYMOUS 这个flag,有了这个flag,就会忽略fd参数,但是也有的实现依然要求fd参数为-1
mmap中lock到内存的部分好像也不是绝对的lock: https://blog.csdn.net/lotluck/article/details/81632071
shell 遍历mc
单行脚本:
host=10.10.10.10;port=11211;echo -e "stats cachedump 2 0\r\nquit\r\n" | nc $host $port | awk ‘{print $2;}’| while read key;do echo get $key; done | nc $host $port
ecshop模板引擎学习
ecshop模板引擎比较简单,相对于smarty要轻量多了,她的实现不到1500行的代码,一个文件搞定。
参考ecshop模板引擎的文档时,里面提到了 {if $num is odd} 的语法,觉得这个语法不错,就尝试了一下,结果失败,查看了一下模板引擎的代码,发现该语法不知道什么时候已经没有了,出于好奇,简单看了一下语法解析的实现,可以通过简单的hack来添加该语法。
在cls_template.php 的 _compile_if_tag 函数中添加如下分支:
- <?php
- …
- case ‘is’:
- $token = ‘%’;
- $i++;
- if($tokens[$i] == ‘odd’) {
- $tokens[$i] = ‘2 == 0’;
- }else if($tokens[$i] == ‘even’) {
- $tokens[$i] = ‘2 == 1’;
- }else {
- throw new exception("is odd or is even");
- }
- break;
- …
- ?>
当然,这里只共学习之用,随便hack别人的代码是不好的。
关于unix的历史(点滴)
要想学好linux就要了解unix,聊了解unix就要了解unix的历史,否则很多名词不知道啥意思; 今天从mmap开始,出现了System V(http://baike.baidu.com/view/1503404.htm);
System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支。 又一次遇到了AT&T, 以前遇到就当没看见,这次就了解一下吧; 发现这个100多年历史的公司最初居然是贝尔创建的,而所谓的“贝尔实验室”也是这个公司的一个机构,难怪很多计算机方面的东西总要和AT&T最终老跟扯上一些关系。
system-v: http://baike.baidu.com/view/1503404.htm
关于unix: http://baike.baidu.com/view/8095.htm
关于AT&T: http://baike.baidu.com/view/259956.htm
tar:从压缩包中解压出指定文件
如果你下载了一个压缩包,虽然本身不是很大,但是解压后会很大;可是你并不会去看里面所有的文件,而是只看具体的某一个或几个文件而已,这时你的磁盘空间有很有限,于是你很想只解压指定的文件,于是下面命令就可以用上了。
1. tar -ztf xx.tar.gz | grep file_you_want_to_get
看看你要解压的文件的具体路径,假设为 path/to/file
2. tar -zxf xx.tar.gz path/to/file
然后,你要的file就放到了path/to 目录下了
例如:
>tar -ztf glibc-2.9.tar.gz | grep ldconfig.c
glibc-2.9/elf/ldconfig.c
>tar -zxf glibc-2.9.tar.gz glibc-2.9/elf/ldconfig.c
关于PHP的memcache模块的get、delete方法的patch
patch原因:
解决get、delete方法无法区分连接失败和not found的问题
patch内容
本次修改是在memcache-2.2.6 的基础上修改的,我把她修改版本号为 2.2.6.1来使用了,
patch 文件:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
diff -uN memcache-2.2.6/memcache.c memcache-2.2.6.1/memcache.c --- memcache-2.2.6/memcache.c 2010-10-04 04:57:47.000000000 +0800 +++ memcache-2.2.6.1/memcache.c 2011-08-02 23:44:48.000000000 +0800 @@ -56,6 +56,16 @@ ZEND_DECLARE_MODULE_GLOBALS(memcache) +ZEND_BEGIN_ARG_INFO_EX(arginfo_memcache_get, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(1, flags) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_memcache_delete, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(1, error_flag) +ZEND_END_ARG_INFO() + /* {{{ memcache_functions[] */ zend_function_entry memcache_functions[] = { @@ -68,8 +78,8 @@ PHP_FE(memcache_add, NULL) PHP_FE(memcache_set, NULL) PHP_FE(memcache_replace, NULL) - PHP_FE(memcache_get, NULL) - PHP_FE(memcache_delete, NULL) + PHP_FE(memcache_get, arginfo_memcache_get) + PHP_FE(memcache_delete, arginfo_memcache_delete) PHP_FE(memcache_debug, NULL) PHP_FE(memcache_get_stats, NULL) PHP_FE(memcache_get_extended_stats, NULL) @@ -92,8 +102,8 @@ PHP_FALIAS(add, memcache_add, NULL) PHP_FALIAS(set, memcache_set, NULL) PHP_FALIAS(replace, memcache_replace, NULL) - PHP_FALIAS(get, memcache_get, NULL) - PHP_FALIAS(delete, memcache_delete, NULL) + PHP_FALIAS(get, memcache_get, arginfo_memcache_get) + PHP_FALIAS(delete, memcache_delete, arginfo_memcache_delete) PHP_FALIAS(getstats, memcache_get_stats, NULL) PHP_FALIAS(getextendedstats, memcache_get_extended_stats, NULL) PHP_FALIAS(setcompressthreshold, memcache_set_compress_threshold, NULL) @@ -1290,6 +1300,7 @@ /* not found */ if (result == 0) { + flags |= 1 << 29; // flag for not found ZVAL_FALSE(*return_value); } /* read "END" */ @@ -2382,23 +2393,32 @@ long time = 0; char key_tmp[MMC_KEY_MAX_SIZE]; unsigned int key_tmp_len; + zval *error_flag = NULL; if (mmc_object == NULL) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &mmc_object, memcache_class_entry_ptr, &key, &key_len, &time) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|lz", &mmc_object, memcache_class_entry_ptr, &key, &key_len, &time, &error_flag) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &key, &key_len, &time) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &key, &key_len, &time, &error_flag) == FAILURE) { return; } } + if (error_flag == NULL) { + ALLOC_INIT_ZVAL(error_flag); // init zval + } else { + zval_dtor(error_flag); // if other type then destruct + } + ZVAL_LONG(error_flag, 0); //init to 0 if (!mmc_get_pool(mmc_object, &pool TSRMLS_CC) || !pool->num_servers) { + ZVAL_LONG(error_flag, 1 << 30); //set flag as 1 << 30 for network error RETURN_FALSE; } if (mmc_prepare_key_ex(key, key_len, key_tmp, &key_tmp_len TSRMLS_CC) != MMC_OK) { + ZVAL_LONG(error_flag, 1 << 28); //set flag as 1 << 28 for key prepare fail RETURN_FALSE; } @@ -2410,7 +2430,11 @@ if (result > 0) { RETURN_TRUE; + } else if(result == 0) { // not found + ZVAL_LONG(error_flag, 1 << 29); //set flag as 1 << 29 for not found + RETURN_FALSE; } + ZVAL_LONG(error_flag, 1 << 30); //set flag as 1 << 30 for net work error RETURN_FALSE; } /* }}} */ diff -uN memcache-2.2.6/php_memcache.h memcache-2.2.6.1/php_memcache.h --- memcache-2.2.6/php_memcache.h 2010-10-04 04:57:47.000000000 +0800 +++ memcache-2.2.6.1/php_memcache.h 2011-07-30 21:50:34.000000000 +0800 @@ -63,7 +63,7 @@ PHP_FUNCTION(memcache_flush); PHP_FUNCTION(memcache_setoptimeout); -#define PHP_MEMCACHE_VERSION "2.2.6" +#define PHP_MEMCACHE_VERSION "2.2.6.1" #define MMC_BUF_SIZE 4096 #define MMC_SERIALIZED 1 |
patch说明
修改的地方如下:
1. 添加参数检查(memcache.c), 在 ZEND_DECLARE_MODULE_GLOBALS(memcache) 下面添加:
2. 修改memcache_get、memcache_delete函数的定义:
3. 修改memcache_get 函数的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/ /这里只添加了一行,其它都不变 int mmc_exec_retrieval_cmd(mmc_pool_t *pool, const char *key, int key_len, zval **return_value, zval *return_flags TSRMLS_DC) /* {{{ */ { //... /* send command and read value */ if ((result = mmc_sendcmd(mmc, command, command_len TSRMLS_CC)) > 0 && (result = mmc_read_value(mmc, NULL, NULL, &value, &value_len, &flags TSRMLS_CC)) >= 0) { /* not found */ if (result == 0) { flags |= 1 << 29; // flag for not found, 此处添加该行 ZVAL_FALSE(*return_value); } //... |
4. 修改delete函数的实现:
这里的error_flag 是新添加的可选参数,与改变量相关的地方都是新添加的
测试脚本:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?php define("E_MC_KEY_PREPARE_ERROR", 1<<28); define("E_MC_NO_FOUND", 1<<29); define("E_MC_CONNECT_ERROR", 1<<30); test_delete(); exit; function test_delete() { $m = new Memcache(); $m->addServer("127.0.0.1", 11211); // this is available $result = $m->delete("noexists", 0, $flag); check_error("should no found", $flag); $m->set("exists","I am here",0,600); $result = $m->delete("exists", 0, $flag); check_error("should ok", $flag); $m = new Memcache(); $m->addServer("127.0.0.1", 11219); // this is unavailable $result = $m->delete("noexists", 0, $flag); check_error("should connect error", $flag); $result = @$m->delete("", 0, $flag); // test no flag check_error("should key error", $flag); $result = $m->delete("m", 0); // test no flag echo "it can work without flag argument, that's ok\n"; } function check_error($lable, $flag) { echo $lable .":\t"; if ($flag & E_MC_CONNECT_ERROR) { echo "connect error\n"; } if ($flag & E_MC_NO_FOUND) { echo "no found\n"; } if ($flag & E_MC_KEY_PREPARE_ERROR) { echo "Key is unvalidate\n"; } if ($flag == 0) { echo "OK\n"; } } |
遗留问题
===========================
如果没有第一部分的修改,貌似也是可以的,但是下面三段脚本是值得思考的:
关于PHP的memcache模块的delete方法的修改(2)
前面有篇文章(http://phpor.net/blog/post/883/)提到了PHP 的memcache模块的delete方法的问题,并且做了一些修改,但是,那篇文章也提到,那种修改办法也有很大的缺点,这里给出一种比较好一些的方式。
修改memcache_delete函数如下:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
PHP_FUNCTION(memcache_delete) { mmc_t *mmc; mmc_pool_t *pool; int result = -1, key_len; zval *mmc_object = getThis(); char *key; long time = 0; char key_tmp[MMC_KEY_MAX_SIZE]; unsigned int key_tmp_len; zval *error_flag = NULL; if (mmc_object == NULL) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|lz", &mmc_object, memcache_class_entry_ptr, &key, &ke y_len, &time, &error_flag) == FAILURE) { return; } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &key, &key_len, &time, &error_flag) == FAILURE) { return; } } if (error_flag != NULL) { // 如果提供了默认参数,先析构一下,避免所传参数不是整型; // 即使提供的是一个未初始化的参数,error_flag不是NULL,但是,如果提供的是一个未初始化的参数, // 则该函数里面对值的修改是不能回传过去的 zval_dtor(error_flag); } else { // 如果没有提供默认参数,则初始化之,方便下面的行文 ALLOC_INIT_ZVAL(error_flag); } ZVAL_LONG(error_flag, 0); // 初始化为0 if (!mmc_get_pool(mmc_object, &pool TSRMLS_CC) || !pool->num_servers) { ZVAL_LONG(error_flag, 1 << 30); // 如果网络错误,设置为 1<<30 RETURN_FALSE; } if (mmc_prepare_key_ex(key, key_len, key_tmp, &key_tmp_len TSRMLS_CC) != MMC_OK) { ZVAL_LONG(error_flag, 1 << 28); // 如果key错误,设置为 1<<28 RETURN_FALSE; } while (result < 0 && (mmc = mmc_pool_find(pool, key_tmp, key_tmp_len TSRMLS_CC)) != NULL) { if ((result = mmc_delete(mmc, key_tmp, key_tmp_len, time TSRMLS_CC)) < 0) { mmc_server_failure(mmc TSRMLS_CC); } } if (result > 0) { RETURN_TRUE; } elseif(result == 0) { // not found ZVAL_LONG(error_flag, 1 << 29); // 如果没有找到,设置为 1 << 29 RETURN_FALSE; } ZVAL_LONG(error_flag, 1 << 30); // 如果网络错误,设置为 1<<30 RETURN_FALSE; } |
测试:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?php define("E_MC_KEY_PREPARE_ERROR", 1<<28); define("E_MC_NO_FOUND", 1<<29); define("E_MC_CONNECT_ERROR", 1<<30); test_delete(); exit; function test_delete() { $m = new Memcache(); $m->addServer("127.0.0.1", 11211); // this is available $flag = 0; $result = $m->delete("noexists", 0, $flag); check_error("should no found", $flag); $flag = 0; $m->set("exists","I am here",0,600); $result = $m->delete("exists", 0, $flag); check_error("should ok", $flag); $flag = 0; $m = new Memcache(); $m->addServer("127.0.0.1", 11219); // this is unavailable $result = $m->delete("noexists", 0, $flag); check_error("should connect error", $flag); $flag = 0; $result = @$m->delete("", 0, $flag); // test no flag check_error("should key error", $flag); $result = $m->delete("m", 0); // test no flag echo "it can work without flag argument, that's ok\n"; } function check_error($lable, $flag) { echo $lable .":\t"; if ($flag & E_MC_CONNECT_ERROR) { echo "connect error\n"; } if ($flag & E_MC_NO_FOUND) { echo "no found\n"; } if ($flag & E_MC_KEY_PREPARE_ERROR) { echo "Key in unvalidate\n"; } if ($flag == 0) { echo "OK\n"; } } |
输出结果:
should no found: no found
should ok: OK
should connect error: connect error
should key error: Key in unvalidate
it can work without flag argument, that’s ok
====================================================
本次所学:
1. 关于参数的传递,可以直接解析成内部类型,也可以直接使用zval类型
2. 关于引用传参这里做的不太对,且看后面的文章
VIM NERD_tree 的小小hack
如果你在看这篇文章,大概你也在使用VIM写代码了。如果你使用了NERD_tree这个插件,可能你会用到BookMark的功能,如果还不知道,可以先看一下NERD_tree的文档。
如果你为自己的项目的根目录建立了一个BookMark,则下次进入项目的时候就不需要先打开项目目录,然后再一点一点地找到自己想看到的文件,例如,我建立了一个叫Test的项目,首先启动vim,然后执行命令 :BookMarkToRoot Test ; 这样就直接到了我的项目目录了;
但是有一点很不痛快的是,现在使用:pwd 来查看当前目录的话,并不是项目的目录,于是查看了一下NERD_tree.vim,做了如下修改:
添加了红方框标出的一行,就可以了;
这样的话,在项目所在的目录执行一些命令也比较方便,例如一些svn的命令。
另外,当你打开树目录时,在目录树窗口中使用 "B" 命令可以打开可关闭你设置过的标签,很方便哦~
php vld模块
Provides functionality to dump the internal representation of PHP scripts
http://pecl.php.net/package/vld