MySQL Storage Engine 小记

这段时间在看《High Performance MySQL》,看到存储引擎这个地方感到很多细节比较陌生,所以总结小记一些

为了适应各种不同的运行环境,MYSQL提供了多种不同的存储引擎(Storage Engine ),在应用程序开发这个层面上,开发者可以根据不同的需求选择适合的Storage Engine 方案,更为灵活的是,你可以根据每张表将要存储数据的特点,选择不同的Storage Engine,也就是说,在一个MYSQL数据库中,可以混合使用多种不同的Storage Engine

首先小瞥一下MySQL的体系结构,在最高抽象层度下,可以用Garlan & Shaw的分层结构体系来表示(左)

其中应用层为所有RDBMS用户提供用户接口,逻辑层包括了所有核心功能的实现,物理层则负责将数据存储在硬件设备上。

图中右侧更为具体的描述了逻辑层的组成,查询处理子系统、事务管理子系统、恢复管理子系统和存储管理子系统共同组成了MySQL的逻辑层。相信Storage Engine的位置是在Storage Management处,既Storage Engine属于Storage Management子系统的一部分

为了让思路更清晰一些,下面给出一幅比较全面的体系结构图(或更确切的说是流程图,只是忽略了反馈)

上面三幅图来自于一篇非官方(不保证百分百的正确)的MySQL体系结构的报告,与《High Performance MySQL》一书中给出的MySQL大体结构(下图,基本对应于Logic Layer,从第一幅图右侧可以看出MySQL logic layer同样遵从分层体系结构)还是比较吻合的。

连接上图中第二层和第三层之间的接口是并不针对任何存储引擎的单一API,.大概由20个基本的类似“启动事务,返回结果集”等函数组成。存储引擎并不处理SQL,相互之间也不通信,它们的任务只是简单的响应高层传来的请求。

存储引擎各自的一些特点

上面提到的四种存储引擎都有各自适用的环境,这取决于它们独有的一些特征。主要体现在性能、事务、并发控制、参照完整性、缓存、 故障恢复,备份及回存等几个方面


目前比较普及的存储引擎是MyISAM和InnoDB.而MyISAM又是绝大部分Web应用的首选。MyISAM与InnoDB的主要的不同点在于性能和事务控制上。

MyISAM是早期ISAM(Indexed Sequential Access Method,我现在用的MySQL5.0已经不支持ISAM了)的扩展实现,ISAM被设计为适合处理读频率远大于写频率这样一种情况,因此ISAM以及后来的MyISAM都没有考虑对事物的支持,排除了TPM,不需要事务记录,ISAM的查询效率相当可观,而且内存占用很少。MyISAM在继承了这类优点的同时,与时俱进的提供了大量实用的新特性和相关工具。例如考虑到并发控制,提供了表级锁,虽然MyISAM本身不支持容错,但可以通过myisamchk进行故障恢复。而且由于MyISAM是每张表使用各自独立的存储文件(MYD数据文件和MYI索引文件),使得备份及恢复十分方便(拷贝覆盖即可),而且还支持在线恢复。

所以如果你的应用是不需要事务,处理的只是基本的CRUD操作,那么MyISAM是不二选择

InnoDB被设计成适用于高并发读写的情况.使用MVCC(Multi-Version Concurrency Control)以及行级锁来提供遵从ACID的事务支持。InnoDB支持外键参照完整性,具备故障恢复能力。另外 InnoDB的性能其实还是不错的,特别是在处理大数据量的情况下,用官方的话说就是: InnoDB的CPU效率是其他基于磁盘的关系数据库存储引擎所不能比的。不过InnoDB的备份恢复要麻烦一点,除非你使用了4.1以后版本提供的Mulit-tablespace支持,因为InnoDB和MyISAM不同,他的数据文件并不是独立对应于每张表的。而是使用的共享表空间,简单的拷贝覆盖方法对他不适用,必须在停掉MYSQL后对进行数据恢复。使用Per-Table Tablespacesd,使其每张表对应一个独立的表空间文件,则情况要简单很多。

一般来说,如果需要事务支持,并且有较高的并发读写频率,InnoDB是不错的选择。要是并发读写频率不高的话,其实可以考虑BDB,但由于在MySQL5.1及其以后版本中,将不再提供BDB支持。这个选项也就没有了

至于Heap和BDB(Berkeley DB),相对来说,普及率不如前两种,但在有些情况下,还是挺适用的

Heap存储引擎就是将数据存储在内存中,由于没有磁盘I./O的等待,速度极快。但由于是内存存储引擎,所做的任何修改在服务器重启后都将消失。
 
Heap挺适合做测试的时候使用


BDB是MySQL第一款事务安全的存储引擎。在Berkeley DB database library的基础上建立,同样是事务安全的,但BDB的普及率显然不及InnoDB,因为大多数在MySQL中寻找支持事务的存储引擎的同时也在找支持MVCC或是行级锁定存储引擎,而BDB只支持Page-level Lock。


 


 


附上一张《High Performance MySQL》 中的各存储引擎的特性表

































































Attribute


MyISAM


Heap


BDB


InnoDB


Transactions


No


No


Yes


Yes


Lock granularity


Table


Table


Page (8 KB)


Row


Storage


Split files


In-memory


Single file per table


Tablespace(s)


Isolation levels


None


None


Read committed


All


Portable format


Yes


N/A


No


Yes


Referential integrity


No


No


No


Yes


Primary key with data


No


No


Yes


Yes


MySQL caches data records


No


Yes


Yes


Yes


Availability


All versions


All versions


MySQL-Max


All Versions


 


Maven… 它是什么?





1.1. Maven… 它是什么?


如何回答这个问题要看你怎么看这个问题。 绝大部分Maven用户都称Maven是一个”构建工具”:一个用来把源代码构建成可发布的构件的工具。 构建工程师和项目经理会说Maven是一个更复杂的东西:一个项目管理工具。那么区别是什么? 像Ant这样的构建工具仅仅是关注预处理,编译,打包,测试和分发。像 Maven 这样的一个项目管理工具提供了构建工具所提供功能的超集。 除了提供构建的功能,Maven还可以生成报告,生成Web站点,并且帮助推动工作团 队成员间的交流。


一个更正式的 Apache Maven 的定义: Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。 当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后 Maven 可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。


别让Maven是一个”项目管理”工具的事实吓跑你。如果你只是在找一个构建工具,Maven能做这个工作。 事实上,本书的一些章节将会涉及使用Maven来构建和分发你的项目。






1.2. 约定优于配置(Convention Over Configuration)


约定优于配置是一个简单的概念。 系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置。 流行的框架如 Ruby on RailsEJB3 已经开始坚持这些原则,以对像原始的 EJB 2.1 规范那样的框架的配置复杂度做出反应。 一个约定优于配置的例子就像 EJB3 持久化,将一个 特殊的Bean持久化,你所需要做的只是将这个类标注为 @Entity 。 框架将会假定表名和列名是基于类名是属性名。 系统也提供了一些钩子,当有需要的时候你可以重写这些名字,但是,在大部分情况下,你会发现使用框架提供的默认值会让你的项目运行的更快。


Maven通过给项目提供明智的默认行为来融合这个概念。 在没有自定义的情况下,源代码假定是在 ${basedir}/src/main/java,资源文件假定是在 ${basedir}/src/main/resources 。测试代码假定是在 ${basedir}/src/test 。项目假定会产生一个 JAR 文件。Maven 假定你想要把编译好的字节码放到 ${basedir}/target/classes 并且在 ${basedir}/target 创建一个可分发的 JAR 文件。 虽然这看起来无关紧要,但是想想大部分基于 Ant 的构建必须为每个子项目定义这些目录。 Maven 对约定优于配置的应用不仅仅是简单的目录位置,Maven 的核心插件使用了一组通用的约定,以用来编译源代码,打包可分发的构件,生成 web 站点,还有许多其他的过程。 Maven 的力量来自它的”武断”,它有一个定义好的生命周期和一组知道如何构建和装配软件的通用插件。如果你遵循这些约定,Maven 只需要几乎为零的工作——仅仅是将你的源代码放到正确的目录,Maven 将会帮你处理剩下的事情。


使用“遵循约定优于配置”系统的一个副作用是用户可能会觉得他们被强迫使用一种特殊的方法。 当然 Maven 有一些核心观点不应该被怀疑,但是其实很多默认行为还是可配置的。 例如项目源码的资源文件的位置可以被自定义,JAR 文件的名字可以被自定义,在开发自定义插件的时候,几乎任何行为可以被裁剪以满足你特定的环境需求。 如果你不想遵循约定,Maven 也会允许你自定义默认值来适应你的需求。






1.3. 一个一般的接口


在 Maven 为构建软件提供一个一般的接口之前,每个单独的项目都专门有人来管理一个完全自定义的构建系统。开发人员必须在开发软件之外去学习每个他们要参与的新项目的构建系统的特点。 在2001年,构建一个项目如 Turbine 和构建另外一个项目如 Tomcat ,两者方法是完全不同的。如果一个新的进行静态源码分析的源码分析工具面世了,或者如果有人开发了一个新的单元测试框架,每个人都必须放下手头的工作去想办法使这个新东西适应每个项目的自定义构建环境。 如何运行单元测试?世界上有一千种不同的答案。构建环境由无数无休止的关于工具和构建程序的争论所描述刻画。Maven 之前的时代是低效率的时代,是“构建工程师”的时代。


现在,大部分开源开发者已经或者正在使用 Maven 来管理他们新的软件项目。这种转变不仅仅是开发人员从一种构建工具转移到另外一种构建工具,更是开发人员开始为他们的项目采用一种一般的接口。随着软件系统变得越来越模块化,构建系统变得更复杂,而项目的数量更是如火箭般飞速上升。在 Maven 之前,当你想要从 Subversion 签出一个项目如 Apache ActiveMQApache ServiceMix ,然后从源码进行构建,你需要为每个项目留出一个小时来理解给它的构建系统。这个项目需要构建什么?需要现在什么类库?把类库放哪里?构建中我该运行什么目标?最好的情况下,理解一个新项目的构建需要几分钟,最坏的情况下(例如 Jakarta 项目的旧的 Servlet API 实现),一个项目的构建特别的困难,以至于花了几个小时以后,新的贡献者也只能编辑源码和编译项目。现在,你只要签出源码,然后运行: mvn install 。虽然 Maven 有很多优点,包括依赖管理和通过插件重用一般的构建逻辑,但它成功的最核心原因是它定义了构建软件的一般的接口。每当你看到一个使用 Maven 的项目如 Apache Wicket ,你就可以假设你能签出它的源码然后使用 mvn install 构建它,没什么好争论的。你知道点火开关在哪里,你知道油门在右边,刹车在左边。






1.4. 基于Maven插件的全局性重用


Maven 的核心其实不做什么实际的事情,除了解析一些 XML 文档,管理生命周期与插件之外,它什么也不懂。Maven 被设计成将主要的职责委派给一组 Maven 插件,这些插件可以影响 Maven 生命周期,提供对目标的访问。绝大多数 Maven 的动作发生于 Maven 插件的目标,如编译源码,打包二进制代码,发布站点和其它构建任务。你从 Apache 下载的 Maven 不知道如何打包 WAR 文件,也不知道如何运行单元测试,Maven 大部分的智能是由插件实现的,而插件从 Maven 仓库获得。事实上,第一次你用全新的 Maven 安装运行诸如 mvn install 命令的时候,它会从中央 Maven 仓库下载大部分核心 Maven 插件。这不仅仅是一个最小化 Maven 分发包大小的技巧,这种方式更能让你升级插件以给你项目的构建提高能力。Maven 从远程仓库获取依赖和插件的这一事实允许了构建逻辑的全局性重用。


Maven Surefire 插件是负责运行单元测试的插件。从版本 1.0 发展到目前广泛使用的在 JUnit 基础上增加了 TestNG 测试框架支持的版本。这种发展并没有破坏向后兼容性,如果你使用之前 Surefire 插件编译运行你的 JUnit 3 单元测试,然后你升级到了最新版本的 Surefire 插件,你的测试仍然能成功运行。但是,我们又获得了新的功能,如果你想使用 TestNG 运行单元测试,那么感谢 Surefire 插件的维护者,你已经可以使用 TestNG 了。你也能运行支持注解的 JUnit 4 单元测试。不用升级 Maven 安装或者新装任何软件,你就能获得这些功能。更重要的是,除了 POM 中一个插件的版本号,你不需要更改你项目的任何东西。


这种机制不仅仅适用于 Surefire 插件,项目使用 Compiler 插件进行编译,通过 Jar 插件变成 JAR 文件,还有一些插件生成报告,运行 JRuby 和 Groovy 的代码,以及一些用来向远程服务器发布站点的插件。Maven 将一般的构建任务抽象成插件,同时这些插件得到了很好的维护以及全局的共享,你不需要从头开始自定义你项目的构建系统然后提供支持。你完全可以从 Maven 插件获益,这些插件有人维护,可以从远程仓库下载到。这就是基于 Maven 插件的全局性重用。






1.5. 一个“项目”的概念模型


Maven 维护了一个项目的模型,你不仅仅需要把源码编译成字节码,你还需要开发软件项目的描述信息,为项目指定一组唯一的坐标。你要描述项目的的属性。项目的许可证是什么?谁开发这个项目,为这个项目做贡献?这个项目依赖于其它什么项目没有?Maven不仅仅是一个“构建工具”,它不仅仅是在类似于 make 和 Ant 的工具的基础上的改进,它是包含了一组关于软件项目和软件开发的语义规则的平台。这个基于每一个项目定义的模型实现了如下特征:




依赖管理


由于项目是根据一个包含组标识符,构件标识符和版本的唯一的坐标定义的。项目间可以使用这些坐标来声明依赖。


远程仓库


和项目依赖相关的,我们可以使用定义在项目对象模型(POM)中的坐标来创建 Maven 构件的仓库。


全局性构建逻辑重用


插件被编写成和项目模型对象(POM)一起工作,它们没有被设计成操作某一个已知位置的特定文件。一切都被抽象到模型中,插件配置和自定义行为都在模型中进行。


工具可移植性/集成


像 Eclipse,NetBeans,和 InteliJ 这样的工具现在有共同的地方来找到项目的信息。在 Maven 出现之前,每个 IDE 都有不同的方法来存储实际上是自定义项目对象模型(POM)的信息。Maven 标准化了这种描述,而虽然每个 IDE 仍然继续维护它的自定义项目文件,但这些文件现在可以很容易的由模型生成。


便于搜索和过滤构件


像 Nexus 这样的工具允许你使用存储在 POM 中的信息对仓库中的内容进行索引和搜索。


Maven 为软件项目的语义一致性描述的开端提供了一个基础。






1.6. Maven是Ant的另一种选择么?


当然,Maven 是 Ant 的另一种选择,但是 Apache Ant 继续是一个伟大的,被广泛使用的工具。它已经是多年以来 Java 构建的统治者,而你很容易的在你项目的 Maven 构建中集成 Ant 构建脚本。这是 Maven 项目一种很常见的使用模式。而另一方面,随着越来越多的开源项目转移到 Maven 用它作为项目管理平台,开发人员开始意识到 Maven 不仅仅简化了构建管理任务,它也帮助鼓励开发人员的软件项目使用通用的接口。Maven 不仅仅是一个工具,它更是一个平台,当你只是将 Maven 考虑成 Ant 的另一种选择的时候,你是在比较苹果和橘子。“Maven”包含了很多构建工具以外的东西。


有一个核心观点使得所有的关于 Maven 和. Ant, Maven 和 Buildr, Maven 和 Grandle 的争论变得无关紧要。Maven并不是完全根据你构建系统的机制来定义的,它不是为你构建的不同任务编写脚本,它提倡一组标注,一个一般的接口,一个生命周期,一个标准的仓库格式,一个标准的目录布局,等等。它当然也不太在意 POM 的格式正好是 XML 还是 YAML 还是 Ruby。它比这些大得多,Maven 涉及的比构建工具本身多得多。当本书讨论 Maven 的时候,它也设计到支持 Maven 的软件,系统和标准。Buildr,Ivy,Gradle,所有这些工具都和 Maven 帮助创建的仓库格式交互,而你可以很容易的使用如 Nexus 这样的工具来支持一个完全由 Buildr 编写的构建。Nexus 将在本书后面介绍。


虽然 Maven 是很多类似工具的另一个选择?但社区需要向前发展,就要看清楚技术是资本经济中不友好的竞争者之间持续的、零和的游戏。这可能是大企业之前相互关联的方式,但是和开源社区的工作方式没太大关系。“谁是胜利者?Ant 还是 Maven”这个大标题没什么建设性意义。如果你非要我们来回答这个问题,我们会很明确的说作为构建的基本技术,Maven 是 Ant 的更好选择;同时,Maven 的边界在持续的移动,Maven 的社区也在持续的是试图找到新的方法,使其更通用,互操作性更好,更易协同工作。Maven 的核心财产是声明性构建,依赖管理,仓库管理,基于插件的高度和重用,但是当前,和开源社区相互协作以降低”企业级构建“的低效率这个目标来比,这些想法的特定实现没那么重要。






1.7. 比较Maven和Ant


虽然上一节应该已经让你确信本书的作者没有兴趣挑起 Apache Ant 和 Apache Maven 之间的争执,但是我们认识到许多组织必须在 Apache Ant 和 Apache Maven 之间做一个选择。本节我们对比一下这两个工具。


Ant 在构建过程方面十分优秀,它是一个基于任务和依赖的构建系统。每个任务包含一组由 XML 编码的指令。有 copy 任务和 javac 任务,以及 jar 任务。在你使用 Ant 的时候,你为 Ant 提供特定的指令以编译和打包你的输出。看下面的例子,一个简单的 build.xml 文件:



Example 1.1. 一个简单的 Ant build.xml 文件


<project name=“my-project” default=“dist” basedir=“.”>
<description>
simple example build file
</description>
<!– set global properties for this build —>
<property name=“src” location=“src/main/java”/>
<property name=“build” location=“target/classes”/>
<property name=“dist” location=“target”/>

<target name=“init”>
<!– Create the time stamp —>
<tstamp/>
<!– Create the build directory structure used by compile —>
<mkdir dir=“${build}”/>
</target>

<target name=“compile” depends=“init”
description=“compile the source “ >
<!– Compile the java code from ${src} into ${build} —>
<javac srcdir=“${src}” destdir=“${build}”/>
</target>

<target name=“dist” depends=“compile”
description=“generate the distribution” >
<!– Create the distribution directory —>
<mkdir dir=“${dist}/lib”/>

<!– Put everything in ${build} into the MyProject-${DSTAMP}.jar file —>
<jar jarfile=“${dist}/lib/MyProject-${DSTAMP}.jar” basedir=“${build}”/>
</target>

<target name=“clean”
description=“clean up” >
<!– Delete the ${build} and ${dist} directory trees —>
<delete dir=“${build}”/>
<delete dir=“${dist}”/>
</target>
</project>



在这个简单的 Ant 例子中,你能看到,你需要明确的告诉 Ant 你想让它做什么。有一个包含 javac 任务的编译目标用来将 src/main/java 的源码编译至 target/classes 目录。你必须明确告诉 Ant 你的源码在哪里,结果字节码你想存储在哪里,如何将这些字节码打包成 JAR 文件。虽然最近有些进展以帮助 Ant 减少程序,但一个开发者对 Ant 的感受是用 XML 编写程序语言。


用 Maven 样例与之前的 Ant 样例做个比较。在 Maven 中,要从 Java 源码创建一个 JAR 文件,你只需要创建一个简单的 pom.xml,将你的源码放在 ${basedir}/src/main/java ,然后从命令行运行 mvn install。下面的样例 Maven pom.xml 文件能完成和之前 Ant 样例所做的同样的事情。



Example 1.2. 一个简单的 Maven pom.xml


<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sonatype.maven</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>


这就是你 pom.xml 的全部。从命令行运行 mvn install 会处理资源文件,编译源代码,运行单元测试,创建一个 JAR ,然后把这个 JAR 安装到本地仓库以为其它项目提供重用性。不用做任何修改,你可以运行 mvn site ,然后在 target/site 目录找到一个 index.html 文件,这个文件链接了 JavaDoc 和一些关于源代码的报告。


诚然,这是一个最简单的样例项目。一个只包含源代码并且生成一个 JAR 的项目。一个遵循 Maven 的约定,不需要任何依赖和定制的项目。如果我们想要定制行为,我们的 pom.xml 的大小将会增加,在最大的项目中,你能看到一个非常复杂的 Maven POM 的集合,它们包含了大量的插件定制和依赖声明。但是,虽然你项目的 POM 文件变得增大,它们包含的信息与一个差不多大小的基于 Ant 项目的构建文件的信息是完全不同的。Maven POM 包含声明:“这是一个 JAR 项目”,“源代码在 src/main/java 目录”。Ant 构建文件包含显式的指令:“这是一个项目”,“源代码在 src/main/java ”,“针对这个目录运行 javac ”,“把结果放到 target/classes ”,“从……创建一个 JAR ”,等等。Ant 必须的过程必须是显式的,而 Maven 有一些“内置”的东西使它知道源代码在哪里,如何处理它们。


该例中 Ant 和 Maven 的区别是:




Apache Ant





  • Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码,哪里放置输出。随着时间的推移,非正式的约定出现了,但是它们还没有在产品中模式化。



  • Ant 是程序化的,你必须明确的告诉 Ant 做什么,什么时候做。你必须告诉它去编译,然后复制,然后压缩。



  • Ant 没有生命周期,你必须定义目标和目标之间的依赖。你必须手工为每个目标附上一个任务序列。


Apache Maven





  • Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里。它把字节码放到 target/classes ,然后在 target 生成一个 JAR 文件。



  • Maven 是声明式的。你需要做的只是创建一个 pom.xml 文件然后将源代码放到默认的目录。Maven 会帮你处理其它的事情。



  • Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。


Maven 以插件的形式为一些一般的项目任务提供了内置的智能。如果你想要编写运行单元测试,你需要做的只是编写测试然后放到 ${basedir}/src/test/java ,添加一个对于 TestNG 或者 JUnit 的测试范围依赖,然后运行 mvn test 。如果你想要部署一个 web 应用而非 JAR ,你需要做的是改变你的项目类型为 war ,然后把你文档根目录置为 ${basedir}/src/main/webapp 。当然,你可以用 Ant 做这些事情,但是你将需要从零开始写这些指令。使用 Ant ,你首先需要确定 JUnit JAR 文件应该放在哪里,然后你需要创建一个包含这个 JUnit JAR 文件的 classpath ,然后告诉 Ant 它应该从哪里去找测试源代码,编写一个目标来编译测试源代码为字节码,使用 JUnit 来执行单元测试。


没有诸如 antlibs 和 lvy 等技术的支持(即使有了这些支持技术),Ant 给人感觉是自定义的程序化构建。项目中一组高效的坚持约定的 Maven POM ,相对于 Ant 的配置文件,只有很少的 XML 。Maven 的另一个优点是它依靠广泛公用的 Maven 插件。所有人使用 Maven Surefire 插件来运行单元测试,如果有人添加了一些针对新的测试框架的支持,你可以仅仅通过在你项目的 POM 中升级某个特定插件的版本来获得新的功能。


使用 Maven 还是 Ant 的决定不是非此即彼的,Ant 在复杂的构建中还有它的位置。如果你目前的构建包含一些高度自定义的过程,或者你已经写了一些 Ant 脚本通过一种明确的方法完成一个明确的过程,而这种过程不适合 Maven 标准,你仍然可以在 Maven 中用这些脚本。作为一个 Maven 的核心插件, Ant 还是可用的。自定义的插件可以用 Ant 来实现,Maven 项目可以配置成在生命周期中运行 Ant 的脚本。






1.8. 总结


我们刻意的使这篇介绍保持得简短。 我们略述了一些Maven定义的要点,它们合起来是什么,它是基于什么改进的,同时介绍了其它构建工具。 下一章将深入一个简单的项目,看 Maven 如何能够通过最小数量的配置来执行典型的任务。


编写对GC友好,又不泄漏的代码


   作者:江南白衣,最新版链接:http://blog.csdn.net/calvinxiu/archive/2007/05/22/1621051.aspx,版权所有,转载请保留原文链接。


    看到JavaOne2007上有篇《Garbage-Collection-Friendly Programming》的68页PPT,心想都2007了还谈这个基本问题,一定总结得很全面了才好意思站出来讲吧。    


GC的基础概念见上篇:JDK5.0垃圾收集优化之–Don’t Pause  


1.使用更多生命周期短的、小的、不改变指向(immutable)的对象,编写清晰的代码。


    出于懒惰也好,朴素的节俭意识也好,我们都习惯对一个变量重用再重用。但是….



  • Java的垃圾收集器喜欢短生命周期的对象,对象如果在新生代内,在垃圾收集发生前就死掉了,垃圾收集器就什么都不用做了。
  • 现代JVM构建一个新对象只需要10个本地CPU指令,并不弱于C/C++。 (但垃圾收集没有压缩算法时会稍慢,更频繁的New对象也导致更频繁的GC)。
  • 大对象的分配效率更低,而且对非压缩算法的垃圾收集器,更容易造成碎片。
  • 对象重用增加了代码的复杂度,降低了可读性。

   所以有标题的呼吁,比如不要害怕为中间结果分配小对象。但编程习惯的改变也不是一朝一夕的事情。



2.将用完的对象设为NULL其实没什么作用。


    貌似很酷的把对象主动设为Null 的”好习惯”其实没什么用,JIT Compiler会自动分析local变量的生命周期。
    只有一个例外情况,就是String[1024] foo 这种赤裸裸的数组,你需要主动的foo[100]=null释放第100号元素,所以最好还是直接用ArrayList这些标准库算了。


 


3.避免显式GC–System.gc()。


    大家都知道System.gc()不好,full-gc浪费巨大,gc的时机把握不一定对等等,甚至有-XX:+DisableExplicitGC的JVM参数来禁止它。


    哈哈,但我还不会用System.gc()呢,不怕不怕。真的不怕吗?



  • 先用FindBugs 查一下所用到的全部第三方类库吧…
  • 至少RMI 就会老实不客气的执行System.gc()来实现分布式GC算法。但我也不会用RMI啊。那EJB呢,EJB可是建在RMI上的….

    如果无可避免,用-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 (单位为微妙) 增大大GC的间隔(原默认值为1分钟),-XX:+ExplicitGCInvokesConcurrent 让System.gc() 也CMS并发执行。


 


4.继续千夫所指的finalize()


    大家也都知道finalize()不好,分配代价昂贵,释放代价更昂贵(要多走一个循环,而且他们死得慢,和他们相关联的对象也跟着死得慢了),又不确定能否被调用(JVM开始关闭时,就不会再进行垃圾收集),又不确定何时被调用(GC时间不定,即使system.gc()也只是提醒而不是强迫GC,又不确定以什么样的顺序调用,所以finalize不是C++的析构函数,也不像C++的析构函数。


   我们都知道啊,所以我从来都没使用。都是在显式的维护那些外部资源,比如在finally{}里释放。


 


5.WeakReference/SoftReference


   这是个平时不怎么会搭理,偶然知道了又觉得有用的Java特征。大家都知道Java里所有对象除int等基本类型外,都是Pass by Reference的指针,实例只要被一个对象连着,就不会被收集。
    而WeakReference就是真正意义上的C++指针,只是单纯的指向一个对象,而不会影响对象的引用计数。
    而SoftReference更特别,在内存足够时,对象会因为SoftReference的存在而不被收集,但内存不足时,对象就还是会被收集,怎么看都是做简单缓存的料子。代码如下:



  Foo foo = new Foo(); 
  SoftReference sr
= new SoftReference(foo); 
  Foo bar 
=  sr.get(); 

  如果foo已被垃圾收集,sr.get()会返回Null;


  另外还有一个ReferenceQueue的机制,使得对象被回收时能获得通知,比finalize()完全不知道GC何时会执行要聪明的多。



  ReferenceQueue rq = new ReferenceQueue();
  ref 
= new WeakReference(foo, rq); 
  WeakReference cleaned 
= rq.pool(); 

  cleaned就是刚刚被GC掉的WeakReference。


6.内存泄漏


   java 不是有垃圾收集器了吗?怎么还泄漏啊,唬我啊??
   嗯,此泄漏非比泄漏。C/C++的泄漏,是对象已不可到达,而内存又没有回收,真正的内存黑洞。
   而Java的泄漏,则是因为各种原因,对象对应用已经无用,但一直被持有,一直可到达。
   总结原因无外乎几方面:



  1. 被生命周期极长的集合类不当持有,号称是Java内存泄漏的首因。
    这些集合类的生命周期通常极长,而且是一个辅助管理性质的对象,在一个业务事务运行完后,如果没有将某个业务对象主动的从中清除的话,这个集合就会吃越来越多内存,可以用WeakReference,如WeakHashMap,使得它持有的对象不增加对象的引用数。
  2. Scope定义不对,这个很简单了,方法的局部变量定义成类的变量,类的静态变量等。
  3. 异常时没有加finally{}来释放某些资源,JDBC时代也是很普遍的事情。
  4. 另外一些我了解不深的原因,如:Swing里的Listener没有显式remove;内部类持有外部对象的隐式引用;Finalizers造成关联对象没有被及时清空等。

内存泄漏的检测


有不少工具辅助做这个事情的,如果手上一个工具也没有,可以用JDK自带的小工具:



  • 看看谁占满了Heap?
    用JDK6的jmap可以显示运行程序中对象的类型,个数与所占的大小
    先用jps 找到进程号,然后jmap -histo pid 显示或 jmap -dump:file=heap_file_name pid 导出heap文件
  • 为什么这些对象仍然可以到达?
    用jhat(Java Heap Analysis Tool) 分析刚才导出的heap文件。
    先jhat heap_file_name,然后打开浏览器http://localhost:7000/ 浏览。

JDK5.0垃圾收集优化之–Don’t Pause



      作者:江南白衣,最新版链接:http://blog.csdn.net/calvinxiu/archive/2007/05/18/1614473.aspx,版权所有,转载请保留原文链接。


      原本想把题目更简单的定为–《不要停》的,但还是自己YY一下就算了。
      Java开发Server最大的障碍,就是JDK1.4版之前的的串行垃圾收集机制会引起长时间的服务暂停,明白原理后,想想那些用JDK1.3写Server的先辈,不得不后怕。
     好在JDK1.4已开始支持多线程并行的后台垃圾收集算法,JDK5.0则优化了默认值的设置。


一、参考资料:



  1. Tuning Garbage Collection with the 5.0 Java Virtual Machine 官方指南。
  2. Hotspot memory management whitepaper 官方白皮书。
  3. Java Tuning White Paper 官方文档。
  4. FAQ about Garbage Collection in the Hotspot  官方FAQ,JVM1.4.2。
  5. Java HotSpot 虚拟机中的垃圾收集 JavaOne2004上的中文ppt
  6. A Collection of JVM Options JVM选项的超完整收集。

二、基本概念


1、堆(Heap)


JVM管理的内存叫堆。在32Bit操作系统上有1.5G-2G的限制,而64Bit的就没有。


JVM初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。


JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。


默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,可以由-XX:MinHeapFreeRatio=指定。
默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio=指定。


服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小,所以上面的两个参数没啥用。 



2.基本收集算法



  1. 复制:将堆内分成两个相同空间,从根(ThreadLocal的对象,静态对象)开始访问每一个关联的活跃对象,将空间A的活跃对象全部复制到空间B,然后一次性回收整个空间A。
    因为只访问活跃对象,将所有活动对象复制走之后就清空整个空间,不用去访问死对象,所以遍历空间的成本较小,但需要巨大的复制成本和较多的内存。
  2. 标记清除(mark-sweep):收集器先从根开始访问所有活跃对象,标记为活跃对象。然后再遍历一次整个内存区域,把所有没有标记活跃的对象进行回收处理。该算法遍历整个空间的成本较大暂停时间随空间大小线性增大,而且整理后堆里的碎片很多。
  3. 标记整理(mark-sweep-compact):综合了上述两者的做法和优点,先标记活跃对象,然后将其合并成较大的内存块。

    可见,没有免费的午餐,无论采用复制还是标记清除算法,自动的东西都要付出很大的性能代价。


3.分代


    分代是Java垃圾收集的一大亮点,根据对象的生命周期长短,把堆分为3个代:Young,Old和Permanent,根据不同代的特点采用不同的收集算法,扬长避短也。


Young(Nursery),年轻代。研究表明大部分对象都是朝生暮死,随生随灭的。因此所有收集器都为年轻代选择了复制算法。
    复制算法优点是只访问活跃对象,缺点是复制成本高。因为年轻代只有少量的对象能熬到垃圾收集,因此只需少量的复制成本。而且复制收集器只访问活跃对象,对那些占了最大比率的死对象视而不见,充分发挥了它遍历空间成本低的优点。


    Young的默认值为4M,随堆内存增大,约为1/15,JVM会根据情况动态管理其大小变化。
    -XX:NewRatio= 参数可以设置Young与Old的大小比例,-server时默认为1:2,但实际上young启动时远低于这个比率?如果信不过JVM,也可以用-Xmn硬性规定其大小,有文档推荐设为Heap总大小的1/4。


    Young的大小非常非常重要,见“后面暂停时间优先收集器”的论述。


    Young里面又分为3个区域,一个Eden,所有新建对象都会存在于该区,两个Survivor区,用来实施复制算法。每次复制就是将Eden和第一块Survior的活对象复制到第2块,然后清空Eden与第一块Survior。Eden与Survivor的比例由-XX:SurvivorRatio=设置,默认为32。Survivio大了会浪费,小了的话,会使一些年轻对象潜逃到老人区,引起老人区的不安,但这个参数对性能并不重要。 


Old(Tenured),年老代。年轻代的对象如果能够挺过数次收集,就会进入老人区。老人区使用标记整理算法。因为老人区的对象都没那么容易死的,采用复制算法就要反复的复制对象,很不合算,只好采用标记清理算法,但标记清理算法其实也不轻松,每次都要遍历区域内所有对象,所以还是没有免费的午餐啊。


-XX:MaxTenuringThreshold=设置熬过年轻代多少次收集后移入老人区,CMS中默认为0,熬过第一次GC就转入,可以用-XX:+PrintTenuringDistribution查看。


Permanent,持久代。装载Class信息等基础数据,默认64M,如果是类很多很多的服务程序,需要加大其设置-XX:MaxPermSize=,否则它满了之后会引起fullgc()或Out of Memory。 注意Spring,Hibernate这类喜欢AOP动态生成类的框架需要更多的持久代内存。


4.minor/major collection


    每个代满了之后都会促发collection,(另外Concurrent Low Pause Collector默认在老人区68%的时候促发)。GC用较高的频率对young进行扫描和回收,这种叫做minor collection
而因为成本关系对Old的检查回收频率要低很多,同时对Young和Old的收集称为major collection。
    System.gc()会引发major collection,使用-XX:+DisableExplicitGC禁止它,或设为CMS并发-XX:+ExplicitGCInvokesConcurrent。


5.小结


Young — minor collection — 复制算法


Old(Tenured) — major colletion — 标记清除/标记整理算法



三、收集器


1.古老的串行收集器(Serial Collector)


    使用 -XX:+UseSerialGC,策略为年轻代串行复制,年老代串行标记整理。


2.吞吐量优先的并行收集器(Throughput Collector)


    使用 -XX:+UseParallelGC ,也是JDK5 -server的默认值。策略为:
    1.年轻代暂停应用程序,多个垃圾收集线程并行的复制收集,线程数默认为CPU个数,CPU很多时,可用–XX:ParallelGCThreads=减少线程数。
    2.年老代暂停应用程序,与串行收集器一样,单垃圾收集线程标记整理。


    所以需要2+的CPU时才会优于串行收集器,适用于后台处理,科学计算。


    可以使用-XX:MaxGCPauseMillis= 和 -XX:GCTimeRatio 来调整GC的时间。


3.暂停时间优先的并发收集器(Concurrent Low Pause Collector-CMS)


    前面说了这么多,都是为了这节做铺垫……


    使用-XX:+UseConcMarkSweepGC,策略为:
    1.年轻代同样是暂停应用程序,多个垃圾收集线程并行的复制收集。
    2.年老代则只有两次短暂停,其他时间应用程序与收集线程并发的清除。


3.1 年老代详述


    并行(Parallel)与并发(Concurrent)仅一字之差,并行指多条垃圾收集线程并行,并发指用户线程与垃圾收集线程并发,程序在继续运行,而垃圾收集程序运行于另一个个CPU上。


    并发收集一开始会很短暂的停止一次所有线程来开始初始标记根对象,然后标记线程与应用线程一起并发运行,最后又很短的暂停一次,多线程并行的重新标记之前可能因为并发而漏掉的对象,然后就开始与应用程序并发的清除过程。可见,最长的两个遍历过程都是与应用程序并发执行的,比以前的串行算法改进太多太多了!!!


    串行标记清除是等年老代满了再开始收集的,而并发收集因为要与应用程序一起运行,如果满了才收集,应用程序就无内存可用,所以系统默认68%满的时候就开始收集。内存已设得较大,吃内存又没有这么快的时候,可以用-XX:CMSInitiatingOccupancyFraction=恰当增大该比率。


3.2 年轻代详述


   可惜对年轻代的复制收集,依然必须停止所有应用程序线程,原理如此,只能靠多CPU,多收集线程并发来提高收集速度,但除非你的Server独占整台服务器,否则如果服务器上本身还有很多其他线程时,切换起来速度就….. 所以,搞到最后,暂停时间的瓶颈就落在了年轻代的复制算法上。


    因此Young的大小设置挺重要的,大点就不用频繁GC,而且增大GC的间隔后,可以让多点对象自己死掉而不用复制了。但Young增大时,GC造成的停顿时间攀升得非常恐怖,比如在我的机器上,默认8M的Young,只需要几毫秒的时间,64M就升到90毫秒,而升到256M时,就要到300毫秒了,峰值还会攀到恐怖的800ms。谁叫复制算法,要等Young满了才开始收集,开始收集就要停止所有线程呢。


3.3 持久代


可设置-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled,使CMS收集持久代的类,而不是fullgc,netbeans5.5 performance文档的推荐。


4.增量(train算法)收集器(Incremental Collector)


已停止维护,–Xincgc选项默认转为并发收集器。


四、暂停时间显示


 加入下列参数 (请将PrintGC和Details中间的空格去掉,CSDN很怪的认为是禁止字句) 


-verbose:gc -XX:+PrintGC Details  -XX:+PrintGCTimeStamps


会程序运行过程中将显示如下输出


 9.211: [GC 9.211: [ParNew: 7994K->0K(8128K), 0.0123935 secs] 427172K->419977K(524224K), 0.0125728 secs]


 显示在程序运行的9.211秒发生了Minor的垃圾收集,前一段数据针对新生区,从7994k整理为0k,新生区总大小为8128k,程序暂停了12ms,而后一段数据针对整个堆。


对于年老代的收集,暂停发生在下面两个阶段,CMS-remark的中断是17毫秒:


[GC [1 CMS-initial-mark: 80168K(196608K)] 81144K(261184K), 0.0059036 secs] 


[1 CMS-remark: 80168K(196608K)] 82493K(261184K),0.0168943 secs]


再加两个参数 -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime对暂停时间看得更清晰。


五、真正不停的BEA JRockit 与Sun RTS2.0


   Bea的JRockit 5.0 R27 的特色之一是动态决定的垃圾收集策略,用户可以决定自己关心的是吞吐量,暂停时间还是确定的暂停时间,再由JVM在运行时动态决定、改变改变垃圾收集策略。
   
   它的Deterministic GC的选项是-Xgcprio: deterministic,号称可以把暂停可以控制在10-30毫秒,非常的牛,一句Deterministic道尽了RealTime的真谛。 不过细看一下文档,30ms的测试环境是1 GB heap 和 平均  30% 的活跃对象(也就是300M)活动对象,2 个 Xeon 3.6 GHz  4G内存 ,或者是4 个Xeon 2.0 GHz,8G内存。


  最可惜JRockt的license很奇怪,虽然平时使用免费,但这个30ms的选项就需要购买整个Weblogic Real Time Server的license。 


  其他免费选项,有:



  • -Xgcprio:pausetime -Xpausetarget=210ms 
      因为免费,所以最低只能设置到200ms pause target。 200ms是Sun认为Real-Time的分界线。
  • -Xgc:gencon
    普通的并发做法,效率也不错。

  JavaOne2007上有Sun的 Java Real-Time System 2.0 的介绍,RTS2.0基于JDK1.5,在Real-Time  Garbage Collctor上又有改进,但还在beta版状态,只供给OEM,更怪。


六、JDK 6.0的改进


因为JDK5.0在Young较大时的表现还是不够让人满意,又继续看JDK6.0的改进,结果稍稍失望,不涉及我最头痛的年轻代复制收集改良。


1.年老代的标识-清除收集,并行执行标识
  JDK5.0只开了一条收集进程与应用线程并发标识,而6.0可以开多条收集线程来做标识,缩短标识老人区所有活动对象的时间。


2.加大了Young区的默认大小
默认大小从4M加到16M,从堆内存的1/15增加到1/7


3.System.gc()可以与应用程序并发执行
使用-XX:+ExplicitGCInvokesConcurrent 设置


七、小结


1. JDK5.0/6.0


对于服务器应用,我们使用Concurrent Low Pause Collector,对年轻代,暂停时多线程并行复制收集;对年老代,收集器与应用程序并行标记–整理收集,以达到尽量短的垃圾收集时间。


本着没有深刻测试前不要胡乱优化的宗旨,命令行属性只需简单写为:



-server -XmsM -XmxM -XX:+UseConcMarkSweepGC  -XX:+PrintGC Details  -XX:+PrintGCTimeStamps

然后要根据应用的情况,在测试软件辅助可以下看看有没有JVM的默认值和自动管理做的不够的地方可以调整,如-xmn 设Young的大小,-XX:MaxPermSize设持久代大小等。


2. JRockit 6.0 R27.2


但因为JDK5的测试结果实在不能满意,后来又尝试了JRockit,总体效果要好些。
 JRockit的特点是动态垃圾收集器是根据用户关心的特征动态决定收集算法的,参数如下



 -XmsM -XmxM -Xgcprio:pausetime -Xpausetarget=200ms -XgcReport -XgcPause -Xverbose:memory


mysql tuner-primer

mysql下tuner-primer使用说明
mysql tuner-primer是检测mysql的主配置文件my.cnf的有力工具,当然还有其他工具,比如mysqlreport,今天先介绍这个工具的使用。
下载并改变执行权限:
wget
http://www.day32.com/MySQL/tuning-primer.sh

chmod a+x tuning-primer.sh
./tuning-primer.sh
首先会要求输入服务器的用户名和密码,并提示保存在当前用户目录下配置文件。
再次执行脚本就会运行,不用输入用户名和密码,并给出参数配置,强悍就强悍在这!!!!
看看我的相关提示,
[root@slave1 tuning-primer]# ./tuning-primer.sh
– INITIAL LOGIN ATTEMPT FAILED –
Testing Stored for passwords: None Found
– RETRY LOGIN ATTEMPT FAILED –
Could not auto detect login info!
Do you have your login handy ? [y/N] : y
User: root
Password:
Would you like me to create a ~/.my.cnf file for you? [y/N] : y
        — MYSQL PERFORMANCE TUNING PRIMER —
             – By: Matthew Montgomery –
MySQL Version 5.1.22-rc-log i686
Uptime = 1 days 2 hrs 16 min 29 sec
Avg. qps = 348
Total Questions = 32946460
Threads Connected = 23
Warning: Server has not been running for at least 48hrs.
It may not be safe to use these recommendations
To find out more information on how each of these
runtime variables effects performance visit:
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html
Visit
http://www.mysql.com/products/enterprise/advisors.html
for info about MySQL’s Enterprise Monitoring and Advisory Service
SLOW QUERIES
The slow query log is NOT enabled.
Current long_query_time = 10.000000 sec.
You have 44 out of 32946564 that take longer than 10.000000 sec. to complete
Your long_query_time seems to be fine
BINARY UPDATE LOG
The binary update log is enabled
The expire_logs_days is not set.
The mysqld will retain the entire binary log until RESET MASTER or PURGE MASTER LOGS commands are run manually
Setting expire_log_days will allow you to remove old binary logs automatically
See
http://dev.mysql.com/doc/refman/5.1/en/purge-master-logs.html
WORKER THREADS
Current thread_cache_size = 1024
Current threads_cached = 363
Current threads_per_sec = 0
Historic threads_per_sec = 0
Your thread_cache_size is fine
MAX CONNECTIONS
Current max_connections = 1500
Current threads_connected = 22
Historic max_used_connections = 391
The number of used connections is 26% of the configured maximum.
Your max_connections variable seems to be fine.
MEMORY USAGE
Max Memory Ever Allocated : 61 G
Configured Max Per-thread Buffers : 225 G
Configured Max Global Buffers : 2 G
Configured Max Memory Limit : 228 G
Physical Memory : 3.95 G
Max memory limit exceeds 90% of physical memory
KEY BUFFER
Current MyISAM index space = 2 G
Current key_buffer_size = 512 M
Key cache miss rate is 1 : 121
Key buffer fill ratio = 31.00 %
Your key_buffer_size seems to be too high.
Perhaps you can use these resources elsewhere
QUERY CACHE
Query cache is enabled
Current query_cache_size = 64 M
Current query_cache_used = 14 M
Current query_cache_limit = 2 M
Current Query cache Memory fill ratio = 23.29 %
Current query_cache_min_res_unit = 4 K
Query Cache is 23 % fragmented
Run “FLUSH QUERY CACHE” periodically to defragment the query cache memory
If you have many small queries lower ‘query_cache_min_res_unit’ to reduce fragmentation.
Your query_cache_size seems to be too high.
Perhaps you can use these resources elsewhere
MySQL won’t cache query results that are larger than query_cache_limit in size
SORT OPERATIONS
Current sort_buffer_size = 4 M
Current read_rnd_buffer_size = 15 M
Sort buffer seems to be fine
JOINS
Current join_buffer_size = 4.00 M
You have had 22509 queries where a join could not use an index properly
join_buffer_size >= 4 M
This is not advised
You should enable “log-queries-not-using-indexes”
Then look for non indexed joins in the slow query log.
OPEN FILES LIMIT
Current open_files_limit = 8192 files
The open_files_limit should typically be set to at least 2x-3x
that of table_cache if you have heavy MyISAM usage.
Your open_files_limit value seems to be fine
TABLE CACHE
Current table_open_cache = 2048 tables
Current table_definition_cache = 128 tables
You have a total of 400 tables
You have 588 open tables.
The table_cache value seems to be fine
You should probably increase your table_definition_cache value.
TEMP TABLES
Current max_heap_table_size = 16 M
Current tmp_table_size = 64 M
Of 53670 temp tables, 44% were created on disk
Effective in-memory tmp_table_size is limited to max_heap_table_size.
Perhaps you should increase your tmp_table_size and/or max_heap_table_size
to reduce the number of disk-based temporary tables
Note! BLOB and TEXT columns are not allow in memory tables.
If you are using these columns raising these values might not impact your
ratio of on disk temp tables.
TABLE SCANS
Current read_buffer_size = 127 M
Current table scan ratio = 407 : 1
read_buffer_size is over 8 MB there is probably no need for such a large read_buffer
TABLE LOCKING
Current Lock Wait ratio = 1 : 3135582
Your table locking seems to be fine

myeclipse 6 hot key content assist

为什么MyEclipse6.0 不出现快速提示,我要把整个单词快打完了才出现,。
如:public class TestMain extends TestCase 如果是以前3.2的extends  直接按“ALT+/”就可以出现这个单词提示,
我现在完全要自己打出来了。这样会浪费很多时间的。
  这是不是那么没有设置好呀。

 

 

eclipse3.3中把内容助手(content assist)的快捷键由 alt + /  改成了ctrl + space,这又刚好跟我们操作系统的切换输入法的快捷键冲突,所以造成内容助手不能使用了,给写代码带来了极大的不便。 而已前eclipse 3.2版本中的 alt + / 快捷键被作为新的单词补全(word competion)功能的快捷键。所以现在想像以前一样使用alt + / 来实现内容助手的功能,就需要更改eclipse3.3快捷键的设置了。具体操作如下:

1. 点击Windows->Preferences->General->Keys .

2. 在列出的快捷键列表中查找到:word competion,把它的快捷键alt + / 改成其它的快捷键(怎么改,先把此快捷键删除,点右边的按钮”remove binding”, 再选中binding文本框,输入你想要的快捷键)。

3. 在列出的快捷键列表中查找到:content assist,把它的快捷键 ctrl + space 改成我们想的的 alt + / 即可了。

从编译到工具:几种Mysql的优化方法

一、在编译时优化mysql


如果你从源代码分发安装mysql,要注意,编译过程对以后的目标程序性能有重要的影响,不同的编译方式可能得到类似的目标文件,但性能可能相差很大,因此,在编译安装mysql适应仔细根据你的应用类型选择最可能好的编译选项。这种定制的mysql可以为你的应用提供最佳性能。 


技巧:选用较好的编译器和较好的编译器选项,这样应用可提高性能10-30%。(mysql文档如是说) 


1.1、使用pgcc(pentium gcc)编译器


