From 75ab0ba653b7c531dcd854792922111eb14592ce Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Fri, 9 Feb 2018 16:46:16 -0300 Subject: [PATCH 1/5] PT-1256 pt-table-sync does not use the character set for the table it is synchronizing --- Changelog | 4 ++ bin/pt-table-sync | 29 ++++++++- sandbox/servers/5.7/my.sandbox.cnf | 1 + t/lib/samples/charset.sql | 15 +++++ t/pt-table-sync/pt-1256.t | 97 ++++++++++++++++++++++++++++++ util/check-load-data | 2 +- 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 t/lib/samples/charset.sql create mode 100644 t/pt-table-sync/pt-1256.t diff --git a/Changelog b/Changelog index a1653c80..8ad59180 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,9 @@ Changelog for Percona Toolkit +v3.0.7 + + * Fixed bug PT-1256: pt-table-sync does not use the character set for the table it is synchronizing + v3.0.6 released 2017-12-20 * Fixed bug PT-234: Genaral log parser cannot handle timestamps with tz diff --git a/bin/pt-table-sync b/bin/pt-table-sync index 67d3d6dc..93c06865 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -55,7 +55,7 @@ BEGIN { { package Percona::Toolkit; -our $VERSION = '3.0.6'; +our $VERSION = '3.0.7'; use strict; use warnings FATAL => 'all'; @@ -2137,6 +2137,7 @@ sub parse { } } + $self->{dsn_props} = \%final_props; return \%final_props; } @@ -2319,6 +2320,20 @@ sub get_dbh { } } + if ($self->{dsn_props}->{D} && $self->{dsn_props}->{t}) { + PTDEBUG && _d("DSN has a schema and table: $self->{dsn_props}->{D}.$self->{dsn_props}->{t}"); + PTDEBUG && _d("Trying to set the default charset for the connection"); + my (undef, $create_table) = eval { $dbh->selectrow_array("SHOW CREATE TABLE $self->{dsn_props}->{D}.$self->{dsn_props}->{t}") }; + + if ($create_table && $create_table =~ m/DEFAULT CHARSET=(\S+)\s*/) { + PTDEBUG && _d("Detected table's character set: $1"); + PTDEBUG && _d("Executing: SET NAMES '$1'"); + $dbh->do("SET NAMES '$1'"); + } else { + PTDEBUG && _d("Cannot get the default character set for the table"); + } + } + PTDEBUG && _d('DBH info: ', $dbh, Dumper($dbh->selectrow_hashref( @@ -10644,6 +10659,16 @@ sub sync_a_table { : $tbl_struct->{engine} eq 'InnoDB' ? 1 : 0; + if ($tbl_struct->{charset}) { + PTDEBUG && _d("Detected table's character set: $tbl_struct->{charset}"); + PTDEBUG && _d("Executing: SET NAMES '$tbl_struct->{charset}'"); + $src->{dbh}->do("SET NAMES '$tbl_struct->{charset}'"); + $src->{misc_dbh}->do("SET NAMES '$tbl_struct->{charset}'"); + $dst->{dbh}->do("SET NAMES '$tbl_struct->{charset}'"); + $dst->{misc_dbh}->do("SET NAMES '$tbl_struct->{charset}'"); + } else { + PTDEBUG && _d("Cannot get the default character set for the table"); + } # Turn off AutoCommit if we're using transactions. $src->{dbh}->{AutoCommit} = !$use_txn; $src->{misc_dbh}->{AutoCommit} = !$use_txn; @@ -12977,6 +13002,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA. =head1 VERSION -pt-table-sync 3.0.6 +pt-table-sync 3.0.7 =cut diff --git a/sandbox/servers/5.7/my.sandbox.cnf b/sandbox/servers/5.7/my.sandbox.cnf index 881ea914..a3cf5c9b 100644 --- a/sandbox/servers/5.7/my.sandbox.cnf +++ b/sandbox/servers/5.7/my.sandbox.cnf @@ -27,6 +27,7 @@ innodb_lock_wait_timeout = 3 general_log general_log_file = genlog lower_case_table_names = 0 +#character-set-server = utf8 # fkc test binlog_format = STATEMENT diff --git a/t/lib/samples/charset.sql b/t/lib/samples/charset.sql new file mode 100644 index 00000000..a2a03af4 --- /dev/null +++ b/t/lib/samples/charset.sql @@ -0,0 +1,15 @@ +DROP DATABASE IF EXISTS `test`; +CREATE DATABASE `test`; + +CREATE TABLE `test`.`t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `f2` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) COMMENT "test1" ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `test`.`t2` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `f2` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + diff --git a/t/pt-table-sync/pt-1256.t b/t/pt-table-sync/pt-1256.t new file mode 100644 index 00000000..04c34f8c --- /dev/null +++ b/t/pt-table-sync/pt-1256.t @@ -0,0 +1,97 @@ +#!/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 utf8; +use Encode qw(decode encode); +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-table-sync"; + +binmode(STDIN, ':utf8') or die "Can't binmode(STDIN, ':utf8'): $OS_ERROR"; +binmode(STDOUT, ':utf8') or die "Can't binmode(STDOUT, ':utf8'): $OS_ERROR"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $master_dbh = $sb->get_dbh_for('master'); +my $slave1_dbh = $sb->get_dbh_for('slave1'); +my $slave2_dbh = $sb->get_dbh_for('slave2'); + +if ( !$master_dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave1'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave2'; +} +else { + plan tests => 5; +} + +my ($output, $status); +my @args = ('--sync-to-master', 'h=127.1,P=12346,u=msandbox,p=msandbox', + qw(-t test.t1 --print --execute)); + +# use lib/samples dir since the main change is in DSNParser +$sb->load_file('master', "t/lib/samples/charset.sql"); + +my $want = encode('UTF-8','абвгд'); + +$master_dbh->do("SET NAMES 'utf8'"); +$slave1_dbh->do("SET NAMES 'utf8'"); +$slave1_dbh->do("SET NAMES 'utf8'"); + +$master_dbh->do("INSERT INTO test.t1 VALUES (NULL, '$want')"); +$sb->wait_for_slaves(); + +$slave1_dbh->do("DELETE FROM test.t1 WHERE id=1 LIMIT 1"); +$slave1_dbh->do("FLUSH TABLES"); + + +# 1 +($output, $status) = full_output( + sub { pt_table_sync::main(@args) }, +); + +like( + $output, + qr/REPLACE INTO `test`.`t1`/, + "PT-1256 Set the correct charset" +); + +# 2 +my $row = $slave1_dbh->selectrow_hashref("SELECT f2 FROM test.t1 WHERE id = 1"); +is( + $row->{f2}, + $want, + "Character set is correct", +); + +# 3 +$output = `$trunk/bin/pt-table-sync --execute --lock-and-rename h=127.1,P=12345,u=msandbox,p=msandbox,D=test,t=t1 t=t2 2>&1`; +$output = `/tmp/12345/use -e 'show create table test.t2'`; +like($output, qr/COMMENT='test1'/, '--lock-and-rename worked'); + +$row = $slave1_dbh->selectrow_hashref("SELECT f2 FROM test.t2 WHERE id = 1"); +is( + $row->{f2}, + $want, + "Character set is correct", +); +# ############################################################################# +# Done. +# ############################################################################# +$sb->wipe_clean($master_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/util/check-load-data b/util/check-load-data index 69f25577..23732ce5 100755 --- a/util/check-load-data +++ b/util/check-load-data @@ -44,7 +44,7 @@ $dbh->do("CREATE TABLE IF NOT EXISTS percona_test.load_data (i int)"); `echo 1 > /tmp/load_data_test.$$`; eval { - $dbh->do("LOAD DATA LOCAL INFILE '/tmp/load_data_test.$$' INTO TABLE percona_test.load_data"); + $dbh->do("LOAD DATA INFILE '/tmp/load_data_test.$$' INTO TABLE percona_test.load_data"); }; if ( $EVAL_ERROR ) { From 53ce571bf13eacd76b86e8182fe65c7141168dce Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 12 Feb 2018 16:40:30 -0300 Subject: [PATCH 2/5] PT-633 Added --mysql-only option to pt-stalk --- Changelog | 1 + bin/pt-stalk | 134 +++++++++++++++++++++------------------ lib/bash/collect.sh | 150 +++++++++++++++++++++++--------------------- 3 files changed, 153 insertions(+), 132 deletions(-) diff --git a/Changelog b/Changelog index 8ad59180..c33079ee 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Changelog for Percona Toolkit v3.0.7 + * Feature PT-644 : Added --mysql-only option to pt-stalk for RDS * Fixed bug PT-1256: pt-table-sync does not use the character set for the table it is synchronizing v3.0.6 released 2017-12-20 diff --git a/bin/pt-stalk b/bin/pt-stalk index 82a64df6..9bdf2ef0 100755 --- a/bin/pt-stalk +++ b/bin/pt-stalk @@ -128,6 +128,7 @@ OPT_ERRS=0 # How many command line option errors OPT_VERSION="" # If --version was specified OPT_HELP="" # If --help was specified OPT_ASK_PASS="" # If --ask-pass was specified +OPT_MYSQL_ONLY="" # If --mysql-only was specified PO_DIR="" # Directory with program option spec files usage() { @@ -795,7 +796,10 @@ collect() { local d="$1" # directory to save results in local p="$2" # prefix for each result file - local mysqld_pid=$(_pidof mysqld | awk '{print $1; exit;}') + local mysqld_pid="" + if [ ! "$OPT_MYSQL_ONLY" ]; then + mysqld_pid=$(_pidof mysqld | awk '{print $1; exit;}') + fi if [ "$CMD_PMAP" -a "$mysqld_pid" ]; then if $CMD_PMAP --help 2>&1 | grep -- -x >/dev/null 2>&1 ; then @@ -824,7 +828,7 @@ collect() { fi local tail_error_log_pid="" - if [ "$mysql_error_log" ]; then + if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then log "The MySQL error log seems to be $mysql_error_log" tail -f "$mysql_error_log" >"$d/$p-log_error" & tail_error_log_pid=$! @@ -865,37 +869,39 @@ collect() { local strace_pid=$! fi - ps -eaF >> "$d/$p-ps" & - top -bn${OPT_RUN_TIME} >> "$d/$p-top" & + if [ ! "$OPT_MYSQL_ONLY" ]; then + ps -eaF >> "$d/$p-ps" & + top -bn${OPT_RUN_TIME} >> "$d/$p-top" & - [ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" & + [ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" & - if [ "$CMD_SYSCTL" ]; then - $CMD_SYSCTL -a >> "$d/$p-sysctl" & - fi + if [ "$CMD_SYSCTL" ]; then + $CMD_SYSCTL -a >> "$d/$p-sysctl" & + fi - if [ "$CMD_DMESG" ]; then - local UPTIME=`cat /proc/uptime | awk '{ print $1 }'` - local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}') - $CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" & - fi + if [ "$CMD_DMESG" ]; then + local UPTIME=`cat /proc/uptime | awk '{ print $1 }'` + local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}') + $CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" & + fi - local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT)) - if [ "$CMD_VMSTAT" ]; then - $CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" & - $CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" & - fi - if [ "$CMD_IOSTAT" ]; then - $CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" & - $CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" & - fi - if [ "$CMD_MPSTAT" ]; then - $CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" & - $CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" & - fi + local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT)) + if [ "$CMD_VMSTAT" ]; then + $CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" & + $CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" & + fi + if [ "$CMD_IOSTAT" ]; then + $CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" & + $CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" & + fi + if [ "$CMD_MPSTAT" ]; then + $CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" & + $CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" & + fi - $CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" & - local mysqladmin_pid=$! + $CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" & + local mysqladmin_pid=$! + fi local have_lock_waits_table="" $CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \ @@ -915,40 +921,41 @@ collect() { fi while [ $((curr_time - start_time)) -lt $OPT_RUN_TIME ]; do + if [ ! "$OPT_MYSQL_ONLY" ]; then + disk_space $d > $d/$p-disk-space + check_disk_space \ + $d/$p-disk-space \ + "$OPT_DISK_BYTES_FREE" \ + "$OPT_DISK_PCT_FREE" \ + || break - disk_space $d > $d/$p-disk-space - check_disk_space \ - $d/$p-disk-space \ - "$OPT_DISK_BYTES_FREE" \ - "$OPT_DISK_PCT_FREE" \ - || break + sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}") + local ts="$(date +"TS %s.%N %F %T")" - sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}") - local ts="$(date +"TS %s.%N %F %T")" - - if [ -d "/proc" ]; then - if [ -f "/proc/diskstats" ]; then - (echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" & - fi - if [ -f "/proc/stat" ]; then - (echo $ts; cat /proc/stat) >> "$d/$p-procstat" & - fi - if [ -f "/proc/vmstat" ]; then - (echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" & - fi - if [ -f "/proc/meminfo" ]; then - (echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" & - fi - if [ -f "/proc/slabinfo" ]; then - (echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" & - fi - if [ -f "/proc/interrupts" ]; then - (echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" & + if [ -d "/proc" ]; then + if [ -f "/proc/diskstats" ]; then + (echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" & + fi + if [ -f "/proc/stat" ]; then + (echo $ts; cat /proc/stat) >> "$d/$p-procstat" & + fi + if [ -f "/proc/vmstat" ]; then + (echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" & + fi + if [ -f "/proc/meminfo" ]; then + (echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" & + fi + if [ -f "/proc/slabinfo" ]; then + (echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" & + fi + if [ -f "/proc/interrupts" ]; then + (echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" & + fi fi + (echo $ts; df -k) >> "$d/$p-df" & + (echo $ts; netstat -antp) >> "$d/$p-netstat" & + (echo $ts; netstat -s) >> "$d/$p-netstat_s" & fi - (echo $ts; df -k) >> "$d/$p-df" & - (echo $ts; netstat -antp) >> "$d/$p-netstat" & - (echo $ts; netstat -s) >> "$d/$p-netstat_s" & (echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \ >> "$d/$p-processlist" & if [ "$have_lock_waits_table" ]; then @@ -1414,6 +1421,7 @@ stalk() { # Start collecting, maybe. # ################################################################## log "Collect $ITER triggered" + log "MYSQL_ONLY: $OPT_MYSQL_ONLY" # Send email to whomever that collect has been triggered. if [ "$OPT_NOTIFY_BY_EMAIL" ]; then @@ -1424,7 +1432,6 @@ stalk() { if [ "$OPT_COLLECT" ]; then local prefix="${OPT_PREFIX:-$(date +%F-%T | tr ':-' '_')}" - # Check if we'll have enough disk space to collect. Disk space # is also checked every interval while collecting. local margin="20971520" # default 20M margin, unless: @@ -2093,6 +2100,13 @@ Plugin writers should keep in mind that the file destination prefix currently in use should be accessed through the C<$prefix> variable, rather than C<$OPT_PREFIX>. +=item --mysql-only + +Trigger only MySQL related captures, ignoring all others. The only not MySQL related +value being collected is the disk space, because it is needed to calculate the +available free disk space to write the result files. +This option is useful for RDS instances. + =item --port short form: -P; type: int @@ -2362,7 +2376,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA. =head1 VERSION -pt-stalk 3.0.6 +pt-stalk 3.0.7 =cut diff --git a/lib/bash/collect.sh b/lib/bash/collect.sh index ba0ca6a3..92dedae2 100644 --- a/lib/bash/collect.sh +++ b/lib/bash/collect.sh @@ -49,8 +49,11 @@ collect() { local d="$1" # directory to save results in local p="$2" # prefix for each result file + local mysqld_pid="" # Get pidof mysqld. - local mysqld_pid=$(_pidof mysqld | awk '{print $1; exit;}') + if [ ! "$OPT_MYSQL_ONLY" ]; then + mysqld_pid=$(_pidof mysqld | awk '{print $1; exit;}') + fi # Get memory allocation info before anything else. if [ "$CMD_PMAP" -a "$mysqld_pid" ]; then @@ -90,7 +93,7 @@ collect() { fi local tail_error_log_pid="" - if [ "$mysql_error_log" ]; then + if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then log "The MySQL error log seems to be $mysql_error_log" tail -f "$mysql_error_log" >"$d/$p-log_error" & tail_error_log_pid=$! @@ -141,44 +144,46 @@ collect() { # Grab a few general things first. Background all of these so we can start # them all up as quickly as possible. - ps -eaF >> "$d/$p-ps" & - top -bn${OPT_RUN_TIME} >> "$d/$p-top" & + if [ ! "$OPT_MYSQL_ONLY" ]; then + ps -eaF >> "$d/$p-ps" & + top -bn${OPT_RUN_TIME} >> "$d/$p-top" & - [ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" & + [ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" & - if [ "$CMD_SYSCTL" ]; then - $CMD_SYSCTL -a >> "$d/$p-sysctl" & - fi + if [ "$CMD_SYSCTL" ]; then + $CMD_SYSCTL -a >> "$d/$p-sysctl" & + fi - # collect dmesg events from 60 seconds ago until present - if [ "$CMD_DMESG" ]; then - local UPTIME=`cat /proc/uptime | awk '{ print $1 }'` - local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}') - $CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" & - fi + # collect dmesg events from 60 seconds ago until present + if [ "$CMD_DMESG" ]; then + local UPTIME=`cat /proc/uptime | awk '{ print $1 }'` + local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}') + $CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" & + fi - local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT)) - if [ "$CMD_VMSTAT" ]; then - $CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" & - $CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" & - fi - if [ "$CMD_IOSTAT" ]; then - $CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" & - $CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" & - fi - if [ "$CMD_MPSTAT" ]; then - $CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" & - $CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" & - fi + local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT)) + if [ "$CMD_VMSTAT" ]; then + $CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" & + $CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" & + fi + if [ "$CMD_IOSTAT" ]; then + $CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" & + $CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" & + fi + if [ "$CMD_MPSTAT" ]; then + $CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" & + $CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" & + fi - # Collect multiple snapshots of the status variables. We use - # mysqladmin -c even though it is buggy and won't stop on its - # own in 5.1 and newer, because there is a chance that we will - # 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. - $CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" & - local mysqladmin_pid=$! + # Collect multiple snapshots of the status variables. We use + # mysqladmin -c even though it is buggy and won't stop on its + # own in 5.1 and newer, because there is a chance that we will + # 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. + $CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" & + local mysqladmin_pid=$! + fi local have_lock_waits_table="" $CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \ @@ -200,47 +205,48 @@ collect() { fi while [ $((curr_time - start_time)) -lt $OPT_RUN_TIME ]; do + if [ ! "$OPT_MYSQL_ONLY" ]; then + # We check the disk, but don't exit, because we need to stop jobs if we + # need to exit. + disk_space $d > $d/$p-disk-space + check_disk_space \ + $d/$p-disk-space \ + "$OPT_DISK_BYTES_FREE" \ + "$OPT_DISK_PCT_FREE" \ + || break - # We check the disk, but don't exit, because we need to stop jobs if we - # need to exit. - disk_space $d > $d/$p-disk-space - check_disk_space \ - $d/$p-disk-space \ - "$OPT_DISK_BYTES_FREE" \ - "$OPT_DISK_PCT_FREE" \ - || break + # Sleep between collect cycles. + # Synchronize ourselves onto the clock tick, so the sleeps are 1-second + sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}") + local ts="$(date +"TS %s.%N %F %T")" - # Sleep between collect cycles. - # Synchronize ourselves onto the clock tick, so the sleeps are 1-second - sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}") - local ts="$(date +"TS %s.%N %F %T")" - - # ##################################################################### - # Collect data for this cycle. - # ##################################################################### - if [ -d "/proc" ]; then - if [ -f "/proc/diskstats" ]; then - (echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" & - fi - if [ -f "/proc/stat" ]; then - (echo $ts; cat /proc/stat) >> "$d/$p-procstat" & - fi - if [ -f "/proc/vmstat" ]; then - (echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" & - fi - if [ -f "/proc/meminfo" ]; then - (echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" & - fi - if [ -f "/proc/slabinfo" ]; then - (echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" & - fi - if [ -f "/proc/interrupts" ]; then - (echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" & + # ##################################################################### + # Collect data for this cycle. + # ##################################################################### + if [ -d "/proc" ]; then + if [ -f "/proc/diskstats" ]; then + (echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" & + fi + if [ -f "/proc/stat" ]; then + (echo $ts; cat /proc/stat) >> "$d/$p-procstat" & + fi + if [ -f "/proc/vmstat" ]; then + (echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" & + fi + if [ -f "/proc/meminfo" ]; then + (echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" & + fi + if [ -f "/proc/slabinfo" ]; then + (echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" & + fi + if [ -f "/proc/interrupts" ]; then + (echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" & + fi fi + (echo $ts; df -k) >> "$d/$p-df" & + (echo $ts; netstat -antp) >> "$d/$p-netstat" & + (echo $ts; netstat -s) >> "$d/$p-netstat_s" & fi - (echo $ts; df -k) >> "$d/$p-df" & - (echo $ts; netstat -antp) >> "$d/$p-netstat" & - (echo $ts; netstat -s) >> "$d/$p-netstat_s" & (echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \ >> "$d/$p-processlist" & if [ "$have_lock_waits_table" ]; then From 0d1193c201cfc3284b8d2b642cd6af0c6092854a Mon Sep 17 00:00:00 2001 From: Evgeniy Patlan Date: Wed, 14 Feb 2018 17:04:35 +0200 Subject: [PATCH 3/5] [BLD-948] write uuid to file during toolkit installation --- config/deb/postinst | 8 ++++++++ config/rpm/percona-toolkit.spec | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 config/deb/postinst diff --git a/config/deb/postinst b/config/deb/postinst new file mode 100644 index 00000000..836c6c91 --- /dev/null +++ b/config/deb/postinst @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ ! -e /etc/percona-toolkit/.percona.toolkit.uuid ]; then + mkdir -p /etc/percona-toolkit + perl -e 'printf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7;' > /etc/percona-toolkit/.percona.toolkit.uuid +fi + +#DEBHELPER# diff --git a/config/rpm/percona-toolkit.spec b/config/rpm/percona-toolkit.spec index b2bddfc9..e19a673c 100644 --- a/config/rpm/percona-toolkit.spec +++ b/config/rpm/percona-toolkit.spec @@ -42,6 +42,11 @@ find $RPM_BUILD_ROOT -type f -name 'percona-toolkit.pod' -exec rm -f {} ';' rm -rf $RPM_BUILD_ROOT/usr/share/perl5 chmod -R u+w $RPM_BUILD_ROOT/* +%post +if [ ! -e /etc/percona-toolkit/.percona.toolkit.uuid ]; then + mkdir -p /etc/percona-toolkit + perl -e 'printf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7;' > /etc/percona-toolkit/.percona.toolkit.uuid +fi %clean rm -rf $RPM_BUILD_ROOT From cdec55dc8417f0e221d8edd61c2e45f410a2992b Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Wed, 14 Feb 2018 12:54:02 -0300 Subject: [PATCH 4/5] PMM-1479 Switched to UUID for version check In order to be able to count individual users for the usage stats, we need to implement UUID instead of just using MD5(hostname) since most servers are just 'localhost' or 'db1'. Using UUID we would be able to count unique users. --- lib/VersionCheck.pm | 60 ++++++++++++++++++++++++++++++++++++++------ t/lib/VersionCheck.t | 18 ++++++++++++- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/lib/VersionCheck.pm b/lib/VersionCheck.pm index 0c126d11..b612dd04 100644 --- a/lib/VersionCheck.pm +++ b/lib/VersionCheck.pm @@ -48,6 +48,14 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + # Return the version check file used to keep track of # MySQL instance that have been checked and when. Some # systems use random tmp dirs; we don't want that else @@ -55,13 +63,6 @@ eval { # per system is the goal, so prefer global sys dirs first. { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -326,6 +327,49 @@ sub get_instance_id { return $name, $id; } + +# This function has been implemented solely to be able to count individual +# Toolkit users for statistics. It uses a random UUID, no client info is +# being gathered nor stored +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + # ############################################################################# # Protocol handlers # ############################################################################# @@ -387,7 +431,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/t/lib/VersionCheck.t b/t/lib/VersionCheck.t index ba9881a5..30436a68 100644 --- a/t/lib/VersionCheck.t +++ b/t/lib/VersionCheck.t @@ -201,7 +201,7 @@ is_deeply( # Former Pingback tests # ############################################################################# -my $general_id = md5_hex( hostname() ); +my $general_id = VersionCheck::get_uuid(); my $master_id; # the instance ID, _not_ 12345 etc. my $slave1_id; # the instance ID, _not_ 12346 etc. my ($mysql_ver, $mysql_distro); @@ -679,6 +679,22 @@ foreach my $tool ( @vc_tools ) { ); } +my $should_remove_uuid_file; +my $home_uuid_file = $ENV{"HOME"} . "/.percona-toolkit.uuid"; + +if ( ! -e $home_uuid_file ) { + $should_remove_uuid_file = 1; +} + +my $uuid = VersionCheck::get_uuid(); +is ( + length($uuid), + 36, + "Have a valid UUID4", +); + +unlink $home_uuid_file if $should_remove_uuid_file; + # ############################################################################# # Done. # ############################################################################# From a8d85f1cd58e9ba9a5481ec035aae7e60d0c27c4 Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Wed, 14 Feb 2018 13:02:24 -0300 Subject: [PATCH 5/5] PMM-1479 Updated all files using VersionCheck pkg --- bin/pt-archiver | 57 +++++++++++++++++++++++++++++++----- bin/pt-config-diff | 57 +++++++++++++++++++++++++++++++----- bin/pt-deadlock-logger | 57 +++++++++++++++++++++++++++++++----- bin/pt-diskstats | 57 +++++++++++++++++++++++++++++++----- bin/pt-duplicate-key-checker | 57 +++++++++++++++++++++++++++++++----- bin/pt-find | 57 +++++++++++++++++++++++++++++++----- bin/pt-fk-error-logger | 57 +++++++++++++++++++++++++++++++----- bin/pt-heartbeat | 57 +++++++++++++++++++++++++++++++----- bin/pt-index-usage | 57 +++++++++++++++++++++++++++++++----- bin/pt-kill | 57 +++++++++++++++++++++++++++++++----- bin/pt-online-schema-change | 57 +++++++++++++++++++++++++++++++----- bin/pt-query-digest | 57 +++++++++++++++++++++++++++++++----- bin/pt-slave-delay | 57 +++++++++++++++++++++++++++++++----- bin/pt-slave-restart | 57 +++++++++++++++++++++++++++++++----- bin/pt-table-checksum | 57 +++++++++++++++++++++++++++++++----- bin/pt-table-sync | 57 +++++++++++++++++++++++++++++++----- bin/pt-upgrade | 57 +++++++++++++++++++++++++++++++----- bin/pt-variable-advisor | 57 +++++++++++++++++++++++++++++++----- 18 files changed, 882 insertions(+), 144 deletions(-) diff --git a/bin/pt-archiver b/bin/pt-archiver index d08e95ed..b297def3 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -5373,15 +5373,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -5598,6 +5599,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -5634,7 +5675,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-config-diff b/bin/pt-config-diff index 7a340806..35b0134f 100755 --- a/bin/pt-config-diff +++ b/bin/pt-config-diff @@ -4711,15 +4711,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4936,6 +4937,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4972,7 +5013,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index d2b09b78..4ed24bb3 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -3775,15 +3775,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4000,6 +4001,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4036,7 +4077,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-diskstats b/bin/pt-diskstats index 9773fd84..a1bb8252 100755 --- a/bin/pt-diskstats +++ b/bin/pt-diskstats @@ -4328,15 +4328,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4553,6 +4554,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4589,7 +4630,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-duplicate-key-checker b/bin/pt-duplicate-key-checker index d6586855..9cca3223 100755 --- a/bin/pt-duplicate-key-checker +++ b/bin/pt-duplicate-key-checker @@ -4379,15 +4379,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4604,6 +4605,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4640,7 +4681,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-find b/bin/pt-find index c1e4a940..e63870c9 100755 --- a/bin/pt-find +++ b/bin/pt-find @@ -3093,15 +3093,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -3318,6 +3319,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -3354,7 +3395,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index 8ce7b713..e99aae70 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -3280,15 +3280,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -3505,6 +3506,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -3541,7 +3582,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-heartbeat b/bin/pt-heartbeat index b3be48c7..f0566be2 100755 --- a/bin/pt-heartbeat +++ b/bin/pt-heartbeat @@ -4980,15 +4980,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -5205,6 +5206,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -5241,7 +5282,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-index-usage b/bin/pt-index-usage index 75239c1f..d34f34a4 100755 --- a/bin/pt-index-usage +++ b/bin/pt-index-usage @@ -5777,15 +5777,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -6002,6 +6003,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -6038,7 +6079,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-kill b/bin/pt-kill index 01154183..5e1fd437 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -6185,15 +6185,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -6410,6 +6411,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -6446,7 +6487,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 91184b0d..bbba173f 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -7413,15 +7413,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -7638,6 +7639,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -7674,7 +7715,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-query-digest b/bin/pt-query-digest index ba90a55f..4923c3cb 100755 --- a/bin/pt-query-digest +++ b/bin/pt-query-digest @@ -12446,15 +12446,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -12671,6 +12672,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -12707,7 +12748,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-slave-delay b/bin/pt-slave-delay index e79bd633..0ff73c59 100755 --- a/bin/pt-slave-delay +++ b/bin/pt-slave-delay @@ -3597,15 +3597,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -3822,6 +3823,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -3858,7 +3899,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-slave-restart b/bin/pt-slave-restart index f202ff2a..59cd6315 100755 --- a/bin/pt-slave-restart +++ b/bin/pt-slave-restart @@ -4306,15 +4306,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4531,6 +4532,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4567,7 +4608,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index c1f14786..67d4fccc 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -797,15 +797,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -1022,6 +1023,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -1058,7 +1099,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-table-sync b/bin/pt-table-sync index 93c06865..0817e384 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -9215,15 +9215,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -9440,6 +9441,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -9476,7 +9517,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-upgrade b/bin/pt-upgrade index c4753636..4e671878 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -4086,15 +4086,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4311,6 +4312,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4347,7 +4388,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/bin/pt-variable-advisor b/bin/pt-variable-advisor index ce80e9f2..e3aeb29e 100755 --- a/bin/pt-variable-advisor +++ b/bin/pt-variable-advisor @@ -4504,15 +4504,16 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -4729,6 +4730,46 @@ sub get_instance_id { } +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + + sub pingback { my (%args) = @_; my @required_args = qw(url instances); @@ -4765,7 +4806,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = {