docker MariaDB增量备份为未更改的数据库生成大文件

v8wbuo2f  于 2022-11-22  发布在  Docker
关注(0)|答案(1)|浏览(98)

基本上我必须为mariadb建立增量备份系统。所有东西都生活在docker容器中,我尝试使用wal-g(就像我可以轻松地使用postgres和WAL归档设置它一样)。备份任务是在基于mariadb:10.8.3-jammy映像并添加了wal-g二进制文件的单独Docker容器中执行的(我运行wal-g backup-push)。在调试期间,我使用导出到数据文件夹(作为Docker卷安装到/bak)。
下面我将介绍更多细节,但让我从实际问题开始:增量备份很大。如果我禁用所有数据库客户端,并连续重复几次相同的备份(因此它们之间没有任何变化),初始备份约为30 Mb,所有后续增量备份均为30 Mb。

# Initial
$ sudo docker compose run --rm db_backup wal-g backup-push
[+] Running 1/0
 ⠿ Container reporting-db-1  Running                                                                                                                                                                                                   0.0s
INFO: 2022/11/20 19:24:01.865762 FILE PATH: stream_20221120T192400Z/stream.lz4                                                                                                                                                              
INFO: 2022/11/20 19:24:01.865984 Backup sentinel: {"StartLocalTime":"2022-11-20T19:24:00.366507Z","StopLocalTime":"2022-11-20T19:24:01.86589Z","UncompressedSize":350375370,"CompressedSize":227476734,"Hostname":"b08f12bbbb68"}

# Incremental
$ sudo docker compose run --rm db_backup wal-g backup-push
[+] Running 1/0
 ⠿ Container reporting-db-1  Running                                                                                                                                                                                                   0.0s
INFO: 2022/11/20 19:24:07.109202 FILE PATH: stream_20221120T192405Z/stream.lz4                                                                                                                                                              
INFO: 2022/11/20 19:24:07.109509 Backup sentinel: {"StartLocalTime":"2022-11-20T19:24:05.639259Z","StopLocalTime":"2022-11-20T19:24:07.109321Z","UncompressedSize":28104928,"CompressedSize":14609954,"Hostname":"3d9854550254"}

如果我提供一个空的数据库作为数据源,那么结果会更滑稽:初始备份和增量备份具有相同的大小(±几Kb)。
我假设mariabackup转储系统表,系统表使用Aria存储引擎,不支持增量备份(source),但手动验证似乎不同意:我尝试将所有的mysql.*表转换为InoDB(ALTER TABLE ... engine=innodb)并重新创建备份,获得了1.5倍的增量转储(尽管压缩后的结果稍好一些)。

# Initial
$ sudo docker compose run --rm db_backup wal-g backup-push
[+] Running 1/0
 ⠿ Container reporting-db-1  Running                                                                                                                                                                                                   0.0s
INFO: 2022/11/20 18:56:06.254782 FILE PATH: stream_20221120T185602Z/stream.lz4                                                                                                                                                              
INFO: 2022/11/20 18:56:06.254984 Backup sentinel: {"StartLocalTime":"2022-11-20T18:56:02.328882Z","StopLocalTime":"2022-11-20T18:56:06.254911Z","UncompressedSize":366630153,"CompressedSize":229793575,"Hostname":"843e27ceff9e"}

# Incremental 1
$ sudo docker compose run --rm db_backup wal-g backup-push
[+] Running 1/0
 ⠿ Container reporting-db-1  Running                                                                                                                                                                                                   0.0s
INFO: 2022/11/20 18:56:15.123822 FILE PATH: stream_20221120T185610Z/stream.lz4                                                                                                                                                              
INFO: 2022/11/20 18:56:15.124035 Backup sentinel: {"StartLocalTime":"2022-11-20T18:56:10.974406Z","StopLocalTime":"2022-11-20T18:56:15.12395Z","UncompressedSize":44359711,"CompressedSize":13798326,"Hostname":"26a6e38afb59"}

# Incremental 2
$ sudo docker compose run --rm db_backup wal-g backup-push
[+] Running 1/0
 ⠿ Container reporting-db-1  Running                                                                                                                                                                                                   0.0s
