Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySQL di Cloud - Migrasi Online dari Amazon RDS ke Server Anda sendiri:Part2

Seperti yang kita lihat sebelumnya, mungkin sulit bagi perusahaan untuk memindahkan data mereka dari RDS untuk MySQL. Di bagian pertama blog ini, kami menunjukkan cara menyiapkan lingkungan target Anda di EC2 dan menyisipkan lapisan proxy (ProxySQL) antara aplikasi Anda dan RDS. Di bagian kedua ini, kami akan menunjukkan kepada Anda bagaimana melakukan migrasi data yang sebenarnya ke server Anda sendiri, dan kemudian mengarahkan ulang aplikasi Anda ke instance database baru tanpa downtime.

Menyalin Data dari RDS

Setelah lalu lintas basis data kami berjalan melalui ProxySQL, kami dapat memulai persiapan untuk menyalin data kami dari RDS. Kita perlu melakukan ini untuk mengatur replikasi antara RDS dan instans MySQL kita yang berjalan di EC2. Setelah ini selesai, kami akan mengonfigurasi ProxySQL untuk mengalihkan lalu lintas dari RDS ke MySQL/EC2 kami.

Seperti yang telah kita bahas di posting blog pertama dalam seri ini, satu-satunya cara Anda bisa mendapatkan data dari RDS adalah melalui dump logis. Tanpa akses ke instance, kami tidak dapat menggunakan alat pencadangan fisik yang panas seperti xtrabackup. Kami juga tidak dapat menggunakan snapshot karena tidak ada cara untuk membuat hal lain selain instance RDS baru dari snapshot.

Kami terbatas pada alat dump logis, oleh karena itu opsi logis adalah menggunakan mydumper/myloader untuk memproses data. Untungnya, mydumper dapat membuat cadangan yang konsisten sehingga kami dapat mengandalkannya untuk menyediakan koordinat binlog untuk menghubungkan budak baru kami. Masalah utama saat membuat replika RDS adalah kebijakan rotasi binlog - pembuangan dan pemuatan logis dapat memakan waktu bahkan berhari-hari pada kumpulan data yang lebih besar (ratusan gigabita) dan Anda perlu menyimpan binlog di instans RDS selama seluruh proses ini. Tentu, Anda dapat meningkatkan retensi rotasi binlog di RDS (panggil mysql.rds_set_configuration('binlog retention hours', 24); - Anda dapat menyimpannya hingga 7 hari) tetapi jauh lebih aman jika melakukannya secara berbeda.

Sebelum melanjutkan dengan mengambil dump, kami akan menambahkan replika ke instance RDS kami.

Dasbor RDS Amazon Buat Replika DB di RDS

Setelah kita mengklik tombol "Buat Replika Baca", snapshot akan dimulai pada replika RDS "master". Ini akan digunakan untuk menyediakan budak baru. Prosesnya mungkin memakan waktu berjam-jam, semuanya tergantung pada ukuran volume, kapan terakhir kali snapshot diambil dan kinerja volume (io1/gp2? Magnetik? Berapa pIOPS yang dimiliki volume?).

Replika Master RDS

Ketika slave sudah siap (statusnya telah berubah menjadi “available”), kita dapat login menggunakan endpoint RDS-nya.

RDS Budak

Setelah masuk, kami akan menghentikan replikasi pada slave kami - ini akan memastikan master RDS tidak akan menghapus log biner dan log tersebut akan tetap tersedia untuk slave EC2 kami setelah kami menyelesaikan proses dump/reload kami.

mysql> CALL mysql.rds_stop_replication;
+---------------------------+
| Message                   |
+---------------------------+
| Slave is down or disabled |
+---------------------------+
1 row in set (1.02 sec)

Query OK, 0 rows affected (1.02 sec)

Sekarang, akhirnya saatnya untuk menyalin data ke EC2. Pertama, kita perlu menginstal mydumper. Anda bisa mendapatkannya dari github:https://github.com/maxbube/mydumper. Proses instalasi cukup sederhana dan dijelaskan dengan baik dalam file readme, jadi kami tidak akan membahasnya di sini. Kemungkinan besar Anda harus menginstal beberapa paket (tercantum dalam readme) dan bagian yang lebih sulit adalah mengidentifikasi paket mana yang berisi mysql_config - itu tergantung pada rasa MySQL (dan terkadang juga versi MySQL).

Setelah mydumper dikompilasi dan siap digunakan, Anda dapat menjalankannya:

[email protected]:~/mydumper# mkdir /tmp/rdsdump
[email protected]:~/mydumper# ./mydumper -h rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com -p tpccpass -u tpcc  -o /tmp/rdsdump  --lock-all-tables --chunk-filesize 100 --events --routines --triggers
. 

Harap perhatikan --lock-all-tables yang memastikan bahwa snapshot data akan konsisten dan memungkinkan untuk digunakan untuk membuat slave. Sekarang, kita harus menunggu sampai mydumper menyelesaikan tugasnya.

Satu langkah lagi diperlukan - kami tidak ingin memulihkan skema mysql tetapi kami perlu menyalin pengguna dan hibah mereka. Kita bisa menggunakan pt-show-grant untuk itu:

[email protected]:~# wget http://percona.com/get/pt-show-grants
[email protected]:~# chmod u+x ./pt-show-grants
[email protected]:~# ./pt-show-grants -h rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com -u tpcc -p tpccpass > grants.sql

Contoh pt-show-grant mungkin terlihat seperti ini:

-- Grants for 'sbtest'@'%'
CREATE USER IF NOT EXISTS 'sbtest'@'%';
ALTER USER 'sbtest'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*2AFD99E79E4AA23DE141540F4179F64FFB3AC521' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE USER, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, PROCESS, REFERENCES, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SELECT, SHOW DATABASES, SHOW VIEW, TRIGGER, UPDATE ON *.* TO 'sbtest'@'%';

Terserah Anda untuk memilih pengguna apa yang perlu disalin ke instans MySQL/EC2 Anda. Tidak masuk akal untuk melakukannya untuk mereka semua. Misalnya, pengguna root tidak memiliki hak istimewa 'SUPER' di RDS sehingga lebih baik untuk membuatnya kembali dari awal. Yang perlu Anda salin adalah hibah untuk pengguna aplikasi Anda. Kami juga perlu menyalin pengguna yang digunakan oleh ProxySQL (proxysql-monitor dalam kasus kami).

Memasukkan Data ke Instans MySQL/EC2 Anda

Seperti yang dinyatakan di atas, kami tidak ingin memulihkan skema sistem. Oleh karena itu kami akan memindahkan file yang terkait dengan skema tersebut keluar dari direktori mydumper kami:

[email protected]:~# mkdir /tmp/rdsdump_sys/
[email protected]:~# mv /tmp/rdsdump/mysql* /tmp/rdsdump_sys/
[email protected]:~# mv /tmp/rdsdump/sys* /tmp/rdsdump_sys/

Setelah selesai, saatnya untuk mulai memuat data ke dalam instance MySQL/EC2:

[email protected]:~/mydumper# ./myloader -d /tmp/rdsdump/ -u tpcc -p tpccpass -t 4 --overwrite-tables -h 172.30.4.238

Harap dicatat bahwa kami menggunakan empat utas (-t 4) - pastikan Anda mengatur ini ke apa pun yang masuk akal di lingkungan Anda. Ini semua tentang menjenuhkan instance MySQL target - baik CPU atau I/O, tergantung pada hambatannya. Kami ingin memeras sebanyak mungkin untuk memastikan kami menggunakan semua sumber daya yang tersedia untuk memuat data.

Setelah data utama dimuat, ada dua langkah lagi yang harus dilakukan, keduanya terkait dengan internal RDS dan keduanya dapat merusak replikasi kami. Pertama, RDS berisi beberapa tabel rds_* dalam skema mysql. Kami ingin memuatnya jika beberapa di antaranya digunakan oleh RDS - replikasi akan rusak jika budak kami tidak memilikinya. Kita dapat melakukannya dengan cara berikut:

[email protected]:~/mydumper# for i in $(ls -alh /tmp/rdsdump_sys/ | grep rds | awk '{print $9}') ; do echo $i ;  mysql -ppass -uroot  mysql < /tmp/rdsdump_sys/$i ; done
mysql.rds_configuration-schema.sql
mysql.rds_configuration.sql
mysql.rds_global_status_history_old-schema.sql
mysql.rds_global_status_history-schema.sql
mysql.rds_heartbeat2-schema.sql
mysql.rds_heartbeat2.sql
mysql.rds_history-schema.sql
mysql.rds_history.sql
mysql.rds_replication_status-schema.sql
mysql.rds_replication_status.sql
mysql.rds_sysinfo-schema.sql

Masalah serupa adalah dengan tabel zona waktu, kita perlu memuatnya menggunakan data dari instance RDS:

[email protected]:~/mydumper# for i in $(ls -alh /tmp/rdsdump_sys/ | grep time_zone | grep -v schema | awk '{print $9}') ; do echo $i ;  mysql -ppass -uroot  mysql < /tmp/rdsdump_sys/$i ; done
mysql.time_zone_name.sql
mysql.time_zone.sql
mysql.time_zone_transition.sql
mysql.time_zone_transition_type.sql

Ketika semua ini sudah siap, kita dapat mengatur replikasi antara RDS (master) dan instance MySQL/EC2 kita (slave).

Menyiapkan replikasi

Mydumper, saat melakukan dump yang konsisten, menuliskan posisi log biner. Kami dapat menemukan data ini dalam file bernama metadata di direktori dump. Mari kita lihat, kemudian kita akan menggunakan posisinya untuk mengatur replikasi.

[email protected]:~/mydumper# cat /tmp/rdsdump/metadata
Started dump at: 2017-02-03 16:17:29
SHOW SLAVE STATUS:
    Host: 10.1.4.180
    Log: mysql-bin-changelog.007079
    Pos: 10537102
    GTID:

Finished dump at: 2017-02-03 16:44:46

Satu hal terakhir yang kami kekurangan adalah pengguna yang dapat kami gunakan untuk mengatur budak kami. Mari kita buat satu di instance RDS:

[email protected]:~# mysql -ppassword -h rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com
mysql> CREATE USER IF NOT EXISTS 'rds_rpl'@'%' IDENTIFIED BY 'rds_rpl_pass';
Query OK, 0 rows affected (0.04 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'rds_rpl'@'%';
Query OK, 0 rows affected (0.01 sec)

Sekarang saatnya untuk menggunakan server MySQL/EC2 kita dari instance RDS:

mysql> CHANGE MASTER TO MASTER_HOST='rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com', MASTER_USER='rds_rpl', MASTER_PASSWORD='rds_rpl_pass', MASTER_LOG_FILE='mysql-bin-changelog.007079', MASTER_LOG_POS=10537102;
Query OK, 0 rows affected, 2 warnings (0.03 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.02 sec)
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com
                  Master_User: rds_rpl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-changelog.007080
          Read_Master_Log_Pos: 13842678
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 20448
        Relay_Master_Log_File: mysql-bin-changelog.007079
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 10557220
              Relay_Log_Space: 29071382
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 258726
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: 1237547456
                  Master_UUID: b5337d20-d815-11e6-abf1-120217bb3ac2
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: System lock
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.01 sec)

Langkah terakhir adalah mengalihkan lalu lintas kita dari instance RDS ke MySQL/EC2, tetapi kita harus membiarkannya mengejar terlebih dahulu.

Ketika budak telah menyusul, kita perlu melakukan pemotongan. Untuk mengotomatiskannya, kami memutuskan untuk menyiapkan skrip bash pendek yang akan terhubung ke ProxySQL dan melakukan apa yang perlu dilakukan.

# At first, we define old and new masters
OldMaster=rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com
NewMaster=172.30.4.238

(
# We remove entries from mysql_replication_hostgroup so ProxySQL logic won’t interfere
# with our script

echo "DELETE FROM mysql_replication_hostgroups;"

# Then we set current master to OFFLINE_SOFT - this will allow current transactions to
# complete while not accepting any more transactions - they will wait (by default for 
# 10 seconds) for a master to become available again.

echo "UPDATE mysql_servers SET STATUS='OFFLINE_SOFT' WHERE hostname=\"$OldMaster\";"
echo "LOAD MYSQL SERVERS TO RUNTIME;"
) | mysql -u admin -padmin -h 127.0.0.1 -P6032


# Here we are going to check for connections in the pool which are still used by 
# transactions which haven’t closed so far. If we see that neither hostgroup 10 nor
# hostgroup 20 has open transactions, we can perform a switchover.

CONNUSED=`mysql -h 127.0.0.1 -P6032 -uadmin -padmin -e 'SELECT IFNULL(SUM(ConnUsed),0) FROM stats_mysql_connection_pool WHERE status="OFFLINE_SOFT" AND (hostgroup=10 OR hostgroup=20)' -B -N 2> /dev/null`
TRIES=0
while [ $CONNUSED -ne 0 -a $TRIES -ne 20 ]
do
  CONNUSED=`mysql -h 127.0.0.1 -P6032 -uadmin -padmin -e 'SELECT IFNULL(SUM(ConnUsed),0) FROM stats_mysql_connection_pool WHERE status="OFFLINE_SOFT" AND (hostgroup=10 OR hostgroup=20)' -B -N 2> /dev/null`
  TRIES=$(($TRIES+1))
  if [ $CONNUSED -ne "0" ]; then
    sleep 0.05
  fi
done

# Here is our switchover logic - we basically exchange hostgroups for RDS and EC2
# instance. We also configure back mysql_replication_hostgroups table.

(
echo "UPDATE mysql_servers SET STATUS='ONLINE', hostgroup_id=110 WHERE hostname=\"$OldMaster\" AND hostgroup_id=10;"
echo "UPDATE mysql_servers SET STATUS='ONLINE', hostgroup_id=120 WHERE hostname=\"$OldMaster\" AND hostgroup_id=20;"
echo "UPDATE mysql_servers SET hostgroup_id=10 WHERE hostname=\"$NewMaster\" AND hostgroup_id=110;"
echo "UPDATE mysql_servers SET hostgroup_id=20 WHERE hostname=\"$NewMaster\" AND hostgroup_id=120;"
echo "INSERT INTO mysql_replication_hostgroups VALUES (10, 20, 'hostgroups');"
echo "LOAD MYSQL SERVERS TO RUNTIME;"
) | mysql -u admin -padmin -h 127.0.0.1 -P6032

Setelah semuanya selesai, Anda akan melihat konten berikut di tabel mysql_servers:

mysql> select * from mysql_servers;
+--------------+-----------------------------------------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname                                      | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+-----------------------------------------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 20           | 172.30.4.238                                  | 3306 | ONLINE | 1      | 0           | 100             | 10                  | 0       | 0              | read server |
| 10           | 172.30.4.238                                  | 3306 | ONLINE | 1      | 0           | 100             | 10                  | 0       | 0              | read server |
| 120          | rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com | 3306 | ONLINE | 1      | 0           | 100             | 10                  | 0       | 0              |             |
| 110          | rds2.cvsw8xpajw2b.us-east-1.rds.amazonaws.com | 3306 | ONLINE | 1      | 0           | 100             | 10                  | 0       | 0              |             |
+--------------+-----------------------------------------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+

Di sisi aplikasi, Anda seharusnya tidak melihat banyak dampak, berkat kemampuan ProxySQL untuk mengantre kueri selama beberapa waktu.

Dengan ini kami menyelesaikan proses pemindahan database Anda dari RDS ke EC2. Langkah terakhir yang harus dilakukan adalah menghapus slave RDS kami - ia melakukan tugasnya dan dapat dihapus.

Dalam posting blog kami berikutnya, kami akan membangunnya. Kami akan membahas skenario di mana kami akan memindahkan database kami dari AWS/EC2 ke penyedia hosting terpisah.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Mengakses PhpMyAdmin tanpa login cPanel

  2. MySQL memberikan semua hak istimewa ke database kecuali satu tabel

  3. MySQL, Gabungkan dua kolom

  4. Cara Membuat Database MySQL di cPanel

  5. Membuat dan Menggunakan Prosedur Tersimpan MySQL - Tutorial