pgsql已經更新到beta11了,不同版本的服務器啟動或相關命令、配置可能會有不同,所以得根據pg版本進行操作。下面記錄一些工作中常用到的一些操作,主要包括服務啟動、備份/恢復數據、數據目錄遷移、常見操作命令
本文環境:
postgres : v10.3
os: MAC
雖然已經在kong部署中介紹了postgres的部署,為了行文連貫性,這里再簡單記錄下pg的啟動相關命令。
服務啟動
安裝
brew install postgresql which psql ~$ /usr/local/bin/psql
執行安裝命令后,會連帶安裝很多有用的pg命令如pg_ctl , postgres, psql等等
啟動pg服務
pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
這里指定了啟動的目錄,因為pg默認安裝在/usr/local/var/postgres目錄下,也可以直接實用pg_ctl start來啟動,但是必須設置環境變量PGDATA=/usr/local/var/postgres,否則會報錯
$ pg_ctl start pg_ctl: no database directory specified and environment variable PGDATA unset Try "pg_ctl --help" for more information.
設置開機自動啟動
ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
常用命令
查看版本
pg_ctl -V
查看數據庫狀態、操作
#啟動數據庫 pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start #日志路徑 cat /usr/local/var/postgres/server.log #查看數據庫狀態 pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log status #停止 pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log stop -s -m fast #查看數據庫進程 ps -ef |grep postgres 或 ps auxwww | grep postgres
創建數據庫用戶
createuser test_user -P
創建數據庫/密碼
createdb db_name -O db_pwd -E UTF8 -e
遠程進入到psql命令行
psql -U pg_user -d pg_db -h pg_host -p 5432
命令總結
1.用戶實用程序:
createdb 創建一個新的PostgreSQL的數據庫(和SQL語句:CREATE DATABASE 相同)
createuser 創建一個新的PostgreSQL的用戶(和SQL語句:CREATE USER 相同)
dropdb 刪除數據庫
dropuser 刪除用戶
pg_dump 將PostgreSQL數據庫導出到一個腳本文件
pg_dumpall 將所有的PostgreSQL數據庫導出到一個腳本文件
pg_restore 從一個由pg_dump或pg_dumpall程序導出的腳本文件中恢復PostgreSQL數據庫
psql 一個基於命令行的PostgreSQL交互式客戶端程序
vacuumdb 清理和分析一個PostgreSQL數據庫,它是客戶端程序psql環境下SQL語句VACUUM的shell腳本封裝,二者功能完全相同
2. 系統實用程序
1). pg_ctl 啟動、停止、重啟PostgreSQL服務(比如:pg_ctl start 啟動PostgreSQL服務,它和service postgresql start相同)
2). pg_controldata 顯示PostgreSQL服務的內部控制信息
3). psql 切換到PostgreSQL預定義的數據庫超級用戶postgres,啟用客戶端程序psql,並連接到自己想要的數據庫,比如說:
psql template1
出現以下界面,說明已經進入到想要的數據庫,可以進行想要的操作了。
template1=#
3. 在數據庫中的一些命令:
template1=# \l 查看系統中現存的數據庫
template1=# \q 退出客戶端程序psql
template1=# \c 從一個數據庫中轉到另一個數據庫中,如template1=# \c sales 從template1轉到sales
template1=# \dt 查看表
template1=# \d 查看表結構
template1=# \di 查看索引
[基本數據庫操作]==============
1). *創建數據庫: create database [數據庫名];
2). *查看數據庫列表: \d
3). *刪除數據庫: . drop database [數據庫名];
創建表: create table ([字段名1] [類型1] <references 關聯表名(關聯的字段名)>;,[字段名2] [類型2],......<,primary key (字段名m,字段名n,...)>;);
*查看表名列表: \d
*查看某個表的狀況: \d [表名]
*重命名一個表: alter table [表名A] rename to [表名B];
*刪除一個表: drop table [表名];
[表內基本操作]===============
*在已有的表里添加字段: alter table [表名] add column [字段名] [類型];
*刪除表中的字段: alter table [表名] drop column [字段名];
*重命名一個字段: alter table [表名] rename column [字段名A] to [字段名B];
*給一個字段設置缺省值: alter table [表名] alter column [字段名] set default [新的默認值];
*去除缺省值: alter table [表名] alter column [字段名] drop default;
在表中插入數據: insert into 表名 ([字段名m],[字段名n],......) values ([列m的值],[列n的值],......);
修改表中的某行某列的數據: update [表名] set [目標字段名]=[目標值] where [該行特征];
刪除表中某行數據: delete from [表名] where [該行特征];
delete from [表名];--刪空整個表
4. PostgreSQL用戶認證
PostgreSQL數據目錄中的pg_hba.conf的作用就是用戶認證,可以在/usr/local/pgsql/data中找到。
有以下幾個例子可以看看:
(1)允許在本機上的任何身份連接任何數據庫
TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
local all all trust(無條件進行連接)
(2)允許IP地址為192.168.1.x的任何主機與數據庫sales連接
TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
host sales all 192.168.1.0 255.255.255.0 ident sameuser(表明任何操作系統用戶都能夠以同名數據庫用戶進行連接)
5. 來一個完整的創建PostgreSQL數據庫用戶的示例吧
(1)進入PostgreSQL高級用戶
(2)啟用客戶端程序,並進入template1數據庫
psql template1
(3)創建用戶
template1=# CREATE USER hellen WITH ENCRYPED PASSWORD'zhenzhen'
(4)因為設置了密碼,所以要編輯pg_hba.conf,使用戶和配置文件同步。
在原有記錄上面添加md5
local all hellen md5
(5)使用新用戶登錄數據庫
template1=# \q
psql -U hellen -d template1
PS:在一個數據庫中如果要切換用戶,要使用如下命令:
template1=# \!psql -U tk -d template1
6. 設定用戶特定的權限
還是要用例子來說明:
創建一個用戶組:
sales=# CREATE GROUP sale;
添加幾個用戶進入該組
sales=# ALTER GROUP sale ADD USER sale1,sale2,sale3;
授予用戶級sale針對表employee和products的SELECT權限
sales=# GRANT SELECT ON employee,products TO GROUP sale;
在sale中將用戶user2刪除
sales=# ALTER GROUP sale DROP USER sale2;
7. 備份數據庫
可以使用pg_dump和pg_dumpall來完成。比如備份sales數據庫:
pg_dump sales>/home/tk/pgsql/backup/1.bak
pg數據目錄介紹
默認數據目錄如下
/usr/local/var/postgres
Linux中可能是:
/var/lib/pgsql/9.5/data 或 /var/lib/postgres/data 或 /home/postgres/data
或其它路徑
數據目錄結構大致如下:
PG_VERSION #pg版本,如10 base/ #每個 database 會在 base 目錄下有一個子目錄,存儲數據庫文件 global/ #存放的文件用於存儲全局的系統表信息和全局控制信息 pg_commit_ts/ #包含已提交事務的時間 pg_dynshmem/ #包含動態共享內存子系統使用的文件 pg_hba.conf pg_ident.conf pg_logical/ #包含邏輯解碼的狀態數據 pg_multixact/ #包含多事務狀態數據(等待鎖定的並發事務 pg_notify/ #包含LISTEN/NOTIFY狀態數據 pg_replslot/ #包含復制槽數據 pg_serial/ #包含了已經提交的序列化事務的有關信息 pg_snapshots/ #包含導出的快照 pg_stat/ #包含統計子系統的永久文件 pg_stat_tmp/ #包含統計子系統的臨時文件 pg_subtrans/ #包含子事務狀態數據 pg_tblspc/ #包含表空間的符號鏈接 pg_twophase/ #包含預備事務的狀態文件 pg_wal/ #包含wal日志 pg_xact/ postgresql.auto.conf #一個用於存儲由ALTER SYSTEM 設置的配置參數的文件 postgresql.conf postmaster.opts #一個記錄服務器最后一次啟動時使用的命令行參數的文件 server.log #pg操作日志,如果有報錯也會記錄在這里
base目錄介紹
base 目錄是最重要的一個目錄,放的是每一個 database 的數據。base 目錄里的每一個數字目錄對於一個 database 的 oid, 可以通過 查看 pg_database 這張表查看每一個 數據庫的 oid :
$ cd /usr/local/var/postgres/base total 0 drwx------ 192 5 18 15:04 ./ drwx------ 832 6 1 22:57 ../ drwx------ 9440 5 18 14:49 1/ drwx------ 9440 5 18 14:49 12557/ drwx------ 9472 6 1 22:31 12558/ drwx------ 14336 6 1 22:33 16385/ $
通過數據庫查看:
select oid, datname from pg_database ; oid datname --------------------- 12558 postgres 16385 my_test_db 1 template1 12557 template0
每一張表的數據(大部分)又是放在 base/(dboid)/(relfilenode) 這個文件里面:
select relname, relowner, relfilenode from pg_class where relowner = 16384;
relname | relowner | relfilenode
-----------------------+----------+-------------
pg_toast_24589 | 16384 | 24592
pg_toast_24589_index | 16384 | 24594
pg_toast_24595 | 16384 | 24598
pg_toast_24595_index | 16384 | 24600
item_id_seq | 16384 | 24601
Feed_pkey | 16384 | 167963
feed | 16384 | 24589
item | 16384 | 24595
pg_toast_168003 | 16384 | 168006
pg_toast_168003_index | 16384 | 168008
tmp | 16384 | 168003
(11 rows)
feed 這張表數據在 base/16384/24589 文件里,item 這張表的數據放在 base/16386/24595 這個文件里。也可以用 pg_relation_filepath 這個函數查詢:
select pg_relation_filepath('item');
pg_relation_filepath
----------------------
base/16385/24595
(1 row)
當然實際的存儲不會這么簡單。每一張表的文件都會有一些附加的存儲文件,如文件名后加上 _fsm 的是空閑空間映射表 (Free Space Map)。另外 base/(dboid)/(relfilenode) 這個文件超過 1GB 以后,Postgres 會把這個文件拆分成不超過 1G 的多個文件,文件末尾加上 .1 .2 .3 … 做編號。 如 24589 24589.1 24589.2 。據說這是因為某些文件系統支持的最大文件大小有限制(如 fat32 只支持最大 4G )的文件。
global目錄介紹
global下有四種文件:
- pg_control
用於存儲全局控制信息 - pg_filenode.map
是pg_class里relfilenode為0的系統表,OID與文件的硬編碼映射(每個用戶創建的數據庫目錄下也有同名文件)。 - pg_internal.init
是系統表的cache文件,用於加快讀取。默認不存在,查詢系統表后自動產生. - 全局系統表文件
數字命名的文件,用於存儲系統表的內容。它們在pg_class里的relfilenode都為0,是靠pg_filenode.map將OID與文件硬編碼映射。(注:不是所有的系統表的relfilenode都為0)
其它文件是需要到pg_class里根據OID查到對應的relfilenode來與文件名匹配的。
例如:tab1的relfilenode是16385,那么16385這個文件就是tab1的數據文件
名字以_fsm結尾的文件是數據文件對應的FSM(free space map)文件,用map方式來標識哪些block是空閑的。用一個Byte而不是bit來標識一個block。對於一個有N個字節的block,它在_fsm文件中第blknum個字節中記錄的值是(31+N)/32。通過這種方式標識一個block空閑字節數。FSM中不是簡單的數組,而是一個三層的樹形結構。FSM文件是在需要用到它時才自動產生的。
名字以_vm結尾的文件是數據文件對應的VM(visibility map)。PostgreSQL中在做多版本並發控制時是通過在元組頭上標識“已無效”來實現刪除或更新的,最后通過VACUUM功能來清理無效數據回收空閑空間。在做VACUUM時就使用VM開快速查找包含無效元組的block。VM僅是個簡單的bitmap,一個bit對應一個block
全局系統表位於global下,例如:pg_database,pg_tablespace,pg_auth_members這種存儲系統級對象的表。
庫級系統表位於數據庫目錄下,例如:pg_type,pg_proc,pg_attribute這種存儲庫級對象的表。
值得注意的是pg_class位於庫級目錄的里,但也包含全局系統表信息,因此研發或運維人員在改動全局系統表信息時需要注意。

