2026年8月23日

2026年8月23日

MySQLのAUTO_INCREMENTのリセット方法 番号を戻す前に知っておきたい仕組みとWordPressでの注意点

MySQL の AUTO_INCREMENT(自動採番)の次の値は ALTER TABLE テーブル名 AUTO_INCREMENT = 値; で変更でき、テーブルを空にして1から振り直したい場合は TRUNCATE TABLE を使います。ただし、InnoDB では使用中の最大値より小さい値には戻せず、WordPress の投稿 ID のように他のテーブルや URL から参照されている番号は、リセットや振り直しをすると関連が壊れます。この記事では、番号が飛ぶ理由、現在の値の確認方法、リセットの方法ごとの違い、そして実際によく起きる「AUTO_INCREMENT が外れて ID が 0 になる」トラブルの直し方を説明します。

番号が飛ぶのは正常な動作

AUTO_INCREMENT の値は「次に使う番号」を表すカウンターで、一度払い出した番号は、その行が保存されなかったり削除されたりしても再利用されません。次のような場面で欠番ができます。

  • 行を削除した。DELETE では次の値は戻りません
  • トランザクションをロールバックした、または INSERT が重複エラーなどで失敗した
  • INSERT IGNORE や INSERT ... ON DUPLICATE KEY UPDATE で、実際には行が増えなかった
  • レプリケーションやクラスタ構成で auto_increment_increment が2以上に設定され、意図的に間隔を空けている

WordPress の wp_posts は特に番号が飛びやすいテーブルです。投稿だけでなく、固定ページ、リビジョン、メディア(添付ファイル)、ナビゲーションメニューの項目、ブロックテーマのテンプレートなども同じテーブルに入ります。さらに「新規追加」を開くと自動下書き(auto-draft)が作られ、保存しなくても ID を1つ使います。公開記事の ID が飛び飛びになるのはこのためで、不具合ではありません。

ID は行を区別するための識別子で、記事の数や順番を表すものではありません。連番に見せたい場合は、ID を変えるのではなく、表示時に番号を振るか、別の列で管理するほうが安全です。

現在の値を確認する

SHOW CREATE TABLE wp_posts;

出力の末尾にある AUTO_INCREMENT=1234 が次に使われる値です。SHOW TABLE STATUS LIKE 'wp_posts'; の Auto_increment 列でも確認できます。

information_schema.TABLES の AUTO_INCREMENT 列を使う場合、MySQL 8.0 では統計情報がキャッシュされるため、古い値が表示されることがあります。正確な値が必要なときは、先にセッションの設定を変えてから参照します。

SET SESSION information_schema_stats_expiry = 0;

SELECT TABLE_NAME, AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'wordpress' AND AUTO_INCREMENT IS NOT NULL;

使用中の最大値は SELECT MAX(ID) FROM wp_posts; で分かります。

方法1:ALTER TABLEで次の値を変更する

ALTER TABLE wp_myplugin_logs AUTO_INCREMENT = 1;

InnoDB では、使用中の最大値以下の値を指定してもエラーにはならず、黙って「最大値+1」に設定されます。つまり、途中の欠番を埋め直すことはできません。テーブルの末尾にあった行を削除した後に、次の値を「残っている最大値+1」まで戻す用途に使えます。

逆に、大きな値へ進めることは自由にできます。テスト用のデータと本番のデータで番号帯を分けたい場合などに使います。

方法2:TRUNCATE TABLEで空にして1から始める

TRUNCATE TABLE wp_myplugin_logs;

テーブルの全行を削除し、AUTO_INCREMENT も初期値に戻します。DELETE FROM で全行を消すより速い一方で、次の点に注意が必要です。

  • DDL 文として扱われ、トランザクションで取り消せません。実行前にバックアップを取ります
  • 他のテーブルから外部キーで参照されているテーブルには実行できません
  • 削除したデータが他のテーブルから ID で参照されていた場合、参照先が存在しない状態が残ります

ログや一時データのように、中身を捨ててよいテーブルに限って使ってください。WordPress のコアテーブルに対して実行すると、サイトのデータが失われます。

方法3:既存の行を連番に振り直す

独自に作ったテーブルで、ID がどこからも参照されていないと分かっている場合に限り、新しいテーブルに詰め直す方法で連番にできます。

-- 1. 同じ構造の空テーブルを作る
CREATE TABLE wp_myplugin_logs_new LIKE wp_myplugin_logs;

-- 2. id 以外の列だけをコピー(id は 1 から振り直される)
INSERT INTO wp_myplugin_logs_new (user_id, action, created_at)
SELECT user_id, action, created_at
FROM wp_myplugin_logs
ORDER BY id;

-- 3. 入れ替える(旧テーブルは確認が済むまで残す)
RENAME TABLE wp_myplugin_logs TO wp_myplugin_logs_old,
             wp_myplugin_logs_new TO wp_myplugin_logs;

CREATE TABLE ... LIKE は空のテーブルを作るため、AUTO_INCREMENT は初期値から始まります。作業中に元のテーブルへ書き込みがあると、その行は新しいテーブルに入りません。書き込みを止められる時間に行い、行数が一致することを確かめてから旧テーブルを削除します。

wp_posts や wp_users の ID を振り直すことは勧めません。投稿 ID は wp_postmeta・wp_term_relationships・wp_comments などに記録され、?p=123 形式の URL、ショートコードやブロックの属性、メニュー、プラグインの設定にも埋め込まれています。すべての参照を漏れなく書き換えるのは現実的ではありません。

InnoDBのカウンターは再起動で戻るか

MySQL 5.7 以前の InnoDB では、AUTO_INCREMENT の値をメモリ上にだけ持っており、再起動すると「現在の最大値+1」に計算し直していました。そのため、末尾の行を削除してから再起動すると、削除した番号が再利用されることがありました。MySQL 8.0 ではカウンターが永続化され、再起動しても値は戻りません。MariaDB も新しい版では永続化されています(2026年10月現在、細かな挙動はバージョンで異なるため公式ドキュメントで確認してください)。古い環境から移行したシステムで「削除した ID が再び使われる」前提の処理があれば、見直しが必要です。

よくあるトラブル:IDが0になる・Duplicate entry '0'

移行や復元の後に、新しい投稿を保存しようとすると Duplicate entry '0' for key 'PRIMARY' が出たり、投稿の ID が 0 になったりすることがあります。原因の多くは、移行の途中でテーブル定義から AUTO_INCREMENT や主キーが外れたことです。まず定義を確認します。

SHOW CREATE TABLE wp_posts;

ID の列に AUTO_INCREMENT が無ければ、ID が 0 の行が無いことを確認したうえで、属性を付け直します。作業前にデータベースのバックアップを取ってください。

-- ID が 0 の行が無いか確認(あれば先に対処する)
SELECT ID, post_type, post_title FROM wp_posts WHERE ID = 0;

-- 主キーが残っている場合、AUTO_INCREMENT を付け直す
ALTER TABLE wp_posts
  MODIFY ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT;

主キー自体が外れている場合は、ALTER TABLE wp_posts ADD PRIMARY KEY (ID), MODIFY ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; のように両方を付けます。ほかのテーブル(wp_postmeta の meta_id、wp_options の option_id など)も同じ状態になっていることが多いため、主要テーブルをまとめて確認します。

なお、列の型の上限に達した場合も新しい行を追加できなくなります。WordPress のコアテーブルの ID は BIGINT UNSIGNED なので通常は問題になりませんが、プラグインの独自テーブルが INT で作られている場合は、ログのように行が増え続けるテーブルで上限に近づくことがあります。

まとめ

  • AUTO_INCREMENT の欠番は削除・ロールバック・自動下書きなどで発生する正常な動作で、ID は連番である必要はありません
  • 現在の値は SHOW CREATE TABLE で確認します。MySQL 8.0 の information_schema は値がキャッシュされることがあります
  • ALTER TABLE ... AUTO_INCREMENT は最大値+1より小さくできず、TRUNCATE TABLE は全データを消して初期値に戻します
  • 連番への振り直しは、参照されていない独自テーブルに限って新テーブルへ詰め直す方法で行います。WordPress の投稿やユーザーの ID は振り直しません
  • Duplicate entry '0' は AUTO_INCREMENT の属性が外れたことが主な原因で、バックアップを取ってから MODIFY で付け直します

お気軽にご相談ください

お見積りへ お問い合わせへ
▲