likes
comments
collection
share

技术分享 | mysql与StoneDB的GTID主从复制集群搭建

作者站长头像
站长
· 阅读数 28

测试背景

从MySQL5.6开始增加了强大的GTID(Global Transaction ID,全局事务ID)这个特性,用来强化数据库的主备一致性, 故障恢复, 以及容错能力。用于取代过去传统的主从复制(即:基于binlog和position的异步复制)。借助GTID,在发生主备切换的情况下,MySQL的其他slave可以自动在新主上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制position发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识,保存在mysql数据目录下的auto.cnf文件里。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。下面是一个GTID的具体形式:3E11FA47-71CA-11E1-9E33-C80AA9429562:23。

GTID是由server_uuid和事务id组成的,即GTID=server_uuid:transaction_id。 server_uuid,是在MySQL第一次启动时自动生成并持久化到auto.cnf文件(存放在数据目录下,每台机器的server_uuid都不一样。

实验环境

IP软件版本作用引擎
192.168.178.1295.7.34-MySQL Community主机innodb
192.168.178.1305.7.36-StoneDB-v1.0.4从机TIANMU

主机配置

[my.cnf]配置文件里面加入以入4个参数
log_bin=mysql-bin
server-id=1
gtid_mode = on
enforce_gtid_consistency = 1

重启mysql


mysql> CREATE USER 'stonedb'@'192.168.178.130' IDENTIFIED WITH mysql_native_password BY 'P@ssw0rd';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'stonedb'@'192.168.178.130';


mysql> create  database  mysql2stone;
Query OK, 1 row affected (0.17 sec)

mysql> use mysql2stone;
Database changed
mysql> create table  mystone(name varchar(50));
Query OK, 0 rows affected (1.16 sec)

从机配置

/opt/stonedb57/install/my.cnf配置文件里面加入以入3个参数

server-id = 2
#开启GTID模式
gtid_mode = on
enforce_gtid_consistency = 1


基于从机对接上主机的配置信息
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.178.129',
MASTER_PORT=3306,
MASTER_USER='stonedb',
MASTER_PASSWORD='P@ssw0rd',
MASTER_AUTO_POSITION = 1575;


启动从机线程
mysql> start slave;


检验主从复制配置状态

技术分享 | mysql与StoneDB的GTID主从复制集群搭建 主要看关键的两个线程有没有在干活

  • Slave_IO_State:从库当前的状态。
  • Slave_IO_Running:从库的I/O线程是否运行,通常情况为Yes.
  • Slave_SOL_Running:从库的SQL线程是否运行,通常情况为Yes.
  • Last_IO_Error,Last_SQL_Error:最近I/O线程和SQL线程的错误,通常情况下应该为空,代表复制正常运行。
  • Seconds_Behind_Master:从库落后主库的秒数
mysql> select * from performance_schema.replication_connection_status\G;
*************************** 1. row ***************************
             CHANNEL_NAME:
               GROUP_NAME:
              SOURCE_UUID: 35ba7ca7-4b1e-11ee-92b9-000c29f88f2f
                THREAD_ID: 37
            SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 74
 LAST_HEARTBEAT_TIMESTAMP: 2023-09-04 09:57:21
 RECEIVED_TRANSACTION_SET: 35ba7ca7-4b1e-11ee-92b9-000c29f88f2f:1-4
        LAST_ERROR_NUMBER: 0
       LAST_ERROR_MESSAGE:
     LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00
1 row in set (0.01 sec)
mysql> select * from performance_schema.replication_applier_status_by_worker\G;
*************************** 1. row ***************************
         CHANNEL_NAME:
            WORKER_ID: 0
            THREAD_ID: 38
        SERVICE_STATE: ON
LAST_SEEN_TRANSACTION: 35ba7ca7-4b1e-11ee-92b9-000c29f88f2f:4
    LAST_ERROR_NUMBER: 0
   LAST_ERROR_MESSAGE:
 LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00
1 row in set (0.00 sec)

mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3306 |         1 | a1e317a1-447d-11ee-8c3a-000c29aa4114 |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.01 sec)

测试用例insert

通过insert的方式持续不断往主机上面插入数据,统计一共插入40010010条数据。过程中,同量的数据落地到stoneDB,通过group by统计查询对比两个数据库的性能。

mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.12 sec)

mysql> select name,count(*)  from mystone group by name;
+----------+----------+
| name     | count(*) |
+----------+----------+
| hello1   | 35380844 |
| 'hello1' |  4629166 |
+----------+----------+
2 rows in set (6.63 sec)

mysql>  show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status               | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting             | 0.051737 | 0.000000 |   0.000119 |            0 |             0 |
| checking permissions | 0.000018 | 0.000000 |   0.000014 |            0 |             0 |
| Opening tables       | 0.000038 | 0.000000 |   0.000039 |            0 |             0 |
| System lock          | 0.000035 | 0.000000 |   0.000035 |            0 |             0 |
| init                 | 0.000264 | 0.000000 |   0.000263 |            0 |             0 |
| optimizing           | 0.000486 | 0.000000 |   0.000485 |            0 |             0 |
| update multi-index   | 0.000475 | 0.000000 |   0.000485 |            0 |             8 |
| aggregation          | 6.579651 | 0.629508 |  26.047125 |        12128 |           160 |
| query end            | 0.000087 | 0.000043 |   0.000005 |            0 |             0 |
| closing tables       | 0.000134 | 0.000131 |   0.000000 |            0 |             0 |
| freeing items        | 0.000110 | 0.000110 |   0.000000 |            0 |             0 |
| logging slow query   | 0.000171 | 0.000172 |   0.000000 |            0 |             8 |
| cleaning up          | 0.000037 | 0.000036 |   0.000000 |            0 |             0 |
+----------------------+----------+----------+------------+--------------+---------------+
13 rows in set, 1 warning (0.00 sec)





mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select name,count(*)  from mystone group by name;
+----------+----------+
| name     | count(*) |
+----------+----------+
| 'hello1' |  4629166 |
| hello1   | 35380844 |
+----------+----------+
2 rows in set (1 min 1.54 sec)

mysql> show profile cpu,block io for query 1;
+----------------------+-----------+-----------+------------+--------------+---------------+
| Status               | Duration  | CPU_user  | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+-----------+-----------+------------+--------------+---------------+
| starting             |  0.000818 |  0.000128 |   0.000065 |            0 |             0 |
| checking permissions |  0.000042 |  0.000026 |   0.000013 |            0 |             0 |
| Opening tables       |  0.000057 |  0.000038 |   0.000020 |            0 |             0 |
| init                 |  0.000094 |  0.000063 |   0.000031 |            0 |             0 |
| System lock          |  0.000017 |  0.000010 |   0.000006 |            0 |             0 |
| optimizing           |  0.000005 |  0.000003 |   0.000001 |            0 |             0 |
| statistics           |  0.000015 |  0.000010 |   0.000005 |            0 |             0 |
| preparing            |  0.000028 |  0.000019 |   0.000010 |            0 |             0 |
| Creating tmp table   |  0.000052 |  0.000034 |   0.000017 |            0 |             0 |
| Sorting result       |  0.000005 |  0.000003 |   0.000002 |            0 |             0 |
| executing            |  0.000003 |  0.000002 |   0.000001 |            0 |             0 |
| Sending data         | 61.540422 | 56.784511 |   6.823924 |            0 |             0 |
| Creating sort index  |  0.000145 |  0.000110 |   0.000031 |            0 |             0 |
| end                  |  0.000006 |  0.000004 |   0.000001 |            0 |             0 |
| query end            |  0.000027 |  0.000021 |   0.000006 |            0 |             0 |
| removing tmp table   |  0.000012 |  0.000009 |   0.000003 |            0 |             0 |
| query end            |  0.000003 |  0.000002 |   0.000000 |            0 |             0 |
| closing tables       |  0.000031 |  0.000025 |   0.000007 |            0 |             0 |
| freeing items        |  0.000064 |  0.000000 |   0.000064 |            0 |             0 |
| cleaning up          |  0.000053 |  0.000000 |   0.000052 |            0 |             0 |
+----------------------+-----------+-----------+------------+--------------+---------------+
20 rows in set, 1 warning (0.00 sec)


第一回合,StoneDB胜,几乎比Innodb要快了10倍。

测试用例bulk load

一物有其正,必有其反。通过bulk load的方式主机导入数据,也是导入40010010条数据。最后通过group by统计查询对比两个数据库的性能。

40010010一下子所有的数据不消一会儿就到主机,当我们可以在MySQL上面查询数据,StoneDB还分文未进,一直过了一个小时后,它才把所有的数据进行入库。这一个小时发生了什么事情 ?

主从复制的工作原理是主机的事务已经提交了,它才会把数据同步到从机。IO线程就把事件日件搬到从机的中继日志, SQL线程再把中继日志进行回放,一边回放,一边往从机同步数据。

技术分享 | mysql与StoneDB的GTID主从复制集群搭建 我结合网络看了IO线程的工作时间,IO把事件数据搬到从机仅花了2秒钟,也就是主要问题是在SQL线程对数据进行回放上。我提高了slave的并发,设置slave-parallel-workers=10,但还是导入数据缓慢 ,查看CPU、内存、硬存都没有到达瓶颈,也没有单线程读取中继日志缓慢的事,因为数据都是写入,更不可能与慢查询有关系。所以初步判断是批量写入时,StoneDB要进行频繁的合并、压缩会比较慢。

简言之,StoneDB一口气把40010010条数据导入进去,花了1个多小时。这局,StoneDB败!

总结

正式的业务场景,应该很少业务场景会往InnoDB插入那么多的数据,InnoDB大多是用来TP的比较多,这样一来,StoneDB还是有自己的特色的。InnoDB作为出色的TP处理,适合频繁更新数据的业务场景,TP后的数据通过GTID流复制到AP,短流量两个节点可以快速数据同步,而TIANMU引擎带来优秀的分析功能,再反哺给应用。

转载自:https://juejin.cn/post/7317824480911360000
评论
请登录