MySQL8 中文参考(二十)(3)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL8 中文参考(二十)

MySQL8 中文参考(二十)(2)https://developer.aliyun.com/article/1566108


隐式错误日志配置

本过程描述了如何使用log_error_services隐式加载和启用错误日志组件。有关错误日志配置方法的讨论,请参见错误日志配置方法。

隐式加载和启用错误日志组件:

  1. log_error_services值中列出错误日志组件。
    要在服务器启动时加载和启用错误日志组件,请在选项文件中设置log_error_services。以下示例配置了使用 JSON 日志接收器(log_sink_json)以及内置日志过滤器和接收器(log_filter_internallog_sink_internal)。
[mysqld]
log_error_services='log_filter_internal; log_sink_internal; log_sink_json'
  1. 注意
    要使用 JSON 日志接收器(log_sink_syseventlog)而不是默认接收器(log_sink_internal),您应该将log_sink_internal替换为log_sink_json
    要立即加载和启用组件并用于后续重新启动,请使用SET PERSIST设置log_error_services
SET PERSIST log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';
  1. 如果错误日志组件公开任何必须设置的系统变量以使组件初始化成功,请为这些变量分配适当的值。您可以在选项文件中设置这些变量,也可以使用SET PERSIST
    重要
    在实现隐式配置时,首先设置log_error_services以加载组件并公开其系统变量,然后设置组件系统变量。无论是在命令行、选项文件还是使用SET PERSIST进行变量赋值,都需要按照此配置顺序进行。

要禁用日志组件,请从log_error_services值中移除它。同时移除您定义的任何相关组件变量设置。

注意

使用log_error_services隐式加载日志组件不会影响mysql.component表。它不会将组件添加到mysql.component表中,也不会从mysql.component表中删除以前使用INSTALL COMPONENT安装的组件。

明确的错误日志配置

本过程描述了如何通过使用INSTALL COMPONENT加载组件,然后通过log_error_services启用错误日志组件。有关错误日志配置方法的讨论,请参见错误日志配置方法。

明确加载和启用错误日志组件:

  1. 使用INSTALL COMPONENT加载组件(除非它是内置的或已加载)。例如,要加载 JSON 日志接收器,请执行以下语句:
INSTALL COMPONENT 'file://component_log_sink_json';
  1. 使用INSTALL COMPONENT加载组件会将其注册到mysql.component系统表中,以便服务器在InnoDB初始化后自动加载它以供后续启动使用。
    使用INSTALL COMPONENT加载日志组件时使用的 URN 是组件名称前缀为file://component_。例如,对于log_sink_json组件,相应的 URN 是file://component_log_sink_json。有关错误日志组件 URN,请参见 Section 7.5.3, “Error Log Components”。
  2. 如果错误日志组件公开了必须设置的系统变量以确保组件初始化成功,为这些变量分配适当的值。您可以在选项文件中设置这些变量,也可以使用SET PERSIST
  3. 通过在log_error_services值中列出组件来启用该组件。
    重要
    从 MySQL 8.0.30 开始,当使用INSTALL COMPONENT显式加载日志组件时,请勿在选项文件中持久化或设置log_error_services,该选项文件在启动时隐式加载日志组件。而是使用SET GLOBAL语句在运行时启用日志组件。
    以下示例配置了使用 JSON 日志接收器(log_sink_json)以及内置日志过滤器和接收器(log_filter_internallog_sink_internal)。
SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';
  1. 注意
    要使用 JSON 日志接收器(log_sink_syseventlog)而不是默认接收器(log_sink_internal),您应该将log_sink_internal替换为log_sink_json

要禁用日志组件,请从log_error_services值中删除它。然后,如果组件是可加载的,并且您还想卸载它,请使用UNINSTALL COMPONENT。还要删除您定义的任何相关组件变量设置。

尝试使用UNINSTALL COMPONENT卸载仍在log_error_services值中命名的可加载组件会产生错误。

更改错误日志配置方法

如果您之前使用INSTALL COMPONENT显式加载了错误日志组件,并且希望切换到隐式配置,如隐式错误日志配置中所述,建议执行以下步骤:

  1. log_error_services设置回默认配置。
SET GLOBAL log_error_services = 'log_filter_internal,log_sink_internal';
  1. 使用UNINSTALL COMPONENT卸载您之前安装的任何可加载日志组件。例如,如果之前安装了 JSON 日志接收器,请按照以下方式��载它:
UNINSTALL COMPONENT 'file://component_log_sink_json';
  1. 删除已卸载组件的任何组件变量设置。例如,如果在选项文件中设置了组件变量,请从选项文件中删除这些设置。如果使用SET PERSIST设置了组件变量,请使用RESET PERSIST来清除这些设置。
  2. 按照隐式错误日志配置中的步骤重新实施您的配置。

如果需要从隐式配置恢复到显式配置,请执行以下步骤:

  1. log_error_services设置回其默认配置以卸载隐式加载的日志组件。
SET GLOBAL log_error_services = 'log_filter_internal,log_sink_internal';
  1. 删除与已卸载组件相关的任何组件变量设置。例如,如果在选项文件中设置了组件变量,请从选项文件中删除这些设置。如果使用SET PERSIST设置了组件变量,请使用RESET PERSIST清除这些设置。
  2. 重新启动服务器以卸载隐式加载的日志组件。
  3. 按照显式错误日志配置中的步骤重新实施您的配置。
故障排除配置问题

从 MySQL 8.0.30 开始,在启动时加载在log_error_services值中列出的日志组件会在 MySQL 服务器启动序列的早期隐式加载。如果以前使用INSTALL COMPONENT加载了日志组件,则服务器会在启动序列的后期尝试重新加载该组件,从而产生以下警告:

Cannot load component from specified URN: 'file://component_*component_name*'

您可以在错误日志中检查此警告,或通过以下查询查询性能模式error_log表来查询此警告:

SELECT error_code, data
  FROM performance_schema.error_log
 WHERE data LIKE "%'file://component_%"
   AND error_code="MY-013129" AND data LIKE "%MY-003529%";

要避免此警告,请按照更改错误日志配置方法中的说明调整您的错误日志配置。应使用隐式或显式错误日志配置,但不要同时使用两者。

当尝试显式加载在启动时隐式加载的组件时会出现类似错误。例如,如果log_error_services列出了 JSON 日志接收器组件,则该组件会在启动时隐式加载。尝试稍后显式加载相同组件会返回此错误:

mysql> INSTALL COMPONENT 'file://component_log_sink_json';
ERROR 3529 (HY000): Cannot load component from specified URN: 'file://component_log_sink_json'.
配置多个日志接收器

可以配置多个日志接收器,从而可以将输出发送到多个目的地。要在默认接收器之外启用 JSON 日志接收器(而不是替代),请将log_error_services值设置如下:

SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';

要恢复仅使用默认接收器并卸载系统日志接收器,请执行以下语句:

SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal;
UNINSTALL COMPONENT 'file://component_log_sink_json';
日志接收器性能模式支持

如果启用了记录组件包含支持性能模式的接收器,那么写入错误日志的事件也会写入性能模式的error_log表中。这样可以使用 SQL 查询来检查错误日志内容。目前,传统格式的log_sink_internal和 JSON 格式的log_sink_json接收器支持此功能。请参阅 Section 29.12.21.2, “错误日志表”。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration.html

7.4.2.2 默认错误日志目的地配置

本节描述了哪些服务器选项配置了默认错误日志目的地,可以是控制台或命名文件。它还指出了哪些日志接收组件将其自身的输出目的地基于默认目的地。

在本讨论中,“控制台”指的是stderr,标准错误输出。这是您的终端或控制台窗口,除非标准错误输出已重定向到其他目的地。

服务器对于确定默认错误日志目的地的选项在 Windows 和 Unix 系统上有些不同。请确保使用适合您平台的信息配置目的地。服务器解释默认错误日志目的地选项后,它将设置log_error系统变量以指示默认目的地,这会影响几个日志接收组件写入错误消息的位置。以下各节将讨论这些主题。

  • Windows 上的默认错误日志目的地
  • Unix 和类 Unix 系统上的默认错误日志目的地
  • 默认错误日志目的地如何影响日志接收组件
Windows 上的默认错误日志目的地

在 Windows 上,mysqld使用--log-error--pid-file--console选项来确定默认错误日志目的地是控制台还是文件,以及如果是文件,则文件名:

  • 如果提供了--console,默认目的地是控制台。(--console优先于--log-error如果两者都提供,则关于--log-error的以下项目不适用。)
  • 如果未提供--log-error,或者提供了但没有指定文件名,则默认目的地是数据目录中名为*host_name*.err的文件,除非指定了--pid-file选项。在这种情况下,文件名是 PID 文件基本名称,带有.err后缀在数据目录中。
  • 如果给定--log-error来命名一个文件,那么默认的目的地就是该文件(如果名称没有后缀,则添加.err后缀)。文件位置位于数据目录下,除非给定绝对路径名以指定不同位置。

如果默认的错误日志目的地是控制台,服务器会将log_error系统变量设置为stderr。否则,默认目的地是一个文件,服务器会将log_error设置为文件名。

Unix 和类 Unix 系统上的默认错误日志目的地

在 Unix 和类 Unix 系统上,mysqld使用--log-error选项来确定默认的错误日志目的地是控制台还是文件,以及文件名:

  • 如果没有给定--log-error,默认的目的地是控制台。
  • 如果给定--log-error而没有命名文件,那么默认的目的地是数据目录中名为*host_name*.err的文件。
  • 如果给定--log-error来命名一个文件,那么默认的目的地就是该文件(如果名称没有后缀,则添加.err后缀)。文件位置位于数据目录下,除非给定绝对路径名以指定不同位置。
  • 如果在[mysqld][server][mysqld_safe]部分的选项文件中给定--log-error,在使用mysqld_safe启动服务器的系统上,mysqld_safe会找到并使用该选项,并将其传递给mysqld

注意

对于 Yum 或 APT 软件包安装来说,通常会在服务器配置文件中使用类似log-error=/var/log/mysqld.log的选项来配置错误日志文件位置在/var/log下。从选项中移除路径名会导致在数据目录中使用*host_name*.err文件。

如果默认的错误日志目的地是控制台,服务器会将log_error系统变量设置为stderr。否则,默认目的地是一个文件,服务器会将log_error设置为文件名。

默认错误日志目的地如何影响日志输出

在服务器解释错误日志目的地配置选项后,它将log_error系统变量设置为指示默认错误日志目的地。日志输出端组件可以基于log_error值确定自己的输出目的地,或者独立于log_error确定它们的目的地。

如果log_errorstderr,默认错误日志目的地为控制台,基于默认目的地的日志输出端也会写入控制台:

  • log_sink_internal, log_sink_json, log_sink_test: 这些输出端写入控制台。即使对于可以多次启用的输出端(例如log_sink_json),所有实例也会写入控制台。
  • log_sink_syseventlog: 此输出端写入系统日志,不受log_error值的影响。

如果log_error不是stderr,默认错误日志目的地是一个文件,并且log_error指示文件名。基于默认目的地的日志输出端会根据该文件名确定输出文件命名。 (一个输出端可能会使用完全相同的名称,或者可能会使用某种变体。)假设log_error值为*file_name*。那么日志输出端使用以下方式的名称:

  • log_sink_internal, log_sink_test: 这些输出端写入*file_name*。
  • log_sink_json: 连续的此输出端实例命名为log_error_services值写入名为*file_name*加上编号为.*NN*.json后缀的文件:*file_name*.00.json*file_name*.01.json等等。
  • log_sink_syseventlog: 此输出端写入系统日志,不受log_error值的影响。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-event-fields.html

7.4.2.3 错误事件字段

用于错误日志的错误事件包含一组字段,每个字段由键/值对组成。事件字段可以分类为核心、可选或用户定义:

  • 核心字段会自动设置为错误事件。但是,在事件处理过程中,不能保证事件���存在核心字段,因为核心字段,像任何类型的字段一样,可能会被日志过滤器取消设置。如果发生这种情况,则在该过滤器内部和在过滤器之后执行的组件(如日志接收器)中无法找到该字段。
  • 通常情况下,可选字段通常不存在,但对于某些事件类型可能存在。当存在时,可选字段根据需要和可用性提供额外的事件信息。
  • 用户定义字段是任何名称尚未定义为核心或可选字段的字段。用户定义字段在由日志过滤器创建之前不存在。

如前述描述所示,任何给定字段在事件处理过程中可能不存在,这可能是因为它一开始就不存在,或者被过滤器丢弃。对于日志接收器,字段缺失的影响是特定于接收器的。例如,接收器可能从日志消息中省略该字段,指示该字段丢失,或者替换为默认值。如果有疑问,请进行测试:使用一个取消设置该字段的过滤器,然后检查日志接收器对其的处理方式。

以下部分描述了核心和可选错误事件字段。对于单独的日志过滤器组件,可能会有关于这些字段的其他特定于过滤器的考虑,或者过滤器可能添加此处未列出的用户定义字段。有关详细信息,请参阅特定过滤器的文档。

  • 核心错误事件字段
  • 可选错误事件字段
核心错误事件字段

这些错误事件字段是核心字段:

  • time
    事件时间戳,精确到微秒。
  • msg
    事件消息字符串。
  • prio事件优先级,用于指示系统、错误、警告或注意/信息事件。此字段对应于syslog中的严重性。以下表显示可能的优先级级别。
事件类型 数字优先级
系统事件 0
错误事件 1
警告事件 2
注意/信息事件 3
  • prio值是数字。与此相关,错误事件还可以包括一个可选的label字段,表示优先级为字符串。例如,具有prio值为 2 的事件可能具有label值为’警告’。根据优先级,过滤器组件可以包含或删除错误事件,但系统事件是强制性的,不能被删除。一般来说,消息优先级的确定如下:这种情况或事件是否可操作?
  • 是:情况或事件是否可忽略?
  • 是:优先级是警告。
  • 不:优先级是错误。
  • 不:情况或事件是否强制性?
  • 是:优先级是系统。
  • 不:优先级是注释/信息。
  • err_code
    事件错误代码,作为数字(例如,1022)。
  • err_symbol
    作为字符串的事件错误符号(例如,'ER_DUP_KEY')。
  • SQL_state
    作为字符串的事件 SQLSTATE 值(例如,'23000')。
  • subsystem
    事件发生的子系统。可能的值为InnoDBInnoDB存储引擎)、Repl(复制子系统)、Server(其他)。
可选的错误事件字段

可选的错误事件字段属于以下类别:

  • 关于错误的其他信息,例如操作系统发出的错误或错误标签:
  • OS_errno
    操作系统错误编号。
  • OS_errmsg
    操作系统错误消息。
  • label
    prio值对应的标签,作为字符串。
  • 事件发生的客户端的标识:
  • user
    客户端用户。
  • host
    客户端主机。
  • thread
    mysqld中负责生成错误事件的线程的 ID。此 ID 指示服务器的哪个部分生成了事件,并与一般查询日志和慢查询日志消息一致,这些消息包括连接线程 ID。
  • query_id
    查询 ID。
  • 调试信息:
  • source_file
    事件发生的源文件,不包含任何前导路径。
  • source_line
    事件发生的源文件中的行号。
  • function
    事件发生的函数。
  • component
    事件发生的组件或插件。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-filtering.html

