mysql知识脉络_MySQL知识点记录(一)

应用场景

这个可能要依据所采用的存储引擎(myisam,innerdb)来看。

Django下MySQL读写分离的设计实现

在Django框架下,数据库的读写分离的设计一般有两种方式:

1. 手动实现

获取数据库实例的时候调用using,举个栗子说明:

transaction = PrepayTransactions.objects.using('read').filter(channel='wechat', deactivated_at__is_null=True).first()

transaction.channel = 'alipy'

transaction.save(using='read')

2. 自动路由处理

重写数据库路由类,在settings.py文件中配置DATABASE_ROUTERS

class MasterSlaveDBRouter(object):

"""数据库主从读写分离路由"""

def db_for_read(self, model, **hints):

"""读数据库"""

return "slave" # 其中slave是settings.py配置的数据的别名

def db_for_write(self, model, **hints):

"""写数据库"""

return "default" # 其中default是settings.py配置的数据的别名

def allow_relation(self, obj1, obj2, **hints):

"""是否运行关联操作"""

return True

然后配置数据库路由(settings.py)

DATABASE_ROUTERS = ['path_to_router.MasterSlaveDBRouter']

MySQL主从复制

这个一般是从MySQL的高可用性来说的,都是基于MySQL Replication来实现的,实现的原理一般是数据库主节点对其数据的更新保存到binary log文件中,而从节点通过I/O线程把主节点上bin log拷贝到从节点并保存为relay log,当从节点上的sql线程监测到relay log新增内容时开始执行对应的SQL语句来实现数据的同步。

目前MySQL主从数据复制技术大概有三种:异步复制、同步复制和半同步复制,至于这三种复制的区别可参考mysql系列(四)异步复制、全同步复制与半同步复制网上这篇博文,此处就不再赘述。

MySQL主从架构的模式主要有四种:

一主一从

一主多从

主主互备

双主多从

其中读业务数据量特别大的时候考虑多从架构,另外为了实现一台master出现故障时自动切换,可以采用keepalived(主主互备架构,只会监控到主节点的状态)、MMM(双主多从比较好,同时监控master和slave节点的状态)等工具来实现。

乐观锁和悲观锁

1. 乐观锁

乐观的认为在自己取数据的时候不会有其他线程来更改数据,因此取数据的时候不加锁,但对数据进行update等写的操作时要加锁(这个一般通过版本号设计,CAS设计来实现)

2. 悲观锁

不管是读数据还是更新数据都加上锁,这个一般在数据库级别来实现,比如mysql自己的锁机制(行锁,表锁,读锁,写锁),像select ... for update就是使用了悲观锁。

选择问题:这个要依据实际的应用场景来决定,一般来讲,读频繁的数据库加乐观锁,而写频繁的数据库加悲观锁。

事务及事务的隔离级别

1. 事务的四大特性(ACID)

原子性:一个事务中的所有操作要么全部执行,要么全部回滚,不可能存在一部分操作成功一部分操作失败的情况;

一致性:事务从一个一致性转化成另一个正确的一致性状态,通常会通过事务的其它三个属性AID来保证;

隔离性:事务在提交完成之前,其他会话无法看到事务的执行结果;

持久性:事务一旦被提交,数据会保存下来,哪怕是提交完之后系统崩溃也不会丢失数据;

2. 事务的隔离级别

读未提交:事务未commit操作之前其他会话能够读到要更新的数据,由于没有commit操作发生数据回滚,造成脏读;

读提交:事务未commit操作之前其他会话无法读到要更新的数据(读到的还是之前的老数据),待commit操作之后其他会话又读到的是新数据,两次读到的数据不一致,不可重复读;

可重复读:可重复读解决了脏读、不可重复读的问题,但可能会造成幻读,比如一个事务A检测到某个数据不存在准备插入一个新数据(包含主键),但这个时候事务B先插入了这个新数据并且做了commit,然后事务A再进行插入就会报错,但是查询又发现该数据就是不存在(因为MVCC的原因),此时就造成了幻读;

串行化:事务中行数据读写都加锁,这样就导致其他进程对该数据的读写都会被阻塞,影响性能;

MySQL默认的事务的隔离级别是可重复读

MVCC

在上面解释可重复读出现幻读提到MVCC,这里就顺便解释一下,全称多版本并发控制,从字面意思不难看出它是为控制并发而设计出来的,它一般配合或者取代行级锁使用,降低系统开销,一般是通过保存数据在某个时间点的快照来实现的。

MySQL InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现的,这两个列分别保存了这个行的创建时间和删除时间,不过这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),每开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID。

Innodb检查每行数据,确保他们符合两个标准:

InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行

行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除

符合了以上两点则返回查询结果。

可序列化的数据库锁

事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放 — 其他事务通过添加共享锁也可以读取数据

事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放 — 其他事务不能对其进行读写操作

最后,再细细结合实例理解几个概念:

脏读:事务A修改了某个数据但未提交,然后事务B读了这条数据(更改后),后来事务A回滚了,这就形成事务B的脏读;

不可重复读:事务A先读了某个数据,而事务B对这个数据进行了更改且提交了,这时候事务A再读这个数据时发现跟之前读的数据不一样了,这就是不可重复读;

幻读:其实跟不可重复读有点类似,只不过幻读侧重新增数据,而不可重复读则侧重更新或者删除;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值