mysql怎么跑代码_java预编译sql

mysql怎么跑代码_java预编译sql工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段?
比如:给下面的用户表(user)添加年龄(age)字段。
有同学会说,这还不简单,直接加不加完了,用下面的命令:

线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段

1. 问题:怎么给线上表加字段?

工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段?

比如:给下面的用户表(user)添加年龄(age)字段。

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT "主键",
  `name` varchar(100) DEFAULT NULL COMMENT "姓名",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT="用户表";

有同学会说,这还不简单,直接加不加完了,用下面的命令:

ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT "0" COMMENT "年龄";

添加完,再查看一下表结构:

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT "主键",
  `name` varchar(100) DEFAULT NULL COMMENT "姓名",
  `age` int NOT NULL DEFAULT "0" COMMENT "年龄",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT="用户表";

这不是添加成功了吗?有什么呀!

是的,线下数据库怎么整都行,但是如果在线上数据库这样操作,整个服务都有宕机的风险!自己也离毕业不远了。

不是危言耸听,我们找个case测试一下:

image

  1. Session1启动了一个事务,没有提交。
  2. Session2执行添加列的操作,被阻塞。
  3. 更严重的是,Session3执行简单查询的语句也被阻塞了。

2. 线上服务宕机的原因

为什么会出现这种情况呢?

原因是在执行查询语句的时候,MySQL自动加了MDL锁(metadata lock,即元数据锁)

不行的话,我们可以再执行一下show processlist命令,查看有哪些正在执行的进程:

image

可以清楚的看到Session2和Session3的语句正在等待MDL锁,Waiting for table metadata lock

MDL锁的作用是什么?

为了保证并发操作下数据的一致性。

如果一个事务正在执行中,另一个在这时修改了表结构,不但可能导致当前事务出现不可重复读的问题,还有可能连事务都无法提交。

什么时候会加MDL锁?

MDL锁是MySQL自动隐式加锁,无需我们手动操作。

在我们执行DDL语句的时候,MySQL自动添加MDL读锁。

在我们执行DML语句的时候,MySQL自动添加MDL写锁。

读锁与读锁之间不互斥,读锁与写锁、写锁与写锁之间互斥。

注意:MDL锁是表锁,会对整张表加锁。

普及额外的小知识点,什么是DML和DDL:

DML(Data Manipulation Language)数据操纵语言:

适用范围:对表数据进行操作,比如 insert、delete、select、update等。

DDL(Data Definition Language)数据定义语言:

适用范围:对表结构进行操作,比如create、drop、alter、rename、truncate等。

3. 如何优雅的给线上表加字段

既然修改表结构的时候,MySQL会自动添加表锁,并且是写锁,会阻塞后续的所有读写请求,造成非常严重的后果。

还有没有办法能优雅的给线上表添加字段呢?

当然有,从MySQL5.6版本开始增加了Online DDL,作用就是在执行DDL的时候,允许并发执行DML。简单翻译就是修改表结构的时候,也能同时支持并发执行增删查改操作。

从MySQL8.0版本开始又优化了Online DDL,支持快速添加列,可以实现给大表秒级加字段。

具体用法就是在DDL语句后面增加两个参数ALGORITHMLOCK

比如下面这样:

ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT "0" COMMENT "年龄", 
ALGORITHM=Inplace, 
LOCK=NONE;

这两个参数分别是干嘛用的?有哪些选项呢?

ALGORITHM可以指定使用哪种算法执行DDL,可选项有:

  • Copy:

    拷贝方式,MySQL5.6 之前 DDL 的执行方式,过程就是先创建新表,修改新表结构,把旧表数据复制到新表,删除旧表,重命名新表。执行过程非常耗时,产生大量的磁盘IO和占用CPU,还有使Buffer poll失效,而且需要锁住旧表,性能较差,现在基本很少使用。

  • Inplace:

    原地修改,MySQL5.6开始引入的,优点是不会在Server层发生表数据拷贝,过程中允许并发执行DML操作。过程就是先添加MDL写锁,执行初始化操作,然后降级为MDL读锁,执行DDL操作(比较耗时,允许并发执行DML操作),升级为MDL写锁,完成DDL操作。

  • Instant:

    快速修改,MySQL8.0开始引入的,可以实现快速给大表添加字段。

性能依次是,Instant > Inplace > Copy。

