Snapshot konsisten aplikasi secara sementara menangguhkan operasi penulisan database sebelum merekam status disk, memastikan data yang dipulihkan identik dengan kondisi pada saat pembuatan snapshot. Panduan ini menjelaskan langkah-langkah membuat snapshot konsisten aplikasi untuk instance ECS CentOS 7.9 yang menjalankan MySQL 8.0, lalu memverifikasi bahwa data yang dipulihkan sesuai dengan kondisi yang diharapkan.
Tingkat konsistensi snapshot
Tidak semua snapshot menjamin integritas data untuk database yang sedang berjalan. Memahami perbedaannya membantu Anda memilih pendekatan pencadangan yang tepat:
| Type | What it captures | Database safety |
|---|---|---|
| Crash-consistent | Status disk pada suatu titik waktu | Data di memori atau operasi I/O yang tertunda mungkin hilang |
| Application-consistent | Status disk setelah membuang data di memori dan menangguhkan penulisan | Data berada dalam kondisi bersih dan dapat dipulihkan — aplikasi dapat dimulai ulang tanpa error |
Untuk MySQL dan database transaksional lainnya, snapshot konsisten aplikasi adalah pilihan yang tepat.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Disk ECS berupa Enterprise SSDs (ESSDs) dengan fitur multi-attach dinonaktifkan
Instance ECS dalam status Running dengan Cloud Assistant dalam status Normal. Lihat Periksa status Cloud Assistant dan tangani anomali
MySQL terinstal pada instance, dengan username dan password MySQL tersedia. Lihat Instal MySQL pada instance Linux
Peran RAM yang dilampirkan ke instance ECS dengan kebijakan kustom yang memberikan izin untuk snapshot konsisten aplikasi. Lihat Buat peran RAM dan lampirkan ke instance ECS
Saat membuat snapshot konsisten aplikasi, Cloud Assistant menjalankan perintah pada instance Anda untuk mengeksekusi prescript dan postscript. Peran RAM memberikan izin yang diperlukan kepada Cloud Assistant.
Kebijakan kustom yang dilampirkan ke peran RAM harus mencakup izin berikut:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:DescribeSnapshot*",
"ecs:CreateSnapshot*",
"ecs:TagResources",
"ecs:DescribeDisks"
],
"Resource": [
"*"
],
"Condition": {}
}
]
}Cara kerja
Alur kerja terdiri dari lima langkah:
Buat prescript dan postscript — Prescript membersihkan tabel MySQL dan mengunci pembacaan global sebelum pembuatan snapshot. Postscript menghentikan proses yang memegang kunci untuk melanjutkan operasi penulisan setelah snapshot selesai.
Persiapkan lingkungan verifikasi — Buat tabel database dan prosedur tersimpan yang mensimulasikan penulisan berkelanjutan. Hal ini memberikan garis waktu data yang diketahui untuk diverifikasi setelah pemulihan.
Buat snapshot konsisten aplikasi — Di Konsol ECS, konfigurasikan pembuatan snapshot agar menjalankan skrip Anda dan menangguhkan sementara I/O sistem file.
Verifikasi pembuatan snapshot — Konfirmasi Cloud Assistant berhasil mengeksekusi skrip dan identifikasi waktu pasti ketika penulisan ditangguhkan dan dilanjutkan.
Verifikasi pemulihan data — Kembalikan disk Anda menggunakan snapshot, lalu kueri database untuk memastikan catatan terakhir yang ditulis mendahului jendela penangguhan.
Prosedur
Langkah 1: Buat prescript dan postscript
Skrip dalam panduan ini disediakan sebagai implementasi referensi. Sesuaikan skrip tersebut agar sesuai dengan kebutuhan aplikasi Anda. Untuk panduan umum, lihat Buat snapshot konsisten aplikasi.
Kedua skrip harus dimiliki oleh root dan memiliki izin chmod 700 (baca, tulis, dan eksekusi hanya untuk root). Jika izin tidak diatur dengan benar, skrip tidak akan dijalankan.
Buat /tmp/prescript.sh
Hubungkan ke instance ECS sebagai pengguna root. Lihat Hubungkan ke instance Linux.
Buat dan buka file prescript:
vim /tmp/prescript.shTekan
Iuntuk masuk ke mode Insert dan tempel skrip berikut. Ganti$MYSQL_USERdengan username MySQL Anda dan$MYSQL_PASSWORDdengan password MySQL Anda.Lihat isi prescript.sh
TIMESTAMP=`date +%s` MYSQL_TEMP_FILE_NAME="/tmp/mysqlfreeze${TIMESTAMP}.tmp" LOG_FILE_NAME="/tmp/mysqlfreeze${TIMESTAMP}.log" # Masukkan username MySQL Anda. export MYSQL_USER="$MYSQL_USER" # Masukkan password MySQL Anda. export MYSQL_PWD="$MYSQL_PASSWORD" function Log() { echo "$1" echo "$1" >> ${LOG_FILE_NAME} } function ExitWithResult() { Log "[INFO]:mysql freeze result is $1." exit $1 } function Main() { Log "*********************************************************************" Log "[INFO]:Begin to freeze mysql." which mysql if [ $? -ne 0 ] then Log "[INFO]:mysql is not installed." ExitWithResult 0 fi systemctl status mysqld.service | grep "inactive (dead)" if [ $? -ne 1 ] then Log "[ERROR]:mysql is not running." ExitWithResult 0 fi mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1 if [ $? -ne 0 ] then cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}" [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:Show process list failed." ExitWithResult 1 fi process_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'` if [ "$process_id" != "" ] then cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}" [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:MySQL already been freezed " ExitWithResult 1 fi cat ${MYSQL_TEMP_FILE_NAME} Log "[INFO]:Try to execute flush tables command" echo "flush tables with read lock;select 1 and sleep(25);" | nohup mysql -u$MYSQL_USER >> "${LOG_FILE_NAME}" 2>&1 & if [ $? -ne 0 ] then Log "[ERROR]:Freeze mysql failed." ExitWithResult 1 fi Log "[INFO]:Flush tables command execute success" checkTime=0 while [ 1 ] do mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1 if [ $? -ne 0 ] then cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}" [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:Show process list failed." ExitWithResult 1 fi cat ${MYSQL_TEMP_FILE_NAME} process_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'` if [ "$process_id" = "" ] then checkTime=`expr $checkTime + 1` Log "[INFO]:Mysql is not freeze. checkTime is ${checkTime}" sleep 1 else Log "[INFO]:Found sleep command in processlist,freeze success" break fi if [ $checkTime -eq 10 ] then cat "${MYSQL_TEMP_FILE_NAME}" >>"${LOG_FILE_NAME}" 2>&1 freeze_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "flush tables with read lock" | awk -F " " '{print $1}'` mysql -u$MYSQL_USER -e "kill $freeze_id;" >> "${LOG_FILE_NAME}" 2>&1 if [ $? -ne 0 ] then Log "[ERROR]:Thaw mysql failed." fi [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:Mysql is not freeze. Will return error" ExitWithResult 1 fi done [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[INFO]:Finish freeze mysql." ExitWithResult 0 } MainParameter yang perlu diperbarui:
Parameter Description $MYSQL_USERUsername MySQL Anda $MYSQL_PASSWORDPassword MySQL Anda Tekan
Esc, ketik:wq, lalu tekan Enter untuk menyimpan file.Atur izin agar hanya root yang dapat membaca, menulis, dan mengeksekusi file:
Pentingchmod 700wajib digunakan. Izin yang lebih luas menyebabkan pemeriksaan izin gagal dan skrip tidak akan dijalankan.chmod 700 /tmp/prescript.sh
Buat /tmp/postscript.sh
Buat dan buka file postscript:
vim /tmp/postscript.shTekan
Iuntuk masuk ke mode Insert dan tempel skrip berikut. Ganti$MYSQL_USERdengan username MySQL Anda dan$MYSQL_PASSWORDdengan password MySQL Anda.Lihat isi postscript.sh
TIMESTAMP=`date +%s` MYSQL_TEMP_FILE_NAME="/tmp/mysqlthaw${TIMESTAMP}.tmp" LOG_FILE_NAME="/tmp/mysqlthaw${TIMESTAMP}.log" # Masukkan username MySQL Anda. export MYSQL_USER="$MYSQL_USER" # Masukkan password MySQL Anda. export MYSQL_PWD="$MYSQL_PASSWORD" function Log() { echo "$1" echo "$1" >> ${LOG_FILE_NAME} } function ExitWithResult() { Log "[INFO]:mysql unfreeze result is $1." exit $1 } function Main() { Log "*********************************************************************" Log "[INFO]:Begin to thaw mysql." which mysql if [ $? -ne 0 ] then Log "[INFO]:mysql is not installed." ExitWithResult 0 fi systemctl status mysqld.service | grep "inactive (dead)" if [ $? -ne 1 ] then Log "[ERROR]:mysql is not running." ExitWithResult 0 fi mysql -u$MYSQL_USER -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1 if [ $? -ne 0 ] then cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}" [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:show process list failed." ExitWithResult 1 fi Log "[INFO]:show process list success." cat ${MYSQL_TEMP_FILE_NAME} process_ids=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'` if [ "$process_ids" = "" ] then [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:Get freeze process_id failed." ExitWithResult 1 fi cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'| while read pid do Log "[INFO]:Try to stop sql process ${pid}." mysql -u$MYSQL_USER -e "kill $pid;" >> "${LOG_FILE_NAME}" 2>&1 if [ $? -ne 0 ] then [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[ERROR]:Thaw mysql failed.PIDs is ${process_ids}" ExitWithResult 1 fi Log "[INFO]:Stop sql process ${pid} success." done [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME} Log "[INFO]:Finish thaw mysql." ExitWithResult 0 } MainParameter yang perlu diperbarui:
Parameter Description $MYSQL_USERUsername MySQL Anda $MYSQL_PASSWORDPassword MySQL Anda Tekan
Esc, ketik:wq, lalu tekan Enter untuk menyimpan file.Atur izin:
chmod 700 /tmp/postscript.sh
Verifikasi izin skrip
Buka direktori /tmp dan pastikan kedua file memiliki izin 700:
cd /tmp
ls -lOutput yang muncul seharusnya mirip seperti berikut:

Langkah 2: Persiapkan lingkungan verifikasi database
Langkah ini membuat tabel dan prosedur tersimpan yang memasukkan satu catatan per detik selama 3 menit. Menjalankan prosedur ini sebelum membuat snapshot memberikan garis waktu referensi untuk diverifikasi setelah rollback.
Buat snapshot konsisten aplikasi saat prosedur tersimpan TestPIT sedang berjalan. Prosedur ini berjalan selama 3 menit — Anda harus menyelesaikan Langkah 3 dalam rentang waktu tersebut.
Buat skrip uji di
/root/test.sql:vim /root/test.sqlTekan
I, tempel konten berikut, lalu tekanEscdan ketik:wquntuk menyimpan:USE AdventureWorks; CREATE TABLE PointInTime(id int, t datetime); DELIMITER $$ CREATE PROCEDURE `TestPIT`() BEGIN DECLARE i int; SET i=1; WHILE i < 180 DO INSERT INTO PointInTime VALUES(i, now()); SELECT SLEEP(1); SET i=i+1; END WHILE; END $$ DELIMITER ;Login ke MySQL:
mysql -u <mysqlUserName> -pGanti
<mysqlUserName>dengan username MySQL Anda, lalu masukkan password Anda saat diminta.Buat database
AdventureWorks:CREATE DATABASE AdventureWorks;Jalankan skrip uji:
source /root/test.sqlPanggil prosedur tersimpan untuk mulai menulis catatan:
CALL TestPIT;Dengan
TestPITsedang berjalan, segera lanjutkan ke Langkah 3.
Langkah 3: Buat snapshot konsisten aplikasi
Buka Konsol ECS - Snapshot-consistent Groups.
Di bilah navigasi atas, pilih wilayah dan kelompok sumber daya untuk instance Anda.

Pada tab Snapshot-consistent Groups, klik Create Snapshot-consistent Group.
Pada kotak dialog Create Snapshot:
Biarkan Resource Type tetap sebagai Instance.
Pilih instance Anda dari daftar drop-down Select Instances. Pada bagian Select Cloud Disks, pilih ESSD yang ingin disertakan dalam snapshot.
Bentangkan Advanced Settings.
Pilih Enable Application-consistent Snapshot.
Atur path prescript dan postscript agar sesuai dengan file yang Anda buat di Langkah 1:
/tmp/prescript.shdan/tmp/postscript.sh.Pilih Enable untuk fitur File System I/O Suspension and Resume dan atur periode timeout.
Klik OK.
Setelah grup snapshot-konsisten dibuat, pesan konfirmasi akan menampilkan ID perintah dan ID tugas Cloud Assistant. Gunakan ID tugas tersebut pada langkah berikutnya untuk memverifikasi hasilnya.
Langkah 4: Verifikasi pembuatan snapshot
Di halaman Cloud Assistant ECS, klik ID tugas untuk melihat hasil eksekusi perintah. Jika skrip berhasil dijalankan, ExitCode bernilai
0dan output mencantumkan ID snapshot serta ID grup snapshot-konsisten. Jika ExitCode bukan0, gunakan tabel berikut untuk pemecahan masalah: Untuk referensi lengkap kode kesalahan, lihat Kode kesalahan.ExitCode Likely cause Action 1(prescript)MySQL sudah dibekukan, koneksi gagal, atau pembekuan timeout setelah 10 percobaan Periksa log prescript di /tmp/mysqlfreeze<timestamp>.loguntuk baris[ERROR]spesifik1(postscript)Tidak ditemukan proses pembekuan, atau perintah kill gagal Periksa log postscript di /tmp/mysqlthaw<timestamp>.log. Verifikasi secara manual apakah MySQL sedang berjalan dengansystemctl status mysqld.servicePermission error Izin skrip bukan 700, atau skrip tidak dimiliki oleh rootJalankan ulang chmod 700dan verifikasi kepemilikan denganls -l /tmp/prescript.sh
Dalam output Cloud Assistant, identifikasi kapan penulisan ditangguhkan dan dilanjutkan:
Prescript dimulai pada
2024-08-27 15:27:55— penulisan ditangguhkan pada waktu ini.
Postscript selesai pada
2024-08-27 15:27:57— penulisan dilanjutkan pada waktu ini.
Konfirmasi snapshot diberi tag sebagai konsisten aplikasi: Buka Konsol ECS - Snapshot-consistent Groups. Pada tab Snapshot-consistent Groups, klik ID grup snapshot-konsisten. Di bagian Snapshot Information, periksa kolom Tag untuk setiap snapshot. Snapshot yang diberi tag
APPConsistent:Truemerupakan snapshot konsisten aplikasi.
Hubungkan ke MySQL dan konfirmasi tidak ada penyisipan yang terjadi selama jendela penangguhan:
Hubungkan ke instance ECS. Lihat Hubungkan ke instance Linux.
Login ke MySQL:
mysql -u <mysqlUserName> -pKueri tabel
PointInTime:USE AdventureWorks; SELECT * FROM PointInTime;Dalam hasilnya, verifikasi tidak ada catatan antara
2024-08-27 15:27:55dan2024-08-27 15:27:58. Celah ini mengonfirmasi database ditangguhkan selama pembuatan snapshot.
Langkah 5: Verifikasi pemulihan data
Kembalikan disk menggunakan grup snapshot-konsisten. Lihat Kembalikan disk menggunakan grup snapshot-konsisten.
Hubungkan ke instance ECS. Lihat Hubungkan ke instance Linux.
Login ke MySQL:
mysql -u <mysqlUserName> -pKueri tabel
PointInTime:USE AdventureWorks; SELECT * FROM PointInTime;Periksa timestamp catatan terakhir. Interpretasikan hasilnya: Dalam contoh output, catatan terakhir berada pada
2024-08-27 15:27:54, yang lebih awal daripada waktu mulai prescript yaitu2024-08-27 15:27:55. Snapshot konsisten aplikasi berhasil membackup data MySQL.Last record timestamp Meaning Lebih awal dari 2024-08-27 15:27:55(waktu mulai prescript)Tidak ada penulisan yang terjadi selama penangguhan. Snapshot berhasil menangkap kondisi database — pemulihan berhasil. Sama dengan atau lebih baru dari 2024-08-27 15:27:55Penulisan terjadi selama jendela penangguhan. Data snapshot tidak konsisten dengan titik pembekuan yang diharapkan. 