web-dev-qa-db-ja.com

MySQLレプリケーションを有効にした後、キャッシュをクリアするとデッドロックが発生する

最近、レプリケーション用に本番MySQLサーバーをセットアップしました。これを行うには、innodb_flush_log_at_trx_commitsync_binlogを有効にし、bind-addressを設定します。米国の反対側の隅にあるスレーブサーバーがマスターを正常に複製しています。

キャッシュがクリアされるたびに(手動で、モジュールが有効化/無効化されたためなど)、サイトが約5分間応答しなくなることを除いて、問題はありません。次のエラーが報告されます(ただし、クエリが変更されることもありますが、エラーは同じです。これは、これを示す最も一般的なクエリです)。

PDOException:SQLSTATE [40001]:シリアル化の失敗:1213ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください:DELETE FROM {セマフォ} WHERE(name =:db_condition_placeholder_0)AND(value =:db_condition_placeholder_1)AND(expire <=:db_condition_placeholder_2);配列([:db_condition_placeholder_0] => variable_init [:db_condition_placeholder_1] => 300377225537241be5ddc00.97685038 [:db_condition_placeholder_2] => 1399996863.3809)in lock_may_be_available()(/usr/local/www/r/example.com/web/includeの181行目) /lock.inc)。

キャッシュをクリアするのに時間がかかります。それが最大で10秒かかる前に。現在、5分以上かかります。他の場所でこのエラーに遭遇したことがありますが(非常にまれですが、update.phpを使用した1時間のバッチ処理中にランダムに他の場所で発生します)、更新をプッシュしてキャッシュをクリアする必要がある場合、本当に問題が発生しています。

現時点では、スレーブサーバーは実際にはWebサイトにサービスを提供していません。それは単なるバックアップです。

mysql  Ver 14.14 Distrib 5.5.14, for Linux (x86_64) using readline 5.1
PHP 5.3.8 (cli) (built: Aug 31 2011 16:27:31)
Drupal 7.8

そしてマスターサーバーのmy.cnf:

[mysqld]
datadir = /usr/local/mysql/db
socket  = /usr/local/mysql/mysql.sock
user    = mysql

old_passwords      = 1
key_buffer         = 16M
max_allowed_packet = 16M
thread_stack       = 128K
max_connections    = 1024

log_slow_queries     = 1
slow_query_log_file  = /usr/local/mysql/log/slow.log
long_query_time      = 10
ft_min_Word_len      = 2
skip-external-locking

# Query cache configuration
query-cache-type  = 1
query_cache_limit = 2M
query_cache_size  = 16M
thread-cache-size = 8

# InnoDB Buffer Pool
innodb_buffer_pool_size=8G

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links                 = 0
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table
default-storage-engine=InnoDB

# For replication
server-id        = 100
log_bin          = /usr/local/mysql/log/mysql-bin.log
sync_binlog      = 1
expire_logs_days = 10
max_binlog_size  = 100M
bind-address     = example

[mysqld_safe]
socket     = /usr/local/mysql/mysql.sock
log-error  = /var/log/mysqld.log
pid-file   = /var/run/mysqld/mysqld.pid

[client]
socket = /usr/local/mysql/mysql.sock

私の検索では、 inndb_locks_unsafe_for_binlog を有効にすることを提案している人もいますが、名前自体はsync_binlogと一緒に使用するべきではないようです。

1
donut

ガイド に続く mikeytown2彼の答え にリンクされ、次のクエリでsemaphoreテーブルを変更すると、デッドロックが修正されました経験しています。

ALTER TABLE semaphore ENGINE = MEMORY;
ALTER TABLE semaphore DROP PRIMARY KEY;
ALTER TABLE semaphore ADD PRIMARY KEY (name, value) USING BTREE;
ALTER TABLE semaphore ADD UNIQUE name (name) USING BTREE;
ALTER TABLE semaphore DROP INDEX value;
ALTER TABLE semaphore ADD INDEX value (value) USING BTREE;
ALTER TABLE semaphore DROP INDEX expire;
ALTER TABLE semaphore ADD INDEX expire (expire) USING BTREE;

しかし、キャッシュをクリアするのに5分ほどかかり、サイトが応答しなくなりました。次に、Drupalを7.8から7.28に更新し、すべてのモジュール(ほとんどは2年以上遅れていました)を追加しました。キャッシュのクリアに約15〜30秒かかります。

0
donut

これに従ってください、そしてあなたは行ってもいいはずです: D7のMySQLデッドロックの修正

2
mikeytown2