2008-08-25 Mon

02:39 直方图视图user_tab_histograms中的endpoint_value (4639 Bytes) » ORATEA

对于那些上严重倾斜性的列来说,直方图是CBO正确选择执行计划的重要基础。
我们一般查询直方图都是查询user_tab_histograms,all_tab_histograms或者dba_tab_histograms。
以user_tab_histograms来说明下视图各个字段的含义

SQL> desc user_tab_histograms
名称                                      是否为空? 类型
—————————————– ——– ————–

TABLE_NAME                                         VARCHAR2(30)      
COLUMN_NAME                                        VARCHAR2(4000)
ENDPOINT_NUMBER                                    NUMBER
ENDPOINT_VALUE                                     NUMBER
ENDPOINT_ACTUAL_VALUE                              VARCHAR2(1000)

TABLE_NAME  ————— 表名          
COLUMN_NAME ————— 字段名
ENDPOINT_NUMBER ———– 结束点序号
ENDPOINT_VALUE  ———– 结束点值
ENDPOINT_ACTUAL_VALUE—— 结束点真实值(一般为空)

以前使用直方图的时候没有过多的关注ENDPOINT_VALUE字段,一直以后这个字段存储的结束点的实际值。
可今天发现不是这样的。

SQL> create table sunwg (id number,grade varchar2(1));

表已创建。

SQL> insert into sunwg values(1,’a');

已创建 1 行。

SQL> insert into sunwg values(2,’b');

已创建 1 行。

SQL> commit;

提交完成。

SQL> begin
  2  dbms_stats.gather_table_stats(
  3  ownname => ‘SUNWG’,
  4  tabname => ‘SUNWG’,
  5  method_opt => ‘FOR TABLE FOR ALL COLUMNS SIZE AUTO’);
  6  end;
  7  /

PL/SQL 过程已成功完成。
SQL> select column_name,endpoint_number,endpoint_value
  2  from user_tab_histograms
  3  where table_name = ‘SUNWG’
  4  order by 1,2;

COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE
———- ————— ————–
GRADE                    0     5.0365E+35
GRADE                    1     5.0885E+35
ID                       0              1
ID                       1              2

从这个测试结果能看出来,对于列ID存储的是实际值,而对于列GRADE则不是。
后来查询了user_tab_histograms的底层表才知道ENDPOINT_VALUE存储的原来是实际值的hash值。

create table histgrm$                                     /* histogram table */
( obj#            number not null,                          /* object number */
  col#            number not null,                          /* column number */
  row#            number,                       /* row number (in row cache) */
  bucket          number not null,                          /* bucket number */
  endpoint        number not null,                  /* endpoint hashed value */
  intcol#         number not null,                 /* internal column number */
  epvalue         varchar2(1000),              /* endpoint value information */
  spare1          number,
  spare2          number)
cluster c_obj#_intcol#(obj#, intcol#)
/

endpoint        number not null,                  /* endpoint hashed value */
这样就清楚了,5.0365E+35是’a'的hash值。
oracle这样可能是为了增强通用性吧,否则需要建一系列的endpoint,字符型的endpoint,数据型的endpoint,日期型的endpoint等。
而使用了hash之后,结果就唯一,一串数字而已。
><

02:21 ORA-01039 (6026 Bytes) » ORATEA

今天同事在查看sql的执行计划的时候出现ORA-01039的错误。原因主要是在视图所在的基表上没有select的权限。

oerr ora 1039
01039, 00000, “insufficient privileges on underlying objects of the view”
 *Cause: Attempting to explain plan on other people’s view without
         the necessary privileges on the underlying objects of the view.
 *Action: Get necessary privileges or do not perform the offending operation.
 
这个时候只要把基表的权限付给相应的用户就可以了。

GRANT SELECT ON xxx TO xxx;

下面模拟下出错的过程和解决的办法:

一 sunwg用户下:

sunwg> desc sunwg
 名称                                      是否为空? 类型
 —————————————– ——– ————————

 OWNER                                              VARCHAR2(30)
 OBJECT_NAME                                        VARCHAR2(128)
 SUBOBJECT_NAME                                     VARCHAR2(30)
 OBJECT_ID                                          NUMBER
 DATA_OBJECT_ID                                     NUMBER
 OBJECT_TYPE                                        VARCHAR2(19)
 CREATED                                            DATE
 LAST_DDL_TIME                                      DATE
 TIMESTAMP                                          VARCHAR2(19)
 STATUS                                             VARCHAR2(7)
 TEMPORARY                                          VARCHAR2(1)
 GENERATED                                          VARCHAR2(1)
 SECONDARY                                          VARCHAR2(1)

sunwg> create view sunwg_v as select * from sunwg;

视图已创建。

sunwg> grant select on sunwg_v to test;

授权成功。
二 test用户下:

test> desc sunwg.sunwg
ERROR:
ORA-04043: 对象 sunwg.sunwg 不存在
test> desc sunwg.sunwg_v
 名称                                      是否为空? 类型
 —————————————– ——– ——————-

 OWNER                                              VARCHAR2(30)
 OBJECT_NAME                                        VARCHAR2(128)
 SUBOBJECT_NAME                                     VARCHAR2(30)
 OBJECT_ID                                          NUMBER
 DATA_OBJECT_ID                                     NUMBER
 OBJECT_TYPE                                        VARCHAR2(19)
 CREATED                                            DATE
 LAST_DDL_TIME                                      DATE
 TIMESTAMP                                          VARCHAR2(19)
 STATUS                                             VARCHAR2(7)
 TEMPORARY                                          VARCHAR2(1)
 GENERATED                                          VARCHAR2(1)
 SECONDARY                                          VARCHAR2(1)

test> set autot traceonly exp
test> select * from sunwg.sunwg_v;

执行计划
———————————————————-
ERROR:
ORA-01039: 视图基本对象的权限不足
SP2-0612: 生成 AUTOTRACE EXPLAIN 报告时出错

三 在sunwg下授权给test

sunwg> grant select on sunwg to test;

授权成功。

四 重新在test下查看sql的执行计划

test> select * from sunwg.sunwg_v;

执行计划
———————————————————-
Plan hash value: 856969577

—————————————————————-
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)|
—————————————————————-
|   0 | SELECT STATEMENT  |       | 10000 |   820K|    33   (4)|
|   1 |  TABLE ACCESS FULL| SUNWG | 10000 |   820K|    33   (4)|
—————————————————————-

问题解决了。
><

01:00 对话 UNIX: 简单的按键操作 (354 Bytes) » developerWorks 中国 : 技术文章 , 教程 AIX
用户与计算机交互的方式在不断发生变化。启动后提供纯命令行界面的操作系统已逐渐演化为图形化前端。然而,脱离构成操作系统的构建块有时并非是迈向正确方向的必要步骤。幸运的是,IBM AIX 操作系统一直把握着重点:计算机操作系统的稳定性、功能和稳健性。
00:45 11g新特性——基于函数的统计信息 (12155 Bytes) » ORATEA

11g在统计信息上的进步还是比较大的,增加了一种新的统计信息——基于函数的统计信息。
通过基于函数的统计信息就可以完美的解决了10g中的在列上存在函数时候的结果集估算上的问题。
想知道基于函数的统计信息有多大的用途,那么先让我们来看看10g中的cbo在处理存在函数的列时候有多笨蛋。

10g

SQL> drop table sunwg ;

表已删除。

SQL> create table sunwg as select * from dba_objects where rownum<10001;

表已创建。

SQL> begin
  2          dbms_stats.gather_table_stats (
  3                  ownname         => ‘SUNWG’,
  4                  tabname         => ‘SUNWG’,
  5                  estimate_percent=> 100,
  6                  method_opt      => ‘FOR TABLE FOR ALL COLUMNS SIZE AUTO’,
  7                  cascade         => true
  8  );
  9  end;
 10  /

PL/SQL 过程已成功完成。

SQL> set autot traceonly exp
SQL> select * from sunwg where substr(object_name,1,1) = ‘S’;

执行计划
———————————————————-
Plan hash value: 856969577

—————————————————————-
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)|
—————————————————————-
|   0 | SELECT STATEMENT  |       |   100 |  8400 |    33   (4)|
|*  1 |  TABLE ACCESS FULL| SUNWG |   100 |  8400 |    33   (4)|
—————————————————————-

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

   1 - filter(SUBSTR(”OBJECT_NAME”,1,1)=’S')

CBO估计最后的结果集100,那么看下实际上结果集应该是多少。

SQL> set autot OFF

SQL> select count(*) from sunwg where substr(object_name,1,1) = ‘S’;

        761

100和761比起来,差距还是很大的。
实际上这个时候CBO计算结果集的方式就是 row_num * 1% = 10000 * 1% = 100
上面的1%是在等值查询的时候,如果是不等查询,比如说是substr(object_name,1,1) > ‘S’,则公式变为row_num * 5%。

SQL> set autot traceonly exp
SQL> select * from sunwg where substr(object_name,1,1) > ‘S’;

执行计划
———————————————————-
Plan hash value: 856969577

—————————————————————-
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)|
—————————————————————-
|   0 | SELECT STATEMENT  |       |   500 | 42000 |    33   (4)|
|*  1 |  TABLE ACCESS FULL| SUNWG |   500 | 42000 |    33   (4)|
—————————————————————-

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

   1 - filter(SUBSTR(”OBJECT_NAME”,1,1)>’S')
  
那么实际呢?

SQL> set autot off
SQL> select count(*) from sunwg where substr(object_name,1,1) > ’s’;

         2337
        
由此可以看出,在10g中如果列上存在函数,CBO的估算存在着严重的问题。这些问题进而导致CBO选择不恰当的执行计划。
最终的结果就是,用户抱怨程序执行缓慢。

下面我们看看11g中有什么新的变化。

11g

sunwg>create table sunwg as select * from dba_objects where rownum<10001;

Table created.

sunwg>begin
  2    dbms_stats.gather_table_stats (
  3             ownname         => ‘SUNWG’,
  4             tabname         => ‘SUNWG’,
  5             estimate_percent=> 100,
  6             method_opt      => ‘FOR TABLE FOR ALL COLUMNS FOR COLUMNS (SUBSTR(OBJECT_NAME,1,1))’);
  7   end;
  8  /

PL/SQL procedure successfully completed.

上面对表收集统计信息的时候和在10g的时候有所不同,增加对了函数的统计信息的收集——FOR COLUMNS (SUBSTR(OBJECT_NAME,1,1))。
先来看下收集了基于函数的统计信息后的效果。

sunwg>set autot traceonly exp

sunwg>select * from sunwg where substr(object_name,1,1) = ‘S’;

Execution Plan
———————————————————-
Plan hash value: 856969577

—————————————————————-
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)|
—————————————————————-
|   0 | SELECT STATEMENT  |       |   737 | 67804 |    19   (0)|
|*  1 |  TABLE ACCESS FULL| SUNWG |   737 | 67804 |    19   (0)|
—————————————————————-

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

   1 - filter(”SUNWG”.”SYS_STU5NQYW0T0Y__CUOUS30XU1JP”=’S')

看看实际的结果集大小:

sunwg@SWORD>set autot OFF

sunwg@SWORD>select count(*) from sunwg where substr(object_name,1,1) = ‘S’;

  COUNT(*)
———-
       737
      
看来CBO这次估算的结果还是很正确的。     

细心的可能注意到一个问题,在上面的执行计划的筛选中出现了”SUNWG”.”SYS_STU5NQYW0T0Y__CUOUS30XU1JP”=’S'。
那么这个”SUNWG”.”SYS_STU5NQYW0T0Y__CUOUS30XU1JP”是什么对象呢,凭感觉应该是和substr(object_name,1,1)有关系的。

在11g中增加了一个新的视图USER_STAT_EXTENSIONS,用来存储那些扩展的统计信息。

sunwg@SWORD>select TABLE_NAME,EXTENSION_NAME,EXTENSION from user_stat_extensions;

TABLE_NAME                     EXTENSION_NAME                 EXTENSION
—————————— —————————— ——————————–
SUNWG                          SYS_STU5NQYW0T0Y__CUOUS30XU1JP (SUBSTR(”OBJECT_NAME”,1,1))

那么这个扩展的统计信息存储在哪里了,我们找找看吧。

sunwg@SWORD>select table_name,column_name,NUM_DISTINCT,DENSITY from user_tab_cols where table_name = ‘SUNWG’ order by 1;

TABLE_NAME                     COLUMN_NAME                    NUM_DISTINCT    DENSITY
—————————— —————————— ———— ———-
SUNWG                          SYS_STU5NQYW0T0Y__CUOUS30XU1JP           25     .00005
SUNWG                          EDITION_NAME                              1  .00018315
SUNWG                          NAMESPACE                                 7     .00005
SUNWG                          SECONDARY                                 1     .00005
SUNWG                          GENERATED                                 2     .00005
SUNWG                          TEMPORARY                                 2     .00005
SUNWG                          STATUS                                    1     .00005
SUNWG                          TIMESTAMP                               334  .00438216
SUNWG                          LAST_DDL_TIME                           361  .00423152
SUNWG                          CREATED                                 320  .00440554
SUNWG                          OBJECT_TYPE                              20     .00005
SUNWG                          DATA_OBJECT_ID                         1931 .000963212
SUNWG                          OBJECT_ID                             10000      .0001
SUNWG                          SUBOBJECT_NAME                           28 .004310345
SUNWG                          OBJECT_NAME                            8067  .00013912
SUNWG                          OWNER                                     6     .00005

一下子就找到了,这个基于函数的统计信息是和表中的列存储在一起的。
从上面的统计信息可以看出来,SUBSTR(”OBJECT_NAME”,1,1)有25个不同值,并且DENSITY值等于.00005。
CBO正是通过这个统计信息来计算出substr(object_name,1,1) = ‘S’的结果集合是737。
至于具体怎么计算得到的,我这就不写了。这涉及到直方图的一些知识了,有兴趣的可以参考我写的:
cbo心得(选择率,基数,直方图) - http://www.oratea.cn/2008/03/25/39.html
><

  2008-08-24 Sun

19:05 开源数据库 Sharding 技术 (9738 Bytes) » DBA notes

注:此文首发于 《程序员》杂志 2008 年 7 月刊。

从 Shard 到 Sharding

"Shard" 这个词英文的意思是"碎片",而作为数据库相关的技术用语,似乎最早见于大型多人在线角色扮演游戏(MMORPG)中。"Sharding" 姑且称之为"分片"。

Sharding 不是一门新技术,而是一个相对简朴的软件理念。如您所知,MySQL 5 之后才有了数据表分区功能,那么在此之前,很多 MySQL 的潜在用户都对 MySQL 的扩展性有所顾虑,而是否具备分区功能就成了衡量一个数据库可扩展性与否的一个关键指标(当然不是唯一指标)。数据库扩展性是一个永恒的话题,MySQL 的推广者经常会被问到:如在单一数据库上处理应用数据捉襟见肘而需要进行分区化之类的处理,是如何办到的呢? 答案是:Sharding。

Sharding 不是一个某个特定数据库软件附属的功能,而是在具体技术细节之上的抽象处理,是水平扩展(Scale Out,亦或横向扩展、向外扩展)的解决方案,其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。

事关数据库扩展性

说起数据库扩展性,这是个非常大的话题。目前的商业数据都有自己的扩展性解决方案,在过去相对来说比较成熟,但是随着互联网的高速发展,不可避免的会带来一些计算模式上的演变,这样很多主流商业系统也难免暴露出一些不足之处。比如 Oracle 的 RAC 是采用共享存储机制,对于 I/O 密集型的应用,瓶颈很容易落在存储上,这样的机制决定后续扩容只能是 Scale Up(向上扩展) 类型,对于硬件成本、开发人员的要求、维护成本都相对比较高。

Sharding 基本上是针对开源数据库的扩展性解决方案,很少有听说商业数据库进行 Sharding 的。目前业界的趋势基本上是拥抱 Scale Out,逐渐从 Scale Up 中解放出来。

Sharding 的应用场景

任何技术都是在合适的场合下能发挥应有的作用。 Sharding 也一样。联机游戏、IM、BSP 都是比较适合 Sharding 的应用场景。其共性是抽象出来的数据对象之间的关联数据很小。比如IM ,每个用户如果抽象成一个数据对象,完全可以独立存储在任何一个地方,数据对象是 Share Nothing 的;再比如 Blog 服务提供商的站点内容,基本为用户生成内容(UGC),完全可以把不同的用户隔离到不同的存储集合,而对用户来说是透明的。

这个 "Share Nothing" 是从数据库集群中借用的概念,举例来说,有些类型的数据粒度之间就不是 "Share Nothing" 的,比如类似交易记录的历史表信息,如果一条记录中既包含卖家信息与买家信息,如果随着时间推移,买、卖家会分别与其它用户继续进行交易,这样不可避免的两个买卖家的信息会分布到不同的 Sharding DB 上,而这时如果针对买卖家查询,就会跨越更多的 Sharding ,开销就会比较大。

Sharding 并不是数据库扩展方案的银弹,也有其不适合的场景,比如处理事务型的应用就会非常复杂。对于跨不同DB的事务,很难保证完整性,得不偿失。所以,采用什么样的 Sharding 形式,不是生搬硬套的。

Sharding与数据库分区(Partition)的区别

有的时候,Sharding 也被近似等同于水平分区(Horizontal Partitioning),网上很多地方也用 水平分区来指代 Sharding,但我个人认为二者之间实际上还是有区别的。的确,Sharding 的思想是从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而 Sharding 是能够跨数据库,甚至跨越物理机器的。(见对比表格)

Sharding.png
(转载别忘了此图。注明全文来自 http://www.dbanotes.net)

Sharding 策略

数据 Sharding 的策略与分区表的方式有很多类似的地方,有基于表、ID 范围、数据产生的时间或是SOA 下理念下的基于服务等众多方式可选择。而与传统的表分区方式不同的是,Sharding 策略和业务结合的更为紧密,成功的 Sharding 必须对自己的业务足够熟悉,进行众多可行性分析的基础上进行,"业务逻辑驱动"。

Sharding 实现案例分析:Digg 网站

作为风头正劲的 Web 2.0 网站之一的 Digg.com,虽然用户群庞大,但网站数据库数据并非海量,去年同期主数据大约只有 30GB 的样子,现在应该更大一些,但应该不会出现数量级上增长,数据库软件采用 MySQL 5.x。Digg.com的 IO 压力非常大,而且是读集中的应用(98%的 IO 是读请求)。因为提供的是新闻类服务,这类数据有其自身特点,最近时间段的数据往往是读压力最大的部分。

根据业务特点,Digg.com 根据时间范围对主要的业务数据做 Sharding,把不到 10% 的"热"数据有效隔离开来,同时对这部分数据用以更好的硬件,提供更好的用户体验。而另外 90% 的数据因用户很少访问,所以尽管访问速度稍慢一点,对用户来说,影响也很小。通过 Sharding,Digg 达到了预期效果。

现有的 Sharding 软件简介

现在 Sharding 相关的软件实现其实不少,基于数据库层、DAO 层、不同语言下也都不乏案例。限于篇幅,作一下简要的介绍。

MySQL Proxy + HSCALE

一套比较有潜力的方案。其中 MySQL Proxy (http://forge.mysql.com/wiki/MySQL_Proxy) 是用 Lua 脚本实现的,介于客户端与服务器端之间,扮演 Proxy 的角色,提供查询分析、失败接管、查询过滤、调整等功能。目前的 0.6 版本还做不到读、写分离。HSCALE 则是针对 MySQL Proxy 插件,也是用 Lua 实现的,对 Sharding 过程简化了许多。需要指出的是,MySQL Proxy 与 HSCALE 各自会带来一定的开销,但这个开销与集中式数据处理方式单条查询的开销还是要小的。

Hibernate Shards

这是 Google 技术团队贡献的项目(http://www.hibernate.org/414.html),该项目是在对 Google 财务系统数据 Sharding 过程中诞生的。因为是在框架层实现的,所以有其独特的特性:标准的 Hibernate 编程模型,会用 Hibernate 就能搞定,技术成本较低;相对弹性的 Sharding 策略以及支持虚拟 Shard 等。

Spock Proxy

这也是在实际需求中产生的一个开源项目。Spock(http://www.spock.com/)是一个人员查找的 Web 2.0 网站。通过对自己的单一 DB 进行有效 Sharding化 而产生了Spock Proxy(http://spockproxy.sourceforge.net/ ) 项目,Spock Proxy 算得上 MySQL Proxy 的一个分支,提供基于范围的 Sharding 机制。Spock 是基于 Rails 的,所以Spock Proxy 也是基于 Rails 构建,关注 RoR 的朋友不应错过这个项目。

HiveDB

上面介绍了 RoR 的实现,HiveDB (http://www.hivedb.org/)则是基于Java 的实现,另外,稍有不同的是,这个项目背后有商业公司支持。

PL/Proxy

前面几个都是针对 MySQL 的 Sharding 方案,PL/Proxy 则是针对 PostgreSQL 的,设计思想类似 Teradata 的 Hash 机制,数据存储对客户端是透明的,客户请求发送到 PL/Proxy 后,由这里分布式存储过程调用,统一分发。 PL/Proxy 的设计初衷就是在这一层充当"数据总线"的职责,所以,当数据吞吐量支撑不住的时候,只需要增加更多的 PL/Proxy 服务器即可。大名鼎鼎的 Skype 用的就是 PL/Proxy 的解决方案。

Pyshards

http://code.google.com/p/pyshards/wiki/Pyshards 这是个基于 Python的解决方案。该工具的设计目标还有个 Re-balancing 在里面,这倒是个比较激进的想法。目前只支持 MySQL 数据库。

结束语

Sharding 是一项仍处于高速发展中的"老"技术,随着 Web 2.0 的发展,Sahrding逐渐从比较"虚"的概念变成比较"实"的运用思路,开放源代码软件大潮也给 Sharding 注入新的活力,相信会有越来越多的项目采用 Sharding 技术,也会有更多成熟的 Sharding 方案和数据库附加软件涌现。

你的站点 Sharding 了么?

--EOF--

另,本周末我讲参加这个活动:体验基于OpenSolaris的Web/企业应用,做一个题为《设计可扩展的面向互联网应用的MySQL数据库》的简单分享。欢迎杭州朋友光临指导。

  2008-08-23 Sat

21:15 Linux中如何让进程在后台运行 (5695 Bytes) » NinGoo.net

Author:NinGoo posted on NinGoo.net

在Linux中,如果要让进程在后台运行,一般情况下,我们在命令后面加上&即可,实际上,这样是将命令放入到一个作业队列中了:

$ ./test.sh &
[1] 17208

$ jobs -l
[1]+ 17208 Running                 ./test.sh &

对于已经在前台执行的命令,也可以重新放到后台执行,首先按ctrl+z暂停已经运行的进程,然后使用bg命令将停止的作业放到后台运行:

$ ./test.sh
[1]+  Stopped                 ./test.sh

$ bg %1
[1]+ ./test.sh &

$ jobs -l
[1]+ 22794 Running                 ./test.sh &

但是如上方到后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。如果我们要在退出shell的时候继续运行进程,则需要使用nohup忽略hangup信号,或者setsid将将父进程设为init进程(进程号为1)

$ echo $$
21734

$ nohup ./test.sh &
[1] 29016

$ ps -ef | grep test
515      29710 21734  0 11:47 pts/12   00:00:00 /bin/sh ./test.sh
515      29713 21734  0 11:47 pts/12   00:00:00 grep test
$ setsid ./test.sh &
[1] 409

$ ps -ef | grep test
515        410     1  0 11:49 ?        00:00:00 /bin/sh ./test.sh
515        413 21734  0 11:49 pts/12   00:00:00 grep test

上面的试验演示了使用nohup/setsid加上&使进程在后台运行,同时不受当前shell退出的影响。那么对于已经在后台运行的进程,该怎么办呢?可以使用disown命令:

$ ./test.sh &
[1] 2539

$ jobs -l
[1]+  2539 Running                 ./test.sh &

$ disown -h %1

$ ps -ef | grep test
515        410     1  0 11:49 ?        00:00:00 /bin/sh ./test.sh
515       2542 21734  0 11:52 pts/12   00:00:00 grep test

另外还有一种方法,即使将进程在一个subshell中执行,其实这和setsid异曲同工。方法很简单,将命令用括号() 括起来即可:

$ (./test.sh &)

$ ps -ef | grep test
515        410     1  0 11:49 ?        00:00:00 /bin/sh ./test.sh
515      12483 21734  0 11:59 pts/12   00:00:00 grep test

注:本文试验环境为Red Hat Enterprise Linux AS release 4 (Nahant Update 5),shell为/bin/bash,不同的OS和shell可能命令有些不一样。例如AIX的ksh,没有disown,但是可以使用nohup -p PID来获得disown同样的效果。

还有一种更加强大的方式是使用screen,首先创建一个断开模式的虚拟终端,然后用-r选项重新连接这个虚拟终端,在其中执行的任何命令,都能达到nohup的效果,这在有多个命令需要在后台连续执行的时候比较方便:

$ screen -dmS screen_test

$ screen -list
There is a screen on:
        27963.screen_test       (Detached)
1 Socket in /tmp/uscreens/S-jiangfeng.

$ screen -r screen_test

Related Articles

PermLink: http://www.ningoo.net/html/2008/how_to_run_processes_on_background_in_linux.html

Add Comments(0) | Follow NinGoo@Twitter | Google Reader

bookmark


  2008-08-22 Fri

19:19 奋斗 (11437 Bytes) » 玉面飞龙的BLOG
3年前,麦子的一篇《我奋斗了18年才和你坐在一起喝咖啡》引起多少共鸣,一个农家子弟经过18年的奋斗,才取得和大都会里的同龄人平起平坐的权利,一代人的真实写照。然而,3年过去,我恍然发觉,他言之过早。18年又如何?再丰盛的年华叠加,我仍不能和你坐在一起喝咖啡。 那年我25,无数个夙兴夜寐,换来一个硕士学位,额上的抬头纹分外明显,脚下却半步也不敢停歇。如果不想让户口打回原籍,子子孙孙无穷匮,得赶紧地找份留京工作。你呢?你不着急,魔兽世界和红色警报?早玩腻了!你野心勃勃地筹划着“创业创业”。当时李彦宏、陈天桥、周云帆,牛人们还没有横空出世,百度、Google、完美时空更是遥远的名词,可青春所向披靡不可一世,你在校园里建起配送网站,大张旗鼓地招兵买马,大小媒体的记者蜂拥而至。334寝室很快在全楼名噪一时,小姑娘们从天南地北寄来粉粉的信纸,仰慕地写道:“从报上得知你的精彩故事……”得空,爬上楼顶吹吹风,你眉飞色舞地转向我,以照顾自己人的口气说,兄弟,一起发财如何? 好呀,可惜,我不能。创业于你,是可进可退可攻可守的棋,启动资金有三姑六眷帮忙筹集,就算铩羽而归,父母那三室一厅、温暖的灶台也永不落空。失败于我,意味着覆水难收一败涂地,每年夏天,为了节省三五百块钱的机器钱,爹娘要扛着腰肌劳损在大日头下收割5亩农田。我穿着借来的西服完成了第一次面试,戴着借来的手表与心爱的女孩进行了第一次约会。当你拿到了第一笔投资兴奋地报告全班时,我冷静地穿越大半个北京城,去做最后一份家教。没错,“这活儿技术含量忒低”,但在第一个月工资下发前,我租来的立锥之地与口粮全靠它维持。 不多久,互联网就遭遇了寒流,你也对创业意兴阑珊,进了家国有性质的通信公司,我被一家外企聘用。坐井观天的我,竟傻傻地以为扳回了一局。明面上的工资,我比你超出一截,税后8000,出差住5星级宾馆,一年带薪休假10天。玩命一样地投入工作,坚信几年后也有个童话般的结尾,“和公主过上幸福的生活”。 好景不长,很快,我明白了为什么大家说白领是句骂人的话。写字楼的套餐,标价35,几乎没人搭理它。午餐时间,最抢手的是各层拐角处的微波炉,“白领”们端着带来的便当,排起了长长的队伍。后来,物业允许快餐公司入住,又出现了“千人排队等丽华”的盛况。这些月入近万的人士节约到抠门的程度。一位同事,10块钱的感冒药都找保险公司理赔;另一位,在脏乱差的火车站耗上3个小时,为的是18:00后返程能多得150元的晚餐补助。 这幕幕喜剧未能令我发笑,我读得懂,每个数字后都凝结着加班加点与忍气吞声;俯首帖耳被老板盘剥,为的是一平米一平米构筑起自己的小窝。白手起家的过程艰辛而漫长,整整3年,我没休过一次长假没吃过一回鸭脖子;听到“华为25岁员工胡新宇过劳死”的新闻,也半点儿不觉得惊讶,以血汗、青春换银子的现象在这个行业太普遍了。下次,当你在上地看见一群人穿着西装革履拎着IBM笔记本奋力挤上4毛钱的公交车,千万别奇怪,我们就是一群IT民工。 惟一让人欣慰的是,我们离理想中的目标一步步靠近。 突如其来地,你的喜讯从天而降:邀请大家周末去新居暖暖房。怎么可能?你竟比我快?可豁亮的100多平方米、红苹果家具、37寸液晶大彩电无可质疑地摆在眼前。你轻描淡写地说,老头子给了10万,她家里也给了10万,老催着我们结婚……回家的路上,女朋友郁郁不说话,她和我一样,来自无名的山城。我揽过她的肩膀,鼓励她也是鼓励自己,没关系,我们拿时间换空间。 蜜月你在香港过的,轻而易举地花掉了半年的工资,回来说,意思不大,不像TVB电视里拍的那样美轮美奂;我的婚礼,在家乡的土路、乡亲的围观中巡游,在低矮昏暗的老房子里拜了天地,在寒冷的土炕上与爱人相拥入眠。幸运的是,多年后黯淡的图景化作妻子博客里光芒四射的图画,她回味:“有爱的地方,就有天堂。” 我们都想给深爱的女孩以天堂,天堂的含义却迥然不同。你的老婆当上了全职太太,每天用电驴下载《老友记》和《越狱》;我也想这么来着,老婆不同意,你养我,谁养我爸妈?不忍心让你一个人养7个人。当你的女孩敷着倩碧面膜舒服地翘起脚,我的女孩却在人海中顽强地搏杀。 两个人赚钱的速度快得多。到2004年年底,我们也攒到了人生中第一个10万,谁知中国的楼市在此时被魔鬼唤醒,海啸般狂飙突进,摧毁一切渺小虚弱的个体。2005年3月,首付还够买西四环的郦城,到7月,只能去南城扫楼了。我们的积蓄本来能买90平方米的两居来着,9月中旬,仅仅过去2个月,只够买80多平。 没学过经济学原理?没关系。生活生动地阐释了什么叫资产泡沫与流动性泛滥。这时专家跳出来发言了,“北京房价应该降30%,上海房价应该降40%。”要不,再等等?我险些栖身于温吞的空方阵营,是你站出来指点迷津:赶快买,房价还会涨。买房的消息传回老家,爹娘一个劲儿地唏嘘:抵得上俺们忙活半年。在他们看来,7500元一平方米是不可思议的天价。3年后的2008,师弟们纷纷感叹,你赚大发了,四环内均价1万4,已无楼可买。 几天前,我看见了水木上一句留言,颇为感慨:“工作5年还没买房真活该,2003年正是楼市低迷与萧条之时。等到今天,踏空的不仅是黄金楼市,更是整个人生。” 真要感谢你,在我不知理财为何物之时,你早早地告诉我什么叫消费什么叫投资。 并非所有人都拥有前瞻的眼光和投资的观念。许多和我一样来自小地方、只知埋头苦干的兄弟们,太过关注脚下的麦田,以至于错过一片璀璨的星空。你的理论是,赚钱是为了花,只有在流通中才能增值,买到喜爱的商品,让生活心旷神怡。而我的农民兄弟——这里特指是出身农家毕业后留在大城市的兄弟,习惯于把人民币紧紧地捏在手中。存折数字的增长让他们痴迷。该买房时,他们在租房;该还贷时,他们宁可忍受7%的贷款利率,也要存上5年的定期。辛苦赚来的银子在等待中缩水贬值。他们往往在房价的巅峰处,无可奈何地接下最后一棒;也曾天真地许愿,赚够100万就回家买房。可等到那一天真的到来,老家的房价,二线、三线城市甚至乡镇的都已疯长。 这便是我和你的最大差别,根深蒂固的分歧、不可逾越的鸿沟也在于此。我曾经以为,学位、薪水、公司名气一样了,我们的人生便一样了。事实上,差别不体现在显而易见的符号上,而是体现在世世代代的传承里,体现在血液里,体现在头脑中。18年的积累,家庭出身、生活方式、财务观念,造就了那样一个你,也造就了这样一个我,造就了你的疏狂佻达与我的保守持重。当我还清贷款时,你买了第二套住房;上证指数6000点,当我好容易试水成为股民,你清仓离场,转投金市;我每月寄1000元回去,承担起赡养父母的责任,你笑嘻嘻地说,养老,我不啃老就不错了;当我思考着要不要生孩子、养孩子的成本会在多大程度上折损生活品质时,4个老人已出钱出力帮你抚养起独二代;黄金周去一趟九寨沟挺好的了,你不满足,你说德国太拘谨美国太随意法国才是你向往的时尚之都…… 我的故事,是一代“移民”的真实写照——迫不得已离乡背井,祖国幅员辽阔,我却像候鸟一样辗转迁徙,择木而栖。现行的社会体制,注定了大城市拥有更丰富的教育资源、医疗资源、生活便利。即便取得了一纸户口,跻身融入的过程依然是充满煎熬,5年、10年乃至更长时间的奋斗才获得土著们唾手可得的一切。曾经愤慨过,追寻过,如今,却学会了不再抱怨,在一个又一个缝隙间心平气和。差距固然存在,但并不令人遗憾,正是差距和为弥补差距所付出的努力,加强了生命的张力,使其更有层次更加多元。 可以想见的未来是,有一天我们的后代会相聚于迪斯尼(这点自信我还是有的),讲起父亲的故事,我的那一个,虽然不一定更精致更华彩,无疑曲折有趣得多。那个故事,关于独立、勇气、绝地反弹、起死回生,我给不起儿子名车豪宅,却能给他一个不断成长的心灵。我要跟他说,无论贫穷富贵,百万家资或颠沛流离,都要一样地从容豁达。 至此,喝不喝咖啡又有什么打紧呢?生活姿态的优雅与否,不取决于你所坐的位置、所持的器皿、所付的茶资。它取决于你品茗的态度。 我奋斗了18年,不是为了和你一起喝咖啡。 背景 3年前,一篇题为《我奋斗了18年才和你坐在一起喝咖啡》的文章引起了社会各界的广泛共鸣。作者麦子,这位来自小城市的年轻人,用第一人称描绘了最典型的中小城市和农村子弟的奋斗历程—— “从我出生的一刻起,我的身份就与你有了天壤之别,因为我只能报农村户口,而你是城市户口。……于是我要通过自己的奋斗获得你生下来就拥有的大城市户口,考学是我跳出农门唯一的机会。……我属于比较幸运的,东拼西凑加上助学贷款终于交齐了第一年的学费,终于可以如愿以偿地在大学校园里汲取知识的养分了。我努力学习获得奖学金,假期打工挣点生活费,因为实在不忍心多拿父母一分钱。……我发现自己真是土得掉渣,不会作画,不会演奏乐器,不认识港台明星,没看过武侠小说,不认得mp3,不知道什么是walkman。我的英语是聋子英语、哑巴英语,我的发音中国人和外国人都听不懂……终于毕业了,能幸运地在上海找到工作的应届本科生只有每月2000元左右的工资,我要租房,要交水电煤电话费还要还助学贷款,还想给家里寄点钱让弟妹继续读书,剩下的钱只够我每顿吃盖浇饭。” 在奋斗了18年之后,“我”终于融入到这个国际化大都市中,与周围的白领没有什么差别。“我的白领朋友们,如果我是一个初中没毕业就来沪打工的民工,你会和我坐在starbucks(星巴克)一起喝咖啡吗?不会,肯定不会。比较我们的成长历程,你会发现,为了一些在你看来唾手可得的东西,我却需要付出巨大的努力。” 革命尚未成功,同志尚需努力。
09:06 需要什么样的监控? (2956 Bytes) » AnySQL.net

作者:d.c.b.a, 订阅AnySQL, Oracle数据库恢复及服务, Sybase恢复, 磁盘及RAID恢复

    一提到系统监控就会联想到Cacti这个优秀的开源软件, 或用Nagios. 不管什么样的监控软件平台, 监控可做的事大约有四个方面.

    一定的报警机制. 对于特定的事件, 需要用特定的方式(手机, 邮件, 淘宝旺旺等)通知相关人员, 通知的事件大小由监制的机制来决定, 如果是7x24的, 那一般只有交易量下降多少比例时才会报警, 如果不是7x24的, 那么有任何错误发生时都需要报警.

    一定的图表显示. 图表是最好的表现数据趋势的方式, 对于交易量或主机负荷之类的少数重要数据, 用图的方式显示. 缺点是一个屏幕内能提供的信息量比较少, 对于详细诊断问题所在起不了多少帮助.

    很多的详细信息. 用网页方式显示某些方面详细的数据, 如将所有的消息滞留的情况记录下来, 用来查找发生的问题. 更多的如应用中关键的API调用次数, 显示一个当前值和历史平均值, 也可以确定某个点是不是有问题. 非常适合于详细问题的快速确定.

    一定的自动响应机制. 管理出身的会很关注这一点, 是很好的设想, 但不容易实现, 最简单地说表空问不足这个问题吧, 让程序自动加文件? 还是做一个空间预测, 提前加好空间, 个人偏向于后者.

    现在监时做的一些监控就是建立在自已开发的WebChart基础上的, 表格和图形并存的方式. 更适合于白天工作时段的监控, 好好保存一定历史信息, 还可用于事后问题查找.

相关文章 | Related Artiles

我要留言(当前0)

  2008-08-21 Thu

21:45 Facebook 的 Scaling Out 经验 (2818 Bytes) » DBA notes

Facebook 其实对待技术的态度其实挺开放的。今天阅读了这篇 Scale Out, 工程师 Jason Sobel 介绍了在对付跨地域 MySQL 复制网络延迟的问题。

Cache 一致性问题解决思路

大量的 MySQL + Memcached 服务器,布署简示:

California (主 Write/Read)............. Virginia (Read Only)

主数据中心在 California ,远程中心在 Virginia 。这两个中心网络延迟就有 70ms,MySQL 数据复制延迟有的时候会达到 20ms. 如果要让只读的信息从 Virginia 端发起,Memcached 的 Cache 数据一致性就是个问题。

  • 1 用户发起更新操作,更名 "Jason" 到 "Monkey" ;
  • 2 主数据库写入 "Monkey",删除主、从两端 Memcached 中的名字值;
  • 3 在 Virginia 有人查看该用户 Profile ;
  • 4 在 Memcached 中没发现用户名字,从 Virginia Slave 数据库读取,因为网络延迟,结果读到了 "Jason";
  • 5 更新 Virginia Memcached 中的该用户名字为 "Jason";
  • 6 复制追上了,更新名字为 ""Monkey";
  • 7 又有人读取 Profile 了;
  • 8 在 Memcached 中找到了键值,返回 "Jason" (实际上造成业务冲突了)

解决办法挺有意思,在 SQL 解析层嵌入了针对 Memcached 的操作。

  • 1 用户发起更新操作,更名 "Jason" 到 "Monkey" ;
  • 2 主数据库写入 "Monkey",删除主端 Memcached 中的名字值,但Virginia 端 Memcached 不删;(这地方在 SQL 解析上作了一点手脚,把更新的操作"示意"给远程);
  • 3 在 Virginia 有人查看该用户 Profile ;
  • 4 在 Memcached 中找到键值,返回值 "Jason";
  • 5 复制追上更新 Slave 数据库用户名字为 "Monkey",删除 Virginia Memcached 中的键值;
  • 6 在 Virginia 有人查看该用户 Profile ;
  • 7 Memcache 中没找到键值,所以从 Slave 中读取,然后得到正确的 "Monkey" 。

这里面的一个简单的原则是: 更新后的数据,用户第一次读取要从数据库读,顺便扔一份到 Cache 里,而不是在写入的时候直接更新 Memcached 。避免写事务过大。

而写操作的原则是:一次写入,到处分发

第二个问题是关于"Page Routing"的 ,也很有参考价值。感兴趣的自己读一下吧。

--EOF--

另推荐一下: 分布式系统中的一致性和可用性,该文是上次在支付宝 QClub 活动的总结之二。

07:51 开启异步IO的相关风险 » OracleBlog.cn
00:07 TCP 连接断连问题剖析 » developerWorks 中国 : 技术文章 , 教程 AIX

  2008-08-20 Wed

22:31 Learning ODI - Sybase to Oracle » Chanel [K]
07:01 推荐一个多协议IM工具Pidgin » Ricky's Test Blog
02:12 Korn Shell 脚本入门 » developerWorks 中国 : 技术文章 , 教程 AIX
02:11 带宽与I/O(转) » ORATEA
00:31 mysql压力测试工具:mysqlslap » Taobao DBA Team

2008-08-19 Tue

08:28 再说刘翔退赛 » 存储部落
03:01 使用过order by rowid排序吗 » Taobao DBA Team

  2008-08-18 Mon

22:22 长寿烟 安定 可乐 旺仔 » OracleDBA Blog---Please enjoy the pain which is unable to avoid!
18:26 Korn Shell 脚本入门 » oracle unix&linux技术
04:06 Data Guard与nid » Taobao DBA Team
 123
 123