3

状況:

Percona MySQL 5.6.32-78.1 で GTID を使用したマスター - マスター - レプリケーションがあります。サーバーには、約 10 のデータベースがあり、設定しましslave_parallel_workers=5た。1 台のサーバーがフロントエンドの処理に使用され、もう 1 台がバックエンドに使用されます。週に 2 ~ 3 回、バックエンド サーバーのレプリケーションがエラーで停止する

2016-10-25 10:00:01 165238 [Warning] Slave SQL: Worker 4 failed executing transaction '0e7b97a8-a689-11e5-8b79-901b0e8b0f53:22506262' at master log mysql-bin.011888, end_log_pos 9306420; Could not execute Update_rows event on table shop.sessions; Deadlock found when trying to get lock; try restarting transaction, Error_code: 1213; handler error HA_ERR_LOCK_DEADLOCK; the event's master log mysql-bin.011888, end_log_pos 9306420, Error_code: 1213 2016-10-25 10:00:01 165238 [ERROR] Slave SQL: ... The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state. A restart should restore consistency automatically, although using non-transactional storage for data or info tables or DDL queries could lead to problems. In such cases you have to examine your data (see documentation for details). Error_code: 1756 2016-10-25 10:00:01 165238 [Note] Error reading relay log event: slave SQL thread was killed

その理由は何ですか?クロスデータベース DML ステートメントはありません。MTS を使用すると、データベースごとに 1 つのスレッドのみが使用されると思いました (MTS の利点は、複数のデータベース間で並列レプリケーションを使用することです)。応答がデッドロックで中断するのはなぜですか?

編集 2016-10-28:

テーブルのスキーマは次のようになります

CREATE TABLE `sessions` (
  `id` int(11) NOT NULL,
  `session_id` char(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `crypt_iv` blob NOT NULL,
  `data` mediumblob NOT NULL,
  `user_id` int(11) NOT NULL,
  `last_refresh` datetime NOT NULL,
  `timeout` datetime NOT NULL,
  `closed` tinyint(4) NOT NULL,
  `inserted` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `sessions`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `session_id` (`session_id`),
  ADD KEY `user_id` (`user_id`),
  ADD KEY `timeout` (`timeout`);
ALTER TABLE `sessions` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

現時点では、このエラーはバックエンド側でのみ発生しており、フロントエンド サーバーでは発生していません。現時点では、バイナリ ログが削除されているため、正確なステートメントを貼り付けることができません。ただし、この GTID トランザクション内の唯一のステートメントは、テーブルに対する行ベースの UPDATE です。

4

1 に答える 1

1

すべてのセッションはフロントエンド サーバーで作成されると思います。バックエンド サーバーにセッション クリーンアップ ジョブが存在する可能性はありますか? したがって、両方のマシンからテーブルに書き込みがあります。セッションとして書き込み負荷の高いテーブルがある場合は、この種のデッドロックを回避するために、1 つのマシンにのみ書き込む必要があります。

実際には、1 つのマスターがダウンした場合のフェールオーバーの場合を除き、すべての書き込みは常に 1 つのマシンでのみ行う必要があります。

フェールオーバーが自動的に処理され、クライアントに対して透過的になるように、haproxy とヘルス チェックを備えた優れたセットアップがあります。

于 2016-10-29T13:18:42.527 に答える