弹冠相庆

December 14, 2010

又搬家了

Filed under: Uncategorized — Corey @ 01:30

刚迁来这里不久,由于wordpress.com被盾,又要搬家了。

请访问 http://www.croey.com

November 29, 2010

The Social Network

Filed under: Uncategorized — Corey @ 22:28

冲着大卫芬奇和Facebook,下载了The Social Network,影片质量较差,dvdscr泄露版,画面和音乐效果都不好,有兴趣看的同学建议等好点的版本。

整部影片就是讲fb的成长史,相信没有IT背景的人看起来会有点无趣。关键字:失恋小伙,哈佛,朋友,金钱,背叛,编程,黑客,硅谷,风投… Mark跟Sheldon比起来还是不够geek,当然也真实得多。没有技术高超的黑客对抗,没有眼前一亮的美女,也压根看不出有什么“奥斯卡”潜质,看来我对这种自传类的电影还是不感兴趣。

满分5分我给2分。

November 22, 2010

简评Android 2.2 (CyanogenMod 6.1.0 RC1)

Filed under: Uncategorized — Corey @ 12:37
Tags: ,

近来把手机升级到了Android 2.2 (CyanogenMod 6.1.0 RC1 rom),使用了一周左右,简单说说使用情况。

先说缺点:

1. 慢,明显比2.1和1.5都慢,不知是用了ADWLauncher的原因还是啥,感觉屏幕滑动呆滞。

2. 自带的calendar, weather等widget不好用,缺少了htc sense之后,必须自己去找相应的widget。

3. 万年老病了,WIFI断线的问题还是没解决 (在电信配的华为无线路由上才有此问题),应该路由路本身也有问题,不然为啥用其它路由器没问题?

4. 自带短信和邮件介面很难看。

5. 拍照程序偶尔会挂掉。

优点:

1. 用官方2.1时无线上网偶尔会没信号,这个版本没问题。

2. 可以APP2SD,这样装”大型”游戏时不会捉襟见肘了。

3. 打电话时延迟几秒才拨号的问题也解决了。

4. 可以装软件实现wifi tether(似乎2.2之前也可以实现?没试过)。

不满意,继续寻找可用的2.2 rom,目前期待一下这个 Android: Froyo with HTC Sense Coming to the HTC Hero http://bit.ly/9Ayk6t

November 11, 2010

wordpress被封了

Filed under: Uncategorized — Corey @ 11:16

刚迁过来这边,又被景德镇的功夫网封掉了,FML

October 23, 2010

犯错了 (vm_nr_hugepages)

Filed under: Uncategorized — Corey @ 13:58
Tags: ,

问题是这样的:操作系统是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?

October 15, 2010

FBReader, My Tracks, WordPress

Filed under: Uncategorized — Corey @ 22:25
Tags:

说说最近试用的三个软件 (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

October 14, 2010

Oracle 11gr2对全外连接的优化

Filed under: Uncategorized — Corey @ 20:46
Tags:

看到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

October 13, 2010

绝密飞行

Filed under: Uncategorized — Corey @ 21:29
Tags: ,

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

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

October 12, 2010

Shenzhen Speed

Filed under: Uncategorized — Corey @ 19:20
Tags:

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.

October 11, 2010

时间管理

Filed under: Uncategorized — Corey @ 20:34
Tags:

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

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

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

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

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

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

October 10, 2010

搬家了

Filed under: Uncategorized — Corey @ 23:05

把itpub的几篇文章搬了过来,以后就维护这个了。

这里好像是强制必须使用category(历史原因?),有谁知道在文章里只显示tag而不显示category吗?

Oracle10gR2在RHEL 5下开启DIRECT IO

Filed under: Uncategorized — Corey @ 23:01
Tags: ,

平台: 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

Filed under: Uncategorized — Corey @ 22:26
Tags: ,

在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

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

Filed under: Uncategorized — Corey @ 22:24
Tags:

如果基于一些复杂查询直接建立快速刷新的物化视图,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.

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

用pl/sql分割字符串

Filed under: Uncategorized — Corey @ 22:06
Tags:

pl/sql 自带的package里面有一个dbms_utility.comma_to_table,可以用来分割以’,’为分割符
的字符串,并且对返回的字符数组类型也有限制,并不是一个通用的方法。如果你的需求恰
好符合该方法的定义,可以考虑使用。与此对应的方法是dbms_utility.table_to_comma,是
把字符串数组转换成字符串。

以下实现改自Tom Kyte的例子

功能: 用pl/sql function分割字符串,并返回相应的number数组

CREATE OR REPLACE TYPE typ_number_table as table of NUMBER;

CREATE OR REPLACE FUNCTION split_string(p_string    IN VARCHAR2
                                                                         ,p_delimiter IN VARCHAR2 DEFAULT ‘,’)
  RETURN typ_number_table IS
  l_string    VARCHAR2(32000) DEFAULT p_string || p_delimiter;
  l_num       NUMBER;
  l_num_table typ_number_table := typ_number_table();
BEGIN
  LOOP
    l_num := instr(l_string
                  ,p_delimiter);
    EXIT WHEN(nvl(l_num
                 ,0) = 0);
    l_num_table.EXTEND;
    l_num_table(l_num_table.COUNT) := to_number(trim(substr(l_string
                                                                                               ,1
                                                                                               ,l_num – 1)));
    l_string := substr(l_string
                      ,l_num + length(p_delimiter));
  END LOOP;
  RETURN l_num_table;
END;

一个并行查询的例子

Filed under: Uncategorized — Corey @ 22:02
Tags:

系统有2个cpu,每个4核,raid 1+0,db为oracle 10gr2 64bit

1. 先直接来个查询看看
SQL> set autot trace
SQL> SELECT COUNT(*)
FROM channels
WHERE channels.snapshot_time > to_date(’10/28/2008 00:00′
                                      ,’MM/DD/YYYY HH24:MI:SS’)
      AND channels.snapshot_time <= to_date(’10/29/2008 23:50′
                                           ,’MM/DD/YYYY HH24:MI:SS’);

Elapsed: 00:01:15.96

Execution Plan
———————————————————-
Plan hash value: 1848729565

———————————————————————————————————–
| Id  | Operation                  | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
———————————————————————————————————–
|   0 | SELECT STATEMENT           |              |     1 |    11 |   533K  (7)| 01:46:45 |       |       |
|   1 |  SORT AGGREGATE            |              |     1 |    11 |            |          |       |       |
|*  2 |   FILTER                   |              |       |       |            |          |       |       |
|   3 |    PARTITION RANGE ITERATOR|              |    89M|   936M|   533K  (7)| 01:46:45 |   KEY |   KEY |
|*  4 |     INDEX FAST FULL SCAN   | CHANNELS_UNQ |    89M|   936M|   533K  (7)| 01:46:45 |   KEY |   KEY |
———————————————————————————————————–

Predicate Information (identified by operation id):
—————————————————

   2 – filter(TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’10/29/2008
              23:50′,’MM/DD/YYYY HH24:MI:SS’))
   4 – filter(“CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’10/29/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’) AND
              “CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’))
Statistics
———————————————————-
       8962  recursive calls
          0  db block gets
     308209  consistent gets
     306423  physical reads
          0  redo size
        518  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
        141  sorts (memory)
          0  sorts (disk)
          1  rows processed

可以看到,默认走了索引,用时1分16秒左右

2. 强制走全表扫描看看
SQL> alter system flush buffer_cache;
SQL> alter system flush shared_pool;

SQL>
SELECT /*+ full(channels)*/
 COUNT(*)
FROM channels
WHERE channels.snapshot_time > to_date(’10/28/2008 00:00′
                                      ,’MM/DD/YYYY HH24:MI:SS’)
      AND channels.snapshot_time <= to_date(’10/29/2008 23:50′
                                           ,’MM/DD/YYYY HH24:MI:SS’);

Elapsed: 00:00:49.31

Execution Plan
———————————————————-
Plan hash value: 4225188383

——————————————————————————————————-
| Id  | Operation                  | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
——————————————————————————————————-
|   0 | SELECT STATEMENT           |          |     1 |    11 |   714K  (6)| 02:22:51 |       |       |
|   1 |  SORT AGGREGATE            |          |     1 |    11 |            |          |       |       |
|*  2 |   FILTER                   |          |       |       |            |          |       |       |
|   3 |    PARTITION RANGE ITERATOR|          |    89M|   936M|   714K  (6)| 02:22:51 |   KEY |   KEY |
|*  4 |     TABLE ACCESS FULL      | CHANNELS |    89M|   936M|   714K  (6)| 02:22:51 |   KEY |   KEY |
——————————————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   2 – filter(TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’10/29/2008
              23:50′,’MM/DD/YYYY HH24:MI:SS’))
   4 – filter(“CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’10/29/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’)
              AND “CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’))
Statistics
———————————————————-
       8922  recursive calls
          0  db block gets
     404835  consistent gets
     403115  physical reads
          0  redo size
        518  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
        141  sorts (memory)
          0  sorts (disk)
          1  rows processed

全表扫描,用时49秒

3. 并行度为4的查询

SQL> alter system flush buffer_cache;
SQL> alter system flush shared_pool;
SQL>
SELECT /*+ full(channels) parallel(channels,4) */
 COUNT(*)
FROM channels
WHERE channels.snapshot_time > to_date(’10/28/2008 00:00′
                                      ,’MM/DD/YYYY HH24:MI:SS’)
      AND channels.snapshot_time <= to_date(’10/29/2008 23:50′
                                           ,’MM/DD/YYYY HH24:MI:SS’);

Elapsed: 00:00:11.96

Execution Plan
———————————————————-
Plan hash value: 166461870

———————————————————————————————————————————
| Id  | Operation               | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
———————————————————————————————————————————
|   0 | SELECT STATEMENT        |          |     1 |    11 |   198K  (6)| 00:39:37 |       |       |        |      |            |
|   1 |  SORT AGGREGATE         |          |     1 |    11 |            |          |       |       |        |      |            |
|*  2 |   PX COORDINATOR        |          |       |       |            |          |       |       |        |      |            |
|   3 |    PX SEND QC (RANDOM)  | :TQ10000 |     1 |    11 |            |          |       |       |  Q1,00 | P->S | QC (RAND)  |
|   4 |     SORT AGGREGATE      |          |     1 |    11 |            |          |       |       |  Q1,00 | PCWP |            |
|*  5 |      FILTER             |          |       |       |            |          |       |       |  Q1,00 | PCWC |            |
|   6 |       PX BLOCK ITERATOR |          |    89M|   936M|   198K  (6)| 00:39:37 |   KEY |   KEY |  Q1,00 | PCWC |            |
|*  7 |        TABLE ACCESS FULL| CHANNELS |    89M|   936M|   198K  (6)| 00:39:37 |   KEY |   KEY |  Q1,00 | PCWP |            |
———————————————————————————————————————————

Predicate Information (identified by operation id):
—————————————————

   2 – filter(TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’10/29/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
   5 – filter(TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’10/29/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
   7 – filter(“CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’10/29/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’) AND
              “CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’10/28/2008 00:00′,’MM/DD/YYYY HH24:MI:SS’))
Statistics
———————————————————-
       9661  recursive calls
          4  db block gets
     405834  consistent gets
     403140  physical reads
        632  redo size
        518  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
        152  sorts (memory)
          0  sorts (disk)
          1  rows processed

全表加并行,用时11秒.

Oracle10gR2在RHEL 5下开启异步IO

Filed under: Uncategorized — Corey @ 21:43
Tags: ,

记录一下步骤,内容主要来自这篇文章

平台:Redhat Enterprise Linux 5 64bit,Oracle 10gR2 10.2.0.4 64bit

1、首先用root用户安装以下必要的rpm包

# rpm -Uvh libaio-0.3.106-3.2.x86_64.rpm
# rpm -Uvh libaio-devel-0.3.106-3.2.x86_64.rpm

2、在系统级支持异步I/O
  与[Note 225751.1]介绍的在RHEL 3里面设置异步IO不同,不需要设置aio-max-size,而且’/proc/sys/fs’路径下也没有这个文件。因为从2.6 kernel开始,已经取消了对IO size的限制[Note 549075.1]。另外根据[Note 471846.1],Oracle建议将aio-max-nr的值设置为1048576或更高。

# echo > /proc/sys/fs/aio-max-nr 1048576

要永久修改这个内核参数,需要在/etc/sysctl.conf加上下面这句
fs.aio-max-nr = 1048576
使参数生效
#/sbin/sysctl -p

3、在数据库级启用异步I/O
  首先修改数据库参数。与[Note 225751.1]在RHEL 3里面设置异步IO不同,Oracle10gR2默认是打开了对异步IO的支持的,不需要重新编译数据库软件。在’$ORACLE_HOME/rdbms/lib’路径下,也没有’skgaioi.o’这个文件。在某些情况下,Oracle无法将IO行为或事件报告给操作系统[Note 365416.1],因此需要做以下操作。

这里开始换成oracle用户

SQL> alter system set disk_asynch_io=TRUE scope=spfile;

SQL> alter system set filesystemio_options=asynch scope=spfile;

SQL>shutdown immediate
$ cd $ORACLE_HOME/rdbms/lib
$ ln -s /usr/lib/libaio.so.1 skgaio.o
$ make PL_ORALIBS=-laio -f ins_rdbms.mk async_on
SQL>startup

  在Oracle10gR2中AIO默认已经是开启的了。可以通过ldd或者nm来检查oracle是否已经启用了AIO支持,有输出代表已经启用。

[oraprod@db01 ~]$ /usr/bin/ldd $ORACLE_HOME/bin/oracle | grep libaio
libaio.so.1 => /usr/lib64/libaio.so.1 (0x00002aaaac4a9000)
[oraprod@db01 ~]$ /usr/bin/nm $ORACLE_HOME/bin/oracle | grep io_getevent
w io_getevents@@LIBAIO_0.4

4、检查异步I/O是否在使用
  根据[Note 370579.1],可以通过查看slabinfo统计信息查看操作系统中AIO是否运行,slab是Linux的内存分配器,AIO相关的内存结构已经分配,kiocb值的第二列和第三列非0即是已使用。与kernel 2.4.x不同,没有显示kiobuf,因为从kernel 2.5.43开始,kiobuf已经从内核中被移除。

$ cat /proc/slabinfo | grep kio
kioctx 64 110 384 10 1 : tunables 54 27 8 : slabdata 11 11 0
kiocb 13 315 256 15 1 : tunables 120 60 8 : slabdata 21 21 44

两个Vim正则的小技巧

Filed under: Uncategorized — Corey @ 21:31
Tags: ,

1. 查找不包括”2009″的行 ^\(.*2009\)\@!.*$
2. 查找不包括”2009″的单词 \<\(\(\(2009\)\@!\)\w\)\+\>

一个CBO错用索引的例子

Filed under: Uncategorized — Corey @ 21:20
Tags:

channels表,索引是channels_unq(svr_grp_id, channels_record_id, snapshot_time)

执行如下语句

SELECT channels.channel_record_id
      ,SUM(channels.max_viewers) AS viewer_sum
FROM channels
WHERE channels.snapshot_time > to_date(’11/25/2008 23:50′
                                      ,’MM/DD/YYYY HH24:MI:SS’)
      AND channels.snapshot_time <= to_date(’12/06/2008 23:50′
                                           ,’MM/DD/YYYY HH24:MI:SS’)
GROUP BY channels.channel_record_id;

474 rows selected.

Elapsed: 02:06:21.62

Execution Plan
———————————————————-
Plan hash value: 443160641

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

| Id  | Operation                            | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |

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

|   0 | SELECT STATEMENT                     |              |     1 |    39 | 365   (1)| 00:00:05 |       |       |

|   1 |  HASH GROUP BY                       |              |     1 |    39 | 365   (1)| 00:00:05 |       |       |

|*  2 |   FILTER                             |              |       |       | |          |       |       |

|   3 |    PARTITION RANGE ITERATOR          |              |     1 |    39 | 364   (0)| 00:00:05 |   KEY |   KEY |

|   4 |     TABLE ACCESS BY LOCAL INDEX ROWID| CHANNELS     |     1 |    39 | 364   (0)| 00:00:05 |   KEY |   KEY |

|*  5 |      INDEX SKIP SCAN                 | CHANNELS_UNQ |     1 |       | 364   (0)| 00:00:05 |   KEY |   KEY |

———————————————————————————————————————
Predicate Information (identified by operation id):
—————————————————

   2 – filter(TO_DATE(’11/25/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’12/06/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
   5 – access(“CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’11/25/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’) AND “CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’12/06/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
       filter(“CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’11/25/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’) AND “CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’12/06/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))

Statistics
———————————————————-
       8100  recursive calls
          0  db block gets
  577374676  consistent gets
    4631561  physical reads
      59904  redo size
      11269  bytes sent via SQL*Net to client
        833  bytes received via SQL*Net from client
         33  SQL*Net roundtrips to/from client
         91  sorts (memory)
          0  sorts (disk)
        474  rows processed

用了两个多小时,可以看到,在第5步不正确地走了索引 channels_unq

把查询语句加个hint,强制用全表扫描

SELECT /*+ FULL(channels) */channels.channel_record_id
      ,SUM(channels.max_viewers) AS viewer_sum
FROM channels
WHERE channels.snapshot_time > to_date(’11/25/2008 23:50′
                                      ,’MM/DD/YYYY HH24:MI:SS’)
      AND channels.snapshot_time <= to_date(’12/06/2008 23:50′
                                           ,’MM/DD/YYYY HH24:MI:SS’)
GROUP BY channels.channel_record_id;

474 rows selected.

Elapsed: 00:12:33.59

Execution Plan
———————————————————-
Plan hash value: 4197359631

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

| Id  | Operation                  | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |

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

|   0 | SELECT STATEMENT           |          |     1 |    39 |  1770K  (1)| 05:54:04 |       |       |

|   1 |  HASH GROUP BY             |          |     1 |    39 |  1770K  (1)| 05:54:04 |       |       |

|*  2 |   FILTER                   |          |       |       |            | |       |       |

|   3 |    PARTITION RANGE ITERATOR|          |     1 |    39 |  1770K  (1)| 05:54:04 |   KEY |   KEY |

|*  4 |     TABLE ACCESS FULL      | CHANNELS |     1 |    39 |  1770K  (1)| 05:54:04 |   KEY |   KEY |

——————————————————————————————————-
Predicate Information (identified by operation id):
—————————————————

   2 – filter(TO_DATE(’11/25/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’)<TO_DATE(’12/06/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
   4 – filter(“CHANNELS”.”SNAPSHOT_TIME”>TO_DATE(’11/25/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’) AND “CHANNELS”.”SNAPSHOT_TIME”<=TO_DATE(’12/06/2008 23:50′,’MM/DD/YYYY HH24:MI:SS’))
Statistics
———————————————————-
          1  recursive calls
          0  db block gets
    2762409  consistent gets
    2391028  physical reads
       4236  redo size
      11269  bytes sent via SQL*Net to client
        833  bytes received via SQL*Net from client
         33  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        474  rows processed

这次走全表了,用时12分钟左右。

没有时间仔细去找原因,猜想:
1. 可能是最新统计信息没收集
2. 由于使用了绑定变量(在这个例子中简化了,没体现出来),可能是bind varible peeking的问题

October 9, 2010

Test

Filed under: Uncategorized — Corey @ 00:26

This post is from wordpress android client. A great app and I have nice blogging experiences.

October 8, 2010

老照片

Filed under: Uncategorized — Corey @ 20:03
Tags:

看exif信息,是dkt在2007-12-20用索爱K750c拍的,地点为飞亚达楼下,图中四字成语的作者分别为弹(我)冠(roby)相(lei)庆(zehong)

October 7, 2010

迁了

Filed under: Uncategorized — Corey @ 22:37
Tags:

wordpress,访问不稳定,而且有点慢,中文url太土

March 29, 2010

Linux IO性能测试

Filed under: Uncategorized — Corey @ 09:07
Tags:
近来想了解一下开发环境的IO性能,分别用dd/orion/iozone/bonnie++四种工具测试了一下
开发环境系统配置如下:
Intel SR1625 server, 2 CPU, 32GB内存, 用主板自带卡做了raid1+0,8个7200转SATA硬盘
操作系统是RHEL 5.3 64位
因为物理内存是32GB,因此整个过程都选用了60GB+的数据量来测试,以避免cache的影响
1. 首先用自带的dd命令先测一下, 块大小为8k
dd只能提供一个大概的测试结果,而且是连续IO而不是随机IO
读测试
# time dd if=/dev/sda2 of=/dev/null bs=8k count=8388608
8388608+0 records in
8388608+0 records out
68719476736 bytes (69 GB) copied, 516.547 seconds, 133 MB/s
real    8m36.926s
user    0m0.117s
sys     0m55.216s
写测试
# time dd if=/dev/zero of=/opt/iotest bs=8k count=8388608
8388608+0 records in
8388608+0 records out
68719476736 bytes (69 GB) copied, 888.398 seconds, 77.4 MB/s
real    14m48.743s
user    0m3.678s
sys     2m47.158s
读写测试
# time dd if=/dev/sda2 of=/opt/iotest bs=8k count=8388608
8388608+0 records in
8388608+0 records out
68719476736 bytes (69 GB) copied, 1869.89 seconds, 36.8 MB/s
real    31m10.343s
user    0m2.613s
sys     3m25.548s
2. 接下来用Oracle的orion工具来测一下
解压即可使用
# gzip orion_linux_x86-64.gz
测异步IO时需要libaio库
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64
# echo $LD_LIBRARY_PATH
:/opt/oracle/product/10.2.0/lib:/usr/lib64
创建配置文件mytest.lun,列出要测试的分区即可. 注意文件名前缀要跟下面的 testname一致
# vi mytest.lun
查看mytest.jun内容
# cat mytest.lun
/dev/sda2
先来个simple test
# ./orion_linux_x86-64 -run simple -testname mytest -num_disks 8
查看测试结果
# cat mytest_20081111_1431_summary.txt
ORION VERSION 11.1.0.7.0
Commandline:
-run simple -testname mytest -num_disks 8
This maps to this test:
Test: mytest
Small IO size: 8 KB
Large IO size: 1024 KB
IO Types: Small Random IOs, Large Random IOs
Simulated Array Type: CONCAT
Write: 0%
Cache Size: Not Entered
Duration for each Data Point: 60 seconds
Small Columns:,      0
Large Columns:,      0,      1,      2,      3,      4,      5,      6,      7,      8,      9,     10,     11,     12,     13,     14,     15,     16
Total Data Points: 38
Name: /dev/sda2 Size: 629143441920
1 FILEs found.
Maximum Large MBPS=56.97 @ Small=0 and Large=7
Maximum Small IOPS=442 @ Small=40 and Large=0
Minimum Small Latency=14.62 @ Small=1 and Large=0
最大MBPS为56.97,最大IOPS为442
再测一下8k随机读操作
# ./orion_linux_x86-64 -run advanced -testname mytest -num_disks 8 -size_small 8 -size_large 8 -type rand &
看看结果
# cat mytest_20081111_1519_summary.txt
ORION VERSION 11.1.0.7.0
Commandline:
-run advanced -testname mytest -num_disks 8 -size_small 8 -size_large 8 -type rand
This maps to this test:
Test: mytest
Small IO size: 8 KB
Large IO size: 8 KB
IO Types: Small Random IOs, Large Random IOs
Simulated Array Type: CONCAT
Write: 0%
Cache Size: Not Entered
Duration for each Data Point: 60 seconds
Small Columns:,      0
Large Columns:,      0,      1,      2,      3,      4,      5,      6,      7,      8,      9,     10,     11,     12,     13,     14,     15,     16
Total Data Points: 38
Name: /dev/sda2 Size: 629143441920
1 FILEs found.
Maximum Large MBPS=3.21 @ Small=0 and Large=13
Maximum Small IOPS=448 @ Small=38 and Large=0
Minimum Small Latency=15.16 @ Small=1 and Large=0
最大MBPS为3.21(这么低??),最大IOPS为448
再测一下1M顺序读操作, 失败了, 原因不明…
# ./orion_linux_x86-64 -run advanced -testname mytest -num_disks 8 -size_small 1024 -size_large 1024 -type seq
ORION: ORacle IO Numbers — Version 11.1.0.7.0
mytest_20081114_1349
Test will take approximately 73 minutes
Larger caches may take longer
rwbase_run_test: rwbase_reap_req failed
rwbase_run_process: rwbase_run_test failed
rwbase_rwluns: rwbase_run_process failed
orion_warm_cache: Warming cache failed. Continuing
看看结果
# cat mytest_20081111_1620_summary.txt
ORION VERSION 11.1.0.7.0
Commandline:
-run advanced -testname mytest -num_disks 8 -size_small 1024 -size_large 1024 -type seq
This maps to this test:
Test: mytest
Small IO size: 1024 KB
Large IO size: 1024 KB
IO Types: Small Random IOs, Large Sequential Streams
Number of Concurrent IOs Per Stream: 4
Force streams to separate disks: No
Simulated Array Type: CONCAT
Write: 0%
Cache Size: Not Entered
Duration for each Data Point: 60 seconds
没结果,失败
3. 用iozone来测一下
安装
# tar -xvf iozone3_345.tar
# make linux-AMD64
指定64G的文件,只测read/reread和write/rewrite,记录大小从4k-16k.同时生成一个excel文件iozone.wks
# ./iozone -Rab iozone.wks -s64G -i 0 -i 1 -y 4k -q 16k
        Iozone: Performance Test of File I/O
                Version $Revision: 3.345 $
                Compiled for 64 bit mode.
                Build: linux-AMD64
        Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins
                     Al Slater, Scott Rhine, Mike Wisner, Ken Goss
                     Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR,
                     Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner,
                     Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone,
                     Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root,
                     Fabrice Bacchella, Zhenghua Xue, Qin Li.
        Run began: Tue Nov 11 10:23:25 2008
        Excel chart generation enabled
        Auto Mode
        File size set to 67108864 KB
        Using Minimum Record Size 4 KB
        Using Maximum Record Size 16 KB
        Command line used: ./iozone -Rab iozone.wks -s64G -i 0 -i 1 -y 4k -q 16k
        Output is in Kbytes/sec
        Time Resolution = 0.000001 seconds.
        Processor cache size set to 1024 Kbytes.
        Processor cache line size set to 32 bytes.
        File stride size set to 17 * record size.
                                                            random  random    bkwd   record   stride                                 
              KB  reclen   write rewrite    read    reread    read   write    read  rewrite     read   fwrite frewrite   fread  freread
        67108864       4   72882   69470   104898   125512
        67108864       8   72083   69256   133689   109061
        67108864      16   73375   69155   142019   116034
iozone test complete.
Excel output is below:
"Writer report"
        "4"  "8"  "16"
"67108864"   72882  72083  73375
"Re-writer report"
        "4"  "8"  "16"
"67108864"   69470  69256  69155
"Reader report"
        "4"  "8"  "16"
"67108864"   104898  133689  142019
"Re-Reader report"
        "4"  "8"  "16"
"67108864"   125512  109061  116034
可以看到,8k的写是72M/s左右,读是133M/s左右,跟dd的结果比较接近
测一下64G文件8k随机读写
# ./iozone -Rab iozone.wks -s64G -i 2 -y 8k -q 8k
        Iozone: Performance Test of File I/O
                Version $Revision: 3.345 $
                Compiled for 64 bit mode.
                Build: linux-AMD64
        Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins
                     Al Slater, Scott Rhine, Mike Wisner, Ken Goss
                     Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR,
                     Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner,
                     Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone,
                     Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root,
                     Fabrice Bacchella, Zhenghua Xue, Qin Li.
        Run began: Fri Nov 14 15:52:01 2008
        Excel chart generation enabled
        Auto Mode
        File size set to 67108864 KB
        Using Minimum Record Size 8 KB
        Using Maximum Record Size 8 KB
        Command line used: ./iozone -Rab iozone.wks -s64G -i 2 -y 8k -q 8k
        Output is in Kbytes/sec
        Time Resolution = 0.000001 seconds.
        Processor cache size set to 1024 Kbytes.
        Processor cache line size set to 32 bytes.
        File stride size set to 17 * record size.
                                                            random  random    bkwd   record   stride                                 
              KB  reclen   write rewrite    read    reread    read   write    read  rewrite     read   fwrite frewrite   fread  freread
        67108864       8
Error reading block at 6501007360
read: Success
出错了(??)
4. 最后用bonnie++测一下
安装
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64
# ./configure
# make
# make install
开始测试,默认文件大小是内存的2倍
# bonnie++ -d /opt/IOTest/ -m sva17 -u root
Using uid:0, gid:0.
Writing with putc()…done
Writing intelligently…done
Rewriting…done
Reading with getc()…done
Reading intelligently…done
start ’em…done…done…done…
Create files in sequential order…done.
Stat files in sequential order…done.
Delete files in sequential order…done.
Create files in random order…done.
Stat files in random order…done.
Delete files in random order…done.
Version 1.03e       ——Sequential Output—— –Sequential Input- –Random-
                    -Per Chr- –Block– -Rewrite- -Per Chr- –Block– –Seeks–
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
sva17           63G 52391  84 35222   7 34323   6 56362  88 131568  10 176.7   0
                    ——Sequential Create—— ——–Random Create——–
                    -Create– –Read— -Delete– -Create– –Read— -Delete–
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
sva17,63G,52391,84,35222,7,34323,6,56362,88,131568,10,176.7,0,16,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++
顺序写: 按字符是52391KB/s,CPU占用率84%;按块是35222KB/s,CPU占用率7%
顺序读: 按字符是56362KB/s, CPU占用率88%;按块是131568KB/s,CPU占用率10%
随机读写: 176.7次/s,CPU占用率0%
后两项全是++ (没结果?)
结论:不同测试工具构建出来的测试环境不同,侧重点也不一样,得到的结果可能相差比较大。
MBPS:
dd和iozone比较接近,读写分别是130+和70+。
orion读57左右,写没测(会删掉分区内所有文件!)
bonnie++按块读是130左右,写是35左右;按字符读是56左右,写是52左右
IOPS:
dd 无结果
orion 440左右(只读)
iozone 出错
bonnie++ 176.7 (读写)

November 29, 2009

久等的LISTAGG

Filed under: Uncategorized — Corey @ 10:52
Tags:
在看Tom的11 things about 11gr2.ppt,里面提到要实现列转行的统计:
1. 9i里面要自己实现统计函数

2. 10g里有个sys_connect_by_path可用

SQL> select deptno,
  2         substr(
  3         max(sys_connect_by_path(ename, ‘; ‘)),
  4         3) enames
  5    from (
  6  select deptno,
  7         ename,
  8         row_number()
  9         over
 10         (partition by deptno
 11          order by ename) rn
 12    from emp
 13         )
 14   start with rn = 1
 15  connect by prior deptno = deptno
 16      and prior rn+1 = rn
 17    group by deptno
 18    order by deptno
 19  /

DEPTNO ENAMES
———- ——————–
        10 CLARK; KING; MILLER
        20 ADAMS; FORD; JONES;
           SCOTT; SMITH
 
        30 ALLEN; BLAKE;
           JAMES; MARTIN;
           TURNER; WARD

3. 11gr2里提供了listagg更方便
SQL> select deptno,
  2         listagg( ename, ‘; ‘ )
  3         within group
  4         (order by ename) enames
  5    from emp
  6   group by deptno
  7   order by deptno
  8  /

    DEPTNO ENAMES
———- ——————–
        10 CLARK; KING; MILLER
        20 ADAMS; FORD; JONES;
           SCOTT; SMITH

        30 ALLEN; BLAKE;
           JAMES; MARTIN;
           TURNER; WARD

January 5, 2009

关注M8

Filed under: Uncategorized — Corey @ 18:23
Tags:
列举缺点如下,看正式上市时能改进多少
1. 软件兼容性差,可用软件少,这个估计要长时间才能改善
2. 不支持手写输入,也没键盘
3. WIFI,蓝牙支持还是屏蔽
4. 能否拍摄DV是个疑问
5. 不支持GPS
6. 不支持3G
7. 价格太高

November 27, 2008

你吃过吗

Filed under: Uncategorized — Corey @ 08:35
Tags:
加州鲈鱼,新奥尔良烤翅,阿拉斯加鳕鱼,夏威夷木瓜,德州扒鸡

November 26, 2008

爆了

Filed under: Uncategorized — Corey @ 19:24
Tags:

Terror attacks in Mumbai; 80 dead, over 250 injured

MUMBAI: Terror struck the country’s financial capital late on Wednesday night
as coordinate serial explosions and indiscriminate firing rocked eight areas
across Mumbai including the crowded CST railway station, two five star hotels–Oberoi and Taj.
At
least 80 people were dead and 250 injured in the terror attacks, hospital
sources said.

October 21, 2008

记孟买的一个夜晚

Filed under: Uncategorized — Corey @ 17:29
Tags:
今天孟买出大事了,颇有影响的某政党的一位首脑被捕,将被带到孟买接受审判。
党羽在多处砸车烧铺闹事,搞到人人自危。平时的孟买路上车暴多,
今晚明显少了,回家一路畅通无阻。
外面乱叫的乌鸦,昏暗的夜晚,幽闷的空气中弥漫着一股躁动的味道。。。

October 6, 2008

在VIM中搜索文件夹

Filed under: Uncategorized — Corey @ 20:19
Tags:
现在主流的编辑器都有搜索文件夹的功能,VIM同样也能实现。

vimgrep是VIM寻找模式匹配的内部方法,可以自动识别换行符和编码,并且
可以使用VIM强大的正则表达式。缺点是相对慢些,因为所有文件都要读
入内存。

语法
:vim[grep][!] /{pattern}/[g][j] {file} …
            Search for {pattern} in the files {file} … and set
            the error list to the matches.
            Without the ‘g’ flag each line is added only once.
            With ‘g’ every match is added.

            {pattern} is a Vim search pattern.  Instead of
            enclosing it in / any non-ID character (see
            |’isident’|) can be used, so long as it does not
            appear in {pattern}.
            ‘ignorecase’ applies.  To overrule it put |/c| in the
            pattern to ignore case or |/C| to match case.
            ‘smartcase’ is not used.

            When a number is put before the command this is used
            as the maximum number of matches to find.  Use
            ":1vimgrep pattern file" to find only the first.
            Useful if you only want to check if there is a match
            and quit quickly when it’s found.

            Without the ‘j’ flag Vim jumps to the first match.
            With ‘j’ only the quickfix list is updated.
            With the [!] any changes in the current buffer are
            abandoned.

来个简单的例子
在 d:mydocs下查找含有“弹冠相庆”的txt文档,但不跳到第一个匹配
:vimgrep /弹冠相庆/gj d:/mydocs/*/*.txt
如果要包含子文件夹,则用

:vimgrep /弹冠相庆/gj d:/mydocs/**/*.txt
打开quickfix窗口查看匹配结果
:cw

参考资料:

http://vimcdoc.sourceforge.net/doc/quickfix.html

:h vimgrep

October 5, 2008

Oracle Virtual Private Database

Filed under: Uncategorized — Corey @ 17:51
Tags:
Oracle VPD(虚拟专有数据库)是从Oracle 8i (8.1.5)引入的一个新特性,为数据库提供了行级别
的安全性 (Row Level Security)或者说细粒度存取控制 (Fine Grained Access Control).
VPD的主要思想就是将访问限定到表中特定的行,这样每个用户将看到完全不同的数据集,
只能对这些被授权的数据进行增删查改。
Oracle 10g中VPD又有进一步完善,使得select操作可以基于列级别的控制(Column-Level Privacy).

关键词: VPD, FGAC,  Row Level Security, Column-Level Privacy, dbms_rls, add_policy

下面是个简单例子 (翻译自http://www.adp-gmbh.ch/ora/security/vpd/index.html)。

在这个例子里,假设一个公司由不同的部门组成(每个部门有一条记录在department表)。一个员
工只能属于一个部门,一个部门可以有一些机密信息记录在department_secrets表。

create table department (
  dep_id int primary key,
  name    varchar2(30)
);

create table employee (
  dep_id references department,
  name    varchar2(30)
);

create table department_secrets (
  dep_id references department,
  secret varchar2(30)
);

插入一些机密信息:

insert into department values (1, ‘Research and Development’);
insert into department values (2, ‘Sales’                   );
insert into department values (3, ‘Human Resources’         );

insert into employee values (2, ‘Peter’);
insert into employee values (3, ‘Julia’);
insert into employee values (3, ‘Sandy’);
insert into employee values (1, ‘Frank’);
insert into employee values (2, ‘Eric’ );
insert into employee values (1, ‘Joel’ );

insert into department_secrets values (1, ‘R+D Secret #1’  );
insert into department_secrets values (1, ‘R+D Secret #2’  );
insert into department_secrets values (2, ‘Sales Secret #1’);
insert into department_secrets values (2, ‘Sales Secret #2’);
insert into department_secrets values (3, ‘HR Secret #1’   );
insert into department_secrets values (3, ‘HR Secret #2’   );

对于任何一个员工,只能看到本部门的机密信息,而不能看见别的部门的机密信息。
为了在Oracle中实现这个功能,我们需要创建一个包,一个触发器以及设置一个策略。
首先创建一个包。

create or replace package pck_vpd

as
  p_dep_id department.dep_id%type;

  procedure set_dep_id(v_dep_id department.dep_id%type);

  function predicate (obj_schema varchar2, obj_name varchar2) return varchar2;
end pck_vpd;
/

create or replace package body pck_vpd as
 
  procedure set_dep_id(v_dep_id department.dep_id%type) is
  begin
    p_dep_id := v_dep_id;
  end set_dep_id;

  function predicate (obj_schema varchar2, obj_name varchar2) return varchar2 is
  begin
    return ‘dep_id = ‘ || p_dep_id;
  end predicate;
 
end pck_vpd;
/

然后定义一个触发器,当用户登陆数据库时,这个触发器将被触发。它找到用户的部门id(dep_id)
并调用包里的set_dep_id存储过程。

create or replace trigger trg_vpd
  after logon on database
declare
  v_dep_id department.dep_id%type;
begin
  select dep_id into v_dep_id
  from employee where upper(name) = user;

  pck_vpd.set_dep_id(v_dep_id);
end;
/

最后,定义一条策略。这条策略表明了如果用户执行一条select语句(注:实际上不止是select,
取决于policy的定义,本例中是select, update, delete),哪个存储过程返回的结果会被用来添加
到where子句中 (注:本例中是’dep_id = ‘ || p_dep_id, 其中p_dept_id会用实际值代替)。

begin
dbms_rls.add_policy  (
  user,
  ‘department_secrets’,
  ‘choosable policy name’,
  user,
  ‘pck_vpd.predicate’,
  ‘select,update,delete’);
end;
/

为了测试上述设置,创建一些用户。

create user frank identified by frank default tablespace users temporary tablespace temp;
create user peter identified by peter default tablespace users temporary tablespace temp;
create user julia identified by julia default tablespace users temporary tablespace temp;

授予必要的权限。

grant all on department_secrets to frank;
grant all on department_secrets to peter;
grant all on department_secrets to julia;

grant create session to frank;
grant create session to peter;
grant create session to julia;

创建一个共有的别名。

create public synonym department_secrets for department_secrets;

Frank (属于R+D部门) 执行一条查询….

connect frank/frank;

select * from department_secrets;

    DEP_ID SECRET
———- ——————————
         1 R+D Secret #1
         1 R+D Secret #2

Peter (属于Sales部门) 执行一条查询….

connect peter/peter;

select * from department_secrets;

    DEP_ID SECRET
———- ——————————
         2 Sales Secret #1
         2 Sales Secret #2

delete, update的情况与select类似.

补充:如果要实现select时对Column-Level的控制,比如说,当查询中包含secret这个字段时所添加的
策略才生效,可以把上面的
begin
dbms_rls.add_policy  (
  user,
  ‘department_secrets’,
  ‘choosable policy name’,
  user,
  ‘pck_vpd.predicate’,
  ‘select,update,delete’);
end;
/
改为
begin
dbms_rls.add_policy  (
  user,
  ‘department_secrets’,
  ‘choosable policy name’,
  user,
  ‘pck_vpd.predicate’,
  ‘select,update,delete’),
  sec_relevant_cols=>’secret’;
end;
/

October 4, 2008

My _vimrc

Filed under: Uncategorized — Corey @ 19:51
Tags:
" Use Vim settings, rather then Vi settings (much better!).
" This must be first, because it changes other options as a side effect.
set nocompatible

" sytle
colo torte

" set encoding
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1

" file format
set fileformats=dos,unix,mac

" allow backspacing over everything in insert mode
set backspace=indent,eol,start

" keep a backup file
set backup

" keep 100 lines of command line history
set history=100

" show the cursor position all the time
set ruler

" display incomplete commands
set showcmd       

" do incremental searching
set incsearch       

" In many terminal emulators the mouse works just fine, thus enable it.
if has(‘mouse’)
  set mouse=a
endif

" Switch syntax highlighting on, when the terminal has colors
" Also switch on highlighting the last used search pattern.
if &t_Co > 2 || has("gui_running")
  syntax on
  set hlsearch
endif

" backspace in Visual mode deletes selection
vnoremap <BS> d

" CTRL-X and SHIFT-Del are Cut
"vnoremap <C-X> "+x
vnoremap <S-Del> "+x

" CTRL-C and CTRL-Insert are Copy
"vnoremap <C-C> "+y
vnoremap <C-Insert> "+y

" CTRL-V and SHIFT-Insert are Paste
"map <C-V>        "+gP
map <S-Insert>        "+gP

" set guioptions
"set guioptions-=a

" CTRL-TAB is Next tab
noremap <C-Tab> gt
vnoremap <C-Tab> <esc>gt
inoremap <C-Tab> <esc>gt

" Shift_TAB is Previous tab
noremap <S-Tab> gT
vnoremap <S-Tab> <esc>gT
inoremap <S-Tab> <esc>gT

" Use CTRL-S for saving, also in Insert mode
noremap <C-S> :update<CR>
vnoremap <C-S> <C-C>:update<CR>
inoremap <C-S> <C-O>:update<CR>

" Don’t use ALT keys for menus.
set winaltkeys=no

" tab mapping
map <M-1> 1gt
map <M-2> 2gt
map <M-3> 3gt
map <M-4> 4gt
map <M-5> 5gt
map <M-6> 6gt
map <M-7> 7gt
map <M-8> 8gt
map <M-9> 9gt
map <M-t> :tabnew<CR>
map <M-w> :bd<CR>
map! <M-1> <esc>1gt
map! <M-2> <esc>2gt
map! <M-3> <esc>3gt
map! <M-4> <esc>4gt
map! <M-5> <esc>5gt
map! <M-6> <esc>6gt
map! <M-7> <esc>7gt
map! <M-8> <esc>8gt
map! <M-9> <esc>9gt
map! <M-t> <esc>:tabnew<CR>
map! <M-w> <esc>:bd<CR>

" display the line number
set number

" smartcase for searching
set ignorecase smartcase

" tab size
set tabstop=2

" 2 space when auto-indent
set shiftwidth=2

" replace tab with space
set expandtab

" linebreak
set linebreak

" linebreak module for asian language
set fo+=mB

" cursor keys wrap to previous/next line
set whichwrap=h,l,~,b,s,<,>,[,]

" auto indent
set autoindent

" When a bracket is inserted, briefly jump to the matching one
set showmatch

" set up statusline
set laststatus=2
set statusline=%<%f %h%m%r%=%k[%{(&fenc=="")?&enc:&fenc}%{(&bomb?",BOM":"")}] [%{&fileformat}] %-14.(%l,%c%V%) %P

"if (has("gui_running"))
" set nowrap
" set guioptions+=b
" colo torte
"else
" set wrap
" colo ron
"endif

" full screen
"au GUIEnter * simalt ~x

" set editor size
let g:editorLines=30
let g:editorColumns=125

" set editor size
function! SetScreenSize()
  let &lines=g:editorLines
  let &columns=g:editorColumns
endfunction

call SetScreenSize()

" get editor size
function! GetScreenSize()
  let g:editorLines=&lines
  let g:editorColumns=&columns
endfunction

" full screen
let g:fullScreened = 0
function! Fullscreen()
  if g:fullScreened == 0
    call GetScreenSize()
    let g:fullScreened = 1
    simalt ~x
    set go-=m
    set go-=T
    set go-=r
    set go-=b
  else
    let g:fullScreened = 0
    call SetScreenSize()
    set go+=m
    set go+=T
    set go+=r
    set go+=b
  endif
endfunction

map <F11> :call Fullscreen()<CR>

function! SaveSession()
  "set sessionoptions-=curdir
  "set sessionoptions+=sesdir
  mksession! $VIM/session.vim
  wviminfo! $VIM/session.viminfo
endfunction

map <F5> :call SaveSession()<CR>

function! LoadSession()
  source $VIM/session.vim
  rviminfo $VIM/session.viminfo
endfunction

map <F6> :call LoadSession()<CR>

set magic

" don’t highlight search result
map <F2> :noh<CR>

" for bufexplorer
map <F3> be
map! <F3> <esc>be

" share clipborad with windows
set clipboard+=unnamed

"When _vimrc is edited, reload it
autocmd! bufwritepost _vimrc source $VIM/_vimrc

August 31, 2008

Mumbai(2)

Filed under: Uncategorized — Corey @ 12:17
Tags:
孟买的电影业很发达,号称“宝莱坞”(Bollywood),可以在街上看到很多电
影海报。海报的内容都很india,我想没来过印度的人看到海报也能猜出来
是印度电影。根据海报推测,大部分放的是宝来坞的电影,兼有少量好莱坞
电影。不过我们还没去电影院看过,我个人对印度的歌舞剧实在是兴趣不大,
再说吧。
印度的音乐很奇怪,听起来都一个调调,节奏感一般都比较强,不喜欢。
这里的米饭比国内的差多了,即使跟东北米相比。超市只有印度本地的米,
没有泰国米之类的东西,也卖得不便宜,2元-5,6元都有。在饭馆里的白米饭
硬硬的,还有一股苏打水的味道,不过习惯了就好了,聊胜于无。我们一般
点个炒饭,以试图用炒饭的香味把苏打水的味道掩盖甚至清除掉,屡试不爽。
这里的面条还不错,有点中国炒面的意思,赞一个。中餐馆在这边算是比较
贵的餐馆,一般人均下来折合人民币30-60/70不等。
房价很贵,比深圳还贵,在南部(算是富人区),一套三室一厅大概要4千万卢
比。
据我观察,孟买喝酒吸烟的人都不多,可能跟宗教信仰有关。上次在超市连
火机都买不到,只好搞了盒火柴回去,有一段时间没用过火柴了,触景伤情
啊。
在这边,如果地位不是很低的话,大都会讲英语。印度英语是出了名的难听,
再加上本人本来就蹩脚的英语,听起来可谓痛苦,目前还处在一个交流的瓶
颈,等哪天能自由地跟同事聊天之时,就是突破瓶颈之日,还须努力。
我在公司用的机器是lenovo的,内存只有1GB,慢就一个字,还要同时运行多
个应用。公司对电脑的限制极其严格,大多数网站上不了,装个软件还要申
请,U盘不能用。。。不爽,极其不爽。窃以为硬软件两条退同时走路的话,
工作效率会更高更快更强,或许印度软件业会进入一个快速的发展的时期:-),
iflex被整合后不知会不会做到这一点。
周六去印度门和象岛石窟逛了一圈。印度门(Gateway of India)是当年殖民
主义者征服印度的象征,是为纪念英国乔治五世国王1911在此登陆而建。其
实就是一座高大的门,我们去到时,正在对门做一些修修补补的工作,怀着
ms虔诚的心情拍了一些照片之后,马上坐船去象岛。在船上再看海边的景色,
才发现"孟买是印度的上海"这句话也不是那么不靠谱,现代化的港口,海水
共长天一色,让我暂时忘却了孟买的臭臭的街道。
再说象岛,这个名字的来历是“16世纪葡萄牙人在岛上登陆地点附近发现一尊
独石圆雕的大象,因此就用葡语大象为该岛命名。”。在石窟入口我们受到了
不公平的待遇,本国人只要10卢比,而外国人要250。岛上石窟里的雕像都是
关于湿婆的,印度一个巨nb的神。由于个人修养有限,所以那些"被公认为印
度雕刻乃至世界雕刻的不朽杰作",对我来说没有太大的震憾(甚至觉得刘翔
奥运退赛的震憾还大点,原谅我吧),照例走过,拍照,走人。更ft的事是印
度人似乎很崇拜湿婆(男)的生殖器所以每个石窟里都有一根或更多圆柱竖在那。

好,下次要去泰姬陵玩玩。

August 24, 2008

Mumbai(1)

Filed under: Uncategorized — Corey @ 08:42
Tags:
Mumbai的前称叫Bombay,很多地方都可以看到写着Bombay的招牌。

所见的人都是黑人居多,印度人分四个等级(不知道现在还是不是这样),
一般来说,肤色越黑的越低级。
男的基本都是穿T shirt,衬衫,女的很多是用一匹长长的色彩鲜艳
的布把自己裹起来,腰间还要露出一坨赘肉。由于宗教的原因,还有
一些教徒用黑衣把自己整个包起来只露出眼睛,或者穿一袭白衣。
吃的东西,大部分都配有咖喱以及辣酱,中餐馆也有不少菜是这样。
肉最常见是鸡肉,羊肉也不少,猪肉牛肉基本看不到。麦当劳只有
chicken burger和fish burger,不过chicken burger里面也有咖哩。。。
还好公司旁边联系了一个中餐馆,现在已经成为我们的食堂了,厨师
的父母据说是中国人,经常搞点炒饭炒面炒青菜的改善一下伙食,
下周据说要搞个蒸整鸡,期待。在这边吃个类似于中国的纯炒青菜
有点难的,一来这里的青菜种类,二来青菜的质量也不怎么好,三来
这边的人似乎不怎么喜欢吃青菜。
关于猪肉,昨天刚在一个叫inorbit ball里的一家Ruby
Tuesday吃了猪排,吃伤了,导致最近都不会想念猪肉了。顺便说一
下这个mall,果然有点大,差不多有海岸城大小了,比我们之前看
到的都要大,号称是全孟买最大的。进去照例要做安检,可能上次
的连环爆炸的影响还没有过去。
总的来说,Mcdonals,KFC, Pizza Hut都远远没有国内的好吃,种类也
少。孟买近海,但在这里吃过的海鲜大都不怎么新鲜,有一股味道,
搞到现在都不敢吃了。
一般的印度普通老百姓都不怎么关心奥运会,不过还是经常被人问到
北京奥运会,说是最好的一届。。。
住宿条件,很一般,比国内的如家还要差点。service apartment,郊区,
因为市区太贵,面积倒挺大,有点脏,有点味道,家具家电有点旧。
刚来的时候,天天下雨,比较痛苦,近来倒是晴天居多,不下雨的孟
买可爱多了。
这里的交通非常混乱。街上的车非常多,以紧凑的车型为主。看来印度的
十几亿人口不是浪得虚名啊。有taxi,但看上去有点
破旧。最多的是一种三轮摩托车,叫auto,满大街都是,我们也经常坐。
auto的优点是方便,通风。缺点是太通风了,导致我们直接把各种
汽车的尾气以及街上各种难闻的气味都吸了个遍。大多数情况下,汽车
可以随便换道,超越,转弯以及调头。坐在auto上简直是在追求一
种惊心动魄的出行体验,因为前后左右的大车似乎随时会撞上来,把你压扁。

想念佳泰的虾蟹粥。

Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: