#### 17.5.1.14 Replication and System Functions

[]()[]()

 Certain functions do not replicate well under some conditions:

* The [`USER()`](information-functions.html#function_user), [`CURRENT_USER()`](information-functions.html#function_current-user) (or [`CURRENT_USER`](information-functions.html#function_current-user)), [`UUID()`](miscellaneous-functions.html#function_uuid), [`VERSION()`](information-functions.html#function_version), and [`LOAD_FILE()`](string-functions.html#function_load-file) functions are replicated without change and thus do not work reliably on the replica unless row-based replication is enabled. (See [Section 17.2.1, “Replication Formats”](replication-formats.html).)

  [`USER()`](information-functions.html#function_user) and [`CURRENT_USER()`](information-functions.html#function_current-user) are automatically replicated using row-based replication when using `MIXED` mode, and generate a warning in `STATEMENT` mode. (See also [Section 17.5.1.8, “Replication of CURRENT\_USER()”](replication-features-current-user.html).) This is also true for [`VERSION()`](information-functions.html#function_version) and [`RAND()`](mathematical-functions.html#function_rand).

* For [`NOW()`](date-and-time-functions.html#function_now), the binary log includes the timestamp. This means that the value *as returned by the call to this function on the source* is replicated to the replica. To avoid unexpected results when replicating between MySQL servers in different time zones, set the time zone on both source and replica. For more information, see [Section 17.5.1.33, “Replication and Time Zones”](replication-features-timezone.html).

   To explain the potential problems when replicating between servers which are in different time zones, suppose that the source is located in New York, the replica is located in Stockholm, and both servers are using local time. Suppose further that, on the source, you create a table `mytable`, perform an [`INSERT`](insert.html) statement on this table, and then select from the table, as shown here:

  ```
  mysql> CREATE TABLE mytable (mycol TEXT);
  Query OK, 0 rows affected (0.06 sec)

  mysql> INSERT INTO mytable VALUES ( NOW() );
  Query OK, 1 row affected (0.00 sec)

  mysql> SELECT * FROM mytable;
  +---------------------+
  | mycol               |
  +---------------------+
  | 2009-09-01 12:00:00 |
  +---------------------+
  1 row in set (0.00 sec)
  ```

   Local time in Stockholm is 6 hours later than in New York; so, if you issue `SELECT NOW()` on the replica at that exact same instant, the value `2009-09-01 18:00:00` is returned. For this reason, if you select from the replica's copy of `mytable` after the [`CREATE TABLE`](create-table.html) and [`INSERT`](insert.html) statements just shown have been replicated, you might expect `mycol` to contain the value `2009-09-01 18:00:00`. However, this is not the case; when you select from the replica's copy of `mytable`, you obtain exactly the same result as on the source:

  ```
  mysql> SELECT * FROM mytable;
  +---------------------+
  | mycol               |
  +---------------------+
  | 2009-09-01 12:00:00 |
  +---------------------+
  1 row in set (0.00 sec)
  ```

   Unlike [`NOW()`](date-and-time-functions.html#function_now), the [`SYSDATE()`](date-and-time-functions.html#function_sysdate) function is not replication-safe because it is not affected by `SET TIMESTAMP` statements in the binary log and is nondeterministic if statement-based logging is used. This is not a problem if row-based logging is used.

   An alternative is to use the [`--sysdate-is-now`](server-options.html#option_mysqld_sysdate-is-now) option to cause [`SYSDATE()`](date-and-time-functions.html#function_sysdate) to be an alias for [`NOW()`](date-and-time-functions.html#function_now). This must be done on the source and the replica to work correctly. In such cases, a warning is still issued by this function, but can safely be ignored as long as [`--sysdate-is-now`](server-options.html#option_mysqld_sysdate-is-now) is used on both the source and the replica.

  [`SYSDATE()`](date-and-time-functions.html#function_sysdate) is automatically replicated using row-based replication when using `MIXED` mode, and generates a warning in `STATEMENT` mode.

   See also [Section 17.5.1.33, “Replication and Time Zones”](replication-features-timezone.html).

* *The following restriction applies to statement-based replication only, not to row-based replication.* The [`GET_LOCK()`](locking-functions.html#function_get-lock), [`RELEASE_LOCK()`](locking-functions.html#function_release-lock), [`IS_FREE_LOCK()`](locking-functions.html#function_is-free-lock), and [`IS_USED_LOCK()`](locking-functions.html#function_is-used-lock) functions that handle user-level locks are replicated without the replica knowing the concurrency context on the source. Therefore, these functions should not be used to insert into a source table because the content on the replica would differ. For example, do not issue a statement such as `INSERT INTO mytable VALUES(GET_LOCK(...))`.

   These functions are automatically replicated using row-based replication when using `MIXED` mode, and generate a warning in `STATEMENT` mode.

 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`](insert.html) is problematic due to the reference to the [`UUID()`](miscellaneous-functions.html#function_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`](insert.html) statement and is available for use in the [`INSERT`](insert.html).

 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()`](mathematical-functions.html#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 source and replica.)

 The [`FOUND_ROWS()`](information-functions.html#function_found-rows) and [`ROW_COUNT()`](information-functions.html#function_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`](insert.html) 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`, you should use [`SELECT ... INTO`](select-into.html), 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 replica correctly.

 These functions are automatically replicated using row-based replication when using `MIXED` mode, and generate a warning in `STATEMENT` mode. (Bug #12092, Bug #30244)

