Следите за новостями GitVerse в нашем телеграм-канале

db_verifier

Форк
0
Форк от sdblist/db_verifier

месяц назад
3 месяца назад
2 месяца назад
месяц назад
2 месяца назад
2 месяца назад
2 месяца назад
README.md

db_verifier

PostgreSQL database verifier.

The script to check the database structure for errors or non-recommended practices.

The script consists of a set of checks that access the system catalog tables and do not require access to data in user tables.

The current version is applicable to PostgreSQL 12 and later. Tested in versions PostgreSQL 15.8.

Project structure

  • db_verifier.sql
    - script, checks and displays a list of errors/warnings/recommendations with comments
  • tests
    - directory with DDL/DML scripts that are used to debug
    db_verifier.sql
    and demonstrate errors

Check list

codeparent_codenameleveldefault statedescription
c1001constraint not validatedwarningenableConstraint was not validated for all data.
fk1001fk uses mismatched typeserrorenableForeign key uses columns with mismatched types.
fk1002fk uses nullable columnswarningdisableForeign key uses nullable columns.
fk1007not involved in foreign keysnoticedisableRelation is not involved in foreign keys.
fk1010similar FKwarningenableFK are very similar.
fk1011fk1010FK have common attributeswarningenableThere are multiple FK between relations, FK have common attributes.
i1001similar indexeswarningenableIndexes are very similar.
i1002index has bad signserrorenableIndex has bad signs.
i1003similar indexes unique and not uniquewarningenableUnique and not unique indexes are very similar.
i1005similar indexes (roughly)noticedisableIndexes are roughly similar.
i1010b-tree index for array columnnoticeenableB-tree index for array column.
n1001confusion in name of schemaswarningenableThere may be confusion in the name of the schemas. The names are dangerously similar.
n1002unwanted characters in schema namenoticeenableSchema name contains unwanted characters such as dots, spaces, etc.
n1005confusion in name of relation attributeswarningenableThere may be confusion in the name of the relation attributes. The names are dangerously similar.
n1006unwanted characters in attribute namenoticeenableAttribute name contains unwanted characters such as dots, spaces, etc.
n1010confusion in name of relationswarningenableThere may be confusion in the name of the relations in the same schema. The names are dangerously similar.
n1011unwanted characters in relation namenoticeenableRelation name contains unwanted characters such as dots, spaces, etc.
n1015confusion in name of indexeswarningenableThere may be confusion in the name of the relation indexes. The names are dangerously similar.
n1016unwanted characters in index namenoticeenableIndex name contains unwanted characters such as dots, spaces, etc.
n1020confusion in name of sequenceswarningenableThere may be confusion in the name of the sequences in the same schema. The names are dangerously similar.
n1021unwanted characters in sequence namenoticeenableSequence name contains unwanted characters such as dots, spaces, etc.
no1001no unique keyerrorenableRelation has no unique key.
no1002no1001no primary key constrainterrorenableRelation has no primary key constraint.
r1001unlogged tablewarningenableUnlogged table is not replicated, truncated after crash.
r1002relation without columnswarningenableRelation without columns.
s1001unlogged sequencewarningenableUnlogged sequence is not replicated, reset after crash.
s1010less 5% unused sequence valuescriticalenableThe sequence has less than 5% unused values left.
s1011s1010less 10% unused sequence valueserrorenableThe sequence has less than 10% unused values left.
s1012s1011less 20% unused sequence valueswarningenableThe sequence has less than 20% unused values left.
sm0001invalid attribute type for uuidnoticedisableThe field probably contains data in uuid/guid format, but a different data type is used.

Usage example

An example of using a script to check database metadata using a docker container with PostgreSQL 15.

Let's dump the database schema in sql format using

pg_dump
, specifying the necessary parameters for the connection.

pg_dump \
--host=database_host \
--port=database_port \
--username=user_name \
--dbname=database_name \
--schema-only \
--format=plain \
--file=database_schema.sql

Let's launch a container with PostgreSQL 15, port

5444
of the local interface will be forwarded to the container.

docker container run \
-p 127.0.0.1:5444:5432 \
--name db_verifier \
--env POSTGRES_USER=user_name \
--env POSTGRES_PASSWORD=user_password \
--env POSTGRES_DB=db_verifier \
--detach postgres:15-alpine

Let's connect to the container on port

5444
of the local interface using the
psql
console client.

psql \
--host=localhost \
--port=5444 \
--username=user_name \
--dbname=db_verifier

Let's set up data output in the

psql
and execute the
db_verifier.sql
.

db_verifier=# \pset format wrapped
Output format is wrapped.
db_verifier=# \pset columns 0
Target width is unset.
db_verifier=# \i db_verifier.sql
object_id | object_name | object_type | check_code | check_level | check_name | check_result_json
-----------+----------------------+-------------+------------+-------------+--------------------------+------------------------------------------
16456 | fk1001_2_fk_fk1001_2 | constraint | fk1001 | error | fk uses mismatched types | {"object_id" : "16456", "object_name" : .
| | | | | |."fk1001_2_fk_fk1001_2", "object_type" : .
| | | | | |."constraint", "relation_name" : "public..
| | | | | |.fk1001_2_fk", "relation_att_names" : ["f.
| | | | | |.k1001_2_id"], "foreign_relation_name" : .
| | | | | |."public.fk1001_2", "foreign_relation_att.
| | | | | |._names" : ["id"], "check" : {"check_code.
| | | | | |.":"fk1001","parent_check_code":null,"che.
| | | | | |.ck_name":"fk uses mismatched types","che.
| | | | | |.ck_level":"error","check_source_name":"s.
| | | | | |.ystem catalog","description_language_cod.
| | | | | |.e":null,"description_value":"Foreign key.
| | | | | |. uses columns with mismatched types."}}

Stop and remove the container.

docker stop db_verifier
docker container remove db_verifier

Examples of adaptation and integration into CI

Switching localization of messages using bash command

Changing the message localization setting to

en
, attribute
conf_language_code
.

sed -i "/AS conf_language_code,/c\'en' AS conf_language_code," db_verifier.sql

Explicitly enable/disable checks using bash command

Explicitly disabling the

i1001
check (similar indexes), the
enable_check_i1001
attribute.

sed -i "s/AS enable_check_i1001/AND false AS enable_check_i1001/" db_verifier.sql
-- before
true AS enable_check_i1001 -- [warning] similar indexes
-- after
true AND false AS enable_check_i1001 -- [warning] similar indexes

Explicitly enabling the

fk1007
check (not involved in foreign keys), attribute
enable_check_fk1007
.

sed -i "s/AS enable_check_fk1007/OR true AS enable_check_fk1007/" db_verifier.sql
-- before
false AS enable_check_fk1007, -- [notice] not involved in foreign keys
-- after
false OR true AS enable_check_fk1007, -- [notice] not involved in foreign keys

Filtering scan results

Filtering scan results is necessary to exclude false positives or to implement exclusion functionality known errors (baseline, error suppression). To do this, you can add a

WHERE
condition to the script at the stage of filtering the test results, the point for setting such conditions are specified in the comment line
>>> WHERE
.

Example of conditions for filtering results (suppressing some errors).

cat examples/where.sql
WHERE
NOT (check_code = 'fk1007' AND object_name = 'public.schema_migrations')
sed -i "/>>> WHERE/ r examples/where.sql" db_verifier.sql

Cumulative score (single value)

An implementation option for obtaining an aggregated score. Let's associate each result line with a numeric value based on

check_level
, example in the file
examples/cumulative_score.sql
.

cat examples/cumulative_score.sql
SELECT
COALESCE(SUM(cumulative_score_value), 0) AS cumulative_score
FROM (
VALUES
('critical', 55),
('error', 25),
('warning', 12),
('notice', 3)
) AS t(check_level, cumulative_score_value)
INNER JOIN (
-- >>> db_verifier
) AS r ON t.check_level = r.check_level
;

Let's combine the scripts, the result in

examples/cumulative_score.sql
.

sed -i "/^;$/d" db_verifier.sql
sed -i "/>>> db_verifier/ r db_verifier.sql" ./examples/cumulative_score.sql

Description of the test results table

column namedescription
object_idid (oid) of the object in the corresponding system table
object_namename of the object, in some cases with a schema
object_typetype of object being checked (relation, constraint, index, sequence)
check_codecheck code (see table above)
check_levellevel (see table above)
check_namecheck name (see table above)
check_result_jsondetailed test results in json format

Alternative description

Описание

Инструмент для статического анализа структуры базы данных на наличие ошибок или нерекомендуемых практик

Языки

Shell

Сообщить о нарушении

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.