基于docker的mysql主从同步

目标:一台已经在运行mysql,增加从库

环境: docker mysql5.7.26 不同主机

步骤:

  1. 在需要安装从库的主机上安装docker(自行百度)
  2. 在从库主机上安装mysql (基于docker)
docker run -d \
--name mysql-slave \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /mnt/up/docker/mysql-slave/conf:/etc/mysql \
-v /mnt/up/docker/mysql-slave/data:/var/lib/mysql \
-v /mnt/up/docker/mysql-slave/logs:/var/log/mysql \
-p 3306:3306 \
-d mysql:5.7.26

解释:

  • docker run -d 后台运行容器
  • --name mysql-slave 给容器起名为 mysql-slave
  • -e MYSQL_ROOT_PASSWORD=123456 设置mysql的root的密码为 123456
  • -v /mnt/up/docker/mysql-slave/conf:/etc/mysql \ 挂载宿主机 /mnt/up/docker/mysql-slave/conf目录到容器 /etc/mysql,mysql的配置文件放在该目录下,映射到宿主机好配置,注3 my.cnf(最下方)
  • -v /mnt/up/docker/mysql-slave/data:/var/lib/mysql \ mysql的数据库文件,映射出来可以持久化数据库文件(自行看需求是否需要映射)
  • -v /mnt/up/docker/mysql-slave/logs:/var/log/mysql \ mysql的日志文件,(自行看需求是否需要映射)
  • -p 3306:3306 \ 暴露到宿主机上的端口
  • -d mysql:5.7.26 指定mysql镜像版本
  1. 查看容器是否启动正常
    docker logs mysql-slave
    出现如下内容代表配置的my.cnf未生效,解决参考docker-mysql使用中的坑
[Warning] World-writable config file ‘/etc/mysql/my.cnf’ is ignored.
  1. 主库机上创建用于主从同步的账号,建议创建一个专用账号
CREATE USER 'repl'@'%' IDENTIFIED BY 'passwd' REQUIRE SSL; 
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
  1. 主库机修改my.cnf配置,注意 server_id尽量唯一,建议主从my.cnf对mysql的配置一致,避免发生奇葩问题
[mysqld]
#0,区分大小写; 1,不区分
#lower_case_table_names=1
# 时间少8个小时
default-time-zone = '+8:00'

#skip-grant-tables
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#解决:mysql5.7 timestamp默认值‘0000-00-00 00:00:00’报错


#GTID 主从复制#
gtid_mode=on
enforce_gtid_consistency=on
server_id=1

#binlog
log_bin=mysqlbin
log_slave_updates=1
#强烈建议,其他格式可能造成数据不一致
binlog_format=row

#relay log
skip_slave_start=1
  1. 重启主库生效
  2. 从库机连接主库
docker run -it --rm mysql:5.7.26 mysql -h172.17.0.1 -P3306 -uroot -p123456 \
-e "CHANGE MASTER TO MASTER_HOST='192.168.1.120', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1, MASTER_SSL=1;" \
-e "START SLAVE;"

解释:

  • 这段运行是创建一个临时的mysql容器进去登录到172.17.0.1:3306,为什么这样配置?因为在没有指定docker网卡时,使用默认网卡,ip段为172.17.0.x 宿主机的ip为172.17.0.1。上面我们把 mysql-slave容器的3306端口映射到宿主机的3306,所以这里登录上去的mysql即为容器 mysql-slave的mysql。当然可以选择自己喜欢的方式去登录,毕竟我们的目的只是去执行sql,不是纠结怎么登录
  • 登录近从库后执行 CHANGE MASTER TO MASTER_HOST='192.168.1.120', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1, MASTER_SSL=1;START SLAVE;
    前一句表示把本mysql(即从库)的主库指向192.168.1.120并且登录账户是repl,后一句表示是开始主从库同步
  1. 查看主从库同步状态
docker run -it --rm mysql:5.7.26 mysql -h172.17.0.1 -P3306 -uroot -p123456  -e "show slave status\G"

如果如下2个字段不是Yes,请先查看错误消息如下:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Last_Error会有错误消息,请结合 docker logs mysql-slave的日志信息分析

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 212.64.35.217
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysqlbin.000002
          Read_Master_Log_Pos: 17984
               Relay_Log_File: 525d536d1c17-relay-bin.000002
                Relay_Log_Pos: 411
        Relay_Master_Log_File: mysqlbin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1032
                   Last_Error: Could not execute Update_rows event on table openshop.QRTZ_SCHEDULER_STATE; Can't find record in 'QRTZ_SCHEDULER_STATE', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysqlbin.000002, end_log_pos 1755
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1378
              Relay_Log_Space: 17231
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1032
               Last_SQL_Error: Could not execute Update_rows event on table openshop.QRTZ_SCHEDULER_STATE; Can't find record in 'QRTZ_SCHEDULER_STATE', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysqlbin.000002, end_log_pos 1755
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 8041418
                  Master_UUID: a1221a75-d8fe-11e9-acf9-0242ac110005
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp: 200804 07:38:08
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: a1221a75-d8fe-11e9-acf9-0242ac110005:4-44
            Executed_Gtid_Set: 0235edd8-d61f-11ea-9d3c-0242ac11000e:1-761,a1221a75-d8fe-11e9-acf9-0242ac110005:1-3
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

注1:已运行的mysql进行主从同步,那么开始的从库是没有数据库的,所以会无法同步,请先把主库上的数据拉一份到从库,再在从库机上重新开启主从同步

docker run -it --rm mysql:5.7.26 mysql -h172.17.0.1 -P3306 -uroot -p123456 -e "stop slave;reset slave;" && docker restart mysql-slave

解释:停止同步,重置主从链接并重启容器 mysql-slave,这个时候容器就恢复到第5步了,继续开始执行第6步

注2:上面出现的错误

Last_Error: Could not execute Update_rows event on table openshop.QRTZ_SCHEDULER_STATE; Can't find record in 'QRTZ_SCHEDULER_STATE', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysqlbin.000002, end_log_pos 1755

这个错误是因为我手动拉了一份主库数据库到从库后再次操作第6步出现的,说的是数据库 openshop中表 QRTZ_SCHEDULER_STATE的数据无法同步,经过查询:解决方法http://www.itpub.net/thread-1566441-1-1.html,还有其它类似的错误基本都是数据约束或者主从配置不一致导致的,所以建议主从配置一致

注3:my.cnf配置,具体参数请自行配置

[mysqld]
#0,区分大小写; 1,不区分
#lower_case_table_names=1
# 时间少8个小时
default-time-zone = '+8:00'

#skip-grant-tables
#解决:mysql5.7 timestamp默认值‘0000-00-00 00:00:00’报错
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

#GTID 主从复制#
gtid_mode=on
enforce_gtid_consistency=on
server_id=8413

#binlog
log_bin=mysqlbin
log_slave_updates=1
#强烈建议,其他格式可能造成数据不一致
binlog_format=row

#relay log
skip_slave_start=1

#主从复制跳过1146错误 https://blog.csdn.net/gua___gua/article/details/52869614
slave_skip_errors=1146

注4:通过docker容器备份数据库

  1. 创建一个临时容器并挂载一个目录作为备份sql的存放
docker run -it -v /tmp/mysql:/etc/tmp --rm mysql:5.7.26 /bin/bash 
  1. 容器中执行如下命令备份全部数据库
mysqldump -h192.168.1.120 -uroot -p123456 --all-databases > /etc/tmp/backup-all.sql
  1. 如果上述执行错误,那么就一个库一个库的备份了
mysqldump -h192.168.1.120 -uroot -p123456 --databases test1> /etc/tmp/backup-test1.sql
mysqldump -h192.168.1.120 -uroot -p123456 --databases test2> /etc/tmp/backup-test2.sql
  1. 备份完成应该在宿主机的/tmp/mysql目录下能看到刚才备份的sql
  2. 还原到从库
//登录到从库
mysql -h172.17.0.1 -P3306 -uroot -p123456 
//使用source命令还原
source /etc/tmp/backup-all.sql

注5:遇到一些问题的参考

  1. 主从复制错误处理总结
//已解决的错误
Last_Errno: 1146
 Last_Error: Error executing row event: 'Table 'panda.t' doesn't exist'
  1. mysql主从同步错误解决和Slave_IO_Running:NO

已解决的错误 Duplicate entry

错误提示如下

Error 'Duplicate entry '1' for key 1' on query. Default database: 'movivi1'. Query: 'INSERT INTO `v1vid0_user_samename` VALUES(null,1,'123','11','4545','123')'

Error 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1' on query. Default database: 'club'. Query: 'INSERT INTO club.point_process ( GIVEID, GETID, POINT, CREATETIME, DEMO ) VALUES ( 0, 4971112, 5, '2010-12-19 16:29:28','
1 ro in set (0.00 sec)

Mysql > Slave status\G;

显示:Slave_SQL_Running 为 NO
解决方法:

Mysql > stop slave;
Mysql > set global sql_slave_skip_counter =1;
Mysql > start slave;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342