簡體   English   中英

PostgreSQL LOGGED和UNLOGGED表性能與LOCK TABLE的使用比較

[英]PostgreSQL LOGGED and UNLOGGED table performance comparison with LOCK TABLE usage

我正在嘗試在PostgreSQL(10.3)中的LOGGEDUNLOGGED表上測量UPDATE速度。 我想使用LOCK TABLE來防止其他應用程序相互干擾。

如果在不使用LOCK TABLE情況下執行UPDATE ,則LOGGED表為UNLOGGED表為UNLOGGED

如果使用LOCK TABLE執行UPDATE ,則兩種表類型的結果都相同。

為什么在兩種表類型中LOCK TABLE返回相同的結果?

我的PL / pgSQL函數:

CREATE OR REPLACE FUNCTION public.myfunction(user_id integer, unitprice numeric(10,6), 
            islock boolean, useunlogged boolean) RETURNS integer AS
$BODY$
declare howMuch integer;
begin       
    if islock then
        if useunlogged then 
            LOCK TABLE credittable_unlogged IN ACCESS EXCLUSIVE MODE;
        else
            LOCK TABLE credittable IN ACCESS EXCLUSIVE MODE;
        end if;
    end if;
    if useunlogged then     
        select (credit_amount/unitprice)::integer into howMuch from credittable where userid=user_id and credit_amount>=unitprice;
        if howMuch is null then 
            select 0 into howMuch;
        else
            update credittable set credit_amount=credit_amount-unitprice where userid=user_id;
        end if;    
    else 
        select (credit_amount/unitprice)::integer into howMuch from credittable_unlogged where userid=user_id and credit_amount>=unitprice;
        if howMuch is null then 
           select 0 into howMuch;
        else
            update credittable_unlogged set credit_amount=credit_amount-unitprice where userid=user_id;
        end if;  
    end if;
    RETURN howMuch;
 end;
 $BODY$
   LANGUAGE plpgsql VOLATILE
    COST 100;
 ALTER FUNCTION public.myfunction(integer, numeric, boolean, boolean)
    OWNER TO postgres;

我的Java代碼:

for(int i=1;i<=4;i++){
    long startTime = System.nanoTime();
    int counter = 0;        
    while ((System.nanoTime() - startTime) < 1000000000L) {
        CallableStatement callst = null;
        try {
            String sql = "{? = call public.myfunction(?,?,?,?) }";
            callst = con.prepareCall(sql);
            callst.registerOutParameter(1, Types.INTEGER);
            callst.setInt(2, 123456);
            callst.setBoolean(3, (i > 2));
            callst.setBoolean(4, (i%2 != 0));
            callst.setBigDecimal(3, BigDecimal.valueOf(0.001));
            callst.execute();
            int howMuch = callst.getInt(1);                
            counter++;                
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (callst != null) {
                callst.close();
            }
        }
    }
    System.out.println("Counter :"+counter);
}   

您在此處測量的很多內容是客戶端服務器延遲和PL / pgSQL執行。

造成這種差異的原因是必須將WAL同步到磁盤。

如果使用未記錄的表,並且不使用LOCK語句,則不會寫入WAL,並且在COMMIT時無需同步任何內容。

顯式表鎖導致寫入WAL記錄,因此COMMIT仍然必須同步WAL,並且您將失去從未記錄表中獲得的優勢。

您可以使用pg_waldump檢查WAL文件,然后您將看到寫入了哪些事務日志記錄。

但是我可以使用-DWAL_DEBUG構建的PostgreSQL v11向您-DWAL_DEBUG

這是我的測試表:

postgres=# \d t
             Unlogged table "public.t"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           |          | 

這里是沒有LOCK TABLEINSERT

postgres=# SET wal_debug=on;
SET
postgres=# BEGIN;
BEGIN
postgres=# INSERT INTO t VALUES (100);
INSERT 0 1
postgres=# COMMIT;
LOG:  INSERT @ 0/166BFB8:  - Transaction/COMMIT: 2018-05-18 20:34:20.060635+02
STATEMENT:  COMMIT;
COMMIT

有一個提交,但沒有WAL刷新。

postgres=# BEGIN;
BEGIN
postgres=# LOCK TABLE t;
LOG:  INSERT @ 0/166C038:  - Standby/LOCK: xid 569 db 13344 rel 16384 
STATEMENT:  LOCK TABLE t;
LOCK TABLE
postgres=# INSERT INTO t VALUES (101);
INSERT 0 1
postgres=# COMMIT;
LOG:  INSERT @ 0/166C138:  - Transaction/COMMIT: 2018-05-18 20:36:15.419081+02
STATEMENT:  COMMIT;
LOG:  xlog flush request 0/166C138; write 0/166BFF0; flush 0/166BFF0
STATEMENT:  COMMIT;
COMMIT

現在我們有了WAL刷新,這是昂貴的部分。

您會看到一個Standby/LOCK記錄已寫入。

解決該問題的一種方法是將wal_level減小為minimal ,將max_wal_senders0 ,然后不必寫入這些WAL記錄。 但是,您將無法進行WAL歸檔和時間點恢復。

另一個解決方法是使用比ACCESS EXCLUSIVE更低的鎖定級別。 除非您絕對必須阻止讀者,否則應該沒問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM