當前位置:首頁 » 編程語言 » sql回滾
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql回滾

發布時間: 2022-01-30 04:41:41

Ⅰ 對於已經執行成功的sql命令,如何回滾

當啟動Binlog後,事務會產生Binlog Event,這些Event被看做事務數據的一部分。因此要保證事務的Binlog Event和InnoDB引擎中的數據的一致性。所以帶Binlog的CrashSafe要求MySQL宕機重啟後能夠保證:

- 所有已經提交的事務的數據仍然存在。

- 所有沒有提交的事務的數據自動回滾。

- 所有已經提交了的事務的Binlog Event也仍然存在。

- 所有沒有提交事務沒有記錄Binlog Event。

這些要求很好理解,如果重啟後數據還在,但是Binlog Event沒有了,就沒辦法復制到其他節點上了。如果重啟後,數據沒了,但是Binlog Event還在,那麼不存在的數據就會被復制到其他節點上,從而導致主從的不一致。

為了保證帶Binlog的CrashSafe,MySQL內部使用的兩階段提交(Two Phase Commit)。

2 - MySQL的Two Phase Commit(2PC)

在開啟Binlog後,MySQL內部會自動將普通事務當做一個XA事務來處理:
- 自動為每個事務分配一個唯一的ID
- COMMIT會被自動的分成Prepare和Commit兩個階段。
- Binlog會被當做事務協調者(Transaction Coordinator),Binlog Event會被當做協調者日誌。
想了解2PC,可以參考文檔:【https://en.wikipedia.org/wiki/Two-phase_commit_protocol。】

- 分布式事務ID(XID)

使用2PC時,MySQL會自動的為每一個事務分配一個ID,叫XID。XID是唯一的,每個事務的XID都不相同。XID會分別被Binlog和InnoDB記入日誌中,供恢復時使用。MySQ內部的XID由三部分組成:

- 前綴部分

前綴部分是字元串"MySQLXid"

- Server ID部分

當前MySQL的server_id
- query_id部分

為了保證XID的的唯一性,數字部分使用了query_id。MySQL內部會自動的為每一個語句分配一個query_id,全局唯一。

參考代碼:sql/xa。h的struct xid_t結構。

- 事務的協調者Binlog

Binlog在2PC中充當了事務的協調者(Transaction Coordinator)。由Binlog來通知InnoDB引擎來執行prepare,commit或者rollback的步驟。事務提交的整個過程如下:

1. 協調者准備階段(Prepare Phase)

告訴引擎做Prepare,InnoDB更改事務狀態,並將Redo Log刷入磁碟。

2. 協調者提交階段(Commit Phase)

2.1 記錄協調者日誌,即Binlog日誌。

2.2 告訴引擎做commit。
注意:記錄Binlog是在InnoDB引擎Prepare(即Redo Log寫入磁碟)之後,這點至關重要。

在MySQ的代碼中將協調者叫做tc_log。在MySQL啟動時,tc_log將被初始化為mysql_bin_log對象。參考sql/binlog.cc中的init_server_components():
if (opt_bin_log) tc_log= &mysql_bin_log;

而在事務提交時,會依次執行:
tc_log->prepare();
tc_log->commit();
參考代碼:sql/binlog.cc中的ha_commit_trans()。當mysql_bin_log是tc_log時,prepare和commit的代碼在sql/binlog.cc中:

MYSQL_BIN_LOG::prepare();
MYSQL_BIN_LOG::commit();

-協調者日誌Xid_log_event
作為協調者,Binlog需要將事務的XID記入日誌,供恢復時使用。Xid_log_event有以下幾個特點:
- 僅記錄query_id
因為前綴部分不變,server_id已經記錄在Event Header中,Xid_log_event中只記錄query_id部分。
- 標志事務的結束

在Binlog中相當於一個事務的COMMIT語句。

一個事務在Binlog中看起來時這樣的:
Query_log_event("BEGIN");DML產生的events; Xid_log_event;

- DDL沒有BEGIN,也沒有Xid_log_event 。
- 僅InnoDB的DML會產生Xid_log_event
因為MyISAM不支持2PC所以不能用Xid_log_event ,但會有COMMIT Event。
Query_log_event("BEGIN");DML產生的events;Query_log_event("COMMIT");

問題:Query_log_event("COMMIT")和Xid_log_event 有不同的影響嗎?

- Xid_log_event 中的Xid可以幫助master實現CrashSafe。
- Slave的CrashSafe不依賴Xid_log_event
事務在Slave上重做時,會重新產生XID。所以Slave伺服器的CrashSafe並不依賴於Xid_log_event 。Xid_log_event 和Query_log_event("COMMIT"),只是作為事務的結尾,告訴Slave Applier去提交這個事務。因此二者在Slave上的影響是一樣的。

3 - 恢復(Recovery)
這個機制是如何保證MySQL的CrashSafe的呢,我們來分析一下。這里我們假設用戶設置了以下參數來保證可靠性:

- 恢復前事務的狀態
在恢復開始前事務有以下幾種狀態:
- InnoDB中已經提交
根據前面2PC的過程,可知Binlog中也一定記錄了該事務的的Events。所以這種事務是一致的不需要處理。
- InnoDB中是prepared狀態,Binlog中有該事務的Events。
需要通知InnoDB提交這些事務。
- InnoDB中是prepared狀態,Binlog中沒有該事務的Events。
因為Binlog還沒記錄,需要通知InnoDB回滾這些事務。
- Before InnoDB Prepare
事務可能還沒執行完,因此InnoDB中的狀態還沒有prepare。根據2PC的過程,Binlog中也沒有該事務的events。 需要通知InnoDB回滾這些事務。

- 恢復過程
從上面的事務狀態可以看出:恢復時事務要提交還是回滾,是由Binlog來決定的。
- 事務的Xid_log_event 存在,就要提交。
- 事務的Xid_log_event 不存在,就要回滾。

恢復的過程非常簡單:
- 從Binlog中讀出所有的Xid_log_event
- 告訴InnoDB提交這些XID的事務
- InnoDB回滾其它的事務

Ⅱ SQL......回滾

當大量賓館酒店借力世博擴張,世博會確實給業者帶來非常多的商機,各個賓館酒店都借力世博擴大發展、提高經營收益。那麼世博會對賓館賓館酒店業產生了哪些影響?上海賓館分析了以下幾大影響。

1.區位的影響

上海世博會對賓館酒店業的影響以世博園為增長極逐步向外擴散。影響最大的第一級為世博會場所在區域賓館酒店;第二級為相對集中的上海市區內賓館酒店;第三極為上海市郊區和杭州、寧波、南京等長三角區域賓館酒店。從上海市區主要地段來看,軌道交通附近的賓館酒店迎來了更好的發展機遇。另外,從賓館酒店類型來看,世博客源以國內團隊為主,上海非星級賓館酒店旅館受到市場青睞,特別是那些品牌經濟型賓館酒店。

2.經營的影響

2009年上海高檔賓館酒店業整體受到金融危機沖擊很大。據上海賓館了解,上海不少高星級賓館酒店大幅度降價、促銷、做外賣來過冬,某賓館酒店甚至降價幅度超過50%,為上海近幾年所罕見。藉助世博效應、虹橋機場以及虹橋交通樞紐的擴建完成等利好因素,上海2010年的賓館酒店市場在短期內取得了比較理性的恢復。另外,作為比鄰的長三角城市是世博會的分會場,它們的賓館酒店業將獲得前所未有的發展機遇。

3.信息的影響

要實現世博規劃中的住宿解決方案,信息作用不可忽視。世博住宿解決方案是一個復雜的系統,不同區域的、各種不同類型賓館酒店接待信息是否能統一、完整地便利搜索,影響到住宿解決方案是否在現實可執行的實際問題。這中間,星級賓館酒店是大多數外來遊客到上海後的首要選擇,無論藉助哪一種交通工具,都得先找到賓館酒店的確切方位。但多數電子地圖的雙語功能都比較差。另外,為應對上海世博會期間極端高峰日的住宿缺口,世博住宿解決方案中提供了上海高校內部招待所和周邊地區疏散等應急預案,這些非常規資源的系統整合情況和具體信息的公開與被搜索同樣非常重要。

4.容量的影響

以第一、第二極為例,抽取5月24日、25日、26日數據,可以了解到,雖然不少賓館酒店的價格已經相對於世博前實現翻番,但隨著入園人數的增加,上海市區客房平均出租率依然逐步增加到飽和狀態(達到97%)。政府的價格規定使賓館酒店業通過提價增加利潤和控制入住流量受到限制。鑒於上海世博會期間預計接待人次與現實的差距,票檢入園人數將繼續增加,那麼住宿問題將形成瓶頸。按照原世博規劃,對應解決方案主要是內挖潛力,外引資源:通過世博人家、世博農家、臨時調用企事業單位及學校等社會資源來緩解;通過向車程在兩小時以內的長三角周邊地區賓館酒店疏散客流來緩解。

但上海周邊杭州、蘇州等地和上海在賓館酒店方面的接洽沒達到理想狀態。

文章轉自 上海賓館 上海賓館

Ⅲ sql service 怎麼回滾

sqlserver 的編輯器一般都是默認自動提交,也就是說你刪除後,就自動提交了;不能回滾。
當然如果你設置成不是默認提交的話,那麼你在提交之前可以回滾。

而如果是程序代碼中刪除的話,看你有沒有啟用事務,如果沒有啟用事務,那麼一般也是默認提交的,如果啟用事務,那麼再提交前可以回滾,如果已經提交了,那麼就回滾不了了。

Ⅳ SQL資料庫,能進行回滾操作么

你在執行update操作的時候,有沒有進行提交操作,如果rollback還原不了數據的話,你可以查看日誌文件,查找到你當時的執行的語句,進行還原就行

Ⅳ sql server 中的update語句回滾怎麼寫啊

回滾要放在事務裡面進行,才能進行回滾;sql裡面的事務使用關鍵字TransAction
1:可以用try catch捕獲
begin try
begin tran
update table set a=1;
commit tran
end Try
begin catch
rollback tran
end catch

2:可以使用error 全局變數
begin tran
update tablename set ad=1111
if @@error<>0 begin rollback end
commit tran

注意:如果一個事務寫了 begin trans ,後面一定要跟上 commit tran或 rollback transaction ,否則可能導致被鎖

Ⅵ SQL回滾的作用什麼

當你遇到死鎖是就有用了
就是回退到上次提交的時間點

Ⅶ sql數據修改回滾

SQL:回滾事務日誌文件中的事務

問:怎樣使用Transact-SQL回滾某個位於事務日誌文件中的事務(例如,ID 0000:0010a183)?

答:出於預防數據錯誤的考慮,SQL Server並不支持個別事務的回滾。舉例來說,假設兩個事務T1和T2使用現金余額域。T1添加了500美金,T2使用更新後的值進行了某個操作。如果回滾T1,則T2可能是錯誤的。但是,您可以使用時間戳或事務日誌標記將日誌恢復至預定義的標記或時間點。以下兩個例子說明了如何使用SQL Server 2000語法。

例1:使用時間戳將日誌進行時點恢復
使用以前的完全備份恢復資料庫,並使其為日誌恢復做好准備。

RESTORE DATABASE pubs FROM DISK = N'C:\Backups\Fullbackup.bak' WITH NORECOVERY

現在您可以將日誌前滾到合適的時間點,並使資料庫可供使用。請注意,STOPAT在資料庫正在執行大容量日誌時禁止執行。

RESTORE LOG pubs FROM DISK=N'C:\Backups\Logbackup.bak' WITH RECOVERY,STOPAT='02/11/2002 17:35:00'

例2:使用資料庫標記將日誌恢復到預定義時間點的語句
在事務日誌中置入一個標記。請注意,被標記的事務至少須提交一個更新,以標記該日誌。

BEGIN TRAN MyMark WITH MARK
UPDATE pubs.dbo.LastLogMark SET MarkTime = GETDATE()
COMMIT TRAN MyMark

按照您常用的方法備份事務日誌。

BACKUP LOG pubs TO DISK='C:\Backups\Fullbackup.bak' WITH INIT

現在您可以將資料庫恢復至日誌標記點。首先恢復資料庫,並使其為接受日誌恢復做好准備。

RESTORE DATABASE pubs FROM DISK=N'C:\Backups\Fullbackup.bak' WITH NORECOVERY

現在將日誌恢復至包含該標記的時間點,並使其可供使用。請注意,STOPAT在資料庫正在執行大容量日誌時禁止執行。

RESTORE LOG pubs FROM DISK=N'C:\Backups\Logbackup.bak' WITH RECOVERY,
STOPAT='02/11/2002 17:35:00'

—Microsoft SQL Server 開發團隊

Ⅷ 資料庫(sql server )回滾事務

這個要求不需要用事務回滾的吧。
insert 中加上判斷該工號記錄數的條件即可,保證當記錄數少於4時執行插入語句。

insert () values() where(select count(*) from table where emp_id=『20100021』)<4

Ⅸ SQL存儲過程,如何回滾啊

當 SET XACT_ABORT 為 ON 時,如果執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止並回滾。
當 SET XACT_ABORT 為 OFF 時,有時只回滾產生錯誤的 Transact-SQL 語句,而事務將繼續進行處理。如果錯誤很嚴重,那麼即使 SET XACT_ABORT 為 OFF,也可能回滾整個事務。OFF 是默認設置。

編譯錯誤(如語法錯誤)不受 SET XACT_ABORT 的影響。

對於大多數 OLE DB 提供程序(包括 SQL Server),必須將隱式或顯示事務中的數據修改語句中的 XACT_ABORT 設置為 ON。唯一不需要該選項的情況是在提供程序支持嵌套事務時。有關詳細信息,請參閱 分布式查詢和分布式事務。

SET XACT_ABORT 的設置是在執行或運行時設置,而不是在分析時設置。

示例
下列代碼示例導致在含有其他 Transact-SQL 語句的事務中發生外鍵沖突錯誤。在第一個語句集中產生錯誤,但其他語句均成功執行且事務成功提交。在第二個語句集中,將 SET XACT_ABORT 設置為 ON。這導致語句錯誤使批處理終止,並使事務回滾。

復制代碼
USE AdventureWorks;
GO
IF OBJECT_ID(N't2', N'U') IS NOT NULL
DROP TABLE t2;
GO
IF OBJECT_ID(N't1', N'U') IS NOT NULL
DROP TABLE t1;
GO
CREATE TABLE t1
(a INT NOT NULL PRIMARY KEY);
CREATE TABLE t2
(a INT NOT NULL REFERENCES t1(a));
GO
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (3);
INSERT INTO t1 VALUES (4);
INSERT INTO t1 VALUES (6);
GO
SET XACT_ABORT OFF;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (2); -- Foreign key error.
INSERT INTO t2 VALUES (3);
COMMIT TRANSACTION;
GO
SET XACT_ABORT ON;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (4);
INSERT INTO t2 VALUES (5); -- Foreign key error.
INSERT INTO t2 VALUES (6);
COMMIT TRANSACTION;
GO
-- SELECT shows only keys 1 and 3 added.
-- Key 2 insert failed and was rolled back, but
-- XACT_ABORT was OFF and rest of transaction
-- succeeded.
-- Key 5 insert error with XACT_ABORT ON caused
-- all of the second transaction to roll back.
SELECT *
FROM t2;
GO

Ⅹ sql 回滾語句

這種情況的數據恢復只能利用事務日誌的備份來進行,所以如果你的SQL沒有進行相應的全庫備份

或不能備份日誌(truncate log on checkpoint選項為1),那麼就無法進行數據的恢復了,或者
只能恢復到最近一次的備份的數據了。

以下簡單說明恢復數據方法:
1,如果誤操作之前存在一個全庫備份(或已有多個差異備份或增量備份),首先要做的事就是進
進行一次日誌備份(如果為了不讓日誌文件變大而置trunc. log on chkpt.選項為1那你就死翹了)
backup log dbName to disk='fileName'
2,恢復一個全庫備份,注意需要使用with norecovery,如果還有其他差異或增量備份,則逐個恢

restore database dbName from disk='fileName' with norecovery
3,恢復最後一個日誌備份即剛做的日誌備份,指定恢復時間點到誤操作之前的時刻
restore log dbName from disk='fileName'
with stopat='date_time'

以上這些操作都可以在SQL SERVER企業管理器里完成,難度不大。。。

當然,如果誤操作是一些不記日誌的操作比如truncate table,select into等操作,那麼是無法利
用上述方法來恢復數據的...