mysql锁知识小了解

一、概述

mysql的锁分为表锁和行锁两种,其中myisam引擎用的是表锁, innoDB默认的使用是行锁, 其他情况是表锁。

两种锁的优缺点:

表级锁:加锁速度快,开销小。不会出现死锁的情况,粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:加锁速度慢,开销大。 会出现死锁的情况,粒度小, 发生锁冲突的概率最小,并发度最高

页面锁:介于以上两者之间

无法确定哪种锁更合适:

表级锁更适合查询为主,只有少量按索引更新数据的应用,如web应用。

行级锁适合有大量索引并发更新少量不同的数据,同时有并发查询的应用,如一些在线的事物系统。

二、MyIsam存储引擎

只支持表锁。

查询表级锁的争用情况:

table_locks_waited

table_locks_immediate

1.  mysql> show status like ‘table%‘;

2.  +-----------------------+-------+

3.  | Variable_name         | Value |

4.  +-----------------------+-------+

5.  | Table_locks_immediate | 2979  |

6.  | Table_locks_waited    | 0     |

2.1、表级锁的锁模式

两种模式:表共享读锁,表独占写锁

分析:

读锁不会阻塞其他用户对同一张表的读请求,但会阻塞对同表的写请求;

对表的写请求,会阻塞对同表的读操作和写操作

myisam的读操作和写操作之间,以及写操作之间是互相串行的。

2.2、如何加表锁

myisam引擎在执行查询语句之前会自动的给涉及到的表加上读锁,执行更新操作的语句之前会自动加上写锁,这个过程不需要用户干预。

加锁代码如下

1.  Lock tables orders read local, order_detail read local;

2.  Select sum(total) from orders;

3.  Select sum(subtotal) from order_detail;

4.  Unlock tables;

2.3、并发插入

Myisam也支持查询和插入同时进行的并发操作:存储引擎有一个系统变量concurrent_insert, 专门控制并发插入的行为。值为 0 1 2

concurrent_insert == 0 :不允许并发的插入

concurrent_insert == 1 :(默认值1)如果该表没有空洞(表的中间没有被删除的行),允许边读边插入。

concurrent_insert == 2 :无论有没有空洞都运行在表的末尾插入数据

2.4、锁调度

Myisam的读写操作是互斥的,读写操作是串行的。

如果一个进程请求表的读锁,同时另一个线程请求表的写锁,那么写的进程会先获得锁,就算是读的进程先到锁的等待队列,如果有写进程

那么也是写进程获得锁,因为mysql默认认为写进程比读的进程更加重要。 可以通过一些设置来调节这些级别:

SET LOW_PRIORITY_UPDATES = 1 :更新请求的优先级降低

还可以通过调节系统参数来调节读写的冲突:max_write_lock_count, 当读锁的阻塞数量达到这个值的时候,就会把写请求的优先级降低,给读的进程获得锁的机会

三、InnoDB存储引擎

InnoDB和Myisam最大的不同就是

1、事物支持

2、行级锁

3.1、事物以及其的属性

  • 原子性:对数据的修改要么执行,要么全部不执行
  • 一致性:事物开始和完成时,数据都应该保持一致的状态,数据结构的完整性都是一致的。
  • 隔离性:数据库系统提供一定的隔离机制,保证事物在不收外部并发操作影响的独立环境进行,意味着事物处理过程中是不对外可见的。
  • 持久性:事物完成后,对于数据的修改是永久性的,即时出现系统故障会保持

相对于串行处理来说,并发事物处理能力能大大的增强数据库资源的利用率,提高数据库系统的吞吐量,可以支持更多的用户量,但是也带来一定的问题:

1、更新丢失:两个事物选择同一行,然后都是基于最后选定的值更新,每个事物都不知道其他事物的存在。最后的事物就会覆盖前面的事物更新的数据。

2、脏读:一个事物正在对一条记录做修改,在这个事物完成并提交之前,此时这条数据就是不一致的状态;有一条事物同时来读取这条记录,并进行下一步的处理,就会产生未提交的数据依赖关系。叫做脏读。

3、不可重复读:一个事物在读取某个数据后的某个时间,再次读取以前读过的数据,却发现读出的数据发生了变换,或者删除了某些记录,这种现象叫做“不可重复读”。

4、幻读:一条事物按照一定的条件检索出以前读取的数据,却发现检索出了其他事物插入的符合条件的数据。这种现象称为 幻读。

3.2、事物隔离级别

事物处理带来的问题中,“更新丢失” 应该是可以完全避免的。防止数据更新丢失 不能全部靠数据库的事物机制来控制,需要应用程序对更新的数据加上必要的锁来控制。 其余的“脏读, 幻读, 不可重复读” 都是数据库的读一致性的问题,那么必须由数据库提供一定的事物隔离机制来解决。解决方式基本分为两种:

  • 读取数据前,对其加上锁。
  • 不加任何锁机制,通过一定的机制生成数据请求时间点的一致性数据快照,并用这个快照提供一定级别的(语句, 事物)的一致性读取,从用户的角度来看,好像是数据库可以提供一份数据的多个版本,因此可以叫做数据库的多版本控制(多版本数据库)。

数据库的隔离机制越高,并发副作用越小, 但是付出的性能代价也是越高,因为事物隔离实质上就是对事物进行串行进行。

为了解决并发和隔离的矛盾,提供了4个隔离级别, 每个级别的隔离程度不同,允许出现的副作用也不同,根据业务要求来决定。


隔离级别

读数据一致性

脏读

不可重复读

幻读

未提交读

最低级别







已提交读
语句级






可重复读
事物级






可序列化

最高级别(事物级)






3.3、InnoDB锁

共享锁:允许一个事物去读一行,阻止其他事物获得相同数据集的排他锁

排他锁:允许获的排他锁的事物更新数据,阻止其他事物取得相同数据集的共享读锁和排他写锁。

InnoDB为了行锁和表锁共存,实现多粒度的锁机制,还有两种内部使用的意向锁,这两种意向锁都是表锁

意向共享锁:事物打算给数据行加上行共享锁,事物在给一个数据行加共享锁前必须获得该表的意向共享锁

意向排他锁:事物打算给数据行加上行排他锁,事物在给一个数据行加排他锁前必须获得该表的意向排他锁

InnoDB的实现方式

行锁是通过索引上的索引项上加锁来实现的:只有通过索引条件检索数据才使用行级锁,否则,InnoDB将使用表搜

3.4、InnoDB死锁

死锁的例子:

步骤1:

用户1:select * from table1 where id = 1;

用户2:select * from table2 where id = 1;

步骤2:

用户1:select * from table2 where id = 1; (此时在步骤1中的用户2中已经取得了排他锁,故等待。。。)

用户2:select * from table1 where id = 1;  (死锁)

发生死锁后,InnoDB 一般都能自动检测到,并使一个事物释放锁并回退,另一个事物获得锁,继续完成事物。但是在涉及到外部锁,或涉及到表锁的情况下,InnoDB并不能自动检测到死锁,需要通过设置锁等待超时参数 innodb_lock_wait_timeout 来解决,需要说明的是, 这个参数并不是只用来解决死锁的问题,在并发访问比较高的情况下,如果大量事物因无法立即获得所需的锁而挂起,会占用大量的计算机资源,造成严重的性能问题,甚至拖垮数据库,我们通过设置合适的锁等待超时值,可以避免这种情况的发生。

此文是通过了解mysql的锁的基本工作原理:

1、让我们在业务数据处理的流程上做出好的设计,可以大部分避免无法解开死锁导致应用挂掉。

举个例子:不同的程序会并发存取某个表,尽量约定好程序以相同的顺序来访问表来降低死锁几率。

2、同时了解一下常用的检测参数值,追踪mysql的锁状态。

时间: 2024-10-16 11:41:40

mysql锁知识小了解的相关文章

MySQL ---- 锁知识

锁 我们知道mysql中支持很多个存储引擎,在不同的存储引擎下所能支持的锁是不同的,我们通过MyISAM和InnoDB来进行一下对比. 表级锁定(table-level) ? 表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制.该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小.所以获取锁和释放锁的速度很快.由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题. ? 当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣. ?

PHP链接Mysql数据库的小知识

1:在PHP写隔行变色有三种写法(但是最好的是用js+css) (1)CSS: tr:nth-child(even){             background: #cad9ea;         } even:代表偶数: ood:代表奇数:   (2)PHP: <?php                 if($n %2 == 0){            ?>            <tr style="background: #cad9ea"> <

mysql锁

锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著

MySQL锁解决并发问题详解

文章分为以下几个要点 问题描述以及解决过程 MySQL锁机制 数据库加锁分析 下面讨论的都是基于MySQL的InnoDB. 0. 问题描述以及解决过程 因为涉及到公司利益问题,所以下面很多代码和数据库信息,进行了缩减和修改,望见谅. 业务场景是优惠券系统规则规定了一个优惠券活动最多可发行多少张优惠券和每个用户最多可领取优惠券数量. 下面列出两张表的结构. 活动表 CREATE TABLE `coupon_activity` ( `act_id` int(11) NOT NULL AUTO_INC

Mysql数据库知识总结(看资料总结出来的)

毕业到现在算起来做了3年多服务端开发了,毕业之后很少有时间想在学校一样可以抽出一些空余的时间对知识进行一个总结,到现在也是时候对一些关键的知识一个总结,今天趁着时间比较多,先来对用了3年多的开源关系型数据库mysql进行一下总结,整理了一下知识点可以分为以下几点进行: 一.基础知识 二.SQL优化与索引 三.数据库规范建议 四.数据库设计 五.数据库架构 一.基础知识 知识点主要包括:数据类型 常用函数 字符集 事务隔离级别 锁机制 (1).数据类型 数值类型 -- TINYINT.SMALLI

mysql 锁表详解

为了给高并发情况下的MySQL进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级. MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking):BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁:InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁. MySQL这3种锁的特性可大致归纳如下: 表级锁:开销小,

20.Mysql锁机制

20.锁问题锁是计算机协调多个进程或线程并发访问某一资源的机制. 20.1 Mysql锁概述锁类型分为表级锁.页面锁.行级锁.表级锁:一个线程对表进行DML时会锁住整张表,其它线程只能读该表,如果要写该表时将产生锁等待. 优点:开销少.加锁快.不会产生死锁.缺点:锁粒度大.容易产生锁等待.并发低.行级锁:一个线程对表进行DML时会锁住该表影响的行,其它线程可以读该表,也可以DML该表其它的行,如果要DML已被锁定的行时将产生锁等待. 缺点:开销大.加锁慢.会产生死锁.优点:锁粒度小.不容易产生锁

MySQL锁(行锁、表锁、页锁、乐观锁、悲观锁等)

锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素.从这一角度来说,锁对于数据库而言就显得尤为重要. MySQL锁 相对于其他的数据库而言,MySQL的锁机制比较简单,最显著的特点就是不同的存储引擎支持不

[转帖]深入理解 MySQL—锁、事务与并发控制

深入理解 MySQL—锁.事务与并发控制 http://www.itpub.net/2019/04/28/1723/ 跟oracle也类似 其实所有的数据库都有相同的机制.. 学习了机制才能够更好的工作,. 数据和云 2019-04-28 10:45:07 本文共11796个字,预计阅读需要30分钟. 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MySQL 中的锁和事务,从而在业务系统开发过程中可以更好地优化与数据库的交互