精华内容
下载资源
问答
  • mysql锁表

    2016-12-08 19:21:08
    MySQL锁表解决方法 一、我的处理过程 1、查进程,主要是查找被锁表的那个进程的ID SHOW PROCESSLIST; 2、kill掉锁表的进程ID KILL 10866;//后面的数字即时进程的ID 网上找了些资料,了解了一下,先分享...

    MySQL锁表解决方法

    一、我的处理过程

    1、查进程,主要是查找被锁表的那个进程的ID

    SHOW PROCESSLIST;

    2、kill掉锁表的进程ID

    KILL   10866;//后面的数字即时进程的ID

    网上找了些资料,了解了一下,先分享一下:

    二、mysql的锁表问题

    SHOW PROCESSLIST查看数据库中表的状态,是否被锁;
    kill id   //杀掉被锁的表
    ===================================================
    set autocommit=0;
    select * from t1  where uid=’xxxx’ for update    //在有索引(例如uid)的情况下是行锁,否则是表锁
    insert into t1 values(1,’xxxxx’);
    commit;
    =====================================================
    lock tables t1 write|read;
    insert into t1 values(2,’xxxxx’); //只有insert
    unlock tables;

    2 《轻松掌握MySQL数据库锁机制的相关原理》

    MySQL 5.1支持对MyISAM和MEMORY表进行表级锁定,对BDB表进行页级锁定,对InnoDB 表进行行级锁定。在许多情况下,可以根据培训猜测应用程序使用哪类锁定类型最好,但一般很难说出某个给出的锁类型就比另一个好。一切取决于应用程序,应用程序的不同部分可能需要不同的锁类型。为了确定是否想要使用行级锁定的存储引擎,应看看应用程序做什么并且混合使用什么样的选择和更新语句。例如,大多数Web应用程序执行许多选择,而很少进行删除,只对关键字的值进行更新,并且只插入少量具体的表。基本MySQL MyISAM设置已经调节得很好。

    在MySQL中对于使用表级锁定的存储引擎,表锁定时不会死锁的。这通过总是在一个查询开始时立即请求所有必要的锁定并且总是以同样的顺序锁定表来管理。

    对WRITE,MySQL使用的表锁定方法原理如下:

    ◆ 如果在表上没有锁,在它上面放一个写锁。
    ◆否则,把锁定请求放在写锁定队列中。

    对READ,MySQL使用的锁定方法原理如下:

    ◆如果在表上没有写锁定,把一个读锁定放在它上面。
    ◆否则,把锁请求放在读锁定队列中。

    当一个锁定被释放时,锁定可被写锁定队列中的线程得到,然后是读锁定队列中的线程。

    这意味着,如果你在一个表上有许多更新,SELECT语句将等待直到没有更多的更新。

    如果INSERT 语句不冲突,可以自由为MyISAM 表混合并行的INSERT 和SELECT 语句而不需要锁定。

    InnoDB 使用行锁定,BDB 使用页锁定。对于这两种存储引擎,都可能存在死锁。这是因为,在SQL语句处理期间,InnoDB 自动获得行锁定,BDB 获得页锁定,而不是在事务启动时获得。

    行级锁定的优点:

    · 当在许多线程中访问不同的行时只存在少量锁定冲突。
    · 回滚时只有少量的更改。
    · 可以长时间锁定单一的行。

    行级锁定的缺点:

    · 比页级或表级锁定占用更多的内存。
    · 当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。
    · 如果你在大部分数据上经常进行 GROUP BY 操作或者必须经常扫描整个表,比其它锁定明显慢很多。
    · 用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。

    在以下情况下,表锁定优先于页级或行级锁定:

    · 表的大部分语句用于读取。
    · 对严格的关键字进行读取和更新,你可以更新或删除可以用单一的读取的关键字来提取的一行:
    • UPDATE tbl_name SET column = value WHERE unique_key_col = key_value ;
    • DELETE FROM tbl_name WHERE unique_key_col = key_value ;
    · SELECT 结合并行的INSERT 语句,并且只有很少的UPDATE或 DELETE 语句。
    · 在整个表上有许多扫描或 GROUP BY 操作,没有任何写操作。
    不同于行级或页级锁定的选项:
    · 版本(例如,为并行的插入在MySQL中使用的技术),其中可以一个写操作,同时有许多读取操作。这明数据库或表支持数据依赖的不同视图,取决于访问何时开始。其它共同的术语是“时间跟踪”、“写复制”或者“按需复制”。
    · 按需复制在许多情况下优先于页级或行级锁定。然而,在最坏的情况下,它可能比使用常规锁定使用多的内存。
    · 除了行级锁定外,你可以使用应用程序级锁定,例如在MySQL中使用GET_LOCK()和RELEASE_LOCK()。这些是建议性锁定,它们只能在运行良好的应用程序中工作。
    为达到最高锁定速度,除InnoDB 和BDB 之外,对所有存储引擎,MySQL使用表锁定(而不是页、行或者列锁定)。对于InnoDB 和BDB 表,如果你用LOCK TABLES显式锁定表,MySQL只使用表锁定;如果你不使用LOCK TABLES,因为 InnoDB 使用自动行级锁定而BDB 使用页级锁定来保证事务隔离。

    但是对于大表,对于大多数应用程序,表锁定比行锁定更好,但存在部分缺陷。表锁定使许多线程同时从一个表中进行读取操作,但如果一个线程想要对表进行写操作,它必须首先获得独占访问。更新期间,所有其它想要访问该表的线程必须等待直到更新完成。

    表更新通常情况认为比表检索更重要,因此给予它们更高的优先级。这应确保更新一个表的活动不能“饿死”,即使该表上有很繁重的SELECT 活动。

    表锁定在这种情况下会造成问题,例如当线程正等待,因为硬盘已满并且在线程可以处理之前必须有空闲空间。在这种情况下,所有想要访问出现问题的表的线程也被设置成等待状态,直到有更多的硬盘空间可用。

    表锁定在下面的情况下也存在问题:

    · 一个客户发出长时间运行的查询。
    · 然后,另一个客户对同一个表进行更新。该客户必须等待直到SELECT完成。
    · 另一个客户对同一个表上发出了另一个 SELECT 语句。因为UPDATE比 SELECT 优先级高,该SELECT 语句等待UPDATE完成,并且等待第1个 SELECT 完成。

    下面描述了一些方法来避免或减少表锁定造成的竞争:

    · 试图使 SELECT 语句运行得更快。可能必须创建一些摘要(summary)表做到这点。
    · 用–low-priority-updates启动mysqld。这将给所有更新(修改)一个表的语句以比SELECT语句低的优先级。在这种情况下,在先前情形的第2个SELECT语句将在UPDATE语句前执行,而不需要等候第1个 SELECT 完成。
    · 可以使用SET_UPDATES=1语句指定具体连接中的所有更新应使用低优先级。
    · 可以用LOW_PRIORITY属性给与一个特定的INSERT、UPDATE或DELETE语句较低优先级。
    · 可以用HIGH_PRIORITY属性给与一个特定的SELECT语句较高优先级。
    · 为max_write_lock_count系统变量指定一个低值来启动mysqld来强制MySQL在具体数量的插入完成后临时提高所有等待一个表的SELECT 语句的优先级。这样允许在一定数量的WRITE锁定后给出READ锁定。
    · 如果你有关于INSERT结合SELECT的问题,切换到使用新的MyISAM表,因为它们支持并发的SELECT和INSERT。
    · 如果你对同一个表混合插入和删除,INSERT DELAYED将会有很大的帮助。
    · 如果你对同一个表混合使用 SELECT 和DELETE 语句出现问题,DELETE 的LIMIT 选项可以有所帮助。
    · 对 SELECT 语句使用SQL_BUFFER_RESULT可以帮助使表锁定时间变短。
    · 可以更改mysys/thr_lock.c中的锁代码以使用单一的队列。在这种情况下,写锁定和读锁定将具有相同的优先级,对一些应用程序会有帮助。

    这里是一些MySQL中表锁定相关的技巧:

    · 如果不混合更新与需要在同一个表中检查许多行的选择,可以进行并行操作。
    · 可以使用 LOCK TABLES 来提高速度,因为在一个锁定中进行许多更新比没有锁定的更新要快得多。将表中的内容切分为几个表也可以有所帮助。
    · 如果在MySQL中表锁定时遇到速度问题,可以将表转换为 InnoDB 或BDB 表来提高性能
    你对人生迷茫吗? 那就背起行囊,起步远行吧

    本篇转自:http://www.cnblogs.com/daxian2012/archive/2012/09/04/mysql.html

     

     

     

     

    三、锁表的机制

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制。

    一、概述

    MySQL有三种锁的级别:页级、表级、行级。

    MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level
    locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

    MySQL这3种锁的特性可大致归纳如下:

    表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
    行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
    页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

    二、MyISAM表锁

    MyISAM存储引擎只支持表锁,是现在用得最多的存储引擎。

    1、查询表级锁争用情况

    可以通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定争夺:
    mysql> show status like ‘table%’;
    +———————–+———-+
    | Variable_name | Value |
    +———————–+———-+
    | Table_locks_immediate | 76939364 |
    | Table_locks_waited | 305089 |
    +———————–+———-+
    2 rows in set (0.00 sec)Table_locks_waited的值比较高,说明存在着较严重的表级锁争用情况。

    2、MySQL表级锁的锁模式

    MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write
    Lock)。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁。

    所以对MyISAM表进行操作,会有以下情况:

    a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
    b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

    下面通过例子来进行验证以上观点。数据表gz_phone里有二百多万数据,字段id,phone,ua,day。现在同时用多个客户端同时对该表进行操作分析。

    a、当我用客户端1进行一个比较长时间的读操作时,分别用客户端2进行读和写操作:

    client1:
    mysql>select count(*) from gz_phone group by ua;
    75508 rows in set (3 min 15.87 sec) client2:
    select id,phone from gz_phone limit 1000,10;
    +——+——-+
    | id | phone |
    +——+——-+
    | 1001 | 2222 |
    | 1002 | 2222 |
    | 1003 | 2222 |
    | 1004 | 2222 |
    | 1005 | 2222 |
    | 1006 | 2222 |
    | 1007 | 2222 |
    | 1008 | 2222 |
    | 1009 | 2222 |
    | 1010 | 2222 |
    +——+——-+
    10 rows in set (0.01 sec)
    mysql> update gz_phone set phone=’11111111111′where id=1001;
    Query OK, 0 rows affected (2 min 57.88 sec)
    Rows matched: 1 Changed: 0 Warnings: 0

    说明当数据表有一个读锁时,其它进程的查询操作可以马上执行,但更新操作需等待读锁释放后才会执行。

    b、当用客户端1进行一个较长时间的更新操作时,用客户端2,3分别进行读写操作:

    client1:
    mysql> update gz_phone set phone=’11111111111′;
    Query OK, 1671823 rows affected (3 min 4.03 sec)
    Rows matched: 2212070 Changed: 1671823 Warnings: 0 client2:
    mysql> select id,phone,ua,day from gz_phone limit 10;
    +—-+——-+——————-+————+
    | id | phone | ua | day |
    +—-+——-+——————-+————+
    | 1 | 2222 | SonyEricssonK310c | 2007-12-19 |
    | 2 | 2222 | SonyEricssonK750c | 2007-12-19 |
    | 3 | 2222 | MAUI WAP Browser | 2007-12-19 |
    | 4 | 2222 | Nokia3108 | 2007-12-19 |
    | 5 | 2222 | LENOVO-I750 | 2007-12-19 |
    | 6 | 2222 | BIRD_D636 | 2007-12-19 |
    | 7 | 2222 | SonyEricssonS500c | 2007-12-19 |
    | 8 | 2222 | SAMSUNG-SGH-E258 | 2007-12-19 |
    | 9 | 2222 | NokiaN73-1 | 2007-12-19 |
    | 10 | 2222 | Nokia2610 | 2007-12-19 |
    +—-+——-+——————-+————+
    10 rows in set (2 min 58.56 sec) client3:
    mysql> update gz_phone set phone=’55555′where id=1;
    Query OK, 1 row affected (3 min 50.16 sec)
    Rows matched: 1 Changed: 1 Warnings: 0

    说明当数据表有一个写锁时,其它进程的读写操作都需等待读锁释放后才会执行。

    3、并发插入

    原则上数据表有一个读锁时,其它进程无法对此表进行更新操作,但在一定条件下,MyISAM表也支持查询和插入操作的并发进行。

    MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。

    a、当concurrent_insert设置为0时,不允许并发插入。
    b、当concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。
    c、当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

    4、MyISAM的锁调度

    由于MySQL认为写请求一般比读请求要重要,所以如果有读写请求同时进行的话,MYSQL将会优先执行写操作。这样MyISAM表在进行大量的更新操作时(特别是更新的字段中存在索引的情况下),会造成查询操作很难获得读锁,从而导致查询阻塞。

    我们可以通过一些设置来调节MyISAM的调度行为:

    a、通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。
    b、通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。
    c、通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。

    上面3种方法都是要么更新优先,要么查询优先的方法。这里要说明的就是,不要盲目的给mysql设置为读优先,因为一些需要长时间运行的查询操作,也会使写进程“饿死”。只有根据你的实际情况,来决定设置哪种操作优先。这些方法还是没有从根本上同时解决查询和更新的问题。

    在一个有大数据量高并发表的mysql里,我们还可采用另一种策略来进行优化,那就是通过mysql主从(读写)分离来实现负载均衡,这样可避免优先哪一种操作从而可能导致另一种操作的堵塞。下面将用一个篇幅来说明mysql的读写分离技术

    展开全文
  • MySql锁表

    2019-09-26 17:13:04
    有的人说mysql的select会锁表,有的人说mysql的查询不会锁表。 其他他们都对,没有,但是很片面。 其实对于mysql的select是否会锁表,这个完全取决于表采用的是什么存储引擎。 这里我就拿大家最熟悉的存...

    部分一:mysql select是否会锁表 转载自:https://blog.csdn.net/wscrf/article/details/78749744

    有的人说mysql的 select 会锁表 ,有的人说 mysql 的查询不会锁表 。
    其他他们都对,没有 ,但是很片面。

    其实对于mysql的select 是否会锁表 ,这个完全取决于表采用的是什么存储引擎。

    这里我就拿大家最熟悉的存储引擎INNODB 和MYISAM 来说明这个问题。

    对于myisam的表select 是会锁定表的 ,会导致其他操作挂起,处于等待状态。
    对于innodb的表select 是不会锁表的。其实这里使用到了快照。快照这里不作讨论。


    下面是是我的佐证:


     会话一:
     select SQL_NO_CACHE * from tmp002
     表 tmp002  有5618288 数据 存储引擎时INNODB  ,全部查询出来大约需要5min左右  

     会话二:
     update tmp002
     set num=6
     where MreasonId in ('700098','301001' ) limit 10000

     我们首先 执行以下 回话一的 语句 。 再执行回话二。


     我们会发现会话2很快就执行了 
     update tmp002
     set num=6
     where MreasonId in ('700098','301001' ) limit 10000

     

    受影响的行: 0
    时间: 0.120s

     

     在会话三种执行下 show full PROCESSLIST 。
     没有发现任何锁定的现象。


    修改表存储引擎:
     alter table tmp002 ENGINE=MYISAM
    受影响的行: 5618288
    时间: 17.510s 


    同样是上面的例子


    会话一:
     select SQL_NO_CACHE * from tmp002
     表 tmp002  有5618288 数据 存储引擎时INNODB  ,全部查询出来大约需要5min左右  
     会话二:
     update tmp002
     set num=6
     where MreasonId in ('700098','301001' ) limit 10000

     我们首先 执行以下 会话一的 语句 。 再执行回话二。
     我们先会话一直处于执行状态 ,没有返回任何信息 。

    在会话三种执行下 show full PROCESSLIST 。
    13564441 root 192.168.53.41:53312 tempDB Query 2 Locked  update tmp002 set num=6 where MreasonId in ('700098','301001' ) limit 10000
    13564671 root 192.168.53.41:53736 tempDB Query 4 Writing to net select SQL_NO_CACHE * from tmp002

    会话13564441状态为 Locked ,等待锁的释放 。

    综上所述,可以得到下面的结果。
    对于myisam的表select 是会锁定表的 ,会导致其他操作挂起,处于等待状态。
    对于innodb的表select 是不会锁表的。其实这里使用到了快照。快照这里不作讨论。

    部分二:锁表了怎么办?转载自:https://www.cnblogs.com/chxl800/p/10498511.html

    1、查询是否锁表
    show OPEN TABLES where In_use > 0;
    
    2、查询进程
    show processlist
    查询到相对应的进程===然后 kill id
    
    补充:
    查看正在锁的事务
    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 
    
    查看等待锁的事务
    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
    
     
    
    SELECT * from information_schema.INNODB_TRX
    kill trx_mysql_thread_id
    展开全文
  • mysql 锁表

    2019-03-12 11:29:27
    1.通常sql造成的锁表 查进程show processlist; 找到db被锁的表名 找到state是waiting的id 杀进程 killid 2.innodb事务书写不规范造成的锁表 SELECT * FROM information_schema.INNODB_TRX; 根据trx_mysql_...

     

    1.通常sql造成的锁表

    查进程show processlist;

    找到db被锁的表名

    找到state是waiting的id

    杀进程 kill id

    2.innodb事务书写不规范造成的锁表

    SELECT * FROM information_schema.INNODB_TRX;

    根据trx_mysql_threading_id,kill掉被锁住的线程:kill trx_mysql_threading_id

    展开全文
  • MYSQL 锁表

    千次阅读 2018-03-25 15:31:47
    锁表: 锁单个表:LOCK TABLES tablename read/write 锁多个表:LOCK TABLES tablename1 read/write,tablename2 read/write 当read时, 当前会话:可以查询,更新会报错; 其他会话:可以查询,更新会...

    锁表:

    锁单个表:LOCK TABLES tablename read/write

    锁多个表:LOCK TABLES tablename1 read/write,tablename2 read/write

    当read时,

    当前会话:可以查询,更新会报错;

    其他会话:可以查询,更新会进入等待;

    当wirte时,

    当前会话:可以读写;

    其他会话:读写会进入等待状态;

    当前会话锁定了表A,没有锁表B,当前会话操作表B时,会报错。必须将表B也锁定才可以操作表B

    解锁:unlock table,当前会话被锁的表全部解锁

    查询是否有被锁定的表:show OPEN TABLES where In_use >= 1;

    展开全文
  • MySQL锁表

    2016-09-18 14:16:33
    1、锁:计算机协调多个进程或线程并发访问某一资源的机制​2、MySQL锁:不同的存储引擎支持不同的锁机制​1)页级锁:引擎DBD(也支持级锁)​开销和枷锁时间结余表锁和行锁间;会出现死锁;锁定力度介于表锁和...
  • MySQL 锁表

    2019-04-13 20:29:19
    今天不知道为什么突然数据库就卡住不动了,刚开始我以为是电脑卡机,重启,打开项目进行运行,发现报SQL错误,上网一查询,原来是引起的! 网上的解释1.: 当多个用户并发地存取数据时,在数据库中就会产生多个事务...
  • mySQL锁表

    2016-06-12 20:18:11
    MySQL有三种的级别:页级、级、行级。 MyISAM和MEMORY存储引擎采用的是(table-level locking);BDB存储引擎采用的是页面(page-level locking),但也支持;InnoDB存储引擎既支持行级
  • MySql 锁表

    2013-11-05 17:52:08
    如果一个被以一个读和一个写锁定,将写放在读之前。 一次只锁定一个,只到线程得到所有的锁定。 这个方案是为了确保,锁定死锁释放。 对于这个模式你仍然有些其它事情需要知道: 如果你对一...
  • mysql锁表、解锁

    千次阅读 2019-05-07 16:48:17
    查看mysql锁表的情况 >select * from information_schema.innodb_trx; >show processlist 杀掉查询结果中锁表的trx_mysql_thread_id,其中trx_mysql_thread_id对应 show processlist 的Id >...
  • 主要介绍了MYSQL锁表问题的解决方法,结合实例形式分析了MySQL锁表问题的常见情况与相应解决方法,需要的朋友可以参考下
  • Mysql 锁表查询

    2020-02-07 21:15:15
    Mysql 锁表查询
  • mysql锁表查询和解锁操作

    万次阅读 2018-08-11 16:42:09
    mysql锁表查询和解锁操作 1、在做数据库操作时,有时会因为自己的粗心或者程序设计上的缺陷导致锁表,在mysql中查看锁表和解锁的步骤如下: //1.查看当前数据库锁表的情况 SELECT * FROM information_schema....
  • MySQL锁表解决方法

    2021-01-09 17:05:06
    MySQL锁表解决方法
  • mysql 锁表查询及解锁

    2020-07-20 18:09:02
    mysql 锁表查询及解锁 show OPEN TABLES where In_use > 0; show processlist; kill 142091
  • MYSQL锁表问题解决

    2020-10-13 16:24:33
    MYSQL锁表问题解决
  • MYsql 锁表解决办法

    万次阅读 2018-03-15 13:28:08
    MySQL锁表解决方法一、我的处理过程1、查进程,主要是查找被锁表的那个进程的IDSHOW PROCESSLIST;2、kill掉锁表的进程IDKILL 10866;//后面的数字即时进程的ID网上找了些资料,了解了一下,先分享一下:二、mysql的锁...
  • Mysql锁表问题解决过程
  • mysql锁表解表

    2017-11-23 15:48:14
    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在...如果是产品环境的核心出现了这样的等待队列,就会造成灾难性的后果。
  • mysql 锁表解决方法

    2018-04-19 17:20:26
    mysql 锁表解决方法 1、查进程,主要是查找被锁表的那个进程的IDSHOW PROCESSLIST;2、kill掉锁表的进程IDKILL 10866;//后面的数字即时进程的ID转自:...
  • MySQL锁表解决方法(转) xxmzhumeng 2014-07-16 18:32:47 82945 收藏 9 MySQL锁表解决方法 一、我的处理过程 1、查进程,主要是查找被锁表的那个进程的ID SHOW PROCESSLIST; 2、kill掉锁表的进程ID KILL 10866;//...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,260
精华内容 4,104
关键字:

mysql锁表

mysql 订阅