Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  ALTER DATABASE Statement

15.1.2 ALTER DATABASE 语句

ALTER {DATABASE | SCHEMA} [db_name]
    alter_option ...

alter_option: {
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | [DEFAULT] ENCRYPTION [=] {'Y' | 'N'}
  | READ ONLY [=] {DEFAULT | 0 | 1}
}

ALTER DATABASE 使您能够更改数据库的整体特征。 这些特征存储在数据字典中。 此语句需要对数据库的 ALTER 权限。 ALTER SCHEMAALTER DATABASE 的同义词。

如果省略数据库名称,则该语句将应用于默认数据库。 在这种情况下,如果没有默认数据库,则会发生错误。

对于语句中省略的任何 alter_option,数据库都会保留其当前选项值,但更改字符集可能会更改排序规则,反之亦然。

字符集和排序规则选项

CHARACTER SET 选项更改默认数据库字符集。 COLLATE 选项更改默认数据库排序规则。 有关字符集和排序规则名称的信息,请参阅 第 12 章,字符集、排序规则、Unicode

要查看可用的字符集和排序规则,请分别使用 SHOW CHARACTER SETSHOW COLLATION 语句。 请参阅 第 15.7.7.4 节,“SHOW CHARACTER SET 语句”,以及 第 15.7.7.5 节,“SHOW COLLATION 语句”

在创建时使用数据库默认值的存储例程会将其默认值包含在其定义中。 (在存储例程中,如果未明确指定字符集或排序规则,则具有字符数据类型的变量将使用数据库默认值。 请参阅 第 15.1.17 节,“CREATE PROCEDURE and CREATE FUNCTION 语句”。)如果您更改了数据库的默认字符集或排序规则,则任何要使用新默认值的存储例程都必须被删除并重新创建。

加密选项

ENCRYPTION 选项定义了默认的数据库加密方式,数据库中创建的表将继承该设置。允许的值为 'Y' (启用加密)和 'N' (禁用加密)。

mysql 系统架构无法设置为默认加密。它现有的表是常规 mysql 表空间的一部分,可以进行加密。 information_schema 只包含视图。无法在其中创建任何表。磁盘上没有可加密的内容。 performance_schema 中的所有表都使用 PERFORMANCE_SCHEMA 引擎,该引擎完全在内存中运行。无法在其中创建任何其他表。磁盘上没有可加密的内容。

只有新创建的表才会继承默认的数据库加密设置。对于与数据库关联的现有表,它们的加密设置保持不变。如果启用了 table_encryption_privilege_check 系统变量,则需要 TABLE_ENCRYPTION_ADMIN 权限才能指定与 default_table_encryption 系统变量值不同的默认加密设置。有关更多信息,请参见 为架构和常规表空间定义加密默认值

只读选项

READ ONLY 选项控制是否允许修改数据库及其中的对象。允许的值为 DEFAULT0 (非只读)和 1 (只读)。此选项对于数据库迁移非常有用,因为启用了 READ ONLY 的数据库可以迁移到另一个 MySQL 实例,而无需担心在操作期间数据库可能会发生更改。

对于 NDB Cluster,在一个 mysqld 服务器上将数据库设置为只读会同步到同一集群中的其他 mysqld 服务器,以便该数据库在所有 mysqld 服务器上都变为只读。

如果启用了 READ ONLY 选项,它将显示在 INFORMATION_SCHEMA SCHEMATA_EXTENSIONS 表中。请参见 第 28.3.32 节,“INFORMATION_SCHEMA SCHEMATA_EXTENSIONS 表”

以下系统模式无法启用 READ ONLY 选项:mysqlinformation_schemaperformance_schema

ALTER DATABASE 语句中,READ ONLY 选项与其自身和其他选项的交互方式如下:

  • 如果 READ ONLY 选项的多个实例冲突(例如,READ ONLY = 1 READ ONLY = 0),则会发生错误。

  • 即使对于只读数据库,也允许包含(非冲突)READ ONLY 选项的 ALTER DATABASE 语句。

  • 如果数据库在语句之前或之后的只读状态允许修改,则允许混合(非冲突)READ ONLY 选项与其他选项。如果语句之前和之后的只读状态都禁止更改,则会发生错误。

    无论数据库是否为只读,此语句都将成功:

    ALTER DATABASE mydb READ ONLY = 0 DEFAULT COLLATE utf8mb4_bin;

    如果数据库不是只读的,则此语句将成功,但如果数据库已经是只读的,则会失败:

    ALTER DATABASE mydb READ ONLY = 1 DEFAULT COLLATE utf8mb4_bin;

启用 READ ONLY 会影响数据库的所有用户,但以下例外情况不受只读检查的限制:

  • 服务器在初始化、重启、升级或复制过程中执行的语句。

  • 服务器启动时由 init_file 系统变量命名的文件中的语句。

  • TEMPORARY 表;可以在只读数据库中创建、更改、删除和写入 TEMPORARY 表。

  • NDB Cluster 非 SQL 插入和更新。

除了上面列出的例外操作之外,启用 READ ONLY 将禁止对数据库及其对象进行写操作,包括它们的定义、数据和元数据。以下列表详细说明了受影响的 SQL 语句和操作:

  • 数据库本身:

  • 视图:

    • CREATE VIEW

    • ALTER VIEW

    • DROP VIEW

    • 从调用具有副作用的函数的视图中进行选择。

    • 更新可更新视图。

    • 如果在可写数据库中创建或删除对象的语句会影响只读数据库中视图的元数据(例如,通过使视图有效或无效),则这些语句将被拒绝。

  • 存储例程:

    • 创建过程

    • 删除过程

    • 调用 (具有副作用的过程)

    • 创建函数

    • 删除函数

    • 选择 (具有副作用的函数)

    • 对于过程和函数,只读检查遵循预锁定行为。对于 调用 语句,只读检查是在每个语句的基础上完成的,因此,如果某些有条件执行的语句写入只读数据库但实际上没有执行,则调用仍然会成功。另一方面,对于在 选择 中调用的函数,函数体的执行发生在预锁定模式下。只要函数中的某些语句写入只读数据库,函数的执行就会失败并出现错误,而不管该语句是否实际执行。

  • 触发器:

  • 事件:

    • 创建事件

    • 修改事件

    • 删除事件

    • 事件执行:

      • 在数据库中执行事件会失败,因为这会更改上次执行时间戳,这是存储在数据字典中的事件元数据。事件执行失败也会导致事件调度程序停止。

      • 如果事件写入只读数据库中的对象,则事件的执行将失败并出现错误,但事件调度程序不会停止。

  • 表:

    • 创建表

    • 修改表

    • 创建索引

    • 删除索引

    • 重命名表

    • 清空表

    • 删除表

    • 删除

    • 插入

    • 导入表

    • 加载数据

    • 加载XML

    • 替换

    • 更新

    • 对于级联外键,如果子表位于只读数据库中,则即使子表没有直接受到影响,对父表的更新和删除也会被拒绝。

    • 对于 MERGE 表,例如 CREATE TABLE s1.t(i int) ENGINE MERGE UNION (s2.t, s3.t), INSERT_METHOD=...,以下行为适用:

      • 如果 s1s2s3 中至少有一个是只读的,则插入到 MERGE 表(INSERT into s1.t)会失败,无论插入方法如何。即使插入实际上最终会进入一个可写表,也会被拒绝。

      • 只要 s1 不是只读的,删除 MERGE 表(DROP TABLE s1.t)就会成功。允许删除引用只读数据库的 MERGE 表。

更改数据库 语句会阻塞,直到所有已访问正在更改的数据库中对象的并发事务都已提交。相反,在并发 更改数据库 中访问正在更改的数据库中对象的写入事务会阻塞,直到 更改数据库 已提交。

如果使用克隆插件克隆本地或远程数据目录,则克隆中的数据库将保留它们在源数据目录中的只读状态。只读状态不会影响克隆过程本身。如果克隆中不需要相同的数据库只读状态,则必须在克隆过程完成后使用克隆上的 更改数据库 操作显式更改该选项。

从捐赠者克隆到接收者时,如果接收者拥有只读的用户数据库,克隆将失败并显示错误消息。在使数据库可写后,可以重试克隆。

只读 权限适用于 ALTER DATABASE 语句,但不适用于 CREATE DATABASE 语句。然而,对于只读数据库,SHOW CREATE DATABASE 语句生成的语句在注释中包含 READ ONLY=1,以指示其只读状态:

mysql> ALTER DATABASE mydb READ ONLY = 1;
mysql> SHOW CREATE DATABASE mydb\G
*************************** 1. row ***************************
       Database: mydb
Create Database: CREATE DATABASE `mydb`
                 /*!40100 DEFAULT CHARACTER SET utf8mb4
                          COLLATE utf8mb4_0900_ai_ci */
                 /*!80016 DEFAULT ENCRYPTION='N' */
                 /* READ ONLY = 1 */

如果服务器执行包含此类注释的 CREATE DATABASE 语句,服务器将忽略该注释,并且不会处理 READ ONLY 选项。这对 mysqldumpmysqlpump 有影响,它们使用 SHOW CREATE DATABASE 在转储输出中生成 CREATE DATABASE 语句:

  • 在转储文件中,只读数据库的 CREATE DATABASE 语句包含注释掉的 READ ONLY 选项。

  • 转储文件可以照常恢复,但由于服务器忽略注释掉的 READ ONLY 选项,因此恢复的数据库不是只读的。如果数据库在恢复后需要是只读的,则必须手动执行 ALTER DATABASE 语句以使其成为只读的。

假设 mydb 是只读的,并且您将其转储如下:

$> mysqldump --databases mydb > mydb.sql

如果 mydb 仍然应该是只读的,则稍后的恢复操作必须后跟 ALTER DATABASE 语句:

$> mysql
mysql> SOURCE mydb.sql;
mysql> ALTER DATABASE mydb READ ONLY = 1;

MySQL Enterprise Backup 不受此问题的影响。它像备份任何其他数据库一样备份和恢复只读数据库,但如果在备份时启用了 READ ONLY 选项,则会在恢复时启用该选项。

ALTER DATABASE 语句写入二进制日志,因此对复制源服务器上 READ ONLY 选项的更改也会影响副本。为了防止这种情况发生,必须在执行 ALTER DATABASE 语句之前禁用二进制日志记录。例如,为了准备迁移数据库而不影响副本,请执行以下操作:

  1. 在单个会话中,禁用二进制日志记录并为数据库启用 READ ONLY 选项:

    mysql> SET sql_log_bin = OFF;
    mysql> ALTER DATABASE mydb READ ONLY = 1;
  2. 例如,使用 mysqldumpmysqlpump 转储数据库:

    $> mysqldump --databases mydb > mydb.sql
  3. 在单个会话中,禁用二进制日志并禁用数据库的 只读

    mysql> SET sql_log_bin = OFF;
    mysql> ALTER DATABASE mydb READ ONLY = 0;