1. 程式人生 > >PostgreSQL基於預寫日誌的複製

PostgreSQL基於預寫日誌的複製

PostgreSQL是一款優秀的開源關係型資料庫,從1989年至今已有22年曆史,經過多次轉折,如今乃是業界流行度僅次於MySQL的開源資料庫系統。比起MySQL,PostgreSQL有更好的索引支援和更穩固的ACID保證,也提供了諸多非常優秀的複製(Replication)解決方案,同時以更自由的開源許可協議釋出。在PostgreSQL 9.0之前,PostgreSQL就有了許多的第三方的複製方案,如下表:

特性 共享磁碟容錯 檔案系統複製 基於預寫日誌的可讀複製 基於觸發的複製 基於語句的複製 非同步多主節點複製 同步多節點主複製
常見的解決方案 NAS DRBD PITR Slony pgpool-II Bucardo
通訊方法 shared disk disk blocks WAL table rows SQL table rows table rows and row locks
無需特製硬體
允許多主伺服器
不增加服務端負荷
多伺服器無等待
主伺服器失敗時不丟失資料
備用伺服器支援讀請求 Hot only
表級別粒度
無衝突解析

從PostgreSQL 9.0開始,基於預寫日誌(Write Ahead Log, WAL

)的可讀複製(PITR)更是成為了官方提供的非同步主從複製(Master-Slave Replication)解決方案,該方案擁有如下優點:

  1. 使用預寫日誌記錄資料庫的改動,不額外增加服務端的其他負荷。
  2. 當主伺服器失敗(如斷電、系統崩潰、災難)時,不會丟失任何資料。
  3. 支援基於流和基於檔案的兩種日誌傳輸方案。
  4. 備用伺服器可作為負載均衡節點提供讀請求。
  5. 支援多個或多級備用伺服器。

實現原理

主伺服器在接受到每個事務請求時,將資料改動用預寫日誌(WAL)記錄。具體而言,事務採用兩段提交(Two Phase Commit),即先將改動寫入預寫日誌,然後再實際改動資料庫。這樣可以保證預寫日誌的時間戳永遠不落後於資料庫,即便是正在寫入時伺服器突然崩潰,重啟以後也可以依據預寫日誌將資料恢復,因為預寫日誌保留了比資料庫記錄中更新的版本。PostgreSQL的非同步複製解決方案正是利用了預寫日誌,將預寫日誌從主伺服器(Master Sever)傳輸到備用伺服器(Standby Server),然後在備用伺服器上回放(Replay)出預寫日誌中記錄改動,從而實現主從複製。PostgreSQL使用了兩種方式傳輸預寫日誌:存檔式

(archive)和流式(streaming)。

存檔式複製的原理是主伺服器將預寫日誌主動拷貝到一個安全的位置(可以直接到備用伺服器,也可以是第三臺伺服器),同時備用伺服器定期掃描這個位置,並將預寫日誌拷貝到備用伺服器端然後再回放。這樣即使主伺服器崩潰了,備用伺服器也可以從這個安全的位置獲取到一份完整的記錄,以確保任何資料不會丟失。而流式複製則簡化了這一個步驟,由主伺服器直接通過TCP協議向備用伺服器傳輸日誌,避免了兩次複製的開銷,有利於減小備用伺服器和主伺服器直接的資料延時。但當主伺服器崩潰時,未被傳輸到備用伺服器的日誌則會丟失,造成資料損失。PostgreSQL支援存檔式和流式兩種模式的混合,當兩種模式都開啟時,備用伺服器會定期檢查是否有存檔已經到達指定的位置,並回放日誌。一旦檢測到指定的位置沒有新的日誌,則會切換到流式模式試圖直接從網路傳輸日誌,接著再檢查存檔,不斷重複這一迴圈。

基本配置步驟

1、在主伺服器和從伺服器上分別安裝PostgreSQL 9.1以上版本,初始化資料庫:

initdb -D "/var/postgres/data"  # Unix
initdb -D "D:/postgres/data"  # Windows

2、修改主伺服器資料目錄下的配置檔案pg_hba.conf,增加備用伺服器訪問的許可權,例如:

host    replication    postgres_repl    59.66.134.0/24    md5

以上表示允許來自59.66.134.0/24的連線,使用者名稱為postgres_repl,口令採用MD5驗證。 如果不需要配置流式複製,此項配置可以忽略。

3、修改主伺服器資料目錄下的配置檔案postgresql.conf: 將wal_level設為archive或hot_standby,archive為單純備用伺服器所需的日誌格式,hot_standby為支援讀請求的備用伺服器所需格式; 如果要支援流式複製,修改max_wal_senders為一個大於零的數值,表示流式複製最大的備用伺服器連線數目; 如果要支援流式複製,修改wal_sender_delay為一個適合的時間值,表示傳送流式日誌的週期。 如果要支援檔案式複製,設定

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'  # Unix
archive_command = 'copy "%p" "X:\\server\\archivedir\\%f"'  # Windows

其中cp或copy是shell可執行命令,用於複製日誌,具體應用中根據環境可以是scp,或其他拷貝方式。/mnt/server/archivedir/或X:\server\archivedir\表示儲存日誌的安全的位置,可供備用伺服器讀取。

4、修改備份伺服器資料目錄下的配置檔案postgresql.conf: 如果設定hot_standby為on,則允許備用伺服器支援讀請求,對應主伺服器上wal_level要設定為hot_standby;否則只作為單純的備份伺服器。

5、在備份伺服器資料目錄下新增檔案recovery.conf: 設定standby_mode為on; 如果要支援流式複製,設定primary_conninfo,例如:

'host=59.66.134.21 port=5432 user=postgres_repl password=my_pass_word'

如果要支援檔案式複製,設定

restore_command = 'cp /path/to/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'

其中/path/to/archive/為儲存從主伺服器複製的日誌的位置,cp或copy的意義同上,可替換。

6、分別啟動主伺服器和備份伺服器:

pg_ctl start -D "/var/postgres/data"  # Unix
pg_ctl start -D "D:/postgres/data"  # Windows

在主伺服器上改動資料,測試配置是否成功。

相關推薦

PostgreSQL基於日誌複製

PostgreSQL是一款優秀的開源關係型資料庫,從1989年至今已有22年曆史,經過多次轉折,如今乃是業界流行度僅次於MySQL的開源資料庫系統。比起MySQL,PostgreSQL有更好的索引支援和更穩固的ACID保證,也提供了諸多非常優秀的複製(Replicatio

PostgreSQL日誌標誌位的使用和影響

1、外掛初始化設定callback函式commit_cb 它處理事務提交資訊,但這裡拿不到太多,LogicalDecodingContext 中並沒有包含事務狀態。 2、邏輯解碼 src/backend/replication/logical/logical.c callback函式 commit

請問你知道分散式系統的日誌設計模式麼?

> 原文地址:https://martinfowler.com/articles/patterns-of-distributed-systems/wal.html # Write-Ahead log 預寫日誌 預寫日誌(WAL,Write-Ahead Log)將每次狀態更新抽象為**一個命令**並*

postgres日誌的核心實現詳解-wal記錄讀取

    之前已經寫了關於wal記錄的結構、wal記錄的寫入的部落格,流複製、PITR、資料庫啟動、邏輯複製等PG功能都需要藉助wal日誌,他們是怎樣讀取wal日誌記錄的呢?這一篇部落格將會講解。 pg核心程式碼中讀取wal有固定的程式。如下結構:  XLo

基於 raft 協議的 RocketMQ DLedger 多副本日誌複製設計原理

目錄 1、RocketMQ DLedger 多副本日誌複製流程圖 1.1 RocketMQ DLedger 日誌轉發(append) 請求流程圖 1.2 RocketMQ DLedger 日誌仲裁流程圖 1.

日誌

and 所屬組 strlen fclose 所有 modify 簡潔 urn chm 已下為我自己寫的一個寫日誌的類,比較簡潔。 <?php class Log { /** * @Purpose : 寫日誌 * @Method

基於Dapper的一個sqlhelp適用於多版本數據庫

insert mar char new delet 新車 pwd dbconnect xxx ConnectionInit方法用於初始化數據庫連接對象, 只需要修改databasetype參數即可進行適用各個版本的數據庫, ExecuteNonQuery方法用於執行增、刪、

一個不需要Log4Net的日誌的簡單方法

filename stream lena creat test contex writer exists ndt 有些項目寫日誌時會選擇大名鼎鼎的Log4Net。而在我們使用它時,總會出現一些諸如版本不匹配而造成的寫日誌失敗的情況,還要改web.config,還要改Asse

C# 日誌的方法

cto void -m directory 方法 消息 gpa sts datetime public void WriteLog(string msg) { string filePath = AppDomain.Curren

postgresql如何維護WAL日誌/歸檔日誌

font head poc removes mini iter html sting ets WAL日誌介紹   wal全稱是write ahead log,是postgresql中的online redo log,是為了保證數據庫中數據的一致性和事務的完整性。而在Post

logging模塊小知識--同時往不同文件日誌

set message 文件中 .get and sage name veh ger 當定義一個寫log的函數後,用logging多次調用該函數寫不同文件的日誌時,會出現只往一個文件中寫日誌。 因為logger會一直打開一個日誌handler,再次調用時,該handler仍

PostgreSql基於Standby的異步流主從復制

postgresql postgresql主從 一、概述PostgreSQl從9.0版本之後推出一個類似於Oracle的active dataguard和MySql中繼日誌一樣的日誌傳送。我們借助這個功能就可實現PostgreSql的主從復制。基本原理就是,通常一臺主數據庫提供讀寫,然後把數據同步到另

【php日誌】php將日誌寫入文件

web 讀寫權限 lock pen ade fwrite nginx ron lag php 寫內容到文件,把日誌寫到log文件 <?php header("Content-type: text/html; charset=utf-8"); /***********

python中logging會重復日誌的問題分析

python自動化測試 logging日誌 小強測試品牌 測試幫日記 點擊鏈接加入QQ群 522720170(免費公開課、視頻應有盡有):https://jq.qq.com/?_wv=1027&k=5C08ATe現象小強python全棧自動化測試班的學員問到,會出現重復寫日誌的情況,如

封裝日誌的類

辦公 寫日誌 gin ati 一個 ESS 輸出 int warn import loggingfrom logging import handlersclass MyLogger(): def __init__(self,file_name,level=‘info‘

重復造輪子,編寫一個輕量級的異步日誌的實用工具類(LogAsyncWriter)

tail arch read 屬性 .info ssa CA TP arp 一說到寫日誌,大家可能推薦一堆的開源日誌框架,如:Log4Net、NLog,這些日誌框架確實也不錯,比較強大也比較靈活,但也正因為又強大又靈活,導致我們使用他們時需要引用一些DLL,同時還要學習各種

.NET基於Eleasticsearch搭建日誌系統實戰演練(公開版)

問題: 動手 控制 arch 推送 平臺 記錄 插件 解決 一、需求背景介紹 1.1、需求描述 大家都知道C/S架構模式的客戶端應用程序(比如:WinForm桌面應用、WPF、移動App應用程序、控制臺應用程序、Windows服務等等)的日誌記錄都存儲在本地客戶端中

shell運行下的日誌

class nbsp current 使用 tee pytho name basename ren tee 重定向輸出到多個文件 在執行Linux命令時,我們既想把輸出保存到文件中,又想在屏幕上看到輸出內容,就可以使用tee命令 要註意的是:在使用管道線時,前一個命

Postgresql - 監控 moniter - 監控日誌

監控日誌,之前介紹過一個第三方工具,pgbadger。非常的好用。 這次介紹其他的方法。1. 通過ELK監控日誌。2. 藉助filebeats,kafka,自己編寫的監控指令碼。   通過ELK監控日誌 說是監控日誌,其實ELK主要的功能是對檔案進行收集和統計。比如某個資料