Skip to content

关于Aix上的逻辑卷偏移量

##########################
www.ludatou.com 大头
转载请指明处,否则追责法律责任
##########################

在AIX5.3中,系统支持三种类型的VG,分别是Original VG、Big VG、Scalable VG(AIX5.3的新特性)。
mkvg命令默认将创建Origninal VG:最大支持32 physical volumes and 255 logical volumes
mkvg –B命令将创建Big VG:最大支持128 physical volumes and 512 logical volumes
mkvg –S命令将创建Scalable VG:最大支持1024 physical volumes, 256 logical volumes and 32k physical partitions

应用程序直接访问LVCB是比较危险的,因此在建立数据文件使用的裸设备时,不能从逻辑卷开始位置,而是应该有一个偏移量(offset),偏移量的大小应大于LVCB的大小,一般用一个AIX逻辑块的大小做偏移量,即4096字节。Oracle数据库会自动跳过前 4k不用,这样保证了lvcb不会被覆盖,但这带来了另一个潜在的问题,当 Oracle的db_block_size大于4k的时候,一个Block可能跨在两个PV/LUN/磁盘上(如果做了条带化,那么将总有数据块跨在两个条带上–其实也还是将跨在不同的 PV/LUN/磁盘上。这样当系统崩溃的时候,很有可能造成大量的IO不完整,一个PV上IO写入,另一边可能未完成,启动Oracle的时候将会看到ORA-1578 错误,这几乎是致命的。
原有的带有偏移量的lv类型就叫做DS_LV。未解决上述问题,AIX引进了一种新的LV类,也就是“Z”类型LV,这种类型的LV通过lslv -L lv_name可以看到它的类型为:DS_LVZ。
零偏移量LV的创建:
1.在Origninal VG中,不论是否使用“-T O”参数,创建出来的lv都是DS_LV类型。
2.在Scalable VG中,不论是否使用“-T O”参数,创建出来的lv都是DS_LVZ类型。
3.在Big VG中,使用“-T O”参数,创建出来的lv都是DS_LVZ类型,而不使用则是DS_LV类型。

由此可见,为了解决alert日志中报告的问题,使用scalable VG或是big VG创建DS_LVZ类型的LV(zero offset)即可解决。

检查lv是不是0偏移的裸设备命令:
1、用oracle账户执行:dbfsize /dev/rlv_test
2、lslv -L lvName
案例:

hz@bank:[/home/oracle]#lslv -L lvdata002
LOGICAL VOLUME:     lvdata002              VOLUME GROUP:   datavg02
LV IDENTIFIER:      00cffde300004c000000012157f880d8.81 PERMISSION:     read/write
VG STATE:           active/complete        LV STATE:       opened/syncd
TYPE:               raw                    WRITE VERIFY:   off
MAX LPs:            512                    PP SIZE:        256 megabyte(s)
COPIES:             2                      SCHED POLICY:   parallel
LPs:                16                     PPs:            32
STALE PPs:          0                      BB POLICY:      relocatable
INTER-POLICY:       minimum                RELOCATABLE:    no
INTRA-POLICY:       middle                 UPPER BOUND:    16
MOUNT POINT:        N/A                    LABEL:          None
MIRROR WRITE CONSISTENCY: off
EACH LP COPY ON A SEPARATE PV ?: no
Serialize IO ?:     NO
DEVICESUBTYPE : DS_LVZ

确认VG的类型,用命令 lsvg 看 MAX PVs 的值—-Normal: 32, Big:128, Scalable:1024 (不一定准确,准确的查询用下面的方法)

lqueryvg -At -g VGID(如00cffde300004c000000012157f8acd7)

10.111.4.1上查看到datavg03的 VG Type:1,0对应的是普通,1对应的是big,2对应的是scale

创建数据库使用的裸设备

mklv -y 'lvxscmxindx004' -T O -w 'n' -s 'n' -r 'n' -t raw datavg 20

遭遇ORA-3927错误的不规范处理操作

客户早上碰到问题,我正好检查下系统,在告警日志中碰到3927错误,大致如下:

Thu Jul 17 09:53:13 2014
ORA-1654: unable to extend index DYMPOPSA.IDX_P17_TB_SP_LOG by 8192 in tablespace               DYMPOPS
Thu Jul 17 09:53:13 2014
ORA-1654: unable to extend index DYMPOPSA.IDX_P17_TB_SP_LOG by 8192 in tablespace               DYMPOPS
Thu Jul 17 09:53:18 2014
ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA2.dbf'
RESIZE 500M
Thu Jul 17 09:53:18 2014
ORA-3297 signalled during: ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA2.dbf'
RESIZE 500M...
Thu Jul 17 09:53:28 2014
ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf'
RESIZE 500M
Thu Jul 17 09:53:28 2014
ORA-3297 signalled during: ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf'
RESIZE 500M...
Thu Jul 17 09:53:45 2014
ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf'
RESIZE 2000M
Thu Jul 17 09:53:45 2014
Completed: ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf'
RESIZE 2000M
Thu Jul 17 09:54:12 2014
ALTER DATABASE
DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf'
RESIZE 3000M

发现在17号表空间DYMPOPS满了,有人尝试通过resize的方式去扩大datafile,从500M开始一直尝试到3000m,终于成功了。其中在小于3000M时候,系统报错如下:

ORA-3297 signalled during: ALTER DATABASE DATAFILE '/u02/oradata/DYMPOPS/DYMPOPSA5.dbf' RESIZE *M...

通过以上可以看出几个问题:

1.首先ORA-3297的错误是告诉你file contains used data beyond requested RESIZE value,意思是实际数据文件使用的数据量要大于你所resize的指定值,所以最好在做这个操作的时候,最好先查一下dba_free_space,所要更改的这个数据文件的一些信息,比如实际使用数据量是多少等;

2.其次日志中显示是在早上9点多时候执行操作,这个点对这个系统来讲是高峰期,在这个时候需要考虑整体的资源使用情况,一般不建议在高峰时间resize datafile,建议通过增加datafile的方式来处理ORA-1654表空间空间不足的情况.

如果要问第二个问题为什么?请考虑下resize datafile的原理以及系统处理高负荷状况下resize datafile可能造成的对系统的影响.

提供一个数据库检测的脚本。适用新数据库环境检测

该脚本适用于新环境数据库的初步检测。

数据库检查:check_db_stats.sql

Rem
Rem check_db_stats_v1.2.sql
Rem modify by ludatou
Rem
Rem only for single instance database
Rem

Rem
Rem This script do health check .
Rem Must run under system or user has dba privilege.
Rem

set pages 0
set lines 1000
set trimspool on
set head off
set feedback off
set echo off
set verify off

Rem get report name based on database name and report date
Rem
col logname noprint new_value log_name
select lower(name)||to_char(sysdate,'yyyymmddhh24mi')||'.txt' logname
from v$database;
spool &log_name


Rem
Rem report header
Rem
prompt
select 'Report produced at '||to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss')  from dual;

prompt
prompt Basic information:
prompt --------------------------------------------------------------------------------

Rem
Rem Check database information
Rem
set head on
set pages 45
col dbid heading "Database|ID" format a11
col name heading "Database|Name"
col open_mode heading  "Open |Mode"
col force_logging heading "Force|Logging" format a7
select
	to_char(dbid,9999999999) dbid
	, name
	, open_mode
	, force_logging
from 	v$database
;

Rem
Rem Check instance information
Rem
col instance_name heading "Instance|Name" format a10
col host_name heading "Host|Name" format a10
col status heading "Instance|Status" format a8
col archiver heading "Archiver|Status" format a8
col up_time heading "Running Time" format a30
select
	host_name
	, instance_name
	, status
	, archiver
	, trunc(sysdate - startup_time) || ' Days '
		|| trunc(mod(sysdate-startup_time, 1) *24) || ' Hours '
		|| trunc(mod((sysdate-startup_time)*24,1)*60) || ' Minutes '
		up_time
from 	v$instance
;


prompt
prompt
prompt Check hit ratio
prompt       These value expected higher than 90%
prompt --------------------------------------------------------------------------------

Rem
Rem Check buffer cache hit ratio
Rem
col pr heading "Physical|Reads" format 999,999,999
col prd heading "Phy_Reads|Direct" format 999,999,999
col prl heading "Phy_Reads|Direct_LOB" format 999,999,999
col bg heading "Block|Gets" format 999,999,999,999
col cg heading "Consistent|Gets" format 999,999,999,999
col ht heading "Buffer|Hit Ratio"
select
	to_char((1-((pr - prd - prl) / (bg + cg - prd - prl))) * 100, '999.9')||'%' ht
	, bg, cg, pr, prd, prl
from
	(select value pr from v$sysstat where name = 'physical reads') pr
	, (select value prd from v$sysstat where name = 'physical reads direct') prd
	, (select value prl from v$sysstat where name = 'physical reads direct (lob)') prl
	, (select value bg from v$sysstat where name = 'db block gets') bg
	, (select value cg from v$sysstat where name = 'consistent gets') cg
;

Rem
Rem check library hit ratio
Rem
col ht heading "Libray|Hit Ratio" format a10
select
	to_char(sum(pinhits) / sum(pins) * 100, 999.9)||'%' ht
from 	v$librarycache
;


prompt
prompt Check session informations
prompt --------------------------------------------------------------------------------

Rem
Rem Check session high water mark
Rem
col sessions_current heading "Sessions|Current" format 999,999,999
col sessions_highwater heading "Sessions|High Water" format 999,999,999
select
	sessions_current
	, sessions_highwater
from 	v$license
;

Rem
Rem Check session wait events
Rem
col username heading "User Name" format a15
col program heading "Program" format a35
col event heading "Wait Event" format a25
prompt
prompt Session wait events, excluding waiting for user's message
prompt _________________

col event format a32
col wait_class format a18
col segment_name format a30
select event, count(*)
  from v$session_wait
 where event not in (select name from v$event_name where wait_class = 'Idle')
  group by event order by 2 desc;

Rem
Rem Check session status
Rem
col status heading "Session|Status"
col nu heading "Number|of Sessions"
compute sum of nu on report
break on report
prompt
prompt Session status
prompt -----------------

select
	status, count(*) nu
from 	v$session
where username is not null
group by status
;
clear break;

Rem
Rem detail information for sessions which idle for more than 4 hours
Rem
col lc heading "Idle Time|(Hours)" format a8
col username format a10 heading "Database|Username"
col machine format a17 heading "Machine"
col osuser format a10 heading "OS|Username"
col prg format a35 heading "Program"
prompt
prompt Idle sessions
prompt -----------------

select
	username, machine, osuser, program prg
	, to_char(trunc(last_call_et/3600, 1), 99999.9) lc
from 	v$session
where last_call_et > 14400
	and username is not null
order by last_call_et desc
;


prompt
prompt Redo log files information
prompt --------------------------------------------------------------------------------

Rem
Rem Online redo logfile information
Rem
col grp format 99 heading "Log Group|Number"
col bytes format 999,999.99 heading "Bytes|(M)"
col status heading "Status"
col member heading "Log File|Members" format a45
break on grp on bytes on status skip 1
prompt
prompt Online redo log file
prompt -----------------

select
	l.group# grp
	, l.bytes/1024/1024 bytes
	, l.status
	, lf.member
from 	v$log l, v$logfile lf
where l.group# = lf.group#
order by 1
;
clear break;

Rem
Rem Online redo logfile switch frequency
Rem
col dt heading "Begin Time (1 hour)" format a25
col cnt heading "Switch times" format 999
prompt
prompt Switch frequency
prompt -----------------

select
	to_char(trunc(first_time, 'hh'), 'yyyy-mm-dd hh24:mi') dt
	, count(*) cnt
from
	v$loghist
where first_time > sysdate - 30
group by trunc(first_time,'hh')
order by 1
;


Rem
Rem Space usage check
Rem
prompt
prompt Tablespace usage
prompt --------------------------------------------------------------------------------

col tbsn heading "Tablespace|Name" format a20
col bytes heading "Current|Size(M)" format 999,999.99
col max_b heading "Maximum|Size(M)" format 999,999.99
col fre_b heading "Free Space|Size(M)" format 999,999.99
col usg heading "Free Space|persentage" format a10
col em heading "Extent|Management" format a10
col ssm heading "Segment|Management" format a10
select
	tb.tbsn
	, bytes
	, fre_b
	, lpad(to_char(nvl(fre_b,0)/bytes*100, 999.99)||'%',10) usg
	, max_b
from
	(select tablespace_name tbsn, sum(bytes)/1024/1024 bytes
		, sum( decode(AUTOEXTENSIBLE,
			'YES', greatest(bytes, maxbytes),
			bytes))/1024/1024 max_b
		from dba_data_files
		group by tablespace_name
	) tb,
	(select tablespace_name tbsn, sum(bytes)/1024/1024 fre_b
		from dba_free_space
		group by tablespace_name
	) fre
where tb.tbsn = fre.tbsn (+)
order by 4
;


prompt
prompt Table usage
prompt -----------------

set serveroutput on
exec dbms_output.enable(100000000);

declare
  type seg is record (
	seg_owner	dba_segments.owner%type,
	seg_name	dba_segments.segment_name%type,
	par_name	dba_segments.PARTITION_NAME%type,
	seg_type	dba_segments.segment_type%type,
	tbs_name	dba_segments.TABLESPACE_NAME%type
	);
  type usg is record (
	t_bck    number,
 	t_byt     number,
 	u_bck   number,
 	u_byt    number,
 	luefi        number,
 	luebi       number,
 	lub number);
  v_seg		seg;
  v_usg		usg;
  v_tbsname	dba_tablespaces.tablespace_name%type;
  v_tbsseg	dba_tablespaces.SEGMENT_SPACE_MANAGEMENT%type;
  cursor c_tbs is
    select
	tablespace_name, SEGMENT_SPACE_MANAGEMENT
    from
	dba_tablespaces
    where
	CONTENTS = 'PERMANENT'
    order by 1
    ;
  cursor c_seg is
    select
	owner, segment_name, PARTITION_NAME, segment_type
    from
	dba_segments
    where
	owner not in ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'WMSYS')
	and tablespace_name = v_tbsname
    order by 1, 2, 3
    ;
