1. 程式人生 > >mySQL 事物提交成功不等於資料儲存成功

mySQL 事物提交成功不等於資料儲存成功

最近遇到過生產上的資料丟失問題,看到大家各種分析程式碼,然後我發現很多人認為事物提交了就認為資料不會丟失!!!。。。我只能說這是公司沒有DBA或者說大家不能深層次理解mySQL原理的悲哀!

針對此,特意寫了這篇部落格!(理解不深刻不準確之處,敬請指出)

現象

正常情況下,我們會將一系列增,刪,改操作寫在一個事物中,也就是一個原子操作,那麼理論上這一系列的操作,要麼會同時成功,要麼會同時失敗(回滾)!

但實際上呢,資料庫返回失敗,那麼這一系列資料庫操作肯定都不會成功,但如果資料庫返回成功,那麼絕大部分情況都會會全部成功,但也有可能會部分成功,或者全部不成功。這也就是資料丟失。

mysql的資料丟失大致可以分為:

儲存引擎層面丟失資料

在實際專案中,我們一般接觸到的是支援事物的InnoDB儲存引擎,此處只講innoDB儲存引擎的資料丟失。

InnoDB預設開啟內部的XA事物(實現方式是基於redo logundo log),也就是採用日誌先行的策略。在未開啟binlog的情況下,資料變更(資料的增,刪,改操作)會在記憶體中操作,並將事物順序寫入到redo log中,這時就會認為事物已經完成,響應事物提交成功。然後在一定條件下,才將記憶體中的資料合併到磁碟中。

所以,在持久化到磁碟的過程中,如果伺服器宕機等導致記憶體中的資料丟失,資料也就會丟失。不過這種資料丟失是可以通過 recovery 重做日誌,找回資料的。

      這就是前面描述的資料丟失,根本原因就是記憶體中的資料沒有及時重新整理到磁碟中。 所以InnoDB有一個特別的引數用於設定這兩個快取的重新整理: innodb_flush_log_at_trx_commit.

      預設,innodb_flush_log_at_trx_commit=1,表示在每次事務提交的時候,都把log buffer刷到檔案系統中去,並且呼叫檔案系統的“flush”操作將快取重新整理到磁碟上去。這樣的話,資料庫對IO的要求就非常高了,如果底層的硬體提供的IOPS比較差,那麼MySQL資料庫的併發很快就會由於硬體IO的問題而無法提升。

      為了提高效率,保證併發,犧牲一定的資料一致性。

innodb_flush_log_at_trx_commit 還可以設定為02

      innodb_flush_log_at_trx_commit=0時,每隔一秒把log buffer刷到檔案系統中去,並且呼叫檔案系統的“flush”操作將快取重新整理到磁碟上去。這樣的話,可能丟失1秒的事務資料。

      innodb_flush_log_at_trx_commit=2時,在每次事務提交的時候會把log buffer刷到檔案系統中去,但是每隔一秒呼叫檔案系統的“flush”操作將快取重新整理到磁碟上去。如果只是MySQL資料庫掛掉了,由於檔案系統沒有問題,那麼對應的事務資料並沒有丟失。只有在資料庫所在的主機作業系統損壞或者突然掉電的情況下,資料庫的事務資料可能丟失1秒之類的事務資料。這樣的好處就是,減少了事務資料丟失的概率,而對底層硬體的IO要求也沒有那麼高(log buffer寫到檔案系統中,一般只是從log buffer的記憶體轉移的檔案系統的記憶體快取中,對底層IO沒有壓力)MySQL 5.6.6以後,這個“1秒”的重新整理還可以用innodb_flush_log_at_timeout 來控制重新整理間隔。

   在大部分應用環境中,應用對資料的一致性要求並沒有那麼高,所以很多MySQL DBA會設定innodb_flush_log_at_trx_commit=2,這樣的話,資料庫就存在丟失最多1秒的事務資料的風險。

mysql還存在另外一種資料丟失,資料庫的複製丟失資料。

主從複製層面丟失資料

mysql的複製並不能很好地從伺服器宕機,磁碟損壞、記憶體或網路錯誤中恢復,這時一般得從某個點開啟重啟複製。

       這些情況包括:主庫意外關閉、備庫意外關閉、主庫上的二進位制日誌損壞、備庫上的中繼日誌損壞、二進位制日誌與InnoDb事物日誌不同步等。



相關推薦

mySQL 事物提交成功等於資料儲存成功

最近遇到過生產上的資料丟失問題,看到大家各種分析程式碼,然後我發現很多人認為事物提交了就認為資料不會丟失!!!。。。我只能說這是公司沒有DBA,或者說大家不能深層次理解mySQL原理的悲哀!針對此,特意寫了這篇部落格!(理解不深刻不準確之處,敬請指出)現象正常情況下,我們會將

西安客戶希捷2T桌上型電腦硬碟識別資料恢復成功

接到客戶電話,說有一塊希捷2T的桌上型電腦硬碟突然不識別了,然後他拿到其他資料恢復公司去恢復了,放了一個多月然後給他說做不了,只能做前面的一部分,後面的分割槽都做不了,根據客戶的描述,可能是硬碟韌體出問題了,所謂韌體,就是整合在硬碟盤面上的一套程式,由這套程式來控制硬碟的

mysql not in 查詢資料

表結構如下 表Table_A: 專案 數量 id name 1 張三 2 趙四

Mysql資料庫修復,Ibdata1檔案刪除資料恢復成功

