Mysql权限系统工作原理

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

MySQL权限系统保证所有的用户可以严格地做他们假定被允许做的事情。当你连接一个MySQL服务器时, 你的身份由你从那连接的主机和你指定的用户名来决定,系统根据你的身份和你想做什么来授予权限。

MySQL在认定身份中考虑你的主机名和用户名字,是因为有很小的原因假定一个给定的用户在因特网上属于同一个人。例如,用户从whitehouse.gov连接的bill不必和从mosoft.com连接bill是同一个人。 MySQL通过允许你区分在不同的主机上碰巧有同样名字用户来处理它:你可以对从whitehouse.gov连接授与bill一个权限集,而为从microsoft.com的连接授予一个不同的权限集。

MySQL存取控制包含2个阶段:

阶段1:服务器检查你是否允许连接。

阶段2:假定你能连接,服务器检查你发出的每个请求。看你是否有足够的权限实施它。例如,如果你从数据库中一个表精选(select)行或从数据库抛弃一个表,服务器确定你对表有select权限或对数据库有drop权限。

服务器在存取控制的两个阶段使用在mysql的数据库中的user、db和host表,在这些授权表中字段如下:

表名称  user  db  host  
范围字段  Host  Host  Host  
User  Db  Db  
Password  User   
权限字段  Select_priv  Select_priv  Select_priv  
Insert_priv  Insert_priv  Insert_priv  
Update_priv  Update_priv  Update_priv  
Delete_priv  Delete_priv  Delete_priv  
Index_priv  Index_priv  Index_priv  
Alter_priv  Alter_priv  Alter_priv  
Create_priv  Create_priv  Create_priv  
Drop_priv  Drop_priv  Drop_priv  
Grant_priv  Grant_priv  Grant_priv  
Reload_priv    
Shutdown_priv    
Process_priv    
File_priv   

对存取控制的第二阶段(请求证实),如果请求涉及表,服务器可以另外参考tables_priv和columns_priv表。这些表的字段如下:

表名称 tables_priv  columns_priv  
范围字段  Host  Host  
Db  Db  
User  User  
Table_name  Table_name  
  Column_name  
权限字段  Table_priv  Column_priv  
Column_priv   
其他字段  Timestamp  Timestamp  
Grantor  

每个授权表包含范围字段和权限字段。

范围字段决定表中每个条目的范围,即,条目适用的上下文。例如, 一个user表条目的Host和User值为''thomas.loc.gov''和''bob''将被用于证实来自主机thomas.loc.gov的bob对服务器的连接。同样,一个db表条目的Host、User和Db字段的值是''thomas.loc.gov''、''bob''和''reports''将用在bob从主机联接thomas.loc.gov存取reports数据库的时候。 tables_priv和columns_priv表包含范围字段,指出每个条目适用的表或表/列的组合。

对于检查存取的用途,比较Host值是忽略大小写的。User、Password、Db和Table_name值是区分大小写的。Column_name值在MySQL3.22.12或以后版本是忽略大小写的。

权限字段指出由一个表条目授予的权限,即,可实施什么操作。服务器组合各种的授权表的信息形成一个用户权限的完整描述。为此使用的规则在6.8 存取控制, 阶段2:请求证实描述。

范围字段是字符串,如下所述;每个字段的缺省值是空字符串:

字段名  类型  
Host  CHAR(60)  
User  CHAR(16)  
Password  CHAR(16)  
Db  CHAR(64)  (tables_priv和columns_priv表为CHAR(60))

在user、db和host表中,所有权限字段被声明为ENUM(''N'',''Y'')--每一个都可有值''N''或''Y'',并且缺省值是''N''.

在tables_priv和columns_priv表中,权限字段被声明为SET字段:

表名  字段名  可能的集合成员  
tables_priv  Table_priv  ''Select'', ''Insert'', ''Update'', ''Delete'', ''Create'', ''Drop'', ''Grant'', ''References'', ''Index'', ''Alter''  
tables_priv  Column_priv  ''Select'', ''Insert'', ''Update'', ''References''  
columns_priv  Column_priv  ''Select'', ''Insert'', ''Update'', ''References'' 

简单地说,服务器使用这样的授权表:

user表范围字段决定是否允许或拒绝到来的连接。对于允许的连接,权限字段指出用户的全局(超级用户)权限。

db和host表一起使用:

db表范围字段决定用户能从哪个主机存取哪个数据库。权限字段决定允许哪个操作。

