• 主页
  • 随笔
所有文章 友链 关于我

  • 主页
  • 随笔

InnoDB表快速修改字段名方案

2022-09-28

最近被问到一个问题,InnoDB 表,只修改一个字段的名字,定义不修改,是否有快速方案。
这个需求的意义来源于,在表设计初期可以预留一些字段,但在预留字段投入使用时,最好能够赋予一个有意义的名字以方便使用。
复现
以下实验基于 5.1.48 版本。
创建一个简单表

| CREATE TABLE t (
c1 int(11) DEFAULT NULL,
c2 int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

插入 10w 条数据。将字段 c2 改名为 c3.

| mysql> alter table t change c2 c3 int(11) default null;
Query OK, 100000 rows affected (4.29 sec)

Records: 100000 Duplicates: 0 Warnings: 0

可以看到,虽然只是简单修改了字段名,在实验机器上耗时达到 4.2s,显然重做了所有数据。由于这个表没有索引,数据量也比较小,如果对于更大数据的表,则需要更长的操作时间。
分析
我们知道,在
Innodb_file_per_table 参数下,每个 InnoDB 表有两个文件 t.frm 和 t.ibd. 实际上,表字段信息只保存于 t.frm。这个文件保存了表的定义信息,只有 8k。 仅修改字段名,实际上不需要重作数据,如果能够只对 t.frm 做修改,则可以加快上面这个 alter 语句的执行速度。
源码相关
可以想象 MySQL 框架中应该是调用了 InnoDB 引擎的某个函数,用于判断是否需要重做数据。
我们追踪一下 alter table 语句的执行流程,在 mysql_alter_table(sql_table.cc)函数中,我们看到这个局部变量 need_copy_table,它有三个可能的取值。
ALTER_TABLE_METADATA_ONLY= 0,
ALTER_TABLE_DATA_CHANGED= 1,
ALTER_TABLE_INDEX_CHANGED= 2
显然这个取值的判断结果,决定了后面的执行流程。
mysql_alter_table 中调用了 compare_tables 用于判断 alter 前后的表做了多大的改动,后者在这个语句中修改了 need_copy_table 的值。

| /_ Check if changes are compatible with current handler without a copy _/
if (table->file->check_if_incompatible_data(create_info, changes))
{
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);

}

这个 check_if_incompatitble_table 的函数实现在 handler/ha_innodb.cc 中。这个函数的返回值可能是 COMPATIBLE_DATA_NO 表示表改动前后不兼容(需要重做数据)或 COMPATIBLE_DATA_YES 兼容(不需要重做)。
该函数有如下片段

| if (check_column_being_renamed(table, NULL)) {
return COMPATIBLE_DATA_NO;

}

其实现逻辑是,如果有任何一个字段名被修改,则返回 COMPATIBLE_DATA_NO。
简单修改
有了上述分析,要做到快速修改表字段名,只需要把调用 check_column_being_renamed 的这三行注释掉即可。重新编译发布后,执行结果如下。

| mysql> alter table t change c2 c3 int(11) default null;
Query OK, 0 rows affected (0.01 sec)

Records: 0 Duplicates: 0 Warnings: 0

可以看到,这回执行基本不需要时间. 对比修改前后的 t.ibd 的 MD5,没有修改,而 t.frm 中只是将 c2 的字段名改为 c3,其他不变。
问题!!
这里的问题是,这个修改,是否会有副作用?虽然我们知道修改字段名应该是对数据时没有影响的,但 MySQL 就是这么实现了。
更深入的调查带来了“坏消息“。 在 MySQL 5.1.45 版本中,就没有这个字段名的判断,也就是说在 5.1.45 中仅修改字段名是只修改 frm 文件的。
在新版本中特别加入的判断,是否有什么原因?这是撰写本文的意图。若有与此相关的 bug 或者文章说明,请回复或站内私信我。
延伸
实际上,关于这个问题,还可以继续深入,这里抛砖引玉。

  1. 如果上述修改有副作用,副作用是什么,是否可以通过简单修改 ibd 文件,仍达到快速修改的目的?

展开全文 >>

MacM1安装MAT全流程解析(已收录)

2022-09-27

image.png前言

MAT 作为开发者分析堆栈快照信息的常用工具,本文介绍了在 MBP M1 中安装指南。

下载

首先去https://www.eclipse.org/mat/downloads.php下载 MAT 的安装包
image.png

异常

下载完打开会出现错误提示,如果没有异常,可以跳过。
image.png

安装 jdk11

在https://www.azul.com/downloads/?package=jdk#download-openjdk下载 jdk11
image.png
image.png
image.png

验证

1
2
3
4
duansg@DuansiguodeMacBook-Pro zulu-8.jdk % java -version
openjdk version "11.0.16.1" 2022-07-19 LTS
OpenJDK Runtime Environment Zulu11.58+23-CA (build 11.0.16.1+1-LTS)
OpenJDK 64-Bit Server VM Zulu11.58+23-CA (build 11.0.16.1+1-LTS, mixed mode)

环境配置

1
2
# 编辑配置文件
vim ~/.bash_profile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 配置JDK路径
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home
export JAVA_11_HOME=/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
export JAVA_17_HOME=/Library/Java/JavaVirtualMachines/jdk-17.0.1.jdk/Contents/Home

CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.

# 设置默认JDK版本
export JAVA_HOME=$JAVA_11_HOME

# 配置alias命令可以动态切换JDK版本
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
alias jdk11="export JAVA_HOME=$JAVA_11_HOME"
alias jdk17="export JAVA_HOME=$JAVA_17_HOME"

export JAVA_HOME
export PATH
export CLASSPATH


# maven配置
export MAVEN_HOME=/Users/itzhuzhu/Desktop/Java/maven/apache-maven-3.8.4
export PATH=$PATH:$MAVEN_HOME/bin
1
source ~/.bash_profile

验证环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines % java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (Zulu 8.58.0.13-CA-macos-aarch64) (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (Zulu 8.58.0.13-CA-macos-aarch64) (build 25.312-b07, mixed mode)
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines % jdk11
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines % java -version
openjdk version "11.0.16.1" 2022-07-19 LTS
OpenJDK Runtime Environment Zulu11.58+23-CA (build 11.0.16.1+1-LTS)
OpenJDK 64-Bit Server VM Zulu11.58+23-CA (build 11.0.16.1+1-LTS, mixed mode)
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines % jdk8
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines % java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (Zulu 8.58.0.13-CA-macos-aarch64) (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (Zulu 8.58.0.13-CA-macos-aarch64) (build 25.312-b07, mixed mode)
duansg@DuansiguodeMacBook-Pro JavaVirtualMachines %

MAT 配置修改

在 MAT 包的目录下找到 MemoryAnalyzer.ini,编辑 MemoryAnalyzer.ini

1
2
3
4
5
6
7
8
9
10
-vm
/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin
-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx_1.2.400.v20211117-0650
-vmargs
-Xmx1024m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread

验证 MAT

image.png

展开全文 >>

浅析Mybatis核心组件(已收录)

2022-09-23

image.png

前言

Mybaits 作为国内大流行的“伪”ORM 框架,它也是不少大厂的“御用框架”,可想而知其地位举足轻重。究其原因,国内很多互联网公司早期大部分都是基于面向数据库(表)编程,而 java 对象只是作为数据的载体,数据模型的 CRUD 都设计在一张表上,而业务逻辑就是不同表的 CRUD 集合。所以开发者需要它做的就是将 SQL 自动封装映射成 java 对象,没有其他花里胡哨的功能,这也是它流行原因之一。

Mybaits 组件简要流程图

image.png

Configuration

image.png

  • Configuration:MyBatis 所有的主配置信息都在 Configuration 里面,MyBatis 通过 Configuration 对象获取各种配置,例如:启动加载的 MappedStatement、TypeHandler、类型别名、插件等等。
  • MappedStatement:它封装了就是大家经常编写的 XxxxMapper.xml 文件里面

tag:

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 友情链接1
  • 友情链接2
  • 友情链接3
  • 友情链接4
  • 友情链接5
  • 友情链接6
很惭愧<br><br>只做了一点微小的工作<br>谢谢大家