InnoDB Clusterは、MySQLの高可用性構成をサポートするMySQLの可用性フレームワークです。
まだLab版ですが、既にRCになっているMySQL Group Replication、GAになっているMySQL Router (GAはバージョンは1.x),MySQL Shell (DMR)を組み合わせて高可用性を実現しています。
基本的な動作は、MySQL Fabricに似ていますが、管理リポジトリー自体がGroup Replication内にあるので、デフォルトで冗長化されています。また、MySQL Router,MySQL Shell,MySQL Group Replicationが蜜に連携していて1つのHAパッケージのようになっています。まだ、十分に検証出来ていませんが、基本的な動作を確認したので、此方にメモしておきます。
※まだLab版なので、仕様は変わると思います。

innodb_cluster

ダウンロード
MySQL Labs :: MySQL InnoDB Cluster 5.7.15 Preview
※ インストール方法は、RPMが提供されているので割愛しています。

■ Sandboxインスタンスのデプロイ
※ Do not run MySQL Shell as root.
以下のdeployLocalInstanceコマンドで新規インスタンスが構築されます。


[root@replications admin]# su - mysql
最終ログイン: 2016/09/27 (火) 22:32:27 JST日時 pts/2
-bash-4.2$ mysqlsh
Welcome to MySQL Shell 1.0.5-labs Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> dba.deployLocalInstance(3310)
A new MySQL sandbox instance will be created on this host in 
/home/mysql/mysql-sandboxes/3310

Please enter a MySQL root password for the new instance: 
Deploying new MySQL instance...

Instance localhost:3310 successfully deployed and started.
Use '\connect root@localhost:3310' to connect to the instance.

mysql-js> dba.deployLocalInstance(3320) 
A new MySQL sandbox instance will be created on this host in 
/home/mysql/mysql-sandboxes/3320

Please enter a MySQL root password for the new instance: 
Deploying new MySQL instance...

Instance localhost:3320 successfully deployed and started.
Use '\connect root@localhost:3320' to connect to the instance.

mysql-js> dba.deployLocalInstance(3330)
A new MySQL sandbox instance will be created on this host in 
/home/mysql/mysql-sandboxes/3330

Please enter a MySQL root password for the new instance: 
Deploying new MySQL instance...

Instance localhost:3330 successfully deployed and started.
Use '\connect root@localhost:3330' to connect to the instance.

mysql-js> 


[root@replications mysql-sandboxes]# pwd
/home/mysql/mysql-sandboxes
[root@replications mysql-sandboxes]# ls -l
合計 12
drwxrwxr-x. 4 mysql mysql 4096  9月 27 17:25 3310
drwxrwxr-x. 4 mysql mysql 4096  9月 27 17:26 3320
drwxrwxr-x. 4 mysql mysql 4096  9月 27 17:27 3330
[root@replications mysql-sandboxes]# ls -l 3310/
合計 28
-rw-r-----. 1 mysql mysql    5  9月 27 17:25 3310.pid
drwxr-x---. 5 mysql mysql 4096  9月 27 17:25 data
-rw-------. 1 mysql mysql  806  9月 27 17:25 my.cnf
drwxrwxr-x. 2 mysql mysql    6  9月 27 17:25 mysql-files
srwxrwxrwx. 1 mysql mysql    0  9月 27 17:25 mysqld.sock
-rw-------. 1 mysql mysql    5  9月 27 17:25 mysqld.sock.lock
srwxrwxrwx. 1 mysql mysql    0  9月 27 17:25 mysqlx.sock
-rw-------. 1 mysql mysql    6  9月 27 17:25 mysqlx.sock.lock
-rwx------. 1 mysql mysql  121  9月 27 17:25 start.sh
-rwx------. 1 mysql mysql  186  9月 27 17:25 stop.sh
[root@replications mysql-sandboxes]# ls -l 3310/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:25 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:25 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:25 auto.cnf
-rw-r-----. 1 mysql mysql    14266  9月 27 17:25 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:25 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:25 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:25 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:25 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:25 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:25 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 sys
[root@replications mysql-sandboxes]# ls -l 3320/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:26 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:26 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:26 auto.cnf
-rw-r-----. 1 mysql mysql    14369  9月 27 17:26 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:26 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:26 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:26 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:26 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:26 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:26 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 sys
[root@replications mysql-sandboxes]# ls -l 3330/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:27 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:27 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:27 auto.cnf
-rw-r-----. 1 mysql mysql    13201  9月 27 17:27 error.log
-rw-r-----. 1 mysql mysql      359  9月 27 17:27 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:27 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 sys
[root@replications mysql-sandboxes]# ls -l 3330/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:27 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:27 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:27 auto.cnf
-rw-r-----. 1 mysql mysql    13201  9月 27 17:27 error.log
-rw-r-----. 1 mysql mysql      359  9月 27 17:27 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:27 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 sys
[root@replications mysql-sandboxes]# 

■ InnoDB Clusterの初期化
※Do not lose the MASTER key because it is required for managing the InnoDB cluster.
構築したインスタンスでグループレプリケーションを構築します。


mysql-js> \connect root@localhost:3310
Creating a Session to 'root@localhost:3310'
Enter password: 
Classic Session successfully established. No default schema selected.
mysql-js> cluster = dba.createCluster('test')
A new InnoDB cluster will be created on instance 'root@localhost:3310'.

When setting up a new InnoDB cluster it is required to define an administrative
MASTER key for the cluster. This MASTER key needs to be re-entered when making
changes to the cluster later on, e.g.adding new MySQL instances or configuring
MySQL Routers. Losing this MASTER key will require the configuration of all
InnoDB cluster entities to be changed.

Please specify an administrative MASTER key for the cluster 'test': 
Creating InnoDB cluster 'test' on 'root@localhost:3310'...
Adding Seed Instance...

Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

<Cluster:test>
mysql-js> 



[root@replications mysql-sandboxes]# ls -l 3310/data/
合計 122988
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000002
-rw-r-----. 1 mysql mysql    10397  9月 27 17:31 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:25 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:25 auto.cnf
-rw-r-----. 1 mysql mysql    21676  9月 27 17:31 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:25 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:31 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:25 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:31 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:31 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:25 mysql
drwxr-x---. 2 mysql mysql     4096  9月 27 17:31 mysql_innodb_cluster_metadata
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 performance_schema
-rw-r-----. 1 mysql mysql      232  9月 27 17:31 replications-relay-bin-group_replication_applier.000001
-rw-r-----. 1 mysql mysql      598  9月 27 17:31 replications-relay-bin-group_replication_applier.000002
-rw-r-----. 1 mysql mysql      116  9月 27 17:31 replications-relay-bin-group_replication_applier.index
-rw-r-----. 1 mysql mysql      150  9月 27 17:31 replications-relay-bin-group_replication_recovery.000001
-rw-r-----. 1 mysql mysql       59  9月 27 17:31 replications-relay-bin-group_replication_recovery.index
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 sys
[root@replications mysql-sandboxes]# ls -l 3320/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:26 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:26 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:26 auto.cnf
-rw-r-----. 1 mysql mysql    14369  9月 27 17:26 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:26 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:26 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:26 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:26 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:26 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:26 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 sys
[root@replications mysql-sandboxes]# ls -l 3330/data/
合計 122948
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000002
-rw-r-----. 1 mysql mysql      150  9月 27 17:27 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:27 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:27 auto.cnf
-rw-r-----. 1 mysql mysql    13201  9月 27 17:27 error.log
-rw-r-----. 1 mysql mysql      359  9月 27 17:27 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:27 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:27 mysql
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 performance_schema
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 sys
[root@replications mysql-sandboxes]# 

■ InnoDB Clusterへのインスタンスの追加
グループレプリケーションへインスタンスを追加します。


mysql-js> cluster.addInstance('root@localhost:3320')
A new instance will be added to the InnoDB cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Please provide the password for 'root@localhost:3320': 
Adding instance to the cluster ...

The instance 'root@localhost:3320' was successfully added to the cluster.

mysql-js> cluster.addInstance('root@localhost:3330')
A new instance will be added to the InnoDB cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Please provide the password for 'root@localhost:3330': 
Adding instance to the cluster ...

The instance 'root@localhost:3330' was successfully added to the cluster.

mysql-js> 


[root@replications mysql-sandboxes]# ls -l 3310/data/
合計 122988
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:25 ON.000002
-rw-r-----. 1 mysql mysql    12253  9月 27 17:36 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:25 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:25 auto.cnf
-rw-r-----. 1 mysql mysql    23760  9月 27 17:36 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:25 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:36 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:25 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:36 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:36 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:25 mysql
drwxr-x---. 2 mysql mysql     4096  9月 27 17:31 mysql_innodb_cluster_metadata
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 performance_schema
-rw-r-----. 1 mysql mysql      232  9月 27 17:31 replications-relay-bin-group_replication_applier.000001
-rw-r-----. 1 mysql mysql     1336  9月 27 17:36 replications-relay-bin-group_replication_applier.000002
-rw-r-----. 1 mysql mysql      116  9月 27 17:31 replications-relay-bin-group_replication_applier.index
-rw-r-----. 1 mysql mysql      150  9月 27 17:31 replications-relay-bin-group_replication_recovery.000001
-rw-r-----. 1 mysql mysql       59  9月 27 17:31 replications-relay-bin-group_replication_recovery.index
drwxr-x---. 2 mysql mysql     8192  9月 27 17:25 sys
[root@replications mysql-sandboxes]# ls -l 3320/data/
合計 122996
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:26 ON.000002
-rw-r-----. 1 mysql mysql    12129  9月 27 17:36 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:26 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:26 auto.cnf
-rw-r-----. 1 mysql mysql    24847  9月 27 17:37 error.log
-rw-r-----. 1 mysql mysql      362  9月 27 17:26 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:36 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:26 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:36 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:35 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:26 mysql
drwxr-x---. 2 mysql mysql     4096  9月 27 17:35 mysql_innodb_cluster_metadata
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 performance_schema
-rw-r-----. 1 mysql mysql      232  9月 27 17:35 replications-relay-bin-group_replication_applier.000001
-rw-r-----. 1 mysql mysql     2135  9月 27 17:36 replications-relay-bin-group_replication_applier.000002
-rw-r-----. 1 mysql mysql      116  9月 27 17:35 replications-relay-bin-group_replication_applier.index
-rw-r-----. 1 mysql mysql      233  9月 27 17:35 replications-relay-bin-group_replication_recovery.000001
-rw-r-----. 1 mysql mysql      269  9月 27 17:35 replications-relay-bin-group_replication_recovery.000002
-rw-r-----. 1 mysql mysql      118  9月 27 17:35 replications-relay-bin-group_replication_recovery.index
drwxr-x---. 2 mysql mysql     8192  9月 27 17:26 sys
[root@replications mysql-sandboxes]# ls -l 3330/data/
合計 122992
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000001
-rw-r-----. 1 mysql mysql      169  9月 27 17:27 ON.000002
-rw-r-----. 1 mysql mysql    12129  9月 27 17:36 ON.000003
-rw-r-----. 1 mysql mysql       36  9月 27 17:27 ON.index
-rw-r-----. 1 mysql mysql       56  9月 27 17:27 auto.cnf
-rw-r-----. 1 mysql mysql    22841  9月 27 17:36 error.log
-rw-r-----. 1 mysql mysql      359  9月 27 17:27 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:36 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648  9月 27 17:27 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:36 ibdata1
-rw-r-----. 1 mysql mysql 12582912  9月 27 17:36 ibtmp1
drwxr-x---. 2 mysql mysql     4096  9月 27 17:27 mysql
drwxr-x---. 2 mysql mysql     4096  9月 27 17:36 mysql_innodb_cluster_metadata
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 performance_schema
-rw-r-----. 1 mysql mysql      232  9月 27 17:36 replications-relay-bin-group_replication_applier.000001
-rw-r-----. 1 mysql mysql     1202  9月 27 17:36 replications-relay-bin-group_replication_applier.000002
-rw-r-----. 1 mysql mysql      116  9月 27 17:36 replications-relay-bin-group_replication_applier.index
-rw-r-----. 1 mysql mysql      233  9月 27 17:36 replications-relay-bin-group_replication_recovery.000001
-rw-r-----. 1 mysql mysql      269  9月 27 17:36 replications-relay-bin-group_replication_recovery.000002
-rw-r-----. 1 mysql mysql      118  9月 27 17:36 replications-relay-bin-group_replication_recovery.index
drwxr-x---. 2 mysql mysql     8192  9月 27 17:27 sys
[root@replications mysql-sandboxes]# 


[root@replications mysql-sandboxes]# netstat -na | grep sandboxes
unix  2      [ ACC ]     STREAM     LISTENING     26245    /home/mysql/mysql-sandboxes/3310/mysqlx.sock
unix  2      [ ACC ]     STREAM     LISTENING     26250    /home/mysql/mysql-sandboxes/3310/mysqld.sock
unix  2      [ ACC ]     STREAM     LISTENING     22039    /home/mysql/mysql-sandboxes/3330/mysqlx.sock
unix  2      [ ACC ]     STREAM     LISTENING     22044    /home/mysql/mysql-sandboxes/3330/mysqld.sock
unix  2      [ ACC ]     STREAM     LISTENING     21930    /home/mysql/mysql-sandboxes/3320/mysqlx.sock
unix  2      [ ACC ]     STREAM     LISTENING     21935    /home/mysql/mysql-sandboxes/3320/mysqld.sock
[root@replications mysql-sandboxes]# 

■ InnoDB Clusterのステータス確認
全てのホストがONLINEでHAが構成されている事が確認出来る。


mysql-js> cluster.status()
{
    "clusterName": "test",
    "defaultReplicaSet": {
        "status": "Cluster tolerant to up to ONE failure.",
        "topology": {
            "localhost:3310": {
                "address": "localhost:3310",
                "status": "ONLINE",
                "role": "HA",
                "mode": "R/W",
                "leaves": {
                    "localhost:3320": {
                        "address": "localhost:3320",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    },
                    "localhost:3330": {
                        "address": "localhost:3330",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    }
                }
            }
        }
    }
}
mysql-js> 

Sandbox環境のGroup ReplicationはSingle Primary Modeで動いています。
It is a configuration mode for Group Replication that makes a single member act as a writeable master (PRIMARY) and the rest of the members act as hot-standbys (SECONDARY).
The group itself coordinates and configures itself automatically to determine which member will act as the PRIMARY, through a leader election mechanism.


-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6446 -e "show variables like 'group_replication_single_primary_mode'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------------+-------+
| Variable_name                         | Value |
+---------------------------------------+-------+
| group_replication_single_primary_mode | ON    |
+---------------------------------------+-------+
-bash-4.2$ 

-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6446 -e "show variables like 'group_replication_enforce_update_everywhere_checks'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------------------------------+-------+
| Variable_name                                      | Value |
+----------------------------------------------------+-------+
| group_replication_enforce_update_everywhere_checks | OFF   |
+----------------------------------------------------+-------+
-bash-4.2$ 

-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6447 -e "SELECT * FROM performance_schema.global_status WHERE VARIABLE_NAME='group_replication_primary_member'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------------+--------------------------------------+
| VARIABLE_NAME                    | VARIABLE_VALUE                       |
+----------------------------------+--------------------------------------+
| group_replication_primary_member | 944915c6-853a-11e6-8e3d-080027d65c57 |
+----------------------------------+--------------------------------------+
-bash-4.2$ 

■ MySQL Routerのデプロイ
MySQL Routerを起動させて、グループレプリケーションへの接続をコントロールします。


-bash-4.2$ sudo mysqlrouter --bootstrap localhost:3310
[sudo] password for mysql: 
Please enter the administrative MASTER key for the MySQL InnoDB cluster: 
MySQL Router has now been configured for the InnoDB cluster 'test'.

The following connection information can be used to connect to the cluster.

Classic MySQL protocol connections to cluster 'test':
- Read/Write Connections: localhost:6446
- Read/Only Connections: localhost:6447
-bash-4.2$ 


-bash-4.2$ mysqlrouter &
[1] 3615
-bash-4.2$ Logging to /var/log/mysqlrouter/mysqlrouter.log

-bash-4.2$ ps -ef | grep mysqlrouter
mysql     3615  3589  0 14:32 pts/1    00:00:00 mysqlrouter
mysql     3625  3589  0 14:32 pts/1    00:00:00 grep --color=auto mysqlrouter
-bash-4.2$ 

■ MySQLRouter経由でmysqlに接続し動作確認
mysqlshell経由


1) MySQL Shell経由

-bash-4.2$ mysqlsh --uri root@localhost:6446
Creating a Session to 'root@localhost:6446'
Enter password: 
Classic Session successfully established. No default schema selected.
Welcome to MySQL Shell 1.0.5-labs Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3310 |
+--------------+--------+
1 row in set (0.00 sec)
mysql-sql> 


-bash-4.2$ mysqlsh --uri root@localhost:6447
Creating a Session to 'root@localhost:6447'
Enter password: 
Classic Session successfully established. No default schema selected.
Welcome to MySQL Shell 1.0.5-labs Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3330 |
+--------------+--------+
1 row in set (0.00 sec)
mysql-sql>

2) MySQLコマンド経由での確認とステータスの確認


-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6446
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3310 |
+--------------+--------+
1 row in set (0.00 sec)

mysql> 


-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6447
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3320 |
+--------------+--------+
1 row in set (0.00 sec)

mysql> 



mysql-js> cluster.status()
{
    "clusterName": "test",
    "defaultReplicaSet": {
        "status": "Cluster tolerant to up to ONE failure.",
        "topology": {
            "localhost:3310": {
                "address": "localhost:3310",
                "status": "ONLINE",
                "role": "HA",
                "mode": "R/W",
                "leaves": {
                    "localhost:3320": {
                        "address": "localhost:3320",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    },
                    "localhost:3330": {
                        "address": "localhost:3330",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    }
                }
            }
        }
    }
}
mysql-js> 

mysql-js> cluster.describe();
{
    "clusterName": "test",
    "adminType": "local",
    "defaultReplicaSet": {
        "name": "default",
        "instances": [
            {
                "name": "localhost:3310",
                "host": "localhost:3310",
                "role": "HA"
            },
            {
                "name": "localhost:3320",
                "host": "localhost:3320",
                "role": "HA"
            },
            {
                "name": "localhost:3330",
                "host": "localhost:3330",
                "role": "HA"
            }
        ]
    }
}
mysql-js> 

■ フェイルオーバーの確認 (HA)
既存のマスターインスタンスをdba.killLocalInstanceでダウンさせてみる。


mysql-js> dba.killLocalInstance(3310)
The MySQL sandbox instance on this host in 
/home/mysql/mysql-sandboxes/3310 will be killed

Killing MySQL instance...

Instance localhost:3310 successfully killed.

mysql-js> 

– 書き込みの接続が3310から3320に代わっている事が確認出来ます。


-bash-4.2$ mysqlsh --uri root@localhost:6446
Creating a Session to 'root@localhost:6446'
Enter password: 
ERROR: 2003 (HY000): Can't connect to remote MySQL server on '127.0.0.1:6446'
-bash-4.2$ mysqlsh --uri root@localhost:6446
Creating a Session to 'root@localhost:6446'
Enter password: 
Classic Session successfully established. No default schema selected.
Welcome to MySQL Shell 1.0.5-labs Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3320 |
+--------------+--------+
1 row in set (0.00 sec)
mysql-sql> 



-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6446
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3320 |
+--------------+--------+
1 row in set (0.00 sec)

mysql> 


-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6447
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> select @@hostname,@@port;
+--------------+--------+
| @@hostname   | @@port |
+--------------+--------+
| replications |   3330 |
+--------------+--------+
1 row in set (0.00 sec)

mysql> 


-bash-4.2$ mysqlsh
Welcome to MySQL Shell 1.0.5-labs Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> \connect root@localhost:6446
Creating a Session to 'root@localhost:6446'
Enter password: 
Classic Session successfully established. No default schema selected.
mysql-js> cluster = dba.getCluster()
When the InnoDB cluster was setup, a MASTER key was defined in order to enable
performing administrative tasks on the cluster.

Please specify the administrative MASTER key for the default cluster: 
<Cluster:test>
mysql-js> cluster.status()
{
    "clusterName": "test",
    "defaultReplicaSet": {
        "status": "Cluster is NOT tolerant to any failures.",
        "topology": {
            "localhost:3320": {
                "address": "localhost:3320",
                "status": "ONLINE",
                "role": "HA",
                "mode": "R/W",
                "leaves": {
                    "localhost:3330": {
                        "address": "localhost:3330",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    },
                    "localhost:3310": {
                        "address": "localhost:3310",
                        "status": "OFFLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    }
                }
            }
        }
    }
}
mysql-js> cluster.describe();
{
    "clusterName": "test",
    "adminType": "local",
    "defaultReplicaSet": {
        "name": "default",
        "instances": [
            {
                "name": "localhost:3310",
                "host": "localhost:3310",
                "role": "HA"
            },
            {
                "name": "localhost:3320",
                "host": "localhost:3320",
                "role": "HA"
            },
            {
                "name": "localhost:3330",
                "host": "localhost:3330",
                "role": "HA"
            }
        ]
    }
}
mysql-js> 

■ 停止したインスタンスの再開


mysql-js> dba.startLocalInstance(3310)
The MySQL sandbox instance on this host in 
/home/mysql/mysql-sandboxes/3310 will be started

Starting MySQL instance...

Instance localhost:3310 successfully started.

mysql-js> cluster.status()
{
    "clusterName": "test",
    "defaultReplicaSet": {
        "status": "Cluster is NOT tolerant to any failures.",
        "topology": {
            "localhost:3320": {
                "address": "localhost:3320",
                "status": "ONLINE",
                "role": "HA",
                "mode": "R/W",
                "leaves": {
                    "localhost:3330": {
                        "address": "localhost:3330",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    },
                    "localhost:3310": {
                        "address": "localhost:3310",
                        "status": "OFFLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    }
                }
            }
        }
    }
}
mysql-js> 

■ インスタンスをInnoDB Clusterグループへ再参加


mysql-js> dba.validateInstance('root@localhost:3310')
Please provide a password for 'root@localhost:3310': 
Validating instance...


Running check command.
Checking Group Replication prerequisites.
* Comparing options compatibility with Group Replication... PASS
Server configuration is compliant with the requirements.
* Checking server version... PASS
Server is 5.7.15

* Checking that server_id is unique... PASS
The server_id is valid.


* Checking compliance of existing tables... PASS

The instance: localhost:3310 is valid for Cluster usage

mysql-js> cluster.rejoinInstance('root@localhost:3310')
Please provide the password for 'root@localhost:3310': 
The instance will try rejoining the InnoDB cluster. Depending on the original
problem that made the instance unavailable the rejoin, operation might not be
successful and further manual steps will be needed to fix the underlying
problem.

Please monitor the output of the rejoin operation and take necessary action if
the instance cannot rejoin.
mysql-js> cluster.status()
{
    "clusterName": "test",
    "defaultReplicaSet": {
        "status": "Cluster tolerant to up to ONE failure.",
        "topology": {
            "localhost:3320": {
                "address": "localhost:3320",
                "status": "ONLINE",
                "role": "HA",
                "mode": "R/W",
                "leaves": {
                    "localhost:3310": {
                        "address": "localhost:3310",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    },
                    "localhost:3330": {
                        "address": "localhost:3330",
                        "status": "ONLINE",
                        "role": "HA",
                        "mode": "R/O",
                        "leaves": {}
                    }
                }
            }
        }
    }
}
mysql-js> 

■ SQLクライアントを利用したデータ同期と参照用インスタンスへのラウンドロビンを確認。

1) データ作成


-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6446
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
+-------------------------------+
5 rows in set (0.00 sec)

mysql> create database test;
Query OK, 1 row affected (0.05 sec)

mysql> use test
Database changed
mysql> CREATE TABLE `InnoDB_Cluster` (
    -> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    -> `comment` varchar(100) NOT NULL,
    -> `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.05 sec)

mysql> show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
| test                          |
+-------------------------------+
6 rows in set (0.00 sec)

mysql> exit
Bye
-bash-4.2$ mysql -u root -p -h 127.0.0.1 -P 6447
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
| test                          |
+-------------------------------+
6 rows in set (0.00 sec)

mysql> 

■ データを1万件入れてます。

※ もし、参照側データベースにデータをINSERTしようとすると以下のようにエラーになる。
1290 (HY000): The MySQL server is running with the –super-read-only option so it cannot execute this statement
MySQL5.7からのsuper-read-onlyオプションが設定されている。

-bash-4.2$ python innodb_cluster.py 
Finish Creating Data
-bash-4.2$ 

■ 書き込み接続の確認(MySQL Routerの設定により、特定のマスターへ接続)

-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6446 -e 'select @@port,count(*) from test.InnoDB_Cluster'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+----------+
| @@port | count(*) |
+--------+----------+
|   3320 |    10000 |
+--------+----------+
-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6446 -e 'select @@port,count(*) from test.InnoDB_Cluster'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+----------+
| @@port | count(*) |
+--------+----------+
|   3320 |    10000 |
+--------+----------+
-bash-4.2$ 

■ 読み込み接続の確認(MySQL Routerの設定により、複数スレーブへのラウンドロビン接続)

-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6447 -e 'select @@port,count(*) from test.InnoDB_Cluster'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+----------+
| @@port | count(*) |
+--------+----------+
|   3330 |    10000 |
+--------+----------+
-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6447 -e 'select @@port,count(*) from test.InnoDB_Cluster'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+----------+
| @@port | count(*) |
+--------+----------+
|   3310 |    10000 |
+--------+----------+
-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6447 -e 'select @@port,count(*) from test.InnoDB_Cluster'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+----------+
| @@port | count(*) |
+--------+----------+
|   3330 |    10000 |
+--------+----------+
-bash-4.2$ 

■ その他参考:リポジトリー(各ノードで持っているので冗長化が取れている)

-bash-4.2$ mysql -u root -pP@33word -h 127.0.0.1 -P 6446
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 50
Server version: 5.7.15-labs-gr090-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> show databases;
+-------------------------------+
| Database                      |
+-------------------------------+
| information_schema            |
| mysql                         |
| mysql_innodb_cluster_metadata |
| performance_schema            |
| sys                           |
| test                          |
+-------------------------------+
6 rows in set (0.01 sec)

mysql> use mysql_innodb_cluster_metadata
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------------------------------+
| Tables_in_mysql_innodb_cluster_metadata |
+-----------------------------------------+
| clusters                                |
| hosts                                   |
| instances                               |
| replicasets                             |
| schema_version                          |
+-----------------------------------------+
5 rows in set (0.00 sec)

mysql> desc clusters;
+---------------------+------------------+------+-----+---------+----------------+
| Field               | Type             | Null | Key | Default | Extra          |
+---------------------+------------------+------+-----+---------+----------------+
| cluster_id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| cluster_name        | varchar(40)      | NO   | UNI | NULL    |                |
| default_replicaset  | int(10) unsigned | YES  | MUL | NULL    |                |
| description         | text             | YES  |     | NULL    |                |
| mysql_user_accounts | blob             | YES  |     | NULL    |                |
| options             | json             | YES  |     | NULL    |                |
| attributes          | json             | YES  |     | NULL    |                |
+---------------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

mysql> desc hosts;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| host_id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| host_name          | varchar(128)     | YES  |     | NULL    |                |
| ip_address         | varchar(45)      | YES  |     | NULL    |                |
| location           | varchar(256)     | NO   |     | NULL    |                |
| attributes         | json             | YES  |     | NULL    |                |
| admin_user_account | json             | YES  |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

mysql> desc instances;
+-------------------+---------------------------+------+-----+---------+----------------+
| Field             | Type                      | Null | Key | Default | Extra          |
+-------------------+---------------------------+------+-----+---------+----------------+
| instance_id       | int(10) unsigned          | NO   | PRI | NULL    | auto_increment |
| host_id           | int(10) unsigned          | NO   | MUL | NULL    |                |
| replicaset_id     | int(10) unsigned          | YES  | MUL | NULL    |                |
| mysql_server_uuid | varchar(40)               | NO   | UNI | NULL    |                |
| instance_name     | varchar(40)               | NO   | UNI | NULL    |                |
| role              | enum('HA','readScaleOut') | NO   |     | NULL    |                |
| weight            | float                     | YES  |     | NULL    |                |
| addresses         | json                      | NO   |     | NULL    |                |
| attributes        | json                      | YES  |     | NULL    |                |
| version_token     | int(10) unsigned          | YES  |     | NULL    |                |
| description       | text                      | YES  |     | NULL    |                |
+-------------------+---------------------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)

mysql> desc replicasets;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| replicaset_id   | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| cluster_id      | int(10) unsigned | NO   | MUL | NULL    |                |
| replicaset_type | enum('gr')       | NO   |     | NULL    |                |
| topology_type   | enum('pm','mm')  | NO   |     | pm      |                |
| replicaset_name | varchar(40)      | NO   |     | NULL    |                |
| active          | tinyint(1)       | NO   |     | NULL    |                |
| attributes      | json             | YES  |     | NULL    |                |
| description     | text             | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

mysql> desc schema_version;
+-------+--------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| major | int(1) | NO   |     | 0       |       |
| minor | int(1) | NO   |     | 0       |       |
+-------+--------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> 

■ その他参考:MySQL Router設定

[root@replications mysql-sandboxes]# cat /etc/mysqlrouter/mysqlrouter.conf 
[DEFAULT]
plugin_folder=/lib64/mysqlrouter
# logging_folder=/var/log/mysqlrouter

[logger]
level = INFO

[metadata_cache]
bootstrap_server_addresses=mysql://localhost:3310,mysql://localhost:3320,mysql://localhost:3330
user=mysql_innodb_cluster_reader
password=]yZQL(C7H7AU.x(2
metadata_cluster=test
ttl=300
metadata_replicaset=default

[routing:default_rw]
bind_port=6446
destinations=metadata-cache:///default?role=PRIMARY
mode=read-write

[routing:default_ro]
bind_port=6447
destinations=metadata-cache:///default?role=SECONDARY
mode=read-only
[root@replications mysql-sandboxes]# 


[root@replications mysql-sandboxes]# cat /etc/mysqlrouter/mysqlrouter.ini 
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# MySQL Router configuration file
#
# Documentation is available at
#    http://dev.mysql.com/doc/mysql-router/en/

[DEFAULT]
logging_folder = /var/log/mysqlrouter/
plugin_folder = /usr/lib64/mysqlrouter
runtime_folder = /var/run/mysqlrouter
config_folder = /etc/mysqlrouter

[logger]
level = info

# If no plugin is configured which starts a service, keepalive
# will make sure MySQL Router will not immediately exit. It is
# safe to remove once Router is configured.
[keepalive]
interval = 60
[root@replications mysql-sandboxes]# 

参考)
https://dev.mysql.com/doc/mysql-innodb-cluster/en/mysql-innodb-cluster-getting-started.html
http://wagnerbianchi.com/blog/?p=1229
http://wagnerbianchi.com/blog/?p=1259
https://www.pythian.com/blog/rejoining-node-mysqls-innodb-cluster/


MySQL Enterprise Auditのログローテーションについての追加の手法。
合わせて、NFS上に監査ログを設定していて、万が一NFSが一時的に切れてしまった場合の挙動の確認。

1) ログサイズによる自動ローテーション
audit_log_rotate_on_size

2) mysqlutilitiesを利用したローテーション
mysqlauditadmin.exe

上記は、前回のブログ記事で紹介。
MySQL Audit Logのローテーション

今回は、CRON等で定期的に実行して、自分のカスタマイズしたいようにログをシェルでローテーションする方法です。

3) 自分でSHELLを用意して運用する方法

概要はこちらのマニュアルページで紹介しています。
https://dev.mysql.com/doc/refman/5.7/en/audit-log-logging-control.html

By default, audit_log_rotate_on_size=0 and there is no log rotation. In this case, the audit log plugin closes and reopens the log file when the audit_log_flush value changes from disabled to enabled.
If audit_log_rotate_on_size is greater than 0, setting audit_log_flush has no effect. In this case, the audit log plugin closes and reopens its log file whenever a write to the file causes its size to exceed the audit_log_rotate_on_size value.

MySQLのaudit関連設定

parameter

実際に、以下の様にSHELLを作成してログのローテーション確認してみました。
audit.logがリネームされて、新しいaudit.logファイルが再作成されています。


[root@misc01 mysql]# ls -l
合計 396
-rw-r-----. 1 mysql mysql   2813  9月 21 23:19 audit.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd
[root@misc01 mysql]# ./audit_log_rotate.sh 
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@misc01 mysql]# ls -l
合計 400
-rw-r-----. 1 mysql mysql     47  9月 21 23:19 audit.log
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd

簡易版なので、適宜用途によって加工して利用して下さい。


[root@misc01 mysql]# cat audit_log_rotate.sh 
#!/bin/sh

#######################################
#
#    MySQL Aduit Log Rotate Shell
#
#######################################

TODAY=`date -d 'today' '+%Y-%m-%d'`
AUDIT_LOG=/home/mysql/audit_log_${TODAY}.log

# Archive and rotate audit.log
mv /home/mysql/audit.log ${AUDIT_LOG}

# Flush Audit Log for creating new log file.
mysql -u root -ppassword -e "SET GLOBAL audit_log_flush = ON;"

[root@misc01 mysql]# 


【その他、確認事項】
■ NFS上にaudit.logを配置して、運用中にNFSが切れてしまった場合の挙動の確認。

ログのローテションを確認する為に、一時的にaudit_log_rotate_on_sizeに最小限のサイズを設定しています。


root@localhost [(none)]> show variables like 'audit%';
+-----------------------------+-----------------------+
| Variable_name               | Value                 |
+-----------------------------+-----------------------+
| audit_log_buffer_size       | 1048576               |
| audit_log_connection_policy | ALL                   |
| audit_log_current_session   | OFF                   |
| audit_log_exclude_accounts  |                       |
| audit_log_file              | /home/mysql/audit.log |
| audit_log_filter_id         | 0                     |
| audit_log_flush             | OFF                   |
| audit_log_format            | NEW                   |
| audit_log_include_accounts  |                       |
| audit_log_policy            | ALL                   |
| audit_log_rotate_on_size    | 0                     |
| audit_log_statement_policy  | ALL                   |
| audit_log_strategy          | ASYNCHRONOUS          |
+-----------------------------+-----------------------+
13 rows in set (0.00 sec)

root@localhost [(none)]> set global audit_log_rotate_on_size=4096;
Query OK, 0 rows affected (0.00 sec)

root@localhost [(none)]> show variables like 'audit%';
+-----------------------------+-----------------------+
| Variable_name               | Value                 |
+-----------------------------+-----------------------+
| audit_log_buffer_size       | 1048576               |
| audit_log_connection_policy | ALL                   |
| audit_log_current_session   | OFF                   |
| audit_log_exclude_accounts  |                       |
| audit_log_file              | /home/mysql/audit.log |
| audit_log_filter_id         | 0                     |
| audit_log_flush             | OFF                   |
| audit_log_format            | NEW                   |
| audit_log_include_accounts  |                       |
| audit_log_policy            | ALL                   |
| audit_log_rotate_on_size    | 4096                  |
| audit_log_statement_policy  | ALL                   |
| audit_log_strategy          | ASYNCHRONOUS          |
+-----------------------------+-----------------------+
13 rows in set (0.01 sec)

root@localhost [(none)]> 


ログをリネームして一時的にMySQLからファイルを見えなくしています。この間にAudit対象のQueryを実行して、ローテーションサイズを超えてもadit.logが無いので監査ログは書き込まれません。


[root@misc01 mysql]# ls -l
合計 424
-rw-r-----. 1 mysql mysql    504  9月 22 21:52 audit.log
-rw-r-----. 1 mysql mysql   4466  9月 22 21:52 audit.log.14745487509667319.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487651271064.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487704909257.xml
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd

[root@misc01 mysql]# mv audit.log on_purpose_rename_audit.log
[root@misc01 mysql]# ls -l
合計 424
-rw-r-----. 1 mysql mysql   4466  9月 22 21:52 audit.log.14745487509667319.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487651271064.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487704909257.xml
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql    504  9月 22 21:52 on_purpose_rename_audit.log
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd
[root@misc01 mysql]# ls -l
合計 424
-rw-r-----. 1 mysql mysql   4466  9月 22 21:52 audit.log.14745487509667319.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487651271064.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487704909257.xml
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql    961  9月 22 21:53 on_purpose_rename_audit.log
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd
[root@misc01 mysql]# ls -l
合計 428
-rw-r-----. 1 mysql mysql   4466  9月 22 21:52 audit.log.14745487509667319.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487651271064.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487704909257.xml
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql   6902  9月 22 21:53 on_purpose_rename_audit.log
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd

NFSの接続が戻ったと仮定して、ログを元の名前に戻す。
21:56の段階でaudit.logが無かった時のデータがaudit.log.14745489750144595.xmlに書き込まれている。
ログローテーションのサイズ(4096)をオーバーしているがデータがロストしていない事が確認出来る。
また、新規でaudit.logが作成されている。ローテーションも設定サイズできちんと行われている。
audit.logに書き込めない間は、audit_log_bufferに蓄積されているようです。


[root@misc01 mysql]# mv on_purpose_rename_audit.log audit.log
[root@misc01 mysql]# ls -l
合計 440
-rw-r-----. 1 mysql mysql   1418  9月 22 21:56 audit.log
-rw-r-----. 1 mysql mysql   4466  9月 22 21:52 audit.log.14745487509667319.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487651271064.xml
-rw-r-----. 1 mysql mysql   4169  9月 22 21:52 audit.log.14745487704909257.xml
-rw-r-----. 1 mysql mysql  15594  9月 22 21:56 audit.log.14745489750144595.xml
-rw-r-----. 1 mysql mysql   2822  9月 21 23:19 audit_log_2016-09-21.log
-rwxr-xr-x. 1 root  root     391  9月 21 23:19 audit_log_rotate.sh
-rw-r-----. 1 mysql mysql  98304 11月 18  2015 osc_tablespace01.ibd
drwxrwxr-x. 2 mysql mysql      6  4月 29  2015 perl5
drwxrwxr-x. 2 mysql mysql   4096  4月 29  2015 ssl
-rw-r-----. 1 mysql mysql 163840  9月 19 21:43 user_tablespace01.ibd
-rw-r-----. 1 mysql mysql  65536  4月 22  2015 user_tablespace02.ibd
-rw-r-----. 1 mysql mysql  65536  4月 20  2015 user_tablespace02_8k.ibd
[root@misc01 mysql]# 

nfs


補足:ログに書けない間も、MySQLのステータス変数はカウントアップされている事がaudit_log_current_sizeから確認する事が出来ます。
ファイルを戻したタイミングで、ログがファイルに書き込まれ、audit_log_current_sizeは値が小さくなっている事が確認出来ます。

root@localhost [(none)]> show status like 'audit%';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| audit_log_current_size        | 15585 |
| audit_log_event_max_drop_size | 0     |
| audit_log_events              | 1     |
| audit_log_events_buffered     | 0     |
| audit_log_events_filtered     | 0     |
| audit_log_events_lost         | 0     |
| audit_log_events_written      | 59    |
| audit_log_total_size          | 28389 |
| audit_log_write_waits         | 0     |
+-------------------------------+-------+
9 rows in set (0.00 sec)

root@localhost [(none)]> show status like 'audit%';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| audit_log_current_size        | 1418  |
| audit_log_event_max_drop_size | 0     |
| audit_log_events              | 1     |
| audit_log_events_buffered     | 0     |
| audit_log_events_filtered     | 0     |
| audit_log_events_lost         | 0     |
| audit_log_events_written      | 62    |
| audit_log_total_size          | 29816 |
| audit_log_write_waits         | 0     |
+-------------------------------+-------+
9 rows in set (0.00 sec)

root@localhost [(none)]> 


ログポジションベースのレプリケーションの場合は、レプリケーション障害発生時にスレーブでSKIP処理を容易に行う事ができましたが、GTIDモードの場合は以下のように空のトランザクションを実行して、エラー対応をする必要がありました。

mysqlslavetrxを利用しない場合の例

root@localhost [sakila]> stop slave;
Query OK, 0 rows affected (0.03 sec)

root@localhost [sakila]> SET GTID_NEXT = "3edaa0b8-3e39-11e4-9df1-080027f5bf08:54";
Query OK, 0 rows affected (0.00 sec)

root@localhost [sakila]> begin; commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

root@localhost [sakila]> SET GTID_NEXT = "3edaa0b8-3e39-11e4-9df1-080027f5bf08:55";
Query OK, 0 rows affected (0.00 sec)

root@localhost [sakila]> begin; commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

root@localhost [sakila]> SET GTID_NEXT = AUTOMATIC;
Query OK, 0 rows affected (0.00 sec)

root@localhost [sakila]> start slave;
Query OK, 0 rows affected (0.02 sec)

多くのトランザクションをSKIPする場合は、何回もコミットを実行して空のトランザクションを作成しないといけなかったので、非常に面倒な操作でしたが、MySQL Utilitiesの1.6以降で準備されているmysqlslavetrxを利用すると、まとめて1回で複数のGTIDをスキップ出来るようになっています。これまで以上にGTIDでの運用がし易くなっているので、活用頂ければと思います。

[root@misc02 scripts]# ./mysqlslavetrx --help
MySQL Utilities mysqlslavetrx version 1.6.4 
License type: GPLv2

1) 先ずは、レプリケーションに問題が発生していない状況を確認

■ マスターの状況

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
+----+--------------------+------------+
3 rows in set (0.01 sec)

root@localhost [REPLI]> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.002412 |     3028 |              |                  | 2dde009f-d4dc-11e4-b437-0800279cea3c:1-222553 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
1 row in set (0.00 sec)

root@localhost [REPLI]> 

■Slaveの状況

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc02     |
|  2 | mysqlslavetrx - 02 | misc02     |
|  3 | mysqlslavetrx - 03 | misc02     |
+----+--------------------+------------+
3 rows in set (0.00 sec)

root@localhost [REPLI]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.113
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.002412
          Read_Master_Log_Pos: 3028
               Relay_Log_File: misc02-relay-bin.000133
                Relay_Log_Pos: 821
        Relay_Master_Log_File: mysql-bin.002412
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: REPLI
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 3028
              Relay_Log_Space: 3749
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 2dde009f-d4dc-11e4-b437-0800279cea3c
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 2dde009f-d4dc-11e4-b437-0800279cea3c:216437-222553
            Executed_Gtid_Set: 2d0d3b32-4269-11e6-aca7-0800275fa837:1-7,
2dde009f-d4dc-11e4-b437-0800279cea3c:1-222553
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

root@localhost [REPLI]> 

■スレーブでデータ変更し、レプリケーションの不整合を発生させてみます。

スレーブでデータをINSERT

root@localhost [REPLI]> insert into T_Sample01(memo) values('Inserted @ Slave');
Query OK, 1 row affected (0.00 sec)

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc02     |
|  2 | mysqlslavetrx - 02 | misc02     |
|  3 | mysqlslavetrx - 03 | misc02     |
|  4 | Inserted @ Slave   | misc02     |
+----+--------------------+------------+
4 rows in set (0.00 sec)

root@localhost [REPLI]> 

マスターの状況

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
+----+--------------------+------------+
3 rows in set (0.00 sec)

root@localhost [REPLI]> 

■上記の状況でマスターでデータを変更

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
+----+--------------------+------------+
3 rows in set (0.00 sec)

root@localhost [REPLI]> insert into T_Sample01(memo) values('mysqlslavetrx - 04');
Query OK, 1 row affected (0.01 sec)

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
|  4 | mysqlslavetrx - 04 | misc01     |
+----+--------------------+------------+
4 rows in set (0.00 sec)

root@localhost [REPLI]> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.002412 |     3395 |              |                  | 2dde009f-d4dc-11e4-b437-0800279cea3c:1-222554 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
1 row in set (0.00 sec)

root@localhost [REPLI]> 

SLAVEではReplicationエラーになっている。(Duplicate Key)

root@localhost [REPLI]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.113
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.002412
          Read_Master_Log_Pos: 3395
               Relay_Log_File: misc02-relay-bin.000133
                Relay_Log_Pos: 821
        Relay_Master_Log_File: mysql-bin.002412
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: REPLI
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1062
                   Last_Error: Could not execute Write_rows event on table REPLI.T_Sample01; Duplicate entry '4' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.002412, end_log_pos 3364
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 3028
              Relay_Log_Space: 4116
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 1062
               Last_SQL_Error: Could not execute Write_rows event on table REPLI.T_Sample01; Duplicate entry '4' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.002412, end_log_pos 3364
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 2dde009f-d4dc-11e4-b437-0800279cea3c
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 160808 10:31:59
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 2dde009f-d4dc-11e4-b437-0800279cea3c:216437-222554
            Executed_Gtid_Set: 2d0d3b32-4269-11e6-aca7-0800275fa837:1-8,
2dde009f-d4dc-11e4-b437-0800279cea3c:1-222553
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

root@localhost [REPLI]> 

マスターでデータをもう1件変更(不要ですが、GTIDのSKIPを分かり易くする為)

root@localhost [REPLI]> insert into T_Sample01(memo) values('mysqlslavetrx - 05');
Query OK, 1 row affected (0.00 sec)

root@localhost [REPLI]> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.002412 |     3762 |              |                  | 2dde009f-d4dc-11e4-b437-0800279cea3c:1-222555 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
1 row in set (0.00 sec)

root@localhost [REPLI]> 

■Slave側ではリレーログの受信まで出来て、SQL(Applier)スレッドがINSERTに失敗しているので、
Duplicate entry ‘4’ for key ‘PRIMARY’の処理だけSKIPしてみる。

【対象】
Retrieved_Gtid_Set: 2dde009f-d4dc-11e4-b437-0800279cea3c:216437-222555
Executed_Gtid_Set: 2d0d3b32-4269-11e6-aca7-0800275fa837:1-8,
2dde009f-d4dc-11e4-b437-0800279cea3c:1-222553

 対象: 2dde009f-d4dc-11e4-b437-0800279cea3c:222554

mysqlslavetrxで対象のGTID(トランザクション)をSKIP実行

[root@misc02 scripts]# ./mysqlslavetrx --gtid-set=2dde009f-d4dc-11e4-b437-0800279cea3c:222554 --slaves=admin:password@misc02
WARNING: Using a password on the command line interface can be insecure.
#
# GTID set to be skipped for each server:
# - misc02@3306: 2dde009f-d4dc-11e4-b437-0800279cea3c:222554
#
# Injecting empty transactions for 'misc02:3306'...
#
#...done.
#
[root@misc02 scripts]# 

補足:複数GTIDをスキップする場合は以下のようにハイフンでつなぎます。

# Skip the specified GTID set (three transaction: 10, 11, 12) on two slaves.
$ mysqlslavetrx –gtid-set=ee2655ae-2e88-11e4-b7a3-606720440b68:10-12 –slaves=rpl:pass@host2:3306,rpl:pass@host3:3306

SKIP後のレプリケーションの状況を確認(レプリケーションが停止している状況が解消されている)
※リトライカウントがオーバーしている場合は、STOP SLAVE, START SLAVEを実行してみて下さい。


root@localhost [REPLI]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.113
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.002412
          Read_Master_Log_Pos: 3762
               Relay_Log_File: misc02-relay-bin.000135
                Relay_Log_Pos: 454
        Relay_Master_Log_File: mysql-bin.002412
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: REPLI
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 3762
              Relay_Log_Space: 962
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 2dde009f-d4dc-11e4-b437-0800279cea3c
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 2dde009f-d4dc-11e4-b437-0800279cea3c:216437-222555
            Executed_Gtid_Set: 2d0d3b32-4269-11e6-aca7-0800275fa837:1-8,
2dde009f-d4dc-11e4-b437-0800279cea3c:1-222555
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc02     |
|  2 | mysqlslavetrx - 02 | misc02     |
|  3 | mysqlslavetrx - 03 | misc02     |
|  4 | Inserted @ Slave   | misc02     |
|  5 | mysqlslavetrx - 05 | misc02     |
+----+--------------------+------------+
5 rows in set (0.00 sec)

root@localhost [REPLI]> 


以下、レプリケーション再開後のデータ修正例

■データ修正@SLAVE

root@localhost [REPLI]> set sql_log_bin = 0;
Query OK, 0 rows affected (0.00 sec)

root@localhost [REPLI]> update T_Sample01 set memo = 'mysqlslavetrx - 04' where id = 4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

root@localhost [REPLI]> set sql_log_bin = 1;
Query OK, 0 rows affected (0.00 sec)

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc02     |
|  2 | mysqlslavetrx - 02 | misc02     |
|  3 | mysqlslavetrx - 03 | misc02     |
|  4 | mysqlslavetrx - 04 | misc02     |
|  5 | mysqlslavetrx - 05 | misc02     |
+----+--------------------+------------+
5 rows in set (0.00 sec)

root@localhost [REPLI]> 

■データ修正後の動作確認@マスター

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
|  4 | mysqlslavetrx - 04 | misc01     |
|  5 | mysqlslavetrx - 05 | misc01     |
+----+--------------------+------------+
5 rows in set (0.00 sec)

root@localhost [REPLI]> insert into T_Sample01(memo) values('mysqlslavetrx - 06');
Query OK, 1 row affected (0.00 sec)

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc01     |
|  2 | mysqlslavetrx - 02 | misc01     |
|  3 | mysqlslavetrx - 03 | misc01     |
|  4 | mysqlslavetrx - 04 | misc01     |
|  5 | mysqlslavetrx - 05 | misc01     |
|  6 | mysqlslavetrx - 06 | misc01     |
+----+--------------------+------------+
6 rows in set (0.01 sec)

root@localhost [REPLI]> 

■SLAVE

root@localhost [REPLI]> select *,@@hostname from T_Sample01;
+----+--------------------+------------+
| id | memo               | @@hostname |
+----+--------------------+------------+
|  1 | mysqlslavetrx - 01 | misc02     |
|  2 | mysqlslavetrx - 02 | misc02     |
|  3 | mysqlslavetrx - 03 | misc02     |
|  4 | mysqlslavetrx - 04 | misc02     |
|  5 | mysqlslavetrx - 05 | misc02     |
|  6 | mysqlslavetrx - 06 | misc02     |
+----+--------------------+------------+
6 rows in set (0.01 sec)

root@localhost [REPLI]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.113
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.002412
          Read_Master_Log_Pos: 4129
               Relay_Log_File: misc02-relay-bin.000135
                Relay_Log_Pos: 821
        Relay_Master_Log_File: mysql-bin.002412
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: REPLI
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 4129
              Relay_Log_Space: 1329
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 2dde009f-d4dc-11e4-b437-0800279cea3c
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 2dde009f-d4dc-11e4-b437-0800279cea3c:216437-222556
            Executed_Gtid_Set: 2d0d3b32-4269-11e6-aca7-0800275fa837:1-8,
2dde009f-d4dc-11e4-b437-0800279cea3c:1-222556
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

root@localhost [REPLI]> 

詳細:
3.4.7 How do you fix errant transactions on the replication topology?


MySQL Shell経由でPythonで書いた処理をそのまま流し込めるので、
Twitter APIからJSONデータを取得して100件程データベースに流し込むデモを行いました。
PS: ネットワークがなぜか、共有WIFI、プライベートWIFI共に調子が悪く微妙な感じになってしまいましたが。。。

JSONデータ型、Generated Column(生成列)、MySQL Shellの挙動を簡易的にデモするものなので内容的には微妙ですが、
もしAPI経由でJSONデータを取得して、バッチ処理で定期的にサービスで使えそうなデータを取得して、
データを蓄積したり検索したい場合などに使えるかもしれません。

demo

————————————————————————
1) Create a Sample Table for Importing Data from Twitter API
————————————————————————
name列は、Tweetした人の名前が入ります。
text列は、Tweetしたコメントが入ります。


Create Table: CREATE TABLE `X_PYTHON` (
  `doc` json DEFAULT NULL,
  `_id` varchar(32) GENERATED ALWAYS AS (json_unquote(json_extract(`doc`,'$._id'))) STORED NOT NULL,
  `name` varchar(64) GENERATED ALWAYS AS (json_unquote(json_extract(`doc`,'$.user.name'))) STORED,
  `text` varchar(512) GENERATED ALWAYS AS (json_unquote(json_extract(`doc`,'$.text'))) STORED,
  UNIQUE KEY `_id` (`_id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

————————————————————————
2) Create python file ( demo_python_twitter.py )
————————————————————————
デモ用サンプルなので色々とコメントアウトしてます。またエラー処理も入れてません。
動作確認のみでご利用下さい。
※ Twitterキー、スキーマ、アカウントに関しては、適宜変更して下さい。
※ 必要に応じて、”pip install requests-oauthlib”でOauthもインストールしておいてください。


# coding: utf-8

print "======================================================"
print "MySQL5.7.12 Basic CRUD Operations by Python"
print "MySQL Innovation Daysデモ"
print "======================================================"

from requests_oauthlib import OAuth1Session
import json
import mysqlx

##############################################################
#    This section is just used for my private account.
##############################################################

api_key      = "Please put your own key"
api_secret   = "Please put your own key"
token        = "Please put your own key"
token_secret = "Please put your own key"

##############################################################
#    This section is API and Auth.
##############################################################

url = "https://api.twitter.com/1.1/statuses/home_timeline.json"
params = {'count':'100',}

auth = OAuth1Session(api_key, api_secret, token, token_secret)
res = auth.get(url, params = params)

##############################################################
#     Connect Session to the MySQL Instance.
##############################################################

if res.status_code == 200: # In case of successfully connect to API

 mySession = mysqlx.getSession({
 'host': 'localhost', 'port': 33060,
 'dbUser': 'demo_user', 'dbPassword': 'password'} )
 myDb = mySession.getSchema('NEW57')


### Create a new collection 'my_collection' ###
### This section is turned off for demo.    ###
# myColl = myDb.createCollection('X_PYTHON')


### Insert documents ###

 timeline = json.loads(res.text)
 for tweet in timeline:
   myDb.X_PYTHON.add(tweet).execute()
#  myDb.X_PYTHON.add(tweet).executeAsync() # ASYNCはmysqlshでは対象外.
#  print(tweet["text"])


####################################################
###         Drop the collection(Table)
####################################################
# mySession.dropCollection('NEW57','X_PYTHON')

else: # 失敗した場合
        print ("Error: %d" % req.status_code)

————————————————————————
3) Please Execute the Script through mysqlsh
————————————————————————
こちらは、Pythonモードで処理しています。


mysqlsh --py < demo_python_twitter.py

————————————————————————
4) You can find who is the most active user in twitter.
————————————————————————
mysqlshではパイプでつないで、リダイレクトする事が出来ます。


echo "select name,count(name) from X_PYTHON group by name order by count(name) desc limit 10;" | mysqlsh -u demo_user -ppassword --sql --schema=NEW57

実行結果(直近100件のTweet件数毎のデータ確認)


mysqlx: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------------+-------------+
| name                                  | count(name) |
+---------------------------------------+-------------+
<snip>
| Tony Darnell                          |          13 |
| Giuseppe Maxia                        |           2 |
| planetmysql                           |           2 |
<snip>

name以外にtextにも生成列を設定しているので、コメントをフィルターする事も出来ます。
簡易デモなので何ですが、実用的な用途があれば簡単にJSONデータ処理出来るので色々なケースで使えるかもしれません。


root@localhost [NEW57]> desc X_PYTHON;
+-------+--------------+------+-----+---------+------------------+
| Field | Type         | Null | Key | Default | Extra            |
+-------+--------------+------+-----+---------+------------------+
| doc   | json         | YES  |     | NULL    |                  |
| _id   | varchar(32)  | NO   | PRI | NULL    | STORED GENERATED |
| name  | varchar(64)  | YES  | MUL | NULL    | STORED GENERATED |
| text  | varchar(512) | YES  |     | NULL    | STORED GENERATED |
+-------+--------------+------+-----+---------+------------------+
4 rows in set (0.00 sec)

root@localhost [NEW57]> 

【補足資料】
先日、MyNA(MySQL User Group)のイベントでMySQL AS Document Storeのデモした時の資料です。


先日は、mysqlxプラグインをMySQL Shellから処理して基本動作確認しました。
mysqlxとMySQL Shell初期設定と基本動作確認
本日は、mysqlxに対応しているConnector/Node.jsからMySQLにJSONデータを処理を確認してみました。
基本的には、JohannesさんがMySQL Server Blogに書いた記事をベースに検証しています。
http://mysqlserverteam.com/mysql-5-7-12-part-5-connectornode-js/

【mysqlxとConnector/Node.jsを利用する為の前提条件】
MySQL 5.7.12 or higher, with the X plugin enabled
Node.JS 4.2

Download Connector/Node.js
~概要~
Connector/Node.js is the official Node.js driver for MySQL.
MySQL Connector/Node.js is an native asychronous promise-based client library for the of
MySQL 5.7.12+ providing New CRUD APIs for Document and Relational development

http://dev.mysql.com/downloads/connector/nodejs/

設定前の各種バージョン確認


[root@misc01 nodejs]# node -v
v4.4.3
[root@misc01 nodejs]# npm -v
2.15.1
[root@misc01 nodejs]# 

admin@192.168.56.113 [NEW57]> select @@version;
+-------------------------------------------+
| @@version                                 |
+-------------------------------------------+
| 5.7.12-enterprise-commercial-advanced-log |
+-------------------------------------------+
1 row in set (0.01 sec)

admin@192.168.56.113 [NEW57]> select PLUGIN_NAME,PLUGIN_VERSION,PLUGIN_STATUS,PLUGIN_TYPE_VERSION from information_schema.plugins
    -> where PLUGIN_NAME = 'mysqlx';
+-------------+----------------+---------------+---------------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_STATUS | PLUGIN_TYPE_VERSION |
+-------------+----------------+---------------+---------------------+
| mysqlx      | 1.0            | ACTIVE        | 50712.0             |
+-------------+----------------+---------------+---------------------+
1 row in set (0.01 sec)

admin@192.168.56.113 [NEW57]> 

ダウンロード
node.jsもMySQLもコネクター対応している事が確認出来たので、コネクターをダウンロードしてインストールしてみます。


[root@misc01 nodejs]# wget http://dev.mysql.com/get/Downloads/Connector-Nodejs/mysql-connector-nodejs-1.0.2.tar.gz
--2016-04-18 11:00:12--  http://dev.mysql.com/get/Downloads/Connector-Nodejs/mysql-connector-nodejs-1.0.2.tar.gz
dev.mysql.com (dev.mysql.com) をDNSに問いあわせています... 137.254.60.11
dev.mysql.com (dev.mysql.com)|137.254.60.11|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 302 Found
場所: http://cdn.mysql.com//Downloads/Connector-Nodejs/mysql-connector-nodejs-1.0.2.tar.gz [続く]
--2016-04-18 11:00:18--  http://cdn.mysql.com//Downloads/Connector-Nodejs/mysql-connector-nodejs-1.0.2.tar.gz
cdn.mysql.com (cdn.mysql.com) をDNSに問いあわせています... 104.78.21.123
cdn.mysql.com (cdn.mysql.com)|104.78.21.123|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 121705 (119K) [application/x-tar-gz]
`mysql-connector-nodejs-1.0.2.tar.gz' に保存中
100%[==============================================================================================>] 121,705      157KB/s 時間 0.8s   
2016-04-18 11:00:19 (157 KB/s) - `mysql-connector-nodejs-1.0.2.tar.gz' へ保存完了 [121705/121705]
[root@misc01 nodejs]# 

npmを使用してインストール
http://dev.mysql.com/doc/dev/connector-nodejs/
http://dev.mysql.com/doc/dev/connector-nodejs/tutorial-Getting_Started.html


[root@misc01 nodejs]# npm install mysql-connector-nodejs-1.0.2.tar.gz
mysqlx@1.0.2 node_modules/mysqlx
[root@misc01 nodejs]# 

シェルのサンプルを利用した基本動作確認

[root@misc01 nodejs]# cat sample_node_X_API.js 
const mysqlx = require('mysqlx');

mysqlx.getSession({
    host: 'localhost',
    port: 33060,
    dbUser: 'demo_user',
    dbPassword: 'password'
}).then(function (session) {
    return session.createSchema("test_schema").then(function (schema) {
        return schema.createCollection("myCollection");
    }).then(function (collection) {
        return Promise.all([
            collection.add(
                {baz: { foo: "bar"}},
                {foo: { bar: "baz"}}
            ).execute(),
            collection.find("$.baz.foo == 'bar'").execute(function (row) {
                console.log("Row: %j", row);
            }).then(function (res) {
                console.log("Collection find done!");
            }),
            collection.remove("($.foo.bar) == 'baz'").execute().then(function () {
                console.log("Document deleted");
            }),
            collection.drop()
        ]);
    }).then(function () {
        return session.dropSchema("test_schema");
    }).then(function () {
        return session.close();
    });
}).catch(function (err) {
    console.log(err.stack);
    process.exit();
});

上記スクリプトを実行


[root@misc01 nodejs]# node sample_X_API.js 
Row: {"_id":"d0ef5b1d-86e6-34b2-5794-3ebcab02","baz":{"foo":"bar"}}
Collection find done!
Document deleted
[root@misc01 nodejs]# 

実行すると、以下のオブジェクトとデータがmysqlx経由(33060)でjavascriptから登録されている

admin@192.168.56.113 [test_schema]> show tables;
+-----------------------+
| Tables_in_test_schema |
+-----------------------+
| myCollection          |
+-----------------------+
1 row in set (0.01 sec)

admin@192.168.56.113 [test_schema]> select * from myCollection;
+--------------------------------------------------------------------+----------------------------------+
| doc                                                                | _id                              |
+--------------------------------------------------------------------+----------------------------------+
| {"_id": "21dddfdd-2d4e-3cf1-fc5f-05a0e9ea", "foo": {"bar": "baz"}} | 21dddfdd-2d4e-3cf1-fc5f-05a0e9ea |
| {"_id": "7a7a7497-95c8-b7e7-fa15-064a8aba", "baz": {"foo": "bar"}} | 7a7a7497-95c8-b7e7-fa15-064a8aba |
+--------------------------------------------------------------------+----------------------------------+
2 rows in set (0.00 sec)

admin@192.168.56.113 [test_schema]> 

MySQLXのClassは以下のページを参照してください。
http://dev.mysql.com/doc/dev/connector-nodejs/NodeSession.html

その他、幾つかのパターンを検証してみましたが、node.js経由でJSONドキュメントデータをプラグイン経由で処理する事が可能なので、
JSONドキュメント処理をXプロトコル経由で高速に処理出来そうです。ただ、SQL処理とSQLX経由の処理に関しては、自分の方では実際のベンチマークは行っていないので、
Dimitriさんがブログで結果を発表してくれるのを待とうかと思います。
まだリリース間もないので、色々と情報を集めて紹介出来ればと思います。


先日、リリースされたMySQL5.7.12に含まれるmysqlxプラグインと、
同時にリリースされた、MySQL Shellの初期設定と基本動作確認を確認してみました。
基本的にこれらは、MySQL5.7で追加されたJSONデータ型を含むスキーマレスなドキュメントデータを、
mysqlxプラグインを利用する事でより柔軟に処理出来るようにする為に追加され、
MySQLをドキュメントデータベースとしてより利用し易くする為に追加された機能となっています。

MySQL Shellは、MySQLサーバの開発と管理をサポートする、
JavaScript、Python、SQLの対話型のインタフェースをサポートするMySQLの新しいコンポーネント。
データのクエリと更新処理だけでなく、様々な管理操作を実行する為にMySQLのシェルを使用することができます。
※MySQL Shellを利用する為には、事前にMySQL5.7.12以降に含まれているXプラグインをインストールしておく必要があります。

Xプラグイン
Xプロトコルを使用して通信を可能にするMySQLサーバプラグイン。
X DevAPIを実装するクライアントをサポートし、ドキュメントストアとしてMySQLを使用することができます。

Xプロトコル
Xプロトコルは、Xプラグインを実行しているMySQLサーバーと通信します。
Xプロトコルは、SSL経由でCRUDとSQL操作、認証の両方をサポートしていて、
コマンドのストリーミング処理を可能にし、プロトコルとメッセージレイヤ上に拡張可能。

root@localhost [information_schema]> select PLUGIN_NAME,PLUGIN_VERSION,PLUGIN_DESCRIPTION from plugins
    -> where PLUGIN_NAME = 'mysqlx';
+-------------+----------------+--------------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_DESCRIPTION |
+-------------+----------------+--------------------+
| mysqlx      | 1.0            | X Plugin for MySQL |
+-------------+----------------+--------------------+
1 row in set (0.00 sec)

root@localhost [information_schema]> 

【X Pluginインストール】
参照:http://dev.mysql.com/doc/refman/5.7/en/x-plugin-installation.html

通常通り、INSTALL PLUGINコマンドでインストール

root@localhost [mysql]> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';
Query OK, 0 rows affected (0.25 sec)

root@localhost [mysql]> show plugins;
+----------------------------+----------+--------------------+-------------------+-------------+
| Name                       | Status   | Type               | Library           | License     |
+----------------------------+----------+--------------------+-------------------+-------------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL              | PROPRIETARY |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL              | PROPRIETARY |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL              | PROPRIETARY |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL              | PROPRIETARY |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL              | PROPRIETARY |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL              | PROPRIETARY |
<SNIP>
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL              | PROPRIETARY |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL              | PROPRIETARY |
| ngram                      | ACTIVE   | FTPARSER           | NULL              | PROPRIETARY |
| mecab                      | ACTIVE   | FTPARSER           | libpluginmecab.so | PROPRIETARY |
| MYSQL_FIREWALL             | ACTIVE   | AUDIT              | firewall.so       | PROPRIETARY |
| MYSQL_FIREWALL_USERS       | ACTIVE   | INFORMATION SCHEMA | firewall.so       | PROPRIETARY |
| MYSQL_FIREWALL_WHITELIST   | ACTIVE   | INFORMATION SCHEMA | firewall.so       | PROPRIETARY |
| mysqlx                     | ACTIVE   | DAEMON             | mysqlx.so         | PROPRIETARY |
+----------------------------+----------+--------------------+-------------------+-------------+
49 rows in set (0.00 sec)

root@localhost [mysql]> 

【X Plugin オプションと変数について】
設定パラメータに関しては、此方を参照下さい。
http://dev.mysql.com/doc/refman/5.7/en/x-plugin-option-variable-reference.html

【接続方法】
既に、mysqlshをインストール済みなので –sqlオプションを仕様してSQLを流し込んでみる。
mysqlxのPort33060(Default:mysqlx_port)から、ローカルのMySQLにアクセスしてSQLを実行しています。

【サンプルデータベース作成】
参照:
http://downloads.mysql.com/docs/world_x-db.zip
http://dev.mysql.com/doc/refman/5.7/en/mysql-shell-tutorial-javascript-download.html

mysqlsh経由でサンプルデータベースの作成して、mysqlクライアントで接続してスキーマとテーブルの確認

[root@misc01 MID2016]# mysqlsh -u admin -p --sql --recreate-schema world_x < world_x.sql
Enter password: 
Recreating schema world_x...

[root@misc01 MID2016]# mysql -u root -p -e "show databases like 'world%'"
Enter password: 
+-------------------+
| Database (world%) |
+-------------------+
| world             |
| world2            |
| world_x           |
+-------------------+
[root@misc01 MID2016]# mysql -u root -p -e "show tables from world_x"
Enter password: 
+-------------------+
| Tables_in_world_x |
+-------------------+
| City              |
| Country           |
| CountryInfo       |
| CountryLanguage   |
+-------------------+

【接続モード】
参考) 接続方法としては、現状では、以下のモードを選択できるようです。

# mysqlsh --help
MySQL Shell 1.0.3 Development Preview

<SNIP>

  --sql                    Start in SQL mode using a node session.
  --sqlc                   Start in SQL mode using a classic session.
  --js                     Start in JavaScript mode.
  --py                     Start in Python mode.

<SNIP>

こちらでは、mysqlsh経由でjava scriptモードの状態でJSONデータを処理してみます。


[root@misc01 MID2016]# mysqlsh -u admin -p 
Creating an X Session to admin@localhost:33060
Enter password: 
No default schema selected.

Welcome to MySQL Shell 1.0.3 Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> news_collection = session.getSchema('NEW57').createCollection("X_JSON");
<Collection:X_JSON>
mysql-js> news_collection.add({"id": 1, "name": "Document Data", "price": 60000, "Conditions": ["NEW", 2016]});
Query OK, 1 item affected (0.01 sec)

mysql-js> news_collection.find('name like :n').bind('n','Document%');
[
    {
        "Conditions": [
            "NEW",
            2016
        ],
        "_id": "26c8af795703e611630c0800279cea3c",
        "id": 1,
        "name": "Document Data",
        "price": 60000
    }
]
1 document in set (0.03 sec)

mysql-js>  

MySQLに接続してデータを確認した状態


root@localhost [NEW57]> desc X_JSON;
+-------+-------------+------+-----+---------+------------------+
| Field | Type        | Null | Key | Default | Extra            |
+-------+-------------+------+-----+---------+------------------+
| doc   | json        | YES  |     | NULL    |                  |
| _id   | varchar(32) | NO   | PRI | NULL    | STORED GENERATED |
+-------+-------------+------+-----+---------+------------------+
2 rows in set (0.00 sec)

root@localhost [NEW57]> select * from X_JSON\G
*************************** 1. row ***************************
doc: {"id": 1, "_id": "26c8af795703e611630c0800279cea3c", "name": "Document Data", "price": 60000, "Conditions": ["NEW", 2016]}
_id: 26c8af795703e611630c0800279cea3c
1 row in set (0.00 sec)

root@localhost [NEW57]> 

【Beta Draft】
X DevAPI User Guide / Overview
http://dev.mysql.com/doc/x-devapi-userguide/en/devapi-users-introduction.html
その他、X DevAPI経由でコーディング出来そう。但し、現時点ではベータリリースなのでもう少ししたら確認。

【その他:Status変数】
こちらで、mysqlx経由の処理を確認する事が可能です。


[root@misc01 MID2016]# mysql -u root -p -e "show status like 'mysqlx%'"
Enter password: 
+-------------------------------------+--------------------------+
| Variable_name                       | Value                    |
+-------------------------------------+--------------------------+
| Mysqlx_bytes_received               | 389773                   |
| Mysqlx_bytes_sent                   | 3466                     |
| Mysqlx_connection_accept_errors     | 0                        |
| Mysqlx_connection_errors            | 0                        |
| Mysqlx_connections_accepted         | 2                        |
| Mysqlx_connections_closed           | 2                        |
| Mysqlx_connections_rejected         | 0                        |
| Mysqlx_crud_delete                  | 0                        |
| Mysqlx_crud_find                    | 0                        |
| Mysqlx_crud_insert                  | 0                        |
| Mysqlx_crud_update                  | 0                        |
| Mysqlx_errors_sent                  | 1                        |
| Mysqlx_expect_close                 | 0                        |
| Mysqlx_expect_open                  | 0                        |
| Mysqlx_init_error                   | 1                        |
| Mysqlx_notice_other_sent            | 76                       |
| Mysqlx_notice_warning_sent          | 2                        |
| Mysqlx_rows_sent                    | 18                       |
| Mysqlx_sessions                     | 0                        |
| Mysqlx_sessions_accepted            | 1                        |
| Mysqlx_sessions_closed              | 1                        |
| Mysqlx_sessions_fatal_error         | 0                        |
| Mysqlx_sessions_killed              | 0                        |
| Mysqlx_sessions_rejected            | 1                        |
| Mysqlx_ssl_accepts                  | 0                        |
| Mysqlx_ssl_active                   |                          |
| Mysqlx_ssl_cipher                   |                          |
| Mysqlx_ssl_cipher_list              |                          |
| Mysqlx_ssl_ctx_verify_depth         | 18446744073709551615     |
| Mysqlx_ssl_ctx_verify_mode          | 5                        |
| Mysqlx_ssl_finished_accepts         | 0                        |
| Mysqlx_ssl_server_not_after         | Oct 19 05:28:15 2025 GMT |
| Mysqlx_ssl_server_not_before        | Oct 22 05:28:15 2015 GMT |
| Mysqlx_ssl_verify_depth             |                          |
| Mysqlx_ssl_verify_mode              |                          |
| Mysqlx_ssl_version                  |                          |
| Mysqlx_stmt_create_collection       | 0                        |
| Mysqlx_stmt_create_collection_index | 0                        |
| Mysqlx_stmt_disable_notices         | 0                        |
| Mysqlx_stmt_drop_collection         | 0                        |
| Mysqlx_stmt_drop_collection_index   | 0                        |
| Mysqlx_stmt_enable_notices          | 0                        |
| Mysqlx_stmt_execute_sql             | 69                       |
| Mysqlx_stmt_execute_xplugin         | 2                        |
| Mysqlx_stmt_kill_client             | 0                        |
| Mysqlx_stmt_list_clients            | 0                        |
| Mysqlx_stmt_list_notices            | 0                        |
| Mysqlx_stmt_list_objects            | 2                        |
| Mysqlx_stmt_ping                    | 0                        |
| Mysqlx_worker_threads               | 2                        |
| Mysqlx_worker_threads_active        | 0                        |
+-------------------------------------+--------------------------+
[root@misc01 MID2016]# 

参考までに、MySQL ShellのSQLモードの場合とjavascriptモードの場合では接続が3306か33060からの接続かどうかは以下のステータス変数でも確認する事が可能です。

【SQLモードの場合】


[root@misc01 MID2016]# echo "INSERT INTO T_UC01 VALUES (1,'mysql shell'),(2,'マイエスキュウエルシェル');" | mysqlsh -u demo_user -ppassword --sql --schema=world_x2
mysqlx: [Warning] Using a password on the command line interface can be insecure.
[root@misc01 MID2016]# 


root@localhost [sys]> show status like 'Mysqlx_crud%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Mysqlx_crud_delete | 0     |
| Mysqlx_crud_find   | 0     |
| Mysqlx_crud_insert | 0     |
| Mysqlx_crud_update | 0     |
+--------------------+-------+
4 rows in set (0.00 sec)

root@localhost [sys]> root@localhost [sys]> show status like 'Mysqlx_crud%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Mysqlx_crud_delete | 0     |
| Mysqlx_crud_find   | 0     |
| Mysqlx_crud_insert | 0     |
| Mysqlx_crud_update | 0     |
+--------------------+-------+
4 rows in set (0.00 sec)

root@localhost [sys]> 


【JavaScriptモードの場合】


[root@misc01 MID2016]# mysqlsh --uri demo_user@localhost/NEW57 -ppassword
mysqlx: [Warning] Using a password on the command line interface can be insecure.
Creating an X Session to demo_user@localhost:33060/NEW57
Default schema `NEW57` accessible through db.

Welcome to MySQL Shell 1.0.3 Development Preview

Copyright (c) 2016, 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', '\h' or '\?' for help.

Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries.
mysql-js> db.createCollection("x_posts");
<Collection:x_posts>
mysql-js> db.x_posts.add({"title":"Hello World", "text":"This is the first post via mysqlx"});
Query OK, 1 item affected (0.01 sec)

mysql-js> db.x_posts.find("title = 'Hello World'").sort(["title"]);
[
    {
        "_id": "d2c6eb188b08e6113d110800279cea3c",
        "text": "This is the first post via mysqlx",
        "title": "Hello World"
    }
]
1 document in set (0.00 sec)

mysql-js> 

mysqlx経由のCRUDの実行数が確認出来る。
INSERT x 1回
SELECT x 1回


root@localhost [sys]> show status like 'Mysqlx_crud%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Mysqlx_crud_delete | 0     |
| Mysqlx_crud_find   | 0     |
| Mysqlx_crud_insert | 0     |
| Mysqlx_crud_update | 0     |
+--------------------+-------+
4 rows in set (0.00 sec)

root@localhost [sys]> show status like 'Mysqlx_crud%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Mysqlx_crud_delete | 0     |
| Mysqlx_crud_find   | 1     |
| Mysqlx_crud_insert | 1     |
| Mysqlx_crud_update | 0     |
+--------------------+-------+
4 rows in set (0.01 sec)

root@localhost [sys]> 


【参考】
http://dev.mysql.com/doc/refman/5.7/en/mysql-shell.html
http://dev.mysql.com/doc/refman/5.7/en/document-store.html
http://dev.mysql.com/doc/dev/connector-nodejs/
http://mysqlserverteam.com/mysql-5-7-12-part-3-more-than-just-sql/
http://mysqlserverteam.com/mysql-5-7-12-part-4-a-new-mysql-command-line-shell/

メモ:Node.jsのサンプルもあるので、後日、別途JSONドキュメント処理を実施してみる。
http://dev.mysql.com/doc/dev/connector-nodejs/


NoSQL with MySQL Cluster
本日、話をさせて頂いた、MySQL Clusterにおけるトランザクション対応NoSQLについての資料です。

MySQL ClusterはMySQLとは基本的には異なるデータベースです。
NDB(Network Database)に対して、MySQLからもNoSQLからもデータ処理出来るデータベースがMySQL Clusterです。
MySQLからはもともとストレージエンジンを選択出来るデータベースシステムですが、
MySQLはndbclusterというストレージエンジンとしてNDBを利用しています。

NDBはNDB API (C++)を経由してアクセスする事で,MySQLから独立して利用する事が可能です。
MySQLサーバの観点からは,NDB Clusterは行のテーブルを格納するためのストレージエンジンです。
NDB Clusterの観点からは、MySQLサーバインスタンスがクラスタに接続されているAPIのプロセスの一つです。

概要図
ndb_diag

Storage Engine
storage_engines

ndbinfo
データは、冗長化と拡張性の為にデータノード間で分散されています。
その状況は、ndbinfoを確認する事でも確認可能です。

ndbinfo

検証
先ずは、MySQL Clusterをダウンロードして頂き、MySQL Clsuterを設定して下さい。
設定が終了したら、MySQL ClusterにSQLで接続しスキーマとテスト用のテーブルを作成して下さい。
NDB APIからNoSQLでもNDBにコマンドでテーブルを作成出来ますが、その場合はMySQLからオブジェクトを見る事が出来ません。
MySQLとNoSQL両方から使いたい場合は、MySQLにて先ずはオブジェクト作成して下さい。

Download MySQL Cluster
https://dev.mysql.com/downloads/cluster/

18.2.2. Linux での MySQL Cluster のインストール
https://dev.mysql.com/doc/refman/5.6/ja/mysql-cluster-install-linux.html

5分で作るMySQL Cluster環境
http://www.ospn.jp/osc2013-kyoto/pdf/osc2013kyoto_mysql2.pdf


mysql> use TEST_DB
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show create table employee\G
*************************** 1. row ***************************
       Table: employee
