MySQL——MVCC--多版本并發(fā)控制機(jī)制

前言

以下的分析均在mysql的InnoDB引擎下。假設(shè)此時(shí)事務(wù)A與事務(wù)B同時(shí)執(zhí)行。

一、定義:

MVCC(Multi-Version Concurrency Control,多版本并發(fā)控制)一種并發(fā)控制機(jī)制扮授,在數(shù)據(jù)庫(kù)中用來(lái)控制并發(fā)執(zhí)行的事務(wù),控制事務(wù)隔離進(jìn)行专肪。

二刹勃、核心思想:

MVCC是通過保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來(lái)進(jìn)行控制的。使用MVCC就是允許同一個(gè)數(shù)據(jù)記錄擁有多個(gè)不同的版本嚎尤。然后在查詢時(shí)通過添加相對(duì)應(yīng)的約束條件荔仁,就可以獲取用戶想要的對(duì)應(yīng)版本的數(shù)據(jù)。

三、基本數(shù)據(jù)結(jié)構(gòu)

1乏梁、redo log:

重做日志記錄次洼。存儲(chǔ)事務(wù)操作的最新數(shù)據(jù)記錄,方便日后使用遇骑。

2卖毁、undo log

撤回日志記錄,也稱版本鏈落萎。當(dāng)前事務(wù)未提交之前亥啦,undo log保存了當(dāng)前事務(wù)的正在操作的數(shù)據(jù)記錄的所有版本的信息,undo log中的數(shù)據(jù)可作為數(shù)據(jù)舊版本快照供其他并發(fā)事務(wù)進(jìn)行快照讀练链。每次有其它事務(wù)提交對(duì)當(dāng)前數(shù)據(jù)行的修改翔脱,都是添加到undo log中。undo log是由每個(gè)數(shù)據(jù)行的多個(gè)不同的版本鏈接在一起構(gòu)成的一個(gè)記錄“鏈表”媒鼓。如下圖:

3届吁、read_view(快照)

①read_view的簡(jiǎn)單理解:

會(huì)對(duì)數(shù)據(jù)在每個(gè)時(shí)刻的狀態(tài)拍成照片記錄下來(lái)。那么之后獲取某時(shí)刻的數(shù)據(jù)時(shí)就還是原來(lái)的照片上的數(shù)據(jù)绿鸣,是不會(huì)變的疚沐。其實(shí)也可以簡(jiǎn)單理解為是一個(gè)版本鏈的集合,只不過在這里的版本鏈?zhǔn)墙?jīng)過篩選的枚驻。

②read_view的基本結(jié)構(gòu):

read_view->creator_trx_id = 當(dāng)前事務(wù)id; # 當(dāng)前的事務(wù)id
read_view->up_limit_id = 12654;        # 當(dāng)前活躍事務(wù)的最小id
read_view->low_limit_id = 12659;       # 當(dāng)前活躍事務(wù)的最小id
read_view->trx_ids = [12654, 12659];   # 當(dāng)前活躍的事務(wù)的id列表濒旦,又稱活躍事務(wù)鏈表。表示在記錄當(dāng)前快照時(shí)的所有活躍的再登、未提交的事務(wù)
read_view->m_trx_ids = 2;              # 當(dāng)前活躍的事務(wù)id列表長(zhǎng)度

注意:

  • read_view中包含了活躍事務(wù)鏈表,這個(gè)鏈表表示此時(shí)還在活躍的事務(wù)晾剖,指的是那些在當(dāng)前快照中還未提交的事務(wù)锉矢。(注意:新建事務(wù)(當(dāng)前事務(wù))與正在內(nèi)存中commit 的事務(wù)不在活躍事務(wù)鏈表)。
  • read_view中不會(huì)顯示所有的數(shù)據(jù)行齿尽,只會(huì)顯示“可見”的記錄沽损。篩選方式如下所述。

③read_view的記錄篩選方式:

前提:DATA_TRX_ID 表示每個(gè)數(shù)據(jù)行的最新的事務(wù)ID循头;up_limit_id表示當(dāng)前快照中的最先開始的事務(wù)绵估;low_limit_id表示當(dāng)前快照中的最慢開始的事務(wù),即最后一個(gè)事務(wù)卡骂。

  • 如果記錄的DATA_TRX_ID < up_limit_id:在創(chuàng)建read_view時(shí)国裳,修改該記錄的事務(wù)已提交,該記錄可被快照中的事務(wù)讀取到(即可見)全跨。

  • 如果DATA_TRX_ID >= low_limit_id:表示該記錄是在當(dāng)前read_view創(chuàng)建之后被其它事務(wù)修改的缝左,該記錄在當(dāng)前快照中肯定不可見。此時(shí)需要從DB_ROLL_PTR指針?biāo)赶虻幕貪L段中取出最新的undo-log的版本號(hào), 然后用它繼續(xù)重新開始整套比較算法。

  • 如果up_limit_id <= DATA_TRX_ID < low_limit_i:

    • 需要在活躍事務(wù)鏈表中查找是否存在ID為DATA_TRX_ID的值的事務(wù)渺杉。
    • 如果存在蛇数,那么因?yàn)樵诨钴S事務(wù)鏈表中的事務(wù)是未提交的,所以該記錄是不可見的是越。此時(shí)需要從DB_ROLL_PTR指針?biāo)赶虻幕貪L段中取出最新的undo-log的版本號(hào), 然后用它繼續(xù)重新開始整套比較算法耳舅。(詳細(xì)分析為什么“不可見”:因?yàn)镈ATA_TRX_ID只有在事務(wù)提交之后才會(huì)更新,而此時(shí)因?yàn)槭聞?wù)還存在于活躍事務(wù)鏈表中倚评,所以說明事務(wù)是還沒有commit浦徊,所以此時(shí)不可能存在對(duì)應(yīng)的數(shù)據(jù)行,只有在當(dāng)前事務(wù)提交之后才會(huì)有對(duì)應(yīng)的數(shù)據(jù)行蔓纠。)
    • 如果不存在辑畦,所以是可見的。(分析:按照上一點(diǎn)的對(duì)“不可見”原因的分析腿倚,可明白只能是當(dāng)前本事務(wù)更新了這條記錄纯出,因?yàn)樵诋?dāng)前read view中,只能是當(dāng)前事務(wù)和正在內(nèi)存中commit的事務(wù)不在事務(wù)活躍鏈表中敷燎,對(duì)于“正在內(nèi)存中commit的事務(wù)”暂筝,因?yàn)樗€沒有commit,所以肯定是不可能讀取到它的即將要commit的數(shù)據(jù)的硬贯,而所以只能是當(dāng)前事務(wù)對(duì)這個(gè)數(shù)據(jù)行做了修改了焕襟,雖然未提交,但是因?yàn)槭窃诋?dāng)前事務(wù)中饭豹,所以肯定是可以讀取到更新的數(shù)據(jù)的鸵赖。

④read_view的更新方式:

注意:僅分析RC級(jí)別和RR級(jí)別,因?yàn)镸VCC不適用于其它兩個(gè)隔離級(jí)別拄衰。

  • a它褪、對(duì)于Read Committed級(jí)別的:

    • 基本描述:每次執(zhí)行select都會(huì)創(chuàng)建新的read_view,更新舊read_view翘悉,保證能讀取到其他事務(wù)已經(jīng)COMMIT的內(nèi)容(讀提交的語(yǔ)義)茫打;
    • 詳細(xì)分析:假設(shè)當(dāng)前有事務(wù)A和事務(wù)A+1并發(fā)進(jìn)行。在當(dāng)前級(jí)別下妖混,事務(wù)A每次select的時(shí)候會(huì)創(chuàng)建新的read_view老赤,此時(shí)可以簡(jiǎn)單理解為事務(wù)A會(huì)提交,也就是讓事務(wù)A執(zhí)行完畢制市,然后創(chuàng)建一個(gè)新的事務(wù)比如是事務(wù)A+2抬旺。這樣子的話,因?yàn)槭聞?wù)A+2的事務(wù)ID肯定是比事務(wù)A+1的ID大息堂,所以就能夠讀取到事務(wù)A+1的更新了嚷狞。那么便可以讀取到在創(chuàng)建這個(gè)新的read_view之前事務(wù)A+1所提交的所有信息块促。這是RC級(jí)別下能讀取到其他事務(wù)已經(jīng)COMMIT的內(nèi)容的原因所在龄句。
  • b又兵、對(duì)于Repeatable Read級(jí)別的:

    • 第一次select時(shí)更新這個(gè)read_view沥邻,以后不會(huì)再更新崇呵,后續(xù)所有的select都是復(fù)用這個(gè)read_view噩峦。所以能保證每次讀取的一致性状勤,即都是讀取第一次讀取到的內(nèi)容(可重復(fù)讀的語(yǔ)義)谴仙。

注意:通過對(duì)read view的更新方式的分析可以得出:對(duì)于InnoDB下的MVCC來(lái)說央星,RR雖然比RC隔離級(jí)別高啃洋,但是開銷反而相對(duì)少(因?yàn)椴挥妙l繁更新read_view)传货。

