<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19262010</id><updated>2012-01-29T18:21:41.954+08:00</updated><category term='linux'/><category term='apache'/><category term='firefox'/><category term='android'/><category term='emacs'/><category term='tools'/><category term='javascript'/><category term='mysql'/><category term='python'/><category term='development'/><category term='perl'/><category term='ie'/><category term='mod_perl'/><title type='text'>静室</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default?start-index=101&amp;max-results=100'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>186</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19262010.post-6459252229451660714</id><published>2011-11-15T18:06:00.002+08:00</published><updated>2011-11-15T18:11:26.711+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>将matplotlib画的图拷贝到剪贴板</title><content type='html'>matplotlib画完的图没有copy的功能，于是组合了网上找到的几个函数，执行之后将figure中的图复制到剪贴板。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;from cStringIO import StringIO&lt;br /&gt;import win32clipboard&lt;br /&gt;from PIL import Image&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def send_to_clipboard(clip_type, data):&lt;br /&gt;    win32clipboard.OpenClipboard()&lt;br /&gt;    win32clipboard.EmptyClipboard()&lt;br /&gt;    win32clipboard.SetClipboardData(clip_type, data)&lt;br /&gt;    win32clipboard.CloseClipboard()&lt;br /&gt;&lt;br /&gt;def save_figure(f, file, w, h):&lt;br /&gt;    if not f:&lt;br /&gt;        f = plt.gcf()&lt;br /&gt;    dpi = f.get_dpi()&lt;br /&gt;    f.set_figwidth(w / dpi)&lt;br /&gt;    f.set_figheight(h /dpi)&lt;br /&gt;    f.savefig(file)&lt;br /&gt;&lt;br /&gt;def copy_figure(w=600, h=400, fig=None):&lt;br /&gt;    file = StringIO()&lt;br /&gt;    save_figure(fig, file, w, h)&lt;br /&gt;    file.seek(0)&lt;br /&gt;    image = Image.open(file)&lt;br /&gt;    output = StringIO()&lt;br /&gt;    image.convert("RGB").save(output, "BMP")&lt;br /&gt;    data = output.getvalue()[14:]&lt;br /&gt;    output.close()&lt;br /&gt;    send_to_clipboard(win32clipboard.CF_DIB, data)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6459252229451660714?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6459252229451660714/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6459252229451660714' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6459252229451660714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6459252229451660714'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2011/11/matplotlib.html' title='将matplotlib画的图拷贝到剪贴板'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6564550964530300324</id><published>2011-09-22T18:43:00.003+08:00</published><updated>2011-09-22T19:11:33.030+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>服务器进程卡死调查</title><content type='html'>服务器上运行了一个python的爬虫程序，一直运行的很好的。今天凌晨突然进程占cpu 100%，然后爬取一直无法继续，因为是多线程的，用strace, ltrace都只能看到线程在等待锁。后来想到用gdb查看线程的信息，gdb完全不会用，只好借用poor man's profiler里的&lt;br /&gt;&lt;pre&gt;(echo "set pagination 0";&lt;br /&gt;echo "thread apply all bt";&lt;br /&gt;echo "quit"; cat /dev/zero ) | gdb -p [processid]&lt;br /&gt;&lt;/processid&gt;&lt;/pre&gt;&lt;br /&gt;得到&lt;br /&gt;&lt;pre&gt;Thread 12 (Thread 0x41d61940 (LWP 2741)):&lt;br /&gt;#0  0x000000333120cb21 in sem_wait () from /lib64/libpthread.so.0&lt;br /&gt;#1  0x00000000004c06ad in PyThread_acquire_lock (lock=0x48bb110, waitflag=1) at Python/thread_pthread.h:349&lt;br /&gt;#2  0x000000000048c6fa in PyEval_AcquireThread (tstate=0x48e8a10) at Python/ceval.c:253&lt;br /&gt;#3  0x00002b31ff3b9121 in util_write_callback ...&lt;br /&gt;#4  0x00002b31ff5d9bf8 in Curl_client_write ...&lt;br /&gt;#5  0x00002b31ff5f030f in Curl_httpchunk_read ...&lt;br /&gt;#6  0x00002b31ff5ee150 in readwrite_data (conn=0x2aaaac052b70, done=0x41d606c7) at transfer.c:530&lt;br /&gt;#7  Curl_readwrite (conn=0x2aaaac052b70, done=0x41d606c7) at transfer.c:1600&lt;br /&gt;#8  0x00002b31ff5ef016 in Transfer (data=0x2aaaac053b10) at transfer.c:1855&lt;br /&gt;#9  Curl_perform (data=0x2aaaac053b10) at transfer.c:2451&lt;br /&gt;#10 0x00002b31ff3b9503 in do_curl_perform (self=0x2aaaac047120) at src/pycurl.c:1024&lt;br /&gt;#11 0x0000000000492f12 in call_function (f=0x4a70930, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3690&lt;br /&gt;#12 PyEval_EvalFrameEx (f=0x4a70930, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#13 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x484ddc8, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a706a8, argcount=1, kws=0x4a706b0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#14 0x0000000000492d71 in call_function (f=0x4a70510, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#15 PyEval_EvalFrameEx (f=0x4a70510, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#16 0x00000000004941c5 in call_function (f=0x4a70340, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3792&lt;br /&gt;#17 PyEval_EvalFrameEx (f=0x4a70340, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#18 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x475e6c0, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a12ee8, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#19 0x00000000004ea69d in function_call (func=0x4799cf8, arg=0x4a12ed0, kw=0x0) at Objects/funcobject.c:524&lt;br /&gt;#20 0x0000000000417bbd in PyObject_Call (func=0x4799cf8, arg=0x4a12ed0, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#21 0x000000000041efcf in instancemethod_call (func=&lt;value optimized="" out=""&gt;, arg=0x4a12ed0, kw=0x0) at Objects/classobject.c:2579&lt;br /&gt;#22 0x0000000000417bbd in PyObject_Call (func=0x4858b40, arg=0x2b31f944d050, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#23 0x000000000048c516 in PyEval_CallObjectWithKeywords (func=0x4858b40, arg=0x2b31f944d050, kw=0x0) at Python/ceval.c:3575&lt;br /&gt;#24 0x00000000004c39ad in t_bootstrap (boot_raw=0x4a63920) at ./Modules/threadmodule.c:425&lt;br /&gt;#25 0x0000003331206617 in start_thread () from /lib64/libpthread.so.0&lt;br /&gt;#26 0x0000003330ad3c2d in clone () from /lib64/libc.so.6&lt;br /&gt;&lt;br /&gt;Thread 11 (Thread 0x427f5940 (LWP 2742)):&lt;br /&gt;#0  0x000000333120cb21 in sem_wait () from /lib64/libpthread.so.0&lt;br /&gt;#1  0x00000000004c06ad in PyThread_acquire_lock (lock=0x48bb110, waitflag=1) at Python/thread_pthread.h:349&lt;br /&gt;#2  0x000000000048c6fa in PyEval_AcquireThread (tstate=0x48e18e0) at Python/ceval.c:253&lt;br /&gt;#3  0x00002b31ff3b9121 in util_write_callback ...&lt;br /&gt;#4  0x00002b31ff5d9bf8 in Curl_client_write ...&lt;br /&gt;#5  0x00002b31ff5f030f in Curl_httpchunk_read ...&lt;br /&gt;#6  0x00002b31ff5ee150 in readwrite_data (conn=0x2aaaac001170, done=0x427f46c7) at transfer.c:530&lt;br /&gt;#7  Curl_readwrite (conn=0x2aaaac001170, done=0x427f46c7) at transfer.c:1600&lt;br /&gt;#8  0x00002b31ff5ef016 in Transfer (data=0x2aaaac086660) at transfer.c:1855&lt;br /&gt;#9  Curl_perform (data=0x2aaaac086660) at transfer.c:2451&lt;br /&gt;#10 0x00002b31ff3b9503 in do_curl_perform (self=0x2aaaac048430) at src/pycurl.c:1024&lt;br /&gt;#11 0x0000000000492f12 in call_function (f=0x4a72760, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3690&lt;br /&gt;#12 PyEval_EvalFrameEx (f=0x4a72760, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#13 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x484ddc8, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a71cb8, argcount=1, kws=0x4a71cc0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#14 0x0000000000492d71 in call_function (f=0x4a71b20, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#15 PyEval_EvalFrameEx (f=0x4a71b20, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#16 0x00000000004941c5 in call_function (f=0x4a71950, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3792&lt;br /&gt;#17 PyEval_EvalFrameEx (f=0x4a71950, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#18 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x475e6c0, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a2aea8, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#19 0x00000000004ea69d in function_call (func=0x4799cf8, arg=0x4a2ae90, kw=0x0) at Objects/funcobject.c:524&lt;br /&gt;#20 0x0000000000417bbd in PyObject_Call (func=0x4799cf8, arg=0x4a2ae90, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#21 0x000000000041efcf in instancemethod_call (func=&lt;value optimized="" out=""&gt;, arg=0x4a2ae90, kw=0x0) at Objects/classobject.c:2579&lt;br /&gt;#22 0x0000000000417bbd in PyObject_Call (func=0x4858d20, arg=0x2b31f944d050, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#23 0x000000000048c516 in PyEval_CallObjectWithKeywords (func=0x4858d20, arg=0x2b31f944d050, kw=0x0) at Python/ceval.c:3575&lt;br /&gt;#24 0x00000000004c39ad in t_bootstrap (boot_raw=0x49a2ba0) at ./Modules/threadmodule.c:425&lt;br /&gt;#25 0x0000003331206617 in start_thread () from /lib64/libpthread.so.0&lt;br /&gt;#26 0x0000003330ad3c2d in clone () from /lib64/libc.so.6&lt;br /&gt;&lt;br /&gt;Thread 6 (Thread 0x459fa940 (LWP 2747)):&lt;br /&gt;#0  sre_match (state=0x459f8880, pattern=0x0) at ./Modules/_sre.c:1137&lt;br /&gt;&lt;span style="color:red;"&gt;#1  0x00000000004d2a13 in sre_search (state=0x459f8880, pattern=0x4c8f4ba) at ./Modules/_sre.c:1609&lt;/span&gt;&lt;br /&gt;#2  0x00000000004d3fc3 in pattern_findall (self=0x4c8f350, args=&lt;value optimized="" out=""&gt;, kw=&lt;value optimized="" out=""&gt;) at ./Modules/_sre.c:2072&lt;br /&gt;#3  0x0000000000493261 in call_function (f=0x4868950, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3706&lt;br /&gt;#4  PyEval_EvalFrameEx (f=0x4868950, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#5  0x0000000000494b7d in PyEval_EvalCodeEx (co=0x490a198, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4d8a410, argcount=2, kws=0x4d8a420, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#6  0x0000000000492d71 in call_function (f=0x4d8a280, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#7  PyEval_EvalFrameEx (f=0x4d8a280, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#8  0x0000000000494b7d in PyEval_EvalCodeEx (co=0x4aff738, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x49fe318, argcount=1, kws=0x49fe320, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#9  0x0000000000492d71 in call_function (f=0x49fe170, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#10 PyEval_EvalFrameEx (f=0x49fe170, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#11 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x4852dc8, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a78380, argcount=3, kws=0x4a78398, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#12 0x0000000000492d71 in call_function (f=0x4a781a0, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#13 PyEval_EvalFrameEx (f=0x4a781a0, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#14 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x484ddc8, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a77818, argcount=1, kws=0x4a77820, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#15 0x0000000000492d71 in call_function (f=0x4a77680, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3802&lt;br /&gt;#16 PyEval_EvalFrameEx (f=0x4a77680, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#17 0x00000000004941c5 in call_function (f=0x4a774b0, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:3792&lt;br /&gt;#18 PyEval_EvalFrameEx (f=0x4a774b0, throwflag=&lt;value optimized="" out=""&gt;) at Python/ceval.c:2389&lt;br /&gt;#19 0x0000000000494b7d in PyEval_EvalCodeEx (co=0x475e6c0, globals=&lt;value optimized="" out=""&gt;, locals=&lt;value optimized="" out=""&gt;, args=0x4a318e8, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968&lt;br /&gt;#20 0x00000000004ea69d in function_call (func=0x4799cf8, arg=0x4a318d0, kw=0x0) at Objects/funcobject.c:524&lt;br /&gt;#21 0x0000000000417bbd in PyObject_Call (func=0x4799cf8, arg=0x4a318d0, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#22 0x000000000041efcf in instancemethod_call (func=&lt;value optimized="" out=""&gt;, arg=0x4a318d0, kw=0x0) at Objects/classobject.c:2579&lt;br /&gt;#23 0x0000000000417bbd in PyObject_Call (func=0x48fbe10, arg=0x2b31f944d050, kw=0x0) at Objects/abstract.c:2492&lt;br /&gt;#24 0x000000000048c516 in PyEval_CallObjectWithKeywords (func=0x48fbe10, arg=0x2b31f944d050, kw=0x0) at Python/ceval.c:3575&lt;br /&gt;#25 0x00000000004c39ad in t_bootstrap (boot_raw=0x49efb60) at ./Modules/threadmodule.c:425&lt;br /&gt;#26 0x0000003331206617 in start_thread () from /lib64/libpthread.so.0&lt;br /&gt;#27 0x0000003330ad3c2d in clone () from /lib64/libc.so.6&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt; Inferior 1 [process 2724] will be detached.&lt;br /&gt;&lt;br /&gt;Quit anyway? (y or n) [answered Y; input not from terminal]&lt;br /&gt;Detaching from program: /usr/local/python/bin/python2.6, process 2724&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;可以看到大部分的线程都在等待信号，只有一个线程是sre_search，这就是罪魁祸首了。具体的原因是正则匹配里有一个类似"a.*?b.*?c.*?d"的东西，页面今天改版之后，无法匹配，而这个表达式会不停的尝试，所以cpu一直是100%，这个线程也导致整个python进程卡死。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6564550964530300324?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6564550964530300324/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6564550964530300324' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6564550964530300324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6564550964530300324'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2011/09/blog-post.html' title='服务器进程卡死调查'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3573425116880747032</id><published>2011-07-29T13:03:00.000+08:00</published><updated>2011-07-29T13:06:12.116+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ie'/><title type='text'>ie无法设置cookie的问题</title><content type='html'>在测试站点上写cookie发现ie始终不会保存，其他浏览器都是好的。改各种东西测试了半天，最后发现是域名的问题，换了个域名问题就解决了。搞不清到底是什么毛病。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3573425116880747032?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3573425116880747032/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3573425116880747032' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3573425116880747032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3573425116880747032'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2011/07/iecookie.html' title='ie无法设置cookie的问题'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6617002555646906912</id><published>2011-05-25T15:21:00.001+08:00</published><updated>2011-05-25T15:26:12.018+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>dns奇怪的问题</title><content type='html'>公司里在ubuntu上架了bind服务，今天发现某些机器对某些地址进行dns解析时，返回NXDOMAIN，而同样的地址在另一些机器上又是可以正常解析的，它们用的dns都是自己架的这个。通过google和测试发现关闭dns服务器上的ipv6就都正常了。&lt;br /&gt;&lt;br /&gt;在ubuntu上禁用ipv6：&lt;br /&gt;注释掉 /etc/modprobe.d/aliases中的alias net-pf-10 ipv6，&lt;br /&gt;然后在/etc/modprobe.d/blacklist中加入blacklist ipv6，&lt;br /&gt;最后重启服务器。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6617002555646906912?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6617002555646906912/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6617002555646906912' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6617002555646906912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6617002555646906912'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2011/05/dns.html' title='dns奇怪的问题'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2013970137540555093</id><published>2011-03-16T16:13:00.002+08:00</published><updated>2011-03-16T16:17:55.483+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>虚拟机无法正常启动的问题</title><content type='html'>在centos 5.5上用kvm再装centos，运行一段时间后重启会报错：&lt;br /&gt;&lt;pre&gt;SELinux:  Disabled at runtime.&lt;br /&gt;type=1404 audit(1299831154.138:2): selinux=0 auid=4294967295 ses=4294967295&lt;br /&gt;INIT: version 2.86 booting&lt;br /&gt;rc.sysinit[395]: segfault at 000000000f86a002 rip 000000000f86a002 rsp 00007fff2932cfc8 error 14&lt;br /&gt;INIT: Entering runlevel: 3&lt;br /&gt;rc[397]: segfault at 000000000f86a002 rip 000000000f86a002 rsp 00007fff2854c3d8 error 14&lt;br /&gt;&lt;/pre&gt;然后虚拟机占cpu一直是100%，也无法登陆。经测试发现，如果映像文件使用稀疏文件，那么运行几个小时之后重启就有这个问题，用普通文件没事。为什么就不知道了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2013970137540555093?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2013970137540555093/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2013970137540555093' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2013970137540555093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2013970137540555093'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2011/03/blog-post.html' title='虚拟机无法正常启动的问题'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-9007685102991030988</id><published>2010-12-14T15:26:00.001+08:00</published><updated>2010-12-14T15:28:07.814+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>全屏切换后status bar导致屏幕下移</title><content type='html'>当全屏切换出去之后再返回，status bar的位置会被空出来，导致整个view下移。&lt;br /&gt;已经有人提了bug。&lt;br /&gt;http://code.google.com/p/android/issues/detail?id=8052&lt;br /&gt;&lt;br /&gt;下面的讨论中提供了一个hack，就是加上下面setFlags这句&lt;br /&gt;http://groups.google.com/group/android-developers/browse_thread/thread/2de77043f32835aa/315d393bb8334db5&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-9007685102991030988?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/9007685102991030988/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=9007685102991030988' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9007685102991030988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9007685102991030988'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2010/12/status-bar.html' title='全屏切换后status bar导致屏幕下移'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7372609568714619446</id><published>2010-12-11T02:04:00.003+08:00</published><updated>2010-12-11T23:07:10.919+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>组合WebView和ProgressBar</title><content type='html'>想给WebView加一个进度条，结果发现android的文档中“Building Custom Components”提到的R.styleable这个类已经不能用了。我不想加xml配置，还没有找到什么好方法能处理初始化时的attrs。进度条在顶部固定显示在试了半天之后倒是弄好了。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@SuppressWarnings("deprecation")&lt;br /&gt;public class ProgressWebView extends WebView {&lt;br /&gt;&lt;br /&gt;   private ProgressBar progressbar;&lt;br /&gt;&lt;br /&gt;   public ProgressWebView(Context context, AttributeSet attrs) {&lt;br /&gt;       super(context, attrs);&lt;br /&gt;       progressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);&lt;br /&gt;       progressbar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 3, 0, 0));&lt;br /&gt;       addView(progressbar);&lt;br /&gt;       setWebViewClient(new WebViewClient());&lt;br /&gt;       setWebChromeClient(new WebChromeClient());&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public class WebChromeClient extends android.webkit.WebChromeClient {&lt;br /&gt;       @Override&lt;br /&gt;       public void onProgressChanged(WebView view, int newProgress) {&lt;br /&gt;           if(newProgress == 100) {&lt;br /&gt;               progressbar.setVisibility(GONE);&lt;br /&gt;           } else {&lt;br /&gt;               if(progressbar.getVisibility() == GONE)&lt;br /&gt;                   progressbar.setVisibility(VISIBLE);&lt;br /&gt;               progressbar.setProgress(newProgress);&lt;br /&gt;           }&lt;br /&gt;           super.onProgressChanged(view, newProgress);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   @Override&lt;br /&gt;   protected void onScrollChanged(int l, int t, int oldl, int oldt) {&lt;br /&gt;       LayoutParams lp = (LayoutParams) progressbar.getLayoutParams();&lt;br /&gt;       lp.x = l;&lt;br /&gt;       lp.y = t;&lt;br /&gt;       progressbar.setLayoutParams(lp);&lt;br /&gt;       super.onScrollChanged(l, t, oldl, oldt);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7372609568714619446?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7372609568714619446/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7372609568714619446' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7372609568714619446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7372609568714619446'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2010/12/webviewprogressbar.html' title='组合WebView和ProgressBar'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2737857542657254883</id><published>2010-04-16T10:51:00.004+08:00</published><updated>2010-04-16T11:07:19.395+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>emeditor的monokai配色</title><content type='html'>看到textmate上的monokai配色，觉得很漂亮，移植到emeditor上了。因为最近基本只写python的代码，所以只有python的。&lt;br /&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 593px; height: 415px;" src="http://4.bp.blogspot.com/_stJgJ465TXE/S8fUAG4yRHI/AAAAAAAACr8/gX04Uq2kXVU/s1600/monokai.png" alt="monokai" id="BLOGGER_PHOTO_ID_5460566171523892338" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;python.esy&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; EmEditor Syntax File&lt;br /&gt;;&lt;br /&gt;; To import this file to an existing configuration, select Configuration&lt;br /&gt;; under the Tool menu, select Define Configurations, select a configuration&lt;br /&gt;; you want to import to, press [Properties], select the Highlight page, and&lt;br /&gt;; press [Import].&lt;br /&gt;;&lt;br /&gt;; Submit your customized file to submit@emurasoft.com&lt;br /&gt;; to be listed in www.emurasoft.com user files pages.&lt;br /&gt;;&lt;br /&gt;#Highlight=on&lt;br /&gt;#BeginTag=&lt;br /&gt;#EndTag=&lt;br /&gt;#CommentBegin="""&lt;br /&gt;#CommentEnd="""&lt;br /&gt;#LineComment1=^#&lt;br /&gt;#LineComment2=&lt;br /&gt;#SingleQuote=on&lt;br /&gt;#DoubleQuote=on&lt;br /&gt;#ContinueQuote=off&lt;br /&gt;#Escape=\&lt;br /&gt;#ScriptBegin=&lt;br /&gt;#ScriptEnd=&lt;br /&gt;#SpecialSyntax=off&lt;br /&gt;#HighlightBraces=on&lt;br /&gt;&lt;br /&gt;#Keyword color=4,word=on,rightall=off,case=on,insidetag=off,regexp=off,rightall2=off&lt;br /&gt;and&lt;br /&gt;assert&lt;br /&gt;break&lt;br /&gt;continue&lt;br /&gt;def&lt;br /&gt;del&lt;br /&gt;elif&lt;br /&gt;else&lt;br /&gt;except&lt;br /&gt;exec&lt;br /&gt;finally&lt;br /&gt;for&lt;br /&gt;from&lt;br /&gt;global&lt;br /&gt;if&lt;br /&gt;import&lt;br /&gt;in&lt;br /&gt;is&lt;br /&gt;lambda&lt;br /&gt;not&lt;br /&gt;or&lt;br /&gt;pass&lt;br /&gt;print&lt;br /&gt;raise&lt;br /&gt;return&lt;br /&gt;try&lt;br /&gt;while&lt;br /&gt;as&lt;br /&gt;with&lt;br /&gt;&lt;br /&gt;#Keyword color=1,word=on,rightall=off,case=on,insidetag=off,regexp=off,rightall2=off&lt;br /&gt;class&lt;br /&gt;object&lt;br /&gt;Exception&lt;br /&gt;BaseException&lt;br /&gt;StandardError&lt;br /&gt;ArithmeticError&lt;br /&gt;LookupError&lt;br /&gt;EnvironmentError&lt;br /&gt;AssertionError&lt;br /&gt;AttributeError&lt;br /&gt;EOFError&lt;br /&gt;FloatingPointError&lt;br /&gt;GeneratorExit&lt;br /&gt;IOError&lt;br /&gt;ImportError&lt;br /&gt;IndexError&lt;br /&gt;KeyError&lt;br /&gt;KeyboardInterrupt&lt;br /&gt;MemoryError&lt;br /&gt;NameError&lt;br /&gt;NotImplementedError&lt;br /&gt;OSError&lt;br /&gt;OverflowError&lt;br /&gt;ReferenceError&lt;br /&gt;RuntimeError&lt;br /&gt;StopIteration&lt;br /&gt;SyntaxError&lt;br /&gt;SystemError&lt;br /&gt;SystemExit&lt;br /&gt;TypeError&lt;br /&gt;UnboundLocalError&lt;br /&gt;UnicodeError&lt;br /&gt;UnicodeEncodeError&lt;br /&gt;UnicodeDecodeError&lt;br /&gt;UnicodeTranslateError&lt;br /&gt;ValueError&lt;br /&gt;VMSError&lt;br /&gt;WindowsError&lt;br /&gt;ZeroDivisionError&lt;br /&gt;Warning&lt;br /&gt;UserWarning&lt;br /&gt;DeprecationWarning&lt;br /&gt;PendingDeprecationWarning&lt;br /&gt;SyntaxWarning&lt;br /&gt;RuntimeWarning&lt;br /&gt;FutureWarning&lt;br /&gt;ImportWarning&lt;br /&gt;UnicodeWarning&lt;br /&gt;xrange&lt;br /&gt;range&lt;br /&gt;iter&lt;br /&gt;sorted&lt;br /&gt;&lt;br /&gt;#Keyword color=1,word=on,rightall=off,case=on,insidetag=off,regexp=on,rightall2=off&lt;br /&gt;(?&amp;lt;!\.)list&lt;br /&gt;(?&amp;lt;!\.)tuple&lt;br /&gt;(?&amp;lt;!\.)dict&lt;br /&gt;(?&amp;lt;!\.)set&lt;br /&gt;(?&amp;lt;!\.)len&lt;br /&gt;(?&amp;lt;!\.)all&lt;br /&gt;(?&amp;lt;!\.)any&lt;br /&gt;__(abs|add|and|class|cmp|coerce|delattr|div|divmod|doc)__&lt;br /&gt;__(float|floordiv|format|getattribute|getnewargs|hash|hex|index)__&lt;br /&gt;__(init|int|invert|long|lshift|mod|mul|neg|new|nonzero|oct|or|pos|pow)__&lt;br /&gt;__(radd|rand|rdiv|rdivmod|reduce|reduceex|repr|rfloordiv|rlshift|rmod)__&lt;br /&gt;__(rmul|ror|rpow|rrshift|rshift|rsub|rtruediv)__&lt;br /&gt;__(rxor|setattr|sizeof|str|sub|subcl)__&lt;br /&gt;&lt;br /&gt;#Keyword color=3,word=on,rightall=off,case=on,insidetag=off,regexp=off,rightall2=off&lt;br /&gt;True&lt;br /&gt;False&lt;br /&gt;None&lt;br /&gt;&lt;br /&gt;#Keyword color=2,word=on,rightall=off,case=on,insidetag=off,regexp=on,rightall2=off&lt;br /&gt;\+|\=|\-|\*|\/|\!|\||\&amp;amp;|\^^|\@&lt;br /&gt;&lt;br /&gt;#Keyword color=7,word=off,rightall=off,case=off,insidetag=off,regexp=on,rightall2=off&lt;br /&gt;(?&amp;lt;=def )\w+(?=\(| \()&lt;br /&gt;&lt;br /&gt;#Keyword color=3,word=on,rightall=off,case=off,insidetag=off,regexp=on,rightall2=off&lt;br /&gt;[\-\+]?(\d+|\d+\.\d*|\.\d+)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;monokai.eetheme&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[Monokai]&lt;br /&gt;MaxFind=1&lt;br /&gt;Normal=#f8f8f2,#272822,normal&lt;br /&gt;Sel=transparent,#49483e,normal&lt;br /&gt;CurrentLine=transparent,#3e3d32,normal&lt;br /&gt;Quoted=#c0c0ff,transparent,normal&lt;br /&gt;Find=transparent,#40ff40,normal&lt;br /&gt;URL=#008080,transparent,underline&lt;br /&gt;Mail=#008000,transparent,underline&lt;br /&gt;Tag=#808000,transparent,underline&lt;br /&gt;SingleQuotes=#e6db74,transparent,normal&lt;br /&gt;DoubleQuotes=#e6db74,transparent,normal&lt;br /&gt;Comment=#75715e,transparent,normal&lt;br /&gt;Script=#a6e22e,transparent,normal&lt;br /&gt;Braces=#ffff00,transparent,bold&lt;br /&gt;InTag=#a6e22e,transparent,normal&lt;br /&gt;Highlight1=#66d9ef,transparent,normal&lt;br /&gt;Highlight2=#fd971f,transparent,normal&lt;br /&gt;Highlight3=#ae81ff,transparent,normal&lt;br /&gt;Highlight4=#f92672,transparent,normal&lt;br /&gt;Highlight5=#f8f8ff,#f92672,normal&lt;br /&gt;Highlight6=#f8f8ff,#ae81ff,normal&lt;br /&gt;Highlight7=#a6e22e,transparent,normal&lt;br /&gt;Highlight8=#fd971f,transparent,normal&lt;br /&gt;Highlight9=transparent,#00ffff,normal&lt;br /&gt;Highlight10=transparent,#40ff40,normal&lt;br /&gt;Return=#c0c0ff,transparent,normal&lt;br /&gt;Line=#c0c0c0,#e1e1e1,normal&lt;br /&gt;PageBreak=transparent,#c0c0c0,normal&lt;br /&gt;LineNumber=#7a4ba2,#c0c0ff,normal&lt;br /&gt;Ruler=#7a4ba2,#c0c0ff,normal&lt;br /&gt;Outside=transparent,transparent,normal&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2737857542657254883?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2737857542657254883/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2737857542657254883' title='5 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2737857542657254883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2737857542657254883'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2010/04/emeditormonokai.html' title='emeditor的monokai配色'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_stJgJ465TXE/S8fUAG4yRHI/AAAAAAAACr8/gX04Uq2kXVU/s72-c/monokai.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8153947485854055496</id><published>2009-12-20T20:47:00.003+08:00</published><updated>2009-12-22T12:21:34.895+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>查询性能的跳跃</title><content type='html'>今天遇到一个很奇怪的问题，两句差不多的sql，性能却有很大差别。&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;$ mysql test -e  'flush status;set profiling=1;select t from t where t like "%a%" order by id desc limit 9085,1;show profiles;show status;' &amp;gt; a.txt&lt;br /&gt;$ mysql test -e  'flush status;set profiling=1;select t from t where t like "%a%" order by id desc limit 9086,1;show profiles;show status;' &amp;gt; b.txt&lt;br /&gt;$ diff a.txt b.txt&lt;br /&gt;2c2&lt;br /&gt;&amp;lt; sportsman&lt;br /&gt;---&lt;br /&gt;&amp;gt; sportscasts&lt;br /&gt;4c4&lt;br /&gt;&amp;lt; 1     0.07678300      select t from t where t like "%a%" order by id desc limit 9085,1&lt;br /&gt;---&lt;br /&gt;&amp;gt; 1     0.24102700      select t from t where t like "%a%" order by id desc limit 9086,1&lt;br /&gt;11c11&lt;br /&gt;&amp;lt; Bytes_sent    297&lt;br /&gt;---&lt;br /&gt;&amp;gt; Bytes_sent    299&lt;br /&gt;155c155&lt;br /&gt;&amp;lt; Connections   219&lt;br /&gt;---&lt;br /&gt;&amp;gt; Connections   220&lt;br /&gt;170c170&lt;br /&gt;&amp;lt; Handler_read_prev     18633&lt;br /&gt;---&lt;br /&gt;&amp;gt; Handler_read_prev     18634&lt;br /&gt;224c224&lt;br /&gt;&amp;lt; Key_read_requests     1630&lt;br /&gt;---&lt;br /&gt;&amp;gt; Key_read_requests     2064&lt;br /&gt;247c247&lt;br /&gt;&amp;lt; Queries       1779817&lt;br /&gt;---&lt;br /&gt;&amp;gt; Queries       1779824&lt;br /&gt;296c296&lt;br /&gt;&amp;lt; Uptime        1419010&lt;br /&gt;---&lt;br /&gt;&amp;gt; Uptime        1419015&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div&gt;其中t上有索引(id,t)。limit的偏移量小于9085，或者大于9086时看上去查询时间是和偏移量成正比的。&lt;br /&gt;不知道为什么会有一个跳跃，感觉可能是触发了某个开关，导致两者的查询方式有区别。不过从状态信息上没看出来。&lt;br /&gt;&lt;br /&gt;上面用的是5.1.40，换成5.1.41发现limit 9086,1变成0.12秒了，正常了一点，不过从change log上没有看上任何相关的东西。&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8153947485854055496?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8153947485854055496/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8153947485854055496' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8153947485854055496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8153947485854055496'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/12/blog-post.html' title='查询性能的跳跃'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1000873849036170095</id><published>2009-08-18T18:00:00.001+08:00</published><updated>2009-08-18T18:04:37.170+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>ext3 文件反删除</title><content type='html'>看到一个 ext3 上文件反删除的工具，尝试了一下，不过因为我服务器上的分区没有办法umount，所以没成功，不过看他写的&lt;a href="http://www.xs4all.nl/%7Ecarlo17/howto/undelete_ext3.html"&gt;帮助&lt;/a&gt;倒是对ext3的文件系统结构有了更深的了解。对于文件被删除而绝望的人可以自己试试。还有另一个工具，http://www.cgsecurity.org/wiki/TestDisk_Download，不过这个完全没有看了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1000873849036170095?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://code.google.com/p/ext3grep/' title='ext3 文件反删除'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1000873849036170095/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1000873849036170095' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1000873849036170095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1000873849036170095'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/08/ext3.html' title='ext3 文件反删除'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2206212214223515272</id><published>2009-08-18T17:58:00.001+08:00</published><updated>2009-08-18T18:00:07.666+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>ssd 读写性能</title><content type='html'>在某人的幻灯片上看到下面关于flash磁盘性能的一些总结，记录一下&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                Read B/W        Write B/W       Erase Lat.      Read Lat.       Cost per GB&lt;br /&gt;HDD             100 mb/s        150.00 mb/s                     5,000.00 us     $0.10&lt;br /&gt;NAND MLC        250 mb/s        70.00 mb/s      3.5 ms          85.00 us        $3.50&lt;br /&gt;NAND SLC        250 mb/s        170.00 mb/s     1.5 ms          75.00 us        $11.00&lt;br /&gt;NOR SLC         58 mb/s         0.13 mb/s       5,000.00 ms     0.27 us         $70.00&lt;br /&gt;DRAM            2,000 mb/s      2,000.00 mb/s                   0.08 us         $75.00&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2206212214223515272?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2206212214223515272/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2206212214223515272' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2206212214223515272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2206212214223515272'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/08/ssd.html' title='ssd 读写性能'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2244524814607304404</id><published>2009-03-23T00:03:00.002+08:00</published><updated>2009-03-23T00:09:56.432+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>erlang的匿名递归函数</title><content type='html'>&lt;pre&gt;&lt;br /&gt;spawn(&lt;br /&gt;  fun() -&gt;&lt;br /&gt;    F = fun(This, X) -&gt;&lt;br /&gt;      error_logger:error_msg("~p~n", [X]),&lt;br /&gt;      receive after 3000 -&gt; void end ,&lt;br /&gt;      This(This, X+1) end,&lt;br /&gt;    F(F, 0) end&lt;br /&gt;).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;比较绕，没有什么更直接的方法了。需要定义一个辅助函数，恩，自己体会吧，不知道该怎么解释。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2244524814607304404?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2244524814607304404/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2244524814607304404' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2244524814607304404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2244524814607304404'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/03/erlang.html' title='erlang的匿名递归函数'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5961319926748255050</id><published>2009-03-22T23:46:00.003+08:00</published><updated>2009-03-23T00:01:18.372+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>flash socket的授权</title><content type='html'>这两天看了下flash的编程。我现在似乎对socket的部分兴趣更大一些，以前都是对动画感兴趣，因为比较炫。后来大概是觉得对图像没天份，还是老老实实的做系统比较好。&lt;br /&gt;&lt;br /&gt;下了一个两三年前的开源程序，但就是运行不起来，说是没有许可连接。网上可以收到不少文章，说是加一个crossdomain.xml的策略文件就可以了。但尝试了很久都不行，再深入搜索才知道原来是在去年8月的flash 9的某个版本中做了调整，之前看的文章都太旧了。新的规则是用socket连接不能使用http上的策略文件了，必须要使用xmlsocket发送策略文件的内容。xmlsocket的端口在1024以下的，策略文件可以开放所有端口，否则只能开发1024以上的端口。使用&lt;pre&gt;security.loadPolicyFile("xmlsocket://192.168.1.1:843");&lt;/pre&gt;加载策略文件。&lt;br /&gt;&lt;br /&gt;flash会向server发送&lt;pre&gt;&amp;lt;policy-file-request/&amp;gt;&lt;/pre&gt;并以\0结束，请求策略文件，server发送文件内容，同样以\0结尾。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE cross-domain-policy&lt;br /&gt;SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"&amp;gt;&lt;br /&gt;&amp;lt;cross-domain-policy&amp;gt;&lt;br /&gt;   &amp;lt;site-control permitted-cross-domain-policies="all"/&amp;gt;&lt;br /&gt;   &amp;lt;allow-access-from domain="*" to-ports="*" /&amp;gt;&lt;br /&gt;&amp;lt;/cross-domain-policy&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5961319926748255050?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5961319926748255050/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5961319926748255050' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5961319926748255050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5961319926748255050'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/03/flash-socket.html' title='flash socket的授权'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5618173269006558409</id><published>2009-02-02T01:28:00.002+08:00</published><updated>2009-02-02T01:51:31.690+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>还用不惯erlang</title><content type='html'>断断续续的看了几周erlang，然后用一天写了个聊天室的原型，再用一天写了web接口和网页的demo，不过第二天基本在看inets的文档和调js，接口倒是很简单。总得来说用erlang写东西还是挺方便的，和perl同年生的东西啊，虽然用的人不多，但库还是不少的。虽然看了本书，但还只是了解了几个很常用的。而且函数模块的命名有些很奇怪，总是会忘记名字是什么。现在对otp还不是很明白，书上内容太少了，仍然需要看文档才行。&lt;br /&gt;&lt;br /&gt;写程序有一些很不爽的地方，没有return语句，然后条件判断if和case里要把所有可能情况都写上，否则就会抛异常，搞得一个程序要是分支多一点就要拼命的缩进。因为用匹配很多，而两个匹配的处理可能只有一点差别，结果就要把相同的语句在每个匹配的分支好一遍，为这一两句写一个函数又觉得不值得，怎么看都不舒服。感觉不想写条件语句，不像其它语言中写if很随意的，不明原因。可能还没有体会到erlang的风格，需要多看看别人的代码。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5618173269006558409?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5618173269006558409/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5618173269006558409' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5618173269006558409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5618173269006558409'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/02/erlang.html' title='还用不惯erlang'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1846267632413623731</id><published>2009-02-02T01:10:00.003+08:00</published><updated>2009-02-02T01:27:27.211+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>跨域ajax请求</title><content type='html'>刚放假回来，今天一帮搞js的人居然都不在。要写一个跨域的ajax的请求，用的是jquery。它包含带了一些ajax方法，可是文档太不详细了，看到可以使用.getJSON请求异域的json文件，因为js文件可以跨域。文档里写jquery会自动执行一个回调函数，看了半天也没明白什么意思。还是google比较快。用getJSON请求时，jquery会自动在url上加两个参数，jsoncallback=XXXA和_=XXXB，后一个不知道有什么，反正问题解决了就没管了。请求的url返回的json文件应该有这样的内容：XXXA(json_struct)，如XXXA({"name":"w","channel":"chat123"})，jquery会把文本数据自动生成为js的数据结构，然后传给getJSON中指定的回调函数。jquery文档中只说明了客户端的部分，没有说服务器端输出的文件内容是特殊的。可能是json调用的协议吧，js用得少，完全不知道。如果json文件中的内容不符，则回调函数不会执行，.ajaxSuccess， .ajaxComplete，.ajaxXXX...事件好像都不会触发，没想到有什么办法分辨ajax访问还没有结束和文件内容出错。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1846267632413623731?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1846267632413623731/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1846267632413623731' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1846267632413623731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1846267632413623731'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/02/ajax.html' title='跨域ajax请求'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2346439273519229498</id><published>2009-01-11T00:07:00.003+08:00</published><updated>2009-01-16T09:33:57.633+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>erlang和haskell</title><content type='html'>3年前学haskell，完全是因为pugs是用haskell写的。之前为了用emacs看过一些lisp的东西，函数语言也不算完全陌生。但总觉用haskell写算法实现不错，真的要用它做一个可以用的东西还是有点不太实际，总的来说只是学着玩的。而同为函数语言，erlang原本是用于电信行业，至少看得到应用，让人觉得有了那么一点不是玩的意思。&lt;br /&gt;&lt;br /&gt;和haskell比起来，erlang的语法让人觉得有些别扭，看上去也不是那么清爽。小于等于用=&lt;，真是不习惯。列表，元组的括号成堆，还是少写些数据处理的程序比较好，否则近视又要加深了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2346439273519229498?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2346439273519229498/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2346439273519229498' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2346439273519229498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2346439273519229498'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/01/erlanghaskell.html' title='erlang和haskell'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8876221638433872900</id><published>2009-01-10T23:26:00.003+08:00</published><updated>2009-01-10T23:34:38.785+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>erlang学习</title><content type='html'>Erlang程序设计第8章的习题：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;start(N,M) -&gt;&lt;br /&gt;    statistics(wall_clock),&lt;br /&gt;    Pids = for(1,N,fun(_X) -&gt; spawn(fun get_msg/0) end),&lt;br /&gt;    for(1,M,fun(X)-&gt;send_msg(Pids, "message " ++ integer_to_list(X)) end),&lt;br /&gt;    {_,Time} = statistics(wall_clock),&lt;br /&gt;    io:format("take ~p seconds~n", [Time/1000]),&lt;br /&gt;    send_msg(Pids, stop),&lt;br /&gt;    ok.&lt;br /&gt;&lt;br /&gt;for(N,N,F) -&gt;&lt;br /&gt;    [F(N)];&lt;br /&gt;for(I,N,F) -&gt;&lt;br /&gt;    [F(I)|for(I+1,N,F)].&lt;br /&gt;&lt;br /&gt;get_msg() -&gt;&lt;br /&gt;    receive&lt;br /&gt;         stop -&gt;&lt;br /&gt;             void;&lt;br /&gt;         _Any -&gt;&lt;br /&gt;%            io:format("got ~p~n", [_Any]),&lt;br /&gt;             get_msg()&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;send_msg([Pid], Msg) -&gt; Pid!Msg;&lt;br /&gt;send_msg([Pid|Pids], Msg) -&gt;&lt;br /&gt;    Pid!Msg,&lt;br /&gt;    send_msg(Pids, Msg).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;在笔记本上跑start(1000,1000)要0.4秒，而在一台双CPU的服务器上居然要1.3秒。以为是linux上编译erlang时有优化参数没有设好。看README，注意到默认是打开SMP模拟器的，于是试着使用&lt;pre&gt;erl -smp disable&lt;/pre&gt;启动erl shell将smp模拟器关掉，结果CPU占用率从170%下降到100%，时间变成了0.3秒，看来模拟器的效率还不够好啊。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8876221638433872900?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8876221638433872900/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8876221638433872900' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8876221638433872900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8876221638433872900'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2009/01/erlang.html' title='erlang学习'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3784834968832390078</id><published>2008-12-25T14:47:00.005+08:00</published><updated>2008-12-25T15:04:19.942+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><title type='text'>Firefox 扩展开发初试</title><content type='html'>&lt;h3&gt;简述 &lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Firefox的扩展开发主要使用JavaScript。界面的制作用XUL，并且可以配合CSS使用。Mozilla的核心XPCOM——跨平台组件模型，提供了一套组件和类，用于诸如内存管理，线程，基本数据结构等，这些都可以在扩展中使用。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Firefox中有Chrome的概念。Chrome 指的是应用程序窗口的内容区域之外的用户界面元素的集合，这些用户界面元素包括工具条，菜单，进度条和窗口的标题栏等。Chrome 提供者能为特定的窗口类型（如浏览器窗口）提供 chrome。有三种基本的 chrome 提供者：&lt;br /&gt;&lt;br&gt; &lt;ul&gt;&lt;br /&gt;&lt;li&gt; 内容（Content）：通常是 XUL 文件。&lt;br /&gt;&lt;/li&gt; &lt;li&gt; 区域（Locale） ：存放本地化信息。&lt;br /&gt;&lt;/li&gt; &lt;li&gt; 皮肤（Skin）：描述 chrome 的外观。通常包含 CSS 和图像文件。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;开发环境 &lt;/h3&gt;&lt;br /&gt;有一些Firefox的扩展是专门为开发者提供的，使用它们可以使开发更加方便。为了不影响FF使用环境，我们可以用-P参数启动FF创建一个新的配置文件。然后安装下面的扩展：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://addons.mozilla.org/zh-CN/firefox/addon/216" target="_blank"&gt;JavaScript Debugger&lt;/a&gt;，做JS的调试&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://addons.mozilla.org/zh-CN/firefox/addon/7434" target="_blank"&gt;Extension Developer&lt;/a&gt;，一些开发工具&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://addons.mozilla.org/zh-CN/firefox/addon/1815" target="_blank"&gt;Console²&lt;/a&gt;，扩展的错误控制台&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://addons.mozilla.org/zh-CN/firefox/addon/4453" target="_blank"&gt;Chrome List&lt;/a&gt;，查看Chrome&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://addons.mozilla.org/zh-CN/firefox/addon/1843" target="_blank"&gt;Firebug&lt;/a&gt;，用于查看DOM&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br&gt;&lt;br /&gt;为了调试容易，还需要设置下面FF的环境参数，在地址栏中输入about:config，然后进行修改&lt;br /&gt;&lt;pre&gt;javascript.options.showInConsole = true //把 JavaScript 的出错信息显示在错误控制台&lt;br /&gt;nglayout.debug.disable_xul_cache = true //禁用 XUL 缓存，使得对窗口和对话框的修改不需要重新加载 XUL 文件&lt;br /&gt;browser.dom.window.dump.enabled  = true //允许使用 dump() 语句向标准控制台输出信息&lt;br /&gt;javascript.options.strict        = true //在错误控制台中启用严格的 JavaScript 警告信息&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;在 Windows 上，为了可以在js中使用 dump 调试，在FF启动时还需要增加启动参数 -console。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;扩展的目录结构 &lt;/h3&gt;&lt;br /&gt;FF的扩展都是以.xpi的文件形式发布，xpi文件实际上就是一个zip文件更改了后缀名。可以通过这个&lt;a href="http://ted.mielczarek.org/code/mozilla/extensionwiz/" target="_blank"&gt;Extension Wizard&lt;/a&gt;来生成一个目录结构。如下：&lt;br /&gt;&lt;pre&gt;exname&lt;br /&gt;|   build.sh             # 两个sh的脚本在windows下没有什么用处，可以直接删掉&lt;br /&gt;|   chrome.manifest      # Chrome 注册的清单文件&lt;br /&gt;|   config_build.sh&lt;br /&gt;|   install.rdf          # 扩展安装信息&lt;br /&gt;|   readme.txt&lt;br /&gt;|&lt;br /&gt;+---content&lt;br /&gt;|       firefoxOverlay.xul  # 覆盖的界面&lt;br /&gt;|       options.xul         # 选项设置的界面&lt;br /&gt;|       overlay.js          # 覆盖的程序&lt;br /&gt;|&lt;br /&gt;+---defaults&lt;br /&gt;|   \---preferences&lt;br /&gt;|           exname.js       # 选项的默认值&lt;br /&gt;|&lt;br /&gt;+---locale&lt;br /&gt;|   \---en-US               # 英语文件&lt;br /&gt;|           exname.dtd&lt;br /&gt;|           exname.properties&lt;br /&gt;|           prefwindow.dtd&lt;br /&gt;|&lt;br /&gt;\---skin&lt;br /&gt;        overlay.css         # 样式文件&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;其中除了chrome.manifest和install.rdf的文件名是固定的，其他文件的名字都随意的。content目录下一般存放扩展界面和程序文件。defaults/preferences下存放扩展选项的默认值文件，FF会自动读取这个目录下所有js的文件，所以文件名是任意的。locale下是各种语言文件，如果扩展支持多语言，那么每一种语言对应到locale下的一个子目录，子目录的名字是像en-US，zh-CN这样的语言代码。skin目录下存放CSS文件，图标之类的。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;把这个exname目录拷贝到FF扩展的目录下，一般是&lt;pre style="display: inline; color: blue;"&gt;C:\Documents and Settings\&amp;lt;用户名&amp;gt;\Application Data\Mozilla\Firefox\Profiles\&amp;lt;配置文件对应的子目录&amp;gt;\extensions&lt;/pre&gt;。然后把目录名由exname改为install.rdf中指定的扩展的ID，FF启动时会自动识别并加载这个新的扩展。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;对扩展做了修改之后，不需要重启FF，只要安装了Extension Developer，在Tools菜单中选择 &lt;pre style="display: inline; color: blue;"&gt;Extension Developer &amp;gt; Reload all Chrome&lt;/pre&gt; 就可以了。&lt;br /&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;下载示例中的扩展&lt;a href="http://jedywu.googlepages.com/contentfilter.xpi" target="_blank"&gt;Content Filter&lt;/a&gt;。这个扩展的功能是对匹配url的网页，查找所有的find并替换为replace。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;install.rdf &lt;/h3&gt;&lt;br /&gt;这个文件中是扩展的安装信息。&lt;br /&gt;如：&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" &lt;br /&gt; xmlns:em="http://www.mozilla.org/2004/em-rdf#"&amp;gt;&lt;br /&gt;  &amp;lt;Description about="urn:mozilla:install-manifest"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;em:id&amp;gt;contentfilter@adways.net&amp;lt;/em:id&amp;gt;&lt;br /&gt;    &amp;lt;em:name&amp;gt;Content Filter&amp;lt;/em:name&amp;gt;&lt;br /&gt;    &amp;lt;em:version&amp;gt;1.0&amp;lt;/em:version&amp;gt;&lt;br /&gt;    &amp;lt;em:creator&amp;gt;Jedy&amp;lt;/em:creator&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;em:homepageURL&amp;gt;http://my.homepage.net/&amp;lt;/em:homepageURL&amp;gt;&lt;br /&gt;    &amp;lt;em:description&amp;gt;Content Filter&amp;lt;/em:description&amp;gt;&lt;br /&gt;    &amp;lt;em:optionsURL&amp;gt;chrome://contentfilter/content/options.xul&amp;lt;/em:optionsURL&amp;gt;&lt;br /&gt;    &amp;lt;!-- em:iconURL&amp;gt;chrome://contentfilter/content/xxx.png&amp;lt;/em:iconURL--&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Firefox --&amp;gt;&lt;br /&gt;    &amp;lt;em:targetApplication&amp;gt;&lt;br /&gt;      &amp;lt;Description&amp;gt;&lt;br /&gt;        &amp;lt;em:id&amp;gt;{ec8030f7-c20a-464f-9b0e-13a3a9e97384}&amp;lt;/em:id&amp;gt;&lt;br /&gt;        &amp;lt;em:minVersion&amp;gt;3.0&amp;lt;/em:minVersion&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;em:maxVersion&amp;gt;3.0.*&amp;lt;/em:maxVersion&amp;gt;&lt;br /&gt;      &amp;lt;/Description&amp;gt;&lt;br /&gt;    &amp;lt;/em:targetApplication&amp;gt;&lt;br /&gt;  &amp;lt;/Description&amp;gt;&lt;br /&gt;&amp;lt;/RDF&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;这个文件里需要设置扩展的id，这也是扩展的目录名。设置了optionsURL的话，就可以在FF的扩展列表中使用选项按钮打开这里设置的选项界面。&lt;pre style="display: inline; color: blue;"&gt;{ec8030f7-c20a-464f-9b0e-13a3a9e97384}&lt;/pre&gt;是Firefox的id，不用更改的，如果扩展还支持Thundbird等其他的Mozilla程序，那么这里会有另一段targetApplication的信息，这会使用其他程序的id。minVersion和maxVersion设置了扩展适合的程序版本，FF的扩展兼容性检查就是查这里的信息。所以如果有的扩展在FF升级后没有升级，结果不能通过兼容性检查，那么可以自己把xpi文件下载下来后改一下maxVersion之后再安装，有不少情况都是可以直接用的。&lt;br /&gt;&lt;h3&gt;chrome.manifest &lt;/h3&gt;&lt;br /&gt;这个内容如下：&lt;br /&gt;&lt;pre&gt;content   contentfilter   content/&lt;br /&gt;overlay   chrome://browser/content/browser.xul   chrome://contentfilter/content/overlay.xul&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;content行告诉FF可以在content/目录下找到contentfilter的content文件，设置的目录路径是相对于chrome.manifest所在目录的路径。overlay行设置了对浏览器的覆盖文件。这里还可以设置skin，locale的目录等。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Mozilla通过overlay的方式使扩展可以直接更改浏览器的界面，比如可以在菜单栏上增加一组菜单，可以在状态栏上增加图标等。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;overlay&lt;/h3&gt;&lt;br /&gt;通过overlay，在FF的tools菜单上增加了一个菜单项：&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;overlay id="contentfilter-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&amp;gt;&lt;br /&gt;   &amp;lt;script type="application/x-javascript;version=1.7" src="overlay.js" /&amp;gt;&lt;br /&gt;   &lt;br /&gt;   &amp;lt;menupopup id="menu_ToolsPopup"&amp;gt;&lt;br /&gt;       &amp;lt;menuitem id="contentfilter-open" label="Content Filter..." insertafter="prefSep" oncommand="contentFilter.openConfig()" /&amp;gt;&lt;br /&gt;   &amp;lt;/menupopup&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/overlay&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;扩展使用XUL来描述界面。XUL文件实际上就是一个XML文件，其中可以使用JS和CSS定义行为和样式。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;上面的文件中，id为menu_ToolsPopup的menupopup就是FF中工具菜单，menuitem这句在菜单中插入了一个“Content Filter...”的菜单项，插入的位置是在prefSep分隔之后，点击时执行contentFilter.openConfig函数。这里使用的各个FF中组件的id，在安装了Chrome List扩展之后，都可以通过工具菜单的&lt;pre style="display: inline; color: blue;"&gt;Explore Chrome...&lt;/pre&gt;，打开&lt;pre style="display: inline; color: blue;"&gt;browser/content/browser.xul&lt;/pre&gt;查到。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;XUL &lt;/h3&gt;&lt;br /&gt;写XUL和写HTML差不多，只是元素的名字不一样，格式上更严格一些。Mozilla的所有程序都是使用XUL描述界面的。它不仅用于扩展，还可以直接用于编写应用程序。有兴趣的可以看这些网站：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://xulplanet.com/references/elemref/" target="_blank"&gt;http://xulplanet.com/references/elemref/&lt;/a&gt;, XUL的手册，刚写扩展时要经常查阅&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://developer.mozilla.org/En/XUL_Tutorial" target="_blank"&gt;https://developer.mozilla.org/En/XUL_Tutorial&lt;/a&gt;, 一篇XUL入门教程&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="https://developer.mozilla.org/en/Getting_started_with_XULRunner"  target="_blank"&gt;https://developer.mozilla.org/en/Getting_started_with_XULRunner&lt;/a&gt;, 使用XUL开发应用程序&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;用XUL编写的程序需要XULRunner的运行环境，这跟java差不多。从FF3开始，FF中已经自带XULRunner，可以直接用Firefox的程序文件执行XUL的程序。如下载这个&lt;a href="https://developer.mozilla.org/samples/xulrunner/myapp.zip" target="_blank"&gt;例子&lt;/a&gt;，解压到一个目录中，然后运行&lt;pre style="display: inline; color: blue;"&gt;firefox.exe -app application.ini&lt;/pre&gt;就能执行这个程序。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;选项菜单 &lt;/h3&gt;&lt;br /&gt;在XUL中可以使用dialog标签创建一个选项对话框，如例子中的options.xul文件。&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&amp;gt;&lt;br /&gt;&amp;lt;dialog&lt;br /&gt;    id="contentfilter-configwindow"&lt;br /&gt;    title="Content Filter"&lt;br /&gt;    buttons="accept, cancel"&lt;br /&gt;    onload="init();"&lt;br /&gt;    ondialogaccept="save();"&lt;br /&gt;    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/dialog&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dialog的buttons属性定义了不同的按钮，onload属性定义了对话框在载入时执行的函数，ondialogaccept属性定义了点击accept按钮时执行的函数。因为是XML格式的文件，所以如果要直接在文件中写js的代码需要使用&lt;pre style="display: inline; color: blue;"&gt;&amp;lt;![CDATA[ ]]&amp;gt;&lt;/pre&gt;包含起来。options.xul中定义了一系列的js函数，这些都对应到一些点击或按键的动作。还可以使用js在操纵XML的DOM树，方法和HTML中是基本一致的。如：&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;script type="application/x-javascript;version=1.7"&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;function deletePattern() {&lt;br /&gt;   var list = document.getElementById("patternList");&lt;br /&gt;   var delItems = list.selectedItems;&lt;br /&gt;   for(var i = delItems.length - 1; i &amp;gt;= 0; i--)&lt;br /&gt;      list.removeChild(delItems[i]);&lt;br /&gt;}&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;listbox width="480px" id="patternList" seltype="multiple" onkeypress="pressDel(event);"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;在listbox上按键会触发pressDel函数，这个函数使用对象的removeChild方法移除DOM树中的一个子节点。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;扩展功能 &lt;/h3&gt;&lt;br /&gt;对于一个实用的扩展来说，通常只有一个选项对话框是不够的，还需要注册一些事件监听函数，或者菜单项提供一个事务处理的入口。见overlay.js：&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var contentFilter = {&lt;br /&gt;   init: function() {&lt;br /&gt;      var appcontent = document.getElementById("appcontent");&lt;br /&gt;      appcontent.addEventListener("DOMContentLoaded", contentFilter.filter, true);&lt;br /&gt;      contentFilter.patterns.loadAsRegex();&lt;br /&gt;   },&lt;br /&gt;&lt;br /&gt;   filter: function(aEvent) {&lt;br /&gt;      var doc = aEvent.originalTarget;&lt;br /&gt;      if (doc.nodeName != "#document") return;&lt;br /&gt;      var docElement = doc.documentElement;&lt;br /&gt;      var p = contentFilter.patterns.patternList;&lt;br /&gt;      for (var i = 0; i &amp;lt; p.url.length; i++) {&lt;br /&gt;         if(p.url[i].test(doc.location)) {&lt;br /&gt;            docElement.innerHTML = docElement.innerHTML.replace(p.find[i], p.replace[i]);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   },&lt;br /&gt;...&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;window.addEventListener("load", function() { contentFilter.init(); }, false);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;最后一行定义了一个window.load的监听器，当打开FF的窗口时触发。init函数的定义了页面加载时的监听器并调用了loadAsRegex方法载入配置。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;这里定义的contentFilter变量是处于当前窗口的命名空间下，并不是全局的变量，所以在选项对话框中并不能直接调用。因此在options.xul的save函数中&lt;br /&gt;&lt;pre&gt;var win= Components.classes["@mozilla.org/appshell/window-mediator;1"].&lt;br /&gt;   getService(Components.interfaces.nsIWindowMediator).getEnumerator("navigator:browser");&lt;br /&gt;while(win.hasMoreElements()) {&lt;br /&gt;   var browser = win.getNext();&lt;br /&gt;   browser.contentFilter.patterns.loadAsRegex();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;使用了getEnumerator得到所有的浏览器窗口，然后让每一个窗口中的contentFilter对象重新加载配置。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;配置 &lt;/h3&gt;&lt;br /&gt;扩展的默认配置参数可以在defaults/preferences目录下定义，如prefs.js：&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;pref("extensions.contentfilter.url", "baidu");&lt;br /&gt;pref("extensions.contentfilter.find", "hao123");&lt;br /&gt;pref("extensions.contentfilter.replace", "kaixin");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;可以在about:config中查找扩展的配置参数。一般命名的方法是extensions.&amp;lt;扩展名&amp;gt;.&amp;lt;参数名&amp;gt;，当没有定义用户的值时，FF会读取这些默认的值。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;在程序中可以使用&lt;br /&gt;&lt;pre&gt;var prefs = Components.classes["@mozilla.org/preferences-service;1"].&lt;br /&gt;   getService(Components.interfaces.nsIPrefService);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;得到配置树，然后在找到某个分支&lt;br /&gt;&lt;pre&gt;var branch = prefs.getBranch("extensions.contentfilter.");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;配置中有4个值的类型：布尔值，整值，字符串和复杂类型。取一个字符串值可以使用getCharPref，如：&lt;br /&gt;&lt;pre&gt;branch.getCharPref("name");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;这里就是取得extensions.contentfilter.name的值，要注意的是getBranch不会做解析，所以&lt;br /&gt;&lt;pre&gt;prefs.getBranch("extensions.contentfilter.na").getCharPref("me")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;也是取extensions.contentfilter.name的值，因此，一般在使用getBranch时，branch都是以.结尾的。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;发布 &lt;/h3&gt;&lt;br /&gt;讲整个扩展目录下的文件压缩为zip格式，install.rdf为第一层，不要包含扩展本身的目录，然后改后缀为xpi。将这个文件拖到FF中，就会弹出对话框询问是否要安装了。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;总结 &lt;/h3&gt;&lt;br /&gt;开发一个功能简单的扩展是很容易的。不过感觉官方的文档不够详细，或者组织的不是很好，想实现个功能很难找到应该怎么做，使用什么API，很多细节的地方不知道该怎么处理。可能要把所有文档浏览一遍才能比较顺手吧。新手可以多看看&lt;a href="https://developer.mozilla.org/en/Code_snippets" target="_blank"&gt;Code Snippets&lt;/a&gt;或其他人的扩展。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;参考链接 &lt;/h3&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/" target="_blank"&gt;http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt; &lt;a href="http://www.rietta.com/firefox/Tutorial/overview.html" target="_blank"&gt;http://www.rietta.com/firefox/Tutorial/overview.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt; &lt;a href="https://developer.mozilla.org/en/Extensions" target="_blank"&gt;https://developer.mozilla.org/en/Extensions&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt; &lt;a href="https://developer.mozilla.org/en/Creating_XPCOM_Components" target="_blank"&gt;https://developer.mozilla.org/en/Creating_XPCOM_Components&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt; &lt;a href="https://developer.mozilla.org/en/XPCOM_API_Reference" target="_blank"&gt;https://developer.mozilla.org/en/XPCOM_API_Reference&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3784834968832390078?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3784834968832390078/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3784834968832390078' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3784834968832390078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3784834968832390078'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/12/firefox.html' title='Firefox 扩展开发初试'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3678381567438495069</id><published>2008-11-03T09:24:00.004+08:00</published><updated>2008-11-03T09:32:03.778+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>cluster性能测试</title><content type='html'>&lt;h3&gt;测试环境 &lt;/h3&gt; &lt;dl&gt;&lt;dt&gt; 服务器 &lt;/dt&gt;&lt;dd&gt; 192.168.1.1，192.168.1.2，192.168.1.3，192.168.1.4，192.168.1.5 &lt;/dd&gt;&lt;dt&gt; CPU &lt;/dt&gt;&lt;dd&gt; 1～3为Intel(R) Pentium(R) D CPU 2.80GHz， 4、5为Intel(R) Xeon(R) 3040 1.86GHz  &lt;/dd&gt;&lt;dt&gt; 操作系统 &lt;/dt&gt;&lt;dd&gt; Centos 4.4 &lt;/dd&gt;&lt;dt&gt; Cluster版本 &lt;/dt&gt;&lt;dd&gt; 5.1.27-ndb-6.3.17-cluster-gpl-log &lt;span class="twikiLink"&gt;MySQL&lt;/span&gt; Cluster Server (GPL)  &lt;/dd&gt;&lt;dt&gt; 测试软件 &lt;/dt&gt;&lt;dd&gt; sysbench  &lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt; &lt;/p&gt;&lt;h3&gt;&lt;a name="Cluster结构"&gt;&lt;/a&gt; Cluster结构 &lt;/h3&gt; 192.168.1.1，192.168.1.2，192.168.1.3，192.168.1.4为data node，192.168.1.5为management node和sql node。192.168.1.4为第二台sql node，并运行sysbench。 &lt;p&gt; Cluster中NoOfReplicas设为2，即每行数据储存两次，到两台data node上。 &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h3&gt;&lt;a name="测试结果"&gt;&lt;/a&gt; 测试结果 &lt;/h3&gt;测试是使用sysbench的oltp测试模式进行的，它的测试查询以事 务为单位，一个事务中包含了联机事务处理中常见的读和写操作。测试表的行数为100万，对1到128个线程并发做了测试。其中Innodb的测试数据作为 比较。innodb设置了足够大的buffer_pool，能够把整张表缓存到内存里。Cluster的测试中，除了内存选项，其他都是默认配置，在一个 测试中出现错误没有完成，是因为资源的限制导致错误，只是查询失败，集群并没有出现问题。 &lt;p&gt; "2 data"的测试是使用2个data node的结果，NoOfReplicas同样是2，即两台数据节点中的内容完全相同。比较它和"4 data"的结果可以看出，虽然增加了节点，但由于增加了节点之间的通讯的消耗，查询的速度并没有提升反而下降。增加了节点的优势在于大并发量，当只有一 个sql node时，这个节点成为瓶颈，所以4个data node的优势没有表现出来。当使用两个sql node时，比较"2 data + 2 sql"和"4 data + 2 sql"就可看到使用更多的节点可以提高并发量。"4 data, disk"是使用硬盘的表格式测试，每个节点上表文件的大小为120M左右，用于缓存表内容的内存大小设置为64M，即表的内容不能完全缓存到内存中。这样在查询中需要硬盘的随机读写，使得查询的速度和并发量都有大幅下降。 &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;br /&gt;&lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 线程数 &lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; innodb &lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 2 data + 1 sql&lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 2 data + 2 sql &lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 4 data + 1 sql&lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 4 data + 2 sql &lt;/span&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top; color: rgb(0, 0, 0);" maxcols="0" bgcolor="#6b7f93" align="center" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; 4 data, disk &lt;/span&gt; &lt;/th&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 1 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 202.05 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 95.52 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 46.75 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 16.02 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0049 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0105 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0214 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0624 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 2 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 358.21 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 153.05 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 94.65 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 24.74 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0056 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0131 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0211 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0808 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 4 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 539.47 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 249.31 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 187.92 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 46.08 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0074 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.016 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0213 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0868 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 8 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 616.36 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 340.24 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 295.99 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 83.07 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.013 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0235 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.027 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0962 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 16 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 574.6 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 427.09 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 404.7 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 94.71 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0278 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0374 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0395 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.1688 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 32 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 538.16 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 431.75 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 413.09 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 421.8 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 491.55 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 97.42 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0594 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0741 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0774 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.0758 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.065 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.3281 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 64 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 497.74 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 390.83 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 401.09 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 385.5 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 498.05 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; × &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.1285 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.1637 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.1595 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.166 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.1294 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; 每秒事务数 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#ffffff" valign="top"&gt; 128 &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 453.15 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 382.24 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;td style="vertical-align: top;" align="center" bgcolor="#ffffff" valign="top"&gt; 461.39 &lt;/td&gt;&lt;td rowspan="2" style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#ffffff" valign="top"&gt; - &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol twikiLast" bgcolor="#edf4f9" valign="top"&gt; 平均响应时间（秒） &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.2824 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.3348 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" align="center" bgcolor="#edf4f9" valign="top"&gt; 0.2782 &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 表中"-"代表没有进行测试，"×"代表测试中出现错误。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3678381567438495069?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3678381567438495069/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3678381567438495069' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3678381567438495069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3678381567438495069'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/11/cluster.html' title='cluster性能测试'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5334966116555774020</id><published>2008-10-21T16:40:00.003+08:00</published><updated>2008-10-21T16:47:34.845+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>cluster中增加或减少数据节点</title><content type='html'>增加或减少数据节点的数量和NoOfReplicas有关，一般来说NoOfReplicas是2，那么增加或减少的数量也应该是成对的，否则要设置另外的NoOfReplicas。增减节点时需要重启整个cluster，并使用某个备份进行恢复。使用cluster自己的备份机制，备份后每个数据节点上有一组备份的文件。恢复时需要对每一组文件运行一次ndb_restore，即原来的数据节点有多少个就运行多少次，不管增减后有多少个数据节点。其中-b始终是一样的，-n指定原来的node id。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5334966116555774020?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5334966116555774020/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5334966116555774020' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5334966116555774020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5334966116555774020'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/10/cluster.html' title='cluster中增加或减少数据节点'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2059926921669031114</id><published>2008-09-25T18:17:00.002+08:00</published><updated>2008-09-25T18:24:18.353+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Innodb_os_log_written</title><content type='html'>从 Innodb_os_log_written 可以知道 innodb 日志的写入量，从而判断 innodb_log_buffer_size 的大小是否合适，同时也可以估计出一个 log_file 大概能支持多长时间。innodb 当buffer满了，事务提交或每秒1次刷新，看哪个更早发生。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2059926921669031114?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2059926921669031114/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2059926921669031114' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2059926921669031114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2059926921669031114'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/09/innodboslogwritten.html' title='Innodb_os_log_written'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1101823984782075868</id><published>2008-09-24T09:44:00.005+08:00</published><updated>2008-11-18T13:38:35.566+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>query cache的存储方式</title><content type='html'>当查询进行时，如果设置了query cache，MySQL会把查询的结果保存在qc中。保存并不是在结果集完全得到的时候进行的，而是一边检索一边保存，MySQL每次会分配一块大小为query_cache_min_res_unit的内存用于保存结果集，当使用完之后再分配一块，所以如果结果集大于query_cache_min_res_unit会使得在一次查询中进行多次内存的分配。&lt;br /&gt;&lt;br /&gt;当最后一块分配的内存没有完全使用时，MySQL会把这块内存截断，并把没有使用的那部分归还以重复利用。但是当多个query同时进行时，可能归还的部分无法和空余的内存合成连续的块而造成这部分大小小于query_cache_min_res_unit无法再分配，这样出现了无法再使用的内存碎片。一个连续的同一类型的内存块称为block，包含使用的块，也包含未使用的块。&lt;br /&gt;&lt;br /&gt;Qcache_total_blocks 显示了所有的块数，而Qcache_free_blocks 反映了未使用的块数。如果Qcache_free_blocks很大，说明内存的碎片很多，内存的使用率会比较差，所以这时虽然Qcache_free_memory显示还有剩余的内存，也可能无法使用，当插入新的query时就需要清除旧的，使得Qcache_lowmem_prunes很高。可以使用flush query cache重整内存，操作之后Qcache_free_blocks应该为1，因为所有未使用的内存都放在一起作为连续的一块了。可以根据&lt;br /&gt;query的大小调整query_cache_min_res_unit以更好地利用内存。可以使用&lt;br /&gt;&lt;verbatim&gt;&lt;br /&gt;(query_cache_size - Qcache_free_memory）/ Qcache_queries_in_cache&lt;br /&gt;&lt;/verbatim&gt;&lt;br /&gt;计算query的平均大小。不过不是把query_cache_min_res_unit设得越小越好，因为频繁的分配内存会影响执行的速度。&lt;br /&gt;&lt;br /&gt;我不知道一个query会使用几个block，对于一个刚使用qc，发现每加入一个query，block增加了2，但在一个运行的服务器上看到Qcache_queries_in_cache*2和Qcache_total_blocks要相差不少。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1101823984782075868?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1101823984782075868/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1101823984782075868' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1101823984782075868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1101823984782075868'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/09/query-cache.html' title='query cache的存储方式'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1960361263525784932</id><published>2008-09-24T09:41:00.003+08:00</published><updated>2008-09-28T17:25:13.660+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>High Performance MySQL 2nd</title><content type='html'>最近在看这本书，感觉比第一版内容充实了不少，讲得也比较清晰，深入。所以虽然讲的大部分东西都知道了，还是看得很仔细。顺便把一些以前理解不完全的东西写下来，加深印象。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1960361263525784932?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1960361263525784932/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1960361263525784932' title='3 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1960361263525784932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1960361263525784932'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/09/high-performance-mysql-2nd.html' title='High Performance MySQL 2nd'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3015877833574690770</id><published>2008-09-24T09:26:00.003+08:00</published><updated>2008-10-15T16:55:24.369+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>使用load data infile时的字符集</title><content type='html'>在High Performance MySQL 2nd上看到，load data infile在某些MySQL的版本上不支持指定导入时的字符集。这时，MySQL假设导入文件的字符集是character_set_database，这个变量根据当前数据库指定的字符集而变化，如果没有指定当前数据库，那么它的值由character_set_server决定。因此如果load data infile不支持指定字符集，那么在导入前需要确认当前数据库的字符集，如果不符，则使用set character_set_database = ... 更改。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3015877833574690770?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3015877833574690770/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3015877833574690770' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3015877833574690770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3015877833574690770'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/09/load-data-infile.html' title='使用load data infile时的字符集'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1746957100755144359</id><published>2008-09-19T20:14:00.003+08:00</published><updated>2008-09-19T20:29:07.705+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>explain的误解</title><content type='html'>发现MySQL的explain还是很有迷惑性的。&lt;br /&gt;&lt;br /&gt;看下面两个sql的explain，(i,j)是tt的主键&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; explain select * from tt where i between 3 and 5 and j = 4\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;          id: 1&lt;br /&gt; select_type: SIMPLE&lt;br /&gt;       table: tt&lt;br /&gt;        type: range&lt;br /&gt;possible_keys: PRIMARY&lt;br /&gt;         key: PRIMARY&lt;br /&gt;     key_len: 8&lt;br /&gt;         ref: NULL&lt;br /&gt;        rows: 8&lt;br /&gt;       Extra: Using where; Using index&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; explain select * from tt where i &gt; 2 and i &lt; 6 and j = 4\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;           id: 1&lt;br /&gt;  select_type: SIMPLE&lt;br /&gt;        table: tt&lt;br /&gt;         type: range&lt;br /&gt;possible_keys: PRIMARY&lt;br /&gt;          key: PRIMARY&lt;br /&gt;      key_len: 4&lt;br /&gt;          ref: NULL&lt;br /&gt;         rows: 8&lt;br /&gt;        Extra: Using where; Using index&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;看上去如果使用了between，那么MySQL可以用的索引的两列。但仔细的研究了一下，发现实际并不是这样。between 3 and 5可以写为(i&gt;3 or i=3) and (i&lt;5 or i=5)，是这两个等号使用了两列，而大于和小于的判断仍然是index扫描，只用了一列。&lt;br /&gt;&lt;br /&gt;再看另一个&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; explain select * from tt where i in (3,4,5) and j=4\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;          id: 1&lt;br /&gt; select_type: SIMPLE&lt;br /&gt;       table: tt&lt;br /&gt;        type: range&lt;br /&gt;possible_keys: PRIMARY&lt;br /&gt;         key: PRIMARY&lt;br /&gt;     key_len: 8&lt;br /&gt;         ref: NULL&lt;br /&gt;        rows: 3&lt;br /&gt;       Extra: Using where; Using index&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这个才是真正用了两列，可以看到这里估计的行数是3，而刚才两个是8。用 show status 可以看得更清楚一些：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; show status like 'handler_read%';&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Variable_name         | Value |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Handler_read_first    | 0     |&lt;br /&gt;| Handler_read_key      | 0     |&lt;br /&gt;| Handler_read_next     | 0     |&lt;br /&gt;| Handler_read_prev     | 0     |&lt;br /&gt;| Handler_read_rnd      | 0     |&lt;br /&gt;| Handler_read_rnd_next | 0     |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;6 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from tt where i in (3,4,5) and j=4;&lt;br /&gt;+---+---+&lt;br /&gt;| i | j |&lt;br /&gt;+---+---+&lt;br /&gt;| 3 | 4 |&lt;br /&gt;+---+---+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; show status like 'handler_read%';&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Variable_name         | Value |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Handler_read_first    | 0     |&lt;br /&gt;| Handler_read_key      | 4     |&lt;br /&gt;| Handler_read_next     | 1     |&lt;br /&gt;| Handler_read_prev     | 0     |&lt;br /&gt;| Handler_read_rnd      | 0     |&lt;br /&gt;| Handler_read_rnd_next | 0     |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;6 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from tt where i between 3 and 5 and j = 4;&lt;br /&gt;+---+---+&lt;br /&gt;| i | j |&lt;br /&gt;+---+---+&lt;br /&gt;| 3 | 4 |&lt;br /&gt;+---+---+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; show status like 'handler_read%';&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Variable_name         | Value |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;| Handler_read_first    | 0     |&lt;br /&gt;| Handler_read_key      | 6     |&lt;br /&gt;| Handler_read_next     | 10    |&lt;br /&gt;| Handler_read_prev     | 0     |&lt;br /&gt;| Handler_read_rnd      | 0     |&lt;br /&gt;| Handler_read_rnd_next | 0     |&lt;br /&gt;+-----------------------+-------+&lt;br /&gt;6 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;后一个sql中有9次read_next_key，说明做了索引扫描。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1746957100755144359?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1746957100755144359/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1746957100755144359' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1746957100755144359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1746957100755144359'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/09/explain.html' title='explain的误解'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8671850168960322591</id><published>2008-06-14T09:27:00.000+08:00</published><updated>2009-01-16T09:33:35.209+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>如何编写MySQL的全文索引插件</title><content type='html'>&lt;h3&gt;说明 &lt;/h3&gt; 在MySQL5.1中可以为全文索引编写插件。插件的作用是代替MySQL内部的分词模块。 我们知道MySQL自带的分词只是通过空格和控制符将词分开，对于英语来说，可以通过这种方式分词，但中文是没有空格的，所以MySQL本身的全文索引不支持中文。 我们可以通过全文索引分词插件的方式让MySQL可以对中文分词，从而使得MySQL的全文索引支持中文。 &lt;p&gt; 设置了MySQL的插件之后，当我们插入或者更新在全文索引中的字段时，MySQL使用插件对字段进行分词。当对这个索引进行检索时，也需要使用插件对检索的关键字进行分词。 &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h3&gt;&lt;a name="安装"&gt;&lt;/a&gt; 安装 &lt;/h3&gt; &lt;p&gt; 需要从C或C++编写插件，编译为so文件。编译时需要定义MYSQL_DYNAMIC_PLUGIN。某些平台下的gcc可能还要加上-D_GNU_SOURCE，否则会报错。 &lt;/p&gt;&lt;pre&gt;gcc -fPIC -DMYSQL_DYNAMIC_PLUGIN -Wall -shared -I /usr/local/mysql-5.1.25/include/ \&lt;br /&gt; -I /usr/local/mysql-5.1.25-rc/include/ \&lt;br /&gt; -I /usr/local/mysql-5.1.25-rc/  \&lt;br /&gt; -o libthunder_ft.so thunder_ft.c&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 然后放在plugin_dir启动选项定义的目录下，默认是MySQL安装目录下的lib/plugin目录。然后使用 &lt;/p&gt;&lt;pre&gt;INSTALL PLUGIN plugin_name SONAME 'plugin_library'&lt;br /&gt;&lt;/pre&gt; 安装插件。 &lt;p&gt; 删除可以使用 &lt;/p&gt;&lt;pre&gt;UNINSTALL PLUGIN plugin_name&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 如果删除了一个全文索引插件，那么使用了这个插件的表将不可用，不能对该表做任何操作。 &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h3&gt;&lt;a name="代码"&gt;&lt;/a&gt; 代码 &lt;/h3&gt; &lt;p&gt; 每一个插件都要提供一个st_mysql_plugin结构 &lt;/p&gt;&lt;pre&gt;struct st_mysql_plugin&lt;br /&gt;{&lt;br /&gt; int type;             /* the plugin type (a MYSQL_XXX_PLUGIN value)   */&lt;br /&gt; void *info;           /* pointer to type-specific plugin descriptor   */&lt;br /&gt; const char *name;     /* plugin name                                  */&lt;br /&gt; const char *author;   /* plugin author (for SHOW PLUGINS)             */&lt;br /&gt; const char *descr;    /* general descriptive text (for SHOW PLUGINS ) */&lt;br /&gt; int license;          /* the plugin license (PLUGIN_LICENSE_XXX)      */&lt;br /&gt; int (*init)(void *);  /* the function to invoke when plugin is loaded */&lt;br /&gt; int (*deinit)(void *);/* the function to invoke when plugin is unloaded */&lt;br /&gt; unsigned int version; /* plugin version (for SHOW PLUGINS)            */&lt;br /&gt; struct st_mysql_show_var *status_vars;&lt;br /&gt; void * __reserved1;   /* placeholder for system variables             */&lt;br /&gt; void * __reserved2;   /* placeholder for config options               */&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; 用plugin.h中的宏mysql_declare_plugin定义，如： &lt;pre&gt;mysql_declare_plugin(thunder_ft)&lt;br /&gt;{&lt;br /&gt;       MYSQL_FTPARSER_PLUGIN,     /* type                            */&lt;br /&gt;       &amp;amp;thunder_ft_descriptor,    /* descriptor                      */&lt;br /&gt;       "thunder_ft",              /* name                            */&lt;br /&gt;       "Jedy",                    /* author                          */&lt;br /&gt;       "A fulltext plugin",       /* description                     */&lt;br /&gt;       PLUGIN_LICENSE_GPL,&lt;br /&gt;       thunder_ft_plugin_init,    /* init function (when loaded)     */&lt;br /&gt;       thunder_ft_plugin_deinit,  /* deinit function (when unloaded) */&lt;br /&gt;       0x0001,                    /* version                         */&lt;br /&gt;       thunder_status,            /* status variables                */&lt;br /&gt;       NULL,                      /* system variables                */&lt;br /&gt;       NULL&lt;br /&gt;}&lt;br /&gt;mysql_declare_plugin_end;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; init和deinit两个函数用于插件的初始化和卸载，在install，uninstall或者server启动停止时执行一次，我们可以用这两个函数分配和收回一些资源。 &lt;/p&gt;&lt;p&gt; status_vars是一个st_mysql_show_var结构，定义如下： &lt;/p&gt;&lt;pre&gt;struct st_mysql_show_var {&lt;br /&gt; const char *name;&lt;br /&gt; char *value;&lt;br /&gt; enum enum_mysql_show_type type;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; 其中value是一个char指针，MySQL会按照enum_mysql_show_type的类型将这个指针转为符合类型的指针。 的元素为 &lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; SHOW_BOOL &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; Pointer to a boolean variable &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; SHOW_INT &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; Pointer to an integer variable &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; SHOW_LONG &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; Pointer to a long integer variable &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; SHOW_LONGLONG &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; Pointer to a longlong integer variable &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; SHOW_CHAR &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; A string &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; SHOW_CHAR_PTR &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; Pointer to a string &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; SHOW_ARRAY &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; Pointer to another st_mysql_show_var array &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; SHOW_FUNC &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; Pointer to a function &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol twikiLast" bgcolor="#ffffff" valign="top"&gt; SHOW_UNDEF &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#ffffff" valign="top"&gt; undefined &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; status_vars指向一个结构数组，数组最后一行为{0,0,0}（有些编译器中要写为{0,0,SHOW_UNDEF}，否则会报错）代表数组结束。之前的每一行为一个状态值。 &lt;p&gt; 我们还需要申明一个st_mysql_ftparser结构： &lt;/p&gt;&lt;pre&gt;struct st_mysql_ftparser&lt;br /&gt;{&lt;br /&gt; int interface_version;&lt;br /&gt; int (*parse)(MYSQL_FTPARSER_PARAM *param);&lt;br /&gt; int (*init)(MYSQL_FTPARSER_PARAM *param);&lt;br /&gt; int (*deinit)(MYSQL_FTPARSER_PARAM *param);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; init是初始化函数，在每个使用到parser的语句之前调用，deinit在parser函数之后调用。 比如一次insert多行，init调用一次，然后调用多次parser进行分词，每一行都处理完成之后调用deinit。 例如： &lt;pre&gt;static struct st_mysql_ftparser thunder_ft_descriptor={&lt;br /&gt;   MYSQL_FTPARSER_INTERFACE_VERSION, /* interface version      */&lt;br /&gt;   thunder_ft_parse, /* parsing function       */&lt;br /&gt;   thunder_ft_init, /* parser init function   */&lt;br /&gt;   thunder_ft_deinit /* parser deinit function */&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 传给这三个函数的参数MYSQL_FTPARSER_PARAM定义如下： &lt;/p&gt;&lt;pre&gt;typedef struct st_mysql_ftparser_param&lt;br /&gt;{&lt;br /&gt; int (*mysql_parse)(struct st_mysql_ftparser_param *,&lt;br /&gt;                    char *doc, int doc_len);&lt;br /&gt; int (*mysql_add_word)(struct st_mysql_ftparser_param *,&lt;br /&gt;                       char *word, int word_len,&lt;br /&gt;                       MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);&lt;br /&gt; void *ftparser_state;&lt;br /&gt; void *mysql_ftparam;&lt;br /&gt; struct charset_info_st *cs;&lt;br /&gt; char *doc;&lt;br /&gt; int length;&lt;br /&gt; int flags;&lt;br /&gt; enum enum_ftparser_mode mode;&lt;br /&gt;} MYSQL_FTPARSER_PARAM;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 其中mysql_parse是MySQL内部parser的回调函数。mysql_add_word是分词后将词传给MySQL的函数。 ftparser_state用于给编写者保存一定的状态信息，可以是任何的指针。 cs是字符集的指针，可以由之得到传入文本的字符信息。doc是需要parser的文本指针，length是其长度。这里的doc不是以\0结尾的字符 串，所以一定要通过length处理。flags目前只有MYSQL_FTFLAGS_NEED_COPY这样一个非零值，告诉MySQL mysql_add_word添加的词需要进行拷贝，比如算法是每次parser把doc拷贝到一个buffer中处理，而返回这个buffer中词的指 针时需要设置MYSQL_FTFLAGS_NEED_COPY，因为buffer的值在处理过程中会变化的。mode用于区别是普通分词还是 boolean的分词。 &lt;/p&gt;&lt;p&gt; MYSQL_FTPARSER_FULL_BOOLEAN_INFO的分词只是用于解析boolean检索时的条件，建索引时始终使用的是MYSQL_FTPARSER_SIMPLE_MODE。 &lt;/p&gt;&lt;h3&gt;&lt;a name="MySQL函数"&gt;&lt;/a&gt; &lt;span class="twikiLink"&gt;MySQL&lt;/span&gt;函数 &lt;/h3&gt; &lt;p&gt;实现分词可以使用完全独立的函数也可以使用一些MySQL的函数。MySQL中提供了btree的实现，可以直接使用。另外MySQL分配和释放内 存也是使用了自己定义的函数my_malloc和my_free，它们的第二个参数说明了出错的处理，一般设为MYF(MY_WME)即可。 &lt;/p&gt;&lt;p&gt; 使用get_charset_by_csname可以返回一个charset_info_st结构的指针，三个参数分别为字符集名字的字串，类型和错误处理的flag。 &lt;/p&gt;&lt;p&gt;param-&gt;cs-&gt;cset-&gt;ctype(param-&gt;cs, &amp;amp;ctype, (uchar*) doc, (uchar*) end)返回对应param-&gt;cs字符集的一个字符的长度，ctype的值反映了一些这个字符种类的信息，比如字母，空格或控制符等。在utf8 字符集中汉字既是大写字母又是小写字母。 &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8671850168960322591?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8671850168960322591/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8671850168960322591' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8671850168960322591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8671850168960322591'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/06/mysql_14.html' title='如何编写MySQL的全文索引插件'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3208293996976401722</id><published>2008-06-13T14:32:00.003+08:00</published><updated>2008-06-15T22:35:05.759+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL全文检索插件</title><content type='html'>hightman实现了一个MySQL全文检索的插件。它只能使用在5.1.11-12，并且需要更改MySQL的源码，故对其做了一些修改，替换了一个MySQL后续版本中更改了的接口，去掉了一些不需要的功能。 &lt;p&gt; hightman的插件使用了自己的wordlist和stopword list，并使用正向最大匹配分词，新的插件对算法没有任何改变。插件只支持utf8，就是说用于建索引的字段的字符集必须为utf8。wordlist 中只有26万的词汇，可能分词不是很准确，因为我不太清楚好的分词是什么样子，所以也说不准。支持normal mode和boolean mode，不支持query expansion。分词的速度大概为65M的文本建索引需要85秒（没比较，不知道是快还是慢）。源码见最后的链接。 &lt;/p&gt;&lt;p&gt; 使用方法： &lt;/p&gt;&lt;p&gt; 1. 编译插件，MySQL必须是5.1.12版之后的版本，编译出来的so文件必须放在MySQL安装目录的lib/plugin目录下 &lt;/p&gt;&lt;pre&gt;shell&gt; gcc -DMYSQL_DYNAMIC_PLUGIN -Wall -shared \&lt;br /&gt;-I/usr/local/mysql/include \&lt;br /&gt;-I/usr/local/mysql-source/include \&lt;br /&gt;-I/usr/local/mysql-source \&lt;br /&gt;-o /usr/local/mysql/lib/plugin/libthunder_ft.so \&lt;br /&gt;thunder_ft.c&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 2. 拷贝wordlist，将附件中的wordlist和stopword两个文件放到/usr/local/mysql/share/mysql中 &lt;/p&gt;&lt;p&gt; 3. 进入mysql，安装插件 &lt;/p&gt;&lt;pre&gt;mysql&gt; install plugin thunder_ft soname 'libthunder_ft.so';&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 4. 建索引时增加 with parser thunder_ft 修饰 &lt;/p&gt;&lt;pre&gt;mysql&gt; alter table review add fulltext index i_title_content(title, content) with parser thunder_ft;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 5. 使用全文索引 &lt;/p&gt;&lt;pre&gt;mysql&gt; select * from review where match(title, content) against('+大显 +手机' in boolean mode);&lt;br /&gt;&lt;/pre&gt; 注意match中必须列出索引中的每一项。如果希望对title单独检索，则必须要为title这一列单独建一个索引。 &lt;p&gt; 6. 可以查看插件被调用了多少次用于分词 &lt;/p&gt;&lt;pre&gt;mysql&gt; show global status like 'thunder_ft_called';&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; 7. 因为要将wordlist放在内存中，所以这个插件会使用十几兆的内存。当不需要使用时，可以卸载。 &lt;/p&gt;&lt;pre&gt;mysql&gt; uninstall plugin thunder_ft;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jedywu.googlepages.com/thunder_ft.c"&gt;thunder_ft.c&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jedywu.googlepages.com/wordlist.tgz"&gt;wordlist&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3208293996976401722?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://hiei.yeax.com/archives_159.html' title='MySQL全文检索插件'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3208293996976401722/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3208293996976401722' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3208293996976401722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3208293996976401722'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/06/mysql.html' title='MySQL全文检索插件'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-9184927655055014362</id><published>2008-05-04T15:17:00.002+08:00</published><updated>2008-05-04T15:38:21.389+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>设置MySQL使用大内存页面</title><content type='html'>一般情况下使用的内存为每页4K，使用 &lt;a href="http://linux-mm.org/HugePages"&gt;huge page&lt;/a&gt; 的话默认是每页 2M。如果设置MySQL使用 huge page 至少有两个好处，一个是可以减少 Translation Lookaside Buffer (TLB) 失误以提高性能，另一个是利用 huge page不会swap的特性保证MySQL的内存不会被交换到swap中。&lt;br /&gt;MySQL 5.0.3之后在linux上支持huge page，可以使用 large-page 选项启动MySQL。&lt;br /&gt;当然还有一些相关的系统设置。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;echo 400 &gt; /proc/sys/vm/nr_hugepages&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这个指定总共huge page的页数，可以放到/etc/rc.local中。由于分配时需要有连续的内存空间，所以如果在运行了一段时间的系统上执行，可能无法分配到指定的数量，即使还有足够的内存。&lt;br /&gt;&lt;br /&gt;之后还需要设置内核参数kernel.shmmax和kernel.shmall，否则MySQL启动时会报22的错误&lt;br /&gt;&lt;pre&gt;InnoDB: HugeTLB: Warning: Failed to allocate 536887296 bytes. errno 22&lt;/pre&gt;&lt;br /&gt;shmmax是最大的共享内存段的大小，单位是字节，默认32M，肯定是不够的，这个应该比innodb_buffer_pool要大。shmall是共享内存的总大小，单位是页，默认2097152（8G）。可以使用sysctl -w或者在/etc/sysctl.conf中设置。&lt;br /&gt;&lt;br /&gt;除此还需要设max locked memory，使用ulimit -l或设置/etc/security/limits.conf，否则会报12的错误：&lt;br /&gt;&lt;pre&gt;Warning: Failed to allocate 31457280 bytes from HugeTLB memory. errno 12&lt;/pre&gt;&lt;br /&gt;MySQL启动之后可以使用&lt;pre&gt;grep Huge /proc/meminfo&lt;/pre&gt;查看huge page的使用情况。&lt;br /&gt;&lt;pre&gt;HugePages_Total:   400&lt;br /&gt;HugePages_Free:    128&lt;br /&gt;Hugepagesize:     2048 kB&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-9184927655055014362?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/9184927655055014362/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=9184927655055014362' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9184927655055014362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9184927655055014362'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/05/mysql.html' title='设置MySQL使用大内存页面'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4418281629174447436</id><published>2008-04-18T09:11:00.002+08:00</published><updated>2008-04-18T09:14:44.512+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>禁用一个用户</title><content type='html'>临时的禁用一个用户在MySQL中是不支持，不过还是有一些办法可以实现。&lt;br /&gt;MySQL是支持SSL连接的，可以设置希望禁用用户的SSL连接使得该用户无法再连上。&lt;br /&gt;比如把ssl_type从空字符串设为X509。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4418281629174447436?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4418281629174447436/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4418281629174447436' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4418281629174447436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4418281629174447436'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/04/blog-post_18.html' title='禁用一个用户'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2573445319547705639</id><published>2008-04-15T14:49:00.003+08:00</published><updated>2008-04-15T15:53:25.673+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>取随机记录</title><content type='html'>&lt;pre&gt;&lt;br /&gt;set @a:=N+1, @b:=-1;&lt;br /&gt;select * from t,&lt;br /&gt;  (select id from t &lt;br /&gt;     where if(rand()*(M - (@b:=@b+1)) &lt; @a, @a:=@a-1, 0)&lt;br /&gt;     limit 10&lt;br /&gt;  ) as tt &lt;br /&gt;where t.id = tt.id; &lt;/pre&gt;&lt;br /&gt;其中M是表的行数，这比order by rand() limit N将会快很多，而且应该是均匀随机的（感觉上是，懒的去证明了）。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DELIMITER $$&lt;br /&gt;&lt;br /&gt;DROP PROCEDURE IF EXISTS `test`.`rand_rows` $$&lt;br /&gt;CREATE PROCEDURE `test`.`rand_rows` (t varchar(64), id_col varchar(64), n int)&lt;br /&gt;BEGIN&lt;br /&gt;  set @rand_rows_i:=-1;&lt;br /&gt;  set @rand_rows_table_count:=0;&lt;br /&gt;  set @rand_rows_limit:=n+1;&lt;br /&gt;  set @rand_rows_sql := concat('select count(*) from ', t, ' into @rand_rows_table_count');&lt;br /&gt;  prepare st from @rand_rows_sql;&lt;br /&gt;  execute st;&lt;br /&gt;  deallocate prepare st;&lt;br /&gt;  set @rand_rows_sql := concat('select * from ', t, ' as t1, ',&lt;br /&gt;                '(select ', id_col,' from ', t,&lt;br /&gt;                ' where if(rand()*(', @rand_rows_table_count, ' - (@rand_rows_i:=@rand_rows_i+1)) &lt; @rand_rows_limit, @rand_rows_limit:=@rand_rows_limit-1, 0) limit ',&lt;br /&gt;                @rand_rows_limit - 1, ' ) as t2 ',&lt;br /&gt;                'where t1.', id_col,' = t2.', id_col);&lt;br /&gt;  prepare st from @rand_rows_sql;&lt;br /&gt;  execute st;&lt;br /&gt;  deallocate prepare st;&lt;br /&gt;  set @rand_rows_sql := null, @rand_rows_i := null, @rand_rows_table_count := null, @rand_rows_limit := null;&lt;br /&gt;END $$&lt;br /&gt;&lt;br /&gt;DELIMITER ;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2573445319547705639?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2573445319547705639/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2573445319547705639' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2573445319547705639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2573445319547705639'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/04/blog-post.html' title='取随机记录'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2076552658141480735</id><published>2008-04-10T09:15:00.003+08:00</published><updated>2008-07-09T09:14:20.517+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>replication的错误</title><content type='html'>昨天replication又出问题了。master上更改了max_allowed_packet，但slave上的忘记改了，结果导致master上过大的SQLslave不能取到。之后虽然在slave上也更改了max_allowed_packet，但start slave仍然不能成功。错误日志中的记录是：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;080409 18:37:31 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000251', position &lt;span style="color:red;"&gt;607694155&lt;/span&gt;&lt;br /&gt;080409 18:51:23 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.000251' at position &lt;span style="color:red;"&gt;605990219&lt;/span&gt;, relay log './mysql-relay-bin.001025' position: 89483173&lt;br /&gt;080409 18:51:23 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000251' position &lt;span style="color:red;"&gt;605990219&lt;/span&gt;&lt;br /&gt;080409 18:51:23 [Note] Slave I/O thread: connected to master 'replicate@192.168.1.169:3306',  replication started in log 'mysql-bin.000251' at position &lt;span style="color:red;"&gt;607694155&lt;/span&gt;&lt;br /&gt;080409 18:51:24 [ERROR] Error reading packet from server: log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master ( server_errno=1236)&lt;br /&gt;080409 18:51:24 [ERROR] Got fatal error 1236: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master' from master when reading data from binary log&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;注意红色的部分，605990219开始是一个长达18M的SQL，slave的sql thread执行到这一个sql出错了，不过不知道原因。而io thread读到了日志中的607694155。我们使用change master to应该是给sql thread设开始位置，所以用change master to把master_log_pos设为605990219，再运行start slave就可以了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2076552658141480735?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2076552658141480735/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2076552658141480735' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2076552658141480735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2076552658141480735'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/04/replication.html' title='replication的错误'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7923800007476209928</id><published>2008-03-30T22:46:00.001+08:00</published><updated>2008-03-30T23:02:54.960+08:00</updated><title type='text'>免费的flash图表</title><content type='html'>看这个：&lt;br /&gt;http://tutorialblog.org/free-chart-and-graph-solutions/&lt;br /&gt;&lt;div style="padding: 15px; float: none; font-size: 16px;" dragover="true" class="entry"&gt;      &lt;p dragover="true"&gt;Charts and graphs help the user to visualise data in a more meaningfull way than rows of text statistics. They are extensively used in reporting applications, for displaying earnings, website traffic etc - here we take a look at some pre-made scripts and frameworks available to the web designer or web application developer …&lt;/p&gt;  &lt;hr /&gt; &lt;p dragover="true"&gt;&lt;a dragover="true" href="http://teethgrinder.co.uk/open-flash-chart/"&gt; Open Flash Chart&lt;/a&gt; -  Open Flash Chart, is open source. It is free to use &lt;em dragover="true"&gt;and&lt;/em&gt; you get the source code to fiddle with&lt;/p&gt; &lt;p&gt;  &lt;a href="http://teethgrinder.co.uk/open-flash-chart/"&gt;&lt;img dragover="true" src="http://tutorialblog.org/wp-content/uploads/2008/01/114.jpg" alt="114.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p dragover="true"&gt;&lt;a href="http://www.amcharts.com/"&gt;amCharts&lt;/a&gt; - Pie and donut charts, line and area charts, column and bar charts, scatter and bubble charts and an interactive map tool are all free for download&lt;/p&gt; &lt;p&gt;  &lt;a href="http://www.amcharts.com/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/29.jpg" alt="29.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://www.maani.us/charts"&gt;Php / Swf Charts&lt;/a&gt; - PHP/SWF Charts is a simple, yet powerful PHP tool to create attractive web charts and graphs from dynamic data. Use PHP scripts to generate or gather the data from databases, then pass it to this tool to generate Flash (swf) charts and graphs. Any other scripting language (ASP, CFML, Perl, etc.) can be used with XML/SWF Charts (the XML version of the same tool.)&lt;/p&gt; &lt;p&gt;  &lt;a href="http://www.maani.us/charts"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/33.jpg" alt="33.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://www.fusioncharts.com/free/"&gt;Fusion Charts Free&lt;/a&gt; - FusionCharts Free is a flash charting component that can be used to render data-driven &amp;amp; animated charts for your web applications and presentations &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.fusioncharts.com/free/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/43.jpg" alt="43.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://developer.yahoo.com/yui/charts/"&gt;Yahoo! UI Library: Charts&lt;/a&gt; - The YUI Charts Control visualizes tabular data on a web page in several possible formats including vertical columns, horizontal bars, lines, and pies. Notable features include support for the DataSource Utility, customizable series and axes, a customizable mouse-over datatip, combination charts, and skinning&lt;/p&gt; &lt;p&gt;  &lt;a href="http://developer.yahoo.com/yui/charts/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/53.jpg" alt="53.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://code.google.com/p/flot/"&gt;Flot&lt;/a&gt; - Flot is a pure Javascript plotting library for jQuery. It produces graphical plots of arbitrary datasets on-the-fly client-side. The focus is on simple usage (all settings are optional), attractive looks and interactive features like zooming&lt;/p&gt; &lt;p&gt;  &lt;a href="http://code.google.com/p/flot/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/63.jpg" alt="63.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://grassegger.at/xperimente/charts-daten-semantik-css/"&gt;SAC&lt;/a&gt; - Simple accessible charts, An easy, fast and accessible way to display simple Data and beautify them with CSS. Works fine in FF, IE 7/6, Opera 9 tested on WIN XP&lt;/p&gt; &lt;p&gt;  &lt;a href="http://grassegger.at/xperimente/charts-daten-semantik-css/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/73.jpg" alt="73.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://simile.mit.edu/timeplot/"&gt;Similie&lt;/a&gt; - Timeplot is a DHTML-based AJAXy widget for plotting time series and overlay time-based events over them (with the same data formats that &lt;a href="http://simile.mit.edu/timeline/"&gt;Timeline&lt;/a&gt; supports)&lt;/p&gt; &lt;p&gt;  &lt;a href="http://simile.mit.edu/timeplot/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/82.jpg" alt="82.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://www.liquidx.net/plotkit/"&gt;PlotKit&lt;/a&gt; - PlotKit is a Chart and Graph Plotting Library for Javascript. It has support for HTML Canvas and also SVG via Adobe SVG Viewer and native browser support&lt;/p&gt; &lt;p&gt;  &lt;a href="http://www.liquidx.net/plotkit/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/92.jpg" alt="92.jpg" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;hr /&gt; &lt;p&gt;&lt;a href="http://naku.dohcrew.com/libchart/pages/introduction/"&gt;Libchart&lt;/a&gt; - Libchart is a free chart creation PHP library, that is easy to use&lt;/p&gt; &lt;p&gt;  &lt;a href="http://naku.dohcrew.com/libchart/pages/introduction/"&gt;&lt;img src="http://tutorialblog.org/wp-content/uploads/2008/01/102.jpg" alt="102.jpg" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7923800007476209928?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7923800007476209928/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7923800007476209928' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7923800007476209928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7923800007476209928'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/03/flash.html' title='免费的flash图表'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8231270183666986593</id><published>2008-03-27T10:19:00.000+08:00</published><updated>2008-03-27T10:22:42.744+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>max函数的缺陷</title><content type='html'>当使用enum或set类型时，order by是使用它们的内部整值来排序的，但是并不是所有的操作都是基于内部值得。max和min函数使用的是它们的字符串值来比较的，有点意外，不是吗？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8231270183666986593?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8231270183666986593/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8231270183666986593' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8231270183666986593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8231270183666986593'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/03/max.html' title='max函数的缺陷'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6979057213437308578</id><published>2008-03-05T18:07:00.000+08:00</published><updated>2008-03-05T18:08:07.703+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>查询返回的默认顺序</title><content type='html'>&lt;p&gt; 按照sql标准，select如果不加order by子句，返回结果的顺序是不可靠的。 &lt;/p&gt;&lt;p&gt; 如果你希望保证顺序，必须要加上order by子句。 &lt;/p&gt;&lt;p&gt; 见下面的例子： &lt;/p&gt;&lt;p&gt; innodb的情况 &lt;/p&gt;&lt;pre&gt;test@127.0.0.1&gt;CREATE TABLE t (&lt;br /&gt;   -&gt;   ID INT NOT NULL PRIMARY KEY,&lt;br /&gt;   -&gt;   PID INT,&lt;br /&gt;   -&gt;   FOREIGN KEY (PID) REFERENCES t(ID)&lt;br /&gt;   -&gt; ) ENGINE=INNODB;&lt;br /&gt;Query OK, 0 rows affected (0.06 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;INSERT INTO t VALUES (1, NULL);&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;INSERT INTO t VALUES (2, NULL);&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;select * from t;&lt;br /&gt;+----+------+&lt;br /&gt;| ID | PID  |&lt;br /&gt;+----+------+&lt;br /&gt;|  1 | NULL |&lt;br /&gt;|  2 | NULL |&lt;br /&gt;+----+------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;UPDATE t SET PID  = 2 WHERE ID = 1;&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;Rows matched: 1  Changed: 1  Warnings: 0&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;select * from t;&lt;br /&gt;+----+------+&lt;br /&gt;| ID | PID  |&lt;br /&gt;+----+------+&lt;br /&gt;|  2 | NULL |&lt;br /&gt;|  1 |    2 |&lt;br /&gt;+----+------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt; myisam的情况 &lt;/p&gt;&lt;pre&gt;test@127.0.0.1&gt;create table t (a int primary key, b int) engine=myisam;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;insert into t values (1,2),(2,3),(3,4);&lt;br /&gt;Query OK, 3 rows affected (0.00 sec)&lt;br /&gt;Records: 3  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;delete from t where a = 2;&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;insert into t values (4,5);&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;select * from t;&lt;br /&gt;+---+------+&lt;br /&gt;| a | b    |&lt;br /&gt;+---+------+&lt;br /&gt;| 1 |    2 |&lt;br /&gt;| 4 |    5 |&lt;br /&gt;| 3 |    4 |&lt;br /&gt;+---+------+&lt;br /&gt;3 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6979057213437308578?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6979057213437308578/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6979057213437308578' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6979057213437308578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6979057213437308578'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/03/blog-post.html' title='查询返回的默认顺序'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-13786184948684312</id><published>2008-02-27T20:47:00.002+08:00</published><updated>2008-02-27T20:51:59.424+08:00</updated><title type='text'>dev认证</title><content type='html'>上月通过了MySQL的dev认证，果然还是寄来了个飞镖，只是从十字镖换成了三角镖。MySQL从2月18日起提高了中国的认证考试价格，一个认证从100美元跳到了400美元。质的飞跃啊！严重影响了我们的培训计划，送考试券促销完全不可行了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-13786184948684312?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/13786184948684312/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=13786184948684312' title='3 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/13786184948684312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/13786184948684312'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/02/dev.html' title='dev认证'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2335320285845505688</id><published>2008-02-21T17:20:00.003+08:00</published><updated>2008-02-21T17:40:26.564+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>information_schema的插件</title><content type='html'>在MySQL5.1中可以自己编写information_schema的插件，用于得到一些服务器的内部信息，&lt;a href="http://dev.mysql.com/tech-resources/articles/mysql_i_s_plugins_part2.html"&gt;这里&lt;/a&gt;提供了一个简单的例子，是显示会话的savepoint的。虽然他说会增加显示临时表的插件，但我实在不想等了，于是也照葫芦画了一个。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql &gt;create temporary table a (a int); create temporary table b (b int); select * from information_schema.mysql_temporary;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;+--------------------+----------------------+---------------------+&lt;br /&gt;| TEMPORARY_TABLE_ID | TEMPORARY_TABLE_NAME | TEMPORARY_FILE_PATH |&lt;br /&gt;+--------------------+----------------------+---------------------+&lt;br /&gt;|                  1 | b                    | /tmp/#sql3ad0_1_1   |&lt;br /&gt;|                  2 | a                    | /tmp/#sql3ad0_1_0   |&lt;br /&gt;+--------------------+----------------------+---------------------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://jedywu.googlepages.com/mysql_is_temporary.cc"&gt;mysql_is_temporary.cc&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2335320285845505688?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://dev.mysql.com/tech-resources/articles/mysql_i_s_plugins_part2.html' title='information_schema的插件'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2335320285845505688/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2335320285845505688' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2335320285845505688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2335320285845505688'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/02/informationschema.html' title='information_schema的插件'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-759947682797188323</id><published>2008-02-02T16:16:00.000+08:00</published><updated>2008-02-02T16:24:33.933+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>不同语言使用MySQL的性能比较</title><content type='html'>应某人要求比较了用C（gcc 3.4.6），Java（1.6），Perl（5.8），PHP（4）连接数据库并处理查询的性能。 C使用的是MySQL的C API，JAVA使用的是MySQL的Connector/J，Perl使用的是DBD::mysql，PHP使用的是mysql库。&lt;br /&gt;&lt;br /&gt;比较了连接的速度，结果集很小的查询的速度（select 'a'）和结果集较大的查询的速度（select * from user limit 10000）。&lt;br /&gt;&lt;br /&gt;服务器配置为1G内存，CPU为Intel Xeon CPU 3040@1.86GHz（双核），操作系统为Centos4.5。&lt;br /&gt;&lt;br /&gt;测试结果&lt;br /&gt;&lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" href="http://twiki.shang.adways.net/twiki/bin/view/Technique/ConnectorCompare?sortcol=0;table=1;up=0#sorted_table" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;          &lt;/a&gt;&lt;br /&gt;&lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" href="http://twiki.shang.adways.net/twiki/bin/view/Technique/ConnectorCompare?sortcol=1;table=1;up=0#sorted_table" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt; C &lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" href="http://twiki.shang.adways.net/twiki/bin/view/Technique/ConnectorCompare?sortcol=2;table=1;up=0#sorted_table" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt; Java &lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" href="http://twiki.shang.adways.net/twiki/bin/view/Technique/ConnectorCompare?sortcol=3;table=1;up=0#sorted_table" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt; Perl &lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" href="http://twiki.shang.adways.net/twiki/bin/view/Technique/ConnectorCompare?sortcol=4;table=1;up=0#sorted_table" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt; PHP &lt;/a&gt; &lt;/th&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td dragover="true" rowspan="3" style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; connect (s) &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.159 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 4.936 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.541 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.263 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.186 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 4.933 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.540 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.262 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td dragover="true" style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.153 &lt;/td&gt;&lt;td dragover="true" style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 4.86 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.553 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.240 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td rowspan="3" style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; small resultset(s) &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.066 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.149 &lt;/td&gt;&lt;td dragover="true" style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.141 &lt;/td&gt;&lt;td dragover="true" style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.070 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.066 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.155 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.147 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 0.071 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.066 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.157 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.141 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 0.070 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td rowspan="2" style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; large resultset(s) &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 26.021 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 108.539 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 68.488 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 72.956 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 25.902 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 108.2 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 68.42 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 72.990 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#ffffff" valign="top"&gt; memory while large query(K) &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 1484 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 26684 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 5800 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 4960 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol" bgcolor="#edf4f9" valign="top"&gt; vm while large query(K) &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 5380 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 216028 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 12744 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#edf4f9" valign="top"&gt; 14796 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;td style="vertical-align: top;" class="twikiFirstCol twikiLast" bgcolor="#ffffff" valign="top"&gt; CPU while large query(%) &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#ffffff" valign="top"&gt; ~94 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#ffffff" valign="top"&gt; ~98 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#ffffff" valign="top"&gt; ~91 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#ffffff" valign="top"&gt; ～97 &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; Perl不用变量绑定fetch的方式，而使用fetchall_arrayref()的时间为约83秒，如果使用fetchall_arrayref({})得到hash ref的数组，则所用时间为225秒。&lt;/p&gt;&lt;p&gt;测试程序&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;b&gt;C：&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;#include "/usr/local/mysql/include/mysql.h"&lt;br /&gt;/* gcc -c -I/usr/include C.c &amp;&amp; gcc -o C C.o -lmysqlclient -lm -lz */&lt;br /&gt;struct timeval tv;&lt;br /&gt;MYSQL my_connection;&lt;br /&gt;MYSQL_RES *res_ptr;&lt;br /&gt;MYSQL_ROW sqlrow;&lt;br /&gt;int res;&lt;br /&gt;&lt;br /&gt;void conn(void);&lt;br /&gt;void selectshort(void);&lt;br /&gt;void selectlong(void);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc,char *argv)&lt;br /&gt;{&lt;br /&gt;  gettimeofday(&amp;tv, NULL);&lt;br /&gt;  double t1_u = tv.tv_usec;&lt;br /&gt;  double t1_s = tv.tv_sec;&lt;br /&gt;&lt;br /&gt;  mysql_init(&amp;my_connection);&lt;br /&gt;  conn();&lt;br /&gt;&lt;br /&gt;  int j=0;&lt;br /&gt;  for(j=0;j&lt;1000;j++)&lt;br /&gt; {&lt;br /&gt;   selectlong();&lt;br /&gt; }&lt;br /&gt;    &lt;br /&gt;  mysql_close(&amp;my_connection);&lt;br /&gt;&lt;br /&gt;  gettimeofday(&amp;tv, NULL);&lt;br /&gt;  double t2_u = tv.tv_usec;&lt;br /&gt;  double t2_s = tv.tv_sec;&lt;br /&gt;&lt;br /&gt;  double t1= t1_s + (t1_u / 1000000);&lt;br /&gt;  double t2= t2_s + (t2_u / 1000000);&lt;br /&gt;  printf(" %f seconds used. \n", (t2-t1));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void conn()&lt;br /&gt;{&lt;br /&gt;  mysql_init(&amp;my_connection);&lt;br /&gt;  mysql_real_connect(&amp;my_connection,"127.0.0.1","root","","test",0,NULL,CLIENT_FOUND_ROWS);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void selectshort()&lt;br /&gt;{&lt;br /&gt;  res = mysql_query(&amp;my_connection, "select 'a'");&lt;br /&gt;  if (res)&lt;br /&gt;    {&lt;br /&gt;   printf("SELECT error:%s\n",mysql_error(&amp;my_connection));&lt;br /&gt;    }&lt;br /&gt;  res_ptr=mysql_store_result(&amp;my_connection);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void selectlong()&lt;br /&gt;{&lt;br /&gt;  res = mysql_query(&amp;my_connection, "select * from user limit 10000");&lt;br /&gt;  if (res)&lt;br /&gt;    {&lt;br /&gt;   printf("SELECT error:%s\n",mysql_error(&amp;my_connection));&lt;br /&gt;    }&lt;br /&gt;  res_ptr=mysql_store_result(&amp;my_connection);&lt;br /&gt;  if(res_ptr)&lt;br /&gt;    {&lt;br /&gt;   //printf("Retrieved %lu Rows\n",(unsigned long)mysql_num_rows(res_ptr));&lt;br /&gt;   while((sqlrow=mysql_fetch_row(res_ptr)))&lt;br /&gt;        {&lt;br /&gt;    //printf("%s   %s   %s\n",sqlrow[0], sqlrow[1], sqlrow[2]);&lt;br /&gt;        }&lt;br /&gt;   if (mysql_errno(&amp;my_connection))&lt;br /&gt;        {&lt;br /&gt;    fprintf(stderr,"Retrive error:%s\n",mysql_error(&amp;my_connection));&lt;br /&gt;        }&lt;br /&gt; }&lt;br /&gt;  mysql_free_result(res_ptr);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Java：&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;import java.sql.*;&lt;br /&gt;&lt;br /&gt;public class J {&lt;br /&gt;    private static Connection conn;&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        try {&lt;br /&gt;            Class.forName("com.mysql.jdbc.Driver").newInstance();&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            System.out.println(ex);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        connect();&lt;br /&gt;        long stime = System.currentTimeMillis();&lt;br /&gt;        for (int i = 0; i &lt; 1000; i++) {&lt;br /&gt;            selectlong();&lt;br /&gt;        }&lt;br /&gt;        long etime = System.currentTimeMillis();&lt;br /&gt;        System.out.println("Jave used " + (etime - stime) / 1000.0&lt;br /&gt;                + " seconds.");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void connect() {&lt;br /&gt;        try {&lt;br /&gt;            conn = DriverManager&lt;br /&gt;                    .getConnection("jdbc:mysql://127.0.0.1/test?user=root&amp;password=");&lt;br /&gt;&lt;br /&gt;        } catch (SQLException ex) {&lt;br /&gt;            System.out.println("SQLException: " + ex.getMessage());&lt;br /&gt;            System.out.println("SQLState: " + ex.getSQLState());&lt;br /&gt;            System.out.println("VendorError: " + ex.getErrorCode());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void selectshort() {&lt;br /&gt;        Statement stmt = null;&lt;br /&gt;        ResultSet rs = null;&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            stmt = conn.createStatement();&lt;br /&gt;            rs = stmt.executeQuery("SELECT 'a'");&lt;br /&gt;            // while (rs.next()) {&lt;br /&gt;            // rs.getString(1);&lt;br /&gt;            // }&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            System.out.println(ex);&lt;br /&gt;        } finally {&lt;br /&gt;            if (rs != null) {&lt;br /&gt;                try {&lt;br /&gt;                    rs.close();&lt;br /&gt;                } catch (SQLException sqlEx) {&lt;br /&gt;                }&lt;br /&gt;                rs = null;&lt;br /&gt;            }&lt;br /&gt;            if (stmt != null) {&lt;br /&gt;                try {&lt;br /&gt;                    stmt.close();&lt;br /&gt;                } catch (SQLException sqlEx) {&lt;br /&gt;                }&lt;br /&gt;                stmt = null;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void selectlong() {&lt;br /&gt;        Statement stmt = null;&lt;br /&gt;        ResultSet rs = null;&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            stmt = conn.createStatement();&lt;br /&gt;            rs = stmt.executeQuery("SELECT * from user limit 10000");&lt;br /&gt;            int id, age;&lt;br /&gt;            String name, email, address;&lt;br /&gt;            Timestamp createTime;&lt;br /&gt;            while (rs.next()) {&lt;br /&gt;                id = rs.getInt(1);&lt;br /&gt;                name = rs.getString(2);&lt;br /&gt;                email = rs.getString(3);&lt;br /&gt;                address = rs.getString(4);&lt;br /&gt;                age = rs.getInt(5);&lt;br /&gt;                createTime = rs.getTimestamp(6);&lt;br /&gt;                // System.err.printf("%3d %-20s%-20s%-30s%3d\n", id, name,&lt;br /&gt;                // email, address, age);&lt;br /&gt;            }&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            System.out.println(ex);&lt;br /&gt;        } finally {&lt;br /&gt;            if (rs != null) {&lt;br /&gt;                try {&lt;br /&gt;                    rs.close();&lt;br /&gt;                } catch (SQLException sqlEx) {&lt;br /&gt;                }&lt;br /&gt;                rs = null;&lt;br /&gt;            }&lt;br /&gt;            if (stmt != null) {&lt;br /&gt;                try {&lt;br /&gt;                    stmt.close();&lt;br /&gt;                } catch (SQLException sqlEx) {&lt;br /&gt;                }&lt;br /&gt;                stmt = null;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Perl：&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;use DBI;&lt;br /&gt;use Time::HiRes qw/gettimeofday tv_interval/;&lt;br /&gt;&lt;br /&gt;our $dbh;&lt;br /&gt;my $stime = [gettimeofday];&lt;br /&gt;&lt;br /&gt;conn();&lt;br /&gt;for($i = 0; $i &lt; 1000; $i++) {&lt;br /&gt;    selectlong();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;my $elapsed = tv_interval($stime);&lt;br /&gt;print "Perl used $elapsed seconds.\n";&lt;br /&gt;&lt;br /&gt;sub conn {&lt;br /&gt;    $dbh = DBI-&gt;connect("dbi:mysql:host=127.0.0.1;database=test","root") or die "Can not connect.";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub selectshort {&lt;br /&gt;    my $sth = $dbh-&gt;prepare("select 'a'");&lt;br /&gt;    $sth-&gt;execute();&lt;br /&gt;#    my $re = $sth-&gt;fetchall_arrayref();&lt;br /&gt;#    print $re-&gt;[0][0],"\n";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub selectlong {&lt;br /&gt;    my $sth = $dbh-&gt;prepare("select * from user limit 10000");&lt;br /&gt;    $sth-&gt;execute();&lt;br /&gt;    my ($id, $name, $email, $address, $age, $create_time);&lt;br /&gt;    $sth-&gt;bind_columns(\$id, \$name, \$email, \$address, \$age, \$create_time);&lt;br /&gt;    while($sth-&gt;fetch){&lt;br /&gt;#        printf(STDERR "%3d %-20s%-20s%-30s%3d\n",$id, $name, $email, $address, $age);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub selectlong2 {&lt;br /&gt;    my $sth = $dbh-&gt;prepare("select * from user limit 10000");&lt;br /&gt;    $sth-&gt;execute();&lt;br /&gt;    my $re = $sth-&gt;fetchall_arrayref();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PHP：&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;?php &lt;br /&gt;$dbh=null; &lt;br /&gt;$time_start = microtime_float(); &lt;br /&gt;conn();&lt;br /&gt;for ($i = 0; $i &lt; 1000; ++$i) { &lt;br /&gt;    selectlong();&lt;br /&gt;} &lt;br /&gt;$time_end = microtime_float(); &lt;br /&gt;echo "PHP used ", $time_end - $time_start, " seconds\n"; &lt;br /&gt; &lt;br /&gt;function conn() { &lt;br /&gt;    global $dbh; &lt;br /&gt;    $dbh = mysql_connect("127.0.0.1", "root") or die("Can not connect."); &lt;br /&gt;    mysql_select_db("test", $dbh) or die("Can not connect."); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;function selectshort() { &lt;br /&gt;    global $dbh; &lt;br /&gt;    $re = mysql_query("select 'a'", $dbh); &lt;br /&gt;#    $row = mysql_fetch_array($re); &lt;br /&gt;#    echo $row[0], "\n"; &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;function selectlong() { &lt;br /&gt;    global $dbh; &lt;br /&gt;    $re = mysql_query("SELECT * from user limit 10000", $dbh); &lt;br /&gt;    while ($row = mysql_fetch_array($re)) { &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;function microtime_float(){ &lt;br /&gt;    list($usec, $sec) = explode(" ", microtime());&lt;br /&gt;    return ((float)$usec + (float)$sec);&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-759947682797188323?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/759947682797188323/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=759947682797188323' title='3 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/759947682797188323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/759947682797188323'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/02/cgcc-3.html' title='不同语言使用MySQL的性能比较'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8313329890604050168</id><published>2008-01-29T16:15:00.000+08:00</published><updated>2008-01-29T16:19:41.625+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>drbd性能测试</title><content type='html'>一直想做drbd的性能测试，但一直没有时间，其中等买千兆的网线还等了一个星期。拖拖拉拉弄了一个多月，终于有了结果。&lt;br /&gt;&lt;br /&gt;使用的drbd版本是0.7.24。&lt;br /&gt;拷贝一个612M的目录，所需时间如下： &lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;&lt;sub&gt;from&lt;/sub&gt;&lt;sup&gt;to&lt;/sup&gt;&lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;normal&lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;drbd&lt;/a&gt; &lt;/th&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; normal &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 25s &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 33s &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol twikiLast" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; drbd &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 28s &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 38s &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 拷贝10000个16K的文件 &lt;/p&gt;&lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;&lt;sub&gt;from&lt;/sub&gt;&lt;sup&gt;to&lt;/sup&gt;&lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;normal&lt;/a&gt; &lt;/th&gt;&lt;th style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;a rel="nofollow" style="color: rgb(255, 255, 255);" title="Sort by this column"&gt;drbd&lt;/a&gt; &lt;/th&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; normal &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 1.2s &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 3.5s &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol twikiLast" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; drbd &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 2.2s &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 3.4s &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 使用load data向数据库中导入500000条数据，文件大小为44M，单位秒。 &lt;/p&gt;&lt;table style="border-width: 1px;" class="twikiTable" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt;  &lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;&lt;/th&gt;&lt;th colspan="3" style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt;  innodb  &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;th colspan="3" style="text-align: center; vertical-align: top;" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt;  myisam  &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;/tr&gt; &lt;tr class="twikiTableOdd"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; drbd &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 10.24 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 11.37 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 9.26 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 5.43 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 5.53 &lt;/td&gt;&lt;td style="vertical-align: top;" bgcolor="#ffffff" valign="top"&gt; 5.32 &lt;/td&gt;&lt;/tr&gt; &lt;tr class="twikiTableEven"&gt;&lt;th style="text-align: center; vertical-align: top;" class="twikiFirstCol twikiLast" maxcols="0" align="center" bgcolor="#6b7f93" valign="top"&gt; &lt;span style="color: rgb(255, 255, 255);"&gt; &lt;strong&gt; normal &lt;/strong&gt; &lt;/span&gt; &lt;/th&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 9.24 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 9.90 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 8.27 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 5.24 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 5.22 &lt;/td&gt;&lt;td style="vertical-align: top;" class="twikiLast" bgcolor="#edf4f9" valign="top"&gt; 5.27 &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; 可以看到时间多了10%左右。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8313329890604050168?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8313329890604050168/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8313329890604050168' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8313329890604050168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8313329890604050168'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/01/drbd.html' title='drbd性能测试'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8695654312417597662</id><published>2008-01-17T13:14:00.000+08:00</published><updated>2008-01-17T13:34:40.114+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>explain的extended选项</title><content type='html'>&lt;div&gt;MySQL的explain命令有一个extended选项，我想可以很多人都没有注意，因为它对命令的输出结果没有任何改变，只是增加了一个warning。这个warning中显示了MySQL对SQL的解释，从这个解释中我们可以看到SQL的执行方式，对于分析SQL还是很有用的。&lt;/div&gt;&lt;br /&gt;&lt;div&gt;比如：&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt;explain extended select * from t where a in (select b from i);&lt;br /&gt;+----+--------------------+-------+------+&lt;br /&gt;| id | select_type        | table | type |&lt;br /&gt;+----+--------------------+-------+------+&lt;br /&gt;|  1 | PRIMARY            | t     | ALL  |&lt;br /&gt;|  2 | DEPENDENT SUBQUERY | i     | ALL  |&lt;br /&gt;+----+--------------------+-------+------+&lt;br /&gt;2 rows in set, 1 warning (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;子查询看起来和外部的查询没有任何关系，为什么MySQL显示的是DEPENDENT SUBQUERY，和外部相关的查询呢？从explain extended的结果我们就可以看出原因了。&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt;show warnings\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;Level: Note&lt;br /&gt;Code: 1003&lt;br /&gt;Message: select `test`.`t`.`a` AS `a`,`test`.`t`.`b` AS `b`,`test`.`t`.`c` AS `c`&lt;br /&gt;from `test`.`t` where&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;lt;in_optimizer&amp;gt;&lt;/span&gt;(`test`.`t`.`a`,&lt;br /&gt;&amp;lt;exists&amp;gt;(select 1 AS `Not_used` from `test`.`i`&lt;br /&gt;where (&amp;lt;cache&amp;gt;(`test`.`t`.`a`) = `test`.`i`.`b`)))&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;在这里MySQL改写了SQL，做了in的优化。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8695654312417597662?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8695654312417597662/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8695654312417597662' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8695654312417597662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8695654312417597662'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/01/explainextended.html' title='explain的extended选项'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1723666329271376101</id><published>2008-01-17T13:03:00.001+08:00</published><updated>2008-07-05T23:52:56.159+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>用连接改写子查询</title><content type='html'>由于在MySQL中对子查询的优化不如连接，所以通常连接的速度会比子查询快，我们可以通过把子查询改写成连接来优化查询。&lt;br /&gt;&lt;br /&gt;改写的方法可以见：&lt;a href="http://dev.mysql.com/doc/refman/4.1/en/rewriting-subqueries.html"&gt;http://dev.mysql.com/doc/refman/4.1/en/rewriting-subqueries.html&lt;/a&gt;&lt;br /&gt;因为5.0开始支持子查询，所以这一节在新的手册中被删除了，必须要看4.1的手册。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1723666329271376101?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1723666329271376101/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1723666329271376101' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1723666329271376101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1723666329271376101'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/01/blog-post.html' title='用连接改写子查询'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2844218286797892809</id><published>2008-01-04T15:41:00.000+08:00</published><updated>2008-01-04T15:50:22.459+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>soliddb</title><content type='html'>soliddb是一个第三方的MySQL存储引擎，看到它网站上的测试报告说soliddb的数据扩展性，CPU扩展性和事务响应时间都比innodb强。于是自己下载了做了一些测试，也希望以后能用。结果发现结果很不好，批量插入的速度是innodb的一半，一个简单的select count(*)也比innodb慢一倍。大致看了一遍手册，觉得性能相关的参数主要就是soliddb_durability_level和soliddb_cache_size。soliddb_durability_level设为1和3插入的时间好像没有什么变化，soliddb_cache_size设为500M，应该足够了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2844218286797892809?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2844218286797892809/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2844218286797892809' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2844218286797892809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2844218286797892809'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2008/01/soliddb.html' title='soliddb'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5038412350244693956</id><published>2007-12-19T10:00:00.001+08:00</published><updated>2008-03-21T14:11:10.032+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL的字符集错误</title><content type='html'>在使用字符集的时候有三个部分：&lt;br /&gt;&lt;p&gt;&lt;br /&gt;1. 服务器上使用的字符集，是我们在表定义时使用 default charset 指定的字符集&lt;br /&gt;&lt;br /&gt;2. 连接使用的字符集，一般用 set names 指定&lt;br /&gt;&lt;br /&gt;3. 客户端使用的字符集，插入记录时记录的字符集&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;如果不在乎汉字在数据库中怎么保存，那么只需要保证1，2一致，然后写入和读取的3都一样，在使用时就不会有乱码了，即使在数据库中保存的内容实际和指定的字符集不一样。这就是为什么默认都使用latin1的编码，但应用程序中不会出现问题。如果这时1和2不一样，MySQL会自动转码，可能会因为1的编码范围没有包含汉字的编码而导致乱码。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;如果希望数据库中的内容和指定的字符集一致，那么1中就要设成gbk或utf8以保证符合汉字的编码范围。然后2，3的字符集始终要保持一致，但写入和读出时使用的字符集可以不同。比如：&lt;br /&gt;表定义中使用gbk&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;CREATE TABLE `aa` (&lt;br /&gt;`a` varchar(20) DEFAULT NULL&lt;br /&gt;) ENGINE=MyISAM DEFAULT CHARSET=gbk&lt;/pre&gt;&lt;br /&gt;插入记录时使用utf8，MySQL会自动把utf8的字符转成gbk的字符后插入数据库。为了使插入记录是utf8编码的，这时需要把 term 的编码设成utf8。使用putty的话，在 change settings/Translation 中更改。&lt;br /&gt;&lt;pre&gt;mysql&gt; set names utf8;&lt;br /&gt;mysql&gt; insert into aa values ('你好');&lt;/pre&gt;&lt;br /&gt;然后当读出的时候，可是仍使用utf8，或者使用gbk：&lt;br /&gt;&lt;pre&gt;mysql&gt; set names gbk;&lt;br /&gt;mysql&gt; select * from aa;&lt;br /&gt;+------+&lt;br /&gt;| a    |&lt;br /&gt;+------+&lt;br /&gt;| 你好     |&lt;br /&gt;+------+&lt;br /&gt;1 rows in set (0.00 sec)&lt;/pre&gt;&lt;br /&gt;MySQL会以gbk输出内容，这时需要把 term 的编码改成gbk以正常显示。putty 中可以把显示字体改为中文字体，然后选择编码为 Use font encoding，以显示gbk的编码。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;如果在插入是2，3使用的字符集不一致，那么正常读取的时候就会出现乱码。比如现在 term 的编码是utf8。&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;mysql &gt;set names gbk;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt;insert into aa values ('明天');&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt;set names utf8;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt;select * from aa;&lt;br /&gt;+-----------+&lt;br /&gt;| a         |&lt;br /&gt;+-----------+&lt;br /&gt;| 你好      |&lt;br /&gt;| 鏄庡ぉ    |&lt;br /&gt;+-----------+&lt;br /&gt;2 rows in set (0.01 sec)&lt;/pre&gt;&lt;br /&gt;这时aa中的第二条记录在数据库中保存的是"明天"的utf8编码，所以如果用 set names utf8，MySQL在读取时会做一次gbk到utf8的转换导致乱码。如果 set names gbk，那么MySQL不会做编码转换，需要保存 term 的编码为utf8才能正常显示第二条记录，但第一条又会变成乱码：&lt;br /&gt;&lt;pre&gt;mysql &gt;select * from aa;&lt;br /&gt;+--------+&lt;br /&gt;| a      |&lt;br /&gt;+--------+&lt;br /&gt;| ▒▒▒       |&lt;br /&gt;| 明天   |&lt;br /&gt;+--------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;/pre&gt;&lt;br /&gt;我们可以使用下面的语句纠正编码&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql &gt;set names utf8;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql &gt;update aa set a = convert(convert(a using binary) using utf8) where a &lt;&gt; '你好';&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;Rows matched: 1  Changed: 1  Warnings: 0&lt;br /&gt;&lt;br /&gt;mysql &gt;select * from aa;&lt;br /&gt;+--------+&lt;br /&gt;| a      |&lt;br /&gt;+--------+&lt;br /&gt;| 你好   |&lt;br /&gt;| 明天   |&lt;br /&gt;+--------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; 同样的，如果原来使用的编码一直是latin1，之后想转成utf8，可以按照如下步骤： &lt;/p&gt;&lt;pre&gt;create table x (a varchar(10)) character set latin1;&lt;br /&gt;set names latin1;&lt;br /&gt;insert into x values ('你好');&lt;br /&gt;set names utf8;&lt;br /&gt;alter table x modify a varchar(10) character set utf8;&lt;br /&gt;update x set a = convert(convert(convert(a using latin1) using binary) using utf8);&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5038412350244693956?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mysqlperformanceblog.com/2007/12/18/fixing-column-encoding-mess-in-mysql/' title='MySQL的字符集错误'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5038412350244693956/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5038412350244693956' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5038412350244693956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5038412350244693956'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/12/mysql_19.html' title='MySQL的字符集错误'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2320036505202694068</id><published>2007-12-14T17:19:00.000+08:00</published><updated>2007-12-14T17:31:03.877+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>在MySQL中使用memcached</title><content type='html'>&lt;a href="http://tangent.org/"&gt;这里&lt;/a&gt;提供了一组MySQL的UDF函数，可以直接在SQL中操作memcached。安装比较简单，需要安装&lt;a href="http://download.tangent.org/libmemcached-0.12.tar.gz" title="Source"&gt;libmemcached-0.12.tar.gz&lt;/a&gt;，然后安装&lt;a href="http://download.tangent.org/memcached_functions_mysql-0.1.tar.gz" title="Source"&gt;memcached_functions_mysql-0.1.tar.gz&lt;/a&gt;就可以了。它的帮助文件中提供了使用方法。只是需要设置LD_LIBRARY_PATH，重启MySQL后，在定义函数时才能找到对应的so文件。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test@127.0.0.1&gt;select memc_set(2,10009);&lt;br /&gt;+-------------------+&lt;br /&gt;| memc_set(2,10009) |&lt;br /&gt;+-------------------+&lt;br /&gt;|                 0 |&lt;br /&gt;+-------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;select memc_get(2);&lt;br /&gt;+-------------+&lt;br /&gt;| memc_get(2) |&lt;br /&gt;+-------------+&lt;br /&gt;| 10009       |&lt;br /&gt;+-------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;test@127.0.0.1&gt;select benchmark(100000,memc_get(2));&lt;br /&gt;+-------------------------------+&lt;br /&gt;| benchmark(100000,memc_get(2)) |&lt;br /&gt;+-------------------------------+&lt;br /&gt;|                             0 |&lt;br /&gt;+-------------------------------+&lt;br /&gt;1 row in set (2.68 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;速度也还不错，perl读10000次需要2.x秒，这个快了不少。&lt;br /&gt;这样的话，如果有什么东西需要缓存到memcached中，那么可以直接用trigger实现缓存的插入和更新操作，写程序应该会方便很多。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2320036505202694068?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://tangent.org/' title='在MySQL中使用memcached'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2320036505202694068/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2320036505202694068' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2320036505202694068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2320036505202694068'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/12/mysqlmemcached.html' title='在MySQL中使用memcached'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6004081560284992506</id><published>2007-12-03T08:46:00.000+08:00</published><updated>2007-12-03T08:49:38.674+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL认证</title><content type='html'>通过了MySQL的DBA认证，还是挺容易的。今天证书终于寄到了，比较搞笑的是，居然还寄来了一个玩具十字镖。是建议DBA多多放松吗？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6004081560284992506?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6004081560284992506/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6004081560284992506' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6004081560284992506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6004081560284992506'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/12/mysql.html' title='MySQL认证'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3440766980281863579</id><published>2007-11-15T16:53:00.000+08:00</published><updated>2007-11-15T16:55:32.958+08:00</updated><title type='text'>EverNote限时免费</title><content type='html'>evernote是一个记笔记的软件，看了不少它的介绍，感觉还不错了，除了对中文的支持还不算完美。原价$49.95，但今天是免费的。&lt;br /&gt;http://www.giveawayoftheday.com/evernote/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3440766980281863579?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3440766980281863579/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3440766980281863579' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3440766980281863579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3440766980281863579'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/11/evernote.html' title='EverNote限时免费'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2828651933981854656</id><published>2007-11-11T00:26:00.000+08:00</published><updated>2007-11-11T00:33:05.427+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>为输出添加颜色</title><content type='html'>&lt;pre&gt;$str = "TAKE CARE";&lt;br /&gt;if(-t STDOUT){&lt;br /&gt;  print "\e[1;31m$str\e[0m\n";&lt;br /&gt;} else {&lt;br /&gt;  print "$str\n";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;-t 是判断输出是不是tty，如果是的则输出颜色信息，如果不是，比如在STDOUT被重定向到文件时则不加颜色信息。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2828651933981854656?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2828651933981854656/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2828651933981854656' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2828651933981854656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2828651933981854656'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/11/blog-post_11.html' title='为输出添加颜色'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7991822072719552951</id><published>2007-11-03T19:19:00.000+08:00</published><updated>2007-11-03T21:38:48.654+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>把中文按读音转成字母</title><content type='html'>因为在url中使用中文有时候会很麻烦，今天就遇到了。所以会想把中文转成拼音，这样就不会出现问题了，就像很多blog的程序生成文章的链接时会只取标题中的英文。很久以前就看到过这样一个模块，就是想不起来名字了，在CPAN找到半天，终于还是找到了：Text::Unidecode。&lt;pre&gt;&lt;br /&gt;use utf8;&lt;br /&gt;use Text::Unidecode;&lt;br /&gt;print unidecode("你好");&lt;br /&gt;&lt;br /&gt;# That prints: Ni Hao&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;虽然还有一些把汉字转成拼音的模块，也有比这个转得更好的，甚至还有声调，但这个强在日韩通吃（不过我没试过其他的到底支不支持日文和韩文）。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7991822072719552951?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7991822072719552951/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7991822072719552951' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7991822072719552951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7991822072719552951'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/11/blog-post.html' title='把中文按读音转成字母'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2641662664247972157</id><published>2007-10-18T12:09:00.000+08:00</published><updated>2007-10-18T12:11:02.091+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>使用Devel::Size查看变量占用内存</title><content type='html'>在“mastering perl”上看到一个有用的模块：Devel::Size。可以用来查看变量的大小，以后不用靠free来猜到底用了多少内存了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2641662664247972157?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2641662664247972157/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2641662664247972157' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2641662664247972157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2641662664247972157'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/10/develsize.html' title='使用Devel::Size查看变量占用内存'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1146446286231618269</id><published>2007-10-17T18:17:00.000+08:00</published><updated>2007-10-17T18:18:36.207+08:00</updated><title type='text'>Nerd</title><content type='html'>&lt;a href="http://www.nerdtests.com/nt2ref.html"&gt;&lt;br /&gt;&lt;img src="http://www.nerdtests.com/images/badge/nt2/1d68ae6c30155526.png" alt="NerdTests.com says I'm a Light-Weight Nerd.  What are you?  Click here!"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1146446286231618269?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1146446286231618269/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1146446286231618269' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1146446286231618269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1146446286231618269'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/10/nerd.html' title='Nerd'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7095649963817176427</id><published>2007-10-10T18:39:00.000+08:00</published><updated>2007-10-10T18:40:03.524+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>使用XML::Parser的乱码问题</title><content type='html'>目前使用XML::Parser解析XML文件的时候，它会把读入的字符设成utf8的（perl内部的utf8 flag设成on），可能导致之后的处理中出现乱码。可以把读出的字符用_utf8_off或encode转一遍去掉utf8 flag以解决乱码问题。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7095649963817176427?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7095649963817176427/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7095649963817176427' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7095649963817176427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7095649963817176427'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/10/xmlparser.html' title='使用XML::Parser的乱码问题'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4312747577998068462</id><published>2007-10-10T11:08:00.000+08:00</published><updated>2007-10-10T11:35:33.840+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>批量update</title><content type='html'>我们都知道在MySQL中批量insert的速度会比一条条insert快很多。类似的，update也应该是如此，但因为update的值往往因为条件的不同而不同，只能分开做。&lt;br /&gt;但是在下面的情况下，批量的update是可以做到的。&lt;br /&gt;1. 查询的条件中有主键或唯一键&lt;br /&gt;2. 查询的条件是等于，而不是范围。这实际上包含了1的情况&lt;br /&gt;&lt;br /&gt;在1的情况下，可以使用&lt;br /&gt;replace 或者 insert into ... values ... on duplicate key update ...&lt;br /&gt;两者都是在键重复的情况下自动的做更新，但需要注意的是，键不存在的时候会做insert操作。&lt;br /&gt;&lt;br /&gt;在2的情况下，可以建一张临时表，把要更新的值插入临时表，然后和需要更新的表连接做update&lt;br /&gt;如:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+-------------+------------------+------+-----+-------------------+&lt;br /&gt;| Field       | Type             | Null | Key | Default           |&lt;br /&gt;+-------------+------------------+------+-----+-------------------+&lt;br /&gt;| id          | int(11)          | NO   | PRI | NULL              |&lt;br /&gt;| name        | varchar(30)      | YES  |     | NULL              |&lt;br /&gt;| email       | varchar(40)      | YES  |     | NULL              |&lt;br /&gt;| address     | varchar(50)      | YES  |     | NULL              |&lt;br /&gt;| age         | int(10) unsigned | YES  |     | NULL              |&lt;br /&gt;| regist_time | timestamp        | NO   |     | CURRENT_TIMESTAMP |&lt;br /&gt;+-------------+------------------+------+-----+-------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;要按照id更新name&lt;br /&gt;两种方法分别为&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into user (id,name) values (?,?),(?,?) on duplicate key update name = values(name)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr width="250"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create temporary table tmp (id int primary key, n varchar(20));&lt;br /&gt;insert into tmp values (?,?),(?,?);&lt;br /&gt;update user, tmp set user.name = tmp.n where user.id = tmp.id;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这样当user的数据量是10万，更新2万的时候，包括必要的程序时间，一条条更新需要1.7秒，方法1需要0.30秒，方法2需要0.26秒。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4312747577998068462?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4312747577998068462/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4312747577998068462' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4312747577998068462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4312747577998068462'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/10/update.html' title='批量update'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-201570248551121802</id><published>2007-10-02T11:50:00.000+08:00</published><updated>2007-10-02T12:04:58.536+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>DBI</title><content type='html'>程序中一直用DBI的绑定，但是发现DBI做绑定的时候不管参数是数字还是字符都会当成字符，至少在MySQL中是如此。比如，age = ?，绑定20时，实际上的查询会是 age = '20'。因此MySQL在执行时需要做字符到数字的转换，对性能有一定的影响。&lt;br /&gt;如，&lt;blockquote&gt;select count(*) from user ignore key (age) where age = '45' &lt;/blockquote&gt;的查询时间为0.50秒，而&lt;blockquote&gt;select count(*) from user ignore key (age) where age = 45&lt;br /&gt;&lt;/blockquote&gt;只需要0.41秒，其中user中有100万数据。&lt;br /&gt;查看了一下DBI的文档，没有看到什么地方可以设置。&lt;br /&gt;不过发现了一些以前不曾用到的DBI的功能，不知道是一直没注意还是新版加的，DBI的更新还是挺频繁的。&lt;br /&gt;比如可以设置dbh的Profile属性，设置之后执行完会多一条时间的显示：&lt;br /&gt;&lt;blockquote&gt;DBI::Profile: 0.005288s (4 calls) test.pl @ 2007-10-02 12:01:09&lt;/blockquote&gt;另外还有TraceLevel属性，可以跟踪打印执行的sql。&lt;br /&gt;还有很多以前没用过的方法，过完节可以找人研究一下。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-201570248551121802?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/201570248551121802/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=201570248551121802' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/201570248551121802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/201570248551121802'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/10/dbi.html' title='DBI'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2273754711357021000</id><published>2007-09-20T09:01:00.000+08:00</published><updated>2007-09-20T09:10:21.953+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Commit database</title><content type='html'>在“Building Scalable Web Sites”这本书里看到一个概念：commit database。指用数据库记录版本控制系统的提交信息，以方便查询。对于SVN，有Kamikaze (&lt;a class="docLink" href="http://kamikaze-qscm.tigris.org/" target="_blank"&gt;http://kamikaze-qscm.tigris.org/&lt;/a&gt;)，它是用脚本将commit信息记录到MySQL中。目前还没有觉得有多大的用处，先记下来。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2273754711357021000?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2273754711357021000/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2273754711357021000' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2273754711357021000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2273754711357021000'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/commit-database.html' title='Commit database'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1769041528719483225</id><published>2007-09-14T10:58:00.000+08:00</published><updated>2007-09-14T11:03:22.424+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>innodb_support_xa</title><content type='html'>按文档上说支持XA的事务提交分成两步，会有两次写操作。这个选项默认是开的，如果没有用到XA事务，则可以关闭以提高性能。因为只是和提交有关，所以如果事务都比较大，那么性能改善不明显，如果事务较小，或者使用了autocommit，那么从测试的结果看性能能提高10%左右。&lt;br /&gt;另外还有一个选项innodb_flush_method，改成O_DIRECT在centos4.4上看不到明显效果，不过文档说这是和系统相关的，所以如果是其他的系统也可以试一试，但有性能下降的可能。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1769041528719483225?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1769041528719483225/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1769041528719483225' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1769041528719483225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1769041528719483225'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/innodbsupportxa.html' title='innodb_support_xa'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-871866610001587925</id><published>2007-09-13T11:07:00.000+08:00</published><updated>2007-09-13T11:58:42.292+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>read_rnd_buffer和sort_buffer</title><content type='html'>做了一个对这两个参数的测试。表有100万行，每行100左右。&lt;br /&gt;select * from test_table order by a;&lt;br /&gt;改sort_buffer_size的效果比较明显，改成256k时需要2分10秒，而是32M的时候只需要24秒。&lt;br /&gt;read_rnd_buffer是在使用行指针排序之后，随机读用的。&lt;br /&gt;把max_length_for_sort_data改成64，使得排序时不会读入整行，只用行指针排序，排序的时间缩短为7秒。但这时表实际上已经在内存中了，read_rnd_buffer应该没有起到多大的作用，修改之后时间都差不多。如果表的内容不在内存里，从硬盘读，就需要100万次随机读，等了将近10分钟，没有出来，于是放弃了。我想read_rnd_buffer_size可能能把1个小时的时间缩短成半个小时，但最终结果对于web运用仍然是不可接受的。因此read_rnd_buffer_size不需要设成很大的值。&lt;br /&gt;还有一个read_buffer，据说目前只是MyISAM表用到，直接改变量的值看不出明显的效果。MyISAM的表的内容是缓存在系统cache中的，除了重启不知道有什么办法清除，所以没有做更多的测试。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-871866610001587925?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/871866610001587925/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=871866610001587925' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/871866610001587925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/871866610001587925'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/readrndbuffersortbuffer.html' title='read_rnd_buffer和sort_buffer'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-8663274547983000540</id><published>2007-09-11T15:08:00.000+08:00</published><updated>2007-11-14T15:09:14.999+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>取分组中的特定记录</title><content type='html'>表test有三列(a,b,c)，100万条记录。(a,b)上有唯一索引，现在要查找对于每一个a，b的值最大的那条记录。有好几种方法。&lt;br /&gt;&lt;br /&gt;1. select * from (select * from test order by d desc) as t group by a;&lt;br /&gt;速度最快的，但只有MySQL可以用。&lt;br /&gt;&lt;br /&gt;2. select t1.* from test t1 left join test t2 on  t1.a = t2.a and t1.b &lt; t2.b where t2.b is null; 因为用了联接，查询的行数比较多，所以比较慢。a的选择率越低，速度越慢。 &lt;br /&gt;&lt;br /&gt;3. select * from test where (a,b) in (select a,max(b) from test group by a); 这个慢不是因为表扫描，而是因为对于test的每一行，select a,max(b) from test group by a都会做一遍，这个从profile的结果可以看出来，explain中select_type是DEPENDENT SUBQUERY应该是同样的意思。 &lt;div id="mb_1"&gt;所以先建一个临时表可以提高速度，&lt;br /&gt;select t1.* from test t1 , (select a,max(b) as b from test group by a) as t2 where t1.a = t2.a and t1.b = t2.b&lt;/div&gt;这种方法，a的选择性越高则越慢&lt;br /&gt;&lt;br /&gt;4. select * from test t1 where not exists (select * from test t2 where t1.a = t2.a and t1.b &lt; t2.b)&lt;br /&gt;和2差不多&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-8663274547983000540?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/8663274547983000540/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=8663274547983000540' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8663274547983000540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/8663274547983000540'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/blog-post.html' title='取分组中的特定记录'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-9099173344473438715</id><published>2007-09-05T11:22:00.001+08:00</published><updated>2009-04-17T16:22:42.241+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL的 select 和 sort 变量</title><content type='html'>总是会忘记 status 中 Select% 的那几个变量的具体含义，这次干脆写下来以便日后查询。&lt;br /&gt;主要有这9个变量。&lt;br /&gt;  1. Select_scan&lt;br /&gt;  2. Select_range&lt;br /&gt;  3. Select_full_join&lt;br /&gt;  4. Select_range_check&lt;br /&gt;  5. Select_full_range_join&lt;br /&gt;  6. Sort_scan&lt;br /&gt;  7. Sort_range&lt;br /&gt;  8. Sort_merge_passes&lt;br /&gt;  9. Sort_rows&lt;br /&gt;其中 Select_scan 和 Select_range 包括了单表查询和多表联接查询中的第一个表。Select_full_join, Select_range_check 和 Select_full_range_join 用于多表联接查询中的第二张及之后的表。Sort 的那几个变量则用于任何需要排序的查询。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Select_scan&lt;/span&gt;&lt;br /&gt;代表了需要做全表扫描。在 explain 中 type 会显示为 ALL，原因是查询没有能用到索引。因为全表扫描一般比较慢，所以应该尽量避免。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Select_range&lt;/span&gt;&lt;br /&gt;代表需要从硬盘读表在一段范围内的行。在 explain 中显示为 range，说明使用了索引查找记录在硬盘上的位置。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Select_full_join&lt;/span&gt;&lt;br /&gt;和 Select_scan 差不多，区别是 Select_full_join 代表的是第二张及之后的表。explain 中的类型也是 ALL，原因是表联接所用的字段上没有索引。它对性能有更为严重的影响，绝对要避免，所以用于联接的字段上一般都要加索引。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Select_range_check&lt;/span&gt;&lt;br /&gt;这个比 Select_full_join 要好一点，和 Select_range 差不多。区别是 MySQL 不能确定它是否能否使用一个范围来做联接。如果可以那么会使用范围，如果不行仍会使用全表扫描。在 explain 中 type 也会是 ALL，但 extra 中会有 Range checked for each record (index map: ) 的说明。不能肯定是否能用范围是因为联接是条件不确定。如：&lt;br /&gt;SELECT * FROM tbl1, tbl2 WHERE tbl1.col1 &gt; tbl2.col1&lt;br /&gt;如果 tbl2.col1 上有索引，那么可以做 Select_range_check，explain的结果如下&lt;br /&gt;&lt;pre&gt;   mysql&gt; EXPLAIN SELECT * FROM tbl1, tbl2 WHERE tbl1.col1 &gt; tbl2.col1;&lt;br /&gt;  +-------------+-------+------+---------------+------+---------+------+------+------------------------------------------------+&lt;br /&gt;  | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                          |&lt;br /&gt;  +-------------+-------+------+---------------+------+---------+------+------+------------------------------------------------+&lt;br /&gt;  | SIMPLE      | tbl1  | ALL  | NULL          | NULL | NULL    | NULL |   27 |                                                |&lt;br /&gt;  | SIMPLE      | tbl2  | ALL  | col1          | NULL | NULL    | NULL |   18 | Range checked for each record (index map: 0x1) |&lt;br /&gt;  +-------------+-------+------+---------------+------+---------+------+------+------------------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;  如果链接 tbl2 的时候 MySQL 判断可以使用范围查找，它仍然会增加 Select_range_check 而不是 Select_range。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Select_full_range_join&lt;/span&gt;&lt;br /&gt;和 Select_range_check 类似，不过 MySQL 可以肯定它能够使用范围查找。这时 explain 中的类型是 range。这也可能是有一些性能问题的。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sort_scan 和 Sort_range&lt;/span&gt;&lt;br /&gt;查询做排序，不论是因为 order by 还是 group by（除了使用了 order by NULL 的 group by），主要都是下面的三步：&lt;br /&gt; 1. 通过 where 条件找到记录&lt;br /&gt; 2. 排序&lt;br /&gt; 3. 按排好的顺序读取记录&lt;br /&gt;如果第二步不被跳过，那么第三步中就会有 Sort_scan 或 Sort_range。如果第一步是 Select_scan，那么第三步将是 Sort_scan，如果第一步是 Select_range，那么第三步会是 Sort_range。但 Sort_scan 和 Sort_range 其实没有功能上的区别，都是将需要的记录按顺序读出来，所以性能也是一样的。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sort_merge_passes&lt;/span&gt;&lt;br /&gt;Sort_merge_passes 包括两步。MySQL 首先会尝试在内存中做排序，使用的内存大小由系统变量 Sort_buffer_size 决定，如果它的大小不够把所有的记录都读到内存中，MySQL 就会把每次在内存中排序的结果存到临时文件中，等 MySQL 找到所有记录之后，再把临时文件中的记录做一次排序。这再次排序就会增加 Sort_merge_passes。实际上，MySQL 会用另一个临时文件来存再次排序的结果，所以通常会看到 Sort_merge_passes 增加的数值是建临时文件数的两倍。因为用到了临时文件，所以速度可能会比较慢，增加 Sort_buffer_size 会减少 Sort_merge_passes 和 创建临时文件的次数。但盲目的增加 Sort_buffer_size 并不一定能提高速度，见 &lt;a href="http://www.mysqlperformanceblog.com/2007/08/18/how-fast-can-you-sort-data-with-mysql/"&gt;How fast can you sort data with MySQL ?&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sort_row&lt;/span&gt;&lt;br /&gt;这代表了在第二步中被排序的记录的总数。因为 Sort_range 和 Sort_scan 是一样的，所以这个值只是说明了有多少记录被排序，意思不大。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-9099173344473438715?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://hackmysql.com/selectandsort' title='MySQL的 select 和 sort 变量'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/9099173344473438715/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=9099173344473438715' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9099173344473438715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9099173344473438715'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/mysql-select-sort.html' title='MySQL的 select 和 sort 变量'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1061985806207499237</id><published>2007-09-01T22:26:00.000+08:00</published><updated>2007-09-01T22:46:23.781+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>mysqltoolkit</title><content type='html'>mysqltoolkit是一组MySQL的命令行工具。&lt;br /&gt;包括11个小工具。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Visual Explain&lt;/span&gt;&lt;br /&gt;提供sql的树状explain结果，看得比较清楚。不过我觉得对于我来说用处不大，MySQL自己的结果我已经看得很习惯了。可能对初学者比较友好吧。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Query Profiler&lt;/span&gt;&lt;br /&gt;执行一系列sql，并显示status中的变化。分析sql的时候比较有用。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Show Grants&lt;/span&gt;&lt;br /&gt;将权限信息导出成sql。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Find&lt;/span&gt;&lt;br /&gt;根据行数，字段大小等很多条件找表，算是个有趣的工具吧。不过现在表最多也只有1000个左右，还有很多结构类似的，暂时还不需要用程序找。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Duplicate Key Checker&lt;/span&gt;&lt;br /&gt;检查重复的索引。&lt;br /&gt;简单的用了一下上面这几个。算不上很有用处的工具吧，不过当然比没有强。&lt;br /&gt;&lt;br /&gt;下面这些还没有机会试。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Archiver&lt;/span&gt;&lt;br /&gt;表存档。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Deadlock Logger&lt;/span&gt;&lt;br /&gt;可以记录死锁。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Slave Restart&lt;/span&gt;&lt;br /&gt;监视slave，如果出问题了，可以设置忽略某些错误自动重启。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Slave Delay&lt;/span&gt;&lt;br /&gt;保持slave有一定的延迟，让delete语句有反悔的机会吗？暂时没想到有什么用处。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Table Checksum&lt;/span&gt;&lt;br /&gt;检查表的数据是否一致。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MySQL Table Sync&lt;/span&gt;&lt;br /&gt;表同步，可以用于replication同步。replication数据不一致的时候，同步一下就好了，不用重建，也不需要很麻烦的对日志文件了。不过系统用了lvm之后，重建replication太简单了，搞得只要有问题就重建。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1061985806207499237?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mysqltoolkit.sourceforge.net/' title='mysqltoolkit'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1061985806207499237/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1061985806207499237' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1061985806207499237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1061985806207499237'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/09/mysqltoolkit.html' title='mysqltoolkit'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4453589898769023872</id><published>2007-08-28T18:51:00.000+08:00</published><updated>2007-08-28T18:58:59.913+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>group by是否应该使用索引</title><content type='html'>在MySQL的论坛上看到有人说“ Index slows down SELECT ... GROUP BY query”，追究下来才知道做group by有时不要索引更好。MySQL为此在5.0.40和5.1.17中追加了新的语法。&lt;br /&gt;&lt;blockquote&gt;5.0.40 ignore key for join (idxname)&lt;br /&gt;5.1.17 ignore key for join |order by | group by(idxname)&lt;br /&gt;&lt;/blockquote&gt;如果没有指定for语句，则是所有的情况都忽略索引。&lt;br /&gt;而使用索引变慢的原因是，做统计的列不在索引中，所以需要通过索引读每一行，这样行数多的时候会产生很多的随机读，其速度还不如按顺序读整表之后再group。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4453589898769023872?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4453589898769023872/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4453589898769023872' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4453589898769023872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4453589898769023872'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/08/group-by.html' title='group by是否应该使用索引'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5031051661399922162</id><published>2007-08-20T08:31:00.000+08:00</published><updated>2007-08-20T08:53:43.864+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>原来show status也可以用where的</title><content type='html'>看到文档上只说show statue like，一直以为只能用like，于是看两个变量名差得比较远的就很不方便了。今天看到有人说用where也可以，果然如此，为什么自己没有试一试呢。写法如下：&lt;br /&gt;show global status where variable_name like "com_%";&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5031051661399922162?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5031051661399922162/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5031051661399922162' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5031051661399922162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5031051661399922162'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/08/show-statuswhere.html' title='原来show status也可以用where的'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-9158207586243154843</id><published>2007-07-31T14:52:00.000+08:00</published><updated>2007-07-31T14:54:54.699+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>db字段过长</title><content type='html'>DBI报错&lt;blockquote&gt;Data in column 5 has been truncated to 32700 bytes. A maximum of 37556 bytes are  available at /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/DBI.pm line  1981&lt;/blockquote&gt;原因是字段太长了被截断了，可以在db连接的参数中加入LongReadLen指定最大的长度。如:&lt;br /&gt;DBI-&gt;connect('xxx','root','',{LongReadLen =&gt; 8 * 1024 * 1024})&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-9158207586243154843?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/9158207586243154843/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=9158207586243154843' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9158207586243154843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9158207586243154843'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/07/db.html' title='db字段过长'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3450361663911049375</id><published>2007-06-25T17:32:00.000+08:00</published><updated>2007-06-25T17:37:25.258+08:00</updated><title type='text'>神奇</title><content type='html'>网上下了一个digg的幻灯片，因为用的是openoffice的格式，机器上没有装，又懒得去下载了。搜到sharepoint可以播放这种格式的，就注册了个用户上传上去了。没想到就开始一直收到sharepoint的邮件通知说幻灯被人收藏了，随后还在delicious的hotlist中看到。看来sharepoint的访问量应该挺大，或许可以利用它来增加流量。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3450361663911049375?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3450361663911049375/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3450361663911049375' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3450361663911049375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3450361663911049375'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/06/blog-post_25.html' title='神奇'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1396512876075380984</id><published>2007-06-23T17:04:00.000+08:00</published><updated>2007-06-23T17:05:43.454+08:00</updated><title type='text'>日本</title><content type='html'>又来到日本了，最高兴的应该是没有某盾的阻挠，又可以直接访问blogspot了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1396512876075380984?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1396512876075380984/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1396512876075380984' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1396512876075380984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1396512876075380984'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/06/blog-post.html' title='日本'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4686948545053089113</id><published>2007-06-13T10:50:00.000+08:00</published><updated>2007-06-13T10:52:08.967+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>mysql 字符集</title><content type='html'>mysql在建表的时候可以指定字符集和校对规则。校对规则有三种形式的结尾，_ci 代表了大小写不敏感，_cs是大小写敏感，_bin是二进制，也是大小写敏感的。&lt;br /&gt;默认的校对规则是大小写不敏感的，所以如何我们建了这样一张表：&lt;br /&gt;&lt;pre&gt;create table t (n varchar(10)) default charset=latin1;&lt;br /&gt;insert into t values('w'), ('W');&lt;/pre&gt;&lt;br /&gt;然后查询&lt;br /&gt;&lt;pre&gt;select * from t where n = 'w';&lt;/pre&gt;&lt;br /&gt;将会返回两条记录。&lt;br /&gt;如果我们需要大小写敏感的查询，可以临时改变其校对规则：&lt;br /&gt;&lt;pre&gt;select * from t where n collate latin1_general_cs = 'w';&lt;/pre&gt;这样将只有一条记录返回，但是如果n上有索引，那么索引通常是不能被使用的。&lt;br /&gt;另外mysql中char和varchar末尾的空格会被忽略，&lt;br /&gt;&lt;pre&gt;select * from t where n = 'w   ';&lt;/pre&gt;&lt;br /&gt;同样会返回两条结果，所以如果n上有unique index，那么只有末尾空格数有差别的两条记录会被认为是重复的。&lt;br /&gt;如果希望比较末尾的空格，需要使用&lt;br /&gt;&lt;pre&gt;select * from t where binary n = 'w  ';&lt;/pre&gt;&lt;br /&gt;同样这种形式也不能用到索引。&lt;br /&gt;如果确实需要区别末尾的空格，可以使用varbinary类型，它是保存二进制的字符串，比较时也使用二进制，没有校对规则。&lt;br /&gt;如&lt;br /&gt;&lt;pre&gt;alter table t modify n varbinary(10);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4686948545053089113?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4686948545053089113/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4686948545053089113' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4686948545053089113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4686948545053089113'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/06/mysql.html' title='mysql 字符集'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6939740023045766742</id><published>2007-06-04T08:15:00.000+08:00</published><updated>2007-06-04T08:23:58.603+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>32位系统的最大内存</title><content type='html'>mysql遇到内存不足的问题，但实际上内存并没有用完。所以做了一些调查，道听途说而已，可能结果并不是很准确。32位的linux只支持最大4G内存，而4G的内存一般情况下是分1G为系统空间，3G为用户空间，用户的程序只能在用户空间中分配内存，也可能用到系统空间，但不是自己分配的。因此一般单进程最大能分配3G内存。可以使用下面的程序测试一下：&lt;br /&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;int main(){&lt;br /&gt;  int MB = 0;&lt;br /&gt;  while(malloc(1 &amp;lt;&amp;lt; 20)) ++MB;&lt;br /&gt;  printf("Allocated %d MB total.\n", MB);&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6939740023045766742?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6939740023045766742/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6939740023045766742' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6939740023045766742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6939740023045766742'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/06/32.html' title='32位系统的最大内存'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7546032492366343141</id><published>2007-05-26T10:24:00.000+08:00</published><updated>2007-05-26T10:38:07.747+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MONyog 又一个mysql监视工具</title><content type='html'>MONyog MySQL Monitor and Advisor：&lt;br /&gt;在本机装客户端监视mysql，基于网页的，安装完了会开一个本地的web服务。&lt;br /&gt;可以监视多个服务器，并且针对各种配置有一些优化的意见。网页主要基于js，似乎还可以自己修改。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_stJgJ465TXE/Rleb8noCQDI/AAAAAAAAAOE/Zp51ce6F5IQ/s1600-h/mysql-dashboard.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_stJgJ465TXE/Rleb8noCQDI/AAAAAAAAAOE/Zp51ce6F5IQ/s400/mysql-dashboard.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5068691371360141362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_stJgJ465TXE/RlecFHoCQEI/AAAAAAAAAOM/mM0TRO0GkiY/s1600-h/mysql-status.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_stJgJ465TXE/RlecFHoCQEI/AAAAAAAAAOM/mM0TRO0GkiY/s400/mysql-status.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5068691517389029442" /&gt;&lt;/a&gt;&lt;br /&gt;另外这里还提供一个mysql gui的工具。有企业版和免费版。用着跟mysql query browser差不多，不过感觉比qb好一点，主要是前一阵子用qb总是做了几个查询之后就使用内存太多爆掉了，之后一直在使用mysql的命令行，这个也算是一个gui的代替品吧。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7546032492366343141?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.webyog.com/en/' title='MONyog 又一个mysql监视工具'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7546032492366343141/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7546032492366343141' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7546032492366343141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7546032492366343141'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/05/monyog-mysql.html' title='MONyog 又一个mysql监视工具'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_stJgJ465TXE/Rleb8noCQDI/AAAAAAAAAOE/Zp51ce6F5IQ/s72-c/mysql-dashboard.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-109412193287798456</id><published>2007-05-16T13:08:00.000+08:00</published><updated>2007-05-16T13:33:05.241+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>HotSaNIC的MySQL监视模块</title><content type='html'>写了一个hotsanic的mysql module。目前有5个项目：cache，connection，query/s，slow queries和innodb buffer pool。&lt;br /&gt;点&lt;a href="http://jedywu.googlepages.com/module_mysql.tar.gz"&gt;这里&lt;/a&gt;下载。&lt;br /&gt;使用比较简单，下载后运行下面的命令，运行前更改命令中相关的部分，最好为mysql建一个专门的监视用户，如 grant usage on *.* to watcher@'127.0.0.1' identified by 'xxxxx'。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cd /usr/local/HotSaNIC/modules/&lt;br /&gt;tar zxvf /tmp/module_mysql.tar.gz&lt;br /&gt;cd mysql&lt;br /&gt;sed -i "/PASSWORD/cPASSWORD=\"XXXXXXX\"" settings&lt;br /&gt;cd ../../&lt;br /&gt;sed -i -e "/^RUN/s/=\"/=\"mysql /" -e "/^SHOW/s/=\"/=\"mysql /" settings&lt;br /&gt;./rrdgraph restart&lt;br /&gt;./makeindex.pl &amp;&amp;amp; ./diagrams.pl &amp;&amp;amp; ./convert.pl&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;就只做了目前觉得需要的，其他的项目以后有需要了再加。&lt;br /&gt;例:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_stJgJ465TXE/RkqXaHoCQBI/AAAAAAAAANs/ZGN4Kz513Bw/s1600-h/connection-6h.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_stJgJ465TXE/RkqXaHoCQBI/AAAAAAAAANs/ZGN4Kz513Bw/s400/connection-6h.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5065027205910904850" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-109412193287798456?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/109412193287798456/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=109412193287798456' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/109412193287798456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/109412193287798456'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/05/hotsanicdmysql.html' title='HotSaNIC的MySQL监视模块'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_stJgJ465TXE/RkqXaHoCQBI/AAAAAAAAANs/ZGN4Kz513Bw/s72-c/connection-6h.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3776723910880402066</id><published>2007-05-10T17:01:00.001+08:00</published><updated>2007-05-10T17:02:50.277+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>加快MySQL关闭速度</title><content type='html'>InnoDB的buffer pool中可能有很多unflushed的数据，使得关闭MySQL很慢。如果需要加快关闭的速度，可以设置&lt;br /&gt;set global innodb_max_dirty_pages_pct=0&lt;br /&gt;然后通过show status看InnoDB_buffer_pool_pages_dirty。当它接近于0时再关MySQL。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3776723910880402066?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3776723910880402066/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3776723910880402066' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3776723910880402066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3776723910880402066'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/05/mysql_10.html' title='加快MySQL关闭速度'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1083021804240680077</id><published>2007-05-08T12:55:00.000+08:00</published><updated>2007-05-08T12:57:07.437+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>设置swap</title><content type='html'>linux系统会用内存做很 多的buffer和cache，所以经常会看到内存用完了，其实这里面可能只有很少的一部分是程序用到的。当内存不足的时候，系统有两种选择，一是减少缓 存的量，另一种是把部分程序使用的内存换到swap中。如果是mysql使用的内存被转移到swap中了会对性能有很大的影响，所以应该尽量保持 mysql使用的部分在内存中不被转移出去。可以使用&lt;span&gt;memlock启动mysql是mysqld保持在内存中，不过使用这个选项需要以 root运行服务器。还可以使用关闭swap，可以使用swapoff或者umount分区，不过当内存不够大的时候（比如只有1G）系统不太稳定，可能 会导致mysql内存不足出错。也可以设置系统变量&lt;/span&gt;vm.swappiness，修改 /etc/sysctl.conf 添加 vm.swappiness = 0，并执行 sysctl -p 或 sysctl -w vm.swappiness=0。这个变量的范围是0至100，默认值60，当内存不足时，此变量的值小则系统偏向于减少缓存，反之则转移程序内存到 swap。但即使将它设为0了，系统仍然有可能使用swap。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1083021804240680077?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1083021804240680077/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1083021804240680077' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1083021804240680077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1083021804240680077'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/05/swap.html' title='设置swap'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4073108258431584052</id><published>2007-04-25T15:13:00.000+08:00</published><updated>2007-04-25T15:14:18.668+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL的备份与恢复</title><content type='html'>&lt;strong&gt;备份&lt;/strong&gt;&lt;br /&gt;备份分为完全备份和增量备份。&lt;br /&gt;&lt;strong&gt;完全备份&lt;/strong&gt;有两种方式，一种是备份所有的数据库文件，适合比较大的数据库，另一种是将数据库全部dump出来，适合数据比较少的情况。&lt;br /&gt;对于第一种方法，各种引擎的方式差不多，步骤如下：&lt;br /&gt;1. flush tables with read lock 加读锁保持数据的一致性&lt;br /&gt;2. flush logs或者show master status记下二进制日志的位置方便增量备份&lt;br /&gt;3. 建立快照或者直接拷贝数据库文件&lt;br /&gt;4. unlock tables&lt;br /&gt;3中如果建立快照还需要下面两步：&lt;br /&gt;5. 拷贝数据库文件&lt;br /&gt;6. 删除快照&lt;br /&gt;对于MyISAM表还可以使用mysqlhotcopy，它也是直接拷贝表文件。由于脚本自己会锁表所以步骤比较少，命令为：&lt;br /&gt;mysqlhotcopy -h hostname -u username --flushlog db_name /bak/path&lt;br /&gt;需要注意的是mysqlhotcopy（5.0.37）和最新的DBI（1.54）不兼容，可以在842行后加上一行&lt;br /&gt;s/.*$quote//g;&lt;br /&gt;解决。&lt;br /&gt;注意用这种方法，如果不是用快照，那么当数据库很大的时候，锁表的时间比较长，这段时间内更新操作不能进行。&lt;br /&gt;&lt;br /&gt;对于第二种方法，可以使用mysqldump，当然也可以用select into，不过用这个命令比较麻烦。&lt;br /&gt;如果是innodb的表，那么使用参数--single-transaction可以保持数据库的一致性，而锁表的时间很短。&lt;br /&gt;如果不是innodb表，那么就要使用--lock-tables或者--lock-all-tables，这样在整个导出过程中加读锁，期间更新操作不 能进行，当数据库比较大的时候需要注意。--lock-tables是按数据库加锁，不能保证全部数据库的一致性，--lock-all-tables是 给所有数据库的所有表加锁。&lt;br /&gt;命令为：&lt;br /&gt; mysqldump --lock-all-tables --flush-logs --master-data=2 --all-database &gt; db.sql&lt;br /&gt;或&lt;br /&gt; mysqldump --single-transaction --flush-logs --master-data=2 --database db_name&gt; db.sql&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;增量备份&lt;/strong&gt;则是定期备份二进制日志，备份前使用 flush logs 刷新日志。如果之前完全备份使用了flush命令或选项，那么增加备份从完全备份之后新生成的日志开始，否则从完全备份时在使用的日志开始。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;恢复&lt;/strong&gt;&lt;br /&gt;恢复步骤比较简单。&lt;br /&gt;1. 如果是备份的数据文件，那么拷回数据目录。如果是导出的，用 mysql &lt; bak.sql 导入&lt;br /&gt;2. 导入完全备份之后增量备份的二进制日志，命令为 mysqlbinlog mysql-bin.xxxx | mysql。&lt;br /&gt;如果完全备份时没有刷新日志可能还需要用--start-datetime或--start-position指定日志的起始位置。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4073108258431584052?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4073108258431584052/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4073108258431584052' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4073108258431584052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4073108258431584052'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/04/mysql_25.html' title='MySQL的备份与恢复'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7532757898609866643</id><published>2007-04-20T13:49:00.001+08:00</published><updated>2007-04-20T13:51:01.111+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>[zz] MySQL使用tips</title><content type='html'>&lt;ul type="1"&gt;&lt;li&gt;     &lt;p&gt; 用mysql内置函数转换ip地址和数字&lt;br /&gt;   利用两个内置函数&lt;br /&gt;   inet_aton:将ip地址转换成数字型&lt;br /&gt;   inet_ntoa:将数字型转换成ip地址 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 充分利用mysql内置的format函数&lt;br /&gt;   尤其是在处理字符格式的时候,例如将12345转换成12,345这样的,只要用:format(12345,0)即可,如果用format(12345,2)则显示的是12,345.00了... &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 利用mysql的内置函数处理时间戳问题&lt;br /&gt;   eg : select FROM_UNIXTIME(UNIX_TIMESTAMP(),'%Y %D %M %h:%i:%s %x');&lt;br /&gt;   结果: 2004 3rd August 03:35:48 2004 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 利用mysql_convert_table_format转换表类型&lt;br /&gt;   需要DBI和DBD的mysql相关模块支持才能用,例子:&lt;br /&gt;   mysql_convert_table_format --user=root --password='xx' --type=myisam test yejr &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 修改mysql表中的字段名&lt;br /&gt;   alter table tb_name change old_col new_col definition... &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 利用临时变量&lt;br /&gt;   select @var1:=a1+a2 as a_sum,@var2:=b1+b2 as b_sum,@var1+@var2 as total_sum from test_table xxx; &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 用int类型存储ip地址&lt;br /&gt;   原先错误的认为必须用bigint才够，后来发现使用int unsigned类型就足够了。 :) &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 利用IF函数快速修改ENUM字段值&lt;br /&gt;   一个例子：&lt;br /&gt;   update rule set enable = if('0' = enable,'1','0') where xxx;&lt;br /&gt;   enable 类型：enum('0','1') not null default '0' &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 事务无法嵌套 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 避免长时间的sleep连接造成的连接数超出问题&lt;br /&gt;   设定全局变量 wait_timeout 和 interactive_timeout 为比较小的值，例如&lt;br /&gt;   10(s)，就能使每个sleep连接在10s之后如果还没有查询的话自动断开。 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 设定mysql客户端的提示符(prompt)&lt;br /&gt;   export MYSQL_PS1="(\\u:\\h:)\\d&gt; "&lt;br /&gt;   则用 mysql -hlocalhost -uroot -pxx db_name 登录后，提示符变成：&lt;br /&gt;   (root:localhost:)db_name&gt;&lt;br /&gt;   好用吧 :), 时时刻刻提醒你在哪个服务器上，尽量避免误操作的发生&lt;br /&gt;   更详细的请查看MySQL手册 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 整理MyISAM碎片&lt;br /&gt;   1.) 定期运行  OPTIMIZE TABLE  命令即可&lt;br /&gt;   2.) 用mysqldump出数据，然后重新import回去，这对大表来说显然第一种方法比较方便 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 整理Innodb碎片&lt;br /&gt;   1.) 运行NULL命令， ALTER TABLE XXX ENGINE=Innodb;&lt;br /&gt;   2.) 同上的mysqldump方法 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; MySQL如果认为检索的记录数量超过总记录数的30%，则选择全表扫描，而非使用索引 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; MySQL 5.0.3之后,VARCHAR字段后面的空格就不再删除。但查询时是忽略末尾空格的。 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; MySQL 4.1之后，MySQL把字符串类型字段的长度定义理解为字符长度而不是字节长度 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; MySQL 4.1=&gt;5.0时，增加了一个新的启动选项 innodb_table_locks，它导致 LOCK TABLE 时也可以请求 InnoDB&lt;br /&gt;   表锁。这个选项默认打开，不过可能在 AUTOCOMMIT=1 和 LOCK TABLES 应用中会导致死锁 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 5.0.3开始，在计算 DECIMAL 值和舍入精确值的时候采用精确数学，DECIMAL 用更有效的格式来存储 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 从5.0.12开始，自然连接和使用 USING&lt;br /&gt;   的连接，包括外部连接的衍生形式，都按照SQL:2003标准来处理了；这个变化导致减少了自然连接和使用 USING&lt;br /&gt;   的连接产生的结果字段数，并且还将按照更合理的顺序显示这些字段，逗号比较符的优先顺序和 JOIN, LEFT JOIN 中的一样了 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; 在以前，等待超时的锁会导致 InnoDB 回滚当前全部事务，从5.0.13开始，就只回滚最近的SQL语句了 &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; InnoDB 和 MyISAM 表中空格结尾的 TEXT 字段索引顺序改变了。因此需要运行 "CHECK TABLE" 语句修复数据表，如果出现错误，就运行&lt;br /&gt;   "OPTIMIZE TABLE" 或 "REPAIR TABLE" 语句修复，甚至重新转储(用mysqldump) &lt;/p&gt;     &lt;/li&gt;&lt;li&gt;     &lt;p&gt; MySQL 5.0.3到5.0.5之间版本的 MyISAM 和 InnoDB 表中创建的 DECIMAL 字段升级到5.0.6之后会发生崩溃 &lt;/p&gt;     &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7532757898609866643?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://imysql.cn/?q=node/69' title='[zz] MySQL使用tips'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7532757898609866643/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7532757898609866643' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7532757898609866643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7532757898609866643'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/04/zz-mysqltips.html' title='[zz] MySQL使用tips'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4072655449512295627</id><published>2007-04-20T11:50:00.000+08:00</published><updated>2007-05-19T22:31:58.291+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>使用LVM快速建立数据库的快照</title><content type='html'>LVM（逻辑卷管理器） 是一种把硬盘驱动器空间分配成逻辑卷的方法，这样硬盘就不必使用分区而被简易地重划大小。下图是LVM的主要结构。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_stJgJ465TXE/Rk8Jt3oCQCI/AAAAAAAAAN8/ABM67xR6Gdw/s1600-h/lvm.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://3.bp.blogspot.com/_stJgJ465TXE/Rk8Jt3oCQCI/AAAAAAAAAN8/ABM67xR6Gdw/s400/lvm.png" alt="" id="BLOGGER_PHOTO_ID_5055353487907450114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;使用LVM可以快速的对一个逻辑卷做快照，所以可以为不能停机的数据库做快照。如果我们要对一个数据库系统做快照，数据库的数据文件必须在一个逻辑卷上，而 不能只使用传统的分区。虽然可以把一个物理分区转成LVM的卷，但这个操作需要先卸载分区，所以如果希望不关闭数据库，在安装数据库时就需要使用LVM。&lt;br /&gt;&lt;br /&gt;建立逻辑卷的步骤：&lt;br /&gt;1. 首先使用fdisk建立新的分区（假设为/dev/sda3），并使用t指令把分区类型改成8e。使用p指令可以看到system为Linux LVM&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;/dev/sda1   *           1          13      104391   83  Linux&lt;br /&gt;/dev/sda2              14         650     5116702+  83  Linux&lt;br /&gt;/dev/sda3             651        1287     5116702+  8e  Linux LVM&lt;br /&gt;/dev/sda4            1288        9726    67786267+   5  Extended&lt;br /&gt;/dev/sda5            1670        1924     2048256   82  Linux swap&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. 使用&lt;span style="font-weight: bold;"&gt; pvcreate /dev/sda3&lt;/span&gt; 建立物理卷&lt;br /&gt;&lt;br /&gt;3. 然后使用 &lt;span style="font-weight: bold;"&gt;vgcreate db /dev/sda3&lt;/span&gt; 建立卷组。这里卷组中只用了一个物理卷，也可以有多个，如：&lt;span style="font-weight: bold;"&gt;vgcreate db /dev/sda1 /dev/sda3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4. 激活卷组（可能需要）&lt;span style="font-weight: bold;"&gt;vgchange -a y db&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;5. 可以使用 &lt;span style="font-weight: bold;"&gt;vgdisplay -v db&lt;/span&gt; 查看卷组的状态&lt;br /&gt;&lt;br /&gt;6. 在卷组上建立逻辑卷。&lt;span style="font-weight: bold;"&gt;lvcreate -L 50G -n main db&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;7. 建立文件系统，&lt;span style="font-weight: bold;" id="zoom" class="f14"&gt;mke2fs /dev/db/main&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;8. 挂载卷。&lt;span style="font-weight: bold;"&gt;mount /dev/db/main /var/db&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;假设逻辑卷/dev/db/main已经挂载为数据库的数据目录/var/db，/dev/db是逻辑卷组。如果/dev/db中还有空余的空间，那么可以直接建立快照，否则需要为卷组增加空间。使用 &lt;span style="font-weight: bold;"&gt;vgextend db /dev/sdb1&lt;/span&gt; 增加一个新的物理卷。&lt;br /&gt;&lt;br /&gt;下面来建立快照：&lt;br /&gt;1. 使用 &lt;span style="font-weight: bold;"&gt;flush tables with read lock&lt;/span&gt; 给表加锁。操作结束了不要推出mysql client，否则就会解锁了。&lt;br /&gt;注意：如果你当前正在执行一个较长时间的查询，那么这个命令可能需要较长时间才能完成。&lt;br /&gt;&lt;br /&gt;2. 开一个新的shell，使用 &lt;span style="font-weight: bold;"&gt;lvcreate -L10G -s -n backup /dev/db/main&lt;/span&gt; 建立main卷的快照backup。备份过程中务必指定足够大的撤销空间用于保存发生变化的东西。这里指定了10GB。如果撤销空间不够大，快照就会无效。这个命令应该是只需要几秒的时间。&lt;br /&gt;如果遇到这样的错误，“&lt;b&gt;snapshot: Required device-mapper target(s) not detected in your kernel&lt;/b&gt;”，需要执行 &lt;span style="font-weight: bold;"&gt;modprobe dm-snapshot&lt;/span&gt;。&lt;br /&gt;当快照存在时重启服务器可以会出现卷无法挂载的错误，错误信息为：&lt;span style="font-weight: bold;"&gt;mount: special device /dev/db/main does not exist&lt;/span&gt;。这里也需要执行 &lt;span style="font-weight: bold;"&gt;modprobe dm-snapshot&lt;/span&gt; 并激活卷组 &lt;span style="font-weight: bold;"&gt;vgchange -a y db&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;3. 在1中的mysql client里解锁，&lt;span style="font-weight: bold;"&gt;unlock tables&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4. 挂载backup，然后将快照拷贝出来&lt;br /&gt;&lt;br /&gt;5. 卸载backup&lt;br /&gt;&lt;br /&gt;6. 删除快照 &lt;span style="font-weight: bold;"&gt;lvremove /dev/db/backup&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4072655449512295627?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4072655449512295627/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4072655449512295627' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4072655449512295627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4072655449512295627'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/04/lvm.html' title='使用LVM快速建立数据库的快照'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_stJgJ465TXE/Rk8Jt3oCQCI/AAAAAAAAAN8/ABM67xR6Gdw/s72-c/lvm.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7018387382562880335</id><published>2007-04-15T20:27:00.000+08:00</published><updated>2007-04-15T20:28:49.611+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>mysql如何区分大小写</title><content type='html'>是否区分大小写和校对规则有关，默认设的规则是大小写不敏感的。&lt;br /&gt;show create table如果看到collate是ci结尾，那么就是不区别的，如果cs或bin结尾，就是区别的。&lt;br /&gt;如果建表的时候选择的是区别大小写的规则而查询的时候又暂时不想区别，&lt;br /&gt;可以用类似&lt;br /&gt;WHERE column_name COLLATE latin1_general_ci = 'xxx'&lt;br /&gt;的写法改变查询使用的校对规则&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7018387382562880335?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7018387382562880335/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7018387382562880335' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7018387382562880335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7018387382562880335'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/04/mysql.html' title='mysql如何区分大小写'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1390321068438742877</id><published>2007-04-11T10:23:00.000+08:00</published><updated>2007-04-11T10:24:19.621+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>使用延迟的join来优化count(*)和limit语句（翻译）</title><content type='html'>&lt;p&gt;在很多运用中，常有这样的结构，一个主表和一个附加表，附加表用来存一些附加信息，取数据的时候需要和主表连接。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;如果你在这样的结构上执行count(*)，那么即使使用了left join，MySQL仍然会做连接。同样的如果使用了limit，MySQL也会连接一些最终会扔掉的行。当limit的偏移量很大的时候，这样的连接是很浪费时间的。&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;对于这样的情况，你可以帮助MySQL不要对count(*)做连接或者做了limit之后再连接。&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;请看下面的例子：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   1      CREATE TABLE `fact` (&lt;br /&gt;   2        `i` int(10) UNSIGNED NOT NULL,&lt;br /&gt;   3        `val` int(10) UNSIGNED NOT NULL,&lt;br /&gt;   4        KEY `i` (`i`,`val`)&lt;br /&gt;   5      )&lt;br /&gt;   6       &lt;br /&gt;   7      CREATE TABLE `dim` (&lt;br /&gt;   8        `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,&lt;br /&gt;   9        `pad` varchar(100) NOT NULL,&lt;br /&gt;  10        PRIMARY KEY  (`id`)&lt;br /&gt;  11      )&lt;br /&gt;  12       &lt;br /&gt;  13      mysql&gt; SELECT count(*) FROM dim;&lt;br /&gt;  14      +----------+&lt;br /&gt;  15      | count(*) |&lt;br /&gt;  16      +----------+&lt;br /&gt;  17      |    30720 |&lt;br /&gt;  18      +----------+&lt;br /&gt;  19      1 row IN SET (0.00 sec)&lt;br /&gt;  20       &lt;br /&gt;  21      mysql&gt; SELECT count(*) FROM fact;&lt;br /&gt;  22      +----------+&lt;br /&gt;  23      | count(*) |&lt;br /&gt;  24      +----------+&lt;br /&gt;  25      |  7340032 |&lt;br /&gt;  26      +----------+&lt;br /&gt;  27      1 row IN SET (0.00 sec)&lt;br /&gt;  28       &lt;br /&gt;  29      mysql&gt; SELECT count(*) FROM fact WHERE i&lt;10000;&lt;br /&gt;  30      +----------+&lt;br /&gt;  31      | count(*) |&lt;br /&gt;  32      +----------+&lt;br /&gt;  33      |   733444 |&lt;br /&gt;  34      +----------+&lt;br /&gt;  35      1 row IN SET (0.44 sec)&lt;br /&gt;  36       &lt;br /&gt;  37       &lt;br /&gt;  38      mysql&gt; SELECT count(*) FROM fact LEFT JOIN dim ON val=id WHERE i&lt;10000;&lt;br /&gt;  39      +----------+&lt;br /&gt;  40      | count(*) |&lt;br /&gt;  41      +----------+&lt;br /&gt;  42      |   733444 |&lt;br /&gt;  43      +----------+&lt;br /&gt;  44      1 row IN SET (2.15 sec)&lt;br /&gt;  45       &lt;br /&gt;  46       &lt;br /&gt;  47      mysql&gt; SELECT i,pad FROM fact LEFT JOIN dim ON val=id WHERE i&lt;10000 LIMIT 500000,10;&lt;br /&gt;  48      +------+------------------------------------------+&lt;br /&gt;  49      | i    | pad                                      |&lt;br /&gt;  50      +------+------------------------------------------+&lt;br /&gt;  51      | 6811 | 06bfea523be29a6070488ee66e874dffa170de76 |&lt;br /&gt;  52      | 6811 | 3baf40c2d76998270f8954bedda386b5021e0624 |&lt;br /&gt;  53      | 6811 | 35ad5c3a9d0763acc305992327864bed1af34167 |&lt;br /&gt;  54      | 6811 | 81de98a3ef74ddc0fa4f7c95a27e3dbebca8df0d |&lt;br /&gt;  55      | 6811 | 11cde5d0bd8ffe1eda86b39d05a58c525e8fac8f |&lt;br /&gt;  56      | 6811 | 25c474b380388c23b1de730c4255612e1233e14e |&lt;br /&gt;  57      | 6811 | 1d32b5ba28a513097fc88f3efd91155b2697aeec |&lt;br /&gt;  58      | 6811 | bdc9a39cdfafda26fc2f48a48abd3bc5f051a4ea |&lt;br /&gt;  59      | 6811 | d2e6cb9ca5aa9dd2bc3d033de45579a76ccdafdf |&lt;br /&gt;  60      | 6811 | 0130c708083d77377255bd8f5e0daa15fbb24212 |&lt;br /&gt;  61      +------+------------------------------------------+&lt;br /&gt;  62      10 rows IN SET (3.88 sec)&lt;br /&gt;  63       &lt;br /&gt;  64      mysql&gt; SELECT i,pad FROM (SELECT i,val FROM fact WHERE i&lt;10000 LIMIT 500000,10) res LEFT JOIN dim ON val=id;&lt;br /&gt;  65      +------+------------------------------------------+&lt;br /&gt;  66      | i    | pad                                      |&lt;br /&gt;  67      +------+------------------------------------------+&lt;br /&gt;  68      | 6811 | 06bfea523be29a6070488ee66e874dffa170de76 |&lt;br /&gt;  69      | 6811 | 3baf40c2d76998270f8954bedda386b5021e0624 |&lt;br /&gt;  70      | 6811 | 35ad5c3a9d0763acc305992327864bed1af34167 |&lt;br /&gt;  71      | 6811 | 81de98a3ef74ddc0fa4f7c95a27e3dbebca8df0d |&lt;br /&gt;  72      | 6811 | 11cde5d0bd8ffe1eda86b39d05a58c525e8fac8f |&lt;br /&gt;  73      | 6811 | 25c474b380388c23b1de730c4255612e1233e14e |&lt;br /&gt;  74      | 6811 | 1d32b5ba28a513097fc88f3efd91155b2697aeec |&lt;br /&gt;  75      | 6811 | bdc9a39cdfafda26fc2f48a48abd3bc5f051a4ea |&lt;br /&gt;  76      | 6811 | d2e6cb9ca5aa9dd2bc3d033de45579a76ccdafdf |&lt;br /&gt;  77      | 6811 | 0130c708083d77377255bd8f5e0daa15fbb24212 |&lt;br /&gt;  78      +------+------------------------------------------+&lt;br /&gt;  79      10 rows IN SET (0.30 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;可以看到使用的小技巧改善了速度。&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1390321068438742877?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mysqlperformanceblog.com/2007/04/06/using-delayed-join-to-optimize-count-and-limit-queries/' title='使用延迟的join来优化count(*)和limit语句（翻译）'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1390321068438742877/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1390321068438742877' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1390321068438742877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1390321068438742877'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/04/joincountlimit.html' title='使用延迟的join来优化count(*)和limit语句（翻译）'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-4815198323663145166</id><published>2007-03-27T11:14:00.000+08:00</published><updated>2007-03-27T11:23:39.008+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>mysql监视分析工具</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;strong&gt;mysqlbinlog&lt;/strong&gt; 这个大家都应该知道的，用来看mysql的binlog的。mysql自带。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;mysqldumpslow&lt;/strong&gt; 用于分析mysql的slow log。自带的。结果如下。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Count: 1  Time=4.00s (4s)  Lock=0.00s (0s)  Rows=0.0 (0), root[root]@[127.0.0.1]&lt;br /&gt;  select * from user ignore key (PRIMARY)  where address = 'S' order by id asc limit N&lt;br /&gt;&lt;br /&gt;Count: 3  Time=4.00s (12s)  Lock=0.00s (0s)  Rows=0.0 (0), root[root]@[127.0.0.1]&lt;br /&gt;  select * from user  where address = 'S' order by id asc limit N&lt;br /&gt;&lt;br /&gt;Count: 2  Time=4.00s (8s)  Lock=0.00s (0s)  Rows=32.0 (64), root[root]@[127.0.0.1]&lt;br /&gt;  select count(*), age from user group by age with rollup&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;mysql_explain_log&lt;/strong&gt; 分析mysql的通用查询日志（用log选项打开的），自带的。需要注意的是用客户端连接mysql的时候需要指定数据库，使用use XXX选择数据库的时候此工具无法分辨出sql使用的是什么数据库。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;explain_log     provided by http://www.mobile.de&lt;br /&gt;===========     ================================&lt;br /&gt;&lt;br /&gt;Index usage ------------------------------------&lt;br /&gt;&lt;br /&gt;Table   test.user: ---&lt;br /&gt; count  key:&lt;br /&gt;  1     PRIMARY&lt;br /&gt; count  possible_keys:&lt;br /&gt;  1     PRIMARY&lt;br /&gt; count  type:&lt;br /&gt;  1     ALL&lt;br /&gt;  1     range&lt;br /&gt;&lt;br /&gt;Queries causing table scans -------------------&lt;br /&gt;&lt;br /&gt;EXPLAIN select * from test.user&lt;br /&gt;Sum: 1 table scans&lt;br /&gt;&lt;br /&gt;Summary ---------------------------------------&lt;br /&gt;&lt;br /&gt;Select:         4 queries&lt;br /&gt;Update:         0 queries&lt;br /&gt;&lt;br /&gt;Init:           0 times&lt;br /&gt;Field:          6 times&lt;br /&gt;Refresh:        0 times&lt;br /&gt;Query:          35 times&lt;br /&gt;Statistics:     0 times&lt;br /&gt;&lt;br /&gt;Logfile:        59 lines&lt;br /&gt;Started:        Tue Mar 27 10:45:12 2007&lt;br /&gt;Finished:       Tue Mar 27 10:45:12 2007&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;perror&lt;/strong&gt; 显示错误码对应的错误信息。mysql自带。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;shell&gt;perror 13&lt;br /&gt;OS error code  13:  Permission denied&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;mysqlslap&lt;/strong&gt; 一个性能测试的工具。mysql的&lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html" target="_blank"&gt;test suite&lt;/a&gt;中带的。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://mtop.sourceforge.net/" target="_blank"&gt;mtop&lt;/a&gt;&lt;/strong&gt; 一个进程监视的工具，可以直接在里面显示出explain的结果。也可以使用watch -n 1 mysqladmin status processlist来监视。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;127.0.0.1  mysqld 5.0.27-standard-log up 0 day(s),  0:10 hrs&lt;br /&gt;1 threads: 1 running, 1 cached. Queries/slow: 26/0 Cache Hit: 100.00%&lt;br /&gt;Opened tables: 0  RRN: 467  TLW: 0  SFJ: 0  SMP: 0  QPS: 0&lt;br /&gt;&lt;br /&gt;ID       USER     HOST             DB           TIME   COMMAND STATE        INFO&lt;br /&gt;26       root     1270.0.1:52841                       Query                show full processlist&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://www.willamowius.de/mysql-tools.html" target="_blank"&gt;mysql_explain_slow_log&lt;/a&gt;&lt;/strong&gt; 和mysql_explain_log差不多，不过这个是分析slow log的。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql_explain_slow_log&lt;br /&gt;======================&lt;br /&gt;&lt;br /&gt;Index usage ------------------------------------&lt;br /&gt;&lt;br /&gt;Table   test: ---&lt;br /&gt; count  type:&lt;br /&gt;  10    ALL&lt;br /&gt;&lt;br /&gt;Table   test.click: ---&lt;br /&gt; count  type:&lt;br /&gt;  1     ALL&lt;br /&gt;&lt;br /&gt;Table   test.user: ---&lt;br /&gt; count  key:&lt;br /&gt;  1     username,useraa&lt;br /&gt;  9     usertime&lt;br /&gt;  16    PRIMARY&lt;br /&gt;  29    useraa&lt;br /&gt; count  possible_keys:&lt;br /&gt;  1     PRIMARY&lt;br /&gt;  7     useraa,username&lt;br /&gt;  9     usertime&lt;br /&gt;  23    useraa&lt;br /&gt; count  type:&lt;br /&gt;  1     index_merge&lt;br /&gt;  2     range&lt;br /&gt;  23    ref&lt;br /&gt;  29    index&lt;br /&gt;  31    ALL&lt;br /&gt;&lt;br /&gt;Queries causing table scans -------------------&lt;br /&gt;EXPLAIN select * from test.user&lt;br /&gt;EXPLAIN select * from test.user order by rand() limit 5&lt;br /&gt;省略若干行...&lt;br /&gt;&lt;br /&gt;Sum: 56 table scans&lt;br /&gt;&lt;br /&gt;Summary ---------------------------------------&lt;br /&gt;&lt;br /&gt;Select:         97 queries&lt;br /&gt;Update:         0 queries&lt;br /&gt;Load:   33 queries&lt;br /&gt;&lt;br /&gt;Logfile:        1657 lines&lt;br /&gt;Started:        Tue Mar 27 11:01:14 2007&lt;br /&gt;Finished:       Tue Mar 27 11:01:14 2007&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://hackmysql.com/mysqlreport" target="_blank"&gt;mysqlreport&lt;/a&gt;&lt;/strong&gt; 监视分析mysql状态的工具。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MySQL 5.0.27-standard-l  uptime 0 0:17:57       Tue Mar 27 11:04:15 2007&lt;br /&gt;&lt;br /&gt;__ Key _________________________________________________________________&lt;br /&gt;Buffer used         0 of  32.00M  %Used:   0.00&lt;br /&gt;  Current       3.68M            %Usage:  11.51&lt;br /&gt;Write ratio     0.000&lt;br /&gt;Read ratio      0.000&lt;br /&gt;&lt;br /&gt;__ Questions ___________________________________________________________&lt;br /&gt;Total             170     0.2/s&lt;br /&gt;Slow                0       0/s  %Total:   0.00  %DMS:   0.00&lt;br /&gt;DMS               105     0.1/s           61.76&lt;br /&gt;&lt;br /&gt;__ Table Locks _________________________________________________________&lt;br /&gt;Waited              0       0/s  %Total:   0.00&lt;br /&gt;Immediate         109     0.1/s&lt;br /&gt;&lt;br /&gt;__ Tables ______________________________________________________________&lt;br /&gt;Open                8 of 2048    %Cache:   0.39&lt;br /&gt;Opened             14     0.0/s&lt;br /&gt;&lt;br /&gt;__ Connections _________________________________________________________&lt;br /&gt;Max used            2 of  500      %Max:   0.40&lt;br /&gt;Total              38     0.0/s&lt;br /&gt;&lt;br /&gt;__ Created Temp ________________________________________________________&lt;br /&gt;Disk table          0       0/s&lt;br /&gt;Table              16     0.0/s&lt;br /&gt;File                5     0.0/s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://hackmysql.com/mysqlsla" target="_blank"&gt;mysqlsla&lt;/a&gt;&lt;/strong&gt; 分析mysql的各种日志。分析slow log的结果如下。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Reading slow log 'db-slow.log'&lt;br /&gt;170 total queries, 72 unique&lt;br /&gt;Sorting by 't'&lt;br /&gt;&lt;br /&gt;__ 001 _______________________________________________________________________&lt;br /&gt;&lt;br /&gt;Count         : 15 (8%)&lt;br /&gt;Time          : 1297.000 total, 86.467 avg, 3.000 min to 833.000 max&lt;br /&gt;                9:20% 10:13% 833:6% 67:6% 57:6% 3:6% 61:6% 58:6% 20:6% 103:6% (87%)&lt;br /&gt;Lock          : 0.000 total, 0.000 avg, 0.000 min to 0.000 max&lt;br /&gt;Rows sent     : 0 avg, 0 min to 0 max&lt;br /&gt;Rows examined : 0 avg, 0 min to 0 max&lt;br /&gt;User          : root[root]@/127.0.0.1 (100%)&lt;br /&gt;&lt;br /&gt;SET insert_id=N;&lt;br /&gt;LOAD data infile 'S' INTO table user;&lt;br /&gt;省略若干行...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://hackmysql.com/mysqlsniffer" target="_blank"&gt;mysqlsniffer&lt;/a&gt;&lt;/strong&gt; 监听mysql通讯的工具。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysqlsniffer listening for MySQL on interface eth0 port 3306&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 0 len 65 Handshake &lt;proto 10 ver 5.0.27-standard-log thd 39&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 1 len 38 Handshake (new auth) &lt;user root db (null) max pkt 16777216&gt;&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 2 len 7 OK &lt;fields 0 affected rows 0 insert id 0 warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 18 COM_QUERY: SELECT DATABASE()&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 1 1 Fields&lt;br /&gt;        ID 2 len 32 Field: ..DATABASE() &lt;type var string (253) size 102&gt;&lt;br /&gt;        ID 3 len 5 End &lt;warnings 0&gt;&lt;br /&gt;        ID 4 len 1 || NULL ||&lt;br /&gt;        ID 5 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 5 COM_INIT_DB: test&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 7 OK &lt;fields 0 affected rows 0 insert id 0 warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 15 COM_QUERY: show databases&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 1 1 Fields&lt;br /&gt;        ID 2 len 49 Field: .SCHEMATA.Database &lt;type var string (509) size 192&gt;&lt;br /&gt;        ID 3 len 5 End &lt;warnings 0&gt;&lt;br /&gt;        ID 4 len 19 || information_schema ||&lt;br /&gt;        ID 5 len 3 || aa ||&lt;br /&gt;        ID 6 len 6 || mysql ||&lt;br /&gt;        ID 7 len 7 || sakila ||&lt;br /&gt;        ID 8 len 5 || test ||&lt;br /&gt;        ID 9 len 6 || world ||&lt;br /&gt;        ID 10 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 12 COM_QUERY: show tables&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 1 1 Fields&lt;br /&gt;        ID 2 len 57 Field: .TABLE_NAMES.Tables_in_test &lt;type var string (509) size 192&gt;&lt;br /&gt;        ID 3 len 5 End &lt;warnings 0&gt;&lt;br /&gt;        ID 4 len 6 || click ||&lt;br /&gt;        ID 5 len 8 || s_click ||&lt;br /&gt;        ID 6 len 5 || user ||&lt;br /&gt;        ID 7 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 7 COM_FIELD_LIST: click&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 42 Field: test.click.id &lt;type long int (771) size 11&gt;&lt;br /&gt;        ID 2 len 51 Field: test.click.user_id &lt;type long int (2051) size 11&gt;&lt;br /&gt;        ID 3 len 62 Field: test.click.promotion_id &lt;type long int (2307) size 11&gt;&lt;br /&gt;        ID 4 len 49 Field: test.click.status &lt;type tiny int (1) size 4&gt;&lt;br /&gt;        ID 5 len 78 Field: test.click.record_time &lt;type timestamp (57607) size 19&gt;&lt;br /&gt;        ID 6 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 9 COM_FIELD_LIST: s_click&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 46 Field: test.s_click.id &lt;type long int (771) size 11&gt;&lt;br /&gt;        ID 2 len 66 Field: test.s_click.promotion_id &lt;type long int (259) size 11&gt;&lt;br /&gt;        ID 3 len 53 Field: test.s_click.status &lt;type tiny int (1) size 4&gt;&lt;br /&gt;        ID 4 len 59 Field: test.s_click.click_num &lt;type long int (3) size 11&gt;&lt;br /&gt;        ID 5 len 73 Field: test.s_click.record_date &lt;type date (33034) size 10&gt;&lt;br /&gt;        ID 6 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 6 COM_FIELD_LIST: user&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 40 Field: test.user.id &lt;type long int (771) size 11&gt;&lt;br /&gt;        ID 2 len 43 Field: test.user.name &lt;type var string (2301) size 120&gt;&lt;br /&gt;        ID 3 len 45 Field: test.user.email &lt;type var string (253) size 765&gt;&lt;br /&gt;        ID 4 len 49 Field: test.user.address &lt;type var string (253) size 765&gt;&lt;br /&gt;        ID 5 len 41 Field: test.user.age &lt;type long int (2051) size 11&gt;&lt;br /&gt;        ID 6 len 76 Field: test.user.regist_time &lt;type timestamp (59655) size 19&gt;&lt;br /&gt;        ID 7 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 27 COM_QUERY: select * from user limit 1&lt;br /&gt;server &gt; 192.168.1.170.32958: ID 1 len 1 6 Fields&lt;br /&gt;        ID 2 len 38 Field: test.user.id &lt;type long int (771) size 11&gt;&lt;br /&gt;        ID 3 len 42 Field: test.user.name &lt;type var string (2301) size 120&gt;&lt;br /&gt;        ID 4 len 44 Field: test.user.email &lt;type var string (253) size 765&gt;&lt;br /&gt;        ID 5 len 48 Field: test.user.address &lt;type var string (253) size 765&gt;&lt;br /&gt;        ID 6 len 40 Field: test.user.age &lt;type long int (2051) size 11&gt;&lt;br /&gt;        ID 7 len 56 Field: test.user.regist_time &lt;type timestamp (59655) size 19&gt;&lt;br /&gt;        ID 8 len 5 End &lt;warnings 0&gt;&lt;br /&gt;        ID 9 len 34 || 1 | ll | ff | ll | 10 | 2007-03-21 09:58:07 ||&lt;br /&gt;        ID 10 len 5 End &lt;warnings 0&gt;&lt;br /&gt;192.168.1.170.32958 &gt; server: ID 0 len 1 COM_QUIT&lt;br /&gt;192.168.1.57.60248 &gt; server: ID 0 len 48 COM_QUERY: SELECT COUNT(*) FROM product WHERE index_flag=0&lt;br /&gt;server &gt; 192.168.1.57.60248: ID 1 len 1 1 Fields&lt;br /&gt;        ID 2 len 30 Field: ..COUNT(*) &lt;type longlong (33032) size 21&gt;&lt;br /&gt;        ID 3 len 1 End&lt;br /&gt;        ID 4 len 2 || 0 ||&lt;br /&gt;        ID 5 len 5 End &lt;warnings 0&gt;&lt;br /&gt;70 MySQL packets captured (2022 bytes)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jedywu.googlepages.com/mysql-tools.tar.gz"&gt;下载&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-4815198323663145166?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/4815198323663145166/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=4815198323663145166' title='5 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4815198323663145166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/4815198323663145166'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/mysql_27.html' title='mysql监视分析工具'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-911808055956998825</id><published>2007-03-26T11:28:00.000+08:00</published><updated>2007-03-26T11:29:20.381+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>小心太大的query_cache</title><content type='html'>当query_size过大，比如说有256M或者更多，而又缓存了很多query（Qcache_queries_in_cache），在加上一条插入 语句可能使很多的缓存无效，那么插入就会变得很慢，因为有一个使大量缓存无效的过程。可以使用flush query cache清除缓存看一下需要多长时间。解决方法可以减小缓存，或者使用外部的缓存如memcached。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-911808055956998825?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mysqlperformanceblog.com/2007/03/23/beware-large-query_cache-sizes/' title='小心太大的query_cache'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/911808055956998825/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=911808055956998825' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/911808055956998825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/911808055956998825'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/querycache.html' title='小心太大的query_cache'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5253245583714606556</id><published>2007-03-20T16:11:00.000+08:00</published><updated>2007-03-20T16:12:34.580+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>性能测试</title><content type='html'>做了一个insert into on duplicate key update的性能测试。&lt;br /&gt;原始表有200万数据，有4个字段（不包括主键），unique key为其中一个字段。&lt;br /&gt;直接插入2万条无重复的数据使用了1.74秒。&lt;br /&gt;使用on duplicate key update插入1万条数据，更新1万条唯一键重复的数据使用了2.96秒。&lt;br /&gt;使用replace则是使用了3.32秒，大概是因为replace是先删除再插入，速度慢一点。&lt;br /&gt;如果自己select之后判断则更慢了，需要4.32秒。&lt;br /&gt;另外on duplicate key update和replace如果都是插入无重复的数据则速度和直接插入差不多。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5253245583714606556?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5253245583714606556/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5253245583714606556' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5253245583714606556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5253245583714606556'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/blog-post_20.html' title='性能测试'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-1352775810474172261</id><published>2007-03-14T12:01:00.000+08:00</published><updated>2007-03-14T12:02:34.025+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>在MySQL中如何为连接添加索引</title><content type='html'>译文：&lt;br /&gt;&lt;br&gt;&lt;br /&gt;我先通过一个简单的例子说明在MySQL中如何为连接添加索引，然后再看一个有挑战性的例子。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;简单的3个表的连接&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;表结构很简单，3个表tblA, tblB, tblC，每个表有3个字段：col1, col2, col3。&lt;br /&gt;在没有索引的情况下连接3个表&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   SELECT&lt;br /&gt;      *&lt;br /&gt;   FROM&lt;br /&gt;      tblA,&lt;br /&gt;      tblB,&lt;br /&gt;      tblC&lt;br /&gt;   WHERE&lt;br /&gt;          tblA.col1 = tblB.col1&lt;br /&gt;      AND tblA.col2 = tblC.col1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;explain的结果如下：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+------+---------------+------+---------+------+------+-------------+&lt;br /&gt;   | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |&lt;br /&gt;   +-------+------+---------------+------+---------+------+------+-------------+&lt;br /&gt;   | tblA  | ALL  | NULL          | NULL |    NULL | NULL | 1000 |             |&lt;br /&gt;   | tblB  | ALL  | NULL          | NULL |    NULL | NULL | 1000 | Using where |&lt;br /&gt;   | tblC  | ALL  | NULL          | NULL |    NULL | NULL | 1000 | Using where |&lt;br /&gt;   +-------+------+---------------+------+---------+------+------+-------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最后，在MySQL的手册中(&lt;a href="http://dev.mysql.com/doc/mysql/en/explain.html" target="_blank"&gt;7.2.1&lt;/a&gt;)：&lt;br /&gt;表以它们在处理查询过程中将被MySQL读入的顺序被列出。MySQL用一遍扫描多次联接（single-sweep multi-join）的方式解决所有联接。这意味着MySQL从第一个表中读一行，然后找到在第二个表中的一个匹配行，然后在第3个表中等等。当所有的表处理完后，它输出选中的列并且返回表清单直到找到一个有更多的匹配行的表。从该表读入下一行并继续处理下一个表。&lt;br /&gt;如手册所说的，MySQL读第一个表(tnlA)，然后第二个(tblB)，然后第三个(tblC)，像explain中输出的一样。先前的表中的值用来查找当前表中的行。在我们的例子中，tblA中的值用来找tblB中的匹配行，然后tblB的值来找tblC的行。当一个完整的扫描结束(在表tblA,tblB,tblC中找到了结果)，MySQL不会返回tblA,它到tblB中查看是否有更多的行匹配当前tblA的值。如果有，它拿出这一行，然后再在tblC中找匹配的。记住MySQL连接的基本原则是很重要的：先前的表中的值用来查找当前表中的行。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;按原理建索引&lt;/b&gt;&lt;br /&gt;&lt;p&gt;知道了MySQL使用从tblA中得到的值查找tblB中的行，我们需要怎么建索引来帮助MySQL？为此我们要知道它需要什么。考虑连接tblA和tblB：它们通过“tblA.col1 = tblB.col1”来连接。我们已经有了tblA.col1的值，所以MySQL需要一个tblB.col1的值来完成等值操作。因此如果MySQL需要tblB.col1，我们就在tblB.col1上加索引。加了之后，这是新的explain结果：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;   | table | type | possible_keys | key      | key_len | ref       | rows | Extra       |&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;   | tblA  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 |             |&lt;br /&gt;   | tblB  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col1 |    1 | Using where |&lt;br /&gt;   | tblC  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 | Using where |&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;如上，MySQL现在使用ndx_col1索引来连接tblB到tblA。就是说，当MySQL要找tblB中的行时，使用了ndx_col1索引通过tblA.col1的值直接得到匹配的行，而不是像以前需要做表扫描。这就是为什么tblB的ref列说“tablA.col1”。tblC现在还是用表扫描，这可以通过同样的方法解决。查看MySQL的需求：从sql中连接两表的语句“tblA.col2 = tblC.col1”可以看出它需要tblC.col1因为我们已经有了tblA.col2。给这一列加上索引之后explain：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;   | table | type | possible_keys | key      | key_len | ref       | rows | Extra       |&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;   | tblA  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 |             |&lt;br /&gt;   | tblB  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col1 |    1 | Using where |&lt;br /&gt;   | tblC  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col2 |    1 | Using where |&lt;br /&gt;   +-------+------+---------------+----------+---------+-----------+------+-------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;更复杂的查询&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;在实际中不会遇到刚才那种sql。所以你可能更想看看这样的：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   SELECT&lt;br /&gt;      COUNT(tblB.a_id) as correct,&lt;br /&gt;      tblA.type,&lt;br /&gt;      tblA.se_type&lt;br /&gt;   FROM&lt;br /&gt;      tblA,&lt;br /&gt;      tblB,&lt;br /&gt;      tblC,&lt;br /&gt;      tblD&lt;br /&gt;   WHERE&lt;br /&gt;          tblA.ex_id = tblC.ex_id&lt;br /&gt;      AND tblC.st_ex_id = tblB.st_ex_id&lt;br /&gt;      AND tblB.q_num = tblA.q_num&lt;br /&gt;      AND tblB.se_num = tblA.se_num&lt;br /&gt;      AND tblD.ex_id = tblA.ex_id&lt;br /&gt;      AND tblD.exp &lt;&gt; tblB.se_num&lt;br /&gt;      AND tblB.ans = tblA.ans&lt;br /&gt;      AND tblA.ex_id = 1001&lt;br /&gt;      AND tblC.r_id = 542&lt;br /&gt;   GROUP BY&lt;br /&gt;      tblA.type,&lt;br /&gt;      tblA.se_type;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;乍一看是很复杂的：有4个表，有聚合函数，有9个where条件，还有一个group by。explain的伟大之处在于我们现在可以忽略这些，每次只看两个表，判断每一步MySQL需要什么。这是一个实际的查询，只是字段名有一些改动。explain的结果：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+&lt;br /&gt;   | table | type   | possible_keys | key     | key_len | ref           | rows  | Extra                                        |&lt;br /&gt;   +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+&lt;br /&gt;   | tblA  | ALL    | NULL          | NULL    |    NULL | NULL          |  1080 | Using where; Using temporary; Using filesort |&lt;br /&gt;   | tblB  | ALL    | NULL          | NULL    |    NULL | NULL          | 87189 | Using where                                  |&lt;br /&gt;   | tblC  | eq_ref | PRIMARY       | PRIMARY |       4 | tblB.st_ex_id |     1 | Using where                                  |&lt;br /&gt;   | tblD  | eq_ref | PRIMARY       | PRIMARY |       4 | tblA.ex_id    |     1 | Using where                                  |&lt;br /&gt;   +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;判断连接影响的主要看结果集。结果集就是查询的结果。对于连接，一个估计结果集大小的方法是把MySQL预测的读取每个表的行数相乘。作为估计，这样做比较偏向于坏的情况，因为where条件通常会减少很多的行数。但这个查询的结果集有9400万行。这就是没有索引连接很危险的原因；几千行乘几千行你就会有一个上百万的结果集了。&lt;br /&gt;那么现在这个查询需要什么？从tblA和tblB开始。在sql中：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;AND tblB.q_num = tblA.q_num&lt;br /&gt;AND tblB.se_num = tblA.se_num&lt;br /&gt;AND tblB.ans = tblA.ans&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;MySQL至少需要q_num, se_num, ans中的一个。我选择在se_num和q_num上加索引因为在几乎所有其他的查询中我都会需要它们。折中是优化的一部分，多数人没有时间去为每一个查询找最优的索引方案，只能是找到一个对于大多数情况而言最优的方案。在tblB上加索引(se_num, q_num)，explain的结果：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;   | table | type   | possible_keys | key         | key_len | ref                    | rows | Extra                                        |&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;   | tblA  | ALL    | NULL          | NULL        |    NULL | NULL                   | 1080 | Using where; Using temporary; Using filesort |&lt;br /&gt;   | tblB  | ref    | ndx_secn_qn   | ndx_secn_qn |       2 | tblA.se_num,tblA.q_num |  641 | Using where                                  |&lt;br /&gt;   | tblC  | eq_ref | PRIMARY       | PRIMARY     |       4 | tblB.st_ex_id          |    1 | Using where                                  |&lt;br /&gt;   | tblD  | eq_ref | PRIMARY       | PRIMARY     |       4 | tblA.ex_id             |    1 | Using where                                  |&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;现在结果集下降了99.3%变为692280行。但为什么要停在这里？我们可以很容易的解决tblA的表扫描。因为它是第一个表，我们并不需要为连接加索引，这在tblB上已经做过了。一般来说，给第一个表加索引可以把它当成只在这一个表上查询的情况。在这个例子中很幸运，tblA是："AND tblA.ex_id = 1001"。我们只需要加ex_id索引：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;   | table | type   | possible_keys | key         | key_len | ref                    | rows | Extra                                        |&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;   | tblA  | ref    | ndx_ex_id     | ndx_ex_id   |       4 | const                  |    1 | Using where; Using temporary; Using filesort |&lt;br /&gt;   | tblB  | ref    | ndx_secn_qn   | ndx_secn_qn |       2 | tblA.se_num,tblA.q_num |  641 | Using where                                  |&lt;br /&gt;   | tblC  | eq_ref | PRIMARY       | PRIMARY     |       4 | tblB.st_ex_id          |    1 | Using where                                  |&lt;br /&gt;   | tblD  | eq_ref | PRIMARY       | PRIMARY     |       4 | tblA.ex_id             |    1 | Using where                                  |&lt;br /&gt;   +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;现在结果集是641行。相比开始的9400万，可以说了下降了100%。如果继续研究这个查询我们还可以去掉temp table和filesort，但现在查询已经很快了，也已经说明了如何为连接加索引。尽管最初看这个查询很麻烦，但可以看到只要每次独立的看两张表，为MySQL的需求加索引，整个过程并不困难。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;结论&lt;/b&gt;&lt;br /&gt;&lt;p&gt;为复杂的连接加索引要认识到两件事：&lt;br&gt;&lt;br /&gt;1. 不管sql多复杂，每次只看explain中的两个表&lt;br&gt;&lt;br /&gt;2. 先前表中的值已经有了，我们的工作就是通过索引帮助MySQL在当前表中使用这些值来找到匹配行&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-1352775810474172261?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://hackmysql.com/case4' title='在MySQL中如何为连接添加索引'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/1352775810474172261/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=1352775810474172261' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1352775810474172261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/1352775810474172261'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/mysql_5695.html' title='在MySQL中如何为连接添加索引'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3350335592392081648</id><published>2007-03-09T13:41:00.000+08:00</published><updated>2007-03-09T13:46:30.711+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Incorrect information in file 错误</title><content type='html'>更改了innodb的日志文件大小，即innodb_log_file_size的值，重启mysql之后对innodb的表都会报错：[ERROR] /usr/local/mysql/bin/mysqld: Incorrect information in file: './a/b.frm'。解决办法是修改其值后把日志文件ib_logfile删掉再启动mysql（请注意备份）。&lt;br /&gt;&lt;br /&gt;注：删log之前确保innodb_fast_shutdown的值不是2，如果是2则需要先改为1，然后重启使之生效，再关闭mysql删log文件。其默认值是1。&lt;br /&gt;&lt;br /&gt;参考：&lt;a href="http://dev.mysql.com/doc/refman/5.0/en/adding-and-removing.html"&gt;http://dev.mysql.com/doc/refman/5.0/en/adding-and-removing.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3350335592392081648?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3350335592392081648/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3350335592392081648' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3350335592392081648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3350335592392081648'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/incorrect-information-in-file.html' title='Incorrect information in file 错误'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-554509506910584368</id><published>2007-03-09T10:47:00.000+08:00</published><updated>2007-12-21T15:42:53.963+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>hackmysql</title><content type='html'>&lt;a class="ext-link" href="http://hackmysql.com/"&gt;&lt;span class="icon"&gt;&lt;/span&gt;http://hackmysql.com/&lt;/a&gt;&lt;br /&gt;mysql的一些工具，report, sniffer等&lt;br /&gt;其中mysqlsniffer使用下面的命令编译&lt;br /&gt;&lt;pre&gt;gcc -O2 -lpcap -o mysqlsniffer mysqlsniffer.c packet_handlers.c misc.c&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-554509506910584368?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/554509506910584368/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=554509506910584368' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/554509506910584368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/554509506910584368'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/hackmysql.html' title='hackmysql'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2966550392807623218</id><published>2007-03-07T15:07:00.000+08:00</published><updated>2007-03-07T15:08:09.978+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>union的性能</title><content type='html'>mysql的union操作是先做查询然后把结果集求并。union的过程中会使用到临时表，所以当结果集比较小时，union的速度比较快，5万的结果 集union all一次大约要1，2秒的时间，但如果是50万的结果集可能就要100秒了。因此如果结果集很大应该尽量避免使用union，尤其是union all，完全可以通过两次查询得到。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2966550392807623218?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2966550392807623218/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2966550392807623218' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2966550392807623218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2966550392807623218'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/union.html' title='union的性能'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3819124208449382088</id><published>2007-03-07T11:29:00.000+08:00</published><updated>2007-03-07T11:30:26.468+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>为MySQL添加帮助信息</title><content type='html'>在MySQL的网站上下载它提供的帮助文件，http://dev.mysql.com/doc/，MySQL Help Tables。&lt;br /&gt;然后直接导入到MySQL的系统数据库中&lt;br /&gt;mysql mysql &lt; file_name&lt;br /&gt;之后用MySQL自带client（就是mysql命令）连接就可以使用帮助，比如 &lt;pre&gt;mysql&gt; help create index&lt;br /&gt;Name: 'CREATE INDEX'&lt;br /&gt;Description:&lt;br /&gt;Syntax:&lt;br /&gt;CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name&lt;br /&gt;   [index_type]&lt;br /&gt;   ON tbl_name (index_col_name,...)&lt;br /&gt;&lt;br /&gt;index_col_name:&lt;br /&gt;   col_name [(length)] [ASC | DESC]&lt;br /&gt;&lt;br /&gt;index_type:&lt;br /&gt;   USING {BTREE | HASH}&lt;br /&gt;&lt;br /&gt;CREATE INDEX is mapped to an ALTER TABLE statement to create indexes.&lt;br /&gt;See [HELP ALTER TABLE]. For more information about indexes, see&lt;br /&gt;http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html.&lt;br /&gt;&lt;br /&gt;URL: http://dev.mysql.com/doc/refman/5.0/en/create-index.html&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3819124208449382088?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3819124208449382088/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3819124208449382088' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3819124208449382088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3819124208449382088'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/mysql.html' title='为MySQL添加帮助信息'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2904166339847376004</id><published>2007-03-06T16:32:00.001+08:00</published><updated>2007-03-06T16:32:24.601+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>建表要使记录尽可能小</title><content type='html'>建表的时候记录的长度越短越好，越短则IO操作越少，查询越快。&lt;br /&gt;能用int就不要用bigint，而如果能用tinyint是最好的。&lt;br /&gt;定义varchar时按照业务需要设置长度，不要一律varchar(255)，这样虽然并不会增加储存空间，但如以前提过的MySQL使用临时表是会把 varchar字段变成char，这样会增加临时表的大小，降低查询速度。同样的道理，对于不会使用utf8的字段（如：email, url），也不要用utf8的格式，因为MySQL必须为char(10)保留30个字节。&lt;br /&gt;用指明not null的时候也最好指明，这样也可以减少记录的长度。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2904166339847376004?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2904166339847376004/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2904166339847376004' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2904166339847376004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2904166339847376004'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/03/blog-post.html' title='建表要使记录尽可能小'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2721286903368158412</id><published>2007-02-28T15:26:00.000+08:00</published><updated>2007-02-28T15:27:22.320+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>导入数据时是否需要禁用索引</title><content type='html'>使用load data导入数据，如果导入的表是MyISAM的，对于空表，MySQL会把所有的非唯一索引进行一次独立的处理，而对于非空的表则会边插入边建索引。&lt;br /&gt;所以对于非空的MyISAM表，需要用alter table xxx disable keys禁用索引，导入完成之后再用alter table xxx enable keys打开。&lt;br /&gt;对于innodb，从测试的结果看无论表中是否已有记录，索引都是单独处理的，所以无需禁用索引。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2721286903368158412?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2721286903368158412/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2721286903368158412' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2721286903368158412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2721286903368158412'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/blog-post_28.html' title='导入数据时是否需要禁用索引'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7504809324547596626</id><published>2007-02-26T15:51:00.001+08:00</published><updated>2009-03-20T08:51:27.528+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>临时表过大</title><content type='html'>今天遇到一个这样的错误：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ERROR 126 (HY000): Incorrect key file for table '/tmp/#sql_dbd_0.MYI'; try to repair it&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;发现其原因是临时表太大了，而/tmp分区只有2G，放不下就报错了。&lt;br /&gt;sql是这样的：&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select promotion.promotion_id,&lt;br /&gt;      client.* ,&lt;br /&gt;      thanks.thanks_id,&lt;br /&gt;      thanks.thanks_type,&lt;br /&gt;      draft.draft_id,&lt;br /&gt;      rand() as s&lt;br /&gt;    from promotion, client, thanks, draft&lt;br /&gt;    where promotion.client_id = client.client_id&lt;br /&gt;      and promotion.promotion_id = thanks.promotion_id&lt;br /&gt;      and promotion.promotion_id = draft.promotion_id&lt;br /&gt;    order by s&lt;br /&gt;    limit 10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;如果把中间结果自己建一个临时表&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create temporary table tmp select ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;建出的表文件只有100M左右，那么为什么/tmp中会放不下呢？&lt;br /&gt;这是因为MySQL自己建的临时表都是静态行。如果使用下面的语句建表&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create temporary table tmp row_format=fixed select ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;会出现同样的错误了。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ERROR 126 (HY000): Incorrect key file for table '/tmp/#sqldbd_6bd_0.MYI'; try to repair it&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;所以这个问题有两个解决方法：&lt;br /&gt;1. 自己建临时表&lt;br /&gt;2. 加大临时目录。可以加大/tmp分区，也可以在启动MySQL时设置TMPDIR环境变量指定另外的临时目录&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7504809324547596626?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7504809324547596626/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7504809324547596626' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7504809324547596626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7504809324547596626'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/blog-post_26.html' title='临时表过大'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-7089057610067991322</id><published>2007-02-25T18:55:00.001+08:00</published><updated>2007-02-25T18:55:43.243+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL测试 一</title><content type='html'>做了一些简单的测试，以熟悉一些平时不用的命令。&lt;br /&gt;测试的环境：&lt;br /&gt;CPU：Intel(R) Xeon(R) CPU 3040  @ 1.86GHz X 2&lt;br /&gt;MEM: 1G&lt;br /&gt;HD: SATA 7200/m&lt;br /&gt;&lt;br /&gt;一张表，1130025数据，记录平均长61。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE `user` (&lt;br /&gt;  `id` int(11) NOT NULL auto_increment,&lt;br /&gt;  `name` varchar(40) default NULL,&lt;br /&gt;  `email` varchar(255) default NULL,&lt;br /&gt;  `address` varchar(255) default NULL,&lt;br /&gt;  `age` int(11) default NULL,&lt;br /&gt;  `regist_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_T&lt;br /&gt;  PRIMARY KEY  (`id`)&lt;br /&gt;) ENGINE=MyISAM AUTO_INCREMENT=1130026 DEFAULT CHARSET=utf8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;无其他索引。&lt;br /&gt;dump数据用mysqldump和select * into outfile用的时间都差不多，都是5秒。&lt;br /&gt;使用innodb时，导入数据用load data infile需要18秒左右，mysql &lt; user.sql需要30秒左右。&lt;br /&gt;user.sql中insert是一次插入15522个记录，用mysqldump -e（-e似乎是自动的，没发现怎么一个insert一个记录）自动分的，不知道为什么是这个数字。&lt;br /&gt;将innodb转成myisam用了8.35秒，转后使用的硬盘差不多，都是60M左右。&lt;br /&gt;然后用load data只用了9秒就把数据导入了。用mysql &lt; user.sql则是22秒。&lt;br /&gt;再把myisam转成innodb用了10.92秒，看来先用myisam导入再转innodb和直接用innodb导入使用的时间差不多。&lt;br /&gt;mysql的文档说导入myisam表时加大key_buffer_size可以提高导入的速度，我把该值从32M改成128M，速度没有变化。可能32M就已经足够了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-7089057610067991322?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/7089057610067991322/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=7089057610067991322' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7089057610067991322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/7089057610067991322'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/mysql.html' title='MySQL测试 一'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-9133993956542743561</id><published>2007-02-15T17:55:00.001+08:00</published><updated>2007-02-15T17:55:40.266+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>emacs的shell mode中使用 ansi color</title><content type='html'>(autoload &amp;#39;ansi-color-for-comint-mode-on &amp;quot;ansi-color&amp;quot; nil t)&lt;br&gt;(add-hook &amp;#39;shell-mode-hook &amp;#39;ansi-color-for-comint-mode-on)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-9133993956542743561?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/9133993956542743561/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=9133993956542743561' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9133993956542743561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/9133993956542743561'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/emacsshell-mode-ansi-color.html' title='emacs的shell mode中使用 ansi color'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-2823648981142471081</id><published>2007-02-09T09:16:00.000+08:00</published><updated>2007-02-08T15:01:29.417+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>有用的调试工具</title><content type='html'>truss, strace, ltrace。这三个工具都可以显示出程序运行的信息，虽然不能准确找到出错的地方，但可以提供一些线索。像unix中经常出现的segment fault就可以用它们试试。其中strace和ltrace在centos上可以直接用yum安装。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-2823648981142471081?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www-128.ibm.com/developerworks/cn/linux/l-tsl/' title='有用的调试工具'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/2823648981142471081/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=2823648981142471081' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2823648981142471081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/2823648981142471081'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/blog-post.html' title='有用的调试工具'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-5172119523807925517</id><published>2007-02-08T14:47:00.000+08:00</published><updated>2007-02-01T17:59:52.605+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL的datetime设置当前时间为默认值</title><content type='html'>由于MySQL目前字段的默认值不支持函数，所以以&lt;br /&gt;&lt;pre&gt;create_time datetime default now()&lt;/pre&gt;&lt;br /&gt;的形式设置默认值是不可能的。&lt;br /&gt;&lt;br /&gt;代替的方案是使用TIMESTAMP类型代替DATETIME类型。&lt;br /&gt;&lt;br /&gt;TIMESTAMP列类型自动地用当前的日期和时间标记INSERT或UPDATE的操作。 &lt;br /&gt;如果有多个TIMESTAMP列，只有第一个自动更新。   &lt;br /&gt;自动更新第一个TIMESTAMP列在下列任何条件下发生：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;列值没有明确地在一个INSERT或LOAD  DATA  INFILE语句中指定。 &lt;/li&gt;&lt;br /&gt;&lt;li&gt;列值没有明确地在一个UPDATE语句中指定且另外一些的列改变值。（注意一个UPDATE设置一个列为它已经有的值，这将不引起TIMESTAMP列被更新，因为如果你设置一个列为它当前的值，MySQL为了效率而忽略更改。）&lt;/li&gt;&lt;br /&gt;&lt;li&gt;你明确地设定TIMESTAMP列为NULL. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;除第一个以外的TIMESTAMP列也可以设置到当前的日期和时间，只要将列设为NULL，或NOW()。&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;另外在5.0以上版本中也可以使用trigger来实现此功能。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create table test_time (&lt;br /&gt; id int(11),&lt;br /&gt; create_time datetime&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;delimiter |&lt;br /&gt;&lt;br /&gt;create trigger default_datetime before insert on test_time&lt;br /&gt;  for each row&lt;br /&gt;     if new.create_time is null then&lt;br /&gt;       set new.create_time = now();&lt;br /&gt;     end if;|&lt;br /&gt;&lt;br /&gt;delimiter ;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-5172119523807925517?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/5172119523807925517/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=5172119523807925517' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5172119523807925517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/5172119523807925517'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/mysqldatetime.html' title='MySQL的datetime设置当前时间为默认值'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-3006028673636164482</id><published>2007-02-01T13:44:00.001+08:00</published><updated>2007-02-01T13:45:48.274+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>小心使用MySQL中的in</title><content type='html'>在MySQL中，where语句里使用&lt;br /&gt;&lt;pre&gt;(A,B) in ((X1,Y1),(X2,Y2))&lt;/pre&gt;&lt;br /&gt;如果没有(A,B)的索引，而只有A或B上的索引，则此索引不会被使用。&lt;br /&gt;所以类似&lt;br /&gt;&lt;pre&gt;select * from t1, t2 where (t1.a, t2.b) in ((1,2),(2,3))&lt;/pre&gt;&lt;br /&gt;的语句是无法使用a,b上的索引的，应该改为&lt;br /&gt;&lt;pre&gt;select * from t1, t2 where  (t1.a = 1 and t2.b = 2) or (t1.a = 2 and t2.b = 3)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-3006028673636164482?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/3006028673636164482/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=3006028673636164482' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3006028673636164482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/3006028673636164482'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/02/mysqlin_01.html' title='小心使用MySQL中的in'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-6810864859777539281</id><published>2007-01-16T19:13:00.000+08:00</published><updated>2007-01-16T19:28:00.838+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>ssh agent</title><content type='html'>今天终于知道 putty 的 Pageant.exe 是干什么的了。&lt;br /&gt;假设本机上有私钥可以登录A和B。而B只有内网 ip，不能直接连，以前的做法是把私钥放到A上或者用A做代理。而用了 pageant 之后就无需在A上放私钥也可以从A连接到B。&lt;br /&gt;步骤如下：&lt;br /&gt;1. 运行 pageant&lt;br /&gt;2. 在 pageant 中加入使用的私钥&lt;br /&gt;3. 在 putty 的A的连接设置 auth 中把“Allow agent forwarding”选中&lt;br /&gt;4. 用 putty 连接A&lt;br /&gt;5. 然后直接在A的 shell 中输入 ssh B 就可以连接到 B 了&lt;br /&gt;这样当要连接的内网机器比较多的时候很方便，不需要把私钥到处放了&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-6810864859777539281?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/6810864859777539281/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=6810864859777539281' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6810864859777539281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/6810864859777539281'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/01/ssh-agent.html' title='ssh agent'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-67162608409683450</id><published>2007-01-10T15:52:00.000+08:00</published><updated>2007-01-10T16:33:49.915+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mod_perl'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>HTTP的状态码</title><content type='html'>今天有一个比较特殊的需求。在mod_perl中根据情况返回不同的状态码200和203，但都需要返回一张图片作为内容。本来是需要返回200和204的，但发现返回204的时候浏览器根本就不会显示内容。所以考虑返回203，这时候是可以正常显示的。&lt;br /&gt;但是在mod_perl中自定义状态码一般写成&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sub handler {&lt;br /&gt;my $r = shift;&lt;br /&gt;$r-&gt;custom_response(Apache2::Const::HTTP_NON_AUTHORITATIVE, $gif);&lt;br /&gt;return Apache2::Const::HTTP_NON_AUTHORITATIVE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;$gif中是图片的内容，现在的问题是这样写头部中的content type不能自己设置，始终是text/html，导致不能正常显示。即使加上&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$r-&gt;content_type("image/gif");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;也没有效果，似乎返回不是Apache2::Const::OK时，这些设置都被忽略了。如果不用custom_response，直接print图片的内容，返回的状态码又会自动变成200，好像只要有输出就自动设成200了。&lt;br /&gt;弄了半天，也没有发现有什么API能够直接更改返回的状态码。无奈，后来发现custom_response的第二个参数还可以用文件名，想着用文件名apache应该可以根据扩展名判断文件类型，可以一试。结果果然如此。&lt;br /&gt;函数调用改成&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$r-&gt;custom_response(Apache2::Const::HTTP_NON_AUTHORITATIVE, '/images/t.gif');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;然后配置文件设置好扩展名的对应&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;AddType image/gif .gif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;就可以了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;附HTTP的状态码，从Apache2::Const中抓出来的。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;HTTP_CONTINUE:                       100&lt;br /&gt;HTTP_SWITCHING_PROTOCOLS:            101&lt;br /&gt;HTTP_PROCESSING:                     102&lt;br /&gt;HTTP_OK:                             200&lt;br /&gt;HTTP_CREATED:                        201&lt;br /&gt;HTTP_ACCEPTED:                       202&lt;br /&gt;HTTP_NON_AUTHORITATIVE:              203&lt;br /&gt;HTTP_NO_CONTENT:                     204&lt;br /&gt;HTTP_RESET_CONTENT:                  205&lt;br /&gt;HTTP_PARTIAL_CONTENT:                206&lt;br /&gt;HTTP_MULTI_STATUS:                   207&lt;br /&gt;HTTP_MULTIPLE_CHOICES:               300&lt;br /&gt;HTTP_MOVED_PERMANENTLY:              301&lt;br /&gt;HTTP_MOVED_TEMPORARILY:              302&lt;br /&gt;HTTP_SEE_OTHER:                      303&lt;br /&gt;HTTP_NOT_MODIFIED:                   304&lt;br /&gt;HTTP_USE_PROXY:                      305&lt;br /&gt;HTTP_TEMPORARY_REDIRECT:             307&lt;br /&gt;HTTP_BAD_REQUEST:                    400&lt;br /&gt;HTTP_UNAUTHORIZED:                   401&lt;br /&gt;HTTP_PAYMENT_REQUIRED:               402&lt;br /&gt;HTTP_FORBIDDEN:                      403&lt;br /&gt;HTTP_NOT_FOUND:                      404&lt;br /&gt;HTTP_METHOD_NOT_ALLOWED:             405&lt;br /&gt;HTTP_NOT_ACCEPTABLE:                 406&lt;br /&gt;HTTP_PROXY_AUTHENTICATION_REQUIRED:  407&lt;br /&gt;HTTP_REQUEST_TIME_OUT:               408&lt;br /&gt;HTTP_CONFLICT:                       409&lt;br /&gt;HTTP_GONE:                           410&lt;br /&gt;HTTP_LENGTH_REQUIRED:                411&lt;br /&gt;HTTP_PRECONDITION_FAILED:            412&lt;br /&gt;HTTP_REQUEST_ENTITY_TOO_LARGE:       413&lt;br /&gt;HTTP_REQUEST_URI_TOO_LARGE:          414&lt;br /&gt;HTTP_UNSUPPORTED_MEDIA_TYPE:         415&lt;br /&gt;HTTP_RANGE_NOT_SATISFIABLE:          416&lt;br /&gt;HTTP_EXPECTATION_FAILED:             417&lt;br /&gt;HTTP_UNPROCESSABLE_ENTITY:           422&lt;br /&gt;HTTP_LOCKED:                         423&lt;br /&gt;HTTP_FAILED_DEPENDENCY:              424&lt;br /&gt;HTTP_UPGRADE_REQUIRED:               426&lt;br /&gt;HTTP_INTERNAL_SERVER_ERROR:          500&lt;br /&gt;HTTP_NOT_IMPLEMENTED:                501&lt;br /&gt;HTTP_BAD_GATEWAY:                    502&lt;br /&gt;HTTP_SERVICE_UNAVAILABLE:            503&lt;br /&gt;HTTP_GATEWAY_TIME_OUT:               504&lt;br /&gt;HTTP_VARIANT_ALSO_VARIES:            506&lt;br /&gt;HTTP_INSUFFICIENT_STORAGE:           507&lt;br /&gt;HTTP_NOT_EXTENDED:                   510&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-67162608409683450?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/67162608409683450/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=67162608409683450' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/67162608409683450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/67162608409683450'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2007/01/http.html' title='HTTP的状态码'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116723733205420494</id><published>2006-12-28T00:34:00.000+08:00</published><updated>2006-12-28T00:35:32.056+08:00</updated><title type='text'>地震的后果</title><content type='html'>一场地震断了光纤无数，今天MSN和SKYPE都连不上了。据“专家”说修复要一个月的时间，要换用QQ了。估计类似情况的人不少，马化腾爽啊。一年没用密码都忘记了，折腾了半天才能登录。唉，微软也真是，中国那么多人居然连一台服务器都不搬过来。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116723733205420494?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116723733205420494/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116723733205420494' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116723733205420494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116723733205420494'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/blog-post_28.html' title='地震的后果'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116719034255775539</id><published>2006-12-27T11:32:00.000+08:00</published><updated>2006-12-27T11:32:22.563+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>日文字符匹配</title><content type='html'>&lt;!-- Converted from text/plain format --&gt; &lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT  size=2&gt;以前程序用的EUC编码，在页面输入做检查时，使用的都是EUC的字符编码范围。主要是匹配全角カタカナ  (?:\xA5[\xA1-\xF6]|\xA1[\xA6\xBC\xB3\xB4]) 和全角空格 (?:\xA1\xA1)。&lt;/FONT&gt;&lt;/P&gt; &lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT  size=2&gt;现在程序改为UTF-8的了，再用上面的方式会很麻烦，需要把输入转成EUC再做。perl的正则表达式支持Unicode的属性，看上去用起来比直接写编码范围要清楚多了。全角カタカナ可以用  \p{Katakana}。而空格可以用 \p{IsSpace}，它包括\n,\t等，如果只是匹配空白可以用  \p{IsZs}。&lt;/FONT&gt;&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116719034255775539?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116719034255775539/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116719034255775539' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116719034255775539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116719034255775539'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/blog-post_27.html' title='日文字符匹配'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116713794119267943</id><published>2006-12-26T20:54:00.000+08:00</published><updated>2006-12-26T20:59:01.193+08:00</updated><title type='text'>暂时换个地方</title><content type='html'>最近更新的时候总是失败，sitesled不能访问了。难以忍受了，正好现在blogspot解封了，再转回来。用了那么长时间sitesled，blogspot上的域名也没有了，想到的几个一看都是些没有什么东西又不更新的，唉。试了半天终于有个能用了。&lt;br /&gt;&lt;a href="http://qroom.blogspot.com"&gt;http://qroom.blogspot.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116713794119267943?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116713794119267943/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116713794119267943' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116713794119267943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116713794119267943'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/blog-post.html' title='暂时换个地方'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116675929872921412</id><published>2006-12-22T11:47:00.000+08:00</published><updated>2006-12-22T11:48:18.746+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>perl 代码优化 - 查找需要优化的部分</title><content type='html'>做代码优化首先要知道程序各部分的速度，什么地方最慢，最需要优化。&lt;br /&gt;下面有几种方法可以用于调查程序各部分的速度。&lt;br /&gt;&lt;br /&gt;1. time&lt;br /&gt;&lt;br /&gt;shell&gt;time perl script.pl&lt;br /&gt;&lt;br /&gt;这样可以得到程序的运行时间。&lt;br /&gt;&lt;br /&gt;2. Time::HiRes&lt;br /&gt;使用模块Time::HiRes中的函数gettimeofday，gettimeofday&lt;br /&gt;例：&lt;br /&gt;&lt;br /&gt;for (xxx) {&lt;br /&gt;# code 1&lt;br /&gt;    $t0 = [gettimeofday];&lt;br /&gt;# code 2&lt;br /&gt;    $elapsed = tv_interval ( $t0 );&lt;br /&gt;    $t += $slapsed;&lt;br /&gt;# code 3&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;这样$t中就是代码段code 2在程序中执行总共需要的时间。这个结果是精确到微秒的。&lt;br /&gt;&lt;br /&gt;3. Devel::DProf&lt;br /&gt;&lt;br /&gt;# test.pl&lt;br /&gt;sub d {&lt;br /&gt;print 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub g{&lt;br /&gt;print 1 for 1..10;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub f {&lt;br /&gt;print 2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;for (1..10000){&lt;br /&gt;d();&lt;br /&gt;g();&lt;br /&gt;f();&lt;br /&gt;g();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# script end&lt;br /&gt;&lt;br /&gt;shell&gt;perl -d:DProf test.pl&lt;br /&gt;shell&gt;dprofpp&lt;br /&gt;Total Elapsed Time = 0.289990 Seconds&lt;br /&gt;  User+System Time = 0.269990 Seconds&lt;br /&gt;Exclusive Times&lt;br /&gt;%Time ExclSec CumulS #Calls sec/call Csec/c  Name&lt;br /&gt; 85.1   0.230  0.230  20000   0.0000 0.0000  main::g&lt;br /&gt; 14.8   0.040  0.040  10000   0.0000 0.0000  main::f&lt;br /&gt; 11.1   0.030  0.030  10000   0.0000 0.0000  main::d&lt;br /&gt;&lt;br /&gt;4. Devel::SmallProf&lt;br /&gt;shell&gt;perl -d:SmallProf  test.pl&lt;br /&gt;&lt;br /&gt;shell&gt;cat smallprof.out&lt;br /&gt;           ================ SmallProf version 1.15 ================&lt;br /&gt;                                Profile of a.pl                        Page 1&lt;br /&gt;       =================================================================&lt;br /&gt;    count wall tm  cpu time line&lt;br /&gt;    10000 0.000000 0.000000     1:sub d {&lt;br /&gt;    10000 0.062426 0.090000     2:print 1;&lt;br /&gt;        0 0.000000 0.000000     3:}&lt;br /&gt;        0 0.000000 0.000000     4:&lt;br /&gt;    20000 0.000000 0.000000     5:sub g{&lt;br /&gt;    40000 0.390327 0.550000     6:print 1 for 1..10;&lt;br /&gt;        0 0.000000 0.000000     7:}&lt;br /&gt;        0 0.000000 0.000000     8:&lt;br /&gt;    10000 0.000000 0.000000     9:sub f {&lt;br /&gt;    10000 0.061660 0.100000    10:print 2;&lt;br /&gt;        0 0.000000 0.000000    11:}&lt;br /&gt;        0 0.000000 0.000000    12:&lt;br /&gt;        1 0.000006 0.000000    13:for (1..10000){&lt;br /&gt;    10000 0.036328 0.090000    14:d();&lt;br /&gt;    10000 0.037353 0.160000    15:g();&lt;br /&gt;    10000 0.038129 0.220000    16:f();&lt;br /&gt;    10000 0.038368 0.150000    17:g();&lt;br /&gt;        0 0.000000 0.000000    18:}&lt;br /&gt;        0 0.000000 0.000000    19:&lt;br /&gt;&lt;br /&gt;shell&gt;sort -k 2nr,2 smallprof.out&lt;br /&gt;    40000 0.390327 0.550000     6:print 1 for 1..10;&lt;br /&gt;    10000 0.062426 0.090000     2:print 1;&lt;br /&gt;    10000 0.061660 0.100000    10:print 2;&lt;br /&gt;    10000 0.038368 0.150000    17:g();&lt;br /&gt;    10000 0.038129 0.220000    16:f();&lt;br /&gt;    10000 0.037353 0.160000    15:g();&lt;br /&gt;    10000 0.036328 0.090000    14:d();&lt;br /&gt;        1 0.000006 0.000000    13:for (1..10000){&lt;br /&gt;       =================================================================&lt;br /&gt;        0 0.000000 0.000000    11:}&lt;br /&gt;        0 0.000000 0.000000    12:&lt;br /&gt;        0 0.000000 0.000000    18:}&lt;br /&gt;        0 0.000000 0.000000    19:&lt;br /&gt;        0 0.000000 0.000000     3:}&lt;br /&gt;        0 0.000000 0.000000     4:&lt;br /&gt;        0 0.000000 0.000000     7:}&lt;br /&gt;        0 0.000000 0.000000     8:&lt;br /&gt;    10000 0.000000 0.000000     1:sub d {&lt;br /&gt;    10000 0.000000 0.000000     9:sub f {&lt;br /&gt;    20000 0.000000 0.000000     5:sub g{&lt;br /&gt;    count wall tm  cpu time line&lt;br /&gt;                                Profile of a.pl                        Page 1&lt;br /&gt;           ================ SmallProf version 1.15 ================&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;程序改进之后如果想知道效果如何，可以使用模块Benchmark。&lt;br /&gt;例:&lt;br /&gt;&lt;br /&gt;use Benchmark qw/timethse/;&lt;br /&gt;timethese($count, {&lt;br /&gt;    'before' =&gt; sub { ...code1... },&lt;br /&gt;    'after'    =&gt; sub { ...code2... },&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;上面这些模块的详细说明见各自的文档。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116675929872921412?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116675929872921412/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116675929872921412' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116675929872921412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116675929872921412'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/perl.html' title='perl 代码优化 - 查找需要优化的部分'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116620278524742727</id><published>2006-12-16T01:13:00.000+08:00</published><updated>2006-12-26T16:57:54.153+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MySQL性能优化 - 参数调整</title><content type='html'>&lt;p&gt;无聊中，看到一片MySQL的文件，觉得不错，就翻译了一下，没想到用了1个多小时，好长啊。&lt;/p&gt; &lt;p&gt;原文：&lt;a title="http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/" href="http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/"&gt;http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;我喜欢问别人在安装了MySQL之后，其默认的配置应该怎么改。但令人惊讶的是很多人都无法给出一个合理的理由。虽然MySQL有许多可以调整的变量，但对于大多数的情况它们中只有少数有用。只要把这几个设好了，其他的对于多数情况只能起到锦上添花的作用。 &lt;/p&gt; &lt;p&gt;&lt;strong&gt;key_buffer_size&lt;/strong&gt;&lt;br&gt;如果用MyISAM则非常重要。如果只用MyISAM表，那么设成可用内存的30%到40%。主要决定于索引的数量，数据的多少和读写量。要知道MyISAM是用系统的缓存来缓存数据的，而数据通常比索引大很多，所以你需要留一部分内存给系统。记得检查是否所有的key_buffer都被用到，经常看到有人把它设成4G，而所有的MYI文件加起来才1G（4G呀，看到的次数还不少，真是羡慕。内存不是这么浪费的）。如果用的MySIAM表很少，那么可以把它设得比较少，但至少要有16-32M，提供给创建的临时表的索引用。  &lt;p&gt;&lt;strong&gt;innodb_buffer_pool_size&lt;br&gt;&lt;/strong&gt;如果用Innodb，那么这是一个重要变量。相对于MyISAM来说，Innodb对于buffer size更敏感。MySIAM可能对于大数据量使用默认的key_buffer_size也还好，但Innodb在大数据量时用默认值就感觉在爬了。Innodb的缓冲池会缓存数据和索引，所以不需要给系统的缓存留空间，如果只用Innodb，可以把这个值设为内存的70%-80%。和key_buffer相同，如果数据量比较小也不怎么增加，那么不要把这个值设太高也可以提高内存的使用率。  &lt;p&gt;&lt;strong&gt;innodb_additional_pool_size&lt;/strong&gt;&lt;br&gt;这个的效果不是很明显，至少是当操作系统能合理分配内存时。但你可能仍需要设成20M或更多一点以看Innodb会分配多少内存做其他用途。  &lt;p&gt;&lt;strong&gt;innodb_log_file_size&lt;br&gt;&lt;/strong&gt;对于写很多尤其是大数据量时非常重要。要注意，大的文件提供更高的性能，但数据库恢复时会用更多的时间。我一般用64M-512M，具体取决于服务器的空间。  &lt;p&gt;&lt;strong&gt;innodb_log_buffer_size&lt;/strong&gt;&lt;br&gt;默认值对于多数中等写操作和事务短的运用都是可以的。如果经常做更新或者使用了很多blob数据，应该增大这个值。但太大了也是浪费内存，因为1秒钟总会flush（这个词的中文怎么说呢？）一次，所以不需要设到超过1秒的需求。8M-16M一般应该够了。小的运用可以设更小一点。  &lt;p&gt;&lt;strong&gt;innodb_flush_log_at_trx_commit&lt;/strong&gt;&lt;br&gt;抱怨Innodb比MyISAM慢100倍？那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入（flush）硬盘，这是很费时的。特别是使用电池供电缓存（Battery backed up cache）时。设成2对于很多运用，特别是从MyISAM表转过来的是可以的，它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘，所以你一般不会丢失超过1-2秒的更新。设成0会更快一点，但安全方面比较差，即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统挂了时才可能丢数据。  &lt;p&gt;&lt;strong&gt;table_cache&lt;/strong&gt;&lt;br&gt;打开表的操作代价很高。比如MyISAM表标记MYI头部来标记表在使用中。你不会希望频繁进行此操作，所以最好设置缓存使得能够保存大部分打开的表。它会用到一些系统资源和内存，但对于现在的硬件来说不是问题。对于200个表的运用1024比较好。如果你的连接数多，或者表多则再大一些。我见过超过100000的。  &lt;p&gt;&lt;strong&gt;thread_cache&lt;/strong&gt;&lt;br&gt;建立连接和断开时的线程的创建和死亡开销很大。我一般把它设为至少16。如果程序中有大量并发连接，而变量Threads_Created（status中可以看到）长得很快，那么会设大一些。主要是让正常操作中不要去创建线程。  &lt;p&gt;&lt;strong&gt;query_cache&lt;/strong&gt;&lt;br&gt;如果你的程序有大量的读操作而又没有程序级的缓存，那么把它设大一点应该有很大的帮助。但设得太大会减慢速度因为维护的开销很大。32M-512M就可以了。设过之后检查一下是否运行良好。For certain workloads cache hit ratio is lower than would justify having it enabled.（这句看不懂，我怀疑他写错了。一般来说，如果hit ratio比较低说明cache还不够大，可以适当的增加）  &lt;p&gt;注意：这些都是一些全局变量。它们依赖于硬件和存储引擎，而session的变量更偏重于负荷。如果你只做简单的查询，那么即使你有64G的内存可以浪费也没理由要增加sort_buffer_size。而且这样还可能会降低性能。我一般会把session变量的调整放到第二步，在弄清了负荷以后。  &lt;p&gt;另外MySQL提供的my.cnf的样例不错，可以拿来改改了用。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116620278524742727?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/' title='MySQL性能优化 - 参数调整'/><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116620278524742727/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116620278524742727' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116620278524742727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116620278524742727'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/mysql.html' title='MySQL性能优化 - 参数调整'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116599449246497162</id><published>2006-12-13T15:18:00.000+08:00</published><updated>2006-12-13T15:21:32.476+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>〜 and ～</title><content type='html'>今天发现从utf8到shift-jis转换。&lt;br /&gt;〜和～，这两个波浪线是有区别的。前者可以转成shift-jis的～，而后者会出现乱码。&lt;br /&gt;真是麻烦的编码呀。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116599449246497162?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116599449246497162/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116599449246497162' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116599449246497162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116599449246497162'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/and.html' title='〜 and ～'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116556276582512099</id><published>2006-12-08T15:26:00.000+08:00</published><updated>2006-12-08T15:26:05.903+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>用反向代理访问catalyst时的问题</title><content type='html'>&lt;p&gt;由于测试需要，catalyst的服务器前有两个反向代理，像这样：&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;user-&amp;gt;A-&amp;gt;B-&amp;gt;Catalyst Server&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;这样的结构当使用uri_for的时候，拼接出来的url可能就会变成“http://A,%20B/....”。这是因为catalyst从apache的X-Forwarded-Host中（Catalyst/Engine/Apache.pm）得到真正的地址，而通过两次代理之后，这个变量中存了A和B的地址。因此会出现这种情况。&lt;/p&gt; &lt;p&gt;另外这个pm中也可以看到，用代理的时候，如果不改cayalyst的代码，前端的端口只能用80或443，否则uri_for这种内部生成url的函数都不会生成正确的端口。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116556276582512099?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116556276582512099/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116556276582512099' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116556276582512099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116556276582512099'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/catalyst.html' title='用反向代理访问catalyst时的问题'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19262010.post-116498566019544860</id><published>2006-12-01T23:07:00.000+08:00</published><updated>2006-12-01T23:07:40.273+08:00</updated><title type='text'>Total Commander</title><content type='html'>smth版上组织TC的团购，一个许可150，想想也不算太贵，于是买了一个。今天终于收到key了，小小激动一把。 &lt;p&gt;自从工作之后，受到环境的影响，用软件渐渐向免费的靠拢。有个同事号称freeware master，我虽然还不能达到那种境界，但基本上都换成了免费的。像写文档用openoffice，写程序用emacs，画图用gimp，杀毒用AVG，解压缩用7zip，辞典用stardict（这个好像辞典开始收费了，准备快成lingoes了）。但TC这个用了一次之后就每次开机都常驻的软件却始终找不到一个好的替代品，趁这个机会也就向作者贡献了一下。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19262010-116498566019544860?l=qroom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qroom.blogspot.com/feeds/116498566019544860/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19262010&amp;postID=116498566019544860' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116498566019544860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19262010/posts/default/116498566019544860'/><link rel='alternate' type='text/html' href='http://qroom.blogspot.com/2006/12/total-commander.html' title='Total Commander'/><author><name>jedy</name><uri>http://www.blogger.com/profile/04289869955957083884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
