mysql innodb的行鎖(6) --不安全語句加鎖
一般情況下select 使用mvcc的技術,是不加行鎖的,但是對於insert ... select , create table .. select 等不安全語句,會自動對源表加共享鎖
當然是否加鎖還受到下面引數控制, 因為這個加鎖不是隔離級別的原因,而是為了複製安全。
root@sakila 11:03:59>show variables like '%unsafe%';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_locks_unsafe_for_binlog | OFF |
+--------------------------------+-------+
1 row in set (0.00 sec)
會話1:
root@sakila 11:02:28>insert into target select * from tab_no_index;
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
會話2:
root@sakila 11:03:02>update tab_no_index set name=name where name='1';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
*************************************************************************************
如果修改變數,則不會對上面的select 的源表加鎖,但是在statement 的複製模式下,複製會出現問題
set global innodb_locks_unsafe_for_binlog=1;
use `sakila`/*!*/;
SET TIMESTAMP=1489331894/*!*/;
update tab_no_index set name='8' where name='1'
/*!*/;
# at 328
#170312 23:18:32 server id 2552763370 end_log_pos 359 CRC32 0xebeef64e Xid = 20
COMMIT/*!*/;
# at 359
#170312 23:17:41 server id 2552763370 end_log_pos 442 CRC32 0xae75ad5e Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1489331861/*!*/;
BEGIN
/*!*/;
# at 442
#170312 23:17:41 server id 2552763370 end_log_pos 580 CRC32 0x3368f120 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1489331861/*!*/;
insert into target select * from tab_no_index where name='1'
/*!*/;
# at 580
#170312 23:18:48 server id 2552763370 end_log_pos 611 CRC32 0x1b39b7d7 Xid = 19
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
綜述:
避免上鎖又不影響複製的最優方式是:
innodb_locks_unsafe_for_binlog =1 (允許不安全的語句)
同時把
binlog_format=row (避免不安全的語句)
當然是否加鎖還受到下面引數控制, 因為這個加鎖不是隔離級別的原因,而是為了複製安全。
root@sakila 11:03:59>show variables like '%unsafe%';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_locks_unsafe_for_binlog | OFF |
+--------------------------------+-------+
1 row in set (0.00 sec)
會話1:
root@sakila 11:02:28>insert into target select * from tab_no_index;
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
root@sakila 11:03:02>update tab_no_index set name=name where name='1';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
如果修改變數,則不會對上面的select 的源表加鎖,但是在statement 的複製模式下,複製會出現問題
set global innodb_locks_unsafe_for_binlog=1;
mysqlbinlog mysql-bin.000039 | more 結果分析如下: 因為記錄bin log是按提交順序記錄的,所以在執行insert ... select 語句前,已經執行了update了,而主庫是先執行insert.. select ,再執行update. 所以兩者的結果是不一樣的,所以是不安全的。
#170312 23:18:14 server id 2552763370 end_log_pos 328 CRC32 0x6262bb7c Query thread_id=2 exec_time=0 error_code=0use `sakila`/*!*/;
SET TIMESTAMP=1489331894/*!*/;
update tab_no_index set name='8' where name='1'
/*!*/;
# at 328
#170312 23:18:32 server id 2552763370 end_log_pos 359 CRC32 0xebeef64e Xid = 20
COMMIT/*!*/;
# at 359
#170312 23:17:41 server id 2552763370 end_log_pos 442 CRC32 0xae75ad5e Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1489331861/*!*/;
BEGIN
/*!*/;
# at 442
#170312 23:17:41 server id 2552763370 end_log_pos 580 CRC32 0x3368f120 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1489331861/*!*/;
insert into target select * from tab_no_index where name='1'
/*!*/;
# at 580
#170312 23:18:48 server id 2552763370 end_log_pos 611 CRC32 0x1b39b7d7 Xid = 19
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
綜述:
避免上鎖又不影響複製的最優方式是:
innodb_locks_unsafe_for_binlog =1 (允許不安全的語句)
同時把
binlog_format=row (避免不安全的語句)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/674865/viewspace-2135289/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql innodb的行鎖MySql
- 超全面 MySQL 語句加鎖分析(上篇)MySql
- 超全面 MySQL 語句加鎖分析(中篇)MySql
- 超全面 MySQL 語句加鎖分析(下篇)MySql
- MySQL鎖:03.InnoDB行鎖MySql
- MySQL鎖:InnoDB行鎖需要避免的坑MySql
- mysql innodb的行鎖(2)MySql
- mysql innodb的行鎖(3)MySql
- mysql innodb的行鎖(4)MySql
- InnoDB事務鎖之行鎖-insert加鎖-隱式鎖加鎖原理
- MySQL 5.5 InnoDB表鎖行鎖測試MySql
- MySQL鎖(四)行鎖的加鎖規則和案例MySql
- mysql innodb的行鎖(5) --next-Key 鎖MySql
- InnoDB事務鎖之行鎖-聚集索引加鎖流程索引
- 一條簡單的更新語句,MySQL是如何加鎖的?MySql
- Mysql研磨之InnoDB行鎖模式MySql模式
- InnoDB 事務加鎖分析
- Mysql加鎖過程詳解(9)-innodb下的記錄鎖,間隙鎖,next-key鎖MySql
- MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解MySql
- InnoDB事務鎖之行鎖-delete流程update階段加鎖delete
- MySQL InnoDB行鎖優化建議MySql優化
- 詳解 MySql InnoDB 中的三種行鎖(記錄鎖、間隙鎖與臨鍵鎖)MySql
- InnoDB事務鎖之行鎖-insert加鎖原理圖-聚集索引索引
- oracle 鎖表、解鎖的語句Oracle
- Mysql innodb引擎(二)鎖MySql
- mysql加鎖讀MySql
- InnoDB事務鎖之行鎖-insert二級索引加鎖原理圖索引
- Mysql加鎖過程詳解(8)-理解innodb的鎖(record,gap,Next-Key lock)MySql
- MySQL InnoDB 中的鎖機制MySql
- InnoDB常用鎖總結(行鎖、間隙鎖、臨鍵鎖、表鎖)
- Mysql在InnoDB引擎下索引失效行級鎖變表鎖案例MySql索引
- mysql事務和鎖InnoDBMySql
- mysql innodb間隙鎖示例MySql
- 【MYSQL】一個關於Innodb儲存引擎表的加鎖問題MySql儲存引擎
- InnoDB行鎖實現方式
- MySQL:Innodb 一個死鎖案例MySql
- MySQL 5.7 查詢InnoDB鎖表MySql
- 【MySQL】InnoDB鎖機制之一MySql