まるまるこふこふ

数々の次元が崩壊し、全ての生命が塵と化すのを見てきた。私ほどの闇の心の持ち主でも、そこには何の喜びも無かった。

MySQL サーバーを再起動するとAUTO_INCREMENT の値が戻る

InnoDB では AUTO_INCREMENT のカウンタはメモリ上に保持します。

14.6.5.1 従来の InnoDB の自動インクリメントロック https://dev.mysql.com/doc/refman/5.6/ja/innodb-auto-increment-traditional.html

InnoDB テーブルに AUTO_INCREMENT カラムを指定すると、InnoDB データディクショナリ内のテーブルハンドルに、カラムに新しい値を割り当てる際に使用される自動インクリメントカウンタと呼ばれる特別なカウンタが含まれます。このカウンタは、ディスク上には格納されず、メインメモリー内にのみ格納されます。

InnoDB では、ai_col という名前の AUTO_INCREMENT カラムを含むテーブル t に自動インクリメントカウンタを初期化するために、次のようなアルゴリズムが使用されます。サーバーの起動のあとで、テーブル t への最初の挿入をするために、InnoDB は次のステートメントと同等なものを実行します。

SELECT MAX(ai_col) FROM t FOR UPDATE;

何が問題かというと、最新のレコードを削除して MySQL サーバーを再起動すると AUTO_INCREMENT の値が巻き戻る。

>select * from test;

1
2
3
4
5

>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

>delete from test where id = 5;
>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

ここでMySQLを再起動

>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

まあこのように SELECT MAX(id) FROM test FOR UPDATE; の値に巻き戻る。 AUTO_INCREMENTした値が一意であることを見越して、
他のテーブルの外部キーにしてたりすると、整合性が取れなくなってしまう。

対策としては
・外部キー制約入れる
・AUTO_INCREMENTに頼らず、別に採番テーブルを用意する
・論理削除してレコードを delete しない(!)

toho-like-js のソースコードを読む 4

進捗

StageState を読んだ

わかったこと

1.ビット演算子でフラグ管理するの便利(キーの押下、SEの再生等)
2. 画面各要素のマネージャーインスタンス初期化時に、initDrawerを呼んでる
3.キー押下は一旦 KeyFlagQueue に格納され、キュー先頭から使用されていく

StageStateが持つ各シーン

ShootingState
ゲーム画面
TalkState
ボスキャラとの会話シーン
ClearState
ステージクリア
GameOverState
ゲームオーバー

画面の各要素

BackGround
Fighter
FighterOption
Enemy
Boss
Effect
Bullet
Bomb
EnemyBullet
Item
SpellCard

各要素毎に下記のクラスが存在する

Drawer
Factory
Manager
View
Element
FreeList

わからんこと

1.lag の役割(恐らく multiplay 用だと思う)
2.KeyFlagQueue クラスの必要性(恐らく通信プレイの同期のため)
3.viewScore で本来の score から表示の際に調整入れてる理由

toho-like-js のソースコードを読む 3

進捗

ReplaySelectState.js
リプレイ選択画面
CharacterSelectState.js
キャラクターセレクト画面
PostReplayState.js
リプレイ投稿画面
EndingState.js
エンディング画面
StaffRollState.js
スタッフロール画面

StageState以外を読んだ

わかったこと

1.オープニング等のトランジション効果は canvas の globalAlpha によって透過度を設定して実現してる

次回

いよいよゲームのシーンである StageStateを読んでいく

toho-like-js のソースコードを読む 2

進捗

LoadingState.js(ローディング画面)を読んだ OpeningState.js(オープニング及びStart・Replayセレクト画面)を読んだ GameState.js(各シーンの基底クラス)を読んだ

わかったこと

LoadingState.js

1.LoadingState で各画像, BGM, SEを読み込み 2.読み込みカウントが最大になったら、Game オブジェクトに通知 3.Game オブジェクトは通知を受けてシーン切り替え

OpeningState.js

1.中でさらにロゴシーン・タイトルシーンのインスタンスを持つ。 2. OpeningStateはそれらの管理を行う

toho-like-js のソースコードを読む 1

進捗

index.html を読んだ
Game.js を読んだ

わかったこと

1.index.html で Game インスタンスの作成及び run をしている
2.Gameインスタンスは各シーンの管理及び、BGMや画像、描画用canvasなどのグローバルなデータを管理している
3.Game インスタンスは requestAnimationFrame を再帰的に呼び出して再描画を行っている
4.Game オブジェクトは各シーンに引き渡され、各シーンのインスタンスから使用される
5.Game インスタンスが各シーンのインスタンスを持ち、各シーンインスタンスが Game オブジェクトを持つので、GCの実装によってはメモリリークする
6.シーンの切り替えは、Gameインスタンスメソッドによって行う

各シーン

LoadingState.js
ローディング画面
OpeningState.js
オープニング画面
ReplaySelectState.js
リプレイ選択画面
CharacterSelectState.js
キャラクターセレクト画面
StageState.js
ゲーム画面
PostReplayState.js
リプレイ投稿画面
EndingState.js
エンディング画面
StaffRollState.js
スタッフロール画面
GameState.js
各シーンの基底クラス