Permalink
Browse files

Add support for starting MySQL Cluster 7.5.4

  • Loading branch information...
MarkLeith committed Oct 25, 2016
1 parent 826b9da commit 8993bb3d1af6cbf52738cf127085abf178cfb5e9
View
199 README.md
@@ -11,6 +11,205 @@ All MySQL instances are configured to listen on port 3306 (the default), with th
* repl / repl (a replication user)
* mem / mem (a MySQL Enterprise Monitor user)
### mysql-cluster
Sets up a MySQL Cluster using the latest Oracle Linux and MySQL Cluster 7.5.4.
A wrapper script is included that allows you to build and start the cluster:
```
$ cluster.py -h
usage: cluster.py [-h] [--debug] {build,start,stop,clean} ...
Create a test MySQL Cluster deployment in docker
positional arguments:
{build,start,stop,clean}
build Build the cluster containers
start Start up the cluster containers
stop Stop the cluster containers
clean Stop and remove the cluster containers
optional arguments:
-h, --help show this help message and exit
--debug Whether to print debug info
$ cluster.py build -h
usage: cluster.py build [-h] [-m MANAGEMENT_NODES] [-d DATA_NODES]
[-s SQL_NODES]
optional arguments:
-h, --help show this help message and exit
-m MANAGEMENT_NODES, --management-nodes MANAGEMENT_NODES
Number of Management nodes to run (default: 2; max: 2)
-d DATA_NODES, --data-nodes DATA_NODES
Number of NDB nodes to run (default: 4; max: 48)
-s SQL_NODES, --sql-nodes SQL_NODES
Number of SQL nodes to run (default: 2)
$ cluster.py start -h
usage: cluster.py start [-h] [-n NETWORK] [-m MANAGEMENT_NODES]
[-d DATA_NODES] [-s SQL_NODES]
optional arguments:
-h, --help show this help message and exit
-n NETWORK, --network NETWORK
Name of the docker network to use
-m MANAGEMENT_NODES, --management-nodes MANAGEMENT_NODES
Number of Management nodes to run (default: 2; max: 2)
-d DATA_NODES, --data-nodes DATA_NODES
Number of NDB nodes to run (default: 4; max: 48)
-s SQL_NODES, --sql-nodes SQL_NODES
Number of SQL nodes to run (default: 2)
```
```
You must invoke this with both the build and start arguments being the same, as the build command builds the initial cluster.ini file, which is then used when started using the start command - the initial number of ndb nodes must be as expected when started.
#### Build:
```
$ cluster.py --debug build
2016-10-25T16:04:33.229000: Arguments: Namespace(data_nodes=4, debug=True, func=<function build at 0x0000000002E63BA8>, management_nodes=2, sql_nodes=2)
2016-10-25T16:04:33.235000: Running: docker build -t markleith/mysqlcluster75:ndb_mgmd -f management-node/Dockerfile management-node
2016-10-25T16:04:33.511000: Running: docker build -t markleith/mysqlcluster75:ndbmtd -f data-node/Dockerfile data-node
2016-10-25T16:04:33.809000: Running: docker build -t markleith/mysqlcluster75:sql -f sql-node/Dockerfile sql-node
```
#### Run:
```
$ cluster.py --debug start
2016-10-25T16:04:37.007000: Arguments: Namespace(data_nodes=4, debug=True, func=<function start at 0x0000000002F73C18>, management_nodes=2, network='myclusternet', sql_nodes=2)
2016-10-25T16:04:37.012000: Running: docker network ls
2016-10-25T16:04:37.076000: myclusternet network found, using existing
2016-10-25T16:04:37.078000: Running: docker run -d -P --net myclusternet --name mymgmd49 --ip 172.18.0.249 -e NODE_ID=49 -e NOWAIT=50 -e CONNECTSTRING= markleith/mysqlcluster75:ndb_mgmd
2016-10-25T16:04:38.799000: Running: docker port mymgmd49 1186/tcp
2016-10-25T16:04:38.885000: Added: Node(mymgmd49 : 32800 : mgmd)
2016-10-25T16:04:38.887000: Running: docker run -d -P --net myclusternet --name mymgmd50 --ip 172.18.0.250 -e NODE_ID=50 -e NOWAIT=49 -e CONNECTSTRING=mymgmd49:1186 markleith/mysqlcluster75:ndb_mgmd
2016-10-25T16:04:40.338000: Running: docker port mymgmd50 1186/tcp
2016-10-25T16:04:40.394000: Added: Node(mymgmd50 : 32801 : mgmd)
2016-10-25T16:04:40.396000: Running: docker run -d -P --net myclusternet --name myndbmtd1 --ip 172.18.0.11 -e NODE_ID=1 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:ndbmtd
2016-10-25T16:04:41.925000: Running: docker port myndbmtd1 11860/tcp
2016-10-25T16:04:41.987000: Added: Node(myndbmtd1 : 32802 : ndbmtd)
2016-10-25T16:04:41.989000: Running: docker run -d -P --net myclusternet --name myndbmtd2 --ip 172.18.0.12 -e NODE_ID=2 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:ndbmtd
2016-10-25T16:04:43.280000: Running: docker port myndbmtd2 11860/tcp
2016-10-25T16:04:43.336000: Added: Node(myndbmtd2 : 32803 : ndbmtd)
2016-10-25T16:04:43.338000: Running: docker run -d -P --net myclusternet --name myndbmtd3 --ip 172.18.0.13 -e NODE_ID=3 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:ndbmtd
2016-10-25T16:04:44.855000: Running: docker port myndbmtd3 11860/tcp
2016-10-25T16:04:44.936000: Added: Node(myndbmtd3 : 32804 : ndbmtd)
2016-10-25T16:04:44.937000: Running: docker run -d -P --net myclusternet --name myndbmtd4 --ip 172.18.0.14 -e NODE_ID=4 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:ndbmtd
2016-10-25T16:04:49.039000: Running: docker port myndbmtd4 11860/tcp
2016-10-25T16:04:49.117000: Added: Node(myndbmtd4 : 32805 : ndbmtd)
2016-10-25T16:04:49.119000: Running: docker run -d -P --net myclusternet --name mysqlndb51 --ip 172.18.0.151 -e NODE_ID=51 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:sql
2016-10-25T16:05:06.190000: Running: docker port mysqlndb51 3306/tcp
2016-10-25T16:05:06.264000: Added: Node(mysqlndb51 : 32806 : sql)
2016-10-25T16:05:06.266000: Running: docker run -d -P --net myclusternet --name mysqlndb52 --ip 172.18.0.152 -e NODE_ID=52 -e CONNECTSTRING=mymgmd49:1186,mymgmd50:1186 markleith/mysqlcluster75:sql
2016-10-25T16:05:12.735000: Running: docker port mysqlndb52 3306/tcp
2016-10-25T16:05:13.104000: Added: Node(mysqlndb52 : 32807 : sql)
2016-10-25T16:05:13.105000: Started: [Node(mymgmd49 : 32800 : mgmd), Node(mymgmd50 : 32801 : mgmd), Node(myndbmtd1 : 32802 : ndbmtd), Node(myndbmtd2 : 32803 : ndbmtd), Node(myndbmtd3 : 32804 : ndbmtd), Node(myndbmtd4 : 32805 : ndbmtd), Node(mysqlndb51 : 32806 : sql), Node(mysqlndb52 : 32807 : sql)]
```
#### Connecting
You can use the exposed ports to connect directly to a SQL node from the docker host OS, such as taking the exposed port for mysqlndb52 above (32807):
```
$ mysql -u root -pmysql -h 127.0.0.1 -P 32807
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 4
Server version: 5.7.16-ndb-7.5.4-cluster-gpl MySQL Cluster 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 tables from ndbinfo;
+---------------------------------+
| Tables_in_ndbinfo |
+---------------------------------+
| arbitrator_validity_detail |
| arbitrator_validity_summary |
| blocks |
| cluster_locks |
| cluster_operations |
| cluster_transactions |
| config_params |
| config_values |
| counters |
| cpustat |
| cpustat_1sec |
| cpustat_20sec |
| cpustat_50ms |
| dict_obj_info |
| dict_obj_types |
| disk_write_speed_aggregate |
| disk_write_speed_aggregate_node |
| disk_write_speed_base |
| diskpagebuffer |
| locks_per_fragment |
| logbuffers |
| logspaces |
| membership |
| memory_per_fragment |
| memoryusage |
| nodes |
| operations_per_fragment |
| resources |
| restart_info |
| server_locks |
| server_operations |
| server_transactions |
| table_distribution_status |
| table_fragments |
| table_info |
| table_replicas |
| tc_time_track_stats |
| threadblocks |
| threads |
| threadstat |
| transporters |
+---------------------------------+
41 rows in set (0.00 sec)
mysql> desc ndbinfo.memoryusage;
+-------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| node_id | int(10) unsigned | YES | | NULL | |
| memory_type | varchar(512) | YES | | NULL | |
| used | decimal(62,0) | YES | | NULL | |
| used_pages | decimal(42,0) | YES | | NULL | |
| total | decimal(62,0) | YES | | NULL | |
| total_pages | decimal(42,0) | YES | | NULL | |
+-------------+------------------+------+-----+---------+-------+
6 rows in set (0.10 sec)
mysql> select node_id, memory_type, sys.format_bytes(used) used, sys.format_bytes(total) total from ndbinfo.memoryusage;
+---------+---------------------+------------+-----------+
| node_id | memory_type | used | total |
+---------+---------------------+------------+-----------+
| 1 | Data memory | 704.00 KiB | 80.00 MiB |
| 1 | Index memory | 104.00 KiB | 18.25 MiB |
| 1 | Long message buffer | 384.00 KiB | 32.00 MiB |
| 2 | Data memory | 704.00 KiB | 80.00 MiB |
| 2 | Index memory | 104.00 KiB | 18.25 MiB |
| 2 | Long message buffer | 256.00 KiB | 32.00 MiB |
| 3 | Data memory | 704.00 KiB | 80.00 MiB |
| 3 | Index memory | 104.00 KiB | 18.25 MiB |
| 3 | Long message buffer | 256.00 KiB | 32.00 MiB |
| 4 | Data memory | 704.00 KiB | 80.00 MiB |
| 4 | Index memory | 104.00 KiB | 18.25 MiB |
| 4 | Long message buffer | 256.00 KiB | 32.00 MiB |
+---------+---------------------+------------+-----------+
12 rows in set (0.42 sec)
```
### mysql-repo-server-5.6-centos-6.8
Sets up CentOS 6.8 with SSH and MySQL started.
View
@@ -0,0 +1,193 @@
#!/usr/bin/python
#
# Copyright (c) 2016, 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
#
import argparse
import datetime
import os
import shutil
import subprocess
NDBD_BASE_ID = 1
NDBD_BASE_IP = "172.18.0.1"
MGMD_BASE_ID = 49
MGMD_BASE_IP = "172.18.0.2"
API_BASE_ID = 51
API_BASE_IP = "172.18.0.1"
SUBNET_BASE = "172.18.0.0/16"
nodes=[]
class Node:
def __init__(self, name, port, node_type):
self.name = name
self.port = port
self.node_type = node_type
def __str__(self):
return("Node("+str(self.name)+" : "+str(self.port)+" : "+str(self.node_type)+")")
def __repr__(self):
return str(self)
def add_node(nodeName, node_type):
if node_type == "mgmd":
port = cmd("docker port {0} 1186/tcp".format(nodeName))
elif node_type == "ndbmtd":
port = cmd("docker port {0} 11860/tcp".format(nodeName))
elif node_type == "sql":
port = cmd("docker port {0} 3306/tcp".format(nodeName))
node = Node(nodeName, port.strip().split(":",1)[1], node_type)
nodes.append(node)
debug("Added: {0}".format(node))
def ts():
return datetime.datetime.utcnow().isoformat()+": "
def debug(msg):
if args.debug: print ts()+msg
def cmd(cmd):
debug("Running: " + cmd)
return subprocess.check_output(cmd, shell=True)
def write_ini_section(file, header, nodeid, nodeip):
file.write("\n["+header+"]\n")
file.write("NodeId={0}\n".format(nodeid))
file.write("HostName={0}\n".format(nodeip))
def build_config_ini():
config_ini = os.getcwd()+"/management-node/config.ini"
try:
cfgtmpl = os.getcwd()+"/management-node/config.ini.in"
shutil.copy(cfgtmpl, config_ini)
except shutil.Error as e:
print('Error: %s' % e)
except IOError as e:
print('Error: %s' % e.strerror)
with open(config_ini, "ab") as f:
nodeid = MGMD_BASE_ID
for i in range(args.management_nodes):
write_ini_section(f, "NDB_MGMD", nodeid, "{0}{1}".format(MGMD_BASE_IP, nodeid))
nodeid += 1
nodeid = NDBD_BASE_ID
for i in range(args.data_nodes):
write_ini_section(f, "NDBD", nodeid, "{0}{1}".format(NDBD_BASE_IP, nodeid))
nodeid += 1
nodeid = API_BASE_ID
for i in range(args.sql_nodes):
write_ini_section(f, "MYSQLD", nodeid, "{0}{1}".format(API_BASE_IP, nodeid))
nodeid += 1
def connect_string():
mgmd_nodes = filter(lambda x: x.node_type == "mgmd", nodes)
return ",".join(x.name+":1186" for x in mgmd_nodes)
def management_nodes_option(x):
x = int(x)
if x > 2:
raise argparse.ArgumentTypeError("Maximum Managment nodes is 2")
return x
def create_mgmd_nodes():
nodeid = MGMD_BASE_ID
mgmdSibling = nodeid + 1
ndbConnectString = ""
for i in range(args.management_nodes):
if i: nodeid, mgmdSibling = mgmdSibling, nodeid
nodeName = "mymgmd{0}".format(nodeid)
ip = "{0}{1}".format(MGMD_BASE_IP, nodeid)
runCmd = 'docker run -d -P --net {0} --name {1} --ip {2} -e NODE_ID={3} -e NOWAIT={4} -e CONNECTSTRING={5} markleith/mysqlcluster75:ndb_mgmd'
cmd(runCmd.format(args.network, nodeName, ip, nodeid, mgmdSibling, connect_string()))
add_node(nodeName, "mgmd")
def data_nodes_option(x):
x = int(x)
if x > 48:
raise argparse.ArgumentTypeError("Maximum Data nodes is 48")
return x
def create_data_nodes():
nodeid = NDBD_BASE_ID
for i in range(args.data_nodes):
nodeName = "myndbmtd{0}".format(nodeid)
ip = "{0}{1}".format(NDBD_BASE_IP, nodeid)
runCmd = 'docker run -d -P --net {0} --name {1} --ip {2} -e NODE_ID={3} -e CONNECTSTRING={4} markleith/mysqlcluster75:ndbmtd'
cmd(runCmd.format(args.network, nodeName, ip, nodeid, connect_string()))
add_node(nodeName, "ndbmtd")
nodeid += 1
def create_sql_nodes():
nodeid = API_BASE_ID
for i in range(args.sql_nodes):
nodeName = "mysqlndb{0}".format(nodeid)
ip = "{0}{1}".format(API_BASE_IP, nodeid)
runCmd = 'docker run -d -P --net {0} --name {1} --ip {2} -e NODE_ID={3} -e CONNECTSTRING={4} markleith/mysqlcluster75:sql'
cmd(runCmd.format(args.network, nodeName, ip, nodeid, connect_string()))
add_node(nodeName, "sql")
nodeid += 1
def build(args):
build_config_ini()
cmd('docker build -t markleith/mysqlcluster75:ndb_mgmd -f management-node/Dockerfile management-node')
cmd('docker build -t markleith/mysqlcluster75:ndbmtd -f data-node/Dockerfile data-node')
cmd('docker build -t markleith/mysqlcluster75:sql -f sql-node/Dockerfile sql-node')
def start(args):
networks = cmd("docker network ls")
if networks.find(args.network) != -1:
debug(args.network + " network found, using existing")
else:
debug(args.network + " network not found, creating")
cmd("docker network create --subnet="+SUBNET_BASE+" "+args.network)
create_mgmd_nodes()
create_data_nodes()
create_sql_nodes()
print "{0}Started: {1}".format(ts(), nodes)
def stop(args):
debug("OH DEAR, MUST IMPLEMENT STOP")
def clean(args):
debug("OH DEAR, MUST IMPLEMENT CLEAN")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Create a test MySQL Cluster deployment in docker")
network = argparse.ArgumentParser(add_help=False)
network.add_argument('-n', '--network', default="myclusternet", help='Name of the docker network to use')
mgmd_nodes = argparse.ArgumentParser(add_help=False)
mgmd_nodes.add_argument('-m', '--management-nodes', default=2, type=management_nodes_option, help='Number of Management nodes to run (default: 2; max: 2)')
data_nodes = argparse.ArgumentParser(add_help=False)
data_nodes.add_argument('-d', '--data-nodes', default=4, type=data_nodes_option, help='Number of NDB nodes to run (default: 4; max: 48)')
sql_nodes = argparse.ArgumentParser(add_help=False)
sql_nodes.add_argument('-s', '--sql-nodes', default=2, type=int, help='Number of SQL nodes to run (default: 2)')
sp = parser.add_subparsers()
sp_build = sp.add_parser('build', parents=[mgmd_nodes, data_nodes, sql_nodes], help='Build the cluster containers')
sp_build.set_defaults(func=build)
sp_start = sp.add_parser('start', parents=[network, mgmd_nodes, data_nodes, sql_nodes], help='Start up the cluster containers')
sp_start.set_defaults(func=start)
sp_stop = sp.add_parser('stop', parents=[network], help='Stop the cluster containers')
sp_stop.set_defaults(func=stop)
sp_clean = sp.add_parser('clean', parents=[network], help='Stop and remove the cluster containers')
sp_clean.set_defaults(func=clean)
parser.add_argument('--debug', default=False, action="store_true", help='Whether to print debug info')
args = parser.parse_args()
debug("Arguments: {0}".format(args))
args.func(args)
Oops, something went wrong.

0 comments on commit 8993bb3

Please sign in to comment.