MyISAMの読み取りロックについて

MyISAMのテーブルに対してSELECTするとテーブルに対して読み取りロックがかかるけど同時INSERTが可能な場合もある。具体的には可変長カラムのUPDATE、レコードの削除が発生していないテーブルに対しては同時INSERTが可能。これはSHOW TABLE STATUSした時のData_freeを見ればわかる。また、この領域を開放する方法もいくつかある。

以下、いろいろ調べた結果。

    • -

データファイル内に空きブロックがないテーブルに対し、他のスレッドがそのテーブルから読み取りを行うのと同時に新しいレコードを INSERT できる(同時挿入)。空きブロックは、大量のデータを含んだ可変長レコードに含まれるデータの長さが短くなるような更新をした場合、またはレコードを削除した場合に発生する。すべての空きブロックを使い切ると、それ以後の挿入は再び同時挿入になる。
http://dev.mysql.com/doc/refman/4.1/ja/myisam.html

MySQL バージョン 3.23.7 以降は、MyISAM テーブルへのレコードの挿入を、他のスレッドが同一テーブルから読み取りを行うのと同時に実行できるようになりました。現在のところ、挿入実行時にテーブルのレコード削除後のホールがない場合にのみ、この機能が使用可能になるため注意が必要です。すべてのホールに新規のデータが入力されると、同時挿入が自動的に再度可能になります。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.10.2 テーブルロックの問題

この条件化ではINSERTが可能な読み取りロックになるということか。「空きブロック」というのはSHOW TABLE STATUSした時に出てくるData_free(割り当て済みだが、現在のところ未使用な容量)のことか。どうやったら「すべての空きブロックを使い切る」ことができるのか?

LOCK TABLES

READ LOCAL と READ の違いは、READ LOCAL の場合、ロックの保有中に、コンフクリトを発生させない INSERT ステートメントを実行できることです。しかし、ロックの保有中にデータベースを MySQL の外部で操作しようとする場合は、この機能を使用できません。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.3.5 LOCK TABLES および UNLOCK TABLES 構文

LOCK TABLES table_name READ

LOCK TABLES table_name READ LOCAL
かの違いってことか?でもちょっと違う気もする。

「空きブロックがない」状態

「空きブロック」がData_freeのことだとして。

MySQLには,いくつかのフラグメンテーション対象方法が提示されている。しかし,最も確実な解消策は,MYSQLDUMPでバックアップをとり,テーブルを削除して,再構築する。MyISAMは,テーブルごとにファイルを3つ作成するので,即座にフラグメンテーションが解消される。
[MySQLウォッチ]第24回 台風の目になったMySQLの現状とバックアップ・ファイルの活用 | 日経 xTECH(クロステック)

「提示されている」方法を知りたい。
調べた。

  1. OPTIMIZE TABLE
  2. myisamchk -r

MySQL :: MySQL 8.0 Reference Manual :: 16.2.3.2 Dynamic Table Characteristics

ダンプしてテーブル再構築が簡単かな。