<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 背景和原理 有沒有被突發的IO驚到過,有沒有見到過大量的autovacuum for prevent wrap。? PostgreSQL 的版本凍結是一個比較蛋疼的事情,為什么要做版本凍結呢?? 因為PG的版本號是uint32的,是重復使用的,所以每隔大約20億個事務后,必須要凍結,否則記錄會變成未來的,對當前事務”不可見”。? 凍結的事務號是2 ~~~ src/include/access/transam.h #define InvalidTransactionId ((TransactionId) 0) #define BootstrapTransactionId ((TransactionId) 1) #define FrozenTransactionId ((TransactionId) 2) #define FirstNormalTransactionId ((TransactionId) 3) #define MaxTransactionId ((TransactionId) 0xFFFFFFFF) ~~~ 現在,還可以通過行的t_infomask來區分行是否為凍結行 ~~~ src/include/access/htup_details.h /* * information stored in t_infomask: */ #define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */ #define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ #define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID) ~~~ 表的最老事務號則是記錄在pg_class.relfrozenxid里面的。 執行vacuum freeze table,除了修改t_infomask,還需要修改該表對應的pg_class.relfrozenxid的值。 那么系統什么時候會觸發對表進行凍結呢? 當表的年齡大于autovacuum_freeze_max_age時(默認是2億),autovacuum進程會自動對表進行freeze。? freeze后,還可以清除掉比整個集群的最老事務號早的clog文件。? 那么可能會出現這樣的情形:? 可能有很多大表的年齡會先后到達2億,數據庫的autovacuum會開始對這些表依次進行vacuum freeze,從而集中式的爆發大量的讀IO(DATAFILE)和寫IO(DATAFILE以及XLOG)。? 如果又碰上業務高峰,會出現很不好的影響。 為什么集中爆發Freeze很常見?? 因為默認情況下,所有表的autovacuum_freeze_max_age是一樣的,并且大多數的業務,一個事務或者相鄰的事務都會涉及多個表的操作,所以這些大表的最老的事務號可能都是相差不大的。? 這樣,就有非常大的概率導致很多表的年齡是相仿的,從而導致集中的爆發多表的autovacuum freeze。 PostgreSQL有什么機制能盡量的減少多個表的年齡相仿嗎?? 目前來看,有一個機制,也許能降低年齡相仿性,但是要求表有發生UPDATE,對于只有INSERT的表無效。? vacuum_freeze_min_age 這個參數,當發生vacuum或者autovacuum時,掃過的記錄,只要年齡大于它,就會置為freeze。因此有一定的概率可以促使頻繁更新的表年齡不一致。 那么還有什么手段能放在或者盡量避免大表的年齡相仿呢?? 為每個表設置不同的autovacuum_freeze_max_age值,從認為的錯開來進行vacuum freeze的時機。? 例如有10個大表,把全局的autovacuum_freeze_max_age設置為5億,然后針對這些表,從2億開始每個表間隔1000萬事務設置autovacuum_freeze_max_age。 如2億,2.1億,2.2億,2.3億,2.4億….2.9億。? 除非這些表同時達到 2億,2.1億,2.2億,2.3億,2.4億….2.9億。 否則不會出現同時需要vacuum freeze的情況。 但是,如果有很多大表,這樣做可能就不太合適了。? 建議還是人為的在業務空閑時間,對大表進行vacuum freeze。 優化建議? 1\. 分區,把大表分成小表。每個表的數據量取決于系統的IO能力,前面說了VACUUM FREEZE是掃全表的, 現代的硬件每個表建議不超過32GB。? 2\. 對大表設置不同的vacuum年齡. alter table t set (autovacuum_freeze_max_age=xxxx);? 3\. 用戶自己調度 freeze,如在業務低谷的時間窗口,對年齡較大,數據量較大的表進行vacuum freeze。? 4\. 年齡只能降到系統存在的最早的長事務即 min pg_stat_activity.(backend_xid, backend_xmin)。 因此也需要密切關注長事務。 講完了Freeze的背景,接下來給大家講講如何預測Freeze IO風暴。 ## 預測 IO 風暴 如何預測此類(prevent wrapped vacuum freeze) IO 風暴的來臨呢?? 首先需要測量幾個維度的值。 1. 表的大小以及距離它需要被強制vacuum freeze prevent wrap的年齡 2. 每隔一段時間的XID值的采樣(例如每分鐘一次),采樣越多越好,因為需要用于預測下一個時間窗口的XID。(其實就是每分鐘消耗多少個事務號的數據) 3. 通過第二步得到的結果,預測下一個時間窗口的每分鐘的pXID(可以使用線性回歸來進行預測) 預測方法這里不在細說,也可以參考我以前寫的一些預測類的文章。 預測的結論包括”未來一段時間的總Freeze IO量,以及分時的Freeze IO量”。? 預測結果范例? Freeze IO 時段總量? ![](https://box.kancloud.cn/2016-07-22_5791a6c8f4062.png) Freeze IO 分時走勢? ![](https://box.kancloud.cn/2016-07-22_5791a7050e8b0.png) ## 預測過程 * 每隔一段時間的XID值的采樣(例如每分鐘一次),采樣越多越好,因為需要用于預測下一個時間窗口的XID。(其實就是每分鐘消耗多少個事務號的數據) ~~~ vi xids.sh #!/bin/bash export PATH=/home/digoal/pgsql9.5/bin:$PATH export PGHOST=127.0.0.1 export PGPORT=1921 export PGDATABASE=postgres export PGUSER=postgres export PGPASSWORD=postgres psql -c "create table xids(crt_time timestamp, xids int8)" for ((i=1;i>0;)) do # 保留1個月的數據 psql -c "with a as (select ctid from xids order by crt_time desc limit 100 offset 43200) delete from xids where ctid in (select ctid from a);" psql -c "insert into xids values (now(), txid_current());" sleep 60 done chmod 500 xids.sh nohup ./xids.sh >/dev/null 2>&1 & ~~~ 采集1天的數據可能是這樣的 ~~~ postgres=# select * from xids ; crt_time | xids ----------------------------+------ 2016-06-12 12:36:13.201315 | 2020 2016-06-12 12:37:13.216002 | 9021 2016-06-12 12:38:13.240739 | 21022 2016-06-12 12:39:13.259203 | 32023 2016-06-12 12:40:13.300604 | 42024 2016-06-12 12:41:13.325874 | 52025 2016-06-12 12:42:13.361152 | 62026 2016-06-12 12:43:15.481609 | 72027 ... ~~~ * 表的大小以及距離它需要被強制vacuum freeze prevent wrap的年齡(因為freeze是全集群的,所以需要把所有庫得到的數據匯總到一起) ~~~ vi pred_io.sh #!/bin/bash export PATH=/home/digoal/pgsql9.5/bin:$PATH export PGHOST=127.0.0.1 export PGPORT=1921 export PGDATABASE=postgres export PGUSER=postgres export PGPASSWORD=postgres psql -c "drop table pred_io; create table pred_io(crt_time timestamp, bytes int8, left_live int8);" for db in `psql -A -t -q -c "select datname from pg_database where datname <> 'template0'"` do psql -d $db -c " copy ( select now(), bytes, case when max_age>age then max_age-age else 0 end as xids from (select block_size*relpages bytes, case when d_max_age is not null and d_max_age<max_age then d_max_age else max_age end as max_age, age from (select (select setting from pg_settings where name='block_size')::int8 as block_size, (select setting from pg_settings where name='autovacuum_freeze_max_age')::int8 as max_age, relpages, substring(reloptions::text,'autovacuum_freeze_max_age=(\d+)')::int8 as d_max_age, age(relfrozenxid) age from pg_class where relkind in ('r', 't')) t) t ) to stdout;" | psql -d $PGDATABASE -c "copy pred_io from stdin" done . ./pred_io.sh ~~~ 得到的數據可能是這樣的 ~~~ postgres=# select * from pred_io limit 10; crt_time | bytes | left_live ----------------------------+--------+----------- 2016-06-12 13:24:08.666995 | 131072 | 199999672 2016-06-12 13:24:08.666995 | 65536 | 199999672 2016-06-12 13:24:08.666995 | 0 | 199999672 2016-06-12 13:24:08.666995 | 0 | 199999672 2016-06-12 13:24:08.666995 | 0 | 199999672 2016-06-12 13:24:08.666995 | 0 | 199999672 ... ~~~ * 預測XIDs走勢(略),本文直接取昨天的同一時間點開始后的數據。 ~~~ create view v_pred_xids as with b as (select min(crt_time) tbase from pred_io), a as (select crt_time + interval '1 day' as crt_time, xids from xids,b where crt_time >= b.tbase - interval '1 day') select crt_time, xids - (select min(xids) from a) as xids from a ; ~~~ 數據可能是這樣的,預測未來分時的相對XIDs消耗量 ~~~ crt_time | xids ----------------------------+------ 2016-06-13 12:36:13.201315 | 0 2016-06-13 12:37:13.216002 | 100 2016-06-13 12:38:13.240739 | 200 2016-06-13 12:39:13.259203 | 300 2016-06-13 12:40:13.300604 | 400 ~~~ * 結合pred_io與v_pred_xids 進行 io風暴預測? 基準視圖,后面的數據通過這個基準視圖得到 ~~~ create view pred_tbased_io as with a as (select crt_time, xids as s_xids, lead(xids) over(order by crt_time) as e_xids from v_pred_xids) select a.crt_time, sum(b.bytes) bytes from a, pred_io b where b.left_live >=a.s_xids and b.left_live < a.e_xids group by a.crt_time order by a.crt_time; ~~~ 未來一天的總freeze io bytes預測 ~~~ postgres=# select min(crt_time),max(crt_time),sum(bytes) from pred_tbased_io ; min | max | sum ----------------------------+----------------------------+---------- 2016-06-13 12:36:13.201315 | 2016-06-14 12:35:26.104025 | 19685376 (1 row) ~~~ 未來一天的freeze io bytes分時走勢? 得到的結果可能是這樣的 ~~~ postgres=# select * from pred_tbased_io ; crt_time | bytes ----------------------------+---------- 2016-06-13 12:36:13.201315 | 65536 2016-06-13 12:37:13.216002 | 581632 2016-06-13 12:38:13.240739 | 0 2016-06-13 12:39:13.259203 | 0 2016-06-13 12:40:13.300604 | 0 2016-06-13 12:41:13.325874 | 0 2016-06-13 12:43:15.481609 | 106496 2016-06-13 12:43:24.133055 | 8192 2016-06-13 12:45:24.193318 | 0 2016-06-13 12:46:24.225559 | 16384 2016-06-13 12:48:24.296223 | 13434880 2016-06-13 12:49:24.325652 | 24576 2016-06-13 12:50:24.367232 | 401408 2016-06-13 12:51:24.426199 | 0 2016-06-13 12:52:24.457375 | 393216 ...... ~~~ ## 小結 預測主要用到哪些PostgreSQL的手段? 1. 線性回歸 2. with語法 3. 窗口函數 4. xid分時消耗統計 5. 強制prevent wrap freeze vacuum的剩余XIDs統計
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看