Skip to content

Conversation

ken39arg
Copy link
Contributor

@ken39arg ken39arg commented Oct 3, 2017

ref schemalex/schemalex#33

( sorry in japanese )

目的

データベースをあるべき状態に強制的に変更すること
その為、-schemaオプションが示すsqlのコミット間の差分ではなく、実際のデータベースとあるべきスキーマとの差分を扱えるようにすること

なぜ必要か

例えば、以下のようなケースでのリカバリを想定しています。

  • migrateをしたけどUNIQ制約などによってADD COLUMNが出来ないような変更があった場合
    DDLはトランザクションが効かないため、一度migrateに失敗すると次回以降already existsなどが発生してしまう。
  • うっかり手動で直接mysqlのスキーマを変更してしまった場合
    この場合もエラーが発生してしまったり、成功したとしても-schamaにcreate table文を追加せず、手元のコードとDBだけを更新してしまったなどのケースも想定されます。

懸念点

versionteable以外のSchama管理していないテーブルを同じデータベースに入れている場合にdropしてしまうので、ignore tables みたいなオプションを用意したほうが良いでしょうか?

そもそも、git-schamalex-recovery みたいな別ツールにしたほうが良いでしょうか?

外部キー制約を使っていて、暗黙にINDEXが作成された時に、手書きのSQLとshow create tableで暗黙的に作成されたINDEXがdiffとなり、それがDROP INDEXできないという問題があったので外部キーを設定している場合 schemalex/schemalex#33 だけでは足りなそうでした。
https://dev.mysql.com/doc/refman/5.6/ja/create-table-foreign-keys.html
この件についてはschemalexに別途prしようと思います。

usecase: after failed deploy. but ddl is non transaction.
then use this option for force migrate.
@lestrrat
Copy link
Contributor

lestrrat commented Oct 3, 2017

目的部分の文章がよくわかりませんでした。なんとなく察せますが、ここはハッキリさせておいたほうがよさそうです。さらにオプション名が"fromdb"なので「データベースから」なにかをするのはわかりますが、何をするのかよくわからない印象です。

わかりにくい点の例のひとつとして、データベースと任意のスキーマの差分を出すのか?それとも任意のスキーマとデータベースの差分を出すのか?がfromdbというオプション名この説明だけではわからないです。目的がハッキリしてれば意見をする方としてもオプション名の提案等ができますが、ちょっとこの説明だとなんとも言えない感じです。

ということで、上記のような細かい点以前に大枠の目的をしっかりPRに書いていただく方が良い気がします。

@soh335
Copy link
Member

soh335 commented Oct 4, 2017

懸念点以降の処理がどのぐらい大きくなるかで分けるか、サブコマンド式にするか、みたいなこともあるかもしれないですね。これの場合はこっちのオプションは使われないみたいなのが、もし増えてくるとちょっとわかりづらそうかなというきも。

失敗した時に db と差分が出せる機能自体は便利そうで良さそうな気がしています。

@ken39arg
Copy link
Contributor Author

ken39arg commented Oct 6, 2017

PRのdescription更新しました。
GitDDLを使ってたときも同じようなカスタマイズをして使っていましたが、schemalex/schemalex#33 で対応しているようにSHOW CREATE TABLE と人間が書いたクエリで予期せぬ差分があるみたいなことがあるので、普段はschemaのコミット間の差分のみを使って本当にやらかした時に、手元でだけ使うみたいな感じでした。

実際、手元でslowlogをみながらINDEXの調整をするみたいなことがあって、調整が終わったらschemaを修正してこれと同じような仕組みで元に戻すということをしていました。

@lestrrat
Copy link
Contributor

lestrrat commented Oct 6, 2017

直感的な反応としては

  • それ、もはや"git-"schemalexではないのでは?
  • でも、やりたい気持ちはわかる

schemalexが差分を出すツールで、git-schemalexがgitに保存してある差分を出して適用するツールなんだから、schemalexのほうでファイル vs ファイルとかじゃなくて、ファイル vs DBを出せるようにするほうが正しいのかも?

@soh335 どうでしょう?

@lestrrat
Copy link
Contributor

lestrrat commented Oct 6, 2017

例えば、こう

schemalex 'mysql://user:pass@tcp(127.0.0.1:3306)/dbname?foo=bar&baz=quux' /path/to/file

@ken39arg
Copy link
Contributor Author

ken39arg commented Oct 6, 2017

確かに mysqldump -d と組み合わせてできないことも無いですね。(ヒドイですけど)

$ mysqldump -d -h ** > /tmp/current.sql
$ schemalex /tmp/current.sql path/to/schema.sql > diff.sql
$ v=`git log --pretty=%H -n 1 path/to/schema.sql` && echo "UPDATE table SET version='$v';" >> diff.sql
$ mysql *** < diff.sql

このオプションが無くても、これでいけますよーくらいで良い気もしますのでおまかせします。

@lestrrat
Copy link
Contributor

lestrrat commented Oct 6, 2017

@soh335 @ken39arg ほい、書いてみましたよ。PTAL

schemalex/schemalex#34

@lestrrat
Copy link
Contributor

lestrrat commented Oct 6, 2017

gitに登録されてるファイルも読み込めるようにしたらすげぇ便利になってきた…

gitに登録されてるファイル vs 適当なファイル

schemalex 'local-git:///path/to/dir?file=sql/foo.sql?commitish=$sha1' /path/to/file.sql

gitに登録されてるファイル vs MySQLからひっぱてきたスキーマ

schemalex 'local-git:///path/to/dir?file=sql/foo.sql?commitish=$sha1' 'mysql://user:pass@tcp(host:port)/dbname'

@lestrrat
Copy link
Contributor

lestrrat commented Oct 6, 2017

こうなってくると、git-schemalexほどごつごつしたものはいらなくなって、schemalexの簡単なラッパーがあるとなんでもできるようになりそう。

基本、

schemalex from to | mysql ...

さえできればDDLの差分は適用できるわけだから、git-schemalex的なツールが提供するのはもうバージョンテーブルの管理くらいになりますよね

@lestrrat
Copy link
Contributor

lestrrat commented Oct 7, 2017

stdin対応もつけたので、これもできるようになりました(現在デプロイされてるものと、ローカルのファイルの差分を出す)

cat foo.sql | schemalex 'mysql://....' -

@soh335
Copy link
Member

soh335 commented Oct 7, 2017

mysql の現在を読み込めるようにするなら

  • git-schemalex に取り込む
    • pros: version table と一緒に動かせる
    • cons: git-schemalex の機能なのか?
  • 別ツールとして取り込む
    • pros: git-schemalex はそのまま
    • cons: 今後取り込みもとが増えたらまた増えるの?
  • もう git から読み込むのも合わせて、schemalex に寄せる
    • pros: 今後種類が増えても、schemalex だけメンテで良い
    • cons: 今回のケース含めて、git-schemalex の立ち位置をどうするか考える必要がある( cons ではないけど)

だと思っていたので、schemalex に寄せるでいいかなぁと思ってます。
テーブルで git の commit で version 管理する時に、今回みたいなケースの時はどうするかだけ考えますかね。(失敗したら、こういう手順で適用すると良いですと readme に書くとか?)

@lestrrat
Copy link
Contributor

lestrrat commented Oct 7, 2017

失敗の場合は、ロールバック手順があってもいいかもですねぇ。例えば、「現在のバージョン」だけを保存するのではなく、ヒストリーを保存しておくとかしてロールバック可能にするとか。

でも、

(失敗したら、こういう手順で適用すると良いですと readme に書くとか?)

とりあえずこれがよさそうな気がします。

@soh335
Copy link
Member

soh335 commented Oct 7, 2017

そうですね。そういう機能を将来的に? git-schemalex で schemalex をラップしつつ提供していくが良さそうな気がします。

@lestrrat
Copy link
Contributor

lestrrat commented Oct 7, 2017

とりあえず schemalex側レビューおねしゃす!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants