zoukankan      html  css  js  c++  java
  • MySQL


    MySQL事务

    事务是指逻辑上的一组操作,组成这个操作的各个单元,要么全部成功,要么全部失败回滚

    • 支持连续SQL的集体成功或集体撤销。

    • 事务是数据库在数据数据完整性的一个功能。

    • 需要利用 InnoDB 或 BDB 存储引擎,对自动提交的特性支持完成。

    • InnoDB被称为事务安全型引擎。

    ---事务开启 start transaction; 或者 begin ; 开启事务后,所有被执行的SQL语句均被认作当前事务内的SQL语句。 
    
    -- 事务提交 commit; 
    
    -- 事务回滚 rollback; 如果部分操作发生问题,映射到事务开启前
    

    事务的特性

    1.原子性(Atomicity)
          事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
    
    2.一致性(Consistency)
          事务前后数据的完整性必须保持一致
          -事务开始和结束时,外部数据一致
          -在整个事务过程中,操作是连续的
    
    3.隔离性(Isolation)
          多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间的数据要相互隔离。
          事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的
    
    4.持久性(Durability)
          一个事务一旦被提交,它对数据库中的数据改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
    

    --事务的实现

    1. 要求是事务支持的表类型
    
    2. 执行一组相关的操作前开启事务
    
    3. 整组操作完成后,都成功,则提交;如果存在失败,选择回滚,则会回到事务开始的备份点。
    

    --事务的原理

    利用InnoDB的自动提交(autocommit)特性完成。
    普通的MySQL执行语句后,当前的数据提交操作均可被其他客户端可见。
    而事务是暂时关闭“自动提交”机制,需要commit提交持久化数据操作。

    --注意

    1. 数据定义语言(DDL)语句不能被回滚,比如创建或取消数据库的语句,和创建、取消或更改表或存储的子程序的语句。
    
    2. 事务不能被嵌套
    

    并发事务带来的几个问题

    更新丢失,脏读,不可重复读,幻读。
    事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)

    --Read Uncommitted(读取未提交内容)
          在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
    
    --Read Committed(读取提交内容)
    这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
    
    --Repeatable Read(可重读)
    这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
    
    --Serializable(可串行化) 
    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
    
    
    
    --ps:这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:
    --脏读(Drity Read):
    某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
    
    --不可重复读(Non-repeatable read):
    在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
    
    --幻读(Phantom Read):
    在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
    

    1,脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

    2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

    3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

    小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

    低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

    4.可重复读(Repeatable read)是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。

    悲观锁和乐观锁

    --乐观锁
    乐观锁不是数据库自带的,需要我们自己去实现,
    乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,
    在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,
    再去判断是否有冲突了。
    
    --悲观锁
    每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
    这样别人想拿这个数据就会block(阻塞)直到它拿到锁
    

    设计到锁的问题

    更新丢失:最后的更新覆盖了其他事务之前的更新,而事务之间并不知道,发生更新丢失。更新丢失,可以完全避免,应用对访问的数据加锁即可。
    
    脏读:(针对未提交的数据)一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,
    会产生对第一个未提交,解决方案加锁,或者调整mysql事务隔离级别,数据库的事务隔离越严格,并发负作用越小,代价越高
    

    MySQL主从同步原理

    mysql主从同步的原理很简单,从库生成两个线程,一个I/O线程,一个SQL线程;i/o线程去请求主库 的binlog(二进制日志),
    并将得到的binlog日志写到relay log(中继日志) 文件中;主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;
    SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致
    

    关于binlog日志

    binlog是二进制日志文件,用于记录mysql的数据更新或者潜在更新(比如DELETE语句执行删除而实际并没有符合条件的数据)
    
    binlog索引文件mysql-bin.index。如官方文档中所写,binlog格式如下:
    
    binlog文件以一个值为0Xfe62696e的魔数开头,这个魔数对应0xfe 'b''i''n'。
    
    binlog由一系列的binlog event构成。每个binlog event包含header和data两部分。
    
    header部分提供的是event的公共的类型信息,包括event的创建时间,服务器等等。
    
    data部分提供的是针对该event的具体信息,如具体数据的修改。
    

    主从同步延迟问题:

    架构方面
    
    1.业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力。
    
    2.单个库读写分离,一主多从,主写从读,分散压力。这样从库压力比主库高,保护主库。
    
    3.服务的基础架构在业务和mysql之间加入memcache或者Redis的cache层。降低mysql的读压力。
    
    4.不同业务的mysql物理上放在不同机器,分散压力。
    
    5.使用比主库更好的硬件设备作为slave
    
    总结,mysql压力小,延迟自然会变小。
    
    硬件方面
    
    1.采用好服务器,比如4u比2u性能明显好,2u比1u性能明显好。
    
    2.存储用ssd或者盘阵或者san,提升随机写的性能。
    
    3.主从间保证处在同一个交换机下面,并且是万兆环境。
    
    总结,硬件强劲,延迟自然会变小。一句话,缩小延迟的解决方案就是花钱和花时间。
    
    mysql主从同步加速
    
    1、sync_binlog在slave端设置为0
    
    2、–logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。
    
    3、直接禁用slave端的binlog
    
    4、slave端,如果使用的存储引擎是innodb,innodb_flush_log_at_trx_commit = 2
    

    MySQL优化

    为什么要优化

    系统的吞吐量瓶颈往往出现在数据库的访问速度上 随着应用程序的运行,数据库的中的数据会越来越多,
    处理时间会相应变慢 数据是存放在磁盘上的,读写速度无法和内存相比

    如何优化
    设计数据库时:数据库表、字段的设计,存储引擎 利用好MySQL自身提供的功能,如索引等 横向扩展:MySQL集群、负载均衡、读写分离 SQL语句的优化(收效甚微)

  • 相关阅读:
    《构建之法》阅读笔记二
    《构建之法》阅读笔记一
    软件工程个人课程总结
    纯随机数生成器
    递归方法
    素数的输出
    字母统计|英语的26 个字母在一本小说中是如何分布的
    类的声明
    FileInputStream类与FileOutputStream类
    验证码|程序登录界面
  • 原文地址:https://www.cnblogs.com/wonderlandlove/p/12877809.html
Copyright © 2011-2022 走看看