我正试图在一个码头容器中运行一个MySQL复制从服务器。我们在生产中运行MySQL 5.7.24-27-日志,它来自percona存储库(Ubuntu18.04)。
我使用xtrabackup备份、准备和发送用于复制的起始数据集,然后启动percona映像(docker pull percona)如下:
$ docker run --name mysql-replication -v /replication/data:/var/lib/mysql -v /replication/docker.cnf:/etc/mysql/docker.cnf:ro -e MYSQL_ROOT_PASSWORD=xxxx -P -d percona我的docker.cnf只是记录了服务器id(我从percona映像复制了它)。
[mysqld]
skip-host-cache
skip-name-resolve
bind-address = 0.0.0.0
server-id = 4然后使用CHANGE MASTER等。我的复制运行良好。
我的目的是(按照卷挂载-v /replication/data:/var/lib/mysql)将所有MySQL数据保存在主机上,并将复制对接器容器视为临时状态,即容器中没有保存状态。如果我需要另一个复制容器,可以通过停止现有容器、在其他地方复制数据、更改server-id和运行新容器来轻松启动另一个复制容器。
为了测试这一点,在正确设置和运行它之后(我看到Seconds_Behind_Master下降到了0),我想我应该能够删除容器并重新创建它,并且复制仍然可以正常工作。因此,我尝试这样做:
$ docker stop mysql-replication
$ docker rm mysql-replication
$ docker run ... // same command as before当我这样做并连接到运行在容器中的MySQL时,我发现Slave_IO_Running是No,在启动它(START SLAVE;)之后,我得到以下信息(如SHOW SLAVE STATUS;中所示):
Last_Error: Could not execute Update_rows event on table databasename.tablename; Can't find record in 'tablename', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000681, end_log_pos 9952(databasename和tablename是真实的数据库和表名)
一开始,我以为我可能弄脏了什么东西,但现在我已经尝试了好几次,试图解决这个问题。使用docker diff mysql-replication未显示对运行中的容器的任何更改,这些更改似乎具有重要意义:
$ docker diff mysql-replication
C /run
C /run/mysqld
A /run/mysqld/mysqld.pid
C /var
C /var/log
A /var/log/mysql谷歌建议我需要使用RESET SLAVE;和START SLAVE;,但这似乎并不能解决这个问题--就像数据(容器外)不再与主服务器同步,因此复制不能继续。
有人能在我做的事上找出漏洞吗?
非常感谢。
发布于 2019-06-12 11:57:36
造成此问题的根本原因是mysql.cnf文件中缺少D1选项(或者在本例中,由于停靠器卷挂载,docker.cnf文件)。这导致了文件的创建和使用,比如最初的89726507f176-relay-bin.000002,其中89726507f176是机器的主机名(在创建映像时由停靠守护进程随机分配)。当容器被停止、删除和重新创建时,会创建和使用一组新的文件(例如be0c801d95bc-relay-bin.000407),但这会导致同步问题。
通过在relay-log文件中显式指定docker.cnf值,容器能够被移除并重新创建,而不会出现问题。
作为附带说明,我还建议,没有挂载/var/log/mysql目录存在问题--情况并非如此。但是,如果您指定了一个log_bin = /var/log/mysql/mysql-bin.log值,那么这是一个要求。如果您不指定这个路径,那么二进制日志似乎是本地存储在/var/lib/mysql中的,它已经挂载在容器之外。
我的最后一个docker.cnf文件如下:
[mysqld]
skip-host-cache
skip-name-resolve
bind-address = 0.0.0.0
binlog-ignore-db = mysql
replicate-ignore-db = mysql
log_bin = /var/log/mysql/mysql-bin.log
relay-log = replication-1
server_id = 1注意:复制从服务器上的server_id = 2。
还请注意,如果没有relay-log选项,命令SHOW MASTER STATUS;将不返回主数据库容器上的结果。
还有一个可能尚未解决的问题,即默认情况下,当您使用docker stop时,它会请求容器终止(通过向码头入口点命令发送一个SIGHUP ),如果它没有在10秒内终止,它就会被强制停止。我需要确保这是足够的时间关闭,因为它可能需要一小段时间来整理自己在负载下,可能导致数据丢失的结果。
https://dba.stackexchange.com/questions/239639
复制相似问题