• (转)mysql锁相关知识


    原文地址:http://www.cnblogs.com/RicCC/archive/2009/09/25/mysql.html

    存储引擎

    Attribute MyISAM Heap BDB InnoDB
    Transactions No No Yes Yes
    Lock granularity Table Table Page (8 KB) Row
    Storage Split files In-memory Single file per table Tablespace(s)
    Isolation levels None None Read committed All
    Portable format Yes N/A No Yes
    Referential integrity No No No Yes
    Primary key with data No No Yes Yes
    MySQL caches data records No Yes Yes Yes
    Availability All versions All versions MySQL-Max All Versions

    To make it easier to follow the unique characteristics of each storage engine, I created this magic quadrant diagram:

    Below are some examples of using the best storage engine for different tasks:
    Search Engine - NDBCluster
    Web stats logging - Flat file for the logging with an offline processing demon processing and writing all stats into InnoDB tables.
    Financial Transactions - InnoDB
    Session data - MyISAM or NDBCluster
    Localized calculations - HEAP
    Dictionary - MyISAM

    MyISAM

    设计为处理读频率远大于写频率的情况,查询性能非常好;不支持事务,没有REDO、UNDO日志;支持表锁;
    每个表使用独立的文件,索引和数据都 存放在不同文件中,文件的存储以file block(页)的形式存储。只缓存索引,并不缓存实际数据,每次读取数据时要使用磁盘IO,索引在内存中以cache block形式组织,与file block对应。索引的缓存使用LRU算法管理,为了提高缓存的利用率,支持将缓存分成多个区域,例如分成Hot Area、Warm Area
    key_buffer_size:设置缓存总大小
    key_buffer_block_size:设置cache block大小
    key_cache_division_limit:以百分比的形式将整个缓存区划分为多个区域。系统默认为100,即只有Warm Area
    key_cache_age_threshold:控制各区域中的何时被降级,值越小,越容易降级到下一级area中
    表的扫描分为Sequential Scan和Radom Scan 2种方式,read_buffer_size设置sequential scan时使用的缓存,read_rnd_buffer_size设置radom scan时使用的缓存
    InnoDB
    设计用于高并发读写情况,支持行锁(必须有索引支持);支持事务安全性,具有REDO、UNDO日志,具备故障恢复能力,其事务实现了SQL92的4个级别;支持外键,实现了数据库的引用完整性特性;
    Adaptive Hash Index:InnoDB自动检测索引状况,如果发现可以通过hash index提高效率,会在内部创建一个基于B-Tree的hash index,并根据B-Tree索引的变化自动调整。hash index并不基于整个B-Tree创建,只针对其中的某部分;并不会存储到磁盘,仅创建在缓存区中
    InnoDB的数据文件支持共享表空间和独享 表空间2种模式,数据和索引存储在一起,支持数据和索引的缓存。存储结构从大到小依次为 tablespace->segment->extent->Page,page默认为16KB,每个extent包含64个 page,每个segment存放同一种数据,一般每个表存放于一个单独的segment中

    锁机制
    有表锁(MyISAM)、页锁(BDB)、行锁(InnoDB)三种

    表锁
    有4个队列记录锁的使用情况:Current read-lock(当前读锁队列), Pending read-lock(等待读锁的队列), Current write-lock(当前写锁队列), Pending write-lock(等待写锁的队列)
    读锁、写锁
    a). Current write-lock中当前资源的写锁会阻塞读锁和写锁请求.
    b). Pending write-lock中WRITE类型的写锁会阻塞除了READ_HIGH_PRIORITY类型外的所有读锁请 求;READ_HIGH_PRIORITY类型的读锁比WRITE类型的写锁优先级高,因此它会阻塞Pending write-lock中所有的写锁请求;除了WRITE类型的写锁,Pending write-lock中其他类型的写锁优先级比读锁低(提高查询的响应时间)
    c). Current write-lock中对资源的写锁类型为WRITE_ALLOW_WRITE时,允许除了WRITE_ONLY之外的所有读锁和写锁请求
    MyISAM是MySQL官方开发的存储引擎,完全使用MySQL自己的表锁机制,其他几种支持事务的存储引擎都是让MySQL将锁处理交由存储引擎自行 实现,他们在MySQL中仅持有WRITE_ALLOW_WRITE类型的锁,至于锁的定义、并发冲突控制等都由各存储引擎处理
    MyISAM表锁优化提示:MyISAM表锁读写互相阻塞,写锁优先级高于读锁
    a). 参数选项low_priority_updates设置写锁优先级比读锁低,用于保证查询响应速度
    b). 参数选项concurrent_insert配置是否使用并发插入特性,可以实现并发的读取和插入操作,配置值: 0:不允许并发插入; 1:数据文件中不存在空闲空间的时候可以在文件尾部进行并发插入; 2:不管数据文件是否存在空闲空间,均允许在文件尾部进行并发插入(插入操作将一直在文件尾部进行,中间的空闲空间无法利用,适用于删除操作很少的表)

    InnoDB的行锁
    不是MySQL实现的锁机制,行锁都由其他存储引擎实现,这里以InnoDB为例(不同存储引擎实现机制也不一样)
    Oracle的行锁是在物理块的事务槽中记录锁信息,而InnoDB是在索引键值的起始、结束位置上记录锁信息(间隙锁),所以InnoDB的行锁只是利用索引实现的一个范围锁,而利用索引可以定位到数据行
    锁类型以及排他性:

      共享锁(S) 排他锁(X) 意向共享锁(IS) 意向排他锁(IX)
    共享锁(S) 兼容 冲突 兼容 冲突
    排他锁(X) 冲突 冲突 冲突 冲突
    意向共享锁(IS) 兼容 冲突 兼容 兼容
    意向排他锁(IX) 冲突 冲突 兼容 兼容

    InnoDB行锁潜在的问题:
    a). 如果无法使用索引信息,InnoDB将使用表锁
    b). 当索引不是确定到某一行数据时,InnoDB锁定的是索引匹配到的整个范围内的数据。例如使用索引定位到了10条记录,而加上非索引的条件可以准确确定到一条记录,这种情况下InnoDB仍然锁定这10条记录
    事务隔离级别:
    InnoDB实现了SQL92的4个隔离级别:Read UnCommited, Read Commited, Repeatable Read, Serializable
    InnoDB有死锁检测机制,将发生死锁的2个事务中较小(修改数据量比较少)的那个作为死锁牺牲品。当然只限于InnoDB存储引擎范围之内,跨存储引擎的死锁只能通过死锁超时设置进行处理

    索引
    MySQL主要有4类索引:B-Tree索引、Hash索引、Fulltext索引、R-Tree索引

    B-Tree索引: 通用索引类型
    InnoDB中的B-Tree索引分为Cluster形式的Primary Key和Secondary Index,与SQL Server类似,Primary Key索引的叶节点是实际数据文件,按索引顺序排列,Secondary Index的叶节点只存储Primary Key值。MyISAM的主键索引和非主键索引没什么区别,与InnoDB的Secondary Index类似,只是其叶节点存放的不是PK值,而是直接定位到数据行的信息

    Hash索引:
    将数据的索引键值进行hash运算建立索引,查询匹配时将查询条件也做hash运算,比较hash值进行匹配。主要是Memory和NDB Cluster存储引擎使用
    Hash索引的查询效率非常高,因为不需要像B-Tree一样从根匹配到页节点(《MySQL性能调优与架构设计》中说hash索引可以一次定位要查找的 记录,这种说法可能存在问题,Hash索引的组织、hash值的匹配同样需要数据结构和算法的实现,不可能一次定位,设想hash索引以B-Tree方式 组织,比B-Tree索引优秀的地方可能是其B-Tree数据量会小,即使这样也可能意味着hash冲突的存在,其效率比B-Tree索引高的说法是有待 验证的,可能需要有不少前提条件)
    缺点:只能进行等值匹配;hash索引是无序的,可能需要额外的排序操作;无法进行部分匹配,只能全索引匹配;遇到hash冲突后效率可能会比较低

    Fulltext索引: 只有MyISAM的CHAR, VARCHAR, TEXT三种数据类型支持fulltext索引,主要用于优化效率比较低的like '%***%'操作
    MySQL的fulltext中文支持有待考察,fulltext索引的创建成本比较高

    R-Tree索引: 用于空间数据检索
    MySQL有空间数据类型GEOMETRY(5.0.16之前只有MyISAM支持,之后BDB、InnoDB、NDB Cluster、Archieve等支持),只有MyISAM存储引擎支持R-Tree索引

  • 相关阅读:
    《程序员修炼之道》阅读笔记2
    《程序员修炼之道》阅读笔记1
    Ubuntu16桥接模式上网并设置静态ip
    读《架构漫谈》有感
    质量属性6个常见属性的场景分析
    sql注水
    python版本切换
    使用vue-cli构建 webpack打包工具时,生产环境下,每次build时,删除dist目录,并重新生成,以防dist目录文件越来越多。
    Java栈与堆
    从一个字符串s的第i个字符(不包括此字符)开始删除n个字符
  • 原文地址:https://www.cnblogs.com/sunyuw/p/4303356.html
Copyright © 2020-2023  润新知