Oracle 10g用户频繁被锁(ORA-28000)的诊断与处理
今天早上同事向我求助,说是一个用户(我们假设该用户名为HOEGH)的数据不是最新的。奇怪,我明明上周五统一使用exp、imp脚本更新了相关用户的数据,肯定是包含HOEGH用户的。同事把应用程序启动起来,指着程序界面告诉我,这个数据肯定不是最新的。好吧,难道是我当时更新数据时漏掉了HOEGH用户?
首先,我尝试登录PLSQL,想查询一下HOEGH用户下表的编译时间,确认一下我执行imp操作的具体时间。令人意外的是,使用PLSQL登录时报错了,提示“ORA-28000: the account is locked”。
有点晕,谁动了HOEGH用户?
我登陆到sys用户,通过下面的sql语句查询HOEGH用户的帐户状态以及锁定时间。
SQL> select username,account_status,to_char(lock_date,'yyyymmdd hh24:mi:ss') from dba_users where username='HOEGH';
USERNAME ACCOUNT_STATUS TO_CHAR(LOCK_DATE
------------------------------ -------------------------------- -----------------
HOEGH LOCKED 20150817 08:57:54
SQL>
从查询结果来看,HOEGH用户确实被锁了,而且,锁定操作就发生在几分钟之前。
虽然没弄明白怎么回事,还是先把问题解决了再说吧。我使用“alter user HOEGH account unlock”语句把HOEGH用户解锁,然后登录PLSQL,查询HOEGH用户下表的编译时间。结果证明我周五执行数据更新并没有遗漏HOEGH用户,所有表的编译时间都是上周五。
我怀疑是不是刚才启动的程序版本有问题。于是,我让同事重新运行应用程序,显示的界面仍然不是最新数据,问题依旧。
好吧,解决问题要紧!我重新执行了一次导入脚本,脚本先对所有表执行truncate操作,然后执行imp进行数据导入。没想到执行imp操作时再次报错,提示“ORA-28000: the account is locked”。
HOEGH用户被锁定了,again!
没想明白。
再次使用“alter user HOEGH account unlock”语句把HOEGH用户解锁,重新执行导入脚本,这次数据顺利导入成功。
这次总该没问题了吧。让同事第三次启动应用程序,问题依旧!!!
通常来说,程序不会出错,肯定有其他问题。
果然,过了一会,同事不好意思的告诉我,密码不小心配错了,改过来就OK了。
这个原因我还真没想到,问题弄清楚了就好,谁都有打盹的时候嘛。
可是,为什么HOEGH用户会被一而再地锁定呢?估计也和错误密码有关,最直接的就是Oracle数据库的安全策略。于是,我执行以下语句来查询:
SQL>
SQL> select * from dba_profiles where resource_name like 'FAILED_LOGIN_ATTEMPTS%';
PROFILE RESOURCE_NAME RESOURCE LIMIT
------------------------------ -------------------------------- -------- --------------------------------
DEFAULT FAILED_LOGIN_ATTEMPTS PASSWORD 10
MONITORING_PROFILE FAILED_LOGIN_ATTEMPTS PASSWORD UNLIMITED
SQL>
其中,FAILED_LOGIN_ATTEMPTS参数被设置为10,也就是说当输错密码登陆超过次10次,用户就会自动被锁定。结合我们应用程序的设计思路,它会定时去连接数据库以监视数据库连接状态;导致这个错误的原因就是由于客户端由于没有使用正确的密码,连接次数超过数据库默认安全策略中定义的FAILED_LOGIN_ATTEMPTS参数大小。至于为什么会一直显示老版本数据,是因为Oracle数据库连不上,本地数据无法更新,界面显示只好去读老版本的本地数据。
另外,在Oracle10g中,FAILED_LOGIN_ATTEMPTS参数默认值为10,这个设置其实是有隐患的。如果有一个用户不停尝试错误口令,那就会导致用户被锁。如果要恢复之前无限制,可以通过一条命令解决:
alter profile default limit FAILED_LOGIN_ATTEMPTS unlimited;
今天解决这个故障得到以下启示:
1.一定要细心,抓住一切可以利用的资源去进行trouble-shooting;因为,我们的应用程序界面就有数据库连接状态的提示(字比较小),当时竟给忽略了;
2.规范项目开发管理,降低类似配置文件出错的概率;