Backup with xtrabackup from Docker-Container "percona/percona-xtradb-cluster:5.7"

Hello,I use Docker with the image “percona/percona-xtradb-cluster:5.7” in a
cluster with 3 nodes. I would like to make a backup of the database
with “xtrabackup” in the container. Unfortunately, only the “ibdata1”
is saved and the error output includes “sh: perl: command not found”. I
know that “xtrabackup” has to be run locally (unfortunately it doesn’t
work over the network) and that it needs the package
“libdbd-mysql-perl”. But unfortunately the package “libdbd-mysql-perl”
is not available in your image “percona / percona-xtradb-cluster: 5.7”.
My question is, how can I make a backup of the current operation from
the database in the container? “Xtrabackup” doesn’t seem to work.I would be very grateful for a helpful answer.Best RegardsYoda

Yoda,

Backups from docker images can be complicated.
Can you share command line how do you start an individual docker container?

I think that could be so (maybe):
docker run -d <br>  -e MYSQL_ROOT_PASSWORD=geheim <br>  -e CLUSTER_NAME=db3306_cluster1 <br>  -e DISCOVERY_SERVICE=db3306_etcd:2379 <br>  --name=db3306_xtradb-cluster <br>  --net=db3306_dbnet <br>  -v /usr/share/ca-certificates/:/etc/ssl/certs <br>  -v db3306-db-vol-1:/var/lib/mysql <br>  -v db3306-db-my-cnf-vol-1:/etc/mysql/conf.d <br>  percona/percona-xtradb-cluster:5.7


I use Docker-Swarm and build the Docker-Services (where the Container are inside) with Ansible.The DB-Volumes are mounted from the ceph with rexray.
From outsite of the Swarm, you can only connect to the DB through ProxySQL.

Maybe its helpfull to see how i go into the Container per script:

1.
I have the script (bk.sh) to start from inside of Container:
#--------------------------------------------------#
#!/bin/bash
/usr/bin/xtrabackup --backup --stream=tar -h /var/lib/mysql -uroot -p${MYSQL_ROOT_PASSWORD} -Hlocalhost -P3306 2>>/tmp/xtrabackup.log
#--------------------------------------------------#

Start:

docker cp bk.sh $(docker ps -f name=db3306_xtradb-cluster -q | head -n1):/tmp/bk.sh
docker exec -t -uroot $(docker ps -f name=db3306_xtradb-cluster -q | head -n1) /tmp/bk.sh
docker exec -t -uroot $(docker ps -f name=db3306_xtradb-cluster -q | head -n1) rm -fv /tmp/bk.sh


what version of xtrabackup do you use? make sure it is 2.4

I use what is already in the Percona image, because nothing else can be installed in the container. It is version 2.4.20.

xtrabackup 2.4 does require perl only to check if new version is available, it is not critical if perl is not present, xtrabackup will work.

This is what I just tried:
start container:

docker run -d \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --name ps1 -p3306:3306 \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -e MYSQL_ROOT_PASSWORD=root \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -v /data/ps-docker:/var/lib/mysql \
&nbsp; percona/percona-xtradb-cluster:5.7<br>

execute backup: 

docker exec -it ps1&nbsp; xtrabackup --backup -uroot -proot --target-dir=/tmp/back1

xtrabackup: recognized server arguments: --datadir=/var/lib/mysql --innodb_flush_log_at_trx_commit=0 --innodb_flush_method=O_DIRECT --innodb_file_per_table=1&nbsp;
xtrabackup: recognized client arguments: --socket=/tmp/mysql.sock --backup=1 --user=root --password=* --target-dir=/tmp/back1&nbsp;

sh: perl: command not found
200807 16:58:46 Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: /tmp/mysql.sock
Using server version 5.7.30-33-57

It prints “perl: command not found” but it is not an error, the backup should succeed.
If you want to eliminate this warning, you can add “–no-version-check” option to xtrabackup.
For example:

docker exec -it ps1&nbsp; xtrabackup --backup -uroot -proot --target-dir=/tmp/back1 --no-version-check

Thank you!

Then my problem is different.
My appeal is as follows:

/usr/bin/xtrabackup --backup --stream=tar -h /var/lib/mysql -uroot -p${MYSQL_ROOT_PASSWORD} -Hlocalhost -P3306 2&gt;&gt;/tmp/xtrabackup.log


and otherwise no error is output.

When I test this:

/usr/bin/xtrabackup --backup --stream=tar -h /var/lib/mysql -uroot -p${MYSQL_ROOT_PASSWORD} -Hlocalhost -P3306 2&gt;&gt;/tmp/xtrabackup.log &gt; /tmp/db.tar

``` tar tf /tmp/db.tar ```
ibdata1


Then it is a healthy TAR archive with only one file in it. => “ibdata1”

I would need to see the whole xtrabackup output, otherwise it is hard to say what is the problem

I think I found the culprit.
It’s not xtrabackup but docker.If I go into the container and then write the backup to a tar file, it works.
But if I pass the xtrabackup command to Docker, it doesn’t work.
Even if I have a script in the container and then pass this script to Docker as a command, it doesn’t work either.
The TAR file in the container is always a few bytes smaller.
Whenever I start the backup with a Docker call, Docker mixes additional lines of text into the data stream.
Even if I set Docker’s log level to “fatal”, it doesn’t get any better.
How can I get Docker to be completely silent?

I do not know how to solve docker output problem, but I probably would do backup differently.
1. Mount another backup volume to the docker container and perform xtrabackup from one volume to backup volume
or 
2. using stream=tar but streaming directly to another host which accepts incoming steams

Yes, thank you!I’ll try this out next week.
Can you tell me how to mount another drive in the container?

Yoda said: Yes, thank you!I'll try this out next week.
Can you tell me how to mount another drive in the container?
You add the volume the same way as you add data volume, for example, add the line
```  -v /data/backup:/tmp/backup \ ```
to your docker run command.
Then from inside of docker make ``` xtrabackup ... --target-dir=/tmp/backup ```


Yes, it can work that way.But I thought of using the additional backup drive as a transfer drive
because the backup should then also be stored on tape.Therefore I wanted to mount the drive shortly before starting
xtrabackup and then release it again so that the tape robot can mount
the drive and then write the backup to tape.
For this reason I would need a CLI command to mount a drive during operation.

I solved it with a Ceph volume, which I mounted in
the container and on the backup server.
The only thing to note is that after the backup, a “sync” is carried
out and a umount and then a mount on the backup server. The backup
server may only have read access to the drive.

Thank you for your help! :slight_smile: