MySQL8.0 PXC 集群--GTID-分布式事务
https://zhuanlan.zhihu.com/p/608898859
一句话概括:基于GTID(全局事务标识符),同步复制事务信息到其他节点,其他节点采用写时复制-也就是构造副本来修改然后提交给协调节点-随后协调节点进行事务的提交或者回滚--其中会通过多并发版本机制来避免数据冲突-也就是采用最新的版本号
- 主库将修改操作写入二进制日志(Binary Log)中。
- 从库连接主库,并请求复制日志。
- 主库将二进制日志中的数据发送给从库,并在从库上执行。
- 从库将执行结果写入中继日志(Relay Log)中。
- 从库根据中继日志中的信息更新自己的数据。
具体来说,当一个事务在PXC中执行写操作时,会生成一个新的版本号,并将该版本号作为GTID广播给其他节点。其他节点在接收到该GTID后,会在本地创建一个新的版本,并保存该版本号。这样,每个节点都有了一个最新的版本号,用于确定数据行的最新版本。
协调节点是集群中的一个特殊节点,它不参与具体的数据读写操作,而是负责管理整个集群的状态和数据同步。
为了避免这些问题,InnoDB存储引擎提供了MVCC和GTID的支持。
在MVCC中,每个数据行都会有多个版本,每个版本有一个唯一的ID。在修改数据时,InnoDB会创建一个新的版本,并将新版本的ID作为GTID广播给其他节点。在读取数据时,InnoDB会选择一个合适的版本来返回,以保证读取的数据是一致的。例如,T1和T2同时读取了表中的记录,T1会选择原始版本,T2会选择T1提交的版本,这样就可以避免出现数据不一致的情况。
在GTID的同步复制中,每个事务都有一个全局唯一的ID,用于标识这个事务在整个集群中的执行情况。在修改数据时,InnoDB会记录修改操作的GTID,并将该GTID广播给其他节点。在其他节点接收到该GTID后,它们会执行相同的操作,并将本地提交的结果发送回协调节点。协调节点会对各个节点提交的结果进行整合和验证,并进行最终的提交或者回滚。这样,InnoDB可以保证数据的一致性和完整性。
作者:GreatSQL
链接:https://juejin.cn/post/7064384838039666701
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- GTID事务是全局唯一性的,并且一个事务对应一个GTID值。
- 一个GTID值在同一个MySQL实例上只会执行一次。
GTID(Global Transaction ID,全局事务标识符)
跟踪事务:GTID 可以跟踪事务在分布式环境中的执行情况,当一个节点提交了一个事务时,它会生成一个全局事务标识符,并将该标识符发送给其他节点。其他节点会通过该标识符来判断事务的提交情况,并进行数据同步
GTID 主要由两个部分组成:server_uuid 和 sequence_number。其中,server_uuid 是一个唯一的标识符,用于标识 MySQL 实例;sequence_number 是一个递增的数字,用于标识 MySQL 实例中提交的事务数。
在多主复制的实现过程中,Galera 使用了基于写时复制(copy-on-write)的技术来避免数据冲突。当一个节点更新了数据时,它会将更新的数据存储在内存中,并将内存中的数据复制到其他节点,而不是直接更新磁盘上的数据。这种方式可以避免数据冲突,提高并发性能。
在多主复制的实现过程中,通常采用乐观锁或者版本控制来避免数据冲突,而不是采用传统的分布式锁。具体来说,每个节点都维护一个事务日志,当一个节点更新数据时,它会在事务日志中记录一个版本号。其他节点在更新数据时,会检查数据的版本号是否与自己的版本号一致,如果一致,则更新数据;如果不一致,则认为数据已经被其他节点更新,需要进行冲突处理。
GTID 机制仅适用于分布式环境下的 MySQL 实例。在单个 MySQL 实例中,可以使用 binlog 文件来跟踪事务的执行情况。
Galera是同步复制方案,事务在本地节点(客户端提交事务的节点)上提交成功时,其它节点保证执行该事务。在提交事务时,本地节点把事务复制到所有节点后,之后各个节点独立异步地进行certification test、事务插入待执行队列、执行事务。然而由于不同节点之间执行事务的速度不一样,长时间运行后,慢节点的待执行队列可能会越积越长,最终可能导致事务丢失。Galera内部实现了flow control,作用就是协调各个节点,保证所有节点执行事务的速度大于队列增长速度,从而避免丢失事务。
Raft算法会先选举出Leader,Leader完全负责replicated log的管理,Leader负责接受所有客户端更新请求,然后复制到Follower,并在“安全”的时候执行这些请求,如果Leader故障,Follower会重新选举出新的Leader,保证一致性。
Paxos proposer将发起提案(value)给所有accpetor,超过半数accpetor获得批准后,proposer将提案写入accpetor内,最终所有accpetor获得一致性的确定性取值,且后续不允许再修改。
将所有节点都写入同一个值,且被写入后不再更改。
MySQL 数据库主从复制有异步复制、半同步复制和全同步复制的方式。
异步复制:异步复制模式下,主库在接受并处理客户端的写入请求时,直接返回执行结果,不关心从库同步是否成功,这样就会存在上面说的问题,主库崩溃以后,可能有部分操作没有同步到从库,出现数据丢失问题。
半同步复制:在半同步复制模式下,主库需要等待至少一个从库完成同步之后,才完成写操作。主库在执行完客户端提交的事务后,从库将日志写入自己本地的 relay log 之后,会返回一个响应结果给主库,主库确认从库已经同步完成,才会结束本次写操作。相对于异步复制,半同步复制提高了数据的安全性,避免了主库崩溃出现的数据丢失,但是同时也增加了主库写操作的耗时。
全同步复制:全同步复制指的是在多从库的情况下,当主库执行完一个事务,需要等待所有的从库都同步完成以后,才完成本次写操作。全同步复制需要等待所有从库执行完对应的事务,所以整体性能是最差的。
作者:我是一只鱼吖
链接:https://juejin.cn/post/7143541597165060109
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
pxc-master.yml 文件
version: '3' services: pxc1: image: percona/percona-xtradb-cluster:8.0 restart: always container_name: pxc1 privileged: true ports: - 13306:3306 - 14444:4444 - 14567:4567 - 14568:4568 environment: - MYSQL_ROOT_PASSWORD=123456 - CLUSTER_NAME=pxc_cluster volumes: - /var/lib/docker/volumes/v1/mysql/data:/var/lib/mysql/ - /var/lib/docker/volumes/v1/mysql/cert:/cert/ - /var/lib/docker/volumes/v1/mysql/config:/etc/percona-xtradb-cluster.conf.d networks: default: ipv4_address: 172.20.0.2 pxc2: image: percona/percona-xtradb-cluster:8.0 restart: always container_name: pxc2 privileged: true ports: - 33306:3306 - 34444:4444 - 34567:4567 - 34568:4568 environment: - MYSQL_ROOT_PASSWORD=123456 - CLUSTER_NAME=pxc_cluster - CLUSTER_JOIN=172.20.0.2 volumes: - /var/lib/docker/volumes/v2/mysql/data:/var/lib/mysql/ - /var/lib/docker/volumes/v2/mysql/cert:/cert/ - /var/lib/docker/volumes/v2/mysql/config:/etc/percona-xtradb-cluster.conf.d networks: default: ipv4_address: 172.20.0.12 pxc3: image: percona/percona-xtradb-cluster:8.0 restart: always container_name: pxc3 privileged: true ports: - 23306:3306 - 24444:4444 - 24567:4567 - 24568:4568 environment: - MYSQL_ROOT_PASSWORD=123456 - CLUSTER_NAME=pxc_cluster - CLUSTER_JOIN=172.20.0.2 volumes: - /var/lib/docker/volumes/v3/mysql/data:/var/lib/mysql/ - /var/lib/docker/volumes/v3/mysql/cert:/cert/ - /var/lib/docker/volumes/v3/mysql/config:/etc/percona-xtradb-cluster.conf.d networks: default: ipv4_address: 172.20.0.13 # volumes: # v1/mysql/data: # v1/mysql/cert: # v1/mysql/config: # v2/mysql/data: # v2/mysql/cert: # v2/mysql/config: # v3/mysql/data: # v3/mysql/cert: # v3/mysql/config: networks: default: external: name: mysql_default
custom.cnf
[mysqld] ssl-ca = /cert/ca.pem ssl-cert = /cert/server-cert.pem ssl-key = /cert/server-key.pem [client] ssl-ca = /cert/ca.pem ssl-cert = /cert/client-cert.pem ssl-key = /cert/client-key.pem [sst] encrypt = 4 ssl-ca = /cert/ca.pem ssl-cert = /cert/server-cert.pem ssl-key = /cert/server-key.pem
node.cnf
[mysqld] default_authentication_plugin=mysql_native_password datadir=/var/lib/mysql socket=/tmp/mysql.sock skip-host-cache #coredumper #server_id=0 binlog_format=ROW default_storage_engine=InnoDB innodb_flush_log_at_trx_commit = 0 innodb_flush_method = O_DIRECT innodb_file_per_table = 1 innodb_autoinc_lock_mode=2 bind_address = 0.0.0.0 wsrep_slave_threads=2 wsrep_cluster_address=gcomm:// wsrep_provider=/usr/lib64/galera4/libgalera_smm.so wsrep_cluster_name=pxc_cluster wsrep_node_address=172.20.0.2 wsrep_node_incoming_address=8a69f9baf846:3306 wsrep_sst_method=xtrabackup-v2 [client] socket=/tmp/mysql.sock [sst] progress=/var/lib/mysql/sst_in_progress pxc-encrypt-cluster-traffic=OFF#多主复制#