大家好,这次大表哥带来的是 mysql innodb cluster.
innodb cluster 也是官方taf(transparent application failover))的m6米乐安卓版下载的解决方案
目前市面上支持应用程序自动感知mgr的taf大致有如下几种方式:
1)官方的m6米乐安卓版下载的解决方案: innodb cluster (router mysql shell mgr ). 属于mysql 的亲儿子。
2)开源的路由组件 像是 proxysql 等等
3)公司自研的集成在 像是 springboot l里面 数据库驱动层的代码逻辑里面,基本上还会集成sharding 分片等逻辑,需要专业的开发来维护。
我们先来看看官方的架构图: mgr 集群 mysql shell mysql router
mysql shell 是 innodb cluster 的管理客户端。 支持js,sql, python 等多种语法 对数据库进行运维操作。
mysql router 是一个高性能的路由组件,初始化的时候会读取innodb cluster 集群的metadata信息,保存在data 目录下。
并实时像集群发送心跳,记录状态来支持 应用的自动故障转移。
官方的宣传卖点:
1内置ha的m6米乐安卓版下载的解决方案
2)黑盒m6米乐安卓版下载的解决方案,整合你想要的所有,不需要关注内部实现
3)高性能扩展性,添加新的节点只需要一个命令
我们可以看到 官方推荐的是 mysql router 安装在application 端。
下面我们来体验一下:
一 )mysql shell 安装步骤:
官方文档: https://dev.mysql.com/doc/mysql-shell/8.0/en/
安装我们参考的官方文档: https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-install-linux-quick.html 中的installing mysql shell on unix/linux using generic binaries 部分:
a)下载 mysql shell 软件
https://downloads.mysql.com/archives/shell/
这里我们选择 mysql shell 的版本是 8.0.20 版本, 应该是版本向下兼容的。
b)上传软件到服务器并解压
uat mysql@wqdcsrv3352[10:51:00]:/data/software $ ls -lhtr
-rw-r--r-- 1 mysql mysql 33m apr 28 10:43 mysql-shell-8.0.20-linux-glibc2.12-x86-64bit.tar.gz
-rw-r--r-- 1 mysql mysql 37m apr 28 10:45 mysql-router-8.0.20-linux-glibc2.12-x86_64.tar.xz
uat mysql@wqdcsrv3352[10:55:40]:/data/software $ tar -xvf mysql-shell-8.0.20-linux-glibc2.12-x86-64bit.tar.gz
uat mysql@wqdcsrv3352[10:56:11]:/data/software $ mv mysql-shell-8.0.20-linux-glibc2.12-x86-64bit mysql-shell-8.0.20
c)配置环境变量
uat mysql@wqdcsrv3352[10:58:36]:~ $ vi .bash_profile mysqlshell_home=/data/software/mysql-shell-8.0.20 path=$path:$home/.local/bin:$home/bin:$mysqlshell_home/bin
d)测试mysql shell 的版本
uat mysql@wqdcsrv3352[11:00:24]:~ $ mysqlsh
mysql shell 8.0.20
米乐app官网下载 copyright (c) 2016, 2020, 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 '\?' for help; '\quit' to exit.
mysql js >
二)mysql router 安装步骤:
a)下载 mysql router 软件
下载地址: https://downloads.mysql.com/archives/router/
这里我们选择 router 的版本是 8.0.20 版本, 应该是版本向下兼容的。
b)上传软件到服务器并解压
uat mysql@wqdcsrv3352[10:51:00]:/data/software $ ls -lhtr
-rw-r--r-- 1 mysql mysql 33m apr 28 10:43 mysql-shell-8.0.20-linux-glibc2.12-x86-64bit.tar.gz
-rw-r--r-- 1 mysql mysql 37m apr 28 10:45 mysql-router-8.0.20-linux-glibc2.12-x86_64.tar.xz
uat mysql@wqdcsrv3352[10:54:26]:/data/software $ tar -xvf mysql-router-8.0.20-linux-glibc2.12-x86_64.tar.xz
uat mysql@wqdcsrv3352[10:55:06]:/data/software $ mv mysql-router-8.0.20-linux-glibc2.12-x86_64 mysql-router-8.0.20
c)配置环境变量
mysqlshell_home=/data/software/mysql-shell-8.0.20 mysql_router_home=/data/software/mysql-router-8.0.20 path=$path:$home/.local/bin:$home/bin:$mysqlshell_home/bin:$mysql_router_home/bin
三)安装沙箱sandbox 的测试实例
a)创建沙箱测试实例的目录
uat mysql@wqdcsrv3352[11:45:19]:/data $ sudo mkdir -p /data/mysql-sandboxes uat mysql@wqdcsrv3352[11:49:34]:/data $ sudo chown -r mysql:mysql /data/mysql-sandboxes/
b)安装沙箱实例
mysql js > shell.options.sandboxdir='/data/mysql-sandboxes'
/data/mysql-sandboxes
mysql js > dba.deploysandboxinstance(3310);
a new mysql sandbox instance will be created on this host in
/data/mysql-sandboxes/3310
warning: sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
please enter a mysql root password for the new instance: ********
deploying new mysql instance...
instance localhost:3310 successfully deployed and started.
use shell.connect('root@localhost:3310') to connect to the instance.
mysql js > dba.deploysandboxinstance(3320);
a new mysql sandbox instance will be created on this host in
/data/mysql-sandboxes/3320
warning: sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
please enter a mysql root password for the new instance: ********
deploying new mysql instance...
instance localhost:3320 successfully deployed and started.
use shell.connect('root@localhost:3320') to connect to the instance.
mysql js > dba.deploysandboxinstance(3330);
a new mysql sandbox instance will be created on this host in
/data/mysql-sandboxes/3330
warning: sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
please enter a mysql root password for the new instance: ********
deploying new mysql instance...
instance localhost:3330 successfully deployed and started.
use shell.connect('root@localhost:3330') to connect to the instance.
四)构建 innodb cluster
a)连接到实例3310中
mysql js > shell.connect('root@localhost:3310');
creating a session to 'root@localhost:3310'
error: failed to retrieve the password: logger: tried to log to an uninitialized logger.
logger: tried to log to an uninitialized logger.
invalid entry: root3838. entry has a socket and a host which resolves to non-local address.
please provide the password for 'root@localhost:3310': ********
save password for 'root@localhost:3310'? [y]es/[n]o/ne[v]er (default no): y
fetching schema names for autocompletion... press ^c to stop.
your mysql connection id is 12
server version: 8.0.27-18 percona server (gpl), release 18, revision 24801e21b45
no default schema selected; type \use <schema> to set one.
3310>
b)创建 innodb cluster : mgrcluster
mysql localhost:3310 ssl js > var cluster = dba.createcluster('mgrcluster');
a new innodb cluster will be created on instance 'localhost:3310'.
validating instance configuration at localhost:3310...
note: instance detected as a sandbox.
please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
this instance reports its own address as 127.0.0.1:3310
instance configuration is suitable.
note: group replication will communicate with other members using '127.0.0.1:33101'. use the localaddress option to override.
creating innodb cluster 'mgrcluster' on '127.0.0.1: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.
c)加入另外2个实例 3320,3330
cluster.addinstance('root@localhost:3320'); cluster.addinstance('root@localhost:3330');
d)我们查看一下 innodb cluster 的状态
我们可以看到主节点 是 127.0.0.1:3310 读写的状态 “mode”: “r/w”
mysql localhost:3310 ssl js > cluster.status(); { "clustername": "mgrcluster", "defaultreplicaset": { "name": "default", "primary": "127.0.0.1:3310", "ssl": "required", "status": "ok", "statustext": "cluster is online and can tolerate up to one failure.", "topology": { "127.0.0.1:3310": { "address": "127.0.0.1:3310", "mode": "r/w", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" }, "127.0.0.1:3320": { "address": "127.0.0.1:3320", "mode": "r/o", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" }, "127.0.0.1:3330": { "address": "127.0.0.1:3330", "mode": "r/o", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "127.0.0.1:3310" }
至此, 我们用mysql shell 构建了3 个 sandbox 的实例:
mysql> select * from replication_group_members;
--------------------------- -------------------------------------- ------------- ------------- -------------- ------------- ---------------- ----------------------------
| channel_name | member_id | member_host | member_port | member_state | member_role | member_version | member_communication_stack |
--------------------------- -------------------------------------- ------------- ------------- -------------- ------------- ---------------- ----------------------------
| group_replication_applier | 6b7a0fd9-c6a8-11ec-9586-005056aeb15f | 127.0.0.1 | 3310 | online | primary | 8.0.27 | xcom |
| group_replication_applier | 759e66ea-c6a8-11ec-9afb-005056aeb15f | 127.0.0.1 | 3320 | online | secondary | 8.0.27 | xcom |
| group_replication_applier | 7e43cca4-c6a8-11ec-9f5e-005056aeb15f | 127.0.0.1 | 3330 | online | secondary | 8.0.27 | xcom |
--------------------------- -------------------------------------- ------------- ------------- -------------- ------------- ---------------- ----------------------------
3 rows in set (0.00 sec)
四)启动mysql router
a) mysql router 第一次启动需要 bootstrapping
创建mysql router 的home 目录
uat mysql@wqdcsrv3352[13:36:10]:/data/mysql-sandboxes/3310/sandboxdata $ sudo mkdir /data/mysqlrouter uat mysql@wqdcsrv3352[13:36:44]:/data/mysql-sandboxes/3310/sandboxdata $ sudo chown -r mysql:mysql /data/mysqlrouter
bootstrapping mysql router : 这个操作会读取mgr的集群信息 保存在 router 的 home 目录中
mysqlrouter --bootstrap root@localhost:3310 -d /data/mysqlrouter
uat mysql@wqdcsrv3352[13:36:50]:/data/mysql-sandboxes/3310/sandboxdata $ mysqlrouter --bootstrap root@localhost:3310 -d /data/mysqlrouter
please enter mysql password for root:
# bootstrapping mysql router instance at '/data/mysqlrouter'...
- creating account(s) (only those that are needed, if any)
- verifying account (using it to run sql queries that would be run by router)
- storing account in keyring
- adjusting permissions of generated files
- creating configuration /data/mysqlrouter/mysqlrouter.conf
# mysql router configured for the innodb cluster 'mgrcluster'
after this mysql router has been started with the generated configuration
$ mysqlrouter -c /data/mysqlrouter/mysqlrouter.conf
the cluster 'mgrcluster' can be reached by connecting to:
## mysql classic protocol
- read/write connections: localhost:6446
- read/only connections: localhost:6447
## mysql x protocol
- read/write connections: localhost:64460
- read/only connections: localhost:64470
b)初始化集群的信息之后, 我们可以按照上面的提示来启动一下 mysql router:
mysqlrouter -c /data/mysqlrouter/mysqlrouter.conf
我们可以观察启动的日志:
uat mysql@wqdcsrv3352[13:44:22]:/data/mysqlrouter/log $ tail -f mysqlrouter.log
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] potential changes detected in cluster 'mgrcluster' after metadata refresh
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] metadata for cluster 'mgrcluster' has 1 replicasets:
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] 'default' (3 members, single-master)
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] 127.0.0.1:3310 / 33100 - role=ha mode=rw
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] 127.0.0.1:3320 / 33200 - role=ha mode=ro
2022-04-28 13:42:45 metadata_cache info [7ff1b0fa8700] 127.0.0.1:3330 / 33300 - role=ha mode=ro
2022-04-28 13:42:45 routing info [7ff1b0fa8700] routing routing:mgrcluster_x_ro listening on 64470 got request to disconnect invalid connections: metadata change
2022-04-28 13:42:45 routing info [7ff1b0fa8700] routing routing:mgrcluster_x_rw listening on 64460 got request to disconnect invalid connections: metadata change
2022-04-28 13:42:45 routing info [7ff1b0fa8700] routing routing:mgrcluster_rw listening on 6446 got request to disconnect invalid connections: metadata change
2022-04-28 13:42:45 routing info [7ff1b0fa8700] routing routing:mgrcluster_ro listening on 6447 got request to disconnect invalid connections: metadata change
我们可以看到 rw 的读写端口是 6446 , ro 的只读端口是 6447
c)我们可以通过 mysql shell 来连接测试一下 端口 6446 对应是主节点 3310
uat mysql@wqdcsrv3352[13:47:44]:/data/mysqlrouter/log $ mysqlsh root@localhost:6446
please provide the password for 'root@localhost:6446': ********
mysql localhost:6446 ssl js > \sql
switching to sql mode... commands end with ;
mysql localhost:6446 ssl sql > select @@port;
--------
| @@port |
--------
| 3310 |
--------
1 row in set (0.0004 sec)
再次测试一下 只读端口: 6447
我们可以看到 指向了 secondary 节点 3330
uat mysql@wqdcsrv3352[14:02:24]:/data/mysqlrouter/log $ mysqlsh root@localhost:6447
mysql localhost:6447 ssl js > \sql
switching to sql mode... commands end with ;
mysql localhost:6447 ssl sql > select @@port;
--------
| @@port |
--------
| 3330 |
--------
1 row in set (0.0004 sec)
五)taf自动切换测试
a)准备一段简单的python 连接 mysql router 的代码片段
我们现在 kill 掉主节点:
mysql localhost:6446 ssl js > shell.options.sandboxdir='/data/mysql-sandboxes' /data/mysql-sandboxes mysql localhost:6446 ssl js > dba.killsandboxinstance(3310); killing mysql instance... instance localhost:3310 successfully killed.
我们再次执行程序: mysql router 重定向到了 3320这个端口
我们通过mysql shell 查询一下 3320 已经升级为 primary 节点了
mysql localhost:6446 ssl js > dba.getcluster().status(); { "clustername": "mgrcluster", "defaultreplicaset": { "name": "default", "primary": "127.0.0.1:3320", "ssl": "required", "status": "ok_no_tolerance", "statustext": "cluster is not tolerant to any failures. 1 member is not active", "topology": { "127.0.0.1:3310": { "address": "127.0.0.1:3310", "mode": "n/a", "readreplicas": {}, "role": "ha", "shellconnecterror": "mysql error 2003 (hy000): can't connect to mysql server on '127.0.0.1' (111)", "status": "(missing)" }, "127.0.0.1:3320": { "address": "127.0.0.1:3320", "mode": "r/w", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" }, "127.0.0.1:3330": { "address": "127.0.0.1:3330", "mode": "r/o", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "127.0.0.1:3320" }
六)手动主从switch over 切换
命令很简单: dba.getcluster().setprimaryinstance(‘root@localhost:3330’);
mysql localhost:6446 ssl js > dba.getcluster().setprimaryinstance('root@localhost:3330'); setting instance 'localhost:3330' as the primary instance of cluster 'mgrcluster'... instance '127.0.0.1:3310' was switched from primary to secondary. instance '127.0.0.1:3320' remains secondary. instance '127.0.0.1:3330' was switched from secondary to primary. warning: the cluster internal session is not the primary member anymore. for cluster management operations please obtain a fresh cluster handle using dba.getcluster(). the instance 'localhost:3330' was successfully elected as primary.
我们再次查看3330 的角色: 已经是r/w的节点了
mysql localhost:6446 ssl js > dba.getcluster().status().defaultreplicaset.topology; { "127.0.0.1:3310": { "address": "127.0.0.1:3310", "mode": "r/o", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" }, "127.0.0.1:3320": { "address": "127.0.0.1:3320", "mode": "r/o", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" }, "127.0.0.1:3330": { "address": "127.0.0.1:3330", "mode": "r/w", "readreplicas": {}, "replicationlag": null, "role": "ha", "status": "online", "version": "8.0.27" } }
最后总结:
1)安装,部署 整体感觉很轻量级,后续运维可以通过mysql shell ,大大简化了dba登录多台机器的工作。
2) mysql rounter 是需要企业license的, 如果你的公司有预算的话,是个不错的选择。