◎智谷趋势(ID:zgtrend) | 黄汉城






转自:https://mp.weixin.qq.com/s/RaOBRzL5U7POq6-T_Nbxaw
分享个人经验,保留阅读记录,做时间的朋友
◎智谷趋势(ID:zgtrend) | 黄汉城






转自:https://mp.weixin.qq.com/s/RaOBRzL5U7POq6-T_Nbxaw
相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durability)等。今天想跟大家一起研究下事务内部到底是怎么实现的,在讲解前我想先抛出个问题:
事务想要做到什么效果?
按我理解,无非是要做到可靠性以及并发处理
可靠性:数据库要保证当insert或update操作时抛异常或者数据库crash的时候需要保障数据的操作前后的一致,想要做到这个,我需要知道我修改之前和修改之后的状态,所以就有了undo log和redo log。
并发处理:也就是说当多个并发请求过来,并且其中有一个请求是对数据修改操作的时候会有影响,为了避免读到脏数据,所以需要对事务之间的读写进行隔离,至于隔离到啥程度得看业务系统的场景了,实现这个就得用MySQL 的隔离级别。
下面我首先讲实现事务功能的三个技术,分别是日志文件(redo log 和 undo log),锁技术以及MVCC,然后再讲事务的实现原理,包括原子性是怎么实现的,隔离型是怎么实现的等等。最后在做一个总结,希望大家能够耐心看完
redo log叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。
当事务提交之后会把所有修改信息都会存到该日志中。假设有个表叫做tb1(id,username) 现在要插入数据(3,ceshi)

start transaction;
select balance from bank where name="zhangsan";
// 生成 重做日志 balance=600
update bank set balance = balance - 400;
// 生成 重做日志 amount=400
update finance set amount = amount + 400;
commit;

mysql 为了提升性能不会把每次的修改都实时同步到磁盘,而是会先存到Boffer Pool(缓冲池)里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。
那么问题来了,如果还没来的同步的时候宕机或断电了怎么办?还没来得及执行上面图中红色的操作。这样会导致丢部分已提交事务的修改信息!
所以引入了redo log来记录已成功提交事务的修改信息,并且会把redo log持久化到磁盘,系统重启之后在读取redo log恢复最新数据。
总结:
redo log是用来恢复数据的 用于保障,已提交事务的持久化特性
undo log 叫做回滚日志,用于记录数据被修改前的信息。他正好跟前面所说的重做日志所记录的相反,重做日志记录数据被修改后的信息。undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。
还用上面那两张表

每次写入数据或者修改数据之前都会把修改前的信息记录到 undo log。
undo log 记录事务修改之前版本的数据信息,因此假如由于系统错误或者rollback操作而回滚的话可以根据undo log的信息来进行回滚到没被修改前的状态。
总结:
undo log是用来回滚数据的用于保障 未提交事务的原子性
当有多个请求来读取表中的数据时可以不采取任何操作,但是多个请求里有读请求,又有修改请求时必须有一种措施来进行并发控制。不然很有可能会造成不一致。
解决上述问题很简单,只需用两种锁的组合来对读写请求进行控制即可,这两种锁被称为:
共享锁(shared lock),又叫做”读锁”
读锁是可以共享的,或者说多个读请求可以共享一把锁读数据,不会造成阻塞。
排他锁(exclusive lock),又叫做”写锁”
写锁会排斥其他所有获取锁的请求,一直阻塞,直到写入完成释放锁。

总结:通过读写锁,可以做到读读可以并行,但是不能做到写读,写写并行 事务的隔离性就是根据读写锁来实现的!!!这个后面再说。
MVCC (MultiVersion Concurrency Control) 叫做多版本并发控制。
InnoDB的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列, 一个保存了行的创建时间,一个保存了行的过期时间,当然存储的并不是实际的时间值,而是系统版本号。
以上片段摘自《高性能Mysql》这本书对MVCC的定义。他的主要实现思想是通过数据多版本来做到读写分离。从而实现不加锁读进而做到读写并行。
MVCC在mysql中的实现依赖的是undo log与read view

