InnoDB存儲引擎架構(gòu)

InnoDB架構(gòu)如下圖所示:

1

如圖所示敲霍,InnoDB存儲引擎由內(nèi)存池和一些后臺線程組成,其各自主要的工作是:

內(nèi)存池主要工作

維護所有進程/線程需要訪問的多個內(nèi)部數(shù)據(jù)結(jié)構(gòu)

緩存磁盤上的數(shù)據(jù)俭茧,方便快速讀取,同時在對磁盤文件修改之前進行緩存

緩存重做日志(redo log)

后臺線程主要工作

刷新內(nèi)存池中的數(shù)據(jù),保證緩沖池中緩存的數(shù)據(jù)最新

將已修改數(shù)據(jù)文件刷新到磁盤文件

保證數(shù)據(jù)庫異常時InnoDB能恢復到正常運行狀態(tài)

2.1淡溯、 InnoDB內(nèi)存池

2.1.1. InnoDB內(nèi)存池架構(gòu)圖

內(nèi)存池架構(gòu)

內(nèi)存池架構(gòu)

2.1.2譬重、 緩沖池

InnoDB緩沖池是為了通過內(nèi)存的速度來彌補磁盤速度慢對數(shù)據(jù)庫性能造成的影響拒逮。其工作方式總是將數(shù)據(jù)庫文件按頁(每頁16K)讀取到緩沖池,然后按最近最少使用(LRU)的算法來保留在緩沖池中的緩存數(shù)據(jù)害幅。在數(shù)據(jù)庫中進行讀操作時消恍,首先將從磁盤讀到的頁存放在緩沖池中,下一次讀取相同的頁時以现,首先判定是否存在緩沖池中狠怨,如果有就是被命中直接讀取,沒有的話就從磁盤中讀取邑遏。在數(shù)據(jù)庫進行改操作時佣赖,首先修改緩沖池中的頁(修改后,該頁即為臟頁)记盒,然后在以一定的頻率刷新到磁盤上憎蛤。這里的刷新機制不是每頁在發(fā)生變更時觸發(fā)。而是通過一種checkpoint機制刷新到磁盤的纪吮。

所以緩沖池的大小直接影響著數(shù)據(jù)庫的整體性能俩檬,可以通過配置參數(shù)innodb_buffer_pool_size來設(shè)置。

從架構(gòu)圖中可以看出緩沖池中緩存的數(shù)據(jù)頁類型有:索引頁碾盟、數(shù)據(jù)頁棚辽、 undo 頁、插入緩沖冰肴、自適應(yīng)哈希索引屈藐、 InnoDB 的鎖信息榔组、數(shù)據(jù)字典信息等。索引頁和數(shù)據(jù)頁占緩沖池的很大一部分联逻。

數(shù)據(jù)頁和索引頁: Page是Innodb存儲的最基本結(jié)構(gòu)搓扯,也是Innodb磁盤管理的最小單位,與數(shù)據(jù)庫相關(guān)的所有內(nèi)容都存儲在Page結(jié)構(gòu)里包归。Page分為幾種類型锨推,數(shù)據(jù)頁和索引頁就是其中最為重要的兩種類型。

插入緩存: 在InnoDB引擎上進行插入操作時箫踩,一般需要按照主鍵順序進行插入爱态,這樣才能獲得較高的插入性能。當一張表中存在非聚簇的且不唯一的索引時境钟,在插入時锦担,數(shù)據(jù)頁的存放還是按照主鍵進行順序存放,但是對于非聚簇索引葉節(jié)點的插入不再是順序的了慨削,這時就需要離散的訪問非聚簇索引頁洞渔,由于隨機讀取的存在導致插入操作性能下降。

InnoDB為此設(shè)計了Insert Buffer來進行插入優(yōu)化缚态。對于非聚簇索引的插入或者更新操作磁椒,不是每一次都直接插入到索引頁中,而是先判斷插入的非聚集索引是否在緩沖池中玫芦,若在浆熔,則直接插入;若不在桥帆,則先放入到一個Insert Buffer中医增。看似數(shù)據(jù)庫這個非聚集的索引已經(jīng)查到葉節(jié)點老虫,而實際沒有叶骨,這時存放在另外一個位置。然后再以一定的頻率和情況進行Insert Buffer和非聚簇索引頁子節(jié)點的合并操作祈匙。這時通常能夠?qū)⒍鄠€插入合并到一個操作中忽刽,這樣就大大提高了對于非聚簇索引的插入性能。

自適應(yīng)哈希索引: InnoDB會根據(jù)訪問的頻率和模式夺欲,為熱點頁建立哈希索引跪帝,來提高查詢效率。InnoDB存儲引擎會監(jiān)控對表上各個索引頁的查詢些阅,如果觀察到建立哈希索引可以帶來速度上的提升歉甚,則建立哈希索引,所以叫做自適應(yīng)哈希索引扑眉。

自適應(yīng)哈希索引是通過緩沖池的B+樹頁構(gòu)建而來纸泄,因此建立速度很快,而且不需要對整張數(shù)據(jù)表建立哈希索引腰素。其 有一個要求聘裁,即對這個頁的連續(xù)訪問模式必須是一樣的,也就是說其查詢的條件(WHERE)必須完全一樣弓千,而且必須是連續(xù)的衡便。

鎖信息 : nnoDB存儲引擎會在行級別上對表數(shù)據(jù)進行上鎖。不過InnoDB也會在數(shù)據(jù)庫內(nèi)部其他很多地方使用鎖洋访,從而允許對多種不同資源提供并發(fā)訪問镣陕。數(shù)據(jù)庫系統(tǒng)使用鎖是為了支持對共享資源進行并發(fā)訪問,提供數(shù)據(jù)的完整性和一致性姻政。關(guān)于鎖的具體知識我們之后再進行詳細學習呆抑。

數(shù)據(jù)字典信息 : InnoDB有自己的表緩存,可以稱為表定義緩存或者數(shù)據(jù)字典汁展。當InnoDB打開一張表鹊碍,就增加一個對應(yīng)的對象到數(shù)據(jù)字典。

數(shù)據(jù)字典是對數(shù)據(jù)庫中的數(shù)據(jù)食绿、庫對象侈咕、表對象等的元信息的集合。在MySQL中器紧,數(shù)據(jù)字典信息內(nèi)容就包括表結(jié)構(gòu)耀销、數(shù)據(jù)庫名或表名、字段的數(shù)據(jù)類型铲汪、視圖熊尉、索引焚挠、表字段信息傻寂、存儲過程、觸發(fā)器等內(nèi)容屋谭。MySQL INFORMATION_SCHEMA庫提供了對數(shù)據(jù)局元數(shù)據(jù)辅斟、統(tǒng)計信息转晰、以及有關(guān)MySQL server的訪問信息(例如:數(shù)據(jù)庫名或表名,字段的數(shù)據(jù)類型和訪問權(quán)限等)士飒。該庫中保存的信息也可以稱為MySQL的數(shù)據(jù)字典查邢。

2.1.3. 重做日志沖池

InnoDB有buffer pool(簡稱bp)。bp是數(shù)據(jù)庫頁面的緩存酵幕,對InnoDB的任何修改操作都會首先在bp的page上進行扰藕,然后這樣的頁面將被標記為dirty并被放到專門的flush list上,后續(xù)將由master thread或?qū)iT的刷臟線程階段性的將這些頁面寫入磁盤(disk or ssd)芳撒。這樣的好處是避免每次寫操作都操作磁盤導致大量的隨機IO邓深,階段性的刷臟可以將多次對頁面的修改merge成一次IO操作未桥,同時異步寫入也降低了訪問的時延。然而芥备,如果在dirty page還未刷入磁盤時冬耿,server非正常關(guān)閉,這些修改操作將會丟失萌壳,如果寫入操作正在進行亦镶,甚至會由于損壞數(shù)據(jù)文件導致數(shù)據(jù)庫不可用。為了避免上述問題的發(fā)生袱瓮,Innodb將所有對頁面的修改操作寫入一個專門的文件缤骨,并在數(shù)據(jù)庫啟動時從此文件進行恢復操作,這個文件就是redo log file尺借。這樣的技術(shù)推遲了bp頁面的刷新绊起,從而提升了數(shù)據(jù)庫的吞吐,有效的降低了訪問時延褐望。帶來的問題是額外的寫redo log操作的開銷(順序IO勒庄,當然很快),以及數(shù)據(jù)庫啟動時恢復操作所需的時間瘫里。

