MySQL 8.0 リファレンスマニュアル


13.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 オプションは、デフォルトのデータベース照合順序を変更します。 文字セットおよび照合順序名の詳細は、第10章「文字セット、照合順序、Unicode を参照してください。

使用可能な文字セットおよび照合順序を確認するには、それぞれ SHOW CHARACTER SET ステートメントおよび SHOW COLLATION ステートメントを使用します。 セクション13.7.7.3「SHOW CHARACTER SET ステートメント」およびセクション13.7.7.4「SHOW COLLATION ステートメント」を参照してください。

ルーチンの作成時にデータベースのデフォルトを使用するストアドルーチンには、それらのデフォルトがその定義の一部として含まれます。 (ストアドルーチンでは、文字セットまたは照合順序が明示的に指定されていない場合、文字データ型を伴う変数は、データベースのデフォルトを使用します。 セクション13.1.17「CREATE PROCEDURE ステートメントおよび CREATE FUNCTION ステートメント」を参照してください。) データベースのデフォルトの文字セットまたは照合順序を変更する場合は、新しいデフォルトを使用するストアドルーチンを削除して再作成する必要があります。

暗号化オプション

MySQL 8.0.16 で導入された ENCRYPTION オプションは、データベースで作成されたテーブルによって継承されるデフォルトのデータベース暗号化を定義します。 許可される値は、'Y' (暗号化有効) および'N' (暗号化無効) です。 新しく作成されたテーブルのみがデフォルトのデータベース暗号化を継承します。 データベースに関連付けられている既存のテーブルの場合、暗号化は変更されません。 table_encryption_privilege_check システム変数が有効になっている場合、default_table_encryption システム変数の値とは異なるデフォルトの暗号化設定を指定するには、TABLE_ENCRYPTION_ADMIN 権限が必要です。 詳細は、スキーマおよび一般テーブルスペースの暗号化デフォルトの定義を参照してください。

読取り専用オプション

MySQL 8.0.22 で導入された READ ONLY オプションは、データベースおよびデータベース内のオブジェクトの変更を許可するかどうかを制御します。 許可される値は、DEFAULT または 0 (読取り専用ではない) および 1 (読取り専用) です。 READ ONLY が有効になっているデータベースは、操作中にデータベースが変更される可能性があることに関係なく、別の MySQL インスタンスに移行できるため、このオプションはデータベースの移行に役立ちます。

NDB Cluster では、ある mysqld サーバー上のデータベースを読み取り専用にすると、同じクラスタ内のほかの mysqld サーバーと同期されるため、データベースはすべての mysqld サーバー上で読み取り専用になります。

READ ONLY オプションが有効になっている場合は、INFORMATION_SCHEMA SCHEMATA_EXTENSIONS テーブルに表示されます。 セクション26.32「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 オプションと他のオプションを混在させることができます。 読取り専用状態が変更前と変更後の両方で禁止されている場合、エラーが発生します。

    このステートメントは、データベースが読取り専用かどうかにかかわらず成功します:

    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 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

    • 子テーブルが読取り専用データベースにあるカスケード外部キーの場合、子テーブルが直接影響を受けない場合でも、親での更新および削除は拒否されます。

    • CREATE TABLE s1.t(i int) ENGINE MERGE UNION (s2.t, s3.t), INSERT_METHOD=... などの MERGE テーブルの場合、次の動作が適用されます:

      • 挿入方法に関係なく、少なくともいずれかの s1, s2, s3 が読取り専用の場合、MERGE テーブル (INSERT into s1.t) への挿入は失敗します。 挿入は、実際に書込み可能なテーブルで終了する場合でも拒否されます。

      • s1 が読取り専用でないかぎり、MERGE テーブル (DROP TABLE s1.t) の削除は成功します。 読取り専用データベースを参照する MERGE テーブルを削除できます。

ALTER DATABASE ステートメントは、変更中のデータベース内のオブジェクトにすでにアクセスしているすべての同時トランザクションがコミットされるまでブロックされます。 逆に、同時 ALTER DATABASE で変更されるデータベース内のオブジェクトにアクセスする書込みトランザクションは、ALTER DATABASE がコミットされるまでブロックされます。

クローンプラグインを使用してローカルまたはリモートのデータディレクトリをクローニングする場合、クローン内のデータベースは、ソースデータディレクトリにあった読取り専用状態を保持します。 読取り専用状態は、クローニングプロセス自体には影響しません。 クローンで同じデータベース読取り専用状態にすることが望ましくない場合は、クローンで ALTER DATABASE 操作を使用して、クローニングプロセスの終了後にクローンのオプションを明示的に変更する必要があります。

ドナーから受信者にクローニングする場合、受信者に読取り専用のユーザーデータベースがあると、クローニングは失敗し、エラーメッセージが表示されます。 クローニングは、データベースを書込み可能にした後に再試行できます。

READ ONLY は、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 オプションは処理されません。 これは、SHOW CREATE DATABASE を使用してダンプ出力に CREATE DATABASE ステートメントを生成する mysqldump および mysqlpump に影響します:

  • ダンプファイルでは、読取り専用データベースの CREATE DATABASE ステートメントにコメント付きの READ ONLY オプションが含まれています。

  • ダンプファイルは通常どおりリストアできますが、サーバーはコメント化された READ ONLY オプションを無視するため、リストアされたデータベースは読取り専用ではありません。 リストア後にデータベースを読取り専用にする場合は、ALTER DATABASE を手動で実行して読取り専用にする必要があります。

mydb が読取り専用で、次のようにダンプするとします:

shell> mysqldump --databases mydb > mydb.sql

mydb を読取り専用にする必要がある場合は、後でリストア操作の後に ALTER DATABASE を実行する必要があります:

shell> 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. たとえば、mysqldump または mysqlpump を使用してデータベースをダンプします:

    shell> mysqldump --databases mydb > mydb.sql
  3. 単一セッション内で、バイナリロギングを無効にし、データベースの READ ONLY を無効にします:

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

関連キーワード:  ステートメント, データベース, CREATE, DATABASE, 専用, TABLE, READ, ONLY, DROP, 読取り