pg數據庫學習


一、高可用stolon基礎概念

https://github.com/sorintlab/stolon  項目地址

Stolon是一個cloud native的PostgreSQL高可用管理工具

stolon is a cloud native PostgreSQL manager for PostgreSQL high availability.

Stolon 是由3個部分組成的:

  • keeper:負責管理PostgreSQL的實例匯聚到由sentinel(s)提供的clusterview。

  • sentinel:負責發現並且監控keeper,並且計算最理想的clusterview。

  • proxy:客戶端的接入點。它強制連接到右邊PostgreSQL的master並且強制關閉連接到由非選舉產生的master。

Stolon 用etcd或者Consul作為主要的集群狀態存儲。

二、pg數據庫備份

pg_dump(SQL轉儲備份,屬於邏輯備份工具

pg_dump是一個普通的客戶端工具,如果不指定主機IP和端口,那么默認備份的是本地服務器上的數據庫。一般來說,這個命令由超級管理員來運行,這樣可以備份到整個數據庫的所有對象。由數據庫創建的對象是一致的,即在運行pg_dump那一刻存儲了該時刻的數據庫快照,這個命令在運行過程中數據庫的更新不會被轉儲。同時,pg_dump不會阻塞其他對數據庫的操作。

備份:
pg_dump  -h 主機地址  -U username   數據庫   >   備份數據庫.dmp   
恢復:
createdb -h localhost -U username  -E unicode   新數據庫名字
psql  -h localhost -U username    -d  新數據庫名字   <  備份數據庫.dmp

上述兩個命令都是在postgres用戶下運行的,outfile和infile都是sql文件。

恢復

pg_dump生成的sql文本可以有psql程序讀取,但是注意的是恢復數據庫的時候dbname是需要存在的,也就是說,轉儲文件中並不包含創建數據庫的語句。可以在恢復之前創建一個數據庫,用如下命令來創建一個數據庫。

createdb -T template0 dbname

表明這個數據庫dbname是基於模板template0來創建的,然后再執行如下恢復語句:

psql dbname < infile

pg_dumpall

pg_dump工具轉儲的是一個數據庫dbname中所有的信息,不會轉儲角色和表空間等信息,進行單個數據庫的備份,如果需要完整轉儲整個數據庫中所有的數據庫實例,PostgreSQL提供了一個工具pg_dumpall,該工具能夠轉儲一個數據庫集簇中所有的內容,同時還確保保留象用戶和組這樣的全局數據狀態,包含了前面提到的角色和表空間。使用的方法是:

備份:pg_dumpall > outfile

docker exec -t pg_container bash -c " 
export PGPASSWORD=$POSTGRES_PASS; 
pg_dumpall \ 
-h $POSTGRES_HOST \ 
-p $POSTGRES_PORT \ 
-U $POSTGRES_USER \ 
| gzip > $BACK_DIR/$POSTGRES_DB_NAME; "

恢復:psql -f infile postgres

從pg_dump和pg_dumpall兩個工具的作用來看,前者偏向於重建一個數據庫實例,這個實例中包含了基本的對象和數據信息,適用於角色等信息比較簡單等,常用於定期備份使用;后者偏向於重建一個數據庫集簇,適用於在一個新的環境中部署一套與原來一致的數據庫環境,包括表空間和角色,尤其是在角色較多的復雜環境下,減少了手動干預的工作量。

pg_basebackup(物理備份)

Usage:
  pg_basebackup [OPTION]...

-h 指定連接的數據庫的主機名或IP地址,這里就是主庫的ip。

-U 指定連接的用戶名,專門負責流復制的repl用戶。

-F, --format=p|t output format (plain (default), tar)

指定輸出格式:p原樣輸出,即把主數據庫中的各個數據文件,配置文件、目錄結構都完全一樣的寫到備份目錄;t 把輸出的備份文件打包到一個tar文件中。

-x 表示備份開始后,啟動另一個流復制連接從主庫接收WAL日志。

-R 表示會在備份結束后自動生成recovery.conf文件,這樣也就避免了手動創建。(12.0有差異)

-D, --pgdata=DIRECTORY receive base backup into directory

指定把備份寫到那個目錄,如果這個目錄或這個目錄路徑中的各級父目錄不存在,則pg_basebackup就會自動創建這個目錄,如果目錄存在,但目錄不為空,則會導致pg_basebackup執行
失敗。

-l 表示指定一個備份的標識

-r, --max-rate=RATE maximum transfer rate to transfer data directory  (in kB/s, or use suffix "k" or "M")

-T, --tablespace-mapping=OLDDIR=NEWDIR   relocate tablespace in OLDDIR to NEWDIR

-x, --xlog include required WAL files in backup (fetch mode)

備份時會把備份中產生的xlog文件也自動備份出來,這樣才能在恢復數據庫時,應用這些xlog文件把數據庫推到一個一致點,然后真正打開這個備份的數據庫,這個選項與

-X fetch是完全一樣的。使用這個選項,需要設置“wal_keep_segments"參數,以保證在備份過程中,需要的WAL日志文件不會被覆蓋。

-X, --xlog-method=fetch|stream

include required WAL files with specified method

--xlogdir=XLOGDIR location for the transaction log directory

-z, --gzip compress tar output  使用gzip壓縮,僅能能與tar輸出模式配合使用。

-Z, --compress=0-9 compress tar output with given compression level   指定壓縮級別

-P, --progress show progress information    在備份過程中實時打印備份進度

-v, --verbose output verbose messages    詳細模式,使用了-P后,還會打印出正在備份的具體文件的信息。

-p, --port=PORT database server port number

docker exec -t pg_container bash -c "
export PGPASSWORD=xxxx;
pg_basebackup \
-h stolon_node \
-p stolon-proxy-port \
-U replication \
-Ft -Pv -z \
-D XXX"

選項含義

選項 含義
-f<文件名> 指定輸出文件
-s 只轉儲模式,不包括數據
-x 不要轉儲權限
-a 只轉儲數據,不包括模式
-t 只轉儲表空間,而不轉儲數據庫或角色
-r 只轉儲角色,不包括數據庫或表空間
-g 只轉儲全局對象,不包括數據庫
-c 在重新創建之前,先刪除數據庫對象
-O 不恢復對象所屬者
--disable-triggers 在只恢復數據的過程中禁用觸發器
-S<用戶名> 在轉儲中,指定的超級用戶名
-h<主機名> 數據庫服務器的主機名
-l<數據庫名> 另一個默認數據庫
-p<端口號> 數據庫服務器端口號
-U<名字> 以指定的數據庫用戶連接
-w 永遠不提示輸入口令
-W 強制口令提示
--inserts 以INSERT命令,而不是COPY命令的形式轉儲數據
--column-inserts 以帶有列名的INSERT命令形式轉儲數據
--no-tablespaces 不轉儲表空間分配信息

備份postgresql服務器上的所有數據庫

# su - postgres
$ pg_dumpall >db.sql

備份postgresql服務器上的所有數據庫,只轉儲模式,不包括數據

$ pg_dumpall -s >db2.sql

備份postgresql服務器上的所有數據庫,只轉儲數據,不包括模式

$ pg_dumpall -a >db3.sql 

案例

#!/bin/bash

POSTGRES_HOST='node8'
POSTGRES_PORT=5432
POSTGRES_USER='xxxxx'
POSTGRES_PASS='xxxxx'

# 數據庫備份文件夾名
POSTGRES_DB_NAME="node_basebackup_$(date '+%Y%m%d_%H%M%S')"

# 數據庫備份路徑名
BACK_FOLDER=/mnt/hdd2/pg_data_back

saturday=$(date '+%w') #確定今天是周幾
if [[ $saturday -eq 6 ]]; then
    folder="weeks";
else
    folder="days";
fi

BACK_DIR=$BACK_FOLDER/$folder/$(date '+%Y%m%d')
mkdir -p $BACK_DIR

# 生成備份
docker exec -t pg_tools bash -c "
export PGPASSWORD=$POSTGRES_PASS;
pg_basebackup \
-h $POSTGRES_HOST \
-p $POSTGRES_PORT \
-U $POSTGRES_USER \
-Ft  -Pv -z \
-D $BACK_DIR/$POSTGRES_DB_NAME \
"

## 刪除days目錄下7天前的文件
## 刪除weeks目錄下365天前的文件
## 每周六運行一次刪除
if [[ $saturday -eq 6 ]]; then
    DEL_DIR=$BACK_FOLDER/days
    if [[ -d $DEL_DIR ]]; then
        find $DEL_DIR -mindepth 1 -type d -mtime +7 | xargs rm -rf
    else
        echo "Folder $DEL_DIR is not exist";
    fi
    DEL_DIR=$BACK_FOLDER/weeks
    if [[ -d $DEL_DIR ]]; then
        find $DEL_DIR -mindepth 1 -type d -mtime +365 | xargs rm -rf
    else
        echo "Folder $DEL_DIR is not exist";
    fi
fi

# 同步到 storage
rsync -aP --delete ${BACK_FOLDER}/  node5:/mnt/hdd1/pg_data_back/

# 重啟pg_tools,防止卡死導致備份失敗
docker restart pg_tools

三、客戶端可視化工具pgadmin4

docker pull dpage/pgadmin4
docker run -p 80:80 \
    --restart=always \
    -e "PGADMIN_DEFAULT_EMAIL=user@domain.com" \
    -e "PGADMIN_DEFAULT_PASSWORD=SuperSecret" \
    -d dpage/pgadmin4

 

https://blog.csdn.net/qq_28289405/article/details/80243476

https://www.yiibai.com/postgresql/postgresql-syntax.html  不錯的教程

四、導出csv文件

查詢stolon從節點

方法一:執行sql語句查詢,順便導出csv文件

文件名
file_name="slave.csv"

# sql語句
sql1="select client_addr from pg_stat_replication"

# 導出csv文件
docker exec -it stolon_proxy sh -c "export PGPASSWORD=xxxxx;  psql -h 127.0.0.1 -d dbname -U db_user -c \"COPY (${sql1}) to stdout (FORMAT CSV, HEADER);\" | tee /tmp/${file_name} " && docker cp stolon_proxy:/tmp/$file_name ~/xxx/xxx/xx/

執行腳本

bash sql-import.sh
client_addr
192.20.223.3
192.20.223.13
方法二:查看stolon的log
stolon-proxy 的日志,會顯示 proxying to master address XXXXXX ,這個地址就是master,剩下的就是slave

四、索引

--查詢索引
select * from pg_indexes where tablename='tab1';   

--創建索引  tab1_bill_code_index  為索引名,
create index  tab1_bill_code_index  on  "db1".tab1(bill_code);

--刪除索引
drop index tab1_bill_code_index  ;

統計創建索引耗時、索引占用空間大小

#!bin/bash

sql1='CREATE INDEX fingerprint_citizen_f436dd_hash  ON public.fingerprint_personinfo USING hash (citizen_id_number COLLATE pg_catalog."default") TABLESPACE pg_default'

sql2="select pg_size_pretty(pg_relation_size('fingerprint_citizen_f436dd_hash'))"

start=$(date +%s)

docker exec -it  postgres sh -c "export PGPASSWORD=moqi#233@fingerprint;   psql -h 127.0.0.1 -d fingerprint -U moqi_user -c \"${sql1};\""

end=$(date +%s)

take=$((end - start)) 

echo $take

docker exec -it  postgres sh -c "export PGPASSWORD=xx;   psql -h 127.0.0.1 -d databasename -U user -c \"COPY (${sql}) to stdout (FORMAT CSV, HEADER);\" | tee /tmp/zjz " && docker cp stolon_proxy:/tmp/zjz ~

執行后在創建索引期間會阻塞 dml,特別是比較繁忙的系統或者大表上執行

因此使用 concurrently 選項不阻塞事務創建索引

create index concurrently idx_table_name_x1 on table_name(col_name); 

五、解鎖

查詢正在運行的進程

//datname為數據庫名稱
select * from pg_stat_activity WHERE datname='aaa' 

查看等待中的進程

//wait_event_type = 'Lock' 表示鎖表線程
select * from pg_stat_activity WHERE datname='aaa' and wait_event_type = 'Lock'

釋放鎖定

//多個同時執行,返回結果為f
select pg_cancel_backend('上面查到的pid');
select pg_cancel_backend('上面查到的pid');
select pg_cancel_backend('上面查到的pid');
select pg_cancel_backend('上面查到的pid');
select pg_cancel_backend('上面查到的pid');

六、補充:

1、目前主流的數據庫訪問技術(驅動)

2、postgresql 列出某個數據庫下的某個schema下面所有的表

select * from pg_tables where schemaname = 'schema_name'

 

 

 

 

https://blog.csdn.net/horses/category_2677699.html     14年數據庫方向大佬


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM