赞
踩
为什么要了解数据库原理
先输入,然后按照自己的理解进行输出,知识的转化。
很多知识是比较枯燥的,你需要坚持,然后在其中找到乐趣。多给自己一些反馈,相信时间的力量。
连接器,分析器,优化器和执行器,故语法报错在分析器的时候就卡壳了,因为是语法错误。
在执行器阶段进行,因为有些触发型的sql语句,在最后才知道执行的内容是什么,所以在最后一道保险处进行执行。
查询和更新的逻辑相似!
问题解决:在更新mysql数据库的时候存在一个为题:如果每次修噶一下数据,就对数据库进行更新,会导致更新太频繁,浪费资源,解决方法有:先把一批需要更新的内容记录下来,积攒了一部分之后再进行统一更新,多了一个缓存的作用,积攒一部分再一起做!
类比我开了一家酒店,每天喝酒的人需要记录账单,我有两种记录方式:1)对每个人的消费记录进行记录,需要频繁打开账本;2)在大堂前放一个黑板,消费一笔记一笔,黑板写满了,更新到账本中去,(这里账本就是MySQL数据库,黑板就是redo log日志,日志容量是有限的。容量是循环使用的,使用后面的,在保存前面的基础上进行删除)
redo log作用:当数据库发生异常重启的时候,能够保证之前对数据库的操作内容,全部得到保存,也叫做crash-safe能力。
问题一:为什么需要两个日志:因为之前非InnoDB引擎只有bin log日志,用于数据库重启异常,需要有一个日志进行操作记录,之后InnoDB引擎出来了,又多了个redo log日志,用于实现crash-safe功能。只有binlog不具备crash-safe能力,
问题二:为什么redo log具有crash-safe能力,而binlog不具备‘’
因为redo记录的内容为“循环写”物理日志,会详细到修改了那一页的信息,而binlog日志比较大条,只是“追加写”的逻辑日志,只能记录添加,删除,修改了哪一个内容,不能够细致到哪一步。
为什么redo log具有crash-safe能力,而binlog不具备
如上图所示:其中浅色为InnoDB引擎的作用,深色为执行器的作用。
过程:先提交redolog日志(暂时不上传),再提交binlog日志,两个日志齐备后自动触发commit,上传redolog日志。(相当于在这里多了一个事务的操作,两个日志同时成功或者同时失败)
错误情况:先写redolog和先写binlog日志都会发生数据不一致的错误。
疑问一:前面我说到定期全量备份的周期“取决于系统重要性,有的是一天一备,有的是一周一备”。那么在什么场景下,一天一备会比一周一备更有优势呢?或者说,它影响了这个数据库系统的哪个指标?
回答一:主要看对数据丢失的重要性程度;内容的更新频率,是否是增删改操作多还是查询操作多!
疑问二:如果使用的是InnoDB搜索引擎,是不是可以不要binlog了?
回答二不可以,因为redolog日志是循环写, 修改一部分就会写进磁盘里,不能够恢复任意一个时段的数据情况,只有不存在容量大小限制的binlog日志能够。redolog日志填补了一个crash-safe功能。
大神对本章的见解:
事务是在引擎层实现功能的,且InnoDB引擎才具有,MyISAM不具备。
MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务(MyISAM不支持)
1) 原子性:事务内的操作,要么全部成功,要么全部失败
2)一致性:我们不追求整个操作过程中每一时刻的一致性(强一致性),转而追求最终结果的一致性(最终一致性)。
3)持久性:修改后的数据最终会保存到磁盘中,永久改变。
4)隔离性:事务之间是相互隔离的,互不影响,影响程度通过隔离级别控制。
读取未提交:事务之间可以读取未提交的信息,会出现脏读(即一些临时的数据,不需要去读)
读取已提交:只能读取事务提交了的数据,但是会出现幻读(对同一个数据进行两次读,如果在中间过程中,其他事务对数据修改了,会造成数据的不一致,像幻觉一样)
可重复读:一个事务,如果对相同数据进行读操作,数据会保持一直,及时在事务中间,其他事务已经改变了数据,
可串行化:一个事务执行过程中会进行上锁(写会加写锁,读会加读锁),当事务提交后才会解锁,下一个事务再重头执行。
mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
事务一 | 事务二 |
---|---|
启动事务查询得到值1 | 启动事务 |
查询得到值1 | |
将1改成2 | |
查询得到值V1 | |
提交事务 | |
查询得到值V2 | |
提交事务 | |
查询得到值V3 | |
隔离方式 | V1 | V3 | V3 |
---|---|---|---|
读取未提交 | 2 | 2 | 2 |
读取已提交 | 1 | 2 | 2 |
可重复度 | 1 | 1 | 2 |
可串行化 | 2 | 2 | 2 |
数据库为MySQL时,默认的隔离级别为可重复度
数据库为Oracle时,默认的隔离级别为读取已提交
总结:没有最好的隔离级别,只有最合适的隔离级别,具体问题具体分析。
事务的隔离是通过视图实现的:每个视图对应一张独立的表格,可以进行数据的增删改查。
读取未提交:没有视图的概念
读取已提交:在每个SQL执行开始的时候创建
可重复读:在事务开启的时候创建(贯穿整个事务过程,用一个视图显示)
通过MVCC(多版本并发控制):每一个数据后面有两个隐藏列(版本号和过期号,同一个版本下的数据会形成条链子,不同版本下的多事务能够并发执行)多一条数据在系统中存在多个版本,即多版本并发控制。
轻松理解:多版本并发控制MVCC
select * from information_schema.innodb_trx where
TIME_TO_SEC(timediff(now(),trx_started))>60
参考文献
- 极客时间:MySQL实战45讲
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。