data ├── global # under global, all the filenode is hard-code(select oid,relname,relfilenode from pg_class where relfilenode=0 order by oid;) │ ├── 1136 # pg_pltemplate │ ├── 1137 # pg_pltemplate_name_index │ ├── 1213 # pg_tablespace │ ├── 1214 # pg_shdepend │ ├── 1232 # pg_shdepend_depender_index │ ├── 1233 # pg_shdepend_reference_index │ ├── 1260 # pg_authid │ ├── 1261 # pg_auth_members │ ├── 1262 # pg_database │ ├── 2396 # pg_shdescription │ ├── 2397 # pg_shdescription_o_c_index │ ├── 2671 # pg_database_datname_index │ ├── 2672 # pg_database_oid_index │ ├── 2676 # pg_authid_rolname_index │ ├── 2677 # pg_authid_oid_index │ ├── 2694 # pg_auth_members_role_member_index │ ├── 2695 # pg_auth_members_member_role_index │ ├── 2697 # pg_tablespace_oid_index │ ├── 2698 # pg_tablespace_spcname_index │ ├── 2846 # pg_toast_2396 │ ├── 2847 # pg_toast_2396_index │ ├── 2964 # pg_db_role_setting │ ├── 2965 # pg_db_role_setting_databaseid_rol_index │ ├── 2966 # pg_toast_2964 │ ├── 2967 # pg_toast_2964_index │ ├── 3592 # pg_shseclabel │ ├── 3593 # pg_shseclabel_object_index │ ├── 4060 # pg_toast_3592x │ ├── 4061 # pg_toast_3592_index │ ├── 6000 # pg_replication_origin │ ├── 6001 # pg_replication_origin_roiident_index │ ├── 6002 # pg_replication_origin_roname_index │ ├── pg_control # global control file, use pgcheck -pc to see it. │ ├── pg_filenode.map # system table (oid -> filenode) mapping file, use pgcheck -pm to see it. │ └── pg_internal.init # system table cache file, use pgcheck -pr to see it.
表空間目錄介紹
my_test_db=# select oid,* from pg_tablespace; oid | spcname | spcowner | spcacl | spcoptions -------+------------+----------+--------+------------ 1663 | pg_default | 10 | | 1664 | pg_global | 10 | | 49162 | dbspace | 10 | | (3 rows)
每一個Oid都在/pg_tblspc下對應一個名為Oid的軟鏈接文件,指向真正的space目錄。
postgresql.conf文件
文件存儲路徑,連接配置,資源使用,優化配置,日志設置等
修改需要重啟數據庫
主要配置如下:

#------------------------------------------------------------------------------ # FILE LOCATIONS #------------------------------------------------------------------------------ # The default values of these variables are driven from the -D command-line # option or PGDATA environment variable, represented here as ConfigDir. #data_directory = 'ConfigDir' # use data in another directory # (change requires restart) #hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file # (change requires restart) #ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file # (change requires restart) # If external_pid_file is not explicitly set, no extra PID file is written. #external_pid_file = '' # write an extra PID file # (change requires restart) #------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION #------------------------------------------------------------------------------ # - Connection Settings - listen_addresses = 'localhost' # what IP address(es) to listen on; # comma-separated list of addresses; # defaults to 'localhost'; use '*' for all # (change requires restart) port = 5432 # (change requires restart) max_connections = 100 # (change requires restart) #superuser_reserved_connections = 3 # (change requires restart)
pg_hba.conf 文件
服務器主機連接驗證配置文件
修改需要重啟數據庫
數據備份和恢復
備份庫
pg_dump -h PG_HOST -U PG_USER DATABASE > DATABASE.bak
備份表
pg_dump -h localhost -U postgres(用戶名) 數據庫名(缺省時同用戶名) -t table(表名) >data.bak
pg_dump命令參數說明:
pg_dump 把一個數據庫轉儲為純文本文件或者是其它格式. 用法: pg_dump [選項]... [數據庫名字] 一般選項: -f, --file=FILENAME 輸出文件或目錄名 -F, --format=c|d|t|p 輸出文件格式 (定制, 目錄, tar) 明文 (默認值)) -j, --jobs=NUM 執行多個並行任務進行備份轉儲工作 -v, --verbose 詳細模式 -V, --version 輸出版本信息,然后退出 -Z, --compress=0-9 被壓縮格式的壓縮級別 --lock-wait-timeout=TIMEOUT 在等待表鎖超時后操作失敗 -?, --help 顯示此幫助, 然后退出
恢復庫/表
psql -h PG_HOST -U PG_USER -d DATABASE < DATABASE.bak
或
psql -h PG_HOST -U PG_USER -d DATABASE -f DATABASE.bak
注意:
- 如果直接進入PostgreSQL的安裝目錄bin下,執行命令,可能會出現 找不到pg_dump,psql的現象,可以用命令的絕對路徑,如/usr/local/bin/psql 等
- 如果是遠程備份和恢復,必須保證數據庫允許外部訪問的權限
常見數據庫操作
基本和mysql類似
# 創建新表 CREATE TABLE user_tbl(name VARCHAR(20), signup_date DATE); # 插入數據 INSERT INTO user_tbl(name, signup_date) VALUES('張三', '2013-12-22'); # 選擇記錄 SELECT * FROM user_tbl; # 更新數據 UPDATE user_tbl set name = '李四' WHERE name = '張三'; # 刪除記錄 DELETE FROM user_tbl WHERE name = '李四' ; # 添加欄位 ALTER TABLE user_tbl ADD email VARCHAR(40); # 更新結構 ALTER TABLE user_tbl ALTER COLUMN signup_date SET NOT NULL; # 更名欄位 ALTER TABLE user_tbl RENAME COLUMN signup_date TO signup; # 刪除欄位 ALTER TABLE user_tbl DROP COLUMN email; # 表格更名 ALTER TABLE user_tbl RENAME TO backup_tbl; # 刪除表格 DROP TABLE IF EXISTS backup_tbl;
數據目錄遷移
通常數據目錄會安裝在系統盤,而系統盤的空間有限,當數據庫量大或日志多時,會撐爆硬盤造成服務停掉,因此通常將數據遷移到數據盤
在CentOS 系統中,pg的默認數據安裝目錄是
/var/lib/pgsql/{version}/data
數據庫服務一般開機自動啟動,那么就可以順藤摸瓜找到相關的service。
對於postgresql10,它的服務名為postgresql-10.service,該文件的路徑為:
/usr/lib/systemd/system/postgresql-10.service
postgresql-10.service的文件內容如下:

# It's not recommended to modify this file in-place, because it will be # overwritten during package upgrades. If you want to customize, the # best way is to create a file "/etc/systemd/system/postgresql-10.service", # containing # .include /lib/systemd/system/postgresql-10.service # ...make your changes here... # For more info about custom unit files, see # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F # Note: changing PGDATA will typically require adjusting SELinux # configuration as well. # Note: do not use a PGDATA pathname containing spaces, or you will # break postgresql-setup. [Unit] Description=PostgreSQL 10 database server Documentation=https://www.postgresql.org/docs/10/static/ After=syslog.target After=network.target [Service] Type=notify User=postgres Group=postgres # Note: avoid inserting whitespace in these Environment= lines, or you may # break postgresql-setup. # Location of database directory Environment=PGDATA=/home/pgsql/data/ # Where to send early-startup messages from the server (before the logging # options of postgresql.conf take effect) # This is normally controlled by the global default set by systemd # StandardOutput=syslog # Disable OOM kill on the postmaster OOMScoreAdjust=-1000 Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj Environment=PG_OOM_ADJUST_VALUE=0 ExecStartPre=/usr/pgsql-10/bin/postgresql-10-check-db-dir ${PGDATA} ExecStart=/usr/pgsql-10/bin/postmaster -D ${PGDATA} ExecReload=/bin/kill -HUP $MAINPID KillMode=mixed KillSignal=SIGINT # Do not set any timeout value, so that systemd will not kill postmaster # during crash recovery. TimeoutSec=0 [Install] WantedBy=multi-user.target
如果postgresql沒有作為服務加到systemctl, 則修改對應的配置文件postgresql.conf中的data_directory的值,通過pg_ctl啟動,和下面操作一樣
從上面來看里面用到了PGDATA Environment,后面需要修改該變量,但是得先執行下列步驟:
1. 關閉數據庫服務
service postgresql-10 stop
2. 拷貝原先的data目錄到新的data目錄
sudo cp -rf /var/lib/pgsql/10/data /home/pgsql/data
3. 設置用戶和權限
# 修改data_directory的所有者 sudo chown -R postgres:postgres /home/pgsql/data
# 設置數據目錄權限 sudo chmod 700 /home/pgsql/data
4. 上述2、3完成后,可以修改service文件里面的enviroment變量,可以將這個變量修改為自己的data目錄
cd /usr/lib/systemd/system/
sudo vi postgresql-10.service ~ 修改這個文件中的
Environment=PGDATA=/var/lib/pgsql/10/data/
將其修改為自己的新的數據路徑:
Environment=PGDATA=/home/psql/data/
修改PGDATA路徑之后,就可以執行下面的命令讓其立即生效
sudo systemctl daemon-reload
5. 重啟數據庫
service postgresql-10 start
6. 驗證
show data_directory;
1)如果還沒有改正過來,可以看下PGDATA這個變量的位置,
這個變量的位置在哪呢?這里因為postgresql安裝后會自動生成一個postgres用戶,因此猜測這個用戶下存在PGDATA環境變量
su - postgres ,進入postgres用戶下,查看當前用戶的環境變量
echo $PGDATA,打印出PGDATA變量值,可以看到這個變量值還是之前那個值。因此我們可以知道了,是這個地方有問題。
於是,修改這個用戶的環境變量設置文件
vi ~/.bash_profile,修改里面的PGDATA路徑
source ~/.bash_profile使文件生效
再重啟數據庫服務
2)可能需要postgres用戶的宿主目錄
cat /etc/passwd
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
sudo usermod -d /home/data/pgsql -u 26 postgres
查看數據庫用戶
SELECT u.usename AS "User name", u.usesysid AS "User ID" , CASE WHEN u.usesuper AND u.usecreatedb THEN CAST('superuser, createdatabase' AS pg_catalog.text) WHEN u.usesuper THEN CAST('superuser' AS pg_catalog.text) WHEN u.usecreatedb THEN CAST('create database' AS pg_catalog.text) ELSE CAST('' AS pg_catalog.text) END AS "Attributes" FROM pg_catalog.pg_user u ORDER BY 1; -- 或者直接這么查 select * from pg_catalog.pg_user
3)注意:postgresql已經作為服務添加到了systemctl
MAC 系統數據目錄遷移思路同上。
參考:
https://blog.csdn.net/guanguoxiang/article/details/46375653