8.11 Optimizing Locking Operations 优化锁操作
8.11.1 Internal Locking Methods
8.11.2 Table Locking Issues
8.11.3 Concurrent Inserts
8.11.4 Metadata Locking
8.11.5 External Locking
MySQL 管理表的内容 使用locking:
1.内部锁 是MySQL server本身来管理连接,多个threads的争用。 这种类型的锁是内部锁,
因为它是完全由服务器进行的, 没有涉及其他程序。See Section 8.11.1, “Internal Locking Methods”.
2.外部锁发生在当服务器和程序lock MyISAM表文件来协调它们自己的程序可以访问表
8.11.1 Internal Locking Methods 内部锁方式
这个章节讨论 内部锁,即, MySQL 本身执行锁定来管理多个会话的表争用。
这种类型的锁定是内部的,因为它完全是服务器进行的,并且没有涉及其他程序。
Row-Level Locking
MySQL 使用row-level locking 对于InnoDB 表来支持多个会话的同时写访问,
使它们适用于多个用户,高并发,和OLTP 应用。
为了避免死锁,当执行多个并发的写操作在一个单独的InnoDB 表,
获得需要的锁在事务的开始通过执行一个SELECT … FOR UPDATE 豫剧对于每个期望被修改的每个组的结果集,
即使如果是DML 语句在交易后。如果交易修改了或者锁定多个表,执行适当的语句在相同的顺序在每个事务。
Deadlocks 影响性能相比表现一个严重的错误,因为InnoDB 自动检查死锁条件,回滚其中受影响的一个事务。
行锁的优点:
1.当不同的会话访问不同的记录
2.更少的改变对于回滚
3.可能需要锁定一条记录很长的时间
Table-Level Locking 表级锁
MySQL 使用表级锁用于MyISAM, MEMORY, and MERGE tables, 允许只有一个事务在同一时间来更新那些表,
使你更适合用于只读,以读为主,或单用户应用程序。
这些存储引擎避免死锁通过总是请求所需要的锁一次 在查询开始,总是锁住表以相同的顺序。
MySQL grants table write locks as follows:
1.如果这里没有locks 在表上, 放一个写锁在上面
2.否则,放一个lock请求在写锁队列里
MySQL grants table read locks as follows:
1.如果没有写锁在表上,放一个read lock 在上面
2.否则, 把lock 请求放在read lock 队列里
表更新给更好的优先级相比表检索,因此,当一个锁被释放时,lock变的可用来请求在写锁队列,
请求在读锁队列。
这个确保update到一个表不是急需的 ,即使这里有一个很大的查询活动。
然而, 如果你在一个表上有很多更新, SELECT 语句会等待直到没有更多的更新。
改变读写的优先级,see Section 8.11.2, “Table Locking Issues”.
你可以分析表lock 争用在你的系统通过检查Table_locks_immediate and Table_locks_waited状态变量,
mysql> SHOW STATUS LIKE ‘Table%’;
+———————–+———+
| Variable_name | Value |
+———————–+———+
| Table_locks_immediate | 1151552 |
| Table_locks_waited | 15324 |
+———————–+———+
MyISAM 存储引擎支持并发的插入来降低竞争在读和写在给定的表,
如果一个MyISAM 表没有空闲的快在数据文件的中部,记录总是被插入到数据文件的尾部。
在这种情况下,你可以自由的混合INSERT和SELECT 语句对于一个MyISAM 表没有lock
那就是,你可以插入记录到一个MyISAM 表在同一时间 其他客户端可以读。
在该表中,记录被删除或者更新在表里导致漏洞,如果有漏洞,并发的INSERT 是被禁用的。
如果你需要一个表锁 ,明确的使用LOCK TABLES,你可以请求一个READ LOCAL lock 相比一个READ lock 来
让其他会话执行并发的插入当你的表被锁定.
执行很多的插入和查询操作在表 real_table上, 当并发的插入是不可能的,你可以插入表到一个临时表
temp_table ,update rel table 用temporary table里的记录更新 这个可以用以下代码:
mysql> LOCK TABLES real_table WRITE, temp_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM temp_table;
mysql> DELETE FROM temp_table;
mysql> UNLOCK TABLES;