AWS雲平台上,RDS Mysql資料庫的跨賬号遷移。并沒有像同賬号内的簡易建立方式,在控制台“點一點”實作。但是為了将業務停機時間降到最低,master+replica 的方式又是最成熟有效的方案。如何自行實作這個方案呢?
本文就是将 RDS Mysql 5.7 的資料庫,從 A 賬号,遷移到 B 賬号。使用 master+replica 的方式,進行遷移。遷移前進行方案驗證,步驟如下:
1. 環境準備:
Region/AZ: us-east-1f
賬号 A
EC2(M5.xlarge): 安裝 sysbench,模拟生産,持續通路資料庫
RDS Mysql 5.7(M5.large): 主資料庫(MasterA)
RDS Mysql 5.7(M5.large): 臨時從資料庫(replicaA)
賬号 B
RDS Mysql 5.7(M5.large): 從資料庫,遷移後的主資料庫(replicaB)
2. 賬号 A 的 masterA 和 replicA 已經準備完成
注釋:RDS mysql 是沒有權限 lock table 的,為了能拿到一緻性備份,并且擷取 binglogID 和 position ID,是以臨時
需要賬号 A 的 RDS replica。
3. 使用 sysbench 模拟生産資料,後續通過 sysbench 模拟生産流量(在 masterA 上插入)
mysql>create database dbtest;
#sysbench --test=oltp.lua \
--mysql-host=mysql-host-ip --mysql-port=3306 \
--mysql-user=admin \
--mysql-password=password \
--mysql-db=dbtest --oltp-tables-count=20 --oltp-table-size=500000 \
--report-interval=10 --rand-init=on --max-requests=0 \
--oltp-read-only=off --max-time=120 --num-threads=30 \
[ prepare | run | cleanup ]
4. 暫停 masterA 和 replicaA 的同步
4.1. 在主庫根據情況設定 binlog 的保留期限,我這裡滾動間隔設定為 96 小時,語句如下:
CALL mysql.rds_set_configuration('binlog retention hours', 96);
查詢設定資訊:
CALL mysql.rds_show_configuration;
4.2. 準備擷取生産的一緻性備份,需要暫停“賬号 A“主從之間複制,在 replicaA 上執行:
mysql -hreplica-local.xxxxxxxx.us-east-1.rds.amazonaws.com -uadmin -p<password>
MYSQL> CALL mysql.rds_stop_replication;
恢複同步指令:
CALL mysql.rds_start_replication;
需要緊密監控 RDS 存儲所剩空間,以防磁盤空間枯竭的情況發生。
4.3. 指令輸出參考:
5. 建立 Amazon RDS 資料庫執行個體的快照
5.1. 連接配接到隻讀副本 replicaA,然後運作 mysql_rds_stop_replication 過程以停止複制。
5.2.當隻讀副本處于 Stopped(已停止)時,連接配接到隻讀副本并運作
SHOW SLAVE STATUS\G
從 Relay_Master_Log_File 字段檢索目前二進制日志檔案名,并從 Exec_Master_Log_Pos 字段檢索日志檔案位置。在開始複制前,儲存這些值。
mysql> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 10.1.1.206
Master_User: rdsrepladmin
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-changelog.000336
Read_Master_Log_Pos: 154
Relay_Log_File: relaylog.000106
Relay_Log_Pos: 387Relay_Master_Log_File: mysql-bin-changelog.000336
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
mysql.plugin,mysql.rds_monitor,mysql.rds_sysinfo,innodb_memcache.cache_policies,mysql.rds_history,innodb_memcache.config_options,mysql.rds_configuration,m
ysql.rds_replication_status
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 644
Until_Condition: None
5.3. 在隻讀副本保持 Stopped (已停止) 狀态期間,建立隻讀副本的資料庫快照。
6. 傳輸鏡像到賬号 B
6.1. 建立一個客戶管理的 Key,用于後續在賬戶 B 中還原 RDS 使用
6.2. 建立 Key 的過程中,直接共享給“賬号 B”
6.3. 拷貝鏡像,修改 AWS Managed Key 為 Customer Managed Key
這裡要選擇剛剛建立的Key
6.4. 共享快照給賬号B
6.5. 在賬号 B,可以看到賬号 A 共享的鏡像
6.6. 通過鏡像,複制一份到賬号 B,然後通過該鏡像建立 RDS Mysql
6.7. 此時,隻讀副本 replicaA 已經沒有用處,可以删除。
7. 開始準備跨賬号的 master+replica 的設定
7.1. 在 masterA 上建立專用于複制的使用者 ID。
mysql> CREATE USER 'repl_user'@'%' IDENTIFIED BY '<password>';
7.2. 該使用者需要 REPLICATION CLIENT 和 REPLICATION SLAVE 權限。向該使用者授予這些權限。
GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
7.3. 如果您需要使用加密複制,則需為複制使用者要求 SSL 連接配接。例如,您可以使用下面一個語句來要求使用者賬戶repl_user的 SSL 連接配接。
GRANT USAGE ON *.* TO 'repl_user'@'<domain_name>' REQUIRE SSL;
7.4. ReplicaB 上設定同步,指令如下:
CALL mysql.rds_set_external_master ('masterA-hostname', 3306,'repl_user', '<password>', 'mysql-bin-
changelog.000336', 154, 0);
7.5. 啟動同步
CALL mysql.rds_start_replication;
注:重置 replica 指令
CALL mysql.rds_reset_external_master
7.6. 現在可以在 replicaB 上查詢 slave 狀态,已經正常同步
7.7. 在 masterA 上,可以觀察連接配接資訊。 Repl_user 已經連上 master,并且等待 master 發送新的 binlog
8. 效果和性能驗證
8.1. 經過測試,在主庫masterA插入 5W 行,replicaB 可以立即查詢到,同步速度在 ms 級别,左邊視窗為masterA,右邊視窗為replicaB
注釋:賬号 B 的 replica,是無法在控制台觀察同步的 lag 的。
隻能通過 show slave status\G檢查狀态,重點關注名額如下:
判斷 Slave_IO_Running 和 Slave_SQL_Running 兩個線程的狀态Slave_IO 線程負責把主庫的 bin 日志(Master_Log)内容,投遞到從庫的中繼日志上(Relay_Log)。
Slave_SQL 線程負責把中繼日志上的語句在從庫上執行一遍。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_SQL_Running_State:顯示為 wait意思是中繼日志的 sql 語句已經全部執行完畢
8.2. ReplicaB 的輸出參考:
MySQL> show slave status\G
*************************** 1. row ***************************
......
Slave_IO_State: Waiting for master to send event
Master_Host: master.xxxxxxxx.us-east-1.rds.amazonaws.com
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-changelog.000421
Read_Master_Log_Pos: 511
Relay_Log_File: relaylog.000092
Relay_Log_Pos: 744
Relay_Master_Log_File: mysql-bin-changelog.000421
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 511
Relay_Log_Space: 1001
......
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 775308671
Master_UUID: e910577b-b95d-11ec-8675-164e76cd8371
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
8.3. 驗證方法二,自動化校驗 replica 同步情況8.4.
在主庫建立一個表,每 10s 插入時間戳,在 replica 查詢時間戳,就可以判斷同步情況
mysql> create table test.master_time (master_time datetime);
mysql> insert into test.master_time values(now());
自動化腳本,contab 每 10s 執行一次
#!/bin/sh
#insert time into master table
mysql -hmaster.xxxxxxxx.us-east-1.rds.amazonaws.com -uadmin -p<password> -e 'insert into test.master_time
values(now());'
# query time gap from replica
sleep 3
gap=$(mysql -haccb.cpbyya1ujkgc.us-east-1.rds.amazonaws.com -uadmin -p<password> -N -e 'select
time_to_sec(timediff(now(),(select max(master_time) from test.master_time as aa)));');
#Check the gap, then print the info
if [ $gap -gt 60 ]
then echo "Gap is bigger then 60s!!! Gap is "$gap"s"
else echo "Syncing, gap is "$gap"s"
fi
- 至此,完整的AWS RDS Mysql的遷移方案已經準備好。但是在實際生産切換之前,還有幾點需要注意:
9.1. MasterA上已有的使用者和權限,需要手動在replicaB上建立;
9.2. 持續觀察幾天資料同步的狀态,尤其是特殊類型字段的查詢;
9.3. 業務層通路測試,關注網絡連通性,安全組設定等。
現在,我們可以申請維護視窗,準備生産切換了。
參考文檔:
https://docs.amazonaws.cn/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Replication.html#AuroraMySQL.Replication.MySQL.RetainBinlogs
https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/mysql_rds_set_configuration.html
https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/mysql_rds_stop_replication.html
https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/mysql_rds_start_replication.html
https://blog.csdn.net/qq_38486203/article/details/80654040
https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/USER_MySQL.Replication.ReadReplicas.html
https://aws.amazon.com/cn/premiumsupport/knowledge-center/rds-mysql-high-replica-lag/