 
 最近公众号有人留言:为啥使用 ProxySQL 而不使用 InnoDB Cluster ?可用 其实使用什么方案,根据实际情况进行权衡利弊即可,署详如果先部署了 MGR ,可用想在此基础之上完善高可用,署详添加 ProxySQL 比较方便。可用如果新部署一个高可用环境,署详直接使用 InnoDB Cluster 也可以,可用InnoDB Cluster 也是署详依赖 MGR 。 下面从零开始,可用来讲解怎么通过 Docker Compose 来部署 MySQL InnoDB Cluster,署详让你能够快速搭建一套完整的可用高可用数据库系统。 什么是署详 MySQL InnoDB Cluster核心概念        MySQL InnoDB Cluster是 MySQL 官方提供的高可用解决方案,它基于以下三个核心组件: MySQL Group Replication:提供数据复制和故障检测,可用这个就是署详前面文章中提到的 MGRMySQL Router:提供透明的路由和负载均衡MySQL Shell:提供集群管理和监控功能架构优势自动故障检测和转移强一致性数据复制透明的读写分离简化的管理操作        架构图开始部署为了测试方便,在一台服务器上使用 docker compose 部署多个服务节点。可用 启动 MySQL 节点        在服务器上创建一个目录 mysql-innodb-cluster ,目录中按照下图进行目录和文件的创建。 docker-compose.yml 文件内容如下: 复制version: 3.8                        services:                        mysql1:                        image: mysql:8.0.39                        container_name: mysql1                        hostname: mysql1                        restart: unless-stopped                        environment:                        MYSQL_ROOT_PASSWORD: rootpass123                        TZ: Asia/Shanghai                        networks:                        - mysql-cluster-net                        volumes:                        - ./node1/conf:/etc/mysql/conf.d:ro                        - ./node1/data:/var/lib/mysql                        - ./node1/log:/var/log/mysql                        ports:                        - "3310:3306"                        mysql2:                        image: mysql:8.0.39                        container_name: mysql2                        hostname: mysql2                        restart: unless-stopped                        environment:                        MYSQL_ROOT_PASSWORD: rootpass123                        TZ: Asia/Shanghai                        networks:                        - mysql-cluster-net                        volumes:                        - ./node2/conf:/etc/mysql/conf.d:ro                        - ./node2/data:/var/lib/mysql                        - ./node2/log:/var/log/mysql                        ports:                        - "3311:3306"                        mysql3:                        image: mysql:8.0.39                        container_name: mysql3                        hostname: mysql3                        restart: unless-stopped                        environment:                        MYSQL_ROOT_PASSWORD: rootpass123                        TZ: Asia/Shanghai                        networks:                        - mysql-cluster-net                        volumes:                        - ./node3/conf:/etc/mysql/conf.d:ro                        - ./node3/data:/var/lib/mysql                        - ./node3/log:/var/log/mysql                        ports:                        - "3312:3306"                        mysql-router:                        image: mysql/mysql-router:8.0                        container_name: mysql-router                        restart: unless-stopped                        depends_on:                        - mysql1                        - mysql2                        - mysql3                        networks:                        - mysql-cluster-net                        volumes:                        - ./router/data:/tmp/mysqlrouter                        ports:                        - "6446:6446" # 读写端口 (RW)                        - "6447:6447" # 只读端口 (RO)                        - "6448:6448" # 管理端口 (X Protocol RW)                        - "6449:6449" # 管理端口 (X Protocol RO)                        environment:                        MYSQL_HOST: mysql1                        MYSQL_PORT: 3306                        MYSQL_USER: clusteradmin                        MYSQL_PASSWORD: clusterpass123                        MYSQL_CREATE_ROUTER_USER: 0                        MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS: >                        --conf-use-sockets                        --conf-bind-address 0.0.0.0                        --conf-base-port 6446                        networks:                        mysql-cluster-net:                        driver: bridge                        name: mysql-cluster-net1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.                                            router 节点说明: 检测 /tmp/mysqlrouter/mysqlrouter.conf 是否存在,如果不存在则执行mysqlrouter --bootstrap clusteradmin@mysql1:3306 ... --directory /tmp/mysqlrouter ,密码从 MYSQL_PASSWORD 变量读入,非交互(不用手动输入)。bootstrap 成功后,云服务器以后每次容器重启直接 mysqlrouter -c /tmp/mysqlrouter/mysqlrouter.conf 不再重新扫描集群,配置持久化。Router 根据集群实时角色,把 6446 流量转发到 PRIMARY,6447 转发到 SECONDARY,应用只需连固定端口即可。        mysql 节点 1 的配置文件 mysql1.cnf 内容如下: 复制[mysqld]                        # 网络和连接                        bind-address = 0.0.0.0                        # 复制基础                        server_id = 1                        log_bin = mysql-bin                        binlog_format = ROW                        enforce_gtid_consistency = ON                        gtid_mode = ON                        # Group Replication 特定配置                        transaction_write_set_extraction = XXHASH64                        loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 请替换为一个有效的UUID,可使用 `uuidgen` 命令生成                        loose-group_replication_start_on_boot = OFF                        loose-group_replication_local_address = "mysql1:33061" # 内部组通信地址和端口,通常为 33061                        loose-group_replication_group_seeds = "mysql1:33061, mysql2:33061, mysql3:33061"                        loose-group_replication_single_primary_mode = ON # 单主模式                        loose-group_replication_bootstrap_group = OFF # 切勿随意开启引导                        # Innodb Cluster 元数据存储                        disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,ARCHIVE                        # 性能与可靠性                        binlog_transaction_dependency_tracking = WRITESET1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.                                            mysql 节点 2 的配置文件 mysql2.cnf 内容如下: 复制[mysqld]                        bind-address = 0.0.0.0                        server_id = 2                        log_bin = mysql-bin                        binlog_format = ROW                        enforce_gtid_consistency = ON                        gtid_mode = ON                        transaction_write_set_extraction = XXHASH64                        loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 必须与node1相同                        loose-group_replication_start_on_boot = OFF                        loose-group_replication_local_address = "mysql2:33061"                        loose-group_replication_group_seeds = "mysql1:33061, mysql2:33061, mysql3:33061"                        loose-group_replication_single_primary_mode = ON                        loose-group_replication_bootstrap_group = OFF                        disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,ARCHIVE                        binlog_transaction_dependency_tracking = WRITESET1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.                                            mysql 节点 3 的配置文件 mysql3.cnf 内容如下: 复制[mysqld]                        bind-address = 0.0.0.0                        server_id = 3                        log_bin = mysql-bin                        binlog_format = ROW                        enforce_gtid_consistency = ON                        gtid_mode = ON                        transaction_write_set_extraction = XXHASH64                        loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 必须与node1相同                        loose-group_replication_start_on_boot = OFF                        loose-group_replication_local_address = "mysql3:33061"                        loose-group_replication_group_seeds = "mysql1:33061, mysql2:33061, mysql3:33061"                        loose-group_replication_single_primary_mode = ON                        loose-group_replication_bootstrap_group = OFF                        disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,ARCHIVE                        binlog_transaction_dependency_tracking = WRITESET1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.                                            节点 3 内容与节点 2 类似,但 server_id 必须改为 3,loose-group_replication_local_address 改为 mysql3:33061。loose-group_replication_group_name 必须与其它节点相同。 关于配置文件中 mgr 相关的部分可以参考之前的文章《MySQL高可用-使用Docker部署MGR》。 执行下面的命令,先启动三个 mysql 节点。 复制docker-compose up -d mysql1 mysql2 mysql31.                                            等三个 mysql 节点都启动成功后,再执行下面的操作。 添加集群管理账户        在三个 MySQL 节点上,都需要创建一个用于集群管理和 Router 引导的管理员用户(需要 SYSTEM_VARIABLES_ADMIN, REPLICATION_SLAVE_ADMIN, GROUP_REPLICATION_ADMIN 权限)。 先使用下面命令连接到节点 1 的 shell: 复制# 连接到 mysql1 容器并登录 MySQL                        docker-compose exec mysql1 mysql -uroot -prootpass1231.2.                                            然后执行下面的语句进行 clusteradmin 账户的创建和权限设置: 复制CREATE USER IF NOT EXISTS clusteradmin@% IDENTIFIED WITH mysql_native_password BY clusterpass123;                        GRANT ALL PRIVILEGES ON *.* TO clusteradmin@% WITH GRANT OPTION;                        FLUSH PRIVILEGES;1.2.3.                                            在节点 2 和节点 3 上执行相同的操作。站群服务器 使用 mysql shell 构建集群        配置和启动 InnoDB Cluster,可以使用 MySQL Shell (mysqlsh) 来创建集群。临时启动一个 MySQL Shell 容器。 复制docker run --rm -it --network=mysql-cluster-net mysql/mysql-server:8.0 mysqlsh1.                                            执行成后会进入到 MySQL JS 的 shell 界面,如下图: 在 shell 模式下逐步执行下面的代码: 复制// 连接到第一个节点(将成为初始主节点)                        \connect clusteradmin@mysql1:3306                        // 提供密码:clusterpass123                        // 检查实例配置是否符合集群要求                        dba.checkInstanceConfiguration(clusteradmin@mysql1:3306);                        dba.checkInstanceConfiguration(clusteradmin@mysql2:3306);                        dba.checkInstanceConfiguration(clusteradmin@mysql3:3306);                        // 创建集群,命名为 myCluster                        var cluster = dba.createCluster(myCluster);                        // 添加其他实例到集群中                        cluster.addInstance(clusteradmin@mysql2:3306, {password: your_strong_clusteradmin_password, recoveryMethod: clone}); // 使用 clone 方式进行恢复                        cluster.addInstance(clusteradmin@mysql3:3306, {password: your_strong_clusteradmin_password, recoveryMethod: clone});                        // 检查集群状态                        cluster.status();1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.                                            节点成功添加到集群中如下图: 最后查看集群状态: 输出应显示三个实例都是 ONLINE,其中一个角色是 PRIMARY,另外两个是 SECONDARY。 启动并配置 MySQL Router        执行下面命令启动 router 容器 复制docker-compose up -d mysql-router1.                                            router 启动成功的日志如下: 到这 MySQL InnoDB Cluster 已经部署完成,可以使用 Navicat 之类的工具进行连接进行测试: 使用 Navicat 时需要注意,SSL 中的使用 SSL 必须勾选。 最后一开始想使用 AI 来生成所有的配置,尝试了很多次,没有能一次性成功的,根据日志中的错误信息让 AI 修改,越改越混乱。因为整个过程中我没有参与,给不出更多有价值的信息,最后放弃了让 AI 直接来操作。 从这个过程我体会到更好使用 AI 的IT技术网方式应该是: 先让 AI 总结出部署 MySQL InnoDB Cluster 的关键步骤。从这个步骤中了解到一些基本的原理,然后分步骤让 AI 搞定配置,实操的过程中也是分步骤进行,这样即便出现问题也比较容易排查。手动一步一步去操作,有助于更好的理解和理清逻辑关系。学习任何技术,我们自己懂的越多,就越能让 AI 发挥更大的能力。 |