当mysql表从压缩表变成普通表会发生什么

本文章做了把mysql表从压缩表过渡到普通表的实验过程,看看压缩表变成普通表会发生什么?本文针对mysql5.7和mysql8分别进行了实验。

1、什么是表压缩

在将压缩表引入普通表之前,让我们首先普及表压缩是什么。

[En]

Before introducing compressed tables to ordinary tables, let’s first popularize what table compression is.

表压缩,即表中的数据是以压缩格式存储的,压缩可以显著提高处理速度,压缩磁盘。压缩意味着硬盘和内存之间传输的数据更少,占用的内存和硬盘相对更少,这种压缩给二级索引带来的好处更明显,因为索引数据也是压缩的。

[En]

Table compression, which means that the data in the table is stored in a compressed format, compression can significantly improve processing speed and compress the disk. Compression means that less data is transferred between the hard disk and memory and takes up relatively less memory and the hard disk, and this compression brings more obvious benefits to secondary indexes because the index data is also compressed.

表压缩是有很大好处的,能减少磁盘的I/O,还能提高系统吞吐量,节约空间,压缩率越大,占用的磁盘空间越小,文件传输时间提升,降低数据的存储和网络传输成本。

2、如何表压缩( mysql的版本需要大于5.5 )

#打开配置文件
vim /etc/my.inf

#加入配置项
innodb_file_per_table=1
innodb_file_format=Barracuda
innodb_strict_mode=1 #建议加上
innodb_default_row_format = COMPRESSED #在整个库默认启用行压缩格式时设定,一边不改变此值

#重启数据库
systemctl restart mysqld
mysql> alter table t1 ROW_FORMAT=COMPRESSED;
mysql> alter table t1 ROW_FORMAT=DEFAULT;
  • mysql数据库版本:5.7.31
  • linux版本:centos5.7

1、建表和初始化测试数据


#1、建表
CREATE TABLE test_compress (
    id bigint(20) unsigned NOT NULL,
    identification_id int(10) unsigned DEFAULT NULL,
    timestamp datetime NOT NULL,
    action varchar(50) NOT NULL,
    result varchar(50) NOT NULL,
    PRIMARY KEY (id),
    KEY INDEX_test_compress_result (result),
    KEY INDEX_test_compress_timestamp (timestamp)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

#2、插入测试数据(linux里执行脚本)
for NUM in {1..100000}; do mysql -h localhost PS_57 -e "insert into test_compress (id, identification_id, timestamp, action, result) values ($NUM,$NUM*100,now(),concat('string',$NUM),concat('VeryVeryLargeString',$NUM))"; done

2、验证表的大小

让我们验证表的大小(之前执行innodb_stats_persistent_sample_pages=100000 的 ANALYZE 表,以便统计信息尽可能真实)。

set global innodb_stats_persistent_sample_pages=100000;
analyze table test_compress;

+------------------------+---------+----------+----------+
| Table                  | Op      | Msg_type | Msg_text |
+------------------------+---------+----------+----------+
| PS_57.test_compress    | analyze | status   | OK       |
+------------------------+---------+----------+----------+
Query OK, 0 rows affected (0.00 sec)
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+----------------+
| table_schema | table_name    | table_rows | TOTAL_MB | create_options |
+--------------+---------------+------------+----------+----------------+
| PS_57        | test_compress |     100000 |       37 |                |
+--------------+---------------+------------+----------+----------------+

3、对表压缩

接下来,我们将用KEY_BLOCK_SIZE=4压缩表(这个大小是任意选择的,在任何时候都没有指示或决定它是否是最优值,事实上,它不是)。

ALTER TABLE test_compress ROW_FORMAT=COMPRESSED,KEY_BLOCK_SIZE=4,ALGORITHM=INPLACE,LOCK=NONE;

Query OK, 0 rows affected (3.33 sec)

我们再次验证表的大小(以前执行innodb_stats_persistent_sample_pages=100000 的 ANALYZE 表,以便统计信息尽可能真实)。

set global innodb_stats_persistent_sample_pages=100000;

Query OK, 0 rows affected (0.00 sec)
analyze table test_compress;

+------------------------+---------+----------+----------+
| Table                  | Op      | Msg_type | Msg_text |
+------------------------+---------+----------+----------+
| PS_57.test_compress    | analyze | status   | OK       |
+------------------------+---------+----------+----------+
Query OK, 0 rows affected (0.00 sec)
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+----------------------------------------+
| table_schema | table_name    | table_rows | TOTAL_MB | create_options                         |
+--------------+---------------+------------+----------+----------------------------------------+
| PS_57        | test_compress |     100000 |       19 | row_format=COMPRESSED KEY_BLOCK_SIZE=4 |
+--------------+---------------+------------+----------+----------------------------------------+

这张桌子已经被压缩了,让我们检查一下它的结构。

[En]

The table has been compressed, let’s check its structure.

show create table test_compress;
*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint(20) unsigned NOT NULL,
  identification_id int(10) unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id),
  KEY INDEX_test_compress_result (result),
  KEY INDEX_test_compress_timestamp (timestamp)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4

1 row in set (0.00 sec)

4、压缩表解压缩(变成普通表)

ALTER TABLE test_compress ROW_FORMAT=DEFAULT,ALGORITHM=INPLACE,LOCK=NONE;

Query OK, 0 rows affected (6.25 sec)
Records: 0  Duplicates: 0  Warnings: 0

拉链解压成功,让我们来检查一下。

[En]

Unzipped successfully, let’s check it.

select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+--------------------+
| table_schema | table_name    | table_rows | TOTAL_MB | create_options     |
+--------------+---------------+------------+----------+--------------------+
| PS_57        | test_compress |     100000 |       25 | KEY_BLOCK_SIZE=4   |
+--------------+---------------+------------+----------+--------------------+

更好的检查:

show create table test_compress;

*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint(20) unsigned NOT NULL,
  identification_id int(10) unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id),
  KEY INDEX_test_compress_result (result),
  KEY INDEX_test_compress_timestamp (timestamp)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=4

出了点问题!KEY_BLOCK_SIZE仍然是4。

第二次尝试:

ALTER TABLE test_compress ROW_FORMAT=DEFAULT,KEY_BLOCK_SIZE=0,ALGORITHM=INPLACE,LOCK=NONE;

Query OK, 0 rows affected (2.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';
+--------------+---------------+------------+----------+--------------------+
| table_schema | table_name    | table_rows | TOTAL_MB | create_options     |
+--------------+---------------+------------+----------+--------------------+
| PS_57        | test_compress |     100000 |       25 |                    |
+--------------+---------------+------------+----------+--------------------+

更好的检查:

show create table test_compress\G
*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint(20) unsigned NOT NULL,
  identification_id int(10) unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id) KEY_BLOCK_SIZE=4,
  KEY INDEX_test_compress_result (result) KEY_BLOCK_SIZE=4,
  KEY INDEX_test_compress_timestamp (timestamp) KEY_BLOCK_SIZE=4
) ENGINE=InnoDB DEFAULT CHARSET=latin1

出了点问题!主键和二级索引都继续显示 KEY_BLOCK_SIZE=4。

尽管当表从压缩转换为未压缩时,在内部,索引的KEY_BLOCK_SIZE支持表的索引,但 CREATE TABLE 语句则不然。起初,这将是一个美学/外观问题,但是当您进行转储时,这是一个真正的问题,因为CREATE TABLE保留了KEY_BLOCK_SIZE值,这并不好。以下是 mysqldump 的输出:

mysqldump -h localhost PS_57 test_compress --no-data > test_compress.sql
cat test_compress.sql
...

--
-- Table structure for table test_compress
--

DROP TABLE IF EXISTS test_compress;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE test_compress (
  id bigint(20) unsigned NOT NULL,
  identification_id int(10) unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id) KEY_BLOCK_SIZE=4,
  KEY INDEX_test_compress_result (result) KEY_BLOCK_SIZE=4,
  KEY INDEX_test_compress_timestamp (timestamp) KEY_BLOCK_SIZE=4
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
ALTER TABLE test_compress
DROP PRIMARY KEY, add PRIMARY KEY (id),
DROP key INDEX_test_compress_result, add key INDEX_test_compress_result (result),
DROP key INDEX_test_compress_timestamp, add key INDEX_test_compress_timestamp (timestamp),
ROW_FORMAT=DEFAULT,KEY_BLOCK_SIZE=0,ALGORITHM=INPLACE,LOCK=NONE;

现在,它具有正确的定义,没有KEY_BLOCK_SIZE:

show create table test_compress;
*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint(20) unsigned NOT NULL,
  identification_id int(10) unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id),
  KEY INDEX_test_compress_result (result),
  KEY INDEX_test_compress_timestamp (timestamp)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';
+--------------+---------------+------------+----------+----------------+
| table_schema | table_name    | table_rows | TOTAL_MB | create_options |
+--------------+---------------+------------+----------+----------------+
| PS_57        | test_compress |     100000 |       25 |                |
+--------------+---------------+------------+----------+----------------+

5、针对第4步出现问题的bug

在MySQL 8中,情况如下:

select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+----------------+
| TABLE_SCHEMA | TABLE_NAME    | TABLE_ROWS | TOTAL_MB | CREATE_OPTIONS |
+--------------+---------------+------------+----------+----------------+
| PS_8         | test_compress |      31000 |       15 |                |
+--------------+---------------+------------+----------+----------------+

让我们执行 ALTER 来压缩表:

alter table test_compress ROW_FORMAT=COMPRESSED,KEY_BLOCK_SIZE=4,ALGORITHM=INPLACE,LOCK=NONE;

Query OK, 0 rows affected (4.54 sec)
Records: 0  Duplicates: 0  Warnings: 0

让我们再检查一下:

analyze table test_compress;

+-----------------------+---------+----------+----------+
| Table                 | Op      | Msg_type | Msg_text |
+-----------------------+---------+----------+----------+
| PS_8.test_compress    | analyze | status   | OK       |
+-----------------------+---------+----------+----------+
1 row in set (0.07 sec)
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+----------------------------------------+
| TABLE_SCHEMA | TABLE_NAME    | TABLE_ROWS | TOTAL_MB | CREATE_OPTIONS                         |
+--------------+---------------+------------+----------+----------------------------------------+
| PS_8         | test_compress |     100000 |       19 | row_format=COMPRESSED KEY_BLOCK_SIZE=4 |
+--------------+---------------+------------+----------+----------------------------------------+
show create table test_compress;
*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint unsigned NOT NULL,
  identification_id int unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
 action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id),
  KEY INDEX_test_compress_result (result),
  KEY INDEX_test_compress_timestamp (timestamp)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4
1 row in set (0.01 sec)

到目前为止,一切都与MySQL 5.7相同:KEY_BLOCK_SIZE保留在整个表的定义中,而不是索引的定义中。

同样的,也能通过下面sql对表进行解压缩:

alter table test_compress ROW_FORMAT=DEFAULT, KEY_BLOCK_SIZE=0,ALGORITHM=INPLACE,LOCK=NONE;

Query OK, 0 rows affected (2.56 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看解压缩情况

show create table test_compress;

*************************** 1. row ***************************
       Table: test_compress
Create Table: CREATE TABLE test_compress (
  id bigint unsigned NOT NULL,
  identification_id int unsigned DEFAULT NULL,
  timestamp datetime NOT NULL,
  action varchar(50) NOT NULL,
  result varchar(50) NOT NULL,
  PRIMARY KEY (id),
  KEY INDEX_test_compress_result (result),
  KEY INDEX_test_compress_timestamp (timestamp)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
select table_schema, table_name, table_rows,  round(data_length / 1024 / 1024)+round(index_length / 1024 / 1024)+round(data_free / 1024 / 1024) TOTAL_MB, create_options from information_schema.tables where table_name='test_compress';

+--------------+---------------+------------+----------+----------------+
| TABLE_SCHEMA | TABLE_NAME    | TABLE_ROWS | TOTAL_MB | CREATE_OPTIONS |
+--------------+---------------+------------+----------+----------------+
| PS_8         | test_compress |     100000 |       25 |                |
+--------------+---------------+------------+----------+----------------+

在MySQL 5.7中,完全解压缩一张压缩表的唯一方法(至少在表及其索引的定义中)是重新生成主键及其所有索引。否则, 主键和二级索引都继续显示压缩表时候的KEY_BLOCK_SIZE。

然后在MySQL8里,修复了这个问题在MySQL5.7出现的问题。

更多资讯,敬请关注微信公众号[程序员],分享优质文章,编程酷科技,帮你成为程序员!

[En]

For more information, please follow the Wechat official account [programmer], share high-quality articles, programming cool techs, to help you become a programmer!

Original: https://www.cnblogs.com/zhbeier/p/16470091.html
Author: 奇想派
Title: 当mysql表从压缩表变成普通表会发生什么

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505242/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • springboot~Screw生成数据库文档

    数据库说明文档,在我们开发项目时是非常必要的,有时项目交付时,客户也是需要让我们提供的,而如果人工编写,比如耗时,通过screw组件来生成文档,非常方便。 源代码和使用:https…

    数据库 2023年6月6日
    0139
  • StoneDB 读、写操作的执行过程

    背景介绍 StoneDB 是一款兼容 MySQL 的开源 HTAP 数据库。StoneDB 的整体架构分为三层,分别是应用层、服务层和存储引擎层。应用层主要负责客户端的连接管理和权…

    数据库 2023年5月24日
    0122
  • MRCTF2020 pyFlag

    可以看到在zip文件头和jpg文件尾中有提示这是秘密文件的part1,那么思路就打开了,将其他图片的秘密文件部分拼成一个文件即可。 全部合起来组成一个zip文件,不是伪加密,先爆破…

    数据库 2023年6月11日
    0119
  • 2022-8-26 jq简单了解

    Query 是一个 JavaScript 函数库。 jQuery 是一个轻量级的”写的少,做的多”的 JavaScript 库。jQuery 库包含以下功能…

    数据库 2023年6月14日
    0147
  • mysql关于权限

    use db; select user(),database();— 建立账号 create user user1; create user user2@’192,16…

    数据库 2023年6月9日
    0110
  • JVM详解

    一、JVM的位置及体系结构 JVM作用在操作系统之上,而Java程序作用在jvm之上,其他的程序则与jvm并列 二、类加载器,及双亲委派机制 1.类加载器 作用:加载Class文件…

    数据库 2023年6月16日
    098
  • 我的第一次校招

    2018-09-26 23:40:03 虽然是第一次参加,但这次的笔试完成结果让我不是很满意,因为有几道超简单的字符串编程没有做,忘了或者是想复杂了,还有一些概念题不是很清楚,自己…

    数据库 2023年6月16日
    0146
  • loadrunner 无法保存许可信息

    1.CONFUGURATION—>loadrunner license—>New License页面,输入许可信息,提示:无法保存许可信息 2.解决方法,使用管理员角色…

    数据库 2023年6月14日
    0147
  • maven项目编译报错处理

    1、问题一: [ERROR] Failed to execute goal on project data-common:Could not resolve dependencie…

    数据库 2023年6月11日
    0119
  • COLA 架构规范定义

    基础架构图 Adapter 适配层:对前端展示的路由和适配。 VO:返回给前端的对象 assembler:将 responseDTO 转换为 VO web:处理页面请求的 Cont…

    数据库 2023年6月6日
    0143
  • 高可用 | Xenon 实现 MySQL 高可用架构 常用操作篇

    原创:知数堂 上一篇文章,我们详细介绍了 Xenon 实现 MySQL 高可用架构的部署过程。接下来本篇将介绍 Xenon 的常用操作,帮助大家在完成环境搭建之后,能把 Xenon…

    数据库 2023年5月24日
    0137
  • Decorator 装饰(结构型)

    Decorator 装饰 (结构型) 一:描述: Decorator 装饰模式是动态地给一个对象增加一些额外的功能职责特性。 来替换以前使用的继承来静态扩展对象的功能,避免子类的增…

    数据库 2023年6月11日
    0114
  • Nginx实现服务器端集群搭建

    Nginx实现服务器端集群搭建 Nginx与Tomcat部署 前面课程已经将Nginx的大部分内容进行了讲解,我们都知道了Nginx在高并发场景和处理静态资源是非常高性能的,但是在…

    数据库 2023年6月6日
    0116
  • MySQL常用语句

    数据库设置 查看设置 `sql Original: https://www.cnblogs.com/1fengchen1/p/15781973.htmlAuthor: SonnyZ…

    数据库 2023年6月9日
    0102
  • MySQL实战45讲 12

    12 | 为什么我的MySQL会”抖”一下? 一条 SQL 语句,正常执行的时候特别快,但是 有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现…

    数据库 2023年6月16日
    0134
  • 2018年最新JAVA面试题总结之基础(1)

    转自于:https://zhuanlan.zhihu.com/p/39322967 1、JAVA中能创建volatile数组吗?volatile能使得一个非原子操作变成原子操作吗?…

    数据库 2023年6月16日
    0132
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球