前面讲的重做日志,回滚日志以及锁技术就是实现事务的基础。
原子性,持久性,隔离性折腾半天的目的也是为了保障数据的一致性!
总之,ACID只是个概念,事务最终目的是要保障数据的可靠性,一致性。
什么是原子性:
一个事务必须被视为不可分割的最小工作单位,一个事务中的所有操作要么全部成功提交,要么全部失败回滚,对于一个事务来说不可能只执行其中的部分操作,这就是事务的原子性。
上面这段话取自《高性能MySQL》这本书对原子性的定义,原子性可以概括为就是要实现要么全部失败,要么全部成功。
以上概念相信大家伙儿都了解,那么数据库是怎么实现的呢?就是通过回滚操作。
所谓回滚操作就是当发生错误异常或者显式的执行rollback语句时需要把数据还原到原先的模样,所以这时候就需要用到undo log来进行回滚,接下来看一下undo log在实现事务原子性时怎么发挥作用的
假设有两个表 bank和finance,表中原始数据如图所示,当进行插入,删除以及更新操作时生成的undo log如下面图所示:

从上图可以了解到数据的变更都伴随着回滚日志的产生:(1) 产生了被修改前数据(zhangsan,1000) 的回滚日志
(2) 产生了被修改前数据(zhangsan,0) 的回滚日志
根据上面流程可以得出如下结论:
思考:为什么先写日志后写数据库?—稍后做解释
为了做到同时成功或者失败,当系统发生错误或者执行rollback操作时需要根据undo log 进行回滚

回滚操作就是要还原到原来的状态,undo log记录了数据被修改前的信息以及新增和被删除的数据信息,根据undo log生成回滚语句,比如:
事务一旦提交,其所作做的修改会永久保存到数据库中,此时即使系统崩溃修改的数据也不会丢失。
先了解一下MySQL的数据存储机制,MySQL的表数据是存放在磁盘上的,因此想要存取的时候都要经历磁盘IO,然而即使是使用SSD磁盘IO也是非常消耗性能的。
为此,为了提升性能InnoDB提供了缓冲池(Buffer Pool),Buffer Pool中包含了磁盘数据页的映射,可以当做缓存来使用:
上面这种缓冲池的措施虽然在性能方面带来了质的飞跃,但是它也带来了新的问题,当MySQL系统宕机,断电的时候可能会丢数据!!!
因为我们的数据已经提交了,但此时是在缓冲池里头,还没来得及在磁盘持久化,所以我们急需一种机制需要存一下已提交事务的数据,为恢复数据使用。
于是 redo log就派上用场了。下面看下redo log是什么时候产生的。
事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。
既然redo log也需要存储,也涉及磁盘IO为啥还用它?
隔离性是事务ACID特性里最复杂的一个。在SQL标准里定义了四种隔离级别,每一种级别都规定一个事务中的修改,哪些是事务之间可见的,哪些是不可见的。
级别越低的隔离级别可以执行越高的并发,但同时实现复杂度以及开销也越大。
Mysql 隔离级别有以下四种(级别由低到高):
只要彻底理解了隔离级别以及他的实现原理就相当于理解了ACID里的隔离型。前面说过原子性,隔离性,持久性的目的都是为了要做到一致性,但隔离型跟其他两个有所区别,原子性和持久性是为了要实现数据的可性保障靠,比如要做到宕机后的恢复,以及错误后的回滚。
那么隔离性是要做到什么呢?隔离性是要管理多个并发读写请求的访问顺序。这种顺序包括串行或者是并行
说明一点,写请求不仅仅是指insert操作,又包括update操作。

