2013年6月28日金曜日

もう一度MySQL Utilitiesを試してみる(インストール編)

WEBサーバーが増設されて、MySQLのユーザーを追加しなきゃいけなかった時にCREATE USER .. LIKE ...みたいなのが使えたらなぁとか思っていたら、@RKajiyamaさんにmysqlusercloneがあるよ! と教えてもらったので試してみる。

MySQL Utilitiesはだいぶ前にmysqlfailoverを試したくて入れたっきりで、あの時はまだMySQL Workbenchにしか入っていなかった(いつだったか独立して入れられるようになった)ので、WorkbenchのソースコードからUtilitiesの部分だけインストールしたなぁとか感傷に浸りつつ、お手軽にrpmで突っ込む。

CentOS6.3だから本当は"Oracle & Red Hat Linux 6"じゃないんだけど気にしない。"Linux Generic"がないので。

$ sudo rpm -i http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-utilities-1.3.2-1.el6.noarch.rpm/from/http://cdn.mysql.com/
エラー: 依存性の欠如:
        mysql-connector-python >= 1.0.9 は mysql-utilities-1.3.2-1.el6.noarch に必要とされています

おやま。
MySQL公式のConnector/Pythonが必要で、MySQL-pythonじゃダメらしい。

$ sudo rpm -i http://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-1.0.10-1.el6.noarch.rpm/fro
m/http://cdn.mysql.com/

$ sudo rpm -i http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-utilities-1.3.2-1.el6.noarch.rpm/from/http://cdn.mysql.com/

入れたら通った。うん。
取り敢えずmysqluc(MySQL Utilities Client)を起動してみる。

$ mysqluc
Launching console ...
WARNING: mysqlauditadmin failed to read options. This utility will not be shown in 'help utilities' and cannot be accessed from the console.
ERROR: The mysqlauditadmin utility requires Python version 2.7.0 or higher and lower than 3.0.0. The version of Python detected was 2.6.6. You may need to install or redirect the execution of this utility to an environment that includes a compatible Python version.

WARNING: mysqlauditgrep failed to read options. This utility will not be shown in 'help utilities' and cannot be accessed from the console.
ERROR: The mysqlauditgrep utility requires Python version 2.7.0 or higher and lower than 3.0.0. The version of Python detected was 2.6.6. You may need to install or redirect the execution of this utility to an environment that includes a compatible Python version.


Welcome to the MySQL Utilities Client (mysqluc) version 1.3.2
Copyright (c) 2000, 2013, 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' for a list of commands or press TAB twice for list of utilities.

mysqluc>

(;´д`) Python古い言われた。
sudo yum update pythonしても2.6.6のままだったのでまあいいやAudit Pluginからみのやつだけぽいし。

mysqluc> help
Command                 Description
----------------------  ---------------------------------------------------
help utilities          Display list of all utilities supported.
help <utility>          Display help for a specific utility.
help | help commands    Show this list.
exit | quit             Exit the console.
set <variable>=<value>  Store a variable for recall in commands.
show options            Display list of options specified by the user on
                        launch.
show variables          Display list of variables.
<ENTER>                 Press ENTER to execute command.
<ESCAPE>                Press ESCAPE to clear the command entry.
<DOWN>                  Press DOWN to retrieve the previous command.
<UP>                    Press UP to retrieve the next command in history.
<TAB>                   Press TAB for type completion of utility, option,
                        or variable names.
<TAB><TAB>              Press TAB twice for list of matching type
                        completion (context sensitive).
mysqluc> help utilities
Utility           Description
----------------  ---------------------------------------------------------
mysqldbcompare    compare databases for consistency
mysqldbcopy       copy databases from one server to another
mysqldbexport     export metadata and data from databases
mysqldbimport     import metadata and data from files
mysqldiff         compare object definitions among objects where the
                  difference is how db1.obj1 differs from db2.obj2
mysqldiskusage    show disk usage for databases
mysqlfailover     automatic replication health monitoring and failover
mysqlfrm          show CREATE TABLE from .frm files
mysqlindexcheck   check for duplicate or redundant indexes
mysqlmetagrep     search metadata
mysqlprocgrep     search process information
mysqlreplicate    establish replication with a master
mysqlrpladmin     administration utility for MySQL replication
mysqlrplcheck     check replication
mysqlrplshow      show slaves attached to a master
mysqlserverclone  start another instance of a running server
mysqlserverinfo   show server information
mysqluserclone    clone a MySQL user account to one or more new users

mysqluc> help mysqluserclone
Usage: mysqluserclone --source=user:pass@host:port:socket --destination=user:pass@host:port:socket joe@localhost sam:secret1@localhost

mysqluserclone - clone a MySQL user account to one or more new users

Options:
Option                       Description
---------------------------  ----------------------------------------------
--version                    show program's version number and exit
--help                       display a help message and exit
--source=SOURCE              connection information for source server in
                             the form:
                             <user>[:<password>]@<host>[:<port>][:<socket>]
                             or <login-path>[:<port>][:<socket>].
--destination=DESTINATION    connection information for destination server
                             in the form:
                             <user>[:<password>]@<host>[:<port>][:<socket>]
                             or <login-path>[:<port>][:<socket>].
-d, --dump                   dump GRANT statements for user - does not
                             require a destination
--force                      drop the new user if it exists
--include-global-privileges  include privileges that match base_user@% as
                             well as base_user@host
--list                       list all users on the source - does not
                             require a destination
-f, --format=FORMAT          display the list of users in either grid
                             (default), tab, csv, or vertical format -
                             valid only for --list option
-v, --verbose                control how much information is displayed.
                             e.g., -v = verbose, -vv = more verbose, -vvv =
                             debug
-q, --quiet                  turn off all messages for quiet execution.

mysqluc> 

このあたりはドキュメントに書いてあることやmysqluserclone --helpと一緒ね。
mysqluc立ち上げた時のバナーに書いてある通り、TABで補完が利く。

mysqluc> mysqluserclone<TAB><TAB>

Option                       Description
---------------------------  ----------------------------------------------
--version                    show program's version number and exit
--help                       display a help message and exit
--source=SOURCE              connection information for source server in
                             the form:
                             <user>[:<password>]@<host>[:<port>][:<socket>]
                             or <login-path>[:<port>][:<socket>].
--destination=DESTINATION    connection information for destination server
                             in the form:
                             <user>[:<password>]@<host>[:<port>][:<socket>]
                             or <login-path>[:<port>][:<socket>].
-d, --dump                   dump GRANT statements for user - does not
                             require a destination
--force                      drop the new user if it exists
--include-global-privileges  include privileges that match base_user@% as
                             well as base_user@host
--list                       list all users on the source - does not
                             require a destination
-f, --format=FORMAT          display the list of users in either grid
                             (default), tab, csv, or vertical format -
                             valid only for --list option
-v, --verbose                control how much information is displayed.
                             e.g., -v = verbose, -vv = more verbose, -vvv =
                             debug
-q, --quiet                  turn off all messages for quiet execution.

mysqluc> mysqluserclone --s<TAB><TAB>

Option           Description
---------------  ----------------------------------------------------------
--source=SOURCE  connection information for source server in the form:
                 <user>[:<password>]@<host>[:<port>][:<socket>] or <login-
                 path>[:<port>][:<socket>].

オプションも補完が利く&ついでにそのオプションのhelpも出してくれた。ちょっとCISCOぽい?
しかしこのmysqluc自体が誰得な感じがしないでもない…。


当初の目的のmysqlusercloneにたどり着いてないけどとりあえずここまで。
しかし、どうにもmysqltuner的な気配がするよねこいつら。。(mysqldiskusageとかmysqlserverinfoとかmysqlprocgrepとか)


【2013/07/02 13:17】
mysqluserclone試してみた。すごくフツー。
http://yoku0825.blogspot.jp/2013/07/mysql-utilitiesmysqluserclone.html

2013年6月25日火曜日

手抜きでmysqlコマンドラインクライアントに色をつける

mysqlコマンドラインクライアントの表示に色をつけたくなった。
イメージとしてはこんな感じ。

$ client/mysql -S/usr/mysql/5.6.12/data/mysql.sock
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11532
Server version: 5.6.12-log Source distribution

Copyright (c) 2000, 2013, 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>
mysql>
mysql>
mysql> exit
Bye

mysql-5.6.12/client/mysql.ccに手抜きな感じで追加。

$ vim client/mysql.cc
..
1316   put_info("\033[1;31mWelcome to the MySQL monitor.  Commands end with ; or \\g.",
..
1429     put_info(sig ? "\033[0mAborted" : "\033[0mBye", INFO_RESULT);
..

ビバ、手抜き。

いつも忘れるSHOW SLAVE STATUSとかの権限

何度も忘れるのでいい加減メモ。

SHOW {MASTER|SLAVE} STATUSがSUPERまたはREPLICATION CLIENT、
SHOW SLAVE HOSTS, SHOW {BINLOG|RELAYLOG} EVENTSがREPLICATION SLAVE。

mysql55> SHOW MASTER STATUS;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation

mysql55> SHOW SLAVE STATUS;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation

mysql55> SHOW SLAVE HOSTS;
ERROR 1227 (42000): Access denied; you need (at least one of) the REPLICATION SLAVE privilege(s) for this operation

mysql55> SHOW BINLOG EVENTS IN 'bin.000001';
ERROR 1227 (42000): Access denied; you need (at least one of) the REPLICATION SLAVE privilege(s) for this operation

mysql55> SHOW RELAYLOG EVENTS IN 'relay.000001';
ERROR 1227 (42000): Access denied; you need (at least one of) the REPLICATION SLAVE privilege(s) for this operation

mysql55> RESET SLAVE;
ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation

mysql55> RESET MASTER;
ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation

本気でただのメモ。

2013年6月21日金曜日

クエリーキャッシュはカレントデータベースやキャラクターセットも区別する

クエリーキャッシュに載ってるかどうかの判定はSQLがパースされる前に比較されるから、SELECTステートメントは一字一句同じでないとクエリキャッシュ利かないよ、というのは有名な話。

http://dev.mysql.com/doc/refman/5.5/en/query-cache-operation.html

取り敢えず↑に答えが書いてあったがメモ。

MariaDBのinformation_schema.QUERY_CACHE_INFOをいじっていて気が付いたんだけど、クエリーキャッシュってカレントデータベースも区別してクエリキャッシュに登録してる。
(↓の出力は、そのプラグインをMySQL5.5向けに書き直したやつだけど)

mysql55> RESET QUERY CACHE;
Query OK, 0 rows affected (0.00 sec)

mysql55> SHOW GLOBAL STATUS LIKE 'Qcache_queries_in_cache';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Qcache_queries_in_cache | 0     |
+-------------------------+-------+
1 row in set (0.00 sec)

mysql55> USE d1; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> USE information_schema; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> USE mysql; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> SELECT * FROM information_schema.query_cache_info;
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
| STATEMENT_SCHEMA   | STATEMENT_TEXT              | RESULT_BLOCKS_COUNT | RESULT_BLOCKS_SIZE | RESULT_BLOCKS_SIZE_USED |
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
| d1                 | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| information_schema | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| mysql              | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
3 rows in set (0.01 sec)

mysql55> SHOW GLOBAL STATUS LIKE 'Qcache_queries_in_cache';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Qcache_queries_in_cache | 3     |
+-------------------------+-------+
1 row in set (0.01 sec)


とはいえこれはよく考えれば当たり前で、↑のクエリはたまたまデータベース名まで修飾してるけど、テーブル名だけの場合はカレントデータベースが違えば当然別のクエリだもんね。
SQLステートメントの大文字小文字が違っただけで別のクエリーとしてキャッシュに押し込むsql/cache.ccが、データベース名まで修飾されてるからってよしなにやってくれるとは当然思えないので、これはこれで良い。

でもでも。

さっきのマニュアル、キャラクターセットやプロトコル(MySQLプロトコル)のバージョンも区別するって書いてあるぞ。。。

mysql55> SET NAMES sjis;
Query OK, 0 rows affected (0.00 sec)

mysql55> USE d1; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> USE information_schema; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> USE mysql; SELECT * FROM d1.t1 LIMIT 2;
Database changed
+-----+------+
| num | val  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
+-----+------+
2 rows in set (0.00 sec)

mysql55> SELECT * FROM information_schema.query_cache_info;
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
| STATEMENT_SCHEMA   | STATEMENT_TEXT              | RESULT_BLOCKS_COUNT | RESULT_BLOCKS_SIZE | RESULT_BLOCKS_SIZE_USED |
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
| d1                 | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| information_schema | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| mysql              | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| information_schema | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| d1                 | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
| mysql              | SELECT * FROM d1.t1 LIMIT 2 |                   1 |                512 |                     177 |
+--------------------+-----------------------------+---------------------+--------------------+-------------------------+
6 rows in set (0.02 sec)

mysql55> SHOW GLOBAL STATUS LIKE 'Qcache_queries_in_cache';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Qcache_queries_in_cache | 6     |
+-------------------------+-------+
1 row in set (0.00 sec)

うええええ、ホントだ。これ知らなかった。
確かにbyte単位でSQLステートメントを比較してるだけなら、キャラクターセットが違ったら一致しないねぇ。

プロトコルバージョンの違いは、どのバージョンで変わってるのかよく判らなくて断念。
取り敢えず4.0.30だとプロトコルバージョン違いそうなんだけど、Authのアレで蹴られるので試せず。

最近クエリーキャッシュ漬け。

2013年6月19日水曜日

CREATE TEMPORARY TABLEとレプリケーション

マスターでこんな処理をしている時の話。
mysql> CREATE TEMPORARY TABLE this_is_tmp_table (..);
mysql> INSERT INTO this_is_tmp_table SELECT .. FROM this_is_origin_table WHERE ..;
mysql> UPDATE this_is_tmp_table SET ..;
mysql> INSERT INTO this_is_summary_table SELECT .. FROM this_is_tmp_table;
mysql> DROP TEMPORARY TABLE this_is_tmp_table;
テンポラリーテーブルを使ってごにょごにょした後に、
テンポラリーじゃないテーブルにデータを書き出すような処理。

テンポラリーテーブルは
・datadirではなくtmpdirにデータ実体が吐かれる(ibdata1は別として)
・CREATE TEMPORARY TABLEしたスレッド以外からは見えない
・CREATE TEMPORARY TABLEしたスレッドが接続を閉じれば消される
ような特性を持っている関係上、↑のような処理をレプリケーションしていると、
CREATE TEMPORARY TABLEからDROP TEMPORARY TABLEの間で
SQL_Threadが終了(STOP SLAVEやmysqldの再起動を含めて)してしまうと、
ステートメントベースのレプリケーションではそのままレプリケーションが再開できなくなる。

たとえば、↑の3行目の処理中にSTOP SLAVEしたりすると、
次にSTART SLAVEした時に
2013-06-18 21:44:30 8865 [ERROR] Slave SQL: Error 'Table 'd1.this_is_tmp_table' doesn't exist' on query. Default database: 'd1'. Query: 'INSERT INTO this_is_summary_table SELECT * FROM this_is_tmp_table', Error_code: 1146
となる。
この動作はbinlog_format = STATEMENTの時に起こり得る。

binlog_format = MIXEDだと、
$ mysqlbinlog -vv relay.000018
..
### INSERT INTO `d1`.`this_is_tmp_table`
### SET
###   @1=999990 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2=NULL /* LONGINT meta=96 nullable=1 is_null=1 */
..
のように、テンポラリーテーブルを使ってる周りはレプリケーションアンセーフだと判定して、
ROWモードでの書き出しになる。
なので、この場合は途中で止めてもなんとかなる。

5.1で推しだったbinlog_format = MIXEDは、5.5からは暗黙のデフォルトでは`ない'ので注意。
(binlog_formatの暗黙のデフォルトはSTATEMENTに戻った。5.1の中盤~後半だけ暗黙のデフォルトがMIXED)

2013年6月18日火曜日

時間泥棒なMySQL Clusterのmemcached APIを起動してみる

ちょっと触ってみた。
使ったのはMySQL Cluster 7.3.1-m1(開発版)

( ´-`).oO(って書いてる間に、7.3.2がGAってリリースノートを見た。まだDownloadには来てない。


取り敢えずconfig.iniを最小限で作ってみる。

$ vim config.ini
[NDB_MGMD]
NodeId=49
HostName=localhost
DataDir=/home/yoku/mysql/ndb_7.3.1/mgmd
Portnumber=1186

[NDBD]
NodeId=1
HostName=localhost
DataDir=/home/yoku/mysql/ndb_7.3.1/ndbd/1

[NDBD]
NodeId=2
HostName=localhost
DataDir=/home/yoku/mysql/ndb_7.3.1/ndbd/2

[MYSQLD]
NodeId=51
HostName=localhost

[API]
NodeId=52
HostName=localhost

ディレクトリは自動で作ってくれないので自分で作ってから、ndb_mgmd起動。

$ mkdir -p mgmd ndbd/1 ndbd/2
$ bin/ndb_mgmd --initial --ndb-nodeid=49 --config-file=./config.ini

起動すればそれだけでバックグラウンドに回ってくれる。
続いてndbd。2つ。

$ bin/ndbd --initial --ndb-nodeid=1 --ndb-connectstring=localhost
$ bin/ndbd --initial --ndb-nodeid=2 --ndb-connectstring=localhost

おなじみmysqld。

$ vim my.cnf
[mysqld]
loose-ndbcluster
loose-ndb-connectstring= localhost:1186
log-error= error.log
log-bin= bin

$ scripts/mysql_install_db --datadir=./data
$ bin/mysqld_safe --defaults-file=./my.cnf --datadir=./data &

$ bin/ndb_mgm
ndb_mgm> SHOW
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @127.0.0.1  (mysql-5.6.10 ndb-7.3.1, Nodegroup: 0, Master)
id=2    @127.0.0.1  (mysql-5.6.10 ndb-7.3.1, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=49   @127.0.0.1  (mysql-5.6.10 ndb-7.3.1)

[mysqld(API)]   2 node(s)
id=51   @127.0.0.1  (mysql-5.6.10 ndb-7.3.1)
id=52 (not connected, accepting connect from localhost)

ここまではOK。。(このあとかなりハマった。。)

NDB memcached EngineはInnoDB Memcached Pluginと同じく、
予めそれ用のテーブルを作っておく必要があるので、さっくり食わせる。

$ bin/mysql -uroot < share/memcache-api/ndb_memcache_metadata.sql
$ bin/mysql -uroot -e "SELECT * FROM ndbmemcache.containers"
+------------+-------------+------------------+-------------+----------------+-------+------------------+------------+--------------------+-----------------------------+
| name       | db_schema   | db_table         | key_columns | value_columns  | flags | increment_column | cas_column | expire_time_column | large_values_table          |
+------------+-------------+------------------+-------------+----------------+-------+------------------+------------+--------------------+-----------------------------+
| demo_table | ndbmemcache | demo_table       | mkey        | string_value   | flags | math_value       | cas_value  | NULL               | NULL                        |
| demo_tabs  | ndbmemcache | demo_table_tabs  | mkey        | val1,val2,val3 | flags | NULL             | NULL       | expire_time        | NULL                        |
| demo_ext   | ndbmemcache | demo_table_large | mkey        | string_value   | flags | NULL             | cas_value  | NULL               | ndbmemcache.external_values |
+------------+-------------+------------------+-------------+----------------+-------+------------------+------------+--------------------+-----------------------------+

InnoDB Memcached Pluginと同じように、メタデータを放り込むテーブルに色々定義してやる感じ。
InnoDBのアレはINSTALL PLUGINして再起動だけど、こっちはmemcachedが別プロセスになるのでひょっこり起動してやる。

$ bin/memcached -E lib/ndb_engine.so -e "connectstring=localhost:1186" &
18-Jun-2013 14:41:41 JST NDB Memcache 5.6.10-ndb-7.3.1 started [NDB 7.3.1; MySQL 5.6.10]
Contacting primary management server (localhost:1186) ...
Connected to "localhost:1186" as node id 52.
Retrieved 4 key prefixes for server role "default_role".
The default behavior is that:
    GET uses NDB only
    SET uses NDB only
    DELETE uses NDB only.
The 3 explicitly defined key prefixes are "b:" (demo_table_large), "mc:" () and "t:" (demo_table_tabs)
Server started with 4 threads.
Priming the pump ...
   Failed to grow connection pool.
Scheduler: using 1 connection to cluster 0
Scheduler: starting for 1 cluster; c0,f0,g1,t1
done [14.838 sec].

なぜか-dオプションでバックグラウンド起動させると上手くいかない(´・ω・`)

$ bin/ndb_mgm -e "SHOW"
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @127.0.0.1  (mysql-5.6.10 ndb-7.3.1, Nodegroup: 0, Master)
id=2    @127.0.0.1  (mysql-5.6.10 ndb-7.3.1, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=49   @127.0.0.1  (mysql-5.6.10 ndb-7.3.1)

[mysqld(API)]   2 node(s)
id=51   @127.0.0.1  (mysql-5.6.10 ndb-7.3.1)
id=52   @127.0.0.1  (mysql-5.6.10 ndb-7.3.1)


$ less/mgmd/ndb_49_cluster.log
..

2013-06-18 14:41:40 [MgmtSrvr] INFO     -- Node 1: Communication to Node 52 opened
2013-06-18 14:41:41 [MgmtSrvr] INFO     -- Node 2: Communication to Node 52 opened
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Nodeid 52 allocated for API at 127.0.0.1
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Node 52: memcached
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Node 1: Node 52 Connected
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Node 2: Node 52 Connected
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Node 2: Node 52: API mysql-5.6.10 ndb-7.3.1
2013-06-18 14:41:42 [MgmtSrvr] INFO     -- Node 1: Node 52: API mysql-5.6.10 ndb-7.3.1
2013-06-18 14:41:45 [MgmtSrvr] WARNING  -- Failed to allocate nodeid for API at 127.0.0.1. Returned eror: 'No free node id found for mysqld(API).'
2013-06-18 14:41:48 [MgmtSrvr] WARNING  -- Failed to allocate nodeid for API at 127.0.0.1. Returned eror: 'No free node id found for mysqld(API).'
2013-06-18 14:41:51 [MgmtSrvr] WARNING  -- Failed to allocate nodeid for API at 127.0.0.1. Returned eror: 'No free node id found for mysqld(API).'
2013-06-18 14:41:54 [MgmtSrvr] WARNING  -- Failed to allocate nodeid for API at 127.0.0.1. Returned eror: 'No free node id found for mysqld(API).'
2013-06-18 14:41:57 [MgmtSrvr] WARNING  -- Failed to allocate nodeid for API at 127.0.0.1. Returned eror: 'No free node id found for mysqld(API).'

コネクションプールが作れないとか行ってたのは、APIノードの定義を2つしか作ってないから、
mysqldで1個、memcachedで1個しか使えなくてこうなってるのかな。


ともあれこれで

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set name 0 0 8
yoku0825
Pipeline 0 attached to S scheduler.
STORED
get name
VALUE name 0 8
yoku0825
END
^]
telnet> quit
Connection closed.

$ bin/mysql -uroot -e "SELECT * FROM ndbmemcache.demo_table"
+------+------------+-------+---------------+--------------+
| mkey | math_value | flags | cas_value     | string_value |
+------+------------+-------+---------------+--------------+
| name |       NULL |     0 | 6129992073216 | yoku0825     |
+------+------------+-------+---------------+--------------+

イェーイ。

2013年6月13日木曜日

MySQL 5.7 クライアントの新機能(?)

ちょっと感動したMySQL 5.7.1 クライアント(mysqldではない)の新機能。


まずは取り敢えずこのBugs。

MySQL Bugs: #66583: Ctrl-C behavior violates principle of least astonishment http://bugs.mysql.com/bug.php?id=66583

mysqlコマンドラインクライアントに向かってCtrl+Cを叩くとmysqlコマンドラインクライアントが落ちるという、
ごくごく馴染みの動作に対するFeature Request。

MySQL 4.1.6からは--sigint-ignoreというオプションで(そんな昔からあったのか)
SIGINTそのものを無効化してmysqlコマンドラインクライアントが終了しないようにできるものの、
これだとクエリを止めようと思ってもCtrl+Cで止まらなくなる。

$ mysql56 --sigint-ignore
..
mysql56> SELECT SLEEP(10);
^C^C^C^C^C^C^C^C^C+-----------+
| SLEEP(10) |
+-----------+
|         0 |
+-----------+
1 row in set (10.00 sec)

(´・ω・`) ショボーン

だが、MySQL 5.7.0以降では、SIGINTは無効化せず、
SIGINTでmysqlコマンドラインクライアントが終了する動作だけをハンドルしてくれるようになったのだ!
(何もオプション要らない。デフォルト。むしろ--sigint-ignore使うと↑と同じ動作になる)

$ mysql57 -S/usr/mysql/5.6.12/data/mysql.sock
..
mysql57> SELECT SLEEP(10);
^C^C -- query aborted
+-----------+
| SLEEP(10) |
+-----------+
+-----------+
1 row in set (0.51 sec)

mysql57> ^C
mysql57> ^C

mysqldの機能ではなく、mysqlコマンドラインクライアントの機能です。


ところでMySQL 5.7.1って、もうm11(milestone 11)なのね。
MySQL 5.6.6がm9でその次がMySQL 5.6.7-rc(release candidate)だったので、
結構もりもりやってると期待して良いのかしら。


【2013/06/13 17:44】
くだらないこと書いてやったぜー、と思っていたら、御大が既に書いていらっしゃった。。orz

http://nippondanji.blogspot.jp/2013/05/mysqlmysql-57.html

2013年6月6日木曜日

Amazon RDSでできないかも知れないことメモ

Amazon RDSのrootユーザーからは
SHUTDOWN, FILE, SUPER, REPLICATION SLAVE, CREATE TABLESPACEが
取り上げられているので、これでできなくなるであろうことのメモ。


Shutdown_priv
 mysqladmin shutdownでmysqldをシャットダウンできない。

File_priv
 LOAD DATA INFILEステートメントが使えない。
 SELECT .. INTO OUTFILEステートメントが使えない。
 LOAD_FILE関数が使えない。
  このページを見ていて知ったんだけれど、mysqldに--secure-file-privというオプションがあって、
  これにディレクトリ名を渡すと、
  そのディレクトリ{から|に}だけ{LOAD DATA|SELECT .. INTO OUTFILE|LOAD_FILE}できる
  というように制限をかけられるんだそうな。
  コンマ区切りとか2行書くとか試してみたけど、複数指定は不可能ぽい。

Super_priv
 レプリケーションスレーブになれない。
  (CHANGE MASTER TO, {START|STOP} SLAVEできない)
 自分のスレッド以外をKILL(ステートメントの方ね), mysqladmin killできない。
  (自分のスレッドはSUPERなしでもできるのか。。
 PURGE MASTER LOGSできない。
 SET GLOBALできない。
 mysqladmin debugできない。
 DEFINER属性を指定できない。
 max_connectionsに到達したときの+1コネクションがない。
 binlogが有効な場合、ストアドファンクションの{CREATE|DROP}ができない。
  (log-bin-trust-function-creators使えば作れる)
 SET @@sql_log_bin, SET @@binlog_formatできない。
 {CREATE|ALTER|DROP} SERVERできない。
  (いや、FEDERATEDエンジン使えるのか知らないけど)
 
Repl_slave_priv
 SHOW BINLOG EVENTSできない。
 SHOW SLAVE HOSTSできない。
 レプリケーションスレーブ作れない(GRANTできないから)

Create_tablespace_priv
 CREATE TABLESPACEできない…けどこれndbclusterのやつだから特に困らないはず。


少なくともこれだけの動作が(自前のMySQL rootに比べて)できなくなると思う。

なんかやたら推し量る系の言い回しなのは、RDSなんか変だから。
DROP USERした瞬間からそのユーザーの権限が無効になったり
 (フツーのMySQLは次にログインしたときかUSEでデータベース変えた時に効くはず)
なんか手を入れてる気がする。
バージョンもSource Distributionだし。。

2013年6月4日火曜日

MySQL 5.6.12の--connect-expired-passwordオプション

MySQL 5.6.12のChangeLogを読んでいて不思議に思った--connect-expired-passwordオプションのメモ。

オプションの説明を読んでもいまいちピンと来なかった。

どうやらpassword_expiredが'Y'になっている(rpmとかでインストールした時はこうなる)と、
非対話モードでのログインができないらしい。

とりあえずためす。

mysql56> grant all on *.* to test;
Query OK, 0 rows affected (0.05 sec)

mysql56> alter user test password expire;
Query OK, 0 rows affected (0.00 sec)

$ mysql -utest -e "select current_user()"
ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.

# mysql -utest --connect-expired-password -e "select current_user()"
ERROR 1820 (HY000) at line 1: You must SET PASSWORD before executing this statement

おおー、ホントだー。

これがあるからmysql_secure_installation
(Perl、内部でsystem("mysql .. < $command");って呼び方をしてる)
が動かなくて、今回動くようになったっていうBug Fixなのか。。

にしても、mysql_secure_installation使ってる人いるのかな?
個人的には手間がなくて便利なんだけれども、gtid-mode=ONにしてると怒られるから
(MyISAMなmysql.userテーブルを直接叩くので、gitd-mode=ONだとunsafeって言われて転ける)
使わなくなっちゃった感じです。5.5までは常用してた。

mysqld_safeは如何にしてmysqldのダウンを検知するのか

LinuxとかUnixのMySQL-serverにくっついてくるmysqld_safe、コイツは内部でmysqldを呼ぶ
シェルスクリプトになっていて、環境変数の面倒とかulimitの面倒とかumaskの面倒とか見てくれたりする。

mysqldが落ちるとmysqld_safeがそれを検知して起動してくれるんだけど、
今までコイツがどうやってmysqldダウンを検知してるんだか知らなかった。

で、よくよく読んでみると、なんと

 フ ォ ア グ ラ ウ ン ド で m y s q l d を 起 動 し て る

から、mysqldが落ちた途端にmysqld_safeに制御が戻って、
(mysqldを起動した(=eval_log_error関数)直後にリスタートの処理が書いてある)
ほぼノータイムでmysqldのダウンを検知する。

まさかこんなに当たり前でシンプルな作りだとは。なんかシグナルもらってるんだとずっと思ってたよ。。


あと、mysqld_safeってSIGTERMで落ちないようになってるのね。
そういえばオプション無しのkillで落ちなかった気がする。