read_view的詳細(xì)分析:https://www.iteye.com/blog/mahl1990-2347029

四、MVCC在mysql的具體實(shí)現(xiàn):

4.1宏娄、基本數(shù)據(jù)結(jié)構(gòu)的定義:

在mysql中问裕,在實(shí)現(xiàn)MVCC時(shí),會(huì)為每一個(gè)表添加如下幾個(gè)隱藏的字段:

  • 6字節(jié)的DATA_TRX_ID:
    標(biāo)記了最新更新這條行記錄的transaction id孵坚,每處理一個(gè)事務(wù)粮宛,其值自動(dòng)設(shè)置為當(dāng)前事務(wù)ID(DATA_TRX_ID只有在事務(wù)提交之后才會(huì)更新);

  • 7字節(jié)的DATA_ROLL_PTR:
    一個(gè)rollback指針卖宠,指向當(dāng)前這一行數(shù)據(jù)的上一個(gè)版本巍杈,找之前版本的數(shù)據(jù)就是通過這個(gè)指針,通過這個(gè)指針將數(shù)據(jù)的多個(gè)版本連接在一起構(gòu)成一個(gè)undo log版本鏈扛伍;

  • 6字節(jié)的DB_ROW_ID:
    隱含的自增ID筷畦,如果數(shù)據(jù)表沒有主鍵,InnoDB會(huì)自動(dòng)以DB_ROW_ID產(chǎn)生一個(gè)聚簇索引刺洒。這是一個(gè)用來(lái)唯一標(biāo)識(shí)每一行的字段鳖宾;

  • DELETE BIT位:
    用于標(biāo)識(shí)當(dāng)前記錄是否被刪除,這里的不是真正的刪除數(shù)據(jù)逆航,而是標(biāo)志出來(lái)的刪除攘滩。真正意義的刪除是在commit的時(shí)候。

MVCC在二級(jí)索引結(jié)構(gòu)下的分析:https://www.cnblogs.com/stevenczp/p/8018986.html

4.2纸泡、增刪改查:

①增加:INSERT
  • 設(shè)置新記錄的DATA_TRX_ID為當(dāng)前事務(wù)ID,其他的采用默認(rèn)的赖瞒。
②刪除:DELETE
  • 修改DATA_TRX_ID的值為當(dāng)前的執(zhí)行刪除操作的事務(wù)的ID女揭,然后設(shè)置DELETE BIT為True,表示被刪除栏饮。
③修改:UPDATE <==> INSERT + DELETE
  • 用X鎖鎖定該行(因?yàn)槭菍懖僮鳎?/li>
  • 記錄redo log:將更新之后的數(shù)據(jù)記錄到redo log中吧兔,以便日后使用;
  • 記錄undo log:將更新之后的數(shù)據(jù)記錄到undo log中袍嬉,設(shè)置當(dāng)前數(shù)據(jù)行的DATA_TRX_ID為當(dāng)前事務(wù)ID境蔼,回滾指針DATA_ROLL_PTR指向undo log中的當(dāng)前數(shù)據(jù)行更新之前的數(shù)據(jù)行灶平,同時(shí)設(shè)置更新之前的數(shù)據(jù)行的DATA_TRX_ID為當(dāng)前事務(wù)ID,并且設(shè)置DELETE BIT為True箍土,表示被刪除逢享。
④查找:SELECT
  • 如果當(dāng)前數(shù)據(jù)行的DELETE BIT為False,只查找版本早于當(dāng)前事務(wù)版本的數(shù)據(jù)行(也就是數(shù)據(jù)行的DATA_TRX_ID必須小于等于當(dāng)前事務(wù)的ID)吴藻,這確保當(dāng)前事務(wù)讀取的行都是事務(wù)之前已經(jīng)存在的瞒爬,或者是由當(dāng)前事務(wù)創(chuàng)建或修改的行;
  • 如果當(dāng)前數(shù)據(jù)行的DELETE BIT為True沟堡,表示被刪除侧但,那么只能返回DATA_TRX_ID的值大于當(dāng)前事務(wù)的行。獲取在當(dāng)前事務(wù)開始之前航罗,還沒有被刪除的行禀横。

注意:

  • a、此時(shí)就是要去查找read_view粥血,判斷其中是否有需要的記錄柏锄;
  • b、就算在當(dāng)前事務(wù)提交的時(shí)候立莉,也不會(huì)讀取到DATA_TRX_ID大于當(dāng)前事務(wù)ID的數(shù)據(jù)記錄(而默認(rèn)情況下绢彤,RR隔離級(jí)別下,當(dāng)前事務(wù)一commit蜓耻,就能夠讀取到其他事務(wù)的commit)茫舶。這也是MVCC能夠解決幻讀的原因。

五刹淌、使用MVCC核心優(yōu)勢(shì):

  • 1饶氏、在mysql中,使用MVCC本質(zhì)上是為了在進(jìn)行讀操作的時(shí)候代替加鎖有勾,減少加鎖帶來(lái)的負(fù)擔(dān)疹启。
  • 2、在mysql的InnoDB引擎蔼卡,并且是在RR隔離級(jí)別下喊崖,通過使用MVCC和gap鎖來(lái)解決幻讀問題。

六雇逞、MVCC與四大隔離級(jí)別的關(guān)系的分析:

分析了在MVCC的控制之下荤懂,如何實(shí)現(xiàn)四大隔離級(jí)別。

6.1塘砸、Read Uncimmitted級(jí)別:

由于存在臟讀节仿,即能讀到未提交事務(wù)的數(shù)據(jù)行,所以不適用MVCC掉蔬。原因是MVCC的DATA_TRX_ID只有在事務(wù)提交之后才會(huì)更新廊宪,而在Read uncimmitted級(jí)別下矾瘾,由于是讀取未提交的,所以說MVCC在這個(gè)級(jí)別下是不適用的箭启。

6.2壕翩、Read Committed級(jí)別:

查找操作:
分析:假設(shè)當(dāng)前有事務(wù)A、事務(wù)A+1册烈、數(shù)據(jù)B(DATA_TRX_ID為A-1)戈泼。

  • 事務(wù)A進(jìn)行查找,此時(shí)找出事務(wù)ID小于它本身的赏僧,所以此時(shí)數(shù)據(jù)B可以被找到大猛;
  • 如果在事務(wù)A還沒有執(zhí)行完畢的時(shí)候,事務(wù)A+1對(duì)數(shù)據(jù)B進(jìn)行了更新操作淀零,那么此時(shí)數(shù)據(jù)B的undo log則被更新為“數(shù)據(jù)B(DATA_TRX_ID為A+1)-> 數(shù)據(jù)B(DATA_TRX_ID為A-1)”挽绩;
  • 此時(shí)如果事務(wù)A再次進(jìn)行查找操作,會(huì)更新read_view驾中。更新舊的read_view唉堪,并且開啟新的事務(wù)A+2。那么根據(jù)MVCC的規(guī)定肩民,就能夠找到數(shù)據(jù)B(DATA_TRX_ID為A+1)唠亚,可以找到更新之后的。這樣子的話就等價(jià)于能夠讀取到別的事務(wù)commit的最新的數(shù)據(jù)記錄持痰。這就符合RC級(jí)別的語(yǔ)義灶搜。

6.3、Repeatable Read級(jí)別:

查找操作:
分析:假設(shè)當(dāng)前有:事務(wù)A工窍、事務(wù)A+1割卖,數(shù)據(jù)B(DATA_TRX_ID為A-1)。

  • 事務(wù)A進(jìn)行查找患雏,此時(shí)找出事務(wù)ID小于它本身的鹏溯,所以此時(shí)數(shù)據(jù)B可以被找到;
  • 如果在事務(wù)A還沒有執(zhí)行完畢的時(shí)候淹仑,事務(wù)A+1對(duì)數(shù)據(jù)B進(jìn)行了更新操作丙挽,那么此時(shí)數(shù)據(jù)B的undo log則被更新為“數(shù)據(jù)B(DATA_TRX_ID為A+1)-> 數(shù)據(jù)B(DATA_TRX_ID為A-1)”;
  • 此時(shí)如果事務(wù)A再次進(jìn)行查找操作匀借,那么根據(jù)MVCC的規(guī)定取试,還是只能找到數(shù)據(jù)B(DATA_TRX_ID為A-1)(因?yàn)锽(DATA_TRX_ID為A+1)的事務(wù)ID比當(dāng)前事務(wù)A的事務(wù)ID大,所以不會(huì)被找到)怀吻,不會(huì)找到更新之后的。這樣子的話就等價(jià)于只能夠讀取到事務(wù)A開始時(shí)讀取到的數(shù)據(jù)記錄初婆。這就符合RR級(jí)別的語(yǔ)義蓬坡。

6.4猿棉、Serialization級(jí)別:

串行化由于是會(huì)對(duì)所涉及到的表加鎖,并非行鎖屑咳,自然也就不存在行的版本控制問題

總結(jié):通過上面的分析可得:MVCC只適用于MySQL隔離級(jí)別中的讀已提交(Read committed)和可重復(fù)讀(Repeatable Read)

七萨赁、MVCC、gap鎖解決幻讀問題的分析:

前提:InnoDB引擎兆龙、RR隔離級(jí)別(gap鎖只存在于這個(gè)級(jí)別下)

7.1杖爽、首先了解數(shù)據(jù)記錄的讀取方式:快照讀和當(dāng)前讀

①快照讀:

讀快照,可以讀取數(shù)據(jù)的所有版本信息紫皇,包括舊版本的信息慰安。其實(shí)就是讀取MVCC中的read_view,同時(shí)結(jié)合MVCC進(jìn)行相對(duì)應(yīng)的控制聪铺;

select * from table where ?;
②當(dāng)前讀:

讀當(dāng)前化焕,讀取當(dāng)前數(shù)據(jù)的最新版本。而且讀取到這個(gè)數(shù)據(jù)之后會(huì)對(duì)這個(gè)數(shù)據(jù)加鎖铃剔,防止別的事務(wù)更改撒桨。

(分析:在進(jìn)行寫操作的時(shí)候就需要進(jìn)行“當(dāng)前讀”,讀取數(shù)據(jù)記錄的最新版本)

select * from table where ? lock in share mode;  # 讀鎖
select * from table where ? for update;          # 寫鎖
insert into table values (…); 
update table set ? where ?; 
delete from table where ?;

詳見:http://www.reibang.com/p/27352449bcc0

③RC和RR隔離級(jí)別下的快照讀和當(dāng)前讀:
  • RC隔離級(jí)別下键兜,快照讀和當(dāng)前讀結(jié)果一樣凤类,都是讀取已提交的最新;
  • RR隔離級(jí)別下普气,當(dāng)前讀結(jié)果是其他事務(wù)已經(jīng)提交的最新結(jié)果谜疤,快照讀是讀當(dāng)前事務(wù)之前讀到的結(jié)果。RR下創(chuàng)建快照讀的時(shí)機(jī)決定了讀到的版本棋电。

7.2茎截、解決幻讀問題:

  • ①對(duì)于快照讀:通過MVCC來(lái)進(jìn)行控制的,不用加鎖赶盔。按照MVCC中規(guī)定的“語(yǔ)法”進(jìn)行增刪改查等操作企锌,以避免幻讀。(MVCC的具體內(nèi)容參見上方第1點(diǎn)到第4點(diǎn)的分析)

  • ②對(duì)于當(dāng)前讀:通過next-key鎖(行鎖+gap鎖)來(lái)解決問題的于未。(next-key鎖的分析:mysql中的鎖

7.3撕攒、特殊語(yǔ)句分析:

“MVCC不能根本上解決幻讀的情況?”

分析:這句話的含義是指對(duì)于快照讀烘浦,那么是可以通過MVCC來(lái)解決的抖坪;但是對(duì)于當(dāng)前讀,則必須通過next-key鎖(行鎖+gap鎖)來(lái)解決闷叉。

參考:
https://www.cnblogs.com/axing-articles/p/11415763.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末擦俐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子握侧,更是在濱河造成了極大的恐慌蚯瞧,老刑警劉巖嘿期,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異埋合,居然都是意外死亡备徐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門甚颂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蜜猾,“玉大人,你說我怎么就攤上這事振诬〔渌” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵贷揽,是天一觀的道長(zhǎng)棠笑。 經(jīng)常有香客問我,道長(zhǎng)禽绪,這世上最難降的妖魔是什么蓖救? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮印屁,結(jié)果婚禮上循捺,老公的妹妹穿的比我還像新娘。我一直安慰自己雄人,他們只是感情好从橘,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著础钠,像睡著了一般恰力。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旗吁,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天踩萎,我揣著相機(jī)與錄音,去河邊找鬼很钓。 笑死香府,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的码倦。 我是一名探鬼主播企孩,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼袁稽!你這毒婦竟也來(lái)了勿璃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝗柔,沒想到半個(gè)月后闻葵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癣丧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栈妆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胁编。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鳞尔,靈堂內(nèi)的尸體忽然破棺而出嬉橙,到底是詐尸還是另有隱情,我是刑警寧澤寥假,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布市框,位于F島的核電站,受9級(jí)特大地震影響糕韧,放射性物質(zhì)發(fā)生泄漏枫振。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一萤彩、第九天 我趴在偏房一處隱蔽的房頂上張望粪滤。 院中可真熱鬧,春花似錦雀扶、人聲如沸杖小。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)予权。三九已至,卻和暖如春浪册,著一層夾襖步出監(jiān)牢的瞬間扫腺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工议经, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斧账,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓煞肾,卻偏偏與公主長(zhǎng)得像咧织,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子籍救,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容