只用KILL命令安全高效的关闭clusterwar

xiaoxiao2021-02-28  68

转自:http://www.itpub.net/thread-1620414-1-1.html

我们知道,11gR2中,集群引入了很多新的进程。并且一旦集群完全启动,我们很难用单用linux的kill命令去关闭这些进程。

一是 因为这些进程互相依赖守护,不管你kill了哪些进程,这些进程立刻都会被重新启动。  二是 如果kill的顺序不对,轻则宕机重启,重则可能产生不一致性。(脑裂) 而实际工作中,有些情况下,即使crsctl stop crs -f 也会遇到hang住的情况,所以这种情况下,我们还是得借助linux的KILL命令去杀死进程。 下面我们就来模拟一个极端的情况,对于一个正常工作的,所有服务都启动了的集群中的某节点,如何在不touch任何 oracle 相关的东东的前提下,只用kill命令,就安全高效的清理此节点上所有的clusterware资源? 下面我们来演示下: [root@node1 ~]# ps -ef|grep d.bin root       462     1  0 10:27 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/octssd.bin root       464     1  0 10:27 ?        00:00:02 /prod/grid/app/11.2.0/grid/bin/crsd.bin reboot grid       470     1  0 10:27 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/gpnpd.bin root       538     1  0 10:28 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oclskd.bin oracle     599     1  0 10:28 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oraagent.bin root       603     1  0 10:28 ?        00:00:01 /prod/grid/app/11.2.0/grid/bin/orarootagent.bin root      1280     1  1 10:31 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/ohasd.bin reboot grid      1336     1  0 10:31 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oraagent.bin root      1340     1  0 10:31 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/orarootagent.bin root      1342     1  5 10:31 ?        00:00:02 /prod/grid/app/11.2.0/grid/bin/cssdagent ....省略剩下的若干进程... 我们随便来kill排在前几号的进程:464 470 538 599 603, 对应crsd|gpnpd|oclskd|oraagent|orarootagent [root@node1 ~]# kill -9 464 470 538 599 603 然后检查: [root@node1 ~]#  ps -ef|grep -v grep|egrep 'crsd|gpnpd|oclskd|oraagent|orarootagent' grid      1336     1  0 10:31 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oraagent.bin root      1340     1  0 10:31 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/orarootagent.bin grid      1481     1  0 10:32 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/gpnpd.bin root      1500     1  1 10:32 ?        00:00:01 /prod/grid/app/11.2.0/grid/bin/crsd.bin reboot root      1530     1  0 10:32 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oclskd.bin root      1584     1  0 10:32 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/orarootagent.bin grid      1587     1  0 10:32 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oraagent.bin oracle    1592     1  0 10:32 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/oraagent.bin 我们看到,随便乱kill是没有作用的,这些进程如烧不尽的野草般又生长出来。 并且注意进程的启动时间有了变化,可以确定这是我们kill后重新启动起来的。 这样盲目的kill是不行的,我们很快能想到,要kill的话,就必须从根开始。根若不死,则就会一生二,二生三,三生万物的把整个进群结构给重新演化出来。 根在哪?  答:ohasd 那么下一步是否先从这个根ohasd开始杀起? 可是,这么明显的漏洞,oracle能没想到吗? 对于这最脆弱的根,oracle使用了守护进程进行保护,一旦死亡,会被自动重新启动。所以这最后的弱点也没有了。 下面我们看到,杀死ohasd.bin,立刻被init.ohasd重新生成,我们kill init.ohasd进程,也重新被PID=1的根进程给重新respawn起来: [root@node1 ~]# ps -ef|grep ohasd |grep -v grep root       750     1  0 10:28 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run root      1280     1  0 10:31 ?        00:00:01 /prod/grid/app/11.2.0/grid/bin/ohasd.bin reboot [root@node1 ~]# kill -9 1280                            ---先尝试杀死ohasd.bin [root@node1 ~]# ps -ef|grep ohasd |grep -v grep         ---没用,注意时间和PID的改变,说明又被重新启动 root       750     1  0 10:28 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run root      2294   750 12 10:52 ?        00:00:00 /prod/grid/app/11.2.0/grid/bin/ohasd.bin restart [root@node1 ~]# kill -9 750                             ---尝试杀死守护进程init.ohasd [root@node1 ~]# ps -ef|grep ohasd |grep -v grep         ---没用,注意时间和PID的改变,说明又被重新启动 root      2294     1  3 10:52 ?        00:00:01 /prod/grid/app/11.2.0/grid/bin/ohasd.bin restart root      2462     1  0 10:53 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run 那么真的没有办法了吗?想要摧毁敌人,先要了解敌人。 下面简单介绍下关于ohasd的一些知识点: 1./etc/init.d/init.ohasd:也就是大家看到的守护进程,但是要注意,这个守护进程并不会在操作系统重新启动时自动启动ohasd服务的进程。 2.ohasd.bin:真正的d.bin进程,负责生成几个最主要的agent进程(oraagent, orarootagent, cssdagent),从而由这些agent去生万物。 3./etc/init.d/ohasd 负责在系统启动时调用一次自动启动ohasd服务。   注意,这个服务只会在系统启动时候自动调用一次自动启动ohasd,之后再也没有任何作用,直到下一次重启。在此期间ohasd.bin的监视交给init.ohasd守护进程负责,一旦发现ohasd.bin意外死亡,将由/etc/init.d/init.ohasd 守护进程负责重启。 你在系统日志中看到的"May 28 09:52:10 node1 root:  Oracle  HA daemon is enabled for autostart.",  就是由/etc/init.d/ohasd产生。 4./rc.d/rc3.d/S96ohasd, ./rc.d/rc5.d/S96ohasd, ./rc.d/rc6.d/K19ohasd, ./rc.d/rc1.d/K19ohasd.  这些都是/etc/init.d/ohasd的快捷方式, 负责在系统启动时调用一次自动启动ohasd服务。 5.$GRID_HOME/bin/ohasd.    你在日志中看到的诸如以下信息都由此脚本负责写入: May 28 09:52:12 node1 logger: exec /prod/grid/app/11.2.0/grid/perl/bin/perl -I/prod/grid/app/11.2.0/grid/perl/lib /prod/grid/app/11.2.0/grid/bin/crswrapexece.pl /prod/g rid/app/11.2.0/grid/crs/install/s_crsconfig_node1_env.txt /prod/grid/app/11.2.0/grid/bin/ohasd.bin "reboot" May 28 09:52:13 node1 /prod/grid/app/11.2.0/grid/bin/crswrapexece.pl[30866]: executing "/prod/grid/app/11.2.0/grid/bin/ohasd.bin reboot" 6. 简单的关联关系来描述下: /etc/init.d/ohasd     (系统启动时运行一次启动负责ohasd.bin初始启动) ----->  $GRID_HOME/bin/crsctl   |                                                                                                       |  =====>$GRID_HOME/bin/ohasd ====> ohasd.bin /etc/init.d/init.ohasd(系统启动后监视ohasd.bin,发现失败则重启    ) ----->                          | 我们可以看到,大家熟知的init.ohasd守护进程并不是负责在系统启动时候启动ohasd服务的,所以这也回答了一些朋友的疑问: 为什么即使关闭了cluster后重启节点后集群仍然会重新启动。 如果是是由init.ohasd负责启动的那为什么一定要重启操作系统后才能自动启动? 答案就是操作系统启动时ohasd的启动由/etc/init.d/ohasd负责的而不是/etc/init.d/init.ohasd。 那么系统启动时由/etc/init.d/ohasd会启动ohasd.bin, 这不会和也负责保护ohasd的/etc/init.d/init.ohasd冲突吗? 所以 /etc/init.d/init.ohasd有自己的一套判断机制,可以判断当前是否处在操作系统重新启动时/etc/init.d/ohasd 正在开始启动ohasd.bin但是还尚未启动的过程中,如果是处在这一过程,那么 /etc/init.d/init.ohasd就会进行等待,而不会再去尝试启动ohasd.bin。 所以我们想要永久性的杀死ohasd.bin并阻止init.ohasd守护启动进程重新启动它的方法也落在此处,那就是让init.ohasd误以为当前状体是处于一个刚刚重启,/etc/init.d/ohasd  尚未启动ohasd.bin的状态中。 这样自然init.ohasd就会一直等待下去,而不再尝试重启ohasd.bin。 原理有点晦涩,但是知道了这个原理后,真正的解决方法很简单: [root@node1 log]# ps -ef|grep ohasd root     32563     1  0 10:25 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run root     32693 32563  0 10:25 ?        00:00:01 /prod/grid/app/11.2.0/grid/bin/ohasd.bin restart [root@node1 log]# kill -9 32563; kill -9 32693   [root@node1 log]# ps -ef|grep ohasd root       750     1  0 10:28 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run root       768   750  0 10:28 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run [root@node1 log]# ps -ef|grep ohasd root       750     1  0 10:28 ?        00:00:00 /bin/sh /etc/init.d/init.ohasd run  ---ohasd.bin被成功杀死并且不再启动,只剩下init.ohasd孤单的运行着 注意红字部分 kill -9 32563; kill -9 32693 ,通过这种kill方式,我们就成功杀死了ohasd.bin ,并且使得init.ohasd 成功落在了上面黑体字段所描述的那种特殊状态中,不会再次尝试重启ohasd.bin。 (当然,如果只是简单的想失效init.ohasd,更简单些我们可以给ohasdrun文件写入STOP标志,或者直接从inittab中注释掉init.ohasd然后生效更改, 可是这么一来就失去了本文的目的,也称不上是在不动任何oracle东西的情况下杀死。有兴趣的朋友可以自行实验。)
转载请注明原文地址: https://www.6miu.com/read-54722.html

最新回复(0)