mysql锁
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MySQL 锁
注本:
• MySQL锁的特点是不同的存储引擎支持不同的锁机制。比如, MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);
• BDB存储引擎采用的是页面锁(page-level locking),但也支持表 级锁;
• InnoDB存储引擎既支持行级锁(row-level locking),也支持表级 锁,但默认情况下是采用行级锁。
Tpis:
如果Table_locks_immediate / Table_locks_waited >一定的值(书上未介绍),最好采用InnoDB引擎, 因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些。
表级锁的锁模式
• MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)读锁 和表独占写锁(Table Write Lock)
则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向 链表)也都必须是正确的。 • l 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立” 环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。 • l 持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。 • 银行转帐就是事务的一个典型例子。
• SELECT查询的HIGH_PRIORITY(高优先级)关键字也类似。它允许SELECT插 入正在等待的写入操作之前,即使在正常情况下写入操作的优先级更高。另 外一种影响是,高优先级的SELECT在正常的SELECT语句之前执行,因为这些 语句会被写入操作阻塞。
• LOW_PRIORITY选项的语句都默认地按照低优先级来处理,那么请使用--lowpriority-updates选项来启动服务器。通过使用INSERT HIGH_PRIORITY来把 INSERT语句提高到正常的写入优先级,可以消除该选项对单个INSERT语句的 影响。
InnoDB的行锁模式及加锁方法
• l数共据享集锁的(排S他)锁:。允许一个事务去读一行,阻止其他事务获得相同 • l 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务
取得相同数据集的共享读锁和排他写锁。 • 另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还
有两种内部使用的意向锁(Intention Locks),这两种意向锁都是 表锁。 • l个意数向据共行享加锁共(享IS锁)前:必事须务先打取算得给该数表据的行IS加锁行。共享锁,事务在给一 • l一意个向数排据他行锁加(排IX他)锁:前事必务须打先算取给得数该据表行的加IX行锁排。他锁,事务在给
下面可查看例子
InnoDB行锁实现方式
• InnoDB行锁是通过给索引上的索引项加锁来实现的 • 这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据
行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索 引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表 锁!
• 通过指定启动参数low-priority-updates,使MyISAM引擎默认给予 读请求以优先的权利。
• 通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更 新请求优先级降低。
• 通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降 低该语句的优先级。
• 如果写入操作是一个LOW_PRIORITY(低优先级)请求,那么系统就不会认为 它的优先级高于读取操作。在这种情况下,如果写入者在等待的时候,第二 个读取者到达了,那么就允许第二个读取者插到写入者之前。只有在没有其 它的读取者的时候,才允许写入者开始操作。理论上,这种调度修改暗示着, 可能存在LOW_PRIORITY写入操作永远被阻塞的情况。如果前面的读取操作在 进行的过程中一直有其它的读取操作到达,那么新的请求都会插入到 LOW_PRIORITY写入操作之前。
• 所以对MyISAM表的读操作,不会阻塞其他用户对同一表的读请 求,但会阻塞对同一表的写请求;对 MyISAM表的写操作,则会 阻塞其他用户对同一表的读和写操作;MyISAM表的读操作与写 操作之间,以及写操作之间是串行的!根据如表20-2所示的例子 可以知道,当一个线程获得对一个表的写锁后,只有持有锁的线 程可以对表进行更新操作。其他线程的读、写操作都会等待,直 到锁被释放为止。
Fra Baidu bibliotek
分析表锁争锁的情况:
• 可以通过检查:show status like 'table%'; table_locks_waited表示需要等待的表锁数 和table_locks_immediate表示立即释放表锁数 状态变量来分析系统上的表锁定争夺: 如果Table_locks_waited的值比较高,则说明存在着较严重的表级锁 争用情况。
• l 当concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中 间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从 表尾插入记录。这也是MySQL的默认设置。
• l 当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许 在表尾并发插入记录。
下面讲另外一个Innodb
• 1.事务(Transaction)及其ACID属性
• 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性。 • l 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。 • l 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规
如何加表锁
• MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加 读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自 动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户 一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁
• 给MyISAM表显示加锁,一般是为了在一定程度模拟事务操作, 实现对某一时间点多个表的一致性读取。
MyISAM的锁调度
• MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的。 那么,一个进程请求某个 MyISAM表的读锁,同时另一个进程也 请求同一表的写锁,MySQL如何处理呢?
• 答案是写进程先获得锁。不仅如此,即使读请求先到锁等待队列, 写请求后到,写锁也会插到读锁请求之前!这是因为MySQL认为 写请求一般比读请求要重要。这也正是MyISAM表不太适合于有 大量更新操作和查询操作应用的原因,因为,大量的更新操作会 造成查询操作很难获得读锁,从而可能永远阻塞。这种情况有时 可能会变得非常糟糕!幸好我们可以通过一些设置来调节 MyISAM 的调度行为。
• 可以使用:lock table table_name read/write;
并发插入(Concurrent Inserts)
• MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控 制其并发插入的行为,值分别可以为0、1或2。
• 可修改my.conf: • l 当concurrent_insert设置为0时,不允许并发插入。
锁定粒度界于表锁和行锁之间,并发度一般。
• 从锁的角度来说:表级锁更适合于以查询为主,只有少量按索引 条件更新数据的应用,如Web应用;
• 而行级锁则更适合于有大量按索引条件并发更新少量不同数据, 同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。
• 重点介绍MySQL表锁和 InnoDB行锁的问题, • 注:BDB已经被InnoDB取代,即将成为历史
• LOW_PRIORITY关键字影响DELETE、INSERT、LOAD DATA、REPLACE和UPDATE语 句的执行调度。通常情况下,某张数据表正在被读取的时候,如果有写入操 作到达,那么写入者一直等待读取者完成操作(查询开始之后就不能中断, 因此允许读取者完成操作)。如果写入者正在等待的时候,另一个读取操作 到达了,该读取操作也会被阻塞(block),因为默认的调度策略是写入者 优先于读取者。当第一个读取者完成操作的时候,写入者开始操作,并且直 到该写入者完成操作,第二个读取者才开始操作。
• 如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的 锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。
• 意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE 和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于 普通SELECT语句,InnoDB不会加任何锁;
锁的特性大致归纳:
• 开销、加锁速度、死锁、粒度、并发性能 • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发
生锁冲突的概率最高,并发度最低。 • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发
生锁冲突的概率最低,并发度也最高。 • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;