为了从根本上解决这个问题,gtid(Global Transaction ID)就被开发了出来。
MySQL为每一个transactions都生成了独一无二的ID,由二部分构成:
1) mysql服务器的128bit的UUID
2) 自增的一个int变量。 此服务器的第一个transaction的id就是1,第二个就是2…
比如: 22096C54-FE03-4B44-95E7-BD3C4400AF21:4711
这样GTID就可以在全局范围内唯一标识一个transaction。
GTID也会写入binary log,然后被传输到从服务器。
有了GTID, 主从复制也不再基于master的binary logfile和logfile postition,
从服务器连接到主服务器之后,把自己执行过的GTID(Executed_Gtid_Set) 曾经获取到的GTID(Retrieved_Gtid_Set)发给主服务器,主服务器把从服务器缺少的GTID及对应的transactions发过去即可。
当主服务器挂掉的时候,可以任意选择一台从服务器直接提升为主,然后其它从服务器连接到新的主服务器之后,首先把自已已经执行过的GTID发给新主服务器,新主根据这些GTID,判断自己缺少哪些transactions,先把自己补全了(细节不知),然后再把从服务器缺少的GTID及对应的transactions发给从服务器,不过这个过程,只是我的猜测, 下面可以实验一下,有可能的话,还是要看看mysql的源码的。
另外,gtid与myisam的关系,也不是很明确。
master-info-repository与relay-log-info-repository
都设置为TABLE, 默认值是FILE, 比如master info就保存在master.info文件中,relay log info保存在relay-log.info文件中,
如果服务器意外关闭,正确的relay info 没有来得及更新到 relay-log.info文件中,那就比较悲剧了。
如果把它们保存到table: mysql.slave_master_info与 mysql.slave_relay_log_info 中, 这二个table都是innodb类型的, 天生就支持事务,比写文件靠谱多了。
sync-master-info
If the value of this variable is greater than 0, a replication slave synchronizes its master.info file to disk (using fdatasync()) after every sync_master_info events. 不是很理解。
slave-parallel-workers
5.6以前的从服务器,有一个io线程负责接收binary log,还有一个sql线程负责执行binary log中的sql语句。
如果主服务器的数据更新相当频繁,而从服务器一般来说硬件性能要低于主服务器,如果只有一个sql线程的话,万一某条语句执行速度过慢,就卡在这里了,会导致从服务器落后比较长的时间。
采用多个sql线程,每个sql线程处理不同的database,提高了并发性能,即使某database的某条语句暂时卡住,也不会影响到后续对其它的database进行操作。
ps:如果只有一个database要同步,那么多个sql线程也没有什么意义。
ps2: show slave status里面的Exec_Master_Log_Pos, 在多个sql线程的情况下,变为 a “low-water” mark,并非表示最近执行到的pos。
ps3: START SLAVE UNTIL SQL_AFTER_MTS_GAPS; 可以保证sql thread执行完relay log中全部的语句,然后自动stop slave。
如果要把slave-parallel-workers的值从非0改为0(切换回单sql线程),需要这样做:
START SLAVE UNTIL SQL_AFTER_MTS_GAPS;
SET @@GLOBAL.slave_parallel_workers = 0;
START SLAVE SQL_THREAD;
binlog-checksum=CRC32 master-verify-checksum=1 slave-sql-verify-checksum=1
这也是新特性,有了checksum, 如果binlog文件在master上损坏,或者在网络传输时损坏,或者保存到slave的时候损坏,都能自动检测出来。
binlog-rows-query-log-events
只对row-based binlog有效。enable之后,会向binlog中写入更多的调试信息,比如sql语句自身都会被写进去。 mysqlbinlog -vv 可以看到。
innodb_flush_log_at_trx_commit=1 与 sync_binlog=1
保证数据库事务完全正确(ACID). 看起来会对性能有较大影响,不知道binlog的group commit会不会对此有所改善。