1.主从复制
1.什么是主从复制?
- 主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从数据库上,然后在从数据库上对这些日志进行重新执行,从而使从数据库和主数据库的数据保持一致。
2.主从复制怎么实现的?
3个线程(Binlog Dump线程、I/O线程和SQL线程)+2个日志(Binlog日志、中继日志Relay Log)
- 1.MySql主库在事务提交时会把数据变更作为事件记录在二进制日志Binlog中;
- 2.主库推送二进制日志文件Binlog中的事件到从库的中继日志Relay Log中,之后从库根据中继日志重做数据变更操作,通过逻辑复制来达到主库和从库的数据一致性;
- 3.MySql通过三个线程来完成主从库间的数据复制,其中Binlog Dump线程跑在主库上,I/O线程和SQL线程跑着从库上;
- 4.当在从库上启动复制时,首先创建I/O线程连接主库,主库随后创建Binlog Dump线程读取数据库事件并发送给I/O线程,I/O线程获取到事件数据后更新到从库的中继日志Relay Log中去,之后从库上的SQL线程读取中继日志Relay Log中更新的数据库事件并应用,如下图所示。
2.事务
1.事务的4个特性——ACID
-
原子性(atomicity): 事务的最小工作单元,要么全成功,要么全失败。
-
一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏。
-
隔离性(isolation): 不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。
-
持久性(durability): 事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失。
2.事务的隔离级别——4个级别
-
1.未提交读(脏读)
一个事务可以读取到另一个事务未提交的数据。这种隔离级别岁最不安全的一种,因为未提交的事务是存在回滚的情况。 -
2.已提交读
又称为不可重复读,一个事务因为读取到另一个事务已提交的修改数据,导致在当前事务的不同时间读取同一条数据获取的结果不一致。 -
如下:SessionA3次读取3个不同的结果
-
3.可重复度(幻读)
一个事物读可以读取到其他事务提交的数据,但是在RR隔离级别下,当前读取此条数据只可读取一次,在当前事务中,不论读取多少次,数据任然是第一次读取的值,不会因为在第一次读取之后,其他事务再修改提交此数据而产生改变。读出来的数据并不一定就是最新的数据。 -
eg:SessionA3次读取的记录和第1次都一样。
-
4.串行化
所有的数据库的读或者写操作都为串行执行,当前隔离级别下只支持单个请求同时执行,所有的操作都需要队列执行。所以种隔离级别下所有的数据是最稳定的,但是性能也是最差的。
- SessionA等待,直到SessionB提交commit之后才能读到数据
3.事务和MVCC原理
- 不同事务同时操作同一条数据产生的问题
1.LBCC,基于锁的并发控制,Lock Based Concurrency Control
- 使用锁的机制,在当前事务需要对数据修改时,将当前事务加上锁,同一个时间只允许一条事务修改当前数据,其他事务必须等待锁释放之后才可以操作。
2.MVCC,多版本并发控制,Multi-Version Concurrency Control
-
使用版本来控制并发情况下的数据问题,在B事务开始修改账户且事务未提交时,当A事务需要读取账户余额时,此时会读取到B事务修改操作之前的账户余额的副本数据,但是如果A事务需要修改账户余额数据就必须要等待B事务提交事务。
-
MVCC使得数据库读不会对数据加锁,普通的SELECT请求不会加锁,提高了数据库的并发处理能力。借助MVCC,数据库可以实现READ COMMITTED,REPEATABLE READ等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本,保证了ACID中的I特性(隔离性)。
核心:创建版本号、删除版本号
-
InnoDB的MVCC,通过在每行记录后面保存两个隐藏的列来实现:一个保存了行的创建时间(行的事务ID),一个保存行的过期时间(删除时间),当然,这里的时间并不是时间戳,而是系统版本号(行的事务ID),每开始一个新的事务,系统版本号就会递增。在RR隔离级别下,MVCC的操作如下:
- select操作。
- InnoDB只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录。
- 行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取的行,在事务开始之前未删除。
- insert操作。将新插入的行保存当前版本号为行版本号。
- delete操作。将删除的行保存当前版本号为删除版本号。
- update操作。变为insert和delete操作的组合,insert的行保存当前版本号为行版本号,delete则保存当前版本号到原来的行作为删除标识。
- 由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。
- select操作。
3.可重复读级别怎么解决了幻读问题?
mysql里面实际上有两种读,一种是“快照读”,一种是“当前读”。
select 快照读
当执行select操作是innodb默认会执行快照读,会记录下这次select后的结果,之后select 的时候就会返回这次快照的数据,即使其他事务提交了不会影响当前select的数据,这就实现了可重复读了。
快照的生成当在第一次执行select的时候,也就是说假设当A开启了事务,然后没有执行任何操作,这时候B insert了一条数据然后commit,这时候A执行 select,那么返回的数据中就会有B添加的那条数据。
之后无论再有其他事务commit都没有关系,因为快照已经生成了,后面的select都是根据快照来的。
当前读
对于会对数据修改的操作(update、insert、delete)都是采用当前读的模式。在执行这几个操作时会读取最新的记录,即使是别的事务提交的数据也可以查询到。
假设要update一条记录,但是在另一个事务中已经delete掉这条数据并且commit了,如果update就会产生冲突,所以在update的时候需要知道最新的数据。也正是因为这样所以才导致上面我们测试的那种情况。