您可以将分区和二级子分区设置为只读状态,用于保护数据不受任何用户或触发器执行的DML操作的影响。
只读分区如下图所示:
语法
- 新建表时创建只读分区
其中partition_options为:CREATE TABLE [IF NOT EXISTS] [schema.]table_name table_definition [READ {ONLY | WRITE}] partition_options;
partition_definition为:PARTITION BY { RANGE{(expr) | COLUMNS(column_list)} } [(partition_definition [, partition_definition] ...)]
PARTITION partition_name [VALUES LESS THAN {expr | MAXVALUE}] [READ {ONLY | WRITE}] [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'string' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] tablespace_name]
- 修改表时创建只读分区
其中partition_options为:ALTER TABLE tbl_name [alter_option [, alter_option] ...] [partition_options]
partition_option为:partition_options: partition_option [partition_option] ...
partition_definition为:partition_option: { ADD PARTITION (partition_definition)
其中alter_option为:PARTITION partition_name [VALUES LESS THAN {expr | MAXVALUE}] [READ {ONLY | WRITE}] [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'string' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] tablespace_name]
alter_option: { table_options | ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name] | ADD [COLUMN] (col_name column_definition,...) | ADD {INDEX | KEY} [index_name] [index_type] (key_part,...) [index_option] ... | ADD {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY] [index_name] [index_type] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name,...) reference_definition | ADD [CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED] | DROP {CHECK | CONSTRAINT} symbol | ALTER {CHECK | CONSTRAINT} symbol [NOT] ENFORCED | ALGORITHM [=] {DEFAULT | INSTANT | INPLACE | COPY} | ALTER [COLUMN] col_name { SET DEFAULT {literal | (expr)} | SET {VISIBLE | INVISIBLE} | DROP DEFAULT } | ALTER INDEX index_name {VISIBLE | INVISIBLE} | CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST | AFTER col_name] | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name] | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name] | {DISABLE | ENABLE} KEYS | {DISCARD | IMPORT} TABLESPACE | DROP [COLUMN] col_name | DROP {INDEX | KEY} index_name | DROP PRIMARY KEY | DROP FOREIGN KEY fk_symbol | FORCE | LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE} | MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name] | ORDER BY col_name [, col_name] ... | RENAME COLUMN old_col_name TO new_col_name | RENAME {INDEX | KEY} old_index_name TO new_index_name | RENAME [TO | AS] new_tbl_name | {WITHOUT | WITH} VALIDATION }
参数
参数名称 | 参数说明 |
---|---|
table_name | 表名称。 |
expr | 分区字段表达式。 |
column_list | 分区字段列表,不支持表达式。 |
MAXVALUE | 最大值。 |
partition_name | 分区名称,同一个表中不可重复。 |
engine_name | 存储引擎名称。 |
table_options | 表选项。 |
col_name | 列名。 |
注意事项
您不能修改只读分区的数据。如果尝试修改只读分区的数据,系统会报错ERROR HY000: Data in a read-only partition or subpartition cannot be modified.
。这里的修改操作不仅仅包括INSERT、UPDATE和DELETE操作,任何对只读分区数据结果产生变化的DDL操作都会被拒绝。
由于添加列不会修改原有的只读数据属性,因此添加列是被允许的。如下:
ALTER TABLE [schema.]table_name ADD col_new varchar(100) DEFAULT 'i am not empty';
示例
创建
t1
表时,指定t1
表的所有分区为只读分区CREATE TABLE t1 (
id INT,
year_col INT
) READ ONLY
PARTITION BY RANGE (year_col) (
PARTITION p0 VALUES LESS THAN (2001),
PARTITION p1 VALUES LESS THAN (2010),
PARTITION p2 VALUES LESS THAN (2020)
);
为
t1
表新增只读分区ALTER TABLE t1 ADD PARTITION (PARTITION p3 values LESS THAN (2030));
Query OK, 0 rows affected (0.22 sec)
Records: 0 Duplicates: 0 Warnings: 0
新增只读分区后,可以发现新分区仍然为只读分区SHOW CREATE TABLE t1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`year_col` int(11) DEFAULT NULL
) /*!99990 800020201 READ ONLY */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY RANGE (`year_col`)
(PARTITION p0 VALUES LESS THAN (2001) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (2010) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2020) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (2030) ENGINE = InnoDB) */ |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
为
t1
表创建混合属性的分区CREATE TABLE t1 (
id INT,
year_col INT
) READ WRITE
PARTITION BY RANGE (year_col) (
PARTITION p0 VALUES LESS THAN (2001) READ ONLY,
PARTITION p1 VALUES LESS THAN (2010),
PARTITION p2 VALUES LESS THAN (2020) READ ONLY
);
如何查看只读分区
目前只能通过SHOW CREATE命令查询分区表的分区只读属性,例如:
show create table t1;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`year_col` int(11) DEFAULT NULL
) /*!99990 800020201 READ WRITE */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY RANGE (`year_col`)
(PARTITION p0 VALUES LESS THAN (2001) */ /*!99990 800020201 READ ONLY */
/*!50100 ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (2010) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2020) */ /*!99990 800020201 READ ONLY */
/*!50100 ENGINE = InnoDB) */ |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)