[20241212]Oracle 多线程测试.txt

[20241212]Oracle 多线程测试.txt

--//oracle从12c版本开始支持多线程,各种原因从来没有测试,好像最近很少有人提及,或许使用oracle的人越来越少,或者许多人根
--//本没有这样的需求,印象最深的是启用后必须使用口令登录,即使是sys用户.
--//自己还是看一些文章,测试看看。

1.环境:
SYS@book> @ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

SYS@book> @hidez threaded_execution
SYS@book> @ pr
==============================
NUM                           : 990
N_HEX                         :   3DE
NAME                          : threaded_execution
DESCRIPTION                   : Threaded Execution Mode
DEFAULT_VALUE                 : TRUE
SESSION_VALUE                 : FALSE
SYSTEM_VALUE                  : FALSE
ISSES_MODIFIABLE              : FALSE
ISSYS_MODIFIABLE              : FALSE
PL/SQL procedure successfully completed.
--//缺省FALSE。

SYS@book> alter system set threaded_execution=true scope=spfile;
System altered.

$ cat pp.txt
SELECT s.username, s.sid, s.serial#, s.con_id, p.spid, p.sosid, p.stid,
       p.execution_type
  FROM v$session s, v$process p
 WHERE s.sid   = &&1
   AND s.paddr = p.addr;

2.开始测试:
SYS@book> shutdown immediate ;
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@book> startup
ERROR:
ORA-01017: invalid username/password; logon denied
ORA-01017: invalid username/password; logon denied

--//不必担心,需要使用sys加口令登录。

$ rlsql -l sys/bookbook as sysdba
SQL*Plus: Release 21.0.0.0.0 - Production on Thu Dec 12 16:10:36 2024
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle.  All rights reserved.
Connected to:
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0

SYS@book> select open_mode from v$database;
select open_mode from v$database
*
ERROR at line 1:
ORA-01507: database not mounted

--//仅仅启动到nomount。

SYS@book> alter database mount ;
Database altered.

SYS@book> alter database open ;
Database altered.

$ ps -ef | egrep "UI[D]|ora[_]"
UID        PID  PPID  C STIME TTY          TIME CMD
oracle    3799     1  0 16:08 ?        00:00:00 ora_pmon_book
oracle    3803     1  0 16:08 ?        00:00:01 ora_u002_book
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
oracle    3808     1  0 16:08 ?        00:00:00 ora_psp0_book
oracle    3812     1  0 16:08 ?        00:00:01 ora_vktm_book
oracle    3825     1  0 16:08 ?        00:00:00 ora_gen1_book
oracle    3831     1  4 16:08 ?        00:00:12 ora_u006_book
oracle    3834     1  0 16:08 ?        00:00:00 ora_ofsd_book
oracle    3837     1  0 16:08 ?        00:00:00 ora_dbw0_book
oracle    3841     1  0 16:08 ?        00:00:00 ora_lgwr_book
oracle    3871     1  0 16:08 ?        00:00:00 ora_bg00_book
oracle    3882     1  0 16:08 ?        00:00:00 ora_bg01_book
oracle    3891     1  0 16:08 ?        00:00:00 ora_u00c_book
--//仅仅看到这些进程。可以发现一些以前没有出现的进程比如u00N进程。ps加入-L参数可以看到线程号。

$ ps -eLf | egrep "UI[D]|ora[_]u002"
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
oracle    3803     1  3803  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3804  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3817  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3820  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3826  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3833  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3836  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3843  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3858  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3861  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  3862  0   12 16:08 ?        00:00:00 ora_u002_book
oracle    3803     1  4040  0   12 16:13 ?        00:00:00 ora_u002_book

--//可以发现LWP列对应线程号,NLWP对应数量。这样的方式以前一些sql脚本查询仅仅知道spid。以scott用户登录PDB。

--//rlsql scott/book@book01p
SCOTT@book01p> @ spid
==============================
SID                           : 275
SERIAL#                       : 34688
PROCESS                       : 4093
SERVER                        : DEDICATED
SPID                          : 4095
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PID                           : 78
P_SERIAL#                     : 3
KILL_COMMAND                  : alter system kill session '275,34688' immediate;
PL/SQL procedure successfully completed.

SCOTT@book01p> @ pp.txt 275
SCOTT@book01p> @ pr
==============================
USERNAME                      : SCOTT
SID                           : 275
SERIAL#                       : 34688
CON_ID                        : 3
SPID                          : 4095
SOSID                         : 4095
STID                          : 4095
EXECUTION_TYPE                : PROCESS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PL/SQL procedure successfully completed.
--// SPID , SOSID ,STID  三者值一样,说明并没有使用线程。

