乐趣区

关于数据库:StoneDB修改字段长度调研

一、调研

1. 反对状况调研

以 varchar 数据类型为例,开启调研。

1)其余引擎 / 数据库调研

对象 字段长度批改反对状况 详情
mysql-innodb 反对 严格模式:能够改大;能够改小,但不能批改小于已有数据的长度;非严格模式:能够改大;能够改小,会失落精确度
mysql-myisam 反对 严格模式:能够改大;能够改小,但不能批改小于已有数据的长度;非严格模式:能够改大;能够改小,会失落精确度
mariadb-columnstore 不反对 会报错
ClickHouse 不反对 有 String 类型,主动扩大,无需反对
TiDB 反对 只反对改大,不反对改小

验证过程:

innodb:

myisam:

mariadb-columnstore:

2)字段长度范畴限度

varchar 的长度范畴与字符集无关;
例如:

字符集 长度范畴
latin1 字符集 0~65532
utf8mb4 字符集 0~16383
utf8 字符集 0~21844

验证过程:

2.alter table 语法调研

1)反对性能

次要包含以下性能:

  • 索引的减少、删除
  • 列的减少、删除
  • 列的属性批改:类型批改、长度批改、重命名等
  • 引擎批改
  • 表重命名
  • 2)并发管制

    通过锁来进行管制并发,反对以下锁:
    LOCK= DEFAULT | NONE | SHARED | EXCLUSIVE

DEFAULT:默认形式,MySQL 自行判断应用哪种 LOCK 模式,尽量不锁表。

NONE:无锁:容许 Online DDL 期间进行并发读写操作。如果 Online DDL 操作不反对对表的持续写入,则 DDL 操作失败,对表批改有效。

SHARED:共享锁:Online DDL 操作期间梗塞写入,不影响读取。

EXCLUSIVE:排它锁:Online DDL 操作期间不容许对锁表进行任何操作。

3)算法反对

反对两种算法,8.0 后新增了一种算法:INSTANT。
ALGORITHM=COPY
ALGORITHM=INPLACE

  • copy 这个操作一行一行的 copy 数据从原始表到新表,而且不反对并发 DML,然而并发查问依然是反对的,默认应用共享锁(能够并发查问),也可指定排他锁(并发查问和 DML 都不反对)。
  • inplace 这个操作会防止 copy 表数据,然而可能会重建表。在数据筹备和执行阶段会进行行锁定,通常反对并发 DML。

mysql 默认抉择 inplace,如果存储引擎不反对,就会选中 copy。
应用 INPLACE 的算法场景包含:

  • alter table 的操作被 InnoDB online DDL 的个性所反对。
  • 重命名表。mysql 会重命名 table 对应的文件,并不会做 copy 数据的操作。(per_file_on_table 须要关上)
  • 仅批改表的元数据的操作。包含:rename column,变更列的默认值,不扭转数据类型存储空间的操作。
  • 重命名索引。
  • 增加或者删除一个二级索引。

4)总体反对状况

执行操作 容许 ALGORITHM=INPLACE 是否拷贝表 容许并发 DML 容许并发查问 备注和注意事项
create index add index Yes* No* Yes Yes 对于全文索引,有一些限度,具体看下一行。目前,该操作不是在原地执行,须要拷贝表。
add fulltext index Yes No* No Yes 创立第一个全文索引波及到拷贝表,除非有应用 FTS_DOC_ID 列。前面的全文索引则在原地执行。
drop index Yes No Yes Yes
optimize table Yes Yes Yes Yes 在 MySQL5.6.17 里应用 ALGORITHM=INPLACE。如果设置 old_alter_table= 1 或应用 mysqld –skip-new 选项,则应用 ALGORITHM=COPY。如果表应用了全文索引,则 ALGORITHM=INPLACE 不实用
set default value for column Yes No Yes Yes 批改.frm 文件,不波及数据文件
change auto-increment value Yes No Yes Yes 批改存储到内存的一个值,不批改数据文件
add foreign key constraint Yes* No* Yes Yes 禁用 foreign_key_checks, 则能够防止拷贝表
drop forgien key constraing Yes No Yes Yes foreign_key_checks 能够禁用或开启
rename column Yes* No* Yes* Yes 容许并发 DML,放弃雷同的数据类型,仅扭转字段名
add column Yes Yes Yes* Yes 减少 auto-increment 字段时不容许 DML 操作。尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
drop column Yes Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
reorder columns Yes Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
change ROW_FORMAT property Yes Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
change KEY_BLOCK_SIZE property Yes Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
make column null Yes Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,
make cplumn not null Yes* Yes Yes Yes 当 SQL_MODE 为 strict_all_tables, 如果执行的列蕴含 null,则会执行失败。尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉.
change data type of column No Yes Yes Yes
add primary key Yes* Yes Yes Yes 尽管 ALGORITHM=INPLACE 能够容许,然而数据要重组,代价比拟低廉。如果列必须转换为非空的条件下,ALGORITHM=INPLACE 是不容许的。
drop primary key and add other Yes Yes Yes Yes 当在同一个 alter table 新增主键时 ALGORITHM=INPLACE 是容许的. 数据要重组,因而代价比拟低廉。
drop primary key No Yes No Yes 删除主键然而又不新增主键是被限度的
convert character set No Yes No Yes 如果新的字符编码不同将会重建表
specify character set No Yes No Yes 如果新的字符编码不同将会重建表
rebulid with force option Yes Yes Yes Yes 在 MySQL5.6.17 里应用 ALGORITHM=INPLACE。如果设置 old_alter_table= 1 或应用 mysqld –skip-new 选项,则应用 ALGORITHM=COPY。如果表应用了全文索引,则 ALGORITHM=INPLACE 不实用
rebulid with “null” alter table … engine=innodb Yes Yes Yes Yes 在 MySQL5.6.17 里应用 ALGORITHM=INPLACE。如果设置 old_alter_table= 1 或应用 mysqld –skip-new 选项,则应用 ALGORITHM=COPY。如果表应用了全文索引,则 ALGORITHM=INPLACE 不实用

二、计划总结

1.alter table 执行流程

通过后期调研和代码剖析,批改字段长度总体实现流程如下:

函数整体调用流程如下:

次要性能实现集中在 mysql_alter_table 函数中,具体执行流程如下:

次要性能介绍和对应接口如下:
1. 关上表:

open_tables(thd, &table_list, &tables_opened, 0,&alter_prelocking_strategy);

2. 查看引擎是否反对,批改后的表的数据类型:

check_engine

3. 查看引擎是否反对 alter 操作:

ha_check_storage_engine_flag

4.alter table 预处理:包含列属性的赋值、新列的增加、列的删除等,其中会调用到引擎的 update_create_info 函数,用于赋值一些创立表的信息,stonedb 引擎的此函数为空:

mysql_prepare_alter_table

5. 算法抉择
判断每个引擎是否反对 inplace 算法进行 alter table:

check_if_supported_inplace_alter

如果反对 inplace 算法进行 alter table 解决:

通过 mysql_inplace_alter_table 调用引擎的
prepare_inplace_alter_table
inplace_alter_table
commit_inplace_alter_table
这三个接口进行解决

如果不反对则采纳 copy 算法,创立新表 -> 复制数据 > 新表旧表重命名 > 删除旧表,达到 alter table 目标:

ha_create_table -- 创立表
copy_data_between_tables -- 复制数据
mysql_rename_table -- 重命名表
quick_rm_table -- 删除表

2. 批改计划

1)批改引擎代码,使其走 copy 算法。
2)update_create_info 函数,须要实现,用于更新创立新表时候的一些信息。
3)inplace 算法须要批改,减少性能,使其反对索引的减少和删除等其余操作。
波及批改的函数,包含以下函数:

check_if_supported_inplace_alter
check_if_incompatible_data
prepare_inplace_alter_table
inplace_alter_table
commit_inplace_alter_table
退出移动版