Mysql

–log-slave-updates 已關閉,但某些更新仍會記錄到從屬二進制日誌中?

  • April 5, 2012

MySQL 版本 5.5.14

根據文件,預設情況下,從屬伺服器不會將任何從主伺服器接收到的更新記錄到其二進制日誌中。

這是我的配置。在奴隸上:

# egrep 'bin|slave' /etc/my.cnf
relay-log=mysqld-relay-bin
log-bin = /var/log/mysql/mysql-bin
binlog-format=MIXED
sync_binlog = 1
log-bin-trust-function-creators = 1

mysql> show global variables like 'log_slave%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| log_slave_updates | OFF   |
+-------------------+-------+
1 row in set (0.01 sec)

mysql> select @@log_slave_updates;
+---------------------+
| @@log_slave_updates |
+---------------------+
|                   0 |
+---------------------+
1 row in set (0.00 sec)

但是slave仍然記錄了它的二進制日誌的一些變化,讓我們看看文件大小:

-rw-rw---- 1 mysql mysql  37M Apr  1 01:00 /var/log/mysql/mysql-bin.001256
-rw-rw---- 1 mysql mysql  25M Apr  2 01:00 /var/log/mysql/mysql-bin.001257
-rw-rw---- 1 mysql mysql  46M Apr  3 01:00 /var/log/mysql/mysql-bin.001258
-rw-rw---- 1 mysql mysql 115M Apr  4 01:00 /var/log/mysql/mysql-bin.001259
-rw-rw---- 1 mysql mysql 105M Apr  4 18:54 /var/log/mysql/mysql-bin.001260

mysqlbinlog以及使用實用程序讀取這些二進製文件時的範例查詢:

#120404 19:08:57 server id 3  end_log_pos 110324763     Query   thread_id=382435        exec_time=0     error_code=0
SET TIMESTAMP=1333541337/*!*/;
INSERT INTO norep_SplitValues VALUES ( NAME_CONST('cur_string',_utf8'118212' COLLATE 'utf8_general_ci'))
/*!*/;
# at 110324763

我錯過了什麼?


回复@RolandoMySQLDBA:

如果複製帶來了這種情況,那麼中繼日誌中必須有相同的查詢。請查找具有相同 TIMESTAMP (1333541337) 的 INSERT 查詢的中繼日誌。

中繼日誌中沒有具有相同 TIMESTAMP 的此類查詢。

如果您在中繼日誌中找不到它,請查看 Infobright 是否發布了 INSERT 查詢。在這種情況下,INSERT 應該記錄在 Slave 的二進制日誌中。

更深入地查看二進制日誌,我發現幾乎所有查詢都是 CREATE/INSERT/UPDATE/DROP “臨時”表,如下所示:

# at 123873315
#120405  0:42:04 server id 3  end_log_pos 123873618     Query   thread_id=395373        exec_time=0     error_code=0
SET TIMESTAMP=1333561324/*!*/;
SET @@session.pseudo_thread_id=395373/*!*/;
CREATE TEMPORARY TABLE `norep_tmpcampaign` (
   `campaignid` INTEGER(11)  NOT NULL DEFAULT '0' ,
   `status` INTEGER(11)  NOT NULL DEFAULT '0' ,
   `updated` DATETIME,
        KEY `campaignid` (`campaignid`)             
       )ENGINE=MEMORY
/*!*/;
# at 123873618
#120405  0:42:04 server id 3  end_log_pos 123873755     Query   thread_id=395373        exec_time=0     error_code=0
SET TIMESTAMP=1333561324/*!*/;
DROP TABLE IF EXISTS `norep_tmpcampaign1` /* generated by server */

這裡的“臨時”意味著它們在計算完成後被丟棄。我還告訴從站不要複製任何與norep_萬用字元模式匹配的語句:

replicate-wild-ignore-table=%.norep_%

但是二進制日誌中有一個異常表:

# at 123828094
#120405  0:37:21 server id 3  end_log_pos 123828495     Query   thread_id=395209        exec_time=0     error_code=0
SET TIMESTAMP=1333561041/*!*/;
INSERT INTO sessions  (SessionId, ApplicationName, Created, Expires,   LockDate, LockId, Timeout, Locked, SessionItems, Fla
gs)  Values('pgv2exo4y4vo4ccz44vwznu0', '/', '2012-04-05 00:37:21', '2012-04-05 00:57:21',   '2012-04-05 00:37:21', 0, 20, 
0, 'AwAAAP////8IdXNlcm5hbWUGdXNlcmlkCHBlcm1pdGlkAgAAAAQAAAAGAAAAAQABAAEA', 0)
/*!*/;

描述:

mysql> desc reportingdb.sessions;
+-----------------+------------------+------+-----+---------------------+-------+
| Field           | Type             | Null | Key | Default             | Extra |
+-----------------+------------------+------+-----+---------------------+-------+
| SessionId       | varchar(64)      | NO   | PRI |                     |       |
| ApplicationName | varchar(255)     | NO   |     |                     |       |
| Created         | timestamp        | NO   |     | 0000-00-00 00:00:00 |       |
| Expires         | timestamp        | NO   |     | 0000-00-00 00:00:00 |       |
| LockDate        | timestamp        | NO   |     | 0000-00-00 00:00:00 |       |
| LockId          | int(11) unsigned | NO   |     | NULL                |       |
| Timeout         | int(11) unsigned | NO   |     | NULL                |       |
| Locked          | bit(1)           | NO   |     | NULL                |       |
| SessionItems    | varchar(255)     | YES  |     | NULL                |       |
| Flags           | int(11)          | NO   |     | NULL                |       |
+-----------------+------------------+------+-----+---------------------+-------+

我確信所有這些查詢都是由 MySQL 發布的,而不是 Infobright

$ mysql-ib -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 48971
Server version: 5.1.40 build number (revision)=IB_4.0.5_r15240_15370(ice) (static)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select * from information_schema.tables where table_name='sessions';
Empty set (0.02 sec)

我一直在嘗試使用主伺服器上的測試表進行一些 INSERT/UPDATE 查詢,它被複製到中繼日誌,而不是從伺服器上的二進制日誌:

# at 311664029
#120405  0:15:23 server id 1  end_log_pos 311664006     Query   thread_id=10458250      exec_time=0     error_code=0
use testuser/*!*/;
SET TIMESTAMP=1333559723/*!*/;
update users set email2='xx@gmail.com' where id=22
/*!*/;

請注意server id,在中繼日誌中,server id 是 master 的(1),而在二進制日誌中,server id 是 slave 的(在這種情況下為 3)。


回复@RolandoMySQLDBA:Thu Apr 5 10:06:00 ICT 2012

CREATE DATABASE quantatest;現在請在Master上執行。告訴我是否CREATE DATABASE quantatest;出現在奴隸的二進制日誌中。

正如我上面所說:

我一直在嘗試使用主控上的測試表進行一些 INSERT/UPDATE 查詢,它被複製到中繼日誌,而不是二進制日誌

你可以猜到,IO 執行緒將其複製到中繼日誌,而不是二進制日誌。

#120405 10:07:25 server id 1  end_log_pos 347573819     Query   thread_id=10480775      exec_time=0     error_code=0
SET TIMESTAMP=1333595245/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
create database quantatest
/*!*/;

問題可能必須更改為:為什麼某些更新查詢仍然記錄到從屬二進制日誌中,但--log-slave-updates一直被禁用?他們來自哪裡?

以下是最後幾個:

/*!*/;
# at 27492197
#120405 10:12:45 server id 3  end_log_pos 27492370      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595565/*!*/;
CREATE TEMPORARY TABLE norep_SplitValues (
       value VARCHAR(1000) NOT NULL
     ) ENGINE=MEMORY
/*!*/;
# at 27492370
#120405 10:12:45 server id 3  end_log_pos 27492445      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595565/*!*/;
BEGIN
/*!*/;
# at 27492445
#120405 10:12:45 server id 3  end_log_pos 27492619      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595565/*!*/;
INSERT INTO norep_SplitValues VALUES ( NAME_CONST('cur_string',_utf8'119577' COLLATE 'utf8_general_ci'))
/*!*/;
# at 27492619
#120405 10:12:45 server id 3  end_log_pos 27492695      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595565/*!*/;
COMMIT
/*!*/;
# at 27492918
#120405 10:12:46 server id 3  end_log_pos 27493115      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595566/*!*/;
SELECT `reportingdb`.`selfserving_get_locationad`(_utf8'3' COLLATE 'utf8_general_ci',_utf8'' COLLATE 'utf8_general_ci')
/*!*/;
# at 27493199
#120405 10:12:46 server id 3  end_log_pos 27493353      Query   thread_id=410353        exec_time=0     error_code=0
SET TIMESTAMP=1333595566/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
DROP TEMPORARY TABLE IF EXISTS `norep_SplitValues` /* generated by server */
/*!*/;

對我來說,server-id 值顯示事情正在按預期工作。

每個語句都與來自該語句的伺服器的 server-id 相關聯(這是 mysql 伺服器知道不從自身複製語句的方式,除非您使用特定設置)。即使通過複製也可以保留此關聯。

您可以看到來自 master (server-id 1) 的語句僅被複製,儲存在中繼日誌中,然後在 slave 上執行,而不寫入 slave binlog。您看到的與 server-id 3(從屬)關聯的語句必須在從屬數據庫上本地執行。這就是為什麼它們被寫入二進制日誌的原因。log-slave-updates 不會排除本地編寫的查詢。

您應該查看從屬數據庫上的流量:必須連接並執行這些查詢。如果您在程序列表中看不到任何內容(沒有持久連接),您可以嘗試打開通用日誌或使用 tcpdump 或其他方式擷取 mysql 流量。

另外:您說您希望從站上的二進制日誌用於增量備份。如果您有意從從屬二進制日誌中排除複製流量,那聽起來您實際上沒有能力使用這些二進制日誌進行時間點備份/恢復。您將失去所有複製流量。所以也許你應該使用 log-slave-updates 嗎?沒有把握。

-和

引用自:https://serverfault.com/questions/376627