MariaDB
 sql >> Teknologi Basis Data >  >> RDS >> MariaDB

Menggunakan Flashback MariaDB di Server MySQL

MariaDB telah memperkenalkan fitur yang sangat keren bernama Flashback. Flashback adalah fitur yang memungkinkan instance, database, atau tabel dikembalikan ke snapshot lama. Secara tradisional, untuk melakukan pemulihan point-in-time (PITR), seseorang akan memulihkan database dari cadangan, dan memutar ulang log biner untuk menggulung ke depan status database pada waktu atau posisi tertentu.

Dengan Flashback, database dapat diputar kembali ke titik waktu di masa lalu, yang jauh lebih cepat jika kita hanya ingin melihat masa lalu yang baru saja terjadi belum lama ini. Terkadang, menggunakan kilas balik mungkin tidak efisien jika Anda ingin melihat cuplikan data yang sangat lama terkait dengan tanggal dan waktu saat ini. Memulihkan dari slave yang tertunda, atau dari cadangan plus memutar ulang log biner mungkin merupakan opsi yang lebih baik.

Fitur ini hanya tersedia dalam paket klien MariaDB, tetapi bukan berarti kami tidak dapat menggunakannya dengan server MySQL kami. Postingan blog ini menunjukkan bagaimana kami dapat menggunakan fitur luar biasa ini di server MySQL.

Persyaratan Flashback MariaDB

Bagi yang ingin menggunakan fitur flashback MariaDB di atas MySQL, pada dasarnya kita dapat melakukan hal berikut:

  1. Aktifkan log biner dengan setelan berikut:
    1. binlog_format =ROW (default sejak MySQL 5.7.7).
    2. binlog_row_image =FULL (default sejak MySQL 5.6).
  2. Gunakan utilitas msqlbinlog dari instalasi MariaDB 10.2.4 dan yang lebih baru.
  3. Flashback saat ini hanya didukung melalui pernyataan DML (INSERT, DELETE, UPDATE). Versi MariaDB yang akan datang akan menambahkan dukungan untuk kilas balik melalui pernyataan DDL (DROP, TRUNCATE, ALTER, dll.) dengan menyalin atau memindahkan tabel saat ini ke database yang dicadangkan dan disembunyikan, lalu menyalin atau memindahkan kembali saat menggunakan kilas balik.

Kilas balik dicapai dengan memanfaatkan dukungan yang ada untuk log biner format gambar penuh, sehingga mendukung semua mesin penyimpanan. Perhatikan bahwa peristiwa kilas balik akan disimpan dalam memori. Oleh karena itu, Anda harus memastikan server Anda memiliki cukup memori untuk fitur ini.

Bagaimana Cara Kerja Flashback MariaDB?

Utilitas mysqlbinlog MariaDB hadir dengan dua opsi tambahan untuk tujuan ini:

  • -B, --flashback - Fitur Flashback dapat mengembalikan data komitmen Anda ke titik waktu khusus.
  • -T, --table=[name] - Daftar entri hanya untuk tabel ini (log lokal saja).

Dengan membandingkan output mysqlbinlog dengan dan tanpa flag --flashback, kita dapat dengan mudah memahami cara kerjanya. Pertimbangkan pernyataan berikut dijalankan pada server MariaDB:

MariaDB> DELETE FROM sbtest.sbtest1 WHERE id = 1;

Tanpa flag flashback, kita akan melihat event DELETE binlog yang sebenarnya:

$ mysqlbinlog -vv \
--start-datetime="$(date '+%F %T' -d 'now - 10 minutes')" \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000003

...
# at 453196541
#200227 12:58:18 server id 37001  end_log_pos 453196766 CRC32 0xdaa248ed Delete_rows: table id 238 flags: STMT_END_F

BINLOG '
6rxXXhOJkAAAQwAAAP06AxsAAO4AAAAAAAEABnNidGVzdAAHc2J0ZXN0MQAEAwP+/gTu4P7wAAEB
AAID/P8AFuAQfA==
6rxXXiCJkAAA4QAAAN47AxsAAO4AAAAAAAEAAgAE/wABAAAAVJ4HAHcAODM4Njg2NDE5MTItMjg3
NzM5NzI4MzctNjA3MzYxMjA0ODYtNzUxNjI2NTk5MDYtMjc1NjM1MjY0OTQtMjAzODE4ODc0MDQt
NDE1NzY0MjIyNDEtOTM0MjY3OTM5NjQtNTY0MDUwNjUxMDItMzM1MTg0MzIzMzA7Njc4NDc5Njcz
NzctNDgwMDA5NjMzMjItNjI2MDQ3ODUzMDEtOTE0MTU0OTE4OTgtOTY5MjY1MjAyOTHtSKLa
'/*!*/;

### DELETE FROM `sbtest`.`sbtest1`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2=499284 /* INT meta=0 nullable=0 is_null=0 */
###   @3='83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='67847967377-48000963322-62604785301-91415491898-96926520291' /* STRING(240) meta=65264 nullable=0 is_null=0 */
...

Dengan memperluas perintah mysqlbinlog di atas dengan --flashback, kita dapat melihat acara DELETE diubah menjadi acara INSERT dan mirip dengan masing-masing klausa WHERE dan SET:

$ mysqlbinlog -vv \
--start-datetime="$(date '+%F %T' -d 'now - 10 minutes')" \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000003 \
--flashback

...
BINLOG '
6rxXXhOJkAAAQwAAAP06AxsAAO4AAAAAAAEABnNidGVzdAAHc2J0ZXN0MQAEAwP+/gTu4P7wAAEB
AAID/P8AFuAQfA==
6rxXXh6JkAAA4QAAAN47AxsAAO4AAAAAAAEAAgAE/wABAAAAVJ4HAHcAODM4Njg2NDE5MTItMjg3
NzM5NzI4MzctNjA3MzYxMjA0ODYtNzUxNjI2NTk5MDYtMjc1NjM1MjY0OTQtMjAzODE4ODc0MDQt
NDE1NzY0MjIyNDEtOTM0MjY3OTM5NjQtNTY0MDUwNjUxMDItMzM1MTg0MzIzMzA7Njc4NDc5Njcz
NzctNDgwMDA5NjMzMjItNjI2MDQ3ODUzMDEtOTE0MTU0OTE4OTgtOTY5MjY1MjAyOTHtSKLa
'/*!*/;

### INSERT INTO `sbtest`.`sbtest1`
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2=499284 /* INT meta=0 nullable=0 is_null=0 */
###   @3='83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='67847967377-48000963322-62604785301-91415491898-96926520291' /* STRING(240) meta=65264 nullable=0 is_null=0 */
...

Dalam replikasi berbasis baris (binlog_format=ROW), setiap peristiwa perubahan baris berisi dua gambar, gambar "sebelum" (kecuali INSERT) yang kolomnya dicocokkan saat mencari baris yang akan diperbarui, dan gambar "setelah" (kecuali DELETE) yang berisi perubahan. Dengan binlog_row_image=FULL, MariaDB mencatat baris penuh (yaitu, semua kolom) untuk gambar sebelum dan sesudah.

Contoh berikut menunjukkan peristiwa log biner untuk UPDATE. Pertimbangkan pernyataan berikut dijalankan pada server MariaDB:

MariaDB> UPDATE sbtest.sbtest1 SET k = 0 WHERE id = 5;

Saat melihat event binlog untuk pernyataan di atas, kita akan melihat sesuatu seperti ini:

$ mysqlbinlog -vv \
--start-datetime="$(date '+%F %T' -d 'now - 5 minutes')" \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000001 

...
### UPDATE `sbtest`.`sbtest1`
### WHERE
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=499813 /* INT meta=0 nullable=0 is_null=0 */
###   @3='44257470806-17967007152-32809666989-26174672567-29883439075-95767161284-94957565003-35708767253-53935174705-16168070783' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='34551750492-67990399350-81179284955-79299808058-21257255869' /* STRING(240) meta=65264 nullable=0 is_null=0 */
### SET
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=0 /* INT meta=0 nullable=0 is_null=0 */
###   @3='44257470806-17967007152-32809666989-26174672567-29883439075-95767161284-94957565003-35708767253-53935174705-16168070783' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='34551750492-67990399350-81179284955-79299808058-21257255869' /* STRING(240) meta=65264 nullable=0 is_null=0 */
# Number of rows: 1
...

Dengan flag --flashback, gambar "sebelum" ditukar dengan gambar "setelah" dari baris yang ada:

$ mysqlbinlog -vv \
--start-datetime="$(date '+%F %T' -d 'now - 5 minutes')" \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000001 \
 --flashback

...
### UPDATE `sbtest`.`sbtest1`
### WHERE
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=0 /* INT meta=0 nullable=0 is_null=0 */
###   @3='44257470806-17967007152-32809666989-26174672567-29883439075-95767161284-94957565003-35708767253-53935174705-16168070783' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='34551750492-67990399350-81179284955-79299808058-21257255869' /* STRING(240) meta=65264 nullable=0 is_null=0 */
### SET
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=499813 /* INT meta=0 nullable=0 is_null=0 */
###   @3='44257470806-17967007152-32809666989-26174672567-29883439075-95767161284-94957565003-35708767253-53935174705-16168070783' /* STRING(480) meta=61152 nullable=0 is_null=0 */
###   @4='34551750492-67990399350-81179284955-79299808058-21257255869' /* STRING(240) meta=65264 nullable=0 is_null=0 */
...

Kemudian kita dapat mengarahkan output flashback ke klien MySQL, sehingga mengembalikan database atau tabel ke titik waktu yang kita inginkan. Contoh lainnya akan ditampilkan di bagian selanjutnya.

MariaDB memiliki halaman basis pengetahuan khusus untuk fitur ini. Lihat halaman basis pengetahuan Flashback MariaDB.

Flashback MariaDB Dengan MySQL

Untuk memiliki kemampuan flashback untuk MySQL, seseorang harus melakukan hal berikut:

  • Salin utilitas mysqlbinlog dari server MariaDB mana pun (10.2.4 atau lebih baru).
  • Nonaktifkan MySQL GTID sebelum menerapkan file SQL flashback. Variabel global gtid_mode dan force_gtid_consistency dapat disetel saat runtime sejak MySQL 5.7.5.

Misalkan kita memiliki topologi replikasi MySQL 8.0 sederhana berikut:

Dalam contoh ini, kami menyalin utilitas mysqlbinlog dari MariaDB 10.4 terbaru di salah satu budak MySQL 8.0 kami (slave2):

(mariadb-server)$ scp /bin/mysqlbinlog [email protected]:/root/
(slave2-mysql8)$ ls -l /root/mysqlbinlog
-rwxr-xr-x. 1 root root 4259504 Feb 27 13:44 /root/mysqlbinlog

Utilitas mysqlbinlog MariaDB kami sekarang terletak di /root/mysqlbinlog di slave2. Pada master MySQL, kami mengeksekusi pernyataan bencana berikut:

mysql> DELETE FROM sbtest1 WHERE id BETWEEN 5 AND 100;
Query OK, 96 rows affected (0.01 sec)

96 baris dihapus dalam pernyataan di atas. Tunggu beberapa detik untuk membiarkan peristiwa mereplikasi dari master ke semua budak sebelum kita dapat mencoba menemukan posisi binlog dari peristiwa bencana di server budak. Langkah pertama adalah mengambil semua log biner di server itu:

mysql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       850 |        No |
| binlog.000002 |     18796 |        No |
+---------------+-----------+-----------+

Peristiwa bencana kami harus ada di dalam binlog.000002, log biner terbaru di server ini. Kami kemudian dapat menggunakan utilitas mysqlbinlog MariaDB untuk mengambil semua peristiwa binlog untuk tabel sbtest1 sejak 10 menit yang lalu:

(slave2-mysql8)$ /root/mysqlbinlog -vv \
--start-datetime="$(date '+%F %T' -d 'now - 10 minutes')" \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000002

...
# at 195
#200228 15:09:45 server id 37001  end_log_pos 281 CRC32 0x99547474 Ignorable
# Ignorable event type 33 (MySQL Gtid)
# at 281
#200228 15:09:45 server id 37001  end_log_pos 353 CRC32 0x8b12bd3c Query thread_id=19 exec_time=0 error_code=0
SET TIMESTAMP=1582902585/*!*/;
SET @@session.pseudo_thread_id=19/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=524288/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;

BEGIN
/*!*/;
# at 353
#200228 15:09:45 server id 37001  end_log_pos 420 CRC32 0xe0e44a1b Table_map: `sbtest`.`sbtest1` mapped to number 92

# at 420
# at 8625
# at 16830
#200228 15:09:45 server id 37001  end_log_pos 8625 CRC32 0x99b1a8fc Delete_rows: table id 92
#200228 15:09:45 server id 37001  end_log_pos 16830 CRC32 0x89496a07 Delete_rows: table id 92
#200228 15:09:45 server id 37001  end_log_pos 18765 CRC32 0x302413b2 Delete_rows: table id 92 flags: STMT_END_F

Untuk mencari nomor posisi binlog dengan mudah, perhatikan baris yang dimulai dengan "# at ". Dari baris di atas, kita dapat melihat event DELETE sedang terjadi pada posisi 281 di dalam binlog.000002 (dimulai dari "# at 281"). Kami juga dapat mengambil peristiwa binlog langsung di dalam server MySQL:

