mysql/redis
mysql
1.事务的特性
- 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节,而且事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样,就好比买一件商品,购买成功时,则给商家付了钱,商品到手;购买失败时,则商品在商家手中,消费者的钱也没花出去。
- 一致性(Consistency):是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。
- 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致,因为多个事务同时使用相同的数据时,不会相互干扰,每个事务都有一个完整的数据空间,对其他并发事务是隔离的。
- 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?
- 持久性是通过 redo log (重做日志)来保证的;
- 原子性是通过 undo log(回滚日志) 来保证的;
- 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
- 一致性则是通过持久性+原子性+隔离性来保证;
2.并行事务引发的问题
- 脏读
- 如果一个事务「读到」了另一个「未提交事务修改过的数据」,就意味着发生了「脏读」现象。
- 不可重复读
- 在一个事务内多次读取同一个数据,如果出现前后两次读到的数据不一样的情况,就意味着发生了「不可重复读」现象。
- 幻读
- 在一个事务内多次查询某个符合查询条件的「记录数量」,如果出现前后两次查询到的记录数量不一样的情况,就意味着发生了「幻读」现象。
3.事务的隔离级别
- 读未提交(read uncommitted),指一个事务还没提交时,它做的变更就能被其他事务看到;
- 读提交(read committed),指一个事务提交之后,它做的变更才能被其他事务看到;
- 可重复读(repeatable read),指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别;
- 串行化(serializable );会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;
4.索引
按「物理存储」分类:聚簇索引(主键索引)、二级索引(辅助索引)。
按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引。
- 主键索引和二级索引区别:
- 主键索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里;
- 二级索引的 B+Tree 的叶子节点存放的是主键值,而不是实际数据。
5.索引失效及优化
索引下推优化
对于联合索引(a, b),在执行 select * from table where a > 1 and b = 2 语句的时候,只有 a 字段能用到索引
- 在 MySQL 5.6 之前,只能从 ID2 (主键值)开始一个个回表,到「主键索引」上找出数据行,再对比 b 字段值。
- 而 MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在联合索引遍历过程中,对联合索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
索引优化
- 前缀索引优化;
- 覆盖索引优化;
- 主键索引最好是自增的;
- 防止索引失效;
索引失效
- 字段类型隐式转换
- 查询条件中包含or
- like 通配符% 错误使用
- 联合索引最左匹配原则
- 索引列存在计算,使用(+、-、*、/),或者存在mysql函数,索引失效
- 使用(!= 或者 < >,not in),导致索引失效
6.锁机制
7.加行锁过程
8.mysql死锁问题
redis
-
1.过期键删除
- 过期词典,expires字段
- 定时器删除
- 占用cpu,影响服务的吞吐量
- 惰性删除
- 当访问时键过期就删除,但是如果过期key太多,占用内存
- 定期删除
- 定期删除过期key,控制并发,与惰性删除相结合
- RDB,AOF,复制时对过期键处理
- RDB:
- 生成RDB文件时,当执行SAVE或BGSAVE时,不会写入过期键
- 载入RDB文件时,主服务器不会处理,从服务器都会载入数据库
- AOF:
- 写入阶段如果key过期没被删除照样写入到文件,如果删除了,就会向AOF文件里写入DEL命令;重写阶段会对key进行过期检查。
- 复制:
- 当服务器在复制模式下时,主服务器删除这个key会向AOF文件写入DEL命令,同时通知从服务器删除这个key
- 当从服务器读到这个过期key时,还是会读出来,不删除,只有接收到到主服务器的DEL命令之后才会删除
- RDB:
-
2.可持久化
- RDB文件
- 服务器启动时,写入文件,文件保留键值对信息
- SAVE命令,创建RDB文件时,阻塞服务器不接受命令请求
- BGSAVE命令,开启一个子进程创建RDB文件,父进程接受命令请求,写时复制技术。
- AOF文件
- 保存redis写命令操作,以redis请求协议格式保存
- 写命令追加,写入到aof_buf缓冲区
- 写入同步,将aof_buf缓冲区数据写入到AOF文件,如果上次同步时间超过1s,再次对AOF文件进行同步
- 当AOF越来越大时,有了AOF文件重写,
- RDB文件
-
3.AOF写回策略
- Always,这个单词的意思是「总是」,所以它的意思是每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘,执行 fsync() 函数;
- Everysec,这个单词的意思是「每秒」,所以它的意思是每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘;异步执行 fsync() 函数
- No,意味着不由 Redis 控制写回硬盘的时机,转交给操作系统控制写回的时机,也就是每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。不会执行 fsync() 函数
-
4.AOF重写
- Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的
- 子进程进行 AOF 重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程;
- 子进程带有主进程的数据副本,和父进程的数据互不影响,进程不共享内存数据
- 当子进程完成 AOF 重写工作,会向父进程发送信号,将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中,使得新旧两个 AOF 文件所保存的数据库状态一致; 新的 AOF 的文件进行改名,覆盖现有的 AOF 文件。
- Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的