$ ps -eLf | egrep -i "[U]ID|[4]095"
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
oracle    4095     1  4095  0    1 16:17 ?        00:00:00 oraclebook (LOCAL=NO)
--//可以发现并没有使用线程。

--//要想用户登录使用线程必须修改监听配置文件,加入。
DEDICATED_THROUGH_BROKER_listener =ON

--//注意21c使用Read-Only Oracle Homes,监听配置文件不在原来位置,我的测试环境在

$ locate --regex listener.ora$
/u01/app/oracle/homes/OraDB21Home1/network/admin/listener.ora
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/u01/app/oracle/product/21.0.0/dbhome_1/network/admin/samples/listener.ora

--//停止监听,修改监听配置文件,再重启启动监听(输出略)。scott用户登录退出重新登录:

SCOTT@book01p> @ spid
==============================
SID                           : 276
SERIAL#                       : 56799
PROCESS                       : 4616
SERVER                        : DEDICATED
SPID                          : 4618
PID                           : 78
P_SERIAL#                     : 5
KILL_COMMAND                  : alter system kill session '276,56799' immediate;
PL/SQL procedure successfully completed.

SCOTT@book01p> @ pp.txt 276
SCOTT@book01p> @ pr
==============================
USERNAME                      : SCOTT
SID                           : 276
SERIAL#                       : 56799
CON_ID                        : 3
SPID                          : 4618
SOSID                         : 4618_4619
STID                          : 4619
EXECUTION_TYPE                : THREAD
PL/SQL procedure successfully completed.

--//注意现在SPID=4618,stid=4619。再使用scott登录1个新的会话。

SCOTT@book01p> @ pp.txt 404
SCOTT@book01p> @ pr
==============================
USERNAME                      : SCOTT
SID                           : 404
SERIAL#                       : 14329
CON_ID                        : 3
SPID                          : 4618
SOSID                         : 4618_4629
STID                          : 4629
EXECUTION_TYPE                : THREAD
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PL/SQL procedure successfully completed.

$ ps -eLf | egrep -i "[U]ID|461[8]"
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
oracle    4618     1  4618  0    3 16:40 ?        00:00:00 ora_u000_book
oracle    4618     1  4619  0    3 16:40 ?        00:00:00 ora_u000_book
oracle    4618     1  4629  0    3 16:40 ?        00:00:00 ora_u000_book
--//可以发现使用2个会话,并且使用线程。现在就不能简单的kill 4618,这样如果存在多个线程,可能许多会话会全部kill,看看kill
--//-9 4619发生什么情况。

$ kill -9 4619
$ ps -eLf | egrep -i "[U]ID|461[8]"
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD

--//只要一个线程kill,整个相关线程包含主进程全部都被kill。也许正是这个原因导致很少采用的缘故。

SCOTT@book01p> select sysdate from dual ;
select sysdate from dual
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 4618 Thread ID: 4619
Session ID: 276 Serial number: 56799

SCOTT@book01p> select sysdate from dual ;
select sysdate from dual
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 4618 Thread ID: 4629
Session ID: 404 Serial number: 14329
--//注意看提示。

3.继续测试:
--//重新登陆:
SCOTT@book01p> @ pp.txt 19
SCOTT@book01p> @ pr
==============================
USERNAME                      : SCOTT
SID                           : 19
SERIAL#                       : 60052
CON_ID                        : 3
SPID                          : 4730
SOSID                         : 4730_4731
STID                          : 4731
EXECUTION_TYPE                : THREAD
PL/SQL procedure successfully completed.

