ITPub博客

首页 > 数据库 > 数据库开发技术 > Oracle系列 | 好端端地编译一个包怎么就不成功呢?

Oracle系列 | 好端端地编译一个包怎么就不成功呢?

原创 数据库开发技术 作者:小安 时间:2020-10-26 22:44:55 0 删除 编辑

  这是学习笔记的第37篇文章


场景说明


开发小姐姐 :在吗?小安Sir,可以帮忙重新编译一个包吗?我们有个包编译不了!
小安Sir心想,天哪!终于出现小姐姐!我可以好好表现一番了。


YY瞎编


首先,小安Sir需要让小姐姐花些时间跟我理顺下事件的前因后果,对这个编译事件来个"望闻问切",显得我的专业性!比如,芳龄、有没有男朋友,额?


其实,我是想问下:为什么要编译,编译的前中后做了什么?持续多久?等等


交流的过程中,小安Sir的大脑已经蹦出了处理思路,不愧是我。

(1)是包头失效还是包体失效?
(2)是否存在阻碍的进程影响重新编译?
(3)如果存在阻碍,与应用人员沟通,是否可以尝试杀Process以及会话


1. 查看包头和包体是否失效?


从以下SQL语句输出得知,包头没有失效,包体失效了

 1SQL> set lines 250
2SQL> set pages 1000000
3SQL> set pages 10000
4SQL> select * from dba_objects where owner in ('ZJDB') and object_name = 'PKG_TEST';
5
6OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
7------------------------------ ------------------------------------------------------------------------------------ ---------- -------------- -------------------
8CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S NAMESPACE EDITION_NAME
9------------------- ------------------- ------------------- ------- - - - ---------- ------------------------------
10ZJDB PKG_TEST 451406 PACKAGE
112018-01-16 05:42:35 2018-04-14 10:21:22 2018-04-22:17:50:30 VALID N N N 1
12
13ZJDB PKG_TEST 451443 PACKAGE BODY
142018-01-16 05:44:41 2018-04-14 10:21:25 2018-04-25:10:14:04 INVALID N N N 2


2. 重新编译包体


检查有什么阻碍包体的编译,让问题重现。这个步骤是非常重要的,你说有Bug,我就要相信有Bug啦?小安Sir才不吃这一套,show me the Bug !我个人认为,介入故障事件,就要分出前后对比的效果。

1SQL> alter package ZJDB.PKG_TEST compile body;



3. 查看DDL锁的独占


3.1 查看DDL锁表结构

1SQL> desc dba_ddl_locks
2 Name Null? Type
3 ------------------ ------- ----------------
4 SESSION_ID       NUMBER
5 OWNER           VARCHAR2(30)
6 NAME            VARCHAR2(30)
7 TYPE            VARCHAR2(40)
8 MODE_HELD       VARCHAR2(9)
9 MODE_REQUESTED  VARCHAR2(9)


3.2 查看DDL锁的独占 

找出Exclusive的信息。

 1SQL> select * from dba_ddl_locks where name='PKG_TEST';
2SESSION_ID OWNER NAME TYPE MODE_HELD MODE_REQU
3---------- --------------- -------------------- -------------------- --------- ---------
4      1719 ZJDB PKG_TEST Table/Procedure/Type Null None
5     12481 ZJDB PKG_TEST Table/Procedure/Type Null None
6       948 ZJDB PKG_TEST Table/Procedure/Type Null None
7     10155 ZJDB PKG_TEST Table/Procedure/Type Null None
8      6814 ZJDB PKG_TEST Table/Procedure/Type Null None
9      2851 ZJDB PKG_TEST Table/Procedure/Type Null None
10     21183 ZJDB PKG_TEST Table/Procedure/Type Null None
11     14698 ZJDB PKG_TEST Table/Procedure/Type Null None
12     16963 ZJDB PKG_TEST Table/Procedure/Type Null None
13     23503 ZJDB PKG_TEST Table/Procedure/Type Null None
14      2650 ZJDB PKG_TEST Table/Procedure/Type Null None
15     20671 ZJDB PKG_TEST Table/Procedure/Type Null None
16     12481 ZJDB PKG_TEST Body Exclusive None        -- 会话阻碍
17      1719 ZJDB PKG_TEST Body Null None
18       948 ZJDB PKG_TEST Body Null None
19     10155 ZJDB PKG_TEST Body Null None
20      6814 ZJDB PKG_TEST Body Null None
21      2851 ZJDB PKG_TEST Body Null None
22     21183 ZJDB PKG_TEST Body Null None
23     14698 ZJDB PKG_TEST Body Null None
24     16963 ZJDB PKG_TEST Body Null None
25     23503 ZJDB PKG_TEST Body Null None
26      2650 ZJDB PKG_TEST Body Null None
27     20671 ZJDB PKG_TEST Body Null None
28     19155 ZJDB PKG_TEST Body None Exclusive
2925 rows selected.


3.3 找出独占Exclusive的会话和SQL信息

1SQL> select username,sid,serial#,sql_id,blocking_session from v$session where sid=12481;
2USERNAME    SID    SERIAL#    SQL_ID       BLOCKING_SESSION
3--------- ------ ---------- ------------- ----------------
4ZJDB        12481  8711      7b4dpss4k3hc5
525 rows selected.


3.4 查看是否阻碍正在执行重新编译的包体

通过SQL_ID找到对应的SQL语句,查看执行语句。以下SQL就是阻塞源,随后让开发小姐姐确认该会话是否可以杀掉。

 1### 该会话正在执行语句为:
2BEGIN pkg_test.ap_get_baTran(200,20180515); END;
3
4SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(to_char('7b4dpss4k3hc5'),NULL));
5
6PLAN_TABLE_OUTPUT
7--------------------------------------------------
8SQL_ID 7b4dpss4k3hc5, child number 0
9BEGIN pkg_test.ap_get_baTran(200,20180515); END;
10NOTE: cannot fetch plan for SQL_ID: 7b4dpss4k3hc5, CHILD_NUMBER: 0
11      Please verify value of SQL_ID and CHILD_NUMBER;
12      It could also be that the plan is no longer in cursor cache (check v$sql_plan)


3.5 试杀会话

先杀下会话。

1alter system kill session '12481,8711';


3.6 再次查看是否有独占编译包体的锁

经排查,可检查出1719 ZJDB PKG_TEST Body Exclusive None(第16行信息),还是存在独占DDL锁的进程按照以上的方式。

但杀1719的会话,是不对的!因为这个会话就是SYS用户正在执行重新编译的语句。

 1SQL> select * from dba_ddl_locks where name='PKG_REPORT';
2
3SESSION_ID OWNER NAME TYPE MODE_HELD MODE_REQU
4---------- --------------- ---------------- ------------------------- --------- ---------
5      9710 ZJDB PKG_TEST Table/Procedure/Type Null None
6       948 ZJDB PKG_TEST Table/Procedure/Type Null None
7     10155 ZJDB PKG_TEST Table/Procedure/Type Null None
8      6814 ZJDB PKG_TEST Table/Procedure/Type Null None
9      2851 ZJDB PKG_TEST Table/Procedure/Type Null None
10     21183 ZJDB PKG_TEST Table/Procedure/Type Null None
11     14698 ZJDB PKG_TEST Table/Procedure/Type Null None
12     16963 ZJDB PKG_TEST Table/Procedure/Type Null None
13     23503 ZJDB PKG_TEST Table/Procedure/Type Null None
14      2650 ZJDB PKG_TEST Table/Procedure/Type Null None
15     20671 ZJDB PKG_TEST Table/Procedure/Type Null None
16      1719 ZJDB PKG_TEST Body Exclusive None
17      9710 ZJDB PKG_TEST Body Null None
18     20671 ZJDB PKG_TEST Body Null None
19      6814 ZJDB PKG_TEST Body Null None
20     16963 ZJDB PKG_TEST Body Null None
21     21183 ZJDB PKG_TEST Body Null None
22       948 ZJDB PKG_TEST Body Null None
23      2851 ZJDB PKG_TEST Body Null None
24     10155 ZJDB PKG_TEST Body Null None
25     23503 ZJDB PKG_TEST Body Null None
26      2650 ZJDB PKG_TEST Body Null None
27     14698 ZJDB PKG_TEST Body Null None
2823 rows selected.

3.7 找出ZJDB.PKG_TEST对应ddl锁的相关信息

小安Sir使用的是SYS进行编译,但是出现了很多ZJDB的用户,那就只能都干掉了,避免阻塞!

 1SQL> select b.saddr, b.sid, b.serial#,b.process,b.status,b.username, b.MACHINE from v$session b where b.sid in
