1. 程式人生 > >mysql中 insert …select …帶來的死鎖問題

mysql中 insert …select …帶來的死鎖問題



mysql中 insert …select …帶來的問題


當使用insert...select...進行記錄的插入時,如果select的表是innodb型別的,不論insert的表是什麼型別的表,都會對select的表的紀錄進行鎖定。


對於那些從oracle遷移過來的應用,需要特別的注意,因為oracle並不存在類似的問題,所以在oracle的應用中insert...select...操作非常的常見。例如:有時候會對比較多的紀錄進行統計分析,然後將統計的中間結果插入到另外一個表,這樣的操作因為進行的非常少,所以可能並沒有設定相應的索引。如果遷移到mysql資料庫後不進行相應的調整,那麼在進行這個操作期間,對需要select的表實際上是進行的全表掃描導致的所有記錄的鎖定,將會對應用的其他操作造成非常嚴重的影響。


究其主要原因,是因為mysql在實現複製的機制時和oracle是不同的,如果不進行select表的鎖定,則可能造成從資料庫在恢復期間插入結果集的不同,造成主從資料的不一致。如果不採用主從複製,關閉binlog並不能避免對select紀錄的鎖定,某些文件中提到可以通過設定innodb_locks_unsafe_for_binlog來避免這個現象,當這個引數設定為true的時候,將不會對select的結果集加鎖,但是這樣的設定將可能帶來非常嚴重的隱患。如果使用這個binlog進行從資料庫的恢復,或者進行主資料庫的災難恢復,都將可能和主資料庫的執行效果不同。


因此,我們並不推薦通過設定這個引數來避免insert...select...導致的鎖,如果需要進行可能會掃描大量資料的insert...select操作,我們推薦使用select...into outfile和load data infile的組合來實現,這樣是不會對紀錄進行鎖定的,但是效率會下降