📄 mysql.pm
字号:
# We check for the existence of a particular "short name" index that # has existed at least since Bugzilla 2.8, and probably earlier. # For fixing the inconsistent naming of Schema indexes, # we also check for one of those inconsistently-named indexes. if (grep($_ eq 'bugs', @tables) && ($self->bz_index_info_real('bugs', 'assigned_to') || $self->bz_index_info_real('flags', 'flags_bidattid_idx')) ) { # This is a check unrelated to the indexes, to see if people are # upgrading from 2.18 or below, but somehow have a bz_schema table # already. This only happens if they have done a mysqldump into # a database without doing a DROP DATABASE first. # We just do the check here since this check is a reliable way # of telling that we are upgrading from a version pre-2.20. if (grep($_ eq 'bz_schema', $self->bz_table_list_real())) { die("\nYou are upgrading from a version before 2.20, but the" . " bz_schema\ntable already exists. This means that you" . " restored a mysqldump into\nthe Bugzilla database without" . " first dropping the already-existing\nBugzilla database," . " at some point. Whenever you restore a Bugzilla\ndatabase" . " backup, you must always drop the entire database first.\n\n" . "Please drop your Bugzilla database and restore it from a" . " backup that\ndoes not contain the bz_schema table. If for" . " some reason you cannot\ndo this, you can connect to your" . " MySQL database and drop the bz_schema\ntable, as a last" . " resort.\n"); } my $bug_count = $self->selectrow_array("SELECT COUNT(*) FROM bugs"); # We estimate one minute for each 3000 bugs, plus 3 minutes just # to handle basic MySQL stuff. my $rename_time = int($bug_count / 3000) + 3; # And 45 minutes for every 15,000 attachments, per some experiments. my ($attachment_count) = $self->selectrow_array("SELECT COUNT(*) FROM attachments"); $rename_time += int(($attachment_count * 45) / 15000); # If we're going to take longer than 5 minutes, we let the user know # and allow them to abort. if ($rename_time > 5) { print "\nWe are about to rename old indexes.\n" . "The estimated time to complete renaming is " . "$rename_time minutes.\n" . "You cannot interrupt this action once it has begun.\n" . "If you would like to cancel, press Ctrl-C now..." . " (Waiting 45 seconds...)\n\n"; # Wait 45 seconds for them to respond. sleep(45) unless Bugzilla->installation_answers->{NO_PAUSE}; } print "Renaming indexes...\n"; # We can't be interrupted, because of how the "if" # works above. local $SIG{INT} = 'IGNORE'; local $SIG{TERM} = 'IGNORE'; local $SIG{PIPE} = 'IGNORE'; # Certain indexes had names in Schema that did not easily conform # to a standard. We store those names here, so that they # can be properly renamed. # Also, sometimes an old mysqldump would incorrectly rename # unique indexes to "PRIMARY", so we address that here, also. my $bad_names = { # 'when' is a possible leftover from Bugzillas before 2.8 bugs_activity => ['when', 'bugs_activity_bugid_idx', 'bugs_activity_bugwhen_idx'], cc => ['PRIMARY'], longdescs => ['longdescs_bugid_idx', 'longdescs_bugwhen_idx'], flags => ['flags_bidattid_idx'], flaginclusions => ['flaginclusions_tpcid_idx'], flagexclusions => ['flagexclusions_tpc_id_idx'], keywords => ['PRIMARY'], milestones => ['PRIMARY'], profiles_activity => ['profiles_activity_when_idx'], group_control_map => ['group_control_map_gid_idx', 'PRIMARY'], user_group_map => ['PRIMARY'], group_group_map => ['PRIMARY'], email_setting => ['PRIMARY'], bug_group_map => ['PRIMARY'], category_group_map => ['PRIMARY'], watch => ['PRIMARY'], namedqueries => ['PRIMARY'], series_data => ['PRIMARY'], # series_categories is dealt with below, not here. }; # The series table is broken and needs to have one index # dropped before we begin the renaming, because it had a # useless index on it that would cause a naming conflict here. if (grep($_ eq 'series', @tables)) { my $dropname; # This is what the bad index was called before Schema. if ($self->bz_index_info_real('series', 'creator_2')) { $dropname = 'creator_2'; } # This is what the bad index is called in Schema. elsif ($self->bz_index_info_real('series', 'series_creator_idx')) { $dropname = 'series_creator_idx'; } $self->bz_drop_index_raw('series', $dropname) if $dropname; } # The email_setting table also had the same problem. if( grep($_ eq 'email_setting', @tables) && $self->bz_index_info_real('email_setting', 'email_settings_user_id_idx') ) { $self->bz_drop_index_raw('email_setting', 'email_settings_user_id_idx'); } # Go through all the tables. foreach my $table (@tables) { # Will contain the names of old indexes as keys, and the # definition of the new indexes as a value. The values # include an extra hash key, NAME, with the new name of # the index. my %rename_indexes; # And go through all the columns on each table. my @columns = $self->bz_table_columns_real($table); # We also want to fix the silly naming of unique indexes # that happened when we first checked-in Bugzilla::DB::Schema. if ($table eq 'series_categories') { # The series_categories index had a nonstandard name. push(@columns, 'series_cats_unique_idx'); } elsif ($table eq 'email_setting') { # The email_setting table had a similar problem. push(@columns, 'email_settings_unique_idx'); } else { push(@columns, "${table}_unique_idx"); } # And this is how we fix the other inconsistent Schema naming. push(@columns, @{$bad_names->{$table}}) if (exists $bad_names->{$table}); foreach my $column (@columns) { # If we have an index named after this column, it's an # old-style-name index. if (my $index = $self->bz_index_info_real($table, $column)) { # Fix the name to fit in with the new naming scheme. $index->{NAME} = $table . "_" . $index->{FIELDS}->[0] . "_idx"; print "Renaming index $column to " . $index->{NAME} . "...\n"; $rename_indexes{$column} = $index; } # if } # foreach column my @rename_sql = $self->_bz_schema->get_rename_indexes_ddl( $table, %rename_indexes); $self->do($_) foreach (@rename_sql); } # foreach table } # if old-name indexes # If there are no tables, but the DB isn't utf8 and it should be, # then we should alter the database to be utf8. We know it should be # if the utf8 parameter is true or there are no params at all. # This kind of situation happens when people create the database # themselves, and if we don't do this they will get the big # scary WARNING statement about conversion to UTF8. if ( !$self->bz_db_is_utf8 && !@tables && (Bugzilla->params->{'utf8'} || !scalar keys %{Bugzilla->params}) ) { $self->_alter_db_charset_to_utf8(); } # And now we create the tables and the Schema object. $self->SUPER::bz_setup_database(); # The old timestamp fields need to be adjusted here instead of in # checksetup. Otherwise the UPDATE statements inside of bz_add_column # will cause accidental timestamp updates. # The code that does this was moved here from checksetup. # 2002-08-14 - bbaetz@student.usyd.edu.au - bug 153578 # attachments creation time needs to be a datetime, not a timestamp my $attach_creation = $self->bz_column_info("attachments", "creation_ts"); if ($attach_creation && $attach_creation->{TYPE} =~ /^TIMESTAMP/i) { print "Fixing creation time on attachments...\n"; my $sth = $self->prepare("SELECT COUNT(attach_id) FROM attachments"); $sth->execute(); my ($attach_count) = $sth->fetchrow_array(); if ($attach_count > 1000) { print "This may take a while...\n"; } my $i = 0; # This isn't just as simple as changing the field type, because # the creation_ts was previously updated when an attachment was made # obsolete from the attachment creation screen. So we have to go # and recreate these times from the comments.. $sth = $self->prepare("SELECT bug_id, attach_id, submitter_id " . "FROM attachments"); $sth->execute(); # Restrict this as much as possible in order to avoid false # positives, and keep the db search time down my $sth2 = $self->prepare("SELECT bug_when FROM longdescs WHERE bug_id=? AND who=? AND thetext LIKE ? ORDER BY bug_when " . $self->sql_limit(1)); while (my ($bug_id, $attach_id, $submitter_id) = $sth->fetchrow_array()) { $sth2->execute($bug_id, $submitter_id, "Created an attachment (id=$attach_id)%"); my ($when) = $sth2->fetchrow_array(); if ($when) { $self->do("UPDATE attachments " . "SET creation_ts='$when' " . "WHERE attach_id=$attach_id"); } else { print "Warning - could not determine correct creation" . " time for attachment $attach_id on bug $bug_id\n"; } ++$i; print "Converted $i of $attach_count attachments\n" if !($i % 1000); } print "Done - converted $i attachments\n"; $self->bz_alter_column("attachments", "creation_ts", {TYPE => 'DATETIME', NOTNULL => 1}); } # 2004-08-29 - Tomas.Kopal@altap.cz, bug 257303 # Change logincookies.lastused type from timestamp to datetime my $login_lastused = $self->bz_column_info("logincookies", "lastused"); if ($login_lastused && $login_lastused->{TYPE} =~ /^TIMESTAMP/i) { $self->bz_alter_column('logincookies', 'lastused', { TYPE => 'DATETIME', NOTNULL => 1}); } # 2005-01-17 - Tomas.Kopal@altap.cz, bug 257315 # Change bugs.delta_ts type from timestamp to datetime my $bugs_deltats = $self->bz_column_info("bugs", "delta_ts"); if ($bugs_deltats && $bugs_deltats->{TYPE} =~ /^TIMESTAMP/i) { $self->bz_alter_column('bugs', 'delta_ts', {TYPE => 'DATETIME', NOTNULL => 1}); } # 2005-09-24 - bugreport@peshkin.net, bug 307602 # Make sure that default 4G table limit is overridden my $row = $self->selectrow_hashref("SHOW TABLE STATUS LIKE 'attach_data'"); if ($$row{'Create_options'} !~ /MAX_ROWS/i) { print "Converting attach_data maximum size to 100G...\n"; $self->do("ALTER TABLE attach_data AVG_ROW_LENGTH=1000000, MAX_ROWS=100000"); } # Convert the database to UTF-8 if the utf8 parameter is on. # We check if any table isn't utf8, because lots of crazy # partial-conversion situations can happen, and this handles anything # that could come up (including having the DB charset be utf8 but not # the table charsets. my $utf_table_status = $self->selectall_arrayref("SHOW TABLE STATUS", {Slice=>{}}); $self->_after_table_status([map($_->{Name}, @$utf_table_status)]); my @non_utf8_tables = grep($_->{Collation} !~ /^utf8/, @$utf_table_status); if (Bugzilla->params->{'utf8'} && scalar @non_utf8_tables) { print <<EOT;WARNING: We are about to convert your table storage format to UTF8. This allows Bugzilla to correctly store and sort international characters. However, if you have any non-UTF-8 data in your database, it ***WILL BE DELETED*** by this process. So, before you continue with checksetup.pl, if you have any non-UTF-8 data (or even if you're not sure) you should press Ctrl-C now to interrupt checksetup.pl, and run contrib/recode.pl to make all the data in your database into UTF-8. You should also back up your database before continuing. This will affect every single table in the database, even non-Bugzilla tables. If you ever used a version of Bugzilla before 2.22, we STRONGLY recommend that you stop checksetup.pl NOW and run contrib/recode.pl.EOT if (!Bugzilla->installation_answers->{NO_PAUSE}) { if (Bugzilla->installation_mode == INSTALLATION_MODE_NON_INTERACTIVE) { print <<EOT; Re-run checksetup.pl in interactive mode (without an 'answers' file) to continue.EOT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -