参考《深入理解MySQL主从原理32讲》
一,WriteSet是什么?
实际上 Writeset 是一个集合,使用的是 C++ STL 中的 set 容器,在类 Rpl_transaction_write_set_ctx 中包含了如下定义:
class Rpl_transaction_write_set_ctx
{
public:
...
private:
std::vector<uint64> write_set;
std::set<uint64> write_set_unique;
集合中的每一个元素都是 hash 值,这个 hash 值和我们的 transaction_write_set_extraction 参数指定的算法有关,其来源就是行数据的主键和唯一键。每行数据包含了两种格式:
- 字段值为二进制格式
- 字段值为字符串格式
每行数据的具体格式为:
在 Innodb 层修改一行数据之后会将这上面的格式的数据进行 hash 后写入到 Writeset 中。可以参考函数 add_pke ,后面我也会以伪代码的方式给出部分流程。
但是需要注意一个事务的所有的行数据的 hash 值都要写入到一个 Writeset。如果修改的行比较多那么可能需要更多内存来存储这些 hash 值。虽然8字节比较小,但是如果一个事务修改的行很多,那么还是需要消耗较多的内存资源的。为了更直观的观察到这种数据格式,可以使用 debug 的方式获取。下面我们来看一下。
二,WriteSet的生成
我们使用如下表:
mysql> use test
Database changed
mysql> show create table jj10 \G
*************************** 1. row ***************************
Table: jj10
Create Table: CREATE TABLE `jj10` (
`id1` int(11) DEFAULT NULL,
`id2` int(11) DEFAULT NULL,
`id3` int(11) NOT NULL,
PRIMARY KEY (`id3`),
UNIQUE KEY `id1` (`id1`),
KEY `