簡體   English   中英

備份 MySQL 亞馬遜 RDS

[英]Backup MySQL Amazon RDS

我正在嘗試在 AWS 之外設置副本,並且 master 正在 AWS RDS 上運行。 而且我不希望我的主人有任何停機時間。 所以我設置了我的從節點,現在我想備份我在 AWS 上的當前數據庫。

mysqldump -h RDS ENDPOINT -u root -p --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --all-databases > /root/dump.sql

我在我的虛擬機上測試了它並且它工作正常但是當它與 RDS 綁定時它給了我錯誤

mysqldump: Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied for user 'root'@'%' (using password: YES) (1045)

是因為我沒有超級用戶權限還是如何解決這個問題? 請有人建議我。

RDS 甚至不允許主用戶具有SUPER權限,這是執行FLUSH TABLES WITH READ LOCK所必需的。 (這是 RDS 的一個不幸限制)。

失敗語句是由--master-data選項生成的,當然,如果您希望能夠了解備份開始的精確二進制日志坐標,這是必要的。 FLUSH TABLES WITH READ LOCK獲取所有表上的全局讀鎖,這允許 mysqldump 以START TRANSACTION WITH CONSISTENT SNAPSHOT (與--single-transaction ),然后SHOW MASTER STATUS以獲取二進制日志坐標,然后釋放全局讀鎖,因為它有一個事務,可以將可見數據保持在與該日志位置一致的狀態。

RDS 通過拒絕SUPER特權並且沒有提供明顯的解決方法來破壞這種機制。

有一些 hacky 選項可用於正確解決此問題,但沒有一個可能特別有吸引力:

  • 在低流量期間做備份。 如果 binlog 坐標在您開始備份和備份開始將數據寫入輸出文件或目標服務器之后沒有改變(假設您使用了--single-transaction ),那么這將起作用,因為您知道坐標沒有t 在進程運行時更改。

  • 在開始備份之前觀察 master 上的 binlog 位置,並將這些坐標與CHANGE MASTER TO 如果您的 master 的binlog_format設置為ROW那么這應該可以工作,盡管您可能必須跳過一些初始錯誤,但隨后不必有任何錯誤。 這是有效的,因為基於行的復制是非常確定的,如果它試圖插入已經存在的東西或刪除已經消失的東西,它就會停止。 一旦通過錯誤,您將處於一致快照實際開始的真實二進制日志坐標處。

  • 與上一項一樣,但是,在恢復備份后,嘗試通過使用mysqlbinlog --base64-output=decode-rows --verbose在您獲得的坐標處讀取主站的二進制日志,檢查您的新從站以查看正確的位置哪些事件必須在快照實際開始之前已經執行,並使用以這種方式確定的坐標來CHANGE MASTER TO

  • 使用外部進程獲取服務器上每個表的讀鎖,這將停止所有寫入; 觀察SHOW MASTER STATUS中的 binlog 位置已停止遞增,開始備份並釋放這些鎖。

如果您使用這些方法中的任何一種,也許不是最后一種,那么進行表比較以確保您的從站與主站運行時相同,這一點尤為重要。 如果您遇到后續的復制錯誤......那么它不是。

可能最安全的選擇——但也可能是最煩人的,因為它似乎沒有必要——首先創建 RDS 主節點的 RDS 只讀副本。 一旦它啟動並同步到主服務器,您可以通過執行 RDS 提供的存儲過程來停止 RDS 只讀副本上的復制, CALL mysql.rds_stop_replication 在 RDS 5.6.13 和 5.5.33 中引入,它不需要SUPER特權。

在 RDS 副本從站停止后,從 RDS 只讀副本中獲取您的mysqldump ,該副本現在將具有作為特定主坐標集的不變數據集。 將此備份恢復到您的異地從站,然后使用來自SHOW SLAVE STATUS Exec_Master_Log_PosRelay_Master_Log_File的 RDS 只讀副本的主坐標作為您的CHANGE MASTER TO坐標。

從站上的Exec_Master_Log_Pos顯示的值是 要處理的下一個事務或事件的開始,這正是您的新從站需要在主站上開始讀取的位置。

然后,一旦您的外部從站啟動並運行,您就可以停用 RDS 只讀副本。

