写点什么

百尺竿头更进一步丨拓展 Amazon Aurora 的读写能力之 Gaea 篇

  • 2022 年 5 月 21 日
  • 本文字数:9874 字

    阅读完需:约 32 分钟

前言

Amazon Aurora 是亚马逊云科技自研的一项关系数据库服务,它在提供和开源数据库 MySQL、PostgreSQL 的完好兼容性同时,也能够提供和商业数据库媲美的性能和可用性。性能方面,Aurora MySQL 能够支持到与开源标准 MySQL 同等配置下五倍的吞吐量,Amazon Aurora PostgreSQL 能够支持与开源标准 PostgreSQL 同等配置下三倍的吞吐量的提升。在扩展性的角度,Amazon Aurora 在存储与计算、横向与纵向方面都进行了功能的增强和创新。


Amazon Aurora 的最大数据存储量现在支持多达 128TB,而且可以支持存储的动态收缩。计算方面,Amazon Aurora 提供多个读副本的可扩展性配置支持一个区域内 15 个多达 15 个读副本的扩展,提供多主的架构来支持同一个区域内 4 个写节点的扩展,提供 Serverless 无服务器化的架构实例级别的秒级纵向扩展,提供全球数据库来实现数据库的低延迟跨区域扩展。


随着用户数据量的增长,Amazon Aurora 已经提供了很好的扩展性,那是否可以进一步增强更多的数据量、更多的并发访问能力呢?您可以考虑利用分库分表的方式,来支持底层多个 Amazon Aurora 集群的配置。基于此,包含这篇博客在内的系列博客会进行相应的介绍,旨在为您进行分库分表时代理选择提供参考。


本篇博客会聚焦如何使用开源的 Gaea proxy ,一个开源的分库分表中间件工具,来进行数据库集群的构建。会涵盖分库分表、读写分离、分片表关联查询和 failover 自动识别等方面。

Gaea 介绍

Gaea 是某互联网电商开源的基于 mySQL 协议的数据库中间件,Gaea 支持分库分表、SQL 路由、读写分离,配置热加载,连接池,自定义 SQL 拦截与过滤等基本特性,并支持分片表和全局表的 join、支持多个分片表但是路由规则相同的 join。


更多功能介绍,请参阅 Github https://github.com/XiaoMi/Gaea 最新说明

1、设计架构图



Gaea 包含四个模块,分别是 Gaea-proxy、Gaea-cc、Gaea-agent、Gaea-web。Gaea-proxy 为在线代理,负责承接 SQL 流量,Gaea-cc 是中控模块,负责 Gaea-proxy 的配置管理及一些后台任务,Gaea-agent 部署在 mysql 所在的机器上,负责实例创建、管理、回收等工作,Gaea-web 是 Gaea 的一个管理界面,使 Gaea 整体使用更加方便。

2、基本概念

cluster

集群, 按照业务重要程度划分集群, 一个集群内可包含多个 Gaea-proxy 实例, 通过指定 Gaea-proxy 启动时依赖的配置文件中的 cluster_name 确定该 proxy 所属集群。集群内的 proxy 实例只为该集群内的 namespace 提供服务, 起到物理隔离的作用。一套集群可为多个 namespace 提供服务。


namespace

命名空间,每一个业务系统对应一个 namespace,一个 namespace 对应多个 database,业务方可以自由切换。每个 namespace 理论上只会属于一个集群。通过 Gaea-cc 配置管理接口, 指定 namespace 所属集群。


slice

分片,逻辑上的分组,一个分片包含 mysql 一主多从。


shard

分表规则,确定一个表如何分表,包括分表的类型、分布的分片位置。


proxy

指代理本身,承接线上流量。


gaea_cc

代理控制模块,主要负责配置下发、实例监控等。


3、部署架构图

在生产环境中可以参考以下部署架构图来实现多 mySQL 集群的代理和集中式的配置管理,图中 Gaea 核心集群和普通集群没有区别。


环境构建

1、Amazon Aurora 集群

首先创建三套 Aurora MySQL 集群,机型为 db.r5.2xlarge,每套集群有一个写节点一个读节点。


2、Gaea proxy 搭建

1)安装 Go 语言环境

参考 https://go.dev/doc/install


2)下载源码并编译

git clone https://github.com/XiaoMi/Gae...

cd Gaea && make

完成后会在 bin 目录出现 gaea and gaea-cc

[ec2-user@ip-172-31-29-68 bin]$ ls

gaea gaea-cc

3、Proxy 配置

Gaea 配置由两部分组成,本地配置为 Gaea_proxy 直接使用的配置内容,一般不需要在运行时改变。gaea 为多租户模式,每个租户称为一个 namespace,namespace 的配置在运行时都可变,一般存放在 etcd 中,以下以 json 文件替代 etcd 做演示,配置的详细说明请参考 Github 的说明。


1)准备好本地基础配置文件,该文件用于 Gaea 的全局配置,该配置文件放在 $Gaea_Home/etc,参考以下例子:


; 配置类型,目前支持file/etcd两种方式,file方式不支持热加载,但是可以快速体验功能; file 模式下读取file_config_path下的namespace配置文件; etcd 模式下读取coordinator_addr/cluster_name下的namespace配置文件config_type=file;file config path, 具体配置放到file_config_path的namespace目录下,该下级目录为固定目录file_config_path=/data/gaea/Gaea/etc/file;配置中心地址,目前只支持etcd;coordinator_addr=http://127.0.0.1:2379;配置中心用户名和密码;username=test;password=test;环境划分、test、onlineenviron=test;service nameservice_name=gaea_proxy;gaea_proxy 当前proxy所属的集群名称cluster_name=gaea_default_cluster;日志配置log_path=/data/gaea/Gaea/loglog_level=Noticelog_filename=gaealog_output=file;管理地址admin_addr=0.0.0.0:13399;basic authadmin_user=adminadmin_password=admin;代理服务监听地址proto_type=tcp4proxy_addr=0.0.0.0:13306; 默认编码proxy_charset=utf8;慢sql阈值,单位: 毫秒slow_sql_time=100;空闲会话超时时间,单位: 秒session_timeout=3600;打点统计配置stats_enabled=truestats_interval=10;encrypt key, 用于对etcd中存储的namespace配置加解密encrypt_key=1234abcd5678efg*;server_version 服务器版本号配置server_version=5.7-gaea;auth plugin mysql_native_password or caching_sha2_password or '';自定义认证插件,支持 5.x 和 8.x 版本认证,认证插件为 caching_sha2_password 时,不支持低版本客户端认证auth_plugin=mysql_native_password
复制代码

左滑查看更多


2)准备好 sharding 的配置文件

Gaea 支持多租户,每个租户单独一个 namespace,每个 namespace 一个配置文件

Gaea 支持 kingshard 和 mycat 两种 sharding 方式,本次测试使用 kingshard 的 hash 方式分表,

namespace 配置文件必须位于 Gaea 编译目录 etc/file/namespace 目录下,以下配置主要做这些事项:


  1. 同时开启 kingshard 和 mycat 两种分库分表方式(测试只用 kingshard 这种)

  2. 配置前端接受请求的用户(Gaea)和后端连接 Amazon Aurora 的用户(root)

  3. 启用读写分离

  4. 数据分片规则如下:

  • 使用 kingshard 的 hash 方式对 tbl_ks 做了 3 个物理集群(slice),分片 key 配置的是 id 字段

  • 3 个物理分片下都有一个分表(location 1,1,1)

  • 把 tbl_ks2 表配置成 tbl_ks 的关联表(proxy 自动会根据父表的分片规则把子表数据分布到同 slice 中以方便做 join 和关联查询)

  • 把 tbl_global 配置成全局表(所有分片都有这个表的全量数据)

  • 非分片查询的 SQL 默认发送到 slice 1(default_slice”: “slice-1)


    }
],"global_sequences": [
],"users": [ { "user_name": "gaea", "password": "gaea_password", "namespace": "gaea_namespace_1", "rw_flag": 2, "rw_split": 1 }],"default_slice": "slice-1","open_general_log": false,"max_sql_execute_time": 5000,"max_sql_result_size": 100000}
复制代码

左滑查看更多

4、启动 Proxy

使用 bin 目录下的 Gaea 二进制文件启动,指定好静态配置文件路径


[root@ip-172-31-29-68 etc]# ../bin/gaea -config ./test.iniBuild Version Information:Version: fbac80acdd922a3d563bc703994f7f9145c2d41bGitRevision: fbac80acdd922a3d563bc703994f7f9145c2d41bUser: root@ip-172-31-29-68.ap-southeast-1.compute.internalGolangVersion: go1.17.6BuildStatus: CleanBuildTime: 2022-02-09--07:13:01BuildBranch: masterBuildGitDirty: 0[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.using env: export GIN_MODE=releaseusing code: gin.SetMode(gin.ReleaseMode)[GIN-debug] GET /api/proxy/ping --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).ping-fm (2 handlers)[GIN-debug] PUT /api/proxy/config/prepare/:name --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).prepareConfig-fm (2 handlers)[GIN-debug] PUT /api/proxy/config/commit/:name --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).commitConfig-fm (2 handlers)[GIN-debug] PUT /api/proxy/namespace/delete/:name --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).deleteNamespace-fm (2 handlers)[GIN-debug] GET /api/proxy/config/fingerprint --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).configFingerprint-fm (2 handlers)[GIN-debug] GET /api/proxy/stats/sessionsqlfingerprint/:namespace --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).getNamespaceSessionSQLFingerprint-fm (2 handlers)[GIN-debug] GET /api/proxy/stats/backendsqlfingerprint/:namespace --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).getNamespaceBackendSQLFingerprint-fm (2 handlers)[GIN-debug] DELETE /api/proxy/stats/sessionsqlfingerprint/:namespace --> github.com/XiaoMi/Gaea/proxy/server.(AdminServer).clearNamespaceSessionSQLFingerprint-fm (2 handlers)[GIN-debug] DELETE /api/proxy/stats/backendsqlfingerprint/:namespace --> github.com/XiaoMi/Gaea/proxy/server.(*AdminServer).clearNamespaceBackendSQLFingerprint-fm (2 handlers)[GIN-debug] GET /api/metric/metrics --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)[GIN-debug] GET /debug/pprof/ --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/cmdline --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/profile --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] POST /debug/pprof/symbol --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/symbol --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/trace --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/block --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/goroutine --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/heap --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/mutex --> github.com/gin-gonic/gin.WrapF.func1 (2 handlers)[GIN-debug] GET /debug/pprof/threadcreate --> github.com/gin-gonic/gin.WrapF.func1
复制代码

左滑查看更多

5、验证连接

使用动态配置文件中指定的用户名和密码连接 proxy,因为上面的动态配置文件开启了 kingshard 和 mycat 两种分库分表方式,所以登陆后默认看到两个预先配置好的 proxy 里的 database:


[root@ip-172-31-29-68 namespace]# mysql -ugaea -pgaea_password -P13306 -h172.31.29.68Welcome to the MariaDB monitor. Commands end with ; or \g.Your MySQL connection id is 10001Server version: 5.6.20-gaea MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> show databases;+----------+| Database |+----------+| db_ks || db_mycat |+----------+2 rows in set (0.00 sec)
复制代码

左滑查看更多

功能测试

1、分库分表验证

Gaea 因为对 DDL 兼容性一般,官网建议预先在后端数据库创建好对应的数据库然后再在 proxy 应用规则。因为我们使用 kingshard 的 hash 规则分表,我们预先在每个 Amazon Aurora 建好相应的数据库和表,注意:table 必须是从 0000 开始


CREATE TABLE IF NOT EXISTS tbl_ks_0000(id INT UNSIGNED AUTO_INCREMENT,col1 VARCHAR(100) NOT NULL,col2 VARCHAR(40) NOT NULL,col_date DATE,PRIMARY KEY ( id ))ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

左滑查看更多



  • 插入数据并查看



MySQL [db_ks]> select * from tbl_ks;+----+-------+-------+------------+| id | col1 | col2 | col_date |+----+-------+-------+------------+| 3 | name3 | addr3 | 2022-02-11 || 1 | name1 | addr1 | 2022-02-11 || 4 | name4 | addr4 | 2022-02-11 || 2 | name2 | addr2 | 2022-02-11 |+----+-------+-------+------------+4 rows in set (0.03 sec)
复制代码

左滑查看更多


  • 分别登陆 3 个 Amazon Aurora 检查数据,验证按 id 做了 hash 分布


[root@ip-172-31-29-68 ec2-user]# mysql -uroot -pPass1234 -hshard-1.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -P3306 -e "select * from db_ks.tbl_ks_0000"+----+-------+-------+------------+| id | col1 | col2 | col_date |+----+-------+-------+------------+| 3 | name3 | addr3 | 2022-02-11 |+----+-------+-------+------------+[root@ip-172-31-29-68 ec2-user]# mysql -uroot -pPass1234 -hshard-2.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -P3306 -e "select * from db_ks.tbl_ks_0001"+----+-------+-------+------------+| id | col1 | col2 | col_date |+----+-------+-------+------------+| 1 | name1 | addr1 | 2022-02-11 || 4 | name4 | addr4 | 2022-02-11 |+----+-------+-------+------------+[root@ip-172-31-29-68 ec2-user]# mysql -uroot -pPass1234 -hshard-3.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -P3306 -e "select * from db_ks.tbl_ks_0002"+----+-------+-------+------------+| id | col1 | col2 | col_date |+----+-------+-------+------------+| 2 | name2 | addr2 | 2022-02-11 |
复制代码

左滑查看更多

2、全局表测试

全局表是在各个 slice 上 (准确的说是各个 slice 的各个 DB 上) 数据完全一致的表,方便执行一些跨分片查询,如果是小表和分片表做 join 推荐使用全局表这种方式,对应在 shard_rules 的配置如下这段:


 {            "db": "db_ks",            "table": "tbl_global",            "type": "global",            "locations": [                1,                1,                1            ],    "slices": [        "slice-1",        "slice-2",        "slice-3"    ]
复制代码

左滑查看更多


测试过程如下:


  • 在 Amazon Aurora 后端数据库建表

同样的,因为 Gaea 不支持 DDL,需要先在所有后端数据库建好表,再应用规则


CREATE TABLE IF NOT EXISTS tbl_global(   id INT UNSIGNED AUTO_INCREMENT,   PRIMARY KEY ( id )   )ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

左滑查看更多


  • 连接 proxy 并 插入数据


插入一行会提示 3 rows affected


MySQL [db_ks]> insert into tbl_global (id) values (1);Query OK, 3 rows affected (0.02 sec)MySQL [db_ks]> insert into tbl_global (id) values (2);Query OK, 3 rows affected (0.02 sec)MySQL [db_ks]> insert into tbl_global (id) values (3);Query OK, 3 rows affected (0.02 sec)
复制代码

左滑查看更多


  • 登陆每一个 Amazon Aurora 看是否插入了 3 行数据


[ec2-user@ip-172-31-29-68 ~]$ mysql -uroot -pPass1234 -hshard-1.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -e "select * from db_ks.tbl_global"+----+| id |+----+|  1 ||  2 ||  3 |+----+
复制代码

左滑查看更多


  • 做全局表和分片表 join 的测试


MySQL [db_ks]> select * from tbl_global,tbl_ks where tbl_ks.id=tbl_global.id;+----+----+-------+-------+------------+| id | id | col1  | col2  | col_date   |+----+----+-------+-------+------------+|  2 |  2 | name2 | addr2 | 2022-02-11 ||  3 |  3 | name3 | addr3 | 2022-02-11 ||  1 |  1 | name1 | addr1 | 2022-02-11 |+----+----+-------+-------+------------+3 rows in set (0.05 sec)
复制代码

左滑查看更多


  • 通过执行计划来验证


MySQL [db_ks]> explain select * from tbl_global,tbl_ks where tbl_ks.id=tbl_global.id;+-------+---------+-------+--------------------------------------------------------------------------------------------+| type  | slice   | db    | sql                                                                                        |+-------+---------+-------+--------------------------------------------------------------------------------------------+| shard | slice-1 | db_ks | SELECT * FROM (`tbl_global`) JOIN `tbl_ks_0000` WHERE `tbl_ks_0000`.`id`=`tbl_global`.`id` || shard | slice-2 | db_ks | SELECT * FROM (`tbl_global`) JOIN `tbl_ks_0001` WHERE `tbl_ks_0001`.`id`=`tbl_global`.`id` || shard | slice-3 | db_ks | SELECT * FROM (`tbl_global`) JOIN `tbl_ks_0002` WHERE `tbl_ks_0002`.`id`=`tbl_global`.`id` |+-------+---------+-------+--------------------------------------------------------------------------------------------+3 rows in set (0.00 sec)
复制代码

左滑查看更多

3、全局表数据一致性测试

先说结论,通过 proxy 写全局表的时候,这个事务不是原子性的。


假如分片 1 的全局表存在了 id=1,其他两个分片没有这条数据,这时候从 proxy insert id=1 会报错但是分片 2 和 3 都可以成功写入本地, 所以需要定期检查全局表是否数据一致。


# 在分片1 手动插入id=4 制造不一致mysql -uroot -pPass1234 -hshard-1.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -e "insert into db_ks.tbl_global values (4)"# 在proxy insert id=4 会报错MySQL [db_ks]>  insert into tbl_global (id) values (4);ERROR 1105 (HY000): unknown error: execute in InsertPlan error: ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'# 在分片2 和3 查看全局表能发现id=4 这条数据[ec2-user@ip-172-31-29-68 ~]$ mysql -uroot -pPass1234 -hshard-2.cluster-c3luzotrlr7v.ap-southeast-1.rds.amazonaws.com -e "select * from db_ks.tbl_global"+----+| id |+----+|  1 ||  2 ||  3 ||  4 |+----+
复制代码

左滑查看更多

4、父表和子表做 join 查询

1) 验证子表的数据分布


