Rechercher dans le manuel MySQL
17.1.3.2 GTID Life Cycle
The life cycle of a GTID consists of the following steps:
A transaction is executed and committed on the master. This client transaction is assigned a GTID composed of the master's UUID and the smallest nonzero transaction sequence number not yet used on this server. The GTID is written to the master's binary log (immediately preceding the transaction itself in the log). If a client transaction is not written to the binary log (for example, because the transaction was filtered out, or the transaction was read-only), it is not assigned a GTID.
If a GTID was assigned for the transaction, the GTID is persisted atomically at commit time by writing it to the binary log at the beginning of the transaction (as a
Gtid_log_event
). Whenever the binary log is rotated or the server is shut down, the server writes GTIDs for all transactions that were written into the previous binary log file into themysql.gtid_executed
table.If a GTID was assigned for the transaction, the GTID is externalized non-atomically (very shortly after the transaction is committed) by adding it to the set of GTIDs in the
gtid_executed
system variable (@@GLOBAL.gtid_executed
). This GTID set contains a representation of the set of all committed GTID transactions, and it is used in replication as a token that represents the server state. With binary logging enabled (as required for the master), the set of GTIDs in thegtid_executed
system variable is a complete record of the transactions applied, but themysql.gtid_executed
table is not, because the most recent history is still in the current binary log file.After the binary log data is transmitted to the slave and stored in the slave's relay log (using established mechanisms for this process, see Section 17.2, “Replication Implementation”, for details), the slave reads the GTID and sets the value of its
gtid_next
system variable as this GTID. This tells the slave that the next transaction must be logged using this GTID. It is important to note that the slave setsgtid_next
in a session context.The slave verifies that no thread has yet taken ownership of the GTID in
gtid_next
in order to process the transaction. By reading and checking the replicated transaction's GTID first, before processing the transaction itself, the slave guarantees not only that no previous transaction having this GTID has been applied on the slave, but also that no other session has already read this GTID but has not yet committed the associated transaction. So if multiple clients attempt to apply the same transaction concurrently, the server resolves this by letting only one of them execute. Thegtid_owned
system variable (@@GLOBAL.gtid_owned
) for the slave shows each GTID that is currently in use and the ID of the thread that owns it. If the GTID has already been used, no error is raised, and the auto-skip function is used to ignore the transaction.If the GTID has not been used, the slave applies the replicated transaction. Because
gtid_next
is set to the GTID already assigned by the master, the slave does not attempt to generate a new GTID for this transaction, but instead uses the GTID stored ingtid_next
.If binary logging is enabled on the slave, the GTID is persisted atomically at commit time by writing it to the binary log at the beginning of the transaction (as a
Gtid_log_event
). Whenever the binary log is rotated or the server is shut down, the server writes GTIDs for all transactions that were written into the previous binary log file into themysql.gtid_executed
table.If binary logging is disabled on the slave, the GTID is persisted atomically by writing it directly into the
mysql.gtid_executed
table. MySQL appends a statement to the transaction to insert the GTID into the table. From MySQL 8.0, this operation is atomic for DDL statements as well as for DML statements. In this situation, themysql.gtid_executed
table is a complete record of the transactions applied on the slave.Very shortly after the replicated transaction is committed on the slave, the GTID is externalized non-atomically by adding it to the set of GTIDs in the
gtid_executed
system variable (@@GLOBAL.gtid_executed
) for the slave. As for the master, this GTID set contains a representation of the set of all committed GTID transactions. If binary logging is disabled on the slave, themysql.gtid_executed
table is also a complete record of the transactions applied on the slave. If binary logging is enabled on the slave, meaning that some GTIDs are only recorded in the binary log, the set of GTIDs in thegtid_executed
system variable is the only complete record.
Client transactions that are completely filtered out on the master
are not assigned a GTID, therefore they are not added to the set
of transactions in the
gtid_executed
system variable, or
added to the mysql.gtid_executed
table.
However, the GTIDs of replicated transactions that are completely
filtered out on the slave are persisted. If binary logging is
enabled on the slave, the filtered-out transaction is written to
the binary log as a Gtid_log_event
followed by
an empty transaction containing only BEGIN
and
COMMIT
statements. If binary logging is
disabled, the GTID of the filtered-out transaction is written to
the mysql.gtid_executed
table. Preserving the
GTIDs for filtered-out transactions ensures that the
mysql.gtid_executed
table and the set of GTIDs
in the gtid_executed
system
variable can be compressed. It also ensures that the filtered-out
transactions are not retrieved again if the slave reconnects to
the master, as explained in
Section 17.1.3.3, “GTID Auto-Positioning”.
On a multithreaded replication slave (with
slave_parallel_workers > 0
),
transactions can be applied in parallel, so replicated
transactions can commit out of order (unless
slave_preserve_commit_order=1
is
set). When that happens, the set of GTIDs in the
gtid_executed
system
variable will contain multiple GTID ranges with gaps between them.
(On a master or a single-threaded replication slave, there will be
monotonically increasing GTIDs without gaps between the numbers.)
Gaps on multithreaded replication slaves only occur among the most
recently applied transactions, and are filled in as replication
progresses. When replication threads are stopped cleanly using the
STOP SLAVE
statement,
ongoing transactions are applied so that the gaps are filled in.
In the event of a shutdown such as a server failure or the use of
the KILL
statement to stop
replication threads, the gaps might remain.
What changes are assigned a GTID?
The typical scenario is that the server generates a new GTID for a committed transaction. However, GTIDs can also be assigned to other changes besides transactions, and in some cases a single transaction can be assigned multiple GTIDs.
Every database change (DDL or DML) that is written to the binary
log is assigned a GTID. This includes changes that are
autocommitted, and changes that are committed using
BEGIN
and COMMIT
or
START TRANSACTION
statements. A GTID is also
assigned to the creation, alteration, or deletion of a database,
and of a non-table database object such as a procedure,
function, trigger, event, view, user, role, or grant.
Non-transactional updates as well as transactional updates are assigned GTIDs. In addition, for a non-transactional update, if a disk write failure occurs while attempting to write to the binary log cache and a gap is therefore created in the binary log, the resulting incident log event is assigned a GTID.
When a table is automatically dropped by a generated statement
in the binary log, a GTID is assigned to the statement.
Temporary tables are dropped automatically when a replication
slave begins to apply events from a master that has just been
started, and when statement-based replication is in use
(binlog_format=STATEMENT
) and a
user session that has open temporary tables disconnects. Tables
that use the MEMORY
storage engine
are deleted automatically the first time they are accessed after
the server is started, because rows might have been lost during
the shutdown.
When a transaction is not written to the binary log on the
server of origin, the server does not assign a GTID to it. This
includes transactions that are rolled back and transactions that
are executed while binary logging is disabled on the server of
origin, either globally (with --skip-log-bin
specified in the server's configuration) or for the session
(SET @@SESSION.sql_log_bin = 0
). This also
includes no-op transactions when row-based replication is in use
(binlog_format=ROW
).
XA transactions are assigned separate GTIDs for the XA
PREPARE
phase of the transaction and the XA
COMMIT
or XA ROLLBACK
phase of the
transaction. XA transactions are persistently prepared so that
users can commit them or roll them back in the case of a failure
(which in a replication topology might include a failover to
another server). The two parts of the transaction are therefore
replicated separately, so they must have their own GTIDs, even
though a non-XA transaction that is rolled back would not have a
GTID.
In the following special cases, a single statement can generate multiple transactions, and therefore be assigned multiple GTIDs:
A stored procedure is invoked that commits multiple transactions. One GTID is generated for each transaction that the procedure commits.
A multi-table
DROP TABLE
statement drops tables of different types. Multiple GTIDs can be generated if any of the tables use storage engines that do not support atomic DDL, or if any of the tables are temporary tables.A
CREATE TABLE ... SELECT
statement is issued when row-based replication is in use (binlog_format=ROW
). One GTID is generated for theCREATE TABLE
action and one GTID is generated for the row-insert actions.
By default, for new transactions committed in user sessions, the
server automatically generates and assigns a new GTID. When the
transaction is applied on a replication slave, the GTID from the
server of origin is preserved. You can change this behavior by
setting the session value of the
gtid_next
system variable:
When
gtid_next
is set toAUTOMATIC
, which is the default, and a transaction is committed and written to the binary log, the server automatically generates and assigns a new GTID. If a transaction is rolled back or not written to the binary log for another reason, the server does not generate and assign a GTID.If you set
gtid_next
to a valid GTID (consisting of a UUID and a transaction sequence number, separated by a colon), the server assigns that GTID to your transaction. This GTID is assigned and added togtid_executed
even when the transaction is not written to the binary log, or when the transaction is empty.
Note that after you set
gtid_next
to a specific GTID,
and the transaction has been committed or rolled back, an
explicit SET @@SESSION.gtid_next
statement
must be issued before any other statement. You can use this to
set the GTID value back to AUTOMATIC
if you
do not want to assign any more GTIDs explicitly.
When replication applier threads apply replicated transactions,
they use this technique, setting
@@SESSION.gtid_next
explicitly to the GTID of
the replicated transaction as assigned on the server of origin.
This means the GTID from the server of origin is retained,
rather than a new GTID being generated and assigned by the
replication slave. It also means the GTID is added to
gtid_executed
on the
replication slave even when binary logging or slave update
logging is disabled on the slave, or when the transaction is a
no-op or is filtered out on the slave.
It is possible for a client to simulate a replicated transaction
by setting @@SESSION.gtid_next
to a specific
GTID before executing the transaction. This technique is used by
mysqlbinlog to generate a dump of the binary
log that the client can replay to preserve GTIDs. A simulated
replicated transaction committed through a client is completely
equivalent to a replicated transaction committed through a
replication applier thread, and they cannot be distinguished
after the fact.
The set of GTIDs in the
gtid_purged
system variable
(@@GLOBAL.gtid_purged
) 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 of
gtid_executed
. The following
categories of GTIDs are in
gtid_purged
:
GTIDs of replicated transactions that were committed with binary logging disabled on the slave.
GTIDs of transactions that were written to a binary log file that has now been purged.
GTIDs that were added explicitly to the set by the statement
SET @@GLOBAL.gtid_purged
.
You can change the value of
gtid_purged
in order to record
on the server that the transactions in a certain GTID set have
been applied, although they do not exist in any binary log on
the server. When you add GTIDs to
gtid_purged
, they are also
added to gtid_executed
. 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. Before MySQL 8.0, you could only change the value of
gtid_purged
when
gtid_executed
(and therefore
gtid_purged
) was empty. From
MySQL 8.0, this restriction does not apply, and you can also
choose whether to replace the whole GTID set in
gtid_purged
with a specified
GTID set, or to add a specified GTID set to the GTIDs already in
gtid_purged
. For details of how
to do this, see the description for
gtid_purged
.
The sets of GTIDs in the
gtid_executed
and
gtid_purged
system variables
are initialized when the server starts. Every binary log file
begins with the event
Previous_gtids_log_event
, which contains the
set of GTIDs in all previous binary log files (composed from the
GTIDs in the preceding file's
Previous_gtids_log_event
, and the GTIDs of
every Gtid_log_event
in the preceding file
itself). The contents of
Previous_gtids_log_event
in the oldest and
most recent binary log files are used to compute the
gtid_executed
and
gtid_purged
sets at server
startup:
gtid_executed
is computed as the union of the GTIDs inPrevious_gtids_log_event
in the most recent binary log file, the GTIDs of transactions in that binary log file, and the GTIDs stored in themysql.gtid_executed
table. This GTID set contains all the GTIDs that have been used (or added explicitly togtid_purged
) on the server, whether or not they are currently in a binary log file on the server. It does not include the GTIDs for transactions that are currently being processed on the server (@@GLOBAL.gtid_owned
).gtid_purged
is computed by first adding the GTIDs inPrevious_gtids_log_event
in the most recent binary log file and the GTIDs of transactions in that binary log file. This step gives the set of GTIDs that are currently, or were once, recorded in a binary log on the server (gtids_in_binlog
). Next, the GTIDs inPrevious_gtids_log_event
in the oldest binary log file are subtracted fromgtids_in_binlog
. This step gives the set of GTIDs that are currently recorded in a binary log on the server (gtids_in_binlog_not_purged
). Finally,gtids_in_binlog_not_purged
is subtracted fromgtid_executed
. The result is the set of GTIDs that have been used on the server, but are not currently recorded in a binary log file on the server, and this result is used to initializegtid_purged
.
If binary logs from MySQL 5.7.7 or older are involved in these
computations, it is possible for incorrect GTID sets to be
computed for gtid_executed
and
gtid_purged
, and they remain
incorrect even if the server is later restarted. For details,
see the description for the
binlog_gtid_simple_recovery
system variable, which controls how the binary logs are iterated
to compute the GTID sets. If one of the situations described
there applies on a server, set
binlog_gtid_simple_recovery=FALSE
in the server's configuration file before starting it. That
setting makes the server iterate all the binary log files (not
just the newest and oldest) to find where GTID events start to
appear. This process could take a long time if the server has a
large number of binary log files without GTID events.
If you need to reset the GTID execution history on a server, use
the RESET MASTER
statement. For
example, you might need to do this after carrying out test
queries to verify a replication setup on new GTID-enabled
servers, or when you want to join a new server to a replication
group but it contains some unwanted local transactions that are
not accepted by Group Replication.
Use RESET MASTER
with caution
to avoid losing any wanted GTID execution history and binary
log files.
Before issuing RESET MASTER
,
ensure that you have backups of the server's binary log files
and binary log index file, if any, and obtain and save the GTID
set held in the global value of the
gtid_executed
system variable
(for example, by issuing a SELECT
@@GLOBAL.gtid_executed
statement and saving the
results). If you are removing unwanted transactions from that
GTID set, use mysqlbinlog to examine the
contents of the transactions to ensure that they have no value,
contain no data that must be saved or replicated, and did not
result in data changes on the server.
When you issue RESET MASTER
, the
following reset operations are carried out:
The value of the
gtid_purged
system variable is set to an empty string (''
).The global value (but not the session value) of the
gtid_executed
system variable is set to an empty string.The
mysql.gtid_executed
table is cleared (see mysql.gtid_executed Table).If the server has binary logging enabled, the existing binary log files are deleted and the binary log index file is cleared.
Note that RESET MASTER
is the
method to reset the GTID execution history even if the server is
a replication slave where binary logging is disabled.
RESET SLAVE
has no effect on the
GTID execution history.
Nederlandse vertaling
U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.
Bij voorbaat dank.
Document heeft de 26/06/2006 gemaakt, de laatste keer de 26/10/2018 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/mysql-rf-replication-gtids-lifecycle.html
De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.
Referenties
Deze verwijzingen en links verwijzen naar documenten die geraadpleegd zijn tijdens het schrijven van deze pagina, of die aanvullende informatie kunnen geven, maar de auteurs van deze bronnen kunnen niet verantwoordelijk worden gehouden voor de inhoud van deze pagina.
De auteur Deze site is als enige verantwoordelijk voor de manier waarop de verschillende concepten, en de vrijheden die met de referentiewerken worden genomen, hier worden gepresenteerd. Vergeet niet dat u meerdere broninformatie moet doorgeven om het risico op fouten te verkleinen.