2011-10-27 40 views
1

我有一個標準的單向主從設置。 表中有MyIsam存儲引擎。這個查詢如何破壞我的mysql複製?

的版本是:

主 Server版本:5.1.41-3ubuntu12.10日誌 協議版本:10

1日從: 服務器版本:5.1.41-3ubuntu12.10 協議版本:10

第二從屬: 服務器版本:5.1.49-1ubuntu8.1 協議版本:10

我已經將專用複製用戶旁邊的所有用戶設置爲只能在從服務器上讀取。

下面的語句,在主執行,得到不正確複製:

$insert = "INSERT INTO search_affiliate_product 
(film_id, ext_id, affiliate_id, `status`, url, created_at) 
SELECT film_id, LPAD(imdb, 7, '0'), $affiliate_id, 5, CONCAT('http://www.imdb.com/title/tt', LPAD(imdb, 7, '0'),'/'), NOW() FROM search_film_entity 
WHERE film_id NOT IN (SELECT film_id FROM search_affiliate_product WHERE affiliate_id = $affiliate_id) 
AND status IN (5, 9) 
AND release_year BETWEEN 0 AND $year 
AND imdb > 0"; 

奴隸得到這個錯誤:

Error 'Duplicate entry '271769' for key 'PRIMARY'' on query. Default database:  'flimmit_search_14'. Query: 'INSERT INTO `search_affiliate_product` (`affiliate_id`,  `ext_id`, `url`, `status`, `film_id`, `created_at`, `updated_at`) VALUES ('16', '1991/JohnnyStecchino', 'http://www.cineman.ch/movie/1991/JohnnyStecchino/review.html', '5', '102164', '2011-10-26 02:30:05', '2011-10-26 02:30:05')' 

我也做了一些其他意見:

  • 語句在bin日誌(中繼日誌和主日誌)上「按原樣」傳輸,因此exp不包含插入的合法數據,但使用select和subselect的整個語句在從站上執行,並依賴於本地數據。

  • 如果我查看主表和主表,並通過主鍵進行排序,我可以看到上述語句在兩臺服務器上生成的一系列插入。之前和之後的行同步。該語句生成的範圍內的很多行也是相同的。但也有差異。

我認爲這個問題可能是因爲併發sql事務。因此插入過程會干擾其他插入,因此這些值會混淆在一起,因爲日誌在過程中處理,因此從站上的這種情況不會發生。

我還注意到,在插入過程中,一些ID似乎插入了不插入到另一個服務器上,並且插入了一些重複項(重複項在字段ext_id中由來自其他表,這是獨一無二的......

我真的被困在這裏。

任何建議?我真的想明白爲什麼會這樣。

我想到了選擇的所有ID,使應用程序中的單個插入語句或在執行它之前鎖定表認爲這可以解決它,但我真的想了解錯誤。

下一個奇怪的是,第二個奴隸似乎運行良好!只有第一個奴隸遇到問題。我只是不明白這一點。

回答

2

這種複製只能根據可靠做的InnoDB使用以下設置到位在客戶端上

[mysqld] 
innodb_flush_log_at_trx_commit=1 
sync_binlog=1 
1

我會說search_affiliate_product表中(猜測)ID列的AUTO_INCREMENT計數器已經不合適。具體而言,我懷疑第一個從設備上的AUTO_INCREMENT值在某種程度上超過了等價的主設備值。我猜想從屬服務器2上的值一直保持在這個步驟,這就是爲什麼錯誤不會發生在那裏。

如果運行在掌握以下,服務器1和服務器2,你應該能夠看到這是否是真還是假:

select auto_increment 
from information_schema.tables 
where table_name = 'search_affiliate_product'; 

其中一個原因可能出現這種情況的原因是插入到數據search_affiliate_product直接在從屬服務器1上,即不通過主設備,因此遞增AUTO_INCREMENT值並使其在主設備之前。

這樣做的一個簡單的解決方法是使用擺脫從屬服務器1最大ID:

select max(id) from search_affiliate_product; 

比方說,你得到的123456值上加100,它的好運氣,然後更改AUTO_INCREMENT值的主要search_affiliate_product表:

alter table search_affiliate_product auto_increment = 123556; 

然後嘗試再次運行插入。

如果情況並非如此,那麼我猜這是回到了繪圖板!