崑崙分散式資料庫Sequence功能及其實現機制

KunlunDB發表於2022-01-17

崑崙分散式資料庫(下文簡稱崑崙或者崑崙資料庫)的計算節點源自PostgreSQL,因此繼承了PostgreSQL的Sequence功能,本文介紹崑崙分散式資料庫的Sequence的功能用法、用例和實現。

 

用法和用例

 

崑崙資料庫的Sequence與MySQL的autoincrement(自增列)相比,其功能更加強大和靈活。主要體現在以下幾方面:


1.  崑崙的Sequence與表是多對多的關係,而MySQL的自增列與表是1對1關係


具體來說,崑崙資料庫的每個表可以有任意數量的sequence列使用相同或者不同的sequence產生序列值;


並且每一個sequence可以被任意多個表的任意多個列使用來產生ID值。


而MySQL的每個表最多隻能有一個自增列並且這個自增列只能被這個表使用(這是廢話,但是為了內容對稱還是要提一下)。


2.  可以在任何時候調整sequence的初始值,最大值,步長,範圍等屬性然後繼續使用,然後sequence就會按照新的屬性產生新序列值。


3.  不依賴索引,清空表後序列值不迴繞。


4.  崑崙資料庫叢集多個計算節點直接或者間接使用同一個sequence 都可以產生全域性唯一的序列值。


讓我們看一個例子,首先建立一個表t1,t1的主鍵列serial型別標明它使用一個隱式建立的sequence來產生欄位值,所以插入時候可以不為它指定欄位值。


    create table t1(a serial primary key, b int);


    崑崙分散式資料庫Sequence功能及其實現機制


    然後建立sequence seq_b,準備用seq_b來產生欄位值。建立時可以可選地指定sequence的屬性,不指定就使用預設值。


      create sequence seq_b;


      先執行這個語句插入9行,顯式呼叫seq_b產生欄位值。


        insert into t1(b) values(nextval('seq_b'));


        可以看到t1的資料如下:


          select*from t1;


          崑崙分散式資料庫Sequence功能及其實現機制



          然後建立表t2,它的b和c列都使用seq_b產生預設欄位值,並且其主鍵列也適用隱式sequence來產生欄位值。


            create table t2(a serial primary key, b int default nextval('seq_b'), c int default nextval('seq_b'));


            由於t2的所有欄位都有預設值,所以用如下語句插入表t2 3行。


              insert into t2 default values;


              檢視t2的資料,可以看到每行b和c欄位是使用seq_b依次產生的欄位值,並且從seq_b上次產生的9之後開始產生序列值。


                select*from t2;


                崑崙分散式資料庫Sequence功能及其實現機制


                最後,還可以使用 select nextval('seq_b'); 這樣的語句來直接產生序列值。

                 

                修改sequence後設資料及其他

                 

                可以使用ALTER SEQUENCE 語句來修改sequence的屬性,也可以使用ALTER TABLE ... ALTER COLUMN ... SET seqoptions 語句來修改列的隱式sequence的屬性。


                還可以使用上述alter table語句restart一個sequence。並且可以使用lastval()函式獲得sequence上次返回的值。


                崑崙分散式資料庫Sequence功能及其實現機制

                 

                sequence實現

                 

                崑崙資料庫的sequence實現繼承了PostgreSQL原有的sequence機制。


                為了使sequence資料具備容災能力並且能夠被任意數量的計算節點同時使用,因此sequence的與序列值分發有關的數值資料儲存在儲存節點的mysql.sequences表中,每行對應一個sequence。


                一個sequence的後設資料具體儲存在哪個儲存叢集中,是在建立sequence時由計算節點動態分配的。


                sequence的其他後設資料儲存在計算節點,可以使用下面的語句檢視sequence在計算節點中的後設資料:


                  select t2.relname, t2.oid, seqstart, seqincrement, seqmax, seqmin, seqcache, seqcycle from pg_sequence t1, pg_class t2 where t1.seqrelid = t2.oid;


                  崑崙分散式資料庫Sequence功能及其實現機制


                  可以看到 t1和t2的主鍵列的隱式sequence分別是t1_a_seq和 t2_a_seq,還有顯式建立的seq_b ,這些sequence的數值後設資料所在的儲存叢集分別是1,2,1。


                  同時,可以看到sequence的基本後設資料也儲存在pg_class後設資料表中,而其特有屬性儲存在pg_sequence表中。


                  分別連線到編號為1和2的shard檢視這3個sequence在這兩個儲存叢集的mysql.sequence表中的數值後設資料,可以看到以下資訊:


                  崑崙分散式資料庫Sequence功能及其實現機制

                  崑崙分散式資料庫Sequence功能及其實現機制

                   

                  當首次使用一個sequence或者其預約的數值範圍用盡時,一個計算節點CN就會透過其cluster_log_applier程式到這個sequence所在的儲存叢集中去reserve (curval, cur_val + max(10, seqcache)) 這個範圍的欄位值,然後CN使用這個reserve的範圍來為這個sequence分發序列值,直到再次用盡。


                  這樣,即使有多個計算節點使用同一個sequence來分發序列值,仍然可以保持高效能並且保持所有計算節點分發的序列值都唯一。


                  結語


                  通俗來講,如果對資料庫的讀和寫都在同一個資料庫伺服器中操作,業務系統效能會降低。 

                  為了提升業務系統效能,最佳化使用者體驗,可以透過做主從複製來減輕主資料庫的負載。 

                  而且如果主資料庫當機,可快速將業務系統切換到從資料庫上,可避免資料丟失。



                  THE END


                  來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011764/viewspace-2852626/,如需轉載,請註明出處,否則將追究法律責任。

                  相關文章