Tips: AUL License, DBA Tools

AIX下获得HBA卡的IO流量信息

Posted by anysql on 2010-07-14

    IO历史是调优的兵家必争之地, 然而存贮厂商对IO的性能数据接口采用了保守的态度, 不对用户免费开放, 只提供定向开发服务, 没办法只能从主机这块入手了. 在AIX下可以用scsistat小程序来实时查看HBA卡上的流量.

    在命令行不带参数运行时, 会将IO性能数据直接写在屏幕上.

[oracle@test:/home/oracle/xinloufx]scsistat.bin
2010-07-14 17:07:15,test,fscsi2,2368,32,150,148,4
2010-07-14 17:07:15,test,fscsi3,2368,48,151,148,2
2010-07-14 17:07:15,test,fscsi0,2352,32,149,147,0
2010-07-14 17:07:15,test,fscsi1,2368,32,150,148,2
2010-07-14 17:07:25,test,fscsi2,2304,32,146,144,1
2010-07-14 17:07:25,test,fscsi3,2320,32,147,145,2
2010-07-14 17:07:25,test,fscsi0,2288,80,148,143,3
2010-07-14 17:07:25,test,fscsi1,2320,48,148,145,5

    各个列的数据依次为: 时间, 主机名, 光纤通道, RBLKS, WBLKS, XFERS, XRATE, IOTIME. 可以将数据用file选项输出到文件, 然后进行数据处理.

scsistat.bin file=scsistat.dat wait=60

    上面的命令将会每分钟收集一次性能数据,并将性能数据写入到scsistat.dat文件. 画成曲线分析,将会更显效果.

    上面的曲线可用AnySQL DataReport轻松制作出来.

控制SQLULDR2的字符集

Posted by anysql on 2010-06-24

    默认情况下, Oracle客户端程序的字符集都由环境变量(NLS_LANG)决定, 很多时侯会因为忽略了环境变量的检查, 尤其是在Shell或Perl脚本中调用时, 导致导出的数据变成了乱码. 在OCI 8的接口中, 可以使用OCIEnvNlsCreate函数在程序中指定客户端字符集, 从而跳过环境变量的影响, 于是就在SQLULDR2工具中新增了两个选项, 用于指定导出时了字符集.

    新的SQLULDR2工具命令行帮助如下所示:

SQL*UnLoader: Fast Oracle Text Unloader (GZIP, Parallel), Release 4.0.1
(@) Copyright Lou Fangxin (AnySQL.net) 2004 – 2010, all rights reserved.

Usage: SQLULDR2 keyword=value [,keyword=value,...]

Valid Keywords:
  user    = username/password@tnsname
  sql    = SQL file name
  query  = select statement
  field  = separator string between fields
  record  = separator string between records
  rows    = print progress for every given rows (default, 1000000)
  file    = output file name(default: uldrdata.txt)
  log    = log file name, prefix with + to append mode
  fast    = auto tuning the session level parameters(YES)
  text    = output type (MYSQL, CSV, MYSQLINS, ORACLEINS, FORM, SEARCH).
  charset = character set name of the target database.
  ncharset= national character set name of the target database.
  parfile = read command option from parameter file

  for field and record, you can use ’0x’ to specify hex character code,
  \r=0x0d \n=0x0a |=0x7c ,=0x2c, \t=0×09, :=0x3a, #=0×23, “=0×22 ‘=0×27

    在一个GBK的数据库中存入”中国”两个字, 然后以GBK和UTF8两种不同的字符集进行导出, 在命令行指定字符集设置.

C:\>sqluldr2 scott/tiger query=test charset=ZHS16GBK
      0 rows exported at 2010-06-24 09:12:27, size 0 MB.
      1 rows exported at 2010-06-24 09:12:27, size 0 MB.
        output file uldrdata.1.txt closed at 1 rows, size 0 MB.

C:\>dir uldrdata.1.txt
2010-06-24  09:12                5 uldrdata.1.txt

C:\>sqluldr2 scott/tiger query=test  charset=UTF8
      0 rows exported at 2010-06-24 09:12:42, size 0 MB.
      1 rows exported at 2010-06-24 09:12:42, size 0 MB.
        output file uldrdata.1.txt closed at 1 rows, size 0 MB.

C:\>dir uldrdata.1.txt
2010-06-24  09:12                7 uldrdata.1.txt

    用GBK导出时, 文件大小为5个字节, 两个汉字(一个汉字占两个字节)再加一个换行符. 而用UTF8导出时, 文件大小为7, 两个汉字(一个汉字占三个字节)加上一个换行符. 如果用SQLULDR2为特定的数据库写脚本程序时, 在命令行指定字符集, 将使脚本更加强壮.

    另外, SQLULDR2将终结新功能的开发了, 除非有商业的需求.

2011年起SQLULDR2中的收费功能

Posted by anysql on 2010-06-19

    决定从2011年开始, 对文本导出工具SQLULDR2中的部份功能收费, 当然这些收费的功能一般是用不到的, 所以大家也不用太担心这个工具还能不能再用. 四个收费的功能是: 自动生成SQL*Loader控制文件, 按记录数切分文件, 按大小切分文件, 大表并行导出, 如果对这个有很强的意见, 可以在这里回复.

    自动生成SQL*Loader控制文件功能取决于是否用TABLE参数指定目标文件名.

sqluldr2 … table=target_table control=target_table.ctl

    按记录数切分文件的功能取决于三个命令行选项: FILE, ROWS, BATCH. 其中FILE选项指定的文件名中需要包括”%b”特征串, 以表示生成的文件号. ROWS指定单个文件的记录数, 而BATCH则指定是否切换成多个文件.

sqluldr2 … rows=100000 batch=yes file=uldrdata.%b.txt

    按大小切分文件的功能取决于两个命令行选项: FILE, SIZE. 其中FILE选项指定的文件名中需要包括”%b”特征串, 以表示生成的文件号; 而SIZE选项指定每个文件的目标大小.

sqluldr2 … size=100 file=uldrdata.%b.txt

    大表并行导出功能, 用法比较复杂一些, 可以参照这篇英文文章. 注册码和源数据库的名字关联,只要源库的名字相同,则可以共用注册码,并且DataCopy, DataSync, oramon也自动获得注册码, 实际上是这四个工具的注册码一起获得.

Linux下获取IO压力数据

Posted by anysql on 2010-06-18

    Linux 2.6内核版本后, 在proc文件系统中, 加入了存入磁盘IO访问数据的文件diskstats, 查看文件就可以获得某一时刻的累计访问值.

$ cat /proc/diskstats
  ……
  8    0 sda 130767120 478199 2848404253 865895766 …
  8    1 sda1 58 740 1598 96 2 0 4 0 0 96 96
  8    2 sda2 4031326 3249 64502142 3693948 5273723 …
  8    3 sda3 142 3261 4030 865 538334 302764 …
  8    4 sda4 1 0 2 3 0 0 0 0 0 3 3
  8    5 sda5 57717 8304 2083594 152577 2023051 …
  8    6 sda6 3283 617 126914 18536 1965077 …
  8    7 sda7 31 1062 1348 164 0 0 0 0 0 121 164
  8    8 sda8 63475 1067 1170446 364557 1050986 …
  8    9 sda9 409 1423 4454 2141 579616 2614979 …
  8  10 sda10 30 352 1668 130 0 0 0 0 0 125 130
  ……

    在实际的编程中, 有两个问题要处理, 一个是如何找出磁盘, 并将分区过滤掉, 因为Linux会同步更新磁盘分区及磁盘的数据, 如果不加区分, 数据就会不准确, 这个可以通第2列及第3列加以区分, 第二列为16的倍数的表示是磁盘而非分区, 第三列是磁盘名字, 一般的系统中磁盘都是小写的sd开头的. 对于普通的scsi磁盘, 只要找出第二列是16的倍数, 并且第三列前两个字母是”sd”的, 就表示是真正的磁盘, 比如前面的数据中, 只能取第一行. 为什么是16的倍数, 估计和一块盘最多有16个分区有关吧.

    磁盘中, 第四列后的都是性能数据, 各列的官方解释如下.

Field  1 — # of reads completed
    This is the total number of reads completed successfully.
Field  2 — # of reads merged, field 6 — # of writes merged
    Reads and writes which are adjacent to each other may be merged for
    efficiency.  Thus two 4K reads may become one 8K read before it is
    ultimately handed to the disk, and so it will be counted (and queued)
    as only one I/O.  This field lets you know how often this was done.
Field  3 — # of sectors read
    This is the total number of sectors read successfully.
Field  4 — # of milliseconds spent reading
    This is the total number of milliseconds spent by all reads (as
    measured from __make_request() to end_that_request_last()).
Field  5 — # of writes completed
    This is the total number of writes completed successfully.
Field  7 — # of sectors written
    This is the total number of sectors written successfully.
Field  8 — # of milliseconds spent writing
    This is the total number of milliseconds spent by all writes (as
    measured from __make_request() to end_that_request_last()).
Field  9 — # of I/Os currently in progress
    The only field that should go to zero. Incremented as requests are
    given to appropriate struct request_queue and decremented as they finish.
Field 10 — # of milliseconds spent doing I/Os
    This field is increases so long as field 9 is nonzero.
Field 11 — weighted # of milliseconds spent doing I/Os
    This field is incremented at each I/O start, I/O completion, I/O
    merge, or read of these stats by the number of I/Os in progress
    (field 9) times the number of milliseconds spent doing I/O since the
    last update of this field.  This can provide an easy measure of both
    I/O completion time and the backlog that may be accumulating.

    另一个问题, 当Linux接到存贮时, 可能会有多条通路, 形成很多的虚盘, 这时不能取虚盘的性能数据, 比如连到EMC的存贮时, 第三列的名字应当为emcpower开头, 而不是sd开头了. 在Linuxmon程序中, 可以通过disk参数, 指定磁盘的前缀名字.

$ linuxmon.bin disk=emcpower
… Read RTim Writ WTim Busy Time
…  70    0  57    0    0  39
…  65    0  55    0    0  40
…  100    0  162    0    0  112
…  70    0  57    0    0  36
…  65    0  70    0    0  64
…  76    0  55    0    0  33
…  105    2  98    0    0  74
…  65    0  54    0    0  38
…  155    0  102    0    0  85
…  76    0  63    0    0  49
…  64    0  54    0    0  38
…  53    0  34    0    0  22

    如果上面的理解有问题, 欢迎指出来, 正在学习之中, 有理解错误也是难免的.

不可靠的EXP远程备份

Posted by anysql on 2010-05-28

    前天接到一个求助电话, 说是一个dmp文件不能导入, 一开始经验性地认为可能是ftp传文件的模式问题, 后来对方再三确认不是这个问题, 就让人家将dmp文件传给我看一下, 在导入指定用户时遇到了不正常的dmp文件结束错误.

    虽然因为写AUL而对数据文件块格式比较清楚, 但DMP文件如果乱了却是没有什么招的, 虽然如此, 试着导入几次无果后, 还是用UltraEdit以十六进制打开了DMP文件, 看到DMP文件中有SH等Oracle Demo用户的表, 于是指定导入SH用户试试, 居然全部导入, 然后报了一个不正常的dmp文件结束错误.

    这时明白了最终的原因, 这个DMP文件不全, 也就是只给了完整DMP文件的一部份, 于是在DMP文件中查找所有的”CONNECT”字符, 没有发现用户表所在的用户名, 就告诉用户这个DMP文件不全, 只导出了部份, 有没有更大的DMP文件. 但心中明白了一些原委, 一般情况下在安装Oracle时都会装很多的Demo用户, 并且一般会使用具有DBA权限的用户(给常用的帐户授于DBA权限), 所以进行导出时, 虽然连到了准确的用户, 但还是因为拥有DBA权限而做了全库导出, 每次都优先导出了那一堆Demo用户的数据, 而不是用户的真正数据.

    进一步与用户确认, 原来用户为了做灾备, 对这个并不重要的数据, 用Internet的连接来做EXP备份, 猜想由于国内互联网的不稳定性, 经常导到一半或更少时就断开了, 造成了一个不全的EXP备份. 然后以为有EXP备份, 没有确认就将系统重新格掉重装Oracle了, 引起了这一悲剧.

    上一次去做现场服务时, 发现只用EXP做备份的情况还是比较多的存在, 这下要小心了, 至少要判断EXP命令的返回值, 最好是做EXP备份的导入验证, 以确保这个唯一的备份是有效的, 当然更好的是咨询专业人员采用更好的备份策略.

    如果你正在用Internet连接做远程备份, 千万要小心了!


(©)Copyright 2006-2010 AnySQL.net. All rights reserved.