begin

  open c_tbs;
  fetch c_tbs into v_tbsname, v_tbsseg;
  while c_tbs%found loop
    dbms_output.put_line('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~');
    dbms_output.put_line('Tablespace:   '||v_tbsname);
    dbms_output.put_line (
	rpad('Owner',15)
	||rpad('Segment Name', 30)
	||rpad('Par', 8)
	||rpad('Seg Type', 10)
	||rpad('Bytes(K)',10)
	||'Used(K)'
	);
    dbms_output.put_line (
	rpad('-',14, '-')||' '
	||rpad('-',29, '-')||' '
	||rpad('-',7, '-')||' '
	||rpad('-', 9, '-')||' '
	||rpad('-',9, '-')||' '
	||' ------------'
	);

    open c_seg;
    fetch c_seg into v_seg.seg_owner, v_seg.seg_name, v_seg.par_name, v_seg.seg_type;
    while c_seg%found loop
      if v_seg.seg_type in ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION',
		'INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION', 'CLUSTER','LOB') then
      dbms_space.unused_space (
	v_seg.seg_owner, v_seg.seg_name, v_seg.seg_type
	, v_usg.t_bck, v_usg.t_byt, v_usg.u_bck, v_usg.u_byt
	, v_usg.luefi, v_usg.luebi, v_usg.lub, v_seg.par_name);
      dbms_output.put_line(rpad(v_seg.seg_owner,15)
	||rpad(v_seg.seg_name, 30)
	||rpad(substr(nvl(v_seg.par_name,'NULL'),1,7), 8)
	||rpad(substr(v_seg.seg_type, 1, 9), 10)
	||to_char(v_usg.t_byt/1024, '9,999,999')
	||to_char((v_usg.t_byt-v_usg.u_byt)/1024, '9,999,999')
	);
      end if;
      fetch c_seg into v_seg.seg_owner, v_seg.seg_name, v_seg.par_name, v_seg.seg_type;
    end loop;
    close c_seg;
    fetch c_tbs into v_tbsname, v_tbsseg;
  end loop;
  close c_tbs;

end;
/



spool off;
exit;

脚本效果:

[ora10g@ludatou ~]$ sqlplus '/as sysdba'

SQL*Plus: Release 10.2.0.4.0 - Production on Mon Jul 28 17:25:00 2014

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @check_db_heath.sql


Report produced at 2014-07-28 17:25:04

Basic information:
-------------------------------------------------------------------------------

Database    Database  Open       Force
ID          Name      Mode       Logging
----------- --------- ---------- -------
 2580936880 LU10G     READ WRITE NO

Host       Instance   Instance Archiver
Name       Name       Status   Status   Running Time
---------- ---------- -------- -------- ------------------------------
ludatou    lu10g      OPEN     STOPPED  1 Days 18 Hours 9 Minutes


Check hit ratio
These value expected higher than 90%
-------------------------------------------------------------------------------

Buffer             Block       Consistent     Physical    Phy_Reads    Phy_Reads
Hit Rat             Gets             Gets        Reads       Direct   Direct_LOB
------- ---------------- ---------------- ------------ ------------ ------------
  98.8%          221,523        1,181,248       16,972           34            0

Libray
Hit Ratio
----------
  95.3%

Check session informations
-------------------------------------------------------------------------------

    Sessions     Sessions
     Current   High Water
------------ ------------
           1           10


Session status
----------------

Session       Number
Status   of Sessions
-------- -----------
ACTIVE             1
         -----------
sum                1

Idle sessions
----------------

Redo log files information
-------------------------------------------------------------------------------

Online redo log file
----------------

Log Group       Bytes          Log File
   Number         (M) Status   Members
--------- ----------- -------- ---------------------------------------------
        1       50.00 CURRENT  /oradata/lu10g/redo01.log

        2       50.00 INACTIVE /oradata/lu10g/redo02.log

        3       50.00 INACTIVE /oradata/lu10g/redo03.log


Switch frequency
----------------

Begin Time (1 hour)       Switch times
------------------------- ------------
2014-07-24 13:00                     2
2014-07-26 23:00                     1

Tablespace usage
-------------------------------------------------------------------------------

Tablespace               Current  Free Space Free Space     Maximum
Name                     Size(M)     Size(M) persentage     Size(M)
-------------------- ----------- ----------- ---------- -----------
SYSTEM                    480.00        4.25       .89%   32,767.98
SYSAUX                    260.00        9.38      3.61%   32,767.98
UNDOTBS1                   25.00       21.88     87.50%   32,767.98
USERS                       5.00        4.56     91.25%   32,767.98

