Welcome to PHPor's Blog.

[置顶] 时间

[不指定 2009/08/16 17:03 | by phpor ]
因为时间在流逝,所以一切都在变。
server-id做什么用的,你知道吗?

1、 mysql的同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,所以server-id一定要有的

2、 每一个同步中的slave在master上都对应一个master线程,该线程就是通过slave的server-id来标识的;每个slave在master端最多有一个master线程,如果两个slave的server-id 相同,则后一个连接成功时,前一个将被踢掉。 这里至少有这么一种考虑:
   slave主动连接master之后,如果slave上面执行了slave stop;则连接断开,但是master上对应的线程并没有退出;当slave start之后,master不能再创建一个线程而保留原来的线程,那样同步就可能有问题;

3、 在mysql做主主同步时,多个主需要构成一个环状,但是同步的时候有要保证一条数据不会陷入死循环,这里就是靠server-id来实现的

PHP源码阅读点滴

[不指定 2010/09/05 23:51 | by phpor ]
下面讨论的PHP都是5.1.5版本的。

1. PHP源码文件 Zend/zend_globals.h 中的_zend_executor_globals定义了执行时全局的hash表:
    /* symbol table cache */
    HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
    HashTable **symtable_cache_limit;
    HashTable **symtable_cache_ptr;

    HashTable *active_symbol_table;
    HashTable symbol_table;     /* main symbol table */

    HashTable included_files;   /* files already included */
    HashTable *function_table;  /* function symbol table */
    HashTable *class_table;     /* class table */                    
    HashTable *zend_constants;  /* constants table */
    HashTable *in_autoload;

    HashTable regular_list;
    HashTable persistent_list;

    HashTable *ini_directives;

这里面只列了hash表类型的字段,从中可以看出: 函数、类、常量、头文件等都是存储为hash表的。


2.
PHP源码文件 Zend/zend_globals.h 中的下列结构应该说明declare 关键字可以声明的内容都有哪些,似乎目前只有ticks

typedef struct _zend_declarables {
    zval ticks;
} zend_declarables;

3. hash表数据结构,Zend/zend_hash.h 文件中:

typedef struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;   /* Used for element traversal */
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    dtor_func_t pDestructor;
    zend_bool persistent;
    unsigned char nApplyCount;
    zend_bool bApplyProtection;
#if ZEND_DEBUG
    int inconsistent;
#endif
} HashTable;

4. PHP内部的Hash函数, Zend/zend_hash.h中:
static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength)
{
    register ulong hash = 5381;

    /* variant with the hash unrolled eight times */
    for (; nKeyLength >= 8; nKeyLength -= 8) {
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
    }
    switch (nKeyLength) {
        case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 1: hash = ((hash << 5) + hash) + *arKey++; break;
        case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
    }
    return hash;
}

5. hash表查找函数:

/* Returns SUCCESS if found and FAILURE if not. The pointer to the
 * data is returned in pData. The reason is that there's no reason
 * someone using the hash table might not want to have NULL data
 */
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData)
{
    ulong h;
    uint nIndex;
    Bucket *p;
       
    IS_CONSISTENT(ht);

    h = zend_inline_hash_func(arKey, nKeyLength);  
    nIndex = h & ht->nTableMask;
    p = ht->arBuckets[nIndex];
    while (p != NULL) { 
        if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
            if (!memcmp(p->arKey, arKey, nKeyLength)) {
                *pData = p->pData;
                return SUCCESS;
            }
        }
        p = p->pNext; 
    }        
    return FAILURE;
}    

这里面:
   
    h = zend_inline_hash_func(arKey, nKeyLength);  
    nIndex = h & ht->nTableMask;
就可以定位到具体的
Bucket了,特别是这个按位与的操作,就可以知道Bucket的数量了,怎么算呢?

6. 文件Zend/zend_globals_macros.h中定义了EG:
# define EG(v) (executor_globals.v)

EG 就是
executor_globals的意思,比如EG(ini_directives) 就是:
executor_globals.ini_directives

从上面的
结构体executor_globals就可以知道这是在做什么了

7. Zend/zend_ini.h 中定义了ini变量的结构体:

struct _zend_ini_entry {
    int module_number;
    int modifiable;
    char *name;
    uint name_length;
    ZEND_INI_MH((*on_modify));
    void *mh_arg1;
    void *mh_arg2;
    void *mh_arg3;

    char *value;
    uint value_length;

    char *orig_value;
    uint orig_value_length;
    int modified;

    void (*displayer)(zend_ini_entry *ini_entry, int type);
};

8. ini_set 函数是在源码中是通过函数zend_alter_ini_entry来实现的,其中的modifytype参数值为:PHP_INI_USER

 

PHP 的strlen函数

[不指定 2010/09/04 19:55 | by phpor ]
1. PHP中不是所有函数都通过PHP_FE来定义的,也或者PHP的strlen根本就不是一个函数,使用gdb都没有找到strlen对应了哪段c代码。 晕死

关于Linux的crontab 与 sar

[不指定 2010/09/03 14:34 | by phpor ]
我们一般用root使用crontab -e写crontab的时候,是写在 /var/spool/cron/root  文件中的,通过strace crontab -l 可以看到, 对于每个用户来讲,都可以有自己的crontab,对应文件为:
/var/spool/cron/{username}

如果目录 /var/spool/cron 的权限为700, 则非root用户将不被允许使用cron了

另外, cron在执行的时候,不仅扫描 /var/spool/cron 目录,还会扫描 /etc/crontab 文件和 /etc/cron* 的相关目录和文件。

如: /etc/cron.daily/logrotate 是配置系统日志的滚动的,每天一次

对于sar命令,是属于sysstat包中的,通过配置文件: /etc/cron.d/sysstat

---------------------------------------------------------
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib/sa/sa1 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib/sa/sa2 -A
---------------------------------------------------------

使得10分钟获取一次系统信息

通过配置文件: /etc/sysconfig/sysstat

---------------------------------------------------
# How long to keep log files (days), maximum is a month
HISTORY=7
----------------------------------------------------

来配置保存数据多长时间,最长1个月,因为历史数据默认保存在目录: /var/log/sa/ 中,每天一个文件,文件名的格式为 sa + day-of-month , 如:
-rw-r--r-- 1 root root 382704 Sep  1 23:50 sa01
-rw-r--r-- 1 root root 382704 Sep  2 23:50 sa02
-rw-r--r-- 1 root root 236624 Sep  3 14:20 sa03
-rw-r--r-- 1 root root 382704 Aug 26 23:50 sa26

另外,这些文件不是以文本格式存放的,不能直接查看,可以通过命令:

sar -f /var/log/sa/sa02 200

-f 选项默认是当天的文件
200 是查看多少条,默认(还没看)

======================================================

主要是这个工具可以查看历史负载,所以才看了一下。

sar 10分钟一次,每天产生370K的文件,如果改为1分钟1次,则每天也才3.7M的文件,对于查看服务器的状态已经查不多了



无言的感怀

[不指定 2010/09/01 13:00 | by phpor ]
无言的感怀

作者 花未眠


人生有多少故事

真实的令人心碎

人生有多少记忆

总是置于心的高地

有多少梦可以重来

有多少人值得等待

又有多少感慨可以

化成许多无言的感怀


评论:
何处找回青春年少,何日登临儿时楼台,寄言风清月白,谁堪白露秋凉?一曲古琴流水融入沉箫,一杯浊酒相伴病魂悠悠……

命运的安排总是那样的无奈,很难把荣辱沉浮面对,叹往昔不可再来,喜风雨之后,依然有别样的精彩!

有多少是非能说明白,有多少收获值得欣慰,有多少失误可以修改,有多少情结谁来解开?有多少爱,痴心为谁,有多少怨,怎生掩埋?人间是舞台,人生多无奈,偏爱上层楼,叹风清月白?
 

磁盘相关

[不指定 2010/08/30 21:26 | by phpor ]

Linux上磁盘的名字有/dev/hdx  和 /dev/sdx 的,其中:
/dev/hd[a-t] : 表示 IDE/ATA 设备
/dev/sd[a-t] :  表示 SCSI 或 SATA 设备

关于磁盘的一些指标和报价可以参考一些设备官方网站:

网上折扣店:http://discountechnology.com/
简介: 主要销售企业级硬件,包括存储设备、网络设备、显示器等, 你可以到这里看一下各种新型磁盘的报价,路由器的报价等等。当然你也可以查看一些设备的详细参数。


希捷官方: http://www.seagate.com/
(如果遇到死循环,你可以修改一下你的浏览器的accept-language 为english)


关于smartctl 的使用参考:
http://smartmontools.sourceforge.net/


硬盘的种类:

IDE
SCSI
SATA
SSD

它们的区别还需要花时间去学习

给我的blog添加了订阅功能

[不指定 2010/08/30 09:57 | by phpor ]
        
  1. 去http://www.feedsky.com/ 注册一个账户
  2.     
  3. 在http://www.feedsky.com/add_feed.html 添加feed订阅
  4.     
  5. feedsky可以生成“订阅到xx”的html代码,将这些代码写到自己的blog里就行了
        

索引知识

[不指定 2010/08/19 18:03 | by phpor ]

select * from tb1 where `field1` like  'mmmm' and `field2`='nnnnn' ;

如果field1和field2都做了索引,则这里使用field2的索引,因为“等号”操作比“like”操作效率更高

一种js的回调的写法

[不指定 2010/08/08 18:20 | by phpor ]
url:  http://phpor.net/render_js.php?callback=cb
返回:
(function(){ if('cb' && cb) { var call = cb; var json ={...}; call(json); } })();

一般来讲,写为:
cb({...});
就够了,这样的话,cb为空或者该函数不存在就会出现js错误

或者,写成如下:
if('cb' && cb) { var call = cb; var json ={...}; call(json); }

不觉得这种方式和第一种有什么区别。
分页: 1/69 第一页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]