ALTER DATABASE 语句

ALTER DATABASE使您能够更改数据库的全部特征。这些特征存储在数据字典中。此语句要求对数据库具有ALTER特权。ALTER SCHEMA是ALTER DATABASE的同义词。

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

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

字符集和排序规则选项

CHARACTER SET选项更改默认数据库字符集。COLLATE选项更改默认数据库排序规则。

要查看可用的字符集和排序规则,请分别使用SHOW CHARACTER SET和SHOW COLLATION语句。

创建存储过程时使用数据库默认值,这些默认值作为其定义的一部分。(在存储过程中,如果未显式指定字符集或排序规则,字符数据类型的变量将使用数据库默认值。)如果更改数据库的默认字符集或排序规则,任何存储过程,如果要使用新默认值,则必须删除并重新创建。

加密选项

MySQL 8.0.16中引入的ENCRYPTION选项定义了默认的数据库加密,由数据库中创建的表继承。允许的值为'Y'(启用加密)和'N'(禁用加密)。只有新创建的表才能继承默认的数据库加密。对于与数据库关联的现有表,其加密保持不变。如果启用 table_encryption_privilege_check 系统变量,则需要 TABLE_ENCRYPTION_ADMIN 权限来指定与 default_table_encryption 系统变量的值不同的默认加密设置。

只读选项

MySQL 8.0.22中引入的READ ONLY选项控制是否允许修改数据库和其中的对象。允许的值为DEFAULT或0(非只读)和1(只读)。此选项对于数据库迁移非常有用,因为启用了只读功能的数据库可以迁移到另一个MySQL实例,而不必担心在操作过程中数据库可能会发生更改。

用于NDB Cluster,通过使一个mysqld服务器上的数据库只读,然后同步到同一集群中的其他mysqld服务器,从而使数据库在所有mysqld服务器上变为只读。

如果启用READ ONLY选项,将显示在INFORMATION_SCHEMA SCHEMATA_EXTENSIONS表中。

无法为以下系统架构启用READ ONLY选项:mysql、information_schema、performance_schema。

在ALTER DATABASE语句中,READ ONLY选项与自身其他实例以及其他选项相互影响,如下所示:

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

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

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

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

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

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

●作为服务器初始化、重新启动、升级或复制的一部分,是由服务器执行的语句。

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

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

●NDB群集非SQL插入和更新。

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

● 数据库

■ CREATE DATABASE

■ ALTER DATABASE (除非是更改 READ ONLY 选项)

■ DROP DATABASE

● 视图

■ CREATE VIEW

■ ALTER VIEW

■ DROP VIEW

■ 调用具有副作用函数的视图检索。

■ 正在更新可更新视图。

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

● 存储过程

   ■ CREATE PROCEDURE

■ DROP PROCEDURE

■ CALL (有副作用的存储过程)

■ CREATE FUNCTION

■ DROP FUNCTION

■ SELECT (有副作用的函数)

■ 对于存储过程和函数,只读检查遵循预锁定行为。对于CALL语句,只读检查是在每个语句的基础上进行的,因此,如果写入只读数据库的某些有条件执行的语句实际上没有执行,则调用仍然成功。另一方面,对于在SELECT中调用的函数,函数体的执行以预锁定模式进行。只要函数中的某些语句写入只读数据库,无论语句是否实际执行,函数的执行都会失败并出现错误。

● 触发器

■ CREATE TRIGGER

■ DROP TRIGGER

■ 触发器调用

● 事件

■ CREATE EVENT

■ ALTER EVENT

■ DROP EVENT

■ 事件执行:

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

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

● 表

■ CREATE TABLE

■ ALTER TABLE

■ CREATE INDEX

■ DROP INDEX

■ RENAME TABLE

■ TRUNCATE TABLE

■ DROP TABLE

■ DELETE

■ INSERT

■ IMPORT TABLE

■ LOAD DATA

■ LOAD XML

■ REPLACE

■ UPDATE

■ 对于子表位于只读数据库中的级联外键,即使子表不受直接影响,父表上的更新和删除也会被拒绝。

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

○ 如果s1、s2、s3中至少有一个是只读的,则插入MERGE表(INSERT into s1.t)失败,不管插入方法如何。即使插入实际上会在可写表中结束,也会被拒绝。

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

ALTER DATABASE语句将阻塞,直到所有已访问被更改数据库中的对象的并发事务都已提交。相反,对变更数据库中对象的并发写事务将阻塞,直到ALTER DATABASE提交。

如果克隆插件用于克隆本地或远程数据目录,则克隆中的数据库将保持其在源数据目录中的只读状态。只读状态不影响克隆过程本身。如果不希望在克隆中具有相同的数据库只读状态,则必须在克隆过程完成后,使用ALTER DATABASE操作显式更改克隆的数据库。

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

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

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

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

● 可以照常还原转储文件,但由于服务器忽略带注释的只读选项,因此还原的数据库不是只读的。如果要在还原后保持数据库只读,则必须手动执行ALTER DATABASE进行修改。

假设mydb是只读的,并按如下方式转储:

如果mydb仍应为只读,则后面的还原操作必须后跟ALTER DATABASE:

MySQL企业备份不受此问题的影响。它像其他数据库一样备份和还原只读数据库,但如果在备份时启用了只读选项,则在还原时启用该选项。

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

1.在单个会话中,为数据库禁用二进制日志记录,启用只读:

2.使用mysqldump或mysqlpump转储数据库:

3.在单个会话中,对数据库禁用二进制日志记录并禁用只读:

官方文档地址: https://dev.mysql.com/doc/refman/8.0/en/alter-database.html