Table usage
----------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tablespace:   SYSAUX
Owner          Segment Name                  Par     Seg Type  Bytes(K)  Used(K)
-------------- ----------------------------- ------- --------- ---------  ------------
CTXSYS         DR$CLASS                      NULL    TABLE             64        64
CTXSYS         DR$INDEX                      NULL    TABLE             64        64
CTXSYS         DR$INDEX_ERROR                NULL    TABLE             64        24
CTXSYS         DR$INDEX_PARTITION            NULL    TABLE             64        24
CTXSYS         DR$INDEX_SET                  NULL    TABLE             64        64
CTXSYS         DR$INDEX_SET_INDEX            NULL    TABLE             64        24
CTXSYS         DR$INDEX_VALUE                NULL    TABLE             64        64
CTXSYS         DR$NUMBER_SEQUENCE            NULL    TABLE             64        64
CTXSYS         DR$NVTAB                      NULL    TABLE             64        24
CTXSYS         DR$OBJECT                     NULL    TABLE             64        64
CTXSYS         DR$OBJECT_ATTRIBUTE           NULL    TABLE             64        64
CTXSYS         DR$OBJECT_ATTRIBUTE_LOV       NULL    TABLE             64        64
CTXSYS         DR$POLICY_TAB                 NULL    TABLE             64        24
CTXSYS         DR$PREFERENCE                 NULL    TABLE             64        64
CTXSYS         DR$PREFERENCE_VALUE           NULL    TABLE             64        64
CTXSYS         DR$SECTION                    NULL    TABLE             64        24
CTXSYS         DR$SECTION_GROUP              NULL    TABLE             64        64
CTXSYS         DR$STATS                      NULL    TABLE             64        24
CTXSYS         DR$STOPLIST                   NULL    TABLE             64        64
CTXSYS         DR$SUB_LEXER                  NULL    TABLE             64        24
CTXSYS         DR$THS                        NULL    TABLE             64        24
CTXSYS         DR$THS_BT                     NULL    TABLE             64        24
CTXSYS         DR$THS_PHRASE                 NULL    TABLE             64        24
CTXSYS         DR$WAITING                    NULL    TABLE             64        24
CTXSYS         DRC$DEL_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$IDX_COLSPEC               NULL    INDEX             64        32
CTXSYS         DRC$IDX_COLUMN                NULL    INDEX             64        32
CTXSYS         DRC$IDX_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$IXO_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$IXP_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$IXS_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$IXS_NAME                  NULL    INDEX             64        32
CTXSYS         DRC$IXX_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$OAT_KEY                   NULL    INDEX             64        32
CTXSYS         DRC$OAT_NAME                  NULL    INDEX             64        32
...............

遭遇Listener hang 报错TNS-12537

数据库版本10201
客户端报错TNS-12537
具体信息参考如下官方说法:

APPLIES TO:

Oracle Net Services - Version: 10.2.0.4 to 11.2.0.1 - Release: 10.2 to 11.2
Information in this document applies to any platform.
SYMPTOMS

TNS listener hangs every 49.7 days. Parameter RATE_LIMIT is set in the listener.ora file.
Level 16 listener trace for the hang shows the following functions:
[000001 17-MAY-2011 23:30:42:953] nstoSetupTimeout: entry
[000001 17-MAY-2011 23:30:42:953] nstoSetupTimeout: MTO enabled for ctx=0x1002bcaf0, val=-47967511(millisecs)
[000001 17-MAY-2011 23:30:42:953] nstoUpdateActive: entry
[000001 17-MAY-2011 23:30:42:953] nstoUpdateActive: Active timeout is 5 (see nstotyp)
[000001 17-MAY-2011 23:30:42:953] nstoControlMTO: MTO enabled for ctx=0x1002bcaf0, val=-47967511(millisecs)
[000001 17-MAY-2011 23:30:42:953] nstoControlMTO: exit (0)
[000001 17-MAY-2011 23:30:42:954] nsglhc: At Connection Rate Limit. Muted Request.
[000001 17-MAY-2011 23:30:42:954] nsglhe: exit
[000001 17-MAY-2011 23:30:42:954] nsevwait: entry
[000001 17-MAY-2011 23:30:42:954] nsevwait: 4 registered connection(s)
[000001 17-MAY-2011 23:30:42:954] nsevwait: 0 pre-posted event(s)
[000001 17-MAY-2011 23:30:42:954] nsevwait: waiting for transport event (1 thru 5)...

When the listener is hung, client reports error code ORA-12537

CAUSE

The cause of this problem has been identified in Bug:8529537 All New Connections Are refused By ORA-12547 After TNS-01158 in Listener.log. It is caused by that is negative figure (buffer overflow) for inbound_connect_timeout function call.
SOLUTION

Issue is fixed in Patch Set 11.2.0.2 and future release 12.1
One off fixes are available via Patch:8529537
RATE_LIMIT parameter can be disabled as a workaround.

最终去掉RATE_LIMIT参数重启监听解决

Tuxedo IPC 优化

[ID 1532550.1]

IPC 技术简介

IPC 被划分为三组操作系统级可调参数,分别为“信号量”、“消息”和“共享内存”。在深入研究 IPC 优化之前,我们首先来看一看上述各个独立功能的性质。

 

信号量

信号量是一种可以在操作系统级别设置的标志,用于提供一般的建议锁定机制(与文件锁相似)。信号量将某个资源锁定后,操作系统中的其他程序将无法访问该资源。您可以使用信号量来控制对文件、共享内存或任何其他需要限制访问的资源的访问权限。

想象一下那些争夺同一资源(例如某个文件)的进程所面临的问题。(此处的资源可能是任何东西,例如磁盘分区、共享内存段或打印机)。如果一个进程正在修改某个文件,而与此同时,另一个进程正在读取该文件,则后者可能会看到半新半旧的信息。如果两个进程同时修改该文件的内容,则很可能会得到一堆乱码。

为了防止此类情况发生,通常会使用一个信号量来保护共享资源。信号量初始化为“1”,表示资源可用。进程在访问资源之前,会首先检查信号量的值。如果值为 1,进程会立即将该值降为 0(表明该资源不再处于空闲状态),然后在确知其他进程无法执行相同操作的情况下对该资源执行所有必要的操作。如果信号量为 0,则进程必须先等待该值恢复到 1,然后再检查或修改该资源。在进程完成对资源的访问之后,它需要将信号量返回到 1,从而允许其他进程继续进行操作。

T信号量的基本功能在于,您可以对它进行设置、检查(以查看是否已设置),或者您可以等到信号量被清除,然后再进行设置。

有关信号量的一个复杂之处在于,在对信号量操作进行编程时,您请求的不是单个信号量,而是一个信号量组。您可以请求只包含一个信号量的信号量组,但 Tuxedo 不会这么做,因此,它只需创建一个信号量组即可获取大量信号量。

参与 Tuxedo 应用程序的每个进程都需要信号量。应用程序会在启动时检查操作系统中已配置的信号量的数量。如果已配置的数量不够多,启动将失败。


消息队列和消息

消息队列和消息为操作系统中的不同进程提供了一种用于传输消息并由此进行通信的机制。消息队列可在进程之间共享,并且,由一个进程放入队列的消息可以被其他进程提取。

Oracle Tuxedo 系统使用 UNIX 系统消息和消息队列进行客户端/服务器通信。此类消息的示例包括服务请求、服务回复、会话消息、未经请求的通知消息、管理消息和事务控制消息。

每个 MSSQ 组(Multiple Servers, Single Queue)的多个服务器程序和单个服务器程序都相应地有一个用于接收请求的消息队列。每个客户端本身也都相应地拥有用于接收回复的消息队列。指定 REPLYQ 参数的服务器程序则会拥有各自独立的回复队列。

调整内核消息参数对于适当优化应用程序而言至关重要。如果值不恰当,可能会造成无法启动或性能严重下降。

共享内存

顾名思义,“共享内存”是指操作系统中两个或多个进程之间共享的内存。通常,操作系统在执行某个进程时,会为该进程分配单独的内存空间,因而,所分配的内存范围只能由该进程使用。各个进程在自己的内存空间内运行时,它们之间互相影响的可能性就大大降低了。当这些进程开始通过共享内存的使用共享内存空间时,某个进程破坏共享内存的可能性会大大增加。

在 Tuxedo 环境中,共享内存用于 Bulletin Board 以及工作站侦听器(Workstation Listener,WSL) 进程的控制表。应用程序可能也会将共享内存用于其他用途。

Tuxedo 对 IPC 资源的使用

如前所述,Tuxedo 会大量使用来自操作系统的 IPC 资源。

附加到 Tuxedo Bulletin Board 的每个进程或线程都需要 UNIX 信号量。其中包括 native 客户端、服务器、WSH、WSL、BBL、TMS、Bridge、Domain 网关以及所有其他系统进程,例如 event broker 或 /Q 进程。

在Tuxedo启动之前,UNIX会预先分配信号量。在信号量过少的情况下,Tuxedo 系统会无法正常启动且会报告错误,表明信号量缺乏。因此,通常很容易确定操作系统的信号量是否过少。

消息队列的不同之处在于,它们由 Tuxedo 动态分配。每个 native 客户端和 WSH 都需要回复消息队列。每个服务器都需要请求队列,但多个服务器可以通过 RQADDR 参数共享请求队列(MSSQ 集)。多个服务器还可以拥有回复队列;如果设置了 REPLYQ=Y 开关,每个服务器都可以获得回复队列,即使是在 MSSQ 集中,也是如此。

此外,即使没有明确的规定,系统服务器也常常会分配回复队列,例如 TMS 服务器和 Domain 网关。由于消息队列是动态分配的(尤其是在动态调整 Tuxedo Server 数量的情况下),因此很难事先预测应用程序是否会出现消息队列问题。

共享内容由 Bulletin Board 以及其他子系统(例如 /WS、/Q、/Domain)使用。Bulletin Board 的大小由不同的 UBBCONFIG 参数控制,例如 MAXACCESSERS、MAXGTT、MAXSERVERS、MAXSERVICES。事实上,UBBCONFIG 中以 MAX 开头的几乎所有属性都会影响 Bulletin Board 的最终大小。

定义 IPC 限制

出于快速处理的目的,大多数 IPC 和共享内存 Bulletin Board 表都是静态分配的,因此对其进行正确优化至关重要。如果其大小过大,内存和 IPC 资源会出现过度消耗;如果其大小过小,便很容易超出限制,从而导致进程失败。

UBBconfig 文件下 RESOURCES 节中的以下可优化参数与 IPC 大小相关:

  • MAXACCESSERS – 一个节点上允许附加到 TUXEDO 系统的所有进程的最大数量。它不是所有进程的总和,而是进程最多的节点上的进程数量。默认值为 50。(您可以在每个计算机上重写 MACHINES 节中的 MAXACCESSERS。)
  • MAXSERVERS – 应用程序中服务器进程的最大数量,包括所有管理服务器(例如 BBL 和 TMS)。它是所有节点上服务器进程的总和。默认值为 50。
  • MAXSERVICES – 应用程序中可以发布的不同服务的最大数量。它是系统中所有服务的总和。默认值为 100。(设置此值时,请将默认值作为针对系统资源保留的数量。)

增加 MAXACCESSERS 的代价是,每增加一个访问器,节点就需要增加一个信号量。除了由 MAXACCESSERS 值添加的信号量开销外,系统进程也存在少量固定信号量开销。增加 MAXSERVERS 和 MAXSERVICES 的代价是,需要为各个服务器、服务和客户端项分别保留少量的共享内存。设置这些参数的目的是为应用程序的未来扩展做准备。尤其要仔细检查 MAXACCESSERS。

此外,还有三个参数会影响 IPC 大小,即 MAXGTT、MAXINTERFACES 和 MAXCONV:

  • MAXGTT – 指定在任何时候均受 Tuxedo 应用程序支持的全局事务的最大数量。修改此值将改变共享内存开销。
  • MAXINTERFACES – 指定此 Tuxedo 应用程序 CORBA 接口的最大数量。默认值为 100。修改此值将改变信号量和共享内存开销。
  • MAXCONV – 指定可在计算机上同时进行的会话的最大数量。MAXCONV 的值必须大于 0 且小于 32,768。在具有会话服务器的计算机上,默认值为 10,除此以外则为 1。修改此值将改变共享内存开销。

请注意,如果要评估修改这些参数所产生的影响,其计算过程非常复杂。最好使用 tmloadcf –c 或 tmboot –c 作为替代来获取 IPC 大小信息。

 

了解 Tuxedo IPC

首次尝试确定 IPC 的正确设置时,第一步只需在您尝试为其配置 IPC 资源的系统环境中对 ubbconfig 文件运行命令

 

tmloadcf –c [ubbconfig file]

 

即可。

运行此命令将生成类似以下内容的输出:

 

Ipc sizing (minimum /T values only) …

Fixed Minimums Per Processor

SHMMIN: 1
SHMALL: 1
SEMMAP: SEMMNI

Variable Minimums Per Processor

SEMUME,           A                             SHMMAX
SEMMNU,           *                               *
Node                    SEMMNS  SEMMSL  SEMMSL  SEMMNI  MSGMNI  MSGMAP  SHMSEG
——                  ——  ——  ——  ——  ——  ——  ——
PRODUCTIONMACH             105      13     100   A + 1      31      62    173K

where 1 <= A <= 8.

The number of expected application clients per processor should be added to each MSGMNI value.

 

在上表中,A 表示值介于 1 和 8 之间的变量。您可以用“A * SEMMS”列下的值(在本例中为 100)除 SEMMSL 的值(在本例中为 13),来确定 A 的值(在本例中,100/13 = 7.69 或四舍五入到 8)。得出 A 的值后,您就可以确定 SEMMNI,它等于 A + 1,在本例中即为 9。

列出的这些值是操作系统中各个属性可以设置的最小值。遗憾的是,tmloadcf –c 方法未涵盖所有对环境的 IPC 设置,且所示值只表示实际情况中运行系统环境所需的最小值。

一种更为完整的方法是,独立调整各个 IPC 资源的大小。这种做法需要统一的方法来执行。附加的 Excel 电子表格(请参阅附件:Tuxedo_IPC_Calculator.xls)中概述了下列方法,该方法可帮助您确定正确的值。

在开始调整 IPC 资源的大小之前,必须先了解和记录以下项目。下面的表格中有一栏是空白的,您可以使用该表格来帮助调整 IPC 的大小。

 

属性 描述 您的值
Servers 此节点上配置的 Tuxedo Server 的总数量。该节点是运行 Tuxedo 的物理计算机,因此这个数量不应包括在其他计算机上运行的服务器程序数量。
Servers with ReplyQ 已配置 REPLYQ=Y选项的 Tuxedo Server。
Servers in MSSQ 在MSSQ组中配置的服务器程序的总数量。
Total MSSQ Sets 实际的MSSQ组的总数量(相对于一组服务器程序的数量)。
Native Clients 环境中 native 客户端的数量(不是通过工作站处理器连接的客户端)。
Largest Message Size 系统将传输的最大消息大小。
Average Message Size 系统正在传输的消息的平均大小。
Message Queue Size 系统中 IPC 消息队列的大小,此值由在操作系统中设置的 MSGMNB 属性确定。
Total Inflight Messages 在任何时候系统中可能会发行的消息总数(如果您不知道具体的值,请将此属性设置得高一点)。
Total /Q Queuespaces 系统中 /Q 队列空间总数。
MAXWSCLIENTS 可与此计算机连接的工作站客户端的最大数量。此属性在 UBBConfig 中设置。
MAXACCESORS 按照 UBBConfig 文件 *RESOURCES 节中的内容进行设置。

 

上述属性需要在 UNIX 或 Windows 环境中进行配置。如果是在 UNIX 中配置这些属性,请与当地的系统管理员联系,以获取有关设置实施的帮助。如果是在 Windows 中进行更改,则请双击 Windows 控制面板中的“Oracle Tuxedo”(或“BEA Administration(BEA 管理)”)图标。有关如何通过 Windows 工具使用和配置 IPC 资源的详细信息,请参考如下文档:

http://download.oracle.com/docs/cd/E13161_01/tuxedo/docs10gr3/nt/ntadmin.html#wp418757

现在,我们来检查一下每个可能的 IPC 配置选项及其用途和正确的值。请注意,在查看下面的结构和公式时,默认值设置所示的是 Oracle 或操作系统供应商通常会推荐的设置。显然,每个供应商可能会针对其自身的操作系统推荐不同的值,但是您可以将这些值用作在整个操作系统中进行设置的参考值(请经常查看的操作系统手册,以确认系统环境中的设置和范围)。最小值设置指定可使用哪个公式来确定此属性可以设置的最小值,以使 Tuxedo 系统正常运行。最小值只应作为指示值使用,若将属性的值设置为最小值,在以后其他应用程序需要操作系统中的 IPC 资源或者 Tuxedo 系统发生扩展时,很可能会引起某些问题。

因此,正确的值通常介于最小值和所提供的默认值之间。如果无法肯定,请使用接近默认值的值,因为默认值提供了可伸缩性空间,同时也为平台上的其他 Tuxedo 实例提供了空间。请注意,IPC 设置会在操作系统中分配真实的内存。如果不需要使用大量资源,请不要在操作系统中分配过多的资源,因为这样会导致性能问题。

Oracle 针对每个平台提供了建议的 IPC 设置。这些建议的设置被称为“平台数据表”,Tuxedo 10gR3 的建议设置可通过以下链接找到:

http://download.oracle.com/docs/cd/E13161_01/tuxedo/docs10gr3/install/inspds.html

SEMMNS

 

完整名称: 信号量的最大数量
用途: Semmns 定义系统范围内可以分配给用户的单个 IPC 信号量的最大数量。
默认值: 1024
最小值设置: 至少设置为 MAXACCESSERS – MAXWSCLIENTS + 13

 

SEMMNI

 

完整名称: 信号量组的最大数量
用途: Semmni 指定可以同时存在于系统中的 IPC 信号量组的最大数量。
默认值: 1024
最小值设置: 使用命令 tmloadcf –c 确定此属性的适当值。

 

SEMMSL

 

完整名称: 每个标识符可具有的 IPC 信号量的最大数量
用途: Semmsl 指定每个信号量标识符可具有的单个 IPC 信号量的最大数量。
默认值: 2048
最小值设置: SEMMNS / SEMMNI

 

SEMMAP

 

完整名称: 信号量资源图的最大大小
用途: Semmap 指定用于在共享内存中分配新 IPC 信号量的可用空间资源图的大小。
默认值: 1024
最小值设置: SEMMNI + 2


SEMMNU

 

完整名称: 信号量 undo 结构的最大数量
用途: Semmnu 指定进程的 IPC undo 结构的最大数量
默认值: 1024
最小值设置: 与 SEMMNS 相同

 

SEMUME

 

完整名称: 挂起的 undo 操作的最大数量
用途: Semume 指定某给定进程可以在其上挂起 undo 操作的 IPC 信号量的最大数量。
默认值: 1024
最小值设置: 与 SEMMNS 相同


SHMMAX

 

完整名称: 最大共享内存大小
用途: Shmmax 指定系统范围内最大可允许的共享内存段大小。
默认值: 4194304 (4MB)
最小值设置: BBL 的大小很难确定,但 SHMMAX 必须大于 BBL 的大小。我们建议对该值保留系统默认值(通常介于 4MB 和 64MB 之间)。请注意,此设置仅针对 Tuxedo 所使用的 BBL。如果曾有其他应用程序在计算机上运行且使用了共享内存,则还必须根据该应用程序的共享内存使用情况对这一数字进行验证。


SHMSEG

 

完整名称: 每个进程的共享内存段数量
用途: Shmseg 定义每个进程的共享内存段的最大数量
默认值: 500
最小值设置: 对于繁忙的应用程序,必须至少设置为 32 到 64。任何小于 SHMMNI 的值均有效,稍高一点也可以接受。


SHMMNI

 

