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

表格模板免费下载网站wordpress 插件位置

表格模板免费下载网站,wordpress 插件位置,贵阳网站建设1685,网站图片移动怎么做深入理解隔离性 一、数据库并发的场景二、多版本并发控制#xff08; MVCC #xff09;三、三个前提知识1、3个记录隐藏字段2、undo日志 四、快照的概念五、Read View六、隔离级别RR与RC的本质区别 一、数据库并发的场景 数据库并发的场景总共有三种#xff1a; 读-读 MVCC 三、三个前提知识1、3个记录隐藏字段2、undo日志 四、快照的概念五、Read View六、隔离级别RR与RC的本质区别 一、数据库并发的场景 数据库并发的场景总共有三种 读-读不存在任何问题也不需要并发控制读-写有线程安全问题可能会造成事务隔离性问题可能遇到脏读幻读不可重复读写-写有线程安全问题可能会存在更新丢失问题比如第一类更新丢失第二类更新丢失。 第一类更新丢失也被称为回滚丢失是指一个事务的回滚操作导致了另一个已经提交的事务的更新操作丢失。换句话说当一个事务回滚时它覆盖了另一个已经提交的事务所做的更改。这可能会导致数据的不一致性和错误。 第二类更新丢失也被称为覆盖丢失是指一个事务的提交操作导致了另一个已经提交的事务的更新操作丢失。换句话说当一个事务提交时它覆盖了另一个已经提交的事务所做的更改。这也会导致数据的不一致性和错误 说明 读-读并发不需要进行并发控制写-写并发实际也就是对数据进行加锁这里最值得讨论的是读-写并发读-写并发是数据库当中最高频的场景在解决读-写并发时不仅需要考虑线程安全问题还需要考虑并发的性能问题。 二、多版本并发控制 MVCC 多版本并发控制 MVCC 是一种用来解决读-写冲突 的无锁并发控制 其主要内容是 为事务分配单向增长的事务IDID越大代表事务越新。为每个修改保存一个版本版本与事务ID关联。读操作只读该事务开始前的数据库的快照。 所以MVCC 可以为数据库解决以下问题 在并发读写数据库时可以做到在读操作时不用阻塞写操作写操作也不用阻塞读操作提高了数据库并发读写的性能。同时还可以解决脏读幻读不可重复读等事务隔离问题。 三、三个前提知识 理解MVCC 需要知道三个前提知识 3个记录隐藏字段undo 日志Read View (在后面我们进行讲述) 1、3个记录隐藏字段 数据库表中的每条记录都会有如下3个隐藏字段 DB_TRX_ID6字节创建或最近一次修改本条记录的事务ID。DB_ROW_ID6字节隐含的自增ID隐藏主键如果数据表没有主键 InnoDB 会自动以DB_ROW_ID 产生一个聚簇索引。DB_ROLL_PTR7字节回滚指针指向这条记录的上一个版本(这些数据一般在undo log 中)。 此外数据库表中的每条记录还有一个删除flag隐藏字段用于表示该条记录是否被更新或删除所以mysql中的删除并不代表真的删除只是是删除flag变了然后当数据需要进行刷盘持久化时通过查看这个flag字段来进行选择性刷盘。 例如下面的一个学生表表中包含学生的姓名和年龄。如下 当向表中插入一条记录后(假设插入的这条SQL对应的事务ID是9)该记录不仅包含name和age字段还包含三个隐藏字段。如下 因为这是插入的第一条记录所以隐式主键DB_ROW_ID字段填的就是1。由于这条记录是新插入的没有历史版本所以回滚指针DB_ROLL_PTR的值设置为null。MVCC重点需要的就是这三个隐藏字段实际还有其他隐藏字段只不过没有画出。 2、undo日志 MySQL的三大日志如下 redo log重做日志用于MySQL崩溃后进行数据恢复保证数据的持久性。bin log逻辑日志用于主从数据备份时进行数据同步保证数据的一致性。undo log回滚日志用于对已经执行的操作进行回滚保证事务的原子性。 MySQL会为上述三大日志在内存中开辟对应的缓冲区用于存储日志相关的信息必要时会将缓冲区中的数据刷新到磁盘。 说明 MVCC的实现主要依赖三大日志中的undo log记录的历史版本就是存储在undo log对应的缓冲区中的。 四、快照的概念 现在有一个事务ID为10的事务要将刚才插入学生表中的记录的学生姓名改为“李四” 因为是要进行写操作所以需要先给该记录加行锁。修改前先将该行记录拷贝到undo log中此时undo log中就有了一行副本数据。然后再将原始记录中的学生姓名改为“李四”并将该记录的DB_TRX_ID改为10回滚指针DB_ROLL_PTR设置成undo log中副本数据的地址从而指向该记录的上一个版本。最后当事务10提交后释放锁这时最新的记录就是学生姓名为“李四”的那条记录。 备注此时最新的记录是’李四‘那条记录。 现在又有一个事务ID为11的事务要将刚才学生表中的那条记录的学生年龄改为38 因为是要进行写操作所以需要先给该记录最新的记录加行锁。修改前先将该行记录拷贝到undo log中此时undo log中就又有了一行副本数据。然后再将原始记录中的学生年龄改为38并将该记录的DB_TRX_ID改为11回滚指针DB_ROLL_PTR设置成刚才拷贝到undo log中的副本数据的地址从而指向该记录的上一个版本。最后当事务11提交后释放锁这时最新的记录就是学生年龄为38的那条记录。 修改后的示意图如下 此时我们就有了一个基于链表记录的历史版本链而undo log中的一个个的历史版本就称为一个个的快照。 说明 所谓的回滚实际就是用undo log中的历史数据覆盖当前数据而所谓的创建保存点就可以理解成是给某些版本做了标记让我们可以直接用这些版本数据来覆盖当前数据。这种技术实际就是基于版本的写时拷贝当需要进行写操作时先将最新版本拷贝一份到undo log中然后再进行写操作和父子进程为了保证独立性而进行的写时拷贝是类似的 insert和delete的记录如何维护版本链 删除记录并不是真的把数据删除了而是先将该记录拷贝一份放入undo log中然后将该记录的删除flag隐藏字段设置为1这样回滚后该记录的删除flag隐藏字段就又变回0了相当于删除的数据又恢复了。新插入的记录是没有历史版本的但是一般为了回滚操作新插入的记录也需要拷贝一份放入undo log中只不过被拷贝到undo log中的记录的删除flag隐藏字段被设置为1这样回滚后就相当于新插入的数据就被删除了。 当前读 VS 快照读 在前面我们讨论了update,delete,insert形成版本链的方式那么select怎么形成版本链呢 首先select不会对数据做任何修改所以为select维护多版本没有意义 不过此时对于select有个问题值得被讨论就是select读取是读取最新的版本呢还是读取历史版本 当前读读取最新的记录就叫做当前读。例如使用select * from 表名 lock in share mode(共享锁)进行当前读。快照读读取历史版本就叫做快照读。一般我们使用的类似于select * from 表名都是快照读如果没有快照就进行当前读。 所以事务在进行增删查改的时候并不是都需要进行加锁保护的 事务对数据进行增删改的时候操作的都是最新记录即进行的是当前读所以需要进行加锁保护。事务在进行select查询的时候既可能是当前读也可能是快照读如果是当前读那也需要进行加锁保护但如果是快照读那就不需要加锁因为历史版本不会被修改也就是可以并发执行这提高了效率这也就是MVCC的意义所在。 而select查询时应该进行当前读还是快照读则是由隔离级别决定的在读未提交和串行化隔离级别下进行的都是当前读而在读提交和可重复读隔离级别下既可能进行当前读也可能进行快照读。 undo log中的版本链何时才会被清除 在undo log中形成的版本链不仅仅是为了进行回滚操作其他事务在执行过程中也可能读取版本链中的某个版本也就是快照读。因此只有当某条记录的最新版本已经修改并提交并且此时没有其他事务与该记录的历史版本有关了这时该记录在undo log中的版本链才可以被清除。 说明 对于新插入的记录来说没有其他事务会访问它的历史版本因此新插入的记录在提交后就可以将undo log中的版本链清除了。因此版本链在undo log中可能会存在很长时间尤其是有其他事务和这个版本链相关联的时候但这也没有坏处这说明它是一个热数据。 五、Read View 事务在进行快照读操作时会生成读视图Read View在该事务执行快照读的那一刻会生成数据库系统当前的一个快照记录并维护系统当前活跃的事务ID。 Read View在MySQL源码中就是一个类本质是用来进行可见性判断的当事务对某个记录执行快照读的时候对该记录创建一个Read View根据这个Read View来判断当前事务能够看到该记录的哪个版本的数据既可能是当前最新的数据也有可能是该行记录的undo log 里面的某个版本的数据。 ReadView类的源码简化版如下 class ReadView {// 省略... private:/** 高水位大于等于这个ID的事务均不可见*/trx_id_t m_low_limit_id;/** 低水位小于这个ID的事务均可见 */trx_id_t m_up_limit_id;/** 创建该 Read View 的事务ID*/trx_id_t m_creator_trx_id;/** 创建视图时的活跃事务id列表*/ids_t m_ids;/** 配合purge标识该视图不需要小于m_low_limit_no的UNDO LOG* 如果其他视图也不需要则可以删除小于m_low_limit_no的UNDO LOG*/trx_id_t m_low_limit_no;/** 标记视图是否被关闭*/bool m_closed;// 省略... }; 部分成员说明 m_ids 一张列表记录Read View生成时刻系统中活跃的事务ID。m_up_limit_id 记录m_ids列表中事务ID最小的ID。m_low_limit_id 记录Read View生成时刻系统尚未分配的下一个事务ID。m_creator_trx_id 记录创建该Read View的事务的事务ID。 我们在实际读取数据版本链的时候是能读取到每一个版本对应的事务ID的即当前记录的DB_TRX_ID 那么我们现在手里面有的东西就有当前快照读的ReadView和 版本链中的某一个记录的DB_TRX_ID 。 所以现在的问题就是当前快照读应不应该读到当前版本记录下面的图能够解释这个问题。 由于事务ID是单向增长的因此根据Read View中的m_up_limit_id和m_low_limit_id可以将事务ID分为三个部分 事务ID小于m_up_limit_id的事务一定是生成Read View时已经提交的事务因为m_up_limit_id是生成Read View时刻系统中活跃事务ID中的最小ID因此事务ID比它小的事务在生成Read View时一定已经提交了。事务ID大于等于m_low_limit_id的事务一定是生成Read View时还没有启动的事务因为m_low_limit_id是生成Read View时刻系统尚未分配的下一个事务ID。事务ID位于m_up_limit_id和m_low_limit_id之间的事务在生成Read View时可能正处于活跃状态也可能已经提交了这时需要通过判断事务ID是否存在于m_ids中来判断该事务是否已经提交。 判断部分 一个事务在进行读操作时只应该看到自己或已经提交的事务所作的修改因此我们可以根据Read View来判断当前事务能否看到另一个事务所作的修改。版本链中的每个版本的记录都有自己的DB_TRX_ID即创建或最近一次修改该记录的事务ID因此可以依次遍历版本链中的各个版本通过Read View来判断当前事务能否看到这个版本如果不能则继续遍历下一个版本。 源码策略如下(这个函数被调用的在一个循环中这个循环从最新的历史版本开始向后遍历undo log里面的所有历史版本) bool changes_visible(trx_id_t id, const table_name_t name) const MY_ATTRIBUTE((warn_unused_result)) {ut_ad(id 0);//1、事务id小于m_up_limit_id已提交或事务id为创建该Read View的事务的id则可见if (id m_up_limit_id || id m_creator_trx_id) {return(true);}check_trx_id_sanity(id, name);//2、事务id大于等于m_low_limit_id生成Read View时还没有启动的事务则不可见if (id m_low_limit_id) {return(false);}//3、事务id位于m_up_limit_id和m_low_limit_id之间并且活跃事务id列表为空即不在活跃列表中则可见else if (m_ids.empty()) {return(true);}const ids_t::value_type* p m_ids.data();//4、事务id位于m_up_limit_id和m_low_limit_id之间如果在活跃事务id列表中则不可见如果不在则可见return (!std::binary_search(p, p m_ids.size(), id)); }说明 使用该函数时将版本的DB_TRX_ID传给参数id该函数是Read View类里面的一个成员函数其作用就是根据Read View判断当前事务能否看到这个版本。 六、隔离级别RR与RC的本质区别 我们通过下面的实验现象来理解RR与RC隔离级别 现象演示1 主要操作以及执行顺序 事务A操作事务A描述事务B描述事务B操作begin开启事务开启事务begin--快照读快照读查询select * from accountupdate account set balance1789.7 where name‘张三’;更新 balance1789.7--commit提交事务----进行快照读select * from account--进行当前读select * from user lock in share mode 启动两个终端将隔离级别都设置为可重复读并查看此时银行用户表中的数据。如下 在两个终端各自启动一个事务在左终端中的事务操作之前先让右终端中的事务查看一下表中的信息。如下 左终端中的事务对表中的信息进行修改并提交右终端中的事务看不到修改后的数据。如下 在右终端中使用select ... lock in share mode命令进行当前读可以看到表中的数据确实是被修改了只是右终端中的事务看不到而已。如下 现象演示2 主要操作以及执行顺序 事务A操作事务A描述事务B描述事务B操作begin开启事务开启事务beginselect * from account快照读快照读select * from accountupdate account set balance789.6 where id7;更新 balance789.6--commit提交事务----快照读select * from account 如果修改一下SQL的执行顺序在两个终端各自启动一个事务后直接先让左终端中的事务对表中的信息进行修改并提交然后再让右终端中的事务进行查看这时右终端中的事务就直接看到了修改后的数据。如下 这是为什么呢 因为Read View的形成时机是在第一次进行快照读的时候形成的 实验1中右边的终端在左边的修改提交之前进行了快照读形成了Read View于是这个Read View认为左边终端中的事务是和它一起并发运行的事务它不应该看到左边终端中修改提交后的数据。 实验二中左边终端的修改没有提交之前右边的终端在一直没有形成Read View直到左边的事务结束以后右边的终端才开始进行快照读形成Read View但是这个时候左边的事务已经结束了于是这个刚形成的Read View就会判定左边终端中的事务是一个已经运行完毕的事务其内容可以被看到。 RR与RC的本质区别 RR与RC的本质区别于Read View生成时机 在RR级别下事务第一次进行快照读时会创建一个Read View将当前系统中活跃的事务记录下来此后再进行快照读时就会直接使用这个Read View进行可见性判断因此当前事务看不到第一次快照读之后其他事务所作的修改。 而在RC级别下事务每次进行快照读时都会创建一个Read View然后根据这个Read View进行可见性判断因此每次快照读时都能读取到被提交了的最新的数据。 RR级别下快照读只会创建一次Read View所以RR级别是可重复读的而RC级别下每次快照读都会创建新的Read View所以RC级别是不可重复读的。 参考文章 MySQL事务管理
http://www.zqtcl.cn/news/766014/

相关文章:

  • 做网站的公司 贵阳流媒体网站建设
  • 北京建网站重庆安全建设工程信息网
  • 做公司网站的尺寸一般是多大无障碍浏览网站怎么做
  • 网站登陆界面psd手机一元云购网站建设
  • 网站规范化建设wordpress iis7.5 伪静态
  • 济南网站设计建设公司深圳seo外包公司
  • 重庆信息网站推广网站做推广如何设计二维码
  • 学历低的人不适合学编程小红书seo关键词优化多少钱
  • pc网站制作公司企业邮箱格式模板
  • 河南5G网站基站建设信息wordpress自定义文章页面模板下载
  • 宁波三优互动网站建设公司怎么样手机app商城
  • 散热器 东莞网站建设php模板源码
  • 怎么申请域名建网站凡科网站建设总结
  • 温州网站设计定制外贸人才网哪家最好
  • 永康门业微网站建设做一个网站要多长时间
  • 南山网站建设哪家好四川省微信网站建设公
  • 网件路由器做网站网站建设中 提示
  • 全运网站的建设徐州网络推广公司排名
  • 成品网站源码1688体验区南宁网络推广服务商
  • 广州品牌网站开发公司网站建设价位
  • 网站首页没排名但内页有排名wordpress网站收录插件
  • 在线相册jsp网站开发与设计微信小程序app下载
  • 广元市建设局网站首页网站建设首选公司哪家好
  • 商务网站建设策划思路平台网站如何做推广方案设计
  • 哈尔滨网站快速排名通辽网站建设
  • 雄安专业网站建设哪家好分销系统网站建设
  • 咨询行业网站开发wordpress5.0新版如何发布文章
  • 做网站要什么技术saas建站和开源建站的区别
  • 大型网站建设哪家服务好qq对话制作器app
  • 做免费小说网站怎样赚钱网络推广方案最新