Fixes for DSN parser to use UTF8

This commit is contained in:
Carlos Salguero
2018-01-28 14:46:51 -03:00
parent f3132d3cee
commit d38a584271
7 changed files with 4132 additions and 23 deletions

View File

@@ -379,6 +379,28 @@ sub get_dbh {
. ": $EVAL_ERROR";
}
}
my ($mysql_version) = eval { $dbh->selectrow_array('SELECT VERSION()') };
if ($EVAL_ERROR) {
die "Cannot get MySQL version: $EVAL_ERROR";
}
my (undef, $character_set_server) = eval { $dbh->selectrow_array("SHOW VARIABLES LIKE 'character_set_server'") };
if ($EVAL_ERROR) {
die "Cannot get MySQL var character_set_server: $EVAL_ERROR";
}
if ($mysql_version =~ m/^(\d+)\.(\d)\.(\d+).*/) {
if ($1 >= 8 && $character_set_server =~ m/^utf8/) {
$dbh->{mysql_enable_utf8} = 1;
my $msg = "MySQL version $mysql_version >= 8 and character_set_server = $character_set_server\n".
"Setting: SET NAMES $character_set_server";
PTDEBUG && _d($msg);
eval { $dbh->do("SET NAMES 'utf8mb4'") };
if ($EVAL_ERROR) {
die "Cannot SET NAMES $character_set_server: $EVAL_ERROR";
}
}
}
PTDEBUG && _d('DBH info: ',
$dbh,

View File

@@ -133,7 +133,7 @@ sub create_dbs {
sub get_dbh_for {
my ( $self, $server, $cxn_ops, $user ) = @_;
_check_server($server);
$cxn_ops ||= { AutoCommit => 1 };
$cxn_ops ||= { AutoCommit => 1, mysql_enable_utf8 => 1 };
$user ||= 'msandbox';
PTDEBUG && _d('dbh for', $server, 'on port', $port_for{$server});
my $dp = $self->{DSNParser};

View File

@@ -44,6 +44,7 @@
package TableChunker;
use strict;
use utf8;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
@@ -591,7 +592,7 @@ sub _chunk_char {
$dbh->do($sql);
my $col_def = $args{tbl_struct}->{defs}->{$chunk_col};
$sql = "CREATE TEMPORARY TABLE $tmp_db_tbl ($col_def) "
. "ENGINE=MEMORY";
. "ENGINE=MEMORY DEFAULT CHARSET = utf8";
PTDEBUG && _d($dbh, $sql);
$dbh->do($sql);
@@ -601,7 +602,8 @@ sub _chunk_char {
PTDEBUG && _d($dbh, $sql);
my $ins_char_sth = $dbh->prepare($sql); # avoid quoting issues
for my $char_code ( $min_col_ord..$max_col_ord ) {
$ins_char_sth->execute($char_code);
# Ignore errors on invalid chars for UTF8
eval { $ins_char_sth->execute($char_code) };
}
# Select from the char-to-number map all characters between the

View File

@@ -29,7 +29,7 @@ report-host = 127.0.0.1
report-port = PORT
server-id = PORT
#local_infile = ON
#default_authentication_plugin=mysql_native_password
default_authentication_plugin=mysql_native_password
# fkc test
binlog_format = STATEMENT

File diff suppressed because one or more lines are too long

View File

@@ -315,6 +315,7 @@ sub test_alter_table {
# still functiona: i.e. that they'll prevent us from delete
# a parent row that's being referenced by a child.
my $sql = "DELETE FROM $table WHERE $pk_col=1 LIMIT 1";
warn ">> SQL: $sql";
eval {
$master_dbh->do($sql);
};
@@ -471,6 +472,7 @@ test_alter_table(
],
);
diag(">>>>>>>");
test_alter_table(
name => "Basic FK drop_swap --execute",
table => "pt_osc.country",
@@ -487,6 +489,7 @@ test_alter_table(
],
);
diag("2 >>>>>>>");
# Let the tool auto-determine the fk update method. This should choose
# the rebuild_constraints method because the tables are quite small.
# This is tested by indicating the rebuild_constraints method, which
@@ -510,6 +513,7 @@ test_alter_table(
],
);
diag("3 >>>>>>>");
# Specify --alter-foreign-keys-method for a table with no child tables.
test_alter_table(
name => "Child table",
@@ -527,6 +531,7 @@ test_alter_table(
],
);
diag("4 >>>>>>>");
# Use drop_swap to alter address, which no other table references,
# so the tool should re-enable --swap-tables and --drop-old-table.
test_alter_table(
@@ -545,6 +550,7 @@ test_alter_table(
],
);
diag("5 >>>>>>>");
# Alter city and verify that its fk to country still exists.
# (https://bugs.launchpad.net/percona-toolkit/+bug/969726)
test_alter_table(

View File

@@ -32,25 +32,25 @@ CREATE TABLE `address` (
CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO pt_osc.country VALUES
(1, 'Canada', null),
(2, 'USA', null),
(3, 'Mexico', null),
(4, 'France', null),
(5, 'Spain', null);
INSERT INTO pt_osc.country (`country_id`, `country`) VALUES
(1, 'Canada'),
(2, 'USA'),
(3, 'Mexico'),
(4, 'France'),
(5, 'Spain');
INSERT INTO pt_osc.city VALUES
(1, 'Montréal', 1, null),
(2, 'New York', 2, null),
(3, 'Durango', 3, null),
(4, 'Paris', 4, null),
(5, 'Madrid', 5, null);
INSERT INTO pt_osc.city (`city_id`, `city`, `country_id`) VALUES
(1, 'Montréal', 1),
(2, 'New York', 2),
(3, 'Durango', 3),
(4, 'Paris', 4),
(5, 'Madrid', 5);
INSERT INTO pt_osc.address VALUES
(1, 'addy 1', 1, '10000', null),
(2, 'addy 2', 2, '20000', null),
(3, 'addy 3', 3, '30000', null),
(4, 'addy 4', 4, '40000', null),
(5, 'addy 5', 5, '50000', null);
INSERT INTO pt_osc.address (`address_id`, `address`, `city_id`, `postal_code`) VALUES
(1, 'addy 1', 1, '10000'),
(2, 'addy 2', 2, '20000'),
(3, 'addy 3', 3, '30000'),
(4, 'addy 4', 4, '40000'),
(5, 'addy 5', 5, '50000');
SET foreign_key_checks=1;