質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

1260閲覧

Laravelから該当のDBプロセスをkillするにはどうしたらいいか?

kodokuna_dancer

総合スコア7

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

1クリップ

投稿2022/10/26 05:36

初めに

都内でソフトウェアエンジニアをしている者です。
業務中に解決しにくい問題にぶつかったので、ここで質問させてください。

前提

私が担当しているあるサービスには検索機能が実装されています。
ただし、検索条件によっては結果が返ってくるまで時間を要するので、ユーザーの任意で検索を中断できるよう「検索キャンセル処理」というものを追加で実装することになりました。

そこでaxiosAbortControllerを利用し実現しようと試みましたが、期待通りにはいきませんでした。
フロントエンドとバックエンド(Laravel)のhttps通信を切ることはできていましたが、DBのプロセスまではkillできていませんでした。
(先輩エンジニアに見てもらいましたが、AbortControllerの使い方には問題がないようです)

実現したいこと

検索キャンセル後、Laravel側から該当のDBプロセスをkillしたいです。
もし、Laravelにそういった機能がない場合、この状況だとどういった解決案が考えられるのでしょうか?
(一つ考えているのは、ジョブキューを利用しあえて一定時間処理の実行を遅らせ、ユーザーがキャンセルするまでの時間を確保する方法です)

補足情報

Laravel 8.83.14
axios 0.22.0
postgreSQL 11.2
node 14.4.0

最後に

色々ググってみても、なかなか該当する情報を得られないでいます。
何かアドバイスございましたら、ご教示いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikukiku

2022/10/27 00:22

DBをプロセスをkillすることで、 DBのデータが壊れない保証はないと思うため 自分だったら、killする選択はしないです。 その他の方法を検討することをお勧めします。
guest

回答1

0

ベストアンサー

やってやれないことはなさそうですが、
セキュリティや動作面での不安は残りますね。

上司・お客さんにもセキュリティの問題がある旨を報告し、
言った言わないの問題を避ける為に念書もらうとかの話になってきます。

なのでオススメはしません。
まずは下記を徹底するべきです。

  • インデックスを張る等して高速な検索を実現する
  • 何個もテーブルを結合しまくるような超重いクエリを1訪問者に使わせる権限与えるな
  • ページネーションを実装する等して時間稼ぎする
  • フロントエンドでは砂時計を回転させる等して待たせる

前提として想定しうる内容はこれですね。
Laravelだろうがなんだろうが、MySQLのrootレベルの権限を持たせたアカウントとでSQL文を発行するだけです。

参考記事: MySQLでクエリをキャンセル - Qiita

show processlistのSQL文を発行すれば一覧が帰ってくるとして、
「Aユーザーが検索して遅いので取り消したいクエリ」を正確に見抜くのが問題ですね。
Bユーザーが「別に遅いけどブラウザ開きっぱなしで待ってよう」としているものを誤って停止させましたという話になるようではとんでもない不具合です。

もし、Laravelにそういった機能がない場合、この状況だとどういった解決案が考えられるのでしょうか?

Laravelは裏でPDOを利用してMySQLとの通信を実現しています。
https://readouble.com/laravel/5.7/ja/database.html

このPDOを使って$conn->query("select * from users");みたいな命令をした瞬間
PHPは待ちぼうけして結果が帰ってくるまでは次の行は実行しません。
なので実行した後にプロセスIDを掴んで、外部に保存するというフローは実現できません。

なのでクエリを投げる前に、クエリビルダで作った実行予定SQLを何らかの方法で取り出しておき、
Redis等のデータベースなんかに「私このユーザーとしてこのSQLを送信しますよ」という情報を覚えさせておき
結果が帰ってきたらRedis上から消すというフローを実装しておきます。

フロント側は別口のAjax/FetchでRedisの登録を見ながら投げられたクエリを察知、
Redisのデータを見ながらshow processlistでプロセスIDを取り出して、
KILL CONNECTION [ID]を発行してプロセスを停止させるといった事は考えられます。


ですが、そんな仕組み必要なんですか?

DBのチューニングはしましたか?
インデックスは張りましたか?
不要なカラムは結果から取り除きましたか?
クエリの実行計画は確認しましたか?
http://nippondanji.blogspot.com/2009/03/mysqlexplain.html
それによりテーブルの正規・非正規の設計を見直しましたか?
ユーザーには時間が掛かる旨の同意を取らせましたか?

そこまで全部やって
なお重い、何分・何時間もかかるなら質問文のような発想に至ったのであればわかります。

しかし、実際MySQLの実行計画すら見てないのでは?
だったら同じ1エンジニアとしてプロセスをKILLする手法を推奨するわけにはいきません。
それはWebサービスの安定性を削ったり、悪用されかねないような機能の実装になります。

極力使わなくて済む方向で考える事を推奨します。
もし質問文の発端が上司・顧客だったならば
「知人に機密情報伏せて軽く相談したら、絶対やめたほうがいいよってアドバイスもらった」
みたいな報告・連絡をしましょう。

投稿2022/10/27 09:43

miyabi-sun

総合スコア21400

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kodokuna_dancer

2022/11/01 02:06

すみません、返信遅くなりました。 DBプロセスをkillするのはやめ、ご提示していただいたような方法で対処していこうと思います。 詳細な回答ありがとうございました。感謝します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問