MySQL系列-架构体系、日志、事务

MySQL架构

在这里插入图片描述
在这里插入图片描述

  • server 层 :层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等
  • 存储引擎层 :负责数据的存储和提取,支持 InnoDB、MyISAM、Memory 等多个存储引擎。你执行 create table 建表的时候,如果不指定引擎类型,默认使用的就是 InnoDB

redo log (重做日志) 和 binlog(二进制归档日志) undo log(回滚日志)

mysql的 redo log (重做日志) 和 binlog(二进制归档日志) undo log(回滚日志)的区别

MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,以 InnoDB 使用另外一套日志系统——也就是 redo log 来实现 crash-safe 能力;Mysql三个核心日志分别是 binlog(二进制日志) 、redo log(重做日志)、undo log(回滚日志), 这里面binlog 是server层的日志,而redo log 和undo log都是引擎层(innodb)的日志,其他数据引擎就没有redo log和undo log,例如myisam引擎就没有这2个日志,因为它不支持事物。

  • binlog(归档二进制日志) 是 MySQL 的 Server 层实现的,所有引擎都可以使用。​binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。Binlog可以作为主从复制和数据恢复使用。Binlog没有自动crash-safe;

  • redo log (重做日志模块)是 InnoDB 引擎特有的,是 MySQL 的 Server 层实现的;redo log 是物理日志,记录的是“在某个数据页上做了什么修改,记录数据页的修改状态”;redo log 是循环写的,空间固定会用完;redo log 是循环写的,空间固定会用完;Redo Log作为服务器异常宕机后事务数据自动恢复使用,WAL技术也是借助于redo log 来实现的;

在这里插入图片描述

binlog(二进制归档日志)日志详解

binlog 是作为mysql操作记录归档的日志,这个日志记录了所有对数据库的数据、表结构、索引等等变更的操作。也就是说只要是对数据库有变更的操作都会记录到binlog里面来;mysql里我们就是通过binlog来归档、验证、恢复、同步数据。

binlog 有三种记录格式,分别是ROW、STATEMENT、MIXED。

  1. ROW: 基于变更的数据行进行记录,如果一个update语句修改一百行数据,那么这种模式下就会记录100行对应的记录日志。
  • 优点:binlog 中可以不记录执行的 SQL 语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定情况下的存储过程、或 function、或trigger的调用和触发无法被正确复制的问题。
  • 缺点:可能会产生大量的日志内容。
  1. STATEMENT:基于SQL语句级别的记录日志,相对于ROW模式,STATEMENT模式下只会记录这个update 的语句。所以此模式下会非常节省日志空间,也避免着大量的IO操作。
  • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
  • 缺点:由于记录的只是执行语句,为了这些语句能在备库上正确运行,还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在备库得到和在主库端执行时候相同的结果。
  1. MIXED: 混合模式,此模式是ROW模式和STATEMENT模式的混合体,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog。

这三种模式需要注意的是:使用 row 格式的 binlog 时,在进行数据同步或恢复的时候不一致的问题更容易被发现,因为它是基于数据行记录的。而使用 mixed 或者 statement 格式的 binlog 时,很多事务操作都是基于SQL逻辑记录,我们都知道一个SQL在不同的时间点执行它们产生的数据变化和影响是不一样的,所以这种情况下,数据同步或恢复的时候就容易出现不一致的情况。

binlog 写入策略

在进行事务的过程中,首先会把binlog 写入到binlog cache中(因为写入到cache中会比较快,一个事务通常会有多个操作,避免每个操作都直接写磁盘导致性能降低),事务最终提交的时候再把binlog 写入到磁盘中。当然事务在最终commit的时候binlog是否马上写入到磁盘中是由参数 sync_binlog 配置来决定的。

  1. sync_binlog=0 的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多,不过在Mysql 崩溃的时候会有丢失日志的风险。

  2. sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘 ;

  3. sync_binlog的值大于1 的时候,表示每次提交事务都 先写到page cach,只有等到积累了N个事务之后才fsync 写入到磁盘,同样在此设置下Mysql 崩溃的时候会有丢失N个事务日志的风险。

很显然三种模式下,sync_binlog=1 是强一致的选择,选择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一致性的要求。

redolog

redolog 设计原理

redo log 是属于引擎层(innodb)的日志,它的设计目标是支持innodb的“事务”的特性,事务ACID特性分别是原子性、一致性、隔离性、持久性, 一致性是事务的最终追求的目标,隔离性、原子性、持久性是达成一致性目标的手段,根据的文章我们已经知道隔离性是通过锁机制来实现的。 而事务的原子性和持久性则是通过redo log 和undo log来保障的

redo log 能保证对于已经COMMIT的事务产生的数据变更,即使是系统宕机崩溃也可以通过它来进行数据重做,达到数据的一致性,这也就是事务持久性的特征,一旦事务成功提交后,只要修改的数据都会进行持久化,不会因为异常、宕机而造成数据错误或丢失,所以解决异常、宕机而可能造成数据错误或丢是redo log的核心职责。

redolog 记录内容

redo log记录的是操作数据变更的日志,听起来好像和binlog有类似的地方,有时候我都会想有了binlog为什么还要redo log,当然从其它地方可以找到很多的理由,但是我认为最核心的一点就是redo log记录的数据变更粒度和binlog的数据变更粒度是不一样的,也正因为这个binlog是没有进行崩溃恢复事务数据的能力的。

以修改数据为例,binlog 是以表为记录主体,在ROW模式下,binlog保存的表的每行变更记录。

比如update tb_user set age =18 where name =‘张三’ ,如果这条语句修改了三条记录的话,那么binlog记录就是

 UPDATE `db_test`.`tb_user` WHERE @1=5 @2='张三' @3=91 @4='1543571201' SET  @1=5 @2='张三' @3=18 @4='1543571201'
 UPDATE `db_test`.`tb_user` WHERE @1=6 @2='张三' @3=91 @4='1543571201' SET  @1=5 @2='张三' @3=18 @4='1543571201'
 UPDATE `db_test`.`tb_user` WHERE @1=7 @2='张三' @3=91 @4='1543571201' SET  @1=5 @2='张三' @3=18 @4='1543571201'

redo log则是记录着磁盘数据的变更日志,以磁盘的最小单位“页”来进行记录。上面的修改语句,在redo log里面记录得可能就是下面的形式。

 把表空间10、页号5、偏移量为10处的值更新为18。
 把表空间11、页号1、偏移量为2处的值更新为18。
 把表空间12、页号2、偏移量为9处的值更新为18

当我们把数据从内存保存到磁盘的过程中,Mysql是以页为单位进行刷盘的,这里的页并不是磁盘的页,而是Mysql自己的单位,Mysql里的一页数据单位为16K,所以在刷盘的过程中需要把数据刷新到磁盘的多个扇区中去。 而把16K数据刷到磁盘的每个扇区里这个过程是无法保证原子性的,也就意味着Mysql把数据从内存刷到磁盘的过程中,如果数据库宕机,那么就可能会造成一步分数据成功,一部分数据失败的结果。而这个时候通过binlog这种级别的日志是无法恢复的,一个update可能更改了多个磁盘区域的数据,如果根据SQL语句回滚,那么势必会让那些已经刷盘成功的数据造成数据不一致。所以这个时候还是得需要通过redo log这种记录到磁盘数据级别的日志进行数据恢复。

redolog 写入策略

redo log占用的空间是一定的,并不会无线增大(可以通过参数设置),写入的时候是进顺序写的,所以写入的性能比较高。当redo log空间满了之后又会从头开始以循环的方式进行覆盖式的写入。

在写入redo log的时候也有一个redo log buffer,日志什么时候会刷到磁盘是通过innodb_flush_log_at_trx_commit 参数决定。

当设置为0的时候,事务提交时不会将log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到log file on disk中。也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。
当设置为1的时候,事务每次提交都会将log buffer中的日志写入os buffer并调用fsync()刷到log file on disk中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。
当设置为2的时候,每次提交都仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到log file on disk。
除了上面几种机制外,还有其它两种情况会把redo log buffer中的日志刷到磁盘。

  1. 定时处理:有线程会定时(每隔 1 秒)把redo log buffer中的数据刷盘。
  2. 根据空间处理:redo log buffer 占用到了一定程度( innodb_log_buffer_size 设置的值一半)占,这个时候也会把redo log buffer中的数据刷盘。

redo log包括两部分内容,分别是内存中的日志缓冲(redo log buffer)和磁盘上的日志文件(redo log file)。

MySQL 每执行一条 DML 语句,会先把记录写入 redo log buffer(用户空间) ,再保存到内核空间的缓冲区 OS-buffer 中,后续某个时间点再一次性将多个操作记录写到 redo log file(刷盘) 。这种先写日志,再写磁盘的技术,就是WAL。

undolog

undolog 设计目标

redo log 是也属于引擎层(innodb)的日志,从上面的redo log介绍中我们就已经知道了,redo log 和undo log的核心是为了保证innodb事务机制中的持久性和原子性,事务提交成功由redo log保证数据持久性,而事务可以进行回滚从而保证事务操作原子性则是通过undo log 来保证的。

要对事务数据回滚到历史的数据状态,所以我们也能猜到undo log是保存的是数据的历史版本,通过历史版本让数据在任何时候都可以回滚到某一个事务开始之前的状态。undo log除了进行事务回滚的日志外还有一个作用,就是为数据库提供MVCC多版本数据读的功能。

undolog 记录内容

在Mysql里数据每次修改前,都首先会把修改之前的数据作为历史保存一份到undo log里面的,数据里面会记录操作该数据的事务ID,然后我们可以通过事务ID来对数据进行回滚。

比如我们执行 update user_info set name =“李四”where id=1的时候。整个undo log的记录形式会如下。
1、首先准备一张原始原始数据表
在这里插入图片描述
2、开启一个事务A: 对user_info表执行 update user_info set name =“李四”where id=1 会进行如下流程操作

1、首先获得一个事务编号 104

2、把user_info表修改前的数据拷贝到undo log

3、修改user_info表 id=1的数据

4、把修改后的数据事务版本号改成 当前事务版本号,并把DB_ROLL_PTR 地址指向undo log数据地址。

3、最后执行完结果如图:
在这里插入图片描述
redo、undo、binlog的生成流程与崩溃恢复

当我们执行update user_info set name =“李四”where id=1 的时候大致流程如下:

  1. 从磁盘读取到id=1的记录,放到内存。
  2. 记录undo log 日志。
  3. 记录redo log (预提交状态)
  4. 修改内存中的记录。
  5. 记录binlog
  6. 提交事务,写入redo log (commit状态)
    在这里插入图片描述
    我们根据上面的流程来看,如果在上面的某一个阶段数据库崩溃,如何恢复数据。

1 . 在第一步、第二步、第三步执行时据库崩溃:因为这个时候数据还没有发生任何变化,所以没有任何影响,不需要做任何操作。
2. 在第四步修改内存中的记录时数据库崩溃:因为此时事务没有commit,所以这里要进行数据回滚,所以这里会通过undo log进行数据回滚。
3. 第五步写入binlog时数据库崩溃:这里和第四步一样的逻辑,此时事务没有commit,所以这里要进行数据回滚,会通过undo log进行数据回滚。
4. 执行第六步事务提交时数据库崩溃:如果数据库在这个阶段崩溃,那其实事务还是没有提交成功,但是这里并不能像之前一样对数据进行回滚,因为在提交事务前,binlog可能成功写入磁盘了,所以这里要根据两种情况来做决定。

  • 如果binlog存在事务记录:那么就"认为"事务已经提交了,这里可以根据redo log对数据进行重做。其实你应该有疑问,其实这个阶段发生崩溃了,最终的事务是没提交成功的,这里应该对数据进行回滚。 这里主要的一个考虑是因为binlog已经成功写入了,而binlog写入后,那么依赖于binlog的其它扩展业务(比如:从库已经同步了日志进行数据的变更)数据就已经产生了,如果这里进行数据回滚,那么势必就会造成主从数据的不一致。
  • 另外一种情况就 是binlog不存在事务记录,那么这种情况事务还未提交成功,所以会对数据进行回滚。

如果MySQL挂了,怎么办?
例如有一个修改数据的请求到MySQL服务上,对于业务代码来说,方才执行的事务是OK的,甚至前端都接受到了请求成功的响应。那结果修改的数据没同步回磁盘,MySQL宕机了会不会导致真实数据和逻辑上的数据不一致呢?其实不会的!
MySQL使用redo log解决了这个问题,redo顾名思义:重做。
当发生事务(增、删、改)时会导致缓存页变成脏页,于此同时MySQL会将事务涉及到的:对 XXX表空间中的XXX数据页XXX偏移量的地方做了XXX更新。
所以MySQL意外宕机重启也没关系。只要在重启时解析redo log中的事务然后重放遍。将Buffer Pool中的缓存页重做成脏页。后续再在合适的时机将该脏页刷入磁盘即可。

mysql的 CrashSafe能力

CrashSafe指MySQL服务器宕机重启后,能够保证:

  • 所有已经提交的事务的数据仍然存在。
  • 所有没有提交的事务的数据自动回滚。

如果MySQL宕机了,重启后,就需要检查redolog 日志文件里面,系统会自动定位到上次checkpoint的位置,同时,每个数据页中也存在一个LSN,当redo log中的LSN大于数据页中的LSN时,说明重启前redo log中的数据未完全写入数据页中,那么将从数据页中记录的LSN开始,从redo log中恢复数据。

mysql的 WAL技术(预写日志技术)

在这里插入图片描述

WAL的全称是Write Ahead Logging, 它的关键点就是先写日志, 再写磁盘. 日志是顺序写的, 磁盘是随机写. 顺序写速度是比随机写快的. 具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log的(记录板文件)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做;InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写;如果记录满了的话,擦除记录前要把记录更新到数据文件。有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。

两段提交

为了保证binlog 和 redolog两份日志最终恢复到数据库的数据是一致的,采用两阶段提交的机制。
例如现在有一个数据更新的sql

update T set c=c+1 where ID=2;

update 语句流程

  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内 存,然后再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的 一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状 态,更新完成。

在这里插入图片描述

两段提交的必要性

假设redo log和binlog分别提交,可能会造成用日志恢复出来的数据和原来数据不一致的情况。

情况一: 先写redolog再写binlog
如果在一条语句redolog之后崩溃了,binlog则没有记录这条语句。系统在用binlog恢复从库时便会少了这一次的修改。恢复的从库少了这条更新。
情况二:先写binlog再写redolog
如果在一条语句binlog之后崩溃了,redolog则没有记录这条语句(可以理解为主库没有)。系统在用binlog恢复从库时便会多了这一次的修改。恢复的从库多了这条更新。
由此可见,如果不使用两阶段提交,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

两段提交崩溃恢复

采用两阶段提交,在做崩溃恢复(Crash recovery)时分为以下3种情况:

情况一: binlog无记录,redolog状态prepare
由于 binlog 还没写,redo log 处于 prepare 状态还没提交,所以崩溃恢复的时候,这个事务会回滚,此时 binlog 还没写,所以也不会传到备库。

情况二:binlog有记录,redolog状态prepare
redolog 中的日志是不完整的,处于 prepare 状态,还没有提交,那么恢复的时候,首先检查 binlog 中的事务是否存在并且完整,如果存在且完整,则直接提交事务,如果不存在或者不完整,则回滚事务。

情况三:binlog有记录,redolog状态commit
直接提交事务,不需要恢复。

mysql的事务

在 MySQL 中,事务支持是在引擎层实现的。你现在知道,MySQL 是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。我将会以 InnoDB 为例,剖析 MySQL 在事务支持方面的特定实现,并基于原理给出相应的实践建议,希望这些案例能加深你对 MySQL 事务原理的理解

隔离性与隔离级别

先说下事物4种特性

原子性:事物在执行过程中,要么全部执行成功,要么全部失败
一致性:事物在执行过程中,保障数据的完整性,一致性,
隔离性:同一时间,只能有一个事物进行
持久性:事物执行完后后,数据会保存在数据库中,无法回滚

事物并发的几个概念

  • 脏读:比如财务给员工发工资,发了1W元,员工查工资卡一看挺高兴,后来财务发现工资发错了,立马取消,又改成8K,那么员工看到的1W就是脏数据,这就是脏读
  • 不可重复读:事物1需要读2次数据a,读完第一次时,事物2把a的值修改并提交了,这是事物1进行第二次读的时候前后2次读的数据不一致
  • 幻读:跟不可重复度类似,例如事物1需要查询2次本月发放工资1W-2W的人,查询完第一次有5条记录,这时事物2发现有一个人的工作发的是8K,发错了,应该发1.2W的,然后把这个人的工资改成了1.2W,这时事物1进行第二次查询的时候,就会发现有6条记录,多了一条记录,就邪门了,产生幻觉了

隔离级别

读未提交:读了一个未提交的数据,隔离级别最低 (可能会脏读)
读已提交:只能读提交过后的数据,sqlserver的默认隔离级别 (可能出现不可重复读)
可重复读:同一事物多次读取数据都一致,MySQL的默认级别(mysql 默认)
序列化读:把事物排序按照顺序执行,上锁,这样会造成锁竞争,占用资源,不建议使用

  • 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。而当前读,总是读取已经提交完成的最新版本。
  • 读已提交提交是指,一个事务提交之后,它做的变更才会被其他事务看到。对于读提交,查询只承认在语句启动前就已经提交完成的数据;
  • 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。(事务内多次查询,每次查询的结果是一致的),可重复读的核心就是一致性读(consistent read);而事务更新数据的时候,只能用当前读。如果当前的记录的行锁被其他事务占用的话,就需要进入锁等待。对于可重复读,查询只承认在事务启动前就已经提交完成的数据;
  • 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。(多个事务执行的话,是线性顺序执行)(当前读)

事务使用建议

长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就会导致大量占用存储空间。除了对回滚段的影响,长事务还占用锁资源,也可能拖垮整个库,这个我们会在后面讲锁的时候展开。

事务的启动方式

其实很多时候业务开发同学并不是有意使用长事务,通常是由于误用所致。MySQL 的事务启动方式有以下几种:

  1. 显式启动事务语句, begin 或 start transaction。配套的提交语句是 commit,回滚语句是 rollback。set autocommit=0,这个命令会将这个线程的自动提交关掉。意味着2.如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接。

    有些客户端连接框架会默认连接成功后先执行一个 set autocommit=0 的命令。这就导致接下来的查询都在事务中,如果是长连接,就导致了意外的长事务。因此,我会建议你总是使用 set autocommit=1, 通过显式语句的方式来启动事务。但是有的开发同学会纠结“多一次交互”的问题。对于一个需要频繁使用事务的业务,第二种方式每个事务在开始时都不需要主动执行一次 “begin”,减少了语句的交互次数。如果你也有这个顾虑,我建议你使用 commit work and chain 语法。在 autocommit 为 1 的情况下,用 begin 显式启动的事务,如果执行 commit 则提交事务。如果执行 commit work and chain,则是提交事务并自动启动下一个事务,这样也省去了再次执行 begin 语句的开销。同时带来的好处是从程序开发的角度明确地知道每个语句是否处于事务中。你可以在 information_schema 库的 innodb_trx 这个表中查询长事务,比如下面这个语句,用于查找持续时间超过 60s 的事务。查询查询数据库中的长事务
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 项目实战 | 俄罗斯方块

Qt 项目实战 | 俄罗斯方块 Qt 项目实战 | 俄罗斯方块游戏架构实现游戏逻辑游戏流程实现基本游戏功能设计小方块设计方块组添加游戏场景添加主函数 测试踩坑点1:rotate 失效踩坑点2:items 方法报错踩坑点3:setCodecForTr 失效踩坑点4&#xff…

蓝桥杯刷题

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析(3) 👉🏻最大降雨量 原题链接&#xff1…

OpenCV官方教程中文版 —— 分水岭算法图像分割

OpenCV官方教程中文版 —— 分水岭算法图像分割 前言一、原理二、示例三、完整代码 前言 本节我们将要学习 • 使用分水岭算法基于掩模的图像分割 • 函数:cv2.watershed() 一、原理 任何一副灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成…

Hand Avatar: Free-Pose Hand Animation and Rendering from Monocular Video

Github: https://seanchenxy.github.io/HandAvatarWeb 1、结构摘要 MANO-HD模型:作为高分辨率网络拓扑来拟合个性化手部形状将手部几何结构分解为每个骨骼的刚性部分,再重新组合成对的几何编码,得到一个跨部分的一致占用场纹理建…

2.数据结构-链表

概述 目标 链表的存储结构和特点链表的几种分类及各自的存储结构链表和数组的差异刷题(反转链表) 概念及存储结构 先来看一下动态数组 ArrayList 存在哪些弊端 插入,删除时间复杂度高需要一块连续的存储空间,对内存要求比较高,比如要申请…

CentOS 安装 Hadoop Local (Standalone) Mode 单机模式

CentOS 安装 Hadoop Local (Standalone) Mode 单机模式 Hadoop Local (Standalone) Mode 单机模式 1. 修改yum源 并升级内核和软件 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repoyum clean allyum makecacheyum -y update2. 安…

如何让salesforce提交待审批后不锁定记录

在 Salesforce 中,默认情况下,当记录被提交待审批时,它会被锁定以防止其他用户对其进行修改。这是为了确保审批过程中数据的完整性和一致性。然而,有时可能希望提交待审批后不锁定记录,这时可以使用Apex代码来实现: Ap…

idea自动编译以及修改代码后需要执行 mvn clean install 才生效

idea自动编译以及修改代码后需要执行 mvn clean install 才生效 一. idea热部署一、开启IDEA的自动编译(静态)二、开启IDEA的自动编译(动态)三、开启IDEA的热部署策略(非常重要) 二. IDEA 中项目代码修改后…

Vue 插槽 组件插入不固定内容

定义好一个组件&#xff0c;如果想插入图片或视频这非常不好的控制应该显示什么&#xff0c;这个时候可以使用插槽插入自定义内容 默认插槽 <Login><template><h1>我是插入的内容</h1></template></Login >组件 <slot></slot>…

一文了解Elasticsearch

数据分类 数据按数据结构分类主要有三种&#xff1a;结构化数据、半结构化数据和非结构化数据。 结构化数据 结构化数据具有明确定义数据模型和格式的数据类型。 特点&#xff1a; 数据具有固定的结构和模式。 数据项明确定义数据类型和长度。 适合用于数据查询、过滤和分…

ZOC8 for Mac:超越期待的终端仿真器

在Mac上&#xff0c;一个优秀的终端仿真器是每位开发者和系统管理员的必备工具。ZOC8&#xff0c;作为一款广受好评的终端仿真器&#xff0c;以其强大的功能和易用性&#xff0c;已经在Mac用户中积累了良好的口碑。本文将为您详细介绍ZOC8的各项特性&#xff0c;以及为什么它会…

MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

Mysql实战-为什么索引要建立在被驱动表上 前面我们讲解了BTree的索引结构&#xff0c;也详细讲解下 left Join的底层驱动表 选择原理&#xff0c;那么今天我们来看看到底如何用以及如何建立索引和索引优化 开始之前我们先提一个问题&#xff0c; 为什么索引要建立在被驱动表上…

【NI-DAQmx入门】传感器基础知识

1.什么是传感器&#xff1f; 传感器可将真实的现象&#xff08;例如温度或压力&#xff09;转换为可测量的电流和电压&#xff0c;因而对于数据采集应用必不可少。接下来我们将介绍您所需的测量类型及其对应的传感器类型。在开始之前&#xff0c;您还可以先了解一些传感器术语&…

uniapp 开发微信小程序 v-bind给子组件传递函数,该函数中的this不是父组件的二是子组件的this

解决办法&#xff1a;子组件通过缓存子组件this然后&#xff0c;用bind改写this 这个方法因为定义了全局变量that 那么该变量就只能用一次&#xff0c;不然会有赋值覆盖的情况。 要么就弃用v-bind传入函数,改为emit传入自定义事件 [uniapp] uview(1.x) 二次封装u-navbar 导致…

[MySQL]——SQL预编译、动态sql

键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、SQL的预编译 &#x1f4d5;一条SQL语句的执行过程 &#x1f4d5;弊端 &#x1f4d5;预编译SQL的优势 &#x1f4d5;两种参数占位符 &#x1f4d5;小结 二、动态SQL &#x1f4d5;概念介绍&#xff1a; &#x1f4…

ROS自学笔记二十: Gazebo里面仿真环境搭建

Gazebo 中创建仿真实现方式有两种:1直接添加内置组件创建仿真环境2: 手动绘制仿真环境 1.添加内置组件创建仿真环境 1.1启动 Gazebo 并添加组件 1.2保存仿真环境 添加完毕后&#xff0c;选择 file ---> Save World as 选择保存路径(功能包下: worlds 目录)&#xff0c;文…

Docker:命令

Docker&#xff1a;命令 1. 创建MySQL的命令解读2. 基础命令3. 案例 查看DockerHub&#xff0c;拉取Nginx镜像&#xff0c;创建并运行Nginx容器4. 命令别名附录 1. 创建MySQL的命令解读 docker run :创建并运行一个容器&#xff0c;-d 是让容器在后台运行--name:给容器起一个名…

Java日志组件介绍之一

一、前言 前段时间爆出Log4j安全漏洞的事情&#xff0c;XX云因未及时报告漏洞被工信部暂停网络安全威胁和漏洞信息共享平台合作单位&#xff08;https://www.cstis.cn/&#xff09;&#xff0c;话说Java的日志组件真是多而且也比较乱&#xff0c;后续几篇文章就聊一下各日志组…

【嵌入式】【GIT】如何迁移老的GIF到新的仓库时使用LFS功能并保持LOG不变

一、正常迁移流程 假设有仓库 ssh://old/buildroot-201902 需要迁移到新的仓库 ssh://old/buildroot-201902时,我们可以使用以下命令来完成: # 下载老的仓库 git clone ssh://old/buildroot-201902 # 向新的仓库上传所有的tags git push ssh://new/buildroot-201902 --tag…

【Linux】:Linux开发工具之Linux编辑器vim的使用

&#x1f52b;1.Linux编辑器-vim使用 &#x1f4e4; vi/vim的区别简单点来说&#xff0c;它们都是多模式编辑器&#xff0c;不同的是vim是vi的升级版本&#xff0c;它不仅兼容vi的所有指令&#xff0c;而且还有一些新的特性在里面。例如语法加亮&#xff0c;可视化操作不仅可以…