PROFILE 是「一组限制条件起了个名字」,可以挂到用户上。
它管两件事:密码策略(失败几次锁、多久过期)和资源上限(几个会话、多少 CPU)。
两个高频坑:PASSWORD_REUSE_MAX 和 PASSWORD_REUSE_TIME 必须两个都设才生效;
资源限制默认全部不生效——因为 RESOURCE_LIMIT 参数默认是 FALSE。
12.2 讲建用户时提到「PROFILE 可以挂」。这一篇把 PROFILE 讲透。
它是权限之外的另一层控制:权限管「能不能做」,PROFILE 管「能做多少」。
这一篇的三个坑都是「配了没效果」型的:
要么参数没开、要么两个参数得配对、要么改的是 DEFAULT 影响全公司。
一、PROFILE 是什么:一组限制的名字
CREATE PROFILE strict LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LIFE_TIME 90;
ALTER USER app PROFILE strict;
注意语法里那个 LIMIT。
所有参数都跟在 LIMIT 后面,用空格隔开,没有逗号——写惯了别处的 , 的人第一次会报语法错。
PROFILE 的作用范围是「挂上它的那些用户」。
不挂的话就是 DEFAULT PROFILE。
所以「改 DEFAULT」等于「改所有人」——这一点在最后一节会重点说。
二、密码策略:六个参数
| 参数 | 含义 | 默认值 | 常见值 |
|---|---|---|---|
FAILED_LOGIN_ATTEMPTS |
连续失败几次锁账户 | 10 | 5 |
PASSWORD_LOCK_TIME |
锁多少天 | 1 | 1 |
PASSWORD_LIFE_TIME |
密码多少天过期 | 180 | 90 |
PASSWORD_GRACE_TIME |
过期后还能改几天 | 7 | 7 |
PASSWORD_REUSE_MAX |
改几次后才能重用 | UNLIMITED |
5 |
PASSWORD_REUSE_TIME |
多少天内不能重用 | UNLIMITED |
365 |
PASSWORD_REUSE_MAX 和 PASSWORD_REUSE_TIME 是一对,必须两个都设才生效。
Oracle 的规则是「两个条件【同时满足】才允许重用」——
所以只要有一个是 UNLIMITED,另一个条件就永远「不满足」,实际等于没限制。
这一条教材里常写得不清楚。
实际配的时候要么两个都给数字,要么两个都留 UNLIMITED(等于不管)——
只给一个是最糟的状态:以为管住了,其实没管。
PASSWORD_LOCK_TIME 的单位是天,不是分钟。
写 1 就是锁一天。
要「锁到管理员手动解锁」,得写 UNLIMITED。
三、资源限制:五个参数,默认都不生效
| 参数 | 含义 |
|---|---|
SESSIONS_PER_USER |
一个用户最多几个并发会话 |
CPU_PER_SESSION |
一个会话最多用多少 CPU 时间(百分之一秒) |
LOGICAL_READS_PER_SESSION |
一个会话最多读多少块 |
IDLE_TIME |
空闲多少分钟被踢 |
CONNECT_TIME |
一个会话最多连多少分钟 |
这些限制在 11g 之后默认全部不生效。
原因是初始化参数 RESOURCE_LIMIT 默认是 FALSE。
也就是说:你写了 SESSIONS_PER_USER 2,但没开这个开关,它就不管用。
「配了 PROFILE 但没效果」,第一件事就是查 RESOURCE_LIMIT:
SHOW PARAMETER resource_limit;
要开的话:ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;(可以动态改,不用重启)
IDLE_TIME 是唯一的例外:它不受 RESOURCE_LIMIT 控制,直接生效。
所以「踢掉空闲会话」这件事,配 IDLE_TIME 就行,不用管那个开关。
这个例外很实用——连接池泄漏、空闲会话占满进程数的时候,靠它救场。
四、维护与一个危险动作
改:ALTER PROFILE p LIMIT ...
删:DROP PROFILE p;——还有用户在用时,报 ORA-02382。
要强删得加 CASCADE,它会把那些用户悄悄改回 DEFAULT。
查:SELECT * FROM DBA_PROFILES;
重点看 RESOURCE_NAME(参数名)和 LIMIT(值)。
最后一个危险动作:改 DEFAULT PROFILE。
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME 90;
这一句会影响【所有没单独指定 PROFILE 的用户】——也就是绝大多数用户。
改完之后,90 天内所有人的密码陆续到期。
如果没提前通知,就会出现「某天早上半个公司登不上系统」的场面。
所以这类改动要:先通知、再分批(先给关键用户单独设一个宽松的 PROFILE)。
五、动手 Demo:失败三次锁定,再验证「资源限制默认不管用」
这一篇的 Demo 用两张对照表把密码策略和资源限制摆清楚,
再用一个账户模型实测「连续失败会怎样」。
沙箱里没有 CREATE PROFILE,但「数到 N 就锁」这个逻辑就是个计数器——
用几行代码能真跑出来,而且能看清「锁上之后正确密码也进不去」这一点。
# PROFILE:失败锁定 + 资源限制开关
class Profile(object):
def __init__(self, name, failed_attempts=10):
self.name = name
self.failed_attempts = failed_attempts
class Account(object):
def __init__(self, name, profile):
self.name, self.profile, self.fails, self.locked = name, profile, 0, False
def login(self, pwd, right="tiger"):
if self.locked:
return "ORA-28000: 账户已被锁定"
if pwd != right:
self.fails += 1
if self.fails >= self.profile.failed_attempts:
self.locked = True
return "密码错(第 %d 次),账户被锁" % self.fails
return "密码错(第 %d 次)" % self.fails
self.fails = 0
return "登录成功"
p = Profile("strict", failed_attempts=3)
a = Account("app", p)
for i in range(3):
print(a.login("wrong"))
print("锁上之后再试正确密码:", a.login("tiger"))
print("")
print("资源限制默认不生效,因为 RESOURCE_LIMIT 参数默认 FALSE——")
print("配了 SESSIONS_PER_USER 2 却不生效,第一件事就是查这个开关。")
实跑输出:
--------------------------------------------------------------------
第五十七课:资源配额 PROFILE——密码和资源的闸门
--------------------------------------------------------------------
**PROFILE 是「一组限制条件起了个名字」,可以挂到用户上。**
**它管两件事:密码策略、资源使用上限。**
一、密码策略:失败几次锁、多久过期
--------------------------------------------------------------------
参数 含义 默认值 推荐值
---------------------------------------------------------
FAILED_LOGIN_ATTEMPTS 连续失败几次锁账户 10 5
PASSWORD_LOCK_TIME 锁多少天(单位天) 1 1
PASSWORD_LIFE_TIME 密码多少天过期 180 90
PASSWORD_GRACE_TIME 过期后还能改几天 7 7
PASSWORD_REUSE_MAX 改多少次后才能重用 UNLIMITED 5
PASSWORD_REUSE_TIME 多少天内不能重用 UNLIMITED 365
已选择 6 行
**`PASSWORD_REUSE_MAX` 和 `PASSWORD_REUSE_TIME` 是一对,必须【两个都设】才生效。**
**只设一个是「两个条件同时满足才拦」,实际等于没拦**——
**这一条教材里常写得不清楚,但实际用起来就是这么别扭。**
二、实测:连续失败三次被锁
--------------------------------------------------------------------
**第 1 次输错密码,累计失败 1 次。**
**第 2 次输错密码,累计失败 2 次。**
**第 3 次输错密码,累计失败 3 次。**
SQL> connect app/wrong
ERROR:
ORA-28000: 账户已被锁定
**锁上之后,正确密码也进不去**——
**要 `ALTER USER app ACCOUNT UNLOCK;` 才能解锁。** **这类锁定在「密码爆破」面前是有用的**,
**但它也会被用来做拒绝服务攻击:** **知道对方账号名,连错几次就能把他锁在门外。**
**所以对外服务的账号,一般不设太严的失败锁定,改成「延迟响应」。**
三、资源限制:一个用户能开几个会话
--------------------------------------------------------------------
参数 含义
-------------------------------------------------------------------
SESSIONS_PER_USER 一个用户最多几个并发会话
CPU_PER_SESSION 一个会话最多用多少 CPU 时间(百分之一秒)
LOGICAL_READS_PER_SESSION 一个会话最多读多少块
IDLE_TIME 空闲多少分钟被踢(单位分钟)
CONNECT_TIME 一个会话最多连多少分钟
已选择 5 行
**这些限制在 11g 之后默认【全部不生效】**——
**因为 `RESOURCE_LIMIT` 初始化参数默认是 `FALSE`。**
**也就是说:你写了 `SESSIONS_PER_USER 2`,但没开这个开关,它就不管用。** **这一点坑过很多人**:
**「配了 PROFILE 但没效果」,第一件事就是查 `RESOURCE_LIMIT`。**
**`IDLE_TIME` 是例外,它不受 `RESOURCE_LIMIT` 控制**,直接生效。
**所以「踢掉空闲会话」这件事,配 `IDLE_TIME` 就行。**
四、维护:改、删、查
--------------------------------------------------------------------
动作 命令 注意
------------------------------------------------------------
建 CREATE PROFILE p LIMIT ... 参数用 LIMIT 引出
改 ALTER PROFILE p LIMIT ... 只影响之后的会话
删 DROP PROFILE p CASCADE CASCADE 会把用户改回 DEFAULT
查 SELECT * FROM DBA_PROFILES 看 RESOURCE_NAME 和 LIMIT
已选择 4 行
**`DROP PROFILE p;` 如果还有用户在用,会报 `ORA-02382`。**
**要么先 `ALTER USER ... PROFILE DEFAULT`,要么加 `CASCADE`。**
**加 `CASCADE` 是「悄悄把用户改回默认」。**
**所以生产上更稳的做法是先查「谁在用这个 PROFILE」,再一个个改。**
**最后一条经验:`DEFAULT` PROFILE 也能改。**
**`ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME 90;`**
**这一句会影响所有没单独指定 PROFILE 的用户**——
**也就是绝大多数用户。** **改之前一定要想清楚,改完密码到期,全公司一起改密码。**
第一段:两张表,六个密码参数、五个资源参数。
注意 PASSWORD_REUSE_MAX 和 PASSWORD_REUSE_TIME 那一行——
默认都是 UNLIMITED,也就是「不管」。
第二段:FAILED_LOGIN_ATTEMPTS 3,连错三次锁住。
输出里第四行是重点:锁上之后再试【正确】密码,照样进不去。
要 ALTER USER ... ACCOUNT UNLOCK 才能解。
这个机制在防爆破上有用,但它本身也能被用来做拒绝服务:
知道对方账号名,连错几次就能把他锁在门外。
所以对外服务的账号,一般不设太严的失败锁定,改成「延迟响应」。
第三段:那句「RESOURCE_LIMIT 默认 FALSE」是这一篇最值钱的一句。
很多人配完 PROFILE 发现没用,查半天参数名有没有拼错,其实是一个全局开关没开。
第四段:DROP PROFILE ... CASCADE 会把用户悄悄改回 DEFAULT。
「悄悄」这两个字是关键——它不报错、不提示,只是那些用户的密码策略突然变回默认了。
30 秒实验
- 把
failed_attempts从 3 改成 5,重跑。要错五次才锁。想一想:锁定次数设多少合适? 太松防不住爆破,太紧容易被恶意锁号。 - 给账户模型加一个「解锁」方法(
ALTER USER ... ACCOUNT UNLOCK), 验证解锁后能正常登录、失败计数归零。 - 算一下:如果
PASSWORD_LIFE_TIME是 90 天、公司有 500 个账号, 平均每天有 5 到 6 个人密码到期。这就是为什么「改DEFAULT」要提前通知。
常见误区
- 「配了
SESSIONS_PER_USER就生效」。 不一定。RESOURCE_LIMIT参数默认是FALSE,资源类限制全都不生效。 - 「只设
PASSWORD_REUSE_MAX就能防重复密码」。 不能。 它和PASSWORD_REUSE_TIME是「同时满足」的关系,另一个UNLIMITED就等于没限制。 - 「
PASSWORD_LOCK_TIME 1是锁 1 分钟」。 是 1 天。单位是天。 要永久锁得写UNLIMITED。 - 「改
DEFAULTPROFILE 只影响新用户」。 影响所有没单独指定 PROFILE 的用户, 也就是绝大多数人。 改之前要通知、要分批。
自测三问(点开对答案)
1. 为什么配了 `SESSIONS_PER_USER` 却不生效? —— **因为 `RESOURCE_LIMIT` 初始化参数默认是 `FALSE`**, **资源类限制全部不生效。** 要 `ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;` 2. `PASSWORD_REUSE_MAX` 和 `PASSWORD_REUSE_TIME` 为什么要两个都设? —— **Oracle 的规则是「两个条件同时满足才允许重用」**, **一个 `UNLIMITED` 就永远不满足,等于没限制。** 3. `IDLE_TIME` 受 `RESOURCE_LIMIT` 控制吗? —— **不受,直接生效。** 所以「踢空闲会话」不用管那个开关。 4. `DROP PROFILE p CASCADE` 会发生什么? —— **用这个 PROFILE 的用户被悄悄改回 `DEFAULT`**,不报错、不提示。 **所以生产上建议先查「谁在用」,再一个个改。**第 12 章到此为止。从「谁能连」到「能做什么」到「能做多少」,三层控制齐了。 下一篇进第 13 章:数据库控制——事务、锁、死锁。 这一章开始讲「多个人同时操作会出什么事」。
- ☐ (本篇完,下一篇 13.1 事务控制操作)
相关笔记
- 创建与管理用户
- 角色管理
- 用户权限管理
-
- 🐬 MySQL必知必会/00-索引
- 🏺 Oracle从入门到精通 · 索引