### 6.1.6 LOAD DATA LOCAL 的安全注意事项

[](<>)

这[`加载数据`](load-data.html)语句将数据文件加载到表中。该语句可以加载位于服务器主机上的文件，或者，如果`当地的`在客户端主机上指定关键字。

这`当地的`版本[`加载数据`](load-data.html)有两个潜在的安全问题：

-   因为[`本地加载数据`](load-data.html)是一条 SQL 语句，解析发生在服务器端，文件从客户端主机到服务器主机的传输是由 MySQL 服务器发起的，它告诉客户端语句中命名的文件。理论上，打补丁的服务器可以告诉客户端程序传输服务器选择的文件，而不是语句中指定的文件。这样的服务器可以访问客户端用户具有读取访问权限的客户端主机上的任何文件。（打了补丁的服务器实际上可以用文件传输请求来回复任何语句，而不仅仅是[`本地加载数据`](load-data.html)，所以一个更根本的问题是客户端不应该连接到不受信任的服务器。）

-   在客户端从 Web 服务器连接的 Web 环境中，用户可以使用[`本地加载数据`](load-data.html)读取 Web 服务器进程具有读取权限的任何文件（假设用户可以针对 SQL 服务器运行任何语句）。在这种环境中，相对于 MySQL 服务器的客户端实际上是 Web 服务器，而不是由连接到 Web 服务器的用户运行的远程程序。

    为避免连接到不受信任的服务器，客户端可以建立安全连接并通过使用连接来验证服务器身份[`--ssl-mode=VERIFY_IDENTITY`](connection-options.html#option_general_ssl-mode)选项和适当的 CA 证书。

    避免[`加载数据`](load-data.html)问题，客户应避免使用`当地的`除非已采取适当的客户端预防措施。

    为了控制本地数据加载，MySQL 允许启用或禁用该功能。此外，从 MySQL 8.0.21 开始，MySQL 允许客户端将本地数据加载操作限制为位于指定目录中的文件。

-   [启用或禁用本地数据加载功能](load-data-local-security.html#load-data-local-configuration)

-   [限制本地数据加载允许的文件](load-data-local-security.html#load-data-local-permitted-files)

-   [MySQL Shell 和本地数据加载](load-data-local-security.html#load-data-local-shell)

#### 启用或禁用本地数据加载功能

管理员和应用程序可以配置是否允许本地数据加载，如下所示：

-   在服务器端：

    -   这[`local_infile`](server-system-variables.html#sysvar_local_infile)系统变量控制服务器端`当地的`能力。取决于[`local_infile`](server-system-variables.html#sysvar_local_infile)设置，服务器拒绝或允许请求本地数据加载的客户端加载本地数据。

    -   默认，[`local_infile`](server-system-variables.html#sysvar_local_infile)被禁用。（这是对 MySQL 以前版本的更改。）导致服务器拒绝或允许[`本地加载数据`](load-data.html)显式声明（无论在构建时或运行时如何配置客户端程序和库），开始[**mysqld**](mysqld.html)和[`local_infile`](server-system-variables.html#sysvar_local_infile)禁用或启用。[`local_infile`](server-system-variables.html#sysvar_local_infile)也可以在运行时设置。

        [](<>)[](<>)

-   在客户端：

    -   这[`ENABLED_LOCAL_INFILE`](source-configuration-options.html#option_cmake_enabled_local_infile) **制作**选项控制编译的默认值`当地的`MySQL 客户端库的功能（请参阅[第 2.9.7 节，“MySQL 源配置选项”](source-configuration-options.html)）。因此，没有做出明确安排的客户有`当地的`功能禁用或启用根据[`ENABLED_LOCAL_INFILE`](source-configuration-options.html#option_cmake_enabled_local_infile)在 MySQL 构建时指定的设置。

        [](<>)[](<>)

    -   默认情况下，MySQL 二进制发行版中的客户端库是用[`ENABLED_LOCAL_INFILE`](source-configuration-options.html#option_cmake_enabled_local_infile)禁用。如果你从源代码编译 MySQL，配置它[`ENABLED_LOCAL_INFILE`](source-configuration-options.html#option_cmake_enabled_local_infile)根据没有明确安排的客户端是否应该有禁用或启用`当地的`功能禁用或启用。

    -   对于使用 C API 的客户端程序，本地数据加载能力由编译到 MySQL 客户端库中的默认值决定。要显式启用或禁用它，请调用[`mysql_options()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html)C API 函数来禁用或启用`MYSQL_OPT_LOCAL_INFILE`选项。看[mysql\_选项（）](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html).

        [](<>)

    -   为了[**mysql**](mysql.html)客户端，本地数据加载能力由默认编译到 MySQL 客户端库中决定。要显式禁用或启用它，请使用[`--local-infile=0`](mysql-command-options.html#option_mysql_local-infile)要么[`--local-infile[=1]`](mysql-command-options.html#option_mysql_local-infile)选项。

        [](<>)[](<>)

    -   为了[**mysql导入**](mysqlimport.html)客户端，默认不使用本地数据加载。要显式禁用或启用它，请使用[`--local=0`](mysqlimport.html#option_mysqlimport_local)要么[`--本地[=1]`](mysqlimport.html#option_mysqlimport_local)选项。

        [](<>)[](<>)

    -   如果你使用[`本地加载数据`](load-data.html)在 Perl 脚本或其他读取`[客户]`来自选项文件的组，您可以添加一个`本地文件`该组的选项设置。要防止不理解此选项的程序出现问题，请使用[`松动的-`](option-modifiers.html)字首：

        ```
        [client]
        loose-local-infile=0
        ```

        要么：

        ```
        [client]
        loose-local-infile=1
        ```

    -   在所有情况下，成功使用`当地的`客户端的加载操作还需要服务器允许本地加载。

    如果`当地的`功能被禁用，无论是在服务器端还是客户端，客户端尝试发出[`本地加载数据`](load-data.html)语句收到以下错误消息：


```
ERROR 3950 (42000): Loading local data is disabled; this must be
enabled on both the client and server side
```

[](<>)[](<>)

#### 限制本地数据加载允许的文件

从 MySQL 8.0.21 开始，MySQL 客户端库使客户端应用程序能够将本地数据加载操作限制为位于指定目录中的文件。某些 MySQL 客户端程序利用此功能。

使用 C API 的客户端程序可以使用`MYSQL_OPT_LOCAL_INFILE`和`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`的选项[`mysql_options()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html)C API 函数（见[mysql\_选项（）](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html)）。

[](<>)[](<>)

的效果`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`取决于是否`当地的`启用或禁用数据加载：

-   如果`当地的`数据加载已启用，默认情况下在 MySQL 客户端库中或通过显式启用`MYSQL_OPT_LOCAL_INFILE`， 这`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`选项无效。

-   如果`当地的`数据加载被禁用，默认情况下在 MySQL 客户端库中或通过显式禁用`MYSQL_OPT_LOCAL_INFILE`， 这`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`选项可用于为本地加载的文件指定允许的目录。在这种情况下，`当地的`数据加载是允许的，但仅限于位于指定目录中的文件。的解释`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`值如下：

    -   如果该值为空指针（默认值），则不命名目录，结果不允许任何文件`当地的`数据加载。

    -   如果值是目录路径名，`当地的`数据加载是允许的，但仅限于位于指定目录中的文件。无论底层文件系统是否区分大小写，目录路径名和要加载文件的路径名的比较都是区分大小写的。

    MySQL 客户端程序使用前面的[`mysql_options()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html)选项如下：

-   这[**mysql**](mysql.html)客户有一个[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)采用目录路径或空字符串的选项。[**mysql**](mysql.html)使用选项值来设置`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`选项（使用空字符串将值设置为空指针）。的效果[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)取决于是否`当地的`启用数据加载：

    [](<>)[](<>)

    -   如果`当地的`默认情况下，在 MySQL 客户端库中或通过指定启用数据加载[`--local-infile[=1]`](mysql-command-options.html#option_mysql_local-infile)， 这[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)选项被忽略。

    -   如果`当地的`数据加载被禁用，默认情况下在 MySQL 客户端库中或通过指定[`--local-infile=0`](mysql-command-options.html#option_mysql_local-infile)， 这[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)选项适用。

        什么时候[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)适用时，选项值指定本地数据文件必须位于的目录。无论底层文件系统是否区分大小写，目录路径名和要加载文件的路径名的比较都是区分大小写的。如果选项值为空字符串，则不命名目录，结果是不允许任何文件用于本地数据加载。

-   [**mysql导入**](mysqlimport.html)套`MYSQL_OPT_LOAD_DATA_LOCAL_DIR`对于它处理的每个文件，以便包含该文件的目录是允许的本地加载目录。

-   对于对应的数据加载操作[`加载数据`](load-data.html)陈述，[**mysqlbinlog**](mysqlbinlog.html)从二进制日志事件中提取文件，将它们作为临时文件写入本地文件系统，并写入[`本地加载数据`](load-data.html)导致文件被加载的语句。默认，[**mysqlbinlog**](mysqlbinlog.html)将这些临时文件写入特定于操作系统的目录。这[`--本地加载`](mysqlbinlog.html#option_mysqlbinlog_local-load)选项可用于显式指定目录[**mysqlbinlog**](mysqlbinlog.html)应该准备本地临时文件。

    [](<>)[](<>)

    由于其他进程可以将文件写入默认的系统特定目录，因此建议指定[`--本地加载`](mysqlbinlog.html#option_mysqlbinlog_local-load)选项[**mysqlbinlog**](mysqlbinlog.html)为数据文件指定不同的目录，然后通过指定[`--load-data-local-dir`](mysql-command-options.html#option_mysql_load-data-local-dir)选项[**mysql**](mysql.html)在处理来自的输出时[**mysqlbinlog**](mysqlbinlog.html).

#### MySQL Shell 和本地数据加载

MySQL Shell 提供了许多实用程序来转储表、模式或服务器实例并将它们加载到其他实例中。当您使用这些实用程序处理数据时，MySQL Shell 提供额外的功能，例如输入预处理、多线程并行加载、文件压缩和解压缩，以及处理对 Oracle 云基础设施对象存储桶的访问。要获得最佳功能，请始终使用 MySQL Shell 的转储和转储加载实用程序的最新版本。

MySQL Shell 的数据上传实用程序使用[`加载数据本地文件`](load-data.html)语句上传数据，所以[`local_infile`](server-system-variables.html#sysvar_local_infile)系统变量必须设置为`在`在目标服务器实例上。您可以在上传数据之前执行此操作，然后再将其删除。这些实用程序安全地处理文件传输请求，以处理本主题中讨论的安全注意事项。

MySQL Shell 包括这些转储和转储加载实用程序：

表导出实用程序`util.exportTable()`

将 MySQL 关系表导出到数据文件中，可以使用 MySQL Shell 的并行表导入实用程序将其上传到 MySQL 服务器实例、导入到不同的应用程序或用作逻辑备份。该实用程序具有预设选项和自定义选项以生成不同的输出格式。

并行表导入实用程序`util.importTable()`

将数据文件导入 MySQL 关系表。数据文件可以是 MySQL Shell 的表导出实用程序的输出，也可以是实用程序的预设和自定义选项支持的其他格式。该实用程序可以在将数据添加到表之前执行输入预处理。它可以接受多个数据文件合并成一个关系表，并自动解压缩压缩文件。

实例转储实用程序`util.dumpInstance()`, 模式转储实用程序`util.dumpSchemas()`, 和表转储实用程序`util.dumpTables()`

将实例、模式或表导出到一组转储文件，然后可以使用 MySQL Shell 的转储加载实用程序将其上传到 MySQL 实例。这些实用程序提供 Oracle 云基础设施对象存储流、MySQL 数据库服务兼容性检查和修改，以及在继续转储之前进行试运行以识别问题的能力。

转储加载实用程序`util.loadDump()`

将使用 MySQL Shell 的实例、模式或表转储实用程序创建的转储文件导入 MySQL 数据库服务数据库系统或 MySQL 服务器实例。该实用程序管理上传过程并提供来自远程存储的数据流、表或表块的并行加载、进度状态跟踪、恢复和重置功能，以及在转储仍在进行时的并发加载选项。MySQL Shell 的并行表导入实用程序可以与转储加载实用程序结合使用，以在将数据上传到目标 MySQL 实例之前对其进行修改。

有关实用程序的详细信息，请参阅[MySQL 外壳实用程序](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities.html).
