├── .circleci
├── config.yml
├── custom.sql
├── ddl_create_index.sql
├── ddl_drop_index.sql
├── run.yml
├── sample.log
├── sample.replay
├── test.dump.bz2
├── test.dump.gz
└── test.dump.sql
├── .gitignore
├── LICENSE
├── README.md
├── docker
├── Dockerfile
├── README.md
├── postgresql_10_tweak.conf
├── postgresql_11_tweak.conf
├── postgresql_12_tweak.conf
├── postgresql_9.6_tweak.conf
├── rebuild_push_images.sh
└── tsearch_data
│ ├── russian.affix
│ └── russian.dict
├── help
├── help.sh
├── nancy.md
├── nancy_prepare_workload.md
└── nancy_run.md
├── nancy
├── nancy_describe.sh
├── nancy_prepare_workload.sh
├── nancy_run.sh
├── pg_badger_parsing.sh
├── tests
├── nancy_cli_run.sh
├── nancy_cli_run_no_optons.sh
├── nancy_cli_unknown.sh
├── nancy_prepare_workload.sh
├── nancy_run_abnormal.sh
├── nancy_run_aws_no_keys.sh
├── nancy_run_aws_pgdata_dir.sh
├── nancy_run_aws_zfs_i3.sh
├── nancy_run_before_init_code.sh
├── nancy_run_ebs_disk_size.sh
├── nancy_run_ebs_disk_size_incorrect.sh
├── nancy_run_invalid_aws_option.sh
├── nancy_run_invalid_option.sh
├── nancy_run_invalid_spot_duration.sh
├── nancy_run_localhost_connection_str.sh
├── nancy_run_localhost_less_output.sh
├── nancy_run_localhost_norm_output.sh
├── nancy_run_localhost_pgbench.sh
├── nancy_run_localhost_pgdata_dir.sh
├── nancy_run_localhost_real_workload.sh
├── nancy_run_localhost_series.sh
├── nancy_run_localhost_simple_dump.sh
├── nancy_run_localhost_simple_dump_with_index.sh
├── nancy_run_localhost_simple_gz_dump.sh
├── nancy_run_localhost_simple_sql_dump.sh
├── nancy_run_localhost_wildcards.sh
├── nancy_run_options_ddl_do+_undo-.sh
├── nancy_run_options_ddl_do-_undo+.sh
├── nancy_run_options_multi_workloads.sh
├── nancy_run_options_no_dump_snapshot.sh
├── nancy_run_options_no_instance_type.sh
├── nancy_run_too_many_objects.sh
└── nancy_run_too_many_workloads.sh
└── tools
├── meminfo.sh
├── parse_yaml.sh
└── unittest
└── parse_yml.sh
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | working_directory: ~/nancy
5 | docker:
6 | - image: ubuntu:16.04
7 | steps:
8 | - run:
9 | name: Install software
10 | command: |
11 | apt-get update && apt-get install -y sudo wget jq gawk pgreplay bc \
12 | && wget get.docker.com -q -S -O - | sudo sh
13 | - checkout
14 | - setup_remote_docker
15 | - run:
16 | name: Install Docker client
17 | command: |
18 | set -x
19 | VER="17.03.0-ce"
20 | curl -L -o /tmp/docker-$VER.tgz https://download.docker.com/linux/static/stable/x86_64/docker-$VER.tgz
21 | tar -xz -C /tmp -f /tmp/docker-$VER.tgz
22 | mv /tmp/docker/* /usr/bin
23 | - run:
24 | name: Tests
25 | command: |
26 | errcount=0
27 | printTail=" "
28 | for f in tests/*.sh; do
29 | printf "$f${printTail:0:-${#f}}"
30 | bash "$f" -H
31 | status=$?
32 | if [ "$status" -ne 0 ]; then
33 | errcount="$(($errcount+1))"
34 | fi
35 | done
36 | if [ "$errcount" -ne 0 ]; then
37 | >&2 echo "Oh no! $errcount tests failed"
38 | exit 1
39 | fi
40 | for f in tools/unittest/*.sh; do
41 | printf "$f${printTail:0:-${#f}}"
42 | bash "$f" -H
43 | status=$?
44 | if [ "$status" -ne 0 ]; then
45 | errcount="$(($errcount+1))"
46 | fi
47 | done
48 | if [ "$errcount" -ne 0 ]; then
49 | >&2 echo "Oh no! $errcount tests failed"
50 | exit 1
51 | fi
52 |
53 |
--------------------------------------------------------------------------------
/.circleci/custom.sql:
--------------------------------------------------------------------------------
1 | select count(1) from t1 where id between 555 and 777;
2 |
3 | select count(1) from t1 where val between 0.555 and 0.777;
4 |
--------------------------------------------------------------------------------
/.circleci/ddl_create_index.sql:
--------------------------------------------------------------------------------
1 | create index i_speedup on t1 using btree(val);
2 |
--------------------------------------------------------------------------------
/.circleci/ddl_drop_index.sql:
--------------------------------------------------------------------------------
1 | drop index i_speedup;
2 |
--------------------------------------------------------------------------------
/.circleci/run.yml:
--------------------------------------------------------------------------------
1 | run:
2 | 0:
3 | delta_ddl_do: select now(); select now();
4 | delta_ddl_undo: select now();
5 | # delta_config: max_wal_size = 2048MB
6 | 1:
7 | # delta_ddl_do: select now();
8 | # delta_ddl_undo: select now();
9 | delta_config: max_wal_size = 4092MB
10 | 2:
11 | # delta_ddl_do: select now();
12 | # delta_ddl_undo: select now();
13 | delta_config: max_wal_size = 4092MB
14 |
--------------------------------------------------------------------------------
/.circleci/sample.log:
--------------------------------------------------------------------------------
1 | 2018-07-12 22:47:06.085 UTC,"testci","testci",2460,"127.0.0.1:53862",5b47da68.99c,6,"idle",2018-07-12 22:47:04 UTC,,0,LOG,00000,"disconnection: session time: 0:00:01.185 user=testci database=testci host=127.0.0.1 port=53862",,,,,,,,,""
2 | 2018-07-12 22:47:06.302 UTC,,,2473,"127.0.0.1:53865",5b47da6a.9a9,1,"",2018-07-12 22:47:06 UTC,,0,LOG,00000,"connection received: host=127.0.0.1 port=53865",,,,,,,,,""
3 | 2018-07-12 22:47:07.394 UTC,"testci","testci",28569,"127.0.0.1:53615",5b47d84e.6f99,15,"idle",2018-07-12 22:38:06 UTC,,0,LOG,00000,"disconnection: session time: 0:09:00.762 user=testci database=testci host=127.0.0.1 port=53615",,,,,,,,,""
4 | 2018-07-12 22:47:07.838 UTC,"testci","testci",2473,"127.0.0.1:53865",5b47da6a.9a9,4,"SELECT",2018-07-12 22:47:06 UTC,12/0,0,LOG,00000,"duration: 14.564 ms statement: select count(*)
5 | from ""hello_world"" as t
6 | order by t.id desc limit 26",,,,,,,,,""
7 | 2018-07-12 22:47:08.053 UTC,"testci","testci",2473,"127.0.0.1:53865",5b47da6a.9a9,5,"SELECT",2018-07-12 22:47:06 UTC,12/0,0,LOG,00000,"duration: 43.544 ms statement: SELECT * FROM ""hello_world"" ""t"" WHERE i > 0 ORDER BY random()",,,,,,,,,""
8 | 2018-07-12 22:47:08.547 UTC,"testci","testci",2473,"127.0.0.1:53865",5b47da6a.9a9,6,"idle",2018-07-12 22:47:06 UTC,,0,LOG,00000,"disconnection: session time: 0:00:02.245 user=testci database=testci host=127.0.0.1 port=53865",,,,,,,,,""
9 | 2018-07-12 22:47:19.218 UTC,,,2642,"127.0.0.1:54013",5b47da77.a52,1,"",2018-07-12 22:47:19 UTC,,0,LOG,00000,"connection received: host=127.0.0.1 port=54013",,,,,,,,,""
10 | 2018-07-12 22:47:19.218 UTC,,,2643,"127.0.0.1:54014",5b47da77.a53,1,"",2018-07-12 22:47:19 UTC,,0,LOG,00000,"connection received: host=127.0.0.1 port=54014",,,,,,,,,""
11 | 2018-07-12 22:47:19.218 UTC,,,2644,"127.0.0.1:54015",5b47da77.a54,1,"",2018-07-12 22:47:19 UTC,,0,LOG,00000,"connection received: host=127.0.0.1 port=54015",,,,,,,,,""
12 | 2018-07-12 22:47:19.226 UTC,"testci","testci",2644,"127.0.0.1:54015",5b47da77.a54,2,"authentication",2018-07-12 22:47:19 UTC,11/77223,0,LOG,00000,"connection authorized: user=testci database=testci SSL enabled (protocol=TLSv1.2, cipher=ECDHE-RSA-AES256-GCM-SHA384, compression=off)",,,,,,,,,""
13 | 2018-07-12 22:47:19.227 UTC,"testci","testci",2642,"127.0.0.1:54013",5b47da77.a52,2,"authentication",2018-07-12 22:47:19 UTC,12/323914,0,LOG,00000,"connection authorized: user=testci database=testci SSL enabled (protocol=TLSv1.2, cipher=ECDHE-RSA-AES256-GCM-SHA384, compression=off)",,,,,,,,,""
14 | 2018-07-12 22:47:19.227 UTC,"testci","testci",2643,"127.0.0.1:54014",5b47da77.a53,2,"authentication",2018-07-12 22:47:19 UTC,13/6385,0,LOG,00000,"connection authorized: user=testci database=testci SSL enabled (protocol=TLSv1.2, cipher=ECDHE-RSA-AES256-GCM-SHA384, compression=off)",,,,,,,,,""
15 | 2018-07-12 22:47:25.491 UTC,"testci","testci",2687,"127.0.0.1:54016",5b47da7a.a7f,3,"idle",2018-07-12 22:47:22 UTC,,0,LOG,00000,"disconnection: session time: 0:00:02.680 user=testci database=testci host=127.0.0.1 port=54016",,,,,,,,,""
16 |
--------------------------------------------------------------------------------
/.circleci/sample.replay:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postgres-ai/nancy/4b0932165043ab4b4646b7e3f2d1b9a53808ac8f/.circleci/sample.replay
--------------------------------------------------------------------------------
/.circleci/test.dump.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postgres-ai/nancy/4b0932165043ab4b4646b7e3f2d1b9a53808ac8f/.circleci/test.dump.bz2
--------------------------------------------------------------------------------
/.circleci/test.dump.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postgres-ai/nancy/4b0932165043ab4b4646b7e3f2d1b9a53808ac8f/.circleci/test.dump.gz
--------------------------------------------------------------------------------
/.circleci/test.dump.sql:
--------------------------------------------------------------------------------
1 | create table t1 as
2 | select i as id, random() val
3 | from generate_series(1, 1000000) _(i);
4 |
5 | alter table t1 add primary key (id);
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .circleci/tmp
2 | docker/tmp
3 | *.gz
4 | *.json
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, Nikolay Samokhvalov
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](github.com/postgres-ai/nancy)
4 |
5 |
6 |
7 | [](https://circleci.com/gh/postgres-ai/nancy)
8 |
9 | :warning: Nancy CLI project is on hold now. See details: https://gitlab.com/postgres-ai/nancy/-/issues/228
10 |
11 | # About
12 |
13 |
14 | Nancy helps to conduct automated database experiments.
15 |
16 | The Nancy Command Line Interface is a unified way to manage automated
17 | database experiments either in clouds or on-premise.
18 |
19 | ### What is a Database Experiment?
20 |
21 | Database experiment is a set of actions performed to test
22 | * (a) specified SQL queries ("workload")
23 | * (b) on specified machine / OS / Postgres version ("environment")
24 | * (c) against specified database ("object")
25 | * (d) with an optional change – some DDL or config change ("target" or "delta").
26 |
27 | Two main goals for any database experiment:
28 | * (1) validation – check that the specified workload is valid,
29 | * (2) benchmark – perform deep SQL query analysis.
30 |
31 | Database experiments are needed when you:
32 | - add or remove indexes;
33 | - for a new DB schema change, want to validate it and estimate migration time;
34 | - want to verify some query optimization ideas;
35 | - tune database configuration parameters;
36 | - do capacity planning and want to stress-test your DB in some environment;
37 | - plan to upgrade your DBMS to a new major version;
38 | - want to train ML model related to DB optimization.
39 |
40 | # Currently Supported Features
41 |
42 | * Works anywhere where Docker can run (checked: Linux Ubuntu/Debian, macOS)
43 | * Experiments are conducted in a Docker container with extended Postgres setup
44 | * Supported Postgres versions: 12 (default), 11, 10, 9.6
45 | * Postgres config specified via options, may be partial
46 | * Supported locations for experimental runs:
47 | * Any machine with Docker installed
48 | * AWS EC2:
49 | * Run on AWS EC2 Spot Instances (using Docker Machine)
50 | * Allow to specify EC2 instance type
51 | * Auto-detect and use current lowest EC2 Spot Instance prices
52 | * Support i3 instances (with NVMe SSD drives)
53 | * Support arbitrary-size EBS volumes
54 | * Support local or remote (S3) files – config, dump, etc
55 | * The object (database) can be specified in various ways:
56 | * Plain text
57 | * Synthetic database generated by [pgbench](https://www.postgresql.org/docs/current/static/pgbench.html)
58 | * Dump file (.sql, .gz, .bz2)
59 | * What to test (a.k.a. "target" or "delta"):
60 | * Test Postgres parameters change
61 | * Test DDL change (specified as "do" and "undo" SQL to return state)
62 | * Supported types of workload:
63 | * Any custom SQL
64 | * Synthetic workload generated by [pgbench](https://www.postgresql.org/docs/current/static/pgbench.html)
65 | * "Real workload" based on Postgres logs (using [pgreplay](https://github.com/laurenz/pgreplay))
66 | * For "real workload", allow replaying it with increased speed
67 | * Allow to keep container alive for specified time after all steps are done
68 | * Collected artifacts:
69 | * `pg_stat_statements` snapshot
70 | * `pg_stat_database`, ...
71 | * Workload SQL logs
72 | * Deep SQL query analysis report
73 |
74 | # Requirements
75 |
76 | 1) To use Nancy CLI you need Linux or MacOS with installed Docker.
77 |
78 | 2) To run on AWS EC2 instances, you also need:
79 | * AWS CLI https://aws.amazon.com/en/cli/
80 | * Docker Machine https://docs.docker.com/machine/
81 | * jq https://stedolan.github.io/jq/
82 |
83 |
84 | # Installation
85 |
86 | In the minimal configuration, only a few steps are needed:
87 |
88 | NOTICE: The [Additional notes](#additional-notes) section contains
89 | instructions useful in case of docker-related errors during `nancy run` calls.
90 | Alternatively, see Docker's official [post-installation instructions for Linux](https://docs.docker.com/install/linux/linux-postinstall/).
91 |
92 | 1) Install Docker
93 |
94 | Ubuntu/Debian:
95 | ```shell
96 | sudo apt-get -y install docker
97 | sudo systemctl enable docker
98 | sudo systemctl start docker
99 | ```
100 |
101 | RHEL7:
102 | ```shell
103 | yum -y install docker
104 | systemctl enable docker
105 | systemctl start docker
106 | ```
107 |
108 | MacOS (assuming that [Homebrew](https://brew.sh/) is installed):
109 | ```shell
110 | brew install docker
111 | ```
112 | See also: https://docs.docker.com/docker-for-mac/install/
113 |
114 | 2) Clone this repo and adjust `$PATH`:
115 | ```shell
116 | git clone https://gitlab.com/postgres.ai/nancy.git
117 | echo "export PATH=\$PATH:"$(pwd)"/nancy" >> ~/.bashrc
118 | source ~/.bashrc
119 | ```
120 |
121 | 3) Install jq
122 | - Ubuntu/Debian: `sudo apt-get -y install jq`
123 | - CentOS/RHEL: `sudo yum install jq`
124 | - MacOS: `brew install jq`
125 |
126 | Additionally, to allow use of AWS EC2 instances:
127 |
128 | 4) Install AWS CLI https://docs.aws.amazon.com/cli/latest/userguide/installing.html
129 |
130 | 5) Install Docker Machine tools https://docs.docker.com/machine/install-machine/
131 |
132 | # Getting started
133 |
134 | Start with these commands:
135 | ```shell
136 | nancy help
137 | nancy run help
138 | ```
139 |
140 | # "Hello World!"
141 |
142 | Locally, on any Linux or macOS machine:
143 | ```shell
144 | echo "create table hello_world as select i from generate_series(1, (10^6)::int) _(i);" \
145 | | bzip2 > ./sample.dump.bz2
146 |
147 | # "Clean run": w/o index
148 | # (seqscan is expected, total time ~150ms, depending on resources)
149 | nancy run \
150 | --db-dump file://$(pwd)/sample.dump.bz2 \
151 | --workload-custom-sql "select i from hello_world where i between 10 and 20;"
152 |
153 | # Now check how a regular btree index affects performance
154 | # (expected total time: ~0.05ms)
155 | nancy run \
156 | --db-dump file://$(pwd)/sample.dump.bz2 \
157 | --workload-custom-sql "select i from hello_world where i between 10 and 20;" \
158 | --delta-sql-do "create index i_hello_world_i on hello_world(i);" \
159 | --delta-sql-undo "drop index i_hello_world_i;"
160 | ```
161 |
162 | AWS EC2:
163 | ```shell
164 | nancy run \
165 | --run-on aws \
166 | --aws-ec2-type "i3.large" \
167 | --aws-keypair-name awskey \
168 | --aws-ssh-key-path file://$(echo ~)/.ssh/awskey.pem \
169 | --db-dump "create table hello_world as select i from generate_series(1, (10^6)::int) _(i);" \
170 | --workload-custom-sql "select i from hello_world where i between 10 and 20;"
171 | ```
172 |
173 | # Additional notes
174 |
175 | On Linux, if you experience issues with running (locally) `nancy run` inside `screen` or
176 | `tmux`, double-check that Docker is running and add your user to the `docker`
177 | group, as described below. See also: https://docs.docker.com/install/linux/linux-postinstall/.
178 |
179 | Ubuntu/Debian:
180 | ```shell
181 | # Ubuntu/Debian
182 | sudo usermod -aG docker ${USER}
183 | newgrp docker
184 | ```
185 |
186 | CentOS/RHEL:
187 | ```shell
188 | sudo usermod -aG dockerroot ${USER}
189 | newgrp dockerroot
190 | ```
191 |
192 | On MacOS, it is recommended to specify `--tmp-path` explicitly, similar to this:
193 | ```
194 | mkdir ./tmp
195 | nancy run ... --tmp-path "$(pwd)/tmp"
196 | ```
197 |
--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:18.04
2 |
3 | ARG PG_SERVER_VERSION
4 |
5 | ENV PG_SERVER_VERSION=${PG_SERVER_VERSION:-12} \
6 | DEBIAN_FRONTEND=noninteractive
7 |
8 | # add custom FTS dictionaries
9 | ADD ./tsearch_data /usr/share/postgresql/${PG_SERVER_VERSION}/tsearch_data
10 |
11 | # logging ON; memory setting – for 2CPU/4096MB/SSD
12 | ADD ./postgresql_${PG_SERVER_VERSION}_tweak.conf /postgresql.tweak.conf
13 |
14 | # set up apt, add Postgres repo
15 | RUN apt-get update
16 | RUN apt-get install -y wget ca-certificates gnupg2
17 | RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
18 | RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
19 | RUN apt-get update
20 | RUN apt-get install -y apt-utils
21 |
22 | # install additional utilites
23 | RUN apt-get install -y sudo git jq libjson-xs-perl vim
24 | RUN apt-get install -y sysbench s3cmd sudo bzip2 software-properties-common
25 | RUN apt-get install -y sysstat iotop moreutils psmisc
26 |
27 | # install Postgres and postgres-specific packages
28 | RUN apt-get install -y postgresql-${PG_SERVER_VERSION}
29 | RUN apt-get install -y postgresql-contrib-${PG_SERVER_VERSION}
30 | RUN apt-get install -y postgresql-server-dev-${PG_SERVER_VERSION}
31 | #RUN if [ "${PG_SERVER_VERSION}" != "12" ]; then apt-get install -y postgresql-${PG_SERVER_VERSION}-dbg; fi
32 | RUN apt-get install -y postgresql-${PG_SERVER_VERSION}-pg-stat-kcache
33 | RUN apt-get install -y postgresql-client-12
34 | RUN if [ "${PG_SERVER_VERSION}" == "12" ]; then apt-get install -y postgresql-plpython3-${PG_SERVER_VERSION}; fi
35 | RUN if [ "${PG_SERVER_VERSION}" != "12" ]; then apt-get install -y postgresql-plpython-${PG_SERVER_VERSION}; fi
36 |
37 | RUN apt-get install -y pgreplay
38 | RUN apt-get update && apt-get install -y pspg
39 | RUN git clone https://github.com/NikolayS/postgres_dba.git /root/postgres_dba
40 | RUN apt-get install -y postgresql-${PG_SERVER_VERSION}-repack
41 | RUN git clone https://github.com/darold/pgbadger.git /root/pgbadger && cd /root/pgbadger && git checkout "tags/v11.1"
42 |
43 | # install FlameGraph and generic perf
44 | RUN git clone https://github.com/brendangregg/FlameGraph /root/FlameGraph
45 | RUN apt-get install -y linux-tools-generic
46 | # replace incorrect Debian perf wrapper with a symbolic link
47 | RUN path=$(ls /usr/lib/linux-tools/*generic/perf | head -n 1) && ln -s -f "$path" /usr/bin/perf
48 |
49 | # configure psql, configure Postgres
50 | RUN echo "\\set dba '\\\\\\\\i /root/postgres_dba/start.psql'" >> ~/.psqlrc
51 | RUN echo "\\setenv PAGER 'pspg -bX --no-mouse'" >> ~/.psqlrc
52 | RUN echo "local all all trust" > /etc/postgresql/${PG_SERVER_VERSION}/main/pg_hba.conf
53 | RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/${PG_SERVER_VERSION}/main/pg_hba.conf
54 | RUN echo "listen_addresses='*'" >> /etc/postgresql/${PG_SERVER_VERSION}/main/postgresql.conf
55 | RUN echo "log_filename='postgresql-${PG_SERVER_VERSION}-main.log'" >> /etc/postgresql/${PG_SERVER_VERSION}/main/postgresql.conf
56 |
57 | # prepare database 'test' with 'testuser'
58 | RUN /etc/init.d/postgresql start && psql -U postgres -c "create database test" \
59 | && psql -U postgres -d test -c "CREATE EXTENSION pg_repack" \
60 | && psql -U postgres -c "CREATE ROLE testuser LOGIN password 'testuser' superuser" && /etc/init.d/postgresql stop
61 |
62 | # apply 'tweaked' config
63 | RUN cat /postgresql.tweak.conf >> /etc/postgresql/${PG_SERVER_VERSION}/main/postgresql.conf
64 |
65 | # prepare Postgres start script
66 | RUN echo "#!/bin/bash" > /pg_start.sh && chmod a+x /pg_start.sh
67 | RUN printf "sudo -u postgres /usr/lib/postgresql/${PG_SERVER_VERSION}/bin/postgres -D /var/lib/postgresql/${PG_SERVER_VERSION}/main -c config_file=/etc/postgresql/${PG_SERVER_VERSION}/main/postgresql.conf \n" >> /pg_start.sh
68 | # infinite sleep to allow restarting Postgres
69 | RUN echo "/bin/bash -c \"trap : TERM INT; sleep infinity & wait\"" >> /pg_start.sh
70 |
71 | # generate english locale for iostat + iostat-tool
72 | RUN locale-gen en_US.UTF-8
73 |
74 | # install pip and iostat-tool
75 | RUN apt-get install -y curl
76 | RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
77 | RUN python3 get-pip.py
78 | RUN pip3 install iostat-tool
79 |
80 | # install zfs utils
81 | RUN apt-get install -y zfsutils-linux
82 |
83 | # reduce images size
84 | RUN rm -rf /tmp/*
85 | RUN apt-get purge -y --auto-remove
86 | RUN apt-get clean -y autoclean
87 | RUN rm -rf /var/lib/apt/lists/*
88 |
89 | EXPOSE 5432
90 |
91 | #VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
92 |
93 | CMD ["/pg_start.sh"]
94 |
--------------------------------------------------------------------------------
/docker/README.md:
--------------------------------------------------------------------------------
1 | How to build/rebuild:
2 |
3 | Rebuild and push images for all postgres versions:
4 | ```bash
5 | ./rebuild_push_images.sh
6 | ```
7 |
8 | Or do it manually:
9 | ```bash
10 | export NANCY_DOCKER_PG_VERSION=9.6
11 |
12 | docker build \
13 | --build-arg "PG_SERVER_VERSION=${NANCY_DOCKER_PG_VERSION}" \
14 | -t "postgresmen/postgres-nancy:${NANCY_DOCKER_PG_VERSION}" .
15 |
16 | docker login # you must be registered, go to hub.docker.com
17 |
18 | docker push "postgresmen/postgres-nancy:${NANCY_DOCKER_PG_VERSION}"
19 | ```
20 |
--------------------------------------------------------------------------------
/docker/postgresql_10_tweak.conf:
--------------------------------------------------------------------------------
1 | # IMPORTANT: on faster systems, you need to use your own memory-related settings!
2 | statement_timeout = 0
3 |
4 | log_destination = 'stderr,csvlog'
5 | logging_collector = on
6 | log_directory = '/var/log/postgresql'
7 | # log_filename – to be set dynamically
8 | log_min_messages = notice
9 | log_min_error_statement = notice
10 | log_min_duration_statement = -1 # rely on "auto_explain.log_min_duration = 0", avoid duplicates
11 | log_checkpoints = on
12 | log_connections = on
13 | log_disconnections = on
14 | log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u (%a,%h) '
15 | log_lock_waits = on
16 | log_replication_commands = on
17 | log_temp_files = 0
18 | log_autovacuum_min_duration = 0
19 |
20 | shared_preload_libraries = 'pg_stat_statements,auto_explain,pg_stat_kcache'
21 |
22 | pg_stat_statements.max = 5000
23 | pg_stat_statements.track = all
24 | pg_stat_statements.track_utility = on
25 | pg_stat_statements.save = on
26 |
27 | auto_explain.log_min_duration = 0
28 | auto_explain.log_analyze = on
29 | auto_explain.log_verbose = on
30 | auto_explain.log_buffers = on
31 | auto_explain.log_format = 'json'
32 | auto_explain.log_timing = on
33 | auto_explain.log_triggers = on
34 | auto_explain.log_nested_statements = on
35 |
--------------------------------------------------------------------------------
/docker/postgresql_11_tweak.conf:
--------------------------------------------------------------------------------
1 | # IMPORTANT: on faster systems, you need to use your own memory-related settings!
2 | statement_timeout = 0
3 |
4 | log_destination = 'stderr,csvlog'
5 | logging_collector = on
6 | log_directory = '/var/log/postgresql'
7 | # log_filename – to be set dynamically
8 | log_min_messages = notice
9 | log_min_error_statement = notice
10 | log_min_duration_statement = -1 # rely on "auto_explain.log_min_duration = 0", avoid duplicates
11 | log_checkpoints = on
12 | log_connections = on
13 | log_disconnections = on
14 | log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u (%a,%h) '
15 | log_lock_waits = on
16 | log_replication_commands = on
17 | log_temp_files = 0
18 | log_autovacuum_min_duration = 0
19 |
20 | shared_preload_libraries = 'pg_stat_statements,auto_explain,pg_stat_kcache'
21 |
22 | pg_stat_statements.max = 5000
23 | pg_stat_statements.track = all
24 | pg_stat_statements.track_utility = on
25 | pg_stat_statements.save = on
26 |
27 | auto_explain.log_min_duration = 0
28 | auto_explain.log_analyze = on
29 | auto_explain.log_verbose = on
30 | auto_explain.log_buffers = on
31 | auto_explain.log_format = 'json'
32 | auto_explain.log_timing = on
33 | auto_explain.log_triggers = on
34 | auto_explain.log_nested_statements = on
35 |
--------------------------------------------------------------------------------
/docker/postgresql_12_tweak.conf:
--------------------------------------------------------------------------------
1 | # IMPORTANT: on faster systems, you need to use your own memory-related settings!
2 | statement_timeout = 0
3 |
4 | log_destination = 'stderr,csvlog'
5 | logging_collector = on
6 | log_directory = '/var/log/postgresql'
7 | # log_filename – to be set dynamically
8 | log_min_messages = notice
9 | log_min_error_statement = notice
10 | log_min_duration_statement = -1 # rely on "auto_explain.log_min_duration = 0", avoid duplicates
11 | log_checkpoints = on
12 | log_connections = on
13 | log_disconnections = on
14 | log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u (%a,%h) '
15 | log_lock_waits = on
16 | log_replication_commands = on
17 | log_temp_files = 0
18 | log_autovacuum_min_duration = 0
19 |
20 | shared_preload_libraries = 'pg_stat_statements,auto_explain,pg_stat_kcache'
21 |
22 | pg_stat_statements.max = 5000
23 | pg_stat_statements.track = all
24 | pg_stat_statements.track_utility = on
25 | pg_stat_statements.save = on
26 |
27 | auto_explain.log_min_duration = 0
28 | auto_explain.log_analyze = on
29 | auto_explain.log_verbose = on
30 | auto_explain.log_buffers = on
31 | auto_explain.log_format = 'json'
32 | auto_explain.log_timing = on
33 | auto_explain.log_triggers = on
34 | auto_explain.log_nested_statements = on
35 |
--------------------------------------------------------------------------------
/docker/postgresql_9.6_tweak.conf:
--------------------------------------------------------------------------------
1 | # IMPORTANT: on faster systems, you need to use your own memory-related settings!
2 | statement_timeout = 0
3 |
4 | log_destination = 'stderr,csvlog'
5 | logging_collector = on
6 | log_directory = '/var/log/postgresql'
7 | # log_filename – to be set dynamically
8 | log_min_messages = notice
9 | log_min_error_statement = notice
10 | log_min_duration_statement = -1 # rely on "auto_explain.log_min_duration = 0", avoid duplicates
11 | log_checkpoints = on
12 | log_connections = on
13 | log_disconnections = on
14 | log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u (%a,%h) '
15 | log_lock_waits = on
16 | log_replication_commands = on
17 | log_temp_files = 0
18 | log_autovacuum_min_duration = 0
19 |
20 | shared_preload_libraries = 'pg_stat_statements,auto_explain,pg_stat_kcache'
21 |
22 | pg_stat_statements.max = 5000
23 | pg_stat_statements.track = all
24 | pg_stat_statements.track_utility = on
25 | pg_stat_statements.save = on
26 |
27 | auto_explain.log_min_duration = 0
28 | auto_explain.log_analyze = on
29 | auto_explain.log_verbose = on
30 | auto_explain.log_buffers = on
31 | auto_explain.log_format = 'json'
32 | auto_explain.log_timing = on
33 | auto_explain.log_triggers = on
34 | auto_explain.log_nested_statements = on
35 |
--------------------------------------------------------------------------------
/docker/rebuild_push_images.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Rebuild all images and push to Docker Hub
3 | set -e -u -o pipefail
4 |
5 | VERSIONS="9.6 10 11 12"
6 |
7 | if [[ ! -z ${1+x} ]]; then
8 | VERSIONS="$1"
9 | fi
10 |
11 | # support of CI secrets (login & password for Docker Hub registry)
12 | if [[ ! -z ${DOCKER_LOGIN+x} ]] && [[ ! -z ${DOCKER_PASSWORD+x} ]]; then
13 | docker login --username "${DOCKER_LOGIN}" --password "${DOCKER_PASSWORD}"
14 | else
15 | # you must be loged in with Docker Desktop
16 | docker login
17 | fi
18 |
19 | for version in $VERSIONS; do
20 | docker build \
21 | --build-arg "PG_SERVER_VERSION=${version}" \
22 | -t "postgresmen/postgres-nancy:${version}" .
23 |
24 | docker push "postgresmen/postgres-nancy:${version}"
25 | done
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docker/tsearch_data/russian.affix:
--------------------------------------------------------------------------------
1 | SET KOI8-R
2 |
3 | SFX Z Y 4
4 | SFX Z ый о [лнртв]ый
5 | SFX Z ий о ький
6 | SFX Z ий и [цс]кий
7 | SFX Z ий е щий
8 |
9 | SFX Y Y 435
10 | SFX Y чь жешь чь
11 | SFX Y чь жете чь
12 | SFX Y чь жет чь
13 | SFX Y чь жем чь
14 | SFX Y чь гут чь
15 | SFX Y чь гу чь
16 | SFX Y заться жутся заться
17 | SFX Y заться жусь заться
18 | SFX Y заться жешься заться
19 | SFX Y заться жется заться
20 | SFX Y заться жетесь заться
21 | SFX Y заться жемся заться
22 | SFX Y зать жут зать
23 | SFX Y зать жу зать
24 | SFX Y зать жешь зать
25 | SFX Y зать жете зать
26 | SFX Y зать жет зать
27 | SFX Y зать жем зать
28 | SFX Y ыться удутся быться
29 | SFX Y ыться удусь быться
30 | SFX Y ыться удешься быться
31 | SFX Y ыться удется быться
32 | SFX Y ыться удетесь быться
33 | SFX Y ыться удемся быться
34 | SFX Y ыть удут быть
35 | SFX Y ыть уду быть
36 | SFX Y ыть удешь быть
37 | SFX Y ыть удете быть
38 | SFX Y ыть удет быть
39 | SFX Y ыть удем быть
40 | SFX Y ваться овутся зваться
41 | SFX Y ваться овусь зваться
42 | SFX Y ваться овешься зваться
43 | SFX Y ваться овется зваться
44 | SFX Y ваться оветесь зваться
45 | SFX Y ваться овемся зваться
46 | SFX Y ваться овёшься зваться
47 | SFX Y ваться овётся зваться
48 | SFX Y ваться овётесь зваться
49 | SFX Y ваться овёмся зваться
50 | SFX Y вать овут звать
51 | SFX Y вать ову звать
52 | SFX Y вать овешь звать
53 | SFX Y вать овете звать
54 | SFX Y вать овет звать
55 | SFX Y вать овем звать
56 | SFX Y вать овёшь звать
57 | SFX Y вать овёте звать
58 | SFX Y вать овёт звать
59 | SFX Y вать овём звать
60 | SFX Y жаться гутся жаться
61 | SFX Y жаться гусь жаться
62 | SFX Y жать гут жать
63 | SFX Y жать гу жать
64 | SFX Y ться шься даться
65 | SFX Y ться вутся лыться
66 | SFX Y ться вусь лыться
67 | SFX Y ться вешься лыться
68 | SFX Y ться вется лыться
69 | SFX Y ться ветесь лыться
70 | SFX Y ться вемся лыться
71 | SFX Y ться вёшься лыться
72 | SFX Y ться вётся лыться
73 | SFX Y ться вётесь лыться
74 | SFX Y ться вёмся лыться
75 | SFX Y ться стся даться
76 | SFX Y ться нутся статься
77 | SFX Y ться нусь статься
78 | SFX Y ться нешься статься
79 | SFX Y ться нется статься
80 | SFX Y ться нетесь статься
81 | SFX Y ться немся статься
82 | SFX Y ться мся даться
83 | SFX Y ться дутся даться
84 | SFX Y ться дитесь даться
85 | SFX Y ться димся даться
86 | SFX Y ть шь дать
87 | SFX Y ть вут лыть
88 | SFX Y ть ву лыть
89 | SFX Y ть вешь лыть
90 | SFX Y ть вете лыть
91 | SFX Y ть вет лыть
92 | SFX Y ть вем лыть
93 | SFX Y ть вёшь лыть
94 | SFX Y ть вёте лыть
95 | SFX Y ть вёт лыть
96 | SFX Y ть вём лыть
97 | SFX Y ть ут лезть
98 | SFX Y ть у лезть
99 | SFX Y ть ст дать
100 | SFX Y ть нут стать
101 | SFX Y ть ну стать
102 | SFX Y ть нешь стать
103 | SFX Y ть нете стать
104 | SFX Y ть нет стать
105 | SFX Y ть нем стать
106 | SFX Y ть м дать
107 | SFX Y ть ешь лезть
108 | SFX Y ть ете лезть
109 | SFX Y ть ет лезть
110 | SFX Y ть ем лезть
111 | SFX Y ть дут дать
112 | SFX Y ть дите дать
113 | SFX Y ть дим дать
114 | SFX Y таться чутся [^с]таться
115 | SFX Y таться чусь [^с]таться
116 | SFX Y таться чешься [^с]таться
117 | SFX Y таться чется [^с]таться
118 | SFX Y таться четесь [^с]таться
119 | SFX Y таться чемся [^с]таться
120 | SFX Y тать чут [^с]тать
121 | SFX Y тать чу [^с]тать
122 | SFX Y тать чешь [^с]тать
123 | SFX Y тать чете [^с]тать
124 | SFX Y тать чет [^с]тать
125 | SFX Y тать чем [^с]тать
126 | SFX Y сться дутся асться
127 | SFX Y сться дусь асться
128 | SFX Y сться дешься асться
129 | SFX Y сться дется асться
130 | SFX Y сться детесь асться
131 | SFX Y сться демся асться
132 | SFX Y сться дёшься асться
133 | SFX Y сться дётся асться
134 | SFX Y сться дётесь асться
135 | SFX Y сться дёмся асться
136 | SFX Y сть дут асть
137 | SFX Y сть ду асть
138 | SFX Y сть дешь асть
139 | SFX Y сть дете асть
140 | SFX Y сть дет асть
141 | SFX Y сть дем асть
142 | SFX Y сть дёшь асть
143 | SFX Y сть дёте асть
144 | SFX Y сть дёт асть
145 | SFX Y сть дём асть
146 | SFX Y стись тутся лестись
147 | SFX Y стись тусь лестись
148 | SFX Y стись тешься лестись
149 | SFX Y стись тется лестись
150 | SFX Y стись тетесь лестись
151 | SFX Y стись темся лестись
152 | SFX Y стись тёшься лестись
153 | SFX Y стись тётся лестись
154 | SFX Y стись тётесь лестись
155 | SFX Y стись тёмся лестись
156 | SFX Y стись дутся вестись
157 | SFX Y стись дусь вестись
158 | SFX Y стись дешься вестись
159 | SFX Y стись дется вестись
160 | SFX Y стись детесь вестись
161 | SFX Y стись демся вестись
162 | SFX Y стись дёшься вестись
163 | SFX Y стись дётся вестись
164 | SFX Y стись дётесь вестись
165 | SFX Y стись дёмся вестись
166 | SFX Y сти тут лести
167 | SFX Y сти ту лести
168 | SFX Y сти тешь лести
169 | SFX Y сти тете лести
170 | SFX Y сти тет лести
171 | SFX Y сти тем лести
172 | SFX Y сти тёшь лести
173 | SFX Y сти тёте лести
174 | SFX Y сти тёт лести
175 | SFX Y сти тём лести
176 | SFX Y сти дут вести
177 | SFX Y сти ду вести
178 | SFX Y сти дешь вести
179 | SFX Y сти дете вести
180 | SFX Y сти дет вести
181 | SFX Y сти дем вести
182 | SFX Y сти дёшь вести
183 | SFX Y сти дёте вести
184 | SFX Y сти дёт вести
185 | SFX Y сти дём вести
186 | SFX Y сти бут рести
187 | SFX Y сти бу рести
188 | SFX Y сти бешь рести
189 | SFX Y сти бете рести
190 | SFX Y сти бет рести
191 | SFX Y сти бем рести
192 | SFX Y сти бёшь рести
193 | SFX Y сти бёте рести
194 | SFX Y сти бёт рести
195 | SFX Y сти бём рести
196 | SFX Y слаться шлешься слаться
197 | SFX Y слаться шлется слаться
198 | SFX Y слаться шлетесь слаться
199 | SFX Y слаться шлемся слаться
200 | SFX Y слаться шлются слаться
201 | SFX Y слаться шлюсь слаться
202 | SFX Y слаться шлёшься слаться
203 | SFX Y слаться шлётся слаться
204 | SFX Y слаться шлётесь слаться
205 | SFX Y слаться шлёмся слаться
206 | SFX Y слать шлешь слать
207 | SFX Y слать шлете слать
208 | SFX Y слать шлет слать
209 | SFX Y слать шлем слать
210 | SFX Y слать шлют слать
211 | SFX Y слать шлю слать
212 | SFX Y слать шлёшь слать
213 | SFX Y слать шлёте слать
214 | SFX Y слать шлёт слать
215 | SFX Y слать шлём слать
216 | SFX Y скаться щутся скаться
217 | SFX Y скаться щусь скаться
218 | SFX Y скаться щешься скаться
219 | SFX Y скаться щется скаться
220 | SFX Y скаться щетесь скаться
221 | SFX Y скаться щемся скаться
222 | SFX Y скать щут скать
223 | SFX Y скать щу скать
224 | SFX Y скать щешь скать
225 | SFX Y скать щете скать
226 | SFX Y скать щет скать
227 | SFX Y скать щем скать
228 | SFX Y сеть шу сеть
229 | SFX Y саться шутся [^о]саться
230 | SFX Y саться шусь [^о]саться
231 | SFX Y саться шешься [^о]саться
232 | SFX Y саться шется [^о]саться
233 | SFX Y саться шетесь [^о]саться
234 | SFX Y саться шемся [^о]саться
235 | SFX Y сать шут [^о]сать
236 | SFX Y сать шу [^о]сать
237 | SFX Y сать шешь [^о]сать
238 | SFX Y сать шете [^о]сать
239 | SFX Y сать шет [^о]сать
240 | SFX Y сать шем [^о]сать
241 | SFX Y раться рутся [^бд]раться
242 | SFX Y раться русь [^бд]раться
243 | SFX Y раться решься [^бд]раться
244 | SFX Y раться рется [^бд]раться
245 | SFX Y раться ретесь [^бд]раться
246 | SFX Y раться ремся [^бд]раться
247 | SFX Y раться рёшься [^бд]раться
248 | SFX Y раться рётся [^бд]раться
249 | SFX Y раться рётесь [^бд]раться
250 | SFX Y раться рёмся [^бд]раться
251 | SFX Y раться ерутся [бд]раться
252 | SFX Y раться ерусь [бд]раться
253 | SFX Y раться ерешься [бд]раться
254 | SFX Y раться ерется [бд]раться
255 | SFX Y раться еретесь [бд]раться
256 | SFX Y раться еремся [бд]раться
257 | SFX Y раться ерёшься [бд]раться
258 | SFX Y раться ерётся [бд]раться
259 | SFX Y раться ерётесь [бд]раться
260 | SFX Y раться ерёмся [бд]раться
261 | SFX Y рать рут [^бд]рать
262 | SFX Y рать ру [^бд]рать
263 | SFX Y рать решь [^бд]рать
264 | SFX Y рать рете [^бд]рать
265 | SFX Y рать рет [^бд]рать
266 | SFX Y рать рем [^бд]рать
267 | SFX Y рать рёшь [^бд]рать
268 | SFX Y рать рёте [^бд]рать
269 | SFX Y рать рёт [^бд]рать
270 | SFX Y рать рём [^бд]рать
271 | SFX Y рать ерут [бд]рать
272 | SFX Y рать еру [бд]рать
273 | SFX Y рать ерешь [бд]рать
274 | SFX Y рать ерете [бд]рать
275 | SFX Y рать ерет [бд]рать
276 | SFX Y рать ерем [бд]рать
277 | SFX Y рать ерёшь [бд]рать
278 | SFX Y рать ерёте [бд]рать
279 | SFX Y рать ерёт [бд]рать
280 | SFX Y рать ерём [бд]рать
281 | SFX Y яться нутся мяться
282 | SFX Y яться нусь мяться
283 | SFX Y яться нешься мяться
284 | SFX Y яться нется мяться
285 | SFX Y яться нетесь мяться
286 | SFX Y яться немся мяться
287 | SFX Y яться нёшься мяться
288 | SFX Y яться нётся мяться
289 | SFX Y яться нётесь мяться
290 | SFX Y яться нёмся мяться
291 | SFX Y ять нут мять
292 | SFX Y ять ну мять
293 | SFX Y ять нешь мять
294 | SFX Y ять нете мять
295 | SFX Y ять нет мять
296 | SFX Y ять нем мять
297 | SFX Y ять нёшь мять
298 | SFX Y ять нёте мять
299 | SFX Y ять нёт мять
300 | SFX Y ять нём мять
301 | SFX Y наться онятся гнаться
302 | SFX Y наться онишься гнаться
303 | SFX Y наться онится гнаться
304 | SFX Y наться онитесь гнаться
305 | SFX Y наться онимся гнаться
306 | SFX Y наться онюсь гнаться
307 | SFX Y нать онят гнать
308 | SFX Y нать онишь гнать
309 | SFX Y нать оните гнать
310 | SFX Y нать онит гнать
311 | SFX Y нать оним гнать
312 | SFX Y нать оню гнать
313 | SFX Y каться чутся [^с]каться
314 | SFX Y каться чусь [^с]каться
315 | SFX Y каться чешься [^с]каться
316 | SFX Y каться чется [^с]каться
317 | SFX Y каться четесь [^с]каться
318 | SFX Y каться чемся [^с]каться
319 | SFX Y кать чут [^с]кать
320 | SFX Y кать чу [^с]кать
321 | SFX Y кать чешь [^с]кать
322 | SFX Y кать чете [^с]кать
323 | SFX Y кать чет [^с]кать
324 | SFX Y кать чем [^с]кать
325 | SFX Y ить ешь лить
326 | SFX Y ить ете лить
327 | SFX Y ить ет лить
328 | SFX Y ить ем лить
329 | SFX Y ить ют лить
330 | SFX Y ить ю лить
331 | SFX Y и ут расти
332 | SFX Y и у расти
333 | SFX Y и ешь расти
334 | SFX Y и ете расти
335 | SFX Y и ет расти
336 | SFX Y и ем расти
337 | SFX Y и ёшь расти
338 | SFX Y и ёте расти
339 | SFX Y и ёт расти
340 | SFX Y и ём расти
341 | SFX Y хаться шутся хаться
342 | SFX Y хаться шусь хаться
343 | SFX Y хаться шешься хаться
344 | SFX Y хаться шется хаться
345 | SFX Y хаться шетесь хаться
346 | SFX Y хаться шемся хаться
347 | SFX Y хать шут хать
348 | SFX Y хать шу хать
349 | SFX Y хать шешь хать
350 | SFX Y хать шете хать
351 | SFX Y хать шет хать
352 | SFX Y хать шем хать
353 | SFX Y еться ятся [дрт]еться
354 | SFX Y еться люсь петься
355 | SFX Y еться ишься [дрт]еться
356 | SFX Y еться ится [дрт]еться
357 | SFX Y еться итесь [дрт]еться
358 | SFX Y еться имся [дрт]еться
359 | SFX Y еться юсь реться
360 | SFX Y еть ят [дмнпрст]еть
361 | SFX Y еть лю петь
362 | SFX Y еть ишь [дмнпрст]еть
363 | SFX Y еть ите [дмнпрст]еть
364 | SFX Y еть ит [дмнпрст]еть
365 | SFX Y еть им [дмнпрст]еть
366 | SFX Y еть ю реть
367 | SFX Y есть тут честь
368 | SFX Y есть ту честь
369 | SFX Y есть тешь честь
370 | SFX Y есть тете честь
371 | SFX Y есть тет честь
372 | SFX Y есть тем честь
373 | SFX Y есть тёшь честь
374 | SFX Y есть тёте честь
375 | SFX Y есть тёт честь
376 | SFX Y есть тём честь
377 | SFX Y есть ядут сесть
378 | SFX Y есть яду сесть
379 | SFX Y есть ядешь сесть
380 | SFX Y есть ядете сесть
381 | SFX Y есть ядет сесть
382 | SFX Y есть ядем сесть
383 | SFX Y деться жусь деться
384 | SFX Y деть жу деть
385 | SFX Y аться утся рваться
386 | SFX Y аться утся осаться
387 | SFX Y аться усь рваться
388 | SFX Y аться усь осаться
389 | SFX Y аться ятся спаться
390 | SFX Y аться люсь спаться
391 | SFX Y аться ишься жаться
392 | SFX Y аться ишься спаться
393 | SFX Y аться ится жаться
394 | SFX Y аться ится спаться
395 | SFX Y аться итесь жаться
396 | SFX Y аться итесь спаться
397 | SFX Y аться имся жаться
398 | SFX Y аться имся спаться
399 | SFX Y аться ешься рваться
400 | SFX Y аться ешься осаться
401 | SFX Y аться ется рваться
402 | SFX Y аться ется осаться
403 | SFX Y аться етесь рваться
404 | SFX Y аться етесь осаться
405 | SFX Y аться емся рваться
406 | SFX Y аться емся осаться
407 | SFX Y аться ёшься рваться
408 | SFX Y аться ёшься осаться
409 | SFX Y аться ётся рваться
410 | SFX Y аться ётся осаться
411 | SFX Y аться ётесь рваться
412 | SFX Y аться ётесь осаться
413 | SFX Y аться ёмся рваться
414 | SFX Y аться ёмся осаться
415 | SFX Y ать ут рвать
416 | SFX Y ать ут осать
417 | SFX Y ать у рвать
418 | SFX Y ать у осать
419 | SFX Y ать ят спать
420 | SFX Y ать лю спать
421 | SFX Y ать ишь жать
422 | SFX Y ать ишь спать
423 | SFX Y ать ите жать
424 | SFX Y ать ите спать
425 | SFX Y ать ит жать
426 | SFX Y ать ит спать
427 | SFX Y ать им жать
428 | SFX Y ать им спать
429 | SFX Y ать ешь рвать
430 | SFX Y ать ешь осать
431 | SFX Y ать ете рвать
432 | SFX Y ать ете осать
433 | SFX Y ать ет рвать
434 | SFX Y ать ет осать
435 | SFX Y ать ем рвать
436 | SFX Y ать ем осать
437 | SFX Y ать ёшь рвать
438 | SFX Y ать ёшь осать
439 | SFX Y ать ёте рвать
440 | SFX Y ать ёте осать
441 | SFX Y ать ёт рвать
442 | SFX Y ать ёт осать
443 | SFX Y ать ём рвать
444 | SFX Y ать ём осать
445 |
446 | SFX X Y 3
447 | SFX X ый ы нный
448 | SFX X ый о нный
449 | SFX X ый а нный
450 |
451 | SFX W Y 28
452 | SFX W зиться жусь зиться
453 | SFX W зить жу зить
454 | SFX W ься ся иться
455 | SFX W ься есь иться
456 | SFX W ь е ить
457 | SFX W ться шься иться
458 | SFX W ться мся иться
459 | SFX W ть шь ить
460 | SFX W ть т ить
461 | SFX W ть м ить
462 | SFX W титься чусь [^юаеиоясуыэч]титься
463 | SFX W тить чу [^юаеиоясуыэч]тить
464 | SFX W ститься щусь ститься
465 | SFX W стить щу стить
466 | SFX W ситься шусь ситься
467 | SFX W сить шу сить
468 | SFX W иться усь [жшщч]иться
469 | SFX W иться ятся [^жшщч]иться
470 | SFX W иться люсь [бфмпв]иться
471 | SFX W иться атся [жшщч]иться
472 | SFX W иться юсь [аелнору]иться
473 | SFX W ить у [жшщч]ить
474 | SFX W ить ят [^жшщч]ить
475 | SFX W ить лю [бфмпв]ить
476 | SFX W ить ат [жшщч]ить
477 | SFX W ить ю [аелнору]ить
478 | SFX W диться жусь диться
479 | SFX W дить жу дить
480 |
481 | SFX V Y 179
482 | SFX V ться вутся житься
483 | SFX V ться вусь житься
484 | SFX V ться вешься житься
485 | SFX V ться вется житься
486 | SFX V ться ветесь житься
487 | SFX V ться вемся житься
488 | SFX V ться вёшься житься
489 | SFX V ться вётся житься
490 | SFX V ться вётесь житься
491 | SFX V ться вёмся житься
492 | SFX V ться нутся деться
493 | SFX V ться нусь деться
494 | SFX V ться нешься деться
495 | SFX V ться нется деться
496 | SFX V ться нетесь деться
497 | SFX V ться немся деться
498 | SFX V ться ешься уться
499 | SFX V ться ется уться
500 | SFX V ться етесь уться
501 | SFX V ться емся уться
502 | SFX V ться ются уться
503 | SFX V ться юсь уться
504 | SFX V ть вут жить
505 | SFX V ть ву жить
506 | SFX V ть вешь жить
507 | SFX V ть вете жить
508 | SFX V ть вет жить
509 | SFX V ть вем жить
510 | SFX V ть вёшь жить
511 | SFX V ть вёте жить
512 | SFX V ть вёт жить
513 | SFX V ть вём жить
514 | SFX V ть нут деть
515 | SFX V ть ну деть
516 | SFX V ть нешь деть
517 | SFX V ть нете деть
518 | SFX V ть нет деть
519 | SFX V ть нем деть
520 | SFX V ть ешь уть
521 | SFX V ть ете уть
522 | SFX V ть ет уть
523 | SFX V ть ем уть
524 | SFX V ть ют уть
525 | SFX V ть ю уть
526 | SFX V яться ешься яться
527 | SFX V яться ется яться
528 | SFX V яться етесь яться
529 | SFX V яться емся яться
530 | SFX V яться ются яться
531 | SFX V яться юсь яться
532 | SFX V яться ёшься яться
533 | SFX V яться ётся яться
534 | SFX V яться ётесь яться
535 | SFX V яться ёмся яться
536 | SFX V ять ешь ять
537 | SFX V ять ете ять
538 | SFX V ять ет ять
539 | SFX V ять ем ять
540 | SFX V ять ют ять
541 | SFX V ять ю ять
542 | SFX V ять ёшь ять
543 | SFX V ять ёте ять
544 | SFX V ять ёт ять
545 | SFX V ять ём ять
546 | SFX V оваться уешься оваться
547 | SFX V оваться уется оваться
548 | SFX V оваться уетесь оваться
549 | SFX V оваться уемся оваться
550 | SFX V оваться уются оваться
551 | SFX V оваться уюсь оваться
552 | SFX V оваться уёшься оваться
553 | SFX V оваться уётся оваться
554 | SFX V оваться уётесь оваться
555 | SFX V оваться уёмся оваться
556 | SFX V овать уешь овать
557 | SFX V овать уете овать
558 | SFX V овать ует овать
559 | SFX V овать уем овать
560 | SFX V овать уют овать
561 | SFX V овать ую овать
562 | SFX V овать уёшь овать
563 | SFX V овать уёте овать
564 | SFX V овать уёт овать
565 | SFX V овать уём овать
566 | SFX V иться ьешься [блпв]иться
567 | SFX V иться ьется [блпв]иться
568 | SFX V иться ьетесь [блпв]иться
569 | SFX V иться ьемся [блпв]иться
570 | SFX V иться ьются [блпв]иться
571 | SFX V иться ьюсь [блпв]иться
572 | SFX V иться ьёшься [блпв]иться
573 | SFX V иться ьётся [блпв]иться
574 | SFX V иться ьётесь [блпв]иться
575 | SFX V иться ьёмся [блпв]иться
576 | SFX V ить ьешь [блпв]ить
577 | SFX V ить ьете [блпв]ить
578 | SFX V ить ьет [блпв]ить
579 | SFX V ить ьем [блпв]ить
580 | SFX V ить ьют [блпв]ить
581 | SFX V ить ью [блпв]ить
582 | SFX V ить ьёшь [блпв]ить
583 | SFX V ить ьёте [блпв]ить
584 | SFX V ить ьёт [блпв]ить
585 | SFX V ить ьём [блпв]ить
586 | SFX V хаться дутся хаться
587 | SFX V хаться дусь хаться
588 | SFX V хаться дешься хаться
589 | SFX V хаться дется хаться
590 | SFX V хаться детесь хаться
591 | SFX V хаться демся хаться
592 | SFX V хать дут хать
593 | SFX V хать ду хать
594 | SFX V хать дешь хать
595 | SFX V хать дете хать
596 | SFX V хать дет хать
597 | SFX V хать дем хать
598 | SFX V ечься яжешься лечься
599 | SFX V ечься яжется лечься
600 | SFX V ечься яжетесь лечься
601 | SFX V ечься яжемся лечься
602 | SFX V ечься ягутся лечься
603 | SFX V ечься ягусь лечься
604 | SFX V ечь яжешь лечь
605 | SFX V ечь яжете лечь
606 | SFX V ечь яжет лечь
607 | SFX V ечь яжем лечь
608 | SFX V ечь ягут лечь
609 | SFX V ечь ягу лечь
610 | SFX V еваться уется [цжшщч]еваться
611 | SFX V еваться уются [цжшщч]еваться
612 | SFX V еваться уётся [цжшщч]еваться
613 | SFX V еваться юешься [^цжшщч]еваться
614 | SFX V еваться юется [^цжшщч]еваться
615 | SFX V еваться юетесь [^цжшщч]еваться
616 | SFX V еваться юемся [^цжшщч]еваться
617 | SFX V еваться юются [^цжшщч]еваться
618 | SFX V еваться ююсь [^цжшщч]еваться
619 | SFX V еваться юёшься [^цжшщч]еваться
620 | SFX V еваться юётся [^цжшщч]еваться
621 | SFX V еваться юётесь [^цжшщч]еваться
622 | SFX V еваться юёмся [^цжшщч]еваться
623 | SFX V евать уешь [цжшщч]евать
624 | SFX V евать уете [цжшщч]евать
625 | SFX V евать ует [цжшщч]евать
626 | SFX V евать уем [цжшщч]евать
627 | SFX V евать уют [цжшщч]евать
628 | SFX V евать ую [цжшщч]евать
629 | SFX V евать уёшь [цжшщч]евать
630 | SFX V евать уёте [цжшщч]евать
631 | SFX V евать уёт [цжшщч]евать
632 | SFX V евать уём [цжшщч]евать
633 | SFX V евать юешь [^цжшщч]евать
634 | SFX V евать юете [^цжшщч]евать
635 | SFX V евать юет [^цжшщч]евать
636 | SFX V евать юем [^цжшщч]евать
637 | SFX V евать юют [^цжшщч]евать
638 | SFX V евать юю [^цжшщч]евать
639 | SFX V евать юёшь [^цжшщч]евать
640 | SFX V евать юёте [^цжшщч]евать
641 | SFX V евать юёт [^цжшщч]евать
642 | SFX V евать юём [^цжшщч]евать
643 | SFX V аться лешься паться
644 | SFX V аться лется паться
645 | SFX V аться летесь паться
646 | SFX V аться лемся паться
647 | SFX V аться лются паться
648 | SFX V аться люсь паться
649 | SFX V ать ут дать
650 | SFX V ать у дать
651 | SFX V ать лешь пать
652 | SFX V ать лете пать
653 | SFX V ать лет пать
654 | SFX V ать лем пать
655 | SFX V ать лют пать
656 | SFX V ать лю пать
657 | SFX V ать ешь дать
658 | SFX V ать ете дать
659 | SFX V ать ет дать
660 | SFX V ать ем дать
661 |
662 | SFX U Y 162
663 | SFX U чься жешься чься
664 | SFX U чься жется чься
665 | SFX U чься жетесь чься
666 | SFX U чься жемся чься
667 | SFX U чься жёшься чься
668 | SFX U чься жётся чься
669 | SFX U чься жётесь чься
670 | SFX U чься жёмся чься
671 | SFX U чься гутся чься
672 | SFX U чься гусь чься
673 | SFX U чь жешь чь
674 | SFX U чь жете чь
675 | SFX U чь жет чь
676 | SFX U чь жем чь
677 | SFX U чь жёшь чь
678 | SFX U чь жёте чь
679 | SFX U чь жёт чь
680 | SFX U чь жём чь
681 | SFX U чь гут чь
682 | SFX U чь гу чь
683 | SFX U ься ся уться
684 | SFX U ься ся ояться
685 | SFX U ься ся [жшщч]аться
686 | SFX U ваться ешься аваться
687 | SFX U ваться ется аваться
688 | SFX U ваться етесь аваться
689 | SFX U ваться емся аваться
690 | SFX U ваться ются аваться
691 | SFX U ваться юсь аваться
692 | SFX U ваться ёшься аваться
693 | SFX U ваться ётся аваться
694 | SFX U ваться ётесь аваться
695 | SFX U ваться ёмся аваться
696 | SFX U вать ешь авать
697 | SFX U вать ете авать
698 | SFX U вать ет авать
699 | SFX U вать ем авать
700 | SFX U вать ют авать
701 | SFX U вать ю авать
702 | SFX U вать ёшь авать
703 | SFX U вать ёте авать
704 | SFX U вать ёт авать
705 | SFX U вать ём авать
706 | SFX U уться ешься уться
707 | SFX U уться ется уться
708 | SFX U уться етесь уться
709 | SFX U уться емся уться
710 | SFX U уться ёшься уться
711 | SFX U уться ётся уться
712 | SFX U уться ётесь уться
713 | SFX U уться ёмся уться
714 | SFX U уть у уть
715 | SFX U уть ешь уть
716 | SFX U уть ете уть
717 | SFX U уть ет уть
718 | SFX U уть ем уть
719 | SFX U уть ёшь уть
720 | SFX U уть ёте уть
721 | SFX U уть ёт уть
722 | SFX U уть ём уть
723 | SFX U ться сь уться
724 | SFX U ться ешься [^аеоу]яться
725 | SFX U ться ется [^аеоу]яться
726 | SFX U ться етесь [^аеоу]яться
727 | SFX U ться емся [^аеоу]яться
728 | SFX U ться ются [^аеоу]яться
729 | SFX U ться юсь [^аеоу]яться
730 | SFX U ть т уть
731 | SFX U ть т оять
732 | SFX U ть т [жшщч]ать
733 | SFX U ть ешь [^аеоу]ять
734 | SFX U ть ете [^аеоу]ять
735 | SFX U ть ет [^аеоу]ять
736 | SFX U ть ем [^аеоу]ять
737 | SFX U ть ют [^аеоу]ять
738 | SFX U ть ю [^аеоу]ять
739 | SFX U яться ишься ояться
740 | SFX U яться ится ояться
741 | SFX U яться итесь ояться
742 | SFX U яться имся ояться
743 | SFX U яться ешься [аеу]яться
744 | SFX U яться ется [аеу]яться
745 | SFX U яться етесь [аеу]яться
746 | SFX U яться емся [аеу]яться
747 | SFX U яться ются [аеу]яться
748 | SFX U яться юсь [аеоу]яться
749 | SFX U ять ишь оять
750 | SFX U ять ите оять
751 | SFX U ять ит оять
752 | SFX U ять им оять
753 | SFX U ять ешь [аеу]ять
754 | SFX U ять ете [аеу]ять
755 | SFX U ять ет [аеу]ять
756 | SFX U ять ем [аеу]ять
757 | SFX U ять ют [аеу]ять
758 | SFX U ять ю [аеоу]ять
759 | SFX U оваться уешься оваться
760 | SFX U оваться уется оваться
761 | SFX U оваться уетесь оваться
762 | SFX U оваться уемся оваться
763 | SFX U оваться уются оваться
764 | SFX U оваться уюсь оваться
765 | SFX U овать уешь овать
766 | SFX U овать уете овать
767 | SFX U овать ует овать
768 | SFX U овать уем овать
769 | SFX U овать уют овать
770 | SFX U овать ую овать
771 | SFX U еваться уешься [цжшщч]еваться
772 | SFX U еваться уется [цжшщч]еваться
773 | SFX U еваться уетесь [цжшщч]еваться
774 | SFX U еваться уемся [цжшщч]еваться
775 | SFX U еваться уются [цжшщч]еваться
776 | SFX U еваться уюсь [цжшщч]еваться
777 | SFX U еваться юешься [^цжшщч]еваться
778 | SFX U еваться юется [^цжшщч]еваться
779 | SFX U еваться юетесь [^цжшщч]еваться
780 | SFX U еваться юемся [^цжшщч]еваться
781 | SFX U еваться юются [^цжшщч]еваться
782 | SFX U еваться ююсь [^цжшщч]еваться
783 | SFX U евать уешь [цжшщч]евать
784 | SFX U евать уете [цжшщч]евать
785 | SFX U евать ует [цжшщч]евать
786 | SFX U евать уем [цжшщч]евать
787 | SFX U евать уют [цжшщч]евать
788 | SFX U евать ую [цжшщч]евать
789 | SFX U евать юешь [^цжшщч]евать
790 | SFX U евать юете [^цжшщч]евать
791 | SFX U евать юет [^цжшщч]евать
792 | SFX U евать юем [^цжшщч]евать
793 | SFX U евать юют [^цжшщч]евать
794 | SFX U евать юю [^цжшщч]евать
795 | SFX U аться утся даться
796 | SFX U аться усь даться
797 | SFX U аться усь [жшщч]аться
798 | SFX U аться ишься [жшщч]аться
799 | SFX U аться ится [жшщч]аться
800 | SFX U аться итесь [жшщч]аться
801 | SFX U аться имся [жшщч]аться
802 | SFX U аться ешься даться
803 | SFX U аться ется даться
804 | SFX U аться етесь даться
805 | SFX U аться емся даться
806 | SFX U аться ёшься даться
807 | SFX U аться ётся даться
808 | SFX U аться ётесь даться
809 | SFX U аться ёмся даться
810 | SFX U ать ут дать
811 | SFX U ать у дать
812 | SFX U ать у [жшщч]ать
813 | SFX U ать ишь [жшщч]ать
814 | SFX U ать ите [жшщч]ать
815 | SFX U ать ит [жшщч]ать
816 | SFX U ать им [жшщч]ать
817 | SFX U ать ешь дать
818 | SFX U ать ете дать
819 | SFX U ать ет дать
820 | SFX U ать ем дать
821 | SFX U ать ёшь дать
822 | SFX U ать ёте дать
823 | SFX U ать ёт дать
824 | SFX U ать ём дать
825 |
826 | SFX T Y 38
827 | SFX T уться ьтесь уться
828 | SFX T уться ься уться
829 | SFX T уть ьте уть
830 | SFX T уть ь уть
831 | SFX T саться шитесь саться
832 | SFX T саться шись саться
833 | SFX T сать шите сать
834 | SFX T сать ши сать
835 | SFX T яться йтесь [аеоу]яться
836 | SFX T яться йся [аеоу]яться
837 | SFX T ять йте [аеоу]ять
838 | SFX T ять й [аеоу]ять
839 | SFX T оваться уйтесь оваться
840 | SFX T оваться уйся оваться
841 | SFX T овать уйте овать
842 | SFX T овать уй овать
843 | SFX T иться ьтесь [^аео]иться
844 | SFX T иться ься [^аео]иться
845 | SFX T иться йтесь [аео]иться
846 | SFX T иться йся [аео]иться
847 | SFX T ить ьте [^аео]ить
848 | SFX T ить ь [^аео]ить
849 | SFX T ить йте [аео]ить
850 | SFX T ить й [аео]ить
851 | SFX T еваться уйтесь [цжшщч]еваться
852 | SFX T еваться уйся [цжшщч]еваться
853 | SFX T еваться юйтесь [^цжшщч]еваться
854 | SFX T еваться юйся [^цжшщч]еваться
855 | SFX T евать уйте [цжшщч]евать
856 | SFX T евать уй [цжшщч]евать
857 | SFX T евать юйте [^цжшщч]евать
858 | SFX T евать юй [^цжшщч]евать
859 | SFX T еться итесь еться
860 | SFX T еться ись еться
861 | SFX T еть ите еть
862 | SFX T еть и еть
863 | SFX T аться ись [жч]аться
864 | SFX T ать и [жч]ать
865 |
866 | SFX S Y 40
867 | SFX S ый ы [^н]ый
868 | SFX S ый о [^н]ый
869 | SFX S ый а [^н]ый
870 | SFX S ый 0 [^н]ый
871 | SFX S ьный ен ьный
872 | SFX S ький ек ький
873 | SFX S ой ы [^гх]ой
874 | SFX S ой о ой
875 | SFX S ой и [гх]ой
876 | SFX S ой а ой
877 | SFX S ой 0 ой
878 | SFX S ный ы нный
879 | SFX S ный ы [^ё]нный
880 | SFX S ный он лный
881 | SFX S ный о нный
882 | SFX S ный о [^ё]нный
883 | SFX S ный ны [^н]ный
884 | SFX S ный но [^н]ный
885 | SFX S ный на [^н]ный
886 | SFX S ный н еный
887 | SFX S ный н [ёе]ный
888 | SFX S ный ен [^ейлнь]ный
889 | SFX S ный ен [^ёейлнь]ный
890 | SFX S ный а нный
891 | SFX S ный а [^ё]нный
892 | SFX S нный н нный
893 | SFX S кий ок [^аеийоуьы]кий
894 | SFX S кий ок [^ёаеийоуьы]кий
895 | SFX S кий к [аеиоуы]кий
896 | SFX S кий к [ёаеиоуы]кий
897 | SFX S йный ен йный
898 | SFX S йкий ек йкий
899 | SFX S ий о [гхк]ий
900 | SFX S ий и [гхкжщч]ий
901 | SFX S ий е [жщч]ий
902 | SFX S ий а [гхкжщч]ий
903 | SFX S ий 0 [гхжщч]ий
904 | SFX S ённый ены ённый
905 | SFX S ённый ено ённый
906 | SFX S ённый ена ённый
907 |
908 | SFX R Y 4
909 | SFX R ться вшись [аеиояуы]ться
910 | SFX R ть в [аеиояуы]ть
911 | SFX R сться вшись сться
912 | SFX R сть в сть
913 |
914 | SFX Q Y 6
915 | SFX Q оваться уясь оваться
916 | SFX Q овать уя овать
917 | SFX Q еваться уясь [цжшщч]еваться
918 | SFX Q еваться юясь [^цжшщч]еваться
919 | SFX Q евать уя [цжшщч]евать
920 | SFX Q евать юя [^цжшщч]евать
921 |
922 | SFX P Y 12
923 | SFX P ыться оясь ыться
924 | SFX P ыть оя ыть
925 | SFX P ться сь [аеоу]яться
926 | SFX P ться ясь [ае]ться
927 | SFX P ться ясь [^аеоу]яться
928 | SFX P ть я [ае]ть
929 | SFX P ть я [^аеоу]ять
930 | SFX P ять я [аеоу]ять
931 | SFX P иться ясь [^жшщч]иться
932 | SFX P иться ась [жшщч]иться
933 | SFX P ить я [^жшщч]ить
934 | SFX P ить а [жшщч]ить
935 |
936 | SFX O Y 131
937 | SFX O ы ами ы
938 | SFX O ы ам ы
939 | SFX O ы ах ы
940 | SFX O рин р рин
941 | SFX O оть тями оть
942 | SFX O оть тям оть
943 | SFX O оть тях оть
944 | SFX O оть тя оть
945 | SFX O оть ти оть
946 | SFX O оть тем оть
947 | SFX O оть тей оть
948 | SFX O оть те оть
949 | SFX O оть тю оть
950 | SFX O ок ку ок
951 | SFX O ок ков ок
952 | SFX O ок ком ок
953 | SFX O ок ки ок
954 | SFX O ок ке ок
955 | SFX O ок ками ок
956 | SFX O ок кам ок
957 | SFX O ок ках ок
958 | SFX O ок ка ок
959 | SFX O нин н нин
960 | SFX O ин ы рин
961 | SFX O ин е нин
962 | SFX O ин ами ин
963 | SFX O ин ам ин
964 | SFX O ин ах ин
965 | SFX O ий ья ий
966 | SFX O ий ьими ий
967 | SFX O ий ьим ий
968 | SFX O ий ьих ий
969 | SFX O ий ьи ий
970 | SFX O ий ьему ий
971 | SFX O ий ьем ий
972 | SFX O ий ьей ий
973 | SFX O ий ьего ий
974 | SFX O ий ье ий
975 | SFX O ий ью ий
976 | SFX O и ями [арс]ти
977 | SFX O и ями [абеилнорсь]и
978 | SFX O и ям [абдеилнорсть]и
979 | SFX O и ях [абдеилнорсть]и
980 | SFX O и ами [^абдеилнорсть]и
981 | SFX O и ам [^абдеилнорсть]и
982 | SFX O и ах [^абдеилнорсть]и
983 | SFX O ень нями ень
984 | SFX O ень ням ень
985 | SFX O ень нях ень
986 | SFX O ень ня ень
987 | SFX O ень ни ень
988 | SFX O ень нем ень
989 | SFX O ень ней ень
990 | SFX O ень не ень
991 | SFX O ень ню ень
992 | SFX O ел лы ел
993 | SFX O ел лу ел
994 | SFX O ел лов ел
995 | SFX O ел лом ел
996 | SFX O ел ле ел
997 | SFX O ел лами ел
998 | SFX O ел лам ел
999 | SFX O ел лах ел
1000 | SFX O ел ла ел
1001 | SFX O ек ьку [лнрс]ек
1002 | SFX O ек ьков [лнрс]ек
1003 | SFX O ек ьком [лнрс]ек
1004 | SFX O ек ьки [лнрс]ек
1005 | SFX O ек ьке [лнрс]ек
1006 | SFX O ек ьками [лнрс]ек
1007 | SFX O ек ькам [лнрс]ек
1008 | SFX O ек ьках [лнрс]ек
1009 | SFX O ек ька [лнрс]ек
1010 | SFX O ек ку [жшч]ек
1011 | SFX O ек ков [жшч]ек
1012 | SFX O ек ком [жшч]ек
1013 | SFX O ек ки [жшч]ек
1014 | SFX O ек ке [жшч]ек
1015 | SFX O ек ками [жшч]ек
1016 | SFX O ек кам [жшч]ек
1017 | SFX O ек ках [жшч]ек
1018 | SFX O ек ка [жшч]ек
1019 | SFX O ец ьцы лец
1020 | SFX O ец ьцу лец
1021 | SFX O ец ьце лец
1022 | SFX O ец ьцами лец
1023 | SFX O ец ьцам лец
1024 | SFX O ец ьцах лец
1025 | SFX O ец ьца лец
1026 | SFX O ец йцы [аеио]ец
1027 | SFX O ец йцу [аеио]ец
1028 | SFX O ец йцев [аеи]ец
1029 | SFX O ец йцем [аеи]ец
1030 | SFX O ец йце [аеио]ец
1031 | SFX O ец йцами [аеио]ец
1032 | SFX O ец йцам [аеио]ец
1033 | SFX O ец йцах [аеио]ец
1034 | SFX O ец йца [аеио]ец
1035 | SFX O ец цы [^аеило]ец
1036 | SFX O ец цу [^аеило]ец
1037 | SFX O ец це [^аеило]ец
1038 | SFX O ец цами [^аеило]ец
1039 | SFX O ец цам [^аеило]ец
1040 | SFX O ец цах [^аеило]ец
1041 | SFX O ец ца [^аеило]ец
1042 | SFX O ёл лы ёл
1043 | SFX O ёл лу ёл
1044 | SFX O ёл лов ёл
1045 | SFX O ёл лом ёл
1046 | SFX O ёл ле ёл
1047 | SFX O ёл лами ёл
1048 | SFX O ёл лам ёл
1049 | SFX O ёл лах ёл
1050 | SFX O ёл ла ёл
1051 | SFX O ёк ьку [лнрс]ёк
1052 | SFX O ёк ьков [лнрс]ёк
1053 | SFX O ёк ьком [лнрс]ёк
1054 | SFX O ёк ьки [лнрс]ёк
1055 | SFX O ёк ьке [лнрс]ёк
1056 | SFX O ёк ьками [лнрс]ёк
1057 | SFX O ёк ькам [лнрс]ёк
1058 | SFX O ёк ьках [лнрс]ёк
1059 | SFX O ёк ька [лнрс]ёк
1060 | SFX O 0 у ин
1061 | SFX O 0 ом ин
1062 | SFX O 0 ми [ая]
1063 | SFX O 0 м [ая]
1064 | SFX O 0 х [ая]
1065 | SFX O 0 ев [аняр]ц
1066 | SFX O 0 е ин
1067 | SFX O 0 а ин
1068 |
1069 | SFX N Y 17
1070 | SFX N ь ями [^жшщч]ь
1071 | SFX N ь ям [^жшщч]ь
1072 | SFX N ь ях [^жшщч]ь
1073 | SFX N ь и ь
1074 | SFX N ь ей ь
1075 | SFX N ь ами [жшщч]ь
1076 | SFX N ь ам [жшщч]ь
1077 | SFX N ь ах [жшщч]ь
1078 | SFX N 0 у [^ь]
1079 | SFX N 0 ов [^цжьшщч]
1080 | SFX N 0 ом [^цжьшщч]
1081 | SFX N 0 е [^ь]
1082 | SFX N 0 ами [^ь]
1083 | SFX N 0 ам [^ь]
1084 | SFX N 0 ах [^ь]
1085 | SFX N 0 а [^ь]
1086 | SFX N 0 ю ь
1087 |
1088 | SFX M Y 108
1089 | SFX M чься кутся чься
1090 | SFX M чься кусь чься
1091 | SFX M чь кут чь
1092 | SFX M чь ку чь
1093 | SFX M ыться оешься ыться
1094 | SFX M ыться оется ыться
1095 | SFX M ыться оетесь ыться
1096 | SFX M ыться оемся ыться
1097 | SFX M ыться оются ыться
1098 | SFX M ыться оюсь ыться
1099 | SFX M ыть оешь ыть
1100 | SFX M ыть оете ыть
1101 | SFX M ыть оет ыть
1102 | SFX M ыть оем ыть
1103 | SFX M ыть оют ыть
1104 | SFX M ыть ою ыть
1105 | SFX M ься ся уться
1106 | SFX M ься ешься чься
1107 | SFX M ься ется чься
1108 | SFX M ься етесь чься
1109 | SFX M ься емся чься
1110 | SFX M ься ёшься чься
1111 | SFX M ься ётся чься
1112 | SFX M ься ётесь чься
1113 | SFX M ься ёмся чься
1114 | SFX M ь ешь чь
1115 | SFX M ь ете чь
1116 | SFX M ь ет чь
1117 | SFX M ь ем чь
1118 | SFX M ь ёшь чь
1119 | SFX M ь ёте чь
1120 | SFX M ь ёт чь
1121 | SFX M ь ём чь
1122 | SFX M уться ешься уться
1123 | SFX M уться ется уться
1124 | SFX M уться етесь уться
1125 | SFX M уться емся уться
1126 | SFX M уть у уть
1127 | SFX M уть ешь уть
1128 | SFX M уть ете уть
1129 | SFX M уть ет уть
1130 | SFX M уть ем уть
1131 | SFX M ться сь уться
1132 | SFX M ться ешься [ае]ться
1133 | SFX M ться ется [ае]ться
1134 | SFX M ться етесь [ае]ться
1135 | SFX M ться емся [ае]ться
1136 | SFX M ться ются [ае]ться
1137 | SFX M ться юсь [ае]ться
1138 | SFX M ть т уть
1139 | SFX M ть ешь [ае]ть
1140 | SFX M ть ете [ае]ть
1141 | SFX M ть ет [ае]ть
1142 | SFX M ть ем [ае]ть
1143 | SFX M ть ют [ае]ть
1144 | SFX M ть ю [ае]ть
1145 | SFX M тись утся [сз]тись
1146 | SFX M тись усь [сз]тись
1147 | SFX M тись ешься [сз]тись
1148 | SFX M тись ется [сз]тись
1149 | SFX M тись етесь [сз]тись
1150 | SFX M тись емся [сз]тись
1151 | SFX M тись дутся йтись
1152 | SFX M тись дусь йтись
1153 | SFX M тись дешься йтись
1154 | SFX M тись дется йтись
1155 | SFX M тись детесь йтись
1156 | SFX M тись демся йтись
1157 | SFX M тись дёшься йтись
1158 | SFX M тись дётся йтись
1159 | SFX M тись дётесь йтись
1160 | SFX M тись дёмся йтись
1161 | SFX M тись ёшься [сз]тись
1162 | SFX M тись ётся [сз]тись
1163 | SFX M тись ётесь [сз]тись
1164 | SFX M тись ёмся [сз]тись
1165 | SFX M ти ут [сз]ти
1166 | SFX M ти у [сз]ти
1167 | SFX M ти ешь [сз]ти
1168 | SFX M ти ете [сз]ти
1169 | SFX M ти ет [сз]ти
1170 | SFX M ти ем [сз]ти
1171 | SFX M ти дут йти
1172 | SFX M ти ду йти
1173 | SFX M ти дешь йти
1174 | SFX M ти дете йти
1175 | SFX M ти дет йти
1176 | SFX M ти дем йти
1177 | SFX M ти дёшь йти
1178 | SFX M ти дёте йти
1179 | SFX M ти дёт йти
1180 | SFX M ти дём йти
1181 | SFX M ти ёшь [сз]ти
1182 | SFX M ти ёте [сз]ти
1183 | SFX M ти ёт [сз]ти
1184 | SFX M ти ём [сз]ти
1185 | SFX M оться ешься оться
1186 | SFX M оться ется оться
1187 | SFX M оться етесь оться
1188 | SFX M оться емся оться
1189 | SFX M оться ются оться
1190 | SFX M оться юсь оться
1191 | SFX M оть ешь оть
1192 | SFX M оть ете оть
1193 | SFX M оть ет оть
1194 | SFX M оть ем оть
1195 | SFX M оть ют оть
1196 | SFX M оть ю оть
1197 |
1198 | SFX L Y 63
1199 | SFX L чься кся чься
1200 | SFX L чься кся [^е]чься
1201 | SFX L чься клось чься
1202 | SFX L чься клись чься
1203 | SFX L чься клась чься
1204 | SFX L чь кло чь
1205 | SFX L чь кли чь
1206 | SFX L чь кла чь
1207 | SFX L чь к чь
1208 | SFX L чь к [^е]чь
1209 | SFX L зть з зть
1210 | SFX L зти з зти
1211 | SFX L ться ся зться
1212 | SFX L ться лся [^сз]ться
1213 | SFX L ться лось [^с]ться
1214 | SFX L ться лись [^с]ться
1215 | SFX L ться лась [^с]ться
1216 | SFX L ть ло [^с]ть
1217 | SFX L ть ли [^с]ть
1218 | SFX L ть ла [^с]ть
1219 | SFX L ть л [^сз]ть
1220 | SFX L ти ло зти
1221 | SFX L ти ли зти
1222 | SFX L ти ла зти
1223 | SFX L сться лся сться
1224 | SFX L сться лось сться
1225 | SFX L сться лись сться
1226 | SFX L сться лась сться
1227 | SFX L сть ло [^ч].сть
1228 | SFX L сть ли [^ч].сть
1229 | SFX L сть ла [^ч].сть
1230 | SFX L сть л [^ч].сть
1231 | SFX L стись лся стись
1232 | SFX L стись лся [^е]стись
1233 | SFX L стись лось стись
1234 | SFX L стись лись стись
1235 | SFX L стись лась стись
1236 | SFX L сти ло сти
1237 | SFX L сти ли сти
1238 | SFX L сти ла сти
1239 | SFX L сти л сти
1240 | SFX L сти л [^е]сти
1241 | SFX L ся лось [^аияь]ся
1242 | SFX L ся лись [^аияь]ся
1243 | SFX L ся лась [^аияь]ся
1244 | SFX L лзти лз лзти
1245 | SFX L ечься ёкся ечься
1246 | SFX L ечь ёк ечь
1247 | SFX L езти ёз езти
1248 | SFX L есть ло честь
1249 | SFX L есть ли честь
1250 | SFX L есть ла честь
1251 | SFX L есть ел честь
1252 | SFX L есть ёл честь
1253 | SFX L естись ёлся естись
1254 | SFX L ести ёл ести
1255 | SFX L ась ось ась
1256 | SFX L ась ись ась
1257 | SFX L а о а
1258 | SFX L а и а
1259 | SFX L 0 ло [^аияь]
1260 | SFX L 0 ли [^аияь]
1261 | SFX L 0 ла [^аияь]
1262 |
1263 | SFX K Y 55
1264 | SFX K ще щ ще
1265 | SFX K ье ий ье
1266 | SFX K ь ями ь
1267 | SFX K ь ям ь
1268 | SFX K ь ях ь
1269 | SFX K ь я ь
1270 | SFX K ь и ь
1271 | SFX K ь ем ь
1272 | SFX K ь ей ь
1273 | SFX K ь е ь
1274 | SFX K ь ю ь
1275 | SFX K о у о
1276 | SFX K о и [ишч]ко
1277 | SFX K о е о
1278 | SFX K о ами о
1279 | SFX K о ам о
1280 | SFX K о ах о
1281 | SFX K о а о
1282 | SFX K о 0 [дгств]о
1283 | SFX K й ями й
1284 | SFX K й ям й
1285 | SFX K й ях й
1286 | SFX K й я й
1287 | SFX K й и ий
1288 | SFX K й и [юаеояу]й
1289 | SFX K й ев й
1290 | SFX K й ем й
1291 | SFX K й е [^и]й
1292 | SFX K й ю й
1293 | SFX K е у [цжшщ]е
1294 | SFX K е ями [^цжшщ]е
1295 | SFX K е ям [^цжшщ]е
1296 | SFX K е ях [^цжшщ]е
1297 | SFX K е я [^цжшщ]е
1298 | SFX K е й ие
1299 | SFX K е и ие
1300 | SFX K е ей [^цижьщ]е
1301 | SFX K е ами [цжшщ]е
1302 | SFX K е ам [цжшщ]е
1303 | SFX K е ах [цжшщ]е
1304 | SFX K е а [цжшщ]е
1305 | SFX K е ю [^цжшщ]е
1306 | SFX K 0 ы [^егхйкожьшщч]
1307 | SFX K 0 у [^ейоь]
1308 | SFX K 0 ов [^цейожьшщч]
1309 | SFX K 0 ом [^цейожьшщч]
1310 | SFX K 0 м о
1311 | SFX K 0 м е
1312 | SFX K 0 и [гхкжшщч]
1313 | SFX K 0 ей [жшщч]
1314 | SFX K 0 е [^ейоь]
1315 | SFX K 0 ами [^ейоь]
1316 | SFX K 0 ам [^ейоь]
1317 | SFX K 0 ах [^ейоь]
1318 | SFX K 0 а [^ейоь]
1319 |
1320 | SFX J Y 37
1321 | SFX J ь я ь
1322 | SFX J ь ем ь
1323 | SFX J ь е ь
1324 | SFX J ь ю ь
1325 | SFX J о у о
1326 | SFX J о е о
1327 | SFX J о а о
1328 | SFX J й я й
1329 | SFX J й и ий
1330 | SFX J й ем й
1331 | SFX J й е [^и]й
1332 | SFX J й ю й
1333 | SFX J е у [цжшщ]е
1334 | SFX J е я [^цжшщ]е
1335 | SFX J е и ие
1336 | SFX J е а [цжшщ]е
1337 | SFX J е ю [^цжшщ]е
1338 | SFX J ёж ежу ёж
1339 | SFX J ёж еже ёж
1340 | SFX J ёж ежа ёж
1341 | SFX J ё я ё
1342 | SFX J ё е ьё
1343 | SFX J ё ю ё
1344 | SFX J 0 у [^ейоь]
1345 | SFX J 0 у [^ёейожь]
1346 | SFX J 0 у [^ё]ж
1347 | SFX J 0 ом [^цейожьшщч]
1348 | SFX J 0 ом [^ёцейожьшщч]
1349 | SFX J 0 м о
1350 | SFX J 0 м е
1351 | SFX J 0 м [ёе]
1352 | SFX J 0 е [^ейоь]
1353 | SFX J 0 е [^ёейожь]
1354 | SFX J 0 е [^ё]ж
1355 | SFX J 0 а [^ейоь]
1356 | SFX J 0 а [^ёейожь]
1357 | SFX J 0 а [^ё]ж
1358 |
1359 | SFX I Y 30
1360 | SFX I ьня ен ьня
1361 | SFX I ька ек ька
1362 | SFX I я ь [аеиояуы]ня
1363 | SFX I я й [еиу]я
1364 | SFX I я и я
1365 | SFX I я ей я
1366 | SFX I я ею я
1367 | SFX I я е [^и]я
1368 | SFX I я ю я
1369 | SFX I ня ен [^аеийояуьыз]ня
1370 | SFX I ка ок [^юацеийояужьышч]ка
1371 | SFX I ка к [юаеиояуы]ка
1372 | SFX I ка ек [цжшч]ка
1373 | SFX I йня ен йня
1374 | SFX I йка ек йка
1375 | SFX I а ы [^гхкжшщч]а
1376 | SFX I а у а
1377 | SFX I а ой [^цжшщч]а
1378 | SFX I а ою [^цжшщч]а
1379 | SFX I а и [гхкжшщч]а
1380 | SFX I а ей [цшщч]а
1381 | SFX I а ею [цшщч]а
1382 | SFX I а е а
1383 | SFX I а 0 [^к]а
1384 | SFX I 0 ми я
1385 | SFX I 0 ми а
1386 | SFX I 0 м я
1387 | SFX I 0 м а
1388 | SFX I 0 х я
1389 | SFX I 0 х а
1390 |
1391 | SFX H Y 14
1392 | SFX H я и я
1393 | SFX H я ей я
1394 | SFX H я ею я
1395 | SFX H я е [^и]я
1396 | SFX H я ю я
1397 | SFX H й ю [ео]й
1398 | SFX H а ы [^гхкжшщч]а
1399 | SFX H а у а
1400 | SFX H а ой [^цжшщч]а
1401 | SFX H а ою [^цжшщч]а
1402 | SFX H а и [гхкжшщч]а
1403 | SFX H а ей ща
1404 | SFX H а ею ща
1405 | SFX H а е а
1406 |
1407 | SFX G Y 52
1408 | SFX G ый ому ый
1409 | SFX G ый ом ый
1410 | SFX G ый ого ый
1411 | SFX G ьня ен ьня
1412 | SFX G ь ями ь
1413 | SFX G ь ям ь
1414 | SFX G ь ях ь
1415 | SFX G ь я ь
1416 | SFX G ь и ь
1417 | SFX G ь ем ь
1418 | SFX G ь ей ь
1419 | SFX G ь е ь
1420 | SFX G ь ю ь
1421 | SFX G ь ём ь
1422 | SFX G я ь [аеиоуы]ня
1423 | SFX G я й [еиу]я
1424 | SFX G я и я
1425 | SFX G я ей я
1426 | SFX G я ею я
1427 | SFX G я е [^и]я
1428 | SFX G я ю я
1429 | SFX G я ёй я
1430 | SFX G я ёю я
1431 | SFX G ок ку ок
1432 | SFX G ок ком ок
1433 | SFX G ок ке ок
1434 | SFX G ок ка ок
1435 | SFX G ой им ой
1436 | SFX G ня ен [^аеийоуьыз]ня
1437 | SFX G йня ен йня
1438 | SFX G й му ой
1439 | SFX G й м ый
1440 | SFX G й м ой
1441 | SFX G й м ий
1442 | SFX G й го ой
1443 | SFX G ий ому ий
1444 | SFX G ий ом ий
1445 | SFX G ий ого ий
1446 | SFX G ек ку ек
1447 | SFX G ек ком ек
1448 | SFX G ек ке ек
1449 | SFX G ек ка ек
1450 | SFX G ец цу ец
1451 | SFX G ец це ец
1452 | SFX G ец ца ец
1453 | SFX G 0 ым [^цейкояжьшщч]
1454 | SFX G 0 у [^цейкояь]
1455 | SFX G 0 ми я
1456 | SFX G 0 м я
1457 | SFX G 0 х я
1458 | SFX G 0 е [^цейкояь]
1459 | SFX G 0 а [^цейкояь]
1460 |
1461 | SFX F Y 25
1462 | SFX F ь и ь
1463 | SFX F онок атами онок
1464 | SFX F онок атам онок
1465 | SFX F онок атах онок
1466 | SFX F онок ата онок
1467 | SFX F онок ат онок
1468 | SFX F ок ку нок
1469 | SFX F ок ком нок
1470 | SFX F ок ке нок
1471 | SFX F ок ка нок
1472 | SFX F енок ятами енок
1473 | SFX F енок ятам енок
1474 | SFX F енок ятах енок
1475 | SFX F енок ята енок
1476 | SFX F енок ят енок
1477 | SFX F ая ую ая
1478 | SFX F ая ой ая
1479 | SFX F а у а
1480 | SFX F а ой а
1481 | SFX F ёнок ятами ёнок
1482 | SFX F ёнок ятам ёнок
1483 | SFX F ёнок ятах ёнок
1484 | SFX F ёнок ята ёнок
1485 | SFX F ёнок ят ёнок
1486 | SFX F 0 ю ь
1487 |
1488 | SFX E Y 15
1489 | SFX E ый ей ый
1490 | SFX E ый ее ый
1491 | SFX E ь я ь
1492 | SFX E ь ем ь
1493 | SFX E ь е ь
1494 | SFX E ь ю ь
1495 | SFX E ь ём ь
1496 | SFX E я и я
1497 | SFX E я ей я
1498 | SFX E я ею я
1499 | SFX E я е [^и]я
1500 | SFX E я ю я
1501 | SFX E я ёй я
1502 | SFX E я ёю я
1503 | SFX E е й ее
1504 |
1505 | SFX D Y 5
1506 | SFX D ься ся иться
1507 | SFX D ться ется [ая]ться
1508 | SFX D ться ются [ая]ться
1509 | SFX D иться ятся [^жшщч]иться
1510 | SFX D иться атся [жшщч]иться
1511 |
1512 | SFX B Y 25
1513 | SFX B ыться ойтесь ыться
1514 | SFX B ыться ойся ыться
1515 | SFX B ыть ойте ыть
1516 | SFX B ыть ой ыть
1517 | SFX B ь е ить
1518 | SFX B уться итесь уться
1519 | SFX B уться ись уться
1520 | SFX B уть ите уть
1521 | SFX B уть и уть
1522 | SFX B ться тесь иться
1523 | SFX B ться сь иться
1524 | SFX B ться йтесь [аея]ться
1525 | SFX B ться йся [аея]ться
1526 | SFX B ть йте [аея]ть
1527 | SFX B ть й [аея]ть
1528 | SFX B сь тесь ись
1529 | SFX B ся тесь йся
1530 | SFX B ся тесь [^т]ься
1531 | SFX B оться итесь оться
1532 | SFX B оться ись оться
1533 | SFX B оть ите оть
1534 | SFX B оть и оть
1535 | SFX B ить и ить
1536 | SFX B 0 те [ий]
1537 | SFX B 0 те [^ст]ь
1538 |
1539 | SFX A Y 93
1540 | SFX A ый ую ый
1541 | SFX A ый ому [^ц]ый
1542 | SFX A ый ом [^ц]ый
1543 | SFX A ый ой [^ц]ый
1544 | SFX A ый ого [^ц]ый
1545 | SFX A ый ое [^ц]ый
1546 | SFX A ый ою [^ц]ый
1547 | SFX A ый ему цый
1548 | SFX A ый ем цый
1549 | SFX A ый ей цый
1550 | SFX A ый его цый
1551 | SFX A ый ее цый
1552 | SFX A ый ая ый
1553 | SFX A ой ыми [^гхкжшщч]ой
1554 | SFX A ой ым [^гхкжшщч]ой
1555 | SFX A ой ых [^гхкжшщч]ой
1556 | SFX A ой ые [^гхкжшщч]ой
1557 | SFX A ой ую ой
1558 | SFX A ой ому ой
1559 | SFX A ой ом ой
1560 | SFX A ой ого ой
1561 | SFX A ой ое ой
1562 | SFX A ой ими [гхкжшщч]ой
1563 | SFX A ой им [гхкжшщч]ой
1564 | SFX A ой их [гхкжшщч]ой
1565 | SFX A ой ие [гхкжшщч]ой
1566 | SFX A ой ая ой
1567 | SFX A й ми ый
1568 | SFX A й ми [гхк]ий
1569 | SFX A й ми [енржшщч]ий
1570 | SFX A й м ый
1571 | SFX A й м [гхк]ий
1572 | SFX A й м [енржшщч]ий
1573 | SFX A й х ый
1574 | SFX A й х [гхк]ий
1575 | SFX A й х [енржшщч]ий
1576 | SFX A й е ый
1577 | SFX A й е [гхк]ий
1578 | SFX A й е [енржшщч]ий
1579 | SFX A й ю ой
1580 | SFX A ийся уюся [шщ]ийся
1581 | SFX A ийся имся [шщ]ийся
1582 | SFX A ийся имися [шщ]ийся
1583 | SFX A ийся ихся [шщ]ийся
1584 | SFX A ийся иеся [шщ]ийся
1585 | SFX A ийся емуся [шщ]ийся
1586 | SFX A ийся емся [шщ]ийся
1587 | SFX A ийся ейся [шщ]ийся
1588 | SFX A ийся егося [шщ]ийся
1589 | SFX A ийся ееся [шщ]ийся
1590 | SFX A ийся еюся [шщ]ийся
1591 | SFX A ийся аяся [шщ]ийся
1592 | SFX A ий ую [жшщч]ий
1593 | SFX A ий ую [гхк]ий
1594 | SFX A ий яя [ен]ий
1595 | SFX A ий ому [гхк]ий
1596 | SFX A ий ом [гхк]ий
1597 | SFX A ий ой [гхк]ий
1598 | SFX A ий ого [гхк]ий
1599 | SFX A ий ое [гхк]ий
1600 | SFX A ий ою [гхк]ий
1601 | SFX A ий ему [енржшщч]ий
1602 | SFX A ий ем [енржшщч]ий
1603 | SFX A ий ей [енжшщч]ий
1604 | SFX A ий его [енржшщч]ий
1605 | SFX A ий ее [енжшщч]ий
1606 | SFX A ий ею [енжшщч]ий
1607 | SFX A ий ая [жшщч]ий
1608 | SFX A ий ая [гхк]ий
1609 | SFX A ий юю [ен]ий
1610 | SFX A е ми [иы]е
1611 | SFX A е м [иы]е
1612 | SFX A е х [иы]е
1613 | SFX A 0 ыми в
1614 | SFX A 0 ыми ин
1615 | SFX A 0 ым в
1616 | SFX A 0 ым ин
1617 | SFX A 0 ых в
1618 | SFX A 0 ых ин
1619 | SFX A 0 ы в
1620 | SFX A 0 ы ин
1621 | SFX A 0 у в
1622 | SFX A 0 у ин
1623 | SFX A 0 ому ин
1624 | SFX A 0 ом в
1625 | SFX A 0 ом ин
1626 | SFX A 0 ой в
1627 | SFX A 0 ой ин
1628 | SFX A 0 ого ин
1629 | SFX A 0 о в
1630 | SFX A 0 о ин
1631 | SFX A 0 а в
1632 | SFX A 0 а ин
1633 |
--------------------------------------------------------------------------------
/help/help.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #######################################
4 | # Print a help for given script
5 | # Arguments:
6 | # script name
7 | #######################################
8 |
9 | help=$(cat ${BASH_SOURCE%/*}/$1.md)
10 | help=${help///\\033[1m}
11 | help=${help//<\/b>/\\033[22m}
12 | help=${help//"\`\`\`"/"'"}
13 | help=${help//"\`"/"'"}
14 | help=${help//"==="/""}
15 | help=${help//"=="/""}
16 | echo -e "$help" | less -RFX
17 |
--------------------------------------------------------------------------------
/help/nancy.md:
--------------------------------------------------------------------------------
1 | DESCRIPTION
2 | ==
3 | The Nancy Command Line Interface is a unified way to manage database
4 | experiments.
5 |
6 | Nancy is a member of Postgres.ai's Artificial DBA team responsible for
7 | conducting experiments.
8 |
9 | SYNOPSYS
10 | ==
11 | nancy [parameters]
12 |
13 | AVAILABLE COMMANDS
14 | ==
15 | * help
16 | * prepare-database (WIP)
17 | * prepare-workload
18 | * run
19 |
--------------------------------------------------------------------------------
/help/nancy_prepare_workload.md:
--------------------------------------------------------------------------------
1 | COMMAND
2 | ==
3 | run
4 |
5 | DESCRIPTION
6 | ==
7 | Nancy is a member of Postgres.ai's Artificial DBA team responsible for
8 | conducting experiments.
9 |
10 | Use 'nancy prepare-workload' to prepare real-world workload based on Postgres
11 | logs from any of your real Postgres server.
12 |
13 | WIP! Not finished. More details TBD later.
14 |
15 | SEE ALSO
16 | ==
17 |
18 | nancy help
19 |
20 | nancy run help
21 |
--------------------------------------------------------------------------------
/help/nancy_run.md:
--------------------------------------------------------------------------------
1 | COMMAND
2 | ==
3 | run
4 |
5 | DESCRIPTION
6 | ===
7 | Use 'nancy run' to perform a single run for a database experiment.
8 |
9 | A DB experiment consists of one or more 'runs'. For example, if Nancy is being
10 | used to verify that a new index will affect performance only in a positive
11 | way, two runs are needed. If one needs to only collect query plans for each
12 | query group, a single run is enough. And finally, if there is a goal to find
13 | an optimal value for some PostgreSQL setting, multiple runs will be needed to
14 | check how various values of the specified setting affect performance of the
15 | specified database and workload.
16 |
17 | An experimental run needs the following 4 items to be provided as an input:
18 | * environment: hardware or cloud instance type, PostgreSQL version, etc;
19 | * database: copy or clone of the database;
20 | * workload: 'real' workload or custom SQL;
21 | * (optional) delta (a.k.a. target): some DB change to be evaluated:
22 | * PostgreSQL config changes, or
23 | * some DDL (or arbitrary SQL) such as 'CREATE INDEX ...', or
24 | * theoretically, anything else.
25 |
26 | OPTIONS
27 | ===
28 | NOTICE: A value for a string option that starts with 'file://' is treated as
29 | a path to a local file. A string value starting with 's3://' is
30 | treated as a path to remote file located in S3 (AWS S3 or analog).
31 | Otherwise, a string values is considered as 'content', not a link to
32 | a file.
33 |
34 | --debug (boolean)
35 |
36 | Turn on debug logging. This significantly increases the level of verbosity
37 | of messages being sent to STDOUT.
38 |
39 | --keep-alive (integer)
40 |
41 | How many seconds the entity (Docker container, Docker machine) will remain
42 | alive after the main activity of the run is finished. Useful for
43 | debugging (using ssh access to the container), for serialization of
44 | multiple experimental runs, for optimization of resource (re-)usage.
45 |
46 | WARNING: in clouds, use it with care to avoid unexpected expenses.
47 |
48 | --run-on (string)
49 |
50 | Where the experimental run will be performed. Allowed values:
51 |
52 | * 'localhost' (default)
53 | * 'aws'
54 | * 'gcp' (WIP, not yet implemented)
55 |
56 | If 'localhost' is specified (or --run-on is omitted), Nancy will perform the
57 | run on the localhost in a Docker container so ('docker run' must work
58 | locally).
59 |
60 | If 'aws' is specified, Nancy will use a Docker machine (EC2 Spot Instance)
61 | with a single container on it.
62 |
63 | --tmp-path (string)
64 |
65 | Path to the temporary directory on the current machine (where 'nancy run' is
66 | being invoked), to store various files while preparing them to be shipped to
67 | the experimental container/machine. Default: '/tmp'.
68 |
69 | --container-id (string)
70 |
71 | If specified, new container/machine will not be created. Instead, the existing
72 | one will be reused. This might be a significant optimization for a series of
73 | experimental runs to be executed sequentially.
74 |
75 | WARNING: This option is to be used only with read-only workloads.
76 |
77 | WIP: Currently, this option works only with '--run-on localhost'.
78 |
79 | --pg-version (string)
80 |
81 | Specify the major version of PostgreSQL. Allowed values:
82 |
83 | * '9.6'
84 | * '10'
85 | * '11'
86 | * '12' (default)
87 |
88 | Currently, there is no way to specify the minor version – it is always the
89 | most recent version, available in the official PostgreSQL APT repository (see
90 | https://www.postgresql.org/download/linux/ubuntu/).
91 |
92 | --pg-config (string)
93 |
94 | PostgreSQL config to be used (may be partial).
95 |
96 | --pg-config-auto (enum: oltp|olap)
97 |
98 | Perform "auto-tuning" for PostgreSQL config. Allowed values:
99 |
100 | * 'oltp' to auto-tune Postgres for OLTP workload,
101 | * 'olap' to auto-tune Postgres for OLAP (analytical) workload.
102 |
103 | This option can be combined with "--pg-config" – in this case, it will be
104 | applied *after* it (so "auto-tuning" values will be added to the end of
105 | the postgresql.conf file).
106 |
107 | --db-prepared-snapshot (string)
108 |
109 | Reserved / Not yet implemented.
110 |
111 | --db-dump (string)
112 |
113 | Database dump (created by pg_dump) to be used as an input. May be:
114 |
115 | * path to dump file (must start with 'file://' or 's3://'), may be:
116 | * plain dump made with 'pg_dump',
117 | * gzip-compressed plain dump ('*.gz'),
118 | * bzip2-compressed plain dump ('*.bz2'),
119 | * dump in "custom" format, made with 'pg_dump -Fc ..' ('*.pgdmp'),
120 | * sequence of SQL commands specified as in a form of plain text.
121 |
122 | --db-name (string)
123 |
124 | Name of database which must be tested. Name 'test' is internal used name,
125 | so is not correct value.
126 |
127 | --db-ebs-volume-id (string)
128 |
129 | ID of an AWS EBS volume, containing the database backup (made with pg_basebackup).
130 |
131 | In the volume's root directory, the following two files are expected:
132 | * base.tar.gz
133 | * pg_xlog.tar.gz for Postgres version up to 9.6 or pg_wal.tar.gz for Postgres 10+
134 |
135 | The following command can be used to get such files:
136 |
137 | pg_basebackup -U postgres -zPFt -Z 5 -D /path/to/ebs/volume/root
138 |
139 | Here '-Z 5' means that level 5 to be used for compression, you can choose any value from 0 to 9.
140 |
141 | --db-pgbench (string)
142 |
143 | Initialize database for pgbench. Contains pgbench init arguments:
144 |
145 | Example: `nancy run --db-pgbench "-s 100"`
146 |
147 | --db-local-pgdata
148 |
149 | Path of Postgres pgdata placed on local storage to use in experiments. All changes at database,
150 | which done during experiment will be stored.
151 |
152 | --pgdata-dir
153 |
154 | The path of Postgres pgdata is placed in local storage to use it in experiments.
155 | All changes to the database, which are done during experiments will be stored.
156 |
157 | --commands-after-container-init (string)
158 |
159 | Shell commands to be executed after the container initialization. Can be used
160 | to add additional software such as Postgres extensions not present in
161 | the main contrib package.
162 |
163 | --sql-before-db-restore (string)
164 |
165 | Additional SQL queries to be executed before the database is initiated.
166 | Applicable only when '--db-dump' is used.
167 |
168 | --sql-after-db-restore (string)
169 |
170 | Additional SQL queries to be executed once the experimental database is
171 | initiated and ready to accept connections.
172 |
173 | --workload-real (string)
174 |
175 | 'Real' workload – path to the file prepared by using 'nancy prepare-workload'.
176 |
177 | --workload-real-replay-speed (integer)
178 |
179 | The speed of replaying of the 'real workload'. Useful for stress-testing
180 | and forecasting the performance of the database under heavier workloads.
181 |
182 | --workload-custom-sql (string)
183 |
184 | SQL queries to be used as workload. These queries will be executed in a signle
185 | database session.
186 |
187 | --workload-pgbench (string)
188 |
189 | pgbench arguments to pass for tests. Ex: "-c 10 -j 4 -t 1000"
190 |
191 | --workload-basis (string)
192 |
193 | Reserved / Not yet implemented.
194 |
195 | --delta-sql-do (string)
196 |
197 | SQL changing database somehow before running workload. For example, DDL:
198 |
199 | create index i_t1_experiment on t1 using btree(col1);
200 |
201 | --delta-sql-undo (string)
202 |
203 | SQL reverting changes produced by those specified in the value of the
204 | '--delta-sql-do' option. Reverting allows to serialize multiple runs, but it
205 | might be not possible in some cases. 'UNDO SQL' example reverting index
206 | creation:
207 |
208 | drop index i_t1_experiment;
209 |
210 | --delta-config (string)
211 |
212 | Config changes to be applied to postgresql.conf before running workload.
213 | Once configuration changes are made, PostgreSQL is restarted. Example:
214 |
215 | random_page_cost = 1.1
216 |
217 | --artifacts-destination (string)
218 |
219 | Path to a local ('file://...') or S3 ('s3://...') directory where artifacts
220 | of the experimental run will be placed. Among these artifacts:
221 |
222 | * detailed performance report in JSON format
223 | * whole PostgreSQL log, gzipped
224 | * full PostgreSQL config used in this experimental run
225 |
226 | --artifacts-dirname
227 |
228 | Folder name where will be saved artifacts files.
229 |
230 | --aws-ec2-type (string)
231 |
232 | Type of EC2 instance to be used. To keep budgets low, EC2 Spot instances will
233 | be utilized and automatic detections of the lowest price in the current AZ
234 | will be performed.
235 |
236 | WARNING: 'i3-metal' instances are not currently supported (WIP).
237 |
238 | The option may be used only with '--run-on aws'.
239 |
240 | --aws-keypair-name (string)
241 |
242 | The name of key pair to be used on EC2 instance to allow ssh access. Must
243 | correspond to SSH key file specified in the '--aws-ssh-key-path' option.
244 |
245 | The option may be used only with '--run-on aws'.
246 |
247 | --aws-ssh-key-path (string)
248 |
249 | Path to SSH key file (usually, has '.pem' extension).
250 |
251 | The option may be used only with '--run-on aws'.
252 |
253 | --aws-ebs-volume-size (string)
254 |
255 | Size (in gigabytes) of EBS volume to be attached to the EC2 instance.
256 |
257 | --aws-region (string)
258 |
259 | Region for creating AWS EC2 instance
260 |
261 | --aws-zone (letter)
262 |
263 | Zone for creating AWS EC2 spot in region given by --aws-zone.
264 |
265 | --aws-zfs
266 |
267 | Attach local NVME drive to 'i3' instance and format it with ZFS.
268 | Tunning options are applied: atime=off, recordsize=8k, logbias=throughput.
269 | ARC MAX is set to 30% of RAM or at least 1GB.
270 |
271 | Otherwise, Ext4 will be used with the following options:
272 | noatime, data=writeback, barrier=0, nobh
273 |
274 | --aws-block-duration (integer)
275 |
276 | EC2 spot max live time in minutes. This value must be a multiple
277 | of 60 (60, 120, 180, 240, 300, or 360). Default value is 0 - no time limit.
278 |
279 | --s3cfg-path
280 |
281 | The path the '.s3cfg' configuration file to be used when accessing files in
282 | S3. This file must be local and must be specified if some options' values are
283 | in 's3://***' format.
284 |
285 | See also: https://github.com/s3tools/s3cmd
286 |
287 | --config
288 |
289 | The path to configuration file with description of deltas for series experiments.
290 | File expected as Yaml file, but without multiline values. File should describe
291 | array of runs like follow:
292 |
293 | run:
294 | 0:
295 | delta_ddl_do: select now(); select now();
296 | delta_ddl_undo: select now();
297 | # delta_config: max_wal_size = 2048MB
298 | 1:
299 | # delta_ddl_do: select now();
300 | # delta_ddl_undo: select now();
301 | delta_config: max_wal_size = 4092MB
302 | # 2:
303 | # delta_ddl_do: select now();
304 | # delta_ddl_undo: select now();
305 | # delta_config: max_wal_size = 4092MB
306 |
307 | For every experinment can be set three fields: delta_ddl_do, delta_ddl_undo and
308 | delta_config. If param delta_ddl_do is used then param delta_ddl_undo must be
309 | given also and vise versa. If you need enumerate several configuration params
310 | as delta_config value you should divide them by ';'
311 |
312 | --no-pgbadger
313 |
314 | Turn off use pgbadger to prepare reports.
315 |
316 | --no-perf
317 |
318 | Turn off use perf and FlameGraphs.
319 |
320 | --less-output
321 |
322 | Turn off all output besides errors and results statistic.
323 |
324 | SEE ALSO
325 | ==
326 | nancy help
327 |
--------------------------------------------------------------------------------
/nancy:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # 2018–2019 © Postgres.ai
4 | #
5 | # A wrapper for all Nancy CLI commands.
6 | # Usage: use 'nancy help' for help.
7 | #
8 |
9 | DEBUG=0
10 | cmd=""
11 |
12 | case "$1" in
13 | help )
14 | source ${BASH_SOURCE%/*}/help/help.sh "nancy"
15 | exit 1;
16 | ;;
17 | * )
18 | word="${1/-/_}"
19 | if [[ ! -f "${BASH_SOURCE%/*}/nancy_$word.sh" ]]; then
20 | >&2 echo "ERROR: Unknown command: $word."
21 | >&2 echo "Try 'nancy help'"
22 | exit 1
23 | fi
24 | cmd="${BASH_SOURCE%/*}/nancy_$word.sh"
25 | shift;
26 | ;;
27 | esac
28 |
29 | while [ -n "$1" ]; do
30 | if [ "$1" == "--debug" ]; then
31 | DEBUG=1
32 | fi
33 | if [ ${1%"${1#??}"} = '--' ]; then
34 | cmd="$cmd $1"
35 | else
36 | cmd="$cmd \"$1\""
37 | fi
38 | shift
39 | done
40 |
41 | [[ "$DEBUG" -eq "1" ]] && echo "CMD: $cmd"
42 |
43 | eval "$cmd"
44 |
--------------------------------------------------------------------------------
/nancy_describe.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # 2018–2019 © Postgres.ai
4 | #
5 | # Describe one or more experimental runs, taking
6 | # collection(s) of artifacts as input.
7 |
8 | DEBUG=false
9 | VERBOSE_OUTPUT_REDIRECT=''
10 | ARTIFACTS_PATH=''
11 |
12 | #######################################
13 | # Print a help
14 | # Globals:
15 | # None
16 | # Arguments:
17 | # None
18 | # Returns:
19 | # None
20 | #######################################
21 | function help() {
22 | echo -e "Describe results of nancy run tests. To start use:
23 | nancy describe %artifacts_directory_path%
24 | " | less -RFX
25 | }
26 |
27 | #######################################
28 | # Print an error/warning/notice message to STDERR
29 | # Globals:
30 | # None
31 | # Arguments:
32 | # (text) Error message
33 | # Returns:
34 | # None
35 | #######################################
36 | function err() {
37 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')] $@" >&2
38 | }
39 |
40 | #######################################
41 | # Print a debug-level message to STDOUT
42 | # Globals:
43 | # DEBUG
44 | # Arguments:
45 | # (text) Message
46 | # Returns:
47 | # None
48 | #######################################
49 | function dbg() {
50 | if $DEBUG ; then
51 | msg "DEBUG: $@"
52 | fi
53 | }
54 |
55 | #######################################
56 | # Print an message to STDOUT
57 | # Globals:
58 | # None
59 | # Arguments:
60 | # (text) Message
61 | # Returns:
62 | # None
63 | #######################################
64 | function msg() {
65 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')] $@"
66 | }
67 |
68 | #######################################
69 | # Print an 5 top slowest queries
70 | # Globals:
71 | # ARTIFACTS_PATH
72 | # Arguments:
73 | # (int) count of slowest queries
74 | # Returns:
75 | # None
76 | #######################################
77 | function out_top_slowest() {
78 | local top_count=$1
79 | local i=0
80 | local j=1
81 | while : ; do
82 | let j=$i+1
83 | echo -e " Slowest query #$j."
84 | duration=$(cat $FILE_PATH | jq '.top_slowest | .['$i'] | .[0]')
85 | duration="${duration/\"/}"
86 | duration="${duration/\"/}"
87 | query=$(cat $FILE_PATH | jq '.top_slowest | .['$i'] | .[2]')
88 | query="${query//'\\n'/}"
89 | query="${query//'\\\"'/'"'}" #'
90 | echo -e " Duration is: $duration ms"
91 | echo -e " Query text: $query\n"
92 | let i=$i+1
93 | [[ "$i" -eq "$top_count" ]] && break;
94 | done
95 | }
96 |
97 | #######################################
98 | # Print an durations of slowest queries in different runs
99 | # Globals:
100 | # ARTIFACTS_PATH
101 | # Arguments:
102 | # (int) count of slowest queries to analyze
103 | # Returns:
104 | # (int) 1 if is not series experiment
105 | #######################################
106 | function compare_series_slowest() {
107 | local top_count=$1
108 | # Check is series experiment
109 | if [[ ! -f "$ARTIFACTS_PATH/pgbadger.1.json" ]]; then
110 | msg "Experiment is not series."
111 | return 1
112 | fi
113 | local file_path=$ARTIFACTS_PATH/pgbadger.1.json
114 | local i=0
115 | local j=1
116 | while : ; do
117 | let j=$i+1
118 | echo -e " Slowest query #$j."
119 | duration=$(cat $file_path | jq '.top_slowest | .['$i'] | .[0]')
120 | duration="${duration/\"/}"
121 | duration="${duration/\"/}"
122 | query=$(cat $file_path | jq '.top_slowest | .['$i'] | .[2]')
123 | query_text="${query//'\\n'/}"
124 | query_text="${query_text//'\\\"'/'"'}" #'
125 | echo -e " Slowest query text: $query_text"
126 | echo -e " Run 1 duration is:\t$duration ms"
127 | local fi=2
128 | while : ; do
129 | if [[ ! -f "$ARTIFACTS_PATH/pgbadger.$fi.json" ]]; then
130 | dbg "File $ARTIFACTS_PATH/pgbadger.$fi.json not found"
131 | break
132 | fi
133 | local qi=0
134 | local fcount=$(cat $ARTIFACTS_PATH/pgbadger.$fi.json | jq '.top_slowest | length')
135 | while : ; do
136 | qduration=$(cat $ARTIFACTS_PATH/pgbadger.$fi.json | jq '.top_slowest | .['$qi'] | .[0]')
137 | qduration="${qduration/\"/}"
138 | qduration="${qduration/\"/}"
139 | qquery=$(cat $ARTIFACTS_PATH/pgbadger.$fi.json | jq '.top_slowest | .['$qi'] | .[2]')
140 | if [[ "$query" == "$qquery" ]]; then
141 | echo -e " Run $fi duration is:\t$qduration ms"
142 | fi
143 | let qi=$qi+1
144 | [[ "$qi" -eq "$fcount" ]] && break;
145 | done
146 | let fi=$fi+1
147 | done
148 | let i=$i+1
149 | [[ "$i" -eq "$top_count" ]] && break;
150 | done
151 | }
152 |
153 | while [ $# -gt 0 ]; do
154 | case "$1" in
155 | help )
156 | help
157 | exit ;;
158 | -d | --debug )
159 | DEBUG=true
160 | VERBOSE_OUTPUT_REDIRECT=''
161 | shift ;;
162 | * )
163 | option=$1
164 | option="${option##*( )}"
165 | option="${option%%*( )}"
166 | if [[ ! -d $option ]]; then
167 | err "Artifacts directory not given"
168 | exit 1
169 | else
170 | ARTIFACTS_PATH=$option
171 | fi
172 | break ;;
173 | esac
174 | done
175 |
176 | if [[ -z "$ARTIFACTS_PATH" ]]; then
177 | err "Artifacts directory not given"
178 | exit 1
179 | fi
180 |
181 | #if [[ -f "$ARTIFACTS_PATH/pgreplay.txt" ]]; then
182 | # cat "$ARTIFACTS_PATH/pgreplay.txt"
183 | #fi
184 |
185 | if [[ -f "$ARTIFACTS_PATH/pgbadger.json" ]]; then
186 | FILE_PATH=$ARTIFACTS_PATH/pgbadger.json
187 | echo -e "------------------------------------------------------------------------------"
188 | echo -e "Artifacts (collected in \"$ARTIFACTS_PATH\"):"
189 | echo -e " Postgres config: postgresql.conf"
190 | echo -e " Postgres logs: postgresql.prepare.log.gz (preparation),"
191 | echo -e " postgresql.workload.log.gz (workload)"
192 | echo -e " pgBadger reports: pgbadger.html (for humans),"
193 | echo -e " pgbadger.json (for robots)"
194 | echo -e " Stat stapshots: pg_stat_statements.csv,"
195 | echo -e " pg_stat_***.csv"
196 | echo -e " pgreplay report: pgreplay.txt"
197 | echo -e "------------------------------------------------------------------------------"
198 | echo -e "Workload:"
199 | echo -e " Total query time: "$(cat $FILE_PATH | jq '.overall_stat.queries_duration') " ms"
200 | echo -e " Queries: "$(cat $FILE_PATH | jq '.overall_stat.queries_number')
201 | echo -e " Query groups: "$(cat $FILE_PATH | jq '.normalyzed_info | length')
202 | echo -e " Errors: "$(cat $FILE_PATH | jq '.overall_stat.errors_number')
203 | echo -e " Errors groups: "$(cat $FILE_PATH | jq '.error_info | length')
204 | echo -e "------------------------------------------------------------------------------"
205 | elif [[ -f "$ARTIFACTS_PATH/pgbadger.1.json" ]]; then
206 | FILE_PATH=$ARTIFACTS_PATH/pgbadger.1.json
207 | SERIES_COUNT=2
208 | while : ; do
209 | if [[ ! -f "$ARTIFACTS_PATH/pgbadger.$SERIES_COUNT.json" ]]; then
210 | let SERIES_COUNT=$SERIES_COUNT-1
211 | break
212 | fi
213 | let SERIES_COUNT=$SERIES_COUNT+1
214 | done
215 | echo -e "------------------------------------------------------------------------------"
216 | echo -e "Runs count: $SERIES_COUNT"
217 | echo -e "Experiment artifacts collected in \"$ARTIFACTS_PATH/\"."
218 | echo -e "Postgres prepare log: postgresql.prepare.log.gz (preparation),"
219 | echo -e "------------------------------------------------------------------------------"
220 | local i=1;
221 | while : ; do
222 | FILE_PATH="$ARTIFACTS_PATH/pgbadger.$i.json"
223 | echo -e "\n"
224 | echo -e "Run $i"
225 | echo -e "------------------------------------------------------------------------------"
226 | echo -e "Run artifacts (collected in \"$ARTIFACTS_PATH\"):"
227 | echo -e " Postgres config: postgresql.$i.conf"
228 | echo -e " Postgres log: postgresql.workload.$i.log.gz (workload)"
229 | echo -e " pgBadger reports: pgbadger.$i.html (for humans),"
230 | echo -e " pgbadger.$i.json (for robots)"
231 | echo -e " Stat stapshots: pg_stat_statements.$i.csv,"
232 | echo -e " pg_stat_***.$i.csv"
233 | echo -e " pgreplay report: pgreplay.$i.txt"
234 | echo -e "------------------------------------------------------------------------------"
235 | echo -e "Workload:"
236 | echo -e " Total query time: "$(cat $FILE_PATH | jq '.overall_stat.queries_duration') " ms"
237 | echo -e " Queries: "$(cat $FILE_PATH | jq '.overall_stat.queries_number')
238 | echo -e " Query groups: "$(cat $FILE_PATH | jq '.normalyzed_info | length')
239 | echo -e " Errors: "$(cat $FILE_PATH | jq '.overall_stat.errors_number')
240 | echo -e " Errors groups: "$(cat $FILE_PATH | jq '.error_info | length')
241 | echo -e "------------------------------------------------------------------------------"
242 | let i=$i+1
243 | [[ "$i" -eq "$SERIES_COUNT" ]] && break;
244 | done
245 | fi
246 | compare_series_slowest 5
247 | if [ $? -ne 0 ]; then
248 | out_top_slowest 5
249 | fi
250 |
--------------------------------------------------------------------------------
/nancy_prepare_workload.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # 2018–2019 © Postgres.ai
4 | #
5 | # Prepare worklod file based on a full production Postgres log.
6 | #
7 |
8 | DEBUG=0
9 |
10 | ## Get command line params
11 | while true; do
12 | case "$1" in
13 | help )
14 | source ${BASH_SOURCE%/*}/help/help.sh "nancy_prepare_workload"
15 | exit ;;
16 | -d | --debug ) DEBUG=1; shift ;;
17 | --db-name )
18 | DB_NAME="$2"; shift 2 ;;
19 | --output )
20 | OUTPUT="$2"; shift 2 ;;
21 | -- )
22 | >&2 echo "ERROR: Invalid option '$1'"
23 | exit 1
24 | break ;;
25 | * )
26 | if [ "${1:0:2}" == "--" ]; then
27 | >&2 echo "ERROR: Invalid option '$1'. Please double-check options."
28 | exit 1
29 | else
30 | INPUT="$1"
31 | fi
32 | break ;;
33 | esac
34 | done
35 |
36 | if [ $DEBUG -eq 1 ]; then
37 | echo "debug: ${DEBUG}"
38 | echo "input: ${INPUT}"
39 | echo "output: ${OUTPUT}"
40 | echo "db_name: ${DB_NAME}"
41 | fi
42 |
43 | if [ -z ${INPUT+x} ]; then
44 | >&2 echo "ERROR: the input (path to Postgres log file) is not specified."
45 | exit 1;
46 | fi
47 |
48 | if [ -z ${OUTPUT+x} ]; then
49 | >&2 echo "ERROR: the output path is not specified."
50 | exit 1;
51 | fi
52 |
53 | awk_version=$((awk -Wversion 2>/dev/null || awk --version) | head -n1)
54 | if [ "${awk_version:0:3}" != "GNU" ]; then
55 | >&2 echo "ERROR: GNU awk is required. Your awk version is: ${awk_version}. Try to install gawk."
56 | exit 1;
57 | fi
58 |
59 | pgreplay_version=$(pgreplay -v 2>/dev/null)
60 | if [ "${pgreplay_version:0:8}" != "pgreplay" ]; then
61 | >&2 echo "ERROR: pgreplay is not installed."
62 | exit 1;
63 | fi
64 |
65 | bc_version=$(bc -v 2>/dev/null)
66 | if [ "${bc_version:0:2}" != "bc" ]; then
67 | >&2 echo "ERROR: bc is not installed."
68 | exit 1;
69 | fi
70 |
71 | cat $INPUT \
72 | | sed -r 's/^([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3} .*)$/\nNANCY_NEW_LINE_SEPARATOR\n\1/' \
73 | | sed "s/\"\"/NANCY_TWO_DOUBLE_QUOTES_SEPARATOR/g" \
74 | | awk -v dbname="\"$DB_NAME\"" '
75 | BEGIN {
76 | RS="\nNANCY_NEW_LINE_SEPARATOR\n";
77 | FPAT = "([^,]+)|(\"[^\"]+\")"
78 | OFS=","
79 | }
80 | {
81 | if ($3 == dbname && substr($14, 0, 11) == "\"duration: ") {
82 | duration_ms = substr($14, 0, 30)
83 | if (match($14, /^"duration: ([^ ]+) ms statement: (.*)$/, match_arr)) {
84 | duration = match_arr[1] * 1000
85 | statement = "\"statement: " match_arr[2]
86 | }
87 | "date -u -d @$(echo \"scale=6; ($(date -u --date=\"" $1 "\" +'%s%6N') - " duration \
88 | ") / 1000000\" | bc) +\"%Y-%m-%d %H:%M:%S.%6N%:::z\" | tr -d \"\\n\"" | getline res_ts
89 | print res_ts,"\"postgres\"","\"test\"",$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,statement ",,,,,,,,"
90 | }
91 | }' \
92 | | sed "s/NANCY_TWO_DOUBLE_QUOTES_SEPARATOR/\"\"/g" \
93 | | pgreplay -f -c -o "$OUTPUT"
94 |
--------------------------------------------------------------------------------
/pg_badger_parsing.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # written by Yorick
3 | #
4 | # Usage: pg_badger_parsing.sh - for parsing /var/log/postgresql/ after logrotate
5 | # pg_badger_parsing.sh postgresql.log - specifying the file
6 | #
7 | # Requires: apt-get install libjson-xs-perl
8 | #
9 |
10 | hostname=$(hostname -f)
11 | logfile=$NANCY_LOGFILE
12 |
13 | [ "$logfile" = '' ] && logfile=$1
14 |
15 | if [ ! -s ~/.s3cfg ]
16 | then
17 | project=$NANCY_PROJECT
18 | [ "$(psql -X -A -t postgres_ai -c "select s3_access_key,s3_secret_key,s3_region from project where name='$project';" 2>/dev/null | wc -l)" -ne 1 ] && echo "FAIL: project=$project is invalid, exit" && exit 1
19 | s3cfg=$(psql -X -A -t postgres_ai -c "select s3_access_key,s3_secret_key,s3_region from project where name='$project';")
20 | (echo '[default]'
21 | echo "access_key = $(echo "$s3cfg" | awk -F '|' '{print $1}')"
22 | echo "secret_key = $(echo "$s3cfg" | awk -F '|' '{print $2}')"
23 | echo "region = $(echo "$s3cfg" | awk -F '|' '{print $3}')"
24 | ) > ~/.s3cfg
25 | fi
26 |
27 | if [ "$logfile" != '' ]
28 | then
29 | [ ! -s $logfile ] && echo "FAIL: file=$file is empty or absent, exit" && exit 1
30 | pgbadger -j 4 --prefix '%t [%p]: [%l-1] db=%d,user=%u (%a,%h)' "$logfile" -f stderr -o "$logfile.json" && gzip -vf "$logfile.json" && s3cmd put "$logfile.json.gz" s3://p-dumps/${hostname}-manual/
31 | echo "Listing (on S3 storage):"
32 | s3cmd ls s3://p-dumps/${hostname}-manual/
33 | else
34 | version=postgresql-9.6-main
35 | date=$(date -d 'now' '+%Y%m%d')
36 | logdir=/var/log/postgresql
37 | pgbadger -j 4 --prefix '%t [%p]: [%l-1] db=%d,user=%u (%a,%h)' ${logdir}/${version}.log-${date}.gz -f stderr -o ${logdir}/${version}.json-${date} && gzip -vf ${logdir}/${version}.json-${date} && s3cmd put ${logdir}/${version}.*-${date}.gz s3://p-dumps/${hostname}/
38 | echo "Listing (on S3 storage):"
39 | s3cmd ls s3://p-dumps/$hostname/
40 | fi
41 |
--------------------------------------------------------------------------------
/tests/nancy_cli_run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export PATH=$PATH:${BASH_SOURCE%/*}/..
4 |
5 | output=$(nancy run --run-on aws 2>&1)
6 |
7 | if [[ $output =~ "ERROR: AWS keypair name and SSH key file must be specified to run on AWS EC2." ]]; then
8 | echo -e "\e[36mOK\e[39m"
9 | else
10 | >&2 echo -e "\e[31mFAILED\e[39m"
11 | >&2 echo -e "Output: $output"
12 | exit 1
13 | fi
14 |
--------------------------------------------------------------------------------
/tests/nancy_cli_run_no_optons.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(${BASH_SOURCE%/*}/../nancy run --run-on aws 2>&1)
4 |
5 | if [[ $output =~ "ERROR: AWS keypair name and SSH key file must be specified to run on AWS EC2." ]]; then
6 | echo -e "\e[36mOK\e[39m"
7 | else
8 | >&2 echo -e "\e[31mFAILED\e[39m"
9 | >&2 echo -e "Output: $output"
10 | exit 1
11 | fi
12 |
--------------------------------------------------------------------------------
/tests/nancy_cli_unknown.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(${BASH_SOURCE%/*}/../nancy init --run-on aws 2>&1)
4 |
5 | if [[ $output =~ "ERROR: Unknown command" ]]; then
6 | echo -e "\e[36mOK\e[39m"
7 | else
8 | >&2 echo -e "\e[31mFAILED\e[39m"
9 | >&2 echo -e "Output: $output"
10 | exit 1
11 | fi
12 |
--------------------------------------------------------------------------------
/tests/nancy_prepare_workload.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$( \
4 | ${BASH_SOURCE%/*}/../nancy prepare-workload --db-name testci \
5 | --output ./test.replay ./.circleci/sample.log \
6 | 2>&1
7 | )
8 | if [[ $output =~ "Total SQL statements processed: 2" ]]; then
9 | echo -e "\e[36mOK\e[39m"
10 | else
11 | >&2 echo -e "\e[31mFAILED\e[39m"
12 | >&2 echo -e "Output: $output"
13 | exit 1
14 | fi
15 |
16 |
--------------------------------------------------------------------------------
/tests/nancy_run_abnormal.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --commands-after-container-init "exit 1" \
12 | --db-pgbench "-s 1" \
13 | --workload-pgbench "-t 1" 2>&1
14 | )
15 |
16 | if [[ $output =~ "Check artifacts to understand the reasons." ]]; then
17 | echo -e "\e[36mOK\e[39m"
18 | else
19 | >&2 echo -e "\e[31mFAILED\e[39m"
20 | >&2 echo -e "Output: $output"
21 | exit 1
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_aws_no_keys.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(${BASH_SOURCE%/*}/../nancy_run.sh --run-on aws 2>&1)
4 |
5 | if [[ $output =~ "ERROR: AWS keypair name and SSH key file must be specified to run on AWS EC2." ]]; then
6 | echo -e "\e[36mOK\e[39m"
7 | else
8 | >&2 echo -e "\e[31mFAILED\e[39m"
9 | >&2 echo -e "Output: $output"
10 | exit 1
11 | fi
12 |
--------------------------------------------------------------------------------
/tests/nancy_run_aws_pgdata_dir.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 | if [ ! -d "$src_dir/tmp" ]; then
9 | mkdir "$src_dir/tmp"
10 | fi
11 |
12 | output=$(
13 | ${BASH_SOURCE%/*}/../nancy run \
14 | --run-on aws \
15 | --workload-custom-sql "file://$src_dir/custom.sql" \
16 | --db-dump "file://$src_dir/test.dump.sql" \
17 | --db-local-pgdata ./ \
18 | --pgdata-dir ./ \
19 | --tmp-path $src_dir/tmp 2>&1
20 | )
21 |
22 | regex="ERROR: --db-local-pgdata may be specified only for local runs"
23 | if [[ $output =~ $regex ]]; then
24 | echo -e "\e[36mOK\e[39m"
25 | else
26 | >&2 echo -e "\e[31mFAILED\e[39m"
27 | >&2 echo -e "Output: $output"
28 | exit 1
29 | fi
30 |
--------------------------------------------------------------------------------
/tests/nancy_run_aws_zfs_i3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Test ZFS on i3
4 |
5 | # TODO(vyagofarov): fix after migration to GitLab CI/CD
6 |
7 | #output=$(
8 | # bash -x ${BASH_SOURCE%/*}/../nancy run \
9 | # --run-on aws \
10 | # --aws-keypair-name awskey \
11 | # --aws-ssh-key-path /path/.ssh/awskey.pem \
12 | # --aws-ec2-type i3.large \
13 | # --db-dump "create table hello_world as select i from generate_series(1, (10)::int) _(i);" \
14 | # --workload-custom-sql "select 1" \
15 | # --no-pgbadger \
16 | # --aws-zfs \
17 | # 2>&1
18 | #)
19 | #
20 | #exit_code="$?"
21 | #
22 | #if [[ "$exit_code" -ne "0" ]]; then
23 | # echo -e "\e[31mFAILED\e[39m" >&2
24 | # echo -e "Output: $output" >&2
25 | # exit 1
26 | #else
27 | # echo -e "\e[36mOK\e[39m"
28 | #fi
29 | #
30 |
--------------------------------------------------------------------------------
/tests/nancy_run_before_init_code.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --sql-before-db-restore "select abs from beforeinittable;" \
12 | --workload-custom-sql "file://$src_dir/custom.sql" \
13 | --db-dump "file://$src_dir/test.dump.bz2" \
14 | --tmp-path $src_dir/tmp \
15 | 2>&1
16 | )
17 |
18 | if [[ $output =~ "ERROR: relation \"beforeinittable\" does not exist" ]]; then
19 | echo -e "\e[36mOK\e[39m"
20 | else
21 | >&2 echo -e "\e[31mFAILED\e[39m"
22 | >&2 echo -e "Output: $output"
23 | exit 1
24 | fi
25 |
--------------------------------------------------------------------------------
/tests/nancy_run_ebs_disk_size.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # TODO(NikolayS) -aws-ebs-volume-size requires "--run-on aws" – allow these tests in CI
4 |
5 | #output=$(
6 | # ${BASH_SOURCE%/*}/../nancy run \
7 | # --debug \
8 | # --run-on aws \
9 | # --aws-ebs-volume-size 37 \
10 | # 2>&1
11 | #)
12 | #
13 | #if [[ $output =~ "ebs-volume-size: 37" ]]; then
14 | # echo -e "\e[36mOK\e[39m"
15 | #else
16 | # >&2 echo -e "\e[31mFAILED\e[39m"
17 | # >&2 echo -e "Output: $output"
18 | # exit 1
19 | #fi
20 |
--------------------------------------------------------------------------------
/tests/nancy_run_ebs_disk_size_incorrect.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | # TODO(NikolayS) -aws-ebs-volume-size requires "--run-on aws" – allow these tests in CI
10 |
11 | #output=$(
12 | # ${BASH_SOURCE%/*}/../nancy run \
13 | # --run-on aws \
14 | # --aws-ebs-volume-size sa \
15 | # --workload-custom-sql "file://$src_dir/custom.sql" \
16 | # --db-dump "file://$src_dir/test.dump.bz2" \
17 | # --tmp-path $src_dir/tmp \
18 | # 2>&1
19 | #)
20 | #
21 | #if [[ $output =~ "ERROR: ebs-volume-size must be integer." ]]; then
22 | # echo -e "\e[36mOK\e[39m"
23 | #else
24 | # >&2 echo -e "\e[31mFAILED\e[39m"
25 | # >&2 echo -e "Output: $output"
26 | # exit 1
27 | #fi
28 |
--------------------------------------------------------------------------------
/tests/nancy_run_invalid_aws_option.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(
4 | ${BASH_SOURCE%/*}/../nancy run \
5 | --run-on localhost \
6 | --aws-keypair-name awskey \
7 | --aws-ssh-key-path /path/.ssh/awskey.pem \
8 | --aws-ec2-type i3.large \
9 | 2>&1
10 | )
11 |
12 | if [[ $output =~ "may be used only with '--run-on aws'" ]]; then
13 | echo -e "\e[36mOK\e[39m"
14 | else
15 | >&2 echo -e "\e[31mFAILED\e[39m"
16 | >&2 echo -e "Output: $output"
17 | exit 1
18 | fi
19 |
--------------------------------------------------------------------------------
/tests/nancy_run_invalid_option.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(${BASH_SOURCE%/*}/../nancy run --run-on-type test 2>&1)
4 |
5 | if [[ $output =~ "ERROR: Invalid option '--run-on-type'. Please double-check options." ]]; then
6 | echo -e "\e[36mOK\e[39m"
7 | else
8 | >&2 echo -e "\e[31mFAILED\e[39m"
9 | >&2 echo -e "Output: $output"
10 | exit 1
11 | fi
12 |
--------------------------------------------------------------------------------
/tests/nancy_run_invalid_spot_duration.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | output=$(
4 | ${BASH_SOURCE%/*}/../nancy run \
5 | --run-on aws \
6 | --aws-keypair-name awskey \
7 | --aws-ssh-key-path /path/.ssh/awskey.pem \
8 | --aws-ec2-type i3.large \
9 | --aws-block-duration 30 \
10 | 2>&1
11 | )
12 |
13 | if [[ $output =~ "ERROR: The value of '--aws-block-duration' is invalid" ]]; then
14 | echo -e "\e[36mOK\e[39m"
15 | else
16 | >&2 echo -e "\e[31mFAILED\e[39m"
17 | >&2 echo -e "Output: $output"
18 | exit 1
19 | fi
20 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_connection_str.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --db-dump "create table hello_world as select i, i as id from generate_series(1, 1000) _(i);" \
12 | --workload-real "file://$src_dir/sample.replay" \
13 | --tmp-path $src_dir/tmp 2>&1
14 | )
15 |
16 | if [[ $output =~ " How to connect to" ]]; then
17 | echo -e "\e[36mOK\e[39m"
18 | else
19 | >&2 echo -e "\e[31mFAILED\e[39m"
20 | >&2 echo -e "Output: $output"
21 | exit 1
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_less_output.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --less-output \
12 | --db-pgbench "-s 1" \
13 | --workload-pgbench "-t 1" 2>&1
14 | )
15 |
16 | if ! [[ $output =~ "LOG: Ok, generating html report..." ]]; then
17 | echo -e "\e[36mOK\e[39m"
18 | else
19 | >&2 echo -e "\e[31mFAILED\e[39m"
20 | >&2 echo -e "Output: $output"
21 | exit 1
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_norm_output.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --db-pgbench "-s 1" \
12 | --workload-pgbench "-t 1" 2>&1
13 | )
14 |
15 | if [[ $output =~ "LOG: Ok, generating html report..." ]]; then
16 | echo -e "\e[36mOK\e[39m"
17 | else
18 | >&2 echo -e "\e[31mFAILED\e[39m"
19 | >&2 echo -e "Output: $output"
20 | exit 1
21 | fi
22 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_pgbench.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --db-pgbench "-s 1" \
12 | --workload-pgbench "-t 1" 2>&1
13 | )
14 |
15 | regex="Errors:[[:blank:]]*0"
16 | if [[ $output =~ $regex ]]; then
17 | echo -e "\e[36mOK\e[39m"
18 | else
19 | >&2 echo -e "\e[31mFAILED\e[39m"
20 | >&2 echo -e "Output: $output"
21 | exit 1
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_pgdata_dir.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 | if [ ! -d "$src_dir/tmp" ]; then
9 | mkdir "$src_dir/tmp"
10 | fi
11 |
12 | output=$(
13 | ${BASH_SOURCE%/*}/../nancy run \
14 | --workload-custom-sql "file://$src_dir/custom.sql" \
15 | --db-dump "file://$src_dir/test.dump.sql" \
16 | --db-local-pgdata ./ \
17 | --pgdata-dir ./ \
18 | --tmp-path $src_dir/tmp 2>&1
19 | )
20 |
21 | regex="ERROR: Both --pgdata-dir and --db-local-pgdata are provided"
22 | if [[ $output =~ $regex ]]; then
23 | echo -e "\e[36mOK\e[39m"
24 | else
25 | >&2 echo -e "\e[31mFAILED\e[39m"
26 | >&2 echo -e "Output: $output"
27 | exit 1
28 | fi
29 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_real_workload.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --db-dump "create table hello_world as select i, i as id from generate_series(1, 1000) _(i); drop role testuser;" \
12 | --workload-real "file://$src_dir/sample.replay" \
13 | --tmp-path $src_dir/tmp 2>&1
14 | )
15 |
16 | regex="Queries:[[:blank:]]*[1-9]"
17 | if [[ $output =~ $regex ]]; then
18 | echo -e "\e[36mOK\e[39m"
19 | else
20 | >&2 echo -e "\e[31mFAILED\e[39m"
21 | >&2 echo -e "Output: $output"
22 | exit 1
23 | fi
24 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_series.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --less-output \
12 | --db-pgbench "-s 1" \
13 | --workload-pgbench "-t 1" \
14 | --config file://${BASH_SOURCE%/*}/../.circleci/run.yml 2>&1
15 | )
16 |
17 | if [[ $output =~ "Run #1 done." ]] && [[ $output =~ "Run #2 done." ]] && [[ $output =~ "Run #3 done." ]]; then
18 | echo -e "\e[36mOK\e[39m"
19 | else
20 | >&2 echo -e "\e[31mFAILED\e[39m"
21 | >&2 echo -e "Output: $output"
22 | exit 1
23 | fi
24 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_simple_dump.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | test_passed=true
3 |
4 | realpath() {
5 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
6 | }
7 |
8 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
9 |
10 | output=$(
11 | ${BASH_SOURCE%/*}/../nancy run \
12 | --workload-custom-sql "file://$src_dir/custom.sql" \
13 | --db-dump "file://$src_dir/test.dump.bz2" \
14 | --tmp-path $src_dir/tmp 2>&1
15 | )
16 |
17 | regex="Errors:[[:blank:]]*0"
18 | if [[ ! $output =~ $regex ]]; then
19 | test_passed=false
20 | fi
21 |
22 | artifacts_location=$(
23 | echo "$output" | grep "Artifacts (collected in " | awk -F"\"" '{print $2}'
24 | )
25 | if [[ ! $(grep Linux "$artifacts_location/system_info.txt") =~ ^Linux ]]; then
26 | test_passed=false
27 | fi
28 |
29 | if [[ $test_passed ]]; then
30 | echo -e "\e[36mOK\e[39m"
31 | else
32 | >&2 echo -e "\e[31mFAILED\e[39m"
33 | >&2 echo -e "Output: $output"
34 | exit 1
35 | fi
36 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_simple_dump_with_index.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 | if [ ! -d "$src_dir/tmp" ]; then
9 | mkdir "$src_dir/tmp"
10 | fi
11 |
12 | output=$(
13 | ${BASH_SOURCE%/*}/../nancy run \
14 | --workload-custom-sql "file://$src_dir/custom.sql" \
15 | --tmp-path ${src_dir}/tmp \
16 | --db-dump "file://$src_dir/test.dump.bz2" \
17 | --delta-sql-do "create index i_speedup on t1 using btree(val);" \
18 | --delta-sql-undo "drop index i_speedup;" 2>&1
19 | )
20 |
21 | regex="Errors:[[:blank:]]*0"
22 | if [[ $output =~ $regex ]]; then
23 | echo -e "\e[36mOK\e[39m"
24 | else
25 | >&2 echo -e "\e[31mFAILED\e[39m"
26 | >&2 echo -e "Output: $output"
27 | exit 1
28 | fi
29 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_simple_gz_dump.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 | if [ ! -d "$src_dir/tmp" ]; then
9 | mkdir "$src_dir/tmp"
10 | fi
11 |
12 | output=$(
13 | ${BASH_SOURCE%/*}/../nancy run \
14 | --workload-custom-sql "file://$src_dir/custom.sql" \
15 | --db-dump "file://$src_dir/test.dump.gz" \
16 | --tmp-path $src_dir/tmp 2>&1
17 | )
18 |
19 | regex="Errors:[[:blank:]]*0"
20 | if [[ $output =~ $regex ]]; then
21 | echo -e "\e[36mOK\e[39m"
22 | else
23 | >&2 echo -e "\e[31mFAILED\e[39m"
24 | >&2 echo -e "Output: $output"
25 | exit 1
26 | fi
27 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_simple_sql_dump.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 | if [ ! -d "$src_dir/tmp" ]; then
9 | mkdir "$src_dir/tmp"
10 | fi
11 |
12 | output=$(
13 | ${BASH_SOURCE%/*}/../nancy run \
14 | --workload-custom-sql "file://$src_dir/custom.sql" \
15 | --db-dump "file://$src_dir/test.dump.sql" \
16 | --tmp-path $src_dir/tmp 2>&1
17 | )
18 |
19 | regex="Errors:[[:blank:]]*0"
20 | if [[ $output =~ $regex ]]; then
21 | echo -e "\e[36mOK\e[39m"
22 | else
23 | >&2 echo -e "\e[31mFAILED\e[39m"
24 | >&2 echo -e "Output: $output"
25 | exit 1
26 | fi
27 |
--------------------------------------------------------------------------------
/tests/nancy_run_localhost_wildcards.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | realpath() {
4 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
5 | }
6 |
7 | src_dir=$(dirname $(dirname $(realpath "$0")))"/.circleci"
8 |
9 | output=$(
10 | ${BASH_SOURCE%/*}/../nancy run \
11 | --db-dump "create table t1 as select * from generate_series(1, 1000);" \
12 | --workload-custom-sql "select count(*) from t1;" \
13 | --tmp-path $src_dir/tmp 2>&1
14 | )
15 |
16 | regex="Errors:[[:blank:]]*0"
17 | if [[ $output =~ $regex ]]; then
18 | echo -e "\e[36mOK\e[39m"
19 | else
20 | >&2 echo -e "\e[31mFAILED\e[39m"
21 | >&2 echo -e "Output: $output"
22 | exit 1
23 | fi
24 |
25 |
--------------------------------------------------------------------------------
/tests/nancy_run_options_ddl_do+_undo-.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | read -r -d '' params <&1)
16 |
17 | if [[ $output =~ "must be also specified" ]]; then
18 | echo -e "\e[36mOK\e[39m"
19 | else
20 | >&2 echo -e "\e[31mFAILED\e[39m"
21 | >&2 echo -e "Output: $output"
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_options_ddl_do-_undo+.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | read -r -d '' params <&1)
16 |
17 | if [[ $output =~ "must be also specified" ]]; then
18 | echo -e "\e[36mOK\e[39m"
19 | else
20 | >&2 echo -e "\e[31mFAILED\e[39m"
21 | >&2 echo -e "Output: $output"
22 | fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_options_multi_workloads.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #read -r -d '' params <&1)
16 |
17 | #if [[ $output =~ "ERROR: 2 or more workload sources are given." ]]; then
18 | # echo -e "\e[36mOK\e[39m"
19 | #else
20 | # >&2 echo -e "\e[31mFAILED\e[39m"
21 | # >&2 echo -e "Output: $output"
22 | #fi
23 |
--------------------------------------------------------------------------------
/tests/nancy_run_options_no_dump_snapshot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | read -r -d '' params <&1)
14 |
15 | if [[ $output =~ "ERROR: The object (database) is not defined." ]]; then
16 | echo -e "\e[36mOK\e[39m"
17 | else
18 | >&2 echo -e "\e[31mFAILED\e[39m"
19 | >&2 echo -e "Output: $output"
20 | fi
21 |
--------------------------------------------------------------------------------
/tests/nancy_run_options_no_instance_type.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | params="--run-on aws --aws-keypair-name awskey --aws-ssh-key-path \"/home/someuser/.ssh/awskey.pem\""
4 | output=$(${BASH_SOURCE%/*}/../nancy_run.sh $params 2>&1)
5 |
6 | if [[ $output =~ "ERROR: AWS EC2 Instance type is not specified." ]]; then
7 | echo -e "\e[36mOK\e[39m"
8 | exit 0
9 | else
10 | >&2 echo -e "\e[31mFAILED\e[39m"
11 | >&2 echo -e "Output: $output"
12 | exit 1
13 | fi
14 |
--------------------------------------------------------------------------------
/tests/nancy_run_too_many_objects.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export PATH=$PATH:${BASH_SOURCE%/*}/..
4 |
5 | output=$(nancy run --db-dump '--' --db-local-pgdata file:///z --workload-custom-sql '--' 2>&1)
6 |
7 | if [[ $output =~ "ERROR: Too many objects (ways to get PGDATA) are specified. Please specify only one." ]]; then
8 | echo -e "\e[36mOK\e[39m"
9 | else
10 | >&2 echo -e "\e[31mFAILED\e[39m"
11 | >&2 echo -e "Output: $output"
12 | exit 1
13 | fi
14 |
--------------------------------------------------------------------------------
/tests/nancy_run_too_many_workloads.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export PATH=$PATH:${BASH_SOURCE%/*}/..
4 |
5 | output=$(nancy run --db-dump '--' --workload-custom-sql '--' --workload-pgbench '-t 1' 2>&1)
6 |
7 | if [[ $output =~ "ERROR: Too many kinds of workload are specified. Please specify only one." ]]; then
8 | echo -e "\e[36mOK\e[39m"
9 | else
10 | >&2 echo -e "\e[31mFAILED\e[39m"
11 | >&2 echo -e "Output: $output"
12 | exit 1
13 | fi
14 |
15 |
--------------------------------------------------------------------------------
/tools/meminfo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | MACHINE_HOME="/machine_home"
4 |
5 | echo "time;MemTotal,kB;MemFree,kB;Buffers,kB;Active(file),kB;Inactive(file),kB;SwapFree,kB;Shmem,kB;Slab,kB;PageTables,kB" > $MACHINE_HOME/meminfo.run.csv
6 | while true; do
7 | dt=$(date --rfc-3339=ns)
8 | echo "${dt}" >> $MACHINE_HOME/meminfo.run.log
9 | cat /proc/meminfo > $MACHINE_HOME/meminfo.log
10 | cat $MACHINE_HOME/meminfo.log >> $MACHINE_HOME/meminfo.run.log
11 | echo "" >> $MACHINE_HOME/meminfo.run.log
12 | meminfo="${dt}"
13 | for param in "MemTotal" "MemFree" "Buffers" "Active\(file\)" "Inactive\(file\)" "SwapFree" "Shmem" "Slab" "PageTables"
14 | do
15 | paramValue=$(bash -c "cat ${MACHINE_HOME}/meminfo.log | grep -P '^${param}: +.+ .+' | awk '{print \$2}'")
16 | meminfo="${meminfo};${paramValue}"
17 | done
18 | echo -e "${meminfo}" >> $MACHINE_HOME/meminfo.run.csv
19 | sleep $FREQ
20 | done;
--------------------------------------------------------------------------------
/tools/parse_yaml.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #######################################
4 | # Parse simple YAML file
5 | # Globals:
6 | # None
7 | # Arguments:
8 | # (text) path to yaml file
9 | # Returns:
10 | # None
11 | #######################################
12 | function parse_yaml() {
13 | local yaml_file=$1
14 | local prefix=$2
15 | local s
16 | local w
17 | local fs
18 |
19 | s='[[:space:]]*'
20 | w='[a-zA-Z0-9_.-]*'
21 | fs="$(echo @|tr @ '\034')"
22 |
23 | (
24 | sed -ne '/^--/s|--||g; s|\"|\\\"|g; s/\s*$//g;' \
25 | -e "/#.*[\"\']/!s| #.*||g; /^#/s|#.*||g;" \
26 | -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
27 | -e "s|^\($s\)\($w\)$s[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" |
28 | awk -F"$fs" '{
29 | indent = length($1)/2;
30 | if (length($2) == 0) { conj[indent]="+";} else {conj[indent]="";}
31 | vname[indent] = $2;
32 | for (i in vname) {if (i > indent) {delete vname[i]}}
33 | if (length($3) > 0) {
34 | vn=""; for (i=0; i&1 > /dev/null
--------------------------------------------------------------------------------
/tools/unittest/parse_yml.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ${BASH_SOURCE%/*}/../parse_yaml.sh "${BASH_SOURCE%/*}/../../.circleci/run.yml" "yml_"
4 |
5 | i=0
6 | while : ; do
7 | var_name_config="yml_run_"$i"_delta_config"
8 | delta_config=$(eval echo \$$var_name_config)
9 | delta_config=$(echo $delta_config | tr ";" "\n")
10 | var_name_ddl_do="yml_run_"$i"_delta_ddl_do"
11 | delta_ddl_do=$(eval echo \$$var_name_ddl_do)
12 | var_name_ddl_undo="yml_run_"$i"_delta_ddl_undo"
13 | delta_ddl_undo=$(eval echo \$$var_name_ddl_undo)
14 | [[ -z $delta_config ]] && [[ -z $delta_ddl_do ]] && [[ -z $delta_ddl_undo ]] && break;
15 | let j=$i*3
16 | RUNS[$j]="$delta_config"
17 | [[ -z $delta_config ]] && RUNS[$j]=""
18 | RUNS[$j+1]="$delta_ddl_do"
19 | [[ -z $delta_ddl_do ]] && RUNS[$j+1]=""
20 | RUNS[$j+2]="$delta_ddl_undo"
21 | [[ -z $delta_ddl_undo ]] && RUNS[$j+2]=""
22 | let i=i+1
23 | done
24 | # validate runs config
25 | runs_count=${#RUNS[*]}
26 | let runs_count=runs_count/3
27 |
28 | if [[ "$runs_count" -eq "3" ]] ; then
29 | echo -e "\e[36mOK\e[39m"
30 | else
31 | >&2 echo -e "\e[31mFAILED\e[39m"
32 | echo "YML runs config count: $runs_count"
33 | exit 1
34 | fi
35 |
--------------------------------------------------------------------------------