Mysql

MySQL:從 binlog 中提取 SQL 語句

  • September 7, 2013

我正在嘗試使用以下命令從 binlog 中提取 SQL 語句,以便在另一個數據庫(Amazon RDS)中使用它

mysqlbinlog /var/lib/mysql/binlog.000027 --start-position=54375264 --base64-output=NEVER > /home/ec2-user/output2.sql

但我收到以下錯誤:

ERROR: --base64-output=never specified, but binlog contains a Table_map event which must be printed in base64.

我在文件中讀到,如果發現必須使用 BINLOG 顯示的行事件,mysqlbinlog 將退出並出現錯誤。有什麼辦法可以從 binlog 中提取 SQL 語句嗎?


更新 1: 我使用選項 –verbose 再次執行該命令,但在命令行中沒有得到任何返回

[root@server ec2-user]# mysqlbinlog /var/lib/mysql/binlog.000027 --start-position=54375264 --base64-output=DECODE-ROWS --verbose  > /home/ec2-user/output4.sql
[root@server ec2-user]# 
[root@server ec2-user]#

當我瀏覽 output4.sql 時,我可以看到一些有效 SQL + 一些註釋 SQL,如下所示:

#130906 14:54:55 server id 1  end_log_pos 269447893     Query   thread_id=1221718733    exec_time=0 error_code=0
SET TIMESTAMP=1378479295/*!*/;
BEGIN
/*!*/;
# at 269447893
# at 269447950
#130906 14:54:55 server id 1  end_log_pos 269447950     Table_map: `dbname`.`tablename` mapped to number 102
#130906 14:54:55 server id 1  end_log_pos 269448102     Update_rows: table id 102 flags: STMT_END_F
### UPDATE `dbname`.`tablename`
### WHERE
###   @1='edited by me'
###   @2=0
###   @3=1373178370
### SET
###   @1='edited by me'
###   @2=0
###   @3=1378479295
# at 269448102
#130906 14:54:55 server id 1  end_log_pos 269448162     Query   thread_id=1221718733    exec_time=0 error_code=0

更新 2: 我正在關注這裡的教程https://engineering.gosquared.com/migrating-mysql-to-amazon-rds

我想從 binlog 的輸出中更新 Amazon RDS。目前 Amazon RDS 不允許從 binlog 寫入。我正在嘗試從 binlog 中提取 SQL 語句,以便更新 Amazon RDS。有沒有辦法從 binlog 更新 Amazon RDS?

--base64-output=DECODE-ROWS --verbose

如果您手動查看二進制日誌,這是您需要使用的格式……它從日誌中提取最大數量的有用數據……但如果您首先了解二進制日誌在 MySQL 中的工作原理,它將有所幫助。

RDS(至少對於 MySQL 5.5 和 5.6)使用binlog_format= MIXED這意味著伺服器可以在逐個查詢的基礎上選擇記錄已執行的實際 SQL 語句(“語句”日誌)或查詢更改**的實際行(“行”日誌),但不能同時記錄兩者.

正如文件中所解釋的,您所看到的“註釋 SQL”是對使用該ROW格式記錄的事件在主伺服器上更改的實際數據的人類可讀偽 SQL 重建。不保留進行更改的查詢主體,因為複制不需要它——從屬伺服器可以複製與主伺服器上發生的完全相同的更改,基於這些之前(“where”)和之後(“設置”)行圖像。

您無法從這些事件中“獲取”原始 SQL,因為這樣編寫事件時它不會保存到二進制日誌中。在您發布的範例中,它告訴您第三列的值發生了變化。

###   @3=1373178370 # old value

###   @3=1378479295 # new value

此“偽 SQL”已被註釋掉,因為它不是伺服器可以執行的實際有效 SQL。它僅與眼球兼容。(為了讓伺服器重放這些行事件,它需要查看塊,這些塊是為您解碼BINLOG的資訊的 base64 編碼版本,請點擊此處)。mysqlbinlog

對於基於行的事件,列名也不會保留在二進制日誌中,因為由於它們在主從伺服器上應該相同,因此不需要該資訊。

(編輯:您提到了 RDS,但重新閱讀了您的問題,看來您可能正在嘗試將這些日誌應用到 RDS,而不是從 RDS 中檢索它們;從 RDS 檢索日誌僅適用於 RDS/MySQL 5.6。結論,那麼,產生這些日誌的伺服器是登錄MIXED還是ROW模式。)


更新:我明白你現在在做什麼。總結您發布的連結,您正在嘗試 (1) 使用 為現有伺服器拍攝時間點快照mysqldump,(2) 將該快照還原到 RDS 實例,然後 (3) 用於mysqlbinlog向前播放事務從 binlog 將 RDS 伺服器同步到您現有的生產伺服器,最後 (4) 將您的應用程序遷移到 RDS。

底線:您過度思考問題的性質,並且無緣無故地擔心。MySQL 伺服器知道如何解釋mysqlbinlog 沒有--base64-outputor--verbose標誌的輸出並應用它看到的更改,無論原始查詢 SQL 是否被記錄,因為當查詢沒有被記錄時,實際的行更改會被記錄。

當你跑步時,mysqlbinlog你會看到看起來幾乎像噪音的東西。例子:

#080828 15:03:08 server id 1  end_log_pos 442   Delete_rows: table id 17 flags: STMT_END_F
...
BINLOG '
fAS3SBMBAAAALAAAANoAAAAAABEAAAAAAAAABHRlc3QAAXQAAwMPCgIUAAQ=
fAS3SBcBAAAAKAAAAAIBAAAQABEAAAAAAAEAA//8AQAAAAVhcHBsZQ==
'/*!*/;

這是一個非常緊湊的二進制“行圖像”的 base-64 編碼版本,其中包含需要對數據庫進行的*實際更改。*MySQL 伺服器知道如何解碼和應用此更改。相反,當您decode-rows和時verbose,您要求mysqlbinlog解碼人類眼球的二進制日誌。

保持伺服器binlog_format設置不變。二進制日誌應該可以正常工作。


**但是現在,忘記你計劃的一切,**因為在過去的 24 小時內,亞馬遜宣布了一種更好的方法:他們已經開放了將 RDS 實例作為從站臨時連接到非 RDS 主站的能力,以允許RDS 實例在升級為主伺服器之前自動進入實時狀態。

這正是您要完成的任務的解決方案,並且更容易且不易出錯。

要從不在 Amazon RDS 中的 MySQL 數據庫導入數據,您可以配置從該數據庫到在 Amazon RDS 中執行的 MySQL 實例的複制。您要從中遷移的 MySQL 數據庫可以在您的數據中心本地執行,也可以在 Amazon EC2 實例上執行。Amazon RDS 中的 MySQL 實例必須執行版本 5.5.33 或 5.6.13。使用複制來遷移數據可以減少停機時間。

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Procedural.Importing.NonRDSRepl.html

不開玩笑。

作為一名 DBA,我一直非常不願意在我自己的生產網路中使用 RDS,更願意保留對伺服器所有方面的完全控制……“不願意”,我的意思是“我們沒有”。當 Amazon 在 RDS for MySQL 5.6 中將 RDS 實例用作非 RDS 從屬伺服器的主伺服器時,我終於心軟了……現在,使用 RDS 主伺服器作為舊伺服器的從屬伺服器來簡化遷移似乎是另一個積極的方面簽署 RDS 的可行性。

MySQL文件中提到了唯一可能的解決方法

您可以使用 –base64-output=DECODE-ROWS 選項告訴 mysqlbinlog 禁止行事件的 BINLOG 語句。這類似於 –base64-output=NEVER 但如果找到行事件,則不會退出並出現錯誤。–base64-output=DECODE-ROWS 和 –verbose 的組合提供了一種僅將行事件視為 SQL 語句的便捷方法:

試一試 !!!

引用自:https://dba.stackexchange.com/questions/49409