»
S
I
D
E
B
A
R
«
XHProf中文文档
Aug 12th, 2009 by 一米六二

XHProf是facebook在用的php性能分析工具,跟Xdebug相比,性能开销更低,可以用在生产环境。
原文地址在:
http://mirror.facebook.net/facebook/xhprof/doc.html
半成品:XHProf中文文档
约在本周内完成。
[addons at 2009-08-14:目前已经推进到了75%。欢迎斧正。]

测试FusionIO:strict_sync太秀逗了…
Jun 23rd, 2009 by 一米六二

这是一篇译文,原文地址是:   http://www.mysqlperformanceblog.com/2009/06/15/testing-fusionio-strict_sync-is-too-strict/

随着新的更新FusionIO驱动的更新,我能够在我的戴尔R900与Ubuntu 8.10上进行尝鲜,而不再需要痛苦地编译驱动或是降级kernel.现在我决定测试一下strict_sync模式。

据我所知FusionIO默认情况下,比如英特尔的SSD ,是对应用程序“撒谎”了,fsync()并不是真正的发生了,它仍然只是提交到了内存而不是最终的磁盘。FusionIO还有一个“ strict_sync ”模式,可以保证fsync函数可靠地操作。

好啊兄弟,让我们来压一下性能—通常我在100w数据(约9GB数据),O_DIRECT模式下开着3GB的buffer_pool来搞这个测试。
原始测试数量参见这里
pub
结果用TPM (每分钟的事务数)表示 ,这样更清楚一些。图形显示,结果是是随着时间[X轴]不断变化 。
这个图形已经很明显,我都不需要再用文字来说明了。。。

但是我没有测试,在断电的情况下,在默认模式下处理、结束事务的情况。这个需要读者您检查一下。

缓慢的drop table 操作
Jun 22nd, 2009 by 一米六二

原文地址:http://www.mysqlperformanceblog.com/2009/06/16/slow-drop-table/

大家都知道,Ext3并不是最有效的文件系统,例如,删除文件会非常缓慢(那真是一个痛苦的过程,不是吗老兄?),造成大量的随机I / O。然而事实上,有时候它比你想象的更能影响MySQL的性能。那么,什么时候会发生,又为什么会发生呢?

当您运行DROP TABLE时,会有好几件事情需要去做:对表进行write lock,这样它不会被其他线程使用;存储引擎删除数据文件;当然,最后MySQL会删除表定义文件(.frm文件)。这还不是所有的事,还有另外一件事需要去做:

  1. VOID(pthread_mutex_lock(&LOCK_open));
  2. error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
  3. pthread_mutex_unlock(&LOCK_open);

这整段删除表操作的代码都被LOCK_open互斥信号量所包围。这个互斥信号量在MySQL中不少地方都用到过,但主要是表在开启或关闭的时候。这意味着,当LOCK_open锁定时,没有查询语句可以执行,因为他们阻止任何访问。

这就解释了在ext3文件系统上删除10GB的文件何时成为了痛苦的等待的开始。删除10GB的文件将持续一段时间,如果这是一个MySQL表,这段时间mutex里将会一直存在,而这个互斥会拖延所有查询。

代码:

  1. +—–+——+———–+——+———+——+ —————-+——————————— —————+
  2. | Id | User | Host | db | Command | Time | State | Info |
  3. +—–+——+———–+——+———+——+ —————-+——————————— —————+
  4. | 1 | root | localhost | test | Query | 7 | NULL | drop table large_table |
  5. | 329 | root | localhost | test | Query | 7 | Opening tables | select sql_no_cache * from other_table limit 1 |
  6. +—–+——+———–+——+———+——+ —————-+——————————— —————+

我尝试了一些替代的办法,让MySQL来在DROP TABLE时删除小文件,以尽量减少影响,如:

  • TRUNCATE TABLE large_table; ALTER TABLE large_table ENGINE=…; DROP TABLE large_table;
  • TRUNCATE TABLE large_table; OPTIMIZE TABLE large_table; DROP TABLE large_table;

不幸的是,原来所有管理指令:ALTER TABLE <ALTER ALTER TABLEOPTIMIZE TABLE实际都一样,或是在旧的表文件删除时使用了其他的LOCK_open互斥信号锁。

代码:

  1. | 3 | root | localhost | test | Query | 7 | rename result table | ALTER TABLE large_table ENGINE=MyISAM |
  2. | 679 | root | localhost | test | Query | 6 | Opening tables | select * from other_table limit 1 |

唯一的选择似乎就只能是改变文件系统了。例如,换成处理文件删除更有效的XFS文件系统。

EXT3

代码:

  1. mysql> drop table large_table;
  2. Query OK, 0 rows affected (7.44 sec)

的xfs

代码:

  1. mysql> drop table large_table;
  2. Query OK, 0 rows affected (0.29 sec)

一个MySQL的内部操作可能更好一点:可以通过先重命名对应的数据文件,再在没有互斥信号锁的情况下删除物理文件。但是事实上可能没有那么简单,因为实际的删除操作是由存储引擎来完成的,因此不是MySQL的代码能控制的。

这肯定不是一个共同的情况,但是有时候(虽然我们极其不愿)确实可能会让任何人头痛(例如,删除一个老的不再使用的表) 。

这里绍明同学说应该翻译成:这不是一个常见的情况,但是它可能会在最不期望出现的时候成为一个问题(例如 删除没有使用的旧表).


后附:

一个评论回复说:

从一个完全不同的领域的解决办法。

mythtv (电视记录系统)开发者们在ext3系统上删除大型文件时,通过“缓慢删除”功能取得更好的效果。一般来说,电视录音大概1 – 12GB每小时,所以一部电影可以20 + GB大小的文件。如果没有该功能,删除文件操作将锁定ext3整个系统约20-30秒。

“慢删除”只是在后台执行将文件中的块清空的操作。

另一个评论说:

我应该指出,这并不只适用于MyISAM表,对于InnoDB表,在innodb_file_per_table模式下也一样。
我最近刚跟客户做了个spoke,他们几乎无法删掉一个400G的表,因为这个操作阻塞了很长时间。。

更改字符集设置[译文]
Mar 24th, 2009 by 一米六二

更改字符集设置
原文设置:http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/

Web世界已经走向UTF8;Drizzle选中它作为默认的字符集。大多网站后端用utf-8来存储文本数据,另外那些用latin1字符集的网也开始将他们的数据库迁移到utf8;google一下”mysql convert charset to utf8″,可以找到大量的网站,每个途径都有些微的不同,又在某些方面都有些不对。我会总结一下这些方法,说明他们为什么不奏效,然后给出一段脚本,大致上可以用来转换一个数据库或是一系列表到目标字标集。

方法一:

ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

拿这个数据表作例子,我们可以看到这种方法为啥子行不通呢。

SQL:

1.
mysql> CREATE TABLE `t1` (
2.
-> `c1` text NOT NULL
3.
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
4.
Query OK, 0 rows affected (0.02 sec)
5.

6.
mysql> ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
7.
Query OK, 0 rows affected (0.02 sec)
8.
Records: 0 Duplicates: 0 Warnings: 0
9.

10.
mysql> SHOW CREATE TABLE `t1`\G
11.
*************************** 1. row ***************************
12.
TABLE: t1
13.
CREATE TABLE: CREATE TABLE `t1` (
14.
`c1` mediumtext NOT NULL
15.
) ENGINE=MyISAM DEFAULT CHARSET=utf8
16.
1 row IN SET (0.01 sec)


注意这里的c1隐含的从text到mediumtext的转换。这种方法能引起改变的数据类型和没有提示的截断,这从我们的目的上说是不能接受的。

方法二[在这里记录着]:

这种方法在转换之前,把所有的数据都转成了他二进制相似的数据类类型,避免了隐含的类型转换。由于实现方式的限制,他把原来以二进制形式存储的数据列也转成了文本的近似列。另外,这种方式有可能因为二进制数据不能进行全文检索而失败。即使这些解决了,这个过程也因为它过多的在每个表上执行alter语句而不能用在大数据量的数据库上。这些语句包括:
1) Drop FULLTEXT indexes
2) Convert target columns to their binary counterparts
3) Convert the table to the target character set
4) Convert target columns to their original data types
5) Add FULLTEXT indexes back
由于这些语句有时执行一句我们都需要花上n个钟头(我们是不是该庆幸是用小时来计数而不是用天来计数?),这也是不可接受的。

方法三:
导出整个数据库,再导入进去。当然,导入导出时选用正确的server端和client端字符集。
这是一个有三个步骤的过程。我们先导出数据库结构,然后手工编辑把数据字符集修改正确,接出单独导出数据。接下来,创建数据表结构,导入数据。如果你在使用复制(replication),这通常不太可取,因为这样导致可笑的一大堆日志,并引起复制链上所有服务器重新载入数据。
除开方法一之外,这些方法都不必要地麻烦。针对方法一,考虑一下下面这个alter语句:

1.
ALTER TABLE `t1`
2.
DEFAULT CHARSET=utf8,
3.
MODIFY COLUMN `c1` text CHARACTER SET utf8;

这个语句能转换整个表的默认字符集和目标数据表列的字符集,并且保持全文索引不变。对于一个指定的数据表,只需要一句sql语句。一个perl脚本已经写好了,它可以将这个alter table 的操作原子化,您可以从这里下载:

$ wget http://www.pablowe.net/convert_charset

当这个脚本完成后,它会加到launchpad的Percona Tools 中去(也许是maatkit,如果证明是足够有用的话).它的一些不错的特性包括:
1.对字符型外键的恰当处理。(当下还没搞定,不过你可能最好不要使用字符型外键)
2.可以调节这个脚本创建的线程数目。(目前是每个表一个线程).
用法:

Usage:
convert_charset –database=database [options]
Options:
–askpass Prompt for a MySQL password
–charset The target character set to convert to
–collate The target collation to convert to
–database|d The target database
–help|? Display this help and exit
–host|h The target host
–ignore-columns Columns to ignore, useful if you want to
keep the existing charset for a target column
Comma-separated. NO SPACES.
table.column
–ignore-tables A comma-separated list of tables to ignore
–password|p The MySQL password to use
–port The target port
–tables A comma-separated list of tables to convert.
All non-named tables will be ignored
–test Print the ALTER statements that would be executed
without executing them.
–user|u The MySQL user
–version|V Display version information and exit
defaults are:
ATTRIBUTE VALUE
————————– ——————
askpass FALSE
charset utf8
collate No Default Value
database No Default Value
help FALSE
host localhost
ignore-columns No Default Value
ignore-tables No Default Value
password No Default Value
port 3306
tables No Default Value
test FALSE
user Current User
version FALSE

Spread学习系列[1]-SP_receive函数说明
Jul 5th, 2008 by 一米六二

