며칠전에 mysql master장비에 update를 했는데 replica(slave) 장비에는 update되지 않는 현상을 발견했다.
slave 장비의 Seconds_Behind_Master도 0이었다. 즉, update량이 많아서 늦어지는 것이 아니었다는 이야기다.
나는 그 row들에 다시한번 update를 하다가 이상한 점을 발견했는데 실제로 update되지 않는 것을 목격한 것이다.
즉, master에
update MyDatabase.MyTable set myname="jigu" where id=12345;
라는 query를 쳤을 때
mater 장비의 myname에는 "jigu"가 slave의 myname에는 "abc"라는 이전값이 그대로 있는 것이다.
원인은 database name을 주는 방식에 있었다.
http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication
저 페이지를 보면 아래 두게의 query의 의미는 같아도 replication시에는 A는 slave에 전달되고 B에는 전달되지 않는다고....
A) mysql -uxxx -pxxx -e 'update MyDatabase.MyTable set myname="jigu" where id=12345';
B) mysql -d MyDatabase -uxxx -pxxx -e 'update MyTable set myname="jigu" where id=12345';
그래서 mysql의 관련 페이지를 찾아 봤다.
http://dev.mysql.com/doc/refman/5.0/en/replication-options-slave.html
여기서 보면 두개를 다르게 처리하는 것 (A는 replication되지 않는 것)은 default database name을 명시적으로 적어주지 않은 query에 대해서 어떤 database에 replication되어야하는지 정하기 쉽지 않기 때문이라는 것이다.
즉, A의 예에서는 MyDatabase라는 것으로 default database name정해서 replica에게 전달해주면 된다고 생각되겠지만 여러개의 Database name을 사용하는 한개의 query에서는 사실상 default database name을 찾아내기가 불가능 하다는 것이 이유다.
해당 부분을 copy해서 붙여 놓는다.
Command-Line Format | --replicate-ignore-db=name |
||
Option-File Format | replicate-ignore-db |
||
Permitted Values | |||
Type | string |
Tells the slave SQL thread not to replicate any statement where the default database (that is, the one selected by USE
) is db_name
. To specify more than one database to ignore, use this option multiple times, once for each database. You should not use this option if you are using cross-database updates and you do not want these updates to be replicated. See Section 15.2.3, “How Servers Evaluate Replication Filtering Rules”.
An example of what does not work as you might expect: If the slave is started with --replicate-ignore-db=sales
and you issue the following statements on the master, the UPDATE
statement is replicated:
USE prices; UPDATE sales.january SET amount=amount+1000;
In the preceding example the statement is replicated because --replicate-ignore-db
only applies to the default database (set through the USE
statement). Because the sales
database was specified explicitly in the statement, the statement has not been filtered.
If you need cross-database updates to work, use --replicate-wild-ignore-table=
instead. SeeSection 15.2.3, “How Servers Evaluate Replication Filtering Rules”.db_name
.%
Beginning with MySQL 5.0.84, this option has no effect on BEGIN
, COMMIT
, or ROLLBACK
statements. (Bug #43263)
잘보면
--replicate-wild-ignore-table=db_name
.%
와 같은 형식으로 지정하면 해결할 수 있기는 하다. 'DB > Mysql' 카테고리의 다른 글
Mysql purge lag (0) | 2011.10.26 |
---|---|
Mysql timestamp update null value, mysql에서 timestamp 컬럼에 null을 update할때 (0) | 2011.08.30 |
Mysql 서브쿼리 사용법 페이지 (0) | 2011.07.01 |
Mysql index에 대해서 (0) | 2011.06.23 |
mysql insert 속도에 대하여 (Speed of INSERT Statements) (0) | 2011.04.19 |