当前位置: 首页 > news >正文

SQLite Write-ahead Logging

  1. 1. 概述
  2. 2. WAL如何工作
    1. 2.1 检验指示(Checkpointing)
    2. 2.2 并发性(Concurrency)
    3. 2.3 性能考虑(Performance Considerations)
  3. 3. 激活并配置WAL模式
    1. 3.1 自动checkpoint
    2. 3.2 应用开始的checkpoint
    3. 3.3 WAL模式的持久性
  4. 4. 只读数据库
  5. 5. 避免过大的WAL文件
  6. 6. WAL索引的共享内存应用
  7. 7. 不用共享内存实现WAL
  8. 8. 向后兼容性

1. 概述

默认模式下SQLite使用回滚日志来实现原子提交和回滚. 从3.7.0版本开始, 可以使用"预写式日志"(WAL)选项.
比起回滚日志, WAL有一些好处:

  • 在大多数情况下WAL速度更快
  • 提供并发性, 读和写不会互相阻塞
  • IO操作变得更有序
  • 更少的使用fsync(), 这样当fsync()不能正常使用时可避免一些错误

WAL也有一些缺点:

  • 虚拟文件系统(VFS)必须支持共享内存技术, UNIX和Windows自带的VFS支持这种技术, 但定制系统的第三方VFS可能不支持.
  • 使用该数据库的进程必须在一台主机中, WAL不支持网络文件系统
  • ATTACH的事务对于单个数据库是原子性的, 但对于多个数据库来说不是原子性的
  • 进入WAL模式后不能改变数据库页面大小, 即使是在一个空数据库、使用VACCUM或从备份中恢复数据. 必须从回滚日志模式中修改页面大小.
  • 不能打开只读WAL数据库, 只有对该数据库相关的"-shm"WAL索引共享内存文件有写入权限才能执行打开操作. 否则只有"-shm"文件不存在才能打开该数据库.
  • 如果频繁使用读操作很少使用写操作, WAL可能比回滚日志方法慢一点点(大概百分之一二)
  • 每个数据库都会有对应的"-WAL"和"-shm"共享内存文件, 这使得SQLite不能像一个应用文件格式一样使用.
  • 需要额外进行checkpointing操作, 模式是自动执行的. 有时应用开发者需要注意这些.
  • WAL能更好的处理小事务, 对大的事务处理的并不好. 对于大于100M的事务, 传统的回滚日志模式处理的更快. 对于大于G的事务操作, WAL模式会报I/O错误. 所以建议使用回滚日志模式来处理上几十M的事务.

2. WAL如何工作

传统回滚日志通过将还未改变的数据库部分内容写入一个独立的回滚日志文件中, 并将修改的信息直接谢日数据库文件中. 在回滚中, 回滚日中的原始内容将会被写入数据库中间中, 并将数据库还原回原始状态. 当回滚日志被删除时COMMIT执行.
WAL颠倒了这个过程. 原始数据被保存在数据库文件中并将改变信息放在一个单独的WAL文件中. 因此一次COMMIT可能不会修改原始数据库, 这使得读者可以在修改提交到WAL文件的同时继续对未修改的数据库操作. 多个事务可以追加到单个WAL文件尾部.

2.1 检验指示(Checkpointing)

如果想将WAL中所有事务修改的内容都写入原始数据库, 这个转移就叫做"检查点"(checkpoint)
回滚日志和预写式日志的另一个区别在于, 回滚日志方法中有两个主要操作: 读和写;然而预写式日志有三个主要操作: 读, 写和checkpointing.
默认情况下, 当WAL文件到达1000页面大小时会自动进行checkpointing(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT编译时选项可用于修改默认值). 使用WAL技术的应用不需要对此做任何额外工作, 但可以修改checkpoint的临界值;也可以关闭自动checkpoint并在空闲时间主动进行checkpointing.

2.2 并发性(Concurrency)

当对于一个WAL模式下的数据库进行读操作时, 它将会找到WAL中的最后一个提交记录的位置, 叫做"结束标记"(end mark). 由于WAL会不断增长, 并且其他进程进行读连接时也会产生新的提交, 所以每个读进程都有各自的结束标记. 但对于单个读进程来说, 结束标记在整个事务中是不会变的, 因此可以确保单个读事务中只能看到某个时刻的数据库内容.
当读者需要一个页面的内容时, 首先需要检查WAL文件中是够存在该页面, 并取出WAL中的最新页面. 如果WAL中没有所需的页面, 将会直接从原始数据库中提取页面. 读者可位于一个单独的进程中, 这样可以避免每个读者都扫描完整的WAL(根据checkpoint的周期时间, WAL文件可能长到几十上百M), "WAL索引"这种数据结构保留在共享内存中, 它可以帮助读者通过更少的IO操作定位WAL中页面的位置. WAL索引极大地提升读取性能, 但共享内存的使用意味着读者必须都在一个机器上. 这就是为什么预写式日志不能用于网络文件系统.
写入者仅仅是将新的内容追加在WAL文件尾部, 因为写入者与读者不会有什么交集, 写入者和读者可以同时运行. 由于只有一个WAL文件, 所以同一时间只能有一个写入者.
checkpoint使得WAL文件中的内容写入原始数据库. checkpoint可以和读操作同时运行, 然而当checkpoint遇到当前读者所阅读的页面时就必须停止, 因为对这些页面的修改会重写读者正在读的内容. checkpoint会记录它进行到了哪里, 并在下一次调用时从上次结束点开始写入.
因此一个持续的读事务会阻断checkpoint, 但读操作终会结束, 所以checkpoint总会重新继续写入.
当写入操作发生时, 写入者会查看checkpoint进行了多少. 如果所有WAL都被写入并同步到数据库, 并且没有读者在使用WAL文件, 那么写入者将会将WAL初始化并将新的事务放在WAL头部. 这一机制能够防止WAL文件过大.

2.3 性能考虑(Performance Considerations)

由于写操作是序列化的, 并且只需要写入内容一次(回滚日志事务需要写入两次), 所以写入事务很快. 只要应用愿意在断电或重启后牺牲持久性, 内容就不需要同步. (如果将PRAGMA的synchronous设置为FULL, 写入者会在每次事务结束后同步提交的内容, 如果设置为NORMAL就会忽略同步)
另一方面, 由于每个读者都需要先从WAL文件中查找, 而且查找消耗的时间与WAL文件的大小成正比, 所以随着WAL文件体积的增加, 读操作性能会不断降低. WAL索引会提升查找内容的性能, 但依然会随着WAL提交的增加而不断变慢. 所以在间隙中运行checkpoint来减少WAL文件大小对于读取性能提升是很有必要的.
Checkpointing要求同步操作, 为了避免由于断电或系统崩溃导致的数据库崩溃. 在将WAL文件中的内容写入数据库之前, 必须先将WAL同步到硬盘中;在重置WAL之前, 必须先同步数据库文件. Checkpoint在将序列化页面写入数据库时需要进行查询操作(WAL页面以升序写入数据库). 即使这样, 在写入页面期间也要进行多次查询操作. 以上原因导致checkpoint比写入事务要慢.
默认的策略是不断写入来增加WAL文件, 直到到达1000页面终止写入. 然后对每一个子COMMIT运行checkpoint操作, 直到WAL小于1000页面. 默认情况下, 将COMMIT的内容写入WAL的线程也会自动运行checkpoint, 这就是COMMIT操作变得十分快速的原因, 但部分COMMIT也会变慢(因为触发了checkpoint). 如果不想自动checkpoint, 也可以关闭自动checkpoint并改为周期性checkpoint.
注意, PRAGMA synchronous设为NORMAL时, checkpoint或sync(UNIX的fsync()或Windows上的FlushFileBuffers())是唯一的I/O障碍. 如果一个线程或进程运行了checkpoint, 那么主线程或主进程上query或update不会阻塞. 这有助于在频繁I/O操作中防止应用中的"闭锁"(latch-up). 这种配置的缺点在于事务不再具有持久性, 断电或系统崩溃后不能回滚.
还需要注意要权衡读和写性能, 为了最大化读操作性能, 需要将WAL文件保持的尽量小, 这样可以频繁的checkpoint, 可能与COMMIT一样频繁. 为了最大化写操作性能, 需要将每一次checkpoint的损耗分摊在每一次写操作中, 这意味着不能频繁的进行checkpoint, 并且让WAL文件在checkpoint前增加到尽量大. 因此, 多久进行一次checkpoint取决于不同的应用对读写性能的要求. 默认策略是在WAL文件到达1000页面大小时进行checkpoint, 并且这个策略在测试应用和工作站中都表现不错;但根据不同平台和不同工作量, 其他策略可能运行的更好.

3. 激活并配置WAL模式

SQLite数据库连接默认为journal_mode=DELETE, 为了切换到WAL模式, 使用以下pragma:

PRAGMA journal_mode=WAL;

journal_mode将返回一个字符串, 它代表一种新的日志模式. 如果操作成功, pragma返回"WAL";如果没能转换成WAL模式(例如, VFS不支持共享内存技术), 那么不会改变日志模式. 将会返回之前的日志模式的字符串.

3.1 自动checkpoint

SQLite默认会在WAL文件到达1000页面或更多页面时进行自动的checkpoint, 或数据库文件上的最后一个数据库连接断开. 对于大多数应用来说, 默认配置工作的很不错. 但如果应用想控制checkpoint可以使用WAL_checkpoint pragma或调用sqlite3_WAL_checkpoint()接口. 自动checkpoint的临界值可被修改数值, 也可以使用WAL_autocheckpoint pragma或sqlite3_WAL_autocheckpoint()接口彻底禁止checkpoint. 也可以使用注册一个回调, 这样每次事务提交都能调用这个回调函数. 这个回调函数可以在任何它认为合适的情况下调用sqlite3_WAL_checkpoint()或sqlite3_WAL_checkpoint_v2(). (自动checkpoint机制就是凭借sqlite3_WAL_hook()来实现)

3.2 应用开始的checkpoint

当使用可写的数据库连接时, 可调用sqlite3_WAL_checkpoint()或sqlite3_WAL_checkpoint_v2()来开始一个checkpoint. 根据checkpoint的主动性可分为三种子类型: PASSIVE、FULL和RESTART. 默认是PASSIVE, 会在不干扰其他数据库连接的基础上尽可能多的checkpoint, 如果有同时发生的读者或写入者, 那么不会checkpoint会终止. 所有的checkpoint都由sqlite3_WAL_checkpoint()初始化, 并且自动checkpoint机制就是PASSIVE模式. FULL和RESTART模式的checkpoint会尝试完整地checkpoint, 并且只能通过sqlite3_WAL_checkpoint_v2()来初始化. 关于FULL和RESET的更多信息可以查看sqlite3_WAL_checkpoint_v2()

3.3 WAL模式的持久性

不同于其他日志模式, PRAGMA journal_mode=WAL是持久的. 如果一个进程设为WAL模式, 然后关闭并重启数据库, 数据库还是WAL模式. 而如果设为PRAGMA journal_mode=TRUNCATE, 然后关闭并重启, 那么会恢复到默认的DELETE回滚模式.
WAL模式的持久性意味着应用可以在不改变的情况下使用WAL模式. 仅仅可以使用shell命令行的"PRAGMA journal_mode=WAL;"然后重启应用, 就可以切换到WAL模式.

4. 只读数据库

如果数据库位于一个只读媒介中, 并且需要恢复, 那么该数据库就没法读取了. 举个例子, 如果应用崩溃, 数据库会留一个热日志(hot journal), 除非进程又写权限, 否则没法打开数据库, 也没法打开热日志文件. 这是因为在读取数据库前由于崩溃导致数据库需要回滚, 而回滚需要对该文件夹下的文件具有写权限才可以.
WAL模式下的数据库在只读媒介下没法读取, 因为即使是读取操作也需要checkpoint, 所以还需要写权限.
WAL读操作算法的高效实现要求共享内存中有一个hash表存放WAL文件的内容, 这个hash表叫做WAL索引. 共享内存中的WAL索引在主计算机文件系统中没有一个名字. 自定义的VFS可以自由的使用共享内存;但内置的SQLite通过UNIX和Windows驱动来实现共享内存, 使用以"-shm"为后缀的mmaped文件, 该文件与数据库位于同一文件夹中. 为了开启WAL数据库, 必须有对"-shm"后缀的共享内存文件的写权限;并且需要对数据库所在的文件夹具有写权限, 因为需要在WAL索引不存在时创建它. WAL索引必须在第一次访问时重建, 即使访问者是读者. 这会让默认的UNIX和Windows在只读媒介上不能访问WAL数据库, 但这并不排除自定义VFS实现的共享内存能实现访问只读WAL数据库,
因此, SQLite数据库应在导入只读媒介前切换为PRAGMA journal_mode=DELETE.
如果多个进程访问WAL模式的数据库, 那么基于用户或组ID的所有进程都会被赋予写权限, 权限覆盖数据库文件、WAL文件、共享内存的"-shm"文件和所位于的文件夹.

5. 避免过大的WAL文件

WAL文件会一直追加新的内容, 直到WAL文件到达1000页面(大约4MB), 达到临界值后会自动checkpoint并循环使用WAL文件. checkpoint通常不会截断WAL文件(除非设置了journal_size_limit), 相反的, checkpoint只会再次从WAL文件头部开始使用. 因为重写比追加要快. 当数据库没有连接时会删除WAL和它的共享内存文件.
所以大多数情况下, 应用不需要在意WAL文件, SQLite会自动处理它们. 但也存在着可能使得WAL文件不断增长, 甚至超过硬盘额度并减慢查询速度. 下面列举了一些可能出现的情况和如何避免它们:

  1. 关闭了自动checkpoint机制
    默认情况下, SQLite会在WAL文件超过1000页面时进行checkpoint. 编译时和运行时可选项会推迟或关闭自动checkpoint. 如果应用关闭了自动checkpoint, 那WAL文件注定会越来越大.
  2. checkpoint饥饿
    如果没有进程连接着数据库, checkpoint只能去完成并重置WAL文件. 如果有一个读事务连接到了数据库, 那么checkpoint会终止重置工作, 因为重置需要从WAL文件中删除一些内容. checkpoint只能在没有读者烦扰的情况下尽量多的工作. checkpoint会在下一次写事务结束后再次开启, 直到checkpoint完成了整个工作.
    如果有多个读者不断访问数据库, 而且某一时刻总有一个活跃的读者, 那么checkpoint总不能完成任务, 因此WAL文件将不断增加.
    这种情况可通过确保存在"读者间隙"来解决这个问题: 确保读者不会不间断地读取数据库, 这样就能使用间隙时间来checkpoint. 如果一个应用有多个同时存在的读者, 那么需要使用SQLITE_CHECKPOINT_RESTART或SQLITE_CHECKPOINT_TRUNCATE来手动checkpoint. 这些选项优点在于可以完整的checkpoint, 缺点在于会阻塞读者来完成checkpoint.
  3. 大面积的写事务
    checkpoint只能在没有其他事务运行时进行, 这意味着WAL文件不能在写事务进行时重置. 所以一次较大的写事务可能导致WAL文件变得很大. WAL文件可能在写事务完成后进行checkpoint(假设没有读者进行阻塞), 但在写入时WAL文件会不断增大.
    注意到有时数据库的单个页面可能在一次事务中写入WAL文件多次, 因此WAL文件最后可能比原始数据库大好几倍. 当缓存大小小于数据库页面数量时, 会在事务进行中发生这种情况. 当对一个页面进行多次更改时, 这些更改会一直留在内存中, 直到事务结束时它们会被修WAL文件. 但如果在事务结束前缓存填满了, 那么可能会溢出某些页面. 如果有多个相同的页面多次改变, 它们必须都写入WAL文件中. 对于一个很大的事务和很小的缓存, 相同的页面有可能多次移出并多次写入WAL文件.

解决方案包含:

  • 对于大的更新操作, 可以切换到回滚日志模式
  • 确保缓存大小足够大, 这样可以存储事务更新的内容
  • 通过拆分事务来保持更改页面的数量
  • 在进行一次大规模插入前删除索引, 并在事务完成后重新创建索引

6. WAL索引的共享内存应用

WAL索引使用一个普通的文件来实现稳健性. WAL模式的早期实现将WAL索引放置在不稳定的共享内存中, 比如Linux上创建的/dev/shm或UNIX系统上的/tmp. 这种方法的缺点在于, 如果进程位于不同的根目录, 那么他们使用的是不同的共享内存空间, 这将导致数据库崩溃. 另一种方法就是创建无名共享内存区间, 但他们无法再众多UNIX系统中移植, 并且我们无法再Windows系统中创建无名共享内存区间. 但我们还有唯一一种方法确保所有进程都访问同一数据库文件: 在数据库所在的文件夹中通过映射一个文件来创建共享内存.
使用一个普通的硬盘文件来创建共享内存有一个缺点: 为了将共享内存中数据写入硬盘, 需要进行不必要的I/O操作. 但开发者并不认为这是个大问题, 因为WAL索引很少超过32KB, 也不会同步. 此外, WAL索引文件将会在最后的数据库连接断开时被删除, 这使得I/O操作几乎不大会发生.
对于某些应用, 默认的共享内存实现不能使用, 可以使用可选的方法来实现一个定制的VFS. 举个例子, 如果已知一个特定的数据库, 它仅能通过单个进程中的线程访问, WAL索引可通过堆内存来实现, 而不是共享内存.

7. 不用共享内存实现WAL

SQLite3.7.4版本开始, 只要在第一次访问之前将lock_mode设为EXCLUSIVE, 即使不能使用共享内存也能使用WAL模式. 换句话说, 如果同一时间只能有一个进程访问数据库, 那么就可以实现不使用共享内存来使用WAL模式. 这一特性可以让那些没有"第二版"共享内存方法xShmMap、xShmLock、xShmVarrier和xShmUnmap的VFS使用WAL模式来读写.
如果lcoking_mode在第一次访问前设为EXCLUSIVE, 那么SQLite不会调用共享内存方法, 因此不会创建共享内存的WAL索引. 在这种情况下, 只要日志模式为WAL, 那么数据库连接就会一直保持EXCLUSIVE模式. 无法使用"PRAGMA locking_mode=NORMAL;"来改变锁模式. 如果想改变EXCLUSIVE模式就必须先改变WAL日志模式. 如果第一次WAL模式的数据库访问是NORMAL锁模式, 那么就会创建共享内存中的WAL索引. 这意味着底层的VFS必须支持"第二版"共享内存. 如果VFS不支持共享内存方法, 并且尝试以WAL模式开启数据库或转换为WAL模式, 操作将会失败. 只有数据库连接使用共享内存中的WAL索引, 锁模式才能在NORMAL和EXCLUSIVE之间自由转换. 只要锁模式在第一次访问前设为EXCLUSIVE, 那么就会忽略共享内存的WAL索引, 并且锁模式会锁定在EXCLUSIVE且不可改变.

8. 向后兼容性

WAL模式下的数据库格式没有变化, 但对于旧版SQLite来说WAL文件和WAL索引是全新的概念, 所以旧版SQlite无法对WAL模式下SQLite的进行恢复. 为了防止旧版SQLite对WAL模式的数据库进行恢复, 数据库文件格式的版本号从1提升到2. 因此如果旧版的SQLite连接到该数据库时提示"文件被加密或不是一个数据库".
使用以下pragma可以抹去WAL模式的改变:

PRAGMA journal_mode=DELETE

将数据库文件格式的版本号改回1时必须要谨慎, 因为这样旧版SQLite就能访问数据库文件了.

相关文章:

SQLite Write-ahead Logging

1. 概述2. WAL如何工作 2.1 检验指示(Checkpointing)2.2 并发性(Concurrency)2.3 性能考虑(Performance Considerations)3. 激活并配置WAL模式 3.1 自动checkpoint3.2 应用开始的checkpoint3.3 WAL模式的持久性4. 只读数据库5. 避免过大的WAL文件6. WAL索引的共享内存应用7. 不…...

手机有什么爬虫App工具?

随着智能手机的普及和应用的繁盛,越来越多的人开始对手机App进行数据爬取和分析。那么,在进行手机App爬虫的过程中,我们可以借助哪些工具呢?让我们一起来了解一下吧! 1、Fiddler Fiddler是一款功能强大的网络调试工具…...

290_C++_截取的一部分FTP视频上传代码,任务信息中读取视频帧数据并将其提供给 libcurl 用于上传。

1、这些结构体和枚举类型的设计是为了在上传过程中有效地存储和传递不同类型的任务信息,以便在上传操作中使用这些信息来管理和跟踪不同类型的上传任务。它们提供了不同类型上传任务所需的特定信息和状态变量 enum UploadTaskType {UTT_Common,UTT_Video };struct UploadInfo…...

读《Gaitset: Regarding gait as a set for cross-view gait recognition》

2019在AAAI(还有一版叫GaitSet: Regarding Gait as a Set for Cross-View Gait Recognition,大体上一样) 摘要 现有的步态识别方法要么利用步态模板,难以保存时间信息,要么利用保持不必要的顺序约束的步态序列&#x…...

驱动实现LED点灯

demo.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include "head.h" //定义三个指针指向映射后的虚拟内存 unsigned int *vir_moder; unsigned …...

【Reinforcement Learning】Ubuntu中mujoco210 mujoco_py D4RL安装及错误解决

Ubuntu中mujoco210 mujoco_py D4RL安装及错误解决 本文根据一篇知乎文章链接在此进行配置&#xff0c;记录在配置过程中遇到的一些问题&#xff0c;原文作者的教程很详细&#xff0c;在此对原作者表示感谢&#xff5e; 直接进行知乎原文的第2.2 有效安装过程(避坑) 2.注意上…...

设计模式截图记录

设计模式截图记录...

代碼隨想錄算法訓練營|第三十九天|738.单调递增的数字、968.监控二叉树、第八章 贪心算法總結。刷题心得(c++)

目录 讀題 738.单调递增的数字 自己看到题目的第一想法 看完代码随想录之后的想法 968.监控二叉树 自己看到题目的第一想法 看完代码随想录之后的想法 738.单调递增的数字 - 實作 思路 Code 968.监控二叉树 - 實作 思路 Code 贪心算法 總結 贪心理论基础 貪心…...

前言:自动化框架的设计模式

1、UI自动化框架的设计模式 自动化测试框架有很多种&#xff0c;常见的自动化框架分类如下&#xff1a; 在使用上面的自动化框架时&#xff0c;通常会结合使用分层思想&#xff0c;也就是一些自动化框架设计模式&#xff0c;今天重点分享一下UI自动化框架设计使用比较多的一种…...

Web架构安全分析/http/URL/Cookie攻击

Web 架构安全分析 Web 工作机制及基本概念 传统 Web 架构 LAMP 网页 概念 网页就是我们可以通过浏览器上网看到的精美页面&#xff0c;一般都是经过浏览器渲染过的 .html 页面&#xff0c;html 语言在浏览器中渲染。其中包含了CSS、JavaScript 等前端技术。通过浏览器访问…...