Mysql資料庫Ibdata1檔案刪除資料恢復成功 【客戶描述】 一RAID1網站伺服器,存放Mysql資料庫目錄被惡意刪除,計算機重啟後,Mysql服務啟動後自動建立了Ibdata及系統庫,後又被刪除 【恢復過程】 因資料庫有以前的老備份,檢視備份發現數據庫

MYSQL】金額(金錢)相關的資料儲存型別

int 對於遊戲幣等代幣,一般儲存為int型別是可行的。 問題在於越界,int型別長度為11位。 在儲存人民幣相關的金額的時候,則只能儲存到9長度的人民幣,也就是說,最大隻能儲存999999999,不到10億的數值,如果業務增長很快的話,就會給自己留下隱患

MySql的簡單查詢等於,NULL

查詢表中aa是null的資料: select * from table where aa is null; 查詢表中aa不等於1的資料: select * from table where aa

mysql遊標cursor查出來資料

有2個表:t1,t2 t1: id msg 2 aaaa 3 bbbb t2結構與t1一樣 建一個儲存過程,寫個遊標把資料拷貝過去: DELIMITER $$ USE `aporroreport`

MySQL如何實現萬億級資料儲存

## 前言 業界對系統的高可用有著基本的要求,簡單的說,這些要求可以總結為如下所示。 * 系統架構中不存在單點問題。 * 可以最大限度的保障服務的可用性。 一般情況下系統的高可用可以用幾個9來評估。所謂的幾個9就是系統可以保證對外提供的服務的時間達到總時間的百分比。例如如果需要達到99.99的高可用,則

MySQL二階段提交以及xtrabackup如何保證備份丟失資料

MySQL二階段提交與xtrabackup如何保證備份不丟失資料 MySQL二階段提交與crash recovery 1. MySQL二階段提交 2. crash recovery的實現 xtrabackup如何實現資料不丟失 1.

mybatis mysql儲存成功返回主鍵生效

mapper.xml配置如下: <insert id="insertReturnKey" parameterType="com.entity.CarBaseBrand" keyProperty="id" useGeneratedKeys="true"> insert int

Spring+JPA 資料庫儲存操作沒有異常但資料儲存成功

Spring+JPA儲存資料儲存不進去是因為jpa給修改操作加了預設事務,所以必須加上flush()方法提交才能真正的儲存資料。 而且儲存操作的方法必須在spring中配置好事務,否則呼叫flush時spring會報該方法不在事務中的異常

儲存過程執行成功,就是修改資料

1: 先看看資料庫的emp表的資料型別 2: 錯誤的姿勢 create procedure update_sal(in_name in varchar2,in_new_sal in number) is begin update emp set sa

冰河,能能講講如何實現MySQL資料儲存的無限擴容?

## 寫在前面 > 隨著網際網路的高速發展,企業中沉澱的資料也越來越多,這就對資料儲存層的擴充套件性要求越來越高。當今網際網路企業中,大部分企業使用的是MySQL來儲存關係型資料。如何實現MySQL資料儲存層的高度可擴充套件性成為了網際網路企業必須要解決的問題。那麼,如何實現真正意義上的MySQL無限

spark跑YARN模式或Client模式提交任務成功(application state: ACCEPTED)

應該是yarn的記憶體資源不夠 cd $HADOOP_HOME/bin 然後檢視yarn程序 yarn application -list 然後殺死任務 yarn application -kill application_1437456051228_1725

python爬蟲系列(4.3-資料儲存mysql資料庫中)

一、如果你對mysql資料庫還不太熟悉   二、基本操作 1、在python中使用pymysql連線mysql 2、安裝包 pip3 install pymysql 3、定義一個建立資料庫的方法(或者手動、SQL語句建立資料庫) # 定義一個建立資料庫的函

將爬取的資料儲存mysql

為了把資料儲存到mysql費了很多周折,早上再來折騰,終於折騰好了 安裝資料庫 1、pip install pymysql(根據版本來裝) 2、建立資料       開啟終端 鍵入mysql -u root -p  回車輸入密碼     &

mysql 資料儲存引擎區別

一,儲存型別         二 , MyISAM預設儲存引擎     MyISAM 管理非事務表、是ISAM 的擴充套件格式。除了提供ISAM裡所沒有的索引的欄位管理等的大量功能、MyISAM 還使用一種表格鎖定的機制、來優化多個併發的讀寫操作。MyISAM 提供高速儲存和檢

ubuntu mysql 修改資料儲存位置

停止 MySQL 使用以下命令 如果不成功可以嘗試stop mysql 命令 sudo /etc/init.d/mysql stop 複製已有的資料到新的資料儲存地址,預設資料地址(/var/lib/mysql) : sudo cp -R -p /var/lib/mysql /n

MySQL更改資料庫資料儲存目錄

MySQL資料庫預設的資料庫檔案位於 /var/lib/mysql 下,有時候由於儲存規劃等原因,需要更改 MySQL 資料庫的資料儲存目錄。下文總結整理了實踐過程的操作步驟。 1 確認MySQL資料庫儲存目錄 1

MySQL資料儲存引擎

什麼是MySQL資料儲存引擎 一、 概念: 1. 什麼是儲存引擎? MySQL的儲存引擎是MySQL體系架構中的重要組成部分,也是MySQL體系結構的核心,外掛式的儲存引擎更是它區別於其它資料庫的重要特徵。它處於MySQL體系架構中Server端底層,是底層物理結構的