2013年10月16日水曜日

5.1.72のmysql_upgrade --skip-write-binlogでスクリプトが転けるバグ

昨日、MySQL 5.0.83から5.1.72へのバージョンアップをしてたんですが、バイナリー入れ替えてmysql_upgradeかけても何か様子がおかしい。
前に5.0.83に上げた時にmysql_upgrade忘れてたんじゃないかと疑ってたんですが、実際5.1.72のmysql_upgradeのバグっぽいです。ごめんとなりのひと。

http://dev.mysql.com/doc/refman/5.1/en/mysql-upgrade.html


mysql_upgradeに--skip-write-binlogまたは--write-binlogのオプションを引き渡すと、実行されるべき`mysql_fix_privilege_tables'のクエリーが全て転けてアップグレードできない、というもの。
取り敢えず5.1.72のmysql_upgradeで確認しましたが、どこで混入したのかは謎。


$ gdb --args mysql_upgrade --socket=/xxx/mysql.sock -uroot -p'xxx' --skip-write-binlog

brake mysql_check.c:770 and go on.

770   run_query(mysql_fix_privilege_tables,
771             &ds_result, /* Collect result */
772             TRUE);

(gdb) bt full
#0  run_tool (tool_path=, ds_res=0x7fffffffe7f0) at mysql_upgrade.c:372
        ret = 
        arg = 
        args = {{gp_offset = 48, fp_offset = 0, overflow_arg_area = 0x7fffffffe170, reg_save_area = 0x7fffffffe060}}
        ds_cmdline = {
          str = 0x610650 "'/home/yoku0825/mysql-5.1.72/client/mysql' '--no-defaults' '--socket=/xxx/mysql.sock' '--user=root' '--password=xxx' '--write-binlog' '--user=root'  '--database=mysql' '--batch' '--"..., length = 240,
          max_length = 512, alloc_increment = 512}
#1  0x00000000004019bf in run_query (ba
    query=0x4028b0 "-- Copyright (c) 2007, 2008 MySQL AB, 2009 Sun Microsystems, Inc.\n -- Use is subject to license terms.\n -- \n -- This program is free software; you can redistribute it and/or modify\n -- it under the te"...,
    ds_res=0x7fffffffe7f0, force=1 '\001') at mysql_upgrade.c:497
        ret = 
        fd = 7
        query_file_path = "/tmp/sqlQG2xcV", '\000' "\220, \353\200\313>\000\000\000\200\027\365\312>", '\000' , "\b\000\000\000\060\000\000\000\300\343\377\377\377\177\000\000\000\343\377\377\377\177", '\000' , "#\245\306\312>", '\000' "\200, \027\365\312>\000\000\000(\000\000\000\000\000\000\000\n\000\000\000\000\000\000\000\000\000\253\252\252*\000\000\066\244\306\312>\000\000\000\000\002\000\000\000\000\000\000\200\027\365\312>\000\000\000\200\027\365\312>\000\000\000\n\000\000\000\000\000\000\000\360\347\377\377\377\177\000\000\264\253\306\312>\000\000\000\200\027\365\312>\000\000\000\224\342@\000\000\000\000\000\200\027\365\312>\000\000\000\020\374\305\312>\000\000\000\224\342@\000\000\000\000\000\032\025@\000\000\000\000\000\b\000\000\000\060\000\000\000\300\343\377\377\377\177\000\000\000\343\377\377\377\177\000\000\020\000a\000\000\000\000\000\331\342@\000\000\000\000\000"...
        sql_log_bin = "SET SQL_LOG_BIN=0;"
#2  0x000000000040211c in run_sql_fix_privilege_tables (argc=0, argv=0x6102f8) at mysql_upgrade.c:770
        found_real_errors = 0
        ds_result = {str = 0x610420 "/home/yoku0825/mysql-5.1.72/client/.libs/lt-mysql: unknown option '--write-binlog'\n",
          length = 82, max_length = 512, alloc_increment = 512}
#3  main (argc=0, argv=0x6102f8) at mysql_upgrade.c:872
        self_name = "/home/yoku0825/mysql-5.1.72/client/.libs/mysql_upgrade", '\000' 
(gdb)
(gdb) p *ds_res
$1 = {str = 0x610420 "/home/yoku0825/mysql-5.1.72/client/.libs/lt-mysql: unknown option '--write-binlog'\n", length = 82,
  max_length = 512, alloc_increment = 512}


mysql_upgradeがテンポラリーファイルにアップグレード用のステートメントを書き出し(この時、--skip-write-binlogならファイルの先頭に"SET SQL_LOG_BIN= 0;"を書き込む)、mysqlコマンドラインクライアントを呼んでそのファイルを食わせる、という流れで実際のALTERが行われる手筈になっているのだけれど、その時にmysql_upgradeが--skip-write-binlog, --write-binlogオプションをmysqlコマンドラインクライアントに渡してしまうのが問題で、unknown optionって怒られる羽目に遭う。

mysql_upgrade --skip-write-binlogの時はmysql .. --write-binlog .. --skip-write-binlogの両方を渡して、後から渡した--skipの方でオーバーライドさせてる、mysql_upgrade --write-binlogの時はmysql .. --write-binlog ..と渡してる。
どっちも指定されていない時はどちらのオプションもmysqlに渡さず、5.1では暗黙のデフォルトとして--write-binlog扱いになり、"SET SQL_LOG_BIN= 0;"は書き込まれない。

--write-binlogオプションを押し込むところを--loose-write-binlogにして、mysql_upgradeに渡すのを--loose-skip-write-binlogにすれば何とかなるかな、と思いつつパッチでも書こうかしら。でも電車動き始めたらしいのでそろそろ出勤するかな。

ちなみにこれ、MySQL Bugsにも上げたんですが、backtraceの中にパスワードとか残したままにしてしまって、しかもBugsは後から投稿取り消せないのでモニョモニョな状態になってコメントで泣きついたところ、Access deniedにしてもらいました。

「Oracle様にとってはゴミ屑のようなコミュニティエディションの1ユーザーの懇願など無視されるかな」と思ってたんですが、数時間でさっくり対応してくれて感謝感謝です。
正直ちょっと(だけ)見直した。

MySQL Bugs #70624 mysql_upgrade with --skip-write-binlog doesn't work
http://bugs.mysql.com/bug.php?id=70624


【2013/10/16 16:05】
パッチ書きました。

https://gist.github.com/yoku0825/7003161

【2013/10/24 12:29】
本家でもVerifyされたので、次のリリースでは直るといいなー。

0 件のコメント :

コメントを投稿