需求
MySQL5.7不停机,直接拷贝数据目录下的文件进行备份。
前提
源数据库使用general Linux安装。
新数据库使用general Linux安装,保证首次启动之前:配置文件、数据目录、应用目录均一致。
参考文章
【innodb_flush_log_at_trx_commit参数简明讲解】
【mysqlcheck命令检查所有数据库表】
常用检查命令
方法一:mysql> show variables like 'innodb_flush_log_at_trx_commit';
方法二:直接查看my.cnf文件innodb_flush_log_at_trx_commit参数值检查所有库中的所有表
mysqlcheck -u root -p123456 -A -c
-A, –all-databases —选择所有的库
-c, –check —检查表
-C, –check-only-changed —最后一次检查之后变动的表
-auto-repair —自动修复表redo log的LSN信息可以通过 show engine innodb status 命令来查看。 (MySQL-8.0.26-debug)
实际结论
- 没有实时事务时,可直接scp复制,并成功启动。
- 存在实时事务时,可SCP复制,但无法启动。 有两种解决:一,将recovery等级改为6,可启动,但所有表等级3以上就只读。二、将所有redo日志文件删除,重新启动。
- 新启动的数据库会存在LSN两种报错:一,删除redo日志后,系统LSN(从0开始重新计数)小于数据页LSN,出现future报错。但数据结构正常。二、将redo日志删除后,再次将最新的redo日志复制一次,理论上系统LSN已小于数据页LSN,但出现了找不到数据页的报错(原因:新事务创建了新的表、新的数据,不仅增加了系统LSN数据)
实际操作问题
将测试环境中K8S使用的一台MySQL5.7.34-glibc数据库datadir整体热迁移至新数据库服务器。
修改相关my.cnf文件后,修改datadir owner后,直接热启动。竟然成功。需要检查下日志和LSN状态。
这次迁移没有删除redo日志文件,竟然能成功启动。
一个推测:LSN的变动是先发生在了数据页上,然后才发生到innodb engine上。
肯能出现上述情况的原因有两个:
- innodb_flush_log_at_trx_commit参数,让LSN的变动率先产生在page,之后才产生在engine。
- 热迁移时,先完成了对redo日志物理文件的传输,后完成了page文件的传输。就算二者的变动仍然在进行,LSN不管瞬间的先后变化都在增长。但因为SCP造成的文件先后的传输而引起的不同步。会在新数据库上造成page-LSN值大于engine-LSN的现象。
redo log的物理文件是:ib_logfile0、ib_logfile1
如果在热迁移过程中没有按照一定顺序
下一步尝试:不管文件复制的先后顺序,flush log,查看报错。
下一步尝试:scp所有datadir以后,再次scp ib_logfile文件。此时engine的LSN必然大于page-LSN。
推测:所有SCP完成后,再次复制redolog(存储了engine-LSN的文件),将会解决LSN报错。