Prosty i szybki backup bazy dzięki Percona XtraBackup
Kamil Porembiński
Kamil Porembiński
26.04.2017

Prosty i szybki backup bazy dzięki Percona XtraBackup

Wykonanie backupu małej bazy danych nie jest problemem. Kilkusekundowy przestój aplikacji czy strony w godzinach nocnych, nie stanowi dla nas większego kłopotu. Trudność pojawia się, kiedy do zarchiwizowania mamy naprawdę spore ilości rekordów. Przykładem takim może być baza danych MySQL 5.5, która zawiera około 83 973 092 rekordów, zajmujących blisko 8,2 GB. Jak wykonać szybko kopię zapasową takiej bazy, aby nie odczuli tego użytkownicy? Na szczęście jest na to rozwiązanie!

Najprostszą metodą może być wykorzystanie mechanizmu replikacji bazy MySQL. Konfigurujemy drugą bazę slave, z której to wykonujemy kopię zapasową. Na czas backupu możemy taki serwer zatrzymać, skopiować pliki lub wykonać zrzut za pomocą polecenia mysqldump. Podczas archiwizacji obciążamy jedynie klona głównej maszyny.

A co zrobić, jeżeli nie stać nas na zakup drugiego serwera, która posłuży nam jako baza zapasowa? Odpowiedzią na to pytanie jest aplikacja Percona XtraBackup, która wydawana jest na licencji GPLv2. Pozwala ona na wykonanie kopii zapasowej bazy danych, bez jej przestoju. Wspierane są serwery bazodanowe, takie jak: Percona Server, MySQL, MariaDB, oraz Drizzle. Oprogramowanie to pozwala na takie operacje jak:

  • szybkie wykonywanie kopii zapasowej
  • nieprzerywanie transakcji podczas wykonywania backup
  • automatyczną weryfikację zarchiwizowanych danych
  • szybszy czas odzyskiwania danych
  • wykonywanie przyrostowych backupów
  • prostsze tworzenie replikacji
  • wykonywanie kopii zapasowej bez obciążania serwera
  • przenoszenie tabel w czasie rzeczywistym pomiędzy serwerami
  • backupuje tylko dane składowane w InnoDB

Z oprogramowania Percona XtraBackup, korzystają duże portale społecznościowe jak na przykład Facebook:

„Facebook users create a vast amount of data every day. To make sure that data is stored reliably, we back up our databases daily. Facebook was an early adopter of incremental backup in XtraBackup.” – Vamsi Ponnekanti, Facebook Engineering

Instalacja Percona XtraBackup

Instalacja oprogramowania jest bardzo prosta, dzięki przygotowanym binarnym paczkom dostępnych dla systemów takich jak: Red Hat, CentOS, Debian i Ubuntu. Dostępne są również repozytoria dla aplikacji Yum oraz Apt.

Instalację rozpoczynamy od dodania do systemu, repozytorium z aplikacją. Do pliku /etc/yum.repos.d/percona.repo dodajemy wpis:

[percona]
name = CentOS $releasever - Percona
baseurl=http://repo.percona.com/centos/$releasever/os/$basearch/
enabled = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-percona
gpgcheck = 1

Musimy jeszcze skopiować klucz GPG i zapisać go do /etc/pki/rpm-gpg/RPM-GPG-KEY-percona. Od tego momentu możemy zacząć instalować oprogramowanie wydając polecenie:

yum install xtrabackup

Całe oprogramowanie składa się z tak naprawdę trzech aplikacji:

  • xtrabackup – oprogramowanie napisane w języku C, które kopiuje dane InnoDB i XtraDB
  • innobackupex – skrypt, który uzupełnia braki poprzedniego programu. Kopiuje całą zawartość serwera MySQL
  • tar4ibd – pakuje do formatu tar dane InnoDB

Zostaną zainstalowane trzy podobne polecenia, które służą do wykonywania kopii zapasowych z odpowiednich wersji serwerów bazodanowych:

  • xtrabackup – Percona Server 5.1 & MySQL 5.1 w/InnoDB plugin
  • xtrabackup_51 – Percona Server 5.0, MySQL 5.0 & MySQL 5.1
  • xtrabackup_55 – Percona Server 5.5 & MySQL 5.5

Czas na wykonanie pierwszego backupu za pomocą xtrabackup.

Wykonywanie kopii zapasowej

Najszybszą metodą zrobienia kopii zapasowej jest wydanie polecenia xtrabackup z parametrem --backup. W naszym wypadku jest to serwer w wersji 5.5 zatem użyjemy polecenia:

xtrabackup_55 --backup --datadir=/var/lib/mysql/ --target-dir=/backup

Dodatkowo należy określić katalog docelowy (--target_dir) w jakim ma zostać zapisana kopia zapasowa, oraz katalog w jakim znajdują się dane serwera MySQL (--datadir). Opcje te mogą zosać zapisane w pliku /etc/my.cnf, aby nie podawać ich ciągle jako parametr:

[mysqld]
datadir=/var/lib/mysql/
[xtrabackup]
target_dir=/backup

Natomiast jeżeli pojawi się nam błąd:

xtrabackup_55: ambiguous option '--innodb=FORCE' (innodb_adaptive_hash_index, innodb_doublewrite_file)

oznacza to, ze w pliku /etc/my.cnf, mamy ustawioną opcję innodb=force. Obejściem problemu jest zamiana jej na loose-innodb=force. Błąd ten powinien zostać rozwiązany w kolejnych wersjach aplikacji. Jeżeli wszystko poszło poprawnie zobaczymy wynik polecenia:

xtrabackup_55 version 1.6.2 for Percona Server 5.5.9 Linux (x86_64) (revision id: 274)
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /var/lib/mysql/
xtrabackup: Target instance is assumed as followings.
xtrabackup:   innodb_data_home_dir = ./
xtrabackup:   innodb_data_file_path = ibdata1:10M:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 2
xtrabackup:   innodb_log_file_size = 5242880
110812 11:11:41 InnoDB: Using Linux native AIO
>> log scanned up to (274992220655)
[01] Copying ./ibdata1 
     to /backup/ibdata1
>> log scanned up to (274992326877)
>> log scanned up to (274992483657)
>> log scanned up to (274992585754)
>> log scanned up to (274992665719)
>> log scanned up to (274992759458)
>> log scanned up to (274992852501)
>> log scanned up to (274992865265)
>> log scanned up to (274993036879)
>> log scanned up to (274993127087)
>> log scanned up to (274993241361)
>> log scanned up to (274993291339)
>> log scanned up to (274993427789)
>> log scanned up to (274993587569)
>> log scanned up to (274993678820)
>> log scanned up to (274993789123)
>> log scanned up to (274993835340)
>> log scanned up to (274994021991)
>> log scanned up to (274994033880)
>> log scanned up to (274994268323)
>> log scanned up to (274994376271)
>> log scanned up to (274994462281)
>> log scanned up to (274994529600)
>> log scanned up to (274994645157)
>> log scanned up to (274994727307)
>> log scanned up to (274994796009)
>> log scanned up to (274994898785)
>> log scanned up to (274994973583)
>> log scanned up to (274995041628)
>> log scanned up to (274995159543)
>> log scanned up to (274995244693)
>> log scanned up to (274995341883)
>> log scanned up to (274995439890)
>> log scanned up to (274995517633)
>> log scanned up to (274995608306)
>> log scanned up to (274995730882)
>> log scanned up to (274995798412)
>> log scanned up to (274995877561)
>> log scanned up to (274995983804)
>> log scanned up to (274996075140)
[01]        ...done
>> log scanned up to (274996152436)
xtrabackup: The latest check point (for incremental): '274994706269'
>> log scanned up to (274996152436)
xtrabackup: Stopping log copying thread.
xtrabackup: Transaction log of lsn (274991525290) to (274996152436) was copied.

Czas wykonania kopii zapasowej bazy danych zawierającej 83 973 092 rekordów, które zajmują około 8,2 GB zabrał około 1 minuty. W domyślnej konfiguracji oprogramowanie będzie starało się wykonać kopię zapasową tak szybko jak to tylko jest możliwe. Może to obciążyć dodatkowo maszynę, zatem aby ograniczyć skorzystamy z parametru --throttle. Zbyt restrykcyjne ograniczenie programu, może spowodować, że kopia nie zostanie wykonana, ponieważ do serwera bazy danych będzie docierało więcej rekordów niż jest archiwizowane.

Niestety tak wykonana kopia nie jest jeszcze gotowa do użytku. Przed wykonaniem przywracania danych należy ją specjalnie do tego przygotować. Należy jednak pamiętać, że są to skopiowane jedynie dane InnoDB. Do wykonania całej kopii bazy należy skorzystać ze skryptu innobackupex. W pierwszej kolejności uruchamia on program xtrabackup. Po skończeniu kopiowania danych, blokuje tabele za pomocą FLUSH TABLES WITH READ LOCK, wykonuje kopiowanie danych MyISAM a następnie zdejmuje blokadę.

Przygotowanie kopii zapasowej

Podczas wykonywania backupu, część danych mogła ulec zmianie, dlatego wykonana kopia może być niespójna. Próba uruchomienia bazy danych na takich plikach spowoduje jej awarię. Dlatego mechanizm XtraBackup wykorzystuje funkcję crash-recovery do przygotowania danych.

Silnik InnoDB prowadzi tak zwany redo log (log transakcji). Zawiera on zapis każdej zmiany jaka nastąpiła w danych. Kiedy baza startuje, odczytuje ten log i wykonuje dwa kroki. Akceptuje wszystkie dane jakie zostały zacommitowane w logu, a cofa wszystkie zmiany jakie nie posiadają commita.

Przygotowanie danych przez xtrabackup działa podobnie wykorzystując wbudowany silnik InnoDB. Aby rozpocząć ten proces wydajemy polecenie:

xtrabackup_55 --prepare --target-dir=/backup

Wynikiem jego powinien podobny fragment logu:

xtrabackup_55 version 1.6.2 for Percona Server 5.5.9 Linux (x86_64) (revision id: 274)
xtrabackup: cd to /backup
xtrabackup: This target seems to be not prepared yet.
xtrabackup: xtrabackup_logfile detected: size=5210112, start_lsn=(274991525290)
xtrabackup: Temporary instance for recovery is set as followings.
xtrabackup:   innodb_data_home_dir = ./
xtrabackup:   innodb_data_file_path = ibdata1:10M:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 1
xtrabackup:   innodb_log_file_size = 5210112
110812 11:33:21 InnoDB: Using Linux native AIO
xtrabackup: Starting InnoDB instance for recovery.
xtrabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
110812 11:33:21 InnoDB: The InnoDB memory heap is disabled
110812 11:33:21 InnoDB: Mutexes and rw_locks use GCC atomic builtins
110812 11:33:21 InnoDB: Compressed tables use zlib 1.2.3
110812 11:33:21 InnoDB: Using Linux native AIO
110812 11:33:21 InnoDB: Warning: innodb_file_io_threads is deprecated. Please use innodb_read_io_threads and innodb_write_io_threads instead
110812 11:33:21 InnoDB: Initializing buffer pool, size = 100.0M

110812 11:33:21 InnoDB: Completed initialization of buffer pool
110812 11:33:21 InnoDB: highest supported file format is Barracuda.
InnoDB: Log scan progressed past the checkpoint lsn 274991525290
110812 11:33:21  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Doing recovery: scanned up to log sequence number 274996152436 (99 %)
110812 11:33:23  InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percents: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 
InnoDB: Apply batch completed
110812 11:33:26  InnoDB: Waiting for the background threads to start
110812 11:33:27 Percona XtraDB (http://www.percona.com) 1.1.5-20.0 started; log sequence number 274996152436

[notice (again)]
  If you use binary log and don't use any hack of group commit,
  the binary log position seems to be:

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
110812 11:33:27  InnoDB: Starting shutdown...
110812 11:33:32  InnoDB: Shutdown completed; log sequence number 274996207841

Ostatnia linijka świadczy o poprawnym przygotowaniu kopii zapasowej do przywracania. Proces ten można uruchomić na osobnej maszynie, aby nie obciążać tej, na której wykonujemy backup. Należy pamiętać tylko o tym, aby uzywać tej samej wersji aplikacji Percona XtraBackup. Podczas przygotowywania, xtrabackup uruchamia specjalną wersję silnika InnoDB.

Backup jest gotowy do odzyskiwania. Warto jednak wykonać jeszcze jeden krok, aby przywracanie bazy było zdecydowanie szybsze. Należy przygotować kopię po raz drugi za pomocą tego samego polecenia. Pierwsze wykonanie polecenia sprawia, że dane stają się poprawne i ciągłe, ale nie jest tworzony plik dziennika logów InnoDB. Po przywróceniu takiej kopii, serwer MySQL będzie musiał ten dziennik utworzyć sam. Przy dużych bazach operacja ta zajmie kawałek czasu. Dlatego ponowne wykonanie tego polecenia, powinno stworzyć wspomniane pliki.

Tym razem w logach powinniśmy zobaczyć:

110812 13:43:49  InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
110812 13:43:49  InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait..

Przyszedł czas na przywracanie danych.

Przywracanie danych

Oprogramowanie nie ma opcji przywracania danych, dlatego tę czynność musimy wykonać samodzielnie za pomcą dowolnego narzędzia. Możemy wykorzystać do tego na przykład polecenie rsync i skopiować pliki w odpowiednie miejsce. Następnie należy upewnić się, że posiadają one odpowiednie uprawnienia.

Należy pamiętać, że xtrabackup kopiuje tylko dane InnoDB, dlatego należy samodzielnie przywrócić dane dane MyISAM, definicje tabel (pliki .frm) i wszystko inne co jest potrzebne do uruchomienia serwera. Do przywrócenia danych InnoDB posłużą nam polecenia:

cd /backup
rsync -rvt --exclude 'xtrabackup_checkpoints' --exclude 'xtrabackup_logfile' ./ /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql/

Po przywróceniu pozostałych danych, można wystartować bazę.

Kopie przyrostowe

Obie aplikacje (xtrabackup i innobackupex) wspierają wykonywanie przyrostowych kopii zapasowych. Oznacza to, że możliwe jest archiwizowanie tylko tych danych, jakie uległy zmianie od ostatniej kopii zapasowej. Dzięki temu możemy wprowadzić politykę archiwizacji, która będzie polegała na wykonaniu pełnej kopii raz na tydzień, a codziennie wykonywać będziemy kopie przyrostowe. Na początku wykonamy pełną kopię zapasową znanym już poleceniem:

xtrabackup_55 --backup --datadir=/var/lib/mysql/ --target-dir=/backup/base

Poza skopiowaniem danych, aplikacja tworzy plik o nazwie xtrabackup_checkpoints, który zawiera następujące dane:

backup_type = full-backuped
from_lsn = 0
to_lsn = 1291135

Zapisane są tam informacje, do którego miejsca została wykonana kopia zapasowa. Podczas wykonywania kopii przyrostowej, aplikacja właśnie od tego miejsca zaczyna kopiować dane. Aby rozpocząć taką archiwizację wydajemy polecenie:

xtrabackup_55 --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base --datadir=/var/lib/mysql/

Katalog /backup/inc1 zawierać teraz będzie pliki w postaci *.delta, które zawierają dane zmienione od ostatniej pełnej kopii zapasowej. Zaglądając do pliku xtrabackup_checkpoints zobaczymy wpis:

backup_type = incremental
from_lsn = 1291135
to_lsn = 1291340

Wykonując kolejną kopię przyrostową korzystamy z poprzedniej. Wydajemy analogiczne polecenie:

xtrabackup_55 --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1 --datadir=/var/lib/mysql/

Przygotowanie kopii zapasowej z backupu przyrostowego

Krok --prepare nie jest taki sam jak dla kopii całościowej. W poprzedniej metodzie wystarczyło wydać dwa razy to samo polecenie by uzyskać sprawną kopię danych InnoDB. W tym przypadku będzie to wyglądało troszkę inaczej. W powyższym przykładzie stworzyliśmy trzy kopie zapasowe:

  • /backup/base – pełna kopia
  • /backup/inc1 – pierwsza kopia przyrostowa
  • /backup/inc2 – druga kopia przyrostowa

Zaczynamy od wydania polecenia:

xtrabackup_55 --prepare --apply-log-only --target-dir=/backup/base

Teraz należy nałożyć na pełen backup, kolejne kopie przyrostowe. Zaczynamy kolejno wydawać polecenia:

xtrabackup_55 --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1
xtrabackup_55 --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc2

Wykonując te polecenia powinno się nam udać nałożyć zmiany z każdej kopii przyrostowej. Gotowa kopia będzie znajdowała się w katalogu /backup/base, a na ekranie powinniśmy widzieć wynik ostatniego polecenia:

incremental backup from 1291135 is enabled.
xtrabackup: cd to /backup/base/
xtrabackup: This target seems to be already prepared.
xtrabackup: xtrabackup_logfile detected: size=2097152, start_lsn=(1291340)
Applying /backup/inc1/ibdata1.delta ...
Applying /backup/inc1/test/table1.ibd.delta ...

Częściowa kopia zapasowa

Oprogramowanie wspiera wykonywanie częściowych kopii zapasowych, kiedy na serwerze włączona jest opcja innodb_file_per_table. Dostępne są dwie metody podejścia do tego tematu. Dla przykładu wykonamy kopię zapasową bazy danych o nazwie test, która zawiera dwie tabele: t1 i t2.

Pierwszym sposobem jest skorzystanie z przełącznika --tables. Parametr ten obsługuje wyrażenia regularne, dlatego aby wykonać kopię zapasową wybranej bazy możemy skorzystać z polecenia:

xtrabackup_55 --backup --datadir=/var/lib/mysql --target-dir=/backup --tables="^test[.].*"

Natomiast, aby zarchiwizować wybraną tabelę, posłużymy się poleceniem:

xtrabackup_55 --backup --datadir=/var/lib/mysql --target-dir=/backup --tables="^test[.]t1"

Podobne wyniki uzyskamy korzystając z przełącznika --tables-file wskazując zamiast nazwy tabeli, plik w jakim jest ona składowana. Parametr rozróżnia wielkość liter. Kolejnym krokiem będzie przygotowanie kopii do jej odzyskania. Posłużymy się parametrem --prepare.

Polecenie wydajemy analogicznie, jak w poprzednich krokach, z tym że w logach pojawią się błędy, że nie istnieją inne tabele. Zachowanie to jest normalne dla aplikacji, gdyż ich nie kopiowaliśmy. Takimi błędami nie należy się przejmować. Przykładowy wynik polecenia:

InnoDB: Reading tablespace information from the .ibd files...
101107 22:31:30  InnoDB: Error: table 'test1/t'
InnoDB: in InnoDB data dictionary has tablespace id 6,
InnoDB: but tablespace with that id or name does not exist. It will be removed from

Ograniczenia XtraBackupu

Oprogramowanie ma kilka ograniczeń, o których należy pamiętać podczas wykonywania kopii zapasowej. Dzięki temu możemy uniknąć wielu później rozczarowań. Ograniczenie te to:

  • Jeżeli plik xtrabackup_logfile jest większy niż 4GB, podczas kroku --prepare, aplikacje ulegnie awarii i nie wykona zadania. Błąd dotyczy tylko 32 bitowej wersji xtrabackup. Limit ten pojawia się również w starszych wersjach 64 bitowego programu.
  • Obecnie oprogramowanie nie tworzy logów InnoDB (np. ib_logfile0) podczas pierwszego uruchomienia --prepare. Aby stworzyć te pliki nalezy wykonać ten krok dwukrotnie.
  • Opogramowanie kopiuje tylko dane i logi InnoDB. Aby posiadać pełną kopię zapasową serwera bazy danych, nalezy ręcznie skopiować definicje tabel (pliki .frm, dane MyISAM, użytkowników, przywileje, czyli wszystko co nie jest składowane w InnoDB. Do wykonania kopii tych danych został stworzony skrypt innobackupex.
  • xtrabackup nie rozpoznaje bardzo starej składni --set-variable w pliku my.cnf.
  • W niektórych przypadkach może dojść do uszkodzenia przygotowywanych danych, jeżeli --target-dir wskazuje na zamontowany zasób NFS z opcją async. Jeżeli skopiujmy dane w taki katalog, a następnie uruchomimy przygotowanie plików z innego serwera, który również montuje dane w sposób asynchroniczny, możemy uszkodzić pliki kopii zapasowej.

Statystyki

Oprogramowanie XtraBackup pozwala również na analizowanie plików InnoDB w trybie tylko do odczytu. Pozwala to na zebranie różnych statystyk na temat bazy danych. Służy do tego opcja --stats. Aby odciążyć serwer można analizować tylko wybrane tabele za pomocą --tables.

Analizę można uruchomić na działającym serwerze, lecz nie zawsze może się ona udać. Zalecane jest wykonanie jej na kopii zapasowej, po drukrotnym wykonaniu --prepare. Przykładowy wynik polecenia:

<INDEX STATISTICS>
  table: test/table1, index: PRIMARY, space id: 12, root page 3
  estimated statistics in dictionary:
    key vals: 25265338, leaf pages 497839, size pages 498304
  real statistics:
     level 2 pages: pages=1, data=5395 bytes, data/pages=32%
     level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
        leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%

Przygotowany został również specjalny skrypt, który formatuje wygenerowane dane do postaci bardziej czytelnej dla użytkownika. Poniżej zawartość skryptu tabulate-xtrabackup-stats.pl:

#!/usr/bin/env perl
    use strict;
    use warnings FATAL => 'all';
    my $script_version = "0.1";
     
    my $PG_SIZE = 16_384; # InnoDB defaults to 16k pages, change if needed.
    my ($cur_idx, $cur_tbl);
    my (%idx_stats, %tbl_stats);
    my ($max_tbl_len, $max_idx_len) = (0, 0);
    while ( my $line = <> ) {
       if ( my ($t, $i) = $line =~ m/table: (.*), index: (.*), space id:/ ) {
          $t =~ s!/!.!;
          $cur_tbl = $t;
          $cur_idx = $i;
          if ( length($i) > $max_idx_len ) {
             $max_idx_len = length($i);
          }
          if ( length($t) > $max_tbl_len ) {
             $max_tbl_len = length($t);
          }
       }
       elsif ( my ($kv, $lp, $sp) = $line =~ m/key vals: (\d+), \D*(\d+), \D*(\d+)/ ) {
          @{$idx_stats{$cur_tbl}->{$cur_idx}}{qw(est_kv est_lp est_sp)} = ($kv, $lp, $sp);
          $tbl_stats{$cur_tbl}->{est_kv} += $kv;
          $tbl_stats{$cur_tbl}->{est_lp} += $lp;
          $tbl_stats{$cur_tbl}->{est_sp} += $sp;
       }
       elsif ( my ($l, $pages, $bytes) = $line =~ m/(?:level (\d+)|leaf) pages:.*pages=(\d+), data=(\d+) bytes/ ) {
          $l ||= 0;
          $idx_stats{$cur_tbl}->{$cur_idx}->{real_pages} += $pages;
          $idx_stats{$cur_tbl}->{$cur_idx}->{real_bytes} += $bytes;
          $tbl_stats{$cur_tbl}->{real_pages} += $pages;
          $tbl_stats{$cur_tbl}->{real_bytes} += $bytes;
       }
    }
     
    my $hdr_fmt = "%${max_tbl_len}s %${max_idx_len}s %9s %10s %10s\n";
    my @headers = qw(TABLE INDEX TOT_PAGES FREE_PAGES PCT_FULL);
    printf $hdr_fmt, @headers;
     
    my $row_fmt = "%${max_tbl_len}s %${max_idx_len}s %9d %10d %9.1f%%\n";
    foreach my $t ( sort keys %tbl_stats ) {
       my $tbl = $tbl_stats{$t};
       printf $row_fmt, $t, "", $tbl->{est_sp}, $tbl->{est_sp} - $tbl->{real_pages},
          $tbl->{real_bytes} / ($tbl->{real_pages} * $PG_SIZE) * 100;
       foreach my $i ( sort keys %{$idx_stats{$t}} ) {
          my $idx = $idx_stats{$t}->{$i};
          printf $row_fmt, $t, $i, $idx->{est_sp}, $idx->{est_sp} - $idx->{real_pages},
             $idx->{real_bytes} / ($idx->{real_pages} * $PG_SIZE) * 100;
       }
    }

Wygenerowane wcześniej dane zostaną sformatowane do postaci:

          TABLE           INDEX TOT_PAGES FREE_PAGES   PCT_FULL
art.link_out104                    832383      38561      86.8%
art.link_out104         PRIMARY    498304         49      91.9%
art.link_out104       domain_id     49600       6230      76.9%
art.link_out104     domain_id_2     26495       3339      89.1%
art.link_out104 from_message_id     28160        142      96.3%
art.link_out104    from_site_id     38848       4874      79.4%
art.link_out104   revert_domain    153984      19276      71.4%
art.link_out104    site_message     36992       4651      83.4%

Podsumowanie

Oprogramowanie Percona XtraBackup jest bardzo ciekawym rozwiązaniem w stosunku do innych jakie możemy odszukać w Internecie. Prostym i tanim kosztem możemy wdrożyć szybką archiwizację danych i skorzystać z technologii jakiej używają duże serwisy jak np. Facebook.