LOCK可以指定执行过程中,是否加锁,可选项有:

  • NONE

    不加锁,允许DML操作。

  • SHARED

    加读锁,允许读操作,禁止DML操作。

  • DEFAULT

    默认锁模式,在满足DDL操作前提下,默认锁模式会允许尽可能多的读操作和DML操作。

  • EXCLUSIVE

    加写锁,禁止读操作和DML操作。

Online DDL并不是支持所有DDL操作,看一下到底支持哪些操作?

操作 Instant Inplace Rebuilds Table 允许并发DML 仅修改元数据
添加列 Yes Yes No Yes No
删除列 No Yes Yes Yes No
重命名列 No Yes No Yes Yes
更改列顺序 No Yes Yes Yes No
设置列默认值 Yes Yes No Yes Yes
更改列数据类型 No No Yes No No
设置VARCHAR列大小 No Yes No Yes Yes
删除列默认值 Yes Yes No Yes Yes
更改自动增量值 No Yes No Yes No
设置列为null No Yes Yes Yes No
设置列not null No Yes Yes Yes No

像最常见的添加列就可以使用Instant,而像删除列、重命名列、更改列数据类型就只能使用Inplace了。

image

原文地址:https://www.cnblogs.com/yidengjiagou/archive/2022/10/08/16769180.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/4685.html

(0)
上一篇 2023-06-09
下一篇 2023-06-09

相关推荐

  • Python实现简单的命令行工具

    Python实现简单的命令行工具a href=”https://beian.miit.gov.cn/”苏ICP备2023018380号-1/a Copyright www.python100.com .Some Rights Reserved.

    2024-02-26
    106
  • 数据库删除记录语句_sql语言中实现数据删除的语句是

    数据库删除记录语句_sql语言中实现数据删除的语句是学习重点 如果想将整个表全部删除,可以使用 DROP TABLE 语句,如果只想删除表中全部数据,需使用 DELETE 语句。 如果想删除部分数据行,只需在 WHERE 子句中书写对象数据的条件即可。

    2023-04-28
    142
  • mysql中的字段类型_sql字段类型有哪些

    mysql中的字段类型_sql字段类型有哪些字符串类型 类型 范围 说明 char(M) M=1~255 字符 固定长度 varchar(M) 一行中所有 varchar 的列所占用的字节数不能超过 65535 字节 存储可变长度的 M 个字…

    2023-03-01
    153
  • leetcode176(第二高的薪水)–SQL查询实现「建议收藏」

    leetcode176(第二高的薪水)–SQL查询实现「建议收藏」求: 编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。 +—-+——–+ | Id | Salary | +—-+——–+ | 1 |…

    2023-03-30
    151
  • 从简单实现mysql自动化备份说起[通俗易懂]

    从简单实现mysql自动化备份说起[通俗易懂]从简单实现mysql自动化备份说起 场景 随着云技术的发展,很多公司的产品、应用都已经在云上部署了、云服务器也提供了越来越多的专业性的服务器。例如云服务器 ECS 、数据库 RDS 、对象存储等等。…

    2023-02-16
    146
  • 用Python实现高效数据抓取

    用Python实现高效数据抓取随着互联网的发展,数据已经成为了一个重要的资源,而数据抓取也成为了一项重要的技能。由于Python具有简单易学、性能良好、支持各种操作系统、第三方类库丰富等诸多优势,它已经成为了数据科学领域非常流行的编程语言之一。本文将介绍如何用Python实现高效数据抓取。

    2024-05-22
    72
  • Python字符串编码

    Python字符串编码字符串是文本数据,而计算机只能处理二进制数据。在计算机中,文本字符串需要通过编码方式转换为二进制数据,以便于存储和传输。所以,字符串编码是将Unicode字符转换为二进制数据的过程。Python中的字符串编码是将字符串转换为字节序列的过程,以便它们可以在网络上传输或以二进制文件的形式存储。

    2024-02-17
    99
  • MySQL数据库升级[亲测有效]

    MySQL数据库升级[亲测有效]当前不少系统的数据库依旧是MySQL5.6,由于MySQL5.7及MySQL8.0在性能及安全方面有着很大的提升,因此需要升级数据库。本文通过逻辑方式、物理方式原地升级来介绍MySQL5.6 升级至M

    2023-02-10
    141

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注