当你想要一个给定的db条目应用于若干主机时,host表作为db表的扩展被使用。例如,如果你想要一个用户能在你的网络从若干主机使用一个数据库,在用户的db表的Host条目设为空值,然后将那些主机的每一个移入host表。这个机制详细描述在6.8 存取控制, 阶段2:请求证实。

tables_priv和columns_priv表类似于db表,但是更精致:他们在表和列级应用而非在数据库级。

注意管理权限(reload, shutdown, 等等)仅在user表中被指定。这是因为管理性操作是服务器本身的操作并且不是特定数据库,因此没有理由在其他授权表中列出这样的权限。事实上,只需要请教user表来决定你是否执行一个管理操作。

file权限也仅在user表中指定。它不是管理性权限,但你读或谢在服务器主机上的文件的的能力独立于你正在存取的数据库。

当mysqld服务器启动时,读取一次授权

MySQL教程是:Mysql权限系统工作原理。表内容。对授权表的更改生效在6.9 权限更改何时生效描述。

当你修改授权表的内容时,确保你按你想要的方式更改权限设置是一个好主意。为帮助诊断问题,见6.13 “存取拒绝引起”错误的原因。对于安全问题上的忠告,见6.14 怎么对使MySQL安全对抗解密高手。

一个有用的诊断工具是mysqlaccess脚本,由Carlier Yves 提供给MySQL分发。使用--help选项调用mysqlaccess查明它怎样工作。注意:mysqlaccess仅用user、db和host表仅检查存取。它不检查表或列级权限。

6.7 存取控制, 阶段1:连接证实

当你试图联接一个MySQL服务器时,服务器基于你的身份和你是否能通过供应正确的口令验证身份来接受或拒绝连接。如果不是,服务器完全具结你的存取,否则,服务器接受连接,然后进入阶段2并且等待请求。

你的身份基于2个信息:

你从那个主机连接

你的MySQL用户名

身份检查使用3个user表(Host, User和Password)范围字段执行。服务器只有在一个user表条目匹配你的主机名和用户名并且你提供了正确的口令时才接受连接。

在user表范围字段可以如下被指定:

一个Host值可以是主机名或一个IP数字,或''localhost''指出本地主机。

你可以在Host字段里使用通配符字符“%”和“_”。

一个Host值''%''匹配任何主机名,一个空白Host值等价于''%''。注意这些值匹配能创建一个连接到你的服务器的任何主机! 
通配符字符在User字段中不允许,但是你能指定空白的值,它匹配任何名字。如果user表匹配到来的连接的条目有一个空白的用户名,用户被认为是匿名用户(没有名字的用户),而非客户实际指定的名字。这意味着一个空白的用户名被用于在连接期间的进一步的存取检查(即,在阶段2期间)。

Password字段可以是空白的。这不意味着匹配任何口令,它意味着用户必须不指定一个口令进行连接。

非空白Password值代表加密的口令。 MySQL不以任何人可以看的纯文本格式存储口令,相反,正在试图联接的一个用户提供的口令被加密(使用PASSWORD()函数),并且与存储了user表中的已经加密的版本比较。如果他们匹配,口令是正确的。

下面的例子显示出各种user表中Host和User条目的值的组合如何应用于到来的连接:

Host 值  User 值  被条目匹配的连接  
''thomas.loc.gov''  ''fred''  fred, 从thomas.loc.gov 连接 
''thomas.loc.gov''  ''''  任何用户, 从thomas.loc.gov连接  
''%''  ''fred''  fred, 从任何主机连接 
''%''  ''''  任何用户, 从任何主机连接 
''%.loc.gov''  ''fred''  fred, 从在loc.gov域的任何主机连接 
''x.y.%''  ''fred''  fred, 从x.y.net、x.y.com,x.y.edu等联接。(这或许无用) 
''144.155.166.177''  ''fred''  fred, 从有144.155.166.177 IP 地址的主机连接 
''144.155.166.%''  ''fred''  fred, 从144.155.166 C类子网的任何主机连接

既然你能在Host字段使用IP通配符值(例如,''144.155.166.%''匹配在一个子网上的每台主机),有可能某人可能企图探究这种能力,通过命名一台主机为144.155.166.somewhere.com。为了阻止这样的企图,MySQL不允许匹配以数字和一个点起始的主机名,这样,如果你用一个命名为类似1.2.foo.com的主机,它的名字决不会匹配授权表中Host列。只有一个IP数字能匹配IP通配符值。

一个到来的连接可以被在user表中的超过一个条目匹配。例如,一个由fred从thomas.loc.gov的连接匹配多个条目如上所述。如果超过一个匹配,服务器怎么选择使用哪个条目呢?服务器在启动时读入user表后通过排序来解决这个问题,然后当一个用户试图连接时,以排序的顺序浏览条目,第一个匹配的条目被使用。

user表排序工作如下,假定user表看起来像这样:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

当服务器在表中读取时,它以最特定的Host值为先的次序排列(''%''在Host列里意味着“任何主机”并且是最不特定的)。有相同Host值的条目以最特定的User值为先的次序排列(一个空白User值意味着“任何用户”并且是最不特定的)。最终排序的user表看起来像这样:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

当一个连接被尝试时,服务器浏览排序的条目并使用找到的第一个匹配。对于由jeffrey从localhost的一个连接,在Host列的''localhost''条目首先匹配。那些有空白用户名的条目匹配连接的主机名和用户名。(''%''/''jeffrey''条目也将匹配,但是它不是在表中的第一匹配。)

这是另外一个例子。假定user桌子看起来像这样:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-

排序后的表看起来像这样:

+---------------

MySQL教程是:Mysql权限系统工作原理。-+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

一个由jeffrey从thomas.loc.gov的连接被第一个条目匹配,而一个由jeffrey从whitehouse.gov的连接被第二个匹配。

普遍的误解是认为,对一个给定的用户名,当服务器试图对连接寻找匹配时,明确命名那个用户的所有条目将首先被使用。这明显不是事实。先前的例子说明了这点,在那里一个由jeffrey从thomas.loc.gov的连接没被包含''jeffrey''作为User字段值的条目匹配,但是由没有用户名的题目匹配!

如果你有服务器连接的问题,打印出user表并且手工排序它看看第一个匹配在哪儿进行。

6.8 存取控制,阶段2:请求证实

一旦你建立了一个连接,服务器进入阶段2。对在此连接上进来的每个请求,服务器检查你是否有足够的权限来执行它,它基于你希望执行的操作类型。这正是在授权表中的权限字段发挥作用的地方。这些权限可以来子user、db、host、tables_priv或columns_priv表的任何一个。授权表用GRANT和REVOKE命令操作。见7.26 GRANT和REVOKE 句法。(你可以发觉参考6.6 权限系统怎样工作很有帮助,它列出了在每个权限表中呈现的字段。)

user表在一个全局基础上授予赋予你的权限,该权限不管当前的数据库是什么均适用。例如,如果user表授予你delete权限, 你可以删除在服务器主机上从任何数据库删除行!换句话说,user表权限是超级用户权限。只把user表的权限授予超级用户如服务器或数据库主管是明智的。对其他用户,你应该把在user表中的权限设成''N''并且仅在一个特定数据库的基础上授权, 使用db和host表。

db和host表授予数据库特定的权限。在范围字段的值可以如下被指定:

通配符字符“%”和“_”可被用于两个表的Host和Db字段。

在db表的''%''Host值意味着“任何主机”,在db表中一个空白Host值意味着“对进一步的信息咨询host表”。

在host表的一个''%''或空白Host值意味着“任何主机”。

在两个表中的一个''%''或空白Db值意味着“任何数据库”。

在两个表中的一个空白User值匹配匿名用户。

db和host表在服务器启动时被读取和排序(同时它读user表)。db表在Host、Db和User范围字段上排序,并且host表在Host和Db范围字段上排序。对于user表,排序首先放置最特定的值然后最后最不特定的值,并且当服务器寻找匹配入条目时,它使用它找到的第一个匹配。

tables_priv和columns_priv表授予表和列特定的权限。在范围字段的值可以如下被指定:

通配符“%”和“_”可用在使用在两个表的Host字段。

在两个表中的一个''%''或空白Host意味着“任何主机”。

在两个表中的Db、Table_name和Column_name字段不能包含通配符或空白。

tables_priv和columns_priv表在Host、Db和User字段上被排序。这类似于db表的排序,尽管因为只有Host字段可以包含通配符,但排序更简单。

请求证实进程在下面描述。(如果你熟悉存取检查的源代码,你会注意到这里的描述与在代码使用的算法略有不同。描述等价于代码实际做的东西;它只是不同于使解释更简单。)

对管理请求(shutdown、reload等等),服务器仅检查user表条目,因为那是唯一指定管理权限的表。如果条目许可请求的操作,存取被授权了,否则拒绝。例如,如果你想要执行mysqladmin shutdown,但是你的user表条目没有为你授予shutdown权限,存取甚至不用检查db或host表就被拒绝。(因为他们不包含Shutdown_priv行列,没有这样做的必要。)

对数据库有关的请求(insert、update等等),服务器首先通过查找user表条目来检查用户的全局(超级用户)权限。如果条目允许请求的操作,存取被授权。如果在user表中全局权限不够,服务器通过检查db和host表确定特定的用户数据库权限:

服务器在db表的Host、Db和User字段上查找一个匹配。 Host和User对应连接用户的主机名和MySQL用户名。Db字段对应用户想要存取的数据库。如果没有Host和User的条目,存取被拒绝。

如果db表中的条目有一个匹配而且它的Host字段不是空白的,该条目定义用户的数据库特定的权限。

如果匹配的db表的条目的Host字段是空白的,它表示host表列举主机应该被允许存取数据库的主机。在这种情况下,在host表中作进一步查找以发现Host和Db字段上的匹配。如果没有host表条目匹配,存取被拒绝。如果有匹配,用户数据库特定的权限以在db和host表的条目的权限,即在两个条目都是''Y''的权限的交集(而不是并集!)计算。(这样你可以授予在db表条目中的一般权限,然后用host表条目按一个主机一个主机为基础地有选择地限制它们。)

在确定了由db和host表条目授予的数据库特定的权限后,服务器把他们加到由user表授予的全局权限中。如果结果允许请求的操作,存取被授权。否则,服务器检查在tables_priv和columns_priv表中的用户的表和列权限并把它们加到用户权限中。基于此结果允许或拒绝存取。

用布尔术语表示,前面关于一个用户权限如何计算的描述可以这样总结:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

它可能不明显,为什么呢,如果全局user条目的权限最初发现对请求的操作不够,服务器以后把这些权限加到数据库、表和列的特定权限。原因是一个请求可能要求超过一种类型的权限。例如,如果你执行一个INSERT ... SELECT语句,你就都要insert和select权限。你的权限必须如此以便user表条目授予一个权限而db表条目授予另一个。在这种情况下,你有必要的权限执行请求,但是服务器不能自己把两个表区别开来;两个条目授予的权限必须组合起来。

host表能被用来维护一个“安全”服务器列表。在TcX,host表包含一个在本地的网络上所有的机器的表,这些被授予所有的权限。

你也可以使用host表指定不安全的主机。假定你有一台机器public.your.domain,它位于你不认为是安全的一个公共区域,你可以用下列的host表条目子允许除了那台机器外的网络上所有主机的存取:

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (所有权限设为 ''N'')
| %.your.domain      | %  | ... (所有权限设为 ''Y'')
+--------------------+----+-

当然,你应该总是测试你在授权表中的条目(例如,使用mysqlaccess)让你确保你的存取权限实际上以你认为的方式被设置.


本文转自holy2009 51CTO博客,原文链接:http://blog.51cto.com/holy2010/370154

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
27天前
|
自然语言处理 搜索推荐 关系型数据库
MySQL实现文档全文搜索,分词匹配多段落重排展示,知识库搜索原理分享
本文介绍了在文档管理系统中实现高效全文搜索的方案。为解决原有ES搜索引擎私有化部署复杂、运维成本高的问题,我们转而使用MySQL实现搜索功能。通过对用户输入预处理、数据库模糊匹配、结果分段与关键字标红等步骤,实现了精准且高效的搜索效果。目前方案适用于中小企业,未来将根据需求优化并可能重新引入专业搜索引擎以提升性能。
|
1月前
|
关系型数据库 MySQL Linux
MySQL原理简介—6.简单的生产优化案例
本文介绍了数据库和存储系统的几个主题: 1. **MySQL日志的顺序写和数据文件的随机读指标**:解释了磁盘随机读和顺序写的原理及对数据库性能的影响。 2. **Linux存储系统软件层原理及IO调度优化原理**:解析了Linux存储系统的分层架构,包括VFS、Page Cache、IO调度等,并推荐使用deadline算法优化IO调度。 3. **数据库服务器使用的RAID存储架构**:介绍了RAID技术的基本概念及其如何通过多磁盘阵列提高存储容量和数据冗余性。 4. **数据库Too many connections故障定位**:分析了MySQL连接数限制问题的原因及解决方法。
|
1月前
|
SQL Java 关系型数据库
MySQL原理简介—3.生产环境的部署压测
本文介绍了Java系统和数据库在高并发场景下的压测要点: 1. 普通系统在4核8G机器上每秒能处理几百个请求 2. 高并发下数据库建议使用8核16G或更高配置的机器 3. 数据库部署后需进行基准压测,以评估其最大承载能力 4. QPS和TPS的区别及重要性 5. 压测时需关注IOPS、吞吐量、延迟 6. 除了QPS和TPS,还需监控CPU、内存、磁盘IO、网络带宽 7. 影响每秒可处理并发请求数的因素包括线程数、CPU、内存、磁盘IO和网络带宽 8. Sysbench是数据库压测工具,可构造测试数据并模拟高并发场景 9. 在增加线程数量的同时,必须观察机器的性能,确保各硬件负载在合理范围
148 72
|
1月前
|
SQL 存储 关系型数据库
MySQL原理简介—1.SQL的执行流程
本文介绍了MySQL驱动、数据库连接池及SQL执行流程的关键组件和作用。主要内容包括:MySQL驱动用于建立Java系统与数据库的网络连接;数据库连接池提高多线程并发访问效率;MySQL中的连接池维护多个数据库连接并进行权限验证;网络连接由线程处理,监听请求并读取数据;SQL接口负责执行SQL语句;查询解析器将SQL语句解析为可执行逻辑;查询优化器选择最优查询路径;存储引擎接口负责实际的数据操作;执行器根据优化后的执行计划调用存储引擎接口完成SQL语句的执行。整个流程确保了高效、安全地处理SQL请求。
232 76
|
1月前
|
关系型数据库 MySQL 数据库
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
随着数据量增长和业务扩展,单个数据库难以满足需求,需调整为集群模式以实现负载均衡和读写分离。MySQL主从复制是常见的高可用架构,通过binlog日志同步数据,确保主从数据一致性。本文详细介绍MySQL主从复制原理及配置步骤,包括一主二从集群的搭建过程,帮助读者实现稳定可靠的数据库高可用架构。
108 9
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
|
1月前
|
SQL 存储 关系型数据库
MySQL原理简介—9.MySQL索引原理
本文详细介绍了MySQL索引的设计与使用原则,涵盖磁盘数据页的存储结构、页分裂机制、主键索引设计及查询过程、聚簇索引和二级索引的原理、B+树索引的维护、联合索引的使用规则、SQL排序和分组时如何利用索引、回表查询对性能的影响以及索引覆盖的概念。此外还讨论了索引设计的案例,包括如何处理where筛选和order by排序之间的冲突、低基数字段的处理方式、范围查询字段的位置安排,以及通过辅助索引来优化特定查询场景。总结了设计索引的原则,如尽量包含where、order by、group by中的字段,选择离散度高的字段作为索引,限制索引数量,并针对频繁查询的低基数字段进行特殊处理等。
MySQL原理简介—9.MySQL索引原理
|
1月前
|
存储 关系型数据库 MySQL
MySQL底层概述—6.索引原理
本文详细回顾了:索引原理、二叉查找树、平衡二叉树(AVL树)、红黑树、B-Tree、B+Tree、Hash索引、聚簇索引与非聚簇索引。
102 11
MySQL底层概述—6.索引原理
|
1月前
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
108 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
1月前
|
SQL 监控 关系型数据库
MySQL原理简介—12.MySQL主从同步
本文介绍了四种为MySQL搭建主从复制架构的方法:异步复制、半同步复制、GTID复制和并行复制。异步复制通过配置主库和从库实现简单的主从架构,但存在数据丢失风险;半同步复制确保日志复制到从库后再提交事务,提高了数据安全性;GTID复制简化了配置过程,增强了复制的可靠性和管理性;并行复制通过多线程技术降低主从同步延迟,保证数据一致性。此外,还讨论了如何使用工具监控主从延迟及应对策略,如强制读主库以确保即时读取最新数据。
MySQL原理简介—12.MySQL主从同步
|
1月前
|
SQL 缓存 关系型数据库
MySQL原理简介—7.redo日志的底层原理
本文介绍了MySQL中redo日志和undo日志的主要内容: 1. redo日志的意义:确保事务提交后数据不丢失,通过记录修改操作并在系统宕机后重做日志恢复数据。 2. redo日志文件构成:记录表空间号、数据页号、偏移量及修改内容。 3. redo日志写入机制:redo日志先写入Redo Log Buffer,再批量刷入磁盘文件,减少随机写以提高性能。 4. Redo Log Buffer解析:描述Redo Log Buffer的内存结构及刷盘时机,如事务提交、Buffer过半或后台线程定时刷新。 5. undo日志原理:用于事务回滚,记录插入、删除和更新前的数据状态,确保事务可完整回滚。
138 22