謝謝邁克爾,我覺得使用讀取副本作為源的最正確的解決方案和通過AWS建議是做復制作為解釋在這里

准備好 RDS master、RDS 只讀副本和 MySQL 實例,獲取外部 slave 的步驟是:

  1. 在 master 上,增加 binlog 保留期。

mysql> CALL mysql.rds_set_configuration('binlog retention hours', 12);

  1. 在只讀副本上停止復制以避免備份期間發生更改。

mysql> CALL mysql.rds_stop_replication;

  1. 在只讀副本上注釋 binlog 狀態(Master_Log_File 和 Read_Master_Log_Pos)

mysql> SHOW SLAVE STATUS;

  1. 在服務器實例上做一個備份並導入它(按照 Max 的建議使用 mydumper 可以加快進程)。

mysqldump -h RDS_READ_REPLICA_IP -u root -p YOUR_DATABASE > backup.sql

mysql -u root -p YOUR_DATABASE < backup.sql

  1. 在服務器實例上將其設置為 RDS master 的 slave。

mysql> CHANGE MASTER TO MASTER_HOST='RDS_MASTER_IP',MASTER_USER='myrepladmin', MASTER_PASSWORD='pass', MASTER_LOG_FILE='mysql-bin-changelog.313534', MASTER_LOG_POS=1097;

將 MASTER_LOG_FILE 和 MASTER_LOG_POS 替換為你之前保存的 Master_Log_File Read_Master_Log_Pos 的值,同時你還需要 RDS master 中的用戶才能被 slave 復制使用。

mysql> START SLAVE;

  1. 在服務器實例上檢查復制是否成功。

mysql> SHOW SLAVE STATUS;

  1. 在 RDS 只讀副本上恢復復制。 mysql> CALL mysql.rds_start_replication;

對於 RDS binlog 位置,您可以將mydumper--lock-all-tables使用,它將使用LOCK TABLES ... READ只是為了獲取 binlog 坐標,然后重新FTWRL它而不是FTWRL

Michael 的回答非常有幫助,並且集中在主要症結上:您根本無法在 RDS 上授予所需的 SUPER 特權,因此您不能使用 --master-data 標志,這會使事情變得更加容易。

我讀到可以通過 API 創建或修改數據庫參數組來解決此問題,但我認為使用 RDS 過程是更好的選擇。

不過,多層復制方法運行良好,並且可以包括 RDS/VPC 之外的層,因此可以使用此方法從“經典”EC2 復制到 VPC。

許多必要的功能僅在 MySQL 5.5 和 5.6 的更高版本中才有,我強烈建議您在復制堆棧中涉及的所有數據庫上運行相同版本,因此您可能必須先升級舊數據庫其中,這意味着更多的乏味和重復等等。

我遇到了類似的問題,對此的快速解決方法是:

  1. 創建 EBS 卷以擁有額外空間或擴展 EC2 上的當前 EBS 卷。 (或者如果你有額外的空間,你可以使用它)。

  2. 使用不帶 --master-data 或 --flush-data 指令的 mysqldump 命令生成數據庫的完整(FULL)備份。

    mysqldump -h 主機名 --routines -uadmin -p12344 test_db > filename.sql

admin 是數據庫名稱,12344 是密碼

以上是備份單個數據庫,如果需要備份所有數據庫,則指定 --all-databases 並提及數據庫名稱。

  1. 創建此命令的 Cron 以每天運行一次,它將自動生成轉儲。

請注意,如果您的數據庫大小很大,這將產生額外費用。 因為它創建了一個完整的數據庫轉儲。

希望這有幫助

你需要

1- 在 aws 上創建只讀副本

2- 確保此實例趕上主實例

3- 停止復制並通過獲取log_filelog_position參數

show slave status \G

4- 轉儲數據庫並使用第 3 步中記錄的參數在您自己的服務器上啟動復制。

5-啟動從站。

詳細說明在這里

要么事情發生了變化,因為@Michael - sqlbot 的回應,或者這里發生了誤解(可能是我的原因),

您可以使用COPY將 csv 文件導入 rds,至少在 postgres 版本上,您只需要使用FROM STDIN而不是直接命名文件,
這意味着您最終會使用管道,例如:

cat data.csv | psql postgresql://server:5432/mydb -U user -c "COPY \"mytable\" FROM STDIN DELIMITER ',' "

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM