首页 | 摘要显示 | 上一页 1 2 3 4 5 6 7 8 9 10 下一页

Developer Archives

August 15, 2007

从OCIThread回到POSIX Thread编程模式

    我要实现的任务其实很简单, 就是想要每隔一定的时间去数据库中获得一些信息, 获得这些信息可能需要运行八到十个SQL语句, 随着数据库上的连接数, 负荷等的不同, 这些查询所需要的时间是不一定的, 有可能十分之一秒就可以返回, 也可能要几秒. 但是我想要的是以固定的间隔打印出这些数据. 于是我就想了一个主进程, 隔一定的时间去产生一个线程, 由线程去执行这些SQL语句, 打印出信息, 这样可以保证时间是很均匀的.

    于是我就从fork到vfork, 再到thread(Solaris), 再到pthread(Solaris和Linux), 然后再到OCIThread. 上了OCIThread后, 还有程序挂起的情况发生, 因此并没有解决我想要解决的问题, 一开始是用自已的变量来防止并行执行OCI调用, 后来改成OCIThreadMutex, 还是一样, 并且发现OCIThread后, 服务器端的Oracle后台进程的CPU消耗要比普通方式高出20%左右, 因此OCIThread并没有优势. 于是退出到了POSIX的线程调用, 这次用了上POSIX上的Mutex.

    程序还在测试, 以前用多线程方式时, 总是12小时左右, 整个程序就挂起了. 现在分成两路来测试, 一组是不用线程, 另一组是用了线程的, 希望这一次能顺利通过, 要是能不停顿运行一周的话, 表示程序足够稳定了, 同时也要观察有没有内存分配后没有回收的问题. 虽然写程序很累, 不过能学到不少东西.

    我正在测试的程序是什么呢? 就是最上面挂的AnySQL Oracle Monitor了, 在前面的贴子里我已经讲过这个程序不会主动公开下载. 有谁对线程比较熟的, 探讨一下?

August 16, 2007

终于找到POSIX Thread挂起的原因了

    昨天跑的Thread程序还是停住了, 原因是不能再创建新的线程了, 返回错误代码11, 表示达到了最大能创建的线程数了. 一开始很不明白, 因为就我这个程序, 应当只会有一个线程在去行, 不可能多个. 于是我检查了一下进程占用的内存, 居然高达132MB, 因此是系统资源到了最大限制了(POSIX对最多进程数的限制).

    于是我想起了当初用fork/vfork时, 因为没有加入一行代码, 导致了进程结束后, 系统并没有自动回收占用的有关资源, 因此线程可能也遇到了同样的问题. 经过一翻网上搜索, 终于明白了其中的道理.

    创建线程时可以指定很多的属性, 如可Join的线程或者是自动Detach的线程, 默认是可Join的. 在系统中有一个定长数组, 存放了历来创建线的线程的信息, 可Join的线程虽然运行结束了, 但是资源不会回收, 要等主进程来检查, 因此线程创建多了, 这个数据全都满了, 所以不能再创建线了. 在大部份程中, 主进程创建了几个子进程后, 就调用pthread_join方法来等所有的子线程结束, 这时就相当于主进程去检查这个数据, 并回收已经结束的线程的资源. 在我的程序里没有pthread_join调用, 因此出了这个问题.

    今天我又改了代码, 在开始线程之前, 先将老的线程清掉(pthread_detach), 其实就是从这个数组中清除占位标志, 并回收分配给每个线程的堆栈空间, 原来运行几分钟后内存就涨到30M, 现在这样改了后就一直没有增长, 看来应当是可以解决问题了.

    又看不懂了吧? 我自已也是希里糊涂的了.

September 4, 2007

在Perl中用Array DML来进行性能调优

    asyncdata是一个用于同步数据的角本, 基于实体化视图日志或自定义的触发器来获得变更的记录, 然后防照实体化视图刷新的过程来进行数据同步. 几个月之前完成的这一段角本, 现在要拿来作一些数据的迁移用了. 除正确性外, 性能就是最关键的因素了.

    在处理SELECT的结果时, 我们已经广泛地使用Array Fetch提升性能了, 不过Array DML真正用得还是不够广的, 相对来说, 在PL/SQL中用得多一些. 现在我要测试的是在Perl测试Array DML的性能提升.

    做的测试是在两个不同的数据中心间进行数据同步, 网络速度肯定是不够快的, 在不用Array DML的情况下, 源节点这边插入一万条记录(表有13个字段, 一个主键索引), 用Perl同步到目标数据库需要40秒, 用dblink的结果更差, 需要一分钟左右. 通过升级DBD Oracle后, 用Array DML方式处理这一万条刻录时(Array Size为500), 只用了4秒钟, 整个速度提升了10倍, 应当可以满足性能要求了.

    用Perl而不用PL/SQL的原因是可以做得比较通用, 要写一段PL/SQL程序来处理几个表, 还要用Array DML方式, 代码难度比较高. 而用Perl等角本语言, 则可以很轻松地实现. 如有这种少量表的数据同步需求, 不防考虑使用这个角本. 如果两端的数据互不干涉, 则还可以做成双向同步.

September 10, 2007

Perl Array DML的正确错误处理方法

    以前一直以为自已的处理方法是对的, 在asyncdata脚角正式使用了一次后, 发现还是错了.

    下面一段是原来的处理角本:

my $rv = $delstmt->execute_array({ArrayTupleStatus => \@rowstats});

if (! defined($rv))
{
    # Error processing
    my $updcnt = @rowstats;
    for($i=0;$i<$updcnt;$i++)
    {
       if (ref $rowstats[$i])
       {
           # Error code : $rowstats[$i]->[0]
           # Error mesg : $rowstats[$i]->[1]
           ......
       }
    }
}

    而准确的代码应当是:

my $rv = $delstmt->execute_array({ArrayTupleStatus => \@rowstats});

if (! defined($rv))
{
    if ($delstmt->err())
    {
       # Normal Oracle error, for example table is read only.
       ......
    }
    else
    {
       # Array DML Error processing
       my $updcnt = @rowstats;
       my $j = 0;
       for($i=0;$i<$updcnt;$i++)
       {
          if (ref $rowstats[$i])
          {
              # Error code : $rowstats[$i]->[0]
              # Error mesg : $rowstats[$i]->[1]
              ......
          }
       }
    }
}

    现在已经修复好了, 如果有使用asyncdata角本的, 请重新下载.

December 14, 2007

简单Perl XML编程

    XML出来好久了, 亏我很早就用Java写程了, 但从没有写过处理XML的程序, 前段时间在整Text Links Ads的广告代码时, 发现了一段Perl处理XML的样本程序, 因为也常用XML来写工具, 如果将配置文件改成XML文件, 倒是件好事, 就在这儿总结一下. 下面是我要处理的一个XML文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
  <row col1="AnySQL" col2="4"></row>
  <row col1="DBATools" col2="1"></row>
</rows>

    XML的数据结构, 在Perl中对应起来主要是Hash的Hash结构, 也不是很复杂.

#!/usr/bin/perl -w
use XML::Simple;
my $xml  = new XML::Simple;
my $data = $xml->XMLin("./test.xml");
if ($data->{'row'}) {
   # Convert to hash, if it's array
   if (ref $data->{'row'} eq "HASH") {
       @$temp = ($data->{'row'});
       $data->{'row'} = $temp;    }
   if ($data->{'row'}->[0])    {
       my $count = 0;
       while($data->{'row'}->[$count])  {
         if (ref $data->{'row'}->[$count] eq "HASH")  {
           print $data->{'row'}->[$count]->{'col1'}, ",";
           print $data->{'row'}->[$count]->{'col2'}, "\n";  }
         $count ++;  }
   }     }

    程序运行的结果:

C:\temp\>xml.pl
AnySQL,4
DBATools,1

    如果你不知道什么是XML, 则请跳过这篇文件.

上一页 1 2 3 4 5 6 7 8 9 10 下一页

当前分类: Developer

Creative Commons License
本站版权: 共用创作 CC
署名-非商业性-相同方式分享
本站基于MT-3.36免费版
(©)版权所有, 2004 - 2008, www.AnySQL.net, 保留所有权利.
MSN: loufangxin(a)msn.com, Mail: anysql(at)126.com/support(at)iamdba.com, Skype ID:anysql