Как мога да направя инкрементално архивиране на SQLite база данни?

Искам да архивирам базата данни с висока честота, но цената на пълното архивиране не е приемлива. Изглежда, че SQLite няма API, за да прави директно инкрементално архивиране. Но открих, че има обратни извиквания за известие за промяна на данни, което изглежда полезно. https://www.sqlite.org/c3ref/update_hook.html Параметрите на обратните извиквания са тип операция, име на база данни, име на таблица и rowID. Въпреки това, не знам дали е възможно да се генерира резервна информация (например SQL израз) за този ред от дата чрез тази информация, без да се знае подробната информация на таблицата. Което означава, че има общ метод за генериране на резервно копие за тази операция за таблици с различна структура? Знам, че има някои изключения, при които обратното извикване няма да бъде извикано, и мисля, че това е приемливо, ако периодично правя пълно архивиране.


person iuradz    schedule 19.03.2015    source източник
comment
SQLite има API за архивиране: sqlite.org/backup.html   -  person Colonel Thirty Two    schedule 20.03.2015
comment
@ColonelThirtyTwo И това прави пълни резервни копия.   -  person CL.    schedule 20.03.2015
comment
да И струваше твърде скъпо да се прави пълен гръб често.   -  person iuradz    schedule 20.03.2015
comment
Възможен дубликат на Как мога да създам инкрементални архиви на mysql бази данни   -  person Paul Sweatte    schedule 03.10.2015
comment
Възможен дубликат на Как да правя инкрементални архиви за SQLite?   -  person Bernardo Ramos    schedule 15.01.2017
comment
Възможен дубликат на Има ли начин да актуализирате SQLITE база данни с делти?   -  person Paul Sweatte    schedule 21.01.2017


Отговори (1)


Мислех за тази идея, тя не е официално одобрена от SQLite, но на теория звучи много правдоподобно.

API за архивиране на SQLite по същество ви позволява да получите работеща моментна снимка на файла на живата база данни. По подобен начин VACCUM INTO ви позволява да актуализирате съществуващ резервен файл с база данни. https://www.sqlite.org/lang_vacuum.html#vacuuminto

Това е просто добро старо архивиране, ние искаме инкрементално архивиране (нещо като git)

Да предположим, че искаме да архивираме базата данни на всеки час и това е 1GB база данни с относително малко записи, съхраняването на 24GB на ден звучи като прекаляване.

Можем да се възползваме от файловия формат SQLite, който по същество е фиксиран 100 байтов хедър + (page_size * num_pages). SQLite винаги ще пише около границите на страницата. Page_size и num_pages се съхраняват в 100-байтовия хедър. Вижте спецификацията за съхранение https://www.sqlite.org/fileformat.html

Така че това, което можем да направим, е да създадем референтен файл, който е просто файл със списък от хешове. Да кажем, че използваме sha256 (което използва новата версия на git), така че ще бъде файл (напр. backups/2020-02-22-19-12-00.txt)

sha256(header)
sha256(page1)
sha256(page2)
sha256(page3)

И ние съхраняваме съответните страници като отделни файлове, както git прави в директория на обекти.

Например objects/ab/cdef12343..

Първите две букви се използват като име на директория, така че да нямаме твърде много файлове в директория.

Като алтернатива можете просто да качите файловете на страниците на някой от доставчиците на облачно хранилище, например GCS, S3, Azure Blobs, DO spaces. Това може да осигури многорегионално архивиране.

Тъй като не съхраняваме дублиращи се копия на страници, общият файлов размер на всички архиви е доста малък в сравнение с база_размер * брой_бекъпи.

Можете дори да използвате хеш файла като начин за синхронизиране/възстановяване на SQLite файл. Ето как Dropbox/rsync синхронизира файлове. Файлът с хешове ни казва кои страници са се променили и ние изтегляме само променените обекти и актуализираме тези диапазони във файла.

person user3893988    schedule 06.03.2020