MySQL 5.7 集群搭建

2,941 阅读14分钟
  • 安装MySQL

  • InnoDB集群搭建

使用Zip压缩包安装MySQL

注意

MySQL Community 5.7 Server在Windows平台运行需要Microsoft Visual C ++ 2013 Redistributable Package支持,用户安装前请检查系统环境是否支持。

  1. 下载MySQL 5.7社区版

  2. 选择安装位置

    注意

    选择安装位置,尽可能保证安装路径当中不要出现空格。本次安装的位置选择在 C:\MySQL

  3. 创建配置文件my.ini,并将my.ini存放在MySQL安装目录下

    [mysqld]
    # 设置MySQL安装路径
    basedir=C:/MySQL
    # 设置MySQL数据保存目录
    datadir=C:/MySQL/data
    
  4. 使用mysqld手动初始化数据目录

    • 初始化选项说明

      • --initialize使用该选项初始化将生成随机密码,建议结合--console选项使用
      • --initialize-insecure使用该选项初始化将不会生成任何密码
      • --defaults-file指定mysql数据目录初始化时读取的配置文件,该选项必须在mysqld命令之后的第一位
    • 初始化数据目录

      注意

      --initialize选项初始化生成的随机密码在最后一行

      mysqld --defaults-file=C:/MySQL/my.ini ----initialize --console
      
  5. 启动MySQL服务器

    mysqld --console
    
  6. 连接MySQL服务器

    • 使用--initialize选项初始化数据目录,请使用随机密码登录服务器

      mysql -u root -p
      
    • 使用--initialize-insecure选项初始化数据目录,请使用--skip-password选项连接服务器

      mysql -u root --skip-password
      
  7. 连接后,修改root密码

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password'
    

    注意

    通常情况下使用127.0.0.1连接到服务器会被解析为localhost账户。可以通过以下方式确保连接到MySQL服务器

    CREATE USER 'username'@'hostname' IDENTIFIED BY 'new_password'
    

InnoDB集群搭建

  1. InnoDB集群简介

    MySQL InnoDB集群为MySQL提供了一套的高可用性解决方案。MySQL Shell包含的AdminAPI,使您可以轻松配置和管理至少3个MySQL服务器实例集群。每个MySQL服务器实例都运行MySQL Group Replication模块,它提供了InnoDB集群数据复制机制,并且具有内置的故障转移功能。

    注意

    InnoDB集群不支持MySQL NDB Cluster。NDB Cluster依赖于NDB存储引擎,以及许多NDB Cluster程序都未随MySQL Server 5.7提供。此外,MySQL Server 5.7提供的mysqld不能与NDB Cluster一起使用。

    下图显示了MySQL InnoDB Cluster使用那些技术协同工作

使用AdminAPI

MySQL Shell提供了AdminAPI功能,通过AdminAPI提供的dba全局变量和方法使您能够部署、配置和管理InnoDB集群。如,使用dba.createCluster()方法创建InnoDB集群。

注意

MySQL Shell允许您通过套接字连接到服务器,但AdminAPI需要TCP连接到服务器实例。不要在AdminAPI中使用基于套接字的连接。

MySQL Shell为AdminAPI提供了在线帮助。要列出所有可用的dba命令,请使用dba.help()方法。有关特定的方法的帮助,使用格式为object.help('methodname')。

  1. 创建InnoDB Cluster

    • Sandbox deployment:如果您在生产部署之前测试InnoDB Cluster,可通过Sandbox功能使您可以在本地计算机上快速创建集群。
    • Production deployment:如果要在生产环境使用InnoDB Cluster,则需要配置所有MySQL Server实例,然后将服务器部署到计算机。

    注意

    Sandbox deployment不适合在完整的生产环境部署。

  2. InnoDB Cluster集群环境要求

    • InnoDB集群使用Group Replication模块,您必须保证您的服务器必须满足相同的要求。AdminAPI提供了dba.checkInstanceConfiguration()验证实例是否满足组复制要求,dba.configureLocalInstance()配置实例以满足组复制要求。

      注意

      使用Sandbox deployment,实例将配置为自动满足这些条件。

      Group Replication(组复制)基本要求
      • InnoDB Storage Engine,数据必须使用InnoDB事务存储引擎。
      • Primary Keys,要确保使用组复制的每个表必须具有已定义的主键或等效主键。
      • IPv4 Network,MySQL Group Replication模块仅支持IPv4网络。
      • Network Performance,组复制需要服务器实例在彼此非常接近的集群环境中,因为组复制功能极大的受网络延迟和带宽的影响。
      服务器配置
      • Binary Log Active, 激活二进制日志,--log-bin[=log_file_name]
      • Slave Updates Logged,服务器需要通过组复制应用程序更新二进制日志,--log-slave-updates
      • Binary Log Row Format,组复制格式基于行,以便在组中的服务器之间一致的传播更改,--binlog-format=row
      • Global Transaction Identifiers On,组复制使用全局事务标识符来准确跟踪在每个服务器实例上已提交的事务,从而能够推断那些服务器执行的事务可能与其他地方提交的事务冲突,--gtid-mode=on
      • Replication Information Repositories,设置--master-info-repository=TABLE--relay-log-info-repository=TABLE。组复制需要将主节点信息和从属节点信息写入系统表mysql.slave_master_infomysql.slave_relay_log_info系统表。该方式可确保组复制插件具有一致的可复制性和复制元数据的事务管理功能。
      • Transaction Write Set Extraction,设置--transaction-write-set-extraction=XXHASH64为了在收集行并记录到二进制日志时,服务器也会收集写入。写集基于每行的主键,是标记的简化和紧凑视图,唯一标识已更改的行。然后,此标记用于检测冲突。
      • Multithreaded Appliers,组复制成员可以配置为多线程应用程序,从而可以并行应用事务。设置--slave-parallel-workers=N(N标识并行应用程序的线程数量)、--slave-preserve-commit-order=1--slave-parallel-type=LOGICAL_CLOCK。组复制依赖于围绕所有参与成员以相同的顺序接受和应用已提交事务的一致性机制,因此必须设置--slave-preserve-commit-order=1确保并行事务的最终提交与原始事务的顺序相同。最后,为了确定那些事务可以并行执行,从属服务器必须包含生成事务的父信息。
    • MySQL Shell用于配置InnoDB Cluster,配置脚本需要访问Python 2.7版本。

  3. 安装方法

    用户安装InnoDB Cluster的方法取决于使用的部署方式。对于Sandbox deployment,将集群组件安装在单个计算机上。Sandbox deployment部署是单个计算机的本地部署,因此安装只需要在本地计算机完成一次。对于生产部署,请将组件安装到每台计算机上。

  4. Sandbox deployment

    您可以使用包含AminAPI的MySQL Shell创建和管理InnoDB集群。在生产部署之前,您可以使用Sandbox deployment InnoDB Cluster是探索集群的最好方式。MySQL Shell内置Sandbox deployment,可用于创建正确配置的InnoDB Cluster集群。

    注意

    Sandbox deployment仅适用于在本地计算机上进行部署和测试。在生产环境中,MySQL Server实例部署到网络上的各种主机。

    部署Sandbox实例

    MySQL Shell提供的AdminAPI中的dba全局变量提供了Sandbox deployment的功能,你可以使用dba.deploySandboxInstance()创建并部署Sandbox实例。

    启动MySQL Shell

    > mysqlsh
    

    MySQL Shell除了包含SQL模式之外,还提供了两种脚本语言模式,Javascript和Python。本次示例中,主要通过Javascript模式来创建Sandbox InnoDB Cluster。在MySQL Shell中可以通过\js\py\sql命令来切换模式,默认处于Javascript模式。

    msyql-js> dba.deploySandboxInstance(3310)
    

    注意

    在Javascript和Python模式下,不需要使用分号终止命令。

    传递给deploySandboxInstance()的参数是MySQL端口号,MySQL实例将监听来自3310端口的连接。命令执行后,将提示输入实例的root密码。

    注意

    每个实例都有自己的密码。在测试环境中建议密码设置的尽可能简单和相同,但是生产部署中尽可能的为每个实例使用不同的密码。

    要部署其他Sandbox实例,请重复上述命令:

    msyql-js> dba.deploySandboxInstance(3320)
    msyql-js> dba.deploySandboxInstance(3330)
    
    创建Sandbox InnoDB Cluster

    下一步连接到MySQL Server主服务器(该服务器是包含其他实例要复制数据的实例)创建InnoDB Cluster。在本次示例中,Sandbox实例为空,因此您可以选择任何实例。

    使用MySQL Shell连接到主实例,在本例中连接3310端口的实例:

    mysql-js> \connect root@localhost:3310
    

    \connect是MySQL Shell中shell.connect()方法的快捷方法:

    mysql-js> shell.connect('root@localhost:3310')
    

    连接后,AdminAPI可以写入本实例的配置文件。这与使用生产部署不同是,在生产部署中,您需要连接到远程实例并在实例上本地运行MySQL Shell应用程序,然后AdminAPI才能写入实例的配置文件。

    使用dba.createCluster()方法创建InnoDB集群,并将当前连接的实例作为主服务器:

    mysql-js> var cluster = dba.createCluster('testCluster')
    

    createCluster()将InnoDB Cluster元数据配置到所选择实例,并将当前连接的实例作为主实例。createCluster()方法返回创建的集群,在上面的示例中,它被分配给cluster变量。createCluster()的参数是为InnoDB Cluster赋予名称。

    将实例添加到InnoDB Cluster

    由主实例执行的事务都会在从属实例添加时重新执行。

    由于示例主服务器数据是空的。在生产环境中,主实例有很多数据,建议通过数据库备份软件备份现有数据,并在其他的实例恢复,从而减少从属数据库复制数据造成的延迟。

    添加第二个实例InnoDB Cluster:

    mysql-js> cluster.addInstance('root@localhost:3320')
    

    提示输入root用户密码。

    添加第三个实例

    mysql-js> cluster.addInstance('root@localhost:3330')
    

    提示

    如是实例时Sandbox实例,只能指定localhost实例。

    存储集群配置

    将Sandbox实例添加到集群中,必须将InnoDB集群所需的配置保留到每个实例的配置文件中。

    使用dba.configureLocalInstance('instance')可以将实例的配置保存到每个实例的配置文件中。

    mysql-js> \connect instance
    mysql-js> dba.configureLocalInstance('instance')
    

    注意

    若dba.configureLocalInstance()没有执行成功,实例在下次重启后将无法重新加入集群。

    重复以上操作,保证各个Sandbox实例的配置保存,对于此示例,需要在3310,3320,3330端口进行配置的存储。

    mysql-js> \connect root@localhost:port_number)
    mysql-js> dba.configureLocalInstance('root@localhost:port_number)
    

    要检查是否已创建集群,请使用集群实例的status()功能。

    部署集群后,您可以配置MySQL Router以提高高可用性。

  5. 生产部署

    在生产环境中,组成InnoDB集群的MySQL服务器实例作为网络的一部分在多台主机上运行,而不是在单机上运行。

    下图说明了您在本节使用的方案:

    注意

    与Sandbox deployment不同的是,对于生产部署,您必须连接每台计算机并使用MySQL Shell提供的AdminAPI的dba.configureLocalInstance()保存每个实例的配置。您还可以通过MySQL Shell控制访问集群权限。

    用户权限

    用户管理实例的用户账号可以不是root账户,但需要分配MySQL管理员全读权限并写入集群的元数据表当中(SUPER, GRANT OPTION, CREATE, DROP等)。为your_user提供管理InnoDB集群所需权限:

    GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata.* TO your_user@'%' WITH GRANT OPTION;
    GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, \
    CREATE USER ON *.* TO your_user@'%' WITH GRANT OPTION;
    GRANT SELECT ON *.* TO your_user@'%' WITH GRANT OPTION;
    

    如果仅需读取操作,则可以使用具有更多受限特权的账号。为your_user提供监控InnoDB集群权限:

    GRANT SELECT ON mysql_innodb_cluster_metadata.* TO your_user@'%';
    GRANT SELECT ON performance_schema.global_status TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_applier_configuration TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_applier_status TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_connection_configuration TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_connection_status TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_group_member_stats TO your_user@'%';
    GRANT SELECT ON performance_schema.replication_group_members TO your_user@'%';
    GRANT SELECT ON performance_schema.threads TO your_user@'%' WITH GRANT OPTION;
    
    配置主机名

    组成集群的生产实例在不同的计算机上运行,因此每台计算机必须具有唯一的主机名,并且能够解析集群中运行服务器实例的其他计算机主机名。如果不符合这种情况,您可以

    • 配置每台计算机以将每台其他计算机的IP映射到主机名。
    • 配置DNS服务
    • report_host每个实例的配置为外部可访问的地址

    要验证是否正确配置了MySQL服务器的主机名,请执行以下查询查看实例如何将自己的地址报告给其他服务器,并尝试使用返回的地址从其他主连接到该MySQL服务器:

    SELECT coalesce(@@report_host, @@hostname);
    
    详细日志

    使用生产部署时,为MySQL Shell配置详细日志记录能帮助您查找和解决在准备服务器实例作为InnoDB集群一部分发生的任何为题。使用--log-level选项设置:

    ps> mysqlsh --log-level=DEBUG3
    

    除了启用MySQL Shell日志,您可以查看每次调用API后的输出内容:

    mysql-js> dba.verbose=2
    

    这是AdminAPI调用的最完整输出。可用的输出选项:

    • 0或OFF表示不进行故障排除时的推荐时,该值也时默认值
    • 1或ON每次调用的都会输出详细的内容
    • 2将调试内容完整的数据。
    检查实例配置

    在生产服务器部署之前,您可以使用dba.checkInstanceConfiguration()功能检查每个实例上的MySQL是否满足InnoDB集群配置,该操作不会检查实例上任何数据,以下时演示数据:

    mysql-js> dba.checkInstanceConfiguration('ic@ic-1:3306')
    
    Please provide the password for 'ic@ic-1:3306':
    Validating instance...
    
    The instance 'ic-1:3306' is not valid for Cluster usage.
    
    The following issues were encountered:
    
    - Some configuration options need to be fixed.
    
    +----------------------------------+---------------+----------------+--------------------------------------------------+
    | Variable                         | Current Value | Required Value | Note                                             |
    +----------------------------------+---------------+----------------+--------------------------------------------------+
    | binlog_checksum                  | CRC32         | NONE           | Update the server variable or restart the server |
    | enforce_gtid_consistency         | OFF           | ON             | Restart the server                               |
    | gtid_mode                        | OFF           | ON             | Restart the server                               |
    | log_bin                          | 0             | 1              | Restart the server                               |
    | log_slave_updates                | 0             | ON             | Restart the server                               |
    | master_info_repository           | FILE          | TABLE          | Restart the server                               |
    | relay_log_info_repository        | FILE          | TABLE          | Restart the server                               |
    | transaction_write_set_extraction | OFF           | XXHASH64       | Restart the server                               |
    +----------------------------------+---------------+----------------+--------------------------------------------------+
    
    
    Please fix these issues , restart the server and try again.
    
    {
      "config_errors": [
        {
          "action": "server_update",
          "current": "CRC32",
          "option": "binlog_checksum",
          "required": "NONE"
        },
        {
          "action": "restart",
          "current": "OFF",
          "option": "enforce_gtid_consistency",
          "required": "ON"
        },
        {
          "action": "restart",
          "current": "OFF",
          "option": "gtid_mode",
          "required": "ON"
        },
        {
          "action": "restart",
          "current": "0",
          "option": "log_bin",
          "required": "1"
        },
        {
          "action": "restart",
          "current": "0",
          "option": "log_slave_updates",
          "required": "ON"
        },
        {
          "action": "restart",
          "current": "FILE",
          "option": "master_info_repository",
          "required": "TABLE"
        },
        {
          "action": "restart",
          "current": "FILE",
          "option": "relay_log_info_repository",
          "required": "TABLE"
        },
        {
          "action": "restart",
          "current": "OFF",
          "option": "transaction_write_set_extraction",
          "required": "XXHASH64"
        }
      ],
      "errors": [],
      "restart_required": true,
      "status": "error"
    }
    mysql-js>
    

    对计划集群中的每一个实例重复此过程,以检查实例是否符合集群运行的条件。

    配置实例

    您可以根据dba.checkInstanceConfiguration()检查报告在配置文件配置以上选项从而保证数据库服务符合InnoDB集群要求。您还可以通过dba.configureLocalInstance()自动配置实例以符合集群要求。以下时示例数据:

    mysql-js> dba.configureLocalInstance('root@localhost:3306')
    
    Please provide the password for 'root@localhost:3306':
    
    Please specify the path to the MySQL configuration file: /etc/mysql/mysql.conf.d/mysqld.cnf
    Validating instance...
    
    The configuration has been updated but it is required to restart the server.
    {
      "config_errors": [
        {
          "action": "restart",
          "current": "OFF",
          "option": "enforce_gtid_consistency",
          "required": "ON"
        },
        {
          "action": "restart",
          "current": "OFF",
          "option": "gtid_mode",
          "required": "ON"
          },
        {
          "action": "restart",
          "current": "0",
          "option": "log_bin",
          "required": "1"
        },
        {
          "action": "restart",
          "current": "0",
          "option": "log_slave_updates",
          "required": "ON"
        },
        {
          "action": "restart",
          "current": "FILE",
          "option": "master_info_repository",
          "required": "TABLE"
        },
        {
          "action": "restart",
          "current": "FILE",
          "option": "relay_log_info_repository",
          "required": "TABLE"
        },
        {
          "action": "restart",
          "current": "OFF",
          "option": "transaction_write_set_extraction",
          "required": "XXHASH64"
        }
      ],
      "errors": [],
      "restart_required": true,
      "status": "error"
    }
    mysql-js>
    
    创建集群

    使用MySQL Shell连接主数据库服务器,并在该服务器上创建集群。

    shell> mysqlsh --uri username@hostname:port
    mysql-js> var cluster = dba.createCluster('prodCluster')
    
          A new InnoDB cluster will be created on instance 'ic@ic-1:3306'.
    
          Creating InnoDB cluster 'prodCluster' on 'ic@ic-1:3306'...
          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.
    

    添加其他实例到InnoDB集群:

    mysql-js> cluster.addInstance('username@hostname:port')
    

    注意

    在次阶段,服务器实例已添加到集群,但InnoDB集群的元数据更改尽在当前连接有效。您必须在没给实例使用dba.configureLocalInstance()保证实例配置保存到服务器上面,以便下次重启后使用。

  6. 采用组复制部署

    若您的服务器实例已经具备组复制功能,并且希望使用它来创建集群,请将adoptFromGR选项传递给dba.createCluster()。创建的InnoDB集群会匹配复制组是以单主数据库还是多主数据库运行。

    提示

    若组复制实例中包含MyISAM引擎创建的表,将所有此类表转换为InnoDB存储引擎,才可创建集群

    mysql-js> var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});
    
    A new InnoDB cluster will be created on instance 'root@gr-member-2:3306'.
    
    Creating InnoDB cluster 'prodCluster' on 'root@gr-member-2:3306'...
    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.