.git 目录中有什么?

好吧&#xff0c;我想你们中的大多数人每天都或多或少地使用 git&#xff0c;但是您是否研究过 git 创建的 .git 文件夹中的内容&#xff1f;本文[1]我们将一起探索一下&#xff0c;了解里面到底发生了什么。 ❝ git 在基本层面上只是一堆通过文件名相互链接的文本文件。 ❞ in…...

Debian11系统简单配置

debian11系统简单配置 网卡配置 修改/etc/network/interfaces address 192.168.0.188 gateway 192.168.0.1 netmask 255.255.255.0重启网卡systemctl restart networking.service systemctl restart networking 执行apt 报错 rootdebian:~# apt update 忽略:1 cdrom://[D…...

家装、家居两不误,VR全景打造沉浸式家装体验

当下&#xff0c;用户对生活品质要求日益提升&#xff0c;越来越多的用户对多功能家装用品需求较大&#xff0c;由此造就了VR全景家装开始盛行。VR全景家装打破传统二维空间模式&#xff0c;通过视觉、交互等功能让用户更加真实、直观的体验和感受家居布置的效果。 一般来说&am…...

Ubuntu服务器 Clash Dashboard

正文发不出来 链接&#xff1a;【Linux】解决Ubuntu服务器版本无法使用Clash Dashboard的问题 这个图展示了RNA-Seq实验数据生成的流程。下面是该流程的逐步解释&#xff1a; mRNA或总RNA提取&#xff1a;首先&#xff0c;从细胞或组织样本中提取mRNA或总RNA。mRNA是经过剪切…...

创建数据库表的命令

创建数据库表的通用语法&#xff1a; ​CREATE TABLE table_name (column1 datatype constraint,column2 datatype constraint,...columnN datatype constraint ); 其中&#xff0c;table_name 为要创建的表名&#xff0c;column1 到 columnN 为表的列名&#xff0c;datatype …...

ubuntu18.04 LTS卸载qtcreator-10.0.2

之前通过命令&#xff0c;通过.run文件&#xff0c;安装了Qt Creator 默认安装路径是/opt/ 卸载 在安装路径下&#xff0c;可以看到QtCreatorUninstaller文件 命令行运行该执行文件&#xff0c;会弹出卸载窗口&#xff0c;记得勾选下面的“仅卸载”...

通过字符设备驱动并编写应用程序控制三盏灯亮灭

现象 键盘按1三灯全亮 按0三灯全灭 头文件.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014#defin…...

SpringCloud链路追踪——Spring Cloud Sleuth 和 Zipkin 介绍 Windows 下使用初步

前言 在微服务中&#xff0c;随着服务越来越多&#xff0c;对调用链的分析越来越复杂。如何能够分析调用链&#xff0c;定位微服务中的调用瓶颈&#xff0c;并对其进行解决。 本篇博客介绍springCloud中用到的链路追踪的组件&#xff0c;Spring Cloud Sleuth和Zipkin&#xf…...

深入探究音视频开源库 WebRTC 中 NetEQ 音频抗网络延时与抗丢包的实现机制

目录 1、引言 2、什么是NetEQ&#xff1f; 3、NetEQ技术详解 3.1、NetEQ概述 3.2、抖动消除技术 3.3、丢包补偿技术 3.4、NetEQ概要设计 3.5、NetEQ的命令机制 3.6、NetEQ的播放机制 3.7、MCU的控制机制 3.8、DSP的算法处理 3.9、DSP算法的模拟测试 4、NetEQ源文件…...

一篇文章教会你C++11入门知识点

C11入门 列表初始化1. {}初始化2. initializer_list 声明1. auto2. decltype3. nullptr 范围for循环STL新增容器1. array2. forward_list3. unordered_map和unordered_set 右值引用和移动语义1. 左值引用和右值引用2. 左值引用和右值引用比较3. 右值引用使用场景和意义4. 右值引…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...