一、高可用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
四、索引
--查詢索引 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年數據庫方向大佬