# 连接proxy手动插入3条数据到MySQL [db_ks]> insert into tbl_ks2 (id) values (1);Query OK, 1 row affected (0.01 sec)MySQL [db_ks]>MySQL [db_ks]> insert into tbl_ks2 (id) values (2);Query OK, 1 row affected (0.01 sec)MySQL [db_ks]> insert into tbl_ks2 (id) values (3);Query OK, 1 row affected (0.01 sec)
MySQL [db_ks]> explain select * from tbl_ks2;+-------+---------+-------+------------------------------+| type | slice | db | sql |+-------+---------+-------+------------------------------+| shard | slice-1 | db_ks | SELECT * FROM `tbl_ks2_0000` || shard | slice-2 | db_ks | SELECT * FROM `tbl_ks2_0001` || shard | slice-3 | db_ks | SELECT * FROM `tbl_ks2_0002` |+-------+---------+-------+------------------------------+3 rows in set (0.00 sec)
复制代码

左滑查看更多


从上面的执行结果确认子表也是按照父表的规则做了分片,并且 id 字段 hash 后和父表在同分片


2)验证父表和子表做 join 查询


# 先看看父表的数据MySQL [db_ks]> select * from tbl_ks;+----+----------+-------+------------+| id | col1     | col2  | col_date   |+----+----------+-------+------------+|  2 | name2    | addr2 | 2022-02-11 ||  3 | name3    | addr3 | 2022-02-11 ||  1 | failover | addr1 | 2022-02-11 ||  4 | name4    | addr4 | 2022-02-11 |+----+----------+-------+------------+4 rows in set (0.04 sec)
复制代码

左滑查看更多


join 测试


MySQL [db_ks]> select * from tbl_ks,tbl_ks2 where tbl_ks.id=tbl_ks2.id;+----+----------+-------+------------+----+| id | col1     | col2  | col_date   | id |+----+----------+-------+------------+----+|  3 | name3    | addr3 | 2022-02-11 |  3 ||  1 | failover | addr1 | 2022-02-11 |  1 ||  2 | name2    | addr2 | 2022-02-11 |  2 |+----+----------+-------+------------+----+MySQL [db_ks]> explain select * from tbl_ks,tbl_ks2 where tbl_ks.id=tbl_ks2.id;+-------+---------+-------+------------------------------------------------------------------------------------------------+| type  | slice   | db    | sql                                                                                            |+-------+---------+-------+------------------------------------------------------------------------------------------------+| shard | slice-2 | db_ks | SELECT * FROM (`tbl_ks_0001`) JOIN `tbl_ks2_0001` WHERE `tbl_ks_0001`.`id`=`tbl_ks2_0001`.`id` || shard | slice-3 | db_ks | SELECT * FROM (`tbl_ks_0002`) JOIN `tbl_ks2_0002` WHERE `tbl_ks_0002`.`id`=`tbl_ks2_0002`.`id` || shard | slice-1 | db_ks | SELECT * FROM (`tbl_ks_0000`) JOIN `tbl_ks2_0000` WHERE `tbl_ks_0000`.`id`=`tbl_ks2_0000`.`id` |+-------+---------+-------+------------------------------------------------------------------------------------------------+3 rows in set (0.00 sec)
复制代码

左滑查看更多


从上面执行结果看,父表和子表可以通过 sharding key 做关联做 join 查询。

5、检查读写分离是否实现

编写脚本验证读请求是否都发往从库执行


#!/bin/bashwhile true;domysql -ugaea -pgaea_password -P13306 -h172.31.29.68 -e "use db_ks;select  * from tbl_ks;"sleep 0.1done
复制代码

左滑查看更多


结果如下图所示,所有的读请求都发往了 replica 节点执行,主节点没有收到查询请求


6、故障恢复验证

此测试在于验证当 Aurora failover 的时候验证 proxy 是否能在不改变配置的情况下自动识别 failover 的发生并自动恢复。


测试脚本如下:


[root@ip-172-31-29-68 ec2-user]# cat test_failover.sh#!/bin/bashwhile truedo     mysql -ugaea -pgaea_password -P13306 -h172.31.29.68 -e "use db_ks; update  tbl_ks set col1='failover' where id = 1;"    now=$(date +"%T")    echo "update done: $now"    sleep 1
done
复制代码

左滑查看更多


运行脚本,然后在 Amazon Aurora 集群的写节点上点击 Action→Failover。会启动 Amazon Aurora 写节点和读节点的自动切换。在切换过程中,整个集群的读/写 endpoint 和只读 endpoint 维持不变,只是底层映射的节点发生变化。



从 Event 看 Amazon Aurora 30 秒内完成 failover



但是从脚本输出看,proxy 一直在报错,不能自动发现 failover 事件


ERROR 1105 (HY000) at line 1: unknown error: execute in UpdatePlan error: ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statementupdate done: 11:52:09ERROR 1105 (HY000) at line 1: unknown error: execute in UpdatePlan error: ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
复制代码

左滑查看更多


需要重启 proxy 才能恢复正常的写入

结语

本篇文章通过数据库中间件的方法来拓展了 Amazon Aurora 的分库分表能力和读写分离的能力。通过 Gaea,这个方案能够实现连接池、SQL 的兼容性、跨分片路由、读写分离、分片表和全局表 join 以及父表和子表做关联查询的能力。不足之处在于 Gaea 在 Aurora failover 发生后不能识别和自动恢复,需要重启或者手动刷新配置等方式才能恢复。


后续我们会继续推出对其他中间件的拓展和研究系列博客。


本篇作者


张振威


亚马逊云科技 APN 解决方案架构师


主要负责合作伙伴架构咨询和方案设计,同时致力于亚马逊云科技云服务在国内的应用及推广,擅长数据迁移,数据库调优和数据分析相关。



用户头像

还未添加个人签名 2019.09.17 加入

还未添加个人简介

评论

发布
暂无评论
百尺竿头更进一步丨拓展 Amazon Aurora 的读写能力之 Gaea 篇_Amazon_亚马逊云科技 (Amazon Web Services)_InfoQ写作社区