mysql

94 阅读4分钟

查看sql运行记录

SET GLOBAL log_output = 'TABLE';SET GLOBAL general_log = 'ON' ;

SELECT * from mysql.general_log ORDER BY event_time DESC;

SET GLOBAL log_output = 'TABLE';SET GLOBAL general_log = 'OFF' ; //做完别忘记关掉日志记录(性能消耗大)


truncate table mysql.general_log;

间隙锁和间隙锁之间不互斥,间隙锁只和插入操作互斥 image.png

RC级别下在普通索引间无间隙锁,但是在唯一键和主键那里还是有间隙锁的

on duplicate key update的坑

image.png

解决办法:

1、尽量不对存在多个唯一键的table使用该语句

2、在有可能有并发事务执行的insert 的内容一样情况下不使用该语句

生产死锁记录

隔离级别:RC 背景:幂等的通知消息,如每个人的收件箱,大量的操作,insert on dup key update

批量的插入或者更新,出现死锁【mysql出现死锁以后都能自动会滚,所以,死锁危害不是那么大】

事务A持有uid=2的行锁,准备更新uid=3的数据,
事务B持有uid=3的行锁,准备更新uid=2的数据,导致死锁,
解决办法:批量更新前,先按照uid排序,这样就可以避免死锁

案例

CREATE TABLE `test2` (
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `code` int(11) NOT NULL,
  `other` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `code` (`code`)
) ENGINE=InnoDB 

insert into test2 (code, other) values(1,1),(3,3),(5,5);

begin;
insert into test2 (code, other) values(2,2);
insert into test2 (code, other) values(4,4);
commit;

begin;
insert into test2 (code, other) values(4,4);
insert into test2 (code, other) values(2,2);
commit;

on dup key update的坑

image.png

只要并发更新同一个key,就有可能产生死锁

解决办法: 1.进行避免并发更新 2.可以考虑分表

image.png 批量插入产生的死锁,本质还是行锁,在两个事务中插入了同样的行,然后顺序又不一致。最好的办法是根据唯一索引做一致性hash,然后串行化。

批量插入或者更新死锁的解决办法

按照唯一索引维度进行一致性hash,保证同一行记录总是由一个线程插入或者更新即可。【也可以借助kafka实现一致性hash】

慢sql的分析经验

如果有几千万数据,一条全表扫描的查询,可以执行几分钟。在这几分钟内,所有的插入和更新sql都会受这个全表扫描sql的影响,变得很慢。抢占cpu,磁盘io,内存页的换进换出等等。

出现慢sql,不能单独的分析那一条sql,而是要分析整个mysql进程的状态,把附近时间点的sql都分析一遍。

默认生成的create_time字段,是sql开始执行的时间,不是sql执行完毕的时间。

磁盘相关指标

IOPS:每秒执行的io请求数【计算方式:wenku.baidu.com/view/cdd5e2… 参数的影响:IOPS使用率到20%多以后就会有很多超时了,30%左右就会用明显的性能瓶颈。 出现情况:在大量数据8000w的表中,查询不命中索引,导致全表扫描【扫描时间能持续4000s左右】,期间的所有插入操作,耗时急剧增加。 使用经验:IOPS在达到10%以后就应该考虑扩容了

查看死锁日志

MySQL [(none)]> show engine innodb status \G;
对同一行数据并发的insert on duplicate key update不会导致死锁,如果是批量的操作,且没有排序,则会死锁。

比如:
事务1:批量插入或者更新(name,age)[("y",1),("t",2)]
事务2:批量插入或者更新(name,age)[("t",2),("y",1)]
如果两个事务并发的执行,则会导致死锁。

解决办法:先按照唯一键排序,再批量的插入或者更新【注意:不要有多个唯一键,不然没法排序了,总会有几率冲突】

索引命中情况

index(uid,status). 查询条件 where uid in(123,122,333) and status=1 ,命中情况 use condition index(uid). 查询条件 where uid in(123,122,333) and status=1 ,命中情况 use filesort index(uid,status). 查询条件 where uid in(123,122,333) and status=1 order by update_time desc ,命中情况 use filesort