私は現在、MySQL 5.5をAWS RDSとnode.js経由でサーバーに使用しています。私たちには、中央サーバーを使用するいくつかのWebアプリケーションがあり、認証は、oauthのような種類のトークンベースです。ログインすると、認証コードが取得され、アクセスとリフレッシュトークンが交換されます。次に、ある間隔でリフレッシュトークンを使用して、新しいアクセスおよびリフレッシュトークンを取得する。 3つのトークンすべてに有効期限があり、現在は新しいトークンを作成するときに、期限切れのトークンを削除するDELETEクエリがあります。頻繁に実行されるDELETEクエリのパフォーマンスは向上しますか?
DELETE FROM tokens WHERE expires <= NOW() LIMIT 50;
INSERT INTO tokens (type, ...) VALUES ('access', ...);
INSERT INTO tokens (type, ...) VALUES ('refresh', ...);
これらの3つのステートメントは、単一のトランザクションとしてdbサーバーに送信され、個別に照会されません。トークンテーブルには、次のようになります。これは数年のために働いてきたし、時間の99%が素晴らしい作品
CREATE TABLE `tokens` (
`type` varchar(10) NOT NULL,
`system` varchar(45) NOT NULL,
`userid` int(10) NOT NULL,
`key` varchar(45) NOT NULL,
`token` varchar(45) NOT NULL,
`created` datetime NOT NULL,
`expires` datetime NOT NULL,
`scopes` longtext,
PRIMARY KEY (`token`,`expires`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
。無作為に、サーバーがハングアップし、接続やクエリを使用しなくなります。プロセスリストを見ると、ハングしているDELETEクエリがたくさんあります。 WHEREとINSERTが実行しようとしているので、行がロックされているように見えます。 DELETEは最大50行を削除するだけですので、なぜこれがランダムにborkになるのか不思議です。
小さなチャンクを削除し、あまり頻繁ではない(アクセストークンの有効期限を延長する)ように、これを回避するために他の対策を講じています。
有効期限が切れたトークンをクリーンアップする方法はありますか?
返信いただきありがとうございます。主キーを削除し、有効期限を追加しようとしましたが、何らかの意味がある重複したエントリによってキャッチされました。したがって、プライマリとしてトークンが追加され、有効期限が切れるとインデックスが追加されますだから今は 'PRIMARY KEY(トークン)、KEYは期限切れ(期限切れ)'です。私は本当にそれが再び失敗するまで動作するかどうかは分からないでしょう。 –
プライマリが正しいと確信していますか?古いスキーマは異なる期限を持つ重複トークンを許可しますが、これ以上許可しません。古い行動が意図されたのか間違いですか? – Barmar
'PRIMARY KEY(token、expires)'が期限切れを追加していただけで、複合語が作成されているかどうかわからなかったと言われます。それらを分割することは私自身の無知であり、あなたは "可能かもしれない"と言って私を怒らせます。 'PRIMARY KEY(expires、token)'を持つことは、perfヒットやロックを意味するものではありませんか?それらを分割することは役に立たないでしょうか?私は実際にこれをテストする良い方法はないし、それはすべて生産段階にあり、問題はprod dbがランダムに1週間おきにロックするということです。 –