Preface
Generally, in PostgreSQL, because the table often needs to UPDATE and DELETE, the table will generate fragmented space. In PostgreSQL, using VACUUM only marks the deleted space as unused for the VACUUM table, so that the space can be reused in the future, but the occupied space cannot be returned to the operating system immediately, so VACUUM FULL is required to release the space , And immediately return the space to the operating system.
Implementation script
Record collection table creation
CREATE TABLE IF NOT EXISTS tab_vacuum_record
(sqltext text);
Collection requires VACUUM table function
CREATE OR REPLACE FUNCTION f_vacuum_tables()
RETURNS void AS
$FUNCTION$
DECLARE
v_tablename text;
v_dead_cond bigint;
v_sql text;
cur_tablename REFCURSOR;
v_vacuum_record text;
BEGIN
v_vacuum_record := 'tab_vacuum_record';
OPEN cur_tablename FOR SELECT tablename FROM pg_tables WHERE tablename !~ '^pg|^sql';
LOOP
FETCH cur_tablename INTO v_tablename;
SELECT n_dead_tup INTO v_dead_cond FROM pg_stat_user_tables WHERE relname = v_tablename;
IF v_dead_cond > 0 THEN
v_sql := 'INSERT INTO ' || v_vacuum_record || ' VALUES(' || chr(39) ||'VACUUM FULL ' || v_tablename ||';'|| chr(39) ||')';
EXECUTE v_sql;
END IF;
EXIT WHEN NOT FOUND;
END LOOP;
CLOSE cur_tablename;
END;
$FUNCTION$
LANGUAGE PLPGSQL;
Shell script
#!/bin/bash
#获取环境变量
CURRDIR=$(cd "$(dirname $0)";pwd)
TOPDIR=$(cd $CURRDIR/..;pwd)
CONFIG=$TOPDIR/conf/host.ini
CT_FILE=${TOPDIR}/sql/CREATE_VACCUM_TABLE_RECORD.sql
CT_FUNCTION=${TOPDIR}/sql/CHECK_NEEDS_VACUUM_TABLE_FUNCTION.sql
source $CONFIG
CONNINFO="psql -U $USER -d $DBNAME -h $HOSTADDR -p $PORT"
function check_status()
{
echo "检查数据库服务器状态是否正常 !"
stat=`$CONNINFO -Aqt -c 'SELECT 1'`
if [ "${stat}" == "1" ];then
echo "服务器连接正常"
else
echo "服务器连接异常,退出"
exit -1;
fi
}
function create_table()
{
echo "创建收集需要vacuum的表"
$CONNINFO -f $CT_FILE
}
function create_function()
{
echo "创建收集需要 vacuum 表的函数"
$CONNINFO -f $CT_FUNCTION
}
check_status
create_table
create_function
execution way
postgres=# SELECT * FROM f_vacuum_tables();
f_vacuum_tables
-----------------
(1 row)
--创建测试表
postgres=# CREATE TABLE tab_test(id int);
--插入数据
postgres=# INSERT INTO tab_test SELECT id FROM generate_series(1,100000) as id;
INSERT 0 100000
--删除数据
postgres=# DELETE FROM tab_Test WHERE id <= 10000;
DELETE 10002
postgres=# SELECT * FROM tab_vacuum_record ;
sqltext
-----------------------
VACUUM FULL tab_test;
(1 row)
The script can also be modified as needed, see github https://github.com/OpenSourceLinux/VACUUM-FOR-PostgreSQL for details