2014年10月16日木曜日

MySQL 5.7では"[Note] mysqld: ready for connections"がどっかいった? (いってなかった

MySQLがちゃんと起動したかどうか(クラッシュリカバリーとか終わったかどうか)を見るのに、「"ready for connections"が出てれば接続はできるよ」とか昔から言ってたんですが、5.7.5で遊んでたらどうもこのログが出ない。

-- 5.6.21
2014-10-07 19:38:03 23139 [Note] /usr/mysql/5.6.21/bin/mysqld: ready for connections.
Version: '5.6.21-log'  socket: '/usr/mysql/5.6.21/data/mysql.sock'  port: 64056  Source distribution

-- 5.7.5
141016 19:17:37 mysqld_safe Starting mysqld daemon with databases from /usr/mysql/5.7.5/data
2014-10-16T10:17:38.421845Z 0 [Warning] The syntax '--log_warnings/-W' is deprecated and will be removed in a future release. Please use '--log_error_verbosity' instead.
2014-10-16T10:17:38.422101Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2014-10-16T10:17:38.869037Z 0 [Warning] Failed to setup SSL
2014-10-16T10:17:38.869069Z 0 [Warning] SSL error: SSL context is not usable without certificate and private key

…あれ、これだけ?; と思ったら俺の設定が悪いせいだった。


$ vim my.cnf
..
log-warnings= 1
..

よかれと思って(いや、少なくとも悪さはしないので)このパラメーター指定していたんですが、コイツ5.7で少し意味合いが変わってます。
↑のエラーログにも書いてありますが、log_error_verbosityを代わりに使え! ってことで、log_warnings + 1の値が勝手にlog_error_verbosityにセットされます
http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_log_warnings

log_error_verbosityは何者かというと、

Verbosity ValueMessage Types Logged
1Errors only
2Errors and warnings
3Errors, warnings, and notes

http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_log_error_verbosity


正に名前の通り、ログレベルによって出力をフィルターしてくれるやつです。ログを書き出す関数はちゃんとログレベルを評価するようになってます。暗黙のデフォルトは3。
log-warningsが、「ほとんどのログには影響なくて、1以上の場合にのみ出力されるログがある」(=その関数を通らずに出力されるログがいっぱいあるというかほとんど)という超投げ遣りな意味合いだったのに比べて大きな違いです。

というわけで暗黙のデフォルト3がlog-warnings=1 => log_error_verbosity=2に上書きされて、Noteの出力を抑制するモードに…。。


よかれと思って取り敢えずつけてる人(俺も前職のころのクセでそうだった)がハマりそうな感じでした。ちゃんちゃん。

MySQL 5.7.5でsecure-authが軒並み使えなくなるはなし

みんなだいすき(?)、MySQL 4.0以前の古い16桁ハッシュで保存されたパスワードで認証するために必要な --secure-auth が5.7.5でついに非推奨になりました。
http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_secure-auth
が、「非推奨になったよ。そのうち消える。オプションはパースされるけど無視されるようになった!」というマニュアルの記載はアレで、実際はちょっと下に引用文っぽく書かれている「--secure-auth=0 や--skip-secure-auth を指定すると起動しません」の方が正しい。

mysqldのみならず同梱されているCLI類は全てそうなっています。

$ bin/mysqld --no-defaults --datadir=./data --skip-secure-auth
2014-10-16T06:05:04.604270Z 0 [Warning] The syntax '--secure-auth' is deprecated and will be removed in a future release
2014-10-16T06:05:04.604334Z 0 [ERROR] Unsupported value 0 for secure-auth
2014-10-16T06:05:04.604341Z 0 [ERROR] Aborting

2014-10-16T06:05:04.604357Z 0 [Note] Binlog end

$ bin/mysql --no-defaults --skip-secure-auth
WARNING: --secure-auth is deprecated and will be removed in a future version
bin/mysql  Ver 14.14 Distrib 5.7.5-m15, for linux-glibc2.5 (x86_64) using  EditLine wrapper
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Usage: bin/mysql [OPTIONS] [database]
..

$ bin/mysqldump --no-defaults --skip-secure-auth
WARNING: --secure-auth is deprecated and will be removed in a future version
mysqldump  Ver 10.13 Distrib 5.7.5-m15, for linux-glibc2.5 (x86_64)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Dumping structure and contents of MySQL databases and tables.
Usage: mysqldump [OPTIONS] database [tables]
OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR     mysqldump [OPTIONS] --all-databases [OPTIONS]
..


このクライアントがダメになるやつ、ワーニング出したあとsecure-authの値が不正だってことを一切出力 *せずに* usageを表示して抜ける。これイヤだ。

$ grep -A4 -r 'if (!opt_secure_auth)' client/
client/mysqlimport.c:    if (!opt_secure_auth)
client/mysqlimport.c-    {
client/mysqlimport.c-      usage();
client/mysqlimport.c-      exit(1);
client/mysqlimport.c-    }
--
client/mysqladmin.cc:    if (!opt_secure_auth)
client/mysqladmin.cc-    {
client/mysqladmin.cc-      usage();
client/mysqladmin.cc-      exit(1);
client/mysqladmin.cc-    }
--
client/mysql.cc:    if (!opt_secure_auth)
client/mysql.cc-    {
client/mysql.cc-      usage(0);
client/mysql.cc-      exit(1);
client/mysql.cc-    }
--
client/check/mysqlcheck.cc:    if (!opt_secure_auth)
client/check/mysqlcheck.cc-    {
client/check/mysqlcheck.cc-      usage();
client/check/mysqlcheck.cc-      exit(1);
client/check/mysqlcheck.cc-    }
--
client/mysqlshow.c:    if (!opt_secure_auth)
client/mysqlshow.c-    {
client/mysqlshow.c-      usage();
client/mysqlshow.c-      exit(1);
client/mysqlshow.c-    }
--
client/mysqlbinlog.cc:    if (!opt_secure_auth)
client/mysqlbinlog.cc-    {
client/mysqlbinlog.cc-      usage();
client/mysqlbinlog.cc-      exit(1);
client/mysqlbinlog.cc-    }
--
client/mysqlslap.c:    if (!opt_secure_auth)
client/mysqlslap.c-    {
client/mysqlslap.c-      usage();
client/mysqlslap.c-      exit(1);
client/mysqlslap.c-    }
--
client/mysqldump.c:    if (!opt_secure_auth)
client/mysqldump.c-    {
client/mysqldump.c-      usage();
client/mysqldump.c-      exit(1);
client/mysqldump.c-    }


16桁ハッシュってそもそも何語? 対処は? っていうのはこちらあたりを。
昔っぽいMySQLにmysql2とかからつなぎにいくと怒られる件の対処 - Qiita
日々の覚書: MySQL5.6とMySQL5.0のレプリケーションでI/OスレッドがError: 2049


【2014/10/16 16:29】
old-passwords=1もダメになってますね。SHA256を使うold-passwords=2とかいうのも5.6で追加されてる。。(それ、そのオプション名でいいのか)

http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_old_passwords

2014年10月7日火曜日

すごくどうでもいいかもしれないMySQL 5.7の変更点 in mysql_install_db

取り合えず、PerlからCに変わってる。

$ file /usr/mysql/5.6.20/scripts/mysql_install_db
/usr/mysql/5.6.20/scripts/mysql_install_db: a /usr/bin/perl script text executable

$ file /usr/mysql/5.7.5/bin/mysql_install_db
/usr/mysql/5.7.5/bin/mysql_install_db: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped


あと、パスが変わってる。今までは./scriptsだったのが./binに(rpmで使ってるぶんには何も変わらないはず) ソースの位置もclient/mysql_install_db.ccになってる。

増えたオプションがいっぱい。

$ /usr/mysql/5.7.5/bin/mysql_install_db --help
..
  --admin-auth-plugin=name
                      Plugin to use for the default admin account.
  --admin-host=name   Hostname part of the default admin account.
  --admin-require-ssl Require SSL/TLS for the default admin account.
  --admin-user=name   Username part of the default admin account.
..
  --defaults          Read any option files from default location. If program
                      startup fails due to reading unknown options from an
                      option file, --no-defaults can be used to prevent them
                      from being read.
..
  -f, --extra-sql-file=name
                      Optional SQL file to execute during bootstrap.
  --insecure          Disables random passwords for the default admin account.
..
  --lc-messages=name  Specifies the language to use.
  -l, --lc-messages-dir=name
                      Specifies the path to the language files.
  --login-file=name   Use the MySQL password store at the specified location
                      to set the default password. This option takes precedence
                      over admin-user, admin-host options. Use the login-path
                      option to change the default credential category (default
                      is 'client').
  --login-path=name   Set the credential category to use with the MySQL
                      password store when setting default credentials. This
                      option takes precedence over admin-user, admin-host
                      options.
  --mysqld-file=name  Qualified path to the mysqld binary.
  --random-password-file=name
                      Specifies the qualified path to the .mysql_secret
                      temporary password file.
..


.mylogin.cnf周りっぽいやつが軒並み追加。あと、5.6.20で折角追加された--keep-my-cnfがいきなりなくなってるけど、そもそもmy.cnfを勝手に作るロジックがなくなったような気がする(けど、support-files/my-default.cnfはまだ残ってるな)
敢えて/etc/my.cnfとか/usr/local/mysql/etc/my.cnfとかを読むであろう、--defaultsとかいうオプションも追加されてる。誰得。。

extra-sql-fileとかいうのを上手く使うと、mysql_install_dbの段階でユーザーを初期設定できたりするのかしらん? と思ったら


$ cat ./test.sql
GRANT ALL ON tpcc.* TO tpcc@localhost IDENTIFIED BY 'tpcc';

$ ./bin/mysql_install_db --datadir=./data --basedir=./ --extra-sql-file=./test.sql
2014-10-07 18:35:26 [ERROR]   The bootstrap log isn't empty:
2014-10-07 18:35:26 [ERROR]   2014-10-07T09:35:25.177361Z 1 [ERROR] 1290  The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
2014-10-07T09:35:25.177637Z 0 [ERROR] Aborting


--bootstrapしてる状態で食わせるから、GRANTステートメントはダメか。
CREATE DATABASEとかはどうだ。

$ cat test2.sql
CREATE DATABASE tpcc;

$ ./bin/mysql_install_db --datadir=./data --basedir=./ --extra-sql-file=./test2.sql

$ ll data
合計 110612
-rw-rw---- 1 yoku0825 yoku0825 50331648 10月  7 18:37 2014 ib_logfile0
-rw-rw---- 1 yoku0825 yoku0825 50331648 10月  7 18:37 2014 ib_logfile1
-rw-rw---- 1 yoku0825 yoku0825 12582912 10月  7 18:37 2014 ibdata1
drwx------ 2 yoku0825 yoku0825     4096 10月  7 18:37 2014 mysql
drwx------ 2 yoku0825 yoku0825     4096 10月  7 18:37 2014 performance_schema
drwx------ 2 yoku0825 yoku0825     4096 10月  7 18:37 2014 tpcc


通ったってことは、GRANTをmysql.user, dbあたりへのINSERTステートメントにすれば食えるだろうけど、微妙だなぁ。。

--insecureはrootのランダムパスワード生成を無効化してくれるので、好んで使う人多いんじゃないでしょうか :)
5.6までは--random-passwordがオプション扱いだった(rpm -iの時にこのオプションが押し込まれる)けれど、5.7では逆に--insecureがないと常にランダムパスワード生成ぽい。

あと、5.6までは--basedirを与えない時は暗黙にカレントディレクトリがbasedirだったのが、5.7では明示的に与えないといけない。


$ ./bin/mysql_install_db --datadir=./data
2014-10-07 18:44:41 [ERROR]   Can't locate the language directory.

暗黙のbasedirが与えられてないから、$basedir/shareが見つからずにこんなん言われる。慣れてるからすぐわかるけど、初心者殺しな罠だと思うこれ。

2014年9月29日月曜日

MySQL 5.7.5のコンパイルにはBoostが必要になった

実際にはLabs版の5.7.4(InnoDB GIS)から必要になってたらしい。5.7.5のリリースノート を"boost"で引っかけると出てきたり、Building MySQL with Boost | MySQL Server Blog に書いてあったりした内容を試したっていうだけのメモ。

( ´-`).oO(MySQL Server Blogには1.55が必要って書いてあるけど、リリースノートにはバージョン特に書いてないなぁ。。cmake/boost.cmakeを見る限り、1.55が決め打ちで必要とされてるぽいけど(1.56ではダメ)


CentOS 6.3の公式リポジトリからyumで突っ込んでみるも、バージョンが1.41なのでやっぱりダメっぽい。

$ cmake .
..
-- BOOST_VERSION_NUMBER is #define BOOST_VERSION 104100
CMake Warning at cmake/boost.cmake:200 (MESSAGE):
  Boost minor version found is 41 we need 55
Call Stack (most recent call first):
  CMakeLists.txt:466 (INCLUDE)


-- Could not find (the correct version of) boost.

CMake Error at cmake/boost.cmake:37 (MESSAGE):
  You can download it with -DDOWNLOAD_BOOST=1 -DWITH_BOOST=<directory>

  This CMake script will look for boost in $lt;directory>.  If it is not there,
  it will download and unpack it (in that directory) for you.

  If you are inside a firewall, you may need to use an http proxy:

  export http_proxy=http://example.com:80

Call Stack (most recent call first):
  cmake/boost.cmake:203 (COULD_NOT_FIND_BOOST)
  CMakeLists.txt:466 (INCLUDE)


-- Configuring incomplete, errors occurred!


$ rpm -qa | grep boost
boost-date-time-1.41.0-18.el6.x86_64
boost-iostreams-1.41.0-18.el6.x86_64
boost-wave-1.41.0-18.el6.x86_64
boost-1.41.0-18.el6.x86_64
boost-system-1.41.0-18.el6.x86_64
boost-thread-1.41.0-18.el6.x86_64
boost-program-options-1.41.0-18.el6.x86_64
boost-python-1.41.0-18.el6.x86_64
boost-regex-1.41.0-18.el6.x86_64
boost-signals-1.41.0-18.el6.x86_64
boost-serialization-1.41.0-18.el6.x86_64
boost-devel-1.41.0-18.el6.x86_64
boost-graph-1.41.0-18.el6.x86_64
boost-math-1.41.0-18.el6.x86_64
boost-filesystem-1.41.0-18.el6.x86_64
boost-test-1.41.0-18.el6.x86_64


というわけで、前述のURLの通りにcmakeにオプションを渡してやる。

$ cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/tmp/boost
-- Running cmake version 2.8.11.1
..
-- MySQL 5.7.5-m15
-- Packaging as: mysql-5.7.5-m15-Linux-x86_64
-- Local boost dir LOCAL_BOOST_DIR-NOTFOUND
-- Local boost zip LOCAL_BOOST_ZIP-NOTFOUND
-- Downloading boost_1_55_0.tar.gz to /tmp/boost
-- [download 0% complete]
..
-- cd /tmp/boost; tar xfz /tmp/boost/boost_1_55_0.tar.gz
-- BOOST_VERSION_NUMBER is #define BOOST_VERSION 105500
-- BOOST_INCLUDE_DIR /tmp/boost/boost_1_55_0
..
-- Build files have been written to: /home/yoku0825/mysql-5.7.5-m15

おお、通った。

というわけで誰かmysql-buildにパッチ投げてください。。(Issue上げただけで力尽きた)


【2014/09/28 16:46 PDT】
結局書きました。
https://github.com/kamipo/mysql-build/pull/13

2014年9月26日金曜日

MySQL 5.7.5のInnoDB undo log truncationを試してみた

MySQL 5.7.5では、*UNDOログ領域が共有テーブルスペース上になければ* 使っていない領域をシュリンクさせることが出来るようになったらしい。

まずはUNDOログ領域を共有テーブルスペース上から追い出す設定。これは5.6で既に使える。共有テーブルスペースを作る *前に* やっておかないといけないので注意。


$ vim my.cnf
..
innodb-undo-tablespaces= 2
..

とりあえずinnodb-undo-tablespacesを2以上にすればOK。暗黙のデフォルトは0(=共有テーブルスペース上にUNDOテーブルスペースを作る)
1だとUNDOログ領域はibdata1上には作られなくなるものの、今回追加されたシュリンクの機能は使えない。
これで起動すると


# cd /usr/local/mysql
[root@v157-7-154-209 mysql]# ll data
total 652604
-rw-rw---- 1 mysql mysql        56 Sep 22 16:43 auto.cnf
-rw-rw---- 1 mysql mysql     87754 Sep 22 16:43 bin.000001
-rw-rw---- 1 mysql mysql   1230997 Sep 22 16:43 bin.000002
-rw-rw---- 1 mysql mysql  83893472 Sep 22 16:45 bin.000003
-rw-rw---- 1 mysql mysql        39 Sep 22 16:43 bin.index
-rw-rw---- 1 mysql mysql      3260 Sep 22 16:43 error.log
-rw-rw---- 1 mysql mysql  12582912 Sep 22 16:44 ibdata1
-rw-rw---- 1 mysql mysql 268435456 Sep 22 16:45 ib_logfile0
-rw-rw---- 1 mysql mysql 268435456 Sep 22 16:43 ib_logfile1
-rw-rw---- 1 mysql mysql  12582912 Sep 22 16:43 ibtmp1
drwx------ 2 mysql mysql      4096 Sep 22 16:44 mysql
-rw-rw---- 1 root  root          5 Sep 22 16:43 mysqld_safe.pid
-rw-r--r-- 1 root  root          9 Sep 22 16:44 mysql_upgrade_info
drwx------ 2 mysql mysql      4096 Sep 22 16:44 performance_schema
-rw-rw---- 1 mysql mysql       682 Sep 22 16:44 slow.log
drwx------ 2 mysql mysql      4096 Sep 22 16:44 tpcc
-rw-rw---- 1 mysql mysql  10485760 Sep 22 16:44 undo001
-rw-rw---- 1 mysql mysql  10485760 Sep 22 16:44 undo002
-rw-rw---- 1 mysql mysql         5 Sep 22 16:43 hostname.pid

こんなかんじ。$datadir/undo{連番} がUNDOログ領域。何番まで作られるかはinnodb-indo-tablespacesで決まる。
これを肥大化させるようにしばらくトラフィックをかけて


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:39 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:39 data/undo002

これを


mysql> SELECT @@innodb_max_undo_log_size;
+----------------------------+
| @@innodb_max_undo_log_size |
+----------------------------+
|                 1073741824 |
+----------------------------+
1 row in set (0.02 sec)

mysql> SET GLOBAL innodb_max_undo_log_size= 10 * 1024 * 1024;
Query OK, 0 rows affected (0.02 sec)

mysql> SET GLOBAL innodb_undo_log_truncate= 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%undo%';
+--------------------------+----------+
| Variable_name            | Value    |
+--------------------------+----------+
| innodb_max_undo_log_size | 10485760 |
| innodb_undo_directory    | .        |
| innodb_undo_log_truncate | ON       |
| innodb_undo_logs         | 128      |
| innodb_undo_tablespaces  | 2        |
+--------------------------+----------+
5 rows in set (0.00 sec)

こうじゃ!


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002

( ゚д゚) ・・・

(つд⊂)ゴシゴシ


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002

(;゚д゚) ・・・

(つд⊂)ゴシゴシゴシ


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002
_, ._
(;゚ Д゚) …!?


減ってないじゃん。何がいけないんだろう。。
と思ったら、innodb_purge_rseg_truncate_frequencyというパラメーターがあるらしい。n回、undoログのパージが呼ばれるとtruncationが炸裂する、みたいな。


mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
|                                    128 |
+----------------------------------------+
1 row in set (0.00 sec)

-- tpcc_start

# ll data/undo00*
-rw-rw---- 1 mysql mysql  10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:47 data/undo002

# ll data/undo00*
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo002

# ll data/undo00*
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo002


おお、トランザクションをかければパージが呼ばれるようになるので、シュリンクが発動する、みたいな。
innodb_buffer_pool_dump_nowみたいにSET GLOBALしたところからバックグラウンドに処理が始まるわけじゃなくて、常に有効で容量が監視されて超えたらtruncationになるわけか。。

てことはあんまり小さいサイズにすると死ねると。

ともあれちょっと感動した。

MySQL 5.7.5でmysqlスキーマの中身がちょっとだけInnoDB化された

MySQL 5.7ではmysqlスキーマのテーブルがいくつかMyISAM => InnoDB化されている。

5.6ではInnoDB統計情報永続化のヤーツと{master|relay-log}_info_repositoryのヤーツだけだったのが、


mysql56> SELECT @@version;
+------------+
| @@version  |
+------------+
| 5.6.20-log |
+------------+
1 row in set (0.00 sec)

mysql56> SELECT table_name, engine FROM information_schema.tables WHERE table_schema= 'mysql';
+---------------------------+--------+
| table_name                | engine |
+---------------------------+--------+
| columns_priv              | MyISAM |
| db                        | MyISAM |
| event                     | MyISAM |
| func                      | MyISAM |
| general_log               | CSV    |
| help_category             | MyISAM |
| help_keyword              | MyISAM |
| help_relation             | MyISAM |
| help_topic                | MyISAM |
| innodb_index_stats        | InnoDB |
| innodb_table_stats        | InnoDB |
| ndb_binlog_index          | MyISAM |
| plugin                    | MyISAM |
| proc                      | MyISAM |
| procs_priv                | MyISAM |
| proxies_priv              | MyISAM |
| servers                   | MyISAM |
| slave_master_info         | InnoDB |
| slave_relay_log_info      | InnoDB |
| slave_worker_info         | InnoDB |
| slow_log                  | CSV    |
| tables_priv               | MyISAM |
| time_zone                 | MyISAM |
| time_zone_leap_second     | MyISAM |
| time_zone_name            | MyISAM |
| time_zone_transition      | MyISAM |
| time_zone_transition_type | MyISAM |
| user                      | MyISAM |
+---------------------------+--------+
28 rows in set (0.00 sec)


5.7.5では

mysql> SELECT @@version;
+---------------+
| @@version     |
+---------------+
| 5.7.5-m15-log |
+---------------+
1 row in set (0.05 sec)

mysql> SELECT table_name, engine FROM information_schema.tables WHERE table_schema= 'mysql';
+---------------------------+--------+
| table_name                | engine |
+---------------------------+--------+
| columns_priv              | MyISAM |
| db                        | MyISAM |
| engine_cost               | InnoDB |
| event                     | MyISAM |
| func                      | MyISAM |
| general_log               | CSV    |
| gtid_executed             | InnoDB |
| help_category             | InnoDB |
| help_keyword              | InnoDB |
| help_relation             | InnoDB |
| help_topic                | InnoDB |
| innodb_index_stats        | InnoDB |
| innodb_table_stats        | InnoDB |
| ndb_binlog_index          | MyISAM |
| plugin                    | MyISAM |
| proc                      | MyISAM |
| procs_priv                | MyISAM |
| proxies_priv              | MyISAM |
| server_cost               | InnoDB |
| servers                   | MyISAM |
| slave_master_info         | InnoDB |
| slave_relay_log_info      | InnoDB |
| slave_worker_info         | InnoDB |
| slow_log                  | CSV    |
| tables_priv               | MyISAM |
| time_zone                 | InnoDB |
| time_zone_leap_second     | InnoDB |
| time_zone_name            | InnoDB |
| time_zone_transition      | InnoDB |
| time_zone_transition_type | InnoDB |
| user                      | MyISAM |
+---------------------------+--------+
31 rows in set (0.00 sec)


:(;゙゚'ω゚'): おいmysql_install_dbとmysql_upgradeしか触らないようなテーブルじゃまいか。

engine_cost, server_cost, gtid_executedが新設テーブルですね。

MySQL 5.7.5のオフラインモードはgraceful shutdownの夢を見るか

MySQL 5.7.5の新機能ネタ。

いままでMySQLでgraceful shutdownぽいことをしようとすると、SET GLOBAL max_connections= 1 で接続を制限するくらいしか思いつかなかったけれども(LVSとかでやりくりするのは除く)
* 接続を切断するわけではないので、Connector/Jのコネクションプーリング的なものとかと相性が悪い
* クライアントにはError: 1040 (ER_CON_COUNT_ERROR) "Too many connections" が戻ってしまう
  * しかも、Error: 1040は通常運用でも異常系として発生しうるので、区別してハンドルするのはかなり無理ゲー
と、イマイチgraceful shutdownの夢を見切れなかったけれども。


5.7.5で追加されたオフラインモードが多少なりとも夢を見させてくれるかも知れない。
オフラインモードは
* SET GLOBAL offline_mode= 1で有効化
* オフラインモードだと、Super_privを持っていないユーザーは接続できない
* Super_privを持っていないユーザーのセッションは、トランザクションが終了次第コネクションを切断される
という機能。

http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_offline_mode


tpcc_startをかけながら、以下のコマンドでドン。

mysql> SHOW PROCESSLIST; SET GLOBAL offline_mode= 1; SHOW PROCESSLIST;
+----+------+-----------+------+---------+------+----------------+------------------------------------------------------------
------------------------------------------+
| Id | User | Host      | db   | Command | Time | State          | Info
                                          |
+----+------+-----------+------+---------+------+----------------+------------------------------------------------------------
------------------------------------------+
|  7 | root | localhost | NULL | Query   |    0 | starting       | SHOW PROCESSLIST
                                          |
|  8 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 997 WHERE w_id = 1
                                          |
|  9 | tpcc | localhost | tpcc | Execute |    0 | Writing to net | UPDATE stock SET s_quantity = 62 WHERE s_i_id = 14040 AND s
_w_id = 1                                 |
| 10 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 1347 WHERE w_id = 1
                                          |
| 11 | tpcc | localhost | tpcc | Execute |    0 | statistics     | SELECT count(*) FROM stock WHERE s_w_id = 1 AND s_i_id = 96
265 AND s_quantity < 19                   |
| 12 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 2773 WHERE w_id = 1
                                          |
| 13 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 2927 WHERE w_id = 1
                                          |
| 14 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE stock SET s_quantity = 5 WHERE s_i_id = 89835 AND s_
w_id = 1                                  |
| 15 | tpcc | localhost | tpcc | Query   |    0 | starting       | commit
                                          |
| 16 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE order_line SET ol_delivery_d = '2014-09-20 16:29:37'
 WHERE ol_o_id = 2310 AND ol_d_id = 2 AND |
| 17 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 3326 WHERE w_id = 1
                                          |
| 18 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 1965 WHERE w_id = 1
                                          |
| 19 | tpcc | localhost | tpcc | Execute |    0 | optimizing     | SELECT count(*) FROM stock WHERE s_w_id = 1 AND s_i_id = 78
08 AND s_quantity < 12                    |
| 20 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 4738 WHERE w_id = 1
                                          |
| 21 | tpcc | localhost | tpcc | Sleep   |    0 |                | NULL
                                          |
| 22 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 925 WHERE w_id = 1
                                          |
| 23 | tpcc | localhost | tpcc | Sleep   |    0 |                | NULL
                                          |
| 24 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 1413 WHERE w_id = 1
                                          |
| 25 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 3134 WHERE w_id = 1
                                          |
| 26 | tpcc | localhost | tpcc | Execute |    0 | Writing to net | INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, ol_numbe
r, ol_i_id, ol_supply_w_id, ol_quantity,  |
| 27 | tpcc | localhost | tpcc | Execute |    0 | updating       | UPDATE warehouse SET w_ytd = w_ytd + 1808 WHERE w_id = 1
                                          |
+----+------+-----------+------+---------+------+----------------+------------------------------------------------------------
------------------------------------------+
21 rows in set (0.03 sec)

Query OK, 0 rows affected (0.02 sec)

+----+------+-----------+------+---------+------+-------------+---------------------------------------------------------------
---------------------+
| Id | User | Host      | db   | Command | Time | State       | Info
                     |
+----+------+-----------+------+---------+------+-------------+---------------------------------------------------------------
---------------------+
|  7 | root | localhost | NULL | Query   |    0 | starting    | SHOW PROCESSLIST
                     |
| 11 | tpcc | localhost | tpcc | Killed  |    0 | System lock | SELECT count(*) FROM stock WHERE s_w_id = 1 AND s_i_id = 32770
 AND s_quantity < 19 |
| 15 | tpcc | localhost | tpcc | Killed  |    0 | starting    | commit
                     |
+----+------+-----------+------+---------+------+-------------+---------------------------------------------------------------
---------------------+
3 rows in set (0.00 sec)


オフラインモードに設定したあと、クエリー(not トランザクション)が終了したタイミングでクライアントは切断される。 切断されたクライアントで更に操作をしようとすると、フツーにError: 2006 "MySQL Server has gone away"が出力される(wait_timeoutとかで切断されたときといっしょ)

..
payment 3:1
2006, HY000, MySQL server has gone away
payment 3:1
2006, HY000, MySQL server has gone away
..

tpcc_startは起動時にセッション確保してそのままずっとそれでトラフィックをかけ続けるので、セッションをつなぎ直さないので、これがどばーとで続ける。
新しくつなぎ直そうとすると、


# mysql -utpcc -p tpcc
Enter password:
ERROR 1917 (HY000): The server is currently in offline mode

# mysql -uroot -p tpcc
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 30
Server version: 5.7.5-m15-log MySQL Community Server (GPL)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

SUPERでないユーザーはError: 1917でエラーが返り、スーパーユーザーはそのまま接続できる。max_connection= 1みたいに2セッションしかメンテ用に使えないとか(スーパーユーザー全体で+1セッションなので、1本スーパーユーザーで入ると他のスーパーユーザーも入れない)そんなこともない。

オフラインモードに入れてもポートのLISTENはそのままなので、TCPで3306を叩くだけの死活監視は生きてしまうことくらいがアレだけど、LVSとか手前で切り離せばそれでもたぶんOK。

mysqladmin pingはエラーを出力するけど戻り値は0だった。FR出そうかな。


# mysqladmin -utpcc -p ping
Enter password:
mysqladmin: connect to server at 'localhost' failed
error: 'The server is currently in offline mode'

# echo $?
0


# mysqladmin -uroot -p ping
Enter password:
mysqld is alive

# echo $?
0