7.4.2.4 错误日志过滤类型

错误日志配置通常包括一个日志过滤组件和一个或多个日志接收组件。对于错误日志过滤,MySQL 提供了多种组件选择:

  • log_filter_internal:该过滤组件基于日志事件优先级和错误代码提供错误日志过滤,结合log_error_verbositylog_error_suppression_list系统变量。log_filter_internal是内置的,默认启用。参见 Section 7.4.2.5, “基于优先级的错误日志过滤(log_filter_internal)”。
  • log_filter_dragnet:该过滤组件基于用户提供的规则,结合dragnet.log_error_filter_rules系统变量,提供错误日志过滤。参见 Section 7.4.2.6, “基于规则的错误日志过滤(log_filter_dragnet)”。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-priority-based-filtering.html

7.4.2.5 基于优先级的错误日志过滤(log_filter_internal)

log_filter_internal日志过滤组件实现了一种基于错误事件优先级和错误代码的简单形式的日志过滤。要影响log_filter_internal如何允许或抑制写入错误日志的错误、警告和信息事件,请设置log_error_verbositylog_error_suppression_list系统变量。

log_filter_internal是内置的并默认启用。如果禁用此过滤器,log_error_verbositylog_error_suppression_list将不起作用,因此必须在需要时使用另一个过滤器服务执行过滤(例如,在使用log_filter_dragnet时使用单独的过滤规则)。有关过滤器配置的信息,请参见第 7.4.2.1 节“错误日志配置”。

  • 详细程度过滤
  • 抑制列表过滤
  • 详细程度和抑制列表交互
详细程度过滤

事件意图记录到错误日志的优先级为ERRORWARNINGINFORMATIONlog_error_verbosity系统变量控制基于哪些优先级允许写入日志的消息的详细程度,如下表所示。

log_error_verbosity 值 允许的消息优先级
1 ERROR
2 ERRORWARNING
3 ERRORWARNINGINFORMATION

如果log_error_verbosity为 2 或更高,则服务器会记录关于对基于语句的日志记录不安全的语句的消息。如果值为 3,则服务器会记录有关新连接尝试的中止连接和访问被拒绝的错误。请参见第 B.3.2.9 节“通信错误和中止连接”。

如果使用复制,建议将log_error_verbosity值设置为 2 或更高,以获取有关正在发生的情况的更多信息,例如有关网络故障和重新连接的消息。

如果在副本上log_error_verbosity为 2 或更高,则副本会将消息打印到错误日志中,以提供有关其状态的信息,例如二进制日志和中继日志的坐标,它开始工作的位置,当它切换到另一个中继日志时,重新连接后等等。

存在一个SYSTEM的消息优先级,不受冗长过滤的影响。关于非错误情况的系统消息会被打印到错误日志中,无论log_error_verbosity的值是多少。这些消息包括启动和关闭消息,以及一些重要的设置更改。

在 MySQL  错误日志中,系统消息标记为“System”。其他日志接收器可能会或可能不会遵循相同的约定,在生成的日志中,系统消息可能被分配给信息优先级级别使用的标签,例如“Note”或“Information”。如果基于消息标签应用任何额外的过滤或重定向以进行日志记录,系统消息不会覆盖您的过滤器,而是以与其他消息相同的方式处理。

抑制列表过滤

log_error_suppression_list系统变量适用于写入错误日志的事件,并指定在出现WARNINGINFORMATION优先级时要抑制哪些事件。例如,如果某种类型的警告被认为是错误日志中频繁发生但不感兴趣的“噪音”,则可以将其抑制。log_error_suppression_list不会抑制具有ERRORSYSTEM优先级的消息。

log_error_suppression_list的值可以是空字符串以表示无抑制,或者是一个或多个逗号分隔值的列表,指示要抑制的错误代码。错误代码可以用符号形式或数字形式指定。可以使用或不使用MY-前缀指定数字代码。数字部分的前导零不重要。允许的代码格式示例:

ER_SERVER_SHUTDOWN_COMPLETE
MY-000031
000031
MY-31
31

为了可读性和可移植性,符号值比数字值更可取。

尽管要抑制的代码可以用符号形式或数字形式表示,但每个代码的数字值必须在允许的范围内:

  • 1 至 999:服务器和客户端使用的全局错误代码。
  • 10000 及以上:服务器错误代码,意在写入错误日志(不发送给客户端)。

此外,指定的每个错误代码必须实际被 MySQL 使用。尝试指定不在允许范围内或在允许范围内但未被 MySQL 使用的代码会产生错误,并且log_error_suppression_list的值保持不变。

有关错误代码范围、每个范围内定义的错误符号和数字的信息,请参见第 B.1 节,“错误消息来源和元素”,以及 MySQL 8.0 错误消息参考。

服务器可以为给定错误代码生成具有不同优先级的消息,因此与log_error_suppression_list中列出的错误代码相关联的消息的抑制取决于其优先级。假设变量的值为'ER_PARSER_TRACE,MY-010001,10002'。那么log_error_suppression_list对这些代码的消息产生以下影响:

  • 生成具有WARNINGINFORMATION优先级的消息会被抑制。
  • 生成具有ERRORSYSTEM优先级的消息不会被抑制。
详细度和抑制列表的交互

log_error_verbosity的效果与log_error_suppression_list的效果相结合。考虑使用以下设置启动的服务器:

[mysqld]
log_error_verbosity=2 # error and warning messages only
log_error_suppression_list='ER_PARSER_TRACE,MY-010001,10002'

在这种情况下,log_error_verbosity允许具有ERRORWARNING优先级的消息,并丢弃具有INFORMATION优先级的消息。在未被丢弃的消息中,log_error_suppression_list会丢弃具有WARNING优先级和任何命名错误代码的消息。

注意

示例中显示的log_error_verbosity值为 2,这也是其默认值,因此该变量对INFORMATION消息的影响默认情况下如上所述,无需显式设置。如果要使log_error_suppression_list影响具有INFORMATION优先级的消息,必须将log_error_verbosity设置为 3。

考虑使用以下设置启动的服务器:

[mysqld]
log_error_verbosity=1 # error messages only

在这种情况下,log_error_verbosity 允许具有ERROR优先级的消息,并丢弃具有WARNINGINFORMATION优先级的消息。设置log_error_suppression_list 不起作用,因为它可能抑制的所有错误代码已经由log_error_verbosity 设置丢弃了。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-rule-based-filtering.html


MySQL8 中文参考(二十)(4)https://developer.aliyun.com/article/1566110

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
关系型数据库 MySQL Unix
MySQL8 中文参考(二十三)(3)
MySQL8 中文参考(二十三)
45 4
|
4月前
|
存储 缓存 关系型数据库
MySQL8 中文参考(二十一)(5)
MySQL8 中文参考(二十一)
71 3
|
4月前
|
存储 监控 Java
MySQL8 中文参考(二十一)(4)
MySQL8 中文参考(二十一)
102 3
|
4月前
|
存储 安全 关系型数据库
MySQL8 中文参考(二十一)(1)
MySQL8 中文参考(二十一)
44 3
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十一)(3)
MySQL8 中文参考(二十一)
62 2
|
4月前
|
关系型数据库 MySQL Unix
MySQL8 中文参考(二十一)(2)
MySQL8 中文参考(二十一)
48 2
|
4月前
|
关系型数据库 MySQL 数据安全/隐私保护
MySQL8 中文参考(二十五)(5)
MySQL8 中文参考(二十五)
36 2
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十四)(1)
MySQL8 中文参考(二十四)
40 2
|
4月前
|
NoSQL 关系型数据库 MySQL
MySQL8 中文参考(二十三)(2)
MySQL8 中文参考(二十三)
50 2
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十三)(1)
MySQL8 中文参考(二十三)
30 2