完整名称: 共享内存段的数量
用途: Shmmni 定义系统中共享内存段标识符的数量
默认值: 100 至 400,具体取决于您的系统环境
最小值设置: Tuxedo 要求 BLL 和每个 /Q 队列空间都有共享内存段。系统环境中的其他应用程序可能也需要共享内存段。通常情况下,100 即可,但在某些情况下可能需要更高的值。再次提醒,这一设置具体取决于运行 Tuxedo 应用程序的同一计算机上运行的其他应用程序,且应当根据具体情况进行处理。


SHMMIN

 

完整名称: 共享内存段的最小大小
用途: Shmmin 指定系统环境中共享内存段的最小大小。
默认值: 1
最小值设置: 设置为 1,即允许系统为共享内存段分配最低 1 字节的空间。


MSGMNI

 

完整名称: 消息标识符的最大数量
用途:

Msgmni 指定计算机上允许的系统范围内的消息队列的最大数量。

默认值: 256 至 512,具体取决于系统环境
最小值设置: MAXACCESSORS + (Servers with ReplyQ – Servers in MSSQ) + MSSQ组总数 + 7


MSGMAP

 

完整名称: 消息资源图大小
用途: Msgmap 指定 IPC 消息空间资源图中的条目数量
默认值: 8130
最小值设置: MSGTQL + 2 或 3。此设置取决于具体的平台。有关更多信息,请参阅您的平台数据表。


MSGMAX

 

完整名称: 消息最大大小
用途: Msgmax 定义最大的 IPC 消息大小(以字节为单位)
默认值: 65536
最小值设置: MSGMNB 的 75%


MSGMNB

 

完整名称: 消息队列的最大字节数
用途: Msgmnb 定义单个 IPC 消息队列上的最大字节数
默认值: 65536
最小值设置: 65536,您可以将它设置得更低,但是标准的 Tuxedo 队列大小是 65536 (64K),诸如 128K 和 256K 之类的值也是可以的。但请注意,每个拥有队列的 Tuxedo Server 在开始构建队列时都会尽数使用这些内存。


MSGSSZ

 

完整名称: 消息段大小
用途: Msgssz 指定 IPC 消息段中的字节数
默认值: 64
最小值设置: 通常设置为 8、16、32 或 64(消息段大小以字节为单位)

 

MSGTQL

 

完整名称: 消息总数
用途: Msgtql 定义在任何时候系统中的 IPC 消息的最大数量
默认值: 1024 至 8128,具体取决于您的系统环境
最小值设置: 在任何时候 Tuxedo 系统中可能会发行的消息的最大数量。请务必将此值设置得足够大,以便能够处理所有发行的消息。如果该值过小,系统性能可能会降低。


MSGSEG

 

完整名称: 消息段
用途: Msgseg 定义系统中的 IPC 消息段数量
默认值: 介于 8192 和 32767 之间,具体取决于您的系统环境
最小值设置: 设置为 (Average Message Size * Maximum Message Headers)/MSGSSZ


IPC 命令

下面列出了一些有用的 IPC 命令,可用于查看和处理您的 Tuxedo 应用程序的 IPC 数据。

ipcs

ipcs 实用程序用于输出活动的进程间进行通信所使用的IPC资源相关信息。显示的信息由提供的选项控制。如果没有这些选项,有关当前在系统中处于活动状态的消息队列、共享内存和信号量的信息会以短格式形式输出。

一些较为有用的选项包括:

 

选项 描述
-b 输出有关最大允许大小的信息:消息队列上消息的最大字节数、共享内存段的大小以及每个信号量组中的信号量数量。
-o 输出有关未决使用情况的信息:队列上的消息数量、消息队列上消息的字节总数以及附加到共享内存段的进程数量。
-q 输出有关活动消息队列的信息。
-s 输出有关活动信号量的信息。
-m 输出有关活动共享内存段的信息。


ipcs示例:ipcs -boq

下面给出了 ipcs –boq 命令的输出内容。–b 显示队列上的消息的最大字节数量,-o 显示队列上的消息数量,–q 指定我们仅显示有关队列的信息(即,不显示有关共享内存或信号量的信息)。

 

IPCS status from BEA_segV8.1 as of Wed Jun 22 10:41:54 2005
>T     ID     KEY        MODE       OWNER    GROUP CBYTES  QNUM QBYTES
Message Queues:
q    513 0x0000bea2 -Rrw-rw-rw-        0        0      0     0  65536
q    770 0x00000000 -Rrw-rw-rw-        0        0      0     0  65536
q    515 0x00000000 -Rrw-rw-rw-        0        0      0     0  65536
q      4 0x00000000 –rw-rw-rw-        0        0  11396    37  65536

 

在上述输出内容中,我们可以看到 ID 为 4 的队列有 37 条消息 (QNUM),队列上有 11396 字节 (CBYTES)。

我们还可以在 MODE 列中看到队列的 UNIX 风格权限,而 OWNER 和 GROUP 列表示了队列所有者和所在的组。所有三类 IPC(信号量、队列和共享内存)都有这些列。

有关 ipcs 命令的更多信息,请参阅 UNIX 使用手册。

ipcrm

ipcrm 用于删除一个或多个消息队列、信号量或共享内存段。在出现灾难性的 Tuxedo 系统故障而不得不 kill Tuxedo 进程之后,通常会使用此命令。在这种情况下,Tuxedo Server 无法释放其 IPC 资源,我们需要手动进行操作。

使用 ipcs 命令输出 ID 列中的 ID,我们可以确定要清除的单个 IPC 资源。相关的选项包括:

 

选项 描述
-m <ID> 删除 ID 为 <ID> 的共享内存段。
-s <ID> 删除 ID 为 <ID> 的信号量。
-q <ID> 删除 ID 为 <ID> 的消息队列。

 

因此,假设 ipcs –boq 命令的输出如下:

 

IPCS status from BEA_segV8.1 as of Wed Jun 22 10:41:54 2005
T     ID     KEY        MODE       OWNER    GROUP CBYTES  QNUM QBYTES
Message Queues:
q    513 0x0000bea2 -Rrw-rw-rw-        0        0      0     0  65536
q    770 0x00000000 -Rrw-rw-rw-        0        0      0     0  65536
q    515 0x00000000 -Rrw-rw-rw-        0        0      0     0  65536
q      4 0x00000000 –rw-rw-rw-        0        0  11396    37  65536

 

我们可以使用以下命令删除所有消息队列:

 

Ipcrm –q 513 –q 770 –q 515 –q 4

 

此命令将删除 ID 为 513、770、515 和 4 的队列。–m 和 –s 选项的用法与 –q 完全相同。


tmipcrm

tmipcrm 用于清除由 Tuxedo ATMI 应用程序分配的 IPC 资源,例如共享内存、消息队列和信号量。此命令通常在出现异常错误情况(例如故障关机)之后运行。在正常情况下,Tuxedo ATMI 系统会在关闭时清除所有已分配的 IPC 资源。将被删除的 IPC 资源包括那些由核心 Tuxedo ATMI 系统和工作站组件所使用的资源。

tmipcrm 只在本地服务器上运作;它不清除处于 Tuxedo 配置中的远程计算机上的 IPC 资源。您必须将 TUXCONFIG 文件的名称指定为 TUXCONFIG 环境变量的值,或在命令行上指定该名称。TUXCONFIG 文件必须存在且必须是可读的。

只有管理员或其他拥有适当权限的人才能成功运行此命令。此命令假设它可以附加到 Bulletin Board (BB) 的共享内存段,并尝试删除存储在 Bulletin Board 中并从中引用的 IPC 资源。此类删除尝试可能会因系统上的其他情况而失败。如果检测到失败,将会进行报告。

支持以下选项:

 

选项 描述
-y 对所有提示均给出肯定回答。
-n 不删除 IPC 资源,而是在标准输出中显示 IPC 资源列表。

 

tmipcrm的输出示例:

 

$ tmipcrm /home/user/apps/tuxconfig
Looking for IPC resources in TUXCONFIG file /home/user/apps/tuxconfig
The following IPC resources were found:
Message Queues:
0x2345
0x3456

Semaphores:
0x34567
0x45678

Shared Memory:
0x45678
0x56789
Remove these IPC resources (y/n)?: y
Removing IPC resources  done!


bbsread

为了检查此配置的本地 IPC 资源,启动了 tmadmin 会话并运行了 bbsread 命令。bbsread 的输出如下所示:

bbsread Output

 

SITE1> bbsread
IPC resources for the bulletin board on machine SITE1:
SHARED MEMORY:          Key: 0x1013c38
SEGMENT 0:
ID: 15730
Size: 36924
Attached processes: 12
Last attach/detach by: 4181

This semaphore is the system semaphore
SEMAPHORE:              Key: 0x1013c38
Id: 15666
|  semaphore |  current |   last   | # waiting |
|   number   |  status  | accesser | processes |
|———————————————-|
|     0      |   free   |   4181   |     0     |
|———————————————-|
This semaphore set is part of the user-level semaphore
SEMAPHORE:              Key: IPC_PRIVATE
Id: 11572
|  semaphore |  current |   last   | # waiting |
|   number   |  status  | accesser | processes |
|———————————————-|
|      0     |  locked  |   4181   |     0     |
|      1     |  locked  |   4181   |     0     |
|      2     |  locked  |   4181   |     0     |
|      3     |  locked  |   4181   |     0     |
|      4     |  locked  |   4181   |     0     |
|      5     |  locked  |   4181   |     0     |
|      6     |  locked  |   4181   |     0     |
|      7     |  locked  |   4181   |     0     |
|      8     |  locked  |   4181   |     0     |
|      9     |  locked  |   4181   |     0     |
|     10     |  locked  |   4181   |     0     |
|     11     |  locked  |   4181   |     0     |
|     12     |  locked  |   4181   |     0     |
|     13     |  locked  |   4181   |     0     |
|————|———-|———-|———–|

 

bbsread 命令的输出分为两个部分,即共享内存和信号量。

共享内存

共享内存输出分为若干个段,每个段都拥有自己的 ID。在所有 IPC 资源中,段 ID 是唯一的,它也是您在运行 ipcs –m 命令时会看到的 ID。

对于共享内存的每个段,系统会显示以下一些项目:

 

项目 描述
ID IPC 资源的唯一 ID
Size 共享内存段的大小(以字节为单位)
Attached processes 显示附加到共享内存段的活动进程数量。这些进程包括 BBL、WSH 进程、Tuxedo Server 等。
Last attach/detach by 显示最后一个连接到共享内存段的进程的进程 ID。


信号量

请务必注意,ipcs 命令的信号量输出的 ID 是信号量组的 ID,并且这些信号量组所包含的是实际的信号量。bbsread 命令的输出显示系统中信号量的某个部分。这些信号量按其信号量组 ID 进行分组,该 ID 是由 ipcs 命令显示的 ID,也是传递到 ipcrm 命令的 –s 选项的 ID。

每个信号量组的所有信号量都会显示在输出中,表示这些信号量是处于锁定状态还是空闲状态(当前状态)、最后使用信号量的进程 ID(最后一个访问器)以及正在等待使用该信号量的进程数量(等待进程数)。

从这个输出中,我们可以确定 Tuxedo 域内的信号量活动状态。

IPC 的常见故障排查

如何在应用程序无法正常关闭时使用 IPC 工具

通过 tmshutdown 命令正常关闭 Tuxedo 应用程序时,所有 IPC 资源都会从系统中删除。但是在某些情况下,应用程序可能无法正常关闭,一些偏离的 IPC 资源可能会保留在系统中。如果发生此类情况,您可能无法重新启动该应用程序。

解决此问题的一个方法是,使用可调用系统 ipcs 命令的脚本删除 IPC 资源,并扫描特定用户帐户所有的全部 IPC 资源。但是,此方法很难辨别不同的 IPC 资源集;一些资源可能属于 Tuxedo 系统,一些可能属于特定的 Tuxedo 应用程序,而另外一些可能属于与 Tuxedo 系统毫不相关的应用程序。能够辨别这些资源集非常重要;误删 IPC 资源可能会严重损坏应用程序。

通过 Tuxedo IPC 工具(即 tmipcrm 命令),您可以删除活动应用程序中由 Tuxedo 系统分配的 IPC 资源(也就是说,此操作仅适用于核心 Tuxedo 和工作站组件)。

用于删除 IPC 资源的 tmipcrm 命令位于 TUXDIR/bin 中。此命令可读取二进制配置文件 (TUXCONFIG),并附加到使用此文件中所含信息的 Bulletin Board。tmipcrm 只在本地服务器计算机上运作;它不清除处于 Tuxedo 配置中的远程计算机上的 IPC 资源。

若要运行此命令,请在命令行上输入该命令,如下所示:

 

tmipcrm [-y] [-n] [TUXCONFIG_file]

 

IPC 工具会列出由 Tuxedo 系统使用的所有 IPC 资源,并给出删除选项。

注意:只有在命令行中正确设置了 TUXCONFIG 环境变量或指定了相应的 TUXCONFIG 文件的情况下,此命令才起作用。