2つのmysql mysqlスレーブサーバーがあります。 DBバージョンは次のとおりです。
mysql> show variables like '%version%';
+-------------------------+-----------------------------------------------------+
| Variable_name | Value |
+-------------------------+-----------------------------------------------------+
| innodb_version | 1.1.8-rel29.4 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.29-29.4-log |
| version_comment | Percona Server (GPL), Release rel29.4, Revision 401 |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+-----------------------------------------------------+
7 rows in set (0.00 sec)
開発者はマスターで大きなテーブルを再構築する必要があり、その後スレーブのステータスは次のように表示されます。
show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Queueing master event to the relay log
Master_Host: 10.140.10.31
Master_User: replicator
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000100
Read_Master_Log_Pos: 246814935
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 163153081
Relay_Master_Log_File: mysql-bin.000100
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: temp
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 244925740
Relay_Log_Space: 165042426
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 10
1 row in set (0.01 sec)
Seconds_Behind_Master: 0
値が0から短期間に多数に変化し、その後再び0に戻ります。マスターDBの変更がスレーブにまだ書き込まれていないことを確認しました。
スレーブのDISKアクティビティを確認しましたが、DISKの使用率はまだ非常に高く、リレーログに書き込んでいることを示しています。
# iostat -dx 1
Linux 2.6.32-279.19.1.el6.centos.plus.x86_64 (hmg-slave-hoteldata2) 09/04/2014 _x86_64_ (4 CPU)
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.01 8.99 0.49 9.65 23.04 213.78 23.34 0.05 4.45 2.28 2.31
dm-0 0.00 0.00 0.01 0.01 0.04 0.05 8.00 0.00 23.31 1.11 0.00
dm-1 0.00 0.00 0.50 18.64 23.00 213.74 12.36 0.18 9.33 1.21 2.31
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 321.00 0.00 337.00 0.00 5264.00 15.62 0.87 2.59 2.59 87.20
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
dm-1 0.00 0.00 0.00 658.00 0.00 5264.00 8.00 1.22 1.86 1.32 87.10
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 315.00 0.00 345.00 0.00 5280.00 15.30 0.87 2.50 2.50 86.40
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
dm-1 0.00 0.00 0.00 660.00 0.00 5280.00 8.00 1.27 1.92 1.31 86.40
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 324.00 0.00 345.00 0.00 5352.00 15.51 0.86 2.50 2.50 86.10
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
dm-1 0.00 0.00 0.00 669.00 0.00 5352.00 8.00 1.20 1.80 1.29 86.10
テーブルを再構築するために実行されたクエリは次のとおりです。
case 'TWN':
$query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source, ValidSize)
SELECT hmid, Caption, MainURL, Width, Height, PopOutURL, ThumbnailURL, DefaultImage, 'TWN', 'Y'
FROM FeedHotels.LondonTownImages
INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='TWN'
WHERE HotelID IN ('" . implode("','", $hotelIDs) . "')";
break;
case 'EXP':
case 'XPP':
$query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source)
SELECT hmid, Caption, URL, Width, Height, URL, ThumbnailURL, `Default`, 'EXP'
FROM FeedHotels.ExpediaImages
INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='" . $feed->id . "'
WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
break;
case 'ORB':
$query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, URL, PopOutURL, ThumbnailURL, Source)
SELECT hmid, URL, URL, URL, 'ORB'
FROM FeedHotels.OrbitzImages
INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='ORB'
WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
break;
case 'HRS':
$query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source, ValidSize)
SELECT hmid, Location, URL, Width, Height, URL, URL, IF(`Default`='Y', 1, 0),'HRS','Y'
FROM FeedHotels.HRSImages
INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='HRS'
WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
break;
}
これを引き起こしている原因と解決方法を知りたいと思います。何か助けは?
大きなテーブルがLOAD DATA INFILE
を使用してマスターにリロードされた場合、次のようになります。
LOAD DATA INFILE
を実行する必要があります。このプロセスについては、以前にDBA StackExchangeで説明しました
Jan 22, 2012
: MySqlシェルコマンドはスレーブに複製されませんApr 18, 2013
: LOAD DATA INFILEを使用してmysqlにデータをロードし、レプリケーションは安全ですか?May 04, 2014
: MySQL 5.6が誤った「second_behind_master」を表示しているMySQLレプリケーションでこのプロセスを完了する必要があります。
リレーログが増大して大量の書き込みI/Oが発生する理由を明らかにする可能性のある実用的な理論があり、Seconds_Behind_Masterはまだ0です。
Binlog_formatがROWまたはMIXEDに設定されている場合、SELECTを構成するすべての行がLOAD DATA INFILE
と同じ方法でリレーログに埋め込まれているように見えますが、同じメカニズムではありません。どうして ?
LOAD DATA INFILE
は、CSVファイルをbinlogイベントチャンクに埋め込み、スレーブでCSVファイルを抽出および表示できるようにします。 INSERT ... SELECT
はSELECT
を単一のトランザクションとして扱う必要があります。次に、INSERT
の一部としてすべての行の変更をインポートします。そのためには、マスターとスレーブでbinlog_format ROW
またはMIXED
を使用する必要があります。 binlog_format STATEMENT
を使用している場合、ステートメントはスレーブのリレーログに即座に到達し、Seconds_Behind_Master
はすぐに上昇を開始する必要があります。
MySQL DocumentationがINSERT ... SELECT
について述べているため、これは私の疑いです。
この問題のため、MySQL 5.6.4以降では、INSERT ... SELECT ON DUPLICATE KEY UPDATEおよびINSERT IGNORE ... SELECTステートメントに、ステートメントベースのレプリケーションでは安全でないというフラグが立てられます。この変更により、このようなステートメントは、ステートメントベースモードを使用する場合はログに警告を生成し、MIXEDモードを使用する場合は行ベースのフォーマットを使用してログに記録されます。 (バグ#11758262、バグ#50439)
これらのバグレポートを見ると、これはまったく新しい視点をとります
MySQL 5.5.18がリリースされたとき 、このバグは修正されるはずでした
修正されたバグ
互換性のない変更:レプリケーション:次のリストのステートメントは、ステートメントベースのレプリケーションでは安全でないとマークされています。これは、これらの各ステートメントが、順序を常に決定できるとは限らないSELECTステートメントの結果に依存するためです。 STATEMENTロギングモードを使用すると、これらのステートメントのいずれかについて警告がバイナリログに発行されます。 MIXEDロギングモードを使用する場合、ステートメントは行ベースのフォーマットを使用してログに記録されます。
挿入...選択...重複キー更新時
交換...選択
CREATE TABLE ... IGNORE SELECT
CREATE TABLE ... REPLACE SELECT
無視を挿入...選択
UPDATE IGNOREアップグレードする場合、アプリケーションでのこれらのステートメントの使用に注意する必要があります。SELECTから取得した行を挿入または置換するステートメントは、行ベースを使用してログに記録すると、バイナリログの何倍ものスペースを占める可能性があることに注意してください。ステートメント自体のみがログに記録される場合よりもフォーマット。このようなステートメントによって選択および挿入(または置換)された行の数とサイズに応じて、これらのステートメントのロギングがステートメントベースから行ベースに切り替えられた後のバイナリログのサイズの違いは、潜在的にいくつかの順序になる可能性があります大きさの。 15.1.2.1項「文ベースおよび行ベースのレプリケーションの長所と短所」を参照してください。 (バグ#11758262、バグ#50439)
あなたは言うその部分を見ましたか
a statement that inserts or replaces rows obtained from a SELECT can take up many times as much space in the binary log when logged using row-based format than when only the statement itself is logged. Depending on the number and size of the rows selected and inserted (or replaced) by any such statements, the difference in size of the binary log after the logging of these statements is switched from statement-based to row-based can potentially be several orders of magnitude
これは、5.5.18より前のバージョンのMySQLまたはこのパッチを適用していないバージョンのMySQLを使用しているために発生している可能性があります。
Binlog_format STATEMENTに切り替えると、リレーログの増加、ディスクI/Oの増加、およびSeconds_Behind_Masterがまだ0であるというこの現象は解消されます。それか、MySQLをアップグレードします。
明確にさせてください。個人的には、私は binlog_format ROWが好きではありません。バイナリログとリレーログが肥大化するためです。この投稿では、STATEMENTを使用すると述べました。それは私の好みです。私が言うより正しいのは、マスターとそのスレーブをまったく同じにする binlog_format です。すべてを混ぜ合わせてください。弾丸を噛み、スレーブを最初から再同期する必要があります。