利用事務複製實現大容量表定長欄位型別的快速變更

2021-07-02 14:07:16 字數 1522 閱讀 5290

場景描述:

我們的某個業務系統,由於快速增長,導致之前的主鍵列(自增屬性+int型別)即將達到上限,需要變更為bigint型別;

另一方面,由於需要修改的鍵涉及多個表的關聯,且有多點的複製關係,經過測試,單錶修改(僅alter table alter column環節)就需要7個小時,嚴重影響業務;

考慮到alter table帶來的鎖表時間過長,我利用事務複製,變相進行型別變更操作,實現了快速變更,在大幅提高工效的同時,將alter table無法控制回滾的風險降到最低;

思路:

如果在停機後某個較短的時刻,原db中存在乙份和待修改資料表(tb_a)資料相同但結構不同的資料副本(tb_a_new),那我們就可以通過直接sp_rename(交換表名)的方式來實現字段型別的快速變更;

因此,如何能在停機前實現這個「資料相同但結構不同的資料副本」,就成為我們要解決的關鍵步驟;而利用事務複製,可以在不停機的前提下實現這一步驟;

在這裡,建立事務複製並非完全採用常規方法,這是因為:

sqlserver複製中,要求發布的db不能為同一鏈路上自身的訂閱db;

即,複製鏈路不能成環

這似乎與我們的思路矛盾,這裡需要通過一些技巧來實現「複製環路」的設想;

操作:

1、按照一般方法建立好乙個publication,並新增需要發布的article;

編輯專案屬性,參照下圖,編輯「目標物件名稱」、「名稱已被使用時的操作」及「語句傳遞」

在這裡,有兩點需要注意:

2、新增訂閱並通過快照初始化,即可生成「舊結構表到新結構表的訂閱」;

這裡有幾點注意:

本機型:

採用mssql方式生成快照檔案,其內容與資料頁(page)的儲存方式類似,其中對欄位及值的描述是以位進行操作;這樣做的好處就是快照檔案生成快,且容易壓縮,快照檔案相對較小,便於傳輸;但弊端就是訂閱端需要和發布同樣結構(例如,int為4位元組,bigint為8位元組,如果按字位進行訂閱,將導致快照在訂閱端產生位移動,影響資料一致性)

字元型:

採用類似csv方式生成快照,列、行由分隔符進行區分,快照檔案相對較大,對於異構環境(如sqlserver到oracle,或類似本案例的場景),不影響資料一致性;

3、參照原訂閱端舊表,新增對新錶的相關許可權、索引等;

4、在停機維護視窗,停止發布端的寫操作;

5、待複製命令完全應用到訂閱端後,拆除全部複製關係,交換訂閱端tb_a和tb_a_new的表名,參照舊的複製關係重新新增不初始化的訂閱,即可實現訂閱端表結構的變更;

至此,我們實現了大資料表公升級表結構的業務需求,較之直接在資料表上進行alter table,時間大大縮短,且盡可能的避免長時間架構鎖給業務帶來的影響;

PHP 使用事務簡單實現

db new mysqli localhost root test 連線資料庫 db autocommit false 設定為非自動提交 事務處理 sql1 insert into test test1 name values 1 result1 db query sql1 sql2 insert ...

用事務實現函式效果

事務xml控制 用事務 xml實現函式效果 create table ta id int name varchar 50 insert taselect 1,a union all select 1,b union all select 1,a union all select 2,e union ...

MYSQL中預設隱式事務及利用事務DML

一 預設情況下,mysql採用autocommit模式執行。這意味著,當您執行乙個用於更新 修改 表的語句之後,mysql立刻把更新儲存到磁碟中。預設級別為不可重複讀。二 會造成隱式提交的語句 以下語句 以及同義詞 均隱含地結束乙個事務,似乎是在執行本語句前,您已經進行了乙個commit。1 alt...