该编译器(http://www.goof.com/pcg/)针对运行在奔腾处理器系统上的程序进行优化,用pgcc编译mysql源代码,总体性能可提高10%。当然如果你的服务器不是用奔腾处理器,就不必用它了,因为它是专为奔腾系统设计的。 


1.2、仅使用你想使用的字符集编译mysql


mysql目前提供多达24种不同的字符集,为全球用户以他们自己的语言插入或查看表中的数据。却省情况下,mysql安装所有者这些字符集,热然而,最好的选择是指选择一种你需要的。如,禁止除latin1字符集以外的所有其它字符集: 


—————————————————————————— 


%>./configure -with-extra-charsets=none [–other-configuration-options] 


—————————————————————————— 


1.3、将mysqld编译成静态执行文件


将mysqld编译成静态执行文件而无需共享库也能获得更好的性能。通过在配置时指定下列选项,可静态编译mysqld。 


—————————————————————————— 


%>./configure -with-mysqld-ldflags=-all-static [–other-configuration-options] 


—————————————————————————— 


1.4、配置样本


下列配置命令常用于提高性能: 


—————————————————————————— 


%>cflags=”-o6  -mpentiumpro -fomit-frame-pointer” cxx=gcc cxxflags=”-o6 -mpentiumpro  -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti”  ./configure –prefix=/usr/local –enable-assembler  –with-mysqld-ldflags=-all-static –disable-shared 


—————————————————————————— 


二、调整服务器


确保运用正确的编译固然重要,但这只是成功的第一步,配置众多的mysql变量同样对服务器的正常运行起关键作用。你可以将这些变量的赋值存在一个配置文件中,以确保它们在每次启动mysql时均起作用,这个配置文件就是my.cnf文件。


mysql已经提供了几个my.cnf文件的样本,可在/usr/local/mysqld/share/mysql/目录下找到。这些文件分别命名为my-small.cnf、 my-medium.cnf、my-large.cnf和my-huge.cnf,规模说明可在描述配置文件适用的系统类型标题中找到。如果在只有相当少内存的系统上运行mysql,而且只是偶尔的用一下,那么my-small.cnf会比较理想,因为它命令mysqld 只使用最少的资源。类似地,如果你计划构建电子商务超市,而且系统拥有2g内存,那么你可能要用到mysql-huge.cnf文件了。为了利用这些文件中的一个,你需要复制一个最适合需求的文件,改名为my.cnf。你可以选择使用配置文件三种作用范围的一种:


global:将my.cnf文件复制到服务器的/etc目录下,这使得配置文件中的变量作用于全局,即对所有服务器上的mysql数据库服务器有效。


local:将my.cnf文件复制到[mysql-install-dir]/var/目录下,使得my.cnf作用于特定的服务器。[mysql-install-dir]表示mysql安装目录。


user:你可以再限制作用于特定的用户,将my.cnf复制到用户的根目录下。


究竟如何设置my.cnf中的这些变量呢?更进一步说,你可以设置哪一个变量。虽然所用变量对mysql服务器相对通用,每一个变量与mysql的的某些组件有更特定的关系。如变量max_connects归在mysqld类别下。执行下列命令即可知道: 


——————————————————————


%>/usr/local/mysql/libexec/mysqld –help 


—————————————————————— 


它显示大量的选项及与mysqld相关的变量。你可以很容易地在该行文字之下找出变量: 


——————————————————————- 


possible variables for option –set-variable (-o) are 


——————————————————————- 


然后你可以如下设置my.cnf中的那些变量: 


——————————————————————- 


set-variable = max_connections=100 


——————————————————————- 


它设置mysql服务器的最大并发连接数为100。要确保在my.cnf文件中的[mysqld]标题下插入变量设置。 


三、表类型


很多mysql用户可能很惊讶,mysql确实为用户提供5种不同的表类型,称为dbd、heap、isam、merge和myiasm。dbd归为事务安全类,而其他为非事务安全类。 


3.1、事务安全 


dbd 


berkeley  db(dbd)表是支持事务处理的表,由sleepycat软件公司(http://www.sleepycat.com)开发。它提供mysql用户期待已久的功能-事务控制。事务控制在任何数据库系统中都是一个极有价值的功能,因为它们确保一组命令能成功地执行。 


3.2、非事务安全 


heap 


heap表是mysql中存取数据最快的表。这是因为他们使用存储在动态内存中的一个哈希索引。另一个要点是如果mysql或服务器崩溃,数据将丢失。 


isam 


isam表是早期mysql版本的缺省表类型,直到myiasm开发出来。建议不要再使用它。 


merge 


merge是一个有趣的新类型,在3.23.25之后出现。一个merge表实际上是一个相同myisam表的集合,合并成一个表,主要是为了效率原因。这样可以提高速度、搜索效率、修复效率并节省磁盘空间。 


myiasm 


这是mysql的缺省表类型。它基于iasm代码,但有很多有用的扩展。myiasm比较好的原因: 


myiasm表小于iasm表,所以使用较少资源。 


myiasm表在不同的平台上二进制层可移植。 


更大的键码尺寸,更大的键码上限。 


3.3、指定表类型


你可在创建表时指定表的类型。下例创建一个heap表: 


——————————————————————–


mysql>create table email_addresses type=heap ( 


->email char(55) not null, 


->name char(30) not null, 


->primary key(email) ); 


———————————————————————


bdb表需要一些配置工作,参见http://www.mysql.com/doc/b/d/bdb_overview.HTML。 


3.4、更多的表类型


为了使mysql管理工作更有趣,即将发布的mysql 4.0将提供两种新的表类型,称为innobase和gemeni。 


四、优化工具


mysql服务器本身提供了几条内置命令用于帮助优化。 


4.1、show 


你可能有兴趣知道mysql服务器究竟更了什么,下列命令给出一个总结: 


———————————–


mysql>show status; 


———————————–


它给出了一个相当长的状态变量及其值的列表。有些变量包含了异常终止客户的数量、异常终止连接的数量、连接尝试的次数、最大并发连接数和大量其他有用的信息。这些信息对找出系统问题和低效极具价值。 


show还能做更多的事情。它可以显示关于日志文件、特定数据库、表、索引、进程和权限表中有价值的信息。详见mysql手册。 


4.2、explain 


当你面对select语句时,explain解释select命令如何被处理。这不仅对决定是否应该增加一个索引,而且对决定一个复杂的join如何被mysql处理都是有帮助的。 


4.3、optimize 


optimize语句允许你恢复空间和合并数据文件碎片,对包含变长行的表进行了大量更新和删除后,这样做特别重要。optimize目前只工作于myiasm和bdb表。


日誌分析工具 access.log analysis


Visitors is a very fast web log analyzer for Linux, Windows, and other Unix-like operating systems. It takes as input a web server log file, and outputs statistics in form of different reports. The design principles are very different compared to other software of the same type:


  • No installation required, can process up to 150,000 lines of log entries per second in fast computers (20MB/s with my log files average length).
  • Designed to be executed by the command line, output html and text reports. The text report can be used in pipe to less to check web stats from ssh.
  • Support for real time statistics with the Visitors Stream Mode introduced with version 0.3.
  • To specify the log format is not needed at all. Works out of box with apache and most other web servers with a standard log format (see the documentation for more information on the format).
  • It’s a portable C program, can be compiled on many different systems. Binaries for Windows systems are in the Download section of this page.
  • The produced html report doesn’t contain images or external CSS, is self-contained, you can send it by email to users.
  • Visitors is free software (and of course, freeware), under the terms of the GPL license. You don’t need to pay to use it. Visitors is supported, if you want a custom version made directly by the original author for a modest price, contact me at antirez (at) invece (dot) org. ISPs may take advantage of the high processing speed.

  •  


    download:http://www.hping.org/visitors/visitors-0.7.tar.gz

    Get Working day difference for 2 dates

    CREATE DEFINER=`root`@`%` FUNCTION `getworkdaydiff`(b date, a date) RETURNS int(11)
    DETERMINISTIC
    COMMENT ‘Get Working day difference for 2 dates’
    BEGIN
    DECLARE freedays int;
    SET freedays = 0;


    SET @x = DATEDIFF(b, a);
    IF @x<0 THEN
    SET @m = a;
    SET a = b;
    SET b = @m;
    SET @m = -1;
    ELSE
    SET @m = 1;
    END IF;
    SET @x = abs(@x) + 1;
    /* days in first week */
    SET @w1 = WEEKDAY(a)+1;
    SET @wx1 = 8-@w1;
    IF @w1>5 THEN
    SET @w1 = 0;
    ELSE
    SET @w1 = 6-@w1;
    END IF;
    /* days in last week */
    SET @wx2 = WEEKDAY(b)+1;
    SET @w2 = @wx2;
    IF @w2>5 THEN
    SET @w2 = 5;
    END IF;
    /* summary */
    SET @weeks = (@x-@wx1-@wx2)/7;
    SET @noweekends = (@weeks*5)+@w1+@w2;
    SET @result = @noweekends-freedays;
    RETURN @result*@m;
    END


    製作帶sata驅動的winxp安裝盤 include sp3

    其實也不是什麼新鮮事  最出名的就是用nLite去改造了  只不過最近看了些微軟的幫助支持文章  試了試下載SP3和改造系統安裝盤  順帶將新的經驗和方法分享


    不管你手頭的是不帶service pack的最原始安裝盤 還是xp sp1, xp sp1a, xp sp2 都可以利用


    1. 不過是nLite還是怎麼做 基本都是先把手頭有的純淨xp安裝盤放到光碟機  在C盤下新建一個檔夾 把光碟裏所有的檔和檔夾複製到新建檔夾裏 在C盤是方便區分和省了以下步驟中輸入命令時的路徑問題


    2. 我們把檔夾改名叫xpcd, 位置c:\xpcd


    3. 我們要做帶SATA驅動的安裝盤 當然就把SATA驅動下回來 解包
    裏面有用的就5個檔
    IAAHCI.CAT  size 11.0KB (11,352 bytes)
    IAAHCI.INF   size 6.31KB (6,467 bytes)
    IASTOR.CAT size 10.9KB (11,254 bytes)
    IASTOR.INF  size 6.29KB (6,451 bytes)
    IASTOR.SYS size 271KB (277,783 bytes)
    (注明檔大小是確認SATA驅動是最新 而且試驗證明 不同版本SATA驅動 裏面inf檔描述不一樣 可能會導致做出失敗的安裝盤)


    4. 把5個檔拷貝到c:\xpcd\i386


    5. 用記事本打開並修改c:\xpcd\i386 中三個檔, 把下列字串加到檔對應位置中。
    下面內容像”d1,iastor.sys”只需查找到[FloppyFiles.1]然後把”d1,iastor.sys”插入到[FloppyFiles.1]緊接的第二行;
    [Files]下面的內容也是同樣插入, 三個檔都是同樣處理。


    第一個文件是DOSNET.INF, 裏面要加的是
    [FloppyFiles.1]
    d1,iastor.sys


    [Files]
    d1,iaAHCI.INF
    d1,iaAHCI.cat
    d1,iastor.CAT
    d1,iastor.INF
    d1,iastor.sys


    第二個檔是TXTSETUP.SIF,裏面要加的是
    [SourceDisksFiles]
    iaStor.cat=1,,,,,,,20,0,0
    iaStor.inf=1,,,,,,,20,0,0
    iaAHCI.cat=1,,,,,,,20,0,0
    iaAHCI.inf=1,,,,,,,20,0,0
    iaStor.sys=1,,,,,,4_,4,1,,,1,4


    [HardwareIdsDatabase]
    PCI\VEN_8086&DEV_2821&CC_0106=”iaStor”
    PCI\VEN_8086&DEV_2822&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_282A&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_2829&CC_0106=”iaStor”
    PCI\VEN_8086&DEV_25B0&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_24DF&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_2652&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_27C3&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_27C1&CC_0106=”iaStor”
    PCI\VEN_8086&DEV_2652&CC_0106=”iaStor”
    PCI\VEN_8086&DEV_27C5&CC_0106=”iaStor”
    PCI\VEN_8086&DEV_27C6&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_2682&CC_0104=”iaStor”
    PCI\VEN_8086&DEV_2653=”iaStor”


    [SCSI.Load]
    iaStor=iaStor.sys,4


    [SCSI]
    iaStor=”Intel(R) 82801HEM SATA RAID Controller (Mobile ICH8M-E)”
    iastor=”Intel(R) 631xESB/632xESB SATA AHCI Controller (Server/Workstation ESB2)”
    iastor=”Intel(R) 631xESB/632xESB SATA RAID Controller (Server/Workstation ESB2)”
    iastor=”Intel(R) 82801FBM SATA AHCI Controller (Mobile ICH6M)”
    iastor=”Intel(R) 82801FR SATA AHCI Controller (Desktop ICH6R)”
    iastor=”Intel(R) 82801FR SATA RAID Controller (Desktop ICH6R)”
    iastor=”Intel(R) 82801GBM SATA AHCI Controller (Mobile ICH7M/DH)”
    iastor=”Intel(R) 82801GHM SATA RAID Controller (Mobile ICH7MDH)”
    iastor=”Intel(R) 82801GR/GH SATA AHCI Controller (Desktop ICH7R/DH)”
    iastor=”Intel(R) 82801GR/GH SATA RAID Controller (Desktop ICH7R/DH)”
    iastor=”Intel(R) 82801HEM/HBM SATA AHCI Controller (Mobile ICH8M-E/M)”
    iastor=”Intel(R) 82801HR/HH/HO SATA AHCI Controller (Desktop ICH8R)”
    iastor=”Intel(R) 82801HR/HH/HO SATA RAID Controller (Desktop ICH8R)”


    第三個文件是WINNT.SIF, 把[Data]和[OemInfFiles]修改成如下
    [Data]
    MSDosInitiated=0
    UnattendedInstall=Yes
    OemDrivers=OemInfFiles


    [OemInfFiles]
    OemDriverFlags=1
    OemDriverPathName=”%systemroot%\inf”
    OemInfName=”iaahci.inf”,”iastor.inf”


    6. integrate sp2/sp3 到安裝檔夾
    如果你的是最原始的XP盤 不帶service pack, 那麼下面步驟需要做兩次。
    當然首先是下載對應語言的service pack安裝包
    sp2
    http://www.microsoft.com/downloads/details.aspx?familyid=049C9DBE-3B8E-4F30-8245-9E368D3CDB5A
    sp3
    http://www.microsoft.com/downloads/details.aspx?FamilyId=5B33B5A8-5E76-401F-BE08-1E1555D4F3D4


    各service pack的語言需要和安裝盤的語言一致, 請更改再下載安裝程式。
    下載就保存在C盤吧,SP2 就保存成SP2.EXE; SP3就保存成SP3.EXE 免得亂
    XP安裝檔夾還是在c:\xpcd
    在CMD, c:\>
    sp0/sp1/sp1a載入sp2的方式是輸入命令 sp2.exe /integrate:c:\xpcd
    sp1/sp1a/sp2載入sp3的方式是輸入命令 sp3.exe /integrate:c:\xpcd


    注明sp0不能直接載入sp3, 由於sp1/sp1a沒有下載檔,所以只能做兩次第一次是sp0升sp2 然後sp2升sp3


    service pack載入完成



    7. 整個安裝檔就改好,然後需要的是把xpcd檔夾裏的檔夾刻錄成可以光碟啟動的安裝盤
    這 裏需要用到的是isobuster或者bbie去抓取光碟啟動檔”Microsoft Corporation.img”, 兩個軟體得效果都一樣,隨 你喜歡,isobuster是圖形介面,bbie10是用命令執行,所以相對程式很小。抓取img檔後再用nero或者其他刻錄軟體中加入 “Microsoft Corporation.img”就可以做出光碟啟動的光碟。
    下載網站, 使用方法我就不囉嗦了, 不是最主要的。
    http://www.isobuster.com/
    http://www.nu2.nu/bbie/


    我自己用的方法是用winpe裏面的OSCDIMG.EXE  ETFSBOOT.COM 程式製作ISO然後用用刻錄軟體刻錄


    假設像我把winpe放在c盤,那麼oscdimg.exe和etfsboot.com都在c:\winpe\, 所以命令是打開cmd, 回到winpe目錄。 在c:\winpe> 輸入
    oscdimg -l<disc Volume Label> -bETFSBOOT.COM -n c:\xpcd c:\xpcd.iso


    上面-l和<disc Volume Label>之間, -b和ETFSBOOT.COM 之間都沒有空格 其他看到的空格確實是要輸入的;
    < disc Volume Label>包括<>最好就是輸入與被改造的XP安裝盤一樣。 當然最後xpcd.iso檔案名可以按自己喜 歡改成XXX.iso, 不影響什麼。 然後直接用刻錄軟體把ISO檔刻出來,隨便打開sata native mode裝吧。


    打完收工!


    參考文章:
    How to integrate Windows XP Service Pack 2 files into the Windows XP installation folder
    http://support.microsoft.com/kb/900871


    How to obtain the latest Windows XP service pack
    http://support.microsoft.com/kb/322389


    Combining Windows XP with Service Pack 2 for reinstallation (Part 1: Introduction)
    http://support.microsoft.com/kb/894947
    Combining Windows XP and Windows XP Service Pack 2 for reinstallation (Part 2: Copying the Windows CD to the hard disk)
    http://support.microsoft.com/kb/894948
    Combining Windows XP and Service Pack 2 for reinstallation (Part 3: Integratng Service Pack 2 in the Setup files)
    http://support.microsoft.com/kb/894949
    Combining Windows XP with Service Pack 2 for reinstallation (Part 4: Reading the boot image file)
    http://support.microsoft.com/kb/894950