1.一条查询语句怎么执行的
2.一条update语句怎么执行的
redo log,binlog
WAL(write-ahead logging,先写日志再写磁盘),更新的时候就是写到redo log,等合适的时机再写入磁盘。
redo log是固定大小的,写完就从开头写。
crash-safe:异常重启的时候,有了redo log数据不会丢失。
redo log在引擎层,物理日志(记录的是“在某个数据页上做了什么修改”),空间有限;binlog是在server层,逻辑日志(记录语句的原始逻辑),可以追加日志。
redolog-prepare,写binlog,commit,redolog
当需要恢复到指定的某一秒时,比如某天下午两点发现中午十二点有一次误删表,需要找回数据,那你可以这么做:首先,找到最近的一次全量备份,如果你运气好,可能就是昨天晚上的一个备份,从这个备份恢复到临时库;然后,从备份的时间点开始,将备份的 binlog 依次取出来,重放到中午误删表之前的那个时刻。
innodb_flush_log_at_trx_commit 这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘。这个参数我建议你设置成 1,这样可以保证 MySQL 异常重启之后数据不丢失。
sync_binlog 这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘。这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启之后 binlog 不丢失。
3.索引
b+树
覆盖索引
联合索引
索引下推优化(mysql5.6+):在索引查找过程中,直接过滤掉索引中相关的字段,减少回表次数。
4.锁
全局锁,表锁
行锁,将复杂业务的锁放到事务执行的最后,减少这个操作的锁时间。
死锁解决方式:1)超时(innodb_lock_wait_timeout);2)死锁检测(innodb_deadlock_detect 设置为 on),主动回滚某个事务。
超时时间不好把控,所以一般采用死锁检测的方式。
5.mvcc
多版本并发控制
每个数据都有多个版本
每个事务在启动的时候有其他正在run的事务数组,某个事务id不在这个数组里就是代表是提交了的,可以访问。
更新数据的时候是先读后写的,只能基于当前读来写。
每个事务或语句都有自己的一致性视图。
已提交读每次读取都会生成一个新的readview,而可重复读只会第一次生成readview。
6.delete数据
删除数据只是被标记为可复用,并不能释放空间,所以表空间没有变小。插入数据时,前一个数据页也会留下空洞。
处理空洞,垃圾碎片。
alter table A engine=InnoDB 命令来重建表
optimize table t 等于 recreate+analyze
7.慢查询
set long_query_time=0,记录慢查询。
8.间隙锁,next-key lock
间隙锁和间隙锁没有冲突,只和“新插入记录”有冲突。只在rr级别下才会引入间隙锁,间隙锁可能导致死锁。
两个原则:1)加锁的基本单位是next-key lock;2)只有查询中访问到的对象才会加锁。
两个优化:1)唯一索引的等值查询,next-key lock退化为行锁;
2)索引的等值查询,向右遍历到最后一个值还不匹配时,nexk-key lock退化到间隙锁;
一个bug:唯一索引上的范围查询会查询到第一个不满足条件的指为止。
9.数据不丢失
binlog:binlog-cache,binlog,每个线程先写到自己的binlog-cache里,然后刷盘到磁盘,可以实时同步,也可以累积n个事务后批量刷盘。
redolog:redolog prepare,binlog,redolog commit。一般都是写入cache,然后批量刷盘。刷盘有后台进程处理。
binlog和redolog都是顺序写的,组提交机制节省io开支。
10.主备一致
binlog格式:statement(sql执行记录,同步可能导致主从不一致),row(每行执行的记录),mixed(判断是否导致主从不一致,从而选择合适statement或row格式)。
seconds_behind_master:主备延迟时间
11.主从延迟
解决方案:强制走主库,sleep
声明:以上内容来源于网络,如有侵权请联系我们(123@shiyan.com)删除! |