Thursday, March 19, 2009

Ubuntu 8.10安装Oracle 10g笔记

上周末重新换了一块硬盘,因此操作系统和数据库都要重装一遍。重新安装Oracle 10g的过程中遇到不少有趣的问题,在解决这些问题的过程中学到了不少东西。
安装过程主要是参照孙高勇的那份文档来做的,但是在Ubuntu 8.10上面还会遇到一些其它问题。
1、关于安装是OUI中文的问题
该问题困扰我很久,一直没找到解决办法,最终采用英文环境进行安装以避免安装过程中的中文乱码问题。

2、安装过程运行runInstaller过程中会出现unzip的错误
该问题是由于Oracle 10g安装文件中/install 下的unzip与Ubuntu 8.10自带的unzip版本不一致导致的,我的解决方法如下:
install$ mv unzip unzipbak
install$ ln -s /usr/bin/unzip unzip

3、运行runInstaller后出现如下报错:
Error in writing to directory /tmp/OraInstall2009-03-16_02-26-36PM. Please
ensure that this directory is writable and has at least 60 MB of disk space.

该问题通过修改/install下所有文件的权限得于解决

在解决安装过程出现的问题时,发现了自己现在有一个很不好的习惯:在出现问题是首先想到的不是分析问题并尝试解决,而是通过Google找答案。
查了一下google的web history,发现只要在上网,每天都用使用Google进行搜索。在这过程中很多问题或许能找到答案,但是对于问题的理解并不深刻,下次出现该问题仍然无法解决。
在解决第二个问题过程中,我在Google没有发现任何有效信息,最终还是自己静下心来分析出错的日志,最终确认是由于unzip的版本冲突导致该问题。
在这过程中给我印象非常深刻,很多的问题在分析日志的过程中肯定能找到线索, 这在使用Ubuntu的过程中非常重要。

Wednesday, March 18, 2009

Java程序运行时,各变量在JVM中存放的位置

Java程序运行时,各变量在JVM中存放的位置

JVM对于内存是通过分成不同的部分来管理的,主要包括方法区(Method Area),堆(Heap),Java栈(Stack)。其中方法区存放装载到JVM中的类的信息,堆存放类的实例对象,Java棧以帧为单位保存线程运行的状态,存放每一个线程在程序执行过程中需要的数据信息。
对应于Java文件中的各种类变量,实例变量,类本身等内容,下面阐述一下它们在JVM中的存放位置。
public static final int i =1;
这个i在编译时就可以确认它的值,因此它作为一个常量被直接写在.class文件中,其它类用到这个i的时候,在编译过程中会拷贝i的值到该类的.class文件中。
public static final int i = (int)(Math.random() * 4);
如果是以上面这种形式的定义变量,因为其在编译时无法确认其值,在运行过程中才会确定值,因此它会当作一个类变量在类初始化是存放在方法区中。

static int i = 9;
以上这种形式定义的变量在类初始化时被初始化正确的值,并将其与类信息一起存放在方法区。

int i = 9;
这种形式定义的变量是实例变量,在类被实例化时赋于正确的初始值,和类实例对象一起存放在堆区。

void getXX(int a){
int i = 1;
}
上面这种形式定义的变量a是一个参数,i是一个局部变量,只在运算过程在有效,因此会存放在Java棧中棧帧中,在方法返回后其值也会无效,等待GC回收。


通过上面的论述可以推断出有哪些情况可能会导致OutOfMemory的错误了。
1、过多的类信息被装载到方法区,导致该区域OutOfMemory错误,在一些框架中通过反射机制生成大量的类信息可能导致该问题。
2、使用过多的static类型的类变量,特别是将大的数组,字符串等,导致方法区占用内存过多,造成OutOfMemory错误。由于JVM中并没有提供设置方法区大小的参数,因此只能通过加大JVM的内存来解决。
3、程序创建了过多的线程,导致Java棧使用内存过多,导致OutOfMemory。可通过-Xss来设置每一个Java thread stack 的大小来解决该问题。
4、程序生成了过多的实例对象,使得堆占用大量内存,最终出现OutOfMemory错误。 该问题可通过设置下面两个JVM启动参数来避免:
-Xms set initial Java heap size
-Xmx set maximum Java heap size

Tuesday, March 10, 2009

expect小记

今天在找资料时意外地学到了如何在Shell中进行交互。 学习资源在这里
下面是我写的一个在Terminal里通过bash操作SQLPlus的脚本。
#!/usr/bin/expect

spawn sqlplus

expect "name"

send "umail\r"

expect "password\r"

send "umail\r"

expect "SQL>"

send "desc employees\r"

expect "SQL>"

send "quit\r"
上面的几个指令的意义如下:
pawn命令激活一个Unix程序来进行交互式的运行。 
send命令向进程发送字符串。
expect命令等待进程的某些字符串。 
expect支持正规表达式并能同时等待多个字符串,并对每一个字符串执行不同的操作

这个东西非常有用,可以直接将SSH,FTP等写到脚本里面,不需要人工来干预它。在系统维护中可以写一些脚本处理某些批量处理的问题,而不需要有人来看着它。
更多内容请看这里

Monday, February 23, 2009

SQL WHERE多个子句的优先级关系

Oracle where字句优先级
今天在复习Oracle SQL,发现了一个以前一直都没有在意的问题。SQL查询时WHERE后面带有多个子句时,各子句之间有一定的优化关系。大约半年前就碰到过这个问题,当时TSE发给我一个SQL,告诉我说系统存在严重的数据问题,因为这个SQL查出了很多有问题的数据。当时吓得我一身冷汗,然后自己马上连到线上数据库,按照他说的业务需求自己写了个SQL,并执行了一下。我的SQL执行得出的结果并没有他说的数据不对的问题。于是比较了两个SQL,发现在写OR子句的位置有区别。当时只是得出了WHERE子句有一定的关系,但是具体的关系并没有去深入研究。今天在看一个Presentation时终于注意到了一个确切的说法。 在SQL的WHERE后面的多个子句有如下的优先关系:
优先级
1 算术运算符
2 连接符
3 比较符
4 IS [NOT] NULL, LIKE, [NOT] IN
5 [NOT] BETWEEN
6 NOT
7 AND
8 OR

下面用一个例子来证明一下这之间的关系
SQL>SELECT last_name, job_id, salary
2 FROM employees
3 WHERE job_id = 'SA_REP'
4 OR job_id = 'AD_PRES'
5 AND salary > 15000;

执行结果如下:SQL> /

LAST_NAME JOB_ID SALARY
------------------------- ---------- ----------
King AD_PRES 24000
Tucker SA_REP 10000
Bernstein SA_REP 9500
Hall SA_REP 9000
Olsen SA_REP 8000
Cambrault SA_REP 7500
Tuvault SA_REP 7000
King SA_REP 10000
Sully SA_REP 9500
McEwen SA_REP 9000
Smith SA_REP 8000
Doran SA_REP 7500
Sewall SA_REP 7000
Vishney SA_REP 10500
Greene SA_REP 9500
Marvins SA_REP 7200
Lee SA_REP 6800
Ande SA_REP 6400
Banda SA_REP 6200
Ozer SA_REP 11500
Bloom SA_REP 10000
Fox SA_REP 9600
Smith SA_REP 7400
Bates SA_REP 7300
Kumar SA_REP 6100
Abel SA_REP 11000
Hutton SA_REP 8800
Taylor SA_REP 8600
Livingston SA_REP 8400
Grant SA_REP 7000
Johnson SA_REP 6200

31 rows selected

现在修改一下OR的位置再执行一次:
SQL> select last_name,job_id,salary from employees where job_id = 'SA_REP'
2 and salary > 15000 or job_id = 'AD_PRES';

LAST_NAME JOB_ID SALARY
------------------------- ---------- ----------
King AD_PRES 24000

发现两次查询的数据差别非常大。 下面来分析一下执行的过程,我在网上并没有找到确切的描述,下面这些都是我通过对数据观察推断出来的结论。

在第一个SQL中真正执行的应该是如下语句:
select last_name,job_id,salary from employees where job_id = 'SA_REP' or (job_id = 'AD_PRES' and salary > 15000)
因为AND条件比OR高,因此先进行运算
在第二个SQL中是按照where各子句的顺序过滤数据,在执行过程中job_id = 'SA_REP'
and salary > 15000 没有取得符合条件的数据,只有job_id = 'AD_PRES'子句找到了符合条件的数据。 下面执行一下语句验证一下:
SQL> select last_name,job_id,salary from employees where job_id='AD_PRES';

LAST_NAME JOB_ID SALARY
------------------------- ---------- ----------
King AD_PRES 24000

其他几个运算符的优先级也可按照上面的方法来进行分析。

Saturday, February 21, 2009

About this blog

This is another blog.I will post all my thought about computer and software.
I hope i can consistently write...