
这是学习笔记的第37篇文章
场景说明
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自动化运维;如有侵权,请联系管理员删除。