INFO: 2022/11/20 19:06:57.626672 FILE PATH: stream_20221120T190653Z/stream.lz4
INFO: 2022/11/20 19:06:57.626904 Backup sentinel: {"StartLocalTime":"2022-11-20T19:06:53.667772Z","StopLocalTime":"2022-11-20T19:06:57.626823Z","UncompressedSize":44360402,"CompressedSize":13799019,"Hostname":"184342c39610"}

不幸的是,我不能要求我的客户端切换到方便的DBMS,并必须在这里做一些事情。我不想为每个备份存储这30 MB,如果可以避免的话。

  • 我的推理是否正确?还有什么能导致这种奇怪的行为?
  • 我能把所有的系统表都转换成InnoDB吗?我发现了证据表明它在mysql 5.7上可能是有害的,但是找不到更近的引用。它会解决这个问题,因为这样所有的东西都将正确地支持增量备份。(Dupe? Not really
  • 是否有其他备份解决方案可以更好地处理所述情况?
  • 我能给予并阻止mariabackup备份系统表吗?我怀疑这可能是一个可行的解决方案(因为备份越完整,就越容易接受它),但可能是错误的。

侧面问题:

  • 如何检查mariabackup输出的二进制流,以确认系统表是真正的问题(也许还能找出确切的表)?
  • 什么会导致转储大小波动?每当我连续运行多个增量备份时,压缩和未压缩的大小每次都会略有不同备份应该是一个确定性的过程,并且上述所有操作都是在同一数据库上执行的,中间没有任何修改(我从本地转储开始,该转储已加载到新的mariadb容器,其中包含干净的卷,并且没有客户端可以访问该示例,因此应该没有任何不同)-那么为什么会出现这种情况?我使用mariabackup进行了检查,但没有使用wal-g工具,然后大小是稳定的。它是在一些更高的层次上引入的,这就不那么有趣了。

上述所有内容也使用普通mariabackup进行复制,每次增量备份生成大约27 Mb文件.
mariabackup Package 器脚本:

last_lsns=$(ls /bak/lsns/ | sort -rn | head -n1)

if [ -n "$last_lsns" ]; then
  ex="/bak/lsns/lsn_$(date +%s)"
  mkdir -p "$ex"
  mariabackup -H"$WEB_DB_HOST" -uroot -p"$MYSQL_ROOT_PASSWORD" --backup \
    --stream=xbstream --datadir=/var/lib/mysql \
    --incremental-basedir=/bak/lsns/$last_lsns --extra-lsndir=$ex
else
  mkdir -p /bak/lsns/initial
  mariabackup -H$WEB_DB_HOST -uroot -p"$MYSQL_ROOT_PASSWORD" --backup \
    --stream=xbstream --datadir=/var/lib/mysql \
    --extra-lsndir=/bak/lsns/initial
fi

此脚本用作WALG_STREAM_CREATE_COMMAND

WALG_MYSQL_DATASOURCE_NAME='root:$MYSQL_ROOT_PASSWORD@tcp($REPORTING_DB_HOST:$REPORTING_DB_PORT)/$REPORTING_DATABASE'
WALG_FILE_PREFIX='/bak/foo'

这些设置(实际上写在合成文件中,但可能并不重要)看起来是正确的(备份按预期创建并写入正确的目录)。
以下是使用的存储类型:

> select table_schema, table_name, engine from information_schema.tables where table_schema <> 'performance_schema' and engine <> 'MEMORY';

+--------------------+---------------------------+--------+
| table_schema       | table_name                | engine |
+--------------------+---------------------------+--------+
| information_schema | ALL_PLUGINS               | Aria   |
| information_schema | CHECK_CONSTRAINTS         | Aria   |
| information_schema | COLUMNS                   | Aria   |
| information_schema | EVENTS                    | Aria   |
| information_schema | OPTIMIZER_TRACE           | Aria   |
| information_schema | PARAMETERS                | Aria   |
| information_schema | PARTITIONS                | Aria   |
| information_schema | PLUGINS                   | Aria   |
| information_schema | PROCESSLIST               | Aria   |
| information_schema | ROUTINES                  | Aria   |
| information_schema | SYSTEM_VARIABLES          | Aria   |
| information_schema | TRIGGERS                  | Aria   |
| information_schema | VIEWS                     | Aria   |
| mysql              | slow_log                  | CSV    |
| mysql              | db                        | Aria   |
| mysql              | help_relation             | Aria   |
| mysql              | general_log               | CSV    |
| mysql              | innodb_index_stats        | InnoDB |
| mysql              | servers                   | Aria   |
| mysql              | time_zone_transition_type | Aria   |
| mysql              | gtid_slave_pos            | InnoDB |
| mysql              | time_zone                 | Aria   |
| mysql              | roles_mapping             | Aria   |
| mysql              | transaction_registry      | InnoDB |
| mysql              | procs_priv                | Aria   |
| mysql              | proxies_priv              | Aria   |
| mysql              | global_priv               | Aria   |
| mysql              | func                      | Aria   |
| mysql              | innodb_table_stats        | InnoDB |
| mysql              | help_topic                | Aria   |
| mysql              | time_zone_leap_second     | Aria   |
| mysql              | help_keyword              | Aria   |
| mysql              | time_zone_transition      | Aria   |
| mysql              | event                     | Aria   |
| mysql              | columns_priv              | Aria   |
| mysql              | tables_priv               | Aria   |
| mysql              | time_zone_name            | Aria   |
| mysql              | plugin                    | Aria   |
| mysql              | table_stats               | Aria   |
| mysql              | index_stats               | Aria   |
| mysql              | proc                      | Aria   |
| mysql              | help_category             | Aria   |
| mysql              | column_stats              | Aria   |
| test_reporting     | merchant_configs          | InnoDB |
| test_reporting     | masterdata_prediction     | InnoDB |
| test_reporting     | aggregator_config         | InnoDB |
| test_reporting     | masterdata                | InnoDB |
| test_reporting     | fixed_costs               | InnoDB |
| test_reporting     | timeline                  | InnoDB |
| test_reporting     | migrations                | InnoDB |
| test_reporting     | user_analytics            | InnoDB |
| test_reporting     | affiliate                 | InnoDB |
| test_reporting     | vat_config                | InnoDB |
| sys                | sys_config                | Aria   |
| reporting          | merchant_configs          | InnoDB |
| reporting          | masterdata_prediction     | InnoDB |
| reporting          | aggregator_config         | InnoDB |
| reporting          | masterdata                | InnoDB |
| reporting          | fixed_costs               | InnoDB |
| reporting          | timeline                  | InnoDB |
| reporting          | migrations                | InnoDB |
| reporting          | user_analytics            | InnoDB |
| reporting          | affiliate                 | InnoDB |
| reporting          | vat_config                | InnoDB |
| reporting_web      | record_change             | InnoDB |
| reporting_web      | jwt_expiry                | InnoDB |
| reporting_web      | forecasting               | InnoDB |
| reporting_web      | users                     | InnoDB |
| reporting_web      | alembic_version           | InnoDB |
| reporting_web      | merchant_analytics        | InnoDB |
| reporting_web      | email_config              | InnoDB |
| reporting_web      | user_company              | InnoDB |
| reporting_web      | user_detail               | InnoDB |
+--------------------+---------------------------+--------+
7gyucuyw

7gyucuyw1#

由于引用了MDEV-23614,因此无法增量备份Aria系统表。
正如您所看到的,在10.4+中,系统表可以更改为InnoDB。
有两个小问题使其无法在--enforce-storage-engine=InnoDB下成为默认值,这两个问题都与帮助表有关:

  • CREATE TABLE IF NOT EXISTS help_relation具有对help_keyword的FK引用,但未创建help_keyword(易于修复,交换mysql_system_tables.sql中的顺序)
  • fill_help_tables.sql中,lock tables help_topic write, help_category write..一旦返回其InnoDB,则可以注解掉ER_WRONG_LOCK_OF_SYSTEM_TABLE,但实际上是一个需要报告/修复的bug。

为了保存空间,help表和proc表是最大的表。

  • 帮助表,对于HELP command语法是可选的。并且可以被截断/删除。
  • 默认情况下,proc包含一堆您可能不需要的gis函数。
  • 两者都可以转换为InnoDB。

备选方案:

  • 使用二进制日志作为PITR备用机制,并在更远的地方执行增量较少的mariabackup。

mariabackup贡献一个补丁。

相关问题