Create Table: CREATE TABLE `employee` (
  `id` int(11) NOT NULL,
  `first` varchar(64) DEFAULT NULL,
  `last` varchar(64) DEFAULT NULL,
  `municipality` varchar(64) DEFAULT NULL,
  `started` varchar(64) DEFAULT NULL,
  `ended` varchar(64) DEFAULT NULL,
  `department` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_u_hash` (`first`,`last`) USING HASH,
  KEY `idx_municipality` (`municipality`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

mysql> 

ClusterJ サンプルソース
MySQLClusterJ_Sample

MySQL Clusterへの接続文字列は適宜変更して下さい。
— com.mysql.clusterj.connectstring
— com.mysql.clusterj.database=TEST_DB

[SELL]

[root@Labs01 java]# cat clusterj.properties
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

com.mysql.clusterj.connectstring=192.168.56.114:1186
com.mysql.clusterj.database=TEST_DB
com.mysql.clusterj.connect.retries=4
com.mysql.clusterj.connect.delay=5
com.mysql.clusterj.connect.verbose=1
com.mysql.clusterj.connect.timeout.before=30
com.mysql.clusterj.connect.timeout.after=20
com.mysql.clusterj.max.transactions=1024
[root@Labs01 java]#

[/SHELL]

コンパイル
※ javacにてコンパイル時には、clusterj-api-7.x.x.jarを含める必要があります。
※ パスは適宜書き換えて下さい。


javac -classpath /mysql-cluster-gpl-7.4.6/746bin/share/java/clusterj-api-7.4.6.jar:. Main.java Employee.java

実行例


java -classpath /mysql-cluster-gpl-7.4.6/746bin/share/java/clusterj-7.4.6.jar:. -Djava.library.path=/mysql-cluster-gpl-7.4.6/746bin/lib Main

上記の実行内容は、先にスキーマをSQLから作成してあるのでSQLでも見る事が出来ます。

del_in

それ以外の方法としては、NDB用にMySQL Clusterに用意されている以下のコマンドを利用すると良いでしょう。

ndb_show_tables

ndb_show_tables

ndb_select_all

ndb_select_all

SQLが得意な処理は、SQLで処理して、Primary Keyベースでの特定のデータに対しての処理などは、
MySQL ClusterでのNoSQLで処理するという方法も選択出来ます。
NDB APIはC++ですので、C++が得意な方はそのままC++で書いて高速な処理を検証してみるのも良いかと思います。
※ネットワークは重要です、トラフィックが多い場合は10Gなどの高速なネットワークをご利用下さい。


mysql fabricにて書き込みのRANGEシャーディングしたテーブルから、
データを読み込みの確認。

分割定義


# Create Sharding Grop1
mysqlfabric group create shard1
mysqlfabric group add shard1 127.0.0.1:63304
mysqlfabric group add shard1 127.0.0.1:63305
mysqlfabric group add shard1 127.0.0.1:63306
mysqlfabric group promote shard1
mysqlfabric group activate shard1

# Create Sharding Group2
mysqlfabric group create shard2
mysqlfabric group add shard2 127.0.0.1:63307
mysqlfabric group add shard2 127.0.0.1:63308
mysqlfabric group add shard2 127.0.0.1:63309
mysqlfabric group promote shard2
mysqlfabric group activate shard2

# Add sharding to employee
mysqlfabric sharding add_table 1 test.employees emp_no
mysqlfabric sharding add_shard 1 shard1/1,shard2/300 --state=enabled

select_shard

それぞれのグループに分散されたテーブルからデータを読み込み
0 ~ 299は、shard1
300以上はshard2


# coding: utf-8

import mysql.connector 
from mysql.connector import fabric

import time

def find_employee(conn, emp_no):
    try:
       conn.set_property(tables=["test.employees"], key=str(emp_no), mode=fabric.MODE_READONLY, scope=fabric.SCOPE_LOCAL)
       cur = conn.cursor()
       cur.execute(
           "SELECT concat('Hostname:',@@hostname),concat(': ',@@port,' ; '), first_name, last_name "
           "FROM employees WHERE emp_no = %s", (emp_no,)
        )
    except mysql.connector.Error: 
       print "find_employee: Database connection error, trying to reconnect ..." 
       conn=connect() 
    for row in cur:
        print row[0],row[1],row[2],row[3]

# Address of the Fabric, not the host we are going to connect to.
def connect():
    try:
       conn=mysql.connector.connect(
          fabric={"host" : "localhost", "port" : 32274, "username": "admin", "password": "admin"},
          user="app", database="test", password="app",
          autocommit=True
       )
    except mysql.connector.Error as e: 
        print "Error trying to get a new database connection"
        print "Error code:", e.errno 
        print "SQLSTATE value:", e.sqlstate
        print "Error message:", e.msg
        quit()
    return conn

conn = connect()
for x in range(295, 310):
    find_employee(conn, x)


実行結果
メモ:それぞれのFabric Groupのスレーブから分散してデータを持ってきている。
select_shard_range


Pythonによる、乱数を用いたデータInsert処理確認

事前データ状況確認

mysql> select * from language;
+-------------+----------+---------------------+
| language_id | name     | last_update         |
+-------------+----------+---------------------+
|           1 | English  | 2006-02-15 05:02:19 |
|           2 | Italian  | 2006-02-15 05:02:19 |
|           3 | Japanese | 2014-07-15 16:14:50 |
|           4 | Mandarin | 2006-02-15 05:02:19 |
|           5 | French   | 2006-02-15 05:02:19 |
|           6 | German   | 2006-02-15 05:02:19 |
|           7 | Chinese  | 2014-08-04 11:36:23 |
|           8 | Korean   | 2014-08-04 14:20:16 |
|           9 | Ainu     | 2014-08-04 14:44:03 |
|          10 | Irish    | 2014-08-04 14:44:03 |
+-------------+----------+---------------------+
10 rows in set (0.00 sec)

mysql> 

乱数を用いてデータInsertする為に処理を入れる。
但し、データベースのテーブル内容とは関係無い文字列を利用しています。

$ vim mysql_loop.py
$ cat mysql_loop.py
# coding: utf-8

try:
 # import

 import mysql.connector
 import string
 from random import randrange

 # 接続
 connect = mysql.connector.connect(user='root', password='password', host='localhost', database='test', charset='utf8')

 # カーソル
 cursor = connect.cursor()
 # SQL 発行
 # cursor.execute('select language_id,name from language',())

  # Random Charactor Create
 LENGTH = 20
 alphabets = string.digits + string.letters

 def randstr(n):
     return ''.join(alphabets[randrange(len(alphabets))] for i in xrange(n))
 if __name__ == '__main__':

   randstr_ins =  randstr(LENGTH)
   insert_stmt = 'insert into language(name) values("%s")' % randstr_ins
   cursor.execute(insert_stmt)

 # connect.commit()

 # フェッチ
 #
 # rows = cursor.fetchall()
 # print(rows)
   connect.commit()
   cursor.close()
 # 切断
 connect.close()

except Exception as myout:

 print(myout)

$
$ python mysql_loop.py

20文字で作成された乱数文字が入力された事を確認。

mysql> select * from language;
+-------------+----------------------+---------------------+
| language_id | name                 | last_update         |
+-------------+----------------------+---------------------+
|           1 | English              | 2006-02-15 05:02:19 |
|           2 | Italian              | 2006-02-15 05:02:19 |
|           3 | Japanese             | 2014-07-15 16:14:50 |
|           4 | Mandarin             | 2006-02-15 05:02:19 |
|           5 | French               | 2006-02-15 05:02:19 |
|           6 | German               | 2006-02-15 05:02:19 |
|           7 | Chinese              | 2014-08-04 11:36:23 |
|           8 | Korean               | 2014-08-04 14:20:16 |
|           9 | Ainu                 | 2014-08-04 14:44:03 |
|          10 | Irish                | 2014-08-04 14:44:03 |
|          11 | bihnbj3Mr4xcRxtaJaDE | 2014-08-04 16:04:56 |
+-------------+----------------------+---------------------+
11 rows in set (0.00 sec)

mysql>

上記スクリプトの確認出来たので、データ作成用のLoopが動くか確認。
1) 事前データ確認

mysql> select * from language;
+-------------+----------------------+---------------------+
| language_id | name                 | last_update         |
+-------------+----------------------+---------------------+
|           1 | English              | 2006-02-15 05:02:19 |
|           2 | Italian              | 2006-02-15 05:02:19 |
|           3 | Japanese             | 2014-07-15 16:14:50 |
|           4 | Mandarin             | 2006-02-15 05:02:19 |
|           5 | French               | 2006-02-15 05:02:19 |
|           6 | German               | 2006-02-15 05:02:19 |
|           7 | Chinese              | 2014-08-04 11:36:23 |
|           8 | Korean               | 2014-08-04 14:20:16 |
|           9 | Ainu                 | 2014-08-04 14:44:03 |
|          10 | Irish                | 2014-08-04 14:44:03 |
|          11 | bihnbj3Mr4xcRxtaJaDE | 2014-08-04 16:04:56 |
|          12 | xadk5JJmgPLkw7kFQ2LT | 2014-08-04 16:10:46 |
+-------------+----------------------+---------------------+
12 rows in set (0.00 sec)

mysql>

2) PRINTコマンドで確認

$ vim mysql_loop.py
$ python mysql_loop.py
insert into language(name) values("t6hiIohEArPADMXA7P35")
insert into language(name) values("51akdy18UtKDJVeNXjdK")
insert into language(name) values("BiQnfmMX4hlBynVJpXKC")
insert into language(name) values("6NdLDWOS72vKy4hfYtgZ")
insert into language(name) values("j2WbDYCt63PO5XQtK5Qr")
insert into language(name) values("QR05Zd7Y8Y9EnKXFqjMr")
insert into language(name) values("JMIF6GKBF7yyHnVUxFc0")
insert into language(name) values("ScgelcWkaQVrLKkPkjtV")
insert into language(name) values("1bWLI0OMRv6CNEhe8Iax")
insert into language(name) values("ZTSCsBNyWqxN32ErJnxE")
Finish Creating Data

$ vim mysql_loop.py

3) PRINTをコメントして実際のSQLコマンド実行してみる。

$ cat mysql_loop.py
# coding: utf-8

try:
 # import

 import mysql.connector
 import string
 from random import randrange

 # 接続
 connect = mysql.connector.connect(user='root', password='password', host='localhost', database='test', charset='utf8')

 # カーソル
 cursor = connect.cursor()
 # SQL 発行
 # cursor.execute('select language_id,name from language',())

 for i in  range(0, 10):

  # Random Charactor Create
  LENGTH = 20
  alphabets = string.digits + string.letters

  def randstr(n):
      return ''.join(alphabets[randrange(len(alphabets))] for i in xrange(n))
  if __name__ == '__main__':

   randstr_ins =  randstr(LENGTH)
   insert_stmt = 'insert into language(name) values("%s")' % randstr_ins
   cursor.execute(insert_stmt)
   #print insert_stmt
   #connect.commit()

 else:
    print('Finish Creating Data')

 # フェッチ
 #
 # rows = cursor.fetchall()
 # print(rows)
 connect.commit()
 cursor.close()
 # 切断
 connect.close()

except Exception as myout:

 print(myout)

$
$ python mysql_loop.py
Finish Creating Data
$

4) Loopされた後にテーブルを確認してみて、テスト用のデータ作成確認

mysql> select * from language;
+-------------+----------------------+---------------------+
| language_id | name                 | last_update         |
+-------------+----------------------+---------------------+
|           1 | English              | 2006-02-15 05:02:19 |
|           2 | Italian              | 2006-02-15 05:02:19 |
|           3 | Japanese             | 2014-07-15 16:14:50 |
|           4 | Mandarin             | 2006-02-15 05:02:19 |
|           5 | French               | 2006-02-15 05:02:19 |
|           6 | German               | 2006-02-15 05:02:19 |
|           7 | Chinese              | 2014-08-04 11:36:23 |
|           8 | Korean               | 2014-08-04 14:20:16 |
|           9 | Ainu                 | 2014-08-04 14:44:03 |
|          10 | Irish                | 2014-08-04 14:44:03 |
|          11 | bihnbj3Mr4xcRxtaJaDE | 2014-08-04 16:04:56 |
|          12 | xadk5JJmgPLkw7kFQ2LT | 2014-08-04 16:10:46 |
|          13 | 8yM0B3BgYbOt2KQW141i | 2014-08-04 16:51:28 |
|          14 | PKvnobsxLU3dTZZBItn7 | 2014-08-04 16:51:28 |
|          15 | aXu9jdW8OWL7ajtkYf4R | 2014-08-04 16:51:28 |
|          16 | 7BGNAekeHNeCSCM8kMxS | 2014-08-04 16:51:28 |
|          17 | pKwi8LY8HyAKKmEs7Th0 | 2014-08-04 16:51:28 |
|          18 | p5MADXZyinC9Yetr51nj | 2014-08-04 16:51:28 |
|          19 | P2hBaAK9HbCiVW8gBSPj | 2014-08-04 16:51:28 |
|          20 | Igddxz3UzmwEzYacX6iO | 2014-08-04 16:51:28 |
|          21 | FslzpwD8WKBbBhOkvTKz | 2014-08-04 16:51:28 |
|          22 | yE8AheE4dglD3lcojEfc | 2014-08-04 16:51:28 |
+-------------+----------------------+---------------------+
22 rows in set (0.00 sec)

mysql>

こんな感じでrandomで変数を取得する事も出来る。

$ cat randum_import.py
# coding: utf-8

import string
from random import randrange

import random


LENGTH = 20
alphabets = string.digits + string.letters

def randstr(n):
    return ''.join(alphabets[randrange(len(alphabets))] for i in xrange(n))
if __name__ == '__main__':


 print randstr(LENGTH)
 print random.random()


 mix_string = randstr(LENGTH) +  str(random.random())
 print mix_string

$ python randum_import.py
2GaN2hELQd7sDe9Hxdt6
0.28266427386
Zxp7xV3cMolzZFaXtB9p0.235414511771

$

OpenStackでもMySQL UtilityでもPythonが使われていて、
関わっていく事も多いと思うので、少しずつPythonにCatch Upしておく。

Download the latest version for Windows 2.7.8
https://www.python.org/downloads/

admin@local#cat hello_world.py
# coding: utf-8

print "Hello World"
print "こんにちはPythonです"

import datetime # Import datetime Module
import locale   # import locale

d = datetime.datetime.today()

# year, month, day
print '%s年%s月%s日\n' % (d.year, d.month, d.day)

admin@local#python hello_world.py
Hello World
こんにちはPythonです
2014年7月30日

admin@local#

admin@local#cat count_row.py
# coding: utf-8

import sys
print "行数"
print len(sys.stdin.readlines())

admin@local#vim test
admin@local#cat test
1
2
3
4
5
6
7
admin@local#python count_row.py < test
行数
7
admin@local#
[/SHELL]


■MySQLと接続してみる
http://dev.mysql.com/downloads/connector/python/
Windows (Architecture Independent), MSI Installer
Python 2.7をインストールしました。

[SHELL]
$ cat mysql_test.py
# coding: utf-8

try:
 # import

 import mysql.connector

 # 接続
 connect = mysql.connector.connect(user='root', password='passowrd', host='localhost', database='test', charset='utf8')

 # カーソル
 cursor = connect.cursor()
 # SQL 発行
 cursor.execute('select language_id,name from language', ())
 # フェッチ
 rows = cursor.fetchall()
 print(rows)
 cursor.close()
 # 切断
 connect.close()

except Exception as myout:

 print(myout)

$
[/SHELL]

テーブルの中身はこんな感じ
[SQL]
mysql> select language_id,name from language;
+-------------+----------+
| language_id | name     |
+-------------+----------+
|           1 | English  |
|           2 | Italian  |
|           3 | Japanese |
|           4 | Mandarin |
|           5 | French   |
|           6 | German   |
+-------------+----------+
6 rows in set (0.00 sec)

mysql>
[/SQL]


■実行するとこんな感じでアウトプットが出てくる。

[SHELL]

$ python mysql_test.py
[(1, u'English'), (2, u'Italian'), (3, u'Japanese'), (4, u'Mandarin'), (5, u'French'), (6, u'German')]

$

■Sample ScriptフォルダーにあるGoogle Searchのスクリプトは
 引数を後ろに付けられる。試しに確認してみた。

$ cat google.py
#! /usr/bin/env python

import sys, webbrowser

def main():
    args = sys.argv[1:]
    if not args:
        print "Usage: %s querystring" % sys.argv[0]
        return
    list = []
    for arg in args:
        if '+' in arg:
            arg = arg.replace('+', '%2B')
        if ' ' in arg:
            arg = '"%s"' % arg
        arg = arg.replace(' ', '+')
        list.append(arg)
    s = '+'.join(list)
    url = "http://www.google.com/search?q=%s" % s
    webbrowser.open(url)

if __name__ == '__main__':
    main()

$