mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-02 10:36:28 +00:00
Compare commits
15 Commits
pmm-2.22.0
...
PT-1857_he
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7809e2f39f | ||
![]() |
c081a59e0d | ||
![]() |
ff6b05b381 | ||
![]() |
e731cf4d83 | ||
![]() |
442a099268 | ||
![]() |
fc4e86928b | ||
![]() |
03bd58e3a3 | ||
![]() |
d7a7a1c7a5 | ||
![]() |
1090f017a1 | ||
![]() |
a8ea8dfe56 | ||
![]() |
0aac7b4cfc | ||
![]() |
d7ece0aecc | ||
![]() |
ff8b0aff84 | ||
![]() |
db7dee46b6 | ||
![]() |
ecaaf4cc42 |
13
.travis.yml
13
.travis.yml
@@ -1,6 +1,7 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.15.x
|
||||
- 1.14.x
|
||||
- tip
|
||||
|
||||
@@ -9,6 +10,7 @@ services:
|
||||
|
||||
env:
|
||||
global:
|
||||
- GO111MODULE: "off" # TODO test with "on" too
|
||||
- DOCKER_COMPOSE_VERSION: 1.8.0
|
||||
- TEST_MONGODB_FLAVOR: mongo
|
||||
- TEST_PSMDB_VERSION: 4.0
|
||||
@@ -27,7 +29,7 @@ env:
|
||||
- TEST_MONGODB_S2_SECONDARY1_PORT: 17005
|
||||
- TEST_MONGODB_S2_SECONDARY2_PORT: 17006
|
||||
- TEST_MONGODB_CONFIGSVR_RS: csReplSet
|
||||
- TEST_MONGODB_CONFIGSVR1_PORT: 17007
|
||||
- TEST_MONGODB_CONFIGSVR1_PORT: 17007
|
||||
- TEST_MONGODB_CONFIGSVR2_PORT: 17008
|
||||
- TEST_MONGODB_CONFIGSVR3_PORT: 17009
|
||||
- TEST_MONGODB_S3_RS: rs3
|
||||
@@ -35,10 +37,10 @@ env:
|
||||
- TEST_MONGODB_S3_SECONDARY1_PORT: 17022
|
||||
- TEST_MONGODB_S3_SECONDARY2_PORT: 17023
|
||||
# REVIEWDOG_GITHUB_API_TOKEN
|
||||
- secure: "px8XYeNEAFTSTb1hYZuEOxqOXUxvp3EoU+KCtPck/KNozkoS95eBd9klgr3Os4wPKloLdMhrr0VE98lukogUxA/NmnYnos01kegjWgwwM6fkob8JxaN5KK4oUFF1wmirBlrjGlw8vUErPwINmrK4BywKpDbw6Yip6FzxdlWESHI="
|
||||
secure: "iba+2pzxc/zfMxnYki9qM9pCZs1uTEoqfPTaG9qtVr8cMutDzCJvMftn0bb6gSUrglt2mjSNhV65HX7mZl0qh8p/6a46QpzFiwZmaTH+E1tGQf97Z55tx3tHgrcoFI8LGPEHpTQehcI7V0VVo69aBhz+8lNNScOuJwt8ulyuVwE="
|
||||
|
||||
matrix:
|
||||
include:
|
||||
include:
|
||||
- MONGODB_IMAGE=mongo:3.0
|
||||
- MONGODB_IMAGE=mongo:3.2
|
||||
- MONGODB_IMAGE=mongo:3.4
|
||||
@@ -61,8 +63,9 @@ before_install:
|
||||
- docker-compose --version
|
||||
|
||||
install:
|
||||
- go get -u github.com/golang/dep/cmd/dep
|
||||
# install reviewdog and golangci-lin
|
||||
- curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
|
||||
# install reviewdog and golangci-lint
|
||||
- curl https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh| sh -s
|
||||
- curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s latest
|
||||
|
||||
|
@@ -1,5 +1,11 @@
|
||||
Changelog for Percona Toolkit
|
||||
|
||||
* Fixed bug PT-1857: pt-heartbeat cannot reconnect.
|
||||
|
||||
* Fixed bug PT-169 : pt-online-schema-change FKs error handling.
|
||||
* Fixed bug PT-1892: pt-summary says sshd not running
|
||||
* Fixed bug PT-1881: pt-upgrade fails when query including format strings and SQL errors is given (Thanks Nayuta Yanagisawa)
|
||||
|
||||
* Fixed bug PT-1859: pt-pg-summary fails for Postgres12 (Thanks Sergey Kuzmichev)
|
||||
* Improvement PT-1853: Added --no-check-foreing-keys to pt-osc
|
||||
* Improvement PT-1851: Backslashes missing from documentation
|
||||
|
45
Gopkg.lock
generated
45
Gopkg.lock
generated
@@ -202,7 +202,15 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:55dcddb2ba6ab25098ee6b96f176f39305f1fde7ea3d138e7e10bb64a5bf45be"
|
||||
digest = "1:9d1d58facb0409ecf634fec680d83b6f57f4e619458f7b7b5e4dda1665fd89ec"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = ["log"]
|
||||
pruneopts = ""
|
||||
revision = "f39dfa2b000545b3a763b844012958c275a62266"
|
||||
version = "v0.13.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9d35a914be9b807050704f377becb1f864ee46b000f590566a8b9fb871d6c571"
|
||||
name = "github.com/shirou/gopsutil"
|
||||
packages = [
|
||||
"cpu",
|
||||
@@ -212,16 +220,8 @@
|
||||
"process",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "e4ec7b275ada47ca32799106c2dba142d96aaf93"
|
||||
version = "v2.19.8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:99c6a6dab47067c9b898e8c8b13d130c6ab4ffbcc4b7cc6236c2cd0b1e344f5b"
|
||||
name = "github.com/shirou/w32"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "bb4de0191aa41b5507caa14b0650cdbddcd9280b"
|
||||
revision = "9aa2bee419e8b592ecf9f46018f3f1f6a5474c10"
|
||||
version = "v2.20.8"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1a405cddcf3368445051fb70ab465ae99da56ad7be8d8ca7fc52159d1c2d873c"
|
||||
@@ -324,6 +324,8 @@
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
"windows/registry",
|
||||
"windows/svc/eventlog",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "749cb33beabd9aa6d3178e3de05bcc914f70b2bf"
|
||||
@@ -343,6 +345,25 @@
|
||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||
version = "v0.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:15d017551627c8bb091bde628215b2861bed128855343fdd570c62d08871f6e1"
|
||||
name = "gopkg.in/alecthomas/kingpin.v2"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "947dcec5ba9c011838740e680966fd7087a71d0d"
|
||||
version = "v2.2.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
digest = "1:e56755c5336ff37d20befca76df29097085c85ea1fe58af746e3df6b815decfa"
|
||||
name = "gopkg.in/mgo.v2"
|
||||
packages = [
|
||||
"bson",
|
||||
"internal/json",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "a6b53ec6cb22a3699387a57a161566f9402ee85b"
|
||||
|
||||
[[projects]]
|
||||
branch = "v3"
|
||||
digest = "1:2e9c4d6def1d36dcd17730e00c06b49a2e97ea5e1e639bcd24fa60fa43e33ad6"
|
||||
@@ -368,6 +389,7 @@
|
||||
"github.com/pborman/getopt",
|
||||
"github.com/percona/go-mysql/query",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/prometheus/common/log",
|
||||
"github.com/shirou/gopsutil/process",
|
||||
"github.com/sirupsen/logrus",
|
||||
"github.com/stretchr/testify/assert",
|
||||
@@ -377,6 +399,7 @@
|
||||
"go.mongodb.org/mongo-driver/mongo",
|
||||
"go.mongodb.org/mongo-driver/mongo/options",
|
||||
"golang.org/x/crypto/ssh/terminal",
|
||||
"gopkg.in/mgo.v2/bson",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@@ -24,4 +24,4 @@
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/shirou/gopsutil"
|
||||
version = "2.17.11"
|
||||
version = "2.20.8"
|
||||
|
@@ -5947,6 +5947,7 @@ sub main {
|
||||
|
||||
$dbh->{InactiveDestroy} = 1; # Don't disconnect on fork
|
||||
$dbh->{FetchHashKeyName} = 'NAME_lc';
|
||||
$dbh->{mysql_auto_reconnect} = 1;
|
||||
$dbh->do("USE `$db`");
|
||||
|
||||
# ########################################################################
|
||||
|
@@ -8788,6 +8788,7 @@ sub main {
|
||||
my $flow_ctl_pr; # Progress for FlowControlWaiter
|
||||
my $sys_load; # MySQLStatusWaiter object
|
||||
my $sys_load_pr; # Progress for MySQLStatusWaiter object
|
||||
my $process_error; # Used if drop_swap fails
|
||||
|
||||
if ( $o->get('execute') ) {
|
||||
# #####################################################################
|
||||
@@ -9150,7 +9151,7 @@ sub main {
|
||||
}
|
||||
# No child tables and --alter-fk-method wasn't specified,
|
||||
# so nothing to do.
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "Child tables:\n";
|
||||
foreach my $child_table ( @$child_tables ) {
|
||||
@@ -9414,6 +9415,9 @@ sub main {
|
||||
. "cause MySQL error 1146 (42S02): \"Table $new_tbl->{name} "
|
||||
. " doesn't exist\".\n";
|
||||
}
|
||||
elsif ($process_error) {
|
||||
print "Not dropping new table because FKs processing has failed.\n";
|
||||
}
|
||||
else {
|
||||
print ts("Dropping new table...\n");
|
||||
print $sql, "\n" if $o->get('print');
|
||||
@@ -10208,8 +10212,9 @@ sub main {
|
||||
}
|
||||
};
|
||||
if ( $EVAL_ERROR ) {
|
||||
# TODO: improve error message and handling.
|
||||
_die("Error updating foreign key constraints: $EVAL_ERROR", ERROR_UPDATING_FKS);
|
||||
#$oktorun = 0;
|
||||
$process_error = "Error updating foreign key constraints: $EVAL_ERROR";
|
||||
_die($process_error, ERROR_UPDATING_FKS);
|
||||
}
|
||||
|
||||
# --plugin hook
|
||||
@@ -10273,7 +10278,8 @@ sub main {
|
||||
# ########################################################################
|
||||
# Done.
|
||||
# ########################################################################
|
||||
$orig_tbl->{success} = 1; # flag for cleanup tasks
|
||||
|
||||
$orig_tbl->{success} = 1; # flag for cleanup tasks
|
||||
$cleanup = undef; # exec cleanup tasks
|
||||
|
||||
# --plugin hook
|
||||
|
@@ -1278,7 +1278,7 @@ top_processes () { local PTFUNCNAME=top_processes;
|
||||
|
||||
notable_processes_info () { local PTFUNCNAME=notable_processes_info;
|
||||
local format="%5s %+2d %s\n"
|
||||
local sshd_pid=$(ps -eo pid,args | awk '$2 ~ /\/usr\/sbin\/sshd/ { print $1; exit }')
|
||||
local sshd_pid=$(ps -eo pid,args | awk '$0 ~ /\/usr\/sbin\/sshd/ { print $1; exit }')
|
||||
|
||||
echo " PID OOM COMMAND"
|
||||
|
||||
|
@@ -6159,7 +6159,7 @@ sub _print_failures {
|
||||
foreach my $failure ( @$failures ) {
|
||||
print "\n-- $failno.\n";
|
||||
if ( ($failure->[1] || '') eq ($failure->[2] || '') ) {
|
||||
printf "\nOn both hosts:\n\n" . ($failure->[1] || '') . "\n";
|
||||
print "\nOn both hosts:\n\n" . ($failure->[1] || '') . "\n";
|
||||
}
|
||||
else {
|
||||
printf "\n%s\n\nvs.\n\n%s\n",
|
||||
|
@@ -1,6 +1,28 @@
|
||||
Percona Toolkit
|
||||
***************
|
||||
|
||||
|
||||
|
||||
v3.2.1 released 2020-08-13
|
||||
==========================
|
||||
|
||||
Improvements:
|
||||
|
||||
* :jirabug:`PT-1836`: Review and consider lintian reported issues (Thanks to user midget for reporting this issue)
|
||||
|
||||
Bugs Fixed:
|
||||
|
||||
* :jirabug:`PT-1853`: Added --no-check-foreign-keys to pt-osc
|
||||
* :jirabug:`PT-1869`: pt-osc dynamically update slave list on check slaves (Thanks to user mateus.dubiela for reporting this issue)
|
||||
* :jirabug:`PT-1829`: pt-heartbeat doesn't reconnect for check-read-only
|
||||
* :jirabug:`PT-1822`: pt-mongodb-summary fails on standalone mongodb instances
|
||||
* :jirabug:`PT-1851`: Backslashes missing from documentation (Thanks to user billkarwin for reporting this issue)
|
||||
* :jirabug:`PT-1518`: pt-table-checksum gives error CRC32 never needs BIT_XOR optimization (Thanks to user soumya_s_das (AT homedepot DOT com) for reporting this issue)
|
||||
* :jirabug:`PT-1859`: pt-pg-summary fails for Postgres12
|
||||
|
||||
|
||||
|
||||
|
||||
v3.2.0 released 2020-04-23
|
||||
==========================
|
||||
|
||||
@@ -59,7 +81,7 @@ Bugs Fixed:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
v3.0.13 released 2019-01-03
|
||||
===========================
|
||||
|
||||
@@ -445,7 +467,7 @@ New Features
|
||||
|
||||
* 1642994: Following schemas/tables have been added to the default ignore list: ``mysql.gtid_execution``, ``sys.sys_config``, ``mysql.proc``, ``mysql.inventory``, ``mysql.plugin``, ``percona.*`` (including checksums, dsns table), ``test.*``, and ``percona_schema.*``.
|
||||
|
||||
* 1643940: ``pt-summary`` now provides information about Transparent huge pages.
|
||||
* 1643940: ``pt-summary`` now provides information about Transparent huge pages.
|
||||
|
||||
* 1604834: New ``--preserve-embedded-numbers`` option has been implemented for ``pt-query-digest`` which can be used to preserve numbers in database/table names when fingerprinting queries.
|
||||
|
||||
@@ -454,7 +476,7 @@ Bug Fixes
|
||||
* 1613915: ``pt-online-schema-change`` could miss the data due to the way ENUM values are sorted.
|
||||
|
||||
* 1625005: ``pt-online-schema-change`` didn't apply underscores to foreign keys individually.
|
||||
|
||||
|
||||
* 1566556: ``pt-show-grants`` didn't work correctly with *MariaDB* 10 (*Daniël van Eeden*).
|
||||
|
||||
* 1634900: ``pt-upgrade`` would fail when log contained ``SELECT...INTO`` queries.
|
||||
@@ -469,19 +491,19 @@ Changelog
|
||||
---------
|
||||
|
||||
* Fixed bug 1362942: pt-slave-restart fails on MariaDB 10.0.13 (gtid_mode confusion)
|
||||
* Fixed bug 1566556: pt-show-grants fails against MariaDB10+
|
||||
* Fixed bug 1566556: pt-show-grants fails against MariaDB10+
|
||||
* Feature 1604834: pt-query-digest numbers in table or column names converted to question marks (--preserve-embedded-numbers)
|
||||
* Fixed bug 1613915: pt-online-schema-change misses data. Fixed sort order for ENUM fields
|
||||
* Fixed bug 1613915: pt-online-schema-change misses data. Fixed sort order for ENUM fields
|
||||
* Fixed bug 1625005: pt-online-schema-change doesn't apply underscores to foreign keys individually
|
||||
* Fixed bug 1634900: pt-upgrade fails with SELECT INTO
|
||||
* Fixed bug 1635734: pt-slave-restart --config does not recognize = as separator
|
||||
* Fixed bug 1634900: pt-upgrade fails with SELECT INTO
|
||||
* Fixed bug 1635734: pt-slave-restart --config does not recognize = as separator
|
||||
* Feature 1636068: Added pause to NibbleIterator
|
||||
* Feature 1638293: --data-dir parameter in order to create the table on a different partition
|
||||
* Feature 1639052: with pt-table-checksum automatically exclude checking schemas named percona, percona_schema
|
||||
* Feature 1639052: with pt-table-checksum automatically exclude checking schemas named percona, percona_schema
|
||||
* Feature 1642364: pt-online-schema-change Added --remove-data-dir feature
|
||||
* Feature 1643914: Fixed several typos in the doc (Thanks Dario Minnucci)
|
||||
* Feature 1643940: Add Transparent huge pages info to pt-summary
|
||||
* Feature 1643941: Add Memory management library to pt-mysql-summary
|
||||
* Feature 1643941: Add Memory management library to pt-mysql-summary
|
||||
|
||||
v2.2.19 released 2016-08-16
|
||||
===========================
|
||||
@@ -548,7 +570,7 @@ New features:
|
||||
* 1553340: Added "Shared" memory info to ``pt-summary``
|
||||
|
||||
* PT-24: Added the ``--no-vertical-format`` option for ``pt-query-digest``, allowing compatibility with non-standard MySQL clients that don't support the ``\G`` directive at the end of a statement
|
||||
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* 1402776: Fixed error when parsing ``tcpdump`` capture with ``pt-query-digest``
|
||||
@@ -674,7 +696,7 @@ v2.2.15 released 2015-08-28
|
||||
This feature was requested in the following bugs: 1413101 and 1413137.
|
||||
|
||||
* Added the ``--sleep`` option for ``pt-online-schema-change`` to avoid performance problems. The option accepts float values in seconds.
|
||||
|
||||
|
||||
This feature was requested in the following bug: 1413140.
|
||||
|
||||
* Implemented ability to specify ``--check-slave-lag`` multiple times. The following example enables lag checks for two slaves:
|
||||
@@ -686,69 +708,69 @@ v2.2.15 released 2015-08-28
|
||||
This feature was requested in the following bug: 14452911.
|
||||
|
||||
* Added the ``--rds`` option to ``pt-kill``, which makes the tool use Amazon RDS procedure calls instead of the standard MySQL ``kill`` command.
|
||||
|
||||
|
||||
This feature was requested in the following bug: 1470127.
|
||||
|
||||
**Bugs Fixed**
|
||||
|
||||
* 1042727: ``pt-table-checksum`` doesn't reconnect the slave $dbh
|
||||
|
||||
|
||||
Before, the tool would die if any slave connection was lost. Now the tool waits forever for slaves.
|
||||
|
||||
* 1056507: ``pt-archiver --check-slave-lag`` agressiveness
|
||||
|
||||
|
||||
The tool now checks replication lag every 100 rows instead of every row, which significantly improves efficiency.
|
||||
|
||||
* 1215587: Adding underscores to constraints when using ``pt-online-schema-change`` can create issues with constraint name length
|
||||
|
||||
|
||||
Before, multiple schema changes lead to underscores stacking up on the name of the constraint until it reached the 64 character limit. Now there is a limit of two underscores in the prefix, then the tool alternately removes or adds one underscore, attempting to make the name unique.
|
||||
|
||||
* 1277049: ``pt-online-schema-change`` can't connect with comma in password
|
||||
|
||||
|
||||
For all tools, documented that commas in passwords provided on the command line must be escaped.
|
||||
|
||||
* 1441928: Unlimited chunk size when using ``pt-online-schema-change`` with ``--chunk-size-limit=0`` inhibits checksumming of single-nibble tables
|
||||
|
||||
|
||||
When comparing table size with the slave table, the tool now ignores ``--chunk-size-limit`` if it is set to zero to avoid multiplying by zero.
|
||||
|
||||
* 1443763: Update documentation and/or implentation of ``pt-archiver --check-interval``
|
||||
|
||||
|
||||
Fixed the documentation for ``--check-interval`` to reflect its correct behavior.
|
||||
|
||||
* 1449226: ``pt-archiver`` dies with "MySQL server has gone away" when ``--innodb_kill_idle_transaction`` is set to a low value and ``--check-slave-lag`` is enabled
|
||||
|
||||
The tool now sends a dummy SQL query to avoid timing out.
|
||||
|
||||
The tool now sends a dummy SQL query to avoid timing out.
|
||||
|
||||
* 1446928: ``pt-online-schema-change`` not reporting meaningful errors
|
||||
|
||||
|
||||
The tool now produces meaningful errors based on text from MySQL errors.
|
||||
|
||||
* 1450499: ReadKeyMini causes ``pt-online-schema-change`` session to lock under some circumstances
|
||||
|
||||
|
||||
Removed ReadKeyMini, because it is no longer necessary.
|
||||
|
||||
* 1452914: ``--purge`` and ``--no-delete`` are mutually exclusive, but still allowed to be specified together by ``pt-archiver``
|
||||
|
||||
|
||||
The tool now issues an error when ``--purge`` and ``--no-delete`` are specified together
|
||||
|
||||
* 1455486: ``pt-mysql-summary`` is missing the ``--ask-pass`` option
|
||||
|
||||
|
||||
Added the ``--ask-pass`` option to the tool
|
||||
|
||||
* 1457573: ``pt-sift`` fails to download ``pt-diskstats`` ``pt-pmp`` ``pt-mext`` ``pt-align``
|
||||
|
||||
|
||||
Added the ``-L`` option to ``curl`` and changed download address to use HTTPS.
|
||||
|
||||
* 1462904: ``pt-duplicate-key-checker`` doesn't support triple quote in column name
|
||||
|
||||
|
||||
Updated TableParser module to handle literal backticks.
|
||||
|
||||
* 1488600: ``pt-stalk`` doesn't check TokuDB status
|
||||
|
||||
|
||||
Implemented status collection similar to how it is performed for InnoDB.
|
||||
|
||||
* 1488611: various testing bugs related to newer perl versions
|
||||
|
||||
|
||||
Fixed test failures related to new Perl versions.
|
||||
|
||||
v2.2.14 released 2015-04-14
|
||||
@@ -758,7 +780,7 @@ Percona Toolkit 2.2.14 has been released. This release contains two new features
|
||||
|
||||
New Features:
|
||||
|
||||
* pt-slave-find can now resolve the IP address and show the slave's hostname. This can be done with the new ``--resolve-address`` option.
|
||||
* pt-slave-find can now resolve the IP address and show the slave's hostname. This can be done with the new ``--resolve-address`` option.
|
||||
|
||||
* pt-table-sync can now ignore the tables whose names match specific Perl regex with the ``--ignore-tables-regex`` option.
|
||||
|
||||
@@ -778,7 +800,7 @@ Bugs Fixed:
|
||||
|
||||
* Fixed bug 1417558: pt-stalk when used along with ``--collect-strace`` didn't write the strace output to the expected destination file.
|
||||
|
||||
* Fixed bug 1421025: Missing dependency for ``perl-TermReadKey`` RPM package was causing toolkit commands to fail when they were run with ``--ask-pass`` option.
|
||||
* Fixed bug 1421025: Missing dependency for ``perl-TermReadKey`` RPM package was causing toolkit commands to fail when they were run with ``--ask-pass`` option.
|
||||
|
||||
* Fixed bug 1421781: pt-upgrade would fail when log contained ``SELECT...INTO`` queries. Fixed by ignoring/skipping those queries.
|
||||
|
||||
@@ -815,11 +837,11 @@ Percona Toolkit 2.2.13 has been released. This release contains one new feature
|
||||
|
||||
New Features:
|
||||
|
||||
* pt-kill now supports new ``--query-id`` option. This option can be used to print a query fingerprint hash after killing a query to enable the cross-referencing with the pt-query-digest output. This option can be used along with ``--print`` option as well.
|
||||
* pt-kill now supports new ``--query-id`` option. This option can be used to print a query fingerprint hash after killing a query to enable the cross-referencing with the pt-query-digest output. This option can be used along with ``--print`` option as well.
|
||||
|
||||
Bugs Fixed:
|
||||
|
||||
* Fixed bug 1019479: pt-table-checksum now works with ``ONLY_FULL_GROUP_BY`` sql_mode.
|
||||
* Fixed bug 1019479: pt-table-checksum now works with ``ONLY_FULL_GROUP_BY`` sql_mode.
|
||||
|
||||
* Fixed bug 1394934: running pt-table-checksum in debug mode would cause an error.
|
||||
|
||||
@@ -829,9 +851,9 @@ Bugs Fixed:
|
||||
|
||||
* Fixed bug 1408375: Percona Toolkit was vulnerable to MITM attack which could allow exfiltration of MySQL configuration information via ``--version-check`` option. This vulnerability was logged as `CVE 2015-1027 <http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2015-1027>_`
|
||||
|
||||
* Fixed bug 1321297: pt-table-checksum was reporting differences on timestamp columns with replication from 5.5 to 5.6 server version, although the data was identical.
|
||||
* Fixed bug 1321297: pt-table-checksum was reporting differences on timestamp columns with replication from 5.5 to 5.6 server version, although the data was identical.
|
||||
|
||||
* Fixed bug 1388870: pt-table-checksum was showing differences if the master and slave were in different time zone.
|
||||
* Fixed bug 1388870: pt-table-checksum was showing differences if the master and slave were in different time zone.
|
||||
|
||||
* Fixed bug 1402668: pt-mysql-summary would exit if Percona XtraDB Cluster was in ``Donor/Desynced`` state.
|
||||
|
||||
@@ -840,19 +862,19 @@ Bugs Fixed:
|
||||
Changelog
|
||||
---------
|
||||
|
||||
* Feature 1391240: pt-kill added query fingerprint hash to output
|
||||
* Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
|
||||
* Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
|
||||
* Feature 1391240: pt-kill added query fingerprint hash to output
|
||||
* Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
|
||||
* Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
|
||||
* Fixed bug 1396868: pt-online-schema-change --ask-pass option error
|
||||
* Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
|
||||
* Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
|
||||
* Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
|
||||
* Fixed bug 1394934: pt-table-checksum error in debug mode
|
||||
* Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
|
||||
* Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
|
||||
* Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
|
||||
* Fixed bug 1388870: pt-table-checksum has some errors with different time zones
|
||||
* Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
|
||||
* Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
|
||||
* Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
|
||||
* Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
|
||||
* Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
|
||||
|
||||
v2.2.12 released 2014-11-14
|
||||
===========================
|
||||
@@ -861,7 +883,7 @@ Percona Toolkit 2.2.12 has been released. This release contains one new feature
|
||||
|
||||
New Features:
|
||||
|
||||
* pt-stalk now gathers ``dmesg`` output from up to 60 seconds before the triggering event.
|
||||
* pt-stalk now gathers ``dmesg`` output from up to 60 seconds before the triggering event.
|
||||
|
||||
Bugs Fixed:
|
||||
|
||||
@@ -873,7 +895,7 @@ Bugs Fixed:
|
||||
|
||||
* Fixed bug 1328686: Running pt-hearbeat with --check-read-only option would cause an error when running on server with ``read_only`` option. Tool now waits for server ``read_only`` status to be disabled before starting to run.
|
||||
|
||||
* Fixed bug 1373937: pt-table-checksum now supports ``none`` as valid ``--recursion-method`` when using with Percona XtraDB Cluster.
|
||||
* Fixed bug 1373937: pt-table-checksum now supports ``none`` as valid ``--recursion-method`` when using with Percona XtraDB Cluster.
|
||||
|
||||
* Fixed bug 1377888: Documentation was stating that pt-query-digest is able to parse a raw binary log file, while it can only parse a file which was decoded with ``mysqlbinlog`` tool before. Fixed by improving the documentation and adding a check for binary file and providing a relevant error message.
|
||||
|
||||
@@ -886,7 +908,7 @@ Changelog
|
||||
* Fixed bug 1217466: pt-table-checksum refuses to run on PXC if server_id is the same on all nodes
|
||||
* Fixed bug 1373937: pt-table-checksum requires recursion when working with and XtraDB Cluster node
|
||||
* Fixed bug 1377888: pt-query-digest manual for --type binlog is ambiguous
|
||||
* Fixed bug 1349086: pt-stalk should also gather dmesg output
|
||||
* Fixed bug 1349086: pt-stalk should also gather dmesg output
|
||||
* Fixed bug 1361293: Some scripts fail when no-version-check option is put in global config file
|
||||
|
||||
v2.2.11 released 2014-09-26
|
||||
@@ -939,12 +961,12 @@ Bugs Fixed:
|
||||
Changelog
|
||||
---------
|
||||
|
||||
* Fixed bug 1287253: pt-table-checksum deadlock
|
||||
* Fixed bug 1287253: pt-table-checksum deadlock
|
||||
* Fixed bug 1299387: 5.6 slow query log Thead_id becomes Id
|
||||
* Fixed bug 1311654: pt-table-checksum + PXC inconsistent results upon --resume
|
||||
* Fixed bug 1340728: pt-online-schema-change doesn't work with HASH indexes
|
||||
* Fixed bug 1253872: pt-table-checksum max load 20% rounds down
|
||||
* Fixed bug 1340364: some shell tools output error when queried for --version
|
||||
* Fixed bug 1340364: some shell tools output error when queried for --version
|
||||
|
||||
v2.2.9 released 2014-07-08
|
||||
==========================
|
||||
@@ -967,10 +989,10 @@ Changelog
|
||||
---------
|
||||
|
||||
* Fixed bug 1258135: pt-deadlock-logger introduces a noise to MySQL
|
||||
* Fixed bug 1329422: pt-online-schema-change foreign-keys-method=none breaks constraints
|
||||
* Fixed bug 1315130: pt-online-schema-change not properly detecting foreign keys
|
||||
* Fixed bug 1329422: pt-online-schema-change foreign-keys-method=none breaks constraints
|
||||
* Fixed bug 1315130: pt-online-schema-change not properly detecting foreign keys
|
||||
* Fixed bug 1335960: pt-query-digest cannot parse binlogs from 5.6
|
||||
* Fixed bug 1335322: pt-stalk fails when variable or threshold is non-integer
|
||||
* Fixed bug 1335322: pt-stalk fails when variable or threshold is non-integer
|
||||
|
||||
v2.2.8 released 2014-06-04
|
||||
==========================
|
||||
@@ -992,7 +1014,7 @@ Bugs Fixed:
|
||||
|
||||
* Fixed bug 1286250: pt-online-schema-change was requesting password twice.
|
||||
|
||||
* Fixed bug 1295667: pt-deadlock-logger was logging incorrect timestamp because tool wasn't aware of the time-zones.
|
||||
* Fixed bug 1295667: pt-deadlock-logger was logging incorrect timestamp because tool wasn't aware of the time-zones.
|
||||
|
||||
* Fixed bug 1304062: when multiple tables were specified with pt-table-checksum --ignore-tables, only one of them would be ignored.
|
||||
|
||||
@@ -1016,7 +1038,7 @@ Changelog
|
||||
v2.2.7 released 2014-02-20
|
||||
==========================
|
||||
|
||||
Percona Toolkit 2.2.7 has been released. This release has only one bug fix.
|
||||
Percona Toolkit 2.2.7 has been released. This release has only one bug fix.
|
||||
|
||||
* Fixed bug 1279502: --version-check behaves like spyware
|
||||
|
||||
@@ -1130,9 +1152,9 @@ Changelog
|
||||
v2.2.4 released 2013-07-18
|
||||
==========================
|
||||
|
||||
Percona Toolkit 2.2.4 has been released. This release two new features and a number of bugfixes.
|
||||
Percona Toolkit 2.2.4 has been released. This release two new features and a number of bugfixes.
|
||||
|
||||
pt-query-digest --output json includes query examples as of v2.2.3. Some people might not want this because it exposes real data. New option, --output json-anon, has been implemented. This option will provide the same data without query examples. It's "anonymous" in the sense that there's no identifying data; nothing more than schema and table structs can be inferred from fingerprints.
|
||||
pt-query-digest --output json includes query examples as of v2.2.3. Some people might not want this because it exposes real data. New option, --output json-anon, has been implemented. This option will provide the same data without query examples. It's "anonymous" in the sense that there's no identifying data; nothing more than schema and table structs can be inferred from fingerprints.
|
||||
|
||||
When using drop swap with pt-online-schema-change there is some production impact. This impact can be measured because tool outputs the current timestamp on lines for operations that may take awhile.
|
||||
|
||||
@@ -1140,7 +1162,7 @@ When using drop swap with pt-online-schema-change there is some production impac
|
||||
pt-table-checksum would fail if variable explicit_defaults_for_timestamp was enabled in MySQL 5.6.
|
||||
|
||||
* Fixed bug #1182856: Zero values causes "Invalid --set-vars value: var=0"
|
||||
Trying to assign 0 to any variable by using --set-vars option would cause “Invalid --set-vars value” message.
|
||||
Trying to assign 0 to any variable by using --set-vars option would cause “Invalid --set-vars value” message.
|
||||
|
||||
* Fixed bug #1188264: pt-online-schema-change error copying rows: Undefined subroutine &pt_online_schema_change::get
|
||||
|
||||
@@ -1844,7 +1866,7 @@ Changelog
|
||||
* Fixed bug 954990: pt-stalk --nostalk does not work
|
||||
* Fixed bug 977226: pt-summary doesn't detect LSI RAID control
|
||||
* Fixed bug 1030031: pt-table-checksum reports wrong number of DIFFS
|
||||
* Fixed bug 916168: pt-table-checksum privilege check fails on MySQL 5.5
|
||||
* Fixed bug 916168: pt-table-checksum privilege check fails on MySQL 5.5
|
||||
* Fixed bug 950294: pt-table-checksum should always create schema and tables with IF NOT EXISTS
|
||||
* Fixed bug 953141: pt-table-checksum ignores its default and explicit --recursion-method
|
||||
* Fixed bug 1030975: pt-table-sync crashes if sql_mode includes ANSI_QUOTES
|
||||
@@ -2204,7 +2226,7 @@ Changelog
|
||||
* Fixed bug 1402776: Improved fix (protocol parser fix): error when parsing tcpdump capture with pt-query-digest
|
||||
* Fixed bug 1632522: pt-osc: Fails with duplicate key in table for self-referencing (Thanks Amiel Marqeta)
|
||||
* Fixed bug 1654668: pt-summary exists with an error (Thanks Marcelo Altmann)
|
||||
* New tool : pt-mongodb-summary
|
||||
* New tool : pt-mongodb-summary
|
||||
* New tool : pt-mongodb-query-digest
|
||||
|
||||
Percona Toolkit 3.0.0 RC includes the following changes:
|
||||
|
28
docs/rn.3-2-1.txt
Normal file
28
docs/rn.3-2-1.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
.. _PT-3.2.1:
|
||||
|
||||
================================================================================
|
||||
*Percona Toolkit* 3.2.1
|
||||
================================================================================
|
||||
|
||||
:Date: August 13, 2020
|
||||
:Installation: `Installing Percona Toolkit <https://www.percona.com/doc/percona-toolkit/LATEST/installation.html>`_
|
||||
|
||||
Improvements
|
||||
================================================================================
|
||||
|
||||
* :jirabug:`PT-1836`: Review and consider lintian reported issues (Thanks to user midget for reporting this issue)
|
||||
|
||||
|
||||
|
||||
Bugs Fixed
|
||||
================================================================================
|
||||
|
||||
* :jirabug:`PT-1853`: Added --no-check-foreign-keys to pt-osc
|
||||
* :jirabug:`PT-1869`: pt-osc dynamically update slave list on check slaves (Thanks to user mateus.dubiela for reporting this issue)
|
||||
* :jirabug:`PT-1829`: pt-heartbeat doesn't reconnect for check-read-only
|
||||
* :jirabug:`PT-1822`: pt-mongodb-summary fails on standalone mongodb instances
|
||||
* :jirabug:`PT-1851`: Backslashes missing from documentation (Thanks to user billkarwin for reporting this issue)
|
||||
* :jirabug:`PT-1518`: pt-table-checksum gives error CRC32 never needs BIT_XOR optimization (Thanks to user soumya_s_das@homedepot.com for reporting this issue)
|
||||
* :jirabug:`PT-1859`: pt-pg-summary fails for Postgres12
|
||||
|
||||
|
40
go.mod
Normal file
40
go.mod
Normal file
@@ -0,0 +1,40 @@
|
||||
module github.com/percona/percona-toolkit
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver v1.4.2
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible
|
||||
github.com/go-ini/ini v1.46.0
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf // indirect
|
||||
github.com/google/go-cmp v0.5.2 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/hashicorp/go-version v1.2.1-0.20190424083514-192140e6f3e6
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c
|
||||
github.com/klauspost/compress v1.10.10 // indirect
|
||||
github.com/lib/pq v1.2.0
|
||||
github.com/mattn/go-shellwords v1.0.6
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe
|
||||
github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3
|
||||
github.com/percona/go-mysql v0.0.0-20190903141930-197f4ad8db8d
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/common v0.13.0
|
||||
github.com/shirou/gopsutil v2.20.8+incompatible
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/xdg/stringprep v1.0.1-0.20180714160509-73f8eece6fdc // indirect
|
||||
go.mongodb.org/mongo-driver v1.3.4
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/ini.v1 v1.61.0 // indirect
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||
mvdan.cc/gofumpt v0.0.0-20200927160801-5bfeb2e70dd6 // indirect
|
||||
)
|
539
go.sum
Normal file
539
go.sum
Normal file
@@ -0,0 +1,539 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ini/ini v1.46.0 h1:hDJFfs/9f75875scvqLkhNB5Jz5/DybKEOZ5MLF+ng4=
|
||||
github.com/go-ini/ini v1.46.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
|
||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
|
||||
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
|
||||
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
|
||||
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
|
||||
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
|
||||
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
|
||||
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
|
||||
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 h1:tT8iWCYw4uOem71yYA3htfH+LNopJvcqZQshm56G5L4=
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws=
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.1-0.20190424083514-192140e6f3e6 h1:rL76JewpeImeqMtpkAHVZkHrXWt6B5sGSj6sAsL0VnI=
|
||||
github.com/hashicorp/go-version v1.2.1-0.20190424083514-192140e6f3e6/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
|
||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
|
||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3 h1:YtFkrqsMEj7YqpIhRteVxJxCeC3jJBieuLr0d4C4rSA=
|
||||
github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/percona/go-mysql v0.0.0-20190903141930-197f4ad8db8d h1:ZkztfR4jYDnkFQtZfwMVm9z7wkK/WiCXRQ7l1CB1/1M=
|
||||
github.com/percona/go-mysql v0.0.0-20190903141930-197f4ad8db8d/go.mod h1:/SGLf9OMxlnK6jq4mkFiImBcJXXk5jwD+lDrwDaGXcw=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.13.0 h1:vJlpe9wPgDRM1Z+7Wj3zUUjY1nr6/1jNKyl7llliccg=
|
||||
github.com/prometheus/common v0.13.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
|
||||
github.com/shirou/gopsutil v2.20.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xdg/stringprep v1.0.1-0.20180714160509-73f8eece6fdc h1:vIp1tjhVogU0yBy7w96P027ewvNPeH6gzuNcoc+NReU=
|
||||
github.com/xdg/stringprep v1.0.1-0.20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE=
|
||||
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6 h1:qKpj8TpV+LEhel7H/fR788J+KvhWZ3o3V6N2fU/iuLU=
|
||||
golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 h1:rbvTkL9AkFts1cgI78+gG6Yu1pwaqX6hjSJAatB78E4=
|
||||
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
|
||||
gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
mvdan.cc/gofumpt v0.0.0-20200927160801-5bfeb2e70dd6 h1:z+/YqapuV7VZPvBb3GYmuEJbA88M3PFUxaHilHYVCpQ=
|
||||
mvdan.cc/gofumpt v0.0.0-20200927160801-5bfeb2e70dd6/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
@@ -405,7 +405,7 @@ sub _print_failures {
|
||||
foreach my $failure ( @$failures ) {
|
||||
print "\n-- $failno.\n";
|
||||
if ( ($failure->[1] || '') eq ($failure->[2] || '') ) {
|
||||
printf "\nOn both hosts:\n\n" . ($failure->[1] || '') . "\n";
|
||||
print "\nOn both hosts:\n\n" . ($failure->[1] || '') . "\n";
|
||||
}
|
||||
else {
|
||||
printf "\n%s\n\nvs.\n\n%s\n",
|
||||
|
@@ -138,8 +138,8 @@ test: ## Run tests
|
||||
@./runtests.sh
|
||||
|
||||
format: ## Format source code.
|
||||
gofmt -w -s $(FILES)
|
||||
goimports -local github.com/percona/pmm-managed -l -w $(FILES)
|
||||
gofumpt -w -s $(FILES)
|
||||
gofumports -local github.com/percona/pmm-managed -l -w $(FILES)
|
||||
|
||||
vet: ## Run vet on Go code
|
||||
@echo ">> vetting code"
|
||||
|
@@ -1,11 +1,16 @@
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -143,30 +148,70 @@ func BaseDir() string {
|
||||
}
|
||||
|
||||
basedir = strings.TrimSpace(string(out))
|
||||
|
||||
return basedir
|
||||
}
|
||||
|
||||
// GetMongoDBAddr returns the address of an instance by replicaset name and instance type like
|
||||
// (rs1, primary) or (rs1, secondary1)
|
||||
// (rs1, primary) or (rs1, secondary1).
|
||||
func GetMongoDBAddr(rs, name string) string {
|
||||
if _, ok := hosts[rs]; !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
replset := hosts[rs]
|
||||
|
||||
if host, ok := replset[name]; ok {
|
||||
return host
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetMongoDBReplsetAddrs return the addresses of all instances for a replicaset name
|
||||
// GetMongoDBReplsetAddrs return the addresses of all instances for a replicaset name.
|
||||
func GetMongoDBReplsetAddrs(rs string) []string {
|
||||
addrs := []string{}
|
||||
|
||||
if _, ok := hosts[rs]; !ok {
|
||||
return addrs
|
||||
}
|
||||
|
||||
for _, host := range hosts[rs] {
|
||||
addrs = append(addrs, host)
|
||||
}
|
||||
|
||||
return addrs
|
||||
}
|
||||
|
||||
// TestClient returns a new MongoDB connection to the specified server port.
|
||||
func TestClient(ctx context.Context, port string) (*mongo.Client, error) {
|
||||
if port == "" {
|
||||
port = MongoDBShard1PrimaryPort
|
||||
}
|
||||
|
||||
hostname := "127.0.0.1"
|
||||
direct := true
|
||||
to := time.Second
|
||||
co := &options.ClientOptions{
|
||||
ConnectTimeout: &to,
|
||||
Hosts: []string{net.JoinHostPort(hostname, port)},
|
||||
Direct: &direct,
|
||||
Auth: &options.Credential{
|
||||
Username: MongoDBUser,
|
||||
Password: MongoDBPassword,
|
||||
PasswordSet: true,
|
||||
},
|
||||
}
|
||||
|
||||
client, err := mongo.Connect(ctx, co)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = client.Ping(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
@@ -75,10 +75,8 @@ func DefaultConfigFiles(toolName string) ([]string, error) {
|
||||
}
|
||||
|
||||
func DefaultConfig(toolname string) *Config {
|
||||
|
||||
files, _ := DefaultConfigFiles(toolname)
|
||||
return NewConfig(files...)
|
||||
|
||||
}
|
||||
|
||||
func NewConfig(files ...string) *Config {
|
||||
@@ -94,7 +92,6 @@ func NewConfig(files ...string) *Config {
|
||||
}
|
||||
|
||||
func read(filename string, opts map[string]interface{}) error {
|
||||
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -135,7 +132,7 @@ func read(filename string, opts map[string]interface{}) error {
|
||||
}
|
||||
|
||||
if f == float64(int64(f)) {
|
||||
opts[key] = int64(f) //int64
|
||||
opts[key] = int64(f) // int64
|
||||
continue
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
)
|
||||
|
||||
func TestReadConfig(t *testing.T) {
|
||||
|
||||
rootPath, err := tutil.RootPath()
|
||||
if err != nil {
|
||||
t.Errorf("cannot get root path: %s", err)
|
||||
@@ -69,7 +68,6 @@ func TestReadConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOverrideConfig(t *testing.T) {
|
||||
|
||||
rootPath, err := tutil.RootPath()
|
||||
if err != nil {
|
||||
t.Errorf("cannot get root path: %s", err)
|
||||
@@ -131,7 +129,6 @@ func TestOverrideConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDefaultFiles(t *testing.T) {
|
||||
|
||||
user, _ := user.Current()
|
||||
toolname := "pt-testing"
|
||||
|
||||
@@ -150,5 +147,4 @@ func TestDefaultFiles(t *testing.T) {
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("got %#v\nwant: %#v\n", got, want)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/percona/percona-toolkit/src/go/pt-pg-summary/models"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/percona/percona-toolkit/src/go/pt-pg-summary/models"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shirou/gopsutil/process"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@@ -108,17 +108,15 @@ func LoadBson(filename string, destination interface{}) error {
|
||||
}
|
||||
|
||||
func WriteJson(filename string, data interface{}) error {
|
||||
|
||||
buf, err := json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filename, buf, 0777)
|
||||
err = ioutil.WriteFile(filename, buf, 0o777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func ShouldUpdateSamples() bool {
|
||||
|
@@ -12,7 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func TestCheckUpdates(t *testing.T) {
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
m := strings.Split(string(body), ";")
|
||||
@@ -39,11 +38,9 @@ func TestCheckUpdates(t *testing.T) {
|
||||
if msg == "" {
|
||||
t.Error("got empty response")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEmptyResponse(t *testing.T) {
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "")
|
||||
}))
|
||||
@@ -57,5 +54,4 @@ func TestEmptyResponse(t *testing.T) {
|
||||
if msg != "" {
|
||||
t.Error("response should return error due to empty body")
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,10 +11,8 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
var (
|
||||
// DocsBufferSize is the buffer size to store documents from the MongoDB profiler
|
||||
DocsBufferSize = 100
|
||||
)
|
||||
// DocsBufferSize is the buffer size to store documents from the MongoDB profiler
|
||||
var DocsBufferSize = 100
|
||||
|
||||
// Profiler interface
|
||||
type Profiler interface {
|
||||
|
@@ -34,9 +34,11 @@ type OpLogs []OplogInfo
|
||||
func (s OpLogs) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s OpLogs) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s OpLogs) Less(i, j int) bool {
|
||||
return s[i].TimeDiffHours < s[j].TimeDiffHours
|
||||
}
|
||||
|
30
src/go/mongolib/proto/procinfo.go
Normal file
30
src/go/mongolib/proto/procinfo.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package proto
|
||||
|
||||
import "time"
|
||||
|
||||
type ProcInfo struct {
|
||||
CreateTime time.Time
|
||||
Path string
|
||||
UserName string
|
||||
Error error
|
||||
}
|
||||
|
||||
type GetHostInfo struct {
|
||||
Hostname string
|
||||
HostOsType string
|
||||
HostSystemCPUArch string
|
||||
HostDatabases int
|
||||
HostCollections int
|
||||
DBPath string
|
||||
|
||||
ProcPath string
|
||||
ProcUserName string
|
||||
ProcCreateTime time.Time
|
||||
ProcProcessCount int
|
||||
|
||||
// Server Status
|
||||
ProcessName string
|
||||
ReplicasetName string
|
||||
Version string
|
||||
NodeType string
|
||||
}
|
@@ -4,8 +4,11 @@ import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ReplicaSetConfigTags map[string]string
|
||||
type GetLastErrorModes map[string]*ReplicaSetConfigTags
|
||||
type (
|
||||
ReplicaSetConfigTags map[string]string
|
||||
|
||||
GetLastErrorModes map[string]*ReplicaSetConfigTags
|
||||
)
|
||||
|
||||
// https://docs.mongodb.com/v3.2/reference/command/getLastError/#dbcmd.getLastError
|
||||
type GetLastErrorDefaults struct {
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package proto
|
||||
|
||||
import "go.mongodb.org/mongo-driver/bson/primitive"
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
const (
|
||||
REPLICA_SET_MEMBER_STARTUP = iota
|
||||
@@ -48,3 +51,83 @@ type ReplicaSetStatus struct {
|
||||
Ok float64 `bson:"ok"` //
|
||||
Set string `bson:"set"` // Replica set name
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
Host string `bson:"host"`
|
||||
Votes int32 `bson:"votes"`
|
||||
ID int32 `bson:"_id"`
|
||||
SlaveDelay int64 `bson:"slaveDelay"`
|
||||
Priority float64 `bson:"priority"`
|
||||
BuildIndexes bool `bson:"buildIndexes"`
|
||||
ArbiterOnly bool `bson:"arbiterOnly"`
|
||||
Hidden bool `bson:"hidden"`
|
||||
Tags bson.M `bson:"tags"`
|
||||
}
|
||||
|
||||
type RSConfig struct {
|
||||
ID string `bson:"_id"`
|
||||
ConfigServer bool `bson:"configsvr"`
|
||||
WriteConcernMajorityJournalDefault bool `bson:"writeConcernMajorityJournalDefault"`
|
||||
Version int32 `bson:"version"`
|
||||
ProtocolVersion int64 `bson:"protocolVersion"`
|
||||
Settings RSSettings `bson:"settings"`
|
||||
Members []Member `bson:"members"`
|
||||
}
|
||||
|
||||
type LastErrorDefaults struct {
|
||||
W int32 `bson:"w"`
|
||||
WTimeout int32 `bson:"wtimeout"`
|
||||
}
|
||||
|
||||
type RSSettings struct {
|
||||
HeartbeatTimeoutSecs int32 `bson:"heartbeatTimeoutSecs"`
|
||||
ElectionTimeoutMillis int32 `bson:"electionTimeoutMillis"`
|
||||
CatchUpTimeoutMillis int32 `bson:"catchUpTimeoutMillis"`
|
||||
GetLastErrorModes bson.M `bson:"getLastErrorModes"`
|
||||
ChainingAllowed bool `bson:"chainingAllowed"`
|
||||
HeartbeatIntervalMillis int32 `bson:"heartbeatIntervalMillis"`
|
||||
CatchUpTakeoverDelayMillis int32 `bson:"catchUpTakeoverDelayMillis"`
|
||||
GetLastErrorDefaults LastErrorDefaults `bson:"getLastErrorDefaults"`
|
||||
ReplicaSetID primitive.ObjectID `bson:"replicaSetId"`
|
||||
}
|
||||
|
||||
type Signature struct {
|
||||
Hash primitive.Binary `bson:"hash"`
|
||||
KeyID int64 `bson:"keyId"`
|
||||
}
|
||||
|
||||
type ClusterTime struct {
|
||||
ClusterTime primitive.Timestamp `bson:"clusterTime"`
|
||||
Signature Signature `bson:"signature"`
|
||||
}
|
||||
|
||||
type ReplicasetConfig struct {
|
||||
Config RSConfig `bson:"config"`
|
||||
OK float64 `bson:"ok"`
|
||||
LastCommittedOpTime primitive.Timestamp `bson:"lastCommittedOpTime"`
|
||||
ClusterTime ClusterTime `bson:"$clusterTime"`
|
||||
OperationTime primitive.Timestamp `bson:"operationTime"`
|
||||
}
|
||||
|
||||
type ConfigVersion struct {
|
||||
ID int32 `bson:"_id"`
|
||||
MinCompatibleVersion int32 `bson:"minCompatibleVersion"`
|
||||
CurrentVersion int32 `bson:"currentVersion"`
|
||||
ClusterID primitive.ObjectID `bson:"clusterId"`
|
||||
}
|
||||
|
||||
type ShardIdentity struct {
|
||||
ID string `bson:"_id"`
|
||||
ShardName string `bson:"shardName"`
|
||||
ClusterID primitive.ObjectID `bson:"clusterId"`
|
||||
ConfigsvrConnectionString string `bson:"configsvrConnectionString"`
|
||||
}
|
||||
|
||||
// MyState is a subset of getDiagnosticData result used to tag metrics in the MongoDB exporter
|
||||
type MyState struct {
|
||||
Data struct {
|
||||
ReplicasetGetStatus struct {
|
||||
MyState int `bson:"myState"`
|
||||
} `bson:"replSetGetStatus"`
|
||||
} `bson:"data"`
|
||||
}
|
||||
|
@@ -2,23 +2,39 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/common/log"
|
||||
"github.com/shirou/gopsutil/process"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
const (
|
||||
TypeIsDBGrid = "isdbgrid"
|
||||
TypeMongos = "mongos"
|
||||
TypeMongod = "mongod"
|
||||
TypeShardServer = "shardsvr"
|
||||
|
||||
milliToSeconds = 1000
|
||||
shardingNotEnabledErrorCode = 203
|
||||
ErrNotYetInitialized = int32(94)
|
||||
ErrNoReplicationEnabled = int32(76)
|
||||
)
|
||||
|
||||
var (
|
||||
CannotGetQueryError = errors.New("cannot get query field from the profile document (it is not a map)")
|
||||
ShardingNotEnabledError = errors.New("sharding not enabled")
|
||||
|
||||
ErrCannotGetProcess = fmt.Errorf("cannot get process")
|
||||
ErrCannotGetClusterID = fmt.Errorf("cannot get cluster ID")
|
||||
)
|
||||
|
||||
func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOptions) ([]proto.Members, error) {
|
||||
@@ -26,6 +42,7 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot get a new client for GetReplicasetMembers")
|
||||
}
|
||||
|
||||
if err := client.Connect(ctx); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot connect to MongoDB")
|
||||
}
|
||||
@@ -34,6 +51,7 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := client.Disconnect(ctx); err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot disconnect from %v", clientOptions.Hosts)
|
||||
}
|
||||
@@ -54,7 +72,10 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
cmdOpts := proto.CommandLineOptions{}
|
||||
// Not always we can get this info. For examples, we cannot get this for hidden hosts so
|
||||
// if there is an error, just ignore it
|
||||
res := client.Database("admin").RunCommand(ctx, primitive.D{{"getCmdLineOpts", 1}, {"recordStats", 1}})
|
||||
res := client.Database("admin").RunCommand(ctx, primitive.D{
|
||||
{Key: "getCmdLineOpts", Value: 1},
|
||||
{Key: "recordStats", Value: 1},
|
||||
})
|
||||
if res.Err() == nil {
|
||||
if err := res.Decode(&cmdOpts); err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot decode getCmdLineOpts response for host %s", hostname)
|
||||
@@ -62,6 +83,7 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
}
|
||||
|
||||
rss := proto.ReplicaSetStatus{}
|
||||
|
||||
res = client.Database("admin").RunCommand(ctx, primitive.M{"replSetGetStatus": 1})
|
||||
if res.Err() != nil {
|
||||
m := proto.Members{
|
||||
@@ -73,26 +95,34 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
m.ID = serverStatus.Pid
|
||||
m.StorageEngine = serverStatus.StorageEngine
|
||||
}
|
||||
|
||||
membersMap[m.Name] = m
|
||||
|
||||
continue // If a host is a mongos we cannot get info but is not a real error
|
||||
}
|
||||
|
||||
if err := res.Decode(&rss); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode replSetGetStatus response")
|
||||
}
|
||||
|
||||
for _, m := range rss.Members {
|
||||
if _, ok := membersMap[m.Name]; ok {
|
||||
continue // already exists
|
||||
}
|
||||
|
||||
m.Set = rss.Set
|
||||
|
||||
if serverStatus, err := GetServerStatus(ctx, client); err == nil {
|
||||
m.ID = serverStatus.Pid
|
||||
m.StorageEngine = serverStatus.StorageEngine
|
||||
|
||||
if cmdOpts.Parsed.Sharding.ClusterRole != "" {
|
||||
m.StateStr = cmdOpts.Parsed.Sharding.ClusterRole + "/" + m.StateStr
|
||||
}
|
||||
|
||||
m.StateStr = strings.ToUpper(m.StateStr)
|
||||
}
|
||||
|
||||
membersMap[m.Name] = m
|
||||
}
|
||||
|
||||
@@ -104,30 +134,36 @@ func GetReplicasetMembers(ctx context.Context, clientOptions *options.ClientOpti
|
||||
}
|
||||
|
||||
sort.Slice(members, func(i, j int) bool { return members[i].Name < members[j].Name })
|
||||
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func GetHostnames(ctx context.Context, client *mongo.Client) ([]string, error) {
|
||||
// Probably we are connected to an individual member of a replica set
|
||||
rss := proto.ReplicaSetStatus{}
|
||||
|
||||
res := client.Database("admin").RunCommand(ctx, primitive.M{"replSetGetStatus": 1})
|
||||
if res.Err() == nil {
|
||||
if err := res.Decode(&rss); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode replSetGetStatus response for GetHostnames")
|
||||
}
|
||||
|
||||
return buildHostsListFromReplStatus(rss), nil
|
||||
}
|
||||
|
||||
// Try getShardMap first. If we are connected to a mongos it will return
|
||||
// all hosts, including config hosts
|
||||
var shardsMap proto.ShardsMap
|
||||
|
||||
smRes := client.Database("admin").RunCommand(ctx, primitive.M{"getShardMap": 1})
|
||||
if smRes.Err() != nil {
|
||||
if e, ok := smRes.Err().(mongo.CommandError); ok && e.Code == shardingNotEnabledErrorCode {
|
||||
return nil, ShardingNotEnabledError // standalone instance
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(smRes.Err(), "cannot getShardMap for GetHostnames")
|
||||
}
|
||||
|
||||
if err := smRes.Decode(&shardsMap); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode getShardMap result for GetHostnames")
|
||||
}
|
||||
@@ -145,48 +181,47 @@ func GetHostnames(ctx context.Context, client *mongo.Client) ([]string, error) {
|
||||
return nil, nil // standalone instance
|
||||
}
|
||||
|
||||
/*
|
||||
"members" : [
|
||||
{
|
||||
"_id" : 0,
|
||||
"name" : "localhost:17001",
|
||||
"health" : 1,
|
||||
"state" : 1,
|
||||
"stateStr" : "PRIMARY",
|
||||
"uptime" : 4700,
|
||||
"optime" : Timestamp(1486554836, 1),
|
||||
"optimeDate" : ISODate("2017-02-08T11:53:56Z"),
|
||||
"electionTime" : Timestamp(1486651810, 1),
|
||||
"electionDate" : ISODate("2017-02-09T14:50:10Z"),
|
||||
"configVersion" : 1,
|
||||
"self" : true
|
||||
},
|
||||
*/
|
||||
func buildHostsListFromReplStatus(replStatus proto.ReplicaSetStatus) []string {
|
||||
/*
|
||||
"members" : [
|
||||
{
|
||||
"_id" : 0,
|
||||
"name" : "localhost:17001",
|
||||
"health" : 1,
|
||||
"state" : 1,
|
||||
"stateStr" : "PRIMARY",
|
||||
"uptime" : 4700,
|
||||
"optime" : Timestamp(1486554836, 1),
|
||||
"optimeDate" : ISODate("2017-02-08T11:53:56Z"),
|
||||
"electionTime" : Timestamp(1486651810, 1),
|
||||
"electionDate" : ISODate("2017-02-09T14:50:10Z"),
|
||||
"configVersion" : 1,
|
||||
"self" : true
|
||||
},
|
||||
*/
|
||||
|
||||
hostnames := []string{}
|
||||
for _, member := range replStatus.Members {
|
||||
hostnames = append(hostnames, member.Name)
|
||||
}
|
||||
|
||||
sort.Strings(hostnames) // to make testing easier
|
||||
|
||||
return hostnames
|
||||
}
|
||||
|
||||
/* Example
|
||||
mongos> db.getSiblingDB('admin').runCommand('getShardMap')
|
||||
{
|
||||
"map" : {
|
||||
"config" : "localhost:19001,localhost:19002,localhost:19003",
|
||||
"localhost:17001" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
"r1" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
"r1/localhost:17001,localhost:17002,localhost:17003" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
},
|
||||
"ok" : 1
|
||||
}.
|
||||
*/
|
||||
func buildHostsListFromShardMap(shardsMap proto.ShardsMap) []string {
|
||||
/* Example
|
||||
mongos> db.getSiblingDB('admin').runCommand('getShardMap')
|
||||
{
|
||||
"map" : {
|
||||
"config" : "localhost:19001,localhost:19002,localhost:19003",
|
||||
"localhost:17001" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
"r1" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
"r1/localhost:17001,localhost:17002,localhost:17003" : "r1/localhost:17001,localhost:17002,localhost:17003",
|
||||
},
|
||||
"ok" : 1
|
||||
}
|
||||
*/
|
||||
|
||||
hostnames := []string{}
|
||||
hm := make(map[string]bool)
|
||||
|
||||
@@ -197,10 +232,11 @@ func buildHostsListFromShardMap(shardsMap proto.ShardsMap) []string {
|
||||
for _, val := range shardsMap.Map {
|
||||
m := strings.Split(val, "/")
|
||||
hostsStr := ""
|
||||
|
||||
switch len(m) {
|
||||
case 1:
|
||||
hostsStr = m[0] // there is no / in the hosts list
|
||||
case 2:
|
||||
case 2: //nolint
|
||||
hostsStr = m[1] // there is a / in the string. Remove the prefix until the / and keep the rest
|
||||
}
|
||||
// since there is no Sets in Go, build a map where the value is the map key
|
||||
@@ -209,33 +245,39 @@ func buildHostsListFromShardMap(shardsMap proto.ShardsMap) []string {
|
||||
hm[host] = false
|
||||
}
|
||||
}
|
||||
|
||||
for host := range hm {
|
||||
hostnames = append(hostnames, host)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(hostnames)
|
||||
|
||||
return hostnames
|
||||
}
|
||||
|
||||
// GetShardedHosts is like GetHostnames but it uses listShards instead of getShardMap
|
||||
// so it won't include config servers in the returned list
|
||||
// so it won't include config servers in the returned list.
|
||||
func GetShardedHosts(ctx context.Context, client *mongo.Client) ([]string, error) {
|
||||
shardsInfo := &proto.ShardsInfo{}
|
||||
|
||||
res := client.Database("admin").RunCommand(ctx, primitive.M{"listShards": 1})
|
||||
if res.Err() != nil {
|
||||
return nil, errors.Wrap(res.Err(), "cannot list shards")
|
||||
}
|
||||
|
||||
if err := res.Decode(&shardsInfo); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode listShards response")
|
||||
}
|
||||
|
||||
hostnames := []string{}
|
||||
|
||||
for _, shardInfo := range shardsInfo.Shards {
|
||||
m := strings.Split(shardInfo.Host, "/")
|
||||
h := strings.Split(m[1], ",")
|
||||
hostnames = append(hostnames, h[0])
|
||||
}
|
||||
|
||||
return hostnames, nil
|
||||
}
|
||||
|
||||
@@ -248,6 +290,7 @@ func GetServerStatus(ctx context.Context, client *mongo.Client) (proto.ServerSta
|
||||
{Key: "recordStats", Value: 1},
|
||||
}
|
||||
res := client.Database("admin").RunCommand(ctx, query)
|
||||
|
||||
if res.Err() != nil {
|
||||
return ss, errors.Wrap(res.Err(), "GetHostInfo.serverStatus")
|
||||
}
|
||||
@@ -265,14 +308,17 @@ func GetQueryField(doc proto.SystemProfile) (primitive.M, error) {
|
||||
// however MongoDB 3.0 doesn't have that field
|
||||
// so we need to detect protocol by looking at actual data.
|
||||
query := doc.Query
|
||||
if len(doc.Command) > 0 {
|
||||
|
||||
if len(doc.Command) > 0 { //nolint
|
||||
query = doc.Command
|
||||
|
||||
if doc.Op == "update" || doc.Op == "remove" {
|
||||
if squery, ok := query.Map()["q"]; ok {
|
||||
// just an extra check to ensure this type assertion won't fail
|
||||
if ssquery, ok := squery.(primitive.M); ok {
|
||||
return ssquery, nil
|
||||
}
|
||||
|
||||
return nil, CannotGetQueryError
|
||||
}
|
||||
}
|
||||
@@ -309,6 +355,7 @@ func GetQueryField(doc proto.SystemProfile) (primitive.M, error) {
|
||||
if ssquery, ok := squery.(primitive.M); ok {
|
||||
return ssquery, nil
|
||||
}
|
||||
|
||||
return nil, CannotGetQueryError
|
||||
}
|
||||
|
||||
@@ -317,6 +364,7 @@ func GetQueryField(doc proto.SystemProfile) (primitive.M, error) {
|
||||
if ssquery, ok := squery.(primitive.M); ok {
|
||||
return ssquery, nil
|
||||
}
|
||||
|
||||
return nil, CannotGetQueryError
|
||||
}
|
||||
|
||||
@@ -333,5 +381,173 @@ func GetQueryField(doc proto.SystemProfile) (primitive.M, error) {
|
||||
func GetClientForHost(co *options.ClientOptions, newHost string) (*mongo.Client, error) {
|
||||
newOptions := options.MergeClientOptions(co, &options.ClientOptions{Hosts: []string{newHost}})
|
||||
newOptions.SetDirect(true)
|
||||
|
||||
return mongo.NewClient(newOptions)
|
||||
}
|
||||
|
||||
func GetHostInfo(ctx context.Context, client *mongo.Client) (*proto.GetHostInfo, error) {
|
||||
hi := proto.HostInfo{}
|
||||
if err := client.Database("admin").RunCommand(ctx, primitive.M{"hostInfo": 1}).Decode(&hi); err != nil {
|
||||
log.Debugf("run('hostInfo') error: %s", err)
|
||||
return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
|
||||
}
|
||||
|
||||
cmdOpts := proto.CommandLineOptions{}
|
||||
query := primitive.D{{Key: "getCmdLineOpts", Value: 1}, {Key: "recordStats", Value: 1}}
|
||||
|
||||
err := client.Database("admin").RunCommand(ctx, query).Decode(&cmdOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot get command line options")
|
||||
}
|
||||
|
||||
ss := proto.ServerStatus{}
|
||||
query = primitive.D{{Key: "serverStatus", Value: 1}, {Key: "recordStats", Value: 1}}
|
||||
|
||||
if err := client.Database("admin").RunCommand(ctx, query).Decode(&ss); err != nil {
|
||||
return nil, errors.Wrap(err, "GetHostInfo.serverStatus")
|
||||
}
|
||||
|
||||
pi := proto.ProcInfo{}
|
||||
if err := fillProcInfo(int32(ss.Pid), &pi); err != nil {
|
||||
pi.Error = err
|
||||
}
|
||||
|
||||
nodeType, _ := getNodeType(ctx, client)
|
||||
procCount, _ := countMongodProcesses()
|
||||
|
||||
i := &proto.GetHostInfo{
|
||||
Hostname: hi.System.Hostname,
|
||||
HostOsType: hi.Os.Type,
|
||||
HostSystemCPUArch: hi.System.CpuArch,
|
||||
DBPath: "", // Sets default. It will be overridden later if necessary
|
||||
|
||||
ProcessName: ss.Process,
|
||||
ProcProcessCount: procCount,
|
||||
Version: ss.Version,
|
||||
NodeType: nodeType,
|
||||
|
||||
ProcPath: pi.Path,
|
||||
ProcUserName: pi.UserName,
|
||||
ProcCreateTime: pi.CreateTime,
|
||||
}
|
||||
if ss.Repl != nil {
|
||||
i.ReplicasetName = ss.Repl.SetName
|
||||
}
|
||||
|
||||
if cmdOpts.Parsed.Storage.DbPath != "" {
|
||||
i.DBPath = cmdOpts.Parsed.Storage.DbPath
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func ClusterID(ctx context.Context, client *mongo.Client) (string, error) {
|
||||
var cv proto.ConfigVersion
|
||||
if err := client.Database("config").Collection("version").FindOne(ctx, bson.M{}).Decode(&cv); err == nil {
|
||||
return cv.ClusterID.Hex(), nil
|
||||
}
|
||||
|
||||
var si proto.ShardIdentity
|
||||
|
||||
filter := bson.M{"_id": "shardIdentity"}
|
||||
|
||||
if err := client.Database("admin").Collection("system.version").FindOne(ctx, filter).Decode(&si); err == nil {
|
||||
return si.ClusterID.Hex(), nil
|
||||
}
|
||||
|
||||
rc, err := ReplicasetConfig(ctx, client)
|
||||
if err != nil {
|
||||
if e, ok := err.(mongo.CommandError); ok && IsReplicationNotEnabledError(e) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rc.Config.Settings.ReplicaSetID.Hex(), nil
|
||||
}
|
||||
|
||||
func IsReplicationNotEnabledError(err mongo.CommandError) bool {
|
||||
return err.Code == ErrNotYetInitialized || err.Code == ErrNoReplicationEnabled
|
||||
}
|
||||
|
||||
func MyState(ctx context.Context, client *mongo.Client) (int, error) {
|
||||
var ms proto.MyState
|
||||
if err := client.Database("admin").RunCommand(ctx, bson.M{"getDiagnosticData": 1}).Decode(&ms); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ms.Data.ReplicasetGetStatus.MyState, nil
|
||||
}
|
||||
|
||||
func ReplicasetConfig(ctx context.Context, client *mongo.Client) (*proto.ReplicasetConfig, error) {
|
||||
var rs proto.ReplicasetConfig
|
||||
if err := client.Database("admin").RunCommand(ctx, bson.M{"replSetGetConfig": 1}).Decode(&rs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rs, nil
|
||||
}
|
||||
|
||||
func fillProcInfo(pid int32, procInfo *proto.ProcInfo) error {
|
||||
proc, err := process.NewProcess(pid)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrCannotGetProcess, "%s", err)
|
||||
}
|
||||
|
||||
ct, err := proc.CreateTime()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
procInfo.CreateTime = time.Unix(ct/milliToSeconds, 0)
|
||||
|
||||
if procInfo.Path, err = proc.Exe(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if procInfo.UserName, err = proc.Username(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getNodeType(ctx context.Context, client *mongo.Client) (string, error) {
|
||||
md := proto.MasterDoc{}
|
||||
if err := client.Database("admin").RunCommand(ctx, primitive.M{"isMaster": 1}).Decode(&md); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if md.SetName != nil || md.Hosts != nil {
|
||||
return TypeShardServer, nil
|
||||
} else if md.Msg == TypeIsDBGrid {
|
||||
// isdbgrid is always the msg value when calling isMaster on a mongos
|
||||
// see http://docs.mongodb.org/manual/core/sharded-cluster-query-router/
|
||||
return TypeMongos, nil
|
||||
}
|
||||
|
||||
return TypeMongod, nil
|
||||
}
|
||||
|
||||
func countMongodProcesses() (int, error) {
|
||||
pids, err := process.Pids()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := process.NewProcess(pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if name, _ := p.Name(); name == TypeMongod || name == TypeMongos {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
tu "github.com/percona/percona-toolkit/src/go/internal/testutils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
@@ -20,34 +21,58 @@ func TestGetHostnames(t *testing.T) {
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "from_mongos",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s", tu.MongoDBUser, tu.MongoDBPassword, tu.MongoDBHost, tu.MongoDBMongosPort),
|
||||
name: "from_mongos",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s",
|
||||
tu.MongoDBUser,
|
||||
tu.MongoDBPassword,
|
||||
tu.MongoDBHost,
|
||||
tu.MongoDBMongosPort,
|
||||
),
|
||||
want: []string{"127.0.0.1:17001", "127.0.0.1:17002", "127.0.0.1:17004", "127.0.0.1:17005", "127.0.0.1:17007"},
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "from_mongod",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s", tu.MongoDBUser, tu.MongoDBPassword, tu.MongoDBHost, tu.MongoDBShard1PrimaryPort),
|
||||
name: "from_mongod",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s",
|
||||
tu.MongoDBUser,
|
||||
tu.MongoDBPassword,
|
||||
tu.MongoDBHost,
|
||||
tu.MongoDBShard1PrimaryPort,
|
||||
),
|
||||
want: []string{"127.0.0.1:17001", "127.0.0.1:17002", "127.0.0.1:17003"},
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "from_non_sharded",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s", tu.MongoDBUser, tu.MongoDBPassword, tu.MongoDBHost, tu.MongoDBShard3PrimaryPort),
|
||||
name: "from_non_sharded",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s",
|
||||
tu.MongoDBUser,
|
||||
tu.MongoDBPassword,
|
||||
tu.MongoDBHost,
|
||||
tu.MongoDBShard3PrimaryPort,
|
||||
),
|
||||
want: []string{"127.0.0.1:17021", "127.0.0.1:17022", "127.0.0.1:17023"},
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "from_standalone",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s", tu.MongoDBUser, tu.MongoDBPassword, tu.MongoDBHost, tu.MongoDBStandalonePort),
|
||||
name: "from_standalone",
|
||||
uri: fmt.Sprintf("mongodb://%s:%s@%s:%s",
|
||||
tu.MongoDBUser,
|
||||
tu.MongoDBPassword,
|
||||
tu.MongoDBHost,
|
||||
tu.MongoDBStandalonePort,
|
||||
),
|
||||
want: nil,
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
uri := test.uri
|
||||
want := test.want
|
||||
wantError := test.wantError
|
||||
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
client, err := mongo.NewClient(options.Client().ApplyURI(test.uri))
|
||||
client, err := mongo.NewClient(options.Client().ApplyURI(uri))
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get a new MongoDB client: %s", err)
|
||||
}
|
||||
@@ -59,12 +84,12 @@ func TestGetHostnames(t *testing.T) {
|
||||
}
|
||||
|
||||
hostnames, err := GetHostnames(ctx, client)
|
||||
if err != nil && !test.wantError {
|
||||
if err != nil && !wantError {
|
||||
t.Errorf("Expecting error=nil, got: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(hostnames, test.want) {
|
||||
t.Errorf("Invalid hostnames. Got: %+v, want %+v", hostnames, test.want)
|
||||
if !reflect.DeepEqual(hostnames, want) {
|
||||
t.Errorf("Invalid hostnames. Got: %+v, want %+v", hostnames, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -194,3 +219,139 @@ func TestGetShardedHosts(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplicasetConfig(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
tcs := []struct {
|
||||
port string
|
||||
wantID string
|
||||
wantConfigServer bool
|
||||
wantError error
|
||||
}{
|
||||
{
|
||||
port: tu.MongoDBStandalonePort,
|
||||
wantID: "",
|
||||
wantConfigServer: false,
|
||||
wantError: mongo.CommandError{
|
||||
Code: 76,
|
||||
Message: "not running with --replSet",
|
||||
Labels: []string(nil),
|
||||
Name: "NoReplicationEnabled",
|
||||
},
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBMongosPort,
|
||||
wantID: "",
|
||||
wantConfigServer: false,
|
||||
wantError: mongo.CommandError{
|
||||
Code: 59,
|
||||
Message: "no such cmd: replSetGetConfig",
|
||||
Labels: []string(nil),
|
||||
Name: "CommandNotFound",
|
||||
},
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBShard1PrimaryPort,
|
||||
wantID: "rs1",
|
||||
wantConfigServer: false,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBConfigsvr1Port,
|
||||
wantID: "csReplSet",
|
||||
wantConfigServer: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
client, err := tu.TestClient(ctx, tc.port)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rs, err := ReplicasetConfig(ctx, client)
|
||||
assert.Equal(t, tc.wantError, err, fmt.Sprintf("%v", tc.port))
|
||||
|
||||
if tc.wantError != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.wantID, rs.Config.ID)
|
||||
assert.Equal(t, tc.wantConfigServer, rs.Config.ConfigServer)
|
||||
assert.NotEmpty(t, rs.Config.Settings.ReplicaSetID.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
func TestClusterID(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
tcs := []struct {
|
||||
port string
|
||||
emptyID bool
|
||||
}{
|
||||
{
|
||||
port: tu.MongoDBMongosPort,
|
||||
emptyID: false,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBShard1PrimaryPort,
|
||||
emptyID: false,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBShard1Secondary1Port,
|
||||
emptyID: false,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBConfigsvr1Port,
|
||||
emptyID: false,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBStandalonePort,
|
||||
emptyID: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
client, err := tu.TestClient(ctx, tc.port)
|
||||
assert.NoError(t, err)
|
||||
cid, err := ClusterID(ctx, client)
|
||||
assert.NoError(t, err, fmt.Sprintf("port: %v", tc.port))
|
||||
assert.Equal(t, cid == "", tc.emptyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMyState(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
tcs := []struct {
|
||||
port string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
port: tu.MongoDBShard1PrimaryPort,
|
||||
want: 1,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBShard1Secondary1Port,
|
||||
want: 2,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBMongosPort,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
port: tu.MongoDBStandalonePort,
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
client, err := tu.TestClient(ctx, tc.port)
|
||||
assert.NoError(t, err)
|
||||
|
||||
state, err := MyState(ctx, client)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.want, state, fmt.Sprintf("port: %v", tc.port))
|
||||
}
|
||||
}
|
||||
|
@@ -70,7 +70,6 @@ type report struct {
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
opts, err := getOptions()
|
||||
if err != nil {
|
||||
log.Errorf("error processing command line arguments: %s", err)
|
||||
@@ -193,7 +192,6 @@ func main() {
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
|
||||
}
|
||||
|
||||
func formatResults(rep report, outputFormat string) ([]byte, error) {
|
||||
@@ -368,7 +366,6 @@ func getHeaders(opts *cliOptions) []string {
|
||||
}
|
||||
|
||||
func getQueryTemplate() string {
|
||||
|
||||
t := `
|
||||
# Query {{.Rank}}: {{printf "% 0.2f" .QPS}} QPS, ID {{.ID}}
|
||||
# Ratio {{Format .Ratio 7.2}} (docs scanned/returned)
|
||||
@@ -522,7 +519,6 @@ func sortQueries(queries []stats.QueryStats, orderby []string) []stats.QueryStat
|
||||
|
||||
OrderedBy(sortFuncs...).Sort(queries)
|
||||
return queries
|
||||
|
||||
}
|
||||
|
||||
func isProfilerEnabled(ctx context.Context, clientOptions *options.ClientOptions) (bool, error) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package main
|
||||
|
||||
//TODO: Rewrite tests to use the new sandbox
|
||||
// TODO: Rewrite tests to use the new sandbox
|
||||
|
||||
// const (
|
||||
// samples = "/src/go/tests/"
|
||||
|
@@ -3,11 +3,16 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -39,18 +44,23 @@ const (
|
||||
DefaultOutputFormat = "text"
|
||||
typeMongos = "mongos"
|
||||
|
||||
// Exit Codes
|
||||
// Exit Codes.
|
||||
cannotFormatResults = 1
|
||||
cannotParseCommandLineParameters = 2
|
||||
cannotGetHostInfo = 3
|
||||
cannotGetReplicasetMembers = 4
|
||||
cannotGetClientOptions = 4
|
||||
cannotConnectToMongoDB = 5
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
Build string = "2020-04-23" // nolint
|
||||
GoVersion string = "1.14.1" // nolint
|
||||
Build string = "2020-04-23"
|
||||
GoVersion string = "1.14.1"
|
||||
Version string = "3.2.0"
|
||||
Commit string
|
||||
|
||||
defaultConnectionTimeout = 3 * time.Second
|
||||
directConnection = true
|
||||
)
|
||||
|
||||
type TimedStats struct {
|
||||
@@ -69,6 +79,7 @@ type opCounters struct {
|
||||
Command TimedStats
|
||||
SampleRate time.Duration
|
||||
}
|
||||
|
||||
type hostInfo struct {
|
||||
Hostname string
|
||||
HostOsType string
|
||||
@@ -164,14 +175,11 @@ func main() {
|
||||
opts, err := parseFlags()
|
||||
if err != nil {
|
||||
log.Errorf("cannot get parameters: %s", err.Error())
|
||||
|
||||
os.Exit(cannotParseCommandLineParameters)
|
||||
}
|
||||
if opts == nil && err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if opts.Help {
|
||||
getopt.Usage()
|
||||
if opts == nil && err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -187,6 +195,7 @@ func main() {
|
||||
fmt.Printf("Version %s\n", Version)
|
||||
fmt.Printf("Build: %s using %s\n", Build, GoVersion)
|
||||
fmt.Printf("Commit: %s\n", Commit)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -201,34 +210,46 @@ func main() {
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
clientOptions := getClientOptions(opts)
|
||||
clientOptions, err := getClientOptions(opts)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
|
||||
os.Exit(cannotGetClientOptions)
|
||||
}
|
||||
|
||||
client, err := mongo.NewClient(clientOptions)
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot get a MongoDB client: %s", err)
|
||||
log.Errorf("Cannot get a MongoDB client: %s", err)
|
||||
|
||||
os.Exit(cannotConnectToMongoDB)
|
||||
}
|
||||
|
||||
if err := client.Connect(ctx); err != nil {
|
||||
log.Fatalf("Cannot connect to MongoDB: %s", err)
|
||||
log.Errorf("Cannot connect to MongoDB: %s", err)
|
||||
os.Exit(cannotConnectToMongoDB)
|
||||
}
|
||||
|
||||
defer client.Disconnect(ctx) // nolint
|
||||
|
||||
hostnames, err := util.GetHostnames(ctx, client)
|
||||
if err != nil && errors.Is(err, util.ShardingNotEnabledError) {
|
||||
log.Errorf("Cannot get hostnames: %s", err)
|
||||
}
|
||||
|
||||
log.Debugf("hostnames: %v", hostnames)
|
||||
|
||||
ci := &collectedInfo{}
|
||||
|
||||
ci.HostInfo, err = getHostInfo(ctx, client)
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("Cannot get host info for %q: %s", opts.Host, err.Error())
|
||||
log.Errorf(message)
|
||||
os.Exit(cannotGetHostInfo)
|
||||
log.Errorf("Cannot get host info for %q: %s", opts.Host, err)
|
||||
os.Exit(cannotGetHostInfo) //nolint:gocritic
|
||||
}
|
||||
|
||||
if ci.ReplicaMembers, err = util.GetReplicasetMembers(ctx, clientOptions); err != nil {
|
||||
log.Warnf("[Error] cannot get replicaset members: %v\n", err)
|
||||
}
|
||||
|
||||
log.Debugf("replicaMembers:\n%+v\n", ci.ReplicaMembers)
|
||||
|
||||
if opts.RunningOpsSamples > 0 && opts.RunningOpsInterval > 0 {
|
||||
@@ -274,9 +295,10 @@ func main() {
|
||||
|
||||
out, err := formatResults(ci, opts.OutputFormat)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot format the results: %s", err.Error())
|
||||
log.Errorf("Cannot format the results: %s", err)
|
||||
os.Exit(cannotFormatResults)
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
|
||||
@@ -287,8 +309,9 @@ func formatResults(ci *collectedInfo, format string) ([]byte, error) {
|
||||
case "json":
|
||||
b, err := json.MarshalIndent(ci, "", " ")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[Error] Cannot convert results to json: %s", err.Error())
|
||||
return nil, errors.Wrap(err, "Cannot convert results to json")
|
||||
}
|
||||
|
||||
buf = bytes.NewBuffer(b)
|
||||
default:
|
||||
buf = new(bytes.Buffer)
|
||||
@@ -338,6 +361,7 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
|
||||
hi := proto.HostInfo{}
|
||||
if err := client.Database("admin").RunCommand(ctx, primitive.M{"hostInfo": 1}).Decode(&hi); err != nil {
|
||||
log.Debugf("run('hostInfo') error: %s", err)
|
||||
|
||||
return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
|
||||
}
|
||||
|
||||
@@ -393,12 +417,15 @@ func countMongodProcesses() (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := process.NewProcess(pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if name, _ := p.Name(); name == "mongod" || name == typeMongos {
|
||||
count++
|
||||
}
|
||||
@@ -440,6 +467,7 @@ func getClusterwideInfo(ctx context.Context, client *mongo.Client) (*clusterwide
|
||||
if collStats.Sharded {
|
||||
cwi.ShardedDataSize += collStats.Size
|
||||
cwi.ShardedColsCount++
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -464,11 +492,14 @@ func sizeAndUnit(size int64) (float64, string) {
|
||||
unit := []string{"bytes", "KB", "MB", "GB", "TB"}
|
||||
idx := 0
|
||||
newSize := float64(size)
|
||||
|
||||
for newSize > 1024 {
|
||||
newSize /= 1024
|
||||
idx++
|
||||
}
|
||||
|
||||
newSize = float64(int64(newSize*100)) / 100
|
||||
|
||||
return newSize, unit[idx]
|
||||
}
|
||||
|
||||
@@ -486,7 +517,10 @@ func getSecuritySettings(ctx context.Context, client *mongo.Client, ver string)
|
||||
}
|
||||
|
||||
cmdOpts := proto.CommandLineOptions{}
|
||||
err = client.Database("admin").RunCommand(ctx, primitive.D{{"getCmdLineOpts", 1}, {"recordStats", 1}}).Decode(&cmdOpts)
|
||||
err = client.Database("admin").RunCommand(ctx, primitive.D{
|
||||
{Key: "getCmdLineOpts", Value: 1},
|
||||
{Key: "recordStats", Value: 1},
|
||||
}).Decode(&cmdOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot get command line options")
|
||||
}
|
||||
@@ -503,7 +537,7 @@ func getSecuritySettings(ctx context.Context, client *mongo.Client, ver string)
|
||||
s.BindIP = cmdOpts.Parsed.Net.BindIP
|
||||
s.Port = cmdOpts.Parsed.Net.Port
|
||||
|
||||
if cmdOpts.Parsed.Net.BindIP == "" {
|
||||
if cmdOpts.Parsed.Net.BindIP == "" { //nolint:nestif
|
||||
if prior26 {
|
||||
s.WarningMsgs = append(s.WarningMsgs, "WARNING: You might be insecure. There is no IP binding")
|
||||
}
|
||||
@@ -586,7 +620,11 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int,
|
||||
// count + 1 because we need 1st reading to stablish a base to measure variation
|
||||
for i := 0; i < count+1; i++ {
|
||||
<-ticker.C
|
||||
err := client.Database("admin").RunCommand(ctx, primitive.D{{"serverStatus", 1}, {"recordStats", 1}}).Decode(&ss)
|
||||
|
||||
err := client.Database("admin").RunCommand(ctx, primitive.D{
|
||||
{Key: "serverStatus", Value: 1},
|
||||
{Key: "recordStats", Value: 1},
|
||||
}).Decode(&ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -598,6 +636,7 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int,
|
||||
prevOpCount.Insert.Total = ss.Opcounters.Insert
|
||||
prevOpCount.Query.Total = ss.Opcounters.Query
|
||||
prevOpCount.Update.Total = ss.Opcounters.Update
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -631,57 +670,63 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int,
|
||||
}
|
||||
|
||||
// Insert --------------------------------------
|
||||
if delta.Opcounters.Insert > oc.Insert.Max {
|
||||
switch {
|
||||
case delta.Opcounters.Insert > oc.Insert.Max:
|
||||
oc.Insert.Max = delta.Opcounters.Insert
|
||||
}
|
||||
if delta.Opcounters.Insert < oc.Insert.Min {
|
||||
case delta.Opcounters.Insert < oc.Insert.Min:
|
||||
oc.Insert.Min = delta.Opcounters.Insert
|
||||
}
|
||||
|
||||
oc.Insert.Total += delta.Opcounters.Insert
|
||||
|
||||
// Query ---------------------------------------
|
||||
if delta.Opcounters.Query > oc.Query.Max {
|
||||
switch {
|
||||
case delta.Opcounters.Query > oc.Query.Max:
|
||||
oc.Query.Max = delta.Opcounters.Query
|
||||
}
|
||||
if delta.Opcounters.Query < oc.Query.Min {
|
||||
case delta.Opcounters.Query < oc.Query.Min:
|
||||
oc.Query.Min = delta.Opcounters.Query
|
||||
}
|
||||
|
||||
oc.Query.Total += delta.Opcounters.Query
|
||||
|
||||
// Command -------------------------------------
|
||||
if delta.Opcounters.Command > oc.Command.Max {
|
||||
switch {
|
||||
case delta.Opcounters.Command > oc.Command.Max:
|
||||
oc.Command.Max = delta.Opcounters.Command
|
||||
}
|
||||
if delta.Opcounters.Command < oc.Command.Min {
|
||||
case delta.Opcounters.Command < oc.Command.Min:
|
||||
oc.Command.Min = delta.Opcounters.Command
|
||||
}
|
||||
|
||||
oc.Command.Total += delta.Opcounters.Command
|
||||
|
||||
// Update --------------------------------------
|
||||
if delta.Opcounters.Update > oc.Update.Max {
|
||||
switch {
|
||||
case delta.Opcounters.Update > oc.Update.Max:
|
||||
oc.Update.Max = delta.Opcounters.Update
|
||||
}
|
||||
if delta.Opcounters.Update < oc.Update.Min {
|
||||
case delta.Opcounters.Update < oc.Update.Min:
|
||||
oc.Update.Min = delta.Opcounters.Update
|
||||
}
|
||||
|
||||
oc.Update.Total += delta.Opcounters.Update
|
||||
|
||||
// Delete --------------------------------------
|
||||
if delta.Opcounters.Delete > oc.Delete.Max {
|
||||
switch {
|
||||
case delta.Opcounters.Delete > oc.Delete.Max:
|
||||
oc.Delete.Max = delta.Opcounters.Delete
|
||||
}
|
||||
if delta.Opcounters.Delete < oc.Delete.Min {
|
||||
case delta.Opcounters.Delete < oc.Delete.Min:
|
||||
oc.Delete.Min = delta.Opcounters.Delete
|
||||
}
|
||||
|
||||
oc.Delete.Total += delta.Opcounters.Delete
|
||||
|
||||
// GetMore -------------------------------------
|
||||
if delta.Opcounters.GetMore > oc.GetMore.Max {
|
||||
switch {
|
||||
case delta.Opcounters.GetMore > oc.GetMore.Max:
|
||||
oc.GetMore.Max = delta.Opcounters.GetMore
|
||||
}
|
||||
if delta.Opcounters.GetMore < oc.GetMore.Min {
|
||||
case delta.Opcounters.GetMore < oc.GetMore.Min:
|
||||
oc.GetMore.Min = delta.Opcounters.GetMore
|
||||
}
|
||||
|
||||
oc.GetMore.Total += delta.Opcounters.GetMore
|
||||
|
||||
prevOpCount.Insert.Total = ss.Opcounters.Insert
|
||||
@@ -690,8 +735,8 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int,
|
||||
prevOpCount.Update.Total = ss.Opcounters.Update
|
||||
prevOpCount.Delete.Total = ss.Opcounters.Delete
|
||||
prevOpCount.GetMore.Total = ss.Opcounters.GetMore
|
||||
|
||||
}
|
||||
|
||||
ticker.Stop()
|
||||
|
||||
oc.Insert.Avg = oc.Insert.Total
|
||||
@@ -707,11 +752,12 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int,
|
||||
}
|
||||
|
||||
func getProcInfo(pid int32, templateData *procInfo) error {
|
||||
//proc, err := process.NewProcess(templateData.ServerStatus.Pid)
|
||||
// proc, err := process.NewProcess(templateData.ServerStatus.Pid)
|
||||
proc, err := process.NewProcess(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get process %d", pid)
|
||||
return errors.New(fmt.Sprintf("cannot get process %d", pid))
|
||||
}
|
||||
|
||||
ct, err := proc.CreateTime()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -742,6 +788,7 @@ func GetBalancerStats(ctx context.Context, client *mongo.Client) (*proto.Balance
|
||||
event := item.Id.Event
|
||||
note := item.Id.Note
|
||||
count := item.Count
|
||||
|
||||
switch event {
|
||||
case "moveChunk.to", "moveChunk.from", "moveChunk.commit":
|
||||
if note == "success" || note == "" {
|
||||
@@ -760,7 +807,7 @@ func GetBalancerStats(ctx context.Context, client *mongo.Client) (*proto.Balance
|
||||
}
|
||||
|
||||
func GetShardingChangelogStatus(ctx context.Context, client *mongo.Client) (*proto.ShardingChangelogStats, error) {
|
||||
var qresults []proto.ShardingChangelogSummary
|
||||
qresults := []proto.ShardingChangelogSummary{}
|
||||
coll := client.Database("config").Collection("changelog")
|
||||
match := primitive.M{"time": primitive.M{"$gt": time.Now().Add(-240 * time.Hour)}}
|
||||
group := primitive.M{"_id": primitive.M{"event": "$what", "note": "$details.note"}, "count": primitive.M{"$sum": 1}}
|
||||
@@ -776,6 +823,7 @@ func GetShardingChangelogStatus(ctx context.Context, client *mongo.Client) (*pro
|
||||
if err := cursor.Decode(&res); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode GetShardingChangelogStatus")
|
||||
}
|
||||
|
||||
qresults = append(qresults, res)
|
||||
}
|
||||
|
||||
@@ -796,6 +844,7 @@ func isPrivateNetwork(ip string) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
addr := net.ParseIP(ip)
|
||||
if cidrnet.Contains(addr) {
|
||||
return true, nil
|
||||
@@ -803,7 +852,6 @@ func isPrivateNetwork(ip string) (bool, error) {
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
func externalIP() (string, error) {
|
||||
@@ -811,17 +859,21 @@ func externalIP() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
}
|
||||
|
||||
if iface.Flags&net.FlagLoopback != 0 {
|
||||
continue // loopback interface
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
@@ -830,9 +882,11 @@ func externalIP() (string, error) {
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
}
|
||||
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // not an ipv4 address
|
||||
@@ -840,6 +894,7 @@ func externalIP() (string, error) {
|
||||
return ip.String(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("are you connected to the network?")
|
||||
}
|
||||
|
||||
@@ -880,8 +935,8 @@ func parseFlags() (*cliOptions, error) {
|
||||
gop.StringVarLong(&opts.SSLPEMKeyFile, "sslPEMKeyFile", 0, "SSL client PEM file used for authentication")
|
||||
|
||||
gop.SetParameters("host[:port]")
|
||||
|
||||
gop.Parse(os.Args)
|
||||
|
||||
if gop.NArgs() > 0 {
|
||||
opts.Host = gop.Arg(0)
|
||||
gop.Parse(gop.Args())
|
||||
@@ -889,19 +944,25 @@ func parseFlags() (*cliOptions, error) {
|
||||
|
||||
if gop.IsSet("password") && opts.Password == "" {
|
||||
print("Password: ")
|
||||
|
||||
pass, err := gopass.GetPasswd()
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
|
||||
opts.Password = string(pass)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(opts.Host, "mongodb://") {
|
||||
opts.Host = "mongodb://" + opts.Host
|
||||
}
|
||||
|
||||
if opts.Help {
|
||||
gop.PrintUsage(os.Stdout)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if opts.OutputFormat != "json" && opts.OutputFormat != "text" {
|
||||
log.Infof("Invalid output format '%s'. Using text format", opts.OutputFormat)
|
||||
}
|
||||
@@ -920,27 +981,93 @@ func getChunksCount(ctx context.Context, client *mongo.Client) ([]proto.ChunksBy
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for cursor.Next(ctx) {
|
||||
res := proto.ChunksByCollection{}
|
||||
if err := cursor.Decode(&res); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot decode chunks aggregation")
|
||||
}
|
||||
|
||||
result = append(result, res)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getClientOptions(opts *cliOptions) *options.ClientOptions {
|
||||
func getClientOptions(opts *cliOptions) (*options.ClientOptions, error) {
|
||||
clientOptions := options.Client().ApplyURI(opts.Host)
|
||||
|
||||
clientOptions.ServerSelectionTimeout = &defaultConnectionTimeout
|
||||
clientOptions.Direct = &directConnection
|
||||
credential := options.Credential{}
|
||||
if opts.User != "" {
|
||||
credential.Username = opts.User
|
||||
clientOptions.SetAuth(credential)
|
||||
}
|
||||
|
||||
if opts.Password != "" {
|
||||
credential.Password = opts.Password
|
||||
credential.PasswordSet = true
|
||||
clientOptions.SetAuth(credential)
|
||||
}
|
||||
return clientOptions
|
||||
|
||||
if opts.SSLPEMKeyFile != "" || opts.SSLCAFile != "" {
|
||||
tlsConfig, err := getTLSConfig(opts.SSLPEMKeyFile, opts.SSLCAFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot read SSL certificate files")
|
||||
}
|
||||
|
||||
clientOptions.TLSConfig = tlsConfig
|
||||
}
|
||||
|
||||
return clientOptions, nil
|
||||
}
|
||||
|
||||
func getTLSConfig(sslPEMKeyFile, sslCAFile string) (*tls.Config, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
MinVersion: tls.VersionTLS10,
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
roots := x509.NewCertPool()
|
||||
|
||||
if sslPEMKeyFile != "" {
|
||||
crt, err := ioutil.ReadFile(filepath.Clean(expandHome(sslPEMKeyFile)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err := tls.X509KeyPair(crt, crt)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
if sslCAFile != "" {
|
||||
ca, err := ioutil.ReadFile(filepath.Clean(expandHome(sslCAFile)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roots.AppendCertsFromPEM(ca)
|
||||
tlsConfig.RootCAs = roots
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
func expandHome(path string) string {
|
||||
usr, _ := user.Current()
|
||||
dir := usr.HomeDir
|
||||
|
||||
switch {
|
||||
case path == "~":
|
||||
path = dir
|
||||
case strings.HasPrefix(path, "~/"):
|
||||
path = filepath.Join(dir, path[2:])
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
@@ -99,8 +99,8 @@ func TestClusterWideInfo(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func addToCounters(ss proto.ServerStatus, increment int64) proto.ServerStatus {
|
||||
ss.Opcounters.Command += increment
|
||||
ss.Opcounters.Delete += increment
|
||||
|
@@ -85,7 +85,6 @@ func GetOplogInfo(ctx context.Context, hostnames []string, co *options.ClientOpt
|
||||
|
||||
sort.Sort(results)
|
||||
return results, nil
|
||||
|
||||
}
|
||||
|
||||
func getOplogCollection(ctx context.Context, client *mongo.Client) (string, error) {
|
||||
|
@@ -31,6 +31,7 @@ type connOpts struct {
|
||||
Password string
|
||||
DisableSSL bool
|
||||
}
|
||||
|
||||
type cliOptions struct {
|
||||
app *kingpin.Application
|
||||
connOpts connOpts
|
||||
@@ -110,7 +111,6 @@ func main() {
|
||||
if err := masterTmpl.ExecuteTemplate(os.Stdout, "report", info); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func connect(dsn string) (*sql.DB, error) {
|
||||
@@ -131,29 +131,29 @@ func funcsMap() template.FuncMap {
|
||||
if len(s) < size {
|
||||
return s
|
||||
}
|
||||
return s[:size]+"..."
|
||||
return s[:size] + "..."
|
||||
},
|
||||
"convertnullstring": func(s sql.NullString) string {
|
||||
if s.Valid {
|
||||
return s.String
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
},
|
||||
"convertnullint64": func(s sql.NullInt64) int64 {
|
||||
if s.Valid {
|
||||
return s.Int64
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
"convertnullfloat64": func(s sql.NullFloat64) float64 {
|
||||
if s.Valid {
|
||||
return s.Float64
|
||||
} else {
|
||||
return 0.0
|
||||
}
|
||||
},
|
||||
"convertnullstring": func(s sql.NullString) string {
|
||||
if s.Valid {
|
||||
return s.String
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
},
|
||||
"convertnullint64": func(s sql.NullInt64) int64 {
|
||||
if s.Valid {
|
||||
return s.Int64
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
"convertnullfloat64": func(s sql.NullFloat64) float64 {
|
||||
if s.Valid {
|
||||
return s.Float64
|
||||
} else {
|
||||
return 0.0
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,8 +5,8 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/percona/percona-toolkit/src/go/pt-pg-summary/internal/tu"
|
||||
"github.com/percona/percona-toolkit/src/go/lib/pginfo"
|
||||
"github.com/percona/percona-toolkit/src/go/pt-pg-summary/internal/tu"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -37,7 +37,7 @@ func TestConnection(t *testing.T) {
|
||||
// use an "external" IP to simulate a remote host
|
||||
tests := append(tests, Test{"remote_host", tu.PG9DockerIP, tu.DefaultPGPort, tu.Username, tu.Password})
|
||||
// use IPV6 for PostgreSQL 9
|
||||
//tests := append(tests, Test{"IPV6", tu.IPv6Host, tu.IPv6PG9Port, tu.Username, tu.Password})
|
||||
// tests := append(tests, Test{"IPV6", tu.IPv6Host, tu.IPv6PG9Port, tu.Username, tu.Password})
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
@@ -48,16 +48,15 @@ func TestConnection(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewWithLogger(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable dbname=%s",
|
||||
test.host, test.port, test.username, test.password, "postgres")
|
||||
db, err := connect(dsn);
|
||||
db, err := connect(dsn)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot connect to the db using %q: %s", dsn, err)
|
||||
}
|
||||
@@ -65,21 +64,20 @@ func TestNewWithLogger(t *testing.T) {
|
||||
t.Errorf("Cannot run NewWithLogger using %q: %s", dsn, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestCollectGlobalInfo(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable dbname=%s",
|
||||
test.host, test.port, test.username, test.password, "postgres")
|
||||
db, err := connect(dsn);
|
||||
db, err := connect(dsn)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot connect to the db using %q: %s", dsn, err)
|
||||
}
|
||||
info, err := pginfo.NewWithLogger(db, nil, 30, logger);
|
||||
info, err := pginfo.NewWithLogger(db, nil, 30, logger)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot run NewWithLogger using %q: %s", dsn, err)
|
||||
}
|
||||
@@ -92,27 +90,27 @@ func TestCollectGlobalInfo(t *testing.T) {
|
||||
t.Errorf("Cannot collect global information using %q", dsn)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectPerDatabaseInfo(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable dbname=%s",
|
||||
test.host, test.port, test.username, test.password, "postgres")
|
||||
db, err := connect(dsn);
|
||||
db, err := connect(dsn)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot connect to the db using %q: %s", dsn, err)
|
||||
}
|
||||
info, err := pginfo.NewWithLogger(db, nil, 30, logger);
|
||||
info, err := pginfo.NewWithLogger(db, nil, 30, logger)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot run New using %q: %s", dsn, err)
|
||||
}
|
||||
for _, dbName := range info.DatabaseNames() {
|
||||
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable dbname=%s",
|
||||
test.host, test.port, test.username, test.password, dbName)
|
||||
conn, err := connect(dsn);
|
||||
conn, err := connect(dsn)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot connect to the %s database using %q: %s", dbName, dsn, err)
|
||||
}
|
||||
@@ -122,5 +120,5 @@ func TestCollectPerDatabaseInfo(t *testing.T) {
|
||||
conn.Close()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ func GetAllDatabases(db XODB) ([]*AllDatabases, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT datname ` +
|
||||
sqlstr := `SELECT datname ` +
|
||||
`FROM pg_database ` +
|
||||
`WHERE datistemplate = false`
|
||||
|
||||
|
@@ -24,7 +24,7 @@ func GetClusterInfos(db XODB) ([]*ClusterInfo, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT usename, now() AS "Time", ` +
|
||||
sqlstr := `SELECT usename, now() AS "Time", ` +
|
||||
`client_addr, ` +
|
||||
`client_hostname, ` +
|
||||
`version() AS version, ` +
|
||||
|
@@ -20,7 +20,7 @@ func GetConnectedClients(db XODB) ([]*ConnectedClients, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT usename, ` +
|
||||
sqlstr := `SELECT usename, ` +
|
||||
`CASE WHEN client_hostname IS NULL THEN client_addr::text ELSE client_hostname END AS client, ` +
|
||||
`state, count(*) ` +
|
||||
`FROM pg_stat_activity ` +
|
||||
|
@@ -14,7 +14,7 @@ func GetConnections(db XODB) ([]*Connections, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT state, count(*) ` +
|
||||
sqlstr := `SELECT state, count(*) ` +
|
||||
`FROM pg_stat_activity ` +
|
||||
`GROUP BY 1`
|
||||
|
||||
|
@@ -27,7 +27,7 @@ func GetCounters(db XODB) ([]*Counters, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT COALESCE(datname, '') datname, numbackends, xact_commit, xact_rollback, ` +
|
||||
sqlstr := `SELECT COALESCE(datname, '') datname, numbackends, xact_commit, xact_rollback, ` +
|
||||
`blks_read, blks_hit, tup_returned, tup_fetched, tup_inserted, ` +
|
||||
`tup_updated, tup_deleted, conflicts, temp_files, ` +
|
||||
`temp_bytes, deadlocks ` +
|
||||
|
@@ -14,7 +14,7 @@ func GetDatabases(db XODB) ([]*Databases, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT datname, pg_size_pretty(pg_database_size(datname)) ` +
|
||||
sqlstr := `SELECT datname, pg_size_pretty(pg_database_size(datname)) ` +
|
||||
`FROM pg_stat_database ` +
|
||||
`WHERE datid <> 0`
|
||||
|
||||
|
@@ -22,7 +22,7 @@ func GetDatabaseWaitEvents(db XODB) ([]*DatabaseWaitEvents, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT c.relname, c.relkind, d.wait_event_type, d.wait_event, b.datname, count(*) ` +
|
||||
sqlstr := `SELECT c.relname, c.relkind, d.wait_event_type, d.wait_event, b.datname, count(*) ` +
|
||||
`FROM pg_locks a ` +
|
||||
`JOIN pg_stat_database b ON a.database=b.datid ` +
|
||||
`JOIN pg_class c ON a.relation=c.oid ` +
|
||||
|
@@ -14,7 +14,7 @@ func GetPortAndDatadir(db XODB) (*PortAndDatadir, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT name, ` +
|
||||
sqlstr := `SELECT name, ` +
|
||||
`setting ` +
|
||||
`FROM pg_settings ` +
|
||||
`WHERE name IN ('port','data_directory')`
|
||||
|
@@ -20,7 +20,7 @@ func GetSlaveHosts10s(db XODB) ([]*SlaveHosts10, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT application_name, client_addr, state, sent_offset - (replay_offset - (sent_lsn - replay_lsn) * 255 * 16 ^ 6 ) AS byte_lag ` +
|
||||
sqlstr := `SELECT application_name, client_addr, state, sent_offset - (replay_offset - (sent_lsn - replay_lsn) * 255 * 16 ^ 6 ) AS byte_lag ` +
|
||||
`FROM ( SELECT application_name, client_addr, client_hostname, state, ` +
|
||||
`('x' || lpad(split_part(sent_lsn::TEXT, '/', 1), 8, '0'))::bit(32)::bigint AS sent_lsn, ` +
|
||||
`('x' || lpad(split_part(replay_lsn::TEXT, '/', 1), 8, '0'))::bit(32)::bigint AS replay_lsn, ` +
|
||||
|
@@ -20,7 +20,7 @@ func GetSlaveHosts96s(db XODB) ([]*SlaveHosts96, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT application_name, client_addr, state, sent_offset - (replay_offset - (sent_xlog - replay_xlog) * 255 * 16 ^ 6 ) AS byte_lag ` +
|
||||
sqlstr := `SELECT application_name, client_addr, state, sent_offset - (replay_offset - (sent_xlog - replay_xlog) * 255 * 16 ^ 6 ) AS byte_lag ` +
|
||||
`FROM ( SELECT application_name, client_addr, client_hostname, state, ` +
|
||||
`('x' || lpad(split_part(sent_location::TEXT, '/', 1), 8, '0'))::bit(32)::bigint AS sent_xlog, ` +
|
||||
`('x' || lpad(split_part(replay_location::TEXT, '/', 1), 8, '0'))::bit(32)::bigint AS replay_xlog, ` +
|
||||
|
@@ -20,7 +20,7 @@ func GetTableAccesses(db XODB) ([]*TableAccess, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT c.relname, c.relkind, b.datname datname, count(*) FROM pg_locks a ` +
|
||||
sqlstr := `SELECT c.relname, c.relkind, b.datname datname, count(*) FROM pg_locks a ` +
|
||||
`JOIN pg_stat_database b ` +
|
||||
`ON a.database=b.datid ` +
|
||||
`JOIN pg_class c ` +
|
||||
|
@@ -18,7 +18,7 @@ func GetTableCacheHitRatio(db XODB) (*TableCacheHitRatio, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT 'cache hit rate' AS name, ` +
|
||||
sqlstr := `SELECT 'cache hit rate' AS name, ` +
|
||||
`CASE WHEN (sum(heap_blks_read) + sum(idx_blks_hit)) > 0 ` +
|
||||
`THEN ` +
|
||||
`sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) ` +
|
||||
|
@@ -15,7 +15,7 @@ func GetTablespaces(db XODB) ([]*Tablespaces, error) {
|
||||
var err error
|
||||
|
||||
// sql query
|
||||
var sqlstr = `SELECT spcname AS Name, ` +
|
||||
sqlstr := `SELECT spcname AS Name, ` +
|
||||
`pg_catalog.pg_get_userbyid(spcowner) AS Owner, ` +
|
||||
`pg_catalog.pg_tablespace_location(oid) AS Location ` +
|
||||
`FROM pg_catalog.pg_tablespace ` +
|
||||
|
@@ -57,7 +57,7 @@ var TPL = `{{define "report"}}
|
||||
+----------------------+----------------------+----------------------------------------------------+
|
||||
{{ end -}} {{/* end define */}}
|
||||
` +
|
||||
`{{- define "slaves_and_log_none" -}}
|
||||
`{{- define "slaves_and_log_none" -}}
|
||||
##### --- Slave and the lag with Master --- ####
|
||||
There are no slave hosts
|
||||
{{ end -}} {{/* end define */}}
|
||||
|
@@ -50,7 +50,7 @@ func encrypt(infile, outfile string, pass [32]byte) error {
|
||||
var iv [aes.BlockSize]byte
|
||||
stream := cipher.NewOFB(block, iv[:])
|
||||
|
||||
outFile, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
outFile, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Cannot create output file %q", outfile)
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func decrypt(infile, outfile string, pass [32]byte) error {
|
||||
var iv [aes.BlockSize]byte
|
||||
stream := cipher.NewOFB(block, iv[:])
|
||||
|
||||
outFile, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
outFile, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Cannot open %q for writing", outfile)
|
||||
}
|
||||
|
@@ -32,11 +32,9 @@ func TestProcessCliParams(t *testing.T) {
|
||||
t.Errorf("Test #%d expected error, have nil", i)
|
||||
}
|
||||
if !reflect.DeepEqual(opts, test.WantOpts) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollect(t *testing.T) {
|
||||
|
||||
}
|
||||
|
@@ -6,12 +6,12 @@ cd $BASEDIR
|
||||
|
||||
source ${BASEDIR}/src/go/setenv.sh
|
||||
|
||||
for dir in $(ls -d ./src/go/pt-*)
|
||||
for dir in $(ls -d ./src/go/pt-* ) ./src/go/mongolib
|
||||
do
|
||||
echo "Running tests at $BASEDIR/$dir"
|
||||
cd $BASEDIR/$dir
|
||||
go get ./...
|
||||
go test -v -coverprofile=coverage.out
|
||||
go test -v -coverprofile=coverage.out ./...
|
||||
if [ -f coverage.out ]
|
||||
then
|
||||
go tool cover -func=coverage.out
|
||||
|
95
t/pt-heartbeat/pt-1857.t
Normal file
95
t/pt-heartbeat/pt-1857.t
Normal file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use threads ('yield');
|
||||
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
|
||||
use Data::Dumper;
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
use SqlModes;
|
||||
use File::Temp qw/ tempfile /;
|
||||
|
||||
plan tests => 2;
|
||||
|
||||
require "$trunk/bin/pt-heartbeat";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
|
||||
my $slave1_dbh = $sb->get_dbh_for('slave1');
|
||||
my $slave1_dsn = 'h=127.1,P=12346,u=unprivileged,p=password';
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
sub start_thread {
|
||||
my ($dsn_opts, $sleep) = @_;
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh= $sb->get_dbh_for('slave1');
|
||||
my $rows = $dbh->selectall_arrayref('SHOW PROCESSLIST', { Slice => {} });
|
||||
for my $row (@$rows) {
|
||||
if ($row->{user} eq 'unprivileged') {
|
||||
$dbh->do("kill $row->{id}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $create_table_sql = <<__EOQ;
|
||||
CREATE TABLE IF NOT EXISTS sakila.heartbeat (
|
||||
ts varchar(26) NOT NULL,
|
||||
server_id int unsigned NOT NULL PRIMARY KEY,
|
||||
file varchar(255) DEFAULT NULL, -- SHOW MASTER STATUS
|
||||
position bigint unsigned DEFAULT NULL, -- SHOW MASTER STATUS
|
||||
relay_master_log_file varchar(255) DEFAULT NULL, -- SHOW SLAVE STATUS
|
||||
exec_master_log_pos bigint unsigned DEFAULT NULL -- SHOW SLAVE STATUS
|
||||
);
|
||||
__EOQ
|
||||
|
||||
$sb->do_as_root('master', "$create_table_sql");
|
||||
if ($sandbox_version ge '8.0') {
|
||||
$sb->do_as_root('slave1', 'CREATE USER "unprivileged"@"localhost" IDENTIFIED WITH mysql_native_password BY "password"');
|
||||
} else {
|
||||
$sb->do_as_root('slave1', 'CREATE USER "unprivileged"@"localhost" IDENTIFIED BY "password"');
|
||||
}
|
||||
$sb->do_as_root('slave1', 'GRANT SELECT, INSERT, UPDATE, REPLICATION CLIENT ON *.* TO "unprivileged"@"localhost"');
|
||||
$sb->do_as_root('slave1', "FLUSH TABLES WITH READ LOCK;");
|
||||
$sb->do_as_root('slave1', "SET GLOBAL read_only = 1;");
|
||||
|
||||
my $thread = threads->create('start_thread', $dsn_opts, 4);
|
||||
$thread->detach();
|
||||
threads->yield();
|
||||
|
||||
my $output = `PTDEBUG=1 $trunk/bin/pt-heartbeat --database=sakila --table heartbeat --read-only-interval 2 --check-read-only --run-time 5 --update $slave1_dsn 2>&1`;
|
||||
|
||||
unlike (
|
||||
$output,
|
||||
qr/Lost connection to MySQL/,
|
||||
'PT-1508 --read-only-interval',
|
||||
);
|
||||
|
||||
$master_dbh->do("DROP DATABASE IF EXISTS test");
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->do_as_root('master', 'DROP TABLE IF EXISTS sakila.heartbeat');
|
||||
$sb->do_as_root('slave1', 'DROP USER "unprivileged"@"localhost"');
|
||||
|
||||
$sb->wipe_clean($master_dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
76
t/pt-online-schema-change/pt-169.t
Normal file
76
t/pt-online-schema-change/pt-169.t
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use threads;
|
||||
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
|
||||
use Data::Dumper;
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
use SqlModes;
|
||||
use File::Temp qw/ tempdir /;
|
||||
|
||||
plan tests => 3;
|
||||
|
||||
require "$trunk/bin/pt-online-schema-change";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the
|
||||
# tool will die.
|
||||
my @args = (qw(--set-vars innodb_lock_wait_timeout=3));
|
||||
my $output;
|
||||
my $exit_status;
|
||||
my $sample = "t/pt-online-schema-change/samples/";
|
||||
my $ERROR_UPDATING_FKS = 15; # from pt-online-schema-change line 8453
|
||||
|
||||
$sb->load_file('master', "$sample/pt-169.sql");
|
||||
|
||||
($output, $exit_status) = full_output(
|
||||
sub { pt_online_schema_change::main(@args, "$master_dsn,D=test,t=users",
|
||||
'--execute', '--alter', 'CHANGE COLUMN id id BIGINT UNSIGNED NOT NULL FIRST',
|
||||
'--set-vars', 'foreign_key_checks=0',
|
||||
'--alter-foreign-keys-method', 'drop_swap', '--no-check-alter')
|
||||
},
|
||||
);
|
||||
|
||||
is(
|
||||
$exit_status,
|
||||
$ERROR_UPDATING_FKS,
|
||||
"--alter rename columns with uppercase names -> exit status 0",
|
||||
);
|
||||
|
||||
# Since drop_swap has failed, the clueanup process should be skipped and the new table
|
||||
# shouldn't be deleted
|
||||
my $row = $master_dbh->selectrow_hashref("select count(*) AS how_many from test._users_new");
|
||||
is (
|
||||
$row->{how_many},
|
||||
1,
|
||||
"Correct number of rows",
|
||||
);
|
||||
|
||||
$master_dbh->do("DROP DATABASE IF EXISTS test");
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($master_dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
40
t/pt-online-schema-change/samples/pt-169.sql
Normal file
40
t/pt-online-schema-change/samples/pt-169.sql
Normal file
@@ -0,0 +1,40 @@
|
||||
DROP DATABASE IF EXISTS `test`;
|
||||
CREATE DATABASE test;
|
||||
USE test;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(10) unsigned NOT NULL,
|
||||
`username` varchar(255) NOT NULL,
|
||||
`full_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL,
|
||||
`is_verified` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`is_private` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`profile_pic_url` varchar(255) DEFAULT NULL,
|
||||
`follower_count` int(11) NOT NULL DEFAULT '0',
|
||||
`following_count` int(11) NOT NULL DEFAULT '0',
|
||||
`media_count` int(11) NOT NULL DEFAULT '0',
|
||||
`biography` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
|
||||
`user_active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `username` (`username`),
|
||||
KEY `follower_count` (`follower_count`),
|
||||
KEY `following_count` (`following_count`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `user_comments` (
|
||||
`id_user_comments` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`msg` varchar(255) DEFAULT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id_user_comments`),
|
||||
KEY `fk1_idx` (`user_id`),
|
||||
CONSTRAINT `fk1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
INSERT INTO `test`.`users` (`id`, `username`, `full_name`, `is_verified`, `is_private`, `profile_pic_url`,
|
||||
`follower_count`, `following_count`, `media_count`, `biography`, `user_active`)
|
||||
VALUES
|
||||
(1, "zappb", "zapp brannigan", 1, 1, "https://pbs.twimg.com/profile_images/447660347273408512/NdZEGKvr.jpeg", 0, 0, 0, "", 1);
|
||||
|
||||
INSERT INTO `test`.`user_comments` (`id_user_comments`, `msg`, `user_id`)
|
||||
VALUES
|
||||
(1, "I am the man with no name. Zapp Brannigan, at your service.", 1);
|
@@ -23,7 +23,9 @@ if ($ENV{PERCONA_SLOW_BOX}) {
|
||||
plan skip_all => 'This test needs a fast machine';
|
||||
} else {
|
||||
plan tests => 6;
|
||||
}
|
||||
#plan skip_all => 'This test is taking too much time even in fast machines';
|
||||
}
|
||||
|
||||
our $delay = 30;
|
||||
|
||||
my $tmp_file = File::Temp->new();
|
||||
@@ -39,10 +41,6 @@ my $slave_dbh = $sb->get_dbh_for('slave1');
|
||||
my $master_dsn = 'h=127.0.0.1,P=12345,u=msandbox,p=msandbox';
|
||||
my $slave_dsn = 'h=127.0.0.1,P=12346,u=msandbox,p=msandbox';
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
sub reset_query_cache {
|
||||
my @dbhs = @_;
|
||||
return if ($sandbox_version >= '8.0');
|
||||
@@ -64,7 +62,7 @@ $sb->load_file('master', "t/pt-online-schema-change/samples/slave_lag.sql");
|
||||
|
||||
my $num_rows = 5000;
|
||||
diag("Loading $num_rows into the table. This might take some time.");
|
||||
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=12345 --user=msandbox --password=msandbox test pt178 --bulk-size=1 --max-threads=1 $num_rows`);
|
||||
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=12345 --user=msandbox --password=msandbox test pt178 $num_rows`);
|
||||
|
||||
diag("Setting slave delay to $delay seconds");
|
||||
|
Reference in New Issue
Block a user