The world's most popular open source database
Certain functions do not replicate well under some conditions:
The USER(),
CURRENT_USER(),
UUID(),
VERSION(), and
LOAD_FILE() functions are
replicated without change and thus do not work reliably on
the slave unless row-based replication is enabled. This is
also true for CURRENT_USER.
(See Section 16.1.2, “Replication Formats”.)
For early implementations of mixed-format logging, stored
functions, triggers, and views that use these functions in
their body do not replicate reliably in mixed-format logging
mode because the logging did not switch from statement-based
to row-based format. For example, INSERT INTO t
SELECT FROM v, where v is a
view that selects UUID()
could cause problems. This limitation is lifted in MySQL
5.1.12.
Beginning with MySQL 5.1.23,
USER(),
CURRENT_USER(), and
CURRENT_USER are
automatically replicated using row-based replication when
using MIXED mode, and generate a warning
in STATEMENT mode. (Bug#28086)
For NOW(), the binary log
includes the timestamp and replicates correctly.
Unlike NOW(), the
SYSDATE() function is not
replication-safe because it is not affected by SET
TIMESTAMP statements in the binary log and is
non-deterministic if statement-based logging is used. This
is not a problem if row-based logging is used. Another
option is to start the server with the
--sysdate-is-now option to cause
SYSDATE() to be an alias for
NOW().
The following restriction applies to
statement-based replication only, not to row-based
replication. The
GET_LOCK(),
RELEASE_LOCK(),
IS_FREE_LOCK(), and
IS_USED_LOCK() functions that
handle user-level locks are replicated without the slave
knowing the concurrency context on master. Therefore, these
functions should not be used to insert into a master's table
because the content on the slave would differ. (For example,
do not issue a statement such as INSERT INTO
mytable VALUES(GET_LOCK(...)).)
As a workaround for the preceding limitations when
statement-based replication is in effect, you can use the
strategy of saving the problematic function result in a user
variable and referring to the variable in a later statement. For
example, the following single-row
INSERT is problematic due to the
reference to the UUID() function:
INSERT INTO t VALUES(UUID());
To work around the problem, do this instead:
SET @my_uuid = UUID(); INSERT INTO t VALUES(@my_uuid);
That sequence of statements replicates because the value of
@my_uuid is stored in the binary log as a
user-variable event prior to the
INSERT statement and is available
for use in the INSERT.
The same idea applies to multiple-row inserts, but is more cumbersome to use. For a two-row insert, you can do this:
SET @my_uuid1 = UUID(); @my_uuid2 = UUID(); INSERT INTO t VALUES(@my_uuid1),(@my_uuid2);
However, if the number of rows is large or unknown, the workaround is difficult or impracticable. For example, you cannot convert the following statement to one in which a given individual user variable is associated with each row:
INSERT INTO t2 SELECT UUID(), * FROM t1;
Within a stored function, RAND()
replicates correctly as long as it is invoked only once during
the execution of the function. (You can consider the function
execution timestamp and random number seed as implicit inputs
that are identical on the master and slave.)
The FOUND_ROWS() and
ROW_COUNT() functions are not
replicated reliably using statement-based replication. A
workaround is to store the result of the function call in a user
variable, and then use that in the
INSERT statement. For example, if
you wish to store the result in a table named
mytable, you might normally do so like this:
SELECT SQL_CALC_FOUND_ROWS FROM mytable LIMIT 1; INSERT INTO mytable VALUES( FOUND_ROWS() );
However, if you are replicating mytable, then
you should use SELECT INTO, and then store
the variable in the table, like this:
SELECT SQL_CALC_FOUND_ROWS INTO @found_rows FROM mytable LIMIT 1; INSERT INTO mytable VALUES(@found_rows);
In this way, the user variable is replicated as part of the context, and applied on the slave correctly.
Beginning with MySQL 5.1.23, these functions are automatically
replicated using row-based replication when using
MIXED mode, and generate a warning in
STATEMENT mode. (Bug#12092, Bug#30244)


User Comments
Add your own comment.