将写查询发送到Percona XtraDB群集时,所有节点会将写集存储在名为gcache的文件中。默认情况下,该文件的名称为galera.cache,它存储在MySQL数据目录中。这是一个非常重要的文件,并且像往常一样,对于MySQL中最重要的变量,默认值不适用于高负载服务器。让我们看看为什么它很重要,以及如何为集群的工作负载计算正确的值。
什么是gcache? 当节点离开群集(崩溃或维护)时,它显然停止接收更改。当您尝试将节点重新连接到群集时,数据将过时。Joiner节点需要要求捐助方发送在停机期间发生的更改。
施主将首先尝试传输增量(IST),即在节点关闭时接收群集的写入集。施主检查加入程序接收到的最后一个写集,然后检查本地gcache文件。如果所有需要的写集都在该高速缓存上,则捐助者将它们发送给联接器。联接程序将应用它们,仅此而已,它是最新的并准备加入集群。因此,只有丢失的节点遗漏的所有更改仍在施主的gcache文件中时,才能实现IST。
另一方面,如果没有写集,则需要使用一种受支持的方法XtraBackup,Rsync或mysqldump 进行完全传输(SST)。
总之,IST和SST之间的区别是节点需要加入集群的时间。差异可能在几秒到几小时之间。在WAN连接和大型数据集的情况下,可能需要几天的时间。
这就是为什么正确的gcache很重要的原因。它以循环日志的形式工作,因此当它充满时,它会从头开始重写写集。使用更大的gcache,节点可以在不使用SST的情况下有更多时间离开群集。
计算正确的大小 当技巧与用于计算正确的InnoDB日志文件大小的技巧非常相似时。我们需要检查每分钟写入多少字节。要检查的变量是:
wsrep_replicated_bytes:发送到其他节点的写集的总大小(以字节为单位)。
wsrep_received_bytes:从其他节点接收到的写集的总大小(以字节为单位)。
计算的SQL:
show global status like 'wsrep_received_bytes';
show global status like 'wsrep_replicated_bytes';
select sleep(60);
show global status like 'wsrep_received_bytes';
show global status like 'wsrep_replicated_bytes';
下面是我在生产环境获取的数据(我的集群负载比较低):
[(none)] 21:41:23 > show global status like 'wsrep_received_bytes';
+----------------------+------------+
| Variable_name | Value |
+----------------------+------------+
| wsrep_received_bytes | 2457075353 |
+----------------------+------------+
1 row in set (0.00 sec)
[(none)] 21:41:28 > show global status like 'wsrep_replicated_bytes';
+------------------------+------------+
| Variable_name | Value |
+------------------------+------------+
| wsrep_replicated_bytes | 1092525304 |
+------------------------+------------+
1 row in set (0.00 sec)
[(none)] 21:41:28 > select sleep(60);
+-----------+
| sleep(60) |
+-----------+
| 0 |
+-----------+
1 row in set (1 min 0.00 sec)
[(none)] 21:42:28 > show global status like 'wsrep_received_bytes';
+----------------------+------------+
| Variable_name | Value |
+----------------------+------------+
| wsrep_received_bytes | 2461808265 |
+----------------------+------------+
1 row in set (0.01 sec)
[(none)] 21:42:28 > show global status like 'wsrep_replicated_bytes';
+------------------------+------------+
| Variable_name | Value |
+------------------------+------------+
| wsrep_replicated_bytes | 1095290728 |
+------------------------+------------+
1 row in set (0.00 sec)
每分钟字节数:
(第二个wsrep_received_bytes –第一个wsrep_received_bytes)+(第二个wsrep_replicated_bytes –第一个wsrep_replicated_bytes)
我们这里计算的结果就是: (1095290728-1092525304)+(2461808265-2457075353) = 7498336 = 7.5MB
即 每分钟writeset用量为7.5MB , 每小时为7.5*60=450MB,
因此,如果要允许1小时的停机维护窗口, 则 gcache.size 至少为 450MB (生产环境,一般要多估算些,按照1.5倍计算,1小时停机需要设置675MB的gcache.size值)。