change log

gdb info

set args --defaults-file=etc/my.cnf --user=liuzhuan

调试的断点列表

mysql_alter_table()

create_table_info_t::innobase_table_flags()

修改发生位置

./sql/mysqld.cc: //[liuzhuan] 增加一个全局hash存储算法项

./plugin/daemon_example/daemon_example.cc: //[liuzhuan] 改写为mysql_pthread(sep-15 second)静默方式刷盘算法数据

./storage/innobase/handler/ha_innodb.cc: //[liuzhuan] 改写为向hash存储算法项,key是table name(排除临时表),value是算法

./storage/innobase/os/os0file.cc://[liuzhuan] os0file刷盘page位置增加了算法分支,分支的入参是IORequest这个类,算法的判断依据来自hash内存储的key

./storage/innobase/include/os0file.h //[liuzhuan] 修改了IORequest这个类,增加了算法判断的一个表达式,这样的考虑个人认为是比较妥当的,因为堆栈函数的入参不用去改了

mysql5.6以后内部在alter table上有两种算法,做如下定义

ALGORITHM=INPLACE

ALGORITHM=COPY

copy table方式

新建跟原表格一致的临时表,并在该临时表上执行DDL语句

锁原表,不允许DML,允许查询

逐行数据从原表拷贝到临时表中(这个过程是没有排序的)

拷贝结束后,原表禁止读操作,也就是原表此时不提供读写服务

进行rename操作,完成DDL过程

inplace方式(fast index creation,仅针对索引的创建跟删除)

新建frm临时文件

锁原表,不允许DML,允许查询

按照聚集索引的顺序,查询数据,找到需要的索引列数据,排序后插入到新的索引页中

原表禁止读操作,也就是原表此时不提供读写服务

进行rename操作,替换frm文件,完成DDL过程

这两种算法的IO行为区别很大,具体在这里不再表述,引用一个博主的文章,对online ddl解释的非常漂亮了:

SQL语句默认的算法行为

inplace算法

alter table encrypt_test_1 ENCRYPTION='y';

alter table encrypt_test_1 add passtest int(4) default 0, ADD genedetail varchar(50) default '0', encryption='y';

CREATE TABLE `test_5` (

`id` int(11) DEFAULT NULL,

`name` varchar(32) DEFAULT NULL,

`passtest` int(4) DEFAULT '0',

`genedetail` varchar(50) DEFAULT '0'

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ENCRYPTION='n';

CREATE INDEX idd1 ON test_5 (`id`);

ALTER TABLE test_5 ADD INDEX nameid1 (name);

DROP INDEX idd1 ON test_5;

ALTER TABLE test_5 DROP INDEX nameid1;

CREATE FULLTEXT INDEX nameid1 ON test_5(name);

DROP INDEX nameid1 ON test_5;

ALTER TABLE test_5 ADD CONSTRAINT fk_name1 FOREIGN KEY(id) REFERENCES t1(id);

copy算法

CREATE TEMPORARY TABLE aaa as ( select * from encrypt_test_1);

CREATE TABLE aaa as ( select * from encrypt_test_1);

alter table encrypt_test_1 ENCRYPTION='n';

mysql 5.7后版本中的一个bug

CREATE TABLE `test_5` (

`id` int(11) DEFAULT NULL,

`name` varchar(32) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8 encryption='y';

然后取消encryption,设置alter table test_5 encryption='n';

最后执行alter table test_5 ENGINE=myisam会出错,这里在

./storage/myisam/ha_myisam.cc中ha_myisam::create()存在一处bug

2024 if (ha_create_info->encrypt_type.length > 0)

2025│ {

2026│ set_my_errno(HA_WRONG_CREATE_OPTION);

2027│ DBUG_RETURN(HA_WRONG_CREATE_OPTION);

2028│ }

这个条件是不可能失败的,这样的结果就是encrypt后的innodb表,转myisam都会失败,这在mariadb中是通过table comment解决的,他把这种变革前的语句写到了comment里,想法也说不上多好

但也算个解决方法吧

他也间接导致sql_table.cc-->mysql_alter_table()函数的copy模式下:

9871行

if (ha_create_table())

goto err_new_table_cleanup; //成立

从而返回 ERROR 1031 (HY000): Table storage engine for '#sql-1ba8_2' doesn't have this option

根据上述两种算法,在alter table中找到算法发生位置,一共要修改三处

bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name, HA_CREATE_INFO *create_info, ABLE_LIST *table_list, Alter_info *alter_info){

1:

9230行,if (alter_ctx.is_table_renamed()) 他是alter table ... reanme ... 词法的切入点,这里直接发生调用mysql_rename_table,然后根据执行状态返回true(失败)或false(成功)

if (table->s->tmp_table != NO_TMP_TABLE) 判断是否具备临时表,table->s->tmp_table有定义好的几种类型在table.h中定义

引用table.h中定义

enum tmp_table_type

{

NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE, INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE

};

INTERNAL_TMP_TABLE : 大致如'#sql-5bf6',内部临时表后是一个动态数,每次mysql重启,这个动态数都会更新

TRANSACTIONAL_TMP_TABLE : 更多发生在inplace模式,事务性临时表

这个位置修改alter rename对hash的操作

2:

9733行, switch (inplace_supported) 这里进入inplace模式的处理,这种情况下,if (use_inplace)条件成立

这个位置处理无table io的流程(inplace无io,这里切换hash算法是不能被支持的)

3:

9822行,if (!table->s->tmp_table) 这里进去表拷贝模式

这个位置处理copy io流程下,表的encrypt关键字变更

}

mysql有table函数吗_mysql_alter_table函数流程的部分修改和注解相关推荐

  1. MySql基础篇---004 其它数据库对象篇:视图,存储过程与函数,变量、流程控制与游标 ,触发器

    第14章_视图 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 1. 常见的数据库对象 对象 描述 表(TABLE) 表是存储数据的逻辑单元,以行和列的形 ...

  2. MySQL(视图、存储过程与函数、流程控制、触发器)

    第一章 视图 1 什么是视图 为了提高复杂的SQL语句的复用性和表的操作的安全性 ,MySQL数据库管理系统提高了视图特性,所谓视图,本质上是一种虚拟表,其内容与真实的表相似,包含一系列带有名称的列和 ...

  3. MySQL 学习笔记(3)— 字符串函数、数值函数、日期时间函数、流程函数、聚集函数以及分组数据

    1. 字符串函数 MySQL 的常用函数包括字符串函数.数值函数.日期时间函数.流程函数等. SELECT ascii("abc"),char(97),concat("h ...

  4. mysql now str,数据库学习之MySQL (十)—— 日期和时间函数 NOW STR_TO_DATE DATE_FORMAT 流程控制函数 IF IFNULL CASE...

    MySQL学习专栏 正在持续更新中:) 文章目录 日期和时间函数 NOW STR_TO_DATE DATE_FORMAT 流程控制函数 IF IFNULL CASE 下章预告 日期和时间函数 NOW ...

  5. 加密解密,MySQL单行函数,数学函数字符串日期时间,流程控制,完整详细可收藏查询SQL

    前些天发现了十分不错的人工智能学习网站,通俗易懂,风趣幽默,没有广告,分享给大家,大家可以自行看看.(点击跳转人工智能学习资料) 文章目录 1.函数的理解 2.数值函数 2.1 基本函数 2.2 角度 ...

  6. 我的MYSQL学习心得(六) 函数

    2019独角兽企业重金招聘Python工程师标准>>> 这一节主要介绍MYSQL里的函数,MYSQL里的函数很多,我这里主要介绍MYSQL里有而SQLSERVER没有的函数 数学函数 ...

  7. mysql+if+x+mod+2_MySQL常用函数 二

    结合MySQL自带的帮助文档列一下MySQL数据库中常用的一些函数. 事实证明:MySQL的联机帮助资料非常实用,希望哪一天可爱的Oracle可以像MySQL学习一下,她可以让您基本不用查看其他的资料 ...

  8. MySql基础篇---002 SQL之SELECT使用篇: 基本的SELECT语句,运算符,排序与分页,多表查询,单行函数,聚合函数,子查询

    第03章_基本的SELECT语句 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑 ...

  9. hibernate mysql 时间比较_Hibernate中HQL函数汇总及获取当前时间进行比较举例

    在很多时候,我们负责的项目中,在数据访问层(DAO层)通常我们会使用sql语句或者hql语句,而在我们使用hql语句拼接时有时会报错,通常的原因是:我们使用了标准的sql语句,开启的确是hiberna ...

最新文章

  1. SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全
  2. vue 目录名称详解_使用脚手架创建vue项目目录详解
  3. anconda安装后命令行中安装tensorflow报错
  4. 跟无闻学习GO Web 编程(四) -- bee 工具使用
  5. linux里打包和压缩文件,linux ---打包和压缩文件
  6. oracle对象类型的member方法
  7. Dropout视角下的MLM和MAE:一些新的启发
  8. CVPR 2020 开源论文 | 多种可能性行人未来路径预测
  9. 跨平台---udpclient与udpserver
  10. IOS之学习笔记十四(协议的定义和实现)
  11. 谷爱凌惊“险”一跳,最少价值10个亿!
  12. 华为2018年收入超阿里腾讯总和,任正非:华为最大问题是赚钱太多
  13. 路径中“./”、“../”、“/”代表的含义
  14. 一份完整的建模文档需涵盖的模块与指标
  15. KeyMob手机聚合平台已集成多家移动广告平台
  16. pythonos文件目录方法_python12-OS模块(文件/目录方法)
  17. 应用于电力电子变压器的双向DC_DC变换器综述(学习笔记)
  18. Unity3D开发之画墙、地面分割(户型绘制)
  19. 尚学堂马士兵struts2 课堂笔记(二)
  20. 七种常见的数据分析法之:帕累托法则

热门文章

  1. oracle清空无效数据,如何清除编译后留下的无效对象
  2. 2021年图灵奖公布!72岁的美国科学家 Jack Dongarra 获奖
  3. 唐人街神探:用数学方法确定罪犯位置
  4. 过年,你肯定会用到这款小程序!
  5. c语言使用循环编写勾股数,刘徽《九章算术》中的勾股数
  6. id 重启event_windows 2003 R2 系统自动重启了. event ID 6008
  7. html5调用系统声音1s响一次_20款奔驰GLC260提车改柏林之声音响,音乐诉请,为爱发声!...
  8. 《论可计算数及其在判定上的应用》简单理解
  9. 蝌蚪与青蛙是同一个物种么?
  10. Java8 默认方法