systemadmin.es > DBA > Statement is not safe to log in statement format

Statement is not safe to log in statement format

En un entorno de replicación master-slave en MySQL nos podemos encontrar en el log del master la siguiente alerta:

100225  8:32:10 [Warning] Statement is not safe to log in statement
format. Statement: update ejemplo set
counter=counter+1 where id = 11 and date_start < now()
and date_end > now() limit 1

Esto nos esta indicando que no puede garantizar que esta misma query ejecutada tanto en el master como en el slave modifique los mismos registros: Sea una sentencia no deterministica. Un ejemplo simple de como ver este problema es con la siguiente tabla:

mysql> create table jordi (id int primary key, count int, d timestamp);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into jordi values(1,1,now());
Query OK, 1 row affected (0.00 sec)

mysql> insert into jordi values(2,1,now());
Query OK, 1 row affected (0.00 sec)

mysql> insert into jordi values(3,1,now());
Query OK, 1 row affected (0.00 sec)

mysql> select * from jordi;
+----+-------+---------------------+
| id | count | d                   |
+----+-------+---------------------+
|  1 |     1 | 2010-02-25 09:03:14 |
|  2 |     1 | 2010-02-25 09:03:17 |
|  3 |     1 | 2010-02-25 09:03:21 |
+----+-------+---------------------+
3 rows in set (0.00 sec)

Con la siguiente query:

mysql> update jordi set count=count+1 where d<now() limit 1;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Estaríamos eligiendo uno de los tres valores por el LIMIT, pero no podemos garantizar quien es el elegido porque no estamos especificando ningún orden. Por esto si hacemos el SHOW WARNINGS veremos el mensaje:

mysql> show warnings;
+-------+------+---------------------------------------------------+
| Level | Code | Message                                           |
+-------+------+---------------------------------------------------+
| Note  | 1592 | Statement is not safe to log in statement format. |
+-------+------+---------------------------------------------------+
1 row in set (0.00 sec)

Una forma de garantizar que la sentencia SQL sea igual en el master que en el slave es indicando un ORDER BY:

mysql> update jordi set count=count+1 where d<now() order by id limit 1;
Query OK, 1 row affected, 1 warning (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> show warnings;
+-------+------+---------------------------------------------------+
| Level | Code | Message                                           |
+-------+------+---------------------------------------------------+
| Note  | 1592 | Statement is not safe to log in statement format. |
+-------+------+---------------------------------------------------+
1 row in set (0.00 sec)

Podemos comprobar como sigue mostrando el error, en este caso se trata de un bug de MySQL que aún no esta corregido.

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>