犯错了 (vm_nr_hugepages)

问题是这样的:操作系统是RHEL 5.3 64bit,上面装有Oracle和其它应用,开机之后,用top/free/ps等工具查看内存使用情况,发现少了几G内存,不知道被用到哪里去了。

折腾了几天之后,最后发现是有一个内核参数配置过大,导致一开机,有超过预期数量的内存被系统锁住了。因为系统启用了HugePages来分配Oracle的SGA,而在之前的某个时间,我把SGA的值改小了,这个参数(vm_nr_hugepages)又没相应地改小。这个低级错误的根本原因在于没有完全地理解这个参数,惭愧。

还有一个问题,用ipcs -m看到的Shared Memory Segment会比指定的SGA大一点,是什么道理?比如SGA设置为8G,用show sga看到确实是分配了8G(8589934592),而ipcs -m看到却是分配了8592031744,比8G大了2M。这样又导致vm_nr_hugepages=4096的时候 (HugePages size=2M,理论上4096*2M刚好=8G),系统无法成功分配8G内存给SGA,现在是把vm_nr_hugepages设成4196了。看了几篇文章,都没提到有类似问题。

有关Linux HugePages的参考信息

RHEL 5下为Oracle SGA启用huge pages

Memory

MEMORY_TARGET (SGA_TARGET) or HugePages – which to choose?

FBReader, My Tracks, WordPress

说说最近试用的三个软件 (Android)。

FBReader,电子书阅读器,目前只能读ePub格式的,貌似其它平台下还可以读txt, chm等。比较简单,没有太多的设置选项,该有的功能有。用它读了小说《1988我想和这个世界谈谈》,很沉重,把现实中的很多黑暗面都提到了。

My Tracks,是个绝好的软件,如果不在大陆用的话。Google出品,主要功能是在Google Mpas上记录你的GPS路线,当然还能记录移动速度,时间,距离等,个人认为相当实用。缺点是显示地图会有偏移,如果用卫星图就没问题,但可读性太差。完了还可以上传到My Maps和Google Docs(这个也不能用,时盾时通)。所以它从一个绝世好软变成了一个很不实用的软件(悲),如果非要保存一个路线图的话,只能根据录制的结果再去G Maps手动绘制了。

WordPress,官方出的Android客户端,感觉不错,目前为止用它发了两篇blog,推荐给用WordPress的同学使用(拜Windows Live所赐,WP的用户要激增?)

EOF

Oracle 11gr2对全外连接的优化

看到yangtingkun的贴子,说11gr2会对全外连接生成更优的执行计划,看起来还是很给力的,查询效率高了很多。手中没有机器装了11gr2,所以以下结论没亲自测试。

摘录结论如下,更详细信息请查看原贴:

在以前的版本中,”全外连接由一个外连接和一个反连接UNION ALL来获得,因此每张表必须扫描两次。”

—————————————————————————–
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————–
|   0 | SELECT STATEMENT     |      |    10 |   260 |    13   (8)| 00:00:01 |
|   1 |  VIEW                |      |    10 |   260 |    13   (8)| 00:00:01 |
|   2 |   UNION-ALL          |      |       |       |            |          |
|*  3 |    HASH JOIN OUTER |      |     9 |   234 |     7  (15)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| T1   |     9 |   117 |     3   (0)| 00:00:01 |
|   5 |     TABLE ACCESS FULL| T2   |     9 |   117 |     3   (0)| 00:00:01 |
|*  6 |    HASH JOIN ANTI |      |     1 |    26 |     7  (15)| 00:00:01 |
|   7 |     TABLE ACCESS FULL| T2   |     9 |   117 |     3   (0)| 00:00:01 |
|   8 |     TABLE ACCESS FULL| T1   |     9 |   117 |     3   (0)| 00:00:01 |
—————————————————————————–

在11gr2中,“Oracle优化了全外连接的执行计划,通过HASH JOIN FULL OUTER执行计划,使得每个表仅扫描一次,对比两个版本的逻辑读也可以看出,在11.2中全外连接的逻辑读减少了一半。”

———————————————————————————-
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
———————————————————————————-
|   0 | SELECT STATEMENT      |          |     9 |   234 |     9  (12)| 00:00:01 |
|   1 |  VIEW                 | VW_FOJ_0 |     9 |   234 |     9  (12)| 00:00:01 |
|*  2 |   HASH JOIN FULL OUTER|          |     9 |   234 |     9  (12)| 00:00:01 |
|   3 |    TABLE ACCESS FULL  | T1       |     9 |   117 |     4   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL  | T2       |     9 |   117 |     4   (0)| 00:00:01 |
———————————————————————————-

Update Oct 15, 2010

相对应的hint为NATIVE_FULL_OUTER_JOIN和NO_NATIVE_FULL_OUTER_JOIN

绝密飞行

一部典型的好莱坞式英雄主义影片,场面倒是挺好看,剧情没啥新意。三位主角二男一女加上一位“有感情”的无人机,Jamie Foxx死得早了点,要升华剧情也不带这样的吧。女主角不够漂亮,很多场面似曾相识。泰国风光那段不错,无人机撞向朝鲜机上怎么一点感动也没有。。。

天威已经慢慢改变我看电影的方式了,现在主要是电影院+天威免费高清,已经很少专门去下载了。天威的优点是方便,清晰,缺点是更新太慢,电影也相对旧一点。对我来说足够了,更新快了也看不来,加上好多旧电影没看过(蜘蛛侠1,2,3也是在上面看的,汗)。估计不会一直有免费大餐,人生苦短,及时行乐。

Shenzhen Speed

There are always millions of people at bus stop during off-the-job time (around 18:00-19:00). It really made me down to see the bus arrived at then left me behind. Ok byebye I was not alone.
I am not complaining about the more and more people nor the insufficient buses. What makes me feel upset most is the speed of metro system construction. So far there are 2 (or 3?) operating lines only in Shenzhen. The metro station around my home is not finished yet, while it is said that it would be done in the late of 2008 when I bought the house 3 years ago.
It’s not that Shenzhen which built a university in few months, not any more.

时间管理

前两天培训学了点时间管理的内容,分享一下。

一般来说,可以把事情分为下面四类

  1. 重要紧急
  2. 重要不紧急
  3. 不重要紧急
  4. 不重要不紧急

建议每天做个工作计划表,一天当中,应该在黄金时间(也就是你工作效率最高的时间段)做重要紧急的事,约占工作时间的20%。把大部分时间,用来做重要而不紧急的事,因为如何一直拖着不做,这类事情迟早变成重要紧急的事,约占65%,这样也可以避免长期做第1类到处救火的事,防患于未然。不重要紧急的事可做可不做,约占1x%。第四类不重要不紧急的事,最好不要做,<1%。

时间比例仅供参考,这种思路还是有点参考价值(顺便埋怨一下google tasks,什么时候才能变得好用且能同步到手机上)。

以上说起来简单,执行起来却不容易,首先对我来说把每件事情进行正确的分类已经有点困难了。。。

Oracle10gR2在RHEL 5下开启DIRECT IO

平台: Red Hat Linux Enterprise 5.3 64 bit, Oracle 10gR2 10.2.0.4 64 bit

Oracle开启direct io前

SQL> show parameter filesystemio_options

NAME                                 TYPE        VALUE
———————————— ———– ——————————
filesystemio_options                 string      ASYNCH

重启动oracle实例后,cached内存为160700KB
# free
             total       used       free     shared    buffers     cached
Mem:      32887744    4583296   28304448          0       2992    160700
-/+ buffers/cache:    4419604   28468140
Swap:      4192924          0    4192924

现在做一个大表查询
SQL> select /*+ full(channels) parallel(channels,4) */ count(*) from channels;
  COUNT(*)
———-
 793103894
Elapsed: 00:13:09.42

再看看内存使用情况,cached内存为9669284KB
# free
             total       used       free     shared    buffers     cached
Mem:      32887744   14155316   18732428          0      26484   9669284
-/+ buffers/cache:    4459548   28428196
Swap:      4192924          0    4192924

开启direct io
SQL> alter system set filesystemio_options=SETALL scope=spfile;
System altered.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

把cached内存释放掉
# sync; echo 3 > /proc/sys/vm/drop_caches
# free
             total       used       free     shared    buffers     cached
Mem:      32887744    4374724   28513020          0        540     47532
-/+ buffers/cache:    4326652   28561092
Swap:      4192924          0    4192924

重启Oracle instance
SQL> startup
ORACLE instance started.

Total System Global Area 4294967296 bytes
Fixed Size                  2089432 bytes
Variable Size             301993512 bytes
Database Buffers         3976200192 bytes
Redo Buffers               14684160 bytes
Database mounted.
Database opened.
SQL> show parameter filesystemio_options

NAME                                 TYPE        VALUE
———————————— ———– ——————————
filesystemio_options                 string      SETALL

此时cached内存94612KB
# free
             total       used       free     shared    buffers     cached
Mem:      32887744    4503964   28383780          0       1872     94612
-/+ buffers/cache:    4407480   28480264
Swap:      4192924          0    4192924

再做一个同样的查询
SQL> select /*+ full(channels) parallel(channels,4) */ count(*) from channels;
  COUNT(*)
———-
 793103894
Elapsed: 00:03:37.87

速度快了不少,cached内存96872KB,基本不变
# free
             total       used       free     shared    buffers     cached
Mem:      32887744    4559484   28328260          0      43556     96872
-/+ buffers/cache:    4419056   28468688
Swap:      4192924          0    4192924

RHEL 5下为Oracle SGA启用huge pages

在64位操作系统下,为oracle SGA启用huge pages memory mapping,可以更高效地使用系统内存。
有关huge pages和oracle的内存分配,可以参见下面两篇文章,讲解非常详细,推荐一看。
Memory
Pythian Goodies: The Answer to Free Memory, Swap, Oracle, and Everything

平台: Red Hat Linux Enterprise 5.3 64 bit, Oracle 10gR2 10.2.0.4 64 bit
启用huge pages的步骤。

查看默认的small page size
# getconf PAGE_SIZE
4096

查看huge page size
# grep Hugepagesize /proc/meminfo
Hugepagesize:     2048 kB

对比以上可以看出,一个是4k,一个是2M

假设要为SGA分配4G内存,则需要4G/2M=2048 pages
我们要在/etc/sysctl.conf里添加一句
vm.nr_hugepages = 2052  #比2048稍大
# echo  “vm.nr_hugepages = 2052” >> /etc/sysctl.conf
# sysctl -p

huge pages使用时会锁在内存中,不会被交换出去
需要在/etc/security/limits.conf里添加如下内容 (16777216KB是基于可扩展性考虑,大于4GB即可)
# cat >> /etc/security/limits.conf <<EOF
> oracle           soft    memlock        16777216
> oracle           hard    memlock        16777216
> EOF
#

重启oracle instance,然后查看huge page使用情况
# cat /proc/meminfo |grep Huge
HugePages_Total:  2052
HugePages_Free:   1702
HugePages_Rsvd:   1699
Hugepagesize:     2048 kB

创建基于复杂查询的快速刷新物化视图一例

如果基于一些复杂查询直接建立快速刷新的物化视图,oracle会返回一个这样的错误
ORA-12015: cannot create a fast refresh materialized view from a complex query
比如下面这条查询

SELECT t2.c1
      ,t4.c1
      ,MAX(t3.c1)
FROM (SELECT MAX(t1.c1) c1
      FROM t1) t4
    ,t2
    ,t3
WHERE t3.c1 > t4.c1
      AND t2.c1 = t3.c2
GROUP BY t2.c1
        ,t4.c1

在此感谢yangtingkun,咨询后他给出了一个使用嵌套物化视图的解决方案,如下

SQL> CREATE TABLE T1(C1 NUMBER);

Table created.

SQL> CREATE TABLE T2(C1 NUMBER);

Table created.

SQL> CREATE TABLE T3(C1 NUMBER,C2 NUMBER);

Table created.

SQL> CREATE MATERIALIZED VIEW LOG ON T1
  2  WITH ROWID, SEQUENCE (C1)
  3  INCLUDING NEW VALUES;

Materialized view log created.

SQL> CREATE MATERIALIZED VIEW LOG ON T2
  2  WITH ROWID, SEQUENCE (C1)
  3  INCLUDING NEW VALUES;

Materialized view log created.

SQL> CREATE MATERIALIZED VIEW LOG ON T3
  2  WITH ROWID, SEQUENCE (C1, C2)
  3  INCLUDING NEW VALUES;

Materialized view log created.

SQL> CREATE MATERIALIZED VIEW MV_T4
  2  REFRESH FAST AS
  3  SELECT COUNT(*) CN, COUNT(C1), MAX(T1.C1) C1
  4  FROM T1;

Materialized view created.

SQL> CREATE MATERIALIZED VIEW LOG ON MV_T4
  2  WITH ROWID, SEQUENCE (C1)
  3  INCLUDING NEW VALUES;

Materialized view log created.

SQL> CREATE MATERIALIZED VIEW  MV_T123
  2  REFRESH FAST AS
  3  SELECT T2.C1 T2_C1, MV_T4.C1 T4_C1, COUNT(*) CNT, COUNT(T3.C1), MAX(T3.C1)
  4  FROM MV_T4, T2, T3
  5  WHERE T3.C1 > MV_T4.C1
  6  AND T2.C1 = T3.C2
  7  GROUP BY T2.C1, MV_T4.C1;

Materialized view created.

快速刷新的物化视图创建成功。