本文主要是介绍GTID的变更时机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- mysql.
gtid_executed:GTID的持久化介质,GTID模块初始化时,会读取这个表,作为gtid_executed 变量的初始值
gtid_executed 变量:表示数据库执行了哪些GTID
,This is the same as the value of theExecuted_Gtid_Set
column in the output ofSHOW MASTER STATUS
andSHOW SLAVE STATUS
.- gtid_purged变量:包含了mysql执行过的且没有在binlog文件存在的事务。
gtid_purged是
gtid_executed的一个子集。
The set of GTIDs in the
gtid_purged
system variable contains the GTIDs of all the transactions that have been committed on the server, but do not exist in any binary log file on the server.gtid_purged
is a subset ofgtid_executed
.
gtid_purged写入的策略:
- GTIDs of replicated transactions that were committed with binary logging disabled on the replica. 从库禁用binlog情况下,从库执行的已提交的事务时的GTID
-
GTIDs of transactions that were written to a binary log file that has now been purged.在binlog文件在被清理时,已经写入binlog文件的GTID
- GTIDs that were added explicitly to the set by the statement
SET @@GLOBAL.gtid_purged
. 手工设置了参数
例如:An example use case for this action is when you are restoring a backup of one or more databases on a server, but you do not have the relevant binary logs containing the transactions on the server,In MySQL 5.7, you can only change the value of
gtid_purged
whengtid_executed
(and thereforegtid_purged
) is empty
我们在通过备份搭建从库时,我们需要手工设置set gtid_purged
=‘’,前提是清空gtid_executed
。
变量gtid_executed
and gtid_purged在mysql启动的时候被初始化。
前提是binlog打开,gtid打开的情况下讨论。
一,主库修改时机
1,mysql.gtid_executed什么时间被修改?
mysql重启或者binlog 切换时,它不是实时更新的。
相关函数(文件rpl_gtid.h):Gtid_state::save_gtids_of_last_binlog_into_table()
int save_gtids_of_last_binlog_into_table(bool on_rotation);/**Fetch gtids from gtid_executed table and store them intogtid_executed set.@retval0 OK@retval1 The table was not found.@retval-1 Error*/
2,变量gtid_executed什么时间被修改?
在order commit的flush阶段生成GTID,在commit阶段才记入gtid_executed变量,是实时更新的。
源码:
void Gtid_state::update_gtids_impl_own_gtid_set(THD *thd, bool is_commit)
{
#ifdef HAVE_GTID_NEXT_LISTrpl_sidno prev_sidno= 0;Gtid_set::Gtid_iterator git(&thd->owned_gtid_set);Gtid g= git.get();while (g.sidno != 0){if (g.sidno != prev_sidno)sid_locks.lock(g.sidno);owned_gtids.remove_gtid(g);git.next();g= git.get();if (is_commit)executed_gtids._add_gtid(g);}if (is_commit && !thd->owned_gtid_set.is_empty())thd->rpl_thd_ctx.session_gtids_ctx().notify_after_gtid_executed_update(thd);thd->variables.gtid_next.set_undefined();thd->owned_gtid.dbug_print(NULL,"set owned_gtid (clear; old was gtid_set) ""in update_gtids_impl");thd->clear_owned_gtids();
#elseDBUG_ASSERT(0);
#endif
}
3,gtid_purged什么时间被修改的?
在清理binlog的时候进行修改,如purge或者过期时间到了,需要将丢失的GTID SETS 计入这个变量中,不是实时更新的。
对应源码函数(binlog.cc文件):MYSQL_BIN_LOGS::purge_logs
int MYSQL_BIN_LOG::purge_logs(const char *to_log,bool included,bool need_lock_index,bool need_update_threads,ulonglong *decrease_log_space,bool auto_purge)
{...// Update gtid_state->lost_gtidsif (!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't need lock*/,NULL/*trx_parser*/, NULL/*gtid_partial_trx*/);global_sid_lock->unlock();if (error)goto err;}
二,从库修改时机
前提是binlog,log_state_update开启
此时mysql.gtid_executed和 gtid_purge不需要实时更新,可以通过binlog文件进行保存,修改时机也是主库一样的
三,其他情况下
1,reset master
此时mysql.gtid_executed,变量gtid_executed和gtid_purge都会被清空,对应函数如下:
reset master 源码对应如下:
bool reset_master(THD* thd)
{bool ret= false;/*RESET MASTER command should ignore 'read-only' and 'super_read_only'options so that it can update 'mysql.gtid_executed' replication repositorytable.Please note that skip_readonly_check flag should be set even when binary logis not enabled, as RESET MASTER command will clear 'gtid_executed' table.*/
...
{global_sid_lock->wrlock();ret= (gtid_state->clear(thd) != 0); //执行gtid清理操作global_sid_lock->unlock();}
清理函数
int Gtid_state::clear(THD *thd)
{DBUG_ENTER("Gtid_state::clear()");int ret= 0;// the wrlock implies that no other thread can hold any of the mutexessid_lock->assert_some_wrlock();lost_gtids.clear(); //清理gtid_purgedexecuted_gtids.clear(); //清理gtid_executedgtids_only_in_table.clear(); //清理mysql.gtid_executedprevious_gtids_logged.clear();/* Reset gtid_executed table. */if ((ret= gtid_table_persistor->reset(thd)) == 1){/*Gtid table is not ready to be used, so failed toopen it. Ignore the error.*/thd->clear_error();ret= 0;}next_free_gno= 1;DBUG_RETURN(ret);
}
这篇关于GTID的变更时机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!