Mysql 5.7中mysql.gtid_executed表及其他变量更改时机是什么
本篇内容介绍了“Mysql 5.7中mysql.gtid_executed表及其他变量更改时机是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
一、主库修改时机(2) binlog打开mysql.gtid_executed表修改时机
在binlog发生切换(rotate)的时候保存直到上一个binlog文件执行过的全部Gtid,它不是实时更新的。
栈帧如下:
#0Gtid_table_persistor::save(this=0x2f9f9c0,gtid_set=0x7ffff03595a0)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:425#10x0000000001803dbeinGtid_state::save(this=0x2ff8bb0,gtid_set=0x7ffff03595a0)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:796#20x0000000001803f62inGtid_state::save_gtids_of_last_binlog_into_table(this=0x2ff8bb0,on_rotation=true)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:835#30x000000000185266dinMYSQL_BIN_LOG::new_file_impl(this=0x2dffc80,need_lock_log=false,extra_description_event=0x0)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6751#40x00000000018520a7inMYSQL_BIN_LOG::new_file_without_locking(this=0x2dffc80,extra_description_event=0x0)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6636#50x0000000001853e67inMYSQL_BIN_LOG::rotate(this=0x2dffc80,force_rotate=true,check_purge=0x7ffff0359c4b)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:7292
其主要逻辑在Gtid_state::save_gtids_of_last_binlog_into_table 中我们在随后的部分讨论这个函数逻辑。
gtid_executed变量修改时机
如前文所述ordered_commit flush阶段生成Gtid,在commit阶段才计入gtid_executed变量,它是实时更新的。
栈帧如下:
#0Gtid_set::_add_gtid(this=0x2ff8d38,sidno=1,gno=16)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid.h:1135#10x0000000001804576inGtid_set::_add_gtid(this=0x2ff8d38,gtid=...)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid.h:1166#20x00000000018024bainGtid_state::update_gtids_impl(this=0x2ff8bb0,thd=0x7fff2c000b70,is_commit=true)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:304#30x00000000018020dfinGtid_state::update_on_commit(this=0x2ff8bb0,thd=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:148#40x00000000018573d4inMYSQL_BIN_LOG::process_commit_stage_queue(this=0x2dffc80,thd=0x7fff2c000b70,first=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8646#50x0000000001858b51inMYSQL_BIN_LOG::ordered_commit(this=0x2dffc80,thd=0x7fff2c000b70,all=false,skip_commit=false)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9304
其主要逻辑在Gtid_state::update_gtids_impl中我们在随后的部分讨论这个函数逻辑。
gtid_purged变量修改时机
在Mysql触发的清理binlog的情况下,比如purge binary logs to或者超过参数expire_logs_days设置的天数后自动删除,需要将丢失的Gtid计入这个变量中。
栈帧如下:
#0MYSQL_BIN_LOG::init_gtid_sets(this=0x2e00280,all_gtids=0x0,lost_gtids=0x2fcaee8,verify_checksum=false,need_lock=false,trx_parser=0x0,gtid_partial_trx=0x0,is_server_starting=false)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:4333#10x0000000001850b8einMYSQL_BIN_LOG::purge_logs(this=0x2e00280,to_log=0x7fff57a74ad0"/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/mysqld.1/test.000202",included=false,need_lock_index=true,need_update_threads=true,decrease_log_space=0x0,auto_purge=false)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6036#20x0000000001848ecfinpurge_master_logs(thd=0x7fff49200dc0,to_log=0x7fff492051a8"test.000202")at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:2815
其主要逻辑在MYSQL_BIN_LOG::purge_logs中,我们随后查看其代码片段,同时MYSQL_BIN_LOG::init_gtid_sets函数是一个及其重要的函数,主要用在:
Mysql启动时候初始化整个Gtid_state中的各种Gtid_set。
Mysql删除binlog(如purge binary logfiles或者超过expire_logs_days设置)后需要确认gtid_purged变量(及Gtid_state.lost_gtids)的值的时候。
随后我会单独一节来讲解Mysql Gtid模块的初始化还会讲解这个函数。
二、主库修改时机源码函数分析这里就对上面提到的主要逻辑函数进行分析
Gtid_state::save_gtids_of_last_binlog_into_table函数逻辑
logged_gtids_last_binlog.add_interval_memory(PREALLOCATED_INTERVAL_COUNT,iv);//这里构建一个logged_gtids_last_binlog集合来保存切换后需要写入表和previous_gtids_logged的Gtid/*logged_gtids_last_binlog=executed_gtids-previous_gtids_logged-gtids_only_in_table*/global_sid_lock->wrlock();//ret=(logged_gtids_last_binlog.add_gtid_set(&executed_gtids)!=//将当前执行过的Gtid全部加入logged_gtids_last_binlog列如:executed_gtidsstart=1,end=27RETURN_STATUS_OK);if(!ret){logged_gtids_last_binlog.remove_gtid_set(&previous_gtids_logged);//获得上一个binlog文件包含的全部Gtid,并且做一个差集列如:previous_gtids_logged为start=1,end=25//做完差集后logged_gtids_last_binlog为start=26,end=27logged_gtids_last_binlog.remove_gtid_set(>ids_only_in_table);//此处主库一定为空,除非异常情况if(!logged_gtids_last_binlog.is_empty()){/*Prepareprevious_gtids_loggedfornextbinlogonbinlogrotation*/if(on_rotation)ret=previous_gtids_logged.add_gtid_set(&logged_gtids_last_binlog);//将这个start=26,end=27的Gtid集合加入到previous_gtids_logged中,这样previous_gtids_logged也完整了global_sid_lock->unlock();/*SavesetofGTIDsofthelastbinlogintogtid_executedtable*/if(!ret)ret=save(&logged_gtids_last_binlog);//将这个start=26,end=27的Gtid集合写入到表mysql.gtid_executed表中}
Gtid_state::update_gtids_impl函数代码片段
while(g.sidno!=0){if(g.sidno!=prev_sidno)sid_locks.lock(g.sidno);owned_gtids.remove_gtid(g);//从owned_gtid中去掉git.next();g=git.get();if(is_commit)executed_gtids._add_gtid(g);//将这个Gtid加入到executed_gtids}
MYSQL_BIN_LOG::purge_logs函数代码片段
if(!is_relay_log){global_sid_lock->wrlock();error=init_gtid_sets(NULL,const_cast<Gtid_set*>(gtid_state->get_lost_gtids()),opt_master_verify_checksum,false/*false=don'tneedlock*/,NULL/*trx_parser*/,NULL/*gtid_partial_trx*/);//这里我看到将gtid_state->lost_gtids直接传入给了init_gtid_sets//init_gtid_sets会做正向查找获得gtid_state->lost_gtids这个函数稍后//详细讨论global_sid_lock->unlock();if(error)gotoerr;}三、从库修改时机(2)binlog开启同时参数log_slave_updates开启的情况
这种情况sql_thread执行过的Gtid事物可以通过binlog进行维护,所以mysql.gtid_executed表和gtid_purged变量不需要实时更新。
mysql.gtid_executed表修改时机
和主库一致。及在进行日志切换的时候进行更新,不做讨论
gtid_executed变量修改时机
和主库一样实时更新,不做讨论
gtid_purged变量修改时机
和主库一致,binlog删除时更新,不做讨论
四、从库修改时机源码函数分析commit_owned_gtids函数逻辑:
//如果binlog没有开启包括(log_bin=0和sql_log_bin=0)或者开启了binlog但是slave线程并且slaveupdate没有开启,都会记录gtid到表//但是这里要注意一点在主库上如果binlog不开启那么thd->owned_gtid.sidno==0因为这个时候Gtid都没有生成,生成阶段为order_commit的commit阶段if((!opt_bin_log||(thd->slave_thread&&!opt_log_slave_updates))&&(all||!thd->in_multi_stmt_transaction_mode())&&//all代表是否是显示begin事物in_multi_stmt_transaction_mode则相反!thd->is_operating_gtid_table_implicitly&&//是否是GTID_NEXT方式flase!thd->is_operating_substatement_implicitly)//是否是子语句flase{/*Ifthebinarylogisdisabledforthisthread(eitherbylog_bin=0orsql_log_bin=0orbylog_slave_updates=0foraslavethread),thenthestatementwillnotbewrittentothebinarylog.Inthiscase,weshouldsaveitsGTIDintomysql.gtid_executedtableand@@GLOBAL.GTID_EXECUTEDasitdidwhenbinlogisenabled.*/if(thd->owned_gtid.sidno>0){error=gtid_state->save(thd);//就是这里进行了mysql.gtid_executed表的实时更新*need_clear_owned_gtid_ptr=true;}elseif(thd->owned_gtid.sidno==THD::OWNED_SIDNO_ANONYMOUS)*need_clear_owned_gtid_ptr=true;}
Gtid_state::update_gtids_impl_own_gtid 函数逻辑片段
这个函数是5.7.17的,5.7.14没有逻辑放到了Gtid_state::update_gtids_impl中
if(is_commit){DBUG_EXECUTE_IF("rpl_gtid_update_on_commit_simulate_out_of_memory",DBUG_SET("+d,rpl_gtid_get_free_interval_simulate_out_of_memory"););/*AnysessionaddstransactionownedGTIDintoglobalexecuted_gtids.Ifbinlogisdisabled,wereport@@GLOBAL.GTID_PURGEDfromexecuted_gtids,since@@GLOBAL.GTID_PURGEDand@@GLOBAL.GTID_EXECUTEDarealwayssame,sowedidnotsavegtidintolost_gtidsforeverytransactionforimprovingperformance.Ifbinlogisenabledandlog_slave_updatesisdisabled,slaveSQLthreadorslaveworkerthreadaddstransactionownedGTIDintoglobalexecuted_gtids,lost_gtidsandgtids_only_in_table.*/executed_gtids._add_gtid(thd->owned_gtid);//加入executed_gtids集合thd->rpl_thd_ctx.session_gtids_ctx().notify_after_gtid_executed_update(thd);if(thd->slave_thread&&opt_bin_log&&!opt_log_slave_updates)//如果是slave线程同时binlog开启了并且log_slave_updates关闭了//如果binlog关闭则使用executed_gtids这样提高性能前面的注释说了{lost_gtids._add_gtid(thd->owned_gtid);//写入lost_gtids也就是更新参数gtid_purged变量gtids_only_in_table._add_gtid(thd->owned_gtid);}}五、通用更改时机
mysql.gtid_executed表修改时机
在reset master的时候清空本表
栈帧如下:
#0Gtid_table_persistor::delete_all(this=0x2f9f9c0,table=0x7fff2c0116a0)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:795#10x000000000180a4efinGtid_table_persistor::reset(this=0x2f9f9c0,thd=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:689#20x0000000001801f2einGtid_state::clear(this=0x2ff8bb0,thd=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:36#30x000000000184fee6inMYSQL_BIN_LOG::reset_logs(this=0x2dffe80,thd=0x7fff2c000b70,delete_only=false)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:5586#40x0000000001872308inreset_master(thd=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_master.cc:587
其主要逻辑在Gtid_state::clear中。
在set global gitd_purged的时候,设置本表
栈帧如下:
#0Gtid_table_persistor::save(this=0x2f9f9c0,gtid_set=0x7ffff0359a70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:425#10x000000000180400ainGtid_state::save(this=0x2ff8bb0,gtid_set=0x7ffff0359a70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:796#20x0000000001803c25inGtid_state::add_lost_gtids(this=0x2ff8bb0,gtid_set=0x7ffff0359a70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:737#30x00000000016778f3inSys_var_gtid_purged::global_update(this=0x2de9fe0,thd=0x7fff2c000b70,var=0x7fff2c006630)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/sys_vars.cc:5888#40x00000000014d5cd1insys_var::update(this=0x2de9fe0,thd=0x7fff2c000b70,var=0x7fff2c006630)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:184#50x00000000014d74eeinset_var::update(this=0x7fff2c006630,thd=0x7fff2c000b70)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:812#60x00000000014d6d1ainsql_set_variables(thd=0x7fff2c000b70,var_list=0x7fff2c003528)at/root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:669
其主要逻辑在Gtid_state::add_lost_gtids中。
gtid_executed变量修改时机
在reset master的时候清空本变量
栈帧同上
在set global gitd_purged的时候,设置本变量
栈帧同上
在mysql启动的时候初始化设置gtid_executed变量,这个将在后面章节详细描述描述步骤。
gtid_purged变量修改时机
在reset master的时候清空本变量
栈帧同上
在set global gitd_purged的时候,设置本变量
栈帧同上
在mysql启动的时候初始化设置gtid_executed变量,这个将在后面章节详细描述描述步骤。
六、通用更改时机源码函数分析Gtid_state::clear函数逻辑
intGtid_state::clear(THD*thd){....//thewrlockimpliesthatnootherthreadcanholdanyofthemutexessid_lock->assert_some_wrlock();lost_gtids.clear();//此处清空gtid_purged变量executed_gtids.clear();//此处清空gtid_executed变量gtids_only_in_table.clear();//清空onlyintableGtidsetprevious_gtids_logged.clear();//清空previousgtidsloggedGtidset/*Resetgtid_executedtable.*/if((ret=gtid_table_persistor->reset(thd))==1)//此处清空mysql.gtid_executed表{/*Gtidtableisnotreadytobeused,sofailedtoopenit.Ignoretheerror.*/thd->clear_error();ret=0;}next_free_gno=1;DBUG_RETURN(ret);}
Gtid_state::add_lost_gtids函数逻辑
enum_return_statusGtid_state::add_lost_gtids(constGtid_set*gtid_set){......if(save(gtid_set))//此处将setgtid_purge的值加入到mysql.gtid_executed表中RETURN_REPORTED_ERROR;PROPAGATE_REPORTED_ERROR(gtids_only_in_table.add_gtid_set(gtid_set));PROPAGATE_REPORTED_ERROR(lost_gtids.add_gtid_set(gtid_set));//此处将setgtid_purge的值加入到gtid_purge变量中PROPAGATE_REPORTED_ERROR(executed_gtids.add_gtid_set(gtid_set));//此处将setgtid_purge的值加入到gtid_executed变量中lock_sidnos(gtid_set);broadcast_sidnos(gtid_set);unlock_sidnos(gtid_set);DBUG_RETURN(RETURN_STATUS_OK);}
“Mysql 5.7中mysql.gtid_executed表及其他变量更改时机是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。