【实战】Mysql 千万级数据表结构变更 、含脚本

news2024/11/28 20:59:08

一、实测结果

  1. 业务无感知,无死锁平滑

  2. 线上800万数据以下 直接使用 alter 新增字段 300ms左右

  3. 2000万数据,强制使用主键索引,每次查询50万数据 并插入新表 ,耗时 20s ,cpu 占45%

在这里插入图片描述

在这里插入图片描述

二、整体步骤

  1. 创建新表 biz_table_new

  2. 查询当前表first_max_id

    1. 确定当前同步数据量 37509688
  3. 将数据同步至新表

    insert into biz_table_new(id,app_trade_no,trade_no,trade_sub_no,uid,account_type,relate_uid,relate_account_type,biz_type,biz_subtype,in_out,amount,balance_before,remark,extra,created_at,updated_at)
    select * from journal_2022 force index(PRIMARY)
    where  id>0 and id <=500000;select sleep(10);
    
    insert into biz_table_new(id,app_trade_no,trade_no,trade_sub_no,uid,account_type,relate_uid,relate_account_type,biz_type,biz_subtype,in_out,amount,balance_before,remark,extra,created_at,updated_at)
    select * from biz_table force index(PRIMARY)
    where  id>500000 and id <=1000000;select sleep(10);
            
    ....        
    
    1. 分批次查询,根据步长设置区间
    2. 每次执行完毕休眠10s
  4. 验证数据一致性,截止到first_max_id的数据同步完成

    1. 根据max_id 验证历史数据是否一致
     select count(1) from biz_table where id<=37509688;
     select count(1) from biz_table_new where id<=37509688;
    
  5. 评估1分钟后的increment值

    1. 查询当前max_id 如:37609688
    2. 当前业务,增长量 ,计算1分钟内的数据量,如:200000
    3. 得出预计的increment 值 如:37609688+200000=37809688
  6. 执行表迁移

    1. 设置新表的Increment 值
    2. 重命名 biz_table 为 biz_table_bak
    3. 重命名 new_table 为 biz_table
     alter table biz_table_new  AUTO_INCREMENT =37809688;
     rename table biz_table to biz_table_bak;
     rename table biz_table_new to biz_table;
    
  7. 同步新增数据量

    1. 计算biz_table_bak 的max_id 为 last_max_id 如 37808688
    2. 根据first_max_id () 、last_max_id 获取此区间数据,同步至新表
    insert into biz_table_new(id,app_trade_no,trade_no,trade_sub_no,uid,account_type,relate_uid,relate_account_type,biz_type,biz_subtype,in_out,amount,balance_before,remark,extra,created_at,updated_at)
    select * from biz_table force index(PRIMARY)
    where  id>37509688 and id <=37808688
    
  8. 数据同步完毕

三、GO脚本分享

  • 脚本
package utils

import "fmt"

const diffTmp = `
insert into %s(id,uid,account_type,balance,frozen,status,created_at,updated_at,app_alias)
     select *,"lailiao" as app_alias from %s_bak force index(PRIMARY)
     where  id>%d and id <=%d;select sleep(1);
`


func SyncDataV2(tmp string, oldTable, newTable string, step, minId, maxId int) string {
	if tmp == "" {
		tmp = defaultTmp
	}
	var sql string
	if minId < 0 {
		minId = 0
	}

	var nextId int
	for i := minId; i < maxId; i++ {
		nextId = minId + step
		if nextId > maxId {
			nextId = maxId
		}
		sql += fmt.Sprintf(tmp, newTable, oldTable, minId, nextId)
		minId = nextId
		if minId == maxId {
			break
		}
	}

	return sql
}

func SyncDiffData(tmp string, oldTable, newTable string, step, minId, maxId int) string {
	if tmp == "" {
		tmp = diffTmp
	}
	var sql string
	if minId < 0 {
		minId = 0
	}

	var nextId int
	for i := minId; i < maxId; i++ {
		nextId = minId + step
		if nextId > maxId {
			nextId = maxId
		}
		sql += fmt.Sprintf(tmp, newTable, oldTable, minId, nextId)
		minId = nextId
		if minId == maxId {
			break
		}
	}

	return sql
}

func VerifyData(oldTable, newTable string, max int) string {
	sql := fmt.Sprintf("select count(1) from %s where id<=%d;", oldTable, max)
	sql += fmt.Sprintf("select count(1) from %s where id<=%d;", newTable, max)
	return sql
}

func RenameTable(oldTable, newTable string, incrementId int) (sql string) {
	sql += fmt.Sprintf("alter table %s  AUTO_INCREMENT =%d;", newTable, incrementId)
	sql += fmt.Sprintf("rename table %s to %s;", oldTable, oldTable+"_bak")
	sql += fmt.Sprintf("rename table %s to %s;", newTable, oldTable)
	return sql
}

  • 测试用例
func TestAccount(t *testing.T) {
	oldTable := "account"
	newTable := "account_new"

	//同步历史数据
	step := 100000
	min := 0
	max := 952317 //数据表max_id
	tmp := `
	insert into %s(id,uid,account_type,balance,frozen,status,created_at,updated_at,app_alias)
	select *,"xxx" as app_alias from %s force index(PRIMARY)
	where  id>%d and id <=%d;select sleep(10);
	`

  
	template := SyncDataV2(tmp, oldTable, newTable, step, min, max)
	t.Log(template)

	//验证数据一致性
	verify := VerifyData(oldTable, newTable, max)
	t.Log("Verify:\n",verify)

	//变更表名
	increment := max + 20000
	sql := RenameTable(oldTable, newTable, increment)
	t.Log("SyncData:\n",sql)


	//同步新增数据
	tmp = `
	insert into %s(id,uid,account_type,balance,frozen,status,created_at,updated_at,app_alias)
     select *,"lailiao" as app_alias from %s_bak force index(PRIMARY)
     where  id>%d and id <=%d;select sleep(1);
`
	template = SyncDiffData(tmp, oldTable, oldTable, step, max, increment)
	t.Log(template)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue-脚手架的创建

本篇vue3的脚手架主要是使用vue-cli进行创建&#xff0c;有网的情况下才能创建成功 文章目录一、下载node.js二、全局安装vue/cli三、使用vue-cli创建项目3.1 使用vscode打开终端3.2 创建项目3.3 创建成功四、注意事项一、下载node.js 1、打开node的官网 node官网 2、点击下方图…

Oxygen XML Editor 25.0.X Crack

XML 编辑器 Oxygen XML Editor 是完整的 XML 编辑解决方案&#xff0c;适用于 XML 开发人员和内容作者。它提供了必备的 XML 编辑工具&#xff0c;涵盖了大多数 XML 标准和技术。Oxygen XML Editor 包括 Oxygen XML Developer 和 Author 的所有功能。 特点与技术 单一来源出版 …

【树莓派不吃灰】使用frp内网穿透,实现远程访问树莓派

目录1. 前言2. frp内网穿透2.1 概述2.2 实现原理3. 开源frp项目4. 公网服务器选型5. 下载frp软件5.1 公网服务器下载frp服务器5.1.1 github选择适合服务端的版本5.1.2 公网服务器进行下载解压5.2 树莓派下载frp客户端5.2.1 github选择适合客户端的版本5.2.2 树莓派进行下载解压…

流形上的预积分(上)

预积分和流形 论文&#xff1a;IMU Preintegration on Manifold for Effificient Visual-Inertial Maximum-a-Posteriori Estimation 引言 Recent results in monocular visual-inertial navigation (VIN) have shown that optimization-based approaches outperform filteri…

免费体验CSDN云IDE使用指南

云IDE产品介绍 云IDE使用教程 免费使用地址&#xff1a;点击【云IDE】&#xff0c;即可开始创建工作空间啦~ 官方活动入口 文章目录1.免费体验CSDN云IDE使用指南1.1云IDE优点2.自己的代码在云IDE上跑起来看看如何操作2.1 克隆开源仓库2.2 创建一个空工作空间2.3 使用默认模板代…

Thread类中run和start的区别

一.认识 Thread类 中的 start() 和 run() 首先来看一张jdk-api中对于start 和 run 的描述. 二.方法的区别 下面我们简单看一下代码: // 继承Thread类 重写run() class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("thread&q…

如何通过点击商品的信息(图片或者文字)跳转到更加详细的商品信息介绍(前后端分离之Vue实现)

以下只是做简单的演示、大致实现的效果。页面效果需要进一步优化。目的是提供思路 视频效果&#xff1a; 首页商品跳转1、需求 1、首页的的商品来自接口数据2、在首页点击某一个商品跳转到更加详细的商品介绍页面&#xff08;可以购买、加入购物车、查看商品评价信息等&#x…

频频出现的DevOps到底是什么呢?浅浅了解下什么是DevOps吧

文章目录 &#x1f4d1;前言 &#x1f9e9;DevOps的概念和起源 &#x1f4f0;DevOps的概念 &#x1f4f0;DevOps的起源与发展 &#x1f4f0;总结 &#x1f9e9;DevOps的发展 &#x1f4f0;发展过程速览 &#x1f4f0;发展现状 &#x1f4f0;未来发展 &#x1f4c4;以…

【前端】JavaScript数据类型

目录 一、数据类型简介 二、简单数据类型 数字型Number 1.数字型进制 2.数字型范围 3.数字型三个特殊值 4.isNaN() 字符串型String 1.字符串引号嵌套 2.字符串转义符 3.字符串长度 4.字符串拼接 布尔型Boolean Undefined和Null 三、获取变量数据类型 四、数据类型…

res.add(new ArrayList<>(path))和res.add(path)的区别

一.问题描述 在链表path里面添加值&#xff0c;之后把path链表添加到res链表中&#xff0c;自己做的时候使用res.add(path)&#xff0c;结果发现出现解答错误。 题目链接&#xff1a;113. 路径总和 II - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; class …

网络初始之网络协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 1.局域网&#xff1a; 概念&#xff1a; 构建方式 2.广域网&#xff1a; 3.IP地址&#xff1a; 4. 端口号&#xff1a; 常考点&#xff1a; 一、…

【单端S参数与差分S参数转化】

单端S参数与差分S参数转化 1 单端S参数说明 对于单端信号来说&#xff0c;用单端S参数来描述其传输特性&#xff0c;如常见的2端口网络&#xff0c;其S参数包括S11&#xff08;1端口回波损耗RL&#xff09;、S21&#xff08;插入损耗IL&#xff09;、S12&#xff08;插入损耗…

[JSON] JSON基础知识

JSON(JavaScript Object Notation&#xff0c;JavaScript对象表简谱)是一种轻量级的数据交换格式&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据 JSON文件的文件类型是.json JSON是纯文本&#xff0c;具有层级结构&#xff0c;易于阅读和编写&#xff0c;其本…

【愚公系列】2022年11月 微信小程序-优购电商项目-商品支付页面

文章目录前言1. 商品⽀付页面设计规范一、商品支付页面1.业务逻辑2.涉及的接口数据3. 关键技术二、商品购物车页面相关代码1.页面代码2.效果前言 1. 商品⽀付页面设计规范 第一、支付流程一定要简单。现代人的生活节奏是非常快速的&#xff0c;而且情绪比较浮躁。当用户在浏览…

深入理解Java内存区域(最新版面试题)

1、什么是JVM&#xff1f; JVM&#xff08;Java Virtual Machine&#xff09;是用于运行Java字节码的虚拟机&#xff0c;包括一套字节码指令集、一组程序寄存器、一个虚拟机栈、一个虚拟机堆、一个方法区和一个垃圾回收器。JVM运行在操作系统之上&#xff0c;不与硬件设备直接交…

微信小程序消息订阅Java

前言 编写日期 : 2022-11-04 写这篇文章原因 公司给政府做一个订餐系统&#xff0c;需要在员工在小程序上发起订餐后经过部门领导和书记的审批后&#xff0c;再由食堂确认订餐结果。在订餐审批单在各个节点流转的过程中&#xff0c;需要给每一个节点的审批人发送微信订阅消息…

Linux企业应用——Docker(三)之史上最简单,一篇学会Docker私有仓库Harbor的搭建

文章目录一、什么是Harbor二、搭建私有仓库1.安装docker-ce2.安装软件库包3.创建认证三、在另一台已安装docker的主机上四、搭建Harbor测试docker hub虽然方便&#xff0c;但是还是有限制&#xff1a;• 需要internet连接&#xff0c;速度慢• 所有人都可以访问• 由于安全原因…

SharpShooter Reports.Web 7.5 Crack

SharpShooter Reports.Web 是真正的跨平台报告查看器&#xff0c;因为它能够向 Windows、Linux、Mac OS 甚至 iOS 和 Android 平板电脑和手机提供报告。创建的报告可以轻松集成到任何网站和网页中&#xff0c;包括 MS MVC 和 ASP.NET 应用程序。by Ω578867473报告设计方便易用…

22级第三次比赛题解

文章目录A (1). Ashy与几何(贪心几何)B (2). One eye question of hengheng(前缀和)C Fox hate oranges(模拟)D KingZhangs Similar pair (思维)E (5). 38秒你敢交我A题&#xff1f;F (6). How many numbers are thereG (7). Jump lattice (思维)H (8). CCoolGuang Conjecture(…

五十万字总结,2022最新Java面试八股汇总(含答案,收藏版)

写在前面 今年的疫情&#xff0c;让招聘面试变得雪上加霜。已经有不少大厂&#xff0c;如腾讯、字节跳动的招聘名额明显减少&#xff0c;面试门槛却一再拔高&#xff0c;如果不用心准备&#xff0c;很可能就被面试官怼得哑口无言&#xff0c;甚至失去了难得的机会。 现如今&a…