接在Spread 简介(试译)之后,我跟啃骨头一样一点点儿地把SP_receive的man文档看完了。
这是我做的笔记,基本就是原文翻译,但是我英文太差,翻得太烂了点:(
SP_receive
NAME
SP_receive, SP_scat_receive – Receive message from Spread

SYNOPSIS
#include

int SP_receive( mailbox mbox, service *service_type, char sender[MAX_GROUP_NAME], int max_groups, int *num_groups, char groups[][MAX_GROUP_NAME], int16 *mess_type, int *endian_mismatch, int max_mess_len, char *mess);

int SP_scat_receive( mailbox mbox, service *service_type, char sender[MAX_GROUP_NAME], int max_groups, int *num_groups, char groups[][MAX_GROUP_NAME], int16 *mess_type, int *endian_mismatch, scatter *scat_mess);

DESCRIPTION
SP_receive 函数主要实现接收消息的功能。这个函数不仅接收数据消息,也接收成员关系数据。当前连接所在的所有组的消息都会到达同一个
“收件箱”,因此SP_receive函数一次会从任意一个组中间取回一条消息。当接收完成后,一些成员变量会被设置值,以标记这条消息的各种属性。
因为这个函数是程序从spread 系统中取回消息的唯一渠道,因此在Spread中的应用也是最复杂的。基于这条消息是数据消息,还是成员关系消息,许多
参数的含义都会改变。
没有消息到达的时候,SP_receive函数会阻塞。
mbox参数指定了要在哪个(spread)连接上获取消息。Service_type是指向一个变量的指针,这个变量会
指出当前接收到的消息是”数据消息“,还是成员关系消息。这个变量要么是REG_MESSAGE,要么是
MEMBER_SHIP_MESS,当然会是特定的类型.这个变量也是一个输入参数,在一般的情况下应该被置为0。如果您置为”DROP_RECV”,则表示您愿意接收“不可信消息”,这可能导般如果为消息或组列表分配的缓冲不够的话,消息会被清空。更多关于DROP_RECV的介绍会在后面提到。
后面的参数的含义是依赖于service_type这个变量的取值的.如果service_type的取值是REG_MESSAGE(比如数据消息),那么:
sender参数是一个指向字符的指针,至少需要能容纳MAX_GROUP_NAME个字符。(很拗口吧?其实就是一个长度至为MAX_GROUP_NAME的字符串…)
这个参数将会被设置成为消息发送方的名称(它的组内名称)
max_groups参数是你为groups参数分配的地址所能容纳的最大的组的个数。
Num_groups是一个整型指针,指向在groups参数中返回的组的个数。
groups 参数可以容纳max_groups个组名,每个组名是一个最多有MAX_GROUP_NAME个字符的字符串。所有接收这个消息的组都会被更在这儿,除非数组太小(此时groups尽可能多地接纳至到它满了为止,并且
num_groups会设为负的值).比如,如果你的groups数组能接收5个数组名,而这个消息被7个组接收,前5个组的名字会存在groups这个数组中,num_groups会被设为-7.

真正的消息内容存在命名为mess的缓冲区中,这个缓冲区最少要有max_mess个字节。如果接收的消息的长度要比这个缓冲区大,默认将会返回BUFFER_TOO_SHOFT错误,并在endian_mismatch字域中提供需要的长度。如果DROP_RECV标记被在service_type中传进来,那么mess会尽量多地存储消息内容,多余的内容会被丢弃掉,同时,SP_receive的返回值会指示一个错误。如果使用SP_scat_receive,那么mess和length参数会被一个scat_mess scatter结构体所取代,这个结构会存储它收到的消息和消息的长度。它们会被以接收的次序存储。
如果是MEMB_MESSAGE(比如,成员关系消息),并且特别指出是TRANS_MESS,那么:
sender这个字符数据(字符串)就会设置为成员关系发生变化的组的名字。
max_groups和max_mess_len参数没有用,num_groups会是0,而groups参数因为当前正处于变动之中,暂时没有
了正常的组,由sender参数取代。mess_type参数设为-1,endian_mismatch参数为0(也因为组关系处于变动之中).mess参数只包含
关系变化作用的group的group_id。因此消息体就是:
group_id;

因此本质上你所得到的信息就是通过sender参数和group_id值反映的哪个组产生了变动。

TRANS_MEMB_MESS 的重要性在于,它告诉应用程序,在它之后,在来自同一组的REG_MEMB_MESS之前,接收到的消息都是’clean up’消息,这些消息在真正改变成员关系之前需要保持常态。请阅读其他文档或研究文献以得到更多相关资料。

如果这是一条MEMB_MESSAGE(比如成员关系消息)并且指定了是REG_MEMB_MESS,那么:
sender 字符数组指定了成员关系发生改变的组的名称。
max_groups和max_mess_len参数的含义跟前面一样,mess_type参数设定为当前进程在组成员数组中的索引。endian_mismatch会再次设为0.
groups参数和mess内容用来提供当前组内发生的变化的两种信息。num_groups参数设置为新成员关系中的当前组的成员数(指变动发生后)。相对地,groups 这个数组会被设置为新成员关系中当前组的所有成员的组内名称。这个名称的顺序常常是按接收方的顺序排序的,这样当程序需要一个做代表时就能取一个出来。不同的Spread版本的顺序不同,当前版本的首先按连接到守护进程的顺序,其次是它的私有名称。守护进程的顺序是按照它们在spread.conf文件中列出来的顺序排列的。
第二类信息存储在消息体中,提供了当前进程中所有私有组名称,这些名称从原来的成员关系迁到了新的成员关系中。
所有的内容都一个挨一个地放在message缓冲中。因为这个结构在各个版本中经常变,最好的处理办法就是使用
我们提供的解析函数来将消息体翻译成定义好的描述成员关系的结构体。解析函数有两个变量,一个用来处理字
节流,一个用来处理scatters格式的消息体。
SP_get_memb_info
SP_get_vs_sets_info
SP_get_vs_set_members
SP_scat_get_memb_info
这四个函数填入标准的应用程序用来设置以成员关系的gid和vs信息的结构体。
SP_scat_get_vs_sets_info
SP_scat_get_vs_set_members

这样,如果一个程序需要得到它自己的vs_set(Spread版本4之前提供的信息),他们可以被两个函数调用来文档化。先用SP_get_memb_info然后用SP_get_vs_set_members;

每个vs_set定义成若干成员和一个成员关系字符数组(字符串)。这个数组的类型是char members[][MAX_GROUP_NAME];
每个成员关系型的消息都可能含有一系列的vs_sets,当一个网络合并动作发生时,几个不同的部分可能同时发生合并,每个区块都有它自己的成员集合,这些既有旧成员关系的又有新成员关系的。
如果你想自行解析这个成员关系消息内容,下面的段落指出了当前的数据格式。这个格式肯定会改变(过去已经改变过好几次了),我们不对未来的改变做保证。如果您想自行解析数据,在更新Spread的版本时您需要更新您的代码。
成员关系消息体包含以下几段(它们是有顺序的)。每一段数据都是一个结构体,或者是一个整数(是整数时,一定是一个32位无符号的整数)。vs sets是这样定义的:
group_id gid;
unsigned int num_vs_sets;
unsigned int local_vs_set_offset;
以及一系列vs_sets;
所有的vs_sets都序列地存在成员关系消息体中,读完了一个vs_set,另一个vs_set就在下一个字节开始了。
每一个vs_set都以一下整数num_vs_members开始,因而程序能够得到members数组的长度来进行读取。
unsigned int num_vs_members;
char members[][MAX_GROUP_NAME]

vs_set members数组有num_vs_members个组名,每一个都是一个固定长度的字符串。vs_set members
数组的内容取决于成员关系变更的类型:
CAUSED_BY_JOIN:
vs_set包含有加入进来的进程的私有组名。
CAUSED_BY_LEAVE:
vs_set包含有退出的进程的私有组名。
CAUSED_BY_DISCONNECT:
vs_set 包含有关闭连接的进程的私有组名。
CAUSED_BY_NETWORK:
vs_set包含有形成新成员关系的各个成员组的组名称。每个加入的成员集合都有一个vs_set对应。包含有本地应用程序的私有组名的vs_set会有后来加入的成员。
如果这是一条MEMB_MESSAGE但是既不是REG_MEMB_MESS也不是TRANS_MEMB_MESS,那这就表明这种情形是接收消息的成员离开了组,这是一条通知消息。这种有时被称作”闪人通知”。
这个成员刚刚离开的组的成员们会收到一个正常的TRANS_MEMB_MESS,REG_MEMB_MESS消息对,就跟前面描述的一样。
SP_receive的参数如下:
sender参数就是成员关系发生改变的组的名字。
mess_type and endian_mismatch fields will again be set to 0.
max_groups和max_mess_len参数的含义与原来一样,mess_type和endian_dismatch参数再次置为0.
groups数组和消息体提供发生变动的组的两种信息。num_groups会置为0,groups数组会置为0(既然这个成员不再是组的一个成员了。mess的消息体内容也是空。

返回值:返回返回消息的长度(当成功时)或在失败时返回以下任何一个:
ILLEGAL_SESSION
指定的mbox不正确。
ILLEGAL_MESSAGE
消息包含一个正常的结构,比如一个scatter结构没有正确填充。
CONNECTION_CLOSED
在通信时发生了连接错误,接收无法完成。
GROUPS_TOO_SHORT
如果你的groups数组设定的太小了无法存下返回的数组,会返回一个GROUPS_TOO_SHORT的错误。
这时num_groups会返回负数。
BUFFER_TOO_SHORT
如果消息体缓冲(mess)设置的太短,存不下返回的消息时,会返回这个错误,就会返回这个错误,同时endian_mismatch参数会设置为需要的缓冲的长度。

Spread 简介(试译)
Jun 19th, 2008 by 一米六二

项目网站:http://www.spread.org/

Spread 是一个开源工具,它提供高性能的的消息服务,这种服务在局域网和广域网上能有效地避够失效。它在分布式程序中充当一个统一的消息总线的角色,并且提供高调谐的应用级的消息多路播送、组通讯、点到点支持。Spread的应用范围既包括高可靠的消息传送,也包括有序消息的传输(有保证).
Spread可用在许多需要高可靠性,高性能,以及各种子集和成员之间健壮的消息传播的分布式程序中。这个工具封装了异步网络的复杂性,便于创建可高靠和可扩展性的分布式程序.
Spread包含:一些需要被用户程序包含的库文件,一个守护进程(它需要运行在这个一组应用的每台机器上),以及一些工具和演示程序。
Spread提供的功能和便利有:
可靠的、可扩展地消息传播和组通讯。
可以简化分布式程序架构的简单而功能强大的API
易于使用,开发和维护
从本地局域网到复杂的广域网的可扩展性
支持有不同数目的成员的上千个组
提供在机器失效、应用崩溃和网络划分、重组时的可靠的消息传送的能力
为消息传送提供了可靠和排序、稳定保证。
重视健壮性和高性能
完全的分布式算法,不会有中央节点失效风险

为什么使用Spread
* 功能强大而简单的API.只需要六个基本的调用就可以使用Spread了!
* Spread做了优先,在本地局域网中可以支撑每秒8000个1Kbytes的消息
* 在网络划分或系统某部分失效时的可靠性和可用性,不管系统是由几台电脑构成的cluster,或是一些cluster,还是分布于广域网的几千台电脑组成的系统。
* 允许系统无缝地增长扩容而不需要改变架构.
* Spread允许单播,多播,多组多播,scatter-gather calls,或是多路查询。
* Spread能处理网络和机器的重新划分并且能够安全地重新组合,能通知应用当前的状态.
* 跨平台:Spread 支持跨平台的操作:Unix( BSD,Linux,Solaris,Irix,AIX,Mac OS X,etc)和Windows(2000/NT/98/95)
* Spread当前有C/C++,C#,Java,Perl,Python和Ruby的编程接口.

Mysql server tuning(译文)
Jun 29th, 2007 by 一米六二

从某个英文pdf文档译过来的,很久了,还是Mysql Conference 2007时的PDF.
(如果能找到,我把原文地址和pdf给出来)
向原作者致谢….

调整Server Config时需要考虑的事情
设置是针对负载的,不存在说有什么针对一个16GB内存的优化方案这种说法.
存储引擎的选择或是混用是很重要的
有些设置取决于您的硬件和操作系统。

Approaching?tuning
您只需要设置一部分,其余的一些要具体分析(这些也很难决定如何去调整)
有些设置会影响Mysql的行为和安全,要小心
有些设置是可以基于连接的,利用这一点!
首先优化您的查询,否则您需要重新检阅您的设置。
常见错误:
运行默认设置。(当然如果您用来在您的本儿上存您的DVD收集资料, 那当然可以)
直接使用其他人的My.conf文件,都没检查一下是否符合您的需求。
虽然只有一两个查询需要,您仍为它设置了一个巨大的全局设置。您可以这样:
SET sort_buffer_size=128000000;

set sort_buffer_size=DEFAULT

我们能得到的信息:
SHOW STATUS
SHOW INNODB STATUS
操作系统的命令比如:vmstat,iostat,mpstat

使用内存:
为Mysql server分配更多内存常常带来显著的性能提升.
但是分配过多的内存会损失性能甚至是稳定性
检查一下:
Swapping
查看swap IO ,这比简单地使用swap space要好
使用了32位以上的地址(确保OS和mysql server都是64位的)

战胜Swapping
有些操作系统会使用Swap,虽然内存充足。
处理好IO cache和swap间的平衡。
设置VM子系统为只有在最后一次使用resort的时候才swap
tune VM subsystem to use swap only as last resort
echo 1 >/proc/sys/vm/swappiness
如果在linux上使用innodb可以用直接磁盘IO:
innodb_flush_method=O_DIRECt

了解一下变量的单位:
table_cache=128M
错了,它的单位是用个(entries)来衡量的。
key_buffer_size=1024
错了,key buffer size要用bytes来设定。
innodb_max_dirty_pages_pct=8GB
这个设置准确无误。

了解作用域和内存分配规则
key_buffer_size
全局的,由所有线程共用。
sort_buffer_size
需要排序时将内存分配给线程。
read_buffer_size:
一次性就分配指定大小的内存,虽然可能更小的内存就够了
过大的值反而会让事情慢得糟糕
更多的分配常常由OS来完成。
tmp_table_size:
指定一个最大值,在需要的时候会增长到这个值 。
调得过大也没什么事

细节:
关于SHOW STATUS
show global status:了解服务器的全局状态。了解负载的好方法。在Mysql4.1和以下版本中唯一一个。
show local status:
查询/会话配置的好东西
从mysql 5.0开始能用
show status 默认就是这个
有些变量是全局的
也出现会在show status 的输出中
mysqladmin extended -i100 -r
抽样一下,看看Mysql server现在干了些什么,这是个好办法
Show status:
aborted clients:
不用担心,许多程序都没有恰当地关闭连接。
aborted_connects:
可能意味着认证失败,网络超时或其他错误。
值得看一看,因为可能引起主机blocked out
max_connect_errors=100000
可能意味着有人尝试暴力密码破解
binlog_cache_disk_use/binlog_cache_use
bin log 溢出到磁盘的频率。
如果太频繁,需要增大–binlog_cache_size
com_xxx:
按查询来了解服务器负载
查询可以是相当复杂多样的

如何用php和AJAX来创建mailing List (译文,勿转载。)
Nov 1st, 2006 by 一米六二


Use AJAX and PHP to Build your Mailing List
By Aarron Walter
November 1st 2006
Reader Rating: Not rated yet

一个设计优雅,内容充实的网站,没有用户的参与,也是没有生命力的。选择邮件列表作为你的用户与网站之前交互的工具,是一个不错的选择。如果访问者喜欢并且相信您的网站,他们会很信任地把他们的邮件地址告诉佻,毕竟,他们也希望能够 得关于新产品,文章或其他有关信息的通知。这是一个在您的访问者之间建立关系网的不错的方法,并且还能让他一次又一次地访问您的网站,成为您网站的回头客。
在这篇文章中,我们将会用AJAX来接受用户提交的邮件订阅地址,这样就不用刷新页面。用这样一种方法,您的提交过程序会轻松许多。同时,我们的AJAX的提交表格也能接纳那些并不使用支持AJAX技术的浏览器的用户.
这篇文章假定您的mailing list 是储存在Mysql数据库中的。但是只要加上合适的代码,文章中的代码就能很好地适合您自己的应用。

在开始之前,请 href="http://www.sitepoint.com/examples/mailinglist/code-archive.zip">下载代码,看
一看我们要在这篇教程中讲的程序。

[概要]

(奶奶的,这个不好翻译,原文是The Big Picture)
我们的mailing list 登记过程有三个要素:

在php脚本中的一段HTML 表单代码,用来接受用户的邮件地址.
一段javascript代码,监听用户提交表单的事件,并调用AJAX过程,发送Email地址。

一个简单的PHP代码,以接受邮件地址。他会检查邮件地址是否出错,并储存到Mysql数据库中。一个告诉用户操作是成功还是失败的信息会返回给HTML页。
我们同时需要保证登记过程对所有用户是正常可用的,因此写了一个php储存的过程,这样那些浏览器不支持Javascript的用户也能正常使用。

为了简化我们的AJAX编程,我们将用一个通用的javascript库(Prototype)来监听表单提交事件,并处理Ajax消息。如果您是一个Prototype的初学者,建议您看看Dan Webb的文章 href="http://www.sitepoint.com/article/painless-javascript-prototype">Painless
JavaScript Using Prototype
and href="http://www.sitepoint.com/article/javascript-library">The JavaScript
Library World Cup
.

表单提交过程

我们的第一步是建立表单以接受邮件地址。然后我们调用javascript来发送消息。这就是表单代码:


Join our mailing list!



表单是相当地简单。我们只弄了一个text类型的输入框,用来接受用户的邮件地址,然后放了一个submit按钮,用来激发Ajax事件。表单的ID必须确定,因为要靠它来激活javascript对提交事件的监听。

注意表单文字中有一个PHP函数:storeAddress.这是我们实现登记过程的可用性的核心。当这个页面第一次载入时,storeAddress返回一个空格,这样整段文字显示空。稍后,当Ajax过程被用户的提交事件激发后,Javascript会往这一段中加入消息,以让用户知道我们做了什么事。另外,如果用户客户端并没有开启对javascript的支持,那这个页面会被再次调入。这会导致storeAddress被再次调用。这一次,会显示一段消息。
在页面的头部,我们需要用<script> 标记链入Prototype库.我们也需要链入mailingList.js,这样代码将会是这样了:




这种架构的优雅之处就在于,不同的功能之间完全分开了,使得开发和维护更方便了。

用AJAX来发送邮件地址

在js目录中,除开progotype.js文件之外,另外一个是mailinglist.js.这个文件是特别征对我们的html页面的AJAX应用的。这个文件的第一个应用就是往表单中添加一个事件监听器,由这个事件监听器来调用AJAX过程。当然,我们不能直接这么干,得等页面加载完成之后。而页面加载完成这个事件是是window这个对象的load事件来通知的。
为了添加这个事件监听器,我们需要用到Prototype的一个叫observe的很方便的方法。我们首先添加页面的load的事件的监听。
在这个监听器中,我们可以为表单的提交事件也加上我们的监听器

// Attach handler to window load event
Event.observe(window, ‘load’, init, false);

function init() {
// Attach handler to form’s submit event
Event.observe(’addressForm’, ’submit’, storeAddress);
}


注意,当表单被提交时,监听器会调用一个叫storeAddress的Javascript方法。这个方法包含了一个到PHP脚本的Ajax调用。脚本是这样的:

function storeAddress(e) {
// Update user interface
$(’response’).innerHTML = ‘Adding email address…’;
// Prepare query string and send AJAX request
var pars = ‘address=’ + escape($F(’address’));
var myAjax = new Ajax.Updater(’response’, ‘ajaxServer.php’, {method: ‘get’, parameters: pars});
// Stop form from submitting when JavaScript is enabled
Event.stop(e);
}

这个方法(函数)是非常简单的。它先显示”Adding email address…”以告知用户我们在做什么。接着,我们收集表单的信息,以便于发送AJAX请求。注意我们通过一个叫$F的函数来访问文本框的内容。这个函数接受的参数是HTML元素的ID,返回这个元素的值。我们使用javascript的escape函数来将用户的输入换成Unicode格式。这样,要发送给PHP script的url就已经准备好了。
接下来,就是最重要的部分了:Ajax.Updater对象的创建。当我们创建好Ajax.Updater对象时,我们把这些参数传给他:

我们希望在它的里面显示服务器端返回的内容的那个元素的ID
php 脚本的地址
您希望发送给服务器端的内容,以及发送方法。(POST还是GET)
Ajax.Updater会发送邮件地址,然后会很老实地等着服务器端的返回。当它收到回信儿,它就会在”Adding email address…” 那个地方显示出来。最后,我们调用 Event.stop(Prototype上提供的另一个方法)来停止表音的提交过程。(事实上,这个表单还正在往服务器上提交数据呢。)

设置Mailinglist数据库

在我们写任任PHP脚本之前,我们需要一个地方来储存他们。这段sql脚本会创建一个叫mailinglist的表。

CREATE TABLE `mailinglist` (
`id` INT NOT NULL AUTO_INCREMENT ,
`email` TEXT NOT NULL ,
PRIMARY KEY ( `id` )
);

后面的老子懒得翻了,老外的技术也就这德性。后面的会php的都会。没技术含量。需要的,自个儿下代码慢慢看吧。

CakePHP入门…译文,请勿转载.
Oct 21st, 2006 by 一米六二

CakePHP入门

第一部分:

什么是CakePHP?

cakephp是PHP的一个免费的快速开发开源框架。它是一些最早是在Ruby on rails中闪现的天才创意的让程序员来创建应用的库,类和运行时构件而构成的结构。我们的最大目标是希望能让您以一种良好的组织和快捷的开式来工作,并且,还不损失其灵活性。

第二部分:

为什么要用CakePHP?

CakePHP有一些很好的特性,这使得它将当仁不让地成为您快速开发时最好的开发框架。这里是一些特性,注意并没有特别排序.

  • 活跃的,友好的社区支持
  • 宽松的许可制度
  • 能兼容PHP5和PHP4.
  • 程序代码自动生成
  • Model,View,Controller 架构。
  • 看起来比较漂亮的URL
  • 内建的检查认证支持
  • 快速而灵活的模板支持(支持PHP语法,有帮助文档)
  • 安全,会话,请求处理组件…

权限控制。。
数据清理
可以工作在任一个子目录下,只需要一丁点儿配置..

 

第三部分:

CakePHP的历史:

2005年

Michal Tatarynowicz用php写了一个很小的快速开发的框架。他认为这将是一个很好的开发框架的起源。

Michal Tatarynowicz后来将他在MIT的条款下发布,给他取名Cake,并展示给一群开发者,这些人后来继续维持着Cake,虽然此时已经改名为Cakephp.

 

cakePHP手册(译文,勿转载)
Oct 21st, 2006 by 一米六二

序言

第一部分:听众应当是谁?

这个手册是写给那些希望快速并且轻松地创建web应用程序的人们。CakePHP旨在帮助各种水平的PHP用户们

轻松、快速地创建功能 强大而又具备良好的可扩展性的程序 。

阅读这本手册需要您对PHP,HTML有一个基本的了解。如果您对MVC的设计模式有所了解那是更好,不过,即便您是一个MVC的新手,也不用急,我们会慢慢带您入门。这本手册当然会教那些在配置WEB服务器等问题上遇到麻烦的读者,但完全覆盖这些显示超出了本手册的范围。

一些初步的知识,基本的的解围技巧,相关的历史和关系,会在这个手册里加以说明,虽然这已经超出了本手册的范围。

第二部分:CakePHP是免费的

Cakephp是免费的,您不需要为它付一个铜子儿,您可以以任何需要的方式使用它。CakePHP是基于MIT的那些条款来发布的。Cakephp是一个开源软件,这意味着您可以得到它的全部源代码。得到它的最好方式是访问它的官方网站(http://www.cakephp.org);您也可以在这个网站上看到一些最新发布的或是非常酷的代码。

第三部分:

CakePHP是由一个工作非常努力的社区的人们来开发的。他们来自世界各地,聚到了一起为千万用户,尽可能多的用户能用上这么一个好的框架而努力工作。您可以访问http://www.cakephp.org来得到关于cakephp的活跃用户和开发者的更多信息。

我们的IRC聊天室总是有许多知识扎实,乐于助人的朋友。如果您为一个代码问题而伤神,或是需要一位聆听者,或是想发起一场关于编程习惯的讨论,拿起您的话筒吧(这点我有点不确定,原文是Drop on by.我猜的..)。我们期望听到你的声音。请到irc.Freenode.com的#cakephp房间来找我们吧。

 

»  Substance: WordPress   »  Style: Ahren Ahimsa
29312 页面访问次数, 545 今天
11320 访问数, 168 今天
FireStats icon 由FireStats提供支持