MySQL MASTER TO MASTER 复制在数据库级别工作,但不使用 Spring / Hibernate 的应用程序级别
MySQL MASTER TO MASTER replication working at DB level but not application level using Spring / Hibernate
我们正在使用 MySQL 和 MASTER TO MASTER 复制。
当我们直接使用 MySQL 监视器输入 SQL 语句时(即在 table 上执行 INSERT 或 DELETE),它会起作用(即复制到另一个数据库)。这已经通过两种方式进行了测试,即在每个数据库上查看它们是否都复制到另一个数据库(并且它们确实如此)。
但是,当我们使用我们的 Web 应用程序使用 Spring / Hibernate 来持久化数据时,它会正确保存到当前连接的数据库中,但不会复制到另一个数据库中!我不会认为这是可能的!
我查看了我能找到的日志文件:
/var/log/mysqld.log
但看不到任何错误。
我该如何进一步调查?
我可以改进日志记录以使其更详细吗?
这有可能以某种方式实际绕过复制吗?我不这么认为,但我刚刚 运行 一系列测试来证明这一点。
事实证明,通过在 server.xml 的数据源 TAG 中为 Liberty WebSphere Appserver 指定数据库名称,它停止了复制!?
删除了 databaseName 属性,一切正常!
<dataSource id="athlete" jndiName="jdbc/myJNDIName">
<jdbcDriver libraryRef="MySqlLib"/>
**<properties databaseName="mydb"**
user="myuser" password="password" serverName="myserver" portNumber="3306"/>
</dataSource>
真正的原因是关于 STATEMENT 与基于 ROW 的二进制日志记录
- 我们使用的是基于语句的日志记录 - 已切换到基于 ROW 的日志记录,它现在工作正常。
如果使用基于语句的复制(5.1.71 的默认设置),如果为会话分配的数据库与正在复制的数据库不同,它将不会复制到另一个数据库。
https://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_replicate-do-db
<<
基于语句的复制。告诉从 SQL 线程将复制限制为默认数据库(即由 USE 选择的数据库)为 db_name 的语句。
>
答案是我们有基于 STATEMENT 的复制而不是基于 ROW 的复制!
Link 下面解释了基于 STATEMENT 的复制(默认和我们正在使用的)和基于 ROW 的复制
https://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_replicate-do-db
mysql> show variables like 'binlog_format';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
mysql> SET GLOBAL binlog_format = 'ROW';
/etc/my.cnf
#Setup binary logging
log_bin=/var/log/mysql/mysql-bin.log
binlog_do_db=MY_DATABASE
binlog-format=ROW
我们正在使用 MySQL 和 MASTER TO MASTER 复制。
当我们直接使用 MySQL 监视器输入 SQL 语句时(即在 table 上执行 INSERT 或 DELETE),它会起作用(即复制到另一个数据库)。这已经通过两种方式进行了测试,即在每个数据库上查看它们是否都复制到另一个数据库(并且它们确实如此)。
但是,当我们使用我们的 Web 应用程序使用 Spring / Hibernate 来持久化数据时,它会正确保存到当前连接的数据库中,但不会复制到另一个数据库中!我不会认为这是可能的!
我查看了我能找到的日志文件: /var/log/mysqld.log 但看不到任何错误。
我该如何进一步调查?
我可以改进日志记录以使其更详细吗?
这有可能以某种方式实际绕过复制吗?我不这么认为,但我刚刚 运行 一系列测试来证明这一点。
事实证明,通过在 server.xml 的数据源 TAG 中为 Liberty WebSphere Appserver 指定数据库名称,它停止了复制!?
删除了 databaseName 属性,一切正常!
<dataSource id="athlete" jndiName="jdbc/myJNDIName">
<jdbcDriver libraryRef="MySqlLib"/>
**<properties databaseName="mydb"**
user="myuser" password="password" serverName="myserver" portNumber="3306"/>
</dataSource>
真正的原因是关于 STATEMENT 与基于 ROW 的二进制日志记录 - 我们使用的是基于语句的日志记录 - 已切换到基于 ROW 的日志记录,它现在工作正常。
如果使用基于语句的复制(5.1.71 的默认设置),如果为会话分配的数据库与正在复制的数据库不同,它将不会复制到另一个数据库。
https://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_replicate-do-db
<< 基于语句的复制。告诉从 SQL 线程将复制限制为默认数据库(即由 USE 选择的数据库)为 db_name 的语句。
>
答案是我们有基于 STATEMENT 的复制而不是基于 ROW 的复制!
Link 下面解释了基于 STATEMENT 的复制(默认和我们正在使用的)和基于 ROW 的复制 https://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_replicate-do-db
mysql> show variables like 'binlog_format';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
mysql> SET GLOBAL binlog_format = 'ROW';
/etc/my.cnf
#Setup binary logging
log_bin=/var/log/mysql/mysql-bin.log
binlog_do_db=MY_DATABASE
binlog-format=ROW