## 落盤


```
write('1', $file);
write('2', $file);
write_log('ok');
write 2 時突然斷電,write_log 沒成功,就認為是失敗的,只有 write_log 成功 才算是事務的提交,表示寫入的 1 2 數據 被成功 永久的寫入到磁盤或其它存儲設備了(持久化)。
注意,應用層同步寫,但在操作系統底層,乃至硬件底層不一定同步的,可能存在緩刷盤,所以 write_log 一定要是 操作系統級別和硬件級別的同步刷盤,只有這樣才能保證可靠。
并且還要考慮所使用的編程語言層實現,所以使用越低級的語言就能最大限度,甚至硬件級別的去控制數據的處理,這也體現了 “封裝會泄露” 的概念。
程序并不是作為一個整體(所有代碼并不是原子性的),讓CPU獨立時間片串行執行的(一次執行一個獨立的程序,所有代碼為一個整體),而是被操作系統“大卸八塊”來調度執行的,對應用層來說也可以簡單的理解成代碼是從上到下一行一行執行的,所有代碼最后都是一個一個的系統調用,這些調用的順序,時間我們無法控制,取決于系統調度和IO情況,這個過程可能有多個程序在被這樣處理(只是他們不知道彼此,以為cpu是自己專屬的一樣 —— CPU 是中央空調,且保密工作做的好),所以對應層用來說,每一行代碼都可能和不同的進程、程序 里面某個系統調用(某行代碼)搶奪系統資源(網絡,文件,IO),在這種情況下,編程開始變得復雜,并且開始產生了 事務、并發編程、鎖等概念。
程序的這種執行機制確實使得CPU利用率更高,畢竟沒人愿意使用非批處理計算機。
編程之所以會是這樣,是因為底層平臺是這么設計的,如果換做另一種完全不同的平臺,那么編程的概念可能又是另一種截然不同的光景了。
```
數據只有落盤成功了,才算是持久化了,我們調用保存文件函數返回也成功了,此時文件一定安全的保存好了嗎,如果調用返回后立即斷電呢。
幾乎所有的寫入都被 應用軟件(db/nosql)做了封裝,甚至操作系統也有緩存刷盤機制,所以 上游調用并不知道調用后是否真正落盤了,不過通常也并不需要關心(下游可能會緩存并立即返回寫入成功,上游假裝是成功了就可以,這樣應用速度就會快很多),只有這樣上游應用才能專注于自己的業務邏輯,除非是做那種對準確性穩定些要求超級高的應用,當然這也是一個取舍的問題,準確性&穩定與性能。
將事情交給其他程序做,自己只關心應用層,這樣封裝了的好處是屏蔽掉了底層復雜的實現問題,從而讓開發變得更簡單直觀了,所以當我們調用 `error_log`就不需要擔心并發寫日志是否會錯亂的問題了,只要將寫的請求發出去就可以心安理得的做其他事情了,`應用層` `php` `c` `操作系統` `驅動底層`,每一層都有封裝,最終會按照順序將內容寫入目標文件,至于數據 是不是在調用時就寫入的,還是其它時機寫入的,這些并不重要,只要最后我們準確的得到了沒有錯亂的日志就好了。—— **哪有什么的歲月靜好,只是有人為你負重前行。**
[PHP error\_log 實際運用 - walkingSun - 博客園](https://www.cnblogs.com/followyou/p/46600749ff3894915ff040b50162c645.html)
*****
### 并發寫文件
**并發寫文件會讓文件字節亂掉嗎,可能根本不可能**,因為操作系統,甚至磁盤驅動底層都做了序列化(串行)操作,不會允許出現這樣的操作,除非深入硬件底層,突破上層封裝和驅動,手寫驅動控制硬件才能實現這樣破壞性的操作。
[多進程同時寫一個文件會怎樣? - 楊博東的博客 - CSDN博客](https://blog.csdn.net/yangbodong22011/article/details/63064166/)
[用讀寫鎖三句代碼解決多線程并發寫入文件 z - 武勝-阿偉 - 博客園](https://www.cnblogs.com/zeroone/p/6160232.html)
*****
### 擴展
[淺談mysql事務 - 知乎](https://zhuanlan.zhihu.com/p/52677680)
[硬盤太慢!內存太慢!網絡太慢!全靠我來拯救](https://mp.weixin.qq.com/s/tf76tik8gs6KGMEIWTbAVQ)
> 俗話說,**計算機編程的任何問題,都可以通過增加一個抽象層來解決**,這句話用在我身上就太合適了。?我是緩存(Cache),今天我給大家聊聊我這個抽象層是怎么工作的
[操作系統和Web服務器那點事兒](https://mp.weixin.qq.com/s/-rzyDpckS9CUQblAUac0FQ)
> 這其實就是所謂的**zero copy**技術, 從內核角度看,除了把文件從硬盤讀出來之外,沒有任何的額外copy。
> zero copy技術減少了上下文的切換,避免了數據不斷地在用戶態和核心態搬運,不需要CPU參與數據的復制,提高了系統性能,在ngnix, apache等web 服務器中都引入了zero copy技術。(另外還有一個 寫時復制 技術 也是為了提高系統性能)
[緩存更新的套路](https://coolshell.cn/articles/17416.html)
[無鎖隊列的實現](https://coolshell.cn/articles/8239.html)
> 對于Retry-Loop,我個人感覺其實和鎖什么什么兩樣。只是這種“鎖”的粒度變小了,主要是“鎖”HEAD和TAIL這兩個關鍵資源。而不是整個數據結構。
[SFKP ? 計算機百科丨存儲介質發展史](https://mp.weixin.qq.com/s/G50EpIguF9G5hgS2nEZODg)
[假如有人把支付寶存儲服務器炸了](https://mp.weixin.qq.com/s/Iipiv5njlPDD8BJMUzr0Pw)
[《吊打面試官》系列-緩存雪崩、擊穿、穿透](https://mp.weixin.qq.com/s/tyo_pkTvFo-nODCdkE-d2w)
[double write buffer,你居然沒聽過?](https://mp.weixin.qq.com/s/bkoQ9g4cIcFFZBnpVh8ERQ)
[玩轉 Redis 持久化](https://mp.weixin.qq.com/s/7B2oteX-bpyALQIp-saA3g)
> 順序追加寫入文件會很快,但要寫或者更新結構化數據就很耗時,所以順序寫的性能損耗可以忽略不計
[硬盤太慢!內存太慢!網絡太慢!全靠我來拯救!](https://mp.weixin.qq.com/s/tf76tik8gs6KGMEIWTbAVQ)
[漫畫:要跳槽?這道緩存設計題你有必要看看!](https://mp.weixin.qq.com/s/kldwdfNUloJHGE43VaFeGg)
[事務已提交,數據卻丟了,趕緊檢查下這個配置!!! | 數據庫系列](https://mp.weixin.qq.com/s/-Hx2KKYMEQCcTC-ADEuwVA)
[國產數據庫崛起史](https://mp.weixin.qq.com/s/h6goLk8qofsYtAC3FNWggg)
[我用Rust徒手重寫了一個Spark,并把它開源了](https://mp.weixin.qq.com/s/F9mGwxkpYjprx2DWD__nBQ)
[【系統架構】緩存關注點——先寫DB還是「緩存」?](https://mp.weixin.qq.com/s/Gm7S0a5VN9L57wlry4-t6w)
> 可能你會說本地緩存修改失敗怎么辦?比如重復key啊什么的異常。那你可以反思一下為這種數據為什么可以成功的寫進數據庫。
> 分布式由于是網絡環境,多節點服務,所以可認為所有的一切操作都不可控,都可能會失敗,失敗不一定是單機程序的問題,而是網絡的問題。
[你真的理解零拷貝了嗎?](https://mp.weixin.qq.com/s/8J3Hnr7PX7YBX4hbK8oAQQ)
[分庫分表就能無限擴容嗎](https://mp.weixin.qq.com/s/P9pV7jx9zj30YjZ_p0nSAQ)
> 或許這是一個架構問題,不應該屬于業務范疇,TiDB能徹底解決這個問題嗎?
[ElasticSearch寫入數據的工作原理是什么?](https://mp.weixin.qq.com/s/rw6vmDgXUh0SUUh7uo1APg)
[undo log和redo log](https://www.cnblogs.com/shizheyangde/p/7390122.html)
> Undo日志記錄某數據被修改前的值,可以用來在事務失敗時進行rollback;Redo日志記錄某數據塊被修改后的值,可以用來恢復未寫入data file的已成功事務更新的數據。
> tp日志并發,寫入文件的系統調用,在系統底層中對文件句柄資源是獨占,串行的,每個寫入都是原子性的,再寫這一句的時候,另一句要等這句寫完才能寫,不然字節就亂了,就會出現亂碼,也就是對文件資源每次寫入的字節串是原子性和串行的,只有這樣寫入文件才不會亂碼。
> trace默認傳兩個參數不會實時寫入日志到文件,而是記錄到內存,在腳本執行完畢時一次性執行寫入到日志文件,這樣做的好處是保證了每個請求的日志最終寫入順序是正確的,而不會打亂。所以通常來說我們不用傳第三個參數,但如果你有需要,比如你想記錄的日志信息只想要單條的便于分析,那么可以傳第三個參數:
> tp日志其實也考慮到并發了,日志是寫入到內存,最后才一次性寫入文件的,并不是每次記錄實時寫入的,這樣就規避了并發問題,不然的話就會出現多次請求的日志串聯了,這樣日志就回錯亂了。
~~~
trace($value, '>my-debug', true);
~~~
[為什么寄存器比內存塊?](https://mp.weixin.qq.com/s/QGz_kEs0zyYNdt9sR05q5Q)
[一篇文章理解 Web 緩存](https://mp.weixin.qq.com/s/3SDKNbWZHWenzi34TR38gg)
[緩存的正確使用方式,你都會了嗎?](https://mp.weixin.qq.com/s/pUBa4L1bfF09LgGyq_LSCw)
[Python和Java的硬盤夜話](https://mp.weixin.qq.com/s/0z-KbJS3dvNs2XlsvSGVEw)
[持久化:Java帝國反擊戰](https://mp.weixin.qq.com/s/FrRWFaI2X5x9RpPbXoMq9w)
[三年之久的 etcd3 數據不一致 bug 分析](https://mp.weixin.qq.com/s/qittYHY2GUwhFtvsRDaIAQ)
[降低 80% 的讀寫響應延遲!我們測評了 etcd 3.4 新特性(內含讀寫發展史)](https://mp.weixin.qq.com/s/uLntRRW4R9WQ-I-N-mM0yg)
[重大事故!IO問題引發線上20臺機器同時崩潰](https://mp.weixin.qq.com/s/bpIgifIaoQ7aBtX2zmLXrA)
[就為了一個原子操作,其他CPU核心罷工了](https://mp.weixin.qq.com/s?__biz=MzAwNjkxNzgxNg==&mid=2247485772&idx=1&sn=0f89aa0d44ee2c1d0753e43588cca32d&source=41#wechat_redirect)
[我一頓操作把電腦弄崩了!!!數據全沒了!!!我該怎么辦?](https://mp.weixin.qq.com/s/_3zotlzAl_1OrF1zg3ksKg)
[昨晚上女友問我,你知道啥是文件嗎?于是就有了今天的文章](https://mp.weixin.qq.com/s/NMAYt0mNiVDRM9Ys05WgFw)
[MySQL為什么取消了Query Cache?](https://mp.weixin.qq.com/s/4cbtKU2P5f-S8cILpkCpbQ)
> MySQL8.0取消查詢緩存的另外一個原因是,研究表明,緩存越靠近客戶端,獲得的好處越大。
[老李大戰PHP之file\_put\_contents](https://mp.weixin.qq.com/s/fImYaDiSJDNlBx48bFbEtQ)
[來,聊個小問題](https://mp.weixin.qq.com/s/dfyglaSAfLQzoGLREte3aw)
----
為什么生產測試時第一次api請求快些,每次都是這樣,后面會快一些,過一段時間第一次又慢一點,難道有什么東西存活,緩存。
操作系統,數據庫,網絡,乃至硬件層,為了提高響應速度都有各自的緩存設計,所以這就是為什么第一次明顯比后面慢些的原因。
[機械硬盤隨機IO慢的超乎你的想象](https://mp.weixin.qq.com/s/qz57uPtFaoQ_5z59NSBEUQ)
> 數據庫事務:所有的數據庫在實現事務的時候,都要保證寫數據落盤成功才能返回。但為什么他們 **幾乎都是落盤到自己的事務日志文件里去就返回成功的,而不是直接寫入到數據表文件里。** 這背后的原因還是磁盤讀寫性能問題,事務只需要保證數據落地成功就可以,至于寫到哪里并不重要。寫到數據文件中的話大概率就變成隨機IO了。**如果寫到一個日志文件中,就是地地道道的順序IO,性能就發揮到極致。**
[write文件一個字節后何時發起寫磁盤IO?](https://mp.weixin.qq.com/s/qEsK6X_HwthWUbbMGiydBQ)
> 最后我們要認識到,這套write pagecache+回寫的機制第一目標是性能,不是保證不丟失我們寫入的數據的。如果這時候掉電,臟頁時間未超過dirty\_expire\_centisecs的就真的丟了。如果你做的是和錢相關非常重要的業務,必須保證落盤完成才能返回,那么你就可能需要考慮使用fsync。
[read文件一個字節實際會發生多大的磁盤IO?](https://mp.weixin.qq.com/s/LcuWAg10hxZjCoyR1cMJSQ)
> 操作系統的本意是做到讓你簡單可依賴, 讓你盡量把它當成一個黑盒。
[理解格式化原理](https://mp.weixin.qq.com/s/DobymgQ-TRXrO32wjf2fWQ)
> 比如oracle就是繞開操作系統直接使用裸設備的。**但是這個時候你就無法利用Linux文件系統里為你封裝好的inode、block組成的文件與目錄了,開發工作量會增加。**
~~~
上傳 模板文件的過程中,tp可能生成這一半 殘缺 不完整的 模板緩存文件 [笑哭],所以 原子性 還是很必要的啊,極端情況也還是很容易出現的
~~~
----
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南