タグ

MySQLとロックに関するiwwのブックマーク (12)

  • 排他制御のためだけに Redis 渋々使ってませんか?データベース単独でアドバイザリーロックできるよ!

    トランザクション分離レベルについての教養があったほうがこの記事の内容を理解しやすいため,必要に応じてまず以下を参照されたい。 背景 以前, Qiita で以下の記事を投稿した。今回の議題に直接的な関係はないが,関連している部分があるため引用する。 MySQL/Postgres とも, MVCC アーキテクチャの恩恵で, SELECT と UPDATE は基的には競合しない。 単一レコードのシンプルな UPDATE でも排他ロックされ,排他ロック中のレコードへの UPDATE での変更操作は トランザクション分離レベルによらず ブロックされる。UPDATE 文に含まれる WHERE 句での検索もブロックされ,これはブロックされない SELECT による検索とは別扱いになる。 但し UPDATE 文の WHERE 句上で,更新対象をサブクエリの SELECT から自己参照している場合は例外。

    排他制御のためだけに Redis 渋々使ってませんか?データベース単独でアドバイザリーロックできるよ!
  • WHERE 条件のフィールドを UPDATE するのって,明示的にロックしてなくても安全?全パターン調べてみました! - Qiita

    WHERE 条件のフィールドを UPDATE するのって,明示的にロックしてなくても安全?全パターン調べてみました!MySQLSQLPostgreSQLDatabaseQiitaEngineerFesta2022 TL; DR MySQL/Postgres とも, MVCC アーキテクチャの恩恵で, SELECT と UPDATE は基的には競合しない。 単一レコードのシンプルな UPDATE でも排他ロックされ,排他ロック中のレコードへの UPDATE での変更操作は トランザクション分離レベルによらず ブロックされる。UPDATE 文に含まれる WHERE 句での検索もブロックされ,これはブロックされない SELECT による検索とは別扱いになる。 但し UPDATE 文の WHERE 句上で,更新対象をサブクエリの SELECT から自己参照している場合は例外。トランザクション分離

    WHERE 条件のフィールドを UPDATE するのって,明示的にロックしてなくても安全?全パターン調べてみました! - Qiita
    iww
    iww 2022/07/05
    『元の StackExchange サイト上の最も投票されている回答が完全に間違っていました。やっぱり一次ソースが曖昧なときは実験しないとダメですね。』
  • MySQLで発生し得る思わぬデッドロックと対応方法

    はじめに この記事は実際の業務で発生した MySQL のデッドロックとそのいくつかの回避方法や対応方法を(テーマは変えて)手元で実行できるコードを用いて解説する記事です。具体的には「トランザクション張っておけば大丈夫」と思ってませんか? バグの温床になる、よくある実装パターンの記事で紹介されている「1on1 チャットサービス」で紹介されているデッドロックとデータベースレイヤでは同じ状況だったのですが、記事で紹介されている方法とは別の方法でデッドロックを回避する必要があったため、同じ状況に遭遇した人の助けになればという思いで記事を書きました。また、こちらの記事が無ければ私自身も現象を理解するのにもっと苦労したと思うので、この場を借りてお礼申し上げます! 出金サービス履歴登録サービスを例に考える コードと説明が https://github.com/shuntagami/withdrawal_

    MySQLで発生し得る思わぬデッドロックと対応方法
  • MySQLでSELECT FOR UPDATEと行ロックの挙動を検証してみた - Continue(s)

    どうも、今日も今日とて野毛で飲みながらブログを書いている@0kawaraです。 今日は、普段あまり意識してこなかったMySQLのInnoDBでのロックの振る舞いについて色々実験してみました。(もちろん、きっかは自分がドツボにはまったから) ちゃんと理解するためには「共有・排他的ロックとは」って話や、「行ロックってつまりインデックスレコードロックだよね」などの話とか理解する必要があるんですが、それは github.com をちゃんと一読してもらえれば十分かと思います。 (というか、これが問題なく読めて理解できる人はこの記事読む必要ない….) 以下は上のドキュメント含め関連する記事などを読んで自分でInnoDBの行ロック周りについて、というかSELECT FOR UPDATEについて理解を深めるために手元で実験したことのまとめです。 技術的にちゃんとした理解を深めたい人は最後にまとめた参考サイ

    MySQLでSELECT FOR UPDATEと行ロックの挙動を検証してみた - Continue(s)
    iww
    iww 2018/09/18
    ファントムリード
  • MySQL :: MySQL 8.0 リファレンスマニュアル :: 5.4.5 スロークエリーログ

    スロークエリーログは、実行に long_query_time 秒を超える時間がかかり、少なくとも min_examined_row_limit 行を検査する必要がある SQL ステートメントで構成されます。 スロークエリーログは、実行に長い時間がかかっているため最適化の候補となるクエリーを見つけるために使用できます。 ただし、長いスロークエリーログの調査には時間がかかる場合があります。 これを簡単にするために、mysqldumpslow コマンドを使用してスロークエリーログファイルを処理し、その内容を要約できます。 セクション4.6.9「mysqldumpslow — スロークエリーログファイルの要約」を参照してください。 初期ロックを取得する時間は実行時間として計算されません。mysqld がスロークエリーログにステートメントを書き込むのは、ステートメントが実行されて、すべてのロックが解

  • mysqlのバックアップ(mysqldump)のロック問題 - SEEDS Creator's Blog

    こんにちは、はらぐちです。 今回お話したいのは、mysqlのバックアップ方法についてのあれこれです。 バックアップ mysqldump mysqlのバックアップといえばmysqldumpです。 以下のような形で使います。 mysqldump -u root -p -x -A > my_dumpall.db これで全データベースのダンプができます。 特定のデータベースをダンプしたい場合は、以下のようにデータベース名を指定します。 mysqldump -u root -p -x データベース名 > dump.sql 定期的にバックアップを取りたい場合は、シェルスクリプトで以下のようなものを cronで実行してあげるといいでしょう。 二日間のバックアップを保持するスクリプト例です。 #!/bin/bash MPASS=パスワード mysqldump --defaults-extra-file=<

    mysqlのバックアップ(mysqldump)のロック問題 - SEEDS Creator's Blog
  • tree-tips: mysqldumpでロックせずオンラインバックアップする | MySQL

    mysqldumpのオンラインバックアップ mysqldumpのオプション mysqldump時にロックをかけないオプションは「--single-transaction」です。 --single-transaction このオプションはサーバからデータをダンプする前にBEGIN SQLステートメントを発行します。InnoDBといったトランザクションテーブルに対してのみ便利です。なぜなら、アプリケーションをブロックせずに、BEGINが発行された当時のデータベースの状態をダンプするからです。 このオプションを使用しているときは、一定の状態でダンプされるのはInnoDBテーブルのみだということを留意してください。例えば、このオプションを使用中にダンプされたMyISAMやMEMORYテーブルは状態が変化する可能性があります。 mysqldump — データベースバックアッププログラム リファレンス

    iww
    iww 2016/10/21
    --single-transaction
  • MySQL :: MySQL 8.0 リファレンスマニュアル :: 15.7.2.4 読取りのロック

    データのクエリーを実行してから、同じトランザクション内で関連データを挿入または更新する場合は、通常の SELECT ステートメントで十分な保護が提供されません。 ほかのトランザクションは、クエリーが実行されたばかりの同じ行を更新または削除できます。 InnoDB では、追加の安全性が提供される 2 つのタイプのロック読み取りがサポートされています。 SELECT ... FOR SHARE 読み取られる行に共有モードロックを設定します。 ほかのセッションもその行を読み取ることができますが、トランザクションがコミットするまで変更することはできません。 これらの行のいずれかがコミットされていない別のトランザクションによって変更された場合、クエリーはそのトランザクションが終了するまで待機してから、最新の値を使用します。 SELECT ... FOR SHARE は SELECT ... LOCK

    iww
    iww 2016/03/25
    『トランザクションがコミットまたはロールバックされると、LOCK IN SHARE MODE および FOR UPDATE クエリーで設定されたすべてのロックが解放されます。 』
  • MySQLの行ロックのふしぎ挙動で夜も安心して眠れない | 三鷹台でひきこもるプログラマの日記

    MySQLのびみょーな行ロックに悩まされたのでメモ代わりに。 全部MySQL5.5でInnoDB使っている時のお話デス。 こんなテーブルが有るとしますよ。 create table table001 ( id int primary key, name text ); そしてこんなデータが入っています。 A> select * from table001; +----+-----------------+ | id | name | +----+-----------------+ | 1 | 水瀬伊織 | | 2 | 伊織さま | | 3 | いおりん | | 4 | デコちゃん | +----+-----------------+ まあ、データの中身は気にしない方向で。 そんなアイマス好きのAさん。 伊織さまを「デコちゃん」呼ばわりしている id=4 が許せないので書き換えてやろうと決

  • MySQL InnoDBの行レベルロック

    この機能はMyISAMにはなかったものなので、自分用のメモを書きました。 行レベル・ロックとは 行レベル・ロックは「レコード単位のロック機能」のことです。1レコードだけロックされるわけではなく、対象となる複数レコードがロックされます。 innoDBテーブル・タイプでは、レコード更新時とSELECT文(ロック・オプション付き)で行レベル・ロックが行われます。 読み取り時のロック 通常の「SELECT .. FROM ..」というステートメントでは、いっさいロックされません。また、読み取り一貫性機能によって、こういったクエリーを実行した後に、他でロックしても読み取りを続行することは可能です。 読み取り時にロックしたい場合、明示的にロック方法を指定する必要があります。 ロック方法 SQL 共有モードでは、まだ残っている更新トランザクションが存在したら、まず、そのトランザクションが終了するまで待機

  • updateが行ロックするとは限らない(MySQL InnoDB) - Qiita

    MySQLで、スレッドが排他的にテーブルを操作する方法がねえかと考えた。 updateなりdeleteなりなら行ロックでも別にいいのだが、テーブルに対するinsertもロックする方法がわからん。 LOCK TABLES構文というのを見つけて「名前的にこれやろ」と思ったが全然違って、しかも運用中のサービスに安易にコードを付け加えテストもせずにリリースしてしまったおかげで、4人しか入れない部屋に10人ぐらい参加してゲームが始まらないという恐怖の状態に陥ってしまった。当たり前である。(LOCK TABLES は、現在のスレッドに対してベース テーブル (ビュー以外) をロックします) 最初は、LOCK TABLESが「現在のスレッドに対しロック」して、「もしテーブルが1つでも他のスレッドによってロックされていたら、それは全てのロックを入手するまでブロック」するというのなら、必要なデータの読み書き

    updateが行ロックするとは限らない(MySQL InnoDB) - Qiita
    iww
    iww 2013/06/24
    『「名前的にこれやろ」と思ったが全然違って、しかも運用中のサービスに安易にコードを付け加えテストもせずにリリース』 行動がロックすぎる
  • あるあるおハマり大事典 - InnoDBなのに行ロックしないの - (ひ)メモ

    drop table if exists t; create table t ( iid int ,nid int ,bid binary(3) ,msg varchar(69) ,key (iid) ,key (bid) ) ENGINE=InnoDB; insert into t values (1,1,1,"ichi"),(2,2,2,"ni"),(3,3,3,"san") ,(4,4,4,"si"),(5,5,5,"go"),(6,6,6,"roku") ; なテーブルとデータで、2つ端末を用意して update しあいっこしてみます。 まず、これ↓は両方ともupdateが完了してスコっと返ってきます。行レベルロック++ begin; update t set msg = "t1" where iid = 1; と begin; update t set msg = "t2" wh

    あるあるおハマり大事典 - InnoDBなのに行ロックしないの - (ひ)メモ
  • 1