$ strace -f -p 4731  -y -Ttt 2>&1 | tee /tmp/test.txt
Process 4731 attached with 3 threads
[pid  4752] 16:51:44.858251 read(18<socket:[29176]>,  <unfinished ...>
[pid  4731] 16:51:44.858513 read(13<socket:[29150]>,  <unfinished ...>
[pid  4730] 16:51:44.858556 semtimedop(262144, {{82, -1, 0}}, 1, {3, 0}) = -1 EAGAIN (Resource temporarily unavailable) <3.230285>
[pid  4730] 16:51:48.089368 semtimedop(262144, {{82, -1, 0}}, 1, {3, 0}) = -1 EAGAIN (Resource temporarily unavailable) <3.016547>
[pid  4730] 16:51:51.106292 semtimedop(262144, {{82, -1, 0}}, 1, {3, 0}) = -1 EAGAIN (Resource temporarily unavailable) <3.021049>
[pid  4730] 16:51:54.127456 semtimedop(262144, {{82, -1, 0}}, 1, {3, 0}) = -1 EAGAIN (Resource temporarily unavailable) <3.002734>
--//可以发现对应主进程4730调用semtimedop,休眠3秒,如果线程有sql语句执行必须会被唤醒,这样如果多个相同主进程的线程执行
--//sql语句存在一个协调调度问题。

--//drop table t purge ;
create table t as select rownum id ,'test' pad from dual connect by level<=2e5;
create unique index pk_t on t(id);
exec dbms_stats.gather_table_stats(user, 't', method_opt=>'for all columns size 1');

$ cat m9.txt
set verify on
variable v_method varchar2(20)
exec :v_method := '&&2';

define t=&&1;

@@ ma.txt 1 &&2

insert into job_times values ( sys_context ('userenv', 'sid') ,dbms_utility.get_time ,'&&2') ;
commit ;

@@ ma.txt &&t &&2

update job_times set time_ela = dbms_utility.get_time - time_ela where sid=sys_context ('userenv', 'sid') and method= :v_method;
commit;
quit
[oracle@centtest IP=56.101 ~/study/202410 ] $ cat ma.txt
DECLARE
   l_count PLS_INTEGER;
BEGIN
    FOR i IN 1..&&1
    LOOP
       EXECUTE IMMEDIATE 'Select /*+ &2 */ count(*) from t where id = :j ' INTO l_count USING i;
    END LOOP;
END;
/

$ zzdate;seq 8 | xargs -P 8 -IQ sqlplus -s -l scott/book@book01p @m9.txt 8e5 CCCC > /dev/null;zzdate
trunc(sysdate)+17/24+06/1440+59/86400 1733994419.410840721
trunc(sysdate)+17/24+07/1440+31/86400 1733994451.309702554

--//使用top查看:
top - 17:06:15 up  1:35,  1 user,  load average: 2.52, 1.35, 0.73
Tasks: 164 total,   1 running, 163 sleeping,   0 stopped,   0 zombie
%Cpu(s): 97.5 us,  0.8 sy,  0.0 ni,  0.5 id,  0.0 wa,  0.0 hi,  1.2 si,  0.0 st
KiB Mem :  8010488 total,  4202600 free,  2044268 used,  1763620 buff/cache
KiB Swap:  1048572 total,  1048572 free,        0 used.  5644572 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 4730 oracle    20   0 2390620 108416  46960 S 396.3  1.4   5:13.37 ora_u000_book
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 3812 oracle    -2   0 1302296  18708  14540 S   1.7  0.2   0:14.30 ora_vktm_book
 2843 oracle    20   0  118764   3340   1660 S   0.0  0.0   0:00.04 -bash

$ strace -f -p 4730 -c
Process 4730 attached with 11 threads
^CProcess 4730 detached
Process 4752 detached
Process 4946 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 51.70    5.708983           6    940107           getrusage
 45.81    5.057840      133101        38        30 semtimedop
  2.48    0.273415         104      2630           select
  0.01    0.000676           6       111           munmap
  0.00    0.000302          38         8           madvise
  0.00    0.000220           2       136           read
  0.00    0.000180           0       424        48 stat
  0.00    0.000082           0       352           geteuid
  0.00    0.000021           0        72           close
  0.00    0.000021           3         8           timer_delete
  0.00    0.000018           1        32           write
  0.00    0.000014           0        31           rt_sigprocmask
  0.00    0.000013           0        32           open
  0.00    0.000010           0        72           lseek
  0.00    0.000008           0        23           mmap
  0.00    0.000008           0        32           getrlimit
  0.00    0.000007           0        40           lstat
  0.00    0.000004           0        16           semctl
  0.00    0.000004           0        16           gettid
  0.00    0.000003           0        16           fstat
  0.00    0.000002           0        16           rt_sigaction
  0.00    0.000002           1         3           io_setup
  0.00    0.000001           0         5           rt_sigreturn
  0.00    0.000001           0        24           fcntl
  0.00    0.000000           0        16           setsockopt
  0.00    0.000000           0         3           io_destroy
  0.00    0.000000           0         8           epoll_ctl
------ ----------- ----------- --------- --------- ----------------
100.00   11.041835                944271        78 total

--//链接http://blog.ora-600.pl/2015/12/17/oracle-12c-internals-of-threaded-execution/提到的情况
[root@rico fd]# strace -cp 12165
Process 12165 attached
^CProcess 12165 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 84.22    0.113706           0    980840           poll
 10.37    0.014000        7000         2           read
  5.41    0.007310        1218         6           semtimedop
  0.00    0.000000           0         2           write
  0.00    0.000000           0         1           semctl
  0.00    0.000000           0       419           getrusage
  0.00    0.000000           0        12           times
------ ----------- ----------- --------- --------- ----------------
100.00    0.135016                981282           total

[root@rico fd]# strace -p 12165 -o /tmp/threaded_exec.out
Process 12165 attached
^CProcess 12165 detached
[root@rico fd]# grep poll /tmp/threaded_exec.out | tail
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
poll([{fd=63, events=POLLIN|POLLRDNORM}], 1, 0) = 0 (Timeout)
--//可以推测21c使用semtimedop调用代替poll。

--//重复测试:
$ zzdate;seq 8 | xargs -P 8 -IQ sqlplus -s -l scott/book@book01p @m9.txt 8e5 CCCC > /dev/null;zzdate
trunc(sysdate)+17/24+11/1440+42/86400 -1733994702.866654595
trunc(sysdate)+17/24+12/1440+14/86400 1733994734.657435531
--//Sum = 31.790780936

SYS@book> @ ashtop event 1=1 trunc(sysdate)+17/24+11/1440+42/86400 trunc(sysdate)+17/24+12/1440+14/86400

    Total                                                                                                      Distinct Distinct    Distinct
  Seconds     AAS %This   EVENT                                      FIRST_SEEN          LAST_SEEN           Execs Seen  Tstamps Execs Seen1
--------- ------- ------- ------------------------------------------ ------------------- ------------------- ---------- -------- -----------
      219     6.8   91% |                                            2024-12-12 17:11:43 2024-12-12 17:12:13        112       31         139
       21      .7    9% | cursor: pin S                              2024-12-12 17:11:51 2024-12-12 17:12:10          1       10          10


--//停止监听,修改监听注解DEDICATED_THROUGH_BROKER_listener =ON,再重新启动监听,重复测试:

$ zzdate;seq 8 | xargs -P 8 -IQ sqlplus -s -l scott/book@book01p @m9.txt 8e5 DDDD > /dev/null;zzdate
trunc(sysdate)+17/24+19/1440+15/86400 -1733995155.460912071
trunc(sysdate)+17/24+19/1440+47/86400 1733995187.632465143
--//Sum = 32.171553072,虚拟机器太不稳定。

SCOTT@book01p> @ ashtop event 1=1 trunc(sysdate)+17/24+19/1440+15/86400 trunc(sysdate)+17/24+19/1440+47/86400
    Total                                                                                                      Distinct Distinct    Distinct
  Seconds     AAS %This   EVENT                                      FIRST_SEEN          LAST_SEEN           Execs Seen  Tstamps Execs Seen1
--------- ------- ------- ------------------------------------------ ------------------- ------------------- ---------- -------- -----------
      218     6.8   88% |                                            2024-12-12 17:19:16 2024-12-12 17:19:46        105       31         135
       29      .9   12% | cursor: pin S                              2024-12-12 17:19:18 2024-12-12 17:19:46          1       10          10
        1      .0    0% | log file sync                              2024-12-12 17:19:15 2024-12-12 17:19:15          1        1           1
--//从性能讲差别不大。

SCOTT@book01p> Select method,count(*),round(avg(TIME_ELA),2),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD                 COUNT(*) ROUND(AVG(TIME_ELA),2) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
CCCC                          8                   3095         24760
DDDD                          8                3121.88         24975

总结:
1.参考链接:
http://blog.ora-600.pl/2015/12/17/oracle-12c-internals-of-threaded-execution/
https://martincarstenbach.wordpress.com/2014/07/21/implications-of-threaded_execution-true-in-12c/

2.采用后sys启动数据库必须使用用户+口令模式,实际上关库也是一样。

3.kill 其中1个线程,整个相关线程全部kill。

4.不建议在生产系统使用。

5.补充后台进程实际上scmn
SYS@book> @ bgx scmn
PROGRAM                MODULE       ACTION SID     PID SPID
---------------------- ------------ ------ --- ------- --------
oracle@centtest (SCMN)                       1       4 3803
oracle@centtest (SCMN)                     382      11 3825
oracle@centtest (SCMN)                     383      15 3831
oracle@centtest (SCMN)                     129      17 3834
oracle@centtest (SCMN)                     276      78 4730
oracle@centtest (SCMN)                       8      36 3871
oracle@centtest (SCMN)                      10      40 3882
oracle@centtest (SCMN)                     263      46 3891
oracle@centtest (SCMN)                     130      25 3841
9 rows selected.

6.测试后注意修改回来。
SYS@book> alter system reset threaded_execution;
System altered.
--//修改监听文件,注解DEDICATED_THROUGH_BROKER_listener =ON。

posted @ 2024-12-14 20:25  lfree  阅读(16)  评论(0编辑  收藏  举报