postgresql学习笔记--基础篇 -psql工具

--创建用户
CREATE ROLE pguser WITH ENCRYPTED PASSWORD 'pguser';
--创建表空间目录
mkdir -p /database/pg10/pg_tbs/tbs_mydb
--创建表空间
CREATE TABLESPACE tbs_mydb OWNER pguser LOCATION '/database/pg10/pg_tbs/tbs_mydb';
--创建数据库
CREATE DATABSE mydb WITH OWNER = pguser TEMPLATE=template0 ENCODING='UTF8' TABLESPACE=tbs_mydb;
--赋权
GRANT ALL ON DATABASE mydb TO pguser WITH GRANT OPTION;
GRANT ALL ON TABLESPACE tbs_mydb TO pguser;

1. psql 元命令介绍

1.1 \l 列出所有数据库列表

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |  Collation  |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 ambari    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres
                                                             : postgres=CTc/postgres
                                                             : ambari=CTc/postgres
 ambarirca | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres
                                                             : postgres=CTc/postgres
                                                             : mapred=CTc/postgres
 mydb      | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
                                                             : postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
                                                             : postgres=CTc/postgres
(6 rows)

1.2 、\db 查看表空间列表

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

1.3 \d查看表定义

postgres=# \dt
                  List of relations
 Schema |           Name           | Type  |  Owner
--------+--------------------------+-------+----------
 public | cloud_sql_static         | table | postgres
 public | cloud_subscriber_devices | table | postgres
 public | cloud_subscribers        | table | postgres
 public | cloud_table_static       | table | postgres
 public | sxacc-device-types       | table | postgres
 public | sxacc-devices            | table | postgres
(6 rows)

postgres=# \d cloud_table_static
             Table "public.cloud_table_static"
       Column        |           Type           | Modifiers
---------------------+--------------------------+-----------
 relname             | character varying(255)   |
 seq_scan            | bigint                   |
 seq_tup_read        | bigint                   |
 idx_scan            | bigint                   |
 idx_tup_fetch       | bigint                   |
 n_tup_ins           | bigint                   |
 n_tup_upd           | bigint                   |
 n_tup_del           | bigint                   |
 n_tup_hot_upd       | bigint                   |
 n_live_tup          | bigint                   |
 n_dead_tup          | bigint                   |
 n_mod_since_analyze | bigint                   |
 last_vacuum         | timestamp with time zone |
 last_autovacuum     | timestamp with time zone |
 last_analyze        | timestamp with time zone |
 last_autoanalyze    | timestamp with time zone |
 vacuum_count        | bigint                   |
 autovacuum_count    | bigint                   |
 analyze_count       | bigint                   |
 autoanalyze_count   | bigint                   |
 import_date         | timestamp with time zone |

postgres=#

 1.4 查看表/索引占用空间大小

给测试表test插入500万数据:

postgres=# create table test(id int primary key, name varchar(100));
CREATE TABLE
postgres=# insert into test(id,name) select n,n||'_francs' from generate_series(1,5000000) n;
INSERT 0 5000000
postgres=# \di+ test_pkey
                          List of relations
 Schema |   Name    | Type  |  Owner   | Table |  Size  | Description
--------+-----------+-------+----------+-------+--------+-------------
 public | test_pkey | index | postgres | test  | 107 MB |
(1 row)

postgres=# \dt+ test
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description
--------+------+-------+----------+--------+-------------
 public | test | table | postgres | 249 MB |
(1 row)

1.5 \sf 查看函数代码

mydb#\sf random_range
CREATE OR REPLACE FUNCTION pguser.random_range(integer,integer)
     RETURN integer
     LANGUAGE sql
AS $function$
     SELECT ($1 + FLOOR(($2-$1 +1 )* random()))::int4;
     $function$

上述\sf命令后面可以只接函数的名称,或者函数名称及输入参数类型,例如random_range(integer,integer),Postgres支持名称相同但输入参数类型不同的函数,如果有同名函数,\sf 必须指定参数类型。 

1.6 \x 设置查询结果输出

postgres=# \x
Expanded display is on.
postgres=# select * from test limit 1;
-[ RECORD 1 ]--
id   | 1
name | 1_francs

 

1.7 -E 获取元命令对应的SQL代码

postgres:~$ psql -E
psql (9.5.14)
Type "help" for help.

postgres=# \db
********* QUERY **********
SELECT spcname AS "Name",
  pg_catalog.pg_get_userbyid(spcowner) AS "Owner", pg_catalog.pg_tablespace_location(oid) AS "Location" FROM pg_catalog.pg_tablespace ORDER BY 1; ************************** List of tablespaces Name | Owner | Location ------------+----------+---------- pg_default | postgres | pg_global | postgres | (2 rows) postgres=#

 

1.8 -A 设置非对齐输出模式

psql执行SQL输出默认是对齐模式,例如

postgres@nancloud-onprem-06:~$ psql -c "select datname,dattablespace from pg_database limit 1;"
  datname  | dattablespace
-----------+---------------
 template1 |          1663
(1 row)

--注意返回结果,这里有空行

以上输出,格式是对齐的,psql加上-A选项如下所示:

postgres@nancloud-onprem-06:~$ psql -A -c "select datname,dattablespace from pg_database limit 1;"
datname|dattablespace
template1|1663
(1 row) --注意返回结果,没有空行

加上-A选项以后输出的格式变成不对齐的了,并且返回结果中没有空行。

1.9 -t 只显示记录数据

-t 参数设置输出只显示数据,而不显示字段名称和返回的结果集行数。

postgres@nancloud-onprem-06:~$ psql -t -c "select datname,dattablespace from pg_database limit 1;"
 template1 |          1663
--注意返回结果,这里有空行

 

postgres@nancloud-onprem-06:~$ psql -At -c "select datname,dattablespace from pg_database limit 1;"
template1|1663    --> 注意这里没有空行
postgres@nancloud-onprem-06:~$

以上在写shell 脚本非常有效。 

1.10 -q 不显示输出信息

默认情况下,使用psql执行sql命令会返回多种消息,使用-q参数后将不再显示这些信息。

postgres@nancloud-onprem-06:~$ psql -f test.sql
DROP TABLE
CREATE TABLE 
INSERT 0 1
postgres@nancloud-onprem-06:~$ psql  -q -f test.sql
--这里不显示输出信息

 

注意:psql 的-single-transaction 或 -l 选项支持在一个事物中执行脚本,要么脚本中所有SQL执行成功,如果其中有SQL执行失败,则文件中的所有SQL回滚。 

 

2. psql 如何传递变量到SQL

2.1 \set 元命令方式传递变量

\set 元子命令可以设置变量,格式如下所示,name表示变量名称,value表示变量值,如果不填写value,变量值为空。

\set name value

mydb=>\set v_id 2
mydb=>select * from test where id:v_id;
id  | name
----+------
2   |   b
(1 row)

如果想取消之前变量设置的值,\set 命令后接参数名称即可:

mydb=>\set v_id

通过\set 元命令设置变量的一个典型应用场景是使用pgbench进行压力测试。

 

2.2 psql 的-v 参数传递变量

样例:写一个select_1.sql 脚本

select * from test where id:v_id;

通过psql接-v传递变量,并执行脚本

postgre# psql -v v_id=1 mydb pguser -f select_1.sql
id   | name
-----+-------
1    | a
(1 row)

 

2.3 使用psql定制日常维护脚本

先介绍 .psqlrc文件,如果psql没有带-X 选项,psql尝试读取和执行用户~/.psqlrc 启动文件中的命令,结合这个文件能够方便地预先定制维护脚本。

2.3.1.查询活动会话

cloud=# select pid,usename,datname,application_name,client_addr,age(clock_timestamp(), query_start),query from pg_stat_activity where pid<>pg_backend_pid() and state='active' order by query_start desc;
  pid  |   usename   | datname |    application_name    | client_addr |       age       |          query
-------+-------------+---------+------------------------+-------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  6634 | replication |         | walreceiver            | 10.2.38.108 |                 |
  6636 | replication |         | walreceiver            | 10.2.39.66  |                 |
 30315 | calixcloud  | cloud   | PostgreSQL JDBC Driver | 10.2.42.249 | 00:00:00.419892 | SELECT subscriber_id,service_addr,street,city,state,country,postcode FROM cloud_subscribers WHERE lat IS NULL and lon IS NULL AND service_addr IS NOTNULL LIMIT 1
  7791 | calixcloud  | cloud   | PostgreSQL JDBC Driver | 10.2.35.36  | 00:00:00.602242 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs4-us.calix.com.8339"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test"t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536640}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1)  t1 WHERE t.info->>'_id' =  t1.info->>'_id' RETURNING  t1.*
  9747 | calixcloud  | cloud   | PostgreSQL JDBC Driver | 10.2.36.242 | 00:00:00.979992 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs3-us.calix.com.32325"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536261}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1)  t1WHERE t.info->>'_id' =  t1.info->>'_id' RETURNING  t1.*
  8615 | calixcloud  | cloud   | PostgreSQL JDBC Driver | 10.2.35.127 | 00:00:01.071608 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs2-us.calix.com.1277"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test"t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536171}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1)  t1 WHERE t.info->>'_id' =  t1.info->>'_id' RETURNING  t1.*
 14164 | postgres    | cloud   | psql                   |             | 00:05:52.667716 | VACUUM (VERBOSE, ANALYZE) "sxacc-files";
(7 rows)
  • active: 任务正在执行
  • idle:后台进程为空闲状态,等待后续客户端发出命令
  • idle in transaction:后台进程正在事务中,并不是指正在执行SQL
  • idle in transaction(aborted):和idle in transaction 类似,只是事务中的部分SQL异常
vim ~/.psqlrc
-- 设置活动会话
\set active_session 'select pid,usename,datname,application_name,client_addr,age(clock_timestamp(), query_start),query from pg_stat_activity where pid<>pg_backend_pid() and state=\'active\' order by query_start desc;'

之后重新连接数据库,执行:active_session即可。 

postgres#:active_session
pid | usename | datname | application_name | client_addr | age | query
-------+-------------+---------+------------------------+-------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6634 | replication | | walreceiver | 10.2.38.108 | |
6636 | replication | | walreceiver | 10.2.39.66 | |
30315 | calixcloud | cloud | PostgreSQL JDBC Driver | 10.2.42.249 | 00:00:00.419892 | SELECT subscriber_id,service_addr,street,city,state,country,postcode FROM cloud_subscribers WHERE lat IS NULL and lon IS NULL AND service_addr IS NOTNULL LIMIT 1
7791 | calixcloud | cloud | PostgreSQL JDBC Driver | 10.2.35.36 | 00:00:00.602242 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs4-us.calix.com.8339"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test"t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536640}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1) t1 WHERE t.info->>'_id' = t1.info->>'_id' RETURNING t1.*
9747 | calixcloud | cloud | PostgreSQL JDBC Driver | 10.2.36.242 | 00:00:00.979992 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs3-us.calix.com.32325"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536261}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1) t1WHERE t.info->>'_id' = t1.info->>'_id' RETURNING t1.*
8615 | calixcloud | cloud | PostgreSQL JDBC Driver | 10.2.35.127 | 00:00:01.071608 | UPDATE "sxacc-net-perf-test" t SET info = jsonb_set(t.info,'{worker}','"gcs2-us.calix.com.1277"',true) FROM (SELECT t.info FROM "sxacc-net-perf-test"t WHERE (t.info->>'nextRunTime')::jsonb < '{"$date":1576820536171}' AND (t.info->'worker')::jsonb IS NULL LIMIT 1) t1 WHERE t.info->>'_id' = t1.info->>'_id' RETURNING t1.*
14164 | postgres | cloud | psql | | 00:05:52.667716 | VACUUM (VERBOSE, ANALYZE) "sxacc-files";
(7 rows)

 

2.3.2.查询等待事件

-- check wait events
\set wait_event 'select pid,application_name,client_addr,age(clock_timestamp(),query_start),state,wait_event_type,wait_event from pg_stat_activity where pid<>pg_backend_pid() and wait_event is not null order by wait_event_type;'
cloud=# :wait_event
  pid  |    application_name    |  client_addr   |       age       | state  | wait_event_type |     wait_event
-------+------------------------+----------------+-----------------+--------+-----------------+---------------------
  6576 |                        |                |                 |        | Activity        | CheckpointerMain
  6636 | walreceiver            | 10.2.39.66     |                 | active | Activity        | WalSenderMain
  6634 | walreceiver            | 10.2.38.108    |                 | active | Activity        | WalSenderMain
  6581 |                        |                |                 |        | Activity        | LogicalLauncherMain 6577 | | | | | Activity | BgWriterMain 6578 | | | | | Activity | WalWriterMain 8466 | PostgreSQL JDBC Driver | 10.2.41.193 | 00:08:38.596477 | idle | Client | ClientRead 18770 | PostgreSQL JDBC Driver | 10.2.42.249 | 00:28:02.041479 | idle | Client | ClientRead 9401 | PostgreSQL JDBC Driver | 10.2.42.219 | 00:07:35.883319 | idle | Client | ClientRead 5690 | PostgreSQL JDBC Driver | 10.2.41.193 | 00:10:09.736458 | idle | Client | ClientRead

 

3. PSQL 其他功能

 3.1 \timing 显示SQL执行时间

cloud=# \timing
Timing is on.
cloud=# select tablename,tableowner from pg_tables limit 10;
             tablename             | tableowner
-----------------------------------+------------
 pg_statistic                      | postgres
 cloud_subscriber_services_bak     | calixcloud
 sxacc-es-index                    | calixcloud
 pg_foreign_table                  | postgres
 pg_authid                         | postgres
 cloud_subscriber_devices_12670060 | postgres
 cloud_subscribers_12670060        | postgres
 pg_user_mapping                   | postgres
 pg_subscription                   | postgres
 pg_largeobject                    | postgres
(10 rows)

Time: 64.629 ms
cloud=# \timing
Timing is off.

 

3.2 \watch 反复执行当前SQL

\watch 元命令会反复执行当前查询缓冲区的SQL命令,直到SQL被终止或执行失败。语法如下:

\watch [seconds]

seconds表示两次执行的间隔时间,以秒为单位,默认为2s,例如

postgres=# select now()
postgres-# ;
              now
-------------------------------
 2019-12-23 11:06:17.857293+08
(1 row)

postgres=# \watch 3
Watch every 3s  Mon Dec 23 11:06:21 2019

              now
-------------------------------
 2019-12-23 11:06:21.457454+08
(1 row)

Watch every 3s  Mon Dec 23 11:06:24 2019

              now
-------------------------------
 2019-12-23 11:06:24.461225+08
(1 row)

Watch every 3s  Mon Dec 23 11:06:27 2019

              now
-------------------------------
 2019-12-23 11:06:27.465306+08
(1 row)

 

3.3 psql 客户端提示符

用户可以根据喜好设置psql客户端提示符,常用选项如下:

  • %M:数据库服务器别名,不是指主机名,显示的是psql -h 参数设置的值;
  • %> :数据库服务器的端口号
  • %n :数据库会话的用户名,在数据库会话期间,这个值可能会因为命令SET SESSION AUTHORIZATION的结果而改变
  • %/  :当前数据库名称
  • %# :如果是超级用户则显示#,其他用户显示>,这个值可能会因为命令SET SESSION AUTHORIZATION的结果而改变
  • %p :当前数据库连接的后台进程号
  • %R:在PROMPT1中通常显示"=",如果进程被断开则显示!

 

postgres=# \echo :PROMPT1
%/%R%#

  postgres=# \set PROMPT1 '%/@%M:%>%R%#'
  postgres@[local]:5432=#

同样可以编辑~/.psqlrc

vim ~/.psqlrc
 \set PROMPT1 '%/@%M:%>%R%#'

 

 

你可能感兴趣的:(postgresql学习笔记--基础篇 -psql工具)