<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_killkill</title><subtitle type="text">专注于技术</subtitle><id>http://feed.cnblogs.com/blog/u/21523/rss</id><updated>2012-05-22T05:31:32Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/21523/rss"/><entry><id>http://www.cnblogs.com/killkill/archive/2012/05/22/2513192.html</id><title type="text">[转]Linux下SSH Session复制</title><summary type="text">羡慕Windows下secureCRT的Session Copy功能，一直在寻找Linux下类似的软件，殊不知SSH本身就支持此功能。</summary><published>2012-05-22T05:30:00Z</published><updated>2012-05-22T05:30:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2012/05/22/2513192.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2012/05/22/2513192.html"/><content type="html">&lt;p&gt;羡慕Windows下secureCRT的Session Copy功能，一直在寻找Linux下类似的软件，殊不知SSH本身就支持此功能。    &lt;br /&gt;特别感谢&lt;a href="http://weibo.com/argan"&gt;阿干&lt;/a&gt;同学的邮件分享。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;详细方法&lt;/strong&gt;&lt;/p&gt;  Linux/mac下，在$HOME/.ssh/config中加入&lt;br/&gt;Host *&lt;br/&gt;ControlMaster auto&lt;br/&gt;ControlPath /tmp/ssh-%r@%h&lt;p&gt;至此只要第一次SSH登录输入密码，之后同个Hosts则免登。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;配置文件分析&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;man ssh_config 5&lt;/p&gt;ControlPath&lt;br/&gt;             Specify the path to the control socket used for connection sharing as described in the ControlMaster section&lt;br/&gt;             above or the string “none” to disable connection sharing.  In the path, ‘%l’ will be substituted by the&lt;br/&gt;             local host name, ‘%h’ will be substituted by the target host name, ‘%p’ the port, and ‘%r’ by the remote&lt;br/&gt;             login username.  It is recommended that any ControlPath used for opportunistic connection sharing include at&lt;br/&gt;             least %h, %p, and %r.  This ensures that shared connections are uniquely identified.&lt;p&gt;%r 为远程机器的登录名  &lt;br /&gt;%h 为远程机器名&lt;/p&gt;&lt;p&gt;&lt;strong&gt;    &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;原理分析&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;严格地讲，它并不是真正意义上的Session Copy，而只能说是共享Socket。  &lt;br /&gt;第一次登录的时候，将Socket以文件的形式保存到：/tmp/ssh-%r@%h这个路径  &lt;br /&gt;之后登录的时候，一旦发现是同个主机，则复用这个Socket  &lt;br /&gt;故，一旦主进程强制退出（Ctrl+C），则其他SSH则被迫退出。&lt;/p&gt;&lt;p&gt;可以通过ssh -v参数，看debug信息验证以上过程&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有同学说在linux上通过证书的形式，可以实现免登录，没错。  &lt;br /&gt;对于静态密码，完全可以这么干；对于动态密码（口令的方式），则上述手段可以方便很多。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2513192.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2012/05/22/2513192.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2012/04/08/2437960.html</id><title type="text">使用taskset命令来限制进程的CPU</title><summary type="text">Linux限制及调配进程的CPU使用情况。</summary><published>2012-04-08T12:35:00Z</published><updated>2012-04-08T12:35:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2012/04/08/2437960.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2012/04/08/2437960.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 常常感觉系统资源不够用，一台机子上跑了不下3个比较重要的服务，但是每天我们还要在上面进行个备份压缩等处理，网络长时间传输，这在就很影响本就不够用的系统资源；&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 这个时候我们就可以把一些不太重要的比如copy/备份/同步等工作限定在一颗cpu上，或者是多核的cpu的一颗核心上进行处理，虽然这不一定是最有效的方法，但可以最大程度上利用了有效资源，降低那些不太重要的进程占用cpu资源；&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;taskset&lt;/strong&gt;就可以帮我们完成这项工作，而且操作非常简单；&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 该工具系统默认安装，rpm包名util-linux&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 借助一个例子说明，借助以前写过的一个消耗CPU的脚本 &lt;a href="http://www.cnblogs.com/killkill/archive/2010/09/08/1821496.html"&gt;原]消耗CPU资源的shell脚本&lt;/a&gt; ，将一台16个CPU的机器上其中4个CPU的资源耗尽：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/killkill/201204/201204082034484040.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/killkill/201204/201204082034493418.png" width="426" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 使用 top 命令能看到4颗CPU跑满的效果：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/killkill/201204/201204082034551362.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/killkill/201204/20120408203459966.png" width="644" height="327" /&gt;&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 现在可以使用 taskset 命令调整这些进程所使用的CPU了：&lt;/p&gt;  taskset -cp 1  25718&lt;br/&gt;taskset -cp 3  25720&lt;br/&gt;taskset -cp 5  25722&lt;br/&gt;taskset -cp 7  25724&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 在top中再看看效果：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/killkill/201204/201204082035025586.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/killkill/201204/201204082035068745.png" width="644" height="323" /&gt;&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 哈哈，CPU的使用得到调配了，同样我们可以使某个进程仅使用其中几个CPU：&lt;/p&gt;taskset -cp 1,2  25718&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 更详细的信息可以用 man taskset 查看。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2437960.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2012/04/08/2437960.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/12/22/2297539.html</id><title type="text">MySQL重复记录删除</title><summary type="text">一种诡异的写法</summary><published>2011-12-22T03:50:00Z</published><updated>2011-12-22T03:50:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/12/22/2297539.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/12/22/2297539.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 一种诡异的写法：&lt;/p&gt;  delete t  &lt;br/&gt;from t, &lt;br/&gt;( select table_name,max(id) id &lt;br/&gt;  from t &lt;br/&gt;  group by table_name &lt;br/&gt;  having count(*)&amp;gt;1 ) d &lt;br/&gt;where t.table_name=d.table_name &lt;br/&gt;  and t.id&amp;lt;d.id;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 没见过这种语法，记录一下。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2297539.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/12/22/2297539.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/09/19/2181915.html</id><title type="text">使用Screen抵御杯具</title><summary type="text">Linux screen的简单用法</summary><published>2011-09-19T15:27:00Z</published><updated>2011-09-19T15:27:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/09/19/2181915.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/09/19/2181915.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 当DBA远程做一个大操作的时候最怕的是什么？断网！有木有啊！！&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 建一个20G的索引，进度到98%的时候突然断网，前功尽弃，有木有啊！！&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 怎么样才能抵御这种杯具呢？找一台Windows的机器作为终端，上面装上SSH工具，那Linux呢？靠它——screen&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话的概念，用户可以在一个screen会话中创建多个screen窗口，在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。&lt;/strong&gt;简单来说就是一个命令行版本的SecureCRT。&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 当远程会话不幸关闭的时候，screen还能驻留在服务器端，并且很容易地重连（attach），这样就保证我们的工作不会因为网络问题而终端，这是多么好的功能啊。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 键入screen即可使用screen&lt;/p&gt;  [oracle@alifina-dev12 ~]$ screen&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 如果报以下错：&lt;/p&gt;Cannot open your terminal '/dev/pts/10' - please check.&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 使用以下命令将输出重定向即可：&lt;/p&gt;[oracle@alifina-dev12 ~]$ script /dev/null &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 然后我们开始一个任务，譬如用vim写小说，突然抓狂把终端强行关闭了，那时不是之前的努力都没有了呢？ &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 我们重连一个会话，用以下命令查看并且再次attach即可，我们的成果还在！&lt;/p&gt;[oracle@alifina-dev12 ~]$ screen -ls&lt;br/&gt;There is a screen on:&lt;br/&gt;        7366.pts-0.alifina-dev12        (Detached)&lt;br/&gt;1 Socket in /var/run/screen/S-oracle.&lt;br/&gt;&lt;br/&gt;[oracle@alifina-dev12 ~]$ screen -r 7366 &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 这绝对是screen的杀手锏功能！！&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; screen还能做得更好吗？当然！&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 修改~/.screenrc，如果整台服务器都是你用的话也可以修改/etc/screenrc&lt;/p&gt;## general tweaks&lt;br/&gt;vbell off&lt;br/&gt;autodetach on&lt;br/&gt;startup_message off&lt;br/&gt;defscrollback 1000&lt;br/&gt;attrcolor b &amp;quot;.I&amp;quot;&lt;br/&gt;termcap xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'&lt;br/&gt;defbce &amp;quot;on&amp;quot; &lt;br/&gt;escape &amp;quot;^Kk&amp;quot;&lt;br/&gt;defencoding UTF-8&lt;br/&gt;encoding UTF-8 UTF-8&lt;br/&gt;hardstatus alwayslastline '%{gk}[%= %{wk}%?%-Lw%?%{=b kR}[%{W}%n%f %t%?(%u)%?%{=b kR}]%{= kw}%?%+Lw%?%?%= %{g}]%{=b C}[%m/%d %C%a]%{W}'&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 现在screen开起来会像这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/killkill/201109/201109192326439805.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Powered By killkill" border="0" alt="Powered By killkill" src="http://images.cnblogs.com/cnblogs_com/killkill/201109/201109192326432836.png" width="644" height="344" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 看到没，下面那一行彩色的东西，输入Ctrl+k，紧接着马上输入c，多了一个：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/killkill/201109/201109192326432280.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/killkill/201109/201109192326431723.png" width="644" height="342" /&gt;&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 输入 Ctrl+k n 就可以移动到下一个window（输入Ctrl+k p是上一个window），功能和SecureCRT的tab一样。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 有朋友会问为什么是Ctrl+k 呢？这个是在screenrc(.screenrc)中定义的，还有个特别的名字——命令键，我受Visual Studio的毒害很深，爱上了Ctrl+k，所以把它设为 Ctrl+k。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 一些有用的操作：&lt;/p&gt;&lt;ol&gt;  &lt;ol&gt;    &lt;li&gt;命令键 A（注意是大写的A，平时输入是shift+A）：将window改名。&lt;/li&gt;    &lt;li&gt;命令键 c：创建一个新的window&lt;/li&gt;    &lt;li&gt;命令键 d：detache当前这个screen&lt;/li&gt;    &lt;li&gt;命令键 ?：帮助……&lt;/li&gt;  &lt;/ol&gt;&lt;/ol&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2181915.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/09/19/2181915.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/06/15/2081317.html</id><title type="text">[摘]Oracle 11g Flashback_transaction_query的undo_sql为空？</title><summary type="text"/><published>2011-06-15T03:14:00Z</published><updated>2011-06-15T03:14:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/06/15/2081317.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/06/15/2081317.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 近日测试的时候发现 flashback_transaction_query中 undo_sql 为空，我记得以前明明不为空的，而且还做个&lt;a href="http://www.cnblogs.com/killkill/archive/2010/05/08/1730783.html" target="_blank"&gt;一单数据恢复&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://forums.oracle.com/forums/thread.jspa?threadID=1107387" target="_blank"&gt;经查证&lt;/a&gt;这个问题是 Oracle 11g 默认把 supplemental logging 禁用了导致的。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 使用如下语句，把 supplemental logging 打开就好了：&lt;/p&gt;  alter database add supplemental log data;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2081317.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/06/15/2081317.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/05/29/2062118.html</id><title type="text">Duplicate Active Database 遇到 ORA-01017 invalid username/password</title><summary type="text">Duplicate Active Database 遇到挺蛋疼的问题。</summary><published>2011-05-29T07:21:00Z</published><updated>2011-05-29T07:21:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/05/29/2062118.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/05/29/2062118.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Oracle 11g 的新特性Duplicate Active Database可以在不备份target database的情况下构建 duplicate database，特别适合于为VLDB构建standby的场景。今天特意试一下，但是却让我遇上了 ORA-01017 invalid username/password，过程如下：&lt;/p&gt;  oracle@dev18:abank /home/oracle&amp;gt;rman target / auxiliary sys/__password__@abank_123 &lt;br/&gt;&lt;br/&gt;Recovery Manager: Release 11.2.0.1.0 - Production on Sun May 29 14:16:08 2011&lt;br/&gt;&lt;br/&gt;Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.&lt;br/&gt;&lt;br/&gt;connected to target database: abank (DBID=433589790)&lt;br/&gt;connected to auxiliary database: abank (not mounted)&lt;br/&gt;&lt;br/&gt;RMAN&amp;gt; duplicate target database for standby from active database ;  &lt;br/&gt;&lt;br/&gt;Starting Duplicate Db at 2011-05-29 14:16:17&lt;br/&gt;using target database control file instead of recovery catalog&lt;br/&gt;allocated channel: ORA_AUX_DISK_1&lt;br/&gt;channel ORA_AUX_DISK_1: SID=1149 device type=DISK&lt;br/&gt;&lt;br/&gt;contents of Memory Script:&lt;br/&gt;{&lt;br/&gt;   backup as copy reuse&lt;br/&gt;   targetfile  '/opt/app/oracle/product/11.2.0/db/dbs/orapwabank' auxiliary format &lt;br/&gt; '/opt/app/oracle/product/11.2.0/db/dbs/orapwabank'   ;&lt;br/&gt;}&lt;br/&gt;executing Memory Script&lt;br/&gt;&lt;br/&gt;Starting backup at 2011-05-29 14:16:18&lt;br/&gt;allocated channel: ORA_DISK_1&lt;br/&gt;channel ORA_DISK_1: SID=594 device type=DISK&lt;br/&gt;RMAN-00571: ===========================================================&lt;br/&gt;RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============&lt;br/&gt;RMAN-00571: ===========================================================&lt;br/&gt;RMAN-03002: failure of Duplicate Db command at 05/29/2011 14:16:19&lt;br/&gt;RMAN-03015: error occurred in stored script Memory Script&lt;br/&gt;RMAN-03009: failure of backup command on ORA_DISK_1 channel at 05/29/2011 14:16:19&lt;br/&gt;ORA-17629: Cannot connect to the remote database server&lt;br/&gt;ORA-17627: ORA-01017: invalid username/password; logon denied&lt;br/&gt;ORA-17629: Cannot connect to the remote database server&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 打开rman的时候已经进行了验证，理论上不应在有验证的问题，google得知使用Duplicate Active Database要这样登入rman：&lt;/p&gt;rman target sys/__password__ auxiliary sys/__password__@abank_123 &lt;img src="http://www.cnblogs.com/killkill/aggbug/2062118.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/05/29/2062118.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/05/14/2046321.html</id><title type="text">[摘]如何抓住蝴蝶效应中的那只蝴蝶</title><summary type="text">看了老白分享的一个案例，感触很深，特此摘录。</summary><published>2011-05-14T07:34:00Z</published><updated>2011-05-14T07:34:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/05/14/2046321.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/05/14/2046321.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 原文地址：&lt;a href="http://www.oraclefans.cn/forum/showblog.jsp?rootid=32059" target="_blank"&gt;如何抓住蝴蝶效应中的那只蝴蝶&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 蝴蝶效应可以参考&lt;a href="http://baike.baidu.com/view/1180.htm" target="_blank"&gt;这里&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 南美丛林的一只蝴蝶煽动翅膀，可能导致莫斯科下大雪，说明的大气系统的复杂性。而DBA在日常工作中叶经常会面临类似的问题，我们从故障的表象上分析问题处理问题，而往往我们采取的措施仅仅是解决一些表象的问题，并没有找到问题的关键。也就是说，我们并没有抓到扇翅膀的那只蝴蝶，而仅仅抓住了莫斯科上空的乌云。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 前几天碰到一个案例，写出来和大家共享。客户有一套系统下午1点多的时候，突然出现了故障，服务无法响应，新会话连不上去。最后只能通过杀掉了大量的会话，才恢复正常。客户想找到问题的原因。找到我的时候已经是下午的4点多了。出现故障的时段有大量这样的信息：&lt;/p&gt;  Mon Apr 11 12:52:24 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_10410.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27544: Failed to map memory region for export&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:55:01 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_13426.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27544: Failed to map memory region for export&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:55:25 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_13934.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27544: Failed to map memory region for export&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:55:25 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_13936.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27504: IPC error creating OSD context&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:55:25 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_13938.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27504: IPC error creating OSD context&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:56:00 2011&lt;br/&gt;Thread 2 advanced to log sequence 2945 (LGWR switch)&lt;br/&gt;  Current log# 4 seq# 2945 mem# 0: /redolog/sjzzw2/redo04.log&lt;br/&gt;Mon Apr 11 12:56:01 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_14554.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27544: Failed to map memory region for export&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 同时还存在一些类似的ORA-27XXX错误：&lt;/p&gt;Mon Apr 11 12:56:33 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_22957.trc:&lt;br/&gt;ORA-27509: IPC error receiving a message&lt;br/&gt;ORA-27300: OS system dependent operation:recvmsg failed with status: 216&lt;br/&gt;ORA-27301: OS failure message: Socket operation on non-socket&lt;br/&gt;ORA-27302: failure occurred at: sskgxprcv1&lt;br/&gt;Mon Apr 11 12:56:33 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_25431.trc:&lt;br/&gt;ORA-27509: IPC error receiving a message&lt;br/&gt;ORA-27300: OS system dependent operation:recvmsg failed with status: 216&lt;br/&gt;ORA-27301: OS failure message: Socket operation on non-socket&lt;br/&gt;ORA-27302: failure occurred at: sskgxprcv1&lt;br/&gt;Mon Apr 11 12:57:24 2011&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 根据&lt;/p&gt;ORA-27300: OS system dependent operation:recvmsg failed with status: 216&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 现场工程师认为是BUG 6689903导致，建议关闭NUMA。客户准备晚上实施关闭NUMA的操作，想听听我的建议。我觉得关闭NUMA时一个十分大的操作，应该十分谨慎，因此先要搞清楚到底是什么导致了今天的问题。从ORA-27300来看，一般来说是某种OS资源不足导致的问题。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 因此我们首先要从分析错误信息开始，HP-UX的ERRNO=227，216&lt;/p&gt;#  define ENOTSOCK              216     /* Socket operation on non-socket */&lt;br/&gt;#  define EADDRNOTAVAIL         227     /* Can't assign requested address */ &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 216 是在非SOCKET上操作SOCKET操作，227是无法分配地址。对于BUG 6689903，Oracle官方解释是使用了NUMA后，Oracle存在一个BUG，导致一个会话使用了大量的UDP端口，造成UDP端口不足。可以通过打补丁或者关闭NUMA来解决这个问题。而UDP端口耗尽也可能出现ERRNO =227，无法分配地址的错误。因此可以初步判断是由于UDP端口耗尽导致了问题。在这种情况下打PATCH 6689903可以解决过多UDP端口被一个会话消耗的问题，但是不一定能解决所有的问题，当系统负载进一步加大（系统设置的 PROCESSES=4500，而出故障时发现会话数无法突破1600）,可能还会出问题。关闭NUMA虽然可以减少UDP端口的使用，但是会降低系统的性能，无法充分享受大型SMP系统的架构优势，也是不足取的。因此较好的解决这个问题是打PATCH 6689903，避免由于BUG过多消耗UDP端口，另外调整UDP端口的范围，从而让OS提供更多的UDP端口。通过下面命令：&lt;/p&gt;oracle@sjzzw22:/usr/include/sys$ ndd -get /dev/udp udp_largest_anon_port&lt;br/&gt;65535&lt;br/&gt;oracle@sjzzw22:/usr/include/sys$ ndd -get /dev/udp udp_smallest_anon_port&lt;br/&gt;49152&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 我们看到系统的UDP端口使用了缺省值，通过调整这两个值，使中间的区间变大，就能提供更多的UDP端口号了。问题分析道这里，看样子已经解决的差不多了。可能大多数DBA到此就大功告成了。而老白认为其实不然，如果说建议NUMA只是看到了下雪时莫斯科上空的乌云，那么分析到这里也仅仅看到了西伯利亚冷空气的影响。离那只南美洲的蝴蝶还有万里之遥呢。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 老白当然会继续分析下去，是什么原因导致了UDP端口号被消耗光呢？客户说平时这个系统会话数在1000出头，故障时会话数达到了1600。这个是UDP端口号被消耗光的一个很好的解释。但是为什么会话数会突增呢?通过对应用架构的了解，我们知道这个系统的大多数应用没有采用连接池，而是客户端直接连接的，当系统处理能力下降时，客户端连接数据库的连接会增加，以适应外部服务的请求。因此我们可以将怀疑点集中到系统出现了变慢的情况。如果在故障前的某个时段，系统突然变慢了，那么就有可能造成会话数增加的可能。会话数增加后，UDP端口配置过低的问题就暴露出来了。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 那么接下来我们就需要分析系统为什么会变慢，在什么时间变慢的。我们继续分析ALERT LOG，发现第一次报错的时间是12点41分左右：&lt;/p&gt;Mon Apr 11 12:38:06 2011&lt;br/&gt;Thread 2 advanced to log sequence 2940 (LGWR switch)&lt;br/&gt;  Current log# 3 seq# 2940 mem# 0: /redolog/sjzzw2/redo03.log&lt;br/&gt;Mon Apr 11 12:40:58 2011&lt;br/&gt;Errors in file /oracle/app/oracle/admin/sjzzw2/udump/sjzzw22_ora_25451.trc:&lt;br/&gt;ORA-00603: ORACLE server session terminated by fatal error&lt;br/&gt;ORA-27544: Failed to map memory region for export&lt;br/&gt;ORA-27300: OS system dependent operation:bind failed with status: 227&lt;br/&gt;ORA-27301: OS failure message: Can't assign requested address&lt;br/&gt;ORA-27302: failure occurred at: sskgxpcre3&lt;br/&gt;Mon Apr 11 12:40:59 2011&lt;br/&gt;Trace dumping is performing id=[cdmp_20110411124059]&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 看样子故障点应该在12点41分之前。于是我们做一个ASH报告，来看看12：:00-12:40之间系统发生了什么，为了便于分析，我们先按照10分钟周期做4个报告，在前面三个报告中，一切正常，在12:30-12:40的报告中，我们发现了一个疑点：&lt;/p&gt;gcs drm freeze in enter server       24&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 在 1分钟内，活跃会话的采样中，出现了24次drm的等待平均等待时间600毫秒左右。而且这个时间段内的SQL执行次数，BUFFER GET等指标明显低于前面的时段。因此我们可以初步断定，这可能是导致会话数量突增的一个重要疑点。而这个系统的另外一个节点跑的是完全不同的应用，而且还没有投产，为什么会出现这么多DRM呢？通过LMD,LMON，LMS等的日志我们也看出，在12:36-38这段时间里的DRM数量比前面时段增加了数倍。于是我们在另外一个节点上的12:30-12:40生成了一个ASH报告，从这里我们终于看到了那只美丽的蝴蝶的真面目了，原来在这个时段，在另外一个节点上有人用SQLPLUS登陆上去，访问了大量的故障节点的数据。而这个操作导致了DRM事件增加，短暂降低了系统的性能。如果UDP端口号够用，这个影响不会被放大，而仅仅会在12点多钟业务不繁忙时段出现短暂几分钟的性能下降，很快就会平息。而正是由于UDP端口号不足，才放大了这个蝴蝶扇翅膀动作。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 抓住了这只蝴蝶，那么如何解决这个问题就很明显了，尽可能不要出现类似的操作肯定是要提的。不过另外一个问题也是需要我们考虑的，在这样的一个系统中，DRM其实是不必要的，因为正常情况下，两个节点会跑自己的数据，不会交叉。因此关闭DRM是一个更靠谱的选择。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 大家可能对关闭DRM这个结局感到意外，不过如果你看过了这个抓蝴蝶的全过程，你就会认为这是顺理成章的事情了。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 事情就是这么简单，但是我想大多数人只会走到这个过程中的某个步骤，就停下了。这就是DBA之间的差距，不仅仅是技术上的，更多的是态度的问题。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2046321.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/05/14/2046321.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/04/30/2033228.html</id><title type="text">[原]将Oracle 中的blob导出到文件中</title><summary type="text"/><published>2011-04-29T16:41:00Z</published><updated>2011-04-29T16:41:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/04/30/2033228.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/04/30/2033228.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 直接上代码：&lt;/p&gt;  declare&lt;br/&gt;  l_directory varchar(200) := '__dir__';&lt;br/&gt;l_file UTL_FILE.FILE_TYPE;  &lt;br/&gt;l_buffer RAW(32767);  &lt;br/&gt;l_amount BINARY_INTEGER:=32767;  &lt;br/&gt;l_pos NUMBER:=1;  &lt;br/&gt;l_Blob Blob;  &lt;br/&gt;l_Blob_len Number;  &lt;br/&gt;l_lob_id number;&lt;br/&gt;CURSOR cur is &lt;br/&gt;  select __id__ from __table_name__;&lt;br/&gt;BEGIN  &lt;br/&gt;  open cur;&lt;br/&gt;loop&lt;br/&gt;  fetch cur into l_lob_id;&lt;br/&gt;  EXIT when cur%NOTFOUND; &lt;br/&gt;  select __blob_fild__ into l_Blob from __table_name__ where __id__=l_lob_id ; &lt;br/&gt;  l_file:=UTL_FILE.FOPEN(l_directory,'adapter_blob.'||to_char(l_lob_id)||'.bin','wb',32767); &lt;br/&gt;  l_Blob_len:=dbms_lob.getlength(l_Blob);  &lt;br/&gt;  l_pos := 1;&lt;br/&gt;  WHILE l_pos&amp;lt;l_Blob_len LOOP  &lt;br/&gt;    DBMS_LOB.READ(l_Blob,l_amount,l_pos,l_buffer);&lt;br/&gt;    UTL_FILE.PUT_RAW(l_file,l_buffer,TRUE);  &lt;br/&gt;    l_pos:=l_pos+l_amount;  &lt;br/&gt;  end loop;  &lt;br/&gt;  utl_file.fclose(l_file);  &lt;br/&gt;end loop;&lt;br/&gt;exception  &lt;br/&gt;when others then  &lt;br/&gt;if utl_file.is_open(l_file) then  &lt;br/&gt;utl_file.fclose(l_file);  &lt;br/&gt;end if;  &lt;br/&gt;END;  &lt;img src="http://www.cnblogs.com/killkill/aggbug/2033228.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/04/30/2033228.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/04/26/2029818.html</id><title type="text">[原]unique index和non unique index的区别</title><summary type="text"/><published>2011-04-26T14:13:00Z</published><updated>2011-04-26T14:13:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/04/26/2029818.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/04/26/2029818.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 今天做Schema评审的时候发现一个很奇怪的现象，也许是用工具生成的SQL语句，清一色的如下：&lt;/p&gt;  CREATE TABLE table_name (&lt;br/&gt;idNUMBERNOT NULL,&lt;br/&gt;......&lt;br/&gt;......&lt;br/&gt;) ;&lt;br/&gt;&lt;br/&gt;CREATE INDEX table_name_PK ON table_name(ID) ;&lt;br/&gt;ALTER TABLE table_name &lt;br/&gt;  ADD CONSTRAINT table_name_PK PRIMARY KEY (ID) &lt;br/&gt;  USING INDEX table_name_PK ;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 通常来说主键（Primary Key，PK）的index是unique index，而现在变成了non-unique index，这有什么不同呢？于是我建了两张1000万数据的表，并用两种不同的index设定为PK的index，语句如下：&lt;/p&gt;create table tab1000w01 &lt;br/&gt;as &lt;br/&gt;select level id,'killkill Hello world' data&lt;br/&gt;from dual connect by level&amp;lt;=1000*10000;&lt;br/&gt;&lt;br/&gt;create table tab1000w02 &lt;br/&gt;as &lt;br/&gt;select level id,'killkill Hello world' data&lt;br/&gt;from dual connect by level&amp;lt;=1000*10000;&lt;br/&gt;&lt;br/&gt;CREATE UNIQUE INDEX tab1000w01_pk ON tab1000w01 (PK_ID)  ;&lt;br/&gt;ALTER TABLE  tab1000w01 ADD CONSTRAINT tab1000w01_PK PRIMARY KEY (PK_ID) USING INDEX tab1000w01_pk ;&lt;br/&gt;&lt;br/&gt;CREATE INDEX tab1000w02_pk ON tab500w02 (PK_ID)  ;&lt;br/&gt;ALTER TABLE  tab1000w02 ADD CONSTRAINT tab1000w02_PK PRIMARY KEY (PK_ID) USING INDEX tab1000w02_pk ;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 以下是按照PK查找数据的语句：&lt;/p&gt;select * from tab1000w01 where id=34567;&lt;br/&gt;&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;|   0 | SELECT STATEMENT            |                   |     1 |    35 |     3   (0)| 00:00:01 |&lt;br/&gt;|   1 |  TABLE ACCESS BY INDEX ROWID| TAB1000W01        |     1 |    35 |     3   (0)| 00:00:01 |&lt;br/&gt;|*  2 |   INDEX UNIQUE SCAN         | IDX_TAB1000W01_PK |     1 |       |     2   (0)| 00:00:01 |&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;&lt;br/&gt;Predicate Information (identified by operation id):&lt;br/&gt;---------------------------------------------------&lt;br/&gt;&lt;br/&gt;   2 - access(&amp;quot;ID&amp;quot;=34567)&lt;br/&gt;&lt;br/&gt;Statistics&lt;br/&gt;----------------------------------------------------------&lt;br/&gt;          0  recursive calls&lt;br/&gt;          0  db block gets&lt;br/&gt;          4  consistent gets&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;select * from tab1000w02 where id=34567;&lt;br/&gt;&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;|   0 | SELECT STATEMENT            |                   |     1 |    35 |     3   (0)| 00:00:01 |&lt;br/&gt;|   1 |  TABLE ACCESS BY INDEX ROWID| TAB1000W02        |     1 |    35 |     3   (0)| 00:00:01 |&lt;br/&gt;|*  2 |   INDEX RANGE SCAN          | IDX_TAB1000W02_PK |     1 |       |     2   (0)| 00:00:01 |&lt;br/&gt;-------------------------------------------------------------------------------------------------&lt;br/&gt;&lt;br/&gt;Predicate Information (identified by operation id):&lt;br/&gt;---------------------------------------------------&lt;br/&gt;&lt;br/&gt;   2 - access(&amp;quot;ID&amp;quot;=34567)&lt;br/&gt;&lt;br/&gt;Statistics&lt;br/&gt;----------------------------------------------------------&lt;br/&gt;          0  recursive calls&lt;br/&gt;          0  db block gets&lt;br/&gt;          5  consistent gets&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 从执行计划来看，一个是index unique scan，一个是index range scan，从consistent gets来看，一个是4，一个是5，使用unique index节省了1个，不要少看这1个consistent gets，它可是占了总体的20%啊。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 不过这是为什么呢？这篇文章很好地介绍这两种索引的异同：&lt;a href="http://richardfoote.wordpress.com/2007/12/18/differences-between-unique-and-non-unique-indexes-part-i/" target="_blank"&gt;Differences Between Unique and Non-Unique Indexes&lt;/a&gt;，说到底是这两种索引的结构不同。引用一下这篇文章的分析：&lt;/p&gt;Leaf block dump&lt;br/&gt;===============&lt;br/&gt;header address 143336028=0x88b225c&lt;br/&gt;kdxcolev 0&lt;br/&gt;KDXCOLEV Flags = - - -&lt;br/&gt;kdxcolok 0&lt;br/&gt;kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y&lt;br/&gt;kdxconco 2&lt;br/&gt;kdxcosdc 0&lt;br/&gt;kdxconro 500&lt;br/&gt;kdxcofbo 1036=0x40c&lt;br/&gt;kdxcofeo 1042=0x412&lt;br/&gt;kdxcoavs 6&lt;br/&gt;kdxlespl 0&lt;br/&gt;kdxlende 0&lt;br/&gt;kdxlenxt 75520140=0x480588c&lt;br/&gt;kdxleprv 75520138=0x480588a&lt;br/&gt;kdxledsz 0&lt;br/&gt;kdxlebksz 8036&lt;br/&gt;row#0[8022] flag: ------, lock: 0, len=14     &amp;lt;=== length is 14 bytes for the index row entry&lt;br/&gt;col 0; len 4; (4):  c3 60 61 1c&lt;br/&gt;col 1; len 6; (6):  04 80 50 3c 01 06         &amp;lt;=== rowid is stored as a second column for the index row entry&lt;br/&gt;row#1[8008] flag: ------, lock: 0, len=14&lt;br/&gt;col 0; len 4; (4):  c3 60 61 1d&lt;br/&gt;col 1; len 6; (6):  04 80 50 3c 01 07&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; non-unique index将 rowid 作为一个字段和数据字段组合成一个“唯一、复合”索引，而unique index的结构如下：&lt;/p&gt;Leaf block dump&lt;br/&gt;===============&lt;br/&gt;header address 143336028=0x88b225c&lt;br/&gt;kdxcolev 0&lt;br/&gt;KDXCOLEV Flags = - - -&lt;br/&gt;kdxcolok 0&lt;br/&gt;kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y&lt;br/&gt;kdxconco 1&lt;br/&gt;kdxcosdc 0&lt;br/&gt;kdxconro 533&lt;br/&gt;kdxcofbo 1102=0x44e&lt;br/&gt;kdxcofeo 1112=0x458&lt;br/&gt;kdxcoavs 10&lt;br/&gt;kdxlespl 0&lt;br/&gt;kdxlende 0&lt;br/&gt;kdxlenxt 75527436=0x480750c&lt;br/&gt;kdxleprv 75527434=0x480750a&lt;br/&gt;kdxledsz 6&lt;br/&gt;kdxlebksz 8036&lt;br/&gt;row#0[8023] flag: ------, lock: 0, len=13, data:(6):  04 80 5e 34 02 82    &amp;lt;=== length is 13 byes and rowid not stored as a second column entry&lt;br/&gt;col 0; len 4; (4):  c3 60 30 2c&lt;br/&gt;row#1[8010] flag: ------, lock: 0, len=13, data:(6):  04 80 5e 34 02 83&lt;br/&gt;col 0; len 4; (4):  c3 60 30 2d&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 从dump文件中可以看到结构不同导致index中的entry的长度是不一样的，unique index稍稍短一点，所以每个block可以容纳更多的index entry，从宏观来看unique index更小一点。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/killkill/aggbug/2029818.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/04/26/2029818.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/killkill/archive/2011/04/22/2024417.html</id><title type="text">[摘]Oracle限制某个数据库帐号只能在特定机器上连入数据库</title><summary type="text"/><published>2011-04-21T16:34:00Z</published><updated>2011-04-21T16:34:00Z</updated><author><name>killkill</name><uri>http://www.cnblogs.com/killkill/</uri></author><link rel="alternate" href="http://www.cnblogs.com/killkill/archive/2011/04/22/2024417.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/killkill/archive/2011/04/22/2024417.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 逛&lt;a href="http://www.itpub.net/thread-1421297-1-1.html" target="_blank"&gt;论坛&lt;/a&gt;的时候发现一个好脚本，记录下来以备日后有用：&lt;/p&gt;  CREATE OR REPLACE TRIGGER sys.trg_work_log&lt;br/&gt;AFTER LOGON ON DATABASE&lt;br/&gt;declare&lt;br/&gt;v_program_name varchar2(200);&lt;br/&gt;v_username varchar2(100);&lt;br/&gt;v_ip varchar2(18);&lt;br/&gt;v_error varchar2(1000);&lt;br/&gt;begin&lt;br/&gt;select username,program,SYS_CONTEXT('USERENV','IP_ADDRESS')   &lt;br/&gt;into v_username,v_program_name,v_ip&lt;br/&gt;from sys.v_$session where AUDSID = SYS_CONTEXT('USERENV', 'SESSIONID');&lt;br/&gt;if (upper(v_username)='TEST') then&lt;br/&gt;  if (UPPER(v_program_name) = 'SQLPLUS.EXE') then&lt;br/&gt;     if (v_ip = ('10.142.244.30')) then&lt;br/&gt;       RAISE_APPLICATION_ERROR(-20001,'You are not allowed to connect to the database,err01');&lt;br/&gt;         &lt;br/&gt;    end if;&lt;br/&gt;  ELSE&lt;br/&gt;     RAISE_APPLICATION_ERROR(-20001,'不能使用sqlplus登陸');&lt;br/&gt;        &lt;br/&gt;  end if;&lt;br/&gt;else&lt;br/&gt;   RAISE_APPLICATION_ERROR(-20001,'You are not allowed to connect to the database');&lt;br/&gt;   &lt;br/&gt;end if;&lt;br/&gt;&lt;br/&gt;END ;&lt;br/&gt;/&lt;img src="http://www.cnblogs.com/killkill/aggbug/2024417.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/killkill/archive/2011/04/22/2024417.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
