第六章 邏輯結構管理
6.9 索引
6.9.2 索引的分類
PostgreSQL支持以下幾類索引:
- B-tree:最常用,適合處理等值查詢和範圍查詢;
- Hash:只能處理簡單等值查詢;
- Gist:可用於圖形操作符;
- SP-GiST:空間分區GiST索引;
- GIN:反轉索引
6.9.3 創建索引
CREATE INDEX indexname on tablename(column_name)
6.9.4 併發創建索引
CREATE INDEX CONCURRENTLY indexname on tablename(column_name)
6.9.5 修改索引
ALTER INDEX name RENAME TO new_name;
ALTER INDEX name SET tablespace_name;
6.9.6 刪除索引
DROP INDEX indexname;
6.11 事務、併發、鎖
6.11.1 ACID
略
注意區別不可重複讀和幻讀。
PostgreSQL中,可以使用多版本併發控制(MVCC)來維護數據一致性。
6.11.2 DDL事務
PostgreSQL與MySQL最大區別:大多數DDL可以包含在一個事務中,也可以回滾。
具體場景:多個節點建相同的表(分庫分表),將這些建表語句放在同一個事務中。
6.11.3 事務的使用
-
將AUTOCOMMIT設置爲off
# \set AUTOCOMMIT off # \ehco : AUTOCOMMIT off
-
使用“BEGIN”語句來啓動一個事務
# begin; BEGIN ... # rollback; ROLLBACK
6.11.4 SAVEPOINT
PostgreSQL支持保存點,用以回滾至整個事務的某一個點。
# begin;
BEGIN
...
# savepoint my_savepoint01
...
# rollback to SAVEPOINT my_savepoint01;
ROLLBACK
6.11.5 事務隔離級別
數據庫四個隔離級別:
-
READ UNCOMMITTED:讀未提交
-
READ COMMITTED:讀已提交(PostgreSQL默認隔離級別)
-
REPEATABLE READ:重複讀(MySQL默認隔離級別)
-
SERIALIZABLE:串行化
6.11.6 兩階段提交
兩階段提交是實現分佈式事務的關鍵。
兩階段提交協議五個步驟:
- 應用調用各數據庫執行各自操作,不提交;然後應用調用事務協調器中的提交方法;
- 事務協調器通知各數據庫,準備提交事務,第一階段開始。PostgreSQL一般是調用“PREPARE TRANSACTION”;
- 各數據庫收到命令,返回成功(或失敗);數據庫需確保後續在被要求提交事務時能夠提交事務,或被要求回滾時能夠回滾。PostgreSQL會將已準備好提交的信息寫入持久存儲區中。若數據庫無法完成此事務,則返回失敗給事務協調器;
- 事務協調器收到所有數據庫的響應;
- 在第二階段,如果有任意一個數據庫返回了失敗,則事務協調器會發送一個回滾命令(ROLLBACK PREPARED)給各數據庫。如果所有返回都爲成功,則發送“COMMIT PREPAREED”命令,通知各數據庫事務成功。
其中第二個步驟,PREPARE TRANSACTION transcationId,transcationId爲全局事務ID,由事務協調器生成。PostgreSQL一旦成功執行這條命令,就會把此事務持久化,及時數據庫重啓,此事務既不會回滾,也不會丟失。
6.11.7 鎖機制
表級鎖、行級鎖
SHARE 共享鎖(讀鎖)、EXCLUSIVE 排它鎖(寫鎖)
多版本功能下,表鎖增加ACCESS SHARE和ACCESS EXCLUSION
意向鎖:ROW SHARE、ROW EXCLUSIVE
6.11.8 死鎖及防範
死鎖四個必要條件:
- 互斥;
- 請求和保持條件(佔有並等待);
- 不可搶佔;
- 環路等待條件(循環等待)
死鎖防止方法:以固定順序獲取對象的鎖(事務中以固定順序更新數據表)
第七章 PostgreSQL核心架構
進程及內存結構
-
Postmaster主進程
Postmaster是整個數據庫實例的總控進程。
PostgreSQL數據庫是進程架構模型,MySQL數據庫是線程架構模型
-
SysLogger(系統日誌)進程
配置文件postgresql.conf中參數:logging_collect爲“on”時,主進程纔會啓動SysLogger輔助進程;
收集所有stderr輸出,並寫入到日誌文件中。
-
BgWrite(後臺寫)進程
功能:將共享內存中髒頁寫到磁盤上(髒頁刷盤);
作用:提高增刪改的效率;
類比:操作系統頁緩存機制。
-
WalWriter(預寫式日誌寫)進程
功能:修改數據之前,先記錄修改操作至磁盤,再實際更新數據;
作用:宕機後重啓也可以根據WAL日誌重新執行,以恢復宕機前狀態;
WAL日誌保存在pg_xlog下,每個pg_xlog文件默認爲16M;
類比:類似於Redis的AOF,但Redis是先執行命令,再記錄至AOF。
-
PgArch(歸檔)進程
功能:將WAL日誌文件再覆蓋前備份出來;
目的:解決WAL日誌循環使用覆蓋問題;
數據庫全量備份後,將備份時間點之後的WAL日誌通過歸檔進行備份。全量備份加後續產生的WAL,即可恢復至全量備份後任意一時間點的狀態。
-
AutoVacuum(自動清理)進程
PG中,刪除數據不會立馬被刪除,更新數據不會在舊數據上操作,而是生成一行新數據(MV);
舊數據只是被標識爲刪除狀態,只有併發的其他事務讀到這些舊數據時,它們纔會被清除。清除工作由AutoVacuum進程完成。
-
PgStat(統計數據收集)進程
共享內存
-
共享內存主要用作數據塊緩衝區,以提高讀寫性能。
-
WAL日誌緩衝區和CLOG(Commit log)緩衝區也在共享內存中、還有其他一些全局信息。
-
PostgreSQL9.3之後,使用“mmap()”方式實現共享內存。
本地內存
存儲一些不需要全局存儲的數據,主要有:
- 臨時緩衝區:用戶訪問臨時表的本地緩衝區;
- work_mem:內部排序操作和Hash表在使用臨時磁盤文件之前使用的內存緩衝區;
- maintenance_work_mem:在維護性操作中使用的內存緩衝區。