MySQL求职知识速记
2022-08-10 17:25:58 0 举报
AI智能生成
MySQL 面试
作者其他创作
大纲/内容
锁
分类
全局锁
对整个数据库实例加锁
Flush tables with read lock (FTWRL)
阻塞
数据更新语句(数据的增删改)
数据定义语句(包括建表、修改表结构等)
更新类事务的提交语句
做全库逻辑备份
表级锁
两种
表锁
表锁是最常用的处理并发的方式
元数据锁
MDL 不需要显式使用,在访问一个表的时候会被自动加上。MDL 的作用是,保证读写的正确性
行锁
两阶段锁协议
在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议
如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放
死锁
两种策略
直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置
发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑
正常情况下我们还是要采用第二种策略,即:主动死锁检测
死锁检测要耗费大量的 CPU 资源
一种头痛医头的方法,就是如果你能确保这个业务一定不会出现死锁,可以临时把死锁检测关掉
另一个思路是控制并发度
事务
隔离级别
读未提交
读提交
可重复读
在可重复读隔离级别下,事务在启动的时候就“拍了个快照”。注意,这个快照是基于整库的
InnoDB 利用了“所有数据都有多个版本”的这个特性,实现了“秒级创建快照”的能力
串行化
主备
主备延迟
原因
机器性能差
备库的压力大
大事务
大表 DDL
备库的并行复制能力
判断主备无延迟方案
第一种确保主备无延迟的方法是,每次从库执行查询请求前,先判断 seconds_behind_master 是否已经等于 0。如果还不等于 0 ,那就必须等到这个参数变为 0 才能执行查询请求
第二种方法,对比位点确保主备无延迟
第三种方法,对比 GTID 集合确保主备无延迟
慢查询
索引没有设计好
SQL 语句没写好
join
如果可以使用 Index Nested-Loop Join 算法,也就是说可以用上被驱动表上的索引,其实是没问题的
如果使用 Block Nested-Loop Join 算法,扫描行数就会过多。尤其是在大表上的 join 操作,这样可能要扫描被驱动表很多次,会占用大量的系统资源。所以这种 join 尽量不要用
在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表
MySQL 选错了索引
误删库 / 表
这种情况下,要想恢复数据,就需要使用全量备份,加增量日志的方式了。这个方案要求线上有定期的全量备份,并且实时备份 binlog
取最近一次全量备份,假设这个库是一天一备,上次备份是当天 0 点
用备份恢复出一个临时库
从日志备份里面,取出凌晨 0 点之后的日志
把这些日志,除了误删除数据的语句外,全部应用到临时库
自增主键
InnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 版本后,才有了“自增值持久化”的能力,也就是才实现了“如果发生重启,表的自增值可以恢复为 MySQL 重启前的值”
不连续的原因
唯一键冲突是导致自增主键 id 不连续的第一种原因
事务回滚也会产生类似的现象,这就是第二种原因
0 条评论
下一页