总之,从隔离性的实现可以看出这是一场数据的可靠性与性能之间的权衡。
在READ UNCOMMITTED隔离级别下,事务中的修改即使还没提交,对其他事务是可见的。事务可以读取未提交的数据,造成脏读。
因为读不会加任何锁,所以写操作在读的过程中修改数据,所以会造成脏读。好处是可以提升并发处理性能,能做到读写并行。
换句话说,读的操作不能排斥写请求。

一个事务的修改在他提交之前的所有修改,对其他事务都是不可见的。其他事务能读到已提交的修改变化。在很多场景下这种逻辑是可以接受的。
InnoDB在 READ COMMITTED,使用排它锁,读取数据不加锁而是使用了MVCC机制。或者换句话说他采用了读写分离机制。
但是该级别会产生不可重读以及幻读问题。往期:100期面试题汇总
什么是不可重读?
在一个事务内多次读取的结果不一样。
为什么会产生不可重复读?
这跟 READ COMMITTED 级别下的MVCC机制有关系,在该隔离级别下每次 select的时候新生成一个版本号,所以每次select的时候读的不是一个副本而是不同的副本。
在每次select之间有其他事务更新了我们读取的数据并提交了,那就出现了不可重复读

在一个事务内的多次读取的结果是一样的。这种级别下可以避免,脏读,不可重复读等查询问题。mysql 有两种机制可以达到这种隔离级别的效果,分别是采用读写锁以及MVCC。
采用读写锁实现:

为什么能可重复度?只要没释放读锁,在次读的时候还是可以读到第一次读的数据。
优点:实现起来简单
缺点:无法做到读写并行
采用MVCC实现:

为什么能可重复度?因为多次读取只生成一个版本,读到的自然是相同数据。
但是在该隔离级别下仍会存在幻读的问题,关于幻读的解决我打算另开一篇来介绍。
该隔离级别理解起来最简单,实现也最单。在隔离级别下除了不会造成数据不一致问题,没其他优点。


数据库总是从一个一致性的状态转移到另一个一致性的状态.
下面举个例子:zhangsan 从银行卡转400到理财账户
start transaction;
select balance from bank where name="zhangsan";
// 生成 重做日志 balance=600
update bank set balance = balance - 400;
// 生成 重做日志 amount=400
update finance set amount = amount + 400;
commit;
1.假如执行完 update bank set balance = balance – 400;之发生异常了,银行卡的钱也不能平白无辜的减少,而是回滚到最初状态。
2.又或者事务提交之后,缓冲池还没同步到磁盘的时候宕机了,这也是不能接受的,应该在重启的时候恢复并持久化。
3.假如有并发事务请求的时候也应该做好事务之间的可见性问题,避免造成脏读,不可重复读,幻读等。在涉及并发的情况下往往在性能和一致性之间做平衡,做一定的取舍,所以隔离性也是对一致性的一种破坏。
本文出发点是想讲一下Mysql的事务的实现原理。
实现事务采取了哪些技术以及思想?
·END·
作者:小小木
来源:cnblogs.com/wyc1994666/p/11367051.html
版权申明:内容来源网络,版权归原创者所有
转自:https://mp.weixin.qq.com/s/79HhQsZRzzuskP5p5LNONA
◎智谷趋势(ID:zgtrend) | 黄汉城、逍道一
刚刚,恒大“辟谣”了。
今天早些时候,一份《恒大集团有限公司关于恳请支持重大资产重组项目的情况报告》在网上迅速疯传。
这份报告描述出了一种恒大向广东省“诉苦”的画面。由于内容太过耸动,也不知真假,我就不贴出报告了。感兴趣的朋友可以自己找来看看。
恒大对此是打死都不承认的。

“有关我公司重组情况的谣言,相关文件和截图凭空捏造,纯属诽谤……我公司已向公安机关报案……”
耐人寻味的背后,还是耐人寻味。

这事情,绝不简单。

9月17日,全国第一大房企恒大提前偿还了15.65亿美元(约合106亿人民币)的外债。公告表示,此举是为降低债务水平和融资成本。

如此急迫提前偿还,或与房地产融资监管“三条红线”有关。
上个月,住建部和人民银行在北京召开重点房企座谈会,给重点房企划定了“三条红线”:
房企剔除预收款后的资产负债率不得大于70%;
房企的净负债率不得大于100%;
房企的“现金短债比”小于1。
一句话,就是负债水平过高的房企不能再加杠杆,一旦“过线”就不能增加或需严控有息负债规模。
今年上半年房企半年报数据显示,恒大、融创、绿地“三条红线”全踩;中南、世贸“踩线”2条;保利、万科、招商蛇口、中梁“踩线”1条。

看到这里,你应该就不难理解,为什么今年恒大会高调推出两次楼盘打折促销活动了吧。一切,都是为了提(ti)升(qian)业(huan)绩(zhai)。
恒大不容易啊。

2016年是房地产的好日子。
恒大地产想要借壳上市回A股,寻觅了一圈,最后看中四家公司,深深房 、嘉凯城、廊坊发展和梅雁吉祥。
当然,真正的底牌是深深房。
这个应该很好理解,恒大地产制定了将总部迁往深圳的计划,未来跟深圳就是站在同一条船上了。而且深深房又是国企,涉及这么大的资产重组项目,这么敏感的行业(房地产),背靠一家国企,就不是一个人在战斗了嘛。
2016年10月3日,恒大地产跟深深房签署了《关于重组上市的合作协议》,约定深深房发行A股股份来购买恒大地产100%股权,而恒大拿了深深房的股份,也就成了深深房的控股股东。
这个事情谋划了很久,但是四年过去了,都还在镜中水月。
因为它涉及到监管的一条“红线”,就是政策上不允许房地产公司在内地上市。
恒大“挣扎”了一段时间,用起了另外一种融资方式——引入战略投资者。
大家还记得吧,16年前后,是大放水后房地产狂飙突进最疯狂的日子。一二线涨到人人自危,无心工作,三四线小地方也跟着狂涨一倍。
恒大的套路就是下沉到小县城,用高周转的方式赚上一波。在那个黄金时代,傻子都知道加杠杆的好处。
所有人都认为,赌明天一定会有未来。
在这样的氛围下,2017年恒大地产引入了1300亿元的战略投资。
据时代财经整理,首轮8家:中信聚恒(50亿)、广田投资(50亿)、广东唯美(50亿)、中融鼎兴(30亿)、华建(30亿)、美投(30亿)、睿灿投资(30亿)、山东高速公司(30亿)。
第二轮13家:深业集团有限公司(55亿)、宝信投资(50亿)、华达置业(50亿)、麒翔投资(50亿)、键诚投资(35亿)、睿灿投资(35亿)、鸿达投资(30亿)、宇民投资(20亿)、金橙宏源(20亿)、嘉寓(20亿)、深圳中意(10亿)、豪仁物业(10亿)、永合金丰(10亿)。
第三轮6家:山东高速集团(200亿)、苏宁电器集团(200亿)、深圳正威(50亿)、嘉寓(50亿)、广州逸合(50亿)、四川鼎祥(50亿)。

短短一年时间,恒大地产就完成了史上最大规模股权融资,1300亿元到账后,恒大地产估值飙升至4252亿元,一度超过万科A总市值。
真不愧是中国第一、世界五百强的房企。区区一条爱马仕皮带算得了什么。
但是有句话怎么说来着,借来的钱,含着泪也要还完啊。
如果恒大地产能够成功借壳上市,这27家投资者就能一道升天,日日会所。
可惜啊,恒大地产迟迟迈不出这一步。

恒大当年敢签下对赌协议,想必不是贸贸然的决定,而是对自己借壳上市很有信心。
后来不知道什么原因,恒大地产还是没有闯关成功。
可能很多人会问了,这条“不允许房企上市的红线”到底是什么来头?
说起来,这个政策最早可以追溯到1993年。
“当时的情况是经济过热中出现房地产热,土地批租、楼堂馆所建设在各地泛滥”。
为了防止经济过热,上头出了这么一个政策。后来,它就成为了资本市场上的一个行规,贯穿至今。
当然,不是说完完全全就没有机会,而是这条道路充满了艰难险阻,比其他行业的难度高出太多。
可以说,房企的上市之路是非常受歧视的。一方面被视为地方上的经济支柱,一方面又畏之如虎。
不给房企开闸,可能是基于以下几个理由:
第一中国是一个政府主导性经济体。国家习惯于宏观调控,经济热的时候踩刹车,经济冷就的时候加加油。如果房企在经济上行的时候拼命加杠杆,很可能会在说来就来的政策调控下,摔得遍体鳞伤,成为社会系统性风险的最脆弱的那个板块。
第二房地产的风险系数甚高。91年日本房地产泡沫崩盘,93年海南楼市大溃败,历史上的经济大衰败,往往都发生在房地产领域。这个行业特别的重资产,借由土地抵押便可以从金融机构套出贷款,拿了钱去买一块新的土地,之后又可以再抵押融资,不断的开发下去。试问哪个行业有这样的资本炼金术?所以,房企的资产负债率天然就容易冲高,一旦现金流断裂传染性不堪设想。
第三,房地产是国内被骂的最多的行业。
……
所以,房企在资本市场上的待遇,就有点像那种不符合产业升级方向、需要被淘汰掉的污染性产业,很难在股市上分得一杯羹。

关于房地产,政府有无数种调控手法。
不过在我看来,有关部门的调控充满了很多自相矛盾、相互冲突的手段,导致最后的效果大打折扣。
大家想过没有,为什么过去很长一段时间内,越是调控,房价涨得越猛呢?有一个很大的原因,就是里头有部分调控政策的作用,根本就不是抑制房价,而是会推动房价上涨。
比如说,“收紧房企融资渠道”这一条。
这是普通民众特别喜闻乐见的事情,因为他们觉得,全天下最坏的人就是开发商了,不能让他们的日子太舒服。
那就断了房企的粮吧!
听起来很解气,实际上完全是违背经济学原理的。
诸位想过没有,让一件东西价格下跌,难道不应该是加大供应,压缩需求,让特别紧张的供需关系趋向于平衡吗?
所以,你打击房企是几个意思啊?人家没有钱去拿地,无法狂飙突进的去建房子,怎么向市场加大供应呢?
有关部门真正应该做的事情,其实是拼命卖地,然后鼓励房企们都来开发,并且在这个过程中严防开发商囤地、捂盘、惜售,让他们尽快盖好房子扔到市场上去,实行天量供应。
大家一看,好家伙,房子比老家的韭菜还多,就不会有抢房的着急心态。再配合限购限贷等手段,整个市场预期就能降下来。
整个链条是非常简单的。关键点在于想要加大房子供应,地方政府就必须扩大土地供应计划,这样地价可能就会阴跌,动了某些人的奶酪。
真的调控难点在哪,明眼人都知道。有些人就是揣着明白装糊涂。个中滋味,大家自己品品把。

明斯基时刻的警报,到现在都还没有解除。
经过三轮大放水,深圳,上海、北京的房价通通进入全球最贵十个城市行列,比纽约巴黎洛杉矶这些世界顶级城市都要高。
在这个六亿人月收入不足一千的国度里,一个芯片、一台光刻机都造不出来的城市,凭什么房价这么贵?
用脚指头想都知道,动不动就十几二十万/平方米的房价里头,肯定是有泡沫。
中国的工业体系处于外循环,但是房地产是内循环的。我们严防外国人投资地产,对国外热钱严防死守。
这点跟纽约特别不同。
但是你看到了没有,属于60亿人的纽约均价也才64万美元/套,属于14亿人的上海凭什么要90万美元/套?

