MYSQL批量插入并发场景下的DEADLOCK

这篇具有很好参考价值的文章主要介绍了MYSQL批量插入并发场景下的DEADLOCK。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

公元2023-10-12(周四)上午,组内的亚梅反馈,用户生成标签报死锁异常

MYSQL批量插入并发场景下的DEADLOCK

 文章来源地址https://www.toymoban.com/news/detail-711110.html

 

二、排查异常日志

查到当时报错的日志

MYSQL批量插入并发场景下的DEADLOCK

 

具体异常信息如下

server-provider-info-2023-10-12.0.log:2023-10-12 09:40:50.593 [TID:bf623bded189486cbb0b6a64d81b64b4.357.16970748504097047] [4ed7b7943a8a47de912e4b644d70285e] [SimpleAsyncTaskExecutor-5080] INFO  com.emax.user.user.provider.UserTagAPIImpl:? - 签约完成,更新用户标签信息异常,用户id[1712282059297107970]org.apache.ibatis.exceptions.PersistenceException:
server-provider-info-2023-10-12.0.log-### Error flushing statements.  Cause: org.apache.ibatis.executor.BatchExecutorException: com.emax.user.user.mapper.UserTagMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-### Cause: org.apache.ibatis.executor.BatchExecutorException: com.emax.user.user.mapper.UserTagMapper.insert (batch index #1)failed. Cause: java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.session.defaults.DefaultSqlSession.flushStatements(DefaultSqlSession.java:254)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveBatch(ServiceImpl.java:127)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.IService.saveBatch(IService.java:58)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
server-provider-info-2023-10-12.0.log-  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
server-provider-info-2023-10-12.0.log-  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
server-provider-info-2023-10-12.0.log-  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.service.UserTagManager$$EnhancerBySpringCGLIB$$67ca0067.saveBatch(<generated>)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl.addUserTagByUser(UserTagAPIImpl.java:236)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl.addTagAfterSign(UserTagAPIImpl.java:116)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl$$FastClassBySpringCGLIB$$2547ce26.invoke(<generated>)
server-provider-info-2023-10-12.0.log-  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
--
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.StatementProxy.lambda$executeBatch$9(StatementProxy.java:129)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:73)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:51)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.StatementProxy.executeBatch(StatementProxy.java:129)
server-provider-info-2023-10-12.0.log-  at sun.reflect.GeneratedMethodAccessor1346.invoke(Unknown Source)
server-provider-info-2023-10-12.0.log-  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
server-provider-info-2023-10-12.0.log-  at java.lang.reflect.Method.invoke(Method.java:498)
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:78)
server-provider-info-2023-10-12.0.log-  at com.sun.proxy.$Proxy501.executeBatch(Unknown Source)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.core.executor.MybatisBatchExecutor.doFlushStatements(MybatisBatchExecutor.java:132)
server-provider-info-2023-10-12.0.log-  ... 71 common frames omitted
server-provider-info-2023-10-12.0.log-Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:970)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1109)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:849)
server-provider-info-2023-10-12.0.log-  ... 89 common frames omitted
server-provider-info-2023-10-12.0.log-

 

三、代码所在地

查看发生Deadlock的代码现场。

代码如下:

    /**
     * 增加用户标签
     * @param user 用户信息
     * @param tagNameList 标签集合
     */
    private void addUserTagByUser(User user, List<String> tagNameList){
        log.info("用户添加标签入参信息,当前用户id[{}],标签信息[{}]", user.getUserId(), JSON.toJSONString(tagNameList));
        Set<String> existTags = new HashSet<>();
        final List<UserTag> userTagList = userTagManager.listUserTagByUserId(user.getUserId());
        if(CollectionUtils.isNotEmpty(userTagList)){
            existTags = userTagList.stream().map(UserTag::getTagName).collect(Collectors.toSet());
        }
        //遍历合集 如果不存在旧数据 直接都新增 存在 判断当前数据是否在旧数据中
        List<UserTag> newInsertList = new ArrayList<>();
        for(String name : tagNameList){
            if (StringUtils.isNotBlank(name) && existTags.add(name)) {
                newInsertList.add(userTagManager.buildEntity(user.getUserId(), user.getIdcardNo(), name));
            }
        }
        userTagManager.saveBatch(newInsertList);
    }

 

观察代码,大致逻辑是,先根据用户id查询出所有标签信息,计算出来需要新增的用户标签,批量入库。其中,user_tag表存储用户的标签数据。两个关键字段 user_id(用户id)和tag_name(标签)上面具有唯一索引,插入的数据也主要是这两个字段。

从这段代码并不容易判断出来如何会产生死锁。推测是多个线程同时操作相同的数据,并发插入导致的死锁。

 

四、并发操作日志

elk上查询方法入参日志。果然在发生异常的时间节点上,发现了两条插入相同数据的日志。相同时间点,两个traceId,可见当时发生了并发调用。

MYSQL批量插入并发场景下的DEADLOCK

 

找到当时另一个线程的操作日志,日志无异常,数据入库成功。见下面截图。

MYSQL批量插入并发场景下的DEADLOCK

 

 

 

五、数据库死锁日志验证推测

当天下午上班后,找运维大哥帮忙,找出死锁日志

执行命令 show ENGINE INNODB status 

得到信息如下

=====================================
2023-10-12 13:49:17 0x7fea5ae87700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 61 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 3123131 srv_active, 0 srv_shutdown, 7715544 srv_idle
srv_master_thread log flush and writes: 10838675
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 3905404
OS WAIT ARRAY INFO: signal count 27617015
RW-shared spins 0, rounds 21456656, OS waits 2772950
RW-excl spins 0, rounds 41132727, OS waits 487320
RW-sx spins 227170, rounds 4363782, OS waits 66152
Spin rounds per wait: 21456656.00 RW-shared, 41132727.00 RW-excl, 19.21 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2023-10-12 09:40:50 0x7fecedb1e700
*** (1) TRANSACTION:
TRANSACTION 404898333, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 11375251, OS thread handle 140644580488960, query id 1031478425 10.128.0.160 emax_base update
INSERT INTO emax_user_tag  ( user_id,
id_card_no,
tag_name,
create_time,
update_time )  VALUES  ( 1712282059297107970,
'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9',
'市场推广',
'2023-10-12 09:40:50.481',
'2023-10-12 09:40:50.481' )
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898333 lock mode S waiting
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** (2) TRANSACTION:
TRANSACTION 404898332, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11375224, OS thread handle 140655576868608, query id 1031478426 10.128.0.160 emax_base update
INSERT INTO emax_user_tag  ( user_id,
id_card_no,
tag_name,
create_time,
update_time )  VALUES  ( 1712282059297107970,
'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9',
'信息技术服务',
'2023-10-12 09:40:50.481',
'2023-10-12 09:40:50.481' )
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898332 lock_mode X locks rec but not gap
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898332 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** WE ROLL BACK TRANSACTION (1)

此处省略掉若干非关键信息行 ---------------------------- END OF INNODB MONITOR OUTPUT ============================

 

该日志信息量很多,已省略掉若干非关键信息行,我们主要关注最后一次死锁相关信息。

六、死锁复现

sql准备

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

本地创建一个和生产一样的数据库emax_user_tag,同样,在user_id和tag_name两个字段上创建唯一索引。

 

操作步骤1

在窗口一执行

begin;

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

 

操作步骤2

在窗口二执行

begin;

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

 

操作步骤3

在窗口一执行

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

commit;

 

操作步骤4

切回窗口二

 

操作步骤5

执行命令 show ENGINE INNODB status 查看死锁日志。与上面的情况一样。

MYSQL批量插入并发场景下的DEADLOCKMYSQL批量插入并发场景下的DEADLOCK
=====================================
2023-10-13 14:52:43 0x7fe759575700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 24 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 137590 srv_active, 0 srv_shutdown, 2010475 srv_idle
srv_master_thread log flush and writes: 2148065
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 6627679
OS WAIT ARRAY INFO: signal count 14339066
RW-shared spins 0, rounds 22104735, OS waits 1859432
RW-excl spins 0, rounds 258795010, OS waits 2238669
RW-sx spins 6551822, rounds 136672247, OS waits 1786313
Spin rounds per wait: 22104735.00 RW-shared, 258795010.00 RW-excl, 20.86 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2023-10-13 14:50:31 0x7fe892ad0700
*** (1) TRANSACTION:
TRANSACTION 293171186, ACTIVE 10 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 1266048, OS thread handle 140631613069056, query id 35172347 192.168.48.179 develop update
/* ApplicationName=DBeaver 22.2.1 - SQLEditor <Script-4.sql> */ INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' )
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171186 lock mode S waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** (2) TRANSACTION:
TRANSACTION 293171182, ACTIVE 19 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 1266036, OS thread handle 140636869953280, query id 35172492 192.168.48.179 develop update
/* ApplicationName=DBeaver 22.2.1 - SQLEditor <Script-1.sql> */ INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' )
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171182 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171182 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** WE ROLL BACK TRANSACTION (1)
View Code

 

 

七、死锁分析

根据死锁日志进行分析。

执行操作步骤一时:

事务一   获取到了插入意向锁

执行操作步骤二时:

事务二  将事务的意向锁升级为唯一索引排他锁,并且尝试获取唯一索引共享锁(还没有获得共享锁,排队中)

执行操作步骤三时:

事务一 尝试获取插入意向间隙锁

 

事务二等待事务一释放排他锁

事务一等待事务二释放共享锁

形成相互等待关系,死锁。

八、总结归纳

 

1.批量插入操作尽量保证数据有序性

2.可借助性能更高的redis进行并发拦截 或 同步处理控制

3.将参数 innodb_deadlock_detect 设置为 on,死锁时会进行回滚(数据库默认开启)

4.业务代码需要考虑数据库异常

5.当前mysql数据库版本是5.7.28-log。经细心的红洁同学验证,mysql-8.0版本针对这个场景做了优化,不会发生死锁。

 

 

文献参考 https://blog.csdn.net/minghao0508/article/details/129093202

 

到了这里,关于MYSQL批量插入并发场景下的DEADLOCK的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • mysql 批量插入BulkCopy

    一、新建项目:SqlSugarDemo 二、连接串未添加AllowLoadLocalInfile=true 中文提示 : BulkCopy MySql连接字符串需要添加 AllowLoadLocalInfile=true; 添加后如果还不行Mysql数据库执行一下 SET GLOBAL local_infile=1  English Message : connection string add : AllowLoadLocalInfile=true  三、Startup.cs HomeController.cs

    2024年02月12日
    浏览(32)
  • MySQL批量插入技巧

    关于MySQL批量插入的一些问题 MySQL 一直是我们互联网行业比较常用的数据,当我们使用 半ORM框架 进行 MySQL 大批量插入操作时,你是否考虑过这些问题: 进行大数据量插入时,是否需要进行分批次插入,一次插入多少合适?有什么判断依据? 使用 foreach 进行大数据量的插入存

    2024年02月03日
    浏览(22)
  • Mysql大数据批量插入方法

    MySQL是当前最流行的关系型数据库之一,大数据批量插入是MySQL中常用的操作之一。在处理大量数据时,如果一条一条地插入会极大地影响效率,因此批量插入是一个更好的选择,可以大大提高数据的处理速度。下面介绍几种MySQL大数据批量插入的方法。 使用LOAD DATA INFILE语句

    2024年02月10日
    浏览(22)
  • mysql批量插入insert语句

    在MySQL中批量插入数据有几种方法,下面我将介绍其中两种常用的方法: 这是一种简单的方式,可以一次性插入多个值。以下是一个示例: 在上面的示例中,你需要替换your_table_name为你的表名,列名和相应的值。你可以一次性插入多行数据。 另一种批量插入数据的方法是使

    2024年02月06日
    浏览(25)
  • python批量插入数据到mysql

    使用python批量插入数据到mysql的三种方法 单条insert的话插入5w条数据大约用时5秒左右,相对来说效率不高

    2024年02月10日
    浏览(24)
  • MySQL - 批量插入唯一索引冲突避免办法

    我们在进行大批量的数据插入时,遇到唯一索引冲突是经常的事,报错如下: 在MySQL中有4种方法可以避免唯一索引冲突 (一)导入差异数据,忽略重复数据,IGNORE INTO的使用 (二)导入并覆盖重复数据,REPLACE INTO 的使用 (三)导入保留重复数据未指定字段,INSERT INTO ON DU

    2024年02月01日
    浏览(21)
  • 设计模式之并发特定场景下的设计模式 Two-phase Termination(两阶段终止)模式

    在线程1中如何终止线程2? stop()?还是System.exit()?还是其他方式 1.使用stop()不可取 线程对象的stop()方法会直接杀死线程,假设此时使用了线程锁,当此时使用了stop()命令会导致线程锁无法释放,以至于程序出现严重的问题,其中最常见的是死锁。还可能导致资源泄露,因为

    2024年01月21日
    浏览(22)
  • MySQL---使用索引优化、大批量插入数据优化

    1. 使用索引优化 索引是数据库优化最常用也是最重要的手段之一 , 通过索引通常可以帮助用户解决大多数的 MySQL 的性能优化问题: 1.1 避免索引失效应用-全值匹配 该情况下,索引生效,执行效率高。 1.2 避免索引失效应用-最左前缀法则 1.3 避免索引失效应用-其他匹配原则

    2024年02月07日
    浏览(32)
  • Mysql 实现批量插入对已存在数据忽略或更新

    对已存在的数据进行 忽略/更新 ,需要唯一索引/主键。 唯一索引可为多个字段的联合索引,比如根据我提供的sql中,我需要``name + age`不重复,则可把这2个字段联合创建为唯一索引 创建联合唯一索引的sql 批量插入对已存在数据忽略 批量插入对已存在数据更新 笔者这里只举

    2024年02月15日
    浏览(22)
  • mysql 批量数据插入很慢(kettle 输入输出组件) 性能优化办法

    背景 最近在做数仓重构项目,遇到一些性能瓶颈,这里记录一下解决办法。 随着业务数据每天都在增加,几年前开发的etl任务开始跑不动了。大表一般是通过增量的方式插入,但是修复bug 或者每月/季度跑一次的情况 需要跑全量,原来的etl任务可能需要跑几个小时,甚至出

    2024年01月17日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包