2      ( Select b.sid From dba_ddl_locks a, v$session b Where a.session_id = b.SID and a.name = 'PKG_TEST' and owner='ZJDB')
3      order by b.username desc;
4
5SADDR             SID SERIAL# PROCESS STATUS USERNAME MACHINE
6---------------- ---- ----- ------- -------- -------- --------- 
7070000A02BB0E7E0 1719 30765 37358470 ACTIVE SYS RACZJ-DB1
8070000A010BFF958 10155 46885 33227250 ACTIVE ZJDB RACZJ-DB1
9070000A00CB32110 9710 9641 27525876 ACTIVE ZJDB RACZJ-DB1
10070000A023BC4438 2032 9479 31195338 ACTIVE ZJDB RACZJ-DB1
11070000A0061E8210 23503 30787 55313168 ACTIVE ZJDB RACZJ-DB1
12070000A0279C9920 948 44781 13631706 ACTIVE ZJDB RACZJ-DB1
13070000A02B9B4FC0 893 27923 54263886 ACTIVE ZJDB RACZJ-DB1
14070000A02BCA68C8 2650 48113 29033334 ACTIVE ZJDB RACZJ-DB1
15070000A00DE3DE58 21183 59867 43516348 ACTIVE ZJDB RACZJ-DB1
16070000A015A40440 18410 50345 3998656 ACTIVE ZJDB RACZJ-DB1
17070000A009727FB0 16963 33555 66847560 ACTIVE ZJDB RACZJ-DB1
18070000A023D20C00 2851 17117 10224286 ACTIVE ZJDB RACZJ-DB1
19070000A02FB62590 1776 28699 46334786 ACTIVE ZJDB RACZJ-DB1
20070000A015E08488 20671 38781 53150014 ACTIVE ZJDB RACZJ-DB1
21070000A011386AF0 14698 60901 37421588 ACTIVE ZJDB RACZJ-DB1
22070000A005CC69A8 20416 37977 30147116 ACTIVE ZJDB RACZJ-DB1
23070000A001EE7AC0 21745 60937 8192734 ACTIVE ZJDB RACZJ-DB1
2417 rows selected.


3.8 数据库层面杀会话

把编译这个包的会话,除了1719,都干掉。

 1alter system kill session '10155,46885';
2alter system kill session '9710,9641';
3alter system kill session '2032,9479';
4alter system kill session '23503,30787';
5alter system kill session '948,44781';
6alter system kill session '893,27923';
7alter system kill session '2650,48113';
8alter system kill session '21183,59867';
9alter system kill session '18410,50345';
10alter system kill session '16963,33555';
11alter system kill session '2851,17117';
12alter system kill session '1776,28699';
13alter system kill session '20671,38781';
14alter system kill session '14698,60901';
15alter system kill session '20416,37977';
16alter system kill session '21745,60937';


3.9 操作系统层面杀非本地连接

演示下个别怎么操作。

1SQL> select sid, SERIAL#,process,status from v$session where sid=10155;
2
3       SID SERIAL# PROCESS STATUS
4---------- ---------- ------------------------ --------
5      10155 30765 37358425 ACTIVE
6
7$ ps -ef|grep 37358425  
8$ kill -9 37358425                    --操作系统层面杀会话
9$ ps -ef|grep 37358452


3.10 查看创建包体的命令是否成功

1SQL> alter package ZJDB.PKG_TEST compile body;
2Package body altered.


最后,小姐姐不仅了解到了原来编译包有这么多的讲究,开心地回去交代了;而我却得到的是小姐姐的一句话:你是个好人!


今天的YY瞎编就到此结束了,学习代码是个枯燥无味的过程,有趣的是YY一下还是很有意思的。学代码,不仅仅是代码喔!


我个人一直认为学数据库是一件非常有意义和有趣的事情,原因嘛,后续分享,哈哈。




 往期回顾 ·


自动化运维实战五  | 【演示】3分钟一键部署Mysql数据库

自动化运维实战四  | 【实现】Mysql一键部署的前后端交互

自动化运维实战三  | 【规划】Mysql一键部署的数据模型

自动化运维实战二  | 【构思】Mysql一键部署的界面

自动化运维实战一  | 【模板】 套用精美模板演示登陆界面



喜欢就点个  在看  呀!

原文作者:Python自动化运维;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-10-07

  • 博文量
    47
  • 访问量
    17924