前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL 5.6到MySQL 8的主从复制(通过5.7版本做桥接实现)

MySQL 5.6到MySQL 8的主从复制(通过5.7版本做桥接实现)

作者头像
用户1148526
发布2024-05-26 15:29:10
950
发布2024-05-26 15:29:10
举报
文章被收录于专栏:Hadoop数据仓库Hadoop数据仓库

        MySQL 8与MySQL 5.6跨了两个大版本,直接从5.6(主)复制到8(从)是不行的,因此需要用一个MySQL 5.7版本作为桥接。5.6、5.7实例都要开启log_bin和log_slave_updates。5.6、5.7、8的安装步骤从略。

1. 在8中创建要复制的表,表使用缺省的innodb引擎

代码语言:javascript
复制
use spacex;
create table space_praise_record (
  userid bigint(20) not null default '0' comment '用户id',
  objectid bigint(20) not null default '0' comment '对象id,作品id或者分享id',
  type smallint(6) not null default '0' comment '0 作品; 1 分享',
  createtime timestamp not null default current_timestamp,
  status smallint(6) not null default '1' comment '状态 0 取消赞 1 未读点赞 2 已读点赞 ',
  touserid bigint(20) not null default '-1',
  primary key (userid,objectid,type),
  key inx_to_userid (touserid,userid,status),
  key inx_objectid (objectid,type,status,createtime),
  key index_1 (touserid,status),
  key inx_touserid_createtime (touserid,createtime)
) comment='点赞记录表';

        如果需要整库导出/导入,可使用下面的命令:

代码语言:javascript
复制
/home/mysql/mysql-5.7/bin/mysqldump -uwxy -p123456 -h172.19.1.90 -P30000 --single-transaction --triggers --routines --events --set-gtid-purged=OFF --master-data=2 -e --max_allowed_packet=1073741824 -e --net_buffer_length=16384 --databases vvmobileliveconfig vvmobilelivemetadata --no-data --no-create-db --skip-add-drop-table > dump_schema.sql



# 源库生成创建索引的文件
mysql -uwxy -p12345 -S /data/18253/mysqldata/mysql.sock -e "
select concat('alter table \`',table_schema,'\`.\`',table_name,'\` ',create_index,';')
from (
select table_schema, table_name, group_concat(if(index_name='PRIMARY',concat('add primary key (',index_columns,')'),concat('add ',if(NON_UNIQUE=0, ' unique ', ' '), 'index \`',index_name,'\` (',index_columns,')'))) create_index
from (
select table_schema, table_name, index_name, NON_UNIQUE, group_concat(concat('\`',column_name,'\`', if(sub_part is null,'',concat('(',sub_part,')'))) order by seq_in_index) index_columns
from information_schema.statistics
where table_schema in ('test', 'test_jhy') and index_name <> 'PRIMARY'
and (table_schema, table_name, index_name) not in (
select t1.table_schema, t1.table_name, t1.index_name
from information_schema.statistics t1, information_schema.columns t2
where t1.table_schema in ('test', 'test_jhy') and index_name <> 'PRIMARY'
and t1.table_schema = t2.table_schema and t1.table_name = t2.table_name and t1.column_name = t2.column_name
and t2.extra='auto_increment')
group by table_schema, table_name, index_name, NON_UNIQUE) t
group by table_schema, table_name) t;" -N > create_index.sql




# 替换掉存储程序中的定义者,因为源库中的用户有可能在目标库中不存在
sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i dump_schema.sql

# 替换掉高版本中新定义的保留字,如 rank
sed 's/ Rank=/ `Rank`=/g;s/ Rank</ `Rank`</g;s/,Rank)/,`Rank`)/g;s/,rank,/,`rank`,/g;s/\.rank,/\.`rank`,/g;s/AS rank,/AS `rank`,/g' -i dump_schema.sql

# 删除除主键外的索引。不能删除主键,否则建表时遇到自增列报错:
# Incorrect table definition; there can be only one auto column and it must be defined as a key
sed -i '/ KEY `/d;' dump_schema.sql
# 删除闭括号前的逗号
sed -i ':a;N;$!ba;s/,\n) ENGINE=InnoDB/\n) ENGINE=InnoDB/g' dump_schema.sql

# 导入结构到 MySQL 8 实例
mysql -uwxy -p123456 -S /data/18251/mysqldata/mysql.sock < dump_schema.sql

2. 在5.7创建要复制的库表,表使用innodb引擎

代码语言:javascript
复制
create database space;
use space;
create table space_praise_record (
  userid bigint(20) not null default '0' comment '用户id',
  objectid bigint(20) not null default '0' comment '对象id,作品id或者分享id',
  type smallint(6) not null default '0' comment '0 作品; 1 分享',
  createtime timestamp not null default current_timestamp,
  status smallint(6) not null default '1' comment '状态 0 取消赞 1 未读点赞 2 已读点赞 ',
  touserid bigint(20) not null default '-1',
  primary key (userid,objectid,type),
  key inx_to_userid (touserid,userid,status),
  key inx_objectid (objectid,type,status,createtime),
  key index_1 (touserid,status),
  key inx_touserid_createtime (touserid,createtime)
) engine=innodb default charset=utf8mb4 comment='点赞记录表';

        如果需要整库导出/导入,可使用下面的命令:

代码语言:javascript
复制
# 继续处理上一步的导出文件

# 将引擎从 innodb 改为 blackhole
# sed 's/ENGINE=InnoDB/engine=blackhole/g' -i dump_schema.sql

# 去掉分区子句中的 ENGINE = InnoDB
# sed 's/ ENGINE = InnoDB//g' -i dump_schema.sql

# 导入 5.7 
/home/mysql/mysql-5.7/bin/mysql -h127.0.0.1 -P18252 -uwxy -p123456 < dump_schema.sql

3. 在8启动到5.7的复制

代码语言:javascript
复制
stop slave;
reset slave all;

change master to
master_host='10.10.10.1',
master_port=3306,
master_user='u1',
master_password='123456',
master_log_file='mysqlbinlog.000001',
master_log_pos=120;

change replication filter replicate_do_table = (spacex.space_praise_record), replicate_rewrite_db = ((space, spacex));

-- 如果是整库复制
-- change replication filter replicate_do_db = (vvmobileliveconfig,vvmobilelivemetadata);

start slave;

4. 在5.7上配置到5.6的复制

代码语言:javascript
复制
stop slave;
reset slave all;

change master to
master_host='10.10.10.2',
master_port=3306,
master_user='u1',
master_password='123456';

change replication filter replicate_do_table = (space.space_praise_record);

-- 如果是整库复制
-- change replication filter replicate_do_db = (vvmobileliveconfig,vvmobilelivemetadata);

5. 将5.6的表复制到5.7

代码语言:javascript
复制
mysqldump -u u1 -p123456 -S /data/3306/mysqldata/mysql.sock --no-create-info --quick --apply-slave-statements --single-transaction --master-data=1 space space_praise_record | mysql -u u1 -p123456 -h10.10.10.1 -P3306 -Dspace

        如果是大表,可以创建脚本后台执行:

代码语言:javascript
复制
cat dump_and_load_data.sh 

#!/bin/bash
source ~/.bash_profile

date

/home/mysql/mysql-5.7/bin/mysqldump -uwxy -p123456 -h172.19.1.90 -P30000 --single-transaction --skip-triggers --set-gtid-purged=OFF --master-data=1 -e --max_allowed_packet=1073741824 -e --net_buffer_length=16384 --databases vvmobileliveconfig vvmobilelivemetadata --no-create-db --skip-add-drop-table --no-create-info --quick --apply-slave-statements > /data/18252/dump_data.sql

date

/home/mysql/mysql-5.7/bin/mysql -h127.0.0.1 -P18252 -uwxy -p123456 < /data/18252/dump_data.sql

date
代码语言:javascript
复制
nohup ~/dump_and_load_data.sh > ~/dump_and_load_data.log 2>&1 &

6. MySQL 8 目标库上创建索引

代码语言:javascript
复制
cat create_index.sh 

#!/bin/bash
source ~/.bash_profile

sed -i '1i set sql_log_bin=0;' create_index.sql

date

/home/mysql/mysql-5.7/bin/mysql -h127.0.0.1 -P18252 -uwxy -p123456 < create_index.sql

date

        后台执行:

代码语言:javascript
复制
nohup ~/create_index.sh > ~/create_index.log 2>&1 &

7. MySQL 8 目标库上分析表

代码语言:javascript
复制
mysql -uwxy -p123456 -S /data/18251/mysqldata/mysql.sock -e "
select concat('analyze table \`',table_schema,'\`.\`',table_name,'\`;') 
  from information_schema.tables 
 where table_schema in ('vvmobileliveconfig', 'vvmobilelivemetadata');" -N > analyze_table.sql

mysql -uwxy -p123456 -S /data/18251/mysqldata/mysql.sock < analyze_table.sql

8. 按源库在目标库创建用户并授权

        我最初的想法是,在起到桥接作用的 5.7 版本中的表使用 blackhole 引擎,这样避免中间数据落盘,既能节省存储空间,又可以提高效率。然而,这种方案并不成立,原因是 MySQL 的 1870 错误:

        对于 blackhole 引擎的表,MySQL 不会将 update 或 delete 语句改变的数据行写入 binlog,这样源上的修改无法复制到目标。更进一步,如果不是在 5.7 上手工执行 update 语句暴露了这个问题,本场景下这个错误是透明的,两个阶段的复制都不报错,只有对比数据才会发现这个问题。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档