mysql-online-ddl是否需要rebuild
一、背景
DDL一直是DBA业务中的大项,看了TIDB的DDL讲解,恰巧我们的mysql业务大表也遇到了DDL的变更项,变更内容是将varchar(10)变更成varchar(20),这个变更通过官方文档很容易知道是不需要rebuild的(这里要注意下这个varchar(255)的临界值与字符集有关,如果是utf8则为255/3,如果是utf8mb4则为255/4),但是问题是这个字段是索引字段,所以这里我就不太确定了,那么怎么办呢,解决办法就是看源码和测试了。
二、实验
1.打开性能监控
我们可以从官网的文章1,文章2中明白性能监控是如何打开的
mysql> UPDATE performance_schema.setup_instrumentsSET ENABLED = 'YES'WHERE NAME LIKE 'stage/innodb/alter%';
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7 Changed: 7 Warnings: 0mysql> UPDATE performance_schema.setup_consumersSET ENABLED = 'YES'WHERE NAME LIKE '%stages%';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
2.建表并准备测试数据
# 创建表
mysql> create table ddl_test(id int(10) unsigned not null auto_increment primary key,name varchar(20) not null,email varchar(30) not null,key idx_name_mail(name,email));
Query OK, 0 rows affected (0.02 sec)
# 创建存储过程插入数据
DELIMITER //
CREATE PROCEDURE insert_test_data(in record int)
BEGIN
DECLARE num INT DEFAULT 0;
START TRANSACTION;
WHILE num <= record DOINSERT INTO ddl_test(name, email) values(concat("asd",num),concat("uvw",num));SET num = num+1;
END WHILE;
COMMIT;
END //
DELIMITER ;
# 调用存储过程
call insert_test_data(1000000);
# 删除存储过程drop procedure insert_test_data;
3.更改字段长度并查看性能监控
# 查看版本
mysql> select @@version;
+------------+
| @@version |
+------------+
| 5.7.22-log |
+------------+
1 row in set (0.16 sec)
# 清空事件监控表
truncate table performance_schema.events_stages_history;
# 变更测试表字段长度
alter table ddl_test change name name varchar(23) NOT NULL;
# 查看时间监控表,通过下面可以看到明显进行了rebuild操作
mysql> select * from performance_schema.events_stages_history;
+-----------+----------+--------------+------------------------------------------------------+----------------+----------------------+----------------------+---------------+----------------+----------------+------------------+--------------------+
| THREAD_ID | EVENT_ID | END_EVENT_ID | EVENT_NAME | SOURCE | TIMER_START | TIMER_END | TIMER_WAIT | WORK_COMPLETED | WORK_ESTIMATED | NESTING_EVENT_ID | NESTING_EVENT_TYPE |
+-----------+----------+--------------+------------------------------------------------------+----------------+----------------------+----------------------+---------------+----------------+----------------+------------------+--------------------+
| 1222844 | 4000077 | 4000077 | stage/innodb/alter table (read PK and internal sort) | ut0stage.h:241 | 10065196379488577152 | 10065197613867973152 | 1234379396000 | 5526 | 11290 | 4000076 | STATEMENT |
| 1222844 | 4000078 | 4000078 | stage/innodb/alter table (merge sort) | ut0stage.h:501 | 10065197613867973152 | 10065198518747528152 | 904879555000 | 8289 | 12306 | 4000076 | STATEMENT |
| 1222844 | 4000079 | 4000079 | stage/innodb/alter table (insert) | ut0stage.h:501 | 10065198518747528152 | 10065198836121509152 | 317373981000 | 11052 | 12845 | 4000076 | STATEMENT |
| 1222844 | 4000080 | 4000080 | stage/innodb/alter table (flush) | ut0stage.h:501 | 10065198836121509152 | 10065200599444653152 | 1763323144000 | 12845 | 12845 | 4000076 | STATEMENT |
| 1222844 | 4000081 | 4000081 | stage/innodb/alter table (log apply index) | ut0stage.h:501 | 10065200599444653152 | 10065200599846345152 | 401692000 | 13229 | 13229 | 4000076 | STATEMENT |
| 1222844 | 4000082 | 4000082 | stage/innodb/alter table (flush) | ut0stage.h:501 | 10065200599846345152 | 10065200599869246152 | 22901000 | 13229 | 13229 | 4000076 | STATEMENT |
| 1222844 | 4000083 | 4000083 | stage/innodb/alter table (end) | ut0stage.h:501 | 10065200599873146152 | 10065200615285329152 | 15412183000 | 13229 | 13229 | 4000076 | STATEMENT |
+-----------+----------+--------------+------------------------------------------------------+----------------+----------------------+----------------------+---------------+----------------+----------------+------------------+--------------------+
7 rows in set (0.07 sec)
三、源码
1.inplace_alter所需的几大操作步骤:
源码地址
enum_alter_inplace_result check_if_supported_inplace_alter(TABLE* altered_table,Alter_inplace_info* ha_alter_info);/** Allows InnoDB to update internal structures with concurrent
writes blocked (provided that check_if_supported_inplace_alter()
did not return HA_ALTER_INPLACE_NO_LOCK).
This will be invoked before inplace_alter_table().
@param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done
by ALTER TABLE and holding data used during in-place alter.
@retval true Failure
@retval false Success
*/
bool prepare_inplace_alter_table(TABLE* altered_table,Alter_inplace_info* ha_alter_info);/** Alter the table structure in-place with operations
specified using HA_ALTER_FLAGS and Alter_inplace_information.
The level of concurrency allowed during this operation depends
on the return value from check_if_supported_inplace_alter().
@param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done
by ALTER TABLE and holding data used during in-place alter.
@retval true Failure
@retval false Success
*/
bool inplace_alter_table(TABLE* altered_table,Alter_inplace_info* ha_alter_info);/** Commit or rollback the changes made during
prepare_inplace_alter_table() and inplace_alter_table() inside
the storage engine. Note that the allowed level of concurrency
during this operation will be the same as for
inplace_alter_table() and thus might be higher than during
prepare_inplace_alter_table(). (E.g concurrent writes were
blocked during prepare, but might not be during commit).
@param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done
by ALTER TABLE and holding data used during in-place alter.
@param commit true => Commit, false => Rollback.
@retval true Failure
@retval false Success
*/
bool commit_inplace_alter_table(TABLE* altered_table,Alter_inplace_info* ha_alter_info,bool commit);
/** @} */bool check_if_incompatible_data(HA_CREATE_INFO* info,uint table_changes);
2.alter操作的几种类型划分:
源码地址
/** Operations for creating secondary indexes (no rebuild needed) */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE= Alter_inplace_info::ADD_INDEX| Alter_inplace_info::ADD_UNIQUE_INDEX| Alter_inplace_info::ADD_SPATIAL_INDEX;/** Operations for rebuilding a table in place */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD= Alter_inplace_info::ADD_PK_INDEX| Alter_inplace_info::DROP_PK_INDEX| Alter_inplace_info::CHANGE_CREATE_OPTION/* CHANGE_CREATE_OPTION needs to check innobase_need_rebuild() */| Alter_inplace_info::ALTER_COLUMN_NULLABLE| Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE| Alter_inplace_info::ALTER_STORED_COLUMN_ORDER| Alter_inplace_info::DROP_STORED_COLUMN| Alter_inplace_info::ADD_STORED_BASE_COLUMN| Alter_inplace_info::RECREATE_TABLE/*| Alter_inplace_info::ALTER_STORED_COLUMN_TYPE*/;/** Operations that require changes to data */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_DATA= INNOBASE_ONLINE_CREATE | INNOBASE_ALTER_REBUILD;/** Operations for altering a table that InnoDB does not care about */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_IGNORE= Alter_inplace_info::ALTER_COLUMN_DEFAULT| Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT| Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE| Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR| Alter_inplace_info::ALTER_RENAME;/** Operations on foreign key definitions (changing the schema only) */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_FOREIGN_OPERATIONS= Alter_inplace_info::DROP_FOREIGN_KEY| Alter_inplace_info::ADD_FOREIGN_KEY;/** 整理重点看下,改变字段长度其实就是改变了索引的长度 */
/** Operations that InnoDB cares about and can perform without rebuild */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD= INNOBASE_ONLINE_CREATE| INNOBASE_FOREIGN_OPERATIONS| Alter_inplace_info::DROP_INDEX| Alter_inplace_info::DROP_UNIQUE_INDEX| Alter_inplace_info::RENAME_INDEX| Alter_inplace_info::ALTER_COLUMN_NAME//这里的PACK_LENGTH要注意,也可以理解成字段长度的变化,实际是指字段存储的大小的变化,比如字段是varchar,utf8mb4来看,那么varchar(10)和varchar(63)的PACK_LENGTH都是相等的| Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH| Alter_inplace_info::ALTER_INDEX_COMMENT| Alter_inplace_info::ADD_VIRTUAL_COLUMN| Alter_inplace_info::DROP_VIRTUAL_COLUMN| Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER//Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;这个定义是5.7.23才开始有的| Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;/* | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE; */
3.这里解释了什么是索引长度变更:
源码地址
/**Change column datatype in such way that new type has compatiblepacked representation with old type, so it is theoreticallypossible to perform change by only updating data dictionarywithout changing table rows.
*/
static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14;/**Change in index length such that it does not require index rebuild.For example, change in index length due to column expansion likevarchar(X) changed to varchar(X + N).
*/
static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH = 1ULL << 42;
4.这里定义了algorithm和lock的划分:
源码地址
/**Data describing the table being created by CREATE TABLE oraltered by ALTER TABLE.
*/class Alter_info
{
public:/*These flags are set by the parser and describes the type ofoperation(s) specified by the ALTER TABLE statement.They do *not* describe the type operation(s) to be executedby the storage engine. For example, we don't yet know thetype of index to be added/dropped.*/// Set for CHANGE [COLUMN] | MODIFY [CHANGE]// Set by mysql_recreate_table()static const uint ALTER_CHANGE_COLUMN = 1L << 2;// Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULTstatic const uint ALTER_CHANGE_COLUMN_DEFAULT = 1L << 8;enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };/**The different values of the ALGORITHM clause.Describes which algorithm to use when altering the table.*/enum enum_alter_table_algorithm{// In-place if supported, copy otherwise.ALTER_TABLE_ALGORITHM_DEFAULT,// In-place if supported, error otherwise.ALTER_TABLE_ALGORITHM_INPLACE,// Copy if supported, error otherwise.ALTER_TABLE_ALGORITHM_COPY};/**The different values of the LOCK clause.Describes the level of concurrency during ALTER TABLE.*/enum enum_alter_table_lock{// Maximum supported level of concurency for the given operation.ALTER_TABLE_LOCK_DEFAULT,// Allow concurrent reads & writes. If not supported, give erorr.ALTER_TABLE_LOCK_NONE,// Allow concurrent reads only. If not supported, give error.ALTER_TABLE_LOCK_SHARED,// Block reads and writes.ALTER_TABLE_LOCK_EXCLUSIVE};/**Status of validation clause in ALTER TABLE statement. Used duringpartitions and GC alterations.*/enum enum_with_validation{/**Default value, used when it's not specified in the statement.Means WITH VALIDATION for partitions alterations and WITHOUT VALIDATIONfor altering virtual GC.*/ALTER_VALIDATION_DEFAULT,ALTER_WITH_VALIDATION,ALTER_WITHOUT_VALIDATION};
5.这里是变更索引长度的具体逻辑:
源码地址
for (key_part= table_key->key_part, new_part= new_key->key_part;key_part < end;key_part++, new_part++){new_field= get_field_by_index(alter_info, new_part->fieldnr);/*If there is a change in index length due to column expansionlike varchar(X) changed to varchar(X + N) and has a compatiblepacked data representation, we mark it for fast/INPLACE changein index definition. Some engines like InnoDB supports INPLACEalter for such cases.In other cases, key definition has changed if we are using adifferent field or if the used key part length is different, orkey part direction has changed.*/if (key_part->length != new_part->length &&ha_alter_info->alter_info->flags == Alter_info::ALTER_CHANGE_COLUMN &&(key_part->field->is_equal((Create_field *)new_field) == IS_EQUAL_PACK_LENGTH)){ha_alter_info->handler_flags|=Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;}else if (key_part->length != new_part->length)return true;
6.具体分析
我们通过上面的2,3,5可以发现,ALTER_COLUMN_INDEX_LENGTH在PACK_LENGTH(这个pack_length在varchar的保存实际内容的长度,而我们是utf8mb4,所以临界值是255/4=64,所以变更前后的pack_length相同)不变的情况下是norebuild的,但是我们上面的实验也确实出现了rebuild,那么这是为什么呢,我在注释中也写了,ALTER_COLUMN_INDEX_LENGTH是在5.7.23中才开始加的,而我们的实验环境是5.7.22,所以才会进行rebuild
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD= INNOBASE_ONLINE_CREATE| Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER//Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;这个定义是5.7.23才开始有的| Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;
四、再次实验确定
我们采用5.7.30进行实验,发现performance_schema.events_stages_history的内容为空,所以我们的判断是正确的
总结:
初次探索源码,有很多地方可能理解的不对,之后会学习些DDL相关的如加MDL锁,rebuild等等的具体操作,欢迎各位大佬指出不足之处
相关文章:

mysql-online-ddl是否需要rebuild
一、背景 DDL一直是DBA业务中的大项,看了TIDB的DDL讲解,恰巧我们的mysql业务大表也遇到了DDL的变更项,变更内容是将varchar(10)变更成varchar(20),这个变更通过官方文档很容易知道是不需要rebuild的(这里要注意下这个varchar(255…...

力扣-超过经理收入的员工
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:181. 超过经理收入的员工二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其…...
决策树基础知识点解读
目录 ID3算法 C4.5算法 CART树 ID3算法 定义:在决策树各个结点上应用信息增益准则选择特征,递归的构建决策树。该决策树是多分支分类。 信息增益 意义:给定特征X的条件下,使得类别Y的信息的不确定性减少的程度。取值越大越好。 定义&am…...

【C++】入门知识之 命名空间与输入输出
前言C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(object oriented …...

redis持久化的几种方式
一、简介 Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持…...

数据持久化层--查询分离
1. 业务场景 1)查询慢。当时工单数据库里面有1000万左右的客服工单时,每次查询时需要关联其他近10个表,一次查询平均花费13秒左右。 2)打开工单慢。工单打开以后需要调用多个接口,分别将用户信息、订单信息以及其他客服创建的单据信息列出来(如退款、赔偿、充值、投诉等…...
一文读懂Js中的this指向
前言 this关键字是一个非常重要的语法点。毫不夸张地说,不理解它的含义,大部分开发任务都无法完成。 简单说,this就是属性或方法“当前”所在的对象。 this.property上面代码中,this就代表property属性当前所在的对象。 下面是…...
零费用、零学习成本,用户快速可自定义json格式
随着物联网的发展,越来越多的设备被连接到互联网,数据量不断增加。这就需要有一种高效的方法来处理传输和处理这些数据。钡铼技术R40B边缘计算路由器,集成4G工业路由器、智能网关、RTU、DTU等产品多合一。支持边缘计算,它可以将计…...
2023年全国最新高校辅导员精选真题及答案25
百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 101.属于大学教师职业特征的是()。 A.教师劳动的复杂性 B.教师…...

二、数据结构-线性表
目录 🌻🌻一、线性表概述1.1 线性表的基本概念1.2 线性表的顺序存储1.2.1 线性表的基本运算在顺序表上的实现1.2.2 顺序表实现算法的分析1.2.3 单链表类型的定义1.2.4 线性表的基本运算在单链表上的实现1.3 其他运算在单链表上的实现1.3.1 建表1.3.2 删除…...

CGAL 点云上采样
目录一、算法原理1、主要函数2、参数解析二、代码实现三、结果展示一、算法原理 该方法对点集进行逐步上采样,同时根据法向量信息来检测边缘点,需要输入点云具有法线信息。在点云空洞填充和稀疏表面重建中具有较好的应用。 1、主要函数 头文件 #inclu…...

阿里云短信验证码实战
一、创建阿里云短信权限用户 1、登陆阿里云之后我们点击头像,接着点击AccessKey: 2、选择开始使用子用户 : 3、我们先要创建一个用户组: 4、依次点击新建的用户组——授权管理,给用户组授权,开通短信验证码服务…...

Android APP隐私合规检测工具Camille使用
目录一、简介二、环境准备常用使用方法一、简介 现如今APP隐私合规十分重要,各监管部门不断开展APP专项治理工作及核查通报,不合规的APP通知整改或直接下架。camille可以hook住Android敏感接口,检测是否第三方SDK调用。根据隐私合规的场景&a…...

手把手学会DFS (递归入门)
目录 算法介绍 递归实现指数型枚举 递归实现排列型枚举 递归实现组合型枚举 算法介绍 🧩DFS 即 Depth First Search ,中文又叫深度优先搜索,是一种沿着树的深度对其进行遍历,直到尽头之后再进行回溯,再走其他路线的…...

由《三体》太阳文明末日场景想到的……
《三体》电视剧正在热播,热度持续不退,豆瓣评分8.6,基本已经预定年度口碑最高的科幻题材剧;除了在国内多个平台播出外,还走出国门,成功“出海”,《人民日报》两会特刊都予以了高度赞扬。 上图红…...

es6的Proxy与Reflect
Proxy是在对目标对象的读取时,架设一层拦截,可以在读取对象中的任意一个属性时做一些额外的操作 Proxy与Object.defineProperty方式设置setter、getter方法不同的是,Proxy是对目标对象的整体拦截,而Object.defineProperty注重对对…...

Linux环境部署vue项目 + nginx访问(包含nginx配置简介)
1、本地打包、上传 # 打包命令不同项目有略微差别,核心命令 npm run build# 我们项目前端给配了测试、生产环境,测试环境打包命令是 npm run build:stage# 建议先看一下项目的README文件打包之后,得到一个文件夹,一般叫dist、也有…...

到底什么是跨域,如何解决跨域(常见的几种跨域解决方案)?
文章目录1、什么是跨域2、解决跨域的几种方案2.1、JSONP 方式解决跨域2.2、CORS 方式解决跨域(常见,通常仅需服务端修改即可)2.3、Nginx 反向代理解决跨域(推荐使用,配置简单)2.4、WebSocket 解决跨域2.5、…...

pm3包1.4版本发布----一个用于3组倾向性评分的R包
目前,本人写的第二个R包pm3包的1.4版本已经正式在CRAN上线,用于3组倾向评分匹配,只能3组不能多也不能少。 可以使用以下代码安装 install.packages("pm3")什么是倾向性评分匹配?倾向评分匹配(Propensity Sc…...

没有关系的话,那就去建立关系吧
今天给大家分享一道链表的好题--链表的深度拷贝,学会这道题,你的链表就可以达到优秀的水平了。力扣 先来理解一下题目意思,即建立一个新的单向链表,里面每个结点的值与对应的原链表相同,并且random指针也要指向新链表中…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...