如何解决死锁?
1.查看运行中的事务, 得到事务线程id(trx_mysql_thread_id)
select * from information_schema.innodb_trx; // 查看未结束的事务
select * from performance_schema.data_locks; // 查看已被锁定的数据 8.0版本
select * from performance_schema.data_lock_waits; // 查看等待锁的数据 8.0版本
2.结束线程, 语法如下
kill [trx_mysql_thread_id]; // 因为事务被干掉, 数据不会发生修改
查看进程表
show processlist
Innodb_trx表字段 - Eleanor123 - 博客园
==============
事务相关
Spring事务超时时间可能存在的错误认识_记事本-CSDN博客
得出观点@Transactional(timeout = 2) 并不是单纯的指 mysql中事务的执行时间
Spring、Mybatis和JDBC级别的超时并没有更改mysql的属性。可以查看三者的实现:
对于Spring的@transactional是通过timeout属性初始化了一个deadline,每一次创建statment判断deadline是否小于0,如果小于0抛异常;
否则通过JDBC的statement#setQueryTimeout来设置超时
Mybatis的timeout也是通过通过JDBC的statement#setQueryTimeout来设置超时。
JDBC的timeout,是在stament执行时,开启了一个监听线程,发现超时,就终端当前执行的stament,然后抛异常。
查看事务 自动提交开关(如果开启,则每执行一条 SQL 语句,事务都会提交一次)
show variables like 'autocommit';
手动开启事务:start transaction 或 begin
提交事务:commit
回滚事务:rollback
查看锁等待超时时间: 默认50秒
show variables like 'innodb_lock_wait_timeout';
innodb_rollback_on_timeout; // 获取锁超时, 是否回滚整个事务(默认关闭)
// 假设更新2条数据, 其中1条有行锁, 则默认是另一条可以修改成功
============
如何查看事务的隔离级别?
show global variables like 'tx_isolation';// 5.7版本
show variables like 'transaction_isolation';// 8.0版本
查看连接数
show status 查看系统运行的实时状态,不可修改,只能系统自动update
show variables 查看系统参数,可以通过set修改 或者 my.cnf配置文件修改
show variables like '%conn%'; // 查看连接数相关属性
max_connections --最大连接数
spring的中事务注解的超时间是多少?
如果未设置, 则默认使用底层系统的默认时间
============
InnoDB层面的日志是 redo undo
MySQL Servce层的日志是 binlog
MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结 - MSSQL123 - 博客园
MyBatis面试题:事务执行过程中发生宕机怎么处理_st1993的博客-CSDN博客
详细分析MySQL事务日志(redo log和undo log) - 骏马金龙 - 博客园
redo log 用于恢复开启事务后, 某一次修改后的数据
undo log 用于回滚开启事务后, 某一次修改前的数据
二进制日志 bin_log
show variables like '%bin%'; // 模糊查询多个相关属性
show variables like 'log_bin';// 8.0默认 开启-ON, 之前的版本是默认 关闭-OFF
show binary logs;// 查看日志文件大小
show master status;// 查看正在写入的binlog文件
show binlog events;// 查看日志表, 最好用上limit进行分页
show binlog events in 'binlog.000003'; 查看指定的日志
show variables like 'expire_logs_days'; // 查看日志保存天数
show variables like 'max_binlog_size'; // 查看日志文件大小, 执行中的事务会超过限制, 默认最大值1G, 最小4096
mysqladmin -uroot -p flush-logs 刷新日志文件, 重启也会自动 开启新的日志文件(文件名的数字+1)
binlog有三种格式:Statement、Row以及Mixed
关于binlog日志导致的主从延迟 揪出MySQL延迟上千秒的元凶 - 知乎
慢日志 slow_log
show variables like 'slow_query_log'; // 慢日志开关
show variables like 'long_query_time'; //查询超过多少秒才记录(默认10s)
set global slow_query_log = on; //临时开启
慢查询内容可以通过 mysqldumpslow 查看
mysqldumpslow -s c -t 10 /var/run/mysqld/mysqld-slow.log # 取出使用最多的10条慢查询
mysqldumpslow -s t -t 3 /var/run/mysqld/mysqld-slow.log # 取出查询时间最慢的3条慢查询
mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log # 得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s r -t 10 -g 'left join' /var/run/mysqld/mysqld-slow.log # 按照扫描行数最多的
参考 详解 慢查询 之 mysqldumpslow - 知乎
通用日志 General_log
记录服务器执行的全部sql语句, 默认关闭, 量会很大
show variables like 'general_log'; // 查看通用日志开关
========================
replace into和insert into区别
相同点: 实现了数据的插入
不同点在于:
insert into 新增的数据如果唯一索引重复, 则直接报错
replace into 尝试新增, 如果遇到重复记录
1. 根据主键或者唯一索引判断, 是否存在重复数据, 有则先删除, 再插入新数据。
2. 无重复,则直接插入新数据。(如果没有主键, 索引唯一性控制, 则会出现重复数据)
REPLACE INTO … ON DUPLICATE KEY UPDATE 的作用?
因为 replace into 是先删再保存; 假设原来的表有3个字段 id_no, name, age 101,张三,12岁
此时执行 replace into `t_user` ("id_no","name") values ("101","张三");
造成了age值丢失, 为null
解决方案就是在结尾加上 ON DUPLICATE KEY UPDATE
insert into 直接用会因为唯一索引重复报错
insert into + on duplicate key update 等于更新的效果
replace 直接用, 是先删, 再新增, sql如果是动态拼接的, 则有数据丢失风险;
replace into + on duplicate key update 等于更新的效果
on duplicate key update 的潜在风险点, 高并发场景下死锁问题
https://www.cnblogs.com/sueyyyy/p/13047035.html
========================
表结构复制, 数据复制
create table 新表 like 旧表; // 复制表结构
create table 新表 select* from 旧表; // 复制表结构+数据(不包含索引)
蠕虫复制
insert into 表名 (字段列表) select 字段列表 from 来源表
举例: insert into t_new_user (name,age) select name,age from t_user
(mysql 8.0默认开启binlog日志, 本地docker, 固态硬盘)
(相同数据, 复制200W数据约19s)
(不同数据, 370W, 复制到有主键的表66s, 无主键: 68s; 有主键全删除 157s)
由于是复制的数据, name都是一样的, 如何变得不一样?
因为主键是自增的, name+id 是最简单的方式
UPDATE t_slow_user SET name = concat(NAME, id) WHERE id=1; //修改name为 name+id
(name字段无索引 372W数据 耗时131.6s)
查看库, 表占用空间
select * from information_schema.tables; //数据库信息概要
select concat(round(sum(data_length/1024/1024),2),'MB') as data
from information_schema.tables
where table_schema='test'
GROUP BY table_name; // 查看某个库下各表大小,假设库名为: test
===
其他待看
详细分析MySQL事务日志(redo log和undo log) - 骏马金龙 - 博客园
===end