mysql> SHOW BINLOG EVENTS IN 'binlog.000002';
+---------------+-------+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name      | Pos   | Event_type     | Server_id | End_log_pos | Info                                                              |
+---------------+-------+----------------+-----------+-------------+-------------------------------------------------------------------+
| binlog.000002 |     4 | Format_desc    |     37003 | 124         | Server ver: 8.0.19, Binlog ver: 4                                 |
| binlog.000002 |   124 | Previous_gtids |     37003 | 195         | 0d98d975-59f8-11ea-bd30-525400261060:1                            |
| binlog.000002 |   195 | Gtid           |     37001 | 281         | SET @@SESSION.GTID_NEXT= '0d98d975-59f8-11ea-bd30-525400261060:2' |
| binlog.000002 |   281 | Query          |     37001 | 353         | BEGIN                                                             |
| binlog.000002 |   353 | Table_map      |     37001 | 420         | table_id: 92 (sbtest.sbtest1)                                     |
| binlog.000002 |   420 | Delete_rows    |     37001 | 8625        | table_id: 92                                                      |
| binlog.000002 |  8625 | Delete_rows    |     37001 | 16830       | table_id: 92                                                      |
| binlog.000002 | 16830 | Delete_rows    |     37001 | 18765       | table_id: 92 flags: STMT_END_F                                    |
| binlog.000002 | 18765 | Xid            |     37001 | 18796       | COMMIT /* xid=171006 */                                           |
+---------------+-------+----------------+-----------+-------------+-------------------------------------------------------------------+

9 rows in set (0.00 sec)

Sekarang kami dapat mengonfirmasi bahwa posisi 281 adalah tempat yang kami inginkan untuk mengembalikan data. Kami kemudian dapat menggunakan flag --start-position untuk menghasilkan peristiwa kilas balik yang akurat. Perhatikan bahwa kita menghilangkan tanda "-vv" dan tambahkan --flashback flag:

(slave2-mysql8)$ /root/mysqlbinlog \
--start-position=281 \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000002 \
--flashback > /root/flashback.binlog

Flashback.binlog berisi semua peristiwa yang diperlukan untuk membatalkan semua perubahan yang terjadi pada tabel sbtest1 di server MySQL ini. Karena ini adalah node slave dari cluster replikasi, kita harus memutus replikasi pada slave yang dipilih (slave2) agar dapat digunakan untuk tujuan flashback. Untuk melakukan ini, kita harus menghentikan replikasi pada slave yang dipilih, setel MySQL GTID ke ON_PERMISSIVE dan buat slave dapat ditulis:

mysql> STOP SLAVE; 
SET GLOBAL gtid_mode = ON_PERMISSIVE; 
SET GLOBAL enforce_gtid_consistency = OFF; 
SET GLOBAL read_only = OFF;

Pada titik ini, slave2 bukan bagian dari replikasi dan topologi kita terlihat seperti ini:

Impor flashback melalui klien mysql dan kami tidak ingin perubahan ini terjadi direkam dalam log biner MySQL:

(slave2-mysql8)$ mysql -uroot -p --init-command='SET sql_log_bin=0' sbtest < /root/flashback.binlog

Kami kemudian dapat melihat semua baris yang dihapus, sebagaimana dibuktikan oleh pernyataan berikut:

mysql> SELECT COUNT(id) FROM sbtest1 WHERE id BETWEEN 5 and 100;
+-----------+
| COUNT(id) |
+-----------+
|        96 |
+-----------+
1 row in set (0.00 sec)

Kami kemudian dapat membuat file dump SQL untuk tabel sbtest1 untuk referensi kami:

(slave2-mysql8)$ mysqldump -uroot -p --single-transaction sbtest sbtest1 > sbtest1_flashbacked.sql

Setelah operasi kilas balik selesai, kita dapat bergabung kembali dengan node slave kembali ke dalam rantai replikasi. Tetapi pertama-tama, kita harus mengembalikan database ke kondisi yang konsisten, dengan memutar ulang semua peristiwa mulai dari posisi yang telah kita flashback. Jangan lupa untuk melewatkan pencatatan biner karena kita tidak ingin "menulis" ke slave dan mempertaruhkan diri kita dengan transaksi yang salah:

(slave2-mysql8)$ /root/mysqlbinlog \
--start-position=281 \
--database=sbtest \
--table=sbtest1 \
/var/lib/mysql/binlog.000002 | mysql -uroot -p --init-command='SET sql_log_bin=0' sbtest

Terakhir, siapkan node kembali ke perannya sebagai budak MySQL dan mulai replikasi:

mysql> SET GLOBAL read_only = ON;
SET GLOBAL enforce_gtid_consistency = ON; 
SET GLOBAL gtid_mode = ON; 
START SLAVE; 

Verifikasi bahwa node slave mereplikasi dengan benar:

mysql> SHOW SLAVE STATUS\G
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Pada titik ini, kami telah bergabung kembali dengan budak kembali ke rantai replikasi dan topologi kami sekarang kembali ke keadaan semula:

Berteriak kepada tim MariaDB karena memperkenalkan fitur menakjubkan ini!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana SECOND() Bekerja di MariaDB

  2. Bagaimana LOAD_FILE() Bekerja di MariaDB

  3. Apa itu MariaDB Enterprise dan Bagaimana Cara Mengelolanya dengan ClusterControl?

  4. 3 Cara Mendapatkan Kolasi Kolom di MariaDB

  5. Cara Menyebarkan Database Chamilo MariaDB untuk Ketersediaan Tinggi