I can believe fly.

Tuesday, December 28, 2010

使用subprocess.Popen,程序block问题处理

使用subprocess.Popen,程序block问题处理

问题:

 脚本运行中,执行sudo strace svnadmin,出现卡死现象,一直保持如下信息不动:

 getcwd("/home/ysl/svn-repo-bak"..., 4098) = 28

 write(2, "* Dumped revision 2769.\n", 24

分析:

jessinio: jobs有什么呢

: 没东西

jessinio: 终端是不是和你运行SvnDumpBak.py是同一个?

: 不是,我又另外打开了一个

jessinio: 呃。。。车子不同, 你查个刹车 没有意义

: 那我要在执行命令那里,ctrl z掉,让它在后台跑?

jessinio: ctrl z 然后bg

: [ysl@svn-repo-bak]$ bg

[1]+ sudo python SvnDumpBak.py yslProR &

[[ysl@svn-repo-bak]]$ jobs

[1]+ Running sudo python SvnDumpBak.py yslProR &

 

jessinio: ps auxwww|grep strace

: [[ysl@svn-repo-bak]]$ ps auxwww|grep strace

ysl 10851 0.0 0.0 61144 728 pts/0 S+ 14:45 0:00 grep strace

root 31108 2.2 0.0 4112 632 pts/1 S+ 14:31 0:17 strace -p 17686

jessinio: 还有一个strace

: 我打另一个连接,在跑strace来看,刚还有信息在更新。现就卡着了

jessinio: 你把strace停了

: ctrl c??

: 停了

 

jessinio: ps auxwww|grep 7z

: root 17687 85.5 4.9 233772 199576 pts/0 Sl 14:15 27:37 /usr/local/p7zip_9.13/bin/7z a -si /data/backup/svnRepo//20101227/yslProR.full20101227.dump -pNBc5RB!

jessinio: strace -p 17687

: [[ysl@svn-repo-bak]]$ sudo strace -p 17687

Process 17687 attached - interrupt to quit

[ Process PID=17687 runs in 32 bit mode. ]

futex(0x86b54ac, FUTEX_WAIT_PRIVATE, 1366961, NULL

jessinio: top -p 17687

: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

17687 root 15 0 228m 194m 1856 S 0.0 4.9 27:37.96 7z

jessinio: 变化 不?

: TIME+下的数据没变啊

jessinio: 还是没有变?

: 没,还是 27:37.96

jessinio: ps auxwww|grep svnadmin

: root 17686 2.4 2.5 205868 103152 pts/0 S 14:15 1:10 svnadmin dump /storage/repool/yslProR -r 0:4855

jessinio: 你的代码应该有问题。

: 可是小的仓库为什么没问题呢

jessinio: buffer没有满呀

结论:

    同事帮忙分析是由于buffer满导致,检查了程序,原版:

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    p.wait()

    # command exec error,print detail info

    if p.returncode:     

        write_log(p.stdout.read())

    return p.returncode

    也就是说没有处理输出数据,而pipe容量有限的。如果满了将会block或者fail。信息如下:

Pipe Capacity

      A pipe has a limited capacity.  If the pipe is full, then a write(2) will block or fail, depending on whether the  O_NONBLOCK

      flag  is  set  (see  below).

解决:调整脚本,增加了一个变量来读取PIPE里的输出数据

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    retval = p.stdout.read()

    p.wait()

    # command exec error,print detail info

    if p.returncode:     

        write_log(retval)

    return p.returncode

资料:   

    subprocess模块:http://docs.python.org/library/subprocess.html


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

svnadmin dump | 7z命令执行失败

svnadmin dump | 7z命令执行失败

问题:

7-Zip 9.13 beta  Copyright (c) 1999-2010 Igor Pavlov  2010-04-15

p7zip Version 9.13 (locale=C,Utf16=off,HugeFiles=on,2 CPUs)

Compressing  [Content]

System error:

Operation not permitted

svnadmin: Can't write to stream: Broken pipe

疑问:为什么小仓库dump,7z压缩正常,而大的仓库就会报类似以上的错误?

分析:

1. 执行mount,获取分区信息

2. 执行df -h,获取硬盘大小信息

3. 检查引发错误的的执行命令行是否有问题

svnadmin dump /storage/yslProR -r 0:1000 | /usr/local/p7zip_9.13/bin/7z a -si /data/space/svndumpbak/20101229/yslProR.full20101229.dump -p2048密码

结论:

   1.问题是由于空间不足引发的,其中/data目录的空间占用100%,信息如下:

     /dev/mapper/VolGroupData-LogVolData   10G   10G   74M 100% /data

   2.而引发空间不足,又是由于/data/space的空间没mount成功导致的。

解决:

    1.重新mount备份存储空间

      mount -t nfs 192.168.5.5:/data/space/ /data/space/

    2.为避免机子重启,mount空间失效,则请将以上mount命令加入/etc/rc.local


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

Linux下scp密钥问题

需求A机往Bscp操作

事件:要求运维的系统管理员给配个密钥,把公钥分配给B机。原以为他把公钥让我扔给B机的主人,而私钥他会配好,结果啥也没做, 啥也没配,也没说。结果,我杯剧:

情景

SSHA机,scp数据时出现如下错误:

Permission denied (publickey,gssapi-with-mic).

lost connection

咨询了一下,私钥放在哪。答案:本地(A)没放。好吧,我认,自个动手把私钥cpA机的某目录下如/home/ysl/cfg/ysl_key,并更改文件的权限:chmod 0600 /home/ysl/cfg/ysl_key

继续试着执行scp操作:

scp -r /data/tempdir/20101025 -i /home/ysl/cfg/ysl_key ysl@5.5.5.5:/data/ysldata

结果错误信息仍然存在。

那么,试着SSH一下:

ssh -i /home/ysl/cfg/ysl_key ysl@5.5.5.5: "ls -ld /data/ysldata"

很好,有正常信息出现,那为什么scp不行??

试着在scp时打印出相关日志,执行:

scp -vvv /data/tempdir/20101025/file -i /home/ysl/cfg/ysl_key ysl@5.5.5.5:/data/ysldata

日志中发现-i指定私钥不被识别,只会在当前账号的根目录去找/home/ysl/.ssh/id_rsa

继续试着执行cp /home/ysl/cfg/ysl_key /home/ysl/.ssh/id_rsa

然后重新scp操作,发现正常了。

结论

据同事给出scp的手册中说明-i identity_file的信息:

Selects the file from which the identity (private key) for RSA authentication is read. This option is directly passed to ssh(1).

相当于说-i是指定使用RSA的私钥。上面用到的私钥/home/ysl/cfg/ysl_key并不是RSA格式的,因此无效。

解决

1. 更找密钥,生成RSA格式的

2. 以某个要执行scp动作的账号按以下步骤操作(elian)

mkdir /elian/.ssh

chmod 0700 /elian/.ssh

cp /home/ysl/cfg/ysl_key /elian/.ssh/id_dsa

chown -R root:root /elian/.ssh

chmod 0600 /elian/.ssh/id_dsa



--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

Tuesday, December 21, 2010

SVN命令行:error while loading shared libraries

错误类似信息:

svnlook: error while loading shared libraries: libsvn_repos-1.so.0: cannot open shared object file: No such file or directory

 

以下是本人在执行脚本报如上错误时,查找原因的步骤信息

1.执行ldd $(which svnlook),获取含有so.0:文件的信息(文件存在,为何还报错呢?)

libsvn_repos-1.so.0 => /usr/local/lib/libsvn_repos-1.so.0 (0x00002b0260dd2000)

2. 接着试单独执行svnlook ......,结果是正常使用的;

3. 继续执行了whereis svnlook ,得出以下两个路径:

usr/bin/svnlook usr/bin/local/svnlook

4. 紧接,试着单独执行usr/bin/svnlook,结果报了一样的错误(注:脚本带有/usr/bin/env,因此脚本运行时也是使用这路径的命令)

5. 执行ldd /usr/bin/svnlook,需要的文件真的是找不到 

libsvn_repos-1.so.0 => not found

libsvn_fs-1.so.0 => not found

libsvn_fs_fs-1.so.0 => not found

libsvn_fs_base-1.so.0 => not found

libsvn_delta-1.so.0 => not found

libsvn_diff-1.so.0 => not found

libsvn_subr-1.so.0 => not found

 

结论usr/bin/svnlook该路径的命令有问题

处理:

a.安全起见,备份下原来的

mv /usr/bin/svnlook /usr/bin/svnlook_back

b.重新ln一份正常的

ln -s /usr/local/bin/svnlook /usr/bin/svnlook


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

Py脚本莫名的问题莫名的解决

脚本在执行时,突然报如下错误(声明:在十分几分钟前运行是正常的):

  File "/home/yusulian/ysltest/mail.py", line 6, in <module>

    import smtplib

  File "/usr/local/lib/python2.5/smtplib.py", line 49, in <module>

    from email.base64MIME import encode as encode_base64

ImportError: cannot import name encode

 疑惑:有点莫名其妙,没变动python的环境。

 结果:实在是没有头绪,直接跑到运行的工作目录,把相关*.pyc文件给删出,然后在重新运行一下,竟然正常了。


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

Linux/win下共用正则表达式,获取干净的md5值

linuxwin下执行完md5命令后,各自返回的信息格式有出入,作下记录:

[yusulian@wol-svn-svr0 ysltest]$ md5sum /data/backup/20101217/dop.full20101217.dump

b5952f4f489e9db46115425f01408343  /data/backup/20101217/dop.full20101217.dump

 

E:\WorkDir\yusulian\>D:\soft\too\md5\md5sum.exe E:\WorkDir\temp\svndump\20101217\R0.full20101217.dump

\98b8f16be45b07e64b1dceff19b6a3aa *E:\\WorkDir\\temp\\svndump\\20101217\\R0.full20101217.dump

 

给出共用的正则表达式,获取干净的md5值:

regStr = r"(\\|)(.*)(  | \*)(.*)"

md5Value = re.match(regStr, md5Result).group(2)

return md5Value


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

Wednesday, November 24, 2010

[转]tomcat内存溢出总结

转载下别人对方面的总结,比较清晰
http://developer.51cto.com/art/200908/144653.htm

在生产环境中tomcat内存设置不好很容易出现内存溢出。本文分析了三种造成Tomcat内存溢出的原因,并分别进行了分析。
Tomcat内存溢出的原因

在生产环境中tomcat内存设置不好很容易出现内存溢出。造成内存原因是不一样的,当然处理方式也不一样。

这里根据平时遇到的情况和相关资料进行一个总结。常见的一般会有下面三种情况:

1.OutOfMemoryError: Java heap space

2.OutOfMemoryError: PermGen space

3.OutOfMemoryError: unable to create new native thread.

Tomcat内存溢出解决方案

对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。(-Xms -Xmx -XX:PermSize  -XX:MaxPermSize)

最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。

第一种:是堆溢出。

在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。

没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。

-Xms:初始堆大小

-Xmx:最大堆大小

但堆的大小受下面三方面影响:

1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试 1612M,64为操作系统对内存无限制。)

2.系统的可用虚拟内存限制;

3.系统的可用物理内存限制。

堆的大小可以使用 java -Xmx***M  version 命令来测试。支持的话会出现jdk的版本号,不支持会报错。

-Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m

第二种:永久保存区域溢出

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。但目前的hibernate和spring项目中也很容易出现这样的问题。http://www.javaeye.com/topic/80620?page=1 的帖子有讨论的这个问题。可能是由于这些框架会动态class,而且jvm的gc是不会清理PemGen space的,导致内存溢出。

这一个一般是加大-XX:PermSize  -XX:MaxPermSize 来解决问题。

-XX:PermSize 永久保存区域初始大小

-XX:PermSize 永久保存区域初始最大值

这一般结合第一条使用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m  -XX:PermSize=128M -XX:PermSize=256M

有一点需要注意:java -Xmx***M  version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的 和 比如系统支持最大的jvm堆大小事1.5G,那  -Xmx1024m  -XX:PermSize=768M 是无法运行的。

第三种:无法创建新的线程。

这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。

这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。

产生这种现象的原因如下(从这个blog中了解到原因:http://hi.baidu.com/hexiong/blog ... b10c2542a75b3c.html):

每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。

这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。

给出一个有关能够创建线程的最大个数的估算公式:

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

对于jdk1.5而言,假设操作系统保留120M内存:

1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads

1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads

在2000/XP/2003的boot.ini里头有一个启动选项,好像是:/PAE /3G ,可以让用户进程最大内存扩充至3G,这时操作系统只能占用最多1G的虚存。那样应该可以让JVM创建更多的线程。

因此这种情况需要结合操作系统进行相关调整。

因此:我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。

以上就是针对Tomcat内存溢出的几种解决方案。本文来自George的博客:《tomcat内存溢出总结》


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com