redo日志由兩部分構(gòu)成:redo log buffer实蔽、redo log file。innodb是支持事務(wù)的存儲引擎谨读,在事務(wù)提交時局装,必須先將該事務(wù)的所有日志寫入到redo日志文件中,待事務(wù)的commit操作完成才算整個事務(wù)操作完成劳殖。在每次將redo log buffer寫入redo log file后铐尚,都需要調(diào)用一次fsync操作,因為重做日志緩沖只是把內(nèi)容先寫入操作系統(tǒng)的緩沖系統(tǒng)中哆姻,并沒有確保直接寫入到磁盤上宣增,所以必須進行一次fsync操作。因此矛缨,磁盤的性能在一定程度上也決定了事務(wù)提交的性能爹脾。

InnoDB 存儲引擎先將重做日志信息放入這個緩沖區(qū),然后以一定頻率將其刷新到重做日志文件。重做日志文件一般不需要設(shè)置得很大,因為在下列三種情況下重做日志緩沖中的內(nèi)容會刷新到磁盤的重做日志文件中箕昭。

Master Thread 每一秒將重做日志緩沖刷新到重做日志文件

每個事物提交時會將重做日志緩沖刷新到重做日志文件

當重做日志緩沖剩余空間小于1/2時,重做日志緩沖刷新到重做日志文件

2.1.4. 額外的緩沖池

在 InnoDB 存儲引擎中灵妨,對一些數(shù)據(jù)結(jié)構(gòu)本身的內(nèi)存進行分配時,需要從額外的內(nèi)存池中進行申請落竹。例如: 分配了緩沖池,但是每個緩沖池中的幀緩沖還有對應(yīng)的緩沖控制對象泌霍,這些對象記錄以一些諸如 LRU, 鎖,等待等信息,而這個對象的內(nèi)存需要從額外的內(nèi)存池中申請。

2.2 主要后臺線程

后臺線程架構(gòu)

后臺線程架構(gòu)

2.2.1. master thread

核心的后臺線程述召,主要負責將緩沖池中的數(shù)據(jù)異步刷新到磁盤朱转,保證數(shù)據(jù)的一致性蟹地,包括臟頁的刷新、合并插入緩沖藤为、undo頁的回收等锈津。

Master thread在主循環(huán)中,分兩大部分操作凉蜂,每秒鐘的操作和每10秒鐘的操作:

每秒一次的操作

日志緩沖刷新到磁盤: 即使這個事務(wù)還沒有提交(總是),這點解釋了為什么再大的事務(wù)commit時都很快性誉;

合并插入緩沖(可能): 合并插入并不是每秒都發(fā)生窿吩,InnoDB會判斷當前一秒內(nèi)發(fā)生的IO次數(shù)是否小于5,如果是错览,則系統(tǒng)認為當前的IO壓力很小纫雁,可以執(zhí)行合并插入緩沖的操作。

至多刷新100個InnoDB的緩沖池的臟頁到磁盤(可能) : 這個刷新100個臟頁也不是每秒都在做倾哺,InnoDB引擎通過判斷當前緩沖池中臟頁的比例(buf_get_modified_ratio_pct)是否超過了配置文件中innodb_max_drity_pages_pct參數(shù)(默認是90轧邪,即90%),如果超過了這個閾值羞海,InnoDB引擎認為需要做磁盤同步操作忌愚,將100個臟頁寫入磁盤。

每10秒一次的操作

刷新100個臟頁到磁盤(可能): InnoDB引擎先判斷過去10秒內(nèi)磁盤的IO操作是否小于200次却邓,如果是硕糊,認為當前磁盤有足夠的IO操作能力,即將100個臟頁刷新到磁盤腊徙。

合并至多5個插入緩沖(總是): 此次的合并插入緩沖操作總會執(zhí)行简十,不同于每秒操作時可能發(fā)生的合并操作。

將日志緩沖刷新到磁盤(總是): InnoDB引擎會再次執(zhí)行日志緩沖刷新到磁盤的操作撬腾,與每秒發(fā)生的操作一樣螟蝙。

刪除無用的undo頁(總是): 當對表執(zhí)行update,delete操作時民傻,原先的行會被標記為刪除胰默,但是為了一致性讀的關(guān)系,需保留這些行版本的信息饰潜,在進行10S一次的刪除操作時初坠,InnoDB引擎會判斷當前事務(wù)系統(tǒng)中已被刪除的行是否可以刪除,如果可以彭雾,InnoDB會立即將其刪除碟刺。InnoDB每次最多刪除20個Undo頁。

產(chǎn)生一個檢查點(checkpoing)薯酝;

2.2.2. IO threads

在 InnoDB 存儲引擎中大量使用了異步 IO 來處理寫 IO 請求半沽,IO Thread 的工作主要是負責這些 IO 請求的回調(diào).爽柒。分別為write、read者填、insert buffer和log IO thread浩村。線程數(shù)量可以通過參數(shù)進行調(diào)整。5.6以后的版本可以通過innodb_write_io_threads和innodb_read_io_threads來限制讀寫線程占哟,而在5.6版本以前心墅,只有一個參數(shù)innodb_file_io_threads來控制讀寫總線程數(shù)。

2.2.3. purge threads

負責回收已經(jīng)使用并分配的undo頁榨乎,purge操作默認是由master thread中完成的怎燥,為了減輕master thread的工作,提高cpu使用率以及提升存儲引擎的性能蜜暑。用戶可以在參數(shù)文件中添加如下命令來啟動獨立的purge thread铐姚。

innodb_purge_threads=1

從innodb1.2版本開始,可以指定多個innodb_purge_threads來進一步加快和提高undo回收速度肛捍。

2.2.4. page cleaner threads

Page Cleaner Thread是在InnoDB1.2.X版本中引入的隐绵。其作用是將之前版本中臟頁的刷新操作都放入到單獨的線程中來完成。 其目的是減輕master thread的工作以及對于用戶查詢線程的阻塞拙毫,進一步提高InnoDB存儲引擎的性能依许。

三、InnoDB重要特性

MySQL InnoDB通過如下重要特性實現(xiàn)了更好的新能和更高的特性

插入緩沖(insert buffer)

兩次寫(Double write)

自適應(yīng)哈希索引(adaptive hash index)

異步io(Async IO)

刷新領(lǐng)接頁(Flush Neighbor Page)

3.1 插入緩沖

3.1.1. 舉個栗子

我們?nèi)D書館還書恬偷,對應(yīng)圖書館來說悍手,他是做了insert(增加)操作,管理員在1小時內(nèi)接受了100本書袍患,這時候他有2種做法把還回來的書歸位到書架上:

1)每還回來一本書坦康,根據(jù)這本書的編碼(書柜區(qū)-排-號)把書送回架上

2)暫時不做歸位操作,先放到柜面上诡延,等不忙的時候滞欠,再把這些書按照書柜區(qū)-排-號先排好,然后一次性歸位

用方法1肆良,管理員需要進出(IO)藏書區(qū)100次筛璧,不停的登高爬低完成圖書歸位操作,累死累活惹恃,效率很差夭谤。

用方法2,管理員只需要進出(IO)藏書區(qū)1次巫糙,對同一個位置的書朗儒,不管多少,都只要爬一次樓梯,大大減輕了管理員的工作量醉锄。

所以圖書館都是按照方法2來做還書動作的乏悄。但是你要說,我的圖書館就20本書恳不,1個0.5米的架子檩小,方法2和1管理起來都很方便,這種情況不在我們討論的范圍烟勋。當數(shù)據(jù)量非常小的時候规求,就不存在效率問題了。

關(guān)系數(shù)據(jù)庫在處理插入操作的時候卵惦,處理的方法和上面類似颓哮,每一次插入都相當于還一本書,它也需要一個柜臺來保存插入的數(shù)據(jù)鸵荠,然后分類歸檔,在不忙的時候做批量的歸位伤极。這個柜臺就是insert buffer.

這就是為什么會有insert buffer蛹找,更多的是處于性能優(yōu)化的考慮。

3.1.2. 什么是插入緩沖

insert buffer是一種特殊的數(shù)據(jù)結(jié)構(gòu)(B+ tree)并不是緩存的一部分哨坪,而是物理頁庸疾。對于非聚集索引的插入或更新操作,不是每一次直接插入索引頁.而是先判斷插入的非聚集索引頁是否在緩沖池中.如果在,則直接插入,如果不再,則先放入一個插入緩沖區(qū)中.然后再以一定的頻率執(zhí)行插入緩沖和非聚集索引頁子節(jié)點的合并操作.使用條件:非聚集索引,非唯一,原因如下:

primary key 是按照遞增的順序進行插入的当编,異常插入聚族索引一般也順序的届慈,非隨機IO。

寫唯一索引要檢查記錄是不是存在忿偷,所以在修改唯一索引之前,必須把修改的記錄相關(guān)的索引頁讀出來才知道是不是唯一金顿、這樣Insert buffer就沒意義了,要讀出來(隨機IO)鲤桥,所以只對非唯一索引有效揍拆。

3.1.3. insert buffer的原理

對于為非唯一索引,輔助索引的修改操作并非實時更新索引的葉子頁茶凳,而是把若干對同一頁面的更新緩存起來做嫂拴,合并為一次性更新操 作,減少IO贮喧,轉(zhuǎn)隨機IO為順序IO,這樣可以避免隨機IO帶來性能損耗筒狠,提高數(shù)據(jù)庫的寫性能,具體流程:

1) 先判斷要更新的這一頁在不在緩沖池中

a箱沦、若在辩恼,則直接插入;

b、若不在运挫,則將index page 存入Insert Buffer状共,按照Master Thread的調(diào)度規(guī)則來合并非唯一索引和索引頁中的葉子結(jié)點

2) Master Thread的調(diào)度規(guī)則

a、主動merger: innodb主線程定期完成谁帕,用戶線程無感知

主動merge通過innodb主線程(svr_master_thread)判斷:若過去1s之內(nèi)發(fā)生的I/O小于系統(tǒng)I/O能力的5%峡继,則主動進行一次insert buffer的merge操作。merge的頁面數(shù)為系統(tǒng)I/O能力的5%匈挖,讀取采用async io模式碾牌。每10s,必定觸發(fā)一次insert buffer meger操作。meger的頁面數(shù)仍舊為系統(tǒng) I/O能力的5%儡循。

主線程發(fā)出async io請求舶吗,async讀取需要被merge的索引頁面

I/O handler 線程,在接受到完成的async I/O之后择膝,進行merge

b 誓琼、被動merge: 用戶線程完成,用戶能感受到meger操作帶來的性能影響

insert操作肴捉,導致頁面空間不足腹侣,需要分裂(split)。由于insert buffer只針對單個頁面齿穗,不能buffer page split[頁已經(jīng)在內(nèi)存里]傲隶,因此引起頁面的被動meger。同理窃页,update操作導致頁面空間不 足跺株;purge導致頁面為空等〔甭簦總之,若當前操作引起頁面split or merge乒省,那么就會導致被動merge;

insert操作畦木,由于其它各種原因作儿,insert buffer優(yōu)化返回false,需要真正讀取page時馋劈,要進行被動merge攻锰。與一不同的是,頁在disk上妓雾,需要讀取到內(nèi)存里娶吞;

在進行insert buffer操作,發(fā)現(xiàn)insert buffer太大械姻,需要壓縮insert buffer妒蛇,這時需要強制被動merge,不允許 insert 操作進行。

3.2 兩次寫

Insert Buffer帶給InnoDB存儲引擎的是性能上的提升绣夺,doublewrite(兩次寫)帶給InnoDB存儲引擎的是數(shù)據(jù)頁的可靠性吏奸。

當發(fā)生數(shù)據(jù)庫宕機時,可能InnoDB存儲引擎正在寫入某個頁到表中陶耍,而這個頁只寫了一部分奋蔚,比如16KB的頁,只寫了前4KB烈钞,之后就發(fā)生了宕機泊碑,這種情況被稱為部分寫失效(partial page write)。在InnoDB存儲引擎未使用doublewrite技術(shù)前毯欣,曾經(jīng)出現(xiàn)過因為部分寫失效而導致數(shù)據(jù)丟失的情況馒过。

有經(jīng)驗的DBA也許會想,如果發(fā)生寫失效酗钞,可以通過重做日志進行恢復腹忽。這是一個辦法。但是必須清楚地認識到砚作,重做日志中記錄的是對頁的物理操作留凭,如偏移量800,寫‘a(chǎn)aaa’記錄偎巢。如果這個頁本身已經(jīng)發(fā)生了損壞,再對其進行重做是沒有意義的兼耀。這就是說压昼,在應(yīng)用重做日志前,用戶需要一個頁的副本瘤运,當寫入失效發(fā)生時窍霞,先通過頁的副本來還原該頁,再進行重做拯坟,這就是doublewrite但金。在InnoDB存儲引擎中doublewrite的體系架構(gòu)如圖所示:

3

3.3 自適應(yīng)哈希索引

哈希(hash)是一種非常快的查找方法郁季,在一般情況下這種查找的時間復雜度為O(1)冷溃,即一般僅需要一次查找就能定位數(shù)據(jù)。 而B+樹的查找次數(shù)梦裂,取決于B+樹的高度似枕,在生產(chǎn)環(huán)境中,B+樹的高度一般為3~4層年柠,所以需要3~4次的查詢凿歼。

InnoDB存儲引擎會監(jiān)控對表上各索引頁的查詢。如果觀察到建立哈希索引可以帶來速度提升,則建立哈希索引答憔,稱之為自適應(yīng)哈希索引(Adaptive Hash Index, AHI)味赃。AHI是通過緩沖池的B+樹頁構(gòu)造而來,因此建立的速度很快虐拓,而且不需要對整張表構(gòu)建哈希索引心俗。InnoDB存儲引擎會自動根據(jù)訪問的頻率和模式來自動地為某些熱點頁建立哈希索引。

AHI有一個要求侯嘀,對這個頁的連續(xù)訪問模式必須是一樣的另凌。例如對于(a,b)這樣的聯(lián)合索引頁,其訪問模式可以是下面情況:

where a=xxx

where a =xxx and b=xxx

訪問模式一樣是指查詢的條件是一樣的戒幔,若交替進行上述兩種查詢吠谢,那么InnoDB存儲引擎不會對該頁構(gòu)造AHI。

AHI還有下面幾個要求:

以該模式訪問了100次

頁通過該模式訪問了N次诗茎,其中N=頁中記錄*1/16

InnoDB存儲引擎官方文檔顯示工坊,啟用AHI后,讀取和寫入速度可以提高2倍敢订,輔助索引的連接操作性能可以提高5倍王污。AHI的設(shè)計思想是數(shù)據(jù)庫自優(yōu)化,不需要DBA對數(shù)據(jù)庫進行手動調(diào)整楚午。

3.4 異步IO

sync IO :同步IO 即每進行一次IO操作昭齐,此次操作結(jié)束才能繼續(xù)接下來的操作。 但是如果用戶發(fā)需要等待出一條索引掃描的查詢矾柜,那么這條SQL查詢語句可能需要掃描多個索引頁阱驾,也就是需要進行多次的IO操作。在每掃描一個頁并等待期完成再進行下一次的掃描是沒有必要的怪蔑。

異步IO: 用戶可以在發(fā)出一個IO請求后立即再發(fā)出另一個IO請求里覆,當全部IO請求發(fā)送完畢后,等待所有IO操作的完成缆瓣,這就是AIO喧枷。

AIO另一個優(yōu)勢可以將多個IO,合并為1個IO弓坞,以提高IO效率隧甚。例如:用戶需要訪問3頁內(nèi)容,但這3頁時連續(xù)的渡冻。同步IO需要進行3次IO,而AIO只需要一次 就可以了呻逆。

3.5 刷新領(lǐng)接頁

當刷新一個臟頁時,innodb會檢測該頁所在區(qū)(extent)的所有頁菩帝,如果是臟頁咖城,那么一起進行刷新茬腿。這樣做,通過AIO將多個IO寫入操作合并為一個IO操作宜雀。在傳統(tǒng)機械磁盤下有著顯著優(yōu)勢

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末切平,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辐董,更是在濱河造成了極大的恐慌悴品,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件简烘,死亡現(xiàn)場離奇詭異苔严,居然都是意外死亡,警方通過查閱死者的電腦和手機孤澎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門届氢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人覆旭,你說我怎么就攤上這事退子。” “怎么了型将?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵寂祥,是天一觀的道長。 經(jīng)常有香客問我七兜,道長丸凭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任腕铸,我火速辦了婚禮惜犀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恬惯。我一直安慰自己,他們只是感情好亚茬,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布酪耳。 她就那樣靜靜地躺著,像睡著了一般刹缝。 火紅的嫁衣襯著肌膚如雪碗暗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天梢夯,我揣著相機與錄音言疗,去河邊找鬼。 笑死颂砸,一個胖子當著我的面吹牛噪奄,可吹牛的內(nèi)容都是我干的死姚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼勤篮,長吁一口氣:“原來是場噩夢啊……” “哼都毒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碰缔,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤账劲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后金抡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瀑焦,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年梗肝,在試婚紗的時候發(fā)現(xiàn)自己被綠了榛瓮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡统捶,死狀恐怖榆芦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喘鸟,我是刑警寧澤匆绣,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站什黑,受9級特大地震影響崎淳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜愕把,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一拣凹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恨豁,春花似錦嚣镜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至计福,卻和暖如春跌捆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背象颖。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工佩厚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人说订。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓抄瓦,卻偏偏與公主長得像潮瓶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闺鲸,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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