这个问题除了和myisam表有关,其实还和位点的获取有关,下面我们主要讨论一下位点相关的原因。
8.0中整个备份最终一致点依赖log_status的访问,当备份结束的时候是以其中的redo lsn作为redo线程拷贝的结束的条件的。log_status同时也包含了binlog position信息和GTID信息,理论上访问log_status表就能保证GTID/binlog postition和redo信息的一致性(当然有BUG除外,这个还蛮严重的 https://bugs.mysql.com/bug.php?id=102175)。而如果有myisam等引擎因为没有redo,所以还是需要FTWRL防止导致GTID、binlog位点丢失和myisam表之间的不一致,这个问题在代码中叫做不安全的判断如下,
检查是否有myisam表
char *count_str =
read_mysql_one_value(mysql_connection,
"SELECT COUNT(*) FROM information_schema.tables "
"WHERE engine = 'MyISAM' OR engine = 'RocksDB'");
不安全的
have_unsafe_ddl_tables = (count > 0);
这需要进行FTWRL
lock_tables_maybe:
if (!have_unsafe_ddl_tables && !force_ftwrl) { //have_unsafe_ddl_tables 是否包含了myisam表,如果有则have_unsafe_ddl_tables设置为true
return (true); //直接return
}
...
return lock_tables_ftwrl(connection); //FTWRL
如果是不安全则需要FTWRL保护备份。当然8.0还有lock instance来防止DDL这个操作在备份一开始就发起了,也就是整个备份期间都是不能做DDL 了(堵塞DDL)。
而5.7是没有log_status的这个信息的,因此在最后获取redo点/GTID信息/binlog postition位置的一致性就需要加FTWRL进行保证,其中GTID信息/binlog postition位置是在backup_start 备份完myisam表后通过 write_current_binlog_file发起"SHOW MASTER STATUS" 语句获取的,并且是执行了2次分别获取的,而redo信息是在随后获取的,其中ckpt信息则是通过多去redo文件里面的ckpt信息,最后备份的redo lsn信息就是最后扫描的redo LSN信息,正常这些信息应该在FTWRL保护下下获取的。但是如果加-no-lock选项就不可以了,因为没有FTWRL的保护这些信息不能达到一致的点。
那么简单来讲就是8.0有了log_status视图能够获取到一个redo和binlog的一致点,因此不需要FTWRL,但是如果其有myisam引擎的表则不行,因为不存在redo,如果不加FTWRL可能导致GTID、binlog位点丢失和myisam表之间不一致的问题。而5.7不管怎么样都需要FTWRL来获取redo和binlog的一致点,并且很多内部视图也是myisam的表。
以往相关的文章,供参考。
MySQL:8.0新的备份锁的浅析及其在xtrbackup的应用

原文作者:MySQL学习;如有侵权,请联系管理员删除。