innodb compressed 表碰到的问题

compressed innodb 表是MySQL 5.5开始提供的功能,可以把innodb表压缩,对于这个操作,很多人已经说到了,主要要注意两点:
压缩的语法是:
alter/create table …. engine=innodb row_format=compressed key_block_size=8;
其中,row_format=compressed 代表要做压缩表了,key_block_size可选(1,2,4,8,16),16是不压缩,innodb的默认值,比16小都压缩。非这几个值的话,语句无效。

同时要实现这个功能需要配置:
innodb_file_per_table
innodb_file_format = Barracuda

另外,要注意 InnoDB “strict mode” 的时候,也会报错。

这次碰到的问题其实跟上面的没有关系,所以,上面是废话。

下面说事儿:
一个同事有个表是 row_format=compressed key_block_size=8 的,他想把它改回row_format=compact的非压缩模式。但是碰到了问题:

mysql 5.5>alter table t engine =innodb row_format=compact;
ERROR 1005 (HY000): Can’t create table ‘test.#sql-684d_924′ (errno: 140 “Wrong create options”)

这两个error是:
+———+——+—————————————————————————–+
| Level | Code | Message |
+———+——+—————————————————————————–+
| Warning | 140 | InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. |
| Error | 1005 | Can’t create table ‘test.#sql-684d_924′ (errno: 140 “Wrong create options”) |
+———+——+—————————————————————————–+
这是在5.5下面的结果,改不回来了!

接下来我们在5.6.13和MariaDB10下面测试,仅仅报了一个warning,说compact的时候不用指定 key_block_size了,这是可以理解的。
显然5.6做了bug修复。
通过竹峰大侠的指点,我们来看看源码:
这个判断是在 storage/innobase/handler/ha_innodb.cc 里面的create_options_are_valid函数实现的:

在5.5里面是这么写:

首先定义一个变量:
ibool kbs_specified = FALSE;
然后判断有key_block_size的话,设置kbs_specified = TRUE;
if (create_info->key_block_size) {
kbs_specified = TRUE;
…..

}
结束这个if之后,在外面case row type:
case ROW_TYPE_COMPACT:
case ROW_TYPE_REDUNDANT:
if (kbs_specified) {
push_warning_printf(
thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
“InnoDB: cannot specify ROW_FORMAT = %s”
” with KEY_BLOCK_SIZE.”,
get_row_format_name(row_format));
ret = FALSE;
}
break;

通过上面的代码可以看到,在row type为 C或者R的时候,如果kbs_specified 指定了,直接给报错退出了!
也就是,你的语法是 create/alter table …. engine =innodb row_format=compact key_block_size=xx;
这样的语句在5.5的时候是不能执行的,直接报错退出。就是上面我们看的错误。
那么,如果create/alter table …. engine =innodb row_format=compact ;这样的语句在平时没问题,但是如果表原来是compressed的模式的,你即便不指定 key_block_size,它原来还是存在的,也会报错退出!

再来看看5.6的代码,也是老地方 storage/innobase/handler/ha_innodb.cc ,只是函数名改为了create_options_are_invalid,看出区别了么?哈哈。

实现基本一样,也是有个变量
ibool kbs_specified = FALSE;

if (create_info->key_block_size) {
kbs_specified = TRUE;
。。。。。。
}
只是不同之处是:

case ROW_TYPE_COMPACT:
case ROW_TYPE_REDUNDANT:
if (kbs_specified) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
“InnoDB: cannot specify ROW_FORMAT = %s”
” with KEY_BLOCK_SIZE.”,
get_row_format_name(row_format));
ret = “KEY_BLOCK_SIZE”;
}
break;

在case里面,即便是发现kbs_specified,设置了 ret = “KEY_BLOCK_SIZE”,而不是5.5里面的False。
从而语句能顺利执行。

那么回过头来,5.5里面怎么做呢?DBA能被尿憋死么?

我们发现,在定义的时候
ibool kbs_specified = FALSE;
这个变量设置为true的时候是在

if (create_info->key_block_size) {
kbs_specified = TRUE;
。。。。。。
}
那么,如果我们的语句写成
alter table t engine =innodb row_format=compact key_block_size=0;
是不是就没问题了?
实践一下,答案是YES!

这个,不知道是innodb的bug,还是故意留的后门?
这个或许只能求《走进科学》解答了。。。

innodb compressed 表碰到的问题,BUG么?的更多相关文章

  1. InnoDB:表

    数据在表中是如何进行组织存放的?下面我们就来看看: InnoDB引擎表的类型 InnoDB表都会有一个主键. 如果没有显示的指定主键,首先会去查找,看是否有非空的唯一索引, 如果有,则该列为主键:如果 ...

  2. ibdata1文件损坏时恢复InnoDB单表测试

      Preface       ibdata1 file is a shared system tablespace of innodb engine.Although we always set v ...

  3. 9. InnoDB通用表空间

    9. InnoDB通用表空间 通用表空间是InnoDB 使用CREATE TABLESPACE语法创建的共享表空间.本节中的以下主题描述了常规表空间功能和功能: 通用表空间功能 创建通用表空间 将表添 ...

  4. innodb的表最大限制

    相信大多数人都不知道,innodb的表最大限制为64TB,但是why? Each space is divided into pages, normally 16 kib each (this can ...

  5. 开启InnoDB每表一个独立的表空间

    mysql> show variables like '%innodb%'; +---------------------------------+----------------------- ...

  6. 14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小

    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小 这个章节描述如何增加或者减少 InnoDB 系统表空间的大小 增加InnoDB ...

  7. InnoDB 数据表压缩原理与限制

    http://liuxin1982.blog.chinaunix.net/uid-24485075-id-3523032.html 压缩理念 通过提高CPU利用率和节约成本,降低数据库容量及I/O负载 ...

  8. mysql-5.7 扩展innodb系统表空间详解

    一.innodb系统表空间的简介: innodb 系统表空间是由若干个文件组成的,表空间的大小就是对应文件的大小,表空间文件是由innodb_data_file_path 这人参数来定义的.下面我们来 ...

  9. 【转载】Innodb共享表空间VS独立表空间

    http://www.mysqlsupport.cn/innodb%E5%85%B1%E4%BA%AB%E8%A1%A8%E7%A9%BA%E9%97%B4vs%E7%8B%AC%E7%AB%8B%E ...

随机推荐

  1. 全网最详细的CentOS7里安装MySQL时出现No package mysql-server available错误的解决办法(图文详解)

    不多说,直接上干货! 直接yum install mysql的话会报错,原因在于yum安装库里没有直接可以用的安装包,此时需要用到MariaDB了,MariaDB是MySQL社区开发的分支,也是一个增 ...

  2. Python学习--02输入和输出、运算符

    命令行输入 x = input("Please input x:") y = raw_input("Please input x:") 使用input和raw_ ...

  3. JavaScript中十种一步拷贝数组的方法

    JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下. 1.扩展运算符(浅拷贝) 自从ES6出现以来,这已经成为最流行的方法.它是一个很简单的语法,但是 ...

  4. visual studio code 个人设置

    { "vim.disableAnnoyingNeovimMessage": true, "php.validate.executablePath": " ...

  5. 状态管理Vuex

    路由Router 配置 {path:'/login',component:Login} 路由出口 router-view 传参 {path:'/login/:id',component:Login} ...

  6. es6学习笔记11--Proxy和Reflect

    Proxy概述 Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. Proxy可以理解成,在目标对象之前 ...

  7. V8源码边缘试探-黑魔法指针偏移

    这博客是越来越难写了,参考资料少,难度又高,看到什么写什么吧! 众多周知,在JavaScript中有几个基本类型,包括字符串.数字.布尔.null.undefined.Symbol,其中大部分都可以在 ...

  8. Spring Security认证配置(三)

    学习本章之前,可以先了解下上篇Spring Security认证配置(二) 本篇想要达到这样几个目的: 1.登录成功处理 2.登录失败处理 3.调用方自定义登录后处理类型 具体配置代码如下: spri ...

  9. win2d 图片水印

    本文告诉大家如何使用 win2d 给图片加上水印. 安装 首先需要使用 Nuget 安装 win2d ,安装参见win10 uwp win2d 如果没有更新 dot net core 那么在运行可能会 ...

  10. asp.net core webapi 使用ef 对mysql进行增删改查,并生成Docker镜像构建容器运行

    1.构建运行mysql容器,添加数据库user 参考Docker创建运行多个mysql容器,地址 http://www.cnblogs.com/heyangyi/p/9288402.html 添加us ...