2012-03-23 75 views
1

我一直在尝试在两个MySQL服务器之间进行主 - 主复制,但使用不同的数据库名称,而且我遇到了一些绊脚石。看起来,尽管UPDATE按预期正常工作,但INSERT并没有。replicate-rewrite-db是否有任何真实世界的应用程序?

虽然我会说这是一个错误或至少是我的设置有问题,但似乎MySQL说这是一个功能(herehere)。

如果那么,如MySQL所言,它只能在默认数据库上工作,那么这个设置如何具有实际的真实世界目的?

我缺少的东西?


参考my.cnf中的相关部分。我一直在通过在phpMyAdmin中执行插入和更新来测试它,如果这样做有任何区别的话。

log-bin=mysql-bin 
binlog_do_db=db1 

replicate-rewrite-db=db1->db2 
replicate-wild-do-table=db2.table1 
+1

我提供了一个答案,但我明天将设置一个实际环境来重新创建测试场景并验证您的情况。如果您还有时间,请尝试使用标准的mysql控制台,并比较USE db1和通用插入与在查询中指定数据库名称之间的关系。你应该看到有所不同。 – Michael 2012-08-15 15:25:55

回答

4

Replication-rewrite-db用法与其他复制选项相同。不仅Replication-rewrite-db在默认数据库上工作,但这些也是:replicate-do-db, replicate-ignore-db, binlog-do-db and binlog-ignore-db。请参阅thisthis

有真实世界的目的,否则MySQL不会实现这个选项。它仅适用于默认数据库because -

主要的原因“检查只是默认数据库”的行为是 ,很难单从语句来知道它是否 应复制(例如,如果您使用多表 DELETE语句或跨多个数据库操作的多表UPDATE语句)。如果不需要,只检查默认的 数据库而不检查所有数据库也更快。

您还应该知道复制规则。从here

我发出INSERT, DELETE and UPDATE phpmyadmin的测试,发现(通过启用general_query_log),它发出INIT DB 'db_name'(“初始化数据库”中记录了mysql_select_db() API调用)。

例如:

Init DB sakila 
1 Query INSERT INTO `sakila`.`actor_info` (`actor_id`, `first_name`, `last_name`, `film_info`) VALUES ('1235', 'abc', 'efg', NULL) 

所以,最后的复制不应该打破的phpMyAdmin的正确做它的每一个查询之前执行USE数据库。

+0

感谢Ashwin,你是第一个质疑我如何测试的人,并且让我意识到我出错的地方。通过phpmyadmin发布sql命令确实可行,但phpmyadmin生成的sql命令的格式为db1.table_name,所以这就是错误。我现在已经运行了几次测试,看起来不错。 – 2012-08-22 14:16:41

1

我相信他们在文档中提到那里的是,它是不会为你翻译特定数据库的名称,只有数据库通过使用set 。他们的意思是,如果你要执行如下操作:

USE db1; 
INSERT INTO table_name (x,y,z) VALUES (1,2,3); 

它应该按照你的期望执行。

但是,如果您在查询中明确指定了一个数据库,它将不会自动为您进行翻译。例如

INSERT INTO db1.table_name (x,y,z) VALUES (1,2,3); 

很可能phpMyAdmin正在翻译您的查询以指定数据库名称以及表名。

编辑: 尽管如此,如果您完全控制整个系统中的查询创作,这确实有实际用途,但您需要非常小心,以便知道查询在运行前是什么。某些类型的ORM系统或中介会重写您的查询,以使您明确。我不会建议在生产中使用它,尤其是当几个团队正在编写与您的MySQL服务器连接的代码时。

+0

所以要得到这个工作,你必须在每一个sql查询中指定数据库?当然,这是温和的?如果MySQL知道要写入哪个数据库,那么为什么复制引擎不能? – 2012-08-15 20:02:11

+0

嗨迈克尔,虽然这可能有效,但没有作者的每一个查询,它不能保证所有的时间工作。在这种情况下,它可能会很快导致两个数据库的差异。有没有办法让MySQL简单地将当前选定的数据库添加到复制引擎? – 2012-08-21 15:57:24

1

我有一个设置了的MySQL服务器的数量有限,两个。一种是生产(PROD),仅用于生产,另一种是开发,兼作灾难恢复(DR)和运行渴望查询。

要启用灾难恢复,PROD服务器使用复制复制到灾难恢复,但不进行重命名,最终会在具有相同名称的同一台服务器上结束两个数据库。所以,我有什么是生产:

db_application 

和发展我有两个

db_application (which is used for development) 
slave_application (which is used for DR) 

而是在每一个语句中使用的使用,我用的是连接字符串指定的数据库是默认的,没有的语句包含数据库名称。 (即SELECT * FROM表而不是SELECT * FROM DB.TABLE

这使得复制工作,并具有相同的名称作为生产服务器开发服务器上的数据库。这适合我的需求,但我很欣赏别人可能不会觉得这设置实用。这更适合完全控制SQL,但对连接字符串的控制有限。

+0

因此,您在两台服务器之间运行复制,但具有相同的数据库名称,即db_application。我最终也不得不诉诸于这种情况。但是,我的问题是关于使用replicate-rewrite-db语句在不同的数据库名称之间进行操作。对不起,这里没有赏金。 – 2012-08-22 08:20:40

+0

不完全。复制是db_application => slave_application。 DR盒上的db_application是开发实例,这就是为什么我需要使用replicate-rewrite-db(DR,像往常一样,是一个后想) – joocer 2012-08-22 08:25:32

+0

然后这正是我所追求的,你怎么样我的.cnf安装程序来处理这个? – 2012-08-22 09:29:15

相关问题