Compare commits

..

25 Commits

Author SHA1 Message Date
Sveta Smirnova
0289a1a6b4 Merge pull request #1015 from percona/dependabot/go_modules/golang.org/x/crypto-0.42.0
build(deps): bump golang.org/x/crypto from 0.41.0 to 0.42.0
2025-09-19 17:36:00 +03:00
Sveta Smirnova
f9452ef406 Merge pull request #1016 from percona/dependabot/go_modules/k8s.io/api-0.34.1
build(deps): bump k8s.io/api from 0.34.0 to 0.34.1
2025-09-19 17:35:43 +03:00
Sveta Smirnova
e60f742f36 Merge pull request #1009 from percona/dependabot/github_actions/actions/setup-go-6
build(deps): bump actions/setup-go from 5 to 6
2025-09-16 13:49:12 +03:00
Sveta Smirnova
527ba7ef33 Merge pull request #999 from percona/PT-1564_Man_page_broken_for_pt-secure-collect
PT-1564 - Man page broken for pt-secure-collect
2025-09-16 13:41:11 +03:00
Sveta Smirnova
64ced79f7d Merge pull request #1005 from percona/PT-2289_Allow_pt-stalk_do_disable_ps-lock-transactions_data_collection_via_parameter
Pt 2289 allow pt stalk do disable ps lock transactions data collection via parameter
2025-09-16 13:40:22 +03:00
dependabot[bot]
ea8fc17dbc build(deps): bump k8s.io/api from 0.34.0 to 0.34.1
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.34.0 to 0.34.1.
- [Commits](https://github.com/kubernetes/api/compare/v0.34.0...v0.34.1)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 09:50:34 +00:00
dependabot[bot]
11e73c8b60 build(deps): bump golang.org/x/crypto from 0.41.0 to 0.42.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.41.0 to 0.42.0.
- [Commits](https://github.com/golang/crypto/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 09:21:40 +00:00
Sveta Smirnova
2dbdb8642b Merge pull request #1006 from percona/PT-1151_LP_1225577_pt-online-schema-change_can_silently_drop_rows
PT-1151 - LP #1225577: pt-online-schema-change can silently drop rows
2025-09-12 14:25:42 +03:00
Sveta Smirnova
cd6183dbcc Merge pull request #1014 from percona/PT-2346_t/pt-table-sync/specify_column_or_index.t_fails_with_5.7
PT-2346 - t/pt-table-sync/specify_column_or_index.t fails with 5.7
2025-09-12 14:22:44 +03:00
Sveta Smirnova
fb1f5be339 Update Makefile.PL
Co-authored-by: EvgeniyPatlan <evgeniy.patlan@percona.com>
2025-09-10 18:20:44 +03:00
Sveta Smirnova
bfeaa98379 PT-2289 - Allow pt-stalk do disable ps-lock-transactions data collection via parameter
- Fixed typo found during review
2025-09-10 18:19:03 +03:00
Sveta Smirnova
2ac8385d2d Merge pull request #1012 from nilnandan/PT-2014-pt-config-diff_does_not_honor_case_insensitivity_flag
PT-2014 - Updated MySQLConfigComparer.pm so now it can honor case insensitivity…
2025-09-10 18:16:33 +03:00
Sveta Smirnova
128dc2938e Merge pull request #1011 from percona/PT-2470_pt-table-sync_supports_recursion_methods_dsn_and_cluster_but_documentation_does_not_mention_it
PT-2470 - pt-table-sync supports recursion methods dsn and cluster bu…
2025-09-10 18:15:47 +03:00
Sveta Smirnova
f550652dbf PT-2014 - pt-config-diff does not honor case insensitivity flag
- Fixed the proposed fix
- Fixed proposed configuration files
- Added test case
2025-09-09 19:25:13 +03:00
Sveta Smirnova
fef02540fe PT-2346 - t/pt-table-sync/specify_column_or_index.t fails with 5.7
- Adjusted regular expression, so it is independent from randomness of the query plan calculation by EXPLAIN: we test if specified index or column used, not the range of values.
2025-09-09 16:10:45 +03:00
nilnandan
4e190a34ef Updated MySQLConfigComparer.pm so now it can honor case insensitivity. cnf1 and cnf2 are test files. 2025-09-08 14:12:12 +00:00
Sveta Smirnova
21fd4f7b90 PT-2470 - pt-table-sync supports recursion methods dsn and cluster but documentation does not mention it
- Updated documentation for the option --recursion-method
- I did not mention cluster, because pt-table-sync does not make sense with the cluster
- Test case for the --recursion-method=dsn is in ssl.t
2025-09-08 15:27:20 +03:00
dependabot[bot]
de69a69076 build(deps): bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 09:18:06 +00:00
Sveta Smirnova
20b3196cda PT-1151 - LP #1225577: pt-online-schema-change can silently drop rows
- Found case when --check-unique-index-change does not catch error:
  UNIQUE without KEY or INDEX keyword and fixed regular expression
2025-09-08 02:26:30 +03:00
Sveta Smirnova
919970abe9 PT-2289 - Allow pt-stalk do disable ps-lock-transactions data collection via parameter
- Modified t/pt-stalk/pt-stalk.t, so it calls function purge_samples with the correct number of parameters
- Fixed purge_samples, so it can work if variable OPT_PREFIX is not defined
2025-09-07 01:34:05 +03:00
Sveta Smirnova
cdc24c10f0 PT-2289 - Allow pt-stalk do disable ps-lock-transactions data collection via parameter
- Implemented _should_skip function as was suggested
2025-09-05 16:08:43 +03:00
Sveta Smirnova
66d20ae6da PT-2289 - Allow pt-stalk do disable ps-lock-transactions data collection via parameter
- Adjusted the implementation
- Created test cases
2025-09-03 00:41:06 +03:00
Sveta Smirnova
68a4540a3d PT-2289 - Allow pt-stalk do disable ps-lock-transactions data collection via parameter
- Implemented feature
- Started working on the test
2025-09-01 18:17:04 +03:00
Sveta Smirnova
cd36511b52 Merge branch '3.x' into PT-1564_Man_page_broken_for_pt-secure-collect 2025-08-26 19:45:04 +03:00
Sveta Smirnova
1a3f42acb1 PT-1564 - Man page broken for pt-secure-collect
- Removed non-working condition from Makefile.PL
- Added working condition for creating MAN1PODS hash
2025-08-26 19:36:46 +03:00
19 changed files with 621 additions and 195 deletions

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: '1.24'
- name: Build

View File

@@ -12,21 +12,17 @@ MAKE_GOTOOLS
WriteMakefile(
NAME => 'Percona::Toolkit',
VERSION => '3.7.0-2',
EXE_FILES => [
map {
(my $name = $_) =~ s/^bin.//;
my $file_name = $_;
if ( ( $file_name !~ m/mongo/ ) || ( $file_name !~ m/pg/ ) || ( $file_name !~ m/pt-stalk/ ) || ( $file_name !~ m/pt-k8s/ ) ) {
$_;
}
} <bin/*>
],
EXE_FILES => [ <bin/*> ],
MAN1PODS => {
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
map {
(my $name = $_) =~ s/^bin.//;
my $file_name = $_;
if ( ( $file_name !~ m/mongo/ ) || ( $file_name !~ m/pg/ ) || ( $file_name !~ m/pt-stalk/ ) || ( $file_name !~ m/pt-k8s/ ) ) {
if ( $file_name =~ m/(mongo|pg|galera|k8s|secure)/ ) {
# We have to put empty line here to avoid the MAN1PODS hash corruption
'' => '',
}
else {
$_ => "blib/man1/$name.1p";
}
} <bin/*>

View File

@@ -3637,6 +3637,7 @@ sub diff {
next CONFIG if $val0 == $valN;
}
else {
next CONFIG if $ignore_case
? lc($val0) eq lc($valN)
: $val0 eq $valN;
@@ -3699,7 +3700,7 @@ sub _normalize_value {
my ($val, $is_dir, $base_path) = @args{qw(value is_directory base_path)};
$val = defined $val ? $val : '';
$val = $alt_val_for{$val} if exists $alt_val_for{$val};
$val = $alt_val_for{uc($val)} if exists $alt_val_for{uc($val)};
if ( $val =~ m/,/ && !$is_dir && !$base_path) {
$val = join(',', sort(split(',', $val)));

View File

@@ -11211,7 +11211,7 @@ sub get_unique_index_fields {
$clean .= $suffix;
my $fields = [];
my $fields_re = qr/\s(?:PRIMARY|UNIQUE)\s+(?:INDEX|KEY|)\s*(?:.*?)\s*\((.*?)\)/i;
my $fields_re = qr/\s(?:(?:(?:PRIMARY|UNIQUE)\s+(?:INDEX|KEY|))|UNIQUE)\s*(?:.*?)\s*\((.*?)\)/i;
while($clean =~ /$fields_re/g) {
push @$fields, [ split /\s*,\s*/, $1 ];

View File

@@ -971,8 +971,10 @@ collect_mysql_data_one() {
fi
fi
if ! _should_skip "mysqladmin"; then
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
mysqladmin_pid=$!
fi
ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
| sed "2q;d" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
@@ -1014,18 +1016,25 @@ collect_system_data() {
collect_mysql_data_loop() {
if ! _should_skip "processlist"; then
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
>> "$d/$p-processlist" &
fi
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
>> "$d/$p-threads" &
if [ "$have_lock_waits_table" ]; then
if ! _should_skip "lock-waits"; then
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
fi
if ! _should_skip "transactions"; then
(echo $ts; transactions) >>"$d/$p-transactions" &
fi
fi
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ] \
&& ! _should_skip "ps-locks-transactions"; then
ps_locks_transactions "$d/$p-ps-locks-transactions"
fi
@@ -1252,6 +1261,7 @@ innodb_status() {
local innostat=""
if ! _should_skip "innodbstatus"; then
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
>> "$d/$p-innodbstatus$n"
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
@@ -1266,6 +1276,7 @@ innodb_status() {
done
fi
}
fi
}
rocksdb_status() {
@@ -1274,7 +1285,7 @@ rocksdb_status() {
has_rocksdb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'rocksdb'`
exit_code=$?
if [ $exit_code -eq 0 ]; then
if [ $exit_code -eq 0 ] && ! _should_skip "rocksdbstatus"; then
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE ROCKSDB STATUS\G" \
>> "$d/$p-rocksdbstatus$n" || rm -f "$d/$p-rocksdbstatus$n"
fi
@@ -1356,6 +1367,7 @@ collect_mysql_variables() {
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
if ! _should_skip "thread-variables"; then
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
@@ -1367,9 +1379,22 @@ collect_mysql_variables() {
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
fi
}
_should_skip() {
local name=$1
for item in "${OPT_SKIP_COLLECTION[@]}"; do
if [ "$item" == "$name" ]; then
return 0
fi
done
return 1
}
# ###########################################################################
# End collect package
# ###########################################################################
@@ -1524,7 +1549,7 @@ purge_samples() {
local retention_size="$4"
# Delete collect files which more than --retention-time days old.
if [ -n "$OPT_PREFIX" ]; then
if [ -n "${OPT_PREFIX:-}" ]; then
find "$dir" -maxdepth 1 -type f -mtime +$retention_time -name "$OPT_PREFIX-*" -exec rm -f '{}' \;
else
find "$dir" -maxdepth 1 -type f -mtime +$retention_time -regextype posix-egrep -regex "$dir/[0-9]{4}(_[0-9]{2}){5}-.*" -exec rm -f '{}' \;
@@ -1723,10 +1748,6 @@ stalk() {
main() {
trap sigtrap SIGHUP SIGINT SIGTERM
if [ "$OPT_SYSTEM_ONLY" ] && [ "$OPT_MYSQL_ONLY" ]; then
log 'Both options --system-only and --mysql-only specified, collecting only disk-space, hostname, output, and trigger metrics';
fi
# Note: $$ is the parent's PID, but we're a child proc.
# Bash 4 has $BASHPID but we can't rely on that. Consequently,
# we don't know our own PID. See the usage of $! below.
@@ -1770,6 +1791,10 @@ if [ "${0##*/}" = "$TOOL" ] \
mk_tmpdir
parse_options "$0" "${@:-""}"
if [ "$OPT_SYSTEM_ONLY" ] && [ "$OPT_MYSQL_ONLY" ]; then
log 'Both options --system-only and --mysql-only specified, collecting only disk-space, hostname, output, and trigger metrics';
fi
# Verify and set TRIGGER_FUNCTION based on --function.
if ! set_trg_func "$OPT_FUNCTION"; then
option_error "Invalid --function value: $OPT_FUNCTION"
@@ -1784,6 +1809,19 @@ if [ "${0##*/}" = "$TOOL" ] \
fi
fi
if [ "$OPT_SKIP_COLLECTION" ]; then
supported_skips=( "ps-locks-transactions" "thread-variables" "innodbstatus" "lock-waits" "mysqladmin" "processlist" "rocksdbstatus" "transactions" )
IFS=',' read -ra skips <<< "$OPT_SKIP_COLLECTION"
OPT_SKIP_COLLECTION=("${skips[@]}")
for skip in "${skips[@]}"; do
echo "$supported_skips" | grep -q "$skip"
if ! [[ " ${supported_skips[@]} " =~ " ${skip} " ]]; then
log "Invalid --skip-collection value: $skip, exiting."
exit 1
fi
done
fi
if [ -z "$OPT_STALK" -a "$OPT_COLLECT" ]; then
# Not stalking; do immediate collect once.
OPT_CYCLES=0
@@ -2391,6 +2429,12 @@ How long to sleep between collection loop cycles. This is useful with
C<--no-stalk> to do long collections. For example, to collect data every
minute for an hour, specify: C<--no-stalk --run-time 3600 --sleep-collect 60>.
=item --skip-collection
type: array
A comma-separated list of collection types to skip. Valid values are: C<"ps-locks-transactions,thread-variables,innodbstatus,lock-waits,mysqladmin,processlist,rocksdbstatus,transactions">.
=item --socket
short form: -S; type: string

View File

@@ -12965,14 +12965,43 @@ Possible methods are:
=========== ==================
processlist SHOW PROCESSLIST
hosts SHOW REPLICAS (SHOW SLAVE HOSTS before MySQL 8.1)
dsn=DSN DSNs from a table
none Do not find replicas
The processlist method is preferred because SHOW REPLICAS is not reliable.
However, the hosts method is required if the server uses a non-standard
port (not 3306). Usually pt-table-sync does the right thing and finds
the replicas, but you may give a preferred method and it will be used first.
If it doesn't find any replicas, the other methods will be tried.
The C<processlist> method is the default, because C<SHOW REPLICAS> is not
reliable. However, if the server uses a non-standard port (not 3306), then
the C<hosts> method becomes the default because it works better in this case.
The C<hosts> method requires replicas to be configured with C<report_host>,
C<report_port>, etc.
The C<dsn> method is special: rather than automatically discovering replicas,
this method specifies a table with replica DSNs. The tool will only connect
to these replicas. This method works best when replicas do not use the same
MySQL username or password as the source, or when you want to prevent the tool
from connecting to certain replicas. The C<dsn> method is specified like:
C<--recursion-method dsn=h=host,D=percona,t=dsns>. The specified DSN must
have D and t parts, or just a database-qualified t part, which specify the
DSN table. The DSN table must have the following structure:
CREATE TABLE `dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
DSNs are ordered by C<id>, but C<id> and C<parent_id> are otherwise ignored.
The C<dsn> column contains a replica DSN like it would be given on the command
line, for example: C<"h=replica_host,u=repl_user,p=repl_pass">.
The C<none> method makes the tool ignore all replicas and cluster nodes. This
method is not recommended because it effectively disables the
L<"REPLICA CHECKS"> and no differences can be found. It is useful, however, if
you only need to write checksums on the source or a single cluster node. The
safer alternative is C<--no-replicate-check>: the tool finds replicas and
cluster nodes, performs the L<"REPLICA CHECKS">, but does not check for
differences. See L<"--[no]replicate-check">.
=item --replace

16
go.mod
View File

@@ -29,11 +29,11 @@ require (
github.com/stretchr/testify v1.11.1
github.com/xlab/treeprint v1.2.0
go.mongodb.org/mongo-driver v1.17.4
golang.org/x/crypto v0.41.0
golang.org/x/crypto v0.42.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.34.0
k8s.io/api v0.34.1
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
)
@@ -62,14 +62,14 @@ require (
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/term v0.34.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/term v0.35.0 // indirect
golang.org/x/text v0.29.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.34.0 // indirect
k8s.io/apimachinery v0.34.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect

32
go.sum
View File

@@ -131,8 +131,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -146,15 +146,15 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -170,18 +170,18 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -205,10 +205,10 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=

View File

@@ -202,6 +202,7 @@ sub diff {
next CONFIG if $val0 == $valN;
}
else {
next CONFIG if $ignore_case
? lc($val0) eq lc($valN)
: $val0 eq $valN;
@@ -293,7 +294,7 @@ sub _normalize_value {
my ($val, $is_dir, $base_path) = @args{qw(value is_directory base_path)};
$val = defined $val ? $val : '';
$val = $alt_val_for{$val} if exists $alt_val_for{$val};
$val = $alt_val_for{uc($val)} if exists $alt_val_for{uc($val)};
if ( $val =~ m/,/ && !$is_dir && !$base_path) {
$val = join(',', sort(split(',', $val)));

View File

@@ -243,8 +243,10 @@ collect_mysql_data_one() {
# get and keep a connection to the database; in troubled times
# the database tends to exceed max_connections, so reconnecting
# in the loop tends not to work very well.
if ! _should_skip "mysqladmin"; then
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
mysqladmin_pid=$!
fi
ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
| sed "2q;d" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
@@ -289,18 +291,25 @@ collect_mysql_data_loop() {
# SHOW FULL PROCESSLIST duplicates information in performance_schema.threads we collecting now
# Keeping it for backward compatibility and may remove in the future
if ! _should_skip "processlist"; then
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
>> "$d/$p-processlist" &
fi
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
>> "$d/$p-threads" &
if [ "$have_lock_waits_table" ]; then
if ! _should_skip "lock-waits"; then
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
fi
if ! _should_skip "transactions"; then
(echo $ts; transactions) >>"$d/$p-transactions" &
fi
fi
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ] \
&& ! _should_skip "ps-locks-transactions"; then
ps_locks_transactions "$d/$p-ps-locks-transactions"
fi
@@ -538,6 +547,7 @@ innodb_status() {
local innostat=""
if ! _should_skip "innodbstatus"; then
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
>> "$d/$p-innodbstatus$n"
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
@@ -552,6 +562,7 @@ innodb_status() {
done
fi
}
fi
}
rocksdb_status() {
@@ -560,7 +571,7 @@ rocksdb_status() {
has_rocksdb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'rocksdb'`
exit_code=$?
if [ $exit_code -eq 0 ]; then
if [ $exit_code -eq 0 ] && ! _should_skip "rocksdbstatus"; then
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE ROCKSDB STATUS\G" \
>> "$d/$p-rocksdbstatus$n" || rm -f "$d/$p-rocksdbstatus$n"
fi
@@ -646,6 +657,7 @@ collect_mysql_variables() {
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
if ! _should_skip "thread-variables"; then
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
@@ -657,9 +669,22 @@ collect_mysql_variables() {
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
echo -e "\n$sql\n" >> $outfile
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
fi
}
_should_skip() {
local name=$1
for item in "${OPT_SKIP_COLLECTION[@]}"; do
if [ "$item" == "$name" ]; then
return 0
fi
done
return 1
}
# ###########################################################################
# End collect package
# ###########################################################################

View File

@@ -208,7 +208,7 @@ func main() {
if err != nil {
log.Infof("cannot check version updates: %s", err.Error())
} else if advice != "" {
log.Infof("%s", advice)
log.Infof(advice)
}
}
@@ -373,6 +373,24 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
}
cmdOpts := proto.CommandLineOptions{}
query := primitive.D{{Key: "getCmdLineOpts", 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}}
if err := client.Database("admin").RunCommand(ctx, query).Decode(&ss); err != nil {
return nil, errors.Wrap(err, "GetHostInfo.serverStatus")
}
pi := procInfo{}
if err := getProcInfo(int32(ss.Pid), &pi); err != nil {
pi.Error = err
}
nodeType, _ := getNodeType(ctx, client)
procCount, _ := countMongodProcesses()
@@ -380,41 +398,24 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
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,
CmdlineArgs: nil,
}
var cmdOpts proto.CommandLineOptions
query := primitive.D{{Key: "getCmdLineOpts", Value: 1}}
err := client.Database("admin").RunCommand(ctx, query).Decode(&cmdOpts)
if err == nil {
if len(cmdOpts.Argv) > 0 {
i.CmdlineArgs = cmdOpts.Argv
ProcPath: pi.Path,
ProcUserName: pi.UserName,
ProcCreateTime: pi.CreateTime,
CmdlineArgs: cmdOpts.Argv,
}
if cmdOpts.Parsed.Storage.DbPath != "" {
i.DBPath = cmdOpts.Parsed.Storage.DbPath
}
}
var ss proto.ServerStatus
query = primitive.D{{Key: "serverStatus", Value: 1}}
err = client.Database("admin").RunCommand(ctx, query).Decode(&ss)
if err == nil {
i.ProcessName = ss.Process
i.Version = ss.Version
if ss.Repl != nil {
i.ReplicasetName = ss.Repl.SetName
}
pi := procInfo{}
if err := getProcInfo(int32(ss.Pid), &pi); err != nil {
pi.Error = err
} else {
i.ProcPath = pi.Path
i.ProcUserName = pi.UserName
i.ProcCreateTime = pi.CreateTime
}
if cmdOpts.Parsed.Storage.DbPath != "" {
i.DBPath = cmdOpts.Parsed.Storage.DbPath
}
return i, nil

View File

@@ -8,9 +8,9 @@ import (
"time"
"github.com/pborman/getopt"
"github.com/stretchr/testify/require"
tu "github.com/percona/percona-toolkit/src/go/internal/testutils"
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
)
func TestGetHostInfo(t *testing.T) {
@@ -49,26 +49,6 @@ func TestGetHostInfo(t *testing.T) {
}
}
func TestGetHostInfoResult(t *testing.T) {
assert := require.New(t)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
client, err := tu.TestClient(ctx, tu.MongoDBShard1PrimaryPort)
assert.NoError(err, "cannot get a new MongoDB client")
host, err := getHostInfo(ctx, client)
assert.NoError(err, "getHostInfo error")
// With the current setup, we should get this information.
assert.NotEmpty(host.ProcessName, "ProcessName should not be empty if serverStatus succeeds")
assert.NotEmpty(host.Version, "Version should not be empty if serverStatus succeeds")
assert.NotEmpty(host.ProcPath, "ProcPath should not be empty if getProcInfo succeeds")
assert.NotEmpty(host.ProcUserName, "ProcUserName should not be empty if getProcInfo succeeds")
assert.False(host.ProcCreateTime.IsZero(), "ProcCreateTime should not be zero if getProcInfo succeeds")
}
func TestClusterWideInfo(t *testing.T) {
testCases := []struct {
name string
@@ -105,6 +85,16 @@ func TestClusterWideInfo(t *testing.T) {
}
}
func addToCounters(ss proto.ServerStatus, increment int64) proto.ServerStatus {
ss.Opcounters.Command += increment
ss.Opcounters.Delete += increment
ss.Opcounters.GetMore += increment
ss.Opcounters.Insert += increment
ss.Opcounters.Query += increment
ss.Opcounters.Update += increment
return ss
}
func TestParseArgs(t *testing.T) {
tests := []struct {
args []string

View File

@@ -449,6 +449,30 @@ is_deeply(
"..but can be turned off"
);
# ############################################################################
# https://perconadev.atlassian.net/browse/PT-2014
# pt-config-diff does not honor case insensitivity flag for boolean values
# ############################################################################
$c1 = new MySQLConfig(
file => "$trunk/$sample/pt-2014-1.txt",
TextResultSetParser => $trp,
);
$c2 = new MySQLConfig(
file => "$trunk/$sample/pt-2014-2.txt",
TextResultSetParser => $trp,
);
{
my $diff = $cc->diff(
configs => [$c1, $c2],
);
is_deeply(
$diff,
undef,
"Boolean values are the same regardless of the case"
) or diag(Dumper($diff));
}
# #############################################################################
# Done.
# #############################################################################

View File

@@ -0,0 +1,7 @@
[mysqld]
log_bin=1
gtid_mode=on
read_only=off
autocommit=no
binlog_format=mixed
skip_name_resolve=true

View File

@@ -0,0 +1,7 @@
[mysqld]
log_bin=on
gtid_mode=True
read_only=FALSE
autocommit=0
binlog_format=MIXED
skip_name_resolve=TRUE

View File

@@ -19,7 +19,7 @@ use Sandbox;
use SqlModes;
use File::Temp qw/ tempdir /;
plan tests => 6;
plan tests => 10;
require "$trunk/bin/pt-online-schema-change";
@@ -88,6 +88,47 @@ like(
"PT-153 Adding multiple unique indexes -> multime example queries.",
);
# UNIQUE is possible without INDEX or KEY, we need to check this as well.
($output, $exit_status) = full_output(
sub { pt_online_schema_change::main(@args, "$source_dsn,D=test,t=t1",
'--execute',
'--alter', "ADD UNIQUE c1 (f2, f3)",
),
},
);
isnt(
$exit_status,
0,
"PT-153 Adding unique index without index/key keyword exit status != 0.",
);
like(
$output,
qr/You are trying to add an unique key. This can result in data loss if the data is not unique/s,
"PT-153 Adding unique index without index/key keyword warning message.",
);
($output, $exit_status) = full_output(
sub { pt_online_schema_change::main(@args, "$source_dsn,D=test,t=t1",
'--execute',
'--alter', "ADD UNIQUE(f2, f3)",
),
},
);
isnt(
$exit_status,
0,
"PT-153 Adding unique index without index/key keyword and index name exit status != 0.",
);
like(
$output,
qr/You are trying to add an unique key. This can result in data loss if the data is not unique/s,
"PT-153 Adding unique index without index/key keyword and index name warning message.",
);
$source_dbh->do("DROP DATABASE IF EXISTS test");
# #############################################################################

262
t/pt-stalk/pt-2289.t Normal file
View File

@@ -0,0 +1,262 @@
#!/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 Time::HiRes qw(sleep);
use PerconaTest;
use DSNParser;
use Sandbox;
require VersionParser;
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('source');
if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox source';
}
my $cnf = "/tmp/12345/my.sandbox.cnf";
my $pid_file = "/tmp/pt-stalk.pid.$PID";
my $log_file = "/tmp/pt-stalk.log.$PID";
my $dest = "/tmp/pt-stalk.collect.$PID";
my $int_file = "/tmp/pt-stalk-after-interval-sleep";
my $pid;
my $output;
my $retval;
sub cleanup {
diag(`rm $pid_file $log_file $int_file 2>/dev/null`);
diag(`rm -rf $dest 2>/dev/null`);
}
# ###########################################################################
# Test that it collects all data when no --skip-collection is given.
# ###########################################################################
cleanup();
# We need these to collect lock-waits
sub start_thread_pt_1897_1 {
# this must run in a thread because we need to have an active session
# with open transaction
my ($dsn_opts) = @_;
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('source');
$sb->load_file('source', "t/pt-stalk/samples/PT-1897-1.sql");
}
my $thr1 = threads->create('start_thread_pt_1897_1', $dsn_opts);
$thr1->detach();
threads->yield();
sleep 1;
sub start_thread_pt_1897_2 {
# this must run in a thread because we need to have an active session
# with waiting transaction
my ($dsn_opts) = @_;
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('source');
$sb->load_file('source', "t/pt-stalk/samples/PT-1897-2.sql");
}
my $thr2 = threads->create('start_thread_pt_1897_2', $dsn_opts);
$thr2->detach();
threads->yield();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 -- --defaults-file=$cnf >$log_file 2>&1");
sleep 35;
PerconaTest::kill_program(pid_file => $pid_file);
is(
$retval >> 8,
0,
"Parent exit 0"
);
ok(
-d $dest,
"Creates --dest (collect) dir"
);
# ps-locks-transactions,thread-variables,innodbstatus,lock-waits,mysqladmin,processlist,rocksdbstatus,transactions
ok(
glob("$dest/*-ps-locks-transactions"),
"Collects *-ps-locks-transactions"
) or diag(`ls $dest`);
ok(
glob("$dest/*-innodbstatus*"),
"Collects *-innodbstatus*"
) or diag(`ls $dest`);
ok(
glob("$dest/*-lock-waits"),
"Collects *-lock-waits"
) or diag(`ls $dest`);
ok(
glob("$dest/*-mysqladmin"),
"Collects *-mysqladmin"
) or diag(`ls $dest`);
ok(
glob("$dest/*-processlist"),
"Collects *-processlist"
) or diag(`ls $dest`);
ok(
glob("$dest/*-transactions"),
"Collects *-transactions"
) or diag(`ls $dest`);
# thread-variables
ok(
glob("$dest/*-variables"),
"Collects *-variables"
) or diag(`ls $dest`);
$output = `cat $dest/*-variables 2>/dev/null`;
like(
$output,
qr/select \* from performance_schema\.variables_by_thread/,
"Thread variables collected"
); # or diag($output);
SKIP: {
skip "These tests require MyRocks", 1 if ( !$sb->has_engine('source', 'ROCKSDB') ) ;
# rocksdbstatus
ok(
glob("$dest/*-rocksdbstatus*"),
"Collects *-rocksdbstatus"
) or diag(`ls $dest`);
cleanup();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection rocksdbstatus -- --defaults-file=$cnf >$log_file 2>&1");
sleep 5;
PerconaTest::kill_program(pid_file => $pid_file);
ok(
! glob("$dest/*-rocksdbstatus*"),
"Does not collect *-rocksdbstatus"
) or diag(`ls $dest`);
}
cleanup();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection processlist -- --defaults-file=$cnf >$log_file 2>&1");
sleep 5;
PerconaTest::kill_program(pid_file => $pid_file);
ok(
! glob("$dest/*-processlist"),
"Does not collect *-processlist"
) or diag(`ls $dest`);
cleanup();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection ps-locks-transactions,thread-variables,innodbstatus,mysqladmin,processlist,transactions -- --defaults-file=$cnf >$log_file 2>&1");
sleep 5;
PerconaTest::kill_program(pid_file => $pid_file);
ok(
! glob("$dest/*-ps-locks-transactions"),
"Does not collect *-ps-locks-transactions"
) or diag(`ls $dest`);
ok(
glob("$dest/*-variables"),
"Collects *-variables"
) or diag(`ls $dest`);
$output = `cat $dest/*-variables 2>/dev/null`;
unlike(
$output,
qr/select \* from performance_schema\.variables_by_thread/,
"Thread variables not collected"
); # or diag($output);
ok(
! glob("$dest/*-innodbstatus"),
"Does not collect *-innodbstatus"
) or diag(`ls $dest`);
ok(
! glob("$dest/*-mysqladmin"),
"Does not collect *-mysqladmin"
) or diag(`ls $dest`);
ok(
! glob("$dest/*-processlist"),
"Does not collect *-processlist"
) or diag(`ls $dest`);
ok(
! glob("$dest/*-transactions"),
"Does not collect *-transactions"
) or diag(`ls $dest`);
#Unsupported skip-collection value
cleanup();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection ps-locks-transactions,thread-variables,innodbstatus,mysqladmin,processlist,transaction -- --defaults-file=$cnf >$log_file 2>&1");
sleep 5;
PerconaTest::kill_program(pid_file => $pid_file);
is(
$retval >> 8,
1,
"Parent exit 1 on unsupported --skip-collection value"
);
like(
`cat $log_file`,
qr/Invalid --skip-collection value: transaction, exiting./,
"Rejects unsupported --skip-collection value"
);
cleanup();
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection 'mysqladmin and' -- --defaults-file=$cnf >$log_file 2>&1");
sleep 5;
PerconaTest::kill_program(pid_file => $pid_file);
is(
$retval >> 8,
1,
"Parent exit 1 on unsupported --skip-collection value"
);
like(
`cat $log_file`,
qr/Invalid --skip-collection value: mysqladmin and, exiting./,
"Rejects unsupported --skip-collection value"
);
# #############################################################################
# Done.
# #############################################################################
cleanup();
diag(`rm -rf $dest 2>/dev/null`);
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;

View File

@@ -393,18 +393,16 @@ my $tempdir = tempdir( CLEANUP => 1 );
my $script = <<"EOT";
. $trunk/bin/pt-stalk
purge_samples $tempdir 10000 2>&1
purge_samples $tempdir 10000 0 0 2>&1
EOT
$output = `$script`;
$output = `bash -c "$script"`;
unlike(
$output,
qr/\Qfind: warning: you have specified the -depth option/,
"Bug 942114: no bad find usage"
);
# ###########################################################################
# Test that it handles floating point values
# ###########################################################################

View File

@@ -44,16 +44,16 @@ $output = `$trunk/bin/pt-table-sync --sync-to-source h=127.1,P=12346,u=msandbox,
# and EXPLAIN does not guarantee accuracy of results.
like(
$output,
qr/FROM `issue_375`.`t` FORCE INDEX \(`updated_at`\) WHERE \(`updated_at` > 0 AND `updated_at` < '2009-09-05 02:\d\d:\d\d'/,
qr/FROM `issue_375`.`t` FORCE INDEX \(`updated_at`\) WHERE \(`updated_at` > 0 AND `updated_at` < '2009-09-05 \d\d:\d\d:\d\d'/,
'--chunk-index',
);
) or diag($output);
$output = `$trunk/bin/pt-table-sync --sync-to-source h=127.1,P=12346,u=msandbox,p=msandbox -d issue_375 --print -v -v --chunk-size 50 --chunk-column updated_at`;
like(
$output,
qr/FROM `issue_375`.`t` FORCE INDEX \(`updated_at`\) WHERE \(`updated_at` > 0 AND `updated_at` < '2009-09-05 02:\d\d:\d\d'/,
qr/FROM `issue_375`.`t` FORCE INDEX \(`updated_at`\) WHERE \(`updated_at` > 0 AND `updated_at` < '2009-09-05 \d\d:\d\d:\d\d'/,
'--chunk-column',
);
) or diag($output);
# #############################################################################
# Done.