(数据来源:CBRE世邦魏理仕)
今天,在中美脱钩这种百年未有之大变局下,中国更加担心泡沫的破裂。
与全球科技最发达,金融最强大的国家为敌,实在是充满了风险。
像2014年俄罗斯吞并克里米亚,引发美国对俄罗斯制裁,仅当年就有1515亿美元(约合1万亿元人民币)撤出该国市场,导致股市大跌,卢布贬值,人民生活一片哀鸿遍野。
两个国家到底会不会擦枪走火,谁也不知道。
唯一能够确定的是,绝对不能让泡沫吹得更大了。否则一旦真的遭遇惊涛骇浪,今天的泡沫有多大,明天的肉体就会有痛。
虽然说中国设置了金融防火墙,我们的资本账户并没有完全开放,有非常强大的隔离调控能力,但是如果真的擦枪走火了,能架得住市场蚂蚁搬家吗?
这些,就是今天房地产必然要被死死摁住的原因。
史上最严调控至今已有三年多了,这是我有生以来见过最久的调控期。
但是在肉眼可见的未来,它还远未到结束的时候。
转自:https://mp.weixin.qq.com/s/MSZtfu705Ea8VPXJuPmcCA









恒大对此是打死都不承认的。

“有关我公司重组情况的谣言,相关文件和截图凭空捏造,纯属诽谤……我公司已向公安机关报案……”
耐人寻味的背后,还是耐人寻味。

截至当天收盘,中国恒大跌5.58%,报15.22港元;恒大汽车跌8.63%,报19.28港元。
但是这事情,绝不简单!
不给房企开闸,可能是基于以下几个理由:
第一是一个政府主导性经济体。国家习惯于宏观调控,经济热的时候踩刹车,经济冷就的时候加加油。如果房企在经济上行的时候拼命加杠杆,很可能会在说来就来的政策调控下,摔得遍体鳞伤,成为社会系统性风险的最脆弱的那个板块。
第二房地产的风险系数甚高。91年日本房地产泡沫崩盘,93年海南楼市大溃败,历史上的经济大衰败,往往都发生在房地产领域。这个行业特别的重资产,借由土地抵押便可以从金融机构套出贷款,拿了钱去买一块新的土地,之后又可以再抵押融资,不断的开发下去。试问哪个行业有这样的资本炼金术?所以,房企的资产负债率天然就容易冲高,一旦现金流断裂传染性不堪设想。
第三,房地产是国内被骂的最多的行业。
……
转自:https://mp.weixin.qq.com/s/cFhvwvFTaVbMEnpFqcP3yA
导读
在当前的国际形势下,摸清楚印度的真实底牌,又变成了一门必修课程。

三大王牌
从各项经济数据上看,印度是个不折不扣的大国。



为了缓解国内矛盾,印度的外交和军事路线也频频战狼附体,而在中美脱钩的背景下,全球制造业正在寻找新的土壤,这让印度看到了机会。

弯道超车
2019年1月,《福布斯》(Forbes)杂志照例发布富豪榜单,一位名叫穆克什·安巴尼(Mukesh Ambani)的印度人超越马云,荣膺亚洲首富。其产业横跨制造、通信与互联网,可谓低配版的郭台铭+任正非+马化腾。



但无数的历史已经证明,内需市场可以靠移动互联网赶英超美,制造业却没有那么多能超车的弯道。

三座大山
制造业强国里,有的天赋异禀,如随手一挖就是金矿油田的美利坚;有的历史包袱轻,如彻底推翻旧势力的新中国,只要肯迈开步子,终究能摸着石头过河。但对大多数国家来说,法律、资源、土地都是横亘在制造业崛起之路上的三座大山。



2014年9月, 64岁的纳伦德拉·莫迪(Narendra Modi)就任印度总理。在首都新德里的直播中,莫迪向全世界喊出了“Made in India”的口号。他赋予自己的使命,无疑就是推翻印度制造业头上的三座大山。

铩羽而归
出身古吉拉特邦的莫迪,最大的特点是头铁。


转自:https://mp.weixin.qq.com/s/JrZLDdbMEnYOMHDZKQh4BA