独角兽企业重金招聘Python工程师标准>>>
mysql - binlog主从复制
GTID (Global Transaction ID)
InnoDB:事务性引擎。 MyISAM:非事务性存储引擎。
GTID = source_id :transaction_id
一个已提交事务的编号。source_id 表示执行事务的主库 uuid(server_uuid),transaction_id 是一个从 1 开始的自增计数,表示在这个主库上执行的第 n 个事务。MySQL 只要保证每台数据库的 server_uuid 全局唯一,以及每台数据库生成的 transaction_id 自身唯一,就能保证 GTID 的全局唯一性。
source_id
在首次启动时 MySQL 会自动生成一个 server_uuid,并且保存到 f 文件 。再次启动时,会读取文件继续使用上次生成的server_uuid。
transaction_id
在非事务引擎MyISAM中,autocommit的启用停用不影响其binglog写入begin和commit。INNODB不执行commit,那么本次这些提交都默认的放在一个事务里面。 只有显示的执行commit,才会写入binlog并且真正的提交。
开启GTID,MyISAM也会在binlog中记录变化。
推论:非事务指的是不能以事务控制语句如begin等去做一些批量操作的ACID限制。
作用
Server A的服务器宕机,需要将业务切换到Server B上。同时又需要将Server C的复制源改成Server B。复制源修改的命令语法很简单即CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS=nnnn。但同一个事务在每台机器上所在的binlog名字和位置都不一样,那么如何定位Server C当前同步停止点,对应Server B的master_log_file和master_log_pos?这也就是为什么M-S复制集群需要使用MMM,MHA这样的额外管理工具的一个重要原因。
这个问题在5.6的GTID出现后,就非常简单。由于同一事务的GTID在所有节点上的值一致,那么根据Server C当前停止点的GTID就能唯一定位到Server B上的GTID。甚至由于MASTER_AUTO_POSITION功能的出现,我们都不需要知道GTID的具体值,直接使用CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1命令就启用基于GTID的复制, 直接完成failover的工作。
执行
Master是运行中的数据库,新加入Slave服务器:
Master开始就是以GTID方式运行: 此时GTID中保存了所有的事务信息,Slave在启动后会一条条的执行,直到与Master的数据同步,这种方式耗费的时间可能比较长。Master不是以GTID方式运行: 此时GTID中是没有任何信息的,如果此时要配置新的Slave,则需要通过数据的导入导出先保证两个数据库服务器的数据一致,再通过GTID进行数据复制,由于此时需要更改主服务器的f配置文件,所以必须有重启服务器的过程。
在主服务器不是以gtid模式运行,须重启主服务器,在Master的f配置文件中加上如下内容:
server-id = 1log-bin=mysql-bin<!-- 以下三个参数共生-->gtid-mode=onenforce-gtid-consistency=truelog-slave-updates=true
开启GTID后:
首先导出数据库备份文件,此时主服务器开启了GTID功能,所以set-gtid-purged参数默认是开启的,也就是会在导出的备份文件中带上gtid的信息,保证从服务器不会再次同步已有的事务数据。
mysqldump --all-databases --single-transaction --default-character_set=gbk -uroot -proot
修改从服务器的f配置文件,保证GTID的开启,否则导入会在同步GTID信息的SQL语句处报错,后续再开启GTID也可以,但需要重新source备份文件。启动从服务器,首先set names gbk 执行source 备份文件导入主服务器的SNAP数据,完成后可以通过show global variables like '%gtid%' 看到对应的GTID值已经同步。此时执行
change master to master_host='host', master_port='3306', master_user='root',master_auto_position=1, 设置主服务器信息,再执行start slave即可。