深入解析MySQL 8.0新特性:Crash Safe DDL

前言

在MySQL 8.0之前的版本中,由于架構(gòu)的原因忿磅,MySQL在server層使用統(tǒng)一的frm文件來存儲表元數(shù)據(jù)信息,這個信息能夠被不同的存儲引擎識別。而實(shí)際上InnoDB本身也存儲有元數(shù)據(jù)信息崔拥。

這給ddl帶來了一定的挑戰(zhàn),因?yàn)檫@種架構(gòu)無法做到ddl的原子化凤覆,我們在線上經(jīng)常能夠看到數(shù)據(jù)目錄下遺留的臨時文件链瓦,或者類似server層和innodb層列個數(shù)不一致之類的錯誤。甚至某些ddl可能還遺留元數(shù)據(jù)在innodb內(nèi)盯桦,而丟失了frm慈俯,導(dǎo)致無法重建表…..(我們?yōu)榱私鉀Q這個問題,實(shí)現(xiàn)了一個叫drop table force的功能拥峦,去強(qiáng)制做清理….)

(以下所有的討論都假定使用InnoDB存儲引擎)

到了8.0版本贴膘,我們知道所有的元數(shù)據(jù)已經(jīng)統(tǒng)一用InnoDB來進(jìn)行管理,這就給實(shí)現(xiàn)原子ddl帶來了可能略号,幾乎所有的對innodb表刑峡,存儲過程洋闽,觸發(fā)器,視圖或者UDF的操作突梦,都能做到原子化:

- 元數(shù)據(jù)修改诫舅,binlog以及innodb的操作都放在一個事務(wù)中
- 增加了一個內(nèi)部隱藏的系統(tǒng)表`mysql.innodb_ddl_log`,ddl操作被記錄到這個表中阳似,注意對該表的操作產(chǎn)生的redo會fsync到磁盤上骚勘,而不會考慮innodb_flush_log_at_trx_commit的配置。當(dāng)崩潰重啟時撮奏,會根據(jù)事務(wù)是否提交來決定通過這張表的記錄去回滾或者執(zhí)行ddl操作
- 增加了一個post-ddl的階段俏讹,這也是ddl的最后一個階段,會去:1. 真正的物理刪除或重命名文件; 2. 刪除innodb_ddl_log中的記錄項; 3.對于一些ddl操作還會去更新其動態(tài)元數(shù)據(jù)信息(存儲在`mysql.innodb_dynamic_metadata`畜吊,例如corrupt  flag, auto_inc值等)
- 一個正常運(yùn)行的ddl結(jié)束后泽疆,其ddl log也應(yīng)該被清理,如果這中間崩潰了玲献,重啟時會去嘗試重放:1.如果已經(jīng)走到最后一個ddl階段的(commit之后)殉疼,就replay ddl log,把ddl完成掉捌年;2. 如果處于某個中間態(tài)瓢娜,則回滾ddl

由于引入了atomic ddl, 有些ddl操作的行為也發(fā)生了變化:

- DROP TABLE: 在之前的版本中礼预,一個drop table語句中如果要刪多個表眠砾,比如t1,t2, t2不存在時,t1會被刪除托酸。但在8.0中褒颈,t1和t2都不會被刪除,而是拋出錯誤励堡。因此要注意5.7->8.0的復(fù)制問題 (DROP VIEW, CREATE USER也有類似的問題)
- DROP DATABASE: 修改元數(shù)據(jù)和ddl_log先提交事務(wù)应结,而真正的物理刪除數(shù)據(jù)文件放在最后刨疼,因此如果在刪除文件時崩潰,重啟時會根據(jù)ddl_log繼續(xù)執(zhí)行drop database

測試:

MySQL很貼心的加了一個選項

innodb_print_ddl_logs鹅龄,打開后我們可以從錯誤日志看到對應(yīng)的ddl log币狠,下面我們通過這個來看下一些典型ddl的過程

root@(none) 11:12:19>SET GLOBAL innodb_print_ddl_logs = 1;                                                                                                                                    
Query OK, 0 rows affected (0.00 sec)

root@(none) 11:12:22>SET GLOBAL log_error_verbosity = 3;                                                                                                                                                       
Query OK, 0 rows affected (0.00 sec)

CREATE DATABASE

mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.02 sec)

創(chuàng)建數(shù)據(jù)庫語句沒有寫log_ddl,可能覺得這不是高頻操作砾层,如果創(chuàng)建database的過程中失敗了漩绵,重啟后可能需要手動刪除目錄。

CREATE TABLE

mysql> USE test;
Database changed
mysql> CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
Query OK, 0 rows affected (0.06 sec)

[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=428, thread_id=7, space_id=76, old_file_path=./test/t1.ibd]
[InnoDB] DDL log delete : by id 428
[InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=429, thread_id=7, table_id=1102, new_file_path=test/t1]
[InnoDB] DDL log delete : by id 429
[InnoDB] DDL log insert : [DDL record: FREE, id=430, thread_id=7, space_id=76, index_id=190, page_no=4]
[InnoDB] DDL log delete : by id 430
[InnoDB] DDL log post ddl : begin for thread id : 7
InnoDB] DDL log post ddl : end for thread id : 7

從日志來看有三類操作肛炮,實(shí)際上描述了如果操作失敗需要進(jìn)行的三項逆向操作:刪除數(shù)據(jù)文件止吐,釋放內(nèi)存中的數(shù)據(jù)詞典信息宝踪,刪除索引btree。在創(chuàng)建表之前碍扔,這些數(shù)據(jù)被寫入到ddl_log中瘩燥,在創(chuàng)建完表并commit后,再從ddl log中刪除這些記錄不同。

另外上述日志中還有DDL log delete日志厉膀,其實(shí)在每次寫入ddl log時是單獨(dú)事務(wù)提交的,但在提交之后二拐,會使用當(dāng)前事務(wù)執(zhí)行一條delete操作服鹅,直到操作結(jié)束了才會提交。

加列(instant)

mysql> ALTER TABLE t1 ADD COLUMN c INT;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0


[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log post ddl : end for thread id : 7

注意這里執(zhí)行的是Instant ddl, 這是8.0.13新支持的特性百新,加列操作可以只修改元數(shù)據(jù)企软,因此從ddl log中無需記錄數(shù)據(jù)

刪列

mysql> ALTER  TABLE t1 DROP COLUMN c;
Query OK, 0 rows affected (2.77 sec)
Records: 0  Duplicates: 0  Warnings: 0


[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=487, thread_id=7, space_id=83, old_file_path=./test/#sql-ib1108-1917598001.ibd]
[InnoDB] DDL log delete : by id 487
[InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=488, thread_id=7, table_id=1109, new_file_path=test/#sql-ib1108-1917598001]
[InnoDB] DDL log delete : by id 488
[InnoDB] DDL log insert : [DDL record: FREE, id=489, thread_id=7, space_id=83, index_id=200, page_no=4]
[InnoDB] DDL log delete : by id 489

[InnoDB] DDL log insert : [DDL record: DROP, id=490, thread_id=7, table_id=1108]
[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=491, thread_id=7, space_id=82, old_file_path=./test/#sql-ib1109-1917598002.ibd, new_file_path=./test/t1.ibd]
[InnoDB] DDL log delete : by id 491
[InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=492, thread_id=7, table_id=1108, old_file_path=test/#sql-ib1109-1917598002, new_file_path=test/t1]
[InnoDB] DDL log delete : by id 492
[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=493, thread_id=7, space_id=83, old_file_path=./test/t1.ibd, new_file_path=./test/#sql-ib1108-1917598001.ibd]
[InnoDB] DDL log delete : by id 493
[InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=494, thread_id=7, table_id=1109, old_file_path=test/t1, new_file_path=test/#sql-ib1108-1917598001]
[InnoDB] DDL log delete : by id 494
[InnoDB] DDL log insert : [DDL record: DROP, id=495, thread_id=7, table_id=1108]
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=496, thread_id=7, space_id=82, old_file_path=./test/#sql-ib1109-1917598002.ibd]

[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=496, thread_id=7, space_id=82, old_file_path=./test/#sql-ib1109-1917598002.ibd]
[InnoDB] DDL log replay : [DDL record: DROP, id=495, thread_id=7, table_id=1108]
[InnoDB] DDL log replay : [DDL record: DROP, id=490, thread_id=7, table_id=1108]
[InnoDB] DDL log post ddl : end for thread id : 7

這是個典型的三階段ddl的過程:分為prepare, perform 以及commit三個階段:

  • Prepare: 這個階段會修改元數(shù)據(jù),創(chuàng)建臨時ibd文件#sql-ib1108-1917598001.ibd, 如果發(fā)生異常崩潰饭望,我們需要能把這個臨時文件刪除掉仗哨, 因此和create table類似,也為這個idb寫了三條日志:delete space, remove cache,以及free btree

  • Perform: 執(zhí)行操作铅辞,將數(shù)據(jù)拷貝到上述ibd文件中厌漂,(同時處理online dmllog), 這部分不涉及l(fā)og ddl操作

  • Commit: 更新數(shù)據(jù)詞典信息并提交事務(wù), 這里會寫幾條日志:

    DROP : table_id=1108

    RENAME SPACE: #sql-ib1109-1917598002.ibd文件被rename成t1.ibd

    RENAME TABLE: #sql-ib1109-1917598002被rename成t1

    RENAME SPACE: t1.ibd 被rename成#sql-ib1108-1917598001.ibd

    RENAME TABLE: t1表被rename成#sql-ib1108-1917598001

    DROP TABLE: table_id=1108

    DELETE SPACE: 刪除#sql-ib1109-1917598002.ibd

實(shí)際上這一步寫的ddl log描述了commit階段操作的逆向過程:將t1.ibd rename成#sql-ib1109-1917598002, 并將sql-ib1108-1917598001 rename成t1表,最后刪除舊表斟珊。其中刪除舊表的操作這里不執(zhí)行桩卵,而是到post-ddl階段執(zhí)行

  • Post-ddl: 在事務(wù)提交后,執(zhí)行最后的操作:replay ddl log, 刪除舊文件倍宾,清理mysql.innodb_dynamic_metadata中相關(guān)信息

    DELETE SPACE:

    sql-ib1109-1917598002.ibd

    DROP: table_id=1108

    DROP: table_id=1108

加索引

mysql> ALTER TABLE t1 ADD KEY(b);
Query OK, 0 rows affected (0.14 sec)
Records: 0  Duplicates: 0  Warnings: 0


[InnoDB] DDL log insert : [DDL record: FREE, id=431, thread_id=7, space_id=76, index_id=191, page_no=5]
[InnoDB] DDL log delete : by id 431

[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log post ddl : end for thread id : 7

創(chuàng)建索引采用inplace創(chuàng)建的方式,沒有臨時文件胜嗓,但如果異常發(fā)生的話高职,依然需要在發(fā)生異常時清理臨時索引, 因此增加了一條FREE log,用于異常發(fā)生時能夠刪除臨時索引辞州。

TRUNCATE TABLE

mysql> TRUNCATE TABLE t1;
Query OK, 0 rows affected (0.13 sec)


[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=439, thread_id=7, space_id=77, old_file_path=./test/#sql-ib1103-1917597994.ibd, new_file_path=./test/t1.ibd]
[InnoDB] DDL log delete : by id 439
[InnoDB] DDL log insert : [DDL record: DROP, id=440, thread_id=7, table_id=1103]
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=441, thread_id=7, space_id=77, old_file_path=./test/#sql-ib1103-1917597994.ibd]
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=442, thread_id=7, space_id=78, old_file_path=./test/t1.ibd]
[InnoDB] DDL log delete : by id 442
[InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=443, thread_id=7, table_id=1104, new_file_path=test/t1]
[InnoDB] DDL log delete : by id 443
[InnoDB] DDL log insert : [DDL record: FREE, id=444, thread_id=7, space_id=78, index_id=194, page_no=4]
[InnoDB] DDL log delete : by id 444
[InnoDB] DDL log insert : [DDL record: FREE, id=445, thread_id=7, space_id=78, index_id=195, page_no=5]
[InnoDB] DDL log delete : by id 445

[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=441, thread_id=7, space_id=77, old_file_path=./test/#sql-ib1103-1917597994.ibd]
[InnoDB] DDL log replay : [DDL record: DROP, id=440, thread_id=7, table_id=1103]
[InnoDB] DDL log post ddl : end for thread id : 7

Truncate table是個比較有意思的話題怔锌,在早期5.6及之前的版本中, 是通過刪除舊表創(chuàng)建新表的方式來進(jìn)行的,5.7之后為了保證原子性变过,改成了原地truncate文件埃元,同時增加了一個truncate log文件,如果在truncate過程中崩潰媚狰,可以通過這個文件在崩潰恢復(fù)時重新truncate岛杀。

到了8.0版本,又恢復(fù)成了刪除舊表崭孤,創(chuàng)建新表的方式类嗤,與之前不同的是糊肠,8.0版本在崩潰時可以回滾到舊數(shù)據(jù),而不是再次執(zhí)行遗锣。以上述為例货裹,主要包括幾個步驟:

  • 將表t1.ibd rename成#sql-ib1103-1917597994.ibd

  • 創(chuàng)建新文件t1.ibd

  • post-ddl: 將老文件#sql-ib1103-1917597994.ibd刪除

RENAME TABLE

mysql> RENAME TABLE t1 TO t2;
Query OK, 0 rows affected (0.06 sec)

DDL LOG:

[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=450, thread_id=7, space_id=78, old_file_path=./test/t2.ibd, new_file_path=./test/t1.ibd]
[InnoDB] DDL log delete : by id 450
[InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=451, thread_id=7, table_id=1104, old_file_path=test/t2, new_file_path=test/t1]
[InnoDB] DDL log delete : by id 451

[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log post ddl : end for thread id : 7

這個就比較簡單了,只需要記錄rename space 和rename table的逆操作即可. post-ddl不需要做實(shí)際的操作

DROP TABLE

DROP TABLE t2
[InnoDB] DDL log insert : [DDL record: DROP, id=595, thread_id=7, table_id=1119]
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=596, thread_id=7, space_id=93, old_file_path=./test/t2.ibd]

[InnoDB] DDL log post ddl : begin for thread id : 7
[InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=596, thread_id=7, space_id=93, old_file_path=./test/t2.ibd]
[InnoDB] DDL log replay : [DDL record: DROP, id=595, thread_id=7, table_id=1119]
[InnoDB] DDL log post ddl : end for thread id : 7

先在ddl log中記錄下需要刪除的數(shù)據(jù)精偿,再提交后弧圆,再最后post-ddl階段執(zhí)行真正的刪除表對象和文件操作

代碼實(shí)現(xiàn)

主要實(shí)現(xiàn)代碼集中在文件storage/innobase/log/log0ddl.cc中,包含了向log_ddl表中插入記錄以及replay的邏輯笔咽。

隱藏的innodb_log_ddl表結(jié)構(gòu)如下

  def->add_field(0, "id", "id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT");
  def->add_field(1, "thread_id", "thread_id BIGINT UNSIGNED NOT NULL");
  def->add_field(2, "type", "type INT UNSIGNED NOT NULL");
  def->add_field(3, "space_id", "space_id INT UNSIGNED");
  def->add_field(4, "page_no", "page_no INT UNSIGNED");
  def->add_field(5, "index_id", "index_id BIGINT UNSIGNED");
  def->add_field(6, "table_id", "table_id BIGINT UNSIGNED");
  def->add_field(7, "old_file_path",
                 "old_file_path VARCHAR(512) COLLATE UTF8_BIN");
  def->add_field(8, "new_file_path",
                 "new_file_path VARCHAR(512) COLLATE UTF8_BIN");
  def->add_index(0, "index_pk", "PRIMARY KEY(id)");
  def->add_index(1, "index_k_thread_id", "KEY(thread_id)");

記錄類型

根據(jù)不同的操作類型搔预,可以分為如下幾類:

FREE_TREE_LOG

目的是釋放索引btree,入口函數(shù):

log_DDL::write_free_tree_log拓轻,在創(chuàng)建索引和刪除表時會調(diào)用到斯撮。

對于drop table中涉及的刪索引操作,log ddl的插入操作放到父事務(wù)中扶叉,一起要么提交要么回滾
對于創(chuàng)建索引的case, log ddl就需要單獨(dú)提交勿锅,父事務(wù)將記錄標(biāo)記刪除,這樣后面如果ddl回滾了枣氧,也能將殘留的index刪掉溢十。

DELETE_SPACE_LOG

入口函數(shù):

Log_DDL::write_delete_space_log

用于記錄刪除tablespace操作,同樣分為兩種情況:

  1. drop table/tablespace, 寫入的記錄隨父事務(wù)一起提交达吞,并在post-ddl階段replay

  2. 創(chuàng)建tablespace, 寫入的記錄單獨(dú)提交张弛,并被父事務(wù)標(biāo)記刪除,如果父事務(wù)回滾酪劫,就通過replay刪除參與的tablespace

  3. RENAME_SPACE_LOG

入口函數(shù):

Log_DDL::write_rename_space_log

用于記錄rename操作吞鸭,例如如果我們把表t1 rename成t2,在其中就記錄了逆向操作t2 rename to t1。

在函數(shù)Fil_shard::space_rename()中覆糟,總是先寫ddl log, 再做真正的rename操作. 寫日志的過程同樣是獨(dú)立事務(wù)提交刻剥,父事務(wù)做未提交的刪除操作

DROP_LOG

入口函數(shù): Log_DDL::write_drop_log

用于記錄刪除表對象操作,這里不涉及文件層操作滩字,寫ddl log在父事務(wù)中執(zhí)行

RENAME_TABLE_LOG

入口函數(shù):

Log_DDL::write_rename_table_log

用于記錄rename table對象的逆操作造虏,和rename space類似,也是獨(dú)立事務(wù)提交ddl log, 父事務(wù)標(biāo)記刪除

REMOVE_CACHE_LOG

入口函數(shù):

Log_DDL::write_remove_cache_log

用于處理內(nèi)存表對象的清理麦箍,獨(dú)立事務(wù)提交漓藕,父事務(wù)標(biāo)記刪除

ALTER_ENCRYPT_TABLESPACE_LOG

入口函數(shù):

Log_DDL::write_alter_encrypt_space_log

用于記錄對tablespace加密屬性的修改,獨(dú)立事務(wù)提交. 在寫完ddl log后修改tablespace page0 中的加密標(biāo)記

綜上挟裂,在ddl的過程中可能會提交多次事務(wù)享钞,大概分為三類:

  • 獨(dú)立事務(wù)寫ddl log并提交,父事務(wù)標(biāo)記刪除, 如果父事務(wù)提交了诀蓉,ddl log也被順便刪除了嫩与,如果父事務(wù)回滾了寝姿,那就要根據(jù)ddl log做逆操作來回滾ddl

  • 獨(dú)立事務(wù)寫ddl log 并提交, (目前只有ALTER_ENCRYPT_TABLESPACE_LOG)

  • 使用父事務(wù)寫ddl log,在ddl結(jié)束時提交划滋。需要在post-ddl階段處理

post_ddl

如上所述饵筑,有些ddl log是隨著父事務(wù)一起提交的,有些則在post-ddl階段再執(zhí)行, post_ddl發(fā)生在父事提交或回滾之后: 若事務(wù)回滾处坪,根據(jù)ddl log做逆操作根资,若事務(wù)提交,在post-ddl階段做最后真正不可逆操作(例如刪除文件)

入口函數(shù): Log_DDL::post_ddl -->Log_DDL::replay_by_thread_id

根據(jù)執(zhí)行ddl的線程thread id通過innodb_log_ddl表上的二級索引同窘,找到log id,再到聚集索引上找到其對應(yīng)的記錄項玄帕,然后再replay這些操作,完成ddl后想邦,清理對應(yīng)記錄

崩潰恢復(fù)

在崩潰恢復(fù)結(jié)束后裤纹,會調(diào)用ha_post_recover接口函數(shù),進(jìn)而調(diào)用innodb內(nèi)的函數(shù)Log_DDL::recover(), 同樣的replay其中的記錄丧没,并在結(jié)束后刪除記錄鹰椒。但ALTER_ENCRYPT_TABLESPACE_LOG類型并不是在這一步刪除,而是加入到一個數(shù)組ts_encrypt_ddl_records中,在之后調(diào)用resume_alter_encrypt_tablespace來恢復(fù)操作呕童。

參考文檔

  1. 官方文檔:

    https://dev.mysql.com/doc/refman/8.0/en/atomic-ddl.html

  2. WL#9536: InnoDB_New_DD: Support crash-safe DDL

    https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont684418.13.7b5b4116dYdg9Y&id=9536

點(diǎn)關(guān)注漆际,不迷路

好了各位,以上就是這篇文章的全部內(nèi)容了夺饲,能看到這里的人呀奸汇,都是人才。之前說過往声,PHP方面的技術(shù)點(diǎn)很多擂找,也是因?yàn)樘嗔耍瑢?shí)在是寫不過來浩销,寫過來了大家也不會看的太多贯涎,所以我這里把它整理成了PDF和文檔,如果有需要的可以

點(diǎn)擊進(jìn)入暗號:簡書

ziliao4.png
ziliao5.png

更多學(xué)習(xí)內(nèi)容可以訪問【對標(biāo)大廠】精品PHP架構(gòu)師教程目錄大全撼嗓,只要你能看完保證薪資上升一個臺階(持續(xù)更新)

以上內(nèi)容希望幫助到大家,很多PHPer在進(jìn)階的時候總會遇到一些問題和瓶頸欢唾,業(yè)務(wù)代碼寫多了沒有方向感且警,不知道該從那里入手去提升,對此我整理了一些資料礁遣,包括但不限于:分布式架構(gòu)斑芜、高可擴(kuò)展、高性能祟霍、高并發(fā)杏头、服務(wù)器性能調(diào)優(yōu)盈包、TP6,laravel醇王,YII2呢燥,Redis,Swoole寓娩、Swoft叛氨、Kafka、Mysql優(yōu)化棘伴、shell腳本寞埠、Docker、微服務(wù)焊夸、Nginx等多個知識點(diǎn)高級進(jìn)階干貨需要的可以免費(fèi)分享給大家仁连,需要的可以加入我的PHP技術(shù)交流群953224940

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阱穗,隨后出現(xiàn)的幾起案子饭冬,更是在濱河造成了極大的恐慌,老刑警劉巖颇象,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伍伤,死亡現(xiàn)場離奇詭異,居然都是意外死亡遣钳,警方通過查閱死者的電腦和手機(jī)扰魂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕴茴,“玉大人劝评,你說我怎么就攤上這事【氲恚” “怎么了蒋畜?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撞叽。 經(jīng)常有香客問我姻成,道長,這世上最難降的妖魔是什么愿棋? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任科展,我火速辦了婚禮,結(jié)果婚禮上糠雨,老公的妹妹穿的比我還像新娘才睹。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布琅攘。 她就那樣靜靜地躺著垮庐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坞琴。 梳的紋絲不亂的頭發(fā)上哨查,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音置济,去河邊找鬼解恰。 笑死,一個胖子當(dāng)著我的面吹牛浙于,可吹牛的內(nèi)容都是我干的护盈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼羞酗,長吁一口氣:“原來是場噩夢啊……” “哼腐宋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起檀轨,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤胸竞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后参萄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卫枝,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年讹挎,在試婚紗的時候發(fā)現(xiàn)自己被綠了校赤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡筒溃,死狀恐怖马篮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怜奖,我是刑警寧澤浑测,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站歪玲,受9級特大地震影響迁央,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滥崩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一岖圈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夭委,春花似錦幅狮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至慌烧,卻和暖如春逐抑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屹蚊。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工厕氨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汹粤。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓命斧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘱兼。 傳聞我的和親對象是個殘疾皇子国葬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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

  • MySQL 8.0 正式版 8.0.11 已發(fā)布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍芹壕,...
    秦澤超閱讀 8,397評論 0 1
  • 最近MySQL發(fā)布了被期待已久的8.0汇四,GA版本為8.0.11,可以說是喜大普奔了踢涌,MySQL發(fā)行版本可以參照:M...
    Better朔閱讀 2,764評論 0 2
  • 久違的晴天通孽,家長會。 家長大會開好到教室時睁壁,離放學(xué)已經(jīng)沒多少時間了背苦。班主任說已經(jīng)安排了三個家長分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,520評論 16 22
  • 今天感恩節(jié)哎堡僻,感謝一直在我身邊的親朋好友糠惫。感恩相遇!感恩不離不棄钉疫。 中午開了第一次的黨會硼讽,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,562評論 0 11
  • 可愛進(jìn)取,孤獨(dú)成精牲阁。努力飛翔固阁,天堂翱翔。戰(zhàn)爭美好城菊,孤獨(dú)進(jìn)取备燃。膽大飛翔,成就輝煌凌唬。努力進(jìn)取并齐,遙望,和諧家園】鐾剩可愛游走...
    趙原野閱讀 2,726評論 1 1